namespace Server
{
public abstract class Packet
{
public ushort size;
public ushort packetId;
public abstract ArraySegment<byte> Write();
public abstract void Read(ArraySegment<byte> s);
}
class PlayerInfoReq : Packet
{
public long playerId;
public string name;
public struct SkillInfo
{
public int id;
public short level;
public float duration;
public bool Write(Span<byte> s, ref ushort count)
{
bool success = true;
success &= BitConverter.TryWriteBytes(s.Slice(count, s.Length - count), id);
count += sizeof(int);
success &= BitConverter.TryWriteBytes(s.Slice(count, s.Length - count), level);
count += sizeof(short);
success &= BitConverter.TryWriteBytes(s.Slice(count, s.Length - count), duration);
count += sizeof(float);
return success;
}
public void Read(ReadOnlySpan<byte> s, ref ushort count)
{
id = BitConverter.ToInt32(s.Slice(count, s.Length - count));
count += sizeof(int);
level = BitConverter.ToInt16(s.Slice(count, s.Length - count));
count += sizeof(short);
duration = BitConverter.ToSingle(s.Slice(count, s.Length - count));
count += sizeof(float);
}
}
public List<SkillInfo> skills = new List<SkillInfo>();
public PlayerInfoReq()
{
this.packetId = (ushort)PacketID.PlayerInfoReq;
}
public override void Read(ArraySegment<byte> segment)
{
ushort count = 0;
ReadOnlySpan<byte> s = new ReadOnlySpan<byte>(segment.Array, segment.Offset + count, segment.Count);
//ushort size = BitConverter.ToUInt16(s.Array, s.Offset);
count += sizeof(ushort);
//ushort id = BitConverter.ToUInt16(s.Array, s.Offset + count);
count += sizeof(ushort);
this.playerId = BitConverter.ToInt64(s.Slice(count, s.Length - count));
count += sizeof(long);
// string
ushort nameLen = BitConverter.ToUInt16(s.Slice(count, s.Length - count));
count += sizeof(ushort);
this.name = Encoding.Unicode.GetString(s.Slice(count, nameLen));
count += nameLen;
// skill list
skills.Clear();
ushort skillLen = BitConverter.ToUInt16(s.Slice(count, s.Length - count));
count += sizeof(ushort);
for (int i = 0; i < skillLen; i++)
{
SkillInfo skill = new SkillInfo();
skill.Read(s, ref count);
skills.Add(skill);
}
}
public override ArraySegment<byte> Write()
{
ArraySegment<byte> segment = SendBufferHelper.Open(4096);
ushort count = 0;
bool success = true;
Span<byte> s = new Span<byte>(segment.Array, segment.Offset + count, segment.Count - count);
//success &= BitConverter.TryWriteBytes(new Span<byte>(s.Array, s.Offset, s.Count), packet.size);
count += sizeof(ushort);
success &= BitConverter.TryWriteBytes(s.Slice(count, s.Length - count), this.packetId); // s๊ฐ ๋ณํ๋ ๊ฒ์ด ์๋๋ผ Sliceํ์ฌ Span์ ๋ง๋ค์ด์ ๋ฃ์ด์ค
count += sizeof(ushort);
success &= BitConverter.TryWriteBytes(s.Slice(count, s.Length - count), this.playerId);
count += sizeof(long);
//string
//ushort nameLen = (ushort)Encoding.Unicode.GetByteCount(this.name);
//success &= BitConverter.TryWriteBytes(s.Slice(count, s.Length - count), nameLen);
//count += sizeof(ushort);
//Array.Copy(Encoding.Unicode.GetBytes(this.name), 0, segment.Array, count, nameLen);
//count += nameLen;
ushort nameLen = (ushort)Encoding.Unicode.GetBytes(this.name, 0, this.name.Length, segment.Array, segment.Offset + count + sizeof(ushort));
success &= BitConverter.TryWriteBytes(s.Slice(count, s.Length - count), nameLen);
count += sizeof(ushort);
count += nameLen;
// skill list
success &= BitConverter.TryWriteBytes(s.Slice(count, s.Length - count), (ushort)skills.Count);
count += sizeof(ushort);
foreach (SkillInfo skill in skills)
success &= skill.Write(s, ref count);
success &= BitConverter.TryWriteBytes(s, count);
if (success == false)
return null;
return SendBufferHelper.Close(count);
}
}
public enum PacketID
{
PlayerInfoReq = 1,
PlayerInfoOk = 2,
}
class ClientSession : PacketSession
{
public override void OnConnected(EndPoint endPoint)
{
Console.WriteLine($"OnConnected : {endPoint}");
//Packet packet = new Packet() { size = 100, packetId = 10 };
//ArraySegment<byte> openSegment = SendBufferHelper.Open(4096);
//byte[] buffer = BitConverter.GetBytes(packet.size);
//byte[] buffer2 = BitConverter.GetBytes(packet.packetId);
//Array.Copy(buffer, 0, openSegment.Array, openSegment.Offset, buffer.Length);
//Array.Copy(buffer2, 0, openSegment.Array, openSegment.Offset + buffer.Length, buffer2.Length);
//ArraySegment<byte> sendBuff = SendBufferHelper.Close(buffer.Length + buffer2.Length);
// 100๋ช
// 1 -> ์ด๋ํจํท์ด 100๋ช
// 100 -> ์ด๋ํจํท์ด 100 * 100 = 1๋ง
//Send(sendBuff);
Thread.Sleep(5000);
Disconnect();
}
public override void OnRecvPacket(ArraySegment<byte> buffer)
{
ushort count = 0;
ushort size = BitConverter.ToUInt16(buffer.Array, buffer.Offset);
count += 2;
ushort id = BitConverter.ToUInt16(buffer.Array, buffer.Offset + count);
count += 2;
switch ((PacketID)id)
{
case PacketID.PlayerInfoReq:
{
PlayerInfoReq p = new PlayerInfoReq();
p.Read(buffer);
Console.WriteLine($"PlayerInfoReq {p.playerId} {p.name}");
foreach (PlayerInfoReq.SkillInfo skill in p.skills)
{
Console.WriteLine($"skill ({skill.id}) ({skill.level}) ({skill.duration})");
}
}
break;
}
Console.WriteLine($"RecvPacketId {id}, Size {size}");
}
public override void OnDisconnected(EndPoint endPoint)
{
Console.WriteLine($"OnDisconnected : {endPoint}");
}
public override void OnSend(int numOfBytes)
{
Console.WriteLine($"Transferred bytes : {numOfBytes}");
}
}
}