/// <summary>
 /// Called on the 0th frame
 /// </summary>
 protected virtual void Awake()
 {
     ModuleType = GetType();
     if (!DefaultCoroutineQueue.ContainsKey(ModuleType))
     {
         DefaultCoroutineQueue.Add(
             ModuleType,
             new Dictionary <string, CoroutineQueue>()
         {
             { DefaultID, new CoroutineQueue() }
         });
     }
     if (!LoggingIDs.ContainsKey(ModuleType))
     {
         LoggingIDs.Add(ModuleType, 0);
     }
     ModuleID          = ++LoggingIDs[ModuleType];
     TwitchPlaysScores = new Dictionary <string, float>();
 }
    /// <summary>
    /// Called on the 1st frame
    /// </summary>
    protected virtual void Start()
    {
        IsTestHarness  = Application.isEditor;
        TwitchID       = -1;
        TwitchGameType = ReflectionHelper.FindType("TwitchGame", "TwitchPlaysAssembly");

        GetComponent <KMGameInfo>().OnStateChange += state =>
        {
            foreach (var queueDict in DefaultCoroutineQueue)
            {
                LoggingIDs.Clear();
                foreach (var queue in queueDict.Value)
                {
                    queue.Value.Reset();
                }
            }

            DefaultCoroutineQueue.Clear();
        };

        BombInfo    = GetComponent <KMBombInfo>();
        BombModule  = GetComponent <KMBombModule>();
        NeedyModule = GetComponent <KMNeedyModule>();
        BossModule  = GetComponent("KMBossModule");
        Component ColorblindComponent = GetComponent("KMColorblindMode");

        if (ColorblindComponent != null)
        {
            var ColorblindEnabled = ColorblindComponent.GetType().GetProperty("ColorblindModeActive", MainFlags);
            if (ColorblindEnabled != null)
            {
                ColorblindMode = (bool)ColorblindEnabled.GetValue(ColorblindComponent, null);
            }
        }
        if (BossModule != null)
        {
            IgnoredMethod = BossModule
                            .GetType()
                            .GetMethod(
                "GetIgnoredModules",
                MainFlags,
                Type.DefaultBinder,
                new Type[] { typeof(string), typeof(string[]) },
                null
                );
        }
        if (!IsTestHarness)
        {
            Type SceneManagerType = ReflectionHelper.FindType("SceneManager", "Assembly-CSharp");
            SceneManager = SceneManagerType
                           .GetProperty("Instance", MainFlags | BindingFlags.Static)
                           .GetValue(null, null);
            object GameplayStateObject = SceneManagerType
                                         .GetProperty("GameplayState", MainFlags)
                                         .GetValue(SceneManager, null);
            MissionObject = GameplayStateObject.GetType().GetField("Mission", MainFlags).GetValue(GameplayStateObject);
            var MissionType = MissionObject.GetType();
            MissionName = (string)MissionType.GetField("DisplayNameTerm", MainFlags)
                          .GetValue(MissionObject);
            MissionID = (string)MissionType.GetProperty("ID", MainFlags).GetValue(MissionObject, null);

            Type IRCType = ReflectionHelper.FindType("IRCConnection", "TwitchPlaysAssembly");
            if (IRCType != null)
            {
                SendMethod = IRCType.GetMethod(
                    "SendMessage",
                    MainFlags | BindingFlags.Static,
                    Type.DefaultBinder,
                    new Type[] { typeof(string) },
                    null);
            }
        }
        try
        {
            FetchTweaksScores();
        }
        catch (Exception ex)
        {
            Debug.LogFormat("[ModuleUtils] Failed to fetch scores: {0}", ex);
        }
    }