190 lines
6.2 KiB
C#
190 lines
6.2 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
|
|
|
|
namespace BrewMonster
|
|
{
|
|
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;
|
|
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 = textAsset.text;
|
|
|
|
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 (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;
|
|
}
|
|
}
|
|
} |