From a7a5284382ec2f115c36458fea7fb7471a120f55 Mon Sep 17 00:00:00 2001 From: Evan Goode Date: Sun, 13 Jul 2025 23:07:36 -0400 Subject: [PATCH] i18n player.go --- api_test.go | 2 +- flake.nix | 1 + front_test.go | 6 +- locales/es-US/default.po | 452 ++++++++++++++++++++++++++++----------- model.go | 26 ++- player.go | 30 ++- 6 files changed, 369 insertions(+), 148 deletions(-) diff --git a/api_test.go b/api_test.go index 5524e1e..00cbc81 100644 --- a/api_test.go +++ b/api_test.go @@ -417,7 +417,7 @@ func (ts *TestSuite) testAPICreatePlayer(t *testing.T) { assert.Equal(t, http.StatusBadRequest, rec.Code) var apiError APIError assert.Nil(t, json.NewDecoder(rec.Body).Decode(&apiError)) - assert.Equal(t, "You are only allowed to own 1 player(s).", apiError.Message) + assert.Equal(t, "You are only allowed to own 1 player.", apiError.Message) // Admins should be able to override the MaxPlayerCount limit rec = ts.PostJSON(t, ts.Server, DRASL_API_PREFIX+"/players", payload, nil, &admin.APIToken) diff --git a/flake.nix b/flake.nix index d1ffea4..f9147df 100644 --- a/flake.nix +++ b/flake.nix @@ -144,6 +144,7 @@ pre-commit sqlite-interactive swagger-codegen + gettext ]; }; }); diff --git a/front_test.go b/front_test.go index 8272e44..7a8625d 100644 --- a/front_test.go +++ b/front_test.go @@ -859,7 +859,7 @@ func (ts *TestSuite) testRegistrationExistingPlayerNoVerification(t *testing.T) form.Set("existingPlayer", "on") form.Set("returnUrl", returnURL) rec := ts.PostForm(t, ts.Server, "/web/register", form, nil, nil) - ts.registrationShouldFail(t, rec, "Couldn't find your account, maybe try again: registration server returned error", returnURL) + ts.registrationShouldFail(t, rec, "Couldn't find your account, maybe try again: registration server returned an error", returnURL) } } @@ -909,7 +909,7 @@ func (ts *TestSuite) testImportPlayerNoVerification(t *testing.T) { form.Set("existingPlayer", "on") form.Set("returnUrl", returnURL) rec := ts.PostForm(t, ts.Server, "/web/create-player", form, []http.Cookie{*browserTokenCookie}, nil) - ts.createPlayerShouldFail(t, rec, "Couldn't find your account, maybe try again: registration server returned error", returnURL) + ts.createPlayerShouldFail(t, rec, "Couldn't find your account, maybe try again: registration server returned an error", returnURL) } } @@ -1161,7 +1161,7 @@ func (ts *TestSuite) testUserUpdate(t *testing.T) { assert.Nil(t, writer.WriteField("returnUrl", ts.App.FrontEndURL+"/web/user")) assert.Nil(t, writer.Close()) rec := ts.PostMultipart(t, ts.Server, "/web/update-user", body, writer, []http.Cookie{*browserTokenCookie}, nil) - ts.updateUserShouldFail(t, rec, "Invalid password: password must be longer than 8 characters", ts.App.FrontEndURL+"/web/user") + ts.updateUserShouldFail(t, rec, "Invalid password: must be longer than 8 characters", ts.App.FrontEndURL+"/web/user") } } diff --git a/locales/es-US/default.po b/locales/es-US/default.po index 3e7f355..4f4cabf 100644 --- a/locales/es-US/default.po +++ b/locales/es-US/default.po @@ -43,26 +43,53 @@ msgstr "Contraseña" msgid "Configuring your client" msgstr "Configurando tu cliente" -msgid "Using {{ index . 0 }} on the client requires a third-party launcher that supports custom API servers. {{ index . 1 }}, a fork of Prism Launcher, is recommended, but {{ index . 2 }} also works. Both are free/libre." -msgstr "Usar {{ index . 0 }} en el cliente requiere un lanzador de terceros que soporte servidores API personalizados. Se recomienda {{ index . 1 }}, un fork de Prism Launcher, pero {{ index . 2 }} también funciona. Ambos son libres." +msgid "" +"Using {{ index . 0 }} on the client requires a third-party launcher that " +"supports custom API servers. {{ index . 1 }}, a fork of Prism Launcher, is " +"recommended, but {{ index . 2 }} also works. Both are free/libre." +msgstr "" +"Usar {{ index . 0 }} en el cliente requiere un lanzador de terceros que " +"soporte servidores API personalizados. Se recomienda {{ index . 1 }}, un " +"fork de Prism Launcher, pero {{ index . 2 }} también funciona. Ambos son " +"libres." msgid "Click your account in the top right and select “Manage Accounts...”." -msgstr "Haz clic en tu cuenta en la esquina superior derecha y selecciona “Administrar cuentas...”." +msgstr "" +"Haz clic en tu cuenta en la esquina superior derecha y selecciona " +"“Administrar cuentas...”." msgid "Click “Add authlib-injector” in the right-hand sidebar." msgstr "Haz clic en “Add authlib-injector” en la barra lateral derecha." -msgid "Enter your player name and your {{ index . 0 }} password or Minecraft Token, and use {{ index . 1 }} for the URL. Click “OK”." -msgstr "Introduce tu nombre de jugador y tu contraseña de {{ index . 0 }} o Token de Minecraft, y usa {{ index . 1 }} para la URL. Haz clic en “Aceptar”." +msgid "" +"Enter your player name and your {{ index . 0 }} password or Minecraft Token, " +"and use {{ index . 1 }} for the URL. Click “OK”." +msgstr "" +"Introduce tu nombre de jugador y tu contraseña de {{ index . 0 }} o Token de " +"Minecraft, y usa {{ index . 1 }} para la URL. Haz clic en “Aceptar”." -msgid "Go to the “Account List” view by clicking the account at the top of the sidebar." -msgstr "Ve a la vista “Lista de cuentas” haciendo clic en la cuenta en la parte superior de la barra lateral." +msgid "" +"Go to the “Account List” view by clicking the account at the top of the " +"sidebar." +msgstr "" +"Ve a la vista “Lista de cuentas” haciendo clic en la cuenta en la parte " +"superior de la barra lateral." -msgid "At the bottom left, click “New Auth Server” and enter {{ index . 0 }}. Click “Next” and then “Finish”." -msgstr "En la parte inferior izquierda, haz clic en “Añadir un servidor de autenticación” e ingresa {{ index . 0 }}. Haz clic en “Siguiente” y luego en “Finalizar”." +msgid "" +"At the bottom left, click “New Auth Server” and enter {{ index . 0 }}. Click " +"“Next” and then “Finish”." +msgstr "" +"En la parte inferior izquierda, haz clic en “Añadir un servidor de " +"autenticación” e ingresa {{ index . 0 }}. Haz clic en “Siguiente” y luego en " +"“Finalizar”." -msgid "In the sidebar, click the newly-added authentication server, labeled “%s”. Enter your %s player name and password and click “Login”." -msgstr "En la barra lateral, haz clic en el servidor de autenticación recién añadido, etiquetado como “%s”. Ingresa tu nombre de jugador y contraseña de %s y haz clic en “Acceder”." +msgid "" +"In the sidebar, click the newly-added authentication server, labeled “%s”. " +"Enter your %s player name and password and click “Login”." +msgstr "" +"En la barra lateral, haz clic en el servidor de autenticación recién " +"añadido, etiquetado como “%s”. Ingresa tu nombre de jugador y contraseña de " +"%s y haz clic en “Acceder”." msgid "Other launchers" msgstr "Otros lanzadores" @@ -70,8 +97,12 @@ msgstr "Otros lanzadores" msgid "Use the authlib-injector URL {{ index . 0 }}." msgstr "Usa la URL de authlib-injector {{ index . 0 }}." -msgid "Or, if your launcher supports custom API servers but not via authlib-injector, use the following URLs:" -msgstr "O, si tu lanzador soporta servidores API personalizados pero no a través de authlib-injector, usa las siguientes URLs:" +msgid "" +"Or, if your launcher supports custom API servers but not via authlib-" +"injector, use the following URLs:" +msgstr "" +"O, si tu lanzador soporta servidores API personalizados pero no a través de " +"authlib-injector, usa las siguientes URLs:" msgid "Authentication server:" msgstr "Servidor de “Authentication”:" @@ -91,26 +122,57 @@ msgstr "Configurando tu servidor" msgid "Minecraft 1.16 and later" msgstr "Minecraft 1.16 y posteriores" -msgid "On recent versions of Minecraft, you can use %s on an unmodified Vanilla server. To do so, add the following arguments before you specify the jar file when you start the server:" -msgstr "En las versiones recientes de Minecraft, puedes usar %s en un servidor Vanilla sin modificaciones. Para hacerlo, agrega los siguientes argumentos antes de especificar el archivo jar al iniciar el servidor:" +msgid "" +"On recent versions of Minecraft, you can use %s on an unmodified Vanilla " +"server. To do so, add the following arguments before you specify the jar " +"file when you start the server:" +msgstr "" +"En las versiones recientes de Minecraft, puedes usar %s en un servidor " +"Vanilla sin modificaciones. Para hacerlo, agrega los siguientes argumentos " +"antes de especificar el archivo jar al iniciar el servidor:" msgid "For example, the full command you use to start the server might be:" -msgstr "Por ejemplo, el comando completo que usas para iniciar el servidor podría ser:" +msgstr "" +"Por ejemplo, el comando completo que usas para iniciar el servidor podría " +"ser:" msgid "Minecraft 1.7.2 through 1.15.2" msgstr "Minecraft 1.7.2 a 1.15.2" -msgid "Refer to the authlib-injector documentation on setting up a server." -msgstr "Consulta la documentación de authlib-injector sobre cómo configurar un servidor." +msgid "" +"Refer to the authlib-injector documentation on " +"setting up a server." +msgstr "" +"Consulta la documentación de authlib-injector " +"sobre cómo configurar un servidor." -msgid "Alternatively, you can patch your server to use a newer version of Mojang's authlib that supports the arguments for custom API servers. Replace the files under com/mojang/authlib in your server.jar with the files in authlib-1.6.25.jar." -msgstr "Alternativamente, puedes parchear tu servidor para usar una versión más reciente de authlib de Mojang que soporte los argumentos para servidores API personalizados. Reemplaza los archivos bajo com/mojang/authlib en tu server.jar con los archivos en authlib-1.6.25.jar." +msgid "" +"Alternatively, you can patch your server to use a newer version of Mojang's " +"authlib that supports the arguments for custom API servers. Replace the " +"files under com/mojang/authlib in your server.jar " +"with the files in authlib-1.6.25.jar." +msgstr "" +"Alternativamente, puedes parchear tu servidor para usar una versión más " +"reciente de authlib de Mojang que soporte los argumentos para servidores API " +"personalizados. Reemplaza los archivos bajo com/mojang/authlib " +"en tu server.jar con los archivos en authlib-1.6.25.jar." -msgid "Late Classic, Alpha, Beta, etc. through Minecraft 1.6.4" -msgstr "Clásico Tardío, Alpha, Beta, etc. hasta Minecraft 1.6.4" +msgid "" +"Late Classic, Alpha, Beta, etc. through " +"Minecraft 1.6.4" +msgstr "" +"Clásico Tardío, Alpha, Beta, etc. hasta " +"Minecraft 1.6.4" -msgid "Use {{ index . 0 }} and start the server with the -Dminecraft.api.session.host argument described above. For example, the full command you use to start the server might be:" -msgstr "Usa {{ index . 0 }} y arranca el servidor con el argumento -Dminecraft.api.session.host descrito arriba. Por ejemplo, el comando completo que usas para iniciar el servidor podría ser:" +msgid "" +"Use {{ index . 0 }} and start the server with the -Dminecraft.api." +"session.host argument described above. For example, the full command " +"you use to start the server might be:" +msgstr "" +"Usa {{ index . 0 }} y arranca el servidor con el argumento -Dminecraft." +"api.session.host descrito arriba. Por ejemplo, el comando completo " +"que usas para iniciar el servidor podría ser:" msgid "Drasl version %s." msgstr "Versión de Drasl %s." @@ -130,9 +192,6 @@ msgstr "Registrar una cuenta nueva:" msgid "Register a new account with a random UUID:" msgstr "Registrar una cuenta nueva con un UUID aleatorio:" -msgid "Player UUID (leave blank for random)" -msgstr "UUID del jugador (dejar en blanco para uno aleatorio)" - msgid "Using invite code %s" msgstr "Usando el código de invitación %s" @@ -145,29 +204,33 @@ msgstr "El registro como nuevo jugador es solo por invitación." msgid "Registration as an existing player is invite-only." msgstr "El registro como jugador existente es solo por invitación." -msgid "Register a new account with the UUID of an existing %s account. Requires verification that you own the account." -msgstr "Registra una nueva cuenta con el UUID de una cuenta existente de %s. Se requiere verificación de que eres el propietario de la cuenta." +msgid "" +"Register a new account with the UUID of an existing %s account. Requires " +"verification that you own the account." +msgstr "" +"Registra una nueva cuenta con el UUID de una cuenta existente de %s. Se " +"requiere verificación de que eres el propietario de la cuenta." msgid "Register a new account with the UUID of an existing %s account" msgstr "Registrar una nueva cuenta con el UUID de una cuenta existente de %s" -msgid "%s player name" -msgstr "Nombre de jugador de %s" - msgid "Continue" msgstr "Continuar" -msgid "Register" -msgstr "Registrarse" - msgid "Migrate an existing user" msgstr "Migrar un usuario existente" msgid "You can link this identity provider to an existing %s account." -msgstr "Puedes vincular este proveedor de identidad a una cuenta existente de %s." +msgstr "" +"Puedes vincular este proveedor de identidad a una cuenta existente de %s." -msgid "If you do so, you will no longer be able to log in using your %s password. You'll need to use your Minecraft Token to log in to Minecraft launchers." -msgstr "Si lo haces, ya no podrás iniciar sesión usando tu contraseña de %s. Necesitarás usar tu Token de Minecraft para iniciar sesión en los lanzadores de Minecraft." +msgid "" +"If you do so, you will no longer be able to log in using your %s password. " +"You'll need to use your Minecraft Token to log in to Minecraft launchers." +msgstr "" +"Si lo haces, ya no podrás iniciar sesión usando tu contraseña de %s. " +"Necesitarás usar tu Token de Minecraft para iniciar sesión en los lanzadores " +"de Minecraft." msgid "Link account" msgstr "Vincular cuenta" @@ -187,11 +250,19 @@ msgstr "No está permitido elegir un nombre de jugador." msgid "Player name" msgstr "Nombre de jugador" -msgid "We need to verify that you own the %s account “%s” before you register its UUID." -msgstr "Necesitamos verificar que eres el propietario de la cuenta %s “%s” antes de registrar su UUID." +msgid "" +"We need to verify that you own the %s account “%s” before you register its " +"UUID." +msgstr "" +"Necesitamos verificar que eres el propietario de la cuenta %s “%s” antes de " +"registrar su UUID." -msgid "Download this image and set it as your skin on your %s account, on this page." -msgstr "Descarga esta imagen y configúrala como tu skin en tu cuenta de %s, en esta página." +msgid "" +"Download this image and set it as your skin on your %s account, on this page." +msgstr "" +"Descarga esta imagen y configúrala como tu skin en tu cuenta de %s, en esta página." msgid "Download this image and set it as your skin on your %s account." msgstr "Descarga esta imagen y configúrala como tu skin en tu cuenta de %s." @@ -208,8 +279,11 @@ msgstr "Descargar skin" msgid "When you are done, hit “Register”." msgstr "Cuando termines, haz clic en “Registrarse”." -msgid "When you are done, enter a password for your %s account and hit “Register”." -msgstr "Cuando termines, ingresa una contraseña para tu cuenta de %s y haz clic en “Registrarse”." +msgid "" +"When you are done, enter a password for your %s account and hit “Register”." +msgstr "" +"Cuando termines, ingresa una contraseña para tu cuenta de %s y haz clic en " +"“Registrarse”." msgid "When you are done, hit “Create player”." msgstr "Cuando termines, haz clic en “Crear jugador”." @@ -241,8 +315,12 @@ msgstr "No hay invitaciones para mostrar." msgid "All Users" msgstr "Todos los usuarios" -msgid "Are you sure you want to delete the account “%s”? This action is irreversible." -msgstr "¿Está seguro de que desea eliminar la cuenta “%s”? Esta acción es irreversible." +msgid "" +"Are you sure you want to delete the account “%s”? This action is " +"irreversible." +msgstr "" +"¿Está seguro de que desea eliminar la cuenta “%s”? Esta acción es " +"irreversible." msgid "User" msgstr "Usuario" @@ -263,7 +341,9 @@ msgid "Admins can always create unlimited players" msgstr "Los administradores siempre pueden crear jugadores ilimitados" msgid "To demote a default admin, edit the %s configuration." -msgstr "Para degradar a un administrador predeterminado, edite la configuración de %s." +msgstr "" +"Para degradar a un administrador predeterminado, edite la configuración de " +"%s." msgid "Admin?" msgstr "¿Administrador?" @@ -274,17 +354,28 @@ msgstr "¿Bloqueado?" msgid "Save changes" msgstr "Guardar cambios" -msgid "*Specify -1 to allow an unlimited number of players. Leave blank to use the default max number, which is %d." -msgstr "*Especifique -1 para permitir un número ilimitado de jugadores. Déjelo en blanco para usar el máximo predeterminado, que es %d." +msgid "" +"*Specify -1 to allow an unlimited number of players. Leave blank to use the " +"default max number, which is %d." +msgstr "" +"*Especifique -1 para permitir un número ilimitado de jugadores. Déjelo en " +"blanco para usar el máximo predeterminado, que es %d." msgid "New Invite" msgstr "Nueva Invitacion" -msgid "Are you sure you want to delete the player “%s”? This action is irreversible." -msgstr "¿Está seguro de que desea eliminar al jugador “%s”? Esta acción es irreversible." +msgid "" +"Are you sure you want to delete the player “%s”? This action is irreversible." +msgstr "" +"¿Está seguro de que desea eliminar al jugador “%s”? Esta acción es " +"irreversible." -msgid "Are you sure you want to unlink your %s account? You will no longer be able to log in to your %s account using %s." -msgstr "¿Está seguro de que desea desvincular su cuenta de %s? Ya no podrá iniciar sesión en su cuenta de %s usando %s." +msgid "" +"Are you sure you want to unlink your %s account? You will no longer be able " +"to log in to your %s account using %s." +msgstr "" +"¿Está seguro de que desea desvincular su cuenta de %s? Ya no podrá iniciar " +"sesión en su cuenta de %s usando %s." msgid "%s's players" msgstr "Jugadores de %s" @@ -298,16 +389,28 @@ msgstr "Eliminar jugador" msgid "No players yet." msgstr "Todavía no hay jugadores." -msgid "%s is not allowed to add new players. You can override this limit since you're an admin." -msgstr "%s no tiene permiso para agregar nuevos jugadores. Puede omitir este límite porque es administrador." +msgid "" +"%s is not allowed to add new players. You can override this limit since " +"you're an admin." +msgstr "" +"%s no tiene permiso para agregar nuevos jugadores. Puede omitir este límite " +"porque es administrador." msgid "You are not allowed to add new players." msgstr "No tienes permiso para agregar nuevos jugadores." -msgid "%s is only allowed to have %d player. You can override this limit since you're an admin." -msgid_plural "%s is allowed to have up to %d players. You can override this limit since you're an admin." -msgstr[0] "A %s solo se le permite tener %d jugador. Puede omitir este límite porque es administrador." -msgstr[1] "A %s se le permite tener hasta %d jugadores. Puede omitir este límite porque es administrador." +msgid "" +"%s is only allowed to have %d player. You can override this limit since " +"you're an admin." +msgid_plural "" +"%s is allowed to have up to %d players. You can override this limit since " +"you're an admin." +msgstr[0] "" +"A %s solo se le permite tener %d jugador. Puede omitir este límite porque es " +"administrador." +msgstr[1] "" +"A %s se le permite tener hasta %d jugadores. Puede omitir este límite porque " +"es administrador." msgid "You are only allowed to have 1 player." msgid_plural "You are allowed to have up to %d players." @@ -329,14 +432,15 @@ msgstr "Crear un nuevo jugador con un UUID aleatorio:" msgid "Player UUID (leave blank for random)" msgstr "UUID del jugador (déjelo en blanco para uno aleatorio)" -msgid "Create player" -msgstr "Crear jugador" - msgid "Import a player from %s" msgstr "Importar un jugador desde %s" -msgid "Create a new player with the UUID of an existing %s player. Requires verification that you own the account." -msgstr "Crear un nuevo jugador con el UUID de un jugador existente de %s. Se requiere verificación de que usted es el propietario de la cuenta." +msgid "" +"Create a new player with the UUID of an existing %s player. Requires " +"verification that you own the account." +msgstr "" +"Crear un nuevo jugador con el UUID de un jugador existente de %s. Se " +"requiere verificación de que usted es el propietario de la cuenta." msgid "%s player name" msgstr "Nombre del jugador de %s" @@ -362,8 +466,14 @@ msgstr "No hay cuentas externas vinculadas a la cuenta de %s." msgid "No external accounts are linked to your account." msgstr "No hay cuentas externas vinculadas a tu cuenta." -msgid "If you link an external account, you will no longer be able to log in using your %s password. You'll need to use your Minecraft Token to log into Minecraft Launchers" -msgstr "Si vincula una cuenta externa, ya no podrá iniciar sesión usando su contraseña de %s. Deberá usar su token de Minecraft para iniciar sesión en los lanzadores de Minecraft." +msgid "" +"If you link an external account, you will no longer be able to log in using " +"your %s password. You'll need to use your Minecraft Token to log into " +"Minecraft Launchers" +msgstr "" +"Si vincula una cuenta externa, ya no podrá iniciar sesión usando su " +"contraseña de %s. Deberá usar su token de Minecraft para iniciar sesión en " +"los lanzadores de Minecraft." msgid "Link with %s" msgstr "Vincular con %s" @@ -374,20 +484,27 @@ msgstr "Configuración de la cuenta" msgid "Max number of players" msgstr "Número máximo de jugadores" -msgid "Specify -1 to allow unlimited players or leave blank to reset to the configured default value." -msgstr "Especifique -1 para permitir jugadores ilimitados o déjelo en blanco para restablecer al valor predeterminado configurado." +msgid "" +"Specify -1 to allow unlimited players or leave blank to reset to the " +"configured default value." +msgstr "" +"Especifique -1 para permitir jugadores ilimitados o déjelo en blanco para " +"restablecer al valor predeterminado configurado." msgid "Leave blank to keep" msgstr "Déjelo en blanco para mantener" msgid "Can be used instead of a password to sign in to Minecraft launchers." -msgstr "Se puede usar en lugar de una contraseña para iniciar sesión en los lanzadores de Minecraft." +msgstr "" +"Se puede usar en lugar de una contraseña para iniciar sesión en los " +"lanzadores de Minecraft." msgid "check the box to reset your Minecraft token" msgstr "marque la casilla para restablecer su token de Minecraft" msgid "See the %s API documentation" -msgstr "Consulte la documentación de la API de %s" +msgstr "" +"Consulte la documentación de la API de %s" msgid "check the box to reset your API token" msgstr "marque la casilla para restablecer su token de API" @@ -395,9 +512,6 @@ msgstr "marque la casilla para restablecer su token de API" msgid "Preferred Language (used by Minecraft)" msgstr "Idioma preferido (utilizado por Minecraft)" -msgid "Delete Account" -msgstr "Eliminar cuenta" - msgid "Are you sure? This action is irreversible." msgstr "¿Está seguro? Esta acción es irreversible." @@ -440,9 +554,6 @@ msgstr "Subir una skin" msgid "or instead, provide a URL to a skin" msgstr "o en su lugar, proporciona una URL de una skin" -msgid "Leave blank to keep" -msgstr "Déjalo en blanco para conservarla" - msgid "or instead, check the box to delete the current skin" msgstr "o en su lugar, marca la casilla para eliminar la skin actual" @@ -471,19 +582,14 @@ msgid "or instead, check the box to delete the current cape" msgstr "o en su lugar, marca la casilla para eliminar la capa actual" msgid "Fallback Player" -msgstr "Jugador alternativo" +msgstr "Jugador de respaldo" -msgid "UUID or player name. If you don't set a skin or cape, this player's skin on one of the fallback API servers will be used instead." -msgstr "UUID o nombre del jugador. Si no configuras una skin o capa, se usará la skin de este jugador en uno de los servidores API alternativos." - -msgid "Save changes" -msgstr "Guardar cambios" - -msgid "Delete Player" -msgstr "Eliminar jugador" - -msgid "Are you sure you want to delete the player “%s”? This action is irreversible." -msgstr "¿Estás seguro de que deseas eliminar al jugador “%s”? Esta acción no se puede deshacer." +msgid "" +"UUID or player name. If you don't set a skin or cape, this player's skin on " +"one of the fallback API servers will be used instead." +msgstr "" +"UUID o nombre del jugador. Si no configuras una skin o capa, se usará la " +"skin de este jugador en uno de los servidores API alternativos." msgid "You are not logged in." msgstr "No has iniciado sesión." @@ -508,17 +614,16 @@ msgstr[1] "no puede tener más de %d caracteres" msgid "That account is already migrated. Log in via OpenID Connect." msgstr "Esa cuenta ya fue migrada. Inicia sesión con OpenID Connect." -msgid "That account is already migrated. Log in via OpenID Connect." -msgstr "Esa cuenta ya fue migrada. Inicia sesión mediante OpenID Connect." - msgid "Password login is not allowed. Log in via OpenID Connect instead." -msgstr "El inicio de sesión con contraseña no está permitido. Inicia sesión mediante OpenID Connect." +msgstr "" +"El inicio de sesión con contraseña no está permitido. Inicia sesión mediante " +"OpenID Connect." msgid "Invalid player name: %s" msgstr "Nombre de jugador no válido: %s" msgid "Invalid fallback player: %s" -msgstr "Jugador alternativo no válido: %s" +msgstr "Jugador de respaldo no válido: %s" msgid "That %s account does not have a preferred username." msgstr "Esa cuenta de %s no tiene un nombre de usuario preferido." @@ -539,7 +644,8 @@ msgid "Account created." msgstr "Cuenta creada." msgid "Successfully migrated account. From now on, log in with %s." -msgstr "Cuenta migrada correctamente. De ahora en adelante, inicia sesión con %s." +msgstr "" +"Cuenta migrada correctamente. De ahora en adelante, inicia sesión con %s." msgid "Account deleted" msgstr "Cuenta eliminada" @@ -577,9 +683,6 @@ msgstr "Proveedor OIDC desconocido: %s" msgid "OIDC subject for provider %s can't be blank." msgstr "El sujeto OIDC para el proveedor %s no puede estar en blanco." -msgid "Invalid player name: %s" -msgstr "Nombre de jugador no válido: %s" - msgid "Invalid preferred language." msgstr "Idioma preferido no válido." @@ -599,20 +702,21 @@ msgid "Invalid UUID: %s" msgstr "UUID no válido: %s" msgid "Cannot make a new admin user without having admin privileges yourself." -msgstr "No puedes crear un nuevo usuario administrador sin tener privilegios de administrador." +msgstr "" +"No puedes crear un nuevo usuario administrador sin tener privilegios de " +"administrador." msgid "Cannot make a new locked user without admin privileges." msgstr "No puedes crear un usuario bloqueado sin privilegios de administrador." msgid "Cannot set a max player count without admin privileges." -msgstr "No puedes establecer un número máximo de jugadores sin privilegios de administrador." +msgstr "" +"No puedes establecer un número máximo de jugadores sin privilegios de " +"administrador." msgid "Invalid max player count: %s" msgstr "Número máximo de jugadores no válido: %s" -msgid "Invalid fallback player: %s" -msgstr "Jugador de respaldo no válido: %s" - msgid "Invalid skin model." msgstr "Modelo de skin no válido." @@ -620,7 +724,8 @@ msgid "That username is taken." msgstr "Ese nombre de usuario ya está en uso." msgid "That username is in use as the name of another user's player." -msgstr "Ese nombre de usuario ya se usa como el nombre del jugador de otro usuario." +msgstr "" +"Ese nombre de usuario ya se usa como el nombre del jugador de otro usuario." msgid "That player name is taken." msgstr "Ese nombre de jugador ya está en uso." @@ -629,7 +734,8 @@ msgid "That UUID is taken." msgstr "Ese UUID ya está en uso." msgid "That player name is in use as another user's username." -msgstr "Ese nombre de jugador se está usando como nombre de usuario de otro usuario." +msgstr "" +"Ese nombre de jugador se está usando como nombre de usuario de otro usuario." msgid "Error saving the skin." msgstr "Error al guardar el skin." @@ -640,35 +746,36 @@ msgstr "Error al guardar la capa." msgid "Password login is not allowed." msgstr "El inicio de sesión con contraseña no está permitido." -msgid "User not found." -msgstr "Usuario no encontrado." - msgid "Incorrect password." msgstr "Contraseña incorrecta." msgid "User is locked." msgstr "El usuario está bloqueado." -msgid "Caller cannot be null." -msgstr "El llamador no puede ser nulo." - msgid "You are not authorized to update that user." msgstr "No estás autorizado para actualizar ese usuario." -msgid "Cannot change admin status of user without having admin privileges yourself." -msgstr "No puedes cambiar el estado de administrador de un usuario sin tener privilegios de administrador." +msgid "" +"Cannot change admin status of user without having admin privileges yourself." +msgstr "" +"No puedes cambiar el estado de administrador de un usuario sin tener " +"privilegios de administrador." msgid "Cannot revoke admin status of a default admin." -msgstr "No puedes revocar el estado de administrador de un administrador predeterminado." +msgstr "" +"No puedes revocar el estado de administrador de un administrador " +"predeterminado." -msgid "Cannot change locked status of user without having admin privileges yourself." -msgstr "No puedes cambiar el estado de bloqueo de un usuario sin tener privilegios de administrador." - -msgid "You are not an admin." -msgstr "No eres un administrador." +msgid "" +"Cannot change locked status of user without having admin privileges yourself." +msgstr "" +"No puedes cambiar el estado de bloqueo de un usuario sin tener privilegios " +"de administrador." msgid "Can't link an OIDC account for another user unless you're an admin." -msgstr "No puedes vincular una cuenta OIDC de otro usuario a menos que seas administrador." +msgstr "" +"No puedes vincular una cuenta OIDC de otro usuario a menos que seas " +"administrador." msgid "That %s account is already linked to another user." msgstr "Esa cuenta de %s ya está vinculada a otro usuario." @@ -677,10 +784,111 @@ msgid "That user is already linked to a %s account." msgstr "Ese usuario ya está vinculado a una cuenta de %s." msgid "Can't unlink an OIDC account for another user unless you're an admin." -msgstr "No puedes desvincular una cuenta OIDC de otro usuario a menos que seas administrador." +msgstr "" +"No puedes desvincular una cuenta OIDC de otro usuario a menos que seas " +"administrador." msgid "No linked %s account found." msgstr "No se encontró ninguna cuenta vinculada de %s." -msgid "Can't remove the last linked OIDC account." -msgstr "No puedes eliminar la última cuenta OIDC vinculada." +msgid "invalid UUID" +msgstr "UUID inválido" + +msgid "invalid ID" +msgstr "ID inválido" + +msgid "invalid ID or UUID" +msgstr "ID o UUID inválido" + +msgid "must match the following regular expression: %s" +msgstr "debe coincidir con la siguiente expresión regular: %s" + +msgid "neither a valid player name (%s) nor an email address" +msgstr "" +"no es un nombre de jugador válido (%s) ni una dirección de correo electrónico" + +msgid "not a valid player name or UUID" +msgstr "no es un nombre de jugador ni UUID válido" + +msgid "" +"must be greater than 0, or use -1 to indicate unlimited players, or use -2 " +"to use the system default" +msgstr "" +"debe ser mayor que 0, o usa -1 para indicar jugadores ilimitados, o -2 para " +"usar el valor predeterminado del sistema" + +msgid "must be longer than %d character" +msgid_plural "must be longer than %d characters" +msgstr[0] "debe tener más de %d carácter" +msgstr[1] "debe tener más de %d caracteres" + +msgid "You are only allowed to own %d player." +msgid_plural "You are only allowed to own %d players." +msgstr[0] "Solo se te permite tener %d jugador." +msgstr[1] "Solo se te permite tener %d jugadores." + +msgid "Setting a %s texture is not allowed." +msgstr "No está permitido establecer una textura de %s." + +msgid "Can't specify both a file and a URL for %s texture." +msgstr "" +"No puedes especificar tanto un archivo como una URL para la textura de %s." + +msgid "Setting a %s from a URL is not allowed." +msgstr "No está permitido establecer una %s desde una URL." + +msgid "Couldn't download a %s from that URL: %s" +msgstr "No se pudo descargar una %s desde esa URL: %s" + +msgid "Error using that %s: %s" +msgstr "Error al usar ese %s: %s" + +msgid "Caller cannot be null." +msgstr "El solicitante no puede estar vacío." + +msgid "Can't create a player belonging to another user unless you're an admin." +msgstr "" +"No puedes crear un jugador que pertenezca a otro usuario a menos que seas " +"administrador." + +msgid "You are not allowed to create new players." +msgstr "No tienes permiso para crear nuevos jugadores." + +msgid "Importing an existing player is not allowed." +msgstr "No está permitido importar un jugador existente." + +msgid "Can't simultaneously import an existing player and choose a UUID." +msgstr "" +"No puedes importar un jugador existente y elegir un UUID al mismo tiempo." + +msgid "Creating a new player is not allowed." +msgstr "No está permitido crear un nuevo jugador." + +msgid "Can't update a player belonging to another user unless you're an admin." +msgstr "" +"No puedes actualizar un jugador que pertenezca a otro usuario a menos que " +"seas administrador." + +msgid "Changing your player name is not allowed." +msgstr "No está permitido cambiar el nombre de tu jugador." + +msgid "registration server returned an error" +msgstr "el servidor de registro devolvió un error" + +msgid "player does not have a skin" +msgstr "el jugador no tiene un skin" + +msgid "invalid image" +msgstr "imagen inválida" + +msgid "missing challenge token" +msgstr "falta el token de desafío" + +msgid "registration server didn't return textures" +msgstr "el servidor de registro no devolvió texturas" + +msgid "You are not allowed to delete players." +msgstr "No tienes permiso para eliminar jugadores." + +msgid "You don't own that player." +msgstr "No eres el propietario de ese jugador." diff --git a/model.go b/model.go index a05f313..f49f7e1 100644 --- a/model.go +++ b/model.go @@ -3,8 +3,6 @@ package main import ( "crypto/md5" "database/sql" - "errors" - "fmt" "github.com/golang-jwt/jwt/v5" "github.com/google/uuid" "github.com/samber/mo" @@ -74,14 +72,14 @@ func IsValidSkinModel(model string) bool { func UUIDToID(uuid string) (string, error) { if len(uuid) != 36 { - return "", errors.New("invalid UUID") + return "", &UserError{Message: "invalid UUID"} } return strings.ReplaceAll(uuid, "-", ""), nil } func IDToUUID(id string) (string, error) { if len(id) != 32 { - return "", errors.New("invalid ID") + return "", &UserError{Message: "invalid ID"} } return id[0:8] + "-" + id[8:12] + "-" + id[12:16] + "-" + id[16:20] + "-" + id[20:], nil } @@ -103,7 +101,7 @@ func ParseUUID(idOrUUID string) (string, error) { } return idOrUUID, nil } - return "", errors.New("invalid ID or UUID") + return "", &UserError{Message: "invalid ID or UUID"} } type Plural struct { @@ -146,7 +144,7 @@ func (app *App) ValidateUsername(username string) error { if emailErr == nil { return nil } - return fmt.Errorf("neither a valid player name (%s) nor an email address", playerNameErr) + return &UserError{Message: "neither a valid player name (%s) nor an email address", Params: []interface{}{playerNameErr}} } func (app *App) ValidatePlayerNameOrUUID(player string) error { @@ -154,7 +152,7 @@ func (app *App) ValidatePlayerNameOrUUID(player string) error { if err != nil { _, uuidErr := uuid.Parse(player) if uuidErr != nil { - return errors.New("not a valid player name or UUID") + return &UserError{Message: "not a valid player name or UUID"} } return nil } @@ -163,7 +161,7 @@ func (app *App) ValidatePlayerNameOrUUID(player string) error { func (app *App) ValidateMaxPlayerCount(maxPlayerCount int) error { if maxPlayerCount < 0 && maxPlayerCount != app.Constants.MaxPlayerCountUnlimited && maxPlayerCount != app.Constants.MaxPlayerCountUseDefault { - return errors.New("must be greater than 0, OR use -1 to indicate unlimited players, OR use -2 to use the system default") + return &UserError{Message: "must be greater than 0, or use -1 to indicate unlimited players, or use -2 to use the system default"} } return nil } @@ -211,11 +209,17 @@ func (app *App) TransientLoginEligible(playerName string) bool { func (app *App) ValidatePassword(password string) error { if password == "" { - return errors.New("can't be blank") + return &UserError{Message: "can't be blank"} } if len(password) < app.Config.MinPasswordLength { - message := fmt.Sprintf("password must be longer than %d characters", app.Config.MinPasswordLength) - return errors.New(message) + return &UserError{ + Message: "must be longer than %d character", + Plural: mo.Some(Plural{ + Message: "must be longer than %d characters", + N: app.Config.MinPasswordLength, + }), + Params: []interface{}{app.Config.MinPasswordLength}, + } } return nil } diff --git a/player.go b/player.go index 7a063df..e4d5c85 100644 --- a/player.go +++ b/player.go @@ -7,6 +7,7 @@ import ( "errors" "fmt" "github.com/google/uuid" + "github.com/samber/mo" "gorm.io/gorm" "image" "image/color" @@ -108,7 +109,14 @@ func (app *App) CreatePlayer( maxPlayerCount := app.GetMaxPlayerCount(&user) if maxPlayerCount != Constants.MaxPlayerCountUnlimited && len(user.Players) >= maxPlayerCount && !callerIsAdmin { - return Player{}, NewBadRequestUserError("You are only allowed to own %d player(s).", maxPlayerCount) + return Player{}, &UserError{ + Code: mo.Some(http.StatusBadRequest), + Message: "You are only allowed to own %d player.", + Plural: mo.Some(Plural{ + Message: "You are only allowed to own %d players", N: maxPlayerCount, + }), + Params: []interface{}{maxPlayerCount}, + } } if err := app.ValidatePlayerName(playerName); err != nil { @@ -123,7 +131,7 @@ func (app *App) CreatePlayer( } if chosenUUID != nil { - return Player{}, NewBadRequestUserError("Can't import an existing player AND choose a UUID.") + return Player{}, NewBadRequestUserError("Can't simultaneously import an existing player and choose a UUID.") } var err error @@ -388,14 +396,14 @@ func (app *App) ValidateChallenge(playerName string, challengeToken *string) (*P res, err := MakeHTTPClient().Get(base.String()) if err != nil { - log.Printf("Couldn't access registration server at %s: %s\n", base.String(), err) + log.Printf("Couldn't access the registration server at %s: %s\n", base.String(), err) return nil, err } defer res.Body.Close() if res.StatusCode != http.StatusOK { log.Printf("Request to registration server at %s resulted in status code %d\n", base.String(), res.StatusCode) - return nil, errors.New("registration server returned error") + return nil, &UserError{Message: "registration server returned an error"} } var idRes PlayerNameToIDResponse @@ -406,7 +414,7 @@ func (app *App) ValidateChallenge(playerName string, challengeToken *string) (*P base, err = url.Parse(app.Config.ImportExistingPlayer.SessionURL) if err != nil { - return nil, fmt.Errorf("Invalid SessionURL %s: %s", app.Config.ImportExistingPlayer.SessionURL, err) + return nil, fmt.Errorf("invalid SessionURL %s: %s", app.Config.ImportExistingPlayer.SessionURL, err) } base.Path, err = url.JoinPath(base.Path, "session/minecraft/profile/"+idRes.ID) if err != nil { @@ -421,7 +429,7 @@ func (app *App) ValidateChallenge(playerName string, challengeToken *string) (*P if res.StatusCode != http.StatusOK { log.Printf("Request to registration server at %s resulted in status code %d\n", base.String(), res.StatusCode) - return nil, errors.New("registration server returned error") + return nil, &UserError{Message: "registration server returned an error"} } var profileRes SessionProfileResponse @@ -457,7 +465,7 @@ func (app *App) ValidateChallenge(playerName string, challengeToken *string) (*P } if texture.Textures.Skin == nil { - return nil, errors.New("player does not have a skin") + return nil, &UserError{Message: "player does not have a skin"} } res, err = MakeHTTPClient().Get(texture.Textures.Skin.URL) if err != nil { @@ -471,7 +479,7 @@ func (app *App) ValidateChallenge(playerName string, challengeToken *string) (*P } img, ok := rgba_img.(*image.NRGBA) if !ok { - return nil, errors.New("invalid image") + return nil, &UserError{Message: "invalid image"} } challenge := make([]byte, 64) @@ -489,19 +497,19 @@ func (app *App) ValidateChallenge(playerName string, challengeToken *string) (*P } if challengeToken == nil { - return nil, errors.New("missing challenge token") + return nil, &UserError{Message: "missing challenge token"} } correctChallenge := app.GetChallenge(playerName, *challengeToken) if !bytes.Equal(challenge, correctChallenge) { - return nil, errors.New("skin does not match") + return nil, &UserError{Message: "skin does not match"} } return &details, nil } } - return nil, errors.New("registration server didn't return textures") + return nil, &UserError{Message: "registration server didn't return textures"} } func MakeChallengeToken() (string, error) {