.cmds <module name> looks better

This commit is contained in:
Kwoth
2024-04-24 23:34:30 +00:00
parent a04a427af2
commit 006fa1a9fe
5 changed files with 184 additions and 197 deletions

View File

@@ -16,7 +16,12 @@ Experimental changelog. Mostly based on [keepachangelog](https://keepachangelog.
- `.ga list` lists active giveaways on the current server - `.ga list` lists active giveaways on the current server
- `.ga reroll <id>` rerolls the winner on the completed giveaway. This only works for 24 hours after the giveaway has ended, or until the bot restarts. - `.ga reroll <id>` rerolls the winner on the completed giveaway. This only works for 24 hours after the giveaway has ended, or until the bot restarts.
- After the giveaway has started, user join the giveaway by adding a :tada: reaction - After the giveaway has started, user join the giveaway by adding a :tada: reaction
### Changed
- Users who have manage messages perm in the channel will now be excluded from link and invite filtering (`.sfi` and `.sfl`)
- You can now target a different channel with .repeat, for example `.repeat #some-other 1h Hello every hour` - You can now target a different channel with .repeat, for example `.repeat #some-other 1h Hello every hour`
- `.cmds <module name>` looks better / simpler
## [4.3.22] - 23.04.2023 ## [4.3.22] - 23.04.2023

View File

@@ -279,25 +279,17 @@ public sealed class Help : NadekoModule<HelpService>
if (opts.View == CommandsOptions.ViewType.Cross) if (opts.View == CommandsOptions.ViewType.Cross)
{ {
return return
$"{(succ.Contains(x) ? "" : "")}{prefix + x.Aliases.First(),-15} {"[" + x.Aliases.Skip(1).FirstOrDefault() + "]",-8}"; $"{(succ.Contains(x) ? "" : "")} {prefix + x.Aliases[0]}";
} }
return if (x.Aliases.Count == 1)
$"{prefix + x.Aliases.First(),-15} {"[" + x.Aliases.Skip(1).FirstOrDefault() + "]",-8}"; return prefix + x.Aliases[0];
return prefix + x.Aliases[0] + " / " + prefix + x.Aliases[1];
}); });
if (i == last - 1 && (i + 1) % 2 != 0) embed.AddField(g.ElementAt(i).Key, "" + string.Join("\n", transformed) + "", true);
{
transformed = transformed.Chunk(2)
.Select(x =>
{
if (x.Count() == 1)
return $"{x.First()}";
return string.Concat(x);
});
}
embed.AddField(g.ElementAt(i).Key, "```css\n" + string.Join("\n", transformed) + "\n```", true);
} }
} }

View File

