Elin Decompiled Documentation EA 23.344.1 Nightly
Loading...
Searching...
No Matches
LayerMod.cs
Go to the documentation of this file.
1using System;
2using System.Collections.Generic;
3using System.IO;
4using System.Linq;
5using System.Text;
6using HeathenEngineering.SteamworksIntegration;
7using UnityEngine;
8using UnityEngine.EventSystems;
9using UnityEngine.UI;
10
11public class LayerMod : ELayer
12{
13 private sealed class PreviewEntry
14 {
15 public Sprite sprite;
16
17 public bool ownsTexture;
18
19 public ModPreview.PreviewType kind;
20 }
21
22 private sealed class HoverRelay : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler
23 {
24 public Action onEnter;
25
26 public void OnPointerEnter(PointerEventData eventData)
27 {
28 onEnter?.Invoke();
29 }
30 }
31
32 private const string urlWorkshopItem = "https://steamcommunity.com/sharedfiles/filedetails/?id=";
33
34 public static LayerMod Instance;
35
36 public UIList list;
37
38 public UIList list2;
39
41
43
45
47
48 public InputField inputSearch;
49
51
53
55
57
59
61
63
65
66 public UIItem infoId;
67
69
71
73
75
77
79
81
83
85
86 public GameObject infoSpace;
87
89
91
92 private float timerSearch;
93
94 private bool wasSearchFocused;
95
96 private string lastSearch = "";
97
98 private string[] searchTerms = Array.Empty<string>();
99
100 private ModSearch.Filter filterMode;
101
102 private readonly Dictionary<BaseModPackage, string> searchCache = new Dictionary<BaseModPackage, string>();
103
104 private readonly Dictionary<BaseModPackage, PreviewEntry> previews = new Dictionary<BaseModPackage, PreviewEntry>();
105
107
108 public bool HasFilter
109 {
110 get
111 {
112 if (searchTerms.Length == 0)
113 {
114 return filterMode != ModSearch.Filter.All;
115 }
116 return true;
117 }
118 }
119
120 private void Move(BaseModPackage p, int a)
121 {
122 List<object> items = list.items;
123 int num = items.IndexOf(p);
124 if (num < 0 || num + a < 0 || num + a >= items.Count)
125 {
126 SE.BeepSmall();
127 }
128 else
129 {
130 MoveTo(p, items[num + a] as BaseModPackage);
131 }
132 }
133
134 private void MoveTo(BaseModPackage p, BaseModPackage target)
135 {
136 List<BaseModPackage> packages = manager.packages;
137 int num = packages.IndexOf(p);
138 int num2 = ((target == null) ? (-1) : packages.IndexOf(target));
139 if (num < 0 || num2 < 0 || num == num2 || target.builtin)
140 {
141 SE.BeepSmall();
142 return;
143 }
144 packages.Move(p, num2 - num);
145 SE.Tab();
146 textRestart.SetActive(enable: true);
148 RefreshLists();
149 }
150
151 public void RefreshLists()
152 {
153 list.List();
154 list2.List();
155 if ((bool)textNoResult)
156 {
157 textNoResult.SetActive(HasFilter && list.items.Count == 0);
158 }
159 }
160
161 public override void OnInit()
162 {
163 textRestart.SetActive(enable: false);
165 {
166 ELayer.config.other.disableMods = on;
168 textRestart.SetActive(enable: true);
169 });
170 Instance = this;
171 foreach (BaseModPackage package in manager.packages)
172 {
173 package.UpdateMeta(updateOnly: true);
174 searchCache[package] = ModSearch.BuildText(package);
175 }
176 list.dragScrollView = GetComponentInChildren<UIScrollView>();
177 list.dragViewport = windows[0].Rect();
178 list.callbacks = CreateCallbacks(list, builtin: false);
179 list2.callbacks = CreateCallbacks(list2, builtin: true);
180 InitSearchUI();
181 windows[0].AddBottomButton("mod_preset", ShowPresetMenu);
182 infoPreview.button1.SetOnClick(delegate
183 {
185 });
186 RefreshLists();
188 list.dragEdgeSize = list.callbacks.GetMold()?.Rect().sizeDelta.y ?? 34f;
189 }
190
191 private UIList.Callback<ModPackage, ItemMod> CreateCallbacks(UIList target, bool builtin)
192 {
193 return new UIList.Callback<ModPackage, ItemMod>
194 {
195 onClick = delegate
196 {
197 },
198 onInstantiate = delegate(ModPackage a, ItemMod b)
199 {
200 b.package = a;
201 string title = ELayer.core.mods.packages.IndexOf(a) + 1 + ". " + (a.isInPackages ? "[Local] " : "") + a.title.IsEmpty(a.dirInfo.Name);
202 b.buttonActivate.mainText.SetText(FitTitle(b.buttonActivate.mainText, title), (!a.IsValidVersion() || a.blockedBy != null || !a.langDepError.IsEmpty()) ? FontColor.Bad : (a.activated ? FontColor.ButtonGeneral : FontColor.Passive));
203 b.buttonActivate.subText.text = a.version;
204 b.buttonLock.mainText.text = a.author;
205 b.buttonUp.SetActive(!a.builtin);
206 b.buttonDown.SetActive(!a.builtin);
207 b.buttonToggle.SetToggle(a.willActivate);
208 b.buttonUp.SetOnClick(delegate
209 {
210 Move(a, -1);
211 });
212 b.buttonDown.SetOnClick(delegate
213 {
214 Move(a, 1);
215 });
216 b.buttonActivate.GetOrCreate<HoverRelay>().onEnter = delegate
217 {
218 ShowInfo(a);
219 };
220 UIButton bt = b.buttonToggle;
221 bt.SetOnClick(delegate
222 {
223 a.willActivate = !a.willActivate;
224 bt.SetToggle(a.willActivate);
226 textRestart.SetActive(enable: true);
227 });
228 bt.interactable = !a.builtin;
229 b.buttonActivate.onClick.AddListener(delegate
230 {
231 Refresh();
232 UIContextMenu uIContextMenu = ELayer.ui.CreateContextMenuInteraction();
233 if (!a.builtin)
234 {
235 if (ELayer.debug.enable || (!BaseCore.IsOffline && a.isInPackages && !ELayer.core.version.demo))
236 {
237 uIContextMenu.AddButton("mod_publish", delegate
238 {
239 Core.TryWarnUpload(delegate
240 {
241 Dialog.YesNo("mod_publish_warn".lang(a.title, a.id, a.author), delegate
242 {
243 ELayer.core.steam.CreateUserContent(a);
244 });
245 });
246 });
247 }
248 uIContextMenu.AddButton(a.willActivate ? "mod_deactivate" : "mod_activate", delegate
249 {
250 SE.Click();
251 a.willActivate = !a.willActivate;
252 ELayer.core.mods.SaveLoadOrder();
253 RefreshLists();
254 textRestart.SetActive(enable: true);
255 });
256 if (!a.isInPackages && !a.workshopId.IsEmpty())
257 {
258 uIContextMenu.AddButton("mod_convert_local", delegate
259 {
260 SE.Click();
261 string path = ("Mod_" + a.workshopId + "_" + a.id).SanitizeDirectoryName();
262 string text = Path.Combine(BaseModManager.rootMod, path);
263 a.CopyContentTo(text);
264 ModPackage modPackage = manager.AddPackage(new DirectoryInfo(text), isInPackages: true);
265 modPackage.UpdateMeta(updateOnly: true);
266 searchCache[modPackage] = ModSearch.BuildText(modPackage);
267 manager.packages.Move(modPackage, manager.packages.IndexOf(a) - manager.packages.Count + 2);
268 modPackage.willActivate = false;
269 modPackage.activated = false;
271 RefreshLists();
272 textRestart.SetActive(enable: true);
273 });
274 }
275 if (a.isInPackages && a.IsSourceLocalizable)
276 {
277 uIContextMenu.AddButton("mod_export_text", delegate
278 {
279 SE.Click();
280 string text = a.UpdateSourceLocalizationFile(Lang.langCode, force: true);
281 ELayer.ui.Say(text);
282 });
283 }
284 }
285 if (ModPreview.FindPreviewFile(a) != null || (bool)SteamPreview(a))
286 {
287 uIContextMenu.AddButton("mod_preview", delegate
288 {
289 ShowPreview(a);
290 });
291 }
292 if (!a.workshopId.IsEmpty())
293 {
294 uIContextMenu.AddButton("mod_info_workshop", delegate
295 {
296 SE.Click();
297 Application.OpenURL("https://steamcommunity.com/sharedfiles/filedetails/?id=" + a.workshopId.Trim());
298 });
299 }
300 uIContextMenu.AddButton("mod_info", delegate
301 {
302 SE.Click();
303 if (!a.dirInfo.Exists)
304 {
305 SE.BeepSmall();
306 ELayer.ui.Say(a.dirInfo.FullName);
307 }
308 else
309 {
310 string text = a.dirInfo.FullName + "/package.xml";
311 Util.ShowExplorer(File.Exists(text) ? text : a.dirInfo.FullName);
312 }
313 });
314 uIContextMenu.Show();
315 });
316 b.buttonLock.onClick.AddListener(Refresh);
317 },
318 onList = delegate
319 {
320 foreach (BaseModPackage package in manager.packages)
321 {
322 if (package.builtin == builtin && (builtin || Match(package)))
323 {
324 target.Add(package);
325 }
326 }
327 },
328 onRefresh = Refresh,
329 onDragReorder = delegate(ModPackage p, int a)
330 {
332 List<object> items = target.items;
333 int num = items.IndexOf(p);
334 MoveTo(p, items[Mathf.Clamp(num + a, 0, items.Count - 1)] as BaseModPackage);
335 },
336 canDragReorder = (ModPackage p) => !p.builtin
337 };
338 }
339
340 private static string FitTitle(UIText text, string title)
341 {
342 TextGenerationSettings generationSettings = text.GetGenerationSettings(Vector2.zero);
343 TextGenerator cachedTextGeneratorForLayout = text.cachedTextGeneratorForLayout;
344 float num = text.rectTransform.rect.width * text.pixelsPerUnit;
345 if (cachedTextGeneratorForLayout.GetPreferredWidth(title, generationSettings) <= num)
346 {
347 return title;
348 }
349 int num2 = title.Length;
350 while (num2 > 1 && cachedTextGeneratorForLayout.GetPreferredWidth(title[..num2].TrimEnd() + "..", generationSettings) > num)
351 {
352 num2--;
353 }
354 return title[..num2].TrimEnd() + "..";
355 }
356
357 private bool Match(BaseModPackage p)
358 {
359 if (!searchCache.TryGetValue(p, out var value))
360 {
361 value = (searchCache[p] = ModSearch.BuildText(p));
362 }
363 return ModSearch.Match(p, value, searchTerms, filterMode);
364 }
365
366 private void InitSearchUI()
367 {
368 if ((bool)inputSearch)
369 {
370 inputSearch.SetTextWithoutNotify("");
371 if (inputSearch.placeholder is Text text)
372 {
373 text.text = "mod_search".lang();
374 }
375 inputSearch.onValueChanged.AddListener(Search);
376 inputSearch.onSubmit.AddListener(Search);
377 }
378 if ((bool)buttonClearSearch)
379 {
381 }
382 buttonFilter = windows[0].AddBottomButton("mod_filter", CycleFilter);
384 }
385
386 public void Search(string s)
387 {
388 lastSearch = s ?? "";
389 timerSearch = 0.15f;
390 if ((bool)buttonClearSearch)
391 {
392 buttonClearSearch.SetActive(!lastSearch.IsEmpty());
393 }
394 }
395
396 private void ClearSearchText()
397 {
398 SE.Click();
399 if ((bool)inputSearch)
400 {
401 inputSearch.SetTextWithoutNotify("");
402 }
403 Search("");
404 }
405
406 public void ClearSearch()
407 {
408 if ((bool)inputSearch)
409 {
410 inputSearch.SetTextWithoutNotify("");
411 }
412 if ((bool)buttonClearSearch)
413 {
414 buttonClearSearch.SetActive(enable: false);
415 }
416 lastSearch = "";
417 timerSearch = 0f;
418 searchTerms = Array.Empty<string>();
419 filterMode = ModSearch.Filter.All;
421 RefreshLists();
422 }
423
424 private void CycleFilter()
425 {
426 SE.Click();
427 filterMode = ModSearch.Filters[(int)(filterMode + 1) % ModSearch.Filters.Length];
429 RefreshLists();
430 }
431
432 private void RefreshFilterButton()
433 {
434 if ((bool)buttonFilter)
435 {
436 buttonFilter.mainText.text = "mod_filter".lang() + ": " + FilterLabel(filterMode).lang();
437 windows[0].rectBottom.RebuildLayout(recursive: true);
438 }
439 }
440
441 private static string FilterLabel(ModSearch.Filter f)
442 {
443 return f switch
444 {
445 ModSearch.Filter.Enabled => "mod_filter_enabled",
446 ModSearch.Filter.Disabled => "mod_filter_disabled",
447 ModSearch.Filter.Problems => "mod_filter_problem",
448 ModSearch.Filter.Local => "mod_filter_local",
449 ModSearch.Filter.Workshop => "mod_filter_workshop",
450 _ => "all",
451 };
452 }
453
454 private void LateUpdate()
455 {
456 if (timerSearch > 0f)
457 {
459 if (timerSearch <= 0f)
460 {
461 timerSearch = 0f;
462 searchTerms = ModSearch.Terms(lastSearch);
463 RefreshLists();
464 }
465 }
466 if ((bool)inputSearch)
467 {
468 bool isFocused = inputSearch.isFocused;
469 EventSystem current = EventSystem.current;
470 if (wasSearchFocused && !isFocused && (bool)current && current.currentSelectedGameObject == inputSearch.gameObject)
471 {
472 current.SetSelectedGameObject(null);
473 }
474 wasSearchFocused = isFocused;
475 }
476 }
477
479 {
480 if (previews.TryGetValue(p, out var value))
481 {
482 return value;
483 }
484 value = new PreviewEntry();
485 bool owns;
486 Texture2D texture2D = LoadPreviewTexture(p, mipmap: true, out value.kind, out owns);
487 if ((bool)texture2D)
488 {
489 Texture2D texture2D2 = ModPreview.Downscale(texture2D, 280, owns);
490 value.sprite = texture2D2.ToSprite();
491 value.ownsTexture = owns || texture2D2 != texture2D;
492 }
493 previews[p] = value;
494 return value;
495 }
496
497 private static Texture2D LoadPreviewTexture(BaseModPackage p, bool mipmap, out ModPreview.PreviewType kind, out bool owns)
498 {
499 kind = ModPreview.PreviewType.None;
500 owns = true;
501 FileInfo fileInfo = ModPreview.FindPreviewFile(p);
502 if (fileInfo != null)
503 {
504 try
505 {
506 Texture2D texture2D = ModPreview.LoadTexture(File.ReadAllBytes(fileInfo.FullName), out kind, mipmap);
507 if ((bool)texture2D)
508 {
509 return texture2D;
510 }
511 }
512 catch (Exception ex)
513 {
514 Debug.LogWarning("#mod preview " + fileInfo.FullName + ": " + ex.Message);
515 }
516 }
517 Texture2D texture2D2 = SteamPreview(p);
518 if ((bool)texture2D2)
519 {
520 owns = false;
521 if (kind == ModPreview.PreviewType.None)
522 {
523 kind = ModPreview.PreviewType.Jpeg;
524 }
525 }
526 return texture2D2;
527 }
528
529 private static Texture2D SteamPreview(BaseModPackage p)
530 {
531 if (!(p.item is WorkshopItem workshopItem) || !workshopItem.previewImage || workshopItem.previewImage.width <= 2)
532 {
533 return null;
534 }
535 return workshopItem.previewImage;
536 }
537
539 {
540 using (List<object>.Enumerator enumerator = list.items.GetEnumerator())
541 {
542 if (enumerator.MoveNext())
543 {
544 return enumerator.Current as BaseModPackage;
545 }
546 }
547 if (manager.packages.Count <= 0)
548 {
549 return null;
550 }
551 return manager.packages[0];
552 }
553
554 private void ShowInfo(BaseModPackage p)
555 {
556 if (p != null && p != panelTarget)
557 {
558 panelTarget = p;
559 infoTitle.text1.SetText(p.title.IsEmpty(p.dirInfo.Name));
560 PreviewEntry thumb = GetThumb(p);
561 infoPreview.SetActive(thumb.sprite);
562 if ((bool)thumb.sprite)
563 {
564 infoPreview.image1.sprite = thumb.sprite;
565 }
566 SetInfo(value: (thumb.sprite ? ((thumb.kind == ModPreview.PreviewType.Gif) ? "mod_preview_gif" : null) : ((thumb.kind == ModPreview.PreviewType.None) ? "mod_preview_none" : "mod_preview_unsupported"))?.lang(), item: infoPreviewNote);
567 SetTopic(infoAuthor, p.author, null);
568 SetTopic(infoVersion, p.version, null);
569 SetTopic(infoId, p.id, null);
570 string text = ModLoadOrderPreset.WorkshopId(p);
571 SetTopic(infoWorkshop, text.IsEmpty() ? p.dirInfo.Name : text, text.IsEmpty() ? "mod_filter_local" : "mod_filter_workshop");
572 SetTopic(infoStatus, (!p.builtin && !p.willActivate) ? "mod_filter_disabled".lang() : null, null);
573 List<string> list = new List<string>();
574 if (p.blockedBy != null)
575 {
576 list.Add("mod_info_blocked".lang(p.blockedBy.title.IsEmpty(p.blockedBy.id)));
577 }
578 if (!p.langDepError.IsEmpty())
579 {
580 string[] array = p.langDepError.Split('\t');
581 list.Add(array[0].lang(string.Join("mod_info_or".lang(), array, 1, array.Length - 1)));
582 }
583 if (p.duplicateOf != null)
584 {
585 list.Add("mod_info_duplicate".lang(p.duplicateOf.title.IsEmpty(p.duplicateOf.dirInfo?.Name).IsEmpty(p.duplicateOf.id)));
586 }
587 if (!p.IsValidVersion())
588 {
589 list.Add("mod_info_old_version".lang(p.version, ELayer.core.versionMod.GetText()));
590 }
591 if (!p.parseError.IsEmpty())
592 {
593 list.Add("mod_info_parse_error".lang(p.parseError));
594 }
595 SetInfo(infoProblems, string.Join("\n", list));
597 string[] tags = p.tags;
598 SetTopic(item, (tags != null && tags.Length > 0) ? string.Join(", ", p.tags) : null, null);
599 SetTopic(infoRequires, IdList(p.dependency, alternatives: true), null);
600 SetTopic(infoIncompatible, IdList(p.incompatible, alternatives: false), null);
601 SetTopic(infoLoadAfter, IdList(p.loadAfter, alternatives: false), null);
602 SetTopic(infoLoadBefore, IdList(p.loadBefore, alternatives: false), null);
603 infoSpace.SetActive(!p.description.IsEmpty());
604 SetInfo(infoDescription, p.description);
606 panelScroll.content.anchoredPosition = Vector2.zero;
607 }
608 static string IdList(string[][] rows, bool alternatives)
609 {
610 if (rows == null)
611 {
612 return null;
613 }
614 string sep = (alternatives ? "mod_info_or".lang() : "\n");
615 return string.Join("\n", from row in rows
616 where row != null && row.Length > 0
617 select string.Join(sep, row.Where((string id) => !id.IsEmpty())) into line
618 where !line.IsEmpty()
619 select line);
620 }
621 static void SetInfo(UIItem uIItem, string value)
622 {
623 uIItem.SetActive(!value.IsEmpty());
624 if (!value.IsEmpty())
625 {
626 uIItem.text1.SetText(value);
627 }
628 }
629 static void SetTopic(UIItem uIItem, string value, string lang)
630 {
631 uIItem.SetActive(!value.IsEmpty());
632 if (!value.IsEmpty())
633 {
634 if (lang != null)
635 {
636 uIItem.text1.SetText(lang.lang());
637 }
638 uIItem.text2.SetText(value);
639 }
640 }
641 }
642
644 {
645 SE.Click();
646 ModPreview.PreviewType kind;
647 bool owns;
648 Texture2D tex = LoadPreviewTexture(a, mipmap: false, out kind, out owns);
649 if (!tex)
650 {
651 SE.BeepSmall();
652 ELayer.ui.Say("mod_preview_unsupported");
653 return;
654 }
655 Sprite image = tex.ToSprite();
656 LayerImage layerImage = ELayer.ui.AddLayer<LayerImage>();
657 layerImage.SetImage(image);
658 layerImage.SetOnKill(delegate
659 {
660 UnityEngine.Object.Destroy(tex);
661 if (owns)
662 {
663 UnityEngine.Object.Destroy(tex);
664 }
665 });
666 }
667
668 private void ShowPresetMenu()
669 {
670 SE.Click();
672 {
673 Dialog.Ok("mod_preset_disabled");
674 return;
675 }
676 UIContextMenu uIContextMenu = ELayer.ui.CreateContextMenu();
677 uIContextMenu.AddButton("mod_preset_save", SavePreset);
678 uIContextMenu.AddButton("mod_preset_load", delegate
679 {
681 });
682 uIContextMenu.AddButton("mod_preset_delete", delegate
683 {
685 });
686 uIContextMenu.AddButton("mod_preset_copy", CopyPreset);
687 uIContextMenu.AddButton("mod_preset_paste", PastePreset);
688 uIContextMenu.AddButton("mod_preset_folder", delegate
689 {
690 Directory.CreateDirectory(CorePath.PathLoadOrderPreset);
691 Util.ShowExplorer(CorePath.PathLoadOrderPreset, selectFirstFile: true);
692 });
693 uIContextMenu.Show();
694 }
695
696 private void SavePreset()
697 {
698 Dialog.InputName("mod_preset_name", "mod_preset_default_name".lang(), delegate(bool cancel, string text)
699 {
700 if (!cancel)
701 {
702 string name = (text ?? "").Trim().SanitizeFileName().Trim();
703 if (name.IsEmpty())
704 {
705 SE.BeepSmall();
706 }
707 else if (File.Exists(ModManager.GetPresetPath(name)))
708 {
709 Dialog.YesNo("mod_preset_overwrite".lang(name), delegate
710 {
711 WritePreset(name);
712 });
713 }
714 else
715 {
716 WritePreset(name);
717 }
718 }
719 });
720 }
721
722 private void WritePreset(string name)
723 {
724 if (!manager.SavePreset(name, out var _))
725 {
726 SE.BeepSmall();
727 return;
728 }
729 SE.Click();
730 ELayer.ui.Say("mod_preset_saved".lang(name));
731 }
732
733 private void SelectPreset(Action<FileInfo> onSelect)
734 {
735 List<FileInfo> files = manager.ListPresets();
736 if (files.Count == 0)
737 {
738 Dialog.Ok("mod_preset_none");
739 return;
740 }
741 Dialog.List("mod_preset_select", files, (FileInfo f) => Path.GetFileNameWithoutExtension(f.Name), delegate(int i, string _)
742 {
743 onSelect(files[i]);
744 return true;
745 }, canCancel: true);
746 }
747
748 private void ApplyPresetFile(FileInfo file)
749 {
750 if (!manager.TryLoadPresetFile(file, out var preset, out var _))
751 {
752 Dialog.Ok("mod_preset_invalid");
753 }
754 else
755 {
756 ConfirmPreset(preset);
757 }
758 }
759
760 private void DeletePreset(FileInfo file)
761 {
762 string name = Path.GetFileNameWithoutExtension(file.Name);
763 Dialog.YesNo("mod_preset_delete_confirm".lang(name), delegate
764 {
765 if (file.Exists)
766 {
767 file.Delete();
768 }
769 SE.Trash();
770 ELayer.ui.Say("mod_preset_deleted".lang(name));
771 });
772 }
773
774 private void CopyPreset()
775 {
776 ModLoadOrderPreset.Preset preset = ModLoadOrderPreset.Save(manager.packages, "", ELayer.core.version.GetText());
777 if (preset.entries.Count == 0)
778 {
779 SE.BeepSmall();
780 return;
781 }
782 GUIUtility.systemCopyBuffer = ModLoadOrderPreset.Serialize(preset);
783 SE.Click();
784 ELayer.ui.Say("mod_preset_copied");
785 }
786
787 private void PastePreset()
788 {
789 if (!ModLoadOrderPreset.TryParse(GUIUtility.systemCopyBuffer, out var preset, out var _))
790 {
791 Dialog.Ok("mod_preset_invalid");
792 return;
793 }
794 if (preset.name.IsEmpty())
795 {
796 preset.name = "mod_preset_default_name".lang();
797 }
798 ConfirmPreset(preset);
799 }
800
801 private void ConfirmPreset(ModLoadOrderPreset.Preset preset)
802 {
803 List<ModLoadOrderPreset.Entry> list = ModLoadOrderPreset.FindMissing(manager.packages, preset);
804 if (list.Count == 0)
805 {
806 ApplyPreset(preset);
807 return;
808 }
809 Dialog.YesNo("mod_preset_missing".lang(DescribeEntries(list, 15)), delegate
810 {
811 ApplyPreset(preset);
812 }, null, "mod_preset_apply", "cancel");
813 }
814
815 private static string DescribeEntries(List<ModLoadOrderPreset.Entry> entries, int max)
816 {
817 StringBuilder stringBuilder = new StringBuilder();
818 for (int i = 0; i < entries.Count && i < max; i++)
819 {
820 ModLoadOrderPreset.Entry entry = entries[i];
821 stringBuilder.Append(entry.title.IsEmpty() ? entry.id : (entry.title + " (" + entry.id + ")")).Append('\n');
822 }
823 if (entries.Count > max)
824 {
825 stringBuilder.Append("mod_preset_more".lang((entries.Count - max).ToString() ?? "")).Append('\n');
826 }
827 return stringBuilder.ToString().TrimEnd();
828 }
829
830 private void ApplyPreset(ModLoadOrderPreset.Preset preset)
831 {
832 if (HasFilter)
833 {
834 ClearSearch();
835 }
836 ModLoadOrderPreset.ApplyResult applyResult = manager.ApplyPreset(preset);
837 SE.Tab();
838 textRestart.SetActive(enable: true);
839 RefreshLists();
840 string text = ELayer.core.version.GetText();
841 if (!preset.gameVersion.IsEmpty() && preset.gameVersion != text)
842 {
843 ELayer.ui.Say("mod_preset_version_warn".lang(preset.gameVersion, text));
844 }
845 ELayer.ui.Say("mod_preset_applied".lang(preset.name, applyResult.enabled.ToString() ?? "", applyResult.missing.Count.ToString() ?? ""));
846 }
847
848 public void Refresh()
849 {
850 }
851
852 public override void OnKill()
853 {
854 if ((bool)TooltipManager.Instance)
855 {
856 TooltipManager.Instance.HideTooltips(immediate: true);
857 }
858 foreach (PreviewEntry value in previews.Values)
859 {
860 if ((bool)value.sprite)
861 {
862 if (value.ownsTexture)
863 {
864 UnityEngine.Object.Destroy(value.sprite.texture);
865 }
866 UnityEngine.Object.Destroy(value.sprite);
867 }
868 }
869 previews.Clear();
871 if (Instance == this)
872 {
873 Instance = null;
874 }
875 }
876}
FontColor
Definition: FontColor.cs:2
item3. title
Definition: UIBook.cs:640
static bool IsOffline
Definition: BaseCore.cs:9
Version versionMod
Definition: BaseCore.cs:21
Version version
Definition: BaseCore.cs:17
static BaseCore Instance
Definition: BaseCore.cs:11
virtual void FreezeScreen(float duration=0.2f)
Definition: BaseCore.cs:80
UIList.ICallback callbacks
Definition: BaseList.cs:13
static string rootMod
DirectoryInfo dirInfo
string[][] loadAfter
BaseModPackage duplicateOf
void UpdateMeta(bool updateOnly=false)
string[][] loadBefore
string[][] dependency
BaseModPackage blockedBy
string[][] incompatible
void Save()
Definition: CoreConfig.cs:850
OtherSetting other
Definition: CoreConfig.cs:637
bool enable
Definition: CoreDebug.cs:302
static string PathLoadOrderPreset
Definition: CorePath.cs:208
Definition: Core.cs:14
ModManager mods
Definition: Core.cs:39
static void TryWarnUpload(Action action)
Definition: Core.cs:859
static float delta
Definition: Core.cs:17
Definition: Dialog.cs:7
static Dialog YesNo(string langDetail, Action actionYes, Action actionNo=null, string langYes="yes", string langNo="no")
Definition: Dialog.cs:252
static Dialog InputName(string langDetail, string text, Action< bool, string > onClose, InputType inputType=InputType.Default)
Definition: Dialog.cs:536
static Dialog Ok(string langDetail, Action action=null)
Definition: Dialog.cs:230
Definition: ELayer.cs:4
static Core core
Definition: ELayer.cs:7
static CoreDebug debug
Definition: ELayer.cs:43
static CoreConfig config
Definition: ELayer.cs:31
static UI ui
Definition: ELayer.cs:21
UIButton buttonActivate
Definition: ItemMod.cs:5
UIButton buttonUp
Definition: ItemMod.cs:11
UIButton buttonToggle
Definition: ItemMod.cs:15
UIButton buttonDown
Definition: ItemMod.cs:13
UIButton buttonLock
Definition: ItemMod.cs:9
Definition: Lang.cs:7
static string langCode
Definition: Lang.cs:29
void SetImage(Sprite sprite)
Definition: LayerImage.cs:12
void OnPointerEnter(PointerEventData eventData)
Definition: LayerMod.cs:26
ModPreview.PreviewType kind
Definition: LayerMod.cs:19
const string urlWorkshopItem
Definition: LayerMod.cs:32
UIList.Callback< ModPackage, ItemMod > CreateCallbacks(UIList target, bool builtin)
Definition: LayerMod.cs:191
void RefreshLists()
Definition: LayerMod.cs:151
UIItem infoPreviewNote
Definition: LayerMod.cs:60
void ShowInfo(BaseModPackage p)
Definition: LayerMod.cs:554
bool HasFilter
Definition: LayerMod.cs:109
UIItem infoProblems
Definition: LayerMod.cs:72
UIItem infoPreview
Definition: LayerMod.cs:58
UIItem infoStatus
Definition: LayerMod.cs:70
void SelectPreset(Action< FileInfo > onSelect)
Definition: LayerMod.cs:733
UIHeader panelHeader
Definition: LayerMod.cs:52
void ShowPresetMenu()
Definition: LayerMod.cs:668
UIButton buttonFilter
Definition: LayerMod.cs:88
bool Match(BaseModPackage p)
Definition: LayerMod.cs:357
void PastePreset()
Definition: LayerMod.cs:787
bool wasSearchFocused
Definition: LayerMod.cs:94
UIItem infoIncompatible
Definition: LayerMod.cs:78
string lastSearch
Definition: LayerMod.cs:96
UIList list
Definition: LayerMod.cs:36
ModManager manager
Definition: LayerMod.cs:106
UIButton buttonClearSearch
Definition: LayerMod.cs:46
static Texture2D LoadPreviewTexture(BaseModPackage p, bool mipmap, out ModPreview.PreviewType kind, out bool owns)
Definition: LayerMod.cs:497
UIItem infoWorkshop
Definition: LayerMod.cs:68
UIItem infoDescription
Definition: LayerMod.cs:84
UIItem infoTitle
Definition: LayerMod.cs:56
void CopyPreset()
Definition: LayerMod.cs:774
string[] searchTerms
Definition: LayerMod.cs:98
void Move(BaseModPackage p, int a)
Definition: LayerMod.cs:120
void RefreshFilterButton()
Definition: LayerMod.cs:432
void LateUpdate()
Definition: LayerMod.cs:454
ModSearch.Filter filterMode
Definition: LayerMod.cs:100
UIButton toggleDisableMods
Definition: LayerMod.cs:44
override void OnInit()
Definition: LayerMod.cs:161
void Search(string s)
Definition: LayerMod.cs:386
override void OnKill()
Definition: LayerMod.cs:852
void ApplyPreset(ModLoadOrderPreset.Preset preset)
Definition: LayerMod.cs:830
PreviewEntry GetThumb(BaseModPackage p)
Definition: LayerMod.cs:478
UIItem infoTags
Definition: LayerMod.cs:74
BaseModPackage panelTarget
Definition: LayerMod.cs:90
UIItem infoLoadAfter
Definition: LayerMod.cs:80
void ShowPreview(BaseModPackage a)
Definition: LayerMod.cs:643
UIItem infoVersion
Definition: LayerMod.cs:64
void ClearSearchText()
Definition: LayerMod.cs:396
static string FilterLabel(ModSearch.Filter f)
Definition: LayerMod.cs:441
static Texture2D SteamPreview(BaseModPackage p)
Definition: LayerMod.cs:529
UIList list2
Definition: LayerMod.cs:38
void ApplyPresetFile(FileInfo file)
Definition: LayerMod.cs:748
InputField inputSearch
Definition: LayerMod.cs:48
void MoveTo(BaseModPackage p, BaseModPackage target)
Definition: LayerMod.cs:134
UIText textRestart
Definition: LayerMod.cs:40
float timerSearch
Definition: LayerMod.cs:92
UIItem infoId
Definition: LayerMod.cs:66
readonly Dictionary< BaseModPackage, string > searchCache
Definition: LayerMod.cs:102
void CycleFilter()
Definition: LayerMod.cs:424
void InitSearchUI()
Definition: LayerMod.cs:366
UIItem infoLoadBefore
Definition: LayerMod.cs:82
void Refresh()
Definition: LayerMod.cs:848
void SavePreset()
Definition: LayerMod.cs:696
void WritePreset(string name)
Definition: LayerMod.cs:722
static string DescribeEntries(List< ModLoadOrderPreset.Entry > entries, int max)
Definition: LayerMod.cs:815
GameObject infoSpace
Definition: LayerMod.cs:86
readonly Dictionary< BaseModPackage, PreviewEntry > previews
Definition: LayerMod.cs:104
void DeletePreset(FileInfo file)
Definition: LayerMod.cs:760
void ClearSearch()
Definition: LayerMod.cs:406
void ConfirmPreset(ModLoadOrderPreset.Preset preset)
Definition: LayerMod.cs:801
UINote panelNote
Definition: LayerMod.cs:54
BaseModPackage FirstInfoTarget()
Definition: LayerMod.cs:538
static string FitTitle(UIText text, string title)
Definition: LayerMod.cs:340
UIItem infoRequires
Definition: LayerMod.cs:76
UIItem infoAuthor
Definition: LayerMod.cs:62
UIScrollView panelScroll
Definition: LayerMod.cs:50
static LayerMod Instance
Definition: LayerMod.cs:34
UIText textNoResult
Definition: LayerMod.cs:42
List< Window > windows
Definition: Layer.cs:116
Layer SetOnKill(Action action)
Definition: Layer.cs:579
bool TryLoadPresetFile(FileInfo file, out ModLoadOrderPreset.Preset preset, out string error)
Definition: ModManager.cs:244
ModLoadOrderPreset.ApplyResult ApplyPreset(ModLoadOrderPreset.Preset preset, bool disableOthers=true)
Definition: ModManager.cs:268
static string GetPresetPath(string name)
Definition: ModManager.cs:217
static bool disableMod
Definition: ModManager.cs:41
ModPackage AddPackage(DirectoryInfo dir, bool isInPackages=false)
Definition: ModManager.cs:353
bool SavePreset(string name, out string path)
Definition: ModManager.cs:231
void SaveLoadOrder()
Definition: ModManager.cs:104
List< FileInfo > ListPresets()
Definition: ModManager.cs:222
void CopyContentTo(string dir)
Definition: ModPackage.cs:19
override string UpdateSourceLocalizationFile(string lang, bool force=false)
Definition: ModPackage.cs:343
static TooltipManager Instance
void HideTooltips(bool immediate=false)
UIText mainText
Definition: UIButton.cs:102
void SetToggle(bool isOn, Action< bool > onToggle=null)
Definition: UIButton.cs:341
void Show(UIItem i)
void AddButton(Func< string > funcText, UnityAction action=null)
Definition: UIItem.cs:5
UIButton button1
Definition: UIItem.cs:18
UIText text2
Definition: UIItem.cs:8
UIText text1
Definition: UIItem.cs:6
Definition: UIList.cs:9
List< object > items
Definition: UIList.cs:273
override void Add(object item)
Definition: UIList.cs:354
override void List()
Definition: UIList.cs:770
Definition: UINote.cs:6
void Build()
Definition: UINote.cs:49
Definition: UIText.cs:6
void SetText(string s)
Definition: UIText.cs:163
string GetText()
Definition: Version.cs:34
bool demo
Definition: Version.cs:15