mirror of
https://github.com/unmojang/drasl.git
synced 2025-08-05 11:56:10 -04:00
Rename AllowCreatingDeletingPlayers to AllowAddingDeletingPlayers
This commit is contained in:
parent
7ebbafd2be
commit
abbb9bf1da
@ -17,7 +17,7 @@ func TestAPI(t *testing.T) {
|
|||||||
ts := &TestSuite{}
|
ts := &TestSuite{}
|
||||||
|
|
||||||
config := testConfig()
|
config := testConfig()
|
||||||
config.AllowCreatingDeletingPlayers = true
|
config.AllowAddingDeletingPlayers = true
|
||||||
config.RegistrationExistingPlayer.Allow = false
|
config.RegistrationExistingPlayer.Allow = false
|
||||||
config.DefaultAdmins = []string{"admin"}
|
config.DefaultAdmins = []string{"admin"}
|
||||||
ts.Setup(config)
|
ts.Setup(config)
|
||||||
|
106
config.go
106
config.go
@ -93,48 +93,48 @@ type importExistingPlayerConfig struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
AllowCapes bool
|
AllowCapes bool
|
||||||
AllowChangingPlayerName bool
|
AllowChangingPlayerName bool
|
||||||
AllowMultipleAccessTokens bool
|
AllowMultipleAccessTokens bool
|
||||||
AllowPasswordLogin bool
|
AllowPasswordLogin bool
|
||||||
AllowSkins bool
|
AllowSkins bool
|
||||||
AllowTextureFromURL bool
|
AllowTextureFromURL bool
|
||||||
AllowCreatingDeletingPlayers bool
|
AllowAddingDeletingPlayers bool
|
||||||
ApplicationOwner string
|
ApplicationOwner string
|
||||||
ApplicationName string
|
ApplicationName string
|
||||||
BaseURL string
|
BaseURL string
|
||||||
BodyLimit bodyLimitConfig
|
BodyLimit bodyLimitConfig
|
||||||
CORSAllowOrigins []string
|
CORSAllowOrigins []string
|
||||||
CreateNewPlayer createNewPlayerConfig
|
CreateNewPlayer createNewPlayerConfig
|
||||||
DataDirectory string
|
DataDirectory string
|
||||||
DefaultAdmins []string
|
DefaultAdmins []string
|
||||||
DefaultPreferredLanguage string
|
DefaultPreferredLanguage string
|
||||||
DefaultMaxPlayerCount int
|
DefaultMaxPlayerCount int
|
||||||
Domain string
|
Domain string
|
||||||
EnableBackgroundEffect bool
|
EnableBackgroundEffect bool
|
||||||
EnableFooter bool
|
EnableFooter bool
|
||||||
EnableWebFrontEnd bool
|
EnableWebFrontEnd bool
|
||||||
FallbackAPIServers []FallbackAPIServer
|
FallbackAPIServers []FallbackAPIServer
|
||||||
ForwardSkins bool
|
ForwardSkins bool
|
||||||
InstanceName string
|
InstanceName string
|
||||||
ImportExistingPlayer importExistingPlayerConfig
|
ImportExistingPlayer importExistingPlayerConfig
|
||||||
ListenAddress string
|
ListenAddress string
|
||||||
LogRequests bool
|
LogRequests bool
|
||||||
MinPasswordLength int
|
MinPasswordLength int
|
||||||
RegistrationOIDC []RegistrationOIDCConfig
|
RegistrationOIDC []RegistrationOIDCConfig
|
||||||
PreMigrationBackups bool
|
PreMigrationBackups bool
|
||||||
RateLimit rateLimitConfig
|
RateLimit rateLimitConfig
|
||||||
RegistrationExistingPlayer registrationExistingPlayerConfig
|
RegistrationExistingPlayer registrationExistingPlayerConfig
|
||||||
RegistrationNewPlayer registrationNewPlayerConfig
|
RegistrationNewPlayer registrationNewPlayerConfig
|
||||||
RequestCache ristretto.Config
|
RequestCache ristretto.Config
|
||||||
SignPublicKeys bool
|
SignPublicKeys bool
|
||||||
SkinSizeLimit int
|
SkinSizeLimit int
|
||||||
OfflineSkins bool
|
OfflineSkins bool
|
||||||
StateDirectory string
|
StateDirectory string
|
||||||
TokenExpireSec int
|
TokenExpireSec int
|
||||||
TokenStaleSec int
|
TokenStaleSec int
|
||||||
TransientUsers transientUsersConfig
|
TransientUsers transientUsersConfig
|
||||||
ValidPlayerNameRegex string
|
ValidPlayerNameRegex string
|
||||||
}
|
}
|
||||||
|
|
||||||
var defaultRateLimitConfig = rateLimitConfig{
|
var defaultRateLimitConfig = rateLimitConfig{
|
||||||
@ -148,17 +148,17 @@ var defaultBodyLimitConfig = bodyLimitConfig{
|
|||||||
|
|
||||||
func DefaultConfig() Config {
|
func DefaultConfig() Config {
|
||||||
return Config{
|
return Config{
|
||||||
AllowCapes: true,
|
AllowCapes: true,
|
||||||
AllowChangingPlayerName: true,
|
AllowChangingPlayerName: true,
|
||||||
AllowPasswordLogin: true,
|
AllowPasswordLogin: true,
|
||||||
AllowSkins: true,
|
AllowSkins: true,
|
||||||
AllowTextureFromURL: false,
|
AllowTextureFromURL: false,
|
||||||
AllowCreatingDeletingPlayers: false,
|
AllowAddingDeletingPlayers: false,
|
||||||
ApplicationName: "Drasl",
|
ApplicationName: "Drasl",
|
||||||
ApplicationOwner: "Anonymous",
|
ApplicationOwner: "Anonymous",
|
||||||
BaseURL: "",
|
BaseURL: "",
|
||||||
BodyLimit: defaultBodyLimitConfig,
|
BodyLimit: defaultBodyLimitConfig,
|
||||||
CORSAllowOrigins: []string{},
|
CORSAllowOrigins: []string{},
|
||||||
CreateNewPlayer: createNewPlayerConfig{
|
CreateNewPlayer: createNewPlayerConfig{
|
||||||
Allow: true,
|
Allow: true,
|
||||||
AllowChoosingUUID: false,
|
AllowChoosingUUID: false,
|
||||||
|
@ -19,7 +19,7 @@ Other available options:
|
|||||||
- `DataDirectory`: directory where Drasl's static assets are installed. String. Default value: `"/usr/share/drasl"`.
|
- `DataDirectory`: directory where Drasl's static assets are installed. String. Default value: `"/usr/share/drasl"`.
|
||||||
- `ListenAddress`: IP address and port to listen on. Depending on how you configure your reverse proxy and whether you run Drasl in a container, you should consider setting the listen address to `"127.0.0.1:25585"` to ensure Drasl is only accessible through the reverse proxy. If your reverse proxy is unable to connect to Drasl, try setting this back to the default value. String. Default value: `"0.0.0.0:25585"`.
|
- `ListenAddress`: IP address and port to listen on. Depending on how you configure your reverse proxy and whether you run Drasl in a container, you should consider setting the listen address to `"127.0.0.1:25585"` to ensure Drasl is only accessible through the reverse proxy. If your reverse proxy is unable to connect to Drasl, try setting this back to the default value. String. Default value: `"0.0.0.0:25585"`.
|
||||||
- `DefaultAdmins`: Usernames of the instance's permanent admins. Admin rights can be granted to other accounts using the web UI, but admins defined via `DefaultAdmins` cannot be demoted unless they are removed from the config file. Array of strings. Default value: `[]`.
|
- `DefaultAdmins`: Usernames of the instance's permanent admins. Admin rights can be granted to other accounts using the web UI, but admins defined via `DefaultAdmins` cannot be demoted unless they are removed from the config file. Array of strings. Default value: `[]`.
|
||||||
- `DefaultMaxPlayerCount`: Number of players each user is allowed to own by default. Admins can increase or decrease each user's individual limit. Use `-1` to allow creating an unlimited number of players. Has no effect unless `AllowCreatingDeletingPlayers` is `true`. Integer. Default value: `1`.
|
- `DefaultMaxPlayerCount`: Number of players each user is allowed to own by default. Admins can increase or decrease each user's individual limit. Use `-1` to allow creating an unlimited number of players. Has no effect unless `AllowAddingDeletingPlayers` is `true`. Integer. Default value: `1`.
|
||||||
- `PreMigrationBackups`: Back up the database to `/path/to/StateDirectory/drasl.X.YYYY-mm-ddTHH-MM-SSZ.db` (where `X` is the old database version) before migrating to a new database version. Boolean. Default value: `true`.
|
- `PreMigrationBackups`: Back up the database to `/path/to/StateDirectory/drasl.X.YYYY-mm-ddTHH-MM-SSZ.db` (where `X` is the old database version) before migrating to a new database version. Boolean. Default value: `true`.
|
||||||
- `EnableBackgroundEffect`: Whether to enable the 3D background animation in the web UI. Boolean. Default value: `true`.
|
- `EnableBackgroundEffect`: Whether to enable the 3D background animation in the web UI. Boolean. Default value: `true`.
|
||||||
- `EnableFooter`: Whether to enable the page footer in the web UI. Boolean. Default value: `true`.
|
- `EnableFooter`: Whether to enable the page footer in the web UI. Boolean. Default value: `true`.
|
||||||
@ -110,8 +110,8 @@ Other available options:
|
|||||||
- `TokenStaleSec`: number of seconds after which an access token will go "stale". A stale token needs to be refreshed before it can be used to log in to a Minecraft server. By default, `TokenStaleSec` is set to `0`, meaning tokens will never go stale, and you should never see an error in-game like "Failed to login: Invalid session (Try restarting your game)". To have tokens go stale after one day, for example, set this option to `86400`. Integer. Default value: `0`.
|
- `TokenStaleSec`: number of seconds after which an access token will go "stale". A stale token needs to be refreshed before it can be used to log in to a Minecraft server. By default, `TokenStaleSec` is set to `0`, meaning tokens will never go stale, and you should never see an error in-game like "Failed to login: Invalid session (Try restarting your game)". To have tokens go stale after one day, for example, set this option to `86400`. Integer. Default value: `0`.
|
||||||
- `TokenExpireSec`: number of seconds after which an access token will expire. An expired token can neither be refreshed nor be used to log in to a Minecraft server. By default, `TokenExpireSec` is set to `0`, meaning tokens will never expire, and you should never have to log in again to your launcher if you've been away for a while. The security risks of non-expiring JWTs are actually quite mild; an attacker would still need access to a client's system to steal a token. But if you're concerned about security, you might, for example, set this option to `604800` to have tokens expire after one week. Integer. Default value: `0`.
|
- `TokenExpireSec`: number of seconds after which an access token will expire. An expired token can neither be refreshed nor be used to log in to a Minecraft server. By default, `TokenExpireSec` is set to `0`, meaning tokens will never expire, and you should never have to log in again to your launcher if you've been away for a while. The security risks of non-expiring JWTs are actually quite mild; an attacker would still need access to a client's system to steal a token. But if you're concerned about security, you might, for example, set this option to `604800` to have tokens expire after one week. Integer. Default value: `0`.
|
||||||
- `AllowPasswordLogin`: Allow registration and login with passwords. Disable to force users to register via OIDC (see `[[RegistrationOIDC]]`). If disabled, users must use Minecraft Tokens to log in to Minecraft launchers. If this option is disabled after being previously enabled, password accounts will still have the option to link an OIDC provider to their account. Boolean. Default value: `true`.
|
- `AllowPasswordLogin`: Allow registration and login with passwords. Disable to force users to register via OIDC (see `[[RegistrationOIDC]]`). If disabled, users must use Minecraft Tokens to log in to Minecraft launchers. If this option is disabled after being previously enabled, password accounts will still have the option to link an OIDC provider to their account. Boolean. Default value: `true`.
|
||||||
- `AllowCreatingDeletingPlayers`: Allow users to create and delete players up to their individual max player count. The default max player count is controlled by `DefaultMaxPlayerCount`. If this option is disabled, users will only be allowed the one player that is created for them when they register. Admins can create and delete players regardless of this setting. Boolean. Default value: `false`.
|
- `AllowAddingDeletingPlayers`: Allow users to create and delete players up to their individual max player count. The default max player count is controlled by `DefaultMaxPlayerCount`. If this option is disabled, users will only be allowed the one player that is created for them when they register. Admins can create and delete players regardless of this setting. Boolean. Default value: `false`.
|
||||||
- `AllowChangingPlayerName`: Allow users to change their "player name" after their account has already been created. Could be useful in conjunction with `RegistrationExistingPlayer` if you want to make users register from an existing (e.g. Mojang) account but you want them to be able to choose a new player name. Admins can change the name of any player regardless of this setting. Beware: when `AllowCreatingDeletingPlayers` is `true`, users can simply delete a player and create a new one with a new name. Boolean. Default value: `true`.
|
- `AllowChangingPlayerName`: Allow users to change their "player name" after their account has already been created. Could be useful in conjunction with `RegistrationExistingPlayer` if you want to make users register from an existing (e.g. Mojang) account but you want them to be able to choose a new player name. Admins can change the name of any player regardless of this setting. Beware: when `AllowAddingDeletingPlayers` is `true`, users can simply delete a player and create a new one with a new name. Boolean. Default value: `true`.
|
||||||
- `AllowSkins`: Allow users to upload skins. You may want to disable this option if you want to rely exclusively on `ForwardSkins`, e.g. to fully support Vanilla clients. Admins can set skins regardless of this setting. Boolean. Default value: `true`.
|
- `AllowSkins`: Allow users to upload skins. You may want to disable this option if you want to rely exclusively on `ForwardSkins`, e.g. to fully support Vanilla clients. Admins can set skins regardless of this setting. Boolean. Default value: `true`.
|
||||||
- `AllowCapes`: Allow users to upload capes. Admins can set capes regardless of this setting. Boolean. Default value: `true`.
|
- `AllowCapes`: Allow users to upload capes. Admins can set capes regardless of this setting. Boolean. Default value: `true`.
|
||||||
- `AllowTextureFromURL`: Allow users to specify a skin or cape by providing a URL to the texture file. Previously, this option was always allowed; now it is opt-in. Admins can do this regardless of this setting. Boolean. Default value: `false`.
|
- `AllowTextureFromURL`: Allow users to specify a skin or cape by providing a URL to the texture file. Previously, this option was always allowed; now it is opt-in. Admins can do this regardless of this setting. Boolean. Default value: `false`.
|
||||||
|
@ -13,8 +13,8 @@ Major changes:
|
|||||||
New configuration options:
|
New configuration options:
|
||||||
|
|
||||||
- `AllowPasswordLogin`: Allow registration and login with passwords. Disable to force users to register via OIDC (see `[[RegistrationOIDC]]`). If disabled, users must use Minecraft Tokens to log in to Minecraft launchers. If this option is disabled after being previously enabled, password accounts will still have the option to link an OIDC provider to their account. Boolean. Default value: `true`.
|
- `AllowPasswordLogin`: Allow registration and login with passwords. Disable to force users to register via OIDC (see `[[RegistrationOIDC]]`). If disabled, users must use Minecraft Tokens to log in to Minecraft launchers. If this option is disabled after being previously enabled, password accounts will still have the option to link an OIDC provider to their account. Boolean. Default value: `true`.
|
||||||
- `AllowCreatingDeletingPlayers`: Allow users to create and delete players up to their individual max player count. The default max player count is controlled by `DefaultMaxPlayerCount`. If this option is disabled, users will only be allowed the one player that is created for them when they register. Admins can create and delete players regardless of this setting. Boolean. Default value: `false`.
|
- `AllowAddingDeletingPlayers`: Allow users to create and delete players up to their individual max player count. The default max player count is controlled by `DefaultMaxPlayerCount`. If this option is disabled, users will only be allowed the one player that is created for them when they register. Admins can create and delete players regardless of this setting. Boolean. Default value: `false`.
|
||||||
- `DefaultMaxPlayerCount`: Number of players each user is allowed to own by default. Admins can increase or decrease each user's individual limit. Use `-1` to allow creating an unlimited number of players. Has no effect unless `AllowCreatingDeletingPlayers` is set to `true`. Integer. Default value: `1`.
|
- `DefaultMaxPlayerCount`: Number of players each user is allowed to own by default. Admins can increase or decrease each user's individual limit. Use `-1` to allow creating an unlimited number of players. Has no effect unless `AllowAddingDeletingPlayers` is set to `true`. Integer. Default value: `1`.
|
||||||
- `CORSAllowOrigins`: List of origins that may access Drasl API routes. See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin. Necessary for allowing browsers to access the Drasl API. Set to `["*"]` to allow all origins. Array of strings. Example value: `["https://front-end.example.com"]`. Default value: `[]`.
|
- `CORSAllowOrigins`: List of origins that may access Drasl API routes. See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin. Necessary for allowing browsers to access the Drasl API. Set to `["*"]` to allow all origins. Array of strings. Example value: `["https://front-end.example.com"]`. Default value: `[]`.
|
||||||
- `EnableWebFrontEnd`: Whether to enable the web UI. Boolean. Default value: `true`.
|
- `EnableWebFrontEnd`: Whether to enable the web UI. Boolean. Default value: `true`.
|
||||||
- `PreMigrationBackups`: Back up the database to `/path/to/StateDirectory/drasl.X.YYYY-mm-ddTHH-MM-SSZ.db` (where `X` is the old database version) before migrating to a new database version. Boolean. Default value: `true`.
|
- `PreMigrationBackups`: Back up the database to `/path/to/StateDirectory/drasl.X.YYYY-mm-ddTHH-MM-SSZ.db` (where `X` is the old database version) before migrating to a new database version. Boolean. Default value: `true`.
|
||||||
|
@ -31,7 +31,7 @@ func setupRegistrationExistingPlayerTS(t *testing.T, requireSkinVerification boo
|
|||||||
ts.SetupAux(auxConfig)
|
ts.SetupAux(auxConfig)
|
||||||
|
|
||||||
config := testConfig()
|
config := testConfig()
|
||||||
config.AllowCreatingDeletingPlayers = true
|
config.AllowAddingDeletingPlayers = true
|
||||||
config.RegistrationNewPlayer.Allow = false
|
config.RegistrationNewPlayer.Allow = false
|
||||||
config.RegistrationExistingPlayer = registrationExistingPlayerConfig{
|
config.RegistrationExistingPlayer = registrationExistingPlayerConfig{
|
||||||
Allow: true,
|
Allow: true,
|
||||||
@ -207,7 +207,7 @@ func TestFront(t *testing.T) {
|
|||||||
ts := &TestSuite{}
|
ts := &TestSuite{}
|
||||||
|
|
||||||
config := testConfig()
|
config := testConfig()
|
||||||
config.AllowCreatingDeletingPlayers = true
|
config.AllowAddingDeletingPlayers = true
|
||||||
config.RegistrationNewPlayer.AllowChoosingUUID = true
|
config.RegistrationNewPlayer.AllowChoosingUUID = true
|
||||||
ts.Setup(config)
|
ts.Setup(config)
|
||||||
defer ts.Teardown()
|
defer ts.Teardown()
|
||||||
|
@ -102,7 +102,7 @@ func (app *App) CreatePlayer(
|
|||||||
return Player{}, err
|
return Player{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !app.Config.AllowCreatingDeletingPlayers && !callerIsAdmin {
|
if !app.Config.AllowAddingDeletingPlayers && !callerIsAdmin {
|
||||||
return Player{}, NewBadRequestUserError("You are not allowed to create new players.")
|
return Player{}, NewBadRequestUserError("You are not allowed to create new players.")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -586,7 +586,7 @@ func (app *App) InvalidateUser(db *gorm.DB, user *User) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (app *App) DeletePlayer(caller *User, player *Player) error {
|
func (app *App) DeletePlayer(caller *User, player *Player) error {
|
||||||
if !app.Config.AllowCreatingDeletingPlayers && !caller.IsAdmin {
|
if !app.Config.AllowAddingDeletingPlayers && !caller.IsAdmin {
|
||||||
return NewUserError(http.StatusForbidden, "You are not allowed to delete players.")
|
return NewUserError(http.StatusForbidden, "You are not allowed to delete players.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,7 +151,7 @@
|
|||||||
<input type="submit" value="Save changes" />
|
<input type="submit" value="Save changes" />
|
||||||
</p>
|
</p>
|
||||||
</form>
|
</form>
|
||||||
{{ if or .App.Config.AllowCreatingDeletingPlayers .User.IsAdmin }}
|
{{ if or .App.Config.AllowAddingDeletingPlayers .User.IsAdmin }}
|
||||||
<p>
|
<p>
|
||||||
<details>
|
<details>
|
||||||
<summary>Delete Player</summary>
|
<summary>Delete Player</summary>
|
||||||
|
@ -44,7 +44,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td colspan="2">Player</td>
|
<td colspan="2">Player</td>
|
||||||
<td>UUID</td>
|
<td>UUID</td>
|
||||||
{{ if or .App.Config.AllowCreatingDeletingPlayers .User.IsAdmin }}
|
{{ if or .App.Config.AllowAddingDeletingPlayers .User.IsAdmin }}
|
||||||
<td>Delete Player</td>
|
<td>Delete Player</td>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</tr>
|
</tr>
|
||||||
@ -69,7 +69,7 @@
|
|||||||
>
|
>
|
||||||
</td>
|
</td>
|
||||||
<td>{{ $player.UUID }}</td>
|
<td>{{ $player.UUID }}</td>
|
||||||
{{ if or $.App.Config.AllowCreatingDeletingPlayers $.User.IsAdmin }}
|
{{ if or $.App.Config.AllowAddingDeletingPlayers $.User.IsAdmin }}
|
||||||
<td>
|
<td>
|
||||||
<input type="submit" form="delete-{{ $player.UUID }}" value="Delete" />
|
<input type="submit" form="delete-{{ $player.UUID }}" value="Delete" />
|
||||||
</td>
|
</td>
|
||||||
@ -82,7 +82,7 @@
|
|||||||
No players yet.
|
No players yet.
|
||||||
{{ end }}
|
{{ end }}
|
||||||
<p>
|
<p>
|
||||||
{{ if or (and (not .User.IsAdmin) (not .App.Config.AllowCreatingDeletingPlayers)) (eq .MaxPlayerCount 0) }}
|
{{ if or (and (not .User.IsAdmin) (not .App.Config.AllowAddingDeletingPlayers)) (eq .MaxPlayerCount 0) }}
|
||||||
{{ if .AdminView }}{{ .TargetUser.Username }} is{{ else }}You are{{ end }} not allowed to create new players.
|
{{ if .AdminView }}{{ .TargetUser.Username }} is{{ else }}You are{{ end }} not allowed to create new players.
|
||||||
{{ if .AdminView }}You can override this limit since you're an admin.{{ end }}
|
{{ if .AdminView }}You can override this limit since you're an admin.{{ end }}
|
||||||
{{ else if (gt .MaxPlayerCount 0) }}
|
{{ else if (gt .MaxPlayerCount 0) }}
|
||||||
@ -92,7 +92,7 @@
|
|||||||
{{ if .AdminView }}{{ .TargetUser.Username }}'s{{ else }}Your{{ end }} account can have an unlimited number of players.
|
{{ if .AdminView }}{{ .TargetUser.Username }}'s{{ else }}Your{{ end }} account can have an unlimited number of players.
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</p>
|
</p>
|
||||||
{{ if or (and .App.Config.AllowCreatingDeletingPlayers (or (lt (len .TargetUser.Players) .MaxPlayerCount) (lt .MaxPlayerCount 0))) .User.IsAdmin }}
|
{{ if or (and .App.Config.AllowAddingDeletingPlayers (or (lt (len .TargetUser.Players) .MaxPlayerCount) (lt .MaxPlayerCount 0))) .User.IsAdmin }}
|
||||||
{{ if .App.Config.CreateNewPlayer.Allow }}
|
{{ if .App.Config.CreateNewPlayer.Allow }}
|
||||||
{{ if or .User.IsAdmin .App.Config.CreateNewPlayer.AllowChoosingUUID }}
|
{{ if or .User.IsAdmin .App.Config.CreateNewPlayer.AllowChoosingUUID }}
|
||||||
<h4>Create a new player</h4>
|
<h4>Create a new player</h4>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user