Authored Unity primitive/object-model shim, VFX layer (control-flow-preserving, InstantVfx never invokes its action -- headless suppression), god-object stubs (GameMgr/EffectMgr/UIManager with faithfully-extracted nested enums), View/UI/Touch tree, LitJson+BetterList+Tuple copied, third-party stubs. Discovered Roslyn header-error masking: fixing class-header type errors unmasks body references, so the true copy closure is ~2570 files (was 782 under masking). Errors: masked-25720 -> 268; our shim files compile clean. Remaining: ~50 residual shim/external types, 24 NGUI UI-base overrides, static-type fixes, plus likely 1-2 more unmask waves.
528 lines
11 KiB
C#
528 lines
11 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
public static class Localization
|
|
{
|
|
public delegate byte[] LoadFunction(string path);
|
|
|
|
public delegate void OnLocalizeNotification();
|
|
|
|
public static LoadFunction loadFunction;
|
|
|
|
public static OnLocalizeNotification onLocalize;
|
|
|
|
public static bool localizationHasBeenSet = false;
|
|
|
|
private static string[] mLanguages = null;
|
|
|
|
private static Dictionary<string, string> mOldDictionary = new Dictionary<string, string>();
|
|
|
|
private static Dictionary<string, string[]> mDictionary = new Dictionary<string, string[]>();
|
|
|
|
private static Dictionary<string, string> mReplacement = new Dictionary<string, string>();
|
|
|
|
private static int mLanguageIndex = -1;
|
|
|
|
private static string mLanguage;
|
|
|
|
private static bool mMerging = false;
|
|
|
|
public static Dictionary<string, string[]> dictionary
|
|
{
|
|
get
|
|
{
|
|
if (!localizationHasBeenSet)
|
|
{
|
|
LoadDictionary(PlayerPrefs.GetString("Language", "English"));
|
|
}
|
|
return mDictionary;
|
|
}
|
|
set
|
|
{
|
|
localizationHasBeenSet = value != null;
|
|
mDictionary = value;
|
|
}
|
|
}
|
|
|
|
public static string[] knownLanguages
|
|
{
|
|
get
|
|
{
|
|
if (!localizationHasBeenSet)
|
|
{
|
|
LoadDictionary(PlayerPrefs.GetString("Language", "English"));
|
|
}
|
|
return mLanguages;
|
|
}
|
|
}
|
|
|
|
public static string language
|
|
{
|
|
get
|
|
{
|
|
if (string.IsNullOrEmpty(mLanguage))
|
|
{
|
|
mLanguage = PlayerPrefs.GetString("Language", "English");
|
|
LoadAndSelect(mLanguage);
|
|
}
|
|
return mLanguage;
|
|
}
|
|
set
|
|
{
|
|
if (mLanguage != value)
|
|
{
|
|
mLanguage = value;
|
|
LoadAndSelect(value);
|
|
}
|
|
}
|
|
}
|
|
|
|
[Obsolete("Localization is now always active. You no longer need to check this property.")]
|
|
public static bool isActive => true;
|
|
|
|
private static bool LoadDictionary(string value)
|
|
{
|
|
byte[] array = null;
|
|
if (!localizationHasBeenSet)
|
|
{
|
|
if (loadFunction == null)
|
|
{
|
|
TextAsset textAsset = Resources.Load<TextAsset>("Localization");
|
|
if (textAsset != null)
|
|
{
|
|
array = textAsset.bytes;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
array = loadFunction("Localization");
|
|
}
|
|
localizationHasBeenSet = true;
|
|
}
|
|
if (LoadCSV(array))
|
|
{
|
|
return true;
|
|
}
|
|
if (string.IsNullOrEmpty(value))
|
|
{
|
|
value = mLanguage;
|
|
}
|
|
if (string.IsNullOrEmpty(value))
|
|
{
|
|
return false;
|
|
}
|
|
if (loadFunction == null)
|
|
{
|
|
TextAsset textAsset2 = Resources.Load<TextAsset>(value);
|
|
if (textAsset2 != null)
|
|
{
|
|
array = textAsset2.bytes;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
array = loadFunction(value);
|
|
}
|
|
if (array != null)
|
|
{
|
|
Set(value, array);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private static bool LoadAndSelect(string value)
|
|
{
|
|
if (!string.IsNullOrEmpty(value))
|
|
{
|
|
if (mDictionary.Count == 0 && !LoadDictionary(value))
|
|
{
|
|
return false;
|
|
}
|
|
if (SelectLanguage(value))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
if (mOldDictionary.Count > 0)
|
|
{
|
|
return true;
|
|
}
|
|
mOldDictionary.Clear();
|
|
mDictionary.Clear();
|
|
if (string.IsNullOrEmpty(value))
|
|
{
|
|
PlayerPrefs.DeleteKey("Language");
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public static void Load(TextAsset asset)
|
|
{
|
|
ByteReader byteReader = new ByteReader(asset);
|
|
Set(asset.name, byteReader.ReadDictionary());
|
|
}
|
|
|
|
public static void Set(string languageName, byte[] bytes)
|
|
{
|
|
ByteReader byteReader = new ByteReader(bytes);
|
|
Set(languageName, byteReader.ReadDictionary());
|
|
}
|
|
|
|
public static void ReplaceKey(string key, string val)
|
|
{
|
|
if (!string.IsNullOrEmpty(val))
|
|
{
|
|
mReplacement[key] = val;
|
|
}
|
|
else
|
|
{
|
|
mReplacement.Remove(key);
|
|
}
|
|
}
|
|
|
|
public static void ClearReplacements()
|
|
{
|
|
mReplacement.Clear();
|
|
}
|
|
|
|
public static bool LoadCSV(TextAsset asset, bool merge = false)
|
|
{
|
|
return LoadCSV(asset.bytes, asset, merge);
|
|
}
|
|
|
|
public static bool LoadCSV(byte[] bytes, bool merge = false)
|
|
{
|
|
return LoadCSV(bytes, null, merge);
|
|
}
|
|
|
|
private static bool HasLanguage(string languageName)
|
|
{
|
|
int i = 0;
|
|
for (int num = mLanguages.Length; i < num; i++)
|
|
{
|
|
if (mLanguages[i] == languageName)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private static bool LoadCSV(byte[] bytes, TextAsset asset, bool merge = false)
|
|
{
|
|
if (bytes == null)
|
|
{
|
|
return false;
|
|
}
|
|
ByteReader byteReader = new ByteReader(bytes);
|
|
BetterList<string> betterList = byteReader.ReadCSV();
|
|
if (betterList.size < 2)
|
|
{
|
|
return false;
|
|
}
|
|
betterList.RemoveAt(0);
|
|
string[] array = null;
|
|
if (string.IsNullOrEmpty(mLanguage))
|
|
{
|
|
localizationHasBeenSet = false;
|
|
}
|
|
if (!localizationHasBeenSet || (!merge && !mMerging) || mLanguages == null || mLanguages.Length == 0)
|
|
{
|
|
mDictionary.Clear();
|
|
mLanguages = new string[betterList.size];
|
|
if (!localizationHasBeenSet)
|
|
{
|
|
mLanguage = PlayerPrefs.GetString("Language", betterList[0]);
|
|
localizationHasBeenSet = true;
|
|
}
|
|
for (int i = 0; i < betterList.size; i++)
|
|
{
|
|
mLanguages[i] = betterList[i];
|
|
if (mLanguages[i] == mLanguage)
|
|
{
|
|
mLanguageIndex = i;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
array = new string[betterList.size];
|
|
for (int j = 0; j < betterList.size; j++)
|
|
{
|
|
array[j] = betterList[j];
|
|
}
|
|
for (int k = 0; k < betterList.size; k++)
|
|
{
|
|
if (HasLanguage(betterList[k]))
|
|
{
|
|
continue;
|
|
}
|
|
int num = mLanguages.Length + 1;
|
|
Array.Resize(ref mLanguages, num);
|
|
mLanguages[num - 1] = betterList[k];
|
|
Dictionary<string, string[]> dictionary = new Dictionary<string, string[]>();
|
|
foreach (KeyValuePair<string, string[]> item in mDictionary)
|
|
{
|
|
string[] array2 = item.Value;
|
|
Array.Resize(ref array2, num);
|
|
array2[num - 1] = array2[0];
|
|
dictionary.Add(item.Key, array2);
|
|
}
|
|
mDictionary = dictionary;
|
|
}
|
|
}
|
|
Dictionary<string, int> dictionary2 = new Dictionary<string, int>();
|
|
for (int l = 0; l < mLanguages.Length; l++)
|
|
{
|
|
dictionary2.Add(mLanguages[l], l);
|
|
}
|
|
while (true)
|
|
{
|
|
BetterList<string> betterList2 = byteReader.ReadCSV();
|
|
if (betterList2 == null || betterList2.size == 0)
|
|
{
|
|
break;
|
|
}
|
|
if (!string.IsNullOrEmpty(betterList2[0]))
|
|
{
|
|
AddCSV(betterList2, array, dictionary2);
|
|
}
|
|
}
|
|
if (!mMerging && onLocalize != null)
|
|
{
|
|
mMerging = true;
|
|
OnLocalizeNotification onLocalizeNotification = onLocalize;
|
|
onLocalize = null;
|
|
onLocalizeNotification();
|
|
onLocalize = onLocalizeNotification;
|
|
mMerging = false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
private static void AddCSV(BetterList<string> newValues, string[] newLanguages, Dictionary<string, int> languageIndices)
|
|
{
|
|
if (newValues.size < 2)
|
|
{
|
|
return;
|
|
}
|
|
string text = newValues[0];
|
|
if (string.IsNullOrEmpty(text))
|
|
{
|
|
return;
|
|
}
|
|
string[] value = ExtractStrings(newValues, newLanguages, languageIndices);
|
|
if (mDictionary.ContainsKey(text))
|
|
{
|
|
mDictionary[text] = value;
|
|
return;
|
|
}
|
|
try
|
|
{
|
|
mDictionary.Add(text, value);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Debug.LogError("Unable to add '" + text + "' to the Localization dictionary.\n" + ex.Message);
|
|
}
|
|
}
|
|
|
|
private static string[] ExtractStrings(BetterList<string> added, string[] newLanguages, Dictionary<string, int> languageIndices)
|
|
{
|
|
if (newLanguages == null)
|
|
{
|
|
string[] array = new string[mLanguages.Length];
|
|
int i = 1;
|
|
for (int num = Mathf.Min(added.size, array.Length + 1); i < num; i++)
|
|
{
|
|
array[i - 1] = added[i];
|
|
}
|
|
return array;
|
|
}
|
|
string key = added[0];
|
|
if (!mDictionary.TryGetValue(key, out var value))
|
|
{
|
|
value = new string[mLanguages.Length];
|
|
}
|
|
int j = 0;
|
|
for (int num2 = newLanguages.Length; j < num2; j++)
|
|
{
|
|
string key2 = newLanguages[j];
|
|
int num3 = languageIndices[key2];
|
|
value[num3] = added[j + 1];
|
|
}
|
|
return value;
|
|
}
|
|
|
|
private static bool SelectLanguage(string language)
|
|
{
|
|
mLanguageIndex = -1;
|
|
if (mDictionary.Count == 0)
|
|
{
|
|
return false;
|
|
}
|
|
int i = 0;
|
|
for (int num = mLanguages.Length; i < num; i++)
|
|
{
|
|
if (mLanguages[i] == language)
|
|
{
|
|
mOldDictionary.Clear();
|
|
mLanguageIndex = i;
|
|
mLanguage = language;
|
|
PlayerPrefs.SetString("Language", mLanguage);
|
|
if (onLocalize != null)
|
|
{
|
|
onLocalize();
|
|
}
|
|
UIRoot.Broadcast("OnLocalize");
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public static void Set(string languageName, Dictionary<string, string> dictionary)
|
|
{
|
|
mLanguage = languageName;
|
|
PlayerPrefs.SetString("Language", mLanguage);
|
|
mOldDictionary = dictionary;
|
|
localizationHasBeenSet = true;
|
|
mLanguageIndex = -1;
|
|
mLanguages = new string[1] { languageName };
|
|
if (onLocalize != null)
|
|
{
|
|
onLocalize();
|
|
}
|
|
UIRoot.Broadcast("OnLocalize");
|
|
}
|
|
|
|
public static void Set(string key, string value)
|
|
{
|
|
if (mOldDictionary.ContainsKey(key))
|
|
{
|
|
mOldDictionary[key] = value;
|
|
}
|
|
else
|
|
{
|
|
mOldDictionary.Add(key, value);
|
|
}
|
|
}
|
|
|
|
public static string Get(string key)
|
|
{
|
|
if (!localizationHasBeenSet)
|
|
{
|
|
LoadDictionary(PlayerPrefs.GetString("Language", "English"));
|
|
}
|
|
if (mLanguages == null)
|
|
{
|
|
Debug.LogError("No localization data present");
|
|
return null;
|
|
}
|
|
string text = language;
|
|
if (mLanguageIndex == -1)
|
|
{
|
|
for (int i = 0; i < mLanguages.Length; i++)
|
|
{
|
|
if (mLanguages[i] == text)
|
|
{
|
|
mLanguageIndex = i;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (mLanguageIndex == -1)
|
|
{
|
|
mLanguageIndex = 0;
|
|
mLanguage = mLanguages[0];
|
|
}
|
|
string value;
|
|
string[] value2;
|
|
switch (UICamera.currentScheme)
|
|
{
|
|
case UICamera.ControlScheme.Touch:
|
|
{
|
|
string key3 = key + " Mobile";
|
|
if (mReplacement.TryGetValue(key3, out value))
|
|
{
|
|
return value;
|
|
}
|
|
if (mLanguageIndex != -1 && mDictionary.TryGetValue(key3, out value2) && mLanguageIndex < value2.Length)
|
|
{
|
|
return value2[mLanguageIndex];
|
|
}
|
|
if (mOldDictionary.TryGetValue(key3, out value))
|
|
{
|
|
return value;
|
|
}
|
|
break;
|
|
}
|
|
case UICamera.ControlScheme.Controller:
|
|
{
|
|
string key2 = key + " Controller";
|
|
if (mReplacement.TryGetValue(key2, out value))
|
|
{
|
|
return value;
|
|
}
|
|
if (mLanguageIndex != -1 && mDictionary.TryGetValue(key2, out value2) && mLanguageIndex < value2.Length)
|
|
{
|
|
return value2[mLanguageIndex];
|
|
}
|
|
if (mOldDictionary.TryGetValue(key2, out value))
|
|
{
|
|
return value;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
if (mReplacement.TryGetValue(key, out value))
|
|
{
|
|
return value;
|
|
}
|
|
if (mLanguageIndex != -1 && mDictionary.TryGetValue(key, out value2))
|
|
{
|
|
if (mLanguageIndex < value2.Length)
|
|
{
|
|
string text2 = value2[mLanguageIndex];
|
|
if (string.IsNullOrEmpty(text2))
|
|
{
|
|
text2 = value2[0];
|
|
}
|
|
return text2;
|
|
}
|
|
return value2[0];
|
|
}
|
|
if (mOldDictionary.TryGetValue(key, out value))
|
|
{
|
|
return value;
|
|
}
|
|
return key;
|
|
}
|
|
|
|
public static string Format(string key, params object[] parameters)
|
|
{
|
|
return string.Format(Get(key), parameters);
|
|
}
|
|
|
|
[Obsolete("Use Localization.Get instead")]
|
|
public static string Localize(string key)
|
|
{
|
|
return Get(key);
|
|
}
|
|
|
|
public static bool Exists(string key)
|
|
{
|
|
if (!localizationHasBeenSet)
|
|
{
|
|
language = PlayerPrefs.GetString("Language", "English");
|
|
}
|
|
if (!mDictionary.ContainsKey(key))
|
|
{
|
|
return mOldDictionary.ContainsKey(key);
|
|
}
|
|
return true;
|
|
}
|
|
}
|