using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;
using BepInEx;
using BepInEx.Logging;
using CustomFont;
using GlobalEnums;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;
using Silksong.DataManager;
using Silksong.ModMenu.Elements;
using Silksong.ModMenu.Plugin;
using Silksong.ModMenu.Screens;
using TMProOld;
using TeamCherry.Localization;
using TeamCherry.SharedUtils;
using UnityEngine;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("CustomTranslation")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.2.0.0")]
[assembly: AssemblyInformationalVersion("0.2.0+601cf85de81e98a6b78919bf27e1a25ae87a40f5")]
[assembly: AssemblyProduct("CustomTranslation")]
[assembly: AssemblyTitle("CustomTranslation")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/CarrieForle/CustomTranslationSilksong")]
[assembly: NeutralResourcesLanguage("EN")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.2.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace BepInEx
{
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
[Conditional("CodeGeneration")]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class BepInAutoPluginAttribute : Attribute
{
public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
{
}
}
}
namespace BepInEx.Preloader.Core.Patching
{
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
[Conditional("CodeGeneration")]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class PatcherAutoPluginAttribute : Attribute
{
public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
{
}
}
}
namespace Microsoft.CodeAnalysis
{
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace CustomTranslation
{
public enum TranslationFileKind
{
Single,
Splitted
}
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInPlugin("io.github.carrieforle.customtranslation", "CustomTranslation", "0.2.0")]
public class CustomTranslationPlugin : BaseUnityPlugin, IGlobalDataMod<GlobalData>, IRawGlobalDataMod, IModMenuCustomMenu, IModMenuInterface
{
public const string ENTRY_FILENAME = "entry.json";
public const string METADATA_FILENAME = "metadata.json";
public const string ASSET_DIRNAME = "assets";
public static LanguageReader languageReader = new LanguageReader();
public static DirectoryInfo translationDir;
public static DirectoryInfo dir;
internal static ManualLogSource logger;
public static CustomTranslationPlugin Instance;
private Harmony harmony;
private GlobalData? globalData;
public const string Id = "io.github.carrieforle.customtranslation";
public GlobalData? GlobalData
{
get
{
if (globalData == null)
{
globalData = new GlobalData();
}
return globalData;
}
set
{
globalData = value;
}
}
public static string Name => "CustomTranslation";
public static string Version => "0.2.0";
private void Awake()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Expected O, but got Unknown
harmony = new Harmony("io.github.carrieforle.customtranslation");
harmony.PatchAll(typeof(Patch));
logger = ((BaseUnityPlugin)this).Logger;
dir = new DirectoryInfo(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location));
translationDir = DirectoryHelper.TryCreateRecursive(dir, "translation");
Instance = this;
RefreshLanguage();
}
private void Start()
{
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_0055: Unknown result type (might be due to invalid IL or missing references)
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
harmony.PatchAll(typeof(LanguagePatch));
((BaseUnityPlugin)this).Logger.LogInfo((object)"Patched Language class");
LanguagePatch.LoadAvailableLanguages();
LanguageCode? val = GlobalData?.Language;
if (val.HasValue)
{
LanguageCode valueOrDefault = val.GetValueOrDefault();
if (languageReader.ContainsKey(valueOrDefault))
{
Language.DoSwitch(valueOrDefault);
}
}
}
private static IList<TranslationEntry> GetTranslationEntries()
{
List<TranslationEntry> list = new List<TranslationEntry>();
DirectoryInfo[] directories = DirectoryHelper.TryCreate(translationDir).GetDirectories();
string[] validExtensions = new string[2] { ".txt", ".bytes" };
DirectoryInfo[] array = directories;
foreach (DirectoryInfo directoryInfo in array)
{
if (File.Exists(Path.Combine(directoryInfo.FullName, "metadata.json")))
{
if (File.Exists(Path.Combine(directoryInfo.FullName, "entry.json")))
{
list.Add(new TranslationEntry(directoryInfo, TranslationFileKind.Single));
}
else if (directoryInfo.GetFiles().Any((FileInfo f) => ((ReadOnlySpan<string>)validExtensions).IndexOf(f.Extension) != -1))
{
list.Add(new TranslationEntry(directoryInfo, TranslationFileKind.Splitted));
}
}
}
return list;
}
public static void RefreshLanguage()
{
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
//IL_0096: Unknown result type (might be due to invalid IL or missing references)
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
IList<TranslationEntry> translationEntries = GetTranslationEntries();
languageReader = new LanguageReader();
foreach (TranslationEntry item in translationEntries)
{
try
{
TranslationMetadata translationMetadata = TranslationMetadata.ReadFrom(item);
Translation value = new Translation(translationMetadata, item);
if (languageReader.TryGetValue(translationMetadata.Language, out Translation translation))
{
logger.LogWarning((object)$"Found duplicate entries for '{translationMetadata.Language}' ('{translation.entry.Name}' and '{item.Name}'). Use '{item.Name}'.");
}
languageReader[translationMetadata.Language] = value;
}
catch (Exception ex)
{
logger.LogWarning((object)("Failed to load entry at '" + item.Name + "': " + ex.Message));
}
}
if (translationEntries.Count == 0)
{
logger.LogInfo((object)"No entry found.");
}
else
{
logger.LogInfo((object)string.Format("Found {0} entries. Loaded {1} entries: {2}", translationEntries.Count, languageReader.Count, string.Join(", ", languageReader.LanguageList)));
}
}
public LocalizedText ModMenuName()
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
return LocalizedText.op_Implicit(Text.Localized("NAME"));
}
public AbstractMenuScreen BuildCustomMenu()
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Expected O, but got Unknown
//IL_005e: Unknown result type (might be due to invalid IL or missing references)
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
//IL_0079: Unknown result type (might be due to invalid IL or missing references)
//IL_0083: Unknown result type (might be due to invalid IL or missing references)
//IL_0089: Expected O, but got Unknown
//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
//IL_00c7: Expected O, but got Unknown
//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
//IL_0104: Expected O, but got Unknown
SimpleMenuScreen val = new SimpleMenuScreen(LocalisedString.op_Implicit(Text.Localized("NAME")));
TextButton val2 = new TextButton(LocalizedText.op_Implicit(Text.Localized("OPTION_OPEN_TRANSLATION_DIRECTORY")));
val2.OnSubmit = (Action)Delegate.Combine(val2.OnSubmit, (Action)delegate
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
bool flag = false;
try
{
if (languageReader.TryGetValue(Language._currentLanguage, out Translation translation))
{
DirectoryInfo location = translation.entry.location;
Process.Start(location.FullName);
flag = true;
logger.LogInfo((object)("Opened translation directory \"" + location.FullName + "\""));
}
else
{
flag = false;
}
}
catch
{
flag = false;
}
if (!flag)
{
DirectoryInfo directoryInfo5 = DirectoryHelper.TryCreate(translationDir);
Process.Start(directoryInfo5.FullName);
logger.LogInfo((object)("Opened translation directory \"" + directoryInfo5.FullName + "\""));
}
});
val.Add((MenuElement)(object)val2);
TextButton val3 = new TextButton(LocalizedText.op_Implicit(Text.Localized("OPTION_RELOAD_TRANSLATION")), LocalizedText.op_Implicit(Text.Localized("OPTION_DESCRIPTION_RELOAD_TRANSLATION")));
val3.OnSubmit = (Action)Delegate.Combine(val3.OnSubmit, (Action)delegate
{
//IL_0076: Unknown result type (might be due to invalid IL or missing references)
//IL_0097: Unknown result type (might be due to invalid IL or missing references)
logger.LogInfo((object)"Reloading translation");
MenuLanguageSetting val8 = default(MenuLanguageSetting);
if (((Component)((Component)UIManager.instance).transform.Find("UICanvas/GameOptionsMenuScreen/Content/LanguageSetting/LanguageOption")).TryGetComponent<MenuLanguageSetting>(ref val8))
{
RefreshLanguage();
Language.LoadAvailableLanguages();
MenuLanguageSetting.UpdateLangsArray();
int num = ((ReadOnlySpan<string>)MenuLanguageSetting.optionList).IndexOf(((object)(LanguageCode)(ref Language._currentLanguage)).ToString());
if (num != -1)
{
((MenuOptionHorizontal)val8).SetOptionTo(num);
}
else
{
((BaseUnityPlugin)this).Logger.LogWarning((object)$"Unable to load \"{Language._currentLanguage}\". Fallback to EN.");
MenuLanguageSetting obj = val8;
ReadOnlySpan<string> span = MenuLanguageSetting.optionList;
LanguageCode val9 = (LanguageCode)44;
((MenuOptionHorizontal)obj).SetOptionTo(span.IndexOf(((object)(LanguageCode)(ref val9)).ToString()));
}
val8.UpdateLanguageSetting();
ChangeFontByLanguage[] array = Object.FindObjectsByType<ChangeFontByLanguage>((FindObjectsSortMode)0);
for (int j = 0; j < array.Length; j++)
{
array[j].SetFont();
}
((BaseUnityPlugin)this).Logger.LogInfo((object)"Reloaded translation");
}
});
val.Add((MenuElement)(object)val3);
TextButton val4 = new TextButton(LocalizedText.op_Implicit(Text.Localized("OPTION_EXPORT_TRANSLATION")));
val4.OnSubmit = (Action)Delegate.Combine(val4.OnSubmit, (Action)delegate
{
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_0073: Expected O, but got Unknown
//IL_0073: Unknown result type (might be due to invalid IL or missing references)
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
//IL_0084: Expected O, but got Unknown
//IL_0220: Unknown result type (might be due to invalid IL or missing references)
//IL_0227: Expected O, but got Unknown
string text = ((object)(LanguageCode)(ref Language._currentLanguage)).ToString();
logger.LogInfo((object)("Exporting: " + text));
DirectoryInfo directoryInfo = DirectoryHelper.TryCreateRecursive(dir, "export/" + text);
DirectoryInfo directoryInfo2 = new DirectoryInfo(Path.GetTempPath());
DirectoryInfo directoryInfo3 = DirectoryHelper.TryCreateRecursive(directoryInfo, "entry");
using StreamWriter streamWriter = new StreamWriter(Path.Combine(directoryInfo3.FullName, "entry.json"));
JsonTextWriter val5 = new JsonTextWriter((TextWriter)streamWriter);
try
{
JsonSerializer val6 = JsonSerializer.Create(new JsonSerializerSettings
{
Formatting = (Formatting)1
});
Dictionary<string, Dictionary<string, string>> dictionary = new Dictionary<string, Dictionary<string, string>>();
string[] sheetTitles = Language.Settings.sheetTitles;
foreach (string key in sheetTitles)
{
if (Language._currentEntrySheets.TryGetValue(key, out var value) && !Extensions.IsNullOrEmpty<KeyValuePair<string, string>>((ICollection<KeyValuePair<string, string>>)value))
{
dictionary[key] = value;
}
}
val6.Serialize((JsonWriter)(object)val5, (object)dictionary);
DirectoryInfo directoryInfo4 = DirectoryHelper.TryCreateRecursive(directoryInfo, "sheet");
foreach (KeyValuePair<string, Dictionary<string, string>> item in dictionary)
{
item.Deconstruct(out var key2, out var value2);
string text2 = key2;
Dictionary<string, string> dictionary2 = value2;
using StreamWriter streamWriter2 = new StreamWriter(Path.Combine(directoryInfo4.FullName, text + "_" + text2 + ".txt"));
streamWriter2.WriteLine("<entries>");
foreach (KeyValuePair<string, string> item2 in dictionary2)
{
item2.Deconstruct(out key2, out var value3);
string text3 = key2;
string str = value3;
streamWriter2.WriteLine("<entry name=\"" + text3 + "\">" + Text.EscapeXml(str) + "</entry>");
}
streamWriter2.WriteLine("</entries>");
}
FileInfo fileInfo = new FileInfo(Path.Combine(directoryInfo2.FullName, "metadata.json"));
using (StreamWriter streamWriter3 = new StreamWriter(fileInfo.FullName))
{
JsonTextWriter val7 = new JsonTextWriter((TextWriter)streamWriter3);
try
{
val6.Serialize((JsonWriter)(object)val7, (object)new Dictionary<string, string> { ["Language"] = text });
}
finally
{
((IDisposable)val7)?.Dispose();
}
}
fileInfo.CopyTo(Path.Combine(directoryInfo4.FullName, fileInfo.Name), overwrite: true);
fileInfo.CopyTo(Path.Combine(directoryInfo3.FullName, fileInfo.Name), overwrite: true);
logger.LogInfo((object)("Exported \"" + text + "\""));
Process.Start(directoryInfo.FullName);
}
finally
{
((IDisposable)val5)?.Dispose();
}
});
val.Add((MenuElement)(object)val4);
return (AbstractMenuScreen)val;
}
}
public class GlobalData
{
[JsonConverter(typeof(StringEnumConverter))]
public LanguageCode Language;
}
public class Assets
{
public enum FontKind
{
Title,
Text
}
public TMP_FontAsset? TitleFont;
public TMP_FontAsset? TextFont;
private readonly TranslationEntry entry;
private bool read;
public Assets(TranslationEntry entry)
{
this.entry = entry;
base..ctor();
}
public TMP_FontAsset? GetFont(FontKind kind)
{
if (!read)
{
DirectoryInfo directoryInfo = new DirectoryInfo(Path.Combine(entry.location.FullName, "assets"));
if (!directoryInfo.Exists)
{
read = true;
return null;
}
FileInfo fileInfo = null;
try
{
FileInfo[] files = directoryInfo.GetFiles();
foreach (FileInfo fileInfo2 in files)
{
try
{
if ((Object)(object)TitleFont == (Object)null && (fileInfo2.Name == "title.ttf" || fileInfo2.Name == "title.otf"))
{
TitleFont = Text.CreateFontFrom(fileInfo2);
fileInfo = fileInfo2;
CustomTranslationPlugin.logger.LogInfo((object)"Loaded title font");
}
else if ((Object)(object)TextFont == (Object)null && (fileInfo2.Name == "text.ttf" || fileInfo2.Name == "text.otf"))
{
TextFont = Text.CreateFontFrom(fileInfo2);
fileInfo = fileInfo2;
CustomTranslationPlugin.logger.LogInfo((object)"Loaded text font");
}
}
catch (Exception ex)
{
CustomTranslationPlugin.logger.LogWarning((object)("Error while loading \"" + fileInfo2.FullName + "\": " + ex.Message + "\nThis asset will be skipped."));
}
}
if ((Object)(object)TitleFont == (Object)null && (Object)(object)TextFont != (Object)null && fileInfo != null)
{
TitleFont = Text.CreateFontFrom(fileInfo);
}
else if ((Object)(object)TitleFont != (Object)null && (Object)(object)TextFont == (Object)null && fileInfo != null)
{
TextFont = Text.CreateFontFrom(fileInfo);
}
}
catch (Exception ex2)
{
CustomTranslationPlugin.logger.LogError((object)("Error while discovering assets: " + ex2.Message));
}
finally
{
read = true;
}
}
return (TMP_FontAsset?)(kind switch
{
FontKind.Title => TitleFont,
FontKind.Text => TextFont,
_ => null,
});
}
}
public class TranslationEntry
{
public DirectoryInfo location;
public TranslationFileKind kind;
public string Name => location.Name;
public TranslationEntry(DirectoryInfo location, TranslationFileKind kind)
{
this.location = location;
this.kind = kind;
base..ctor();
}
}
public class TranslationMetadata
{
[JsonProperty(/*Could not decode attribute arguments.*/)]
[JsonConverter(typeof(LanguageCodeConverter))]
public LanguageCode Language { get; set; }
[JsonProperty(/*Could not decode attribute arguments.*/)]
[JsonConverter(typeof(LanguageCodeConverter))]
public LanguageCode FallbackLanguage { get; set; } = (LanguageCode)44;
[JsonProperty(/*Could not decode attribute arguments.*/)]
public float TextFontScale { get; set; } = 1f;
[JsonProperty(/*Could not decode attribute arguments.*/)]
public float TitleFontScale { get; set; } = 1f;
[JsonProperty(/*Could not decode attribute arguments.*/)]
public bool UseFontAsFallBack { get; set; } = true;
[JsonConstructor]
public TranslationMetadata(LanguageCode language)
{
//IL_0003: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
Language = language;
}
public static TranslationMetadata ReadFrom(TranslationEntry entry)
{
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
TranslationMetadata translationMetadata = Text.FromJson<TranslationMetadata>(Path.Combine(entry.location.FullName, "metadata.json"));
if (translationMetadata == null || (int)translationMetadata.Language == 0)
{
throw new CustomTranslationException("Invalid language code");
}
return translationMetadata;
}
}
public class Translation
{
public readonly TranslationMetadata metadata;
public readonly TranslationEntry entry;
public readonly Assets assets;
public Translation(TranslationMetadata metadata, TranslationEntry entry)
{
this.metadata = metadata;
this.entry = entry;
assets = new Assets(entry);
base..ctor();
}
public bool UpdateSheet()
{
string text = "";
try
{
if (entry.kind == TranslationFileKind.Single)
{
Dictionary<string, Dictionary<string, string>> dictionary = Text.FromJson<Dictionary<string, Dictionary<string, string>>>(Path.Combine(entry.location.FullName, "entry.json"));
if (dictionary == null)
{
throw new CustomTranslationException("JSON is null");
}
string[] sheetTitles = Language.Settings.sheetTitles;
for (int i = 0; i < sheetTitles.Length; i++)
{
text = sheetTitles[i];
if (!Language._currentEntrySheets.TryGetValue(text, out var value))
{
value = new Dictionary<string, string>();
Language._currentEntrySheets[text] = value;
}
if (!dictionary.TryGetValue(text, out var value2))
{
continue;
}
foreach (KeyValuePair<string, string> item in value2)
{
item.Deconstruct(out var key, out var value3);
string key2 = key;
string value4 = value3;
value[key2] = value4;
}
}
}
else
{
FileInfo[] files = entry.location.GetFiles();
string[] sheetTitles = Language.Settings.sheetTitles;
foreach (string obj in sheetTitles)
{
text = obj;
if (!Language._currentEntrySheets.TryGetValue(text, out var value5))
{
value5 = new Dictionary<string, string>();
Language._currentEntrySheets[text] = value5;
}
Regex pattern = new Regex("[a-zA-Z_]+?" + text + "\\.(?:txt|bytes)");
FileInfo fileInfo = files.FirstOrDefault((FileInfo f) => pattern.IsMatch(f.Name));
if (fileInfo == null)
{
continue;
}
using StreamReader streamReader = new StreamReader(Path.Combine(entry.location.FullName, fileInfo.Name));
string text2 = streamReader.ReadToEnd();
if (!text2.Contains('<'))
{
text2 = Encryption.Decrypt(text2);
}
using XmlReader xmlReader = XmlReader.Create(new StringReader(text2));
while (xmlReader.ReadToFollowing("entry"))
{
xmlReader.MoveToFirstAttribute();
string value6 = xmlReader.Value;
xmlReader.MoveToElement();
string text3 = xmlReader.ReadElementContentAsString().Trim();
text3 = StringExtensions.UnescapeXml(text3);
value5[value6] = text3;
}
}
}
return true;
}
catch (Exception ex)
{
CustomTranslationPlugin.logger.LogError((object)("Error while loading \"" + entry.Name + "\" entry on sheet \"" + text + "\": " + ex.Message));
return false;
}
}
}
public class LanguageReader
{
private readonly SortedList<LanguageCode, Translation> languages = new SortedList<LanguageCode, Translation>(Comparer<LanguageCode>.Default);
public IList<LanguageCode> LanguageList => languages.Keys;
public int Count => languages.Count;
public Translation this[LanguageCode lang]
{
get
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
return languages[lang];
}
set
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
languages[lang] = value;
}
}
public bool ContainsKey(LanguageCode key)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
return languages.ContainsKey(key);
}
public bool TryGetValue(LanguageCode key, out Translation translation)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
return languages.TryGetValue(key, out translation);
}
}
internal class EnumComparer<T> : Comparer<T> where T : Enum
{
public override int Compare(T x, T y)
{
return x.CompareTo(y);
}
}
internal class LanguagePatch
{
[HarmonyPrefix]
[HarmonyPatch(typeof(Language), "DoSwitch")]
private static bool DoSwitch(LanguageCode newLang)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
//IL_010b: Unknown result type (might be due to invalid IL or missing references)
//IL_010c: Unknown result type (might be due to invalid IL or missing references)
//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
//IL_014e: Unknown result type (might be due to invalid IL or missing references)
//IL_016e: Unknown result type (might be due to invalid IL or missing references)
//IL_016f: Unknown result type (might be due to invalid IL or missing references)
LocalizationProjectSettings.OnSwitchedLanguage(newLang);
Language._currentLanguage = newLang;
Language._currentEntrySheets = new Dictionary<string, Dictionary<string, string>>();
if (CustomTranslationPlugin.languageReader.TryGetValue(newLang, out Translation translation))
{
Language._currentLanguage = translation.metadata.FallbackLanguage;
}
string[] sheetTitles = Language.Settings.sheetTitles;
foreach (string text in sheetTitles)
{
Language._currentEntrySheets[text] = new Dictionary<string, string>();
string languageFileContents = Language.GetLanguageFileContents(text);
if (string.IsNullOrEmpty(languageFileContents))
{
continue;
}
using XmlReader xmlReader = XmlReader.Create(new StringReader(languageFileContents));
while (xmlReader.ReadToFollowing("entry"))
{
xmlReader.MoveToFirstAttribute();
string value = xmlReader.Value;
xmlReader.MoveToElement();
string text2 = xmlReader.ReadElementContentAsString().Trim();
text2 = StringExtensions.UnescapeXml(text2);
Language._currentEntrySheets[text][value] = text2;
}
}
if (CustomTranslationPlugin.languageReader.ContainsKey(newLang))
{
CustomTranslationPlugin.languageReader[newLang].UpdateSheet();
}
Language._currentLanguage = newLang;
LocalizedAsset[] array = (LocalizedAsset[])(object)Object.FindObjectsOfType(typeof(LocalizedAsset));
for (int j = 0; j < array.Length; j++)
{
array[j].LocalizeAsset();
}
Language.SendMonoMessage("ChangedLanguage", new object[1] { Language._currentLanguage });
GlobalData? globalData = CustomTranslationPlugin.Instance.GlobalData;
if (globalData != null)
{
globalData.Language = newLang;
}
return false;
}
[HarmonyPostfix]
[HarmonyPatch(typeof(Language), "GetLanguages")]
private static void GetLanguages(ref string[] __result)
{
List<string> list = new List<string>();
list.AddRange(__result);
list.AddRange(CustomTranslationPlugin.languageReader.LanguageList.Select((LanguageCode lang) => ((object)(LanguageCode)(ref lang)).ToString()));
__result = list.ToArray();
}
[HarmonyPostfix]
[HarmonyPatch(typeof(Language), "LoadAvailableLanguages")]
public static void LoadAvailableLanguages()
{
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
foreach (LanguageCode language in CustomTranslationPlugin.languageReader.LanguageList)
{
LanguageCode current = language;
Extensions.AddIfNotPresent<string>(Language._availableLanguages, ((object)(LanguageCode)(ref current)).ToString());
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(Language), "RestoreLanguageSelection")]
private static void RestoreLanguageFromGlobalData(ref string __result)
{
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
LanguageCode? val = CustomTranslationPlugin.Instance.GlobalData?.Language;
if (val.HasValue)
{
LanguageCode valueOrDefault = val.GetValueOrDefault();
__result = ((object)(LanguageCode)(ref valueOrDefault)).ToString();
}
CustomTranslationPlugin.logger.LogInfo((object)("Restored language: " + __result));
}
}
internal class Patch
{
private static string[]? originalOptionList;
private static readonly string[] titleFontNames = new string[2] { "trajan_bold_tmpro", "TrajanPro-Bold SDF" };
[HarmonyPostfix]
[HarmonyPatch(typeof(MenuLanguageSetting), "UpdateLangsArray")]
private static void UpdateLangsArray()
{
if (originalOptionList == null)
{
originalOptionList = MenuLanguageSetting.optionList.ToArray();
}
List<string> list = new List<string>();
list.AddRange(originalOptionList);
list.AddRange(from lang in CustomTranslationPlugin.languageReader.LanguageList
select ((object)(LanguageCode)(ref lang)).ToString() into lang
where !originalOptionList.Any((string og_lang) => lang == og_lang)
select lang);
MenuLanguageSetting.optionList = list.ToArray();
}
[HarmonyPrefix]
[HarmonyPatch(typeof(MenuLanguageSetting), "UpdateLanguageSetting")]
private static bool UpdateLanguageSetting(MenuLanguageSetting __instance)
{
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
//IL_0062: Unknown result type (might be due to invalid IL or missing references)
//IL_0067: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
LanguageCode val;
if (((MenuOptionHorizontal)__instance).selectedOptionIndex < MenuLanguageSetting.langs.Length)
{
GameManager.instance.gameSettings.gameLanguage = MenuLanguageSetting.langs[((MenuOptionHorizontal)__instance).selectedOptionIndex];
val = (LanguageCode)MenuLanguageSetting.langs[((MenuOptionHorizontal)__instance).selectedOptionIndex];
}
else
{
GameManager.instance.gameSettings.gameLanguage = (SupportedLanguages)44;
val = CustomTranslationPlugin.languageReader.LanguageList[((MenuOptionHorizontal)__instance).selectedOptionIndex - MenuLanguageSetting.langs.Length];
}
Language.SwitchLanguage(val);
GameManager.instance.RefreshLocalization();
((MenuOptionHorizontal)__instance).UpdateText();
return false;
}
[HarmonyPostfix]
[HarmonyPatch(typeof(MenuLanguageSetting), "RefreshCurrentIndex")]
private static void PatchCurrentIndex(MenuLanguageSetting __instance)
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
if (!MenuLanguageSetting.languageCodeToSupportedLanguages.ContainsKey(Language._currentLanguage) && CustomTranslationPlugin.languageReader.ContainsKey(Language._currentLanguage))
{
int num = ((ReadOnlySpan<string>)MenuLanguageSetting.optionList).IndexOf(((object)(LanguageCode)(ref Language._currentLanguage)).ToString());
if (num != -1)
{
((MenuOptionHorizontal)__instance).selectedOptionIndex = num;
}
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(ChangeFontByLanguage), "SetFont", new Type[] { })]
private static void PatchFont(ChangeFontByLanguage __instance)
{
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
ChangeFontByLanguage __instance2 = __instance;
if (!CustomTranslationPlugin.languageReader.TryGetValue(Language._currentLanguage, out Translation translation))
{
return;
}
TMP_FontAsset font = translation.assets.GetFont(Assets.FontKind.Text);
TMP_FontAsset font2 = translation.assets.GetFont(Assets.FontKind.Title);
TMP_FontAsset val = null;
float num = 1f;
if (((Object)__instance2.defaultFont).name == "perpetua_tmpro")
{
val = font;
num = translation.metadata.TextFontScale;
}
else if (titleFontNames.Any((string name) => name == ((Object)__instance2.defaultFont).name))
{
val = font2;
num = translation.metadata.TitleFontScale;
}
if ((Object)(object)val == (Object)null)
{
return;
}
TextMeshPro tmpro = __instance2.tmpro;
((TMP_Text)tmpro).fontSize = ((TMP_Text)tmpro).fontSize * num;
if (translation.metadata.UseFontAsFallBack)
{
if (Extensions.IsNullOrEmpty<TMP_FontAsset>((ICollection<TMP_FontAsset>)((TMP_Text)__instance2.tmpro).font.fallbackFontAssets))
{
((TMP_Text)__instance2.tmpro).font.fallbackFontAssets = new List<TMP_FontAsset>(1) { val };
}
else if (!((TMP_Text)__instance2.tmpro).font.fallbackFontAssets.Contains(val))
{
((TMP_Text)__instance2.tmpro).font.fallbackFontAssets.Add(val);
}
return;
}
val.fallbackFontAssets = ((TMP_Text)__instance2.tmpro).font.fallbackFontAssets;
if (Extensions.IsNullOrEmpty<TMP_FontAsset>((ICollection<TMP_FontAsset>)val.fallbackFontAssets))
{
val.fallbackFontAssets = new List<TMP_FontAsset>(1) { ((TMP_Text)__instance2.tmpro).font };
}
else if (!val.fallbackFontAssets.Contains(((TMP_Text)__instance2.tmpro).font))
{
val.fallbackFontAssets.Insert(0, ((TMP_Text)__instance2.tmpro).font);
}
__instance2.SetFont(val, true);
}
}
public class CustomTranslationException : Exception
{
public CustomTranslationException(string message)
: base(message)
{
}
}
public static class Text
{
public static LocalisedString Localized(string key)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
return new LocalisedString("Mods.io.github.carrieforle.customtranslation", key);
}
public static string Localized(string key, params object[] args)
{
return string.Format(Language.Get(key, "Mods.io.github.carrieforle.customtranslation"), args);
}
public static T? FromJson<T>(string path)
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_000e: Expected O, but got Unknown
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
using StreamReader streamReader = new StreamReader(path);
JsonTextReader val = new JsonTextReader((TextReader)streamReader);
try
{
return new JsonSerializer().Deserialize<T>((JsonReader)(object)val);
}
finally
{
((IDisposable)val)?.Dispose();
}
}
public static string EscapeXml(string str)
{
Dictionary<char, string> dictionary = new Dictionary<char, string>
{
['\''] = "'",
['"'] = """,
['>'] = ">",
['<'] = "<",
['&'] = "&"
};
StringBuilder stringBuilder = new StringBuilder(str);
for (int i = 0; i < stringBuilder.Length; i++)
{
if (dictionary.TryGetValue(stringBuilder[i], out var value))
{
stringBuilder.Remove(i, 1);
stringBuilder.Insert(i, value);
i += value.Length - 1;
}
}
return stringBuilder.ToString();
}
public static TMP_FontAsset CreateFontFrom(FileInfo file)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Expected O, but got Unknown
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
return new FontAssetBuilder(new Font(file.FullName))
{
AtlasWidth = 4096,
AtlasHeight = 4096
}.Create();
}
}
public static class DirectoryHelper
{
public static DirectoryInfo TryCreateRecursive(DirectoryInfo dirRoot, string dir)
{
return TryCreate(new DirectoryInfo(Path.Combine(dirRoot.FullName, dir)));
}
public static DirectoryInfo TryCreate(DirectoryInfo dir)
{
dir.Refresh();
try
{
dir.Create();
}
catch
{
}
return dir;
}
}
public class LanguageCodeConverter : JsonConverter
{
public override bool CanRead { get; } = true;
public override bool CanWrite { get; }
public override bool CanConvert(Type objectType)
{
return objectType == typeof(LanguageCode);
}
public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override object ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
{
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
string val = (string)reader.Value;
return Enum.GetValues(typeof(LanguageCode)).Cast<LanguageCode>().First((LanguageCode lang) => ((object)(LanguageCode)(ref lang)).ToString().Equals(val, StringComparison.OrdinalIgnoreCase));
}
}
public class BepinExTraceWriter : ITraceWriter
{
[CompilerGenerated]
private ManualLogSource <logger>P;
public TraceLevel LevelFilter => TraceLevel.Verbose;
public BepinExTraceWriter(ManualLogSource logger)
{
<logger>P = logger;
base..ctor();
}
public void Trace(TraceLevel level, string message, Exception? ex)
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
<logger>P.Log(GetLogLevel(level), (object)message);
if (ex != null)
{
<logger>P.Log(GetLogLevel(level), (object)ex);
}
}
private LogLevel GetLogLevel(TraceLevel level)
{
return (LogLevel)(level switch
{
TraceLevel.Error => 2,
TraceLevel.Warning => 4,
TraceLevel.Info => 16,
TraceLevel.Off => 0,
_ => 8,
});
}
}
}