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

Switch to the GitHub update system for loaders #251

Open
PiKeyAr opened this issue Nov 18, 2024 · 1 comment
Open

Switch to the GitHub update system for loaders #251

PiKeyAr opened this issue Nov 18, 2024 · 1 comment
Assignees
Labels
enhancement New feature or request ready to close Issue is fixed and can be closed when the next update releases.

Comments

@PiKeyAr
Copy link
Member

PiKeyAr commented Nov 18, 2024

Advantages

  1. Single file small download.
  2. No need to check updates separately for extlib, Patches.json, Codes list etc.
  3. Only updates that were actually released will be detected (as opposed to updates triggering on every commit even if the build is in progress or has failed).

How to check if a new version is available

  1. Check local version (tag) information.
    SADX: Load the file sadxmlver.txt in the mods folder as text. If the file doesn't exist, assume the text is 608.
    SA2: Load the file sa2mlver.txt in the mods folder as text. If the file doesn't exist, assume the text is 284.
    Try parse the contents of the string as an integer. If it fails, assume the default values listed above.

  2. Get releases JSON from:
    SADX: https://api.github.com/repos/x-hax/sadx-mod-loader/releases and make a list of releases that have the SADXModLoader.7z asset.
    SA2: https://api.github.com/repos/x-hax/sa2-mod-loader/releases and make a list of releases that have the SA2ModLoader.7z asset.

  3. Parse release tags as integers, and add a changelog entry for each tag that is higher than the one stored locally. Select the the tag with the highest number as the download candidate.

Example implementation:

string url_releases = "https://api.github.com/repos/x-hax/sadx-mod-loader/releases";
string text_releases = string.Empty;
string assetName = "SADXModLoader.7z";
string mlverfile = Path.Combine(gameSettings.GamePath, "mods", "sadxmlver.txt");
string currentTagName = File.Exists(mlverfile) ? File.ReadAllText(mlverfile) : "605";
uint currentID = 608;
if (!uint.TryParse(currentTagName, out currentID))
	currentID = 608;
try
{
	StringBuilder changelog = new StringBuilder();
	List<GitHubRelease> releases;
	try
	{
		text_releases = webClient.DownloadString(url_releases);
	}
	catch (Exception e)
	{
		MessageBox.Show(parent, string.Format("Error downloading Mod Loader GitHub repo data from\n`{0}`.\n{1}\n\nIf this is a 403 error, you may be hitting a rate limit. Wait a while and try again.", url_releases, e.Message.ToString()), "SADX Mod Manager Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
		return null;
	}
	
	releases = JsonConvert.DeserializeObject<List<GitHubRelease>>(text_releases)
	.Where(x => !x.Draft && !x.PreRelease).ToList();
	if (releases == null || releases.Count == 0)
		throw new Exception("No GitHub releases found for URL " + url_releases);

	GitHubRelease latestRelease = null;
	GitHubAsset latestAsset = null;

	DateTime dateCheck = DateTime.MinValue;

	foreach (GitHubRelease release in releases)
	{
		GitHubAsset asset;
		asset = release.Assets
			.FirstOrDefault(x => x.Name.Equals(assetName, StringComparison.OrdinalIgnoreCase));

		if (asset == null)
			continue;

		uint releaseID = 0;
		if (uint.TryParse(release.TagName, out releaseID))
		{
			if (releaseID > currentID)
			{
				changelog.AppendLine(string.Format("Revision {0}\n{1}\n", release.TagName, release.Body));
			}
		}

		DateTime uploaded = DateTime.Parse(asset.Uploaded, CultureInfo.InvariantCulture, DateTimeStyles.AssumeLocal);
		if (uploaded > dateCheck)
		{
			latestRelease = release;
			latestAsset = asset;
			dateCheck = uploaded;
		}
	}

	if (latestRelease == null || latestAsset == null)
	{
		return null;
	}
	
	if (latestRelease.TagName != currentTagName)
	{
		string body = Regex.Replace(changelog.ToString(), "(?<!\r)\n", "\r\n");

		return new DownloadItem()
		{
			Type = DownloadItem.DownloadItemType.Loader,
			Name = "SADX Mod Loader",
			Authors = "MainMemory && x-hax",
			FileCount = 1,
			DownloadUrl = latestAsset.DownloadUrl,
			ReleaseName = "Revision " + latestRelease.TagName,
			Description = "The main tool that makes modding possible. Always keep it up to date.",
			Files = new List<Tuple<string, string, long>> { new Tuple<string, string, long>("Download", "SADXModLoader.7z", latestAsset.Size) },
			HomepageUrl = "https://github.com/x-hax/sadx-mod-loader",
			ReleaseTag = latestRelease.TagName,
			Version = latestRelease.TagName,
			ReleaseDate = DateTime.Parse(latestRelease.Published, DateTimeFormatInfo.InvariantInfo),
			UploadDate = DateTime.Parse(latestAsset.Uploaded, DateTimeFormatInfo.InvariantInfo),
			DownloadSize = latestAsset.Size,
			Changelog = body.TrimEnd(),
		};
	}
	else
		return null;
}
catch (Exception ex)
{
	MessageBox.Show(parent, "Could not retrieve SADX Mod Loader update information: " + ex.Message.ToString(), "SADX Mod Manager", MessageBoxButtons.OK, MessageBoxIcon.Error);
	return null;
}

How to install the update

  1. Extract the root folder of the archive (without subfolders) to the mods folder.
  2. Extract the extlib folder to SAManager\extlib.

Example implementation:

// Extract SADXModLoader.dll, border image, codes, game patches
Process.Start(new ProcessStartInfo("7z.exe", $"e -aoa -o\"{Path.Combine(Variables.gameSettings.GamePath, "mods")}\" \"{filePath}\" *.*") { UseShellExecute = false, CreateNoWindow = true }).WaitForExit();
// Extract extlibs
Process.Start(new ProcessStartInfo("7z.exe", $"x -aoa -o\"{Variables.managerAppDataPath}\" \"{filePath}\" extlib") { UseShellExecute = false, CreateNoWindow = true }).WaitForExit();
// Copy SADXModLoader.dll to system\CHRMODELS.dll if the Loader is installed
if (File.Exists(Variables.datadllorigpath))
{
				DialogResult mlres = DialogResult.Cancel;
				do
				{
								try
								{
												File.Copy(Path.Combine(Variables.gameSettings.GamePath, "mods", "SADXModLoader.dll"), Variables.datadllpath, true);
												mlres = DialogResult.OK;
								}
								catch (Exception ex)
								{
												mlres = MessageBox.Show(this, $"Failed to update the Mod Loader DLL file:\r\n\n{ex.Message.ToString()}\n\nMake sure the game is not running.", "Update Failed", MessageBoxButtons.RetryCancel, MessageBoxIcon.Error);
								}
				}
				while (mlres == DialogResult.Retry);
}
// Copy d3d8to9 DLL to game folder
if (File.Exists(Variables.d3d8to9InstalledDLLName))
{
				DialogResult d3res = DialogResult.Cancel;
				do
				{
								try
								{
												File.Copy(Variables.d3d8to9StoredDLLName, Variables.d3d8to9InstalledDLLName, true);
												d3res = DialogResult.OK;
								}
								catch (Exception ex)
								{
												d3res = MessageBox.Show(this, $"Failed to update Direct3D8to9 file:\r\n\n{ex.Message.ToString()}\n\nMake sure the game is not running.", "Update Failed", MessageBoxButtons.RetryCancel, MessageBoxIcon.Error);
								}
				}
				while (d3res == DialogResult.Retry);
}
@PiKeyAr PiKeyAr added the enhancement New feature or request label Nov 18, 2024
@Sora-yx Sora-yx self-assigned this Nov 18, 2024
@MainMemory
Copy link
Contributor

If/when this is done, be sure to remove the webhook for MMBot.

@Sora-yx Sora-yx added the ready to close Issue is fixed and can be closed when the next update releases. label Nov 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request ready to close Issue is fixed and can be closed when the next update releases.
Projects
None yet
Development

No branches or pull requests

3 participants