Ver código fonte

Better SQl rules, improved reporting, improved coin states and added to xp and karma

tBKwtWS 7 anos atrás
pai
commit
d0806cd41c
6 arquivos alterados com 75 adições e 18 exclusões
  1. 4 4
      database.schema.sql
  2. 5 2
      irc/bot.py
  3. 23 3
      irc/commands/common.py
  4. 29 7
      irc/commands/games.py
  5. 10 2
      irc/events/common.py
  6. 4 0
      irc/events/on_join.py

+ 4 - 4
database.schema.sql

@@ -506,21 +506,21 @@ ALTER TABLE ONLY users
 -- new stuff
 
 CREATE RULE update_username AS ON UPDATE TO users WHERE OLD.name <> NEW.name DO INSTEAD (
-    INSERT INTO users (name, network, last_act_type, last_act_datetime, last_act_channel, last_act_channel_network, last_act, last_act_auxiliary, away, away_reason, xp_spent, level, coin) VALUES (NEW.name, NEW.network, NEW.last_act_type, NEW.last_act_datetime, NEW.last_act_channel, NEW.last_act_channel_network, NEW.last_act, NEW.last_act_auxiliary, NEW.away, NEW.away_reason, NEW.xp_spent, NEW.level, NEW.coin);
+    INSERT INTO users (id, name, network, last_act_type, last_act_datetime, last_act_channel, last_act_channel_network, last_act, last_act_auxiliary, away, away_reason, xp_spent, level, coin, coin_spent, coin_given) VALUES (NEW.id, NEW.name, NEW.network, NEW.last_act_type, NEW.last_act_datetime, NEW.last_act_channel, NEW.last_act_channel_network, NEW.last_act, NEW.last_act_auxiliary, NEW.away, NEW.away_reason, NEW.xp_spent, NEW.level, NEW.coin, NEW.coin_spent, NEW.coin_given);
     UPDATE joins SET "user"=NEW.name WHERE "user"=OLD.name AND user_network=OLD.network;
     UPDATE kicks SET "user"=NEW.name WHERE "user"=OLD.name AND user_network=OLD.network;
     UPDATE messages SET "user"=NEW.name WHERE "user"=OLD.name AND user_network=OLD.network;
-    DELETE FROM users WHERE name=OLD.name AND network=OLD.network;
+    DELETE FROM users WHERE id=OLD.id;
 );
     
 
 CREATE RULE update_channel_name AS ON UPDATE TO channels WHERE OLD.name <> NEW.name DO INSTEAD (
-    INSERT INTO channels (name, network, autojoin, join_greeting, statistics_commands, games, aggressiveness, chat, key, last_lame) VALUES (NEW.name, NEW.network, NEW.autojoin, NEW.join_greeting, NEW.statistics_commands, NEW.games, NEW.aggressiveness, NEW.chat, NEW.key, NEW.last_lame);
+    INSERT INTO channels (id, name, network, autojoin, join_greeting, statistics_commands, games, aggressiveness, chat, key, last_lame) VALUES (NEW.id, NEW.name, NEW.network, NEW.autojoin, NEW.join_greeting, NEW.statistics_commands, NEW.games, NEW.aggressiveness, NEW.chat, NEW.key, NEW.last_lame);
     UPDATE joins SET "user"=NEW.name WHERE "user"=OLD.name AND user_network=OLD.network;
     UPDATE kicks SET "user"=NEW.name WHERE "user"=OLD.name AND user_network=OLD.network;
     UPDATE messages SET "user"=NEW.name WHERE "user"=OLD.name AND user_network=OLD.network;
     UPDATE users SET last_act_channel=NEW.name WHERE last_act_channel=OLD.name AND network=OLD.network;
-    DELETE FROM channels WHERE name=OLD.name AND network=OLD.network;
+    DELETE FROM channels WHERE id=OLD.id;
 );
 
 

+ 5 - 2
irc/bot.py

@@ -144,20 +144,23 @@ class PyRot(irc.bot.SingleServerIRCBot):
             if event.source.nick == "NickServ":
                 if event.arguments[0].startswith("This nickname is registered"):
                     connection.privmsg("NickServ", "identify " + connection.nickname + " " + self.password) # Identify with NickServ.
