Client LuaCsForBarotrauma
TextPack.cs
2 using System.Collections.Generic;
3 using System.Collections.Immutable;
4 using System.Linq;
5 using System.Text;
6 using System.Xml.Linq;
7 
8 namespace Barotrauma
9 {
10  public readonly struct LanguageIdentifier
11  {
12  public static readonly LanguageIdentifier None = "None".ToLanguageIdentifier();
13 
14  public readonly Identifier Value;
15  public int ValueHash => Value.GetHashCode();
16  public LanguageIdentifier(Identifier value) { Value = value; }
17 
18  public override bool Equals(object obj)
19  {
20  if (obj is LanguageIdentifier other) { return this == other; }
21  return base.Equals(obj);
22  }
23 
24  public override int GetHashCode() => ValueHash;
25 
26  public static bool operator ==(LanguageIdentifier a, LanguageIdentifier b) => a.Value == b.Value;
27  public static bool operator !=(LanguageIdentifier a, LanguageIdentifier b) => !(a==b);
28 
29  public override string ToString() => Value.ToString();
30  }
31 
32  public static class LanguageIdentifierExtensions
33  {
34  public static LanguageIdentifier ToLanguageIdentifier(this Identifier identifier)
35  {
36  return new LanguageIdentifier(identifier);
37  }
38 
39  public static LanguageIdentifier ToLanguageIdentifier(this string str)
40  {
41  return str.ToIdentifier().ToLanguageIdentifier();
42  }
43  }
44 
45  public class TextPack
46  {
47  public readonly TextFile ContentFile;
48 
49  public readonly LanguageIdentifier Language;
50 
51 
52  public readonly record struct Text(
53  string String,
54  bool IsOverride,
56 
57  public readonly ImmutableDictionary<Identifier, ImmutableArray<Text>> Texts;
58  public readonly string TranslatedName;
59  public readonly bool NoWhitespace;
60 
61  public TextPack(TextFile file, ContentXElement mainElement, LanguageIdentifier language)
62  {
63  ContentFile = file;
64 
65  var languageName = mainElement.GetAttributeIdentifier("language", Identifier.Empty);
66  if (languageName.IsEmpty)
67  {
68  DebugConsole.AddWarning($"Language not defined in text file \"{file.Path}\". Setting the language as {TextManager.DefaultLanguage}.",
69  mainElement.ContentPackage);
70  languageName = TextManager.DefaultLanguage.Value;
71  }
72  Language = language;
73  TranslatedName = mainElement.GetAttributeString("translatedname", languageName.Value);
74  NoWhitespace = mainElement.GetAttributeBool("nowhitespace", false);
75 
76  Dictionary<Identifier, List<Text>> texts = new Dictionary<Identifier, List<Text>>();
77  LoadElements(mainElement, isOverride: mainElement.IsOverride());
78 
79  void LoadElements(XElement parentElement, bool isOverride)
80  {
81  foreach (var element in parentElement.Elements())
82  {
83  Identifier elemName = element.NameAsIdentifier();
84 
85  if (element.IsOverride())
86  {
87  LoadElements(element, isOverride: true);
88  }
89  else
90  {
91  if (!texts.ContainsKey(elemName)) { texts.Add(elemName, new List<Text>()); }
92 
93  string str = element.ElementInnerText()
94  .Replace(@"\n", "\n")
95  .Replace("&amp;", "&")
96  .Replace("&lt;", "<")
97  .Replace("&gt;", ">")
98  .Replace("&quot;", "\"")
99  .Replace("&apos;", "'");
100 
101  texts[elemName].Add(new Text(str, isOverride, this));
102  }
103  }
104  }
105 
106  Texts = texts.Select(kvp => (kvp.Key, kvp.Value.ToImmutableArray())).ToImmutableDictionary();
107  }
108 
109 #if DEBUG
110  public void CheckForDuplicates(int index)
111  {
112  Dictionary<Identifier, int> tagCounts = new Dictionary<Identifier, int>();
113  Dictionary<string, int> contentCounts = new Dictionary<string, int>();
114 
115  XDocument doc = XMLExtensions.TryLoadXml(ContentFile.Path);
116  if (doc == null) { return; }
117 
118  foreach (var subElement in doc.Root.Elements())
119  {
120  Identifier infoName = subElement.NameAsIdentifier();
121  if (!tagCounts.ContainsKey(infoName))
122  {
123  tagCounts.Add(infoName, 1);
124  }
125  else
126  {
127  tagCounts[infoName] += 1;
128  }
129 
130  string infoContent = subElement.Value;
131  if (string.IsNullOrEmpty(infoContent)) { continue; }
132  if (!contentCounts.ContainsKey(infoContent))
133  {
134  contentCounts.Add(infoContent, 1);
135  }
136  else
137  {
138  contentCounts[infoContent] += 1;
139  }
140  }
141 
142  StringBuilder sb = new StringBuilder();
143  sb.Append("Language: " + Language);
144  sb.AppendLine();
145  sb.Append("Duplicate tags:");
146  sb.AppendLine();
147  sb.AppendLine();
148 
149  List<string> lines = new List<string>();
150  for (int i = 0; i < tagCounts.Keys.Count; i++)
151  {
152  if (tagCounts[Texts.Keys.ElementAt(i)] > 1)
153  {
154  lines.Add(Texts.Keys.ElementAt(i) + " | Count: " + tagCounts[Texts.Keys.ElementAt(i)]);
155  }
156  }
157  foreach (string line in lines.OrderBy(l => l))
158  {
159  sb.AppendLine(line);
160  }
161  sb.AppendLine();
162  sb.AppendLine();
163  sb.Append("Duplicate content:");
164  sb.AppendLine();
165  sb.AppendLine();
166 
167  for (int i = 0; i < contentCounts.Keys.Count; i++)
168  {
169  if (contentCounts[contentCounts.Keys.ElementAt(i)] > 1)
170  {
171  sb.Append(contentCounts.Keys.ElementAt(i) + " | Count: " + contentCounts[contentCounts.Keys.ElementAt(i)]);
172  sb.AppendLine();
173  }
174  }
175 
176  Barotrauma.IO.File.WriteAllText($"duplicate_{Language.ToString().ToLower()}_{index}.txt", sb.ToString());
177  }
178 
179  public void WriteToCSV(int index)
180  {
181  StringBuilder sb = new StringBuilder();
182 
183  XDocument doc = XMLExtensions.TryLoadXml(ContentFile.Path);
184  if (doc == null) { return; }
185 
186  List<(string key, string value)> texts = new List<(string key, string value)>();
187 
188  foreach (var element in doc.Root.Elements())
189  {
190  string text = element.ElementInnerText()
191  .Replace("&amp;", "&")
192  .Replace("&lt;", "<")
193  .Replace("&gt;", ">")
194  .Replace("&quot;", "\"")
195  .Replace("&apos;", "'");
196 
197  texts.Add((element.Name.ToString(), text));
198  }
199 
200  foreach ((string key, string value) in texts)
201  {
202  sb.Append(key); // ID
203  sb.Append('*');
204  sb.Append(value); // Original
205  sb.Append('*');
206  // Translated
207  sb.Append('*');
208  // Comments
209  sb.AppendLine();
210 
211  }
212 
213  Barotrauma.IO.File.WriteAllText($"csv_{Language.ToString().ToLower()}_{index}.csv", sb.ToString());
214  }
215 #endif
216  }
217 }
Base class for content file types, which are loaded from filelist.xml via reflection....
Definition: ContentFile.cs:23
readonly ContentPath Path
Definition: ContentFile.cs:137
string? GetAttributeString(string key, string? def)
ContentPackage? ContentPackage
bool GetAttributeBool(string key, bool def)
Identifier GetAttributeIdentifier(string key, string def)
readonly record struct Text(string String, bool IsOverride, TextPack TextPack)
readonly TextFile ContentFile
Definition: TextPack.cs:47
readonly ImmutableDictionary< Identifier, ImmutableArray< Text > > Texts
Definition: TextPack.cs:57
readonly bool NoWhitespace
Definition: TextPack.cs:59
readonly LanguageIdentifier Language
Definition: TextPack.cs:49
readonly string TranslatedName
Definition: TextPack.cs:58
TextPack(TextFile file, ContentXElement mainElement, LanguageIdentifier language)
Definition: TextPack.cs:61
static bool operator!=(LanguageIdentifier a, LanguageIdentifier b)
LanguageIdentifier(Identifier value)
Definition: TextPack.cs:16
override bool Equals(object obj)
Definition: TextPack.cs:18
override string ToString()
static bool operator==(LanguageIdentifier a, LanguageIdentifier b)
static readonly LanguageIdentifier None
Definition: TextPack.cs:12
readonly Identifier Value
Definition: TextPack.cs:14