fix: Adds server access with protected accounts (#915)
Adds a configuration file to specify protected accounts:
_Distribution/Configuration/server-access.json_
```json
{
"newPasswordOnReset": false,
"protectedAccounts": ["admin"]
}
```
Protected accounts are unbanned and reset to `AccessLevel.Owner` upon login.
The option `newPasswordOnReset` will create a new password for a protected account if it needs to be reset. The password is a random GUID and logged to the console.
_**Note:**_ If your player character was accidentally modified, simply make a new character to fix the old one.
This commit is contained in:
parent
51169ddbb0
commit
fc51b60cc1
4 changed files with 108 additions and 5 deletions
|
|
@ -241,13 +241,15 @@ namespace Server.Misc
|
|||
{
|
||||
res = DeleteResultType.CharBeingPlayed;
|
||||
}
|
||||
else if (RestrictDeletion && Core.Now < m.Created + DeleteDelay)
|
||||
else if (acct.AccessLevel == AccessLevel.Player && RestrictDeletion && Core.Now < m.Created + DeleteDelay)
|
||||
{
|
||||
res = DeleteResultType.CharTooYoung;
|
||||
}
|
||||
else if (m.AccessLevel == AccessLevel.Player &&
|
||||
// Don't need to check current location, if netstate is null, they're logged out
|
||||
else if (
|
||||
m.AccessLevel == AccessLevel.Player &&
|
||||
Region.Find(m.LogoutLocation, m.LogoutMap).IsPartOf<JailRegion>()
|
||||
) // Don't need to check current location, if netstate is null, they're logged out
|
||||
)
|
||||
{
|
||||
res = DeleteResultType.BadRequest;
|
||||
}
|
||||
|
|
@ -265,7 +267,6 @@ namespace Server.Misc
|
|||
|
||||
state.SendCharacterDeleteResult(res);
|
||||
state.SendCharacterListUpdate(acct);
|
||||
|
||||
}
|
||||
|
||||
public static bool CanCreate(IPAddress ip) =>
|
||||
|
|
|
|||
|
|
@ -27,6 +27,9 @@ namespace Server.Misc
|
|||
a.AccessLevel = AccessLevel.Owner;
|
||||
|
||||
Console.WriteLine("Account created.");
|
||||
|
||||
ServerAccess.AddProtectedAccount(a, true);
|
||||
Console.WriteLine("Added {0} to the protected accounts list.", a.Username);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ namespace Server.Network
|
|||
{
|
||||
// Delay in milliseconds
|
||||
private static readonly int[] Delays = new int[0x100];
|
||||
private static string ThrottlesConfiguration = "Configuration/throttles.json";
|
||||
private const string ThrottlesConfiguration = "Configuration/throttles.json";
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
|
|
|
|||
99
Projects/UOContent/Misc/ServerAccess.cs
Normal file
99
Projects/UOContent/Misc/ServerAccess.cs
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text.Json.Serialization;
|
||||
using Server.Accounting;
|
||||
using Server.Json;
|
||||
using Server.Logging;
|
||||
|
||||
namespace Server.Misc;
|
||||
|
||||
public static class ServerAccess
|
||||
{
|
||||
private static readonly ILogger logger = LogFactory.GetLogger(typeof(ServerAccess));
|
||||
private const string _serverAccessConfigurationPath = "Configuration/server-access.json";
|
||||
public static ServerAccessConfiguration ServerAccessConfiguration { get; private set; }
|
||||
|
||||
public static void SaveConfiguration()
|
||||
{
|
||||
var path = Path.Join(Core.BaseDirectory, _serverAccessConfigurationPath);
|
||||
JsonConfig.Serialize(path, ServerAccessConfiguration);
|
||||
}
|
||||
|
||||
public static void AddProtectedAccount(Account acct, bool save = false)
|
||||
{
|
||||
ServerAccessConfiguration.ProtectedAccounts.Add(acct.Username.ToLower());
|
||||
|
||||
if (save)
|
||||
{
|
||||
SaveConfiguration();
|
||||
}
|
||||
}
|
||||
|
||||
public static void RemoveProtectedAccount(Account acct, bool save = false)
|
||||
{
|
||||
ServerAccessConfiguration.ProtectedAccounts.Remove(acct.Username.ToLower());
|
||||
|
||||
if (save)
|
||||
{
|
||||
SaveConfiguration();
|
||||
}
|
||||
}
|
||||
|
||||
public static void Configure()
|
||||
{
|
||||
var path = Path.Join(Core.BaseDirectory, _serverAccessConfigurationPath);
|
||||
|
||||
if (!File.Exists(path))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ServerAccessConfiguration = JsonConfig.Deserialize<ServerAccessConfiguration>(path);
|
||||
var protectedAccounts = string.Join(", ", ServerAccessConfiguration.ProtectedAccounts);
|
||||
logger.Information("Protected accounts registered: {0}", protectedAccounts);
|
||||
}
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
EventSink.AccountLogin += EventSink_ResetProtectedAccount;
|
||||
}
|
||||
|
||||
public static void EventSink_ResetProtectedAccount(AccountLoginEventArgs e)
|
||||
{
|
||||
var username = e.Username.ToLower();
|
||||
if (!ServerAccessConfiguration.ProtectedAccounts.Contains(username))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var account = Accounts.GetAccount(username);
|
||||
if (account is not { Banned: true, AccessLevel: >= AccessLevel.Owner })
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
account.Banned = false;
|
||||
account.AccessLevel = AccessLevel.Owner;
|
||||
|
||||
logger.Warning("Protected account \"{0}\" has been reset.", username);
|
||||
|
||||
if (ServerAccessConfiguration.NewPasswordOnReset)
|
||||
{
|
||||
var password = Guid.NewGuid().ToString();
|
||||
logger.Warning("Protected account \"{0}\" password reset to \"{1}\"", username, password);
|
||||
account.SetPassword(password);
|
||||
}
|
||||
|
||||
e.Accepted = true;
|
||||
}
|
||||
}
|
||||
|
||||
public record ServerAccessConfiguration
|
||||
{
|
||||
[JsonPropertyName("newPasswordOnReset")]
|
||||
public bool NewPasswordOnReset { get; init; }
|
||||
|
||||
[JsonPropertyName("protectedAccounts")]
|
||||
public HashSet<string> ProtectedAccounts { get; init; }
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue