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..75fde174 100644
--- a/profiles.d/papertemplate.js
+++ b/profiles.d/papertemplate.js
@@ -3,55 +3,114 @@ var fs = require('fs-extra');
var profile = require('./template');
var axios = require('axios');
-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);
- }));
-
+module.exports = function papertemplate(name) {
+ const lowername = String(name || 'paper').toLowerCase(); // esperado: "paper"
+ const titlename = lowername.charAt(0).toUpperCase() + lowername.substr(1);
+
+ const USER_AGENT = `${titlename}-MineOS/1.0 (+admin@example.com)`;
+
+ const AXIOS_OPTS = {
+ headers: {
+ 'User-Agent': USER_AGENT,
+ 'Accept': 'application/json'
+ },
+ timeout: 20000,
+ validateStatus: (s) => s >= 200 && s < 300
+ };
+
+ return {
+ name: titlename,
+
+ request_args: {
+ url: `https://fill.papermc.io/v3/projects/${lowername}`,
+ json: true,
+ headers: {
+ 'User-Agent': USER_AGENT,
+ 'Accept': 'application/json'
}
- 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}`;
+ },
+
+ handler: function (profile_dir, body, callback) {
+ (async () => {
+ try {
+
+ let projectData = body;
+ if (!projectData || !projectData.versions || typeof projectData.versions !== 'object') {
+ const projResp = await axios.get(
+ `https://fill.papermc.io/v3/projects/${lowername}`,
+ AXIOS_OPTS
+ );
+ projectData = projResp.data;
+ }
+
+ if (!projectData || !projectData.versions || typeof projectData.versions !== 'object') {
+ return callback(new Error('Respuesta inválida de Fill: faltan versiones.'), []);
+ }
+
+ const allVersions = [];
+ Object.values(projectData.versions).forEach((groupVersions) => {
+ if (Array.isArray(groupVersions)) allVersions.push(...groupVersions);
+ });
+
+ if (allVersions.length === 0) {
+ return callback(new Error('No se encontraron versiones en Fill.'), []);
+ }
+
+ let selectedVersion = null;
+ let selectedStableBuild = null;
+
+ for (const ver of allVersions) {
+ try {
+ const buildsResp = await axios.get(
+ `https://fill.papermc.io/v3/projects/${lowername}/versions/${encodeURIComponent(ver)}/builds`,
+ AXIOS_OPTS
+ );
+
+ const builds = buildsResp.data;
+ if (!Array.isArray(builds) || builds.length === 0) continue;
+
+ const stable = builds.find((b) => b && b.channel === 'STABLE' && b.downloads);
+ if (!stable) continue;
+
+ selectedVersion = ver;
+ selectedStableBuild = stable;
+ break;
+ } catch (_) {
+ continue;
+ }
+ }
+
+ if (!selectedVersion || !selectedStableBuild) {
+ return callback(new Error('No se encontró ninguna versión con build STABLE.'), []);
+ }
+
+ const buildId = selectedStableBuild.id;
+ const downloadUrl = selectedStableBuild.downloads?.['server:default']?.url;
+
+ if (!downloadUrl) {
+ return callback(new Error('Build STABLE encontrado pero sin URL de descarga.'), []);
+ }
+
+ // 4) Crear el item MineOS
+ const item = new profile();
+ item['id'] = `${titlename}-${selectedVersion}-${buildId}`;
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['webui_desc'] = `LATEST STABLE ${titlename} (${selectedVersion}) build #${buildId}`;
+ item['weight'] = 0;
+
+ item['filename'] = `${lowername}-${selectedVersion}-${buildId}.jar`;
+ item['url'] = downloadUrl;
+
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
-}
-}
+ item['version'] = selectedVersion;
+ item['release_version'] = selectedVersion;
+ item['type'] = 'release';
+
+ return callback(null, [item]);
+ } catch (err) {
+ return callback(err, []);
+ }
+ })();
+ }
+ };
+};
\ 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'));