예제 #1
0
        public static void LoadTbl(string path)
        {
            int          count = 0;
            StreamReader sr    = new StreamReader(path, Encoding.UTF8);

            while (sr.Peek() >= 0)
            {
                string line = sr.ReadLine();
                int    pos  = line.IndexOf("=");
                if (pos < 0)
                {
                    continue;
                }
                string hex  = line.Substring(0, pos);
                string word = line.Substring(pos + 1, line.Length - (pos + 1));
                if (!dict.ContainsKey(word))
                {
                    dict.Add(word, ScriptUtil.Hex2Byte(hex));
                    count++;
                }
                else
                {
                    Console.WriteLine("重复的汉字!跳过。{0}", line);
                }
            }

            sr.Close();
            Console.WriteLine("已加载自定义编码表,有效字符数:{0}", count);
        }
예제 #2
0
        public ScriptParser(GameScript game, string custom_game = "",
                            bool oldFormat  = false,
                            bool lua        = false,
                            bool luae       = false,
                            bool json       = false,
                            string onlyText = null)
        {
            this.game       = game;
            this.FormatOld  = oldFormat;
            this.FormatLua  = lua;
            this.FormatLuaE = luae;
            this.FormatJson = json;
            this.OnlyText   = onlyText;
            if (oldFormat)
            {
                // Decompile
                code_bytes    = new List <byte[]>();
                code_position = new Dictionary <uint, int>();

                // Compile
                goto_position = new Dictionary <uint, int>();
                line_position = new List <uint>();
            }

            if (game != GameScript.CUSTOM)
            {
                custom_game = Path.Combine("OPCODE", game.ToString() + ".txt");
            }

            ScriptVersion = ScriptUtil.InitOpcodeDict(custom_game,
                                                      ref decompress_dic, ref compress_dic);
        }
예제 #3
0
        public CodeLine ReadCodeLine()
        {
            CodeLine code        = new CodeLine(current_line, (int)fs.Position);
            UInt16   code_len    = br.ReadUInt16();
            int      code_offset = 0;

            //byte[] bytes = ReadCodeBytes();

            code.opcode_index = br.ReadByte();
            code_offset++;
            if (!opcode_dict.ContainsKey(code.opcode_index))
            {
                throw new Exception("未知的opcode!");
            }
            code.opcode = opcode_dict[code.opcode_index].opcode;

            CodeInfo info = new CodeInfo(br.ReadByte());

            code_offset++;
            info.data = new UInt16[info.count];
            for (int i = 0; i < info.count; i++)
            {
                info.data[i] = br.ReadUInt16();
                code_offset += 2;
            }
            code.info = info;
            // 参数类型列表
            code.param_types = opcode_dict[code.opcode_index].param.ToArray();
            // 参数数据
            code.param_datas = new List <ParamData>(ReadParamData(code.param_types, code_len, ref code_offset));



            while (code_offset + 1 < code_len)
            {
                byte[] temp = br.ReadBytes(2);
                code_offset += 2;
                code.param_datas.Add(new ParamData(Type.Byte2, temp, ScriptUtil.Byte2Hex(temp)));
            }
            if (code_offset < code_len)
            {
                byte temp = br.ReadByte();
                code_offset++;
                code.param_datas.Add(new ParamData(Type.Byte, temp, ScriptUtil.Byte2Hex(temp)));
            }


            current_line++;
            return(code);
        }
예제 #4
0
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            if (reader.TokenType == JsonToken.Null)
            {
                if (objectType == null)
                {
                    throw new Exception(string.Format("不能转换null value to {0}.", objectType));
                }
                return(null);
            }

            if (reader.TokenType == JsonToken.String)
            {
                string hex = (string)reader.Value;
                if (hex.Length >= 4 && hex.Substring(0, 2).Equals("0x", StringComparison.OrdinalIgnoreCase))
                {
                    return(ScriptUtil.Hex2Byte(hex));
                }
            }

            return(reader.Value);
        }
