Skip to content

Commit

Permalink
[h2] Automate PRT simulation tool installation.
Browse files Browse the repository at this point in the history
todo: implement automatic updating.
  • Loading branch information
num0005 committed Jun 24, 2024
1 parent db54f76 commit f691336
Show file tree
Hide file tree
Showing 3 changed files with 255 additions and 2 deletions.
66 changes: 64 additions & 2 deletions Launcher/ToolkitInterface/H2AToolkit.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using System.Windows.Forms;
using ToolkitLauncher.Utility;
using static ToolkitLauncher.ToolkitProfiles;

namespace ToolkitLauncher.ToolkitInterface
{
public class H2AToolkit : H2Toolkit, IToolkitFBX2Jointed, IToolkitFBX2ASS, IToolkitFBX2JMI
{

public H2AToolkit(ProfileSettingsLauncher profle, string baseDirectory, Dictionary<ToolType, string> toolPaths) : base(profle, baseDirectory, toolPaths) { }
public H2AToolkit(ToolkitProfiles.ProfileSettingsLauncher profle, string baseDirectory, Dictionary<ToolType, string> toolPaths) : base(profle, baseDirectory, toolPaths) { }

private string tagPath
{
Expand Down Expand Up @@ -86,6 +86,68 @@ static private string SetFlag(string flag_string, string flag_name)
return flag_string;
}

private string _get_prt_tool_path()
{
return Path.Join(BaseDirectory, @"prt_sim.exe");
}

private async Task CheckPRTToolDeployment()
{
string prt_tool_path = _get_prt_tool_path();

bool should_update_prt = false;
if (!File.Exists(prt_tool_path))
{
// no tool, clear the version data as it's inaccurate
Profile.LatestPRTToolVersion = null;
ToolkitProfiles.Save();

var result = MessageBox.Show(
"PRT related operations will fail until it is installed, do you want to do that now?",
"PRT Simulation Tool not installed!",
MessageBoxButtons.YesNo);
should_update_prt = result == DialogResult.Yes;
}
else if (!PRTSimInstaller.IsRedistInstalled())
{
var result = MessageBox.Show(
"PRT installation is incomplete (missing redist), do you want to reinstall it now?",
"D3DX Redist Package Missing!",
MessageBoxButtons.YesNo);
should_update_prt = result == DialogResult.Yes;
}
else
{

if (Profile.LatestPRTToolVersion is not null)
{
// todo(num0005) put prt tool update logic here
}
else
{
// untracked PRT tool version, there's nothing we can do now
}
}

if (should_update_prt)
{
int? installed_version = await PRTSimInstaller.Install(prt_tool_path);
if (installed_version is null)
{
MessageBox.Show(
"Failed to install PRT simulation tool!",
"Error",
MessageBoxButtons.OK);
}
else
{
Profile.LatestPRTToolVersion = installed_version;
ToolkitProfiles.Save();
}
}

}

public override async Task ImportModel(string path, ModelCompile importType, bool phantomFix, bool h2SelectionLogic, bool renderPRT, bool FPAnim, string characterFPPath, string weaponFPPath, bool accurateRender, bool verboseAnim, bool uncompressedAnim, bool skyRender, bool PDARender, bool resetCompression, bool autoFBX, bool genShaders)
{
string flags = "";
Expand Down
4 changes: 4 additions & 0 deletions Launcher/ToolkitProfiles.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.CompilerServices;
using System.Text.Json;
using System.Text.Json.Serialization;

Expand Down Expand Up @@ -80,6 +81,9 @@ public class ProfileSettingsLauncher
[JsonPropertyName("batch")]
public bool Batch { get; set; }

[JsonPropertyName("prt_tool_version")]
public int? LatestPRTToolVersion { get; set; }

/// <summary>
/// Whatever we should temporarily be experts
/// </summary>
Expand Down
187 changes: 187 additions & 0 deletions Launcher/Utility/PRTInstaller.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Shapes;
using ToolkitLauncher.Utility;
using Path = System.IO.Path;

namespace ToolkitLauncher.Utility
{
internal class PRTSimInstaller
{
const string repoOwner = "digsite";
const string repoName = "prt_sim";
const string redist_dll_name = "d3dx9_43.dll";
const string redist_package_name = "d3d9x_43_redist.exe";

/// <summary>
/// Get the 32-bit windows directory
/// </summary>
/// <returns></returns>
private static string _32bit_windows_folder()
{
// https://stackoverflow.com/a/28448869
if (Environment.Is64BitOperatingSystem && Environment.Is64BitProcess)
{
return Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.Windows), "SysWOW64");
}
else
{
return Environment.GetFolderPath(Environment.SpecialFolder.System);
}
}

/// <summary>
/// Check if the d3d9 redist package is installed already
/// </summary>
/// <returns></returns>
static public bool IsRedistInstalled()
{
string windows_folder = _32bit_windows_folder();
string redist_dll = Path.Join(windows_folder, redist_dll_name);

return File.Exists(redist_dll);
}

static public async Task<GitHubReleases.Release?> GetLatestRelease()
{
GitHubReleases gitHubReleases = new();
IReadOnlyList<GitHubReleases.Release> list = await gitHubReleases.GetReleasesForRepo(repoOwner, repoName);

return list.FirstOrDefault(r => !r.IsPreRelease);
}

private static async Task<byte[]?> DownloadRedistRuntime(CancelableProgressBarWindow<long> progress)
{
GitHubReleases gitHubReleases = new();
IReadOnlyList<GitHubReleases.Release> list = await gitHubReleases.GetReleasesForRepo(repoOwner, repoName);

GitHubReleases.Release? redist_release = list.FirstOrDefault(r => r.Assets.Any(a => a.Name == redist_package_name));

if (redist_release == null)
{
Debug.Print("Failed to find any release with redist package!");
// no redist found
return null;
}

GitHubReleases.Asset redist_asset = redist_release.Assets.First(a => a.Name == redist_package_name);
return await gitHubReleases.DownloadReleaseAsset(redist_asset, progress);
}

private static async Task<bool> DoUpdate(string prt_install_path, GitHubReleases.Release release, CancelableProgressBarWindow<long> progress)
{
GitHubReleases gitHubReleases = new();
CancellationToken token = progress.GetCancellationToken();
progress.Status = "Downloading prt_sim";
byte[]? newExe = await Task.Run(() => {
return gitHubReleases.DownloadReleaseAsset(
release.Assets.First(assert => assert.Name == "prt_sim.exe"),
progress, token);
});
if (newExe is null)
{
progress.Complete = true;
_ = MessageBox.Show("Couldn't download release!", "Download Failed!", MessageBoxButton.OK);
return false;

}
else
{
progress.Status = "Applying update";
if (File.Exists(prt_install_path))
{
File.Delete(prt_install_path);
}

await File.WriteAllBytesAsync(prt_install_path, newExe, progress.GetCancellationToken());

if (!IsRedistInstalled())
{
progress.Status = "Downloading D3DX (Direct3D 9) redistributable package";

byte[]? redist_package = await DownloadRedistRuntime(progress);

if (redist_package is null)
{
progress.Complete = true;
progress.Status = "Failed to download redist package!";
} else
{
string temp_folder = Path.Join(Path.GetTempPath(), "Osoyoos_" + Path.GetRandomFileName());
Directory.CreateDirectory(temp_folder);

try
{
string redist_executable_path = Path.Combine(temp_folder, redist_package_name);
await File.WriteAllBytesAsync(redist_executable_path, redist_package, progress.GetCancellationToken());
progress.Status = "Installing redist package!";

await Process.StartProcess(temp_folder, redist_executable_path, new(), progress.GetCancellationToken(), admin:true);

progress.Complete = true;
progress.Status = IsRedistInstalled() ? "Installed redist package!" : "Failed to install redist package!";
} finally
{
Directory.Delete(temp_folder, true);
}
}


}

progress.Complete = true;

return true;
}
}

static public async Task<int?> Install(string prt_tool_path, GitHubReleases.Release? targetRelease = null)
{
CancelableProgressBarWindow<long> progress = new();
progress.Status = "Fetching prt_sim version information";
progress.Title = progress.Status;

// fetch latest release
if (targetRelease is null)
{
GitHubReleases.Release latestRelease = await GetLatestRelease();
if (latestRelease is null)
{
MessageBox.Show("Unable to fetch PRT release list", "Install error!", MessageBoxButton.OK);
progress.Complete = true;
return null;
}
targetRelease = latestRelease;
}

Debug.Print(targetRelease.ToString());

bool success = false;
try
{
success = await DoUpdate(prt_tool_path, targetRelease, progress);
}
catch (OperationCanceledException) { }
finally
{
progress.Complete = true;
}

if (success)
{
return targetRelease.ID;
}
else
{
return null;
}
}
}
}

0 comments on commit f691336

Please sign in to comment.