Add online player skin rendering to the webui

This commit is contained in:
sqozz 2021-03-25 01:27:33 +01:00
parent 1fb05934f7
commit f1dbbcbbb1
4 changed files with 83 additions and 0 deletions

View file

@ -41,6 +41,9 @@
</div> </div>
</div> </div>
</div> </div>
<div id="skin_container">
</div>
<script src="/js/index.js"></script> <script src="/js/index.js"></script>
<script src="/js/skinview3d.bundle.js"></script>
</body> </body>
</html> </html>

View file

@ -5,6 +5,10 @@ from os.path import join as pathjoin
from random import random, choice from random import random, choice
from mcrcon import MCRcon from mcrcon import MCRcon
import configparser import configparser
import requests
import hashlib
import base64
import json
import re import re
# echo -n "["; ls | xargs -I{} echo -n \"{}\",; echo "]" # echo -n "["; ls | xargs -I{} echo -n \"{}\",; echo "]"
@ -24,6 +28,15 @@ def index():
players = currentPlayerData() players = currentPlayerData()
return template("html/index.html", **{"player_count": players["count"]["current"] , "max_players": players["count"]["max"], "news": news}) 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") @route("/img/bg.png")
def random_bg_image(): def random_bg_image():
bg_file = choice(BG_IMAGES) bg_file = choice(BG_IMAGES)
@ -63,6 +76,18 @@ def currentPlayerData():
player["players"].append({"name": name, "uuid": uuid}) player["players"].append({"name": name, "uuid": uuid})
return player 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(): def parseConfig():
config = configparser.ConfigParser() config = configparser.ConfigParser()
config.read("config.ini") config.read("config.ini")

View file

@ -126,6 +126,17 @@ body {
background-size: 80px; background-size: 80px;
} }
#skin_container {
position: absolute;
left: 0;
top: 0;
margin: 10px;
display: flex;
flex-flow: column wrap;
background-color: #fdfdfd45;
border: 3px solid #686767;
}
@font-face { @font-face {
font-family: 'minecraft'; font-family: 'minecraft';
src: URL('/fonts/Minecraft.ttf') format('truetype'); src: URL('/fonts/Minecraft.ttf') format('truetype');

View file

@ -9,3 +9,47 @@ function toggleDetails(e) {
} }
return false; return false;
} }
// Fetch a list of all online player hashes
function getSkins() {
let xhr = new XMLHttpRequest();
xhr.open ( "GET", "getPlayerSkins", true );
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
skins = JSON.parse(xhr.responseText)["skins"];
skins.forEach(skin_hash => addSkin(skin_hash));
}
}
xhr.send ();
}
// Add a new canvas to the container and render the given skin
function addSkin(hash) {
var container = document.querySelector("#skin_container");
var canvas = document.createElement("canvas");
container.appendChild(canvas);
canvas.id = hash;
renderSkin(hash, canvas);
}
// Create a new instance of the renderer in the given canvas with the given hash as player skin
function renderSkin(hash, canvas) {
let skinViewer = new skinview3d.SkinViewer({
canvas: canvas,
width: 60,
height: 80,
skin: "/img/skins/" + hash
});
let control = skinview3d.createOrbitControls(skinViewer);
control.enableRotate = false;
control.enableZoom = false;
control.enablePan = false;
let walk = skinViewer.animations.add(skinview3d.WalkingAnimation);
let rotate = skinViewer.animations.add(skinview3d.RotatingAnimation);
}
window.onload = function () {
getSkins();
}