Skip to content
Open
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
10 changes: 10 additions & 0 deletions UndertaleModLib/UndertaleData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,16 @@ public object this[Type resourceType]
/// </summary>
public bool ShortCircuit = true;

/// <summary>
/// Whether the data file loaded correctly
/// </summary>
public bool LoadedCorrectly = false;

/// <summary>
/// Whether the data file loaded correctly
/// </summary>
public Exception LoadingError = null;

/// <summary>
/// Whether the data file is from version GMS2.2.2.302
/// </summary>
Expand Down
69 changes: 44 additions & 25 deletions UndertaleModLib/UndertaleIO.cs
Original file line number Diff line number Diff line change
Expand Up @@ -195,31 +195,50 @@ public UndertaleChunk ReadUndertaleChunk()
public UndertaleData ReadUndertaleData()
{
UndertaleData data = new UndertaleData();
undertaleData = data;

resUpdate.Clear();

string name = ReadChars(4);
if (name != "FORM")
throw new IOException("Root chunk is " + name + " not FORM");
uint length = ReadUInt32();
data.FORM = new UndertaleChunkFORM();
DebugUtil.Assert(data.FORM.Name == name);
data.FORM.Length = length;

var lenReader = EnsureLengthFromHere(data.FORM.Length);
data.FORM.UnserializeChunk(this);
lenReader.ToHere();

SubmitMessage("Resolving resource IDs...");
foreach (UndertaleResourceRef res in resUpdate)
res.PostUnserialize(this);
resUpdate.Clear();

data.BuiltinList = new BuiltinList(data);
Decompiler.AssetTypeResolver.InitializeTypes(data);

return data;
try
{
undertaleData = data;

resUpdate.Clear();

string name = ReadChars(4);
if (name != "FORM")
throw new IOException("Root chunk is " + name + " not FORM");
uint length = ReadUInt32();
data.FORM = new UndertaleChunkFORM();
DebugUtil.Assert(data.FORM.Name == name);
data.FORM.Length = length;

var lenReader = EnsureLengthFromHere(data.FORM.Length);
data.FORM.UnserializeChunk(this);
lenReader.ToHere();

SubmitMessage("Resolving resource IDs...");
foreach (UndertaleResourceRef res in resUpdate)
res.PostUnserialize(this);
resUpdate.Clear();

data.BuiltinList = new BuiltinList(data);
Decompiler.AssetTypeResolver.InitializeTypes(data);

data.LoadedCorrectly = true;
return data;
}
catch (Exception e)
{
data.LoadingError = e;
SubmitMessage("Resolving resource IDs...");
foreach (UndertaleResourceRef res in resUpdate)
res.PostUnserialize(this);
resUpdate.Clear();

data.BuiltinList = new BuiltinList(data);
Decompiler.AssetTypeResolver.InitializeTypes(data);
if (data != null)
return data;
else
throw new Exception("Data is null?!");
}
}

internal void RequestResourceUpdate(UndertaleResourceRef res)
Expand Down
7 changes: 7 additions & 0 deletions UndertaleModTool/Converters/UndertaleCachedImageLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,13 @@ public static void Reset()

