Add support for known outdated mods, unpatching on game exit

This commit is contained in:
Norbi Peti 2022-02-14 00:10:30 +01:00
parent 4ddab53b6d
commit ae89291c55
5 changed files with 76 additions and 30 deletions

View file

@ -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));

View file

@ -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

View file

@ -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,26 +129,8 @@ namespace TBMM
case GameState.Unpatched:
{ //TODO: Wine
EnsureShown(false);
var psi = new ProcessStartInfo(GamePath(@"\IPA.exe"), GetExe() + " --nowait")
{
UseShellExecute = false,
RedirectStandardError = true,
RedirectStandardOutput = true,
WorkingDirectory = Configuration.GamePath,
CreateNoWindow = true
};
var process = Process.Start(psi);
process.BeginErrorReadLine();
process.BeginOutputReadLine();
process.EnableRaisingEvents = true;
modinfobox.Text = "";
DataReceivedEventHandler onoutput = (sender, e) =>
{
Invoke((Action)(() => modinfobox.Text += e.Data + Environment.NewLine));
};
process.OutputDataReceived += onoutput;
process.ErrorDataReceived += onoutput;
var (handler, task) = CheckStartGame(command);
var process = ExecutePatcher(true);
process.Exited += handler;
await task;
}
@ -165,6 +147,30 @@ namespace TBMM
return retOpenedWindowShouldStay;
}
private Process ExecutePatcher(bool patch)
{
var psi = new ProcessStartInfo(GamePath(@"\IPA.exe"), $"{GetExe()} --nowait {(patch ? "" : "--revert")}")
{
UseShellExecute = false,
RedirectStandardError = true,
RedirectStandardOutput = true,
WorkingDirectory = Configuration.GamePath,
CreateNoWindow = true
};
var process = Process.Start(psi);
process.BeginErrorReadLine();
process.BeginOutputReadLine();
process.EnableRaisingEvents = true;
modinfobox.Text = "";
DataReceivedEventHandler onoutput = (sender, e) =>
{
Invoke((Action)(() => modinfobox.Text += e.Data + Environment.NewLine));
};
process.OutputDataReceived += onoutput;
process.ErrorDataReceived += onoutput;
return process;
}
public enum GameState
{
NotFound,

View file

@ -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)

View file

@ -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; }
}
}