Skip to content
Monomux edited this page May 11, 2025 · 17 revisions

目前使用的事件结构是实验性的,在后续版本可能会修改

目录

使用方法

基本操作

桌面模式

1、点击 录制 按钮,开始录制。

2、在计算机上进行任意操作,如点击鼠标、键盘输入,这部分的动作会被记录下来。

3、点击 结束 按钮,结束录制。

4、点击 启动 按钮,计算机会重复执行一遍第2步中所录制的动作。

命令行模式

usage: KeymouseGo.py [-h] [-rt RUNTIMES]
                     sctipts [sctipts ...]

positional arguments:
  sctipts               Path for the scripts

optional arguments:
  -h, --help            show this help message and exit
  -rt RUNTIMES, --runtimes RUNTIMES
                        Run times for the script

直接运行指定脚本:

> ./KeymouseGo scripts/0314_1452.txt

运行指定脚本3次:

> ./KeymouseGo scripts/0314_1452.txt -rt 3
> ./KeymouseGo scripts/0314_1452.txt --runtimes 3

脚本语法

演示屏幕分辨率为1920 * 1080

{
  scripts: [
    // 开始运行 `3000ms` 后,在屏幕相对坐标 `(0.05208, 0.1852)`即 `(100,200)` 处 `按下鼠标右键`;
    // 脚本支持使用绝对坐标和相对坐标,录制默认使用相对坐标
    {type: "event", event_type: "EM", delay: 3000, action_type: "mouse right down", action: ["0.05208%", "0.1852%"]},
    // 等待 `50ms` 后在相同位置 `抬起鼠标右键`;
    {type: "event", event_type: "EM", delay: 50, action_type: "mouse right up", action: [-1, -1]},
    // 等待 `1000ms` 后 `按下f键`;
    {type: "event", event_type: "EK", delay: 1000, action_type: "key down", action: [70, 'F', 0]},
    // 等待 `50ms` 后 `抬起f键`;
    {type: "event", event_type: "EK", delay: 50, action_type: "key up", action: [70, 'F', 0]},
    // 等待 `100ms` 后,在屏幕相对坐标 `(0.2604, 0.4630)`即 `(500, 500)` 处 `按下鼠标左键`;
    {type: "event", event_type: "EM", delay: 100, action_type: "mouse left down", action: ["0.2604%", "0.4630%"]},
    // 等待 `100ms` 后,鼠标移动至相对坐标 `(0.2604, 0.5556)`即 `(500, 600)` 位置;
    {type: "event", event_type: "EM", delay: 100, action_type: "mouse move", action: ["0.2604%", "0.5556%"]},
    // 等待 `100ms` 后,在屏幕相对坐标 `(0.3125, 0.5556)`即 `(600, 600)` 处 `抬起鼠标左键`;
    {type: "event", event_type: "EM", delay: 100, action_type: "mouse left up", action: ["0.3125%", "0.5556%"]},
    // 等待 `100ms` 后,在当前位置输入 `你好 world` 文字。
    {type: "event", event_type: "EX", delay: 100, action_type: "input", action: "你好 world"}
  ]
}

脚本为 json5 格式,每个最内层的jsonobject代表一个事件:

键鼠事件

基本格式为

