/// <summary>
        ///
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        private static string DecompileCommand(byte[] data)
        {
            MeleeCMDAction act = ActionCommon.GetMeleeCMDAction((byte)(data[0] >> 2));

            string o = act.Name + "(";

            if (act != null)
            {
                o += act.Decompile(data);
            }
            else
            {
                for (int i = 0; i < data.Length; i++)
                {
                    if (i == 0)
                    {
                        o += "0x" + (data[i] & 0x3).ToString("x");
                    }
                    else
                    {
                        o += ",0x" + data[i].ToString("x");
                    }
                }
            }

            o += ");";
            return(o);
        }
示例#2
0
        private static byte[] CompileCommand(string name, string[] parameters)
        {
            if (name.Equals(""))
            {
                return(new byte[0]);
            }

            MeleeCMDAction action = ActionCommon.GetMeleeCMDAction(name);

            byte[] data = new byte[] { (byte)(action.Command << 2), 0, 0, 0 };
            if (action != null)
            {
                data = action.Compile(parameters);
                if (data == null)
                {
                    //ErrorCode = CompileError.ParameterCount;
                    return(null);
                }
            }

            return(data);
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="output"></param>
        /// <param name="name"></param>
        /// <param name="datas"></param>
        /// <param name="structToFunctionName"></param>
        private void DecompileGroup(StringBuilder output, string name, HSDStruct datas)
        {
            if (structToFunctionName.ContainsKey(datas))
            {
                return;
            }
            structToFunctionName.Add(datas, name);

            output.AppendLine(name);
            output.AppendLine("{");
            using (BinaryReaderExt r = new BinaryReaderExt(new MemoryStream(datas.GetData())))
            {
                byte flag = (byte)(r.ReadByte() >> 2);

                var cmd = ActionCommon.GetMeleeCMDAction(flag);

                while (flag != 0)
                {
                    r.BaseStream.Position -= 1;
                    var size    = cmd.ByteSize;
                    var command = r.GetSection(r.Position, size);
                    r.Skip((uint)size);

                    if (flag == 5 || flag == 7) //goto
                    {
                        var re = datas.GetReference <HSDAccessor>((int)r.BaseStream.Position - 4);
                        if (re != null)
                        {
                            if (!tempStructToName.ContainsKey(re._s))
                            {
                                if (structToFunctionName.ContainsKey(re._s))
                                {
                                    tempStructToName.Add(re._s, structToFunctionName[re._s]);
                                }
                                else
                                {
                                    tempStructToName.Add(re._s, name + "_" + ((int)r.BaseStream.Position - 4).ToString("X4"));
                                }
                            }
                            var funcname = tempStructToName[re._s];
                            output.AppendLine("\t" + (flag == 5 ? "Goto" : "Subroutine") + "(" + funcname + ");");
                        }
                    }
                    else
                    {
                        output.AppendLine("\t" + DecompileCommand(command));
                    }

                    if (r.BaseStream.Position >= r.BaseStream.Length)
                    {
                        break;
                    }

                    flag = (byte)(r.ReadByte() >> 2);
                    cmd  = ActionCommon.GetMeleeCMDAction(flag);
                }
            }
            output.AppendLine("}");

            foreach (var re in datas.References)
            {
                DecompileGroup(output, name + "_" + re.Key.ToString("X4"), re.Value);
            }
        }
示例#4
0
        /// <summary>
        /// Compiles script into subaction byte code
        /// </summary>
        public static void Compile(string script)
        {
            if (scriptToBinary.ContainsKey(script) || scriptToReference.ContainsKey(script))
            {
                return;
            }

            HSDStruct main = null;

            var stream = Regex.Replace(script, @"\s+", string.Empty);

            if (script.StartsWith("ref:"))
            {
                var name = stream.Split(':')[1];
                scriptToReference.Add(script, name);
                return;
            }

            var functions = Regex.Matches(stream, @"([^\{])*\{([^\}]*)\}");

            foreach (Match g in functions)
            {
                var name = Regex.Match(g.Value, @".+?(?={)").Value;
                var code = Regex.Match(g.Value, @"(?<=\{).+?(?=\})").Value.Split(';');

                if (nameToFunction.ContainsKey(name))
                {
                    continue;
                }

                HSDStruct s = new HSDStruct();
                nameToFunction.Add(name, s);
                structToOffsetToFunction.Add(s, new Dictionary <int, string>());

                if (main == null)
                {
                    main = s;
                }

                List <byte> output   = new List <byte>();
                bool        returned = false;
                foreach (var c in code)
                {
                    var cname       = Regex.Match(c, @".+?(?=\()").Value;
                    var cparameters = Regex.Match(c, @"(?<=\().+?(?=\))").Value.Split(',');

                    if (cname == "Return")
                    {
                        returned = true;
                    }

                    byte flag = ActionCommon.GetMeleeCMDAction(cname).Command;

                    if (flag == 0x5 || flag == 0x7) //goto and subroutine
                    {
                        structToOffsetToFunction[s].Add(output.Count + 4, cparameters[0]);
                        output.AddRange(new byte[] { (byte)(flag << 2), 0, 0, 0, 0, 0, 0, 0 });
                    }
                    else
                    {
                        output.AddRange(CompileCommand(cname, cparameters));
                    }

                    // padd
                    if (output.Count % 4 != 0)
                    {
                        output.AddRange(new byte[4 - (output.Count % 4)]);
                    }
                }
                if (true)
                {
                    output.Add(0);
                    if (output.Count % 4 != 0)
                    {
                        output.AddRange(new byte[4 - (output.Count % 4)]);
                    }
                }
                s.SetData(output.ToArray());
            }

            if (main == null)
            {
                main = new HSDStruct(4);
            }

            scriptToBinary.Add(script, main);
        }