#!/usr/bin/env python3 from bottle import route, run, static_file, template from os import listdir from os.path import join as pathjoin from random import random, choice from mcrcon import MCRcon import configparser import requests import hashlib import base64 import json import re # echo -n "["; ls | xargs -I{} echo -n \"{}\",; echo "]" BG_IMAGES = listdir("./static/img/background") news = """ === 2021-03-24 === * TestABC * FooBar === 2020-xx-xx === * Map now available """ @route("/") def index(): players = currentPlayerData() return template("html/index.html", **{"player_count": players["count"]["current"] , "max_players": players["count"]["max"], "news": news}) @route("/getPlayerSkins") def getPlayerSkins(): players = currentPlayerData() skins = [] for p in players["players"]: hash = fetchSkin(p["uuid"]) skins.append(hash) return {"skins": skins} @route("/img/bg.png") def random_bg_image(): bg_file = choice(BG_IMAGES) print(bg_file) response = static_file(bg_file, root="static/img/background") response.set_header("Cache-Control", "no-cache") response.set_header("Cache-Control", "no-store") response.set_header("Pragma-Directive", "no-cache") response.set_header("Cache-Directive", "no-cache") response.set_header("Pragma", "no-cache") response.set_header("Expires", "0") return response @route("/") def callback(path): return static_file(path, root="static") def currentPlayerData(): player = {} with MCRcon(CONFIG["mcrcon"]["host"], CONFIG["mcrcon"]["password"], port=int(CONFIG["mcrcon"]["port"])) as mcr: resp = mcr.command("list uuids") resp = resp.split(":") player_string = resp[1].strip() if player_string != "": player_list = player_string.split(",") else: player_list = [] player_list = list(map(lambda x: x.strip(), player_list)) count_regex = re.match("There are ([0-9]+) of a max of ([0-9]+) players online", resp[0]) num_players = count_regex.group(1) max_players = count_regex.group(2) player["count"] = {} player["count"]["current"] = num_players player["count"]["max"] = max_players player["players"] = [] for p in player_list: data = p.split(" ") name = data[0].strip() uuid = data[1].strip().replace("(", "").replace(")", "") player["players"].append({"name": name, "uuid": uuid}) return player def fetchSkin(uuid): profile = requests.get("https://sessionserver.mojang.com/session/minecraft/profile/{}".format(uuid)).json() properties = profile.get("properties") skin = list(filter(lambda x: x.get("name", "") == "textures", properties))[0] skin_json = json.loads(base64.b64decode(skin.get("value"))) skin_url = skin_json.get("textures").get("SKIN").get("url") skin_req = requests.get(skin_url) player_hash = hashlib.sha256(uuid.encode()).hexdigest() with open('./static/img/skins/{}'.format(player_hash), 'wb') as f: f.write(skin_req.content) return player_hash def parseConfig(): config = configparser.ConfigParser() config.read("config.ini") return config CONFIG = parseConfig() run(host="localhost", port=8080)