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) {