Add online player skin rendering to the webui
This commit is contained in:
parent
1fb05934f7
commit
f1dbbcbbb1
|
@ -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>
|
||||||
|
|
|
@ -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")
|
||||||
|
|
|
@ -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');
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue