diff --git a/.github/workflows/tag-and-release.yml b/.github/workflows/tag-and-release.yml new file mode 100644 index 0000000..c78b16f --- /dev/null +++ b/.github/workflows/tag-and-release.yml @@ -0,0 +1,69 @@ +name: "Build and Release SaltyQQChat" + +on: + push: + tags: + - "v*" + +jobs: + build-and-release: + runs-on: ubuntu-latest + name: "Build, Package and Release" + steps: + - name: "Checkout Code" + uses: actions/checkout@v4 + + - name: "Install Python" + run: | + sudo apt-get update + sudo apt-get install -y python3 python3-pip git zip + + - name: "Check Version from Tag and Files" + id: check_version + run: | + TAG_VERSION="${GITHUB_REF##*/}" + TAG_VERSION="${TAG_VERSION#v}" + + echo "Tag version: $TAG_VERSION" + + PLUGIN_VERSION=$(jq -r '.version' mcdreforged.plugin.json) + + echo "Plugin version from mcdreforged.plugin.json: $PLUGIN_VERSION" + + PYTHON_VERSION=$(python -c "import importlib.util, sys; spec = importlib.util.spec_from_file_location('version', 'salty_qq_chat/version.py'); version = importlib.util.module_from_spec(spec); sys.modules['version'] = version; spec.loader.exec_module(version); print(version.VERSION_STR)") + + echo "Python VERSION_STR: $PYTHON_VERSION" + + if [ "$TAG_VERSION" != "$PLUGIN_VERSION" ]; then + echo "Version mismatch: Tag version and plugin.json version do not match." + exit 1 + elif [ "$TAG_VERSION" != "$PYTHON_VERSION" ]; then + echo "Version mismatch: Tag version and Python VERSION_STR do not match." + exit 1 + elif [ "$PLUGIN_VERSION" != "$PYTHON_VERSION" ]; then + echo "Version mismatch: Plugin version and Python VERSION_STR do not match." + exit 1 + else + echo "Version match: Proceeding with the build." + fi + + echo "version=$TAG_VERSION" >> $GITHUB_OUTPUT + + - name: "Build and Package the Plugin" + run: | + zip -r SaltyQQChat-${{ steps.check_version.outputs.version }}.zip * + mv SaltyQQChat-${{ steps.check_version.outputs.version }}.zip SaltyQQChat-${{ steps.check_version.outputs.version }}.mcdr + + - name: "Upload Artifact" + uses: actions/upload-artifact@v4 + with: + name: "SaltyQQChat-${{ steps.check_version.outputs.version }}.mcdr" + path: "SaltyQQChat-${{ steps.check_version.outputs.version }}.mcdr" + + - name: "Create GitHub Release" + uses: "marvinpinto/action-automatic-releases@latest" + with: + repo_token: "${{ secrets.GITHUB_TOKEN }}" + prerelease: ${{ contains(github.ref, 'pre') }} + files: | + SaltyQQChat-${{ steps.check_version.outputs.version }}.mcdr diff --git a/.github/workflows/tag-release.yml b/.github/workflows/tag-release.yml deleted file mode 100644 index 464d720..0000000 --- a/.github/workflows/tag-release.yml +++ /dev/null @@ -1,53 +0,0 @@ -name: "Build and Release SaltyQQChat" - -on: - push: - tags: - - "v*" - -jobs: - build-and-release: - runs-on: ubuntu-latest - name: "Build, Package and Release" - steps: - - name: "Checkout Code" - uses: actions/checkout@v4 - - - name: "Check Version from Tag" - id: check_version - run: | - # 获取当前推送的tag - TAG_VERSION = "${GITHUB_REF##*/}" - # 从 mcdreforged.plugin.json 中读取 version 字段 - PLUGIN_VERSION=$(jq -r '.version' mcdreforged.plugin.json) - - echo "Tag version: $TAG_VERSION" - echo "Plugin version from mcdreforged.plugin.json: $PLUGIN_VERSION" - - # 比较 tag 和 plugin.json 中的版本 - if [ "$TAG_VERSION" != "$PLUGIN_VERSION" ]; then - echo "Version mismatch: Tag version and meta.json version do not match." - exit 1 - else - echo "Version match: Proceeding with the build." - fi - - - name: "Build and Package the Plugin" - run: | - # 打包源代码为一个压缩包 - mkdir -p dist - tar -czf dist/SaltyQQChat-${TAG_VERSION}.mcdr * # 打包所有文件到压缩包 - - - name: "Upload Artifact" - uses: actions/upload-artifact@v4 - with: - name: "SaltyQQChat-${TAG_VERSION}.mcdr" - path: dist/SaltyQQChat-${TAG_VERSION}.mcdr - - - name: "Create GitHub Release" - uses: "marvinpinto/action-automatic-releases@latest" - with: - repo_token: "${{ secrets.GITHUB_TOKEN }}" - prerelease: ${{ contains(github.ref, 'pre') }} - files: | - dist/SaltyQQChat-${TAG_VERSION}.mcdr diff --git a/README.md b/README.md new file mode 100644 index 0000000..2613709 --- /dev/null +++ b/README.md @@ -0,0 +1,57 @@ +
+ +![SaltyQQChat](https://socialify.git.ci/SALTWOOD/SaltyQQChat/image?description=1&font=Inter&forks=1&issues=1&language=1&name=1&owner=1&pattern=Plus&pulls=1&stargazers=1&theme=Auto) + +# SaltyQQChat +✨🎉 **基于 QQAPI 的、可拓展的 QQ 机器人插件!** 🎉✨ +
+ +# 简介 +这是一个使用 [QQAPI](https://github.com/AnzhiZhang/MCDReforgedPlugins/tree/master/src/qq_api) 的 QQ 机器人插件,可以说相当于重写了 [QQChat](https://github.com/AnzhiZhang/MCDReforgedPlugins/tree/master/src/qq_chat),砍掉了很多个人认为没必要的功能,优化了代码结构。 + +同时,它还支持通过**插件套插件**的方式,简单地扩展机器人,添加属于你的命令! + +目前相比 QQChat 新增功能: +- [x] 支持通过 `/bot-ban` `/bot-pardon` 拒绝响应某用户 +- [x] 支持通过机器人执行更多原版命令而不使用 `/command`(如 `/ban` `/pardon`) +- [x] 支持通过机器人启停服务器 +- [x] 支持艾特机器人进行答复,而不是发一句什么命令就答复 +- [x] 支持 MC 内执行 QQ 机器人命令 +- [x] 通过 `/ping` 命令、`/info` 命令检查机器人状态 +- [x] **[开发特性]** 通过 `/reload` 远程重载插件 +- [x] 可自定义的单向/双向 MC <==> QQ 群转发 +- [x] 基于正则表达式的易扩展命令树 + +同时,还去除/修改了以下功能: +- [x] 没有“管理群”、“主群”、“消息同步群”的功能,改为多群同步(不过一般就一个群而已) +- [x] 没有“MultiServer”特性,因为会导致难以预料的 bug 且应用面小 +- [x] 对 `!!qq` 命令做了权限限制,因为没有对 CQ 码进行转义,可能会导致机器人账号被用于发布违规信息 +- [x] 中文和数字、英文之间做了间隔,且语气更加诙谐 + +# 使用 +## 通过 MCDR 安装 +在 MCDR 控制台使用 `!!MCDR plugin install salty_qq_chat`,然后 `!!MCDR confirm`。 + +## 通过 Release 安装 +在 [Releases 页面](https://github.com/SALTWOOD/SaltyQQChat/releases) 下载对应版本的 `.mcdr` 文件,放入 `plugins` 文件夹重载。 + +## 通过源代码 +在 `plugins` 下执行 `git clone https://github.com/SALTWOOD/SaltyQQChat` 或者 `git clone git@github.com:SALTWOOD/SaltyQQChat`,然后重载插件。 + +# 插件套插件 +这是这个插件最有意思的功能之一,有意思到我还没琢磨出来 +简单来说就是通过一个单文件插件,获取到 SaltyQQChat 的插件实例,然后 +```Python +import re + +commands.add_command(re.compile(r'/你的命令 <你的参数>'), [int, str, float], handler) +``` +就可以添加命令了。稍迟些我会将代码放出来,直接改就可以用。 + +# 特别鸣谢 +- [QQAPI](https://github.com/AnzhiZhang/MCDReforgedPlugins/tree/master/src/qq_api) - 提供正向 WebSocket 接入到 CQHttp 的接口 +- [AnzhiZhang](https://github.com/AnzhiZhang) - 特例为我提供 LGPL 协议授权,但是我还是用了 GPL( +- **SALTWO∅D 服务器的各位** - 帮我测试机器人,还赶在发布 Release 之前帮我发现了越权漏洞( + +# 碎碎念 +- 其实这个项目也不是照抄 QQChat 的啦,只是因为能找到适合我的环境的现成的 API 只有 QQAPI 一个,又只有一个 QQChat 是这个 API 的下游使用,所以有些部分比较像是无法避免的() \ No newline at end of file diff --git a/mcdreforged.plugin.json b/mcdreforged.plugin.json index fabdf31..d99b7ce 100755 --- a/mcdreforged.plugin.json +++ b/mcdreforged.plugin.json @@ -1,10 +1,10 @@ { "id": "salty_qq_chat", - "version": "1.0.0", + "version": "1.1.3", "name": "SaltyQQChat", "description": { - "en_us": "", - "zh_cn": "Scalable QQ-Bot Built on QQAPI" + "en_us": "Scalable QQ-Bot Built on QQAPI", + "zh_cn": "一个基于 QQAPI 的可扩展的 QQ 机器人" }, "author": [ "SALTWOOD" diff --git a/salty_qq_chat/__init__.py b/salty_qq_chat/__init__.py index 4e29ddd..d9496d3 100755 --- a/salty_qq_chat/__init__.py +++ b/salty_qq_chat/__init__.py @@ -14,6 +14,7 @@ import time from .command_builder import CommandBuilder from .info import get_system_info +from .version import * # 变量声明 bindings: dict[str, str] @@ -23,9 +24,6 @@ commands: CommandBuilder -VERSION = (1, 1, 2) -VERSION_STR = '.'.join(map(str, VERSION)) - class Config(Serializable): groups: List[int] = [] treat_qq_admin_as_bot_admin: bool = True @@ -398,7 +396,7 @@ def mc_command_command(src: CommandSource, ctx: CommandContext): player = src.player if src.is_player else "Console" if player not in bindings.values(): src.reply("你还没有绑定,请先在 QQ 群内绑定一下~") - elif (not str(next((key for key, value in bindings.items() if value == player), 0)) in config.admins and not src.has_permission(2)) and (player != "Console"): + elif (not str(next((key for key, value in bindings.items() if value == player), 0)) in config.admins and not src.has_permission(4)) and (player != "Console"): src.reply("你莫得权限哦~") return diff --git a/salty_qq_chat/version.py b/salty_qq_chat/version.py new file mode 100644 index 0000000..4043d84 --- /dev/null +++ b/salty_qq_chat/version.py @@ -0,0 +1,2 @@ +VERSION = (1, 1, 3) +VERSION_STR = '.'.join(map(str, VERSION)) \ No newline at end of file