From 98fddbd9b19d42be461659e950e342b9263c410c Mon Sep 17 00:00:00 2001
From: Toastie <toastie@toastiet0ast.com>
Date: Wed, 19 Mar 2025 11:35:08 +1300
Subject: [PATCH] .xprate will now work on threads properly, and apply parent
 channel rate if set. This is a fix as it worked with exclusions before

---
 .../Modules/Xp/XpRate/GuildConfigXpService.cs        | 10 ++++++----
 src/EllieBot/Modules/Xp/XpService.cs                 | 12 +++++++++---
 2 files changed, 15 insertions(+), 7 deletions(-)

diff --git a/src/EllieBot/Modules/Xp/XpRate/GuildConfigXpService.cs b/src/EllieBot/Modules/Xp/XpRate/GuildConfigXpService.cs
index 495c7d5..bb65a46 100644
--- a/src/EllieBot/Modules/Xp/XpRate/GuildConfigXpService.cs
+++ b/src/EllieBot/Modules/Xp/XpRate/GuildConfigXpService.cs
@@ -161,24 +161,26 @@ public class XpRateService(DbService db, ShardData shardData, XpConfigService xc
         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 (guildChannelRates.TryGetValue((type, channelId), out var rate))
-                return rate;
+                return (rate, true);
         }
 
         if (_guildRates.TryGetValue((type, guildId), out var guildRate))
-            return guildRate;
+            return (guildRate, false);
 
         var conf = xcs.Data;
 
-        return type switch
+        var toReturn = type switch
         {
             XpRateType.Image => new XpRate(XpRateType.Image, conf.TextXpFromImage, conf.TextXpCooldown / 60.0f),
             XpRateType.Voice => new XpRate(XpRateType.Voice, conf.VoiceXpPerMinute, 1.0f),
             _ => new XpRate(XpRateType.Text, conf.TextXpPerMessage, conf.TextXpCooldown / 60.0f),
         };
+
+        return (toReturn, false);
     }
 }
\ No newline at end of file
diff --git a/src/EllieBot/Modules/Xp/XpService.cs b/src/EllieBot/Modules/Xp/XpService.cs
index b371299..0af9e83 100644
--- a/src/EllieBot/Modules/Xp/XpService.cs
+++ b/src/EllieBot/Modules/Xp/XpService.cs
@@ -147,7 +147,7 @@ public class XpService : IEService, IReadyExecutor, IExecNoCommand
                 if (!IsVoiceChannelActive(vc))
                     continue;
 
-                var rate = _xpRateRateService.GetXpRate(XpRateType.Voice, g.Id, vc.Id);
+                var (rate, _) = _xpRateRateService.GetXpRate(XpRateType.Voice, g.Id, vc.Id);
 
                 if (rate.IsExcluded())
                     continue;
@@ -522,12 +522,18 @@ public class XpService : IEService, IReadyExecutor, IExecNoCommand
             var isImage = arg.Attachments.Any(a => a.Height >= 16 && a.Width >= 16);
             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;
             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())
                     return;