From c8c930e52b9209ed6351b0683a839d1bcd123f42 Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Fri, 11 Mar 2016 20:13:48 +0100 Subject: [PATCH] only actual externalization left. Trivia is now >t --- .../Classes/ClashOfClans/ClashOfClans.cs | 146 +++++++ NadekoBot/Commands/ClashOfClans.cs | 374 ------------------ NadekoBot/Commands/DiceRollCommand.cs | 4 +- NadekoBot/Commands/DrawCommand.cs | 6 +- NadekoBot/Commands/FilterInvitesCommand.cs | 8 +- NadekoBot/Commands/FlipCoinCommand.cs | 2 +- NadekoBot/Commands/HelpCommand.cs | 12 +- NadekoBot/Commands/LoLCommands.cs | 4 +- NadekoBot/Commands/LogCommand.cs | 6 +- NadekoBot/Commands/MessageRepeater.cs | 2 +- NadekoBot/Commands/PlayingRotate.cs | 16 +- NadekoBot/Commands/PollCommand.cs | 4 +- NadekoBot/Commands/RatelimitCommand.cs | 2 +- NadekoBot/Commands/ServerGreetCommand.cs | 12 +- NadekoBot/Commands/SpeedTyping.cs | 6 +- NadekoBot/Commands/TriviaCommand.cs | 11 +- .../Commands/VoiceNotificationCommand.cs | 6 +- NadekoBot/Commands/VoicePlusTextCommand.cs | 4 +- NadekoBot/Modules/ClashOfClans.cs | 241 +++++++++++ NadekoBot/Modules/Gambling.cs | 4 +- NadekoBot/Modules/Games.cs | 3 - NadekoBot/Modules/Help.cs | 8 +- NadekoBot/Modules/Music.cs | 4 +- NadekoBot/NadekoBot.cs | 1 + 24 files changed, 445 insertions(+), 441 deletions(-) create mode 100644 NadekoBot/Classes/ClashOfClans/ClashOfClans.cs delete mode 100644 NadekoBot/Commands/ClashOfClans.cs create mode 100644 NadekoBot/Modules/ClashOfClans.cs diff --git a/NadekoBot/Classes/ClashOfClans/ClashOfClans.cs b/NadekoBot/Classes/ClashOfClans/ClashOfClans.cs new file mode 100644 index 00000000..49921681 --- /dev/null +++ b/NadekoBot/Classes/ClashOfClans/ClashOfClans.cs @@ -0,0 +1,146 @@ +ο»Ώusing System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Discord.Commands; + +namespace NadekoBot.Classes.ClashOfClans { + internal class Caller { + public string CallUser { get; } + + public DateTime TimeAdded { get; private set; } + + public bool BaseDestroyed { get; internal set; } + + public Caller(string callUser, DateTime timeAdded, bool baseDestroyed) { + CallUser = callUser; + TimeAdded = timeAdded; + BaseDestroyed = baseDestroyed; + } + + public void ResetTime() { + TimeAdded = DateTime.Now; + } + + public void Destroy() { + BaseDestroyed = true; + } + } + + internal class ClashWar { + private static TimeSpan callExpire => new TimeSpan(2, 0, 0); + + private CommandEventArgs e; + public string EnemyClan { get; } + public int Size { get; } + + private Caller[] bases { get; } + private CancellationTokenSource[] baseCancelTokens; + private CancellationTokenSource endTokenSource { get; } = new CancellationTokenSource(); + public event Action OnUserTimeExpired = delegate { }; + public event Action OnWarEnded = delegate { }; + public bool Started { get; set; } = false; + + public ClashWar(string enemyClan, int size, CommandEventArgs e) { + this.EnemyClan = enemyClan; + this.Size = size; + this.bases = new Caller[size]; + this.baseCancelTokens = new CancellationTokenSource[size]; + } + + internal void End() { + if (endTokenSource.Token.IsCancellationRequested) return; + endTokenSource.Cancel(); + OnWarEnded(); + } + + internal void Call(string u, int baseNumber) { + if (baseNumber < 0 || baseNumber >= bases.Length) + throw new ArgumentException("Invalid base number"); + if (bases[baseNumber] != null) + throw new ArgumentException("That base is already claimed."); + for (var i = 0; i < bases.Length; i++) { + if (bases[i]?.BaseDestroyed == false && bases[i]?.CallUser == u) + throw new ArgumentException($"@{u} You already claimed a base #{i + 1}. You can't claim a new one."); + } + + bases[baseNumber] = new Caller(u.Trim(), DateTime.Now, false); + } + + internal async Task Start() { + if (Started) + throw new InvalidOperationException(); + try { + Started = true; + foreach (var b in bases.Where(b => b != null)) { + b.ResetTime(); + } + Task.Run(async () => await ClearArray()).ConfigureAwait(false); + await Task.Delay(new TimeSpan(24, 0, 0), endTokenSource.Token); + } catch { } finally { + End(); + } + } + internal int Uncall(string user) { + user = user.Trim(); + for (var i = 0; i < bases.Length; i++) { + if (bases[i]?.CallUser != user) continue; + bases[i] = null; + return i; + } + throw new InvalidOperationException("You are not participating in that war."); + } + + private async Task ClearArray() { + while (!endTokenSource.IsCancellationRequested) { + await Task.Delay(5000); + for (var i = 0; i < bases.Length; i++) { + if (bases[i] == null) continue; + if (!bases[i].BaseDestroyed && DateTime.Now - bases[i].TimeAdded >= callExpire) { + Console.WriteLine($"Removing user {bases[i].CallUser}"); + OnUserTimeExpired(bases[i].CallUser); + bases[i] = null; + } + } + } + Console.WriteLine("Out of clear array"); + } + + public string ShortPrint() => + $"`{EnemyClan}` ({Size} v {Size})"; + + public override string ToString() { + var sb = new StringBuilder(); + + sb.AppendLine($"πŸ”°**WAR AGAINST `{EnemyClan}` ({Size} v {Size}) INFO:**"); + if (!Started) + sb.AppendLine("`not started`"); + for (var i = 0; i < bases.Length; i++) { + if (bases[i] == null) { + sb.AppendLine($"`{i + 1}.` ❌*unclaimed*"); + } else { + if (bases[i].BaseDestroyed) { + sb.AppendLine($"`{i + 1}.` βœ… `{bases[i].CallUser}` ⭐ ⭐ ⭐"); + } else { + var left = Started ? callExpire - (DateTime.Now - bases[i].TimeAdded) : callExpire; + sb.AppendLine($"`{i + 1}.` βœ… `{bases[i].CallUser}` {left.Hours}h {left.Minutes}m {left.Seconds}s left"); + } + } + + } + return sb.ToString(); + } + + internal int FinishClaim(string user) { + user = user.Trim(); + for (var i = 0; i < bases.Length; i++) { + if (bases[i]?.BaseDestroyed != false || bases[i]?.CallUser != user) continue; + bases[i].BaseDestroyed = true; + return i; + } + throw new InvalidOperationException($"@{user} You are either not participating in that war, or you already destroyed a base."); + } + } +} diff --git a/NadekoBot/Commands/ClashOfClans.cs b/NadekoBot/Commands/ClashOfClans.cs deleted file mode 100644 index 7c09ad1d..00000000 --- a/NadekoBot/Commands/ClashOfClans.cs +++ /dev/null @@ -1,374 +0,0 @@ -ο»Ώ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 NadekoBot.Modules; - -namespace NadekoBot.Commands { - internal class ClashOfClans : DiscordCommand { - private const string prefix = ","; - - public static ConcurrentDictionary> ClashWars { get; } = new ConcurrentDictionary>(); - - private readonly object writeLock = new object(); - - public ClashOfClans(DiscordModule module) : base(module) { } - - public Func DoFunc() => async e => { - if (!e.User.ServerPermissions.ManageChannels) - return; - List 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)) { - return; - } - int size; - 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 { - await - e.Channel.SendMessage($"β—πŸ”°**Claim from @{u} for a war against {cw.ShortPrint()} has expired.**"); - } catch { } - }; - cw.OnWarEnded += async () => { - try { - await e.Channel.SendMessage($"β—πŸ”°**War against {cw.ShortPrint()} ended.**"); - } catch { } - }; - await e.Channel.SendMessage($"β—πŸ”°**CREATED CLAN WAR AGAINST {cw.ShortPrint()}**"); - //war with the index X started. - }; - - internal override void Init(CommandGroupBuilder cgb) { - cgb.CreateCommand(prefix + "createwar") - .Alias(prefix + "cw") - .Description($"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(DoFunc()); - - cgb.CreateCommand(prefix + "sw") - .Alias(prefix + "startwar") - .Description("Starts a war with a given number.") - .Parameter("number", ParameterType.Required) - .Do(async e => { - var warsInfo = GetInfo(e); - if (warsInfo == null) { - await e.Channel.SendMessage("πŸ’’πŸ”° **That war does not exist.**"); - return; - } - var war = warsInfo.Item1[warsInfo.Item2]; - try { - var startTask = war.Start(); - await e.Channel.SendMessage($"πŸ”°**STARTED WAR AGAINST {war.ShortPrint()}**"); - await startTask; - } catch { - await e.Channel.SendMessage($"πŸ”°**WAR AGAINST {war.ShortPrint()} IS ALREADY STARTED**"); - } - }); - - cgb.CreateCommand(prefix + "listwar") - .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 => { - // if number is null, print all wars in a short way - 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) { - await e.Channel.SendMessage("πŸ”° **No active wars.**"); - return; - } - - var sb = new StringBuilder(); - sb.AppendLine("πŸ”° **LIST OF ACTIVE WARS**"); - sb.AppendLine("**-------------------------**"); - 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("**-------------------------**"); - } - await e.Channel.SendMessage(sb.ToString()); - return; - } - //if number is not null, print the war needed - var warsInfo = GetInfo(e); - if (warsInfo == null) { - await e.Channel.SendMessage("πŸ’’πŸ”° **That war does not exist.**"); - return; - } - await e.Channel.SendMessage(warsInfo.Item1[warsInfo.Item2].ToString()); - }); - - cgb.CreateCommand(prefix + "claim") - .Alias(prefix + "call") - .Alias(prefix + "c") - .Description($"Claims a certain base from a certain war. You can supply a name in the third optional argument to claim in someone else's place. \n**Usage**: {prefix}call [war_number] [base_number] (optional_otheruser)") - .Parameter("number") - .Parameter("baseNumber") - .Parameter("other_name", ParameterType.Unparsed) - .Do(async e => { - var warsInfo = GetInfo(e); - 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)) { - await e.Channel.SendMessage("πŸ’’πŸ”° **Invalid base number.**"); - return; - } - var usr = - string.IsNullOrWhiteSpace(e.GetArg("other_name")) ? - e.User.Name : - e.GetArg("other_name"); - 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) { - await e.Channel.SendMessage($"πŸ’’πŸ”° {ex.Message}"); - } - }); - - cgb.CreateCommand(prefix + "cf") - .Alias(prefix + "claimfinish") - .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 => { - var warInfo = GetInfo(e); - if (warInfo == null || warInfo.Item1.Count == 0) { - await e.Channel.SendMessage("πŸ’’πŸ”° **That war does not exist.**"); - return; - } - var usr = - string.IsNullOrWhiteSpace(e.GetArg("other_name")) ? - e.User.Name : - e.GetArg("other_name"); - - var war = warInfo.Item1[warInfo.Item2]; - 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) { - await e.Channel.SendMessage($"πŸ’’πŸ”° {ex.Message}"); - } - }); - - cgb.CreateCommand(prefix + "unclaim") - .Alias(prefix + "uncall") - .Alias(prefix + "uc") - .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 => { - var warsInfo = GetInfo(e); - if (warsInfo == null || warsInfo.Item1.Count == 0) { - await e.Channel.SendMessage("πŸ’’πŸ”° **That war does not exist.**"); - return; - } - var usr = - string.IsNullOrWhiteSpace(e.GetArg("other_name")) ? - e.User.Name : - e.GetArg("other_name"); - 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) { - await e.Channel.SendMessage($"πŸ’’πŸ”° {ex.Message}"); - } - }); - - cgb.CreateCommand(prefix + "endwar") - .Alias(prefix + "ew") - .Description($"Ends the war with a given index.\n**Usage**:{prefix}ew [war_number]") - .Parameter("number") - .Do(async e => { - var warsInfo = GetInfo(e); - if (warsInfo == null) { - await e.Channel.SendMessage("πŸ’’πŸ”° That war does not exist."); - return; - } - warsInfo.Item1[warsInfo.Item2].End(); - - var size = warsInfo.Item1[warsInfo.Item2].Size; - warsInfo.Item1.RemoveAt(warsInfo.Item2); - }); - } - - 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) { - 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) { - return null; - } - num -= 1; - //get the actual war - return new Tuple, int>(wars, num); - } - } - - internal class Caller { - public string CallUser { get; } - - public DateTime TimeAdded { get; private set; } - - public bool BaseDestroyed { get; internal set; } - - public Caller(string callUser, DateTime timeAdded, bool baseDestroyed) { - CallUser = callUser; - TimeAdded = timeAdded; - BaseDestroyed = baseDestroyed; - } - - public void ResetTime() { - TimeAdded = DateTime.Now; - } - - public void Destroy() { - BaseDestroyed = true; - } - } - - internal class ClashWar { - private static TimeSpan callExpire => new TimeSpan(2, 0, 0); - - private CommandEventArgs e; - public string EnemyClan { get; } - public int Size { get; } - - private Caller[] bases { get; } - private CancellationTokenSource[] baseCancelTokens; - private CancellationTokenSource endTokenSource { get; } = new CancellationTokenSource(); - public event Action OnUserTimeExpired = delegate { }; - public event Action OnWarEnded = delegate { }; - public bool Started { get; set; } = false; - - public ClashWar(string enemyClan, int size, CommandEventArgs e) { - this.EnemyClan = enemyClan; - this.Size = size; - this.bases = new Caller[size]; - this.baseCancelTokens = new CancellationTokenSource[size]; - } - - internal void End() { - if (endTokenSource.Token.IsCancellationRequested) return; - endTokenSource.Cancel(); - OnWarEnded(); - } - - internal void Call(string u, int baseNumber) { - if (baseNumber < 0 || baseNumber >= bases.Length) - throw new ArgumentException("Invalid base number"); - if (bases[baseNumber] != null) - throw new ArgumentException("That base is already claimed."); - for (var i = 0; i < bases.Length; i++) { - if (bases[i]?.BaseDestroyed == false && bases[i]?.CallUser == u) - throw new ArgumentException($"@{u} You already claimed a base #{i + 1}. You can't claim a new one."); - } - - bases[baseNumber] = new Caller(u.Trim(), DateTime.Now, false); - } - - internal async Task Start() { - if (Started) - throw new InvalidOperationException(); - try { - Started = true; - foreach (var b in bases.Where(b => b != null)) { - b.ResetTime(); - } - Task.Run(async () => await ClearArray()).ConfigureAwait(false); - await Task.Delay(new TimeSpan(24, 0, 0), endTokenSource.Token); - } catch { } finally { - End(); - } - } - internal int Uncall(string user) { - user = user.Trim(); - for (var i = 0; i < bases.Length; i++) { - if (bases[i]?.CallUser != user) continue; - bases[i] = null; - return i; - } - throw new InvalidOperationException("You are not participating in that war."); - } - - private async Task ClearArray() { - while (!endTokenSource.IsCancellationRequested) { - await Task.Delay(5000); - for (var i = 0; i < bases.Length; i++) { - if (bases[i] == null) continue; - if (!bases[i].BaseDestroyed && DateTime.Now - bases[i].TimeAdded >= callExpire) { - Console.WriteLine($"Removing user {bases[i].CallUser}"); - OnUserTimeExpired(bases[i].CallUser); - bases[i] = null; - } - } - } - Console.WriteLine("Out of clear array"); - } - - public string ShortPrint() => - $"`{EnemyClan}` ({Size} v {Size})"; - - public override string ToString() { - var sb = new StringBuilder(); - - sb.AppendLine($"πŸ”°**WAR AGAINST `{EnemyClan}` ({Size} v {Size}) INFO:**"); - if (!Started) - sb.AppendLine("`not started`"); - for (var i = 0; i < bases.Length; i++) { - if (bases[i] == null) { - sb.AppendLine($"`{i + 1}.` ❌*unclaimed*"); - } else { - if (bases[i].BaseDestroyed) { - sb.AppendLine($"`{i + 1}.` βœ… `{bases[i].CallUser}` ⭐ ⭐ ⭐"); - } else { - var left = Started ? callExpire - (DateTime.Now - bases[i].TimeAdded) : callExpire; - sb.AppendLine($"`{i + 1}.` βœ… `{bases[i].CallUser}` {left.Hours}h {left.Minutes}m {left.Seconds}s left"); - } - } - - } - return sb.ToString(); - } - - internal int FinishClaim(string user) { - user = user.Trim(); - for (var i = 0; i < bases.Length; i++) { - if (bases[i]?.BaseDestroyed != false || bases[i]?.CallUser != user) continue; - bases[i].BaseDestroyed = true; - return i; - } - throw new InvalidOperationException($"@{user} You are either not participating in that war, or you already destroyed a base."); - } - } -} diff --git a/NadekoBot/Commands/DiceRollCommand.cs b/NadekoBot/Commands/DiceRollCommand.cs index 4a8a6018..7f7c3c09 100644 --- a/NadekoBot/Commands/DiceRollCommand.cs +++ b/NadekoBot/Commands/DiceRollCommand.cs @@ -69,11 +69,11 @@ namespace NadekoBot.Commands { private Image GetDice(int num) => Properties.Resources.ResourceManager.GetObject("_" + num) as Image; internal override void Init(CommandGroupBuilder cgb) { - cgb.CreateCommand("$roll") + cgb.CreateCommand(Module.Prefix + "roll") .Description("Rolls 2 dice from 0-10. If you supply a number [x] it rolls up to 30 normal dice.\n**Usage**: $roll [x]") .Parameter("num", ParameterType.Optional) .Do(DoFunc()); - cgb.CreateCommand("$nroll") + cgb.CreateCommand(Module.Prefix + "nroll") .Description("Rolls in a given range.\n**Usage**: `$nroll 5` (rolls 0-5) or `$nroll 5-15`") .Parameter("range", ParameterType.Required) .Do(NDoFunc()); diff --git a/NadekoBot/Commands/DrawCommand.cs b/NadekoBot/Commands/DrawCommand.cs index 7c1cb5ce..2bbd618b 100644 --- a/NadekoBot/Commands/DrawCommand.cs +++ b/NadekoBot/Commands/DrawCommand.cs @@ -47,13 +47,13 @@ namespace NadekoBot.Commands { }; internal override void Init(CommandGroupBuilder cgb) { - cgb.CreateCommand("$draw") + cgb.CreateCommand(Module.Prefix + "draw") .Description("Draws a card from the deck.If you supply number [x], she draws up to 5 cards from the deck.\n**Usage**: $draw [x]") .Parameter("count", ParameterType.Optional) .Do(DoFunc()); - cgb.CreateCommand("$shuffle") - .Alias("$reshuffle") + cgb.CreateCommand(Module.Prefix + "shuffle") + .Alias(Module.Prefix + "sh") .Description("Reshuffles all cards back into the deck.") .Do(async e => { AllDecks.AddOrUpdate(e.Server, diff --git a/NadekoBot/Commands/FilterInvitesCommand.cs b/NadekoBot/Commands/FilterInvitesCommand.cs index 0848340a..e5342b77 100644 --- a/NadekoBot/Commands/FilterInvitesCommand.cs +++ b/NadekoBot/Commands/FilterInvitesCommand.cs @@ -41,8 +41,8 @@ namespace NadekoBot.Commands { } internal override void Init(CommandGroupBuilder cgb) { - cgb.CreateCommand(";cfi") - .Alias(";channelfilterinvites") + cgb.CreateCommand(Module.Prefix + "cfi") + .Alias(Module.Prefix + "channelfilterinvites") .Description("Enables or disables automatic deleting of invites on the channel." + "If no channel supplied, it will default to current one. Use ALL to apply to all existing channels at once." + "\n**Usage**: ;cfi enable #general-chat") @@ -74,8 +74,8 @@ namespace NadekoBot.Commands { } }); - cgb.CreateCommand(";sfi") - .Alias(";serverfilterinvites") + cgb.CreateCommand(Module.Prefix + "sfi") + .Alias(Module.Prefix + "serverfilterinvites") .Description("Enables or disables automatic deleting of invites on the server.\n**Usage**: ;sfi disable") .Parameter("bool") .Do(async e => { diff --git a/NadekoBot/Commands/FlipCoinCommand.cs b/NadekoBot/Commands/FlipCoinCommand.cs index eea3b385..389f6197 100644 --- a/NadekoBot/Commands/FlipCoinCommand.cs +++ b/NadekoBot/Commands/FlipCoinCommand.cs @@ -36,7 +36,7 @@ namespace NadekoBot.Commands { }; internal override void Init(CommandGroupBuilder cgb) { - cgb.CreateCommand("$flip") + cgb.CreateCommand(Module.Prefix + "flip") .Description("Flips coin(s) - heads or tails, and shows an image.\n**Usage**: `$flip` or `$flip 3`") .Parameter("count", ParameterType.Optional) .Do(DoFunc()); diff --git a/NadekoBot/Commands/HelpCommand.cs b/NadekoBot/Commands/HelpCommand.cs index 2ebfa359..2395656d 100644 --- a/NadekoBot/Commands/HelpCommand.cs +++ b/NadekoBot/Commands/HelpCommand.cs @@ -80,17 +80,17 @@ Version: `{NadekoStats.Instance.BotVersion}`"; }; internal override void Init(CommandGroupBuilder cgb) { - cgb.CreateCommand("-h") - .Alias(new string[] { "-help", NadekoBot.BotMention + " help", NadekoBot.BotMention + " h", "~h" }) + cgb.CreateCommand(Module.Prefix + "h") + .Alias(Module.Prefix + "help", NadekoBot.BotMention + " help", NadekoBot.BotMention + " h", "~h") .Description("Either shows a help for a single command, or PMs you help link if no arguments are specified.\n**Usage**: '-h !m q' or just '-h' ") .Parameter("command", ParameterType.Unparsed) .Do(DoFunc()); - cgb.CreateCommand("-hgit") + cgb.CreateCommand(Module.Prefix + "hgit") .Description("OWNER ONLY commandlist.md file generation.") .AddCheck(Classes.Permissions.SimpleCheckers.OwnerOnly()) .Do(DoGitFunc()); - cgb.CreateCommand("-readme") - .Alias("-guide") + cgb.CreateCommand(Module.Prefix + "readme") + .Alias(Module.Prefix + "guide") .Description("Sends a readme and a guide links to the channel.") .Do(async e => await e.Channel.SendMessage( @@ -100,7 +100,7 @@ Version: `{NadekoStats.Instance.BotVersion}`"; **LIST OF COMMANDS**: ")); - cgb.CreateCommand("-donate") + cgb.CreateCommand(Module.Prefix + "donate") .Alias("~donate") .Description("Instructions for helping the project!") .Do(async e => { diff --git a/NadekoBot/Commands/LoLCommands.cs b/NadekoBot/Commands/LoLCommands.cs index a0105c23..45d044f3 100644 --- a/NadekoBot/Commands/LoLCommands.cs +++ b/NadekoBot/Commands/LoLCommands.cs @@ -57,7 +57,7 @@ namespace NadekoBot.Commands { } internal override void Init(CommandGroupBuilder cgb) { - cgb.CreateCommand("~lolchamp") + cgb.CreateCommand(Module.Prefix + "lolchamp") .Description("Shows League Of Legends champion statistics. If there are spaces/apostrophes or in the name - omit them. Optional second parameter is a role.\n**Usage**:~lolchamp Riven or ~lolchamp Annie sup") .Parameter("champ", ParameterType.Required) .Parameter("position", ParameterType.Unparsed) @@ -244,7 +244,7 @@ Assists: {general["assists"]} Ban: {general["banRate"]}% } }); - cgb.CreateCommand("~lolban") + cgb.CreateCommand(Module.Prefix + "lolban") .Description("Shows top 6 banned champions ordered by ban rate. Ban these champions and you will be Plat 5 in no time.") .Do(async e => { diff --git a/NadekoBot/Commands/LogCommand.cs b/NadekoBot/Commands/LogCommand.cs index 5df08ac9..d56a8e66 100644 --- a/NadekoBot/Commands/LogCommand.cs +++ b/NadekoBot/Commands/LogCommand.cs @@ -122,11 +122,11 @@ namespace NadekoBot.Commands { internal override void Init(CommandGroupBuilder cgb) { - cgb.CreateCommand(".logserver") + cgb.CreateCommand(Module.Prefix + "logserver") .Description("Toggles logging in this channel. Logs every message sent/deleted/edited on the server. BOT OWNER ONLY. SERVER OWNER ONLY.") .Do(DoFunc()); - cgb.CreateCommand(".userpresence") + cgb.CreateCommand(Module.Prefix + "userpresence") .Description("Starts logging to this channel when someone from the server goes online/offline/idle. BOT OWNER ONLY. SERVER OWNER ONLY.") .Do(async e => { if (!NadekoBot.IsOwner(e.User.Id) || @@ -142,7 +142,7 @@ namespace NadekoBot.Commands { await e.Channel.SendMessage($"**User presence notifications disabled.**"); }); - cgb.CreateCommand(".voicepresence") + cgb.CreateCommand(Module.Prefix + "voicepresence") .Description("Toggles logging to this channel whenever someone joins or leaves a voice channel you are in right now. BOT OWNER ONLY. SERVER OWNER ONLY.") .Parameter("all", ParameterType.Optional) .Do(async e => { diff --git a/NadekoBot/Commands/MessageRepeater.cs b/NadekoBot/Commands/MessageRepeater.cs index f726ea94..9ef5d5bd 100644 --- a/NadekoBot/Commands/MessageRepeater.cs +++ b/NadekoBot/Commands/MessageRepeater.cs @@ -36,7 +36,7 @@ namespace NadekoBot.Commands { } internal override void Init(CommandGroupBuilder cgb) { - cgb.CreateCommand(".repeat") + cgb.CreateCommand(Module.Prefix + "repeat") .Description("Repeat a message every X minutes. If no parameters are specified, " + "repeat is disabled. Requires manage messages.") .Parameter("minutes", ParameterType.Optional) diff --git a/NadekoBot/Commands/PlayingRotate.cs b/NadekoBot/Commands/PlayingRotate.cs index dc62d2e9..f2ed46e9 100644 --- a/NadekoBot/Commands/PlayingRotate.cs +++ b/NadekoBot/Commands/PlayingRotate.cs @@ -73,14 +73,14 @@ namespace NadekoBot.Commands { }; internal override void Init(CommandGroupBuilder cgb) { - cgb.CreateCommand(".rotateplaying") - .Alias(".ropl") + cgb.CreateCommand(Module.Prefix + "rotateplaying") + .Alias(Module.Prefix + "ropl") .Description("Toggles rotation of playing status of the dynamic strings you specified earlier.") .AddCheck(Classes.Permissions.SimpleCheckers.OwnerOnly()) .Do(DoFunc()); - cgb.CreateCommand(".addplaying") - .Alias(".adpl") + cgb.CreateCommand(Module.Prefix + "addplaying") + .Alias(Module.Prefix + "adpl") .Description("Adds a specified string to the list of playing strings to rotate. " + "Supported placeholders: " + string.Join(", ", PlayingPlaceholders.Keys)) .Parameter("text", ParameterType.Unparsed) @@ -96,8 +96,8 @@ namespace NadekoBot.Commands { await e.Channel.SendMessage("πŸ†— `Added a new playing string.`"); }); - cgb.CreateCommand(".listplaying") - .Alias(".lipl") + cgb.CreateCommand(Module.Prefix + "listplaying") + .Alias(Module.Prefix + "lipl") .Description("Lists all playing statuses with their corresponding number.") .AddCheck(Classes.Permissions.SimpleCheckers.OwnerOnly()) .Do(async e => { @@ -111,8 +111,8 @@ namespace NadekoBot.Commands { await e.Channel.SendMessage(sb.ToString()); }); - cgb.CreateCommand(".removeplaying") - .Alias(".repl", ".rmpl") + cgb.CreateCommand(Module.Prefix + "removeplaying") + .Alias(Module.Prefix + "repl", Module.Prefix + "rmpl") .Description("Removes a playing string on a given number.") .Parameter("number", ParameterType.Required) .AddCheck(Classes.Permissions.SimpleCheckers.OwnerOnly()) diff --git a/NadekoBot/Commands/PollCommand.cs b/NadekoBot/Commands/PollCommand.cs index 718727c9..4ae93a8c 100644 --- a/NadekoBot/Commands/PollCommand.cs +++ b/NadekoBot/Commands/PollCommand.cs @@ -18,7 +18,7 @@ namespace NadekoBot.Commands { } internal override void Init(CommandGroupBuilder cgb) { - cgb.CreateCommand(">poll") + cgb.CreateCommand(Module.Prefix + "poll") .Description("Creates a poll, only person who has manage server permission can do it.\n**Usage**: >poll Question?;Answer1;Answ 2;A_3") .Parameter("allargs", ParameterType.Unparsed) .Do(async e => { @@ -40,7 +40,7 @@ namespace NadekoBot.Commands { } }); }); - cgb.CreateCommand(">pollend") + cgb.CreateCommand(Module.Prefix + "pollend") .Description("Stops active poll on this server and prints the results in this channel.") .Do(async e => { if (!e.User.ServerPermissions.ManageChannels) diff --git a/NadekoBot/Commands/RatelimitCommand.cs b/NadekoBot/Commands/RatelimitCommand.cs index 532607d8..92bce07f 100644 --- a/NadekoBot/Commands/RatelimitCommand.cs +++ b/NadekoBot/Commands/RatelimitCommand.cs @@ -30,7 +30,7 @@ namespace NadekoBot.Commands { } internal override void Init(CommandGroupBuilder cgb) { - cgb.CreateCommand(".slowmode") + cgb.CreateCommand(Module.Prefix + "slowmode") .Description("Toggles slow mode. When ON, users will be able to send only 1 message every 5 seconds.") .Parameter("minutes", ParameterType.Optional) .Do(async e => { diff --git a/NadekoBot/Commands/ServerGreetCommand.cs b/NadekoBot/Commands/ServerGreetCommand.cs index a38300f1..c404aef0 100644 --- a/NadekoBot/Commands/ServerGreetCommand.cs +++ b/NadekoBot/Commands/ServerGreetCommand.cs @@ -175,7 +175,7 @@ namespace NadekoBot.Commands { internal override void Init(CommandGroupBuilder cgb) { - cgb.CreateCommand(".greet") + cgb.CreateCommand(Module.Prefix + "greet") .Description("Enables or Disables anouncements on the current channel when someone joins the server.") .Do(async e => { if (!e.User.ServerPermissions.ManageServer) return; @@ -190,7 +190,7 @@ namespace NadekoBot.Commands { await e.Channel.SendMessage("Greet announcements disabled."); }); - cgb.CreateCommand(".greetmsg") + cgb.CreateCommand(Module.Prefix + "greetmsg") .Description("Sets a new announce message. Type %user% if you want to mention the new member.\n**Usage**: .greetmsg Welcome to the server, %user%.") .Parameter("msg", ParameterType.Unparsed) .Do(async e => { @@ -205,7 +205,7 @@ namespace NadekoBot.Commands { await e.Channel.SendMessage("Enable greet messsages by typing `.greet`"); }); - cgb.CreateCommand(".bye") + cgb.CreateCommand(Module.Prefix + "bye") .Description("Enables or Disables anouncements on the current channel when someone leaves the server.") .Do(async e => { if (!e.User.ServerPermissions.ManageServer) return; @@ -220,7 +220,7 @@ namespace NadekoBot.Commands { await e.Channel.SendMessage("Bye announcements disabled."); }); - cgb.CreateCommand(".byemsg") + cgb.CreateCommand(Module.Prefix + "byemsg") .Description("Sets a new announce leave message. Type %user% if you want to mention the new member.\n**Usage**: .byemsg %user% has left the server.") .Parameter("msg", ParameterType.Unparsed) .Do(async e => { @@ -235,7 +235,7 @@ namespace NadekoBot.Commands { await e.Channel.SendMessage("Enable bye messsages by typing `.bye`."); }); - cgb.CreateCommand(".byepm") + cgb.CreateCommand(Module.Prefix + "byepm") .Description("Toggles whether the good bye messages will be sent in a PM or in the text channel.") .Do(async e => { if (!e.User.ServerPermissions.ManageServer) return; @@ -251,7 +251,7 @@ namespace NadekoBot.Commands { await e.Channel.SendMessage("Enable bye messsages by typing `.bye`, and set the bye message using `.byemsg`"); }); - cgb.CreateCommand(".greetpm") + cgb.CreateCommand(Module.Prefix + "greetpm") .Description("Toggles whether the greet messages will be sent in a PM or in the text channel.") .Do(async e => { if (!e.User.ServerPermissions.ManageServer) return; diff --git a/NadekoBot/Commands/SpeedTyping.cs b/NadekoBot/Commands/SpeedTyping.cs index 78661dbc..ff64436a 100644 --- a/NadekoBot/Commands/SpeedTyping.cs +++ b/NadekoBot/Commands/SpeedTyping.cs @@ -140,15 +140,15 @@ namespace NadekoBot.Commands { }; internal override void Init(CommandGroupBuilder cgb) { - cgb.CreateCommand("typestart") + cgb.CreateCommand(Module.Prefix + "typestart") .Description("Starts a typing contest.") .Do(DoFunc()); - cgb.CreateCommand("typestop") + cgb.CreateCommand(Module.Prefix + "typestop") .Description("Stops a typing contest on the current channel.") .Do(QuitFunc()); - cgb.CreateCommand("typeadd") + cgb.CreateCommand(Module.Prefix + "typeadd") .Description("Adds a new article to the typing contest. Owner only.") .Parameter("text", ParameterType.Unparsed) .Do(async e => { diff --git a/NadekoBot/Commands/TriviaCommand.cs b/NadekoBot/Commands/TriviaCommand.cs index 56ae266d..c2398e81 100644 --- a/NadekoBot/Commands/TriviaCommand.cs +++ b/NadekoBot/Commands/TriviaCommand.cs @@ -23,16 +23,12 @@ namespace NadekoBot.Commands { }; internal override void Init(CommandGroupBuilder cgb) { - cgb.CreateCommand("t") + cgb.CreateCommand(Module.Prefix + "t") .Description("Starts a game of trivia.") - .Alias("-t") .Do(DoFunc()); - cgb.CreateCommand("tl") + cgb.CreateCommand(Module.Prefix + "tl") .Description("Shows a current trivia leaderboard.") - .Alias("-tl") - .Alias("tlb") - .Alias("-tlb") .Do(async e=> { TriviaGame trivia; if (RunningTrivias.TryGetValue(e.Server.Id, out trivia)) @@ -41,9 +37,8 @@ namespace NadekoBot.Commands { await e.Channel.SendMessage("No trivia is running on this server."); }); - cgb.CreateCommand("tq") + cgb.CreateCommand(Module.Prefix + "tq") .Description("Quits current trivia after current question.") - .Alias("-tq") .Do(async e=> { TriviaGame trivia; if (RunningTrivias.TryGetValue(e.Server.Id, out trivia)) { diff --git a/NadekoBot/Commands/VoiceNotificationCommand.cs b/NadekoBot/Commands/VoiceNotificationCommand.cs index e443c7ac..ecf15957 100644 --- a/NadekoBot/Commands/VoiceNotificationCommand.cs +++ b/NadekoBot/Commands/VoiceNotificationCommand.cs @@ -29,14 +29,12 @@ namespace NadekoBot.Commands { }; internal override void Init(CommandGroupBuilder cgb) { - /* - cgb.CreateCommand(".voicenotif") + cgb.CreateCommand(Module.Prefix + "voicenotif") .Description("Enables notifications on who joined/left the voice channel.\n**Usage**:.voicenotif Karaoke club") .Parameter("voice_name", ParameterType.Unparsed) .Do(DoFunc()); - */ } - public VoiceNotificationCommand(DiscordModule module) : base(module) {} + public VoiceNotificationCommand(DiscordModule module) : base(module) { } } } diff --git a/NadekoBot/Commands/VoicePlusTextCommand.cs b/NadekoBot/Commands/VoicePlusTextCommand.cs index 6acab585..16bebba0 100644 --- a/NadekoBot/Commands/VoicePlusTextCommand.cs +++ b/NadekoBot/Commands/VoicePlusTextCommand.cs @@ -59,8 +59,8 @@ namespace NadekoBot.Commands { } internal override void Init(CommandGroupBuilder cgb) { - cgb.CreateCommand(".v+t") - .Alias(".voice+text") + cgb.CreateCommand(Module.Prefix + "v+t") + .Alias(Module.Prefix + "voice+text") .Description("Creates a text channel for each voice channel only users in that voice channel can see." + "If you are server owner, keep in mind you will see them all the time regardless.") .AddCheck(SimpleCheckers.ManageChannels()) diff --git a/NadekoBot/Modules/ClashOfClans.cs b/NadekoBot/Modules/ClashOfClans.cs new file mode 100644 index 00000000..3f4c412d --- /dev/null +++ b/NadekoBot/Modules/ClashOfClans.cs @@ -0,0 +1,241 @@ +ο»Ώ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.Modules; +using NadekoBot.Classes.ClashOfClans; +using NadekoBot.Modules; + +namespace NadekoBot.Commands { + internal class ClashOfClans : DiscordModule + { + public override string Prefix { get; } = ","; + + public static ConcurrentDictionary> ClashWars { get; } = new ConcurrentDictionary>(); + + private readonly object writeLock = new object(); + + public override void Install(ModuleManager manager) { + manager.CreateCommands("", cgb => { + + cgb.CreateCommand(Prefix + "createwar") + .Alias(Prefix + "cw") + .Description( + $"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 => { + if (!e.User.ServerPermissions.ManageChannels) + return; + List 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)) { + return; + } + int size; + 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 { + await + e.Channel.SendMessage( + $"β—πŸ”°**Claim from @{u} for a war against {cw.ShortPrint()} has expired.**"); + } catch { } + }; + cw.OnWarEnded += async () => { + try { + await e.Channel.SendMessage($"β—πŸ”°**War against {cw.ShortPrint()} ended.**"); + } catch { } + }; + await e.Channel.SendMessage($"β—πŸ”°**CREATED CLAN WAR AGAINST {cw.ShortPrint()}**"); + //war with the index X started. + }); + + cgb.CreateCommand(Prefix + "sw") + .Alias(Prefix + "startwar") + .Description("Starts a war with a given number.") + .Parameter("number", ParameterType.Required) + .Do(async e => { + var warsInfo = GetInfo(e); + if (warsInfo == null) { + await e.Channel.SendMessage("πŸ’’πŸ”° **That war does not exist.**"); + return; + } + var war = warsInfo.Item1[warsInfo.Item2]; + try { + var startTask = war.Start(); + await e.Channel.SendMessage($"πŸ”°**STARTED WAR AGAINST {war.ShortPrint()}**"); + await startTask; + } catch { + await e.Channel.SendMessage($"πŸ”°**WAR AGAINST {war.ShortPrint()} IS ALREADY STARTED**"); + } + }); + + cgb.CreateCommand(Prefix + "listwar") + .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 => { + // if number is null, print all wars in a short way + 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) { + await e.Channel.SendMessage("πŸ”° **No active wars.**"); + return; + } + + var sb = new StringBuilder(); + sb.AppendLine("πŸ”° **LIST OF ACTIVE WARS**"); + sb.AppendLine("**-------------------------**"); + 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("**-------------------------**"); + } + await e.Channel.SendMessage(sb.ToString()); + return; + } + //if number is not null, print the war needed + var warsInfo = GetInfo(e); + if (warsInfo == null) { + await e.Channel.SendMessage("πŸ’’πŸ”° **That war does not exist.**"); + return; + } + await e.Channel.SendMessage(warsInfo.Item1[warsInfo.Item2].ToString()); + }); + + cgb.CreateCommand(Prefix + "claim") + .Alias(Prefix + "call") + .Alias(Prefix + "c") + .Description($"Claims a certain base from a certain war. You can supply a name in the third optional argument to claim in someone else's place. \n**Usage**: {Prefix}call [war_number] [base_number] (optional_otheruser)") + .Parameter("number") + .Parameter("baseNumber") + .Parameter("other_name", ParameterType.Unparsed) + .Do(async e => { + var warsInfo = GetInfo(e); + 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)) { + await e.Channel.SendMessage("πŸ’’πŸ”° **Invalid base number.**"); + return; + } + var usr = + string.IsNullOrWhiteSpace(e.GetArg("other_name")) ? + e.User.Name : + e.GetArg("other_name"); + 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) { + await e.Channel.SendMessage($"πŸ’’πŸ”° {ex.Message}"); + } + }); + + cgb.CreateCommand(Prefix + "cf") + .Alias(Prefix + "claimfinish") + .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 => { + var warInfo = GetInfo(e); + if (warInfo == null || warInfo.Item1.Count == 0) { + await e.Channel.SendMessage("πŸ’’πŸ”° **That war does not exist.**"); + return; + } + var usr = + string.IsNullOrWhiteSpace(e.GetArg("other_name")) ? + e.User.Name : + e.GetArg("other_name"); + + var war = warInfo.Item1[warInfo.Item2]; + 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) { + await e.Channel.SendMessage($"πŸ’’πŸ”° {ex.Message}"); + } + }); + + cgb.CreateCommand(Prefix + "unclaim") + .Alias(Prefix + "uncall") + .Alias(Prefix + "uc") + .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 => { + var warsInfo = GetInfo(e); + if (warsInfo == null || warsInfo.Item1.Count == 0) { + await e.Channel.SendMessage("πŸ’’πŸ”° **That war does not exist.**"); + return; + } + var usr = + string.IsNullOrWhiteSpace(e.GetArg("other_name")) ? + e.User.Name : + e.GetArg("other_name"); + 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) { + await e.Channel.SendMessage($"πŸ’’πŸ”° {ex.Message}"); + } + }); + + cgb.CreateCommand(Prefix + "endwar") + .Alias(Prefix + "ew") + .Description($"Ends the war with a given index.\n**Usage**:{Prefix}ew [war_number]") + .Parameter("number") + .Do(async e => { + var warsInfo = GetInfo(e); + if (warsInfo == null) { + await e.Channel.SendMessage("πŸ’’πŸ”° That war does not exist."); + return; + } + warsInfo.Item1[warsInfo.Item2].End(); + + var size = warsInfo.Item1[warsInfo.Item2].Size; + warsInfo.Item1.RemoveAt(warsInfo.Item2); + }); + }); + } + + 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) { + 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) { + return null; + } + num -= 1; + //get the actual war + return new Tuple, int>(wars, num); + } + } +} diff --git a/NadekoBot/Modules/Gambling.cs b/NadekoBot/Modules/Gambling.cs index f144c0e1..4f73c3ab 100644 --- a/NadekoBot/Modules/Gambling.cs +++ b/NadekoBot/Modules/Gambling.cs @@ -26,7 +26,7 @@ namespace NadekoBot.Modules commands.ForEach(com => com.Init(cgb)); - cgb.CreateCommand("$raffle") + cgb.CreateCommand(Prefix +"raffle") .Description("Prints a name and ID of a random user from the online list from the (optional) role.") .Parameter("role", ParameterType.Optional) .Do(async e => { @@ -41,7 +41,7 @@ namespace NadekoBot.Modules var usr = membersArray[new System.Random().Next(0, membersArray.Length)]; await e.Channel.SendMessage($"**Raffled user:** {usr.Name} (id: {usr.Id})"); }); - cgb.CreateCommand("$$$") + cgb.CreateCommand(Prefix + "$$") .Description("Check how many NadekoFlowers you have.") .Do(async e => { var pts = Classes.DbHandler.Instance.GetStateByUserId((long)e.User.Id)?.Value ?? 0; diff --git a/NadekoBot/Modules/Games.cs b/NadekoBot/Modules/Games.cs index 086eed8d..65a8be92 100644 --- a/NadekoBot/Modules/Games.cs +++ b/NadekoBot/Modules/Games.cs @@ -7,8 +7,6 @@ using System.IO; using Discord.Commands; using NadekoBot.Extensions; -//πŸƒ -//🏁 namespace NadekoBot.Modules { internal class Games : DiscordModule { private readonly string[] _8BallAnswers; @@ -18,7 +16,6 @@ namespace NadekoBot.Modules { commands.Add(new Trivia(this)); commands.Add(new SpeedTyping(this)); commands.Add(new PollCommand(this)); - commands.Add(new ClashOfClans(this)); _8BallAnswers = JArray.Parse(File.ReadAllText("data/8ball.json")).Select(t => t.ToString()).ToArray(); } diff --git a/NadekoBot/Modules/Help.cs b/NadekoBot/Modules/Help.cs index f2a33563..beaa6c3c 100644 --- a/NadekoBot/Modules/Help.cs +++ b/NadekoBot/Modules/Help.cs @@ -18,15 +18,15 @@ namespace NadekoBot.Modules { cgb.AddCheck(Classes.Permissions.PermissionChecker.Instance); commands.ForEach(com => com.Init(cgb)); - cgb.CreateCommand(".modules") - .Alias("-modules") + cgb.CreateCommand(Prefix + "modules") + .Alias(".modules") .Description("List all bot modules.") .Do(async e => { await e.Channel.SendMessage("`List of modules:` \nβ€’ " + string.Join("\nβ€’ ", NadekoBot.Client.GetService().Modules.Select(m => m.Name))); }); - cgb.CreateCommand(".commands") - .Alias("-commands") + cgb.CreateCommand(Prefix + "commands") + .Alias(".commands") .Description("List all of the bot's commands from a certain module.") .Parameter("module", ParameterType.Unparsed) .Do(async e => { diff --git a/NadekoBot/Modules/Music.cs b/NadekoBot/Modules/Music.cs index 837155c2..cb343280 100644 --- a/NadekoBot/Modules/Music.cs +++ b/NadekoBot/Modules/Music.cs @@ -33,12 +33,12 @@ namespace NadekoBot.Modules { } - public override string Prefix { get; } = "!m "; + public override string Prefix { get; } = "!m"; public override void Install(ModuleManager manager) { var client = NadekoBot.Client; - manager.CreateCommands("!m", cgb => { + manager.CreateCommands(Prefix, cgb => { cgb.AddCheck(Classes.Permissions.PermissionChecker.Instance); diff --git a/NadekoBot/NadekoBot.cs b/NadekoBot/NadekoBot.cs index afe07ef0..744df951 100644 --- a/NadekoBot/NadekoBot.cs +++ b/NadekoBot/NadekoBot.cs @@ -121,6 +121,7 @@ namespace NadekoBot { modules.Add(new Music(), "Music", ModuleFilter.None); modules.Add(new Searches(), "Searches", ModuleFilter.None); modules.Add(new NSFW(), "NSFW", ModuleFilter.None); + modules.Add(new ClashOfClans(), "ClashOfClans", ModuleFilter.None); if (!string.IsNullOrWhiteSpace(Creds.TrelloAppKey)) modules.Add(new Trello(), "Trello", ModuleFilter.None);