{
   // jsonobject类型
   type: "event",
   // 时间间隔,指的是本事件与上一个事件之间相隔的时间,单位为毫秒
   delay: /*<Int>*/ ,
   // 鼠标动作或是键盘动作:`EM` 为鼠标,`EK` 为键盘,`EX` 为其他拓展动作。
   event_type: /*<str>*/,
   /* 动作的类型:
    `mouse left down` 为鼠标左键按下,`mouse left up` 为鼠标左键抬起,
    `mouse right down` 为鼠标右键按下,`mouse right up` 为鼠标右键抬起,
    `mouse middle down` 为鼠标中键按下, `mouse middle up` 为鼠标中键抬起,
    `mouse wheel up` 为鼠标滚轮上滑, `mouse wheel down` 为鼠标滚轮下滑,
    `key down` 为键盘按键按下,`key up` 为键盘按键抬起,
    `mouse move` 为鼠标滑过,`input` 输入文字。*/
   action_type: /*<str>*/,
   /* 具体的动作参数
    当为鼠标动作时,由两个子元素构成,分别为鼠标所在的屏幕位置的横纵坐标[x, y],
    横纵坐标为[-1, -1]时,表示在鼠标当前所在位置执行操作。
    当为键盘动作时,由三个子元素构成,分别是[按键编号, 按键名, 拓展标记],
    当为输入文字动作时,为要输入的文字内容。*/
   action: /*<List>/<str>*/,
   // (可选)列表中填入执行前调用的函数名,可以指定多个函数,函数在调用前需要编写相应的插件进行注册
   call: [/* <str>... */],
   // (可选)标签,供goto跳转使用,其它类型的jsonobject也可以有标签,请确保给予不同的jsonobject不同标签
   label: /*<str>*/,
   // (可选)其它参数,key和value均任意,可供插件注册的函数读取
   variable: value
}

序列事件

如果对于一系列键鼠事件需要进行相似的更改,可以采用这种格式的事件进行包装,基本格式为:

{
   // jsonobject类型
   type: "sequence",
   // 键鼠事件列表
   events: [/* ... */] ,
   // (可选)执行前调用的函数,与call不同的是执行列表内每一个键鼠事件前都会调用attach内的函数
   // 对于一系列需要添加相同调用函数的键鼠事件来说可以靠这个简化编写
   attach: [/* <str>... */],
   // (可选)标签,供goto跳转使用,请确保给予不同的jsonobject不同标签
   label: <str>
}

流程事件

if

基本格式为:

{
   // jsonobject类型
   type: "if",
   // 程序先调用judge指定的函数,根据返回值决定后续执行内容,为True执行do内的事件,为False执行else内的事件
   judge: "registered_function_name",
   do: [/* ... */],
   else: [/* ... */],
   // (可选)标签,供goto跳转使用,其它类型的jsonobject也可以有标签,请确保给予不同的jsonobject不同标签
   label: <str>
}

goto

基本格式为:

{
   // jsonobject类型
   type: "goto",
   // 跳转到相应label的object
   tolabel: "label",
   // (可选)标签,供goto跳转使用,请确保给予不同的jsonobject不同标签
   label: <str>
}

子流程事件

可以使程序在运行某一脚本的中途运行另一脚本,基本格式为:

{
   // jsonobject类型
   type: "subroutine",
   // 顺序执行其它脚本
   path: ["subscript_path"],
   // (可选)标签,供goto跳转使用,请确保给予不同的jsonobject不同标签
   label: <str>
}

自定义事件

单纯调用用户注册的函数,基本格式为:

{
   // jsonobject类型
   type: "custom",
   // 顺序执行注册的函数名
   call: [/* <str>... */],
   // (可选)标签,供goto跳转使用,请确保给予不同的jsonobject不同标签
   label: <str>
}
  • 修改时请严格遵守格式,否则可能导致脚本无法运行,建议修改前先备份一下。
  • 程序并未对执行流程进行检测保护,请确保脚本执行的流程合理。

函数注册

用户可以通过编写插件注册自定义函数,要编写一个插件,需要在程序的运行目录新建plugins文件夹,插件的目录结构为

/plugins/Myplugin/

- manifest.json5

- .py files

- ...

manifest.json5的格式为:

// manifest.json5
{
   "entry": "Example.py", // 实现插件接口的文件
   "plugin_class": "MyExample", // 实现插件接口的类名
   // (可选)基本信息
   "name": "Example",
   "description": "This is an example plugin",
   "author": "",
   "version": "1.0"
}

插件接口的定义为

class PluginInterface:
    def __init__(self, manifest: Dict):
        self.meta = PluginMeta(manifest)

    # 注册运行时可调用的函数
    @abstractmethod
    def register_functions(self) -> Dict[str, Callable]:
        pass