public static Bitmap CreateSpriteBitmap(Rectangle rect, in UndertaleTexturePageItem texture, int diffW = 0, int diffH = 0, bool isTile = false)
{
if (texture.TexturePage == null)
{
texture.TexturePage = new UndertaleEmbeddedTexture();
texture.TexturePage.TextureData = new UndertaleEmbeddedTexture.TexData();
ImageConverter conv = new ImageConverter();
texture.TexturePage.TextureData.TextureBlob = (byte[])conv.ConvertTo(new Bitmap(1, 1), typeof(byte[]));
}
using MemoryStream stream = new(texture.TexturePage.TextureData.TextureBlob);
Bitmap spriteBMP = new(rect.Width, rect.Height);

Expand Down
91 changes: 86 additions & 5 deletions UndertaleModTool/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1004,30 +1004,105 @@ private async Task LoadFile(string filename, bool preventClose = false)
DisposeGameData();
Highlighted = new DescriptionView("Welcome to UndertaleModTool!", "Double click on the items on the left to view them!");
OpenInTab(Highlighted);
String current_date_and_time = DateTime.Now.ToString("_\\M\\D\\Y_\\H\\M\\S_MM-dd-yyyy_HH-mm-ss");

Task t = Task.Run(() =>
{
bool hadWarnings = false;
bool loadedCorrectly = true;
Exception loadingException = null;
UndertaleData data = null;
try
{
using (var stream = new FileStream(filename, FileMode.Open, FileAccess.Read))
{
data = UndertaleIO.Read(stream, warning =>
{
this.ShowWarning(warning, "Loading warning");
File.AppendAllText(Path.Combine(ExePath, "log" + current_date_and_time + ".txt"), "\n" + warning);
hadWarnings = true;
}, message =>
{
FileMessageEvent?.Invoke(message);
});
}

UndertaleEmbeddedTexture.TexData.ClearSharedStream();
}
catch (Exception e)
{
this.ShowError("An error occured while trying to load:\n" + e.Message, "Load error");
loadingException = e;
}
if (data != null)
loadingException = data.LoadingError;
if (loadingException != null)
{
File.AppendAllText(Path.Combine(ExePath, "log" + current_date_and_time + ".txt"), "\n" + loadingException.Message);
/*
if (this.ShowQuestion("An error occured while trying to load, please see log" + current_date_and_time + ".txt for more details\n\nSubmit GitHub issue now?") == MessageBoxResult.Yes)
{
string GameName = (data?.GeneralInfo?.DisplayName != null ? data?.GeneralInfo?.DisplayName.Content : "[GAME NAME UNOBTAINABLE]");
string localfilename = Path.GetFileName(filename);
string GameMD5 = GenerateMD5(filename);
string SteamURL = "I will provide a link to the game below.";
int SteamID = 0;
if (data != null)
{
SteamID = Math.Abs(data.GeneralInfo.SteamAppID);
if (SteamID > 0)
SteamURL = "This game can be found at https://store.steampowered.com/app/" + SteamID.ToString() + "/ or at https://steamdb.info/app/" + SteamID.ToString() + "/";
Math.Abs(data.GeneralInfo.SteamAppID).ToString();
}
string OSDescription = System.Runtime.InteropServices.RuntimeInformation.OSDescription;
string ProcessArchitecture = System.Runtime.InteropServices.RuntimeInformation.ProcessArchitecture.ToString();
string OSArchitecture = System.Runtime.InteropServices.RuntimeInformation.OSArchitecture.ToString();
string FrameworkDescription = System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription;
var name = (from x in new System.Management.ManagementObjectSearcher("SELECT Caption FROM Win32_OperatingSystem").Get().Cast<System.Management.ManagementObject>()
select x.GetPropertyValue("Caption")).FirstOrDefault();
string OSName = (name != null ? name.ToString() : "Unknown");
string TitleDescription = Uri.EscapeDataString(@"The game """ + GameName + @""" failed to load in UndertaleModTool (commit " + GitVersion.GetGitVersion() + ")");
string GameDataIfAvailable = "";
if (data != null)
{
DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeSeconds((long)data.GeneralInfo.Timestamp);
DateTimeOffset dateTimeOffset2 = DateTimeOffset.FromUnixTimeMilliseconds((long)data.GeneralInfo.Timestamp);
GameDataIfAvailable = "\nDisplay Name: " + data.GeneralInfo.DisplayName.ToString()
+ "\nFile Name: " + data.GeneralInfo.FileName.Content
+ "\nName: " + data.GeneralInfo.Name.Content
+ "\nBytecode Version: " + data.GeneralInfo.BytecodeVersion.ToString()
+ "\nGMS version: " + data.GeneralInfo.Major.ToString() + "." + data.GeneralInfo.Minor.ToString() + "." + data.GeneralInfo.Release.ToString() + "." + data.GeneralInfo.Build.ToString()
+ "\nTimestamp: " + data.GeneralInfo.Timestamp.ToString() + " (" + dateTimeOffset.ToString() + ")"
+ "\n";
}
string BodyDescription = Uri.EscapeDataString(@"### Describe the bug
The game """ + GameName + @""" (File name: " + localfilename + ", MD5: " + GameMD5 + @") failed to load.
"
+ GameDataIfAvailable
+
@"
See log attached:
```
"
+
File.ReadAllText(Path.Combine(ExePath, "log" + current_date_and_time + ".txt"))
+
@"
```

### Reproducing steps
This can be reproduced by attempting to load the file described. " + SteamURL + @"

### Setup Details
" +
"\nCommit number: " + GitVersion.GetGitVersion() +
"\nOS Name: " + OSName +
"\nOS Details: " + OSDescription +
"\nProcess Architecture: " + ProcessArchitecture +
"\nPlatform Architecture: " + OSArchitecture +
"\nFramework Description: " + FrameworkDescription +
@"");
string BaseURL = "https://github.com/krzys-h/UndertaleModTool/issues/new?" + "title=" + TitleDescription + "&body=" + BodyDescription + "&labels=bug";
ScriptOpenURL(BaseURL);
}
*/
}

Dispatcher.Invoke(async () =>
Expand All @@ -1040,9 +1115,15 @@ private async Task LoadFile(string filename, bool preventClose = false)
CanSave = false;
CanSafelySave = false;
}
else if (hadWarnings)
else if (!(data.LoadedCorrectly))
{
this.ShowError("Something went wrong while loading. Data loss WILL occur when trying to save, probably to a severe degree. As a result, saving has been disabled.\n\nYou may still view the data file loaded, but there is likely to be missing data and unexpected errors may occur.\n\nPlease see log" + current_date_and_time + ".txt for more details regarding what errors happened during loading.", "Loading problems");
CanSave = false;
CanSafelySave = false;
}
else if (hadWarnings && data.LoadedCorrectly)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't data.LoadedCorrectly redundant here because it's an else if?

{
this.ShowWarning("Warnings occurred during loading. Data loss will likely occur when trying to save!", "Loading problems");
this.ShowWarning("Warnings occurred during loading. Data loss will likely occur when trying to save! Please see log" + current_date_and_time + ".txt for more details", "Loading problems");
CanSave = true;
CanSafelySave = false;
}
Expand Down