예제 #5
0
 public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
 {
     if (value == null)
     {
         writer.WriteNull();
         return;
     }
     if (value.GetType().Name == "Byte[]")
     {
         byte[] bytes = ((byte[])value);
         if (bytes.Length == 0)
         {
             writer.WriteNull();
             return;
         }
         writer.WriteValue(ScriptUtil.Byte2Hex(bytes, false, true));
     }
     else
     {
         writer.WriteValue(value);
     }
 }
예제 #6
0
 public ScriptOpcodeGuide(string opcode = "", int version = 3)
 {
     if (opcode == "")
     {
         scriptVersion = version;
         for (int i = 0; i < 128; i++)
         {
             bytesToOpcodeDict.Add((byte)i, new ScriptOpcode((byte)i, "OPCODE_" + ScriptUtil.Byte2Hex((byte)i)));
         }
         Console.WriteLine("无opcode文件,创建默认opcode文件");
     }
     else if (File.Exists(opcode))
     {
         string[] dic;
         dic = File.ReadAllLines(opcode);
         bytesToOpcodeDict.Clear();
         if (dic.Length > 0)
         {
             if (dic[0].Trim() == ";Ver3")
             {
                 scriptVersion = 3;
             }
             else if (dic[0].Trim() == ";Ver2")
             {
                 scriptVersion = 2;
             }
         }
         int i = 0;
         foreach (string line in dic)
         {
             if (line.TrimStart()[0] == ';')
             {
                 continue;
             }
             bytesToOpcodeDict.Add((byte)i, new ScriptOpcode((byte)i, line.Replace("\r", "")));
             i++;
         }
         if (bytesToOpcodeDict.Count > 0)
         {
             hasOpcode = true;
         }
         Console.WriteLine("已加载opcode文件:{0}", Path.GetFileName(opcode));
     }
 }
예제 #7
0
        public ParamData[] ReadParamData(ref BinaryReader tbr, List <ParamType> param)
        {
            Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
            List <string>    retn  = new List <string>();
            List <ParamData> datas = new List <ParamData>();
            int    count           = 0;
            int    curr_pos        = (int)tbr.BaseStream.Position;
            int    tbr_len         = (int)tbr.BaseStream.Length;
            bool   nullable_skip   = false;
            string data_str;

            foreach (var value in param)
            {
                DataType type = value.type;
                count++;
                curr_pos = (int)tbr.BaseStream.Position;
                switch (type)
                {
                case DataType.Byte:
                case DataType.Byte2:
                case DataType.Byte3:
                case DataType.Byte4:
                {
                    var data_bytes = tbr.ReadBytes((int)type);
                    data_str = ScriptUtil.Byte2Hex(data_bytes);
                    datas.Add(new ParamData(type, data_bytes, data_str));
                    break;
                }

                case DataType.UInt16:
                    if (value.nullable && curr_pos + 2 >= tbr_len)
                    {
                        nullable_skip = true;
                        break;
                    }
                    var data_uint16 = tbr.ReadUInt16();
                    data_str = data_uint16.ToString();
                    datas.Add(new ParamData(DataType.UInt16, data_uint16, data_str));
                    break;

                case DataType.Int16:
                    if (value.nullable && curr_pos + 2 > tbr_len)
                    {
                        nullable_skip = true;
                        break;
                    }
                    var data_int16 = tbr.ReadInt16();
                    data_str = data_int16.ToString();
                    datas.Add(new ParamData(DataType.Int16, data_int16, data_str));
                    break;

                case DataType.UInt32:
                    if (value.nullable && curr_pos + 4 > tbr_len)
                    {
                        nullable_skip = true;
                        break;
                    }
                    var data_uint32 = tbr.ReadUInt32();
                    data_str = data_uint32.ToString();
                    datas.Add(new ParamData(DataType.UInt32, data_uint32, data_str));
                    break;

                case DataType.Int32:
                    if (value.nullable && curr_pos + 4 > tbr_len)
                    {
                        nullable_skip = true;
                        break;
                    }
                    var data_int32 = tbr.ReadInt32();
                    data_str = data_int32.ToString();
                    datas.Add(new ParamData(DataType.Int32, data_int32, data_str));
                    break;

                case DataType.StringUnicode:
                case DataType.StringSJIS:
                case DataType.StringUTF8:
                {
                    if (type == DataType.StringUnicode)
                    {
                        data_str = Encoding.Unicode.GetString(ReadStringDoubleEnd(ref tbr));
                        datas.Add(new ParamData(DataType.StringUnicode, data_str, data_str));
                    }
                    else if (type == DataType.StringSJIS)
                    {
                        data_str = Encoding.GetEncoding("Shift-Jis").GetString(ReadStringSingleEnd(ref tbr));
                        datas.Add(new ParamData(DataType.StringSJIS, data_str, data_str));
                    }
                    else if (type == DataType.StringUTF8)
                    {
                        data_str = Encoding.UTF8.GetString(ReadStringSingleEnd(ref tbr));
                        datas.Add(new ParamData(DataType.StringUTF8, data_str, data_str));
                    }

                    break;
                }

                case DataType.LenStringUnicode:
                case DataType.LenStringSJIS:
                {
                    if (value.nullable && curr_pos + 2 > tbr_len)
                    {
                        nullable_skip = true;
                        break;
                    }
                    int len = tbr.ReadUInt16();
                    if (type == DataType.LenStringUnicode)
                    {
                        data_str = Encoding.Unicode.GetString(tbr.ReadBytes(len * 2));
                        datas.Add(new ParamData(DataType.LenStringUnicode, data_str, data_str));
                    }
                    else if (type == DataType.LenStringSJIS)
                    {
                        data_str = Encoding.GetEncoding("Shift-Jis").GetString(tbr.ReadBytes(len * 2));
                        datas.Add(new ParamData(DataType.LenStringSJIS, data_str, data_str));
                    }
                    break;
                }

                case DataType.Position:
                    if (value.nullable && curr_pos + 4 > tbr_len)
                    {
                        nullable_skip = true;
                        break;
                    }
                    uint pos = tbr.ReadUInt32();
                    if (code_position.ContainsKey(pos))
                    {
                        datas.Add(new ParamData(DataType.Position, pos, code_position[pos].ToString()));
                    }
                    else
                    {
                        throw new Exception("错误的跳转位置: " + pos + "!");
                    }
                    break;

                default:
                    break;
                }
            }
            return(datas.ToArray());
        }
