mirror of
https://github.com/liyunze-coding/TwitchPlaysX.git
synced 2026-11-02 20:03:33 +00:00
first commit
This commit is contained in:
commit
cc9f833c4e
5 changed files with 183 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
__pycache__
|
||||
48
README.md
Normal file
48
README.md
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
# Twitch Plays X (by RythonDev)
|
||||
|
||||
> (Credits to [TwitchPlaysPokemon] and [TwitchPlayX by hzoo](https://github.com/hzoo/TwitchPlaysX))
|
||||
|
||||
Allows your Twitch chat to play games such as Pokemon!
|
||||
|
||||

|
||||

|
||||

|
||||
|
||||
## How it works
|
||||
|
||||
1. Connects to your Twitch chat
|
||||
2. Reads messages
|
||||
3. Check if messages contains controls only:
|
||||
- `up up down down left right` - pass
|
||||
- `what's up` - fail
|
||||
4. Executes keyboard controls
|
||||
|
||||
## Installation
|
||||
|
||||
1. Install [Python](https://python.org) onto your machine
|
||||
2. Download zip file or Clone the repo via:
|
||||
```
|
||||
git clone https://github.com/liyunze-coding/TwitchPlaysX.git
|
||||
```
|
||||
|
||||
3. Modify `CHANNEL_NAME` in `main.py`:
|
||||
```
|
||||
CHANNEL_NAME = "rythondev"
|
||||
```
|
||||
|
||||
4. Install the requirements:
|
||||
|
||||
Windows:
|
||||
```
|
||||
pip install pywin32
|
||||
```
|
||||
|
||||
Linux:
|
||||
```
|
||||
sudo apt-get install xdotool
|
||||
```
|
||||
|
||||
5. Run the script:
|
||||
```
|
||||
py main.py
|
||||
```
|
||||
79
functions.py
Normal file
79
functions.py
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
import time
|
||||
import subprocess
|
||||
import platform
|
||||
import socket
|
||||
import win32api # Windows only
|
||||
import win32con # Windows only
|
||||
|
||||
|
||||
class TwitchPlaysX:
|
||||
def __init__(self, key_delay, keymap, channel_name) -> None:
|
||||
self.os = self.get_os()
|
||||
self.key_delay = key_delay
|
||||
self.keymap = keymap
|
||||
self.channel_name = channel_name
|
||||
|
||||
# not tested
|
||||
def sendKeyLinux(self, button):
|
||||
subprocess.run(["xdotool", "key", button])
|
||||
time.sleep(self.key_delay)
|
||||
|
||||
def sendKeyWindows(self, button):
|
||||
win32api.keybd_event(self.keymap[button], 0, 0, 0)
|
||||
time.sleep(self.key_delay)
|
||||
win32api.keybd_event(self.keymap[button], 0, win32con.KEYEVENTF_KEYUP, 0)
|
||||
|
||||
def get_os(self):
|
||||
os_name = platform.system()
|
||||
if os_name == "Windows":
|
||||
return "Windows"
|
||||
elif os_name == "Linux":
|
||||
return "Linux"
|
||||
else:
|
||||
return "Unknown"
|
||||
|
||||
def sendKey(self, button, os_type):
|
||||
if os_type.lower() == "windows":
|
||||
self.sendKeyWindows(button)
|
||||
else:
|
||||
self.sendKeyLinux(button)
|
||||
|
||||
def all_valid_chars(self, char_array):
|
||||
return all(char in self.keymap for char in char_array)
|
||||
|
||||
def process_message(self, author, message):
|
||||
characters = message.lower().split(" ")
|
||||
|
||||
os_type = self.get_os()
|
||||
|
||||
if self.all_valid_chars(characters):
|
||||
for char in characters:
|
||||
print(f"{author}: {char}")
|
||||
self.sendKey(char, os_type)
|
||||
|
||||
def twitch_chat_listener(self, channel):
|
||||
server = "irc.chat.twitch.tv"
|
||||
port = 6667
|
||||
nick = "justinfan123" # Twitch allows anonymous users with 'justinfan' prefix
|
||||
channel = f"#{channel}"
|
||||
|
||||
sock = socket.socket()
|
||||
sock.connect((server, port))
|
||||
sock.send(f"NICK {nick}\r\n".encode("utf-8"))
|
||||
sock.send(f"JOIN {channel}\r\n".encode("utf-8"))
|
||||
|
||||
while True:
|
||||
resp = sock.recv(2048).decode("utf-8")
|
||||
|
||||
if resp.startswith("PING"):
|
||||
sock.send("PONG\n".encode("utf-8"))
|
||||
|
||||
# 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()
|
||||
|
||||
self.process_message(author, msg)
|
||||
54
main.py
Normal file
54
main.py
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
import win32con # Windows only
|
||||
from functions import TwitchPlaysX
|
||||
import platform
|
||||
|
||||
# SETTINGS
|
||||
CHANNEL_NAME = "rythondev"
|
||||
KEYDELAY = 0.3
|
||||
|
||||
# Keymap for Windows
|
||||
windowsKeyMap = {
|
||||
"up": win32con.VK_UP,
|
||||
"left": win32con.VK_LEFT,
|
||||
"down": win32con.VK_DOWN,
|
||||
"right": win32con.VK_RIGHT,
|
||||
"a": ord("X"),
|
||||
"b": ord("Z"),
|
||||
"l": ord("A"),
|
||||
"r": ord("S"),
|
||||
"start": ord("S"),
|
||||
"select": ord("E"),
|
||||
}
|
||||
|
||||
# Keymap for Linux
|
||||
linuxKeyMap = {
|
||||
"up": "Up",
|
||||
"left": "Left",
|
||||
"down": "Down",
|
||||
"right": "Right",
|
||||
"a": "x",
|
||||
"b": "z",
|
||||
"l": "a",
|
||||
"r": "s",
|
||||
"start": "s",
|
||||
"select": "e",
|
||||
}
|
||||
###
|
||||
|
||||
|
||||
def main():
|
||||
if CHANNEL_NAME == "CHANNEL_NAME":
|
||||
print("Please set the CHANNEL_NAME variable in the main.py file")
|
||||
else:
|
||||
os_type = platform.system()
|
||||
|
||||
keymap = windowsKeyMap if os_type == "Windows" else linuxKeyMap
|
||||
|
||||
twitchPlaysX = TwitchPlaysX(KEYDELAY, keymap, CHANNEL_NAME)
|
||||
|
||||
print(f"Starting TwitchPlaysX for channel: {CHANNEL_NAME}")
|
||||
twitchPlaysX.twitch_chat_listener(CHANNEL_NAME)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
1
requirements.txt
Normal file
1
requirements.txt
Normal file
|
|
@ -0,0 +1 @@
|
|||
pywin32==306
|
||||
Loading…
Reference in a new issue