mirror of
https://gitlab.com/Kwoth/nadekobot.git
synced 2025-09-11 17:58:26 -04:00
Medusa System Added
Read about the medusa system [here](https://nadekobot.readthedocs.io/en/latest/medusa/creating-a-medusa/)
This commit is contained in:
@@ -7,7 +7,7 @@ using System.Threading.Channels;
|
||||
|
||||
namespace NadekoBot.Modules.Administration.Services;
|
||||
|
||||
public sealed class ImageOnlyChannelService : IEarlyBehavior
|
||||
public sealed class ImageOnlyChannelService : IExecOnMessage
|
||||
{
|
||||
public int Priority { get; } = 0;
|
||||
private readonly IMemoryCache _ticketCache;
|
||||
@@ -93,7 +93,7 @@ public sealed class ImageOnlyChannelService : IEarlyBehavior
|
||||
return newState;
|
||||
}
|
||||
|
||||
public async Task<bool> RunBehavior(IGuild guild, IUserMessage msg)
|
||||
public async Task<bool> ExecOnMessageAsync(IGuild guild, IUserMessage msg)
|
||||
{
|
||||
if (msg.Channel is not ITextChannel tch)
|
||||
return false;
|
||||
|
@@ -5,7 +5,7 @@ using NadekoBot.Services.Database.Models;
|
||||
|
||||
namespace NadekoBot.Modules.Administration.Services;
|
||||
|
||||
public class DiscordPermOverrideService : INService, ILateBlocker
|
||||
public class DiscordPermOverrideService : INService, IExecPreCommand
|
||||
{
|
||||
public int Priority { get; } = int.MaxValue;
|
||||
private readonly DbService _db;
|
||||
@@ -118,7 +118,7 @@ public class DiscordPermOverrideService : INService, ILateBlocker
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<bool> TryBlockLate(ICommandContext context, string moduleName, CommandInfo command)
|
||||
public async Task<bool> ExecPreCommandAsync(ICommandContext context, string moduleName, CommandInfo command)
|
||||
{
|
||||
if (TryGetOverrides(context.Guild?.Id ?? 0, command.Name, out var perm) && perm is not null)
|
||||
{
|
||||
|
@@ -1,4 +1,5 @@
|
||||
#nullable disable
|
||||
using Nadeko.Medusa;
|
||||
using NadekoBot.Modules.Administration.Services;
|
||||
using NadekoBot.Services.Database.Models;
|
||||
|
||||
@@ -19,13 +20,19 @@ public partial class Administration
|
||||
|
||||
private readonly DiscordSocketClient _client;
|
||||
private readonly IBotStrings _strings;
|
||||
private readonly IMedusaLoaderService _medusaLoader;
|
||||
private readonly ICoordinator _coord;
|
||||
|
||||
public SelfCommands(DiscordSocketClient client, IBotStrings strings, ICoordinator coord)
|
||||
public SelfCommands(
|
||||
DiscordSocketClient client,
|
||||
IBotStrings strings,
|
||||
ICoordinator coord,
|
||||
IMedusaLoaderService medusaLoader)
|
||||
{
|
||||
_client = client;
|
||||
_strings = strings;
|
||||
_coord = coord;
|
||||
_medusaLoader = medusaLoader;
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
@@ -506,6 +513,7 @@ public partial class Administration
|
||||
public async partial Task StringsReload()
|
||||
{
|
||||
_strings.Reload();
|
||||
await _medusaLoader.ReloadStrings();
|
||||
await ReplyConfirmLocalizedAsync(strs.bot_strings_reloaded);
|
||||
}
|
||||
|
||||
|
@@ -6,7 +6,7 @@ using System.Collections.Immutable;
|
||||
|
||||
namespace NadekoBot.Modules.Administration.Services;
|
||||
|
||||
public sealed class SelfService : ILateExecutor, IReadyExecutor, INService
|
||||
public sealed class SelfService : IExecNoCommand, IReadyExecutor, INService
|
||||
{
|
||||
private readonly CommandHandler _cmdHandler;
|
||||
private readonly DbService _db;
|
||||
@@ -206,7 +206,7 @@ public sealed class SelfService : ILateExecutor, IReadyExecutor, INService
|
||||
=> _pubSub.Pub(_guildLeaveKey, guildStr);
|
||||
|
||||
// forwards dms
|
||||
public async Task LateExecute(IGuild guild, IUserMessage msg)
|
||||
public async Task ExecOnNoCommandAsync(IGuild guild, IUserMessage msg)
|
||||
{
|
||||
var bs = _bss.Data;
|
||||
if (msg.Channel is IDMChannel && bs.ForwardMessages && ownerChannels.Any())
|
||||
|
@@ -913,7 +913,7 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor
|
||||
var embed = _eb.Create()
|
||||
.WithOkColor()
|
||||
.WithTitle("♻️ " + GetText(logChannel.Guild, strs.user_unbanned))
|
||||
.WithDescription(usr.ToString())
|
||||
.WithDescription(usr.ToString()!)
|
||||
.AddField("Id", usr.Id.ToString())
|
||||
.WithFooter(CurrentTime(guild));
|
||||
|
||||
@@ -948,7 +948,7 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor
|
||||
var embed = _eb.Create()
|
||||
.WithOkColor()
|
||||
.WithTitle("🚫 " + GetText(logChannel.Guild, strs.user_banned))
|
||||
.WithDescription(usr.ToString())
|
||||
.WithDescription(usr.ToString()!)
|
||||
.AddField("Id", usr.Id.ToString())
|
||||
.WithFooter(CurrentTime(guild));
|
||||
|
||||
@@ -999,7 +999,7 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor
|
||||
.WithOkColor()
|
||||
.WithTitle("🗑 "
|
||||
+ GetText(logChannel.Guild, strs.msg_del(((ITextChannel)msg.Channel).Name)))
|
||||
.WithDescription(msg.Author.ToString())
|
||||
.WithDescription(msg.Author.ToString()!)
|
||||
.AddField(GetText(logChannel.Guild, strs.content),
|
||||
string.IsNullOrWhiteSpace(resolvedMessage) ? "-" : resolvedMessage)
|
||||
.AddField("Id", msg.Id.ToString())
|
||||
@@ -1060,7 +1060,7 @@ public sealed class LogCommandService : ILogCommandService, IReadyExecutor
|
||||
.WithTitle("📝 "
|
||||
+ GetText(logChannel.Guild,
|
||||
strs.msg_update(((ITextChannel)after.Channel).Name)))
|
||||
.WithDescription(after.Author.ToString())
|
||||
.WithDescription(after.Author.ToString()!)
|
||||
.AddField(GetText(logChannel.Guild, strs.old_msg),
|
||||
string.IsNullOrWhiteSpace(before.Content)
|
||||
? "-"
|
||||
|
@@ -577,7 +577,7 @@ public partial class Administration
|
||||
[BotPerm(GuildPerm.BanMembers)]
|
||||
public async partial Task Unban([Leftover] string user)
|
||||
{
|
||||
var bans = await ctx.Guild.GetBansAsync();
|
||||
var bans = await ctx.Guild.GetBansAsync().FlattenAsync();
|
||||
|
||||
var bun = bans.FirstOrDefault(x => x.User.ToString()!.ToLowerInvariant() == user.ToLowerInvariant());
|
||||
|
||||
@@ -596,9 +596,7 @@ public partial class Administration
|
||||
[BotPerm(GuildPerm.BanMembers)]
|
||||
public async partial Task Unban(ulong userId)
|
||||
{
|
||||
var bans = await ctx.Guild.GetBansAsync();
|
||||
|
||||
var bun = bans.FirstOrDefault(x => x.User.Id == userId);
|
||||
var bun = await ctx.Guild.GetBanAsync(userId);
|
||||
|
||||
if (bun is null)
|
||||
{
|
||||
|
@@ -12,7 +12,7 @@ using YamlDotNet.Serialization.NamingConventions;
|
||||
|
||||
namespace NadekoBot.Modules.NadekoExpressions;
|
||||
|
||||
public sealed class NadekoExpressionsService : IEarlyBehavior, IReadyExecutor
|
||||
public sealed class NadekoExpressionsService : IExecOnMessage, IReadyExecutor
|
||||
{
|
||||
private const string MENTION_PH = "%bot.mention%";
|
||||
|
||||
@@ -220,7 +220,7 @@ public sealed class NadekoExpressionsService : IEarlyBehavior, IReadyExecutor
|
||||
return result[_rng.Next(0, result.Count)];
|
||||
}
|
||||
|
||||
public async Task<bool> RunBehavior(IGuild guild, IUserMessage msg)
|
||||
public async Task<bool> ExecOnMessageAsync(IGuild guild, IUserMessage msg)
|
||||
{
|
||||
// maybe this message is an expression
|
||||
var expr = TryGetExpression(msg);
|
||||
|
@@ -93,7 +93,7 @@ public class GameStatusEvent : ICurrencyEvent
|
||||
});
|
||||
}
|
||||
|
||||
Log.Information("Awarded {Count} users {Amount} currency.{Remaining}",
|
||||
Log.Information("Game status event awarded {Count} users {Amount} currency.{Remaining}",
|
||||
toAward.Count,
|
||||
_amount,
|
||||
_isPotLimited ? $" {PotSize} left." : "");
|
||||
|
@@ -86,7 +86,7 @@ public class ReactionEvent : ICurrencyEvent
|
||||
});
|
||||
}
|
||||
|
||||
Log.Information("Awarded {Count} users {Amount} currency.{Remaining}",
|
||||
Log.Information("Reaction Event awarded {Count} users {Amount} currency.{Remaining}",
|
||||
toAward.Count,
|
||||
_amount,
|
||||
_isPotLimited ? $" {PotSize} left." : "");
|
||||
|
@@ -1,5 +1,6 @@
|
||||
#nullable disable
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using NadekoBot.Common.ModuleBehaviors;
|
||||
using NadekoBot.Db;
|
||||
using NadekoBot.Services.Database.Models;
|
||||
using SixLabors.Fonts;
|
||||
@@ -12,7 +13,7 @@ using Image = SixLabors.ImageSharp.Image;
|
||||
|
||||
namespace NadekoBot.Modules.Gambling.Services;
|
||||
|
||||
public class PlantPickService : INService
|
||||
public class PlantPickService : INService, IExecNoCommand
|
||||
{
|
||||
//channelId/last generation
|
||||
public ConcurrentDictionary<ulong, DateTime> LastGenerations { get; } = new();
|
||||
@@ -49,8 +50,7 @@ public class PlantPickService : INService
|
||||
_rng = new();
|
||||
_client = client;
|
||||
_gss = gss;
|
||||
|
||||
cmd.OnMessageNoTrigger += PotentialFlowerGeneration;
|
||||
|
||||
using var uow = db.GetDbContext();
|
||||
var guildIds = client.Guilds.Select(x => x.Id).ToList();
|
||||
var configs = uow.Set<GuildConfig>()
|
||||
@@ -62,6 +62,9 @@ public class PlantPickService : INService
|
||||
_generationChannels = new(configs.SelectMany(c => c.GenerateCurrencyChannelIds.Select(obj => obj.ChannelId)));
|
||||
}
|
||||
|
||||
public Task ExecOnNoCommandAsync(IGuild guild, IUserMessage msg)
|
||||
=> PotentialFlowerGeneration(msg);
|
||||
|
||||
private string GetText(ulong gid, LocStr str)
|
||||
=> _strings.GetText(str, gid);
|
||||
|
||||
|
@@ -6,7 +6,7 @@ using NadekoBot.Modules.Permissions.Services;
|
||||
|
||||
namespace NadekoBot.Modules.Games.Services;
|
||||
|
||||
public class ChatterBotService : IEarlyBehavior
|
||||
public class ChatterBotService : IExecOnMessage
|
||||
{
|
||||
public ConcurrentDictionary<ulong, Lazy<IChatterBotSession>> ChatterBotGuilds { get; }
|
||||
|
||||
@@ -95,7 +95,7 @@ public class ChatterBotService : IEarlyBehavior
|
||||
return true;
|
||||
}
|
||||
|
||||
public async Task<bool> RunBehavior(IGuild guild, IUserMessage usrMsg)
|
||||
public async Task<bool> ExecOnMessageAsync(IGuild guild, IUserMessage usrMsg)
|
||||
{
|
||||
if (guild is not SocketGuild sg)
|
||||
return false;
|
||||
|
@@ -5,7 +5,7 @@ using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace NadekoBot.Modules.Games.Hangman;
|
||||
|
||||
public sealed class HangmanService : IHangmanService, ILateExecutor
|
||||
public sealed class HangmanService : IHangmanService, IExecNoCommand
|
||||
{
|
||||
private readonly ConcurrentDictionary<ulong, HangmanGame> _hangmanGames = new();
|
||||
private readonly IHangmanSource _source;
|
||||
@@ -64,7 +64,7 @@ public sealed class HangmanService : IHangmanService, ILateExecutor
|
||||
public IReadOnlyCollection<string> GetHangmanTypes()
|
||||
=> _source.GetCategories();
|
||||
|
||||
public async Task LateExecute(IGuild guild, IUserMessage msg)
|
||||
public async Task ExecOnNoCommandAsync(IGuild guild, IUserMessage msg)
|
||||
{
|
||||
if (_hangmanGames.ContainsKey(msg.Channel.Id))
|
||||
{
|
||||
|
@@ -7,7 +7,7 @@ using NadekoBot.Services.Database.Models;
|
||||
|
||||
namespace NadekoBot.Modules.Games.Services;
|
||||
|
||||
public class PollService : IEarlyBehavior
|
||||
public class PollService : IExecOnMessage
|
||||
{
|
||||
public ConcurrentDictionary<ulong, PollRunner> ActivePolls { get; } = new();
|
||||
|
||||
@@ -103,7 +103,7 @@ public class PollService : IEarlyBehavior
|
||||
catch { }
|
||||
}
|
||||
|
||||
public async Task<bool> RunBehavior(IGuild guild, IUserMessage msg)
|
||||
public async Task<bool> ExecOnMessageAsync(IGuild guild, IUserMessage msg)
|
||||
{
|
||||
if (guild is null)
|
||||
return false;
|
||||
|
@@ -1,5 +1,6 @@
|
||||
#nullable disable
|
||||
using Amazon.S3;
|
||||
using Nadeko.Medusa;
|
||||
using NadekoBot.Modules.Help.Common;
|
||||
using NadekoBot.Modules.Help.Services;
|
||||
using NadekoBot.Modules.Permissions.Services;
|
||||
@@ -23,6 +24,7 @@ public partial class Help : NadekoModule<HelpService>
|
||||
private readonly IBotStrings _strings;
|
||||
|
||||
private readonly AsyncLazy<ulong> _lazyClientId;
|
||||
private readonly IMedusaLoaderService _medusae;
|
||||
|
||||
public Help(
|
||||
GlobalPermissionService perms,
|
||||
@@ -30,7 +32,8 @@ public partial class Help : NadekoModule<HelpService>
|
||||
BotConfigService bss,
|
||||
IServiceProvider services,
|
||||
DiscordSocketClient client,
|
||||
IBotStrings strings)
|
||||
IBotStrings strings,
|
||||
IMedusaLoaderService medusae)
|
||||
{
|
||||
_cmds = cmds;
|
||||
_bss = bss;
|
||||
@@ -38,6 +41,7 @@ public partial class Help : NadekoModule<HelpService>
|
||||
_services = services;
|
||||
_client = client;
|
||||
_strings = strings;
|
||||
_medusae = medusae;
|
||||
|
||||
_lazyClientId = new(async () => (await _client.GetApplicationInfoAsync()).Id);
|
||||
}
|
||||
@@ -329,8 +333,8 @@ public partial class Help : NadekoModule<HelpService>
|
||||
return new CommandJsonObject
|
||||
{
|
||||
Aliases = com.Aliases.Select(alias => prefix + alias).ToArray(),
|
||||
Description = com.RealSummary(_strings, ctx.Guild?.Id, prefix),
|
||||
Usage = com.RealRemarksArr(_strings, ctx.Guild?.Id, prefix),
|
||||
Description = com.RealSummary(_strings, _medusae, Culture, prefix),
|
||||
Usage = com.RealRemarksArr(_strings, _medusae, Culture, prefix),
|
||||
Submodule = com.Module.Name,
|
||||
Module = com.Module.GetTopLevelModule().Name,
|
||||
Options = optHelpStr,
|
||||
|
@@ -1,33 +1,40 @@
|
||||
#nullable disable
|
||||
using CommandLine;
|
||||
using Nadeko.Medusa;
|
||||
using NadekoBot.Common.ModuleBehaviors;
|
||||
using NadekoBot.Modules.Administration.Services;
|
||||
|
||||
namespace NadekoBot.Modules.Help.Services;
|
||||
|
||||
public class HelpService : ILateExecutor, INService
|
||||
public class HelpService : IExecNoCommand, INService
|
||||
{
|
||||
private readonly CommandHandler _ch;
|
||||
private readonly IBotStrings _strings;
|
||||
private readonly DiscordPermOverrideService _dpos;
|
||||
private readonly BotConfigService _bss;
|
||||
private readonly IEmbedBuilderService _eb;
|
||||
private readonly ILocalization _loc;
|
||||
private readonly IMedusaLoaderService _medusae;
|
||||
|
||||
public HelpService(
|
||||
CommandHandler ch,
|
||||
IBotStrings strings,
|
||||
DiscordPermOverrideService dpos,
|
||||
BotConfigService bss,
|
||||
IEmbedBuilderService eb)
|
||||
IEmbedBuilderService eb,
|
||||
ILocalization loc,
|
||||
IMedusaLoaderService medusae)
|
||||
{
|
||||
_ch = ch;
|
||||
_strings = strings;
|
||||
_dpos = dpos;
|
||||
_bss = bss;
|
||||
_eb = eb;
|
||||
_loc = loc;
|
||||
_medusae = medusae;
|
||||
}
|
||||
|
||||
public Task LateExecute(IGuild guild, IUserMessage msg)
|
||||
public Task ExecOnNoCommandAsync(IGuild guild, IUserMessage msg)
|
||||
{
|
||||
var settings = _bss.Data;
|
||||
if (guild is null)
|
||||
@@ -57,13 +64,16 @@ public class HelpService : ILateExecutor, INService
|
||||
public IEmbedBuilder GetCommandHelp(CommandInfo com, IGuild guild)
|
||||
{
|
||||
var prefix = _ch.GetPrefix(guild);
|
||||
|
||||
|
||||
var str = $"**`{prefix + com.Aliases.First()}`**";
|
||||
var alias = com.Aliases.Skip(1).FirstOrDefault();
|
||||
if (alias is not null)
|
||||
str += $" **/ `{prefix + alias}`**";
|
||||
|
||||
var em = _eb.Create().AddField(str, $"{com.RealSummary(_strings, guild?.Id, prefix)}", true);
|
||||
var culture = _loc.GetCultureInfo(guild);
|
||||
|
||||
var em = _eb.Create()
|
||||
.AddField(str, $"{com.RealSummary(_strings, _medusae, culture, prefix)}", true);
|
||||
|
||||
_dpos.TryGetOverrides(guild?.Id ?? 0, com.Name, out var overrides);
|
||||
var reqs = GetCommandRequirements(com, overrides);
|
||||
@@ -72,7 +82,7 @@ public class HelpService : ILateExecutor, INService
|
||||
|
||||
em.AddField(_strings.GetText(strs.usage),
|
||||
string.Join("\n",
|
||||
Array.ConvertAll(com.RealRemarksArr(_strings, guild?.Id, prefix), arg => Format.Code(arg))))
|
||||
Array.ConvertAll(com.RealRemarksArr(_strings,_medusae, culture, prefix), arg => Format.Code(arg))))
|
||||
.WithFooter(GetText(strs.module(com.Module.GetTopLevelModule().Name), guild))
|
||||
.WithOkColor();
|
||||
|
||||
|
200
src/NadekoBot/Modules/Medusae/Medusa.cs
Normal file
200
src/NadekoBot/Modules/Medusae/Medusa.cs
Normal file
@@ -0,0 +1,200 @@
|
||||
using Nadeko.Medusa;
|
||||
|
||||
namespace NadekoBot.Modules;
|
||||
|
||||
[OwnerOnly]
|
||||
public partial class Medusa : NadekoModule<IMedusaLoaderService>
|
||||
{
|
||||
[Cmd]
|
||||
[OwnerOnly]
|
||||
public async partial Task MedusaLoad(string? name = null)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(name))
|
||||
{
|
||||
var loaded = _service.GetLoadedMedusae()
|
||||
.Select(x => x.Name)
|
||||
.ToHashSet();
|
||||
|
||||
var unloaded = _service.GetAllMedusae()
|
||||
.Where(x => !loaded.Contains(x))
|
||||
.Select(x => Format.Code(x.ToString()))
|
||||
.ToArray();
|
||||
|
||||
if (unloaded.Length == 0)
|
||||
{
|
||||
await ReplyPendingLocalizedAsync(strs.no_medusa_available);
|
||||
return;
|
||||
}
|
||||
|
||||
await ctx.SendPaginatedConfirmAsync(0,
|
||||
page =>
|
||||
{
|
||||
return _eb.Create(ctx)
|
||||
.WithOkColor()
|
||||
.WithTitle(GetText(strs.list_of_unloaded))
|
||||
.WithDescription(unloaded.Skip(10 * page).Take(10).Join('\n'));
|
||||
},
|
||||
unloaded.Length,
|
||||
10);
|
||||
return;
|
||||
}
|
||||
|
||||
var res = await _service.LoadMedusaAsync(name);
|
||||
if (res == MedusaLoadResult.Success)
|
||||
await ReplyConfirmLocalizedAsync(strs.medusa_loaded(Format.Code(name)));
|
||||
else
|
||||
{
|
||||
var locStr = res switch
|
||||
{
|
||||
MedusaLoadResult.Empty => strs.medusa_empty,
|
||||
MedusaLoadResult.AlreadyLoaded => strs.medusa_already_loaded(Format.Code(name)),
|
||||
MedusaLoadResult.NotFound => strs.medusa_invalid_not_found,
|
||||
MedusaLoadResult.UnknownError => strs.error_occured,
|
||||
_ => strs.error_occured
|
||||
};
|
||||
|
||||
await ReplyErrorLocalizedAsync(locStr);
|
||||
}
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
[OwnerOnly]
|
||||
public async partial Task MedusaUnload(string? name = null)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(name))
|
||||
{
|
||||
var loaded = _service.GetLoadedMedusae();
|
||||
if (loaded.Count == 0)
|
||||
{
|
||||
await ReplyPendingLocalizedAsync(strs.no_medusa_loaded);
|
||||
return;
|
||||
}
|
||||
|
||||
await ctx.Channel.EmbedAsync(_eb.Create(ctx)
|
||||
.WithOkColor()
|
||||
.WithTitle(GetText(strs.loaded_medusae))
|
||||
.WithDescription(loaded.Select(x => x.Name)
|
||||
.Join("\n")));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var res = await _service.UnloadMedusaAsync(name);
|
||||
if (res == MedusaUnloadResult.Success)
|
||||
await ReplyConfirmLocalizedAsync(strs.medusa_unloaded(Format.Code(name)));
|
||||
else
|
||||
{
|
||||
var locStr = res switch
|
||||
{
|
||||
MedusaUnloadResult.NotLoaded => strs.medusa_not_loaded,
|
||||
MedusaUnloadResult.PossiblyUnable => strs.medusa_possibly_cant_unload,
|
||||
_ => strs.error_occured
|
||||
};
|
||||
|
||||
await ReplyErrorLocalizedAsync(locStr);
|
||||
}
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
[OwnerOnly]
|
||||
public async partial Task MedusaList()
|
||||
{
|
||||
var all = _service.GetAllMedusae();
|
||||
|
||||
if (all.Count == 0)
|
||||
{
|
||||
await ReplyPendingLocalizedAsync(strs.no_medusa_available);
|
||||
return;
|
||||
}
|
||||
|
||||
var loaded = _service.GetLoadedMedusae()
|
||||
.Select(x => x.Name)
|
||||
.ToHashSet();
|
||||
|
||||
var output = all
|
||||
.Select(m =>
|
||||
{
|
||||
var emoji = loaded.Contains(m) ? "`✅`" : "`🔴`";
|
||||
return $"{emoji} `{m}`";
|
||||
})
|
||||
.ToArray();
|
||||
|
||||
|
||||
await ctx.SendPaginatedConfirmAsync(0,
|
||||
page => _eb.Create(ctx)
|
||||
.WithOkColor()
|
||||
.WithTitle(GetText(strs.list_of_medusae))
|
||||
.WithDescription(output.Skip(page * 10).Take(10).Join('\n')),
|
||||
output.Length,
|
||||
10);
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
[OwnerOnly]
|
||||
public async partial Task MedusaInfo(string? name = null)
|
||||
{
|
||||
var medusae = _service.GetLoadedMedusae();
|
||||
|
||||
if (name is not null)
|
||||
{
|
||||
var found = medusae.FirstOrDefault(x => string.Equals(x.Name,
|
||||
name,
|
||||
StringComparison.InvariantCultureIgnoreCase));
|
||||
|
||||
if (found is null)
|
||||
{
|
||||
await ReplyErrorLocalizedAsync(strs.medusa_name_not_found);
|
||||
return;
|
||||
}
|
||||
|
||||
var cmdCount = found.Sneks.Sum(x => x.Commands.Count);
|
||||
var cmdNames = found.Sneks
|
||||
.SelectMany(x => x.Commands)
|
||||
.Select(x => Format.Code(x.Name))
|
||||
.Join(" | ");
|
||||
|
||||
var eb = _eb.Create(ctx)
|
||||
.WithOkColor()
|
||||
.WithAuthor(GetText(strs.medusa_info))
|
||||
.WithTitle(found.Name)
|
||||
.WithDescription(found.Description)
|
||||
.AddField(GetText(strs.sneks_count(found.Sneks.Count)),
|
||||
found.Sneks.Count == 0
|
||||
? "-"
|
||||
: found.Sneks.Select(x => x.Name).Join('\n'),
|
||||
true)
|
||||
.AddField(GetText(strs.commands_count(cmdCount)),
|
||||
string.IsNullOrWhiteSpace(cmdNames)
|
||||
? "-"
|
||||
: cmdNames,
|
||||
true);
|
||||
|
||||
await ctx.Channel.EmbedAsync(eb);
|
||||
return;
|
||||
}
|
||||
|
||||
if (medusae.Count == 0)
|
||||
{
|
||||
await ReplyPendingLocalizedAsync(strs.no_medusa_loaded);
|
||||
return;
|
||||
}
|
||||
|
||||
await ctx.SendPaginatedConfirmAsync(0,
|
||||
page =>
|
||||
{
|
||||
var eb = _eb.Create(ctx)
|
||||
.WithOkColor();
|
||||
|
||||
foreach (var medusa in medusae.Skip(page * 9).Take(9))
|
||||
{
|
||||
eb.AddField(medusa.Name,
|
||||
$@"`Sneks:` {medusa.Sneks.Count}
|
||||
`Commands:` {medusa.Sneks.Sum(x => x.Commands.Count)}
|
||||
--
|
||||
{medusa.Description}");
|
||||
}
|
||||
|
||||
return eb;
|
||||
}, medusae.Count, 9);
|
||||
}
|
||||
}
|
@@ -6,7 +6,7 @@ using NadekoBot.Services.Database.Models;
|
||||
|
||||
namespace NadekoBot.Modules.Permissions.Services;
|
||||
|
||||
public sealed class BlacklistService : IEarlyBehavior
|
||||
public sealed class BlacklistService : IExecOnMessage
|
||||
{
|
||||
public int Priority
|
||||
=> int.MaxValue;
|
||||
@@ -34,7 +34,7 @@ public sealed class BlacklistService : IEarlyBehavior
|
||||
return default;
|
||||
}
|
||||
|
||||
public Task<bool> RunBehavior(IGuild guild, IUserMessage usrMsg)
|
||||
public Task<bool> ExecOnMessageAsync(IGuild guild, IUserMessage usrMsg)
|
||||
{
|
||||
foreach (var bl in blacklist)
|
||||
{
|
||||
|
@@ -4,7 +4,7 @@ using NadekoBot.Services.Database.Models;
|
||||
|
||||
namespace NadekoBot.Modules.Permissions.Services;
|
||||
|
||||
public class CmdCdService : ILateBlocker, INService
|
||||
public class CmdCdService : IExecPreCommand, INService
|
||||
{
|
||||
public ConcurrentDictionary<ulong, ConcurrentHashSet<CommandCooldown>> CommandCooldowns { get; }
|
||||
public ConcurrentDictionary<ulong, ConcurrentHashSet<ActiveCooldown>> ActiveCooldowns { get; } = new();
|
||||
@@ -51,7 +51,7 @@ public class CmdCdService : ILateBlocker, INService
|
||||
return Task.FromResult(false);
|
||||
}
|
||||
|
||||
public Task<bool> TryBlockLate(ICommandContext ctx, string moduleName, CommandInfo command)
|
||||
public Task<bool> ExecPreCommandAsync(ICommandContext ctx, string moduleName, CommandInfo command)
|
||||
{
|
||||
var guild = ctx.Guild;
|
||||
var user = ctx.User;
|
||||
|
@@ -6,7 +6,7 @@ using NadekoBot.Services.Database.Models;
|
||||
|
||||
namespace NadekoBot.Modules.Permissions.Services;
|
||||
|
||||
public sealed class FilterService : IEarlyBehavior
|
||||
public sealed class FilterService : IExecOnMessage
|
||||
{
|
||||
public ConcurrentHashSet<ulong> InviteFilteringChannels { get; }
|
||||
public ConcurrentHashSet<ulong> InviteFilteringServers { get; }
|
||||
@@ -69,7 +69,7 @@ public sealed class FilterService : IEarlyBehavior
|
||||
if (guild is null || newMsg is not IUserMessage usrMsg)
|
||||
return Task.CompletedTask;
|
||||
|
||||
return RunBehavior(guild, usrMsg);
|
||||
return ExecOnMessageAsync(guild, usrMsg);
|
||||
});
|
||||
return Task.CompletedTask;
|
||||
};
|
||||
@@ -110,7 +110,7 @@ public sealed class FilterService : IEarlyBehavior
|
||||
return words;
|
||||
}
|
||||
|
||||
public async Task<bool> RunBehavior(IGuild guild, IUserMessage msg)
|
||||
public async Task<bool> ExecOnMessageAsync(IGuild guild, IUserMessage msg)
|
||||
{
|
||||
if (msg.Author is not IGuildUser gu || gu.GuildPermissions.Administrator)
|
||||
return false;
|
||||
|
@@ -3,7 +3,7 @@ using NadekoBot.Common.ModuleBehaviors;
|
||||
|
||||
namespace NadekoBot.Modules.Permissions.Services;
|
||||
|
||||
public class GlobalPermissionService : ILateBlocker, INService
|
||||
public class GlobalPermissionService : IExecPreCommand, INService
|
||||
{
|
||||
public int Priority { get; } = 0;
|
||||
|
||||
@@ -19,7 +19,7 @@ public class GlobalPermissionService : ILateBlocker, INService
|
||||
=> _bss = bss;
|
||||
|
||||
|
||||
public Task<bool> TryBlockLate(ICommandContext ctx, string moduleName, CommandInfo command)
|
||||
public Task<bool> ExecPreCommandAsync(ICommandContext ctx, string moduleName, CommandInfo command)
|
||||
{
|
||||
var settings = _bss.Data;
|
||||
var commandName = command.Name.ToLowerInvariant();
|
||||
|
@@ -7,7 +7,7 @@ using NadekoBot.Services.Database.Models;
|
||||
|
||||
namespace NadekoBot.Modules.Permissions.Services;
|
||||
|
||||
public class PermissionService : ILateBlocker, INService
|
||||
public class PermissionService : IExecPreCommand, INService
|
||||
{
|
||||
public int Priority { get; } = 0;
|
||||
|
||||
@@ -94,7 +94,7 @@ public class PermissionService : ILateBlocker, INService
|
||||
return old;
|
||||
});
|
||||
|
||||
public async Task<bool> TryBlockLate(ICommandContext ctx, string moduleName, CommandInfo command)
|
||||
public async Task<bool> ExecPreCommandAsync(ICommandContext ctx, string moduleName, CommandInfo command)
|
||||
{
|
||||
var guild = ctx.Guild;
|
||||
var msg = ctx.Message;
|
||||
|
@@ -8,7 +8,7 @@ using System.Net;
|
||||
|
||||
namespace NadekoBot.Modules.Searches;
|
||||
|
||||
public sealed class TranslateService : ITranslateService, ILateExecutor, IReadyExecutor, INService
|
||||
public sealed class TranslateService : ITranslateService, IExecNoCommand, IReadyExecutor, INService
|
||||
{
|
||||
private readonly IGoogleApiService _google;
|
||||
private readonly DbService _db;
|
||||
@@ -50,7 +50,7 @@ public sealed class TranslateService : ITranslateService, ILateExecutor, IReadyE
|
||||
}
|
||||
|
||||
|
||||
public async Task LateExecute(IGuild guild, IUserMessage msg)
|
||||
public async Task ExecOnNoCommandAsync(IGuild guild, IUserMessage msg)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(msg.Content))
|
||||
return;
|
||||
|
@@ -52,7 +52,7 @@ public class CommandMapService : IInputTransformer, INService
|
||||
string input)
|
||||
{
|
||||
if (guild is null || string.IsNullOrWhiteSpace(input))
|
||||
return input;
|
||||
return null;
|
||||
|
||||
if (AliasMaps.TryGetValue(guild.Id, out var maps))
|
||||
{
|
||||
@@ -86,6 +86,6 @@ public class CommandMapService : IInputTransformer, INService
|
||||
}
|
||||
}
|
||||
|
||||
return input;
|
||||
return null;
|
||||
}
|
||||
}
|
@@ -8,7 +8,7 @@ public partial class Utility
|
||||
private readonly IEnumerable<IConfigService> _settingServices;
|
||||
|
||||
public ConfigCommands(IEnumerable<IConfigService> settingServices)
|
||||
=> _settingServices = settingServices;
|
||||
=> _settingServices = settingServices.Where(x => x.Name != "medusa");
|
||||
|
||||
[Cmd]
|
||||
[OwnerOnly]
|
||||
|
@@ -18,7 +18,7 @@ using Image = SixLabors.ImageSharp.Image;
|
||||
namespace NadekoBot.Modules.Xp.Services;
|
||||
|
||||
// todo improve xp with linqtodb
|
||||
public class XpService : INService, IReadyExecutor
|
||||
public class XpService : INService, IReadyExecutor, IExecNoCommand
|
||||
{
|
||||
public const int XP_REQUIRED_LVL_1 = 36;
|
||||
|
||||
@@ -109,8 +109,6 @@ public class XpService : INService, IReadyExecutor
|
||||
|
||||
_excludedServers = new(allGuildConfigs.Where(x => x.XpSettings.ServerExcluded).Select(x => x.GuildId));
|
||||
|
||||
_cmd.OnMessageNoTrigger += Cmd_OnMessageNoTrigger;
|
||||
|
||||
#if !GLOBAL_NADEKO
|
||||
_client.UserVoiceStateUpdated += Client_OnUserVoiceStateUpdated;
|
||||
|
||||
@@ -552,7 +550,7 @@ public class XpService : INService, IReadyExecutor
|
||||
return true;
|
||||
}
|
||||
|
||||
private Task Cmd_OnMessageNoTrigger(IUserMessage arg)
|
||||
public Task ExecOnNoCommandAsync(IGuild guild, IUserMessage arg)
|
||||
{
|
||||
if (arg.Author is not SocketGuildUser user || user.IsBot)
|
||||
return Task.CompletedTask;
|
||||
|
Reference in New Issue
Block a user