From d303beb2e1fc4d3ff242f278abd01b9941ae5dc2 Mon Sep 17 00:00:00 2001 From: poxifide Date: Sun, 12 Apr 2020 19:52:40 -0400 Subject: [PATCH 1/4] Added miss & some random replies. Two new configuration options are available for channels, ducks-chance-miss and ducks-max-cooldown. --- modules/ducks.py | 92 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 85 insertions(+), 7 deletions(-) diff --git a/modules/ducks.py b/modules/ducks.py index eb6d7ef4..3d510383 100644 --- a/modules/ducks.py +++ b/modules/ducks.py @@ -4,10 +4,43 @@ import random, re, time from src import EventManager, ModuleManager, utils -DUCK = "・゜゜・。。・゜゜\_o< QUACK!" +DUCK = random.choice([ +"・゜゜・。。・゜゜" +])+" "+random.choice([ +"\_o<", +"\_O<", +"\_0<", +"\___o<" +])+" "+random.choice([ +"QUACK!", +"QUACK QUACK!", +"FLAPPITY FLAP!", +"DON'T SHOOT ME!", +"DUCK SEASON!", +"RABBIT SEASON!" +]) + +MISS_BEF = random.choice([ +"The duck didn't want to be friends with you.", +"The duck is too busy right now.", +"The duck put you on ignore.", +"The duck is turning you in for stalking!" +]) + +MISS_TRAP = random.choice([ +"The duck was too smart for your trap.", +"Your trap missed the duck.", +"You trapped a bear by accident.", +"You need to get your eyes checked.", +"Your trap didn't work." +]) DEFAULT_MIN_MESSAGES = 100 +DEFAULT_MAX_COOLDOWN = 10 + +DEFAULT_CHANCE_MISS = 25 + @utils.export("channelset", utils.BoolSetting("ducks-enabled", "Whether or not to spawn ducks")) @utils.export("channelset", utils.IntRangeSetting(50, 200, "ducks-min-messages", @@ -16,11 +49,19 @@ "Whether or not to kick someone talking to non-existent ducks")) @utils.export("channelset", utils.BoolSetting("ducks-prevent-highlight", "Whether or not to prevent highlighting users with !friends/!enemies")) +@utils.export("channelset", utils.IntRangeSetting(5, 30, "ducks-max-cooldown", + "Maximum amount of time a cooldown can last in seconds.")) +@utils.export("channelset", utils.IntRangeSetting(0, 100, "ducks-chance-miss", + "Percent chance that someone will miss.")) class Module(ModuleManager.BaseModule): @utils.hook("new.channel") def new_channel(self, event): self.bootstrap_channel(event["channel"]) + @utils.hook("new.user") + def new_user(self, event): + event["user"]._duck_cooldown = {} + def bootstrap_channel(self, channel): if not hasattr(channel, "duck_active"): channel.duck_active = None @@ -93,15 +134,38 @@ def _no_duck(self, channel, user, stderr): else: stderr.write("%s: %s" % (user.nickname, message)) + def _miss_roll(self, channel, user): + percentage = channel.get_setting("ducks-chance-miss", + DEFAULT_CHANCE_MISS) + if random.randrange(0,100) <= percentage: + max_cooldown = channel.get_setting("ducks-max-cooldown", + DEFAULT_MAX_COOLDOWN) + cooldown = random.randrange(1,max_cooldown) + user._duck_cooldown[channel] = time.time()+cooldown + else: + cooldown = 0 + user._duck_cooldown[channel] = 0 + if cooldown != 0: + cooldown_rem = round((user._duck_cooldown[channel] - time.time())) + else: + cooldown_rem = user._duck_cooldown[channel] + return cooldown_rem + @utils.hook("received.command.bef", alias_of="befriend") @utils.hook("received.command.befriend") @utils.kwarg("help", "Befriend a duck") @utils.spec("!-channelonly") def befriend(self, event): if event["target"].duck_active: - action = self._duck_action(event["target"], event["user"], - "befriended", "ducks-befriended") - event["stdout"].write(action) + channel = event["target"] + user = event["user"] + cooldown_sec = self._miss_roll(channel, user) + if cooldown_sec != 0: + event["stdout"].write(MISS_BEF+" You may try again in "+str(cooldown_sec)+" seconds.") + else: + action = self._duck_action(event["target"], event["user"], + "befriended", "ducks-befriended") + event["stdout"].write(action) else: self._no_duck(event["target"], event["user"], event["stderr"]) @@ -110,12 +174,26 @@ def befriend(self, event): @utils.spec("!-channelonly") def trap(self, event): if event["target"].duck_active: - action = self._duck_action(event["target"], event["user"], - "trapped", "ducks-shot") - event["stdout"].write(action) + channel = event["target"] + user = event["user"] + cooldown_sec = self._miss_roll(channel, user) + if cooldown_sec != 0: + event["stdout"].write(MISS_TRAP+" You may try again in "+str(cooldown_sec)+" seconds.") + else: + action = self._duck_action(event["target"], event["user"], + "trapped", "ducks-shot") + event["stdout"].write(action) else: self._no_duck(event["target"], event["user"], event["stderr"]) +# Left here in case someone wants to enable it for testing. +# @utils.hook("received.command.getduck") +# @utils.kwarg("help", "Get a duck delivered to the channel.") +# @utils.spec("!-channelonly") +# def getduck(self, event): +# channel = event["target"] +# self._trigger_duck(channel) + def _target(self, target, is_channel, query): if query: if not query == "*": From fcf2dd36b3f2c0fab0254b37bd62e293d97636dd Mon Sep 17 00:00:00 2001 From: poxifide Date: Sun, 12 Apr 2020 21:08:34 -0400 Subject: [PATCH 2/4] Fix the miss so it checks user cooldown. --- modules/ducks.py | 48 +++++++++++++++++++++++++++--------------------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/modules/ducks.py b/modules/ducks.py index 3d510383..88fd00c2 100644 --- a/modules/ducks.py +++ b/modules/ducks.py @@ -135,20 +135,26 @@ def _no_duck(self, channel, user, stderr): stderr.write("%s: %s" % (user.nickname, message)) def _miss_roll(self, channel, user): - percentage = channel.get_setting("ducks-chance-miss", - DEFAULT_CHANCE_MISS) - if random.randrange(0,100) <= percentage: - max_cooldown = channel.get_setting("ducks-max-cooldown", - DEFAULT_MAX_COOLDOWN) - cooldown = random.randrange(1,max_cooldown) - user._duck_cooldown[channel] = time.time()+cooldown - else: - cooldown = 0 - user._duck_cooldown[channel] = 0 - if cooldown != 0: - cooldown_rem = round((user._duck_cooldown[channel] - time.time())) + try: + user_cd = user._duck_cooldown[channel] + except KeyError: + user_cd = 0 + if user_cd < time.time(): + percentage = channel.get_setting("ducks-chance-miss", + DEFAULT_CHANCE_MISS) + if random.randrange(0,100) <= percentage: + max_cooldown = channel.get_setting("ducks-max-cooldown", + DEFAULT_MAX_COOLDOWN) + cooldown = random.randrange(1,max_cooldown) + user._duck_cooldown[channel] = time.time()+cooldown + user_cd = user._duck_cooldown[channel] + else: + user._duck_cooldown[channel] = 0 + user_cd = user._duck_cooldown[channel] + if user_cd >= 0: + cooldown_rem = round((user_cd - time.time()),2) else: - cooldown_rem = user._duck_cooldown[channel] + cooldown_rem = user_cd return cooldown_rem @utils.hook("received.command.bef", alias_of="befriend") @@ -160,7 +166,7 @@ def befriend(self, event): channel = event["target"] user = event["user"] cooldown_sec = self._miss_roll(channel, user) - if cooldown_sec != 0: + if cooldown_sec >= 0: event["stdout"].write(MISS_BEF+" You may try again in "+str(cooldown_sec)+" seconds.") else: action = self._duck_action(event["target"], event["user"], @@ -177,7 +183,7 @@ def trap(self, event): channel = event["target"] user = event["user"] cooldown_sec = self._miss_roll(channel, user) - if cooldown_sec != 0: + if cooldown_sec >= 0: event["stdout"].write(MISS_TRAP+" You may try again in "+str(cooldown_sec)+" seconds.") else: action = self._duck_action(event["target"], event["user"], @@ -187,12 +193,12 @@ def trap(self, event): self._no_duck(event["target"], event["user"], event["stderr"]) # Left here in case someone wants to enable it for testing. -# @utils.hook("received.command.getduck") -# @utils.kwarg("help", "Get a duck delivered to the channel.") -# @utils.spec("!-channelonly") -# def getduck(self, event): -# channel = event["target"] -# self._trigger_duck(channel) + @utils.hook("received.command.getduck") + @utils.kwarg("help", "Get a duck delivered to the channel.") + @utils.spec("!-channelonly") + def getduck(self, event): + channel = event["target"] + self._trigger_duck(channel) def _target(self, target, is_channel, query): if query: From 9ec7b2b49b45292a2298713a761cff092bef1c6b Mon Sep 17 00:00:00 2001 From: poxifide Date: Sun, 12 Apr 2020 21:22:58 -0400 Subject: [PATCH 3/4] Forgot to comment out the getduck command sorry. --- modules/ducks.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/modules/ducks.py b/modules/ducks.py index 88fd00c2..08ff568a 100644 --- a/modules/ducks.py +++ b/modules/ducks.py @@ -192,13 +192,14 @@ def trap(self, event): else: self._no_duck(event["target"], event["user"], event["stderr"]) -# Left here in case someone wants to enable it for testing. - @utils.hook("received.command.getduck") - @utils.kwarg("help", "Get a duck delivered to the channel.") - @utils.spec("!-channelonly") - def getduck(self, event): - channel = event["target"] - self._trigger_duck(channel) +#TODO: Fix or destroy. Used for testing. +# @utils.hook("received.command.getduck") +# @utils.kwarg("help", "Get a duck delivered to the channel.") +# @utils.spec("!-channelonly") +# @utils.kwarg("require_access", "admin,ducks") +# def getduck(self, event): +# channel = event["target"] +# self._trigger_duck(channel) def _target(self, target, is_channel, query): if query: From 1708259274280ad9b25cca0719626d7a43a183bc Mon Sep 17 00:00:00 2001 From: poxifide Date: Mon, 13 Apr 2020 17:58:02 -0400 Subject: [PATCH 4/4] Fixed random msgs & add userflood msg. I don't know why I thought a random would work up top. They will just be static when the script fires up lol. --- modules/ducks.py | 51 +++++++++++++++++++++++++++++++++++------------- 1 file changed, 37 insertions(+), 14 deletions(-) diff --git a/modules/ducks.py b/modules/ducks.py index 08ff568a..c811e3ea 100644 --- a/modules/ducks.py +++ b/modules/ducks.py @@ -4,36 +4,49 @@ import random, re, time from src import EventManager, ModuleManager, utils -DUCK = random.choice([ +DUCK_TAILS = [ "・゜゜・。。・゜゜" -])+" "+random.choice([ +] + +DUCK_BODIES = [ "\_o<", "\_O<", "\_0<", "\___o<" -])+" "+random.choice([ +] + +DUCK_PHRASES = [ "QUACK!", "QUACK QUACK!", "FLAPPITY FLAP!", "DON'T SHOOT ME!", "DUCK SEASON!", "RABBIT SEASON!" -]) +] -MISS_BEF = random.choice([ +MISS_BEF = [ "The duck didn't want to be friends with you.", "The duck is too busy right now.", "The duck put you on ignore.", "The duck is turning you in for stalking!" -]) +] -MISS_TRAP = random.choice([ +MISS_TRAP = [ "The duck was too smart for your trap.", "Your trap missed the duck.", "You trapped a bear by accident.", "You need to get your eyes checked.", "Your trap didn't work." -]) +] + +USER_FLOODING = [ +"Stop doing that so fast!", +"Are you mad? Slow down!", +"Calm down Road Runner.", +"Turn off your scripts please.", +"Hit the brakes!", +"That's enough, Mr. Trigger Finger." +] DEFAULT_MIN_MESSAGES = 100 @@ -102,6 +115,7 @@ def _send_duck(self, timer): channel = timer.kwargs["channel"] channel.duck_active = time.time() channel.duck_lines = 0 + DUCK = random.choice(DUCK_TAILS)+" "+random.choice(DUCK_BODIES)+" "+random.choice(DUCK_PHRASES) channel.send_message(DUCK) def _duck_action(self, channel, user, action, setting): @@ -151,11 +165,14 @@ def _miss_roll(self, channel, user): else: user._duck_cooldown[channel] = 0 user_cd = user._duck_cooldown[channel] + userflooding = False + else: + userflooding = True if user_cd >= 0: cooldown_rem = round((user_cd - time.time()),2) else: cooldown_rem = user_cd - return cooldown_rem + return cooldown_rem, userflooding @utils.hook("received.command.bef", alias_of="befriend") @utils.hook("received.command.befriend") @@ -166,8 +183,11 @@ def befriend(self, event): channel = event["target"] user = event["user"] cooldown_sec = self._miss_roll(channel, user) - if cooldown_sec >= 0: - event["stdout"].write(MISS_BEF+" You may try again in "+str(cooldown_sec)+" seconds.") + if cooldown_sec[0] >= 0: + if cooldown_sec[1] == False: + event["stdout"].write(random.choice(MISS_BEF)+" You may try again in "+str(cooldown_sec[0])+" seconds.") + else: + event["stdout"].write(random.choice(USER_FLOODING)+" You may try again in "+str(cooldown_sec[0])+" seconds.") else: action = self._duck_action(event["target"], event["user"], "befriended", "ducks-befriended") @@ -183,8 +203,11 @@ def trap(self, event): channel = event["target"] user = event["user"] cooldown_sec = self._miss_roll(channel, user) - if cooldown_sec >= 0: - event["stdout"].write(MISS_TRAP+" You may try again in "+str(cooldown_sec)+" seconds.") + if cooldown_sec[0] >= 0: + if cooldown_sec[1] == False: + event["stdout"].write(random.choice(MISS_TRAP)+" You may try again in "+str(cooldown_sec[0])+" seconds.") + else: + event["stdout"].write(random.choice(USER_FLOODING)+" You may try again in "+str(cooldown_sec[0])+" seconds.") else: action = self._duck_action(event["target"], event["user"], "trapped", "ducks-shot") @@ -192,7 +215,7 @@ def trap(self, event): else: self._no_duck(event["target"], event["user"], event["stderr"]) -#TODO: Fix or destroy. Used for testing. +#TODO: Fix or destroy. Used for testing. # @utils.hook("received.command.getduck") # @utils.kwarg("help", "Get a duck delivered to the channel.") # @utils.spec("!-channelonly")