Create lib project + todos

pull/9/head
Miepee 4 years ago
parent 5f6d7f1c22
commit 697b5c5dce

@ -5,6 +5,8 @@ VisualStudioVersion = 16.0.28803.156
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AM2RModPacker", "AM2RModPacker\AM2RModPacker.csproj", "{13E58D3E-D34E-4354-B5D3-AC43B05E7212}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AM2RModPackerLib", "AM2RModPackerLib\AM2RModPackerLib.csproj", "{9FC86440-2F54-436C-A71C-50429D7CA0B9}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -15,6 +17,10 @@ Global
{13E58D3E-D34E-4354-B5D3-AC43B05E7212}.Debug|Any CPU.Build.0 = Debug|Any CPU
{13E58D3E-D34E-4354-B5D3-AC43B05E7212}.Release|Any CPU.ActiveCfg = Release|Any CPU
{13E58D3E-D34E-4354-B5D3-AC43B05E7212}.Release|Any CPU.Build.0 = Release|Any CPU
{9FC86440-2F54-436C-A71C-50429D7CA0B9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9FC86440-2F54-436C-A71C-50429D7CA0B9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9FC86440-2F54-436C-A71C-50429D7CA0B9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9FC86440-2F54-436C-A71C-50429D7CA0B9}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

@ -5,11 +5,6 @@
<ItemGroup>
<EmbeddedResource Include="icon64.ico" />
<Folder Include="utilities" />
<Content Include="utilities/**">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
</Content>
</ItemGroup>
<ItemGroup>
@ -27,4 +22,8 @@
</Compile>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\AM2RModPackerLib\AM2RModPackerLib.csproj" />
</ItemGroup>
</Project>

@ -12,7 +12,7 @@ public partial class ModPacker : Form
profile = new ModProfileXML("", 1, "", "", "", false, "", false, false, ""); // (1, "", "", false, "default", false, false);
localPath =
Title = "AM2R ModPacker " + VERSION;
Title = "AM2R ModPacker " + version;
// Currently broken as I don't know how to do this from Rider
//Icon = Icon.FromResource("icon64.ico");

