feat : 보스전 채널 생성, 파티 함께 채널 이동 구현
This commit is contained in:
@@ -22,6 +22,7 @@ public class GameServer : ServerBase
|
||||
packetHandlers = new Dictionary<ushort, Action<NetPeer, int, byte[]>>
|
||||
{
|
||||
[(ushort)PacketCode.INTO_CHANNEL] = OnIntoChannel,
|
||||
[(ushort)PacketCode.INTO_CHANNEL_PARTY] = OnIntoChannelParty,
|
||||
[(ushort)PacketCode.EXIT_CHANNEL] = OnExitChannel,
|
||||
[(ushort)PacketCode.TRANSFORM_PLAYER] = OnTransformPlayer,
|
||||
[(ushort)PacketCode.ACTION_PLAYER] = OnActionPlayer,
|
||||
@@ -208,7 +209,7 @@ public class GameServer : ServerBase
|
||||
private void SendLoadChannelPacket(NetPeer peer, int hashKey)
|
||||
{
|
||||
LoadChannelPacket loadChannelPacket = new LoadChannelPacket();
|
||||
foreach (Channel.Channel channel in ChannelManager.Instance.GetChannels())
|
||||
foreach (Channel.Channel channel in ChannelManager.Instance.GetChannels().Values)
|
||||
{
|
||||
if (channel.ChannelId <= 0)
|
||||
{
|
||||
@@ -376,13 +377,34 @@ public class GameServer : ServerBase
|
||||
IntoChannelPacket packet = Serializer.Deserialize<IntoChannelPacket>(new ReadOnlyMemory<byte>(payload));
|
||||
|
||||
ChannelManager cm = ChannelManager.Instance;
|
||||
Channel.Channel channel = cm.GetChannel(packet.ChannelId);
|
||||
|
||||
// 이전에 다른 채널에 있었는지 체크
|
||||
int preChannelId = cm.HasUser(hashKey);
|
||||
if (preChannelId >= 0)
|
||||
{
|
||||
// 제거 전에 채널/플레이어 정보 저장 (브로드캐스트에 필요)
|
||||
Player? player = cm.GetChannel(preChannelId).GetPlayer(hashKey);
|
||||
|
||||
// 파티 자동 탈퇴
|
||||
HandlePartyLeaveOnExit(preChannelId, hashKey);
|
||||
|
||||
cm.RemoveUser(hashKey);
|
||||
Log.Debug("[GameServer] EXIT_CHANNEL HashKey={Key} PlayerId={PlayerId}", hashKey, preChannelId);
|
||||
|
||||
// 같은 채널 유저들에게 나갔다고 알림
|
||||
if (player != null)
|
||||
{
|
||||
SendExitChannelPacket(peer, hashKey, preChannelId, player);
|
||||
}
|
||||
}
|
||||
|
||||
Channel.Channel newChannel = cm.GetChannel(packet.ChannelId);
|
||||
|
||||
// 최대 인원 체크
|
||||
if (channel.UserCount >= channel.UserCountMax)
|
||||
if (newChannel.UserCount >= newChannel.UserCountMax)
|
||||
{
|
||||
Log.Warning("[GameServer] INTO_CHANNEL 채널 인원 초과 HashKey={Key} ChannelId={ChannelId} UserCount={Count}/{Max}",
|
||||
hashKey, packet.ChannelId, channel.UserCount, channel.UserCountMax);
|
||||
hashKey, packet.ChannelId, newChannel.UserCount, newChannel.UserCountMax);
|
||||
byte[] full = PacketSerializer.Serialize<IntoChannelPacket>((ushort)PacketCode.INTO_CHANNEL,
|
||||
new IntoChannelPacket { ChannelId = -1 });
|
||||
SendTo(peer, full);
|
||||
@@ -407,6 +429,110 @@ public class GameServer : ServerBase
|
||||
SendLoadGame(peer, hashKey);
|
||||
}
|
||||
|
||||
private void OnIntoChannelParty(NetPeer peer, int hashKey, byte[] payload)
|
||||
{
|
||||
IntoChannelPartyPacket packet = Serializer.Deserialize<IntoChannelPartyPacket>(new ReadOnlyMemory<byte>(payload));
|
||||
|
||||
ChannelManager cm = ChannelManager.Instance;
|
||||
|
||||
int preChannelId = cm.HasUser(hashKey);
|
||||
Channel.Channel preChannel = cm.GetChannel(preChannelId);
|
||||
Channel.Channel newChannel = cm.GetChannel(packet.ChannelId);
|
||||
PartyInfo? preParty = preChannel.GetPartyManager().GetParty(packet.PartyId);
|
||||
|
||||
// 이전에 다른 채널에 있었는지 체크 / 파티이동은 이미 접속한 상태여야 한다.
|
||||
if (preChannelId < 0 || preParty == null)
|
||||
{
|
||||
Log.Warning("[GameServer] INTO_CHANNEL_PARTY 해당 파티 없음");
|
||||
return;
|
||||
}
|
||||
|
||||
// 새로운 파티를 복사한다
|
||||
PartyInfo newParty = new PartyInfo();
|
||||
newParty.DeepCopySemi(preParty);
|
||||
|
||||
// 최대 인원 체크
|
||||
if (newChannel.UserCount + newParty.PartyMemberIds.Count >= newChannel.UserCountMax)
|
||||
{
|
||||
Log.Warning("[GameServer] INTO_CHANNEL_PARTY 채널 인원 초과 HashKey={Key} ChannelId={ChannelId} UserCount={Count}/{Max}",
|
||||
hashKey, packet.ChannelId, newChannel.UserCount, newChannel.UserCountMax);
|
||||
byte[] full = PacketSerializer.Serialize<IntoChannelPacket>((ushort)PacketCode.INTO_CHANNEL,
|
||||
new IntoChannelPacket { ChannelId = -1 });
|
||||
SendTo(peer, full);
|
||||
return;
|
||||
}
|
||||
|
||||
// 기존 채널에서 제거 + 기존 채널 유저들에게 나감 알림
|
||||
foreach (int memberId in preParty.PartyMemberIds)
|
||||
{
|
||||
Player? player = preChannel.GetPlayer(memberId);
|
||||
if (player != null)
|
||||
{
|
||||
UpdateChannelUserPacket exitNotify = new UpdateChannelUserPacket
|
||||
{
|
||||
Players = ToPlayerInfo(player),
|
||||
IsAdd = false
|
||||
};
|
||||
byte[] exitData = PacketSerializer.Serialize<UpdateChannelUserPacket>((ushort)PacketCode.UPDATE_CHANNEL_USER, exitNotify);
|
||||
BroadcastToChannel(preChannelId, exitData);
|
||||
|
||||
// 이전 채널에서 제거
|
||||
preChannel.RemoveUser(memberId);
|
||||
|
||||
// 현재 존재하는 파티원만 추가한다.
|
||||
newParty.PartyMemberIds.Add(memberId);
|
||||
}
|
||||
}
|
||||
|
||||
// 이전채널에서 파티를 지운다.
|
||||
preChannel.GetPartyManager().DeleteParty(hashKey, packet.PartyId, out preParty);
|
||||
UpdatePartyPacket notify = new UpdatePartyPacket
|
||||
{
|
||||
PartyId = preParty!.PartyId,
|
||||
Type = PartyUpdateType.DELETE,
|
||||
LeaderId = preParty.LeaderId,
|
||||
};
|
||||
BroadcastToChannel(preChannelId,
|
||||
PacketSerializer.Serialize<UpdatePartyPacket>((ushort)PacketCode.UPDATE_PARTY, notify)); // 채널 전체 파티 목록 갱신
|
||||
|
||||
// 새로운 채널에 파티원 넣기
|
||||
foreach (int memberId in newParty.PartyMemberIds)
|
||||
{
|
||||
sessions.TryGetValue(memberId, out NetPeer? memberPeer);
|
||||
|
||||
if (memberPeer != null)
|
||||
{
|
||||
// 새 채널에 유저 추가
|
||||
Player newPlayer = new Player
|
||||
{
|
||||
HashKey = memberId,
|
||||
PlayerId = memberId,
|
||||
Nickname = memberId.ToString()
|
||||
};
|
||||
cm.AddUser(packet.ChannelId, memberId, newPlayer, memberPeer);
|
||||
|
||||
// 접속된 모든 유저 정보 전달
|
||||
SendIntoChannelPacket(memberPeer, memberId);
|
||||
|
||||
// 내 정보 전달
|
||||
SendLoadGame(memberPeer, memberId);
|
||||
}
|
||||
}
|
||||
|
||||
// 새로운 채널에 파티를 추가한다.
|
||||
newChannel.GetPartyManager().CreateParty(newParty.LeaderId, newParty.PartyName, out newParty, newParty.PartyMemberIds);
|
||||
|
||||
// 새 채널 기존 유저들에게 파티 생성 알림
|
||||
UpdatePartyPacket createNotify = new UpdatePartyPacket
|
||||
{
|
||||
PartyId = newParty.PartyId,
|
||||
Type = PartyUpdateType.CREATE,
|
||||
LeaderId = newParty.LeaderId,
|
||||
PartyName = newParty.PartyName,
|
||||
};
|
||||
BroadcastToChannel(packet.ChannelId, PacketSerializer.Serialize<UpdatePartyPacket>((ushort)PacketCode.UPDATE_PARTY, createNotify));
|
||||
}
|
||||
|
||||
private void OnExitChannel(NetPeer peer, int hashKey, byte[] payload)
|
||||
{
|
||||
ExitChannelPacket packet = Serializer.Deserialize<ExitChannelPacket>(new ReadOnlyMemory<byte>(payload));
|
||||
|
||||
Reference in New Issue
Block a user