예제 #8
0
        private byte[] CompileCode(string code, long position)
        {
            code += " ";
            MemoryStream ms  = new MemoryStream();
            BinaryWriter mbw = new BinaryWriter(ms);

            Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
            int i = 0;

            while (i + 4 <= code.Length && code.Substring(i, 4) == "    ")
            {
                i += 4;
            }
            int len_pos = (int)ms.Position;

            mbw.Write(new byte[2]);//长度填充

            string token = "";
            bool   str   = false;

            for (; i < code.Length; i++)
            {
                if (code[i] == '\"')
                {
                    str = !str;
                }
                if (code[i] == ' ' && !str)
                {
                    switch (token[0])
                    {
                    case '<':
                        int goto_line = Convert.ToInt32(token.Substring(1, token.Length - 2));
                        goto_position.Add((uint)(position + ms.Position), goto_line);
                        mbw.Write(BitConverter.GetBytes((uint)0));
                        break;

                    case '[':    //byte
                        mbw.Write(ScriptUtil.Hex2Byte(token.Substring(1, token.Length - 2)));
                        break;

                    case '(':    //uint16
                        mbw.Write(BitConverter.GetBytes(Convert.ToUInt16(token.Substring(1, token.Length - 2))));
                        break;

                    case '{':    //uint32
                        mbw.Write(BitConverter.GetBytes(Convert.ToUInt32(token.Substring(1, token.Length - 2))));
                        break;

                    case '$':
                    {
                        token = token.Replace(@"\n", "\n");
                        token = token.Replace(@"{\n}", "\n"); // 兼容保留
                        string tmp = token.Substring(3, token.Length - 4);
                        if (token[1] == 'u')                  //unicode string + 00 00
                        {
                            mbw.Write(Encoding.Unicode.GetBytes(tmp));
                            mbw.Write(new byte[] { 0x00, 0x00 });
                        }
                        else if (token[1] == 'j')        //sjis string + 00
                        {
                            mbw.Write(Encoding.GetEncoding("Shift-Jis").GetBytes(tmp));
                            mbw.Write((byte)0x00);
                        }
                        else if (token[1] == '8')        //utf8 string + 00
                        {
                            mbw.Write(Encoding.UTF8.GetBytes(tmp));
                            mbw.Write((byte)0x00);
                        }
                        else if (token[1] == 'c')        //custom string + 00
                        {
                            mbw.Write(CustomEncoding.GetBytes(tmp));
                            mbw.Write((byte)0x00);
                        }
                        break;
                    }

                    case '&':
                    {
                        token = token.Replace(@"\n", "\n");
                        token = token.Replace(@"{\n}", "\n"); // 兼容保留
                        string tmp = token.Substring(3, token.Length - 4);
                        if (token[1] == 'u')                  //len + unicode string
                        {
                            mbw.Write(BitConverter.GetBytes((UInt16)tmp.Length));
                            mbw.Write(Encoding.Unicode.GetBytes(tmp));
                        }
                        else if (token[1] == 'j')        //len + sjis string
                        {
                            mbw.Write(BitConverter.GetBytes((UInt16)tmp.Length));
                            mbw.Write(Encoding.GetEncoding("Shift-Jis").GetBytes(tmp));
                        }
                        else if (token[1] == 'c')        //custom string + 00
                        {
                            mbw.Write(BitConverter.GetBytes((UInt16)tmp.Length));
                            mbw.Write(CustomEncoding.GetBytes(tmp));
                        }
                        break;
                    }

                    case 'u':     // 兼容保留
                        token = token.Replace(@"{\n}", "\n");
                        mbw.Write(Encoding.Unicode.GetBytes(token.Substring(2, token.Length - 3)));
                        mbw.Write(new byte[] { 0x00, 0x00 });
                        break;

                    case 'j':     // 兼容保留
                        token = token.Replace(@"{\n}", "\n");
                        mbw.Write(Encoding.GetEncoding("Shift-Jis").GetBytes(token.Substring(2, token.Length - 3)));
                        mbw.Write((byte)0x00);
                        break;

                    case 'p':     // 兼容保留
                        token = token.Replace(@"{\n}", "\n");
                        mbw.Write(BitConverter.GetBytes((UInt16)(token.Length - 3)));
                        mbw.Write(Encoding.Unicode.GetBytes(token.Substring(2, token.Length - 3)));
                        break;

                    case 's':     // 兼容保留
                        token = token.Replace(@"{\n}", "\n");
                        mbw.Write(BitConverter.GetBytes((UInt16)(token.Length - 3)));
                        mbw.Write(Encoding.GetEncoding("Shift-Jis").GetBytes(token.Substring(2, token.Length - 3)));
                        break;

                    default:
                        if (token[0] >= 'A' && token[0] <= 'Z')
                        {
                            int    index_info = token.IndexOf('(');
                            string info       = "";
                            if (index_info > 0)
                            {
                                info  = token.Substring(index_info);
                                token = token.Substring(0, index_info);
                            }
                            if (compress_dic.ContainsKey(token))
                            {
                                if (ScriptVersion == 2)
                                {
                                    // [opcode] length/2 code
                                    // 1byte  1byte
                                    ms.Seek(len_pos, SeekOrigin.Begin);
                                    mbw.Write(compress_dic[token]);
                                    mbw.Write(new byte[1]);
                                }
                                else if (ScriptVersion == 2)
                                {
                                    // length [opcode] code
                                    // 2byte  1byte
                                    mbw.Write(compress_dic[token]);
                                }
                            }
                            if (index_info > 0)
                            {
                                if (info.Length > 2)
                                {
                                    string[] info_split = info.Substring(1, info.Length - 2).Split(',');
                                    if (ScriptVersion == 3)
                                    {
                                        mbw.Write((byte)info_split.Length);
                                    }
                                    foreach (string str1 in info_split)
                                    {
                                        mbw.Write(BitConverter.GetBytes(Convert.ToUInt16(str1)));
                                    }
                                }
                                else
                                {
                                    mbw.Write((byte)0);
                                }
                            }
                        }
                        else
                        {
                            throw new Exception("未知的指令或错误的数据格式:" + token);
                        }
                        break;
                    }
                    token = "";
                }
                else
                {
                    token += code[i];
                }
            }
            UInt16 len = (UInt16)(ms.Position - len_pos);

            if (ScriptVersion == 2)
            {
                // opcode [length/2] code
                // 1byte  1byte
                ms.Seek(len_pos + 1, SeekOrigin.Begin);
                mbw.Write((byte)(len / 2));
            }
            else if (ScriptVersion == 3)
            {
                // [length] opcode code
                // 2byte  1byte
                if (len % 2 != 0)
                {
                    mbw.Write((byte)0x00);
                }
                ms.Seek(len_pos, SeekOrigin.Begin);
                mbw.Write(BitConverter.GetBytes(len));
            }

            byte[] retn = ms.ToArray();
            if (retn.Length > 0 && Program.debug)
            {
                Console.WriteLine(ScriptUtil.Byte2Hex(retn, true));
            }
            mbw.Close();
            ms.Close();
            return(retn);
        }
예제 #9
0
        private string DecompileCode(byte[] line)
        {
            if (line.Length == 0)
            {
                return("");
            }
            MemoryStream ms           = new MemoryStream(line);
            BinaryReader mbr          = new BinaryReader(ms);
            string       retn         = "";
            byte         opcode_index = mbr.ReadByte();

            if (!decompress_dic.ContainsKey(opcode_index))
            {
                throw new Exception("未知的opcode!");
            }
            else
            {
                string opcode     = decompress_dic[opcode_index].opcode;
                int    param_num  = 0;
                byte[] param_data = null;
                if (ScriptVersion == 2)
                {
                    mbr.ReadByte();
                    param_num  = 1;
                    param_data = mbr.ReadBytes(param_num * 2);
                }
                else if (ScriptVersion == 3)
                {
                    param_num  = mbr.ReadByte();
                    param_data = mbr.ReadBytes(param_num * 2);
                }

                string data = ParamDataToString(ReadParamData(ref mbr, decompress_dic[opcode_index].param));
                retn = (data.Length > 0 ? " " : "") + data;


                while (ms.Position + 1 < ms.Length)
                {
                    retn += " [" + ScriptUtil.Byte2Hex(BitConverter.GetBytes(mbr.ReadUInt16())) + "]";
                }
                if (ms.Position < ms.Length)
                {
                    retn += " [" + ScriptUtil.Byte2Hex(mbr.ReadByte()) + "]";
                }


                param_num = param_data.Length / 2 < param_num ? param_data.Length / 2 : param_num;
                string info = "(";
                for (int i = 0; i < param_num; i++)
                {
                    info += BitConverter.ToUInt16(param_data, i * 2).ToString();
                    if (i != param_num - 1)
                    {
                        info += ",";
                    }
                }
                info += ")";
                retn  = opcode + info + retn;
            }
            if (retn != "    " && retn != "" && Program.debug)
            {
                Console.WriteLine(retn);
            }
            mbr.Close();
            ms.Close();
            return(retn);
        }
예제 #10
0
        public ParamData[] ReadParamData(ParamType[] param, int code_len, ref int code_offset)
        {
            Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
            List <string>    retn  = new List <string>();
            List <ParamData> datas = new List <ParamData>();
            int    count           = 0;
            bool   nullable_skip   = false;
            string data_str;

            foreach (var value in param)
            {
                Type type = value.type;
                count++;
                var temp_pos = fs.Position;
                switch (type)
                {
                case Type.Byte:
                case Type.Byte2:
                case Type.Byte3:
                case Type.Byte4:
                {
                    var data_bytes = br.ReadBytes((int)type + 1);
                    data_str = ScriptUtil.Byte2Hex(data_bytes);
                    datas.Add(new ParamData(type, data_bytes, data_str));
                    break;
                }

                case Type.UInt16:
                    if (value.nullable && code_offset + 2 > code_len)
                    {
                        nullable_skip = true;
                        break;
                    }
                    var data_uint16 = br.ReadUInt16();
                    data_str = data_uint16.ToString();
                    datas.Add(new ParamData(Type.UInt16, data_uint16, data_str));
                    break;

                case Type.Int16:
                    if (value.nullable && code_offset + 2 > code_len)
                    {
                        nullable_skip = true;
                        break;
                    }
                    var data_int16 = br.ReadInt16();
                    data_str = data_int16.ToString();
                    datas.Add(new ParamData(Type.Int16, data_int16, data_str));
                    break;

                case Type.UInt32:
                    if (value.nullable && code_offset + 4 > code_len)
                    {
                        nullable_skip = true;
                        break;
                    }
                    var data_uint32 = br.ReadUInt32();
                    data_str = data_uint32.ToString();
                    datas.Add(new ParamData(Type.UInt32, data_uint32, data_str));
                    break;

                case Type.Int32:
                    if (value.nullable && code_offset + 4 > code_len)
                    {
                        nullable_skip = true;
                        break;
                    }
                    var data_int32 = br.ReadInt32();
                    data_str = data_int32.ToString();
                    datas.Add(new ParamData(Type.Int32, data_int32, data_str));
                    break;

                case Type.StringUnicode:
                case Type.StringSJIS:
                case Type.StringUTF8:
                {
                    if (type == Type.StringUnicode)
                    {
                        data_str = Encoding.Unicode.GetString(ReadStringDoubleEnd());
                        datas.Add(new ParamData(Type.StringUnicode, data_str, data_str));
                    }
                    else if (type == Type.StringSJIS)
                    {
                        data_str = Encoding.GetEncoding("Shift-Jis").GetString(ReadStringSingleEnd());
                        datas.Add(new ParamData(Type.StringSJIS, data_str, data_str));
                    }
                    else if (type == Type.StringUTF8)
                    {
                        data_str = Encoding.UTF8.GetString(ReadStringSingleEnd());
                        datas.Add(new ParamData(Type.StringUTF8, data_str, data_str));
                    }
                    break;
                }

                case Type.LenStringUnicode:
                case Type.LenStringSJIS:
                {
                    if (value.nullable && code_offset + 2 > code_len)
                    {
                        nullable_skip = true;
                        break;
                    }
                    int len = br.ReadUInt16();
                    if (type == Type.LenStringUnicode)
                    {
                        data_str = Encoding.Unicode.GetString(br.ReadBytes(len * 2));
                        datas.Add(new ParamData(Type.LenStringUnicode, data_str, data_str));
                    }
                    else if (type == Type.LenStringSJIS)
                    {
                        data_str = Encoding.GetEncoding("Shift-Jis").GetString(br.ReadBytes(len * 2));
                        datas.Add(new ParamData(Type.LenStringSJIS, data_str, data_str));
                    }
                    break;
                }

                case Type.Position:
                    if (value.nullable && code_offset + 4 > code_len)
                    {
                        nullable_skip = true;
                        break;
                    }
                    uint pos = br.ReadUInt32();
                    if (code_position.ContainsKey(pos))
                    {
                        datas.Add(new ParamData(Type.Position, pos, code_position[pos].ToString()));
                    }
                    else
                    {
                        throw new Exception("错误的跳转位置: " + pos + "!");
                    }
                    break;

                default:
                    break;
                }
                code_offset += (int)(fs.Position - temp_pos);
            }
            return(datas.ToArray());
        }
예제 #11
0
        /// <summary>
        /// 读取参数的实际值
        /// </summary>
        /// <param name="param">类型列表</param>
        /// <param name="codeLength">此指令长度</param>
        /// <param name="codeOffset">当前位置引用</param>
        /// <returns></returns>
        private List <ParamData> ReadParamData(ParamType[] param, int codeLength, ref int codeOffset)
        {
            Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
            List <string>    retn  = new List <string>();
            List <ParamData> datas = new List <ParamData>();
            int    count           = 0;
            bool   nullableSkip    = false;
            string dataStr         = "";

            foreach (var value in param)
            {
                DataType type = value.type;
                count++;
                var tempPos = fs.Position;
                switch (type)
                {
                case DataType.Byte:
                case DataType.Byte2:
                case DataType.Byte3:
                case DataType.Byte4:
                    if (value.nullable && codeOffset + (int)type > codeLength)
                    {
                        nullableSkip = true;
                        break;
                    }
                    var dataBytes = br.ReadBytes((int)type);
                    dataStr = ScriptUtil.Byte2Hex(dataBytes, false, true);
                    datas.Add(new ParamData(type, dataBytes, dataStr));
                    break;

                case DataType.UInt16:
                    if (value.nullable && codeOffset + 2 > codeLength)
                    {
                        nullableSkip = true;
                        break;
                    }
                    var dataUint16 = br.ReadUInt16();
                    dataStr = dataUint16.ToString();
                    datas.Add(new ParamData(type, dataUint16, dataStr));
                    break;

                case DataType.Int16:
                    if (value.nullable && codeOffset + 2 > codeLength)
                    {
                        nullableSkip = true;
                        break;
                    }
                    var dataInt16 = br.ReadInt16();
                    dataStr = dataInt16.ToString();
                    datas.Add(new ParamData(type, dataInt16, dataStr));
                    break;

                case DataType.UInt32:
                case DataType.Position:
                    if (value.nullable && codeOffset + 4 > codeLength)
                    {
                        nullableSkip = true;
                        break;
                    }
                    var dataUint32 = br.ReadUInt32();
                    dataStr = dataUint32.ToString();
                    datas.Add(new ParamData(type, dataUint32, dataStr));
                    break;

                case DataType.Int32:
                    if (value.nullable && codeOffset + 4 > codeLength)
                    {
                        nullableSkip = true;
                        break;
                    }
                    var dataInt32 = br.ReadInt32();
                    dataStr = dataInt32.ToString();
                    datas.Add(new ParamData(type, dataInt32, dataStr));
                    break;

                case DataType.StringUnicode:
                case DataType.StringSJIS:
                case DataType.StringUTF8:
                    if (type == DataType.StringUnicode)
                    {
                        dataStr = Encoding.Unicode.GetString(ReadStringDoubleEnd());
                    }
                    else if (type == DataType.StringSJIS)
                    {
                        dataStr = Encoding.GetEncoding("Shift-Jis").GetString(ReadStringSingleEnd());
                    }
                    else if (type == DataType.StringUTF8)
                    {
                        dataStr = Encoding.UTF8.GetString(ReadStringSingleEnd());
                    }
                    datas.Add(new ParamData(type, dataStr, dataStr));
                    break;

                case DataType.LenStringUnicode:
                case DataType.LenStringSJIS:
                    if (value.nullable && codeOffset + 2 > codeLength)
                    {
                        nullableSkip = true;
                        break;
                    }
                    int len = br.ReadUInt16();
                    if (type == DataType.LenStringUnicode)
                    {
                        dataStr = Encoding.Unicode.GetString(br.ReadBytes(len * 2));
                    }
                    else if (type == DataType.LenStringSJIS)
                    {
                        dataStr = Encoding.GetEncoding("Shift-Jis").GetString(br.ReadBytes(len * 2));
                    }
                    datas.Add(new ParamData(type, dataStr, dataStr));
                    break;

                default:
                    break;
                }
                codeOffset += (int)(fs.Position - tempPos);
                if (codeOffset > codeLength)
                {
                    throw new Exception("opcode参数数量错误! ");
                }
            }
            return(datas);
        }
