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 void Dispose() { if (Initialized == false) { return; } UnsubscribeEvents(); for (int i = 0; i < BotRoutines.Count; i++) { BotRoutines[i].CleanUp(Client); } ClientMessages.Clear(); Client.Disconnect(); //Clean up and relinquish the devices when we're done VJoyController.CleanUp(); instance = null; }
public override void ExecuteCommand(object sender, OnChatCommandReceivedArgs e) { List <string> args = e.Command.ArgumentsAsList; if (args.Count != 1) { BotProgram.QueueMessage($"Usage: \"# of controllers (min: {VJoyController.MIN_VJOY_DEVICE_ID}, max: {VJoyController.MAX_VJOY_DEVICE_ID})\""); return; } if (int.TryParse(args[0], out int newJoystickCount) == false) { BotProgram.QueueMessage("Invalid number of controllers!"); return; } if (newJoystickCount < VJoyController.MIN_VJOY_DEVICE_ID) { BotProgram.QueueMessage($"Value is less than {VJoyController.MIN_VJOY_DEVICE_ID}!"); return; } if (newJoystickCount > VJoyController.MAX_VJOY_DEVICE_ID) { BotProgram.QueueMessage($"Value is greater than {VJoyController.MAX_VJOY_DEVICE_ID}, which is the max number of supported controllers!"); return; } if (newJoystickCount == BotProgram.BotData.JoystickCount) { BotProgram.QueueMessage("There are already that many controllers plugged in!"); return; } //We changed count, so let's stop all inputs and reinitialize the vJoy devices BotProgram.QueueMessage($"Changing controller count from {BotProgram.BotData.JoystickCount} to {newJoystickCount}. Stopping all inputs and reinitializing."); InputHandler.CancelRunningInputs(); //Wait until no inputs are running while (InputHandler.CurrentRunningInputs > 0) { } //Reinitialize the vJoy devices VJoyController.CleanUp(); //Kimimaru: Time out so we don't softlock everything if all devices cannot be freed //While this is an issue if it happens, we'll let the streamer know without permanently suspending inputs const long timeOut = 60000; Stopwatch sw = Stopwatch.StartNew(); //Wait until all vJoy devices are no longer owned while (true) { int freeCount = 0; for (int i = 0; i < VJoyController.Joysticks.Length; i++) { VjdStat stat = VJoyController.VJoyInstance.GetVJDStatus(VJoyController.Joysticks[i].ControllerID); if (stat != VjdStat.VJD_STAT_OWN) { freeCount++; } } //We're done if all are no longer owned if (freeCount == VJoyController.Joysticks.Length) { break; } if (sw.ElapsedMilliseconds >= timeOut) { BotProgram.QueueMessage($"ERROR: Unable to free all vJoy controllers. {freeCount}/{VJoyController.Joysticks.Length} freed."); break; } } int acquiredCount = VJoyController.InitControllers(newJoystickCount); Console.WriteLine($"Acquired {acquiredCount} controllers!"); const long wait = 500L; sw.Stop(); sw.Reset(); sw.Start(); //Wait again to reinitialize while (sw.ElapsedMilliseconds < wait) { } InputHandler.ResumeRunningInputs(); BotProgram.BotData.JoystickCount = newJoystickCount; BotProgram.SaveBotData(); BotProgram.QueueMessage("Controllers reinitialized and inputs resumed!"); }
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(); }
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.Add(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; } Client = new TwitchClient(); Client.Initialize(Credentials, LoginInformation.ChannelName, Globals.CommandIdentifier, Globals.CommandIdentifier, true); Client.OverrideBeingHostedCheck = true; UnsubscribeEvents(); Client.OnJoinedChannel += OnJoinedChannel; Client.OnMessageReceived += OnMessageReceived; Client.OnWhisperReceived += OnWhisperReceived; Client.OnNewSubscriber += OnNewSubscriber; Client.OnReSubscriber += OnReSubscriber; Client.OnChatCommandReceived += OnChatCommandReceived; Client.OnBeingHosted += OnBeingHosted; Client.OnConnected += OnConnected; Client.OnConnectionError += OnConnectionError; Client.OnDisconnected += OnDisconnected; AddRoutine(new PeriodicMessageRoutine()); AddRoutine(new CreditsGiveRoutine()); //Initialize controller input VJoyController.Initialize(); VJoyController.CheckButtonCount(1); Initialized = true; }