register_functions需要返回一个字典,key相当于函数的label,脚本中call和attach中输入的便是函数对应的key值,相应的value为函数本身。所有注册的函数都会收到一个类型为JsonObject的参数,通过访问该对象的content属性可以得到当前执行对象的属性。 在PluginInterface中,manifest.json5的内容以JsonObject的形式存于self.meta,可以通过该变量访问定义文件中添加的自定义参数

样例1:

以下内容实现了修改键鼠事件延时的功能,执行每个键鼠事件前,程序会调用注册的标签为"rd"的函数,并对传入的delay参数进行修改,从而实现在制定范围内随机给出执行延时。

// test.json5
{
    scripts: [
        {
            type: "sequence",
            events: [
                {
                    type: "event",
                    delay: "2-8",
                    event_type: "EM",
                    action_type: "mouse move",
                    action: ["0.39427083333333335%","0.45740740740740743%"]
                },
                {
                    type: "event",
                    delay: "1-514",
                    event_type: "EM",
                    action_type: "mouse move",
                    action: ["0.49270833333333336%","0.4398148148148148%"]
                }
            ],
            attach: ["rd"]
        },
    ]
}
// manifest.json5
{
   // 基本信息
   "name": "Random Delay",
   "description": "使延时的格式变为[0-9]+-[0-9]+,即X-Y,其中X为最小延时,Y为最大延时,X,Y均为整数,单位毫秒",
   "author": "Monomux",
   "version": "1.0",
   "entry": "Random_Delay.py",
   "plugin_class": "RandomDelay",
   "enabled": true
}

Random_Delay.py

from typing import Dict, Callable, List
from Util.Parser import JsonObject
from Plugin.Interface import PluginInterface
from loguru import logger
import re
import random


class RandomDelay(PluginInterface):
    def __init__(self, manifest: Dict):
        super().__init__(manifest)

    def register_functions(self) -> Dict[str, Callable]:
        funcs: Dict[str, Callable] = {}

        def random_delay(json_object: JsonObject):
            delay: str = json_object.content['delay']
            # 避免重复修改
            if type(delay) == str:
                delays = re.match('([0-9]+)\-([0-9]+)', delay).groups()
                json_object.content['delay'] = random.randint(int(delays[0]), int(delays[1]))

        funcs['rd'] = random_delay
        return funcs

样例2

5.2版本移除了原本自带的执行速度功能,该现在功能可以通过序列事件加调用函数实现 以下内容实现了修改键鼠事件延时的功能,执行每个键鼠事件前,程序会调用注册的标签为"rd"的函数,并对传入的delay参数进行修改。

// test.json5
{
    scripts: [
        {
            type: "sequence",
            events: [
                {
                    type: "event",
                    delay: 50,
                    event_type: "EM",
                    action_type: "mouse move",
                    action: ["0.39427083333333335%","0.45740740740740743%"]
                },
                {
                    type: "event",
                    delay: 50,
                    event_type: "EM",
                    action_type: "mouse move",
                    action: ["0.49270833333333336%","0.4398148148148148%"]
                }
            ],
            attach: ["cs"]
        },
    ]
}

manifest.json5

{
   // 基本信息
   "name": "Configure Speed",
   "description": "改变程序执行速度,参数speed为整数,范围(0,+∞),注意程序本身执行也有延时,速率大到一定程度会失效",
   "author": "Monomux",
   "version": "1.0",
   "entry": "Configure_Speed.py",
   "plugin_class": "ConfigureSpeed",
   "speed": 0.8 // 速度乘数,大于1时提速
}

ConfigureSpeed.py

from typing import Dict, Callable, Any
from Util.Parser import JsonObject
from Plugin.Interface import PluginInterface
from loguru import logger


class ConfigureSpeed(PluginInterface):
    def __init__(self, manifest: Dict):
        super().__init__(manifest)

    def register_functions(self) -> Dict[str, Callable]:
        funcs: Dict[str, Callable] = {}

        def change_speed(jsonObject: JsonObject):
            delay: int = jsonObject.content['delay']
            factor = self.meta.speed
            jsonObject.content['delay'] = int(delay / factor)

        funcs['cs'] = change_speed

        return funcs
Clone this wiki locally