using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Core.Logging.Interpolation; using BepInEx.Logging; using BepInEx.NET.Common; using HarmonyLib; using ModSettingsMenu.Api; using RomesteadLocalizationAPI.Api; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETCoreApp,Version=v8.0", FrameworkDisplayName = ".NET 8.0")] [assembly: AssemblyCompany("BuildLogisticsAutoZoom")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.4.0")] [assembly: AssemblyInformationalVersion("1.0.4")] [assembly: AssemblyProduct("BuildLogisticsAutoZoom")] [assembly: AssemblyTitle("BuildLogisticsAutoZoom")] [assembly: AssemblyVersion("1.0.4.0")] [module: RefSafetyRules(11)] namespace BuildLogisticsAutoZoom; internal static class I18n { public static readonly RomesteadLocalizer L = RomesteadLocalization.For("local.romestead.build-logistics-auto-zoom"); } [BepInPlugin("local.romestead.build-logistics-auto-zoom", "Build Logistics Auto Zoom", "1.0.4")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class Plugin : BasePlugin { public const string PluginGuid = "local.romestead.build-logistics-auto-zoom"; public const string PluginName = "Build Logistics Auto Zoom"; public const string PluginVersion = "1.0.4"; internal static ManualLogSource LogSource; internal static ConfigEntry Enabled; internal static ConfigEntry ConstructionEnabled; internal static ConfigEntry LogisticsEnabled; internal static ConfigEntry Diagnostics; internal static ConfigEntry ConstructionCameraScale; internal static ConfigEntry LogisticsCameraScale; private Harmony? _harmony; private bool _settingsRegistered; public override void Load() { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Expected O, but got Unknown //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Expected O, but got Unknown LogSource = ((BasePlugin)this).Log; I18n.L.RegisterJson(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "localization.json")); RegisterSettings(); RomesteadLocalization.LocalizationApplied += OnLocalizationApplied; _harmony = new Harmony("local.romestead.build-logistics-auto-zoom"); PatchMode("Candide.PlayerMode.Construction.ConstructionModeManager"); PatchMode("Candide.PlayerMode.Logistics.LogisticsModeManager"); ManualLogSource logSource = LogSource; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(9, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendFormatted("Build Logistics Auto Zoom"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted("1.0.4"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" loaded."); } logSource.LogInfo(val); } public override bool Unload() { RomesteadLocalization.LocalizationApplied -= OnLocalizationApplied; ModeZoomController.Restore(); Harmony? harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } return true; } private void OnLocalizationApplied(string locale) { RegisterSettings(); } private void RegisterSettings() { //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_023b: Unknown result type (might be due to invalid IL or missing references) //IL_0246: Unknown result type (might be due to invalid IL or missing references) //IL_0251: Unknown result type (might be due to invalid IL or missing references) //IL_025c: Unknown result type (might be due to invalid IL or missing references) //IL_0276: Unknown result type (might be due to invalid IL or missing references) //IL_0288: Expected O, but got Unknown if (!_settingsRegistered) { _settingsRegistered = true; Enabled = ((BasePlugin)this).Config.Bind("General", "Enabled", true, BuildDescription("entry.enabled", "entry.enabled.desc", "General", "section.general", 1)); ConstructionEnabled = ((BasePlugin)this).Config.Bind("Modes", "Construction", true, BuildDescription("entry.construction.enabled", "entry.construction.enabled.desc", "Modes", "section.modes", 10)); ConstructionCameraScale = ((BasePlugin)this).Config.Bind("Modes", "ConstructionCameraScale", 1f, BuildScaleDescription("entry.construction.scale", "entry.construction.scale.desc", 11)); LogisticsEnabled = ((BasePlugin)this).Config.Bind("Modes", "Logistics", true, BuildDescription("entry.logistics.enabled", "entry.logistics.enabled.desc", "Modes", "section.modes", 12)); LogisticsCameraScale = ((BasePlugin)this).Config.Bind("Modes", "LogisticsCameraScale", 1f, BuildScaleDescription("entry.logistics.scale", "entry.logistics.scale.desc", 13)); Diagnostics = ((BasePlugin)this).Config.Bind("Debug", "Diagnostics", false, BuildDescription("entry.diagnostics", "entry.diagnostics.desc", "Debug", "section.debug", 100)); } else { SetDescription((ConfigEntryBase)(object)Enabled, BuildDescription("entry.enabled", "entry.enabled.desc", "General", "section.general", 1)); SetDescription((ConfigEntryBase)(object)ConstructionEnabled, BuildDescription("entry.construction.enabled", "entry.construction.enabled.desc", "Modes", "section.modes", 10)); SetDescription((ConfigEntryBase)(object)ConstructionCameraScale, BuildScaleDescription("entry.construction.scale", "entry.construction.scale.desc", 11)); SetDescription((ConfigEntryBase)(object)LogisticsEnabled, BuildDescription("entry.logistics.enabled", "entry.logistics.enabled.desc", "Modes", "section.modes", 12)); SetDescription((ConfigEntryBase)(object)LogisticsCameraScale, BuildScaleDescription("entry.logistics.scale", "entry.logistics.scale.desc", 13)); SetDescription((ConfigEntryBase)(object)Diagnostics, BuildDescription("entry.diagnostics", "entry.diagnostics.desc", "Debug", "section.debug", 100)); } ModSettingsRegistry.Register("local.romestead.build-logistics-auto-zoom", I18n.L.Text("mod.name", Array.Empty()), ((BasePlugin)this).Config, new ModSettingsModOptions { Icon = "cog", Version = "1.0.4", Author = "wwwshe", Description = I18n.L.Text("mod.description", Array.Empty()), Order = 70 }); } private static ConfigDescription BuildDescription(string nameKey, string descKey, string sectionKey, string sectionNameKey, int order) { //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Expected O, but got Unknown return new ConfigDescription(I18n.L.Text(descKey, Array.Empty()), (AcceptableValueBase)null, new object[2] { ModSettingsTags.Section(sectionKey, I18n.L.Text(sectionNameKey, Array.Empty()), (int?)SectionOrder(sectionKey), (bool?)null), ModSettingsTags.Entry(I18n.L.Text(nameKey, Array.Empty()), I18n.L.Text(descKey, Array.Empty()), (int?)order, (double?)null, (bool?)null) }); } private static ConfigDescription BuildScaleDescription(string nameKey, string descKey, int order) { //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Expected O, but got Unknown return new ConfigDescription(I18n.L.Text(descKey, Array.Empty()), (AcceptableValueBase)(object)new AcceptableValueRange(1f, 5f), new object[2] { ModSettingsTags.Section("Modes", I18n.L.Text("section.modes", Array.Empty()), (int?)20, (bool?)null), ModSettingsTags.Entry(I18n.L.Text(nameKey, Array.Empty()), I18n.L.Text(descKey, Array.Empty()), (int?)order, (double?)0.25, (bool?)null) }); } private static int SectionOrder(string sectionKey) { if (!(sectionKey == "General")) { if (!(sectionKey == "Modes")) { return 90; } return 20; } return 10; } private static void SetDescription(ConfigEntryBase entry, ConfigDescription description) { typeof(ConfigEntryBase).GetField("k__BackingField", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(entry, description); } private void PatchMode(string typeName) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Expected O, but got Unknown //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Expected O, but got Unknown //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Expected O, but got Unknown Type type = FindType(typeName); bool flag = default(bool); if (type == null) { ManualLogSource logSource = LogSource; BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(16, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Could not find "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(typeName); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("."); } logSource.LogWarning(val); return; } BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; MethodInfo method = type.GetMethod("OnEntering", bindingAttr); MethodInfo method2 = type.GetMethod("OnLeaving", bindingAttr); if (method != null) { _harmony.Patch((MethodBase)method, (HarmonyMethod)null, new HarmonyMethod(typeof(ModeZoomController).GetMethod("OnModeEntering", BindingFlags.Static | BindingFlags.Public)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } if (method2 != null) { _harmony.Patch((MethodBase)method2, (HarmonyMethod)null, new HarmonyMethod(typeof(ModeZoomController).GetMethod("OnModeLeaving", BindingFlags.Static | BindingFlags.Public)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } ManualLogSource logSource2 = LogSource; BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(9, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Patched "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(typeName); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("."); } logSource2.LogInfo(val2); } private static Type? FindType(string fullName) { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { Type type = null; try { type = assembly.GetType(fullName, throwOnError: false); } catch { } if (type != null) { return type; } } return null; } } public static class ModeZoomController { private readonly record struct SavedZoom(float XScale, float YScale, float CameraScale, float ZoomScale, bool ZoomedOut, (int W, int H)? PlayerViewSize, (int W, int H)? ViewportSize, Dictionary? OriginalTargets); private const BindingFlags IF = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; private const BindingFlags SF = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; private static int _activeModeCount; private static SavedZoom? _savedZoom; private static readonly List _ownedTargets = new List(); public static void OnModeEntering(object __instance) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Expected O, but got Unknown try { if (!ShouldApply(__instance)) { return; } if (_activeModeCount == 0) { SavedZoom? savedZoom = ReadZoom(); if (!savedZoom.HasValue) { return; } _savedZoom = savedZoom; } _activeModeCount++; ApplyZoom(GetTargetScale(__instance)); LogDiagnostics("enter", __instance); } catch (Exception ex) { ManualLogSource logSource = Plugin.LogSource; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(24, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Auto zoom enter failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logSource.LogWarning(val); } } public static void OnModeLeaving(object __instance) { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown try { if (IsSupportedMode(__instance) && IsModeEnabled(__instance) && _activeModeCount > 0) { _activeModeCount--; if (_activeModeCount == 0) { Restore(); } LogDiagnostics("leave", __instance); } } catch (Exception ex) { ManualLogSource logSource = Plugin.LogSource; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(24, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Auto zoom leave failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logSource.LogWarning(val); } } public static void Restore() { if (_savedZoom.HasValue) { ApplyZoom(_savedZoom.Value); _savedZoom = null; _activeModeCount = 0; LogDiagnostics("restore", null); } } private static bool ShouldApply(object instance) { if (!Plugin.Enabled.Value) { return false; } if (IsSupportedMode(instance)) { return IsModeEnabled(instance); } return false; } private static bool IsSupportedMode(object instance) { string text = instance.GetType().FullName ?? ""; if (!text.Contains(".Construction.")) { return text.Contains(".Logistics."); } return true; } private static bool IsModeEnabled(object instance) { string text = instance.GetType().FullName ?? ""; if (text.Contains(".Construction.")) { return Plugin.ConstructionEnabled.Value; } if (text.Contains(".Logistics.")) { return Plugin.LogisticsEnabled.Value; } return false; } private static float GetTargetScale(object instance) { string text = instance.GetType().FullName ?? ""; if (text.Contains(".Construction.") && Plugin.ConstructionCameraScale.Value > 0f) { return Plugin.ConstructionCameraScale.Value; } if (text.Contains(".Logistics.") && Plugin.LogisticsCameraScale.Value > 0f) { return Plugin.LogisticsCameraScale.Value; } return GetGameMinimumCameraScale() ?? 1f; } private static float? GetGameMinimumCameraScale() { Type type = FindType("Candide.UserSettings.DisplayUserSettings"); if (type == null) { return null; } try { object obj = Activator.CreateInstance(type); object obj2 = type.GetMethod("GetMinCameraScale", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.Invoke(obj, null); return (obj2 == null) ? ((float?)null) : new float?(Convert.ToSingle(obj2)); } catch { return null; } } private static SavedZoom? ReadZoom() { Type? type = FindType("Candide.Globals"); object obj = type?.GetField("Game", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(null); object? instance = obj?.GetType().GetField("Camera", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(obj); float? num = GetFloat(instance, "XScale"); float? num2 = GetFloat(instance, "YScale"); float? staticFloat = GetStaticFloat(type, "CameraScale"); float? staticFloat2 = GetStaticFloat(type, "ZoomScale"); bool? staticBool = GetStaticBool(type, "ZoomedOut"); if (!num.HasValue || !num2.HasValue || !staticFloat.HasValue || !staticFloat2.HasValue || !staticBool.HasValue) { return null; } (int, int)? playerViewSize = null; (int, int)? viewportSize = null; try { object obj2 = FindType("Candide.GameModels.GameState")?.GetField("Config", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(null); object obj3 = obj2?.GetType().GetField("PlayerViewSize", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(obj2); if (obj3 != null) { Type type2 = obj3.GetType(); int num3 = Convert.ToInt32(type2.GetField("X", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(obj3) ?? ((object)0)); int num4 = Convert.ToInt32(type2.GetField("Y", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(obj3) ?? ((object)0)); if (num3 > 0 && num4 > 0) { playerViewSize = (num3, num4); } } } catch { } try { object obj5 = FindType("Candide.World.ExteriorWorldHandler")?.GetField("World", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(null); if (obj5 != null) { object obj6 = obj5.GetType().GetField("ViewportSize", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(obj5); if (obj6 != null) { Type type3 = obj6.GetType(); int num5 = Convert.ToInt32(type3.GetField("X", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(obj6) ?? ((object)0)); int num6 = Convert.ToInt32(type3.GetField("Y", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(obj6) ?? ((object)0)); if (num5 > 0 && num6 > 0) { viewportSize = (num5, num6); } } } } catch { } Dictionary originalTargets = CaptureRenderTargets(obj); return new SavedZoom(num.Value, num2.Value, staticFloat.Value, staticFloat2.Value, staticBool.Value, playerViewSize, viewportSize, originalTargets); } private static void ApplyZoom(float scale) { ApplyZoom(new SavedZoom(scale, scale, scale, scale, GetStaticBool(FindType("Candide.Globals"), "ZoomedOut") == true, null, null, null)); } private static void ApplyZoom(SavedZoom zoom) { Type? type = FindType("Candide.Globals"); SetStaticFloat(type, "CameraScale", zoom.CameraScale); SetStaticFloat(type, "ZoomScale", zoom.ZoomScale); SetStaticBool(type, "ZoomedOut", zoom.ZoomedOut); object obj = type?.GetField("Game", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(null); object obj2 = obj?.GetType().GetField("Camera", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(obj); SetFloat(obj2, "XScale", zoom.XScale); SetFloat(obj2, "YScale", zoom.YScale); RefreshCameraHitBox(obj, obj2, zoom.CameraScale); if (zoom.OriginalTargets != null) { RestoreRenderTargets(obj, zoom.OriginalTargets); } else { RefreshEngineRenderTargets(obj, zoom.CameraScale); } if (zoom.PlayerViewSize.HasValue || zoom.ViewportSize.HasValue) { RestoreChunkedWorldViewportSize(obj, zoom.PlayerViewSize, zoom.ViewportSize); } else { RefreshChunkedWorldViewportSize(obj, zoom.CameraScale); } ClampCameraInsideWorld(obj, obj2, zoom.CameraScale); } private static void LogDiagnostics(string phase, object? modeInstance) { //IL_04a3: Unknown result type (might be due to invalid IL or missing references) //IL_04aa: Expected O, but got Unknown //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Expected O, but got Unknown if (!Plugin.Diagnostics.Value) { return; } bool flag = default(bool); try { Type type = FindType("Candide.Globals"); object obj = type?.GetField("Game", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(null); object instance = obj?.GetType().GetField("Camera", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(obj); object obj2 = obj?.GetType().GetProperty("GraphicsDevice", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(obj) ?? obj?.GetType().GetMethod("get_GraphicsDevice", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.Invoke(obj, null); object obj3 = obj2?.GetType().GetProperty("Viewport", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(obj2); int num = 0; int num2 = 0; if (obj3 != null) { Type type2 = obj3.GetType(); num = Convert.ToInt32(type2.GetProperty("Width", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(obj3) ?? ((object)0)); num2 = Convert.ToInt32(type2.GetProperty("Height", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(obj3) ?? ((object)0)); } TryGetWorldPixelSize(out var width, out var height); ManualLogSource logSource = Plugin.LogSource; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(263, 26, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[diagnostics:"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(phase); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("] mode="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(modeInstance?.GetType().FullName ?? "(none)"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" "); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("globals(CameraScale="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(GetStaticFloat(type, "CameraScale")); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", ZoomScale="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(GetStaticFloat(type, "ZoomScale")); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", ZoomedOut="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(GetStaticBool(type, "ZoomedOut")); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(") "); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("camera(X="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(GetFloat(instance, "X")); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", Y="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(GetFloat(instance, "Y")); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", CurrentX="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(GetFloat(instance, "CurrentX")); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", CurrentY="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(GetFloat(instance, "CurrentY")); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", CurrentPx="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(GetFloat(instance, "CurrentPx")); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", CurrentPy="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(GetFloat(instance, "CurrentPy")); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", XScale="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(GetFloat(instance, "XScale")); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", YScale="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(GetFloat(instance, "YScale")); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(") "); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("hitbox="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(GetObjectValue(instance, "HitBox")); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" "); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("viewport="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("x"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num2); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" world="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(width); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("x"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(height); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" chunkedWorld="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(GetChunkedWorldDiagnostics()); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" playerViewSize="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(GetPlayerViewSizeDiagnostics()); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" "); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("targets(entity="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(GetRenderTargetSize(obj, "_entityTarget")); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", world="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(GetRenderTargetSize(obj, "_worldRender")); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", normal="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(GetRenderTargetSize(obj, "NormalMap")); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", metallic="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(GetRenderTargetSize(obj, "MetallicMap")); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", rendered="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(GetRenderTargetSize(obj, "RenderedTexture")); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", ui="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(GetRenderTargetSize(obj, "UiRenderTarget")); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")"); } logSource.LogInfo(val); } catch (Exception ex) { ManualLogSource logSource2 = Plugin.LogSource; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(20, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Diagnostics failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } logSource2.LogWarning(val2); } } private static string GetRenderTargetSize(object? game, string fieldName) { object obj = game?.GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(game); if (obj == null) { return "null"; } Type type = obj.GetType(); object value = type.GetProperty("Width", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(obj); object value2 = type.GetProperty("Height", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(obj); return $"{value}x{value2}"; } private static object? GetObjectValue(object? instance, string fieldName) { return instance?.GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(instance); } private static Type? FindType(string fullName) { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { Type type = null; try { type = assembly.GetType(fullName, throwOnError: false); } catch { } if (type != null) { return type; } } return null; } private static float? GetStaticFloat(Type? type, string fieldName) { object obj = type?.GetField(fieldName, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(null); if (obj != null) { return Convert.ToSingle(obj); } return null; } private static void SetStaticFloat(Type? type, string fieldName, float value) { type?.GetField(fieldName, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.SetValue(null, value); } private static bool? GetStaticBool(Type? type, string fieldName) { object obj = type?.GetField(fieldName, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(null); if (obj != null) { return Convert.ToBoolean(obj); } return null; } private static void SetStaticBool(Type? type, string fieldName, bool value) { type?.GetField(fieldName, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.SetValue(null, value); } private static float? GetFloat(object? instance, string fieldName) { object obj = instance?.GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(instance); if (obj != null) { return Convert.ToSingle(obj); } return null; } private static void SetFloat(object? instance, string fieldName, float value) { instance?.GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.SetValue(instance, value); } private static void RefreshCameraHitBox(object? game, object? camera, float cameraScale) { //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Expected O, but got Unknown if (game == null || camera == null || cameraScale <= 0f) { return; } try { object obj = game.GetType().GetProperty("GraphicsDevice", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(game) ?? game.GetType().GetMethod("get_GraphicsDevice", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.Invoke(game, null); object obj2 = obj?.GetType().GetProperty("Viewport", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(obj); if (obj2 != null) { Type type = obj2.GetType(); float num = Convert.ToSingle(type.GetProperty("Width", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(obj2) ?? ((object)0f)) / cameraScale; float num2 = Convert.ToSingle(type.GetProperty("Height", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(obj2) ?? ((object)0f)) / cameraScale; float? num3 = GetFloat(camera, "CurrentX"); float? num4 = GetFloat(camera, "CurrentY"); FieldInfo field = camera.GetType().GetField("HitBox", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (num3.HasValue && num4.HasValue && !(field == null)) { object value = Activator.CreateInstance(field.FieldType, num3.Value - num / 2f, num4.Value - num2 / 2f, num, num2); field.SetValue(camera, value); } } } catch (Exception ex) { ManualLogSource logSource = Plugin.LogSource; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(30, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Camera hitbox refresh failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logSource.LogWarning(val); } } private static void RestoreChunkedWorldViewportSize(object? game, (int W, int H)? playerViewSize, (int W, int H)? viewportSize) { //IL_0211: Unknown result type (might be due to invalid IL or missing references) //IL_0218: Expected O, but got Unknown if (game == null) { return; } try { object obj = FindType("Candide.World.ExteriorWorldHandler")?.GetField("World", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(null); if (obj == null) { return; } Type type = obj.GetType(); FieldInfo field = type.GetField("ViewportSize", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); FieldInfo field2 = type.GetField("ChunkSize", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); FieldInfo field3 = type.GetField("VisibleChunks", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); type.GetField("VisibleChunksCount", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field == null || field2 == null || field3 == null) { return; } if (viewportSize.HasValue) { object value = Activator.CreateInstance(field.FieldType, viewportSize.Value.W, viewportSize.Value.H); field.SetValue(obj, value); object value2 = field2.GetValue(obj); int num = Convert.ToInt32(value2?.GetType().GetField("X", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(value2) ?? ((object)32)); int num2 = Convert.ToInt32(value2?.GetType().GetField("Y", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(value2) ?? ((object)32)); int num3 = Math.Max(4, (2 + (viewportSize.Value.W - 1) / num) * (2 + (viewportSize.Value.H - 1) / num2)) + 2; if (!(field3.GetValue(obj) is Array array) || array.Length < num3) { Type elementType = field3.FieldType.GetElementType(); if (elementType != null) { field3.SetValue(obj, Array.CreateInstance(elementType, num3)); } } } if (playerViewSize.HasValue) { SetConfigPlayerViewSize(field.FieldType, playerViewSize.Value.W, playerViewSize.Value.H); } } catch (Exception ex) { ManualLogSource logSource = Plugin.LogSource; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(39, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Chunked world viewport restore failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logSource.LogWarning(val); } } private static void RefreshChunkedWorldViewportSize(object? game, float cameraScale) { //IL_02f4: Unknown result type (might be due to invalid IL or missing references) //IL_02fb: Expected O, but got Unknown if (game == null || cameraScale <= 0f) { return; } try { object obj = game.GetType().GetProperty("GraphicsDevice", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(game) ?? game.GetType().GetMethod("get_GraphicsDevice", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.Invoke(game, null); object obj2 = obj?.GetType().GetProperty("Viewport", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(obj); if (obj2 == null) { return; } Type type = obj2.GetType(); float num = Convert.ToSingle(type.GetProperty("Width", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(obj2) ?? ((object)0f)); float num2 = Convert.ToSingle(type.GetProperty("Height", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(obj2) ?? ((object)0f)); if (num <= 0f || num2 <= 0f) { return; } int num3 = (int)(num / cameraScale / 16f) + 8; int num4 = (int)(num2 / cameraScale / 16f) + 14; object obj3 = FindType("Candide.World.ExteriorWorldHandler")?.GetField("World", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(null); if (obj3 == null) { return; } Type type2 = obj3.GetType(); FieldInfo field = type2.GetField("ViewportSize", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); FieldInfo field2 = type2.GetField("ChunkSize", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); FieldInfo field3 = type2.GetField("VisibleChunks", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); FieldInfo field4 = type2.GetField("VisibleChunksCount", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field == null || field2 == null || field3 == null) { return; } Type fieldType = field.FieldType; object value = Activator.CreateInstance(fieldType, num3, num4); field.SetValue(obj3, value); SetConfigPlayerViewSize(fieldType, num3, num4); object value2 = field2.GetValue(obj3); int num5 = Convert.ToInt32(value2?.GetType().GetField("X", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(value2) ?? ((object)32)); int num6 = Convert.ToInt32(value2?.GetType().GetField("Y", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(value2) ?? ((object)32)); int num7 = Math.Max(4, (2 + (num3 - 1) / num5) * (2 + (num4 - 1) / num6)) + 2; if (!(field3.GetValue(obj3) is Array array) || array.Length < num7) { Type elementType = field3.FieldType.GetElementType(); if (elementType != null) { field3.SetValue(obj3, Array.CreateInstance(elementType, num7)); } } field4?.SetValue(obj3, 0); } catch (Exception ex) { ManualLogSource logSource = Plugin.LogSource; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(39, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Chunked world viewport refresh failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logSource.LogWarning(val); } } private static void SetConfigPlayerViewSize(Type pointType, int width, int height) { //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Expected O, but got Unknown try { object obj = FindType("Candide.GameModels.GameState")?.GetField("Config", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(null); FieldInfo fieldInfo = obj?.GetType().GetField("PlayerViewSize", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (!(fieldInfo == null)) { object value = Activator.CreateInstance(pointType, width, height); fieldInfo.SetValue(obj, value); } } catch (Exception ex) { ManualLogSource logSource = Plugin.LogSource; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(40, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Config player view size refresh failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logSource.LogWarning(val); } } private static void ClampCameraInsideWorld(object? game, object? camera, float cameraScale) { //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Expected O, but got Unknown if (game == null || camera == null || cameraScale <= 0f) { return; } try { object obj = game.GetType().GetProperty("GraphicsDevice", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(game) ?? game.GetType().GetMethod("get_GraphicsDevice", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.Invoke(game, null); object obj2 = obj?.GetType().GetProperty("Viewport", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(obj); if (obj2 == null) { return; } Type type = obj2.GetType(); float num = Convert.ToSingle(type.GetProperty("Width", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(obj2) ?? ((object)0f)) / cameraScale; float num2 = Convert.ToSingle(type.GetProperty("Height", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(obj2) ?? ((object)0f)) / cameraScale; if (!(num <= 0f) && !(num2 <= 0f) && TryGetWorldPixelSize(out var width, out var height)) { float? num3 = GetFloat(camera, "X"); float? num4 = GetFloat(camera, "Y"); if (num3.HasValue && num4.HasValue) { float x = ClampCenter(num3.Value, num, width); float y = ClampCenter(num4.Value, num2, height); SetCameraPosition(camera, x, y, cameraScale); } } } catch (Exception ex) { ManualLogSource logSource = Plugin.LogSource; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(21, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Camera clamp failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logSource.LogWarning(val); } } private static bool TryGetWorldPixelSize(out float width, out float height) { width = 0f; height = 0f; Type type = FindType("Candide.GameModels.GameState"); if (!(type?.GetField("WorldTiles", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(null) is Array { Rank: >=2 } array)) { return false; } float num = 16f; float num2 = 16f; object obj = type?.GetField("Config", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(null); object obj2 = obj?.GetType().GetField("TileSize", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(obj); if (obj2 != null) { num = GetFloat(obj2, "X") ?? num; num2 = GetFloat(obj2, "Y") ?? num2; } width = (float)array.GetLength(0) * num; height = (float)array.GetLength(1) * num2; if (width > 0f) { return height > 0f; } return false; } private static float ClampCenter(float center, float viewSize, float worldSize) { if (worldSize <= viewSize) { return worldSize / 2f; } float num = viewSize / 2f; return Math.Clamp(center, num, worldSize - num); } private static void SetCameraPosition(object camera, float x, float y, float scale) { SetFloat(camera, "X", x); SetFloat(camera, "Y", y); SetFloat(camera, "CurrentX", x); SetFloat(camera, "CurrentY", y); SetFloat(camera, "CurrentPx", (float)(int)(x * scale) / scale); SetFloat(camera, "CurrentPy", (float)(int)(y * scale) / scale); } private static void RefreshEngineRenderTargets(object? game, float cameraScale) { //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Expected O, but got Unknown if (game == null || cameraScale <= 0f) { return; } try { Type type = game.GetType(); object obj = type.GetProperty("GraphicsDevice", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(game) ?? type.GetMethod("get_GraphicsDevice", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.Invoke(game, null); if (obj == null) { return; } object obj2 = obj.GetType().GetProperty("Viewport", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(obj); if (obj2 == null) { return; } Type type2 = obj2.GetType(); int num = Convert.ToInt32(type2.GetProperty("Width", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(obj2) ?? ((object)0)); int num2 = Convert.ToInt32(type2.GetProperty("Height", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(obj2) ?? ((object)0)); if (num > 0 && num2 > 0) { Type type3 = type.GetField("_worldRender", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(game)?.GetType() ?? type.GetField("_entityTarget", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(game)?.GetType() ?? FindType("Microsoft.Xna.Framework.Graphics.RenderTarget2D"); if (!(type3 == null)) { SetRenderTarget(game, type, type3, obj, "_entityTarget", num, num2); SetRenderTarget(game, type, type3, obj, "_worldRender", (int)((float)num / cameraScale) + 3, (int)((float)num2 / cameraScale) + 3); SetRenderTarget(game, type, type3, obj, "NormalMap", num, num2); SetRenderTarget(game, type, type3, obj, "MetallicMap", num, num2); SetRenderTarget(game, type, type3, obj, "RenderedTexture", num, num2); } } } catch (Exception ex) { ManualLogSource logSource = Plugin.LogSource; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(37, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Engine render target refresh failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logSource.LogWarning(val); } } private static void SetRenderTarget(object game, Type gameType, Type renderTargetType, object graphicsDevice, string fieldName, int width, int height) { FieldInfo field = gameType.GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (!(field == null)) { object obj = Activator.CreateInstance(renderTargetType, graphicsDevice, width, height); field.SetValue(game, obj); if (obj is IDisposable item) { _ownedTargets.Add(item); } } } private static Dictionary CaptureRenderTargets(object? game) { Dictionary dictionary = new Dictionary(); if (game == null) { return dictionary; } Type type = game.GetType(); string[] array = new string[5] { "_entityTarget", "_worldRender", "NormalMap", "MetallicMap", "RenderedTexture" }; foreach (string text in array) { dictionary[text] = type.GetField(text, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(game); } return dictionary; } private static void RestoreRenderTargets(object? game, Dictionary originalTargets) { //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Expected O, but got Unknown if (game == null) { return; } try { Type type = game.GetType(); foreach (KeyValuePair originalTarget in originalTargets) { originalTarget.Deconstruct(out var key, out var value); string name = key; object value2 = value; FieldInfo field = type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (!(field == null)) { field.SetValue(game, value2); } } foreach (IDisposable ownedTarget in _ownedTargets) { try { ownedTarget.Dispose(); } catch { } } _ownedTargets.Clear(); } catch (Exception ex) { ManualLogSource logSource = Plugin.LogSource; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(30, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Render target restore failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logSource.LogWarning(val); } } private static string GetChunkedWorldDiagnostics() { try { object obj = FindType("Candide.World.ExteriorWorldHandler")?.GetField("World", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(null); if (obj == null) { return "(none)"; } Type type = obj.GetType(); return $"(viewportSize={type.GetField("ViewportSize", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(obj)}, chunkSize={type.GetField("ChunkSize", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(obj)}, visibleChunks={type.GetField("VisibleChunksCount", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(obj)})"; } catch (Exception ex) { return "(diagnostics failed: " + ex.Message + ")"; } } private static string GetPlayerViewSizeDiagnostics() { try { object obj = FindType("Candide.GameModels.GameState")?.GetField("Config", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(null); return (obj?.GetType().GetField("PlayerViewSize", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(obj))?.ToString() ?? "(null)"; } catch (Exception ex) { return "(failed: " + ex.Message + ")"; } } }