2024-06-19 00:54:39 +12:00
using EllieBot.Modules.Utility.Services ;
using Newtonsoft.Json ;
using System.Diagnostics ;
using System.Text ;
using System.Text.Json ;
using System.Text.Json.Serialization ;
using Microsoft.CodeAnalysis.CSharp.Scripting ;
using Microsoft.CodeAnalysis.Scripting ;
using EllieBot.Modules.Searches.Common ;
namespace EllieBot.Modules.Utility ;
public partial class Utility : EllieModule
{
public enum CreateInviteType
{
Any ,
New
}
public enum MeOrBot
{
Me ,
Bot
}
private static readonly JsonSerializerOptions _showEmbedSerializerOptions = new ( )
{
WriteIndented = true ,
DefaultIgnoreCondition = JsonIgnoreCondition . WhenWritingNull ,
PropertyNamingPolicy = LowerCaseNamingPolicy . Default
} ;
private readonly DiscordSocketClient _client ;
private readonly ICoordinator _coord ;
private readonly IStatsService _stats ;
private readonly IBotCredentials _creds ;
private readonly DownloadTracker _tracker ;
private readonly IHttpClientFactory _httpFactory ;
private readonly VerboseErrorsService _veService ;
private readonly IServiceProvider _services ;
2024-07-17 00:33:43 +12:00
private readonly AfkService _afkService ;
2024-06-19 00:54:39 +12:00
public Utility (
DiscordSocketClient client ,
ICoordinator coord ,
IStatsService stats ,
IBotCredentials creds ,
DownloadTracker tracker ,
IHttpClientFactory httpFactory ,
VerboseErrorsService veService ,
2024-07-17 00:33:43 +12:00
IServiceProvider services ,
AfkService afkService )
2024-06-19 00:54:39 +12:00
{
_client = client ;
_coord = coord ;
_stats = stats ;
_creds = creds ;
_tracker = tracker ;
_httpFactory = httpFactory ;
_veService = veService ;
_services = services ;
2024-07-17 00:33:43 +12:00
_afkService = afkService ;
2024-06-19 00:54:39 +12:00
}
[Cmd]
[RequireContext(ContextType.Guild)]
[UserPerm(GuildPerm.ManageMessages)]
[Priority(1)]
public async Task Say ( ITextChannel channel , [ Leftover ] SmartText message )
{
if ( ! ( ( IGuildUser ) ctx . User ) . GetPermissions ( channel ) . SendMessages )
{
await Response ( ) . Error ( strs . insuf_perms_u ) . SendAsync ( ) ;
return ;
}
if ( ! ( ( ctx . Guild as SocketGuild ) ? . CurrentUser . GetPermissions ( channel ) . SendMessages ? ? false ) )
{
await Response ( ) . Error ( strs . insuf_perms_i ) . SendAsync ( ) ;
return ;
}
var repCtx = new ReplacementContext ( Context ) ;
message = await repSvc . ReplaceAsync ( message , repCtx ) ;
await Response ( )
. Text ( message )
. Channel ( channel )
. UserBasedMentions ( )
. SendAsync ( ) ;
}
[Cmd]
[RequireContext(ContextType.Guild)]
[UserPerm(GuildPerm.ManageMessages)]
[Priority(0)]
public Task Say ( [ Leftover ] SmartText message )
= > Say ( ( ITextChannel ) ctx . Channel , message ) ;
[Cmd]
[RequireContext(ContextType.Guild)]
2024-07-17 00:33:43 +12:00
public async Task WhosPlaying ( [ Leftover ] string? game )
2024-06-19 00:54:39 +12:00
{
game = game ? . Trim ( ) . ToUpperInvariant ( ) ;
if ( string . IsNullOrWhiteSpace ( game ) )
return ;
if ( ctx . Guild is not SocketGuild socketGuild )
{
Log . Warning ( "Can't cast guild to socket guild" ) ;
return ;
}
var rng = new EllieRandom ( ) ;
var arr = await Task . Run ( ( ) = > socketGuild . Users
2024-08-17 18:45:31 +12:00
. Where ( u = > u . Activities . Any ( x
= > x . Name is not null & & x . Name . ToUpperInvariant ( ) = = game ) )
2024-06-19 00:54:39 +12:00
. Select ( u = > u . Username )
. OrderBy ( _ = > rng . Next ( ) )
. Take ( 60 )
. ToArray ( ) ) ;
var i = 0 ;
if ( arr . Length = = 0 )
await Response ( ) . Error ( strs . nobody_playing_game ) . SendAsync ( ) ;
else
{
await Response ( )
. Confirm ( "```css\n"
+ string . Join ( "\n" ,
arr . GroupBy ( _ = > i + + / 2 )
. Select ( ig = > string . Concat ( ig . Select ( el = > $"• {el,-27}" ) ) ) )
+ "\n```" )
. SendAsync ( ) ;
}
}
[Cmd]
[RequireContext(ContextType.Guild)]
[Priority(0)]
2024-07-17 00:33:43 +12:00
public async Task InRole ( int page , [ Leftover ] IRole ? role = null )
2024-06-19 00:54:39 +12:00
{
if ( - - page < 0 )
return ;
await ctx . Channel . TriggerTypingAsync ( ) ;
await _tracker . EnsureUsersDownloadedAsync ( ctx . Guild ) ;
var users = await ctx . Guild . GetUsersAsync (
CacheMode . CacheOnly
) ;
2024-08-17 18:45:31 +12:00
users = role is null
? users
: users . Where ( u = > u . RoleIds . Contains ( role . Id ) ) . ToList ( ) ;
var roleUsers = new List < string > ( users . Count ) ;
foreach ( var u in users )
{
roleUsers . Add ( $"{u.Mention} {Format.Spoiler(Format.Code(u.Username))}" ) ;
}
2024-06-19 00:54:39 +12:00
await Response ( )
. Paginated ( )
. Items ( roleUsers )
. PageSize ( 20 )
. CurrentPage ( page )
. Page ( ( pageUsers , _ ) = >
{
if ( pageUsers . Count = = 0 )
return _sender . CreateEmbed ( ) . WithOkColor ( ) . WithDescription ( GetText ( strs . no_user_on_this_page ) ) ;
2024-08-17 18:45:31 +12:00
var roleName = Format . Bold ( role ? . Name ? ? "No Role" ) ;
2024-06-19 00:54:39 +12:00
return _sender . CreateEmbed ( )
. WithOkColor ( )
2024-08-17 18:45:31 +12:00
. WithTitle ( GetText ( strs . inrole_list ( roleName , roleUsers . Count ) ) )
2024-06-19 00:54:39 +12:00
. WithDescription ( string . Join ( "\n" , pageUsers ) ) ;
} )
. SendAsync ( ) ;
}
[Cmd]
[RequireContext(ContextType.Guild)]
[Priority(1)]
2024-07-17 00:33:43 +12:00
public Task InRole ( [ Leftover ] IRole ? role = null )
2024-06-19 00:54:39 +12:00
= > InRole ( 1 , role ) ;
[Cmd]
[RequireContext(ContextType.Guild)]
public async Task CheckPerms ( MeOrBot who = MeOrBot . Me )
{
var user = who = = MeOrBot . Me ? ( IGuildUser ) ctx . User : ( ( SocketGuild ) ctx . Guild ) . CurrentUser ;
var perms = user . GetPermissions ( ( ITextChannel ) ctx . Channel ) ;
await SendPerms ( perms ) ;
}
private async Task SendPerms ( ChannelPermissions perms )
{
var builder = new StringBuilder ( ) ;
foreach ( var p in perms . GetType ( )
. GetProperties ( )
. Where ( static p = >
{
var method = p . GetGetMethod ( ) ;
if ( method is null )
return false ;
return ! method . GetParameters ( ) . Any ( ) ;
} ) )
builder . AppendLine ( $"{p.Name} : {p.GetValue(perms, null)}" ) ;
await Response ( ) . Confirm ( builder . ToString ( ) ) . SendAsync ( ) ;
}
// [Cmd]
// [RequireContext(ContextType.Guild)]
// [RequireUserPermission(GuildPermission.ManageRoles)]
// public async Task CheckPerms(SocketRole role, string perm = null)
// {
// ChannelPermissions.
// var perms = ((ITextChannel)ctx.Channel);
// await SendPerms(perms)
// }
[Cmd]
[RequireContext(ContextType.Guild)]
2024-07-17 00:33:43 +12:00
public async Task UserId ( [ Leftover ] IGuildUser ? target = null )
2024-06-19 00:54:39 +12:00
{
var usr = target ? ? ctx . User ;
await Response ( )
. Confirm ( strs . userid ( "🆔" ,
Format . Bold ( usr . ToString ( ) ) ,
Format . Code ( usr . Id . ToString ( ) ) ) )
. SendAsync ( ) ;
}
[Cmd]
[RequireContext(ContextType.Guild)]
public async Task RoleId ( [ Leftover ] IRole role )
= > await Response ( )
. Confirm ( strs . roleid ( "🆔" ,
Format . Bold ( role . ToString ( ) ) ,
Format . Code ( role . Id . ToString ( ) ) ) )
. SendAsync ( ) ;
[Cmd]
public async Task ChannelId ( )
= > await Response ( ) . Confirm ( strs . channelid ( "🆔" , Format . Code ( ctx . Channel . Id . ToString ( ) ) ) ) . SendAsync ( ) ;
[Cmd]
[RequireContext(ContextType.Guild)]
public async Task ServerId ( )
= > await Response ( ) . Confirm ( strs . serverid ( "🆔" , Format . Code ( ctx . Guild . Id . ToString ( ) ) ) ) . SendAsync ( ) ;
[Cmd]
[RequireContext(ContextType.Guild)]
2024-07-17 00:33:43 +12:00
public async Task Roles ( IGuildUser ? target , int page = 1 )
2024-06-19 00:54:39 +12:00
{
var guild = ctx . Guild ;
const int rolesPerPage = 20 ;
if ( page is < 1 or > 100 )
return ;
if ( target is not null )
{
var roles = target . GetRoles ( )
. Except ( new [ ] { guild . EveryoneRole } )
. OrderBy ( r = > - r . Position )
. Skip ( ( page - 1 ) * rolesPerPage )
. Take ( rolesPerPage )
. ToArray ( ) ;
if ( ! roles . Any ( ) )
await Response ( ) . Error ( strs . no_roles_on_page ) . SendAsync ( ) ;
else
{
await Response ( )
. Confirm ( GetText ( strs . roles_page ( page , Format . Bold ( target . ToString ( ) ) ) ) ,
"\n• " + string . Join ( "\n• " , ( IEnumerable < IRole > ) roles ) )
. SendAsync ( ) ;
}
}
else
{
var roles = guild . Roles . Except ( new [ ] { guild . EveryoneRole } )
. OrderBy ( r = > - r . Position )
. Skip ( ( page - 1 ) * rolesPerPage )
. Take ( rolesPerPage )
. ToArray ( ) ;
if ( ! roles . Any ( ) )
await Response ( ) . Error ( strs . no_roles_on_page ) . SendAsync ( ) ;
else
{
await Response ( )
. Confirm ( GetText ( strs . roles_all_page ( page ) ) ,
"\n• " + string . Join ( "\n• " , ( IEnumerable < IRole > ) roles ) . SanitizeMentions ( true ) )
. SendAsync ( ) ;
}
}
}
[Cmd]
[RequireContext(ContextType.Guild)]
public Task Roles ( int page = 1 )
= > Roles ( null , page ) ;
[Cmd]
[RequireContext(ContextType.Guild)]
2024-07-17 00:33:43 +12:00
public async Task ChannelTopic ( [ Leftover ] ITextChannel ? channel = null )
2024-06-19 00:54:39 +12:00
{
if ( channel is null )
channel = ( ITextChannel ) ctx . Channel ;
var topic = channel . Topic ;
if ( string . IsNullOrWhiteSpace ( topic ) )
await Response ( ) . Error ( strs . no_topic_set ) . SendAsync ( ) ;
else
await Response ( ) . Confirm ( GetText ( strs . channel_topic ) , topic ) . SendAsync ( ) ;
}
[Cmd]
public async Task Stats ( )
{
var ownerIds = string . Join ( "\n" , _creds . OwnerIds ) ;
if ( string . IsNullOrWhiteSpace ( ownerIds ) )
ownerIds = "-" ;
await Response ( )
. Embed ( _sender . CreateEmbed ( )
. WithOkColor ( )
. WithAuthor ( $"EllieBot v{StatsService.BotVersion}" ,
"https://cdn.elliebot.net/Ellie.png" ,
"https://docs.elliebot.net/" )
. AddField ( GetText ( strs . author ) , _stats . Author , true )
. AddField ( GetText ( strs . botid ) , _client . CurrentUser . Id . ToString ( ) , true )
. AddField ( GetText ( strs . shard ) ,
$"#{_client.ShardId} / {_creds.TotalShards}" ,
true )
. AddField ( GetText ( strs . commands_ran ) , _stats . CommandsRan . ToString ( ) , true )
. AddField ( GetText ( strs . messages ) ,
$"{_stats.MessageCounter} ({_stats.MessagesPerSecond:F2}/sec)" ,
true )
. AddField ( GetText ( strs . memory ) ,
FormattableString . Invariant ( $"{_stats.GetPrivateMemoryMegabytes():F2} MB" ) ,
true )
. AddField ( GetText ( strs . owner_ids ) , ownerIds , true )
. AddField ( GetText ( strs . uptime ) , _stats . GetUptimeString ( "\n" ) , true )
. AddField ( GetText ( strs . presence ) ,
GetText ( strs . presence_txt ( _coord . GetGuildCount ( ) ,
_stats . TextChannels ,
_stats . VoiceChannels ) ) ,
true ) )
. SendAsync ( ) ;
}
[Cmd]
public async Task Showemojis ( [ Leftover ] string _ )
{
var tags = ctx . Message . Tags . Where ( t = > t . Type = = TagType . Emoji ) . Select ( t = > ( Emote ) t . Value ) ;
var result = string . Join ( "\n" , tags . Select ( m = > GetText ( strs . showemojis ( m , m . Url ) ) ) ) ;
if ( string . IsNullOrWhiteSpace ( result ) )
await Response ( ) . Error ( strs . showemojis_none ) . SendAsync ( ) ;
else
await Response ( ) . Text ( result . TrimTo ( 2000 ) ) . SendAsync ( ) ;
}
[Cmd]
[RequireContext(ContextType.Guild)]
[BotPerm(GuildPerm.ManageEmojisAndStickers)]
[UserPerm(GuildPerm.ManageEmojisAndStickers)]
[Priority(2)]
public Task EmojiAdd ( string name , Emote emote )
= > EmojiAdd ( name , emote . Url ) ;
[Cmd]
[RequireContext(ContextType.Guild)]
[BotPerm(GuildPerm.ManageEmojisAndStickers)]
[UserPerm(GuildPerm.ManageEmojisAndStickers)]
[Priority(1)]
public Task EmojiAdd ( Emote emote )
= > EmojiAdd ( emote . Name , emote . Url ) ;
[Cmd]
[RequireContext(ContextType.Guild)]
[BotPerm(GuildPerm.ManageEmojisAndStickers)]
[UserPerm(GuildPerm.ManageEmojisAndStickers)]
[Priority(0)]
2024-07-17 00:33:43 +12:00
public async Task EmojiAdd ( string name , string? url = null )
2024-06-19 00:54:39 +12:00
{
name = name . Trim ( ':' ) ;
url ? ? = ctx . Message . Attachments . FirstOrDefault ( ) ? . Url ;
if ( url is null )
return ;
using var http = _httpFactory . CreateClient ( ) ;
using var res = await http . GetAsync ( url , HttpCompletionOption . ResponseHeadersRead ) ;
if ( ! res . IsImage ( ) | | res . GetContentLength ( ) > 262_144 )
{
await Response ( ) . Error ( strs . invalid_emoji_link ) . SendAsync ( ) ;
return ;
}
await using var imgStream = await res . Content . ReadAsStreamAsync ( ) ;
Emote em ;
try
{
em = await ctx . Guild . CreateEmoteAsync ( name , new ( imgStream ) ) ;
}
catch ( Exception ex )
{
Log . Warning ( ex , "Error adding emoji on server {GuildId}" , ctx . Guild . Id ) ;
await Response ( ) . Error ( strs . emoji_add_error ) . SendAsync ( ) ;
return ;
}
await Response ( ) . Confirm ( strs . emoji_added ( em . ToString ( ) ) ) . SendAsync ( ) ;
}
[Cmd]
[RequireContext(ContextType.Guild)]
[BotPerm(GuildPerm.ManageEmojisAndStickers)]
[UserPerm(GuildPerm.ManageEmojisAndStickers)]
[Priority(0)]
public async Task EmojiRemove ( params Emote [ ] emotes )
{
if ( emotes . Length = = 0 )
return ;
var g = ( SocketGuild ) ctx . Guild ;
var fails = new List < Emote > ( ) ;
foreach ( var emote in emotes )
{
var guildEmote = g . Emotes . FirstOrDefault ( x = > x . Id = = emote . Id ) ;
if ( guildEmote is null )
{
fails . Add ( emote ) ;
}
else
{
await ctx . Guild . DeleteEmoteAsync ( guildEmote ) ;
}
}
if ( fails . Count > 0 )
{
await Response ( ) . Pending ( strs . emoji_not_removed ( fails . Select ( x = > x . ToString ( ) ) . Join ( " " ) ) ) . SendAsync ( ) ;
return ;
}
await ctx . OkAsync ( ) ;
}
[Cmd]
[RequireContext(ContextType.Guild)]
[BotPerm(GuildPerm.ManageEmojisAndStickers)]
[UserPerm(GuildPerm.ManageEmojisAndStickers)]
2024-07-17 00:33:43 +12:00
public async Task StickerAdd ( string? name = null , string? description = null , params string [ ] tags )
2024-06-19 00:54:39 +12:00
{
string format ;
2024-07-17 00:33:43 +12:00
Stream ? stream = null ;
2024-06-19 00:54:39 +12:00
2024-07-08 00:36:45 +12:00
try
2024-06-19 00:54:39 +12:00
{
2024-07-08 00:36:45 +12:00
if ( ctx . Message . Stickers . Count is 1 & & ctx . Message . Stickers . First ( ) is SocketSticker ss )
{
name ? ? = ss . Name ;
description = ss . Description ;
tags = tags is null or { Length : 0 } ? ss . Tags . ToArray ( ) : tags ;
format = FormatToExtension ( ss . Format ) ;
2024-06-19 00:54:39 +12:00
2024-07-08 00:36:45 +12:00
using var http = _httpFactory . CreateClient ( ) ;
stream = await http . GetStreamAsync ( ss . GetStickerUrl ( ) ) ;
}
else if ( ctx . Message . Attachments . Count is 1 & & name is not null )
{
if ( tags . Length = = 0 )
tags = [ name ] ;
2024-06-19 00:54:39 +12:00
2024-07-08 00:36:45 +12:00
if ( ctx . Message . Attachments . Count ! = 1 )
{
await Response ( ) . Error ( strs . sticker_error ) . SendAsync ( ) ;
return ;
}
var attach = ctx . Message . Attachments . First ( ) ;
if ( attach . Size > 512_000 | | attach . Width ! = 300 | | attach . Height ! = 300 )
{
await Response ( ) . Error ( strs . sticker_error ) . SendAsync ( ) ;
return ;
}
format = attach . Filename
. Split ( '.' )
. Last ( )
. ToLowerInvariant ( ) ;
if ( string . IsNullOrWhiteSpace ( format ) | | ( format ! = "png" & & format ! = "apng" ) )
{
await Response ( ) . Error ( strs . sticker_error ) . SendAsync ( ) ;
return ;
}
using var http = _httpFactory . CreateClient ( ) ;
stream = await http . GetStreamAsync ( attach . Url ) ;
}
else
{
await Response ( ) . Error ( strs . sticker_error ) . SendAsync ( ) ;
return ;
}
try
{
await ctx . Guild . CreateStickerAsync (
name ,
stream ,
$"{name}.{format}" ,
tags ,
string . IsNullOrWhiteSpace ( description ) ? "Missing description" : description
) ;
await ctx . OkAsync ( ) ;
}
catch
( Exception ex )
{
Log . Warning ( ex , "Error occurred while adding a sticker: {Message}" , ex . Message ) ;
await Response ( ) . Error ( strs . error_occured ) . SendAsync ( ) ;
}
2024-06-19 00:54:39 +12:00
}
finally
{
2024-07-08 00:36:45 +12:00
await ( stream ? . DisposeAsync ( ) ? ? ValueTask . CompletedTask ) ;
2024-06-19 00:54:39 +12:00
}
}
private static string FormatToExtension ( StickerFormatType format )
{
switch ( format )
{
case StickerFormatType . None :
case StickerFormatType . Png :
case StickerFormatType . Apng :
return "png" ;
case StickerFormatType . Lottie :
return "lottie" ;
default :
throw new ArgumentException ( nameof ( format ) ) ;
}
}
[Cmd]
[OwnerOnly]
2024-08-07 11:32:51 +12:00
public async Task ServerList ( int page = 1 )
2024-06-19 00:54:39 +12:00
{
page - = 1 ;
if ( page < 0 )
return ;
2024-08-07 11:32:51 +12:00
var allGuilds = _client . Guilds
2024-08-14 18:53:35 +12:00
. OrderBy ( g = > g . Name )
. ToList ( ) ;
2024-06-19 00:54:39 +12:00
2024-08-07 11:32:51 +12:00
await Response ( )
. Paginated ( )
. Items ( allGuilds )
. PageSize ( 9 )
. Page ( ( guilds , _ ) = >
{
if ( ! guilds . Any ( ) )
{
return _sender . CreateEmbed ( )
. WithDescription ( GetText ( strs . listservers_none ) )
. WithErrorColor ( ) ;
}
var embed = _sender . CreateEmbed ( )
. WithOkColor ( ) ;
foreach ( var guild in guilds )
embed . AddField ( guild . Name , GetText ( strs . listservers ( guild . Id , guild . MemberCount , guild . OwnerId ) ) ) ;
return embed ;
} )
. SendAsync ( ) ;
2024-06-19 00:54:39 +12:00
}
[Cmd]
[RequireContext(ContextType.Guild)]
public Task ShowEmbed ( ulong messageId )
= > ShowEmbed ( ( ITextChannel ) ctx . Channel , messageId ) ;
[Cmd]
[RequireContext(ContextType.Guild)]
public async Task ShowEmbed ( ITextChannel ch , ulong messageId )
{
var user = ( IGuildUser ) ctx . User ;
var perms = user . GetPermissions ( ch ) ;
if ( ! perms . ReadMessageHistory | | ! perms . ViewChannel )
{
await Response ( ) . Error ( strs . insuf_perms_u ) . SendAsync ( ) ;
return ;
}
var msg = await ch . GetMessageAsync ( messageId ) ;
if ( msg is null )
{
await Response ( ) . Error ( strs . msg_not_found ) . SendAsync ( ) ;
return ;
}
if ( ! msg . Embeds . Any ( ) )
{
await Response ( ) . Error ( strs . not_found ) . SendAsync ( ) ;
return ;
}
var json = new SmartEmbedTextArray ( )
{
Content = msg . Content ,
Embeds = msg . Embeds
. Map ( x = > new SmartEmbedArrayElementText ( x ) )
} . ToJson ( _showEmbedSerializerOptions ) ;
await Response ( ) . Confirm ( Format . Code ( json , "json" ) . Replace ( "](" , "]\\(" ) ) . SendAsync ( ) ;
}
[Cmd]
[RequireContext(ContextType.Guild)]
[OwnerOnly]
public async Task SaveChat ( int cnt )
{
var msgs = new List < IMessage > ( cnt ) ;
await ctx . Channel . GetMessagesAsync ( cnt ) . ForEachAsync ( dled = > msgs . AddRange ( dled ) ) ;
var title = $"Chatlog-{ctx.Guild.Name}/#{ctx.Channel.Name}-{DateTime.Now}.txt" ;
var grouping = msgs . GroupBy ( x = > $"{x.CreatedAt.Date:dd.MM.yyyy}" )
. Select ( g = > new
{
date = g . Key ,
messages = g . OrderBy ( x = > x . CreatedAt )
. Select ( s = >
{
var msg = $"【{s.Timestamp:HH:mm:ss}】{s.Author}:" ;
if ( string . IsNullOrWhiteSpace ( s . ToString ( ) ) )
{
if ( s . Attachments . Any ( ) )
{
msg + = "FILES_UPLOADED: "
+ string . Join ( "\n" , s . Attachments . Select ( x = > x . Url ) ) ;
}
else if ( s . Embeds . Any ( ) )
{
msg + = "EMBEDS: "
+ string . Join ( "\n--------\n" ,
s . Embeds . Select ( x
= > $"Description: {x.Description}" ) ) ;
}
}
else
msg + = s . ToString ( ) ;
return msg ;
} )
} ) ;
await using var stream = await JsonConvert . SerializeObject ( grouping , Formatting . Indented ) . ToStream ( ) ;
await ctx . User . SendFileAsync ( stream , title , title ) ;
}
[Cmd]
2024-08-17 18:45:31 +12:00
[Ratelimit(3)]
2024-06-19 00:54:39 +12:00
public async Task Ping ( )
{
2024-08-17 18:45:31 +12:00
var sw = Stopwatch . StartNew ( ) ;
var msg = await Response ( ) . Text ( "🏓" ) . SendAsync ( ) ;
sw . Stop ( ) ;
msg . DeleteAfter ( 0 ) ;
2024-06-19 00:54:39 +12:00
2024-08-17 18:45:31 +12:00
await Response ( )
. Confirm ( $"{Format.Bold(ctx.User.ToString())} 🏓 {(int)sw.Elapsed.TotalMilliseconds}ms" )
. SendAsync ( ) ;
2024-06-19 00:54:39 +12:00
}
[Cmd]
[RequireContext(ContextType.Guild)]
[UserPerm(GuildPerm.ManageMessages)]
public async Task VerboseError ( bool? newstate = null )
{
var state = _veService . ToggleVerboseErrors ( ctx . Guild . Id , newstate ) ;
if ( state )
await Response ( ) . Confirm ( strs . verbose_errors_enabled ) . SendAsync ( ) ;
else
await Response ( ) . Confirm ( strs . verbose_errors_disabled ) . SendAsync ( ) ;
}
2024-07-17 00:33:43 +12:00
[Cmd]
2024-07-18 21:54:45 +12:00
public async Task Afk ( [ Leftover ] string text = "No reason specified." )
2024-07-17 00:33:43 +12:00
{
var succ = await _afkService . SetAfkAsync ( ctx . User . Id , text ) ;
if ( succ )
{
await Response ( )
. Confirm ( strs . afk_set )
. SendAsync ( ) ;
}
}
2024-06-19 00:54:39 +12:00
[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" ,
"System.Collections.Generic" ,
"System.IO" ,
"System.Linq" ,
"System.Net.Http" ,
"System.Threading" ,
"System.Threading.Tasks" ,
"EllieBot" ,
"EllieBot.Extensions" ,
"Microsoft.Extensions.DependencyInjection" ,
"EllieBot.Common" ,
"EllieBot.Modules" ,
"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 = _sender . CreateEmbed ( )
. WithOkColor ( )
. AddField ( "Code" , scriptText )
. AddField ( "Output" , output . TrimTo ( 512 ) ! ) ;
_ = Response ( ) . Embed ( eb ) . SendAsync ( ) ;
}
}
catch ( Exception ex )
{
await Response ( ) . Error ( ex . Message ) . SendAsync ( ) ;
}
}
}