feat(server): owner role group, custom role colors with effects and animated avatars

This commit is contained in:
justme committed 2026-10-17 13:25:13 +08:00
1 parent 7ef298f587
commit bef8898cd8
8 files changed
+67 -19

No files matched your search

@@ -16,14 +16,20 @@ public sealed partial class SqliteAccountStore
: new AccountProfile { Username = username, DisplayName = username, ModifiedAt = 0 };
}
}
/// <summary>动图头像保留全部帧,允许比静态头像大得多(约 4.5 MB)</summary>
private const int MaxGifAvatarChars = 6_000_000;
public AccountProfile UpdateProfile(string username, string displayName, string? avatar)
{
if (displayName is null || displayName.Trim().Length > 48 || displayName.Any(char.IsControl)) throw new WebDropException(ErrorCode.BadRequest);
if (avatar is not null)
{
string? prefix = new[] { "data:image/png;base64,", "data:image/jpeg;base64,", "data:image/webp;base64," }.FirstOrDefault(p => avatar.StartsWith(p, StringComparison.Ordinal));
if (prefix is null || avatar.Length > 350_000 || avatar.Length <= prefix.Length) throw new WebDropException(ErrorCode.BadRequest);
try { _ = Convert.FromBase64String(avatar[prefix.Length..]); }
string? prefix = new[] { "data:image/png;base64,", "data:image/jpeg;base64,", "data:image/webp;base64,", "data:image/gif;base64," }.FirstOrDefault(p => avatar.StartsWith(p, StringComparison.Ordinal));
if (prefix is null || avatar.Length > (prefix.Contains("gif") ? MaxGifAvatarChars : 350_000) || avatar.Length <= prefix.Length) throw new WebDropException(ErrorCode.BadRequest);
try
{
var bytes = Convert.FromBase64String(avatar[prefix.Length..]);
if (prefix.Contains("gif") && !(bytes.Length > 6 && bytes[0] == (byte)'G' && bytes[1] == (byte)'I' && bytes[2] == (byte)'F')) throw new WebDropException(ErrorCode.BadRequest);
}
catch (FormatException) { throw new WebDropException(ErrorCode.BadRequest); }
}
lock (_gate)