Bobrocket Posted May 29, 2015 Share Posted May 29, 2015 (edited) Alright, so after reading the "My Ban Theory" thread, I decided to take the idea of a normal distribution to keyboard typing. What I have made is experimental and may not work as expected to. All I aim to do with this is help to educate those with typing correctly. How it works: Calculating based on words per minute, it sleeps a variable amount based on the value (assuming the average word has 6 characters) With the help of normal distributions, the mean is the mode and the median (which is also usually the midpoint), so we can calculate a normal distribution of sleeping using the mean. It types character per character It wraps the Script sleep function to pause the appropriate time frame (Version 1.1 and onwards) now makes typing errors based on the words per minute setting! Version 1.1 (newest; typos included): import java.util.ArrayList; import java.util.Random; import org.osbot.rs07.api.Keyboard; import org.osbot.rs07.script.Script; public class SmartKeyboard { public int wordsPM, charsPM, charsPS, msPC, minMS, maxMS, typoRate = 0; public Random rand; public Script baseScript; public Keyboard kb; public int typoConstant = 100000; //You can change this if needed //This is a huge array of all potential typos for every alphabet character public String[][] typos = new String[][] { { "q", "s", "z" }, //a { "v", "g", "n" }, { "x", "d", "v" }, { "s", "e", "f", "c" }, //bcd { "w", "d", "r" }, { "d", "r", "g", "v" }, { "f", "t", "h", "b" }, //efg { "g", "y", "j", "n" }, { "u", "k", "o" }, { "h", "m", "k", "u" }, //hij { "j", ",", "l", "i" }, { "k", ".", ";", "o" }, { "n", "j", "," }, //klm { "b", "h", "m" }, { "i", "l", "p" }, { "o", ";", "[" }, //nop { "w", "a", "s" }, { "e", "f", "t", "4" }, { "w", "a", "d", "x" },//qrs { "r", "g", "y", "5" }, { "y", "j", "i", "8" }, { "c", "f", "b" },//tuv { "q", "s", "e" }, { "z", "s", "c", "d" }, { "t", "h", "u", "j" }, //wxy { "a", "s", "x", "\\" }//z }; public String alphabet = "abcdefghijklmnopqrstuvwxyz"; public SmartKeyboard(Script base, int wpm) { baseScript = base; kb = base.getKeyboard(); wordsPM = wpm; charsPM = (wpm * 6); charsPS = charsPM / 60; msPC = 1000 / charsPS; rand = new Random(); minMS = msPC - (wordsPM / 2) + rand.nextInt(15); //Make this a little bit more random to simulate real key presses maxMS = msPC + (wordsPM / 2) + rand.nextInt(15); } public boolean typeString(String toType, boolean enter, boolean typos) throws InterruptedException { int x = calculateTypo(); ArrayList<TypoChar> indexes = new ArrayList<TypoChar>(); int index = 0; for (char ch : toType.toCharArray()) { //Here we are going to erase any typos if (typos && rand.nextInt(2) == 1) { for (TypoChar tc : indexes) { if (tc.index == (index - 1)) { //We're going to erase this fucker kb.typeKey((char)8); //8 is the backspace character (or 127 which is delete, not sure here) sleep(rand(minMS, maxMS, msPC)); kb.typeKey(tc.original); sleep(rand(minMS, maxMS, msPC)); } } } char old = ch; if (typos && (rand.nextInt(x) == (x / 2))) { ch = toTypo(String.valueOf(ch)).toCharArray()[0]; indexes.add(new TypoChar(index, old)); //We're going to see } kb.typeKey(ch); sleep(rand(minMS, maxMS, msPC)); index++; } if (enter) { pressEnter(); } return true; } public boolean typeCharacter(String character, boolean enter) throws InterruptedException { kb.typeKey(character.toCharArray()[0]); sleep(rand(minMS, maxMS, msPC)); if (enter) { pressEnter(); } return true; } public boolean typeInteger(int integer, boolean enter) throws InterruptedException { kb.typeKey(Character.forDigit(integer, 10)); sleep(rand(minMS, maxMS, msPC)); if (enter) { pressEnter(); } return true; } public boolean pressEnter() { kb.typeKey((char)13); kb.typeKey((char)10); return true; } public int calculateTypo() { int temp = typoConstant / (wordsPM * 10); temp += rand.nextInt(6); return temp; } public String toTypo(String toTypo) { //TODO: preserve uppercase (if wanted) toTypo = toTypo.toLowerCase(); int index = alphabet.indexOf(toTypo.charAt(0)); //Get the index to get typos for String[] charTypos = typos[index]; //We have our typos stored in the order abcdef...z int len = charTypos.length; toTypo = charTypos[getRandom(0, len - 1)]; //We do len - 1 as Java uses zero-based arrays. return toTypo; } public int rand(int min, int max, int mean) { //Edited slightly; in a normal distribution, mean = mode = median = midpoint of graph int n; //int mean = (min + max) / 2; int std = (max - mean) / 3; Random r = new Random(); do { double val = r.nextGaussian() * std + mean; n = (int) Math.round(val); } while (n < min || n > max); return n; } public int getRandom(int min, int max) { int range = (max - min) + 1; return rand.nextInt(range) + min; } public void sleep(int t) throws InterruptedException { Script.sleep(t); } } class TypoChar { //We'll make an arraylist of these bad boys public int index; public char original; public TypoChar(int i, char o) { original = o; index = i; } } Version 1.0 (old; no typos included): import java.util.Random; import org.osbot.rs07.api.Keyboard; import org.osbot.rs07.script.Script; public class SmartKeyboard { public int wordsPM, charsPM, charsPS, msPC, minMS, maxMS = 0; public Random rand; public Script baseScript; public Keyboard kb; public SmartKeyboard(Script base, int wpm) { baseScript = base; kb = base.getKeyboard(); wordsPM = wpm; charsPM = (wpm * 6); charsPS = charsPM / 60; msPC = 1000 / charsPS; rand = new Random(); minMS = msPC - (wordsPM / 2) + rand.nextInt(15); //Make this a little bit more random to simulate real key presses maxMS = msPC + (wordsPM / 2) + rand.nextInt(15); } public boolean typeString(String toType, boolean enter) throws InterruptedException { for (char ch : toType.toCharArray()) { kb.typeKey(ch); sleep(rand(minMS, maxMS, msPC)); } if (enter) { pressEnter(); } return true; } public boolean typeCharacter(String character, boolean enter) throws InterruptedException { kb.typeKey(character.toCharArray()[0]); sleep(rand(minMS, maxMS, msPC)); if (enter) { pressEnter(); } return true; } public boolean typeInteger(int integer, boolean enter) throws InterruptedException { kb.typeKey(Character.forDigit(integer, 10)); sleep(rand(minMS, maxMS, msPC)); if (enter) { pressEnter(); } return true; } public boolean pressEnter() { kb.typeKey((char)13); kb.typeKey((char)10); return true; } public int rand(int min, int max, int mean) { //Edited slightly; in a normal distribution, mean = mode = median = midpoint of graph int n; //int mean = (min + max) / 2; int std = (max - mean) / 3; Random r = new Random(); do { double val = r.nextGaussian() * std + mean; n = (int) Math.round(val); } while (n < min || n > max); return n; } public void sleep(int t) throws InterruptedException { Script.sleep(t); } } Usage example: SmartKeyboard sk = new SmartKeyboard(this, 60); //60 words per minute if (sk.typeString("The quick brown fox jumped over the lazy dog", true, true)) { //Third parameter to true -> enables typos log("Typed the string and pressed enter!"); } if (sk.typeCharacter("g")) { log("Typed the character 'g'"); } if (sk.typeInteger(4)) { log("Typed the number 4!"); } sk.typoConstant = 10000; //Default 100000; lower = more likely to cause a typo; equation ((typoConstant / (words per minute * 10))+ rand.nextInt(6)) If there are any problems with this, let me know. Jagex may be smart, but we're smarter. Proof of typos: (set at 125wpm; original text "The quick brown fox jumped over the lazy dog the quick brown") Feel free to use the SmartKeyboard class however you want, but credit is always nice Edited May 29, 2015 by Bobrocket 9 Quote Link to comment Share on other sites More sharing options...
FrostBug Posted May 29, 2015 Share Posted May 29, 2015 Looks pretty nice Inb4 make and correct typos 2 Quote Link to comment Share on other sites More sharing options...
Bobrocket Posted May 29, 2015 Author Share Posted May 29, 2015 (edited) Looks pretty nice Inb4 make and correct typos I was thinking about typos. What I'm going to do is make a little keychar map with nested arrays (for example, "a" typos could be "q", "s", "z") and then have a chance to see and correct it before typing (pressing backspace x amount of times and then pressing the correct key) or simply not noticing and then in a new message doing the classic "word*". Edit: the equation for a random typo could just be (100000 / (wordsPM * 10) - rand.nextInt(5))? This way it still has a degree of randomness, but it still scales nicely with the words per minute factor (ofc you're not going to make many or any typos at 1wpm but you will at 120wpm) Edit 2: working typos! Set at 125wpm in the example, with the original text "The quick brown fox jumped over the lazy dog the quick brown". Currently, there is a 33% chance that the controller will actually fix the typo. You can change this in the typeString method (where it says if (typos && rand.nextInt(2) == 1 ) {) Good luck everyone, and happy botting Edited May 29, 2015 by Bobrocket 1 Quote Link to comment Share on other sites More sharing options...
Botre Posted May 29, 2015 Share Posted May 29, 2015 pretty cool idea Quote Link to comment Share on other sites More sharing options...
FrostBug Posted May 29, 2015 Share Posted May 29, 2015 I was thinking about typos. What I'm going to do is make a little keychar map with nested arrays (for example, "a" typos could be "q", "s", "z") and then have a chance to see and correct it before typing (pressing backspace x amount of times and then pressing the correct key) or simply not noticing and then in a new message doing the classic "word*". Edit: the equation for a random typo could just be (100000 / (wordsPM * 10) - rand.nextInt(5))? This way it still has a degree of randomness, but it still scales nicely with the words per minute factor (ofc you're not going to make many or any typos at 1wpm but you will at 120wpm) Edit 2: working typos! Set at 125wpm in the example, with the original text "The quick brown fox jumped over the lazy dog the quick brown". Currently, there is a 33% chance that the controller will actually fix the typo. You can change this in the typeString method (where it says if (typos && rand.nextInt(2) == 1 ) {) Good luck everyone, and happy botting Have my babies, sir 1 Quote Link to comment Share on other sites More sharing options...
Bobrocket Posted May 29, 2015 Author Share Posted May 29, 2015 Have my babies, sir Fuck no. Quote Link to comment Share on other sites More sharing options...
Ace Posted February 8, 2016 Share Posted February 8, 2016 Hey, just tried it out and it doesn't seem to work if I try to type an integer, it just doesn't type anything Quote Link to comment Share on other sites More sharing options...
Bobrocket Posted February 8, 2016 Author Share Posted February 8, 2016 Hey, just tried it out and it doesn't seem to work if I try to type an integer, it just doesn't type anything This was made 9 months ago and hasn't been touched. Recreate it using key character events, much better. 1 Quote Link to comment Share on other sites More sharing options...
Aeonx Posted February 14, 2016 Share Posted February 14, 2016 Thanks, really useful Quote Link to comment Share on other sites More sharing options...
Dark Magician Posted March 9, 2016 Share Posted March 9, 2016 Seems pretty interesting. Quote Link to comment Share on other sites More sharing options...