#!/usr/bin/env python import random from threading import Timer import requests from mumo_module import (commaSeperatedIntegers, MumoModule) from tools.Utils import find_create_channel, get_empty_channels, get_subchannels, get_user_for_channel class autochannel(MumoModule): default_config = {'autochannel': ( ('servers', commaSeperatedIntegers, []), ('spare_channel', int, 1), ('top_games_limit', int, 10), ('root_channel_name', str, "Endless"), ('check_timer_interval', int, 10), ('game_channel_permanent', str, ""), ('game_channel_name', str, "Games") ) } def __init__(self, name, manager, configuration=None): MumoModule.__init__(self, name, manager, configuration) self.murmur = manager.getMurmurModule() self.spare_channel = self.cfg().autochannel.spare_channel self.top_games_limit = self.cfg().autochannel.top_games_limit self.root_channel_name = self.cfg().autochannel.root_channel_name self.timer_interval = self.cfg().autochannel.check_timer_interval self.game_channel_permanent = self.cfg().autochannel.game_channel_permanent.replace(" ", "").split(',') self.game_channel_name = self.cfg().autochannel.game_channel_name self.random_root = None self.game_root = None self.servertimer = {} # Load steam top 100 last two weeks r = requests.get("http://steamspy.com/api.php?request=top100in2weeks") if r.status_code == 200: self.top_list = r.json() self.log().info("Loaded steam Top100") else: self.top_list = None # Load wordlist r = requests.get("https://raw.githubusercontent.com/dwyl/english-words/master/words.txt") if r.status_code == 200: self.wordlist = r.text.splitlines() self.log().info("Loaded {} words".format(len(self.wordlist))) else: self.wordlist = None Timer(60 * 60, self.update_timer).start() def connected(self): self.log().debug("Register timer for running servers") servers = self.cfg().autochannel.servers if not servers: servers = self.manager().SERVERS_ALL self.manager().subscribeMetaCallbacks(self, servers) for server in self.manager().getMeta().getBootedServers(): if server.id in self.servertimer: self.servertimer[server.id].cancel() self.servertimer[server.id] = Timer(self.timer_interval, self.handle_timer, [server]) self.servertimer[server.id].start() def handle_timer(self, server): self.check_random_channel(server) self.check_game_channel(server) self.servertimer[server.id] = Timer(self.timer_interval, self.handle_timer, [server]) self.servertimer[server.id].start() def update_timer(self): r = requests.get("http://steamspy.com/api.php?request=top100in2weeks") if r.status_code == 200 and r.json(): self.top_list = r.json() self.log().info("Reloaded steam top100") Timer(60 * 60, self.update_timer).start() else: self.log().warn("Failed to reload top100 - HTTP {} (len={})".format(r.status_code, len(r.json()))) Timer(10, self.update_timer).start() def disconnected(self): pass def check_random_channel(self, server): self.random_root = find_create_channel(self.root_channel_name, server, 0) empty_channels = get_empty_channels(server, self.random_root.id) for cid in empty_channels[1:]: server.removeChannel(cid) if len(empty_channels) == 0: self.add_random_channel(server) def add_random_channel(self, server): word = self.wordlist[random.randint(0, len(self.wordlist))] while not word.isalnum(): word = self.wordlist[random.randint(0, len(self.wordlist))] self.log().info("Added new channel " + word) server.addChannel(word, self.random_root.id) def check_game_channel(self, server): self.game_root = find_create_channel(self.game_channel_name, server, 0) if not self.top_list: return games = {} for idx, app in enumerate(self.top_list.values()): if idx < self.top_games_limit: games[app["name"]] = app else: break for pgame in self.game_channel_permanent: if pgame: game = self.top_list[str(pgame)] if game: games[game["name"]] = game channels = get_subchannels(server, self.game_root.id) games_matched = [] for channel in channels: if len(get_user_for_channel(channel.id, server)) == 0 and channel.name not in games: server.removeChannel(channel.id) elif channel.name in games: games_matched.append(channel.name) channel_tbc = {*games} - set(games_matched) if games_matched: for game in games_matched: ch = find_create_channel(game, server, self.game_root.id) if ch.position is not list(self.top_list).index(str(games[game]["appid"])): ch.description = 'Top {0} on Steam'.format( list(self.top_list).index(str(games[game]["appid"])) + 1, games[game]["appid"]) ch.position = list(self.top_list).index(str(games[game]["appid"])) server.setChannelState(ch) for game in channel_tbc: nc = server.getChannelState(server.addChannel(game, self.game_root.id)) if nc: nc.description = 'Top {0} on Steam'.format( list(self.top_list).index(str(games[nc.name]["appid"])) + 1, games[nc.name]["appid"]) nc.position = list(self.top_list).index(str(games[nc.name]["appid"])) server.setChannelState(nc) # # --- Meta callback functions # def started(self, server): self.log().debug("Register timer for new server") self.servertimer[server.id] = Timer(self.timer_interval, self.handle_timer, [server]) self.servertimer[server.id].start() def stopped(self, server): self.log().debug("Stopped timer for server") if server.id in self.servertimer: self.servertimer[server.id].cancel()