using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Core.Logging.Interpolation; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using Big_Visuals.Configuration; using HarmonyLib; using Il2CppInterop.Runtime.Injection; using Rewired; using UnityEngine; using UnityEngine.Rendering.Universal; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("Big_Visuals")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+56a6a1787d783cbd674f69501bfa6a3e7a93065d")] [assembly: AssemblyProduct("Big Visuals")] [assembly: AssemblyTitle("Big_Visuals")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace Big_Visuals { [BepInPlugin("Big_Visuals", "Big Visuals", "1.0.0")] public class Plugin : BasePlugin { private readonly Harmony _harmony = new Harmony("Big_Visuals"); private ModConfigurationUI _ui; internal static ManualLogSource Log { get; private set; } public static Plugin Instance { get; private set; } public ConfigurationHandler ConfigurationHandler { get; private set; } = null; public Settings Settings { get; private set; } = null; public override void Load() { //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Expected O, but got Unknown //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Expected O, but got Unknown Log = ((BasePlugin)this).Log; if (Instance == null) { Instance = this; } ClassInjector.RegisterTypeInIl2Cpp(); ClassInjector.RegisterTypeInIl2Cpp(); ConfigurationHandler = new ConfigurationHandler(((BasePlugin)this).Config); Settings = new Settings(); _harmony.PatchAll(); GameObject val = new GameObject("BigVisualsUI"); Object.DontDestroyOnLoad((Object)(object)val); _ui = val.AddComponent(); _ui.Init(); SettingsRetry settingsRetry = val.AddComponent(); ((Behaviour)settingsRetry).enabled = false; SettingsRetry.SetInstance(settingsRetry); ManualLogSource log = Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(18, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Plugin "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted("Big Visuals"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" is loaded!"); } log.LogInfo(val2); } } public class Settings { private static readonly BindingFlags PipelineMemberFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; private ConfigurationHandler _configurationHandler = Plugin.Instance.ConfigurationHandler; public void SetAllSettings() { SetResolutionScale(); SetUpscaler(); SetLODQuality(); SetShadowCascades(); SetAnisotropicFiltering(); SetSoftShadows(); SetShadowmapResolution(); } public void SetAllCameraSettings() { SetPostProcessAA(); SetFOV(); } public void SetAllCameraSettings(PlayerCameraMinder cameraMinder) { SetPostProcessAA(cameraMinder); SetFOV(); } public void SetSoftShadows() { ApplyToRenderPipelines("Soft Shadows", delegate(UniversalRenderPipelineAsset pipeline) { SetPipelineMember(pipeline, "supportsSoftShadows", _configurationHandler.SoftShadows); SetPipelineMember(pipeline, "m_SoftShadowsSupported", _configurationHandler.SoftShadows); }, (UniversalRenderPipelineAsset pipeline) => pipeline.supportsSoftShadows.ToString()); } public void SetShadowmapResolution() { ApplyToRenderPipelines("Shadowmap Resolution", delegate(UniversalRenderPipelineAsset pipeline) { pipeline.mainLightShadowmapResolution = _configurationHandler.ShadowmapResolution; SetPipelineMember(pipeline, "m_MainLightShadowmapResolution", (object)(ShadowResolution)_configurationHandler.ShadowmapResolution); }, (UniversalRenderPipelineAsset pipeline) => pipeline.mainLightShadowmapResolution.ToString()); } public void SetAnisotropicFiltering() { QualitySettings.anisotropicFiltering = (AnisotropicFiltering)(_configurationHandler.AnisotropicFiltering ? 2 : 0); Plugin.Log.LogInfo((object)("Anisotropic Filtering applied: " + _configurationHandler.AnisotropicFiltering)); } public void SetPostProcessAA() { ApplyPostProcessAA(Camera.main, "main camera"); } public void SetPostProcessAA(PlayerCameraMinder cameraMinder) { Camera val = null; if (cameraMinder != null && (Object)(object)cameraMinder.playerCameraReferences != (Object)null && (Object)(object)cameraMinder.playerCameraReferences.playerCamera != (Object)null) { val = cameraMinder.playerCameraReferences.playerCamera; } if ((Object)(object)val == (Object)null) { val = Camera.main; } ApplyPostProcessAA(val, "player camera"); } public void SetFOV() { PlayerCameraMinder.fovFromSettings = _configurationHandler.FOV; Plugin.Log.LogInfo((object)("FOV applied: " + _configurationHandler.FOV)); } public void SetResolutionScale() { ApplyToRenderPipelines("Render Scale", delegate(UniversalRenderPipelineAsset pipeline) { pipeline.renderScale = _configurationHandler.RenderScale; SetPipelineMember(pipeline, "m_RenderScale", _configurationHandler.RenderScale); }, (UniversalRenderPipelineAsset pipeline) => pipeline.renderScale.ToString("F3")); } public void SetUpscaler() { ApplyToRenderPipelines("Upscaling Filter", delegate(UniversalRenderPipelineAsset pipeline) { pipeline.upscalingFilter = (UpscalingFilterSelection)_configurationHandler.UpscalingFilter; SetPipelineMember(pipeline, "m_UpscalingFilter", (object)(UpscalingFilterSelection)_configurationHandler.UpscalingFilter); }, (UniversalRenderPipelineAsset pipeline) => ((object)pipeline.upscalingFilter/*cast due to .constrained prefix*/).ToString()); } public void SetLODQuality() { QualitySettings.lodBias = _configurationHandler.LodQuality; Plugin.Log.LogInfo((object)("LOD Bias applied: " + _configurationHandler.LodQuality)); } public void SetShadowCascades() { ApplyToRenderPipelines("Shadow Cascades", delegate(UniversalRenderPipelineAsset pipeline) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) pipeline.shadowCascadeCount = _configurationHandler.ShadowCascades; SetPipelineMember(pipeline, "m_ShadowCascadeCount", _configurationHandler.ShadowCascades); SetPipelineMember(pipeline, "m_ShadowCascades", GetShadowCascadeOption(_configurationHandler.ShadowCascades)); }, (UniversalRenderPipelineAsset pipeline) => pipeline.shadowCascadeCount.ToString()); } private void ApplyToRenderPipelines(string settingName, Action apply, Func readBack) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Expected O, but got Unknown List list = new List(); foreach (UniversalRenderPipelineAsset item in Resources.FindObjectsOfTypeAll()) { list.Add(item); } bool flag = default(bool); if (list.Count == 0) { ManualLogSource log = Plugin.Log; BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(65, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(settingName); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" not applied: no UniversalRenderPipelineAsset is active or loaded"); } log.LogWarning(val); return; } foreach (UniversalRenderPipelineAsset item2 in list) { apply(item2); } ManualLogSource log2 = Plugin.Log; BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(41, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(settingName); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" applied to "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(list.Count); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" URP asset(s), active value: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(readBack(list[0])); } log2.LogInfo(val2); } private static void SetPipelineMember(UniversalRenderPipelineAsset pipeline, string memberName, object value) { PropertyInfo property = ((object)pipeline).GetType().GetProperty(memberName, PipelineMemberFlags); if (property != null && property.CanWrite) { property.SetValue(pipeline, value); return; } FieldInfo field = ((object)pipeline).GetType().GetField(memberName, PipelineMemberFlags); if (field != null) { field.SetValue(pipeline, value); } } private static ShadowCascadesOption GetShadowCascadeOption(int cascadeCount) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) if (cascadeCount <= 1) { return (ShadowCascadesOption)0; } if (cascadeCount <= 2) { return (ShadowCascadesOption)1; } return (ShadowCascadesOption)2; } private void ApplyPostProcessAA(Camera camera, string sourceName) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Expected O, but got Unknown bool flag = default(bool); if ((Object)(object)camera == (Object)null) { ManualLogSource log = Plugin.Log; BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(41, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Camera AA not applied: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(sourceName); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" was not available"); } log.LogWarning(val); return; } UniversalAdditionalCameraData component = ((Component)camera).GetComponent(); if ((Object)(object)component == (Object)null) { ManualLogSource log2 = Plugin.Log; BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(60, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Camera AA not applied: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(sourceName); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" has no UniversalAdditionalCameraData"); } log2.LogWarning(val); } else { component.antialiasing = (AntialiasingMode)Plugin.Instance.ConfigurationHandler.CameraAA; Plugin.Log.LogInfo((object)("Camera AA applied: " + _configurationHandler.CameraAA)); } } } public class SettingsRetry : MonoBehaviour { private const int MaxAttempts = 300; private static SettingsRetry _instance; private static int _remainingAttempts; public SettingsRetry(IntPtr ptr) : base(ptr) { } internal static void SetInstance(SettingsRetry instance) { _instance = instance; } internal static void Request() { _remainingAttempts = 300; if ((Object)(object)_instance == (Object)null) { Plugin.Log.LogWarning((object)"Camera settings retry requested before retry component was ready"); } else { ((Behaviour)_instance).enabled = true; } } private void Update() { if (_remainingAttempts <= 0) { ((Behaviour)this).enabled = false; Plugin.Log.LogWarning((object)"Camera settings retry timed out before a URP camera was available"); return; } _remainingAttempts--; if (CameraSettingsTargetIsReady()) { Plugin.Instance.Settings.SetAllCameraSettings(); Plugin.Instance.Settings.SetAllSettings(); ((Behaviour)this).enabled = false; Plugin.Log.LogInfo((object)"Camera settings applied after player camera became available"); } } private static bool CameraSettingsTargetIsReady() { Camera main = Camera.main; return (Object)(object)main != (Object)null && (Object)(object)((Component)main).GetComponent() != (Object)null; } } public static class MyPluginInfo { public const string PLUGIN_GUID = "Big_Visuals"; public const string PLUGIN_NAME = "Big Visuals"; public const string PLUGIN_VERSION = "1.0.0"; } } namespace Big_Visuals.Patches { public static class PlayerLoadPatches { [HarmonyPatch(typeof(WorldManager), "OnLocalPlayerCharcterStart")] private static class LocalPlayerStartPatch { [HarmonyPostfix] private static void Postfix() { Plugin.Log.LogInfo((object)"Local player loaded, applying Big Visuals settings"); SettingsRetry.Request(); } } } public static class SettingsHandlerPatches { [HarmonyPatch(typeof(SettingsMenu))] [HarmonyPatch(/*Could not decode attribute arguments.*/)] private class ConstructorPatch { [HarmonyPostfix] private static void Postfix(SettingsMenu __instance) { Plugin.Instance.Settings.SetAllSettings(); } } [HarmonyPatch(typeof(SettingsMenu), "ActionResetGraphics")] private class SaveSettingPatch { [HarmonyPostfix] private static void Postfix(SettingsMenu __instance) { Plugin.Instance.Settings.SetAllSettings(); } } } } namespace Big_Visuals.Configuration { public class ConfigurationHandler { private sealed class ConfigChangeListener { private readonly ConfigEntry _entry; private readonly Action _onChanged; private readonly Func _clamp; public ConfigChangeListener(ConfigEntry entry, Action onChanged, Func clamp) { _entry = entry; _onChanged = onChanged; _clamp = clamp; } public void OnSettingChanged(object sender, EventArgs args) { if (_clamp != null) { _entry.Value = _clamp(_entry.Value); } _onChanged(); } } private ConfigFile _config; public ConfigEntry ConfigRenderScale; public ConfigEntry ConfigUpscalingFilter; public ConfigEntry ConfigLODQuality; public ConfigEntry ConfigMenuKey; public ConfigEntry ConfigShadowCascades; public ConfigEntry ConfigShadowmapResolution; public ConfigEntry ConfigSoftShadows; public ConfigEntry ConfigAnisotropicFiltering; public ConfigEntry ConfigCameraAA; public ConfigEntry ConfigFOV; public KeyCode MenuKey { get; private set; } public float RenderScale => ConfigRenderScale.Value; public int UpscalingFilter => ConfigUpscalingFilter.Value; public float LodQuality => ConfigLODQuality.Value; public int ShadowCascades => ConfigShadowCascades.Value; public int ShadowmapResolution => ConfigShadowmapResolution.Value; public bool SoftShadows => ConfigSoftShadows.Value; public bool AnisotropicFiltering => ConfigAnisotropicFiltering.Value; public int CameraAA => ConfigCameraAA.Value; public int FOV => ConfigFOV.Value; public ConfigurationHandler(ConfigFile configFile) { _config = configFile; Plugin.Log.LogInfo((object)"ConfigurationHandler initialising"); ConfigRenderScale = Bind("Scaling", "RenderScale", 1.4f, "Controls the render scale of the game. Native is 1.0 (100%). Range 0.1-2.0", delegate { Plugin.Instance.Settings.SetResolutionScale(); }, (float v) => Mathf.Clamp(v, 0.1f, 2f)); ConfigUpscalingFilter = Bind("Scaling", "UpscalingFilter", 1, "Controls what filter the game uses to scale to your monitor resolution. 0 = auto, 1 = linear, 2 = point, 3 = FSR 1.0", delegate { Plugin.Instance.Settings.SetUpscaler(); }, (int v) => Mathf.Clamp(v, 0, 4)); ConfigLODQuality = Bind("LOD", "LODQuality", 4f, "Controls the LOD bias of the game. Higher values increase detail distance. Range 0.1-10", delegate { Plugin.Instance.Settings.SetLODQuality(); }, (float v) => Mathf.Clamp(v, 0.1f, 10f)); ConfigShadowCascades = Bind("Shadows", "ShadowCascades", 4, "Controls the number of shadow cascades used by the directional light. Higher values improve shadow stability. Range 1-4", delegate { Plugin.Instance.Settings.SetShadowCascades(); }, ClampShadowCascades); ConfigShadowmapResolution = Bind("Shadows", "ShadowmapResolution", 8192, "Controls the quality of the shadows, can reduce performance so turn it down if you're having issues. Makes the trees less wobbly", delegate { Plugin.Instance.Settings.SetShadowmapResolution(); }, ClampShadowmapResolution); ConfigSoftShadows = Bind("Shadows", "SoftShadows", defaultValue: true, "Allows shadows to be soft, if your PC is too low spec for a high shadowmap setting this to false can stop the wobblyness of the shadows (but will result in a pixelly effect if the shadowmap res is low)", delegate { Plugin.Instance.Settings.SetSoftShadows(); }); ConfigAnisotropicFiltering = Bind("Quality", "AnisotropicFiltering", defaultValue: true, "Helps texture sharpness at angles (set to on)", delegate { Plugin.Instance.Settings.SetAnisotropicFiltering(); }); ConfigCameraAA = Bind("AntiAliasing", "CameraAA", 0, "Controls what type of AA the Camera uses. All of these options are essentially clever blur filters and sometimes people find them unpleasant. 0 = None, 1 = FXAA, 2 = SMAA, 3 = TAA.", delegate { Plugin.Instance.Settings.SetPostProcessAA(); }, (int v) => Mathf.Clamp(v, 0, 3)); ConfigFOV = Bind("Camera", "FOV", 90, "Controls the camera field of view. Range 60-150. Will override the option in the game's menu.", delegate { Plugin.Instance.Settings.SetFOV(); }, (int v) => Mathf.Clamp(v, 60, 150)); ConfigMenuKey = Bind("General", "Config Menu Key", "F11", "Keyboard key for opening the mod configuration menu", SetupInputKey); SetupInputKey(); Plugin.Log.LogInfo((object)"ConfigurationHandler initialised"); } private ConfigEntry Bind(string section, string key, T defaultValue, string description, Action onChanged = null, Func clamp = null) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown ConfigEntry val = _config.Bind(section, key, defaultValue, description); if (clamp != null) { val.Value = clamp(val.Value); } ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(9, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(key); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" set to: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(val.Value); } log.LogInfo(val2); if (onChanged != null) { AddSettingChangedHandler(val, onChanged, clamp); } return val; } private static int ClampMsaa(int value) { if (value <= 0) { return 0; } if (value <= 2) { return 2; } if (value <= 4) { return 4; } return 8; } private static int ClampShadowCascades(int value) { if (value <= 1) { return 1; } if (value <= 2) { return 2; } return 4; } private static int ClampShadowmapResolution(int value) { if (value <= 1024) { return 1024; } if (value <= 2048) { return 2048; } if (value <= 4096) { return 4096; } return 8192; } private static void AddSettingChangedHandler(ConfigEntry entry, Action onChanged, Func clamp) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown EventInfo eventInfo = typeof(ConfigEntry).GetEvent("SettingChanged"); if (eventInfo == null) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(42, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Could not subscribe to SettingChanged for "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(((ConfigEntryBase)entry).Definition.Key); } log.LogWarning(val); } else { ConfigChangeListener firstArgument = new ConfigChangeListener(entry, onChanged, clamp); MethodInfo method = typeof(ConfigChangeListener).GetMethod("OnSettingChanged", BindingFlags.Instance | BindingFlags.Public); Delegate handler = Delegate.CreateDelegate(eventInfo.EventHandlerType, firstArgument, method); eventInfo.AddEventHandler(entry, handler); } } private void SetupInputKey() { //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Expected O, but got Unknown //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown //IL_0043: Unknown result type (might be due to invalid IL or missing references) bool flag = default(bool); if (Enum.TryParse(ConfigMenuKey.Value, out KeyCode result)) { MenuKey = result; ManualLogSource log = Plugin.Log; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(16, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Menu key set to "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(MenuKey); } log.LogInfo(val); return; } MenuKey = (KeyCode)292; ManualLogSource log2 = Plugin.Log; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(28, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Invalid menu key "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ConfigMenuKey.Value); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", using F11"); } log2.LogWarning(val2); } } public class ModConfigurationUI : MonoBehaviour { private const int MouseWheelAxis = 2; private List