diff --git a/functions.py b/functions.py index 8353cd5..d6bd4c2 100644 --- a/functions.py +++ b/functions.py @@ -19,19 +19,29 @@ class TwitchPlaysX: self.channel_name = channel_name.lower() self.x_limit = x_limit self.kill_commands = kill_commands + self.controls_queue = [] # not tested - def sendKeyLinux(self, button): + def sendKeyLinux(self, controls): + button = controls["control"] + duration = controls["duration"] / 1000 # convert milliseconds to seconds + subprocess.run(["xdotool", "keydown", button]) - time.sleep(self.key_duration) + time.sleep(duration) subprocess.run(["xdotool", "keyup", button]) time.sleep(self.key_delay) - def sendKeyWindows(self, button): - win32api.keybd_event(self.keymap[button], 0, 0, 0) - time.sleep(self.key_duration) - win32api.keybd_event(self.keymap[button], 0, win32con.KEYEVENTF_KEYUP, 0) - time.sleep(self.key_delay) + def sendKeyWindows(self, controls): + button = controls["control"] + duration = controls["duration"] / 500 # convert milliseconds to half-seconds + + if duration < 1: + duration = 1 + + for i in range(int(duration)): + win32api.keybd_event(self.keymap[button], 0, 0, 0) + time.sleep(0.3) + win32api.keybd_event(self.keymap[button], 0, win32con.KEYEVENTF_KEYUP, 0) def get_os(self): os_name = platform.system() @@ -55,15 +65,21 @@ class TwitchPlaysX: def compile_chars(self, char_array): compiled_chars = [] for char in char_array: - match = re.match(r"([a-z]+)(\d*)", char) + match = re.match(r"([a-z]+)(\d+)(ms|s)", char) if match: - control, count = match.groups() + control, duration, unit = match.groups() if control not in self.keymap: return [] - count = int(count or "1") - if count > self.x_limit: - count = self.x_limit - compiled_chars.extend([control] * count) + duration = int(duration or "1") + if unit == "s": + duration *= 1000 # convert seconds to milliseconds + + if duration > self.x_limit * 1000: + duration = self.x_limit * 1000 + + compiled_chars.append({"control": control, "duration": duration}) + elif char in self.keymap: + compiled_chars.append({"control": char, "duration": self.key_duration}) return compiled_chars @@ -77,11 +93,25 @@ class TwitchPlaysX: os_type = self.get_os() compiled_characters = self.compile_chars(characters) - for char in compiled_characters: - print(f"{author}: {char}") - self.sendKey(char, os_type) + + if compiled_characters: + self.controls_queue.extend(compiled_characters) + + async def execute_controls(self): + while True: + if self.controls_queue: + print(self.controls_queue) + control = self.controls_queue.pop(0) + if self.get_os() == "Windows": + self.sendKeyWindows(control) + else: + self.sendKeyLinux(control) + else: + await asyncio.sleep(0.1) # Sleep for a short time if the queue is empty async def play(self): + asyncio.create_task(self.execute_controls()) + reader, writer = await asyncio.open_connection("irc.chat.twitch.tv", 6667) writer.write(f"NICK justinfan1234\r\n".encode("utf-8")) diff --git a/main.py b/main.py index 9a3f499..fd16f8d 100644 --- a/main.py +++ b/main.py @@ -5,9 +5,9 @@ import asyncio # SETTINGS CHANNEL_NAME = "CHANNEL_NAME" # Twitch channel name -KEY_DURATION = 0.5 +KEY_DURATION = 500 # (milliseconds) duration of each key press KEY_DELAY = 0.1 -X_LIMIT = 10 # "up20" will be converted to "up10" if X_LIMIT is 10 +X_LIMIT = 10 # (seconds) time limit for each command KILL_SWITCH_COMMANDS = ["!killpokemon"] # must be all lowercase # Keymap for Windows @@ -20,8 +20,8 @@ windowsKeyMap = { "b": ord("Z"), "l": ord("A"), "r": ord("S"), - "start": ord("S"), - "select": ord("E"), + "start": ord("E"), + "select": ord("G"), } # Keymap for Linux, if you're using Windows you can ignore this