# licro-docs **Repository Path**: srefp/licro-docs ## Basic Information - **Project Name**: licro-docs - **Description**: Licro教程 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-11-16 - **Last Updated**: 2025-11-16 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Licro脚本教程 新手可以直接看耕地机教程:[耕地机教程](https://gitee.com/srefp/licro-docs#耕地机教程) Licro语言是依赖耕地机实现的高效锄地专用语言,能极大提升工作效率!耕地机是一个通用的键鼠操作模拟软件,可以录制键鼠操作生成代码,然后对代码进行微调。Licro语言以及耕地机具有下面的特性: - 性能上的极致优化,Licro语言可以做到原生语言的效率,无桥接开销。 - 编写效率上的极致优化,Licro语言专为自动办公而生,天然适合编写自动化键鼠操作。 - 支持顺序、选择、循环结构,支持函数调用。自带的优化器会按照语法规则解析脚本,优化为指令列表交给零号引擎执行。 - 支持所有分辨率的屏幕。 > Licro发音:/laɪkrəʊ/ > > Licro是Lightning和Macro两个单词拼合而成,意思为闪宏。 ## 语法 下面介绍Licro语言的编写规则: ### 常量 用const定义全局常量,必须使用确定的字面量来进行定义。常量的作用域是全局的,在任意地方定义的常量,可以在任意地方使用。 ```dart const CONFIRM_POS = [12345, 12345]; const HELLO = '你好!'; const CLICK_DELAY = 10; ``` 允许后定义的const常量覆盖原有的const常量。第二次声明后,第一次声明相当于无效了。 ```dart const CONFIRM_POS = [12345, 12345]; const CONFIRM_POS = [54321, 54321]; ``` 但是不允许对常量进行再次赋值。能跑但是不建议这样写。 ```dart const CONFIRM_POS = [12345, 12345]; // 这样写是错误的! CONFIRM_POS = [54321, 54321]; ``` 常量在脚本解析的时候会直接使用字面量替换常量名称。 ```dart click(CONFIRM_POS, CLICK_DELAY); // 解析时替换为 click([54321, 54321], 10); ``` 耕地机中的配置都会作为常量,每次更改耕地机中的常量会自动触发脚本的重新解析。 ### 变量 用var定义变量,脚本中定义的可更改的为变量。变量的作用域是在其定义的大括号中。函数的返回值一定要使用var关键字接收! ```dart var pos = getMousePos(); click(pos, 10); ``` ### 条件分支 if、else if、else ```dart var xm = isCharatar('小明'); var xl = isCharatar('小李'); if (xm) { click([12345, 12345], 10); } else if (xl) { click([54321, 54321], 10); } else { tip('角色不正确!'); } ``` ### 循环 遍历列表 for of ```dart for (const point of points) { click(point, 8); } ``` 指定次数循环 ```dart for (int i = 0; i < 5; i++) { click([12345, 12345], 8); } ``` ### 运算符 #### 赋值运算符 设置变量或常量的值。 ```dart var name = 'licro'; ``` #### 比较运算符 目前支持数字的相互比较和字符串的相等/不相等比较。 ```dart if (name == 'licro') { tip('hello'); } ``` ## 函数 ### 1、键鼠操作 | 名称 | 作用 | 示例 | | ------- | -------------------------------------------------------- | ------------------------------------------- | | click | 点击 | `click(60)` | | click | 点击(指定左、右、中、侧键)left、right、middle | `click('right', 60)` | | click | 点击,鼠标移动到某个坐标后点击 | `click([12345, 12345], 60)` | | click | 点击,指定次数和间隔 | `click(4, 5, 60)` | | click | 点击【可以按照顺序,分别指定键位、坐标、次数】 | `click('left', [12345, 12345], 4, 5, 20)` | | press | 键盘按某个键 | `press('e', 50)` | | wheel | 滚轮,第一个参数表示次数,正负表示方向 | `wheel(1, 10)` | | drag | 拖动,每四个整数一次拖动,可多次拖动,第二个参数是首次拖动像素数 | `drag([12345, 12345, 54321, 54321], 5, 50)` | | kDown | 键盘按下某个键 | `kDown('e', 50)` | | kUp | 键盘松开某个键 | `kUp('e', 50)` | | mDown | 鼠标按下(左键) | `mDown(50)` | | mDown | 鼠标按下(指定左键还是右键) | `mDown('right', 50)` | | mUp | 鼠标松开(左键) | `mUp(50)` | | mUp | 鼠标松开(指定左键还是右键) | `mUp('right', 50)` | | move | 移动鼠标 | `move([12345, 12345], 50)` | | move | 插值移动鼠标(一次动一点)。参数:坐标、分多少次、每次延迟、最后延迟 | `move([12345, 12345], 20, 2, 50)` | | moveR | 相对移动鼠标 | `move([1000, 1000], 50)` | | moveR | 插值相对移动鼠标(一次动一点)。参数:坐标、分多少次、每次延迟、最后延迟 | `moveR([1000, 1000], 20, 2, 50)` | | moveR3D | 3D视角真正的相对移动鼠标,单位是像素值。 | `moveR3D([50, 50], 50)` | | moveR3D | 3D视角真正的插值相对移动鼠标,单位是像素值。 | `moveR3D([50, 50], 5, 2, 50)` | 另外有`moveAsync, moveRAsync, moveR3DAsync, wheelAsync, mDownAsync, mUpAsync, clickAsync, dragAsync`表示对应操作的异步版本,只管发送指令,完全不等待指令返回,可能会出现“吞指令”的情况。 ### 2、特殊的函数 脚本兼容性考虑。 | 名称 | 作用 | 示例 | | ------- | ---------------------- | ---------------------------- | | map | 开图 | `map(450)` | | book | 开书 | `book(720)` | | tpc | 半自动(选点然后确认) | `tpc([12345, 12345], 0)` | | tpcPlus | 五次点击的半自动 | `tpcPlus([12345, 12345], 0)` | ### 3、辅助函数 | 名称 | 作用 | 示例 | | ------------ | ---------------------------------------------------- | ------------------------------------------------------------ | | wait | 等待指定时长 | `wait(120)` | | cp | 复制并粘贴文本 | `cp('你好')` | | tip | 弹出消息 | `tip('运行到这里')` | | findColor | 找色,在某个点找色 | `findColor([12345, 12345], '#FF0221')` | | findColor | 找色,在某个区域找色 | `findColor([12345, 12345, 54321, 54321], '#FF0221')` | | findPic | 找图,在某个区域找图,与图片功能组合使用 | `[m,l,f] = findPic([12345, 12345, 54321, 54321], 'picKey')` | | findPic | 找图,在某个区域找图,限定时间内循环找图,找到后结束 | `[m,l,f] = findPic([12345, 12345, 54321, 54321], 'picKey', 10, 2000)` | | findMousePos | 返回鼠标所在的逻辑位置 | `let pos = findMousePos()` | | skipNext | 跳过下一个点位 | `skipNext()` | | toByName | 根据点位名称跳转到指定点位 | `toByName('大宝')` | **找图函数详解** 首先在截图管理中截取你想识别的图片。 - `findPic`返回中心位置 - `findPicLT`返回左上角位置 - `findPicRT`返回右上角位置 - `findPicRB`返回右下角位置 - `findPicLB`返回左下角位置 ```js // 找图 // 参数1:[43820, 0, 51605, 3794],找图范围,直接标点:左上角坐标和右下角坐标 // 参数2:'pic' 是你要找的图片的键 [ m, l, f ] = findPic([43820, 0, 51605, 3794], 'pic'); // 找图 // 参数1:[43820, 0, 51605, 3794],找图范围,直接标点:左上角坐标和右下角坐标 // 参数2:'pic' 是你要找的图片的键 // 参数3:10 是每隔10ms找一次 // 参数4:2000 是在2s内找到就返回,阈值在软件中可以自定义 [ m, l, f ] = findPic([43820, 0, 51605, 3794], 'pic', 10, 2000); // 第一个返回值:匹配程度,0 - 1的小数,越靠近1越匹配 // 第二个返回值:最佳匹配位置,返回的是找图中心位置 // 第三个返回值:是否匹配,和你配置的匹配阈值比较,大于则匹配 ``` # 耕地机教程 耕地机是执行Licro脚本的平台,目前耕地机中用到Licro脚本的有自动传脚本和自定义宏。 ## 启动方式 耕地机的启动方式有三种:当前屏幕、锚定进程名称、锚定窗口句柄。推荐使用锚定进程名称方式,如果锚定进程名称方式启动失败,可以使用锚定窗口句柄的启动方式。锚定进程名称的好处是启动方便,只需要选择一次,下次开启就会记住你选择的进程名称,直接启动,不需要再次选择。锚定窗口句柄时,由于每次启动进程所产生的窗口句柄号都不一样,所以下次开启时,需要重新获取一次窗口句柄进行启动。 ![image-20251116104807496](./README.assets/image-20251116104807496.png) ## 自定义宏 我们先学习自定义宏,自定义宏可以自定义一些自动化操作,使用键鼠进行触发。比如我想实现一套小连招,需要好几个键鼠,但是按起来比较费事,那么我可以在自定义宏中将这些键鼠操作写好,然后配置一个触发键/触发鼠标操作,就可以做到只点一下就实现一套小连招。 ![image-20251116103725129](./README.assets/image-20251116103725129.png) 点击耕地机的自定义宏界面,可以对自定义宏进行管理,点击新增按钮新增一个自定义宏。 ![image-20251116104848205](./README.assets/image-20251116104848205.png) 以半自动为例,填写宏的名称,触发类型这里我们选择按下,脚本引擎默认是零号引擎。 触发键这里我们需要点击一下触发键下面的按钮,此时按钮边缘变色表示激活窗口,可以记录我们当前的键鼠,这里我们直接按下鼠标的侧键(当前键盘中的任意键也是可以的),此时触发键变为xbutton2。 然后再脚本中,我们进行编写,半自动的流程: 1. 点击当前鼠标的位置 2. 点击传送按钮 3. 将鼠标复位 有些人不喜欢鼠标复位也是可以的。 这里既然考虑鼠标复位,需要先记录下鼠标的位置,我们使用`findMousePos()`函数获取当前的鼠标位置,将鼠标的位置放到变量中保存: ```js var p = findMousePos(); ``` 这里相当于是将鼠标位置放到变量p中保存,请牢记:调用函数得到的返回值一定要使用`var`这个关键字进行接收!请不要使用`const`进行接收,因为`const`是对已经确定的字面量进行优化的。 > 这里提到了关键字和字面量两个概念,这两个概念都是编程语言中有的概念,感兴趣的小伙伴可以自行百度或者问AI。 之后我们需要点击当前的位置,就使用`click`函数进行点击,这里的p其实内部就是一个整数的数组(例如`[12345, 12345]`)。 ```js click(p, 18); ``` 上述语句的含义是点击p坐标,然后等待18ms,当然每个人的电脑不一样,如果你的电脑比较慢,可以适当提高这个数值。 > 如果findMousePos获取的鼠标位置是:[12345, 12345],那么这个语句就是`click([12345, 12345], 18);` 然后传送按钮的坐标是固定的,这里我们可以在自动耕地机后,直接获取鼠标的坐标(将鼠标移动到传送按钮的位置,然后按下键盘的中的上方向键)就可以获取耕地机坐标。我的屏幕是16:9的屏幕,和我一致的可以直接使用这个坐标:`[50188, 61133]`。 ```js click([50188, 61133], 52); ``` 只有我们将鼠标复位,使用`move`函数操作鼠标移动到指定位置。 ```js move(p, 100); move(p, 0); ``` 这里为什么需要进行两次移动操作呢,因为某些进程中,可能出现第一次移动不了的情况,为了保险起见,我们需要等100ms再次移动,如果进程响应快,那么第一次就成功了,如果进程响应慢,我们也有第二次归位操作兜底。 > 兜底是自动化操作中一个很重要的思想,因为电脑的响应速度不是固定的,如果我们打开的程序比较多,那么电脑就会变慢,很多操作的延迟必须加大才可以。而我们如果想又快又稳,就需要写一个快的操作,然后再写一个慢的操作。慢的操作可以用来兜底,保证在电脑卡顿的情况下也能成功。 这样,一个半自动的宏就写好了!我们可以去在办公软件中使用了。 ## 自动传脚本 - 代码块 代码块机制是自动传脚本的一个亮点,比如我们在锄地时候,需要在指定位置打怪,打完怪传送,而传送的操作基本上是固定的。目前还没有完善的针对此类情形的专有的键鼠操作软件。 每个点位的名称写在最前面,然后跟着大括号包裹的代码块,表示这个点位传送需要进行的操作。 ```js 点位一 { map(450); tpc([32741, 32752], 0); } 点位二 { map(450); tpc([32741, 32752], 0); } 点位三 { map(450); tpc([32605, 32418], 0); } 点位四 { map(450); tpc([32758, 32752], 0); } 点位五 { map(450); tpc([32758, 32752], 0); } 点位六 { map(450); tpc([32758, 32752], 0); } /** * 多行注释 * 使用 斜杠*开始,使用 *斜杠结束 */ // 单行注释,使用两个斜杠 ``` 在名称后添加`#0`就可以使用零号引擎执行脚本。只有零号引擎可以执行Licro脚本优化后的指令列表。 ```js 点位 #0 { map(450); tpc([32758, 32752], 0); } ``` ## 预定义变量 脚本的右上角可以预定义变量,存储一些可能变动的值,比如某个按钮的位置,方便批量修改。 预定义变量中可以定义变量和函数。 ![image-20251116110801662](./README.assets/image-20251116110801662.png) 预定义变量的语法现在暂时是使用`var`定义变量,`const`定义函数,这是因为要兼容之前老的js函数。后续可能会修改为全使用`const` ```js var md = [46308, 9353]; var ly = [56416, 9414]; var dq = [46274, 15427]; var xm = [56485, 15487]; var fd = [46342, 21865]; var nt = [56485, 21743]; var ndkl = [46308, 27999]; var yxg = [46342, 35166]; var cyjy = [56587, 35105]; var ygss = [56553, 41483]; // 吃药函数 const eatFood = (pos) => { click(pos, 50); click([54524, 61680], 20); } // 批量吃药 const batchEatFood = () => { press('b', 600); click([29549, 3399], 120); for (const pos of FOOD_LIST) { eatFood(pos); } } ``` 比如批量吃药函数,预定义保存后就可以直接在脚本中写`batchEatFood();`进行快速吃药。