diff --git a/NadekoBot/App.config b/NadekoBot/App.config
index 151cc154..be94d15f 100644
--- a/NadekoBot/App.config
+++ b/NadekoBot/App.config
@@ -1,14 +1,14 @@
-ο»Ώ
+
-
+
-
-
+
+
-
\ No newline at end of file
+
diff --git a/NadekoBot/Classes/DBHandler.cs b/NadekoBot/Classes/DBHandler.cs
index ba99b635..c6488a27 100644
--- a/NadekoBot/Classes/DBHandler.cs
+++ b/NadekoBot/Classes/DBHandler.cs
@@ -34,6 +34,14 @@ namespace NadekoBot.Classes
}
}
+ internal T FindOne(Expression> p) where T : IDataModel, new()
+ {
+ using (var conn = new SQLiteConnection(FilePath))
+ {
+ return conn.Table().Where(p).FirstOrDefault();
+ }
+ }
+
internal void DeleteAll() where T : IDataModel
{
using (var conn = new SQLiteConnection(FilePath))
diff --git a/NadekoBot/Classes/FlowersHandler.cs b/NadekoBot/Classes/FlowersHandler.cs
index c40dd83e..d696c0b1 100644
--- a/NadekoBot/Classes/FlowersHandler.cs
+++ b/NadekoBot/Classes/FlowersHandler.cs
@@ -4,7 +4,7 @@ namespace NadekoBot.Classes
{
internal static class FlowersHandler
{
- public static async Task AddFlowersAsync(Discord.User u, string reason, int amount)
+ public static async Task AddFlowersAsync(Discord.User u, string reason, int amount, bool silent = false)
{
if (amount <= 0)
return;
@@ -17,6 +17,10 @@ namespace NadekoBot.Classes
Value = amount,
});
});
+
+ if (silent)
+ return;
+
var flows = "";
for (var i = 0; i < amount; i++)
{
@@ -25,19 +29,23 @@ namespace NadekoBot.Classes
await u.SendMessage("πCongratulations!π\nYou received: " + flows);
}
- public static async Task RemoveFlowersAsync(Discord.User u, string reason, int amount)
+ public static bool RemoveFlowers(Discord.User u, string reason, int amount)
{
if (amount <= 0)
- return;
- await Task.Run(() =>
+ return false;
+ var uid = (long)u.Id;
+ var state = DbHandler.Instance.FindOne<_DataModels.CurrencyState>(cs => cs.UserId == uid);
+
+ if (state.Value < amount)
+ return false;
+
+ DbHandler.Instance.InsertData(new _DataModels.CurrencyTransaction
{
- DbHandler.Instance.InsertData(new _DataModels.CurrencyTransaction
- {
- Reason = reason,
- UserId = (long)u.Id,
- Value = -amount,
- });
+ Reason = reason,
+ UserId = (long)u.Id,
+ Value = -amount,
});
+ return true;
}
}
}
diff --git a/NadekoBot/Commands/PlantPick.cs b/NadekoBot/Commands/PlantPick.cs
new file mode 100644
index 00000000..8d688911
--- /dev/null
+++ b/NadekoBot/Commands/PlantPick.cs
@@ -0,0 +1,85 @@
+ο»Ώusing Discord;
+using Discord.Commands;
+using NadekoBot.Classes;
+using NadekoBot.Modules;
+using System;
+using System.Collections.Concurrent;
+using System.IO;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace NadekoBot.Commands
+{
+ ///
+ /// Flower picking/planting idea is given to me by its
+ /// inceptor Violent Crumble from Game Developers League discord server
+ /// (he has !cookie and !nom) Thanks a lot Violent!
+ /// Check out GDL (its a growing gamedev community):
+ /// https://discord.gg/0TYNJfCU4De7YIk8
+ ///
+ class PlantPick : DiscordCommand
+ {
+ public PlantPick(DiscordModule module) : base(module)
+ {
+
+ }
+
+ //channelid/messageid pair
+ ConcurrentDictionary plantedFlowerChannels = new ConcurrentDictionary();
+
+ private object locker = new object();
+
+ internal override void Init(CommandGroupBuilder cgb)
+ {
+ cgb.CreateCommand(Module.Prefix + "pick")
+ .Description("Picks a flower planted in this channel.")
+ .Do(async e =>
+ {
+ Message msg;
+
+ await e.Message.Delete();
+ if (!plantedFlowerChannels.TryRemove(e.Channel.Id, out msg))
+ return;
+
+ await msg.Delete();
+ await FlowersHandler.AddFlowersAsync(e.User, "Picked a flower.", 1, true);
+ msg = await e.Channel.SendMessage($"**{e.User.Name}** picked a {NadekoBot.Config.CurrencyName}!");
+ await Task.Delay(10000);
+ await msg.Delete();
+ });
+
+ cgb.CreateCommand(Module.Prefix + "plant")
+ .Description("Spend a flower to plant it in this channel. (If bot is restarted or crashes, flower will be lost)")
+ .Do(async e =>
+ {
+ lock (locker)
+ {
+ if (plantedFlowerChannels.ContainsKey(e.Channel.Id))
+ {
+ e.Channel.SendMessage($"There is already a {NadekoBot.Config.CurrencyName} in this channel.");
+ return;
+ }
+ var removed = FlowersHandler.RemoveFlowers(e.User, "Planted a flower.", 1);
+ if (!removed)
+ {
+ e.Channel.SendMessage($"You don't have any {NadekoBot.Config.CurrencyName}s.").Wait();
+ return;
+ }
+
+ var rng = new Random();
+ var file = Directory.GetFiles("data/currency_images").OrderBy(s => rng.Next()).FirstOrDefault();
+ Message msg;
+ if (file == null)
+ msg = e.Channel.SendMessage("πΈ").Result;
+ else
+ msg = e.Channel.SendFile(file).Result;
+ plantedFlowerChannels.TryAdd(e.Channel.Id, msg);
+ }
+
+ var msg2 = await e.Channel.SendMessage($"Oh how Nice! **{e.User.Name}** planted a flower. Pick it using {Module.Prefix}pick");
+ await Task.Delay(20000);
+ await msg2.Delete();
+ });
+ }
+ }
+}
diff --git a/NadekoBot/Modules/Administration/AdministrationModule.cs b/NadekoBot/Modules/Administration/AdministrationModule.cs
index cc07e6a1..1a0cbb29 100644
--- a/NadekoBot/Modules/Administration/AdministrationModule.cs
+++ b/NadekoBot/Modules/Administration/AdministrationModule.cs
@@ -228,6 +228,7 @@ namespace NadekoBot.Modules.Administration
try
{
await e.Server.Ban(usr);
+
await e.Channel.SendMessage("Banned user " + usr.Name + " Id: " + usr.Id);
}
catch
diff --git a/NadekoBot/Modules/ClashOfClans.cs b/NadekoBot/Modules/ClashOfClans.cs
index 17264553..2bc9ab42 100644
--- a/NadekoBot/Modules/ClashOfClans.cs
+++ b/NadekoBot/Modules/ClashOfClans.cs
@@ -1,16 +1,14 @@
-ο»Ώusing System;
-using System.Collections.Generic;
-using System.Text;
-using System.Threading.Tasks;
-using Discord.Commands;
-using System.Collections.Concurrent;
-using System.Linq;
-using System.Threading;
+ο»Ώusing Discord.Commands;
using Discord.Modules;
using NadekoBot.Classes.ClashOfClans;
using NadekoBot.Modules;
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Text;
-namespace NadekoBot.Commands {
+namespace NadekoBot.Commands
+{
internal class ClashOfClans : DiscordModule
{
public override string Prefix { get; } = NadekoBot.Config.CommandPrefixes.ClashOfClans;
@@ -19,8 +17,10 @@ namespace NadekoBot.Commands {
private readonly object writeLock = new object();
- public override void Install(ModuleManager manager) {
- manager.CreateCommands("", cgb => {
+ public override void Install(ModuleManager manager)
+ {
+ manager.CreateCommands("", cgb =>
+ {
cgb.CreateCommand(Prefix + "createwar")
.Alias(Prefix + "cw")
@@ -28,38 +28,48 @@ namespace NadekoBot.Commands {
$"Creates a new war by specifying a size (>10 and multiple of 5) and enemy clan name.\n**Usage**:{Prefix}cw 15 The Enemy Clan")
.Parameter("size")
.Parameter("enemy_clan", ParameterType.Unparsed)
- .Do(async e => {
+ .Do(async e =>
+ {
if (!e.User.ServerPermissions.ManageChannels)
return;
List wars;
- if (!ClashWars.TryGetValue(e.Server.Id, out wars)) {
+ if (!ClashWars.TryGetValue(e.Server.Id, out wars))
+ {
wars = new List();
if (!ClashWars.TryAdd(e.Server.Id, wars))
return;
}
var enemyClan = e.GetArg("enemy_clan");
- if (string.IsNullOrWhiteSpace(enemyClan)) {
+ if (string.IsNullOrWhiteSpace(enemyClan))
+ {
return;
}
int size;
- if (!int.TryParse(e.GetArg("size"), out size) || size < 10 || size > 50 || size % 5 != 0) {
+ if (!int.TryParse(e.GetArg("size"), out size) || size < 10 || size > 50 || size % 5 != 0)
+ {
await e.Channel.SendMessage("π’π° Not a Valid war size");
return;
}
var cw = new ClashWar(enemyClan, size, e);
//cw.Start();
wars.Add(cw);
- cw.OnUserTimeExpired += async (u) => {
- try {
+ cw.OnUserTimeExpired += async (u) =>
+ {
+ try
+ {
await
e.Channel.SendMessage(
$"βπ°**Claim from @{u} for a war against {cw.ShortPrint()} has expired.**");
- } catch { }
+ }
+ catch { }
};
- cw.OnWarEnded += async () => {
- try {
+ cw.OnWarEnded += async () =>
+ {
+ try
+ {
await e.Channel.SendMessage($"βπ°**War against {cw.ShortPrint()} ended.**");
- } catch { }
+ }
+ catch { }
};
await e.Channel.SendMessage($"βπ°**CREATED CLAN WAR AGAINST {cw.ShortPrint()}**");
//war with the index X started.
@@ -69,18 +79,23 @@ namespace NadekoBot.Commands {
.Alias(Prefix + "startwar")
.Description("Starts a war with a given number.")
.Parameter("number", ParameterType.Required)
- .Do(async e => {
+ .Do(async e =>
+ {
var warsInfo = GetInfo(e);
- if (warsInfo == null) {
+ if (warsInfo == null)
+ {
await e.Channel.SendMessage("π’π° **That war does not exist.**");
return;
}
var war = warsInfo.Item1[warsInfo.Item2];
- try {
+ try
+ {
var startTask = war.Start();
await e.Channel.SendMessage($"π°**STARTED WAR AGAINST {war.ShortPrint()}**");
await startTask;
- } catch {
+ }
+ catch
+ {
await e.Channel.SendMessage($"π°**WAR AGAINST {war.ShortPrint()} IS ALREADY STARTED**");
}
});
@@ -89,13 +104,16 @@ namespace NadekoBot.Commands {
.Alias(Prefix + "lw")
.Description($"Shows the active war claims by a number. Shows all wars in a short way if no number is specified.\n**Usage**: {Prefix}lw [war_number] or {Prefix}lw")
.Parameter("number", ParameterType.Optional)
- .Do(async e => {
+ .Do(async e =>
+ {
// if number is null, print all wars in a short way
- if (string.IsNullOrWhiteSpace(e.GetArg("number"))) {
+ if (string.IsNullOrWhiteSpace(e.GetArg("number")))
+ {
//check if there are any wars
List wars = null;
ClashWars.TryGetValue(e.Server.Id, out wars);
- if (wars == null || wars.Count == 0) {
+ if (wars == null || wars.Count == 0)
+ {
await e.Channel.SendMessage("π° **No active wars.**");
return;
}
@@ -103,7 +121,8 @@ namespace NadekoBot.Commands {
var sb = new StringBuilder();
sb.AppendLine("π° **LIST OF ACTIVE WARS**");
sb.AppendLine("**-------------------------**");
- for (var i = 0; i < wars.Count; i++) {
+ for (var i = 0; i < wars.Count; i++)
+ {
sb.AppendLine($"**#{i + 1}.** `Enemy:` **{wars[i].EnemyClan}**");
sb.AppendLine($"\t\t`Size:` **{wars[i].Size} v {wars[i].Size}**");
sb.AppendLine("**-------------------------**");
@@ -113,7 +132,8 @@ namespace NadekoBot.Commands {
}
//if number is not null, print the war needed
var warsInfo = GetInfo(e);
- if (warsInfo == null) {
+ if (warsInfo == null)
+ {
await e.Channel.SendMessage("π’π° **That war does not exist.**");
return;
}
@@ -127,14 +147,17 @@ namespace NadekoBot.Commands {
.Parameter("number")
.Parameter("baseNumber")
.Parameter("other_name", ParameterType.Unparsed)
- .Do(async e => {
+ .Do(async e =>
+ {
var warsInfo = GetInfo(e);
- if (warsInfo == null || warsInfo.Item1.Count == 0) {
+ if (warsInfo == null || warsInfo.Item1.Count == 0)
+ {
await e.Channel.SendMessage("π’π° **That war does not exist.**");
return;
}
int baseNum;
- if (!int.TryParse(e.GetArg("baseNumber"), out baseNum)) {
+ if (!int.TryParse(e.GetArg("baseNumber"), out baseNum))
+ {
await e.Channel.SendMessage("π’π° **Invalid base number.**");
return;
}
@@ -142,11 +165,14 @@ namespace NadekoBot.Commands {
string.IsNullOrWhiteSpace(e.GetArg("other_name")) ?
e.User.Name :
e.GetArg("other_name");
- try {
+ try
+ {
var war = warsInfo.Item1[warsInfo.Item2];
war.Call(usr, baseNum - 1);
await e.Channel.SendMessage($"π°**{usr}** claimed a base #{baseNum} for a war against {war.ShortPrint()}");
- } catch (Exception ex) {
+ }
+ catch (Exception ex)
+ {
await e.Channel.SendMessage($"π’π° {ex.Message}");
}
});
@@ -156,9 +182,11 @@ namespace NadekoBot.Commands {
.Description($"Finish your claim if you destroyed a base. Optional second argument finishes for someone else.\n**Usage**: {Prefix}cf [war_number] [optional_other_name]")
.Parameter("number", ParameterType.Required)
.Parameter("other_name", ParameterType.Unparsed)
- .Do(async e => {
+ .Do(async e =>
+ {
var warInfo = GetInfo(e);
- if (warInfo == null || warInfo.Item1.Count == 0) {
+ if (warInfo == null || warInfo.Item1.Count == 0)
+ {
await e.Channel.SendMessage("π’π° **That war does not exist.**");
return;
}
@@ -168,10 +196,13 @@ namespace NadekoBot.Commands {
e.GetArg("other_name");
var war = warInfo.Item1[warInfo.Item2];
- try {
+ try
+ {
var baseNum = war.FinishClaim(usr);
await e.Channel.SendMessage($"βπ°{e.User.Mention} **DESTROYED** a base #{baseNum + 1} in a war against {war.ShortPrint()}");
- } catch (Exception ex) {
+ }
+ catch (Exception ex)
+ {
await e.Channel.SendMessage($"π’π° {ex.Message}");
}
});
@@ -182,9 +213,11 @@ namespace NadekoBot.Commands {
.Description($"Removes your claim from a certain war. Optional second argument denotes a person in whos place to unclaim\n**Usage**: {Prefix}uc [war_number] [optional_other_name]")
.Parameter("number", ParameterType.Required)
.Parameter("other_name", ParameterType.Unparsed)
- .Do(async e => {
+ .Do(async e =>
+ {
var warsInfo = GetInfo(e);
- if (warsInfo == null || warsInfo.Item1.Count == 0) {
+ if (warsInfo == null || warsInfo.Item1.Count == 0)
+ {
await e.Channel.SendMessage("π’π° **That war does not exist.**");
return;
}
@@ -192,11 +225,14 @@ namespace NadekoBot.Commands {
string.IsNullOrWhiteSpace(e.GetArg("other_name")) ?
e.User.Name :
e.GetArg("other_name");
- try {
+ try
+ {
var war = warsInfo.Item1[warsInfo.Item2];
var baseNumber = war.Uncall(usr);
await e.Channel.SendMessage($"π° @{usr} has **UNCLAIMED** a base #{baseNumber + 1} from a war against {war.ShortPrint()}");
- } catch (Exception ex) {
+ }
+ catch (Exception ex)
+ {
await e.Channel.SendMessage($"π’π° {ex.Message}");
}
});
@@ -205,9 +241,11 @@ namespace NadekoBot.Commands {
.Alias(Prefix + "ew")
.Description($"Ends the war with a given index.\n**Usage**:{Prefix}ew [war_number]")
.Parameter("number")
- .Do(async e => {
+ .Do(async e =>
+ {
var warsInfo = GetInfo(e);
- if (warsInfo == null) {
+ if (warsInfo == null)
+ {
await e.Channel.SendMessage("π’π° That war does not exist.");
return;
}
@@ -219,18 +257,21 @@ namespace NadekoBot.Commands {
});
}
- private static Tuple, int> GetInfo(CommandEventArgs e) {
+ private static Tuple, int> GetInfo(CommandEventArgs e)
+ {
//check if there are any wars
List wars = null;
ClashWars.TryGetValue(e.Server.Id, out wars);
- if (wars == null || wars.Count == 0) {
+ if (wars == null || wars.Count == 0)
+ {
return null;
}
// get the number of the war
int num;
if (string.IsNullOrWhiteSpace(e.GetArg("number")))
num = 0;
- else if (!int.TryParse(e.GetArg("number"), out num) || num > wars.Count) {
+ else if (!int.TryParse(e.GetArg("number"), out num) || num > wars.Count)
+ {
return null;
}
num -= 1;
diff --git a/NadekoBot/Modules/Gambling/GamblingModule.cs b/NadekoBot/Modules/Gambling/GamblingModule.cs
index 911fd367..8fe25f16 100644
--- a/NadekoBot/Modules/Gambling/GamblingModule.cs
+++ b/NadekoBot/Modules/Gambling/GamblingModule.cs
@@ -63,7 +63,7 @@ namespace NadekoBot.Modules.Gambling
return;
}
- await FlowersHandler.RemoveFlowersAsync(e.User, "Gift", (int)amount);
+ FlowersHandler.RemoveFlowers(e.User, "Gift", (int)amount);
await FlowersHandler.AddFlowersAsync(mentionedUser, "Gift", (int)amount);
await e.Channel.SendMessage($"{e.User.Mention} successfully sent {amount} {NadekoBot.Config.CurrencyName}s to {mentionedUser.Mention}!");
@@ -109,7 +109,7 @@ namespace NadekoBot.Modules.Gambling
if (mentionedUser == null)
return;
- await FlowersHandler.RemoveFlowersAsync(mentionedUser, $"Taken by bot owner.({e.User.Name}/{e.User.Id})", (int)amount);
+ FlowersHandler.RemoveFlowers(mentionedUser, $"Taken by bot owner.({e.User.Name}/{e.User.Id})", (int)amount);
await e.Channel.SendMessage($"{e.User.Mention} successfully took {amount} {NadekoBot.Config.CurrencyName}s from {mentionedUser.Mention}!");
});
diff --git a/NadekoBot/Modules/Games.cs b/NadekoBot/Modules/Games.cs
index 508a0603..6d2e39c7 100644
--- a/NadekoBot/Modules/Games.cs
+++ b/NadekoBot/Modules/Games.cs
@@ -16,6 +16,7 @@ namespace NadekoBot.Modules
commands.Add(new Trivia(this));
commands.Add(new SpeedTyping(this));
commands.Add(new PollCommand(this));
+ commands.Add(new PlantPick(this));
//commands.Add(new BetrayGame(this));
}
diff --git a/NadekoBot/Modules/Pokemon/PokemonModule.cs b/NadekoBot/Modules/Pokemon/PokemonModule.cs
index 11db1f23..285fceb5 100644
--- a/NadekoBot/Modules/Pokemon/PokemonModule.cs
+++ b/NadekoBot/Modules/Pokemon/PokemonModule.cs
@@ -225,7 +225,7 @@ namespace NadekoBot.Modules.Pokemon
return;
}
var target = (usr.Id == e.User.Id) ? "yourself" : usr.Name;
- await FlowersHandler.RemoveFlowersAsync(e.User, $"Poke-Heal {target}", amount);
+ FlowersHandler.RemoveFlowers(e.User, $"Poke-Heal {target}", amount);
//healing
targetStats.Hp = targetStats.MaxHp;
if (HP < 0)
@@ -285,13 +285,13 @@ namespace NadekoBot.Modules.Pokemon
//Payment~
var amount = 1;
- var pts = Classes.DbHandler.Instance.GetStateByUserId((long)e.User.Id)?.Value ?? 0;
+ var pts = DbHandler.Instance.GetStateByUserId((long)e.User.Id)?.Value ?? 0;
if (pts < amount)
{
await e.Channel.SendMessage($"{e.User.Mention} you don't have enough NadekoFlowers! \nYou still need {amount - pts} to be able to do this!");
return;
}
- await FlowersHandler.RemoveFlowersAsync(e.User, $"set usertype to {targetTypeStr}", amount);
+ FlowersHandler.RemoveFlowers(e.User, $"set usertype to {targetTypeStr}", amount);
//Actually changing the type here
var preTypes = DbHandler.Instance.GetAllRows();
Dictionary Dict = preTypes.ToDictionary(x => x.UserId, y => y.Id);
diff --git a/NadekoBot/NadekoBot.csproj b/NadekoBot/NadekoBot.csproj
index dcd4fa07..f5960d68 100644
--- a/NadekoBot/NadekoBot.csproj
+++ b/NadekoBot/NadekoBot.csproj
@@ -9,7 +9,7 @@
Properties
NadekoBot
NadekoBot
- v4.5.2
+ v4.6
512
true
false
@@ -32,6 +32,7 @@
true
+
AnyCPU
@@ -151,6 +152,7 @@
+
diff --git a/NadekoBot/packages.config b/NadekoBot/packages.config
index ec861bf0..19d0d51d 100644
--- a/NadekoBot/packages.config
+++ b/NadekoBot/packages.config
@@ -9,7 +9,7 @@
-
+
diff --git a/Tests/Tests.csproj b/Tests/Tests.csproj
index d83b8b1a..0ddc6cc5 100644
--- a/Tests/Tests.csproj
+++ b/Tests/Tests.csproj
@@ -8,7 +8,7 @@
Properties
Tests
Tests
- v4.5.2
+ v4.6
512
{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
10.0