homepage/homepage/main.py

147 lines
5.2 KiB
Python

#!/usr/bin/env python3
from bottle import route, run, static_file, template
from os import listdir, sysconf
from os.path import join as pathjoin
from random import random, choice
from mcrcon import MCRcon
import configparser
import platform
import requests
import hashlib
import base64
import json
import re
# echo -n "["; ls | xargs -I{} echo -n \"{}\",; echo "]"
BG_IMAGES = listdir("./static/img/background")
@route("/")
def index():
print(server_details())
players = currentPlayerData()
return template("html/index.html", **{"player_count": players["count"]["current"] , "max_players": players["count"]["max"], "news": news(), "donations": donations(), "server_details": server_details()})
@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("/<path:path>")
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
def donations():
with open("donations.txt", "r") as donation_file:
donations = donation_file.read()
return donations
def news():
with open("news.txt", "r") as news_file:
news = news_file.read()
def hardware_info():
processor = platform.processor()
mem_bytes = sysconf('SC_PAGE_SIZE') * sysconf('SC_PHYS_PAGES')
mem_gib = mem_bytes/(1024.**3)
mem_pretty = round(mem_gib, 1)
return {"cpu": processor, "ram": mem_pretty}
def paper_version():
with MCRcon(CONFIG["mcrcon"]["host"], CONFIG["mcrcon"]["password"], port=int(CONFIG["mcrcon"]["port"])) as mcr:
for i in range(0, 10):
resp = mcr.command("version")
if not "please wait" in resp:
break
match = re.match(".*(This server is running Paper version )(.*) \((.*)\) \(Implementing API version (.*)\).*", resp)
paper_version = match.group(2)
mc_version = match.group(3)
mc_version = mc_version.split(":")[1].strip()
api_version = match.group(4)
return {"paper": paper_version, "minecraft": mc_version, "api": api_version}
def datapack_info():
with MCRcon(CONFIG["mcrcon"]["host"], CONFIG["mcrcon"]["password"], port=int(CONFIG["mcrcon"]["port"])) as mcr:
resp = mcr.command("datapack list")
match = re.match("There are [0-9]* data packs enabled: (\[.*\])*.*", resp)
datapacks = []
datapacks_string = match.group(1)
for datapack in datapacks_string.split(","):
match = re.match("\[(.*)\(.*\)\]", datapack.strip())
datapack_name = match.group(1)
datapack_name = datapack_name.strip()
datapack_name = datapack_name.replace("file/", "")
datapack_name = datapack_name.replace(".zip", "")
if not datapack_name in ["vanilla", "bukkit"]:
datapacks.append(datapack_name)
return datapacks
def server_details():
hardware = hardware_info()
versions = paper_version()
datapacks = datapack_info()
return {"hardware": hardware, "versions": versions, "datapacks": datapacks}
CONFIG = parseConfig()
run(host="localhost", port=8080)