mirror of
https://github.com/DorkSquadRR/DorkNet.git
synced 2026-10-26 07:28:45 -07:00
Refactor room data blob handling and permissions
- Updated the RoomsController to utilize synthetic CDN keys for data blobs. - Introduced methods for determining current or synthetic data blob names. - Adjusted room role permissions to align with new game role definitions. - Enhanced the SanitizeController with a new endpoint for purity checks. - Modified Match and PlayerPresence services to handle deferred presence commits. - Improved RoomDataBlobService to support new game role and tool tag settings. - Added support for boot dorm grace period in PlayerPresenceService. - Updated protobuf definitions to reflect new room role and game role structures. You are now able to go into dorm and the rec center!
This commit is contained in:
@@ -1289,7 +1289,7 @@ public class GoToController(
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(room.CurrentDataBlobName)) return room.CurrentDataBlobName;
|
||||
|
||||
return $"room_{room.Id}_v1.dat";
|
||||
return RoomService.SyntheticDefaultRoomDataBlobName(room.Id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -37,8 +37,8 @@ public class MatchController(
|
||||
/// we mostly use this for visibility into Photon-side issues —
|
||||
/// without it, all we see in the catch-all is an opaque "200, empty
|
||||
/// reply" and no clue why a player crashed back to dorm. Failure
|
||||
/// reports also clear the pending /goto room and push a ModerationKick
|
||||
/// so the watch leaves the "Joining room" overlay instead of softlocking.</summary>
|
||||
/// reports also clear the pending /goto room so the next matchmaking
|
||||
/// attempt starts from a clean presence state.</summary>
|
||||
[HttpPost("/roominstance/{instanceId:long}/reportjoinresult")]
|
||||
public async Task<IActionResult> ReportJoinResult(long instanceId, [FromForm(Name = "result")] int? result)
|
||||
{
|
||||
@@ -59,6 +59,7 @@ public class MatchController(
|
||||
{
|
||||
presence.SetRoom(pid, completed.Value.TargetRoom);
|
||||
presence.MarkActive(pid);
|
||||
presence.EndBootDormGrace(pid);
|
||||
logger.LogInformation(
|
||||
"[joinresult] committed presence player={Player} room={RoomId}/{RoomName} instance={Instance} deferred={Deferred}",
|
||||
pid,
|
||||
@@ -71,6 +72,7 @@ public class MatchController(
|
||||
{
|
||||
presence.MarkActive(pid);
|
||||
presence.TouchRoom(pid);
|
||||
presence.EndBootDormGrace(pid);
|
||||
}
|
||||
logger.LogInformation(
|
||||
"[joinresult] player={Player} instance={Instance} OK ({Label})",
|
||||
@@ -80,7 +82,7 @@ public class MatchController(
|
||||
{
|
||||
await joinTimeouts.MarkFailedAsync(pid, instanceId, label);
|
||||
logger.LogWarning(
|
||||
"[joinresult] player={Player} instance={Instance} FAILED code={Code} ({Label}) — Photon-side error, check Photon AppId/region/auth",
|
||||
"[joinresult] player={Player} instance={Instance} FAILED code={Code} ({Label})",
|
||||
pid, instanceId, code, label);
|
||||
}
|
||||
return Ok();
|
||||
@@ -92,6 +94,22 @@ public class MatchController(
|
||||
var pid = this.CurrentPlayerId() ?? 0;
|
||||
if (pid == 0) return Unauthorized();
|
||||
|
||||
var pending = joinTimeouts.GetPending(pid);
|
||||
if (pending is { DeferPresenceCommit: true })
|
||||
{
|
||||
presence.MarkActive(pid);
|
||||
logger.LogInformation(
|
||||
"[matchmake-none] player={Player} has deferred pending room={Room} instance={Instance}; not committing presence",
|
||||
pid,
|
||||
pending.Value.TargetRoom.RoomId,
|
||||
pending.Value.TargetRoom.RoomInstanceId);
|
||||
return Ok(new MatchmakingResponseDto
|
||||
{
|
||||
ErrorCode = 0,
|
||||
RoomInstance = pending.Value.TargetRoom,
|
||||
});
|
||||
}
|
||||
|
||||
var current = presence.GetRoom(pid) ?? await BuildDormRoomInstanceAsync(pid);
|
||||
presence.SetRoom(pid, current);
|
||||
presence.MarkActive(pid);
|
||||
@@ -110,8 +128,22 @@ public class MatchController(
|
||||
var appId = config["Photon:AppId"] ?? string.Empty;
|
||||
var voiceAppId = config["Photon:VoiceAppId"] ?? string.Empty;
|
||||
var region = (config["Photon:CloudRegion"] ?? "us").ToLowerInvariant();
|
||||
var currentRoom = presence.GetRoom(pid);
|
||||
var permissions = BuildPhotonPermissionSeed();
|
||||
logger.LogInformation(
|
||||
"[photon-token] player={PlayerId} roomInstance={RoomInstanceId} permissions={PermissionCount}",
|
||||
pid, currentRoom?.RoomInstanceId ?? 0L, permissions.Length);
|
||||
return Ok(new Dictionary<string, object>
|
||||
{
|
||||
// 2023 deserializes this endpoint as ALIIIAGAPND before room
|
||||
// permissions initialization. If Permissions is missing/empty,
|
||||
// OMJKHJLFOCO falls into the persisted-role migration path that
|
||||
// currently NREs during first spawn.
|
||||
["RoomInstanceId"] = currentRoom?.RoomInstanceId ?? 0L,
|
||||
["PhotonAccessToken"] = string.Empty,
|
||||
["Permissions"] = permissions,
|
||||
|
||||
// Existing custom-auth/app-id shape kept for Photon auth callers.
|
||||
["ResultCode"] = 1,
|
||||
["Message"] = string.Empty,
|
||||
["UserId"] = pid.ToString(System.Globalization.CultureInfo.InvariantCulture),
|
||||
@@ -125,6 +157,30 @@ public class MatchController(
|
||||
});
|
||||
}
|
||||
|
||||
private static object[] BuildPhotonPermissionSeed()
|
||||
=>
|
||||
[
|
||||
BuildPhotonPermission(13, 30), // Can Use Maker Pen
|
||||
BuildPhotonPermission(20, 30), // Can Spawn Inventions
|
||||
BuildPhotonPermission(21, 30), // Can Spawn Consumables
|
||||
BuildPhotonPermission(22, 30), // Can Use Room Reset Button
|
||||
BuildPhotonPermission(23, 30), // Can Use Play Gizmos Toggle
|
||||
BuildPhotonPermission(13, 255), // Creator alias
|
||||
BuildPhotonPermission(20, 255),
|
||||
BuildPhotonPermission(21, 255),
|
||||
BuildPhotonPermission(22, 255),
|
||||
BuildPhotonPermission(23, 255),
|
||||
];
|
||||
|
||||
private static object BuildPhotonPermission(int permission, int role) => new
|
||||
{
|
||||
Permission = permission.ToString(System.Globalization.CultureInfo.InvariantCulture),
|
||||
Role = role,
|
||||
Override = true,
|
||||
Type = 0,
|
||||
Value = "true",
|
||||
};
|
||||
|
||||
[HttpPost("/matchmake/dorm")]
|
||||
public async Task<IActionResult> MatchmakeDorm()
|
||||
{
|
||||
@@ -132,11 +188,11 @@ public class MatchController(
|
||||
if (pid == 0) return Unauthorized();
|
||||
|
||||
var room = await BuildDormRoomInstanceAsync(pid);
|
||||
presence.SetRoom(pid, room);
|
||||
joinTimeouts.MarkPending(pid, room, deferPresenceCommit: true);
|
||||
presence.MarkActive(pid);
|
||||
await RecordVisitAsync(pid, room.RoomId);
|
||||
logger.LogInformation(
|
||||
"[matchmake-dorm] player={Player} room={Room} instance={Instance} photon={Photon}",
|
||||
"[matchmake-dorm] player={Player} room={Room} instance={Instance} photon={Photon} deferredPresence=True",
|
||||
pid, room.RoomId, room.RoomInstanceId, room.PhotonRoomId);
|
||||
return Ok(new MatchmakingResponseDto
|
||||
{
|
||||
|
||||
@@ -23,6 +23,7 @@ public class MatchPlayerController(
|
||||
NotificationService notifications,
|
||||
RoomService rooms,
|
||||
PrivateInstanceService privateInstances,
|
||||
JoinTimeoutService joinTimeouts,
|
||||
IConfiguration config,
|
||||
DorkNetDbContext db,
|
||||
ILogger<MatchPlayerController> log) : ControllerBase
|
||||
@@ -61,6 +62,8 @@ public class MatchPlayerController(
|
||||
var playerId = TryGetCurrentPlayerId();
|
||||
if (playerId != 0 && !string.IsNullOrWhiteSpace(loginLock))
|
||||
{
|
||||
presence.Clear(playerId);
|
||||
presence.BeginBootDormGrace(playerId);
|
||||
var replaced = presence.SetLock(playerId, loginLock);
|
||||
if (replaced)
|
||||
{
|
||||
@@ -276,8 +279,27 @@ public class MatchPlayerController(
|
||||
if (playerId == 0) return null;
|
||||
|
||||
var room = presence.GetRoom(playerId);
|
||||
var pending = joinTimeouts.GetPending(playerId);
|
||||
if (pending is { DeferPresenceCommit: true })
|
||||
{
|
||||
log.LogInformation(
|
||||
"[player-heartbeat] player={PlayerId} pending deferred room={RoomId} instance={InstanceId}; returning null until join result",
|
||||
playerId,
|
||||
pending.Value.TargetRoom.RoomId,
|
||||
pending.Value.TargetRoom.RoomInstanceId);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (room is null)
|
||||
{
|
||||
if (presence.IsBootDormGraceActive(playerId))
|
||||
{
|
||||
log.LogInformation(
|
||||
"[player-heartbeat] player={PlayerId} in boot dorm grace; returning null roomInstance",
|
||||
playerId);
|
||||
return null;
|
||||
}
|
||||
|
||||
// Boot-time race: the watch hits /player/heartbeat before
|
||||
// /goto/room/DormRoom has finished recording presence. The
|
||||
// watch's OnPresenceHeartbeatResponse compares
|
||||
@@ -434,7 +456,7 @@ public class MatchPlayerController(
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(room.CurrentDataBlobName)) return room.CurrentDataBlobName;
|
||||
|
||||
return $"room_{room.Id}_v1.dat";
|
||||
return RoomService.SyntheticDefaultRoomDataBlobName(room.Id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user