first commit

This commit is contained in:
2026-01-23 15:55:56 +01:00
commit b3827576da
34 changed files with 3805 additions and 0 deletions

View File

@@ -0,0 +1,160 @@
@import url("https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap");
@import url("https://cdn.jsdelivr.net/gh/hung1001/font-awesome-pro@4cac1a6/css/all.css");
* {
margin: 0;
padding: 0;
box-sizing: border-box;
user-select: none;
}
html, body {
overscroll-behavior: none;
user-select: none;
-webkit-touch-callout: none;
}
body {
color: #ffffff;
font-family: "Poppins", sans-serif;
}
main {
position: absolute;
top: 0px;
left: 0px;
right: 0px;
bottom: 0px;
overflow: hidden;
background-color: #212121;
}
main > header {
display: flex;
align-items: center;
width: 100%;
justify-content: right;
-webkit-app-region: drag;
}
main > section {
width: 100%;
}
main > section.frames {
height: calc(60% - 60px);
}
main > section.frames > article.frame {
width: 100%;
height: 100%;
display: grid;
align-content: end;
}
button {
color: #ffffff;
border: none;
cursor: pointer;
outline: none;
transition: .3s all;
font-weight: 600;
font-family: "Poppins", sans-serif;
background-color: transparent;
}
input {
border: none;
outline: none;
color: #ffffff;
padding: 0px 12px;
height: 32px;
font-family: "Poppins", sans-serif;
background-color: transparent;
}
img {
user-select: none;
pointer-events: none;
}
a {
cursor: pointer;
font-size: 12px;
margin-left: calc((100% - 85%) / 2);
text-decoration: underline;
}
div.loader {
overflow: hidden;
position: absolute;
left: 0px;
right: 0px;
bottom: 0px;
width: 100%;
height: 6px;
}
div.loader > div.full {
height: 6px;
width: 100%;
}
div.loader > div.full > div.loading {
height: 6px;
width: 50%;
transition: 1s width;
}
div.loader > div.full > div.loading {
animation: animateLoadingEffect 0.7s linear infinite;
}
@keyframes animateLoadingEffect {
0% {
transform: translateX(-100%);
}
100% {
transform: translateX(200%);
}
}
[hidden] {
display: none !important;
visibility: none !important;
}
* {
scrollbar-width: thin;
scrollbar-color: rgba(146, 146, 146, 0.5) transparent;
}
::-webkit-scrollbar {
width: 6px;
height: 6px;
}
::-webkit-scrollbar-button {
display: none !important;
width: 0 !important;
height: 0 !important;
}
::-webkit-scrollbar-corner {
background: transparent;
}
::-webkit-scrollbar-track {
background: transparent;
}
::-webkit-scrollbar-thumb {
background-color: #9292924d;
border-radius: 10px;
border: 1px solid transparent;
background-clip: content-box;
}
::-webkit-scrollbar-thumb:hover {
background-color: #929292cc;
}

View File

@@ -0,0 +1,251 @@
main {
background-image: url("../img/wallpaper.png");
background-attachment: fixed;
background-size: cover;
background-repeat: no-repeat;
background-position-y: center;
}
main > aside {
position: absolute;
width: 100%;
height: 100%;
background-color: #2626261f;
backdrop-filter: blur(13px);
}
main > aside > nav {
position: absolute;
width: 80px;
height: 100%;
background-color: #414141;
display: flex;
flex-direction: column;
align-items: center;
padding: 13px 0;
}
main > aside > nav > button {
font-size: larger;
margin-top: 20px;
margin-bottom: 10px;
filter: brightness(0.75);
}
main > aside > nav > *.active {
filter: brightness(1);
}
main > aside > nav > button:hover {
filter: brightness(0.90);
}
main > aside > nav > button:first-of-type {
margin-top: 0px;
}
main > aside > nav > button:first-of-type,
main > aside > nav > button:first-of-type:hover {
filter: brightness(1);
}
main > aside > nav > button:first-of-type > img {
width: 60px;
height: 60px;
border-radius: 5px;
}
main > aside > nav > button:nth-child(2) {
margin-top: auto;
}
main > aside > nav > button:last-child {
margin-top: auto;
width: 40px;
height: 40px;
}
main > aside > nav > button:last-child {
margin-bottom: 0;
}
main > aside > nav > button:has(> i.fas.fa-sign-out-alt):hover {
color: #ff4747;
}
main > aside > section.frames {
position: absolute;
left: 80px;
height: 100%;
width: calc(100% - 80px);
}
main > aside > section.frames > article,
main > aside > section.frames > article.frame.dynmap > iframe {
width: 100%;
height: 100%;
}
main > aside > section.frames > article.frame.dynmap > iframe {
background-color: #000000;
}
details {
width: 96%;
min-height: 84px;
color: #ffffff;
cursor: pointer;
margin-left: 2%;
margin-right: 2%;
margin-top: 2%;
margin-bottom: 2%;
border-radius: 10px;
background: #2a2a2a80;
border: 3px solid #929292;
border-radius: 15px;
backdrop-filter: blur(10px);
}
details:nth-of-type(1) {
margin-top: 20px;
}
details > summary {
display: flex;
flex-wrap: wrap;
list-style: none;
flex-direction: row;
}
details > summary > div > i {
font-size: 54px;
margin-left: 30px;
margin-right: 30px;
}
details > summary > div {
height: 80px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: flex-start;
}
details > summary > div > h2 {
font-size: 17px;
}
details > summary > div > h3 {
font-size: 12px;
font-weight: 400;
}
details > div {
cursor: default;
margin-left: 30px;
margin-right: 30px;
margin-bottom: 20px;
}
div.filePathSelector {
width: 100%;
text-align: center;
}
div.filePathSelector > input[type="text"] {
width: 87%;
height: 34px;
border: none;
padding-left: 15px;
border-radius: 10px;
color: #ffffff;
background-color: #262626b9;
margin-right: 0.5%;
}
div.filePathSelector > button {
width: 11%;
color: #ffffff;
border: none;
font-weight: 500;
height: 34px;
cursor: pointer;
font-size: 13px;
border-radius: 10px;
line-height: 18px;
background-color: #E89032;
}
div.filePathSelector > button > i {
margin-right: 4px;
}
details.ram > div > h5 > span {
font-weight: 500;
}
details.ram > div > .ramSelector {
font-weight: 500;
}
input[type="range"] {
border: none;
outline: none;
accent-color: #E89032;
}
section.ramSelector {
display: flex;
flex-wrap: wrap;
justify-content: space-evenly;
}
section.ramSelector > input[type="range"] {
width: calc(100% - ((30px * 2) + 80px));
}
div.container {
margin: 20px 20px 20px 20px;
border: 3px solid #929292;
background: #212121ce;
border-radius: 15px;
color: #fff;
padding: 20px 20px 20px 20px;
word-break: break-all;
overflow: auto;
}
div.logs {
width: calc(100% - 40px);
height: calc(100% - 40px);
}
div.profile {
width: calc(100% - 40px);
height: calc(100% - 40px);
}
div.profile {
display: flex;
justify-content: space-between;
}
div.profile > section.skinview3d {
display: flex;
align-items: center;
justify-content: center;
width: calc(100% / 3);
height: 100%;
}
div.profile > section.cosmectics {
width: calc((100% / 3) * 2 - 20px);
height: 100%;
}
canvas#skin {
width: 85% !important;
height: 85% !important;
outline: none;
}

View File

@@ -0,0 +1,127 @@
main > header {
height: 40px;
}
main > header > button {
width: 40px;
height: 40px;
}
main > section.logo {
display: flex;
align-items: center;
justify-content: center;
height: calc(40% - 20px);
}
main > section.logo > img {
width: 75%;
}
main > section.information {
height: 40px;
display: flex;
align-items: center;
justify-content: center;
}
main > section.information > p {
opacity: 0.50;
font-size: smaller;
font-weight: 600;
}
main > header > button#close {
opacity: 0.75;
font-size: 18px;
}
main > header > button#close:hover {
opacity: 1;
}
main > section.frames > article.frame {
text-align: center;
}
main > section.frames > article.frame > button {
color: #FFFFFF;
width: 85%;
height: 32px;
border-radius: 5px;
font-size: 14px;
margin-top: 4px;
margin-bottom: 4px;
margin-left: auto;
margin-right: auto;
font-weight: 700;
}
main > section.frames > article.frame > button#yggdrasil {
background-color: #db1f29;
}
main > section.frames > article.frame > button > i {
margin-right: 4px;
}
main > section.frames > article.frame > button:hover {
filter: brightness(0.75);
}
main > section.frames > article.frame.provider > button#discord {
color: #FFFFFF;
background-color: #5865F2;
}
main > section.frames > article.frame.manual > input {
background-color: #333333;
width: 85%;
margin-top: 5px;
margin-bottom: 5px;
margin-left: auto;
margin-right: auto;
border-radius: 7px;
}
main > section.frames > article.frame.manual > button {
background-color: #ff9400;
}
main > section.frames > article.frame.manual > a {
color: #ff9400;
font-size: 11px;
text-align: left;
}
main > section.frames > article.frame.manual > a:first-of-type {
margin-top: 3px;
}
main > section.frames > article.frame.manual > a:last-of-type {
margin-bottom: 10px;
}
main > section.frames > article.frame.oauth2 > p {
color: #FFFFFF;
font-weight: 600;
margin-top: 10px;
font-size: 14px;
width: 100%;
padding-left: 20px;
padding-right: 20px;
}
div.loader > div.full > div.loading {
background-color: #ffffff;
}
div.loader > div.full {
background-color: transparent;
}
::-ms-reveal {
filter: invert(100%);
}

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 294 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

