Files
Radicade/Server/Players/UsernameRules.cs
T
2026-10-16 23:33:13 -07:00

66 lines
1.8 KiB
C#

namespace RadicadeServer.Utils
{
public static class UsernameRules
{
public const int MinLength = 3;
public const int MaxLength = 24;
private static readonly string[] ReservedNames =
[
"me", "you", "recroom", "recnet", "radicade", "againstgravity",
"system", "admin", "administrator", "moderator", "mod", "support",
"staff", "official", "developer", "owner", "root"
];
public static string? Normalize(string? posted)
{
if (string.IsNullOrWhiteSpace(posted)) return null;
var name = posted.Trim().TrimStart('@').Trim();
return name.Length == 0 ? null : name;
}
public static string? Parse(string? posted, out string? rejection)
{
rejection = null;
var name = Normalize(posted);
if (name == null) return null;
rejection = Rejection(name);
return rejection == null ? name : null;
}
public static string? Rejection(string name)
{
if (name.Length < MinLength)
return $"Names must be at least {MinLength} characters.";
if (name.Length > MaxLength)
return $"Names must be {MaxLength} characters or fewer.";
bool hasLetter = false;
foreach (var character in name)
{
if (char.IsAsciiLetter(character)) { hasLetter = true; continue; }
if (char.IsAsciiDigit(character)) continue;
return "Names can only use letters and numbers.";
}
if (!hasLetter)
return "Names must contain at least one letter.";
if (ReservedNames.Any(reserved => string.Equals(reserved, name, StringComparison.OrdinalIgnoreCase)))
return "That name is reserved. Please pick another one.";
if (!name.IsPure())
return "That name is not allowed. Please pick another one.";
return null;
}
public static string ComparisonKey(string name) => name.ToUpperInvariant();
public static string Generate() => RecNet.Generators.GenerateUsername();
}
}