/// <inheritdoc /> public void Unserialize(UndertaleReader reader) { uint len = reader.ReadUInt32(); Data = reader.ReadBytes((int)len); Util.DebugUtil.Assert(Data.Length == len); }
public void ReadData(UndertaleReader reader, int length) { if (_Length != 0 && _Length != length) throw new UndertaleSerializationException("Failed to compute length of shader data"); _Length = (uint)length; Data = reader.ReadBytes(length); }
public void Unserialize(UndertaleReader reader) { DisableDebugger = reader.ReadByte() != 0 ? true : false; BytecodeVersion = reader.ReadByte(); Unknown = reader.ReadUInt16(); Filename = reader.ReadUndertaleString(); Config = reader.ReadUndertaleString(); LastObj = reader.ReadUInt32(); LastTile = reader.ReadUInt32(); GameID = reader.ReadUInt32(); Unknown1 = reader.ReadUInt32(); Unknown2 = reader.ReadUInt32(); Unknown3 = reader.ReadUInt32(); Unknown4 = reader.ReadUInt32(); Name = reader.ReadUndertaleString(); Major = reader.ReadUInt32(); Minor = reader.ReadUInt32(); Release = reader.ReadUInt32(); Build = reader.ReadUInt32(); DefaultWindowWidth = reader.ReadUInt32(); DefaultWindowHeight = reader.ReadUInt32(); Info = (InfoFlags)reader.ReadUInt32(); LicenseMD5 = reader.ReadBytes(16); LicenseCRC32 = reader.ReadUInt32(); Timestamp = reader.ReadUInt64(); DisplayName = reader.ReadUndertaleString(); ActiveTargets1 = reader.ReadUInt32(); ActiveTargets2 = reader.ReadUInt32(); FunctionClassifications1 = reader.ReadUInt32(); FunctionClassifications2 = reader.ReadUInt32(); SteamAppID = reader.ReadInt32(); DebuggerPort = reader.ReadUInt32(); RoomOrder = reader.ReadUndertaleObject <UndertaleSimpleResourcesList <UndertaleRoom, UndertaleChunkROOM> >(); if (Major >= 2) { GMS2RandomUID = reader.ReadBytes(40); GMS2FPS = reader.ReadSingle(); GMS2AllowStatistics = reader.ReadBoolean(); GMS2GameGUID = reader.ReadBytes(16); } reader.undertaleData.UnsupportedBytecodeVersion = BytecodeVersion < 14 || BytecodeVersion > 17; reader.Bytecode14OrLower = BytecodeVersion <= 14; }
internal override void UnserializeChunk(UndertaleReader reader) { if (reader.undertaleData.GeneralInfo?.BytecodeVersion >= 17) { /* This code performs four checks to identify GM2022.2. * First, as you've seen, is the bytecode version. * Second, we assume it is. If there are no Glyphs, we are vindicated by the impossibility of null values there. * Third, we check that the Glyph Length is less than the chunk length. If it's going outside the chunk, that means * that the length was misinterpreted. * Fourth, in case of a terrible fluke causing this to appear valid erroneously, we verify that each pointer leads into the next. * And if someone builds their game so the first pointer is absolutely valid length data and the next font is valid glyph data- * screw it, call Jacky720 when someone constructs that and you want to mod it. * Maybe try..catch on the whole shebang? */ uint positionToReturn = reader.Position; if (reader.ReadUInt32() > 0) // Font count { uint firstFontPointer = reader.ReadUInt32(); reader.Position = firstFontPointer + 48; // There are 48 bytes of existing metadata. uint glyphsLength = reader.ReadUInt32(); reader.undertaleData.GMS2022_2 = true; if ((glyphsLength * 4) > this.Length) { reader.undertaleData.GMS2022_2 = false; } else if (glyphsLength != 0) { List <uint> glyphPointers = new List <uint>(); for (uint i = 0; i < glyphsLength; i++) { glyphPointers.Add(reader.ReadUInt32()); } foreach (uint pointer in glyphPointers) { if (reader.Position != pointer) { reader.undertaleData.GMS2022_2 = false; break; } reader.Position += 14; ushort kerningLength = reader.ReadUInt16(); reader.Position += (uint)4 * kerningLength; // combining read/write would apparently break } } } reader.Position = positionToReturn; } base.UnserializeChunk(reader); Padding = reader.ReadBytes(512); }
internal override void UnserializeChunk(UndertaleReader reader) { base.UnserializeChunk(reader); // Strange data for each extension, some kind of unique identifier based on // the product ID for each of them productIdData = new List <byte[]>(); for (int i = 0; i < List.Count; i++) { productIdData.Add(reader.ReadBytes(16)); } }
internal override void UnserializeChunk(UndertaleReader reader) { base.UnserializeChunk(reader); // Strange data for each extension, some kind of unique identifier based on // the product ID for each of them productIdData = new List <byte[]>(); if (reader.undertaleData.GeneralInfo?.Major >= 2 || (reader.undertaleData.GeneralInfo?.Major == 1 && reader.undertaleData.GeneralInfo?.Build >= 9999)) { for (int i = 0; i < List.Count; i++) { productIdData.Add(reader.ReadBytes(16)); } } }
internal override void UnserializeChunk(UndertaleReader reader) { base.UnserializeChunk(reader); // Strange data for each extension, some kind of unique identifier based on // the product ID for each of them productIdData = new List <byte[]>(); // NOTE: I do not know if 1773 is the earliest version which contains product IDs. if (reader.undertaleData.GeneralInfo?.Major >= 2 || (reader.undertaleData.GeneralInfo?.Major == 1 && reader.undertaleData.GeneralInfo?.Build >= 1773) || (reader.undertaleData.GeneralInfo?.Major == 1 && reader.undertaleData.GeneralInfo?.Build == 1539)) { for (int i = 0; i < List.Count; i++) { productIdData.Add(reader.ReadBytes(16)); } } }
public void Unserialize(UndertaleReader reader) { DisableDebugger = reader.ReadByte() != 0 ? true : false; BytecodeVersion = reader.ReadByte(); Unknown = reader.ReadUInt16(); Filename = reader.ReadUndertaleString(); Config = reader.ReadUndertaleString(); LastObj = reader.ReadUInt32(); LastTile = reader.ReadUInt32(); GameID = reader.ReadUInt32(); byte[] GuidData = reader.ReadBytes(16); DirectPlayGuid = new Guid(GuidData); Name = reader.ReadUndertaleString(); Major = reader.ReadUInt32(); Minor = reader.ReadUInt32(); Release = reader.ReadUInt32(); Build = reader.ReadUInt32(); DefaultWindowWidth = reader.ReadUInt32(); DefaultWindowHeight = reader.ReadUInt32(); Info = (InfoFlags)reader.ReadUInt32(); LicenseMD5 = reader.ReadBytes(16); LicenseCRC32 = reader.ReadUInt32(); Timestamp = reader.ReadUInt64(); DisplayName = reader.ReadUndertaleString(); ActiveTargets = reader.ReadUInt64(); FunctionClassifications = (FunctionClassification)reader.ReadUInt64(); SteamAppID = reader.ReadInt32(); DebuggerPort = reader.ReadUInt32(); RoomOrder = reader.ReadUndertaleObject <UndertaleSimpleResourcesList <UndertaleRoom, UndertaleChunkROOM> >(); if (Major >= 2) { // Begin parsing random UID, and verify it based on original algorithm GMS2RandomUID = new List <long>(); Random random = new Random((int)(Timestamp & 4294967295L)); long firstRandom = (long)random.Next() << 32 | (long)random.Next(); if (reader.ReadInt64() != firstRandom) { //throw new IOException("Unexpected random UID"); } long infoNumber = (long)(Timestamp - 1000); ulong temp = (ulong)infoNumber; temp = ((temp << 56 & 18374686479671623680UL) | (temp >> 8 & 71776119061217280UL) | (temp << 32 & 280375465082880UL) | (temp >> 16 & 1095216660480UL) | (temp << 8 & 4278190080UL) | (temp >> 24 & 16711680UL) | (temp >> 16 & 65280UL) | (temp >> 32 & 255UL)); infoNumber = (long)temp; infoNumber ^= firstRandom; infoNumber = ~infoNumber; infoNumber ^= ((long)GameID << 32 | (long)GameID); infoNumber ^= ((long)(DefaultWindowWidth + (int)Info) << 48 | (long)(DefaultWindowHeight + (int)Info) << 32 | (long)(DefaultWindowHeight + (int)Info) << 16 | (long)(DefaultWindowWidth + (int)Info)); infoNumber ^= BytecodeVersion; int infoLocation = (int)(Math.Abs((int)(Timestamp & 65535L) / 7 + (GameID - DefaultWindowWidth) + RoomOrder.Count) % 4); for (int i = 0; i < 4; i++) { if (i == infoLocation) { long curr = reader.ReadInt64(); curr = infoNumber; GMS2RandomUID.Add(curr); } else { int first = reader.ReadInt32(); int second = reader.ReadInt32(); first = random.Next(); second = random.Next(); GMS2RandomUID.Add(((long)first << 32) | (long)second); } } GMS2FPS = reader.ReadSingle(); GMS2AllowStatistics = reader.ReadBoolean(); GMS2GameGUID = reader.ReadBytes(16); } reader.undertaleData.UnsupportedBytecodeVersion = BytecodeVersion < 14 || BytecodeVersion > 17; reader.Bytecode14OrLower = BytecodeVersion <= 14; }
internal override void UnserializeChunk(UndertaleReader reader) { base.UnserializeChunk(reader); Padding = reader.ReadBytes(512); }