View File

@@ -0,0 +1,31 @@
const loader = document.querySelector(".loader")
function toggleLoadingBar() {
if (loader.hasAttribute("hidden")) {
loader.removeAttribute("hidden")
} else {
loader.setAttribute("hidden", "")
}
}
function showLoadingBar() {
if (loader.hasAttribute("hidden")) {
loader.removeAttribute("hidden")
}
}
function hideLoadingBar() {
if (!loader.hasAttribute("hidden")) {
loader.setAttribute("hidden", "")
}
}
window.addEventListener("wheel", (e) => {
if (e.ctrlKey) {
e.preventDefault()
}
}, { passive: false })
window.onpopstate = (event) => {
window.history.pushState(null, document.title, window.location.href)
}

View File

@@ -0,0 +1,10 @@
const frames = document.querySelectorAll("article.frame")
function showFrame(frameIdentifier) {
for (const frame of frames) {
frame.setAttribute("hidden", "")
if (frame.classList.contains(frameIdentifier)) {
frame.removeAttribute("hidden")
}
}
}

34
wwwroot/assets/js/ipc.js Normal file
View File

@@ -0,0 +1,34 @@
const system = {
_pendingRequests: new Map(),
init: function() {
window.external.receiveMessage(response => {
try {
const res = JSON.parse(response)
if (res.requestId && this._pendingRequests.has(res.requestId)) {
const { resolve } = this._pendingRequests.get(res.requestId)
this._pendingRequests.delete(res.requestId)
resolve(res.payload)
}
} catch (e) {
console.error("Erreur format message :", e)
}
})
},
call: function(functionName, data = {}) {
return new Promise((resolve, reject) => {
const requestId = Math.random().toString(36).substring(7)
this._pendingRequests.set(requestId, { resolve, reject })
window.external.sendMessage(JSON.stringify({
requestId: requestId,
functionName: functionName,
payload: data
}))
})
}
}
system.init()

112
wwwroot/assets/js/logged.js Normal file
View File

@@ -0,0 +1,112 @@
const player = await system.call("launcher::profile")
const buttons = document.querySelectorAll("button[frame]")
const dynmapFrame = document.querySelector("article.frame.dynmap > iframe")
const skinViewer = new skinview3d.SkinViewer({
canvas: document.getElementById("skin"),
width: 390,
height: 490,
skin: "assets/img/debug_skin.png"
})
skinViewer.animation = new skinview3d.IdleAnimation()
skinViewer.animation.speed = 1
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
}
function flattenSettings(obj, prefix = "") {
return Object.keys(obj).reduce((acc, k) => {
const pre = prefix.length ? prefix + ".": "";
if (typeof obj[k] === "object" && obj[k] !== null && !Array.isArray(obj[k])) {
Object.assign(acc, flattenSettings(obj[k], pre + k));
} else {
acc[pre + k] = obj[k];
}
return acc;
}, {});
}
window.setting = {}
window.setting.set = async function settingSet(key, value) {
console.log(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 skinViewer = new skinview3d.SkinViewer({
canvas: document.getElementById("skin"),
width: container.clientWidth,
height: container.clientHeight,
skin: "assets/img/debug_skin.png"
})
const ro = new ResizeObserver(() => {
skinViewer.width = container.clientWidth
skinViewer.height = container.clientHeight
})
skinViewer.animation = new skinview3d.IdleAnimation()
window.skinViewer = skinViewer
ro.observe(container)
}
initSkin()
initSettings()

View File

@@ -0,0 +1,39 @@
const version = document.querySelector("#version")
const information = document.querySelector(".information")
document.addEventListener("DOMContentLoaded", async () => {
version.innerText = `Launcher ${await system.call("launcher::version")}`
})
function showInformation() {
return information.removeAttribute("hidden")
}
function hideInformation() {
return information.setAttribute("hidden", "")
}
async function login() {
const username = document.querySelector("#username").value
const password = document.querySelector("#password").value
const result = await system.call("auth::lentia", { username, password })
if (result.success == false) {
await system.call("dialog::error", {
title: result.error.error,
message: result.error.errorMessage
})
}
}
function clearPassword() {
password.value = ""
}
function requestLoginWithOAuth2() {
showFrame("oauth2")
hideInformation()
showLoadingBar()
}
hideLoadingBar()
showFrame("provider")

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long