Add support for known outdated mods, unpatching on game exit
This commit is contained in:
parent
4ddab53b6d
commit
ae89291c55
5 changed files with 76 additions and 30 deletions
|
@ -128,7 +128,9 @@ You may also want to verify the game's files in the launcher.
|
|||
{
|
||||
if (mod.Updatable)
|
||||
addText("New version available! " + mod.UpdateDetails, Color.Aqua);
|
||||
if (mod.LastUpdated != default && mod.LastUpdated < lastGameUpdateTime)
|
||||
if (mod.Broken)
|
||||
addText("Outdated mod! It has been confirmed that the mod is broken on the current version of the game.", Color.Red);
|
||||
else if (mod.LastUpdated != default && mod.LastUpdated < lastGameUpdateTime)
|
||||
addText("Outdated mod! It may not work properly on the current version of the game.", Color.DarkOrange);
|
||||
if (mod.Description != null)
|
||||
modinfobox.AppendText(mod.Description.Replace("\n", Environment.NewLine));
|
||||
|
|
|
@ -66,11 +66,22 @@ namespace TBMM
|
|||
{
|
||||
var sp = line.Split('\t');
|
||||
if (sp.Length < 2) continue;
|
||||
DateTime updated = default;
|
||||
bool broken = false;
|
||||
if (sp.Length > 2)
|
||||
{
|
||||
if (DateTime.TryParse(sp[2].Trim(), out var updatedAt))
|
||||
updated = updatedAt;
|
||||
else if (sp[2].Trim().ToLower() == "broken")
|
||||
broken = true;
|
||||
}
|
||||
|
||||
var mod = new ModInfo
|
||||
{
|
||||
Author = sp[0].Trim(),
|
||||
Name = sp[1].Trim(),
|
||||
LastUpdated = sp.Length > 2 ? DateTime.Parse(sp[2].Trim()) : default
|
||||
LastUpdated = updated,
|
||||
Broken = broken
|
||||
};
|
||||
if (await FetchModInfo(mod, preview, true)) //If it's actually a mod
|
||||
AddUpdateModInList(mod);
|
||||
|
@ -191,6 +202,8 @@ namespace TBMM
|
|||
}
|
||||
if (mod.LatestVersion != null && mod.Version != null && mod.Version < mod.LatestVersion)
|
||||
item.ForeColor = Color.Blue;
|
||||
else if(mod.Broken)
|
||||
item.ForeColor = Color.Red;
|
||||
else if (mod.LastUpdated != default && mod.LastUpdated < lastGameUpdateTime)
|
||||
item.ForeColor = Color.OrangeRed;
|
||||
else
|
||||
|
|
|
@ -18,7 +18,7 @@ namespace TBMM
|
|||
status.Text = "Status: Game not found";
|
||||
return GameState.NotFound;
|
||||
}
|
||||
string pnp = "Patch && Play";
|
||||
string pnp = "Play modded";
|
||||
if (!File.Exists(GamePath(@"\IPA.exe")))
|
||||
{
|
||||
status.Text = "Status: Patcher missing\nClicking Play will install it";
|
||||
|
@ -31,8 +31,8 @@ namespace TBMM
|
|||
playbtn.Text = pnp;
|
||||
return GameState.OldPatcher;
|
||||
}
|
||||
string nopatch = "Status: Unpatched\nClicking Play patches it";
|
||||
string gc = GetExe().Replace(".exe", "");
|
||||
string nopatch = "Status: Unpatched";
|
||||
string gc = GetExe(withExtension: false);
|
||||
string backups = GamePath(@"\IPA\Backups\" + gc);
|
||||
if (!Directory.Exists(backups))
|
||||
{
|
||||
|
@ -129,7 +129,27 @@ namespace TBMM
|
|||
case GameState.Unpatched:
|
||||
{ //TODO: Wine
|
||||
EnsureShown(false);
|
||||
var psi = new ProcessStartInfo(GamePath(@"\IPA.exe"), GetExe() + " --nowait")
|
||||
var (handler, task) = CheckStartGame(command);
|
||||
var process = ExecutePatcher(true);
|
||||
process.Exited += handler;
|
||||
await task;
|
||||
}
|
||||
break;
|
||||
case GameState.Patched:
|
||||
{
|
||||
//CheckStartGame(command)(null, null);
|
||||
var (handler, task) = CheckStartGame(command);
|
||||
handler(null, null);
|
||||
await task;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return retOpenedWindowShouldStay;
|
||||
}
|
||||
|
||||
private Process ExecutePatcher(bool patch)
|
||||
{
|
||||
var psi = new ProcessStartInfo(GamePath(@"\IPA.exe"), $"{GetExe()} --nowait {(patch ? "" : "--revert")}")
|
||||
{
|
||||
UseShellExecute = false,
|
||||
RedirectStandardError = true,
|
||||
|
@ -148,21 +168,7 @@ namespace TBMM
|
|||
};
|
||||
process.OutputDataReceived += onoutput;
|
||||
process.ErrorDataReceived += onoutput;
|
||||
var (handler, task) = CheckStartGame(command);
|
||||
process.Exited += handler;
|
||||
await task;
|
||||
}
|
||||
break;
|
||||
case GameState.Patched:
|
||||
{
|
||||
//CheckStartGame(command)(null, null);
|
||||
var (handler, task) = CheckStartGame(command);
|
||||
handler(null, null);
|
||||
await task;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return retOpenedWindowShouldStay;
|
||||
return process;
|
||||
}
|
||||
|
||||
public enum GameState
|
||||
|
|
|
@ -73,18 +73,28 @@ namespace TBMM
|
|||
return;
|
||||
}
|
||||
if (CheckIfPatched() == GameState.Patched || unpatched.Checked)
|
||||
{
|
||||
Process process = null;
|
||||
if (command != null)
|
||||
{
|
||||
if (sender is Process) //Patched just now
|
||||
CheckCompatibilityAndDisableMods();
|
||||
await CheckModUpdatesAsync();
|
||||
Process.Start(command);
|
||||
process = Process.Start(command);
|
||||
}
|
||||
else if (Environment.OSVersion.Platform == PlatformID.Win32NT)
|
||||
Process.Start(new ProcessStartInfo(GamePath("\\" + GetExe()))
|
||||
{
|
||||
process = Process.Start(new ProcessStartInfo(GamePath("\\" + GetExe()))
|
||||
{
|
||||
WorkingDirectory = GamePath("\\") //Mods are only loaded if the working directory is correct
|
||||
});
|
||||
}
|
||||
if (process is null)
|
||||
throw new NullReferenceException("Game process is null");
|
||||
process.EnableRaisingEvents = true;
|
||||
process.Exited += HandleGameExit;
|
||||
}
|
||||
|
||||
EndWork(false);
|
||||
tcs.SetResult(null);
|
||||
};
|
||||
|
@ -95,6 +105,20 @@ namespace TBMM
|
|||
}, tcs.Task);
|
||||
}
|
||||
|
||||
private void HandleGameExit(object sender, EventArgs e)
|
||||
{
|
||||
ExecutePatcher(false).Exited += (o, args) =>
|
||||
{
|
||||
if (CheckIfPatched() == GameState.Patched)
|
||||
{
|
||||
MessageBox.Show("Failed to unpatch game, launching through the launcher will fail because of anticheat. " +
|
||||
"Check the output in the panel on the right.\n\n" +
|
||||
"Please try starting the game again by clicking Play.", "Patcher error",
|
||||
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void CheckCompatibilityAndDisableMods()
|
||||
{
|
||||
if (!unpatched.Checked && MessageBox.Show("If the game updated just now, some mods may be incompatible or they may work just fine." +
|
||||
|
@ -168,12 +192,12 @@ namespace TBMM
|
|||
return ((gamepath ?? Configuration.GamePath) + path).Replace('\\', Path.DirectorySeparatorChar);
|
||||
}
|
||||
|
||||
public string GetExe(string path = null)
|
||||
public string GetExe(string path = null, bool withExtension = true)
|
||||
{
|
||||
if (File.Exists(GamePath("\\Techblox.exe", path)))
|
||||
return "Techblox.exe";
|
||||
return "Techblox" + (withExtension ? ".exe" : "");
|
||||
if (File.Exists(GamePath("\\TechbloxPreview.exe", path)))
|
||||
return "TechbloxPreview.exe";
|
||||
return "TechbloxPreview.exe" + (withExtension ? ".exe" : "");
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -196,7 +220,7 @@ namespace TBMM
|
|||
public DateTime GetGameVersionAsDate()
|
||||
{
|
||||
if (Configuration.GamePath == null) return default;
|
||||
using var fs = File.OpenRead(GamePath("\\TechbloxPreview_Data\\globalgamemanagers"));
|
||||
using var fs = File.OpenRead(GamePath($"\\{GetExe(withExtension: false)}_Data\\globalgamemanagers"));
|
||||
using var sr = new StreamReader(fs);
|
||||
char[] data = new char[512];
|
||||
while(!sr.EndOfStream)
|
||||
|
|
|
@ -31,5 +31,6 @@ namespace TBMM
|
|||
public HashSet<string> ModFiles { get; set; }
|
||||
public string UpdateDetails { get; set; }
|
||||
public bool Updatable => Version != null && LatestVersion != null && Version < LatestVersion;
|
||||
public bool Broken { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue