public override void ExecuteCommand(EvtChatCommandArgs e)
        {
            List <string> args = e.Command.ArgumentsAsList;

            //See the console
            if (args.Count == 0)
            {
                BotProgram.MsgHandler.QueueMessage($"The current console is {InputGlobals.CurrentConsoleVal}. To set the console, add one as an argument: {GetValidConsoleStr()}");
                return;
            }

            string consoleStr = args[0];

            if (Enum.TryParse <InputGlobals.InputConsoles>(consoleStr, true, out InputGlobals.InputConsoles console) == false)
            {
                BotProgram.MsgHandler.QueueMessage($"Please enter a valid console: {GetValidConsoleStr()}");
                return;
            }

            if (console == InputGlobals.CurrentConsoleVal)
            {
                BotProgram.MsgHandler.QueueMessage($"The current console is already {InputGlobals.CurrentConsoleVal}!");
                return;
            }

            //First stop all inputs completely while changing consoles - we don't want data from other inputs remaining
            InputHandler.CancelRunningInputs();

            //Wait until no inputs are running
            while (InputHandler.CurrentRunningInputs > 0)
            {
            }

            //Set console and buttons
            InputGlobals.SetConsole(console, args);

            for (int i = 0; i < InputGlobals.ControllerMngr.ControllerCount; i++)
            {
                IVirtualController controller = InputGlobals.ControllerMngr.GetController(i);
                if (controller.IsAcquired == true)
                {
                    controller.Reset();
                }
            }

            //Resume inputs
            InputHandler.ResumeRunningInputs();

            BotProgram.MsgHandler.QueueMessage($"Set console to {InputGlobals.CurrentConsoleVal} and reset all running inputs!");
        }
        public override void ExecuteCommand(EvtChatCommandArgs e)
        {
            List <string> args = e.Command.ArgumentsAsList;

            //See the virtual controller
            if (args.Count == 0)
            {
                BotProgram.MsgHandler.QueueMessage($"The current virtual controller is {InputGlobals.CurVControllerType}. To set the virtual controller, add one as an argument: {GetValidControllerStr()}");
                return;
            }

            string vControllerStr = args[0];

            if (Enum.TryParse <InputGlobals.VControllerTypes>(vControllerStr, true, out InputGlobals.VControllerTypes vCType) == false)
            {
                BotProgram.MsgHandler.QueueMessage($"Please enter a valid virtual controller: {GetValidControllerStr()}");
                return;
            }

            if (vCType == InputGlobals.CurVControllerType)
            {
                BotProgram.MsgHandler.QueueMessage($"The current virtual controller is already {InputGlobals.CurVControllerType}!");
                return;
            }

            if (InputGlobals.IsVControllerSupported(vCType) == false)
            {
                BotProgram.MsgHandler.QueueMessage($"{vCType} virtual controllers are not supported on your operating system.");
                return;
            }

            InputHandler.CancelRunningInputs();

            //Wait until no inputs are running
            while (InputHandler.CurrentRunningInputs > 0)
            {
            }

            //Change virtual controller
            InputGlobals.SetVirtualController(vCType);

            //Resume inputs
            InputHandler.ResumeRunningInputs();

            BotProgram.MsgHandler.QueueMessage($"Set virtual controller to {InputGlobals.CurVControllerType} and reset all running inputs!");
        }
