using System.Collections.Generic; using System.Text; using System.IO; using System.Text.RegularExpressions; using Microsoft.Win32; namespace Server { public class ClilocTranslator { private static byte[] m_Buffer = new byte[1024]; private static Dictionary clilocStringList; private static string language = "enu"; private static string clientPath = @"D:\Program\Ultima Online 2D\"; //private static string clientPath = @"D:\Ultima Online Samurai Empire\"; #region UOSDK Code private static List GetClientPaths() { List list = new List(); string possibleClientPath = GetExePath("Ultima Online"); if (possibleClientPath != null) list.Add(possibleClientPath); possibleClientPath = GetExePath("Ultima Online Third Dawn"); if (possibleClientPath != null) list.Add(possibleClientPath); list.Add(clientPath); return list; } private static string GetExePath(string subName) { try { using (RegistryKey key = Registry.LocalMachine.OpenSubKey(string.Format(@"SOFTWARE\Origin Worlds Online\{0}\1.0", subName))) { if (key == null) return null; string v = key.GetValue("ExePath") as string; if (v == null || v.Length <= 0 || !File.Exists(v)) return null; v = Path.GetDirectoryName(v); if (v == null) return null; return v; } } catch { return null; } } public static string GetFilePath(string file) { List dirs = GetClientPaths(); for (int i = 0; i < dirs.Count; ++i) { string path = Path.Combine(dirs[i], file); if (File.Exists(path)) return path; } return null; } #endregion public static void Start() { if (language == null || language == "") language = "enu"; //TODO: Fix this like the SDK string path = GetFilePath(string.Format("cliloc.{0}", language)); clilocStringList = new Dictionary(); #region Ultima SDK code + mod using (BinaryReader bin = new BinaryReader(new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read))) { bin.ReadInt32(); bin.ReadInt16(); while (bin.PeekChar() != -1) { int number = bin.ReadInt32(); bin.ReadByte(); int length = bin.ReadInt16(); if (length > m_Buffer.Length) m_Buffer = new byte[(length + 1023) & ~1023]; bin.Read(m_Buffer, 0, length); clilocStringList[number] = new ClilocStringEntry(Encoding.UTF8.GetString(m_Buffer, 0, length)); } } #endregion } public static string GetString(int number, bool plural) { if (number == 0) return ""; if (!clilocStringList.ContainsKey(number)) return string.Format("ClilocTranslator : Doesn't contain key {0}, contact the admin.", number); if (plural) return clilocStringList[number].Plural; else return clilocStringList[number].Singular; } public static string GetString(int number) { if (number == 0) return ""; if (!clilocStringList.ContainsKey(number)) return string.Format("ClilocTranslator : Doesn't contain key {0}, contact the admin.", number); return clilocStringList[number].Singular; } } class ClilocStringEntry { string singular; string plural; public string Singular { get { return singular; } set { singular = value; } } public string Plural { get { return plural; } set { plural = value; } } public ClilocStringEntry(string clilocString) { if (clilocString.Contains("~")) clilocString = FormatVars(clilocString); singular = clilocString; if ((singular.Length - 1) >= 0 && singular[singular.Length - 1] != 's') plural = singular + "s"; else plural = singular; } public string FormatVars(string text) { Regex r = new Regex("~(.+?)~"); MatchCollection mC = r.Matches(text); for (int i = 0; i < mC.Count; i++) text = text.Replace(mC[i].ToString(), string.Format("{{0}}", i)); return text; } } }