using System; 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.Text.Json; using System.Text.Json.Serialization; using Agents; using AmorLib.Utils; using BepInEx; using BepInEx.Core.Logging.Interpolation; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using Colossus.Attributes; using Colossus.Patches; using Enemies; using GTFO.API; using GTFO.API.Utilities; using GameData; using Globals; using HarmonyLib; using Il2CppInterop.Runtime.Injection; using Il2CppInterop.Runtime.InteropTypes; using LevelGeneration; using MTFO.API; using MTFO.Managers; using Microsoft.CodeAnalysis; using Player; using SNetwork; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("Colossus")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("Colossus")] [assembly: AssemblyTitle("Colossus")] [assembly: AssemblyVersion("1.0.0.0")] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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] [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; } } } namespace Colossus { public static class BossbarJson { private static readonly JsonSerializerOptions _setting; static BossbarJson() { _setting = new JsonSerializerOptions { ReadCommentHandling = JsonCommentHandling.Skip, IncludeFields = true, PropertyNameCaseInsensitive = true, WriteIndented = true, IgnoreReadOnlyProperties = true }; _setting.Converters.Add(new Vector3Converter()); _setting.Converters.Add(new JsonStringEnumConverter()); } public static T? Deserialize(string json) { return JsonSerializer.Deserialize(json, _setting); } public static T? Deserialize(ref Utf8JsonReader reader) { return JsonSerializer.Deserialize(ref reader, _setting); } public static object? Deserialize(Type type, string json) { return JsonSerializer.Deserialize(json, type, _setting); } public static string Serialize(T value) { return JsonSerializer.Serialize(value, _setting); } public static void Serialize(Utf8JsonWriter writer, T value) { JsonSerializer.Serialize(writer, value, _setting); } } internal class BossbarMain : MonoBehaviour { public const string BossAlertEvent = "BossBarAlert"; private readonly HashSet aliveBosses = new HashSet(); private readonly List validBosses = new List(); public readonly List<(EnemyAgent enemy, BossData data)> activeBosses = new List<(EnemyAgent, BossData)>(); private readonly Dictionary> rawSource = new Dictionary>(); private readonly Dictionary levelSource = new Dictionary(); public static readonly List bossBars = new List(); public static BossbarMain Current { get; private set; } = null; [InvokeOnManagersSetup] private static void Init() { ClassInjector.RegisterTypeInIl2Cpp(); Current = ((Component)Global.Current).gameObject.AddComponent(); LevelAPI.OnEnterLevel += Current.LevelStarted; LevelAPI.OnLevelCleanup += Current.LevelCleanup; NetworkAPI.RegisterEvent("BossBarAlert", (Action)Current.ReceiveAlert); Current.ReadData(); } internal static void OnEnemyModeChange(EnemyAgent enemy, AgentMode mode) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 if ((int)mode == 1) { Current.TrySendBossAlert(enemy); } } internal static void OnEnemyStartMode(EnemyAI ai, AgentMode mode) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 if ((int)mode == 1) { Current.TryAddBoss(ai.m_enemyAgent); } } private void LevelStarted() { //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //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_014a: Unknown result type (might be due to invalid IL or missing references) //IL_0150: 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_015b: 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_00dc: Expected O, but got Unknown aliveBosses.Clear(); foreach (PUI_InteractionPrompt bossBar in bossBars) { ToggleBossbar(bossBar, value: false); } ((Behaviour)this).enabled = false; LoadDataForLevel(); if (!SNet.IsMaster || levelSource.Count == 0) { return; } LG_Zone val = default(LG_Zone); bool flag = default(bool); foreach (BossData value in levelSource.Values) { if (!value.SpawnOnLevelGen) { continue; } Loader.Logger.LogDebug((object)("Got Boss that wants to spawn on level gen: " + value.BossName + ". Spawning..")); if (Builder.CurrentFloor.TryGetZoneByLocalIndex(value.DimensionIndex, value.SpawnLayer, value.SpawnZone, ref val)) { ManualLogSource logger = Loader.Logger; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(38, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Spawn location is invalid for "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(value.BossName); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" (id: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(value.BossId); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(")!"); } logger.LogWarning(val2); break; } EnemyAllocator.Current.SpawnEnemy(value.BossId, val.m_areas[value.SpawnArea].m_courseNode, value.SpawnMode, value.SpawnCoords, Quaternion.EulerAngles(value.SpawnRot), (EnemyGroup)null, -1); } } private void ToggleBossbar(PUI_InteractionPrompt bar, bool value) { ((Component)bar.m_timer).gameObject.SetActive(value); ((Component)bar).gameObject.SetActive(value); } private void LevelCleanup() { ((Behaviour)this).enabled = false; levelSource.Clear(); foreach (PUI_InteractionPrompt bossBar in bossBars) { ToggleBossbar(bossBar, value: false); } } private void TrySendBossAlert(EnemyAgent enemy) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) if (SNet.IsMaster && levelSource.ContainsKey(enemy.EnemyDataID)) { pEnemyAgent val = default(pEnemyAgent); ((pEnemyAgent)(ref val)).Set(enemy); NetworkAPI.InvokeEvent("BossBarAlert", val, (SNet_ChannelType)2); ReceiveAlert(0uL, val); } } private void ReceiveAlert(ulong sender, pEnemyAgent packet) { EnemyAgent enemy = default(EnemyAgent); if (((pEnemyAgent)(ref packet)).TryGet(ref enemy)) { TryAddBoss(enemy); } } private void TryAddBoss(EnemyAgent enemy) { if (levelSource.ContainsKey(enemy.EnemyDataID) && aliveBosses.Add(((Object)enemy).GetInstanceID())) { validBosses.Add(enemy); ((Behaviour)this).enabled = true; } } private void TryGetBossEnemy() { //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) PlayerAgent localPlayerAgent = PlayerManager.GetLocalPlayerAgent(); int count = activeBosses.Count; for (int num = activeBosses.Count - 1; num >= 0; num--) { EnemyAgent item = activeBosses[num].enemy; if ((Object)(object)item == (Object)null) { activeBosses.RemoveAt(num); } else if (!((Agent)item).Alive) { activeBosses.RemoveAt(num); aliveBosses.Remove(((Object)item).GetInstanceID()); } else { Dimension dimension = ((Agent)localPlayerAgent).Dimension; if ((dimension == null || !dimension.IsArenaDimension) && ((Agent)item).DimensionIndex != ((Agent)localPlayerAgent).DimensionIndex) { activeBosses.RemoveAt(num); validBosses.Add(item); } } } if (activeBosses.Count == 3) { return; } int num2 = validBosses.Count - 1; while (num2 >= 0 && activeBosses.Count < 3) { EnemyAgent val = validBosses[num2]; if ((Object)(object)val == (Object)null) { validBosses.RemoveAt(num2); } else if (!((Agent)val).Alive) { validBosses.RemoveAt(num2); aliveBosses.Remove(((Object)val).GetInstanceID()); } else if (ZoneGraphUtil.IsReachable(localPlayerAgent, ((Agent)val).CourseNode)) { validBosses.RemoveAt(num2); activeBosses.Add((val, levelSource[val.EnemyDataID])); } num2--; } if (count == activeBosses.Count) { return; } foreach (PUI_InteractionPrompt bossBar in bossBars) { ToggleBossbar(bossBar, value: false); } } private void Update() { //IL_00b6: 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_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_0170: 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_01af: 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_01f7: 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_0249: Unknown result type (might be due to invalid IL or missing references) if (!RundownManager.ExpeditionIsStarted || !PlayerManager.HasLocalPlayerAgent()) { return; } TryGetBossEnemy(); if (validBosses.Count == 0 && activeBosses.Count == 0) { ((Behaviour)this).enabled = false; return; } for (int i = 0; i < activeBosses.Count; i++) { AssignValuesToBar(bossBars[i], activeBosses[i].enemy, activeBosses[i].data); } switch (activeBosses.Count) { case 1: ((RectTransformComp)bossBars[0]).SetPosition(new Vector2(0f, 215f)); ((Component)bossBars[0]).transform.localScale = new Vector3(0.75f, 0.75f, 1f); break; case 2: ((RectTransformComp)bossBars[0]).SetPosition(new Vector2(-300f, 215f)); ((RectTransformComp)bossBars[1]).SetPosition(new Vector2(300f, 215f)); ((Component)bossBars[0]).transform.localScale = new Vector3(0.67f, 0.67f, 1f); ((Component)bossBars[1]).transform.localScale = new Vector3(0.67f, 0.67f, 1f); break; case 3: ((RectTransformComp)bossBars[0]).SetPosition(new Vector2(-500f, 235f)); ((RectTransformComp)bossBars[1]).SetPosition(new Vector2(500f, 235f)); ((RectTransformComp)bossBars[2]).SetPosition(new Vector2(0f, 215f)); ((Component)bossBars[0]).transform.localScale = new Vector3(0.6f, 0.6f, 1f); ((Component)bossBars[1]).transform.localScale = new Vector3(0.6f, 0.6f, 1f); ((Component)bossBars[2]).transform.localScale = new Vector3(0.6f, 0.6f, 1f); break; } } private void AssignValuesToBar(PUI_InteractionPrompt bar, EnemyAgent agent, BossData data) { //IL_0054: 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) ToggleBossbar(bar, value: true); bar.SetStyle((ePUIMessageStyle)0); bar.SetTimerFill(((Dam_SyncedDamageBase)agent.Damage).Health / ((Dam_SyncedDamageBase)agent.Damage).HealthMax); bar.SetMessage("" + data.BossName + "\n" + data.BossSubName); bar.m_timer.color = data.BossbarColor; ((Component)bar).gameObject.transform.localScale = new Vector3(1f, 1f, 1f); } private void ReadData() { List? list = BossbarJson.Deserialize>(File.ReadAllText(Path.Combine(ConfigManager.CustomPath, "Brandon't-Bossbar", "BossbarConfig.json"))); list.RemoveAll((BossData data) => !data.InternalEnabled); foreach (BossData item in list) { if (!rawSource.TryGetValue(item.BossId, out List value)) { rawSource.Add(item.BossId, value = new List()); } value.Add(item); } } private void LoadDataForLevel() { uint levelLayoutData = RundownManager.ActiveExpedition.LevelLayoutData; levelSource.Clear(); foreach (KeyValuePair> item in rawSource) { item.Deconstruct(out var key, out var value); uint key2 = key; List list = value; BossData bossData = null; foreach (BossData item2 in list) { if (item2.IgnoreLevelLayoutCheck) { bossData = item2; } else if (item2.LevelLayoutID == levelLayoutData) { bossData = item2; break; } } if (bossData != null) { levelSource.Add(key2, bossData); } } } } public class BossData { public string BossName { get; set; } public string BossSubName { get; set; } public uint BossId { get; set; } public Color BossbarColor { get; set; } public Vector3 SpawnCoords { get; set; } public Vector3 SpawnRot { get; set; } public uint LevelLayoutID { get; set; } public bool SpawnOnLevelGen { get; set; } public LG_LayerType SpawnLayer { get; set; } public eLocalZoneIndex SpawnZone { get; set; } public int SpawnArea { get; set; } public eDimensionIndex DimensionIndex { get; set; } public AgentMode SpawnMode { get; set; } public string DebugName { get; set; } public bool IgnoreLevelLayoutCheck { get; set; } public bool InternalEnabled { get; set; } public BossData() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) BossName = ""; BossSubName = ""; BossId = 0u; BossbarColor = default(Color); SpawnOnLevelGen = false; SpawnCoords = default(Vector3); SpawnRot = default(Vector3); SpawnLayer = (LG_LayerType)0; SpawnZone = (eLocalZoneIndex)0; SpawnArea = 0; DimensionIndex = (eDimensionIndex)0; LevelLayoutID = 0u; SpawnMode = (AgentMode)4; DebugName = ""; IgnoreLevelLayoutCheck = false; InternalEnabled = false; } } [BepInPlugin("com.Brandonious.Bossbar", "Bossbar", "1.1.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Loader : BasePlugin { public const string MODNAME = "Bossbar"; public const string AUTHOR = "Brandonious"; public const string GUID = "com.Brandonious.Bossbar"; public const string VERSION = "1.1.1"; public static ManualLogSource Logger; private IEnumerable _cleanupCallbacks; private IEnumerable _enterCallbacks; private IEnumerable _checkpointCallbacks; private IEnumerable _buildStartCallbacks; private IEnumerable _buildDoneCallbacks; public override void Load() { //IL_00ee: Unknown result type (might be due to invalid IL or missing references) if (MTFOAPIWrapper.HasCustomContent) { CacheFrequentCallbacks(); LevelAPI.OnLevelCleanup += RunFrequentCallback(_cleanupCallbacks); LevelAPI.OnEnterLevel += RunFrequentCallback(_enterCallbacks); LevelAPI.OnBuildStart += RunFrequentCallback(_buildStartCallbacks); LevelAPI.OnBuildDone += RunFrequentCallback(_buildDoneCallbacks); CheckpointPatches.OnCheckpointReload += RunFrequentCallback(_checkpointCallbacks); EventAPI.OnManagersSetup += InvokeCallbacks; AssetAPI.OnStartupAssetsLoaded += InvokeCallbacks; Directory.CreateDirectory(Path.Combine(ConfigManager.CustomPath, "Brandon't-Bossbar")); if (!File.Exists(Path.Combine(ConfigManager.CustomPath, "Brandon't-Bossbar", "BossbarConfig.Json"))) { File.WriteAllText(Path.Combine(ConfigManager.CustomPath, "Brandon't-Bossbar", "BossbarConfig.Json"), BossbarJson.Serialize(new List { new BossData() })); } Logger = ((BasePlugin)this).Log; new Harmony("Bossbar").PatchAll(); InvokeCallbacks(); ((BasePlugin)this).Log.LogInfo((object)"Plugin Bossbars Loaded! :)"); } } private static Action RunFrequentCallback(IEnumerable callbacks) { return delegate { foreach (MethodInfo callback in callbacks) { callback.Invoke(null, null); } }; } private void CacheFrequentCallbacks() { IEnumerable source = from method in ((IEnumerable)AccessTools.GetTypesFromAssembly(((object)this).GetType().Assembly)).SelectMany((Func>)AccessTools.GetDeclaredMethods) where method.IsStatic select method; _cleanupCallbacks = source.Where((MethodInfo method) => method.GetCustomAttribute() != null); _enterCallbacks = source.Where((MethodInfo method) => method.GetCustomAttribute() != null); _checkpointCallbacks = source.Where((MethodInfo method) => method.GetCustomAttribute() != null); _buildStartCallbacks = source.Where((MethodInfo method) => method.GetCustomAttribute() != null); _buildDoneCallbacks = source.Where((MethodInfo method) => method.GetCustomAttribute() != null); } private void InvokeCallbacks() where T : Attribute { foreach (MethodInfo item in from method in ((IEnumerable)AccessTools.GetTypesFromAssembly(((object)this).GetType().Assembly)).SelectMany((Func>)AccessTools.GetDeclaredMethods) where method.IsStatic && method.GetCustomAttribute() != null select method) { item.Invoke(null, null); } } } internal static class MTFOAPIWrapper { public const string PLUGIN_GUID = "com.dak.MTFO"; public static string GameDataPath => MTFOPathAPI.RundownPath; public static string CustomPath => MTFOPathAPI.CustomPath; public static bool HasCustomContent => MTFOPathAPI.HasRundownPath; } public sealed class Vector3Converter : JsonConverter { public override bool HandleNull => false; public override Vector3 Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) Vector3 vector = default(Vector3); switch (reader.TokenType) { case JsonTokenType.StartObject: { int currentDepth = reader.CurrentDepth; while (reader.Read()) { if (reader.TokenType == JsonTokenType.EndObject && reader.CurrentDepth == currentDepth) { return vector; } if (reader.TokenType != JsonTokenType.PropertyName) { throw new JsonException("Expected PropertyName token"); } string? text2 = reader.GetString(); reader.Read(); switch (text2.ToLowerInvariant()) { case "x": vector.x = reader.GetSingle(); break; case "y": vector.y = reader.GetSingle(); break; case "z": vector.z = reader.GetSingle(); break; } } throw new JsonException("Expected EndObject token"); } case JsonTokenType.String: { string text = reader.GetString().Trim(); if (TryParseVector3(text, out vector)) { return vector; } throw new JsonException("Vector3 format is not right: " + text); } default: throw new JsonException($"Vector3Json type: {reader.TokenType} is not implemented!"); } } private static bool TryParseVector3(string input, out Vector3 vector) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) float[] array = default(float[]); if (!RegexUtils.TryParseVectorString(input, ref array)) { vector = Vector3.zero; return false; } if (array.Length < 3) { vector = Vector3.zero; return false; } vector = new Vector3(array[0], array[1], array[2]); return true; } public override void Write(Utf8JsonWriter writer, Vector3 value, JsonSerializerOptions options) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) writer.WriteStartObject(); writer.WriteNumber("x", value.x); writer.WriteNumber("y", value.y); writer.WriteNumber("z", value.z); writer.WriteEndObject(); } } } namespace Colossus.Patches { [HarmonyPatch] internal class BossbarPatch { private static bool _setStartState; [HarmonyPatch(typeof(InteractionGuiLayer), "Setup")] [HarmonyPostfix] private static void AddNewLayer(InteractionGuiLayer __instance) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < 3; i++) { BossbarMain.bossBars.Add(((Il2CppObjectBase)((GuiLayer)__instance).AddRectComp("Gui/Player/PUI_InteractionPrompt_CellUI", (GuiAnchor)3, new Vector2(0f, 200f), (Transform)null)).TryCast()); } } [HarmonyPatch(typeof(EnemyAI), "SetStartMode")] [HarmonyPrefix] private static void Pre_SetStartMode() { _setStartState = true; } [HarmonyPatch(typeof(EnemyAI), "SetStartMode")] [HarmonyPostfix] private static void Post_SetStartMode(EnemyAI __instance, AgentMode mode) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) _setStartState = false; BossbarMain.OnEnemyStartMode(__instance, mode); } [HarmonyPatch(typeof(EnemyAI), "ModeChange")] [HarmonyPostfix] private static void OnModeChange(EnemyAI __instance) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) if (!_setStartState) { BossbarMain.OnEnemyModeChange(__instance.m_enemyAgent, ((AgentAI)__instance).Mode); } } } [HarmonyPatch] internal static class CheckpointPatches { public static event Action? OnCheckpointReload; [HarmonyPatch(typeof(CheckpointManager), "OnStateChange")] [HarmonyWrapSafe] [HarmonyPostfix] private static void Post_CheckpointLoaded(pCheckpointState oldState, bool isRecall) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) if (oldState.isReloadingCheckpoint && isRecall) { CheckpointPatches.OnCheckpointReload?.Invoke(); } } } } namespace Colossus.Attributes { [AttributeUsage(AttributeTargets.Method)] internal sealed class InvokeOnAssetsLoadedAttribute : Attribute { } [AttributeUsage(AttributeTargets.Method)] internal sealed class InvokeOnBuildDoneAttribute : Attribute { } [AttributeUsage(AttributeTargets.Method)] internal sealed class InvokeOnBuildStartAttribute : Attribute { } [AttributeUsage(AttributeTargets.Method)] internal sealed class InvokeOnCheckpointAttribute : Attribute { } [AttributeUsage(AttributeTargets.Method)] internal sealed class InvokeOnCleanupAttribute : Attribute { } [AttributeUsage(AttributeTargets.Method)] internal sealed class InvokeOnEnterAttribute : Attribute { } [AttributeUsage(AttributeTargets.Method)] internal sealed class InvokeOnLoadAttribute : Attribute { } [AttributeUsage(AttributeTargets.Method)] internal sealed class InvokeOnManagersSetupAttribute : Attribute { } }