Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

2022.3 detection, cleaner 2022.2 detection #821

Merged
merged 3 commits into from
Apr 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions UndertaleModLib/Models/UndertaleEmbeddedTexture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,16 @@ public class UndertaleEmbeddedTexture : UndertaleNamedResource
public UndertaleString Name { get; set; }
public uint Scaled { get; set; } = 0;
public uint GeneratedMips { get; set; }
public uint TextureBlockSize { get; set; }
public TexData TextureData { get; set; } = new TexData();

public void Serialize(UndertaleWriter writer)
{
writer.Write(Scaled);
if (writer.undertaleData.GeneralInfo.Major >= 2)
writer.Write(GeneratedMips);
if (writer.undertaleData.GM2022_3)
writer.Write(TextureBlockSize);
writer.WriteUndertaleObjectPointer(TextureData);
}

Expand All @@ -33,6 +36,8 @@ public void Unserialize(UndertaleReader reader)
Scaled = reader.ReadUInt32();
if (reader.undertaleData.GeneralInfo.Major >= 2)
GeneratedMips = reader.ReadUInt32();
if (reader.undertaleData.GM2022_3)
TextureBlockSize = reader.ReadUInt32();
TextureData = reader.ReadUndertaleObjectPointer<TexData>();
}

Expand Down
38 changes: 2 additions & 36 deletions UndertaleModLib/Models/UndertaleFont.cs
Original file line number Diff line number Diff line change
Expand Up @@ -140,43 +140,9 @@ public void Unserialize(UndertaleReader reader)
if (reader.undertaleData.GeneralInfo?.BytecodeVersion >= 17)
{
AscenderOffset = reader.ReadInt32();
// TODO: Add a second check so it doesn't iterate over every font twice (just the first should do)
if (!reader.undertaleData.GMS2022_2)
{
/* This code performs three 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, 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;
reader.ReadUInt32(); // We assume this is the ascender
uint glyphsLength = reader.ReadUInt32();
reader.undertaleData.GMS2022_2 = true;
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)2 * kerningLength; // combining read/write would apparently break
}
}
reader.Position = positionToReturn;
}
if (reader.undertaleData.GMS2022_2)
Ascender = reader.ReadUInt32();
}
if (reader.undertaleData.GMS2022_2)
Ascender = reader.ReadUInt32();
Glyphs = reader.ReadUndertaleObject<UndertalePointerList<Glyph>>();
}

Expand Down
59 changes: 59 additions & 0 deletions UndertaleModLib/UndertaleChunks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,44 @@ internal override void SerializeChunk(UndertaleWriter writer)

internal override void UnserializeChunk(UndertaleReader reader)
{
if (reader.undertaleData.GeneralInfo?.BytecodeVersion >= 17)
{
/* This code performs three 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, 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 != 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);
Expand Down Expand Up @@ -505,6 +543,27 @@ internal override void SerializeChunk(UndertaleWriter writer)

internal override void UnserializeChunk(UndertaleReader reader)
{
// Detect GM2022.3
if (reader.undertaleData.GMS2_3)
{
uint positionToReturn = reader.Position;
uint texCount = reader.ReadUInt32();
if (texCount == 1) // If no textures exist, this could false positive.
{
reader.Position += 16; // Jump to either padding or length, depending on version
if (reader.ReadUInt32() > 0) // Check whether it's padding or length
reader.undertaleData.GM2022_3 = true;
}
else if (texCount > 1)
{
uint firstTex = reader.ReadUInt32();
uint secondTex = reader.ReadUInt32();
if (firstTex + 16 == secondTex)
reader.undertaleData.GM2022_3 = true;
}
reader.Position = positionToReturn;
}

base.UnserializeChunk(reader);

// texture blobs
Expand Down
1 change: 1 addition & 0 deletions UndertaleModLib/UndertaleData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ public class UndertaleData
public bool UseBZipFormat = false;
public bool GMS2022_1 = false;
public bool GMS2022_2 = false;
public bool GM2022_3 = false;
public ToolInfo ToolInfo = new ToolInfo();
public int PaddingAlignException = -1;

Expand Down