Advertisement
Guest User

Untitled

a guest
Feb 23rd, 2019
230
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 23.63 KB | None | 0 0
  1. import minqlx
  2. import time
  3. import os
  4. import pysftp
  5. import re
  6. import codecs
  7.  
  8. RECORDS_KEY = "minqlx:uberstats_records:{}"
  9. WEAPON_RECORDS = {
  10.                     "kill_machine": ["KILL MACHINE", "{:0.2f} frags/min"],
  11.                     "counterstrike": ["BEST COUNTERSTRIKE PLAYER", "{:0.2f} K/D ratio"],
  12.                     "most_damage": ["DESTRUCTICATOR", "{:,} dmg given"],
  13.                     "longest_spree": ["RAMBO", "{} kill streak"],
  14.                     "best_rail_accuracy": ["LASER EYES", "{:0.2f} percent rail accuracy"],
  15.                     "most_nade_kills": ["PINEAPPLE POWER", "{} grenade frags"],
  16.                     "most_pummels": ["PUMMEL LORD", "{} pummels"],
  17.                     "most_dmg_taken": ["BIGGEST PINCUSHION", "{:,} dmg taken"],
  18.                     "most_world_deaths": ["CLUMSIEST FOOL", "{:,} deaths by world"],
  19.                     "most_dmg_per_kill": ["GOOD SAMARITAN", "{:0.2f} damage per frag"]
  20.                   }
  21. FILE_PATTERN = re.compile('[\W_]+')
  22.  
  23. class uberstats(minqlx.Plugin):
  24.  
  25.   def __init__(self):
  26.     self.set_cvar_once("qlx_uberstats_sftp_hostname", "")
  27.     self.set_cvar_once("qlx_uberstats_sftp_username", "")
  28.     self.set_cvar_once("qlx_uberstats_sftp_password", "")
  29.     self.set_cvar_once("qlx_uberstats_sftp_remote_path", "")
  30.  
  31.     self.sftp_hostname = self.get_cvar("qlx_uberstats_sftp_hostname")
  32.     self.sftp_username = self.get_cvar("qlx_uberstats_sftp_username")
  33.     self.sftp_password = self.get_cvar("qlx_uberstats_sftp_password")
  34.     self.sftp_remote_path = self.get_cvar("qlx_uberstats_sftp_remote_path")
  35.  
  36.     self.add_command("score", self.cmd_score)
  37.     self.add_command("highscores", self.cmd_highscores)
  38.     self.add_command("clearhighscores", self.cmd_clear_highscores, 5)
  39.  
  40.     self.add_hook("stats", self.handle_stats)
  41.     self.add_hook("map", self.handle_map)
  42.     self.add_hook("game_end", self.handle_game_end)
  43.  
  44.     self.weapons = ["PLASMA", "ROCKET", "PROXMINE", "RAILGUN", "CHAINGUN", "NAILGUN", "GRENADE", "LIGHTNING", "SHOTGUN", "MACHINEGUN", "HMG", "BFG", "GAUNTLET"]
  45.     self.weapon_sprees = ["PLASMORGASM", "ROCKET RENEGADE", "MINE MASTER", "RAIL RANGER", "CHAIN GANG", "GNARLY NAILER", "GRENADE GOON", "LIGHTNING LASHER", "SHOTGUN SAMURAI", "MACHINEGUN PECKER", "HMG HARASSER", "BFG BOSS", "GUANTLET GOD"]
  46.     self.kill_streak = {}
  47.     for weapon in self.weapons:
  48.       self.kill_streak[weapon] = {}
  49.  
  50.     self.outputted_accuracy_players = []
  51.     self.kamikaze_stats = {}
  52.  
  53.     self.best_kpm_names = []
  54.     self.best_kpm = 0
  55.  
  56.     self.best_kd_names = []
  57.     self.best_kd = 0
  58.  
  59.     self.most_damage_names = []
  60.     self.most_damage = 0
  61.  
  62.     self.longest_spree_names = []
  63.     self.longest_spree = 0
  64.  
  65.     self.best_rail_accuracy_names = []
  66.     self.best_rail_accuracy = 0
  67.     self.best_rail_hits = 0
  68.     self.best_rail_shots = 0
  69.  
  70.     self.most_nade_kills_names = []
  71.     self.most_nade_kills = 0
  72.  
  73.     self.most_pummels_names = []
  74.     self.most_pummels = 0
  75.  
  76.     self.most_dmg_taken_names = []
  77.     self.most_dmg_taken = 0
  78.  
  79.     self.world_death_types = ["UNKNOWN", "WATER", "SLIME", "LAVA", "CRUSH", "FALLING", "TRIGGER_HURT", "HURT"]
  80.     self.world_death_stats = {}
  81.     self.most_world_deaths_names = []
  82.     self.most_world_deaths = 0
  83.  
  84.     self.most_dmg_per_kill_names = []
  85.     self.most_dmg_per_kill = 0
  86.  
  87.   def cmd_score(self, player, msg, channel):
  88.     if player.team != "spectator":
  89.       sorted_players = sorted(self.players(), key = lambda p: p.stats.score, reverse=True)
  90.       player_index = sorted_players.index(player) + 1
  91.       player.tell("^2{} - ^3Score: ^7{} - ^3K/D: ^7{} - ^3DMG: ^7{} - ^3TIME: ^7{} - ^3PING: ^7{}".format(
  92.         self.ordinal(player_index),
  93.         player.stats.score,
  94.         str(player.stats.kills) + "/" + str(player.stats.deaths),
  95.         player.stats.damage_dealt,
  96.         int((player.stats.time/(1000*60))%60),
  97.         player.stats.ping
  98.       )
  99.       )
  100.  
  101.   def handle_stats(self, stats):
  102.     if stats['DATA']['STEAM_ID'] != "0": #ignore games with bots in them
  103.       if self.game is not None:
  104.         if self.game.state == "in_progress":
  105.           if stats['TYPE'] == "PLAYER_DEATH":
  106.             victim_name = stats['DATA']['VICTIM']['NAME']
  107.  
  108.             #remove player from kill streak counters when they die
  109.             for weapon in self.weapons:
  110.               if self.kill_streak[weapon]:
  111.                 if victim_name in self.kill_streak[weapon]:
  112.                   self.kill_streak[weapon][victim_name] = 0
  113.  
  114.             #count player world deaths
  115.             if stats['DATA']['MOD'] in self.world_death_types:
  116.               victim_name = stats['DATA']['VICTIM']['NAME']
  117.               if victim_name not in self.world_death_stats:
  118.                 self.world_death_stats[victim_name] = 1
  119.               else:
  120.                 self.world_death_stats[victim_name] += 1
  121.           elif stats['TYPE'] == "PLAYER_KILL" and stats['DATA']['MOD'] in self.weapons:
  122.             killer_name = stats['DATA']['KILLER']['NAME']
  123.             weapon = stats['DATA']['MOD']
  124.  
  125.             if killer_name != stats['DATA']['VICTIM']['NAME']:
  126.               if killer_name not in self.kill_streak[weapon]:
  127.                 self.kill_streak[weapon][killer_name] = 1
  128.               else:
  129.                 self.kill_streak[weapon][killer_name] += 1
  130.  
  131.               if self.kill_streak[weapon][killer_name] == 1:
  132.                 self.handle_kill_streak(killer_name, weapon)
  133.           elif stats['TYPE'] == "PLAYER_KILL" and stats['DATA']['MOD'] == "KAMIKAZE":
  134.             killer_name = stats['DATA']['KILLER']['NAME']
  135.             if killer_name != stats['DATA']['VICTIM']['NAME']:
  136.               if killer_name not in self.kamikaze_stats:
  137.                 self.kamikaze_stats[killer_name] = 1
  138.               else:
  139.                 self.kamikaze_stats[killer_name] += 1
  140.  
  141.               if self.kamikaze_stats[killer_name] == 1:
  142.                 self.handle_kamikaze_stats(killer_name)
  143.  
  144.       if stats['TYPE'] == "PLAYER_STATS":
  145.         #these stats come at end of game after MATCH_REPORT for each player
  146.         if stats['DATA']['QUIT'] == 0 and stats['DATA']['WARMUP'] == 0:
  147.           if stats['DATA']['PLAY_TIME'] >= 120:
  148.             player_name = stats['DATA']['NAME']
  149.  
  150.             #player accuracies (sent to each player in tell)
  151.             player = self.player(int(stats['DATA']['STEAM_ID']))
  152.             #dont show if player is in spec, also handle multiple output bug as well
  153.             if player.team != "spectator" and player.steam_id not in self.outputted_accuracy_players:
  154.               accuracy_output = "^2YOUR ACCURACY:"
  155.               for weapon in self.weapons:
  156.                 weapon_shots = stats['DATA']['WEAPONS'][weapon]["S"]
  157.                 weapon_hits = stats['DATA']['WEAPONS'][weapon]["H"]
  158.                 if weapon_shots > 0:
  159.                   if weapon_hits > 0:
  160.                     weapon_accuracy = 100 * (weapon_hits / weapon_shots)
  161.                   else:
  162.                     weapon_accuracy = 0.00
  163.                   accuracy_output += " - ^3{}: ^1{:0.2f}".format(weapon, weapon_accuracy)
  164.               player.tell(accuracy_output)
  165.               self.outputted_accuracy_players.append(player.steam_id)
  166.  
  167.             player_kpm = stats['DATA']['KILLS'] / (stats['DATA']['PLAY_TIME'] / 60)
  168.  
  169.             if stats['DATA']['DEATHS'] != 0: #we don't want to divide by 0!
  170.               player_kd = stats['DATA']['KILLS'] / stats['DATA']['DEATHS']
  171.             else:
  172.               player_kd = stats['DATA']['KILLS']
  173.  
  174.             player_dmg = stats['DATA']['DAMAGE']['DEALT']
  175.             player_longest_spree = stats['DATA']['MAX_STREAK']
  176.  
  177.             player_rail_hits = 0
  178.             player_rail_shots = 0
  179.  
  180.             if stats['DATA']['WEAPONS']['RAILGUN']['S'] >= 15:
  181.               player_rail_hits = stats['DATA']['WEAPONS']['RAILGUN']['H']
  182.               player_rail_shots = stats['DATA']['WEAPONS']['RAILGUN']['S']
  183.               player_rail_accuracy = 100 * (player_rail_hits / player_rail_shots)
  184.             else:
  185.               player_rail_accuracy = 0
  186.  
  187.             player_nade_kills = stats['DATA']['WEAPONS']['GRENADE']['K']
  188.             player_pummels = stats['DATA']['WEAPONS']['GAUNTLET']['K']
  189.             player_dmg_taken = stats['DATA']['DAMAGE']['TAKEN']
  190.  
  191.             player_dmg_per_kill = 0
  192.             if stats['DATA']['KILLS'] > 0: #we don't want to divide by 0!
  193.               player_dmg_per_kill = stats['DATA']['DAMAGE']['DEALT'] / stats['DATA']['KILLS']
  194.  
  195.             if not self.best_kpm_names:
  196.               self.best_kpm_names = [player_name]
  197.               self.best_kpm = player_kpm
  198.             elif player_kpm > self.best_kpm:
  199.               self.best_kpm_names = [player_name]
  200.               self.best_kpm = player_kpm
  201.             elif player_kpm == self.best_kpm:
  202.               self.best_kpm_names.append(player_name)
  203.  
  204.             if not self.best_kd_names:
  205.               self.best_kd_names = [player_name]
  206.               self.best_kd = player_kd
  207.             elif player_kd > self.best_kd:
  208.               self.best_kd_names = [player_name]
  209.               self.best_kd = player_kd
  210.             elif player_kd == self.best_kd:
  211.               self.best_kd_names.append(player_name)
  212.  
  213.             if not self.most_damage_names:
  214.               self.most_damage_names = [player_name]
  215.               self.most_damage = player_dmg
  216.             elif player_dmg > self.most_damage:
  217.               self.most_damage_names = [player_name]
  218.               self.most_damage = player_dmg
  219.             elif player_dmg == self.most_damage:
  220.               self.most_damage_names.append(player_name)
  221.  
  222.             if not self.longest_spree:
  223.               self.longest_spree_names = [player_name]
  224.               self.longest_spree = player_longest_spree
  225.             elif player_longest_spree > self.longest_spree:
  226.               self.longest_spree_names = [player_name]
  227.               self.longest_spree = player_longest_spree
  228.             elif player_longest_spree == self.longest_spree:
  229.               self.longest_spree_names.append(player_name)
  230.  
  231.             if not self.best_rail_accuracy_names:
  232.               self.best_rail_accuracy_names = [player_name]
  233.               self.best_rail_accuracy = player_rail_accuracy
  234.               self.best_rail_hits = player_rail_hits
  235.               self.best_rail_shots = player_rail_shots
  236.             elif player_rail_accuracy > self.best_rail_accuracy:
  237.               self.best_rail_accuracy_names = [player_name]
  238.               self.best_rail_accuracy = player_rail_accuracy
  239.               self.best_rail_hits = player_rail_hits
  240.               self.best_rail_shots = player_rail_shots
  241.             elif player_rail_accuracy == self.best_rail_accuracy:
  242.               self.best_rail_accuracy_names.append(player_name)
  243.  
  244.             if not self.most_nade_kills_names:
  245.               self.most_nade_kills_names = [player_name]
  246.               self.most_nade_kills = player_nade_kills
  247.             elif player_nade_kills > self.most_nade_kills:
  248.               self.most_nade_kills_names = [player_name]
  249.               self.most_nade_kills = player_nade_kills
  250.             elif player_nade_kills == self.most_nade_kills:
  251.               self.most_nade_kills_names.append(player_name)
  252.  
  253.             if not self.most_pummels_names:
  254.               self.most_pummels_names = [player_name]
  255.               self.most_pummels = player_pummels
  256.             elif player_pummels > self.most_pummels:
  257.               self.most_pummels_names = [player_name]
  258.               self.most_pummels = player_pummels
  259.             elif player_pummels == self.most_pummels:
  260.               self.most_pummels_names.append(player_name)
  261.  
  262.             if not self.most_dmg_taken_names:
  263.               self.most_dmg_taken_names = [player_name]
  264.               self.most_dmg_taken = player_dmg_taken
  265.             elif player_dmg_taken > self.most_dmg_taken:
  266.               self.most_dmg_taken_names = [player_name]
  267.               self.most_dmg_taken = player_dmg_taken
  268.             elif player_dmg_taken == self.most_dmg_taken:
  269.               self.most_dmg_taken_names.append(player_name)
  270.  
  271.             if not self.most_dmg_per_kill_names:
  272.               self.most_dmg_per_kill_names = [player_name]
  273.               self.most_dmg_per_kill = player_dmg_per_kill
  274.             elif player_dmg_per_kill > self.most_dmg_per_kill:
  275.               self.most_dmg_per_kill_names = [player_name]
  276.               self.most_dmg_per_kill = player_dmg_per_kill
  277.             elif player_dmg_per_kill == self.most_dmg_per_kill:
  278.               self.most_dmg_per_kill_names.append(player_name)
  279.  
  280.   @minqlx.delay(2)
  281.   @minqlx.thread
  282.   def handle_game_end(self, data):
  283.     if not data["ABORTED"] and self.best_kpm:
  284.       self.msg("^5***UBERSTATS***")
  285.       stats_output = "^1KILL MACHINE: "
  286.       record_response = ""
  287.       for i, player_name in enumerate(self.best_kpm_names):
  288.         record_response = self.check_record("kill_machine", float(self.best_kpm), player_name)
  289.         stats_output += "^7" + player_name
  290.         if len(self.best_kpm_names) > 1 and len(self.best_kpm_names) - 1 != i:
  291.           stats_output += ", "
  292.       stats_output += "^2 - {:0.2f} frags/min".format(self.best_kpm)
  293.       self.msg(record_response + stats_output)
  294.  
  295.       stats_output = "^1BEST COUNTERSTRIKE PLAYER: "
  296.       record_response = ""
  297.       for i, player_name in enumerate(self.best_kd_names):
  298.         record_response = self.check_record("counterstrike", float(self.best_kd), player_name)
  299.         stats_output += "^7" + player_name
  300.         if len(self.best_kd_names) > 1 and len(self.best_kd_names) - 1 != i:
  301.           stats_output += ", "
  302.       stats_output += "^2 - {:0.2f} K/D ratio".format(self.best_kd)
  303.       self.msg(record_response + stats_output)
  304.  
  305.       stats_output = "^1DESTRUCTICATOR: "
  306.       record_response = ""
  307.       for i, player_name in enumerate(self.most_damage_names):
  308.         record_response = self.check_record("most_damage", float(self.most_damage), player_name)
  309.         stats_output += "^7" + player_name
  310.         if len(self.most_damage_names) > 1 and len(self.most_damage_names) - 1 != i:
  311.           stats_output += ", "
  312.       stats_output += "^2 - {:,} dmg given".format(self.most_damage)
  313.  
  314.       self.msg(record_response + stats_output)
  315.       time.sleep(3)
  316.  
  317.       if self.longest_spree > 1:
  318.         stats_output = "^1RAMBO: "
  319.         record_response = ""
  320.         for i, player_name in enumerate(self.longest_spree_names):
  321.           record_response = self.check_record("longest_spree", float(self.longest_spree), player_name)
  322.           stats_output += "^7" + player_name
  323.           if len(self.longest_spree_names) > 1 and len(self.longest_spree_names) - 1 != i:
  324.             stats_output += ", "
  325.         stats_output += "^2 - {} kill streak".format(self.longest_spree)
  326.         self.msg(record_response + stats_output)
  327.  
  328.       if self.best_rail_accuracy > 0:
  329.         stats_output = "^1LASER EYES: "
  330.         record_response = ""
  331.         for i, player_name in enumerate(self.best_rail_accuracy_names):
  332.           record_response = self.check_record("best_rail_accuracy", float(self.best_rail_accuracy), player_name)
  333.           stats_output += "^7" + player_name
  334.           if len(self.best_rail_accuracy_names) > 1 and len(self.best_rail_accuracy_names) - 1 != i:
  335.             stats_output += ", "
  336.         stats_output += "^2 - {:0.2f} percent rail accuracy ({} hits / {} shots)".format(self.best_rail_accuracy, self.best_rail_hits, self.best_rail_shots)
  337.         self.msg(record_response + stats_output)
  338.  
  339.       if self.most_nade_kills > 0:
  340.         stats_output = "^3PINEAPPLE POWER: "
  341.         record_response = ""
  342.         for i, player_name in enumerate(self.most_nade_kills_names):
  343.           record_response = self.check_record("most_nade_kills", float(self.most_nade_kills), player_name)
  344.           stats_output += "^7" + player_name
  345.           if len(self.most_nade_kills_names) > 1 and len(self.most_nade_kills_names) - 1 != i:
  346.             stats_output += ", "
  347.         stats_output += "^2 - {} grenade frags".format(self.most_nade_kills)
  348.         self.msg(record_response + stats_output)
  349.  
  350.       time.sleep(2)
  351.  
  352.       if self.most_pummels > 0:
  353.         stats_output = "^1PUMMEL LORD: "
  354.         record_response = ""
  355.         for i, player_name in enumerate(self.most_pummels_names):
  356.           record_response = self.check_record("most_pummels", float(self.most_pummels), player_name)
  357.           stats_output += "^7" + player_name
  358.           if len(self.most_pummels_names) > 1 and len(self.most_pummels_names) - 1 != i:
  359.             stats_output += ", "
  360.         stats_output += "^2 - {} pummels".format(self.most_pummels)
  361.         self.msg(record_response + stats_output)
  362.  
  363.       stats_output = "^6BIGGEST PINCUSHION: "
  364.       record_response = ""
  365.       for i, player_name in enumerate(self.most_dmg_taken_names):
  366.         record_response = self.check_record("most_dmg_taken", float(self.most_dmg_taken), player_name)
  367.         stats_output += "^7" + player_name
  368.         if len(self.most_dmg_taken_names) > 1 and len(self.most_dmg_taken_names) - 1 != i:
  369.           stats_output += ", "
  370.       stats_output += "^2 - {:,} ^6dmg taken".format(self.most_dmg_taken)
  371.       self.msg(record_response + stats_output)
  372.  
  373.       stats_output = "^6CLUMSIEST FOOL: "
  374.       record_response = ""
  375.       for name, world_deaths in self.world_death_stats.items():
  376.         if not self.most_world_deaths_names:
  377.           self.most_world_deaths_names = [name]
  378.           self.most_world_deaths = world_deaths
  379.         elif world_deaths > self.most_world_deaths:
  380.           self.most_world_deaths_names = [name]
  381.           self.most_world_deaths = world_deaths
  382.         elif world_deaths == self.most_world_deaths:
  383.           self.most_world_deaths_names.append(name)
  384.  
  385.       if self.most_world_deaths > 0:
  386.         for i, player_name in enumerate(self.most_world_deaths_names):
  387.           record_response = self.check_record("most_world_deaths", float(self.most_world_deaths), player_name)
  388.           stats_output += "^7" + player_name
  389.           if len(self.most_world_deaths_names) > 1 and len(self.most_world_deaths_names) - 1 != i:
  390.             stats_output += ", "
  391.         stats_output += "^2 - {:,} deaths by world".format(self.most_world_deaths)
  392.         self.msg(record_response + stats_output)
  393.  
  394.       time.sleep(2)
  395.  
  396.       if self.game.type not in ["Duel", "Instagib"]:
  397.         stats_output = "^6GOOD SAMARITAN: "
  398.         record_response = ""
  399.         for i, player_name in enumerate(self.most_dmg_per_kill_names):
  400.           record_response = self.check_record("most_dmg_per_kill", float(self.most_dmg_per_kill), player_name)
  401.           stats_output += "^7" + player_name
  402.           if len(self.most_dmg_per_kill_names) > 1 and len(self.most_dmg_per_kill_names) - 1 != i:
  403.             stats_output += ", "
  404.         stats_output += "^2 - {:0.2f} damage per frag".format(self.most_dmg_per_kill)
  405.         self.msg(record_response + stats_output)
  406.  
  407.       if self.sftp_hostname:
  408.         self.high_scores("endgame")
  409.  
  410.   @minqlx.delay(8)
  411.   def handle_kill_streak(self, player_name, weapon):
  412.     if int(self.kill_streak[weapon][player_name]) >= 4:
  413.       self.play_sound("sound/uberstats/{}.ogg".format(weapon.lower()))
  414.       self.center_print("{}^1 {}".format(player_name, self.weapon_sprees[self.weapons.index(weapon)]))
  415.       self.msg("{} ^1{}: ^2({} {} frags in 8s)".format(player_name, self.weapon_sprees[self.weapons.index(weapon)], self.kill_streak[weapon][player_name], weapon))
  416.       self.kill_streak[weapon][player_name] = 0
  417.  
  418.   @minqlx.delay(5)
  419.   def handle_kamikaze_stats(self, player_name):
  420.     kami_msg = "{}^7's ^3 KAMI: ^7{} ^1FRAGS".format(player_name, self.kamikaze_stats[player_name])
  421.     self.center_print(kami_msg)
  422.     self.msg(kami_msg)
  423.     self.kamikaze_stats[player_name] = 0
  424.  
  425.   @minqlx.delay(10)
  426.   def handle_map(self, mapname, factory):
  427.     self.best_kpm_names = []
  428.     self.best_kpm = 0
  429.  
  430.     self.best_kd_names = []
  431.     self.best_kd = 0
  432.  
  433.     self.most_damage_names = []
  434.     self.most_damage = 0
  435.  
  436.     self.longest_spree_names = []
  437.     self.longest_spree = 0
  438.  
  439.     self.best_rail_accuracy_names = []
  440.     self.best_rail_accuracy = 0
  441.     self.best_rail_hits = 0
  442.     self.best_rail_shots = 0
  443.  
  444.     self.most_nade_kills_names = []
  445.     self.most_nade_kills = 0
  446.  
  447.     self.most_pummels_names = []
  448.     self.most_pummels = 0
  449.  
  450.     self.most_dmg_taken_names = []
  451.     self.most_dmg_taken = 0
  452.  
  453.     self.world_death_stats = {}
  454.     self.most_world_deaths_names = []
  455.     self.most_world_deaths = 0
  456.  
  457.     self.most_dmg_per_kill_names = []
  458.     self.most_dmg_per_kill = 0
  459.  
  460.     self.kamikaze_stats = {}
  461.     for weapon in self.weapons:
  462.       self.kill_streak[weapon] = {}
  463.  
  464.     self.outputted_accuracy_players = []
  465.  
  466.     self.high_scores("triggered")
  467.  
  468.   def ordinal(self, value):
  469.     try:
  470.       value = int(value)
  471.     except ValueError:
  472.       return value
  473.  
  474.     if value % 100//10 != 1:
  475.       if value % 10 == 1:
  476.         ordval = u"%d%s" % (value, "st")
  477.       elif value % 10 == 2:
  478.         ordval = u"%d%s" % (value, "nd")
  479.       elif value % 10 == 3:
  480.         ordval = u"%d%s" % (value, "rd")
  481.       else:
  482.         ordval = u"%d%s" % (value, "th")
  483.     else:
  484.       ordval = u"%d%s" % (value, "th")
  485.  
  486.     return ordval
  487.  
  488.   def check_record(self, record_name, score, player_name):
  489.     current_record = self.db.get(RECORDS_KEY.format(record_name) + ":high_score")
  490.  
  491.     if current_record is None:
  492.       current_record = 0
  493.     else:
  494.       current_record = float(current_record)
  495.  
  496.     if score > current_record:
  497.       self.db.set(RECORDS_KEY.format(record_name) + ":high_score", score)
  498.       self.db.delete(RECORDS_KEY.format(record_name) + ":players")
  499.       self.db.sadd(RECORDS_KEY.format(record_name) + ":players", player_name)
  500.       self.play_sound("sound/vo_evil/new_high_score")
  501.       return "^5NEW HIGH SCORE! - "
  502.     elif score == current_record:
  503.       self.db.sadd(RECORDS_KEY.format(record_name) + ":players", player_name)
  504.       return "^5TIED HIGH SCORE! - "
  505.     else:
  506.       return ""
  507.  
  508.   def cmd_highscores(self, player, msg, channel):
  509.     self.high_scores("triggered")
  510.  
  511.   @minqlx.thread
  512.   def high_scores(self, method):
  513.     if method == "triggered" and float(self.db.get(RECORDS_KEY.format("kill_machine") + ":high_score")) is not None:
  514.       self.msg("^5***UBERSTATS HIGH SCORES***")
  515.     elif method == "endgame":
  516.       html = "<script src='https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js'></script>\n" + \
  517.            "<script>\n" + \
  518.            "$(function(){\n"
  519.  
  520.     for key, val in WEAPON_RECORDS.items():
  521.       high_score = float(self.db.get(RECORDS_KEY.format(key) + ":high_score"))
  522.       if high_score is not None:
  523.         players = ", ".join(self.db.smembers(RECORDS_KEY.format(key) + ":players"))
  524.         if method == "triggered":
  525.           self.msg("^1{} - ^7{} ^2- {}".format(val[0], players, val[1].format(high_score)).replace(".00", "").replace(".0", ""))
  526.         elif method == "endgame":
  527.           html += "$('.{}_record').text('{}');\n".format(key, val[1].format(high_score).replace(".00", "").replace(".0", ""))
  528.           html += "$('.{}_players').text('{}');\n\n".format(key, players)
  529.  
  530.     if method == "endgame":
  531.       html += "});\n</script>"
  532.       #make nice filename from hostname
  533.       uberfilename = re.sub(' +', '_', (re.sub("[^a-zA-Z.\d\s]", "", self.game.hostname) + "-uberstats.html").lower())
  534.       f = codecs.open(uberfilename, "w+", "utf-8")
  535.       f.write(html)
  536.       f.close()
  537.       cnopts = pysftp.CnOpts()
  538.       cnopts.hostkeys = None
  539.       srv = pysftp.Connection(host = self.sftp_hostname, username = self.sftp_username, password = self.sftp_password, cnopts=cnopts)
  540.       srv.chdir(self.sftp_remote_path)
  541.       srv.put(uberfilename)
  542.  
  543.   def cmd_clear_highscores(self, player, msg, channel):
  544.     for key, val in WEAPON_RECORDS.items():
  545.       self.db.delete(RECORDS_KEY.format(key) + ":players")
  546.       self.db.delete(RECORDS_KEY.format(key) + ":high_score")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement