|
@@ -7,7 +7,7 @@ from os.path import exists, join, isdir
|
|
|
|
|
|
from time import sleep
|
|
|
|
|
|
-from typing import Dict
|
|
|
+from typing import Dict, Tuple
|
|
|
|
|
|
try:
|
|
|
from click import echo, style
|
|
@@ -16,7 +16,7 @@ except ImportError:
|
|
|
exit()
|
|
|
|
|
|
from pyautogui import mouseDown as mouse_down, mouseUp as mouse_up
|
|
|
-from keyboard import press as key_down, release as key_up, KeyboardEvent, add_hotkey, write as key_write
|
|
|
+from keyboard import press as key_down, release as key_up, KeyboardEvent, add_hotkey, hook as key_hook, write as key_write
|
|
|
# Not entirely sure why this doesn't work
|
|
|
#from mouse import press as mouse_down, release as mouse_up, click as mouse_press, move as mouse_move
|
|
|
|
|
@@ -40,35 +40,6 @@ def print_info(msg):
|
|
|
def keyboard_output(msg: str, delay: int=50, hold: int=20):
|
|
|
key_write(msg, delay=hold)
|
|
|
sleep(delay/1000)
|
|
|
- # for k in msg:
|
|
|
- # if k.isupper():
|
|
|
- # k = k.lower()
|
|
|
- # key_down('shift')
|
|
|
- # key_down(k)
|
|
|
- # sleep(hold / 1000)
|
|
|
- # key_up(k)
|
|
|
- # key_up('shift')
|
|
|
- # sleep(hold / 1000)
|
|
|
- # elif k in ['!', '@', '#', '$', '%', '^', '&', '*', '(', ')']:
|
|
|
- # m = {'!': '1', '@': '2', '#': '3', '$': '4', '%': '5', '^': '6', '&': '7', '*': '8', '(': '9', ')': '0'}
|
|
|
- # key_down('shift')
|
|
|
- # key_down(m[k])
|
|
|
- # sleep(hold / 1000)
|
|
|
- # key_up(m[k])
|
|
|
- # key_up('shift')
|
|
|
- # sleep(hold / 1000)
|
|
|
- # elif k in ['\r', '\n']:
|
|
|
- # m = {'\r': 'enter', '\n': 'enter'}
|
|
|
- # key_down(m[k])
|
|
|
- # sleep(hold / 1000)
|
|
|
- # key_up(m[k])
|
|
|
- # sleep(hold / 1000)
|
|
|
- # else:
|
|
|
- # key_down(k)
|
|
|
- # sleep(hold / 1000)
|
|
|
- # key_up(k)
|
|
|
- # sleep(hold / 1000)
|
|
|
- # sleep(delay / 1000)
|
|
|
|
|
|
def mouse_output(button: str, delay: int=50, hold: int=20):
|
|
|
mouse_down(button=button)
|
|
@@ -90,7 +61,184 @@ else:
|
|
|
print_info(f"Platform: {OS_NAME}")
|
|
|
exit()
|
|
|
|
|
|
-class Action():
|
|
|
+class ActionKind(int):
|
|
|
+ """
|
|
|
+ Actions can be defined to do different things
|
|
|
+
|
|
|
+ Because of this complexity, Actions are separated into
|
|
|
+
|
|
|
+ Mouse Actions:
|
|
|
+ - Click (Press mouse button down, then release mouse button up)
|
|
|
+ - Click Down (Press mouse button down, never releasing up)
|
|
|
+
|
|
|
+ Keyboard Actions:
|
|
|
+ - Key (Press key down, then release key up)
|
|
|
+ - Key Down (Press key down, never releasing up)
|
|
|
+
|
|
|
+ Mirror Actions will typically be one of the above (mouse or keyboard actions, typically Click or Key)
|
|
|
+
|
|
|
+ They Mirror a key's state, if it's down: pressing or clicking down, if it's up: releasing up
|
|
|
+ """
|
|
|
+ NONE = 0
|
|
|
+ """ Invalid Action state """
|
|
|
+ CLICK = 1
|
|
|
+ """ Mouse Action, Click (Press mouse button down, then release mouse button up) """
|
|
|
+ CLICK_DOWN = 2
|
|
|
+ """ Mouse Action, Click Down (Press mouse button down, never releasing up) """
|
|
|
+ KEY = 3
|
|
|
+ """ Keyboard Action, Key (Press key down, then release key up) """
|
|
|
+ KEY_DOWN = 4
|
|
|
+ """ Keyboard Action, Key Down (Press key down, never releasing up) """
|
|
|
+ MIRROR = 5
|
|
|
+ """ Mirror Actions will typically be one of the above (mouse or keyboard actions, typically Click or Key)
|
|
|
+
|
|
|
+ They Mirror a key's state, if it's down: pressing or clicking down, if it's up: releasing up
|
|
|
+ """
|
|
|
+ def __init__(self, kind: str):
|
|
|
+ # Unlike most __init__ methods, this converts a string into a ActionKind (returning the ActionKind)
|
|
|
+ k = kind.lower().strip()
|
|
|
+ if k == "click":
|
|
|
+ return ActionKind.CLICK
|
|
|
+ elif k == "click down":
|
|
|
+ return ActionKind.CLICK_DOWN
|
|
|
+ elif k == "key":
|
|
|
+ return ActionKind.KEY
|
|
|
+ elif k == "key down":
|
|
|
+ return ActionKind.KEY_DOWN
|
|
|
+ elif k == "mirror":
|
|
|
+ return ActionKind.MIRROR
|
|
|
+ else:
|
|
|
+ return ActionKind.NONE
|
|
|
+
|
|
|
+ def __str__(self) -> str:
|
|
|
+ # Converts the ActionKind into a string, mostly for debugging
|
|
|
+ if self == ActionKind.CLICK:
|
|
|
+ return "click"
|
|
|
+ elif self == ActionKind.CLICK_DOWN:
|
|
|
+ return "click down"
|
|
|
+ elif self == ActionKind.KEY:
|
|
|
+ return "key"
|
|
|
+ elif self == ActionKind.KEY_DOWN:
|
|
|
+ return "key down"
|
|
|
+ elif self == ActionKind.MIRROR:
|
|
|
+ return "mirror"
|
|
|
+ else:
|
|
|
+ return f"<ActionKind {int(self)}>"
|
|
|
+
|
|
|
+ def is_mouse(self) -> bool:
|
|
|
+ """ Is this Action a Mouse Action
|
|
|
+
|
|
|
+ Mouse Actions:
|
|
|
+ - Click (Press mouse button down, then release mouse button up)
|
|
|
+ - Click Down (Press mouse button down, never releasing up)
|
|
|
+ """
|
|
|
+ return self == ActionKind.CLICK or self == ActionKind.CLICK_DOWN
|
|
|
+
|
|
|
+ def is_keyboard(self) -> bool:
|
|
|
+ """ Is this Action a Keyboard Action
|
|
|
+
|
|
|
+ Keyboard Actions:
|
|
|
+ - Key (Press key down, then release key up)
|
|
|
+ - Key Down (Press key down, never releasing up)
|
|
|
+ """
|
|
|
+ return self == ActionKind.KEY or self == ActionKind.KEY_DOWN
|
|
|
+
|
|
|
+class Action:
|
|
|
+ name: str
|
|
|
+ """ Action's can be named to describe and clarify what the Action should do
|
|
|
+
|
|
|
+ i.e. 'auto click' for some Auto Clicker, 'shop' for something that opens a shop (such as '/shop')
|
|
|
+ """
|
|
|
+ kind: ActionKind
|
|
|
+ """ The Kind of Action to do
|
|
|
+
|
|
|
+ See tyrell.ActionKind
|
|
|
+ """
|
|
|
+ extra: Dict
|
|
|
+ enabled: bool
|
|
|
+ delay: int
|
|
|
+ max_delay: int
|
|
|
+ def __init__(self, name: str, kind: str, extra: Dict, on: bool=False, delay: int=0):
|
|
|
+ self.name = name
|
|
|
+ self.kind = ActionKind(kind)
|
|
|
+ self.enabled = on
|
|
|
+ self.delay = delay
|
|
|
+ self.max_delay = delay
|
|
|
+
|
|
|
+ def toggle(self) -> bool:
|
|
|
+ self.enabled = not self.enabled
|
|
|
+ return self.enabled
|
|
|
+
|
|
|
+ def enable(self):
|
|
|
+ self.enabled = True
|
|
|
+
|
|
|
+ def disable(self):
|
|
|
+ self.enabled = False
|
|
|
+
|
|
|
+ def is_ticker(self) -> bool:
|
|
|
+ """ Actions can be time based or not
|
|
|
+
|
|
|
+ Tickers are: Actions time based will fire after a number of ticks (at a set delay, tick speed)
|
|
|
+
|
|
|
+ All Actions not time based fire only when the selected "keybind" is pressed (where tickers use the "keybind" to toggle them on and off)
|
|
|
+ """
|
|
|
+ return self.max_delay != 0
|
|
|
+
|
|
|
+ def is_mirror(self, key: str) -> bool:
|
|
|
+ if self.kind != ActionKind.MIRROR:
|
|
|
+ return False
|
|
|
+ return key == self.extra["mirror"]
|
|
|
+
|
|
|
+ def tick(self) -> bool:
|
|
|
+ if not self.is_ticker():
|
|
|
+ return False
|
|
|
+ if not self.enabled:
|
|
|
+ if self.delay != self.max_delay:
|
|
|
+ self.delay = self.max_delay
|
|
|
+ return False
|
|
|
+ self.delay -= 1
|
|
|
+ if self.delay <= 0:
|
|
|
+ self.delay = self.max_delay
|
|
|
+ return True
|
|
|
+ return False
|
|
|
+
|
|
|
+ def do(self, key: Tuple[str, int], delay: int=50, hold: int=20):
|
|
|
+ if not self.enabled:
|
|
|
+ return
|
|
|
+ d = delay
|
|
|
+ h = hold
|
|
|
+ if "delay" in self.extra:
|
|
|
+ d = self.extra["delay"]
|
|
|
+ if "hold" in self.extra:
|
|
|
+ h = self.extra["hold"]
|
|
|
+ if self.kind == ActionKind.CLICK:
|
|
|
+ mouse_output(self.extra["button"], d, h)
|
|
|
+ elif self.kind == ActionKind.CLICK_DOWN:
|
|
|
+ mouse_down(button=self.extra["button"])
|
|
|
+ elif self.kind == ActionKind.KEY:
|
|
|
+ keyboard_output(self.extra["write"], d, h)
|
|
|
+ elif self.kind == ActionKind.KEY_DOWN:
|
|
|
+ key_down(self.extra["write"])
|
|
|
+ elif self.kind == ActionKind.MIRROR:
|
|
|
+ if key[1] == 0: # Up
|
|
|
+ if "write" in self.extra: # Key Mirror
|
|
|
+ key_up(self.extra["write"])
|
|
|
+ elif "button" in self.extra: # Mouse Mirror
|
|
|
+ mouse_up(button=self.extra["button"])
|
|
|
+ elif key[1] == 1: # Down
|
|
|
+ if "write" in self.extra: # Key Mirror
|
|
|
+ key_down(self.extra["write"])
|
|
|
+ elif "button" in self.extra: # Mouse Mirror
|
|
|
+ mouse_down(button=self.extra["button"])
|
|
|
+
|
|
|
+ def do_tick(self, delay: int=50, hold: int=20):
|
|
|
+ if self.tick():
|
|
|
+ self.do(delay, hold)
|
|
|
+
|
|
|
+class Tyrell:
|
|
|
+ pass
|
|
|
+
|
|
|
+class OldAction():
|
|
|
name: str
|
|
|
kind: str
|
|
|
extra: Dict
|
|
@@ -143,8 +291,8 @@ class Action():
|
|
|
elif self.kind == "key down":
|
|
|
key_down(self.extra["write"])
|
|
|
|
|
|
-class Tyrell():
|
|
|
- keybinds: Dict[str, Action]
|
|
|
+class OldTyrell():
|
|
|
+ keybinds: Dict[str, OldAction]
|
|
|
mirrors: Dict[str, str] # mirror key -> key in keybinds
|
|
|
toggled: bool
|
|
|
delay: int
|
|
@@ -210,9 +358,9 @@ class Tyrell():
|
|
|
if t["keybind"] == "?" or t["keybind"] == "`":
|
|
|
continue
|
|
|
if "duration" in t:
|
|
|
- self.add_action(t["keybind"], Action(ent.removesuffix(".toml"), t["kind"], extra=t, delay=t["duration"]))
|
|
|
+ self.add_action(t["keybind"], OldAction(ent.removesuffix(".toml"), t["kind"], extra=t, delay=t["duration"]))
|
|
|
else:
|
|
|
- self.add_action(t["keybind"], Action(ent.removesuffix(".toml"), t["kind"], extra=t))
|
|
|
+ self.add_action(t["keybind"], OldAction(ent.removesuffix(".toml"), t["kind"], extra=t))
|
|
|
|
|
|
def toggle(self, all: bool=False, all_tickers: bool=False, all_notickers: bool=False) -> bool:
|
|
|
self.toggled = not self.toggled
|
|
@@ -266,7 +414,7 @@ class Tyrell():
|
|
|
if act.max_delay == 0:
|
|
|
act.toggled = True
|
|
|
|
|
|
- def add_action(self, bind: str, act: Action):
|
|
|
+ def add_action(self, bind: str, act: OldAction):
|
|
|
act.toggled = False
|
|
|
if "placeholder_name" in self.profile:
|
|
|
if self.profile["placeholder_name"] and "write" in act.extra:
|
|
@@ -414,7 +562,7 @@ if __name__ == "__main__":
|
|
|
print_info("And defines in a \"global\" sense key delay and hold delay.")
|
|
|
print()
|
|
|
exit()
|
|
|
- ty = Tyrell(",".join(argv[1:]))
|
|
|
+ ty = OldTyrell(",".join(argv[1:]))
|
|
|
if len(ty.keybinds) == 0:
|
|
|
print_err("Missing keybinds")
|
|
|
print_info("(Might want some keybinds, place them in a 'keys' directory)")
|