Example #1
0
        public override void BuildSignature()
        {
            if (isSignatureBuilt)
            {
                return;
            }

            Program.Log(LogLevel.NOR, "Building Signature for Packet[" + Header.PadRight(4, ' ') + "][" + Desc + "]");

            bool   doesSubcatePlaceholderAppeared = false;
            bool   packetBodySectionEnded         = false;
            bool   isInSubcate          = false;
            bool   isRepeatableTagEnded = true;
            string tmpSignature         = ""; // subcate is not replaced yet
            JArray infoBeforeSubcate    = new JArray();
            JArray infoAfterSubcate     = new JArray();

            dynamic tmpObj = new JObject();
            string  tmpSubcateSignature = "";
            JArray  tmpSubcateInfo      = new JArray();

            foreach (var(num, code) in Lines)
            {
                var(sign, infos)    = ParseSignatureLine(code);
                Program.CurrentLine = num;

                if (infos != null)
                {
                    if (isInSubcate)
                    {
                        tmpSubcateSignature += " " + sign;
                        tmpSubcateInfo.Add(infos);
                    }
                    else
                    {
                        tmpSignature += " " + sign;
                        if (doesSubcatePlaceholderAppeared)
                        {
                            infoAfterSubcate.Add(infos);
                        }
                        else
                        {
                            infoBeforeSubcate.Add(infos);
                        }
                    }
                }
                else
                {
                    if (code.StartsWith("+ Fragment"))
                    {
                        var obj = Fragment.GetFragmentByCode(code);

                        tmpSignature += " " + obj.Signature;
                        // add range
                        obj.Infos.ForEach(info => infoBeforeSubcate.Add(info));
                    }
                    else if (code.StartsWith("+ SubCate"))
                    {
                        // set constraint, only 1 subcate code can be used
                        if (doesSubcatePlaceholderAppeared)
                        {
                            Program.Log(LogLevel.ERR | LogLevel.EXIT,
                                        "Constraint Violation - You can only use 1 \"+ SubCate\" within same packet/fragment.",
                                        "Occurred within: Packet[" + Header.PadRight(4, ' ') + "] " + Desc
                                        );
                        }
                        else if (packetBodySectionEnded)
                        {
                            Program.Log(LogLevel.ERR | LogLevel.EXIT,
                                        "Constraint Violation - You cannot include another subcate within a subcate.",
                                        "Occurred within: Packet[" + Header.PadRight(4, ' ') + "] " + Desc
                                        );
                        }

                        tmpSignature += " {SUBCATE}";
                        doesSubcatePlaceholderAppeared = true;
                    }
                    else if (code.StartsWith("SubCate["))
                    {
                        // start of subcate signature
                        var m = regexSubcate.Match(code);
                        var g = m.Groups;
                        if (!m.Success || (g[1].Value == "" && g[2].Value == ""))
                        {
                            Program.Log(LogLevel.ERR | LogLevel.EXIT,
                                        "Invalid SubCate declaration.",
                                        "Occurred within: Packet[" + Header.PadRight(4, ' ') + "] " + Desc,
                                        "Captured: [" + string.Join(", ", g.Values) + "]",
                                        "Raw: " + code
                                        );
                        }

                        // have subcate before this subcate (another)
                        // push the previous subcate to dict list
                        if (isInSubcate)
                        {
                            if (tmpSignature == "")
                            {
                                Program.Log(LogLevel.WARN,
                                            "Skipped invalid SubCate declaration - No actual signature/body.",
                                            "Occurred within: Packet[" + Header.PadRight(4, ' ') + "] " + Desc
                                            );
                            }
                            else
                            {
                                subcate.Add(tmpSubcateSignature.TrimStart(), tmpObj);
                            }
                        }

                        tmpObj              = new JObject(); // renew
                        tmpObj.desc         = g[1].Value;
                        tmpObj["params"]    = tmpSubcateInfo = new JArray();
                        tmpSubcateSignature = "";

                        if (g[2].Value != "")
                        {
                            // with hex-byte (static hex subcate signature)
                            tmpSubcateSignature += " " + g[2].Value[1..];
Example #2
0
        static void Main(string[] cmdArgs)
        {
            Version version = Assembly.GetExecutingAssembly().GetName().Version;
            AssemblyDescriptionAttribute releaseDate = (AssemblyDescriptionAttribute)Attribute.GetCustomAttribute(Assembly.GetExecutingAssembly(), typeof(AssemblyDescriptionAttribute));

            Console.WriteLine($"============== Signature Builder - For Parser rev5 ==============\r\n" +
                              $"\t+ Build: {version} [{releaseDate.Description}]\r\n\r\n");

            var file    = (cmdArgs.Length >= 1 ? cmdArgs[0] : ".") + "/parser.txt";
            var outFile = (cmdArgs.Length >= 2 ? cmdArgs[1] : ".") + "/_pkts.v5.ignore.json";

            if (!System.IO.File.Exists(file))
            {
                Log(LogLevel.ERR | LogLevel.EXIT, "File not found @ " + file);
            }
            string[] lines = System.IO.File.ReadAllLines(file);

            /* Example of the built output (JSON):
             * {
             *   // layer 1                   - packet header bytes (AKA: delimiter)
             *   "6F": {
             *      // layer 2                - packet infos
             *      "name": "Hero Effect", // - packet main name
             *      "signature": {
             *          // layer 3            - packet signature (determines all the variants of packet body)
             *          "$4 [REPS] $4 $1 $1 [REPE]": {
             *              // layer 4        - infos of the matched packet signature
             *              "desc": "",       - description of this packet signature
             *              "params": [ //    - infos of each param(data) in the packet signature
             *                  { "name": "HeroID" }, // dict<string, dynamic>
             *                  { "name": "EffectID", "func": ["eHeroEffect", ] },
             *                  // more data ...
             *              ]
             *          }
             *      }
             *  }
             * }*/
            bool       parserSectionStart = false;
            ParserCode obj = null;

            foreach (string tmp in lines)
            {
                ++CurrentLine;

                var line = tmp.Replace("/// ", "").Trim();
                if (line == "" || line.StartsWith("//"))
                {
                    continue;
                }

                // split the actual code, remove comment (//) part.
                if (line.Contains("//"))
                {
                    line = line.Split("//")[0].Trim();
                }

                if (line == "<parser>")
                {
                    // start of parser tag
                    parserSectionStart = true;
                    continue;
                }
                else if (line == "</parser>")
                {
                    // end of parser tag
                    parserSectionStart = false;
                    obj = null;
                    continue;
                }

                if (!parserSectionStart)
                {
                    // </parser> exists before but no start tag after that.
                    Log(LogLevel.ERR | LogLevel.EXIT,
                        "Unexpected line outside <parser> tag.",
                        "Raw: " + line
                        );
                }

                if (line.StartsWith("Fragment["))
                {
                    var m = ParserCode.regexFrag.Match(line).Groups;
                    if (m[1].Value == "")
                    {
                        Log(LogLevel.ERR | LogLevel.EXIT,
                            "Malform Fragment declaration found.",
                            "Captured: [" + string.Join(", ", m) + "]",
                            "Raw: " + line
                            );
                    }

                    var frag = new Fragment(m[1].Value);
                    if (!Fragment.FragmentPool.TryAdd(frag.Name, frag))
                    {
                        Log(LogLevel.ERR | LogLevel.EXIT,
                            "Failed to declare Fragment.",
                            "Fragment Name: " + frag.Name,
                            "Raw: " + line
                            );
                    }
                    Log(LogLevel.NOR, $"New Fragment[{frag.Name}]");
                    obj = frag;
                }
                else if (line.StartsWith("Packet["))
                {
                    // packet declaration
                    var m = ParserCode.regexPkt.Match(line).Groups;
                    if (m[1].Value == "" || m[2].Value == "")
                    {
                        Log(LogLevel.WARN,
                            $"Skipped mismatch Packet Declaration",
                            "Captured: {" + string.Join(", ", m) + "}",
                            "Raw: " + line
                            );
                        continue;
                    }

                    var pkt = new Packet(m[1].Value, m[2].Value.ToUpper());
                    if (!Packet.PacketPool.TryAdd(pkt.Header, pkt))
                    {
                        Log(LogLevel.ERR | LogLevel.EXIT, $"Duplicated Packet Header[{pkt.Header}]");
                    }

                    Log(LogLevel.NOR, $"New Packet[{pkt.Header,-4}] Desc[{pkt.Desc}]");
                    obj = pkt;
                }
                else
                {
                    if (obj == null)
                    {
                        Log(LogLevel.ERR | LogLevel.EXIT,
                            "Unexpected line before Packet / Fragment declaration.",
                            "Raw: " + line
                            );
                    }

                    // push to obj's List for further parsing.
                    obj.AddLine(CurrentLine, line);
                }
            }

            Console.WriteLine("");

            // loop all objects to do parsing
            //Fragment.FragmentPool.Values.ToArray()[1].BuildSignature();
            JObject mainDict = new JObject();

            Fragment.FragmentPool.Values.ToList().ForEach(frag => frag.BuildSignature());
            Packet.PacketPool.Values.ToList().ForEach(pkt =>
            {
                pkt.BuildSignature();
                mainDict.Add(pkt.Header, new JObject {
                    { "desc", pkt.Desc },
                    { "signature", pkt.Signatures }
                });
            });

            // add version & timestamp
            mainDict.Add("_timestamp", DateTimeOffset.UtcNow.ToUnixTimeSeconds() * 1000);
            mainDict.Add("_builder", new JArray {
                releaseDate.Description.Split(" ")[0], "build " + version, "5"
            });

            System.IO.File.WriteAllText(outFile, JsonConvert.SerializeObject(mainDict));

            Console.WriteLine("");
            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine("[+] Build Success! Output File: " + outFile);
            Console.ForegroundColor = ConsoleColor.White;
            Console.WriteLine("\nPress any key to exit.");
            Console.ReadKey();
        }