commit c75292cba7c0c0ee632708e21477a920990eb00d Author: Samuel Pua Date: Thu Aug 22 01:02:25 2019 +0800 First commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..cec34c4 --- /dev/null +++ b/README.md @@ -0,0 +1,21 @@ +# Mr Robotic - A cross-platform desktop automation tool + +Mr Robotic is a cross-platform desktop automation tool mainly used for auto-clicking and auto-typing. + +### Prerequisites + +Mr Robotic is built on Go, and have all required libraries built-in within the binary. + +To attempt to recompile the application, the following is required: + +* Go +* robotgo +* Dependencies for robotgo + +Cross-compilation isn't the most stable thing, so OS specific compilation is recommended. + +## Authors + +* **Samuel Pua** - *Initial work* - [GitHub](https://github.com/telboon) + + diff --git a/keys.txt b/keys.txt new file mode 100644 index 0000000..5863172 --- /dev/null +++ b/keys.txt @@ -0,0 +1,16 @@ +sleep 601 +mouseLeftClick 671,570 +sleep 400 +mouseLeftClick 900,531 +sleep 300 +mouseLeftClick 884,333 +sleep 300 +mouseLeftClick 808,493 +sleep 300 +mouseLeftClick 800,495 +sleep 1403 +mouseLeftClick 885,125 +sleep 200 +mouseLeftClick 885,125 +sleep 300 +mouseLeftClick 885,125 diff --git a/main.go b/main.go new file mode 100644 index 0000000..286a8bc --- /dev/null +++ b/main.go @@ -0,0 +1,439 @@ +package main + +import ( + "bufio" + "os" + "io/ioutil" + "fmt" + "strings" + "strconv" + "time" + "runtime" + "github.com/go-vgo/robotgo" +) + +const ( + MOUSELEFTCLICK = "mouseLeftClick" + MOUSERIGHTCLICK = "mouseRightClick" + MOUSEMOVE = "mouseMove" + SLEEP = "sleep" + KEYBOARD = "keyboard" + TAPESCAPE = "tapEscape" + TAPTAB = "tapTab" + TAPUP = "tabUp" + TAPDOWN = "tapDown" + TAPLEFT = "tapLeft" + TAPRIGHT = "tabRight" +) + +var ( + KEYQ uint16 + KEYW uint16 + KEYE uint16 + KEYA uint16 + KEYS uint16 + KEYD uint16 + KEYR uint16 + KEYZ uint16 + KEYCTRL uint16 + KEYESC uint16 + KEYTAB uint16 + KEYUP uint16 + KEYDOWN uint16 + KEYLEFT uint16 + KEYRIGHT uint16 +) + +func mainMenu(keyCommands *[]string, runCount *int) string { + exitChan := make(chan bool, 1) + go listenRun(exitChan, keyCommands, runCount) + fmt.Println(`Main Menu + + l: Listening mode + f: Read from file ("keys.txt") + s: Save to file ("keys.txt") + p: Print stored command + c: Change run count + r: Run stored command (Hotkey: ctrl-r) + `) + reader := bufio.NewReader(os.Stdin) + fmt.Print("Enter Command: ") + command, _ := reader.ReadString('\n') + command = strings.ReplaceAll(command, "\n", "") + command = strings.ReplaceAll(command, "\r", "") + exitChan <- true + return command +} + +func listenRun(exitChan chan bool, keyCommands *[]string, runCount *int) { + time.Sleep(500 * time.Millisecond) + evtChan := robotgo.Start() + defer robotgo.End() + + // Rawcode + // 65507, 162 - ctrl + // 114, 82 - r + + // Kind + // 3 - keydown + // 5 - keyup + + ctrlKey := false + rKey := false + + for evt := range evtChan { + // return if exit signal is given + select { + case <- exitChan: + return + default: + if (evt.Kind == 3 || evt.Kind == 4) && (evt.Rawcode == KEYCTRL) { + ctrlKey = true + } else if evt.Kind == 5 && (evt.Rawcode == KEYCTRL) { + ctrlKey = false + } else if evt.Kind == 3 && (evt.Rawcode == KEYR) { + rKey = true + } else if evt.Kind == 5 && (evt.Rawcode == KEYR) { + rKey = false + } + + if ctrlKey && rKey { + ctrlKey = false + rKey = false + runKeyCommands(*keyCommands, *runCount) + time.Sleep(500 * time.Millisecond) + } + } + } +} + +func listenMode(keyCommands *[]string, runCount *int) { + *keyCommands = nil + time.Sleep(500 * time.Millisecond) + fmt.Println("Entering listening mode...") + evtChan := robotgo.Start() + defer robotgo.End() + + // Rawcode + // 113, 81 - q + // 119, 87 - w + // 101, 69 - e + // 97, 65 - a + // 115, 83 - s + // 100, 68 - d + // 65307, 27 - esc + + // Kind + // 3 - keydown + // 5 - keyup + + leftMouseTrigger := 0 + rightMouseTrigger := 0 + moveMouseTrigger := 0 + sleepTrigger := 0 + typeTrigger := 0 + escapeTrigger := 0 + escapeTypeTrigger := 0 + tabTrigger := 0 + upTrigger := 0 + downTrigger := 0 + leftTrigger := 0 + rightTrigger := 0 + + lastTime := time.Now() + others := false + var newCommand string + for evt := range evtChan { + // return if exit signal is given + if evt.Kind == 4 && (evt.Rawcode == KEYQ) { + leftMouseTrigger += 1 + } else if evt.Kind == 4 && (evt.Rawcode == KEYE) { + rightMouseTrigger += 1 + } else if evt.Kind == 4 && (evt.Rawcode == KEYW) { + moveMouseTrigger += 1 + } else if evt.Kind == 4 && (evt.Rawcode == KEYS) { + sleepTrigger += 1 + } else if evt.Kind == 4 && (evt.Rawcode == KEYD) { + typeTrigger += 1 + } else if evt.Kind == 4 && (evt.Rawcode == KEYESC) { + escapeTrigger += 1 + escapeTypeTrigger += 1 + } else if evt.Kind == 5 && (evt.Rawcode == KEYESC) { + escapeTrigger = 0 + escapeTypeTrigger = 0 + } else if evt.Kind == 4 && (evt.Rawcode == KEYCTRL) { + escapeTrigger += 1 + } else if evt.Kind == 5 && (evt.Rawcode == KEYCTRL) { + escapeTrigger = 0 + } else if evt.Kind == 4 && (evt.Rawcode == KEYTAB) { + tabTrigger += 1 + } else if evt.Kind == 4 && (evt.Rawcode == KEYUP) { + upTrigger += 1 + } else if evt.Kind == 4 && (evt.Rawcode == KEYDOWN) { + downTrigger += 1 + } else if evt.Kind == 4 && (evt.Rawcode == KEYLEFT) { + leftTrigger += 1 + } else if evt.Kind == 4 && (evt.Rawcode == KEYRIGHT) { + rightTrigger += 1 + } + + if escapeTrigger == 2 { + return + } else if leftMouseTrigger == 1 { + posX, posY := robotgo.GetMousePos() + newCommand = fmt.Sprintf("%s %d,%d", MOUSELEFTCLICK, posX, posY) + leftMouseTrigger = 0 + } else if rightMouseTrigger == 1 { + posX, posY := robotgo.GetMousePos() + newCommand = fmt.Sprintf("%s %d,%d", MOUSERIGHTCLICK, posX, posY) + rightMouseTrigger = 0 + } else if moveMouseTrigger == 1 { + posX, posY := robotgo.GetMousePos() + newCommand = fmt.Sprintf("%s %d,%d", MOUSEMOVE, posX, posY) + moveMouseTrigger = 0 + } else if sleepTrigger == 1 { + newCommand = "" + sleepTrigger = 0 + } else if typeTrigger == 1 { + newCommand = fmt.Sprintf("%s \"\"", KEYBOARD) + typeTrigger = 0 + } else if escapeTypeTrigger == 1 { + newCommand = TAPESCAPE + escapeTypeTrigger = 0 + } else if tabTrigger == 1 { + newCommand = TAPTAB + tabTrigger = 0 + } else if upTrigger == 1 { + newCommand = TAPUP + upTrigger = 0 + } else if downTrigger == 1 { + newCommand = TAPDOWN + downTrigger = 0 + } else if leftTrigger == 1 { + newCommand = TAPLEFT + leftTrigger = 0 + } else if rightTrigger == 1 { + newCommand = TAPRIGHT + rightTrigger = 0 + } else { + others = true + } + + if !others { + sleepComamnd := fmt.Sprintf("%s %d", SLEEP, int(time.Since(lastTime).Seconds() * 1000)) + *keyCommands = append(*keyCommands, sleepComamnd) + if newCommand != "" { + *keyCommands = append(*keyCommands, newCommand) + } + lastTime = time.Now() + } else { + others = false + } + } +} + +func main() { + initKeys() + var keyCommands []string + var runCount int + for true { + x := mainMenu(&keyCommands, &runCount) + fmt.Println(x) + if x == "f" { + keyCommands = readFile("keys.txt") + } else if x == "c" { + runCount = changeRunCount() + } else if x == "p" { + printKeyCommands(keyCommands) + } else if x == "r" { + runKeyCommands(keyCommands, runCount) + } else if x == "l" { + listenMode(&keyCommands, &runCount) + } else if x == "s" { + writeFile("keys.txt", keyCommands) + } + } +} + +func initKeys() { + // 113, 81 - q + // 119, 87 - w + // 101, 69 - e + // 97, 65 - a + // 115, 83 - s + // 100, 68 - d + // 65307, 27 - esc + // 114, 82 - r + // 122, 90 - z + // 65507, 162 - ctrl + // 65289,9 - tab + // 65361,37 - left + // 65362,38 - up + // 65363,39 - right + // 65364,40 - down + if (runtime.GOOS == "windows") { + KEYQ = 81 + KEYW = 87 + KEYE = 69 + KEYA = 65 + KEYS = 83 + KEYD = 68 + KEYESC = 27 + KEYR = 82 + KEYCTRL = 162 + KEYTAB = 9 + KEYUP = 38 + KEYDOWN = 40 + KEYLEFT = 37 + KEYRIGHT = 39 + KEYZ = 90 + } else { + KEYQ = 113 + KEYW = 119 + KEYE = 101 + KEYA = 97 + KEYS = 115 + KEYD = 100 + KEYESC = 65307 + KEYR = 114 + KEYCTRL = 65507 + KEYTAB = 65289 + KEYUP = 65362 + KEYDOWN = 65364 + KEYLEFT = 65361 + KEYRIGHT = 65363 + KEYZ = 122 + } +} + +func readFile(filename string) []string { + filecontent, err := ioutil.ReadFile(filename) + if err != nil { + fmt.Println(err) + } + keyCommands := strings.Split(string(filecontent), "\n") + return keyCommands +} + +func writeFile(filename string, keyCommand []string) { + fmt.Println("Writing instructions to file...") + f, err := os.Create(filename) + defer f.Close() + if err != nil { + fmt.Println(err) + } + for _, keyCommand := range keyCommand { + f.WriteString(keyCommand) + f.WriteString("\n") + } +} + +func changeRunCount() int { + var runCount int + fmt.Print("Enter run count: ") + reader := bufio.NewReader(os.Stdin) + countStr, _ := reader.ReadString('\n') + countStr = strings.ReplaceAll(countStr, "\n", "") + countStr = strings.ReplaceAll(countStr, "\r", "") + runCount, err := strconv.Atoi(countStr) + if err != nil { + fmt.Println(err) + fmt.Println("Setting run count as 1...") + runCount = 1 + } + return runCount +} + +func printKeyCommands(keyCommands []string) { + fmt.Println("------------------------------") + for _, keyCommand := range keyCommands { + fmt.Println(keyCommand) + } + fmt.Println("------------------------------") +} + +func runKeyCommands(keyCommands []string, runCount int) { + fmt.Printf("Running commands for %d times\n", runCount) + for i:=0; i