]>
Commit | Line | Data |
---|---|---|
80d02bd8 | 1 | # Erebus IRC bot - Author: Erebus Team |
c695f740 | 2 | # trivia module |
80d02bd8 | 3 | # This file is released into the public domain; see http://unlicense.org/ |
4 | ||
c695f740 | 5 | #TODO: |
6 | # timers (stop game/skip question/hinting) | |
7 | # bonus points | |
8 | # ability to REDUCE users points | |
9 | # dynamic questions | |
10 | # v2 | |
11 | # team play | |
12 | # statistics | |
13 | ||
80d02bd8 | 14 | # module info |
15 | modinfo = { | |
16 | 'author': 'Erebus Team', | |
17 | 'license': 'public domain', | |
18 | 'compatible': [1], # compatible module API versions | |
19 | 'depends': [], # other modules required to work properly? | |
20 | } | |
21 | ||
22 | # preamble | |
23 | import modlib | |
24 | lib = modlib.modlib(__name__) | |
25 | def modstart(parent, *args, **kwargs): | |
9557ee54 | 26 | state.parent = parent |
80d02bd8 | 27 | return lib.modstart(parent, *args, **kwargs) |
28 | def modstop(*args, **kwargs): | |
29 | global state | |
30 | del state | |
31 | return lib.modstop(*args, **kwargs) | |
32 | ||
33 | # module code | |
34 | import json, random | |
35 | ||
36 | class TriviaState(object): | |
9557ee54 | 37 | def __init__(self, questionfile): |
80d02bd8 | 38 | self.questionfile = questionfile |
39 | self.db = json.load(open(questionfile, "r")) | |
9557ee54 | 40 | self.chan = self.db['chan'] |
41 | self.curq = None | |
c695f740 | 42 | self.nextq = None |
80d02bd8 | 43 | |
44 | def __del__(self): | |
c695f740 | 45 | if json is not None and json.dump is not None: |
46 | json.dump(self.db, open(self.questionfile, "w"), indent=4, separators=(',',': ')) | |
80d02bd8 | 47 | |
48 | def nextquestion(self): | |
c695f740 | 49 | if state.nextq is not None: |
50 | nextq = state.nextq | |
51 | self.curq = nextq | |
52 | state.nextq = None | |
53 | else: | |
54 | nextq = random.choice(self.db['questions']) | |
55 | self.curq = nextq | |
56 | ||
57 | qtext = "\00300,01Next up: " | |
58 | qary = nextq['question'].split(None) | |
59 | for qword in qary: | |
60 | qtext += "\00300,01"+qword+"\00301,01"+chr(random.randrange(32,126)) | |
61 | self.parent.channel(self.chan).bot.msg(self.chan, qtext) | |
80d02bd8 | 62 | |
63 | def checkanswer(self, answer): | |
9557ee54 | 64 | if self.curq is None: |
65 | return False | |
66 | elif isinstance(self.curq['answer'], basestring): | |
80d02bd8 | 67 | return answer.lower() == self.curq['answer'] |
68 | else: # assume it's a list or something. | |
69 | return answer.lower() in self.curq['answer'] | |
70 | ||
71 | def addpoint(self, _user, count=1): | |
9557ee54 | 72 | _user = str(_user) |
80d02bd8 | 73 | user = _user.lower() |
74 | if user in self.db['users']: | |
75 | self.db['users'][user]['points'] += count | |
76 | else: | |
77 | self.db['users'][user] = {'points': count, 'realnick': _user, 'rank': len(self.db['ranks'])} | |
9557ee54 | 78 | self.db['ranks'].append(user) |
80d02bd8 | 79 | |
80 | oldrank = self.db['users'][user]['rank'] | |
81 | while oldrank != 0: | |
82 | nextperson = self.db['ranks'][oldrank-1] | |
83 | if self.db['users'][user]['points'] > self.db['users'][nextperson]['points']: | |
84 | self.db['ranks'][oldrank-1] = user | |
c695f740 | 85 | self.db['users'][user]['rank'] = oldrank-1 |
80d02bd8 | 86 | self.db['ranks'][oldrank] = nextperson |
c695f740 | 87 | self.db['users'][nextperson]['rank'] = oldrank |
80d02bd8 | 88 | oldrank = oldrank-1 |
89 | else: | |
90 | break | |
91 | return self.db['users'][user]['points'] | |
92 | ||
93 | def points(self, user): | |
9557ee54 | 94 | user = str(user).lower() |
80d02bd8 | 95 | if user in self.db['users']: |
96 | return self.db['users'][user]['points'] | |
97 | else: | |
98 | return 0 | |
99 | ||
100 | def rank(self, user): | |
c695f740 | 101 | user = str(user).lower() |
102 | return self.db['users'][user]['rank']+1 | |
80d02bd8 | 103 | |
c695f740 | 104 | def targetuser(self, user): |
105 | user = str(user).lower() | |
106 | rank = self.db['users'][user]['rank'] | |
107 | if rank == 0: | |
108 | return "you're in the lead!" | |
109 | else: | |
110 | return self.db['ranks'][rank-1] | |
111 | def targetpoints(self, user): | |
112 | user = str(user).lower() | |
113 | rank = self.db['users'][user]['rank'] | |
114 | if rank == 0: | |
115 | return "N/A" | |
116 | else: | |
117 | return self.db['users'][self.db['ranks'][rank-1]]['points'] | |
80d02bd8 | 118 | |
c695f740 | 119 | state = TriviaState("/home/jrunyon/erebus/modules/trivia.json") #TODO get path from config |
9557ee54 | 120 | |
80d02bd8 | 121 | @lib.hookchan(state.db['chan']) |
122 | def trivia_checkanswer(bot, user, chan, *args): | |
80d02bd8 | 123 | line = ' '.join([str(arg) for arg in args]) |
124 | if state.checkanswer(line): | |
c695f740 | 125 | bot.msg(chan, "\00308%s\003 has it! The answer was \00308%s\003. Current points: %d. Rank: %d. Target: %s (%s)." % (user, line, state.addpoint(user), state.rank(user), state.targetuser(user), state.targetpoints(user))) |
9557ee54 | 126 | state.nextquestion() |
80d02bd8 | 127 | |
128 | @lib.hook('points') | |
129 | def cmd_points(bot, user, chan, realtarget, *args): | |
c695f740 | 130 | if chan == realtarget: replyto = chan |
80d02bd8 | 131 | else: replyto = user |
132 | ||
133 | if len(args) != 0: who = args[0] | |
134 | else: who = user | |
135 | ||
136 | bot.msg(replyto, "%s has %d points." % (who, state.points(who))) | |
137 | ||
138 | @lib.hook('give', clevel=lib.OP) | |
139 | @lib.argsGE(1) | |
140 | def cmd_give(bot, user, chan, realtarget, *args): | |
80d02bd8 | 141 | whoto = args[0] |
c695f740 | 142 | if len(args) > 1: |
143 | numpoints = int(args[1]) | |
144 | else: | |
145 | numpoints = 1 | |
146 | balance = state.addpoint(whoto, numpoints) | |
147 | bot.msg(chan, "%s gave %s %d points. New balance: %d" % (user, whoto, numpoints, balance)) | |
148 | ||
149 | @lib.hook('setnext', clevel=lib.OP) | |
150 | @lib.argsGE(1) | |
151 | def cmd_setnext(bot, user, chan, realtarget, *args): | |
152 | line = ' '.join([str(arg) for arg in args]) | |
153 | linepieces = line.split('*') | |
154 | question = linepieces[0].strip() | |
155 | answer = linepieces[1].strip() | |
156 | state.nextq = {'question':question,'answer':answer} | |
157 | bot.msg(user, "Done.") | |
158 | ||
159 | @lib.hook('skip', clevel=lib.KNOWN) | |
160 | def cmd_skip(bot, user, chan, realtarget, *args): | |
161 | state.nextquestion() | |
162 | ||
163 | @lib.hook('start') | |
164 | def cmd_start(bot, user, chan, realtarget, *args): | |
165 | if chan == realtarget: replyto = chan | |
166 | else: replyto = user | |
167 | ||
168 | if state.curq is None: | |
169 | state.nextquestion() | |
170 | else: | |
171 | bot.msg(replyto, "Game is already started!") | |
172 | ||
173 | @lib.hook('stop', clevel=lib.KNOWN) | |
174 | def cmd_stop(bot, user, chan, realtarget, *args): | |
175 | if chan == realtarget: replyto = chan | |
176 | else: replyto = user | |
177 | ||
178 | if state.curq is not None: | |
179 | state.curq = None | |
180 | bot.msg(chan, "Game ended by %s" % (user)) | |
181 | else: | |
182 | bot.msg(replyto, "Game isn't running.") | |
80d02bd8 | 183 | |
184 | @lib.hook('rank') | |
80d02bd8 | 185 | def cmd_rank(bot, user, chan, realtarget, *args): |
c695f740 | 186 | if chan == realtarget: replyto = chan |
80d02bd8 | 187 | else: replyto = user |
188 | ||
c695f740 | 189 | if len(args) != 0: who = args[0] |
190 | else: who = user | |
191 | ||
192 | bot.msg(replyto, "%s is in %d place." % (who, state.rank(who))) |