From 3b962d66fa63f2ea2a448cfc493ff24bc7d5a99c Mon Sep 17 00:00:00 2001 From: Hotaru Date: Sun, 31 Dec 2023 15:37:08 +0800 Subject: [PATCH] chore: aciton test --- .changeset/README.md | 8 - .changeset/config.json | 14 - .gitignore | 3 +- modules/adapter-onebot/package.json | 22 + modules/adapter-onebot/src/adapter.ts | 240 ++++++++ modules/adapter-onebot/src/api.ts | 128 ++++ modules/adapter-onebot/src/elements.ts | 50 ++ modules/adapter-onebot/src/index.ts | 3 + .../adapter-onebot/src/services/wsserver.ts | 22 + modules/adapter-onebot/src/types.ts | 522 ++++++++++++++++ modules/adapter-onebot/tsconfig.json | 12 + modules/adapter-qq/package.json | 22 + modules/adapter-qq/src/adapter.ts | 190 ++++++ modules/adapter-qq/src/api.ts | 10 + modules/adapter-qq/src/index.ts | 3 + modules/adapter-qq/src/test.ats | 76 +++ modules/adapter-qq/src/types.ts | 247 ++++++++ modules/adapter-qq/tsconfig.json | 12 + modules/core/locales/zh_CN.json | 18 + .../core/package.json | 11 +- modules/core/src/index.ts | 95 +++ modules/core/tsconfig.json | 12 + modules/helper/locales/zh_CN.json | 17 + modules/helper/package.json | 18 + modules/helper/src/index.ts | 87 +++ modules/helper/tsconfig.json | 12 + modules/i18n-command/locales/zh_CN.json | 20 + modules/i18n-command/package.json | 18 + modules/i18n-command/src/index.ts | 98 +++ modules/i18n-command/tsconfig.json | 12 + modules/menu/locales/zh_CN.json | 3 + modules/menu/package.json | 18 + modules/menu/src/index.ts | 28 + modules/menu/tsconfig.json | 12 + modules1/access/locales/en_US.json | 9 - modules1/access/locales/ja_JP.json | 9 - modules1/access/locales/zh_CN.json | 9 - modules1/access/locales/zh_TW.json | 9 - modules1/access/package1.json | 11 - modules1/access/src/index.ts | 46 -- modules1/access/src/method.ts | 62 -- modules1/access/src/type.ts | 7 - modules1/alias/README.md | 41 -- modules1/alias/locales/en_US.json | 106 ---- modules1/alias/locales/ja_JP.json | 106 ---- modules1/alias/locales/zh_CN.json | 106 ---- modules1/alias/locales/zh_TW.json | 106 ---- modules1/alias/manifest.json | 7 - modules1/alias/package1.json | 11 - modules1/alias/src/class/class.cache.ts | 16 - modules1/alias/src/class/class.command.ts | 46 -- modules1/alias/src/class/class.content.ts | 203 ------ modules1/alias/src/class/class.core.ts | 160 ----- modules1/alias/src/class/class.data.ts | 11 - modules1/alias/src/index.ts | 106 ---- modules1/alias/src/method.ts | 122 ---- modules1/alias/src/type.ts | 102 --- modules1/daytool/README.md | 42 -- modules1/daytool/locales/en_US.json | 46 -- modules1/daytool/locales/ja_JP.json | 45 -- modules1/daytool/locales/zh_CN.json | 46 -- modules1/daytool/locales/zh_TW.json | 46 -- modules1/daytool/manifest.json | 7 - modules1/daytool/package1.json | 11 - modules1/daytool/src/config.ts | 6 - modules1/daytool/src/index.ts | 89 --- modules1/daytool/src/method.ts | 12 - modules1/minecraft/locales/en_US.json | 13 - modules1/minecraft/locales/ja_JP.json | 13 - modules1/minecraft/locales/zh_CN.json | 13 - modules1/minecraft/src/index.ts | 109 ---- modules1/minecraft/tsconfig.json | 8 - modules1/querytool/locales/en_US.json | 44 -- modules1/querytool/locales/ja_JP.json | 44 -- modules1/querytool/locales/zh_CN.json | 43 -- modules1/querytool/locales/zh_TW.json | 44 -- modules1/querytool/package1.json | 11 - modules1/querytool/src/index.ts | 62 -- modules1/sed/locales/en_US.json | 44 -- modules1/sed/locales/ja_JP.json | 44 -- modules1/sed/locales/zh_CN.json | 43 -- modules1/sed/locales/zh_TW.json | 44 -- modules1/sed/package1.json | 11 - modules1/sed/src/index.ts | 161 ----- modules1/status/locales/en_US.json | 7 - modules1/status/locales/ja_JP.json | 6 - modules1/status/locales/zh_CN.json | 4 - modules1/status/locales/zh_TW.json | 106 ---- modules1/status/package1.json | 11 - modules1/status/src/class/class.cache.ts | 16 - modules1/status/src/class/class.command.ts | 46 -- modules1/status/src/class/class.content.ts | 204 ------ modules1/status/src/class/class.core.ts | 160 ----- modules1/status/src/class/class.data.ts | 11 - modules1/status/src/index.ts | 579 ------------------ modules1/status/src/method.ts | 122 ---- modules1/status/src/type.ts | 102 --- package.json | 19 +- packages/core/CHANGELOG.md | 7 - packages/core/package.json | 2 +- packages/kotori/CHANGELOG.md | 75 --- packages/loader/CHANGELOG.md | 12 - scripts/release.ts | 275 ++++++--- scripts/release2.ts | 116 ++++ 104 files changed, 2336 insertions(+), 4119 deletions(-) delete mode 100644 .changeset/README.md delete mode 100644 .changeset/config.json create mode 100644 modules/adapter-onebot/package.json create mode 100644 modules/adapter-onebot/src/adapter.ts create mode 100644 modules/adapter-onebot/src/api.ts create mode 100644 modules/adapter-onebot/src/elements.ts create mode 100644 modules/adapter-onebot/src/index.ts create mode 100644 modules/adapter-onebot/src/services/wsserver.ts create mode 100644 modules/adapter-onebot/src/types.ts create mode 100644 modules/adapter-onebot/tsconfig.json create mode 100644 modules/adapter-qq/package.json create mode 100644 modules/adapter-qq/src/adapter.ts create mode 100644 modules/adapter-qq/src/api.ts create mode 100644 modules/adapter-qq/src/index.ts create mode 100644 modules/adapter-qq/src/test.ats create mode 100644 modules/adapter-qq/src/types.ts create mode 100644 modules/adapter-qq/tsconfig.json create mode 100644 modules/core/locales/zh_CN.json rename modules1/minecraft/package1.json => modules/core/package.json (50%) create mode 100644 modules/core/src/index.ts create mode 100644 modules/core/tsconfig.json create mode 100644 modules/helper/locales/zh_CN.json create mode 100644 modules/helper/package.json create mode 100644 modules/helper/src/index.ts create mode 100644 modules/helper/tsconfig.json create mode 100644 modules/i18n-command/locales/zh_CN.json create mode 100644 modules/i18n-command/package.json create mode 100644 modules/i18n-command/src/index.ts create mode 100644 modules/i18n-command/tsconfig.json create mode 100644 modules/menu/locales/zh_CN.json create mode 100644 modules/menu/package.json create mode 100644 modules/menu/src/index.ts create mode 100644 modules/menu/tsconfig.json delete mode 100644 modules1/access/locales/en_US.json delete mode 100644 modules1/access/locales/ja_JP.json delete mode 100644 modules1/access/locales/zh_CN.json delete mode 100644 modules1/access/locales/zh_TW.json delete mode 100644 modules1/access/package1.json delete mode 100644 modules1/access/src/index.ts delete mode 100644 modules1/access/src/method.ts delete mode 100644 modules1/access/src/type.ts delete mode 100644 modules1/alias/README.md delete mode 100644 modules1/alias/locales/en_US.json delete mode 100644 modules1/alias/locales/ja_JP.json delete mode 100644 modules1/alias/locales/zh_CN.json delete mode 100644 modules1/alias/locales/zh_TW.json delete mode 100644 modules1/alias/manifest.json delete mode 100644 modules1/alias/package1.json delete mode 100644 modules1/alias/src/class/class.cache.ts delete mode 100644 modules1/alias/src/class/class.command.ts delete mode 100644 modules1/alias/src/class/class.content.ts delete mode 100644 modules1/alias/src/class/class.core.ts delete mode 100644 modules1/alias/src/class/class.data.ts delete mode 100644 modules1/alias/src/index.ts delete mode 100644 modules1/alias/src/method.ts delete mode 100644 modules1/alias/src/type.ts delete mode 100644 modules1/daytool/README.md delete mode 100644 modules1/daytool/locales/en_US.json delete mode 100644 modules1/daytool/locales/ja_JP.json delete mode 100644 modules1/daytool/locales/zh_CN.json delete mode 100644 modules1/daytool/locales/zh_TW.json delete mode 100644 modules1/daytool/manifest.json delete mode 100644 modules1/daytool/package1.json delete mode 100644 modules1/daytool/src/config.ts delete mode 100644 modules1/daytool/src/index.ts delete mode 100644 modules1/daytool/src/method.ts delete mode 100644 modules1/minecraft/locales/en_US.json delete mode 100644 modules1/minecraft/locales/ja_JP.json delete mode 100644 modules1/minecraft/locales/zh_CN.json delete mode 100644 modules1/minecraft/src/index.ts delete mode 100644 modules1/minecraft/tsconfig.json delete mode 100644 modules1/querytool/locales/en_US.json delete mode 100644 modules1/querytool/locales/ja_JP.json delete mode 100644 modules1/querytool/locales/zh_CN.json delete mode 100644 modules1/querytool/locales/zh_TW.json delete mode 100644 modules1/querytool/package1.json delete mode 100644 modules1/querytool/src/index.ts delete mode 100644 modules1/sed/locales/en_US.json delete mode 100644 modules1/sed/locales/ja_JP.json delete mode 100644 modules1/sed/locales/zh_CN.json delete mode 100644 modules1/sed/locales/zh_TW.json delete mode 100644 modules1/sed/package1.json delete mode 100644 modules1/sed/src/index.ts delete mode 100644 modules1/status/locales/en_US.json delete mode 100644 modules1/status/locales/ja_JP.json delete mode 100644 modules1/status/locales/zh_CN.json delete mode 100644 modules1/status/locales/zh_TW.json delete mode 100644 modules1/status/package1.json delete mode 100644 modules1/status/src/class/class.cache.ts delete mode 100644 modules1/status/src/class/class.command.ts delete mode 100644 modules1/status/src/class/class.content.ts delete mode 100644 modules1/status/src/class/class.core.ts delete mode 100644 modules1/status/src/class/class.data.ts delete mode 100644 modules1/status/src/index.ts delete mode 100644 modules1/status/src/method.ts delete mode 100644 modules1/status/src/type.ts delete mode 100644 packages/core/CHANGELOG.md delete mode 100644 packages/kotori/CHANGELOG.md delete mode 100644 packages/loader/CHANGELOG.md create mode 100644 scripts/release2.ts diff --git a/.changeset/README.md b/.changeset/README.md deleted file mode 100644 index e5b6d8d6..00000000 --- a/.changeset/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# Changesets - -Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works -with multi-package repos, or single-package repos to help you version and publish your code. You can -find the full documentation for it [in our repository](https://github.com/changesets/changesets) - -We have a quick list of common questions to get you started engaging with this project in -[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) diff --git a/.changeset/config.json b/.changeset/config.json deleted file mode 100644 index 6289a364..00000000 --- a/.changeset/config.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "https://unpkg.com/@changesets/config@3.0.0/schema.json", - "changelog": "@changesets/cli/changelog", - "commit": false, - "fixed": [], - "linked": [], - "access": "public", - "baseBranch": "master", - "updateInternalDependencies": "patch", - "ignore": [ - "kotori-plugin-*", - "@kotori-bot/kotori-plugin-*" - ] -} \ No newline at end of file diff --git a/.gitignore b/.gitignore index ebf17aca..990905b2 100644 --- a/.gitignore +++ b/.gitignore @@ -10,4 +10,5 @@ kotori.dev.yml scripts/*.js -modules2 \ No newline at end of file +modules2 +modules3 \ No newline at end of file diff --git a/modules/adapter-onebot/package.json b/modules/adapter-onebot/package.json new file mode 100644 index 00000000..4d453bd4 --- /dev/null +++ b/modules/adapter-onebot/package.json @@ -0,0 +1,22 @@ +{ + "name": "@kotori-bot/kotori-plugin-adapter-onebot", + "version": "1.1.1", + "description": "Adapter For OneBot (go-cqhttp)", + "main": "lib/index.js", + "scripts": { + "build": "tsc --build" + }, + "license": "GPL-3.0", + "files": [ + "lib", + "README.md" + ], + "author": "Hotaru ", + "peerDependencies": { + "kotori-bot": "workspace:^" + }, + "dependencies": { + "@types/ws": "^8.5.8", + "ws": "^8.14.2" + } +} \ No newline at end of file diff --git a/modules/adapter-onebot/src/adapter.ts b/modules/adapter-onebot/src/adapter.ts new file mode 100644 index 00000000..04c76bfe --- /dev/null +++ b/modules/adapter-onebot/src/adapter.ts @@ -0,0 +1,240 @@ +/* + * @Author: Hotaru biyuehuya@gmail.com + * @Blog: https://hotaru.icu + * @Date: 2023-09-29 14:31:09 + * @LastEditors: Hotaru biyuehuya@gmail.com + * @LastEditTime: 2023-12-02 22:54:59 + */ +import { Adapter, AdapterConfig, Context, EventDataApiBase, EventDataTargetId, Tsu } from 'kotori-bot'; +import WebSocket from 'ws'; +import OneBotApi from './api'; +import WsServer from './services/wsserver'; +import { EventDataType } from './types'; +import OneBotElements from './elements'; + +interface EventDataPoke extends EventDataApiBase<'poke'> { + targetId: EventDataTargetId; + + groupId: EventDataTargetId; +} + +declare module 'kotori-bot' { + interface EventType { + poke: EventDataPoke; + } +} + +export const config = Tsu.Intersection([ + Tsu.Object({ + port: Tsu.Number().int().range(1, 65535), + address: Tsu.String().regexp(/^ws(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w-./?%&=]*)?$/), + retry: Tsu.Number().int().min(1).default(10), + }), + Tsu.Union([ + Tsu.Object({ + mode: Tsu.Literal('ws'), + }), + Tsu.Object({ + mode: Tsu.Literal('ws-reverse'), + }), + ]), +]); + +type OneBotConfig = Tsu.infer & AdapterConfig; + +export class OneBotAdapter extends Adapter { + private readonly info: string; + + public readonly config: OneBotConfig; + + public constructor(ctx: Context, config: OneBotConfig, identity: string) { + super(ctx, config, identity, OneBotApi, OneBotElements); + this.config = config; + this.info = `${this.config.address}:${this.config.port}`; + } + + public handle(data: EventDataType) { + if (data.post_type === 'message' && data.message_type === 'private') { + this.emit('private_msg', { + userId: data.user_id, + messageId: data.message_id, + message: data.message, + sender: { + nickname: data.sender.nickname, + age: data.sender.age, + sex: data.sender.sex, + }, + groupId: data.group_id, + }); + } else if (data.post_type === 'message' && data.message_type === 'group') { + this.emit('group_msg', { + userId: data.user_id, + messageId: data.message_id, + message: data.message, + sender: { + nickname: data.sender.nickname, + age: data.sender.age, + sex: data.sender.sex, + }, + groupId: data.group_id!, + }); + } else if (data.post_type === 'notice' && data.notice_type === 'private_recall') { + this.emit('private_recall', { + userId: data.user_id, + messageId: data.message_id, + }); + } else if (data.post_type === 'notice' && data.notice_type === 'group_recall') { + this.emit('group_recall', { + userId: data.user_id, + messageId: data.message_id, + groupId: data.group_id!, + operatorId: data.operator_id || data.user_id, + }); + } else if (data.post_type === 'request' && data.request_type === 'private') { + this.emit('private_request', { + userId: data.user_id, + }); + } else if (data.post_type === 'request' && data.request_type === 'group') { + this.emit('group_request', { + userId: data.user_id, + groupId: data.group_id!, + operatorId: data.operator_id || data.user_id, + }); + } else if (data.post_type === 'notice' && data.notice_type === 'private_add') { + this.emit('private_add', { + userId: data.user_id, + }); + } else if (data.post_type === 'notice' && data.notice_type === 'group_increase') { + this.emit('group_increase', { + userId: data.user_id, + groupId: data.group_id!, + operatorId: data.operator_id || data.user_id, + }); + } else if (data.post_type === 'notice' && data.notice_type === 'group_decrease') { + this.emit('group_decrease', { + userId: data.user_id, + groupId: data.group_id!, + operatorId: data.operator_id || data.user_id, + }); + } else if (data.post_type === 'notice' && data.notice_type === 'group_admin') { + this.emit('group_admin', { + userId: data.user_id, + groupId: data.group_id!, + operation: data.sub_type === 'set' ? 'set' : 'unset', + }); + } else if (data.post_type === 'notice' && data.notice_type === 'group_ban') { + this.emit('group_ban', { + userId: data.user_id, + groupId: data.group_id!, + operatorId: data.operator_id, + time: data.duration!, + }); + } else if (data.post_type === 'meta_event' && data.meta_event_type === 'heartbeat') { + if (data.status.online) { + this.online(); + if (this.onlineTimerId) clearTimeout(this.onlineTimerId); + } + if (this.selfId === -1 && typeof data.self_id === 'number') { + this.selfId = data.self_id; + // this.avatar = `https://q.qlogo.cn/g?b=qq&s=640&nk=${this.selfId}`; + } + } else if (data.data instanceof Object && typeof data.data.message_id === 'number') { + this.ctx.emit('send', { + api: this.api, + messageId: data.data.message_id, + }); + } else if ( + data.post_type === 'notice' && + data.notice_type === 'notify' && + data.sub_type === 'poke' && + data.target_id + ) { + this.emit('poke', { + userId: data.user_id, + targetId: data.target_id, + groupId: data.group_id!, + }); + } + if (!this.onlineTimerId) this.onlineTimerId = setTimeout(() => this.offline, 50 * 1000); + } + + public start() { + if (this.config.mode === 'ws-reverse') { + this.ctx.emit('connect', { + adapter: this, + normal: true, + info: `start wsserver at ${this.info}`, + onlyStart: true, + }); + } + this.connectWss(); + } + + public stop() { + this.ctx.emit('disconnect', { + adapter: this, + normal: true, + info: this.config.mode === 'ws' ? `disconnect from ${this.info}` : `stop wsserver at ${this.info}`, + }); + this.socket?.close(); + this.offline(); + } + + public send(action: string, params?: object) { + this.socket?.send(JSON.stringify({ action, params })); + } + + private socket: WebSocket | null = null; + + private async connectWss() { + if (this.config.mode === 'ws-reverse') { + const wss = await WsServer(this.config.port); + const { 0: socket } = wss; + this.socket = socket; + this.ctx.emit('connect', { + adapter: this, + normal: true, + info: `client connect to ${this.info}`, + }); + this.socket?.on('close', () => { + this.ctx.emit('disconnect', { + adapter: this, + normal: false, + info: `unexpected client disconnect from ${this.info}`, + }); + wss[1].close(); + this.connectWss(); + }); + } else { + this.ctx.emit('connect', { + adapter: this, + normal: true, + info: `connect server to ${this.info}`, + }); + this.socket = new WebSocket(`${this.info}`); + this.socket.on('close', () => { + this.ctx.emit('disconnect', { + adapter: this, + normal: false, + info: `unexpected disconnect server from ${this.info}, will reconnect in ${this.config.retry} seconds`, + }); + setTimeout(() => { + if (!this.socket) return; + this.socket.close(); + this.ctx.emit('connect', { + adapter: this, + normal: false, + info: `reconnect server to ${this.info}`, + }); + this.connectWss(); + }, this.config.retry * 1000); + }); + } + this.socket.on('message', data => this.handle(JSON.parse(data.toString()))); + } + + /* global NodeJS */ + private onlineTimerId: NodeJS.Timeout | null = null; +} + +export default OneBotAdapter; diff --git a/modules/adapter-onebot/src/api.ts b/modules/adapter-onebot/src/api.ts new file mode 100644 index 00000000..a1ceec30 --- /dev/null +++ b/modules/adapter-onebot/src/api.ts @@ -0,0 +1,128 @@ +/* + * @Author: Hotaru biyuehuya@gmail.com + * @Blog: https://hotaru.icu + * @Date: 2023-09-29 14:31:13 + * @LastEditors: Hotaru biyuehuya@gmail.com + * @LastEditTime: 2023-12-03 16:55:35 + */ +import { Api, MessageRaw } from 'kotori-bot'; + +export class OneBotApi extends Api { + public send_private_msg(message: MessageRaw, userId: number) { + this.adapter.status.lastMsgTime = new Date(); + this.adapter.status.sentMsg += 1; + this.adapter.send('send_private_msg', { user_id: userId, message, auto_escape: false }); + } + + /** + * @description: 发送私聊消息 + * @param {Msg} message 要发送的内容 + * @param {groupId} groupId 群号 + * @return {void} + */ + public send_group_msg(message: MessageRaw, groupId: number) { + this.adapter.status.lastMsgTime = new Date(); + this.adapter.status.sentMsg += 1; + this.adapter.send('send_group_msg', { group_id: groupId, message, auto_escape: false }); + } + + /** + * @description: 撤回消息 + * @param {number} messageId 消息id + * @return {void} + */ + public delete_msg(messageId: number) { + this.adapter.send('delete_msg', { messageId }); + } + + /** + * @description: 设置群名 + * @param {number} groupId 群号 + * @param {string} groupName 新群名 + * @return {void} + */ + public set_group_name(groupId: number, groupName: string) { + this.adapter.send('set_group_name', { group_id: groupId, group_name: groupName }); + } + + /** + * @description: 设置群头像 + * @param {number} groupId 群号 + * @param {string} image 图片路径 + * @return {void} + */ + public set_group_avatar(groupId: number, image: string) { + this.adapter.send('set_group_portrait', { group_id: groupId, file: image, cache: false }); + } + + /** + * @description: 设置群管理员 + * @param {number} groupId 群号 + * @param {number} userId 要设置的管理员的QQ号 + * @param {boolean} enable true为设置,false取消,默认true + * @return {void} + */ + public set_group_admin(groupId: number, userId: number, enable: boolean = true) { + this.adapter.send('set_group_admin', { group_id: groupId, user_id: userId, enable }); + } + + /** + * @description: 设置群名片(群备注) + * @param {number} groupId 群号 + * @param {number} userId 要设置的QQ号 + * @param {string} card 群名片内容,不填或空字符串表示删除群名片 + * @return {void} + */ + public set_group_card(groupId: number, userId: number, card: string) { + this.adapter.send('set_group_card', { group_id: groupId, user_id: userId, card }); + } + + /** + * @description: 群禁言 + * @param {number} groupId 群号 + * @param {number} userId 要禁言的QQ号,不填则为群禁言 + * @param {number} time 禁言时长,单位秒,0表示取消禁言 + * @return {void} + */ + public set_group_ban(groupId: number, userId?: number, time: number = 0) { + if (userId) { + this.adapter.send('set_group_ban', { group_id: groupId, user_id: userId, duration: time }); + } else { + this.adapter.send('set_group_whole_ban', { group_id: groupId, enable: !!time }); + } + } + + /** + * @description: 发送群公告 + * @param {number} groupId 群号 + * @param {string} content 公告内容 + * @param {string} image 图片路径(可选) + * @return {void} + */ + public send_group_notice(groupId: number, content: string, image?: string) { + this.adapter.send('_send_group_notice', { group_id: groupId, content, image }); + } + + /** + * @description: 群组踢人 + * @param {number} groupId 群号 + * @param {number} userId 要踢的QQ号 + * @return {void} + */ + public set_group_kick(groupId: number, userId: number) { + this.adapter.send('set_group_kick', { group_id: groupId, user_id: userId, reject_add_request: false }); + } + + /** + * @description: 退出群组 + * @param {number} groupId 群号 + * @return {void} + */ + public set_group_leave(groupId: number) { + this.adapter.send('set_group_leave', { group_id: groupId, is_dismiss: false }); + } + + /* public extra: ApiExtraValue = { type: 'onebot', image, at, poke }; */ +} + +export default OneBotApi; diff --git a/modules/adapter-onebot/src/elements.ts b/modules/adapter-onebot/src/elements.ts new file mode 100644 index 00000000..5a5763aa --- /dev/null +++ b/modules/adapter-onebot/src/elements.ts @@ -0,0 +1,50 @@ +import { ElementsParam } from 'kotori-bot'; + +/* + + + +function cq(type: MessageCqType, data: obj) { + return `[CQ:${type},data]` +} + +const image = ; +const at = (qq: EventDataTargetId) => `[CQ:at,qq=${qq}]`; +const poke = (qq: EventDataTargetId) => `[CQ:poke,qq=${qq}]`; + + interface OneBotApiExtra { + type: 'onebot'; + image: typeof image; + at: typeof at; + poke: typeof poke; +} + +declare module 'kotori-bot' { + interface ApiExtra { + onebot: OneBotApiExtra; + } +} +*/ + +export const OneBotElements: ElementsParam = { + at(target) { + return `[CQ:at,qq=${target}]`; + }, + image(url) { + return `[CQ:image,file=${url},cache=0]`; + }, + voice(url) { + return `[CQ:voice,file=${url}]`; + }, + video(url) { + return `[CQ:video,file=${url}]`; + }, + face(id) { + return `[CQ:face,id=${id}]`; + }, + file(data) { + return `[CQ:file,file=${data}]`; + }, +}; + +export default OneBotElements; diff --git a/modules/adapter-onebot/src/index.ts b/modules/adapter-onebot/src/index.ts new file mode 100644 index 00000000..0d8642e5 --- /dev/null +++ b/modules/adapter-onebot/src/index.ts @@ -0,0 +1,3 @@ +import { OneBotAdapter } from './adapter'; + +export default OneBotAdapter; diff --git a/modules/adapter-onebot/src/services/wsserver.ts b/modules/adapter-onebot/src/services/wsserver.ts new file mode 100644 index 00000000..3a10037b --- /dev/null +++ b/modules/adapter-onebot/src/services/wsserver.ts @@ -0,0 +1,22 @@ +/* + * @Author: hotaru biyuehuya@gmail.com + * @Blog: https://hotaru.icu + * @Date: 2023-06-24 15:12:55 + * @LastEditors: Hotaru biyuehuya@gmail.com + * @LastEditTime: 2023-10-05 18:49:48 + */ +import WebSocket from 'ws'; + +export const WsServer = async (port: number) => + new Promise<[WebSocket, WebSocket.Server]>((resolve, reject) => { + try { + const WebSocketServer: WebSocket.Server = new WebSocket.Server({ port }); + WebSocketServer.on('connection', ws => { + resolve([ws, WebSocketServer]); + }); + } catch (e) { + reject(e); + } + }); + +export default WsServer; diff --git a/modules/adapter-onebot/src/types.ts b/modules/adapter-onebot/src/types.ts new file mode 100644 index 00000000..6cb0cdcc --- /dev/null +++ b/modules/adapter-onebot/src/types.ts @@ -0,0 +1,522 @@ +/* + * @Author: hotaru biyuehuya@gmail.com + * @Blog: https://hotaru.icu + * @Date: 2023-07-12 15:42:18 + * @LastEditors: Hotaru biyuehuya@gmail.com + * @LastEditTime: 2023-12-02 13:50:39 + */ + +import { EventDataMsgSender } from 'kotori-bot'; + +export interface BotInfo { + self_id: number; + connect: number; + heartbeat: number; + status: EventStatusType; +} + +/* Api */ +export type Msg = string | Message | Message[]; +export type MessageCqType = + | 'face' + | 'record' + | 'video' + | 'at' + | 'share' + | 'music' + | 'image' + | 'reply' + | 'redbag' + | 'poke' + | 'gift' + | 'forward' + | 'node' + | 'xml' + | 'json' + | 'cardimage' + | 'tts'; +export type MessageDataType = + | MessageFace + | MessageRecord + | MessageVideo + | MessageAt + | MessageShare + | MessageMusic + | MessageImage + | MessageReply + | MessageRedbag + | MessagePoke + | MessageGift + | MessageForward + | MessageNode + | MessageXml + | MessageJson + | MessageCardImage + | MessageTts; +export interface Message { + type: MessageCqType; + data: MessageDataType; +} + +export type MessageFaceId = + | 0 + | 1 + | 2 + | 3 + | 4 + | 5 + | 6 + | 7 + | 8 + | 9 + | 10 + | 11 + | 12 + | 13 + | 14 + | 15 + | 16 + | 17 + | 18 + | 19 + | 20 + | 21 + | 22 + | 23 + | 24 + | 25 + | 26 + | 27 + | 28 + | 29 + | 30 + | 31 + | 32 + | 33 + | 34 + | 35 + | 36 + | 37 + | 38 + | 39 + | 40 + | 41 + | 42 + | 43 + | 44 + | 45 + | 46 + | 47 + | 48 + | 49 + | 50 + | 51 + | 52 + | 53 + | 54 + | 55 + | 56 + | 57 + | 58 + | 59 + | 60 + | 61 + | 62 + | 63 + | 64 + | 65 + | 66 + | 67 + | 68 + | 69 + | 70 + | 71 + | 72 + | 73 + | 74 + | 75 + | 76 + | 77 + | 78 + | 79 + | 80 + | 81 + | 82 + | 83 + | 84 + | 85 + | 86 + | 87 + | 88 + | 89 + | 90 + | 91 + | 92 + | 93 + | 94 + | 95 + | 96 + | 97 + | 98 + | 99 + | 100 + | 101 + | 102 + | 103 + | 104 + | 105 + | 106 + | 107 + | 108 + | 109 + | 110 + | 111 + | 112 + | 113 + | 114 + | 115 + | 116 + | 117 + | 118 + | 119 + | 120 + | 121 + | 122 + | 123 + | 124 + | 125 + | 126 + | 127 + | 128 + | 129 + | 130 + | 131 + | 132 + | 133 + | 134 + | 135 + | 136 + | 137 + | 138 + | 139 + | 140 + | 141 + | 142 + | 143 + | 144 + | 145 + | 146 + | 147 + | 148 + | 149 + | 150 + | 151 + | 152 + | 153 + | 154 + | 155 + | 156 + | 157 + | 158 + | 159 + | 160 + | 161 + | 162 + | 163 + | 164 + | 165 + | 166 + | 167 + | 168 + | 169 + | 170 + | 171 + | 172 + | 173 + | 174 + | 175 + | 176 + | 177 + | 178 + | 179 + | 180 + | 181 + | 182 + | 183 + | 184 + | 185 + | 186 + | 187 + | 188 + | 189 + | 190 + | 191 + | 192 + | 193 + | 194 + | 195 + | 196 + | 197 + | 198 + | 199 + | 200 + | 201 + | 202 + | 203 + | 204 + | 205 + | 206 + | 207 + | 208 + | 209 + | 210 + | 211 + | 212 + | 213 + | 214 + | 215 + | 216 + | 217 + | 218 + | 219 + | 220 + | 221; + +export interface MessageFace { + id: MessageFaceId; +} + +export interface MessageRecordFile { + file: string; + magic?: 0 | 1; +} + +export interface MessageRecordUrl { + file: string; + url: string; + cache?: 0 | 1; + proxy?: 0 | 1; + timeout?: number; +} + +export type MessageRecord = MessageRecordFile | MessageRecordUrl; + +export interface MessageVideo { + file: string; + cover?: string; + c?: 1 | 2 | 3; +} + +export interface MessageAt { + qq: 'all' | string | number; + name?: string; +} + +export interface MessageShare { + url: string; + title: string; + content?: string; + image?: string; +} + +export interface MessageMusic { + type: 'qq' | '163' | 'xm'; + id: string; +} + +export interface MessageMusicCustom { + type: 'custom'; + url: string; + audio: string; + title: string; + content?: string; + image?: string; +} + +export interface MessageImage { + file: string; + type?: 'flash' | 'show' | 'normal'; + subType?: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 13; + url?: string; + cache?: 0 | 1; + id?: 40000 | 40001 | 40002 | 40003 | 40004 | 40005; + c?: 1 | 2 | 3; +} + +export interface MessageReply { + id: number; + text: string; + qq?: number; + time?: number; + seq?: number; +} + +export interface MessageRedbag { + title: string; +} + +export interface MessagePoke { + qq: number; +} + +export interface MessageGift { + qq: number; + id: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13; +} + +export interface MessageForward { + id: string; +} + +export interface MessageNodeCustom { + name: string; + uin: number; + content: Message; + seq: Message; +} + +export type MessageNode = + | { + id: number; + } + | MessageNodeCustom; + +export interface MessageXml { + data: string; + resid?: number | '' | null; +} + +export interface MessageJson extends MessageXml { + resid?: number; +} + +export interface MessageCardImage { + file: string; + minwidth: number; + minheight: number; + maxwidth: number; + maxheight: number; + source: string; + icon?: string; +} + +export interface MessageTts { + text: string; +} + +export interface ApiInvitedRequest { + request_id: number; + invitor_uin: number; + invitor_nick: number; + group_id: number; + group_name: string; + checked: boolean; + actor: number; +} + +export interface ApiJoinRequest extends ApiInvitedRequest { + message: string; +} + +/* Event */ +export type EventHandle = () => void; +export type EventPostType = 'message' | 'message_sent' | 'request' | 'notice' | 'meta_event'; +export type EventMessageType = 'private' | 'group'; +export type EventSubType = + | 'private' + | 'normal' + | 'anonymous' + | 'group_self' + | 'group' + | 'notice' + | 'connect' + | 'approve' + | 'add' + | 'invite' + | 'leave' + | 'kick' + | 'kick_me' + | 'set' + | 'unset' + | 'ban' + | 'lift_ban' + | 'poke'; +export type EventRequestType = 'private' | 'group'; +export type EventNoticeType = + | 'group_upload' + | 'group_admin' + | 'group_decrease' + | 'group_increase' + | 'group_ban' + | 'private_add' + | 'group_recall' + | 'private_recall' + | 'group_card' + | 'offline_file' + | 'client_status' + | 'essence' + | 'notify'; +export type EventNoticeNotifySubType = 'honor' | 'poke' | 'lucky_king' | 'title'; +export type EventMetaEventType = 'lifecycle' | 'heartbeat'; + +export type EvenetSenderRoleType = 'owner' | 'admin' | 'member'; + +export interface EventSenderType { + user_id: number; + nickname: string; + sex: EventDataMsgSender['sex']; + age: number; + group_id?: number; + card?: string; + area?: string; + level?: string; + role?: EvenetSenderRoleType; + title?: string; +} + +export interface EventStatusType { + app_initialized: boolean; + app_enabled: boolean; + plugins_good: boolean | null; + app_good: boolean; + online: boolean; + stat: EventStatType; +} + +export interface EventStatType { + packet_received: number; + packet_sent: number; + packet_lost: number; + message_received: number; + message_sent: number; + disconnect_times: number; + lost_times: number; + last_message_time: number; +} + +export type EventDataType = { + post_type: EventPostType; + message_type: EventMessageType; + sub_type: EventSubType; + request_type: EventRequestType; + notice_type: EventNoticeType; + notice_notify_subtype: EventNoticeNotifySubType; + meta_event_type: EventMetaEventType; + time: number; + self_id: number; + message_: Message; + message: string; + message_id: number; + raw_message: string; + user_id: number; + group_id?: number; + operator_id?: number; + target_id?: number; + duration?: number; + sender: EventSenderType; + status: EventStatusType; + font: number | 0; + data?: { + message_id?: number; + }; +}; diff --git a/modules/adapter-onebot/tsconfig.json b/modules/adapter-onebot/tsconfig.json new file mode 100644 index 00000000..fe2bbf83 --- /dev/null +++ b/modules/adapter-onebot/tsconfig.json @@ -0,0 +1,12 @@ +{ + "extends": "../../tsconfig.node.json", + "compilerOptions": { + "rootDir": "./src", + "outDir": "./lib" + }, + "references": [ + { + "path": "../../packages/kotori" + } + ] +} \ No newline at end of file diff --git a/modules/adapter-qq/package.json b/modules/adapter-qq/package.json new file mode 100644 index 00000000..6c08d115 --- /dev/null +++ b/modules/adapter-qq/package.json @@ -0,0 +1,22 @@ +{ + "name": "@kotori-bot/kotori-plugin-adapter-qq", + "version": "1.0.0", + "description": "Adapter For QQ Base On Tencent Api", + "main": "lib/index.js", + "scripts": { + "build": "tsc --build" + }, + "license": "GPL-3.0", + "files": [ + "lib", + "README.md" + ], + "author": "Hotaru ", + "peerDependencies": { + "kotori-bot": "workspace:^" + }, + "dependencies": { + "@types/ws": "^8.5.8", + "ws": "^8.14.2" + } +} \ No newline at end of file diff --git a/modules/adapter-qq/src/adapter.ts b/modules/adapter-qq/src/adapter.ts new file mode 100644 index 00000000..0ee82d66 --- /dev/null +++ b/modules/adapter-qq/src/adapter.ts @@ -0,0 +1,190 @@ +/* + * @Author: Hotaru biyuehuya@gmail.com + * @Blog: https://hotaru.icu + * @Date: 2023-09-29 14:31:09 + * @LastEditors: Hotaru biyuehuya@gmail.com + * @LastEditTime: 2023-12-22 22:37:29 + */ +import { Adapter, AdapterConfig, Context, Tsu, obj } from 'kotori-bot'; +import WebSocket from 'ws'; +import QQApi from './api'; +import { PlayloadData } from './types'; + +const WS_ADDRESS = 'wss://api.sgroup.qq.com/websocket'; +const API_ADDRESS = 'https://api.sgroup.qq.com/v2'; + +export const config = Tsu.Object({ + appid: Tsu.String(), + secret: Tsu.String(), + retry: Tsu.Number().positive().default(10), +}); + +type QQConfig = Tsu.infer & AdapterConfig; + +export class QQAdapter extends Adapter { + private token = ''; + + private seq = 0; + + private msg_seq = 0; + + public readonly config: QQConfig; + + public constructor(ctx: Context, config: QQConfig, identity: string) { + super(ctx, config, identity, QQApi); + this.config = config; + } + + public handle(data: PlayloadData) { + if (data.op === 10) { + this.send('ws', { + op: 2, + d: { + token: `QQBot ${this.token}`, + intents: 1241513984, + shard: [0, 1], + }, + }); + this.ctx.emit('connect', { + adapter: this, + normal: true, + onlyStart: true, + info: `logging in qqbot...`, + }); + } else if (data.t === 'READY') { + this.ctx.emit('connect', { + adapter: this, + normal: true, + info: `logged in qqbot successfully`, + }); + this.heartbeat(); + } else if (data.t === 'GROUP_AT_MESSAGE_CREATE') { + this.emit('group_msg', { + userId: data.d.author.member_openid, + messageId: data.d.id, + extra: data.d.id, + message: data.d.content.trim(), + sender: { + nickname: '', + age: 0, + sex: 'unknown', + }, + groupId: data.d.group_openid, + }); + } else if (data.op === 11) { + this.online(); + // this.offlineCheck(); + } + if (data.s) this.seq = data.s; + // if (!this.onlineTimerId) this.onlineTimerId = setTimeout(() => this.offline, 50 * 1000); + } + + public start() { + this.getToken(); + this.connect(); + } + + public stop() { + this.ctx.emit('disconnect', { + adapter: this, + normal: true, + info: `disconnect from ${WS_ADDRESS}`, + }); + this.socket?.close(); + this.offline(); + } + + public send(action: string, params: object) { + if (action === 'ws') { + this.socket?.send(JSON.stringify(params)); + return undefined; + } + let address = '/'; + let req: obj = {}; + if (action === 'send_group_msg' && 'groupId' in params && 'message' in params && 'id' in params) { + if (!params.message) return null; + this.msg_seq += 1; + address += `groups/${params.groupId}/messages`; + req = { + content: params.message, + msg_type: 0, + msg_id: params.id, + msg_seq: this.msg_seq, + }; + } + return this.ctx.http.post(`${API_ADDRESS}${address}`, req, { + headers: { + Authorization: `QQBot ${this.token}`, + 'X-Union-Appid': this.config.appid, + }, + validateStatus: () => true, + }); + } + + private socket: WebSocket | null = null; + + private async connect() { + this.socket = new WebSocket(WS_ADDRESS); + this.socket.on('close', () => { + this.ctx.emit('disconnect', { + adapter: this, + normal: false, + info: `unexpected disconnect server from ${WS_ADDRESS}, will reconnect in ${this.config.retry} seconds`, + }); + setTimeout(() => { + if (!this.socket) return; + this.socket.close(); + this.ctx.emit('connect', { + adapter: this, + normal: false, + info: `reconnect server to ${WS_ADDRESS}`, + }); + this.start(); + }, this.config.retry * 1000); + }); + this.socket.on('message', data => this.handle(JSON.parse(data.toString()))); + } + + private async getToken() { + const data = (await this.ctx.http.post('https://bots.qq.com/app/getAppAccessToken', { + appId: this.config.appid, + clientSecret: this.config.secret, + })) as any; + if (!data.access_token) { + this.offline(); + + this.ctx.emit('disconnect', { + adapter: this, + normal: false, + info: `got token error!`, + }); + return; + } + this.token = data.access_token; + this.getTokenTimerId = setTimeout( + () => { + if (this.getTokenTimerId) clearInterval(this.getTokenTimerId); + this.getToken(); + }, + (parseInt(data.expires_in, 10) - 30) * 1000, + ); + } + + private async heartbeat() { + this.heartbeatTimerId = setTimeout(() => { + this.send('ws', { + op: 1, + d: this.seq || null, + }); + if (this.heartbeatTimerId) clearInterval(this.heartbeatTimerId); + this.heartbeat(); + }, 7 * 1000); + } + + /* global NodeJS */ + private getTokenTimerId?: NodeJS.Timeout; + + private heartbeatTimerId?: NodeJS.Timeout; +} + +export default QQAdapter; diff --git a/modules/adapter-qq/src/api.ts b/modules/adapter-qq/src/api.ts new file mode 100644 index 00000000..82f6293b --- /dev/null +++ b/modules/adapter-qq/src/api.ts @@ -0,0 +1,10 @@ +import { Api, MessageRaw } from 'kotori-bot'; + +export default class QQApi extends Api { + public send_group_msg(message: MessageRaw, groupId: string, msgId: string) { + const handle = message + .replace(/http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w-./?%&=]*)?/g, '[[hidden:link]]') + .replace(/[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+\.?/g, '[[hidden:domain]]'); + this.adapter.send('send_group_msg', { message: handle, groupId, id: msgId }); + } +} diff --git a/modules/adapter-qq/src/index.ts b/modules/adapter-qq/src/index.ts new file mode 100644 index 00000000..20b0055f --- /dev/null +++ b/modules/adapter-qq/src/index.ts @@ -0,0 +1,3 @@ +import { QQAdapter } from './adapter'; + +export default QQAdapter; diff --git a/modules/adapter-qq/src/test.ats b/modules/adapter-qq/src/test.ats new file mode 100644 index 00000000..f66d4518 --- /dev/null +++ b/modules/adapter-qq/src/test.ats @@ -0,0 +1,76 @@ +import axios from 'axios'; +import WebSocket from 'ws'; + +(async () => { + const verify = ( + await axios.post('https://bots.qq.com/app/getAppAccessToken', { + appId: '102073009', + clientSecret: 'HTSDj140jDSTFn6A', + }) + ).data; + // const address = (await axios.get('')) + console.log(verify); + let a = 0; + const ws = new WebSocket('wss://api.sgroup.qq.com/websocket'); + ws.on('close', data => console.log('closed: ', data)); + ws.on('error', data => console.log('error: ', data)); + ws.on('message', async data => { + const json = JSON.parse(data.toString()); + console.log('message: ', json); + if (json.op === 10) { + ws.send( + JSON.stringify({ + op: 2, + d: { + token: `QQBot ${verify.access_token}`, + intents: 1241513984, + shard: [0, 1], + }, + }), + ); + ws.send(JSON.stringify({ op: 1, d: null })); + } else if ( + json.t === 'GROUP_AT_MESSAGE_CREATE' && + json.d && + typeof json.d.content === 'string' && + (json.d.content as string).includes('t') + ) { + a += 1; + console.log( + ( + await axios.post( + `https://api.sgroup.qq.com/v2/groups/${json.d.group_id}/messages`, + { + content: json.d.content, + msg_type: 0, + msg_id: json.d.id, + msg_seq: a, + }, + { + headers: { + Authorization: `QQBot ${verify.access_token}`, + 'X-Union-Appid': '102073009', + }, + validateStatus: () => true, + }, + ) + ).data, + ); + } + }); + ws.on('open', () => { + console.log('open'); + }); + process.stdin.on('data', data => { + let message = data.toString(); + if (message === '\n' || message === '\r\n') return; + message = message.replace('\r\n', '').replace('\n', ''); + try { + const json = JSON.parse(message); + console.log('input: ', json); + // ws.send(json); + } catch (e) { + console.log('JSON: ', e); + } + }); +})(); diff --git a/modules/adapter-qq/src/types.ts b/modules/adapter-qq/src/types.ts new file mode 100644 index 00000000..b4ededc7 --- /dev/null +++ b/modules/adapter-qq/src/types.ts @@ -0,0 +1,247 @@ +export const enum OpCode { + DISPATCH, + HEARTBEAT, + IDENTIFY, + RESUME = 6, + RECONNECT, + INVALID_SESSION = 9, + HELLO, + HEARTBEAT_ACK, + HTTP_CALLBACK_ACK, +} + +export interface EventDataList { + C2C_MESSAGE_CREATE: C2C_MESSAGE_CREATE; + GROUP_AT_MESSAGE_CREATE: GROUP_AT_MESSAGE_CREATE; + DIRECT_MESSAGE_CREATE: DIRECT_MESSAGE_CREATE; + AT_MESSAGE_CREATE: AT_MESSAGE_CREATE; + MESSAGE_CREATE: MESSAGE_CREATE; + GUILD_CREATE: GUILD_CREATE; + GUILD_UPDATE: GUILD_UPDATE; + GUILD_DELETE: GUILD_DELETE; + CHANNEL_UPDATE: CHANNEL_UPDATE; + CHANNEL_DELETE: CHANNEL_DELETE; + GUILD_MEMBER_ADD: GUILD_MEMBER_ADD; + GUILD_MEMBER_UPDATE: GUILD_MEMBER_UPDATE; + GUILD_MEMBER_REMOVE: GUILD_MEMBER_REMOVE; + GROUP_ADD_ROBOT: GROUP_ADD_ROBOT; + GROUP_DEL_ROBOT: GROUP_DEL_ROBOT; + GROUP_MSG_REJECT: GROUP_MSG_REJECT; + GROUP_MSG_RECEIVE: GROUP_MSG_RECEIVE; + FRIEND_ADD: FRIEND_ADD; + FRIEND_DEL: FRIEND_DEL; + C2C_MSG_REJECT: C2C_MSG_REJECT; + C2C_MSG_RECEIVE: C2C_MSG_RECEIVE; + READY: Ready; +} + +export interface Payload { + op: OpCode; + d: EventDataList[T]; + s: number; + t: T; +} + +export type PayloadList = { + [K in keyof EventDataList]: Payload; +}; + +export type PlayloadData = PayloadList[keyof PayloadList]; + +/* Object */ + +interface Message { + id: string; + channel_id: string; + guild: string; + content: string; + timestamp: string; + edited_timestamp: string; + mention_everyone: string; + author: User; + attachments: MessageAttachment[]; + embeds: MessageEmbed[]; + mentions: User[]; + member: ClassMemberDecoratorContext; + ark: MessageArk; + seq: number; + seq_in_channel: string; + message_reference: string; +} + +interface MessageEmbed { + title: string; + prompt: string; + thumbnail: MessageEmbedThumbnail; + fields: MessageEmbedField[]; +} + +interface MessageEmbedThumbnail { + url: string; +} + +interface MessageEmbedField { + name: string; +} + +type MessageAttachment = MessageEmbedThumbnail; + +interface MessageArk { + template_id: number; + kv: MessageArkKv[]; +} + +interface MessageArkKv { + key: string; + value: string; + obj: MessageArkObj[]; +} + +interface MessageArkObj { + obj_kv: MessageArkObjKv[]; +} + +interface MessageArkObjKv { + key: string; + value: string; +} + +export interface MessageReference { + message_id: string; + ignore_get_message_error: boolean; +} +/* +interface MessageMarkdownParams { + key: string; + values: string[]; +} + +interface MessageDelete { + message: Message; + op_user: User; +} + +interface MessageAudited { + audit_id: string; + message_id: string; + guild_id: string; + channel_id: string; + audit_time: number; + create_time: number; + seq_in_channel: string; +} + +interface Member { + user: User; + nick: string; + roles: string[]; + joined_at: number; +} + +interface MemberWithGuildID extends Member { + guild_id: string; +} */ + +interface User { + id: string; + username: string; + avatar: string; + bot: boolean; + union_openid?: string; + union_user_account?: string; +} + +/* Events */ + +interface Ready { + version: number; + session_id: string; + user: { + id: string; + username: string; + bot: boolean; + }; + shard: number[]; +} + +interface C2C_MESSAGE_CREATE { + author: { + user_openid: string; + }; + content: string; + id: string; + timestamp: string; +} + +interface GROUP_AT_MESSAGE_CREATE { + author: { + member_openid: string; + }; + content: string; + group_openid: string; + id: string; + timestamp: string; +} + +type DIRECT_MESSAGE_CREATE = Message; +type AT_MESSAGE_CREATE = Message; +type MESSAGE_CREATE = Message; + +interface GUILD_CREATE { + description: string; + icon: string; + id: string; + joined_at: string; + max_members: number; + member_count: number; + name: string; + op_user_id: string; + owner_id: string; +} + +type GUILD_UPDATE = GUILD_CREATE; +type GUILD_DELETE = GUILD_CREATE; + +interface CHANNEL_CREATE { + guild_id: string; + id: string; + name: string; + op_user_id: string; + owner_id: string; + sub_type: number; + type: number; +} + +type CHANNEL_UPDATE = CHANNEL_CREATE; +type CHANNEL_DELETE = CHANNEL_CREATE; + +interface GUILD_MEMBER_ADD { + guild_id: string; + joined_at: string; + nick: string; + op_user_id: string; + roles: string[]; + user: User; +} + +type GUILD_MEMBER_UPDATE = GUILD_MEMBER_ADD; +type GUILD_MEMBER_REMOVE = GUILD_MEMBER_ADD; + +interface GROUP_ADD_ROBOT { + group_openid: string; + op_member_openid: string; + timestamp: number; +} + +type GROUP_DEL_ROBOT = GROUP_ADD_ROBOT; +type GROUP_MSG_REJECT = GROUP_ADD_ROBOT; +type GROUP_MSG_RECEIVE = GROUP_ADD_ROBOT; + +interface FRIEND_ADD { + openid: string; + timestamp: number; +} + +type FRIEND_DEL = FRIEND_ADD; +type C2C_MSG_REJECT = FRIEND_ADD; +type C2C_MSG_RECEIVE = FRIEND_ADD; diff --git a/modules/adapter-qq/tsconfig.json b/modules/adapter-qq/tsconfig.json new file mode 100644 index 00000000..fe2bbf83 --- /dev/null +++ b/modules/adapter-qq/tsconfig.json @@ -0,0 +1,12 @@ +{ + "extends": "../../tsconfig.node.json", + "compilerOptions": { + "rootDir": "./src", + "outDir": "./lib" + }, + "references": [ + { + "path": "../../packages/kotori" + } + ] +} \ No newline at end of file diff --git a/modules/core/locales/zh_CN.json b/modules/core/locales/zh_CN.json new file mode 100644 index 00000000..83aa359d --- /dev/null +++ b/modules/core/locales/zh_CN.json @@ -0,0 +1,18 @@ +{ + "core.descr.core": "查看实例统计信息", + "core.descr.bot": "查看当前 bot 信息与运行状态", + "core.descr.bots": "查看所有 bot 信息与运行状态", + "core.descr.version": "查看版本信息", + "core.descr.about": "帮助信息", + "core.descr.update": "检查更新", + "core.msg.bot": "ID:%identity%\n语言:%lang%\n平台:%platform%\nid:%self_id%\n连接时间: %create_time%\n接收消息数量:%received_msg%\n发送消息数量:%sent_msg%\n实例下线次数:%offline_times%\n最后消息时间:%last_msg_time%", + "core.msg.core": "全局语言:%lang%\n实例目录:%root%\n运行模式:%mode%\n模块数量:%modules%\n适配器数量:%adapters%\nbot 实例数量:%bots%\n中间件数量:%midwares%\n指令数量:%commands%\n正则数量:%regexps%", + "core.msg.bots": "实例列表:%list%", + "core.msg.bots.list": "\n----------\nID:%identity%\n语言:%lang%\n平台:%platform%\n状态:%status%", + "core.msg.version": "Kotori 版本:%version%\n协议:%license%\nNodeJS 版本:%node_version%", + "core.msg.about": "kotori 是一个跨平台、解耦合、现代化于一体的 ChatBot 聊天机器人 框架,运行于 NodeJS 环境并使用 TypeScript 语言开发。\n官网:kotori.js.org", + "core.msg.update": "当前版本:%version%\n%content%", + "core.msg.update.yes": "当前为最新版本!", + "core.msg.update.no": "检测到有更新!\n最新版本: %version%\n请前往Github仓库获取最新版本:%repo%", + "core.msg.update.fail": "获取更新失败!" +} \ No newline at end of file diff --git a/modules1/minecraft/package1.json b/modules/core/package.json similarity index 50% rename from modules1/minecraft/package1.json rename to modules/core/package.json index 916a2996..aa8f5dee 100644 --- a/modules1/minecraft/package1.json +++ b/modules/core/package.json @@ -1,8 +1,11 @@ { - "name": "kotori-plugin-minecraft", - "version": "1.1.1", - "description": "Plugin Of For Minecraft!", - "main": "src/index.ts", + "name": "@kotori-bot/kotori-plugin-core", + "version": "1.1.0", + "description": "core plugin", + "main": "lib/index.js", + "scripts": { + "build": "tsc --build" + }, "license": "GPL-3.0", "files": [ "lib", diff --git a/modules/core/src/index.ts b/modules/core/src/index.ts new file mode 100644 index 00000000..bffc27d6 --- /dev/null +++ b/modules/core/src/index.ts @@ -0,0 +1,95 @@ +/* + * @Author: hotaru biyuehuya@gmail.com + * @Blog: https://hotaru.icu + * @Date: 2023-07-11 14:18:27 + * @LastEditors: Hotaru biyuehuya@gmail.com + * @LastEditTime: 2023-12-24 22:23:59 + */ + +import Kotori, { Tsu, formatTime, stringTemp } from 'kotori-bot'; +import { resolve } from 'path'; + +Kotori.i18n.use(resolve(__dirname, '../locales')); + +Kotori.command('core - core.descr.core').action((_, events) => { + const { config, baseDir, options, internal } = events.api.adapter.ctx; + let botsLength = 0; + Object.values(internal.getBots()).forEach(bots => + bots.forEach(() => { + botsLength += 1; + }), + ); + return [ + 'core.msg.core', + { + lang: config.global.lang, + root: baseDir.root, + mode: options.env, + modules: internal.getModules().length, + adapters: Object.values(internal.getAdapters()).length, + bots: botsLength, + midwares: internal.getMidwares().length, + commands: internal.getCommands().length, + regexps: internal.getRegexps().length, + }, + ]; +}); + +Kotori.command('bot - core.descr.bot').action((_, events) => { + const { identity, platform, selfId, config, status } = events.api.adapter; + return [ + 'core.msg.bot', + { + identity, + lang: config.lang, + platform, + self_id: selfId, + create_time: formatTime(status.createTime), + last_msg_time: formatTime(status.lastMsgTime), + received_msg: status.receivedMsg, + sent_msg: status.sentMsg, + offline_times: status.offlineTimes, + }, + ]; +}); + +Kotori.command('bots - core.descr.bots').action((_, events) => { + let list = ''; + Object.values(events.api.adapter.ctx.internal.getBots()).forEach(bots => + bots.forEach(bot => { + const { identity, platform, config, status } = bot.adapter; + list += stringTemp(events.locale('core.msg.bots.list'), { + identity, + lang: config.lang, + platform, + status: status.value, + }); + }), + ); + return ['core.msg.bots', { list }]; +}); + +Kotori.command('version - core.descr.version').action((_, events) => { + const { version, license } = events.api.adapter.ctx.package; + return ['core.msg.version', { version, license, node_version: process.version }]; +}); + +Kotori.command('about - core.descr.about').action(() => 'core.msg.about'); + +Kotori.command('update - core.descr.update').action(async (_, events) => { + const { version } = events.api.adapter.ctx.package; + let content: string; + const res = await Kotori.http.get( + 'https://hotaru.icu/api/agent/?url=https://raw.githubusercontent.com/kotorijs/kotori/master/packages/kotori/package.json', + ); + if (!res || !Tsu.Object({ version: Tsu.String() }).check(res)) { + content = events.locale('core.msg.update.fail'); + } else if (version === res.version) { + content = events.locale('core.msg.update.yes'); + } else { + content = stringTemp(events.locale('core.msg.update.fail'), { + repo: 'https://github.com/kotorijs/kotori', + }); + } + return ['core.msg.update', { version, content }]; +}); diff --git a/modules/core/tsconfig.json b/modules/core/tsconfig.json new file mode 100644 index 00000000..fe2bbf83 --- /dev/null +++ b/modules/core/tsconfig.json @@ -0,0 +1,12 @@ +{ + "extends": "../../tsconfig.node.json", + "compilerOptions": { + "rootDir": "./src", + "outDir": "./lib" + }, + "references": [ + { + "path": "../../packages/kotori" + } + ] +} \ No newline at end of file diff --git a/modules/helper/locales/zh_CN.json b/modules/helper/locales/zh_CN.json new file mode 100644 index 00000000..81a5c18f --- /dev/null +++ b/modules/helper/locales/zh_CN.json @@ -0,0 +1,17 @@ +{ + "helper.descr.help": "查看指令帮助信息", + "helper.msg.help": "查询到以下相关指令:%content%", + "helper.msg.descr.fail": "未查询到相关指令", + "helper.msg.descr.command": "\n%root%%args%%description%%options%%help%%alias%", + "helper.template.help": "\n %content%", + "helper.template.alias": "\n 别名:%content%", + "helper.template.alias.delimiter": ",", + "helper.template.arg.required": " <%name%%type%%default%>", + "helper.template.arg.optional": " [%name%%type%%default%]", + "helper.template.arg.type": ":%content%", + "helper.template.default": "=%content%", + "helper.template.description": " - %content%", + "helper.template.options": "\n 参数说明:%content%", + "helper.template.option": "\n -%name%%type%%default%%description%", + "helper.template.option.type": " 类型:%type%" +} \ No newline at end of file diff --git a/modules/helper/package.json b/modules/helper/package.json new file mode 100644 index 00000000..4843ee6b --- /dev/null +++ b/modules/helper/package.json @@ -0,0 +1,18 @@ +{ + "name": "@kotori-bot/kotori-plugin-helper", + "version": "1.1.0", + "description": "helper plugin", + "main": "lib/index.js", + "scripts": { + "build": "tsc --build" + }, + "license": "GPL-3.0", + "files": [ + "lib", + "README.md" + ], + "author": "Hotaru ", + "peerDependencies": { + "kotori-bot": "workspace:^" + } +} \ No newline at end of file diff --git a/modules/helper/src/index.ts b/modules/helper/src/index.ts new file mode 100644 index 00000000..d606fb98 --- /dev/null +++ b/modules/helper/src/index.ts @@ -0,0 +1,87 @@ +/* + * @Author: hotaru biyuehuya@gmail.com + * @Blog: https://hotaru.icu + * @Date: 2023-07-11 14:18:27 + * @LastEditors: Hotaru biyuehuya@gmail.com + * @LastEditTime: 2023-12-03 16:50:16 + */ + +import { Context, stringTemp } from 'kotori-bot'; + +export const lang = [__dirname, '../locales']; + +export function main(ctx: Context) { + /* rest paramter */ + ctx.command('help [command] - helper.descr.help').action((data, events) => { + const commandStack = ctx.internal.getCommands(); + const filterResult = data.args[0] + ? commandStack.filter( + command => + (data.args[0] as string).startsWith(command.data.root) || + command.data.alias.filter(alias => (data.args[0] as string).startsWith(alias)).length > 0, + ) + : commandStack; + if (filterResult.length <= 0) return 'helper.msg.descr.fail'; + let commands = ''; + const temp: typeof stringTemp = (template, args) => stringTemp(events.locale(template), args); + + filterResult.forEach(command => { + const cmd = command.data; + const alias = + cmd.alias.length > 0 + ? temp('helper.template.alias', { + content: cmd.alias.join(events.locale('helper.template.alias.delimiter')), + }) + : ''; + let args = ''; + let options = ''; + cmd.args.forEach(arg => { + let defaultValue = ''; + if ('default' in arg) { + const valueType = typeof arg.default; + if (valueType === 'string' || valueType === 'number') { + defaultValue = temp('helper.template.default', { content: arg.default }); + } + } + args += temp(`helper.template.arg.${arg.optional ? 'optional' : 'required'}`, { + name: arg.name, + type: arg.type === 'string' ? '' : temp('helper.template.arg.type', { content: arg.type }), + default: defaultValue, + }); + }); + cmd.options.forEach(option => { + let defaultValue = ''; + if ('default' in option) { + const valueType = typeof option.default; + if (valueType === 'string' || valueType === 'number') { + defaultValue = temp('helper.template.default', { content: option.default }); + } + } + options += temp('helper.template.option', { + name: option.realname, + type: option.type === 'string' ? '' : temp('helper.template.option.type', { content: option.type }), + default: defaultValue, + + description: option.description + ? temp('helper.template.description', { content: events.locale(option.description) }) + : '', + }); + }); + if (cmd.options.length > 0) options = temp('helper.template.options', { content: options }); + + commands += temp('helper.msg.descr.command', { + root: `${events.api.adapter.config['command-prefix']}${cmd.root}`, + args, + description: cmd.description + ? temp('helper.template.description', { content: events.locale(cmd.description) }) + : '', + options, + help: cmd.help ? temp('helper.template.help', { content: events.locale(cmd.help) }) : '', + alias, + }); + }); + return ['helper.msg.help', { content: commands }]; + }); +} + +export default main; diff --git a/modules/helper/tsconfig.json b/modules/helper/tsconfig.json new file mode 100644 index 00000000..fe2bbf83 --- /dev/null +++ b/modules/helper/tsconfig.json @@ -0,0 +1,12 @@ +{ + "extends": "../../tsconfig.node.json", + "compilerOptions": { + "rootDir": "./src", + "outDir": "./lib" + }, + "references": [ + { + "path": "../../packages/kotori" + } + ] +} \ No newline at end of file diff --git a/modules/i18n-command/locales/zh_CN.json b/modules/i18n-command/locales/zh_CN.json new file mode 100644 index 00000000..012286cd --- /dev/null +++ b/modules/i18n-command/locales/zh_CN.json @@ -0,0 +1,20 @@ +{ + "corei18n.template.args_error": "参数 “%target%” 的类型错误,期望类型:%expected% 实际类型:%reality%", + "corei18n.template.args_few": "输入参数过少请增加参数,期望数量:%expected% 实际数量:%reality%", + "corei18n.template.args_many": "输入参数过多请减少参数,期望数量:%expected% 实际数量:%reality%", + "corei18n.template.option_error": "选项 “%target%” 的类型错误,期望类型:%expected% 实际类型:%reality%", + "corei18n.template.syntax": "指令语法错误,意外地在 %index% 处字符 “%char%”", + "corei18n.template.unknown": "未知的指令 “%input%” ,请检查指令是否输入正确", + "corei18n.template.error": "意外的错误!\n捕获信息:%error%", + "corei18n.template.res_error": "返回数据错误!请联系管理员\n源数据:%res%", + "corei18n.template.num_error": "序号错误,请重新发送", + "corei18n.template.num_choose": "再次发送指令并传入参数【序号】以选择对应内容\n示例:/指令 内容 2", + "corei18n.template.no_access_manger": "该指令仅【群管理员】与【群BOT管理员】可执行!", + "corei18n.template.no_access_admin": "该指令仅【BOT超级管理员】可执行!", + "corei18n.template.disable": "该功能目前未启用,请联系管理员开启", + "corei18n.template.exists": "目标参数【%target%】已存在,请勿重复执行", + "corei18n.template.no_exists": "目标参数【%target%】不存在,请确认后,重新发送", + "----------------------": "----------", + "corei18n.template.empty": "无", + "corei18n.template.unsupported": "当前平台不支持该消息元素" +} \ No newline at end of file diff --git a/modules/i18n-command/package.json b/modules/i18n-command/package.json new file mode 100644 index 00000000..c57c0d13 --- /dev/null +++ b/modules/i18n-command/package.json @@ -0,0 +1,18 @@ +{ + "name": "@kotori-bot/kotori-plugin-i18n-command", + "version": "1.1.0", + "description": "i18n for command", + "main": "lib/index.js", + "scripts": { + "build": "tsc --build" + }, + "license": "GPL-3.0", + "files": [ + "lib", + "README.md" + ], + "author": "Hotaru ", + "peerDependencies": { + "kotori-bot": "workspace:^" + } +} \ No newline at end of file diff --git a/modules/i18n-command/src/index.ts b/modules/i18n-command/src/index.ts new file mode 100644 index 00000000..c4baed15 --- /dev/null +++ b/modules/i18n-command/src/index.ts @@ -0,0 +1,98 @@ +import { Context, TsuError } from 'kotori-bot'; + +declare module 'kotori-bot' { + interface CommandResult { + res_error: { error: TsuError }; + num_error: object; + num_choose: object; + no_access_manger: object; + no_access_admin: object; + disable: object; + exists: { target: string }; + no_exists: CommandResult['exists']; + error: { error: unknown }; + } +} + +export const lang = [__dirname, '../locales']; + +export function main(ctx: Context) { + ctx.on('parse', session => { + const { result } = session; + if (result.type === 'parsed') return; + session.cancel(); + const { quick } = session.event; + switch (result.type) { + case 'arg_error': + quick(['corei18n.template.args_error', result]); + break; + case 'arg_few': + quick(['corei18n.template.args_few', result]); + break; + case 'arg_many': + quick(['corei18n.template.args_many', result]); + break; + case 'option_error': + quick(['corei18n.template.option_error', result]); + break; + case 'syntax': + quick(['corei18n.template.syntax', result]); + break; + case 'unknown': + quick(['corei18n.template.unknown', result]); + break; + default: + } + }); + + ctx.on('command', session => { + const { result } = session; + if (result.type === 'success') return; + const { quick } = session.event; + switch (result.type) { + case 'res_error': + quick(['corei18n.template.res_error', { content: result.error.message }]); + break; + case 'num_error': + quick(['corei18n.template.num_error', result]); + break; + case 'no_access_manger': + quick('corei18n.template.no_access_manger'); + break; + case 'no_access_admin': + quick('corei18n.template.no_access_admin'); + break; + case 'num_choose': + quick('corei18n.template.num_choose'); + break; + case 'disable': + quick('corei18n.template.disable'); + break; + case 'exists': + quick(['corei18n.template.exists', result]); + break; + case 'no_exists': + quick(['corei18n.template.no_exists', result]); + break; + case 'error': + ctx.logger.error(result.error); + if (result.error instanceof TsuError) { + quick(['corei18n.template.res_error', { content: result.error.message }]); + return; + } + if (result.error instanceof Error) { + quick(['corei18n.template.error', { error: `${result.error.name} ${result.error.message}` }]); + return; + } + if (typeof result.error === 'object') { + quick(['corei18n.template.error', { error: JSON.stringify(result.error) }]); + return; + } + quick(['corei18n.template.error', { error: result.error as string }]); + break; + default: + } + }); +} + +export default main; diff --git a/modules/i18n-command/tsconfig.json b/modules/i18n-command/tsconfig.json new file mode 100644 index 00000000..fe2bbf83 --- /dev/null +++ b/modules/i18n-command/tsconfig.json @@ -0,0 +1,12 @@ +{ + "extends": "../../tsconfig.node.json", + "compilerOptions": { + "rootDir": "./src", + "outDir": "./lib" + }, + "references": [ + { + "path": "../../packages/kotori" + } + ] +} \ No newline at end of file diff --git a/modules/menu/locales/zh_CN.json b/modules/menu/locales/zh_CN.json new file mode 100644 index 00000000..9a95e094 --- /dev/null +++ b/modules/menu/locales/zh_CN.json @@ -0,0 +1,3 @@ +{ + "menu.descr.menu": "查看BOT菜单" +} \ No newline at end of file diff --git a/modules/menu/package.json b/modules/menu/package.json new file mode 100644 index 00000000..a4be012f --- /dev/null +++ b/modules/menu/package.json @@ -0,0 +1,18 @@ +{ + "name": "@kotori-bot/kotori-plugin-menu", + "version": "1.0.0", + "description": "menu plugin", + "main": "lib/index.js", + "scripts": { + "build": "tsc --build" + }, + "license": "GPL-3.0", + "files": [ + "lib", + "README.md" + ], + "author": "Hotaru ", + "peerDependencies": { + "kotori-bot": "workspace:^" + } +} \ No newline at end of file diff --git a/modules/menu/src/index.ts b/modules/menu/src/index.ts new file mode 100644 index 00000000..12200460 --- /dev/null +++ b/modules/menu/src/index.ts @@ -0,0 +1,28 @@ +/* + * @Author: hotaru biyuehuya@gmail.com + * @Blog: https://hotaru.icu + * @Date: 2023-07-11 14:18:27 + * @LastEditors: Hotaru biyuehuya@gmail.com + * @LastEditTime: 2023-12-24 22:33:14 + */ + +import { Context, EventDataMsg, MessageQuick, Tsu } from 'kotori-bot'; + +export const config = Tsu.Object({ + alias: Tsu.String().optional(), + keywords: Tsu.Array(Tsu.String()).default(['菜单', '功能']), + content: Tsu.String(), +}); + +export const lang = [__dirname, '../locales']; + +export function main(ctx: Context, conf: Tsu.infer) { + const handle = (session: EventDataMsg): MessageQuick => [conf.content, { at: session.el.at(session.userId) }]; + + const cmd = ctx.command('menu - menu.descr.menu').action((_, session) => handle(session)); + if (conf.alias) cmd.alias(conf.alias); + + conf.keywords.forEach(element => { + ctx.regexp(new RegExp(element), (_, session) => handle(session)); + }); +} diff --git a/modules/menu/tsconfig.json b/modules/menu/tsconfig.json new file mode 100644 index 00000000..fe2bbf83 --- /dev/null +++ b/modules/menu/tsconfig.json @@ -0,0 +1,12 @@ +{ + "extends": "../../tsconfig.node.json", + "compilerOptions": { + "rootDir": "./src", + "outDir": "./lib" + }, + "references": [ + { + "path": "../../packages/kotori" + } + ] +} \ No newline at end of file diff --git a/modules1/access/locales/en_US.json b/modules1/access/locales/en_US.json deleted file mode 100644 index 51f0b0e4..00000000 --- a/modules1/access/locales/en_US.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "access.descr.access.query": "Query group bot admins", - "access.descr.access.add": "Add group bot admin", - "access.descr.access.del": "Remove group bot admin", - "access.msg.access.query": "Current group admins:\n%content%\b ", - "access.msg.access.list": "%content%,", - "access.msg.access.add": "Added [%target%] as current group admin", - "access.msg.access.del": "Removed [%target%] from current group admins" -} \ No newline at end of file diff --git a/modules1/access/locales/ja_JP.json b/modules1/access/locales/ja_JP.json deleted file mode 100644 index b5dd0e34..00000000 --- a/modules1/access/locales/ja_JP.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "access.descr.access.query": "グループBOT管理者を照会する", - "access.descr.access.add": "グループBOT管理者を追加する", - "access.descr.access.del": "グループBOT管理者を削除する", - "access.msg.access.query": "現在のグループ管理者一覧:\n%content%\b", - "access.msg.access.list": "%content%、", - "access.msg.access.add": "[%target%]を現在のグループ管理者に追加しました", - "access.msg.access.del": "[%target%]を現在のグループ管理者から削除しました" -} \ No newline at end of file diff --git a/modules1/access/locales/zh_CN.json b/modules1/access/locales/zh_CN.json deleted file mode 100644 index 75cfb578..00000000 --- a/modules1/access/locales/zh_CN.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "access.descr.access.query": "查询群BOT管理员", - "access.descr.access.add": "添加群BOT管理员", - "access.descr.access.del": "删除群BOT管理员", - "access.msg.access.query": "当前群管理员列表:\n%content%\b ", - "access.msg.access.list": "%content%,", - "access.msg.access.add": "已添加[%target%]至当前群管理员", - "access.msg.access.del": "已删除[%target%]从当前群管理员" -} \ No newline at end of file diff --git a/modules1/access/locales/zh_TW.json b/modules1/access/locales/zh_TW.json deleted file mode 100644 index 1ab2f47a..00000000 --- a/modules1/access/locales/zh_TW.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "access.descr.access.query": "查詢群BOT管理員", - "access.descr.access.add": "添加群BOT管理員", - "access.descr.access.del": "刪除群BOT管理員", - "access.msg.access.query": "當前群管理員列表:\n%content%\b ", - "access.msg.access.list": "%content%,", - "access.msg.access.add": "已添加[%target%]至當前群管理員", - "access.msg.access.del": "已刪除[%target%]從當前群管理員" -} \ No newline at end of file diff --git a/modules1/access/package1.json b/modules1/access/package1.json deleted file mode 100644 index f8c24bf1..00000000 --- a/modules1/access/package1.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "@kotori-bot/kotori-plugin-access", - "version": "1.0.0", - "description": "access plugin", - "main": "src/index.ts", - "license": "GPL-3.0", - "author": "Hotaru ", - "peerDependencies": { - "kotori-bot": "workspace:^" - } -} \ No newline at end of file diff --git a/modules1/access/src/index.ts b/modules1/access/src/index.ts deleted file mode 100644 index d01b374d..00000000 --- a/modules1/access/src/index.ts +++ /dev/null @@ -1,46 +0,0 @@ -import path from 'path'; -import { Core, getQq, temp } from 'plugins/kotori-core'; -import { ACCESS, BOT_RESULT, SCOPE } from 'plugins/kotori-core/type'; -import Content from 'plugins/kotori-core/class/class.content'; -import { loadConfigP, saveConfigP } from 'plugins/kotori-core/method'; -import { Api, Const, Event, EventDataType, Locale } from '@/tools'; -import SDK from '@/utils/class.sdk'; -import config from './config'; -import { CACHE_MSG_TIMES, controlParams } from './method'; - -Locale.register(path.resolve(__dirname)); - -Core.cmd('access', (send, data) => { - const message = controlParams(`${data.group_id}\\accessList.json`, [ - 'access.msg.access.query', - 'access.msg.access.add', - 'access.msg.access.del', - 'access.msg.access.list', - ]); - send(message); -}) - .menuId('adminMange') - .access(ACCESS.ADMIN) - .params({ - query: { - help: 'access.descr.access.query', - }, - add: { - help: 'access.descr.access.add', - args: [ - { - must: true, - name: 'qq/at', - }, - ], - }, - del: { - help: 'access.descr.access.del', - args: [ - { - must: true, - name: 'qq/at', - }, - ], - }, - }); diff --git a/modules1/access/src/method.ts b/modules1/access/src/method.ts deleted file mode 100644 index 68fe313b..00000000 --- a/modules1/access/src/method.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { getQq, loadConfigP, saveConfigP, temp } from 'plugins/kotori-core/method'; -import { BOT_RESULT } from 'plugins/kotori-core/type'; -import { Core } from 'plugins/kotori-core'; -import { FuncStringProcessStr, obj } from '@/tools'; -import CONTROL_PARAMS from './type'; - -export const CACHE_MSG_TIMES: obj<{ time: number; times: number }> = {}; - -export const controlParams(filePath: string, msg: [string, string, string, string], isString: boolean = false) { - let message = ''; - let list = loadConfigP(filePath) as FuncStringProcessStr[]; - const target = isString ? Core.args[2] : getQq(Core.args[2]); - const check() { - if (!Core.args[2]) { - message = BOT_RESULT.ARGS_EMPTY; - return false; - } - if (!target) { - message = BOT_RESULT.ARGS_ERROR; - return false; - } - return true; - }; - - let listRaw = ''; - switch (Core.args[1]) { - case CONTROL_PARAMS.QUERY: - list.forEach(content => { - listRaw += temp(msg[3], { - content, - }); - }); - message = temp(msg[0], { - content: listRaw || BOT_RESULT.EMPTY, - }); - break; - case CONTROL_PARAMS.ADD: - if (!check()) break; - if (list.includes(target!)) { - message = BOT_RESULT.EXIST; - break; - } - list.push(target!); - message = temp(msg[1], { target: target! }); - saveConfigP(filePath, list); - break; - case CONTROL_PARAMS.DEL: - if (!check()) break; - if (!list.includes(target!)) { - message = BOT_RESULT.NO_EXIST; - break; - } - list = list.filter(item => item !== target); - message = temp(msg[2], { target: target! }); - saveConfigP(filePath, list); - break; - default: - break; - } - saveConfigP(filePath, list); - return message; -}; diff --git a/modules1/access/src/type.ts b/modules1/access/src/type.ts deleted file mode 100644 index 947adf95..00000000 --- a/modules1/access/src/type.ts +++ /dev/null @@ -1,7 +0,0 @@ -export const enum CONTROL_PARAMS { - QUERY = 'query', - ADD = 'add', - DEL = 'del', -} - -export default CONTROL_PARAMS; diff --git a/modules1/alias/README.md b/modules1/alias/README.md deleted file mode 100644 index adf7ff8a..00000000 --- a/modules1/alias/README.md +++ /dev/null @@ -1,41 +0,0 @@ -# kotori-core - -KotoriBot's Core Plugin,provide handle message event to normative command - -**Version:** 1.0.0 -**Author:** himeno -**License:** GPL-3.0 - -## List of command - -- /menu - Main menu -- /cores - Core functions -- /days - Daily tools -- /querys - Query tools -- /funs - Entertainment system -- /imgs - Random images -- /other - Other functions -- /alias query - Query all command aliases^ -- /alias add <...command> - Add command alias, supports parameters, no need for slash^ -- /alias del - Delete command alias^ -- /system 0 - Restart Go-cqHttp^^ -- /system 1 - Restart Signature Server and Go-cqHttp^^ -- /locale list - View bot's list of support languages^ -- /locale set - Switching Bot Language^ -- /core - View kotori-core core plugin statistics -- /help - View command help information, no need for slash/ -- /view - View Kotori-bot configuration -- /plugin query - View specified or all plugin information -- /plugin ban - Disable specified plugin -- /plugin unban - Enable specified plugin -- /bot - View BOT information and running status -- /status - View server running status -- /about - Help information -- /update - Check for updates - -## Lang Support - -- ja_JP -- en_US -- zh_TW -- zh_CN diff --git a/modules1/alias/locales/en_US.json b/modules1/alias/locales/en_US.json deleted file mode 100644 index f48bd635..00000000 --- a/modules1/alias/locales/en_US.json +++ /dev/null @@ -1,106 +0,0 @@ -{ - "core.temp.result.guide": " represents a parameter, do not include \"<>\" when sending, use space to separate parameters\n\"?\" indicates an optional parameter, \"=xx\" means an optional parameter with default value, \"...\" means remaining parameters, meaning spaces in parameters will not affect command, \"*\" only available in group chat, \"#\" only available in private chat, \"^\" requires level 1 permission (group BOT admin and group admin), \"^^\" requires level 2 permission (BOT super admin)", - "core.temp.result.data_error": "Data returned error! Please contact admin\nSource data: %res%", - "core.temp.result.args.empty": "Input parameters cannot be empty", - "core.temp.result.args.error": "Input parameter error, please modify and resend", - "core.temp.result.unknown_error": "Unknown error: %error%", - "core.temp.result.num.error": "Number error, please resend", - "core.temp.result.num.choose": "Resend command and input [number] to choose corresponding content\nExample: /command content 2", - "core.temp.result.no_access.1": "This command can only be executed by group admin and BOT group admin!", - "core.temp.result.no_access.2": "This command can only be executed by BOT super admin!", - "core.temp.result.disable": "This function is currently disabled, please contact admin to enable it", - "core.temp.result.exist": "Input parameter target already exists, please do not repeat", - "core.temp.result.no_esist": "Target parameter does not exist, please confirm and resend", - "core.temp.result.repairing": "This function is under maintenance", - "core.temp.result.apikey_error": "Please configure APIKEY first!", - "core.temp.result.empty": "No content", - "core.temp.result.message_type": "This function is only available in group chat or private chat", - "core.temp.result.option.on": "√", - "core.temp.result.option.off": "X", - "core.temp.menu": "%HEAD%%list%\n%AUTHOR%", - "core.temp.menu.list": "\n%name%%param% - %help%%scope%%access%", - "core.temp.menu.param": " <%prefix%%param_name%%suffix%>", - "core.temp.menu.param_name_default": "content", - "core.temp.menu.prefix.rest": "...", - "core.temp.menu.suffix.optional": "?", - "core.temp.menu.suffix.default": "=%content%", - "core.temp.menu.help": "%content%", - "core.temp.menu.scope.private": "#", - "core.temp.menu.scope.group": "*", - "core.temp.menu.access.manger": "^", - "core.temp.menu.access.admin": "^^", - "core.menu.main.help": "Main menu", - "core.menu.corecom.help": "Core functions", - "core.menu.daytool.help": "Daily tools", - "core.menu.querytool.help": "Query tools", - "core.menu.funsys.help": "Entertainment system", - "core.menu.random_img.help": "Random images", - "core.menu.othercom.help": "Other functions", - "core.descr.api": "View API site data", - "core.msg.api": "%content%", - "core.descr.alias.query": "Query all command aliases", - "core.descr.alias.add": "Add command alias, supports parameters, no need for slash", - "core.descr.alias.del": "Delete command alias", - "core.msg.alias.query": "Alias list: %list%", - "core.msg.alias.list": "\n%key% -> %val%", - "core.msg.alias.add": "Succeeded in adding alias: %input%\nSend the alias to see the effect", - "core.msg.alias.del": "Succeeded in deleting alias: %input%", - "core.msg.alias.fail": "This command or alias is already registered", - "core.msg.alias.fail.2": "Invalid command", - "core.descr.system.0": "Restart Go-cqHttp", - "core.descr.system.1": "Restart Signature Server and Go-cqHttp", - "core.msg.system.fail": "Restart failed, Signserver or Go-cqHttp not found", - "core.msg.system.info.0": "Restarting Go-cqHttp...", - "core.msg.system.info.1": "Restarting Signserver and Go-cqHttp...", - "core.msg.system.info.3": "Restart completed!", - "core.descr.run.private": "Simulate running a private command", - "core.descr.run.group": "Simulate running a group command", - "core.msg.run": "Sent to target: %target%", - "core.descr.locale.list": "View bot's list of support languages", - "core.descr.locale.set": "Switching Bot Language", - "core.msg.locale.lists": "List of support languages:%list%", - "core.msg.locale.list": "\n%locale% - %name%", - "core.msg.locale.locale.zh_cn": "简体中文(Simplified Chinese)", - "core.msg.locale.locale.zh_tw": "繁體中文(Traditional Chinese)", - "core.msg.locale.locale.en_us": "English(English)", - "core.msg.locale.locale.ja_jp": "日本語(Japanese)", - "core.msg.locale.set": "Succeeded in switching to locale %locale%\nTotal number of switching Locales: %total%\nNumber of valid Locales: %success%", - "core.msg.locale.fail": "Switch failed, please enter \"/locale list\" to view the list of languages supported by the BOT", - "core.descr.core": "View kotori-core core plugin statistics", - "core.msg.core": "Total number of registered commands: %commands%", - "core.descr.help": "View command help information, no need for slash/", - "core.msg.help": "Help: %content%\n%GUIDE%\nFor detailed BOT usage documentation please check:\n%DOC%", - "core.msg.descr.fail": "Invalid command", - "core.descr.view": "View Kotori-bot configuration", - "core.msg.view": "Connection mode: %mode%\n%mode_content%\n------\nGo-cqHttp path: %program%\nStartup parameters: %params%\nSignature server path: %signserver%\n------\nMaster: %master%\nPrivate chat filtering: %user%%user_list%\nGroup chat filtering: %group%%group_list%", - "core.msg.view.mode.http": "Forward Http address: %url%\nForward Http port: %port%\nReverse Http port: %reverse_port%\nReconnect interval: %retry_time% seconds", - "core.msg.view.mode.ws": "WebSocket address: %url%\nWebSocket port: %port%\nReconnect interval: %retry_time% seconds", - "core.msg.view.mode.wsreverse": "WebSocket reverse port: %port%", - "core.msg.view.user.white": "\nPrivate chat whitelist:\n%list%\b ", - "core.msg.view.user.black": "\nPrivate chat blacklist:\n%list%\b ", - "core.msg.view.group.white": "\nGroup chat whitelist:\n%list%\b ", - "core.msg.view.group.black": "\nGroup chat blacklist:\n%list%\b ", - "core.msg.view.list": "%content%,", - "core.descr.plugin.query": "View specified or all plugin information", - "core.descr.plugin.ban": "Disable specified plugin", - "core.descr.plugin.unban": "Enable specified plugin", - "core.msg.plugin.query": "Plugin information:\nTotal plugins: %num%%list%", - "core.msg.plugin.fail": "Plugin [%target%] not found", - "core.msg.plugin.list": "\n------\nPlugin Id: %id%\nPlugin name: %name%\nPlugin version: %version%\nPlugin description: %description%\nPlugin author: %author%\nPlugin license: %license%\nPlugin status: %state%", - "core.msg.plugin.ban": "Succeeded in disabling plugin [%id%], restart to take effect", - "core.msg.plugin.unban": "Succeeded in enabling plugin [%id%], restart to take effect", - "core.descr.bot": "View BOT info and status", - "core.msg.bot": "BOT Info\nBOT QQ: %self_id%\nConnect time: %connect%\nPackets received: %packet_received%\nPackets sent: %packet_sent%\nPackets lost: %packet_lost%\nMessages received: %message_received%\nMessages sent: %message_sent%\nLost connections: %lost_times%\nDisconnects: %disconnect_times%\nLast message time: %last_message_time%\n%AUTHOR%", - "core.descr.env": "View environment info", - "core.msg.env": "Environment Info\nNode version: %node%\nTypeScript version: %typescript%\nTsNode version: %tsnode%\n%AUTHOR%", - "core.descr.ver": "View version info", - "core.msg.ver": "KotoriBot version: %version%\nLicense: %license%\n%AUTHOR%", - "core.descr.status": "View server running status", - "core.msg.status": "Server status\nKernel: %type%\nPlatform: %platform%\nCPU architecture: %arch%\nCPU model: %model%\nCPU speed: %speed%GHz\nCPU cores: %num%\nCPU usage: %cpu_rate%%\nTotal memory: %total%GB\nAvailable memory: %used%GB\nMemory usage: %ram_rate%%\nNetwork cards: %network%\nUptime: %time%\nHostname: %hostname%\nHome dir: %homedir%\n%AUTHOR%", - "core.descr.about": "Help information", - "core.msg.about": "KotoriBot is a NodeJS+TypeScript SDK and bot framework implementation for go-cqhttp\nSource code: %REPO%\nLeave the poor 🦊 a star\n\nCurrent bot framework version: %version%\nFramework license: %license%\n%AVATAR%\n%AUTHOR%", - "core.descr.update": "Check for updates", - "core.msg.update": "Current version: %version%\n%content%", - "core.msg.update.yes": "Already latest version!", - "core.msg.update.no": "Update detected!\nLatest version: %version%\nPlease get the latest version from Github repo:\n%REPO%" -} \ No newline at end of file diff --git a/modules1/alias/locales/ja_JP.json b/modules1/alias/locales/ja_JP.json deleted file mode 100644 index 01921696..00000000 --- a/modules1/alias/locales/ja_JP.json +++ /dev/null @@ -1,106 +0,0 @@ -{ - "core.temp.result.guide": "<名前>はパラメータを表します。送信時には「<>」を含めないでください。パラメータはスペースで区切ってください。\n「?」はオプションパラメータを示します。「=xx」はデフォルト値のあるオプションパラメータを意味します。「...」は残りのパラメータを意味し、パラメータ内のスペースはコマンドに影響しません。「*」はグループチャットでのみ利用可能。「#」は個人チャットでのみ利用可能。「^」はレベル1の許可が必要(グループBOT管理者とグループ管理者)。「^^」はレベル2の許可が必要(BOTのスーパー管理者)。", - "core.temp.result.data_error": "返されたデータがエラーです!管理者に連絡してください。\nソースデータ: %res%", - "core.temp.result.args.empty": "入力パラメータを空にすることはできません", - "core.temp.result.args.error": "入力パラメータエラーです。変更して再送信してください。", - "core.temp.result.unknown_error": "不明なエラー: %error%", - "core.temp.result.num.error": "番号がエラーです。再送信してください。", - "core.temp.result.num.choose": "コマンドを再送信し、対応するコンテンツを選択するために[番号]を入力してください。\n例: /コマンド コンテンツ 2", - "core.temp.result.no_access.1": "このコマンドは、グループ管理者とBOTグループ管理者のみが実行できます!", - "core.temp.result.no_access.2": "このコマンドは、BOTのスーパー管理者のみが実行できます!", - "core.temp.result.disable": "この機能は現在無効です。有効にするには管理者に連絡してください。", - "core.temp.result.exist": "入力パラメータのターゲットは既に存在するため、実行を繰り返さないでください。", - "core.temp.result.no_esist": "ターゲットパラメータが存在しません。確認して再送信してください。", - "core.temp.result.repairing": "この機能はメンテナンス中です。", - "core.temp.result.apikey_error": "まずAPIKEYを設定してください!", - "core.temp.result.empty": "コンテンツがありません", - "core.temp.result.message_type": "この機能は、グループチャットまたは個人チャットでのみ利用できます。", - "core.temp.result.option.on": "√", - "core.temp.result.option.off": "X", - "core.temp.menu": "%HEAD%%list%\n%AUTHOR%", - "core.temp.menu.list": "\n%name%%param% - %help%%scope%%access%", - "core.temp.menu.param": " <%prefix%%param_name%%suffix%>", - "core.temp.menu.param_name_default": "content", - "core.temp.menu.prefix.rest": "...", - "core.temp.menu.suffix.optional": "?", - "core.temp.menu.suffix.default": "=%content%", - "core.temp.menu.help": "%content%", - "core.temp.menu.scope.private": "#", - "core.temp.menu.scope.group": "*", - "core.temp.menu.access.manger": "^", - "core.temp.menu.access.admin": "^^", - "core.menu.main.help": "メインメニュー", - "core.menu.corecom.help": "コア機能", - "core.menu.daytool.help": "日常ツール", - "core.menu.querytool.help": "検索ツール", - "core.menu.funsys.help": "エンタメシステム", - "core.menu.random_img.help": "ランダム画像", - "core.menu.othercom.help": "その他の機能", - "core.descr.api": "APIサイトのデータを表示", - "core.msg.api": "%content%", - "core.descr.alias.query": "すべてのコマンドエイリアスを照会", - "core.descr.alias.add": "コマンドエイリアスを追加、スラッシュ不要、パラメータ可能", - "core.descr.alias.del": "コマンドエイリアスを削除", - "core.msg.alias.query": "エイリアスリスト:%list%", - "core.msg.alias.list": "\n%key% -> %val%", - "core.msg.alias.add": "エイリアスが追加されました: %input%\nエイリアスを送信して効果を確認してください", - "core.msg.alias.del": "エイリアスが削除されました: %input%", - "core.msg.alias.fail": "そのコマンドまたはエイリアスは既に登録されています", - "core.msg.alias.fail.2": "そのコマンドは無効です", - "core.descr.system.0": "Go-cqHttpを再起動", - "core.descr.system.1": "署名サーバとGo-cqHttpを再起動", - "core.msg.system.fail": "再起動に失敗しました。SignserverまたはGo-cqHttpが見つかりません", - "core.msg.system.info.0": "Go-cqHttpを再起動中...", - "core.msg.system.info.1": "署名サーバとGo-cqHttpを再起動中...", - "core.msg.system.info.3": "再起動完了!", - "core.descr.run.private": "プライベートコマンドの実行をシミュレートする", - "core.descr.run.group": "グループコマンドの実行をシミュレートする", - "core.msg.run": "対象に送信: %target%", - "core.descr.locale.list": "BOTがサポートする言語リストを表示", - "core.descr.locale.set": "BOTが使用する言語を切り替える", - "core.msg.locale.lists": "サポート言語リスト:%list%", - "core.msg.locale.list": "\n%locale% - %name%", - "core.msg.locale.locale.zh_cn": "简体中文(Simplified Chinese)", - "core.msg.locale.locale.zh_tw": "繁體中文(Traditional Chinese)", - "core.msg.locale.locale.en_us": "English(English)", - "core.msg.locale.locale.ja_jp": "日本語(Japanese)", - "core.msg.locale.set": "ロケールを%locale%に切り替えました\n切り替えLocale総数: %total%\n有効Locale数: %success%", - "core.msg.locale.fail": "切り替えに失敗しました。BOTでサポートされている言語のリストを見るには「/locale list」と入力してください", - "core.descr.core": "kotori-coreコアプラグインの統計を表示", - "core.msg.core": "登録されたコマンドの総数: %commands%", - "core.descr.help": "コマンドのヘルプ情報を表示。スラッシュは不要です", - "core.msg.help": "ヘルプ: %content%\n%GUIDE%\nBOTの詳細な使用方法はこちらをご確認ください:\n%DOC%", - "core.msg.descr.fail": "無効なコマンドです", - "core.descr.view": "Kotori-botの設定を表示", - "core.msg.view": "接続モード: %mode%\n%mode_content%\n------\ngo-cqhttpのパス: %program%\n起動パラメータ: %params%\n署名サーバーのパス: %signserver%\n------\nマスター: %master%\n個人チャットフィルタリング: %user%%user_list%\nグループチャットフィルタリング: %group%%group_list%", - "core.msg.view.mode.http": "フォワードHttpアドレス: %url%\nフォワードHttpポート: %port%\nリバースHttpポート: %reverse_port%\n再接続間隔: %retry_time%秒", - "core.msg.view.mode.ws": "WebSocketアドレス: %url%\nWebSocketポート: %port%\n再接続間隔: %retry_time%秒", - "core.msg.view.mode.wsreverse": "WebSocketリバースポート: %port%", - "core.msg.view.user.white": "\n個人チャットホワイトリスト:\n%list%\b", - "core.msg.view.user.black": "\n個人チャットブラックリスト:\n%list%\b", - "core.msg.view.group.white": "\nグループチャットホワイトリスト:\n%list%\b", - "core.msg.view.group.black": "\nグループチャットブラックリスト:\n%list%\b", - "core.msg.view.list": "%content%,", - "core.descr.plugin.query": "指定またはすべてのプラグイン情報を表示", - "core.descr.plugin.ban": "指定プラグインを無効化", - "core.descr.plugin.unban": "指定プラグインを有効化", - "core.msg.plugin.query": "プラグイン情報:\nプラグイン数合計: %num%%list%", - "core.msg.plugin.fail": "[%target%] プラグインが見つかりません", - "core.msg.plugin.list": "\n------\nプラグインID: %id%\nプラグイン名: %name%\nバージョン: %version%\n説明: %description%\n作者: %author%\nライセンス: %license%\nステータス: %state%", - "core.msg.plugin.ban": "[%id%]プラグインを禁止しました。再起動で反映されます。", - "core.msg.plugin.unban": "[%id%]プラグインの禁止を解除しました。再起動で反映されます。", - "core.descr.bot": "BOT情報とステータスを表示", - "core.msg.bot": "BOT情報\nBOT QQ: %self_id%\n接続時間: %connect%\n受信パケット数: %packet_received%\n送信パケット数: %packet_sent%\nパケットロス数: %packet_lost%\n受信メッセージ数: %message_received%\n送信メッセージ数: %message_sent%\n接続ロスト回数: %lost_times%\n切断回数: %disconnect_times%\n最終メッセージ時間: %last_message_time%\n%AUTHOR%", - "core.descr.env": "環境情報を表示", - "core.msg.env": "環境情報\nNodeバージョン: %node%\nTypeScriptバージョン: %typescript%\nTsNodeバージョン: %tsnode%\n%AUTHOR%", - "core.descr.ver": "バージョン情報を表示", - "core.msg.ver": "KotoriBotバージョン: %version%\nライセンス: %license%\n%AUTHOR%", - "core.descr.status": "サーバーの実行状況を確認する", - "core.msg.status": "サーバーステータス\nカーネル: %type%\nプラットフォーム: %platform%\nCPUアーキテクチャ: %arch%\nCPUモデル: %model%\nCPU速度: %speed%GHz\nCPUコア数: %num%\nCPU使用率: %cpu_rate%%\nメモリ総量: %total%GB\n利用可能メモリ: %used%GB\nメモリ使用率: %ram_rate%%\nネットワークカード数: %network%\n起動時間: %time%\nホスト名: %hostname%\nホームディレクトリ: %homedir%\n%AUTHOR%", - "core.descr.about": "ヘルプ情報", - "core.msg.about": "KotoriBotはgo-cqhttpのNodeJS+TypeScript製SDKおよびBOTフレームワークの実装です\nソースコード: %REPO%\n可哀想な:狐狸脸:にスターをつけてあげてください\n\n現在のBOTフレームワークバージョン: %version%\nフレームワークライセンス: %license%\n%AVATAR%\n%AUTHOR%", - "core.descr.update": "アップデートを確認する", - "core.msg.update": "現在のバージョン: %version%\n%content%", - "core.msg.update.yes": "最新バージョンです!", - "core.msg.update.no": "アップデートがあります!\n最新バージョン: %version%\nGithubリポジトリから最新バージョンを取得してください:\n%REPO%" -} \ No newline at end of file diff --git a/modules1/alias/locales/zh_CN.json b/modules1/alias/locales/zh_CN.json deleted file mode 100644 index eb1f23c2..00000000 --- a/modules1/alias/locales/zh_CN.json +++ /dev/null @@ -1,106 +0,0 @@ -{ - "core.temp.result.guide": "<名字>代表参数,发送时无需到\"<>\",使用空格间隔各个参数\n\"?\"表示可选参数,\"=xx\"表示可选且有默认值,\"。。。\"表示剩余参数,意味着参数中的空格将不影响指令,\"*\"仅群聊可用,\"#\"仅私聊可用,\"^\"需一级权限(群BOT管理员和群管理员),\"^^\"需二级权限(BOT超级管理员)", - "core.temp.result.data_error": "返回数据错误!请联系管理员\n源数据: %res%", - "core.temp.result.args.empty": "输入参数不能为空", - "core.temp.result.args.error": "输入参数错误,请更改后重新发送", - "core.temp.result.unknown_error": "未知的错误: %error%", - "core.temp.result.num.error": "序号错误,请重新发送", - "core.temp.result.num.choose": "再次发送指令并传入参数[序号]以选择对应内容\n示例:/指令 内容 2", - "core.temp.result.no_access.1": "该指令仅群管理员与群BOT管理员可执行!", - "core.temp.result.no_access.2": "该指令仅BOT超级管理员可执行!", - "core.temp.result.disable": "该功能目前未启用,请联系管理员开启", - "core.temp.result.exist": "输入参数目标已存在,请勿重复执行", - "core.temp.result.no_esist": "目标参数不存在,请确认后重新发送", - "core.temp.result.repairing": "该功能维修中", - "core.temp.result.apikey_error": "请先配置APIKEY!", - "core.temp.result.empty": "无内容", - "core.temp.result.message_type": "该功能仅在群聊或私聊下可用", - "core.temp.result.option.on": "√", - "core.temp.result.option.off": "X", - "core.temp.menu": "%HEAD%%list%\n%AUTHOR%", - "core.temp.menu.list": "\n%name%%param% - %help%%scope%%access%", - "core.temp.menu.param": " <%prefix%%param_name%%suffix%>", - "core.temp.menu.param_name_default": "content", - "core.temp.menu.prefix.rest": "。。。", - "core.temp.menu.suffix.optional": "?", - "core.temp.menu.suffix.default": "=%content%", - "core.temp.menu.help": "%content%", - "core.temp.menu.scope.private": "#", - "core.temp.menu.scope.group": "*", - "core.temp.menu.access.manger": "^", - "core.temp.menu.access.admin": "^^", - "core.menu.main.help": "主菜单", - "core.menu.corecom.help": "核心功能", - "core.menu.daytool.help": "日常工具", - "core.menu.querytool.help": "查询工具", - "core.menu.funsys.help": "娱乐系统", - "core.menu.random_img.help": "随机图片", - "core.menu.othercom.help": "其它功能", - "core.descr.api": "查看API站点数据", - "core.msg.api": "%content%", - "core.descr.alias.query": "查询全部指令别名", - "core.descr.alias.add": "添加指令别名,支持带参数,无需带斜杠", - "core.descr.alias.del": "删除指令别名", - "core.msg.alias.query": "别名列表:%list%", - "core.msg.alias.list": "\n%key% -> %val%", - "core.msg.alias.add": "成功添加别名: %input%\n发送别名以查看效果", - "core.msg.alias.del": "成功删除别名: %input%", - "core.msg.alias.fail": "该指令或别名已被注册", - "core.msg.alias.fail.2": "该指令无效", - "core.descr.system.0": "重启Go-cqHttp", - "core.descr.system.1": "重启签名服务器与Go-cqHttp", - "core.msg.system.fail": "重启失败,无法找到Signserver或Go-cqHttp", - "core.msg.system.info.0": "即将重启Go-cqHttp。。。", - "core.msg.system.info.1": "即将重启Signserver与Go-cqHttp。。。", - "core.msg.system.info.3": "重启完成!", - "core.descr.run.private": "模拟执行一条私聊指令", - "core.descr.run.group": "模拟执行一条群指令", - "core.msg.run": "发送至目标: %target%", - "core.descr.locale.list": "查看BOT支持语言列表", - "core.descr.locale.set": "切换BOT使用语言", - "core.msg.locale.lists": "支持语言列表:%list%", - "core.msg.locale.list": "\n%locale% - %name%", - "core.msg.locale.locale.zh_cn": "简体中文(Simplified Chinese)", - "core.msg.locale.locale.zh_tw": "繁體中文(Traditional Chinese)", - "core.msg.locale.locale.en_us": "English(English)", - "core.msg.locale.locale.ja_jp": "日本語(Japanese)", - "core.msg.locale.set": "切换至%locale%\n切换Locale总数: %total%\n有效Locale数量: %success%", - "core.msg.locale.fail": "切换失败,请输入\"/locale list\"查看BOT支持语言列表", - "core.descr.core": "查看kotori-core核心插件统计数据", - "core.msg.core": "累计注册指令数量: %commands%", - "core.descr.help": "查看指令帮助信息,不需要带斜杠/", - "core.msg.help": "帮助:%content%\n%GUIDE%\nBOT详细使用文档请查看:\n%DOC%", - "core.msg.descr.fail": "无效的指令", - "core.descr.view": "查看Kotori-bot配置", - "core.msg.view": "连接模式: %mode%\n%mode_content%\n------\nGo-cqHttp路径: %program%\n启动参数: %params%\n签名服务器路径: %signserver%\n------\nMaster: %master%\n私聊过滤: %user%%user_list%\n群聊过滤: %group%%group_list%", - "core.msg.view.mode.http": "正向Http地址: %url%\n正向Http端口: %port%\n反向Http端口: %reverse_port%\n重连间隔时间: %retry_time%秒", - "core.msg.view.mode.ws": "WebSocket地址: %url%\nWebSocket端口: %port%\n重连间隔时间: %retry_time%秒", - "core.msg.view.mode.wsreverse": "WebSocket反向端口: %port%", - "core.msg.view.user.white": "\n私聊白名单:\n%list%\b ", - "core.msg.view.user.black": "\n私聊黑名单:\n%list%\b ", - "core.msg.view.group.white": "\n群聊白名单:\n%list%\b ", - "core.msg.view.group.black": "\n群聊黑名单:\n%list%\b ", - "core.msg.view.list": "%content%,", - "core.descr.plugin.query": "查看指定或全部插件信息", - "core.descr.plugin.ban": "禁用指定插件", - "core.descr.plugin.unban": "启用指定插件", - "core.msg.plugin.query": "插件信息:\n插件总数: %num%%list%", - "core.msg.plugin.fail": "未找到[%target%]插件", - "core.msg.plugin.list": "\n------\n插件Id: %id%\n插件名字: %name%\n插件版本: %version%\n插件描述: %description%\n插件作者: %author%\n插件协议: %license%\n插件状态: %state%", - "core.msg.plugin.ban": "成功禁用[%id%]插件,重启以查看效果", - "core.msg.plugin.unban": "成功取消禁用[%id%]插件,重启以查看效果", - "core.descr.bot": "查看BOT信息与运行状态", - "core.msg.bot": "BOT信息\nBOTQQ: %self_id%\n连接时间: %connect%\n接收包数量: %packet_received%\n发送包数量: %packet_sent%\n丢失包数量: %packet_lost%\n接收消息数量: %message_received%\n发送消息数量: %message_sent%\n连接丢失次数: %lost_times%\n连接断开次数: %disconnect_times%\n最后消息时间: %last_message_time%\n%AUTHOR%", - "core.descr.env": "查看环境信息", - "core.msg.env": "环境信息\nNode版本: %node%\nTypeScript版本: %typescript%\nTsNode版本: %tsnode%\n%AUTHOR%", - "core.descr.ver": "查看版本信息", - "core.msg.ver": "KotoriBot版本: %version%\n协议: %license%\n%AUTHOR%", - "core.descr.status": "查看服务器运行状态", - "core.msg.status": "服务器运行状态\n系统内核: %type%\n系统平台: %platform%\nCPU架构: %arch%\nCPU型号: %model%\nCPU频率: %speed%GHz\nCPU核心数: %num%\nCPU使用率: %cpu_rate%%\n内存总量: %total%GB\n可用内存: %used%GB\n内存使用率: %ram_rate%%\n网卡数量: %network%\n开机时间: %time%\n主机名字: %hostname%\n系统目录: %homedir%\n%AUTHOR%", - "core.descr.about": "帮助信息", - "core.msg.about": "KotoriBot是一个go-cqhttp的基于NodeJS+TypeScript的SDK和QQ机器人框架实现\n开源地址: %REPO%\n来给可怜的🦊点一个star吧\n\n当前BOT框架版本: %version%\n框架协议: %license%\n%AVATAR%\n%AUTHOR%", - "core.descr.update": "检查更新", - "core.msg.update": "当前版本: %version%\n%content%", - "core.msg.update.yes": "当前为最新版本!", - "core.msg.update.no": "检测到有更新!\n最新版本: %version%\n请前往Github仓库获取最新版本:\n%REPO%" -} \ No newline at end of file diff --git a/modules1/alias/locales/zh_TW.json b/modules1/alias/locales/zh_TW.json deleted file mode 100644 index c5bb1b08..00000000 --- a/modules1/alias/locales/zh_TW.json +++ /dev/null @@ -1,106 +0,0 @@ -{ - "core.temp.result.guide": "<名字>代表參數,發送時無需到\"<>\",使用空格間隔各個參數\n\"?\"表示可選參數,\"=xx\"表示可選且有默認值,\"。。。\"表示剩余參數,意味著參數中的空格將不影響指令,\"*\"僅群聊可用,\"#\"僅私聊可用,\"^\"需一級權限(群BOT管理員和群管理員),\"^^\"需二級權限(BOT超級管理員)", - "core.temp.result.data_error": "返回數據錯誤!請聯系管理員\n源數據: %res%", - "core.temp.result.args.empty": "輸入參數不能為空", - "core.temp.result.args.error": "輸入參數錯誤,請更改後重新發送", - "core.temp.result.unknown_error": "未知的錯誤: %error%", - "core.temp.result.num.error": "序號錯誤,請重新發送", - "core.temp.result.num.choose": "再次發送指令並傳入參數[序號]以選擇對應內容\n示例:/指令 內容 2", - "core.temp.result.no_access.1": "該指令僅群管理員與群BOT管理員可執行!", - "core.temp.result.no_access.2": "該指令僅BOT超級管理員可執行!", - "core.temp.result.disable": "該功能目前未啟用,請聯系管理員開啟", - "core.temp.result.exist": "輸入參數目標已存在,請勿重復執行", - "core.temp.result.no_esist": "目標參數不存在,請確認後重新發送", - "core.temp.result.repairing": "該功能維修中", - "core.temp.result.apikey_error": "請先配置APIKEY!", - "core.temp.result.empty": "無內容", - "core.temp.result.message_type": "該功能僅在群聊或私聊下可用", - "core.temp.result.option.on": "√", - "core.temp.result.option.off": "X", - "core.temp.menu": "%HEAD%%list%\n%AUTHOR%", - "core.temp.menu.list": "\n%name%%param% - %help%%scope%%access%", - "core.temp.menu.param": " <%prefix%%param_name%%suffix%>", - "core.temp.menu.param_name_default": "content", - "core.temp.menu.prefix.rest": "。。。", - "core.temp.menu.suffix.optional": "?", - "core.temp.menu.suffix.default": "=%content%", - "core.temp.menu.help": "%content%", - "core.temp.menu.scope.private": "#", - "core.temp.menu.scope.group": "*", - "core.temp.menu.access.manger": "^", - "core.temp.menu.access.admin": "^^", - "core.menu.main.help": "主菜單", - "core.menu.corecom.help": "核心功能", - "core.menu.daytool.help": "日常工具", - "core.menu.querytool.help": "查詢工具", - "core.menu.funsys.help": "娛樂系統", - "core.menu.random_img.help": "隨機圖片", - "core.menu.othercom.help": "其它功能", - "core.descr.api": "查看API站點數據", - "core.msg.api": "%content%", - "core.descr.alias.query": "查詢全部指令別名", - "core.descr.alias.add": "添加指令別名,支持帶參數,無需帶斜杠", - "core.descr.alias.del": "刪除指令別名", - "core.msg.alias.query": "別名列表:%list%", - "core.msg.alias.list": "\n%key% -> %val%", - "core.msg.alias.add": "成功添加別名: %input%\n發送別名以查看效果", - "core.msg.alias.del": "成功刪除別名: %input%", - "core.msg.alias.fail": "該指令或別名已被註冊", - "core.msg.alias.fail.2": "該指令無效", - "core.descr.system.0": "重啟Go-cqHttp", - "core.descr.system.1": "重啟簽名服務器與Go-cqHttp", - "core.msg.system.fail": "重啟失敗,無法找到Signserver或Go-cqHttp", - "core.msg.system.info.0": "即將重啟Go-cqHttp。。。", - "core.msg.system.info.1": "即將重啟Signserver與Go-cqHttp。。。", - "core.msg.system.info.3": "重啟完成!", - "core.descr.run.private": "模擬執行一條私聊指令", - "core.descr.run.group": "模擬執行一條群指令", - "core.msg.run": "發送至目標: %target%", - "core.descr.locale.list": "查看BOT支持語言列表", - "core.descr.locale.set": "切換BOT使用語言", - "core.msg.locale.lists": "支持語言列表:%list%", - "core.msg.locale.list": "\n%locale% - %name%", - "core.msg.locale.locale.zh_cn": "簡體中文(Simplified Chinese)", - "core.msg.locale.locale.zh_tw": "繁體中文(Traditional Chinese)", - "core.msg.locale.locale.en_us": "English(English)", - "core.msg.locale.locale.ja_jp": "日本語(Japanese)", - "core.msg.locale.set": "成功切換至%locale%\n切換Locale總數: %total%\n有效Locale數量: %success%", - "core.msg.locale.fail": "切換失敗,請輸入\"/locale list\"查看BOT支持語言列表", - "core.descr.core": "查看kotori-core核心插件統計數據", - "core.msg.core": "累計註冊指令數量: %commands%", - "core.descr.help": "查看指令幫助信息,不需要帶斜杠/", - "core.msg.help": "幫助:%content%\n%GUIDE%\nBOT詳細使用文檔請查看:\n%DOC%", - "core.msg.descr.fail": "無效的指令", - "core.descr.view": "查看Kotori-bot配置", - "core.msg.view": "連接模式: %mode%\n%mode_content%\n------\nGo-cqHttp路徑: %program%\n啟動參數: %params%\n簽名服務器路徑: %signserver%\n------\nMaster: %master%\n私聊過濾: %user%%user_list%\n群聊過濾: %group%%group_list%", - "core.msg.view.mode.http": "正向Http地址: %url%\n正向Http端口: %port%\n反向Http端口: %reverse_port%\n重連間隔時間: %retry_time%秒", - "core.msg.view.mode.ws": "WebSocket地址: %url%\nWebSocket端口: %port%\n重連間隔時間: %retry_time%秒", - "core.msg.view.mode.wsreverse": "WebSocket反向端口: %port%", - "core.msg.view.user.white": "\n私聊白名單:\n%list%\b ", - "core.msg.view.user.black": "\n私聊黑名單:\n%list%\b ", - "core.msg.view.group.white": "\n群聊白名單:\n%list%\b ", - "core.msg.view.group.black": "\n群聊黑名單:\n%list%\b ", - "core.msg.view.list": "%content%,", - "core.descr.plugin.query": "查看指定或全部插件信息", - "core.descr.plugin.ban": "禁用指定插件", - "core.descr.plugin.unban": "啟用指定插件", - "core.msg.plugin.query": "插件信息:\n插件總數: %num%%list%", - "core.msg.plugin.fail": "未找到[%target%]插件", - "core.msg.plugin.list": "\n------\n插件Id: %id%\n插件名字: %name%\n插件版本: %version%\n插件描述: %description%\n插件作者: %author%\n插件協議: %license%\n插件狀態: %state%", - "core.msg.plugin.ban": "成功禁用[%id%]插件,重啟以查看效果", - "core.msg.plugin.unban": "成功取消禁用[%id%]插件,重啟以查看效果", - "core.descr.bot": "查看BOT信息與運行狀態", - "core.msg.bot": "BOT信息\nBOTQQ: %self_id%\n連接時間: %connect%\n接收包數量: %packet_received%\n發送包數量: %packet_sent%\n丟失包數量: %packet_lost%\n接收消息數量: %message_received%\n發送消息數量: %message_sent%\n連接丟失次數: %lost_times%\n連接斷開次數: %disconnect_times%\n最後消息時間: %last_message_time%\n%AUTHOR%", - "core.descr.env": "查看環境信息", - "core.msg.env": "環境信息\nNode版本: %node%\nTypeScript版本: %typescript%\nTsNode版本: %tsnode%\n%AUTHOR%", - "core.descr.ver": "查看版本信息", - "core.msg.ver": "KotoriBot版本: %version%\n協議: %license%\n%AUTHOR%", - "core.descr.status": "查看服務器運行狀態", - "core.msg.status": "服務器運行狀態\n系統內核: %type%\n系統平臺: %platform%\nCPU架構: %arch%\nCPU型號: %model%\nCPU頻率: %speed%GHz\nCPU核心數: %num%\nCPU使用率: %cpu_rate%%\n內存總量: %total%GB\n可用內存: %used%GB\n內存使用率: %ram_rate%%\n網卡數量: %network%\n開機時間: %time%\n主機名字: %hostname%\n系統目錄: %homedir%\n%AUTHOR%", - "core.descr.about": "幫助信息", - "core.msg.about": "KotoriBot是一個go-cqhttp的基於NodeJS+TypeScript的SDK和QQ機器人框架實現\n開源地址: %REPO%\n來給可憐的🦊點一個star吧\n\n當前BOT框架版本: %version%\n框架協議: %license%\n%AVATAR%\n%AUTHOR%", - "core.descr.update": "檢查更新", - "core.msg.update": "當前版本: %version%\n%content%", - "core.msg.update.yes": "當前為最新版本!", - "core.msg.update.no": "檢測到有更新!\n最新版本: %version%\n請前往Github倉庫獲取最新版本:\n%REPO%" -} \ No newline at end of file diff --git a/modules1/alias/manifest.json b/modules1/alias/manifest.json deleted file mode 100644 index 07959209..00000000 --- a/modules1/alias/manifest.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "KotoriBot Core", - "description": "KotoriBot's Core Plugin,provide handle message event to normative command", - "version": "1.0.0", - "author": "himeno", - "license": "GPL-3.0" -} diff --git a/modules1/alias/package1.json b/modules1/alias/package1.json deleted file mode 100644 index 7aa54171..00000000 --- a/modules1/alias/package1.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "kotori-plugin-testing", - "version": "1.0.0", - "description": "testing plugin", - "main": "src/index.ts", - "license": "GPL-3.0", - "author": "Hotaru ", - "peerDependencies": { - "kotori-bot": "workspace:^" - } -} \ No newline at end of file diff --git a/modules1/alias/src/class/class.cache.ts b/modules1/alias/src/class/class.cache.ts deleted file mode 100644 index 281e6dfb..00000000 --- a/modules1/alias/src/class/class.cache.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { obj } from '@/tools'; - -export class Cache { - private static cache: obj = {}; - - public static set(key: string, data: obj) { - this.cache[key] = data; - } - - public static get = (key: string): obj | null => { - const result = this.cache[key]; - return result; - }; -} - -export default Cache; diff --git a/modules1/alias/src/class/class.command.ts b/modules1/alias/src/class/class.command.ts deleted file mode 100644 index fa36f93f..00000000 --- a/modules1/alias/src/class/class.command.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { ACCESS, CoreKeyword, InfoVal, InfoValArg, SCOPE } from '../type'; -import Data from './class.data'; - -export class Command extends Data { - private keyword: CoreKeyword; - - private info: InfoVal; - - public constructor(keyword: CoreKeyword, info: InfoVal) { - super(); - this.keyword = keyword; - this.info = info; - } - - private handle() { - Command.cmdInfoData.set(this.keyword, this.info); - return this; - } - - public menuId(val: string) { - this.info.menuId = val; - return this.handle(); - } - - public help(help: string) { - this.info.help = help; - return this.handle(); - } - - public scope(scope: SCOPE) { - this.info.scope = scope; - return this.handle(); - } - - public access(access: ACCESS) { - this.info.access = access; - return this.handle(); - } - - public params(params: InfoValArg) { - this.info.params = params; - return this.handle(); - } -} - -export default Command; diff --git a/modules1/alias/src/class/class.content.ts b/modules1/alias/src/class/class.content.ts deleted file mode 100644 index ae39c879..00000000 --- a/modules1/alias/src/class/class.content.ts +++ /dev/null @@ -1,203 +0,0 @@ -import path from 'path'; -import { Api, Const, EventDataType, obj, parseCommand } from '@/tools'; -import SDK from '@/utils/class.sdk'; -import { - ACCESS, - SCOPE, - Send, - CoreKeyword, - CoreKeywordMatch, - InfoArgEx, - CoreVal, - InfoArg, - BOT_RESULT, - Hook, -} from '../type'; -import { loadConfigP, temp } from '../method'; -import Core from './class.core'; -import Data from './class.data'; - -export class Content extends Data { - private data: EventDataType; - - private api: Api; - - public constructor(data: EventDataType, api: Api, consts: Const, callbacks?: Hook[]) { - super(); - this.data = data; - this.api = api; - Content.consts = consts; - Core.args = parseCommand(this.data.message); - - if (callbacks) { - for (const callback of callbacks) { - if (!callback(data, this.send, api)) return; - } - } - - const result = Content.isUsefulCmd(Core.args[0], this.data.message); - if (result) this.runHandlerFunc(...result); - this.runAlias(); - } - - private static consts: Const; - - public static verifyAccess(data: EventDataType) { - if (data.user_id === this.consts.CONFIG.bot.master) return ACCESS.ADMIN; - if (!data.group_id) return ACCESS.NORMAL; - if (data.sender.role === 'admin' || data.sender.role === 'owner') return ACCESS.MANGER; - const mangerList = loadConfigP(path.join(data.group_id.toString(), 'mangerList.json')) as number[]; - return mangerList.includes(data.user_id) ? ACCESS.MANGER : ACCESS.NORMAL; - }; - - public static verifyFrom(data: EventDataType) { - if (data.user_id === data.self_id) return false; - return true; - }; - - public static isUsefulCmd = (cmd: string, message: string): [CoreVal, CoreKeyword | CoreKeywordMatch] | null => { - const result = Data.cmdData.get(cmd); - if (result) return [result, cmd]; - - for (const [key, handlerFunc] of Data.cmdData) { - if ( - typeof key !== 'string' && - ((typeof key === 'function' && key(message)) || (Array.isArray(key) && key.includes(message))) - ) - return [handlerFunc, key]; - } - return null; - }; - - private send: Send(contents, params = {}) { - let content = contents; - if (typeof content !== 'object') content = temp(content, params); - if (this.data.message_type === 'private') { - this.api.send_private_msg(content, this.data.user_id); - } else { - this.api.send_group_msg(content, this.data.group_id!); - } - }; - - private checkParams(key: CoreKeyword) { - const params = Data.cmdInfoData.get(key)?.params; - - if (!params) return true; - if (Array.isArray(params)) return this.checkParamsArr(params); - return this.checkParamsObj(params); - }; - - private checkParamsArr(params: InfoArg[], num: number = 1) { - for (const indexs of Object.keys(params)) { - const index = parseInt(indexs, 10); - const indexNum = index + num; - if (params[index].rest) { - Core.args = this.data.message.split(' '); - for (let init = 0; init < Core.args.length; init += 1) { - if (init > indexNum && Core.args[init]) Core.args[indexNum] += ` ${Core.args[init]}`; - } - } - - if (!Core.args[indexNum] && params[index].must === true) { - this.send(BOT_RESULT.ARGS_EMPTY); - return false; - } - - if (!Core.args[indexNum] && typeof params[index].must === 'string') { - Core.args[indexNum] = params[index].must as string; - } - - if (params[index].rest) return true; - } - return true; - }; - - private checkParamsObj(params: InfoArgEx, num: number = 1) { - if (!Core.args[num]) { - this.send(BOT_RESULT.ARGS_ERROR); - return false; - } - const result = params[Core.args[num]]; - if (result === undefined) { - this.send(BOT_RESULT.ARGS_ERROR); - return false; - } - if (Array.isArray(result.args)) { - return this.checkParamsArr(result.args, num + 1); - } - return true; - }; - - private checkScope(scope: SCOPE) { - if (scope === SCOPE.ALL) return true; - if (scope === SCOPE.PRIVATE && this.data.message_type === 'private') return true; - if (scope === SCOPE.GROUP && this.data.message_type === 'group') return true; - this.send(BOT_RESULT.MESSAGE_TYPE); - return false; - }; - - private checkAccess(access: ACCESS) { - const result = Content.verifyAccess(this.data) >= access; - if (!result) this.send(access === ACCESS.ADMIN ? BOT_RESULT.NO_ACCESS_2 : BOT_RESULT.NO_ACCESS_1); - return result; - }; - - private runHandlerFunc = async (handlerFunc: CoreVal, key: CoreKeyword | CoreKeywordMatch) => { - if (typeof key !== 'function') { - const cmdInfo = Data.cmdInfoData.get(key); - if (!cmdInfo) return; - if (!this.checkScope(cmdInfo.scope)) return; - if (!this.checkAccess(cmdInfo.access)) return; - if (!this.checkParams(key)) return; - } - - if (this.data.message_type === 'group') { - this.api.send_group_msg(SDK.cq_poke(this.data.user_id), this.data.group_id!); - } - if (typeof handlerFunc === 'string') { - this.send(handlerFunc); - return; - } - - const listenr(error: unknown) { - process.removeListener('unhandledRejection', listenr); - Content.isErroring = false; - this.send(BOT_RESULT.UNKNOWN_ERROR, { - error: error instanceof Error ? error.toString() : JSON.stringify(error), - }); - }; - if (!Content.isErroring) { - Content.isErroring = true; - // process.removeAllListeners('unhandledRejection'); - process.on('unhandledRejection', listenr); - } - - const result = await handlerFunc(this.send, this.data); - process.removeListener('unhandledRejection', listenr); - Content.isErroring = false; - if (!result) return; - if (typeof result === 'string') { - this.send(result); - return; - } - if (!Array.isArray(result)) return; - Object.keys(result[1]).forEach(Element => { - const val = result[1][Element]; - const type = typeof val; - if (val instanceof Error) result[1][Element] = val.toString(); - else if (type === 'undefined') result[1][Element] = 'undefined'; - else if (type === 'object' && !val) result[1][Element] = 'null'; - else if (type !== 'string' && type !== 'number') result[1][Element] = JSON.stringify(val); - }); - this.send(result[0], result[1] as obj); - }; - - private runAlias() { - const data = (loadConfigP('alias.json', {}) as obj)[this.data.message]; - if (!data || typeof data !== 'string') return; - this.data.message = data; - JSON.stringify(new Content(this.data, this.api, Content.consts)); - }; -} - -export default Content; diff --git a/modules1/alias/src/class/class.core.ts b/modules1/alias/src/class/class.core.ts deleted file mode 100644 index 6f2835ea..00000000 --- a/modules1/alias/src/class/class.core.ts +++ /dev/null @@ -1,160 +0,0 @@ -import { Locale } from '@/tools'; -import { ACCESS, CoreVal, SCOPE, CoreKeywordMatch, InfoArgEx, CoreKeyword, InfoVal, InfoArg, Hook } from '../type'; -import { temp } from '../method'; -import Command from './class.command'; -import Data from './class.data'; - -export class Core extends Data { - public static args: string[] = []; - - public static cmd(keyword: CoreKeyword, callback: CoreVal) { - const newKeyword = `/${keyword}`; - return this.alias(newKeyword, callback); - }; - - public static alias(keyword: CoreKeyword, callback: CoreVal) { - // if (!this.isInitialize) this.initialize(); - this.cmdData.set(keyword, callback); - const infoData: InfoVal = { - menuId: undefined, - help: undefined, - scope: SCOPE.ALL, - access: ACCESS.NORMAL, - params: undefined, - }; - this.cmdInfoData.set(keyword, infoData); - return new Command(keyword, infoData); - }; - - public static menu(keyword: CoreKeyword, menuId: string) { - const callback() this.menuHandle(menuId); - const main = menuId === 'main' ? '' : 'main'; - const { menuId: menuIdFun, help, scope, access } = this.cmd(keyword, callback).menuId(main); - return { - menuId: menuIdFun, - help, - scope, - access, - }; - }; - - public static custom(match: CoreKeywordMatch, callback: CoreVal) { - // if (!this.isInitialize) this.initialize(); - this.cmdData.set(match, callback); - }; - - public static auto(callback: () void) => { - this.autoEvent.push(callback); - }; - - public static hook(callback: Hook) { - Core.hookEvent.push(callback); - }; - - protected static autoEvent: (() => void)[] = []; - - protected static hookEvent: Hook[] = []; - - /* private static isInitialize: boolean = false; - - private static initialize() { - this.isInitialize = true; - if (CCOM.main) { - this.cmd(LMENU.main.cmd, LMENU.main.content); - } - for (const key of Object.keys(LMENU.customMenu)) { - const menu = (LMENU.customMenu as customMenu)[key]; - if (!menu.cmd || !menu.content) continue; - this.cmd(menu.cmd, menu.content); - } - }; */ - - private static menuHandle(menuId: string) { - let list = ''; - for (const key of this.cmdInfoData) { - const { 0: cmdKey, 1: value } = key; - if (value.menuId !== menuId || typeof cmdKey === 'function') continue; - list += this.menuHandleParams(cmdKey, value); - } - return temp('core.temp.menu', { - list, - }); - }; - - protected static menuHandleParams(key: CoreKeyword, value: InfoVal) { - let cmdName = Array.isArray(key) ? key[0] : key; - if (Array.isArray(key)) cmdName = `${cmdName} (${key.filter(val => val !== key[0]).join('|')})`; - let scope = ''; - if (value.scope !== SCOPE.ALL) { - scope = value.scope === SCOPE.GROUP ? 'core.temp.menu.scope.group' : 'core.temp.menu.scope.private'; - scope = Locale.locale(scope); - } - let access = ''; - if (value.access !== ACCESS.NORMAL) { - access = value.access === ACCESS.MANGER ? 'core.temp.menu.access.manger' : 'core.temp.menu.access.admin'; - access = Locale.locale(access); - } - let list = ''; - let handleParams = ''; - - /* type = InfoArg[] */ - if (Array.isArray(value.params) || !value.params) { - if (value.params) handleParams = this.menuHandleParamsArr(value.params); - return temp('core.temp.menu.list', { - name: cmdName, - param: handleParams, - help: value.help - ? temp('core.temp.menu.help', { - content: Locale.locale(value.help), - }) - : '', - scope, - access, - }); - } - - /* type = InfoArgEx */ - for (const param of Object.keys(value.params)) { - handleParams = ''; - const val = (value.params as InfoArgEx)[param]; - if (Array.isArray(val.args)) handleParams += this.menuHandleParamsArr(val.args); - list += temp('core.temp.menu.list', { - name: `${cmdName} ${param}`, - param: handleParams, - help: val.help - ? temp('core.temp.menu.help', { - content: Locale.locale(val.help), - }) - : '', - scope, - access, - }); - } - return list; - }; - - private static menuHandleParamsArr(params: InfoArg[]) { - let handleParams = ''; - params.forEach(element => { - const paramName = element.name ?? Locale.locale('core.temp.menu.param_name_default'); - const prefix = element.rest ? Locale.locale('core.temp.menu.prefix.rest') : ''; - let suffix = ''; - if (element.must !== true) { - suffix = - element.must === false - ? Locale.locale('core.temp.menu.suffix.optional') - : temp('core.temp.menu.suffix.default', { - content: element.must, - }); - } - handleParams += temp('core.temp.menu.param', { - param_name: paramName, - prefix, - suffix, - }); - }); - return handleParams; - }; -} - -export default Core; diff --git a/modules1/alias/src/class/class.data.ts b/modules1/alias/src/class/class.data.ts deleted file mode 100644 index c2211594..00000000 --- a/modules1/alias/src/class/class.data.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { CmdInfo, Cmd } from '../type'; - -export class Data { - protected static cmdData: Cmd = new Map(); - - protected static cmdInfoData: CmdInfo = new Map(); - - protected static isErroring = false; -} - -export default Data; diff --git a/modules1/alias/src/index.ts b/modules1/alias/src/index.ts deleted file mode 100644 index 1fb6e71e..00000000 --- a/modules1/alias/src/index.ts +++ /dev/null @@ -1,106 +0,0 @@ -/* - * @Author: hotaru biyuehuya@gmail.com - * @Blog: https://hotaru.icu - * @Date: 2023-07-11 14:18:27 - * @LastEditors: Hotaru biyuehuya@gmail.com - * @LastEditTime: 2023-09-03 17:26:30 - */ -import os from 'os'; -import path from 'path'; -import { existsSync } from 'fs'; -import type { EventDataType, Event, Api, Const, PackageInfo, PluginData, obj, EventMessageType } from '@/tools'; -import { - BotConfigFilter, - CONNECT_MODE, - CONST, - Locale, - LocaleIdentifier, - fetchJson, - formatTime, - getPackageInfo, - loadConfig, - saveConfig, - stringProcess, -} from '@/tools'; -import ProcessController from '@/tools/class/class.process'; -import { - dealCpu, - dealEnv, - dealRam, - dealTime, - fetchT, - formatOption, - initConfig, - loadConfigP, - saveConfigP, - setPath, - temp, -} from './method'; -import { ACCESS, BOT_RESULT, CoreVal, GLOBAL } from './type'; -import Core from './class/class.core'; -import Content from './class/class.content'; - -cmdCore('alias', () => { - const data = loadConfigP('alias.json', {}) as obj; - if (Core.args[1] === 'query') { - let list = ''; - Object.keys(data).forEach(key => { - list += temp('core.msg.alias.list', { - key, - val: data[key], - }); - }); - return temp('core.msg.alias.query', { - list: list || BOT_RESULT.EMPTY, - }); - } - if (Core.args[1] === 'add') { - if (data[Core.args[2]]) return BOT_RESULT.EXIST; - Core.args[3] = `/${Core.args[3]}`; - if (!Content.isUsefulCmd(Core.args[3].split(' ')[0], Core.args[3])) return 'core.msg.alias.fail.2'; - data[Core.args[2]] = Core.args[3]; - saveConfigP('alias.json', data); - return temp('core.msg.alias.add', { - input: Core.args[2], - }); - } - if (Core.args[1] === 'del') { - if (!data[Core.args[2]]) return BOT_RESULT.NO_EXIST; - delete data[Core.args[2]]; - saveConfigP('alias.json', data); - return temp('core.msg.alias.del', { - input: Core.args[2], - }); - } - return BOT_RESULT.ARGS_ERROR; -}) - .help('core.descr.alias') - .access(ACCESS.MANGER) - .params({ - query: { - help: 'core.descr.alias.query', - }, - add: { - help: 'core.descr.alias.add', - args: [ - { - must: true, - name: 'alias', - }, - { - must: true, - name: 'command', - rest: true, - }, - ], - }, - del: { - help: 'core.descr.alias.del', - args: [ - { - must: true, - name: 'alias', - }, - ], - }, - }); diff --git a/modules1/alias/src/method.ts b/modules1/alias/src/method.ts deleted file mode 100644 index fc1e3866..00000000 --- a/modules1/alias/src/method.ts +++ /dev/null @@ -1,122 +0,0 @@ -/* - * @Author: hotaru biyuehuya@gmail.com - * @Blog: https://hotaru.icu - * @Date: 2023-07-15 15:52:17 - * @LastEditors: hotaru biyuehuya@gmail.com - * @LastEditTime: 2023-08-21 18:39:27 - */ -import os from 'os'; -import { existsSync } from 'fs'; -import path from 'path'; -import { version as versionTs } from 'typescript'; -import { VERSION as versionTsnode } from 'ts-node'; -import { Locale, fetchJson, fetchText, loadConfig, saveConfig, stringTemp } from '@/tools'; -import type { FuncFetchSuper, FuncStringProcessStr, obj } from '@/tools'; -import SDK from '@/utils/class.sdk'; -import { BOT_RESULT, GLOBAL, URL } from './type'; - -export const dealTime() { - const seconds = Math.floor(os.uptime()); - let day: FuncStringProcessStr = Math.floor(seconds / (3600 * 24)); - let hours: FuncStringProcessStr = Math.floor((seconds - day * 3600 * 24) / 3600); - let minutes: FuncStringProcessStr = Math.floor((seconds - day * 3600 * 24 - hours * 3600) / 60); - let second: FuncStringProcessStr = seconds % 60; - - if (day < 10) { - day = `0${day}`; - } - - if (hours < 10) { - hours = `0${hours}`; - } - - if (minutes < 10) { - minutes = `0${minutes}`; - } - - if (second < 10) { - second = `0${second}`; - } - - return [day, hours, minutes, second].join(':'); -}; - -export const dealRam() { - const total = os.totalmem() / 1024 / 1024 / 1024; - const unused = os.freemem() / 1024 / 1024 / 1024; - const used = total - unused; - const rate = (used / total) * 100; - return { - total, - unused, - used, - rate, - }; -}; - -export const dealCpu() { - const cpuData = os.cpus(); - let rate: number = 0; - const ratearr: number[] = []; - cpuData.forEach(key => { - const { times } = key; - const usage = (1 - times.idle / (times.idle + times.user + times.nice + times.sys + times.irq)) * 100; - ratearr.push(usage); - rate += usage; - }); - return { - model: cpuData[0].model, - speed: cpuData[0].speed / 1024, - num: cpuData.length, - rate, - ratearr, - }; -}; - -export const dealEnv() ({ - node: process.versions.node, - typescript: versionTs, - tsnode: versionTsnode, -}); - -export const initConfig(filePath: string) { - const banword = path.join(filePath, 'banword.json'); - const banwordDefault = ['傻逼', '草拟吗', 'cnm', '死妈']; - if (!existsSync(banword)) saveConfig(banword, banwordDefault); -}; - -let CONFIG_PLUGIN_PATH: string; -export const setPath(value: string) { - CONFIG_PLUGIN_PATH = value; -}; - -export const loadConfigP = (filename: string, init: object = []): object => { - const PATH = path.join(CONFIG_PLUGIN_PATH, filename); - return (loadConfig(PATH, 'json', init) as object) || init; -}; - -export const saveConfigP(filename: string, content: object) { - const PATH = path.join(CONFIG_PLUGIN_PATH, filename); - return saveConfig(PATH, content); -}; - -export const fetchJ: FuncFetchSuper = async (url, params, init) => { - const result = fetchJson(url.substring(0, 4) === 'http' ? url : URL.API + url, params, init); - return result; -}; - -export const fetchT: FuncFetchSuper = async (url, params, init) => { - const result = fetchText(url.substring(0, 4) === 'http' ? url : URL.API + url, params, init); - return result; -}; - -export const temp(message: string, params: obj) { - let msg = Locale.locale(message); - msg = stringTemp(msg, GLOBAL); - msg = stringTemp(msg, BOT_RESULT); - return stringTemp(msg, params); -}; - -export const getQq(msg: string) (msg ? SDK.get_at(msg) || parseInt(msg, 10) : null); - -export const formatOption(option: boolean) (option ? BOT_RESULT.OPTION_ON : BOT_RESULT.OPTION_OFF); diff --git a/modules1/alias/src/type.ts b/modules1/alias/src/type.ts deleted file mode 100644 index daa786bb..00000000 --- a/modules1/alias/src/type.ts +++ /dev/null @@ -1,102 +0,0 @@ -import { Locale, getPackageInfo } from '@/tools'; -import { Api, EventDataType, Msg, obj } from '@/tools/type'; -import SDK from '@/utils/class.sdk'; - -export const enum SCOPE { - ALL, - PRIVATE, - GROUP, -} - -export const enum ACCESS { - NORMAL, - MANGER, - ADMIN, -} - -export const enum URL { - API = 'https://api.hotaru.icu/api/', - BLOG = 'https://hotaru.icu/api/', -} - -export const BOT_RESULT = new Proxy( - { - GUIDE: 'core.temp.result.guide', - SERVER_ERROR: 'core.temp.result.data_error', - ARGS_EMPTY: 'core.temp.result.args.empty', - ARGS_ERROR: 'core.temp.result.args.error', - UNKNOWN_ERROR: 'core.temp.result.unknown_error', - NUM_ERROR: 'core.temp.result.num.error', - NUM_CHOOSE: 'core.temp.result.num.choose', - NO_ACCESS_1: 'core.temp.result.no_access.1', - NO_ACCESS_2: 'core.temp.result.no_access.2', - DISABLE: 'core.temp.result.disable', - EXIST: 'core.temp.result.exist', - NO_EXIST: 'core.temp.result.no_esist', - REPAIRING: 'core.temp.result.repairing', - APIKEY_EMPTY: 'core.temp.result.apikey_error', - EMPTY: 'core.temp.result.empty', - MESSAGE_TYPE: 'core.temp.result.message_type', - OPTION_ON: 'core.temp.result.option.on', - OPTION_OFF: 'core.temp.result.option.off', - }, - { - get(origin, target): string { - if (typeof target === 'symbol') return ''; - return Locale.locale(origin[target as keyof typeof origin]); - }, - }, -); - -export const GLOBAL = { - HEAD: 'Kotori-Bot:', - REPO: 'https://github.com/kotorijs/kotori', - AVATAR: SDK.cq_image(`https://q.qlogo.cn/headimg_dl?spec=640&dst_uin=2142124427`), - DOC: 'http://??????????.com', - AUTHOR: `By ${getPackageInfo().author}`, -}; - -export type CoreKeyword = string | string[]; -export type CoreKeywordMatch(str: string) boolean; -export type CoreVal = CoreValCallback | string; -export type CoreValCallback(send: Send, data: EventDataType) CoreValCallbackVal | Promise; -export type CoreValCallbackVal = void | string | [string, obj]; -export type Cmd = Map; -export type CmdInfo = Cmd; -export type InfoValArg = InfoArg[] | InfoArgEx; -export type Hook(data: EventDataType, send: Send, api: Api) boolean; -export type Send(msg: Msg, params?: obj) void; - -export interface InfoVal { - params?: InfoValArg; - help?: string; - menuId?: string; - scope: SCOPE; - access: ACCESS; -} - -export interface InfoArg { - must: boolean | string; - name?: string; - rest?: boolean; -} - -export interface InfoArgEx { - [key: string]: { - help?: string; - args?: InfoArg[] /* | InfoArgEx */ | null; - }; -} - -export type dataType = string | number | boolean | obj | string[] | number[] | obj[]; - -export interface Res extends obj { - code: 500 | 501 | 502; - message?: string; - data?: T; -} - -export interface ResAfter extends Res { - code: 500; - data: dataType; -} diff --git a/modules1/daytool/README.md b/modules1/daytool/README.md deleted file mode 100644 index 2821e074..00000000 --- a/modules1/daytool/README.md +++ /dev/null @@ -1,42 +0,0 @@ -# DayTool - -Day Tools Base For Core - -**Version:** 1.0.0 -**Author:** himeno -**License:** GPL-3.0 - -## List of command - -- /days - Daily tools -- /music - NetEase Cloud music, default song no. is 1, enter 0 to show song list -- /bili - Bilibili video info query -- /bilier - Bilibili User Information Query -- /bgm - Search games/anime on Bangumi -- /bgmc - Get today's Bangumi schedule -- /star - Check today's horoscope -- /tran <...content> - Translate between Chinese and other languages -- /lunar - Check lunar calendar -- /story - Today in history -- /luck - Check QQ luck -- /value - Check QQ valuation -- /weather - Check weather -- /waste - Garbage classification - -## Config - -```ts -export default { - bangumi: { - apiKey: '', - }, - maxList: 10, -}; -``` - -## Lang Support - -- ja_JP -- en_US -- zh_TW -- zh_CN diff --git a/modules1/daytool/locales/en_US.json b/modules1/daytool/locales/en_US.json deleted file mode 100644 index a971f722..00000000 --- a/modules1/daytool/locales/en_US.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "daytool.descr.music": "NetEase Cloud music, default song no. is 1, enter 0 to show song list", - "daytool.msg.music": "Song ID: %songid%\nSong Title: %title%\nSong Author: %author%\nSong Download: %url%\nSong Cover: %image%", - "daytool.msg.music.list": "%num%.%title% - %author%\n", - "daytool.msg.music.lists": "%list%%NUM_CHOOSE%", - "daytool.msg.music.fail": "Song not found: %input%", - "daytool.descr.bili": "Bilibili video info query", - "daytool.msg.bili": "BV number: %id%\nVideo title: %title%\nVideo description: %description%\nAuthor: %name%\nCategory: %sort%\nPublished time: %time%\nView count: %view%\nCoin count: %coin%\nLike count: %like%\nFavorite count: %collect%\nThumbnail: %image%", - "daytool.msg.bili.fail": "Video not found: %input%", - "daytool.descr.bilier": "Bilibili User Information Query", - "daytool.msg.bilier": "UID: %uid%\nName: %name%\nLevel: LV%level%\nGender: %sex%\nIntroduction: %description%\nFollowing count: %following%\nFollower count: %follower%\nAvatar: %image%", - "daytool.msg.bilier.fail": "User not found: %uid%", - "daytool.descr.bgm": "Search games/anime on Bangumi", - "daytool.msg.bgm": "Original Name: %name%\nChinese Name: %name_cn%\nSummary: %summary%\nTags: %tags%\nDetails: %url%\n%image%", - "daytool.msg.bgm.list": "%num%.%name%%name_cn%\n", - "daytool.msg.bgm.lists": "%list%%NUM_CHOOSE%", - "daytool.msg.bgm.fail": "No matching items found: %input%", - "daytool.descr.bgmc": "Get today's Bangumi schedule", - "daytool.msg.bgmc": "Date: %weekday%~%list%", - "daytool.msg.bgmc.list": "\nOriginal Name: %name%\nChinese Name: %name_cn%\nAir Time: %air_date%\n%image%", - "daytool.descr.star": "Check today's horoscope", - "daytool.msg.star": "%input% today's horoscope: %list%", - "daytool.msg.star.list": "\n%content%", - "daytool.msg.star.fail": "Invalid zodiac sign: %input%", - "daytool.descr.tran": "Translate between Chinese and other languages", - "daytool.msg.tran": "Original: %input%\nTranslation: %content%", - "daytool.descr.lunar": "Check lunar calendar", - "daytool.msg.lunar": "%content%", - "daytool.descr.story": "Today in history", - "daytool.msg.story": "Today in history%list%", - "daytool.msg.story.list": "\n%content%", - "daytool.descr.luck": "Check QQ luck", - "daytool.msg.luck": "QQ: %input%\nLuck: %luck%\nPersonality Type: %character%\nPersonality Score: %character_score%", - "daytool.descr.value": "Check QQ valuation", - "daytool.msg.value": "%image%", - "daytool.descr.weather": "Check weather", - "daytool.msg.weather": "%content%", - "daytool.descr.waste": "Garbage classification", - "daytool.msg.waste": "Item: %input%\nType: %type%", - "daytool.msg.waste.key.0": "Unknown garbage", - "daytool.msg.waste.key.1": "Recyclable garbage", - "daytool.msg.waste.key.2": "Hazardous garbage", - "daytool.msg.waste.key.3": "Wet garbage", - "daytool.msg.waste.key.4": "Dry garbage", - "daytool.msg.waste.key.5": "Construction garbage" -} \ No newline at end of file diff --git a/modules1/daytool/locales/ja_JP.json b/modules1/daytool/locales/ja_JP.json deleted file mode 100644 index 133ae37c..00000000 --- a/modules1/daytool/locales/ja_JP.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "daytool.descr.music": "NetEaseクラウドミュージック、デフォルトの曲番号は1、曲リストを表示するには0を入力", - "daytool.msg.music": "楽曲ID: %songid%\n曲名: %title%\nアーティスト: %author%\nダウンロード: %url%\nジャケット: %image%", - "daytool.msg.music.list": "%num%.%title% - %author%\n", - "daytool.msg.music.lists": "%list%%NUM_CHOOSE%", - "daytool.msg.music.fail": "楽曲が見つかりません: %input%", - "daytool.descr.bili": "Bilibiliの動画情報検索", - "daytool.msg.bili": "BV番号: %id%\n動画タイトル: %title%\n動画概要: %description%\n作者: %name%\n分類: %sort%\n公開日: %time%\n再生数: %view%\n投げ銭数: %coin%\n高評価数: %like%\n保存数: %collect%\nサムネイル: %image%", - "daytool.msg.bili.fail": "動画が見つかりません: %input%", - "daytool.descr.bilier": "Bilibiliユーザ情報照会", - "daytool.msg.bilier": "UID: %uid%\n名前: %name%\nランク: LV%level%\n性別: %sex%\n自己紹介: %description%\nフォロー数: %following%\nフォロワー数: %follower%\nアイコン画像: %image%", - "daytool.msg.bilier.fail": "ユーザーが見つかりません: %uid%", - "daytool.descr.bgm": "Bangumiでゲーム/アニメを検索", - "daytool.msg.bgm": "オリジナル名: %name%\n中国語名: %name_cn%\n概要: %summary%\nタグ: %tags%\n詳細: %url%\n%image%", - "daytool.msg.bgm.list": "%num%.%name%%name_cn%\n", - "daytool.msg.bgm.lists": "%list%%NUM_CHOOSE%", - "daytool.msg.bgm.fail": "一致するアイテムが見つかりません: %input%", - "daytool.descr.bgmc": "今日のBangumiの番組表を取得", - "daytool.msg.bgmc": "日付: %weekday%~%list%", - "daytool.msg.bgmc.list": "\nオリジナル名: %name%\n中国語名: %name_cn%\n放送時間: %air_date%\n%image%", - "daytool.descr.star": "今日の占いをチェック", - "daytool.msg.star": "%input%の今日の運勢: %list%", - "daytool.msg.star.list": "\n%content%", - "daytool.msg.star.fail": "無効な星座: %input%", - "daytool.descr.tran": "中国語と他言語間の翻訳", - "daytool.msg.tran": "元の言語: %input%\n翻訳: %content%", - "daytool.descr.lunar": "旧暦を確認", - "daytool.msg.lunar": "%content%", - "daytool.descr.story": "今日の出来事", - "daytool.msg.story": "今日の出来事%list%", - "daytool.msg.story.list": "\n%content%", - "daytool.descr.luck": "QQの運勢をチェック", - "daytool.msg.luck": "QQ: %input%\n運勢: %luck%\n個性タイプ: %character%\n個性スコア: %character_score%", - "daytool.descr.value": "QQの価値を確認", - "daytool.msg.value": "%image%", - "daytool.descr.weather": "天気を確認", - "daytool.msg.weather": "%content%", - "daytool.msg.waste": "品目: %input%\n種類: %type%", - "daytool.msg.waste.key.0": "不明なゴミ", - "daytool.msg.waste.key.1": "リサイクルゴミ", - "daytool.msg.waste.key.2": "有害ゴミ", - "daytool.msg.waste.key.3": "湿ったゴミ", - "daytool.msg.waste.key.4": "乾いたゴミ", - "daytool.msg.waste.key.5": "建設ゴミ" -} \ No newline at end of file diff --git a/modules1/daytool/locales/zh_CN.json b/modules1/daytool/locales/zh_CN.json deleted file mode 100644 index 2595a812..00000000 --- a/modules1/daytool/locales/zh_CN.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "daytool.descr.music": "网易云点歌,序号默认为1,填0显示歌曲列表", - "daytool.msg.music": "歌曲ID: %songid%\n歌曲标题: %title%\n歌曲作者: %author%\n歌曲下载: %url%\n歌曲封面: %image%", - "daytool.msg.music.list": "%num%。%title% - %author%\n", - "daytool.msg.music.lists": "%list%%NUM_CHOOSE%", - "daytool.msg.music.fail": "未找到相关歌曲: %input%", - "daytool.descr.bili": "B站视频信息查询", - "daytool.msg.bili": "BV号: %id%\n视频标题: %title%\n视频简介: %description%\n作者: %name%\n分类: %sort%\n发布时间: %time%\n播放量: %view%\n投币数: %coin%\n点赞数: %like%\n收藏数: %collect%\n视频封面: %image%", - "daytool.msg.bili.fail": "未找到该视频: %input%", - "daytool.descr.bilier": "B站用户信息查询", - "daytool.msg.bilier": "UID: %uid%\n名字: %name%\n等级: LV%level%\n性别: %sex%\n简介: %description%\n关注数: %following%\n粉丝数: %follower%\n头像: %image%", - "daytool.msg.bilier.fail": "未找到该用户: %uid%", - "daytool.descr.bgm": "翻组计划搜索游戏/动漫", - "daytool.msg.bgm": "原名: %name%\n中文名: %name_cn%\n介绍: %summary%\n标签: %tags%\n详情: %url%\n%image%", - "daytool.msg.bgm.list": "%num%。%name%%name_cn%\n", - "daytool.msg.bgm.lists": "%list%%NUM_CHOOSE%", - "daytool.msg.bgm.fail": "未找到相关条目: %input%", - "daytool.descr.bgmc": "获取番组计划今日放送", - "daytool.msg.bgmc": "日期: %weekday%~%list%", - "daytool.msg.bgmc.list": "\n原名: %name%\n中文名: %name_cn%\n开播时间: %air_date%\n%image%", - "daytool.descr.star": "查看今日星座运势", - "daytool.msg.star": "%input%今日运势: %list%", - "daytool.msg.star.list": "\n%content%", - "daytool.msg.star.fail": "星座错误: %input%", - "daytool.descr.tran": "中外互译", - "daytool.msg.tran": "原文: %input%\n译文: %content%", - "daytool.descr.lunar": "查看农历", - "daytool.msg.lunar": "%content%", - "daytool.descr.story": "查看历史上的今天", - "daytool.msg.story": "历史上的今天%list%", - "daytool.msg.story.list": "\n%content%", - "daytool.descr.luck": "查看QQ凶吉", - "daytool.msg.luck": "QQ: %input%\n运势: %luck%\n性格类型: %character%\n性格系数: %character_score%", - "daytool.descr.value": "查看QQ估价", - "daytool.msg.value": "%image%", - "daytool.descr.weather": "查看天气", - "daytool.msg.weather": "%content%", - "daytool.descr.waste": "查看垃圾分类", - "daytool.msg.waste": "物品: %input%\n类型: %type%", - "daytool.msg.waste.key.0": "未知垃圾", - "daytool.msg.waste.key.1": "可回收垃圾", - "daytool.msg.waste.key.2": "有害垃圾", - "daytool.msg.waste.key.3": "湿垃圾", - "daytool.msg.waste.key.4": "干垃圾", - "daytool.msg.waste.key.5": "装修垃圾" -} \ No newline at end of file diff --git a/modules1/daytool/locales/zh_TW.json b/modules1/daytool/locales/zh_TW.json deleted file mode 100644 index 4ee50b51..00000000 --- a/modules1/daytool/locales/zh_TW.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "daytool.descr.music": "網易雲點歌,序號默認為1,填0顯示歌曲列表", - "daytool.msg.music": "歌曲ID: %songid%\n歌曲標題: %title%\n歌曲作者: %author%\n歌曲下載: %url%\n歌曲封面: %image%", - "daytool.msg.music.list": "%num%。%title% - %author%\n", - "daytool.msg.music.lists": "%list%%NUM_CHOOSE%", - "daytool.msg.music.fail": "未找到相關歌曲: %input%", - "daytool.descr.bili": "B站視頻信息查詢", - "daytool.msg.bili": "BV號: %id%\n視頻標題: %title%\n視頻簡介: %description%\n作者: %name%\n分類: %sort%\n發布時間: %time%\n播放量: %view%\n投幣數: %coin%\n點贊數: %like%\n收藏數: %collect%\n視頻封面: %image%", - "daytool.msg.bili.fail": "未找到該視頻: %input%", - "daytool.descr.bilier": "B站用戶信息查詢", - "daytool.msg.bilier": "UID: %uid%\n名字: %name%\n等級: LV%level%\n性別: %sex%\n簡介: %description%\n關註數: %following%\n粉絲數: %follower%\n頭像: %image%", - "daytool.msg.bilier.fail": "未找到該用戶: %uid%", - "daytool.descr.bgm": "翻組計劃搜索遊戲/動漫", - "daytool.msg.bgm": "原名: %name%\n中文名: %name_cn%\n介紹: %summary%\n標簽: %tags%\n詳情: %url%\n%image%", - "daytool.msg.bgm.list": "%num%。%name%%name_cn%\n", - "daytool.msg.bgm.lists": "%list%%NUM_CHOOSE%", - "daytool.msg.bgm.fail": "未找到相關條目: %input%", - "daytool.descr.bgmc": "獲取番組計劃今日放送", - "daytool.msg.bgmc": "日期: %weekday%~%list%", - "daytool.msg.bgmc.list": "\n原名: %name%\n中文名: %name_cn%\n開播時間: %air_date%\n%image%", - "daytool.descr.star": "查看今日星座運勢", - "daytool.msg.star": "%input%今日運勢: %list%", - "daytool.msg.star.list": "\n%content%", - "daytool.msg.star.fail": "星座錯誤: %input%", - "daytool.descr.tran": "中外互譯", - "daytool.msg.tran": "原文: %input%\n譯文: %content%", - "daytool.descr.lunar": "查看農歷", - "daytool.msg.lunar": "%content%", - "daytool.descr.story": "查看歷史上的今天", - "daytool.msg.story": "歷史上的今天%list%", - "daytool.msg.story.list": "\n%content%", - "daytool.descr.luck": "查看QQ兇吉", - "daytool.msg.luck": "QQ: %input%\n運勢: %luck%\n性格類型: %character%\n性格系數: %character_score%", - "daytool.descr.value": "查看QQ估價", - "daytool.msg.value": "%image%", - "daytool.descr.weather": "查看天氣", - "daytool.msg.weather": "%content%", - "daytool.descr.waste": "查看垃圾分類", - "daytool.msg.waste": "物品: %input%\n類型: %type%", - "daytool.msg.waste.key.0": "未知垃圾", - "daytool.msg.waste.key.1": "可回收垃圾", - "daytool.msg.waste.key.2": "有害垃圾", - "daytool.msg.waste.key.3": "濕垃圾", - "daytool.msg.waste.key.4": "幹垃圾", - "daytool.msg.waste.key.5": "裝修垃圾" -} \ No newline at end of file diff --git a/modules1/daytool/manifest.json b/modules1/daytool/manifest.json deleted file mode 100644 index 4ae82d1f..00000000 --- a/modules1/daytool/manifest.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "DayTool", - "description": "Day Tools Base For Core", - "version": "1.0.0", - "author": "himeno", - "license": "GPL-3.0" -} diff --git a/modules1/daytool/package1.json b/modules1/daytool/package1.json deleted file mode 100644 index 7aa54171..00000000 --- a/modules1/daytool/package1.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "kotori-plugin-testing", - "version": "1.0.0", - "description": "testing plugin", - "main": "src/index.ts", - "license": "GPL-3.0", - "author": "Hotaru ", - "peerDependencies": { - "kotori-bot": "workspace:^" - } -} \ No newline at end of file diff --git a/modules1/daytool/src/config.ts b/modules1/daytool/src/config.ts deleted file mode 100644 index 8d829d96..00000000 --- a/modules1/daytool/src/config.ts +++ /dev/null @@ -1,6 +0,0 @@ -export default { - bangumi: { - apiKey: 'iugKW0Wvby5bNFhz8HY1po2Mn0eiIMl1z0HjpPQN', - }, - maxList: 10, -}; diff --git a/modules1/daytool/src/index.ts b/modules1/daytool/src/index.ts deleted file mode 100644 index c29f1e0a..00000000 --- a/modules1/daytool/src/index.ts +++ /dev/null @@ -1,89 +0,0 @@ -import path from 'path'; -import { Cache, Core, fetchT, getQq, temp } from 'plugins/kotori-core'; -import { fetchJ } from 'plugins/kotori-core/method'; -import { BOT_RESULT, CoreVal } from 'plugins/kotori-core/type'; -import cheerio from 'cheerio'; -import { Locale, formatTime, isObj, obj } from '@/tools'; -import SDK from '@/utils/class.sdk'; -import { fetchBGM } from './method'; -import config from './config'; - -const { maxList } = config; - -Locale.register(path.resolve(__dirname)); - -Kotori.command('star') - .action(async () => { - const res = await fetchJ('starluck', { msg: data.args[0] }); - if (!isObj(res)) return [BOT_RESULT.SERVER_ERROR, { res }]; - if (res.code === 501 || !isObj(res.data)) return ['daytool.msg.star.fail', { input: data.args[0] }]; - - if (!Array.isArray(res.data.info) || !Array.isArray(res.data.index)) - return [BOT_RESULT.SERVER_ERROR, { res: res.data }]; - - let list = ''; - res.data.info.forEach((content: string) => { - list += temp('daytool.msg.star.list', { - content, - }); - }); - res.data.index.forEach((content: string) => { - list += temp('daytool.msg.star.list', { - content, - }); - }); - return [ - 'daytool.msg.star', - { - input: data.args[0], - list, - }, - ]; - }) - .help('daytool.descr.star') - .params([ - { - must: true, - name: 'starName', - }, - ]); - -Kotori.command('tran') - .action(async () => { - const res = await fetchJ('fanyi', { msg: data.args[0] }); - const result = res && res.code === 500 && typeof res.data === 'string'; - return [ - result ? 'daytool.msg.tran' : BOT_RESULT.SERVER_ERROR, - result ? { input: data.args[0], content: res.data } : { res }, - ]; - }) - .help('daytool.descr.tran') - .params([ - { - must: true, - name: 'content', - rest: true, - }, - ]); - -Kotori.command('lunar') - .action(async () => { - const res = await fetchT('lunar'); - return [res ? 'daytool.msg.lunar' : BOT_RESULT.SERVER_ERROR, res ? { content: res } : { res }]; - }) - .help('daytool.descr.lunar'); - -Kotori.command('story') - .action(async () => { - const res = await fetchJ('storytoday'); - if (!res || res.code !== 500 || !Array.isArray(res.data)) return [BOT_RESULT.SERVER_ERROR, res]; - - let list = ''; - (res.data as string[]).forEach(content => { - list += temp('daytool.msg.story.list', { - content, - }); - }); - return ['daytool.msg.story', { list }]; - }) - .help('daytool.descr.story'); diff --git a/modules1/daytool/src/method.ts b/modules1/daytool/src/method.ts deleted file mode 100644 index 4d024ce9..00000000 --- a/modules1/daytool/src/method.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { FuncFetchSuper, fetchJson, obj } from '@/tools'; -import config from './config'; - -export const fetchBGM: FuncFetchSuper = async (url, params) => { - const newParams = { ...params, token: config.bangumi.apiKey }; - return fetchJson(`https://api.bgm.tv/${url}`, newParams, { - headers: { - 'user-agent': 'czy0729/Bangumi/6.4.0 (Android) (http://github.com/czy0729/Bangumi)', - }, - }); -}; -export const a = {}; diff --git a/modules1/minecraft/locales/en_US.json b/modules1/minecraft/locales/en_US.json deleted file mode 100644 index d8597728..00000000 --- a/modules1/minecraft/locales/en_US.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "querytool.descr.motd": "MCJE server info query", - "querytool.descr.motdbe": "MCBE server info query", - "querytool.descr.mcskin": "MC legit account skin query", - "querytool.descr.mcv": "Query Minecraft version info", - "querytool.msg.motd": "Status: Online\nIP: %real%\nPort: %port%\nPhysical address: %location%\nMOTD: %motd%\nProtocol version: %agreement%\nGame version: %version%\nOnline players: %online% / %max%\nLatency: %ping%ms\nIcon: %image%", - "querytool.msg.motd.fail": "Status: Offline\nIP: %ip%\nPort: %port%", - "querytool.msg.motdbe": "Status: Online\nIP: %real%\nPort: %port%\nPhysical address: %location%\nMOTD: %motd%\nGame mode: %gamemode%\nProtocol version: %agreement%\nGame version: %version%\nOnline players: %online% / %max%\nLatency: %delay%ms", - "querytool.msg.motdbe.fail": "Status: Offline\nIP: %ip%\nPort: %port%", - "querytool.msg.mcskin": "Player: %input%\nSkin: %skin%\nCape: %cape%\nHead: %avatar%", - "querytool.msg.mcskin.fail": "%input% player not found!", - "querytool.msg.mcv": "Minecraft Java:\nLatest release: %release%\nRelease date: %releaseDate%\nLatest snapshot: %snapshot%\nRelease date: %snapshotDate%\nMinecraft Bedrock:\nLatest version: %mcbe%\nRelease date: %mcbeDate%" -} \ No newline at end of file diff --git a/modules1/minecraft/locales/ja_JP.json b/modules1/minecraft/locales/ja_JP.json deleted file mode 100644 index a5cbec56..00000000 --- a/modules1/minecraft/locales/ja_JP.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "querytool.descr.motd": "MCJEサーバー情報検索", - "querytool.descr.motdbe": "MCBEサーバー情報検索", - "querytool.descr.mcskin": "MC正規アカウントスキン検索", - "querytool.descr.mcv": "Minecraftのバージョン情報を問い合わせる", - "querytool.msg.motd": "ステータス: オンライン\nIP: %real%\nポート: %port%\n物理アドレス: %location%\nMOTD: %motd%\nプロトコルバージョン: %agreement%\nゲームバージョン: %version%\nオンラインプレイヤー数: %online% / %max%\nレイテンシ: %ping%ms\nアイコン: %image%", - "querytool.msg.motd.fail": "ステータス: オフライン\nIP: %ip%\nポート: %port%", - "querytool.msg.motdbe": "ステータス: オンライン\nIP: %real%\nポート: %port%\n物理アドレス: %location%\nMOTD: %motd%\nゲームモード: %gamemode%\nプロトコルバージョン: %agreement%\nゲームバージョン: %version%\nオンラインプレイヤー数: %online% / %max%\nレイテンシ: %delay%ms", - "querytool.msg.motdbe.fail": "ステータス: オフライン\nIP: %ip%\nポート: %port%", - "querytool.msg.mcskin": "プレイヤー: %input%\nスキン: %skin%\nマント: %cape%\n頭: %avatar%", - "querytool.msg.mcskin.fail": "%input% というプレイヤーはいません!", - "querytool.msg.mcv": "Minecraft Java:\n最新リリース: %release%\nリリース日: %releaseDate%\n最新スナップショット: %snapshot%\nリリース日: %snapshotDate%\nMinecraft Bedrock:\n最新バージョン: %mcbe%\nリリース日: %mcbeDate%" -} \ No newline at end of file diff --git a/modules1/minecraft/locales/zh_CN.json b/modules1/minecraft/locales/zh_CN.json deleted file mode 100644 index edf00bec..00000000 --- a/modules1/minecraft/locales/zh_CN.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "minecraft.descr.motd": "MCJE服务器信息查询", - "minecraft.descr.motdbe": "MCBE服务器信息查询", - "minecraft.descr.mcskin": "MC正版账号皮肤查询", - "minecraft.descr.mcv": "查询Minecraft版本信息", - "minecraft.msg.motd": "状态: 在线\nIP: %real%\n端口: %port%\n物理地址: %location%\nMOTD: %motd%\n协议版本: %agreement%\n游戏版本: %version%\n在线人数: %online% / %max%\n延迟: %ping%ms\n图标: %image%", - "minecraft.msg.motd.fail": "状态: 离线\nIP: %ip%\n端口: %port%", - "minecraft.msg.motdbe": "状态: 在线\nIP: %real%\n端口: %port%\n物理地址: %location%\nMOTD: %motd%\n游戏模式: %gamemode%\n协议版本: %agreement%\n游戏版本: %version%\n在线人数: %online% / %max%\n延迟: %delay%ms", - "minecraft.msg.motdbe.fail": "状态: 离线\nIP: %ip%\n端口: %port%", - "minecraft.msg.mcskin": "玩家: %input%\n皮肤: %skin%\n披风: %cape%\n头颅: %avatar%", - "minecraft.msg.mcskin.fail": "%input%查无此人!", - "minecraft.msg.mcv": "MinecraftJava:\n最新版: %release%\n发布时间: %releaseDate%\n最新快照: %snapshot%\n发布时间: %snapshotDate%\nMinecraftBedrock:\n最新版: %mcbe%\n发布时间: %mcbeDate%" -} \ No newline at end of file diff --git a/modules1/minecraft/src/index.ts b/modules1/minecraft/src/index.ts deleted file mode 100644 index 36d3c1ad..00000000 --- a/modules1/minecraft/src/index.ts +++ /dev/null @@ -1,109 +0,0 @@ -import { formatTime, Context } from 'kotori-bot'; - -export const lang = [__dirname, '../locales']; - -export function main(ctx: Context) { - ctx - .command('motd') - .action(async data => { - const res = await ctx.http.get('https://api.hotaru.icu/api/motd', { ip: data.args[0], port: data.args[1] }); - if (!isObj(res)) return ['BOT_RESULT.SERVER_ERROR', { res }]; - if ((res.code !== 500 && typeof res.code === 'number') || !isObj(res.data)) { - return [ - 'minecraft.msg.motd.fail', - { - ip: data.args[0], - port: data.args[1], - }, - ]; - } - - return [ - 'minecraft.msg.motd', - { - ...res.data, - image: typeof res.data.icon === 'string' ? image(`base64://${res.data.icon.substring(22)}`) : '', - }, - ]; - }) - .help('minecraft.descr.motd'); - - ctx - .command('motdbe') - .action(async data => { - const res = await ctx.http.get('https://api.hotaru.icu/api/motdpe', { ip: data.args[0], port: data.args[1] }); - if (!isObj(res)) return ['BOT_RESULT.SERVER_ERROR', { res }]; - if ((res.code !== 500 && typeof res.code === 'number') || !isObj(res.data)) { - return [ - 'minecraft.msg.motdbe.fail', - { - ip: data.args[0], - port: data.args[1], - }, - ]; - } - - return [ - 'minecraft.msg.motdbe', - { - ...res.data, - }, - ]; - }) - .help('minecraft.descr.motdbe'); - - ctx - .command('mcskin') - .action(async data => { - const res = await ctx.http.get('https://api.hotaru.icu/api/mcskin', { name: data.args[0] }); - if (!isObj(res)) return ['BOT_RESULT.SERVER_ERROR', { res }]; - if (res.code === 502 || !isObj(res.data)) return ['minecraft.msg.mcskin.fail', { input: data.args[0] }]; - - return [ - 'minecraft.msg.mcskin', - { - input: data.args[0], - skin: image(res.data.skin), - cape: res.data.cape ? image(res.data.cape) : '', - avatar: res.data.avatar ? image(`base64://${res.data.avatar.substring(22)}`) : '', - }, - ]; - }) - .help('minecraft.descr.mcskin'); - - ctx - .command('mcv') - .action(async () => { - const res = await ctx.http.get('https://piston-meta.mojang.com/mc/game/version_manifest.json'); - if (!res || !res.latest || !Array.isArray(res.versions)) return 'BOT_RESULT.SERVER_ERROR'; - const res2 = await ctx.http.get('https://bugs.mojang.com/rest/api/2/project/10200/versions'); - if (!res2 || !Array.isArray(res2)) return 'BOT_RESULT.SERVER_ERROR'; - const date = { - releaseDate: '', - snapshotDate: '', - mcbe: '', - mcbeDate: '', - }; - let count = 0; - for (const element of res.versions) { - count += 1; - if (count > 100) break; - if (date.releaseDate && date.snapshotDate) break; - if (element.id === res.latest.release) { - date.releaseDate = formatTime(new Date(element.releaseTime)); - continue; - } - if (element.id === res.latest.snapshot) date.snapshotDate = formatTime(new Date(element.releaseTime)); - } - for (const element of res2) { - if (count > 100) break; - if (!element.releaseDate) continue; - date.mcbe = element.name; - date.mcbeDate = formatTime(new Date(element.releaseDate)); - break; - } - - return ['minecraft.msg.mcv', { ...res.latest, ...date }]; - }) - .help('minecraft.descr.mcv'); -} diff --git a/modules1/minecraft/tsconfig.json b/modules1/minecraft/tsconfig.json deleted file mode 100644 index 785c6f76..00000000 --- a/modules1/minecraft/tsconfig.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "extends": "../../tsconfig.node.json", - "references": [ - { - "path": "../kotori" - } - ] -} \ No newline at end of file diff --git a/modules1/querytool/locales/en_US.json b/modules1/querytool/locales/en_US.json deleted file mode 100644 index 4cb1b407..00000000 --- a/modules1/querytool/locales/en_US.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "querytool.descr.github": "Query Github repository info", - "querytool.msg.github": "URL: %name%\nDescription: %description%\nLanguage: %language%\nOwner: %author%\nCreated: %create%\nLast updated: %update%\nLast push: %push%\nOpen source license: %license%", - "querytool.msg.github.image": "%image%", - "querytool.msg.github.fail": "Repository not found: %input%", - "querytool.descr.motd": "MCJE server info query", - "querytool.msg.motd": "Status: Online\nIP: %real%\nPort: %port%\nPhysical address: %location%\nMOTD: %motd%\nProtocol version: %agreement%\nGame version: %version%\nOnline players: %online% / %max%\nLatency: %ping%ms\nIcon: %image%", - "querytool.msg.motd.fail": "Status: Offline\nIP: %ip%\nPort: %port%", - "querytool.descr.motdbe": "MCBE server info query", - "querytool.msg.motdbe": "Status: Online\nIP: %real%\nPort: %port%\nPhysical address: %location%\nMOTD: %motd%\nGame mode: %gamemode%\nProtocol version: %agreement%\nGame version: %version%\nOnline players: %online% / %max%\nLatency: %delay%ms", - "querytool.msg.motdbe.fail": "Status: Offline\nIP: %ip%\nPort: %port%", - "querytool.descr.mcskin": "MC legit account skin query", - "querytool.msg.mcskin": "Player: %input%\nSkin: %skin%\nCape: %cape%\nHead: %avatar%", - "querytool.msg.mcskin.fail": "%input% player not found!", - "querytool.descr.mcv": "Query Minecraft version info", - "querytool.msg.mcv": "Minecraft Java:\nLatest release: %release%\nRelease date: %releaseDate%\nLatest snapshot: %snapshot%\nRelease date: %snapshotDate%\nMinecraft Bedrock:\nLatest version: %mcbe%\nRelease date: %mcbeDate%", - "querytool.descr.sed": "Social engineering info query", - "querytool.msg.sed": "Query: %input%\nTime: %time% seconds\nRecords found: %count%%list%", - "querytool.msg.sed.list": "\n%key%: %content%", - "querytool.msg.sed.key.qq": "QQ", - "querytool.msg.sed.key.phone": "Phone number", - "querytool.msg.sed.key.location": "Carrier", - "querytool.msg.sed.key.id": "LOL ID", - "querytool.msg.sed.key.area": "LOL area", - "querytool.msg.sed.fail": "No records found for: %input%", - "querytool.descr.idcard": "ID card info query", - "querytool.msg.idcard": "ID Number: %input%\nGender: %gender%\nBirth Date: %birthday%\nAge: %age%\nProvince: %province%\nAddress: %address%\nZodiac Sign: %starsign%", - "querytool.msg.idcard.fail": "ID card error: %input%", - "querytool.descr.hcb": "Weiyi Yun blacklist query", - "querytool.msg.hcb": "%input% has a cloud blacklist record\nUUID: %uuid%\nUser Platform: %plate%\nUser ID: %idkey%\nRecord Description: %descr%\nRecord Level: %level%\nRecord Time: %date%\nRelated Images: %images%", - "querytool.msg.hcb.fail": "%input% has no cloud blacklist record", - "querytool.descr.uuid": "Get a uuid", - "querytool.msg.uuid": "UUID~: %uuid%", - "querytool.descr.color": "Get a random color", - "querytool.msg.color": "Hex: %hex%\nRgb: %rgb%\nHsl: %hsl%\n%image%", - "querytool.descr.ping": "Website ping", - "querytool.descr.header": "Get website icon and title", - "querytool.msg.header": "Website: %input%\nTitle: %title%\nKeywords: %keywords%\nDescription: %description%", - "querytool.msg.header.image": "Icon: %image%", - "querytool.descr.state": "Website status query", - "querytool.msg.state": "%content%", - "querytool.descr.speed": "Website speed test", - "querytool.msg.speed": "%content%" -} \ No newline at end of file diff --git a/modules1/querytool/locales/ja_JP.json b/modules1/querytool/locales/ja_JP.json deleted file mode 100644 index f4454fdc..00000000 --- a/modules1/querytool/locales/ja_JP.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "querytool.descr.github": "Githubリポジトリ情報を検索", - "querytool.msg.github": "アドレス: %name%\n説明: %description%\n言語: %language%\n所有者: %author%\n作成日時: %create%\n最終更新日時: %update%\n最終プッシュ日時: %push%\nオープンソースライセンス: %license%", - "querytool.msg.github.image": "%image%", - "querytool.msg.github.fail": "リポジトリが見つかりません: %input%", - "querytool.descr.motd": "MCJEサーバー情報検索", - "querytool.msg.motd": "ステータス: オンライン\nIP: %real%\nポート: %port%\n物理アドレス: %location%\nMOTD: %motd%\nプロトコルバージョン: %agreement%\nゲームバージョン: %version%\nオンラインプレイヤー数: %online% / %max%\nレイテンシ: %ping%ms\nアイコン: %image%", - "querytool.msg.motd.fail": "ステータス: オフライン\nIP: %ip%\nポート: %port%", - "querytool.descr.motdbe": "MCBEサーバー情報検索", - "querytool.msg.motdbe": "ステータス: オンライン\nIP: %real%\nポート: %port%\n物理アドレス: %location%\nMOTD: %motd%\nゲームモード: %gamemode%\nプロトコルバージョン: %agreement%\nゲームバージョン: %version%\nオンラインプレイヤー数: %online% / %max%\nレイテンシ: %delay%ms", - "querytool.msg.motdbe.fail": "ステータス: オフライン\nIP: %ip%\nポート: %port%", - "querytool.descr.mcskin": "MC正規アカウントスキン検索", - "querytool.msg.mcskin": "プレイヤー: %input%\nスキン: %skin%\nマント: %cape%\n頭: %avatar%", - "querytool.msg.mcskin.fail": "%input% というプレイヤーはいません!", - "querytool.descr.mcv": "Minecraftのバージョン情報を問い合わせる", - "querytool.msg.mcv": "Minecraft Java:\n最新リリース: %release%\nリリース日: %releaseDate%\n最新スナップショット: %snapshot%\nリリース日: %snapshotDate%\nMinecraft Bedrock:\n最新バージョン: %mcbe%\nリリース日: %mcbeDate%", - "querytool.descr.sed": "ソーシャルエンジニアリング情報検索", - "querytool.msg.sed": "検索内容: %input%\n処理時間: %time%秒\n結果数: %count%%list%", - "querytool.msg.sed.list": "\n%key%: %content%", - "querytool.msg.sed.key.qq": "QQ", - "querytool.msg.sed.key.phone": "電話番号", - "querytool.msg.sed.key.location": "キャリア", - "querytool.msg.sed.key.id": "LOL ID", - "querytool.msg.sed.key.area": "LOLエリア", - "querytool.msg.sed.fail": "関連する記録が見つかりません: %input%", - "querytool.descr.idcard": "身分証情報検索", - "querytool.msg.idcard": "ID番号: %input%\n性別: %gender%\n生年月日: %birthday%\n年齢: %age%\n都道府県: %province%\n住所: %address%\n星座: %starsign%", - "querytool.msg.idcard.fail": "ID番号が誤っています: %input%", - "querytool.descr.hcb": "韦一雲ブラックリスト検索", - "querytool.msg.hcb": "%input%はブラックリストに登録されています\nUUID: %uuid%\nプラットフォーム: %plate%\nユーザーID: %idkey%\n理由: %descr%\nレベル: %level%\n登録日時: %date%\n関連画像: %images%", - "querytool.msg.hcb.fail": "%input%はブラックリストに登録されていません", - "querytool.descr.uuid": "UUIDを取得する", - "querytool.msg.uuid": "UUID~: %uuid%", - "querytool.descr.color": "カラーをランダムに取得", - "querytool.msg.color": "Hex: %hex%\nRgb: %rgb%\nHsl: %hsl%\n%image%", - "querytool.descr.ping": "サイトのPING検索", - "querytool.descr.header": "サイトのアイコンとタイトルを取得", - "querytool.msg.header": "サイト: %input%\nタイトル: %title%\nキーワード: %keywords%\n説明: %description%", - "querytool.msg.header.image": "アイコン: %image%", - "querytool.descr.state": "サイトステータス検索", - "querytool.msg.state": "%content%", - "querytool.descr.speed": "サイトスピードテスト", - "querytool.msg.speed": "%content%" -} \ No newline at end of file diff --git a/modules1/querytool/locales/zh_CN.json b/modules1/querytool/locales/zh_CN.json deleted file mode 100644 index c5df45b3..00000000 --- a/modules1/querytool/locales/zh_CN.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "querytool.descr.github": "查询Github仓库信息", - "querytool.msg.github": "地址: %name%\n描述: %description%\n语言: %language%\n所有者: %author%\n创建时间:\n %create%\n最后更新时间: %update%\n最后推送时间: %push%\n开源协议: %license%", - "querytool.msg.github.image": "%image%", - "querytool.msg.github.fail": "未找到仓库: %input%", - "querytool.descr.motd": "MCJE服务器信息查询", - "querytool.msg.motd": "状态: 在线\nIP: %real%\n端口: %port%\n物理地址: %location%\nMOTD: %motd%\n协议版本: %agreement%\n游戏版本: %version%\n在线人数: %online% / %max%\n延迟: %ping%ms\n图标: %image%", - "querytool.msg.motd.fail": "状态: 离线\nIP: %ip%\n端口: %port%", - "querytool.descr.motdbe": "MCBE服务器信息查询", - "querytool.msg.motdbe": "状态: 在线\nIP: %real%\n端口: %port%\n物理地址: %location%\nMOTD: %motd%\n游戏模式: %gamemode%\n协议版本: %agreement%\n游戏版本: %version%\n在线人数: %online% / %max%\n延迟: %delay%ms", - "querytool.msg.motdbe.fail": "状态: 离线\nIP: %ip%\n端口: %port%", - "querytool.descr.mcskin": "MC正版账号皮肤查询", - "querytool.msg.mcskin": "玩家: %input%\n皮肤: %skin%\n披风: %cape%\n头颅: %avatar%", - "querytool.msg.mcskin.fail": "%input%查无此人!", - "querytool.descr.mcv": "查询Minecraft版本信息", - "querytool.msg.mcv": "MinecraftJava:\n最新版: %release%\n发布时间: %releaseDate%\n最新快照: %snapshot%\n发布时间: %snapshotDate%\nMinecraftBedrock:\n最新版: %mcbe%\n发布时间: %mcbeDate%", - "querytool.descr.sed": "社工信息查询", - "querytool.msg.sed": "查询内容: %input%\n消耗时间: %time%秒\n记录数量: %count%%list%", - "querytool.msg.sed.list": "\n%key%: %content%", - "querytool.msg.sed.key.qq": "QQ", - "querytool.msg.sed.key.phone": "手机号", - "querytool.msg.sed.key.location": "运营商", - "querytool.msg.sed.key.id": "LOLID", - "querytool.msg.sed.key.area": "LOL区域", - "querytool.msg.sed.fail": "未查询到相关记录: %input%", - "querytool.descr.idcard": "身份证信息查询", - "querytool.msg.idcard": "身份证号: %input%\n性别: %gender%\n出生日期: %birthday%\n年龄: %age%\n省份: %province%\n地址: %address%\n星座: %starsign%", - "querytool.msg.idcard.fail": "身份证错误: %input%", - "querytool.descr.hcb": "韦一云黑信息查询", - "querytool.msg.hcb": "%input%有云黑记录\nUUID: %uuid%\n用户平台: %plate%\n用户ID: %idkey%\n记录描述: %descr%\n记录等级: %level%\n记录时间: %date%\n相关图片: %images%", - "querytool.msg.hcb.fail": "%input%无云黑记录", - "querytool.descr.uuid": "获取一条UUID", - "querytool.msg.uuid": "UUID~: %uuid%", - "querytool.descr.color": "随机获取一种颜色", - "querytool.msg.color": "Hex: %hex%\nRgb: %rgb%\nHsl: %hsl%\n%image%", - "querytool.descr.ping": "网站PING", - "querytool.msg.header": "网站: %input%\n标题: %title%\n关键词: %keywords%\n描述: %description%", - "querytool.msg.header.image": "图标: %image%", - "querytool.descr.state": "网站状态查询", - "querytool.msg.state": "%content%", - "querytool.descr.speed": "网站速度测试", - "querytool.msg.speed": "%content%" -} \ No newline at end of file diff --git a/modules1/querytool/locales/zh_TW.json b/modules1/querytool/locales/zh_TW.json deleted file mode 100644 index 011cec7b..00000000 --- a/modules1/querytool/locales/zh_TW.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "querytool.descr.github": "查詢Github倉庫信息", - "querytool.msg.github": "地址: %name%\n描述: %description%\n語言: %language%\n所有者: %author%\n創建時間:\n %create%\n最後更新時間: %update%\n最後推送時間: %push%\n開源協議: %license%", - "querytool.msg.github.image": "%image%", - "querytool.msg.github.fail": "未找到倉庫: %input%", - "querytool.descr.motd": "MCJE服務器信息查詢", - "querytool.msg.motd": "狀態: 在線\nIP: %real%\n端口: %port%\n物理地址: %location%\nMOTD: %motd%\n協議版本: %agreement%\n遊戲版本: %version%\n在線人數: %online% / %max%\n延遲: %ping%ms\n圖標: %image%", - "querytool.msg.motd.fail": "狀態: 離線\nIP: %ip%\n端口: %port%", - "querytool.descr.motdbe": "MCBE服務器信息查詢", - "querytool.msg.motdbe": "狀態: 在線\nIP: %real%\n端口: %port%\n物理地址: %location%\nMOTD: %motd%\n遊戲模式: %gamemode%\n協議版本: %agreement%\n遊戲版本: %version%\n在線人數: %online% / %max%\n延遲: %delay%ms", - "querytool.msg.motdbe.fail": "狀態: 離線\nIP: %ip%\n端口: %port%", - "querytool.descr.mcskin": "MC正版賬號皮膚查詢", - "querytool.msg.mcskin": "玩家: %input%\n皮膚: %skin%\n披風: %cape%\n頭顱: %avatar%", - "querytool.msg.mcskin.fail": "%input%查無此人!", - "querytool.descr.mcv": "查詢Minecraft版本信息", - "querytool.msg.mcv": "MinecraftJava:\n最新版: %release%\n發布時間: %releaseDate%\n最新快照: %snapshot%\n發布時間: %snapshotDate%\nMinecraftBedrock:\n最新版: %mcbe%\n發布時間: %mcbeDate%", - "querytool.descr.sed": "社工信息查詢", - "querytool.msg.sed": "查詢內容: %input%\n消耗時間: %time%秒\n記錄數量: %count%%list%", - "querytool.msg.sed.list": "\n%key%: %content%", - "querytool.msg.sed.key.qq": "QQ", - "querytool.msg.sed.key.phone": "手機號", - "querytool.msg.sed.key.location": "運營商", - "querytool.msg.sed.key.id": "LOLID", - "querytool.msg.sed.key.area": "LOL區域", - "querytool.msg.sed.fail": "未查詢到相關記錄: %input%", - "querytool.descr.idcard": "身份證信息查詢", - "querytool.msg.idcard": "身份證號: %input%\n性別: %gender%\n出生日期: %birthday%\n年齡: %age%\n省份: %province%\n地址: %address%\n星座: %starsign%", - "querytool.msg.idcard.fail": "身份證錯誤: %input%", - "querytool.descr.hcb": "韋一雲黑信息查詢", - "querytool.msg.hcb": "%input%有雲黑記錄\nUUID: %uuid%\n用戶平臺: %plate%\n用戶ID: %idkey%\n記錄描述: %descr%\n記錄等級: %level%\n記錄時間: %date%\n相關圖片: %images%", - "querytool.msg.hcb.fail": "%input%無雲黑記錄", - "querytool.descr.uuid": "獲取一條UUID", - "querytool.msg.uuid": "UUID~: %uuid%", - "querytool.descr.color": "隨機獲取一種顏色", - "querytool.msg.color": "Hex: %hex%\nRgb: %rgb%\nHsl: %hsl%\n%image%", - "querytool.descr.ping": "網站PING", - "querytool.descr.header": "獲取網站圖標與標題", - "querytool.msg.header": "網站: %input%\n標題: %title%\n關鍵詞: %keywords%\n描述: %description%", - "querytool.msg.header.image": "圖標: %image%", - "querytool.descr.state": "網站狀態查詢", - "querytool.msg.state": "%content%", - "querytool.descr.speed": "網站速度測試", - "querytool.msg.speed": "%content%" -} \ No newline at end of file diff --git a/modules1/querytool/package1.json b/modules1/querytool/package1.json deleted file mode 100644 index c4135095..00000000 --- a/modules1/querytool/package1.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "kotori-plugin-querytool", - "version": "1.0.0", - "description": "querytool plugin", - "main": "src/index.ts", - "license": "GPL-3.0", - "author": "Hotaru ", - "peerDependencies": { - "kotori-bot": "workspace:^" - } -} \ No newline at end of file diff --git a/modules1/querytool/src/index.ts b/modules1/querytool/src/index.ts deleted file mode 100644 index 89c0a29c..00000000 --- a/modules1/querytool/src/index.ts +++ /dev/null @@ -1,62 +0,0 @@ -import Kotori from 'kotori-bot'; - -export const lang = [__dirname, '../locales']; - -/* - -Kotori.command('uuid') - .action(() => ['querytool.msg.uuid', { uuid: getUuid() }]) - .help('querytool.descr.uuid'); - Kotori.command('color') - .action(async () => { - let r = Math.floor(Math.random() * 256); - let g = Math.floor(Math.random() * 256); - let b = Math.floor(Math.random() * 256); - const componentToHex(c: number) { - const hex = c.toString(16); - return hex.length === 1 ? `0${hex}` : hex; - }; - const hex = `#${componentToHex(r)}${componentToHex(g)}${componentToHex(b)}`; - const rgb = `rgb(${r}, ${g}, ${b})`; - - r /= 255; - g /= 255; - b /= 255; - const max = Math.max(r, g, b); - const min = Math.min(r, g, b); - const l = (max + min) / 2; - let h = 0; - let s; - - if (max === min) { - h = 0; - s = 0; - } else { - const d = max - min; - s = l > 0.5 ? d / (2 - max - min) : d / (max + min); - switch (max) { - case r: - h = (g - b) / d + (g < b ? 6 : 0); - break; - case g: - h = (b - r) / d + 2; - break; - case b: - h = (r - g) / d + 4; - break; - } - h *= 60; - } - const hsl = `hsl(${Math.floor(h)}, ${Math.floor(s * 100)}%, ${Math.floor(l * 100)}%)`; - - const browser = await puppeteer.launch({ headless: 'new' }); - const page = await browser.newPage(); - await page.setViewport({ width: 500, height: 500 }); - await page.evaluate(color => { - document.body.style.backgroundColor = color; - }, hex); - const buffer = await page.screenshot({ encoding: 'base64' }); - await browser.close(); - return ['querytool.msg.color', { hex, rgb, hsl, image: image(`base64://${buffer}`) }]; - }) - .help('querytool.descr.color'); */ diff --git a/modules1/sed/locales/en_US.json b/modules1/sed/locales/en_US.json deleted file mode 100644 index 4cb1b407..00000000 --- a/modules1/sed/locales/en_US.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "querytool.descr.github": "Query Github repository info", - "querytool.msg.github": "URL: %name%\nDescription: %description%\nLanguage: %language%\nOwner: %author%\nCreated: %create%\nLast updated: %update%\nLast push: %push%\nOpen source license: %license%", - "querytool.msg.github.image": "%image%", - "querytool.msg.github.fail": "Repository not found: %input%", - "querytool.descr.motd": "MCJE server info query", - "querytool.msg.motd": "Status: Online\nIP: %real%\nPort: %port%\nPhysical address: %location%\nMOTD: %motd%\nProtocol version: %agreement%\nGame version: %version%\nOnline players: %online% / %max%\nLatency: %ping%ms\nIcon: %image%", - "querytool.msg.motd.fail": "Status: Offline\nIP: %ip%\nPort: %port%", - "querytool.descr.motdbe": "MCBE server info query", - "querytool.msg.motdbe": "Status: Online\nIP: %real%\nPort: %port%\nPhysical address: %location%\nMOTD: %motd%\nGame mode: %gamemode%\nProtocol version: %agreement%\nGame version: %version%\nOnline players: %online% / %max%\nLatency: %delay%ms", - "querytool.msg.motdbe.fail": "Status: Offline\nIP: %ip%\nPort: %port%", - "querytool.descr.mcskin": "MC legit account skin query", - "querytool.msg.mcskin": "Player: %input%\nSkin: %skin%\nCape: %cape%\nHead: %avatar%", - "querytool.msg.mcskin.fail": "%input% player not found!", - "querytool.descr.mcv": "Query Minecraft version info", - "querytool.msg.mcv": "Minecraft Java:\nLatest release: %release%\nRelease date: %releaseDate%\nLatest snapshot: %snapshot%\nRelease date: %snapshotDate%\nMinecraft Bedrock:\nLatest version: %mcbe%\nRelease date: %mcbeDate%", - "querytool.descr.sed": "Social engineering info query", - "querytool.msg.sed": "Query: %input%\nTime: %time% seconds\nRecords found: %count%%list%", - "querytool.msg.sed.list": "\n%key%: %content%", - "querytool.msg.sed.key.qq": "QQ", - "querytool.msg.sed.key.phone": "Phone number", - "querytool.msg.sed.key.location": "Carrier", - "querytool.msg.sed.key.id": "LOL ID", - "querytool.msg.sed.key.area": "LOL area", - "querytool.msg.sed.fail": "No records found for: %input%", - "querytool.descr.idcard": "ID card info query", - "querytool.msg.idcard": "ID Number: %input%\nGender: %gender%\nBirth Date: %birthday%\nAge: %age%\nProvince: %province%\nAddress: %address%\nZodiac Sign: %starsign%", - "querytool.msg.idcard.fail": "ID card error: %input%", - "querytool.descr.hcb": "Weiyi Yun blacklist query", - "querytool.msg.hcb": "%input% has a cloud blacklist record\nUUID: %uuid%\nUser Platform: %plate%\nUser ID: %idkey%\nRecord Description: %descr%\nRecord Level: %level%\nRecord Time: %date%\nRelated Images: %images%", - "querytool.msg.hcb.fail": "%input% has no cloud blacklist record", - "querytool.descr.uuid": "Get a uuid", - "querytool.msg.uuid": "UUID~: %uuid%", - "querytool.descr.color": "Get a random color", - "querytool.msg.color": "Hex: %hex%\nRgb: %rgb%\nHsl: %hsl%\n%image%", - "querytool.descr.ping": "Website ping", - "querytool.descr.header": "Get website icon and title", - "querytool.msg.header": "Website: %input%\nTitle: %title%\nKeywords: %keywords%\nDescription: %description%", - "querytool.msg.header.image": "Icon: %image%", - "querytool.descr.state": "Website status query", - "querytool.msg.state": "%content%", - "querytool.descr.speed": "Website speed test", - "querytool.msg.speed": "%content%" -} \ No newline at end of file diff --git a/modules1/sed/locales/ja_JP.json b/modules1/sed/locales/ja_JP.json deleted file mode 100644 index f4454fdc..00000000 --- a/modules1/sed/locales/ja_JP.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "querytool.descr.github": "Githubリポジトリ情報を検索", - "querytool.msg.github": "アドレス: %name%\n説明: %description%\n言語: %language%\n所有者: %author%\n作成日時: %create%\n最終更新日時: %update%\n最終プッシュ日時: %push%\nオープンソースライセンス: %license%", - "querytool.msg.github.image": "%image%", - "querytool.msg.github.fail": "リポジトリが見つかりません: %input%", - "querytool.descr.motd": "MCJEサーバー情報検索", - "querytool.msg.motd": "ステータス: オンライン\nIP: %real%\nポート: %port%\n物理アドレス: %location%\nMOTD: %motd%\nプロトコルバージョン: %agreement%\nゲームバージョン: %version%\nオンラインプレイヤー数: %online% / %max%\nレイテンシ: %ping%ms\nアイコン: %image%", - "querytool.msg.motd.fail": "ステータス: オフライン\nIP: %ip%\nポート: %port%", - "querytool.descr.motdbe": "MCBEサーバー情報検索", - "querytool.msg.motdbe": "ステータス: オンライン\nIP: %real%\nポート: %port%\n物理アドレス: %location%\nMOTD: %motd%\nゲームモード: %gamemode%\nプロトコルバージョン: %agreement%\nゲームバージョン: %version%\nオンラインプレイヤー数: %online% / %max%\nレイテンシ: %delay%ms", - "querytool.msg.motdbe.fail": "ステータス: オフライン\nIP: %ip%\nポート: %port%", - "querytool.descr.mcskin": "MC正規アカウントスキン検索", - "querytool.msg.mcskin": "プレイヤー: %input%\nスキン: %skin%\nマント: %cape%\n頭: %avatar%", - "querytool.msg.mcskin.fail": "%input% というプレイヤーはいません!", - "querytool.descr.mcv": "Minecraftのバージョン情報を問い合わせる", - "querytool.msg.mcv": "Minecraft Java:\n最新リリース: %release%\nリリース日: %releaseDate%\n最新スナップショット: %snapshot%\nリリース日: %snapshotDate%\nMinecraft Bedrock:\n最新バージョン: %mcbe%\nリリース日: %mcbeDate%", - "querytool.descr.sed": "ソーシャルエンジニアリング情報検索", - "querytool.msg.sed": "検索内容: %input%\n処理時間: %time%秒\n結果数: %count%%list%", - "querytool.msg.sed.list": "\n%key%: %content%", - "querytool.msg.sed.key.qq": "QQ", - "querytool.msg.sed.key.phone": "電話番号", - "querytool.msg.sed.key.location": "キャリア", - "querytool.msg.sed.key.id": "LOL ID", - "querytool.msg.sed.key.area": "LOLエリア", - "querytool.msg.sed.fail": "関連する記録が見つかりません: %input%", - "querytool.descr.idcard": "身分証情報検索", - "querytool.msg.idcard": "ID番号: %input%\n性別: %gender%\n生年月日: %birthday%\n年齢: %age%\n都道府県: %province%\n住所: %address%\n星座: %starsign%", - "querytool.msg.idcard.fail": "ID番号が誤っています: %input%", - "querytool.descr.hcb": "韦一雲ブラックリスト検索", - "querytool.msg.hcb": "%input%はブラックリストに登録されています\nUUID: %uuid%\nプラットフォーム: %plate%\nユーザーID: %idkey%\n理由: %descr%\nレベル: %level%\n登録日時: %date%\n関連画像: %images%", - "querytool.msg.hcb.fail": "%input%はブラックリストに登録されていません", - "querytool.descr.uuid": "UUIDを取得する", - "querytool.msg.uuid": "UUID~: %uuid%", - "querytool.descr.color": "カラーをランダムに取得", - "querytool.msg.color": "Hex: %hex%\nRgb: %rgb%\nHsl: %hsl%\n%image%", - "querytool.descr.ping": "サイトのPING検索", - "querytool.descr.header": "サイトのアイコンとタイトルを取得", - "querytool.msg.header": "サイト: %input%\nタイトル: %title%\nキーワード: %keywords%\n説明: %description%", - "querytool.msg.header.image": "アイコン: %image%", - "querytool.descr.state": "サイトステータス検索", - "querytool.msg.state": "%content%", - "querytool.descr.speed": "サイトスピードテスト", - "querytool.msg.speed": "%content%" -} \ No newline at end of file diff --git a/modules1/sed/locales/zh_CN.json b/modules1/sed/locales/zh_CN.json deleted file mode 100644 index c5df45b3..00000000 --- a/modules1/sed/locales/zh_CN.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "querytool.descr.github": "查询Github仓库信息", - "querytool.msg.github": "地址: %name%\n描述: %description%\n语言: %language%\n所有者: %author%\n创建时间:\n %create%\n最后更新时间: %update%\n最后推送时间: %push%\n开源协议: %license%", - "querytool.msg.github.image": "%image%", - "querytool.msg.github.fail": "未找到仓库: %input%", - "querytool.descr.motd": "MCJE服务器信息查询", - "querytool.msg.motd": "状态: 在线\nIP: %real%\n端口: %port%\n物理地址: %location%\nMOTD: %motd%\n协议版本: %agreement%\n游戏版本: %version%\n在线人数: %online% / %max%\n延迟: %ping%ms\n图标: %image%", - "querytool.msg.motd.fail": "状态: 离线\nIP: %ip%\n端口: %port%", - "querytool.descr.motdbe": "MCBE服务器信息查询", - "querytool.msg.motdbe": "状态: 在线\nIP: %real%\n端口: %port%\n物理地址: %location%\nMOTD: %motd%\n游戏模式: %gamemode%\n协议版本: %agreement%\n游戏版本: %version%\n在线人数: %online% / %max%\n延迟: %delay%ms", - "querytool.msg.motdbe.fail": "状态: 离线\nIP: %ip%\n端口: %port%", - "querytool.descr.mcskin": "MC正版账号皮肤查询", - "querytool.msg.mcskin": "玩家: %input%\n皮肤: %skin%\n披风: %cape%\n头颅: %avatar%", - "querytool.msg.mcskin.fail": "%input%查无此人!", - "querytool.descr.mcv": "查询Minecraft版本信息", - "querytool.msg.mcv": "MinecraftJava:\n最新版: %release%\n发布时间: %releaseDate%\n最新快照: %snapshot%\n发布时间: %snapshotDate%\nMinecraftBedrock:\n最新版: %mcbe%\n发布时间: %mcbeDate%", - "querytool.descr.sed": "社工信息查询", - "querytool.msg.sed": "查询内容: %input%\n消耗时间: %time%秒\n记录数量: %count%%list%", - "querytool.msg.sed.list": "\n%key%: %content%", - "querytool.msg.sed.key.qq": "QQ", - "querytool.msg.sed.key.phone": "手机号", - "querytool.msg.sed.key.location": "运营商", - "querytool.msg.sed.key.id": "LOLID", - "querytool.msg.sed.key.area": "LOL区域", - "querytool.msg.sed.fail": "未查询到相关记录: %input%", - "querytool.descr.idcard": "身份证信息查询", - "querytool.msg.idcard": "身份证号: %input%\n性别: %gender%\n出生日期: %birthday%\n年龄: %age%\n省份: %province%\n地址: %address%\n星座: %starsign%", - "querytool.msg.idcard.fail": "身份证错误: %input%", - "querytool.descr.hcb": "韦一云黑信息查询", - "querytool.msg.hcb": "%input%有云黑记录\nUUID: %uuid%\n用户平台: %plate%\n用户ID: %idkey%\n记录描述: %descr%\n记录等级: %level%\n记录时间: %date%\n相关图片: %images%", - "querytool.msg.hcb.fail": "%input%无云黑记录", - "querytool.descr.uuid": "获取一条UUID", - "querytool.msg.uuid": "UUID~: %uuid%", - "querytool.descr.color": "随机获取一种颜色", - "querytool.msg.color": "Hex: %hex%\nRgb: %rgb%\nHsl: %hsl%\n%image%", - "querytool.descr.ping": "网站PING", - "querytool.msg.header": "网站: %input%\n标题: %title%\n关键词: %keywords%\n描述: %description%", - "querytool.msg.header.image": "图标: %image%", - "querytool.descr.state": "网站状态查询", - "querytool.msg.state": "%content%", - "querytool.descr.speed": "网站速度测试", - "querytool.msg.speed": "%content%" -} \ No newline at end of file diff --git a/modules1/sed/locales/zh_TW.json b/modules1/sed/locales/zh_TW.json deleted file mode 100644 index 011cec7b..00000000 --- a/modules1/sed/locales/zh_TW.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "querytool.descr.github": "查詢Github倉庫信息", - "querytool.msg.github": "地址: %name%\n描述: %description%\n語言: %language%\n所有者: %author%\n創建時間:\n %create%\n最後更新時間: %update%\n最後推送時間: %push%\n開源協議: %license%", - "querytool.msg.github.image": "%image%", - "querytool.msg.github.fail": "未找到倉庫: %input%", - "querytool.descr.motd": "MCJE服務器信息查詢", - "querytool.msg.motd": "狀態: 在線\nIP: %real%\n端口: %port%\n物理地址: %location%\nMOTD: %motd%\n協議版本: %agreement%\n遊戲版本: %version%\n在線人數: %online% / %max%\n延遲: %ping%ms\n圖標: %image%", - "querytool.msg.motd.fail": "狀態: 離線\nIP: %ip%\n端口: %port%", - "querytool.descr.motdbe": "MCBE服務器信息查詢", - "querytool.msg.motdbe": "狀態: 在線\nIP: %real%\n端口: %port%\n物理地址: %location%\nMOTD: %motd%\n遊戲模式: %gamemode%\n協議版本: %agreement%\n遊戲版本: %version%\n在線人數: %online% / %max%\n延遲: %delay%ms", - "querytool.msg.motdbe.fail": "狀態: 離線\nIP: %ip%\n端口: %port%", - "querytool.descr.mcskin": "MC正版賬號皮膚查詢", - "querytool.msg.mcskin": "玩家: %input%\n皮膚: %skin%\n披風: %cape%\n頭顱: %avatar%", - "querytool.msg.mcskin.fail": "%input%查無此人!", - "querytool.descr.mcv": "查詢Minecraft版本信息", - "querytool.msg.mcv": "MinecraftJava:\n最新版: %release%\n發布時間: %releaseDate%\n最新快照: %snapshot%\n發布時間: %snapshotDate%\nMinecraftBedrock:\n最新版: %mcbe%\n發布時間: %mcbeDate%", - "querytool.descr.sed": "社工信息查詢", - "querytool.msg.sed": "查詢內容: %input%\n消耗時間: %time%秒\n記錄數量: %count%%list%", - "querytool.msg.sed.list": "\n%key%: %content%", - "querytool.msg.sed.key.qq": "QQ", - "querytool.msg.sed.key.phone": "手機號", - "querytool.msg.sed.key.location": "運營商", - "querytool.msg.sed.key.id": "LOLID", - "querytool.msg.sed.key.area": "LOL區域", - "querytool.msg.sed.fail": "未查詢到相關記錄: %input%", - "querytool.descr.idcard": "身份證信息查詢", - "querytool.msg.idcard": "身份證號: %input%\n性別: %gender%\n出生日期: %birthday%\n年齡: %age%\n省份: %province%\n地址: %address%\n星座: %starsign%", - "querytool.msg.idcard.fail": "身份證錯誤: %input%", - "querytool.descr.hcb": "韋一雲黑信息查詢", - "querytool.msg.hcb": "%input%有雲黑記錄\nUUID: %uuid%\n用戶平臺: %plate%\n用戶ID: %idkey%\n記錄描述: %descr%\n記錄等級: %level%\n記錄時間: %date%\n相關圖片: %images%", - "querytool.msg.hcb.fail": "%input%無雲黑記錄", - "querytool.descr.uuid": "獲取一條UUID", - "querytool.msg.uuid": "UUID~: %uuid%", - "querytool.descr.color": "隨機獲取一種顏色", - "querytool.msg.color": "Hex: %hex%\nRgb: %rgb%\nHsl: %hsl%\n%image%", - "querytool.descr.ping": "網站PING", - "querytool.descr.header": "獲取網站圖標與標題", - "querytool.msg.header": "網站: %input%\n標題: %title%\n關鍵詞: %keywords%\n描述: %description%", - "querytool.msg.header.image": "圖標: %image%", - "querytool.descr.state": "網站狀態查詢", - "querytool.msg.state": "%content%", - "querytool.descr.speed": "網站速度測試", - "querytool.msg.speed": "%content%" -} \ No newline at end of file diff --git a/modules1/sed/package1.json b/modules1/sed/package1.json deleted file mode 100644 index c4135095..00000000 --- a/modules1/sed/package1.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "kotori-plugin-querytool", - "version": "1.0.0", - "description": "querytool plugin", - "main": "src/index.ts", - "license": "GPL-3.0", - "author": "Hotaru ", - "peerDependencies": { - "kotori-bot": "workspace:^" - } -} \ No newline at end of file diff --git a/modules1/sed/src/index.ts b/modules1/sed/src/index.ts deleted file mode 100644 index daaa0c46..00000000 --- a/modules1/sed/src/index.ts +++ /dev/null @@ -1,161 +0,0 @@ -import Kotori, { formatTime, getUuid, isObj, stringTemp } from 'kotori-bot'; - -export const lang = [__dirname, '../locales']; - -Kotori.command('sed') - .action(async (data, message) => { - if (data.args[0] === message.api.adapter.selfId.toString()) - return ['querytool.msg.sed.fail', { input: data.args[0] }]; - - const res = await Kotori.http.get('sed', { msg: data.args[0] }); - if (!isObj(res)) return ['BOT_RESULT.SERVER_ERROR', { res }]; - if (res.code === 501 || !isObj(res.data)) return ['querytool.msg.sed.fail', { input: data.args[0] }]; - let list = ''; - list += res.data.qq - ? stringTemp('querytool.msg.sed.list', { - key: message.locale('querytool.msg.sed.key.qq'), - content: res.data.qq, - }) - : ''; - list += res.data.phone - ? stringTemp('querytool.msg.sed.list', { - key: message.locale('querytool.msg.sed.key.phone'), - content: res.data.phone, - }) - : ''; - list += res.data.location - ? stringTemp('querytool.msg.sed.list', { - key: message.locale('querytool.msg.sed.key.location'), - content: res.data.location, - }) - : ''; - list += res.data.id - ? stringTemp('querytool.msg.sed.list', { - key: message.locale('querytool.msg.sed.key.id'), - content: res.data.id, - }) - : ''; - list += res.data.area - ? stringTemp('querytool.msg.sed.list', { - key: message.locale('querytool.msg.sed.key.area'), - content: res.data.area, - }) - : ''; - return [ - 'querytool.msg.sed', - { - input: data.args[0], - time: Math.floor(res.takeTime), - count: res.count, - list, - }, - ]; - }) - .help('querytool.descr.sed'); - -Kotori.command('idcard') - .action(async data => { - const res = await Kotori.http.get('idcard', { msg: data.args[0] }); - if (!isObj(res)) return ['BOT_RESULT.SERVER_ERROR', { res }]; - if (res.code === 501 || !isObj(res.data)) return ['querytool.msg.idcard.fail', { input: data.args[0] }]; - - return [ - 'querytool.msg.idcard', - { - input: data.args[0], - ...res.data, - }, - ]; - }) - .help('querytool.descr.idcard'); - -Kotori.command('hcb') - .action(async data => { - const res = await Kotori.http.get('https://hcb.hotaru.icu/api/v3', { - value: data.args[0], - }); - if (!res || res.code !== 500 || !isObj(res.data) || Array.isArray(res.data)) - return [ - 'BOT_RESULT.SERVER_ERROR', - { - /* res */ - }, - ]; - - if (!res.data.status) return ['querytool.msg.hcb.fail', { input: data.args[0] }]; - - const imgs = ''; - /* if (res.data.imgs !== null) { - (res.data.imgs).forEach(element => { - imgs += image(element); - }); - } */ - return [ - 'querytool.msg.hcb', - { - input: data.args[0], - // ...res.data, - images: imgs || 'BOT_RESULT.EMPTY', - }, - ]; - }) - .help('querytool.descr.hcb'); - -/* - -Kotori.command('uuid') - .action(() => ['querytool.msg.uuid', { uuid: getUuid() }]) - .help('querytool.descr.uuid'); - Kotori.command('color') - .action(async () => { - let r = Math.floor(Math.random() * 256); - let g = Math.floor(Math.random() * 256); - let b = Math.floor(Math.random() * 256); - const componentToHex(c: number) { - const hex = c.toString(16); - return hex.length === 1 ? `0${hex}` : hex; - }; - const hex = `#${componentToHex(r)}${componentToHex(g)}${componentToHex(b)}`; - const rgb = `rgb(${r}, ${g}, ${b})`; - - r /= 255; - g /= 255; - b /= 255; - const max = Math.max(r, g, b); - const min = Math.min(r, g, b); - const l = (max + min) / 2; - let h = 0; - let s; - - if (max === min) { - h = 0; - s = 0; - } else { - const d = max - min; - s = l > 0.5 ? d / (2 - max - min) : d / (max + min); - switch (max) { - case r: - h = (g - b) / d + (g < b ? 6 : 0); - break; - case g: - h = (b - r) / d + 2; - break; - case b: - h = (r - g) / d + 4; - break; - } - h *= 60; - } - const hsl = `hsl(${Math.floor(h)}, ${Math.floor(s * 100)}%, ${Math.floor(l * 100)}%)`; - - const browser = await puppeteer.launch({ headless: 'new' }); - const page = await browser.newPage(); - await page.setViewport({ width: 500, height: 500 }); - await page.evaluate(color => { - document.body.style.backgroundColor = color; - }, hex); - const buffer = await page.screenshot({ encoding: 'base64' }); - await browser.close(); - return ['querytool.msg.color', { hex, rgb, hsl, image: image(`base64://${buffer}`) }]; - }) - .help('querytool.descr.color'); */ diff --git a/modules1/status/locales/en_US.json b/modules1/status/locales/en_US.json deleted file mode 100644 index fdb9e6cd..00000000 --- a/modules1/status/locales/en_US.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "core.descr.bot": "View BOT info and status", - "core.msg.bot": "BOT Info\nBOT QQ: %self_id%\nConnect time: %connect%\nPackets received: %packet_received%\nPackets sent: %packet_sent%\nPackets lost: %packet_lost%\nMessages received: %message_received%\nMessages sent: %message_sent%\nLost connections: %lost_times%\nDisconnects: %disconnect_times%\nLast message time: %last_message_time%\n%AUTHOR%", - "core.msg.ver": "KotoriBot version: %version%\nLicense: %license%\n%AUTHOR%", - "core.descr.status": "View server running status", - "core.msg.status": "Server status\nKernel: %type%\nPlatform: %platform%\nCPU architecture: %arch%\nCPU model: %model%\nCPU speed: %speed%GHz\nCPU cores: %num%\nCPU usage: %cpu_rate%%\nTotal memory: %total%GB\nAvailable memory: %used%GB\nMemory usage: %ram_rate%%\nNetwork cards: %network%\nUptime: %time%\nHostname: %hostname%\nHome dir: %homedir%\n%AUTHOR%" -} \ No newline at end of file diff --git a/modules1/status/locales/ja_JP.json b/modules1/status/locales/ja_JP.json deleted file mode 100644 index 9008f826..00000000 --- a/modules1/status/locales/ja_JP.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "core.descr.bot": "BOT情報とステータスを表示", - "core.msg.bot": "BOT情報\nBOT QQ: %self_id%\n接続時間: %connect%\n受信パケット数: %packet_received%\n送信パケット数: %packet_sent%\nパケットロス数: %packet_lost%\n受信メッセージ数: %message_received%\n送信メッセージ数: %message_sent%\n接続ロスト回数: %lost_times%\n切断回数: %disconnect_times%\n最終メッセージ時間: %last_message_time%\n%AUTHOR%", - "core.descr.status": "サーバーの実行状況を確認する", - "core.msg.status": "サーバーステータス\nカーネル: %type%\nプラットフォーム: %platform%\nCPUアーキテクチャ: %arch%\nCPUモデル: %model%\nCPU速度: %speed%GHz\nCPUコア数: %num%\nCPU使用率: %cpu_rate%%\nメモリ総量: %total%GB\n利用可能メモリ: %used%GB\nメモリ使用率: %ram_rate%%\nネットワークカード数: %network%\n起動時間: %time%\nホスト名: %hostname%\nホームディレクトリ: %homedir%\n%AUTHOR%" -} \ No newline at end of file diff --git a/modules1/status/locales/zh_CN.json b/modules1/status/locales/zh_CN.json deleted file mode 100644 index 80b13d57..00000000 --- a/modules1/status/locales/zh_CN.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "core.descr.status": "查看服务器运行状态", - "core.msg.status": "服务器运行状态\n系统内核: %type%\n系统平台: %platform%\nCPU架构: %arch%\nCPU型号: %model%\nCPU频率: %speed%GHz\nCPU核心数: %num%\nCPU使用率: %cpu_rate%%\n内存总量: %total%GB\n可用内存: %used%GB\n内存使用率: %ram_rate%%\n网卡数量: %network%\n开机时间: %time%\n主机名字: %hostname%\n系统目录: %homedir%\n%AUTHOR%" -} \ No newline at end of file diff --git a/modules1/status/locales/zh_TW.json b/modules1/status/locales/zh_TW.json deleted file mode 100644 index c5bb1b08..00000000 --- a/modules1/status/locales/zh_TW.json +++ /dev/null @@ -1,106 +0,0 @@ -{ - "core.temp.result.guide": "<名字>代表參數,發送時無需到\"<>\",使用空格間隔各個參數\n\"?\"表示可選參數,\"=xx\"表示可選且有默認值,\"。。。\"表示剩余參數,意味著參數中的空格將不影響指令,\"*\"僅群聊可用,\"#\"僅私聊可用,\"^\"需一級權限(群BOT管理員和群管理員),\"^^\"需二級權限(BOT超級管理員)", - "core.temp.result.data_error": "返回數據錯誤!請聯系管理員\n源數據: %res%", - "core.temp.result.args.empty": "輸入參數不能為空", - "core.temp.result.args.error": "輸入參數錯誤,請更改後重新發送", - "core.temp.result.unknown_error": "未知的錯誤: %error%", - "core.temp.result.num.error": "序號錯誤,請重新發送", - "core.temp.result.num.choose": "再次發送指令並傳入參數[序號]以選擇對應內容\n示例:/指令 內容 2", - "core.temp.result.no_access.1": "該指令僅群管理員與群BOT管理員可執行!", - "core.temp.result.no_access.2": "該指令僅BOT超級管理員可執行!", - "core.temp.result.disable": "該功能目前未啟用,請聯系管理員開啟", - "core.temp.result.exist": "輸入參數目標已存在,請勿重復執行", - "core.temp.result.no_esist": "目標參數不存在,請確認後重新發送", - "core.temp.result.repairing": "該功能維修中", - "core.temp.result.apikey_error": "請先配置APIKEY!", - "core.temp.result.empty": "無內容", - "core.temp.result.message_type": "該功能僅在群聊或私聊下可用", - "core.temp.result.option.on": "√", - "core.temp.result.option.off": "X", - "core.temp.menu": "%HEAD%%list%\n%AUTHOR%", - "core.temp.menu.list": "\n%name%%param% - %help%%scope%%access%", - "core.temp.menu.param": " <%prefix%%param_name%%suffix%>", - "core.temp.menu.param_name_default": "content", - "core.temp.menu.prefix.rest": "。。。", - "core.temp.menu.suffix.optional": "?", - "core.temp.menu.suffix.default": "=%content%", - "core.temp.menu.help": "%content%", - "core.temp.menu.scope.private": "#", - "core.temp.menu.scope.group": "*", - "core.temp.menu.access.manger": "^", - "core.temp.menu.access.admin": "^^", - "core.menu.main.help": "主菜單", - "core.menu.corecom.help": "核心功能", - "core.menu.daytool.help": "日常工具", - "core.menu.querytool.help": "查詢工具", - "core.menu.funsys.help": "娛樂系統", - "core.menu.random_img.help": "隨機圖片", - "core.menu.othercom.help": "其它功能", - "core.descr.api": "查看API站點數據", - "core.msg.api": "%content%", - "core.descr.alias.query": "查詢全部指令別名", - "core.descr.alias.add": "添加指令別名,支持帶參數,無需帶斜杠", - "core.descr.alias.del": "刪除指令別名", - "core.msg.alias.query": "別名列表:%list%", - "core.msg.alias.list": "\n%key% -> %val%", - "core.msg.alias.add": "成功添加別名: %input%\n發送別名以查看效果", - "core.msg.alias.del": "成功刪除別名: %input%", - "core.msg.alias.fail": "該指令或別名已被註冊", - "core.msg.alias.fail.2": "該指令無效", - "core.descr.system.0": "重啟Go-cqHttp", - "core.descr.system.1": "重啟簽名服務器與Go-cqHttp", - "core.msg.system.fail": "重啟失敗,無法找到Signserver或Go-cqHttp", - "core.msg.system.info.0": "即將重啟Go-cqHttp。。。", - "core.msg.system.info.1": "即將重啟Signserver與Go-cqHttp。。。", - "core.msg.system.info.3": "重啟完成!", - "core.descr.run.private": "模擬執行一條私聊指令", - "core.descr.run.group": "模擬執行一條群指令", - "core.msg.run": "發送至目標: %target%", - "core.descr.locale.list": "查看BOT支持語言列表", - "core.descr.locale.set": "切換BOT使用語言", - "core.msg.locale.lists": "支持語言列表:%list%", - "core.msg.locale.list": "\n%locale% - %name%", - "core.msg.locale.locale.zh_cn": "簡體中文(Simplified Chinese)", - "core.msg.locale.locale.zh_tw": "繁體中文(Traditional Chinese)", - "core.msg.locale.locale.en_us": "English(English)", - "core.msg.locale.locale.ja_jp": "日本語(Japanese)", - "core.msg.locale.set": "成功切換至%locale%\n切換Locale總數: %total%\n有效Locale數量: %success%", - "core.msg.locale.fail": "切換失敗,請輸入\"/locale list\"查看BOT支持語言列表", - "core.descr.core": "查看kotori-core核心插件統計數據", - "core.msg.core": "累計註冊指令數量: %commands%", - "core.descr.help": "查看指令幫助信息,不需要帶斜杠/", - "core.msg.help": "幫助:%content%\n%GUIDE%\nBOT詳細使用文檔請查看:\n%DOC%", - "core.msg.descr.fail": "無效的指令", - "core.descr.view": "查看Kotori-bot配置", - "core.msg.view": "連接模式: %mode%\n%mode_content%\n------\nGo-cqHttp路徑: %program%\n啟動參數: %params%\n簽名服務器路徑: %signserver%\n------\nMaster: %master%\n私聊過濾: %user%%user_list%\n群聊過濾: %group%%group_list%", - "core.msg.view.mode.http": "正向Http地址: %url%\n正向Http端口: %port%\n反向Http端口: %reverse_port%\n重連間隔時間: %retry_time%秒", - "core.msg.view.mode.ws": "WebSocket地址: %url%\nWebSocket端口: %port%\n重連間隔時間: %retry_time%秒", - "core.msg.view.mode.wsreverse": "WebSocket反向端口: %port%", - "core.msg.view.user.white": "\n私聊白名單:\n%list%\b ", - "core.msg.view.user.black": "\n私聊黑名單:\n%list%\b ", - "core.msg.view.group.white": "\n群聊白名單:\n%list%\b ", - "core.msg.view.group.black": "\n群聊黑名單:\n%list%\b ", - "core.msg.view.list": "%content%,", - "core.descr.plugin.query": "查看指定或全部插件信息", - "core.descr.plugin.ban": "禁用指定插件", - "core.descr.plugin.unban": "啟用指定插件", - "core.msg.plugin.query": "插件信息:\n插件總數: %num%%list%", - "core.msg.plugin.fail": "未找到[%target%]插件", - "core.msg.plugin.list": "\n------\n插件Id: %id%\n插件名字: %name%\n插件版本: %version%\n插件描述: %description%\n插件作者: %author%\n插件協議: %license%\n插件狀態: %state%", - "core.msg.plugin.ban": "成功禁用[%id%]插件,重啟以查看效果", - "core.msg.plugin.unban": "成功取消禁用[%id%]插件,重啟以查看效果", - "core.descr.bot": "查看BOT信息與運行狀態", - "core.msg.bot": "BOT信息\nBOTQQ: %self_id%\n連接時間: %connect%\n接收包數量: %packet_received%\n發送包數量: %packet_sent%\n丟失包數量: %packet_lost%\n接收消息數量: %message_received%\n發送消息數量: %message_sent%\n連接丟失次數: %lost_times%\n連接斷開次數: %disconnect_times%\n最後消息時間: %last_message_time%\n%AUTHOR%", - "core.descr.env": "查看環境信息", - "core.msg.env": "環境信息\nNode版本: %node%\nTypeScript版本: %typescript%\nTsNode版本: %tsnode%\n%AUTHOR%", - "core.descr.ver": "查看版本信息", - "core.msg.ver": "KotoriBot版本: %version%\n協議: %license%\n%AUTHOR%", - "core.descr.status": "查看服務器運行狀態", - "core.msg.status": "服務器運行狀態\n系統內核: %type%\n系統平臺: %platform%\nCPU架構: %arch%\nCPU型號: %model%\nCPU頻率: %speed%GHz\nCPU核心數: %num%\nCPU使用率: %cpu_rate%%\n內存總量: %total%GB\n可用內存: %used%GB\n內存使用率: %ram_rate%%\n網卡數量: %network%\n開機時間: %time%\n主機名字: %hostname%\n系統目錄: %homedir%\n%AUTHOR%", - "core.descr.about": "幫助信息", - "core.msg.about": "KotoriBot是一個go-cqhttp的基於NodeJS+TypeScript的SDK和QQ機器人框架實現\n開源地址: %REPO%\n來給可憐的🦊點一個star吧\n\n當前BOT框架版本: %version%\n框架協議: %license%\n%AVATAR%\n%AUTHOR%", - "core.descr.update": "檢查更新", - "core.msg.update": "當前版本: %version%\n%content%", - "core.msg.update.yes": "當前為最新版本!", - "core.msg.update.no": "檢測到有更新!\n最新版本: %version%\n請前往Github倉庫獲取最新版本:\n%REPO%" -} \ No newline at end of file diff --git a/modules1/status/package1.json b/modules1/status/package1.json deleted file mode 100644 index 8f4ab99b..00000000 --- a/modules1/status/package1.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "@kotori-bot/kotori-plugin-status", - "version": "1.0.0", - "description": "status plugin", - "main": "src/index.ts", - "license": "GPL-3.0", - "author": "Hotaru ", - "peerDependencies": { - "kotori-bot": "workspace:^" - } -} \ No newline at end of file diff --git a/modules1/status/src/class/class.cache.ts b/modules1/status/src/class/class.cache.ts deleted file mode 100644 index 281e6dfb..00000000 --- a/modules1/status/src/class/class.cache.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { obj } from '@/tools'; - -export class Cache { - private static cache: obj = {}; - - public static set(key: string, data: obj) { - this.cache[key] = data; - } - - public static get = (key: string): obj | null => { - const result = this.cache[key]; - return result; - }; -} - -export default Cache; diff --git a/modules1/status/src/class/class.command.ts b/modules1/status/src/class/class.command.ts deleted file mode 100644 index fa36f93f..00000000 --- a/modules1/status/src/class/class.command.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { ACCESS, CoreKeyword, InfoVal, InfoValArg, SCOPE } from '../type'; -import Data from './class.data'; - -export class Command extends Data { - private keyword: CoreKeyword; - - private info: InfoVal; - - public constructor(keyword: CoreKeyword, info: InfoVal) { - super(); - this.keyword = keyword; - this.info = info; - } - - private handle() { - Command.cmdInfoData.set(this.keyword, this.info); - return this; - } - - public menuId(val: string) { - this.info.menuId = val; - return this.handle(); - } - - public help(help: string) { - this.info.help = help; - return this.handle(); - } - - public scope(scope: SCOPE) { - this.info.scope = scope; - return this.handle(); - } - - public access(access: ACCESS) { - this.info.access = access; - return this.handle(); - } - - public params(params: InfoValArg) { - this.info.params = params; - return this.handle(); - } -} - -export default Command; diff --git a/modules1/status/src/class/class.content.ts b/modules1/status/src/class/class.content.ts deleted file mode 100644 index c25eac48..00000000 --- a/modules1/status/src/class/class.content.ts +++ /dev/null @@ -1,204 +0,0 @@ -import path from 'path'; -import { Api, Const, EventDataType, obj, parseCommand } from '@/tools'; -import SDK from '@/utils/class.sdk'; -import { - ACCESS, - SCOPE, - Send, - CoreKeyword, - CoreKeywordMatch, - InfoArgEx, - CoreVal, - InfoArg, - BOT_RESULT, - Hook, -} from '../type'; -import { loadConfigP, temp } from '../method'; -import Core from './class.core'; -import Data from './class.data'; - -export class Content extends Data { - private data: EventDataType; - - private api: Api; - - public constructor(data: EventDataType, api: Api, consts: Const, callbacks?: Hook[]) { - super(); - this.data = data; - this.api = api; - Content.consts = consts; - Core.args = parseCommand(this.data.message); - - if (callbacks) { - for (const callback of callbacks) { - if (!callback(data, this.send, api)) return; - } - } - - const result = Content.isUsefulCmd(Core.args[0], this.data.message); - if (result) this.runHandlerFunc(...result); - this.runAlias(); - } - - private static consts: Const; - - public static verifyAccess(data: EventDataType) { - if (data.user_id === this.consts.CONFIG.bot.master) return ACCESS.ADMIN; - if (!data.group_id) return ACCESS.NORMAL; - if (data.sender.role === 'admin' || data.sender.role === 'owner') return ACCESS.MANGER; - const mangerList = loadConfigP(path.join(data.group_id.toString(), 'mangerList.json')) as number[]; - return mangerList.includes(data.user_id) ? ACCESS.MANGER : ACCESS.NORMAL; - }; - - public static verifyFrom(data: EventDataType) { - if (data.user_id === data.self_id) return false; - return true; - }; - - public static isUsefulCmd = (cmd: string, message: string): [CoreVal, CoreKeyword | CoreKeywordMatch] | null => { - const result = Data.cmdData.get(cmd); - if (result) return [result, cmd]; - - for (const [key, handlerFunc] of Data.cmdData) { - if ( - typeof key !== 'string' && - ((typeof key === 'function' && key(message)) || (Array.isArray(key) && key.includes(message))) - ) - return [handlerFunc, key]; - } - return null; - }; - - private send: Send(contents, params = {}) { - let content = contents; - if (typeof content !== 'object') content = temp(content, params); - if (this.data.message_type === 'private') { - this.api.send_private_msg(content, this.data.user_id); - } else { - this.api.send_group_msg(content, this.data.group_id!); - } - }; - - private checkParams(key: CoreKeyword) { - const params = Data.cmdInfoData.get(key)?.params; - - if (!params) return true; - if (Array.isArray(params)) return this.checkParamsArr(params); - return this.checkParamsObj(params); - }; - - private checkParamsArr(params: InfoArg[], num: number = 1) { - for (const indexs of Object.keys(params)) { - const index = parseInt(indexs, 10); - const indexNum = index + num; - if (params[index].rest) { - Core.args = this.data.message.split(' '); - for (let init = 0; init < Core.args.length; init += 1) { - if (init > indexNum && Core.args[init]) Core.args[indexNum] += ` ${Core.args[init]}`; - } - } - - if (!Core.args[indexNum] && params[index].must === true) { - this.send(BOT_RESULT.ARGS_EMPTY); - return false; - } - - if (!Core.args[indexNum] && typeof params[index].must === 'string') { - Core.args[indexNum] = params[index].must as string; - } - - if (params[index].rest) return true; - } - return true; - }; - - private checkParamsObj(params: InfoArgEx, num: number = 1) { - if (!Core.args[num]) { - this.send(BOT_RESULT.ARGS_ERROR); - return false; - } - const result = params[Core.args[num]]; - if (result === undefined) { - this.send(BOT_RESULT.ARGS_ERROR); - return false; - } - if (Array.isArray(result.args)) { - return this.checkParamsArr(result.args, num + 1); - } - return true; - }; - - private checkScope(scope: SCOPE) { - if (scope === SCOPE.ALL) return true; - if (scope === SCOPE.PRIVATE && this.data.message_type === 'private') return true; - if (scope === SCOPE.GROUP && this.data.message_type === 'group') return true; - this.send(BOT_RESULT.MESSAGE_TYPE); - return false; - }; - - private checkAccess(access: ACCESS) { - const result = Content.verifyAccess(this.data) >= access; - if (!result) this.send(access === ACCESS.ADMIN ? BOT_RESULT.NO_ACCESS_2 : BOT_RESULT.NO_ACCESS_1); - return result; - }; - - private runHandlerFunc = async (handlerFunc: CoreVal, key: CoreKeyword | CoreKeywordMatch) => { - if (typeof key !== 'function') { - const cmdInfo = Data.cmdInfoData.get(key); - if (!cmdInfo) return; - if (!this.checkScope(cmdInfo.scope)) return; - if (!this.checkAccess(cmdInfo.access)) return; - if (!this.checkParams(key)) return; - } - - if (this.data.message_type === 'group') { - this.api.send_group_msg(SDK.cq_poke(this.data.user_id), this.data.group_id!); - } - if (typeof handlerFunc === 'string') { - this.send(handlerFunc); - return; - } - - const listenr(error: unknown) { - process.removeListener('unhandledRejection', listenr); - Content.isErroring = false; - this.send(BOT_RESULT.UNKNOWN_ERROR, { - error: error instanceof Error ? error.toString() : JSON.stringify(error), - }); - }; - if (!Content.isErroring) { - Content.isErroring = true; - console.info('1'); - // process.removeAllListeners('unhandledRejection'); - process.on('unhandledRejection', listenr); - } - - const result = await handlerFunc(this.send, this.data); - process.removeListener('unhandledRejection', listenr); - Content.isErroring = false; - if (!result) return; - if (typeof result === 'string') { - this.send(result); - return; - } - if (!Array.isArray(result)) return; - Object.keys(result[1]).forEach(Element => { - const val = result[1][Element]; - const type = typeof val; - if (val instanceof Error) result[1][Element] = val.toString(); - else if (type === 'undefined') result[1][Element] = 'undefined'; - else if (type === 'object' && !val) result[1][Element] = 'null'; - else if (type !== 'string' && type !== 'number') result[1][Element] = JSON.stringify(val); - }); - this.send(result[0], result[1] as obj); - }; - - private runAlias() { - const data = (loadConfigP('alias.json', {}) as obj)[this.data.message]; - if (!data || typeof data !== 'string') return; - this.data.message = data; - JSON.stringify(new Content(this.data, this.api, Content.consts)); - }; -} - -export default Content; diff --git a/modules1/status/src/class/class.core.ts b/modules1/status/src/class/class.core.ts deleted file mode 100644 index 6f2835ea..00000000 --- a/modules1/status/src/class/class.core.ts +++ /dev/null @@ -1,160 +0,0 @@ -import { Locale } from '@/tools'; -import { ACCESS, CoreVal, SCOPE, CoreKeywordMatch, InfoArgEx, CoreKeyword, InfoVal, InfoArg, Hook } from '../type'; -import { temp } from '../method'; -import Command from './class.command'; -import Data from './class.data'; - -export class Core extends Data { - public static args: string[] = []; - - public static cmd(keyword: CoreKeyword, callback: CoreVal) { - const newKeyword = `/${keyword}`; - return this.alias(newKeyword, callback); - }; - - public static alias(keyword: CoreKeyword, callback: CoreVal) { - // if (!this.isInitialize) this.initialize(); - this.cmdData.set(keyword, callback); - const infoData: InfoVal = { - menuId: undefined, - help: undefined, - scope: SCOPE.ALL, - access: ACCESS.NORMAL, - params: undefined, - }; - this.cmdInfoData.set(keyword, infoData); - return new Command(keyword, infoData); - }; - - public static menu(keyword: CoreKeyword, menuId: string) { - const callback() this.menuHandle(menuId); - const main = menuId === 'main' ? '' : 'main'; - const { menuId: menuIdFun, help, scope, access } = this.cmd(keyword, callback).menuId(main); - return { - menuId: menuIdFun, - help, - scope, - access, - }; - }; - - public static custom(match: CoreKeywordMatch, callback: CoreVal) { - // if (!this.isInitialize) this.initialize(); - this.cmdData.set(match, callback); - }; - - public static auto(callback: () void) => { - this.autoEvent.push(callback); - }; - - public static hook(callback: Hook) { - Core.hookEvent.push(callback); - }; - - protected static autoEvent: (() => void)[] = []; - - protected static hookEvent: Hook[] = []; - - /* private static isInitialize: boolean = false; - - private static initialize() { - this.isInitialize = true; - if (CCOM.main) { - this.cmd(LMENU.main.cmd, LMENU.main.content); - } - for (const key of Object.keys(LMENU.customMenu)) { - const menu = (LMENU.customMenu as customMenu)[key]; - if (!menu.cmd || !menu.content) continue; - this.cmd(menu.cmd, menu.content); - } - }; */ - - private static menuHandle(menuId: string) { - let list = ''; - for (const key of this.cmdInfoData) { - const { 0: cmdKey, 1: value } = key; - if (value.menuId !== menuId || typeof cmdKey === 'function') continue; - list += this.menuHandleParams(cmdKey, value); - } - return temp('core.temp.menu', { - list, - }); - }; - - protected static menuHandleParams(key: CoreKeyword, value: InfoVal) { - let cmdName = Array.isArray(key) ? key[0] : key; - if (Array.isArray(key)) cmdName = `${cmdName} (${key.filter(val => val !== key[0]).join('|')})`; - let scope = ''; - if (value.scope !== SCOPE.ALL) { - scope = value.scope === SCOPE.GROUP ? 'core.temp.menu.scope.group' : 'core.temp.menu.scope.private'; - scope = Locale.locale(scope); - } - let access = ''; - if (value.access !== ACCESS.NORMAL) { - access = value.access === ACCESS.MANGER ? 'core.temp.menu.access.manger' : 'core.temp.menu.access.admin'; - access = Locale.locale(access); - } - let list = ''; - let handleParams = ''; - - /* type = InfoArg[] */ - if (Array.isArray(value.params) || !value.params) { - if (value.params) handleParams = this.menuHandleParamsArr(value.params); - return temp('core.temp.menu.list', { - name: cmdName, - param: handleParams, - help: value.help - ? temp('core.temp.menu.help', { - content: Locale.locale(value.help), - }) - : '', - scope, - access, - }); - } - - /* type = InfoArgEx */ - for (const param of Object.keys(value.params)) { - handleParams = ''; - const val = (value.params as InfoArgEx)[param]; - if (Array.isArray(val.args)) handleParams += this.menuHandleParamsArr(val.args); - list += temp('core.temp.menu.list', { - name: `${cmdName} ${param}`, - param: handleParams, - help: val.help - ? temp('core.temp.menu.help', { - content: Locale.locale(val.help), - }) - : '', - scope, - access, - }); - } - return list; - }; - - private static menuHandleParamsArr(params: InfoArg[]) { - let handleParams = ''; - params.forEach(element => { - const paramName = element.name ?? Locale.locale('core.temp.menu.param_name_default'); - const prefix = element.rest ? Locale.locale('core.temp.menu.prefix.rest') : ''; - let suffix = ''; - if (element.must !== true) { - suffix = - element.must === false - ? Locale.locale('core.temp.menu.suffix.optional') - : temp('core.temp.menu.suffix.default', { - content: element.must, - }); - } - handleParams += temp('core.temp.menu.param', { - param_name: paramName, - prefix, - suffix, - }); - }); - return handleParams; - }; -} - -export default Core; diff --git a/modules1/status/src/class/class.data.ts b/modules1/status/src/class/class.data.ts deleted file mode 100644 index c2211594..00000000 --- a/modules1/status/src/class/class.data.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { CmdInfo, Cmd } from '../type'; - -export class Data { - protected static cmdData: Cmd = new Map(); - - protected static cmdInfoData: CmdInfo = new Map(); - - protected static isErroring = false; -} - -export default Data; diff --git a/modules1/status/src/index.ts b/modules1/status/src/index.ts deleted file mode 100644 index 75387ff3..00000000 --- a/modules1/status/src/index.ts +++ /dev/null @@ -1,579 +0,0 @@ -/* - * @Author: hotaru biyuehuya@gmail.com - * @Blog: https://hotaru.icu - * @Date: 2023-07-11 14:18:27 - * @LastEditors: Hotaru biyuehuya@gmail.com - * @LastEditTime: 2023-11-18 14:59:22 - */ -import os from 'os'; -import path from 'path'; -import { existsSync } from 'fs'; -import type { EventDataType, Event, Api, Const, PackageInfo, PluginData, obj, EventMessageType } from '@/tools'; -import { - BotConfigFilter, - CONNECT_MODE, - CONST, - Locale, - LocaleIdentifier, - fetchJson, - formatTime, - getPackageInfo, - loadConfig, - saveConfig, - stringProcess, -} from '@/tools'; -import ProcessController from '@/tools/class/class.process'; -import { - dealCpu, - dealEnv, - dealRam, - dealTime, - fetchT, - formatOption, - initConfig, - loadConfigP, - saveConfigP, - setPath, - temp, -} from './method'; -import { ACCESS, BOT_RESULT, CoreVal, GLOBAL } from './type'; -import Core from './class/class.core'; -import Content from './class/class.content'; - -/* Public Methods */ -export { fetchJ, fetchT, temp, getQq, formatOption } from './method'; -export * from './class/class.cache'; -export * from './class/class.core'; - -/* plugins Import */ -export class Main extends Core { - private Event: Event; - - public constructor( - event: Event, - api: Api, - consts: Const, - Proxy: PluginData[], - Process: [ProcessController, ProcessController], - ) { - super(); - /* Set variables */ - this.Event = event; - Main.Api = api; - Main.Const = consts; - Main.Proxy = Proxy; - Main.Process = Process; - setPath(Main.Const.CONFIG_PLUGIN_PATH); - initConfig(Main.Const.CONFIG_PLUGIN_PATH); - this.registerEvent(); - /* Verify message from(kill bot self) */ - Main.hook(data => Content.verifyFrom(data)); - /* Run all auto events */ - Core.autoEvent.forEach(callback => callback()); - } - - private registerEvent() { - this.Event.listen('on_group_msg', data => Main.onMsg(data)); - this.Event.listen('on_private_msg', data => Main.onMsg(data)); - }; - - private static onMsg(data: EventDataType) { - if (!Content.verifyFrom(data)) return {}; - return new Content(data, this.Api, this.Const, this.hookEvent); - }; - - public static Api: Api; - - public static Const: Const; - - public static Proxy: PluginData[]; - - public static Process: [ProcessController, ProcessController]; - - public static cmdDataP = this.cmdData; - - public static cmdInfoDataP = this.cmdInfoData; - - public static menuHandleParamsP = this.menuHandleParams; -} - -/* Register Locale Support */ -Locale.register(path.resolve(__dirname)); - -/* This is colorful egg */ -Core.custom( - str => stringProcess(str, 'kotori') || str.includes('kotori'), - () => { - const result = Main.cmdDataP.get('/menu'); - return result as string; - }, -); - -Core.menu('menu', 'main').help('core.menu.main.help'); -Core.menu('cores', 'coreCom').help('core.menu.corecom.help'); -Core.menu('days', 'dayTool').help('core.menu.daytool.help'); -Core.menu('querys', 'queryTool').help('core.menu.querytool.help'); -Core.menu('funs', 'funSys').help('core.menu.funsys.help'); -Core.menu('imgs', 'randomImg').help('core.menu.random_img.help'); -Core.menu('other', 'otherCom').help('core.menu.othercom.help'); - -Core.cmd('api', async () => { - const content = await fetchT('https://api.hotaru.icu/sys/datastat', { format: 'text' }); - return [content ? 'core.msg.api' : BOT_RESULT.SERVER_ERROR, content ? { content } : { res: content }]; -}) - .help('core.descr.api') - .menuId('otherCom'); - -const Kotori.command(keyword: string, callback: CoreVal) { - const result = Core.cmd(keyword, callback).menuId('coreCom'); - return result; -}; - -Kotori.command('alias').action( () => { - const data = loadConfigP('alias.json', {}) as obj; - if (data.args[0] === 'query') { - let list = ''; - Object.keys(data).forEach(key => { - list += temp('core.msg.alias.list', { - key, - val: data[key], - }); - }); - return temp('core.msg.alias.query', { - list: list || BOT_RESULT.EMPTY, - }); - } - if (data.args[0] === 'add') { - if (data[data.args[1]]) return BOT_RESULT.EXIST; - Core.args[3] = `/${Core.args[3]}`; - if (!Content.isUsefulCmd(Core.args[3].split(' ')[0], Core.args[3])) return 'core.msg.alias.fail.2'; - data[data.args[1]] = Core.args[3]; - saveConfigP('alias.json', data); - return temp('core.msg.alias.add', { - input: data.args[1], - }); - } - if (data.args[0] === 'del') { - if (!data[data.args[1]]) return BOT_RESULT.NO_EXIST; - delete data[data.args[1]]; - saveConfigP('alias.json', data); - return temp('core.msg.alias.del', { - input: data.args[1], - }); - } - return BOT_RESULT.ARGS_ERROR; -}) - .help('core.descr.alias') - .access(ACCESS.MANGER) - .params({ - query: { - help: 'core.descr.alias.query', - }, - add: { - help: 'core.descr.alias.add', - args: [ - { - must: true, - name: 'alias', - }, - { - must: true, - name: 'command', - rest: true, - }, - ], - }, - del: { - help: 'core.descr.alias.del', - args: [ - { - must: true, - name: 'alias', - }, - ], - }, - }); - -Kotori.command('system').action( (send, data) => { - if ( - !existsSync(path.join(Main.Const.ROOT_PATH, Main.Const.CONFIG.control.signserver)) || - !existsSync(path.join(Main.Const.ROOT_PATH, Main.Const.CONFIG.control.program)) - ) { - send('core.msg.system.fail'); - return; - } - const num = parseInt(data.args[0], 10); - const save() { - saveConfig( - path.join(Main.Const.DATA_PLUGIN_PATH, 'system.ini'), - data.group_id ? data.group_id.toString() : 'private', - 'txt', - ); - }; - if (!num) { - send('core.msg.system.info.0'); - save(); - setTimeout(() => { - Main.Process[0].restart(); - }, 2000); - } else if (num === 1) { - send('core.msg.system.info.1'); - save(); - setTimeout(() => { - Main.Process[1].restart(); - Main.Process[0].restart(); - }, 2000); - } -}) - .access(ACCESS.ADMIN) - .params({ - '0': { - help: 'core.descr.system.0', - }, - '1': { - help: 'core.descr.system.1', - }, - }); - -Kotori.command('run').action( (send, data) => { - const eventData = JSON.parse(JSON.stringify(data)); - eventData.message_type = data.args[0] as EventMessageType; - if (eventData.message_type === 'group') eventData.group_id = parseInt(data.args[1], 10); - eventData.message = Core.args[3]; - send('core.msg.run', { target: data.args[1] }); - JSON.stringify(new Content(eventData, Main.Api, Main.Const)); -}) - .access(ACCESS.ADMIN) - .params({ - private: { - help: 'core.descr.run.private', - args: [ - { must: true, name: 'id' }, - { must: true, name: 'command', rest: true }, - ], - }, - group: { - help: 'core.descr.system.group', - args: [ - { must: true, name: 'id' }, - { must: true, name: 'command', rest: true }, - ], - }, - }); - -Kotori.command('locale').action( () => { - const list = Object.values(LocaleIdentifier).filter(val => typeof val === 'string') as string[]; - if (data.args[0] === 'list') { - let listRaw = ''; - list.forEach(locale => { - listRaw += temp('core.msg.locale.list', { - locale, - name: Locale.locale(`core.msg.locale.locale.${locale.toLowerCase()}`), - }); - }); - return ['core.msg.locale.lists', { list: listRaw }]; - } - if (data.args[0] === 'set') { - const locale = data.args[1]; - if (!list.includes(locale)) return 'core.msg.locale.fail'; - const { 0: total, 1: success } = Locale.setlang(locale as keyof typeof LocaleIdentifier); - return ['core.msg.locale.set', { locale, total, success }]; - } - return BOT_RESULT.ARGS_ERROR; -}) - .help('core.descr.locale') - .access(ACCESS.MANGER) - .params({ - list: { - help: 'core.descr.locale.list', - }, - set: { - help: 'core.descr.locale.set', - args: [ - { - must: true, - name: 'locales', - }, - ], - }, - }); - -Kotori.command('core').action( () => { - const result = temp('core.msg.core', { - commands: Main.cmdDataP.size, - }); - return result; -}).help('core.descr.core'); - -Kotori.command('help').action( () => { - if (!data.args[0]) return temp('core.msg.help', { content: '' }); - data.args[0] = `/${data.args[0]}`; - for (const key of Main.cmdInfoDataP) { - const { 0: cmd, 1: val } = key; - if (typeof cmd === 'string' && cmd !== data.args[0]) continue; - if (Array.isArray(cmd) && !cmd.includes(data.args[0])) continue; - if (typeof cmd === 'function') continue; - return temp('core.msg.help', { - content: Main.menuHandleParamsP(cmd, val), - }); - } - return 'core.msg.descr.fail'; -}) - .help('core.descr.help') - .params([ - { - must: 'menu', - name: 'command', - }, - ]); - -Kotori.command('view').action( () => { - const { connect, control, bot } = Main.Const.CONFIG; - const { mode, http, ws, 'ws-reverse': wsReverse } = connect; - let modeContent = ''; - let userList = ''; - let groupList = ''; - switch (mode) { - case 'http': - modeContent = temp('core.msg.view.mode.http', { - ...http, - reverse_port: http['reverse-port'], - retry_time: http['retry-time'], - }); - break; - case 'ws': - modeContent = temp('core.msg.view.mode.ws', { - ...ws, - retry_time: ws['retry-time'], - }); - break; - case 'ws-reverse': - modeContent = temp('core.msg.view.mode.wsreverse', { - ...wsReverse, - }); - break; - } - const params = control.params.length > 0 ? control.params.join(' ') : BOT_RESULT.EMPTY; - bot.users.list.forEach(content => { - userList += temp('core.msg.view.list', { content }); - }); - bot.groups.list.forEach(content => { - groupList += temp('core.msg.view.list', { content }); - }); - switch (bot.users.type) { - case BotConfigFilter.BLACK: - userList = temp('core.msg.view.user.black', { - list: bot.users.type, - }); - break; - case BotConfigFilter.WHITE: - userList = temp('core.msg.view.user.white', { - list: userList, - }); - break; - } - switch (bot.groups.type) { - case BotConfigFilter.BLACK: - groupList = temp('core.msg.view.group.black', { - list: groupList, - }); - break; - case BotConfigFilter.WHITE: - groupList = temp('core.msg.view.group.white', { - list: groupList, - }); - break; - } - - return temp('core.msg.view', { - mode: CONNECT_MODE[mode], - mode_content: modeContent, - ...control, - params, - master: bot.master, - user: formatOption(!!bot.users.type), - group: formatOption(!!bot.groups.type), - user_list: bot.users.type ? userList : '', - group_list: bot.groups.type ? groupList : '', - }); -}).help('core.descr.view'); - -Kotori.command('plugin').action( () => { - const pluginsJson = path.join(CONST.CONFIG_PATH, 'plugins.json'); - const data = loadConfig(pluginsJson) as string[]; - if (data.args[0] === 'query') { - let result = ''; - for (const element of Main.Proxy) { - if (data.args[1] && element[1] !== data.args[1]) continue; - const res = element[3] ?? {}; - res.name = res?.name ?? BOT_RESULT.EMPTY; - res.version = res?.version ?? BOT_RESULT.EMPTY; - res.description = res?.description ?? BOT_RESULT.EMPTY; - res.author = res?.author ?? BOT_RESULT.EMPTY; - res.license = res?.license ?? BOT_RESULT.EMPTY; - result += temp('core.msg.plugin.list', { - id: element[1], - ...res, - state: formatOption(!data.includes(element[1])), - }); - } - return result - ? temp('core.msg.plugin.query', { - num: Main.Proxy.length, - list: result, - }) - : temp('core.msg.plugin.fail', { - target: data.args[1], - }); - } - if (data.args[0] === 'ban') { - if (data.includes(data.args[1])) return BOT_RESULT.EXIST; - data.push(data.args[1]); - saveConfig(pluginsJson, data); - return temp('core.msg.plugin.ban', { - target: data.args[1], - }); - } - if (data.args[0] === 'unban') { - if (!data.includes(data.args[1])) return BOT_RESULT.NO_EXIST; - saveConfig( - pluginsJson, - data.filter(item => item !== data.args[1]), - ); - return temp('core.msg.plugin.unban', { - target: data.args[1], - }); - } - return BOT_RESULT.ARGS_ERROR; -}) - .help('core.descr.plugin') - .params({ - query: { - help: 'core.descr.plugin.query', - args: [ - { - must: false, - name: 'pluginId', - }, - ], - }, - ban: { - help: 'core.descr.plugin.ban', - args: [ - { - must: true, - name: 'pluginId', - }, - ], - }, - unban: { - help: 'core.descr.plugin.unban', - args: [ - { - must: true, - name: 'pluginId', - }, - ], - }, - }); - -Kotori.command('bot').action( () => { - const { self_id: selfId, connect, status } = Main.Const.BOT; - const STAT = status.stat; - return temp('core.msg.bot', { - self_id: selfId, - ...STAT, - connect: formatTime(new Date(connect * 1000)), - last_message_time: formatTime(new Date(STAT.last_message_time * 1000)), - }); -}).help('core.descr.bot'); - -Kotori.command('env').action( () => { - const ENV = dealEnv(); - return temp('core.msg.env', { ...ENV }); -}).help('core.descr.env'); - -Kotori.command('ver').action( () => { - const { version, license } = getPackageInfo(); - return temp('core.msg.ver', { version, license }); -}).help('core.descr.ver'); - -Kotori.command('status').action( () => { - const { model, speed, num, rate: cpuRate } = dealCpu(); - const { total, used, rate: ramRate } = dealRam(); - return temp('core.msg.status', { - type: os.type(), - platform: os.platform(), - arch: os.arch(), - model, - speed: speed.toFixed(2), - num, - cpu_rate: cpuRate.toFixed(2), - total: total.toFixed(2), - used: used.toFixed(2), - ram_rate: ramRate.toFixed(2), - network: Object.keys(os.networkInterfaces()).length, - time: dealTime(), - hostname: os.hostname(), - homedir: os.homedir(), - }); -}).help('core.descr.status'); - -Kotori.command('about').action( () => { - const { version, license } = getPackageInfo(); - return temp('core.msg.about', { - version, - license, - }); -}).help('core.descr.about'); - -Kotori.command('update').action( async () => { - const { version } = getPackageInfo(); - const res = (await fetchJson('https://biyuehu.github.io/kotori-bot/package.json')) as PackageInfo; - const content = - res.version === version - ? 'core.msg.update.yes' - : temp('core.msg.update.no', { - version: res.version, - }); - const result = res && res.version; - return [result ? 'core.msg.update' : BOT_RESULT.SERVER_ERROR, result ? { version, content } : { res }]; -}).help('core.descr.update'); - -Core.auto(() => { - const result = loadConfig(path.join(Main.Const.DATA_PLUGIN_PATH, 'system.ini'), 'txt') as string; - const isPrivate = result === 'private'; - const id = isPrivate ? Main.Const.CONFIG.bot.master : parseInt(result, 10); - if (id) Main.Api.send_msg(isPrivate ? 'private' : 'group', Locale.locale('core.msg.system.info.0'), id); - saveConfig(path.join(Main.Const.DATA_PLUGIN_PATH, 'system.ini'), '', 'txt'); -}); - -Core.auto(async () => { - const { version } = getPackageInfo(); - const res = (await fetch('https://biyuehu.github.io/kotori-bot/package.json') - .then(res => res.json()) - .catch(() => console.error('Get update failed, please check your network'))) as PackageInfo; - if (!res) { - console.error(`Detection update failed`); - return; - } - if (res.version === version) { - console.log('Kotori-bot is currently the latest version'); - return; - } - console.warn( - `The current version of Kotori-bot is ${version}, and the latest version is ${res.version}. Please go to ${GLOBAL.REPO} to update`, - ); - - Main.Api.send_private_msg( - temp('core.msg.update', { - version, - content: temp('core.msg.update.no', { - version: res.version, - }), - }), - Main.Const.CONFIG.bot.master, - ); -}); - -export default Main; diff --git a/modules1/status/src/method.ts b/modules1/status/src/method.ts deleted file mode 100644 index fc1e3866..00000000 --- a/modules1/status/src/method.ts +++ /dev/null @@ -1,122 +0,0 @@ -/* - * @Author: hotaru biyuehuya@gmail.com - * @Blog: https://hotaru.icu - * @Date: 2023-07-15 15:52:17 - * @LastEditors: hotaru biyuehuya@gmail.com - * @LastEditTime: 2023-08-21 18:39:27 - */ -import os from 'os'; -import { existsSync } from 'fs'; -import path from 'path'; -import { version as versionTs } from 'typescript'; -import { VERSION as versionTsnode } from 'ts-node'; -import { Locale, fetchJson, fetchText, loadConfig, saveConfig, stringTemp } from '@/tools'; -import type { FuncFetchSuper, FuncStringProcessStr, obj } from '@/tools'; -import SDK from '@/utils/class.sdk'; -import { BOT_RESULT, GLOBAL, URL } from './type'; - -export const dealTime() { - const seconds = Math.floor(os.uptime()); - let day: FuncStringProcessStr = Math.floor(seconds / (3600 * 24)); - let hours: FuncStringProcessStr = Math.floor((seconds - day * 3600 * 24) / 3600); - let minutes: FuncStringProcessStr = Math.floor((seconds - day * 3600 * 24 - hours * 3600) / 60); - let second: FuncStringProcessStr = seconds % 60; - - if (day < 10) { - day = `0${day}`; - } - - if (hours < 10) { - hours = `0${hours}`; - } - - if (minutes < 10) { - minutes = `0${minutes}`; - } - - if (second < 10) { - second = `0${second}`; - } - - return [day, hours, minutes, second].join(':'); -}; - -export const dealRam() { - const total = os.totalmem() / 1024 / 1024 / 1024; - const unused = os.freemem() / 1024 / 1024 / 1024; - const used = total - unused; - const rate = (used / total) * 100; - return { - total, - unused, - used, - rate, - }; -}; - -export const dealCpu() { - const cpuData = os.cpus(); - let rate: number = 0; - const ratearr: number[] = []; - cpuData.forEach(key => { - const { times } = key; - const usage = (1 - times.idle / (times.idle + times.user + times.nice + times.sys + times.irq)) * 100; - ratearr.push(usage); - rate += usage; - }); - return { - model: cpuData[0].model, - speed: cpuData[0].speed / 1024, - num: cpuData.length, - rate, - ratearr, - }; -}; - -export const dealEnv() ({ - node: process.versions.node, - typescript: versionTs, - tsnode: versionTsnode, -}); - -export const initConfig(filePath: string) { - const banword = path.join(filePath, 'banword.json'); - const banwordDefault = ['傻逼', '草拟吗', 'cnm', '死妈']; - if (!existsSync(banword)) saveConfig(banword, banwordDefault); -}; - -let CONFIG_PLUGIN_PATH: string; -export const setPath(value: string) { - CONFIG_PLUGIN_PATH = value; -}; - -export const loadConfigP = (filename: string, init: object = []): object => { - const PATH = path.join(CONFIG_PLUGIN_PATH, filename); - return (loadConfig(PATH, 'json', init) as object) || init; -}; - -export const saveConfigP(filename: string, content: object) { - const PATH = path.join(CONFIG_PLUGIN_PATH, filename); - return saveConfig(PATH, content); -}; - -export const fetchJ: FuncFetchSuper = async (url, params, init) => { - const result = fetchJson(url.substring(0, 4) === 'http' ? url : URL.API + url, params, init); - return result; -}; - -export const fetchT: FuncFetchSuper = async (url, params, init) => { - const result = fetchText(url.substring(0, 4) === 'http' ? url : URL.API + url, params, init); - return result; -}; - -export const temp(message: string, params: obj) { - let msg = Locale.locale(message); - msg = stringTemp(msg, GLOBAL); - msg = stringTemp(msg, BOT_RESULT); - return stringTemp(msg, params); -}; - -export const getQq(msg: string) (msg ? SDK.get_at(msg) || parseInt(msg, 10) : null); - -export const formatOption(option: boolean) (option ? BOT_RESULT.OPTION_ON : BOT_RESULT.OPTION_OFF); diff --git a/modules1/status/src/type.ts b/modules1/status/src/type.ts deleted file mode 100644 index daa786bb..00000000 --- a/modules1/status/src/type.ts +++ /dev/null @@ -1,102 +0,0 @@ -import { Locale, getPackageInfo } from '@/tools'; -import { Api, EventDataType, Msg, obj } from '@/tools/type'; -import SDK from '@/utils/class.sdk'; - -export const enum SCOPE { - ALL, - PRIVATE, - GROUP, -} - -export const enum ACCESS { - NORMAL, - MANGER, - ADMIN, -} - -export const enum URL { - API = 'https://api.hotaru.icu/api/', - BLOG = 'https://hotaru.icu/api/', -} - -export const BOT_RESULT = new Proxy( - { - GUIDE: 'core.temp.result.guide', - SERVER_ERROR: 'core.temp.result.data_error', - ARGS_EMPTY: 'core.temp.result.args.empty', - ARGS_ERROR: 'core.temp.result.args.error', - UNKNOWN_ERROR: 'core.temp.result.unknown_error', - NUM_ERROR: 'core.temp.result.num.error', - NUM_CHOOSE: 'core.temp.result.num.choose', - NO_ACCESS_1: 'core.temp.result.no_access.1', - NO_ACCESS_2: 'core.temp.result.no_access.2', - DISABLE: 'core.temp.result.disable', - EXIST: 'core.temp.result.exist', - NO_EXIST: 'core.temp.result.no_esist', - REPAIRING: 'core.temp.result.repairing', - APIKEY_EMPTY: 'core.temp.result.apikey_error', - EMPTY: 'core.temp.result.empty', - MESSAGE_TYPE: 'core.temp.result.message_type', - OPTION_ON: 'core.temp.result.option.on', - OPTION_OFF: 'core.temp.result.option.off', - }, - { - get(origin, target): string { - if (typeof target === 'symbol') return ''; - return Locale.locale(origin[target as keyof typeof origin]); - }, - }, -); - -export const GLOBAL = { - HEAD: 'Kotori-Bot:', - REPO: 'https://github.com/kotorijs/kotori', - AVATAR: SDK.cq_image(`https://q.qlogo.cn/headimg_dl?spec=640&dst_uin=2142124427`), - DOC: 'http://??????????.com', - AUTHOR: `By ${getPackageInfo().author}`, -}; - -export type CoreKeyword = string | string[]; -export type CoreKeywordMatch(str: string) boolean; -export type CoreVal = CoreValCallback | string; -export type CoreValCallback(send: Send, data: EventDataType) CoreValCallbackVal | Promise; -export type CoreValCallbackVal = void | string | [string, obj]; -export type Cmd = Map; -export type CmdInfo = Cmd; -export type InfoValArg = InfoArg[] | InfoArgEx; -export type Hook(data: EventDataType, send: Send, api: Api) boolean; -export type Send(msg: Msg, params?: obj) void; - -export interface InfoVal { - params?: InfoValArg; - help?: string; - menuId?: string; - scope: SCOPE; - access: ACCESS; -} - -export interface InfoArg { - must: boolean | string; - name?: string; - rest?: boolean; -} - -export interface InfoArgEx { - [key: string]: { - help?: string; - args?: InfoArg[] /* | InfoArgEx */ | null; - }; -} - -export type dataType = string | number | boolean | obj | string[] | number[] | obj[]; - -export interface Res extends obj { - code: 500 | 501 | 502; - message?: string; - data?: T; -} - -export interface ResAfter extends Res { - code: 500; - data: dataType; -} diff --git a/package.json b/package.json index fe0946b3..60426d5e 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,8 @@ { "name": "@kotori-bot/root", - "version": "1.0.0", "description": "ChatBot Framework", + "version": "1.0.0", + "packageManager": "pnpm@8.7.4", "private": true, "scripts": { "kotori": "pnpm --filter kotori-bot", @@ -12,10 +13,9 @@ "test": "echo testing", "lint": "eslint \"{packages,modules}/*/src/*.{ts,tsx}\" --fix", "format": "prettier --config .prettierrc \"{packages,modules}/*/src/*.ts\" --write", - "version": "cd ./packages/kotori && pnpm exec conventional-changelog -p angular -i CHANGELOG.md -s -r 0", - "release": "pnpm changeset && pnpm exec release", - "release:only": "pnpm exec release", - "publish": "pnpm changeset publish --no-git-tag" + "version": "pnpm exec conventional-changelog -p angular -i CHANGELOG.md -s -r 0", + "release": "pnpm exec release", + "release:only": "pnpm exec release" }, "license": "GPL-3.0", "author": "Hotaru ", @@ -28,11 +28,11 @@ "kotori.yml" ], "bin": { - "release": "./scripts/release.ts" + "release": "./scripts/release.ts", + "release3": "./scripts/release3.ts" }, "devDependencies": { - "tsconfig-paths": "^4.2.0", - "@changesets/cli": "^2.27.1", + "@manypkg/get-packages": "^2.2.0", "@types/inquirer": "^9.0.7", "@types/node": "^20.8.7", "@typescript-eslint/eslint-plugin": "^6.4.0", @@ -46,6 +46,7 @@ "eslint-plugin-prettier": "^5.0.0", "execa": "^8.0.1", "inquirer": "^9.2.12", - "prettier": "^3.0.2" + "prettier": "^3.0.2", + "tsconfig-paths": "^4.2.0" } } \ No newline at end of file diff --git a/packages/core/CHANGELOG.md b/packages/core/CHANGELOG.md deleted file mode 100644 index 3dc8706a..00000000 --- a/packages/core/CHANGELOG.md +++ /dev/null @@ -1,7 +0,0 @@ -# @kotori-bot/core - -## 1.1.0 - -### Minor Changes - -- 1.1.0 diff --git a/packages/core/package.json b/packages/core/package.json index 36905157..7c0efc58 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@kotori-bot/core", - "version": "1.1.0", + "version": "1.0.0", "description": "Kotori Core", "main": "lib/index.js", "license": "GPL-3.0", diff --git a/packages/kotori/CHANGELOG.md b/packages/kotori/CHANGELOG.md deleted file mode 100644 index 2e749374..00000000 --- a/packages/kotori/CHANGELOG.md +++ /dev/null @@ -1,75 +0,0 @@ -# [1.1.0](https://github.com/kotorijs/kotori/compare/v1.0.0...v1.1.0) (2023-12-30) - - -### Features - -* kotori-bot core ([ab3894e](https://github.com/kotorijs/kotori/commit/ab3894e54a391653b3169ddbb6770d17e85bd8d3)) - - - -# [1.0.0](https://github.com/kotorijs/kotori/compare/v0.7.8...v1.0.0) (2023-12-29) - - -### Features - -* add more callback type and querytool ([952d6fc](https://github.com/kotorijs/kotori/commit/952d6fc9e2bd34af3c7f77c63e8652c8ad7a14bb)) -* add some events and fix command,message ([a68b292](https://github.com/kotorijs/kotori/commit/a68b292b165b02707cce04818c0226adc9876e21)) -* cmd adapter and loader modules ([d698df1](https://github.com/kotorijs/kotori/commit/d698df1cdae524c43a39bd75aeebde8c32fdca39)) -* cmd adapter and loader modules ([f2b656a](https://github.com/kotorijs/kotori/commit/f2b656a3a367d74a1b16a058430d7027b539a2e4)) -* loader and modules && mixed && command ([c0a2abe](https://github.com/kotorijs/kotori/commit/c0a2abe5a27dbb7a3f5523861ca1310c76b1645f)) -* loader and modules && mixed && command ([9ba0bc9](https://github.com/kotorijs/kotori/commit/9ba0bc98a18aa193d588630c8c6ca8c9ab3a25e8)) -* loader and modules,mixed,command ([5d11c5f](https://github.com/kotorijs/kotori/commit/5d11c5f1e25fbd30a49a5333661e1c052bdf83d2)) -* loader updated, as subpack and core-18n ([1e5a6ec](https://github.com/kotorijs/kotori/commit/1e5a6ec12cc7a3ee697fc0d4249acc2e74fe4220)) -* new plugins and adapter-tencent-qq and some fixs ([5512975](https://github.com/kotorijs/kotori/commit/55129758c529cf7ac6cc446ed2202d14c6446a63)) -* new plugins,event.before and bug fix ([283d4c8](https://github.com/kotorijs/kotori/commit/283d4c8505b828151ff84e16bfdb23d7928135ae)) -* some changes about class static ([a440959](https://github.com/kotorijs/kotori/commit/a4409593f645004b2465af2cafe7304205262bff)) -* type checker i18n and error handle ([4596740](https://github.com/kotorijs/kotori/commit/45967408dcd3957a433d7f0aa0b01dd79931ef89)) -* v1 events,modules,message,content,api,adapter,core ([b6349cb](https://github.com/kotorijs/kotori/commit/b6349cb075f1caf7d1151e607e368f4e5de44c45)) - - - -## [0.7.8](https://github.com/kotorijs/kotori/compare/v0.7.7...v0.7.8) (2023-09-10) - - -### Features - -* grouper plugin and favicon ([3640024](https://github.com/kotorijs/kotori/commit/3640024d5a8b289826b2068a4a78b9397b9fdb5f)) - - - -## [0.7.7](https://github.com/kotorijs/kotori/compare/v0.7.6...v0.7.7) (2023-08-26) - - -### Features - -* grouper plugin and favicon ([6756cee](https://github.com/kotorijs/kotori/commit/6756cee88a5bf1e1b9e88a2becef1023ca401b3a)) - - - -## [0.7.6](https://github.com/kotorijs/kotori/compare/v0.7.5...v0.7.6) (2023-08-25) - - -### Features - -* **many plugins:** many plugins ([9e7464a](https://github.com/kotorijs/kotori/commit/9e7464ad6c0bc3e10a673063d762eb469b8cf74c)) - - - -## [0.7.5](https://github.com/kotorijs/kotori/compare/dba239dbd4f1c4fe0067e4b603aab62c31049063...v0.7.5) (2023-08-25) - - -### Bug Fixes - -* regiser plugin events ([6dbca7e](https://github.com/kotorijs/kotori/commit/6dbca7e436abc05842f51154af12a12d22e7c196)) - - -### Features - -* create module,requester ([dba239d](https://github.com/kotorijs/kotori/commit/dba239dbd4f1c4fe0067e4b603aab62c31049063)) -* framework ([18cbe84](https://github.com/kotorijs/kotori/commit/18cbe84ecb5cbbca91c009db5f2e2bd5db0a9351)) -* manger and hitokotos plugin ([20ee234](https://github.com/kotorijs/kotori/commit/20ee23496a209433c656032d300e5474da664945)) -* plugins ([ea644e8](https://github.com/kotorijs/kotori/commit/ea644e85641f39ddbe2fb0b3790cd401d2c758b8)) -* querytool plugin ([d2e5d7c](https://github.com/kotorijs/kotori/commit/d2e5d7c1465d58b84fb916d52c71985bd391f75f)) - - - diff --git a/packages/loader/CHANGELOG.md b/packages/loader/CHANGELOG.md deleted file mode 100644 index 6b57c2bb..00000000 --- a/packages/loader/CHANGELOG.md +++ /dev/null @@ -1,12 +0,0 @@ -# @kotori-bot/loader - -## 1.2.0 - -### Minor Changes - -- 1.1.0 - -### Patch Changes - -- Updated dependencies - - @kotori-bot/core@1.1.0 diff --git a/scripts/release.ts b/scripts/release.ts index 0d8f905c..da6459c3 100644 --- a/scripts/release.ts +++ b/scripts/release.ts @@ -1,117 +1,188 @@ #!/usr/bin/env ts-node -import { readFileSync } from 'fs'; +import { Package, getPackagesSync } from '@manypkg/get-packages'; +import { error, log } from 'console'; +import { writeFileSync } from 'fs'; import { resolve } from 'path'; +const config = { + branch: 'master', + remote: 'origin', + registry: 'https://registry.npmjs.org/', + main: 'kotori-bot', + sync: ['@kotori-bot/core'], + include: '{packages,modules}/*/src/*.{ts,tsx}', + hooks: { + beforeAddcommit: ['pnpm run eslint', 'pnpm run format', 'pnpm run version'], + }, +}; + +const ROOT_DIR = resolve(__dirname, '../'); + +type Version = 'Major' | 'Minor' | 'Patch'; + +type Option = { + cwd: string; +}; + (async () => { - try { - const inquirer = (await import('inquirer')).default; - const Execa = await import('execa'); - const { execa } = Execa; - - const echo = async (cmd: string, args?: string[], option?: unknown) => { - const entity = await execa(cmd, args, option as undefined); - const { stdout: result, stderr: error } = entity; - console.info(result.trim() ? `Result: ${result}` : `Success: ${cmd}`); - if (error) console.error('Error:', error, `\nAt "${cmd}"`); - }; - const dirs = (...args: string[]) => resolve(__dirname, ...args); - const hooks = (hooks: string[]) => - new Promise(resolve => { - hooks.forEach(async (cmd, index) => { - await echo(cmd); - if (index === hooks.length - 1) resolve(undefined); - }); - }); + const { prompt } = (await import('inquirer')).default; + const { execa } = await import('execa'); - /* check branch */ - const config = JSON.parse(readFileSync(dirs('config.json')).toString()); - if (!(await execa('git branch')).stdout.includes(`* ${config.branch}`)) { - console.error(`Branch error! expected: ${config.branch}`); - return; - } + function getTargetPackage(pkgs: Package[], pkgName: string = config.main) { + const filterPackages = pkgs.filter(pkg => pkg.packageJson.name === pkgName); + if (filterPackages.length === 0) return null; + return filterPackages[0]; + } + + async function getFilterPackages(dir: string = ROOT_DIR) { + const { packages, rootPackage } = getPackagesSync(dir); + const { value } = await prompt({ + type: 'checkbox', + name: 'value', + message: 'Select the package you need to update', + choices: packages + .filter(pkg => !config.sync.includes(pkg.packageJson.name)) + .map(pkg => ({ name: pkg.packageJson.name, value: pkg.relativeDir })), + }); + const filterPackages = packages.filter(pkg => value.includes(pkg.relativeDir)); + const mainPkgJson = getTargetPackage(filterPackages)?.packageJson; + if (!mainPkgJson) return filterPackages; + /* Sync packages version by main package */ + config.sync.forEach(async pkgName => { + const pkg = getTargetPackage(packages, pkgName); + if (!pkg) return; + pkg.packageJson.version = mainPkgJson.version; + filterPackages.push(pkg); + }); + if (!rootPackage) return filterPackages; + rootPackage.packageJson.version = mainPkgJson.version; + filterPackages.push(rootPackage); + return filterPackages; + } - /* LifeCycle: BeforeVersion */ - /* code lint and format by eslint and prettier */ - await hooks(config.beforeVersion); - - /* update version info by changeset */ - await echo('pnpm changeset version'); - const defaultVersion = JSON.parse(readFileSync(dirs(config.package, 'package.json')).toString()).version.split('.'); - const answer = await inquirer.prompt([ - { - type: 'number', - name: 'major', - message: 'Input major version', - default: defaultVersion[0], - }, - { - type: 'number', - name: 'minor', - message: 'Input minor version', - default: defaultVersion[1], - }, - { - type: 'number', - name: 'patch', - message: 'Input patch version', - default: defaultVersion[2], - }, - { + async function isUpdateVersion(pkgName: string, version: Version): Promise { + return ( + await prompt({ type: 'confirm', - name: 'submit', - message: 'Do you want to submit it immediately?', - default: true, - }, - ]); - - /* handle tag */ - const version = `v${answer.major}.${answer.minor}.${answer.patch}`; - if ((await execa('git tag -l')).stdout.includes(version)) { - console.error(`Error: tag ${version} already exists`); - return; + name: 'value', + message: `For ${pkgName} : update ${version} version?`, + default: false, + }) + ).value; + } + + function setVersion(pkg: Package) { + writeFileSync(resolve(pkg.dir, 'package.json'), JSON.stringify(pkg.packageJson), 'utf-8'); + } + + async function getVersion(pkg: Package) { + const version = pkg.packageJson.version.split('.'); + if (await isUpdateVersion(pkg.packageJson.name, 'Major')) return `v${version[0] + 1}.0.0`; + if (await isUpdateVersion(pkg.packageJson.name, 'Minor')) return `v${version[0]}.${version[1] + 1}.0`; + return `v${version[0]}.${version[1]}.${version[2] + 1}`; + } + + function publishPackages(pkgs: Package[]) { + return new Promise(resolve => { + pkgs.forEach(async (pkg, index) => { + await step('pnpm publish --access --access public', undefined, { cwd: pkg.dir }); + if (index === pkgs.length - 1) resolve(undefined); + }); + }); + } + + async function step(cmd: string, args?: string[], option: Option = { cwd: ROOT_DIR }, print: boolean = false) { + try { + const entity = await execa(cmd, args, option); + const { stdout, stderr } = entity; + if (stderr) error('Error:', stderr, `\nAt "${cmd}"`); + log(print ? `Result: ${stdout}` : `Success: ${cmd}`); + } catch (err) { + error('Run Error:', error, `\nAt "${cmd}"`); } - await echo(`git tag ${version}`); + } - /* LifeCycle: BeforeAddcommit */ - /* spawn changelog by conventional-changelog */ - await hooks(config.beforeAddcommit); + function hooks(hooks: string[]) { + return new Promise(resolve => { + hooks.forEach(async (cmd, index) => { + await step(cmd); + if (index === hooks.length - 1) resolve(undefined); + }); + }); + } - /* auto commit and push remote branch */ - if (!answer.submit) return; - const answer2 = await inquirer.prompt([ - { - type: 'confirm', - name: 'push', - message: 'Do you need auto push to remote branch?', - default: false, - }, - ]); - await echo('git add .'); - await echo(`git commit -m "chore: ${version}"`); - if (!answer2.push) { - console.info(`All ok!\nPlease enter "git push origin ${config.branch} --tags"`); - return; + /* Main Program */ + /* Step: check branch */ + if (!(await execa('git branch')).stdout.includes(`* ${config.branch}`)) { + error(`Branch error! expected: ${config.branch}`); + return; + } + + /* Step: update version */ + const packages = await getFilterPackages(); + if (packages.length === 0) { + log(`No package selected`); + } + packages.forEach(async pkg => { + const handle = pkg; + handle.packageJson.version = await getVersion(pkg); + try { + setVersion(handle); + } catch (e) { + error(`Error: write failed at package ${pkg.packageJson.name}`); } - echo(`git push origin ${config.branch} --tags`); + }); + log('Update version and write successful'); - const answer3 = await inquirer.prompt([ - { - type: 'confirm', - name: 'pack', - message: 'Do you need auto pack main package?', - default: false, - }, - { - type: 'confirm', - name: 'publish', - message: 'Do you need auto publish all package?', - default: false, - }, - ]); - if (answer3.pack) echo('pnpm pack', undefined, { cwd: config.main }); - if (answer3.pack) echo('pnpm changeset publish --no-git-tag'); - } catch (error) { - console.error('Unexpected error: ', error); + /* Lifecycle: beforeAddcommit */ + await hooks(config.hooks.beforeAddcommit); + + const answer = await prompt([ + { + type: 'confirm', + name: 'push', + message: 'Do you need push to remote branch?', + default: true, + }, + { + type: 'confirm', + name: 'publish', + message: 'Do you need publish all updated package?', + default: true, + }, + ]); + const mainPkg = getTargetPackage(packages); + if (mainPkg) { + /* Step: spawn tag */ + const mainVersion = `v${mainPkg.packageJson.version}`; + if ((await execa('git tag -l')).stdout.includes(mainVersion)) { + console.error(`Error: tag ${mainVersion} already exists`); + } + await step('git add .'); + await step(`git commit -m "release: ${mainVersion}"`); + await step(`git tag ${mainVersion}`); + /* Step: zip main package */ + const answer = await prompt({ + type: 'confirm', + name: 'value', + message: 'Do you need zip main package?', + default: true, + }); + if (answer.value) await step('pnpm pack', undefined, { cwd: mainPkg.dir }); } + + /* Step: push to remote branch */ + const pushCommand = `git push ${config.remote} ${config.branch} ${mainPkg ? '--tags' : ''}`; + if (answer.push) step(pushCommand); + + /* Step: checkout registry and publish */ + const originRegistry = (await execa('pnpm config get registry')).stdout.replace(/(\n)|(\r)/g, ''); + await execa(`pnpm config set registry "${config.registry}"`); + await publishPackages(packages); + await execa(`pnpm config set registry "${originRegistry}"`); + + /* ending */ + if (!answer.push) log(`\nPlease enter "${pushCommand}"`); + log(`All ok!`); })(); diff --git a/scripts/release2.ts b/scripts/release2.ts new file mode 100644 index 00000000..3725c2c8 --- /dev/null +++ b/scripts/release2.ts @@ -0,0 +1,116 @@ +#!/usr/bin/env ts-node + +import { readFileSync } from 'fs'; +import { resolve } from 'path'; + +(async () => { + try { + const inquirer = (await import('inquirer')).default; + const Execa = await import('execa'); + const { execa } = Execa; + + const echo = async (cmd: string, args?: string[], option?: unknown) => { + const entity = await execa(cmd, args, option as undefined); + const { stdout: result, stderr: error } = entity; + console.info(result.trim() ? `Result: ${result}` : `Success: ${cmd}`); + if (error) console.error('Error:', error, `\nAt "${cmd}"`); + }; + const dirs = (...args: string[]) => resolve(__dirname, ...args); + const hooks = (hooks: string[]) => + new Promise(resolve => { + hooks.forEach(async (cmd, index) => { + await echo(cmd); + if (index === hooks.length - 1) resolve(undefined); + }); + }); + + /* check branch */ + const config = JSON.parse(readFileSync(dirs('config.json')).toString()); + if (!(await execa('git branch')).stdout.includes(`* ${config.branch}`)) { + console.error(`Branch error! expected: ${config.branch}`); + return; + } + + /* LifeCycle: BeforeVersion */ + /* code lint and format by eslint and prettier */ + await hooks(config.beforeVersion); + + /* update version info by changeset */ + const defaultVersion = JSON.parse(readFileSync(dirs(config.package, 'package.json')).toString()).version.split('.'); + const answer = await inquirer.prompt([ + { + type: 'number', + name: 'major', + message: 'Input major version', + default: defaultVersion[0], + }, + { + type: 'number', + name: 'minor', + message: 'Input minor version', + default: defaultVersion[1], + }, + { + type: 'number', + name: 'patch', + message: 'Input patch version', + default: defaultVersion[2], + }, + { + type: 'confirm', + name: 'submit', + message: 'Do you want to submit it immediately?', + default: true, + }, + ]); + + /* handle tag */ + const version = `v${answer.major}.${answer.minor}.${answer.patch}`; + if ((await execa('git tag -l')).stdout.includes(version)) { + console.error(`Error: tag ${version} already exists`); + return; + } + await echo(`git tag ${version}`); + + /* LifeCycle: BeforeAddcommit */ + /* spawn changelog by conventional-changelog */ + await hooks(config.beforeAddcommit); + + /* auto commit and push remote branch */ + if (!answer.submit) return; + const answer2 = await inquirer.prompt([ + { + type: 'confirm', + name: 'push', + message: 'Do you need auto push to remote branch?', + default: false, + }, + ]); + await echo('git add '); + await echo(`git commit -m "chore: ${version}"`); + if (!answer2.push) { + console.info(`All ok!\nPlease enter "git push origin ${config.branch} --tags"`); + return; + } + echo(`git push origin ${config.branch} --tags`); + + const answer3 = await inquirer.prompt([ + { + type: 'confirm', + name: 'pack', + message: 'Do you need auto pack main package?', + default: false, + }, + { + type: 'confirm', + name: 'publish', + message: 'Do you need auto publish all package?', + default: false, + }, + ]); + if (answer3.pack) echo('pnpm pack', undefined, { cwd: config.main }); + if (answer3.pack) echo('pnpm changeset publish --no-git-tag'); + } catch (error) { + console.error('Unexpected error: ', error); + } +})();