using System;
using System.Collections;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BoneLib.BoneMenu;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using LitePerf;
using MelonLoader;
using MelonLoader.Preferences;
using UnityEngine;
using UnityEngine.Scripting;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(Core), "LitePerf", "1.1.0", "Devonte", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: VerifyLoaderVersion(0, 6, 5, true)]
[assembly: MelonAdditionalDependencies(new string[] { "BoneLib" })]
[assembly: MelonPriority(1000)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("LitePerf")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("LitePerf")]
[assembly: AssemblyTitle("LitePerf")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace LitePerf;
public class Core : MelonMod
{
private MelonPreferences_Category cfg;
private MelonPreferences_Entry<bool> eIncrementalGC;
private MelonPreferences_Entry<bool> eSceneCleanup;
private MelonPreferences_Entry<bool> eLogSpam;
private MelonPreferences_Entry<bool> eAsyncUpload;
private MelonPreferences_Entry<bool> eParticleBudget;
private MelonPreferences_Entry<bool> eOcclusion;
private MelonPreferences_Entry<float> eCleanupDelay;
private bool hasBoneBoost;
private bool hasBoneFPS;
private bool hasFSR;
public override void OnInitializeMelon()
{
cfg = MelonPreferences.CreateCategory("LitePerf");
eIncrementalGC = cfg.CreateEntry<bool>("IncrementalGC", true, "Spread GC work over frames (kills GC spikes)", (string)null, false, false, (ValueValidator)null, (string)null);
eSceneCleanup = cfg.CreateEntry<bool>("SceneCleanup", true, "Free unused assets after level load (saves VRAM/RAM)", (string)null, false, false, (ValueValidator)null, (string)null);
eLogSpam = cfg.CreateEntry<bool>("CutLogSpam", true, "Turn off stack traces on logs (less CPU)", (string)null, false, false, (ValueValidator)null, (string)null);
eAsyncUpload = cfg.CreateEntry<bool>("AsyncUploadTuning", true, "Smoother texture/mesh uploads, fewer hitches", (string)null, false, false, (ValueValidator)null, (string)null);
eParticleBudget = cfg.CreateEntry<bool>("ParticleRaycastBudget", true, "Lower particle collision raycast budget", (string)null, false, false, (ValueValidator)null, (string)null);
eOcclusion = cfg.CreateEntry<bool>("OcclusionCulling", true, "Turn on camera occlusion culling", (string)null, false, false, (ValueValidator)null, (string)null);
eCleanupDelay = cfg.CreateEntry<float>("CleanupDelaySeconds", 4f, "Wait this long after scene load before cleanup", (string)null, false, false, (ValueValidator)null, (string)null);
DetectMods();
ApplyGC();
ApplyLogs();
ApplyAsyncUpload();
ApplyParticles();
BuildMenu();
((MelonBase)this).LoggerInstance.Msg("LitePerf loaded. BoneBoost=" + hasBoneBoost + " BoneFPS=" + hasBoneFPS + " BonelabFSR=" + hasFSR);
}
private void BuildMenu()
{
//IL_000a: 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_0044: Unknown result type (might be due to invalid IL or missing references)
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_0094: Unknown result type (might be due to invalid IL or missing references)
//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
//IL_010b: Unknown result type (might be due to invalid IL or missing references)
try
{
Page obj = Page.Root.CreatePage("LitePerf", Color.cyan, 0, true);
obj.CreateBool("Incremental GC", Color.white, eIncrementalGC.Value, (Action<bool>)delegate(bool v)
{
eIncrementalGC.Value = v;
Save();
if (v)
{
ApplyGC();
}
});
obj.CreateBool("Scene Cleanup", Color.white, eSceneCleanup.Value, (Action<bool>)delegate(bool v)
{
eSceneCleanup.Value = v;
Save();
});
obj.CreateBool("Cut Log Spam", Color.white, eLogSpam.Value, (Action<bool>)delegate(bool v)
{
eLogSpam.Value = v;
Save();
if (v)
{
ApplyLogs();
}
});
obj.CreateBool("Async Upload Tuning", Color.white, eAsyncUpload.Value, (Action<bool>)delegate(bool v)
{
eAsyncUpload.Value = v;
Save();
if (v)
{
ApplyAsyncUpload();
}
});
obj.CreateBool("Particle Raycast Budget", Color.white, eParticleBudget.Value, (Action<bool>)delegate(bool v)
{
eParticleBudget.Value = v;
Save();
if (v)
{
ApplyParticles();
}
});
obj.CreateBool("Occlusion Culling", Color.white, eOcclusion.Value, (Action<bool>)delegate(bool v)
{
eOcclusion.Value = v;
Save();
if (v)
{
ApplyOcclusion();
}
});
obj.CreateFloat("Cleanup Delay (s)", Color.yellow, eCleanupDelay.Value, 1f, 1f, 15f, (Action<float>)delegate(float v)
{
eCleanupDelay.Value = v;
Save();
});
}
catch (Exception ex)
{
((MelonBase)this).LoggerInstance.Warning("BoneMenu setup failed, using config file only: " + ex.Message);
}
}
private void Save()
{
try
{
MelonPreferences.Save();
}
catch
{
}
}
public override void OnSceneWasLoaded(int buildIndex, string sceneName)
{
ApplyOcclusion();
if (eSceneCleanup.Value)
{
MelonCoroutines.Start(CleanupRoutine());
}
}
private void DetectMods()
{
foreach (MelonMod registeredMelon in MelonTypeBase<MelonMod>.RegisteredMelons)
{
string text = (((MelonBase)registeredMelon).Info.Name ?? "").ToLowerInvariant();
if (text.Contains("boneboost"))
{
hasBoneBoost = true;
}
if (text.Contains("bonefps"))
{
hasBoneFPS = true;
}
if (text.Contains("bonelabfsr") || text.Contains("bonelab fsr") || text.Contains("fsr"))
{
hasFSR = true;
}
}
}
private void ApplyGC()
{
if (!eIncrementalGC.Value)
{
return;
}
try
{
GarbageCollector.GCMode = (Mode)1;
GarbageCollector.incrementalTimeSliceNanoseconds = 2000000uL;
}
catch (Exception ex)
{
((MelonBase)this).LoggerInstance.Warning("Incremental GC not available: " + ex.Message);
}
}
private void ApplyLogs()
{
if (!eLogSpam.Value)
{
return;
}
try
{
Application.SetStackTraceLogType((LogType)3, (StackTraceLogType)0);
Application.SetStackTraceLogType((LogType)2, (StackTraceLogType)0);
}
catch (Exception ex)
{
((MelonBase)this).LoggerInstance.Warning("Log tweak failed: " + ex.Message);
}
}
private void ApplyAsyncUpload()
{
if (!eAsyncUpload.Value)
{
return;
}
try
{
QualitySettings.asyncUploadTimeSlice = 2;
QualitySettings.asyncUploadBufferSize = 32;
QualitySettings.asyncUploadPersistentBuffer = true;
}
catch (Exception ex)
{
((MelonBase)this).LoggerInstance.Warning("Async upload tweak failed: " + ex.Message);
}
}
private void ApplyParticles()
{
if (!eParticleBudget.Value)
{
return;
}
try
{
QualitySettings.particleRaycastBudget = 256;
}
catch (Exception ex)
{
((MelonBase)this).LoggerInstance.Warning("Particle tweak failed: " + ex.Message);
}
}
private void ApplyOcclusion()
{
if (!eOcclusion.Value)
{
return;
}
try
{
foreach (Camera item in (Il2CppArrayBase<Camera>)(object)Camera.allCameras)
{
if ((Object)(object)item != (Object)null && ((Behaviour)item).enabled)
{
item.useOcclusionCulling = true;
}
}
}
catch (Exception ex)
{
((MelonBase)this).LoggerInstance.Warning("Occlusion tweak failed: " + ex.Message);
}
}
private IEnumerator CleanupRoutine()
{
yield return (object)new WaitForSeconds(Mathf.Max(1f, eCleanupDelay.Value));
try
{
Resources.UnloadUnusedAssets();
GC.Collect(0);
}
catch (Exception ex)
{
((MelonBase)this).LoggerInstance.Warning("Cleanup failed: " + ex.Message);
}
}
}