diff --git a/MinecraftUSkinEditor/Classes/FileTypes/LOCFile.cs b/MinecraftUSkinEditor/Classes/FileTypes/LOCFile.cs index b98b2f96..6860182c 100644 --- a/MinecraftUSkinEditor/Classes/FileTypes/LOCFile.cs +++ b/MinecraftUSkinEditor/Classes/FileTypes/LOCFile.cs @@ -9,12 +9,17 @@ namespace PckStudio.Classes.FileTypes { public class LOCFile { - // loc key => language, name - public Dictionary> keys { get; set; } = new Dictionary>(); + public class InvalidLanguageException : Exception + { + private string _language; + public string Language => _language; + public InvalidLanguageException(string message, string language) : base(message) + { + _language = language; + } + } - public List languages = new List(valid_languages.Length); - - public static readonly string[] valid_languages = new string[] + public static readonly string[] ValidLanguages = new string[] { "cs-CS", "cs-CZ", @@ -84,63 +89,96 @@ namespace PckStudio.Classes.FileTypes "zh-HanS", "zh-HanT", }; - public void InitializeDefault(string PackName) + + private Dictionary> _lockeys = new Dictionary>(); + private List _languages = new List(ValidLanguages.Length); + public Dictionary> LocKeys => _lockeys; + public List Languages => _languages; + + public void InitializeDefault(string packName) + => Initialize("en-EN", ("IDS_DISPLAY_NAME", packName)); + public void Initialize(string language, params (string, string)[] locKeyValuePairs) { - AddLanguage("en-EN"); - AddLocKey("IDS_DISPLAY_NAME", PackName); + AddLanguage(language); + foreach (var locKeyValue in locKeyValuePairs) + AddLocKey(locKeyValue.Item1, locKeyValue.Item2); } - - public void AddSingleLocKey(string locKey, string language, string value) + public string GetLocEntry(string locKey, string language) { - if (keys.ContainsKey(locKey)) throw new Exception("Loc key already exists"); - if (!languages.Contains(language)) throw new Exception("Language not found"); - var dict = new Dictionary(); - dict.Add(language, value); - keys.Add(locKey, dict); + if (!LocKeys.ContainsKey(locKey)) + throw new KeyNotFoundException("Loc key not found"); + if (!Languages.Contains(language)) throw new KeyNotFoundException("Language Entry not found"); + return GetTranslation(locKey)[language]?? string.Empty; } - public void AddLocKey(string locKey, string value) + private Dictionary GetTranslation(string locKey) { - if (string.IsNullOrEmpty(locKey) || string.IsNullOrEmpty(value)) - throw new ArgumentNullException("string cant be null"); - if (keys.ContainsKey(locKey)) - throw new Exception("loc key already exists"); - foreach (var langauge in languages) - { - AddSingleLocKey(locKey, langauge, value); - } + if (!LocKeys.ContainsKey(locKey)) + LocKeys.Add(locKey, new Dictionary()); + return LocKeys[locKey]; } - public void ChangeSingleEntry(string locKey, string language, string newValue) + + public void SetLocEntry(string locKey, string language, string value) { - if (!keys.ContainsKey(locKey)) throw new KeyNotFoundException("Loc key not found"); - if (!keys[locKey].ContainsKey(language) || !languages.Contains(language)) throw new KeyNotFoundException("Language Entry not found"); - keys[locKey][language] = newValue; + if (!LocKeys.ContainsKey(locKey)) + LocKeys.Add(locKey, new Dictionary()); + if (!Languages.Contains(language)) + throw new KeyNotFoundException(nameof(language)); + GetTranslation(locKey)[language] = value; } + public bool AddSingleLocEntry(string locKey, string language, string value) + { + if (string.IsNullOrEmpty(locKey) || + string.IsNullOrEmpty(language) || + string.IsNullOrEmpty(value) || + LocKeys.ContainsKey(locKey)) + return false; + SetLocEntry(locKey, language, value); + return true; + } + + public bool AddLocKey(string locKey, string value) + { + if (LocKeys.ContainsKey(locKey)) + return false; + Languages.ForEach( langauge => AddSingleLocEntry(locKey, langauge, value) ); + return true; + } + public void ChangeSingleEntry(string locKey, string language, string newValue) + => SetLocEntry(locKey, language, newValue); + public void ChangeEntry(string locKey, string newValue) - { - if (string.IsNullOrEmpty(locKey) || string.IsNullOrEmpty(newValue)) - throw new ArgumentNullException("string cant be null"); - if (!keys.ContainsKey(locKey)) - throw new KeyNotFoundException("loc key not found"); - foreach (var langauge in languages) - { - ChangeSingleEntry(locKey, langauge, newValue); - } - } + => Languages.ForEach(langauge => SetLocEntry(locKey, langauge, newValue)); - - public void RemoveEntry(string locKey) + public void RemoveLocKey(string locKey) { - if (!keys.ContainsKey(locKey)) throw new KeyNotFoundException("Loc key not found"); - keys.Remove(locKey); + if (!LocKeys.ContainsKey(locKey)) + throw new KeyNotFoundException(nameof(locKey)); + LocKeys.Remove(locKey); } public void AddLanguage(string language) { - if (!valid_languages.Contains(language)) throw new Exception("Invalid language"); - languages.Add(language); + if (!ValidLanguages.Contains(language)) + throw new InvalidLanguageException("Invalid language", language); + if (Languages.Contains(language)) + throw new InvalidLanguageException("Language already exists", language); + Languages.Add(language); + foreach(var key in LocKeys.Keys) + SetLocEntry(key, language, ""); + } + + public void RemoveLanguage(string language) + { + if (!ValidLanguages.Contains(language)) + throw new InvalidLanguageException("Invalid language", language); + if (!Languages.Contains(language)) + throw new InvalidLanguageException("Language doesn't exist", language); + if (Languages.Remove(language)) + foreach (var translation in LocKeys.Values) + translation.Remove(language); } } } \ No newline at end of file diff --git a/MinecraftUSkinEditor/Classes/IO/LOC/LOCFileReader.cs b/MinecraftUSkinEditor/Classes/IO/LOC/LOCFileReader.cs index 6b8f4974..ea5914e7 100644 --- a/MinecraftUSkinEditor/Classes/IO/LOC/LOCFileReader.cs +++ b/MinecraftUSkinEditor/Classes/IO/LOC/LOCFileReader.cs @@ -25,12 +25,12 @@ namespace PckStudio.Classes.IO.LOC { int loc_type = ReadInt(stream); int language_count = ReadInt(stream); - List keys = null; - if (loc_type == 2) keys = ReadKeys(stream); + bool lookUpKey = loc_type == 2; + List keys = lookUpKey ? ReadKeys(stream) : null; for (int i = 0; i < language_count; i++) { string language = ReadString(stream); - _file.languages.Add(language); + _file.Languages.Add(language); ReadInt(stream); // padding ??? } for (int i = 0; i < language_count; i++) @@ -38,21 +38,14 @@ namespace PckStudio.Classes.IO.LOC ReadInt(stream); stream.ReadByte(); string language = ReadString(stream); - if (!_file.languages.Contains(language)) + if (!_file.Languages.Contains(language)) throw new Exception("language not found"); int count = ReadInt(stream); for (int j = 0; j < count; j++) { - string key = loc_type == 2 ? keys[j] : ReadString(stream); + string key = lookUpKey ? keys[j] : ReadString(stream); string value = ReadString(stream); - if (_file.keys.ContainsKey(key)) - { - _file.keys[key].Add(language, value); - continue; - } - var dict = new Dictionary(); - dict.Add(language, value); - _file.keys.Add(key, dict); + _file.SetLocEntry(key, language, value); } } return _file; diff --git a/MinecraftUSkinEditor/Classes/IO/LOC/LOCFileWriter.cs b/MinecraftUSkinEditor/Classes/IO/LOC/LOCFileWriter.cs index 18d85fd2..e80ca4d5 100644 --- a/MinecraftUSkinEditor/Classes/IO/LOC/LOCFileWriter.cs +++ b/MinecraftUSkinEditor/Classes/IO/LOC/LOCFileWriter.cs @@ -25,7 +25,7 @@ namespace PckStudio.Classes.IO.LOC { if (_locfile == null) throw new ArgumentNullException("Loc File is null"); WriteInt(stream, type); - WriteInt(stream, _locfile.languages.Count); + WriteInt(stream, _locfile.Languages.Count); if (type == 2) WriteLocKeys(stream); WriteLanguages(stream); WriteLanguageEntries(stream, type); @@ -35,14 +35,14 @@ namespace PckStudio.Classes.IO.LOC private void WriteLocKeys(Stream stream) { stream.WriteByte(0); - WriteInt(stream, _locfile.keys.Count); - foreach (var key in _locfile.keys.Keys) + WriteInt(stream, _locfile.LocKeys.Count); + foreach (var key in _locfile.LocKeys.Keys) WriteString(stream, key); } private void WriteLanguages(Stream stream) { - foreach (var language in _locfile.languages) + foreach (var language in _locfile.Languages) { WriteString(stream, language); WriteInt(stream, 0); @@ -51,16 +51,16 @@ namespace PckStudio.Classes.IO.LOC private void WriteLanguageEntries(Stream stream, int type) { - foreach (var language in _locfile.languages) + foreach (var language in _locfile.Languages) { WriteInt(stream, 0x1337); stream.WriteByte(0); WriteString(stream, language); - WriteInt(stream, _locfile.keys.Keys.Count); - foreach(var locKey in _locfile.keys.Keys) + WriteInt(stream, _locfile.LocKeys.Keys.Count); + foreach(var locKey in _locfile.LocKeys.Keys) { if (type == 0) WriteString(stream, locKey); - WriteString(stream, _locfile.keys[locKey][language]); + WriteString(stream, _locfile.LocKeys[locKey][language]); } } } diff --git a/MinecraftUSkinEditor/MainForm.cs b/MinecraftUSkinEditor/MainForm.cs index 2e02463e..936f0166 100644 --- a/MinecraftUSkinEditor/MainForm.cs +++ b/MinecraftUSkinEditor/MainForm.cs @@ -353,7 +353,7 @@ namespace PckStudio foreach (var property in file.properties) { if (property.Item1 == "THEMENAMEID" || property.Item1 == "DISPLAYNAMEID") - locFile.RemoveEntry(property.Item2); + locFile.RemoveLocKey(property.Item2); } TrySetLocFile(locFile); }