Jump to content
Frequently Asked Questions
  • Are you not able to open the client? Try following our getting started guide
  • Still not working? Try downloading and running JarFix
  • Help! My bot doesn't do anything! Enable fresh start in client settings and restart the client
  • How to purchase with PayPal/OSRS/Crypto gold? You can purchase vouchers from other users
  • sendHumanKeys - Type a message with mistakes w/ control over typing speed


    holic

    Recommended Posts

    The other day @bebeli555 asked about simulating keypresses with Dreambot and seemed to want more control over the function so I whipped this together.

    There are two functions you could use here:

    1. sendHumanKeys(String text, boolean enter)
      
      * @param text the message to send
      * @param enter should it press enter when finished
      Use this if you want a preset, human-like typing function
    2. void sendKeys(String text, int keyWait, int modifierWait, boolean mistakes)
      
      * @param text     String to send to the client
      * @param keyWait  wait between keystrokes
      * @param modifierWait  wait for hitting modifier keys
      * @param mistakes should it make mistakes
      Use this if you want to set a longer delay with keypresses + modifier keys

     

    These functions will type slower like a human, although Keyboard#type now offers the same functionality, and will produce mistakes in the spelling of the text with a 1 in 10 probability. It will not produce mistakes with special characters.

        /**
         * Types out a message in a human-like fashion with a chance of typing a mistake
         *
         * @param text the message to send
         */
        private void sendHumanKeys(String text, boolean enter) {
            sendKeys(text, Calculations.random(75, 125), Calculations.random(50, 80), true);
            if (enter)
                sendKeys("\n", Calculations.random(75, 125), Calculations.random(50, 80), false);
        }
    
        /**
         * Gets a nearby mistake key
         *
         * @param c Char to check for
         */
        private char getMistakeChar(char c) {
            String s = String.valueOf(c).toLowerCase();
            String[] qwerty = {"zxcvbnm,./", "asdfghjkl;'", "qwertyuiop[]", "1234567890-="};
            for (int i = 0; i < qwerty.length - 1; i++) {
                int direction = getMistakeDirection(s); //Which way to fumble the keys
                if (qwerty[i].contains(s)) { //Which row of keys contains our key
                    int modifier = Calculations.random(1, 2); //Another which way to fumble
                    int index = qwerty[i].indexOf(s) + (Calculations.random(1) == 1 ?-modifier:modifier); //New index of our character
                    int fumble = Calculations.random(1) == 1 ? 1 : -1;
                    if (i == 0) { //bottom row of keys
                        switch (direction) {
                            case -1:
                                return qwerty[i].substring(index - 1, index).toCharArray()[0];
                            case 0:
                                return qwerty[i + 1].substring(index, index + 1).toCharArray()[0];
                            default:
                                return qwerty[i].substring(index, index + 1).toCharArray()[0];
                        }
                    } else if (i == 3) { //top row of keys
                        switch (direction) {
                            case -1:
                                return qwerty[i].substring(index - 1, index).toCharArray()[0];
                            case 0:
                                return qwerty[i - 1].substring(index, index + 1).toCharArray()[0];
                            default:
                                return qwerty[i].substring(index, index + 1).toCharArray()[0];
                        }
    
                    } else {
                        switch (direction) {
                            case -1:
                                return qwerty[i].substring(index - 1, index).toCharArray()[0];
                            case 0:
                                return qwerty[i + fumble].substring(index, index + 1).toCharArray()[0];
                            default:
                                return qwerty[i].substring(index, index + 1).toCharArray()[0];
                        }
                    }
                }
            }
            return c;
        }
    
        /**
         * Checks which direction we should make a mistake
         *
         * @param s character to check
         * @result the direction of the mistake
         */
        private int getMistakeDirection(String s) {
            String left = "`qaz"; String right = "=]'/";
            if (left.contains(s)) { //If its the left column, fumble to the right
                return Calculations.random(2);
            } else if (right.contains(s)) {// If its the right column, fumble to the left
                return Calculations.random(-2,0);
            }
            return Calculations.random(-2,2);//Other fumble in any direction
        }
    
        /**
         * Checks if an entire string is uppercase
         *
         * @param str String to check
         * @result True if the string is uppercase
         */
        private boolean isStringUpperCase(String str) {
            char[] charArray = str.toCharArray();
            for (char c : charArray) {
                if (Character.isLetter(c)) {
                    if (!Character.isUpperCase(c))
                        return false;
                }
            }
    
            return true;
        }
    
        /**
         * Checks if a character requires the shift key to be pressed.
         *
         * @param c Char to check for
         * @result True if shift is required
         */
        private boolean isShiftChar(char c) {
            String special = "~!@#$%^&*()_+|{}:\"<>?";
            return special.indexOf(c) != -1 || (c - 'A' >= 0 && c - 'A' <= 25);
        }
    
        /**
         * Sends a string to the client like a person would type it.
         * Works only with qwerty keyboard setup for mistakes
         *
         * @param text     String to send to the client
         * @param keyWait  wait between keystrokes
         * @param modifierWait  wait for hitting modifier keys
         * @param mistakes should it make mistakes
         */
        public void sendKeys(String text, int keyWait, int modifierWait, boolean mistakes) {
            char[] chars = text.toCharArray();
            KeyboardEvent event = new KeyboardEvent("", false, true);
            boolean isUpper = isStringUpperCase(text);
    
            if (isUpper) { //if its all uppercase we hold shift the entire time
                Keyboard.pressShift();
                sleep((int) ((Math.random() * 0.1 + 1) * modifierWait));
            }
    
            for (char c : chars) {
                if (mistakes && Calculations.random(10) == 5) {
                    c = isShiftChar(c) ? String.valueOf(getMistakeChar(c)).toUpperCase().charAt(0) : getMistakeChar(c);
                }
                if (isShiftChar(c) && !isUpper) {//if its mixed cased, press and release as necessary
                    Keyboard.pressShift();
                    sleep((int) ((Math.random() * 0.1 + 1) * modifierWait));
                    event.dispatchPressed(c);
                    event.dispatchTyped(c);
                    sleep((int) ((Math.random() * 0.1 + 1) * keyWait));
                    event.dispatchReleased(c);
                    sleep((int) ((Math.random() * 0.1 + 1) * modifierWait));
                    Keyboard.releaseShift();
                } else {
                    event.dispatchPressed(c);
                    event.dispatchTyped(c);
                    sleep((int) ((Math.random() * 0.1 + 1) * keyWait));
                    event.dispatchReleased(c);
                }
            }
            if (!isUpper) { //if its all uppercase we hold shift the entire time
                sleep((int) ((Math.random() * 0.1 + 1) * modifierWait));
                Keyboard.releaseShift();
            }
        }

    If this could be done better, please let me know.

    Note: It seems to lock up DB3 when typing just a bit so I'm not certain. It's not an instant ban when typing at least!

    Link to comment
    Share on other sites

    6 hours ago, bebeli555 said:

    Wow. Just added this to my script and it works very well. I added random long delays like 0.5 seconds every now and then and the ability to backspace keys if it mistyped them (1 in 20 chance). 

    This is great looks way more human than the dreambot's default one. Thank you for this.

    You're welcome! And good call on the backspace, I'll add that into mine as well.

    Link to comment
    Share on other sites

    Archived

    This topic is now archived and is closed to further replies.

    ×
    ×
    • Create New...

    Important Information

    We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.