97 lines
2.3 KiB
Python
97 lines
2.3 KiB
Python
import argparse
|
|
import keyboard
|
|
import logging
|
|
import mouse
|
|
import pickle
|
|
import threading
|
|
import time
|
|
|
|
LOGGER = logging.getLogger("playback")
|
|
|
|
def main() -> None:
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument(
|
|
"-d", "--delay",
|
|
default=5,
|
|
type=int,
|
|
help="Seconds to wait before replay."
|
|
)
|
|
parser.add_argument(
|
|
"-i", "--input",
|
|
default="dump.capture",
|
|
help="Name of the file to replay from."
|
|
)
|
|
parser.add_argument(
|
|
"--verbose",
|
|
action="store_true",
|
|
help="Show verbose messages."
|
|
)
|
|
args = parser.parse_args()
|
|
logging.basicConfig(
|
|
level = logging.DEBUG if args.verbose else logging.INFO
|
|
)
|
|
_do_delay(args.delay)
|
|
|
|
events = _load_events(args.input)
|
|
_play_events(events)
|
|
|
|
def _play_events(events) -> None:
|
|
LOGGER.info("Playback started.")
|
|
key_state = keyboard.stash_state()
|
|
last_time = None
|
|
for event in events:
|
|
if last_time is not None:
|
|
to_sleep = event.time - last_time
|
|
if to_sleep > 0:
|
|
time.sleep(to_sleep)
|
|
last_time = event.time
|
|
if isinstance(event, keyboard.KeyboardEvent):
|
|
_play_event_keyboard(event)
|
|
elif any([
|
|
isinstance(event, mouse.ButtonEvent),
|
|
isinstance(event, mouse.MoveEvent),
|
|
isinstance(event, mouse.WheelEvent),
|
|
]):
|
|
_play_event_mouse(event)
|
|
else:
|
|
raise ValueError(f"Not a recognized event {event}")
|
|
|
|
keyboard.restore_modifiers(key_state)
|
|
LOGGER.info("Done.")
|
|
|
|
def _play_event_keyboard(event) -> None:
|
|
LOGGER.debug("Key %s", event)
|
|
key = event.scan_code or event.name
|
|
keyboard.press(key) if event.event_type == keyboard.KEY_DOWN else keyboard.release(key)
|
|
|
|
def _play_event_mouse(event) -> None:
|
|
LOGGER.debug("Mouse %s", event)
|
|
if isinstance(event, mouse.ButtonEvent):
|
|
if event.event_type == mouse.UP:
|
|
mouse.release(event.button)
|
|
else:
|
|
mouse.press(event.button)
|
|
elif isinstance(event, mouse.MoveEvent):
|
|
mouse.move(event.x, event.y, absolute=True)
|
|
# mouse.move(event.x, event.y)
|
|
elif isinstance(event, mouse.WheelEvent):
|
|
mouse.wheel(event.delta)
|
|
|
|
def _do_delay(delay: int) -> None:
|
|
if not delay:
|
|
return
|
|
print("\n")
|
|
for i in range(delay):
|
|
print(f"\rStarting in {delay-i} seconds")
|
|
time.sleep(1)
|
|
|
|
def _load_events(filename: str):
|
|
with open(filename, "rb") as input_:
|
|
events = pickle.load(input_)
|
|
LOGGER.debug("Loaded %s", filename)
|
|
return events
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|