mirror of
https://github.com/DorkSquadRR/DorkNet.git
synced 2026-10-25 23:18:44 -07:00
feat: Enhance room management and moderation APIs
- Added support for multiple tag filters in HotRoomServer endpoint, allowing clients to query hot rooms with multiple tags. - Introduced a new DeleteRoom endpoint for owners to soft-archive their rooms, ensuring room data integrity. - Updated MagicDoor endpoint to return a structured response including refresh timing. - Improved reporting functionality to handle form submissions correctly, ensuring room reports are persisted. - Refactored per-field mutation endpoints to support both legacy and new client formats, accommodating changes in request structure. - Implemented a multi-field payload reader to handle complex requests more efficiently. - Enhanced logging for room code management to track player actions and conflicts.
This commit is contained in:
@@ -382,23 +382,49 @@ public class MatchController(
|
||||
[FromForm(Name = "roomCode")] string? roomCode,
|
||||
[FromForm(Name = "forceChange")] bool? forceChange)
|
||||
{
|
||||
var requested = (roomCode ?? Request.Query["roomCode"].FirstOrDefault())?.Trim();
|
||||
// Same normalisation the join path applies (GoToController.GoToCode →
|
||||
// RoomCodeService.Normalize), so a code typed with dashes/lowercase on
|
||||
// the watch still matches what we persist.
|
||||
var normalized = RoomCodeService.Normalize(
|
||||
roomCode ?? Request.Query["roomCode"].FirstOrDefault());
|
||||
|
||||
if (!string.IsNullOrEmpty(requested))
|
||||
if (normalized.Length > 0)
|
||||
{
|
||||
var normalized = requested.ToUpperInvariant();
|
||||
var taken = await db.PrivateInstances
|
||||
.AnyAsync(p => p.RoomCode == normalized && p.Id != instanceId);
|
||||
if (taken && forceChange != true)
|
||||
return Content(JsonSerializer.Serialize(RoomCodeService.Generate(instanceId)), "application/json");
|
||||
var pid = this.RequireCurrentPlayerId();
|
||||
var clash = await db.PrivateInstances
|
||||
.Where(p => p.RoomCode == normalized && p.Id != instanceId)
|
||||
.Select(p => new { p.Id, p.OwnerPlayerId })
|
||||
.FirstOrDefaultAsync();
|
||||
|
||||
// forceChange only lets a host reclaim a code from one of their OWN
|
||||
// instances; another player's code is never stolen. On refusal the
|
||||
// client just re-reads whatever code we echo back, so we fall
|
||||
// through to the read path instead of erroring.
|
||||
var blocked = clash is not null
|
||||
&& (clash.OwnerPlayerId != pid || forceChange != true);
|
||||
|
||||
var row = await db.PrivateInstances.FirstOrDefaultAsync(p => p.Id == instanceId);
|
||||
if (row is not null)
|
||||
if (!blocked && row is not null)
|
||||
{
|
||||
if (clash is not null)
|
||||
{
|
||||
// Release the caller's older claim first, as its own
|
||||
// statement, so the two rows never hold the code at once.
|
||||
await db.PrivateInstances
|
||||
.Where(p => p.Id == clash.Id)
|
||||
.ExecuteUpdateAsync(s => s.SetProperty(p => p.RoomCode, string.Empty));
|
||||
}
|
||||
row.RoomCode = normalized;
|
||||
await db.SaveChangesAsync();
|
||||
logger.LogInformation(
|
||||
"[roomcode] player={Player} instance={Instance} code={Code} force={Force}",
|
||||
pid, instanceId, normalized, forceChange == true);
|
||||
return Content(JsonSerializer.Serialize(normalized), "application/json");
|
||||
}
|
||||
|
||||
logger.LogWarning(
|
||||
"[roomcode] player={Player} instance={Instance} refused code={Code} taken={Taken} known={Known}",
|
||||
pid, instanceId, normalized, clash is not null, row is not null);
|
||||
}
|
||||
|
||||
var stored = await db.PrivateInstances
|
||||
|
||||
Reference in New Issue
Block a user