using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Core.Logging.Interpolation; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using Fusion; using GameInput; using I2.Loc; using IceBoxModLib.Runtime; using IceBoxModLib.UI; using Il2CppInterop.Runtime.Attributes; using Il2CppInterop.Runtime.Injection; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppSystem; using Store; using Store.UI; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.UI; using WallyBox; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("IceBoxModLib")] [assembly: AssemblyDescription("Shared mod library for Roadside Research by Ice Box Studio")] [assembly: AssemblyCompany("Ice Box Studio")] [assembly: AssemblyProduct("IceBoxModLib")] [assembly: AssemblyCopyright("Copyright © 2026 Ice Box Studio All rights reserved.")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("f01ee749-b2b7-4189-b681-4f4983c38ca9")] [assembly: AssemblyFileVersion("1.0.2.0")] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyVersion("1.0.2.0")] namespace IceBoxModLib { [BepInPlugin("IceBoxStudio.RoadsideResearch.ModLib", "IceBoxModLib", "1.0.2")] public class IceBoxModLib : BasePlugin { private static bool _initialized; public static IceBoxModLib Instance { get; private set; } internal static ManualLogSource Log { get; private set; } public override void Load() { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown Instance = this; Log = ((BasePlugin)this).Log; if (!_initialized) { Il2CppTypeRegistry.RegisterType(); _initialized = true; ManualLogSource log = Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(8, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendFormatted("IceBoxModLib"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" loaded!"); } log.LogInfo(val); } } } public static class PluginInfo { public const string PLUGIN_GUID = "IceBoxStudio.RoadsideResearch.ModLib"; public const string PLUGIN_NAME = "IceBoxModLib"; public const string PLUGIN_VERSION = "1.0.2"; } } namespace IceBoxModLib.Utilities { public static class ImageLoader { public static Sprite LoadSpriteFromFile(string absoluteImagePath, float pixelsPerUnit = 100f, float pivotX = 0.5f, float pivotY = 0.5f, FilterMode filterMode = 1) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) if (!File.Exists(absoluteImagePath)) { return null; } try { byte[] array = File.ReadAllBytes(absoluteImagePath); Texture2D val = new Texture2D(2, 2); ImageConversion.LoadImage(val, Il2CppStructArray.op_Implicit(array)); ((Texture)val).filterMode = filterMode; Sprite obj = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(pivotX, pivotY), pixelsPerUnit, 0u, (SpriteMeshType)1, Vector4.zero); ((Object)val).hideFlags = (HideFlags)61; ((Object)obj).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)(object)val); Object.DontDestroyOnLoad((Object)(object)obj); return obj; } catch { return null; } } public static bool ReplaceImageBySpriteName(Transform rootTransform, string originalSpriteName, Sprite newSprite, bool resetColorToWhite = true) { //IL_005d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)rootTransform == (Object)null || string.IsNullOrEmpty(originalSpriteName) || (Object)(object)newSprite == (Object)null) { return false; } Image[] array = Il2CppArrayBase.op_Implicit(((Component)rootTransform).GetComponentsInChildren(true)); foreach (Image val in array) { if ((Object)(object)val.sprite != (Object)null && ((Object)val.sprite).name.Contains(originalSpriteName)) { val.sprite = newSprite; if (resetColorToWhite) { ((Graphic)val).color = Color.white; } return true; } } return false; } } public static class ItemContainerRefreshHelper { private static ItemAmountInItemContainerLabel[] _cachedLabels; private static float _lastCacheTime; private const float CacheLifetime = 2f; public static void Refresh(ItemContainer container, Item changedItem = null) { if (!((Object)(object)container == (Object)null)) { Item item = changedItem ?? container.Item; try { ((NetworkBehaviour)container).CopyStateToBackingFields(); } catch (Exception) { } try { container.UpdateItemVisuals(container); } catch (Exception) { } RefreshAmountLabels(container); try { container.OnNetworkChangedAmount(); } catch (Exception) { } RefreshStockLabels(item); } } private static ItemAmountInItemContainerLabel[] GetLabels() { float realtimeSinceStartup = Time.realtimeSinceStartup; if (_cachedLabels == null || realtimeSinceStartup - _lastCacheTime > 2f) { _cachedLabels = Il2CppArrayBase.op_Implicit(Resources.FindObjectsOfTypeAll()); _lastCacheTime = realtimeSinceStartup; } return _cachedLabels; } public static void InvalidateCache() { _cachedLabels = null; } private static void RefreshAmountLabels(ItemContainer container) { ItemAmountInItemContainerLabel[] labels = GetLabels(); foreach (ItemAmountInItemContainerLabel val in labels) { if ((Object)(object)val == (Object)null) { continue; } try { ItemContainer currentData = ((DataDisplay)(object)val).CurrentData; if ((Object)(object)currentData != (Object)null && ((Il2CppObjectBase)currentData).Pointer == ((Il2CppObjectBase)container).Pointer) { ((DataDisplay)(object)val).HandleNewData(container); } } catch (Exception) { } } } private static void RefreshStockLabels(Item item) { Action val = default(Action); if (!((Object)(object)item == (Object)null) && !((Object)(object)SingletonNetworkBehaviour.Instance == (Object)null) && SingletonNetworkBehaviour.Instance._onStockTotalChanged != null && SingletonNetworkBehaviour.Instance._onStockTotalChanged.TryGetValue(item, ref val) && !((Delegate)(object)val == (Delegate)null)) { val.Invoke(); } } } public static class KeyboardInputHelper { private static readonly Dictionary KeyPropertyOverrides = new Dictionary { { (KeyCode)96, "backquoteKey" }, { (KeyCode)8, "backspaceKey" }, { (KeyCode)92, "backslashKey" }, { (KeyCode)301, "capsLockKey" }, { (KeyCode)44, "commaKey" }, { (KeyCode)127, "deleteKey" }, { (KeyCode)274, "downArrowKey" }, { (KeyCode)279, "endKey" }, { (KeyCode)61, "equalsKey" }, { (KeyCode)27, "escapeKey" }, { (KeyCode)278, "homeKey" }, { (KeyCode)277, "insertKey" }, { (KeyCode)271, "numpadEnterKey" }, { (KeyCode)308, "leftAltKey" }, { (KeyCode)276, "leftArrowKey" }, { (KeyCode)91, "leftBracketKey" }, { (KeyCode)306, "leftCtrlKey" }, { (KeyCode)304, "leftShiftKey" }, { (KeyCode)319, "contextMenuKey" }, { (KeyCode)45, "minusKey" }, { (KeyCode)300, "numLockKey" }, { (KeyCode)281, "pageDownKey" }, { (KeyCode)280, "pageUpKey" }, { (KeyCode)46, "periodKey" }, { (KeyCode)39, "quoteKey" }, { (KeyCode)13, "enterKey" }, { (KeyCode)307, "rightAltKey" }, { (KeyCode)275, "rightArrowKey" }, { (KeyCode)93, "rightBracketKey" }, { (KeyCode)305, "rightCtrlKey" }, { (KeyCode)303, "rightShiftKey" }, { (KeyCode)302, "scrollLockKey" }, { (KeyCode)59, "semicolonKey" }, { (KeyCode)47, "slashKey" }, { (KeyCode)32, "spaceKey" }, { (KeyCode)9, "tabKey" }, { (KeyCode)273, "upArrowKey" } }; private static readonly Dictionary KeyboardPropertyCache = new Dictionary(); private static readonly Dictionary ActionCache = new Dictionary(StringComparer.OrdinalIgnoreCase); private static bool _legacyInputUnavailable; private static Type _keyboardType; private static PropertyInfo _keyboardCurrentProperty; public static bool WasKeyPressed(KeyCode key) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) if (!TryGetLegacyKeyDown(key)) { return TryGetNewInputSystemKeyDown(key); } return true; } public static bool WasActionPressed(string actionName, KeyCode fallbackKey = 0) { //IL_0029: 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) if (TryGetAction(actionName, out var action)) { try { if (!action.enabled) { action.Enable(); } if (action.WasPressedThisFrame()) { return true; } } catch { } } if ((int)fallbackKey != 0) { return WasKeyPressed(fallbackKey); } return false; } public static bool WasControlPressed(string controlPath, KeyCode fallbackKey = 0) { //IL_0028: 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) try { if (!string.IsNullOrWhiteSpace(controlPath)) { InputControl obj = InputSystem.FindControl(controlPath); ButtonControl val = (ButtonControl)(object)((obj is ButtonControl) ? obj : null); if (val != null && val.wasPressedThisFrame) { return true; } } } catch { } if ((int)fallbackKey != 0) { return WasKeyPressed(fallbackKey); } return false; } private static bool TryGetLegacyKeyDown(KeyCode key) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) if (_legacyInputUnavailable) { return false; } try { return Input.GetKeyDown(key); } catch (InvalidOperationException) { _legacyInputUnavailable = true; return false; } } private static bool TryGetNewInputSystemKeyDown(KeyCode key) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) try { if (!TryResolveKeyboard(out var keyboard)) { return false; } string keyboardPropertyName = GetKeyboardPropertyName(key); if (string.IsNullOrEmpty(keyboardPropertyName)) { return false; } if (!KeyboardPropertyCache.TryGetValue(keyboardPropertyName, out var value)) { value = _keyboardType.GetProperty(keyboardPropertyName); KeyboardPropertyCache[keyboardPropertyName] = value; } if (value == null) { return false; } object value2 = value.GetValue(keyboard); if (value2 == null) { return false; } PropertyInfo property = value2.GetType().GetProperty("wasPressedThisFrame"); return property != null && (bool)property.GetValue(value2); } catch { return false; } } private static bool TryResolveKeyboard(out object keyboard) { keyboard = null; if (_keyboardType == null) { _keyboardType = Type.GetType("UnityEngine.InputSystem.Keyboard, Unity.InputSystem"); if (_keyboardType == null) { return false; } } if (_keyboardCurrentProperty == null) { _keyboardCurrentProperty = _keyboardType.GetProperty("current"); if (_keyboardCurrentProperty == null) { return false; } } keyboard = _keyboardCurrentProperty.GetValue(null); return keyboard != null; } private static string GetKeyboardPropertyName(KeyCode key) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Invalid comparison between Unknown and I4 //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Invalid comparison between Unknown and I4 //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Invalid comparison between Unknown and I4 //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Invalid comparison between Unknown and I4 //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Invalid comparison between Unknown and I4 //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Invalid comparison between Unknown and I4 //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Invalid comparison between Unknown and I4 //IL_0067: 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_0070: Expected I4, but got Unknown //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Invalid comparison between Unknown and I4 //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Expected I4, but got Unknown if (KeyPropertyOverrides.TryGetValue(key, out var value)) { return value; } if ((int)key >= 97 && (int)key <= 122) { return char.ToLowerInvariant(((object)(KeyCode)(ref key)).ToString()[0]) + "Key"; } if ((int)key >= 48 && (int)key <= 57) { return $"digit{key - 48}Key"; } if ((int)key >= 256 && (int)key <= 265) { return $"numpad{key - 256}Key"; } if ((int)key >= 282 && (int)key <= 296) { return ((object)(KeyCode)(ref key)).ToString().ToLowerInvariant() + "Key"; } return null; } private static bool TryGetAction(string actionName, out InputAction action) { action = null; if (string.IsNullOrWhiteSpace(actionName)) { return false; } if (ActionCache.TryGetValue(actionName, out var value) && value != null) { action = value; return true; } InputAction val = ResolveGameAction(actionName); if (val == null) { return false; } ActionCache[actionName] = val; action = val; return true; } private static InputAction ResolveGameAction(string actionName) { try { InputAction val = InputManager.FindAction(actionName); if (val != null) { return val; } } catch { } try { InputActionAsset actionsAsset = InputManager.ActionsAsset; if ((Object)(object)actionsAsset == (Object)null) { return null; } int num = actionName.IndexOf('/'); if (num > 0 && num < actionName.Length - 1) { string text = actionName.Substring(0, num); string text2 = actionName.Substring(num + 1); InputActionMap obj2 = actionsAsset.FindActionMap(text, false); InputAction val2 = ((obj2 != null) ? obj2.FindAction(text2, false) : null); if (val2 != null) { return val2; } } return actionsAsset.FindAction(actionName, false); } catch { return null; } } } } namespace IceBoxModLib.UI { public static class ModNotification { private const string NotificationObjectName = "RoadsideResearch.SharedModNotification"; private static GameObject _notificationObj; public static void Show(string message, float duration = 5f, Color? textColor = null) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_000b: 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_002c: Unknown result type (might be due to invalid IL or missing references) try { Color textColor2 = (Color)(((??)textColor) ?? Color.white); ModNotificationBehaviour orCreateBehaviour = GetOrCreateBehaviour(); if ((Object)(object)orCreateBehaviour != (Object)null) { orCreateBehaviour.ShowNotification(message, duration, textColor2); } } catch (Exception ex) { Debug.LogError(Object.op_Implicit("[ModNotification] 通知创建失败: " + ex.Message)); } } public static void Dismiss() { ModNotificationBehaviour existingBehaviour = GetExistingBehaviour(); if ((Object)(object)existingBehaviour != (Object)null) { existingBehaviour.HideNotification(); } } private static ModNotificationBehaviour GetOrCreateBehaviour() { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown ModNotificationBehaviour existingBehaviour = GetExistingBehaviour(); if ((Object)(object)existingBehaviour != (Object)null) { return existingBehaviour; } _notificationObj = FindExistingNotificationObject(); if ((Object)(object)_notificationObj == (Object)null) { _notificationObj = new GameObject("RoadsideResearch.SharedModNotification"); Object.DontDestroyOnLoad((Object)(object)_notificationObj); } existingBehaviour = _notificationObj.GetComponent(); if ((Object)(object)existingBehaviour == (Object)null) { existingBehaviour = _notificationObj.AddComponent(); } return existingBehaviour; } private static ModNotificationBehaviour GetExistingBehaviour() { if ((Object)(object)_notificationObj == (Object)null) { _notificationObj = FindExistingNotificationObject(); } if ((Object)(object)_notificationObj == (Object)null) { return null; } return _notificationObj.GetComponent(); } private static GameObject FindExistingNotificationObject() { GameObject[] array = Il2CppArrayBase.op_Implicit(Resources.FindObjectsOfTypeAll()); foreach (GameObject val in array) { if ((Object)(object)val != (Object)null && ((Object)val).name == "RoadsideResearch.SharedModNotification") { return val; } } return null; } } public class ModNotificationBehaviour : MonoBehaviour { private string _message; private float _duration; private float _startTime; private Color _textColor; private GUIStyle _textStyle; private GUIStyle _shadowStyle; private Texture2D _bgTexture; private bool _initialized; private bool _visible; private const float FadeInTime = 0.4f; private const float FadeOutTime = 0.6f; private const float SlideDistance = 30f; public ModNotificationBehaviour(IntPtr ptr) : base(ptr) { } [HideFromIl2Cpp] public void ShowNotification(string message, float duration, Color textColor) { //IL_000f: 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_003b: Unknown result type (might be due to invalid IL or missing references) _message = message; _duration = duration; _textColor = textColor; _startTime = Time.time; _visible = true; if (_textStyle != null) { _textStyle.normal.textColor = _textColor; } } [HideFromIl2Cpp] public void HideNotification() { _visible = false; _message = null; } [HideFromIl2Cpp] private void InitStyles() { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: 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_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Expected O, but got Unknown //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Expected O, but got Unknown //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Expected O, but got Unknown //IL_00cb: Unknown result type (might be due to invalid IL or missing references) if (!_initialized) { _initialized = true; _bgTexture = CreateRoundedRectTexture(512, 64, 16, new Color(0.1f, 0.1f, 0.1f, 0.5f)); _textStyle = new GUIStyle(GUI.skin.label) { fontSize = 24, fontStyle = (FontStyle)0, alignment = (TextAnchor)4, wordWrap = true }; _textStyle.normal.textColor = _textColor; _textStyle.padding = new RectOffset(20, 20, 8, 8); _shadowStyle = new GUIStyle(_textStyle); _shadowStyle.normal.textColor = new Color(0f, 0f, 0f, 0.6f); } } private void OnGUI() { //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Expected O, but got Unknown //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) if (!_visible || string.IsNullOrEmpty(_message)) { return; } float num = Time.time - _startTime; if (num > _duration) { HideNotification(); return; } InitStyles(); float num4; float num3; if (num < 0.4f) { float num2 = num / 0.4f; num2 = 1f - (1f - num2) * (1f - num2); num3 = num2; num4 = 30f * (1f - num2); } else if (num > _duration - 0.6f) { float num5 = (_duration - num) / 0.6f; num5 *= num5; num3 = num5; num4 = 30f * (1f - num5); } else { num3 = 1f; num4 = 0f; } num3 = Mathf.Clamp01(num3); float num6 = Mathf.Min((float)Screen.width * 0.75f, 800f); float num7 = 40f; GUIContent val = new GUIContent(_message); float num8 = _textStyle.CalcHeight(val, num6 - num7); float num9 = num6; float num10 = num8 + 24f; float num11 = ((float)Screen.width - num9) / 2f; float num12 = (float)Screen.height - num10 - 140f + num4; Color color = GUI.color; GUI.color = new Color(1f, 1f, 1f, num3); GUI.DrawTexture(new Rect(num11, num12, num9, num10), (Texture)(object)_bgTexture); GUI.Label(new Rect(num11 + 1f, num12 + 1f, num9, num10), _message, _shadowStyle); GUI.Label(new Rect(num11, num12, num9, num10), _message, _textStyle); GUI.color = color; } private void OnDestroy() { if ((Object)(object)_bgTexture != (Object)null) { Object.Destroy((Object)(object)_bgTexture); _bgTexture = null; } } [HideFromIl2Cpp] private static Texture2D CreateRoundedRectTexture(int width, int height, int radius, Color color) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Expected O, but got Unknown //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(width, height, (TextureFormat)4, false); Color val2 = default(Color); ((Color)(ref val2))..ctor(0f, 0f, 0f, 0f); for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { bool flag = true; if (i < radius && j < radius) { flag = (radius - i) * (radius - i) + (radius - j) * (radius - j) <= radius * radius; } else if (i > width - radius - 1 && j < radius) { int num = i - (width - radius - 1); flag = num * num + (radius - j) * (radius - j) <= radius * radius; } else if (i < radius && j > height - radius - 1) { int num2 = j - (height - radius - 1); flag = (radius - i) * (radius - i) + num2 * num2 <= radius * radius; } else if (i > width - radius - 1 && j > height - radius - 1) { int num3 = i - (width - radius - 1); int num4 = j - (height - radius - 1); flag = num3 * num3 + num4 * num4 <= radius * radius; } val.SetPixel(i, j, flag ? color : val2); } } val.Apply(); ((Texture)val).wrapMode = (TextureWrapMode)1; ((Texture)val).filterMode = (FilterMode)1; return val; } } } namespace IceBoxModLib.Runtime { public static class Il2CppTypeRegistry { private static readonly HashSet RegisteredTypes = new HashSet(); public static void RegisterType() where T : class { string item = typeof(T).FullName ?? typeof(T).Name; if (!RegisteredTypes.Contains(item)) { ClassInjector.RegisterTypeInIl2Cpp(); RegisteredTypes.Add(item); } } } } namespace IceBoxModLib.Localization { public class ModLocalizationService { private readonly Dictionary> _localizations = new Dictionary>(); private readonly HashSet _supportedLanguages; private readonly string _fallbackLanguage; private string _currentLanguage; public string CurrentLanguage => _currentLanguage; public ModLocalizationService(IEnumerable supportedLanguages, string fallbackLanguage = "English") { _fallbackLanguage = fallbackLanguage; _currentLanguage = fallbackLanguage; _supportedLanguages = new HashSet(supportedLanguages); LocalizationManager.OnLocalizeEvent += OnLocalizeCallback.op_Implicit((Action)OnGameLanguageChanged); UpdateCurrentLanguage(); } public void AddTranslations(string language, Dictionary translations) { if (!string.IsNullOrEmpty(language) && translations != null && translations.Count != 0) { _localizations[language] = translations; } } public string GetText(string key, params object[] args) { if (string.IsNullOrEmpty(_currentLanguage) || !_localizations.ContainsKey(_currentLanguage)) { _currentLanguage = _fallbackLanguage; } if (_localizations.TryGetValue(_currentLanguage, out var value) && value.TryGetValue(key, out var value2)) { if (args.Length == 0) { return value2; } return string.Format(value2, args); } if (_currentLanguage != _fallbackLanguage && _localizations.TryGetValue(_fallbackLanguage, out var value3) && value3.TryGetValue(key, out var value4)) { if (args.Length == 0) { return value4; } return string.Format(value4, args); } return key; } private void OnGameLanguageChanged() { UpdateCurrentLanguage(); } private void UpdateCurrentLanguage() { try { string currentLanguage = LocalizationManager.CurrentLanguage; if (!string.IsNullOrEmpty(currentLanguage) && _supportedLanguages.Contains(currentLanguage)) { _currentLanguage = currentLanguage; return; } } catch { } _currentLanguage = _fallbackLanguage; } } } namespace IceBoxModLib.Config { public abstract class ModConfigBase { protected readonly ConfigFile ConfigFile; protected ModConfigBase(ConfigFile configFile) { ConfigFile = configFile; } protected ConfigEntry RegisterBool(string section, string key, string description, bool defaultValue) { return ConfigFile.Bind(section, key, defaultValue, description); } protected ConfigEntry RegisterString(string section, string key, string description, string defaultValue) { return ConfigFile.Bind(section, key, defaultValue, description); } protected ConfigEntry RegisterKeyCode(string section, string key, string description, KeyCode defaultValue) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) return ConfigFile.Bind(section, key, defaultValue, description); } protected ConfigEntry RegisterInt(string section, string key, string description, int defaultValue) { return ConfigFile.Bind(section, key, defaultValue, description); } protected ConfigEntry RegisterIntRange(string section, string key, string description, int defaultValue, int minValue, int maxValue) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown return ConfigFile.Bind(section, key, defaultValue, new ConfigDescription(description, (AcceptableValueBase)(object)new AcceptableValueRange(minValue, maxValue), Array.Empty())); } protected ConfigEntry RegisterFloat(string section, string key, string description, float defaultValue) { return ConfigFile.Bind(section, key, defaultValue, description); } protected ConfigEntry RegisterFloatRange(string section, string key, string description, float defaultValue, float minValue, float maxValue) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown return ConfigFile.Bind(section, key, defaultValue, new ConfigDescription(description, (AcceptableValueBase)(object)new AcceptableValueRange(minValue, maxValue), Array.Empty())); } } }