(C#) Packet Generator [1]
포스트
취소

(C#) Packet Generator [1]

패킷을 자동화하는 코드를 만들어본다.

💻 코드

코드 삭제

패킷 클래스르 따로 만들어서 자동화시킬 것이기 때문에 다음 코드는 삭제하고 에러가 나는 부분은 적절히 수정해준다.

1
2
3
4
5
6
7
8
9
10
11
12
13
public abstract class Packet
{
    public ushort size;
    public ushort packetId;

    public abstract ArraySegment<byte> Wirte();
    public abstract void Read(ArraySegment<byte> s);
}

public PlayerInfoReq()
{
    this.packetId = (ushort)PacketID.PlayerInfoReq;
}

PDL.xml 생성

공통적으로 사용할 패킷 변수명과 이름을 xml로 생성한다.

1
2
3
4
5
6
7
8
9
10
11
<PDL>
	<packet name="PlayerInfoReq">
		<long name="playerId"/>
		<string name="name"/>
		<list name="skill">
			<int name="id"/>
			<short name="level"/>
			<float name="duration"/>
		</list>
	</packet>
</PDL>

패킷 자동화 코드

PacketGenerator 클래스를 생성하고 xml을 잘 불러 오는지 테스트한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
namespace PacketGenerator
{
    class Program
    {
        static void Main(string[] args)
        {
            XmlReaderSettings settings = new XmlReaderSettings()
            {
                IgnoreComments = true,      // 주석 무시
                IgnoreWhitespace = true     // 스페이스바 무시
            };

            // 에러가 날 경우 PDL.xml 파일을 현재 경로에서 \bin\Debug\net6.0으로 이동하여 복붙하기
            XmlReader r = XmlReader.Create("PDL.xml", settings);
            {
                // xml에 기본적으로 들어가는 값을 무시 
                r.MoveToContent();

                // 한줄씩 읽기
                while(r.Read())
                {
                    if (r.Depth == 1 && r.NodeType == XmlNodeType.Element)
                    {
                        ParsePacket(r);
                    }
                    //Console.WriteLine(r.Name + " " + r["name"]);
                }
            }
        }
    }
}

만약 경로관련 에러가 나온다면 PDL.xml을 현재 경로에서 \bin\Debug\net6.0으로 이동시켜 다시 실행해본다.

Parse 코드

xml의 패킷을 체크하고 읽는 메소드이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// xml 검사
public static void ParsePacket(XmlReader r)
{
    // 읽은 줄이 </> 인지 체크
    if (r.NodeType == XmlNodeType.EndElement)
        return;

    // 패킷인지 체크
    if (r.Name.ToLower() != "packet")
    {
        Console.WriteLine("Invalid packet node");
        return;
    }

    // 이름을 받고 null 체크
    string packetName = r["name"];
    if (string.IsNullOrEmpty(packetName))
    {
        Console.WriteLine("Packet without name");
        return;
    }

    // 검사 다했으면 읽기
    ParseMembers(r);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// 검사 다했으면 읽기
public static void ParseMembers(XmlReader r)
{
    string packetName = r["name"];

    int depth = r.Depth + 1;
    while (r.Read())
    {
        if (r.Depth != depth)
            break;

        string memberName = r["name"];
        if (string.IsNullOrEmpty(memberName))
        {
            Console.WriteLine("Member without name");
            return;
        }

        string memberType = r.Name.ToLower();
        switch (memberType)
        {
            case "bool":
            case "byte":
            case "short":
            case "ushort":
            case "int":
            case "long":
            case "double":
            case "string":
            case "list":
                break;
            default:
                break;
        }
    }
}

PacketFormat

고정적으로 사용하는 코드를 string으로 만들어 @""에 넣어준다.

1
2
3
4
5
class PacketFormat
{
    // @""안에 공통적인 코드를 각각 넣어 만들어준다.
    public static string packetFormat = @"";
}


💡 참고

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.