Introduced GenericFilesService to fetch and validate required game files before launching. Updated launcher version to beta and added support for AuthlibInjector agent in launch options. Improved avatar rendering and button states in the UI, including pixelated avatar display and disabled state handling for logout during game launch.
315 lines
10 KiB
JavaScript
315 lines
10 KiB
JavaScript
const buttons = document.querySelectorAll("button[frame]")
|
|
const dynmapFrame = document.querySelector("article.frame.dynmap > iframe")
|
|
const capesSelector = document.querySelector("article.capes > div.capes")
|
|
const logsContainer = document.querySelector("div.container.logs")
|
|
const playButton = document.querySelector("button.play")
|
|
const logoutButton = document.querySelector("button.logout")
|
|
|
|
let viewerInstance = new skinview3d.SkinViewer({
|
|
canvas: document.getElementById("skin"),
|
|
width: 390,
|
|
height: 490,
|
|
skin: "https://yggdrasil.azures.fr/textures/texture/steve.png"
|
|
})
|
|
|
|
viewerInstance.animation = new skinview3d.IdleAnimation()
|
|
viewerInstance.animation.speed = 1
|
|
|
|
function wait(ms) {
|
|
return new Promise(resolve => setTimeout(resolve, ms))
|
|
}
|
|
|
|
function setActiveButton(frameIdentifier) {
|
|
for (const button of buttons) {
|
|
button.classList.remove("active")
|
|
if (button.getAttribute("frame") == frameIdentifier) {
|
|
button.classList.add("active")
|
|
}
|
|
}
|
|
}
|
|
|
|
function fixedTo(number, n) {
|
|
const k = Math.pow(10, n)
|
|
const result = (Math.round(number * k) / k)
|
|
return Number.isInteger(result) ? result.toFixed(2) : result
|
|
}
|
|
|
|
window.getPlayer = async function getPlayer() {
|
|
const result = await system.call("network::getPlayer")
|
|
console.log(result)
|
|
if (result.error) {
|
|
console.error("Impossible de récupéré le profil")
|
|
return null
|
|
}
|
|
return result
|
|
}
|
|
|
|
window.displayMinecraftHead = function displayMinecraftHead(skinUrl, targetImg) {
|
|
const canvas = document.createElement("canvas")
|
|
const ctx = canvas.getContext("2d")
|
|
const skinImg = new Image()
|
|
|
|
skinImg.crossOrigin = "anonymous"
|
|
|
|
skinImg.onload = function() {
|
|
canvas.width = 8
|
|
canvas.height = 8
|
|
|
|
ctx.imageSmoothingEnabled = false
|
|
|
|
ctx.drawImage(skinImg, 8, 8, 8, 8, 0, 0, 8, 8)
|
|
ctx.drawImage(skinImg, 40, 8, 8, 8, 0, 0, 8, 8)
|
|
document.querySelector(targetImg).src = canvas.toDataURL()
|
|
}
|
|
|
|
skinImg.src = skinUrl
|
|
}
|
|
|
|
window.profile = await getPlayer()
|
|
displayMinecraftHead(`https://yggdrasil.azures.fr/textures/${profile.skins.find(skin => skin.state == "ACTIVE").url.replace(/^\//, "")}`, "img.avatar")
|
|
|
|
window.refreshProfile = async function refreshProfile() {
|
|
window.profile = await getPlayer()
|
|
}
|
|
|
|
window.setting = {}
|
|
|
|
window.setting.set = async function settingSet(key, value) {
|
|
await system.call("settings::set", { key, value })
|
|
}
|
|
|
|
window.showPage = function showPage(frameIdentifier) {
|
|
showFrame(frameIdentifier)
|
|
setActiveButton(frameIdentifier)
|
|
}
|
|
|
|
window.initDynmap = async function initDynmap() {
|
|
const dynampUrl = await system.call("lentia::dynamp") || "http://azures.fr:8123/"
|
|
if (dynmapFrame.src != dynampUrl) {
|
|
dynmapFrame.src = dynampUrl
|
|
}
|
|
}
|
|
|
|
window.getRamInformation = async function getRamInformation() {
|
|
const $ram = await system.call("hardware::ram")
|
|
ram.setAttribute("max", Math.floor($ram.freeGb * 1024))
|
|
freeRam.innerText = `${$ram.totalGb} Gb`
|
|
totalRam.innerText = `${$ram.freeGb} Gb`
|
|
}
|
|
|
|
window.handleSettingsChanges = async function handleSettingsChanges(key, value) {
|
|
const span = document.querySelector(`span#${key.includes("ram") ? "currentRam" : key}`)
|
|
setting.set(key, value)
|
|
if (span) {
|
|
span.innerText = key.includes("ram") ? fixedTo(value / 1024, 2) + " G" : value
|
|
}
|
|
}
|
|
|
|
window.initSettings = async function initSettings() {
|
|
const settings = await system.call("settings::read")
|
|
ram.value = settings.ram.max
|
|
javaPath.value = settings.javaPath
|
|
currentRam.innerText = fixedTo(settings.ram.max / 1024, 2) + " G"
|
|
getRamInformation()
|
|
}
|
|
|
|
window.initSkin = async function initSkin() {
|
|
const container = document.querySelector(".skinview3d")
|
|
if (container.clientWidth === 0 || container.clientHeight === 0) {
|
|
requestAnimationFrame(initSkin)
|
|
return
|
|
}
|
|
|
|
const skinUrl = `https://yggdrasil.azures.fr/textures/${profile.skins.find(skin => skin.state == "ACTIVE").url.replace(/^\//, "")}`
|
|
viewerInstance = new skinview3d.SkinViewer({
|
|
canvas: document.getElementById("skin"),
|
|
width: container.clientWidth,
|
|
height: container.clientHeight,
|
|
skin: skinUrl
|
|
})
|
|
|
|
displayMinecraftHead(skinUrl, "img.avatar")
|
|
|
|
const activeCape = window.profile.capes.find(s => s.state === "ACTIVE") || null
|
|
const capeUrl = activeCape == null ? null : `https://yggdrasil.azures.fr/textures/${activeCape.url.replace(/^\//, "")}?t=${Date.now()}`
|
|
|
|
viewerInstance.animation = new skinview3d.IdleAnimation()
|
|
viewerInstance.nameTag = profile.name
|
|
viewerInstance.zoom = 0.7
|
|
viewerInstance.loadCape(capeUrl)
|
|
|
|
|
|
const ro = new ResizeObserver(() => {
|
|
viewerInstance.width = container.clientWidth
|
|
viewerInstance.height = container.clientHeight
|
|
})
|
|
|
|
ro.observe(container)
|
|
}
|
|
|
|
window.selectSkin = async function selectSkin() {
|
|
const skin = await system.call("dialog::selectSkin")
|
|
if (!skin.success) {
|
|
return iziToast.error({ title: "Erreur", message: "Impossible d'envoyer le skin" })
|
|
}
|
|
return validateSkinSelection(skin.path)
|
|
}
|
|
|
|
window.validateSkinSelection = async function validateSkinSelection(localPath) {
|
|
const isSlim = confirm("Modèle Slim ?")
|
|
const variant = isSlim ? "slim" : "classic"
|
|
|
|
const result = await system.call("network::uploadSkin", {
|
|
path: localPath,
|
|
variant: variant
|
|
})
|
|
|
|
if (result.success && viewerInstance) {
|
|
await wait(500)
|
|
await refreshProfile()
|
|
const activeSkin = window.profile.skins.find(s => s.state === "ACTIVE")
|
|
const activeCape = window.profile.capes.find(s => s.state === "ACTIVE") || null
|
|
|
|
if (activeSkin) {
|
|
const skinUrl = `https://yggdrasil.azures.fr/textures/${activeSkin.url.replace(/^\//, "")}?t=${Date.now()}`
|
|
const capeUrl = activeCape == null ? null : `https://yggdrasil.azures.fr/textures/${activeCape.url.replace(/^\//, "")}?t=${Date.now()}`
|
|
displayMinecraftHead(skinUrl, "img.avatar")
|
|
await viewerInstance.loadSkin(skinUrl, {
|
|
model: variant.toLowerCase() === "slim" ? "slim" : "default"
|
|
})
|
|
await viewerInstance.loadCape(capeUrl)
|
|
}
|
|
}
|
|
}
|
|
|
|
window.initCapesSelector = async function initCapesSelector() {
|
|
capesSelector.innerHTML = ""
|
|
const blankCape = document.createElement("div")
|
|
blankCape.classList.add("cape")
|
|
blankCape.setAttribute("onclick", `hideCape()`)
|
|
blankCape.title = "Cacher ma cape"
|
|
capesSelector.appendChild(blankCape)
|
|
await viewerInstance.loadCape(null)
|
|
for (const cape of profile.capes) {
|
|
const $cape = document.createElement("div")
|
|
$cape.classList.add("cape")
|
|
$cape.setAttribute("title", cape.alias)
|
|
$cape.setAttribute("style", `background-image: url("https://yggdrasil.azures.fr/textures/${cape.url.replace(/^\//, "")}?t=${Date.now()}") !important;`)
|
|
$cape.setAttribute("onclick", `showCape("${cape.id}")`)
|
|
if (cape.state == "ACTIVE") {
|
|
$cape.classList.add("active")
|
|
await viewerInstance.loadCape(`https://yggdrasil.azures.fr/textures/${cape.url.replace(/^\//, "")}?t=${Date.now()}`)
|
|
}
|
|
capesSelector.appendChild($cape)
|
|
}
|
|
}
|
|
|
|
window.showCape = async function showCape(id) {
|
|
const result = await system.call("network::showCape", { capeId: id })
|
|
|
|
if (result.success) {
|
|
await refreshProfile()
|
|
await initCapesSelector()
|
|
|
|
if (typeof viewerInstance !== "undefined" && window.profile) {
|
|
const activeCape = window.profile.capes.find(c => c.state === "ACTIVE")
|
|
if (activeCape) {
|
|
const fullUrl = `https://yggdrasil.azures.fr/textures/${activeCape.url.replace(/^\//, "")}?t=${Date.now()}`
|
|
await viewerInstance.loadCape(fullUrl)
|
|
}
|
|
}
|
|
|
|
return result.data
|
|
} else {
|
|
alert("Erreur d'équipement : " + result.error)
|
|
}
|
|
}
|
|
|
|
window.hideCape = async function hideCape() {
|
|
const result = await system.call("network::hideCape")
|
|
|
|
if (result.success) {
|
|
await refreshProfile()
|
|
await initCapesSelector()
|
|
|
|
if (typeof viewerInstance !== "undefined") {
|
|
viewerInstance.loadCape(null)
|
|
}
|
|
|
|
return result.data
|
|
} else {
|
|
alert("Erreur lors du retrait : " + result.error)
|
|
}
|
|
}
|
|
|
|
window.changeUsername = async function changeUsername(newName) {
|
|
if (!newName || newName.length < 3) return alert("Pseudo trop court !");
|
|
|
|
const result = await system.call("network::changeUsername", {
|
|
username: newName
|
|
})
|
|
|
|
if (result.success) {
|
|
viewerInstance.nameTag = result.profile.name
|
|
window.profile = result.profile
|
|
} else {
|
|
alert("Erreur : " + result.error)
|
|
}
|
|
}
|
|
|
|
window.gamelog = {}
|
|
|
|
window.gamelog.put = function put(log) {
|
|
const logElement = document.createElement("p")
|
|
logElement.innerText = log
|
|
logsContainer.appendChild(logElement)
|
|
}
|
|
|
|
window.gamelog.clear = function clear() {
|
|
logsContainer.innerHTML = ""
|
|
}
|
|
|
|
window.play = async function play() {
|
|
gamelog.clear()
|
|
showLoadingBar()
|
|
playButton.setAttribute("disabled", "")
|
|
logoutButton.setAttribute("disabled", "")
|
|
const gameLaunch = await system.call("launcher::game")
|
|
if (gameLaunch.success) {
|
|
hideLoadingBar()
|
|
} else {
|
|
hideLoadingBar()
|
|
playButton.removeAttribute("disabled")
|
|
logoutButton.removeAttribute("disabled")
|
|
}
|
|
}
|
|
|
|
window.external.receiveMessage(message => {
|
|
try {
|
|
const data = JSON.parse(message)
|
|
|
|
switch (data.requestId) {
|
|
case "game::log":
|
|
const logMessage = data.payload.message
|
|
if (logMessage != "GAME_CLOSED") {
|
|
console.log("MC:", logMessage)
|
|
gamelog.put(logMessage)
|
|
logsContainer.scrollTop = logsContainer.scrollHeight
|
|
} else {
|
|
playButton.removeAttribute("disabled")
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
} catch (e) {
|
|
console.error("Erreur réception message Photino:", e)
|
|
}
|
|
})
|
|
|
|
await initSkin()
|
|
await initSettings()
|
|
await initCapesSelector()
|
|
hideLoadingBar()
|
|
showFrame("game") |