using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; 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 HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using REPOLib.Modules; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: AssemblyCompany("EnemyTestSpawner")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("EnemyTestSpawner")] [assembly: AssemblyTitle("EnemyTestSpawner")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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 EnemyTestSpawner { [BepInPlugin("themorningstar.enemytestspawner", "Enemy Test Spawner", "1.1.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { public const string Guid = "themorningstar.enemytestspawner"; internal static ManualLogSource Log; internal static ConfigFile Cfg; internal static ConfigEntry EnabledCfg; internal static ConfigEntry KeyCfg; internal static ConfigEntry EnemyCfg; internal static ConfigEntry DistCfg; private static bool _dropdownBound; private void Awake() { //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; Cfg = ((BaseUnityPlugin)this).Config; EnabledCfg = ((BaseUnityPlugin)this).Config.Bind("General", "Enabled", false, "Master switch for the debug enemy spawner. Leave FALSE for normal/shipped play."); KeyCfg = ((BaseUnityPlugin)this).Config.Bind("General", "SpawnKey", "Insert", "Key that spawns the chosen enemy in front of you (any UnityEngine.KeyCode name, e.g. Insert, F2, Backslash, Keypad0)."); DistCfg = ((BaseUnityPlugin)this).Config.Bind("General", "SpawnDistance", 3f, "How far in front of you the enemy spawns (metres)."); try { MethodInfo methodInfo = AccessTools.Method(typeof(Enemies), "RegisterEnemies", (Type[])null, (Type[])null); if (methodInfo != null) { new Harmony("themorningstar.enemytestspawner").Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(Plugin).GetMethod("BindDropdown")), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } else { BindPlainFallback(); } } catch (Exception ex) { Log.LogError((object)("EnemyTestSpawner: dropdown hook failed: " + ex)); BindPlainFallback(); } Log.LogInfo((object)"EnemyTestSpawner: loaded (disabled by default). Enable it + pick an enemy in REPOConfig; press the SpawnKey in a level."); } public static void BindDropdown() { //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Expected O, but got Unknown if (_dropdownBound) { return; } _dropdownBound = true; try { SortedSet sortedSet = new SortedSet(StringComparer.OrdinalIgnoreCase); try { foreach (EnemySetup allEnemy in Enemies.AllEnemies) { if ((Object)(object)allEnemy != (Object)null && !string.IsNullOrEmpty(((Object)allEnemy).name)) { sortedSet.Add(((Object)allEnemy).name); } } } catch { } try { foreach (EnemySetup registeredEnemy in Enemies.RegisteredEnemies) { if ((Object)(object)registeredEnemy != (Object)null && !string.IsNullOrEmpty(((Object)registeredEnemy).name)) { sortedSet.Add(((Object)registeredEnemy).name); } } } catch { } if (sortedSet.Count == 0) { BindPlainFallback(); return; } string[] array = sortedSet.ToArray(); string text = array.FirstOrDefault((string n) => n.IndexOf("Rolling Giant", StringComparison.OrdinalIgnoreCase) >= 0) ?? array[0]; EnemyCfg = Cfg.Bind("General", "Enemy", text, new ConfigDescription("Enemy to spawn (dropdown of registered enemies).", (AcceptableValueBase)(object)new AcceptableValueList(array), Array.Empty())); Log.LogInfo((object)$"EnemyTestSpawner: enemy dropdown ready ({array.Length} enemies)."); } catch (Exception ex) { Log.LogError((object)("EnemyTestSpawner: dropdown bind failed: " + ex)); BindPlainFallback(); } } private static void BindPlainFallback() { if (EnemyCfg == null) { EnemyCfg = Cfg.Bind("General", "Enemy", "Rolling Giant", "Enemy to spawn (name or part of it). (Dropdown unavailable - REPOLib enemy list not found.)"); } } private void Update() { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) if (EnabledCfg == null || !EnabledCfg.Value) { return; } if (!Enum.TryParse(KeyCfg.Value, ignoreCase: true, out KeyCode result)) { result = (KeyCode)277; } if (!Input.GetKeyDown(result)) { return; } try { Spawn(); } catch (Exception ex) { Log.LogError((object)("EnemyTestSpawner: spawn failed: " + ex)); } } private void Spawn() { //IL_0259: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0140: 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_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0161: 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_016b: Unknown result type (might be due to invalid IL or missing references) if (!SemiFunc.IsMasterClientOrSingleplayer()) { Log.LogWarning((object)"EnemyTestSpawner: host/singleplayer only."); return; } EnemyDirector instance = EnemyDirector.instance; if ((Object)(object)instance == (Object)null) { Log.LogWarning((object)"EnemyTestSpawner: no EnemyDirector (are you in a level?)."); return; } PlayerAvatar instance2 = PlayerAvatar.instance; if ((Object)(object)instance2 == (Object)null) { Log.LogWarning((object)"EnemyTestSpawner: no local player."); return; } string text = (EnemyCfg?.Value ?? "").Trim(); EnemySetup val = FindSetup(instance, text); if ((Object)(object)val == (Object)null) { IEnumerable values = from s in instance.enemiesDifficulty1.Concat(instance.enemiesDifficulty2).Concat(instance.enemiesDifficulty3) where (Object)(object)s != (Object)null select ((Object)s).name; Log.LogWarning((object)("EnemyTestSpawner: no enemy matching '" + text + "'. Available: " + string.Join(", ", values))); return; } Vector3 val2 = ((Component)instance2).transform.position + ((Component)instance2).transform.forward * DistCfg.Value + Vector3.up * 0.5f; Quaternion val3 = Quaternion.LookRotation(-((Component)instance2).transform.forward); bool flag = SemiFunc.IsMultiplayer(); int num = 0; GameObject val4 = null; foreach (PrefabRef spawnObject in val.spawnObjects) { if (spawnObject == null) { continue; } GameObject val5 = null; try { val5 = (flag ? PhotonNetwork.InstantiateRoomObject(((PrefabRef)(object)spawnObject).ResourcePath, val2, val3, (byte)0, (object[])null) : (((Object)(object)((PrefabRef)(object)spawnObject).Prefab != (Object)null) ? Object.Instantiate(((PrefabRef)(object)spawnObject).Prefab, val2, val3) : null)); } catch (Exception ex) { Log.LogWarning((object)("EnemyTestSpawner: failed to spawn '" + ((PrefabRef)(object)spawnObject).PrefabName + "': " + ex.Message)); continue; } if ((Object)(object)val5 != (Object)null) { num++; if ((Object)(object)val4 == (Object)null) { val4 = val5; } } } Log.LogInfo((object)$"EnemyTestSpawner: spawned '{((Object)val).name}' ({num} object(s)) at {val2}."); if ((Object)(object)val4 != (Object)null) { ((MonoBehaviour)this).StartCoroutine(DumpComponents(val4)); } } private IEnumerator DumpComponents(GameObject go) { for (int pass = 0; pass < 2; pass++) { yield return (object)new WaitForSeconds((pass == 0) ? 0.3f : 2.5f); if ((Object)(object)go == (Object)null) { Log.LogWarning((object)$"EnemyTestSpawner DUMP pass{pass}: enemy already destroyed."); break; } StringBuilder stringBuilder = new StringBuilder($"EnemyTestSpawner DUMP pass{pass} '{((Object)go).name}' rootActive={go.activeInHierarchy}:\n"); int num = 0; MonoBehaviour[] componentsInChildren = go.GetComponentsInChildren(true); foreach (MonoBehaviour val in componentsInChildren) { if ((Object)(object)val == (Object)null) { num++; continue; } string name = ((object)val).GetType().Name; if (name.StartsWith("Enemy") || name == "PhotonView") { stringBuilder.Append($" {((Object)((Component)val).gameObject).name}/{name} enabled={((Behaviour)val).enabled} goActive={((Component)val).gameObject.activeInHierarchy}\n"); } } stringBuilder.Append($" (+{num} MISSING-script component(s) in hierarchy)"); Log.LogInfo((object)stringBuilder.ToString()); } } private static EnemySetup FindSetup(EnemyDirector ed, string want) { List[] array = new List[3] { ed.enemiesDifficulty1, ed.enemiesDifficulty2, ed.enemiesDifficulty3 }; List[] array2 = array; for (int i = 0; i < array2.Length; i++) { foreach (EnemySetup item in array2[i]) { if ((Object)(object)item != (Object)null && string.Equals(((Object)item).name, want, StringComparison.OrdinalIgnoreCase)) { return item; } } } array2 = array; for (int i = 0; i < array2.Length; i++) { foreach (EnemySetup item2 in array2[i]) { if ((Object)(object)item2 != (Object)null && ((Object)item2).name != null && ((Object)item2).name.IndexOf(want, StringComparison.OrdinalIgnoreCase) >= 0) { return item2; } } } return null; } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { internal IgnoresAccessChecksToAttribute(string assemblyName) { } } }