def Run( self, btn, idx: int, # The current line number split_line # The current line, split ): print("[cmds_head] " + coords + " Line:" + str(idx + 1) + " Simple keybind: " + split_line[1]) #PRESS key = kb.sp(split_line[1]) releasefunc = lambda: kb.release(key) kb.press(key) #WAIT_UNPRESSED while lp_events.pressed[x][y]: sleep(DELAY_EXIT_CHECK) if btn.Check_kill(releasefunc): return idx + 1 #RELEASE kb.release(key) return idx + 1
def Process(self, btn, idx, split_line): cnt = self.Param_count(btn) # how many parameters? key = kb.sp(self.Get_param(btn, 1)) # what key? releasefunc = lambda: None # default is no release function taps = self.Get_param( btn, 2, 1) # Assume 1 tap unless we are told there's more delay = 0 # assume no delay unless we're told there is one if cnt == 3: delay = self.Get_param(btn, 3) releasefunc = lambda: kb.release( key ) # and in this case we'll also need to set up a lambda to release it precheck = delay == 0 and taps > 1 # we need to check if there's no delay and (possibly many) taps for tap in range(taps): # for each tap if btn.Check_kill(releasefunc): # see if we've been killed return idx + 1 # @@@ shouldn't this be -1? if delay == 0: kb.tap(key) else: kb.press(key) if precheck and btn.Check_kill(releasefunc): return -1 if delay > 0: if not btn.Safe_sleep(delay, releasefunc): return -1 releasefunc()
def Validate( self, btn, idx: int, # The current line number split_line, # The current line, split pass_no # interpreter pass (1=gather symbols & check syntax, 2=check symbol references) ): if pass_no == 1: if idx > 0: # headers normally have to check the line number return ("Line:" + str(idx + 1) + " - " + self.name + " must appear on the first line.", btn.Line(0)) if len(split_line) < 2: return ("Line:" + str(idx + 1) + " - " + self.name + " requires a key to bind.", btn.Line(idx)) if len(split_line) > 2: return ("Line:" + str(idx + 1) + " - " + self.name + " only take one argument", btn.Line(idx)) if kb.sp(split_line[1]) == None: return ("Line:" + str(idx + 1) + " - No key named '" + split_line[1] + "'.", btn.Line(idx)) for lin in lines[1:]: if lin != "" and lin[0] != "-": return ("Line:" + str(idx + 1) + " - When " + self.name + " is used, scripts can only contain comments.", lin) return True
def Process(self, btn, idx, split_line): hwnd = win32gui.GetForegroundWindow() # get the current window try: # clear the clipboard win32clipboard.OpenClipboard(hwnd) win32clipboard.EmptyClipboard() finally: win32clipboard.CloseClipboard() try: # do the keyboard stuff for copy (sending a WM_COPY message does not always work) kb.press(kb.sp('ctrl')) kb.tap(kb.sp('c')) finally: kb.release(kb.sp('ctrl')) if self.Param_count(btn) > 0: # save to variable if required try: win32clipboard.OpenClipboard(hwnd) t = win32clipboard.GetClipboardData(win32con.CF_TEXT) self.Set_param(btn, 1, t) finally: win32clipboard.CloseClipboard()
def Process(self, btn, idx, split_line): if self.Param_count( btn) > 0: # place variable into clipboard if required hwnd = win32gui.GetForegroundWindow() # get the current window c = self.Get_param(btn, 1) # get the value try: win32clipboard.OpenClipboard(hwnd) win32clipboard.EmptyClipboard( ) # clear the clipboard first (because that makes it work) win32clipboard.SetClipboardText( str(c)) # and put the string in the clipboard finally: win32clipboard.CloseClipboard() # win32api.SendMessage(hwnd, win32con.WM_PASTE, 0, 0) # do a paste try: kb.press( kb.sp('ctrl') ) # do a ctrl v (because the message version isn't reliable) kb.tap(kb.sp('v')) finally: kb.release(kb.sp('ctrl'))
def validate_script(script_str): if script_str == "": return True script_lines = script_str.split('\n') first_line = script_lines[0].strip() first_line_split = first_line.split(" ") if first_line_split[0] == "@ASYNC": if len(first_line_split) > 1: return ("@ASYNC takes no arguments.", script_lines[0]) temp = script_lines.pop(0) if first_line_split[0] == "@SIMPLE": if len(first_line_split) < 2: return ("@SIMPLE requires a key to bind.", first_line) if len(first_line_split) > 2: return ("@SIMPLE only take one argument", first_line) if kb.sp(first_line_split[1]) == None: return ("No key named '" + first_line_split[1] + "'.", first_line) for line in script_lines[1:]: line = line.strip() if line != "" and line[0] != "-": return ( "When @SIMPLE is used, scripts can only contain comments.", line) #parse labels labels = [] for line in script_lines: line = line.strip() split_line = line.split(" ") if split_line[0] == "LABEL": if len(split_line) != 2: return ("'" + split_line[0] + "' takes exactly 1 argument.", line) if split_line[1] in labels: return ("Label '" + split_line[1] + "' defined multiple times.", line) else: labels.append(split_line[1]) for idx, line in enumerate(script_lines): for sep in (files.ENTRY_SEPERATOR, files.BUTTON_SEPERATOR, files.NEWLINE_REPLACE): if sep[1:-1] in line: return ("You cannot use the string '" + sep[1:-1] + "' in any script.", line) line = line.strip() if line != "": if line[0] != "-": split_line = line.split(' ') if split_line[0][0] == "@": if idx != 0: return ( "Headers must only be used on the first line of a script.", line) if split_line[0] not in VALID_COMMANDS: return ("Command '" + split_line[0] + "' not valid.", line) if split_line[0] in [ "STRING", "DELAY", "TAP", "PRESS", "RELEASE", "WEB", "WEB_NEW", "SOUND", "M_MOVE", "M_SET", "M_SCROLL", "OPEN" ]: if len(split_line) < 2: return ("Too few arguments for command '" + split_line[0] + "'.", line) if split_line[0] in [ "WAIT_UNPRESSED", "RELEASE_ALL", "RESET_REPEATS" ]: if len(split_line) > 1: return ("Too many arguments for command '" + split_line[0] + "'.", line) if split_line[0] in [ "DELAY", "WEB", "WEB_NEW", "PRESS", "RELEASE" ]: if len(split_line) > 2: return ("Too many arguments for command '" + split_line[0] + "'.", line) if split_line[0] in ["SOUND", "M_MOVE", "M_SCROLL", "M_SET"]: if len(split_line) > 3: return ("Too many arguments for command '" + split_line[0] + "'.", line) if split_line[0] in ["TAP"]: if len(split_line) > 4: return ("Too many arguments for command '" + split_line[0] + "'.", line) if len(split_line) > 3: try: temp = float(split_line[3]) except: return (split_line[0] + "Tap wait time '" + split_line[3] + "' not valid.", line) if len(split_line) > 2: try: temp = int(split_line[2]) except: return (split_line[0] + " repetitions '" + split_line[2] + "' not valid.", line) if split_line[0] in ["M_LINE"]: if len(split_line) > 7: return ("Too many arguments for command '" + split_line[0] + "'.", line) if split_line[0] in ["TAP", "PRESS", "RELEASE"]: if kb.sp(split_line[1]) == None: return ("No key named '" + split_line[1] + "'.", line) if split_line[0] == "DELAY": try: temp = float(split_line[1]) except: return ("Delay time '" + split_line[1] + "' not valid.", line) if split_line[0] == "WAIT_UNPRESSED": if len(split_line) > 1: return ("'WAIT_UNPRESSED' takes no arguments.", line) if split_line[0] == "SOUND": final_name = sound.full_name(split_line[1]) if not os.path.isfile(final_name): return ("Sound file '" + final_name + "' not found.", line) if not sound.is_valid(split_line[1]): return ("Sound file '" + final_name + "' not valid.", line) if len(split_line) > 2: try: vol = float(float(split_line[2]) / 100.0) if (vol < 0.0) or (vol > 1.0): return ( "'SOUND' volume must be between 0 and 100.", line) except: return ("'SOUND' volume " + split_line[2] + " not valid.", line) if split_line[0] in ["M_STORE", "M_RECALL"]: if len(split_line) > 1: return ("'" + split_line[0] + "' takes no arguments.", line) if split_line[0] == "M_RECALL_LINE": if len(split_line) > 1: try: temp = float(split_line[1]) except: return ("'" + split_line[0] + "' wait value '" + split_line[1] + "' not valid.", line) if len(split_line) > 2: try: temp = int(split_line[2]) if temp == 0: return ("'" + split_line[0] + "' skip value cannot be zero.", line) except: return ("'" + split_line[0] + "' skip value '" + split_line[2] + "' not valid.", line) if split_line[0] == "M_MOVE": if len(split_line) < 3: return ( "'M_MOVE' requires both an X and a Y movement value.", line) try: temp = int(split_line[1]) except: return ("'M_MOVE' X value '" + split_line[1] + "' not valid.", line) try: temp = int(split_line[2]) except: return ("'M_MOVE' Y value '" + split_line[2] + "' not valid.", line) if split_line[0] == "M_SET": if len(split_line) < 3: return ("'M_SET' requires both an X and a Y value.", line) try: temp = int(split_line[1]) except: return ("'M_SET' X value '" + split_line[1] + "' not valid.", line) try: temp = int(split_line[2]) except: return ("'M_SET' Y value '" + split_line[2] + "' not valid.", line) if split_line[0] == "M_SCROLL": try: temp = float(split_line[1]) except: return ("Invalid scroll amount '" + split_line[1] + "'.", line) if len(split_line) > 2: try: temp = float(split_line[2]) except: return ("Invalid scroll amount '" + split_line[2] + "'.", line) if split_line[0] == "M_LINE": if len(split_line) < 5: return ( "'M_LINE' requires at least X1, Y1, X2, and Y2 arguments.", line) try: temp = int(split_line[1]) except: return ("'M_LINE' X1 value '" + split_line[1] + "' not valid.", line) try: temp = int(split_line[2]) except: return ("'M_LINE' Y1 value '" + split_line[2] + "' not valid.", line) try: temp = int(split_line[3]) except: return ("'M_LINE' X2 value '" + split_line[3] + "' not valid.", line) try: temp = int(split_line[4]) except: return ("'M_LINE' Y2 value '" + split_line[4] + "' not valid.", line) if len(split_line) >= 6: try: temp = float(split_line[5]) except: return ("'M_LINE' wait value '" + split_line[5] + "' not valid.", line) if len(split_line) >= 7: try: temp = int(split_line[6]) if temp == 0: return ("'M_LINE' skip value cannot be zero.", line) except: return ("'M_LINE' skip value '" + split_line[6] + "' not valid.", line) if split_line[0] in ["M_LINE_MOVE", "M_LINE_SET"]: if len(split_line) < 3: return ("'" + split_line[0] + "' requires at least X and Y arguments.", line) try: temp = int(split_line[1]) except: return ("'" + split_line[0] + "' X value '" + split_line[1] + "' not valid.", line) try: temp = int(split_line[2]) except: return ("'" + split_line[0] + "' Y value '" + split_line[2] + "' not valid.", line) if len(split_line) >= 4: try: temp = float(split_line[3]) except: return ("'" + split_line[0] + "' wait value '" + split_line[3] + "' not valid.", line) if len(split_line) >= 5: try: temp = int(split_line[4]) if temp == 0: return ("'" + split_line[0] + "' skip value cannot be zero.", line) except: return ("'" + split_line[0] + "' skip value '" + split_line[4] + "' not valid.", line) if split_line[0] in [ "GOTO_LABEL", "IF_PRESSED_GOTO_LABEL", "IF_UNPRESSED_GOTO_LABEL" ]: if len(split_line) != 2: return ("'" + split_line[0] + "' takes exactly 1 argument.", line) if split_line[1] not in labels: return ("Label '" + split_line[1] + "' not defined in this script.", line) if split_line[0] in [ "REPEAT_LABEL", "IF_PRESSED_REPEAT_LABEL", "IF_UNPRESSED_REPEAT_LABEL" ]: if len(split_line) != 3: return ( "'" + split_line[0] + "' needs both a label name and how many times to repeat.", line) if split_line[1] not in labels: return ("Label '" + split_line[1] + "' not defined in this script.", line) try: temp = int(split_line[2]) if temp < 1: return (split_line[0] + " requires a minimum of 1 repeat.", line) except: return (split_line[0] + " number of repeats '" + split_line[2] + "' not valid.", line) if split_line[0] == "OPEN": path_name = " ".join(split_line[1:]) if (not os.path.isfile(path_name)) and ( not os.path.isdir(path_name)): return (split_line[0] + " folder or file location '" + path_name + "' does not exist.", line) return True
def main_logic(idx): nonlocal m_pos if threads[x][y].kill.is_set(): print("[scripts] " + coords + " Recieved exit flag, script exiting...") threads[x][y].kill.clear() if not is_async: running = False threading.Timer(EXIT_UPDATE_DELAY, lp_colors.updateXY, (x, y)).start() return idx + 1 line = script_lines[idx].strip() if line == "": print("[scripts] " + coords + " Empty line") elif line[0] == "-": print("[scripts] " + coords + " Comment: " + line[1:]) else: split_line = line.split(" ") if split_line[0] == "STRING": type_string = " ".join(split_line[1:]) print("[scripts] " + coords + " Type out string " + type_string) kb.keyboard.write(type_string) elif split_line[0] == "DELAY": print("[scripts] " + coords + " Delay for " + split_line[1] + " seconds") delay = float(split_line[1]) while delay > DELAY_EXIT_CHECK: sleep(DELAY_EXIT_CHECK) delay -= DELAY_EXIT_CHECK if threads[x][y].kill.is_set(): print("[scripts] " + coords + " Recieved exit flag, script exiting...") threads[x][y].kill.clear() if not is_async: running = False threading.Timer(EXIT_UPDATE_DELAY, lp_colors.updateXY, (x, y)).start() return -1 if delay > 0: sleep(delay) elif split_line[0] == "TAP": key = kb.sp(split_line[1]) if len(split_line) <= 2: print("[scripts] " + coords + " Tap key " + split_line[1]) kb.tap(key) elif len(split_line) <= 3: print("[scripts] " + coords + " Tap key " + split_line[1] + " " + split_line[2] + " times") taps = int(split_line[2]) for tap in range(taps): if threads[x][y].kill.is_set(): print("[scripts] " + coords + " Recieved exit flag, script exiting...") threads[x][y].kill.clear() if not is_async: running = False kb.release(split_line[1]) threading.Timer(EXIT_UPDATE_DELAY, lp_colors.updateXY, (x, y)).start() return idx + 1 kb.tap(key) else: print("[scripts] " + coords + " Tap key " + split_line[1] + " " + split_line[2] + " times for " + str(split_line[3]) + " seconds each") taps = int(split_line[2]) delay = float(split_line[3]) for tap in range(taps): temp_delay = delay if threads[x][y].kill.is_set(): print("[scripts] " + coords + " Recieved exit flag, script exiting...") threads[x][y].kill.clear() if not is_async: running = False kb.release(key) threading.Timer(EXIT_UPDATE_DELAY, lp_colors.updateXY, (x, y)).start() return -1 kb.press(key) while temp_delay > DELAY_EXIT_CHECK: sleep(DELAY_EXIT_CHECK) temp_delay -= DELAY_EXIT_CHECK if threads[x][y].kill.is_set(): print("[scripts] " + coords + " Recieved exit flag, script exiting...") threads[x][y].kill.clear() if not is_async: running = False kb.release(key) threading.Timer(EXIT_UPDATE_DELAY, lp_colors.updateXY, (x, y)).start() return -1 if temp_delay > 0: sleep(temp_delay) kb.release(key) elif split_line[0] == "PRESS": print("[scripts] " + coords + " Press key " + split_line[1]) key = kb.sp(split_line[1]) kb.press(key) elif split_line[0] == "RELEASE": print("[scripts] " + coords + " Release key " + split_line[1]) key = kb.sp(split_line[1]) kb.release(key) elif split_line[0] == "WEB": link = split_line[1] if "http" not in link: link = "http://" + link print("[scripts] " + coords + " Open website " + link + " in default browser") webbrowser.open(link) elif split_line[0] == "WEB_NEW": link = split_line[1] if "http" not in link: link = "http://" + link print("[scripts] " + coords + " Open website " + link + " in default browser, try to make a new window") webbrowser.open_new(link) elif split_line[0] == "SOUND": if len(split_line) > 2: print("[scripts] " + coords + " Play sound file " + split_line[1] + " at volume " + str(split_line[2])) sound.play(split_line[1], float(split_line[2])) else: print("[scripts] " + coords + " Play sound file " + split_line[1]) sound.play(split_line[1]) elif split_line[0] == "WAIT_UNPRESSED": print("[scripts] " + coords + " Wait for script key to be unpressed") while lp_events.pressed[x][y]: sleep(DELAY_EXIT_CHECK) if threads[x][y].kill.is_set(): print("[scripts] " + coords + " Recieved exit flag, script exiting...") threads[x][y].kill.clear() if not is_async: running = False threading.Timer(EXIT_UPDATE_DELAY, lp_colors.updateXY, (x, y)).start() return idx + 1 elif split_line[0] == "M_STORE": print("[scripts] " + coords + " Store mouse position") m_pos = ms.getXY() elif split_line[0] == "M_RECALL": if m_pos == tuple(): print( "[scripts] " + coords + " No 'M_STORE' command has been run, cannot do 'M_RECALL'" ) else: print("[scripts] " + coords + " Recall mouse position " + str(m_pos)) ms.setXY(m_pos[0], m_pos[1]) elif split_line[0] == "M_RECALL_LINE": x1, y1 = m_pos delay = None if len(split_line) > 1: delay = float(split_line[1]) / 1000.0 skip = 1 if len(split_line) > 2: skip = int(split_line[2]) if (delay == None) or (delay <= 0): print("[scripts] " + coords + " Recall mouse position " + str(m_pos) + " in a line by " + str(skip) + " pixels per step") else: print("[scripts] " + coords + " Recall mouse position " + str(m_pos) + " in a line by " + str(skip) + " pixels per step and wait " + split_line[1] + " milliseconds between each step") x_C, y_C = ms.getXY() points = ms.line_coords(x_C, y_C, x1, y1) for x_M, y_M in points[::skip]: if threads[x][y].kill.is_set(): print("[scripts] " + coords + " Recieved exit flag, script exiting...") threads[x][y].kill.clear() if not is_async: running = False threading.Timer(EXIT_UPDATE_DELAY, lp_colors.updateXY, (x, y)).start() return -1 ms.setXY(x_M, y_M) if (delay != None) and (delay > 0): temp_delay = delay while temp_delay > DELAY_EXIT_CHECK: sleep(DELAY_EXIT_CHECK) temp_delay -= DELAY_EXIT_CHECK if threads[x][y].kill.is_set(): print("[scripts] " + coords + " Recieved exit flag, script exiting...") threads[x][y].kill.clear() if not is_async: running = False threading.Timer(EXIT_UPDATE_DELAY, lp_colors.updateXY, (x, y)).start() return -1 if temp_delay > 0: sleep(temp_delay) elif split_line[0] == "M_MOVE": if len(split_line) >= 3: print("[scripts] " + coords + " Relative mouse movement (" + split_line[1] + ", " + str(split_line[2]) + ")") ms.moveXY(float(split_line[1]), float(split_line[2])) else: print( "[scripts] " + coords + " Both X and Y are required for mouse movement, skipping..." ) elif split_line[0] == "M_SET": if len(split_line) >= 3: print("[scripts] " + coords + " Set mouse position to (" + split_line[1] + ", " + str(split_line[2]) + ")") ms.setXY(float(split_line[1]), float(split_line[2])) else: print( "[scripts] " + coords + " Both X and Y are required for mouse positioning, skipping..." ) elif split_line[0] == "M_SCROLL": if len(split_line) > 2: print("[scripts] " + coords + " Scroll (" + split_line[1] + ", " + split_line[2] + ")") ms.scroll(float(split_line[2]), float(split_line[1])) else: print("[scripts] " + coords + " Scroll " + split_line[1]) ms.scroll(0, float(split_line[1])) elif split_line[0] == "M_LINE": x1 = int(split_line[1]) y1 = int(split_line[2]) x2 = int(split_line[3]) y2 = int(split_line[4]) delay = None if len(split_line) > 5: delay = float(split_line[5]) / 1000.0 skip = 1 if len(split_line) > 6: skip = int(split_line[6]) if (delay == None) or (delay <= 0): print("[scripts] " + coords + " Mouse line from (" + split_line[1] + ", " + split_line[2] + ") to (" + split_line[3] + ", " + split_line[4] + ") by " + str(skip) + " pixels per step") else: print("[scripts] " + coords + " Mouse line from (" + split_line[1] + ", " + split_line[2] + ") to (" + split_line[3] + ", " + split_line[4] + ") by " + str(skip) + " pixels per step and wait " + split_line[5] + " milliseconds between each step") points = ms.line_coords(x1, y1, x2, y2) for x_M, y_M in points[::skip]: if threads[x][y].kill.is_set(): print("[scripts] " + coords + " Recieved exit flag, script exiting...") threads[x][y].kill.clear() if not is_async: running = False threading.Timer(EXIT_UPDATE_DELAY, lp_colors.updateXY, (x, y)).start() return -1 ms.setXY(x_M, y_M) if (delay != None) and (delay > 0): temp_delay = delay while temp_delay > DELAY_EXIT_CHECK: sleep(DELAY_EXIT_CHECK) temp_delay -= DELAY_EXIT_CHECK if threads[x][y].kill.is_set(): print("[scripts] " + coords + " Recieved exit flag, script exiting...") threads[x][y].kill.clear() if not is_async: running = False threading.Timer(EXIT_UPDATE_DELAY, lp_colors.updateXY, (x, y)).start() return -1 if temp_delay > 0: sleep(temp_delay) elif split_line[0] == "M_LINE_MOVE": x1 = int(split_line[1]) y1 = int(split_line[2]) delay = None if len(split_line) > 3: delay = float(split_line[3]) / 1000.0 skip = 1 if len(split_line) > 4: skip = int(split_line[4]) if (delay == None) or (delay <= 0): print("[scripts] " + coords + " Mouse line move relative (" + split_line[1] + ", " + split_line[2] + ") by " + str(skip) + " pixels per step") else: print("[scripts] " + coords + " Mouse line move relative (" + split_line[1] + ", " + split_line[2] + ") by " + str(skip) + " pixels per step and wait " + split_line[3] + " milliseconds between each step") x_C, y_C = ms.getXY() x_N, y_N = x_C + x1, y_C + y1 points = ms.line_coords(x_C, y_C, x_N, y_N) for x_M, y_M in points[::skip]: if threads[x][y].kill.is_set(): print("[scripts] " + coords + " Recieved exit flag, script exiting...") threads[x][y].kill.clear() if not is_async: running = False threading.Timer(EXIT_UPDATE_DELAY, lp_colors.updateXY, (x, y)).start() return -1 ms.setXY(x_M, y_M) if (delay != None) and (delay > 0): temp_delay = delay while temp_delay > DELAY_EXIT_CHECK: sleep(DELAY_EXIT_CHECK) temp_delay -= DELAY_EXIT_CHECK if threads[x][y].kill.is_set(): print("[scripts] " + coords + " Recieved exit flag, script exiting...") threads[x][y].kill.clear() if not is_async: running = False threading.Timer(EXIT_UPDATE_DELAY, lp_colors.updateXY, (x, y)).start() return -1 if temp_delay > 0: sleep(temp_delay) elif split_line[0] == "M_LINE_SET": x1 = int(split_line[1]) y1 = int(split_line[2]) delay = None if len(split_line) > 3: delay = float(split_line[3]) / 1000.0 skip = 1 if len(split_line) > 4: skip = int(split_line[4]) if (delay == None) or (delay <= 0): print("[scripts] " + coords + " Mouse line set (" + split_line[1] + ", " + split_line[2] + ") by " + str(skip) + " pixels per step") else: print("[scripts] " + coords + " Mouse line set (" + split_line[1] + ", " + split_line[2] + ") by " + str(skip) + " pixels per step and wait " + split_line[3] + " milliseconds between each step") x_C, y_C = ms.getXY() points = ms.line_coords(x_C, y_C, x1, y1) for x_M, y_M in points[::skip]: if threads[x][y].kill.is_set(): print("[scripts] " + coords + " Recieved exit flag, script exiting...") threads[x][y].kill.clear() if not is_async: running = False threading.Timer(EXIT_UPDATE_DELAY, lp_colors.updateXY, (x, y)).start() return -1 ms.setXY(x_M, y_M) if (delay != None) and (delay > 0): temp_delay = delay while temp_delay > DELAY_EXIT_CHECK: sleep(DELAY_EXIT_CHECK) temp_delay -= DELAY_EXIT_CHECK if threads[x][y].kill.is_set(): print("[scripts] " + coords + " Recieved exit flag, script exiting...") threads[x][y].kill.clear() if not is_async: running = False threading.Timer(EXIT_UPDATE_DELAY, lp_colors.updateXY, (x, y)).start() return -1 if temp_delay > 0: sleep(temp_delay) elif split_line[0] == "LABEL": print("[scripts] " + coords + " Label: " + split_line[1]) return idx + 1 elif split_line[0] == "IF_PRESSED_GOTO_LABEL": print("[scripts] " + coords + " If key is pressed goto LABEL " + split_line[1]) if lp_events.pressed[x][y]: return labels[split_line[1]] elif split_line[0] == "IF_UNPRESSED_GOTO_LABEL": print("[scripts] " + coords + " If key is not pressed goto LABEL " + split_line[1]) if not lp_events.pressed[x][y]: return labels[split_line[1]] elif split_line[0] == "GOTO_LABEL": print("[scripts] " + coords + " Goto LABEL " + split_line[1]) return labels[split_line[1]] elif split_line[0] == "REPEAT_LABEL": print("[scripts] " + coords + " Repeat LABEL " + split_line[1] + " " + split_line[2] + " times max") if idx in repeats: if repeats[idx] > 0: print("[scripts] " + coords + " " + str(repeats[idx]) + " repeats left.") repeats[idx] -= 1 return labels[split_line[1]] else: print("[scripts] " + coords + " No repeats left, not repeating.") else: repeats[idx] = int(split_line[2]) repeats_original[idx] = int(split_line[2]) print("[scripts] " + coords + " " + str(repeats[idx]) + " repeats left.") repeats[idx] -= 1 return labels[split_line[1]] elif split_line[0] == "IF_PRESSED_REPEAT_LABEL": print("[scripts] " + coords + " If key is pressed repeat LABEL " + split_line[1] + " " + split_line[2] + " times max") if lp_events.pressed[x][y]: if idx in repeats: if repeats[idx] > 0: print("[scripts] " + coords + " " + str(repeats[idx]) + " repeats left.") repeats[idx] -= 1 return labels[split_line[1]] else: print("[scripts] " + coords + " No repeats left, not repeating.") else: repeats[idx] = int(split_line[2]) print("[scripts] " + coords + " " + str(repeats[idx]) + " repeats left.") repeats[idx] -= 1 return labels[split_line[1]] elif split_line[0] == "IF_UNPRESSED_REPEAT_LABEL": print("[scripts] " + coords + " If key is not pressed repeat LABEL " + split_line[1] + " " + split_line[2] + " times max") if not lp_events.pressed[x][y]: if idx in repeats: if repeats[idx] > 0: print("[scripts] " + coords + " " + str(repeats[idx]) + " repeats left.") repeats[idx] -= 1 return labels[split_line[1]] else: print("[scripts] " + coords + " No repeats left, not repeating.") else: repeats[idx] = int(split_line[2]) print("[scripts] " + coords + " " + str(repeats[idx]) + " repeats left.") repeats[idx] -= 1 return labels[split_line[1]] elif split_line[0] == "@SIMPLE": print("[scripts] " + coords + " Simple keybind: " + split_line[1]) #PRESS key = kb.sp(split_line[1]) kb.press(key) #WAIT_UNPRESSED while lp_events.pressed[x][y]: sleep(DELAY_EXIT_CHECK) if threads[x][y].kill.is_set(): print("[scripts] " + coords + " Recieved exit flag, script exiting...") threads[x][y].kill.clear() if not is_async: running = False threading.Timer(EXIT_UPDATE_DELAY, lp_colors.updateXY, (x, y)).start() return idx + 1 #RELEASE kb.release(key) elif split_line[0] == "OPEN": path_name = " ".join(split_line[1:]) print("[scripts] " + coords + " Open file or folder " + path_name) files.open_file_folder(path_name) elif split_line[0] == "RELEASE_ALL": print("[scripts] " + coords + " Release all keys") kb.release_all() elif split_line[0] == "RESET_REPEATS": print("[scripts] " + coords + " Reset all repeats") for i in repeats: repeats[i] = repeats_original[i] else: print("[scripts] " + coords + " Invalid command: " + split_line[0] + ", skipping...") return idx + 1
def main_logic(idx): nonlocal m_pos if check_kill(x, y, is_async): return idx + 1 line = script_lines[idx] if line == "": return idx + 1 if line[0] == "-": print("[scripts] " + coords + " Comment: " + line[1:]) else: split_line = line.split(" ") if split_line[0] == "STRING": type_string = " ".join(split_line[1:]) print("[scripts] " + coords + " Type out string " + type_string) kb.write(type_string) elif split_line[0] == "DELAY": print("[scripts] " + coords + " Delay for " + split_line[1] + " seconds") delay = float(split_line[1]) if not safe_sleep(delay, x, y, is_async): return -1 elif split_line[0] == "TAP": key = kb.sp(split_line[1]) releasefunc = lambda: kb.release(key) if len(split_line) <= 2: print("[scripts] " + coords + " Tap key " + split_line[1]) kb.tap(key) elif len(split_line) <= 3: print("[scripts] " + coords + " Tap key " + split_line[1] + " " + split_line[2] + " times") taps = int(split_line[2]) for tap in range(taps): if check_kill(x, y, is_async, releasefunc): return idx + 1 kb.tap(key) else: print("[scripts] " + coords + " Tap key " + split_line[1] + " " + split_line[2] + " times for " + str(split_line[3]) + " seconds each") taps = int(split_line[2]) delay = float(split_line[3]) for tap in range(taps): if check_kill(x, y, is_async, releasefunc): return -1 kb.press(key) if not safe_sleep(delay, x, y, is_async, releasefunc): return -1 elif split_line[0] == "PRESS": print("[scripts] " + coords + " Press key " + split_line[1]) key = kb.sp(split_line[1]) kb.press(key) elif split_line[0] == "RELEASE": print("[scripts] " + coords + " Release key " + split_line[1]) key = kb.sp(split_line[1]) kb.release(key) elif split_line[0] == "WEB": link = split_line[1] if "http" not in link: link = "http://" + link print("[scripts] " + coords + " Open website " + link + " in default browser") webbrowser.open(link) elif split_line[0] == "WEB_NEW": link = split_line[1] if "http" not in link: link = "http://" + link print("[scripts] " + coords + " Open website " + link + " in default browser, try to make a new window") webbrowser.open_new(link) elif split_line[0] == "CODE": args = " ".join(split_line[1:]) print("[scripts] " + coords + " Running code: " + args) try: subprocess.run(args) except Exception as e: print("[scripts] " + coords + " Error with running code: " + str(e)) elif split_line[0] == "SOUND": if len(split_line) > 2: print("[scripts] " + coords + " Play sound file " + split_line[1] + " at volume " + str(split_line[2])) sound.play(split_line[1], float(split_line[2])) else: print("[scripts] " + coords + " Play sound file " + split_line[1]) sound.play(split_line[1]) elif split_line[0] == "WAIT_UNPRESSED": print("[scripts] " + coords + " Wait for script key to be unpressed") while lp_events.pressed[x][y]: sleep(DELAY_EXIT_CHECK) if check_kill(x, y, is_async): return idx + 1 elif split_line[0] == "M_STORE": print("[scripts] " + coords + " Store mouse position") m_pos = ms.get_pos() elif split_line[0] == "M_RECALL": if m_pos == tuple(): print( "[scripts] " + coords + " No 'M_STORE' command has been run, cannot do 'M_RECALL'" ) else: print("[scripts] " + coords + " Recall mouse position " + str(m_pos)) ms.set_pos(m_pos[0], m_pos[1]) elif split_line[0] == "M_RECALL_LINE": x1, y1 = m_pos delay = None if len(split_line) > 1: delay = float(split_line[1]) / 1000.0 skip = 1 if len(split_line) > 2: skip = int(split_line[2]) if (delay == None) or (delay <= 0): print("[scripts] " + coords + " Recall mouse position " + str(m_pos) + " in a line by " + str(skip) + " pixels per step") else: print("[scripts] " + coords + " Recall mouse position " + str(m_pos) + " in a line by " + str(skip) + " pixels per step and wait " + split_line[1] + " milliseconds between each step") x_C, y_C = ms.get_pos() points = ms.line_coords(x_C, y_C, x1, y1) for x_M, y_M in points[::skip]: if check_kill(x, y, is_async): return -1 ms.set_pos(x_M, y_M) if (delay != None) and (delay > 0): if not safe_sleep(delay, x, y, is_async): return -1 elif split_line[0] == "M_MOVE": if len(split_line) >= 3: print("[scripts] " + coords + " Relative mouse movement (" + split_line[1] + ", " + str(split_line[2]) + ")") ms.move_to_pos(float(split_line[1]), float(split_line[2])) else: print( "[scripts] " + coords + " Both X and Y are required for mouse movement, skipping..." ) elif split_line[0] == "M_SET": if len(split_line) >= 3: print("[scripts] " + coords + " Set mouse position to (" + split_line[1] + ", " + str(split_line[2]) + ")") ms.set_pos(float(split_line[1]), float(split_line[2])) else: print( "[scripts] " + coords + " Both X and Y are required for mouse positioning, skipping..." ) elif split_line[0] == "M_SCROLL": if len(split_line) > 2: print("[scripts] " + coords + " Scroll (" + split_line[1] + ", " + split_line[2] + ")") ms.scroll(float(split_line[2]), float(split_line[1])) else: print("[scripts] " + coords + " Scroll " + split_line[1]) ms.scroll(0, float(split_line[1])) elif split_line[0] == "M_LINE": x1 = int(split_line[1]) y1 = int(split_line[2]) x2 = int(split_line[3]) y2 = int(split_line[4]) delay = None if len(split_line) > 5: delay = float(split_line[5]) / 1000.0 skip = 1 if len(split_line) > 6: skip = int(split_line[6]) if (delay == None) or (delay <= 0): print("[scripts] " + coords + " Mouse line from (" + split_line[1] + ", " + split_line[2] + ") to (" + split_line[3] + ", " + split_line[4] + ") by " + str(skip) + " pixels per step") else: print("[scripts] " + coords + " Mouse line from (" + split_line[1] + ", " + split_line[2] + ") to (" + split_line[3] + ", " + split_line[4] + ") by " + str(skip) + " pixels per step and wait " + split_line[5] + " milliseconds between each step") points = ms.line_coords(x1, y1, x2, y2) for x_M, y_M in points[::skip]: if check_kill(x, y, is_async): return -1 ms.set_pos(x_M, y_M) if (delay != None) and (delay > 0): if not safe_sleep(delay, x, y, is_async): return -1 elif split_line[0] == "M_LINE_MOVE": x1 = int(split_line[1]) y1 = int(split_line[2]) delay = None if len(split_line) > 3: delay = float(split_line[3]) / 1000.0 skip = 1 if len(split_line) > 4: skip = int(split_line[4]) if (delay == None) or (delay <= 0): print("[scripts] " + coords + " Mouse line move relative (" + split_line[1] + ", " + split_line[2] + ") by " + str(skip) + " pixels per step") else: print("[scripts] " + coords + " Mouse line move relative (" + split_line[1] + ", " + split_line[2] + ") by " + str(skip) + " pixels per step and wait " + split_line[3] + " milliseconds between each step") x_C, y_C = ms.get_pos() x_N, y_N = x_C + x1, y_C + y1 points = ms.line_coords(x_C, y_C, x_N, y_N) for x_M, y_M in points[::skip]: if check_kill(x, y, is_async): return -1 ms.set_pos(x_M, y_M) if (delay != None) and (delay > 0): if not safe_sleep(delay, x, y, is_async): return -1 elif split_line[0] == "M_LINE_SET": x1 = int(split_line[1]) y1 = int(split_line[2]) delay = None if len(split_line) > 3: delay = float(split_line[3]) / 1000.0 skip = 1 if len(split_line) > 4: skip = int(split_line[4]) if (delay == None) or (delay <= 0): print("[scripts] " + coords + " Mouse line set (" + split_line[1] + ", " + split_line[2] + ") by " + str(skip) + " pixels per step") else: print("[scripts] " + coords + " Mouse line set (" + split_line[1] + ", " + split_line[2] + ") by " + str(skip) + " pixels per step and wait " + split_line[3] + " milliseconds between each step") x_C, y_C = ms.get_pos() points = ms.line_coords(x_C, y_C, x1, y1) for x_M, y_M in points[::skip]: if check_kill(x, y, is_async): return -1 ms.set_pos(x_M, y_M) if (delay != None) and (delay > 0): if not safe_sleep(delay, x, y, is_async): return -1 elif split_line[0] == "LABEL": print("[scripts] " + coords + " Label: " + split_line[1]) return idx + 1 elif split_line[0] == "IF_PRESSED_GOTO_LABEL": print("[scripts] " + coords + " If key is pressed goto LABEL " + split_line[1]) if lp_events.pressed[x][y]: return labels[split_line[1]] elif split_line[0] == "IF_UNPRESSED_GOTO_LABEL": print("[scripts] " + coords + " If key is not pressed goto LABEL " + split_line[1]) if not lp_events.pressed[x][y]: return labels[split_line[1]] elif split_line[0] == "GOTO_LABEL": print("[scripts] " + coords + " Goto LABEL " + split_line[1]) return labels[split_line[1]] elif split_line[0] == "REPEAT_LABEL": print("[scripts] " + coords + " Repeat LABEL " + split_line[1] + " " + split_line[2] + " times max") if idx in repeats: if repeats[idx] > 0: print("[scripts] " + coords + " " + str(repeats[idx]) + " repeats left.") repeats[idx] -= 1 return labels[split_line[1]] else: print("[scripts] " + coords + " No repeats left, not repeating.") else: repeats[idx] = int(split_line[2]) repeats_original[idx] = int(split_line[2]) print("[scripts] " + coords + " " + str(repeats[idx]) + " repeats left.") repeats[idx] -= 1 return labels[split_line[1]] elif split_line[0] == "IF_PRESSED_REPEAT_LABEL": print("[scripts] " + coords + " If key is pressed repeat LABEL " + split_line[1] + " " + split_line[2] + " times max") if lp_events.pressed[x][y]: if idx in repeats: if repeats[idx] > 0: print("[scripts] " + coords + " " + str(repeats[idx]) + " repeats left.") repeats[idx] -= 1 return labels[split_line[1]] else: print( "[scripts] " + coords + " No repeats left, not repeating.") else: repeats[idx] = int(split_line[2]) print("[scripts] " + coords + " " + str(repeats[idx]) + " repeats left.") repeats[idx] -= 1 return labels[split_line[1]] elif split_line[0] == "IF_UNPRESSED_REPEAT_LABEL": print("[scripts] " + coords + " If key is not pressed repeat LABEL " + split_line[1] + " " + split_line[2] + " times max") if not lp_events.pressed[x][y]: if idx in repeats: if repeats[idx] > 0: print("[scripts] " + coords + " " + str(repeats[idx]) + " repeats left.") repeats[idx] -= 1 return labels[split_line[1]] else: print( "[scripts] " + coords + " No repeats left, not repeating.") else: repeats[idx] = int(split_line[2]) print("[scripts] " + coords + " " + str(repeats[idx]) + " repeats left.") repeats[idx] -= 1 return labels[split_line[1]] elif split_line[0] == "@SIMPLE": print("[scripts] " + coords + " Simple keybind: " + split_line[1]) #PRESS key = kb.sp(split_line[1]) releasefunc = lambda: kb.release(key) kb.press(key) #WAIT_UNPRESSED while lp_events.pressed[x][y]: sleep(DELAY_EXIT_CHECK) if check_kill(x, y, is_async, releasefunc): return idx + 1 #RELEASE kb.release(key) elif split_line[0] == "@LOAD_LAYOUT": layout_name = " ".join(split_line[1:]) print("[scripts] " + coords + " Load layout " + layout_name) layout_path = os.path.join(files.LAYOUT_PATH, layout_name) if not os.path.isfile(layout_path): print("[scripts] " + coords + " ERROR: Layout file does not exist.") return -1 try: layout = files.load_layout(layout_path, popups=False, save_converted=False) except files.json.decoder.JSONDecodeError: print("[scripts] " + coords + " ERROR: Layout is malformated.") return -1 if files.layout_changed_since_load: files.save_lp_to_layout(files.curr_layout) files.load_layout_to_lp(layout_path, popups=False, save_converted=False, preload=layout) elif split_line[0] == "OPEN": path_name = " ".join(split_line[1:]) print("[scripts] " + coords + " Open file or folder " + path_name) files.open_file_folder(path_name) elif split_line[0] == "RELEASE_ALL": print("[scripts] " + coords + " Release all keys") kb.release_all() elif split_line[0] == "RESET_REPEATS": print("[scripts] " + coords + " Reset all repeats") for i in repeats: repeats[i] = repeats_original[i] else: print("[scripts] " + coords + " Invalid command: " + split_line[0] + ", skipping...") return idx + 1
def Process(self, btn, idx, split_line): key = kb.sp(self.Get_param(btn, 1)) kb.release(key)
def Validate_param_n(self, ret, btn, idx, split_line, val_validation, n): # This method validates parameters. For custom parameters, you're best off defining new validation # methods (like the current variables.Validate_gt_zero()) unless you need access to the symbol # table. # Note that this function, because it runs during validation, accesses the split_line, not the # symbol table. # Where a variable type is defined as having "special" validation, that validation is currently # hard coded here. It would be better to register validation routines, but... later. if not (ret == None or ((type(ret) == bool) and ret)): return ret if n >= len(split_line): return ret if self.auto_validate == None or self.auto_validate == ( ): # no auto validation can be done return ret if n <= len(self.auto_validate): # the normal auto-validation val = self.auto_validate[n - 1] else: # special case for "last" parameters val = self.auto_validate[-1] opt = self.valid_num_params == [] or \ self.valid_num_params[-1] == None or \ (set(range(1,n)) & set(self.valid_num_params)) != [] ret = variables.Check_generic_param(btn, self, idx, split_line, n, val, val_validation) # should we do special validation? if ret == None or ((type(ret) == bool) and ret): if val[AV_VAR_OK] == AVV_REQD: # check for valid variable name if not variables.valid_var_name( split_line[n]): # Is it a valid variable name? return ("Invalid variable name", btn.Line(idx)) elif val[AV_TYPE][AVT_SPECIAL]: if val_validation == AV_P1_VALIDATION: if val[AV_TYPE] == PT_TARGET: # targets (label definitions) have pass 1 validation only # check for duplicate label if split_line[n] in btn.symbols[ SYM_LABELS]: # Does the label already exist (that's bad)? return ("Duplicate LABEL", btn.Line(idx)) # add label to symbol table # Add the new label to the labels in the symbol table btn.symbols[SYM_LABELS][split_line[ n]] = idx # key is label, data is line number elif val[ AV_TYPE] == PT_KEY: # Keys have pass 1 validation only # check for valid key if kb.sp( split_line[n] ) == None: # Does the key exist (if not, that's bad)? return ("Unknown key", btn.Line(idx)) elif val[ AV_TYPE] == PT_BOOL: # booleans have pass 1 validation only # check for valid boolean value if not (split_line[n].upper() in VALID_BOOL): # Is it a valid boolean? return ("Invalid boolean value", btn.Line(idx)) elif val_validation == AV_P2_VALIDATION: if val[AV_TYPE] == PT_LABEL: # references (to a label) have pass 2 validation only # check for existance of label if split_line[n] not in btn.symbols[SYM_LABELS]: return ("Target not found", btn.Line(idx)) return True return (ret, btn.Line(idx))