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 GynxzRepoChallenges v1.5.1
plugins\GynxzRepoChallenges\GynxzRepoChallenges.dll
Decompiled 3 weeks ago
The result has been truncated due to the large size, download it to view full contents!
using 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.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using ExitGames.Client.Photon; using GynxzRepoChallenges.Challenges; using GynxzRepoChallenges.Dev; using GynxzRepoChallenges.Network; using GynxzRepoChallenges.UI; using HarmonyLib; using Photon.Pun; using Photon.Realtime; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("GynxzRepoChallenges")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.5.1.0")] [assembly: AssemblyInformationalVersion("1.5.1")] [assembly: AssemblyProduct("GynxzRepoChallenges")] [assembly: AssemblyTitle("GynxzRepoChallenges")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.5.1.0")] [module: UnverifiableCode] namespace GynxzRepoChallenges { public static class ChallengeManager { private static readonly List<BaseChallenge> _active = new List<BaseChallenge>(); private static readonly List<BaseChallenge> _picks = new List<BaseChallenge>(); public static bool NoCrouchActive = false; public static bool NoSprintActive = false; public static bool NoMapActive = false; public static bool NoHealthPackActive = false; public static bool NoUpgradesActive = false; public static bool TextOnlyActive = false; public static bool CartLeashActive = false; public static bool FlawlessActive = false; public static bool FrugalActive = false; public static bool ExpensiveOnlyActive = false; public static bool PacifistActive = false; public static bool EmpathyActive = false; public static bool NitroFingersActive = false; public static bool ShortRangeActive = false; public static float ShortRangeOriginalValue = -1f; public static float ShortRangeCurrentValue = -1f; public static bool BetterTogetherActive = false; public static float BetterTogetherDamageReduction = 0f; public static bool InLevel = false; public static bool InMapLevel = false; private static int _f8Index = -1; private static int _lastCycleFrame = -1; private static int _lastClearFrame = -1; public static int FlawlessViolations = 0; public static int CartLeashViolations = 0; private static readonly List<Transform> _cartTransforms = new List<Transform>(); private static float _leashTimer = 0f; private const float LEASH_INTERVAL = 1f; public static float CartLeashSlowFactor = 0f; public static Vector3 NearestCartPos = Vector3.zero; private static readonly string[][] _exclusiveGroups = new string[1][] { new string[2] { "frugal", "expensive_only" } }; public static IEnumerable<BaseChallenge> ActiveChallenges => _active; public static IReadOnlyList<BaseChallenge> ActiveList => _active; public static BaseChallenge ActiveChallenge { get { if (_active.Count <= 0) { return null; } return _active[0]; } } public static bool RosterHasActive() { foreach (BaseChallenge item in ChallengeRegistry.All) { if (Plugin.GetMode(item.Id) == ChallengeMode.Active) { return true; } } return false; } private static List<BaseChallenge> RosterActiveList() { return ChallengeRegistry.All.Where((BaseChallenge c) => Plugin.GetMode(c.Id) == ChallengeMode.Active).ToList(); } private static List<BaseChallenge> AvailableList() { return ChallengeRegistry.All.Where((BaseChallenge c) => Plugin.GetMode(c.Id) == ChallengeMode.Available).ToList(); } public static void ReconcileRoster() { List<BaseChallenge> list = RosterActiveList(); foreach (BaseChallenge pick in _picks) { if (!list.Contains(pick)) { list.Add(pick); } } SetActiveSet(list); Plugin.Log.LogInfo((object)($"[ChallengeManager] Reconciled — {list.Count} enforced" + ((list.Count > 0) ? (": " + string.Join(", ", list.Select((BaseChallenge c) => c.Id))) : "."))); } private static void SetActiveSet(IEnumerable<BaseChallenge> desired) { List<BaseChallenge> list = new List<BaseChallenge>(); foreach (BaseChallenge item in desired) { if (item != null && !list.Contains(item)) { list.Add(item); } } ResolveExclusiveConflicts(list); for (int num = _active.Count - 1; num >= 0; num--) { if (!list.Contains(_active[num])) { _active[num].Remove(); _active.RemoveAt(num); } } foreach (BaseChallenge item2 in list) { if (!_active.Contains(item2)) { item2.Apply(); _active.Add(item2); } } ResetViolations(); ChallengeHUD.Dirty = true; Plugin.WriteStatus(); } private static void ResolveExclusiveConflicts(List<BaseChallenge> want) { string[][] exclusiveGroups = _exclusiveGroups; foreach (string[] array in exclusiveGroups) { BaseChallenge baseChallenge = null; foreach (BaseChallenge item in want) { if (Array.IndexOf(array, item.Id) >= 0) { baseChallenge = item; } } if (baseChallenge == null) { continue; } bool flag = false; for (int num = want.Count - 1; num >= 0; num--) { if (want[num] != baseChallenge && Array.IndexOf(array, want[num].Id) >= 0) { Plugin.Log.LogInfo((object)("[ChallengeManager] '" + want[num].Id + "' dropped — mutually exclusive with '" + baseChallenge.Id + "'.")); want.RemoveAt(num); flag = true; } } if (flag) { ChallengeHUD.ShowViolation(baseChallenge.DisplayName + " active — conflicting challenge removed"); } } } public static bool AssignById(string id, bool additive = false) { BaseChallenge baseChallenge = ChallengeRegistry.Get(id); if (baseChallenge == null) { Plugin.Log.LogWarning((object)("[ChallengeManager] Unknown challenge id: '" + id + "'")); return false; } Assign(baseChallenge, additive); return true; } public static void AssignRandom() { Assign(ChallengeRegistry.GetRandom()); } public static void Assign(BaseChallenge challenge, bool additive = false) { if (challenge != null) { if (!additive) { _picks.Clear(); } if (!_picks.Contains(challenge)) { _picks.Add(challenge); } ReconcileRoster(); Plugin.Log.LogInfo((object)("[ChallengeManager] Challenge " + (additive ? "stacked" : "assigned") + " → " + challenge.DisplayName + (additive ? $" ({_picks.Count} picks)" : ""))); } } public static void ClearChallenge() { if (Time.frameCount != _lastClearFrame) { _lastClearFrame = Time.frameCount; _picks.Clear(); ReconcileRoster(); Plugin.Log.LogInfo((object)"[ChallengeManager] Clear — manual picks cleared (Active roster kept)."); } } public static void CycleChallenge() { if (Time.frameCount == _lastCycleFrame) { return; } _lastCycleFrame = Time.frameCount; if (RosterHasActive()) { Plugin.Log.LogInfo((object)"[ChallengeManager] F8 ignored — Active challenges are set in config."); ChallengeHUD.ShowViolation("F8 disabled — Active challenges set in config"); return; } List<BaseChallenge> list = AvailableList(); if (list.Count == 0) { Plugin.Log.LogInfo((object)"[ChallengeManager] F8 ignored — no Available challenges in roster."); ChallengeHUD.ShowViolation("No Available challenges — set some to Available in config"); return; } _f8Index = (_f8Index + 1) % list.Count; BaseChallenge baseChallenge = list[_f8Index]; _picks.Clear(); _picks.Add(baseChallenge); ReconcileRoster(); Plugin.Log.LogInfo((object)$"[ChallengeManager] F8 → {baseChallenge.DisplayName} ({_f8Index + 1}/{list.Count})"); } public static void OnRoundStart() { if (!Plugin.Ready) { Plugin.Log.LogInfo((object)"[ChallengeManager] OnRoundStart — plugin not ready yet, skipping."); return; } Plugin.Log.LogInfo((object)"[ChallengeManager] OnRoundStart triggered."); InLevel = true; ItemDamagePatch.ClearDestroyedSet(); ItemDamagePatch.ClearValueCache(); GrabPatch.OnRoundStart(); HeldItemTicker.OnRoundStart(); BetterTogetherEngine.OnRoundStart(); CacheCartPositions(); Type type = Type.GetType("ValuableObject, Assembly-CSharp"); Object[] array = ((type != null) ? Object.FindObjectsOfType(type) : null); InMapLevel = array != null && array.Length != 0; Plugin.Log.LogInfo((object)$"[ChallengeManager] InMapLevel = {InMapLevel} ({((array != null) ? array.Length : 0)} valuables found)"); if (!InMapLevel) { Plugin.Log.LogInfo((object)"[ChallengeManager] Not a map level — challenge state unchanged."); } else if (Plugin.AutoAssignOnRoundStart.Value) { AssignRandom(); } else if (Plugin.ChallengeScopePerRound.Value && _picks.Count > 0) { Plugin.Log.LogInfo((object)"[ChallengeManager] New round — clearing per-round picks."); _picks.Clear(); ReconcileRoster(); } } public static void OnSceneLoad() { InLevel = false; InMapLevel = false; _cartTransforms.Clear(); _leashTimer = 0f; BetterTogetherEngine.OnSceneLoad(); ChallengeSync.ClearRelayThrottle(); ChallengeHUD.ClearPersistentMessage(); Plugin.Log.LogInfo((object)"[ChallengeManager] Scene changed — cart leash suspended."); } private static void CacheCartPositions() { _cartTransforms.Clear(); _leashTimer = 0f; Type type = Type.GetType("PhysGrabObject, Assembly-CSharp"); if (type != null) { FieldInfo field = type.GetField("isCart", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { Component[] array = Object.FindObjectsOfType(type) as Component[]; bool flag = default(bool); foreach (Component val in array) { if (!((Object)(object)val == (Object)null)) { object value = field.GetValue(val); int num; if (value is bool) { flag = (bool)value; num = 1; } else { num = 0; } if (((uint)num & (flag ? 1u : 0u)) != 0) { _cartTransforms.Add(val.transform); Plugin.Log.LogInfo((object)("[CartLeash] Cached cart: " + ((Object)val.gameObject).name)); } } } Plugin.Log.LogInfo((object)$"[CartLeash] {_cartTransforms.Count} cart(s) cached via isCart."); return; } } GameObject[] array2 = Object.FindObjectsOfType<GameObject>(); foreach (GameObject val2 in array2) { if (!((Object)(object)val2.transform.parent != (Object)null)) { string text = ((Object)val2).name.ToLowerInvariant(); if (text.Contains("cart") || text.Contains("trolley")) { _cartTransforms.Add(val2.transform); Plugin.Log.LogInfo((object)("[CartLeash] Cached (fallback): " + ((Object)val2).name)); } } } Plugin.Log.LogInfo((object)$"[CartLeash] {_cartTransforms.Count} cart(s) cached (fallback)."); } public static void CheckCartLeash(Vector3 playerPos) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) if (!CartLeashActive || !InLevel || !InMapLevel) { CartLeashSlowFactor = 0f; } else { if (_cartTransforms.Count == 0) { return; } float num = float.MaxValue; Vector3 nearestCartPos = Vector3.zero; foreach (Transform cartTransform in _cartTransforms) { if (!((Object)(object)cartTransform == (Object)null)) { float num2 = Vector3.Distance(playerPos, cartTransform.position); if (num2 < num) { num = num2; nearestCartPos = cartTransform.position; } } } if (num == float.MaxValue) { return; } NearestCartPos = nearestCartPos; float value = Plugin.CartLeashSlowStartDistance.Value; float value2 = Plugin.CartLeashMaxDistance.Value; float num3 = (float)Plugin.CartLeashSlowPercent.Value / 100f; if (num <= value) { CartLeashSlowFactor = 0f; return; } if (num >= value2) { CartLeashSlowFactor = 1f; } else { float num4 = (num - value) / (value2 - value); CartLeashSlowFactor = Mathf.Lerp(0f, num3, num4); } if (!(CartLeashSlowFactor < 1f)) { _leashTimer += Time.deltaTime; if (!(_leashTimer < 1f)) { _leashTimer = 0f; CartLeashViolations++; Plugin.LogVerbose($"[CartLeash] Too far! {num:F1}u"); ChallengeHUD.ShowViolation("CART LEASH! Return to cart!"); } } } } public static void OnItemDamaged(string itemName) { if (FlawlessActive) { FlawlessViolations++; Plugin.Log.LogWarning((object)$"[Flawless] Item damaged: {itemName} (violation #{FlawlessViolations})"); ChallengeHUD.ShowViolation("FLAWLESS BROKEN! Damaged: " + itemName); } } public static void OnEmpathyHit() { if (EmpathyActive) { ChallengeHUD.ShowViolation($"EMPATHETIC! -{Plugin.EmpathyDamagePerHit.Value}HP!"); } } private static void ResetViolations() { FlawlessViolations = 0; CartLeashViolations = 0; } } public static class Patches { public static void PatchAll(Harmony harmony) { PatchPlayerController(harmony); PatchMethod(harmony, "MapToolController", "Update", typeof(MapPatch), "Prefix"); PatchHealthPack(harmony); PatchUpgrade(harmony); PatchMethod(harmony, "PhysGrabber", "PhysGrabLogic", typeof(GrabPatch), "Prefix"); PatchItemDamage(harmony); PatchShortRange(harmony); PatchLevelStart(harmony); PatchPlayerHealth(harmony); } private static void PatchPlayerHealth(Harmony harmony) { //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Expected O, but got Unknown try { Type gameType = GetGameType("PlayerHealth"); if (gameType == null) { Plugin.Log.LogError((object)"[Patches] PlayerHealth not found"); return; } MethodInfo method = gameType.GetMethod("Hurt", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (method == null) { Plugin.Log.LogError((object)"[Patches] PlayerHealth.Hurt not found"); return; } MethodInfo method2 = typeof(PlayerHealthDamagePatch).GetMethod("Prefix", BindingFlags.Static | BindingFlags.Public); harmony.Patch((MethodBase)method, new HarmonyMethod(method2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Plugin.Log.LogInfo((object)"[Patches] ✓ PlayerHealth.Hurt() (Better Together damage reduction)"); Plugin.Log.LogInfo((object)"[Patches] Applied: PlayerHealthDamagePatch"); } catch (Exception ex) { Plugin.Log.LogError((object)("[Patches] PlayerHealth patch failed: " + ex.Message)); } } private static void PatchMethod(Harmony harmony, string typeName, string methodName, Type patchClass, string patchMethodName) { //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Expected O, but got Unknown try { Type gameType = GetGameType(typeName); if (gameType == null) { Plugin.Log.LogError((object)("[Patches] Type not found: " + typeName)); return; } MethodInfo method = gameType.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (method == null) { Plugin.Log.LogError((object)("[Patches] Method not found: " + typeName + "." + methodName)); return; } MethodInfo method2 = patchClass.GetMethod(patchMethodName, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); harmony.Patch((MethodBase)method, new HarmonyMethod(method2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Plugin.Log.LogInfo((object)("[Patches] ✓ " + typeName + "." + methodName + "()")); Plugin.Log.LogInfo((object)("[Patches] Applied: " + patchClass.Name)); } catch (Exception ex) { Plugin.Log.LogError((object)("[Patches] Failed to patch " + typeName + "." + methodName + ": " + ex.Message)); } } private static void PatchPlayerController(Harmony harmony) { //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Expected O, but got Unknown //IL_0097: Expected O, but got Unknown try { Type gameType = GetGameType("PlayerController"); if (gameType == null) { Plugin.Log.LogError((object)"[Patches] Type not found: PlayerController"); return; } MethodInfo method = gameType.GetMethod("Update", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (method == null) { Plugin.Log.LogError((object)"[Patches] Method not found: PlayerController.Update"); return; } MethodInfo method2 = typeof(PlayerControllerPatch).GetMethod("Prefix", BindingFlags.Static | BindingFlags.Public); MethodInfo method3 = typeof(PlayerControllerPatch).GetMethod("Postfix", BindingFlags.Static | BindingFlags.Public); harmony.Patch((MethodBase)method, new HarmonyMethod(method2), new HarmonyMethod(method3), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Plugin.Log.LogInfo((object)"[Patches] ✓ PlayerController.Update() (prefix + postfix)"); Plugin.Log.LogInfo((object)"[Patches] Applied: PlayerControllerPatch"); } catch (Exception ex) { Plugin.Log.LogError((object)("[Patches] Failed to patch PlayerController.Update: " + ex.Message)); } } private static void PatchItemDamage(Harmony harmony) { //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Expected O, but got Unknown //IL_00ca: Expected O, but got Unknown try { Type gameType = GetGameType("PhysGrabObjectImpactDetector"); if (gameType == null) { Plugin.Log.LogError((object)"[Patches] PhysGrabObjectImpactDetector not found"); return; } MethodInfo method = typeof(ItemDamagePatch).GetMethod("Prefix", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); MethodInfo method2 = typeof(ItemDamagePatch).GetMethod("Postfix", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); string[] array = new string[3] { "ImpactHeavy", "ImpactMedium", "ImpactLight" }; foreach (string text in array) { MethodInfo method3 = gameType.GetMethod(text, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (method3 == null) { Plugin.Log.LogWarning((object)("[Patches] " + text + " not found")); continue; } harmony.Patch((MethodBase)method3, new HarmonyMethod(method), new HarmonyMethod(method2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Plugin.Log.LogInfo((object)("[Patches] ✓ PhysGrabObjectImpactDetector." + text + "()")); } Plugin.Log.LogInfo((object)"[Patches] Applied: ItemDamagePatch"); } catch (Exception ex) { Plugin.Log.LogError((object)("[Patches] ItemDamage patch failed: " + ex.Message)); } } private static void PatchShortRange(Harmony harmony) { //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Expected O, but got Unknown try { Type gameType = GetGameType("PhysGrabber"); if (gameType == null) { Plugin.Log.LogError((object)"[Patches] PhysGrabber not found for ShortRange"); return; } MethodInfo method = gameType.GetMethod("Update", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (method == null) { Plugin.Log.LogError((object)"[Patches] PhysGrabber.Update not found"); return; } MethodInfo method2 = typeof(ShortRangePatch).GetMethod("Postfix", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); harmony.Patch((MethodBase)method, (HarmonyMethod)null, new HarmonyMethod(method2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Plugin.Log.LogInfo((object)"[Patches] ✓ PhysGrabber.Update() (postfix)"); Plugin.Log.LogInfo((object)"[Patches] Applied: ShortRangePatch"); } catch (Exception ex) { Plugin.Log.LogError((object)("[Patches] ShortRange patch failed: " + ex.Message)); } } private static void PatchLevelStart(Harmony harmony) { //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Expected O, but got Unknown try { Type gameType = GetGameType("GameDirector"); if (gameType == null) { Plugin.Log.LogError((object)"[Patches] GameDirector not found"); return; } MethodInfo method = gameType.GetMethod("SetStart", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (method == null) { Plugin.Log.LogError((object)"[Patches] GameDirector.SetStart not found"); return; } HarmonyMethod val = new HarmonyMethod(typeof(LevelStartPatch).GetMethod("Postfix", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)); val.priority = 0; harmony.Patch((MethodBase)method, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Plugin.Log.LogInfo((object)"[Patches] ✓ GameDirector.SetStart() (Priority.Last)"); Plugin.Log.LogInfo((object)"[Patches] Applied: LevelStartPatch"); } catch (Exception ex) { Plugin.Log.LogError((object)("[Patches] LevelStart patch failed: " + ex.Message)); } } private static void PatchHealthPack(Harmony harmony) { //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Expected O, but got Unknown try { Type gameType = GetGameType("ItemHealthPack"); if (gameType == null) { Plugin.Log.LogError((object)"[Patches] ItemHealthPack not found"); return; } StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine("[Patches] ItemHealthPack methods:"); MethodInfo[] methods = gameType.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (MethodInfo methodInfo in methods) { string text = string.Join(", ", Array.ConvertAll(methodInfo.GetParameters(), (ParameterInfo p) => p.ParameterType.Name + " " + p.Name)); stringBuilder.AppendLine(" " + methodInfo.ReturnType.Name + " " + methodInfo.Name + "(" + text + ")"); } Plugin.Log.LogInfo((object)stringBuilder.ToString()); MethodInfo method = typeof(HealthPackPatch).GetMethod("Prefix", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); int num = 0; string[] array = new string[21] { "Update", "UsedRPC", "Used", "UseItem", "Use", "Interact", "OnInteract", "Activate", "TryUse", "UseLocal", "OnUse", "PickUp", "Heal", "HealRPC", "UseHealthPack", "PickupActivate", "ItemActivate", "UseActivate", "SetUsed", "ActivateItem", "ApplyHeal" }; foreach (string text2 in array) { MethodInfo method2 = gameType.GetMethod(text2, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (!(method2 == null)) { harmony.Patch((MethodBase)method2, new HarmonyMethod(method), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Plugin.Log.LogInfo((object)("[Patches] ✓ ItemHealthPack." + text2 + "()")); num++; } } if (num == 0) { Plugin.Log.LogError((object)"[Patches] No ItemHealthPack methods matched — check dump above"); } Plugin.Log.LogInfo((object)"[Patches] Applied: HealthPackPatch"); } catch (Exception ex) { Plugin.Log.LogError((object)("[Patches] HealthPack patch failed: " + ex.Message)); } } private static void PatchUpgrade(Harmony harmony) { //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Expected O, but got Unknown try { Type gameType = GetGameType("ItemUpgrade"); if (gameType == null) { Plugin.Log.LogError((object)"[Patches] ItemUpgrade not found"); return; } StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine("[Patches] ItemUpgrade methods:"); MethodInfo[] methods = gameType.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (MethodInfo methodInfo in methods) { string text = string.Join(", ", Array.ConvertAll(methodInfo.GetParameters(), (ParameterInfo p) => p.ParameterType.Name + " " + p.Name)); stringBuilder.AppendLine(" " + methodInfo.ReturnType.Name + " " + methodInfo.Name + "(" + text + ")"); } Plugin.Log.LogInfo((object)stringBuilder.ToString()); MethodInfo method = typeof(UpgradePatch).GetMethod("Prefix", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); int num = 0; string[] array = new string[12] { "ButtonToggle", "PlayerUpgrade", "Interact", "Use", "Toggle", "UpgradePlayer", "PressButton", "Purchase", "Buy", "OnInteract", "Activate", "Press" }; foreach (string text2 in array) { MethodInfo method2 = gameType.GetMethod(text2, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (!(method2 == null)) { harmony.Patch((MethodBase)method2, new HarmonyMethod(method), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Plugin.Log.LogInfo((object)("[Patches] ✓ ItemUpgrade." + text2 + "()")); num++; } } if (num == 0) { Plugin.Log.LogError((object)"[Patches] No ItemUpgrade methods matched — check dump above"); } Plugin.Log.LogInfo((object)"[Patches] Applied: UpgradePatch"); } catch (Exception ex) { Plugin.Log.LogError((object)("[Patches] Upgrade patch failed: " + ex.Message)); } } private static Type GetGameType(string name) { return Type.GetType(name + ", Assembly-CSharp"); } } public static class PlayerControllerPatch { private static readonly Dictionary<string, FieldInfo> _fieldCache = new Dictionary<string, FieldInfo>(); public static void Prefix(object __instance) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) Plugin.EnsureUpdaterCreated(); try { if (ChallengeManager.CartLeashActive) { Component val = (Component)((__instance is Component) ? __instance : null); if ((Object)(object)val != (Object)null) { ChallengeManager.CheckCartLeash(val.transform.position); } } } catch (Exception ex) { Plugin.Log.LogError((object)("[PlayerControllerPatch.Prefix] " + ex.Message)); } } public static void Postfix(object __instance) { //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: 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_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_0222: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_0271: Unknown result type (might be due to invalid IL or missing references) //IL_0276: Unknown result type (might be due to invalid IL or missing references) //IL_027a: Unknown result type (might be due to invalid IL or missing references) //IL_027f: Unknown result type (might be due to invalid IL or missing references) //IL_0283: Unknown result type (might be due to invalid IL or missing references) //IL_028f: Unknown result type (might be due to invalid IL or missing references) //IL_029b: Unknown result type (might be due to invalid IL or missing references) //IL_029d: Unknown result type (might be due to invalid IL or missing references) //IL_029f: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_02b4: Unknown result type (might be due to invalid IL or missing references) //IL_02b6: Unknown result type (might be due to invalid IL or missing references) //IL_02b8: Unknown result type (might be due to invalid IL or missing references) //IL_02bf: Unknown result type (might be due to invalid IL or missing references) //IL_02c5: Unknown result type (might be due to invalid IL or missing references) //IL_02ca: Unknown result type (might be due to invalid IL or missing references) //IL_02cf: Unknown result type (might be due to invalid IL or missing references) //IL_02d3: Unknown result type (might be due to invalid IL or missing references) //IL_02da: Unknown result type (might be due to invalid IL or missing references) //IL_02e1: Unknown result type (might be due to invalid IL or missing references) //IL_02e8: Unknown result type (might be due to invalid IL or missing references) try { Type type = __instance.GetType(); if (ChallengeManager.NoCrouchActive && ChallengeManager.InMapLevel) { SetBool(__instance, type, "Crouching", val: false); SetBool(__instance, type, "Crawling", val: false); SetBool(__instance, type, "toggleCrouch", val: false); SetBool(__instance, type, "previousCrouchingState", val: false); SetBool(__instance, type, "previousCrawlingState", val: false); } if (ChallengeManager.NoSprintActive && ChallengeManager.InMapLevel) { SetBool(__instance, type, "sprinting", val: false); SetBool(__instance, type, "toggleSprint", val: false); SetBool(__instance, type, "previousSprintingState", val: false); SetFloat(__instance, type, "SprintSpeedLerp", 0f); } float cartLeashSlowFactor = ChallengeManager.CartLeashSlowFactor; if (!ChallengeManager.CartLeashActive || !(cartLeashSlowFactor > 0f)) { return; } Component val = (Component)((__instance is Component) ? __instance : null); if (!((Object)(object)val != (Object)null)) { return; } Vector3 val2 = ChallengeManager.NearestCartPos - val.transform.position; val2.y = 0f; float magnitude = ((Vector3)(ref val2)).magnitude; float value = Plugin.CartLeashMaxDistance.Value; if (cartLeashSlowFactor >= 1f && magnitude > value && magnitude > 0.001f) { Vector3 normalized = ((Vector3)(ref val2)).normalized; Rigidbody component = val.GetComponent<Rigidbody>(); if ((Object)(object)component != (Object)null) { Vector3 velocity = component.velocity; Vector3 val3 = default(Vector3); ((Vector3)(ref val3))..ctor(velocity.x, 0f, velocity.z); float num = Vector3.Dot(val3, -normalized); if (num > 0f) { val3 -= -normalized * num; } float num2 = magnitude - value; val3 += normalized * Mathf.Min(num2, 3f) * 2f; component.velocity = new Vector3(val3.x, velocity.y, val3.z); } else { Vector3 val4 = ChallengeManager.NearestCartPos - normalized * value; val4.y = val.transform.position.y; val.transform.position = Vector3.MoveTowards(val.transform.position, val4, 0.5f); } } else { if (!(cartLeashSlowFactor > 0f) || !(cartLeashSlowFactor < 1f) || !(magnitude > 0.001f)) { return; } Rigidbody component2 = val.GetComponent<Rigidbody>(); if ((Object)(object)component2 != (Object)null) { Vector3 normalized2 = ((Vector3)(ref val2)).normalized; Vector3 velocity2 = component2.velocity; Vector3 val5 = default(Vector3); ((Vector3)(ref val5))..ctor(velocity2.x, 0f, velocity2.z); float num3 = Vector3.Dot(val5, -normalized2); if (num3 > 0f) { val5 -= -normalized2 * num3 * cartLeashSlowFactor; component2.velocity = new Vector3(val5.x, velocity2.y, val5.z); } } } } catch (Exception ex) { Plugin.Log.LogError((object)("[PlayerControllerPatch.Postfix] " + ex.Message)); } } private static FieldInfo CachedField(Type t, string name) { if (!_fieldCache.TryGetValue(name, out var value)) { value = t.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); _fieldCache[name] = value; } return value; } private static void SetBool(object inst, Type t, string name, bool val) { CachedField(t, name)?.SetValue(inst, val); } private static void SetFloat(object inst, Type t, string name, float val) { CachedField(t, name)?.SetValue(inst, val); } } public static class MapPatch { public static bool Prefix() { if (ChallengeManager.NoMapActive) { return !ChallengeManager.InMapLevel; } return true; } } public static class HealthPackPatch { public static bool Prefix() { if (!ChallengeManager.NoHealthPackActive) { return true; } ChallengeHUD.ShowViolation("NO HEALTH PACK! Challenge active!"); return false; } } public static class UpgradePatch { public static bool Prefix(MethodBase __originalMethod, object[] __args) { if (!ChallengeManager.NoUpgradesActive) { return true; } if (__originalMethod?.Name == "PlayerUpgrade" && __args != null && __args.Length != 0) { try { object obj = __args[0]; object obj2 = obj?.GetType().GetProperty("Sender")?.GetValue(obj); if (obj2?.GetType().GetProperty("IsLocal")?.GetValue(obj2) as bool? == false) { return true; } } catch { } } Plugin.LogVerbose("[UpgradePatch] Blocked: " + __originalMethod?.Name); ChallengeHUD.ShowViolation("NO UPGRADES! Challenge active!"); return false; } } public static class GrabPatch { private static readonly HashSet<int> _violatedItems = new HashSet<int>(); private static bool _disengageDumped = false; private static FieldInfo _grabObjField; private static bool _grabObjFieldResolved; private static Type _grabVoType; private static FieldInfo _grabDollarField; private static bool _grabVoResolved; private static Type[] _weaponTypes; private static readonly Dictionary<int, bool> _weaponVerdicts = new Dictionary<int, bool>(); private static bool _weaponDumped = false; public static bool Prefix(object __instance) { bool flag = ChallengeManager.FrugalActive && ChallengeManager.InMapLevel; bool flag2 = ChallengeManager.ExpensiveOnlyActive && ChallengeManager.InMapLevel; bool pacifistActive = ChallengeManager.PacifistActive; if (!flag && !flag2 && !pacifistActive) { return true; } try { GameObject grabbedObject = GetGrabbedObject(__instance); if ((Object)(object)grabbedObject == (Object)null) { return true; } int instanceID = ((Object)grabbedObject).GetInstanceID(); if (flag || flag2) { int itemValue = GetItemValue(grabbedObject); if (itemValue >= 0) { int value = Plugin.ExpensiveItemThreshold.Value; if ((!flag || itemValue < value) && (!flag2 || itemValue >= value)) { _violatedItems.Remove(instanceID); } else { if (_violatedItems.Add(instanceID)) { string text = (ChallengeManager.FrugalActive ? $"FRUGAL: Too expensive! (${itemValue})" : $"EXPENSIVE ONLY: Too cheap! (${itemValue})"); Plugin.LogVerbose("[GrabPatch] " + text); ChallengeHUD.ShowViolation(text); } ForceRelease(__instance); } } } if (pacifistActive && IsWeapon(grabbedObject)) { if (_violatedItems.Add(instanceID)) { Plugin.LogVerbose("[GrabPatch] PACIFIST: weapon grab blocked (" + ((Object)grabbedObject).name + ")"); ChallengeHUD.ShowViolation("PACIFIST! No weapons!"); } ForceRelease(__instance); } } catch (Exception ex) { Plugin.Log.LogError((object)("[GrabPatch] " + ex.Message)); } return true; } private static void ForceRelease(object grabber) { try { Type type = grabber.GetType(); FieldInfo field = type.GetField("grabbedPhysGrabObject", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); MethodInfo methodInfo = null; MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (MethodInfo methodInfo2 in methods) { if (methodInfo2.Name == "disengagePhysGrabObject") { methodInfo = methodInfo2; break; } } if (methodInfo != null) { ParameterInfo[] parameters = methodInfo.GetParameters(); if (!_disengageDumped) { _disengageDumped = true; string text = string.Join(", ", Array.ConvertAll(parameters, (ParameterInfo p) => p.ParameterType.Name + " " + p.Name)); Plugin.Log.LogInfo((object)("[GrabPatch] disengagePhysGrabObject(" + text + ")")); } if (parameters.Length == 0) { methodInfo.Invoke(grabber, null); return; } if (parameters.Length == 1) { object obj = field?.GetValue(grabber); methodInfo.Invoke(grabber, new object[1] { obj }); return; } } field?.SetValue(grabber, null); } catch (Exception ex) { Plugin.Log.LogError((object)("[ForceRelease] " + ex.GetType().Name + ": " + ex.Message)); } } private static GameObject GetGrabbedObject(object grabber) { if (!_grabObjFieldResolved) { _grabObjFieldResolved = true; Type type = grabber.GetType(); string[] array = new string[5] { "grabbedPhysGrabObject", "physGrabObject", "grabObject", "currentGrabObject", "grabbedObject" }; foreach (string name in array) { FieldInfo field = type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { _grabObjField = field; break; } } } if (_grabObjField == null) { return null; } object value = _grabObjField.GetValue(grabber); Component val = (Component)((value is Component) ? value : null); if (val != null) { return val.gameObject; } GameObject val2 = (GameObject)((value is GameObject) ? value : null); if (val2 != null) { return val2; } return null; } private static int GetItemValue(GameObject go) { if (!_grabVoResolved) { _grabVoResolved = true; _grabVoType = Type.GetType("ValuableObject, Assembly-CSharp"); if (_grabVoType != null) { _grabDollarField = _grabVoType.GetField("dollarValueCurrent", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); } } if (_grabVoType == null || _grabDollarField == null) { return -1; } Component component = go.GetComponent(_grabVoType); if ((Object)(object)component == (Object)null) { return -1; } object value = _grabDollarField.GetValue(component); if (value is float num) { return (int)num; } if (value is int) { return (int)value; } return -1; } private static bool IsWeapon(GameObject go) { int instanceID = ((Object)go).GetInstanceID(); if (_weaponVerdicts.TryGetValue(instanceID, out var value)) { return value; } if (_weaponTypes == null) { List<Type> list = new List<Type>(); string[] array = new string[9] { "ItemGun", "ItemWeapon", "ItemMelee", "ItemRevolver", "ItemShotgun", "ItemRifle", "ItemCrossbow", "ItemGrenade", "ItemGrenadeStun" }; for (int i = 0; i < array.Length; i++) { Type type = Type.GetType(array[i] + ", Assembly-CSharp"); if (type != null) { list.Add(type); } } _weaponTypes = list.ToArray(); } bool flag = false; Type[] weaponTypes = _weaponTypes; foreach (Type type2 in weaponTypes) { if ((Object)(object)go.GetComponent(type2) != (Object)null) { flag = true; break; } } if (!flag && !_weaponDumped) { _weaponDumped = true; StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine("[GrabPatch] Components on '" + ((Object)go).name + "' (pacifist dump):"); Component[] components = go.GetComponents<Component>(); for (int i = 0; i < components.Length; i++) { stringBuilder.AppendLine(" " + ((object)components[i])?.GetType().Name); } Plugin.Log.LogInfo((object)stringBuilder.ToString()); } _weaponVerdicts[instanceID] = flag; return flag; } internal static void OnRoundStart() { _weaponVerdicts.Clear(); } } public static class ItemDamagePatch { private struct ValueWatch { public Component Pg; public object Detector; public float PreValue; public float Deadline; public bool HolderIsLocal; public int HolderActor; } private static readonly HashSet<int> _warnedThisRound = new HashSet<int>(); private static bool _prefixHeld = false; private static bool _prefixHolderIsLocal = false; private static int _prefixHolderActor = -1; private static float _flawlessLastBreak = -10f; private static float _empathyNextHit = 0f; private static float _nitroLastExplosion = -10f; private static Component _empathyComp; private static MethodInfo _empathyMethod; private static FieldInfo _empathyField; private static bool _empathyMethodIsFloat; private static bool _empathyFieldIsFloat; private static bool _explosionResolved; private static MethodInfo _explosionMethod; private static int _explosionParamCount; private static FieldInfo _pgField; private static bool _pgFieldResolved; private static FieldInfo _isValField; private static bool _isValResolved; private static Type _voType; private static FieldInfo _dollarField; private static bool _voResolved; private static readonly List<ValueWatch> _watches = new List<ValueWatch>(); private const float WATCH_WINDOW = 0.75f; private static Type _physGrabberType; private static FieldInfo _grabbedField; private static FieldInfo _grabberIsLocalField; private static bool _grabberFieldsResolved; private static Object[] _grabbers; private static float _grabbersNextRefresh = 0f; private static Type _pgType; private static Type _detType; private static readonly Dictionary<int, Component> _voCache = new Dictionary<int, Component>(); public static void ClearDestroyedSet() { _warnedThisRound.Clear(); _watches.Clear(); } private static bool FindHolder(Component pg, out bool isLocal, out int actor) { isLocal = false; actor = -1; try { if (_physGrabberType == null) { _physGrabberType = Type.GetType("PhysGrabber, Assembly-CSharp"); } if (_physGrabberType == null) { return false; } if (!_grabberFieldsResolved) { _grabberFieldsResolved = true; _grabbedField = _physGrabberType.GetField("grabbedPhysGrabObject", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); _grabberIsLocalField = _physGrabberType.GetField("isLocal", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); } if (_grabbedField == null) { return false; } float unscaledTime = Time.unscaledTime; if (_grabbers == null || unscaledTime >= _grabbersNextRefresh) { _grabbers = Object.FindObjectsOfType(_physGrabberType); _grabbersNextRefresh = unscaledTime + 2f; } Component val = null; Object[] grabbers = _grabbers; bool flag = default(bool); foreach (Object obj in grabbers) { Component val2 = (Component)(object)((obj is Component) ? obj : null); if ((Object)(object)val2 == (Object)null) { continue; } object? value = _grabbedField.GetValue(val2); Component val3 = (Component)((value is Component) ? value : null); if (!((Object)(object)val3 == (Object)null) && !((Object)(object)val3 != (Object)(object)pg)) { object obj2 = _grabberIsLocalField?.GetValue(val2); int num; if (obj2 is bool) { flag = (bool)obj2; num = 1; } else { num = 0; } if (((uint)num & (flag ? 1u : 0u)) != 0) { isLocal = true; return true; } val = val2; } } if ((Object)(object)val != (Object)null) { PhotonView componentInParent = val.GetComponentInParent<PhotonView>(); if ((Object)(object)componentInParent != (Object)null) { actor = componentInParent.OwnerActorNr; return true; } } } catch (Exception ex) { Plugin.Log.LogError((object)("[FindHolder] " + ex.Message)); } return false; } public static bool Prefix(object __instance, MethodBase __originalMethod, ref float __state) { __state = -1f; _prefixHeld = false; string text = __originalMethod?.Name; if (text != "ImpactHeavy" && text != "ImpactMedium") { return true; } if (!ChallengeManager.InMapLevel) { return true; } bool flag = ChallengeManager.FlawlessActive || ChallengeManager.NitroFingersActive || ChallengeManager.EmpathyActive; bool flag2 = PhotonNetwork.InRoom && PhotonNetwork.IsMasterClient; if (!flag && !flag2) { return true; } try { Component physGrabObject = GetPhysGrabObject(__instance); if ((Object)(object)physGrabObject == (Object)null) { return true; } if (!IsValuable(physGrabObject)) { return true; } if (!FindHolder(physGrabObject, out var isLocal, out var actor)) { return true; } if (isLocal && !flag) { return true; } if (!isLocal && (!flag2 || actor < 0)) { return true; } _prefixHeld = true; _prefixHolderIsLocal = isLocal; _prefixHolderActor = actor; __state = ReadItemDollarValue(__instance); } catch (Exception ex) { Plugin.Log.LogError((object)("[ItemDamagePatch.Prefix] " + ex.Message)); } return true; } public static void Postfix(object __instance, MethodBase __originalMethod, float __state) { if (!_prefixHeld) { return; } string text = __originalMethod?.Name; if (text != "ImpactHeavy" && text != "ImpactMedium") { return; } try { Component physGrabObject = GetPhysGrabObject(__instance); if (!((Object)(object)physGrabObject == (Object)null)) { float num = ReadItemDollarValue(__instance); Plugin.LogVerbose($"[Impact] {text} {((Object)physGrabObject.gameObject).name} value {__state:F0} -> {num:F0}" + (_prefixHolderIsLocal ? "" : $" (held by actor {_prefixHolderActor})")); if (__state >= 0f && num >= 0f && num < __state - 0.01f) { FireOrRelay(__instance, physGrabObject, _prefixHolderIsLocal, _prefixHolderActor); } else if (text == "ImpactHeavy") { FireOrRelay(__instance, physGrabObject, _prefixHolderIsLocal, _prefixHolderActor); } else if (__state >= 0f && num >= 0f) { AddWatch(physGrabObject, __instance, __state, _prefixHolderIsLocal, _prefixHolderActor); } } } catch (Exception ex) { Plugin.Log.LogError((object)("[ItemDamagePatch.Postfix] " + ex.Message)); } } private static void FireOrRelay(object detector, Component pg, bool holderIsLocal, int holderActor) { if (holderIsLocal) { FireEffects(detector, pg); return; } PhotonView val = (((Object)(object)pg != (Object)null) ? pg.GetComponentInParent<PhotonView>() : null); if ((Object)(object)val != (Object)null) { ChallengeSync.RelayImpactToHolder(holderActor, val.ViewID); } } internal static void OnRelayedImpact(int viewID) { try { PhotonView val = PhotonView.Find(viewID); if ((Object)(object)val == (Object)null) { return; } if (_pgType == null) { _pgType = Type.GetType("PhysGrabObject, Assembly-CSharp"); } if (_detType == null) { _detType = Type.GetType("PhysGrabObjectImpactDetector, Assembly-CSharp"); } Component val2 = ((_pgType != null) ? ((Component)val).GetComponent(_pgType) : null); object obj = null; if (_detType != null) { obj = ((Component)val).GetComponent(_detType); if (obj == null) { obj = ((Component)val).GetComponentInChildren(_detType); } } Component val3 = (Component)(((Object)(object)val2 != (Object)null) ? ((object)val2) : ((object)val)); Plugin.LogVerbose("[ItemDamagePatch] Relayed impact: " + ((Object)val3.gameObject).name); FireEffects(obj, val3); } catch (Exception ex) { Plugin.Log.LogError((object)("[OnRelayedImpact] " + ex.Message)); } } internal static void DestroyByViewID(int viewID) { try { PhotonView val = PhotonView.Find(viewID); if ((Object)(object)val == (Object)null) { return; } if (_detType == null) { _detType = Type.GetType("PhysGrabObjectImpactDetector, Assembly-CSharp"); } if (_detType == null) { return; } object obj = ((Component)val).GetComponent(_detType); if (obj == null) { obj = ((Component)val).GetComponentInChildren(_detType); } if (obj != null) { if (_pgType == null) { _pgType = Type.GetType("PhysGrabObject, Assembly-CSharp"); } Component val2 = ((_pgType != null) ? ((Component)val).GetComponent(_pgType) : null); DestroyValuable(obj, obj.GetType(), (Component)(((Object)(object)val2 != (Object)null) ? ((object)val2) : ((object)val))); Plugin.Log.LogWarning((object)("[Flawless] Destroyed " + ((Object)((Component)val).gameObject).name + " (remote holder request)")); } } catch (Exception ex) { Plugin.Log.LogError((object)("[DestroyByViewID] " + ex.Message)); } } internal static void FireEffects(object detector, Component pg) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) Vector3 val = (((Object)(object)pg != (Object)null) ? pg.transform.position : Vector3.zero); float time = Time.time; bool flag = PhotonNetwork.InRoom && !PhotonNetwork.IsMasterClient; if (ChallengeManager.FlawlessActive && (Object)(object)pg != (Object)null) { int instanceID = ((Object)pg.gameObject).GetInstanceID(); if (_warnedThisRound.Add(instanceID) && time - _flawlessLastBreak >= 0.3f) { _flawlessLastBreak = time; if (flag) { PhotonView componentInParent = pg.GetComponentInParent<PhotonView>(); if ((Object)(object)componentInParent != (Object)null) { ChallengeSync.RequestDestroy(componentInParent.ViewID); } } else if (detector != null) { DestroyValuable(detector, detector.GetType(), pg); } Plugin.Log.LogWarning((object)("[Flawless] Destroyed " + ((Object)pg.gameObject).name + " (value dropped)")); ChallengeManager.OnItemDamaged(((Object)pg.gameObject).name); } } if (ChallengeManager.NitroFingersActive && time - _nitroLastExplosion >= 0.5f) { _nitroLastExplosion = time; if (flag) { ChallengeSync.RequestExplosion(val); } else { TrySpawnExplosion(val); } if ((Object)(object)pg != (Object)null) { ChallengeHUD.ShowViolation("BOOM! " + ((Object)pg.gameObject).name); } Plugin.LogVerbose($"[NitroFingers] Explosion at {val}"); } if (ChallengeManager.EmpathyActive && time >= _empathyNextHit) { _empathyNextHit = time + 0.5f; DamageLocalPlayer(Plugin.EmpathyDamagePerHit.Value); ChallengeManager.OnEmpathyHit(); } } private static void AddWatch(Component pg, object detector, float preValue, bool holderIsLocal, int holderActor) { float deadline = Time.time + 0.75f; for (int i = 0; i < _watches.Count; i++) { if ((Object)(object)_watches[i].Pg == (Object)(object)pg) { ValueWatch value = _watches[i]; if (preValue > value.PreValue) { value.PreValue = preValue; } value.Deadline = deadline; value.HolderIsLocal = holderIsLocal; value.HolderActor = holderActor; _watches[i] = value; return; } } _watches.Add(new ValueWatch { Pg = pg, Detector = detector, PreValue = preValue, Deadline = deadline, HolderIsLocal = holderIsLocal, HolderActor = holderActor }); } internal static void TickWatches() { if (_watches.Count == 0) { return; } float time = Time.time; for (int num = _watches.Count - 1; num >= 0; num--) { ValueWatch valueWatch = _watches[num]; if ((Object)(object)valueWatch.Pg == (Object)null) { _watches.RemoveAt(num); } else { float num2 = ReadItemDollarValue(valueWatch.Detector); if (num2 >= 0f && num2 < valueWatch.PreValue - 0.01f) { Plugin.LogVerbose($"[Impact] delayed drop {((Object)valueWatch.Pg.gameObject).name} {valueWatch.PreValue:F0} -> {num2:F0}"); FireOrRelay(valueWatch.Detector, valueWatch.Pg, valueWatch.HolderIsLocal, valueWatch.HolderActor); _watches.RemoveAt(num); } else if (time > valueWatch.Deadline) { _watches.RemoveAt(num); } } } } private static Component GetPhysGrabObject(object detector) { if (!_pgFieldResolved) { _pgFieldResolved = true; _pgField = detector.GetType().GetField("physGrabObject", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); } object? obj = _pgField?.GetValue(detector); return (Component)((obj is Component) ? obj : null); } private static bool IsValuable(Component pg) { if (!_isValResolved) { _isValResolved = true; _isValField = ((object)pg).GetType().GetField("isValuable", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); } object obj = _isValField?.GetValue(pg); bool flag = default(bool); int num; if (obj is bool) { flag = (bool)obj; num = 1; } else { num = 0; } return (byte)((uint)num & (flag ? 1u : 0u)) != 0; } private static void DestroyValuable(object detector, Type detType, Component pg) { //IL_00d5: Unknown result type (might be due to invalid IL or missing references) MethodInfo method = detType.GetMethod("DestroyObject", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(bool) }, null); if (method != null) { try { method.Invoke(detector, new object[1] { true }); return; } catch (Exception ex) { Plugin.Log.LogWarning((object)("[Flawless] DestroyObject threw: " + ex.Message)); } } MethodInfo method2 = detType.GetMethod("Break", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[4] { typeof(float), typeof(Vector3), typeof(int), typeof(bool) }, null); if (method2 != null) { try { method2.Invoke(detector, new object[4] { 999999f, pg.transform.position, 0, true }); return; } catch (Exception ex2) { Plugin.Log.LogWarning((object)("[Flawless] Break() threw: " + ex2.Message)); } } try { Object.Destroy((Object)(object)pg.gameObject); } catch (Exception ex3) { Plugin.Log.LogWarning((object)("[Flawless] GameObject destroy threw: " + ex3.Message)); } } internal static void TrySpawnExplosion(Vector3 pos) { //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0282: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) if (_explosionResolved) { if (_explosionMethod != null) { try { _explosionMethod.Invoke(null, (_explosionParamCount != 1) ? new object[2] { pos, 10f } : new object[1] { pos }); return; } catch { } } PhysicsExplosion(pos); return; } string[] array = new string[6] { "Explosion", "ExplosionCustom", "ExplosionManager", "GrenadeBoom", "GrenadeExplosion", "ItemExplosion" }; foreach (string text in array) { Type type = Type.GetType(text + ", Assembly-CSharp"); if (type == null) { continue; } MethodInfo[] methods = type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); foreach (MethodInfo methodInfo in methods) { if (methodInfo.Name != "Spawn" && methodInfo.Name != "Create" && methodInfo.Name != "SpawnExplosion" && methodInfo.Name != "CreateExplosion" && methodInfo.Name != "Explode") { continue; } ParameterInfo[] parameters = methodInfo.GetParameters(); if (parameters.Length != 0 && !(parameters[0].ParameterType != typeof(Vector3))) { try { methodInfo.Invoke(null, (parameters.Length != 1) ? new object[2] { pos, 10f } : new object[1] { pos }); _explosionResolved = true; _explosionMethod = methodInfo; _explosionParamCount = parameters.Length; Plugin.Log.LogInfo((object)("[Flawless] Explosion via " + text + "." + methodInfo.Name + "() (cached)")); return; } catch (Exception ex) { Plugin.Log.LogWarning((object)("[Flawless] " + text + "." + methodInfo.Name + " threw: " + ex.Message)); } } } } _explosionResolved = true; _explosionMethod = null; Plugin.Log.LogInfo((object)"[Flawless] No explosion API — using physics impulse fallback (cached)."); PhysicsExplosion(pos); } private static void PhysicsExplosion(Vector3 pos) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) Collider[] array = Physics.OverlapSphere(pos, 3f); int num = 0; Collider[] array2 = array; foreach (Collider val in array2) { if (!((Object)(object)val == (Object)null)) { Rigidbody attachedRigidbody = val.attachedRigidbody; if ((Object)(object)attachedRigidbody != (Object)null && !attachedRigidbody.isKinematic) { attachedRigidbody.AddExplosionForce(600f, pos, 3f, 1f, (ForceMode)1); num++; } } } if (num > 0) { Plugin.LogVerbose($"[Flawless] Physics explosion — pushed {num} rigidbodies"); } } internal static void ClearValueCache() { _voCache.Clear(); } private static float ReadItemDollarValue(object impactDetector) { try { Component val = (Component)((impactDetector is Component) ? impactDetector : null); if ((Object)(object)val == (Object)null) { return -1f; } if (!_voResolved) { _voResolved = true; _voType = Type.GetType("ValuableObject, Assembly-CSharp"); if (_voType != null) { _dollarField = _voType.GetField("dollarValueCurrent", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); } } if (_voType == null || _dollarField == null) { return -1f; } int instanceID = ((Object)val).GetInstanceID(); if (!_voCache.TryGetValue(instanceID, out var value) || (Object)(object)value == (Object)null) { Transform val2 = val.transform; while ((Object)(object)val2.parent != (Object)null) { val2 = val2.parent; } value = ((Component)val2).GetComponentInChildren(_voType); _voCache[instanceID] = value; } if ((Object)(object)value == (Object)null) { return -1f; } object value2 = _dollarField.GetValue(value); if (value2 is float result) { return result; } if (value2 is int num) { return num; } } catch { } return -1f; } internal static void DamageLocalPlayer(float amount) { try { if ((Object)(object)_empathyComp != (Object)null) { if (ApplyEmpathyDamage(amount)) { return; } _empathyComp = null; _empathyMethod = null; _empathyField = null; } Type type = Type.GetType("PlayerAvatar, Assembly-CSharp"); if (type == null) { Plugin.Log.LogWarning((object)"[Empathy] PlayerAvatar type not found"); return; } FieldInfo field = type.GetField("isLocal", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); Component val = null; Component[] array = Object.FindObjectsOfType(type) as Component[]; foreach (Component val2 in array) { if ((Object)(object)val2 == (Object)null) { continue; } if (field != null) { object value = field.GetValue(val2); if (value is bool && !(bool)value) { continue; } } val = val2; break; } if ((Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)"[Empathy] Local PlayerAvatar not found"); return; } array = val.gameObject.GetComponents<Component>(); foreach (Component val3 in array) { if ((Object)(object)val3 == (Object)null) { continue; } Type type2 = ((object)val3).GetType(); string[] array2 = new string[7] { "HurtLocal", "Hurt", "TakeDamage", "DealDamage", "HurtPlayer", "ApplyDamage", "Damage" }; foreach (string text in array2) { MethodInfo method = type2.GetMethod(text, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(float) }, null); if (method != null) { _empathyComp = val3; _empathyMethod = method; _empathyMethodIsFloat = true; Plugin.Log.LogInfo((object)("[Empathy] Damage via " + type2.Name + "." + text + "(float) (cached)")); ApplyEmpathyDamage(amount); return; } MethodInfo method2 = type2.GetMethod(text, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(int) }, null); if (method2 != null) { _empathyComp = val3; _empathyMethod = method2; _empathyMethodIsFloat = false; Plugin.Log.LogInfo((object)("[Empathy] Damage via " + type2.Name + "." + text + "(int) (cached)")); ApplyEmpathyDamage(amount); return; } } array2 = new string[7] { "health", "hp", "currentHealth", "playerHealth", "hitPoints", "HP", "maxHealth" }; foreach (string text2 in array2) { FieldInfo field2 = type2.GetField(text2, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (!(field2 == null)) { object value2 = field2.GetValue(val3); if (value2 is float || value2 is int) { _empathyComp = val3; _empathyField = field2; _empathyFieldIsFloat = value2 is float; Plugin.Log.LogInfo((object)("[Empathy] Damage via field " + type2.Name + "." + text2 + " (cached)")); ApplyEmpathyDamage(amount); return; } } } } Plugin.Log.LogWarning((object)"[Empathy] No damage method/field found."); } catch (Exception ex) { Plugin.Log.LogError((object)("[DamageLocalPlayer] " + ex.Message)); } } private static bool ApplyEmpathyDamage(float amount) { if ((Object)(object)_empathyComp == (Object)null) { return false; } try { if (_empathyMethod != null) { _empathyMethod.Invoke(_empathyComp, (!_empathyMethodIsFloat) ? new object[1] { (int)amount } : new object[1] { amount }); Plugin.LogVerbose($"[Empathy] -{amount}hp (cached method)"); return true; } if (_empathyField != null) { object value = _empathyField.GetValue(_empathyComp); if (_empathyFieldIsFloat && value is float num) { _empathyField.SetValue(_empathyComp, Mathf.Max(0f, num - amount)); } else { if (_empathyFieldIsFloat || !(value is int num2)) { return false; } _empathyField.SetValue(_empathyComp, Mathf.Max(0, num2 - (int)amount)); } Plugin.LogVerbose($"[Empathy] -{amount}hp (cached field)"); return true; } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[Empathy] cached apply failed: " + ex.Message)); return false; } return false; } } public static class ShortRangePatch { private const string RANGE_FIELD = "grabRange"; private static float _originalRange = -1f; private static float _preChallengeRange = -1f; private static float _targetRange = -1f; private static bool _challengeWasActive = false; private static FieldInfo _isLocalFld; private static FieldInfo _rangeFld; private static bool _fieldsResolved; public static void Postfix(object __instance) { try { Type type = __instance.GetType(); if (!_fieldsResolved) { _fieldsResolved = true; _isLocalFld = type.GetField("isLocal", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); _rangeFld = type.GetField("grabRange", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); } if (_isLocalFld != null) { object value = _isLocalFld.GetValue(__instance); if (value is bool && !(bool)value) { return; } } FieldInfo rangeFld = _rangeFld; if (rangeFld == null) { return; } float num = (float)rangeFld.GetValue(__instance); if (_originalRange < 0f) { _originalRange = num; ChallengeManager.ShortRangeOriginalValue = num; Plugin.Log.LogInfo((object)string.Format("[ShortRange] Base grab range = {0:F2} (field: {1})", num, "grabRange")); } bool shortRangeActive = ChallengeManager.ShortRangeActive; if (!shortRangeActive) { ChallengeManager.ShortRangeCurrentValue = num; } if (!shortRangeActive) { if (_challengeWasActive) { _challengeWasActive = false; if (_preChallengeRange >= 0f) { rangeFld.SetValue(__instance, _preChallengeRange); } Plugin.Log.LogInfo((object)$"[ShortRange] Ended — range restored to {_preChallengeRange:F2}"); _targetRange = -1f; _preChallengeRange = -1f; } return; } if (!_challengeWasActive) { _challengeWasActive = true; _preChallengeRange = num; float num2 = (float)Plugin.ShortRangeReductionPercent.Value / 100f; _targetRange = (Plugin.ShortRangeUseOriginal.Value ? _originalRange : num) * (1f - num2); Plugin.Log.LogInfo((object)($"[ShortRange] Activated — original={_originalRange:F2} " + $"current={num:F2} useOriginal={Plugin.ShortRangeUseOriginal.Value} " + $"reduction={num2 * 100f:F0}% target={_targetRange:F2}")); } if (num != _targetRange) { rangeFld.SetValue(__instance, _targetRange); } } catch (Exception ex) { Plugin.Log.LogError((object)("[ShortRangePatch] " + ex.Message)); } } } public static class PlayerHealthDamagePatch { private static FieldInfo _avatarField; private static FieldInfo _isLocalField; private static bool _resolved; public static void Prefix(object __instance, ref int damage) { if (!ChallengeManager.BetterTogetherActive) { return; } float betterTogetherDamageReduction = ChallengeManager.BetterTogetherDamageReduction; if (betterTogetherDamageReduction <= 0f || damage <= 0) { return; } try { if (!_resolved) { _resolved = true; _avatarField = __instance.GetType().GetField("playerAvatar", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); _isLocalField = Type.GetType("PlayerAvatar, Assembly-CSharp")?.GetField("isLocal", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); } object obj = _avatarField?.GetValue(__instance); if (obj == null) { return; } object obj2 = _isLocalField?.GetValue(obj); if (obj2 is bool && (bool)obj2) { int num = Mathf.CeilToInt((float)damage * (1f - betterTogetherDamageReduction)); if (num < 1) { num = 1; } damage = num; } } catch (Exception ex) { Plugin.Log.LogError((object)("[PlayerHealthDamagePatch] " + ex.Message)); } } } public static class LevelStartPatch { public static void Postfix() { try { Plugin.Log.LogInfo((object)"[LevelStartPatch] GameDirector.SetStart fired."); ChallengeManager.OnRoundStart(); } catch (Exception ex) { Plugin.Log.LogError((object)("[LevelStartPatch] FAILED: " + ex.Message + "\n" + ex.StackTrace)); } } } internal static class HeldItemTicker { public static void Tick() { ItemDamagePatch.TickWatches(); } public static void OnRoundStart() { } public static void OnSceneLoad() { } } [BepInPlugin("com.gynxz.repochallenges", "Gynxz: RepoChallenges", "1.5.1")] public class Plugin : BaseUnityPlugin { public const string GUID = "com.gynxz.repochallenges"; public const string MOD_NAME = "Gynxz: RepoChallenges"; public const string VERSION = "1.5.1"; internal static ManualLogSource Log; internal static Plugin Instance; internal static bool Ready = false; internal static bool UpdaterCreated = false; internal static ConfigEntry<bool> DebugKeysEnabled; internal static ConfigEntry<bool> VerboseLogging; internal static ConfigEntry<KeyboardShortcut> CycleKey; internal static ConfigEntry<KeyboardShortcut> ClearKey; internal static ConfigEntry<bool> ChallengeScopePerRound; internal static ConfigEntry<float> CheckInterval; internal static ConfigEntry<float> CartLeashMaxDistance; internal static ConfigEntry<float> CartLeashSlowStartDistance; internal static ConfigEntry<int> CartLeashSlowPercent; internal static ConfigEntry<int> ExpensiveItemThreshold; internal static ConfigEntry<int> EmpathyDamagePerHit; internal static ConfigEntry<bool> AutoAssignOnRoundStart; internal static ConfigEntry<bool> ShortRangeUseOriginal; internal static ConfigEntry<int> ShortRangeReductionPercent; internal static ConfigEntry<BetterTogetherMode> BetterTogetherModeCfg; internal static ConfigEntry<float> BetterTogetherRadius; internal static ConfigEntry<int> BetterTogetherMaxStack; internal static ConfigEntry<int> BetterTogetherSpeedPerPlayer; internal static ConfigEntry<int> BetterTogetherStrengthPerPlayer; internal static ConfigEntry<int> BetterTogetherStaminaRegenPerPlayer; internal static ConfigEntry<int> BetterTogetherMaxExtraJumps; internal static ConfigEntry<int> BetterTogetherDamageReductionPerPlayer; internal static ConfigEntry<int> BetterTogetherDamageReductionMax; internal static ConfigEntry<bool> BetterTogetherShowGlow; internal static ConfigEntry<bool> BetterTogetherEnableSpeed; internal static ConfigEntry<bool> BetterTogetherEnableJump; internal static ConfigEntry<bool> BetterTogetherEnableStamina; internal static ConfigEntry<bool> BetterTogetherEnableStrength; internal static ConfigEntry<bool> BetterTogetherEnableDamageReduction; internal static ConfigEntry<bool> HudEnabled; internal static ConfigEntry<int> HudPositionX; internal static ConfigEntry<int> HudPositionY; internal static ConfigEntry<int> HudFontSize; internal static ConfigEntry<bool> HudShowDescription; internal static ConfigEntry<bool> HudShowOtherPlayers; internal static ConfigEntry<bool> DisableUIAlerts; internal static ConfigEntry<bool> SbEnabled; internal static ConfigEntry<string> NameAliases; internal static ConfigEntry<string> ManualTarget; internal static ConfigEntry<string> ManualChallenge; internal static ConfigEntry<bool> ManualAssignTrigger; internal static ConfigEntry<bool> ManualClearTrigger; internal static Dictionary<string, ConfigEntry<ChallengeMode>> RosterModes; private static readonly string BASE_PATH = ComputeBasePath(); public static readonly string CMD_FILE = Path.Combine(BASE_PATH, "challenge_cmd.txt"); public static readonly string STATUS_FILE = Path.Combine(BASE_PATH, "challenge_status.txt"); public static readonly string LIST_FILE = Path.Combine(BASE_PATH, "challenge_list.txt"); public static readonly string PLAYERS_FILE = Path.Combine(BASE_PATH, "challenge_players.txt"); public static readonly string IDS_FILE = Path.Combine(BASE_PATH, "challenge_ids.txt"); public static readonly string ALIASES_FILE = Path.Combine(BASE_PATH, "challenge_aliases.txt"); private Harmony _harmony; private float _pollTimer; private bool _updateOnce; private static string _pendingCmd = null; internal static ChallengeMode GetMode(string id) { if (RosterModes != null && RosterModes.TryGetValue(id, out var value)) { return value.Value; } return ChallengeMode.Off; } internal static void LogVerbose(string msg) { if (VerboseLogging != null && VerboseLogging.Value) { ManualLogSource log = Log; if (log != null) { log.LogInfo((object)msg); } } } private static string ComputeBasePath() { try { string text = Directory.GetParent(Paths.BepInExRootPath)?.FullName; if (!string.IsNullOrEmpty(text)) { return text; } } catch { } return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Thunderstore Mod Manager\\DataFolder\\REPO\\profiles\\REPO"); } private void Awake() { //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Expected O, but got Unknown try { Instance = this; Log = ((BaseUnityPlugin)this).Logger; BindConfig(); Log.LogInfo((object)"[Plugin] Config bound."); ChallengeRegistry.RegisterAll(); Log.LogInfo((object)("[Plugin] Registered: " + string.Join(", ", ChallengeRegistry.AllIds()))); BindRosterConfig(); BindManualAssign(); _harmony = new Harmony("com.gynxz.repochallenges"); Patches.PatchAll(_harmony); Log.LogInfo((object)"[Plugin] Patches applied."); ChallengeManager.ReconcileRoster(); if (SbEnabled.Value) { WriteListFile(); TryClearCmd(); WriteStatus(); Log.LogInfo((object)("[Plugin] File bridge ready. CMD: " + CMD_FILE)); } Ready = true; Log.LogInfo((object)"Gynxz: RepoChallenges v1.5.1 ready."); } catch (Exception ex) { ManualLogSource log = Log; if (log != null) { log.LogError((object)("[Plugin] Awake() FAILED: " + ex.Message + "\n" + ex.StackTrace)); } } } private void OnDestroy() { Log.LogWarning((object)"[Plugin] OnDestroy() — BepInEx lifecycle, ignoring."); } private void Update() { //IL_003f: 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_0047: 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_0071: 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) if (!Ready) { return; } if (!_updateOnce) { _updateOnce = true; Log.LogInfo((object)"[Plugin] Update() is alive."); } if (UpdaterCreated) { return; } if (DebugKeysEnabled.Value) { KeyboardShortcut value = CycleKey.Value; if (IsKeyDown(((KeyboardShortcut)(ref value)).MainKey)) { Log.LogInfo((object)"[Plugin] Cycle key pressed."); ChallengeManager.CycleChallenge(); } value = ClearKey.Value; if (IsKeyDown(((KeyboardShortcut)(ref value)).MainKey)) { Log.LogInfo((object)"[Plugin] Clear key pressed."); ChallengeManager.ClearChallenge(); } } if (SbEnabled.Value) { _pollTimer += Time.unscaledDeltaTime; if (!(_pollTimer < CheckInterval.Value)) { _pollTimer = 0f; PollCmdFile(); } } } internal static void PollCmdFile() { try { if (!File.Exists(CMD_FILE)) { return; } string text = File.ReadAllText(CMD_FILE); string text2 = ((text == null) ? "" : text.Trim().ToLowerInvariant()); if (text2.Length != 0 && !(text2 == _pendingCmd)) { try { File.WriteAllText(CMD_FILE, ""); _pendingCmd = null; } catch { _pendingCmd = text2; } Log.LogInfo((object)("[Bridge] Command: '" + text2 + "'")); ExecuteBridgeCommand(text2); } } catch (Exception ex) { Log.LogError((object)("[Bridge] Poll error: " + ex.Message)); } } internal static void ExecuteBridgeCommand(string cmd) { bool flag = cmd.IndexOf('+') >= 0; if (flag) { cmd = cmd.Replace("+", ""); } string targetName = null; string text = null; bool flag2 = false; bool flag3 = false; string[] array = cmd.Split(new char[1] { ',' }); for (int i = 0; i < array.Length; i++) { string text2 = array[i].Trim().Trim('<', '>', '"', '\'').Trim(); if (text2.Length != 0) { if (text2.StartsWith("player:", StringComparison.Ordinal)) { targetName = text2.Substring(7).Trim().Trim('<', '>') .Trim(); } else if (text2.StartsWith("challenge:", StringComparison.Ordinal)) { text = text2.Substring(10).Trim(); } else if (text2 == "clear") { flag2 = true; } else if (text2 == "random") { flag3 = true; } else { text = text2; } } } if (flag2) { ChallengeSync.SendClear(targetName); } else if (flag3) { ChallengeSync.SendChallenge(targetName, ChallengeRegistry.GetRandom()?.Id ?? "", flag); } else if (!string.IsNullOrEmpty(text)) { if (!ChallengeRegistry.Has(text)) { Log.LogWarning((object)("[Bridge] Unknown challenge id: '" + text + "'")); } else { ChallengeSync.SendChallenge(targetName, text, flag); } } else { Log.LogWarning((object)("[Bridge] Could not parse command: '" + cmd + "'")); } WriteStatus(); } private void WriteListFile() { try { Directory.CreateDirectory(BASE_PATH); StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine("# Valid challenge ids — write one to: " + CMD_FILE); stringBuilder.AppendLine("# Special commands: clear, random"); stringBuilder.AppendLine("# Add a '+' to STACK instead of replace, e.g.: no_map+"); stringBuilder.AppendLine("# Target a player: player:<name>,challenge:<id> or player:<name>,clear"); stringBuilder.AppendLine(); foreach (BaseChallenge item in ChallengeRegistry.All) { stringBuilder.AppendLine($"{item.Id,-20} # {item.DisplayName}"); } File.WriteAllText(LIST_FILE, stringBuilder.ToString()); StringBuilder stringBuilder2 = new StringBuilder(); foreach (BaseChallenge item2 in ChallengeRegistry.All) { stringBuilder2.AppendLine(item2.Id); } File.WriteAllText(IDS_FILE, stringBuilder2.ToString()); if (!File.Exists(ALIASES_FILE)) { File.WriteAllText(ALIASES_FILE, "# Twitch/chat name = Steam name — one pair per line (or ; separated).\r\n# Read LIVE: edit this file anytime, even while the game is running.\r\n# Lines starting with # are ignored. Names are not case sensitive.\r\n# Example:\r\n# Kahzimeira=Kahzi\r\n"); } } catch (Exception ex) { Log.LogError((object)("[Plugin] WriteListFile: " + ex.Message)); } } public static void WriteStatus() { try { List<BaseChallenge> list = ChallengeManager.ActiveChallenges.ToList(); string contents = ((list.Count == 0) ? "active: none" : ("active: " + string.Join(", ", list.Select((BaseChallenge a) => a.Id + " | " + a.DisplayName)))); File.WriteAllText(STATUS_FILE, contents); } catch { } } private static void TryClearCmd() { try { File.WriteAllText(CMD_FILE, ""); } catch { } } internal static void EnsureUpdaterCreated() { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Expected O, but got Unknown //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown if (UpdaterCreated) { return; } UpdaterCreated = true; try { if (HudEnabled.Value) { GameObject val = new GameObject("GynxzChallengeHUD"); Object.DontDestroyOnLoad((Object)val); val.AddComponent<ChallengeHUD>(); Log.LogInfo((object)"[Plugin] HUD created from gameplay context."); } GameObject val2 = new GameObject("GynxzChallengeUpdater_Live"); Object.DontDestroyOnLoad((Object)val2); val2.AddComponent<ChallengeUpdater>(); Log.LogInfo((object)"[Plugin] Updater created from gameplay context."); ChallengeSync.Create(); Log.LogInfo((object)"[Plugin] ChallengeSync created."); } catch (Exception ex) { Log.LogError((object)("[Plugin] EnsureUpdaterCreated failed: " + ex.Message)); } } internal static bool IsKeyDown(KeyCode kc) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Expected I4, but got Unknown //IL_0215: Unknown result type (might be due to invalid IL or missing references) try { Keyboard current = Keyboard.current; if (current != null) { switch (kc - 256) { case 26: return ((ButtonControl)current.f1Key).wasPressedThisFrame; case 27: return ((ButtonControl)current.f2Key).wasPressedThisFrame; case 28: return ((ButtonControl)current.f3Key).wasPressedThisFrame; case 29: return ((ButtonControl)current.f4Key).wasPressedThisFrame; case 30: return ((ButtonControl)current.f5Key).wasPressedThisFrame; case 31: return ((ButtonControl)current.f6Key).wasPressedThisFrame; case 32: return ((ButtonControl)current.f7Key).wasPressedThisFrame; case 33: return ((ButtonControl)current.f8Key).wasPressedThisFrame; case 34: return ((ButtonControl)current.f9Key).wasPressedThisFrame; case 35: return ((ButtonControl)current.f10Key).wasPressedThisFrame; case 36: return ((ButtonControl)current.f11Key).wasPressedThisFrame; case 37: return ((ButtonControl)current.f12Key).wasPressedThisFrame; case 0: return ((ButtonControl)current.numpad0Key).wasPressedThisFrame; case 1: return ((ButtonControl)current.numpad1Key).wasPressedThisFrame; case 2: return ((ButtonControl)current.numpad2Key).wasPressedThisFrame; case 3: return ((ButtonControl)current.numpad3Key).wasPressedThisFrame; case 4: return ((ButtonControl)current.numpad4Key).wasPressedThisFrame; case 5: return ((ButtonControl)current.numpad5Key).wasPressedThisFrame; case 6: return ((ButtonControl)current.numpad6Key).wasPressedThisFrame; case 7: return ((ButtonControl)current.numpad7Key).wasPressedThisFrame; case 8: return ((ButtonControl)current.numpad8Key).wasPressedThisFrame; case 9: return ((ButtonControl)current.numpad9Key).wasPressedThisFrame; case 10: case 11: case 12: case 13: case 14: case 15: case 16: case 17: case 18: case 19: case 20: case 21: case 22: case 23: case 24: case 25: break; } } } catch { } return Input.GetKeyDown(kc); } private void BindConfig() { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Expected O, but got Unknown //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Expected O, but got Unknown //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Expected O, but got Unknown //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Expected O, but got Unknown //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Expected O, but got Unknown //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Expected O, but got Unknown //IL_0256: Unknown result type (might be due to invalid IL or missing references) //IL_0260: Expected O, but got Unknown //IL_02d3: Unknown result type (might be due to invalid IL or missing references) //IL_02dd: Expected O, but got Unknown //IL_0304: Unknown result type (might be due to invalid IL or missing references) //IL_030e: Expected O, but got Unknown //IL_0337: Unknown result type (might be due to invalid IL or missing references) //IL_0341: Expected O, but got Unknown //IL_036a: Unknown result type (might be due to invalid IL or missing references) //IL_0374: Expected O, but got Unknown //IL_039b: Unknown result type (might be due to invalid IL or missing references) //IL_03a5: Expected O, but got Unknown //IL_03cc: Unknown result type (might be due to invalid IL or missing references) //IL_03d6: Expected O, but got Unknown //IL_03ff: Unknown result type (might be due to invalid IL or missing references) //IL_0409: Expected O, but got Unknown //IL_0432: Unknown result type (might be due to invalid IL or missing references) //IL_043c: Expected O, but got Unknown //IL_0588: Unknown result type (might be due to invalid IL or missing references) //IL_0592: Expected O, but got Unknown DebugKeysEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("0 - Debug", "DebugKeysEnabled", true, "Enable F8 (cycle challenge) and F9 (clear challenge) hotkeys."); CycleKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("0 - Debug", "CycleKey", new KeyboardShortcut((KeyCode)289, Array.Empty<KeyCode>()), "Cycle through challenges."); ClearKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("0 - Debug", "ClearKey", new KeyboardShortcut((KeyCode)290, Array.Empty<KeyCode>()), "Clear active challenge."); VerboseLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("0 - Debug", "VerboseLogging", false, "Log per-event spam (violations, explosions, grab blocks) to LogOutput.log. Leave OFF for performance — heavy logging during bursts can cause frame hitches."); ChallengeScopePerRound = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - Challenges", "ChallengeScopePerRound", true, "true = challenge clears at the start of each new level."); CheckInterval = ((BaseUnityPlugin)this).Config.Bind<float>("1 - Challenges", "CheckInterval", 0.5f, new ConfigDescription("How often (seconds) the mod runs its background checks — the Better Together proximity scan and the command-file poll. Lower = more responsive but more work per second. If you notice frame drops, stutters, or network hitches/disconnects, raise this (e.g. 1–2s) to lighten the load.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 5f), Array.Empty<object>())); CartLeashMaxDistance = ((BaseUnityPlugin)this).Config.Bind<float>("1 - Challenges", "CartLeashMaxDistance", 5f, new ConfigDescription("Distance from cart for full stop.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 15f), Array.Empty<object>())); CartLeashSlowStartDistance = ((BaseUnityPlugin)this).Config.Bind<float>("1 - Challenges", "CartLeashSlowStartDistance", 3f, new ConfigDescription("Distance from cart where slowdown begins (must be less than CartLeashMaxDistance).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 15f), Array.Empty<object>())); CartLeashSlowPercent = ((BaseUnityPlugin)this).Config.Bind<int>("1 - Challenges", "CartLeashSlowPercent", 50, new ConfigDescription("Speed reduction % in the slow zone between SlowStart and MaxDistance.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>())); ExpensiveItemThreshold = ((BaseUnityPlugin)this).Config.Bind<int>("1 - Challenges", "ExpensiveItemThreshold", 5000, new ConfigDescription("Value threshold for Frugal/ExpensiveOnly.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(100, 15000), Array.Empty<object>())); ShortRangeUseOriginal = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - Challenges", "ShortRangeUseOriginal", true, "true = reduction is based on the original base grab range (ignores upgrades). false = reduction is based on the current grab range at the time the challenge is assigned."); ShortRangeReductionPercent = ((BaseUnityPlugin)this).Config.Bind<int>("1 - Challenges", "ShortRangeReductionPercent", 50, new ConfigDescription("Percentage to reduce grab range for the Short Range challenge.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 99), Array.Empty<object>())); EmpathyDamagePerHit = ((BaseUnityPlugin)this).Config.Bind<int>("1 - Challenges", "EmpathyDamagePerHit", 5, new ConfigDescription("HP the Empathetic challenge deals to you per item hit.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 25), Array.Empty<object>())); AutoAssignOnRoundStart = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - Challenges", "AutoAssignOnRoundStart", false, "Auto-assign random challenge each level."); BetterTogetherModeCfg = ((BaseUnityPlugin)this).Config.Bind<BetterTogetherMode>("1 - Challenges", "BetterTogetherMode", BetterTogetherMode.AllScaling, "AllScaling = every buff active, strength grows per nearby live player. RandomPerPlayer = each nearby player grants ONE random buff (stable until the count changes)."); BetterTogetherRadius = ((BaseUnityPlugin)this).Config.Bind<float>("1 - Challenges", "BetterTogetherRadius", 8f, new ConfigDescription("Distance (units) a live teammate must be within to count.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 20f), Array.Empty<object>())); BetterTogetherMaxStack = ((BaseUnityPlugin)this).Config.Bind<int>("1 - Challenges", "BetterTogetherMaxStack", 3, new ConfigDescription("Max nearby players counted (caps how strong the buffs get).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 5), Array.Empty<object>())); BetterTogetherSpeedPerPlayer = ((BaseUnityPlugin)this).Config.Bind<int>("1 - Challenges", "BetterTogetherSpeedPerPlayer", 15, new ConfigDescription("Speed bonus % per nearby player.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>())); BetterTogetherStrengthPerPlayer = ((BaseUnityPlugin)this).Config.Bind<int>("1 - Challenges", "BetterTogetherStrengthPerPlayer", 20, new ConfigDescription("Grab-strength bonus % per nearby player (experimental — uses the grab override).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 50), Array.Empty<object>())); BetterTogetherStaminaRegenPerPlayer = ((BaseUnityPlugin)this).Config.Bind<int>("1 - Challenges", "BetterTogetherStaminaRegenPerPlayer", 5, new ConfigDescription("Bonus stamina/sec restored per nearby player.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 5), Array.Empty<object>())); BetterTogetherMaxExtraJumps = ((BaseUnityPlugin)this).Config.Bind<int>("1 - Challenges", "BetterTogetherMaxExtraJumps", 2, new ConfigDescription("Cap on extra (mid-air) jumps granted while together.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 5), Array.Empty<object>())); BetterTogetherDamageReductionPerPlayer = ((BaseUnityPlugin)this).Config.Bind<int>("1 - Challenges", "BetterTogetherDamageReductionPerPlayer", 10, new ConfigDescription("Damage reduction % per nearby player.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 40), Array.Empty<object>())); BetterTogetherDamageReductionMax = ((BaseUnityPlugin)this).Config.Bind<int>("1 - Challenges", "BetterTogetherDamageReductionMax", 50, new ConfigDescription("Hard cap on total damage reduction % (never fully immune).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 50), Array.Empty<object>())); BetterTogetherShowGlow = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - Challenges", "BetterTogetherShowGlow", false, "Add a glow light on your character that brightens with more nearby allies."); BetterTogetherEnableSpeed = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - Challenges", "BetterTogetherEnableSpeed", true, "Include the SPEED buff in Better Together."); BetterTogetherEnableJump = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - Challenges", "BetterTogetherEnableJump", true, "Include the EXTRA JUMP buff in Better Together."); BetterTogetherEnableStamina = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - Challenges", "BetterTogetherEnableStamina", true, "Include the STAMINA buff in Better Together."); BetterTogetherEnableStrength = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - Challenges", "BetterTogetherEnableStrength", true, "Include the GRAB STRENGTH buff in Better Together."); BetterTogetherEnableDamageReduction = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - Challenges", "BetterTogetherEnableDamageReduction", true, "Include the DAMAGE REDUCTION buff in Better Together."); HudEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("2 - HUD", "Enabled", true, "Show challenge HUD."); HudPositionX = ((BaseUnityPlugin)this).Config.Bind<int>("2 - HUD", "PositionX", 12, "Horizontal offset."); HudPositionY = ((BaseUnityPlugin)this).Config.Bind<int>("2 - HUD", "PositionY", 12, "Vertical offset."); HudFontSize = ((BaseUnityPlugin)this).Config.Bind<int>("2 - HUD", "FontSize", 18, new ConfigDescription("HUD font size.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 40), Array.Empty<object>())); HudShowDescription = ((BaseUnityPlugin)this).Config.Bind<bool>("2 - HUD", "ShowDescription", true, "Show challenge description."); HudShowOtherPlayers = ((BaseUnityPlugin)this).Config.Bind<bool>("2 - HUD", "ShowOtherPlayers", true, "Show other players challenges."); DisableUIAlerts = ((BaseUnityPlugin)this).Config.Bind<bool>("2 - HUD", "DisableUIAlerts", false, "Suppress the centre-screen violation flashes (cart leash, frugal/expensive, flawless break, nitro BOOM, empathy hit, etc.). The challenge list and persistent banners (e.g. Text Only) still show — this only hides the transient red alerts."); SbEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("4 - Bot / File Bridge", "Enabled", true, "Watch challenge_cmd.txt for commands. Any tool that can write a text file can drive the mod (chat bots, macros, scripts). Streamer.bot is recommended but not required."); NameAliases = ((BaseUnityPlugin)this).Config.Bind<string>("4 - Bot / File Bridge", "NameAliases", "", "Map chat/Twitch names to in-game Steam names so player-targeted commands resolve. Format: TwitchName=SteamName, pairs separated by ';', ',' or new lines. Not case sensitive. Example: Kahzimeira=Kahzi; Bob123=Bobby"); } private void BindRosterConfig() { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected O, but got Unknown RosterModes = new Dictionary<string, ConfigEntry<ChallengeMode>>(StringComparer.OrdinalIgnoreCase); foreach (BaseChallenge item in ChallengeRegistry.All) { ConfigEntry<ChallengeMode> val = ((BaseUnityPlugin)this).Config.Bind<ChallengeMode>("5 - Challenge Roster", item.Id, ChallengeMode.Off, new ConfigDescription(item.DisplayName + ". Active = always enforced (stacks with other Active challenges). Available = part of the F8 rotation. Off = disabled. NOTE: setting ANY challenge to Active disables F8.", (AcceptableValueBase)null, Array.Empty<object>())); val.SettingChanged += delegate { try { ChallengeManager.ReconcileRoster(); } catch (Exception ex) { Log.LogError((object)("[Roster] Reconcile failed: " + ex.Message)); } }; RosterModes[item.Id] = val; } Log.LogInfo((object)$"[Plugin] Roster config bound for {RosterModes.Count} challenges."); } private void BindManualAssign() { //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Expected O, but got Unknown string[] array = ChallengeRegistry.All.Select((BaseChallenge c) => c.Id).ToArray(); string text = ((array.Length != 0) ? array[0] : ""); ManualTarget = ((BaseUnityPlugin)this).Config.Bind<string>("3 - Manual Assign", "Target", "", "Player to target — Steam name, or a Twitch/alias name from NameAliases. Leave blank to target yourself."); ManualChallenge = ((BaseUnityPlugin)this).Config.Bind<string>("3 - Manual Assign", "Challenge", text, new ConfigDescription("Challenge to assign when you flip 'Assign now'.", (AcceptableValueBase)(object)new AcceptableValueList<string>(array), Array.Empty<object>())); ManualAssignTrigger = ((BaseUnityPlugin)this).Config.Bind<bool>("3 - Manual Assign", "Assign now", false, "Flip ON to assign the chosen Challenge to Target. Resets to OFF automatically."); ManualAssignTrigger.SettingChanged += delegate { if (!ManualAssignTrigger.Value) { return; } try { string text2 = (string.IsNullOrWhiteSpace(ManualTarget.Value) ? null : ManualTarget.Value.Trim()); string value = ManualChallenge.Value; Log.LogInfo((object)("[ManualAssign] Assign '" + value + "' → " + (tex