using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using System.Text.Json;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using BigWalkLocalizationAPI.Api;
using HarmonyLib;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("BigWalkLocalizationAPI")]
[assembly: AssemblyDescription("Big Walk Localization API for Big Walk by Ice Box Studio")]
[assembly: AssemblyProduct("BigWalkLocalizationAPI")]
[assembly: ComVisible(false)]
[assembly: Guid("e335fa34-e0fc-41e6-9c93-88cf9ff63f57")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyVersion("1.1.0.0")]
namespace BigWalkLocalizationAPI
{
[BepInPlugin("IceBoxStudio.BigWalk.LocalizationAPI", "BigWalkLocalizationAPI", "1.1.0")]
public sealed class BigWalkLocalizationAPI : BasePlugin
{
internal static ManualLogSource Logger { get; private set; }
public override void Load()
{
//IL_0071: Unknown result type (might be due to invalid IL or missing references)
//IL_0077: Expected O, but got Unknown
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Expected O, but got Unknown
Logger = ((BasePlugin)this).Log;
bool flag = default(bool);
try
{
new Harmony("IceBoxStudio.BigWalk.LocalizationAPI").PatchAll(Assembly.GetExecutingAssembly());
ManualLogSource logger = Logger;
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(14, 2, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("BigWalkLocalizationAPI");
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("1.1.0");
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" initialized.");
}
logger.LogInfo(val);
}
catch (Exception ex)
{
ManualLogSource logger2 = Logger;
BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(43, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Failed to initialize the localization API: ");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<Exception>(ex);
}
logger2.LogError(val2);
}
}
}
public static class PluginInfo
{
public const string PLUGIN_GUID = "IceBoxStudio.BigWalk.LocalizationAPI";
public const string PLUGIN_NAME = "BigWalkLocalizationAPI";
public const string PLUGIN_VERSION = "1.1.0";
}
}
namespace BigWalkLocalizationAPI.Patches
{
[HarmonyPatch(typeof(LocalizationManager), "SetLanguage", new Type[] { typeof(LocalizationLanguage) })]
public static class LocalizationManagerSetLanguagePatch
{
[HarmonyPostfix]
public static void Postfix()
{
LocalizationApi.NotifyLanguageChanged();
}
}
}
namespace BigWalkLocalizationAPI.Api
{
internal sealed class ConfigSectionTag
{
private readonly ModLocalizer _localizer;
private readonly string _key;
public string Section { get; }
public int? Order { get; }
internal ConfigSectionTag(ModLocalizer localizer, string section, string key, int order)
{
_localizer = localizer;
_key = key;
Section = section;
Order = order;
}
internal bool TryGetDisplayName(out string displayName)
{
displayName = _localizer.GetLocalizedText(_key);
return !string.Equals(displayName, _key, StringComparison.Ordinal);
}
}
internal sealed class ConfigEntryTag
{
private readonly ModLocalizer _localizer;
private readonly string _key;
public int? Order { get; }
public double? SliderStep { get; }
internal ConfigEntryTag(ModLocalizer localizer, string key, int order, double? sliderStep)
{
_localizer = localizer;
_key = key;
Order = order;
SliderStep = sliderStep;
}
internal bool TryGetText(string propertyName, out string text)
{
string text2 = (string.Equals(propertyName, "DisplayName", StringComparison.Ordinal) ? ".name" : ".description");
string text3 = _key + text2;
text = _localizer.GetLocalizedText(text3);
return !string.Equals(text, text3, StringComparison.Ordinal);
}
internal bool TryGetDisplayValue(object value, out string displayValue)
{
displayValue = null;
string text = NormalizeValue(value);
if (text.Length == 0)
{
return false;
}
string text2 = _key + "." + text;
string localizedText = _localizer.GetLocalizedText(text2);
if (string.Equals(localizedText, text2, StringComparison.Ordinal))
{
return false;
}
displayValue = localizedText;
return true;
}
private static string NormalizeValue(object value)
{
string text = Convert.ToString(value, CultureInfo.InvariantCulture);
if (string.IsNullOrWhiteSpace(text))
{
return string.Empty;
}
StringBuilder stringBuilder = new StringBuilder(text.Length + 4);
for (int i = 0; i < text.Length; i++)
{
char c = text[i];
if (!char.IsLetterOrDigit(c))
{
if (stringBuilder.Length > 0 && stringBuilder[stringBuilder.Length - 1] != '_')
{
stringBuilder.Append('_');
}
continue;
}
if (char.IsUpper(c) && i > 0 && char.IsLower(text[i - 1]) && stringBuilder.Length > 0 && stringBuilder[stringBuilder.Length - 1] != '_')
{
stringBuilder.Append('_');
}
stringBuilder.Append(char.ToLowerInvariant(c));
}
return stringBuilder.ToString().Trim('_');
}
}
public static class LocalizationApi
{
public const string DefaultLanguage = "English";
private const string LanguageSaveKey = "setting_language";
private static readonly Dictionary<string, ModLocalizer> Localizers = new Dictionary<string, ModLocalizer>(StringComparer.OrdinalIgnoreCase);
private static bool _languageApplied;
public static string CurrentLanguage
{
get
{
TryGetCurrentGameLanguage(out var language);
return language;
}
}
public static event Action<string> LanguageChanged;
public static ModLocalizer For(string pluginGuid)
{
if (string.IsNullOrWhiteSpace(pluginGuid))
{
throw new ArgumentException("Plugin GUID cannot be empty.", "pluginGuid");
}
if (!Localizers.TryGetValue(pluginGuid, out var value))
{
value = new ModLocalizer(pluginGuid);
Localizers.Add(pluginGuid, value);
}
return value;
}
public static bool TryGetCurrentGameLanguage(out string language)
{
//IL_001e: 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)
try
{
if (!_languageApplied && TryGetSavedLanguage(out language))
{
return true;
}
LocalizationManager instance = LocalizationManager.instance;
language = ((instance == null) ? "English" : ((object)instance.currentLanguage/*cast due to .constrained prefix*/).ToString());
if (string.IsNullOrWhiteSpace(language))
{
language = "English";
}
return instance != null;
}
catch
{
language = "English";
return false;
}
}
public static string GetConfigDescription(ConfigEntryBase entry)
{
if (entry != null)
{
ConfigDescription description = entry.Description;
object[] array = ((description != null) ? description.Tags : null) ?? Array.Empty<object>();
for (int i = 0; i < array.Length; i++)
{
if (array[i] is ConfigEntryTag configEntryTag && configEntryTag.TryGetText("Description", out var text))
{
return text;
}
}
}
if (entry == null)
{
return null;
}
ConfigDescription description2 = entry.Description;
if (description2 == null)
{
return null;
}
return description2.Description;
}
public static string GetConfigDisplayName(ConfigEntryBase entry)
{
if (entry != null)
{
ConfigDescription description = entry.Description;
object[] array = ((description != null) ? description.Tags : null) ?? Array.Empty<object>();
for (int i = 0; i < array.Length; i++)
{
if (array[i] is ConfigEntryTag configEntryTag && configEntryTag.TryGetText("DisplayName", out var text))
{
return text;
}
}
}
if (entry == null)
{
return null;
}
ConfigDefinition definition = entry.Definition;
if (definition == null)
{
return null;
}
return definition.Key;
}
public static string GetConfigSection(string section, ConfigFile config)
{
if (section == null || config == null)
{
return section;
}
foreach (ConfigEntryBase value in config.Values)
{
if (!string.Equals(value.Definition.Section, section, StringComparison.Ordinal))
{
continue;
}
ConfigDescription description = value.Description;
object[] array = ((description != null) ? description.Tags : null) ?? Array.Empty<object>();
for (int i = 0; i < array.Length; i++)
{
if (array[i] is ConfigSectionTag configSectionTag && string.Equals(configSectionTag.Section, section, StringComparison.Ordinal) && configSectionTag.TryGetDisplayName(out var displayName))
{
return displayName;
}
}
}
return section;
}
public static bool TryGetConfigDisplayValue(ConfigEntryBase entry, object value, out string displayValue)
{
displayValue = null;
if (entry == null || value == null)
{
return false;
}
ConfigDescription description = entry.Description;
object[] array = ((description != null) ? description.Tags : null) ?? Array.Empty<object>();
for (int i = 0; i < array.Length; i++)
{
if (array[i] is ConfigEntryTag configEntryTag && configEntryTag.TryGetDisplayValue(value, out displayValue))
{
return true;
}
}
return false;
}
internal static void NotifyLanguageChanged()
{
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_004e: Expected O, but got Unknown
_languageApplied = true;
Action<string> languageChanged = LocalizationApi.LanguageChanged;
if (languageChanged == null)
{
return;
}
string currentLanguage = CurrentLanguage;
Delegate[] invocationList = languageChanged.GetInvocationList();
bool flag = default(bool);
foreach (Delegate obj in invocationList)
{
try
{
((Action<string>)obj)(currentLanguage);
}
catch (Exception ex)
{
ManualLogSource logger = BigWalkLocalizationAPI.Logger;
if (logger != null)
{
BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(33, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Language change callback failed: ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
}
logger.LogError(val);
}
}
}
}
private static bool TryGetSavedLanguage(out string language)
{
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
language = null;
if (!PlayerPrefs.HasKey("setting_language"))
{
return false;
}
int num = PlayerPrefs.GetInt("setting_language");
if (num < 1 || num > 15)
{
return false;
}
language = ((object)(LocalizationLanguage)num/*cast due to .constrained prefix*/).ToString();
return !string.IsNullOrWhiteSpace(language);
}
}
public sealed class ModLocalizer
{
private readonly Dictionary<string, Dictionary<string, string>> _localizations = new Dictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase);
public string PluginGuid { get; }
internal ModLocalizer(string pluginGuid)
{
PluginGuid = pluginGuid;
}
public void RegisterJson(string jsonPath)
{
if (string.IsNullOrWhiteSpace(jsonPath))
{
throw new ArgumentException("Localization file path cannot be empty.", "jsonPath");
}
if (!File.Exists(jsonPath))
{
throw new FileNotFoundException("Localization file not found.", jsonPath);
}
Dictionary<string, Dictionary<string, string>> dictionary = new Dictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase);
using (JsonDocument jsonDocument = JsonDocument.Parse(File.ReadAllText(jsonPath)))
{
if (jsonDocument.RootElement.ValueKind != JsonValueKind.Object)
{
throw new InvalidDataException("Localization file root must be a JSON object.");
}
foreach (JsonProperty item in jsonDocument.RootElement.EnumerateObject())
{
if (item.Value.ValueKind != JsonValueKind.Object)
{
continue;
}
Dictionary<string, string> dictionary2 = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
foreach (JsonProperty item2 in item.Value.EnumerateObject())
{
if (item2.Value.ValueKind == JsonValueKind.String)
{
dictionary2[item2.Name] = item2.Value.GetString() ?? string.Empty;
}
}
if (dictionary2.Count > 0)
{
dictionary[item.Name] = dictionary2;
}
}
}
if (!dictionary.ContainsKey("English"))
{
throw new InvalidDataException("Localization file must contain a English section.");
}
_localizations.Clear();
foreach (KeyValuePair<string, Dictionary<string, string>> item3 in dictionary)
{
_localizations.Add(item3.Key, item3.Value);
}
}
public string GetLocalizedText(string key, params object[] args)
{
if (string.IsNullOrEmpty(key))
{
return string.Empty;
}
string currentLanguage = LocalizationApi.CurrentLanguage;
if (TryGetText(currentLanguage, key, out var text))
{
return Format(text, args);
}
if (!string.Equals(currentLanguage, "English", StringComparison.OrdinalIgnoreCase) && TryGetText("English", key, out var text2))
{
return Format(text2, args);
}
return key;
}
public ConfigDescription Config(string key, int entryOrder, string section, string sectionKey, int sectionOrder, AcceptableValueBase acceptableValues = null, double? sliderStep = null)
{
//IL_0096: Unknown result type (might be due to invalid IL or missing references)
//IL_009c: Expected O, but got Unknown
if (string.IsNullOrWhiteSpace(key))
{
throw new ArgumentException("Localization key cannot be empty.", "key");
}
if (string.IsNullOrWhiteSpace(section))
{
throw new ArgumentException("Config section cannot be empty.", "section");
}
if (string.IsNullOrWhiteSpace(sectionKey))
{
throw new ArgumentException("Section localization key cannot be empty.", "sectionKey");
}
string text = key + ".description";
string text2 = GetLocalizedText(text);
if (string.Equals(text2, text, StringComparison.Ordinal))
{
text2 = string.Empty;
}
return new ConfigDescription(text2, acceptableValues, new object[2]
{
new ConfigSectionTag(this, section, sectionKey, sectionOrder),
new ConfigEntryTag(this, key, entryOrder, sliderStep)
});
}
private bool TryGetText(string language, string key, out string text)
{
text = null;
if (_localizations.TryGetValue(language, out var value))
{
return value.TryGetValue(key, out text);
}
return false;
}
private static string Format(string text, object[] args)
{
if (args == null || args.Length == 0)
{
return text;
}
try
{
return string.Format(text, args);
}
catch (FormatException)
{
return text;
}
}
}
}