X-Git-Url: https://jfr.im/git/erebus.git/blobdiff_plain/9306587e2bc53a85c44f9785bb227917e59a0269..36411de919ae2db1ff5b5376e11739c464cec7ae:/modules/trivia.py diff --git a/modules/trivia.py b/modules/trivia.py index b352f51..7dd460c 100644 --- a/modules/trivia.py +++ b/modules/trivia.py @@ -49,6 +49,7 @@ class TriviaState(object): self.chan = self.db['chan'] self.curq = None self.nextq = None + self.nextquestiontimer = None self.steptimer = None self.hintstr = None self.hintanswer = None @@ -72,8 +73,12 @@ class TriviaState(object): def __del__(self): self.closeshop() def closeshop(self): - if threading is not None and threading._Timer is not None and isinstance(self.steptimer, threading._Timer): - self.steptimer.cancel() + if threading is not None and threading._Timer is not None: + if isinstance(self.steptimer, threading._Timer): + self.steptimer.cancel() + if isinstance(self.nextquestiontimer, threading._Timer): + self.nextquestiontimer.cancel() + self.nextquestiontimer = None if json is not None and json.dump is not None: json.dump(self.db, open(self.questionfile, "w"))#, indent=4, separators=(',', ': ')) @@ -185,7 +190,7 @@ class TriviaState(object): self.nextquestion() #start the game! - def nextquestion(self, qskipped=False, iteration=0): + def nextquestion(self, qskipped=False, iteration=0, skipwait=False): if self.gameover == True: return self.doGameOver() if qskipped: @@ -193,9 +198,14 @@ class TriviaState(object): self.missedquestions += 1 else: self.missedquestions = 0 + if 'topicformat' in self.db and self.db['topicformat'] is not None: + self.getbot().conn.send("TOPIC %s" % (self.db['chan'])) if isinstance(self.steptimer, threading._Timer): self.steptimer.cancel() + if isinstance(self.nextquestiontimer, threading._Timer): + self.nextquestiontimer.cancel() + self.nextquestiontimer = None self.hintstr = None self.hintsgiven = 0 @@ -206,31 +216,43 @@ class TriviaState(object): stop() self.getbot().msg(self.getchan(), "%d questions unanswered! Stopping the game.") - if state.nextq is not None: - nextq = state.nextq - state.nextq = None + if skipwait: + self._nextquestion(qskipped, iteration) + else: + print "making timer" + self.nextquestiontimer = threading.Timer(self.db['questionpause'], self._nextquestion, args=[qskipped, iteration]) + self.nextquestiontimer.start() + + def _nextquestion(self, qskipped, iteration): + print "_" + if self.nextq is not None: + nextq = self.nextq + self.nextq = None else: nextq = random.choice(self.db['questions']) - if nextq['question'][0] == "!": + if nextq[0][0] == "!": nextq = specialQuestion(nextq) - if iteration < 10 and 'lastasked' in nextq and nextq['lastasked'] - time.time() < 24*60*60: - return self.nextquestion(iteration=iteration+1) #short-circuit to pick another question - nextq['lastasked'] = time.time() + if len(nextq) > 2 and nextq[2] - time.time() < 7*24*60*60 and iteration < 10: + return self._nextquestion(iteration=iteration+1) #short-circuit to pick another question + if len(nextq) > 2: + nextq[2] = time.time() + else: + nextq.append(time.time()) - nextq['answer'] = nextq['answer'].lower() + nextq[1] = nextq[1].lower() qtext = "\00304,01Next up: " - qary = nextq['question'].split(None) + qary = nextq[0].split(None) for qword in qary: qtext += "\00304,01"+qword+"\00301,01"+chr(random.randrange(0x61,0x7A)) #a-z self.getbot().msg(self.chan, qtext) self.curq = nextq - if isinstance(self.curq['answer'], basestring): self.hintanswer = self.curq['answer'] - else: self.hintanswer = random.choice(self.curq['answer']) + if isinstance(self.curq[1], basestring): self.hintanswer = self.curq[1] + else: self.hintanswer = random.choice(self.curq[1]) self.steptimer = threading.Timer(self.db['hinttimer'], self.nexthint, args=[1]) self.steptimer.start() @@ -238,10 +260,10 @@ class TriviaState(object): def checkanswer(self, answer): if self.curq is None: return False - elif isinstance(self.curq['answer'], basestring): - return answer.lower() == self.curq['answer'] + elif isinstance(self.curq[1], basestring): + return answer.lower() == self.curq[1] else: # assume it's a list or something. - return answer.lower() in self.curq['answer'] + return answer.lower() in self.curq[1] def addpoint(self, user_obj, count=1): user_nick = str(user_obj) @@ -252,12 +274,12 @@ class TriviaState(object): self.db['users'][user] = {'points': count, 'realnick': user_nick, 'rank': len(self.db['ranks'])} self.db['ranks'].append(user) - self.db['ranks'].sort(key=lambda nick: state.db['users'][nick]['points'], reverse=True) #re-sort ranks, rather than dealing with anything more efficient + self.db['ranks'].sort(key=lambda nick: self.db['users'][nick]['points'], reverse=True) #re-sort ranks, rather than dealing with anything more efficient for i in range(0, len(self.db['ranks'])): nick = self.db['ranks'][i] self.db['users'][nick]['rank'] = i - if self.db['users'][user]['points'] >= state.db['target']: + if self.db['users'][user]['points'] >= self.db['target']: self.gameover = True return self.db['users'][user]['points'] @@ -339,7 +361,7 @@ def cmd_setnextid(bot, user, chan, realtarget, *args): try: qid = int(args[0]) state.nextq = state.db['questions'][qid] - bot.msg(user, "Done. Next question is: %s" % (state.nextq['question'])) + bot.msg(user, "Done. Next question is: %s" % (state.nextq[0])) except Exception as e: bot.msg(user, "Error: %s" % (e)) @@ -353,20 +375,20 @@ def cmd_setnext(bot, user, chan, realtarget, *args): return question = linepieces[0].strip() answer = linepieces[1].strip() - state.nextq = {'question':question,'answer':answer} + state.nextq = [question, answer] bot.msg(user, "Done.") @lib.hook('skip', glevel=1, needchan=False) def cmd_skip(bot, user, chan, realtarget, *args): - state.nextquestion(True) + state.nextquestion(qskipped=True, skipwait=True) @lib.hook('start', needchan=False) def cmd_start(bot, user, chan, realtarget, *args): if chan == realtarget: replyto = chan else: replyto = user - if state.curq is None and state.pointvote is None: - state.nextquestion() + if state.curq is None and state.pointvote is None and state.nextquestiontimer is None: + state.nextquestion(skipwait=True) elif state.pointvote is not None: bot.msg(replyto, "There's a vote in progress!") else: @@ -387,6 +409,11 @@ def stop(): state.steptimer.cancel() except Exception as e: print "!!! steptimer.cancel(): %s %r" % (e,e) + try: + state.nextquestiontimer.cancel() + state.nextquestiontimer = None + except Exception as e: + print "!!! nextquestiontimer.cancel(): %s %r" % (e,e) return True else: return False @@ -463,9 +490,17 @@ def cmd_hintnum(bot, user, chan, realtarget, *args): except: bot.msg(user, "Failed to set hintnum.") +@lib.hook('questionpause', glevel=lib.ADMIN, needchan=False) +def cmd_questionpause(bot, user, chan, realtarget, *args): + try: + state.db['questionpause'] = float(args[0]) + bot.msg(state.db['chan'], "Pause between questions has been changed to %s." % (state.db['questionpause'])) + except: + bot.msg(user, "Failed to set questionpause.") + @lib.hook('findq', glevel=1, needchan=False) def cmd_findquestion(bot, user, chan, realtarget, *args): - matches = [str(i) for i in range(len(state.db['questions'])) if state.db['questions'][i]['question'] == ' '.join(args)] #TODO looser equality check + matches = [str(i) for i in range(len(state.db['questions'])) if state.db['questions'][i][0] == ' '.join(args)] #TODO looser equality check if len(matches) > 1: bot.msg(user, "Multiple matches: %s" % (', '.join(matches))) elif len(matches) == 1: @@ -479,7 +514,7 @@ def cmd_deletequestion(bot, user, chan, realtarget, *args): try: backup = state.db['questions'][int(args[0])] del state.db['questions'][int(args[0])] - bot.msg(user, "Deleted %s*%s" % (backup['question'], backup['answer'])) + bot.msg(user, "Deleted %s*%s" % (backup[0], backup[1])) except: bot.msg(user, "Couldn't delete that question.") @@ -492,7 +527,7 @@ def cmd_addquestion(bot, user, chan, realtarget, *args): return question = linepieces[0].strip() answer = linepieces[1].strip() - state.db['questions'].append({'question':question,'answer':answer}) + state.db['questions'].append([question, answer]) bot.msg(user, "Done. Question is #%s" % (len(state.db['questions'])-1)) @@ -501,46 +536,65 @@ def cmd_triviahelp(bot, user, chan, realtarget, *args): if user.glevel == 0: bot.msg(user, "START") bot.msg(user, "TOP10") - bot.msg(user, "POINTS []") - bot.msg(user, "RANK []") + bot.msg(user, "POINTS []") + bot.msg(user, "RANK []") else: - bot.msg(user, "START (ANYONE )") - bot.msg(user, "TOP10 (ANYONE )") - bot.msg(user, "POINTS [] (ANYONE )") - bot.msg(user, "RANK [] (ANYONE )") + bot.msg(user, "START (ANYONE )") + bot.msg(user, "TOP10 (ANYONE )") + bot.msg(user, "POINTS [] (ANYONE )") + bot.msg(user, "RANK [] (ANYONE )") if user.glevel >= 1: - bot.msg(user, "SKIP (>=KNOWN)") - bot.msg(user, "STOP (>=KNOWN)") - bot.msg(user, "FINDQ (>=KNOWN)") + bot.msg(user, "SKIP (>=KNOWN)") + bot.msg(user, "STOP (>=KNOWN)") + bot.msg(user, "FINDQ (>=KNOWN)") if user.glevel >= lib.STAFF: - bot.msg(user, "GIVE [] (>=STAFF)") - bot.msg(user, "SETNEXT * (>=STAFF)") - bot.msg(user, "ADDQ * (>=STAFF)") - bot.msg(user, "DELETEQ * (>=STAFF) [aka DELQ]") + bot.msg(user, "GIVE [] (>=STAFF)") + bot.msg(user, "SETNEXT * (>=STAFF)") + bot.msg(user, "ADDQ * (>=STAFF)") + bot.msg(user, "DELETEQ * (>=STAFF) [aka DELQ]") if user.glevel >= lib.ADMIN: - bot.msg(user, "SETTARGET (>=ADMIN)") - bot.msg(user, "MAXMISSED (>=ADMIN)") - bot.msg(user, "HINTTIMER (>=ADMIN)") - bot.msg(user, "HINTNUM (>=ADMIN)") + bot.msg(user, "SETTARGET (>=ADMIN)") + bot.msg(user, "MAXMISSED (>=ADMIN)") + bot.msg(user, "HINTTIMER (>=ADMIN)") + bot.msg(user, "HINTNUM (>=ADMIN)") + bot.msg(user, "QUESTIONPAUSE (>=ADMIN)") @lib.hooknum(417) def num_417(bot, textline): bot.msg(state.db['chan'], "Whoops, it looks like that question didn't quite go through! (E:417). Let's try another...") - state.nextquestion(False) + state.nextquestion(qskipped=False, skipwait=True) + +@lib.hooknum(332) +def num_TOPIC(bot, textline): + pieces = textline.split(None, 4) + chan = pieces[3] + if chan != state.db['chan']: + return + gottopic = pieces[4][1:] + + formatted = state.db['topicformat'] % { + 'chan': state.db['chan'], + 'top': state.db['users'][state.db['ranks'][0]]['realnick'], + 'top3': '/'.join([state.db['users'][state.db['ranks'][x]]['realnick'] for x in range(3) if x < len(state.db['ranks'])]), + 'topscore': state.db['users'][state.db['ranks'][0]]['points'], + 'target': state.db['target'], + } + if gottopic != formatted: + state.getbot().conn.send("TOPIC %s :%s" % (state.db['chan'], formatted)) def specialQuestion(oldq): - newq = {'question': oldq['question'], 'answer': oldq['answer']} - qtype = oldq['question'].upper() + newq = [oldq[0], oldq[1]] + qtype = oldq[0].upper() if qtype == "!MONTH": - newq['question'] = "What month is it currently (in UTC)?" - newq['answer'] = time.strftime("%B", time.gmtime()).lower() + newq[0] = "What month is it currently (in UTC)?" + newq[1] = time.strftime("%B", time.gmtime()).lower() elif qtype == "!MATH+": randnum1 = random.randrange(0, 11) randnum2 = random.randrange(0, 11) - newq['question'] = "What is %d + %d?" % (randnum1, randnum2) - newq['answer'] = spellout(randnum1+randnum2) + newq[0] = "What is %d + %d?" % (randnum1, randnum2) + newq[1] = spellout(randnum1+randnum2) return newq def spellout(num):