From a52dcade56fe9e2a964cae617db174da665a12d4 Mon Sep 17 00:00:00 2001 From: Interitio Date: Thu, 31 Jul 2025 06:55:21 +1000 Subject: [PATCH] Add timecap. --- src/modules/subathons/component.py | 51 ++++++++++++++++++++++++++---- src/modules/subathons/data.py | 2 ++ 2 files changed, 46 insertions(+), 7 deletions(-) diff --git a/src/modules/subathons/component.py b/src/modules/subathons/component.py index bb60386..2536dc9 100644 --- a/src/modules/subathons/component.py +++ b/src/modules/subathons/component.py @@ -69,6 +69,12 @@ class ActiveSubathon: def running(self): return self.runningdata is not None + async def check_cap(self): + score = await self.get_score() + time_earned = self.get_score_time(score) + total_time = self.subathondata.initial_time + time_earned + return total_time >= self.subathondata.timecap + async def pause(self): if not self.running: raise ValueError("This subathon is not running!") @@ -104,6 +110,8 @@ class ActiveSubathon: score = await self.get_score() time_earned = self.get_score_time(score) total_time = self.subathondata.initial_time + time_earned + if cap := self.subathondata.timecap: + total_time = min(total_time, cap) return total_time - self.get_duration() @@ -181,8 +189,15 @@ class SubathonComponent(cmds.Component): added = f"{sec} seconds" name = bits_payload.user.name pl = 's' if bits_payload.bits != 1 else '' + + contrib_str = f"{name} contributed {score} bit{pl}" + if not await active.check_cap(): + contrib_str += f" and added {added} to the timer! Thank you holono1Heart" + else: + contrib_str += " towards our studython! Thank you holono1Heart" + await bits_payload.broadcaster.send_message( - f"{name} contributed {bits_payload.bits} bit{pl} and added {added} to the timer! Thank you <3", + contrib_str, sender=self.bot.bot_id ) await self.channel.send_updates() @@ -220,8 +235,15 @@ class SubathonComponent(cmds.Component): added = f"{added_min} minutes" name = sub_payload.user.name pl = 's' if score > 1 else '' + + contrib_str = f"{name} contributed {score} sub{pl}" + if not await active.check_cap(): + contrib_str += f" and added {added} to the timer! Thank you holono1Heart" + else: + contrib_str += " towards our studython! Thank you holono1Heart" + await sub_payload.broadcaster.send_message( - f"{name} contributed {score} sub{pl} and added {added} to the timer! Thank you <3", + contrib_str, sender=self.bot.bot_id ) await self.channel.send_updates() @@ -255,8 +277,15 @@ class SubathonComponent(cmds.Component): added_min = int(active.get_score_time(score) // 60) added = f"{added_min} minutes" name = gift_payload.user.name if gift_payload.user else 'Anonymous' + + contrib_str = f"{name} contributed {score} subs" + if not await active.check_cap(): + contrib_str += f" and added {added} to the timer! Thank you holono1Heart" + else: + contrib_str += " towards our studython! Thank you holono1Heart" + await gift_payload.broadcaster.send_message( - f"{name} contributed {score} subs and added {added} to the timer! Thank you <3", + contrib_str, sender=self.bot.bot_id ) await self.channel.send_updates() @@ -291,8 +320,15 @@ class SubathonComponent(cmds.Component): added = f"{added_min} minutes" name = sub_payload.user.name pl = 's' if score > 1 else '' + + contrib_str = f"{name} contributed {score} sub{pl}" + if not await active.check_cap(): + contrib_str += f" and added {added} to the timer! Thank you holono1Heart" + else: + contrib_str += " towards our studython! Thank you holono1Heart" + await sub_payload.broadcaster.send_message( - f"{name} contributed {score} sub{pl} and added {added} to the timer! Thank you <3", + contrib_str, sender=self.bot.bot_id ) await self.channel.send_updates() @@ -315,7 +351,7 @@ class SubathonComponent(cmds.Component): # ----- Commands ----- - @cmds.group(name='subathon', invoke_fallback=True) + @cmds.group(name='subathon', aliases=['studython'], invoke_fallback=True) async def group_subathon(self, ctx: cmds.Context): # TODO: Status community = await self.bot.community_fetch(twitchid=ctx.broadcaster.id, name=ctx.broadcaster.name) @@ -342,7 +378,7 @@ class SubathonComponent(cmds.Component): # subathon start @group_subathon.command(name='setup') - async def cmd_setup(self, ctx: cmds.Context, initial_hours: float, sub1: float, sub2: float, sub3: float, bit: float, timescore: int): + async def cmd_setup(self, ctx: cmds.Context, initial_hours: float, sub1: float, sub2: float, sub3: float, bit: float, timescore: int, timecap: Optional[int]=None): if ctx.broadcaster: community = await self.bot.community_fetch(twitchid=ctx.broadcaster.id, name=ctx.broadcaster.name) cid = community.communityid @@ -358,7 +394,8 @@ class SubathonComponent(cmds.Component): sub2_score=sub2, sub3_score=sub3, bit_score=bit, - score_time=timescore + score_time=timescore, + timecap=timecap ) await ctx.reply("Setup a new subathon! Use !subathon resume to get the timer running.") await self.channel.send_updates() diff --git a/src/modules/subathons/data.py b/src/modules/subathons/data.py index b8cb9bf..76ee590 100644 --- a/src/modules/subathons/data.py +++ b/src/modules/subathons/data.py @@ -19,6 +19,7 @@ class Subathon(RowModel): score_time = Integer() # Conversion factor score to seconds duration = Integer() ended_at = Timestamp() + timecap = Integer() # Maximum subathon duration in seconds class RunningSubathon(RowModel): _tablename_ = 'running_subathons' @@ -36,6 +37,7 @@ class SubathonContribution(RowModel): profileid = Integer() score = Integer() event_id = Integer() + # TODO: Should add a created timestamp here, since not all contributions have event ids class SubathonGoal(RowModel): _tablename_ = 'subathon_goals'