diff --git a/subathon/component.py b/subathon/component.py index 002c3f5..5dbed6d 100644 --- a/subathon/component.py +++ b/subathon/component.py @@ -1,3 +1,4 @@ +import re from collections import defaultdict from datetime import datetime, timedelta from typing import Optional @@ -17,6 +18,36 @@ from .channel import SubathonPayload, prepare_subathon, TimerChannel class SubathonComponent(cmds.Component): + """ + !subathon + !subathon setup [cap] + !subathon stop + + !subathon link + !subathon pause + !subathon resume + + !subathon adjust [@user] + + !subathon config + !subathon config name [new name] + !subathon config cap [new cap] + !subathon config scores [ ] + !subathon config timescore [new score] + + !subathon lb + + !goals + !goals remaining + !goals add + !goals remove + + + Command: + Permissions: + Description: + Examples: + """ # TODO: Add explicit dependencies and version checks # for profile and event tracker modules @@ -60,6 +91,36 @@ class SubathonComponent(cmds.Component): await goal.update(notified=True) # ----- Event Handlers ----- + # Blerp handler + @cmds.Component.listener() + async def event_message(self, message: twitchio.ChatMessage): + if message.chatter.id not in ('253326823', '1361913054'): + return + if 'bits' not in message.text: + return + community = await self.bot.profiles.fetch_community(message.broadcaster) + cid = community.communityid + if (active := await self.get_active_subathon(cid)) is not None and not await active.check_finished(): + # Extract count and user + match = re.match(r"(?P\w+) used (?P\d+)", message.text) + if not match: + match = re.match(r"!For (?P\d+) bits, (?P\w+)", message.text) + if match: + amount = int(match['amount']) + name = match['name'] + # This is for giving the contribution to the calling user + # user = await self.bot.fetch_user(login=name.lower()) + user = await message.chatter.user() + profile = await self.bot.profiles.fetch_profile(user) + pid = profile.profileid + + score = amount * active.subathondata.bit_score + contrib = await active.add_contribution(pid, score, None) + await self.dispatch_update(active) + logger.info(f"Blerp contribution: {contrib!r} from {message!r}") + else: + logger.warning(f"Unknown blerp bit message: {message!r}") + @cmds.Component.listener() async def event_safe_bits_use(self, payload): event_row, detail_row, bits_payload = payload @@ -273,9 +334,10 @@ class SubathonComponent(cmds.Component): await ctx.reply("No active subathon running!") # subathon start + # TODO: Usage line on command error @group_subathon.command(name='setup', alias='start') @cmds.is_broadcaster() - async def cmd_setup(self, ctx: cmds.Context, name: str, initial_hours: float, sub1: float, sub2: float, sub3: float, bit: float, timescore: int, timecap: Optional[int]=None): + 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): """ Creates a new subathon. USAGE: {prefix}subathon setup [timecap] @@ -298,7 +360,6 @@ class SubathonComponent(cmds.Component): subdata = await Subathon.create( communityid=cid, - name=name, initial_time=initial_time, sub1_score=sub1, sub2_score=sub2, @@ -309,7 +370,12 @@ class SubathonComponent(cmds.Component): ) base_timer_url = self.bot.config.subathon['timer_url'] timer_link = f"{base_timer_url}?community={cid}" - await ctx.reply(f"Setup your {name}! Use !subathon resume to get the timer running. Your timer link: {timer_link}") + await ctx.reply( + f"Setup your subathon! " + f"Use {ctx.prefix}subathon resume to get the timer running. " + f"Use {ctx.prefix}subathon config to see and set options, including the name. " + f"Your timer link for OBS: {timer_link}" + ) active = ActiveSubathon(subdata, None) await self.dispatch_update(active) @@ -451,7 +517,7 @@ class SubathonComponent(cmds.Component): cap = active.subathondata.timecap if cap: hours = cap / 3600 - await ctx.reply(f"The timer cap is currently {hours} hours") + await ctx.reply(f"The timer cap is currently {hours} hours") elif option.lower() == 'name': if value: await active.subathondata.update(name=value) @@ -461,10 +527,219 @@ class SubathonComponent(cmds.Component): name = active.subathondata.name await ctx.reply(f"This subathon is called \"{name}\"") else: + # TODO: Add score and timescore config, probably move this to subcommands await ctx.reply( f"Unknown option {option}! Configurable options: 'name', 'cap'" ) + """ + !subathon config + name="Birthday Subathon" ; cap=10 (hours) ; scores=5 10 20 0.1 (t1, t2, t3, and bit points) ; timescore=10 (seconds per point); Use !subathon config