diff --git a/html/locales/locale-es_VA.json b/html/locales/locale-es_VA.json new file mode 100644 index 00000000..2b75c4ef --- /dev/null +++ b/html/locales/locale-es_VA.json @@ -0,0 +1,191 @@ +{ + "WEBSITE_TITLE": "Interfície d'usuari web de MineOS", + "NOTIFICACIONES": "Notificacions", + "REFRESH_SERVER_LIST": "Actualitzar llista de servidors", + "REFRESH_PROFILE_LIST": "Actualitzar llista de perfils", + "LOG_OFF": "Tancar sesió", + + "HOST_SETTINGS": "Configuració de 'Host'", + "DASHBOARD": "Tauler", + "CREATE_NEW_SERVER": "Crear Nou Servidor", + "IMPORT_SERVER": "Importar un Servidor", + "PROFILES": "Perfils", + "BUILDTOOLS": "Ferramentes de Construcció", + "CALENDAR": "Calendari", + + "SERVER_SETTINGS": "Configuració del servidor", + "SERVER_STATUS": "Estat del Servidor", + "BACKUPS_AND_RESTORES": "Copies de seguretat", + "SERVER.PROPERTIES": "server.properties", + "RESTORE_POINT": "Punt de restauració", + "RESTORE_POINTS": "Punts de restauració", + "ARCHIVES": "Archius", + "SCHEDULING": "Scheduling", + "CONFIGURATION": "Programació", + "JAVA": "Java", + "GAME_MAINTENANCE": "Manteniment del joc", + "LOGGING": "Registre", + "CONSOLE": "Consola", + "OTHER_FILES": "Atres Archius", + "PLAYER_INTERACTION": "Interacció del Jugador", + + "CURRENTLY_SELECTED_SERVER": "Servidor actualment seleccionat", + "SERVER_OVERVIEW": "Descripció general del servidor", + "SERVERS_RUNNING": "Servidors en marxa", + "PLAYERS_ONLINE": "Jugadors en llínia", + "UPTIME": "Temps Actiu", + "RAM_FREE": "RAM Lliure", + + "LOAD_AVERAGES": "'Càrrega Mitjana'", + "SERVER": "Servidor", + "TYPE": "Tipus", + "perT": "pert", + "STATUS": "Estat", + "MEMORY": "memòria (RAM)", + "UP": "Encés", + "DOWN": "Apagat", + + "SERVER_NAME": "Nom del servidor", + "CREATE_HELP": "Només lletres, números y guions baixos.", + "UNCONVENTIONAL_SERVER_TYPE": "Este es un servidor no convencional, com un servidor proxy/de balanceig de càrrega.", + + "OFFICIAL_MOJANG_SERVER_JARS": "Jars Oficials Servidores Mojang", + "AVAILABLE_SERVER_JARS": "Jars/Paquets de Servidor Disponibles", + "NO_PROFILES_DOWNLOADED": "No hi ha perfils disponibles; comprova la conexió a Internet i actualitza la llista de perfils.", + "IDENTIFIER": "ID", + "RELEASE_TIMESTAMP": "Temps en Marxa", + "RELEASE_TYPE": "Tipus de versió", + "RELEASE": "Release", + "OLD_VERSION": "Versió Anterior", + "SNAPSHOT": "Snapshot", + "SHOW_ALL_RELEASES": "Mostrar tot", + "DOWNLOADED_PROFILES": "Perfils Descarregats", + "CURRENTLY_USING_PROFILE": "Perfil Utilitzat Actualment:", + "PROFILE": "Perfil", + "PROFILE_DESC": "Descripció del Perfil", + "DOWNLOADED": "Descarregat", + + "SPIGOT_CRAFTBUKKIT": "Spigot", + "BUILDTOOLS_INSTRUCTIONS": "Descarregue l'últim archiu jar del constructor i després seleccione la versió de Minecraft per a compilar Spigot. Una vegada que hi haja acabat, copie els archius jar compilats del servidor a qualsevol servidor. El seu servidor no necessitarà un perfil.", + "DOWNLOAD_BUILDTOOLS": "Descarregar l'últim BuildTools.jar", + "DOWNLOAD_PAPERTOOLS": "Descarregar l'últim PaperTools.jar", + "BUILD_JAR": "Crear archiu Jar", + "BUILD_SPIGOT": "Construir Spigot", + "BUILD_PAPER": "Construir PaperSpigot", + "OUTPUT_FROM_BUILDTOOLS": "Eixida de BuildTools.jar", + "JAR_COPY_DESC": "Copiar binaris compilats al directori del servidor", + "COPY_TO_SERVER": "Copiar al servidor", + + "GLANCE": "Servidor d'una ullada", + "INVALID_SERVER_NAME": "El servidor pot contindre només lletres, números i guions baixos. Este servidor no es pot administrar amb MineOS sense canviar-li el nom.", + "LOG_TAILING_RATE_LIMITED": "El servidor ha estat generant registres més enllà de l'umbral del límit de velocitat. El seguimient de registres s'ha detingut i es pot tornar a habilitar actualitzant la pàgina", + "VERSION": "Versió", + "REperTED_VERSION": "Versió de ping", + "MEMORY_FOOTPRINT": "Emprenta de memória", + + "SERVER_ACTIONS": "Accions del Servidor", + "START": "Inici", + "STOP": "Aturar", + "RESTART": "Reiniciar", + "STOP_AND_BACKUP": "Aturar i fer còpia de seguretat", + "KILL":"Matar", + "BROADCAST_TO_LAN": "Transmetre en LAN", + "START_ON_BOOT": "Iniciar servidor a l'iniciar", + "UNCONVENTIONAL_SERVER": "Este no és un servidor de Minecraft convencional", + "COPY_PROFILE": "Copiar perfil a archius de servidor en viu", + "COMMIT_INTERVAL": "Minuts entre committing el món al disc via 'save-all' (buit per a desactivar)", + + "JAVA_SETTINGS": "Configuració de Java", + "MEMORY_ALLOCATION": "Asignació de memòria (tamany heap)", + "JAVA_XMX": "-Xmx", + "JAVA_XMS": "-Xms", + "MB_ABBREVIATION": "MB", + "SELECT_SERVER_PROFILE": "Seleccionar perfil de servidor", + "CHANGE_PROFILE_TO": "Canviar perfil a:", + "CHANGE_JARFILE_TO": "Canviar jar executable a:", + "CURRENT_JAVA_VERSION": "Versió de Java en Us", + "ADDITIONAL_JAVA_ARGS": "Arguments Java Adicionals:", + "ADDITIONAL_JAR_ARGS": "Arguments Jar Adicionals:", + "CHANGE_NICENESS": "Canviar amabilitat del procés", + "NICENESS_DESC": "Amabilitat pot anat des de -20 (alta prioritat) a 19 (baixa prioritat). Per defecte es 0.", + + "MOST_RECENT_RESTORE_POINT": "Punt de restauració més recent", + "OLDEST_RESTORE_POINT": "Punt de restauració més antic", + "SPACE_USED_RESTORES": "Espai utilitzat per Punts de restauració", + "SUCCESS": "éxit", + "RESTORE_POINT_CREATED": "Punt de restauració creat", + "FAILURE": "Oh oh", + "RESTORE_POINT_FAILED": "Intent de Punt de restauració fallit", + "CREATE_NEW_RESTORE_POINT": "Crear un nou punt de restauració", + "GET_INCREMENT_SIZES": "Obtindre tamanys de punts de restauració (lent)", + + "MOST_RECENT_ARCHIVE": "Archiu més Nou", + "OLDEST_ARCHIVE": "Archiu més Antic", + "SPACE_USED_ARCHIVES": "Espai utilitzat per Archius", + "ARCHIVE_CREATED": "Archiu Creat", + "ARCHIVE_FAILED": "Intent de Archivar Fallit", + "CREATE_NEW_ARCHIVE": "Crear un nou Archiu", + "COMMIT_THEN_CREATE_ARCHIVE": "Guardar Tot i Després Crear Archiu", + + "OWNERSHIP_AND_DISK_USAGE": "Propietat i Ús del Disc", + "SERVER_OWNER": "Propietari del Servidor", + "GROUP_OWNER": "Propietari del Grup", + "SPACE_USED_LIVE": "Espai utilitzat per Archius de servidor en viu", + + "DELETE_SERVER": "Eliminar Servidor", + "DELETE": "Eliminar", + "EDIT": "Editar", + "SETTINGS": "Ajustos", + "DELETE_ARCHIVES": "Esborrar Archius:", + "DELETE_RESTORE_POINTS": "Eliminar Punts de restauració:", + "DELETE_LIVE_FILES": "Eliminar Archius del Servidor en viu:", + + "AVAILABLE_RESTORE_POINTS": "Punts de restauració Disponibles", + "STEP": "Pas", + "TIMESTAMP": "Marca de temps", + "SIZE": "Tamany", + "CUMULATIVE_SIZE": "Tamany Acumulatiu", + "RESTORE": "Restaurar", + "PRUNE": "Eliminar més antics que este", + + "AVAILABLE_ARCHIVES": "Archius Disponibles", + "FILENAME": "Nom de Archiu", + "ACTIONS": "Accions", + "DELETE_THIS_ARCHIVE": "Eliminar este Archiu", + "CREATE_FROM_ARCHIVE": "Crear Servidor des de Archiu", + + "CRONTAB_SCHEDULE": "Horari Crontab", + "CRON_EXPRESSION": "Expresió de Cron", + "COMMAND_TO_RUN": "Comando a Executar", + "SEND_TO_CONSOLE": "Enviar a Consola", + "ADDITIONAL_ARGUMENT": "Argument Adicional", + "SUBMIT_CRONJOB": "Enviar cronjob", + "SUSPEND": "Suspendre", + + "CREDITS": "MineOS creat i mantingut per William Dizon | traducció al valencià per Tsolete", + + "CHANGE_LOCALE": "Canviar idioma", + + "EULA_DETECTED": "EULA de Minecraft", + "EULA_MUST_BE_ACCEPTED": "Mojang requerix que els administradors del servidor de Minecraft accepten l'Acuerd de llicéncia d'usuari final abans d'allotjar un servidor de Minecraft. Açò es fa canviant 'eula=false' a 'eula=true' en eula.txt en l'arrel del seu servidor", + "ACCEPT_EULA": "Acceptar EULA", + "READ_THE_EULA": "Llisca l'EULA de Minecraft", + + "STARTING_A_NEW_SERVER": "Iniciant un nou servidor", + "NEW_SERVER_OVERVIEW": "Iniciar un nou servidor reqierix al menys la següent configuració inicial: un servidor JAR executable i el tamany màxim de heap de Java. Seleccione un perfil per a expandir Archius JAR Adicionals.", + + "CREATE_SERVER_FROM_ARCHIVE": "Crear un Nou Servidor a partir d'un Archiu Existent", + "SERVER_FROM_ARCHIVE_DESC": "Escriba el Nom del Nou Servidor a Crear", + + "ADD_SP_ATTRIBUTE": "Agregar Nou Atribut", + "SP_DESCRIPTION": "Agregar un nou par atribut/valor a server.properties.", + "SP_ADD": "Agregar", + + "SUCCEEDED": "èxit", + "FAILED": "fallit", + "!up": "És possible que el servidor no estiga actiu al realitzar esta acció.", + "up": "El servidor deu estar actiu al realitzar esta acció.", + "!exists": "És posible que el servidor no exisiscaa al realiztar esta acció.", + "exists": "No es pot trobar el servidor per a actuar.", + "eula": "Deus acceptar l'Acuerdo de llicència d'usuari final de Mojang per a iniciar este servidor" +} \ No newline at end of file diff --git a/profiles.d/papertemplate.js b/profiles.d/papertemplate.js index e97317fb..1f565e51 100644 --- a/profiles.d/papertemplate.js +++ b/profiles.d/papertemplate.js @@ -3,55 +3,133 @@ var fs = require('fs-extra'); var profile = require('./template'); var axios = require('axios'); -module.exports = function papertemplate (name){ +module.exports = function papertemplate(name) { const lowername = name.toLowerCase(); const titlename = name.charAt(0).toUpperCase() + lowername.substr(1); -return { - name: titlename, - request_args: { - url: `https://papermc.io/api/v2/projects/${lowername}/`, - json: true - }, - handler: function (profile_dir, body, callback) { - var p = []; - var weight = 0; - - try { - for (var index in body.versions) { - var version = body.versions[index]; - - p.push(axios({ url: `https://papermc.io/api/v2/projects/${lowername}/versions/${version}/`}).catch((err) => { - console.log(err); - })); + return { + name: titlename, + request_args: { + url: `https://fill.papermc.io/v3/projects/${lowername}`, + json: true + }, + handler: function(profile_dir, body, callback) { + var p = []; + var weight = 0; + + try { + const allVersions = []; + if (body.versions && typeof body.versions === 'object') { + Object.values(body.versions).forEach(groupVersions => { + if (Array.isArray(groupVersions)) { + allVersions.push(...groupVersions); + } + }); + } + + // ✅ 1. ÚLTIMA build estable (build más alto de latest) + p.push(axios({ + url: `https://fill.papermc.io/v3/projects/${lowername}/versions/latest`, + json: true + }).catch(() => null)); + + // ✅ 2. Builds más recientes por versión específica (top 8) + if (allVersions.length > 0) { + allVersions.sort((a, b) => { + const va = a.split('.').map(Number); + const vb = b.split('.').map(Number); + for (let i = 0; i < Math.max(va.length, vb.length); i++) { + const vaPart = va[i] || 0; + const vbPart = vb[i] || 0; + if (vaPart !== vbPart) return vbPart - vaPart; + } + return 0; + }); + + allVersions.slice(0, 8).forEach(version => { + p.push(axios({ + url: `https://fill.papermc.io/v3/projects/${lowername}/versions/${version}`, + json: true + }).catch(() => null)); + }); + } + + Promise.all(p).then(responses => { + var items = []; + + responses.forEach((response, index) => { + if (!response || response === null) return; + + const data = response.data; + + if (!data || data.ok === false || !data.builds || !Array.isArray(data.builds)) { + return; + } + + // ✅ ORDENAR BUILDS por número (más alto = más reciente) + const builds = [...data.builds].sort((a, b) => { + const buildA = a.build || a; + const buildB = b.build || b; + return buildB - buildA; // DESCENDENTE: mayor build primero + }); + + if (builds.length === 0) return; + + const latestBuildObj = builds[0]; // PRIMERA = MÁS RECIENTE + const buildNumber = latestBuildObj.build || latestBuildObj; + + // Extraer versión correctamente + let version; + if (index === 0) { // latest + version = data.version?.id || data.version_name || data.version || 'latest'; + if (typeof version === 'object') { + version = version.id || version.name || version.version || 'latest'; + } + } else { + version = allVersions[index - 1]; + } + + const isLatest = index === 0; + const item = new profile(); + + item['id'] = `${titlename}-${version}-${buildNumber}`; + item['group'] = lowername; + item['webui_desc'] = isLatest + ? `LATEST ${titlename} (${version}) build #${buildNumber}` + : `${titlename} ${version} latest build #${buildNumber}`; + item['weight'] = weight; + item['filename'] = `${lowername}-${version}-${buildNumber}.jar`; + + let downloadUrl = ''; + if (latestBuildObj.downloads?.application?.url) { + downloadUrl = latestBuildObj.downloads.application.url; + } else { + const verForUrl = isLatest ? version : allVersions[index - 1]; + downloadUrl = `https://fill.papermc.io/v3/projects/${lowername}/versions/${verForUrl}/builds/${buildNumber}/downloads/${lowername}-${verForUrl}-${buildNumber}.jar`; + } + + item['url'] = downloadUrl; + item['downloaded'] = fs.existsSync(path.join(profile_dir, item.id, item.filename)); + item['version'] = version; + item['release_version'] = version; + item['type'] = 'release'; + + items.push(item); + weight++; + }); + + console.log(`Generated ${items.length} Paper endpoints (latest builds)`); + callback(null, items); + }).catch(err => { + console.error('Error:', err); + callback(err, []); + }); + + } catch (e) { + console.error('Error:', e); + callback(e, []); } - Promise.all(p).then(responses => { - p = []; - responses.forEach(response => { - var build = response.data.builds[ response.data.builds.length -1 ]; - const splitPath = response.request.path.split('/'); - var ver =splitPath[splitPath.length - 2]; - var item = new profile(); - - item['id'] = `${titlename}-${ver}-${build}`; - item['group'] = lowername; - item['webui_desc'] = `Latest ${titlename} build for ${ver}`; - item['weight'] = weight; - item['filename'] = `${lowername}-${ver}-${build}.jar`; - item['url'] = `${response.request.res.responseUrl}builds/${build}/downloads/${lowername}-${ver}-${build}.jar`; - item['downloaded'] = fs.existsSync(path.join(profile_dir, item.id, item.filename)); - item['version'] = ver; - item['release_version'] = ver; - item['type'] = 'release' - - p.push(item); - weight++; - }) - }).then(() => { callback(null, p)}) - .catch((err) => {console.error(err)}); - - } catch (e) { console.log(e) } - } //end handler -} -} + } + }; +}; \ No newline at end of file diff --git a/webui.js b/webui.js index e4f225e8..cdd8b4cd 100755 --- a/webui.js +++ b/webui.js @@ -238,9 +238,11 @@ mineos.dependencies(function(err, binaries) { res.end(); }); - app.get('/logout', function(req, res){ - req.logout(); - res.redirect('/admin/login.html'); + app.get('/logout', function(req, res, next) { + req.logout(function(err) { + if (err) { return next(err); } + res.redirect('/'); + }); }); app.use('/socket.io', express.static(__dirname + '/node_modules/socket.io'));