예제 #1
0
        static IEnumerable <CodeInstruction> LoadCurrentGame_Transpiler(IEnumerable <CodeInstruction> instructions, ILGenerator iLGenerator)
        {
            /* using (BinaryReader binaryReader = new BinaryReader(fileStream)) => Create lzstream and replace binaryReader.
             * set PerformanceMonitor.BeginStream to lzstream.
             * if (fileStream.Length != binaryReader.ReadInt64()) => Replace binaryReader.ReadInt64() to pass file length check.
             * fileStream.Seek((long)num2, SeekOrigin.Current); => Use lzstream.Read to seek forward
             * binaryReader.Dispose(); => Dispose lzstream before fileStream close.
             */
            try
            {
                var matcher = new CodeMatcher(instructions, iLGenerator)
                              .MatchForward(false, new CodeMatch(OpCodes.Newobj, AccessTools.Constructor(typeof(BinaryReader), new Type[] { typeof(FileStream) })))
                              .Set(OpCodes.Call, AccessTools.Method(typeof(PatchSave), "CreateBinaryReader"))
                              .MatchForward(false, new CodeMatch(OpCodes.Call, AccessTools.Method(typeof(PerformanceMonitor), "BeginStream")));

                if (matcher.IsValid)
                {
                    matcher.Set(OpCodes.Call, AccessTools.Method(typeof(PatchSave), "MonitorStream"));
                }

                matcher.Start().MatchForward(false, new CodeMatch(OpCodes.Callvirt, AccessTools.Method(typeof(BinaryReader), "ReadInt64")))
                .Set(OpCodes.Call, AccessTools.Method(typeof(PatchSave), "FileLengthRead"))
                .MatchForward(false, new CodeMatch(OpCodes.Callvirt, AccessTools.Method(typeof(System.IDisposable), "Dispose")))
                .Advance(1)
                .Insert(new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(PatchSave), "DisposeLzstream")))
                .MatchBack(false, new CodeMatch(OpCodes.Callvirt, AccessTools.Method(typeof(System.IO.Stream), "Seek")));
                if (matcher.IsValid)
                {
                    matcher.Set(OpCodes.Call, AccessTools.Method(typeof(PatchSave), "ReadSeek"));
                }
                matcher.Start()
                .MatchForward(false, new CodeMatch(OpCodes.Newobj, AccessTools.Constructor(typeof(GameSaveHeader))));
                if (matcher.IsValid)
                {
                    matcher.Set(OpCodes.Newobj, AccessTools.Constructor(typeof(CompressionGameSaveHeader))); //ReadHeader
                }
                EnableDecompress = true;
                return(matcher.InstructionEnumeration());
            }
            catch (Exception ex)
            {
                SaveUtil.logger.LogError("LoadCurrentGame_Transpiler failed. Mod version not compatible with game version.");
                SaveUtil.logger.LogError(ex);
            }
            return(instructions);
        }