dev: Some minor renaming to match the strings

add: audit logs for several commands
docs: Updated changelog
fix: xp card user avatar wasn't showing for some users
This commit is contained in:
Kwoth
2024-05-08 01:13:58 +00:00
parent bbc277f4b9
commit 4f0692db59
12 changed files with 73 additions and 52 deletions

View File

@@ -39,6 +39,7 @@ Experimental changelog. Mostly based on [keepachangelog](https://keepachangelog.
- Added seconds/sec/s to .convert command
- Added `.prunecancel` to cancel an active prune
- Added progress reporting when using `.prune`. The bot will periodically update on how many messages have been deleted
- Audit log reason will be automatically added when using `.setrole`, reaction role and `.dtch` commands
### Changed
@@ -58,6 +59,8 @@ Experimental changelog. Mostly based on [keepachangelog](https://keepachangelog.
- Fixed a bug in .invitelist not paginating correctly
- `.serverinfo` will now correctly work for other shards
- `.send` will now correctly work for other shards
- `.translate` command will no longer fail if the user capitalizes the language name
- Fixed xp card user avatar not showing for some users
### Removed

View File

@@ -207,7 +207,10 @@ public partial class Administration : NadekoModule<AdministrationService>
[BotPerm(GuildPerm.ManageChannels)]
public async Task DelTxtChanl([Leftover] ITextChannel toDelete)
{
await toDelete.DeleteAsync();
await toDelete.DeleteAsync(new RequestOptions()
{
AuditLogReason = $"Deleted by {ctx.User.Username}"
});
await Response().Confirm(strs.deltextchan(Format.Bold(toDelete.Name))).SendAsync();
}

View File

@@ -103,7 +103,10 @@ public sealed class ReactionRolesService : IReadyExecutor, INService, IReactionR
{
if (user.RoleIds.Contains(role.Id))
{
await user.RemoveRoleAsync(role.Id);
await user.RemoveRoleAsync(role.Id, new RequestOptions()
{
AuditLogReason = $"Reaction role"
});
}
}
finally
@@ -176,11 +179,22 @@ public sealed class ReactionRolesService : IReadyExecutor, INService, IReactionR
var exclusive = reros
.Where(x => x.Group == rero.Group && x.RoleId != role.Id)
.Select(x => x.RoleId)
.Distinct();
.Distinct()
.ToArray();
try { await user.RemoveRolesAsync(exclusive); }
catch { }
if (exclusive.Any())
{
try
{
await user.RemoveRolesAsync(exclusive,
new RequestOptions()
{
AuditLogReason = "Reaction role exclusive group"
});
}
catch { }
}
// remove user's previous reaction
try
@@ -203,7 +217,10 @@ public sealed class ReactionRolesService : IReadyExecutor, INService, IReactionR
}
}
await user.AddRoleAsync(role.Id);
await user.AddRoleAsync(role.Id, new()
{
AuditLogReason = "Reaction role"
});
}
}
finally

View File

