public override void ExecuteCommand(object sender, OnChatCommandReceivedArgs e)
        {
            List <string> args = e.Command.ArgumentsAsList;

            if (args.Count != 1)
            {
                BotProgram.QueueMessage("Usage: state #");
                return;
            }

            string stateNumStr = args[0];

            if (int.TryParse(stateNumStr, out int stateNum) == false)
            {
                BotProgram.QueueMessage($"Invalid state number.");
                return;
            }

            string loadStateStr = $"loadstate{stateNum}";

            if (InputGlobals.CurrentConsole.ButtonInputMap.ContainsKey(loadStateStr) == false)
            {
                BotProgram.QueueMessage($"Invalid state number.");
                return;
            }

            //Load states are always performed on the first controller
            VJoyController joystick = VJoyController.GetController(0);

            joystick.PressButton(loadStateStr);
            joystick.UpdateJoystickEfficient();

            BotProgram.QueueMessage($"Loaded state {stateNum}!");

            //Wait a bit before releasing the input
            const float wait = 50f;
            Stopwatch   sw   = Stopwatch.StartNew();

            while (sw.ElapsedMilliseconds < wait)
            {
            }

            joystick.ReleaseButton(loadStateStr);
            joystick.UpdateJoystickEfficient();
        }
        public override void ExecuteCommand(object sender, OnChatCommandReceivedArgs e)
        {
            List <string> args = e.Command.ArgumentsAsList;

            if (args.Count < 1)
            {
                BotProgram.QueueMessage("Usage: state #");
                return;
            }

            string stateNumStr = args[0];

            if (int.TryParse(stateNumStr, out int stateNum) == false)
            {
                BotProgram.QueueMessage("Invalid state number.");
                return;
            }

            string saveStateStr = $"savestate{stateNum}";

            if (InputGlobals.CurrentConsole.ButtonInputMap.ContainsKey(saveStateStr) == false)
            {
                BotProgram.QueueMessage("Invalid state number.");
                return;
            }

            //Savestates are always performed on the first controller
            VJoyController joystick = VJoyController.GetController(0);

            joystick.PressButton(saveStateStr);
            joystick.UpdateJoystickEfficient();

            //Track the time of the savestate
            DateTime curTime = DateTime.UtcNow;

            //Add a new savestate log
            GameLog newStateLog = new GameLog();

            newStateLog.User = e.Command.ChatMessage.Username;

            string date = curTime.ToShortDateString();
            string time = curTime.ToLongTimeString();

            newStateLog.DateTimeString = $"{date} at {time}";

            newStateLog.User       = e.Command.ChatMessage.Username;
            newStateLog.LogMessage = string.Empty;

            //Add the message if one was specified
            if (args.Count > 1)
            {
                string message = e.Command.ArgumentsAsString.Remove(0, stateNumStr.Length + 1);
                newStateLog.LogMessage = message;
            }

            //Add or replace the log and save the bot data
            BotProgram.BotData.SavestateLogs[stateNum] = newStateLog;
            BotProgram.SaveBotData();

            BotProgram.QueueMessage($"Saved state {stateNum}!");

            //Wait a bit before releasing the input
            const float wait = 50f;
            Stopwatch   sw   = Stopwatch.StartNew();

            while (sw.ElapsedMilliseconds < wait)
            {
            }

            joystick.ReleaseButton(saveStateStr);
            joystick.UpdateJoystickEfficient();
        }