@ -3,17 +3,17 @@ using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Security.Cryptography;
using System.Text.RegularExpressions;
using AM2RModPacker.XML;
using AM2RModPackerLib;
using AM2RModPackerLib.XML;
using Eto.Forms;
namespace AM2RModPacker;
public partial class ModPacker : Form
{
private const string VERSION = "2.0.3";
private const string ORIGINAL_MD5 = "f2b84fe5ba64cb64e284be1066ca08ee";
private static readonly string version = Core.Version;
private const string originalMD5 = "f2b84fe5ba64cb64e284be1066ca08ee";
private bool isOriginalLoaded, isModLoaded, isApkLoaded, isLinuxLoaded;
// TODO: do not get current directory, wont end well
private readonly string localPath = Directory.GetCurrentDirectory();
@ -23,6 +23,7 @@ public partial class ModPacker : Form
private readonly ModProfileXML profile;
private readonly FileFilter zipFileFilter = new FileFilter("zip archives (*.zip)", ".zip");
private readonly FileFilter apkFileFilter = new FileFilter("Android application packages (*.apk)", ".apk");
#region Eto events
private void CustomSaveCheckBoxChecked_Changed(object sender, EventArgs e)
@ -32,19 +33,17 @@ public partial class ModPacker : Form
UpdateCreateButton();
}
private void ApkButton_Click(object sender, EventArgs e)
private void ApkCheckBoxCheckedChanged(object sender, EventArgs e)
{
// Open window to select modded AM2R APK
(isApkLoaded, apkPath) = SelectFile("Please select your custom AM2R .apk", "android application packages (*.apk)|*.apk");
apkLabel.Visible = isApkLoaded;
apkButton.Enabled = apkCheckBox.Checked.Value;
UpdateCreateButton();
}
private void ApkCheckBoxCheckedChanged(object sender, EventArgs e)
private void ApkButton_Click(object sender, EventArgs e)
{
apkButton.Enabled = apkCheckBox.Checked.Value;
// Open window to select modded AM2R APK
(isApkLoaded, apkPath) = SelectFile("Please select your custom AM2R .apk", apkFileFilter);
apkLabel.Visible = isApkLoaded;
UpdateCreateButton();
}
@ -58,9 +57,7 @@ public partial class ModPacker : Form
{
// Open window to select modded Linux .zip
(isLinuxLoaded, linuxPath) = SelectFile("Please select your custom Linux AM2R .zip", zipFileFilter);
linuxLabel.Visible = isLinuxLoaded;
UpdateCreateButton();
}
@ -68,9 +65,7 @@ public partial class ModPacker : Form
{
// Open window to select AM2R 1.1
(isOriginalLoaded, originalPath) = SelectFile("Please select AM2R_11.zip", zipFileFilter);
originalZipLabel.Visible = isOriginalLoaded;
UpdateCreateButton();
}
@ -78,9 +73,7 @@ public partial class ModPacker : Form
{
// Open window to select modded AM2R
(isModLoaded, modPath) = SelectFile("Please select your custom AM2R .zip", zipFileFilter);
modZipLabel.Visible = isModLoaded;
UpdateCreateButton();
}
@ -101,6 +94,7 @@ public partial class ModPacker : Form
createLabel.Visible = true;
createLabel.Text = "Packaging mod(s)... This could take a while!";
// TODO: move most of this into seperate method?
string output;
using (var saveFile = new SaveFileDialog { Title = "Save Windows mod profile", Filters = { zipFileFilter } })
@ -135,6 +129,7 @@ public partial class ModPacker : Form
CreateModPack("Linux", linuxPath, output);
}
//TODO: mac
createLabel.Text = "Mod package(s) created!";
}
@ -142,6 +137,7 @@ public partial class ModPacker : Form
private void CreateModPack(string operatingSystem, string input, string output)
{
// TODO: go over thhis
LoadProfileParameters(operatingSystem);
// Cleanup in case of previous errors
@ -181,12 +177,13 @@ public partial class ModPacker : Form
// Verify 1.1 with an MD5. If it does not match, exit cleanly and provide a warning window.
try
{
string newMD5 = CalculateMD5(tempOriginalPath + "/data.win");
// TODO: dont. do what launcher does
string newMD5 = Core.CalculateMD5(tempOriginalPath + "/data.win");
if (newMD5 != ORIGINAL_MD5)
if (newMD5 != originalMD5)
{
// Show error box
MessageBox.Show("1.1 data.win does not meet MD5 checksum! Mod packaging aborted.\n1.1 MD5: " + ORIGINAL_MD5 + "\nYour MD5: " + newMD5, "Error", MessageBoxButtons.OK, MessageBoxType.Error);
MessageBox.Show("1.1 data.win does not meet MD5 checksum! Mod packaging aborted.\n1.1 MD5: " + originalMD5 + "\nYour MD5: " + newMD5, "Error", MessageBoxButtons.OK, MessageBoxType.Error);
AbortPatch();
@ -222,13 +219,13 @@ public partial class ModPacker : Form
if (profile.UsesYYC)
{
CreatePatch(tempOriginalPath + "/data.win", tempModPath + "/AM2R.exe", tempProfilePath + "/AM2R.xdelta");
Core.CreatePatch(tempOriginalPath + "/data.win", tempModPath + "/AM2R.exe", tempProfilePath + "/AM2R.xdelta");
}
else
{
CreatePatch(tempOriginalPath + "/data.win", tempModPath + "/data.win", tempProfilePath + "/data.xdelta");
Core.CreatePatch(tempOriginalPath + "/data.win", tempModPath + "/data.win", tempProfilePath + "/data.xdelta");
CreatePatch(tempOriginalPath + "/AM2R.exe", tempModPath + "/AM2R.exe", tempProfilePath + "/AM2R.xdelta");
Core.CreatePatch(tempOriginalPath + "/AM2R.exe", tempModPath + "/AM2R.exe", tempProfilePath + "/AM2R.xdelta");
}
}
else if (profile.OperatingSystem == "Linux")
@ -249,8 +246,8 @@ public partial class ModPacker : Form
AbortPatch();
}
CreatePatch(tempOriginalPath + "/data.win", tempModPath + "/assets/game.unx", tempProfilePath + "/game.xdelta");
CreatePatch(tempOriginalPath + "/AM2R.exe", tempModPath + "/" + runnerName, tempProfilePath + "/AM2R.xdelta");
Core.CreatePatch(tempOriginalPath + "/data.win", tempModPath + "/assets/game.unx", tempProfilePath + "/game.xdelta");
Core.CreatePatch(tempOriginalPath + "/AM2R.exe", tempModPath + "/" + runnerName, tempProfilePath + "/AM2R.xdelta");
}
// Create game.droid patch and wrapper if Android is supported
@ -280,7 +277,7 @@ public partial class ModPacker : Form
}
// Create game.droid patch
CreatePatch(tempOriginalPath + "/data.win", tempAndroid + "/assets/game.droid", tempProfilePath + "/droid.xdelta");
Core.CreatePatch(tempOriginalPath + "/data.win", tempAndroid + "/assets/game.droid", tempProfilePath + "/droid.xdelta");
// Delete excess files in APK
@ -349,7 +346,7 @@ public partial class ModPacker : Form
if (profile.UsesCustomMusic)
{
// Copy files, excluding the blacklist
CopyFilesRecursive(dirInfo, DATAFILES_BLACKLIST, tempProfilePath + "/files_to_copy");
Core.CopyFilesRecursive(dirInfo, DATAFILES_BLACKLIST, tempProfilePath + "/files_to_copy");
}
else
{
@ -364,7 +361,7 @@ public partial class ModPacker : Form
string[] blacklist = musFiles.Concat(DATAFILES_BLACKLIST).ToArray();
// Copy files, excluding the blacklist
CopyFilesRecursive(dirInfo, blacklist, tempProfilePath + "/files_to_copy");
Core.CopyFilesRecursive(dirInfo, blacklist, tempProfilePath + "/files_to_copy");
}
// Export profile as XML
@ -464,22 +461,6 @@ public partial class ModPacker : Form
customSaveTextBox.Text = saveFilePath;
}
private static void CopyFilesRecursive(DirectoryInfo source, string[] blacklist, string destination)
{
foreach (var file in source.GetFiles())
{
if (!blacklist.Contains(file.Name))
file.CopyTo(destination + "/" + file.Name);
}
foreach (var dir in source.GetDirectories())
{
// Folders need to be lowercase, because GM only reads from lowercase names on *nix systems. Windows is case-insensitive so doesnt matter for them
string newDir = Directory.CreateDirectory(destination + "/" + dir.Name.ToLower()).FullName;
CopyFilesRecursive(dir, blacklist, newDir);
}
}
private void UpdateCreateButton()
{
if (isOriginalLoaded &&
@ -492,33 +473,7 @@ public partial class ModPacker : Form
createButton.Enabled = false;
}
// Thanks, stackoverflow: https://stackoverflow.com/questions/10520048/calculate-md5-checksum-for-a-file
private static string CalculateMD5(string filename)
{
using var stream = File.OpenRead(filename);
using var md5 = MD5.Create();
byte[] hash = md5.ComputeHash(stream);
return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant();
}
private void CreatePatch(string original, string modified, string output)
{
// Specify process start info
var parameters = new ProcessStartInfo
{
FileName = localPath + "/utilities/xdelta/xdelta3.exe",
WorkingDirectory = localPath,
UseShellExecute = false,
CreateNoWindow = true,
Arguments = "-f -e -s \"" + original + "\" \"" + modified + "\" \"" + output + "\""
};
// Launch process and wait for exit. using statement automatically disposes the object for us!
using var proc = new Process { StartInfo = parameters };
proc.Start();
proc.WaitForExit();
}
//todo: make this part of interface
private (bool, string) SelectFile(string title, FileFilter filter)
{
using var fileFinder = new OpenFileDialog { Filters = { filter } };

@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<LangVersion>10</LangVersion>
</PropertyGroup>
<ItemGroup>
<Content Include="utilities/**">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
</Content>
</ItemGroup>
</Project>

@ -0,0 +1,60 @@
using System.Diagnostics;
using System.IO.Compression;
using System.Security.Cryptography;
namespace AM2RModPackerLib;
public static class Core
{
public static readonly string Version = "2.0.3";
private static readonly string localPath = Directory.GetCurrentDirectory();
public static void CreatePatch(string original, string modified, string output)
{
// Specify process start info
var parameters = new ProcessStartInfo
{
// TODO: deal with linux/mac
FileName = localPath + "/utilities/xdelta/xdelta3.exe",
WorkingDirectory = localPath,
UseShellExecute = false,
CreateNoWindow = true,
Arguments = "-f -e -s \"" + original + "\" \"" + modified + "\" \"" + output + "\""
};
// Launch process and wait for exit. using statement automatically disposes the object for us!
using var proc = new Process { StartInfo = parameters };
proc.Start();
proc.WaitForExit();
}
public static string CalculateMD5(string filename)
{
using var stream = File.OpenRead(filename);
using var md5 = MD5.Create();
byte[] hash = md5.ComputeHash(stream);
return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant();
}
public static void CopyFilesRecursive(DirectoryInfo source, string[] blacklist, string destination)
{
foreach (var file in source.GetFiles())
{
if (!blacklist.Contains(file.Name))
file.CopyTo(destination + "/" + file.Name);
}
foreach (var dir in source.GetDirectories())
{
// Folders need to be lowercase, because GM only reads from lowercase names on *nix systems. Windows is case-insensitive so doesnt matter for them
string newDir = Directory.CreateDirectory(destination + "/" + dir.Name.ToLower()).FullName;
CopyFilesRecursive(dir, blacklist, newDir);
}
}
}

@ -1,7 +1,7 @@
using System;
using System.Xml.Serialization;
namespace AM2RModPacker.XML;
namespace AM2RModPackerLib.XML;
//TODO: sync this with the launcher xml, a bunch more comments are in there.
/// <summary>

@ -2,7 +2,7 @@
using System.IO;
using System.Text;
namespace AM2RModPacker.XML;
namespace AM2RModPackerLib.XML;
/// <summary>
/// The <c>Serializer</c> class, that serializes to and deserializes from XML files.
Loading…
Cancel
Save