added .rolecolor command
updated changelog
This commit is contained in:
parent
55e3a80405
commit
16025b74e3
9 changed files with 182 additions and 31 deletions
16
CHANGELOG.md
16
CHANGELOG.md
|
@ -2,6 +2,22 @@
|
|||
|
||||
*a,c,f,r,o*
|
||||
|
||||
## [6.0.13] - 23.03.2025
|
||||
|
||||
### Added
|
||||
- Added `.linkfix <old> <new>` command
|
||||
- If bot sees a message with the old link, it will reply to the message with a fixed (new) link
|
||||
- ex: `.linkfix twitter.com vxtwitter.com`
|
||||
- Added `.roleicon role <icon_url / server_emoji>` command to set the icon of a role
|
||||
- Added a captcha option for `.fish`
|
||||
|
||||
### Fixed
|
||||
- fixed youtube stream notifications in case invalid channel was provided
|
||||
- `.lcha` (live channel) will now let you override an existing channel template even if you're at the limit
|
||||
|
||||
### Removed
|
||||
- removed `.xpglb` as it is no longer used
|
||||
|
||||
## [6.0.12] - 20.03.2025
|
||||
|
||||
### Fixed
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>true</ImplicitUsings>
|
||||
<SatelliteResourceLanguages>en</SatelliteResourceLanguages>
|
||||
<Version>6.0.12</Version>
|
||||
<Version>6.0.13</Version>
|
||||
|
||||
<!-- Output/build -->
|
||||
<RunWorkingDirectory>$(MSBuildProjectDirectory)</RunWorkingDirectory>
|
||||
|
|
|
@ -48,9 +48,9 @@ public partial class Administration
|
|||
});
|
||||
|
||||
await Response()
|
||||
.Confirm(strs.setrole(Format.Bold(roleToAdd.Name),
|
||||
Format.Bold(targetUser.ToString())))
|
||||
.SendAsync();
|
||||
.Confirm(strs.setrole(Format.Bold(roleToAdd.Name),
|
||||
Format.Bold(targetUser.ToString())))
|
||||
.SendAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
@ -73,9 +73,9 @@ public partial class Administration
|
|||
{
|
||||
await targetUser.RemoveRoleAsync(roleToRemove);
|
||||
await Response()
|
||||
.Confirm(strs.remrole(Format.Bold(roleToRemove.Name),
|
||||
Format.Bold(targetUser.ToString())))
|
||||
.SendAsync();
|
||||
.Confirm(strs.remrole(Format.Bold(roleToRemove.Name),
|
||||
Format.Bold(targetUser.ToString())))
|
||||
.SendAsync();
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
@ -226,8 +226,8 @@ public partial class Administration
|
|||
if (!await CheckRoleHierarchy(role))
|
||||
{
|
||||
await Response()
|
||||
.Error(strs.hierarchy)
|
||||
.SendAsync();
|
||||
.Error(strs.hierarchy)
|
||||
.SendAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -236,10 +236,83 @@ public partial class Administration
|
|||
|
||||
|
||||
await Response()
|
||||
.Confirm(strs.temp_role_added(user.Mention,
|
||||
Format.Bold(role.Name),
|
||||
TimestampTag.FromDateTime(DateTime.UtcNow.Add(timespan.Time), TimestampTagStyles.Relative)))
|
||||
.SendAsync();
|
||||
.Confirm(strs.temp_role_added(user.Mention,
|
||||
Format.Bold(role.Name),
|
||||
TimestampTag.FromDateTime(DateTime.UtcNow.Add(timespan.Time), TimestampTagStyles.Relative)))
|
||||
.SendAsync();
|
||||
}
|
||||
|
||||
[Cmd]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
[UserPerm(GuildPerm.ManageRoles)]
|
||||
[BotPerm(GuildPerm.ManageRoles)]
|
||||
public Task RoleIcon(IRole role, Emote emote)
|
||||
=> RoleIcon(role, emote.Url);
|
||||
|
||||
[Cmd]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
[UserPerm(GuildPerm.ManageRoles)]
|
||||
[BotPerm(GuildPerm.ManageRoles)]
|
||||
public async Task RoleIcon(IRole role, [Leftover] string iconUrl)
|
||||
{
|
||||
if (!await CheckRoleHierarchy(role))
|
||||
return;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(iconUrl))
|
||||
{
|
||||
await Response().Error(strs.userrole_icon_invalid).SendAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
// Validate the URL format
|
||||
if (!Uri.TryCreate(iconUrl, UriKind.Absolute, out var uri))
|
||||
{
|
||||
await Response().Error(strs.userrole_icon_invalid).SendAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
// Download the image
|
||||
using var httpClient = new HttpClient();
|
||||
using var response = await httpClient.GetAsync(uri, HttpCompletionOption.ResponseHeadersRead);
|
||||
|
||||
// Check if the response is successful
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
await Response().Error(strs.userrole_icon_fail).SendAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
// Check content type - must be image/png or image/jpeg
|
||||
var contentType = response.Content.Headers.ContentType?.MediaType?.ToLower();
|
||||
if (contentType != "image/png"
|
||||
&& contentType != "image/jpeg"
|
||||
&& contentType != "image/webp")
|
||||
{
|
||||
await Response().Error(strs.userrole_icon_fail).SendAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
// Check file size - Discord limit is 256KB
|
||||
var contentLength = response.Content.Headers.ContentLength;
|
||||
if (contentLength is > 256 * 1024)
|
||||
{
|
||||
await Response().Error(strs.userrole_icon_fail).SendAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
// Save the image to a memory stream
|
||||
await using var stream = await response.Content.ReadAsStreamAsync();
|
||||
await using var memoryStream = new MemoryStream();
|
||||
await stream.CopyToAsync(memoryStream);
|
||||
memoryStream.Position = 0;
|
||||
|
||||
// Create Discord image from stream
|
||||
using var discordImage = new Image(memoryStream);
|
||||
|
||||
// Upload the image to Discord
|
||||
await role.ModifyAsync(r => r.Icon = discordImage);
|
||||
|
||||
await Response().Confirm(strs.userrole_icon_success(Format.Bold(role.Name))).SendAsync();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -30,8 +30,8 @@ public partial class LinkFixerService(DbService db) : IReadyExecutor, IExecNoCom
|
|||
|
||||
public async Task ExecOnNoCommandAsync(IGuild guild, IUserMessage msg)
|
||||
{
|
||||
if(guild is null)
|
||||
return;
|
||||
if (guild is null)
|
||||
return;
|
||||
|
||||
var guildId = guild.Id;
|
||||
if (!_guildLinkFixes.TryGetValue(guildId, out var guildDict))
|
||||
|
@ -52,7 +52,7 @@ public partial class LinkFixerService(DbService db) : IReadyExecutor, IExecNoCom
|
|||
if (string.IsNullOrWhiteSpace(domain))
|
||||
continue;
|
||||
|
||||
if(!guildDict.TryGetValue(domain, out var newDomain))
|
||||
if (!guildDict.TryGetValue(domain, out var newDomain))
|
||||
continue;
|
||||
|
||||
var newUrl = match.Groups["prefix"].Value + newDomain + match.Groups["suffix"].Value;
|
||||
|
@ -73,10 +73,10 @@ public partial class LinkFixerService(DbService db) : IReadyExecutor, IExecNoCom
|
|||
public async Task<bool> AddLinkFixAsync(ulong guildId, string oldDomain, string newDomain)
|
||||
{
|
||||
oldDomain = oldDomain.ToLowerInvariant();
|
||||
|
||||
|
||||
var guildDict = _guildLinkFixes.GetOrAdd(guildId, _ => new ConcurrentDictionary<string, string>());
|
||||
guildDict[oldDomain] = newDomain;
|
||||
|
||||
|
||||
await using var uow = db.GetDbContext();
|
||||
await uow.GetTable<LinkFix>()
|
||||
.InsertOrUpdateAsync(() => new LinkFix
|
||||
|
@ -107,7 +107,7 @@ public partial class LinkFixerService(DbService db) : IReadyExecutor, IExecNoCom
|
|||
public async Task<bool> RemoveLinkFixAsync(ulong guildId, string oldDomain)
|
||||
{
|
||||
oldDomain = oldDomain.ToLowerInvariant();
|
||||
|
||||
|
||||
if (!_guildLinkFixes.TryGetValue(guildId, out var guildDict) || !guildDict.TryRemove(oldDomain, out _))
|
||||
return false;
|
||||
|
||||
|
|
|
@ -154,7 +154,7 @@ public sealed class UserRoleService : IUserRoleService, IEService
|
|||
memoryStream.Position = 0;
|
||||
|
||||
// Create Discord image from stream
|
||||
var discordImage = new Image(memoryStream);
|
||||
using var discordImage = new Image(memoryStream);
|
||||
|
||||
// Upload the image to Discord
|
||||
var discordSuccess = await _discordRoleManager.ModifyRoleAsync(
|
||||
|
|
|
@ -1606,6 +1606,21 @@
|
|||
"Administrator Server Permission"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Aliases": [
|
||||
".roleicon"
|
||||
],
|
||||
"Description": "Changes the icon of a role.",
|
||||
"Usage": [
|
||||
".roleicon @Role :server_emoji_here:"
|
||||
],
|
||||
"Submodule": "RoleCommands",
|
||||
"Module": "Administration",
|
||||
"Options": null,
|
||||
"Requirements": [
|
||||
"ManageRoles Server Permission"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Aliases": [
|
||||
".iam"
|
||||
|
@ -7384,6 +7399,37 @@
|
|||
"ManageChannels Channel Permission"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Aliases": [
|
||||
".linkfix",
|
||||
".lfix"
|
||||
],
|
||||
"Description": "Configures automatic link fixing from one site to another.\nWhen a user posts a link containing the old domain, the bot will automatically fix it to use the new domain.\nProvide no second domain to disable link fixing.",
|
||||
"Usage": [
|
||||
".linkfix twitter.com vxtwitter.com",
|
||||
".linkfix x.com"
|
||||
],
|
||||
"Submodule": "LinkFixerCommands",
|
||||
"Module": "Utility",
|
||||
"Options": null,
|
||||
"Requirements": [
|
||||
"ManageMessages Server Permission"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Aliases": [
|
||||
".linkfixlist",
|
||||
".lfixlist"
|
||||
],
|
||||
"Description": "Lists all configured link fixes for the server.",
|
||||
"Usage": [
|
||||
".linkfixlist"
|
||||
],
|
||||
"Submodule": "LinkFixerCommands",
|
||||
"Module": "Utility",
|
||||
"Options": null,
|
||||
"Requirements": []
|
||||
},
|
||||
{
|
||||
"Aliases": [
|
||||
".livechadd",
|
||||
|
@ -8218,7 +8264,7 @@
|
|||
],
|
||||
"Description": "Changes the icon of your assigned role.",
|
||||
"Usage": [
|
||||
".userroleicon @Role :thumbsup:"
|
||||
".userroleicon @Role :server_emoji_here:"
|
||||
],
|
||||
"Submodule": "UserRoleCommands",
|
||||
"Module": "Utility",
|
||||
|
|
|
@ -21,24 +21,24 @@ chance:
|
|||
fish:
|
||||
- id: 0
|
||||
name: Bass
|
||||
weather:
|
||||
spot:
|
||||
time:
|
||||
weather:
|
||||
spot:
|
||||
time:
|
||||
chance: 100
|
||||
stars: 4
|
||||
fluff: Very common.
|
||||
condition:
|
||||
condition:
|
||||
image: https://cdn.nadeko.bot/fish/bass.png
|
||||
emoji: <:bass:1328520376892002386>
|
||||
trash:
|
||||
- id: 1002
|
||||
name: Plastic Bag
|
||||
weather:
|
||||
spot:
|
||||
time:
|
||||
weather:
|
||||
spot:
|
||||
time:
|
||||
chance: 50
|
||||
stars: 4
|
||||
fluff: Trophy of your contribution to the environment.
|
||||
condition:
|
||||
condition:
|
||||
image: https://cdn.nadeko.bot/fish/plasticbag.png
|
||||
emoji: <:plasticbag:1328520895454515211>
|
||||
emoji: <:plasticbag:1328520895454515211>
|
||||
|
|
|
@ -165,6 +165,8 @@ deleterole:
|
|||
rolecolor:
|
||||
- rolecolor
|
||||
- roleclr
|
||||
roleicon:
|
||||
- roleicon
|
||||
ban:
|
||||
- ban
|
||||
- b
|
||||
|
|
|
@ -599,6 +599,20 @@ rolehoist:
|
|||
params:
|
||||
- role:
|
||||
desc: "The role that determines the visibility of the sidebar."
|
||||
roleicon:
|
||||
desc: |-
|
||||
Changes the icon of a role.
|
||||
ex:
|
||||
- '@Role :server_emoji_here:'
|
||||
params:
|
||||
- role:
|
||||
desc: 'The role to change the icon of.'
|
||||
imageUrl:
|
||||
desc: 'The image url to be used as a new icon for the role.'
|
||||
- role:
|
||||
desc: 'The role to change the icon of.'
|
||||
serverEmoji:
|
||||
desc: 'The server emoji to be used as a new icon for the role.'
|
||||
createrole:
|
||||
desc: Creates a role with a given name.
|
||||
ex:
|
||||
|
@ -5054,7 +5068,7 @@ userroleicon:
|
|||
desc: |-
|
||||
Changes the icon of your assigned role.
|
||||
ex:
|
||||
- '@Role :thumbsup:'
|
||||
- '@Role :server_emoji_here:'
|
||||
params:
|
||||
- role:
|
||||
desc: 'The assigned role to change the icon of.'
|
||||
|
|
Loading…
Add table
Reference in a new issue