252 lines
8.5 KiB
C#
252 lines
8.5 KiB
C#
using Barotrauma.Extensions;
|
|
using System.Collections.Generic;
|
|
using System.Collections.Immutable;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Xml.Linq;
|
|
|
|
namespace Barotrauma
|
|
{
|
|
public readonly struct LanguageIdentifier
|
|
{
|
|
public static readonly LanguageIdentifier None = "None".ToLanguageIdentifier();
|
|
|
|
public readonly Identifier Value;
|
|
public int ValueHash => Value.GetHashCode();
|
|
public LanguageIdentifier(Identifier value) { Value = value; }
|
|
|
|
public override bool Equals(object obj)
|
|
{
|
|
if (obj is LanguageIdentifier other) { return this == other; }
|
|
return base.Equals(obj);
|
|
}
|
|
|
|
public override int GetHashCode() => ValueHash;
|
|
|
|
public static bool operator ==(LanguageIdentifier a, LanguageIdentifier b) => a.Value == b.Value;
|
|
public static bool operator !=(LanguageIdentifier a, LanguageIdentifier b) => !(a==b);
|
|
|
|
public override string ToString() => Value.ToString();
|
|
}
|
|
|
|
public static class LanguageIdentifierExtensions
|
|
{
|
|
public static LanguageIdentifier ToLanguageIdentifier(this Identifier identifier)
|
|
{
|
|
return new LanguageIdentifier(identifier);
|
|
}
|
|
|
|
public static LanguageIdentifier ToLanguageIdentifier(this string str)
|
|
{
|
|
return str.ToIdentifier().ToLanguageIdentifier();
|
|
}
|
|
}
|
|
|
|
public class TextPack
|
|
{
|
|
public readonly TextFile ContentFile;
|
|
|
|
public readonly LanguageIdentifier Language;
|
|
|
|
public readonly record struct Text(
|
|
string String,
|
|
bool IsOverride,
|
|
TextPack TextPack);
|
|
|
|
|
|
private ImmutableDictionary<Identifier, ImmutableArray<Text>> texts;
|
|
|
|
public ImmutableDictionary<Identifier, ImmutableArray<Text>> Texts
|
|
{
|
|
get
|
|
{
|
|
if (texts == null)
|
|
{
|
|
DebugConsole.NewMessage($"Accessed texts in an unloaded text package ({Language}). Loading the text pack...");
|
|
VerifyLoaded();
|
|
}
|
|
return texts;
|
|
}
|
|
}
|
|
public readonly string TranslatedName;
|
|
public readonly bool NoWhitespace;
|
|
|
|
public TextPack(TextFile file, ContentXElement mainElement, LanguageIdentifier language, bool load = false)
|
|
{
|
|
ContentFile = file;
|
|
|
|
var languageName = mainElement.GetAttributeIdentifier("language", Identifier.Empty);
|
|
if (languageName.IsEmpty)
|
|
{
|
|
DebugConsole.AddWarning($"Language not defined in text file \"{file.Path}\". Setting the language as {TextManager.DefaultLanguage}.",
|
|
mainElement.ContentPackage);
|
|
languageName = TextManager.DefaultLanguage.Value;
|
|
}
|
|
Language = language;
|
|
TranslatedName = mainElement.GetAttributeString("translatedname", languageName.Value);
|
|
NoWhitespace = mainElement.GetAttributeBool("nowhitespace", false);
|
|
|
|
if (load)
|
|
{
|
|
VerifyLoaded();
|
|
}
|
|
}
|
|
|
|
public void VerifyLoaded()
|
|
{
|
|
//already loaded
|
|
if (this.texts != null) { return; }
|
|
|
|
XDocument doc = XMLExtensions.TryLoadXml(ContentFile.Path);
|
|
var mainElement = doc.Root.FromPackage(ContentFile.ContentPackage);
|
|
|
|
Dictionary<Identifier, List<Text>> texts = new Dictionary<Identifier, List<Text>>();
|
|
LoadElements(mainElement, isOverride: mainElement.IsOverride());
|
|
|
|
void LoadElements(XElement parentElement, bool isOverride)
|
|
{
|
|
foreach (var element in parentElement.Elements())
|
|
{
|
|
Identifier elemName = element.NameAsIdentifier();
|
|
|
|
if (element.IsOverride())
|
|
{
|
|
LoadElements(element, isOverride: true);
|
|
}
|
|
else
|
|
{
|
|
if (!texts.ContainsKey(elemName)) { texts.Add(elemName, new List<Text>()); }
|
|
|
|
string str = element.ElementInnerText()
|
|
.Replace(@"\n", "\n")
|
|
.Replace("&", "&")
|
|
.Replace("<", "<")
|
|
.Replace(">", ">")
|
|
.Replace(""", "\"")
|
|
.Replace("'", "'");
|
|
|
|
texts[elemName].Add(new Text(str, isOverride, this));
|
|
}
|
|
}
|
|
}
|
|
|
|
this.texts = texts.Select(kvp => (kvp.Key, kvp.Value.ToImmutableArray())).ToImmutableDictionary();
|
|
}
|
|
|
|
public void Unload()
|
|
{
|
|
texts = null;
|
|
}
|
|
|
|
#if DEBUG
|
|
public void CheckForDuplicates(int index)
|
|
{
|
|
Dictionary<Identifier, int> tagCounts = new Dictionary<Identifier, int>();
|
|
Dictionary<string, int> contentCounts = new Dictionary<string, int>();
|
|
|
|
XDocument doc = XMLExtensions.TryLoadXml(ContentFile.Path);
|
|
if (doc == null) { return; }
|
|
|
|
foreach (var subElement in doc.Root.Elements())
|
|
{
|
|
Identifier infoName = subElement.NameAsIdentifier();
|
|
if (!tagCounts.ContainsKey(infoName))
|
|
{
|
|
tagCounts.Add(infoName, 1);
|
|
}
|
|
else
|
|
{
|
|
tagCounts[infoName] += 1;
|
|
}
|
|
|
|
string infoContent = subElement.Value;
|
|
if (string.IsNullOrEmpty(infoContent)) { continue; }
|
|
if (!contentCounts.ContainsKey(infoContent))
|
|
{
|
|
contentCounts.Add(infoContent, 1);
|
|
}
|
|
else
|
|
{
|
|
contentCounts[infoContent] += 1;
|
|
}
|
|
}
|
|
|
|
StringBuilder sb = new StringBuilder();
|
|
sb.Append("Language: " + Language);
|
|
sb.AppendLine();
|
|
sb.Append("Duplicate tags:");
|
|
sb.AppendLine();
|
|
sb.AppendLine();
|
|
|
|
List<string> lines = new List<string>();
|
|
for (int i = 0; i < tagCounts.Keys.Count; i++)
|
|
{
|
|
if (tagCounts[Texts.Keys.ElementAt(i)] > 1)
|
|
{
|
|
lines.Add(Texts.Keys.ElementAt(i) + " | Count: " + tagCounts[Texts.Keys.ElementAt(i)]);
|
|
}
|
|
}
|
|
foreach (string line in lines.OrderBy(l => l))
|
|
{
|
|
sb.AppendLine(line);
|
|
}
|
|
sb.AppendLine();
|
|
sb.AppendLine();
|
|
sb.Append("Duplicate content:");
|
|
sb.AppendLine();
|
|
sb.AppendLine();
|
|
|
|
for (int i = 0; i < contentCounts.Keys.Count; i++)
|
|
{
|
|
if (contentCounts[contentCounts.Keys.ElementAt(i)] > 1)
|
|
{
|
|
sb.Append(contentCounts.Keys.ElementAt(i) + " | Count: " + contentCounts[contentCounts.Keys.ElementAt(i)]);
|
|
sb.AppendLine();
|
|
}
|
|
}
|
|
|
|
Barotrauma.IO.File.WriteAllText($"duplicate_{Language.ToString().ToLower()}_{index}.txt", sb.ToString());
|
|
}
|
|
|
|
public void WriteToCSV(int index)
|
|
{
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
XDocument doc = XMLExtensions.TryLoadXml(ContentFile.Path);
|
|
if (doc == null) { return; }
|
|
|
|
List<(string key, string value)> texts = new List<(string key, string value)>();
|
|
|
|
foreach (var element in doc.Root.Elements())
|
|
{
|
|
string text = element.ElementInnerText()
|
|
.Replace("&", "&")
|
|
.Replace("<", "<")
|
|
.Replace(">", ">")
|
|
.Replace(""", "\"")
|
|
.Replace("'", "'");
|
|
|
|
texts.Add((element.Name.ToString(), text));
|
|
}
|
|
|
|
foreach ((string key, string value) in texts)
|
|
{
|
|
sb.Append(key); // ID
|
|
sb.Append('*');
|
|
sb.Append(value); // Original
|
|
sb.Append('*');
|
|
// Translated
|
|
sb.Append('*');
|
|
// Comments
|
|
sb.AppendLine();
|
|
|
|
}
|
|
|
|
string fileName = $"csv_{Language.ToString().ToLower()}_{index}.csv";
|
|
Barotrauma.IO.File.WriteAllText(fileName, sb.ToString());
|
|
|
|
DebugConsole.NewMessage($"Wrote \"{ContentFile.Path}\" to \"{fileName}\"");
|
|
}
|
|
#endif
|
|
}
|
|
} |