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