public override void OnReceivePacket(ArraySegment <byte> buffer)
        {
            ushort count = 0;

            // 무슨 패킷인지는 파악해야 하니 헤더 부분은 직접 읽어야 한다.
            ushort size = BitConverter.ToUInt16(buffer.Array, buffer.Offset);

            count += sizeof(ushort);
            ushort id = BitConverter.ToUInt16(buffer.Array, buffer.Offset + count);

            count += sizeof(ushort);

            switch ((PacketID)id)
            {
            case PacketID.PlayerInfoReq:
                PlayerInfoReq packet = new PlayerInfoReq();
                packet.DeSerialize(buffer);
                Console.WriteLine($"Player Info Required : {packet.playerId} ({packet.playerName})");

                foreach (PlayerInfoReq.SkillInfo skill in packet.skills)
                {
                    Console.WriteLine($"Skill [{skill.id}] : {skill.level} 레벨 (지속시간: {skill.duration}초)");
                }
                break;
            }

            Console.WriteLine($"[Packet Received] PacketID : {id}, Size : {size}");
        }
        public override void OnReceivePacket(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)
            {
            // * 수정된 부분
            // 이제 패킷ID에 맞는 클래스(PlayerInfoReq)를 생성하고,
            // 받은 버퍼를 DeSerialize()에 인자로 넘겨 클래스 정보를 역직렬화하여 채운다.
            case PacketID.PlayerInfoReq:
                PlayerInfoReq packet = new PlayerInfoReq();
                packet.DeSerialize(buffer);
                Console.WriteLine($"Player Info Required : {packet.playerId}");
                break;
            }

            Console.WriteLine($"[Packet Received] PacketID : {id}, Size : {size}");
        }