1- import codecs
21import json
3- import os
4- import random
52import re
3+ from collections import defaultdict
4+ from enum import Enum , unique
5+ from pathlib import Path
66
77from cloudbot import hook
88from cloudbot .util import textgen
99
1010
11+ @unique
12+ class RespType (Enum ):
13+ ACTION = 1
14+ MESSAGE = 2
15+ REPLY = 3
16+
17+
1118def is_self (conn , target ):
1219 """ Checks if a string is "****self" or contains conn.name. """
1320 if re .search ("(^..?.?.?self|{})" .format (re .escape (conn .nick )), target , re .I ):
@@ -16,200 +23,109 @@ def is_self(conn, target):
1623 return False
1724
1825
19- @hook .on_start ()
20- def load_attacks (bot ):
21- """
22- :type bot: cloudbot.bot.CloudBot
23- """
24- global larts , flirts , kills , slaps , north_korea , insults , strax , compliments , presents
25-
26- with codecs .open (os .path .join (bot .data_dir , "larts.txt" ), encoding = "utf-8" ) as f :
27- larts = [line .strip () for line in f .readlines () if not line .startswith ("//" )]
28-
29- with codecs .open (os .path .join (bot .data_dir , "flirts.txt" ), encoding = "utf-8" ) as f :
30- flirts = [line .strip () for line in f .readlines () if not line .startswith ("//" )]
31-
32- with codecs .open (os .path .join (bot .data_dir , "insults.txt" ), encoding = "utf-8" ) as f :
33- insults = [line .strip () for line in f .readlines () if not line .startswith ("//" )]
34-
35- with codecs .open (os .path .join (bot .data_dir , "kills.json" ), encoding = "utf-8" ) as f :
36- kills = json .load (f )
37-
38- with codecs .open (os .path .join (bot .data_dir , "slaps.json" ), encoding = "utf-8" ) as f :
39- slaps = json .load (f )
40-
41- with codecs .open (os .path .join (bot .data_dir , "strax.json" ), encoding = "utf-8" ) as f :
42- strax = json .load (f )
43-
44- with codecs .open (os .path .join (bot .data_dir , "compliments.json" ), encoding = "utf-8" ) as f :
45- compliments = json .load (f )
46-
47- with codecs .open (os .path .join (bot .data_dir , "north_korea.txt" ), encoding = "utf-8" ) as f :
48- north_korea = [line .strip () for line in f .readlines () if not line .startswith ("//" )]
49-
50- with codecs .open (os .path .join (bot .data_dir , "presents.json" ), encoding = "utf-8" ) as f :
51- presents = json .load (f )
52-
53-
54- @hook .command
55- def lart (text , conn , nick , action , is_nick_valid ):
56- """<user> - LARTs <user>"""
57- target = text .strip ()
58-
59- if not is_nick_valid (target ):
60- return "I can't lart that."
61-
62- if is_self (conn , target ):
63- # user is trying to make the bot attack itself!
64- target = nick
65-
66- phrase = random .choice (larts )
67-
68- # act out the message
69- action (phrase .format (user = target ))
70-
26+ attack_data = defaultdict (dict )
7127
72- @hook .command ("flirt" , "sexup" , "jackmeoff" )
73- def flirt (text , conn , nick , message , is_nick_valid ):
74- """<user> - flirts with <user>"""
75- target = text .strip ()
7628
77- if not is_nick_valid (target ):
78- return "I can't flirt with that."
29+ class BasicAttack :
30+ def __init__ (self , name , doc , * commands , action = None , file = None , response = RespType .ACTION , require_target = True ):
31+ self .name = name
32+ self .action = action or name
33+ self .doc = doc
34+ self .commands = commands or [name ]
35+ if file is None :
36+ file = "{}.json" .format (name )
7937
80- if is_self ( conn , target ):
81- # user is trying to make the bot attack itself!
82- target = nick
38+ self . file = file
39+ self . response = response
40+ self . require_target = require_target
8341
84- message ('{}, {}' .format (target , random .choice (flirts )))
8542
43+ ATTACKS = (
44+ BasicAttack ("lart" , "<user> - LARTs <user>" ),
45+ BasicAttack (
46+ "flirt" , "<user> - flirts with <user>" , "flirt" , "sexup" , "jackmeoff" , action = "flirt with" ,
47+ response = RespType .MESSAGE
48+ ),
49+ BasicAttack ("kill" , "<user> - kills <user>" , "kill" , "end" ),
50+ BasicAttack ("slap" , "<user> - Makes the bot slap <user>." ),
51+ BasicAttack ("compliment" , "<user> - Makes the bot compliment <user>." , response = RespType .MESSAGE ),
52+ BasicAttack (
53+ "strax" , "[user] - Generates a quote from Strax, optionally targeting [user]" , action = "attack" ,
54+ response = RespType .MESSAGE , require_target = False
55+ ),
56+ BasicAttack (
57+ "nk" , "- outputs a random North Korea propaganda slogan" , action = "target" , response = RespType .MESSAGE ,
58+ require_target = False
59+ ),
60+ BasicAttack ("insult" , "<user> - insults <user>" , response = RespType .MESSAGE ),
61+ BasicAttack ("present" , "<user> - gives gift to <user>" , action = "give a gift to" ),
62+ )
8663
87- @hook .command ("kill" , "end" )
88- def kill (text , conn , nick , action , is_nick_valid ):
89- """<user> - kills <user>"""
90- target = text .strip ()
9164
92- if not is_nick_valid (target ):
93- return "I can't attack that."
65+ def load_data (path , data_dict ):
66+ data_dict .clear ()
67+ with path .open (encoding = 'utf-8' ) as f :
68+ data_dict .update (json .load (f ))
9469
95- if is_self (conn , target ):
96- # user is trying to make the bot attack itself!
97- target = nick
9870
99- generator = textgen .TextGenerator (kills ["templates" ], kills ["parts" ], variables = {"user" : target })
100-
101- # act out the message
102- action (generator .generate_string ())
103-
104-
105- @hook .command
106- def slap (text , action , nick , conn , is_nick_valid ):
107- """<user> -- Makes the bot slap <user>."""
108- target = text .strip ()
109-
110- if not is_nick_valid (target ):
111- return "I can't slap that."
112-
113- if is_self (conn , target ):
114- # user is trying to make the bot attack itself!
115- target = nick
116-
117- variables = {
118- "user" : target
119- }
120- generator = textgen .TextGenerator (slaps ["templates" ], slaps ["parts" ], variables = variables )
121-
122- # act out the message
123- action (generator .generate_string ())
124-
125-
126- @hook .command
127- def compliment (text , nick , conn , is_nick_valid , message ):
128- """<user> -- Makes the bot compliment <user>."""
129- target = text .strip ()
130-
131- if not is_nick_valid (target ):
132- return "I can't compliment that."
133-
134- if is_self (conn , target ):
135- # user is trying to make the bot attack itself!
136- target = nick
137-
138- variables = {
139- "user" : target
140- }
141- generator = textgen .TextGenerator (compliments ["templates" ], compliments ["parts" ], variables = variables )
142-
143- # act out the message
144- message (generator .generate_string ())
71+ @hook .on_start ()
72+ def load_attacks (bot ):
73+ """
74+ :type bot: cloudbot.bot.CloudBot
75+ """
76+ attack_data .clear ()
77+ data_dir = Path (bot .data_dir ) / "attacks"
78+ for data_file in ATTACKS :
79+ load_data (data_dir / data_file .file , attack_data [data_file .name ])
14580
14681
147- @ hook . command ( autohelp = False )
148- def strax ( text , conn , message , nick , is_nick_valid ):
149- """Strax quote."""
82+ def basic_format ( text , data , ** kwargs ):
83+ user = text
84+ kwargs [ 'user' ] = user
15085
15186 if text :
152- target = text .strip ()
153- if not is_nick_valid (target ):
154- return "I can't do that."
155-
156- if is_self (conn , target ):
157- # user is trying to make the bot attack itself!
158- target = nick
159- variables = {
160- "user" : target
161- }
162-
163- generator = textgen .TextGenerator (strax ["target_template" ], strax ["parts" ], variables = variables )
87+ try :
88+ templates = data ["target_templates" ]
89+ except KeyError :
90+ templates = data ["templates" ]
16491 else :
165- generator = textgen .TextGenerator (strax ["template" ], strax ["parts" ])
166-
167- # Become Strax
168- message (generator .generate_string ())
92+ templates = data ["templates" ]
16993
94+ generator = textgen .TextGenerator (
95+ templates , data ["parts" ], variables = kwargs
96+ )
17097
171- @hook .command (autohelp = False )
172- def nk (message ):
173- """outputs a random North Korea propoganda slogan"""
174- slogan = random .choice (north_korea )
175- message (slogan )
98+ return generator .generate_string ()
17699
177100
178- @hook .command ()
179- def insult (text , conn , nick , notice , message , is_nick_valid ):
180- """<user> - insults <user>
181- :type text: str
182- :type conn: cloudbot.client.Client
183- :type nick: str
184- """
185- target = text .strip ()
101+ def basic_attack (attack ):
102+ def func (text , conn , nick , action , message , reply , is_nick_valid ):
103+ responses = {
104+ RespType .ACTION : action ,
105+ RespType .REPLY : reply ,
106+ RespType .MESSAGE : message ,
107+ }
186108
187- if not is_nick_valid (target ):
188- notice ("Invalid username!" )
189- return
109+ target = text
110+ if target :
111+ if not is_nick_valid (target ):
112+ return "I can't {action} that." .format (action = attack .action )
190113
191- # if the user is trying to make the bot target itself, target them
192- if is_self (conn , target ):
193- target = nick
114+ if is_self (conn , target ):
115+ target = nick
194116
195- message ( "{}, {}" . format (target , random . choice ( insults )) )
117+ out = basic_format (target , attack_data [ attack . name ] )
196118
119+ responses [attack .response ](out )
197120
198- @hook .command ("present" , "gift" )
199- def present (text , conn , nick , action , is_nick_valid ):
200- """<user> - gives gift to <user>"""
201- target = text .strip ()
121+ func .__name__ = attack .name
122+ func .__doc__ = attack .doc
123+ return func
202124
203- if not is_nick_valid (target ):
204- return "I can't gift that."
205125
206- if is_self ( conn , target ):
207- # user is trying to make the bot gift itself!
208- target = nick
126+ def create_basic_hooks ( ):
127+ for attack in ATTACKS :
128+ globals ()[ attack . name ] = hook . command ( * attack . commands , autohelp = attack . require_target )( basic_attack ( attack ))
209129
210- variables = {
211- "user" : target
212- }
213130
214- generator = textgen .TextGenerator (presents ["templates" ], presents ["parts" ], variables = variables )
215- action (generator .generate_string ())
131+ create_basic_hooks ()
0 commit comments