modernuo/Projects/UOContent/Misc/ServerAccess.cs
Kamron Batman e6d30fef0f
fix: Reverts GetAccount to use IAccount. Adds IAccount to serialization. (#1565)
### Summary

- Fixes usernames not being `Intern`ed
- Reverts methods related to getting accounts from returning `Account` to `IAccount`.
- Makes `IAccount` also `ISerializable`
- Adds `IGenericReader.ReadAccount()` and `IGenericWriter.Write(IAccount)` -> The read method supports the original serialization of username, and using `IAccount.Serial`. The write method only serializes the `Serial`.
- Exposes `ReadStringRaw()` to allow some advanced scenarios.
2023-10-25 19:17:57 -07:00

101 lines
3 KiB
C#

using System.Collections.Generic;
using System.IO;
using System.Text.Json.Serialization;
using Server.Accounting;
using Server.Json;
using Server.Logging;
using Server.Network;
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 ??= new ServerAccessConfiguration());
}
public static void AddProtectedAccount(Account acct, bool save = false)
{
var username = acct.Username.ToLower();
ServerAccessConfiguration.ProtectedAccounts.Add(username);
logger.Information("Protected account added: {Username}", username);
if (save)
{
SaveConfiguration();
}
}
public static void RemoveProtectedAccount(Account acct, bool save = false)
{
var username = acct.Username.ToLower();
ServerAccessConfiguration.ProtectedAccounts.Remove(username);
logger.Information("Protected account removed: {Username}", username);
if (save)
{
SaveConfiguration();
}
}
public static void Configure()
{
var path = Path.Join(Core.BaseDirectory, _serverAccessConfigurationPath);
if (!File.Exists(path))
{
SaveConfiguration();
return;
}
ServerAccessConfiguration = JsonConfig.Deserialize<ServerAccessConfiguration>(path);
if (ServerAccessConfiguration.ProtectedAccounts.Count > 0)
{
var protectedAccounts = string.Join(", ", ServerAccessConfiguration.ProtectedAccounts);
logger.Information("Protected accounts registered: {Count}", 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;
}
if (Accounts.GetAccount(username) is not Account acct
|| !acct.Banned && acct.AccessLevel >= AccessLevel.Owner || !acct.CheckPassword(e.Password))
{
return;
}
acct.Banned = false;
acct.AccessLevel = AccessLevel.Owner;
logger.Warning("Protected account \"{Username}\" has been reset.", username);
if (e.RejectReason is ALRReason.Blocked or ALRReason.BadPass or ALRReason.BadComm)
{
e.Accepted = true;
}
}
}
public record ServerAccessConfiguration
{
[JsonPropertyName("protectedAccounts")]
public HashSet<string> ProtectedAccounts { get; set; } = new();
}