From 324e7e358fed12b8d00ce9351dfff486edd542bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franti=C5=A1ek=20Boh=C3=A1=C4=8Dek?= Date: Sun, 15 Jan 2023 21:53:57 +0100 Subject: [PATCH] fix(game): handle raid leader before rdlst (raid initialized) correctly --- Core/NosSmooth.Game/Data/Raids/Raid.cs | 1 + .../PacketHandlers/Raids/RaidResponder.cs | 45 ++++++++++++------- .../PacketHandlers/Raids/RdlstResponder.cs | 24 ++++++++-- 3 files changed, 50 insertions(+), 20 deletions(-) diff --git a/Core/NosSmooth.Game/Data/Raids/Raid.cs b/Core/NosSmooth.Game/Data/Raids/Raid.cs index 61a3371..c5e5eb1 100644 --- a/Core/NosSmooth.Game/Data/Raids/Raid.cs +++ b/Core/NosSmooth.Game/Data/Raids/Raid.cs @@ -19,6 +19,7 @@ public record Raid RaidState State, short MinimumLevel, short MaximumLevel, + long? LeaderId, GroupMember? Leader, RaidProgress? Progress, Monster? Boss, diff --git a/Core/NosSmooth.Game/PacketHandlers/Raids/RaidResponder.cs b/Core/NosSmooth.Game/PacketHandlers/Raids/RaidResponder.cs index 8944682..d90ef97 100644 --- a/Core/NosSmooth.Game/PacketHandlers/Raids/RaidResponder.cs +++ b/Core/NosSmooth.Game/PacketHandlers/Raids/RaidResponder.cs @@ -41,31 +41,42 @@ public class RaidResponder : IPacketResponder public async Task Respond(PacketEventArgs packetArgs, CancellationToken ct = default) { var packet = packetArgs.Packet; - if (packet.Type is not(RaidPacketType.Leader or RaidPacketType.ListMembers or RaidPacketType.PlayerHealths or RaidPacketType.JoinLeave)) + if (packet.Type is not(RaidPacketType.Leader or RaidPacketType.ListMembers or RaidPacketType.PlayerHealths)) { return Result.FromSuccess(); } Raid? prevRaid = null; - var currentRaid = await _game.UpdateRaidAsync + var currentRaid = await _game.CreateOrUpdateRaidAsync ( + () => + { + if (packet.Type == RaidPacketType.Leader) + { // leader was sent before raid was created. That is a problem, + // we have to create the raid without correctly initialized members here. + // a better way to handle this could be by creating some kind of a cache. + return new Raid + ( + (RaidType)(-1), + (RaidState)(-1), + -1, + -1, + packet.LeaderId, + null, + null, + null, + null, + null + ); + } + + return null; + }, raid => { prevRaid = raid; switch (packet.Type) { - case RaidPacketType.JoinLeave: - if (packet.JoinLeaveType is not null && packet.JoinLeaveType == RaidJoinLeaveType.PlayerLeft) - { // the player has left. - prevRaid = raid with - { - State = RaidState.Left - }; - - return null; - } - - return raid; case RaidPacketType.Leader: if (packet.LeaderId is null) { // set the raid to null. @@ -74,12 +85,14 @@ public class RaidResponder : IPacketResponder return raid with { - Leader = raid.Members?.FirstOrDefault(x => x.PlayerId == packet.LeaderId.Value) + Leader = raid.Members?.FirstOrDefault(x => x.PlayerId == packet.LeaderId.Value), + LeaderId = packet.LeaderId }; case RaidPacketType.ListMembers: return raid with { - Members = raid.Members?.Where(x => packet.ListMembersPlayerIds?.Contains(x.PlayerId) ?? true).ToList() + Members = raid.Members?.Where + (x => packet.ListMembersPlayerIds?.Contains(x.PlayerId) ?? true).ToList() }; case RaidPacketType.PlayerHealths: // update healths diff --git a/Core/NosSmooth.Game/PacketHandlers/Raids/RdlstResponder.cs b/Core/NosSmooth.Game/PacketHandlers/Raids/RdlstResponder.cs index 67790c2..d70c74f 100644 --- a/Core/NosSmooth.Game/PacketHandlers/Raids/RdlstResponder.cs +++ b/Core/NosSmooth.Game/PacketHandlers/Raids/RdlstResponder.cs @@ -72,23 +72,31 @@ public class RdlstResponder : IPacketResponder, IPacketResponder { prevRaid = raid; + var members = UpdateMembers(raid.Members); + var leader = members.FirstOrDefault(x => x.PlayerId == raid.LeaderId); return raid with { Type = packet.RaidType, MinimumLevel = packet.MinimumLevel, MaximumLevel = packet.MaximumLevel, - Members = UpdateMembers(raid.Members), + Members = members, + Leader = leader, + State = raid.State == (RaidState)(-1) ? RaidState.Waiting : raid.State }; }, ct: ct ); - if (prevRaid is null && currentRaid is not null) + // State is equal to -1 in case Leader (raid 2 ) was sent BEFORE rdlst. + // Rdlst is the packet that initializes the raid, but in this case we have to make an exception + // and initialize it from raid packet. That is because the leader won't be sent again. + if ((prevRaid is null || prevRaid?.State == (RaidState)(-1)) && currentRaid is not null) { return await _eventDispatcher.DispatchEvent(new RaidJoinedEvent(currentRaid), ct); } @@ -135,23 +143,31 @@ public class RdlstResponder : IPacketResponder, IPacketResponder { prevRaid = raid; + var members = UpdateMembers(raid.Members); + var leader = members.FirstOrDefault(x => x.PlayerId == raid.LeaderId); return raid with { Type = packet.RaidType, MinimumLevel = packet.MinimumLevel, MaximumLevel = packet.MaximumLevel, - Members = UpdateMembers(raid.Members), + Members = members, + Leader = leader, + State = raid.State == (RaidState)(-1) ? RaidState.Waiting : raid.State }; }, ct: ct ); - if (prevRaid is null && currentRaid is not null) + // State is equal to -1 in case Leader (raid 2 ) was sent BEFORE rdlst. + // Rdlst is the packet that initializes the raid, but in this case we have to make an exception + // and initialize it from raid packet. That is because the leader won't be sent again. + if ((prevRaid is null || prevRaid?.State == (RaidState)(-1)) && currentRaid is not null) { return await _eventDispatcher.DispatchEvent(new RaidJoinedEvent(currentRaid), ct); } -- 2.48.1