M Core/NosSmooth.Game/Data/Raids/Raid.cs => Core/NosSmooth.Game/Data/Raids/Raid.cs +1 -0
@@ 19,6 19,7 @@ public record Raid
RaidState State,
short MinimumLevel,
short MaximumLevel,
+ long? LeaderId,
GroupMember? Leader,
RaidProgress? Progress,
Monster? Boss,
M Core/NosSmooth.Game/PacketHandlers/Raids/RaidResponder.cs => Core/NosSmooth.Game/PacketHandlers/Raids/RaidResponder.cs +29 -16
@@ 41,31 41,42 @@ public class RaidResponder : IPacketResponder<RaidPacket>
public async Task<Result> Respond(PacketEventArgs<RaidPacket> 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<RaidPacket>
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
M Core/NosSmooth.Game/PacketHandlers/Raids/RdlstResponder.cs => Core/NosSmooth.Game/PacketHandlers/Raids/RdlstResponder.cs +20 -4
@@ 72,23 72,31 @@ public class RdlstResponder : IPacketResponder<RdlstPacket>, IPacketResponder<Rd
null,
null,
null,
+ null,
UpdateMembers(null)
),
raid =>
{
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 <leaderId>) 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<RdlstPacket>, IPacketResponder<Rd
null,
null,
null,
+ null,
UpdateMembers(null)
),
raid =>
{
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 <leaderId>) 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);
}