Techblox Mod Manager / Launcher
Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

245 rindas
9.2KB

  1. using GCMM.Properties;
  2. using Microsoft.Win32;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Diagnostics;
  6. using System.Drawing;
  7. using System.IO;
  8. using System.Linq;
  9. using System.Net;
  10. using System.Text;
  11. using System.Text.RegularExpressions;
  12. using System.Threading.Tasks;
  13. using System.Windows.Forms;
  14. namespace GCMM
  15. {
  16. partial class MainForm
  17. {
  18. public void UpdateButton(Button button, bool enabled)
  19. {
  20. if (enabled)
  21. {
  22. button.ForeColor = Color.Lime;
  23. button.FlatAppearance.MouseOverBackColor = Color.FromArgb(0, 40, 0);
  24. button.FlatAppearance.MouseDownBackColor = Color.Green;
  25. }
  26. else
  27. {
  28. button.ForeColor = Color.Green;
  29. button.FlatAppearance.MouseOverBackColor = Color.Black;
  30. button.FlatAppearance.MouseDownBackColor = Color.Black;
  31. }
  32. }
  33. private bool EnableDisableAutoPatching(bool enable)
  34. {
  35. string launcherConfig =
  36. Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
  37. "Techblox Launcher", "launcher_settings.ini");
  38. bool gamePathSet = false;
  39. if (File.Exists(launcherConfig))
  40. {
  41. string[] lines = File.ReadLines(launcherConfig).Select(line =>
  42. {
  43. if (line.StartsWith("133062..GAME_PATH=") && line.Contains('/'))
  44. {
  45. gamePathSet = true;
  46. return
  47. $"{line.Substring(0, Math.Max(line.LastIndexOf("TBMM", StringComparison.Ordinal), line.Length))}{(enable ? "TBMM/" : "")}";
  48. }
  49. return line;
  50. }).ToArray(); //Need to close the file
  51. File.WriteAllLines(launcherConfig, lines);
  52. }
  53. return gamePathSet;
  54. }
  55. public void EnableDisableAutoPatchingWithDialog(bool enable)
  56. {
  57. if (EnableDisableAutoPatching(enable))
  58. {
  59. DialogUtils.ShowInfo(resources.GetString("Change_launch_settings_done"),
  60. resources.GetString("Change_launch_settings_title"));
  61. Settings.Default.AutoLaunch = enable ? AutoPatchingState.Enabled : AutoPatchingState.Disabled;
  62. }
  63. else
  64. DialogUtils.ShowError(resources.GetString("Change_launch_settings_error"),
  65. resources.GetString("Change_launch_settings_title"));
  66. }
  67. public string GetGameFolder()
  68. {
  69. string launcherConfig =
  70. Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
  71. "Techblox Launcher", "launcher_settings.ini");
  72. if (File.Exists(launcherConfig))
  73. return File.ReadLines(launcherConfig).FirstOrDefault(line => line.StartsWith("133062..GAME_PATH="))
  74. ?.Substring("133062..GAME_PATH=".Length);
  75. return null;
  76. }
  77. public string SelectGameFolder()
  78. {
  79. var ofd = new OpenFileDialog();
  80. ofd.Filter = "Techblox executable|Techblox.exe|Techblox Preview executable|TechbloxPreview.exe";
  81. ofd.Title = "Game location";
  82. ofd.CheckFileExists = true;
  83. ofd.ShowDialog();
  84. return string.IsNullOrWhiteSpace(ofd.FileName) ? null : Directory.GetParent(ofd.FileName)?.FullName;
  85. }
  86. private (EventHandler, Task) CheckStartGame(string command)
  87. {
  88. var tcs = new TaskCompletionSource<object>();
  89. return ((sender, e) =>
  90. {
  91. Action act = async () =>
  92. {
  93. if (((sender as Process)?.ExitCode ?? 0) != 0)
  94. {
  95. status.Text = "Status: Patching failed";
  96. return;
  97. }
  98. if (CheckIfPatched() == GameState.Patched || unpatched.Checked)
  99. if (command != null)
  100. {
  101. if (sender is Process) //Patched just now
  102. CheckCompatibilityAndDisableMods();
  103. await CheckModUpdatesAsync();
  104. Process.Start(command);
  105. }
  106. if (Environment.OSVersion.Platform == PlatformID.Win32NT)
  107. Process.Start(new ProcessStartInfo(GamePath("\\" + GetExe()))
  108. {
  109. WorkingDirectory = GamePath("\\") //Mods are only loaded if the working directory is correct
  110. });
  111. EndWork(false);
  112. tcs.SetResult(null);
  113. };
  114. if (InvokeRequired)
  115. Invoke(act);
  116. else
  117. act();
  118. }, tcs.Task);
  119. }
  120. private void CheckCompatibilityAndDisableMods()
  121. {
  122. if (!unpatched.Checked && MessageBox.Show("If the game updated just now, some mods may be incompatible or they may work just fine." +
  123. " Do you want to try running with mods?" +
  124. "\n\nClick Yes to start the game with mods (after a small update or if you just installed GCMM)" +
  125. "\nClick No to disable mods before starting the game (after a major update)" +
  126. "\n\nYou can always enable/disable mods by launching GCMM.",
  127. "Possible incompatibility warning", MessageBoxButtons.YesNo) == DialogResult.No)
  128. unpatched.Checked = true;
  129. }
  130. private async Task CheckModUpdatesAsync()
  131. {
  132. var updatable = mods.Values.Where(mod => mod.Updatable).ToArray();
  133. if (updatable.Length == 0)
  134. return;
  135. if (MessageBox.Show("Mod update(s) available!\n\n"
  136. + updatable.Select(mod => mod.Name + " " + mod.LatestVersion).Aggregate((a, b) => a + "\n")
  137. + "\n\nDo you want to update them now? You can also update later by opening GCMM.",
  138. "Update(s) available", MessageBoxButtons.YesNo) == DialogResult.No)
  139. return;
  140. foreach (var mod in updatable)
  141. await InstallMod(mod);
  142. MessageBox.Show("Mods updated");
  143. }
  144. public WebClient GetClient()
  145. {
  146. var client = new WebClient();
  147. if (!Settings.Default.UseProxy)
  148. client.Proxy = null;
  149. client.Headers.Clear();
  150. client.Headers[HttpRequestHeader.Accept] = "application/json";
  151. client.BaseAddress = "https://git.exmods.org";
  152. return client;
  153. }
  154. private bool working = false;
  155. /// <summary>
  156. /// Some simple "locking", only allow one operation at a time
  157. /// </summary>
  158. /// <returns>Whether the work can begin</returns>
  159. public bool BeginWork()
  160. {
  161. if (working) return false;
  162. working = true;
  163. UpdateButton(playbtn, false);
  164. UpdateButton(installbtn, false);
  165. UpdateButton(uninstallbtn, false);
  166. UpdateButton(settingsbtn, false);
  167. unpatched.Enabled = false;
  168. return true;
  169. }
  170. public void EndWork(bool desc = true)
  171. {
  172. working = false;
  173. UpdateButton(playbtn, true);
  174. UpdateButton(settingsbtn, true);
  175. if (desc)
  176. modlist_SelectedIndexChanged(modlist, null);
  177. unpatched.Enabled = true;
  178. }
  179. /// <summary>
  180. /// Path must start with \
  181. /// </summary>
  182. /// <param name="path"></param>
  183. /// <param name="gamepath"></param>
  184. /// <returns></returns>
  185. public string GamePath(string path, string gamepath = null)
  186. {
  187. return ((gamepath ?? Settings.Default.GamePath) + path).Replace('\\', Path.DirectorySeparatorChar);
  188. }
  189. public string GetExe(string path = null)
  190. {
  191. if (File.Exists(GamePath("\\Techblox.exe", path)))
  192. return "Techblox.exe";
  193. if (File.Exists(GamePath("\\TechbloxPreview.exe", path)))
  194. return "TechbloxPreview.exe";
  195. return null;
  196. }
  197. private bool CheckNoExe()
  198. {
  199. return CheckNoExe(out _);
  200. }
  201. private bool CheckNoExe(out string path)
  202. {
  203. path = GetExe();
  204. if (path == null)
  205. {
  206. MessageBox.Show("Techblox not found! Set the correct path in Settings.");
  207. return true;
  208. }
  209. return false;
  210. }
  211. public async Task<DateTime> GetLastGameUpdateTime()
  212. {
  213. /*using (var client = GetClient())
  214. {
  215. string html = await client.DownloadStringTaskAsync("https://api.steamcmd.net/v1/info/1078000");
  216. var regex = new Regex("<i>timeupdated:</i>[^<]*<b>([^<]*)</b>");
  217. var match = regex.Match(html);
  218. if (!match.Success)
  219. return default;
  220. return new DateTime(1970, 1, 1).AddSeconds(long.Parse(match.Groups[1].Value));
  221. }*/
  222. //return new DateTime(2020, 12, 28);
  223. return default;
  224. }
  225. }
  226. }