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.

124 lines
4.0 KiB

  1. using IPA.Utilities;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.IO;
  5. using System.Linq;
  6. using static IPA.Logging.Logger;
  7. namespace IPA.Injector
  8. {
  9. internal static class Updates
  10. {
  11. private const string DeleteFileName = Updating.BeatMods.Updater.SpecialDeletionsFile;
  12. public static void InstallPendingUpdates()
  13. {
  14. var pendingDir = Path.Combine(BeatSaber.InstallPath, "IPA", "Pending");
  15. if (!Directory.Exists(pendingDir)) return;
  16. // there are pending updates, install
  17. updater.Info("Installing pending updates");
  18. var toDelete = new string[0];
  19. var delFn = Path.Combine(pendingDir, DeleteFileName);
  20. if (File.Exists(delFn))
  21. {
  22. toDelete = File.ReadAllLines(delFn);
  23. File.Delete(delFn);
  24. }
  25. foreach (var file in toDelete)
  26. {
  27. try
  28. {
  29. File.Delete(Path.Combine(BeatSaber.InstallPath, file));
  30. }
  31. catch (Exception e)
  32. {
  33. updater.Error("While trying to install pending updates: Error deleting file marked for deletion");
  34. updater.Error(e);
  35. }
  36. }
  37. #region Self Protection
  38. string path;
  39. if (Directory.Exists(path = Path.Combine(pendingDir, "IPA")))
  40. {
  41. var dirs = new Stack<string>(20);
  42. dirs.Push(path);
  43. while (dirs.Count > 0)
  44. {
  45. var currentDir = dirs.Pop();
  46. string[] subDirs;
  47. string[] files;
  48. try
  49. {
  50. subDirs = Directory.GetDirectories(currentDir);
  51. files = Directory.GetFiles(currentDir);
  52. }
  53. catch (UnauthorizedAccessException e)
  54. {
  55. updater.Error(e);
  56. continue;
  57. }
  58. catch (DirectoryNotFoundException e)
  59. {
  60. updater.Error(e);
  61. continue;
  62. }
  63. foreach (var file in files)
  64. {
  65. try
  66. {
  67. if (!Utils.GetRelativePath(file, path).Split(Path.PathSeparator).Contains("Pending"))
  68. File.Delete(file);
  69. }
  70. catch (FileNotFoundException e)
  71. {
  72. updater.Error(e);
  73. }
  74. }
  75. foreach (var str in subDirs)
  76. dirs.Push(str);
  77. }
  78. }
  79. if (File.Exists(path = Path.Combine(pendingDir, "IPA.exe")))
  80. {
  81. File.Delete(path);
  82. if (File.Exists(path = Path.Combine(pendingDir, "Mono.Cecil.dll")))
  83. File.Delete(path);
  84. }
  85. #endregion
  86. try
  87. {
  88. Utils.CopyAll(new DirectoryInfo(pendingDir), new DirectoryInfo(BeatSaber.InstallPath), onCopyException: (e, f) =>
  89. {
  90. updater.Error($"Error copying file {Utils.GetRelativePath(f.FullName, pendingDir)} from Pending:");
  91. updater.Error(e);
  92. return true;
  93. });
  94. }
  95. catch (Exception e)
  96. {
  97. updater.Error("While trying to install pending updates: Error copying files in");
  98. updater.Error(e);
  99. }
  100. try
  101. {
  102. Directory.Delete(pendingDir, true);
  103. }
  104. catch (Exception e)
  105. {
  106. updater.Error("Something went wrong performing an operation that should never fail!");
  107. updater.Error(e);
  108. }
  109. }
  110. }
  111. }