Skip to content

Commit

Permalink
Modify statemanager logic around leaving and closing rooms
Browse files Browse the repository at this point in the history
- Don't call to set room visibility to false on RoomBroken,
as the state manager will handle this and it can cause errors.
- Remove RemovedFromRedis flag in actor state and instead make trying
to remove a player from a room they aren't in a non-error
  • Loading branch information
SapiensAnatis committed Aug 11, 2023
1 parent d8adc35 commit b3b05b7
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 34 deletions.
49 changes: 23 additions & 26 deletions DragaliaAPI.Photon.Plugin/GluonPlugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -170,8 +170,6 @@ public override void OnLeave(ILeaveGameCallInfo info)
Event.RoomBroken,
new RoomBroken() { Reason = RoomBroken.RoomBrokenType.HostDisconnected }
);

this.SetRoomVisibility(info, false);
}

if (!this.actorState.Remove(info.ActorNr))
Expand All @@ -195,40 +193,39 @@ public override void OnLeave(ILeaveGameCallInfo info)
return;
}

if (
actor.TryGetViewerId(out int viewerId)
&& this.actorState.TryGetValue(info.ActorNr, out ActorState actorState)
&& !actorState.RemovedFromRedis
)
if (!actor.TryGetViewerId(out int viewerId))
{
this.logger.InfoFormat(
"Actor {0} with viewer ID {1} left game {2}",
info.ActorNr,
viewerId,
this.PluginHost.GameId
this.logger.WarnFormat(
"OnLeave: failed to acquire viewer ID of actor {0}",
info.ActorNr
);
return;
}

this.PostStateManagerRequest(
GameLeaveEndpoint,
new GameModifyRequest
{
GameName = this.PluginHost.GameId,
Player = new Player() { ViewerId = viewerId }
},
info,
true
);
this.logger.InfoFormat(
"Actor {0} with viewer ID {1} left game {2}",
info.ActorNr,
viewerId,
this.PluginHost.GameId
);

// For some strange reason on completing a quest this appears to be raised twice for each actor.
// Prevent duplicate requests by setting a flag.
actorState.RemovedFromRedis = true;
}
this.PostStateManagerRequest(
GameLeaveEndpoint,
new GameModifyRequest
{
GameName = this.PluginHost.GameId,
Player = new Player() { ViewerId = viewerId }
},
info,
true
);

if (this.roomState.MinGoToIngameState > 0)
{
int newMinGoToIngameState = this.PluginHost.GameActors
.Where(x => x.ActorNr != info.ActorNr)
.Select(x => x.Properties.GetIntOrDefault(ActorPropertyKeys.GoToIngameState))
.DefaultIfEmpty()
.Min();

this.roomState.MinGoToIngameState = newMinGoToIngameState;
Expand Down
2 changes: 0 additions & 2 deletions DragaliaAPI.Photon.Plugin/Models/ActorState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,5 @@ internal class ActorState
public bool Dead { get; set; }

public bool Ready { get; set; }

public bool RemovedFromRedis { get; set; }
}
}
28 changes: 22 additions & 6 deletions DragaliaAPI.Photon.StateManager/Controllers/EventController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using DragaliaAPI.Photon.Shared.Requests;
using DragaliaAPI.Photon.StateManager.Authentication;
using DragaliaAPI.Photon.StateManager.Models;
using MessagePack.Formatters;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
Expand Down Expand Up @@ -90,6 +91,17 @@ public async Task<IActionResult> GameJoin(GameModifyRequest request)
return this.Conflict();
}

if (game.Players.Any(x => x.ViewerId == request.Player.ViewerId))
{
this.logger.LogError(
"Player {@player} attempted to join game {@game} that they were already in.",
request.Player,
game
);

return this.Conflict();
}

game.Players.Add(request.Player);
await this.Games.UpdateAsync(game);

Expand Down Expand Up @@ -117,17 +129,17 @@ public async Task<IActionResult> GameLeave(GameModifyRequest request)
Player? toRemove = game.Players.FirstOrDefault(x => x.ViewerId == request.Player.ViewerId);
if (toRemove is null)
{
this.logger.LogError(
"Cannot remove player {@player} from game {@game} as they are not in it.",
this.logger.LogInformation(
"Player {@player} was not in game {@game}",
request.Player,
game
);

return this.BadRequest();
return this.Ok();
}

game.Players.Remove(toRemove);
if (game.Players.Count == 0)
if (game.Players.Count == 0 || request.Player.ActorNr == 1)
{
// Don't remove it just yet, as Photon will request that shortly
this.logger.LogDebug("Hiding game {@game}", game);
Expand Down Expand Up @@ -157,8 +169,12 @@ public async Task<IActionResult> GameClose(GameModifyRequest request)

if (game is null)
{
this.logger.LogError("Could not find game {name}", request.GameName);
return this.NotFound();
this.logger.LogInformation(
"Could not find game {name}. It may have already been closed.",
request.GameName
);

return this.Ok();
}

await this.Games.DeleteAsync(game);
Expand Down

0 comments on commit b3b05b7

Please sign in to comment.