Client LuaCsForBarotrauma
ModMerger.cs
1 #nullable enable
2 using System;
3 using System.Linq;
4 using Barotrauma.Steam;
5 using Barotrauma.IO;
6 
7 namespace Barotrauma
8 {
9  public static class ModMerger
10  {
11  public static void AskMerge(ContentPackage[] mods)
12  {
13  ErrorIfNonLocal(mods);
14 
15  var msgBox = new GUIMessageBox(TextManager.Get("MergeModsHeader"), "", relativeSize: (0.5f, 0.8f),
16  buttons: new LocalizedString[] { TextManager.Get("ConfirmModMerge"), TextManager.Get("Cancel") });
17  msgBox.Buttons[1].OnClicked = msgBox.Close;
18 
19  var desc = new GUITextBlock(new RectTransform((1.0f, 0.1f), msgBox.Content.RectTransform), TextManager.Get("MergeModsDesc"));
20  var modsList = new GUIListBox(new RectTransform((1.0f, 0.5f), msgBox.Content.RectTransform))
21  {
22  OnSelected = (component, o) => false,
23  HoverCursor = CursorState.Default
24  };
25  foreach (var mod in mods)
26  {
27  new GUITextBlock(new RectTransform((1.0f, 0.11f), modsList.Content.RectTransform), mod.Name)
28  {
29  CanBeFocused = false
30  };
31  }
32  var footer = new GUITextBlock(new RectTransform((1.0f, 0.1f), msgBox.Content.RectTransform), TextManager.Get("MergeModsFooter"));
33  var resultName = new GUITextBox(new RectTransform((1.0f, 0.1f), msgBox.Content.RectTransform))
34  {
35  Text = (mods.Count(m => m.Files.Length > 1)==1)
36  ? mods.First(m => m.Files.Length > 1).Name
37  : ""
38  };
39 
40  void flashText()
41  {
42  resultName!.Select();
43  resultName.Flash(GUIStyle.Red);
44  }
45 
46  msgBox.Buttons[0].OnClicked = (button, o) =>
47  {
48  if (string.IsNullOrEmpty(resultName.Text))
49  {
50  flashText();
51  return false;
52  }
53  string targetDir = $"{ContentPackage.LocalModsDir}/{resultName.Text}";
54 
55  bool dirMatches(ContentPackage mod)
56  => mod.Dir.CleanUpPathCrossPlatform(correctFilenameCase: false)
57  .Equals(targetDir, StringComparison.OrdinalIgnoreCase);
58  if (ContentPackageManager.LocalPackages.Any(dirMatches)
59  && !mods.Any(dirMatches))
60  {
61  flashText();
62  return false;
63  }
64 
65  MergeMods(mods, resultName.Text);
66  msgBox.Close();
67  return false;
68  };
69  }
70 
71  private static void MergeMods(ContentPackage[] mods, string resultName)
72  {
73  ModProject resultProject = new ModProject
74  {
75  Name = resultName
76  };
77 
78  string targetDir = $"{ContentPackage.LocalModsDir}/{resultName}";
79  Directory.CreateDirectory(targetDir);
80 
81  foreach (var mod in mods)
82  {
83  foreach (var file in Directory.GetFiles(mod.Dir, "*", System.IO.SearchOption.AllDirectories)
84  .Select(f => f.CleanUpPathCrossPlatform(correctFilenameCase: false)))
85  {
86  if (Path.GetFileName(file).Equals(ContentPackage.FileListFileName, StringComparison.OrdinalIgnoreCase)) { continue; }
87 
88  string targetFilePath = file[mod.Dir.Length..];
89  if (targetFilePath.StartsWith("/") || targetFilePath.StartsWith("\\"))
90  {
91  targetFilePath = targetFilePath[1..];
92  }
93 
94  targetFilePath = Path.Combine(targetDir, targetFilePath).CleanUpPathCrossPlatform(correctFilenameCase: false);
95  //DebugConsole.NewMessage(targetFilePath);
96 
97  Directory.CreateDirectory(Path.GetDirectoryName(targetFilePath)!);
98  File.Copy(file, targetFilePath, overwrite: true);
99 
100  var oldFileInProject = resultProject.Files.FirstOrDefault(f
101  => f.Path.Equals(targetFilePath, StringComparison.OrdinalIgnoreCase));
102  if (oldFileInProject != null)
103  {
104  resultProject.RemoveFile(oldFileInProject);
105  }
106 
107  var fileInMod = mod.Files.Find(f => f.Path == file);
108  if (fileInMod != null)
109  {
110  var newFileInProject = ModProject.File.FromPath(targetFilePath, fileInMod.GetType());
111  resultProject.AddFile(newFileInProject);
112  }
113  }
114  }
115  resultProject.Save(Path.Combine(targetDir, ContentPackage.FileListFileName));
116 
117  foreach (var mod in mods)
118  {
119  Directory.Delete(mod.Dir);
120  }
121  (SettingsMenu.Instance!.WorkshopMenu as MutableWorkshopMenu)!.PopulateInstalledModLists(forceRefreshEnabled: true, refreshDisabled: true);
122  }
123 
124  private static void ErrorIfNonLocal(ContentPackage[] mods)
125  {
126  var nonLocal = mods.Where(m => !ContentPackageManager.LocalPackages.Contains(m)).ToArray();
127  if (nonLocal.Any())
128  {
129  throw new Exception($"{string.Join(", ", nonLocal.Select(m => m.Name))} are not local mods");
130  }
131  }
132  }
133 }
CursorState
Definition: GUI.cs:40