From 0a5671b4026991a8c36e1eda13c1c25d7e64fb06 Mon Sep 17 00:00:00 2001 From: Giuseppe Bilotta Date: Thu, 11 Jan 2007 15:39:15 +0000 Subject: The quiz scores databases can get corrupt sometimes. Until we find how and why, we just prevent further changes to them when we spot one --- data/rbot/plugins/quiz.rb | 174 +++++++++++++++++++++++++++++++++------------- 1 file changed, 127 insertions(+), 47 deletions(-) diff --git a/data/rbot/plugins/quiz.rb b/data/rbot/plugins/quiz.rb index 67cd15b8..72e10aa9 100644 --- a/data/rbot/plugins/quiz.rb +++ b/data/rbot/plugins/quiz.rb @@ -29,7 +29,7 @@ Bold = "\002" ####################################################################### class Quiz attr_accessor :registry, :registry_conf, :questions, :question, :answer, :answer_core, - :first_try, :hint, :hintrange, :rank_table, :hinted + :first_try, :hint, :hintrange, :rank_table, :hinted, :has_errors? def initialize( channel, registry ) if channel.empty? @@ -37,6 +37,17 @@ class Quiz else @registry = registry.sub_registry( channel ) end + @has_errors = false + @registry.each_key { |k| + unless @registry.has_key?(k) + @has_errors = true + error "Data for #{k} is NOT ACCESSIBLE! Database corrupt?" + end + } + if @has_errors + debug @registry.to_a.map { |a| a.join(", ")}.join("\n") + end + @registry_conf = @registry.sub_registry( "config" ) # Per-channel copy of the global questions table. Acts like a shuffled queue @@ -174,12 +185,21 @@ class QuizPlugin < Plugin @quizzes[channel] = Quiz.new( channel, @registry ) end - return @quizzes[channel] + if @quizzes[channel].has_errors + return nil + else + return @quizzes[channel] + end end def say_score( m, nick ) - q = create_quiz( m.channel.to_s ) + chan = m.channel.downcase + q = create_quiz( chan ) + if q.nil? + m.reply "Sorry, the quiz database for #{chan} seems to be corrupt" + return + end if q.registry.has_key?( nick ) score = q.registry[nick].score @@ -264,35 +284,39 @@ class QuizPlugin < Plugin # def listen( m ) return unless m.kind_of?(PrivMessage) - return unless @quizzes.has_key?( m.channel.to_s ) - q = @quizzes[m.channel.to_s] + + chan = m.channel.downcase + return unless @quizzes.has_key?( chan ) + q = @quizzes[chan] return if q.question == nil message = m.message.downcase.strip + nick = m.sourcenick.to_s + if message == q.answer.downcase or message == q.answer_core.downcase points = 1 if q.first_try points += 1 - reply = "WHOPEEE! #{m.sourcenick.to_s} got it on the first try! That's worth an extra point. Answer was: #{q.answer}" - elsif q.rank_table.length >= 1 and m.sourcenick.to_s == q.rank_table[0][0] - reply = "THE QUIZ CHAMPION defends his throne! Seems like #{m.sourcenick.to_s} is invicible! Answer was: #{q.answer}" - elsif q.rank_table.length >= 2 and m.sourcenick.to_s == q.rank_table[1][0] - reply = "THE SECOND CHAMPION is on the way up! Hurry up #{m.sourcenick.to_s}, you only need #{q.rank_table[0][1].score - q.rank_table[1][1].score - 1} points to beat the king! Answer was: #{q.answer}" - elsif q.rank_table.length >= 3 and m.sourcenick.to_s == q.rank_table[2][0] - reply = "THE THIRD CHAMPION strikes again! Give it all #{m.sourcenick.to_s}, with #{q.rank_table[1][1].score - q.rank_table[2][1].score - 1} more points you'll reach the 2nd place! Answer was: #{q.answer}" + reply = "WHOPEEE! #{nick} got it on the first try! That's worth an extra point. Answer was: #{q.answer}" + elsif q.rank_table.length >= 1 and nick == q.rank_table[0][0] + reply = "THE QUIZ CHAMPION defends his throne! Seems like #{nick} is invicible! Answer was: #{q.answer}" + elsif q.rank_table.length >= 2 and nick == q.rank_table[1][0] + reply = "THE SECOND CHAMPION is on the way up! Hurry up #{nick}, you only need #{q.rank_table[0][1].score - q.rank_table[1][1].score - 1} points to beat the king! Answer was: #{q.answer}" + elsif q.rank_table.length >= 3 and nick == q.rank_table[2][0] + reply = "THE THIRD CHAMPION strikes again! Give it all #{nick}, with #{q.rank_table[1][1].score - q.rank_table[2][1].score - 1} more points you'll reach the 2nd place! Answer was: #{q.answer}" else reply = @win_messages[rand( @win_messages.length )].dup - reply.gsub!( "", m.sourcenick ) + reply.gsub!( "", nick ) reply.gsub!( "", q.answer ) end m.reply reply player = nil - if q.registry.has_key?( m.sourcenick.to_s ) - player = q.registry[m.sourcenick.to_s] + if q.registry.has_key?(nick) + player = q.registry[nick] else player = PlayerStats.new( 0, 0, 0 ) end @@ -305,8 +329,8 @@ class QuizPlugin < Plugin m.reply "#{m.sourcenick.to_s} gains a new joker. Rejoice :)" end - q.registry[m.sourcenick.to_s] = player - calculate_ranks( m, q, m.sourcenick.to_s ) + q.registry[nick] = player + calculate_ranks( m, q, nick) q.question = nil cmd_quiz( m, nil ) if q.registry_conf["autoask"] @@ -338,6 +362,10 @@ class QuizPlugin < Plugin def cmd_quiz( m, params ) fetch_data( m ) if @questions.empty? q = create_quiz( m.channel.to_s ) + if q.nil? + m.reply "Sorry, the quiz database for #{chan} seems to be corrupt" + return + end if q.question m.reply "#{Bold}#{Color}03Current question: #{Color}#{Bold}#{q.question}" @@ -393,8 +421,10 @@ class QuizPlugin < Plugin def cmd_solve( m, params ) - return unless @quizzes.has_key?( m.channel.to_s ) - q = @quizzes[m.channel.to_s] + chan = m.channel.to_s + + return unless @quizzes.has_key?( chan ) + q = @quizzes[chan] m.reply "The correct answer was: #{q.answer}" @@ -405,11 +435,14 @@ class QuizPlugin < Plugin def cmd_hint( m, params ) - return unless @quizzes.has_key?( m.channel.to_s ) - q = @quizzes[m.channel.to_s] + chan = m.channel.downcase + nick = m.sourcenick.to_s + + return unless @quizzes.has_key?(chan) + q = @quizzes[chan] if q.question == nil - m.reply "#{m.sourcenick.to_s}: Get a question first!" + m.reply "#{nick}: Get a question first!" else num_chars = case q.hintrange.length # Number of characters to reveal when 25..1000 then 7 @@ -432,19 +465,19 @@ class QuizPlugin < Plugin q.hinted = true if q.hint == q.answer_core - m.reply "#{Bold}#{Color}04BUST!#{Color}#{Bold} This round is over. #{Color}04Minus one point for #{m.sourcenick.to_s}#{Color}." + m.reply "#{Bold}#{Color}04BUST!#{Color}#{Bold} This round is over. #{Color}04Minus one point for #{nick}#{Color}." stats = nil - if q.registry.has_key?( m.sourcenick.to_s ) - stats = q.registry[m.sourcenick.to_s] + if q.registry.has_key?( nick ) + stats = q.registry[nick] else stats = PlayerStats.new( 0, 0, 0 ) end stats["score"] = stats.score - 1 - q.registry[m.sourcenick.to_s] = stats + q.registry[nick] = stats - calculate_ranks( m, q, m.sourcenick.to_s ) + calculate_ranks( m, q, nick) q.question = nil cmd_quiz( m, nil ) if q.registry_conf["autoask"] @@ -454,8 +487,9 @@ class QuizPlugin < Plugin def cmd_skip( m, params ) - return unless @quizzes.has_key?( m.channel.to_s ) - q = @quizzes[m.channel.to_s] + chan = m.channel.downcase + return unless @quizzes.has_key?(chan) + q = @quizzes[chan] q.question = nil cmd_quiz( m, params ) @@ -463,33 +497,39 @@ class QuizPlugin < Plugin def cmd_joker( m, params ) - q = create_quiz( m.channel.to_s ) + chan = m.channel.downcase + nick = m.sourcenick.to_s + q = create_quiz(chan) + if q.nil? + m.reply "Sorry, the quiz database for #{chan} seems to be corrupt" + return + end if q.question == nil - m.reply "#{m.sourcenick.to_s}: There is no open question." + m.reply "#{nick}: There is no open question." return end - if q.registry[m.sourcenick.to_s].jokers > 0 - player = q.registry[m.sourcenick.to_s] + if q.registry[nick].jokers > 0 + player = q.registry[nick] player.jokers -= 1 player.score += 1 - q.registry[m.sourcenick.to_s] = player + q.registry[nick] = player - calculate_ranks( m, q, m.sourcenick.to_s ) + calculate_ranks( m, q, nick ) if player.jokers != 1 jokers = "jokers" else jokers = "joker" end - m.reply "#{Bold}#{Color}12JOKER!#{Color}#{Bold} #{m.sourcenick.to_s} draws a joker and wins this round. You have #{player.jokers} #{jokers} left." + m.reply "#{Bold}#{Color}12JOKER!#{Color}#{Bold} #{nick} draws a joker and wins this round. You have #{player.jokers} #{jokers} left." m.reply "The answer was: #{q.answer}." q.question = nil cmd_quiz( m, nil ) if q.registry_conf["autoask"] else - m.reply "#{m.sourcenick.to_s}: You don't have any jokers left ;(" + m.reply "#{nick}: You don't have any jokers left ;(" end end @@ -500,13 +540,19 @@ class QuizPlugin < Plugin def cmd_top5( m, params ) - q = create_quiz( m.channel.to_s ) + chan = m.channel.downcase + q = create_quiz( chan ) + if q.nil? + m.reply "Sorry, the quiz database for #{chan} seems to be corrupt" + return + end + if q.rank_table.empty? m.reply "There are no scores known yet!" return end - m.reply "* Top 5 Players for #{m.channel.to_s}:" + m.reply "* Top 5 Players for #{chan}:" [5, q.rank_table.length].min.times do |i| player = q.rank_table[i] @@ -520,14 +566,20 @@ class QuizPlugin < Plugin def cmd_top_number( m, params ) num = params[:number].to_i return unless 1..50 === num - q = create_quiz( m.channel.to_s ) + chan = m.channel.downcase + q = create_quiz( chan ) + if q.nil? + m.reply "Sorry, the quiz database for #{chan} seems to be corrupt" + return + end + if q.rank_table.empty? m.reply "There are no scores known yet!" return end ar = [] - m.reply "* Top #{num} Players for #{m.channel.to_s}:" + m.reply "* Top #{num} Players for #{chan}:" n = [ num, q.rank_table.length ].min n.times do |i| player = q.rank_table[i] @@ -548,7 +600,8 @@ class QuizPlugin < Plugin def cmd_score( m, params ) - say_score( m, m.sourcenick.to_s ) + nick = m.sourcenick.to_s + say_score( m, nick ) end @@ -558,7 +611,12 @@ class QuizPlugin < Plugin def cmd_autoask( m, params ) - q = create_quiz( m.channel.to_s ) + chan = m.channel.downcase + q = create_quiz( chan ) + if q.nil? + m.reply "Sorry, the quiz database for #{chan} seems to be corrupt" + return + end if params[:enable].downcase == "on" q.registry_conf["autoask"] = true @@ -574,7 +632,12 @@ class QuizPlugin < Plugin def cmd_transfer( m, params ) - q = create_quiz( m.channel.to_s ) + chan = m.channel.downcase + q = create_quiz( chan ) + if q.nil? + m.reply "Sorry, the quiz database for #{chan} seems to be corrupt" + return + end debug q.rank_table.inspect @@ -627,7 +690,13 @@ class QuizPlugin < Plugin def cmd_del_player( m, params ) - q = create_quiz( m.channel.to_s ) + chan = m.channel.downcase + q = create_quiz( chan ) + if q.nil? + m.reply "Sorry, the quiz database for #{chan} seems to be corrupt" + return + end + debug q.rank_table.inspect nick = params[:nick] @@ -662,7 +731,12 @@ class QuizPlugin < Plugin def cmd_set_score(m, params) - q = create_quiz( m.channel.to_s ) + chan = m.channel.downcase + q = create_quiz( chan ) + if q.nil? + m.reply "Sorry, the quiz database for #{chan} seems to be corrupt" + return + end debug q.rank_table.inspect nick = params[:nick] @@ -680,7 +754,13 @@ class QuizPlugin < Plugin def cmd_set_jokers(m, params) - q = create_quiz( m.channel.to_s ) + chan = m.channel.downcase + q = create_quiz( chan ) + if q.nil? + m.reply "Sorry, the quiz database for #{chan} seems to be corrupt" + return + end + debug q.rank_table.inspect nick = params[:nick] val = [params[:jokers].to_i, Max_Jokers].min -- cgit v1.2.3