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  for (int i = 0; i < tagCounts.Keys.Count; i++)
150  {
151  if (tagCounts[Texts.Keys.ElementAt(i)] > 1)
152  {
153  sb.Append(Texts.Keys.ElementAt(i) + " | Count: " + tagCounts[Texts.Keys.ElementAt(i)]);
154  sb.AppendLine();
155  }
156  }
157 
158  sb.AppendLine();
159  sb.AppendLine();
160  sb.Append("Duplicate content:");
161  sb.AppendLine();
162  sb.AppendLine();
163 
164  for (int i = 0; i < contentCounts.Keys.Count; i++)
165  {
166  if (contentCounts[contentCounts.Keys.ElementAt(i)] > 1)
167  {
168  sb.Append(contentCounts.Keys.ElementAt(i) + " | Count: " + contentCounts[contentCounts.Keys.ElementAt(i)]);
169  sb.AppendLine();
170  }
171  }
172 
173  Barotrauma.IO.File.WriteAllText($"duplicate_{Language.ToString().ToLower()}_{index}.txt", sb.ToString());
174  }
175 
176  public void WriteToCSV(int index)
177  {
178  StringBuilder sb = new StringBuilder();
179 
180  XDocument doc = XMLExtensions.TryLoadXml(ContentFile.Path);
181  if (doc == null) { return; }
182 
183  List<(string key, string value)> texts = new List<(string key, string value)>();
184 
185  foreach (var element in doc.Root.Elements())
186  {
187  string text = element.ElementInnerText()
188  .Replace("&amp;", "&")
189  .Replace("&lt;", "<")
190  .Replace("&gt;", ">")
191  .Replace("&quot;", "\"")
192  .Replace("&apos;", "'");
193 
194  texts.Add((element.Name.ToString(), text));
195  }
196 
197  foreach ((string key, string value) in texts)
198  {
199  sb.Append(key); // ID
200  sb.Append('*');
201  sb.Append(value); // Original
202  sb.Append('*');
203  // Translated
204  sb.Append('*');
205  // Comments
206  sb.AppendLine();
207 
208  }
209 
210  Barotrauma.IO.File.WriteAllText($"csv_{Language.ToString().ToLower()}_{index}.csv", sb.ToString());
211  }
212 #endif
213  }
214 }
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