예제 #12
0
        private CodeLine ReadCodeLine()
        {
            CodeLine code = new CodeLine(currentLine, (int)fs.Position);

            if (!gotoPosLine.ContainsKey((int)fs.Position))
            {
                // 位置 下标
                gotoPosLine.Add((int)fs.Position, currentLine);
            }

            int codeLength = 0;
            int codeOffset = 0;


            if (script.version == 2)
            {
                // [xx]   [xx]
                // opcode len
                code.opcodeIndex = br.ReadByte();
                codeLength       = br.ReadByte() * 2;
                codeOffset      += 2;
            }
            else if (script.version == 3)
            {
                // [xx xx] [xx]
                // len     opcode
                codeLength       = br.ReadUInt16() - 2;
                code.opcodeIndex = br.ReadByte();
                codeOffset++;
            }
            long savePosition = fs.Position;

            fs.Seek(-codeOffset, SeekOrigin.Current);
            code.bytes = br.ReadBytes(codeLength);
            fs.Seek(savePosition, SeekOrigin.Begin);

            if (!opcodeDict.ContainsKey(code.opcodeIndex))
            {
                throw new Exception("未知的opcode!");
            }
            code.opcode = opcodeDict[code.opcodeIndex].opcode;

            int      infoCount = 0;
            CodeInfo info      = null;

            if (script.version == 2)
            {
                info         = new CodeInfo(0);
                info.count   = 1;
                info.data    = new UInt16[1];
                info.data[0] = br.ReadUInt16();
                //fs.Seek(-2, SeekOrigin.Current);
                codeOffset += 2;
                code.info   = info;
            }
            else if (script.version == 3)
            {
                info = new CodeInfo(br.ReadByte());
                codeOffset++;
                infoCount = info.count;
                // END指令info.count需要减一
                if (code.opcode == "END")
                {
                    infoCount--;
                }
                else if (code.opcode == "LOG" && infoCount == 7)
                {
                    infoCount = 3;
                }

                while (codeLength - 2 < infoCount * 2)
                {
                    infoCount--;
                }
                info.data = new UInt16[infoCount];

                for (int i = 0; i < infoCount; i++)
                {
                    info.data[i] = br.ReadUInt16();
                    codeOffset  += 2;
                }
                code.info = info;
            }


            // 参数类型列表
            code.paramTypes = opcodeDict[code.opcodeIndex].param.ToArray();
            // 读取已知参数数据
            code.paramDatas = ReadParamData(code.paramTypes, codeLength, ref codeOffset);
            // 处理未知参数数据
            while (codeOffset + 1 < codeLength)
            {
                byte[] temp = br.ReadBytes(2);
                codeOffset += 2;
                code.paramDatas.Add(new ParamData(DataType.Byte2, temp, ScriptUtil.Byte2Hex(temp, false, true)));
            }
            if (codeOffset < codeLength)
            {
                byte[] temp = br.ReadBytes(1);
                codeOffset++;
                if (script.version == 2 && temp[0] == 0x00)
                {
                    // 最后多出的单字节,若为0x00则舍弃
                }
                else
                {
                    code.paramDatas.Add(new ParamData(DataType.Byte, temp, ScriptUtil.Byte2Hex(temp, false, true)));
                }
            }
            // 长度非偶数,最后会有补位
            if (codeLength % 2 != 0)
            {
                br.ReadByte();
            }

            // 判断是否含跳转
            foreach (var param in code.paramDatas)
            {
                if (param.type == DataType.Position)
                {
                    code.isPosition = true;
                    labelPos.Add((int)(uint)param.value);
                }
            }


            currentLine++;
            return(code);
        }