mirror of
https://github.com/LiteyukiStudio/LiteyukiBot.git
synced 2024-11-11 05:17:24 +08:00
⬇️ 更新文档样式
This commit is contained in:
parent
4910de74fd
commit
50c0216435
8
docs/dev/README.md
Normal file
8
docs/dev/README.md
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
title: 开发及贡献
|
||||||
|
index: false
|
||||||
|
icon: laptop-code
|
||||||
|
category: 开发
|
||||||
|
---
|
||||||
|
|
||||||
|
<Catalog />
|
99
docs/dev/dev_comm.md
Normal file
99
docs/dev/dev_comm.md
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
---
|
||||||
|
title: 进程通信
|
||||||
|
icon: exchange-alt
|
||||||
|
order: 4
|
||||||
|
category: 开发
|
||||||
|
---
|
||||||
|
|
||||||
|
## **通道通信**
|
||||||
|
|
||||||
|
### 简介
|
||||||
|
|
||||||
|
轻雪运行在主进程 MainProcess 里,其他插件框架进程是伴随的子进程,因此无法通过内存共享和直接对象传递的方式进行通信,轻雪提供了一个通道`Channel`用于跨进程通信,你可以通过`Channel`发送消息给其他进程,也可以监听其他进程的消息。
|
||||||
|
|
||||||
|
例如子进程接收到用户信息需要重启机器人,这时可以通过通道对主进程发送消息,主进程接收到消息后重启对应子进程。
|
||||||
|
|
||||||
|
### 示例
|
||||||
|
|
||||||
|
通道是全双工的,有两种接收模式,但一个通道只能使用一种,即被动模式和主动模式,被动模式由`chan.on_receive()`装饰回调函数实现,主动模式需调用`chan.receive()`实现
|
||||||
|
|
||||||
|
- 创建子进程的同时会初始化一个被动通道和一个主动通道,且通道标识为`{process_name}-active`和`{process_name}-passive`,
|
||||||
|
- 主进程中通过`get_channel`函数获取通道对象
|
||||||
|
- 子进程中导入单例`active_channel`及`passive_channel`即可
|
||||||
|
|
||||||
|
> 在轻雪插件中(主进程中)
|
||||||
|
|
||||||
|
```python
|
||||||
|
import asyncio
|
||||||
|
|
||||||
|
from liteyuki.comm import get_channel, Channel
|
||||||
|
from liteyuki import get_bot
|
||||||
|
|
||||||
|
# get_channel函数获取通道对象,参数为调用set_channel时的通道标识
|
||||||
|
channel_passive = get_channel("nonebot-passive") # 获取被动通道
|
||||||
|
channel_active = get_channel("nonebot-active") # 获取主动通道
|
||||||
|
liteyuki_bot = get_bot()
|
||||||
|
|
||||||
|
|
||||||
|
# 注册一个函数在轻雪启动后运行
|
||||||
|
@liteyuki_bot.on_after_start
|
||||||
|
async def send_data():
|
||||||
|
while True:
|
||||||
|
channel_passive.send("I am liteyuki main process passive")
|
||||||
|
channel_active.send("I am liteyuki main process active")
|
||||||
|
await asyncio.sleep(3) # 每3秒发送一次消息
|
||||||
|
```
|
||||||
|
|
||||||
|
> 在子进程中(例如NoneBot插件中)
|
||||||
|
|
||||||
|
```python
|
||||||
|
from nonebot import get_driver
|
||||||
|
from liteyuki.comm import active_channel, passive_channel # 子进程中获取通道直接导入进程全局单例即可
|
||||||
|
from liteyuki.log import logger
|
||||||
|
|
||||||
|
driver = get_driver()
|
||||||
|
|
||||||
|
|
||||||
|
# 被动模式,通过装饰器注册一个函数在接收到消息时运行,每次接收到字符串数据时都会运行
|
||||||
|
@passive_channel.on_receive(filter_func=lambda data: isinstance(data, str))
|
||||||
|
async def on_passive_receive(data):
|
||||||
|
logger.info(f"Passive receive: {data}")
|
||||||
|
|
||||||
|
|
||||||
|
# 注册一个函数在NoneBot启动后运行
|
||||||
|
@driver.on_startup
|
||||||
|
def on_startup():
|
||||||
|
while True:
|
||||||
|
data = active_channel.receive()
|
||||||
|
logger.info(f"Active receive: {data}")
|
||||||
|
```
|
||||||
|
|
||||||
|
> 启动后控制台输出
|
||||||
|
|
||||||
|
```log
|
||||||
|
0000-00-00 00:00:00 [ℹ️信息] Passive receive: I am liteyuki main process passive
|
||||||
|
0000-00-00 00:00:00 [ℹ️信息] Active receive: I am liteyuki main process active
|
||||||
|
0000-00-00 00:00:03 [ℹ️信息] Passive receive: I am liteyuki main process passive
|
||||||
|
0000-00-00 00:00:03 [ℹ️信息] Active receive: I am liteyuki main process active
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
## **共享内存通信**
|
||||||
|
|
||||||
|
### 简介
|
||||||
|
|
||||||
|
- 相比于普通进程通信,内存共享使得代码编写更加简洁,轻雪框架提供了一个内存共享通信的接口,你可以通过`storage`模块实现内存共享通信,该模块封装通道实现
|
||||||
|
- 内存共享是线程安全的,你可以在多个线程中读写共享内存,线程锁会自动保护共享内存的读写操作
|
||||||
|
|
||||||
|
### 示例
|
||||||
|
|
||||||
|
> 在任意进程中均可使用
|
||||||
|
|
||||||
|
```python
|
||||||
|
from liteyuki.comm.storage import shared_memory
|
||||||
|
|
||||||
|
shared_memory.set("key", "value") # 设置共享内存
|
||||||
|
value = shared_memory.get("key") # 获取共享内存
|
||||||
|
```
|
||||||
|
|
||||||
|
源代码:[liteyuki/comm/storage.py](https://github.com/LiteyukiStudio/LiteyukiBot/blob/main/liteyuki/comm/storage.py)
|
74
docs/dev/dev_lyfunc.md
Normal file
74
docs/dev/dev_lyfunc.md
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
---
|
||||||
|
title: 轻雪函数
|
||||||
|
icon: code
|
||||||
|
order: 2
|
||||||
|
category: 开发
|
||||||
|
---
|
||||||
|
|
||||||
|
## **轻雪函数**
|
||||||
|
|
||||||
|
轻雪函数 Liteyuki Function 是轻雪的一个功能,它允许你在轻雪中运行一些自定义的由数据驱动的命令,类似于Minecraft的mcfunction,属于资源包的一部分,但需单独起篇幅.
|
||||||
|
|
||||||
|
### **函数文件**
|
||||||
|
|
||||||
|
函数文件放在资源包的`functions`目录下,文件名以`.mcfunction` `.lyfunction` `.lyf`结尾,例如`test.mcfunction`,文件内容为一系列的命令,每行一个命令,支持单行注释`#`(编辑时的语法高亮可采取`shell`格式),例如:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# 在发信器输出"hello world"
|
||||||
|
cmd echo hello world
|
||||||
|
|
||||||
|
# 如果你想同时输出多行内容可以尝试换行符(Python格式)
|
||||||
|
cmd echo hello world\nLiteyuki bot
|
||||||
|
```
|
||||||
|
|
||||||
|
也支持句末注释,例如:
|
||||||
|
```shell
|
||||||
|
cmd echo hello world # 输出"hello world"
|
||||||
|
```
|
||||||
|
|
||||||
|
### **命令文档**
|
||||||
|
|
||||||
|
```shell
|
||||||
|
var <var1=value1> [var2=value2] ... # 定义变量
|
||||||
|
cmd <command> # 在设备上执行命令
|
||||||
|
api <api_name> [var=value...] # 调用Bot API
|
||||||
|
function <func_name> # 调用函数,可递归
|
||||||
|
sleep <time> # 异步等待,单位s
|
||||||
|
nohup <command> # 使用新的task执行命令,即不等待
|
||||||
|
end # 结束函数关键字,包括子task
|
||||||
|
await # 等待所有异步任务结束,若函数中启动了其他task,需要在最后调用,否则task对象会被销毁
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### **示例**
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# 疯狂戳好友
|
||||||
|
# 使用 /function poke user_id=123456 执行
|
||||||
|
# 每隔0.2s戳两次,无限戳,会触发最大递归深度限制
|
||||||
|
# 若要戳20s后停止,则需要删除await,添加sleep 20和end
|
||||||
|
api friend_poke user_id=user_id
|
||||||
|
api friend_poke user_id=user_id
|
||||||
|
sleep 0.2
|
||||||
|
nohup function poke
|
||||||
|
await
|
||||||
|
```
|
||||||
|
|
||||||
|
### **API**
|
||||||
|
|
||||||
|
理论上所有基于onebotv11的api都可调用,不同Adapter api也有差别.
|
||||||
|
|
||||||
|
[Onebot v11 API文档](https://283375.github.io/onebot_v11_vitepress/api/index.html)
|
||||||
|
|
||||||
|
### **结束关键字**
|
||||||
|
|
||||||
|
由于LiteyukiBot基于异步运行, 所以在编写lyfunction时也要注意异步的调用,避免出现"单线程走到底"的情况是效率提升的关键.
|
||||||
|
|
||||||
|
`await` 异步任务结束关键字,用于结束当前已完成function的执行
|
||||||
|
|
||||||
|
> [!warning]
|
||||||
|
> 但若出现非单function的情况,有一个task任务没有完成而await被执行了,那么当前所有函数包的task都会被截停销毁
|
||||||
|
|
||||||
|
|
||||||
|
> [!tip]
|
||||||
|
> 编写轻雪函数推荐你使用VS Code插件[Liteyuki Function](https://github.com/LiteyukiStudio/lyfunctionTextmate)实现语法高亮
|
82
docs/dev/dev_lyplugin.md
Normal file
82
docs/dev/dev_lyplugin.md
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
---
|
||||||
|
title: 轻雪插件开发
|
||||||
|
icon: laptop-code
|
||||||
|
order: 3
|
||||||
|
category: 开发
|
||||||
|
---
|
||||||
|
|
||||||
|
## 简介
|
||||||
|
|
||||||
|
轻雪插件是轻雪内置的一部分功能,运行在主进程中,可以很高程度地扩展轻雪的功能
|
||||||
|
|
||||||
|
## 开始
|
||||||
|
|
||||||
|
### 创建插件
|
||||||
|
|
||||||
|
一个`.py`文件或一个包含`__init__.py`的文件夹即可被识别为插件
|
||||||
|
|
||||||
|
首先创建一个文件夹,例如`watchdog_plugin`,并在其中创建一个`__init__.py`文件,即可创建一个插件
|
||||||
|
|
||||||
|
`__init__.py`
|
||||||
|
```python
|
||||||
|
from liteyuki.plugin import PluginMetadata, PluginType
|
||||||
|
from .watch_dog import * # 导入逻辑部分
|
||||||
|
|
||||||
|
# 定义插件元数据
|
||||||
|
__plugin_meta__ = PluginMetadata(
|
||||||
|
name="NoneDog", # 插件名称
|
||||||
|
version="1.0.0", # 插件版本
|
||||||
|
description="A simple plugin for nonebot developer", # 插件描述
|
||||||
|
type=PluginType.SERVICE # 插件类型
|
||||||
|
)
|
||||||
|
|
||||||
|
# 你的插件代码
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
### 编写逻辑部分
|
||||||
|
|
||||||
|
轻雪主进程不涉及聊天部分,因此插件主要是一些后台任务或者与聊天机器人的通信
|
||||||
|
以下我们会编写一个简单的插件,用于开发NoneBot时进行文件系统变更重载
|
||||||
|
`watch_dog.py`
|
||||||
|
```python
|
||||||
|
import os
|
||||||
|
from liteyuki.dev import observer # 导入文件系统观察器
|
||||||
|
from liteyuki import get_bot, logger # 导入轻雪Bot和日志
|
||||||
|
from watchdog.events import FileSystemEvent # 导入文件系统事件
|
||||||
|
|
||||||
|
liteyuki = get_bot() # 获取唯一的轻雪Bot实例
|
||||||
|
|
||||||
|
exclude_extensions = (".pyc", ".pyo") # 排除的文件扩展名
|
||||||
|
|
||||||
|
|
||||||
|
# 用observer的on_file_system_event装饰器监听文件系统事件
|
||||||
|
@observer.on_file_system_event(
|
||||||
|
directories=("src/nonebot_plugins",),
|
||||||
|
event_filter=lambda event: not event.src_path.endswith(exclude_extensions) and ("__pycache__" not in event.src_path) and os.path.isfile(event.src_path)
|
||||||
|
)
|
||||||
|
def restart_nonebot_process(event: FileSystemEvent):
|
||||||
|
logger.debug(f"File {event.src_path} changed, reloading nonebot...")
|
||||||
|
liteyuki.restart_process("nonebot") # 调用重启进程方法
|
||||||
|
```
|
||||||
|
|
||||||
|
### 加载插件
|
||||||
|
|
||||||
|
#### 方法1
|
||||||
|
|
||||||
|
- 在配置文件中的`liteyuki.plugins`中添加你的插件路径,例如`watchdog_plugin`,重启轻雪即可加载插件。
|
||||||
|
|
||||||
|
#### 方法2
|
||||||
|
|
||||||
|
- 使用开发工具快速运行插件,无需手动创建实例
|
||||||
|
- 创建入口文件,例如`main.py`,并在其中写入以下代码
|
||||||
|
|
||||||
|
```python
|
||||||
|
from liteyuki.dev.plugin import run_plugins
|
||||||
|
|
||||||
|
run_plugins("watchdog_plugin")
|
||||||
|
```
|
||||||
|
|
||||||
|
然后运行`python main.py`即可启动插件
|
||||||
|
|
||||||
|
启用插件后,我们在src/nonebot_plugins下创建一个文件,例如`test.py`,并在其中写入一些代码,保存后轻雪会自动重载NoneBot进程
|
53
docs/dev/dev_resource_pack.md
Normal file
53
docs/dev/dev_resource_pack.md
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
---
|
||||||
|
title: 资源包开发
|
||||||
|
icon: box
|
||||||
|
order: 1
|
||||||
|
category: 开发
|
||||||
|
---
|
||||||
|
|
||||||
|
## 简介
|
||||||
|
|
||||||
|
资源包,亦可根据用途称为主题包、字体包、语言包等,它允许你一定程度上自定义轻雪的外观,并且不用修改源代码
|
||||||
|
|
||||||
|
- [资源/主题商店](/store/)提供了一些资源包供你选择,你也可以自己制作资源包
|
||||||
|
- 资源包的制作很简单,如果你接触过`Minecraft`的资源包,那么你能够很快就上手,仅需按照原有路径进行文件替换即可,讲起打包成一个新的资源包。
|
||||||
|
- 部分内容制作需要一点点前端基础,例如`html`,`css`
|
||||||
|
- 轻雪原版资源包请查看`LiteyukiBot/liteyuki/resources`,可以在此基础上进行修改
|
||||||
|
- 欢迎各位投稿资源包到轻雪资源商店
|
||||||
|
|
||||||
|
请注意,主题包中的html渲染使用Js来规定数据的渲染位置,请确保您所编写的html代码能被Bot解析,否则会导致渲染失败或渲染结果不理想/异常/错位等无法预料的事情发生。推荐在编写html时同时更改对应Js代码,以避免出现无法预料的问题。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 加载资源包
|
||||||
|
|
||||||
|
- 资源包通常是以`.zip`格式压缩的,只需要将其解压到根目录`resources`目录下即可,注意不要嵌套文件夹,正常的路径应该是这样的
|
||||||
|
|
||||||
|
```shell
|
||||||
|
main.py
|
||||||
|
resources
|
||||||
|
└─resource_pack_1
|
||||||
|
├─metadata.yml
|
||||||
|
├─templates
|
||||||
|
└───...
|
||||||
|
└─resource_pack_2
|
||||||
|
├─metadata.yml
|
||||||
|
└─...
|
||||||
|
```
|
||||||
|
|
||||||
|
- 你自己制作的资源包也应该遵循这个规则,并且应该在`metadata.yml`中填写一些信息
|
||||||
|
- 若没有`metadata.yml`文件,则该文件夹不会被识别为资源包
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
name: "资源包名称"
|
||||||
|
version: "1.0.0"
|
||||||
|
description: "资源包描述"
|
||||||
|
# 你可以自定义一些信息,但请保证以上三个字段
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
- 资源包加载遵循一个优先级,即后加载的资源包会覆盖前面的资源包,例如,你在A包中定义了一个`index.html`文件,B包也定义了一个`index.html`文件,那么加载B包后,A包中的`index.html`文件会被覆盖
|
||||||
|
- 对于不同资源包的不同文件,是可以相对引用的,例如你在A中定义了`templates/index.html`,在B中定义了`templates/style.css`,可以在A的`index.html`中用`./style.css`相对路径引用B中的css
|
||||||
|
|
||||||
|
> [!tip]
|
||||||
|
> 资源包的结构会随着轻雪的更新而有变动,第三方资源包开发者需要注意版本兼容性,同时用户也应该自行选择可用的资源包
|
8
docs/en/dev/README.md
Normal file
8
docs/en/dev/README.md
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
title: 开发及贡献
|
||||||
|
index: false
|
||||||
|
icon: laptop-code
|
||||||
|
category: 开发
|
||||||
|
---
|
||||||
|
|
||||||
|
<Catalog />
|
99
docs/en/dev/dev_comm.md
Normal file
99
docs/en/dev/dev_comm.md
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
---
|
||||||
|
title: 进程通信
|
||||||
|
icon: exchange-alt
|
||||||
|
order: 4
|
||||||
|
category: 开发
|
||||||
|
---
|
||||||
|
|
||||||
|
## **通道通信**
|
||||||
|
|
||||||
|
### 简介
|
||||||
|
|
||||||
|
轻雪运行在主进程 MainProcess 里,其他插件框架进程是伴随的子进程,因此无法通过内存共享和直接对象传递的方式进行通信,轻雪提供了一个通道`Channel`用于跨进程通信,你可以通过`Channel`发送消息给其他进程,也可以监听其他进程的消息。
|
||||||
|
|
||||||
|
例如子进程接收到用户信息需要重启机器人,这时可以通过通道对主进程发送消息,主进程接收到消息后重启对应子进程。
|
||||||
|
|
||||||
|
### 示例
|
||||||
|
|
||||||
|
通道是全双工的,有两种接收模式,但一个通道只能使用一种,即被动模式和主动模式,被动模式由`chan.on_receive()`装饰回调函数实现,主动模式需调用`chan.receive()`实现
|
||||||
|
|
||||||
|
- 创建子进程的同时会初始化一个被动通道和一个主动通道,且通道标识为`{process_name}-active`和`{process_name}-passive`,
|
||||||
|
- 主进程中通过`get_channel`函数获取通道对象
|
||||||
|
- 子进程中导入单例`active_channel`及`passive_channel`即可
|
||||||
|
|
||||||
|
> 在轻雪插件中(主进程中)
|
||||||
|
|
||||||
|
```python
|
||||||
|
import asyncio
|
||||||
|
|
||||||
|
from liteyuki.comm import get_channel, Channel
|
||||||
|
from liteyuki import get_bot
|
||||||
|
|
||||||
|
# get_channel函数获取通道对象,参数为调用set_channel时的通道标识
|
||||||
|
channel_passive = get_channel("nonebot-passive") # 获取被动通道
|
||||||
|
channel_active = get_channel("nonebot-active") # 获取主动通道
|
||||||
|
liteyuki_bot = get_bot()
|
||||||
|
|
||||||
|
|
||||||
|
# 注册一个函数在轻雪启动后运行
|
||||||
|
@liteyuki_bot.on_after_start
|
||||||
|
async def send_data():
|
||||||
|
while True:
|
||||||
|
channel_passive.send("I am liteyuki main process passive")
|
||||||
|
channel_active.send("I am liteyuki main process active")
|
||||||
|
await asyncio.sleep(3) # 每3秒发送一次消息
|
||||||
|
```
|
||||||
|
|
||||||
|
> 在子进程中(例如NoneBot插件中)
|
||||||
|
|
||||||
|
```python
|
||||||
|
from nonebot import get_driver
|
||||||
|
from liteyuki.comm import active_channel, passive_channel # 子进程中获取通道直接导入进程全局单例即可
|
||||||
|
from liteyuki.log import logger
|
||||||
|
|
||||||
|
driver = get_driver()
|
||||||
|
|
||||||
|
|
||||||
|
# 被动模式,通过装饰器注册一个函数在接收到消息时运行,每次接收到字符串数据时都会运行
|
||||||
|
@passive_channel.on_receive(filter_func=lambda data: isinstance(data, str))
|
||||||
|
async def on_passive_receive(data):
|
||||||
|
logger.info(f"Passive receive: {data}")
|
||||||
|
|
||||||
|
|
||||||
|
# 注册一个函数在NoneBot启动后运行
|
||||||
|
@driver.on_startup
|
||||||
|
def on_startup():
|
||||||
|
while True:
|
||||||
|
data = active_channel.receive()
|
||||||
|
logger.info(f"Active receive: {data}")
|
||||||
|
```
|
||||||
|
|
||||||
|
> 启动后控制台输出
|
||||||
|
|
||||||
|
```log
|
||||||
|
0000-00-00 00:00:00 [ℹ️信息] Passive receive: I am liteyuki main process passive
|
||||||
|
0000-00-00 00:00:00 [ℹ️信息] Active receive: I am liteyuki main process active
|
||||||
|
0000-00-00 00:00:03 [ℹ️信息] Passive receive: I am liteyuki main process passive
|
||||||
|
0000-00-00 00:00:03 [ℹ️信息] Active receive: I am liteyuki main process active
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
## **共享内存通信**
|
||||||
|
|
||||||
|
### 简介
|
||||||
|
|
||||||
|
- 相比于普通进程通信,内存共享使得代码编写更加简洁,轻雪框架提供了一个内存共享通信的接口,你可以通过`storage`模块实现内存共享通信,该模块封装通道实现
|
||||||
|
- 内存共享是线程安全的,你可以在多个线程中读写共享内存,线程锁会自动保护共享内存的读写操作
|
||||||
|
|
||||||
|
### 示例
|
||||||
|
|
||||||
|
> 在任意进程中均可使用
|
||||||
|
|
||||||
|
```python
|
||||||
|
from liteyuki.comm.storage import shared_memory
|
||||||
|
|
||||||
|
shared_memory.set("key", "value") # 设置共享内存
|
||||||
|
value = shared_memory.get("key") # 获取共享内存
|
||||||
|
```
|
||||||
|
|
||||||
|
源代码:[liteyuki/comm/storage.py](https://github.com/LiteyukiStudio/LiteyukiBot/blob/main/liteyuki/comm/storage.py)
|
74
docs/en/dev/dev_lyfunc.md
Normal file
74
docs/en/dev/dev_lyfunc.md
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
---
|
||||||
|
title: 轻雪函数
|
||||||
|
icon: code
|
||||||
|
order: 2
|
||||||
|
category: 开发
|
||||||
|
---
|
||||||
|
|
||||||
|
## **轻雪函数**
|
||||||
|
|
||||||
|
轻雪函数 Liteyuki Function 是轻雪的一个功能,它允许你在轻雪中运行一些自定义的由数据驱动的命令,类似于Minecraft的mcfunction,属于资源包的一部分,但需单独起篇幅.
|
||||||
|
|
||||||
|
### **函数文件**
|
||||||
|
|
||||||
|
函数文件放在资源包的`functions`目录下,文件名以`.mcfunction` `.lyfunction` `.lyf`结尾,例如`test.mcfunction`,文件内容为一系列的命令,每行一个命令,支持单行注释`#`(编辑时的语法高亮可采取`shell`格式),例如:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# 在发信器输出"hello world"
|
||||||
|
cmd echo hello world
|
||||||
|
|
||||||
|
# 如果你想同时输出多行内容可以尝试换行符(Python格式)
|
||||||
|
cmd echo hello world\nLiteyuki bot
|
||||||
|
```
|
||||||
|
|
||||||
|
也支持句末注释,例如:
|
||||||
|
```shell
|
||||||
|
cmd echo hello world # 输出"hello world"
|
||||||
|
```
|
||||||
|
|
||||||
|
### **命令文档**
|
||||||
|
|
||||||
|
```shell
|
||||||
|
var <var1=value1> [var2=value2] ... # 定义变量
|
||||||
|
cmd <command> # 在设备上执行命令
|
||||||
|
api <api_name> [var=value...] # 调用Bot API
|
||||||
|
function <func_name> # 调用函数,可递归
|
||||||
|
sleep <time> # 异步等待,单位s
|
||||||
|
nohup <command> # 使用新的task执行命令,即不等待
|
||||||
|
end # 结束函数关键字,包括子task
|
||||||
|
await # 等待所有异步任务结束,若函数中启动了其他task,需要在最后调用,否则task对象会被销毁
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### **示例**
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# 疯狂戳好友
|
||||||
|
# 使用 /function poke user_id=123456 执行
|
||||||
|
# 每隔0.2s戳两次,无限戳,会触发最大递归深度限制
|
||||||
|
# 若要戳20s后停止,则需要删除await,添加sleep 20和end
|
||||||
|
api friend_poke user_id=user_id
|
||||||
|
api friend_poke user_id=user_id
|
||||||
|
sleep 0.2
|
||||||
|
nohup function poke
|
||||||
|
await
|
||||||
|
```
|
||||||
|
|
||||||
|
### **API**
|
||||||
|
|
||||||
|
理论上所有基于onebotv11的api都可调用,不同Adapter api也有差别.
|
||||||
|
|
||||||
|
[Onebot v11 API文档](https://283375.github.io/onebot_v11_vitepress/api/index.html)
|
||||||
|
|
||||||
|
### **结束关键字**
|
||||||
|
|
||||||
|
由于LiteyukiBot基于异步运行, 所以在编写lyfunction时也要注意异步的调用,避免出现"单线程走到底"的情况是效率提升的关键.
|
||||||
|
|
||||||
|
`await` 异步任务结束关键字,用于结束当前已完成function的执行
|
||||||
|
|
||||||
|
> [!warning]
|
||||||
|
> 但若出现非单function的情况,有一个task任务没有完成而await被执行了,那么当前所有函数包的task都会被截停销毁
|
||||||
|
|
||||||
|
|
||||||
|
> [!tip]
|
||||||
|
> 编写轻雪函数推荐你使用VS Code插件[Liteyuki Function](https://github.com/LiteyukiStudio/lyfunctionTextmate)实现语法高亮
|
82
docs/en/dev/dev_lyplugin.md
Normal file
82
docs/en/dev/dev_lyplugin.md
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
---
|
||||||
|
title: 轻雪插件开发
|
||||||
|
icon: laptop-code
|
||||||
|
order: 3
|
||||||
|
category: 开发
|
||||||
|
---
|
||||||
|
|
||||||
|
## 简介
|
||||||
|
|
||||||
|
轻雪插件是轻雪内置的一部分功能,运行在主进程中,可以很高程度地扩展轻雪的功能
|
||||||
|
|
||||||
|
## 开始
|
||||||
|
|
||||||
|
### 创建插件
|
||||||
|
|
||||||
|
一个`.py`文件或一个包含`__init__.py`的文件夹即可被识别为插件
|
||||||
|
|
||||||
|
首先创建一个文件夹,例如`watchdog_plugin`,并在其中创建一个`__init__.py`文件,即可创建一个插件
|
||||||
|
|
||||||
|
`__init__.py`
|
||||||
|
```python
|
||||||
|
from liteyuki.plugin import PluginMetadata, PluginType
|
||||||
|
from .watch_dog import * # 导入逻辑部分
|
||||||
|
|
||||||
|
# 定义插件元数据
|
||||||
|
__plugin_meta__ = PluginMetadata(
|
||||||
|
name="NoneDog", # 插件名称
|
||||||
|
version="1.0.0", # 插件版本
|
||||||
|
description="A simple plugin for nonebot developer", # 插件描述
|
||||||
|
type=PluginType.SERVICE # 插件类型
|
||||||
|
)
|
||||||
|
|
||||||
|
# 你的插件代码
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
### 编写逻辑部分
|
||||||
|
|
||||||
|
轻雪主进程不涉及聊天部分,因此插件主要是一些后台任务或者与聊天机器人的通信
|
||||||
|
以下我们会编写一个简单的插件,用于开发NoneBot时进行文件系统变更重载
|
||||||
|
`watch_dog.py`
|
||||||
|
```python
|
||||||
|
import os
|
||||||
|
from liteyuki.dev import observer # 导入文件系统观察器
|
||||||
|
from liteyuki import get_bot, logger # 导入轻雪Bot和日志
|
||||||
|
from watchdog.events import FileSystemEvent # 导入文件系统事件
|
||||||
|
|
||||||
|
liteyuki = get_bot() # 获取唯一的轻雪Bot实例
|
||||||
|
|
||||||
|
exclude_extensions = (".pyc", ".pyo") # 排除的文件扩展名
|
||||||
|
|
||||||
|
|
||||||
|
# 用observer的on_file_system_event装饰器监听文件系统事件
|
||||||
|
@observer.on_file_system_event(
|
||||||
|
directories=("src/nonebot_plugins",),
|
||||||
|
event_filter=lambda event: not event.src_path.endswith(exclude_extensions) and ("__pycache__" not in event.src_path) and os.path.isfile(event.src_path)
|
||||||
|
)
|
||||||
|
def restart_nonebot_process(event: FileSystemEvent):
|
||||||
|
logger.debug(f"File {event.src_path} changed, reloading nonebot...")
|
||||||
|
liteyuki.restart_process("nonebot") # 调用重启进程方法
|
||||||
|
```
|
||||||
|
|
||||||
|
### 加载插件
|
||||||
|
|
||||||
|
#### 方法1
|
||||||
|
|
||||||
|
- 在配置文件中的`liteyuki.plugins`中添加你的插件路径,例如`watchdog_plugin`,重启轻雪即可加载插件。
|
||||||
|
|
||||||
|
#### 方法2
|
||||||
|
|
||||||
|
- 使用开发工具快速运行插件,无需手动创建实例
|
||||||
|
- 创建入口文件,例如`main.py`,并在其中写入以下代码
|
||||||
|
|
||||||
|
```python
|
||||||
|
from liteyuki.dev.plugin import run_plugins
|
||||||
|
|
||||||
|
run_plugins("watchdog_plugin")
|
||||||
|
```
|
||||||
|
|
||||||
|
然后运行`python main.py`即可启动插件
|
||||||
|
|
||||||
|
启用插件后,我们在src/nonebot_plugins下创建一个文件,例如`test.py`,并在其中写入一些代码,保存后轻雪会自动重载NoneBot进程
|
53
docs/en/dev/dev_resource_pack.md
Normal file
53
docs/en/dev/dev_resource_pack.md
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
---
|
||||||
|
title: 资源包开发
|
||||||
|
icon: box
|
||||||
|
order: 1
|
||||||
|
category: 开发
|
||||||
|
---
|
||||||
|
|
||||||
|
## 简介
|
||||||
|
|
||||||
|
资源包,亦可根据用途称为主题包、字体包、语言包等,它允许你一定程度上自定义轻雪的外观,并且不用修改源代码
|
||||||
|
|
||||||
|
- [资源/主题商店](/store/)提供了一些资源包供你选择,你也可以自己制作资源包
|
||||||
|
- 资源包的制作很简单,如果你接触过`Minecraft`的资源包,那么你能够很快就上手,仅需按照原有路径进行文件替换即可,讲起打包成一个新的资源包。
|
||||||
|
- 部分内容制作需要一点点前端基础,例如`html`,`css`
|
||||||
|
- 轻雪原版资源包请查看`LiteyukiBot/liteyuki/resources`,可以在此基础上进行修改
|
||||||
|
- 欢迎各位投稿资源包到轻雪资源商店
|
||||||
|
|
||||||
|
请注意,主题包中的html渲染使用Js来规定数据的渲染位置,请确保您所编写的html代码能被Bot解析,否则会导致渲染失败或渲染结果不理想/异常/错位等无法预料的事情发生。推荐在编写html时同时更改对应Js代码,以避免出现无法预料的问题。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 加载资源包
|
||||||
|
|
||||||
|
- 资源包通常是以`.zip`格式压缩的,只需要将其解压到根目录`resources`目录下即可,注意不要嵌套文件夹,正常的路径应该是这样的
|
||||||
|
|
||||||
|
```shell
|
||||||
|
main.py
|
||||||
|
resources
|
||||||
|
└─resource_pack_1
|
||||||
|
├─metadata.yml
|
||||||
|
├─templates
|
||||||
|
└───...
|
||||||
|
└─resource_pack_2
|
||||||
|
├─metadata.yml
|
||||||
|
└─...
|
||||||
|
```
|
||||||
|
|
||||||
|
- 你自己制作的资源包也应该遵循这个规则,并且应该在`metadata.yml`中填写一些信息
|
||||||
|
- 若没有`metadata.yml`文件,则该文件夹不会被识别为资源包
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
name: "资源包名称"
|
||||||
|
version: "1.0.0"
|
||||||
|
description: "资源包描述"
|
||||||
|
# 你可以自定义一些信息,但请保证以上三个字段
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
- 资源包加载遵循一个优先级,即后加载的资源包会覆盖前面的资源包,例如,你在A包中定义了一个`index.html`文件,B包也定义了一个`index.html`文件,那么加载B包后,A包中的`index.html`文件会被覆盖
|
||||||
|
- 对于不同资源包的不同文件,是可以相对引用的,例如你在A中定义了`templates/index.html`,在B中定义了`templates/style.css`,可以在A的`index.html`中用`./style.css`相对路径引用B中的css
|
||||||
|
|
||||||
|
> [!tip]
|
||||||
|
> 资源包的结构会随着轻雪的更新而有变动,第三方资源包开发者需要注意版本兼容性,同时用户也应该自行选择可用的资源包
|
Loading…
Reference in New Issue
Block a user