mirror of
https://github.com/DorkSquadRR/DorkNet.git
synced 2026-10-27 07:58:45 -07:00
Refactor room data handling: standardize timestamp usage with savedAt variable; ensure editable persistence version for room role data
This commit is contained in:
@@ -397,6 +397,7 @@ public class RoomsController(
|
|||||||
if (room is null) return NotFound(new { error = "room_not_found" });
|
if (room is null) return NotFound(new { error = "room_not_found" });
|
||||||
|
|
||||||
var newBlob = body.RoomDataFilename?.Trim() ?? string.Empty;
|
var newBlob = body.RoomDataFilename?.Trim() ?? string.Empty;
|
||||||
|
var savedAt = DateTime.UtcNow;
|
||||||
|
|
||||||
// Multi-scene rooms have a RoomScenes row per scene. The 2020
|
// Multi-scene rooms have a RoomScenes row per scene. The 2020
|
||||||
// client usually sends the scene's OrderIndex, but some flows
|
// client usually sends the scene's OrderIndex, but some flows
|
||||||
@@ -426,27 +427,33 @@ public class RoomsController(
|
|||||||
db.DormStates.Add(dormState);
|
db.DormStates.Add(dormState);
|
||||||
}
|
}
|
||||||
dormState.CurrentDataBlobName = newBlob;
|
dormState.CurrentDataBlobName = newBlob;
|
||||||
dormState.UpdatedAt = DateTime.UtcNow;
|
dormState.UpdatedAt = savedAt;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Owned rooms: only the creator can save. Admin override
|
var canSave = room.CreatorPlayerId == pid
|
||||||
// intentionally not included — admins should use /restore
|
|| await db.Players.AnyAsync(p => p.Id == pid && p.IsAdmin)
|
||||||
// when they need to roll a room back.
|
|| await db.RoomRoles.AnyAsync(r =>
|
||||||
if (room.CreatorPlayerId != pid) return Forbid();
|
r.RoomId == room.Id &&
|
||||||
|
r.PlayerId == pid &&
|
||||||
|
r.Accepted &&
|
||||||
|
r.Role == 0);
|
||||||
|
if (!canSave) return Forbid();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sceneRow is not null)
|
if (sceneRow is not null)
|
||||||
{
|
{
|
||||||
sceneRow.DataBlobName = newBlob;
|
sceneRow.DataBlobName = newBlob;
|
||||||
sceneRow.DataModifiedAt = DateTime.UtcNow;
|
sceneRow.DataModifiedAt = savedAt;
|
||||||
}
|
}
|
||||||
await db.Rooms
|
await db.Rooms
|
||||||
.Where(r => r.Id == roomId)
|
.Where(r => r.Id == roomId)
|
||||||
.ExecuteUpdateAsync(s => s
|
.ExecuteUpdateAsync(s => s
|
||||||
.SetProperty(r => r.CurrentDataBlobName, newBlob)
|
.SetProperty(r => r.CurrentDataBlobName, newBlob)
|
||||||
.SetProperty(r => r.UpdatedAt, DateTime.UtcNow));
|
.SetProperty(r => r.UpdatedAt, savedAt));
|
||||||
await db.SaveChangesAsync();
|
await db.SaveChangesAsync();
|
||||||
|
room.CurrentDataBlobName = newBlob;
|
||||||
|
room.UpdatedAt = savedAt;
|
||||||
|
|
||||||
// The watch's MasterUploadRoomDataBlobCoroutine waits for BOTH
|
// The watch's MasterUploadRoomDataBlobCoroutine waits for BOTH
|
||||||
// the /upload + /saveData responses AND a SubscriptionUpdateRoom
|
// the /upload + /saveData responses AND a SubscriptionUpdateRoom
|
||||||
@@ -470,7 +477,7 @@ public class RoomsController(
|
|||||||
if (sceneRow is not null && scene.Id == sceneRow.Id)
|
if (sceneRow is not null && scene.Id == sceneRow.Id)
|
||||||
{
|
{
|
||||||
scene.DataBlobName = newBlob;
|
scene.DataBlobName = newBlob;
|
||||||
scene.DataModifiedAt = DateTime.UtcNow;
|
scene.DataModifiedAt = savedAt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var savedSceneId = sceneRow?.OrderIndex ?? body.RoomSceneId;
|
var savedSceneId = sceneRow?.OrderIndex ?? body.RoomSceneId;
|
||||||
@@ -577,7 +584,7 @@ public class RoomsController(
|
|||||||
DataBlobName = newBlob,
|
DataBlobName = newBlob,
|
||||||
MaxPlayers = sceneRow?.MaxPlayers ?? 8,
|
MaxPlayers = sceneRow?.MaxPlayers ?? 8,
|
||||||
CanMatchmakeInto = sceneRow?.CanMatchmakeInto ?? true,
|
CanMatchmakeInto = sceneRow?.CanMatchmakeInto ?? true,
|
||||||
DataModifiedAt = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ssZ"),
|
DataModifiedAt = savedAt.ToString("yyyy-MM-ddTHH:mm:ssZ"),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -82,13 +82,14 @@ message RoomRoleCollectionData {
|
|||||||
|
|
||||||
// ── PersistedRoomData top-level (rec_room/persistence/persisted_room_data.proto)
|
// ── PersistedRoomData top-level (rec_room/persistence/persisted_room_data.proto)
|
||||||
//
|
//
|
||||||
// The 2026 schema has 30+ fields — we only set field 23 (room_role_data).
|
// The full schema has many more fields — we only set the fields the
|
||||||
// Everything else stays at proto3 defaults, which the client treats as
|
// December 2020 client needs for an editable minimal blob. Its
|
||||||
// "no saved state for this room" — exactly what we want for a fresh dorm
|
// RoomPersistenceManager checks field 1 against a minimum editable
|
||||||
// /clone with the role config injected.
|
// persistence version of 20, so generated blobs must carry a current
|
||||||
|
// version or room editors see the native "save data is out-of-date" prompt.
|
||||||
|
|
||||||
message PersistedRoomData {
|
message PersistedRoomData {
|
||||||
// field 1 (DEPRECATED_version) — reserved, do not set.
|
int32 DEPRECATED_version = 1;
|
||||||
// field 2 (persistence_views) — repeated, default empty list.
|
// field 2 (persistence_views) — repeated, default empty list.
|
||||||
// fields 3..22 — left at defaults.
|
// fields 3..22 — left at defaults.
|
||||||
RoomRoleCollectionData room_role_data = 23;
|
RoomRoleCollectionData room_role_data = 23;
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ namespace DorkNet.Server.Services;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class RoomDataBlobService
|
public class RoomDataBlobService
|
||||||
{
|
{
|
||||||
|
private const int December2020PersistenceVersion = 26;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Cached bytes of the "all-permissions-on" blob. Identical for every
|
/// Cached bytes of the "all-permissions-on" blob. Identical for every
|
||||||
/// room — there's no per-room state we vary yet, so building once at
|
/// room — there's no per-room state we vary yet, so building once at
|
||||||
@@ -40,6 +42,7 @@ public class RoomDataBlobService
|
|||||||
public byte[] OverlayAllPermsRoleData(byte[] existingBlob)
|
public byte[] OverlayAllPermsRoleData(byte[] existingBlob)
|
||||||
{
|
{
|
||||||
var msg = PersistedRoomData.Parser.ParseFrom(existingBlob);
|
var msg = PersistedRoomData.Parser.ParseFrom(existingBlob);
|
||||||
|
EnsureEditablePersistenceVersion(msg);
|
||||||
msg.RoomRoleData = _allPermsRoleData.Clone();
|
msg.RoomRoleData = _allPermsRoleData.Clone();
|
||||||
return msg.ToByteArray();
|
return msg.ToByteArray();
|
||||||
}
|
}
|
||||||
@@ -47,6 +50,7 @@ public class RoomDataBlobService
|
|||||||
public byte[] OverlayRroEditableRoleData(byte[] existingBlob)
|
public byte[] OverlayRroEditableRoleData(byte[] existingBlob)
|
||||||
{
|
{
|
||||||
var msg = PersistedRoomData.Parser.ParseFrom(existingBlob);
|
var msg = PersistedRoomData.Parser.ParseFrom(existingBlob);
|
||||||
|
EnsureEditablePersistenceVersion(msg);
|
||||||
msg.RoomRoleData = _rroEditableRoleData.Clone();
|
msg.RoomRoleData = _rroEditableRoleData.Clone();
|
||||||
return msg.ToByteArray();
|
return msg.ToByteArray();
|
||||||
}
|
}
|
||||||
@@ -55,6 +59,7 @@ public class RoomDataBlobService
|
|||||||
{
|
{
|
||||||
var msg = new PersistedRoomData
|
var msg = new PersistedRoomData
|
||||||
{
|
{
|
||||||
|
DEPRECATEDVersion = December2020PersistenceVersion,
|
||||||
RoomRoleData = BuildAllPermsRoleData(),
|
RoomRoleData = BuildAllPermsRoleData(),
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -73,6 +78,7 @@ public class RoomDataBlobService
|
|||||||
{
|
{
|
||||||
var msg = new PersistedRoomData
|
var msg = new PersistedRoomData
|
||||||
{
|
{
|
||||||
|
DEPRECATEDVersion = December2020PersistenceVersion,
|
||||||
RoomRoleData = BuildRroEditableRoleData(),
|
RoomRoleData = BuildRroEditableRoleData(),
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -153,6 +159,14 @@ public class RoomDataBlobService
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void EnsureEditablePersistenceVersion(PersistedRoomData msg)
|
||||||
|
{
|
||||||
|
if (msg.DEPRECATEDVersion < 20)
|
||||||
|
{
|
||||||
|
msg.DEPRECATEDVersion = December2020PersistenceVersion;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static string StableRoleGuid(int roleId) =>
|
private static string StableRoleGuid(int roleId) =>
|
||||||
GuidUtility.Create(GuidUtility.UrlNamespace, $"dorknet-room-role:{roleId}").ToString();
|
GuidUtility.Create(GuidUtility.UrlNamespace, $"dorknet-room-role:{roleId}").ToString();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user