Compare commits

...

2 commits

5 changed files with 35 additions and 10 deletions

View file

@ -2,6 +2,23 @@
*a,c,f,r,o* *a,c,f,r,o*
## [6.0.7] - 18.03.2025
### Added
- Schedule commands!
- `.scha <time> <text>` adds the command to be excuted after the specified amount of time
- `.schd <id>` deletes the command with the specified id
- `.schl` lists your scheduled commands
- `.masskick` added as massban and masskill already exist
- `.xpex` and `.xpexl` are back, as there was no way to exclude specific users or roles with .xprate
### Fix
- `.xprate` will now (as exclusion did) respect parent channel xp rates in threads
- the xprate system will first check if a thread channel has a rate set
- if it doesn't it will try to use the parent channel's rate
## [6.0.6] - 16.03.2025 ## [6.0.6] - 16.03.2025
### Added ### Added

View file

@ -4,7 +4,7 @@
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<ImplicitUsings>true</ImplicitUsings> <ImplicitUsings>true</ImplicitUsings>
<SatelliteResourceLanguages>en</SatelliteResourceLanguages> <SatelliteResourceLanguages>en</SatelliteResourceLanguages>
<Version>6.0.6</Version> <Version>6.0.7</Version>
<!-- Output/build --> <!-- Output/build -->
<RunWorkingDirectory>$(MSBuildProjectDirectory)</RunWorkingDirectory> <RunWorkingDirectory>$(MSBuildProjectDirectory)</RunWorkingDirectory>

View file

@ -33,7 +33,7 @@ public partial class Utility
foreach (var cmd in pageCommands) foreach (var cmd in pageCommands)
{ {
eb.AddField( eb.AddField(
$"`{GetText(strs.schedule_id)}:` {cmd.Id}", $"`{GetText(strs.schedule_id)}:` {(kwum)cmd.Id}",
$""" $"""
`{GetText(strs.schedule_command)}:` {cmd.Text} `{GetText(strs.schedule_command)}:` {cmd.Text}
`{GetText(strs.schedule_when)}:` {TimestampTag.FromDateTime(cmd.When, TimestampTagStyles.Relative)} `{GetText(strs.schedule_when)}:` {TimestampTag.FromDateTime(cmd.When, TimestampTagStyles.Relative)}
@ -47,7 +47,7 @@ public partial class Utility
[Cmd] [Cmd]
[RequireContext(ContextType.Guild)] [RequireContext(ContextType.Guild)]
public async Task ScheduleDelete([Leftover] int id) public async Task ScheduleDelete([Leftover] kwum id)
{ {
var success = await scs.DeleteScheduledCommandAsync(id, ctx.Guild.Id, ctx.User.Id); var success = await scs.DeleteScheduledCommandAsync(id, ctx.Guild.Id, ctx.User.Id);

View file

@ -161,24 +161,26 @@ public class XpRateService(DbService db, ShardData shardData, XpConfigService xc
return deleted > 0; return deleted > 0;
} }
public XpRate GetXpRate(XpRateType type, ulong guildId, ulong channelId) public (XpRate Rate, bool isItemRate) GetXpRate(XpRateType type, ulong guildId, ulong channelId)
{ {
if (_channelRates.TryGetValue(guildId, out var guildChannelRates)) if (_channelRates.TryGetValue(guildId, out var guildChannelRates))
{ {
if (guildChannelRates.TryGetValue((type, channelId), out var rate)) if (guildChannelRates.TryGetValue((type, channelId), out var rate))
return rate; return (rate, true);
} }
if (_guildRates.TryGetValue((type, guildId), out var guildRate)) if (_guildRates.TryGetValue((type, guildId), out var guildRate))
return guildRate; return (guildRate, false);
var conf = xcs.Data; var conf = xcs.Data;
return type switch var toReturn = type switch
{ {
XpRateType.Image => new XpRate(XpRateType.Image, conf.TextXpFromImage, conf.TextXpCooldown / 60.0f), XpRateType.Image => new XpRate(XpRateType.Image, conf.TextXpFromImage, conf.TextXpCooldown / 60.0f),
XpRateType.Voice => new XpRate(XpRateType.Voice, conf.VoiceXpPerMinute, 1.0f), XpRateType.Voice => new XpRate(XpRateType.Voice, conf.VoiceXpPerMinute, 1.0f),
_ => new XpRate(XpRateType.Text, conf.TextXpPerMessage, conf.TextXpCooldown / 60.0f), _ => new XpRate(XpRateType.Text, conf.TextXpPerMessage, conf.TextXpCooldown / 60.0f),
}; };
return (toReturn, false);
} }
} }

View file

@ -147,7 +147,7 @@ public class XpService : IEService, IReadyExecutor, IExecNoCommand
if (!IsVoiceChannelActive(vc)) if (!IsVoiceChannelActive(vc))
continue; continue;
var rate = _xpRateRateService.GetXpRate(XpRateType.Voice, g.Id, vc.Id); var (rate, _) = _xpRateRateService.GetXpRate(XpRateType.Voice, g.Id, vc.Id);
if (rate.IsExcluded()) if (rate.IsExcluded())
continue; continue;
@ -522,12 +522,18 @@ public class XpService : IEService, IReadyExecutor, IExecNoCommand
var isImage = arg.Attachments.Any(a => a.Height >= 16 && a.Width >= 16); var isImage = arg.Attachments.Any(a => a.Height >= 16 && a.Width >= 16);
var isText = arg.Content.Contains(' ') || arg.Content.Length >= 5; var isText = arg.Content.Contains(' ') || arg.Content.Length >= 5;
var textRate = _xpRateRateService.GetXpRate(XpRateType.Text, guild.Id, gc.Id); // try to get a rate for this channel
// and if there is no specified rate, use thread rate
var (textRate, isItemRate) = _xpRateRateService.GetXpRate(XpRateType.Text, guild.Id, gc.Id);
if (!isItemRate && gc is SocketThreadChannel tc)
{
(textRate, _) = _xpRateRateService.GetXpRate(XpRateType.Text, guild.Id, tc.ParentChannel.Id);
}
XpRate rate; XpRate rate;
if (isImage) if (isImage)
{ {
var imageRate = _xpRateRateService.GetXpRate(XpRateType.Image, guild.Id, gc.Id); var (imageRate, _) = _xpRateRateService.GetXpRate(XpRateType.Image, guild.Id, gc.Id);
if (imageRate.IsExcluded()) if (imageRate.IsExcluded())
return; return;