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
|
||||
{
|
||||
private readonly CommandService _cmds;
|
||||
private readonly CommandHandler _cmdHandler;
|
||||
|
||||
public CommandTypeReader(CommandService cmds, CommandHandler cmdHandler)
|
||||
{
|
||||
_cmds = cmds;
|
||||
_cmdHandler = cmdHandler;
|
||||
}
|
||||
|
||||
public override Task<TypeReaderResult> Read(ICommandContext context, string input, IServiceProvider _)
|
||||
public override Task<TypeReaderResult> Read(ICommandContext context, string input, IServiceProvider services)
|
||||
{
|
||||
var _cmds = ((INServiceProvider)services).GetService<CommandService>();
|
||||
var _cmdHandler = ((INServiceProvider)services).GetService<CommandHandler>();
|
||||
input = input.ToUpperInvariant();
|
||||
var prefix = _cmdHandler.GetPrefix(context.Guild);
|
||||
if (!input.StartsWith(prefix.ToUpperInvariant()))
|
||||
@ -38,17 +31,12 @@ namespace NadekoBot.TypeReaders
|
||||
|
||||
public class CommandOrCrTypeReader : CommandTypeReader
|
||||
{
|
||||
private readonly CustomReactionsService _crs;
|
||||
|
||||
public CommandOrCrTypeReader(CustomReactionsService crs, CommandService cmds, CommandHandler cmdHandler) : base(cmds, cmdHandler)
|
||||
{
|
||||
_crs = crs;
|
||||
}
|
||||
|
||||
public override async Task<TypeReaderResult> Read(ICommandContext context, string input, IServiceProvider _)
|
||||
public override async Task<TypeReaderResult> Read(ICommandContext context, string input, IServiceProvider services)
|
||||
{
|
||||
input = input.ToUpperInvariant();
|
||||
|
||||
var _crs = ((INServiceProvider)services).GetService<CustomReactionsService>();
|
||||
|
||||
if (_crs.GlobalReactions.Any(x => x.Trigger.ToUpperInvariant() == 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)
|
||||
{
|
||||
return TypeReaderResult.FromSuccess(new CommandOrCrInfo(((CommandInfo)cmd.Values.First().Value).Name));
|
||||
|
@ -1,4 +1,5 @@
|
||||
using Discord.Commands;
|
||||
using NadekoBot.Services;
|
||||
using NadekoBot.Services.Administration;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
@ -7,15 +8,9 @@ namespace NadekoBot.TypeReaders
|
||||
{
|
||||
public class GuildDateTimeTypeReader : TypeReader
|
||||
{
|
||||
private readonly GuildTimezoneService _gts;
|
||||
|
||||
public GuildDateTimeTypeReader(GuildTimezoneService gts)
|
||||
{
|
||||
_gts = gts;
|
||||
}
|
||||
|
||||
public override Task<TypeReaderResult> Read(ICommandContext context, string input, IServiceProvider _)
|
||||
public override Task<TypeReaderResult> Read(ICommandContext context, string input, IServiceProvider services)
|
||||
{
|
||||
var _gts = (GuildTimezoneService)services.GetService(typeof(GuildTimezoneService));
|
||||
if (!DateTime.TryParse(input, out var dt))
|
||||
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]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
[RequireUserPermission(GuildPermission.ManageRoles)]
|
||||
[Priority(1)]
|
||||
[Priority(0)]
|
||||
public async Task SetMuteRole([Remainder] string name)
|
||||
{
|
||||
name = name.Trim();
|
||||
@ -45,7 +45,7 @@ namespace NadekoBot.Modules.Administration
|
||||
[NadekoCommand, Usage, Description, Aliases]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
[RequireUserPermission(GuildPermission.ManageRoles)]
|
||||
[Priority(0)]
|
||||
[Priority(1)]
|
||||
public Task SetMuteRole([Remainder] IRole role)
|
||||
=> SetMuteRole(role.Name);
|
||||
|
||||
@ -53,7 +53,7 @@ namespace NadekoBot.Modules.Administration
|
||||
[RequireContext(ContextType.Guild)]
|
||||
[RequireUserPermission(GuildPermission.ManageRoles)]
|
||||
[RequireUserPermission(GuildPermission.MuteMembers)]
|
||||
[Priority(1)]
|
||||
[Priority(0)]
|
||||
public async Task Mute(IGuildUser user)
|
||||
{
|
||||
try
|
||||
@ -71,7 +71,7 @@ namespace NadekoBot.Modules.Administration
|
||||
[RequireContext(ContextType.Guild)]
|
||||
[RequireUserPermission(GuildPermission.ManageRoles)]
|
||||
[RequireUserPermission(GuildPermission.MuteMembers)]
|
||||
[Priority(0)]
|
||||
[Priority(1)]
|
||||
public async Task Mute(int minutes, IGuildUser user)
|
||||
{
|
||||
if (minutes < 1 || minutes > 1440)
|
||||
|
@ -11,7 +11,7 @@ namespace NadekoBot.Modules.Administration
|
||||
public class PrefixCommands : NadekoSubmodule
|
||||
{
|
||||
[NadekoCommand, Usage, Description, Aliases]
|
||||
[Priority(0)]
|
||||
[Priority(1)]
|
||||
public new async Task Prefix()
|
||||
{
|
||||
await ReplyConfirmLocalized("prefix_current", Format.Code(_cmdHandler.GetPrefix(Context.Guild))).ConfigureAwait(false);
|
||||
@ -21,7 +21,7 @@ namespace NadekoBot.Modules.Administration
|
||||
[NadekoCommand, Usage, Description, Aliases]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
[RequireUserPermission(GuildPermission.Administrator)]
|
||||
[Priority(1)]
|
||||
[Priority(0)]
|
||||
public new async Task Prefix([Remainder]string prefix)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(prefix))
|
||||
|
@ -39,7 +39,7 @@ namespace NadekoBot.Modules.Administration
|
||||
[RequireContext(ContextType.Guild)]
|
||||
[RequireUserPermission(ChannelPermission.ManageMessages)]
|
||||
[RequireBotPermission(GuildPermission.ManageMessages)]
|
||||
[Priority(0)]
|
||||
[Priority(1)]
|
||||
public async Task Prune(int count)
|
||||
{
|
||||
count++;
|
||||
@ -55,7 +55,7 @@ namespace NadekoBot.Modules.Administration
|
||||
[RequireContext(ContextType.Guild)]
|
||||
[RequireUserPermission(ChannelPermission.ManageMessages)]
|
||||
[RequireBotPermission(GuildPermission.ManageMessages)]
|
||||
[Priority(1)]
|
||||
[Priority(0)]
|
||||
public async Task Prune(IGuildUser user, int count = 100)
|
||||
{
|
||||
if (user.Id == Context.User.Id)
|
||||
|
@ -67,7 +67,7 @@ namespace NadekoBot.Modules.Administration
|
||||
[NadekoCommand, Usage, Description, Aliases]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
[RequireUserPermission(GuildPermission.ManageMessages)]
|
||||
[Priority(1)]
|
||||
[Priority(0)]
|
||||
public async Task SlowmodeWhitelist(IGuildUser user)
|
||||
{
|
||||
var siu = new SlowmodeIgnoredUser
|
||||
@ -99,7 +99,7 @@ namespace NadekoBot.Modules.Administration
|
||||
[NadekoCommand, Usage, Description, Aliases]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
[RequireUserPermission(GuildPermission.ManageMessages)]
|
||||
[Priority(0)]
|
||||
[Priority(1)]
|
||||
public async Task SlowmodeWhitelist(IRole role)
|
||||
{
|
||||
var sir = new SlowmodeIgnoredRole
|
||||
|
@ -289,7 +289,7 @@ namespace NadekoBot.Modules.Administration
|
||||
|
||||
[NadekoCommand, Usage, Description, Aliases]
|
||||
[RequireUserPermission(GuildPermission.ManageNicknames)]
|
||||
[Priority(1)]
|
||||
[Priority(0)]
|
||||
public async Task SetNick([Remainder] string newNick = null)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(newNick))
|
||||
@ -303,7 +303,7 @@ namespace NadekoBot.Modules.Administration
|
||||
[NadekoCommand, Usage, Description, Aliases]
|
||||
[RequireBotPermission(GuildPermission.ManageNicknames)]
|
||||
[RequireUserPermission(GuildPermission.ManageNicknames)]
|
||||
[Priority(0)]
|
||||
[Priority(1)]
|
||||
public async Task SetNick(IGuildUser gu, [Remainder] string newNick = null)
|
||||
{
|
||||
await gu.ModifyAsync(u => u.Nickname = newNick).ConfigureAwait(false);
|
||||
|
@ -132,27 +132,27 @@ namespace NadekoBot.Modules.Administration
|
||||
[NadekoCommand, Usage, Description, Aliases]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
[RequireUserPermission(GuildPermission.BanMembers)]
|
||||
[Priority(1)]
|
||||
[Priority(2)]
|
||||
public Task Warnlog(int page, IGuildUser user)
|
||||
=> Warnlog(page, user.Id);
|
||||
|
||||
[NadekoCommand, Usage, Description, Aliases]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
[Priority(0)]
|
||||
[Priority(3)]
|
||||
public Task Warnlog(IGuildUser user)
|
||||
=> Context.User.Id == user.Id || ((IGuildUser)Context.User).GuildPermissions.BanMembers ? Warnlog(user.Id) : Task.CompletedTask;
|
||||
|
||||
[NadekoCommand, Usage, Description, Aliases]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
[RequireUserPermission(GuildPermission.BanMembers)]
|
||||
[Priority(3)]
|
||||
[Priority(0)]
|
||||
public Task Warnlog(int page, ulong userId)
|
||||
=> InternalWarnlog(userId, page - 1);
|
||||
|
||||
[NadekoCommand, Usage, Description, Aliases]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
[RequireUserPermission(GuildPermission.BanMembers)]
|
||||
[Priority(2)]
|
||||
[Priority(1)]
|
||||
public Task Warnlog(ulong userId)
|
||||
=> 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]
|
||||
[Priority(0)]
|
||||
[Priority(1)]
|
||||
public async Task ListCustReact(int page = 1)
|
||||
{
|
||||
if (--page < 0 || page > 999)
|
||||
@ -130,7 +130,7 @@ namespace NadekoBot.Modules.CustomReactions
|
||||
}
|
||||
|
||||
[NadekoCommand, Usage, Description, Aliases]
|
||||
[Priority(1)]
|
||||
[Priority(0)]
|
||||
public async Task ListCustReact(All x)
|
||||
{
|
||||
CustomReaction[] customReactions;
|
||||
|
@ -58,7 +58,7 @@ namespace NadekoBot.Modules.Gambling
|
||||
}
|
||||
|
||||
[NadekoCommand, Usage, Description, Aliases]
|
||||
[Priority(0)]
|
||||
[Priority(1)]
|
||||
public async Task Roll(int num)
|
||||
{
|
||||
await InternalRoll(num, true).ConfigureAwait(false);
|
||||
@ -66,21 +66,21 @@ namespace NadekoBot.Modules.Gambling
|
||||
|
||||
|
||||
[NadekoCommand, Usage, Description, Aliases]
|
||||
[Priority(0)]
|
||||
[Priority(1)]
|
||||
public async Task Rolluo(int num = 1)
|
||||
{
|
||||
await InternalRoll(num, false).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
[NadekoCommand, Usage, Description, Aliases]
|
||||
[Priority(1)]
|
||||
[Priority(0)]
|
||||
public async Task Roll(string arg)
|
||||
{
|
||||
await InternallDndRoll(arg, true).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
[NadekoCommand, Usage, Description, Aliases]
|
||||
[Priority(1)]
|
||||
[Priority(0)]
|
||||
public async Task Rolluo(string arg)
|
||||
{
|
||||
await InternallDndRoll(arg, false).ConfigureAwait(false);
|
||||
|
@ -197,12 +197,12 @@ namespace NadekoBot.Modules.Gambling
|
||||
private static readonly TimeSpan _divorceLimit = TimeSpan.FromHours(6);
|
||||
[NadekoCommand, Usage, Description, Aliases]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
[Priority(1)]
|
||||
[Priority(0)]
|
||||
public Task Divorce([Remainder]IGuildUser target) => Divorce(target.Id);
|
||||
|
||||
[NadekoCommand, Usage, Description, Aliases]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
[Priority(0)]
|
||||
[Priority(1)]
|
||||
public async Task Divorce([Remainder]ulong targetId)
|
||||
{
|
||||
if (targetId == Context.User.Id)
|
||||
|
@ -52,7 +52,7 @@ namespace NadekoBot.Modules.Gambling
|
||||
}
|
||||
|
||||
[NadekoCommand, Usage, Description, Aliases]
|
||||
[Priority(0)]
|
||||
[Priority(1)]
|
||||
public async Task Cash([Remainder] IUser user = null)
|
||||
{
|
||||
if(user == null)
|
||||
@ -62,7 +62,7 @@ namespace NadekoBot.Modules.Gambling
|
||||
}
|
||||
|
||||
[NadekoCommand, Usage, Description, Aliases]
|
||||
[Priority(1)]
|
||||
[Priority(0)]
|
||||
public async Task Cash(ulong userId)
|
||||
{
|
||||
await ReplyConfirmLocalized("has", Format.Code(userId.ToString()), $"{GetCurrency(userId)} {CurrencySign}").ConfigureAwait(false);
|
||||
@ -88,7 +88,7 @@ namespace NadekoBot.Modules.Gambling
|
||||
[NadekoCommand, Usage, Description, Aliases]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
[OwnerOnly]
|
||||
[Priority(2)]
|
||||
[Priority(0)]
|
||||
public Task Award(int amount, [Remainder] IGuildUser usr) =>
|
||||
Award(amount, usr.Id);
|
||||
|
||||
@ -107,7 +107,7 @@ namespace NadekoBot.Modules.Gambling
|
||||
[NadekoCommand, Usage, Description, Aliases]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
[OwnerOnly]
|
||||
[Priority(0)]
|
||||
[Priority(2)]
|
||||
public async Task Award(int amount, [Remainder] IRole role)
|
||||
{
|
||||
var users = (await Context.Guild.GetUsersAsync())
|
||||
|
@ -82,14 +82,14 @@ namespace NadekoBot.Modules.Help
|
||||
await ConfirmLocalized("commands_instr", Prefix).ConfigureAwait(false);
|
||||
}
|
||||
[NadekoCommand, Usage, Description, Aliases]
|
||||
[Priority(1)]
|
||||
[Priority(0)]
|
||||
public async Task H([Remainder] string fail)
|
||||
{
|
||||
await ReplyErrorLocalized("command_not_found").ConfigureAwait(false);
|
||||
}
|
||||
|
||||
[NadekoCommand, Usage, Description, Aliases]
|
||||
[Priority(0)]
|
||||
[Priority(1)]
|
||||
public async Task H([Remainder] CommandInfo com = null)
|
||||
{
|
||||
var channel = Context.Channel;
|
||||
|
@ -377,7 +377,7 @@ namespace NadekoBot.Modules.Music
|
||||
|
||||
[NadekoCommand, Usage, Description, Aliases]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
[Priority(0)]
|
||||
[Priority(1)]
|
||||
public async Task SongRemove(int index)
|
||||
{
|
||||
if (index < 1)
|
||||
@ -406,7 +406,7 @@ namespace NadekoBot.Modules.Music
|
||||
public enum All { All }
|
||||
[NadekoCommand, Usage, Description, Aliases]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
[Priority(1)]
|
||||
[Priority(0)]
|
||||
public async Task SongRemove(All all)
|
||||
{
|
||||
var mp = _music.GetPlayerOrDefault(Context.Guild.Id);
|
||||
@ -853,41 +853,6 @@ namespace NadekoBot.Modules.Music
|
||||
else
|
||||
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]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
|
@ -192,10 +192,18 @@ namespace NadekoBot.Modules.NSFW
|
||||
if (imgObj == null)
|
||||
await ReplyErrorLocalized("not_found").ConfigureAwait(false);
|
||||
else
|
||||
await Context.Channel.EmbedAsync(new EmbedBuilder().WithOkColor()
|
||||
{
|
||||
var embed = new EmbedBuilder().WithOkColor()
|
||||
.WithDescription($"{Context.User} [{tag ?? "url"}]({imgObj}) ")
|
||||
.WithImageUrl(imgObj.FileUrl)
|
||||
.WithFooter(efb => efb.WithText(type.ToString()))).ConfigureAwait(false);
|
||||
.WithFooter(efb => efb.WithText(type.ToString()));
|
||||
|
||||
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]
|
||||
[Priority(1)]
|
||||
[Priority(0)]
|
||||
public async Task Mal([Remainder] string name)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(name))
|
||||
@ -132,7 +132,7 @@ namespace NadekoBot.Modules.Searches
|
||||
|
||||
[NadekoCommand, Usage, Description, Aliases]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
[Priority(0)]
|
||||
[Priority(1)]
|
||||
public Task Mal(IGuildUser usr) => Mal(usr.Username);
|
||||
|
||||
[NadekoCommand, Usage, Description, Aliases]
|
||||
|
@ -17,7 +17,7 @@ namespace NadekoBot.Modules.Searches
|
||||
private const string _xkcdUrl = "https://xkcd.com";
|
||||
|
||||
[NadekoCommand, Usage, Description, Aliases]
|
||||
[Priority(1)]
|
||||
[Priority(0)]
|
||||
public async Task Xkcd(string arg = null)
|
||||
{
|
||||
if (arg?.ToLowerInvariant().Trim() == "latest")
|
||||
@ -44,7 +44,7 @@ namespace NadekoBot.Modules.Searches
|
||||
}
|
||||
|
||||
[NadekoCommand, Usage, Description, Aliases]
|
||||
[Priority(0)]
|
||||
[Priority(1)]
|
||||
public async Task Xkcd(int num)
|
||||
{
|
||||
if (num < 1)
|
||||
|
@ -36,7 +36,7 @@ namespace NadekoBot.Modules.Utility
|
||||
|
||||
[NadekoCommand, Usage, Description, Aliases]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
[Priority(0)]
|
||||
[Priority(1)]
|
||||
public async Task Remind(MeOrHere meorhere, string timeStr, [Remainder] string message)
|
||||
{
|
||||
ulong target;
|
||||
@ -47,7 +47,7 @@ namespace NadekoBot.Modules.Utility
|
||||
[NadekoCommand, Usage, Description, Aliases]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
[RequireUserPermission(GuildPermission.ManageMessages)]
|
||||
[Priority(1)]
|
||||
[Priority(0)]
|
||||
public async Task Remind(ITextChannel channel, string timeStr, [Remainder] string message)
|
||||
{
|
||||
var perms = ((IGuildUser)Context.User).GetPermissions((ITextChannel)channel);
|
||||
|
@ -63,7 +63,6 @@ namespace NadekoBot.Modules.Utility
|
||||
[NadekoCommand, Usage, Description, Aliases]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
[RequireUserPermission(GuildPermission.ManageMessages)]
|
||||
[Priority(0)]
|
||||
public async Task RepeatRemove(int index)
|
||||
{
|
||||
if (!_service.RepeaterReady)
|
||||
@ -103,7 +102,7 @@ namespace NadekoBot.Modules.Utility
|
||||
[NadekoCommand, Usage, Description, Aliases]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
[RequireUserPermission(GuildPermission.ManageMessages)]
|
||||
[Priority(1)]
|
||||
[Priority(0)]
|
||||
public async Task Repeat(int minutes, [Remainder] string message)
|
||||
{
|
||||
if (!_service.RepeaterReady)
|
||||
@ -152,7 +151,7 @@ namespace NadekoBot.Modules.Utility
|
||||
[NadekoCommand, Usage, Description, Aliases]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
[RequireUserPermission(GuildPermission.ManageMessages)]
|
||||
[Priority(0)]
|
||||
[Priority(1)]
|
||||
public async Task Repeat(GuildDateTime gt, [Remainder] string message)
|
||||
{
|
||||
if (!_service.RepeaterReady)
|
||||
|
@ -14,20 +14,12 @@ using System.Collections.Immutable;
|
||||
using System.Diagnostics;
|
||||
using NadekoBot.Services.Database.Models;
|
||||
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 NadekoBot.Services.Pokemon;
|
||||
using NadekoBot.DataStructures.ShardCom;
|
||||
using NadekoBot.DataStructures;
|
||||
using NadekoBot.Extensions;
|
||||
using System.Collections.Generic;
|
||||
using NadekoBot.Services.Database;
|
||||
|
||||
namespace NadekoBot
|
||||
{
|
||||
@ -35,6 +27,15 @@ namespace NadekoBot
|
||||
{
|
||||
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
|
||||
* and keep the convenience of .WithOkColor
|
||||
* and .WithErrorColor extensions methods.
|
||||
@ -44,23 +45,9 @@ namespace NadekoBot
|
||||
public static Color OkColor { get; private set; }
|
||||
public static Color ErrorColor { get; private set; }
|
||||
|
||||
public ImmutableArray<GuildConfig> AllGuildConfigs { get; private set; }
|
||||
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 TaskCompletionSource<bool> Ready { get; private set; } = new TaskCompletionSource<bool>();
|
||||
|
||||
public INServiceProvider Services { get; private set; }
|
||||
public BotCredentials Credentials { get; }
|
||||
|
||||
public int ShardId { get; }
|
||||
public ShardsCoordinator ShardCoord { get; private set; }
|
||||
@ -72,26 +59,14 @@ namespace NadekoBot
|
||||
if (shardId < 0)
|
||||
throw new ArgumentOutOfRangeException(nameof(shardId));
|
||||
|
||||
ShardId = shardId;
|
||||
|
||||
LogSetup.SetupLogger();
|
||||
_log = LogManager.GetCurrentClassLogger();
|
||||
TerribleElevatedPermissionCheck();
|
||||
|
||||
ShardId = shardId;
|
||||
|
||||
Credentials = new BotCredentials();
|
||||
|
||||
port = port ?? Credentials.ShardRunPort;
|
||||
_comClient = new ShardComClient(port.Value);
|
||||
|
||||
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
|
||||
{
|
||||
MessageCacheSize = 10,
|
||||
@ -101,16 +76,21 @@ namespace NadekoBot
|
||||
ShardId = shardId,
|
||||
AlwaysDownloadUsers = false,
|
||||
});
|
||||
|
||||
CommandService = new CommandService(new CommandServiceConfig()
|
||||
{
|
||||
CaseSensitiveCommands = false,
|
||||
DefaultRunMode = RunMode.Sync,
|
||||
});
|
||||
|
||||
Images = new ImagesService();
|
||||
Currency = new CurrencyService(BotConfig, Db);
|
||||
GoogleApi = new GoogleApiService(Credentials);
|
||||
port = port ?? Credentials.ShardRunPort;
|
||||
_comClient = new ShardComClient(port.Value);
|
||||
|
||||
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);
|
||||
|
||||
@ -146,140 +126,34 @@ namespace NadekoBot
|
||||
{
|
||||
AllGuildConfigs = uow.GuildConfigs.GetAllGuildConfigs(startingGuildIdList).ToImmutableArray();
|
||||
|
||||
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
|
||||
var localization = new Localization(BotConfig.Locale, AllGuildConfigs.ToDictionary(x => x.GuildId, x => x.Locale), Db);
|
||||
|
||||
//initialize Services
|
||||
Services = new NServiceProvider.ServiceProviderBuilder()
|
||||
.Add<ILocalization>(Localization)
|
||||
.Add<IStatsService>(Stats)
|
||||
.Add<IImagesService>(Images)
|
||||
.Add<IGoogleApiService>(GoogleApi)
|
||||
.Add<IStatsService>(Stats)
|
||||
.Add<IBotCredentials>(Credentials)
|
||||
.Add<CommandService>(CommandService)
|
||||
.Add<NadekoStrings>(Strings)
|
||||
.Add<DiscordSocketClient>(Client)
|
||||
.Add<BotConfig>(BotConfig)
|
||||
.Add<CurrencyService>(Currency)
|
||||
.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)
|
||||
.AddManual<IBotCredentials>(Credentials)
|
||||
.AddManual(Db)
|
||||
.AddManual(BotConfig)
|
||||
.AddManual(Client)
|
||||
.AddManual(CommandService)
|
||||
.AddManual<ILocalization>(localization)
|
||||
.AddManual<IEnumerable<GuildConfig>>(AllGuildConfigs) //todo wrap this
|
||||
.AddManual<NadekoBot>(this)
|
||||
.AddManual<IUnitOfWork>(uow)
|
||||
.AddManual(ShardCoord)
|
||||
.LoadFrom(Assembly.GetEntryAssembly())
|
||||
.Build();
|
||||
|
||||
CommandHandler.AddServices(Services);
|
||||
var commandHandler = Services.GetService<CommandHandler>();
|
||||
commandHandler.AddServices(Services);
|
||||
|
||||
//setup typereaders
|
||||
CommandService.AddTypeReader<PermissionAction>(new PermissionActionTypeReader());
|
||||
CommandService.AddTypeReader<CommandInfo>(new CommandTypeReader(CommandService, CommandHandler));
|
||||
CommandService.AddTypeReader<CommandOrCrInfo>(new CommandOrCrTypeReader(crService, CommandService, CommandHandler));
|
||||
CommandService.AddTypeReader<CommandInfo>(new CommandTypeReader());
|
||||
CommandService.AddTypeReader<CommandOrCrInfo>(new CommandOrCrTypeReader());
|
||||
CommandService.AddTypeReader<ModuleInfo>(new ModuleTypeReader(CommandService));
|
||||
CommandService.AddTypeReader<ModuleOrCrInfo>(new ModuleOrCrTypeReader(CommandService));
|
||||
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)))
|
||||
.ForEach(x => CommandService.RemoveModuleAsync(x));
|
||||
|
||||
Ready = true;
|
||||
Ready.TrySetResult(true);
|
||||
_log.Info($"Shard {ShardId} ready.");
|
||||
//_log.Info(await stats.Print().ConfigureAwait(false));
|
||||
}
|
||||
|
@ -55,7 +55,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<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="CoreCLR-NCalc" Version="2.1.2" />
|
||||
<PackageReference Include="Google.Apis.Urlshortener.v1" Version="1.19.0.138" />
|
||||
|
@ -11,7 +11,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace NadekoBot.Services.Administration
|
||||
{
|
||||
public class AdministrationService
|
||||
public class AdministrationService : INService
|
||||
{
|
||||
public readonly ConcurrentHashSet<ulong> DeleteMessagesOnCommand;
|
||||
private readonly Logger _log;
|
||||
|
@ -9,7 +9,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace NadekoBot.Services.Administration
|
||||
{
|
||||
public class AutoAssignRoleService
|
||||
public class AutoAssignRoleService : INService
|
||||
{
|
||||
private readonly Logger _log;
|
||||
private readonly DiscordSocketClient _client;
|
||||
|
@ -10,7 +10,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace NadekoBot.Services.Administration
|
||||
{
|
||||
public class GameVoiceChannelService
|
||||
public class GameVoiceChannelService : INService
|
||||
{
|
||||
public readonly ConcurrentHashSet<ulong> GameVoiceChannels = new ConcurrentHashSet<ulong>();
|
||||
|
||||
|
@ -9,7 +9,7 @@ using Discord.WebSocket;
|
||||
|
||||
namespace NadekoBot.Services.Administration
|
||||
{
|
||||
public class GuildTimezoneService
|
||||
public class GuildTimezoneService : INService
|
||||
{
|
||||
//hack >.>
|
||||
public static ConcurrentDictionary<ulong, GuildTimezoneService> AllServices { get; } = new ConcurrentDictionary<ulong, GuildTimezoneService>();
|
||||
|
@ -13,7 +13,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace NadekoBot.Services.Administration
|
||||
{
|
||||
public class LogCommandService
|
||||
public class LogCommandService : INService
|
||||
{
|
||||
|
||||
private readonly DiscordSocketClient _client;
|
||||
|
@ -20,7 +20,7 @@ namespace NadekoBot.Services.Administration
|
||||
All
|
||||
}
|
||||
|
||||
public class MuteService
|
||||
public class MuteService : INService
|
||||
{
|
||||
public ConcurrentDictionary<ulong, string> GuildMuteRoles { get; }
|
||||
public ConcurrentDictionary<ulong, ConcurrentHashSet<ulong>> MutedUsers { get; }
|
||||
|
@ -9,7 +9,7 @@ using System.Threading;
|
||||
|
||||
namespace NadekoBot.Services.Administration
|
||||
{
|
||||
public class PlayingRotateService
|
||||
public class PlayingRotateService : INService
|
||||
{
|
||||
private readonly Timer _t;
|
||||
private readonly DiscordSocketClient _client;
|
||||
|
@ -10,7 +10,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace NadekoBot.Services.Administration
|
||||
{
|
||||
public class ProtectionService
|
||||
public class ProtectionService : INService
|
||||
{
|
||||
public readonly ConcurrentDictionary<ulong, AntiRaidStats> AntiRaidGuilds =
|
||||
new ConcurrentDictionary<ulong, AntiRaidStats>();
|
||||
|
@ -9,7 +9,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace NadekoBot.Services.Administration
|
||||
{
|
||||
public class PruneService
|
||||
public class PruneService : INService
|
||||
{
|
||||
//channelids where prunes are currently occuring
|
||||
private ConcurrentHashSet<ulong> _pruningGuilds = new ConcurrentHashSet<ulong>();
|
||||
|
@ -12,7 +12,7 @@ using System.Threading.Tasks;
|
||||
|
||||
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, HashSet<ulong>> IgnoredRoles = new ConcurrentDictionary<ulong, HashSet<ulong>>();
|
||||
|
@ -12,7 +12,7 @@ using System.Collections.Generic;
|
||||
|
||||
namespace NadekoBot.Services.Administration
|
||||
{
|
||||
public class SelfService : ILateExecutor
|
||||
public class SelfService : ILateExecutor, INService
|
||||
{
|
||||
public volatile bool ForwardDMs;
|
||||
public volatile bool ForwardDMsToAllOwners;
|
||||
@ -44,8 +44,7 @@ namespace NadekoBot.Services.Administration
|
||||
|
||||
var _ = Task.Run(async () =>
|
||||
{
|
||||
while (!bot.Ready)
|
||||
await Task.Delay(1000);
|
||||
await bot.Ready.Task.ConfigureAwait(false);
|
||||
|
||||
foreach (var cmd in bc.StartupCommands)
|
||||
{
|
||||
@ -56,8 +55,7 @@ namespace NadekoBot.Services.Administration
|
||||
|
||||
var ___ = Task.Run(async () =>
|
||||
{
|
||||
while (!bot.Ready)
|
||||
await Task.Delay(1000);
|
||||
await bot.Ready.Task.ConfigureAwait(false);
|
||||
|
||||
await Task.Delay(5000);
|
||||
|
||||
|
@ -10,7 +10,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace NadekoBot.Services.Administration
|
||||
{
|
||||
public class VcRoleService
|
||||
public class VcRoleService : INService
|
||||
{
|
||||
private readonly Logger _log;
|
||||
private readonly DbService _db;
|
||||
|
@ -13,7 +13,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace NadekoBot.Services.Administration
|
||||
{
|
||||
public class VplusTService
|
||||
public class VplusTService : INService
|
||||
{
|
||||
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 class CommandHandler
|
||||
|
||||
public class CommandHandler : INService
|
||||
{
|
||||
public const int GlobalCommandsCooldown = 750;
|
||||
|
||||
@ -189,7 +190,7 @@ namespace NadekoBot.Services
|
||||
{
|
||||
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;
|
||||
|
||||
if (!(msg is SocketUserMessage usrMsg))
|
||||
@ -296,52 +297,93 @@ namespace NadekoBot.Services
|
||||
=> 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);
|
||||
if (!searchResult.IsSuccess)
|
||||
return (false, null, null);
|
||||
|
||||
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);
|
||||
if (!preconditionResult.IsSuccess)
|
||||
{
|
||||
return (false, preconditionResult.ErrorReason, commands[i].Command);
|
||||
preconditionResults[match] = await match.Command.CheckPreconditionsAsync(context, services).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
var parseResult = await commands[i].ParseAsync(context, searchResult, preconditionResult).ConfigureAwait(false);
|
||||
if (!parseResult.IsSuccess)
|
||||
var successfulPreconditions = preconditionResults
|
||||
.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)
|
||||
{
|
||||
TypeReaderValue[] argList, paramList;
|
||||
IReadOnlyList<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();
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
if (!parseResult.IsSuccess)
|
||||
{
|
||||
if (commands.Count == 1)
|
||||
return (false, parseResult.ErrorReason, commands[i].Command);
|
||||
else
|
||||
continue;
|
||||
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 cmd = commands[i].Command;
|
||||
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, commands[i].Command);
|
||||
return (false, null, cmd);
|
||||
//return SearchResult.FromError(CommandError.Exception, "You are on a global cooldown.");
|
||||
|
||||
var commandName = cmd.Aliases.First();
|
||||
@ -351,11 +393,14 @@ namespace NadekoBot.Services
|
||||
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);
|
||||
return (false, null, cmd);
|
||||
}
|
||||
}
|
||||
|
||||
var execResult = (ExecuteResult)(await commands[i].ExecuteAsync(context, parseResult, serviceProvider));
|
||||
//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)
|
||||
@ -368,11 +413,8 @@ namespace NadekoBot.Services
|
||||
_log.Warn(execResult.Exception);
|
||||
}
|
||||
}
|
||||
return (true, null, commands[i].Command);
|
||||
}
|
||||
|
||||
return (false, null, null);
|
||||
//return new ExecuteCommandResult(null, null, SearchResult.FromError(CommandError.UnknownCommand, "This input does not match any overload."));
|
||||
return (true, null, cmd);
|
||||
}
|
||||
|
||||
private readonly object errorLogLock = new object();
|
||||
|
@ -7,7 +7,7 @@ using NadekoBot.Services.Database;
|
||||
|
||||
namespace NadekoBot.Services
|
||||
{
|
||||
public class CurrencyService
|
||||
public class CurrencyService : INService
|
||||
{
|
||||
private readonly BotConfig _config;
|
||||
private readonly DbService _db;
|
||||
|
@ -14,7 +14,7 @@ using NadekoBot.Services.Database;
|
||||
|
||||
namespace NadekoBot.Services.CustomReactions
|
||||
{
|
||||
public class CustomReactionsService : IEarlyBlockingExecutor
|
||||
public class CustomReactionsService : IEarlyBlockingExecutor, INService
|
||||
{
|
||||
public CustomReaction[] GlobalReactions = new 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 HashSet<BlockedCmdOrMdl> BlockedCommands { 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 bool CustomReactionsStartWith { get; set; } = false;
|
||||
}
|
||||
|
@ -6,6 +6,6 @@ namespace NadekoBot.Services.Database.Repositories
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace NadekoBot.Services.Games
|
||||
{
|
||||
public class ChatterBotService : IEarlyBlockingExecutor
|
||||
public class ChatterBotService : IEarlyBlockingExecutor, INService
|
||||
{
|
||||
private readonly DiscordSocketClient _client;
|
||||
private readonly Logger _log;
|
||||
|
@ -15,7 +15,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace NadekoBot.Services.Games
|
||||
{
|
||||
public class GamesService
|
||||
public class GamesService : INService
|
||||
{
|
||||
private readonly BotConfig _bc;
|
||||
|
||||
|
@ -9,7 +9,7 @@ using NLog;
|
||||
|
||||
namespace NadekoBot.Services.Games
|
||||
{
|
||||
public class PollService : IEarlyBlockingExecutor
|
||||
public class PollService : IEarlyBlockingExecutor, INService
|
||||
{
|
||||
public ConcurrentDictionary<ulong, Poll> ActivePolls = new ConcurrentDictionary<ulong, Poll>();
|
||||
private readonly Logger _log;
|
||||
|
@ -13,7 +13,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace NadekoBot.Services
|
||||
{
|
||||
public class GreetSettingsService
|
||||
public class GreetSettingsService : INService
|
||||
{
|
||||
private readonly DbService _db;
|
||||
|
||||
|
@ -11,7 +11,7 @@ using NadekoBot.Attributes;
|
||||
|
||||
namespace NadekoBot.Services.Help
|
||||
{
|
||||
public class HelpService : ILateExecutor
|
||||
public class HelpService : ILateExecutor, INService
|
||||
{
|
||||
private readonly BotConfig _bc;
|
||||
private readonly CommandHandler _ch;
|
||||
|
@ -5,7 +5,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace NadekoBot.Services
|
||||
{
|
||||
public interface IGoogleApiService
|
||||
public interface IGoogleApiService : INService
|
||||
{
|
||||
IEnumerable<string> Languages { get; }
|
||||
|
||||
|
@ -3,7 +3,7 @@ using System.Collections.Immutable;
|
||||
|
||||
namespace NadekoBot.Services
|
||||
{
|
||||
public interface IImagesService
|
||||
public interface IImagesService : INService
|
||||
{
|
||||
ImmutableArray<byte> Heads { 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
|
||||
{
|
||||
public interface IStatsService
|
||||
public interface IStatsService : INService
|
||||
{
|
||||
string Author { get; }
|
||||
long CommandsRan { get; }
|
||||
|
@ -11,7 +11,7 @@ using System.Text.RegularExpressions;
|
||||
|
||||
namespace NadekoBot.Services
|
||||
{
|
||||
public class NadekoStrings
|
||||
public class NadekoStrings : INService
|
||||
{
|
||||
public const string stringsPath = @"_strings/";
|
||||
|
||||
|
@ -6,7 +6,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace NadekoBot.Services.Impl
|
||||
{
|
||||
public class SoundCloudApiService
|
||||
public class SoundCloudApiService : INService
|
||||
{
|
||||
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
|
||||
{
|
||||
public class MusicService
|
||||
public class MusicService : INService
|
||||
{
|
||||
public const string MusicDataPath = "data/musicdata";
|
||||
|
||||
|
@ -7,7 +7,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace NadekoBot.Services.Permissions
|
||||
{
|
||||
public class BlacklistService : IEarlyBlocker
|
||||
public class BlacklistService : IEarlyBlocker, INService
|
||||
{
|
||||
public ConcurrentHashSet<ulong> BlacklistedUsers { get; }
|
||||
public ConcurrentHashSet<ulong> BlacklistedGuilds { get; }
|
||||
|
@ -9,7 +9,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace NadekoBot.Services.Permissions
|
||||
{
|
||||
public class CmdCdService : ILateBlocker
|
||||
public class CmdCdService : ILateBlocker, INService
|
||||
{
|
||||
public ConcurrentDictionary<ulong, ConcurrentHashSet<CommandCooldown>> CommandCooldowns { get; }
|
||||
public ConcurrentDictionary<ulong, ConcurrentHashSet<ActiveCooldown>> ActiveCooldowns { get; } = new ConcurrentDictionary<ulong, ConcurrentHashSet<ActiveCooldown>>();
|
||||
|
@ -12,7 +12,7 @@ using NLog;
|
||||
|
||||
namespace NadekoBot.Services.Permissions
|
||||
{
|
||||
public class FilterService : IEarlyBlocker
|
||||
public class FilterService : IEarlyBlocker, INService
|
||||
{
|
||||
private readonly Logger _log;
|
||||
|
||||
|
@ -8,7 +8,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace NadekoBot.Services.Permissions
|
||||
{
|
||||
public class GlobalPermissionService : ILateBlocker
|
||||
public class GlobalPermissionService : ILateBlocker, INService
|
||||
{
|
||||
public readonly ConcurrentHashSet<string> BlockedModules;
|
||||
public readonly ConcurrentHashSet<string> BlockedCommands;
|
||||
|
@ -11,14 +11,14 @@ using System.Threading.Tasks;
|
||||
using Discord;
|
||||
using Discord.WebSocket;
|
||||
using NadekoBot.Extensions;
|
||||
using NadekoBot.Services.Database;
|
||||
using NadekoBot.Services;
|
||||
|
||||
namespace NadekoBot.Services.Permissions
|
||||
{
|
||||
public class PermissionService : ILateBlocker
|
||||
public class PermissionService : ILateBlocker, INService
|
||||
{
|
||||
private readonly DbService _db;
|
||||
private readonly Logger _log;
|
||||
private readonly CommandHandler _cmd;
|
||||
private readonly NadekoStrings _strings;
|
||||
|
||||
@ -26,16 +26,15 @@ namespace NadekoBot.Services.Permissions
|
||||
public ConcurrentDictionary<ulong, PermissionCache> Cache { get; } =
|
||||
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;
|
||||
_cmd = cmd;
|
||||
_strings = strings;
|
||||
|
||||
var sw = Stopwatch.StartNew();
|
||||
if (client.ShardId == 0)
|
||||
TryMigratePermissions(bc);
|
||||
TryMigratePermissions();
|
||||
|
||||
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)
|
||||
@ -71,12 +67,13 @@ namespace NadekoBot.Services.Permissions
|
||||
return pc;
|
||||
}
|
||||
|
||||
private void TryMigratePermissions(BotConfig bc)
|
||||
{
|
||||
var log = LogManager.GetCurrentClassLogger();
|
||||
if (bc.PermissionVersion <= 1)
|
||||
private void TryMigratePermissions()
|
||||
{
|
||||
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.");
|
||||
var oldCache = new ConcurrentDictionary<ulong, OldPermissionCache>(uow.GuildConfigs
|
||||
@ -134,10 +131,7 @@ namespace NadekoBot.Services.Permissions
|
||||
bc.PermissionVersion = 2;
|
||||
uow.Complete();
|
||||
}
|
||||
}
|
||||
if (bc.PermissionVersion <= 2)
|
||||
{
|
||||
using (var uow = _db.UnitOfWork)
|
||||
{
|
||||
var oldPrefixes = new[] { ".", ";", "!!", "!m", "!", "+", "-", "$", ">" };
|
||||
uow._context.Database.ExecuteSqlCommand(
|
||||
|
@ -6,7 +6,7 @@ using System.IO;
|
||||
|
||||
namespace NadekoBot.Services.Pokemon
|
||||
{
|
||||
public class PokemonService
|
||||
public class PokemonService : INService
|
||||
{
|
||||
public readonly List<PokemonType> PokemonTypes = new List<PokemonType>();
|
||||
public readonly ConcurrentDictionary<ulong, PokeStats> Stats = new ConcurrentDictionary<ulong, PokeStats>();
|
||||
|
@ -6,7 +6,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace NadekoBot.Services.Searches
|
||||
{
|
||||
public class AnimeSearchService
|
||||
public class AnimeSearchService : INService
|
||||
{
|
||||
private readonly Logger _log;
|
||||
|
||||
|
@ -15,7 +15,7 @@ using System.Xml;
|
||||
|
||||
namespace NadekoBot.Services.Searches
|
||||
{
|
||||
public class SearchesService
|
||||
public class SearchesService : INService
|
||||
{
|
||||
private readonly DiscordSocketClient _client;
|
||||
private readonly IGoogleApiService _google;
|
||||
|
@ -15,7 +15,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace NadekoBot.Services.Searches
|
||||
{
|
||||
public class StreamNotificationService
|
||||
public class StreamNotificationService : INService
|
||||
{
|
||||
private readonly Timer _streamCheckTimer;
|
||||
private bool firstStreamNotifPass { get; set; } = true;
|
||||
|
@ -3,6 +3,15 @@ using System.Collections;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
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
|
||||
{
|
||||
@ -16,8 +25,14 @@ namespace NadekoBot.Services
|
||||
public class ServiceProviderBuilder
|
||||
{
|
||||
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);
|
||||
return this;
|
||||
@ -27,6 +42,61 @@ namespace NadekoBot.Services
|
||||
{
|
||||
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;
|
||||
|
@ -10,7 +10,7 @@ using NadekoBot.Extensions;
|
||||
|
||||
namespace NadekoBot.Services.Utility
|
||||
{
|
||||
public class CommandMapService : IInputTransformer
|
||||
public class CommandMapService : IInputTransformer, INService
|
||||
{
|
||||
private readonly Logger _log;
|
||||
|
||||
|
@ -13,7 +13,7 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace NadekoBot.Services.Utility
|
||||
{
|
||||
public class ConverterService
|
||||
public class ConverterService : INService
|
||||
{
|
||||
public List<ConvertUnit> Units { get; } = new List<ConvertUnit>();
|
||||
private readonly Logger _log;
|
||||
|
@ -8,7 +8,7 @@ using System.Threading.Tasks;
|
||||
namespace NadekoBot.Services.Utility
|
||||
{
|
||||
//todo 50 rewrite
|
||||
public class MessageRepeaterService
|
||||
public class MessageRepeaterService : INService
|
||||
{
|
||||
//messagerepeater
|
||||
//guildid/RepeatRunners
|
||||
@ -19,8 +19,7 @@ namespace NadekoBot.Services.Utility
|
||||
{
|
||||
var _ = Task.Run(async () =>
|
||||
{
|
||||
while (!bot.Ready)
|
||||
await Task.Delay(1000);
|
||||
await bot.Ready.Task.ConfigureAwait(false);
|
||||
|
||||
Repeaters = new ConcurrentDictionary<ulong, ConcurrentQueue<RepeatRunner>>(gcs
|
||||
.ToDictionary(gc => gc.GuildId,
|
||||
|
@ -9,13 +9,12 @@ using System.Collections.Immutable;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NadekoBot.Services.Utility
|
||||
{
|
||||
public class PatreonRewardsService
|
||||
public class PatreonRewardsService : INService
|
||||
{
|
||||
private readonly SemaphoreSlim getPledgesLocker = new SemaphoreSlim(1, 1);
|
||||
|
||||
|
@ -4,9 +4,9 @@ using NadekoBot.DataStructures.Replacements;
|
||||
using NadekoBot.Extensions;
|
||||
using NadekoBot.Services.Database;
|
||||
using NadekoBot.Services.Database.Models;
|
||||
using NadekoBot.Services.Impl;
|
||||
using NLog;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
@ -14,7 +14,7 @@ using System.Threading.Tasks;
|
||||
|
||||
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)?$",
|
||||
RegexOptions.Compiled | RegexOptions.Multiline);
|
||||
@ -29,7 +29,7 @@ namespace NadekoBot.Services.Utility
|
||||
private readonly DbService _db;
|
||||
|
||||
public RemindService(DiscordSocketClient client, BotConfig config, DbService db,
|
||||
List<long> guilds, IUnitOfWork uow)
|
||||
StartingGuildsService guilds, IUnitOfWork uow)
|
||||
{
|
||||
_config = config;
|
||||
_client = client;
|
||||
|
@ -12,7 +12,7 @@ using NLog;
|
||||
|
||||
namespace NadekoBot.Services.Utility
|
||||
{
|
||||
public class StreamRoleService
|
||||
public class StreamRoleService : INService
|
||||
{
|
||||
private readonly DbService _db;
|
||||
private readonly ConcurrentDictionary<ulong, StreamRoleSettings> guildSettings;
|
||||
@ -26,6 +26,7 @@ namespace NadekoBot.Services.Utility
|
||||
this._log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
guildSettings = gcs.ToDictionary(x => x.GuildId, x => x.StreamRole)
|
||||
.Where(x => x.Value.FromRoleId != 0 && x.Value.AddRoleId != 0)
|
||||
.ToConcurrent();
|
||||
|
||||
client.GuildMemberUpdated += Client_GuildMemberUpdated;
|
||||
|
@ -10,7 +10,7 @@ using System.Linq;
|
||||
|
||||
namespace NadekoBot.Services.Utility
|
||||
{
|
||||
public class VerboseErrorsService
|
||||
public class VerboseErrorsService : INService
|
||||
{
|
||||
private readonly ConcurrentHashSet<ulong> guildsEnabled;
|
||||
private readonly DbService _db;
|
||||
|
@ -3,7 +3,6 @@ using NadekoBot.Services;
|
||||
using NadekoBot.Services.Impl;
|
||||
using NLog;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
Loading…
Reference in New Issue
Block a user