Decompiled source of BuildLogisticsAutoZoom v1.0.4

BepInEx\plugins\BuildLogisticsAutoZoom\BuildLogisticsAutoZoom.dll

Decompiled 2 weeks ago
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<bool> Enabled;

	internal static ConfigEntry<bool> ConstructionEnabled;

	internal static ConfigEntry<bool> LogisticsEnabled;

	internal static ConfigEntry<bool> Diagnostics;

	internal static ConfigEntry<float> ConstructionCameraScale;

	internal static ConfigEntry<float> 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<string>("Build Logistics Auto Zoom");
			((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ");
			((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("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<bool>("General", "Enabled", true, BuildDescription("entry.enabled", "entry.enabled.desc", "General", "section.general", 1));
			ConstructionEnabled = ((BasePlugin)this).Config.Bind<bool>("Modes", "Construction", true, BuildDescription("entry.construction.enabled", "entry.construction.enabled.desc", "Modes", "section.modes", 10));
			ConstructionCameraScale = ((BasePlugin)this).Config.Bind<float>("Modes", "ConstructionCameraScale", 1f, BuildScaleDescription("entry.construction.scale", "entry.construction.scale.desc", 11));
			LogisticsEnabled = ((BasePlugin)this).Config.Bind<bool>("Modes", "Logistics", true, BuildDescription("entry.logistics.enabled", "entry.logistics.enabled.desc", "Modes", "section.modes", 12));
			LogisticsCameraScale = ((BasePlugin)this).Config.Bind<float>("Modes", "LogisticsCameraScale", 1f, BuildScaleDescription("entry.logistics.scale", "entry.logistics.scale.desc", 13));
			Diagnostics = ((BasePlugin)this).Config.Bind<bool>("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<object>()), ((BasePlugin)this).Config, new ModSettingsModOptions
		{
			Icon = "cog",
			Version = "1.0.4",
			Author = "wwwshe",
			Description = I18n.L.Text("mod.description", Array.Empty<object>()),
			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<object>()), (AcceptableValueBase)null, new object[2]
		{
			ModSettingsTags.Section(sectionKey, I18n.L.Text(sectionNameKey, Array.Empty<object>()), (int?)SectionOrder(sectionKey), (bool?)null),
			ModSettingsTags.Entry(I18n.L.Text(nameKey, Array.Empty<object>()), I18n.L.Text(descKey, Array.Empty<object>()), (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<object>()), (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 5f), new object[2]
		{
			ModSettingsTags.Section("Modes", I18n.L.Text("section.modes", Array.Empty<object>()), (int?)20, (bool?)null),
			ModSettingsTags.Entry(I18n.L.Text(nameKey, Array.Empty<object>()), I18n.L.Text(descKey, Array.Empty<object>()), (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("<Description>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<string>(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<string>(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<string, object?>? 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<IDisposable> _ownedTargets = new List<IDisposable>();

	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<string>(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<string>(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<string, object> 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<string>(phase);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("] mode=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(modeInstance?.GetType().FullName ?? "(none)");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("globals(CameraScale=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float?>(GetStaticFloat(type, "CameraScale"));
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", ZoomScale=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float?>(GetStaticFloat(type, "ZoomScale"));
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", ZoomedOut=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool?>(GetStaticBool(type, "ZoomedOut"));
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(") ");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("camera(X=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float?>(GetFloat(instance, "X"));
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", Y=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float?>(GetFloat(instance, "Y"));
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", CurrentX=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float?>(GetFloat(instance, "CurrentX"));
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", CurrentY=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float?>(GetFloat(instance, "CurrentY"));
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", CurrentPx=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float?>(GetFloat(instance, "CurrentPx"));
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", CurrentPy=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float?>(GetFloat(instance, "CurrentPy"));
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", XScale=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float?>(GetFloat(instance, "XScale"));
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", YScale=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float?>(GetFloat(instance, "YScale"));
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(") ");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("hitbox=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<object>(GetObjectValue(instance, "HitBox"));
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("viewport=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(num);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("x");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(num2);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" world=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(width);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("x");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(height);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" chunkedWorld=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(GetChunkedWorldDiagnostics());
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" playerViewSize=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(GetPlayerViewSizeDiagnostics());
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("targets(entity=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(GetRenderTargetSize(obj, "_entityTarget"));
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", world=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(GetRenderTargetSize(obj, "_worldRender"));
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", normal=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(GetRenderTargetSize(obj, "NormalMap"));
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", metallic=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(GetRenderTargetSize(obj, "MetallicMap"));
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", rendered=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(GetRenderTargetSize(obj, "RenderedTexture"));
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", ui=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(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<string>(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<string>(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<string>(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<string>(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<string>(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<string>(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<string>(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<string, object?> CaptureRenderTargets(object? game)
	{
		Dictionary<string, object> dictionary = new Dictionary<string, object>();
		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<string, object?> 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<string, object> 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<string>(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 + ")";
		}
	}
}