]> jfr.im git - erebus.git/blame - modules/trivia.py
fix bug where modules cant be loaded after being unloaded
[erebus.git] / modules / trivia.py
CommitLineData
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
15modinfo = {
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
23import modlib
24lib = modlib.modlib(__name__)
25def modstart(parent, *args, **kwargs):
9557ee54 26 state.parent = parent
80d02bd8 27 return lib.modstart(parent, *args, **kwargs)
28def modstop(*args, **kwargs):
29 global state
30 del state
31 return lib.modstop(*args, **kwargs)
32
33# module code
34import json, random
35
36class 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 119state = TriviaState("/home/jrunyon/erebus/modules/trivia.json") #TODO get path from config
9557ee54 120
80d02bd8 121@lib.hookchan(state.db['chan'])
122def 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')
129def 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)
140def 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)
151def 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)
160def cmd_skip(bot, user, chan, realtarget, *args):
161 state.nextquestion()
162
163@lib.hook('start')
164def 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)
174def 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 185def 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)))