using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.1", FrameworkDisplayName = ".NET Framework 4.7.1")]
[assembly: AssemblyCompany("MoreOptimization")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("More Graphics Settings for Gamble With Your Friends")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1")]
[assembly: AssemblyProduct("MoreOptimization")]
[assembly: AssemblyTitle("MoreOptimization")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace MoreGraphicsSettings
{
[BepInPlugin("com.ananas1k.gwyf.moreoptimization", "More Optimization", "1.0.1")]
public class Plugin : BaseUnityPlugin
{
private const string PluginGuid = "com.ananas1k.gwyf.moreoptimization";
private const string PluginName = "More Optimization";
private const string PluginVersion = "1.0.1";
private const float TextureLimitSceneDelayFallback = 1.75f;
private const float TextureLimitEnforcementDurationFallback = 10f;
private const float TextureLimitEnforcementInterval = 0.5f;
private const float ContinuousQualityEnforcementInterval = 1f;
private const int TextureCopyFixLogLimit = 5;
public static ConfigEntry<int> ConfigGraphicsPreset;
public static ConfigEntry<int> ConfigRenderScale;
public static ConfigEntry<int> ConfigTextureResolution;
public static ConfigEntry<int> ConfigShadows;
public static ConfigEntry<int> ConfigVSync;
public static ConfigEntry<int> ConfigAntiAliasing;
public static ConfigEntry<int> ConfigTargetFPS;
public static ConfigEntry<int> ConfigLodBias;
public static ConfigEntry<int> ConfigAnisotropicFiltering;
public static ConfigEntry<int> ConfigReflectionProbes;
public static ConfigEntry<int> ConfigSoftParticles;
public static ConfigEntry<int> ConfigBackgroundFpsLimit;
public static ConfigEntry<int> ConfigLocalizationLanguage;
private static ConfigEntry<float> ConfigTextureLimitDelay;
private static ConfigEntry<float> ConfigTextureLimitEnforcementDuration;
private static ConfigEntry<int> ConfigContinuousQualityEnforcement;
private static ConfigEntry<int> ConfigRtlcTextureCopyFix;
private static Plugin Instance;
private Harmony harmony;
private Coroutine textureLimitRoutine;
private Coroutine continuousQualityRoutine;
private static bool syncingSettingsUi;
private static float nextTextureLimitApplyTime;
private static bool gameHasFocus = true;
private static bool gamePaused;
private static bool useRussianText;
private static bool textureCopyFallbackInProgress;
private static int textureCopyFixLogCount;
private static readonly float[] RenderScales = new float[5] { 0.5f, 0.6f, 0.75f, 0.9f, 1f };
private static readonly int[] TargetFpsValues = new int[5] { -1, 30, 60, 120, 144 };
private static readonly int[] QualityAntiAliasingLevels = new int[4] { 0, 2, 4, 8 };
private static readonly int[] UrpMsaaSampleCounts = new int[4] { 1, 2, 4, 8 };
private static readonly float[] LodBiasValues = new float[4] { 0.5f, 0.75f, 1f, 1.5f };
private void Awake()
{
//IL_0070: Unknown result type (might be due to invalid IL or missing references)
//IL_007a: Expected O, but got Unknown
Instance = this;
BindConfig();
useRussianText = ShouldUseRussianText();
if (ConfigGraphicsPreset.Value != 0)
{
ApplyPreset(ConfigGraphicsPreset.Value);
}
PrepareTextureCopyWindow();
ApplyGraphicsSettings(applyTextureLimit: false);
QueueDeferredTextureLimit();
StartContinuousQualityEnforcer();
SceneManager.sceneLoaded += OnSceneLoaded;
SceneManager.activeSceneChanged += OnActiveSceneChanged;
harmony = new Harmony("com.ananas1k.gwyf.moreoptimization");
int num = 0;
num += (PatchMethod("GraphicsSettingsApplier", "ApplyAll", null, "PatchGraphicsSettingsApplier_ApplyAll") ? 1 : 0);
num += (PatchMethod("SettingsLayoutRuntimeUI", "Awake", "PatchSettingsLayoutAwake", null) ? 1 : 0);
num += (PatchMethod("SettingsLayout", "NotifyChanged", null, "PatchNotifyChanged") ? 1 : 0);
num += (PatchMethod("Outline", "SmoothNormals", "PatchOutlineSmoothNormals", null) ? 1 : 0);
num += PatchGraphicsCopyTextureMethods();
((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("{0} {1} loaded. Active patches: {2}. URP, RTLC texture copy fix {3}, and {4} UI text enabled.", "More Optimization", "1.0.1", num, (ConfigRtlcTextureCopyFix.Value == 1) ? "enabled" : "disabled", useRussianText ? "Russian" : "English"));
}
private void OnDestroy()
{
SceneManager.sceneLoaded -= OnSceneLoaded;
SceneManager.activeSceneChanged -= OnActiveSceneChanged;
if (continuousQualityRoutine != null)
{
((MonoBehaviour)this).StopCoroutine(continuousQualityRoutine);
}
if (harmony != null)
{
harmony.UnpatchSelf();
}
}
private void BindConfig()
{
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: Expected O, but got Unknown
//IL_0053: Unknown result type (might be due to invalid IL or missing references)
//IL_005d: Expected O, but got Unknown
//IL_0084: Unknown result type (might be due to invalid IL or missing references)
//IL_008e: Expected O, but got Unknown
//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
//IL_00bf: Expected O, but got Unknown
//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
//IL_00f0: Expected O, but got Unknown
//IL_0117: Unknown result type (might be due to invalid IL or missing references)
//IL_0121: Expected O, but got Unknown
//IL_0148: Unknown result type (might be due to invalid IL or missing references)
//IL_0152: Expected O, but got Unknown
//IL_0179: Unknown result type (might be due to invalid IL or missing references)
//IL_0183: Expected O, but got Unknown
//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
//IL_01b4: Expected O, but got Unknown
//IL_01db: Unknown result type (might be due to invalid IL or missing references)
//IL_01e5: Expected O, but got Unknown
//IL_020c: Unknown result type (might be due to invalid IL or missing references)
//IL_0216: Expected O, but got Unknown
//IL_023d: Unknown result type (might be due to invalid IL or missing references)
//IL_0247: Expected O, but got Unknown
//IL_027a: Unknown result type (might be due to invalid IL or missing references)
//IL_0284: Expected O, but got Unknown
//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
//IL_02c1: Expected O, but got Unknown
//IL_02e8: Unknown result type (might be due to invalid IL or missing references)
//IL_02f2: Expected O, but got Unknown
//IL_0319: Unknown result type (might be due to invalid IL or missing references)
//IL_0323: Expected O, but got Unknown
//IL_034a: Unknown result type (might be due to invalid IL or missing references)
//IL_0354: Expected O, but got Unknown
ConfigGraphicsPreset = ((BaseUnityPlugin)this).Config.Bind<int>("Graphics", "Preset", 0, new ConfigDescription("0=Custom, 1=Potato, 2=Low, 3=Medium, 4=High, 5=Ultra", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 5), Array.Empty<object>()));
ConfigRenderScale = ((BaseUnityPlugin)this).Config.Bind<int>("Graphics", "RenderScale", 4, new ConfigDescription("0=0.5x, 1=0.6x, 2=0.75x, 3=0.9x, 4=1.0x", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 4), Array.Empty<object>()));
ConfigTextureResolution = ((BaseUnityPlugin)this).Config.Bind<int>("Graphics", "TextureResolution", 0, new ConfigDescription("0=Full, 1=Half, 2=Quarter, 3=Eighth", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 3), Array.Empty<object>()));
ConfigShadows = ((BaseUnityPlugin)this).Config.Bind<int>("Graphics", "Shadows", 2, new ConfigDescription("0=Disable, 1=HardOnly, 2=All", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 2), Array.Empty<object>()));
ConfigVSync = ((BaseUnityPlugin)this).Config.Bind<int>("Graphics", "VSync", 0, new ConfigDescription("0=Off, 1=On", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 1), Array.Empty<object>()));
ConfigAntiAliasing = ((BaseUnityPlugin)this).Config.Bind<int>("Graphics", "AntiAliasing", 0, new ConfigDescription("0=Off, 1=2x, 2=4x, 3=8x", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 3), Array.Empty<object>()));
ConfigTargetFPS = ((BaseUnityPlugin)this).Config.Bind<int>("Graphics", "TargetFPS", 0, new ConfigDescription("0=Uncapped, 1=30, 2=60, 3=120, 4=144", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 4), Array.Empty<object>()));
ConfigLodBias = ((BaseUnityPlugin)this).Config.Bind<int>("Graphics", "LodBias", 2, new ConfigDescription("0=Low, 1=Balanced, 2=Default, 3=High", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 3), Array.Empty<object>()));
ConfigAnisotropicFiltering = ((BaseUnityPlugin)this).Config.Bind<int>("Graphics", "AnisotropicFiltering", 1, new ConfigDescription("0=Disable, 1=Enable, 2=ForceEnable", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 2), Array.Empty<object>()));
ConfigReflectionProbes = ((BaseUnityPlugin)this).Config.Bind<int>("Graphics", "RealtimeReflectionProbes", 1, new ConfigDescription("0=Off, 1=On", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 1), Array.Empty<object>()));
ConfigSoftParticles = ((BaseUnityPlugin)this).Config.Bind<int>("Graphics", "SoftParticles", 1, new ConfigDescription("0=Off, 1=On", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 1), Array.Empty<object>()));
ConfigBackgroundFpsLimit = ((BaseUnityPlugin)this).Config.Bind<int>("Graphics", "BackgroundFPSLimit", 1, new ConfigDescription("0=Off, 1=10 FPS. Limits FPS while the game is minimized or unfocused.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 1), Array.Empty<object>()));
ConfigTextureLimitDelay = ((BaseUnityPlugin)this).Config.Bind<float>("Compatibility", "TextureLimitSceneDelay", 1.75f, new ConfigDescription("Delay in seconds before applying Texture Resolution after a scene loads. Helps texture replacement mods avoid CopyTexture mipmap errors.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 5f), Array.Empty<object>()));
ConfigTextureLimitEnforcementDuration = ((BaseUnityPlugin)this).Config.Bind<float>("Compatibility", "TextureLimitEnforcementDuration", 10f, new ConfigDescription("How long Texture Resolution is re-applied after startup/scene/settings changes. Keeps Potato/Low texture quality from being reset by the game.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 30f), Array.Empty<object>()));
ConfigContinuousQualityEnforcement = ((BaseUnityPlugin)this).Config.Bind<int>("Compatibility", "ContinuousQualityEnforcement", 1, new ConfigDescription("0=Off, 1=On. Re-applies More Optimization graphics settings while playing so level loads cannot reset Potato/Low texture quality or render scale.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 1), Array.Empty<object>()));
ConfigRtlcTextureCopyFix = ((BaseUnityPlugin)this).Config.Bind<int>("Compatibility", "RTLCTextureCopyFix", 1, new ConfigDescription("0=Off, 1=On. Falls back to Graphics.ConvertTexture when RTLC texture replacements hit a CopyTexture mipmap-count mismatch.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 1), Array.Empty<object>()));
ConfigLocalizationLanguage = ((BaseUnityPlugin)this).Config.Bind<int>("Localization", "Language", 0, new ConfigDescription("0=Auto, 1=English, 2=Russian. Auto uses Russian text when RTLC/XUnity Russian localization is detected.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 2), Array.Empty<object>()));
}
private static bool ShouldUseRussianText()
{
if (ConfigLocalizationLanguage != null)
{
if (ConfigLocalizationLanguage.Value == 1)
{
return false;
}
if (ConfigLocalizationLanguage.Value == 2)
{
return true;
}
}
return IsRussianLocalizationDetected();
}
private static bool IsRussianLocalizationDetected()
{
try
{
foreach (KeyValuePair<string, PluginInfo> pluginInfo in Chainloader.PluginInfos)
{
string text = pluginInfo.Key ?? string.Empty;
string text2 = ((pluginInfo.Value != null && pluginInfo.Value.Metadata != null) ? (pluginInfo.Value.Metadata.Name ?? string.Empty) : string.Empty);
string text3 = ((pluginInfo.Value != null && pluginInfo.Value.Metadata != null) ? (pluginInfo.Value.Metadata.GUID ?? string.Empty) : string.Empty);
string text4 = (text + " " + text2 + " " + text3).ToLowerInvariant();
if (text4.Contains("rtlc.gwyf") || text4.Contains("russian") || text4.Contains("рус"))
{
return true;
}
}
}
catch
{
}
try
{
if (Directory.Exists(Path.Combine(Paths.PluginPath, "RTLC-GWYF_Russian_Translation")))
{
return true;
}
if (File.Exists(Path.Combine(Paths.ConfigPath, "Translation", "ru", "Text", "Translate.txt")))
{
return true;
}
}
catch
{
}
return false;
}
private bool PatchMethod(string typeName, string methodName, string prefixName, string postfixName)
{
//IL_0093: Unknown result type (might be due to invalid IL or missing references)
//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
try
{
Type type = AccessTools.TypeByName(typeName);
if (type == null)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not find type " + typeName + ". This patch will be skipped."));
return false;
}
MethodInfo methodInfo = AccessTools.Method(type, methodName, (Type[])null, (Type[])null);
if (methodInfo == null)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not find method " + typeName + "." + methodName + ". This patch will be skipped."));
return false;
}
HarmonyMethod val = ((prefixName == null) ? ((HarmonyMethod)null) : new HarmonyMethod(typeof(Plugin), prefixName, (Type[])null));
HarmonyMethod val2 = ((postfixName == null) ? ((HarmonyMethod)null) : new HarmonyMethod(typeof(Plugin), postfixName, (Type[])null));
harmony.Patch((MethodBase)methodInfo, val, val2, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
return true;
}
catch (Exception ex)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)("Failed to patch " + typeName + "." + methodName + ": " + ex.Message));
return false;
}
}
private int PatchGraphicsCopyTextureMethods()
{
return 0 + (PatchGraphicsCopyTextureMethod(new Type[2]
{
typeof(Texture),
typeof(Texture)
}, "PatchGraphicsCopyTexture") ? 1 : 0) + (PatchGraphicsCopyTextureMethod(new Type[4]
{
typeof(Texture),
typeof(int),
typeof(Texture),
typeof(int)
}, "PatchGraphicsCopyTextureElement") ? 1 : 0);
}
private bool PatchGraphicsCopyTextureMethod(Type[] parameterTypes, string prefixName)
{
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_0055: Expected O, but got Unknown
try
{
MethodInfo methodInfo = AccessTools.Method(typeof(Graphics), "CopyTexture", parameterTypes, (Type[])null);
if (methodInfo == null)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)"Could not find UnityEngine.Graphics.CopyTexture overload. RTLC texture copy fix will be skipped for this overload.");
return false;
}
harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(Plugin), prefixName, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
return true;
}
catch (Exception ex)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)("Failed to patch UnityEngine.Graphics.CopyTexture: " + ex.Message));
return false;
}
}
private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
PrepareTextureCopyWindow();
ApplyGraphicsSettings(applyTextureLimit: false);
QueueDeferredTextureLimit();
}
private void OnActiveSceneChanged(Scene oldScene, Scene newScene)
{
PrepareTextureCopyWindow();
ApplyGraphicsSettings(applyTextureLimit: false);
QueueDeferredTextureLimit();
}
private void OnApplicationFocus(bool hasFocus)
{
gameHasFocus = hasFocus;
ApplyGraphicsSettings(applyTextureLimit: false);
}
private void OnApplicationPause(bool pauseStatus)
{
gamePaused = pauseStatus;
ApplyGraphicsSettings(applyTextureLimit: false);
}
public static void ApplyPreset(int presetIndex)
{
presetIndex = ClampOption(presetIndex, 0, 5);
switch (presetIndex)
{
case 1:
ConfigRenderScale.Value = 0;
ConfigTextureResolution.Value = 3;
ConfigShadows.Value = 0;
ConfigAntiAliasing.Value = 0;
ConfigTargetFPS.Value = 1;
ConfigLodBias.Value = 0;
ConfigAnisotropicFiltering.Value = 0;
ConfigReflectionProbes.Value = 0;
ConfigSoftParticles.Value = 0;
ConfigVSync.Value = 0;
break;
case 2:
ConfigRenderScale.Value = 2;
ConfigTextureResolution.Value = 2;
ConfigShadows.Value = 0;
ConfigAntiAliasing.Value = 0;
ConfigTargetFPS.Value = 2;
ConfigLodBias.Value = 1;
ConfigAnisotropicFiltering.Value = 0;
ConfigReflectionProbes.Value = 0;
ConfigSoftParticles.Value = 0;
ConfigVSync.Value = 0;
break;
case 3:
ConfigRenderScale.Value = 4;
ConfigTextureResolution.Value = 1;
ConfigShadows.Value = 1;
ConfigAntiAliasing.Value = 1;
ConfigTargetFPS.Value = 2;
ConfigLodBias.Value = 2;
ConfigAnisotropicFiltering.Value = 1;
ConfigReflectionProbes.Value = 0;
ConfigSoftParticles.Value = 0;
ConfigVSync.Value = 0;
break;
case 4:
ConfigRenderScale.Value = 4;
ConfigTextureResolution.Value = 0;
ConfigShadows.Value = 2;
ConfigAntiAliasing.Value = 2;
ConfigTargetFPS.Value = 4;
ConfigLodBias.Value = 2;
ConfigAnisotropicFiltering.Value = 1;
ConfigReflectionProbes.Value = 1;
ConfigSoftParticles.Value = 1;
ConfigVSync.Value = 0;
break;
case 5:
ConfigRenderScale.Value = 4;
ConfigTextureResolution.Value = 0;
ConfigShadows.Value = 2;
ConfigAntiAliasing.Value = 3;
ConfigTargetFPS.Value = 0;
ConfigLodBias.Value = 3;
ConfigAnisotropicFiltering.Value = 2;
ConfigReflectionProbes.Value = 1;
ConfigSoftParticles.Value = 1;
ConfigVSync.Value = 0;
break;
}
}
public static void ApplyGraphicsSettings()
{
ApplyGraphicsSettings(applyTextureLimit: true, forceTextureLimit: true);
}
private static void ApplyGraphicsSettings(bool applyTextureLimit, bool forceTextureLimit = false)
{
if (ConfigRenderScale != null)
{
if (applyTextureLimit)
{
ApplyTextureLimit(forceTextureLimit);
}
ApplyUnityQualitySettings();
ApplyRenderPipelineSettings();
}
}
private static void ApplyUnityQualitySettings()
{
if (IsBackgroundFpsCapActive())
{
QualitySettings.vSyncCount = 0;
Application.targetFrameRate = 10;
}
else
{
QualitySettings.vSyncCount = ClampOption(ConfigVSync.Value, 0, 1);
Application.targetFrameRate = TargetFpsValues[ClampOption(ConfigTargetFPS.Value, 0, TargetFpsValues.Length - 1)];
}
switch (ClampOption(ConfigShadows.Value, 0, 2))
{
case 0:
QualitySettings.shadows = (ShadowQuality)0;
QualitySettings.shadowCascades = 0;
QualitySettings.shadowDistance = 0f;
break;
case 1:
QualitySettings.shadows = (ShadowQuality)1;
QualitySettings.shadowCascades = 1;
QualitySettings.shadowDistance = 75f;
break;
default:
QualitySettings.shadows = (ShadowQuality)2;
QualitySettings.shadowCascades = 4;
QualitySettings.shadowDistance = 150f;
break;
}
QualitySettings.antiAliasing = QualityAntiAliasingLevels[ClampOption(ConfigAntiAliasing.Value, 0, QualityAntiAliasingLevels.Length - 1)];
QualitySettings.lodBias = LodBiasValues[ClampOption(ConfigLodBias.Value, 0, LodBiasValues.Length - 1)];
QualitySettings.anisotropicFiltering = (AnisotropicFiltering)ClampOption(ConfigAnisotropicFiltering.Value, 0, 2);
QualitySettings.realtimeReflectionProbes = ConfigReflectionProbes.Value == 1;
QualitySettings.softParticles = ConfigSoftParticles.Value == 1;
}
private static bool IsBackgroundFpsCapActive()
{
if (ConfigBackgroundFpsLimit != null && ConfigBackgroundFpsLimit.Value == 1)
{
if (gameHasFocus)
{
return gamePaused;
}
return true;
}
return false;
}
private static void ApplyRenderPipelineSettings()
{
RenderPipelineAsset val = GraphicsSettings.currentRenderPipeline ?? QualitySettings.renderPipeline;
if (!((Object)(object)val == (Object)null))
{
Type type = ((object)val).GetType();
float num = RenderScales[ClampOption(ConfigRenderScale.Value, 0, RenderScales.Length - 1)];
TrySetProperty(type, val, "renderScale", num);
switch (ClampOption(ConfigShadows.Value, 0, 2))
{
case 0:
TrySetProperty(type, val, "shadowDistance", 0f);
TrySetProperty(type, val, "shadowCascadeCount", 0);
break;
case 1:
TrySetProperty(type, val, "shadowDistance", 75f);
TrySetProperty(type, val, "shadowCascadeCount", 1);
break;
default:
TrySetProperty(type, val, "shadowDistance", 150f);
TrySetProperty(type, val, "shadowCascadeCount", 4);
break;
}
int num2 = UrpMsaaSampleCounts[ClampOption(ConfigAntiAliasing.Value, 0, UrpMsaaSampleCounts.Length - 1)];
TrySetProperty(type, val, "msaaSampleCount", num2);
}
}
private static void ApplyTextureLimit(bool force = false)
{
if (ConfigTextureResolution != null && (force || !(Time.realtimeSinceStartup < nextTextureLimitApplyTime)))
{
QualitySettings.globalTextureMipmapLimit = ClampOption(ConfigTextureResolution.Value, 0, 3);
}
}
private static void PrepareTextureCopyWindow()
{
if (ConfigTextureResolution != null)
{
float num = ((ConfigTextureLimitDelay == null) ? 1.75f : Mathf.Clamp(ConfigTextureLimitDelay.Value, 0f, 5f));
nextTextureLimitApplyTime = Time.realtimeSinceStartup + num;
if (ConfigTextureResolution.Value > 0)
{
QualitySettings.globalTextureMipmapLimit = 0;
}
}
}
private static void QueueDeferredTextureLimit()
{
if ((Object)(object)Instance == (Object)null)
{
ApplyTextureLimit(force: true);
}
else
{
Instance.QueueDeferredTextureLimitInstance();
}
}
private void QueueDeferredTextureLimitInstance()
{
if (textureLimitRoutine != null)
{
((MonoBehaviour)this).StopCoroutine(textureLimitRoutine);
}
textureLimitRoutine = ((MonoBehaviour)this).StartCoroutine(ApplyTextureLimitAfterDelay());
}
private IEnumerator ApplyTextureLimitAfterDelay()
{
float num = ((ConfigTextureLimitDelay == null) ? 1.75f : Mathf.Clamp(ConfigTextureLimitDelay.Value, 0f, 5f));
if (num > 0f)
{
yield return (object)new WaitForSecondsRealtime(num);
}
float duration = ((ConfigTextureLimitEnforcementDuration == null) ? 10f : Mathf.Clamp(ConfigTextureLimitEnforcementDuration.Value, 0f, 30f));
float endTime = Time.realtimeSinceStartup + duration;
while (true)
{
ApplyGraphicsSettings(applyTextureLimit: true, forceTextureLimit: true);
if (duration <= 0f || Time.realtimeSinceStartup >= endTime)
{
break;
}
yield return (object)new WaitForSecondsRealtime(0.5f);
}
textureLimitRoutine = null;
}
private void StartContinuousQualityEnforcer()
{
if (continuousQualityRoutine != null)
{
((MonoBehaviour)this).StopCoroutine(continuousQualityRoutine);
}
continuousQualityRoutine = ((MonoBehaviour)this).StartCoroutine(ContinuousQualityEnforcer());
}
private IEnumerator ContinuousQualityEnforcer()
{
while (true)
{
yield return (object)new WaitForSecondsRealtime(1f);
if (ConfigContinuousQualityEnforcement != null && ConfigContinuousQualityEnforcement.Value == 1)
{
ApplyGraphicsSettings(applyTextureLimit: true);
}
}
}
private static void PatchGraphicsSettingsApplier_ApplyAll()
{
ApplyGraphicsSettings(applyTextureLimit: false);
QueueDeferredTextureLimit();
}
private static bool PatchOutlineSmoothNormals(Mesh mesh, ref List<Vector3> __result)
{
if ((Object)(object)mesh != (Object)null)
{
return true;
}
__result = new List<Vector3>();
return false;
}
private static bool PatchGraphicsCopyTexture(Texture src, Texture dst)
{
return !TryHandleMismatchedTextureCopy(src, dst, -1, -1);
}
private static bool PatchGraphicsCopyTextureElement(Texture src, int srcElement, Texture dst, int dstElement)
{
return !TryHandleMismatchedTextureCopy(src, dst, srcElement, dstElement);
}
private static bool TryHandleMismatchedTextureCopy(Texture src, Texture dst, int srcElement, int dstElement)
{
//IL_0098: Unknown result type (might be due to invalid IL or missing references)
//IL_009e: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0074: Unknown result type (might be due to invalid IL or missing references)
//IL_007a: Unknown result type (might be due to invalid IL or missing references)
if (ConfigRtlcTextureCopyFix == null || ConfigRtlcTextureCopyFix.Value != 1)
{
return false;
}
if ((Object)(object)src == (Object)null || (Object)(object)dst == (Object)null || src.dimension != dst.dimension)
{
return false;
}
if (src.mipmapCount == dst.mipmapCount && src.width == dst.width && src.height == dst.height)
{
return false;
}
if (textureCopyFallbackInProgress)
{
return false;
}
textureCopyFallbackInProgress = true;
try
{
if (src.graphicsFormat != dst.graphicsFormat)
{
Texture2D val = (Texture2D)(object)((src is Texture2D) ? src : null);
if (val != null)
{
try
{
val.Compress(true);
}
catch
{
}
}
}
if (src.graphicsFormat != dst.graphicsFormat)
{
return false;
}
int num = 0;
int num2 = src.width;
int num3 = src.height;
while ((num2 > dst.width || num3 > dst.height) && num < src.mipmapCount - 1)
{
num2 = Mathf.Max(1, num2 / 2);
num3 = Mathf.Max(1, num3 / 2);
num++;
}
if (num2 == dst.width && num3 == dst.height)
{
int num4 = Mathf.Min(src.mipmapCount - num, dst.mipmapCount);
for (int i = 0; i < num4; i++)
{
if (srcElement >= 0)
{
Graphics.CopyTexture(src, srcElement, num + i, dst, dstElement, i);
}
else
{
Graphics.CopyTexture(src, 0, num + i, dst, 0, i);
}
}
LogTextureCopyFix(src, dst);
return true;
}
return false;
}
catch (Exception ex)
{
if (textureCopyFixLogCount < 5)
{
LogWarning("RTLC texture copy fix failed for " + GetTextureName(src) + " -> " + GetTextureName(dst) + ": " + ex.Message);
}
textureCopyFixLogCount++;
return false;
}
finally
{
textureCopyFallbackInProgress = false;
}
}
private static void LogTextureCopyFix(Texture src, Texture dst)
{
if (textureCopyFixLogCount < 5)
{
LogInfo($"RTLC texture copy fix handled mipmap mismatch for {GetTextureName(src)} -> {GetTextureName(dst)} (src mips {src.mipmapCount}, dst mips {dst.mipmapCount}).");
}
textureCopyFixLogCount++;
}
private static string GetTextureName(Texture texture)
{
if ((Object)(object)texture == (Object)null)
{
return "<null>";
}
if (!string.IsNullOrEmpty(((Object)texture).name))
{
return ((Object)texture).name;
}
return ((object)texture).GetType().Name;
}
private static void PatchSettingsLayoutAwake(object __instance)
{
try
{
if (!(GetFieldValue(GetFieldValue(__instance, "layout"), "tabs") is IList tabs))
{
return;
}
object obj = FindGraphicsTab(tabs);
if (obj == null || !(GetFieldValue(obj, "entries") is IList list) || ContainsModEntry(list, "ModGraphicsPreset"))
{
return;
}
List<ScriptableObject> list2 = new List<ScriptableObject>
{
CreateDropdown("ModGraphicsPreset", GetSettingLabel("ModGraphicsPreset"), GetSettingOptionsList("ModGraphicsPreset"), ConfigGraphicsPreset.Value),
CreateDropdown("ModRenderScale", GetSettingLabel("ModRenderScale"), GetSettingOptionsList("ModRenderScale"), ConfigRenderScale.Value),
CreateDropdown("ModTextureResolution", GetSettingLabel("ModTextureResolution"), GetSettingOptionsList("ModTextureResolution"), ConfigTextureResolution.Value),
CreateDropdown("ModShadows", GetSettingLabel("ModShadows"), GetSettingOptionsList("ModShadows"), ConfigShadows.Value),
CreateDropdown("ModAntiAliasing", GetSettingLabel("ModAntiAliasing"), GetSettingOptionsList("ModAntiAliasing"), ConfigAntiAliasing.Value),
CreateDropdown("ModVSync", GetSettingLabel("ModVSync"), GetSettingOptionsList("ModVSync"), ConfigVSync.Value),
CreateDropdown("ModTargetFPS", GetSettingLabel("ModTargetFPS"), GetSettingOptionsList("ModTargetFPS"), ConfigTargetFPS.Value),
CreateDropdown("ModLodBias", GetSettingLabel("ModLodBias"), GetSettingOptionsList("ModLodBias"), ConfigLodBias.Value),
CreateDropdown("ModAnisotropicFiltering", GetSettingLabel("ModAnisotropicFiltering"), GetSettingOptionsList("ModAnisotropicFiltering"), ConfigAnisotropicFiltering.Value),
CreateDropdown("ModReflectionProbes", GetSettingLabel("ModReflectionProbes"), GetSettingOptionsList("ModReflectionProbes"), ConfigReflectionProbes.Value),
CreateDropdown("ModSoftParticles", GetSettingLabel("ModSoftParticles"), GetSettingOptionsList("ModSoftParticles"), ConfigSoftParticles.Value),
CreateDropdown("ModBackgroundFpsLimit", GetSettingLabel("ModBackgroundFpsLimit"), GetSettingOptionsList("ModBackgroundFpsLimit"), ConfigBackgroundFpsLimit.Value)
};
for (int num = list2.Count - 1; num >= 0; num--)
{
if ((Object)(object)list2[num] != (Object)null)
{
list.Insert(0, list2[num]);
}
}
}
catch (Exception ex)
{
LogWarning("Failed to extend the Graphics settings UI: " + ex.Message);
}
}
private static object FindGraphicsTab(IList tabs)
{
foreach (object tab in tabs)
{
if (string.Equals(GetFieldValue(tab, "tabName") as string, "Graphics", StringComparison.OrdinalIgnoreCase))
{
return tab;
}
}
return null;
}
private static bool ContainsModEntry(IList entries, string key)
{
foreach (object entry in entries)
{
ScriptableObject val = (ScriptableObject)((entry is ScriptableObject) ? entry : null);
if ((Object)(object)val != (Object)null && ((Object)val).name == key)
{
return true;
}
}
return false;
}
private static ScriptableObject CreateDropdown(string key, string label, List<string> options, int defaultIndex)
{
try
{
Type type = AccessTools.TypeByName("DropdownSettingItem");
if (type == null)
{
LogWarning("Could not find DropdownSettingItem. More Optimization settings will not be shown in the menu.");
return null;
}
ScriptableObject obj = ScriptableObject.CreateInstance(type);
((Object)obj).name = key;
TrySetField(obj, "key", key);
TrySetField(obj, "label", label);
TrySetField(obj, "options", options);
TrySetField(obj, "index", defaultIndex);
return obj;
}
catch (Exception ex)
{
LogWarning("Failed to create dropdown " + key + ": " + ex.Message);
return null;
}
}
private static void PatchNotifyChanged(object __instance)
{
try
{
if (syncingSettingsUi || !(GetFieldValue(__instance, "tabs") is IList tabs))
{
return;
}
Dictionary<string, ScriptableObject> dictionary = CollectModItems(tabs);
if (dictionary.Count == 0)
{
return;
}
bool flag = false;
bool flag2 = false;
if (TryGetDropdownIndex(dictionary, "ModGraphicsPreset", out var index))
{
index = ClampOption(index, 0, 5);
if (index != ConfigGraphicsPreset.Value)
{
ConfigGraphicsPreset.Value = index;
flag = true;
if (index != 0)
{
ApplyPreset(index);
SyncDropdownsFromConfig(dictionary);
RefreshVisibleSettingsUi(dictionary);
flag2 = true;
}
}
}
if (!flag2)
{
int num = (int)(0u | (UpdateConfigFromDropdown(dictionary, "ModRenderScale", ConfigRenderScale, 0, 4) ? 1u : 0u) | (UpdateConfigFromDropdown(dictionary, "ModTextureResolution", ConfigTextureResolution, 0, 3) ? 1u : 0u) | (UpdateConfigFromDropdown(dictionary, "ModShadows", ConfigShadows, 0, 2) ? 1u : 0u) | (UpdateConfigFromDropdown(dictionary, "ModAntiAliasing", ConfigAntiAliasing, 0, 3) ? 1u : 0u) | (UpdateConfigFromDropdown(dictionary, "ModVSync", ConfigVSync, 0, 1) ? 1u : 0u) | (UpdateConfigFromDropdown(dictionary, "ModTargetFPS", ConfigTargetFPS, 0, 4) ? 1u : 0u) | (UpdateConfigFromDropdown(dictionary, "ModLodBias", ConfigLodBias, 0, 3) ? 1u : 0u) | (UpdateConfigFromDropdown(dictionary, "ModAnisotropicFiltering", ConfigAnisotropicFiltering, 0, 2) ? 1u : 0u) | (UpdateConfigFromDropdown(dictionary, "ModReflectionProbes", ConfigReflectionProbes, 0, 1) ? 1u : 0u)) | (UpdateConfigFromDropdown(dictionary, "ModSoftParticles", ConfigSoftParticles, 0, 1) ? 1 : 0);
bool flag3 = UpdateConfigFromDropdown(dictionary, "ModBackgroundFpsLimit", ConfigBackgroundFpsLimit, 0, 1);
if (num != 0)
{
ConfigGraphicsPreset.Value = 0;
SetDropdownIndex(dictionary, "ModGraphicsPreset", 0);
RefreshVisibleSettingsUi(dictionary);
flag = true;
}
if (flag3)
{
flag = true;
}
}
if (flag)
{
ApplyGraphicsSettings(applyTextureLimit: true, forceTextureLimit: true);
QueueDeferredTextureLimit();
SaveConfigFile();
}
}
catch (Exception ex)
{
LogWarning("Failed to process Graphics settings change: " + ex.Message);
}
}
private static Dictionary<string, ScriptableObject> CollectModItems(IList tabs)
{
Dictionary<string, ScriptableObject> dictionary = new Dictionary<string, ScriptableObject>();
foreach (object tab in tabs)
{
if (!(GetFieldValue(tab, "entries") is IList list))
{
continue;
}
foreach (object item in list)
{
ScriptableObject val = (ScriptableObject)((item is ScriptableObject) ? item : null);
if ((Object)(object)val != (Object)null && ((Object)val).name.StartsWith("Mod", StringComparison.Ordinal))
{
dictionary[((Object)val).name] = val;
}
}
}
return dictionary;
}
private static bool UpdateConfigFromDropdown(Dictionary<string, ScriptableObject> modItems, string key, ConfigEntry<int> config, int min, int max)
{
if (!TryGetDropdownIndex(modItems, key, out var index))
{
return false;
}
index = ClampOption(index, min, max);
if (config.Value == index)
{
return false;
}
config.Value = index;
return true;
}
private static void SyncDropdownsFromConfig(Dictionary<string, ScriptableObject> modItems)
{
SetDropdownIndex(modItems, "ModGraphicsPreset", ConfigGraphicsPreset.Value);
SetDropdownIndex(modItems, "ModRenderScale", ConfigRenderScale.Value);
SetDropdownIndex(modItems, "ModTextureResolution", ConfigTextureResolution.Value);
SetDropdownIndex(modItems, "ModShadows", ConfigShadows.Value);
SetDropdownIndex(modItems, "ModAntiAliasing", ConfigAntiAliasing.Value);
SetDropdownIndex(modItems, "ModVSync", ConfigVSync.Value);
SetDropdownIndex(modItems, "ModTargetFPS", ConfigTargetFPS.Value);
SetDropdownIndex(modItems, "ModLodBias", ConfigLodBias.Value);
SetDropdownIndex(modItems, "ModAnisotropicFiltering", ConfigAnisotropicFiltering.Value);
SetDropdownIndex(modItems, "ModReflectionProbes", ConfigReflectionProbes.Value);
SetDropdownIndex(modItems, "ModSoftParticles", ConfigSoftParticles.Value);
SetDropdownIndex(modItems, "ModBackgroundFpsLimit", ConfigBackgroundFpsLimit.Value);
}
private static void RefreshVisibleSettingsUi(Dictionary<string, ScriptableObject> modItems)
{
if (syncingSettingsUi)
{
return;
}
syncingSettingsUi = true;
try
{
foreach (KeyValuePair<string, ScriptableObject> modItem in modItems)
{
if (TryGetDropdownIndex(modItems, modItem.Key, out var index))
{
string settingLabel = GetSettingLabel(modItem.Key);
string[] settingOptions = GetSettingOptions(modItem.Key);
if (settingLabel != null && settingOptions != null)
{
RefreshLiveDropdown(settingLabel, settingOptions, index);
}
}
}
}
finally
{
syncingSettingsUi = false;
}
}
private static string GetSettingLabel(string key)
{
return key switch
{
"ModGraphicsPreset" => T("Quality Preset", "Пресет качества"),
"ModRenderScale" => T("Render Scale", "Масштаб рендера"),
"ModTextureResolution" => T("Texture Resolution", "Разрешение текстур"),
"ModShadows" => T("Shadows", "Тени"),
"ModAntiAliasing" => T("Anti-Aliasing", "Сглаживание"),
"ModVSync" => "VSync",
"ModTargetFPS" => T("Target FPS", "Лимит FPS"),
"ModLodBias" => T("LOD Bias", "Дальность LOD"),
"ModAnisotropicFiltering" => T("Anisotropic", "Анизотропия"),
"ModReflectionProbes" => T("Reflections", "Отражения"),
"ModSoftParticles" => T("Soft Particles", "Мягкие частицы"),
"ModBackgroundFpsLimit" => T("Background FPS", "FPS в фоне"),
_ => null,
};
}
private static List<string> GetSettingOptionsList(string key)
{
string[] settingOptions = GetSettingOptions(key);
if (settingOptions != null)
{
return new List<string>(settingOptions);
}
return new List<string>();
}
private static string[] GetSettingOptions(string key)
{
switch (key)
{
case "ModGraphicsPreset":
if (useRussianText)
{
return new string[6] { "Свои", "Картошка", "Низкие", "Средние", "Высокие", "Ультра" };
}
return new string[6] { "Custom", "Potato", "Low", "Medium", "High", "Ultra" };
case "ModRenderScale":
return new string[5] { "50%", "60%", "75%", "90%", "100%" };
case "ModTextureResolution":
if (useRussianText)
{
return new string[4] { "Полное", "Половина", "Четверть", "Восьмая" };
}
return new string[4] { "Full Res", "Half Res", "Quarter Res", "Eighth Res" };
case "ModShadows":
if (useRussianText)
{
return new string[3] { "Выкл", "Только жесткие", "Все" };
}
return new string[3] { "Off", "Hard Only", "All" };
case "ModAntiAliasing":
if (useRussianText)
{
return new string[4] { "Выкл", "2x", "4x", "8x" };
}
return new string[4] { "Off", "2x", "4x", "8x" };
case "ModVSync":
if (useRussianText)
{
return new string[2] { "Выкл", "Вкл" };
}
return new string[2] { "Off", "On" };
case "ModTargetFPS":
if (useRussianText)
{
return new string[5] { "Без лимита", "30", "60", "120", "144" };
}
return new string[5] { "Uncapped", "30", "60", "120", "144" };
case "ModLodBias":
if (useRussianText)
{
return new string[4] { "Низкая", "Баланс", "Обычная", "Высокая" };
}
return new string[4] { "Low", "Balanced", "Default", "High" };
case "ModAnisotropicFiltering":
if (useRussianText)
{
return new string[3] { "Выкл", "Вкл", "Принудительно" };
}
return new string[3] { "Off", "On", "Forced" };
case "ModReflectionProbes":
if (useRussianText)
{
return new string[2] { "Выкл", "Вкл" };
}
return new string[2] { "Off", "On" };
case "ModSoftParticles":
if (useRussianText)
{
return new string[2] { "Выкл", "Вкл" };
}
return new string[2] { "Off", "On" };
case "ModBackgroundFpsLimit":
if (useRussianText)
{
return new string[2] { "Выкл", "10 FPS" };
}
return new string[2] { "Off", "10 FPS" };
default:
return null;
}
}
private static string T(string english, string russian)
{
if (!useRussianText)
{
return english;
}
return russian;
}
private static void RefreshLiveDropdown(string label, string[] expectedOptions, int index)
{
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
Component[] array = Resources.FindObjectsOfTypeAll<Component>();
foreach (Component val in array)
{
if ((Object)(object)val == (Object)null || (Object)(object)val.gameObject == (Object)null)
{
continue;
}
Scene scene = val.gameObject.scene;
if (((Scene)(ref scene)).IsValid())
{
string fullName = ((object)val).GetType().FullName;
if (fullName != null && fullName.IndexOf("Dropdown", StringComparison.OrdinalIgnoreCase) >= 0 && DropdownOptionsMatch(val, expectedOptions) && (expectedOptions.Length > 2 || HierarchyContainsText(val.transform, label)))
{
SetLiveDropdownValue(val, index);
}
}
}
}
private static bool DropdownOptionsMatch(object dropdown, string[] expectedOptions)
{
if (!(GetMemberValue(dropdown, "options") is IEnumerable enumerable))
{
return false;
}
List<string> list = new List<string>();
foreach (object item2 in enumerable)
{
if (GetMemberValue(item2, "text") is string item)
{
list.Add(item);
}
}
if (list.Count != expectedOptions.Length)
{
return false;
}
for (int i = 0; i < expectedOptions.Length; i++)
{
if (!string.Equals(NormalizeUiText(list[i]), NormalizeUiText(expectedOptions[i]), StringComparison.Ordinal))
{
return false;
}
}
return true;
}
private static bool HierarchyContainsText(Transform transform, string expectedText)
{
string normalizedExpected = NormalizeUiText(expectedText);
Transform val = transform;
int num = 0;
while ((Object)(object)val != (Object)null && num < 5)
{
if (TransformContainsText(val, normalizedExpected))
{
return true;
}
val = val.parent;
num++;
}
return false;
}
private static bool TransformContainsText(Transform root, string normalizedExpected)
{
Component[] componentsInChildren = ((Component)root).GetComponentsInChildren<Component>(true);
foreach (Component val in componentsInChildren)
{
if (!((Object)(object)val == (Object)null) && GetMemberValue(val, "text") is string value && string.Equals(NormalizeUiText(value), normalizedExpected, StringComparison.Ordinal))
{
return true;
}
}
return false;
}
private static void SetLiveDropdownValue(object dropdown, int index)
{
if (!TryInvokeMethod(dropdown, "SetValueWithoutNotify", new object[1] { index }))
{
TrySetProperty(dropdown, "value", index);
}
TryInvokeMethod(dropdown, "RefreshShownValue", new object[0]);
}
private static bool TryGetDropdownIndex(Dictionary<string, ScriptableObject> modItems, string key, out int index)
{
index = 0;
if (!modItems.TryGetValue(key, out var value) || (Object)(object)value == (Object)null)
{
return false;
}
object fieldValue = GetFieldValue(value, "index");
if (fieldValue is int)
{
index = (int)fieldValue;
return true;
}
return false;
}
private static void SetDropdownIndex(Dictionary<string, ScriptableObject> modItems, string key, int index)
{
if (modItems.TryGetValue(key, out var value) && (Object)(object)value != (Object)null)
{
TrySetField(value, "index", index);
}
}
private static object GetFieldValue(object target, string fieldName)
{
if (target == null)
{
return null;
}
try
{
FieldInfo fieldInfo = AccessTools.Field(target.GetType(), fieldName);
return (fieldInfo == null) ? null : fieldInfo.GetValue(target);
}
catch
{
return null;
}
}
private static object GetMemberValue(object target, string memberName)
{
if (target == null)
{
return null;
}
try
{
Type type = target.GetType();
PropertyInfo property = type.GetProperty(memberName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (property != null)
{
return property.GetValue(target, null);
}
FieldInfo field = type.GetField(memberName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
return (field == null) ? null : field.GetValue(target);
}
catch
{
return null;
}
}
private static bool TrySetField(object target, string fieldName, object value)
{
if (target == null)
{
return false;
}
try
{
FieldInfo fieldInfo = AccessTools.Field(target.GetType(), fieldName);
if (fieldInfo == null)
{
return false;
}
fieldInfo.SetValue(target, value);
return true;
}
catch
{
return false;
}
}
private static bool TrySetProperty(object target, string propertyName, object value)
{
if (target == null)
{
return false;
}
return TrySetProperty(target.GetType(), target, propertyName, value);
}
private static bool TrySetProperty(Type type, object target, string propertyName, object value)
{
try
{
PropertyInfo property = type.GetProperty(propertyName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (property == null)
{
return false;
}
property.SetValue(target, value, null);
return true;
}
catch
{
return false;
}
}
private static bool TryInvokeMethod(object target, string methodName, object[] args)
{
if (target == null)
{
return false;
}
try
{
Type[] array;
if (args == null || args.Length == 0)
{
array = Type.EmptyTypes;
args = new object[0];
}
else
{
array = new Type[args.Length];
for (int i = 0; i < args.Length; i++)
{
array[i] = args[i].GetType();
}
}
Type type = target.GetType();
MethodInfo methodInfo = type.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, array, null);
if (methodInfo == null)
{
MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
for (int j = 0; j < methods.Length; j++)
{
if (methods[j].Name == methodName && methods[j].GetParameters().Length == args.Length)
{
methodInfo = methods[j];
break;
}
}
}
if (methodInfo == null)
{
return false;
}
methodInfo.Invoke(target, args);
return true;
}
catch
{
return false;
}
}
private static string NormalizeUiText(string value)
{
if (value == null)
{
return string.Empty;
}
return value.Trim().Replace(" ", string.Empty).Replace("-", string.Empty)
.Replace("_", string.Empty)
.ToLowerInvariant();
}
private static int ClampOption(int value, int min, int max)
{
return Mathf.Clamp(value, min, max);
}
private static void SaveConfigFile()
{
if ((Object)(object)Instance == (Object)null)
{
return;
}
try
{
((BaseUnityPlugin)Instance).Config.Save();
}
catch (Exception ex)
{
LogWarning("Failed to save config: " + ex.Message);
}
}
private static void LogWarning(string message)
{
if ((Object)(object)Instance != (Object)null)
{
((BaseUnityPlugin)Instance).Logger.LogWarning((object)message);
}
}
private static void LogInfo(string message)
{
if ((Object)(object)Instance != (Object)null)
{
((BaseUnityPlugin)Instance).Logger.LogInfo((object)message);
}
}
}
}