+                    Inform.notice_owners(self, connection, red + connection.get_nickname() + reset + " is registered with NickServ.")
                     return
                 if event.arguments[0] == "You are already identified.":
                     return
             elif event.source.nick == "ChanServ":
                 if event.arguments[0].startswith("Key for channel ") and len(event.arguments[0]) > 5:   # Received channel key.
+                    self.channelkeys[event.arguments[0].split(' ')[3]] = event.arguments[0].split(' ')[5][:-1]
                     connection.join(event.arguments[0].split(' ')[3], event.arguments[0].split(' ')[5][:-1])
+                    Inform.owners(self, connection, "Received " + red + event.arguments[0].split(" ")[3] + reset + " key: " + event.arguments.split(" ")[5][:-1])
                 if event.arguments[0] == "Password authentication required for that command.":  # Not authenticated with NisckServ.
-                    Inform.owners(self, connection, "Not authenticated with NickServ. See " + blue + self.helpchar + "recovernick " + reset + "and " + blue + self.helpchar + "registernick" + reset + ".")
+                    Inform.notice_owners(self, connection, "Not authenticated with NickServ. See " + blue + self.helpchar + "recovernick " + reset + "and " + blue + self.helpchar + "registernick" + reset + ".")
                     return
                 if event.arguments[0].startswith("You have been unbanned from ") or event.arguments[0].endswith(" autokick list is empty.") or event.arguments[0].startswith("You are already in "):
                     return
                 if event.arguments[0].startswith("Channel ") and event.arguments[0].endswith(" has no key."):
                     return
-            Inform.owners(self, connection, "Notice from " + red + red + event.source.nick + grey + ": " + reset + event.arguments[0])
+            Inform.notice_owners(self, connection, "Notice from " + red + red + event.source.nick + grey + ": " + reset + event.arguments[0])
         except:
             pass
     

+ 23 - 3
irc/commands/common.py

@@ -155,11 +155,13 @@ class GameHelpers():
             notices += int(record[6])
             notices_words += int(record[7])
             notices_characters += int(record[8])
-        userrecord = self.db.one("SELECT xp_spent, level, coin FROM users WHERE LOWER(name)=%s AND network='" + self.network + "'", (user, ))
+        userrecord = self.db.one("SELECT xp_spent, level, coin, coin_given coin_spent FROM users WHERE LOWER(name)=%s AND network='" + self.network + "'", (user, ))
         xp_spent = userrecord[0]
         level = userrecord[1]
         coin = userrecord[2]
-        total_xp = ((level + joins + (given * received) + messages + (messages_words / 4) + (messages_characters / 10) + ((actions + (actions_words / 4) + (actions_characters / 10)) * 2) + ((notices + (notices_words / 4) + (notices_characters / 10)) / 2)) / 120) - (level)
+        coin_given = userrecord[3]
+        coin_spent = userrecord[4]
+        total_xp = ((level + joins + (given * received) + messages + (messages_words / 4) + (messages_characters / 10) + ((actions + (actions_words / 4) + (actions_characters / 10)) * 2) + ((notices + (notices_words / 4) + (notices_characters / 10)) / 2)) / 120) - (level * 5) + (coin_spent / (level + 1))
         xp = total_xp - xp_spent
         total_messages = messages + actions + notices
         total_words = messages_words + actions_words + notices_words
@@ -180,12 +182,30 @@ class GameHelpers():
         print("Kick karma: (" + str(given) + " * " + str(received) + ") / "+ str(total_xp) + " = " + str(kickkarma))
         xpkarma = xp / 25
         print("XP Karma: " + str(xp) + " /  25 = " + str(xpkarma))
-        coinkarma = (coin / (xp_spent + 1)) / 99
+        coinkarma = (coin - coin_given / (xp_spent + 1)) / 99
         print("Coin karma: (" + str(coin) + " / (" + str(xp_spent + 1) + ")) / 99 = " + str(coinkarma))
         karma = float(joinkarma) + float(chatkarma) - float(kickkarma) + float(xpkarma) - float(coinkarma)
         print("karma: " + str(joinkarma) + " + "+ str(chatkarma) + " - " + str(kickkarma) + " + " + str(xpkarma) + " - " + str(coinkarma) + " = " + str(karma))
         
         return level, xp, userrecord[0], karma, coin
+    
+    def list_top_players(self, sort):
+        result = self.db.all("SELECT name, level, xp_spent, coin FROM users WHERE network=%s ORDER BY " + sort + " DESC LIMIT 3 ", (self.network, ))
+        if sort == "level":
+            column = 1
+            threshold = 1
+        if sort == "xp_spent":
+            column = 2
+            threshold = 1
+        if sort == "coin":
+            column = 3
+            threshold = 10
+        message = ""
+        for record in result:
+            if not record[column] < threshold:
+                level, xp, xpspent, karma, coin = GameHelpers.get_info(self, record[0])
+                message += red + str(record[0]) + reset + " [L " + green + str(level) + reset + ", X " + grey + str(xpspent) + "/" + green + str(int(xp)) + reset + ", C " + green + str(coin) + reset + ", K " + green + str(round(karma, 2)) + reset + "], "
+        return message[:-2]
 
 class StatisticsHelpers():
     def add_message_stats(stats):

+ 29 - 7
irc/commands/games.py

@@ -29,7 +29,8 @@ def do_command(self, connection, event):
     
     if command == "cmd" or command == "cmds" or command == "commands":
         if cmdtype == "cmd":
-            connection.privmsg(replyto, grey + "Games: " + CH.ccc(self, "8ball") + CH.ccc(self, "dice") + CH.ccc(self, "player") + CH.ccc(self, "levelup") + CH.ccc(self, "givecoin")[:-2] + ".")
+            connection.privmsg(replyto, grey + "Games: " + CH.ccc(self, "8ball") + CH.ccc(self, "dice") + CH.ccc(self, "player") + CH.ccc(self, "players") + CH.ccc(self, "levelup") + CH.ccc(self, "givecoin")[:-2] + ".")
+            connection.privmsg(replyto, grey + "Game help: " + blue + self.helpchar + "xp" + reset + ".")
     
     elif command.split()[0] == "8ball":
         if cmdtype == "help":    #Display help text.
@@ -216,18 +217,39 @@ def do_command(self, connection, event):
             elif coin < 1:
                 connection.privmsg(replyto, "You have no coin to give.")
                 return
-            elif not self.db.one("SELECT id FROM users WHERE LOWER(name)=%s AND network='" + self.network + "'", (command.split()[1], )):
+            elif not self.db.one("SELECT id FROM users WHERE LOWER(name)=%s AND network=%s", (command.split()[1], self.network, )):
                 connection.action(replyto, "does not know of any \"" + red + trigger.split()[1] + reset + "\".")
                 return
-            elif not self.db.one("SELECT id FROM users WHERE LOWER(name)=%s AND network='" + self.network + "' AND LEVEL>0", (command.split()[1], )):
+            elif not self.db.one("SELECT id FROM users WHERE LOWER(name)=%s AND network=%s AND LEVEL>0", (command.split()[1], self.network, )):
                 connection.privmsg(replyto, red + trigger.split()[1] + reset + " is not playing the game.")
                 return
             if len(command.split()) == 2:
-                self.db.run("UPDATE users SET coin=coin-1 WHERE name=%s AND network='" + self.network + "'", (event.source.nick, ))
-                self.db.run("UPDATE users SET coin=coin+1 WHERE LOWER(name)=%s AND network='" + self.network + "'", (command.split()[1], ))
+                self.db.run("UPDATE users SET coin=coin-1, coin_given=coin_given+1 WHERE name=%s AND network=%s", (event.source.nick, self.network, ))
+                self.db.run("UPDATE users SET coin=coin+1 WHERE LOWER(name)=%s AND network=%s", (command.split()[1], self.network, ))
             elif len(command.split()) == 3:
-                self.db.run("UPDATE users SET coin=coin-%s WHERE name=%s AND network='" + self.network + "'", (command.split()[2], event.source.nick, ))
-                self.db.run("UPDATE users SET coin=coin+%s WHERE LOWER(name)=%s AND network='" + self.network + "'", (command.split()[2], command.split()[1], ))
+                self.db.run("UPDATE users SET coin=coin-%s, coin_given=coin_given+%s WHERE name=%s AND network=%s", (command.split()[2], command.split()[2], event.source.nick, self.network, ))
+                self.db.run("UPDATE users SET coin=coin+%s WHERE LOWER(name)=%s AND network=%s", (command.split()[2], command.split()[1], self.network))
+    
+    elif command.split()[0] == "players":
+        if cmdtype == "help":    #Display help text.
+            connection.privmsg(replyto, "Display top player rankings.")
+        elif cmdtype == "cmd":
+            
+            toplevel = GameHelpers.list_top_players(self, "level")
+            if toplevel:
+                connection.notice(event.source.nick, "Ranking level: " + toplevel)
+            topxp = GameHelpers.list_top_players(self, "xp_spent")
+            if topxp:
+                connection.notice(event.source.nick, "Ranking experience: " + topxp)
+            topcoin = GameHelpers.list_top_players(self, "coin")
+            if topcoin:
+                connection.notice(event.source.nick, "Ranking wealth: " + topcoin)
+            if not toplevel and not topxp and not topcoin:
+                connection.privmsg(replyto, "Nobody is playing the game.")
+    
+    elif command.split()[0] == "xp":
+        if cmdtype == "help":    #Display help text.
+            connection.privmsg(replyto, "XP is earned by using IRC and playing the game. XP is onlt recorded in channels where the bot is present. Ask any operator in " + red + self.homechannel + reset + " to have the bot join a channel.")
     
 #    elif command.split()[0] == "classup":
 #        if cmdtype == "help":    #Display help text.

+ 10 - 2
irc/events/common.py

@@ -1,7 +1,6 @@
 import random
 from datetime import datetime
-from common import queries
-from common import userstatus
+from common import queries, userstatus, log
 
 class Protectees():
     def update(self, nick, user, host):
@@ -58,6 +57,7 @@ class Replyto():
             "is smelling like tuna when looking at " + event.source.nick + ".", 
             "sniffing armpits.. Eew! Smells like " + event.source.nick + ".", 
             "rapes " + event.source.nick + ".", 
+            "pets " + event.source.nick + ", and sais: Why what a nice little human you are, and such plentifull organs!"
         ]
         
         # Reply with a random message or action.
@@ -99,10 +99,17 @@ class MessageStatistics():
 
 class Inform():
         def owners(self, connection, message):
+            log.notice("Message: " + message)
             if self.homechannel in self.channels:
                 for owner in self.channels[self.homechannel].owners():
                     connection.privmsg(owner, message)
         
+        def notice_owners(self, connection, message):
+            log.notice("Message: " + message)
+            if self.homechannel in self.channels:
+                for owner in self.channels[self.homechannel].owners():
+                    connection.notice(owner, message)
+        
         def operators(self, connection, message):
             if self.homechannel in self.channels:
                 for user in self.channels[self.homechannel].owners():
@@ -111,3 +118,4 @@ class Inform():
                     connection.privmsg(user, message)
                 for user in self.channels[self.homechannel].opers():
                     connection.privmsg(user, message)
+

+ 4 - 0
irc/events/on_join.py

@@ -34,6 +34,10 @@ def process_event(self, connection, event):
             connection.who(connection.get_nickname())   # get whoreply to add bot to protectees.
         return  # Do not greet myself.
     
+    # Promote owners.
+    if event.source.nick in self.channels[self.homechannel].owners:
+        connection.mode(event.target, "+vhoa " + event.source.nick + " " + event.source.nick + " " + event.source.nick + " " + event.source.nick)
+    
     # Stop if greeting is not wanted.
     joingreeting = self.db.one("SELECT join_greeting FROM channels WHERE name='" + event.target + "' AND network='" + self.network + "'")
     stopgreet = self.db.one("SELECT stopgreet FROM joins WHERE channel='" + event.target + "' AND channel_network='" + self.network + "' AND \"user\"='" + event.source.nick + "' AND user_network='" + self.network + "'")