Added few internals modules

-  Added game setting parser/stringifier 📝
  -  Added skin upload using mojang api 👾
  -  Added server ping using mcsrvstat.us 🖥️
  -  Added api and endpoints to the config ⚙️
  -  Added syscalls for modules 🧩
This commit is contained in:
Gilles Lazures 2025-04-29 11:08:58 +02:00
parent 5c8be610f1
commit 13c6f14886
6 changed files with 129 additions and 3 deletions

View File

@ -8,7 +8,7 @@
</head>
<body>
<main>
<button class="close" onclick="sys.call('window::close')">
<button class="close" onclick="system.call('window::close')">
<i class="fas fa-times"></i>
</button>
<nav hidden>

View File

@ -5,5 +5,19 @@
"fileHash": "/api/v1/file/hash/",
"checkBanStatus": "/api/v1/ban/iam"
}
},
"minecraft": {
"server": {
"host": "mc.thealfiperf.com",
"port": 3145
},
"services": {
"api": {
"base": "https://api.minecraftservices.com",
"endpoints": {
"uploadSkin": "/minecraft/profile/skins"
}
}
}
}
}

29
main.js
View File

@ -2,8 +2,9 @@ const { BrowserWindow, app, net, dialog, ipcMain, nativeImage } = require("elect
const os = require("os")
const hwid = require("./modules/hwid")
const path = require("node:path")
const serverPing = require("./modules/serverPing")
const config = require("./config.json")
let launcherWindow
let launcherWindow, auth, skinPath
async function createLauncherWindow() {
if (net.isOnline()) {
@ -80,7 +81,7 @@ app.on("window-all-closed", () => {
app.quit()
})
ipcMain.on("call", (event, data) => {
ipcMain.on("call", async (event, data) => {
switch (data.method) {
case "hardware::ramInformation":
launcherWindow.webContents.send("hardware::ramInformation", {
@ -88,5 +89,29 @@ ipcMain.on("call", (event, data) => {
avaibleRam: Math.round(os.freemem() / 1024 / 1024 * 100) / 100,
})
break
case "server::ping":
const status = await serverPing.fetchServerStatus()
launcherWindow.webContents.send("Response<server::ping>", status)
break
case "window::close":
launcherWindow.close()
app.quit()
break
case "skin::set":
const file = await dialog.showOpenDialog(launcherWindow, {
filters: [
{ name: "Images", extensions: ["png", "jpg", "jpeg"] }
],
properties: ["openFile", "dontAddToRecent", "showHiddenFiles"],
title: "Sélectionner l'image de votre skin",
securityScopedBookmarks: true
})
if (!file.canceled) {
skinPath = file.filePaths[0]
}
break
case "skin::reset":
skinPath = null
break
}
})

43
modules/gameSettings.js Normal file
View File

@ -0,0 +1,43 @@
const fs = require("node:fs")
const path = require("node:path")
function parseSettings(settingsFile) {
const settings = fs.readFileSync(settingsFile, "utf-8").toString().split("\n").filter(line => line.trim() !== "")
const parseSettings = {}
for (let i = 0; i < settings.length; i++) {
const line = settings[i].trim()
const [key, value] = line.split(":")
if (key && value) {
const trimmedValue = value.trim().toLowerCase()
if (trimmedValue === "true" || trimmedValue === "false") {
parseSettings[key.trim()] = trimmedValue === "true"
} else {
parseSettings[key.trim()] = isNaN(value) ? value.trim() : parseInt(value, 10)
}
}
}
return parseSettings
}
function stringfySettings(settingsFile) {
const settingsObject = JSON.parse(fs.readFileSync(settingsFile, "utf-8").toString())
const settingsArray = []
if (typeof settingsObject !== "object" || settingsObject === null) {
throw new Error("Invalid settings object")
}
for (const settingKey in settingsObject) {
if (Object.prototype.hasOwnProperty.call(settingsObject, settingKey)) {
const settingValue = settingsObject[settingKey]
if (typeof settingValue === "object" || typeof settingValue === "function" || typeof settingValue === "symbol") {
throw new Error(`Invalid value for setting "${settingKey}": ${settingValue}`)
}
settingsArray.push(`${settingKey}:${settingValue}`)
}
}
return settingsArray.join("\n")
}
module.exports = {
parseSettings,
stringfySettings
}

26
modules/mojangAPI.js Normal file
View File

@ -0,0 +1,26 @@
const fs = require("node:fs")
const path = require("node:path")
const config = require("../config.json")
async function uploadSkin(filePath, variant, token) {
const form = new FormData()
form.append("variant", variant)
form.append("file", fs.readFileSync(filePath), path.parse(filePath).base)
const response = await fetch(`${config.minecraft.services.api.base}${config.minecraft.services.api.endpoints.uploadSkin}`, {
method: "POST",
body: form,
headers: {
Authorization: `Bearer ${token}`
}
})
if (response.ok) {
const json = await response.json()
return json
} else {
throw new Error(`Error uploading skin: ${response.status} ${response.statusText}`)
}
}
module.exports = {
uploadSkin
}

18
modules/serverPing.js Normal file
View File

@ -0,0 +1,18 @@
const config = require("../config.json")
async function fetchServerStatus() {
const response = await fetch(`https://api.mcsrvstat.us/3/${config.minecraft.server.host}:${config.minecraft.server.port}`)
const json = await response.json()
return {
online: json.online,
players: {
online: json.players.online || 0,
max: json.players.max || 0
}
}
}
module.exports = {
fetchServerStatus
}