Merge remote-tracking branch 'upstream/dev' into dev

This commit is contained in:
fkndean 2016-12-08 13:27:29 -05:00
commit f8b6370b88
43 changed files with 155 additions and 261 deletions

@ -1 +1 @@
Subproject commit 57fc8290666dba35b2385c97e3a51c493b40a425 Subproject commit 63cc61d8db062fcbd577dc5f9e764a61f283689b

View File

@ -15,6 +15,7 @@ using System.Net.Http;
using System.IO; using System.IO;
using static NadekoBot.Modules.Permissions.Permissions; using static NadekoBot.Modules.Permissions.Permissions;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using NLog;
namespace NadekoBot.Modules.Administration namespace NadekoBot.Modules.Administration
{ {
@ -24,13 +25,17 @@ namespace NadekoBot.Modules.Administration
private static ConcurrentDictionary<ulong, string> GuildMuteRoles { get; } = new ConcurrentDictionary<ulong, string>(); private static ConcurrentDictionary<ulong, string> GuildMuteRoles { get; } = new ConcurrentDictionary<ulong, string>();
public Administration(ILocalization loc, CommandService cmds, ShardedDiscordClient client) : base(loc, cmds, client) private static Logger _log { get; }
public Administration() : base()
{ {
NadekoBot.CommandHandler.CommandExecuted += DelMsgOnCmd_Handler;
} }
static Administration() static Administration()
{ {
_log = LogManager.GetCurrentClassLogger();
NadekoBot.CommandHandler.CommandExecuted += DelMsgOnCmd_Handler;
using (var uow = DbHandler.UnitOfWork()) using (var uow = DbHandler.UnitOfWork())
{ {
var configs = NadekoBot.AllGuildConfigs; var configs = NadekoBot.AllGuildConfigs;
@ -40,11 +45,11 @@ namespace NadekoBot.Modules.Administration
} }
} }
private async void DelMsgOnCmd_Handler(object sender, CommandExecutedEventArgs e) private static async Task DelMsgOnCmd_Handler(IUserMessage msg, Command cmd)
{ {
try try
{ {
var channel = e.Message.Channel as ITextChannel; var channel = msg.Channel as ITextChannel;
if (channel == null) if (channel == null)
return; return;
@ -56,7 +61,7 @@ namespace NadekoBot.Modules.Administration
} }
if (shouldDelete) if (shouldDelete)
await e.Message.DeleteAsync().ConfigureAwait(false); await msg.DeleteAsync().ConfigureAwait(false);
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -802,7 +807,7 @@ namespace NadekoBot.Modules.Administration
{ {
var channel = (ITextChannel)umsg.Channel; var channel = (ITextChannel)umsg.Channel;
var channels = await Task.WhenAll(_client.GetGuilds().Select(g => var channels = await Task.WhenAll(NadekoBot.Client.GetGuilds().Select(g =>
g.GetDefaultChannelAsync() g.GetDefaultChannelAsync()
)).ConfigureAwait(false); )).ConfigureAwait(false);

View File

@ -74,13 +74,13 @@ namespace NadekoBot.Modules.Administration
private static ConcurrentDictionary<ulong, AntiSpamSetting> antiSpamGuilds = private static ConcurrentDictionary<ulong, AntiSpamSetting> antiSpamGuilds =
new ConcurrentDictionary<ulong, AntiSpamSetting>(); new ConcurrentDictionary<ulong, AntiSpamSetting>();
private Logger _log { get; } private static Logger _log { get; }
public AntiRaidCommands(ShardedDiscordClient client) static AntiRaidCommands()
{ {
_log = LogManager.GetCurrentClassLogger(); _log = LogManager.GetCurrentClassLogger();
client.MessageReceived += (imsg) => NadekoBot.Client.MessageReceived += (imsg) =>
{ {
var msg = imsg as IUserMessage; var msg = imsg as IUserMessage;
if (msg == null || msg.Author.IsBot) if (msg == null || msg.Author.IsBot)
@ -115,7 +115,7 @@ namespace NadekoBot.Modules.Administration
return Task.CompletedTask; return Task.CompletedTask;
}; };
client.UserJoined += (usr) => NadekoBot.Client.UserJoined += (usr) =>
{ {
if (usr.IsBot) if (usr.IsBot)
return Task.CompletedTask; return Task.CompletedTask;
@ -148,7 +148,7 @@ namespace NadekoBot.Modules.Administration
}; };
} }
private async Task PunishUsers(PunishmentAction action, IRole muteRole, ProtectionType pt, params IGuildUser[] gus) private static async Task PunishUsers(PunishmentAction action, IRole muteRole, ProtectionType pt, params IGuildUser[] gus)
{ {
foreach (var gu in gus) foreach (var gu in gus)
{ {

View File

@ -15,13 +15,12 @@ namespace NadekoBot.Modules.Administration
[Group] [Group]
public class AutoAssignRoleCommands public class AutoAssignRoleCommands
{ {
private Logger _log { get; } private static Logger _log { get; }
public AutoAssignRoleCommands() static AutoAssignRoleCommands()
{ {
var _client = NadekoBot.Client; _log = LogManager.GetCurrentClassLogger();
this._log = LogManager.GetCurrentClassLogger(); NadekoBot.Client.UserJoined += (user) =>
_client.UserJoined += (user) =>
{ {
var t = Task.Run(async () => var t = Task.Run(async () =>
{ {

View File

@ -16,7 +16,7 @@ namespace NadekoBot.Modules.Administration
[Group] [Group]
public class CrossServerTextChannel public class CrossServerTextChannel
{ {
public CrossServerTextChannel() static CrossServerTextChannel()
{ {
_log = LogManager.GetCurrentClassLogger(); _log = LogManager.GetCurrentClassLogger();
NadekoBot.Client.MessageReceived += (imsg) => NadekoBot.Client.MessageReceived += (imsg) =>
@ -50,11 +50,11 @@ namespace NadekoBot.Modules.Administration
}; };
} }
private string GetText(IGuild server, ITextChannel channel, IGuildUser user, IUserMessage message) => private static string GetText(IGuild server, ITextChannel channel, IGuildUser user, IUserMessage message) =>
$"**{server.Name} | {channel.Name}** `{user.Username}`: " + message.Content; $"**{server.Name} | {channel.Name}** `{user.Username}`: " + message.Content;
public static readonly ConcurrentDictionary<int, ConcurrentHashSet<ITextChannel>> Subscribers = new ConcurrentDictionary<int, ConcurrentHashSet<ITextChannel>>(); public static readonly ConcurrentDictionary<int, ConcurrentHashSet<ITextChannel>> Subscribers = new ConcurrentDictionary<int, ConcurrentHashSet<ITextChannel>>();
private Logger _log { get; } private static Logger _log { get; }
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)] [RequireContext(ContextType.Guild)]

View File

@ -63,7 +63,7 @@ namespace NadekoBot.Modules.Administration
}, null, TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(10)); }, null, TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(10));
} }
public LogCommands(ShardedDiscordClient client) public LogCommands()
{ {
//_client.MessageReceived += _client_MessageReceived; //_client.MessageReceived += _client_MessageReceived;
_client.MessageUpdated += _client_MessageUpdated; _client.MessageUpdated += _client_MessageUpdated;

View File

@ -18,7 +18,7 @@ namespace NadekoBot.Modules.Administration
[Group] [Group]
public class RepeatCommands public class RepeatCommands
{ {
public ConcurrentDictionary<ulong, RepeatRunner> repeaters; public static ConcurrentDictionary<ulong, RepeatRunner> repeaters { get; }
public class RepeatRunner public class RepeatRunner
{ {
@ -70,7 +70,7 @@ namespace NadekoBot.Modules.Administration
} }
} }
public RepeatCommands() static RepeatCommands()
{ {
using (var uow = DbHandler.UnitOfWork()) using (var uow = DbHandler.UnitOfWork())
{ {

View File

@ -18,7 +18,7 @@ namespace NadekoBot.Modules.Administration
[Group] [Group]
public class PlayingRotateCommands public class PlayingRotateCommands
{ {
private Logger _log { get; } private static Logger _log { get; }
public static List<PlayingStatus> RotatingStatusMessages { get; } public static List<PlayingStatus> RotatingStatusMessages { get; }
public static bool RotatingStatuses { get; private set; } = false; public static bool RotatingStatuses { get; private set; } = false;
@ -30,12 +30,9 @@ namespace NadekoBot.Modules.Administration
RotatingStatusMessages = conf.RotatingStatusMessages; RotatingStatusMessages = conf.RotatingStatusMessages;
RotatingStatuses = conf.RotatingStatuses; RotatingStatuses = conf.RotatingStatuses;
} }
}
public PlayingRotateCommands()
{
_log = LogManager.GetCurrentClassLogger(); _log = LogManager.GetCurrentClassLogger();
Task.Run(async () => var t = Task.Run(async () =>
{ {
var index = 0; var index = 0;
do do

View File

@ -16,9 +16,7 @@ namespace NadekoBot.Modules.Administration
public class RatelimitCommand public class RatelimitCommand
{ {
public static ConcurrentDictionary<ulong, Ratelimiter> RatelimitingChannels = new ConcurrentDictionary<ulong, Ratelimiter>(); public static ConcurrentDictionary<ulong, Ratelimiter> RatelimitingChannels = new ConcurrentDictionary<ulong, Ratelimiter>();
private Logger _log { get; } private static Logger _log { get; }
private ShardedDiscordClient _client { get; }
public class Ratelimiter public class Ratelimiter
{ {
@ -61,12 +59,11 @@ namespace NadekoBot.Modules.Administration
} }
} }
public RatelimitCommand() static RatelimitCommand()
{ {
this._client = NadekoBot.Client; _log = LogManager.GetCurrentClassLogger();
this._log = LogManager.GetCurrentClassLogger();
_client.MessageReceived += (umsg) => NadekoBot.Client.MessageReceived += (umsg) =>
{ {
var t = Task.Run(async () => var t = Task.Run(async () =>
{ {

View File

@ -13,9 +13,9 @@ namespace NadekoBot.Modules.Administration
{ {
private ShardedDiscordClient _client; private ShardedDiscordClient _client;
public SelfCommands(ShardedDiscordClient client) public SelfCommands()
{ {
this._client = client; this._client = NadekoBot.Client;
} }
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]

View File

@ -17,17 +17,16 @@ namespace NadekoBot.Modules.Administration
[Group] [Group]
public class ServerGreetCommands public class ServerGreetCommands
{ {
public static long Greeted = 0; private static Logger _log { get; }
private Logger _log;
public ServerGreetCommands() static ServerGreetCommands()
{ {
NadekoBot.Client.UserJoined += UserJoined; NadekoBot.Client.UserJoined += UserJoined;
NadekoBot.Client.UserLeft += UserLeft; NadekoBot.Client.UserLeft += UserLeft;
_log = LogManager.GetCurrentClassLogger(); _log = LogManager.GetCurrentClassLogger();
} }
private Task UserLeft(IGuildUser user) private static Task UserLeft(IGuildUser user)
{ {
var leftTask = Task.Run(async () => var leftTask = Task.Run(async () =>
{ {
@ -67,7 +66,7 @@ namespace NadekoBot.Modules.Administration
return Task.CompletedTask; return Task.CompletedTask;
} }
private Task UserJoined(IGuildUser user) private static Task UserJoined(IGuildUser user)
{ {
var joinedTask = Task.Run(async () => var joinedTask = Task.Run(async () =>
{ {

View File

@ -17,10 +17,10 @@ namespace NadekoBot.Modules.Administration
[Group] [Group]
public class VoicePlusTextCommands public class VoicePlusTextCommands
{ {
Regex channelNameRegex = new Regex(@"[^a-zA-Z0-9 -]", RegexOptions.Compiled); private static Regex channelNameRegex = new Regex(@"[^a-zA-Z0-9 -]", RegexOptions.Compiled);
private ConcurrentHashSet<ulong> voicePlusTextCache; private static ConcurrentHashSet<ulong> voicePlusTextCache { get; }
public VoicePlusTextCommands() static VoicePlusTextCommands()
{ {
using (var uow = DbHandler.UnitOfWork()) using (var uow = DbHandler.UnitOfWork())
{ {
@ -29,7 +29,7 @@ namespace NadekoBot.Modules.Administration
NadekoBot.Client.UserVoiceStateUpdated += UserUpdatedEventHandler; NadekoBot.Client.UserVoiceStateUpdated += UserUpdatedEventHandler;
} }
private Task UserUpdatedEventHandler(IUser iuser, IVoiceState before, IVoiceState after) private static Task UserUpdatedEventHandler(IUser iuser, IVoiceState before, IVoiceState after)
{ {
var user = (iuser as IGuildUser); var user = (iuser as IGuildUser);
var guild = user?.Guild; var guild = user?.Guild;
@ -101,7 +101,7 @@ namespace NadekoBot.Modules.Administration
return Task.CompletedTask; return Task.CompletedTask;
} }
private string GetChannelName(string voiceName) => private static string GetChannelName(string voiceName) =>
channelNameRegex.Replace(voiceName, "").Trim().Replace(" ", "-").TrimTo(90, true) + "-voice"; channelNameRegex.Replace(voiceName, "").Trim().Replace(" ", "-").TrimTo(90, true) + "-voice";
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]

View File

@ -36,7 +36,7 @@ namespace NadekoBot.Modules.ClashOfClans
.ToDictionary(g => g.Key, g => g.ToList())); .ToDictionary(g => g.Key, g => g.ToList()));
} }
} }
public ClashOfClans(ILocalization loc, CommandService cmds, ShardedDiscordClient client) : base(loc, cmds, client) public ClashOfClans() : base()
{ {
} }

View File

@ -25,7 +25,7 @@ namespace NadekoBot.Modules.CustomReactions
GlobalReactions = new ConcurrentHashSet<CustomReaction>(items.Where(g => g.GuildId == null || g.GuildId == 0)); GlobalReactions = new ConcurrentHashSet<CustomReaction>(items.Where(g => g.GuildId == null || g.GuildId == 0));
} }
} }
public CustomReactions(ILocalization loc, CommandService cmds, ShardedDiscordClient client) : base(loc, cmds, client) public CustomReactions() : base()
{ {
} }

View File

@ -6,12 +6,10 @@ namespace NadekoBot.Modules
{ {
public class DiscordModule public class DiscordModule
{ {
protected CommandService _commands { get; }
protected ShardedDiscordClient _client { get; }
protected Logger _log { get; } protected Logger _log { get; }
protected string _prefix { get; } protected string _prefix { get; }
public DiscordModule(ILocalization loc, CommandService cmds, ShardedDiscordClient client) public DiscordModule()
{ {
string prefix; string prefix;
if (NadekoBot.ModulePrefixes.TryGetValue(this.GetType().Name, out prefix)) if (NadekoBot.ModulePrefixes.TryGetValue(this.GetType().Name, out prefix))
@ -19,8 +17,6 @@ namespace NadekoBot.Modules
else else
_prefix = "?missing_prefix?"; _prefix = "?missing_prefix?";
_commands = cmds;
_client = client;
_log = LogManager.GetCurrentClassLogger(); _log = LogManager.GetCurrentClassLogger();
} }
} }

View File

@ -18,11 +18,7 @@ namespace NadekoBot.Modules.Gambling
[Group] [Group]
public class AnimalRacing public class AnimalRacing
{ {
public static ConcurrentDictionary<ulong, AnimalRace> AnimalRaces { get; } = new ConcurrentDictionary<ulong, AnimalRace>();
public AnimalRacing()
{
}
public static ConcurrentDictionary<ulong, AnimalRace> AnimalRaces = new ConcurrentDictionary<ulong, AnimalRace>();
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)] [RequireContext(ContextType.Guild)]
@ -119,7 +115,7 @@ namespace NadekoBot.Modules.Gambling
await Task.Run(StartRace); await Task.Run(StartRace);
End(); End();
} }
catch { } catch { try { End(); } catch { } }
}); });
} }

View File

@ -15,10 +15,9 @@ namespace NadekoBot.Modules.Gambling
[Group] [Group]
public class FlipCoinCommands public class FlipCoinCommands
{ {
NadekoRandom rng { get; } = new NadekoRandom(); private static NadekoRandom rng { get; } = new NadekoRandom();
private const string headsPath = "data/images/coins/heads.png"; private const string headsPath = "data/images/coins/heads.png";
private const string tailsPath = "data/images/coins/tails.png"; private const string tailsPath = "data/images/coins/tails.png";
public FlipCoinCommands() { }
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)] [RequireContext(ContextType.Guild)]

View File

@ -20,7 +20,7 @@ namespace NadekoBot.Modules.Gambling
public static string CurrencyPluralName { get; set; } public static string CurrencyPluralName { get; set; }
public static string CurrencySign { get; set; } public static string CurrencySign { get; set; }
public Gambling(ILocalization loc, CommandService cmds, ShardedDiscordClient client) : base(loc, cmds, client) public Gambling() : base()
{ {
using (var uow = DbHandler.UnitOfWork()) using (var uow = DbHandler.UnitOfWork())
{ {

View File

@ -31,23 +31,20 @@ namespace NadekoBot.Modules.Games
[Group] [Group]
public class PlantPickCommands public class PlantPickCommands
{ {
private Random rng; private static ConcurrentHashSet<ulong> generationChannels { get; } = new ConcurrentHashSet<ulong>();
private ConcurrentHashSet<ulong> generationChannels = new ConcurrentHashSet<ulong>();
//channelid/message //channelid/message
private ConcurrentDictionary<ulong, List<IUserMessage>> plantedFlowers = new ConcurrentDictionary<ulong, List<IUserMessage>>(); private static ConcurrentDictionary<ulong, List<IUserMessage>> plantedFlowers { get; } = new ConcurrentDictionary<ulong, List<IUserMessage>>();
//channelId/last generation //channelId/last generation
private ConcurrentDictionary<ulong, DateTime> lastGenerations = new ConcurrentDictionary<ulong, DateTime>(); private static ConcurrentDictionary<ulong, DateTime> lastGenerations { get; } = new ConcurrentDictionary<ulong, DateTime>();
private float chance; private static float chance { get; }
private int cooldown; private static int cooldown { get; }
private Logger _log { get; } private static Logger _log { get; }
public PlantPickCommands() static PlantPickCommands()
{ {
_log = LogManager.GetCurrentClassLogger(); _log = LogManager.GetCurrentClassLogger();
NadekoBot.Client.MessageReceived += PotentialFlowerGeneration; NadekoBot.Client.MessageReceived += PotentialFlowerGeneration;
rng = new NadekoRandom();
using (var uow = DbHandler.UnitOfWork()) using (var uow = DbHandler.UnitOfWork())
{ {
@ -60,7 +57,7 @@ namespace NadekoBot.Modules.Games
} }
} }
private Task PotentialFlowerGeneration(IMessage imsg) private static Task PotentialFlowerGeneration(IMessage imsg)
{ {
var msg = imsg as IUserMessage; var msg = imsg as IUserMessage;
if (msg == null || msg.IsAuthor() || msg.Author.IsBot) if (msg == null || msg.IsAuthor() || msg.Author.IsBot)
@ -76,6 +73,7 @@ namespace NadekoBot.Modules.Games
var t = Task.Run(async () => var t = Task.Run(async () =>
{ {
var lastGeneration = lastGenerations.GetOrAdd(channel.Id, DateTime.MinValue); var lastGeneration = lastGenerations.GetOrAdd(channel.Id, DateTime.MinValue);
var rng = new NadekoRandom();
if (DateTime.Now - TimeSpan.FromSeconds(cooldown) < lastGeneration) //recently generated in this channel, don't generate again if (DateTime.Now - TimeSpan.FromSeconds(cooldown) < lastGeneration) //recently generated in this channel, don't generate again
return; return;
@ -194,8 +192,11 @@ namespace NadekoBot.Modules.Games
} }
} }
private string GetRandomCurrencyImagePath() => private static string GetRandomCurrencyImagePath()
Directory.GetFiles("data/currency_images").OrderBy(s => rng.Next()).FirstOrDefault(); {
var rng = new NadekoRandom();
return Directory.GetFiles("data/currency_images").OrderBy(s => rng.Next()).FirstOrDefault();
}
int GetRandomNumber() int GetRandomNumber()
{ {

View File

@ -21,7 +21,7 @@ namespace NadekoBot.Modules.Games
} }
} }
} }
public Games(ILocalization loc, CommandService cmds, ShardedDiscordClient client) : base(loc, cmds, client) public Games() : base()
{ {
} }

View File

@ -30,7 +30,7 @@ namespace NadekoBot.Modules.Help
} }
} }
public Help(ILocalization loc, CommandService cmds, ShardedDiscordClient client) : base(loc, cmds, client) public Help() : base()
{ {
} }
@ -38,7 +38,7 @@ namespace NadekoBot.Modules.Help
public async Task Modules(IUserMessage umsg) public async Task Modules(IUserMessage umsg)
{ {
await umsg.Channel.SendMessageAsync("📜 **List of modules:** ```css\n• " + string.Join("\n• ", _commands.Modules.Select(m => m.Name)) + $"\n``` **Type** `-commands module_name` **to get a list of commands in that module.** ***e.g.*** `-commands games`") await umsg.Channel.SendMessageAsync("📜 **List of modules:** ```css\n• " + string.Join("\n• ", NadekoBot.CommandService.Modules.Select(m => m.Name)) + $"\n``` **Type** `-commands module_name` **to get a list of commands in that module.** ***e.g.*** `-commands games`")
.ConfigureAwait(false); .ConfigureAwait(false);
} }
@ -50,7 +50,7 @@ namespace NadekoBot.Modules.Help
module = module?.Trim().ToUpperInvariant(); module = module?.Trim().ToUpperInvariant();
if (string.IsNullOrWhiteSpace(module)) if (string.IsNullOrWhiteSpace(module))
return; return;
var cmds = _commands.Commands.Where(c => c.Module.Name.ToUpperInvariant().StartsWith(module)) var cmds = NadekoBot.CommandService.Commands.Where(c => c.Module.Name.ToUpperInvariant().StartsWith(module))
.OrderBy(c => c.Text) .OrderBy(c => c.Text)
.Distinct(new CommandTextEqualityComparer()) .Distinct(new CommandTextEqualityComparer())
.AsEnumerable(); .AsEnumerable();
@ -84,7 +84,7 @@ namespace NadekoBot.Modules.Help
await ch.SendMessageAsync(HelpString).ConfigureAwait(false); await ch.SendMessageAsync(HelpString).ConfigureAwait(false);
return; return;
} }
var com = _commands.Commands.FirstOrDefault(c => c.Text.ToLowerInvariant() == comToFind || c.Aliases.Select(a=>a.ToLowerInvariant()).Contains(comToFind)); var com = NadekoBot.CommandService.Commands.FirstOrDefault(c => c.Text.ToLowerInvariant() == comToFind || c.Aliases.Select(a=>a.ToLowerInvariant()).Contains(comToFind));
if (com == null) if (com == null)
{ {
@ -129,7 +129,7 @@ namespace NadekoBot.Modules.Help
helpstr.AppendLine(string.Join("\n", NadekoBot.CommandService.Modules.Where(m => m.Name.ToLowerInvariant() != "help").OrderBy(m => m.Name).Prepend(NadekoBot.CommandService.Modules.FirstOrDefault(m=>m.Name.ToLowerInvariant()=="help")).Select(m => $"- [{m.Name}](#{m.Name.ToLowerInvariant()})"))); helpstr.AppendLine(string.Join("\n", NadekoBot.CommandService.Modules.Where(m => m.Name.ToLowerInvariant() != "help").OrderBy(m => m.Name).Prepend(NadekoBot.CommandService.Modules.FirstOrDefault(m=>m.Name.ToLowerInvariant()=="help")).Select(m => $"- [{m.Name}](#{m.Name.ToLowerInvariant()})")));
helpstr.AppendLine(); helpstr.AppendLine();
string lastModule = null; string lastModule = null;
foreach (var com in _commands.Commands.OrderBy(com=>com.Module.Name).GroupBy(c=>c.Text).Select(g=>g.First())) foreach (var com in NadekoBot.CommandService.Commands.OrderBy(com=>com.Module.Name).GroupBy(c=>c.Text).Select(g=>g.First()))
{ {
if (com.Module.Name != lastModule) if (com.Module.Name != lastModule)
{ {

View File

@ -20,19 +20,16 @@ namespace NadekoBot.Modules.Music
[NadekoModule("Music", "!!", AutoLoad = false)] [NadekoModule("Music", "!!", AutoLoad = false)]
public partial class Music : DiscordModule public partial class Music : DiscordModule
{ {
public static ConcurrentDictionary<ulong, MusicPlayer> MusicPlayers = new ConcurrentDictionary<ulong, MusicPlayer>(); public static ConcurrentDictionary<ulong, MusicPlayer> MusicPlayers { get; } = new ConcurrentDictionary<ulong, MusicPlayer>();
public const string MusicDataPath = "data/musicdata"; public const string MusicDataPath = "data/musicdata";
private IGoogleApiService _google;
public Music(ILocalization loc, CommandService cmds, ShardedDiscordClient client, IGoogleApiService google) : base(loc, cmds, client) public Music() : base()
{ {
//it can fail if its currenctly opened or doesn't exist. Either way i don't care //it can fail if its currenctly opened or doesn't exist. Either way i don't care
try { Directory.Delete(MusicDataPath, true); } catch { } try { Directory.Delete(MusicDataPath, true); } catch { }
Directory.CreateDirectory(MusicDataPath); Directory.CreateDirectory(MusicDataPath);
_google = google;
} }
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
@ -259,13 +256,13 @@ namespace NadekoBot.Modules.Music
await channel.SendMessageAsync("💢 You need to be in a voice channel on this server.\n If you are already in a voice channel, try rejoining it.").ConfigureAwait(false); await channel.SendMessageAsync("💢 You need to be in a voice channel on this server.\n If you are already in a voice channel, try rejoining it.").ConfigureAwait(false);
return; return;
} }
var plId = (await _google.GetPlaylistIdsByKeywordsAsync(arg).ConfigureAwait(false)).FirstOrDefault(); var plId = (await NadekoBot.Google.GetPlaylistIdsByKeywordsAsync(arg).ConfigureAwait(false)).FirstOrDefault();
if (plId == null) if (plId == null)
{ {
await channel.SendMessageAsync("No search results for that query."); await channel.SendMessageAsync("No search results for that query.");
return; return;
} }
var ids = await _google.GetPlaylistTracksAsync(plId, 500).ConfigureAwait(false); var ids = await NadekoBot.Google.GetPlaylistTracksAsync(plId, 500).ConfigureAwait(false);
if (!ids.Any()) if (!ids.Any())
{ {
await channel.SendMessageAsync($"🎵 `Failed to find any songs.`").ConfigureAwait(false); await channel.SendMessageAsync($"🎵 `Failed to find any songs.`").ConfigureAwait(false);

View File

@ -16,7 +16,7 @@ namespace NadekoBot.Modules.NSFW
[NadekoModule("NSFW", "~")] [NadekoModule("NSFW", "~")]
public class NSFW : DiscordModule public class NSFW : DiscordModule
{ {
public NSFW(ILocalization loc, CommandService cmds, ShardedDiscordClient client) : base(loc, cmds, client) public NSFW() : base()
{ {
} }

View File

@ -24,7 +24,7 @@ namespace NadekoBot.Modules.Permissions
public class CmdCdsCommands public class CmdCdsCommands
{ {
public static ConcurrentDictionary<ulong, ConcurrentHashSet<CommandCooldown>> commandCooldowns { get; } public static ConcurrentDictionary<ulong, ConcurrentHashSet<CommandCooldown>> commandCooldowns { get; }
private static ConcurrentDictionary<ulong, ConcurrentHashSet<ActiveCooldown>> activeCooldowns = new ConcurrentDictionary<ulong, ConcurrentHashSet<ActiveCooldown>>(); private static ConcurrentDictionary<ulong, ConcurrentHashSet<ActiveCooldown>> activeCooldowns { get; } = new ConcurrentDictionary<ulong, ConcurrentHashSet<ActiveCooldown>>();
static CmdCdsCommands() static CmdCdsCommands()
{ {

View File

@ -14,14 +14,14 @@ namespace NadekoBot.Modules.Permissions
[Group] [Group]
public class FilterCommands public class FilterCommands
{ {
public static ConcurrentHashSet<ulong> InviteFilteringChannels { get; set; } public static ConcurrentHashSet<ulong> InviteFilteringChannels { get; }
public static ConcurrentHashSet<ulong> InviteFilteringServers { get; set; } public static ConcurrentHashSet<ulong> InviteFilteringServers { get; }
//serverid, filteredwords //serverid, filteredwords
private static ConcurrentDictionary<ulong, ConcurrentHashSet<string>> ServerFilteredWords { get; set; } private static ConcurrentDictionary<ulong, ConcurrentHashSet<string>> ServerFilteredWords { get; }
public static ConcurrentHashSet<ulong> WordFilteringChannels { get; set; } public static ConcurrentHashSet<ulong> WordFilteringChannels { get; }
public static ConcurrentHashSet<ulong> WordFilteringServers { get; set; } public static ConcurrentHashSet<ulong> WordFilteringServers { get; }
public static ConcurrentHashSet<string> FilteredWordsForChannel(ulong channelId, ulong guildId) public static ConcurrentHashSet<string> FilteredWordsForChannel(ulong channelId, ulong guildId)
{ {

View File

@ -21,7 +21,7 @@ namespace NadekoBot.Modules.Permissions
} }
//guildid, root permission //guildid, root permission
public static ConcurrentDictionary<ulong, PermissionCache> Cache; public static ConcurrentDictionary<ulong, PermissionCache> Cache { get; }
static Permissions() static Permissions()
{ {
@ -39,7 +39,7 @@ namespace NadekoBot.Modules.Permissions
} }
} }
public Permissions(ILocalization loc, CommandService cmds, ShardedDiscordClient client) : base(loc, cmds, client) public Permissions() : base()
{ {
} }

View File

@ -27,7 +27,7 @@ namespace NadekoBot.Modules.Pokemon
private Logger _pokelog { get; } private Logger _pokelog { get; }
public Pokemon(ILocalization loc, CommandService cmds, ShardedDiscordClient client) : base(loc, cmds, client) public Pokemon() : base()
{ {
_pokelog = LogManager.GetCurrentClassLogger(); _pokelog = LogManager.GetCurrentClassLogger();
if (File.Exists(PokemonTypesFile)) if (File.Exists(PokemonTypesFile))

View File

@ -10,6 +10,7 @@ using NLog;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Net.Http; using System.Net.Http;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace NadekoBot.Modules.Searches namespace NadekoBot.Modules.Searches
@ -19,14 +20,30 @@ namespace NadekoBot.Modules.Searches
[Group] [Group]
public class AnimeSearchCommands public class AnimeSearchCommands
{ {
private Logger _log; private static Timer anilistTokenRefresher { get; }
private static Logger _log { get; }
private static string anilistToken { get; set; }
private string anilistToken { get; set; } static AnimeSearchCommands()
private DateTime lastRefresh { get; set; }
public AnimeSearchCommands()
{ {
_log = LogManager.GetCurrentClassLogger(); _log = LogManager.GetCurrentClassLogger();
anilistTokenRefresher = new Timer(async (state) =>
{
var headers = new Dictionary<string, string> {
{"grant_type", "client_credentials"},
{"client_id", "kwoth-w0ki9"},
{"client_secret", "Qd6j4FIAi1ZK6Pc7N7V4Z"},
};
using (var http = new HttpClient())
{
http.AddFakeHeaders();
var formContent = new FormUrlEncodedContent(headers);
var response = await http.PostAsync("http://anilist.co/api/auth/access_token", formContent).ConfigureAwait(false);
var stringContent = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
anilistToken = JObject.Parse(stringContent)["access_token"].ToString();
}
}, null, TimeSpan.FromSeconds(0), TimeSpan.FromMinutes(29));
} }
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
@ -119,7 +136,6 @@ namespace NadekoBot.Modules.Searches
throw new ArgumentNullException(nameof(query)); throw new ArgumentNullException(nameof(query));
try try
{ {
await RefreshAnilistToken().ConfigureAwait(false);
var link = "http://anilist.co/api/anime/search/" + Uri.EscapeUriString(query); var link = "http://anilist.co/api/anime/search/" + Uri.EscapeUriString(query);
using (var http = new HttpClient()) using (var http = new HttpClient())
@ -137,37 +153,12 @@ namespace NadekoBot.Modules.Searches
} }
} }
private async Task RefreshAnilistToken()
{
if (DateTime.Now - lastRefresh > TimeSpan.FromMinutes(29))
lastRefresh = DateTime.Now;
else
{
return;
}
var headers = new Dictionary<string, string> {
{"grant_type", "client_credentials"},
{"client_id", "kwoth-w0ki9"},
{"client_secret", "Qd6j4FIAi1ZK6Pc7N7V4Z"},
};
using (var http = new HttpClient())
{
http.AddFakeHeaders();
var formContent = new FormUrlEncodedContent(headers);
var response = await http.PostAsync("http://anilist.co/api/auth/access_token", formContent).ConfigureAwait(false);
var stringContent = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
anilistToken = JObject.Parse(stringContent)["access_token"].ToString();
}
}
private async Task<MangaResult> GetMangaData(string query) private async Task<MangaResult> GetMangaData(string query)
{ {
if (string.IsNullOrWhiteSpace(query)) if (string.IsNullOrWhiteSpace(query))
throw new ArgumentNullException(nameof(query)); throw new ArgumentNullException(nameof(query));
try try
{ {
await RefreshAnilistToken().ConfigureAwait(false);
using (var http = new HttpClient()) using (var http = new HttpClient())
{ {
var res = await http.GetStringAsync("http://anilist.co/api/manga/search/" + Uri.EscapeUriString(query) + $"?access_token={anilistToken}").ConfigureAwait(false); var res = await http.GetStringAsync("http://anilist.co/api/manga/search/" + Uri.EscapeUriString(query) + $"?access_token={anilistToken}").ConfigureAwait(false);

View File

@ -19,11 +19,11 @@ namespace NadekoBot.Modules.Searches
[Group] [Group]
public class JokeCommands public class JokeCommands
{ {
private List<WoWJoke> wowJokes = new List<WoWJoke>(); private static List<WoWJoke> wowJokes = new List<WoWJoke>();
private List<MagicItem> magicItems; private static List<MagicItem> magicItems;
private Logger _log; private static Logger _log;
public JokeCommands() static JokeCommands()
{ {
_log = LogManager.GetCurrentClassLogger(); _log = LogManager.GetCurrentClassLogger();
if (File.Exists("data/wowjokes.json")) if (File.Exists("data/wowjokes.json"))

View File

@ -23,7 +23,7 @@ namespace NadekoBot.Modules.Searches
obj["name"].GetHashCode(); obj["name"].GetHashCode();
} }
private string[] trashTalk { get; } = { "Better ban your counters. You are going to carry the game anyway.", private static string[] trashTalk { get; } = { "Better ban your counters. You are going to carry the game anyway.",
"Go with the flow. Don't think. Just ban one of these.", "Go with the flow. Don't think. Just ban one of these.",
"DONT READ BELOW! Ban Urgot mid OP 100%. Im smurf Diamond 1.", "DONT READ BELOW! Ban Urgot mid OP 100%. Im smurf Diamond 1.",
"Ask your teammates what would they like to play, and ban that.", "Ask your teammates what would they like to play, and ban that.",

View File

@ -18,9 +18,9 @@ namespace NadekoBot.Modules.Searches
[Group] [Group]
public class OsuCommands public class OsuCommands
{ {
private Logger _log; private static Logger _log;
public OsuCommands() static OsuCommands()
{ {
_log = LogManager.GetCurrentClassLogger(); _log = LogManager.GetCurrentClassLogger();
} }

View File

@ -21,9 +21,9 @@ namespace NadekoBot.Modules.Searches
public const string PokemonAbilitiesFile = "data/pokemon/pokemon_abilities.json"; public const string PokemonAbilitiesFile = "data/pokemon/pokemon_abilities.json";
public const string PokemonListFile = "data/pokemon/pokemon_list.json"; public const string PokemonListFile = "data/pokemon/pokemon_list.json";
private Logger _log; private static Logger _log;
public PokemonSearchCommands() static PokemonSearchCommands()
{ {
_log = LogManager.GetCurrentClassLogger(); _log = LogManager.GetCurrentClassLogger();
if (File.Exists(PokemonListFile)) if (File.Exists(PokemonListFile))

View File

@ -69,14 +69,14 @@ namespace NadekoBot.Modules.Searches
[Group] [Group]
public class StreamNotificationCommands public class StreamNotificationCommands
{ {
private Timer checkTimer { get; } private static Timer checkTimer { get; }
private ConcurrentDictionary<string, StreamStatus> oldCachedStatuses = new ConcurrentDictionary<string, StreamStatus>(); private static ConcurrentDictionary<string, StreamStatus> oldCachedStatuses = new ConcurrentDictionary<string, StreamStatus>();
private ConcurrentDictionary<string, StreamStatus> cachedStatuses = new ConcurrentDictionary<string, StreamStatus>(); private static ConcurrentDictionary<string, StreamStatus> cachedStatuses = new ConcurrentDictionary<string, StreamStatus>();
private Logger _log { get; } private static Logger _log { get; }
private bool FirstPass { get; set; } = true; private static bool FirstPass { get; set; } = true;
public StreamNotificationCommands() static StreamNotificationCommands()
{ {
_log = NLog.LogManager.GetCurrentClassLogger(); _log = NLog.LogManager.GetCurrentClassLogger();
@ -118,7 +118,7 @@ namespace NadekoBot.Modules.Searches
}, null, TimeSpan.Zero, TimeSpan.FromSeconds(60)); }, null, TimeSpan.Zero, TimeSpan.FromSeconds(60));
} }
private async Task<StreamStatus> GetStreamStatus(FollowedStream stream, bool checkCache = true) private static async Task<StreamStatus> GetStreamStatus(FollowedStream stream, bool checkCache = true)
{ {
string response; string response;
StreamStatus result; StreamStatus result;

View File

@ -23,13 +23,6 @@ namespace NadekoBot.Modules.Searches
[NadekoModule("Searches", "~")] [NadekoModule("Searches", "~")]
public partial class Searches : DiscordModule public partial class Searches : DiscordModule
{ {
private IGoogleApiService _google { get; }
public Searches(ILocalization loc, CommandService cmds, ShardedDiscordClient client, IGoogleApiService youtube) : base(loc, cmds, client)
{
_google = youtube;
}
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)] [RequireContext(ContextType.Guild)]
public async Task Weather(IUserMessage umsg, string city, string country) public async Task Weather(IUserMessage umsg, string city, string country)
@ -63,7 +56,7 @@ namespace NadekoBot.Modules.Searches
{ {
var channel = (ITextChannel)umsg.Channel; var channel = (ITextChannel)umsg.Channel;
if (!(await ValidateQuery(channel, query).ConfigureAwait(false))) return; if (!(await ValidateQuery(channel, query).ConfigureAwait(false))) return;
var result = (await _google.GetVideosByKeywordsAsync(query, 1)).FirstOrDefault(); var result = (await NadekoBot.Google.GetVideosByKeywordsAsync(query, 1)).FirstOrDefault();
if (string.IsNullOrWhiteSpace(result)) if (string.IsNullOrWhiteSpace(result))
{ {
await channel.SendMessageAsync("No results found for that query."); await channel.SendMessageAsync("No results found for that query.");
@ -186,7 +179,7 @@ namespace NadekoBot.Modules.Searches
if (string.IsNullOrWhiteSpace(ffs)) if (string.IsNullOrWhiteSpace(ffs))
return; return;
await channel.SendMessageAsync(await _google.ShortenUrl($"<http://lmgtfy.com/?q={ Uri.EscapeUriString(ffs) }>")) await channel.SendMessageAsync(await NadekoBot.Google.ShortenUrl($"<http://lmgtfy.com/?q={ Uri.EscapeUriString(ffs) }>"))
.ConfigureAwait(false); .ConfigureAwait(false);
} }
@ -240,7 +233,7 @@ namespace NadekoBot.Modules.Searches
throw new KeyNotFoundException("Cannot find a card by that name"); throw new KeyNotFoundException("Cannot find a card by that name");
var msg = $@"```css var msg = $@"```css
[☕ Magic The Gathering]: {items[0]["name"].ToString()} [☕ Magic The Gathering]: {items[0]["name"].ToString()}
[Store URL]: {await _google.ShortenUrl(items[0]["store_url"].ToString())} [Store URL]: {await NadekoBot.Google.ShortenUrl(items[0]["store_url"].ToString())}
[Cost]: {items[0]["cost"].ToString()} [Cost]: {items[0]["cost"].ToString()}
[Description]: {items[0]["text"].ToString()} [Description]: {items[0]["text"].ToString()}
``` ```
@ -387,7 +380,7 @@ namespace NadekoBot.Modules.Searches
var sb = new StringBuilder(); var sb = new StringBuilder();
sb.AppendLine($"`Term:` {items["list"][0]["word"].ToString()}"); sb.AppendLine($"`Term:` {items["list"][0]["word"].ToString()}");
sb.AppendLine($"`Definition:` {items["list"][0]["definition"].ToString()}"); sb.AppendLine($"`Definition:` {items["list"][0]["definition"].ToString()}");
sb.Append($"`Link:` <{await _google.ShortenUrl(items["list"][0]["permalink"].ToString()).ConfigureAwait(false)}>"); sb.Append($"`Link:` <{await NadekoBot.Google.ShortenUrl(items["list"][0]["permalink"].ToString()).ConfigureAwait(false)}>");
await channel.SendMessageAsync(sb.ToString()); await channel.SendMessageAsync(sb.ToString());
} }
catch catch
@ -429,7 +422,7 @@ namespace NadekoBot.Modules.Searches
var items = JObject.Parse(res); var items = JObject.Parse(res);
var str = $@"`Hashtag:` {items["defs"]["def"]["hashtag"].ToString()} var str = $@"`Hashtag:` {items["defs"]["def"]["hashtag"].ToString()}
`Definition:` {items["defs"]["def"]["text"].ToString()} `Definition:` {items["defs"]["def"]["text"].ToString()}
`Link:` <{await _google.ShortenUrl(items["defs"]["def"]["uri"].ToString()).ConfigureAwait(false)}>"; `Link:` <{await NadekoBot.Google.ShortenUrl(items["defs"]["def"]["uri"].ToString()).ConfigureAwait(false)}>";
await channel.SendMessageAsync(str); await channel.SendMessageAsync(str);
} }
catch catch
@ -564,7 +557,7 @@ namespace NadekoBot.Modules.Searches
await channel.SendMessageAsync("Invalid user specified.").ConfigureAwait(false); await channel.SendMessageAsync("Invalid user specified.").ConfigureAwait(false);
return; return;
} }
await channel.SendMessageAsync(await _google.ShortenUrl(usr.AvatarUrl).ConfigureAwait(false)).ConfigureAwait(false); await channel.SendMessageAsync(await NadekoBot.Google.ShortenUrl(usr.AvatarUrl).ConfigureAwait(false)).ConfigureAwait(false);
} }
public static async Task<string> GetSafebooruImageLink(string tag) public static async Task<string> GetSafebooruImageLink(string tag)

View File

@ -22,7 +22,7 @@ namespace NadekoBot.Modules.Utility
if (guild == null) if (guild == null)
server = channel.Guild; server = channel.Guild;
else else
server = _client.GetGuilds().Where(g => g.Name.ToUpperInvariant() == guild.ToUpperInvariant()).FirstOrDefault(); server = NadekoBot.Client.GetGuilds().Where(g => g.Name.ToUpperInvariant() == guild.ToUpperInvariant()).FirstOrDefault();
if (server == null) if (server == null)
return; return;

View File

@ -22,7 +22,7 @@ namespace NadekoBot.Modules.Utility
[NadekoModule("Utility", ".")] [NadekoModule("Utility", ".")]
public partial class Utility : DiscordModule public partial class Utility : DiscordModule
{ {
public Utility(ILocalization loc, CommandService cmds, ShardedDiscordClient client) : base(loc, cmds, client) public Utility() : base()
{ {
} }
@ -236,8 +236,11 @@ namespace NadekoBot.Modules.Utility
var result = string.Join("\n", matches.Cast<Match>() var result = string.Join("\n", matches.Cast<Match>()
.Select(m => $"**Name:** {m.Groups["name"]} **Link:** http://discordapp.com/api/emojis/{m.Groups["id"]}.png")); .Select(m => $"**Name:** {m.Groups["name"]} **Link:** http://discordapp.com/api/emojis/{m.Groups["id"]}.png"));
await msg.Channel.SendMessageAsync(result).ConfigureAwait(false); if (string.IsNullOrWhiteSpace(result))
await msg.Channel.SendErrorAsync("No special emojis found.");
else
await msg.Channel.SendMessageAsync(result).ConfigureAwait(false);
} }
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]

View File

@ -30,7 +30,6 @@ namespace NadekoBot
public static CommandService CommandService { get; private set; } public static CommandService CommandService { get; private set; }
public static CommandHandler CommandHandler { get; private set; } public static CommandHandler CommandHandler { get; private set; }
public static ShardedDiscordClient Client { get; private set; } public static ShardedDiscordClient Client { get; private set; }
public static Localization Localizer { get; private set; }
public static BotCredentials Credentials { get; private set; } public static BotCredentials Credentials { get; private set; }
public static GoogleApiService Google { get; private set; } public static GoogleApiService Google { get; private set; }
@ -70,17 +69,16 @@ namespace NadekoBot
//initialize Services //initialize Services
CommandService = new CommandService(); CommandService = new CommandService();
Localizer = new Localization();
Google = new GoogleApiService(); Google = new GoogleApiService();
CommandHandler = new CommandHandler(Client, CommandService); CommandHandler = new CommandHandler(Client, CommandService);
Stats = new StatsService(Client, CommandHandler); Stats = new StatsService(Client, CommandHandler);
//setup DI ////setup DI
var depMap = new DependencyMap(); //var depMap = new DependencyMap();
depMap.Add<ILocalization>(Localizer); //depMap.Add<ILocalization>(Localizer);
depMap.Add<ShardedDiscordClient>(Client); //depMap.Add<ShardedDiscordClient>(Client);
depMap.Add<CommandService>(CommandService); //depMap.Add<CommandService>(CommandService);
depMap.Add<IGoogleApiService>(Google); //depMap.Add<IGoogleApiService>(Google);
//setup typereaders //setup typereaders
@ -104,9 +102,9 @@ namespace NadekoBot
// start handling messages received in commandhandler // start handling messages received in commandhandler
await CommandHandler.StartHandling().ConfigureAwait(false); await CommandHandler.StartHandling().ConfigureAwait(false);
await CommandService.LoadAssembly(this.GetType().GetTypeInfo().Assembly, depMap).ConfigureAwait(false); await CommandService.LoadAssembly(this.GetType().GetTypeInfo().Assembly).ConfigureAwait(false);
#if !GLOBAL_NADEKO #if !GLOBAL_NADEKO
await CommandService.Load(new Music(Localizer, CommandService, Client, Google)).ConfigureAwait(false); await CommandService.Load(new Music()).ConfigureAwait(false);
#endif #endif
Ready = true; Ready = true;
Console.WriteLine(await Stats.Print().ConfigureAwait(false)); Console.WriteLine(await Stats.Print().ConfigureAwait(false));

View File

@ -39,7 +39,7 @@ namespace NadekoBot.Services
private List<IDMChannel> ownerChannels { get; set; } private List<IDMChannel> ownerChannels { get; set; }
public event EventHandler<CommandExecutedEventArgs> CommandExecuted = delegate { }; public event Func<IUserMessage,Command, Task> CommandExecuted = delegate { return Task.CompletedTask; };
public CommandHandler(ShardedDiscordClient client, CommandService commandService) public CommandHandler(ShardedDiscordClient client, CommandService commandService)
{ {
@ -154,7 +154,7 @@ namespace NadekoBot.Services
var channel = (usrMsg.Channel as ITextChannel); var channel = (usrMsg.Channel as ITextChannel);
if (result.IsSuccess) if (result.IsSuccess)
{ {
CommandExecuted(this, new CommandExecutedEventArgs(usrMsg, command)); await CommandExecuted(usrMsg, command);
_log.Info("Command Executed after {4}s\n\t" + _log.Info("Command Executed after {4}s\n\t" +
"User: {0}\n\t" + "User: {0}\n\t" +
"Server: {1}\n\t" + "Server: {1}\n\t" +

View File

@ -1,7 +0,0 @@
namespace NadekoBot.Services
{
public interface ILocalization
{
string this[string key] { get; }
}
}

View File

@ -1,6 +1,6 @@
namespace NadekoBot.Services namespace NadekoBot.Services
{ {
public class Localization : ILocalization public class Localization
{ {
public string this[string key] => LoadCommandString(key); public string this[string key] => LoadCommandString(key);

View File

@ -31,14 +31,14 @@ namespace NadekoBot.Services.Impl
Timer carbonitexTimer { get; } Timer carbonitexTimer { get; }
public StatsService(ShardedDiscordClient client, CommandHandler cmdHandler) public StatsService(ShardedDiscordClient client, CommandHandler cmdHandler)
{ {
this.client = client; this.client = client;
Reset(); Reset();
this.client.MessageReceived += _ => Task.FromResult(MessageCounter++); this.client.MessageReceived += _ => Task.FromResult(MessageCounter++);
cmdHandler.CommandExecuted += (_, e) => CommandsRan++; cmdHandler.CommandExecuted += (_, e) => Task.FromResult(CommandsRan++);
this.client.Disconnected += _ => Reset(); this.client.Disconnected += _ => Reset();

View File

@ -79,80 +79,7 @@ namespace NadekoBot.Extensions
public static IEnumerable<IUser> Members(this IRole role) => public static IEnumerable<IUser> Members(this IRole role) =>
NadekoBot.Client.GetGuild(role.GuildId)?.GetUsers().Where(u => u.Roles.Contains(role)) ?? Enumerable.Empty<IUser>(); NadekoBot.Client.GetGuild(role.GuildId)?.GetUsers().Where(u => u.Roles.Contains(role)) ?? Enumerable.Empty<IUser>();
public static async Task<IUserMessage[]> ReplyLong(this IUserMessage msg, string content, string[] breakOn = null, string addToPartialEnd = "", string addToPartialStart = "")
{
if (content.Length == 0) return null;
var characterLimit = 1750;
if (content.Length < characterLimit) return new[] { await msg.Channel.SendMessageAsync(content).ConfigureAwait(false) };
if (breakOn == null) breakOn = new[] { "\n", " ", " " };
var list = new List<IUserMessage>();
var splitItems = new List<string>();
foreach (var breaker in breakOn)
{
if (splitItems.Count == 0)
{
splitItems = Regex.Split(content, $"(?={breaker})").Where(s => !string.IsNullOrWhiteSpace(s)).ToList();
}
else
{
for (int i = 0; i < splitItems.Count; i++)
{
var temp = splitItems[i];
if (temp.Length > characterLimit)
{
var splitDeep = Regex.Split(temp, $"(?={breaker})").Where(s => !string.IsNullOrWhiteSpace(s));
splitItems.RemoveAt(i);
splitItems.InsertRange(i, splitDeep);
}
}
}
if (splitItems.All(s => s.Length < characterLimit)) break;
}
//We remove any entries that are larger than 2000 chars
if (splitItems.Any(s => s.Length >= characterLimit))
{
splitItems = splitItems.Where(s => s.Length < characterLimit).ToList();
}
//ensured every item can be sent (if individually)
var firstItem = true;
Queue<string> buildItems = new Queue<string>(splitItems);
StringBuilder builder = new StringBuilder();
while (buildItems.Count > 0)
{
if (builder.Length == 0)
{
//first item to add
if (!firstItem)
builder.Append(addToPartialStart);
else
firstItem = false;
builder.Append(buildItems.Dequeue());
}
else
{
builder.Append(buildItems.Dequeue());
}
if (buildItems.Count == 0)
{
list.Add(await msg.Channel.SendMessageAsync(builder.ToString()));
builder.Clear();
}
else
{
var peeked = buildItems.Peek();
if (builder.Length + peeked.Length + addToPartialEnd.Length > characterLimit)
{
builder.Append(addToPartialEnd);
list.Add(await msg.Channel.SendMessageAsync(builder.ToString()));
builder.Clear();
}
}
}
return list.ToArray();
}
public static Task<IUserMessage> EmbedAsync(this IMessageChannel ch, Discord.API.Embed embed, string msg = "") public static Task<IUserMessage> EmbedAsync(this IMessageChannel ch, Discord.API.Embed embed, string msg = "")
=> ch.SendMessageAsync(msg, embed: embed); => ch.SendMessageAsync(msg, embed: embed);

View File

@ -60,8 +60,11 @@
}, },
"configurations": { "configurations": {
"GlobalNadeko": { "GlobalNadeko": {
"buildOptions": { "define": [ "GLOBAL_NADEKO" ] }, "buildOptions": {
"compilationOptions": { "optimize": true } "define": [ "GLOBAL_NADEKO" ],
"nowarn": [ "CS1573", "CS1591" ],
"optimize": true
}
} }
} }
} }