progress
parent
1e064c3371
commit
4355f15f85
127
automation.py
127
automation.py
|
@ -1,14 +1,22 @@
|
||||||
import uinput
|
import uinput
|
||||||
import time
|
import time
|
||||||
|
import asyncio
|
||||||
import evdev
|
import evdev
|
||||||
|
import queue
|
||||||
from evdev import InputDevice, categorize, ecodes
|
from evdev import InputDevice, categorize, ecodes
|
||||||
from evdev import UInput, ecodes as e
|
from evdev import UInput, ecodes as e
|
||||||
import threading
|
import threading
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
import sys
|
import sys
|
||||||
from PyQt5 import QtCore, QtWidgets, QtGui
|
from PyQt5 import QtCore, QtWidgets, QtGui
|
||||||
|
from PyQt5.QtGui import QPalette, QColor
|
||||||
|
import signal
|
||||||
|
|
||||||
device_path = '/dev/input/event5' # You can find this with `evtest`
|
event_queue = queue.Queue()
|
||||||
|
|
||||||
|
global app, overlay
|
||||||
|
|
||||||
|
device_paths = [('/dev/input/event1', {"KEY_F20", "KEY_F24"}), ('/dev/input/event22', {}), ('/dev/input/event5', {})]
|
||||||
|
|
||||||
key_events = [
|
key_events = [
|
||||||
uinput.KEY_A, uinput.KEY_B, uinput.KEY_C, uinput.KEY_D, uinput.KEY_E,
|
uinput.KEY_A, uinput.KEY_B, uinput.KEY_C, uinput.KEY_D, uinput.KEY_E,
|
||||||
|
@ -16,7 +24,8 @@ key_events = [
|
||||||
uinput.KEY_K, uinput.KEY_L, uinput.KEY_M, uinput.KEY_N, uinput.KEY_O,
|
uinput.KEY_K, uinput.KEY_L, uinput.KEY_M, uinput.KEY_N, uinput.KEY_O,
|
||||||
uinput.KEY_P, uinput.KEY_Q, uinput.KEY_R, uinput.KEY_S, uinput.KEY_T,
|
uinput.KEY_P, uinput.KEY_Q, uinput.KEY_R, uinput.KEY_S, uinput.KEY_T,
|
||||||
uinput.KEY_U, uinput.KEY_V, uinput.KEY_W, uinput.KEY_X, uinput.KEY_Y,
|
uinput.KEY_U, uinput.KEY_V, uinput.KEY_W, uinput.KEY_X, uinput.KEY_Y,
|
||||||
uinput.KEY_Z,
|
uinput.KEY_Z, uinput.KEY_ESC, uinput.KEY_F20, uinput.KEY_F21, uinput.KEY_F22,
|
||||||
|
uinput.KEY_F23, uinput.KEY_F24,
|
||||||
|
|
||||||
uinput.KEY_ENTER,
|
uinput.KEY_ENTER,
|
||||||
uinput.KEY_COMMA,
|
uinput.KEY_COMMA,
|
||||||
|
@ -42,8 +51,6 @@ def left_click():
|
||||||
mouse.syn()
|
mouse.syn()
|
||||||
|
|
||||||
def place_tower():
|
def place_tower():
|
||||||
keyboard.emit_click(uinput.KEY_Z)
|
|
||||||
time.sleep(0.05)
|
|
||||||
left_click()
|
left_click()
|
||||||
time.sleep(0.05)
|
time.sleep(0.05)
|
||||||
mouse.write(e.EV_REL, e.REL_Y, -10)
|
mouse.write(e.EV_REL, e.REL_Y, -10)
|
||||||
|
@ -52,48 +59,91 @@ def place_tower():
|
||||||
left_click()
|
left_click()
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
|
|
||||||
def upgrade_tower():
|
def upgrade_top(amount = 1):
|
||||||
for i in range(2):
|
for i in range(amount):
|
||||||
|
keyboard.emit_click(uinput.KEY_COMMA)
|
||||||
|
time.sleep(0.05)
|
||||||
|
|
||||||
|
def upgrade_middle(amount = 1):
|
||||||
|
for i in range(amount):
|
||||||
keyboard.emit_click(uinput.KEY_DOT)
|
keyboard.emit_click(uinput.KEY_DOT)
|
||||||
time.sleep(0.05)
|
time.sleep(0.05)
|
||||||
for i in range(2):
|
|
||||||
|
def upgrade_bottom(amount = 1):
|
||||||
|
for i in range(amount):
|
||||||
keyboard.emit_click(uinput.KEY_SLASH)
|
keyboard.emit_click(uinput.KEY_SLASH)
|
||||||
time.sleep(0.05)
|
time.sleep(0.05)
|
||||||
|
|
||||||
def listen_for_keypress():
|
def upgrade_tower():
|
||||||
dev = InputDevice(device_path)
|
# for i in range(0):
|
||||||
print(f"Listening on {dev.name} ({device_path})")
|
# keyboard.emit_click(uinput.KEY_DOT)
|
||||||
|
# time.sleep(0.05)
|
||||||
|
for i in range(3):
|
||||||
|
keyboard.emit_click(uinput.KEY_SLASH)
|
||||||
|
time.sleep(0.05)
|
||||||
|
keyboard.emit_click(uinput.KEY_ESC)
|
||||||
|
time.sleep(0.05)
|
||||||
|
keyboard.emit_click(uinput.KEY_C)
|
||||||
|
time.sleep(0.05)
|
||||||
|
|
||||||
for event in dev.read_loop():
|
async def listen_for_keypress(path, keys):
|
||||||
|
dev = InputDevice(path)
|
||||||
|
print(f"Listening on {dev.name} ({path})")
|
||||||
|
|
||||||
|
async for event in dev.async_read_loop():
|
||||||
if event.type == ecodes.EV_KEY:
|
if event.type == ecodes.EV_KEY:
|
||||||
key_event = categorize(event)
|
key_event = categorize(event)
|
||||||
if key_event.keycode == 'KEY_F9' and key_event.keystate == 0:
|
if key_event.keycode in keys and key_event.keystate == 0:
|
||||||
place_tower()
|
event_queue.put((dev.name, key_event.keycode))
|
||||||
upgrade_tower()
|
|
||||||
|
|
||||||
class Overlay(QtWidgets.QWidget):
|
class Overlay(QtWidgets.QWidget):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
# self.setAttribute(QtCore.Qt.WA_TranslucentBackground, True)
|
||||||
|
self.setAttribute(QtCore.Qt.WA_TransparentForMouseEvents, True)
|
||||||
|
# self.setAttribute(QtCore.Qt.WA_NoSystemBackground, True)
|
||||||
self.setWindowFlags(
|
self.setWindowFlags(
|
||||||
QtCore.Qt.WindowStaysOnTopHint |
|
QtCore.Qt.WindowStaysOnTopHint |
|
||||||
QtCore.Qt.FramelessWindowHint |
|
QtCore.Qt.FramelessWindowHint |
|
||||||
QtCore.Qt.Tool # Makes window not appear in taskbar
|
QtCore.Qt.Tool
|
||||||
)
|
)
|
||||||
self.setAttribute(QtCore.Qt.WA_TranslucentBackground)
|
self.setStyleSheet("background-color: #788178;")
|
||||||
self.setAttribute(QtCore.Qt.WA_TransparentForMouseEvents) # Click-through
|
|
||||||
|
|
||||||
self.label = QtWidgets.QLabel("Mode: 1", self)
|
self.label = QtWidgets.QLabel("Mode: 1", self)
|
||||||
self.label.setStyleSheet("color: white; font-size: 24px; background: rgba(0,0,0,0.5); padding: 10px;")
|
self.label.setStyleSheet("color: white; font-size: 12px; padding: 4px;")
|
||||||
self.label.move(50, 50)
|
self.label.move(50, 50)
|
||||||
|
|
||||||
self.resize(200, 100)
|
layout = QtWidgets.QVBoxLayout(self)
|
||||||
|
layout.setContentsMargins(2, 2, 2, 2) # Very small margins
|
||||||
|
layout.addWidget(self.label)
|
||||||
|
self.setLayout(layout)
|
||||||
|
self.adjustSize()
|
||||||
|
|
||||||
def update_mode(self, mode_num):
|
# self.resize(200, 100)
|
||||||
|
self.move(0, 0)
|
||||||
|
|
||||||
|
# def paintEvent(self, event):
|
||||||
|
# painter = QtGui.QPainter(self)
|
||||||
|
# painter.setOpacity(0.1)
|
||||||
|
# painter.setBrush(QtCore.Qt.white)
|
||||||
|
# painter.setPen(QtGui.QPen(QtCore.Qt.white))
|
||||||
|
# painter.drawRect(self.rect())
|
||||||
|
# super().paintEvent(event)
|
||||||
|
|
||||||
|
def update_mode(self, mode_num: int):
|
||||||
self.label.setText(f"Mode: {mode_num}")
|
self.label.setText(f"Mode: {mode_num}")
|
||||||
|
|
||||||
if __name__ == "__main__":
|
async def main():
|
||||||
try:
|
tasks = [asyncio.create_task(listen_for_keypress(tpl[0], tpl[1])) for tpl in device_paths]
|
||||||
app = QtWidgets.QApplication(sys.argv)
|
|
||||||
|
await asyncio.gather(*tasks)
|
||||||
|
|
||||||
|
def start_async():
|
||||||
|
asyncio.run(main())
|
||||||
|
|
||||||
|
def qt5():
|
||||||
|
global app, overlay
|
||||||
|
app = QtWidgets.QApplication([])
|
||||||
overlay = Overlay()
|
overlay = Overlay()
|
||||||
overlay.show()
|
overlay.show()
|
||||||
|
|
||||||
|
@ -102,10 +152,35 @@ if __name__ == "__main__":
|
||||||
while True:
|
while True:
|
||||||
time.sleep(2)
|
time.sleep(2)
|
||||||
mode = (mode % 3) + 1
|
mode = (mode % 3) + 1
|
||||||
QtCore.QMetaObject.invokeMethod(overlay, "update_mode", QtCore.Qt.QueuedConnection, QtCore.Q_ARG(int, mode))
|
# QtCore.QMetaObject.invokeMethod(overlay, "update_mode", QtCore.Qt.QueuedConnection, QtCore.Q_ARG(int, mode))
|
||||||
|
|
||||||
Thread(target=update_loop, daemon=True).start()
|
Thread(target=update_loop, daemon=True).start()
|
||||||
# listen_for_keypress()
|
app.exec()
|
||||||
|
|
||||||
|
|
||||||
|
def command_processor():
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
device_name, key_event = event_queue.get(timeout=1)
|
||||||
|
print(f"Processing event from {device_name}: {key_event}")
|
||||||
|
|
||||||
|
if key_event == "KEY_F24":
|
||||||
|
global app, overlay
|
||||||
|
app.quit()
|
||||||
|
sys.exit(0)
|
||||||
|
except queue.Empty:
|
||||||
|
continue
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error processing queue item: {e}")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
global app, overlay
|
||||||
|
try:
|
||||||
|
Thread(target=command_processor, daemon=True).start()
|
||||||
|
Thread(target=start_async, daemon=True).start()
|
||||||
|
qt5()
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
print("Goodbye!")
|
print("Goodbye!")
|
||||||
sys.exit(app.exec_())
|
app.quit()
|
||||||
|
sys.exit(0)
|
||||||
|
# sys.exit(app.exec_())
|
||||||
|
|
32
default.nix
32
default.nix
|
@ -1,13 +1,31 @@
|
||||||
let
|
let
|
||||||
pkgs = import <nixpkgs> {};
|
pkgs = import <nixpkgs> {};
|
||||||
in pkgs.mkShell {
|
in pkgs.mkShell {
|
||||||
packages = [
|
nativeBuildInputs = with pkgs; [ qt5.qttools.dev python3Packages.autopep8 python3Packages.flake8 ];
|
||||||
pkgs.git
|
propagatedBuildInputs = with pkgs; [
|
||||||
(pkgs.python3.withPackages (python-pkgs: [
|
(python3.withPackages (ps: with ps; [
|
||||||
python-pkgs.requests
|
pyqt5
|
||||||
python-pkgs.python-uinput
|
evdev
|
||||||
python-pkgs.evdev
|
python-uinput
|
||||||
python-pkgs.pyqt5
|
|
||||||
]))
|
]))
|
||||||
];
|
];
|
||||||
|
|
||||||
|
packages = with pkgs; [
|
||||||
|
git
|
||||||
|
(python3.withPackages (python-pkgs: with python-pkgs; [
|
||||||
|
requests
|
||||||
|
python-uinput
|
||||||
|
evdev
|
||||||
|
pyqt5
|
||||||
|
]))
|
||||||
|
python3Packages.pyqt5
|
||||||
|
python3Packages.pip
|
||||||
|
libsForQt5.qt5.qtbase
|
||||||
|
libsForQt5.qt5.qtx11extras
|
||||||
|
qt5.qtbase
|
||||||
|
qt5.wrapQtAppsHook
|
||||||
|
qt5.qtx11extras
|
||||||
|
];
|
||||||
|
|
||||||
|
QT_QPA_PLATFORM_PLUGIN_PATH="${pkgs.qt5.qtbase.bin}/lib/qt-${pkgs.qt5.qtbase.version}/plugins";
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
from PyQt5 import QtWidgets, QtCore, QtGui
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
class TransparentScene(QtWidgets.QGraphicsScene):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
text = self.addText("Mode: 1")
|
||||||
|
text.setDefaultTextColor(QtGui.QColor("white"))
|
||||||
|
# Add a semi-transparent background rect
|
||||||
|
rect = self.addRect(text.boundingRect().adjusted(-10, -10, 10, 10),
|
||||||
|
QtGui.QPen(QtCore.Qt.NoPen),
|
||||||
|
QtGui.QBrush(QtGui.QColor(0, 0, 0, 128)))
|
||||||
|
rect.setZValue(-1) # Put behind text
|
||||||
|
|
||||||
|
|
||||||
|
class TransparentView(QtWidgets.QGraphicsView):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
scene = TransparentScene()
|
||||||
|
self.setScene(scene)
|
||||||
|
self.setWindowFlags(QtCore.Qt.FramelessWindowHint | QtCore.Qt.WindowStaysOnTopHint)
|
||||||
|
self.setAttribute(QtCore.Qt.WA_TranslucentBackground)
|
||||||
|
self.setStyleSheet("background: transparent;")
|
||||||
|
self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
|
||||||
|
self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
|
||||||
|
self.setRenderHint(QtGui.QPainter.Antialiasing)
|
||||||
|
self.setFrameShape(QtWidgets.QFrame.NoFrame)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
app = QtWidgets.QApplication(sys.argv)
|
||||||
|
view = TransparentView()
|
||||||
|
view.resize(200, 100)
|
||||||
|
view.show()
|
||||||
|
sys.exit(app.exec_())
|
Loading…
Reference in New Issue