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.

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