Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of SADnothingleft v1.0.2
BepInEx/plugins/SADnaki-SADnothingleft/SADnothingleft.dll
Decompiled a day agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using REPOLib.Modules; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("SADnothingleft")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("SADnothingleft")] [assembly: AssemblyTitle("SADnothingleft")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.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 SADnothingleft { internal static class MyPluginInfo { public const string PLUGIN_GUID = "SADnothingleft"; public const string PLUGIN_NAME = "SAD Nothing Left"; public const string PLUGIN_VERSION = "1.0.2"; } [BepInPlugin("SADnothingleft", "SAD Nothing Left", "1.0.2")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { public static Plugin Instance { get; private set; } internal static ManualLogSource Log { get; private set; } internal static ConfigEntry<bool> CfgEnabled { get; private set; } internal static ConfigEntry<float> CfgCheckInterval { get; private set; } internal static ConfigEntry<int> CfgBufferMin { get; private set; } internal static ConfigEntry<int> CfgBufferMax { get; private set; } internal static ConfigEntry<int> CfgMaxSpawnCount { get; private set; } internal static ConfigEntry<bool> CfgSpawnNearExtraction { get; private set; } internal static ConfigEntry<float> CfgSpawnNearExtractionRadius { get; private set; } internal static ConfigEntry<bool> CfgVerboseLogging { get; private set; } private void Awake() { //IL_0126: Unknown result type (might be due to invalid IL or missing references) Instance = this; Log = ((BaseUnityPlugin)this).Logger; CfgEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Disable to turn the mod off without uninstalling."); CfgCheckInterval = ((BaseUnityPlugin)this).Config.Bind<float>("General", "CheckInterval", 60f, "Seconds between value checks."); CfgBufferMin = ((BaseUnityPlugin)this).Config.Bind<int>("Spawning", "BufferMin", 1000, "Min extra value to add on top of the quota gap."); CfgBufferMax = ((BaseUnityPlugin)this).Config.Bind<int>("Spawning", "BufferMax", 5000, "Max extra value to add on top of the quota gap."); CfgMaxSpawnCount = ((BaseUnityPlugin)this).Config.Bind<int>("Spawning", "MaxSpawnCount", 5, "Max number of valuables to spawn per check."); CfgSpawnNearExtraction = ((BaseUnityPlugin)this).Config.Bind<bool>("Spawning", "SpawnNearExtraction", true, "Limit spawn points to within SpawnNearExtractionRadius of the active extraction point."); CfgSpawnNearExtractionRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Spawning", "SpawnNearExtractionRadius", 100f, "Radius in meters. Only used when SpawnNearExtraction is true."); CfgVerboseLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "VerboseLogging", false, "Extra log output each check cycle."); try { new Harmony("SADnothingleft").PatchAll(); } catch (Exception arg) { Log.LogError((object)$"Harmony patching failed: {arg}"); } ((Component)this).gameObject.AddComponent<QuotaFiller>(); Log.LogInfo((object)"SAD Nothing Left v1.0.2 loaded."); } } public class QuotaFiller : MonoBehaviour { [CompilerGenerated] private sealed class <CheckLoop>d__9 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public QuotaFiller <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <CheckLoop>d__9(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown int num = <>1__state; QuotaFiller quotaFiller = <>4__this; if (num != 0) { if (num != 1) { return false; } <>1__state = -1; if (Plugin.CfgEnabled.Value && IsLevelReady()) { int instanceID = ((Object)LevelGenerator.Instance).GetInstanceID(); if (instanceID != quotaFiller._lastLevelInstanceId) { quotaFiller._lastLevelInstanceId = instanceID; if (Plugin.CfgVerboseLogging.Value) { Plugin.Log.LogDebug((object)"[SADnothingleft] New level detected, resetting state."); } } if (SemiFunc.IsMasterClientOrSingleplayer()) { quotaFiller.TryFillQuota(); } } } else { <>1__state = -1; } <>2__current = (object)new WaitForSeconds(Plugin.CfgCheckInterval.Value); <>1__state = 1; return true; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static readonly FieldRef<ValuableObject, float> _dollarValueOriginal = AccessTools.FieldRefAccess<ValuableObject, float>("dollarValueOriginal"); private static readonly FieldRef<ValuableObject, bool> _dollarValueSet = AccessTools.FieldRefAccess<ValuableObject, bool>("dollarValueSet"); private static readonly FieldRef<ExtractionPoint, int> _haulGoal = AccessTools.FieldRefAccess<ExtractionPoint, int>("haulGoal"); private static readonly FieldRef<ExtractionPoint, int> _haulCurrent = AccessTools.FieldRefAccess<ExtractionPoint, int>("haulCurrent"); private static readonly FieldRef<ExtractionPoint, bool> _haulGoalFetched = AccessTools.FieldRefAccess<ExtractionPoint, bool>("haulGoalFetched"); private static readonly FieldRef<ExtractionPoint, bool> _isShop = AccessTools.FieldRefAccess<ExtractionPoint, bool>("isShop"); private static readonly FieldRef<ExtractionPoint, State> _currentState = AccessTools.FieldRefAccess<ExtractionPoint, State>("currentState"); private int _lastLevelInstanceId = -1; private void Start() { ((MonoBehaviour)this).StartCoroutine(CheckLoop()); } [IteratorStateMachine(typeof(<CheckLoop>d__9))] private IEnumerator CheckLoop() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <CheckLoop>d__9(0) { <>4__this = this }; } private static bool IsLevelReady() { if ((Object)(object)RunManager.instance != (Object)null && (Object)(object)LevelGenerator.Instance != (Object)null && LevelGenerator.Instance.Generated && (Object)(object)ValuableDirector.instance != (Object)null && (Object)(object)Map.Instance != (Object)null) { return SemiFunc.RunIsLevel(); } return false; } private void TryFillQuota() { //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_020c: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Unknown result type (might be due to invalid IL or missing references) ValuableObject[] array = Object.FindObjectsOfType<ValuableObject>(false); float num = 0f; ValuableObject[] array2 = array; foreach (ValuableObject val in array2) { if (!((Object)(object)val == (Object)null) && ((Component)val).gameObject.activeInHierarchy && _dollarValueSet.Invoke(val)) { float num2 = _dollarValueOriginal.Invoke(val); if (num2 > 0f) { num += num2; } } } int remainingQuota = GetRemainingQuota(); if (Plugin.CfgVerboseLogging.Value) { Plugin.Log.LogDebug((object)$"[SADnothingleft] mapValue={num:F0} quota={remainingQuota}"); } if (remainingQuota <= 0) { return; } float num3 = (float)remainingQuota - num; if (num3 <= 0f) { return; } int num4 = Mathf.Max(0, Plugin.CfgBufferMin.Value); int num5 = Mathf.Max(num4, Plugin.CfgBufferMax.Value); float num6 = Random.Range(num4, num5); Plugin.Log.LogInfo((object)$"[SADnothingleft] gap={num3:F0} buffer={num6:F0}"); Vector3? extractionPos = GetActiveExtractionPosition(); List<LevelPoint> list = SemiFunc.LevelPointsGetAll(); if (list == null || list.Count == 0) { Plugin.Log.LogWarning((object)"[SADnothingleft] no LevelPoints on map"); return; } float radius = Plugin.CfgSpawnNearExtractionRadius.Value; if (Plugin.CfgSpawnNearExtraction.Value && extractionPos.HasValue && radius > 0f) { List<LevelPoint> list2 = list.FindAll((LevelPoint p) => Vector3.Distance(((Component)p).transform.position, extractionPos.Value) <= radius); if (list2.Count > 0) { list = list2; } } IReadOnlyList<PrefabRef> allValuables = Valuables.AllValuables; if (allValuables == null || allValuables.Count == 0) { Plugin.Log.LogWarning((object)"[SADnothingleft] AllValuables is empty"); return; } int num7 = Mathf.Max(1, Plugin.CfgMaxSpawnCount.Value); int num8 = 0; while (num8 < num7) { int index = Random.Range(0, list.Count); Vector3 position = ((Component)list[index]).transform.position; int index2 = Random.Range(0, allValuables.Count); PrefabRef val2 = allValuables[index2]; try { Valuables.SpawnValuable(val2, position, Quaternion.identity); num8++; if (Plugin.CfgVerboseLogging.Value) { Plugin.Log.LogDebug((object)$"[SADnothingleft] spawned #{num8} at {position}"); } } catch (Exception ex) { Plugin.Log.LogError((object)("[SADnothingleft] spawn failed: " + ex.Message)); break; } } Plugin.Log.LogInfo((object)$"[SADnothingleft] spawned {num8}"); } private Vector3? GetActiveExtractionPosition() { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Invalid comparison between Unknown and I4 //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Invalid comparison between Unknown and I4 ExtractionPoint[] array = Object.FindObjectsOfType<ExtractionPoint>(false); foreach (ExtractionPoint val in array) { if ((Object)(object)val == (Object)null || !((Component)val).gameObject.activeInHierarchy) { continue; } try { if (!_isShop.Invoke(val) && _haulGoalFetched.Invoke(val)) { State val2 = _currentState.Invoke(val); if ((int)val2 == 1 || (int)val2 == 2) { return ((Component)val).transform.position; } } } catch { } } return null; } private int GetRemainingQuota() { ExtractionPoint[] array = Object.FindObjectsOfType<ExtractionPoint>(false); int num = 0; bool flag = false; ExtractionPoint[] array2 = array; foreach (ExtractionPoint val in array2) { if ((Object)(object)val == (Object)null || !((Component)val).gameObject.activeInHierarchy) { continue; } try { bool num2 = _isShop.Invoke(val); bool flag2 = _haulGoalFetched.Invoke(val); if (!num2 && flag2) { int num3 = _haulGoal.Invoke(val); int num4 = _haulCurrent.Invoke(val); int num5 = Mathf.Max(0, num3 - num4); num += num5; flag = true; } } catch (Exception ex) { Plugin.Log.LogError((object)("[SADnothingleft] Error reading ExtractionPoint fields: " + ex.Message)); } } if (!flag && Plugin.CfgVerboseLogging.Value) { Plugin.Log.LogDebug((object)"[SADnothingleft] No valid ExtractionPoint found."); } return num; } } }