mirror of
https://github.com/liyunze-coding/TwitchPlaysX.git
synced 2026-11-02 20:03:33 +00:00
fixed coroutine, added control x num feature
This commit is contained in:
parent
3697c68897
commit
d91de0acdd
2 changed files with 45 additions and 30 deletions
61
functions.py
61
functions.py
|
|
@ -2,16 +2,19 @@ import time
|
||||||
import subprocess
|
import subprocess
|
||||||
import platform
|
import platform
|
||||||
import socket
|
import socket
|
||||||
|
import re
|
||||||
|
import asyncio
|
||||||
import win32api # Windows only
|
import win32api # Windows only
|
||||||
import win32con # Windows only
|
import win32con # Windows only
|
||||||
|
|
||||||
|
|
||||||
class TwitchPlaysX:
|
class TwitchPlaysX:
|
||||||
def __init__(self, key_delay, keymap, channel_name) -> None:
|
def __init__(self, key_delay, keymap, channel_name, x_limit) -> None:
|
||||||
self.os = self.get_os()
|
self.os = self.get_os()
|
||||||
self.key_delay = key_delay
|
self.key_delay = key_delay
|
||||||
self.keymap = keymap
|
self.keymap = keymap
|
||||||
self.channel_name = channel_name
|
self.channel_name = channel_name.lower()
|
||||||
|
self.x_limit = x_limit
|
||||||
|
|
||||||
# not tested
|
# not tested
|
||||||
def sendKeyLinux(self, button):
|
def sendKeyLinux(self, button):
|
||||||
|
|
@ -39,7 +42,20 @@ class TwitchPlaysX:
|
||||||
self.sendKeyLinux(button)
|
self.sendKeyLinux(button)
|
||||||
|
|
||||||
def all_valid_chars(self, char_array):
|
def all_valid_chars(self, char_array):
|
||||||
return all(char in self.keymap for char in char_array)
|
pattern = re.compile(r"^[a-z]+\d*$")
|
||||||
|
return all(pattern.match(char) for char in char_array)
|
||||||
|
|
||||||
|
def compile_chars(self, char_array):
|
||||||
|
compiled_chars = []
|
||||||
|
for char in char_array:
|
||||||
|
match = re.match(r"([a-z]+)(\d*)", char)
|
||||||
|
if match:
|
||||||
|
control, count = match.groups()
|
||||||
|
count = int(count or "1")
|
||||||
|
if count > self.x_limit:
|
||||||
|
count = self.x_limit
|
||||||
|
compiled_chars.extend([control] * count)
|
||||||
|
return compiled_chars
|
||||||
|
|
||||||
def process_message(self, author, message):
|
def process_message(self, author, message):
|
||||||
characters = message.lower().split(" ")
|
characters = message.lower().split(" ")
|
||||||
|
|
@ -47,33 +63,30 @@ class TwitchPlaysX:
|
||||||
os_type = self.get_os()
|
os_type = self.get_os()
|
||||||
|
|
||||||
if self.all_valid_chars(characters):
|
if self.all_valid_chars(characters):
|
||||||
for char in characters:
|
compiled_characters = self.compile_chars(characters)
|
||||||
|
for char in compiled_characters:
|
||||||
print(f"{author}: {char}")
|
print(f"{author}: {char}")
|
||||||
self.sendKey(char, os_type)
|
self.sendKey(char, os_type)
|
||||||
|
|
||||||
def twitch_chat_listener(self, channel):
|
async def listen(self):
|
||||||
server = "irc.chat.twitch.tv"
|
reader, writer = await asyncio.open_connection("irc.chat.twitch.tv", 6667)
|
||||||
port = 6667
|
|
||||||
nick = "justinfan123" # Twitch allows anonymous users with 'justinfan' prefix
|
|
||||||
channel = f"#{channel}"
|
|
||||||
|
|
||||||
sock = socket.socket()
|
writer.write(f"NICK justinfan1234\r\n".encode("utf-8"))
|
||||||
sock.connect((server, port))
|
writer.write(f"JOIN #{self.channel_name}\r\n".encode("utf-8"))
|
||||||
sock.send(f"NICK {nick}\r\n".encode("utf-8"))
|
|
||||||
sock.send(f"JOIN {channel}\r\n".encode("utf-8"))
|
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
resp = sock.recv(2048).decode("utf-8")
|
data = await reader.read(2048)
|
||||||
|
message = data.decode().strip()
|
||||||
|
|
||||||
if resp.startswith("PING"):
|
if message.startswith("PING"):
|
||||||
sock.send("PONG\n".encode("utf-8"))
|
writer.write(b"PONG\r\n")
|
||||||
|
await writer.drain()
|
||||||
# Check if message is not empty
|
|
||||||
elif len(resp) > 0:
|
|
||||||
# Extract author from response
|
|
||||||
author = resp.split("!", 1)[0].split(":", 1)[-1]
|
|
||||||
|
|
||||||
# Extract message from response
|
|
||||||
msg = resp.split(channel, 1)[-1].split(":", 1)[-1].strip()
|
|
||||||
|
|
||||||
|
elif message:
|
||||||
|
author = message.split("!", 1)[0].split(":", 1)[-1]
|
||||||
|
msg = (
|
||||||
|
message.split(f"#{self.channel_name.lower()}", 1)[-1]
|
||||||
|
.split(":", 1)[-1]
|
||||||
|
.strip()
|
||||||
|
)
|
||||||
self.process_message(author, msg)
|
self.process_message(author, msg)
|
||||||
|
|
|
||||||
14
main.py
14
main.py
|
|
@ -1,10 +1,12 @@
|
||||||
import win32con # Windows only
|
import win32con # Windows only
|
||||||
from functions import TwitchPlaysX
|
from functions import TwitchPlaysX
|
||||||
import platform
|
import platform
|
||||||
|
import asyncio
|
||||||
|
|
||||||
# SETTINGS
|
# SETTINGS
|
||||||
CHANNEL_NAME = "CHANNEL_NAME"
|
CHANNEL_NAME = "RythonDev"
|
||||||
KEYDELAY = 0.3
|
KEYDELAY = 0.3
|
||||||
|
X_LIMIT = 10 # "up20" will be converted to "up10" if X_LIMIT is 10
|
||||||
|
|
||||||
# Keymap for Windows
|
# Keymap for Windows
|
||||||
windowsKeyMap = {
|
windowsKeyMap = {
|
||||||
|
|
@ -20,7 +22,7 @@ windowsKeyMap = {
|
||||||
"select": ord("E"),
|
"select": ord("E"),
|
||||||
}
|
}
|
||||||
|
|
||||||
# Keymap for Linux
|
# Keymap for Linux, if you're using Windows you can ignore this
|
||||||
linuxKeyMap = {
|
linuxKeyMap = {
|
||||||
"up": "Up",
|
"up": "Up",
|
||||||
"left": "Left",
|
"left": "Left",
|
||||||
|
|
@ -36,7 +38,7 @@ linuxKeyMap = {
|
||||||
###
|
###
|
||||||
|
|
||||||
|
|
||||||
def main():
|
async def main():
|
||||||
if CHANNEL_NAME == "CHANNEL_NAME":
|
if CHANNEL_NAME == "CHANNEL_NAME":
|
||||||
print("Please set the CHANNEL_NAME variable in the main.py file")
|
print("Please set the CHANNEL_NAME variable in the main.py file")
|
||||||
else:
|
else:
|
||||||
|
|
@ -44,11 +46,11 @@ def main():
|
||||||
|
|
||||||
keymap = windowsKeyMap if os_type == "Windows" else linuxKeyMap
|
keymap = windowsKeyMap if os_type == "Windows" else linuxKeyMap
|
||||||
|
|
||||||
twitchPlaysX = TwitchPlaysX(KEYDELAY, keymap, CHANNEL_NAME)
|
twitchPlaysX = TwitchPlaysX(KEYDELAY, keymap, CHANNEL_NAME, X_LIMIT)
|
||||||
|
|
||||||
print(f"Starting TwitchPlaysX for channel: {CHANNEL_NAME}")
|
print(f"Starting TwitchPlaysX for channel: {CHANNEL_NAME}")
|
||||||
twitchPlaysX.twitch_chat_listener(CHANNEL_NAME)
|
await twitchPlaysX.listen()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
asyncio.run(main())
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue