i18n player.go

This commit is contained in:
Evan Goode 2025-07-13 23:07:36 -04:00
parent 539ce4f92d
commit 57d98fb41c
6 changed files with 369 additions and 148 deletions

View File

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

View File

@ -144,6 +144,7 @@
pre-commit
sqlite-interactive
swagger-codegen
gettext
];
};
});

View File

@ -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")
}
}

View File

@ -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 <a href=\"{{ index . 0 }}\">the authlib-injector documentation on setting up a server</a>."
msgstr "Consulta <a href=\"{{ index . 0 }}\">la documentación de authlib-injector sobre cómo configurar un servidor</a>."
msgid ""
"Refer to <a href=\"{{ index . 0 }}\">the authlib-injector documentation on "
"setting up a server</a>."
msgstr ""
"Consulta <a href=\"{{ index . 0 }}\">la documentación de authlib-injector "
"sobre cómo configurar un servidor</a>."
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 <code>com/mojang/authlib</code> in your <code>server.jar</code> with the files in <a href=\"{{ index . 0 }}\">authlib-1.6.25.jar</a>."
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 <code>com/mojang/authlib</code> en tu <code>server.jar</code> con los archivos en <a href=\"{{ index . 0 }}\">authlib-1.6.25.jar</a>."
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 <code>com/mojang/authlib</code> in your <code>server.jar</code> "
"with the files in <a href=\"{{ index . 0 }}\">authlib-1.6.25.jar</a>."
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 <code>com/mojang/authlib</code> "
"en tu <code>server.jar</code> con los archivos en <a href=\"{{ index . "
"0 }}\">authlib-1.6.25.jar</a>."
msgid "<a href=\"{{ index . 0 }}\">Late Classic</a>, Alpha, Beta, etc. through Minecraft 1.6.4"
msgstr "<a href=\"{{ index . 0 }}\">Clásico Tardío</a>, Alpha, Beta, etc. hasta Minecraft 1.6.4"
msgid ""
"<a href=\"{{ index . 0 }}\">Late Classic</a>, Alpha, Beta, etc. through "
"Minecraft 1.6.4"
msgstr ""
"<a href=\"{{ index . 0 }}\">Clásico Tardío</a>, Alpha, Beta, etc. hasta "
"Minecraft 1.6.4"
msgid "Use {{ index . 0 }} and start the server with the <code>-Dminecraft.api.session.host</code> 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 <code>-Dminecraft.api.session.host</code> 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 <code>-Dminecraft.api."
"session.host</code> 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 <code>-Dminecraft."
"api.session.host</code> 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 <a target=\"_blank\" href=\"%s\">this page</a>."
msgstr "Descarga esta imagen y configúrala como tu skin en tu cuenta de %s, en <a target=\"_blank\" href=\"%s\">esta página</a>."
msgid ""
"Download this image and set it as your skin on your %s account, on <a "
"target=\"_blank\" href=\"%s\">this page</a>."
msgstr ""
"Descarga esta imagen y configúrala como tu skin en tu cuenta de %s, en <a "
"target=\"_blank\" href=\"%s\">esta página</a>."
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 <a href=\"{{ index . 0 }}\">the %s API documentation</a>"
msgstr "Consulte <a href=\"{{ index . 0 }}\">la documentación de la API de %s</a>"
msgstr ""
"Consulte <a href=\"{{ index . 0 }}\">la documentación de la API de %s</a>"
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."

View File

@ -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
}

View File

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