Move LOC processing to OMI lib

This commit is contained in:
miku-666
2023-03-13 14:46:33 +01:00
parent 05b2dfc1e3
commit d42061bbf3
9 changed files with 12 additions and 352 deletions

View File

@@ -1,184 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PckStudio.Classes.FileTypes
{
public class LOCFile
{
public class InvalidLanguageException : Exception
{
public string Language { get; }
public InvalidLanguageException(string message, string language) : base(message)
{
Language = language;
}
}
public static readonly string[] ValidLanguages = new string[]
{
"cs-CS",
"cs-CZ",
"da-CH",
"da-DA",
"da-DK",
"de-AT",
"de-DE",
"el-EL",
"el-GR",
"en-AU",
"en-CA",
"en-EN",
"en-GB",
"en-GR",
"en-IE",
"en-NZ",
"en-US",
"es-ES",
"es-MX",
"fi-BE",
"fi-CH",
"fi-FI",
"fr-FR",
"fr-CA",
"it-IT",
"ja-JP",
"ko-KR",
"la-LAS",
"no-NO",
"nb-NO",
"nl-NL",
"nl-BE",
"pl-PL",
"pt-BR",
"pt-PT",
"ru-RU",
"sk-SK",
"sv-SE",
"tr-TR",
"zh-CN",
"zh-HK",
"zh-SG",
"zh-TW",
"zh-CHT",
"zh-HanS",
"zh-HanT",
};
private Dictionary<string, Dictionary<string, string>> _lockeys = new Dictionary<string, Dictionary<string, string>>();
private List<string> _languages = new List<string>(ValidLanguages.Length);
public Dictionary<string, Dictionary<string, string>> LocKeys => _lockeys;
public List<string> Languages => _languages;
public void InitializeDefault(string packName)
=> Initialize("en-EN", ("IDS_DISPLAY_NAME", packName));
public void Initialize(string language, params (string, string)[] locKeyValuePairs)
{
AddLanguage(language);
foreach (var locKeyValue in locKeyValuePairs)
AddLocKey(locKeyValue.Item1, locKeyValue.Item2);
}
private Dictionary<string, string> GetTranslation(string locKey)
{
if (!LocKeys.ContainsKey(locKey))
LocKeys.Add(locKey, new Dictionary<string, string>());
return LocKeys[locKey];
}
public Dictionary<string, string> GetLocEntries(string locKey)
{
if (!LocKeys.ContainsKey(locKey))
throw new KeyNotFoundException("Loc key not found");
return LocKeys[locKey];
}
public bool HasLocEntry(string locKey)
=> LocKeys.ContainsKey(locKey);
public string GetLocEntry(string locKey, string language)
{
if (!LocKeys.ContainsKey(locKey))
throw new KeyNotFoundException(nameof(locKey));
if (!Languages.Contains(language)) throw new KeyNotFoundException("Language Entry not found");
return GetTranslation(locKey)[language]?? string.Empty;
}
public void SetLocEntry(string locKey, string value)
{
foreach (var language in Languages)
{
GetTranslation(locKey)[language] = value;
}
}
public void SetLocEntry(string locKey, string language, string value)
{
if (!Languages.Contains(language))
throw new KeyNotFoundException(nameof(language));
GetTranslation(locKey)[language] = value;
}
public bool AddLocKey(string locKey, string value)
{
if (LocKeys.ContainsKey(locKey))
return false;
Languages.ForEach( language => SetLocEntry(locKey, language, value) );
return true;
}
public bool RemoveLocKey(string locKey)
{
if (!LocKeys.ContainsKey(locKey))
return false;
return LocKeys.Remove(locKey);
}
public void AddLanguage(string 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);
}
}
}

View File

@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OMI.Formats.Languages;
namespace PckStudio.Classes.FileTypes
{

View File

@@ -1,72 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using PckStudio.Classes.FileTypes;
namespace PckStudio.Classes.IO.LOC
{
internal class LOCFileReader : StreamDataReader<LOCFile>
{
internal LOCFile _file;
public static LOCFile Read(Stream stream)
{
return new LOCFileReader().ReadFromStream(stream);
}
private LOCFileReader() : base(false)
{
_file = new LOCFile();
}
protected override LOCFile ReadFromStream(Stream stream)
{
int loc_type = ReadInt(stream);
int language_count = ReadInt(stream);
bool lookUpKey = loc_type == 2;
List<string> keys = lookUpKey ? ReadKeys(stream) : null;
for (int i = 0; i < language_count; i++)
{
string language = ReadString(stream);
ReadInt(stream); // unknown value
_file.Languages.Add(language);
}
for (int i = 0; i < language_count; i++)
{
if (0 < ReadInt(stream))
stream.ReadByte();
string language = ReadString(stream);
if (!_file.Languages.Contains(language))
throw new KeyNotFoundException(nameof(language));
int count = ReadInt(stream);
for (int j = 0; j < count; j++)
{
string key = lookUpKey ? keys[j] : ReadString(stream);
string value = ReadString(stream);
_file.SetLocEntry(key, language, value);
}
}
return _file;
}
private List<string> ReadKeys(Stream stream)
{
bool useUniqueIds = Convert.ToBoolean(stream.ReadByte());
int keyCount = ReadInt(stream);
List<string> keys = new List<string>(keyCount);
for (int i = 0; i < keyCount; i++)
{
string key = useUniqueIds ? ReadInt(stream).ToString("X08") : ReadString(stream);
keys.Add(key);
}
return keys;
}
private string ReadString(Stream stream)
{
int length = ReadShort(stream);
return ReadString(stream, length, Encoding.UTF8);
}
}
}

View File

@@ -1,89 +0,0 @@
using PckStudio.Classes.FileTypes;
using System;
using System.IO;
using System.Text;
namespace PckStudio.Classes.IO.LOC
{
internal class LOCFileWriter : StreamDataWriter
{
private LOCFile _locfile;
private int _type;
public static void Write(Stream stream, LOCFile file, int type = 2)
{
new LOCFileWriter(file, type).WriteToStream(stream);
}
private LOCFileWriter(LOCFile file, int type) : base(false)
{
_type = type;
_locfile = file;
}
protected override void WriteToStream(Stream stream)
{
_ = _locfile ?? throw new ArgumentNullException(nameof(_locfile));
WriteInt(stream, _type);
WriteInt(stream, _locfile.Languages.Count);
if (_type == 2) WriteLocKeys(stream);
WriteLanguages(stream, _type);
WriteLanguageEntries(stream, _type);
}
private void WriteLocKeys(Stream stream)
{
stream.WriteByte(0); // dont use stringIds(ints)
WriteInt(stream, _locfile.LocKeys.Count);
foreach (var key in _locfile.LocKeys.Keys)
WriteString(stream, key);
}
private void WriteLanguages(Stream stream, int type)
{
foreach(var language in _locfile.Languages)
{
WriteString(stream, language);
//Calculate the size of the language entry
int size = 0;
size += sizeof(int); // null long
size += sizeof(byte); // null byte
size += (sizeof(short) + Encoding.UTF8.GetByteCount(language)); // language name string
size += sizeof(int); // key count
foreach (var locKey in _locfile.LocKeys.Keys)
{
if (type == 0) size += (2 + Encoding.UTF8.GetByteCount(locKey)); // loc key string
size += (2 + Encoding.UTF8.GetByteCount(_locfile.LocKeys[locKey][language])); // loc key string
}
WriteInt(stream, size);
};
}
private void WriteLanguageEntries(Stream stream, int type)
{
foreach (var language in _locfile.Languages)
{
WriteInt(stream, 0x6D696B75); // :P
stream.WriteByte(0); // <- only write when the previous written int was >0
WriteString(stream, language);
WriteInt(stream, _locfile.LocKeys.Keys.Count);
foreach(var locKey in _locfile.LocKeys.Keys)
{
if (type == 0) WriteString(stream, locKey);
WriteString(stream, _locfile.LocKeys[locKey][language]);
}
};
}
private void WriteString(Stream stream, string s)
{
WriteShort(stream, Convert.ToInt16(Encoding.UTF8.GetByteCount(s)));
WriteString(stream, s, Encoding.UTF8);
}
}
}

View File

@@ -11,6 +11,7 @@ using PckStudio.Classes;
using PckStudio.Classes.FileTypes;
using PckStudio.Classes.IO.PCK;
using PckStudio.Forms.Additional_Popups.Audio;
using OMI.Formats.Languages;
// Audio Editor by MattNL
// additional work and optimization by Miku-666

View File

@@ -7,8 +7,9 @@ using System.Windows.Forms;
using MetroFramework.Forms;
using PckStudio.Classes.Misc;
using PckStudio.Classes.FileTypes;
using PckStudio.Classes.IO.LOC;
using PckStudio.Forms.Additional_Popups.Loc;
using OMI.Formats.Languages;
using OMI.Workers.Language;
namespace PckStudio.Forms.Editor
{
@@ -24,7 +25,8 @@ namespace PckStudio.Forms.Editor
_file = file;
using (var ms = new MemoryStream(file.Data))
{
currentLoc = LOCFileReader.Read(ms);
var reader = new LOCFileReader();
currentLoc = reader.FromStream(ms);
}
tbl = new DataTable();
tbl.Columns.Add(new DataColumn("Language") { ReadOnly = true });

View File

@@ -7,6 +7,7 @@ using PckStudio.Classes.FileTypes;
using System.Drawing.Imaging;
using PckStudio.Classes.Utils;
using PckStudio.Classes._3ds.Utils;
using OMI.Formats.Languages;
namespace PckStudio
{

View File

@@ -10,9 +10,11 @@ using System.Drawing.Imaging;
using OMI.Formats.GameRule;
using OMI.Workers.GameRule;
using OMI.Formats.Languages;
using OMI.Workers.Language;
using PckStudio.Properties;
using PckStudio.Classes.FileTypes;
using PckStudio.Classes.IO.LOC;
using PckStudio.Classes.IO.PCK;
using PckStudio.Classes.Utils;
using PckStudio.Classes.Utils.ARC;
@@ -1530,7 +1532,8 @@ namespace PckStudio
{
using (var stream = new MemoryStream(locdata.Data))
{
locFile = LOCFileReader.Read(stream);
var reader = new LOCFileReader();
locFile = reader.FromStream(stream);
}
return true;
}

View File

@@ -194,8 +194,6 @@
<Compile Include="Classes\Utils\SkinANIM.cs" />
<Compile Include="Classes\FileTypes\PCKProperties.cs" />
<Compile Include="Classes\FileTypes\PCKFile.cs" />
<Compile Include="Classes\IO\LOC\LOCFileReader.cs" />
<Compile Include="Classes\IO\LOC\LOCFileWriter.cs" />
<Compile Include="Classes\IO\PCK\PCKFileReader.cs" />
<Compile Include="Classes\IO\PCK\PCKFileWriter.cs" />
<Compile Include="Classes\IO\StreamDataReader.cs" />
@@ -464,7 +462,6 @@
<Compile Include="Classes\ToolboxItems\InterpolationPictureBox.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="Classes\FileTypes\LOCFile.cs" />
<Compile Include="Forms\Additional-Popups\MetaList.cs">
<SubType>Form</SubType>
</Compile>