Files
mumo3/modules/autochannel.py

174 lines
6.4 KiB
Python

#!/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 <a href="http://store.steampowered.com/app/{1}">Steam</a>'.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 <a href="http://store.steampowered.com/app/{1}">Steam</a>'.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()