168 lines
4.5 KiB
C#
168 lines
4.5 KiB
C#
using System.Diagnostics;
|
||
using ClientTester.Packet;
|
||
using LiteNetLib;
|
||
using LiteNetLib.Utils;
|
||
using Serilog;
|
||
|
||
namespace ClientTester.DummyService;
|
||
|
||
public class DummyClients
|
||
{
|
||
private NetManager manager;
|
||
private EventBasedNetListener listener;
|
||
private NetDataWriter? writer;
|
||
public NetPeer? peer;
|
||
public long clientId; // 일단 이게 hashKey가 됨 => 0 ~ 1000번까지는 더미용응로 뺴둠
|
||
|
||
// info
|
||
private Vector3 position = new Vector3();
|
||
private int rotY = 0;
|
||
private float moveSpeed = 3.5f;
|
||
private float distance = 0.0f;
|
||
private float preTime = 0.0f;
|
||
|
||
// 이동 계산용
|
||
private readonly Stopwatch moveClock = Stopwatch.StartNew();
|
||
private float posX = 0f;
|
||
private float posZ = 0f;
|
||
private float dirX = 0f;
|
||
private float dirZ = 0f;
|
||
|
||
// 통계
|
||
public int SentCount
|
||
{
|
||
set;
|
||
get;
|
||
}
|
||
|
||
public int ReceivedCount
|
||
{
|
||
set;
|
||
get;
|
||
}
|
||
|
||
public int RttCount
|
||
{
|
||
set;
|
||
get;
|
||
}
|
||
|
||
public DummyClients(long clientId, string ip, int port, string key)
|
||
{
|
||
this.clientId = clientId;
|
||
listener = new EventBasedNetListener();
|
||
manager = new NetManager(listener);
|
||
writer = new NetDataWriter();
|
||
|
||
listener.PeerConnectedEvent += netPeer =>
|
||
{
|
||
peer = netPeer;
|
||
Log.Information("[Client {ClientId:00}] 연결됨", this.clientId);
|
||
|
||
// clientID가 토큰의 hashKey라고 가정함
|
||
AccTokenPacket recvTokenPacket = new AccTokenPacket();
|
||
recvTokenPacket.Token = clientId;
|
||
|
||
byte[] data = PacketSerializer.Serialize((ushort)PacketCode.ACC_TOKEN, recvTokenPacket);
|
||
writer.Put(data);
|
||
peer.Send(writer, DeliveryMethod.ReliableOrdered);
|
||
writer.Reset();
|
||
};
|
||
|
||
listener.NetworkReceiveEvent += (peer, reader, channel, deliveryMethod) =>
|
||
{
|
||
short code = reader.GetShort();
|
||
short bodyLength = reader.GetShort();
|
||
string? msg = reader.GetString();
|
||
|
||
if (msg != null)
|
||
{
|
||
RttCount++;
|
||
}
|
||
|
||
ReceivedCount++;
|
||
reader.Recycle();
|
||
};
|
||
|
||
listener.PeerDisconnectedEvent += (peer, info) =>
|
||
{
|
||
Log.Warning("[Client {ClientId:00}] 연결 끊김: {Reason}", this.clientId, info.Reason);
|
||
this.peer = null;
|
||
};
|
||
|
||
manager.Start();
|
||
manager.Connect(ip, port, key);
|
||
}
|
||
|
||
public void UpdateDummy()
|
||
{
|
||
// 델타 타임 계산 (초 단위)
|
||
float now = (float)moveClock.Elapsed.TotalSeconds;
|
||
float delta = preTime > 0f ? now - preTime : 0.1f;
|
||
preTime = now;
|
||
|
||
// 남은 거리가 없으면 새 방향·목표 거리 설정
|
||
if (distance <= 0f)
|
||
{
|
||
// 현재 각도에서 -30~+30도 범위로 회전
|
||
rotY = (rotY + Random.Shared.Next(-30, 31) + 360) % 360;
|
||
float rad = rotY * MathF.PI / 180f;
|
||
dirX = MathF.Sin(rad);
|
||
dirZ = MathF.Cos(rad);
|
||
|
||
// 3초~12초에 도달할 수 있는 거리 = moveSpeed × 랜덤 초
|
||
float seconds = 3f + (float)Random.Shared.NextDouble() * 9f;
|
||
distance = moveSpeed * seconds;
|
||
}
|
||
|
||
// 이번 틱 이동량 (남은 거리 초과 방지)
|
||
float step = MathF.Min(moveSpeed * delta, distance);
|
||
posX += dirX * step;
|
||
posZ += dirZ * step;
|
||
distance -= step;
|
||
|
||
// 정수 Vector3 갱신
|
||
position.X = (int)MathF.Round(posX);
|
||
position.Z = (int)MathF.Round(posZ);
|
||
}
|
||
|
||
public void SendTransform()
|
||
{
|
||
if (peer == null || writer == null)
|
||
{
|
||
return;
|
||
}
|
||
|
||
UpdateDummy();
|
||
TransformPlayerPacket transformPlayerPacket = new TransformPlayerPacket
|
||
{
|
||
PlayerId = (int)clientId,
|
||
RotY = rotY,
|
||
Position = new Packet.Vector3
|
||
{
|
||
X = position.X,
|
||
Y = 0, // 높이는 버린다.
|
||
Z = position.Z
|
||
}
|
||
};
|
||
|
||
// Protobuf 직렬화 + 헤더 조립
|
||
byte[] data = PacketSerializer.Serialize((ushort)PacketCode.TRANSFORM_PLAYER, transformPlayerPacket);
|
||
writer.Put(data);
|
||
// 이동은 손실 감수함
|
||
peer.Send(writer, DeliveryMethod.Unreliable);
|
||
SentCount++;
|
||
writer.Reset();
|
||
}
|
||
|
||
public void PollEvents()
|
||
{
|
||
manager.PollEvents();
|
||
}
|
||
|
||
public void Stop()
|
||
{
|
||
manager.Stop();
|
||
}
|
||
}
|