feat : 맵 바운딩 박스 처리 / echo 패킷 구조 재 구성 / 더미 클라이언트 랜덤 이동 작업

This commit is contained in:
qornwh1
2026-03-04 14:51:43 +09:00
parent 241820846d
commit 053c5d23b9
16 changed files with 262 additions and 121 deletions

View File

@@ -21,7 +21,7 @@ public class ChannelManager
public void Initializer(int channelSize = 1)
{
for (int i = 0; i < channelSize; i++)
for (int i = 0; i <= channelSize; i++)
{
channels.Add(new Channel(i));
}
@@ -40,7 +40,7 @@ public class ChannelManager
public void AddUser(int channelId, long userId, Player player)
{
// 유저 추가
connectUsers[userId] = channelId;
connectUsers.Add(userId, channelId);
// 채널에 유저 추가
channels[channelId].AddUser(userId, player);
}

View File

@@ -1,4 +1,5 @@
using LiteNetLib;
using LiteNetLib.Utils;
using MMOserver.Game.Channel;
using MMOserver.Packet;
using ProtoBuf;
@@ -24,6 +25,54 @@ public class GameServer : ServerBase
};
}
protected override void HandleEcho(NetPeer peer, byte[] payload)
{
if (payload.Length < 4)
{
Log.Warning("[Server] Echo 페이로드 크기 오류 PeerId={Id} Length={Len}", peer.Id, payload.Length);
return;
}
// 세션에 넣지는 않는다.
NetDataReader reader = new NetDataReader(payload);
short code = reader.GetShort();
short bodyLength = reader.GetShort();
EchoPacket echoPacket = Serializer.Deserialize<EchoPacket>(payload.AsMemory(4));
Log.Debug("[Echo] : addr={Addr}, str={Str}", peer.Address, echoPacket.Str);
// Echo메시지는 순서보장 안함 HOL Blocking 제거
SendTo(peer, payload, DeliveryMethod.ReliableUnordered);
}
protected override void HandleAuth(NetPeer peer, byte[] payload)
{
AccTokenPacket accTokenPacket = Serializer.Deserialize<AccTokenPacket>(new ReadOnlyMemory<byte>(payload));
long hashKey = accTokenPacket.Token;
if (sessions.TryGetValue(hashKey, out NetPeer? existing))
{
// WiFi → LTE 전환 등 재연결: 이전 피어 교체
existing.Tag = null;
sessions.Remove(hashKey);
Log.Information("[Server] 재연결 HashKey={Key} Old={Old} New={New}", hashKey, existing.Id, peer.Id);
existing.Disconnect();
}
peer.Tag = new Session(hashKey, peer);
sessions[hashKey] = peer;
pendingPeers.Remove(peer.Id);
if (hashKey <= 1000)
{
// 더미 클라다.
ChannelManager cm = ChannelManager.Instance;
cm.AddUser(1, hashKey, new Player());
}
Log.Information("[Server] 인증 완료 HashKey={Key} PeerId={Id}", hashKey, peer.Id);
OnSessionConnected(peer, hashKey);
}
protected override void OnSessionConnected(NetPeer peer, long hashKey)
{
Log.Information("[GameServer] 세션 연결 HashKey={Key} PeerId={Id}", hashKey, peer.Id);

View File

@@ -30,4 +30,8 @@
<ProjectReference Include="..\ServerLib\ServerLib.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="RestApi\" />
</ItemGroup>
</Project>

View File

@@ -4,6 +4,22 @@ using ProtoBuf;
namespace MMOserver.Packet;
// ============================================================
// 에코용
// ============================================================
// ECHO
[ProtoContract]
public class EchoPacket
{
[ProtoMember(1)]
public string Str
{
get;
set;
}
}
// ============================================================
// 공통 타입
// ============================================================

View File

@@ -2,8 +2,10 @@ namespace MMOserver.Packet;
public enum PacketCode : ushort
{
ECHO = 0,
// 초기 클라이언트 시작시 jwt토큰 받아옴
ACC_TOKEN,
ACC_TOKEN = 1,
// 내 정보 로드 (서버 -> 클라)
LOAD_GAME,

View File

@@ -43,7 +43,7 @@ namespace ServerLib.Packet
// 헤더에 명시된 size와 실제 데이터 길이 검증
int actualPayloadLen = data.Length - 4;
if (size > actualPayloadLen)
if (size != actualPayloadLen)
{
Log.Warning("[PacketSerializer] 페이로드 크기 불일치 HeaderSize={Size} ActualSize={Actual}", size, actualPayloadLen);
return (0, 0, null)!;

View File

@@ -30,7 +30,7 @@ public abstract class ServerBase : INetEventListener
protected NetManager netManager = null!;
// 인증 전 대기 피어 (peer.Id → NetPeer)
private readonly Dictionary<int, NetPeer> pendingPeers = new();
protected readonly Dictionary<int, NetPeer> pendingPeers = new();
// 인증된 세션 (hashKey → NetPeer) 재연결 조회용
// peer → hashKey 역방향은 peer.Tag as Session 으로 대체
@@ -202,52 +202,11 @@ public abstract class ServerBase : INetEventListener
// Echo 서버 테스트
private void HandleEcho(NetPeer peer, byte[] payload)
{
if (payload.Length < 4)
{
Log.Warning("[Server] Echo 페이로드 크기 오류 PeerId={Id} Length={Len}", peer.Id, payload.Length);
return;
}
// 세션에 넣지는 않는다.
NetDataReader reader = new NetDataReader(payload);
short code = reader.GetShort();
short bodyLength = reader.GetShort();
Log.Debug("[Echo] : addr={Addr}, str={Str}", peer.Address, reader.GetString());
// Echo메시지는 순서보장 안함 HOL Blocking 제거
SendTo(peer, payload, DeliveryMethod.ReliableUnordered);
}
protected abstract void HandleEcho(NetPeer peer, byte[] payload);
// ─── Auth 처리 (내부) ────────────────────────────────────────────────
private void HandleAuth(NetPeer peer, byte[] payload)
{
if (payload.Length < sizeof(long))
{
Log.Warning("[Server] Auth 페이로드 크기 오류 PeerId={Id} Length={Len}", peer.Id, payload.Length);
peer.Disconnect();
return;
}
long hashKey = BitConverter.ToInt64(payload, 0);
if (sessions.TryGetValue(hashKey, out NetPeer? existing))
{
// WiFi → LTE 전환 등 재연결: 이전 피어 교체
existing.Tag = null;
sessions.Remove(hashKey);
Log.Information("[Server] 재연결 HashKey={Key} Old={Old} New={New}", hashKey, existing.Id, peer.Id);
existing.Disconnect();
}
peer.Tag = new Session(hashKey, peer);
sessions[hashKey] = peer;
pendingPeers.Remove(peer.Id);
Log.Information("[Server] 인증 완료 HashKey={Key} PeerId={Id}", hashKey, peer.Id);
OnSessionConnected(peer, hashKey);
}
protected abstract void HandleAuth(NetPeer peer, byte[] payload);
// ─── 전송 헬퍼 ───────────────────────────────────────────────────────