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.

283 lines
9.7 KiB

  1. using CustomUI.BeatSaber;
  2. using CustomUI.Utilities;
  3. using IPA.Loader;
  4. using IPA.Loader.Features;
  5. using IPA.Old;
  6. using System;
  7. using System.Collections.Generic;
  8. using System.Linq;
  9. using System.Text;
  10. using System.Threading.Tasks;
  11. using UnityEngine;
  12. namespace BSIPA_ModList.UI.ViewControllers
  13. {
  14. internal interface IClickableCell
  15. {
  16. void OnSelect(ModListController cntrl);
  17. void Update();
  18. }
  19. internal class BSIPAModCell : CustomCellInfo, IClickableCell, IDisposable
  20. {
  21. internal PluginLoader.PluginMetadata Plugin;
  22. private ModListController list;
  23. private PluginManager.PluginEnableDelegate enableDel;
  24. private PluginManager.PluginDisableDelegate disableDel;
  25. public BSIPAModCell(ModListController list, PluginLoader.PluginMetadata plugin)
  26. : base("", "", null)
  27. {
  28. Plugin = plugin;
  29. this.list = list;
  30. var thisWeakRef = new WeakReference<BSIPAModCell>(this);
  31. PluginManager.PluginDisableDelegate reflessDDel = null;
  32. reflessDDel = disableDel = (p, r) => PluginManager_PluginDisabled(p, r, thisWeakRef, reflessDDel); // some indirection to make it a weak link for GC
  33. PluginManager.PluginDisabled += reflessDDel;
  34. PluginManager.PluginEnableDelegate reflessEDel = null;
  35. reflessEDel = enableDel = (p, r) => PluginManager_PluginEnabled(p, r, thisWeakRef, reflessEDel); // some indirection to make it a weak link for GC
  36. PluginManager.PluginEnabled += reflessEDel;
  37. Update(propogate: false);
  38. }
  39. private static void PluginManager_PluginEnabled(PluginLoader.PluginInfo plugin, bool needsRestart, WeakReference<BSIPAModCell> _self, PluginManager.PluginEnableDelegate ownDel)
  40. {
  41. if (!_self.TryGetTarget(out var self))
  42. {
  43. PluginManager.PluginEnabled -= ownDel;
  44. return;
  45. }
  46. if (plugin.Metadata != self.Plugin) return;
  47. self.Update(true, needsRestart);
  48. }
  49. private static void PluginManager_PluginDisabled(PluginLoader.PluginMetadata plugin, bool needsRestart, WeakReference<BSIPAModCell> _self, PluginManager.PluginDisableDelegate ownDel)
  50. {
  51. if (!_self.TryGetTarget(out var self))
  52. {
  53. PluginManager.PluginDisabled -= ownDel;
  54. return;
  55. }
  56. if (plugin != self.Plugin) return;
  57. self.Update(false, needsRestart);
  58. }
  59. private ModInfoViewController infoView;
  60. public void OnSelect(ModListController cntrl)
  61. {
  62. Logger.log.Debug($"Selected BSIPAModCell {Plugin.Name} {Plugin.Version}");
  63. if (infoView == null)
  64. {
  65. var desc = Plugin.Manifest.Description;
  66. if (string.IsNullOrWhiteSpace(desc))
  67. desc = "*No description*";
  68. infoView = BeatSaberUI.CreateViewController<ModInfoViewController>();
  69. infoView.Init(icon, Plugin.Name, "v" + Plugin.Version.ToString(), subtext,
  70. desc, Plugin, Plugin.Manifest.Links, true, list.flow);
  71. }
  72. list.flow.SetSelected(infoView, immediate: list.flow.HasSelected);
  73. }
  74. void IClickableCell.Update() => Update(null, false, false);
  75. public void Update(bool? _enabled = null, bool needsRestart = false, bool propogate = true)
  76. {
  77. text = $"{Plugin.Name} <size=60%>v{Plugin.Version}";
  78. subtext = Plugin.Manifest.Author;
  79. if (string.IsNullOrWhiteSpace(subtext))
  80. subtext = "<color=#BFBFBF><i>Unspecified Author</i>";
  81. var enabled = _enabled ?? !PluginManager.IsDisabled(Plugin);
  82. if (!enabled)
  83. subtext += " <color=#C2C2C2>- <i>Disabled</i>";
  84. if (needsRestart)
  85. subtext += " <i>(Restart to apply)</i>";
  86. icon = Plugin.GetIcon();
  87. var desc = Plugin.Manifest.Description;
  88. if (string.IsNullOrWhiteSpace(desc))
  89. desc = "*No description*";
  90. infoView?.Reload(Plugin.Name, "v" + Plugin.Version.ToString(), subtext, desc);
  91. if (propogate)
  92. list.Reload();
  93. }
  94. #region IDisposable Support
  95. private bool disposedValue = false; // To detect redundant calls
  96. protected virtual void Dispose(bool disposing)
  97. {
  98. if (!disposedValue)
  99. {
  100. if (disposing)
  101. {
  102. PluginManager.PluginDisabled -= disableDel;
  103. PluginManager.PluginEnabled -= enableDel;
  104. }
  105. disposedValue = true;
  106. }
  107. }
  108. public void Dispose()
  109. {
  110. Dispose(true);
  111. }
  112. #endregion
  113. }
  114. internal class BSIPAIgnoredModCell : CustomCellInfo, IClickableCell
  115. {
  116. internal PluginLoader.PluginMetadata Plugin;
  117. private ModListController list;
  118. private const string authorFormat = "{0} <color=#BFBFBF>- <i>Not loaded</i>";
  119. private string authorText;
  120. public BSIPAIgnoredModCell(ModListController list, PluginLoader.PluginMetadata plugin)
  121. : base($"<color=#878787>{plugin.Name} <size=60%>v{plugin.Version}", "", Utilities.DefaultBSIPAIcon)
  122. {
  123. Plugin = plugin;
  124. this.list = list;
  125. if (string.IsNullOrWhiteSpace(plugin.Manifest.Author))
  126. authorText = "<color=#BFBFBF><i>Unspecified Author</i>";
  127. else
  128. authorText = plugin.Manifest.Author;
  129. subtext = string.Format(authorFormat, authorText);
  130. }
  131. private ModInfoViewController infoView;
  132. public void OnSelect(ModListController cntrl)
  133. {
  134. Logger.log.Debug($"Selected BSIPAIgnoredModCell {Plugin.Name} {Plugin.Version}");
  135. if (infoView == null)
  136. {
  137. var desc = Plugin.Manifest.Description;
  138. if (string.IsNullOrWhiteSpace(desc))
  139. desc = "*No description*";
  140. infoView = BeatSaberUI.CreateViewController<ModInfoViewController>();
  141. infoView.Init(icon, Plugin.Name, "v" + Plugin.Version.ToString(), authorText,
  142. desc, Plugin, Plugin.Manifest.Links);
  143. }
  144. list.flow.SetSelected(infoView, immediate: list.flow.HasSelected);
  145. }
  146. public void Update()
  147. {
  148. }
  149. }
  150. internal class LibraryModCell : CustomCellInfo, IClickableCell
  151. {
  152. internal PluginLoader.PluginMetadata Plugin;
  153. private ModListController list;
  154. public LibraryModCell(ModListController list, PluginLoader.PluginMetadata plugin)
  155. : base($"{plugin.Name} <size=60%>v{plugin.Version}", plugin.Manifest.Author, null)
  156. {
  157. Plugin = plugin;
  158. this.list = list;
  159. if (string.IsNullOrWhiteSpace(subtext))
  160. subtext = "<color=#BFBFBF><i>Unspecified Author</i></color>";
  161. icon = Utilities.DefaultLibraryIcon;
  162. }
  163. private ModInfoViewController infoView;
  164. public void OnSelect(ModListController cntrl)
  165. {
  166. Logger.log.Debug($"Selected LibraryModCell {Plugin.Name} {Plugin.Version}");
  167. if (infoView == null)
  168. {
  169. var desc = Plugin.Manifest.Description;
  170. if (string.IsNullOrWhiteSpace(desc))
  171. desc = "*No description*";
  172. infoView = BeatSaberUI.CreateViewController<ModInfoViewController>();
  173. infoView.Init(icon, Plugin.Name, "v" + Plugin.Version.ToString(), subtext,
  174. desc, Plugin, Plugin.Manifest.Links);
  175. }
  176. list.flow.SetSelected(infoView, immediate: list.flow.HasSelected);
  177. }
  178. public void Update()
  179. {
  180. }
  181. }
  182. #pragma warning disable CS0618
  183. internal class IPAModCell : CustomCellInfo, IClickableCell
  184. {
  185. internal IPlugin Plugin;
  186. private ModListController list;
  187. public IPAModCell(ModListController list, IPlugin plugin)
  188. : base($"{plugin.Name} <size=60%>{plugin.Version}", "<color=#BFBFBF><i>Legacy</i>", Utilities.DefaultIPAIcon)
  189. {
  190. Plugin = plugin;
  191. this.list = list;
  192. }
  193. private ModInfoViewController infoView;
  194. public void OnSelect(ModListController cntrl)
  195. {
  196. Logger.log.Debug($"Selected IPAModCell {Plugin.Name} {Plugin.Version}");
  197. if (infoView == null)
  198. {
  199. PluginLoader.PluginMetadata updateInfo = null;
  200. try
  201. {
  202. updateInfo = new PluginLoader.PluginMetadata
  203. {
  204. Name = Plugin.Name,
  205. Id = Plugin.Name,
  206. Version = new SemVer.Version(Plugin.Version)
  207. };
  208. }
  209. catch (Exception e)
  210. {
  211. Logger.log.Warn($"Could not generate fake update info for {Plugin.Name}");
  212. Logger.log.Warn(e);
  213. }
  214. infoView = BeatSaberUI.CreateViewController<ModInfoViewController>();
  215. infoView.Init(icon, Plugin.Name, "v" + Plugin.Version.ToString(), "<color=#BFBFBF><i>Unknown Author</i>",
  216. "This mod was written for IPA.\n===\n\n## No metadata is avaliable for this mod.\n\n" +
  217. "Please contact the mod author and ask them to port it to BSIPA to provide more information.", updateInfo);
  218. }
  219. list.flow.SetSelected(infoView, immediate: list.flow.HasSelected);
  220. }
  221. public void Update()
  222. {
  223. }
  224. }
  225. #pragma warning restore
  226. }