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.

161 lines
5.4 KiB

  1. using IPA.Utilities;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Diagnostics;
  5. using System.IO;
  6. using System.Linq;
  7. using System.Reflection;
  8. using static IPA.Logging.Logger;
  9. #if NET3
  10. using Net3_Proxy;
  11. using Path = Net3_Proxy.Path;
  12. using File = Net3_Proxy.File;
  13. using Directory = Net3_Proxy.Directory;
  14. #endif
  15. namespace IPA.Injector
  16. {
  17. internal static class Updates
  18. {
  19. private const string DeleteFileName = Updating.BeatMods.Updater.SpecialDeletionsFile;
  20. public static void InstallPendingUpdates()
  21. {
  22. InstallPendingSelfUpdates();
  23. InstallPendingModUpdates();
  24. }
  25. private static void InstallPendingSelfUpdates()
  26. {
  27. var path = Path.Combine(UnityGame.InstallPath, "IPA.exe");
  28. if (!File.Exists(path)) return;
  29. var ipaVersion = new Version(FileVersionInfo.GetVersionInfo(path).FileVersion);
  30. var selfVersion = Assembly.GetExecutingAssembly().GetName().Version;
  31. if (ipaVersion > selfVersion)
  32. {
  33. Process.Start(new ProcessStartInfo
  34. {
  35. FileName = path,
  36. Arguments = $"\"-nw={Process.GetCurrentProcess().Id},s={string.Join(" ", Environment.GetCommandLineArgs().Skip(1).StrJP()).Replace("\\", "\\\\").Replace(",", "\\,")}\"",
  37. UseShellExecute = false
  38. });
  39. updater.Info("Updating BSIPA...");
  40. Environment.Exit(0);
  41. }
  42. }
  43. private static void InstallPendingModUpdates()
  44. {
  45. var pendingDir = Path.Combine(UnityGame.InstallPath, "IPA", "Pending");
  46. if (!Directory.Exists(pendingDir)) return;
  47. // there are pending updates, install
  48. updater.Info("Installing pending updates");
  49. var toDelete = new string[0];
  50. var delFn = Path.Combine(pendingDir, DeleteFileName);
  51. if (File.Exists(delFn))
  52. {
  53. toDelete = File.ReadAllLines(delFn);
  54. File.Delete(delFn);
  55. }
  56. foreach (var file in toDelete)
  57. {
  58. try
  59. {
  60. File.Delete(Path.Combine(UnityGame.InstallPath, file));
  61. }
  62. catch (Exception e)
  63. {
  64. updater.Error("While trying to install pending updates: Error deleting file marked for deletion");
  65. updater.Error(e);
  66. }
  67. }
  68. #region Self Protection
  69. string path;
  70. if (Directory.Exists(path = Path.Combine(pendingDir, "IPA")))
  71. {
  72. var dirs = new Stack<string>(20);
  73. dirs.Push(path);
  74. while (dirs.Count > 0)
  75. {
  76. var currentDir = dirs.Pop();
  77. string[] subDirs;
  78. string[] files;
  79. try
  80. {
  81. subDirs = Directory.GetDirectories(currentDir);
  82. files = Directory.GetFiles(currentDir);
  83. }
  84. catch (UnauthorizedAccessException e)
  85. {
  86. updater.Error(e);
  87. continue;
  88. }
  89. catch (DirectoryNotFoundException e)
  90. {
  91. updater.Error(e);
  92. continue;
  93. }
  94. foreach (var file in files)
  95. {
  96. try
  97. {
  98. if (!Utils.GetRelativePath(file, path).Split(Path.PathSeparator).Contains("Pending"))
  99. File.Delete(file);
  100. }
  101. catch (FileNotFoundException e)
  102. {
  103. updater.Error(e);
  104. }
  105. }
  106. foreach (var str in subDirs)
  107. dirs.Push(str);
  108. }
  109. }
  110. if (File.Exists(path = Path.Combine(pendingDir, "IPA.exe")))
  111. {
  112. File.Delete(path);
  113. if (File.Exists(path = Path.Combine(pendingDir, "Mono.Cecil.dll")))
  114. File.Delete(path);
  115. }
  116. #endregion
  117. try
  118. {
  119. Utils.CopyAll(new DirectoryInfo(pendingDir), new DirectoryInfo(UnityGame.InstallPath), onCopyException: (e, f) =>
  120. {
  121. updater.Error($"Error copying file {Utils.GetRelativePath(f.FullName, pendingDir)} from Pending:");
  122. updater.Error(e);
  123. return true;
  124. });
  125. }
  126. catch (Exception e)
  127. {
  128. updater.Error("While trying to install pending updates: Error copying files in");
  129. updater.Error(e);
  130. }
  131. try
  132. {
  133. Directory.Delete(pendingDir, true);
  134. }
  135. catch (Exception e)
  136. {
  137. updater.Error("Something went wrong performing an operation that should never fail!");
  138. updater.Error(e);
  139. }
  140. }
  141. }
  142. }