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 MinimumQuotaFinder v1.1.4
MinimumQuotaFinder.dll
Decompiled 2 years agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Threading; using BepInEx; using GameNetcodeStuff; using HarmonyLib; using LethalCompanyInputUtils.Api; using Microsoft.CodeAnalysis; using TMPro; using Unity.Netcode; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("MinimumQuotaFinder")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyDescription("Calculates and highlights the minimum total value of scraps to sell to reach the quota")] [assembly: AssemblyFileVersion("1.1.4.0")] [assembly: AssemblyInformationalVersion("1.1.4")] [assembly: AssemblyProduct("MinimumQuotaFinder")] [assembly: AssemblyTitle("MinimumQuotaFinder")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.1.4.0")] [module: UnverifiableCode] [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.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace MinimumQuotaFinder { [HarmonyPatch] internal class HUDPatch { [HarmonyPostfix] [HarmonyPatch(typeof(HUDManager), "Awake")] public static void OnAwake(HUDManager __instance) { int i; for (i = 0; i < __instance.controlTipLines.Length && ((TMP_Text)__instance.controlTipLines[i]).text != ""; i++) { } if (i < __instance.controlTipLines.Length) { ((TMP_Text)__instance.controlTipLines[i]).text = "Highlight Minimum Quota : [H]"; } } [HarmonyPostfix] [HarmonyPatch(typeof(HUDManager), "PingScan_performed")] public static void OnPing(HUDManager __instance, CallbackContext context) { if (!MinimumQuotaFinder.Instance.CanHighlight(displayReason: false)) { return; } int i; for (i = 0; i < __instance.controlTipLines.Length && ((TMP_Text)__instance.controlTipLines[i]).text != ""; i++) { if (((TMP_Text)__instance.controlTipLines[i]).text == "Highlight Minimum Quota : [H]") { return; } } if (i < __instance.controlTipLines.Length) { ((TMP_Text)__instance.controlTipLines[i]).text = "Highlight Minimum Quota : [H]"; } } [HarmonyPostfix] [HarmonyPatch(typeof(StartOfRound), "SceneManager_OnLoad")] public static void OnChangeLevel(StartOfRound __instance, ulong clientId, string sceneName, LoadSceneMode loadSceneMode, AsyncOperation asyncOperation) { if (sceneName == "CompanyBuilding") { MinimumQuotaFinder.Instance.TurnOnHighlight(displayIfCached: true, displayReason: false); } } [HarmonyPostfix] [HarmonyPatch(typeof(DepositItemsDesk), "PlaceItemOnCounter")] public static void OnItemPlacedOnCounter(DepositItemsDesk __instance, PlayerControllerB playerWhoTriggered) { if (MinimumQuotaFinder.Instance.IsToggled()) { MinimumQuotaFinder.Instance.TurnOnHighlight(displayIfCached: false, displayReason: false); } } } public class MathUtilities { private const int THRESHOLD = 300000; public static List<GrabbableObject> GetGreedyApproximation(List<GrabbableObject> allScrap, int target) { List<GrabbableObject> list = allScrap.OrderByDescending((GrabbableObject scrap) => scrap.scrapValue).ToList(); List<GrabbableObject> list2 = new List<GrabbableObject>(); int num = 0; foreach (GrabbableObject item in list) { int scrapValue = item.scrapValue; if (num + scrapValue <= target) { list2.Add(item); num += scrapValue; continue; } break; } if (list2.Sum((GrabbableObject s) => s.scrapValue) == target) { return list2; } for (int num2 = list.Count - 1; num2 >= 0; num2--) { GrabbableObject val = list[num2]; if (num + val.scrapValue >= target) { list2.Add(val); break; } } return list2; } public static IEnumerator GetIncludedCoroutine(List<GrabbableObject> allScrap, bool inverseTarget, int target, int calculationTarget, HashSet<GrabbableObject> includedScrap) { int numItems = allScrap.Count; MemCell[] prev = new MemCell[calculationTarget + 1]; MemCell[] current = new MemCell[calculationTarget + 1]; for (int i = 0; i < prev.Length; i++) { prev[i] = new MemCell(0, new HashSet<GrabbableObject>()); } int earlyTerminationTarget = (inverseTarget ? calculationTarget : target); int calculations = 0; for (int y = 1; y <= numItems; y++) { for (int x = 0; x <= calculationTarget; x++) { int currentScrapValue = allScrap[y - 1].scrapValue; if (x < currentScrapValue) { current[x] = prev[x]; continue; } int include = currentScrapValue + prev[x - currentScrapValue].Max; int exclude = prev[x].Max; if (include > exclude) { current[x] = new MemCell(include, new HashSet<GrabbableObject>(prev[x - currentScrapValue].Included) { allScrap[y - 1] }); } else { current[x] = prev[x]; } } prev = current; current = new MemCell[calculationTarget + 1]; if (prev[earlyTerminationTarget].Max == earlyTerminationTarget) { if (inverseTarget) { includedScrap.UnionWith(allScrap.Where((GrabbableObject scrap) => !prev[earlyTerminationTarget].Included.Contains(scrap))); } else { includedScrap.UnionWith(prev[earlyTerminationTarget].Included); } yield break; } calculations += calculationTarget; if (calculations > 300000) { yield return null; calculations = 0; } } if (inverseTarget) { includedScrap.UnionWith(allScrap.Where((GrabbableObject scrap) => !prev[calculationTarget].Included.Contains(scrap))); } else { for (int j = target; j < prev.Length; j++) { if (prev[j].Max >= target) { includedScrap.UnionWith(prev[j].Included); break; } } } yield return null; } } public class MemCell { public int Max { get; } public HashSet<GrabbableObject> Included { get; } public MemCell(int max, HashSet<GrabbableObject> included) { Max = max; Included = included; } } [BepInPlugin("com.github.riceisacereal.MinimumQuotaFinder", "MinimumQuotaFinder", "1.1.4")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class MinimumQuotaFinder : BaseUnityPlugin { private const string GUID = "com.github.riceisacereal.MinimumQuotaFinder"; private const string NAME = "MinimumQuotaFinder"; private const string VERSION = "1.1.4"; internal static HighlightInputClass InputActionsInstance = new HighlightInputClass(); public Material wireframeMaterial; private bool _toggled = false; private int _highlightLockState = 0; private int previousQuota = -1; private int previousResult = -1; private HashSet<GrabbableObject> previousInclude; private HashSet<GrabbableObject> previousAllScraps; private Dictionary<MeshRenderer, Material[]> _highlightedObjects = new Dictionary<MeshRenderer, Material[]>(); private List<string> excludedItemNames = new List<string> { "Shotgun", "Ammo", "Gift" }; public static MinimumQuotaFinder Instance { get; private set; } private void Awake() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown Instance = this; SetupKeybindCallbacks(); CreateShader(); Harmony val = new Harmony("com.github.riceisacereal.MinimumQuotaFinder"); val.PatchAll(Assembly.GetExecutingAssembly()); ((BaseUnityPlugin)this).Logger.LogInfo((object)"MinimumQuotaFinder successfully loaded!"); } private void SetupKeybindCallbacks() { InputActionsInstance.HighlightKey.performed += OnHighlightKeyPressed; } private void CreateShader() { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown string text = Path.Join((ReadOnlySpan<char>)Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), (ReadOnlySpan<char>)"wireframe"); AssetBundle val = AssetBundle.LoadFromFile(text); Shader val2 = val.LoadAsset<Shader>("assets/wireframeshader.shader"); wireframeMaterial = new Material(val2); val.Unload(false); } private void OnHighlightKeyPressed(CallbackContext highlightContext) { if (((CallbackContext)(ref highlightContext)).performed && !((Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)null) && HUDManager.Instance.CanPlayerScan() && !(HUDManager.Instance.playerPingingScan > -0.5f)) { if (!_toggled) { TurnOnHighlight(displayIfCached: true, displayReason: true); } else { TurnOffHighlight(); } } } public void TurnOnHighlight(bool displayIfCached, bool displayReason) { if (CanHighlight(displayReason)) { ((MonoBehaviour)GameNetworkManager.Instance).StartCoroutine(HighlightObjectsCoroutine(displayIfCached)); } } public void TurnOffHighlight() { int num = Interlocked.CompareExchange(ref _highlightLockState, 1, 0); if (num == 1) { return; } try { UnhighlightObjects(); } finally { _toggled = false; Interlocked.Exchange(ref _highlightLockState, 0); } } private List<GrabbableObject> GetAllScrap(int level) { GameObject val = GameObject.Find((level == 3) ? "/Environment" : "/Environment/HangarShip"); if ((Object)(object)val == (Object)null) { return new List<GrabbableObject>(); } return (from obj in val.GetComponentsInChildren<GrabbableObject>() where obj.itemProperties.isScrap && obj.scrapValue > 0 && ((Component)obj).transform.position.y > -30f && !excludedItemNames.Contains(obj.itemProperties.itemName) select obj).ToList(); } private List<GrabbableObject> GetDeskScrap() { List<GrabbableObject> list = new List<GrabbableObject>(); DepositItemsDesk val = Object.FindFirstObjectByType<DepositItemsDesk>(); if ((Object)(object)val != (Object)null) { list.AddRange(from obj in ((Component)val.deskObjectsContainer).GetComponentsInChildren<GrabbableObject>() where obj.itemProperties.isScrap select obj); } return list; } private int GetDeskScrapValue() { return GetDeskScrap().Sum((GrabbableObject obj) => obj.scrapValue); } private IEnumerator HighlightObjectsCoroutine(bool displayIfCached) { int oldValue = Interlocked.CompareExchange(ref _highlightLockState, 1, 0); if (oldValue == 1) { yield break; } try { if (displayIfCached) { HUDManager.Instance.DisplayTip("MinimumQuotaFinder", "Calculating...", false, false, "LC_Tip1"); } List<GrabbableObject> allScrap = GetAllScrap(StartOfRound.Instance.currentLevelID); HashSet<GrabbableObject> toHighlight = new HashSet<GrabbableObject>(); yield return ((MonoBehaviour)GameNetworkManager.Instance).StartCoroutine(GetSetToHighlight(allScrap, toHighlight, displayIfCached)); List<GrabbableObject> deskScrap = GetDeskScrap(); if (toHighlight.Count + deskScrap.Count > 0) { UnhighlightObjects(); HighlightObjects(toHighlight); HighlightObjects(deskScrap); _toggled = true; } else { _toggled = false; } } finally { Interlocked.Exchange(ref _highlightLockState, 0); } } private void HighlightObjects(IEnumerable<GrabbableObject> objectsToHighlight) { foreach (GrabbableObject item in objectsToHighlight) { MeshRenderer[] componentsInChildren = ((Component)item).GetComponentsInChildren<MeshRenderer>(); MeshRenderer[] array = componentsInChildren; foreach (MeshRenderer val in array) { if (!_highlightedObjects.ContainsKey(val)) { _highlightedObjects.Add(val, ((Renderer)val).materials); Material[] materials = ((Renderer)val).materials; int num = ((materials != null) ? materials.Length : 0); Material[] array2 = (Material[])(object)new Material[num]; Array.Fill(array2, wireframeMaterial); ((Renderer)val).materials = array2; } } } } private void UnhighlightObjects() { foreach (KeyValuePair<MeshRenderer, Material[]> highlightedObject in _highlightedObjects) { if (!((Object)(object)highlightedObject.Key == (Object)null) && ((Renderer)highlightedObject.Key).materials != null) { ((Renderer)highlightedObject.Key).materials = highlightedObject.Value; } } _highlightedObjects.Clear(); } private IEnumerator GetSetToHighlight(List<GrabbableObject> allScrap, HashSet<GrabbableObject> includedScrap, bool displayIfCached) { int sold = TimeOfDay.Instance.quotaFulfilled + GetDeskScrapValue(); int quota = TimeOfDay.Instance.profitQuota; if (sold >= quota) { string colour = ((sold - quota == 0) ? "#A5D971" : "#992403"); HUDManager.Instance.DisplayTip("MinimumQuotaFinder", $"Quota has been reached (<color={colour}>{sold}</color>/{quota}).", false, false, "LC_Tip1"); yield break; } if (allScrap == null || allScrap.Count == 0) { HUDManager.Instance.DisplayTip("MinimumQuotaFinder", "No scrap detected within the ship.", false, false, "LC_Tip1"); yield break; } if (quota == previousQuota && !ThrewAwayIncludedOrSoldExcluded(allScrap, sold) && (SubsetOfPrevious(allScrap) || quota == previousResult)) { includedScrap.UnionWith(previousInclude.Where(allScrap.Contains)); if (displayIfCached) { DisplayCalculationResult(includedScrap, sold, quota); } yield break; } previousQuota = quota; int sumScrapValue = allScrap.Sum((GrabbableObject scrap) => scrap.scrapValue); if (sold + sumScrapValue < quota) { HUDManager.Instance.DisplayTip("MinimumQuotaFinder", $"Not enough scrap to reach quota ({sumScrapValue + sold} < {quota}). Sell everything.", false, false, "LC_Tip1"); yield break; } allScrap.Sort((GrabbableObject x, GrabbableObject y) => ((NetworkBehaviour)x).NetworkObjectId.CompareTo(((NetworkBehaviour)y).NetworkObjectId)); previousAllScraps = allScrap.ToHashSet(); int target = quota - sold; int inverseTarget = allScrap.Sum((GrabbableObject scrap) => scrap.scrapValue) - target; if (inverseTarget <= quota) { yield return ((MonoBehaviour)GameNetworkManager.Instance).StartCoroutine(MathUtilities.GetIncludedCoroutine(allScrap, inverseTarget: true, target, inverseTarget, includedScrap)); } else { List<GrabbableObject> greedyApproximation = MathUtilities.GetGreedyApproximation(allScrap, quota - sold); int greedyTarget = greedyApproximation.Sum((GrabbableObject scrap) => scrap.scrapValue); if (greedyTarget == quota - sold) { includedScrap.UnionWith(greedyApproximation); } else { yield return ((MonoBehaviour)GameNetworkManager.Instance).StartCoroutine(MathUtilities.GetIncludedCoroutine(allScrap, inverseTarget: false, target, greedyTarget, includedScrap)); } } previousInclude = includedScrap; DisplayCalculationResult(includedScrap, sold, quota); yield return null; } private bool ThrewAwayIncludedOrSoldExcluded(List<GrabbableObject> allScrap, int sold) { if (previousInclude == null) { return true; } int num = previousInclude.Intersect(allScrap.ToHashSet()).Sum((GrabbableObject scrap) => scrap.scrapValue); return num + sold != previousResult; } private bool SubsetOfPrevious(List<GrabbableObject> allScrap) { if (allScrap == null || previousInclude == null || previousAllScraps == null) { return false; } return allScrap.ToHashSet().IsSubsetOf(previousAllScraps); } private void DisplayCalculationResult(IEnumerable<GrabbableObject> toHighlight, int sold, int quota) { int num = (previousResult = toHighlight.Sum((GrabbableObject scrap) => scrap.scrapValue) + sold); int num2 = num - quota; string arg = ((num2 == 0) ? "#A5D971" : "#992403"); HUDManager.Instance.DisplayTip("MinimumQuotaFinder", $"Optimal scrap combination found: {num} ({sold} already sold). " + $"<color={arg}>{num2}</color> over quota. ", false, false, "LC_Tip1"); } public bool IsToggled() { return _toggled; } public bool CanHighlight(bool displayReason) { bool flag = IsOnCompanyMoon(StartOfRound.Instance.currentLevelID); if (flag && Math.Abs(StartOfRound.Instance.companyBuyingRate - 1f) >= 0.001f) { if (displayReason) { HUDManager.Instance.DisplayTip("MinimumQuotaFinder", "Buying rate is not at 100%, no scrap has been highlighted as the calculations would be inaccurate.", false, false, "LC_Tip1"); } return false; } if (!flag && !GameNetworkManager.Instance.localPlayerController.isInHangarShipRoom) { if (displayReason) { HUDManager.Instance.DisplayTip("MinimumQuotaFinder", "Highlighting disabled, player is not on the ship", false, false, "LC_Tip1"); } return false; } return true; } private bool IsOnCompanyMoon(int levelID) { return ((Object)StartOfRound.Instance.levels[levelID]).name == "CompanyBuildingLevel"; } } public class HighlightInputClass : LcInputActions { [InputAction("<Keyboard>/h", Name = "Toggle scrap highlight")] public InputAction HighlightKey { get; set; } } }