/// <summary> /// Simulates a global keystroke in the system. /// </summary> /// <param name="key">The desired key.</param> /// <param name="delay">How long the key will be held down (in milliseconds).</param> /// <returns>true if the keystroke is successfully sent, false if the key is invalid.</param> public static bool SendGlobalKeystroke(GameKey key, int delay) { // move this to a different class maybe? try { DateTime beginspam = DateTime.Now; // this seems to work to make the game register it as holding down the key // TODO: find a more reliable way to do this? while (DateTime.Now - beginspam < TimeSpan.FromMilliseconds(delay)) { SendKeys.SendWait(key.KeyString); } SendKeys.Flush(); Thread.Sleep(100); } catch (Exception) { // invalid keystroke string return(false); } return(true); }
/// <summary> /// Adds a key binding to the GUI's listview. /// </summary> /// <param name="command">Command text</param> /// <param name="thekey">Desired key</param> /// <param name="delay">How long the key will be held down</param> protected void AddKeyBinding(string command, GameKey thekey, int delay) { var item = listKeyBindings.Items.Add(command); item.SubItems.Add(thekey.Name); item.SubItems.Add(delay.ToString()); item.Tag = thekey; }
/// <summary> /// Sends the autosave keystroke. /// </summary> protected void PerformAutoSave() { try { if (menuUsePostMessage.Checked) { if (!gamewindow.SendMinimizedKeystroke(GameKey.ByKeyString(textSaveCombo.Text), 10)) { throw new Exception(); } } else { SendKeys.Send(textSaveCombo.Text); } Thread.Sleep(200); statusBar1.Text = "Successfully autosaved."; } catch (Exception) { statusBar1.Text = "Something's wrong with the autosave hotkey."; } lastautosave = DateTime.Now; }
/// <summary> /// Restores the serialized settings from settings.bin /// </summary> protected void RestoreSettings() { Settings cfg = null; if (!File.Exists("settings.bin")) { return; } IFormatter formatter = new BinaryFormatter(); Stream stream = new FileStream("settings.bin", FileMode.Open, FileAccess.Read, FileShare.Read); cfg = (Settings)formatter.Deserialize(stream); stream.Close(); menuAutosave.Checked = cfg.autosave; autosaveinterval = cfg.autosaveinterval; // internal autosave interval textAutosaveInterval.Text = autosaveinterval.ToString(); // GUI autosave interval textSaveCombo.Text = cfg.autosavekey; menuUsePostMessage.Checked = cfg.usepostmessage; // key bindings foreach (Settings.KeyBinding bind in cfg.binds) { AddKeyBinding(bind.command, GameKey.ByVKey(bind.vkey), bind.delay); } }
public bool Equals(GameKey gk) { // if parameter is null return false if ((object)gk == null) { return(false); } // return true if the fields match return(vkey == gk.vkey); }
/// <summary> /// Simulates a keystroke within the window (even if it's minimized) by /// using PostMessage. Only works on some applications. /// </summary> /// <param name="key">The desired key.</param> /// <param name="milliseconds">How long the key will be held down (in milliseconds).</param> /// <returns>true if the keystroke is successfully sent, false if the key is invalid.</returns> public bool SendMinimizedKeystroke(GameKey key, int milliseconds) { if (key == GameKey.Invalid) return false; WinAPI.PostMessage(handle, WinAPI.WM_KEYDOWN, key.VirtualKey, WinAPI.MapVirtualKey(key.VirtualKey, 0) << 16); Thread.Sleep(TimeSpan.FromMilliseconds(milliseconds)); WinAPI.PostMessage(handle, WinAPI.WM_KEYUP, key.VirtualKey, WinAPI.MapVirtualKey(key.VirtualKey, 0) << 16); Thread.Sleep(100); return true; }
/// <summary> /// Simulates a global key being held down by using keybd_event. /// </summary> /// <param name="key">The desired key.</param> /// <param name="delay">How long the key will be held down (in milliseconds).</param> /// <returns>true if the keystroke is successfully sent, false if the key is invalid.</returns> public static bool SendGlobalKeybdEvent(GameKey key, int delay) { if (key == GameKey.Invalid) return false; WinAPI.keybd_event((byte)key.VirtualKey, 0, 0, UIntPtr.Zero); Thread.Sleep(delay); WinAPI.keybd_event((byte)key.VirtualKey, 0, WinAPI.KEYEVENTF_KEYUP, UIntPtr.Zero); Thread.Sleep(100); return true; }
/// <summary> /// Simulates a keystroke within the window (even if it's minimized) by /// using PostMessage. Only works on some applications. /// </summary> /// <param name="key">The desired key.</param> /// <param name="milliseconds">How long the key will be held down (in milliseconds).</param> /// <returns>true if the keystroke is successfully sent, false if the key is invalid.</returns> public bool SendMinimizedKeystroke(GameKey key, int milliseconds) { if (key == GameKey.Invalid) { return(false); } WinAPI.PostMessage(handle, WinAPI.WM_KEYDOWN, key.VirtualKey, WinAPI.MapVirtualKey(key.VirtualKey, 0) << 16); Thread.Sleep(TimeSpan.FromMilliseconds(milliseconds)); WinAPI.PostMessage(handle, WinAPI.WM_KEYUP, key.VirtualKey, WinAPI.MapVirtualKey(key.VirtualKey, 0) << 16); Thread.Sleep(100); return(true); }
/// <summary> /// Simulates a global key being held down by using keybd_event. /// </summary> /// <param name="key">The desired key.</param> /// <param name="delay">How long the key will be held down (in milliseconds).</param> /// <returns>true if the keystroke is successfully sent, false if the key is invalid.</returns> public static bool SendGlobalKeybdEvent(GameKey key, int delay) { if (key == GameKey.Invalid) { return(false); } WinAPI.keybd_event((byte)key.VirtualKey, 0, 0, UIntPtr.Zero); Thread.Sleep(delay); WinAPI.keybd_event((byte)key.VirtualKey, 0, WinAPI.KEYEVENTF_KEYUP, UIntPtr.Zero); Thread.Sleep(100); return(true); }
private void Form1_Load(object sender, EventArgs e) { RestoreSettings(); ResetKeys(); menuStop.Enabled = false; RestoreStatus(); foreach (GameKey key in GameKey.List) // keys combobox { comboKeyBindings.Items.Add(key); } comboKeyBindings.SelectedItem = GameKey.ByName("left"); // left is selected by default }
private void buttonAddKeyBinding_Click(object sender, EventArgs e) { try { int delay = 0; GameKey thekey = (GameKey)comboKeyBindings.SelectedItem; if (thekey == null || thekey == GameKey.Invalid) { throw new InvalidOperationException("invalid key"); } try { delay = Convert.ToInt32(textDelay.Text); } catch (Exception) { throw new InvalidOperationException("invalid delay value"); } if (delay <= 0) { throw new InvalidOperationException("cannot use a negative delay"); } if (String.IsNullOrEmpty(textCommand.Text)) { throw new InvalidOperationException("the command must be at least one character long"); } for (int i = 0; i < listKeyBindings.Items.Count; i++) { if (listKeyBindings.Items[i].Text == textCommand.Text) { throw new InvalidOperationException("this command already exists"); } } AddKeyBinding(textCommand.Text, thekey, delay); } catch (InvalidOperationException shit) { MessageBox.Show("Could not add key binding: " + shit.Message, "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning); } }
public override bool Equals(Object obj) { // if parameter is null return false if (obj == null) { return(false); } // if parameter cannot be cast to GameKey return false if (!(obj is GameKey)) { return(false); } GameKey gk = (GameKey)obj; // return true if the fields match: return(vkey == gk.vkey); }
/// <summary> /// Simulates a global keystroke in the system. /// </summary> /// <param name="key">The desired key.</param> /// <param name="delay">How long the key will be held down (in milliseconds).</param> /// <returns>true if the keystroke is successfully sent, false if the key is invalid.</param> public static bool SendGlobalKeystroke(GameKey key, int delay) { // move this to a different class maybe? try { DateTime beginspam = DateTime.Now; // this seems to work to make the game register it as holding down the key // TODO: find a more reliable way to do this? while (DateTime.Now - beginspam < TimeSpan.FromMilliseconds(delay)) SendKeys.SendWait(key.KeyString); SendKeys.Flush(); Thread.Sleep(100); } catch (Exception) { // invalid keystroke string return false; } return true; }
/// <summary> /// Handles a chat line and executes any valid command found. /// </summary> /// <param name="line">A raw chat line in formatted as username\tmessage</param> protected void HandleChatLine(string line) { string msgbody = ""; // will contain the message body string user = ""; // will contain the username GameKey key = GameKey.Invalid; // will contain the requested keystroke if the message is a command int times = 1; // will contain how many times the key will be pressed if the msg is a command int delay = 0; // will contain the duration of the keystroke if the msg is a command string[] splitted = line.Split('\t'); // split username from the message body try { user = splitted[0]; msgbody = splitted[1]; } catch (Exception) { // invalid format return; } try { // throttled commands (start9 & similar) string re1 = "([a-z]{1,9})"; // command (1 to 9 letters) string re2 = "(\\d)"; // any single digit // we're separating the command from the number by using a simple regex Regex r = new Regex(re1 + re2, RegexOptions.IgnoreCase | RegexOptions.Singleline); Match m = r.Match(msgbody); if (m.Success) { msgbody = m.Groups[1].ToString(); String d1 = m.Groups[2].ToString(); times = Convert.ToInt32(d1); if (times < 1) // ignore command0's { return; } if (times > 9) // will never happen { times = 1; } } else // invalid format { times = 1; } } catch (Exception) { // invalid format times = 1; } // check if the command actually exists by searching it sequentially in the listview // TODO: index commands in a dictionary for better performance? // (not really necessary for something this trivial) for (int i = 0; i < listKeyBindings.Items.Count; i++) { var item = listKeyBindings.Items[i]; if (msgbody == item.Text) { // command found! retrieve key and duration key = (GameKey)item.Tag; delay = Convert.ToInt32(item.SubItems[2].Text); break; } } if (key == GameKey.Invalid) // command not found { return; } if (delay <= 0) // invalid delay, should never happen { return; } // should never happen if ResetKeys is properly called when it should if (!st.keypresses.ContainsKey(msgbody)) { st.keypresses.Add(msgbody, 0); } // repeat the keystroke as many times as needed for (int i = 0; i < times; i++) { st.keypresses[msgbody]++; st.totalkeypresses++; if (menuUsePostMessage.Checked) { gamewindow.SendMinimizedKeystroke(key, delay); } else { if (menuUseSendKeys.Checked) { GameWindow.SendGlobalKeystroke(key, delay); } else { GameWindow.SendGlobalKeybdEvent(key, delay); } } } commandsdone++; // this is for the command/s counter // log the command listBoxCommands.Items.Add(user + " " + msgbody + (times > 1 ? times.ToString() : "")); // keep the command log under 100 lines to save RAM if (listBoxCommands.Items.Count > 100) { listBoxCommands.Items.RemoveAt(0); } // autscroll the command log to the bottom listBoxCommands.TopIndex = listBoxCommands.Items.Count - 1; // refresh keypresses counter in the GUI labelKeyPresses.Text = "Keypresses: " + st.totalkeypresses; }
public bool Equals(GameKey gk) { // if parameter is null return false if ((object)gk == null) return false; // return true if the fields match return vkey == gk.vkey; }