Huge cleanup,
rewrite of the NadekoBot.cs, way services are loaded has changed. Updated discord.net.
This commit is contained in:
parent
f239c46e20
commit
4eca5be1d4
@ -9,17 +9,10 @@ namespace NadekoBot.TypeReaders
|
|||||||
{
|
{
|
||||||
public class CommandTypeReader : TypeReader
|
public class CommandTypeReader : TypeReader
|
||||||
{
|
{
|
||||||
private readonly CommandService _cmds;
|
public override Task<TypeReaderResult> Read(ICommandContext context, string input, IServiceProvider services)
|
||||||
private readonly CommandHandler _cmdHandler;
|
|
||||||
|
|
||||||
public CommandTypeReader(CommandService cmds, CommandHandler cmdHandler)
|
|
||||||
{
|
|
||||||
_cmds = cmds;
|
|
||||||
_cmdHandler = cmdHandler;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override Task<TypeReaderResult> Read(ICommandContext context, string input, IServiceProvider _)
|
|
||||||
{
|
{
|
||||||
|
var _cmds = ((INServiceProvider)services).GetService<CommandService>();
|
||||||
|
var _cmdHandler = ((INServiceProvider)services).GetService<CommandHandler>();
|
||||||
input = input.ToUpperInvariant();
|
input = input.ToUpperInvariant();
|
||||||
var prefix = _cmdHandler.GetPrefix(context.Guild);
|
var prefix = _cmdHandler.GetPrefix(context.Guild);
|
||||||
if (!input.StartsWith(prefix.ToUpperInvariant()))
|
if (!input.StartsWith(prefix.ToUpperInvariant()))
|
||||||
@ -38,17 +31,12 @@ namespace NadekoBot.TypeReaders
|
|||||||
|
|
||||||
public class CommandOrCrTypeReader : CommandTypeReader
|
public class CommandOrCrTypeReader : CommandTypeReader
|
||||||
{
|
{
|
||||||
private readonly CustomReactionsService _crs;
|
public override async Task<TypeReaderResult> Read(ICommandContext context, string input, IServiceProvider services)
|
||||||
|
|
||||||
public CommandOrCrTypeReader(CustomReactionsService crs, CommandService cmds, CommandHandler cmdHandler) : base(cmds, cmdHandler)
|
|
||||||
{
|
|
||||||
_crs = crs;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override async Task<TypeReaderResult> Read(ICommandContext context, string input, IServiceProvider _)
|
|
||||||
{
|
{
|
||||||
input = input.ToUpperInvariant();
|
input = input.ToUpperInvariant();
|
||||||
|
|
||||||
|
var _crs = ((INServiceProvider)services).GetService<CustomReactionsService>();
|
||||||
|
|
||||||
if (_crs.GlobalReactions.Any(x => x.Trigger.ToUpperInvariant() == input))
|
if (_crs.GlobalReactions.Any(x => x.Trigger.ToUpperInvariant() == input))
|
||||||
{
|
{
|
||||||
return TypeReaderResult.FromSuccess(new CommandOrCrInfo(input));
|
return TypeReaderResult.FromSuccess(new CommandOrCrInfo(input));
|
||||||
@ -65,7 +53,7 @@ namespace NadekoBot.TypeReaders
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var cmd = await base.Read(context, input, _);
|
var cmd = await base.Read(context, input, services);
|
||||||
if (cmd.IsSuccess)
|
if (cmd.IsSuccess)
|
||||||
{
|
{
|
||||||
return TypeReaderResult.FromSuccess(new CommandOrCrInfo(((CommandInfo)cmd.Values.First().Value).Name));
|
return TypeReaderResult.FromSuccess(new CommandOrCrInfo(((CommandInfo)cmd.Values.First().Value).Name));
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using Discord.Commands;
|
using Discord.Commands;
|
||||||
|
using NadekoBot.Services;
|
||||||
using NadekoBot.Services.Administration;
|
using NadekoBot.Services.Administration;
|
||||||
using System;
|
using System;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
@ -7,15 +8,9 @@ namespace NadekoBot.TypeReaders
|
|||||||
{
|
{
|
||||||
public class GuildDateTimeTypeReader : TypeReader
|
public class GuildDateTimeTypeReader : TypeReader
|
||||||
{
|
{
|
||||||
private readonly GuildTimezoneService _gts;
|
public override Task<TypeReaderResult> Read(ICommandContext context, string input, IServiceProvider services)
|
||||||
|
|
||||||
public GuildDateTimeTypeReader(GuildTimezoneService gts)
|
|
||||||
{
|
|
||||||
_gts = gts;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override Task<TypeReaderResult> Read(ICommandContext context, string input, IServiceProvider _)
|
|
||||||
{
|
{
|
||||||
|
var _gts = (GuildTimezoneService)services.GetService(typeof(GuildTimezoneService));
|
||||||
if (!DateTime.TryParse(input, out var dt))
|
if (!DateTime.TryParse(input, out var dt))
|
||||||
return Task.FromResult(TypeReaderResult.FromError(CommandError.ParseFailed, "Input string is in an incorrect format."));
|
return Task.FromResult(TypeReaderResult.FromError(CommandError.ParseFailed, "Input string is in an incorrect format."));
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ namespace NadekoBot.Modules.Administration
|
|||||||
[NadekoCommand, Usage, Description, Aliases]
|
[NadekoCommand, Usage, Description, Aliases]
|
||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
[RequireUserPermission(GuildPermission.ManageRoles)]
|
[RequireUserPermission(GuildPermission.ManageRoles)]
|
||||||
[Priority(1)]
|
[Priority(0)]
|
||||||
public async Task SetMuteRole([Remainder] string name)
|
public async Task SetMuteRole([Remainder] string name)
|
||||||
{
|
{
|
||||||
name = name.Trim();
|
name = name.Trim();
|
||||||
@ -45,7 +45,7 @@ namespace NadekoBot.Modules.Administration
|
|||||||
[NadekoCommand, Usage, Description, Aliases]
|
[NadekoCommand, Usage, Description, Aliases]
|
||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
[RequireUserPermission(GuildPermission.ManageRoles)]
|
[RequireUserPermission(GuildPermission.ManageRoles)]
|
||||||
[Priority(0)]
|
[Priority(1)]
|
||||||
public Task SetMuteRole([Remainder] IRole role)
|
public Task SetMuteRole([Remainder] IRole role)
|
||||||
=> SetMuteRole(role.Name);
|
=> SetMuteRole(role.Name);
|
||||||
|
|
||||||
@ -53,7 +53,7 @@ namespace NadekoBot.Modules.Administration
|
|||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
[RequireUserPermission(GuildPermission.ManageRoles)]
|
[RequireUserPermission(GuildPermission.ManageRoles)]
|
||||||
[RequireUserPermission(GuildPermission.MuteMembers)]
|
[RequireUserPermission(GuildPermission.MuteMembers)]
|
||||||
[Priority(1)]
|
[Priority(0)]
|
||||||
public async Task Mute(IGuildUser user)
|
public async Task Mute(IGuildUser user)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@ -71,7 +71,7 @@ namespace NadekoBot.Modules.Administration
|
|||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
[RequireUserPermission(GuildPermission.ManageRoles)]
|
[RequireUserPermission(GuildPermission.ManageRoles)]
|
||||||
[RequireUserPermission(GuildPermission.MuteMembers)]
|
[RequireUserPermission(GuildPermission.MuteMembers)]
|
||||||
[Priority(0)]
|
[Priority(1)]
|
||||||
public async Task Mute(int minutes, IGuildUser user)
|
public async Task Mute(int minutes, IGuildUser user)
|
||||||
{
|
{
|
||||||
if (minutes < 1 || minutes > 1440)
|
if (minutes < 1 || minutes > 1440)
|
||||||
|
@ -11,7 +11,7 @@ namespace NadekoBot.Modules.Administration
|
|||||||
public class PrefixCommands : NadekoSubmodule
|
public class PrefixCommands : NadekoSubmodule
|
||||||
{
|
{
|
||||||
[NadekoCommand, Usage, Description, Aliases]
|
[NadekoCommand, Usage, Description, Aliases]
|
||||||
[Priority(0)]
|
[Priority(1)]
|
||||||
public new async Task Prefix()
|
public new async Task Prefix()
|
||||||
{
|
{
|
||||||
await ReplyConfirmLocalized("prefix_current", Format.Code(_cmdHandler.GetPrefix(Context.Guild))).ConfigureAwait(false);
|
await ReplyConfirmLocalized("prefix_current", Format.Code(_cmdHandler.GetPrefix(Context.Guild))).ConfigureAwait(false);
|
||||||
@ -21,7 +21,7 @@ namespace NadekoBot.Modules.Administration
|
|||||||
[NadekoCommand, Usage, Description, Aliases]
|
[NadekoCommand, Usage, Description, Aliases]
|
||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
[RequireUserPermission(GuildPermission.Administrator)]
|
[RequireUserPermission(GuildPermission.Administrator)]
|
||||||
[Priority(1)]
|
[Priority(0)]
|
||||||
public new async Task Prefix([Remainder]string prefix)
|
public new async Task Prefix([Remainder]string prefix)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(prefix))
|
if (string.IsNullOrWhiteSpace(prefix))
|
||||||
|
@ -39,7 +39,7 @@ namespace NadekoBot.Modules.Administration
|
|||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
[RequireUserPermission(ChannelPermission.ManageMessages)]
|
[RequireUserPermission(ChannelPermission.ManageMessages)]
|
||||||
[RequireBotPermission(GuildPermission.ManageMessages)]
|
[RequireBotPermission(GuildPermission.ManageMessages)]
|
||||||
[Priority(0)]
|
[Priority(1)]
|
||||||
public async Task Prune(int count)
|
public async Task Prune(int count)
|
||||||
{
|
{
|
||||||
count++;
|
count++;
|
||||||
@ -55,7 +55,7 @@ namespace NadekoBot.Modules.Administration
|
|||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
[RequireUserPermission(ChannelPermission.ManageMessages)]
|
[RequireUserPermission(ChannelPermission.ManageMessages)]
|
||||||
[RequireBotPermission(GuildPermission.ManageMessages)]
|
[RequireBotPermission(GuildPermission.ManageMessages)]
|
||||||
[Priority(1)]
|
[Priority(0)]
|
||||||
public async Task Prune(IGuildUser user, int count = 100)
|
public async Task Prune(IGuildUser user, int count = 100)
|
||||||
{
|
{
|
||||||
if (user.Id == Context.User.Id)
|
if (user.Id == Context.User.Id)
|
||||||
|
@ -67,7 +67,7 @@ namespace NadekoBot.Modules.Administration
|
|||||||
[NadekoCommand, Usage, Description, Aliases]
|
[NadekoCommand, Usage, Description, Aliases]
|
||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
[RequireUserPermission(GuildPermission.ManageMessages)]
|
[RequireUserPermission(GuildPermission.ManageMessages)]
|
||||||
[Priority(1)]
|
[Priority(0)]
|
||||||
public async Task SlowmodeWhitelist(IGuildUser user)
|
public async Task SlowmodeWhitelist(IGuildUser user)
|
||||||
{
|
{
|
||||||
var siu = new SlowmodeIgnoredUser
|
var siu = new SlowmodeIgnoredUser
|
||||||
@ -99,7 +99,7 @@ namespace NadekoBot.Modules.Administration
|
|||||||
[NadekoCommand, Usage, Description, Aliases]
|
[NadekoCommand, Usage, Description, Aliases]
|
||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
[RequireUserPermission(GuildPermission.ManageMessages)]
|
[RequireUserPermission(GuildPermission.ManageMessages)]
|
||||||
[Priority(0)]
|
[Priority(1)]
|
||||||
public async Task SlowmodeWhitelist(IRole role)
|
public async Task SlowmodeWhitelist(IRole role)
|
||||||
{
|
{
|
||||||
var sir = new SlowmodeIgnoredRole
|
var sir = new SlowmodeIgnoredRole
|
||||||
|
@ -289,7 +289,7 @@ namespace NadekoBot.Modules.Administration
|
|||||||
|
|
||||||
[NadekoCommand, Usage, Description, Aliases]
|
[NadekoCommand, Usage, Description, Aliases]
|
||||||
[RequireUserPermission(GuildPermission.ManageNicknames)]
|
[RequireUserPermission(GuildPermission.ManageNicknames)]
|
||||||
[Priority(1)]
|
[Priority(0)]
|
||||||
public async Task SetNick([Remainder] string newNick = null)
|
public async Task SetNick([Remainder] string newNick = null)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(newNick))
|
if (string.IsNullOrWhiteSpace(newNick))
|
||||||
@ -303,7 +303,7 @@ namespace NadekoBot.Modules.Administration
|
|||||||
[NadekoCommand, Usage, Description, Aliases]
|
[NadekoCommand, Usage, Description, Aliases]
|
||||||
[RequireBotPermission(GuildPermission.ManageNicknames)]
|
[RequireBotPermission(GuildPermission.ManageNicknames)]
|
||||||
[RequireUserPermission(GuildPermission.ManageNicknames)]
|
[RequireUserPermission(GuildPermission.ManageNicknames)]
|
||||||
[Priority(0)]
|
[Priority(1)]
|
||||||
public async Task SetNick(IGuildUser gu, [Remainder] string newNick = null)
|
public async Task SetNick(IGuildUser gu, [Remainder] string newNick = null)
|
||||||
{
|
{
|
||||||
await gu.ModifyAsync(u => u.Nickname = newNick).ConfigureAwait(false);
|
await gu.ModifyAsync(u => u.Nickname = newNick).ConfigureAwait(false);
|
||||||
|
@ -132,27 +132,27 @@ namespace NadekoBot.Modules.Administration
|
|||||||
[NadekoCommand, Usage, Description, Aliases]
|
[NadekoCommand, Usage, Description, Aliases]
|
||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
[RequireUserPermission(GuildPermission.BanMembers)]
|
[RequireUserPermission(GuildPermission.BanMembers)]
|
||||||
[Priority(1)]
|
[Priority(2)]
|
||||||
public Task Warnlog(int page, IGuildUser user)
|
public Task Warnlog(int page, IGuildUser user)
|
||||||
=> Warnlog(page, user.Id);
|
=> Warnlog(page, user.Id);
|
||||||
|
|
||||||
[NadekoCommand, Usage, Description, Aliases]
|
[NadekoCommand, Usage, Description, Aliases]
|
||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
[Priority(0)]
|
[Priority(3)]
|
||||||
public Task Warnlog(IGuildUser user)
|
public Task Warnlog(IGuildUser user)
|
||||||
=> Context.User.Id == user.Id || ((IGuildUser)Context.User).GuildPermissions.BanMembers ? Warnlog(user.Id) : Task.CompletedTask;
|
=> Context.User.Id == user.Id || ((IGuildUser)Context.User).GuildPermissions.BanMembers ? Warnlog(user.Id) : Task.CompletedTask;
|
||||||
|
|
||||||
[NadekoCommand, Usage, Description, Aliases]
|
[NadekoCommand, Usage, Description, Aliases]
|
||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
[RequireUserPermission(GuildPermission.BanMembers)]
|
[RequireUserPermission(GuildPermission.BanMembers)]
|
||||||
[Priority(3)]
|
[Priority(0)]
|
||||||
public Task Warnlog(int page, ulong userId)
|
public Task Warnlog(int page, ulong userId)
|
||||||
=> InternalWarnlog(userId, page - 1);
|
=> InternalWarnlog(userId, page - 1);
|
||||||
|
|
||||||
[NadekoCommand, Usage, Description, Aliases]
|
[NadekoCommand, Usage, Description, Aliases]
|
||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
[RequireUserPermission(GuildPermission.BanMembers)]
|
[RequireUserPermission(GuildPermission.BanMembers)]
|
||||||
[Priority(2)]
|
[Priority(1)]
|
||||||
public Task Warnlog(ulong userId)
|
public Task Warnlog(ulong userId)
|
||||||
=> InternalWarnlog(userId, 0);
|
=> InternalWarnlog(userId, 0);
|
||||||
|
|
||||||
|
@ -1,239 +0,0 @@
|
|||||||
using Discord.Commands;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Discord;
|
|
||||||
using NadekoBot.Attributes;
|
|
||||||
using NadekoBot.Services.Database.Models;
|
|
||||||
using NadekoBot.Extensions;
|
|
||||||
using NadekoBot.Services.ClashOfClans;
|
|
||||||
|
|
||||||
namespace NadekoBot.Modules.ClashOfClans
|
|
||||||
{
|
|
||||||
public class ClashOfClans : NadekoTopLevelModule
|
|
||||||
{
|
|
||||||
private readonly ClashOfClansService _service;
|
|
||||||
|
|
||||||
public ClashOfClans(ClashOfClansService service)
|
|
||||||
{
|
|
||||||
_service = service;
|
|
||||||
}
|
|
||||||
|
|
||||||
[NadekoCommand, Usage, Description, Aliases]
|
|
||||||
[RequireContext(ContextType.Guild)]
|
|
||||||
[RequireUserPermission(GuildPermission.ManageMessages)]
|
|
||||||
public async Task CreateWar(int size, [Remainder] string enemyClan = null)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrWhiteSpace(enemyClan))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (size < 10 || size > 50 || size % 5 != 0)
|
|
||||||
{
|
|
||||||
await ReplyErrorLocalized("invalid_size").ConfigureAwait(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
List<ClashWar> wars;
|
|
||||||
if (!_service.ClashWars.TryGetValue(Context.Guild.Id, out wars))
|
|
||||||
{
|
|
||||||
wars = new List<ClashWar>();
|
|
||||||
if (!_service.ClashWars.TryAdd(Context.Guild.Id, wars))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
var cw = await _service.CreateWar(enemyClan, size, Context.Guild.Id, Context.Channel.Id);
|
|
||||||
|
|
||||||
wars.Add(cw);
|
|
||||||
await ReplyErrorLocalized("war_created", _service.ShortPrint(cw)).ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
[NadekoCommand, Usage, Description, Aliases]
|
|
||||||
[RequireContext(ContextType.Guild)]
|
|
||||||
public async Task StartWar([Remainder] string number = null)
|
|
||||||
{
|
|
||||||
int num = 0;
|
|
||||||
int.TryParse(number, out num);
|
|
||||||
|
|
||||||
var warsInfo = _service.GetWarInfo(Context.Guild, num);
|
|
||||||
if (warsInfo == null)
|
|
||||||
{
|
|
||||||
await ReplyErrorLocalized("war_not_exist").ConfigureAwait(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var war = warsInfo.Item1[warsInfo.Item2];
|
|
||||||
try
|
|
||||||
{
|
|
||||||
war.Start();
|
|
||||||
await ReplyConfirmLocalized("war_started", _service.ShortPrint(war)).ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
await ReplyErrorLocalized("war_already_started", _service.ShortPrint(war)).ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
_service.SaveWar(war);
|
|
||||||
}
|
|
||||||
|
|
||||||
[NadekoCommand, Usage, Description, Aliases]
|
|
||||||
[RequireContext(ContextType.Guild)]
|
|
||||||
public async Task ListWar([Remainder] string number = null)
|
|
||||||
{
|
|
||||||
|
|
||||||
// if number is null, print all wars in a short way
|
|
||||||
if (string.IsNullOrWhiteSpace(number))
|
|
||||||
{
|
|
||||||
//check if there are any wars
|
|
||||||
List<ClashWar> wars = null;
|
|
||||||
_service.ClashWars.TryGetValue(Context.Guild.Id, out wars);
|
|
||||||
if (wars == null || wars.Count == 0)
|
|
||||||
{
|
|
||||||
await ReplyErrorLocalized("no_active_wars").ConfigureAwait(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var sb = new StringBuilder();
|
|
||||||
sb.AppendLine("**-------------------------**");
|
|
||||||
for (var i = 0; i < wars.Count; i++)
|
|
||||||
{
|
|
||||||
sb.AppendLine($"**#{i + 1}.** `{GetText("enemy")}:` **{wars[i].EnemyClan}**");
|
|
||||||
sb.AppendLine($"\t\t`{GetText("size")}:` **{wars[i].Size} v {wars[i].Size}**");
|
|
||||||
sb.AppendLine("**-------------------------**");
|
|
||||||
}
|
|
||||||
await Context.Channel.SendConfirmAsync(GetText("list_active_wars"), sb.ToString()).ConfigureAwait(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var num = 0;
|
|
||||||
int.TryParse(number, out num);
|
|
||||||
//if number is not null, print the war needed
|
|
||||||
var warsInfo = _service.GetWarInfo(Context.Guild, num);
|
|
||||||
if (warsInfo == null)
|
|
||||||
{
|
|
||||||
await ReplyErrorLocalized("war_not_exist").ConfigureAwait(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var war = warsInfo.Item1[warsInfo.Item2];
|
|
||||||
await Context.Channel.SendConfirmAsync(_service.Localize(war, "info_about_war", $"`{war.EnemyClan}` ({war.Size} v {war.Size})"), _service.ToPrettyString(war)).ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
[NadekoCommand, Usage, Description, Aliases]
|
|
||||||
[RequireContext(ContextType.Guild)]
|
|
||||||
public async Task BaseCall(int number, int baseNumber, [Remainder] string other_name = null)
|
|
||||||
{
|
|
||||||
var warsInfo = _service.GetWarInfo(Context.Guild, number);
|
|
||||||
if (warsInfo == null || warsInfo.Item1.Count == 0)
|
|
||||||
{
|
|
||||||
await ReplyErrorLocalized("war_not_exist").ConfigureAwait(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var usr =
|
|
||||||
string.IsNullOrWhiteSpace(other_name) ?
|
|
||||||
Context.User.Username :
|
|
||||||
other_name;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var war = warsInfo.Item1[warsInfo.Item2];
|
|
||||||
_service.Call(war, usr, baseNumber - 1);
|
|
||||||
_service.SaveWar(war);
|
|
||||||
await ConfirmLocalized("claimed_base", Format.Bold(usr.ToString()), baseNumber, _service.ShortPrint(war)).ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
await Context.Channel.SendErrorAsync(ex.Message).ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[NadekoCommand, Usage, Description, Aliases]
|
|
||||||
[RequireContext(ContextType.Guild)]
|
|
||||||
public async Task CallFinish1(int number, int baseNumber = 0)
|
|
||||||
{
|
|
||||||
await FinishClaim(number, baseNumber - 1, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
[NadekoCommand, Usage, Description, Aliases]
|
|
||||||
[RequireContext(ContextType.Guild)]
|
|
||||||
public async Task CallFinish2(int number, int baseNumber = 0)
|
|
||||||
{
|
|
||||||
await FinishClaim(number, baseNumber - 1, 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
[NadekoCommand, Usage, Description, Aliases]
|
|
||||||
[RequireContext(ContextType.Guild)]
|
|
||||||
public async Task CallFinish(int number, int baseNumber = 0)
|
|
||||||
{
|
|
||||||
await FinishClaim(number, baseNumber - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
[NadekoCommand, Usage, Description, Aliases]
|
|
||||||
[RequireContext(ContextType.Guild)]
|
|
||||||
public async Task EndWar(int number)
|
|
||||||
{
|
|
||||||
var warsInfo = _service.GetWarInfo(Context.Guild, number);
|
|
||||||
if (warsInfo == null)
|
|
||||||
{
|
|
||||||
await ReplyErrorLocalized("war_not_exist").ConfigureAwait(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var war = warsInfo.Item1[warsInfo.Item2];
|
|
||||||
war.End();
|
|
||||||
_service.SaveWar(war);
|
|
||||||
await ReplyConfirmLocalized("war_ended", _service.ShortPrint(warsInfo.Item1[warsInfo.Item2])).ConfigureAwait(false);
|
|
||||||
|
|
||||||
warsInfo.Item1.RemoveAt(warsInfo.Item2);
|
|
||||||
}
|
|
||||||
|
|
||||||
[NadekoCommand, Usage, Description, Aliases]
|
|
||||||
[RequireContext(ContextType.Guild)]
|
|
||||||
public async Task Unclaim(int number, [Remainder] string otherName = null)
|
|
||||||
{
|
|
||||||
var warsInfo = _service.GetWarInfo(Context.Guild, number);
|
|
||||||
if (warsInfo == null || warsInfo.Item1.Count == 0)
|
|
||||||
{
|
|
||||||
await ReplyErrorLocalized("war_not_exist").ConfigureAwait(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var usr =
|
|
||||||
string.IsNullOrWhiteSpace(otherName) ?
|
|
||||||
Context.User.Username :
|
|
||||||
otherName;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var war = warsInfo.Item1[warsInfo.Item2];
|
|
||||||
var baseNumber = _service.Uncall(war, usr);
|
|
||||||
_service.SaveWar(war);
|
|
||||||
await ReplyConfirmLocalized("base_unclaimed", usr, baseNumber + 1, _service.ShortPrint(war)).ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
await Context.Channel.SendErrorAsync(ex.Message).ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task FinishClaim(int number, int baseNumber, int stars = 3)
|
|
||||||
{
|
|
||||||
var warInfo = _service.GetWarInfo(Context.Guild, number);
|
|
||||||
if (warInfo == null || warInfo.Item1.Count == 0)
|
|
||||||
{
|
|
||||||
await ReplyErrorLocalized("war_not_exist").ConfigureAwait(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var war = warInfo.Item1[warInfo.Item2];
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (baseNumber == -1)
|
|
||||||
{
|
|
||||||
baseNumber = _service.FinishClaim(war, Context.User.Username, stars);
|
|
||||||
_service.SaveWar(war);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_service.FinishClaim(war, baseNumber, stars);
|
|
||||||
}
|
|
||||||
await ReplyConfirmLocalized("base_destroyed", baseNumber + 1, _service.ShortPrint(war)).ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
await Context.Channel.SendErrorAsync($"🔰 {ex.Message}").ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -84,7 +84,7 @@ namespace NadekoBot.Modules.CustomReactions
|
|||||||
}
|
}
|
||||||
|
|
||||||
[NadekoCommand, Usage, Description, Aliases]
|
[NadekoCommand, Usage, Description, Aliases]
|
||||||
[Priority(0)]
|
[Priority(1)]
|
||||||
public async Task ListCustReact(int page = 1)
|
public async Task ListCustReact(int page = 1)
|
||||||
{
|
{
|
||||||
if (--page < 0 || page > 999)
|
if (--page < 0 || page > 999)
|
||||||
@ -130,7 +130,7 @@ namespace NadekoBot.Modules.CustomReactions
|
|||||||
}
|
}
|
||||||
|
|
||||||
[NadekoCommand, Usage, Description, Aliases]
|
[NadekoCommand, Usage, Description, Aliases]
|
||||||
[Priority(1)]
|
[Priority(0)]
|
||||||
public async Task ListCustReact(All x)
|
public async Task ListCustReact(All x)
|
||||||
{
|
{
|
||||||
CustomReaction[] customReactions;
|
CustomReaction[] customReactions;
|
||||||
|
@ -58,7 +58,7 @@ namespace NadekoBot.Modules.Gambling
|
|||||||
}
|
}
|
||||||
|
|
||||||
[NadekoCommand, Usage, Description, Aliases]
|
[NadekoCommand, Usage, Description, Aliases]
|
||||||
[Priority(0)]
|
[Priority(1)]
|
||||||
public async Task Roll(int num)
|
public async Task Roll(int num)
|
||||||
{
|
{
|
||||||
await InternalRoll(num, true).ConfigureAwait(false);
|
await InternalRoll(num, true).ConfigureAwait(false);
|
||||||
@ -66,21 +66,21 @@ namespace NadekoBot.Modules.Gambling
|
|||||||
|
|
||||||
|
|
||||||
[NadekoCommand, Usage, Description, Aliases]
|
[NadekoCommand, Usage, Description, Aliases]
|
||||||
[Priority(0)]
|
[Priority(1)]
|
||||||
public async Task Rolluo(int num = 1)
|
public async Task Rolluo(int num = 1)
|
||||||
{
|
{
|
||||||
await InternalRoll(num, false).ConfigureAwait(false);
|
await InternalRoll(num, false).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
[NadekoCommand, Usage, Description, Aliases]
|
[NadekoCommand, Usage, Description, Aliases]
|
||||||
[Priority(1)]
|
[Priority(0)]
|
||||||
public async Task Roll(string arg)
|
public async Task Roll(string arg)
|
||||||
{
|
{
|
||||||
await InternallDndRoll(arg, true).ConfigureAwait(false);
|
await InternallDndRoll(arg, true).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
[NadekoCommand, Usage, Description, Aliases]
|
[NadekoCommand, Usage, Description, Aliases]
|
||||||
[Priority(1)]
|
[Priority(0)]
|
||||||
public async Task Rolluo(string arg)
|
public async Task Rolluo(string arg)
|
||||||
{
|
{
|
||||||
await InternallDndRoll(arg, false).ConfigureAwait(false);
|
await InternallDndRoll(arg, false).ConfigureAwait(false);
|
||||||
|
@ -197,12 +197,12 @@ namespace NadekoBot.Modules.Gambling
|
|||||||
private static readonly TimeSpan _divorceLimit = TimeSpan.FromHours(6);
|
private static readonly TimeSpan _divorceLimit = TimeSpan.FromHours(6);
|
||||||
[NadekoCommand, Usage, Description, Aliases]
|
[NadekoCommand, Usage, Description, Aliases]
|
||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
[Priority(1)]
|
[Priority(0)]
|
||||||
public Task Divorce([Remainder]IGuildUser target) => Divorce(target.Id);
|
public Task Divorce([Remainder]IGuildUser target) => Divorce(target.Id);
|
||||||
|
|
||||||
[NadekoCommand, Usage, Description, Aliases]
|
[NadekoCommand, Usage, Description, Aliases]
|
||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
[Priority(0)]
|
[Priority(1)]
|
||||||
public async Task Divorce([Remainder]ulong targetId)
|
public async Task Divorce([Remainder]ulong targetId)
|
||||||
{
|
{
|
||||||
if (targetId == Context.User.Id)
|
if (targetId == Context.User.Id)
|
||||||
|
@ -52,7 +52,7 @@ namespace NadekoBot.Modules.Gambling
|
|||||||
}
|
}
|
||||||
|
|
||||||
[NadekoCommand, Usage, Description, Aliases]
|
[NadekoCommand, Usage, Description, Aliases]
|
||||||
[Priority(0)]
|
[Priority(1)]
|
||||||
public async Task Cash([Remainder] IUser user = null)
|
public async Task Cash([Remainder] IUser user = null)
|
||||||
{
|
{
|
||||||
if(user == null)
|
if(user == null)
|
||||||
@ -62,7 +62,7 @@ namespace NadekoBot.Modules.Gambling
|
|||||||
}
|
}
|
||||||
|
|
||||||
[NadekoCommand, Usage, Description, Aliases]
|
[NadekoCommand, Usage, Description, Aliases]
|
||||||
[Priority(1)]
|
[Priority(0)]
|
||||||
public async Task Cash(ulong userId)
|
public async Task Cash(ulong userId)
|
||||||
{
|
{
|
||||||
await ReplyConfirmLocalized("has", Format.Code(userId.ToString()), $"{GetCurrency(userId)} {CurrencySign}").ConfigureAwait(false);
|
await ReplyConfirmLocalized("has", Format.Code(userId.ToString()), $"{GetCurrency(userId)} {CurrencySign}").ConfigureAwait(false);
|
||||||
@ -88,7 +88,7 @@ namespace NadekoBot.Modules.Gambling
|
|||||||
[NadekoCommand, Usage, Description, Aliases]
|
[NadekoCommand, Usage, Description, Aliases]
|
||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
[OwnerOnly]
|
[OwnerOnly]
|
||||||
[Priority(2)]
|
[Priority(0)]
|
||||||
public Task Award(int amount, [Remainder] IGuildUser usr) =>
|
public Task Award(int amount, [Remainder] IGuildUser usr) =>
|
||||||
Award(amount, usr.Id);
|
Award(amount, usr.Id);
|
||||||
|
|
||||||
@ -107,7 +107,7 @@ namespace NadekoBot.Modules.Gambling
|
|||||||
[NadekoCommand, Usage, Description, Aliases]
|
[NadekoCommand, Usage, Description, Aliases]
|
||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
[OwnerOnly]
|
[OwnerOnly]
|
||||||
[Priority(0)]
|
[Priority(2)]
|
||||||
public async Task Award(int amount, [Remainder] IRole role)
|
public async Task Award(int amount, [Remainder] IRole role)
|
||||||
{
|
{
|
||||||
var users = (await Context.Guild.GetUsersAsync())
|
var users = (await Context.Guild.GetUsersAsync())
|
||||||
|
@ -82,14 +82,14 @@ namespace NadekoBot.Modules.Help
|
|||||||
await ConfirmLocalized("commands_instr", Prefix).ConfigureAwait(false);
|
await ConfirmLocalized("commands_instr", Prefix).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
[NadekoCommand, Usage, Description, Aliases]
|
[NadekoCommand, Usage, Description, Aliases]
|
||||||
[Priority(1)]
|
[Priority(0)]
|
||||||
public async Task H([Remainder] string fail)
|
public async Task H([Remainder] string fail)
|
||||||
{
|
{
|
||||||
await ReplyErrorLocalized("command_not_found").ConfigureAwait(false);
|
await ReplyErrorLocalized("command_not_found").ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
[NadekoCommand, Usage, Description, Aliases]
|
[NadekoCommand, Usage, Description, Aliases]
|
||||||
[Priority(0)]
|
[Priority(1)]
|
||||||
public async Task H([Remainder] CommandInfo com = null)
|
public async Task H([Remainder] CommandInfo com = null)
|
||||||
{
|
{
|
||||||
var channel = Context.Channel;
|
var channel = Context.Channel;
|
||||||
|
@ -377,7 +377,7 @@ namespace NadekoBot.Modules.Music
|
|||||||
|
|
||||||
[NadekoCommand, Usage, Description, Aliases]
|
[NadekoCommand, Usage, Description, Aliases]
|
||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
[Priority(0)]
|
[Priority(1)]
|
||||||
public async Task SongRemove(int index)
|
public async Task SongRemove(int index)
|
||||||
{
|
{
|
||||||
if (index < 1)
|
if (index < 1)
|
||||||
@ -406,7 +406,7 @@ namespace NadekoBot.Modules.Music
|
|||||||
public enum All { All }
|
public enum All { All }
|
||||||
[NadekoCommand, Usage, Description, Aliases]
|
[NadekoCommand, Usage, Description, Aliases]
|
||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
[Priority(1)]
|
[Priority(0)]
|
||||||
public async Task SongRemove(All all)
|
public async Task SongRemove(All all)
|
||||||
{
|
{
|
||||||
var mp = _music.GetPlayerOrDefault(Context.Guild.Id);
|
var mp = _music.GetPlayerOrDefault(Context.Guild.Id);
|
||||||
@ -853,41 +853,6 @@ namespace NadekoBot.Modules.Music
|
|||||||
else
|
else
|
||||||
await ReplyConfirmLocalized("rpl_disabled").ConfigureAwait(false);
|
await ReplyConfirmLocalized("rpl_disabled").ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
//todo readd goto
|
|
||||||
//[NadekoCommand, Usage, Description, Aliases]
|
|
||||||
//[RequireContext(ContextType.Guild)]
|
|
||||||
//public async Task Goto(int time)
|
|
||||||
//{
|
|
||||||
// MusicPlayer musicPlayer;
|
|
||||||
// if ((musicPlayer = _music.GetPlayer(Context.Guild.Id)) == null)
|
|
||||||
// return;
|
|
||||||
// if (((IGuildUser)Context.User).VoiceChannel != musicPlayer.PlaybackVoiceChannel)
|
|
||||||
// return;
|
|
||||||
|
|
||||||
// if (time < 0)
|
|
||||||
// return;
|
|
||||||
|
|
||||||
// var currentSong = musicPlayer.CurrentSong;
|
|
||||||
|
|
||||||
// if (currentSong == null)
|
|
||||||
// return;
|
|
||||||
|
|
||||||
// //currentSong.PrintStatusMessage = false;
|
|
||||||
// var gotoSong = currentSong.Clone();
|
|
||||||
// gotoSong.SkipTo = time;
|
|
||||||
// musicPlayer.AddSong(gotoSong, 0);
|
|
||||||
// musicPlayer.Next();
|
|
||||||
|
|
||||||
// var minutes = (time / 60).ToString();
|
|
||||||
// var seconds = (time % 60).ToString();
|
|
||||||
|
|
||||||
// if (minutes.Length == 1)
|
|
||||||
// minutes = "0" + minutes;
|
|
||||||
// if (seconds.Length == 1)
|
|
||||||
// seconds = "0" + seconds;
|
|
||||||
|
|
||||||
// await ReplyConfirmLocalized("skipped_to", minutes, seconds).ConfigureAwait(false);
|
|
||||||
//}
|
|
||||||
|
|
||||||
[NadekoCommand, Usage, Description, Aliases]
|
[NadekoCommand, Usage, Description, Aliases]
|
||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
|
@ -192,10 +192,18 @@ namespace NadekoBot.Modules.NSFW
|
|||||||
if (imgObj == null)
|
if (imgObj == null)
|
||||||
await ReplyErrorLocalized("not_found").ConfigureAwait(false);
|
await ReplyErrorLocalized("not_found").ConfigureAwait(false);
|
||||||
else
|
else
|
||||||
await Context.Channel.EmbedAsync(new EmbedBuilder().WithOkColor()
|
{
|
||||||
|
var embed = new EmbedBuilder().WithOkColor()
|
||||||
.WithDescription($"{Context.User} [{tag ?? "url"}]({imgObj}) ")
|
.WithDescription($"{Context.User} [{tag ?? "url"}]({imgObj}) ")
|
||||||
.WithImageUrl(imgObj.FileUrl)
|
.WithFooter(efb => efb.WithText(type.ToString()));
|
||||||
.WithFooter(efb => efb.WithText(type.ToString()))).ConfigureAwait(false);
|
|
||||||
|
if (Uri.IsWellFormedUriString(imgObj.FileUrl, UriKind.Absolute))
|
||||||
|
embed.WithImageUrl(imgObj.FileUrl);
|
||||||
|
else
|
||||||
|
_log.Error($"Image link from {type} is not a proper Url: {imgObj.FileUrl}");
|
||||||
|
|
||||||
|
await Context.Channel.EmbedAsync(embed).ConfigureAwait(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -25,7 +25,7 @@ namespace NadekoBot.Modules.Searches
|
|||||||
}
|
}
|
||||||
|
|
||||||
[NadekoCommand, Usage, Description, Aliases]
|
[NadekoCommand, Usage, Description, Aliases]
|
||||||
[Priority(1)]
|
[Priority(0)]
|
||||||
public async Task Mal([Remainder] string name)
|
public async Task Mal([Remainder] string name)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(name))
|
if (string.IsNullOrWhiteSpace(name))
|
||||||
@ -132,7 +132,7 @@ namespace NadekoBot.Modules.Searches
|
|||||||
|
|
||||||
[NadekoCommand, Usage, Description, Aliases]
|
[NadekoCommand, Usage, Description, Aliases]
|
||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
[Priority(0)]
|
[Priority(1)]
|
||||||
public Task Mal(IGuildUser usr) => Mal(usr.Username);
|
public Task Mal(IGuildUser usr) => Mal(usr.Username);
|
||||||
|
|
||||||
[NadekoCommand, Usage, Description, Aliases]
|
[NadekoCommand, Usage, Description, Aliases]
|
||||||
|
@ -17,7 +17,7 @@ namespace NadekoBot.Modules.Searches
|
|||||||
private const string _xkcdUrl = "https://xkcd.com";
|
private const string _xkcdUrl = "https://xkcd.com";
|
||||||
|
|
||||||
[NadekoCommand, Usage, Description, Aliases]
|
[NadekoCommand, Usage, Description, Aliases]
|
||||||
[Priority(1)]
|
[Priority(0)]
|
||||||
public async Task Xkcd(string arg = null)
|
public async Task Xkcd(string arg = null)
|
||||||
{
|
{
|
||||||
if (arg?.ToLowerInvariant().Trim() == "latest")
|
if (arg?.ToLowerInvariant().Trim() == "latest")
|
||||||
@ -44,7 +44,7 @@ namespace NadekoBot.Modules.Searches
|
|||||||
}
|
}
|
||||||
|
|
||||||
[NadekoCommand, Usage, Description, Aliases]
|
[NadekoCommand, Usage, Description, Aliases]
|
||||||
[Priority(0)]
|
[Priority(1)]
|
||||||
public async Task Xkcd(int num)
|
public async Task Xkcd(int num)
|
||||||
{
|
{
|
||||||
if (num < 1)
|
if (num < 1)
|
||||||
|
@ -36,7 +36,7 @@ namespace NadekoBot.Modules.Utility
|
|||||||
|
|
||||||
[NadekoCommand, Usage, Description, Aliases]
|
[NadekoCommand, Usage, Description, Aliases]
|
||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
[Priority(0)]
|
[Priority(1)]
|
||||||
public async Task Remind(MeOrHere meorhere, string timeStr, [Remainder] string message)
|
public async Task Remind(MeOrHere meorhere, string timeStr, [Remainder] string message)
|
||||||
{
|
{
|
||||||
ulong target;
|
ulong target;
|
||||||
@ -47,7 +47,7 @@ namespace NadekoBot.Modules.Utility
|
|||||||
[NadekoCommand, Usage, Description, Aliases]
|
[NadekoCommand, Usage, Description, Aliases]
|
||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
[RequireUserPermission(GuildPermission.ManageMessages)]
|
[RequireUserPermission(GuildPermission.ManageMessages)]
|
||||||
[Priority(1)]
|
[Priority(0)]
|
||||||
public async Task Remind(ITextChannel channel, string timeStr, [Remainder] string message)
|
public async Task Remind(ITextChannel channel, string timeStr, [Remainder] string message)
|
||||||
{
|
{
|
||||||
var perms = ((IGuildUser)Context.User).GetPermissions((ITextChannel)channel);
|
var perms = ((IGuildUser)Context.User).GetPermissions((ITextChannel)channel);
|
||||||
|
@ -63,7 +63,6 @@ namespace NadekoBot.Modules.Utility
|
|||||||
[NadekoCommand, Usage, Description, Aliases]
|
[NadekoCommand, Usage, Description, Aliases]
|
||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
[RequireUserPermission(GuildPermission.ManageMessages)]
|
[RequireUserPermission(GuildPermission.ManageMessages)]
|
||||||
[Priority(0)]
|
|
||||||
public async Task RepeatRemove(int index)
|
public async Task RepeatRemove(int index)
|
||||||
{
|
{
|
||||||
if (!_service.RepeaterReady)
|
if (!_service.RepeaterReady)
|
||||||
@ -103,7 +102,7 @@ namespace NadekoBot.Modules.Utility
|
|||||||
[NadekoCommand, Usage, Description, Aliases]
|
[NadekoCommand, Usage, Description, Aliases]
|
||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
[RequireUserPermission(GuildPermission.ManageMessages)]
|
[RequireUserPermission(GuildPermission.ManageMessages)]
|
||||||
[Priority(1)]
|
[Priority(0)]
|
||||||
public async Task Repeat(int minutes, [Remainder] string message)
|
public async Task Repeat(int minutes, [Remainder] string message)
|
||||||
{
|
{
|
||||||
if (!_service.RepeaterReady)
|
if (!_service.RepeaterReady)
|
||||||
@ -152,7 +151,7 @@ namespace NadekoBot.Modules.Utility
|
|||||||
[NadekoCommand, Usage, Description, Aliases]
|
[NadekoCommand, Usage, Description, Aliases]
|
||||||
[RequireContext(ContextType.Guild)]
|
[RequireContext(ContextType.Guild)]
|
||||||
[RequireUserPermission(GuildPermission.ManageMessages)]
|
[RequireUserPermission(GuildPermission.ManageMessages)]
|
||||||
[Priority(0)]
|
[Priority(1)]
|
||||||
public async Task Repeat(GuildDateTime gt, [Remainder] string message)
|
public async Task Repeat(GuildDateTime gt, [Remainder] string message)
|
||||||
{
|
{
|
||||||
if (!_service.RepeaterReady)
|
if (!_service.RepeaterReady)
|
||||||
|
@ -14,20 +14,12 @@ using System.Collections.Immutable;
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using NadekoBot.Services.Database.Models;
|
using NadekoBot.Services.Database.Models;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using NadekoBot.Services.Searches;
|
|
||||||
using NadekoBot.Services.ClashOfClans;
|
|
||||||
using NadekoBot.Services.Music;
|
|
||||||
using NadekoBot.Services.CustomReactions;
|
|
||||||
using NadekoBot.Services.Games;
|
|
||||||
using NadekoBot.Services.Administration;
|
|
||||||
using NadekoBot.Services.Permissions;
|
|
||||||
using NadekoBot.Services.Utility;
|
|
||||||
using NadekoBot.Services.Help;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using NadekoBot.Services.Pokemon;
|
|
||||||
using NadekoBot.DataStructures.ShardCom;
|
using NadekoBot.DataStructures.ShardCom;
|
||||||
using NadekoBot.DataStructures;
|
using NadekoBot.DataStructures;
|
||||||
using NadekoBot.Extensions;
|
using NadekoBot.Extensions;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using NadekoBot.Services.Database;
|
||||||
|
|
||||||
namespace NadekoBot
|
namespace NadekoBot
|
||||||
{
|
{
|
||||||
@ -35,6 +27,15 @@ namespace NadekoBot
|
|||||||
{
|
{
|
||||||
private Logger _log;
|
private Logger _log;
|
||||||
|
|
||||||
|
public BotCredentials Credentials { get; }
|
||||||
|
|
||||||
|
public DiscordSocketClient Client { get; }
|
||||||
|
public CommandService CommandService { get; }
|
||||||
|
|
||||||
|
public DbService Db { get; }
|
||||||
|
public BotConfig BotConfig { get; }
|
||||||
|
public ImmutableArray<GuildConfig> AllGuildConfigs { get; private set; }
|
||||||
|
|
||||||
/* I don't know how to make this not be static
|
/* I don't know how to make this not be static
|
||||||
* and keep the convenience of .WithOkColor
|
* and keep the convenience of .WithOkColor
|
||||||
* and .WithErrorColor extensions methods.
|
* and .WithErrorColor extensions methods.
|
||||||
@ -44,23 +45,9 @@ namespace NadekoBot
|
|||||||
public static Color OkColor { get; private set; }
|
public static Color OkColor { get; private set; }
|
||||||
public static Color ErrorColor { get; private set; }
|
public static Color ErrorColor { get; private set; }
|
||||||
|
|
||||||
public ImmutableArray<GuildConfig> AllGuildConfigs { get; private set; }
|
public TaskCompletionSource<bool> Ready { get; private set; } = new TaskCompletionSource<bool>();
|
||||||
public BotConfig BotConfig { get; }
|
|
||||||
public DbService Db { get; }
|
|
||||||
public CommandService CommandService { get; }
|
|
||||||
public CommandHandler CommandHandler { get; private set; }
|
|
||||||
public Localization Localization { get; private set; }
|
|
||||||
public NadekoStrings Strings { get; private set; }
|
|
||||||
public StatsService Stats { get; private set; }
|
|
||||||
public ImagesService Images { get; }
|
|
||||||
public CurrencyService Currency { get; }
|
|
||||||
public GoogleApiService GoogleApi { get; }
|
|
||||||
|
|
||||||
public DiscordSocketClient Client { get; }
|
|
||||||
public bool Ready { get; private set; }
|
|
||||||
|
|
||||||
public INServiceProvider Services { get; private set; }
|
public INServiceProvider Services { get; private set; }
|
||||||
public BotCredentials Credentials { get; }
|
|
||||||
|
|
||||||
public int ShardId { get; }
|
public int ShardId { get; }
|
||||||
public ShardsCoordinator ShardCoord { get; private set; }
|
public ShardsCoordinator ShardCoord { get; private set; }
|
||||||
@ -72,26 +59,14 @@ namespace NadekoBot
|
|||||||
if (shardId < 0)
|
if (shardId < 0)
|
||||||
throw new ArgumentOutOfRangeException(nameof(shardId));
|
throw new ArgumentOutOfRangeException(nameof(shardId));
|
||||||
|
|
||||||
ShardId = shardId;
|
|
||||||
|
|
||||||
LogSetup.SetupLogger();
|
LogSetup.SetupLogger();
|
||||||
_log = LogManager.GetCurrentClassLogger();
|
_log = LogManager.GetCurrentClassLogger();
|
||||||
TerribleElevatedPermissionCheck();
|
TerribleElevatedPermissionCheck();
|
||||||
|
|
||||||
|
ShardId = shardId;
|
||||||
|
|
||||||
Credentials = new BotCredentials();
|
Credentials = new BotCredentials();
|
||||||
|
|
||||||
port = port ?? Credentials.ShardRunPort;
|
|
||||||
_comClient = new ShardComClient(port.Value);
|
|
||||||
|
|
||||||
Db = new DbService(Credentials);
|
Db = new DbService(Credentials);
|
||||||
|
|
||||||
using (var uow = Db.UnitOfWork)
|
|
||||||
{
|
|
||||||
BotConfig = uow.BotConfig.GetOrCreate();
|
|
||||||
OkColor = new Color(Convert.ToUInt32(BotConfig.OkColor, 16));
|
|
||||||
ErrorColor = new Color(Convert.ToUInt32(BotConfig.ErrorColor, 16));
|
|
||||||
}
|
|
||||||
|
|
||||||
Client = new DiscordSocketClient(new DiscordSocketConfig
|
Client = new DiscordSocketClient(new DiscordSocketConfig
|
||||||
{
|
{
|
||||||
MessageCacheSize = 10,
|
MessageCacheSize = 10,
|
||||||
@ -101,16 +76,21 @@ namespace NadekoBot
|
|||||||
ShardId = shardId,
|
ShardId = shardId,
|
||||||
AlwaysDownloadUsers = false,
|
AlwaysDownloadUsers = false,
|
||||||
});
|
});
|
||||||
|
|
||||||
CommandService = new CommandService(new CommandServiceConfig()
|
CommandService = new CommandService(new CommandServiceConfig()
|
||||||
{
|
{
|
||||||
CaseSensitiveCommands = false,
|
CaseSensitiveCommands = false,
|
||||||
DefaultRunMode = RunMode.Sync,
|
DefaultRunMode = RunMode.Sync,
|
||||||
});
|
});
|
||||||
|
|
||||||
Images = new ImagesService();
|
port = port ?? Credentials.ShardRunPort;
|
||||||
Currency = new CurrencyService(BotConfig, Db);
|
_comClient = new ShardComClient(port.Value);
|
||||||
GoogleApi = new GoogleApiService(Credentials);
|
|
||||||
|
using (var uow = Db.UnitOfWork)
|
||||||
|
{
|
||||||
|
BotConfig = uow.BotConfig.GetOrCreate();
|
||||||
|
OkColor = new Color(Convert.ToUInt32(BotConfig.OkColor, 16));
|
||||||
|
ErrorColor = new Color(Convert.ToUInt32(BotConfig.ErrorColor, 16));
|
||||||
|
}
|
||||||
|
|
||||||
SetupShard(shardId, parentProcessId, port.Value);
|
SetupShard(shardId, parentProcessId, port.Value);
|
||||||
|
|
||||||
@ -146,140 +126,34 @@ namespace NadekoBot
|
|||||||
{
|
{
|
||||||
AllGuildConfigs = uow.GuildConfigs.GetAllGuildConfigs(startingGuildIdList).ToImmutableArray();
|
AllGuildConfigs = uow.GuildConfigs.GetAllGuildConfigs(startingGuildIdList).ToImmutableArray();
|
||||||
|
|
||||||
Localization = new Localization(BotConfig.Locale, AllGuildConfigs.ToDictionary(x => x.GuildId, x => x.Locale), Db);
|
var localization = new Localization(BotConfig.Locale, AllGuildConfigs.ToDictionary(x => x.GuildId, x => x.Locale), Db);
|
||||||
Strings = new NadekoStrings(Localization);
|
|
||||||
CommandHandler = new CommandHandler(Client, Db, BotConfig, AllGuildConfigs, CommandService, Credentials, this);
|
|
||||||
Stats = new StatsService(Client, CommandHandler, Credentials, ShardCoord);
|
|
||||||
|
|
||||||
var soundcloudApiService = new SoundCloudApiService(Credentials);
|
|
||||||
|
|
||||||
#region help
|
|
||||||
var helpService = new HelpService(BotConfig, CommandHandler, Strings);
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
//module services
|
|
||||||
//todo 90 - autodiscover, DI, and add instead of manual like this
|
|
||||||
#region utility
|
|
||||||
var remindService = new RemindService(Client, BotConfig, Db, startingGuildIdList, uow);
|
|
||||||
var repeaterService = new MessageRepeaterService(this, Client, AllGuildConfigs);
|
|
||||||
var converterService = new ConverterService(Client, Db);
|
|
||||||
var commandMapService = new CommandMapService(AllGuildConfigs);
|
|
||||||
var patreonRewardsService = new PatreonRewardsService(Credentials, Db, Currency, Client);
|
|
||||||
var verboseErrorsService = new VerboseErrorsService(AllGuildConfigs, Db, CommandHandler, helpService);
|
|
||||||
var pruneService = new PruneService();
|
|
||||||
var streamRoleService = new StreamRoleService(Client, Db, AllGuildConfigs);
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region permissions
|
|
||||||
var permissionsService = new PermissionService(Client, Db, BotConfig, CommandHandler, Strings);
|
|
||||||
var blacklistService = new BlacklistService(BotConfig);
|
|
||||||
var cmdcdsService = new CmdCdService(AllGuildConfigs);
|
|
||||||
var filterService = new FilterService(Client, AllGuildConfigs);
|
|
||||||
var globalPermsService = new GlobalPermissionService(BotConfig);
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Searches
|
|
||||||
var searchesService = new SearchesService(Client, GoogleApi, Db);
|
|
||||||
var streamNotificationService = new StreamNotificationService(Db, Client, Strings);
|
|
||||||
var animeSearchService = new AnimeSearchService();
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
var clashService = new ClashOfClansService(Client, Db, Localization, Strings, uow, startingGuildIdList);
|
|
||||||
var musicService = new MusicService(Client, GoogleApi, Strings, Localization, Db, soundcloudApiService, Credentials, AllGuildConfigs);
|
|
||||||
var crService = new CustomReactionsService(permissionsService, Db, Strings, Client, CommandHandler, BotConfig, uow);
|
|
||||||
|
|
||||||
#region Games
|
|
||||||
var gamesService = new GamesService(Client, BotConfig, AllGuildConfigs, Strings, Images, CommandHandler);
|
|
||||||
var chatterBotService = new ChatterBotService(Client, permissionsService, AllGuildConfigs, CommandHandler, Strings);
|
|
||||||
var pollService = new PollService(Client, Strings);
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region administration
|
|
||||||
var administrationService = new AdministrationService(AllGuildConfigs, CommandHandler);
|
|
||||||
var greetSettingsService = new GreetSettingsService(Client, AllGuildConfigs, Db);
|
|
||||||
var selfService = new SelfService(Client, this, CommandHandler, Db, BotConfig, Localization, Strings, Credentials);
|
|
||||||
var vcRoleService = new VcRoleService(Client, AllGuildConfigs, Db);
|
|
||||||
var vPlusTService = new VplusTService(Client, AllGuildConfigs, Strings, Db);
|
|
||||||
var muteService = new MuteService(Client, AllGuildConfigs, Db);
|
|
||||||
var ratelimitService = new SlowmodeService(Client, AllGuildConfigs);
|
|
||||||
var protectionService = new ProtectionService(Client, AllGuildConfigs, muteService);
|
|
||||||
var playingRotateService = new PlayingRotateService(Client, BotConfig, musicService, Db);
|
|
||||||
var gameVcService = new GameVoiceChannelService(Client, Db, AllGuildConfigs);
|
|
||||||
var autoAssignRoleService = new AutoAssignRoleService(Client, AllGuildConfigs);
|
|
||||||
var guildTimezoneService = new GuildTimezoneService(Client, AllGuildConfigs, Db);
|
|
||||||
var logCommandService = new LogCommandService(Client, Strings, AllGuildConfigs, Db, muteService, protectionService, guildTimezoneService);
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region pokemon
|
|
||||||
var pokemonService = new PokemonService();
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
//initialize Services
|
//initialize Services
|
||||||
Services = new NServiceProvider.ServiceProviderBuilder()
|
Services = new NServiceProvider.ServiceProviderBuilder()
|
||||||
.Add<ILocalization>(Localization)
|
.AddManual<IBotCredentials>(Credentials)
|
||||||
.Add<IStatsService>(Stats)
|
.AddManual(Db)
|
||||||
.Add<IImagesService>(Images)
|
.AddManual(BotConfig)
|
||||||
.Add<IGoogleApiService>(GoogleApi)
|
.AddManual(Client)
|
||||||
.Add<IStatsService>(Stats)
|
.AddManual(CommandService)
|
||||||
.Add<IBotCredentials>(Credentials)
|
.AddManual<ILocalization>(localization)
|
||||||
.Add<CommandService>(CommandService)
|
.AddManual<IEnumerable<GuildConfig>>(AllGuildConfigs) //todo wrap this
|
||||||
.Add<NadekoStrings>(Strings)
|
.AddManual<NadekoBot>(this)
|
||||||
.Add<DiscordSocketClient>(Client)
|
.AddManual<IUnitOfWork>(uow)
|
||||||
.Add<BotConfig>(BotConfig)
|
.AddManual(ShardCoord)
|
||||||
.Add<CurrencyService>(Currency)
|
.LoadFrom(Assembly.GetEntryAssembly())
|
||||||
.Add<CommandHandler>(CommandHandler)
|
|
||||||
.Add<DbService>(Db)
|
|
||||||
//modules
|
|
||||||
.Add(commandMapService)
|
|
||||||
.Add(remindService)
|
|
||||||
.Add(repeaterService)
|
|
||||||
.Add(converterService)
|
|
||||||
.Add(verboseErrorsService)
|
|
||||||
.Add(patreonRewardsService)
|
|
||||||
.Add(pruneService)
|
|
||||||
.Add(streamRoleService)
|
|
||||||
.Add<SearchesService>(searchesService)
|
|
||||||
.Add(streamNotificationService)
|
|
||||||
.Add(animeSearchService)
|
|
||||||
.Add<ClashOfClansService>(clashService)
|
|
||||||
.Add<MusicService>(musicService)
|
|
||||||
.Add<GreetSettingsService>(greetSettingsService)
|
|
||||||
.Add<CustomReactionsService>(crService)
|
|
||||||
.Add<HelpService>(helpService)
|
|
||||||
.Add<GamesService>(gamesService)
|
|
||||||
.Add(chatterBotService)
|
|
||||||
.Add(pollService)
|
|
||||||
.Add<AdministrationService>(administrationService)
|
|
||||||
.Add(selfService)
|
|
||||||
.Add(vcRoleService)
|
|
||||||
.Add(vPlusTService)
|
|
||||||
.Add(muteService)
|
|
||||||
.Add(ratelimitService)
|
|
||||||
.Add(playingRotateService)
|
|
||||||
.Add(gameVcService)
|
|
||||||
.Add(autoAssignRoleService)
|
|
||||||
.Add(protectionService)
|
|
||||||
.Add(logCommandService)
|
|
||||||
.Add(guildTimezoneService)
|
|
||||||
.Add<PermissionService>(permissionsService)
|
|
||||||
.Add(blacklistService)
|
|
||||||
.Add(cmdcdsService)
|
|
||||||
.Add(filterService)
|
|
||||||
.Add(globalPermsService)
|
|
||||||
.Add<PokemonService>(pokemonService)
|
|
||||||
.Add<NadekoBot>(this)
|
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
CommandHandler.AddServices(Services);
|
var commandHandler = Services.GetService<CommandHandler>();
|
||||||
|
commandHandler.AddServices(Services);
|
||||||
|
|
||||||
//setup typereaders
|
//setup typereaders
|
||||||
CommandService.AddTypeReader<PermissionAction>(new PermissionActionTypeReader());
|
CommandService.AddTypeReader<PermissionAction>(new PermissionActionTypeReader());
|
||||||
CommandService.AddTypeReader<CommandInfo>(new CommandTypeReader(CommandService, CommandHandler));
|
CommandService.AddTypeReader<CommandInfo>(new CommandTypeReader());
|
||||||
CommandService.AddTypeReader<CommandOrCrInfo>(new CommandOrCrTypeReader(crService, CommandService, CommandHandler));
|
CommandService.AddTypeReader<CommandOrCrInfo>(new CommandOrCrTypeReader());
|
||||||
CommandService.AddTypeReader<ModuleInfo>(new ModuleTypeReader(CommandService));
|
CommandService.AddTypeReader<ModuleInfo>(new ModuleTypeReader(CommandService));
|
||||||
CommandService.AddTypeReader<ModuleOrCrInfo>(new ModuleOrCrTypeReader(CommandService));
|
CommandService.AddTypeReader<ModuleOrCrInfo>(new ModuleOrCrTypeReader(CommandService));
|
||||||
CommandService.AddTypeReader<IGuild>(new GuildTypeReader(Client));
|
CommandService.AddTypeReader<IGuild>(new GuildTypeReader(Client));
|
||||||
CommandService.AddTypeReader<GuildDateTime>(new GuildDateTimeTypeReader(guildTimezoneService));
|
CommandService.AddTypeReader<GuildDateTime>(new GuildDateTimeTypeReader());
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -382,7 +256,7 @@ namespace NadekoBot
|
|||||||
.Where(x => x.Preconditions.Any(y => y.GetType() == typeof(NoPublicBot)))
|
.Where(x => x.Preconditions.Any(y => y.GetType() == typeof(NoPublicBot)))
|
||||||
.ForEach(x => CommandService.RemoveModuleAsync(x));
|
.ForEach(x => CommandService.RemoveModuleAsync(x));
|
||||||
|
|
||||||
Ready = true;
|
Ready.TrySetResult(true);
|
||||||
_log.Info($"Shard {ShardId} ready.");
|
_log.Info($"Shard {ShardId} ready.");
|
||||||
//_log.Info(await stats.Print().ConfigureAwait(false));
|
//_log.Info(await stats.Print().ConfigureAwait(false));
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="AngleSharp" Version="0.9.9" />
|
<PackageReference Include="AngleSharp" Version="0.9.9" />
|
||||||
<PackageReference Include="Discord.Net" Version="1.0.1-build-00785" />
|
<PackageReference Include="Discord.Net" Version="1.0.2-build-00797" />
|
||||||
<PackageReference Include="libvideo" Version="1.0.1" />
|
<PackageReference Include="libvideo" Version="1.0.1" />
|
||||||
<PackageReference Include="CoreCLR-NCalc" Version="2.1.2" />
|
<PackageReference Include="CoreCLR-NCalc" Version="2.1.2" />
|
||||||
<PackageReference Include="Google.Apis.Urlshortener.v1" Version="1.19.0.138" />
|
<PackageReference Include="Google.Apis.Urlshortener.v1" Version="1.19.0.138" />
|
||||||
|
@ -11,7 +11,7 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace NadekoBot.Services.Administration
|
namespace NadekoBot.Services.Administration
|
||||||
{
|
{
|
||||||
public class AdministrationService
|
public class AdministrationService : INService
|
||||||
{
|
{
|
||||||
public readonly ConcurrentHashSet<ulong> DeleteMessagesOnCommand;
|
public readonly ConcurrentHashSet<ulong> DeleteMessagesOnCommand;
|
||||||
private readonly Logger _log;
|
private readonly Logger _log;
|
||||||
|
@ -9,7 +9,7 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace NadekoBot.Services.Administration
|
namespace NadekoBot.Services.Administration
|
||||||
{
|
{
|
||||||
public class AutoAssignRoleService
|
public class AutoAssignRoleService : INService
|
||||||
{
|
{
|
||||||
private readonly Logger _log;
|
private readonly Logger _log;
|
||||||
private readonly DiscordSocketClient _client;
|
private readonly DiscordSocketClient _client;
|
||||||
|
@ -10,7 +10,7 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace NadekoBot.Services.Administration
|
namespace NadekoBot.Services.Administration
|
||||||
{
|
{
|
||||||
public class GameVoiceChannelService
|
public class GameVoiceChannelService : INService
|
||||||
{
|
{
|
||||||
public readonly ConcurrentHashSet<ulong> GameVoiceChannels = new ConcurrentHashSet<ulong>();
|
public readonly ConcurrentHashSet<ulong> GameVoiceChannels = new ConcurrentHashSet<ulong>();
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ using Discord.WebSocket;
|
|||||||
|
|
||||||
namespace NadekoBot.Services.Administration
|
namespace NadekoBot.Services.Administration
|
||||||
{
|
{
|
||||||
public class GuildTimezoneService
|
public class GuildTimezoneService : INService
|
||||||
{
|
{
|
||||||
//hack >.>
|
//hack >.>
|
||||||
public static ConcurrentDictionary<ulong, GuildTimezoneService> AllServices { get; } = new ConcurrentDictionary<ulong, GuildTimezoneService>();
|
public static ConcurrentDictionary<ulong, GuildTimezoneService> AllServices { get; } = new ConcurrentDictionary<ulong, GuildTimezoneService>();
|
||||||
|
@ -13,7 +13,7 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace NadekoBot.Services.Administration
|
namespace NadekoBot.Services.Administration
|
||||||
{
|
{
|
||||||
public class LogCommandService
|
public class LogCommandService : INService
|
||||||
{
|
{
|
||||||
|
|
||||||
private readonly DiscordSocketClient _client;
|
private readonly DiscordSocketClient _client;
|
||||||
|
@ -20,7 +20,7 @@ namespace NadekoBot.Services.Administration
|
|||||||
All
|
All
|
||||||
}
|
}
|
||||||
|
|
||||||
public class MuteService
|
public class MuteService : INService
|
||||||
{
|
{
|
||||||
public ConcurrentDictionary<ulong, string> GuildMuteRoles { get; }
|
public ConcurrentDictionary<ulong, string> GuildMuteRoles { get; }
|
||||||
public ConcurrentDictionary<ulong, ConcurrentHashSet<ulong>> MutedUsers { get; }
|
public ConcurrentDictionary<ulong, ConcurrentHashSet<ulong>> MutedUsers { get; }
|
||||||
|
@ -9,7 +9,7 @@ using System.Threading;
|
|||||||
|
|
||||||
namespace NadekoBot.Services.Administration
|
namespace NadekoBot.Services.Administration
|
||||||
{
|
{
|
||||||
public class PlayingRotateService
|
public class PlayingRotateService : INService
|
||||||
{
|
{
|
||||||
private readonly Timer _t;
|
private readonly Timer _t;
|
||||||
private readonly DiscordSocketClient _client;
|
private readonly DiscordSocketClient _client;
|
||||||
|
@ -10,7 +10,7 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace NadekoBot.Services.Administration
|
namespace NadekoBot.Services.Administration
|
||||||
{
|
{
|
||||||
public class ProtectionService
|
public class ProtectionService : INService
|
||||||
{
|
{
|
||||||
public readonly ConcurrentDictionary<ulong, AntiRaidStats> AntiRaidGuilds =
|
public readonly ConcurrentDictionary<ulong, AntiRaidStats> AntiRaidGuilds =
|
||||||
new ConcurrentDictionary<ulong, AntiRaidStats>();
|
new ConcurrentDictionary<ulong, AntiRaidStats>();
|
||||||
|
@ -9,7 +9,7 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace NadekoBot.Services.Administration
|
namespace NadekoBot.Services.Administration
|
||||||
{
|
{
|
||||||
public class PruneService
|
public class PruneService : INService
|
||||||
{
|
{
|
||||||
//channelids where prunes are currently occuring
|
//channelids where prunes are currently occuring
|
||||||
private ConcurrentHashSet<ulong> _pruningGuilds = new ConcurrentHashSet<ulong>();
|
private ConcurrentHashSet<ulong> _pruningGuilds = new ConcurrentHashSet<ulong>();
|
||||||
|
@ -12,7 +12,7 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace NadekoBot.Services.Administration
|
namespace NadekoBot.Services.Administration
|
||||||
{
|
{
|
||||||
public class SlowmodeService : IEarlyBlocker
|
public class SlowmodeService : IEarlyBlocker, INService
|
||||||
{
|
{
|
||||||
public ConcurrentDictionary<ulong, Ratelimiter> RatelimitingChannels = new ConcurrentDictionary<ulong, Ratelimiter>();
|
public ConcurrentDictionary<ulong, Ratelimiter> RatelimitingChannels = new ConcurrentDictionary<ulong, Ratelimiter>();
|
||||||
public ConcurrentDictionary<ulong, HashSet<ulong>> IgnoredRoles = new ConcurrentDictionary<ulong, HashSet<ulong>>();
|
public ConcurrentDictionary<ulong, HashSet<ulong>> IgnoredRoles = new ConcurrentDictionary<ulong, HashSet<ulong>>();
|
||||||
|
@ -12,7 +12,7 @@ using System.Collections.Generic;
|
|||||||
|
|
||||||
namespace NadekoBot.Services.Administration
|
namespace NadekoBot.Services.Administration
|
||||||
{
|
{
|
||||||
public class SelfService : ILateExecutor
|
public class SelfService : ILateExecutor, INService
|
||||||
{
|
{
|
||||||
public volatile bool ForwardDMs;
|
public volatile bool ForwardDMs;
|
||||||
public volatile bool ForwardDMsToAllOwners;
|
public volatile bool ForwardDMsToAllOwners;
|
||||||
@ -44,8 +44,7 @@ namespace NadekoBot.Services.Administration
|
|||||||
|
|
||||||
var _ = Task.Run(async () =>
|
var _ = Task.Run(async () =>
|
||||||
{
|
{
|
||||||
while (!bot.Ready)
|
await bot.Ready.Task.ConfigureAwait(false);
|
||||||
await Task.Delay(1000);
|
|
||||||
|
|
||||||
foreach (var cmd in bc.StartupCommands)
|
foreach (var cmd in bc.StartupCommands)
|
||||||
{
|
{
|
||||||
@ -56,8 +55,7 @@ namespace NadekoBot.Services.Administration
|
|||||||
|
|
||||||
var ___ = Task.Run(async () =>
|
var ___ = Task.Run(async () =>
|
||||||
{
|
{
|
||||||
while (!bot.Ready)
|
await bot.Ready.Task.ConfigureAwait(false);
|
||||||
await Task.Delay(1000);
|
|
||||||
|
|
||||||
await Task.Delay(5000);
|
await Task.Delay(5000);
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace NadekoBot.Services.Administration
|
namespace NadekoBot.Services.Administration
|
||||||
{
|
{
|
||||||
public class VcRoleService
|
public class VcRoleService : INService
|
||||||
{
|
{
|
||||||
private readonly Logger _log;
|
private readonly Logger _log;
|
||||||
private readonly DbService _db;
|
private readonly DbService _db;
|
||||||
|
@ -13,7 +13,7 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace NadekoBot.Services.Administration
|
namespace NadekoBot.Services.Administration
|
||||||
{
|
{
|
||||||
public class VplusTService
|
public class VplusTService : INService
|
||||||
{
|
{
|
||||||
private readonly Regex _channelNameRegex = new Regex(@"[^a-zA-Z0-9 -]", RegexOptions.Compiled);
|
private readonly Regex _channelNameRegex = new Regex(@"[^a-zA-Z0-9 -]", RegexOptions.Compiled);
|
||||||
|
|
||||||
|
@ -1,262 +0,0 @@
|
|||||||
using Discord;
|
|
||||||
using Discord.WebSocket;
|
|
||||||
using NadekoBot.Extensions;
|
|
||||||
using NadekoBot.Services.Database;
|
|
||||||
using NadekoBot.Services.Database.Models;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Concurrent;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace NadekoBot.Services.ClashOfClans
|
|
||||||
{
|
|
||||||
// todo 99 rewrite, just made this compile, it's a complete mess. A lot of the things here should actually be in the actual module.
|
|
||||||
// service should just handle the state, module should print out what happened, so anything that has to do with strings
|
|
||||||
// shouldn't be here
|
|
||||||
public class ClashOfClansService
|
|
||||||
{
|
|
||||||
private readonly DiscordSocketClient _client;
|
|
||||||
private readonly DbService _db;
|
|
||||||
private readonly ILocalization _localization;
|
|
||||||
private readonly NadekoStrings _strings;
|
|
||||||
private readonly Timer checkWarTimer;
|
|
||||||
|
|
||||||
public ConcurrentDictionary<ulong, List<ClashWar>> ClashWars { get; set; }
|
|
||||||
|
|
||||||
public ClashOfClansService(DiscordSocketClient client, DbService db,
|
|
||||||
ILocalization localization, NadekoStrings strings, IUnitOfWork uow,
|
|
||||||
List<long> guilds)
|
|
||||||
{
|
|
||||||
_client = client;
|
|
||||||
_db = db;
|
|
||||||
_localization = localization;
|
|
||||||
_strings = strings;
|
|
||||||
|
|
||||||
ClashWars = new ConcurrentDictionary<ulong, List<ClashWar>>(
|
|
||||||
uow.ClashOfClans
|
|
||||||
.GetAllWars(guilds)
|
|
||||||
.Select(cw =>
|
|
||||||
{
|
|
||||||
cw.Channel = _client.GetGuild(cw.GuildId)?
|
|
||||||
.GetTextChannel(cw.ChannelId);
|
|
||||||
return cw;
|
|
||||||
})
|
|
||||||
.Where(cw => cw.Channel != null)
|
|
||||||
.GroupBy(cw => cw.GuildId)
|
|
||||||
.ToDictionary(g => g.Key, g => g.ToList()));
|
|
||||||
|
|
||||||
checkWarTimer = new Timer(async _ =>
|
|
||||||
{
|
|
||||||
foreach (var kvp in ClashWars)
|
|
||||||
{
|
|
||||||
foreach (var war in kvp.Value)
|
|
||||||
{
|
|
||||||
try { await CheckWar(TimeSpan.FromHours(2), war).ConfigureAwait(false); } catch { }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, null, TimeSpan.FromMinutes(1), TimeSpan.FromMinutes(1));
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task CheckWar(TimeSpan callExpire, ClashWar war)
|
|
||||||
{
|
|
||||||
var Bases = war.Bases;
|
|
||||||
for (var i = 0; i < Bases.Count; i++)
|
|
||||||
{
|
|
||||||
var callUser = Bases[i].CallUser;
|
|
||||||
if (callUser == null) continue;
|
|
||||||
if ((!Bases[i].BaseDestroyed) && DateTime.UtcNow - Bases[i].TimeAdded >= callExpire)
|
|
||||||
{
|
|
||||||
if (Bases[i].Stars != 3)
|
|
||||||
Bases[i].BaseDestroyed = true;
|
|
||||||
else
|
|
||||||
Bases[i] = null;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
SaveWar(war);
|
|
||||||
await war.Channel.SendErrorAsync(_strings.GetText("claim_expired",
|
|
||||||
_localization.GetCultureInfo(war.Channel.GuildId),
|
|
||||||
typeof(ClashOfClansService).Name.ToLowerInvariant(),
|
|
||||||
Format.Bold(Bases[i].CallUser),
|
|
||||||
ShortPrint(war)));
|
|
||||||
}
|
|
||||||
catch { }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Tuple<List<ClashWar>, int> GetWarInfo(IGuild guild, int num)
|
|
||||||
{
|
|
||||||
List<ClashWar> wars = null;
|
|
||||||
ClashWars.TryGetValue(guild.Id, out wars);
|
|
||||||
if (wars == null || wars.Count == 0)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
// get the number of the war
|
|
||||||
else if (num < 1 || num > wars.Count)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
num -= 1;
|
|
||||||
//get the actual war
|
|
||||||
return new Tuple<List<ClashWar>, int>(wars, num);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<ClashWar> CreateWar(string enemyClan, int size, ulong serverId, ulong channelId)
|
|
||||||
{
|
|
||||||
var channel = _client.GetGuild(serverId)?.GetTextChannel(channelId);
|
|
||||||
using (var uow = _db.UnitOfWork)
|
|
||||||
{
|
|
||||||
var cw = new ClashWar
|
|
||||||
{
|
|
||||||
EnemyClan = enemyClan,
|
|
||||||
Size = size,
|
|
||||||
Bases = new List<ClashCaller>(size),
|
|
||||||
GuildId = serverId,
|
|
||||||
ChannelId = channelId,
|
|
||||||
Channel = channel,
|
|
||||||
};
|
|
||||||
cw.Bases.Capacity = size;
|
|
||||||
for (int i = 0; i < size; i++)
|
|
||||||
{
|
|
||||||
cw.Bases.Add(new ClashCaller()
|
|
||||||
{
|
|
||||||
CallUser = null,
|
|
||||||
SequenceNumber = i,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
uow.ClashOfClans.Add(cw);
|
|
||||||
await uow.CompleteAsync();
|
|
||||||
return cw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SaveWar(ClashWar cw)
|
|
||||||
{
|
|
||||||
if (cw.WarState == StateOfWar.Ended)
|
|
||||||
{
|
|
||||||
using (var uow = _db.UnitOfWork)
|
|
||||||
{
|
|
||||||
uow.ClashOfClans.Remove(cw);
|
|
||||||
uow.CompleteAsync();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
using (var uow = _db.UnitOfWork)
|
|
||||||
{
|
|
||||||
uow.ClashOfClans.Update(cw);
|
|
||||||
uow.CompleteAsync();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Call(ClashWar cw, string u, int baseNumber)
|
|
||||||
{
|
|
||||||
if (baseNumber < 0 || baseNumber >= cw.Bases.Count)
|
|
||||||
throw new ArgumentException(Localize(cw, "invalid_base_number"));
|
|
||||||
if (cw.Bases[baseNumber].CallUser != null && cw.Bases[baseNumber].Stars == 3)
|
|
||||||
throw new ArgumentException(Localize(cw, "base_already_claimed"));
|
|
||||||
for (var i = 0; i < cw.Bases.Count; i++)
|
|
||||||
{
|
|
||||||
if (cw.Bases[i]?.BaseDestroyed == false && cw.Bases[i]?.CallUser == u)
|
|
||||||
throw new ArgumentException(Localize(cw, "claimed_other", u, i + 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
var cc = cw.Bases[baseNumber];
|
|
||||||
cc.CallUser = u.Trim();
|
|
||||||
cc.TimeAdded = DateTime.UtcNow;
|
|
||||||
cc.BaseDestroyed = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int FinishClaim(ClashWar cw, string user, int stars = 3)
|
|
||||||
{
|
|
||||||
user = user.Trim();
|
|
||||||
for (var i = 0; i < cw.Bases.Count; i++)
|
|
||||||
{
|
|
||||||
if (cw.Bases[i]?.BaseDestroyed != false || cw.Bases[i]?.CallUser != user) continue;
|
|
||||||
cw.Bases[i].BaseDestroyed = true;
|
|
||||||
cw.Bases[i].Stars = stars;
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
throw new InvalidOperationException(Localize(cw, "not_partic_or_destroyed", user));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void FinishClaim(ClashWar cw, int index, int stars = 3)
|
|
||||||
{
|
|
||||||
if (index < 0 || index > cw.Bases.Count)
|
|
||||||
throw new ArgumentOutOfRangeException(nameof(index));
|
|
||||||
var toFinish = cw.Bases[index];
|
|
||||||
if (toFinish.BaseDestroyed != false) throw new InvalidOperationException(Localize(cw, "base_already_destroyed"));
|
|
||||||
if (toFinish.CallUser == null) throw new InvalidOperationException(Localize(cw, "base_already_unclaimed"));
|
|
||||||
toFinish.BaseDestroyed = true;
|
|
||||||
toFinish.Stars = stars;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int Uncall(ClashWar cw, string user)
|
|
||||||
{
|
|
||||||
user = user.Trim();
|
|
||||||
for (var i = 0; i < cw.Bases.Count; i++)
|
|
||||||
{
|
|
||||||
if (cw.Bases[i]?.CallUser != user) continue;
|
|
||||||
cw.Bases[i].CallUser = null;
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
throw new InvalidOperationException(Localize(cw, "not_partic"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public string ShortPrint(ClashWar cw) =>
|
|
||||||
$"`{cw.EnemyClan}` ({cw.Size} v {cw.Size})";
|
|
||||||
|
|
||||||
public string ToPrettyString(ClashWar cw)
|
|
||||||
{
|
|
||||||
var sb = new StringBuilder();
|
|
||||||
|
|
||||||
if (cw.WarState == StateOfWar.Created)
|
|
||||||
sb.AppendLine("`not started`");
|
|
||||||
var twoHours = new TimeSpan(2, 0, 0);
|
|
||||||
for (var i = 0; i < cw.Bases.Count; i++)
|
|
||||||
{
|
|
||||||
if (cw.Bases[i].CallUser == null)
|
|
||||||
{
|
|
||||||
sb.AppendLine($"`{i + 1}.` ❌*{Localize(cw, "not_claimed")}*");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (cw.Bases[i].BaseDestroyed)
|
|
||||||
{
|
|
||||||
sb.AppendLine($"`{i + 1}.` ✅ `{cw.Bases[i].CallUser}` {new string('⭐', cw.Bases[i].Stars)}");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var left = (cw.WarState == StateOfWar.Started) ? twoHours - (DateTime.UtcNow - cw.Bases[i].TimeAdded) : twoHours;
|
|
||||||
if (cw.Bases[i].Stars == 3)
|
|
||||||
{
|
|
||||||
sb.AppendLine($"`{i + 1}.` ✅ `{cw.Bases[i].CallUser}` {left.Hours}h {left.Minutes}m {left.Seconds}s left");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sb.AppendLine($"`{i + 1}.` ✅ `{cw.Bases[i].CallUser}` {left.Hours}h {left.Minutes}m {left.Seconds}s left {new string('⭐', cw.Bases[i].Stars)} {string.Concat(Enumerable.Repeat("🔸", 3 - cw.Bases[i].Stars))}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
return sb.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Localize(ClashWar cw, string key, params object[] replacements)
|
|
||||||
{
|
|
||||||
return string.Format(Localize(cw, key), replacements);
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Localize(ClashWar cw, string key)
|
|
||||||
{
|
|
||||||
return _strings.GetText(key,
|
|
||||||
_localization.GetCultureInfo(cw.Channel?.GuildId),
|
|
||||||
"ClashOfClans".ToLowerInvariant());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,40 +0,0 @@
|
|||||||
using NadekoBot.Services.Database.Models;
|
|
||||||
using System;
|
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace NadekoBot.Services.ClashOfClans
|
|
||||||
{
|
|
||||||
public static class Extensions
|
|
||||||
{
|
|
||||||
public static void ResetTime(this ClashCaller c)
|
|
||||||
{
|
|
||||||
c.TimeAdded = DateTime.UtcNow;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Destroy(this ClashCaller c)
|
|
||||||
{
|
|
||||||
c.BaseDestroyed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void End(this ClashWar cw)
|
|
||||||
{
|
|
||||||
//Ended = true;
|
|
||||||
cw.WarState = StateOfWar.Ended;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Start(this ClashWar cw)
|
|
||||||
{
|
|
||||||
if (cw.WarState == StateOfWar.Started)
|
|
||||||
throw new InvalidOperationException("war_already_started");
|
|
||||||
//if (Started)
|
|
||||||
// throw new InvalidOperationException();
|
|
||||||
//Started = true;
|
|
||||||
cw.WarState = StateOfWar.Started;
|
|
||||||
cw.StartedAt = DateTime.UtcNow;
|
|
||||||
foreach (var b in cw.Bases.Where(b => b.CallUser != null))
|
|
||||||
{
|
|
||||||
b.ResetTime();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -24,7 +24,8 @@ namespace NadekoBot.Services
|
|||||||
|
|
||||||
public int GetHashCode(IGuildUser obj) => obj.Id.GetHashCode();
|
public int GetHashCode(IGuildUser obj) => obj.Id.GetHashCode();
|
||||||
}
|
}
|
||||||
public class CommandHandler
|
|
||||||
|
public class CommandHandler : INService
|
||||||
{
|
{
|
||||||
public const int GlobalCommandsCooldown = 750;
|
public const int GlobalCommandsCooldown = 750;
|
||||||
|
|
||||||
@ -189,7 +190,7 @@ namespace NadekoBot.Services
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (msg.Author.IsBot || !_bot.Ready) //no bots, wait until bot connected and initialized
|
if (msg.Author.IsBot || !_bot.Ready.Task.IsCompleted) //no bots, wait until bot connected and initialized
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!(msg is SocketUserMessage usrMsg))
|
if (!(msg is SocketUserMessage usrMsg))
|
||||||
@ -296,83 +297,124 @@ namespace NadekoBot.Services
|
|||||||
=> ExecuteCommand(context, input.Substring(argPos), serviceProvider, multiMatchHandling);
|
=> ExecuteCommand(context, input.Substring(argPos), serviceProvider, multiMatchHandling);
|
||||||
|
|
||||||
|
|
||||||
public async Task<(bool Success, string Error, CommandInfo Info)> ExecuteCommand(CommandContext context, string input, IServiceProvider serviceProvider, MultiMatchHandling multiMatchHandling = MultiMatchHandling.Exception)
|
public async Task<(bool Success, string Error, CommandInfo Info)> ExecuteCommand(CommandContext context, string input, IServiceProvider services, MultiMatchHandling multiMatchHandling = MultiMatchHandling.Exception)
|
||||||
{
|
{
|
||||||
var searchResult = _commandService.Search(context, input);
|
var searchResult = _commandService.Search(context, input);
|
||||||
if (!searchResult.IsSuccess)
|
if (!searchResult.IsSuccess)
|
||||||
return (false, null, null);
|
return (false, null, null);
|
||||||
|
|
||||||
var commands = searchResult.Commands;
|
var commands = searchResult.Commands;
|
||||||
for (int i = commands.Count - 1; i >= 0; i--)
|
var preconditionResults = new Dictionary<CommandMatch, PreconditionResult>();
|
||||||
|
|
||||||
|
foreach (var match in commands)
|
||||||
{
|
{
|
||||||
var preconditionResult = await commands[i].CheckPreconditionsAsync(context, serviceProvider).ConfigureAwait(false);
|
preconditionResults[match] = await match.Command.CheckPreconditionsAsync(context, services).ConfigureAwait(false);
|
||||||
if (!preconditionResult.IsSuccess)
|
|
||||||
{
|
|
||||||
return (false, preconditionResult.ErrorReason, commands[i].Command);
|
|
||||||
}
|
|
||||||
|
|
||||||
var parseResult = await commands[i].ParseAsync(context, searchResult, preconditionResult).ConfigureAwait(false);
|
|
||||||
if (!parseResult.IsSuccess)
|
|
||||||
{
|
|
||||||
if (parseResult.Error == CommandError.MultipleMatches)
|
|
||||||
{
|
|
||||||
TypeReaderValue[] argList, paramList;
|
|
||||||
switch (multiMatchHandling)
|
|
||||||
{
|
|
||||||
case MultiMatchHandling.Best:
|
|
||||||
argList = parseResult.ArgValues.Select(x => x.Values.OrderByDescending(y => y.Score).First()).ToArray();
|
|
||||||
paramList = parseResult.ParamValues.Select(x => x.Values.OrderByDescending(y => y.Score).First()).ToArray();
|
|
||||||
parseResult = ParseResult.FromSuccess(argList, paramList);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!parseResult.IsSuccess)
|
|
||||||
{
|
|
||||||
if (commands.Count == 1)
|
|
||||||
return (false, parseResult.ErrorReason, commands[i].Command);
|
|
||||||
else
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var cmd = commands[i].Command;
|
|
||||||
|
|
||||||
// Bot will ignore commands which are ran more often than what specified by
|
|
||||||
// GlobalCommandsCooldown constant (miliseconds)
|
|
||||||
if (!UsersOnShortCooldown.Add(context.Message.Author.Id))
|
|
||||||
return (false, null, commands[i].Command);
|
|
||||||
//return SearchResult.FromError(CommandError.Exception, "You are on a global cooldown.");
|
|
||||||
|
|
||||||
var commandName = cmd.Aliases.First();
|
|
||||||
foreach (var svc in _services)
|
|
||||||
{
|
|
||||||
if (svc is ILateBlocker exec &&
|
|
||||||
await exec.TryBlockLate(_client, context.Message, context.Guild, context.Channel, context.User, cmd.Module.GetTopLevelModule().Name, commandName).ConfigureAwait(false))
|
|
||||||
{
|
|
||||||
_log.Info("Late blocking User [{0}] Command: [{1}] in [{2}]", context.User, commandName, svc.GetType().Name);
|
|
||||||
return (false, null, commands[i].Command);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var execResult = (ExecuteResult)(await commands[i].ExecuteAsync(context, parseResult, serviceProvider));
|
|
||||||
if (execResult.Exception != null && (!(execResult.Exception is HttpException he) || he.DiscordCode != 50013))
|
|
||||||
{
|
|
||||||
lock (errorLogLock)
|
|
||||||
{
|
|
||||||
var now = DateTime.Now;
|
|
||||||
File.AppendAllText($"./command_errors_{now:yyyy-MM-dd}.txt",
|
|
||||||
$"[{now:HH:mm-yyyy-MM-dd}]" + Environment.NewLine
|
|
||||||
+ execResult.Exception.ToString() + Environment.NewLine
|
|
||||||
+ "------" + Environment.NewLine);
|
|
||||||
_log.Warn(execResult.Exception);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return (true, null, commands[i].Command);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (false, null, null);
|
var successfulPreconditions = preconditionResults
|
||||||
//return new ExecuteCommandResult(null, null, SearchResult.FromError(CommandError.UnknownCommand, "This input does not match any overload."));
|
.Where(x => x.Value.IsSuccess)
|
||||||
|
.ToArray();
|
||||||
|
|
||||||
|
if (successfulPreconditions.Length == 0)
|
||||||
|
{
|
||||||
|
//All preconditions failed, return the one from the highest priority command
|
||||||
|
var bestCandidate = preconditionResults
|
||||||
|
.OrderByDescending(x => x.Key.Command.Priority)
|
||||||
|
.FirstOrDefault(x => !x.Value.IsSuccess);
|
||||||
|
return (false, bestCandidate.Value.ErrorReason, commands[0].Command);
|
||||||
|
}
|
||||||
|
|
||||||
|
var parseResultsDict = new Dictionary<CommandMatch, ParseResult>();
|
||||||
|
foreach (var pair in successfulPreconditions)
|
||||||
|
{
|
||||||
|
var parseResult = await pair.Key.ParseAsync(context, searchResult, pair.Value, services).ConfigureAwait(false);
|
||||||
|
|
||||||
|
if (parseResult.Error == CommandError.MultipleMatches)
|
||||||
|
{
|
||||||
|
IReadOnlyList<TypeReaderValue> argList, paramList;
|
||||||
|
switch (multiMatchHandling)
|
||||||
|
{
|
||||||
|
case MultiMatchHandling.Best:
|
||||||
|
argList = parseResult.ArgValues.Select(x => x.Values.OrderByDescending(y => y.Score).First()).ToImmutableArray();
|
||||||
|
paramList = parseResult.ParamValues.Select(x => x.Values.OrderByDescending(y => y.Score).First()).ToImmutableArray();
|
||||||
|
parseResult = ParseResult.FromSuccess(argList, paramList);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
parseResultsDict[pair.Key] = parseResult;
|
||||||
|
}
|
||||||
|
// Calculates the 'score' of a command given a parse result
|
||||||
|
float CalculateScore(CommandMatch match, ParseResult parseResult)
|
||||||
|
{
|
||||||
|
float argValuesScore = 0, paramValuesScore = 0;
|
||||||
|
|
||||||
|
if (match.Command.Parameters.Count > 0)
|
||||||
|
{
|
||||||
|
var argValuesSum = parseResult.ArgValues?.Sum(x => x.Values.OrderByDescending(y => y.Score).FirstOrDefault().Score) ?? 0;
|
||||||
|
var paramValuesSum = parseResult.ParamValues?.Sum(x => x.Values.OrderByDescending(y => y.Score).FirstOrDefault().Score) ?? 0;
|
||||||
|
|
||||||
|
argValuesScore = argValuesSum / match.Command.Parameters.Count;
|
||||||
|
paramValuesScore = paramValuesSum / match.Command.Parameters.Count;
|
||||||
|
}
|
||||||
|
|
||||||
|
var totalArgsScore = (argValuesScore + paramValuesScore) / 2;
|
||||||
|
return match.Command.Priority + totalArgsScore * 0.99f;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Order the parse results by their score so that we choose the most likely result to execute
|
||||||
|
var parseResults = parseResultsDict
|
||||||
|
.OrderByDescending(x => CalculateScore(x.Key, x.Value));
|
||||||
|
|
||||||
|
var successfulParses = parseResults
|
||||||
|
.Where(x => x.Value.IsSuccess)
|
||||||
|
.ToArray();
|
||||||
|
|
||||||
|
if (successfulParses.Length == 0)
|
||||||
|
{
|
||||||
|
//All parses failed, return the one from the highest priority command, using score as a tie breaker
|
||||||
|
var bestMatch = parseResults
|
||||||
|
.FirstOrDefault(x => !x.Value.IsSuccess);
|
||||||
|
return (false, bestMatch.Value.ErrorReason, commands[0].Command);
|
||||||
|
}
|
||||||
|
|
||||||
|
var cmd = successfulParses[0].Key.Command;
|
||||||
|
|
||||||
|
// Bot will ignore commands which are ran more often than what specified by
|
||||||
|
// GlobalCommandsCooldown constant (miliseconds)
|
||||||
|
if (!UsersOnShortCooldown.Add(context.Message.Author.Id))
|
||||||
|
return (false, null, cmd);
|
||||||
|
//return SearchResult.FromError(CommandError.Exception, "You are on a global cooldown.");
|
||||||
|
|
||||||
|
var commandName = cmd.Aliases.First();
|
||||||
|
foreach (var svc in _services)
|
||||||
|
{
|
||||||
|
if (svc is ILateBlocker exec &&
|
||||||
|
await exec.TryBlockLate(_client, context.Message, context.Guild, context.Channel, context.User, cmd.Module.GetTopLevelModule().Name, commandName).ConfigureAwait(false))
|
||||||
|
{
|
||||||
|
_log.Info("Late blocking User [{0}] Command: [{1}] in [{2}]", context.User, commandName, svc.GetType().Name);
|
||||||
|
return (false, null, cmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//If we get this far, at least one parse was successful. Execute the most likely overload.
|
||||||
|
var chosenOverload = successfulParses[0];
|
||||||
|
var execResult = (ExecuteResult)await chosenOverload.Key.ExecuteAsync(context, chosenOverload.Value, services).ConfigureAwait(false);
|
||||||
|
|
||||||
|
if (execResult.Exception != null && (!(execResult.Exception is HttpException he) || he.DiscordCode != 50013))
|
||||||
|
{
|
||||||
|
lock (errorLogLock)
|
||||||
|
{
|
||||||
|
var now = DateTime.Now;
|
||||||
|
File.AppendAllText($"./command_errors_{now:yyyy-MM-dd}.txt",
|
||||||
|
$"[{now:HH:mm-yyyy-MM-dd}]" + Environment.NewLine
|
||||||
|
+ execResult.Exception.ToString() + Environment.NewLine
|
||||||
|
+ "------" + Environment.NewLine);
|
||||||
|
_log.Warn(execResult.Exception);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (true, null, cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly object errorLogLock = new object();
|
private readonly object errorLogLock = new object();
|
||||||
|
@ -7,7 +7,7 @@ using NadekoBot.Services.Database;
|
|||||||
|
|
||||||
namespace NadekoBot.Services
|
namespace NadekoBot.Services
|
||||||
{
|
{
|
||||||
public class CurrencyService
|
public class CurrencyService : INService
|
||||||
{
|
{
|
||||||
private readonly BotConfig _config;
|
private readonly BotConfig _config;
|
||||||
private readonly DbService _db;
|
private readonly DbService _db;
|
||||||
|
@ -14,7 +14,7 @@ using NadekoBot.Services.Database;
|
|||||||
|
|
||||||
namespace NadekoBot.Services.CustomReactions
|
namespace NadekoBot.Services.CustomReactions
|
||||||
{
|
{
|
||||||
public class CustomReactionsService : IEarlyBlockingExecutor
|
public class CustomReactionsService : IEarlyBlockingExecutor, INService
|
||||||
{
|
{
|
||||||
public CustomReaction[] GlobalReactions = new CustomReaction[] { };
|
public CustomReaction[] GlobalReactions = new CustomReaction[] { };
|
||||||
public ConcurrentDictionary<ulong, CustomReaction[]> GuildReactions { get; } = new ConcurrentDictionary<ulong, CustomReaction[]>();
|
public ConcurrentDictionary<ulong, CustomReaction[]> GuildReactions { get; } = new ConcurrentDictionary<ulong, CustomReaction[]>();
|
||||||
|
@ -65,7 +65,7 @@ Nadeko Support Server: https://discord.gg/nadekobot";
|
|||||||
public List<StartupCommand> StartupCommands { get; set; }
|
public List<StartupCommand> StartupCommands { get; set; }
|
||||||
public HashSet<BlockedCmdOrMdl> BlockedCommands { get; set; }
|
public HashSet<BlockedCmdOrMdl> BlockedCommands { get; set; }
|
||||||
public HashSet<BlockedCmdOrMdl> BlockedModules { get; set; }
|
public HashSet<BlockedCmdOrMdl> BlockedModules { get; set; }
|
||||||
public int PermissionVersion { get; set; } = 1;
|
public int PermissionVersion { get; set; }
|
||||||
public string DefaultPrefix { get; set; } = ".";
|
public string DefaultPrefix { get; set; } = ".";
|
||||||
public bool CustomReactionsStartWith { get; set; } = false;
|
public bool CustomReactionsStartWith { get; set; } = false;
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,6 @@ namespace NadekoBot.Services.Database.Repositories
|
|||||||
{
|
{
|
||||||
public interface IReminderRepository : IRepository<Reminder>
|
public interface IReminderRepository : IRepository<Reminder>
|
||||||
{
|
{
|
||||||
IEnumerable<Reminder> GetIncludedReminders(List<long> guildIds);
|
IEnumerable<Reminder> GetIncludedReminders(IEnumerable<long> guildIds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ namespace NadekoBot.Services.Database.Repositories.Impl
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<Reminder> GetIncludedReminders(List<long> guildIds)
|
public IEnumerable<Reminder> GetIncludedReminders(IEnumerable<long> guildIds)
|
||||||
{
|
{
|
||||||
return _set.Where(x => guildIds.Contains((long)x.ServerId)).ToList();
|
return _set.Where(x => guildIds.Contains((long)x.ServerId)).ToList();
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace NadekoBot.Services.Games
|
namespace NadekoBot.Services.Games
|
||||||
{
|
{
|
||||||
public class ChatterBotService : IEarlyBlockingExecutor
|
public class ChatterBotService : IEarlyBlockingExecutor, INService
|
||||||
{
|
{
|
||||||
private readonly DiscordSocketClient _client;
|
private readonly DiscordSocketClient _client;
|
||||||
private readonly Logger _log;
|
private readonly Logger _log;
|
||||||
|
@ -15,7 +15,7 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace NadekoBot.Services.Games
|
namespace NadekoBot.Services.Games
|
||||||
{
|
{
|
||||||
public class GamesService
|
public class GamesService : INService
|
||||||
{
|
{
|
||||||
private readonly BotConfig _bc;
|
private readonly BotConfig _bc;
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ using NLog;
|
|||||||
|
|
||||||
namespace NadekoBot.Services.Games
|
namespace NadekoBot.Services.Games
|
||||||
{
|
{
|
||||||
public class PollService : IEarlyBlockingExecutor
|
public class PollService : IEarlyBlockingExecutor, INService
|
||||||
{
|
{
|
||||||
public ConcurrentDictionary<ulong, Poll> ActivePolls = new ConcurrentDictionary<ulong, Poll>();
|
public ConcurrentDictionary<ulong, Poll> ActivePolls = new ConcurrentDictionary<ulong, Poll>();
|
||||||
private readonly Logger _log;
|
private readonly Logger _log;
|
||||||
|
@ -13,7 +13,7 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace NadekoBot.Services
|
namespace NadekoBot.Services
|
||||||
{
|
{
|
||||||
public class GreetSettingsService
|
public class GreetSettingsService : INService
|
||||||
{
|
{
|
||||||
private readonly DbService _db;
|
private readonly DbService _db;
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ using NadekoBot.Attributes;
|
|||||||
|
|
||||||
namespace NadekoBot.Services.Help
|
namespace NadekoBot.Services.Help
|
||||||
{
|
{
|
||||||
public class HelpService : ILateExecutor
|
public class HelpService : ILateExecutor, INService
|
||||||
{
|
{
|
||||||
private readonly BotConfig _bc;
|
private readonly BotConfig _bc;
|
||||||
private readonly CommandHandler _ch;
|
private readonly CommandHandler _ch;
|
||||||
|
@ -5,7 +5,7 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace NadekoBot.Services
|
namespace NadekoBot.Services
|
||||||
{
|
{
|
||||||
public interface IGoogleApiService
|
public interface IGoogleApiService : INService
|
||||||
{
|
{
|
||||||
IEnumerable<string> Languages { get; }
|
IEnumerable<string> Languages { get; }
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ using System.Collections.Immutable;
|
|||||||
|
|
||||||
namespace NadekoBot.Services
|
namespace NadekoBot.Services
|
||||||
{
|
{
|
||||||
public interface IImagesService
|
public interface IImagesService : INService
|
||||||
{
|
{
|
||||||
ImmutableArray<byte> Heads { get; }
|
ImmutableArray<byte> Heads { get; }
|
||||||
ImmutableArray<byte> Tails { get; }
|
ImmutableArray<byte> Tails { get; }
|
||||||
|
16
src/NadekoBot/Services/INService.cs
Normal file
16
src/NadekoBot/Services/INService.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace NadekoBot.Services
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// All services must implement this interface in order to be auto-discovered by the DI system
|
||||||
|
/// </summary>
|
||||||
|
public interface INService
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -3,7 +3,7 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace NadekoBot.Services
|
namespace NadekoBot.Services
|
||||||
{
|
{
|
||||||
public interface IStatsService
|
public interface IStatsService : INService
|
||||||
{
|
{
|
||||||
string Author { get; }
|
string Author { get; }
|
||||||
long CommandsRan { get; }
|
long CommandsRan { get; }
|
||||||
|
@ -11,7 +11,7 @@ using System.Text.RegularExpressions;
|
|||||||
|
|
||||||
namespace NadekoBot.Services
|
namespace NadekoBot.Services
|
||||||
{
|
{
|
||||||
public class NadekoStrings
|
public class NadekoStrings : INService
|
||||||
{
|
{
|
||||||
public const string stringsPath = @"_strings/";
|
public const string stringsPath = @"_strings/";
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace NadekoBot.Services.Impl
|
namespace NadekoBot.Services.Impl
|
||||||
{
|
{
|
||||||
public class SoundCloudApiService
|
public class SoundCloudApiService : INService
|
||||||
{
|
{
|
||||||
private readonly IBotCredentials _creds;
|
private readonly IBotCredentials _creds;
|
||||||
|
|
||||||
|
24
src/NadekoBot/Services/Impl/StartingGuildsListService.cs
Normal file
24
src/NadekoBot/Services/Impl/StartingGuildsListService.cs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
using Discord.WebSocket;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.Immutable;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Collections;
|
||||||
|
|
||||||
|
namespace NadekoBot.Services.Impl
|
||||||
|
{
|
||||||
|
public class StartingGuildsService : IEnumerable<long>, INService
|
||||||
|
{
|
||||||
|
private readonly ImmutableList<long> _guilds;
|
||||||
|
|
||||||
|
public StartingGuildsService(DiscordSocketClient client)
|
||||||
|
{
|
||||||
|
this._guilds = client.Guilds.Select(x => (long)x.Id).ToImmutableList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerator<long> GetEnumerator() =>
|
||||||
|
_guilds.GetEnumerator();
|
||||||
|
|
||||||
|
IEnumerator IEnumerable.GetEnumerator() =>
|
||||||
|
_guilds.GetEnumerator();
|
||||||
|
}
|
||||||
|
}
|
@ -15,7 +15,7 @@ using NadekoBot.Services.Impl;
|
|||||||
|
|
||||||
namespace NadekoBot.Services.Music
|
namespace NadekoBot.Services.Music
|
||||||
{
|
{
|
||||||
public class MusicService
|
public class MusicService : INService
|
||||||
{
|
{
|
||||||
public const string MusicDataPath = "data/musicdata";
|
public const string MusicDataPath = "data/musicdata";
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace NadekoBot.Services.Permissions
|
namespace NadekoBot.Services.Permissions
|
||||||
{
|
{
|
||||||
public class BlacklistService : IEarlyBlocker
|
public class BlacklistService : IEarlyBlocker, INService
|
||||||
{
|
{
|
||||||
public ConcurrentHashSet<ulong> BlacklistedUsers { get; }
|
public ConcurrentHashSet<ulong> BlacklistedUsers { get; }
|
||||||
public ConcurrentHashSet<ulong> BlacklistedGuilds { get; }
|
public ConcurrentHashSet<ulong> BlacklistedGuilds { get; }
|
||||||
|
@ -9,7 +9,7 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace NadekoBot.Services.Permissions
|
namespace NadekoBot.Services.Permissions
|
||||||
{
|
{
|
||||||
public class CmdCdService : ILateBlocker
|
public class CmdCdService : ILateBlocker, INService
|
||||||
{
|
{
|
||||||
public ConcurrentDictionary<ulong, ConcurrentHashSet<CommandCooldown>> CommandCooldowns { get; }
|
public ConcurrentDictionary<ulong, ConcurrentHashSet<CommandCooldown>> CommandCooldowns { get; }
|
||||||
public ConcurrentDictionary<ulong, ConcurrentHashSet<ActiveCooldown>> ActiveCooldowns { get; } = new ConcurrentDictionary<ulong, ConcurrentHashSet<ActiveCooldown>>();
|
public ConcurrentDictionary<ulong, ConcurrentHashSet<ActiveCooldown>> ActiveCooldowns { get; } = new ConcurrentDictionary<ulong, ConcurrentHashSet<ActiveCooldown>>();
|
||||||
|
@ -12,7 +12,7 @@ using NLog;
|
|||||||
|
|
||||||
namespace NadekoBot.Services.Permissions
|
namespace NadekoBot.Services.Permissions
|
||||||
{
|
{
|
||||||
public class FilterService : IEarlyBlocker
|
public class FilterService : IEarlyBlocker, INService
|
||||||
{
|
{
|
||||||
private readonly Logger _log;
|
private readonly Logger _log;
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace NadekoBot.Services.Permissions
|
namespace NadekoBot.Services.Permissions
|
||||||
{
|
{
|
||||||
public class GlobalPermissionService : ILateBlocker
|
public class GlobalPermissionService : ILateBlocker, INService
|
||||||
{
|
{
|
||||||
public readonly ConcurrentHashSet<string> BlockedModules;
|
public readonly ConcurrentHashSet<string> BlockedModules;
|
||||||
public readonly ConcurrentHashSet<string> BlockedCommands;
|
public readonly ConcurrentHashSet<string> BlockedCommands;
|
||||||
|
@ -11,14 +11,14 @@ using System.Threading.Tasks;
|
|||||||
using Discord;
|
using Discord;
|
||||||
using Discord.WebSocket;
|
using Discord.WebSocket;
|
||||||
using NadekoBot.Extensions;
|
using NadekoBot.Extensions;
|
||||||
|
using NadekoBot.Services.Database;
|
||||||
using NadekoBot.Services;
|
using NadekoBot.Services;
|
||||||
|
|
||||||
namespace NadekoBot.Services.Permissions
|
namespace NadekoBot.Services.Permissions
|
||||||
{
|
{
|
||||||
public class PermissionService : ILateBlocker
|
public class PermissionService : ILateBlocker, INService
|
||||||
{
|
{
|
||||||
private readonly DbService _db;
|
private readonly DbService _db;
|
||||||
private readonly Logger _log;
|
|
||||||
private readonly CommandHandler _cmd;
|
private readonly CommandHandler _cmd;
|
||||||
private readonly NadekoStrings _strings;
|
private readonly NadekoStrings _strings;
|
||||||
|
|
||||||
@ -26,16 +26,15 @@ namespace NadekoBot.Services.Permissions
|
|||||||
public ConcurrentDictionary<ulong, PermissionCache> Cache { get; } =
|
public ConcurrentDictionary<ulong, PermissionCache> Cache { get; } =
|
||||||
new ConcurrentDictionary<ulong, PermissionCache>();
|
new ConcurrentDictionary<ulong, PermissionCache>();
|
||||||
|
|
||||||
public PermissionService(DiscordSocketClient client, DbService db, BotConfig bc, CommandHandler cmd, NadekoStrings strings)
|
public PermissionService(DiscordSocketClient client, DbService db, CommandHandler cmd, NadekoStrings strings)
|
||||||
{
|
{
|
||||||
_log = LogManager.GetCurrentClassLogger();
|
|
||||||
_db = db;
|
_db = db;
|
||||||
_cmd = cmd;
|
_cmd = cmd;
|
||||||
_strings = strings;
|
_strings = strings;
|
||||||
|
|
||||||
var sw = Stopwatch.StartNew();
|
var sw = Stopwatch.StartNew();
|
||||||
if (client.ShardId == 0)
|
if (client.ShardId == 0)
|
||||||
TryMigratePermissions(bc);
|
TryMigratePermissions();
|
||||||
|
|
||||||
using (var uow = _db.UnitOfWork)
|
using (var uow = _db.UnitOfWork)
|
||||||
{
|
{
|
||||||
@ -49,9 +48,6 @@ namespace NadekoBot.Services.Permissions
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sw.Stop();
|
|
||||||
_log.Debug($"Loaded in {sw.Elapsed.TotalSeconds:F2}s");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public PermissionCache GetCache(ulong guildId)
|
public PermissionCache GetCache(ulong guildId)
|
||||||
@ -71,12 +67,13 @@ namespace NadekoBot.Services.Permissions
|
|||||||
return pc;
|
return pc;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void TryMigratePermissions(BotConfig bc)
|
private void TryMigratePermissions()
|
||||||
{
|
{
|
||||||
var log = LogManager.GetCurrentClassLogger();
|
using (var uow = _db.UnitOfWork)
|
||||||
if (bc.PermissionVersion <= 1)
|
|
||||||
{
|
{
|
||||||
using (var uow = _db.UnitOfWork)
|
var bc = uow.BotConfig.GetOrCreate();
|
||||||
|
var log = LogManager.GetCurrentClassLogger();
|
||||||
|
if (bc.PermissionVersion <= 1)
|
||||||
{
|
{
|
||||||
log.Info("Permission version is 1, upgrading to 2.");
|
log.Info("Permission version is 1, upgrading to 2.");
|
||||||
var oldCache = new ConcurrentDictionary<ulong, OldPermissionCache>(uow.GuildConfigs
|
var oldCache = new ConcurrentDictionary<ulong, OldPermissionCache>(uow.GuildConfigs
|
||||||
@ -134,25 +131,22 @@ namespace NadekoBot.Services.Permissions
|
|||||||
bc.PermissionVersion = 2;
|
bc.PermissionVersion = 2;
|
||||||
uow.Complete();
|
uow.Complete();
|
||||||
}
|
}
|
||||||
}
|
if (bc.PermissionVersion <= 2)
|
||||||
if (bc.PermissionVersion <= 2)
|
|
||||||
{
|
|
||||||
using (var uow = _db.UnitOfWork)
|
|
||||||
{
|
{
|
||||||
var oldPrefixes = new[] { ".", ";", "!!", "!m", "!", "+", "-", "$", ">" };
|
var oldPrefixes = new[] { ".", ";", "!!", "!m", "!", "+", "-", "$", ">" };
|
||||||
uow._context.Database.ExecuteSqlCommand(
|
uow._context.Database.ExecuteSqlCommand(
|
||||||
$@"UPDATE {nameof(Permissionv2)}
|
$@"UPDATE {nameof(Permissionv2)}
|
||||||
SET secondaryTargetName=trim(substr(secondaryTargetName, 3))
|
SET secondaryTargetName=trim(substr(secondaryTargetName, 3))
|
||||||
WHERE secondaryTargetName LIKE '!!%' OR secondaryTargetName LIKE '!m%';
|
WHERE secondaryTargetName LIKE '!!%' OR secondaryTargetName LIKE '!m%';
|
||||||
|
|
||||||
UPDATE {nameof(Permissionv2)}
|
UPDATE {nameof(Permissionv2)}
|
||||||
SET secondaryTargetName=substr(secondaryTargetName, 2)
|
SET secondaryTargetName=substr(secondaryTargetName, 2)
|
||||||
WHERE secondaryTargetName LIKE '.%' OR
|
WHERE secondaryTargetName LIKE '.%' OR
|
||||||
secondaryTargetName LIKE '~%' OR
|
secondaryTargetName LIKE '~%' OR
|
||||||
secondaryTargetName LIKE ';%' OR
|
secondaryTargetName LIKE ';%' OR
|
||||||
secondaryTargetName LIKE '>%' OR
|
secondaryTargetName LIKE '>%' OR
|
||||||
secondaryTargetName LIKE '-%' OR
|
secondaryTargetName LIKE '-%' OR
|
||||||
secondaryTargetName LIKE '!%';");
|
secondaryTargetName LIKE '!%';");
|
||||||
bc.PermissionVersion = 3;
|
bc.PermissionVersion = 3;
|
||||||
uow.Complete();
|
uow.Complete();
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ using System.IO;
|
|||||||
|
|
||||||
namespace NadekoBot.Services.Pokemon
|
namespace NadekoBot.Services.Pokemon
|
||||||
{
|
{
|
||||||
public class PokemonService
|
public class PokemonService : INService
|
||||||
{
|
{
|
||||||
public readonly List<PokemonType> PokemonTypes = new List<PokemonType>();
|
public readonly List<PokemonType> PokemonTypes = new List<PokemonType>();
|
||||||
public readonly ConcurrentDictionary<ulong, PokeStats> Stats = new ConcurrentDictionary<ulong, PokeStats>();
|
public readonly ConcurrentDictionary<ulong, PokeStats> Stats = new ConcurrentDictionary<ulong, PokeStats>();
|
||||||
|
@ -6,7 +6,7 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace NadekoBot.Services.Searches
|
namespace NadekoBot.Services.Searches
|
||||||
{
|
{
|
||||||
public class AnimeSearchService
|
public class AnimeSearchService : INService
|
||||||
{
|
{
|
||||||
private readonly Logger _log;
|
private readonly Logger _log;
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ using System.Xml;
|
|||||||
|
|
||||||
namespace NadekoBot.Services.Searches
|
namespace NadekoBot.Services.Searches
|
||||||
{
|
{
|
||||||
public class SearchesService
|
public class SearchesService : INService
|
||||||
{
|
{
|
||||||
private readonly DiscordSocketClient _client;
|
private readonly DiscordSocketClient _client;
|
||||||
private readonly IGoogleApiService _google;
|
private readonly IGoogleApiService _google;
|
||||||
|
@ -15,7 +15,7 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace NadekoBot.Services.Searches
|
namespace NadekoBot.Services.Searches
|
||||||
{
|
{
|
||||||
public class StreamNotificationService
|
public class StreamNotificationService : INService
|
||||||
{
|
{
|
||||||
private readonly Timer _streamCheckTimer;
|
private readonly Timer _streamCheckTimer;
|
||||||
private bool firstStreamNotifPass { get; set; } = true;
|
private bool firstStreamNotifPass { get; set; } = true;
|
||||||
|
@ -3,6 +3,15 @@ using System.Collections;
|
|||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
|
using System.Reflection;
|
||||||
|
using Discord.Commands;
|
||||||
|
using Discord.WebSocket;
|
||||||
|
using NadekoBot.Services.Database.Models;
|
||||||
|
using NadekoBot.Services.Impl;
|
||||||
|
using System.Linq;
|
||||||
|
using NadekoBot.Extensions;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using NLog;
|
||||||
|
|
||||||
namespace NadekoBot.Services
|
namespace NadekoBot.Services
|
||||||
{
|
{
|
||||||
@ -16,8 +25,14 @@ namespace NadekoBot.Services
|
|||||||
public class ServiceProviderBuilder
|
public class ServiceProviderBuilder
|
||||||
{
|
{
|
||||||
private ConcurrentDictionary<Type, object> _dict = new ConcurrentDictionary<Type, object>();
|
private ConcurrentDictionary<Type, object> _dict = new ConcurrentDictionary<Type, object>();
|
||||||
|
private readonly Logger _log;
|
||||||
|
|
||||||
public ServiceProviderBuilder Add<T>(T obj)
|
public ServiceProviderBuilder()
|
||||||
|
{
|
||||||
|
_log = LogManager.GetCurrentClassLogger();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ServiceProviderBuilder AddManual<T>(T obj)
|
||||||
{
|
{
|
||||||
_dict.TryAdd(typeof(T), obj);
|
_dict.TryAdd(typeof(T), obj);
|
||||||
return this;
|
return this;
|
||||||
@ -27,6 +42,61 @@ namespace NadekoBot.Services
|
|||||||
{
|
{
|
||||||
return new NServiceProvider(_dict);
|
return new NServiceProvider(_dict);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ServiceProviderBuilder LoadFrom(Assembly assembly)
|
||||||
|
{
|
||||||
|
var allTypes = assembly.GetTypes();
|
||||||
|
var services = new Queue<Type>(allTypes
|
||||||
|
.Where(x => x.GetInterfaces().Contains(typeof(INService)) && !x.GetTypeInfo().IsInterface && !x.GetTypeInfo().IsAbstract)
|
||||||
|
.ToArray());
|
||||||
|
|
||||||
|
var interfaces = new HashSet<Type>(allTypes
|
||||||
|
.Where(x => x.GetInterfaces().Contains(typeof(INService)) && x.GetTypeInfo().IsInterface));
|
||||||
|
|
||||||
|
var sw = Stopwatch.StartNew();
|
||||||
|
var swInstance = new Stopwatch();
|
||||||
|
while (services.Count > 0)
|
||||||
|
{
|
||||||
|
var type = services.Dequeue(); //get a type i need to make an instance of
|
||||||
|
|
||||||
|
if (_dict.TryGetValue(type, out _)) // if that type is already instantiated, skip
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var ctor = type.GetConstructors()[0];
|
||||||
|
var argTypes = ctor
|
||||||
|
.GetParameters()
|
||||||
|
.Select(x => x.ParameterType)
|
||||||
|
.ToArray(); // get constructor argument types i need to pass in
|
||||||
|
|
||||||
|
var args = new List<object>(argTypes.Length);
|
||||||
|
foreach (var arg in argTypes) //get constructor arguments from the dictionary of already instantiated types
|
||||||
|
{
|
||||||
|
if (_dict.TryGetValue(arg, out var argObj)) //if i got current one, add it to the list of instances and move on
|
||||||
|
args.Add(argObj);
|
||||||
|
else //if i failed getting it, add it to the end, and break
|
||||||
|
{
|
||||||
|
services.Enqueue(type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (args.Count != argTypes.Length)
|
||||||
|
continue;
|
||||||
|
swInstance.Restart();
|
||||||
|
var instance = ctor.Invoke(args.ToArray());
|
||||||
|
swInstance.Stop();
|
||||||
|
if (swInstance.Elapsed.TotalSeconds > 5)
|
||||||
|
_log.Info($"{type.Name} took {swInstance.Elapsed.TotalSeconds:F2}s to load.");
|
||||||
|
var interfaceType = interfaces.FirstOrDefault(x => instance.GetType().GetInterfaces().Contains(x));
|
||||||
|
if (interfaceType != null)
|
||||||
|
_dict.TryAdd(interfaceType, instance);
|
||||||
|
|
||||||
|
_dict.TryAdd(type, instance);
|
||||||
|
}
|
||||||
|
sw.Stop();
|
||||||
|
_log.Info($"All services loaded in {sw.Elapsed.TotalSeconds:F2}s");
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly ImmutableDictionary<Type, object> _services;
|
private readonly ImmutableDictionary<Type, object> _services;
|
||||||
|
@ -10,7 +10,7 @@ using NadekoBot.Extensions;
|
|||||||
|
|
||||||
namespace NadekoBot.Services.Utility
|
namespace NadekoBot.Services.Utility
|
||||||
{
|
{
|
||||||
public class CommandMapService : IInputTransformer
|
public class CommandMapService : IInputTransformer, INService
|
||||||
{
|
{
|
||||||
private readonly Logger _log;
|
private readonly Logger _log;
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace NadekoBot.Services.Utility
|
namespace NadekoBot.Services.Utility
|
||||||
{
|
{
|
||||||
public class ConverterService
|
public class ConverterService : INService
|
||||||
{
|
{
|
||||||
public List<ConvertUnit> Units { get; } = new List<ConvertUnit>();
|
public List<ConvertUnit> Units { get; } = new List<ConvertUnit>();
|
||||||
private readonly Logger _log;
|
private readonly Logger _log;
|
||||||
|
@ -8,7 +8,7 @@ using System.Threading.Tasks;
|
|||||||
namespace NadekoBot.Services.Utility
|
namespace NadekoBot.Services.Utility
|
||||||
{
|
{
|
||||||
//todo 50 rewrite
|
//todo 50 rewrite
|
||||||
public class MessageRepeaterService
|
public class MessageRepeaterService : INService
|
||||||
{
|
{
|
||||||
//messagerepeater
|
//messagerepeater
|
||||||
//guildid/RepeatRunners
|
//guildid/RepeatRunners
|
||||||
@ -19,8 +19,7 @@ namespace NadekoBot.Services.Utility
|
|||||||
{
|
{
|
||||||
var _ = Task.Run(async () =>
|
var _ = Task.Run(async () =>
|
||||||
{
|
{
|
||||||
while (!bot.Ready)
|
await bot.Ready.Task.ConfigureAwait(false);
|
||||||
await Task.Delay(1000);
|
|
||||||
|
|
||||||
Repeaters = new ConcurrentDictionary<ulong, ConcurrentQueue<RepeatRunner>>(gcs
|
Repeaters = new ConcurrentDictionary<ulong, ConcurrentQueue<RepeatRunner>>(gcs
|
||||||
.ToDictionary(gc => gc.GuildId,
|
.ToDictionary(gc => gc.GuildId,
|
||||||
|
@ -9,13 +9,12 @@ using System.Collections.Immutable;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Text;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace NadekoBot.Services.Utility
|
namespace NadekoBot.Services.Utility
|
||||||
{
|
{
|
||||||
public class PatreonRewardsService
|
public class PatreonRewardsService : INService
|
||||||
{
|
{
|
||||||
private readonly SemaphoreSlim getPledgesLocker = new SemaphoreSlim(1, 1);
|
private readonly SemaphoreSlim getPledgesLocker = new SemaphoreSlim(1, 1);
|
||||||
|
|
||||||
|
@ -4,9 +4,9 @@ using NadekoBot.DataStructures.Replacements;
|
|||||||
using NadekoBot.Extensions;
|
using NadekoBot.Extensions;
|
||||||
using NadekoBot.Services.Database;
|
using NadekoBot.Services.Database;
|
||||||
using NadekoBot.Services.Database.Models;
|
using NadekoBot.Services.Database.Models;
|
||||||
|
using NadekoBot.Services.Impl;
|
||||||
using NLog;
|
using NLog;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
@ -14,7 +14,7 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace NadekoBot.Services.Utility
|
namespace NadekoBot.Services.Utility
|
||||||
{
|
{
|
||||||
public class RemindService
|
public class RemindService : INService
|
||||||
{
|
{
|
||||||
public readonly Regex Regex = new Regex(@"^(?:(?<months>\d)mo)?(?:(?<weeks>\d)w)?(?:(?<days>\d{1,2})d)?(?:(?<hours>\d{1,2})h)?(?:(?<minutes>\d{1,2})m)?$",
|
public readonly Regex Regex = new Regex(@"^(?:(?<months>\d)mo)?(?:(?<weeks>\d)w)?(?:(?<days>\d{1,2})d)?(?:(?<hours>\d{1,2})h)?(?:(?<minutes>\d{1,2})m)?$",
|
||||||
RegexOptions.Compiled | RegexOptions.Multiline);
|
RegexOptions.Compiled | RegexOptions.Multiline);
|
||||||
@ -29,7 +29,7 @@ namespace NadekoBot.Services.Utility
|
|||||||
private readonly DbService _db;
|
private readonly DbService _db;
|
||||||
|
|
||||||
public RemindService(DiscordSocketClient client, BotConfig config, DbService db,
|
public RemindService(DiscordSocketClient client, BotConfig config, DbService db,
|
||||||
List<long> guilds, IUnitOfWork uow)
|
StartingGuildsService guilds, IUnitOfWork uow)
|
||||||
{
|
{
|
||||||
_config = config;
|
_config = config;
|
||||||
_client = client;
|
_client = client;
|
||||||
|
@ -12,7 +12,7 @@ using NLog;
|
|||||||
|
|
||||||
namespace NadekoBot.Services.Utility
|
namespace NadekoBot.Services.Utility
|
||||||
{
|
{
|
||||||
public class StreamRoleService
|
public class StreamRoleService : INService
|
||||||
{
|
{
|
||||||
private readonly DbService _db;
|
private readonly DbService _db;
|
||||||
private readonly ConcurrentDictionary<ulong, StreamRoleSettings> guildSettings;
|
private readonly ConcurrentDictionary<ulong, StreamRoleSettings> guildSettings;
|
||||||
@ -26,6 +26,7 @@ namespace NadekoBot.Services.Utility
|
|||||||
this._log = LogManager.GetCurrentClassLogger();
|
this._log = LogManager.GetCurrentClassLogger();
|
||||||
|
|
||||||
guildSettings = gcs.ToDictionary(x => x.GuildId, x => x.StreamRole)
|
guildSettings = gcs.ToDictionary(x => x.GuildId, x => x.StreamRole)
|
||||||
|
.Where(x => x.Value.FromRoleId != 0 && x.Value.AddRoleId != 0)
|
||||||
.ToConcurrent();
|
.ToConcurrent();
|
||||||
|
|
||||||
client.GuildMemberUpdated += Client_GuildMemberUpdated;
|
client.GuildMemberUpdated += Client_GuildMemberUpdated;
|
||||||
|
@ -10,7 +10,7 @@ using System.Linq;
|
|||||||
|
|
||||||
namespace NadekoBot.Services.Utility
|
namespace NadekoBot.Services.Utility
|
||||||
{
|
{
|
||||||
public class VerboseErrorsService
|
public class VerboseErrorsService : INService
|
||||||
{
|
{
|
||||||
private readonly ConcurrentHashSet<ulong> guildsEnabled;
|
private readonly ConcurrentHashSet<ulong> guildsEnabled;
|
||||||
private readonly DbService _db;
|
private readonly DbService _db;
|
||||||
|
@ -3,7 +3,6 @@ using NadekoBot.Services;
|
|||||||
using NadekoBot.Services.Impl;
|
using NadekoBot.Services.Impl;
|
||||||
using NLog;
|
using NLog;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
Loading…
Reference in New Issue
Block a user