Exemple #3
0
        public void Initialize()
        {
            if (Initialized == true)
            {
                return;
            }

            //Kimimaru: Use invariant culture
            Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.InvariantCulture;

            //Load all the necessary data; if something doesn't exist, save out an empty object so it can be filled in manually
            string loginText = Globals.ReadFromTextFileOrCreate(Globals.LoginInfoFilename);

            LoginInformation = JsonConvert.DeserializeObject <LoginInfo>(loginText);

            if (LoginInformation == null)
            {
                Console.WriteLine("No login information found; attempting to create file template. If created, please manually fill out the information.");

                LoginInformation = new LoginInfo();
                string text = JsonConvert.SerializeObject(LoginInformation, Formatting.Indented);
                Globals.SaveToTextFile(Globals.LoginInfoFilename, text);
            }

            LoadSettingsAndBotData();

            //Kimimaru: If the bot itself isn't in the bot data, add it as an admin!
            if (string.IsNullOrEmpty(LoginInformation.BotName) == false)
            {
                string botName = LoginInformation.BotName.ToLowerInvariant();
                User   botUser = null;
                if (BotData.Users.TryGetValue(botName, out botUser) == false)
                {
                    botUser       = new User();
                    botUser.Name  = botName;
                    botUser.Level = (int)AccessLevels.Levels.Admin;
                    BotData.Users.TryAdd(botName, botUser);

                    SaveBotData();
                }
            }

            try
            {
                Credentials = new ConnectionCredentials(LoginInformation.BotName, LoginInformation.Password);
            }
            catch (Exception exception)
            {
                Console.WriteLine($"Invalid credentials: {exception.Message}");
                Console.WriteLine("Cannot proceed. Please double check the login information in the data folder");
                return;
            }

            //Set up client service
            ClientService = new TwitchClientService(Credentials, LoginInformation.ChannelName,
                                                    Globals.CommandIdentifier, Globals.CommandIdentifier, true);

            ClientService.Initialize();

            UnsubscribeEvents();
            SubscribeEvents();

            //Set up message handler
            MsgHandler = new BotMessageHandler(ClientService, LoginInformation.ChannelName, BotSettings.MessageCooldown);

            RoutineHandler = new BotRoutineHandler(ClientService);
            RoutineHandler.AddRoutine(new PeriodicMessageRoutine());
            RoutineHandler.AddRoutine(new CreditsGiveRoutine());
            RoutineHandler.AddRoutine(new ReconnectRoutine());
            RoutineHandler.AddRoutine(new ChatBotResponseRoutine());

            //Initialize controller input - validate the controller type first
            if (InputGlobals.IsVControllerSupported((InputGlobals.VControllerTypes)BotData.LastVControllerType) == false)
            {
                BotData.LastVControllerType = (int)InputGlobals.GetDefaultSupportedVControllerType();
            }

            InputGlobals.VControllerTypes vCType = (InputGlobals.VControllerTypes)BotData.LastVControllerType;
            Console.WriteLine($"Setting up virtual controller {vCType}");

            InputGlobals.SetVirtualController(vCType);

            Initialized = true;
        }
        private void OnMessageReceived(object sender, OnMessageReceivedArgs e)
        {
            User userData = GetOrAddUser(e.ChatMessage.Username, false);

            userData.TotalMessages++;

            string possibleMeme = e.ChatMessage.Message.ToLower();

            if (BotProgram.BotData.Memes.TryGetValue(possibleMeme, out string meme) == true)
            {
                BotProgram.QueueMessage(meme);
            }
            else
            {
                //Ignore commands as inputs
                if (possibleMeme.StartsWith(Globals.CommandIdentifier) == true)
                {
                    return;
                }

                (bool valid, List <List <Parser.Input> > inputList, bool containsStartInput, int durationCounter)
                parsedData = default;

                try
                {
                    string parse_message = Parser.Expandify(Parser.PopulateMacros(e.ChatMessage.Message));

                    parsedData = Parser.Parse(parse_message);
                }
                catch
                {
                    //Kimimaru: Sanitize parsing exceptions for now
                    //Most of these are currently caused by differences in how C# and Python handle slicing strings (Substring() vs string[:])
                    //One example that throws this that shouldn't is "#mash(w234"
                    //BotProgram.QueueMessage($"ERROR: {exception.Message}");
                    parsedData.valid = false;
                }

                if (parsedData.valid == false)
                {
                    //Kimimaru: Currently this also shows this for any message - keep commented until we find a better way to differentiate them
                    //Parser.Input input = parsedData.inputList[0][0];
                    //if (string.IsNullOrEmpty(input.error) == false)
                    //    BotProgram.QueueMessage($"Invalid input: {input.error}");
                }
                else
                {
                    //Ignore if user is silenced
                    if (userData.Silenced == true)
                    {
                        return;
                    }

                    if (InputGlobals.IsValidPauseInputDuration(parsedData.inputList, "start", BotData.MaxPauseHoldDuration) == false)
                    {
                        BotProgram.QueueMessage($"Invalid input: Pause button held for longer than the max duration of {BotData.MaxPauseHoldDuration} milliseconds!");
                        return;
                    }

                    if (InputHandler.StopRunningInputs == false)
                    {
                        //Mark this as a valid input
                        userData.ValidInputs++;

                        bool shouldPerformInput = true;

                        //Check the team the user is on for the controller they should be using
                        //Validate that the controller is acquired and exists
                        int controllerNum = userData.Team;

                        if (controllerNum < 0 || controllerNum >= VJoyController.Joysticks.Length)
                        {
                            BotProgram.QueueMessage($"ERROR: Invalid joystick number {controllerNum + 1}. # of joysticks: {VJoyController.Joysticks.Length}. Please change your controller port to a valid number to perform inputs.");
                            shouldPerformInput = false;
                        }
                        //Now verify that the controller has been acquired by vJoy
                        else if (VJoyController.Joysticks[controllerNum].IsAcquired == false)
                        {
                            BotProgram.QueueMessage($"ERROR: Joystick number {controllerNum + 1} with controller ID of {VJoyController.Joysticks[controllerNum].ControllerID} has not been acquired by the vJoy driver! Ensure you (the streamer) have a vJoy device set up at this ID.");
                            shouldPerformInput = false;
                        }

                        //We're okay to perform the input
                        if (shouldPerformInput == true)
                        {
                            InputHandler.CarryOutInput(parsedData.inputList, controllerNum);

                            //If auto whitelist is enabled, the user reached the whitelist message threshold,
                            //the user isn't whitelisted, and the user hasn't ever been whitelisted, whitelist them
                            if (BotSettings.AutoWhitelistEnabled == true && userData.Level < (int)AccessLevels.Levels.Whitelisted &&
                                userData.AutoWhitelisted == false && userData.ValidInputs >= BotSettings.AutoWhitelistInputCount)
                            {
                                userData.Level           = (int)AccessLevels.Levels.Whitelisted;
                                userData.AutoWhitelisted = true;

                                if (string.IsNullOrEmpty(BotSettings.AutoWhitelistMsg) == false)
                                {
                                    //Replace the user's name with the message
                                    string msg = BotSettings.AutoWhitelistMsg.Replace("{0}", e.ChatMessage.Username);
                                    QueueMessage(msg);
                                }
                            }
                        }
                    }
                    else
                    {
                        QueueMessage("New inputs cannot be processed until all other inputs have stopped.");
                    }

                    //Debug info
                    //BotProgram.QueueMessage("Valid input!");
                    //string thing = "Valid input(s): ";
                    //
                    //for (int i = 0; i < parsedData.inputList.Count; i++)
                    //{
                    //    for (int j = 0; j < parsedData.inputList[i].Count; j++)
                    //    {
                    //        Parser.Input thing2 = parsedData.inputList[i][j];
                    //
                    //        thing += thing2.ToString() + "\n";
                    //    }
                    //}
                    //Console.WriteLine(thing);
                }
            }

            //Kimimaru: For testing this will work, but we shouldn't save after each message
            SaveBotData();
        }