コード例 #1
0
        public void Save(Stream output)
        {
            MemoryStream memory = new MemoryStream();
            UnrealStream stream = new UnrealStream(memory, false, this.Version);

            memory.WriteUInt32(this.Version);

            this.Serialize(stream);

            if (this.Version >= 27)
            {
                memory.Position = 0;
                uint   checksum = 0;
                byte[] data     = new byte[1024];
                while (memory.Position < memory.Length)
                {
                    int read = memory.Read(data, 0, 1024);
                    checksum = CRC32.Compute(data, 0, read, checksum);
                }

                this.Checksum = checksum;
                memory.WriteUInt32(checksum);
            }

            // copy out
            {
                memory.Position = 0;
                byte[] data = new byte[1024];
                while (memory.Position < memory.Length)
                {
                    int read = memory.Read(data, 0, 1024);
                    output.Write(data, 0, read);
                }
            }
        }
コード例 #2
0
        public static SaveFileGame2 Load(Stream input, string fileName = null, MEGame expectedGame = MEGame.Unknown)
        {
            SaveFileGame2 save = new SaveFileGame2();

            save.Version = input.ReadUInt32();

            if (fileName != null)
            {
                // Setup save params
                save.FileName = fileName;

                var sgName = Path.GetFileNameWithoutExtension(fileName);
                if (sgName.StartsWith("Save_"))
                {
                    // Parse number
                    var numStr = sgName.Substring(sgName.IndexOf("_") + 1);
                    if (int.TryParse(numStr, out var saveNum))
                    {
                        save.SaveNumber   = saveNum;
                        save.SaveGameType = ESFXSaveGameType.SaveGameType_Manual;
                    }
                }
                else if (sgName.StartsWith("AutoSave"))
                {
                    save.SaveGameType = ESFXSaveGameType.SaveGameType_Auto;
                }
                else if (sgName.StartsWith("ChapterSave"))
                {
                    save.SaveGameType = ESFXSaveGameType.SaveGameType_Chapter;
                }
                else if (sgName.StartsWith("QuickSave"))
                {
                    save.SaveGameType = ESFXSaveGameType.SaveGameType_Quick;
                }
            }

            if (save.Version != 29 && save.Version != 30)
            {
                throw new FormatException("Save version not supported. This parser only supports ME2 (29) and LE2 (30)");
            }

            if (save.Version == 29)
            {
                save.Game = MEGame.ME2;
            }
            if (save.Version == 30)
            {
                save.Game = MEGame.LE2;
            }
            if (expectedGame != MEGame.Unknown && expectedGame != save.Game)
            {
                throw new Exception($@"Sanity check failure: Save loader expected save for {expectedGame} but save appears to be for {{Game}}");
            }

            UnrealStream stream = new UnrealStream(input, true, save.Version);

            save.Serialize(stream);

            save.BindableDebugName = save.DebugName;

            if (save.Version >= 27)
            {
                // sanity check, cos if we read a strange crc it'll break anyway
                if (input.Position != input.Length - 4)
                {
                    throw new FormatException("bad checksum position");
                }

                save.Checksum = input.ReadUInt32();
            }

            // did we consume the entire save file?
            if (input.Position != input.Length)
            {
                throw new FormatException("did not consume entire file");
            }

            return(save);
        }