fixed # 新增本地部署脚本,一键生成对应平台的压缩包内容

This commit is contained in:
2026-10-22 18:33:42 +08:00
parent 37c933db0c
commit d238005561
41 changed files with 1158 additions and 545 deletions
+36 -5
View File
@@ -1,7 +1,38 @@
# AstrBot 接入预留位置
# AstrBot 农场插件
发布目标:https://github.com/Shu-Ying/astrbot_plugin_farm.git
负责 AstrBot 事件、消息、配置和生命周期,不导入 NoneBot 或真寻。
未来生成 main.py、metadata.yaml、配置描述、依赖和私有核心。
本目录尚不可安装;必须验证资源体积及实际安装。
远程仓库本轮不再拉取或推送。
基于Star插件接口,命令、交易、数据与图片复用主仓库共享核心,
不导入NoneBot或真寻。此目录是接入源码,需构建生成完整插件包。
## 本地构建与安装
Windows双击主仓库根目录的`build_astrbot.cmd`,成功后控制台打印ZIP路径。
亦可运行`python scripts/build_plugin.py astrbot`。每次输出独立新目录,
不会覆盖上次产物,不访问远端,不安装依赖、不启动或修改机器人。
版本由主仓库`version.txt`统一生成,不手工修改metadata.yaml版本。
在AstrBot管理面板的插件管理中选择本地ZIP安装,选择生成的
`astrbot_plugin_farm-版本.zip`。插件依赖Pillow>=10.4,不包含AstrBot本体。
插件源码及素材遵循所附GPLv3许可证;不捆绑字体。
## 配置与使用
管理面板支持`font_path`(中文字体)、`data_dir`、`image_format`及
`image_quality`(整数1~95,默认75)。质量修改后下一次请求生效;
其他配置修改后重载插件。默认数据目录为
`data/plugin_data/astrbot_plugin_farm`,数据库与日志位于该目录,卸载
插件前自行备份;更改目录不自动搬迁数据,旧数据不会被覆盖。
按AstrBot配置的唤醒前缀发送,例如`/开通农场`、`/农场帮助`、
`/我的农场`、`/种子商店`、`/我的种子 文字`、`/播种 白萝卜`、`/收获`。
仅`/我的农场 高清`支持高清;其他图片统一遵循质量配置。
仓库保留分页和文字;偷菜通过`/偷菜 @目标`,不接受手输QQ号。
不提供共享核心尚未实现的签到、开垦、改名、土地升级及外部货币兑换。
存档按AstrBot部署、平台实例、机器人及用户隔离,不自动合并NoneBot或
真寻账号。缺少稳定消息ID时拒绝写操作。字体不可用时尽可能退回文字。
本地模拟和ZIP校验不等于真实平台发图成功,需要部署者实际验证。
官方接口参考:
[插件入口](https://docs.astrbot.app/en/dev/star/guides/simple.html)、
[插件配置](https://docs.astrbot.app/en/dev/star/guides/plugin-config.html)。
+27
View File
@@ -0,0 +1,27 @@
{
"font_path": {
"description": "中文字体路径",
"type": "string",
"default": "",
"hint": "部署环境可访问的中文字体文件;留空时尝试系统字体,找不到则退回文字。"
},
"data_dir": {
"description": "农场数据目录",
"type": "string",
"default": "",
"hint": "留空使用data/plugin_data/astrbot_plugin_farm。修改后重载插件;不会自动搬迁数据。"
},
"image_format": {
"description": "图片格式",
"type": "string",
"default": "AUTO",
"options": ["AUTO", "JPEG", "PNG"],
"hint": "AUTO使用压缩JPEG;修改后重载插件。"
},
"image_quality": {
"description": "农场图片质量",
"type": "int",
"default": 75,
"hint": "整数1~95,下一次图片请求生效;仅我的农场允许高清,质量不低于85。PNG不受影响。"
}
}
+87
View File
@@ -0,0 +1,87 @@
"""AstrBot薄接入;业务、交易及绘图复用共享运行时。"""
import asyncio
import json
import logging
from pathlib import Path
from astrbot.api import AstrBotConfig
from astrbot.api.event import AstrMessageEvent, filter
from astrbot.api.message_components import At, Image
from astrbot.api.star import Context, Star, StarTools
from .runtime import COMMANDS, Runtime
logger = logging.getLogger(__name__)
class FarmPlugin(Star):
def __init__(self, context: Context, config: AstrBotConfig):
super().__init__(context)
self.config = config
self._lifecycle_lock = asyncio.Lock()
self._closed = False
configured = config.get('data_dir', '')
data_dir = (Path(configured).expanduser() if configured else
StarTools.get_data_dir('astrbot_plugin_farm'))
image_format = str(config.get('image_format', 'AUTO')).upper()
if image_format not in ('AUTO', 'JPEG', 'PNG'):
raise ValueError('image_format must be AUTO, JPEG or PNG')
self.runtime = Runtime(
data_dir, config.get('font_path') or None, 'astrbot',
image_format, font_setting='font_path',
image_quality=config.get('image_quality', 75),
image_quality_provider=lambda: self.config.get('image_quality', 75),
)
async def initialize(self):
async with self._lifecycle_lock:
if not self._closed:
await self.runtime.start()
@filter.command('农场帮助', alias=set(COMMANDS) - {'农场帮助'})
async def farm(self, event: AstrMessageEvent):
"""农场帮助、注册、种植、仓库、交易及图片查询。"""
if self._closed:
yield event.plain_result('农场插件已关闭。')
return
await self.initialize()
parts = event.get_message_str().strip().split(maxsplit=1)
if not parts or parts[0] not in COMMANDS:
return
action = COMMANDS[parts[0]]
arguments = parts[1] if len(parts) == 2 else ''
target = None
if action == 'steal':
mentions = [str(segment.qq) for segment in event.get_messages()
if isinstance(segment, At)
and str(segment.qq) != str(event.get_self_id())]
if len(mentions) != 1 or mentions[0] in ('', 'all', '0'):
yield event.plain_result('请@一个具体的偷菜目标。')
return
target = mentions[0]
platform_id = event.get_platform_id()
if not platform_id or not event.get_sender_id():
yield event.plain_result('无法取得稳定的平台或用户标识,未执行。')
return
bot_id = json.dumps([str(platform_id), str(event.get_self_id())])
response = await self.runtime.execute(
action, arguments, bot_id=bot_id,
platform=event.get_platform_name(), user_id=event.get_sender_id(),
message_id=getattr(event.message_obj, 'message_id', None),
display_name=event.get_sender_name() or '农场玩家',
target_user_id=target,
)
if isinstance(response, bytes):
yield event.chain_result([Image.fromBytes(response)])
else:
yield event.plain_result(response)
async def terminate(self):
async with self._lifecycle_lock:
if self._closed:
return
self._closed = True
await self.runtime.close()
logger.info('farm astrbot plugin terminated')
+1
View File
@@ -0,0 +1 @@
Pillow>=10.4