Skip to content

Latest commit

 

History

History
246 lines (206 loc) · 9.14 KB

File metadata and controls

246 lines (206 loc) · 9.14 KB

배치 파일이란 윈도우에서 제공해주는 다양한 명령어들을 작성해서 한번에 실행해주도록 해줌

필요한 기능이 있을 때마다 구글링을 해주는 것이 좋음

현재 우리가 원하는 기능

  1. PacketGenerator.exe 파일을 대신 실행

    START ../../PacketGenerator/bin/Debug/PacketGenerator.exe

    : START 시작 명령어

    : ../../ 현재 폴더 위치에서 뒤로 가기 2번

  2. xml 파일 경로 지정

    START ../../PacketGenerator/bin/Debug/PacketGenerator.exe ../../PacketGenerator/PDL.xml

    ../../PacketGenerator/PDL.xml : 현재 xml 파일이 있는 곳

    ⇒ exe 파일 다음에 들어가는 값이 Main(string[] args)의 args의 인자로 들어가게 된다. ⇒ 현재는 args[0]에 들어감

  3. 생성된 파일 이동

    XCOPY /Y

    XCOPY : 생성된 파일을 원하는 경로에 복사 붙여넣기 하는 명령어

    /Y : 해당 경로에 같은 파일이 있다면 덮어씌우는 옵션

    Batch

    START ../../PacketGenerator/bin/Debug/PacketGenerator.exe ../../PacketGenerator/PDL.xml
    XCOPY /Y GenPacket.cs "../../DummyClient/Packet"
    XCOPY /Y GenPacket.cs "../../Server/Packet"
    

    PacketGeneratorProgram

    using System;
    using System.IO;
    using System.Xml;
    
    namespace PacketGenerator
    {
        class PacketGeneratorProgram
        {
            static string genPacket;
            static ushort packetId;
            static string packetEnum;
    
            static void Main(string[] args)
            {
                // pdl 경로
                string pdlPath = "PDL.xml";
    
                XmlReaderSettings settings = new XmlReaderSettings()
                {
                    IgnoreComments = true,
                    IgnoreWhitespace = true
                };
    
                if (args.Length >= 1)
                    pdlPath = args[0];
                    
                using (XmlReader r = XmlReader.Create(pdlPath, settings))
                {
                    r.MoveToContent();
    
                    while (r.Read())
                    {
                        if (r.Depth == 1 && r.NodeType == XmlNodeType.Element)
                        {
                            ParsePacket(r);
                        }
                    }
                    string fileText = string.Format(PacketFormat.fileFormat, packetEnum, genPacket);
                    File.WriteAllText("GenPacket.cs", fileText);
                };
            }
            
            public static void ParsePacket(XmlReader r)
            {
                if (r.NodeType == XmlNodeType.EndElement)
                    return;
                if (r.Name.ToLower() != "packet")
                {
                    System.Console.WriteLine("Invalid packet name");
                    return;
                }
                string packetName = r["name"];
                if (string.IsNullOrEmpty(packetName))
                {
                    System.Console.WriteLine("Packet without packet");
                    return;
                }
                
                Tuple<string, string, string> t = ParseMembers(r);
                genPacket += string.Format(PacketFormat.packetFormat, packetName, t.Item1, t.Item2, t.Item3);
    
                packetEnum += string.Format(PacketFormat.packetEnumFormat, packetName, ++packetId) + Environment.NewLine + "\t";
            }
    
            public static Tuple<string, string, string> ParseMembers(XmlReader r)
            {
                string packetName = r["name"];
    
                string memberCode = "";
                string readCode = "";
                string writeCode = "";
    
                int depth = r.Depth + 1;
                while(r.Read())
                {
                    if (r.Depth != depth)
                        break;
                    string memberName = r["name"];
                    if (string.IsNullOrEmpty(memberName))
                    {
                        System.Console.WriteLine("Member without name");
                        return null;
                    }
    
                    if (string.IsNullOrEmpty(memberCode) == false)
                        memberCode += Environment.NewLine;
                    if (string.IsNullOrEmpty(readCode) == false)
                        readCode += Environment.NewLine;
                    if (string.IsNullOrEmpty(writeCode) == false)
                        writeCode += Environment.NewLine;
                    
                    string memberType = r.Name.ToLower();
                    switch (memberType)
                    {
                        case "byte":
                        case "sbyte":
                            memberCode += string.Format(PacketFormat.memberFormat, memberType, memberName);
                            readCode += string.Format(PacketFormat.readByteFormat, memberName, memberType);
                            writeCode += string.Format(PacketFormat.writeByteFormat, memberName, memberType);
                            break;
                        case "bool":
                        case "short":
                        case "ushort":
                        case "int":
                        case "long":
                        case "float":
                        case "double":
                            memberCode += string.Format(PacketFormat.memberFormat, memberType, memberName);
                            readCode += string.Format(PacketFormat.readFormat, memberName, ToMemberType(memberType), memberType);
                            writeCode += string.Format(PacketFormat.writeFormat, memberName, memberType);
                            break;
                        case "string":
                            memberCode += string.Format(PacketFormat.memberFormat, memberType, memberName);
                            readCode += string.Format(PacketFormat.readStringFormat, memberName, memberName);
                            writeCode += string.Format(PacketFormat.writeStringFormat, memberName);
                            break;
                        case "list":
                            Tuple<string, string, string> t = ParseList(r);
                            memberCode += t.Item1;
                            readCode += t.Item2;
                            writeCode += t.Item3;
                            break;
                        default:
                            break;
    
                    }
                }
                memberCode = memberCode.Replace("\n", "\n\t");
                readCode = readCode.Replace("\n", "\n\t\t");
                writeCode = writeCode.Replace("\n", "\n\t\t");
                return new Tuple<string, string, string>(memberCode, readCode, writeCode);
            }
    
            private static Tuple<string, string, string> ParseList(XmlReader r)
            {
                string listName = r["name"];
                if (string.IsNullOrEmpty(listName))
                {
                    System.Console.WriteLine("List without name");
                    return null;
                }
    
                Tuple<string, string, string> t = ParseMembers(r);
                string memberCode = string.Format(PacketFormat.memberListFormat, 
                    FirstCharToUpper(listName),
                    FirstCharToLower(listName),
                    t.Item1,
                    t.Item2,
                    t.Item3);
                
                string readCode = string.Format(PacketFormat.readListFormat, 
                    FirstCharToUpper(listName),
                    FirstCharToLower(listName)
                );
    
                string writeCode = string.Format(PacketFormat.writeListFormat, 
                    FirstCharToUpper(listName),
                    FirstCharToLower(listName)
                );
                return new Tuple<string, string, string>(memberCode, readCode, writeCode);
            }
    
            public static string ToMemberType(string memberType)
            {
                switch (memberType)
                {
                    case "bool":
                        return "ToBoolean";
                    case "short":
                        return "ToInt16";
                    case "ushort":
                        return "ToUInt16";
                    case "int":
                        return "ToInt32";
                    case "long":
                        return "ToInt64";
                    case "float":
                        return "ToSingle";
                    case "double":
                        return "ToDouble";
                    default:
                        return "";
                }
            }
    
            public static string FirstCharToUpper(string input)
            {
                if (string.IsNullOrEmpty(input))
                {
                    return "";
                }
                return input[0].ToString().ToUpper() + input.Substring(1);
            }
    
            public static string FirstCharToLower(string input)
            {
                if (string.IsNullOrEmpty(input))
                {
                    return "";
                }
                return input[0].ToString().ToLower() + input.Substring(1);
            }
        }
    }