Files
test/Assets/Scripts/CECStringTab.cs
T
2025-09-18 18:07:23 +07:00

191 lines
5.7 KiB
C#

using ModelRenderer.Scripts.Common;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using UnityEngine; // thêm để dùng Resources & TextAsset
public class CECStringTab
{
private readonly Dictionary<int, string> m_AStrTab = new Dictionary<int, string>();
private readonly Dictionary<int, string> m_WStrTab = new Dictionary<int, string>();
private bool m_bInit = false;
private bool m_bUnicode = false;
public CECStringTab() { }
~CECStringTab() { Release(); }
public bool Init(string szFile, bool bUnicode)
{
Release();
m_bUnicode = bUnicode;
try
{
bool ok = bUnicode ? LoadWideStrings(szFile) : LoadANSIStrings(szFile);
m_bInit = ok;
foreach(var str in m_AStrTab.Values)
{
BrewMonster.Logger.Log("HoangDev: m_AStrTab.Values" + str);
}
return ok;
}
catch (Exception e)
{
Debug.LogError($"[CECStringTab] Init failed: {e}");
Release();
return false;
}
}
public void Release()
{
m_AStrTab.Clear();
m_WStrTab.Clear();
m_bInit = false;
m_bUnicode = false;
}
public string GetANSIString(int n) => m_AStrTab.TryGetValue(n, out var s) ? s : null;
public string GetWideString(int n) => m_WStrTab.TryGetValue(n, out var s) ? s : null;
public string GetWideStringObject(int n) => GetWideString(n);
public bool IsInitialized() => m_bInit;
// ==== Đọc từ Resources thay vì đường dẫn ====
protected bool LoadANSIStrings(string resourceName)
{
TextAsset textAsset = Resources.Load<TextAsset>(resourceName);
if (textAsset == null)
{
Debug.LogError($"[CECStringTab] Resource not found: {resourceName}");
return false;
}
// Giải mã bytes -> string (ANSI: dùng Encoding.Default)
string content = ByteToStringUtils.ByteArrayToCP936String(textAsset.bytes);
using var sr = new StringReader(content);
return ParseIntoDict(sr, isWide: false);
}
protected bool LoadWideStrings(string resourceName)
{
TextAsset textAsset = Resources.Load<TextAsset>(resourceName);
if (textAsset == null)
{
Debug.LogError($"[CECStringTab] Resource not found: {resourceName}");
return false;
}
// Unity TextAsset mặc định đã decode text UTF8 -> textAsset.text
// nhưng để chắc chắn BOM/Unicode thì đọc từ bytes
string content;
content = ByteToStringUtils.ByteArrayToUnicodeString(textAsset.bytes);
using var sr = new StringReader(content);
return ParseIntoDict(sr, isWide: true);
}
private static Encoding DetectEncoding(byte[] bom)
{
if (bom.Length >= 3 && bom[0] == 0xEF && bom[1] == 0xBB && bom[2] == 0xBF) return Encoding.UTF8;
if (bom.Length >= 2 && bom[0] == 0xFF && bom[1] == 0xFE) return Encoding.Unicode;
if (bom.Length >= 2 && bom[0] == 0xFE && bom[1] == 0xFF) return Encoding.BigEndianUnicode;
return null;
}
private bool ParseIntoDict(StringReader sr, bool isWide)
{
bool bIndexMode = false;
bool bBegan = false;
int autoIndex = 0;
var allLines = new List<string>();
string line;
while ((line = sr.ReadLine()) != null)
{
allLines.Add(line);
}
for (int i = 0; i < allLines.Count; i++)
{
var ln = allLines[i].Trim();
if (ln.Length == 0) continue;
if (ln.Equals("#_index", StringComparison.OrdinalIgnoreCase))
{
bIndexMode = true;
}
else if (ln.Equals("#_begin", StringComparison.OrdinalIgnoreCase))
{
bBegan = true;
for (int j = i + 1; j < allLines.Count; j++)
{
var payload = allLines[j].Trim();
if (payload.Length == 0) continue;
if (payload.StartsWith("#")) continue;
if (bIndexMode)
{
if (!TrySplitIndexAndText(payload, out int idx, out string text))
continue;
PutString(idx, text, isWide);
}
else
{
PutString(autoIndex++, payload, isWide);
}
}
break;
}
}
return bBegan;
}
private static bool TrySplitIndexAndText(string line, out int index, out string text)
{
index = 0; text = null;
int eq = line.IndexOf('=');
if (eq >= 0)
{
var left = line.Substring(0, eq).Trim();
var right = line.Substring(eq + 1);
if (int.TryParse(left, out index))
{
text = right;
return true;
}
return false;
}
int sp = FirstWhiteSpaceIndex(line);
if (sp <= 0) return false;
var left2 = line.Substring(0, sp).Trim();
var right2 = line.Substring(sp).TrimStart();
if (int.TryParse(left2, out index))
{
text = right2;
return true;
}
return false;
}
private static int FirstWhiteSpaceIndex(string s)
{
for (int i = 0; i < s.Length; i++)
if (char.IsWhiteSpace(s[i])) return i;
return -1;
}
private void PutString(int id, string value, bool isWide)
{
if (isWide) m_WStrTab[id] = value;
else m_AStrTab[id] = value;
}
}