Techblox Mod Manager / Launcher
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

203 lines
7.8KB

  1. using System;
  2. using System.Diagnostics;
  3. using System.Drawing;
  4. using System.IO;
  5. using System.Linq;
  6. using System.Net;
  7. using System.Threading.Tasks;
  8. using System.Windows.Forms;
  9. using Microsoft.Win32;
  10. using Application = UnityEngine.Application;
  11. namespace GCMM
  12. {
  13. partial class MainForm
  14. {
  15. public void UpdateButton(Button button, bool enabled)
  16. {
  17. if (enabled)
  18. {
  19. button.ForeColor = Color.Lime;
  20. button.FlatAppearance.MouseOverBackColor = Color.FromArgb(0, 40, 0);
  21. button.FlatAppearance.MouseDownBackColor = Color.Green;
  22. }
  23. else
  24. {
  25. button.ForeColor = Color.Green;
  26. button.FlatAppearance.MouseOverBackColor = Color.Black;
  27. button.FlatAppearance.MouseDownBackColor = Color.Black;
  28. }
  29. }
  30. public string GetGameFolder()
  31. {
  32. using var key =
  33. Registry.LocalMachine.OpenSubKey(
  34. @"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Techblox Launcher") ??
  35. Registry.LocalMachine.OpenSubKey(
  36. @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Techblox Launcher");
  37. string launcherPath = key?.GetValue("DisplayIcon") is string launcherExecutable
  38. ? Directory.GetParent(launcherExecutable)?.FullName
  39. : null;
  40. launcherPath ??= Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
  41. "Techblox Launcher");
  42. string launcherConfig = Path.Combine(launcherPath, "launcher_settings.ini");
  43. if (!File.Exists(launcherConfig)) return null;
  44. string path = File.ReadLines(launcherConfig)
  45. .FirstOrDefault(line => line.StartsWith("133062..GAME_PATH="))
  46. ?.Substring("133062..GAME_PATH=".Length).Replace("/TBMM/", "/");
  47. if (path != null) path = (path + "StandaloneWindows64").Replace('/', Path.DirectorySeparatorChar);
  48. if (path != null && GetExe(path) != null) return path;
  49. return null;
  50. }
  51. public string SelectGameFolder()
  52. {
  53. var ofd = new OpenFileDialog();
  54. ofd.Filter = "Techblox executable|Techblox.exe|Techblox Preview executable|TechbloxPreview.exe";
  55. ofd.Title = "Game location";
  56. ofd.CheckFileExists = true;
  57. ofd.ShowDialog();
  58. return string.IsNullOrWhiteSpace(ofd.FileName) ? null : Directory.GetParent(ofd.FileName)?.FullName;
  59. }
  60. private (EventHandler, Task) CheckStartGame(string command)
  61. {
  62. var tcs = new TaskCompletionSource<object>();
  63. return ((sender, e) =>
  64. {
  65. Action act = async () =>
  66. {
  67. if (((sender as Process)?.ExitCode ?? 0) != 0)
  68. {
  69. status.Text = "Status: Patching failed";
  70. return;
  71. }
  72. if (CheckIfPatched() == GameState.Patched || unpatched.Checked)
  73. if (command != null)
  74. {
  75. if (sender is Process) //Patched just now
  76. CheckCompatibilityAndDisableMods();
  77. await CheckModUpdatesAsync();
  78. Process.Start(command);
  79. }
  80. else if (Environment.OSVersion.Platform == PlatformID.Win32NT)
  81. Process.Start(new ProcessStartInfo(GamePath("\\" + GetExe()))
  82. {
  83. WorkingDirectory = GamePath("\\") //Mods are only loaded if the working directory is correct
  84. });
  85. EndWork(false);
  86. tcs.SetResult(null);
  87. };
  88. if (InvokeRequired)
  89. Invoke(act);
  90. else
  91. act();
  92. }, tcs.Task);
  93. }
  94. private void CheckCompatibilityAndDisableMods()
  95. {
  96. if (!unpatched.Checked && MessageBox.Show("If the game updated just now, some mods may be incompatible or they may work just fine." +
  97. " Do you want to try running with mods?" +
  98. "\n\nClick Yes to start the game with mods (after a small update or if you just installed GCMM)" +
  99. "\nClick No to disable mods before starting the game (after a major update)" +
  100. "\n\nYou can always enable/disable mods by launching GCMM.",
  101. "Possible incompatibility warning", MessageBoxButtons.YesNo) == DialogResult.No)
  102. unpatched.Checked = true;
  103. }
  104. private async Task CheckModUpdatesAsync()
  105. {
  106. var updatable = mods.Values.Where(mod => mod.Updatable).ToArray();
  107. if (updatable.Length == 0)
  108. return;
  109. if (MessageBox.Show("Mod update(s) available!\n\n"
  110. + updatable.Select(mod => mod.Name + " " + mod.LatestVersion).Aggregate((a, b) => a + "\n")
  111. + "\n\nDo you want to update them now? You can also update later by opening GCMM.",
  112. "Update(s) available", MessageBoxButtons.YesNo) == DialogResult.No)
  113. return;
  114. foreach (var mod in updatable)
  115. await InstallMod(mod);
  116. MessageBox.Show("Mods updated");
  117. }
  118. public WebClient GetClient()
  119. {
  120. var client = new WebClient();
  121. client.Headers.Clear();
  122. client.Headers[HttpRequestHeader.Accept] = "application/json";
  123. client.BaseAddress = "https://git.exmods.org";
  124. return client;
  125. }
  126. private bool working = false;
  127. /// <summary>
  128. /// Some simple "locking", only allow one operation at a time
  129. /// </summary>
  130. /// <returns>Whether the work can begin</returns>
  131. public bool BeginWork()
  132. {
  133. if (working) return false;
  134. working = true;
  135. UpdateButton(playbtn, false);
  136. UpdateButton(installbtn, false);
  137. UpdateButton(uninstallbtn, false);
  138. UpdateButton(settingsbtn, false);
  139. unpatched.Enabled = false;
  140. return true;
  141. }
  142. public void EndWork(bool desc = true)
  143. {
  144. working = false;
  145. UpdateButton(playbtn, true);
  146. UpdateButton(settingsbtn, true);
  147. if (desc)
  148. modlist_SelectedIndexChanged(modlist, null);
  149. unpatched.Enabled = true;
  150. }
  151. /// <summary>
  152. /// Path must start with \
  153. /// </summary>
  154. /// <param name="path"></param>
  155. /// <param name="gamepath"></param>
  156. /// <returns></returns>
  157. public string GamePath(string path, string gamepath = null)
  158. {
  159. return ((gamepath ?? Configuration.GamePath) + path).Replace('\\', Path.DirectorySeparatorChar);
  160. }
  161. public string GetExe(string path = null)
  162. {
  163. if (File.Exists(GamePath("\\Techblox.exe", path)))
  164. return "Techblox.exe";
  165. if (File.Exists(GamePath("\\TechbloxPreview.exe", path)))
  166. return "TechbloxPreview.exe";
  167. return null;
  168. }
  169. private bool CheckNoExe()
  170. {
  171. return CheckNoExe(out _);
  172. }
  173. private bool CheckNoExe(out string path)
  174. {
  175. path = GetExe();
  176. if (path == null)
  177. {
  178. MessageBox.Show("Techblox not found! Set the correct path in Settings.");
  179. return true;
  180. }
  181. return false;
  182. }
  183. public DateTime GetGameVersionAsDate()
  184. {
  185. return Convert.ToDateTime(Application.version);
  186. }
  187. }
  188. }