Refactored Music, NFW, Search, Trello, ClashOfClans Modules ...

This commit is contained in:
Master Kwoth
2016-04-14 23:47:02 +02:00
parent eb90bb5bd1
commit 4bc7ec9d47
12 changed files with 80 additions and 57 deletions

View File

@ -2,6 +2,7 @@
using NadekoBot.Classes.JSONModels;
using NadekoBot.Commands;
using NadekoBot.Modules.Games.Commands;
using NadekoBot.Modules.Music;
using System;
using System.Collections.Generic;
using System.Linq;
@ -20,10 +21,10 @@ namespace NadekoBot.Modules.Administration.Commands
{"%servers%", () => NadekoBot.Client.Servers.Count().ToString()},
{"%users%", () => NadekoBot.Client.Servers.SelectMany(s => s.Users).Count().ToString()},
{"%playing%", () => {
var cnt = Music.MusicPlayers.Count(kvp => kvp.Value.CurrentSong != null);
var cnt = MusicModule.MusicPlayers.Count(kvp => kvp.Value.CurrentSong != null);
if (cnt != 1) return cnt.ToString();
try {
var mp = Music.MusicPlayers.FirstOrDefault();
var mp = MusicModule.MusicPlayers.FirstOrDefault();
return mp.Value.CurrentSong.SongInfo.Title;
}
catch {
@ -31,7 +32,7 @@ namespace NadekoBot.Modules.Administration.Commands
}
}
},
{"%queued%", () => Music.MusicPlayers.Sum(kvp => kvp.Value.Playlist.Count).ToString()},
{"%queued%", () => MusicModule.MusicPlayers.Sum(kvp => kvp.Value.Playlist.Count).ToString()},
{"%trivia%", () => Trivia.RunningTrivias.Count.ToString()}
};

View File

@ -0,0 +1,175 @@
using Discord.Commands;
using System;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
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<string> 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)
{
OnUserTimeExpired(bases[i].CallUser);
bases[i] = null;
}
}
}
}
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.");
}
}
}

View File

@ -1,15 +1,14 @@
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.Modules.ClashOfClans
{
internal class ClashOfClans : DiscordModule
internal class ClashOfClansModule : DiscordModule
{
public override string Prefix { get; } = NadekoBot.Config.CommandPrefixes.ClashOfClans;

View File

@ -6,10 +6,10 @@ using System.Linq;
namespace NadekoBot.Modules.Help
{
internal class Help : DiscordModule
internal class HelpModule : DiscordModule
{
public Help()
public HelpModule()
{
commands.Add(new HelpCommand(this));
}

View File

@ -13,15 +13,15 @@ using System.IO;
using System.Linq;
using System.Threading.Tasks;
namespace NadekoBot.Modules
namespace NadekoBot.Modules.Music
{
internal class Music : DiscordModule
internal class MusicModule : DiscordModule
{
public static ConcurrentDictionary<Server, MusicPlayer> MusicPlayers = new ConcurrentDictionary<Server, MusicPlayer>();
public static ConcurrentDictionary<ulong, float> DefaultMusicVolumes = new ConcurrentDictionary<ulong, float>();
public Music()
public MusicModule()
{
// ready for 1.0
//NadekoBot.Client.UserUpdated += (s, e) =>

View File

@ -4,9 +4,9 @@ using NadekoBot.Classes;
using Newtonsoft.Json.Linq;
using System;
namespace NadekoBot.Modules
namespace NadekoBot.Modules.NSFW
{
internal class NSFW : DiscordModule
internal class NSFWModule : DiscordModule
{
private readonly Random rng = new Random();

View File

@ -306,7 +306,7 @@ Assists: {general["assists"]} Ban: {general["banRate"]}%
await e.Channel.SendMessage(sb.ToString());
}
catch (Exception ex)
catch (Exception)
{
await e.Channel.SendMessage($":anger: Fail: Champion.gg didsabled ban data until next patch. Sorry for the inconvenience.");
}

View File

@ -16,10 +16,10 @@ using System.Net;
namespace NadekoBot.Modules.Searches
{
internal class Searches : DiscordModule
internal class SearchesModule : DiscordModule
{
private readonly Random rng;
public Searches()
public SearchesModule()
{
commands.Add(new LoLCommands(this));
commands.Add(new StreamNotifications(this));

View File

@ -1,19 +1,22 @@
using System;
using Discord.Modules;
using Manatee.Trello;
using Manatee.Trello.ManateeJson;
using NadekoBot.Extensions;
using System;
using System.Collections.Generic;
using System.Linq;
using Discord.Modules;
using Manatee.Trello.ManateeJson;
using Manatee.Trello;
using System.Timers;
using NadekoBot.Extensions;
using Action = Manatee.Trello.Action;
namespace NadekoBot.Modules {
internal class Trello : DiscordModule {
namespace NadekoBot.Modules.Trello
{
internal class TrelloModule : DiscordModule
{
private readonly Timer t = new Timer { Interval = 2000 };
public override string Prefix { get; } = NadekoBot.Config.CommandPrefixes.Trello;
public override void Install(ModuleManager manager) {
public override void Install(ModuleManager manager)
{
var client = manager.Client;
@ -29,8 +32,10 @@ namespace NadekoBot.Modules {
Board board = null;
List<string> last5ActionIDs = null;
t.Elapsed += async (s, e) => {
try {
t.Elapsed += async (s, e) =>
{
try
{
if (board == null || bound == null)
return; //do nothing if there is no bound board
@ -38,22 +43,27 @@ namespace NadekoBot.Modules {
var cur5Actions = board.Actions.Take(board.Actions.Count() < 5 ? board.Actions.Count() : 5);
var cur5ActionsArray = cur5Actions as Action[] ?? cur5Actions.ToArray();
if (last5ActionIDs == null) {
if (last5ActionIDs == null)
{
last5ActionIDs = cur5ActionsArray.Select(a => a.Id).ToList();
return;
}
foreach (var a in cur5ActionsArray.Where(ca => !last5ActionIDs.Contains(ca.Id))) {
foreach (var a in cur5ActionsArray.Where(ca => !last5ActionIDs.Contains(ca.Id)))
{
await bound.Send("**--TRELLO NOTIFICATION--**\n" + a.ToString());
}
last5ActionIDs.Clear();
last5ActionIDs.AddRange(cur5ActionsArray.Select(a => a.Id));
} catch (Exception ex) {
}
catch (Exception ex)
{
Console.WriteLine("Timer failed " + ex.ToString());
}
};
manager.CreateCommands("trello ", cgb => {
manager.CreateCommands("trello ", cgb =>
{
cgb.AddCheck(Classes.Permissions.PermissionChecker.Instance);
@ -61,11 +71,15 @@ namespace NadekoBot.Modules {
.Alias("j")
.Description("Joins a server")
.Parameter("code", Discord.Commands.ParameterType.Required)
.Do(async e => {
.Do(async e =>
{
if (!NadekoBot.IsOwner(e.User.Id)) return;
try {
try
{
await (await client.GetInvite(e.GetArg("code"))).Accept();
} catch (Exception ex) {
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
});
@ -75,23 +89,28 @@ namespace NadekoBot.Modules {
"You will receive notifications from your board when something is added or edited." +
"\n**Usage**: bind [board_id]")
.Parameter("board_id", Discord.Commands.ParameterType.Required)
.Do(async e => {
.Do(async e =>
{
if (!NadekoBot.IsOwner(e.User.Id)) return;
if (bound != null) return;
try {
try
{
bound = e.Channel;
board = new Board(e.GetArg("board_id").Trim());
board.Refresh();
await e.Channel.SendMessage("Successfully bound to this channel and board " + board.Name);
t.Start();
} catch (Exception ex) {
}
catch (Exception ex)
{
Console.WriteLine("Failed to join the board. " + ex.ToString());
}
});
cgb.CreateCommand("unbind")
.Description("Unbinds a bot from the channel and board.")
.Do(async e => {
.Do(async e =>
{
if (!NadekoBot.IsOwner(e.User.Id)) return;
if (bound == null || bound != e.Channel) return;
t.Stop();
@ -104,7 +123,8 @@ namespace NadekoBot.Modules {
cgb.CreateCommand("lists")
.Alias("list")
.Description("Lists all lists yo ;)")
.Do(async e => {
.Do(async e =>
{
if (!NadekoBot.IsOwner(e.User.Id)) return;
if (bound == null || board == null || bound != e.Channel) return;
await e.Channel.SendMessage("Lists for a board '" + board.Name + "'\n" + string.Join("\n", board.Lists.Select(l => "**• " + l.ToString() + "**")));
@ -113,7 +133,8 @@ namespace NadekoBot.Modules {
cgb.CreateCommand("cards")
.Description("Lists all cards from the supplied list. You can supply either a name or an index.")
.Parameter("list_name", Discord.Commands.ParameterType.Unparsed)
.Do(async e => {
.Do(async e =>
{
if (!NadekoBot.IsOwner(e.User.Id)) return;
if (bound == null || board == null || bound != e.Channel || e.GetArg("list_name") == null) return;