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.

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