Techblox Mod Manager / Launcher
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

272 lines
9.8KB

  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. public string GetGameFolder()
  34. { //TODO
  35. string libs;
  36. if (Environment.OSVersion.Platform == PlatformID.Win32NT)
  37. libs = Settings.Default.SteamUserID + @"\steamapps\libraryfolders.vdf"; //TODO: Not the Steam folder anymore!
  38. else
  39. return null;
  40. foreach (var line in File.ReadAllLines(libs).Concat(new[] {@"C:\Program Files (x86)\Steam\"}))
  41. {
  42. var regex = new Regex("\\t\"\\d+\"\\t\\t\"(.+)\"");
  43. var match = regex.Match(line);
  44. if (!match.Success)
  45. continue;
  46. string library = match.Groups[1].Value.Replace("\\\\", "\\");
  47. library += @"\steamapps\common\";
  48. if (GetExe(library + "Gamecraft") != null)
  49. return library + "Gamecraft";
  50. if (GetExe(library + "RobocraftX") != null)
  51. return library + "RobocraftX";
  52. }
  53. return null;
  54. }
  55. public string SelectGameFolder()
  56. {
  57. var ofd = new OpenFileDialog();
  58. ofd.Filter = "Gamecraft executable|Gamecraft.exe|Gamecraft Preview executable|GamecraftPreview.exe";
  59. ofd.Title = "Game location";
  60. ofd.InitialDirectory = @"C:\Program Files (x86)\Steam\steamapps\common\"; //TODO
  61. ofd.CheckFileExists = true;
  62. ofd.ShowDialog();
  63. if (string.IsNullOrWhiteSpace(ofd.FileName))
  64. return null;
  65. return Directory.GetParent(ofd.FileName).FullName;
  66. }
  67. public (string, int) AskForSteamLogin()
  68. {
  69. while (MessageBox.Show("Couid not find your Steam configuration to set launch options.\n\n" +
  70. "Please make sure you are logged into Steam and click Retry or click Cancel to skip setting this up.",
  71. "Steam config not found", MessageBoxButtons.RetryCancel) != DialogResult.Cancel)
  72. {
  73. var ret = GetSteamLocationAndUser();
  74. if (ret != (null, 0))
  75. return ret;
  76. }
  77. return (null, 0);
  78. }
  79. private bool UpdateOrGetSteamConfigToAutoStart(bool? autoLaunch)
  80. {
  81. var regex = new Regex(@"(\t{6}""LaunchOptions""\t+"")(.*)("")");
  82. string path = steamPath + @"\userdata\" + Settings.Default.SteamUserID + @"\config\localconfig.vdf";
  83. var lines = File.ReadAllLines(path);
  84. bool shouldMatch = false;
  85. bool ret = false;
  86. for (int i = 0; i < lines.Length; i++)
  87. {
  88. if (lines[i] == "\t\t\t\t\t\"1078000\"")
  89. shouldMatch = true; //Found the game
  90. else if(shouldMatch)
  91. {
  92. var match = regex.Match(lines[i]);
  93. if (!match.Success)
  94. continue;
  95. if (autoLaunch.HasValue)
  96. {
  97. if (autoLaunch.Value)
  98. lines[i] = match.Groups[1].Value + Application.ExecutablePath + " -start %command%" + match.Groups[3].Value;
  99. else
  100. lines[i] = match.Groups[1].Value + match.Groups[2].Value;
  101. File.WriteAllLines(path, lines);
  102. }
  103. ret = match.Groups[2].Value.Contains("GCMM.exe");
  104. break;
  105. }
  106. }
  107. return ret;
  108. }
  109. private (string, int) GetSteamLocationAndUser()
  110. {
  111. if (Environment.OSVersion.Platform != PlatformID.Win32NT) return (null, 0);
  112. using (var key = Registry.CurrentUser.OpenSubKey(@"Software\Valve\Steam\ActiveProcess"))
  113. {
  114. string path = (string)key?.GetValue("SteamClientDll");
  115. path = path != null ? Directory.GetParent(path).FullName : null;
  116. return (path, (int)(key.GetValue("ActiveUser") ?? 0));
  117. }
  118. }
  119. private void DetectConfigLocationAndAutoStart(string steamPath, ref int user)
  120. {
  121. string path = steamPath + @"\userdata";
  122. if (user == 0)
  123. {
  124. var dirs = Directory.GetDirectories(path);
  125. var goodPaths = (from dir in dirs
  126. where File.Exists(dir + @"\config\localconfig.vdf")
  127. select dir).ToArray();
  128. if (goodPaths.Length != 1)
  129. {
  130. (_, user) = AskForSteamLogin();
  131. path += user;
  132. }
  133. else
  134. {
  135. path = goodPaths[0];
  136. user = int.Parse(Path.GetFileName(path));
  137. }
  138. }
  139. else
  140. path += user;
  141. path += @"\config\localconfig.vdf";
  142. if (path != null && user != 0 && File.Exists(path))
  143. {
  144. Settings.Default.SteamUserID = user;
  145. UpdateOrGetSteamConfigToAutoStart(true);
  146. }
  147. else
  148. Settings.Default.AutoLaunch = false;
  149. }
  150. private void CheckStartGame(object sender, EventArgs e)
  151. {
  152. Action act = () =>
  153. {
  154. if (((sender as Process)?.ExitCode ?? 0) != 0)
  155. {
  156. status.Text = "Status: Patching failed";
  157. return;
  158. }
  159. if (CheckIfPatched() == GameState.Patched || unpatched.Checked)
  160. if (sender is string command)
  161. Process.Start(command);
  162. else if (Environment.OSVersion.Platform == PlatformID.Win32NT)
  163. Process.Start("steam://run/1078000/");
  164. else
  165. Process.Start("xdg-open", "steam://run/1078000/");
  166. };
  167. if (InvokeRequired)
  168. Invoke(act);
  169. else
  170. act();
  171. EndWork(false);
  172. }
  173. public WebClient GetClient()
  174. {
  175. var client = new WebClient();
  176. if (!Settings.Default.UseProxy)
  177. client.Proxy = null;
  178. client.Headers.Clear();
  179. client.Headers[HttpRequestHeader.Accept] = "application/json";
  180. client.BaseAddress = "https://git.exmods.org";
  181. return client;
  182. }
  183. private bool working = false;
  184. /// <summary>
  185. /// Some simple "locking", only allow one operation at a time
  186. /// </summary>
  187. /// <returns>Whether the work can begin</returns>
  188. public bool BeginWork()
  189. {
  190. if (working) return false;
  191. working = true;
  192. UpdateButton(playbtn, false);
  193. UpdateButton(installbtn, false);
  194. UpdateButton(uninstallbtn, false);
  195. UpdateButton(settingsbtn, false);
  196. unpatched.Enabled = false;
  197. return true;
  198. }
  199. public void EndWork(bool desc = true)
  200. {
  201. working = false;
  202. UpdateButton(playbtn, true);
  203. UpdateButton(settingsbtn, true);
  204. if (desc)
  205. modlist_SelectedIndexChanged(modlist, null);
  206. unpatched.Enabled = true;
  207. }
  208. /// <summary>
  209. /// Path must start with \
  210. /// </summary>
  211. /// <param name="path"></param>
  212. /// <param name="gamepath"></param>
  213. /// <returns></returns>
  214. public string GamePath(string path, string gamepath = null)
  215. {
  216. return ((gamepath ?? Settings.Default.GamePath) + path).Replace('\\', Path.DirectorySeparatorChar);
  217. }
  218. public string GetExe(string path = null)
  219. {
  220. if (File.Exists(GamePath("\\Gamecraft.exe", path)))
  221. return "Gamecraft.exe";
  222. if (File.Exists(GamePath("\\GamecraftPreview.exe", path)))
  223. return "GamecraftPreview.exe";
  224. return null;
  225. }
  226. private bool CheckNoExe()
  227. {
  228. return CheckNoExe(out _);
  229. }
  230. private bool CheckNoExe(out string path)
  231. {
  232. path = GetExe();
  233. if (path == null)
  234. {
  235. MessageBox.Show("Gamecraft not found! Set the correct path in Settings.");
  236. return true;
  237. }
  238. return false;
  239. }
  240. public async Task<DateTime> GetLastGameUpdateTime()
  241. {
  242. /*using (var client = GetClient())
  243. {
  244. string html = await client.DownloadStringTaskAsync("https://api.steamcmd.net/v1/info/1078000");
  245. var regex = new Regex("<i>timeupdated:</i>[^<]*<b>([^<]*)</b>");
  246. var match = regex.Match(html);
  247. if (!match.Success)
  248. return default;
  249. return new DateTime(1970, 1, 1).AddSeconds(long.Parse(match.Groups[1].Value));
  250. }*/
  251. //return new DateTime(2020, 12, 28);
  252. return default;
  253. }
  254. }
  255. }