@@ -5,6 +5,8 @@ using System.Diagnostics;
using System.Text; using System.Text;
using System.Text.Json; using System.Text.Json;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
using Microsoft.CodeAnalysis.CSharp.Scripting;
using Microsoft.CodeAnalysis.Scripting;
using NadekoBot.Modules.Searches.Common; using NadekoBot.Modules.Searches.Common;
namespace NadekoBot.Modules.Utility; namespace NadekoBot.Modules.Utility;
@@ -17,7 +19,11 @@ public partial class Utility : NadekoModule
New New
} }
public enum MeOrBot { Me, Bot } public enum MeOrBot
{
Me,
Bot
}
private static readonly JsonSerializerOptions _showEmbedSerializerOptions = new() private static readonly JsonSerializerOptions _showEmbedSerializerOptions = new()
{ {
@@ -34,6 +40,7 @@ public partial class Utility : NadekoModule
private readonly DownloadTracker _tracker; private readonly DownloadTracker _tracker;
private readonly IHttpClientFactory _httpFactory; private readonly IHttpClientFactory _httpFactory;
private readonly VerboseErrorsService _veService; private readonly VerboseErrorsService _veService;
private readonly IServiceProvider _services;
public Utility( public Utility(
DiscordSocketClient client, DiscordSocketClient client,
@@ -42,7 +49,8 @@ public partial class Utility : NadekoModule
IBotCredentials creds, IBotCredentials creds,
DownloadTracker tracker, DownloadTracker tracker,
IHttpClientFactory httpFactory, IHttpClientFactory httpFactory,
VerboseErrorsService veService) VerboseErrorsService veService,
IServiceProvider services)
{ {
_client = client; _client = client;
_coord = coord; _coord = coord;
@@ -51,6 +59,7 @@ public partial class Utility : NadekoModule
_tracker = tracker; _tracker = tracker;
_httpFactory = httpFactory; _httpFactory = httpFactory;
_veService = veService; _veService = veService;
_services = services;
} }
[Cmd] [Cmd]
@@ -92,12 +101,12 @@ public partial class Utility : NadekoModule
var rng = new NadekoRandom(); var rng = new NadekoRandom();
var arr = await Task.Run(() => socketGuild.Users var arr = await Task.Run(() => socketGuild.Users
.Where(u => u.Activities.FirstOrDefault()?.Name?.Trim().ToUpperInvariant() .Where(u => u.Activities.FirstOrDefault()?.Name?.Trim().ToUpperInvariant()
== game) == game)
.Select(u => u.Username) .Select(u => u.Username)
.OrderBy(_ => rng.Next()) .OrderBy(_ => rng.Next())
.Take(60) .Take(60)
.ToArray()); .ToArray());
var i = 0; var i = 0;
if (arr.Length == 0) if (arr.Length == 0)
@@ -107,7 +116,7 @@ public partial class Utility : NadekoModule
await SendConfirmAsync("```css\n" await SendConfirmAsync("```css\n"
+ string.Join("\n", + string.Join("\n",
arr.GroupBy(_ => i++ / 2) arr.GroupBy(_ => i++ / 2)
.Select(ig => string.Concat(ig.Select(el => $"• {el,-27}")))) .Select(ig => string.Concat(ig.Select(el => $"• {el,-27}"))))
+ "\n```"); + "\n```");
} }
} }
@@ -128,8 +137,8 @@ public partial class Utility : NadekoModule
); );
var roleUsers = users.Where(u => role is null ? u.RoleIds.Count == 1 : u.RoleIds.Contains(role.Id)) var roleUsers = users.Where(u => role is null ? u.RoleIds.Count == 1 : u.RoleIds.Contains(role.Id))
.Select(u => $"`{u.Id,18}` {u}") .Select(u => $"`{u.Id,18}` {u}")
.ToArray(); .ToArray();
await ctx.SendPaginatedConfirmAsync(page, await ctx.SendPaginatedConfirmAsync(page,
cur => cur =>
@@ -140,9 +149,9 @@ public partial class Utility : NadekoModule
return _eb.Create().WithOkColor().WithDescription(GetText(strs.no_user_on_this_page)); return _eb.Create().WithOkColor().WithDescription(GetText(strs.no_user_on_this_page));
return _eb.Create() return _eb.Create()
.WithOkColor() .WithOkColor()
.WithTitle(GetText(strs.inrole_list(Format.Bold(role?.Name ?? "No Role"), roleUsers.Length))) .WithTitle(GetText(strs.inrole_list(Format.Bold(role?.Name ?? "No Role"), roleUsers.Length)))
.WithDescription(string.Join("\n", pageUsers)); .WithDescription(string.Join("\n", pageUsers));
}, },
roleUsers.Length, roleUsers.Length,
20); 20);
@@ -162,14 +171,14 @@ public partial class Utility : NadekoModule
var user = who == MeOrBot.Me ? (IGuildUser)ctx.User : ((SocketGuild)ctx.Guild).CurrentUser; var user = who == MeOrBot.Me ? (IGuildUser)ctx.User : ((SocketGuild)ctx.Guild).CurrentUser;
var perms = user.GetPermissions((ITextChannel)ctx.Channel); var perms = user.GetPermissions((ITextChannel)ctx.Channel);
foreach (var p in perms.GetType() foreach (var p in perms.GetType()
.GetProperties() .GetProperties()
.Where(static p => .Where(static p =>
{ {
var method = p.GetGetMethod(); var method = p.GetGetMethod();
if (method is null) if (method is null)
return false; return false;
return !method.GetParameters().Any(); return !method.GetParameters().Any();
})) }))
builder.AppendLine($"{p.Name} : {p.GetValue(perms, null)}"); builder.AppendLine($"{p.Name} : {p.GetValue(perms, null)}");
await SendConfirmAsync(builder.ToString()); await SendConfirmAsync(builder.ToString());
} }
@@ -214,11 +223,11 @@ public partial class Utility : NadekoModule
if (target is not null) if (target is not null)
{ {
var roles = target.GetRoles() var roles = target.GetRoles()
.Except(new[] { guild.EveryoneRole }) .Except(new[] { guild.EveryoneRole })
.OrderBy(r => -r.Position) .OrderBy(r => -r.Position)
.Skip((page - 1) * rolesPerPage) .Skip((page - 1) * rolesPerPage)
.Take(rolesPerPage) .Take(rolesPerPage)
.ToArray(); .ToArray();
if (!roles.Any()) if (!roles.Any())
await ReplyErrorLocalizedAsync(strs.no_roles_on_page); await ReplyErrorLocalizedAsync(strs.no_roles_on_page);
else else
@@ -230,10 +239,10 @@ public partial class Utility : NadekoModule
else else
{ {
var roles = guild.Roles.Except(new[] { guild.EveryoneRole }) var roles = guild.Roles.Except(new[] { guild.EveryoneRole })
.OrderBy(r => -r.Position) .OrderBy(r => -r.Position)
.Skip((page - 1) * rolesPerPage) .Skip((page - 1) * rolesPerPage)
.Take(rolesPerPage) .Take(rolesPerPage)
.ToArray(); .ToArray();
if (!roles.Any()) if (!roles.Any())
await ReplyErrorLocalizedAsync(strs.no_roles_on_page); await ReplyErrorLocalizedAsync(strs.no_roles_on_page);
else else
@@ -271,29 +280,29 @@ public partial class Utility : NadekoModule
ownerIds = "-"; ownerIds = "-";
await ctx.Channel.EmbedAsync(_eb.Create() await ctx.Channel.EmbedAsync(_eb.Create()
.WithOkColor() .WithOkColor()
.WithAuthor($"NadekoBot v{StatsService.BOT_VERSION}", .WithAuthor($"NadekoBot v{StatsService.BOT_VERSION}",
"https://nadeko-pictures.nyc3.digitaloceanspaces.com/other/avatar.png", "https://nadeko-pictures.nyc3.digitaloceanspaces.com/other/avatar.png",
"https://nadekobot.readthedocs.io/en/latest/") "https://nadekobot.readthedocs.io/en/latest/")
.AddField(GetText(strs.author), _stats.Author, true) .AddField(GetText(strs.author), _stats.Author, true)
.AddField(GetText(strs.botid), _client.CurrentUser.Id.ToString(), true) .AddField(GetText(strs.botid), _client.CurrentUser.Id.ToString(), true)
.AddField(GetText(strs.shard), .AddField(GetText(strs.shard),
$"#{_client.ShardId} / {_creds.TotalShards}", $"#{_client.ShardId} / {_creds.TotalShards}",
true) true)
.AddField(GetText(strs.commands_ran), _stats.CommandsRan.ToString(), true) .AddField(GetText(strs.commands_ran), _stats.CommandsRan.ToString(), true)
.AddField(GetText(strs.messages), .AddField(GetText(strs.messages),
$"{_stats.MessageCounter} ({_stats.MessagesPerSecond:F2}/sec)", $"{_stats.MessageCounter} ({_stats.MessagesPerSecond:F2}/sec)",
true) true)
.AddField(GetText(strs.memory), .AddField(GetText(strs.memory),
FormattableString.Invariant($"{_stats.GetPrivateMemoryMegabytes():F2} MB"), FormattableString.Invariant($"{_stats.GetPrivateMemoryMegabytes():F2} MB"),
true) true)
.AddField(GetText(strs.owner_ids), ownerIds, true) .AddField(GetText(strs.owner_ids), ownerIds, true)
.AddField(GetText(strs.uptime), _stats.GetUptimeString("\n"), true) .AddField(GetText(strs.uptime), _stats.GetUptimeString("\n"), true)
.AddField(GetText(strs.presence), .AddField(GetText(strs.presence),
GetText(strs.presence_txt(_coord.GetGuildCount(), GetText(strs.presence_txt(_coord.GetGuildCount(),
_stats.TextChannels, _stats.TextChannels,
_stats.VoiceChannels)), _stats.VoiceChannels)),
true)); true));
} }
[Cmd] [Cmd]
@@ -486,17 +495,17 @@ public partial class Utility : NadekoModule
private static string FormatToExtension(StickerFormatType format) private static string FormatToExtension(StickerFormatType format)
{ {
switch (format) switch (format)
{ {
case StickerFormatType.None: case StickerFormatType.None:
case StickerFormatType.Png: case StickerFormatType.Png:
case StickerFormatType.Apng: case StickerFormatType.Apng:
return "png"; return "png";
case StickerFormatType.Lottie: case StickerFormatType.Lottie:
return "lottie"; return "lottie";
default: default:
throw new ArgumentException(nameof (format)); throw new ArgumentException(nameof(format));
} }
} }
[Cmd] [Cmd]
@@ -509,9 +518,9 @@ public partial class Utility : NadekoModule
return; return;
var guilds = _client.Guilds.OrderBy(g => g.Name) var guilds = _client.Guilds.OrderBy(g => g.Name)
.Skip(page * 15) .Skip(page * 15)
.Take(15) .Take(15)
.ToList(); .ToList();
if (!guilds.Any()) if (!guilds.Any())
{ {
@@ -560,7 +569,7 @@ public partial class Utility : NadekoModule
{ {
Content = msg.Content, Content = msg.Content,
Embeds = msg.Embeds Embeds = msg.Embeds
.Map(x => new SmartEmbedArrayElementText(x)) .Map(x => new SmartEmbedArrayElementText(x))
}.ToJson(_showEmbedSerializerOptions); }.ToJson(_showEmbedSerializerOptions);
await SendConfirmAsync(Format.Code(json, "json").Replace("](", "]\\(")); await SendConfirmAsync(Format.Code(json, "json").Replace("](", "]\\("));
@@ -576,34 +585,34 @@ public partial class Utility : NadekoModule
var title = $"Chatlog-{ctx.Guild.Name}/#{ctx.Channel.Name}-{DateTime.Now}.txt"; var title = $"Chatlog-{ctx.Guild.Name}/#{ctx.Channel.Name}-{DateTime.Now}.txt";
var grouping = msgs.GroupBy(x => $"{x.CreatedAt.Date:dd.MM.yyyy}") var grouping = msgs.GroupBy(x => $"{x.CreatedAt.Date:dd.MM.yyyy}")
.Select(g => new .Select(g => new
{ {
date = g.Key, date = g.Key,
messages = g.OrderBy(x => x.CreatedAt) messages = g.OrderBy(x => x.CreatedAt)
.Select(s => .Select(s =>
{ {
var msg = $"【{s.Timestamp:HH:mm:ss}】{s.Author}:"; var msg = $"【{s.Timestamp:HH:mm:ss}】{s.Author}:";
if (string.IsNullOrWhiteSpace(s.ToString())) if (string.IsNullOrWhiteSpace(s.ToString()))
{ {
if (s.Attachments.Any()) if (s.Attachments.Any())
{ {
msg += "FILES_UPLOADED: " msg += "FILES_UPLOADED: "
+ string.Join("\n", s.Attachments.Select(x => x.Url)); + string.Join("\n", s.Attachments.Select(x => x.Url));
} }
else if (s.Embeds.Any()) else if (s.Embeds.Any())
{ {
msg += "EMBEDS: " msg += "EMBEDS: "
+ string.Join("\n--------\n", + string.Join("\n--------\n",
s.Embeds.Select(x s.Embeds.Select(x
=> $"Description: {x.Description}")); => $"Description: {x.Description}"));
} }
} }
else else
msg += s.ToString(); msg += s.ToString();
return msg; return msg;
}) })
}); });
await using var stream = await JsonConvert.SerializeObject(grouping, Formatting.Indented).ToStream(); await using var stream = await JsonConvert.SerializeObject(grouping, Formatting.Indented).ToStream();
await ctx.User.SendFileAsync(stream, title, title); await ctx.User.SendFileAsync(stream, title, title);
} }
@@ -639,4 +648,61 @@ public partial class Utility : NadekoModule
else else
await ReplyConfirmLocalizedAsync(strs.verbose_errors_disabled); await ReplyConfirmLocalizedAsync(strs.verbose_errors_disabled);
} }
[Cmd]
[NoPublicBot]
[OwnerOnly]
public async Task Eval([Leftover] string scriptText)
{
_ = ctx.Channel.TriggerTypingAsync();
if (scriptText.StartsWith("```cs"))
scriptText = scriptText[5..];
else if (scriptText.StartsWith("```"))
scriptText = scriptText[3..];
if (scriptText.EndsWith("```"))
scriptText = scriptText[..^3];
var script = CSharpScript.Create(scriptText,
ScriptOptions.Default
.WithReferences(this.GetType().Assembly)
.WithImports(
"System",
"NadekoBot",
"NadekoBot.Extensions",
"Microsoft.Extensions.DependencyInjection",
"NadekoBot.Common",
"System.Text",
"System.Text.Json"),
globalsType: typeof(EvalGlobals));
try
{
var result = await script.RunAsync(new EvalGlobals()
{
ctx = this.ctx,
guild = this.ctx.Guild,
channel = this.ctx.Channel,
user = this.ctx.User,
self = this,
services = _services
});
var output = result.ReturnValue?.ToString();
if (!string.IsNullOrWhiteSpace(output))
{
var eb = _eb.Create(ctx)
.WithOkColor()
.AddField("Code", scriptText)
.AddField("Output", output.TrimTo(512)!);
_ = ctx.Channel.EmbedAsync(eb);
}
}
catch (Exception ex)
{
await SendErrorAsync(ex.Message);
}
}
} }

View File

@@ -1,76 +0,0 @@
#nullable disable
using Microsoft.CodeAnalysis.CSharp.Scripting;
using Microsoft.CodeAnalysis.Scripting;
namespace NadekoBot.Modules.Utility;
public partial class Utility
{
[Group]
public partial class EvalCommands : NadekoModule
{
private readonly IServiceProvider _services;
public EvalCommands(IServiceProvider services)
{
_services = services;
}
[Cmd]
[NoPublicBot]
[OwnerOnly]
public async Task Eval([Leftover] string scriptText)
{
_ = ctx.Channel.TriggerTypingAsync();
if (scriptText.StartsWith("```cs"))
scriptText = scriptText[5..];
else if (scriptText.StartsWith("```"))
scriptText = scriptText[3..];
if (scriptText.EndsWith("```"))
scriptText = scriptText[..^3];
var script = CSharpScript.Create(scriptText,
ScriptOptions.Default
.WithReferences(this.GetType().Assembly)
.WithImports(
"System",
"NadekoBot",
"NadekoBot.Extensions",
"Microsoft.Extensions.DependencyInjection",
"NadekoBot.Common",
"System.Text",
"System.Text.Json"),
globalsType: typeof(EvalGlobals));
try
{
var result = await script.RunAsync(new EvalGlobals()
{
ctx = this.ctx,
guild = this.ctx.Guild,
channel = this.ctx.Channel,
user = this.ctx.User,
self = this,
services = _services
});
var output = result.ReturnValue?.ToString();
if (!string.IsNullOrWhiteSpace(output))
{
var eb = _eb.Create(ctx)
.WithOkColor()
.AddField("Code", scriptText)
.AddField("Output", output.TrimTo(512)!);
_ = ctx.Channel.EmbedAsync(eb);
}
}
catch (Exception ex)
{
await SendErrorAsync(ex.Message);
}
}
}
}

View File

@@ -5,7 +5,7 @@ namespace NadekoBot.Modules.Utility;
public class EvalGlobals public class EvalGlobals
{ {
public ICommandContext ctx; public ICommandContext ctx;
public Utility.EvalCommands self; public Utility self;
public IUser user; public IUser user;
public IMessageChannel channel; public IMessageChannel channel;
public IGuild guild; public IGuild guild;