Radicade Public Code

This commit is contained in:
JogmansonReal
2026-10-16 23:33:13 -07:00
commit 55175acdf6
832 changed files with 363261 additions and 0 deletions
+155
View File
@@ -0,0 +1,155 @@
using Microsoft.EntityFrameworkCore;
using RadicadeServer.API.Notifications;
using RadicadeServer.DB;
using RadicadeServer.RecNet.Enums.Messages;
using RadicadeServer.RecNet.Enums.Moderation;
using RadicadeServer.RecNet.Messages;
using RadicadeServer.RecNet.Moderation;
using RadicadeServer.RecNet.Notifications;
namespace RadicadeServer.Utils
{
public static class VoiceChatRestrictions
{
public const string NotificationId = "VoiceChatRestriction";
public const string Method = "Voice Restriction";
public const long CoachAccountId = 1;
public const string CoachMessage =
"You have had your voice privileges temporarily restricted due to speech which violates the Code of Conduct.";
public static readonly TimeSpan DefaultDuration = TimeSpan.FromHours(24);
public static readonly TimeSpan MinimumDuration = TimeSpan.FromHours(1);
public static readonly TimeSpan MaximumDuration = TimeSpan.FromDays(30);
public static TimeSpan ClampDuration(TimeSpan duration)
{
if (duration < MinimumDuration) return MinimumDuration;
if (duration > MaximumDuration) return MaximumDuration;
return duration;
}
public static Task<VoiceChatRestriction?> ActiveAsync(RecDBContext db, long playerId) =>
db.VoiceChatRestrictions.AsNoTracking()
.Where(x => x.PlayerId == playerId && x.ClearedAt == null && x.ExpiresAt > DateTime.UtcNow)
.OrderByDescending(x => x.ExpiresAt)
.FirstOrDefaultAsync();
public static async Task<bool> IsRestrictedAsync(RecDBContext db, long playerId) =>
await ActiveAsync(db, playerId) != null;
public static async Task<VoiceChatRestriction> ApplyAsync(
RecDBContext db,
long playerId,
string reason,
ReportCategory category,
TimeSpan duration,
string issuedBy,
string? issuedByUsername = null,
string? moderatorNote = null)
{
var now = DateTime.UtcNow;
var clamped = ClampDuration(duration);
var restriction = await db.VoiceChatRestrictions
.Where(x => x.PlayerId == playerId && x.ClearedAt == null && x.ExpiresAt > now)
.OrderByDescending(x => x.ExpiresAt)
.FirstOrDefaultAsync();
if (restriction == null)
{
restriction = new VoiceChatRestriction
{
PlayerId = playerId,
StartedAt = now,
ExpiresAt = now + clamped
};
await db.VoiceChatRestrictions.AddAsync(restriction);
}
else
{
var extended = now + clamped;
if (extended > restriction.ExpiresAt) restriction.ExpiresAt = extended;
restriction.StartedAt = now;
}
restriction.Reason = reason;
restriction.Category = category;
restriction.IssuedBy = issuedBy;
restriction.IssuedByUsername = issuedByUsername;
restriction.ModeratorNote = moderatorNote;
await db.SaveChangesAsync();
await TellPlayerAsync(playerId);
return restriction;
}
private static async Task TellPlayerAsync(long playerId)
{
try
{
await Notify.SendMessage(playerId, new Message
{
Type = MessageType.CoachMessage,
Data = CoachMessage,
FromPlayerId = CoachAccountId
});
}
catch
{
}
}
public static async Task<bool> ClearAsync(RecDBContext db, long playerId, string? clearedBy = null)
{
var now = DateTime.UtcNow;
var active = await db.VoiceChatRestrictions
.Where(x => x.PlayerId == playerId && x.ClearedAt == null && x.ExpiresAt > now)
.ToListAsync();
if (active.Count == 0) return false;
foreach (var restriction in active)
{
restriction.ClearedAt = now;
restriction.ClearedBy = clearedBy;
}
await db.SaveChangesAsync();
return true;
}
public static object Payload(VoiceChatRestriction? restriction) => new
{
restricted = restriction != null,
playerId = restriction?.PlayerId ?? 0,
reason = restriction?.Reason ?? "",
category = restriction?.Category.ToString() ?? "",
startedAtUtc = restriction?.StartedAt,
expiresAtUtc = restriction?.ExpiresAt,
secondsRemaining = restriction == null
? 0
: (int)Math.Max(0, (restriction.ExpiresAt - DateTime.UtcNow).TotalSeconds)
};
public static async Task PushAsync(long playerId, VoiceChatRestriction? restriction)
{
try
{
await Notify.SendNotify(playerId, new Notification
{
Id = NotificationId,
Msg = Payload(restriction)
});
}
catch
{
}
}
}
}