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 m_AStrTab = new Dictionary(); private readonly Dictionary m_WStrTab = new Dictionary(); 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(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(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 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; } }