using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Challenges.Components;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Jay")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Challenges")]
[assembly: AssemblyTitle("Challenges")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace Challenges
{
[BepInPlugin("jaydev.Challenges", "Challenges", "0.1.0")]
public class Challenges : BaseUnityPlugin
{
internal static Challenges Instance { get; private set; }
internal static ManualLogSource Logger => Instance._logger;
private ManualLogSource _logger => ((BaseUnityPlugin)this).Logger;
internal Harmony? Harmony { get; set; }
private void Awake()
{
Instance = this;
((Component)this).gameObject.transform.parent = null;
((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
ConfigManager.Init();
Patch();
Logger.LogInfo((object)"模組載入完成!");
}
internal void Patch()
{
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Expected O, but got Unknown
//IL_0026: Expected O, but got Unknown
if (Harmony == null)
{
Harmony val = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID);
Harmony val2 = val;
Harmony = val;
}
Harmony.PatchAll();
}
internal void Unpatch()
{
Harmony? harmony = Harmony;
if (harmony != null)
{
harmony.UnpatchSelf();
}
}
private void Update()
{
}
}
public static class ConfigManager
{
private static readonly ConfigFile configFile = new ConfigFile(Path.Combine(Paths.ConfigPath, "Challenges.cfg"), true);
private static ConfigEntry<bool> _orbsOnly;
private static ConfigEntry<bool> _enableRespawnTimer;
private static ConfigEntry<int> _respawnTimeMultiplier;
private static ConfigEntry<int> _orbsLimit;
public static bool OrbsOnly => _orbsOnly.Value;
public static bool EnableRespawnTimer => _enableRespawnTimer.Value;
public static int RespawnTimeMultiplier => _respawnTimeMultiplier.Value;
public static int OrbsLimit => _orbsLimit.Value;
public static void Init()
{
//IL_0062: Unknown result type (might be due to invalid IL or missing references)
//IL_006c: Expected O, but got Unknown
//IL_0093: Unknown result type (might be due to invalid IL or missing references)
//IL_009d: Expected O, but got Unknown
_orbsOnly = configFile.Bind<bool>("Challenges", "Orbs Only", false, "Enable orbs only challenge");
_enableRespawnTimer = configFile.Bind<bool>("Utilities", "Respawn Timer", false, "Enable monster respawn timer");
_respawnTimeMultiplier = configFile.Bind<int>("Utilities", "Respawn Time Multiplier", 0, new ConfigDescription("The multiplier for monster respawn time by percentage", (AcceptableValueBase)(object)new AcceptableValueRange<int>(-100, 100), Array.Empty<object>()));
_orbsLimit = configFile.Bind<int>("Utilities", "Orbs Limit", 3, new ConfigDescription("The maximum amount of orbs a monster can drop (-1 = unlimited / 0 = no orbs)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(-1, 100), Array.Empty<object>()));
}
}
}
namespace Challenges.Patches
{
[HarmonyPatch(typeof(EnemyHealth))]
public static class EnemyHealthPatch
{
[HarmonyPostfix]
[HarmonyPatch("Awake")]
public static void AdjustOrbDropLimit(EnemyHealth __instance)
{
int orbsLimit = ConfigManager.OrbsLimit;
if (orbsLimit == 0)
{
__instance.spawnValuable = false;
}
else
{
__instance.spawnValuableMax = ((orbsLimit == -1) ? int.MaxValue : orbsLimit);
}
}
}
[HarmonyPatch(typeof(EnemyParent))]
public static class EnemyParentPatch
{
[HarmonyPostfix]
[HarmonyPatch("Despawn")]
public static void AdjustRespawnTimer(EnemyParent __instance)
{
int respawnTimeMultiplier = ConfigManager.RespawnTimeMultiplier;
if (respawnTimeMultiplier != 0)
{
__instance.DespawnedTimer += __instance.DespawnedTimer * (float)respawnTimeMultiplier / 100f;
}
}
}
[HarmonyPatch(typeof(ExtractionPoint))]
public static class ExtractionPointPatch
{
private static FieldInfo totalHaulField = AccessTools.Field(typeof(RoundDirector), "totalHaul");
[HarmonyPrefix]
[HarmonyPatch("DestroyAllPhysObjectsInHaulList")]
public static bool DestroyAllOrbs()
{
if (!ConfigManager.OrbsOnly || !SemiFunc.IsMasterClientOrSingleplayer())
{
return true;
}
foreach (PlayerAvatar player in GameDirector.instance.PlayerList)
{
player.playerDeathHead.Revive();
}
int num = 0;
foreach (GameObject dollarHaul in RoundDirector.instance.dollarHaulList)
{
if (Object.op_Implicit((Object)(object)dollarHaul) && Object.op_Implicit((Object)(object)dollarHaul.GetComponent<PhysGrabObject>()))
{
ValuableObject component = dollarHaul.GetComponent<ValuableObject>();
if (Object.op_Implicit((Object)(object)component) && Regex.IsMatch(((Object)component).name, "Enemy Valuable - (Small|Medium|Big)\\(Clone\\)"))
{
num += (int)(float)AccessTools.Field(typeof(ValuableObject), "dollarValueCurrent").GetValue(component);
dollarHaul.GetComponent<PhysGrabObject>().DestroyPhysGrabObject();
}
}
}
totalHaulField.SetValue(RoundDirector.instance, num);
return false;
}
[HarmonyPrefix]
[HarmonyPatch("DestroyTheFirstPhysObjectsInHaulList")]
public static bool DestroyFirstOrb()
{
if (!ConfigManager.OrbsOnly || !SemiFunc.IsMasterClientOrSingleplayer() || RoundDirector.instance.dollarHaulList.Count <= 0 || !Object.op_Implicit((Object)(object)RoundDirector.instance.dollarHaulList[0]) || !Object.op_Implicit((Object)(object)RoundDirector.instance.dollarHaulList[0].GetComponent<PhysGrabObject>()))
{
return true;
}
int num = 0;
ValuableObject component = RoundDirector.instance.dollarHaulList[0].GetComponent<ValuableObject>();
if (Regex.IsMatch(((Object)component).name, "Enemy Valuable - (Small|Medium|Big)\\(Clone\\)"))
{
num += (int)(float)AccessTools.Field(typeof(ValuableObject), "dollarValueCurrent").GetValue(component);
RoundDirector.instance.dollarHaulList[0].GetComponent<PhysGrabObject>().DestroyPhysGrabObject();
RoundDirector.instance.dollarHaulList.RemoveAt(0);
totalHaulField.SetValue(RoundDirector.instance, num);
}
return false;
}
}
[HarmonyPatch(typeof(LevelGenerator))]
public static class LevelGeneratorPatch
{
[HarmonyPostfix]
[HarmonyPatch("GenerateDone")]
private static void CreateTimerUI()
{
//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
if (!ConfigManager.EnableRespawnTimer || !RunManager.instance.levels.Contains(RunManager.instance.levelCurrent))
{
return;
}
try
{
GameObject val = GameObject.Find("UI/HUD/HUD Canvas/HUD/Game Hud");
GameObject val2 = GameObject.Find("UI/HUD/HUD Canvas/HUD/Game Hud/Stats");
GameObject val3 = Object.Instantiate<GameObject>(val2, val.transform);
Transform val4 = val3.transform.Find("Upgrades Header");
Transform val5 = val3.transform.Find("StatsNumbers");
((Object)val3).name = "RespawnTimerUI";
((Object)val4).name = "Enemies";
((Object)val5).name = "RespawnTimers";
val4.localPosition = new Vector3(-10f, 9f);
val5.localPosition = new Vector3(120f, -45f);
RespawnTimerUI respawnTimerUI = val3.AddComponent<RespawnTimerUI>();
StatsUI component = val3.GetComponent<StatsUI>();
respawnTimerUI.scanline = ((Component)component).GetComponent<StatsUI>()?.scanlineObject;
if ((Object)(object)component != (Object)null)
{
Object.DestroyImmediate((Object)(object)component);
}
Challenges.Logger.LogInfo((object)"建立重生倒數UI");
}
catch (Exception ex)
{
Challenges.Logger.LogError((object)ex);
}
}
}
[HarmonyPatch(typeof(PhysGrabCart))]
public static class PhysGrabCartPatch
{
private static FieldInfo objectInCartCheckTimerField = AccessTools.Field(typeof(PhysGrabCart), "objectInCartCheckTimer");
private static FieldInfo itemsInCartField = AccessTools.Field(typeof(PhysGrabCart), "itemsInCart");
private static FieldInfo haulCurrentField = AccessTools.Field(typeof(PhysGrabCart), "haulCurrent");
private static FieldInfo haulPreviousField = AccessTools.Field(typeof(PhysGrabCart), "haulPrevious");
private static FieldInfo itemsInCartCountField = AccessTools.Field(typeof(PhysGrabCart), "itemsInCartCount");
private static FieldInfo inCartField = AccessTools.Field(typeof(PhysGrabCart), "inCart");
private static FieldInfo haulUpdateEffectTimerField = AccessTools.Field(typeof(PhysGrabCart), "haulUpdateEffectTimer");
private static FieldInfo deductedFromHaulField = AccessTools.Field(typeof(PhysGrabCart), "deductedFromHaul");
private static FieldInfo thirtyFPSUpdateField = AccessTools.Field(typeof(PhysGrabCart), "thirtyFPSUpdate");
private static FieldInfo resetHaulTextField = AccessTools.Field(typeof(PhysGrabCart), "resetHaulText");
private static FieldInfo originalHaulColorField = AccessTools.Field(typeof(PhysGrabCart), "originalHaulColor");
private static MethodInfo GlitchyTextMethod = AccessTools.Method(typeof(PhysGrabCart), "GlitchyText", (Type[])null, (Type[])null);
private static MethodInfo SetHaulTextMethod = AccessTools.Method(typeof(PhysGrabCart), "SetHaulText", (Type[])null, (Type[])null);
[HarmonyPrefix]
[HarmonyPatch("ObjectsInCart")]
public static bool CalculateOrbsValue(PhysGrabCart __instance)
{
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_007d: Unknown result type (might be due to invalid IL or missing references)
//IL_0083: Unknown result type (might be due to invalid IL or missing references)
//IL_008d: Unknown result type (might be due to invalid IL or missing references)
//IL_0093: Unknown result type (might be due to invalid IL or missing references)
//IL_02d7: Unknown result type (might be due to invalid IL or missing references)
//IL_02dc: Unknown result type (might be due to invalid IL or missing references)
//IL_0266: Unknown result type (might be due to invalid IL or missing references)
//IL_0220: Unknown result type (might be due to invalid IL or missing references)
//IL_0380: Unknown result type (might be due to invalid IL or missing references)
//IL_0303: Unknown result type (might be due to invalid IL or missing references)
//IL_02f5: Unknown result type (might be due to invalid IL or missing references)
//IL_02fa: Unknown result type (might be due to invalid IL or missing references)
if (!ConfigManager.OrbsOnly || SemiFunc.PlayerNearestDistance(((Component)__instance).transform.position) > 12f || (float)objectInCartCheckTimerField.GetValue(__instance) > 0f)
{
return true;
}
int num = (int)haulCurrentField.GetValue(__instance);
haulPreviousField.SetValue(__instance, num);
object? value = inCartField.GetValue(__instance);
Transform val = (Transform)((value is Transform) ? value : null);
Collider[] array = Physics.OverlapBox(val.position, val.localScale / 2f, val.rotation);
List<PhysGrabObject> list = new List<PhysGrabObject>();
int num2 = 0;
int num3 = 0;
Collider[] array2 = array;
foreach (Collider val2 in array2)
{
if (((Component)val2).gameObject.layer != LayerMask.NameToLayer("PhysGrabObject"))
{
continue;
}
PhysGrabObject componentInParent = ((Component)val2).GetComponentInParent<PhysGrabObject>();
if (Object.op_Implicit((Object)(object)componentInParent) && !list.Contains(componentInParent))
{
list.Add(componentInParent);
ValuableObject componentInParent2 = ((Component)val2).GetComponentInParent<ValuableObject>();
if (Object.op_Implicit((Object)(object)componentInParent2) && Regex.IsMatch(((Object)componentInParent2).name, "Enemy Valuable - (Small|Medium|Big)\\(Clone\\)"))
{
num3 += (int)(float)AccessTools.Field(typeof(ValuableObject), "dollarValueCurrent").GetValue(componentInParent2);
}
num2++;
}
}
itemsInCartField.SetValue(__instance, list);
haulCurrentField.SetValue(__instance, num3);
itemsInCartCountField.SetValue(__instance, num2);
objectInCartCheckTimerField.SetValue(__instance, 0.5f);
if (num != num3)
{
haulUpdateEffectTimerField.SetValue(__instance, 0.3f);
if (num3 > num)
{
deductedFromHaulField.SetValue(__instance, false);
__instance.soundHaulIncrease.Play(__instance.displayText.transform.position, 1f, 1f, 1f, 1f);
}
else
{
deductedFromHaulField.SetValue(__instance, true);
__instance.soundHaulDecrease.Play(__instance.displayText.transform.position, 1f, 1f, 1f, 1f);
}
}
float num4 = (float)haulUpdateEffectTimerField.GetValue(__instance);
if (num4 > 0f)
{
num4 -= Time.deltaTime;
num4 = Mathf.Max(0f, num4);
haulUpdateEffectTimerField.SetValue(__instance, num4);
Color color = Color.white;
if ((bool)deductedFromHaulField.GetValue(__instance))
{
color = Color.red;
}
((Graphic)__instance.displayText).color = color;
if ((bool)thirtyFPSUpdateField.GetValue(__instance))
{
((TMP_Text)__instance.displayText).text = GlitchyTextMethod.Invoke(__instance, null) as string;
}
resetHaulTextField.SetValue(__instance, false);
}
else if (!(bool)resetHaulTextField.GetValue(__instance))
{
((Graphic)__instance.displayText).color = (Color)originalHaulColorField.GetValue(__instance);
SetHaulTextMethod.Invoke(__instance, null);
resetHaulTextField.SetValue(__instance, true);
}
return false;
}
}
[HarmonyPatch(typeof(RoundDirector))]
public static class RoundDirectorPatch
{
private static FieldInfo currentHaulField = AccessTools.Field(typeof(RoundDirector), "currentHaul");
private static FieldInfo currentHaulMaxField = AccessTools.Field(typeof(RoundDirector), "currentHaulMax");
[HarmonyPrefix]
[HarmonyPatch("Update")]
public static bool UpdateOrbsOnlyHaul(RoundDirector __instance)
{
if (!ConfigManager.OrbsOnly || __instance.dollarHaulList.Count <= 0)
{
return true;
}
int num = 0;
int num2 = 0;
currentHaulField.SetValue(__instance, num);
currentHaulMaxField.SetValue(__instance, num2);
foreach (GameObject dollarHaul in __instance.dollarHaulList)
{
if (!Object.op_Implicit((Object)(object)dollarHaul))
{
__instance.dollarHaulList.Remove(dollarHaul);
continue;
}
ValuableObject component = dollarHaul.GetComponent<ValuableObject>();
if (Object.op_Implicit((Object)(object)component) && Regex.IsMatch(((Object)component).name, "Enemy Valuable - (Small|Medium|Big)\\(Clone\\)"))
{
float num3 = (float)AccessTools.Field(typeof(ValuableObject), "dollarValueCurrent").GetValue(component);
float num4 = (float)AccessTools.Field(typeof(ValuableObject), "dollarValueOriginal").GetValue(component);
num += (int)num3;
num2 += (int)num4;
}
}
currentHaulField.SetValue(__instance, num);
currentHaulMaxField.SetValue(__instance, num2);
return false;
}
[HarmonyPrefix]
[HarmonyPatch("HaulCheck")]
public static bool CheckOrbsOnlyHaul(RoundDirector __instance)
{
if (!ConfigManager.OrbsOnly)
{
return true;
}
int num = 0;
List<GameObject> list = new List<GameObject>();
foreach (GameObject dollarHaul in __instance.dollarHaulList)
{
if (!Object.op_Implicit((Object)(object)dollarHaul))
{
list.Add(dollarHaul);
continue;
}
ValuableObject component = dollarHaul.GetComponent<ValuableObject>();
FieldInfo fieldInfo = AccessTools.Field(typeof(ValuableObject), "roomVolumeCheck");
MethodInfo methodInfo = AccessTools.Method(typeof(RoomVolumeCheck), "CheckSet", (Type[])null, (Type[])null);
if (Object.op_Implicit((Object)(object)component) && Regex.IsMatch(((Object)component).name, "Enemy Valuable - (Small|Medium|Big)\\(Clone\\)"))
{
object? value = fieldInfo.GetValue(component);
RoomVolumeCheck obj = (RoomVolumeCheck)((value is RoomVolumeCheck) ? value : null);
FieldInfo fieldInfo2 = AccessTools.Field(typeof(RoomVolumeCheck), "inExtractionPoint");
bool flag = (bool)fieldInfo2.GetValue(obj);
methodInfo.Invoke(obj, null);
if (!flag)
{
list.Add(dollarHaul);
}
else
{
num += (int)(float)AccessTools.Field(typeof(ValuableObject), "dollarValueCurrent").GetValue(component);
}
}
}
currentHaulField.SetValue(__instance, num);
foreach (GameObject item in list)
{
__instance.dollarHaulList.Remove(item);
}
return false;
}
}
}
namespace Challenges.Components
{
public class RespawnTimerUI : SemiUI
{
public static RespawnTimerUI instance;
public GameObject? scanline;
private TextMeshProUGUI header;
private TextMeshProUGUI names;
private TextMeshProUGUI timers;
protected override void Start()
{
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: 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)
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
//IL_0102: Unknown result type (might be due to invalid IL or missing references)
//IL_0151: Unknown result type (might be due to invalid IL or missing references)
((SemiUI)this).Start();
GameObject? obj = scanline;
if (obj != null)
{
obj.SetActive(false);
}
instance = this;
base.showPosition = new Vector2(240f, 80f);
base.hidePosition = new Vector2(0f, 0f);
header = ((Component)this).GetComponent<TextMeshProUGUI>();
names = ((Component)((Component)this).transform.Find("Enemies")).GetComponent<TextMeshProUGUI>();
timers = ((Component)((Component)this).transform.Find("RespawnTimers")).GetComponent<TextMeshProUGUI>();
((TMP_Text)header).fontSize = 20f;
((Graphic)header).color = new Color(0.7f, 0.06f, 0.06f);
((TMP_Text)header).text = "<b><u>Respawn Timers</u></b>";
((Behaviour)names).enabled = true;
((TMP_Text)names).fontSize = 17f;
((Graphic)names).color = new Color(1f, 1f, 1f);
((TMP_Text)names).fontStyle = (FontStyles)0;
((TMP_Text)names).alignment = (TextAlignmentOptions)2049;
((TMP_Text)timers).fontSize = 17f;
((Graphic)timers).color = new Color(0.57f, 0.57f, 0.57f);
((TMP_Text)timers).fontStyle = (FontStyles)0;
((TMP_Text)timers).alignment = (TextAlignmentOptions)2049;
Challenges.Logger.LogInfo((object)"初始化重生倒數UI");
}
protected override void Update()
{
if (!SemiFunc.RunIsLevel() || !LevelGenerator.Instance.Generated || !Object.op_Implicit((Object)(object)EnemyDirector.instance))
{
((SemiUI)this).Hide();
return;
}
try
{
((SemiUI)this).Update();
}
catch
{
}
((TMP_Text)names).text = "";
((TMP_Text)timers).text = "";
List<EnemyParent> enemiesSpawned = EnemyDirector.instance.enemiesSpawned;
foreach (EnemyParent item in enemiesSpawned)
{
if (item.DespawnedTimer > 0f)
{
TextMeshProUGUI obj2 = names;
((TMP_Text)obj2).text = ((TMP_Text)obj2).text + item.enemyName + "\n";
TextMeshProUGUI obj3 = timers;
((TMP_Text)obj3).text = ((TMP_Text)obj3).text + TimerToString(item.DespawnedTimer) + "\n";
}
}
}
private string TimerToString(float timer)
{
if (timer <= 0f)
{
throw new Exception("Invalid timer passed.");
}
int num = Mathf.FloorToInt(timer / 60f);
int num2 = Mathf.FloorToInt(timer % 60f);
string text = ((num < 10) ? $"0{num}" : $"{num}");
string text2 = ((num2 < 10) ? $"0{num2}" : $"{num2}");
return text + ":" + text2;
}
}
}