@@ -34,7 +34,10 @@ public partial class Administration
return;
try
{
await targetUser.AddRoleAsync(roleToAdd);
await targetUser.AddRoleAsync(roleToAdd, new RequestOptions()
{
AuditLogReason = $"Added by [{ctx.User.Username}]"
});
await Response().Confirm(strs.setrole(Format.Bold(roleToAdd.Name),
Format.Bold(targetUser.ToString()))).SendAsync();

View File

@@ -21,11 +21,11 @@ public partial class Permissions
var list = _service.GetBlacklist();
var allItems = await list.Where(x => x.Type == type)
.Select(async i =>
.Select(i =>
{
try
{
return i.Type switch
return Task.FromResult(i.Type switch
{
BlacklistType.Channel => Format.Code(i.ItemId.ToString())
+ " "
@@ -40,14 +40,15 @@ public partial class Permissions
+ " "
+ (_client.GetGuild(i.ItemId)?.ToString() ?? ""),
_ => Format.Code(i.ItemId.ToString())
};
});
}
catch
{
Log.Warning("Can't get {BlacklistType} [{BlacklistItemId}]",
i.Type,
i.ItemId);
return Format.Code(i.ItemId.ToString());
return Task.FromResult(Format.Code(i.ItemId.ToString()));
}
})
.WhenAll();

View File

@@ -13,14 +13,14 @@ public partial class Searches
}
[Cmd]
public async Task Translate(string from, string to, [Leftover] string text = null)
public async Task Translate(string fromLang, string toLang, [Leftover] string text = null)
{
try
{
await ctx.Channel.TriggerTypingAsync();
var translation = await _service.Translate(from, to, text);
var translation = await _service.Translate(fromLang, toLang, text);
var embed = _sender.CreateEmbed().WithOkColor().AddField(from, text).AddField(to, translation);
var embed = _sender.CreateEmbed().WithOkColor().AddField(fromLang, text).AddField(toLang, translation);
await Response().Embed(embed).SendAsync();
}
@@ -55,9 +55,9 @@ public partial class Searches
[Cmd]
[RequireContext(ContextType.Guild)]
public async Task AutoTransLang(string from, string to)
public async Task AutoTransLang(string fromLang, string toLang)
{
var succ = await _service.RegisterUserAsync(ctx.User.Id, ctx.Channel.Id, from.ToLower(), to.ToLower());
var succ = await _service.RegisterUserAsync(ctx.User.Id, ctx.Channel.Id, fromLang.ToLower(), toLang.ToLower());
if (succ is null)
{
@@ -71,7 +71,7 @@ public partial class Searches
return;
}
await Response().Confirm(strs.atl_set(from, to)).SendAsync();
await Response().Confirm(strs.atl_set(fromLang, toLang)).SendAsync();
}
[Cmd]

View File

@@ -60,7 +60,7 @@ public class StreamRoleService : IReadyExecutor, INService
/// <param name="guild">Guild</param>
/// <param name="action">Add or rem action</param>
/// <param name="userId">User's Id</param>
/// <param name="userName">User's name#discrim</param>
/// <param name="userName">User's name</param>
/// <returns>Whether the operation was successful</returns>
public async Task<bool> ApplyListAction(
StreamRoleListType listType,

View File

@@ -1200,36 +1200,39 @@ public class XpService : INService, IReadyExecutor, IExecNoCommand
{
var avatarUrl = stats.User.RealAvatarUrl();
var result = await _c.GetImageDataAsync(avatarUrl);
if (!result.TryPickT0(out var data, out _))
if (avatarUrl is not null)
{
using (var http = _httpFactory.CreateClient())
var result = await _c.GetImageDataAsync(avatarUrl);
if (!result.TryPickT0(out var data, out _))
{
var avatarData = await http.GetByteArrayAsync(avatarUrl);
using (var tempDraw = Image.Load<Rgba32>(avatarData))
using (var http = _httpFactory.CreateClient())
{
tempDraw.Mutate(x => x
.Resize(template.User.Icon.Size.X, template.User.Icon.Size.Y)
.ApplyRoundedCorners(Math.Max(template.User.Icon.Size.X,
template.User.Icon.Size.Y)
/ 2.0f));
await using (var stream = await tempDraw.ToStreamAsync())
var avatarData = await http.GetByteArrayAsync(avatarUrl);
using (var tempDraw = Image.Load<Rgba32>(avatarData))
{
data = stream.ToArray();
tempDraw.Mutate(x => x
.Resize(template.User.Icon.Size.X, template.User.Icon.Size.Y)
.ApplyRoundedCorners(Math.Max(template.User.Icon.Size.X,
template.User.Icon.Size.Y)
/ 2.0f));
await using (var stream = await tempDraw.ToStreamAsync())
{
data = stream.ToArray();
}
}
}
await _c.SetImageDataAsync(avatarUrl, data);
}
await _c.SetImageDataAsync(avatarUrl, data);
using var toDraw = Image.Load(data);
if (toDraw.Size() != new Size(template.User.Icon.Size.X, template.User.Icon.Size.Y))
toDraw.Mutate(x => x.Resize(template.User.Icon.Size.X, template.User.Icon.Size.Y));
img.Mutate(x => x.DrawImage(toDraw,
new Point(template.User.Icon.Pos.X, template.User.Icon.Pos.Y),
1));
}
using var toDraw = Image.Load(data);
if (toDraw.Size() != new Size(template.User.Icon.Size.X, template.User.Icon.Size.Y))
toDraw.Mutate(x => x.Resize(template.User.Icon.Size.X, template.User.Icon.Size.Y));
img.Mutate(x => x.DrawImage(toDraw,
new Point(template.User.Icon.Pos.X, template.User.Icon.Pos.Y),
1));
}
catch (Exception ex)
{

View File

@@ -5,8 +5,6 @@ using System.Web;
namespace NadekoBot.Services;
// todo fix
/// <summary>
/// Uses <see cref="IStringsSource" /> to load strings into redis hash (only on Shard 0)
/// and retrieves them from redis via <see cref="GetText" />

View File

@@ -16,6 +16,3 @@ public sealed class CmdAttribute : CommandAttribute
Summary = memberName.ToLowerInvariant();
}
}
[AttributeUsage(AttributeTargets.Method)]
public sealed class PromptableAttribute: Attribute;

View File

@@ -44,8 +44,6 @@ public sealed class ModuleOrExprTypeReader : NadekoTypeReader<ModuleOrExpr>
}
}
// todo chagne commands.en-us to have the new type name
public sealed class ModuleOrExpr
{
public string Name { get; set; }

View File

@@ -9,10 +9,8 @@ public static class UserExtensions
=> usr.AvatarId is null ? new(usr.GetDefaultAvatarUrl()) : new Uri(usr.GetAvatarUrl(ImageFormat.Auto, size));
// This method is only used for the xp card
public static Uri RealAvatarUrl(this DiscordUser usr)
=> usr.AvatarId is null
? new(CDN.GetDefaultUserAvatarUrl(ushort.Parse(usr.Discriminator)))
: new Uri(usr.AvatarId.StartsWith("a_", StringComparison.InvariantCulture)
? $"{DiscordConfig.CDNUrl}avatars/{usr.UserId}/{usr.AvatarId}.gif"
: $"{DiscordConfig.CDNUrl}avatars/{usr.UserId}/{usr.AvatarId}.png");
public static Uri? RealAvatarUrl(this DiscordUser usr)
=> Uri.TryCreate(CDN.GetDefaultUserAvatarUrl(usr.UserId), UriKind.Absolute, out var uri)
? uri
: null;
}