diff --git a/AM2RModPacker/ModPacker.Designer.cs b/AM2RModPacker/ModPacker.Designer.cs
index 751569e..23e4854 100644
--- a/AM2RModPacker/ModPacker.Designer.cs
+++ b/AM2RModPacker/ModPacker.Designer.cs
@@ -12,7 +12,7 @@ public partial class ModPacker : Form
profile = new ModProfileXML();
Title = "AM2R ModPacker " + version;
- // Currently broken as I don't know how to do this from Rider
+ //TODO: Currently broken as I don't know how to do this from Rider
//Icon = Icon.FromResource("icon64.ico");
MinimumSize = new Size(550, 400);
diff --git a/AM2RModPacker/ModPacker.cs b/AM2RModPacker/ModPacker.cs
index 7efbc1c..f696937 100644
--- a/AM2RModPacker/ModPacker.cs
+++ b/AM2RModPacker/ModPacker.cs
@@ -213,6 +213,15 @@ public partial class ModPacker : Form
MessageBox.Show("Name contains invalid characters! These characters are not allowed:\n" + String.Join("\n", Path.GetInvalidFileNameChars()));
return;
}
+
+ // Verify 1.1
+ var result11 = Core.CheckIfZipIsAM2R11(originalPath);
+ if (result11 != IsZipAM2R11ReturnCodes.Successful)
+ {
+ MessageBox.Show("AM2R 1.1 zip is invalid! Error code: " + result11);
+ AbortPatch();
+ return;
+ }
createLabel.Visible = true;
createLabel.Text = "Packaging mod(s)... This could take a while!";
diff --git a/AM2RModPackerLib/Core.cs b/AM2RModPackerLib/Core.cs
index 4c8ce6d..1b0037f 100644
--- a/AM2RModPackerLib/Core.cs
+++ b/AM2RModPackerLib/Core.cs
@@ -14,6 +14,18 @@ public enum ProfileOperatingSystems
Mac
}
+///
+/// An enum, that has possible return codes for .
+///
+public enum IsZipAM2R11ReturnCodes
+{
+ Successful,
+ MissingOrInvalidAM2RExe,
+ MissingOrInvalidD3DX943Dll,
+ MissingOrInvalidDataWin,
+ GameIsInASubfolder
+}
+
public static class Core
{
public static readonly string Version = "2.0.3";
@@ -53,21 +65,7 @@ public static class Core
if (Directory.Exists(tempModPath + "/AM2R"))
tempModPath += "/AM2R";
-
- // Verify 1.1 with an MD5. If it does not match, exit cleanly and provide a warning window.
- try
- {
- // TODO: dont. do what launcher does
- string newMD5 = CalculateMD5(tempOriginalPath + "/data.win");
-
- if (newMD5 != originalMD5)
- return (false, "1.1 data.win does not meet MD5 checksum! Mod packaging aborted.\n1.1 MD5: " + originalMD5 + "\nYour MD5: " + newMD5);
- }
- catch (FileNotFoundException)
- {
- return (false, "data.win not found! Are you sure you selected AM2R 1.1? Mod packaging aborted.");
- }
-
+
switch (profile.OperatingSystem)
{
// Create AM2R.exe and data.win patches
@@ -259,6 +257,70 @@ public static class Core
}
}
+ // Taken from AM2RLauncher
+ ///
+ /// Checks if a Zip file is a valid AM2R_1.1 zip.
+ ///
+ /// Full Path to the Zip file to validate.
+ /// detailing the result
+ public static IsZipAM2R11ReturnCodes CheckIfZipIsAM2R11(string zipPath)
+ {
+ const string d3dHash = "86e39e9161c3d930d93822f1563c280d";
+ const string dataWinHash = "f2b84fe5ba64cb64e284be1066ca08ee";
+ const string am2rHash = "15253f7a66d6ea3feef004ebbee9b438";
+ string tmpPath = Path.GetTempPath() + Path.GetFileNameWithoutExtension(zipPath);
+
+ // Clean up in case folder exists already
+ if (Directory.Exists(tmpPath))
+ Directory.Delete(tmpPath, true);
+ Directory.CreateDirectory(tmpPath);
+
+ // Open archive
+ ZipArchive am2rZip = ZipFile.OpenRead(zipPath);
+
+
+ // Check if exe exists anywhere
+ ZipArchiveEntry am2rExe = am2rZip.Entries.FirstOrDefault(x => x.FullName.Contains("AM2R.exe"));
+ if (am2rExe == null)
+ return IsZipAM2R11ReturnCodes.MissingOrInvalidAM2RExe;
+
+ // Check if it's not in a subfolder. if it'd be in a subfolder, fullname would be "folder/AM2R.exe"
+ if (am2rExe.FullName != "AM2R.exe")
+ return IsZipAM2R11ReturnCodes.GameIsInASubfolder;
+
+ // Check validity
+ am2rExe.ExtractToFile($"{tmpPath}/{am2rExe.FullName}");
+ if (CalculateMD5($"{tmpPath}/{am2rExe.FullName}") != am2rHash)
+ return IsZipAM2R11ReturnCodes.MissingOrInvalidAM2RExe;
+
+
+ // Check if data.win exists / is valid
+ ZipArchiveEntry dataWin = am2rZip.Entries.FirstOrDefault(x => x.FullName == "data.win");
+ if (dataWin == null)
+ return IsZipAM2R11ReturnCodes.MissingOrInvalidDataWin;
+
+ dataWin.ExtractToFile($"{tmpPath}/{dataWin.FullName}");
+ if (CalculateMD5($"{tmpPath}/{dataWin.FullName}") != dataWinHash)
+ return IsZipAM2R11ReturnCodes.MissingOrInvalidDataWin;
+
+
+ // Check if d3d.dll exists / is valid
+ ZipArchiveEntry d3dx = am2rZip.Entries.FirstOrDefault(x => x.FullName == "D3DX9_43.dll");
+ if (d3dx == null)
+ return IsZipAM2R11ReturnCodes.MissingOrInvalidD3DX943Dll;
+
+ d3dx.ExtractToFile($"{tmpPath}/{d3dx.FullName}");
+ if (CalculateMD5($"{tmpPath}/{d3dx.FullName}") != d3dHash)
+ return IsZipAM2R11ReturnCodes.MissingOrInvalidD3DX943Dll;
+
+
+ // Clean up
+ Directory.Delete(tmpPath, true);
+
+ // If we didn't exit before, everything is fine
+ return IsZipAM2R11ReturnCodes.Successful;
+ }
+
public static string CalculateMD5(string filename)
{
using var stream = File.OpenRead(filename);