koishi-plugin-18xx 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/api.d.ts +0 -0
- package/lib/command.d.ts +3 -0
- package/lib/config.d.ts +20 -0
- package/lib/index.d.ts +5 -0
- package/lib/index.js +252 -0
- package/lib/server.d.ts +3 -0
- package/package.json +50 -0
- package/readme.md +5 -0
package/lib/api.d.ts
ADDED
File without changes
|
package/lib/command.d.ts
ADDED
package/lib/config.d.ts
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
import { Schema } from 'koishi';
|
2
|
+
export declare const name = "18xx";
|
3
|
+
export declare const inject: {
|
4
|
+
required: string[];
|
5
|
+
};
|
6
|
+
export interface Config {
|
7
|
+
notification: {
|
8
|
+
enable: boolean;
|
9
|
+
path: string;
|
10
|
+
items: {
|
11
|
+
platform: string;
|
12
|
+
defaultGuildId: string;
|
13
|
+
guildIds: string[];
|
14
|
+
defaultBotIds: string[];
|
15
|
+
botIds: string[];
|
16
|
+
}[];
|
17
|
+
};
|
18
|
+
}
|
19
|
+
export declare const Config: Schema<Config>;
|
20
|
+
export default Config;
|
package/lib/index.d.ts
ADDED
package/lib/index.js
ADDED
@@ -0,0 +1,252 @@
|
|
1
|
+
var __defProp = Object.defineProperty;
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
5
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
6
|
+
var __export = (target, all) => {
|
7
|
+
for (var name2 in all)
|
8
|
+
__defProp(target, name2, { get: all[name2], enumerable: true });
|
9
|
+
};
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
12
|
+
for (let key of __getOwnPropNames(from))
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
15
|
+
}
|
16
|
+
return to;
|
17
|
+
};
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
19
|
+
|
20
|
+
// src/index.ts
|
21
|
+
var src_exports = {};
|
22
|
+
__export(src_exports, {
|
23
|
+
Config: () => Config,
|
24
|
+
apply: () => apply,
|
25
|
+
inject: () => inject,
|
26
|
+
name: () => name
|
27
|
+
});
|
28
|
+
module.exports = __toCommonJS(src_exports);
|
29
|
+
|
30
|
+
// src/config.ts
|
31
|
+
var import_koishi = require("koishi");
|
32
|
+
var name = "18xx";
|
33
|
+
var inject = {
|
34
|
+
required: ["server", "database"]
|
35
|
+
// optional: ['puppeteer'],
|
36
|
+
};
|
37
|
+
var Config = import_koishi.Schema.object({
|
38
|
+
notification: import_koishi.Schema.object({
|
39
|
+
enable: import_koishi.Schema.boolean().default(true).description("启用通知"),
|
40
|
+
path: import_koishi.Schema.string().default("/18xx").description("Webhook 监听路径"),
|
41
|
+
items: import_koishi.Schema.array(
|
42
|
+
import_koishi.Schema.object({
|
43
|
+
platform: import_koishi.Schema.string().default("").description("平台,为空表示不限制"),
|
44
|
+
defaultGuildId: import_koishi.Schema.string().default("").description("默认发送通知的群,如果不指定,通知会被发送到绑定时的群,如果绑定时没有群,通知不会发送"),
|
45
|
+
guildIds: import_koishi.Schema.array(import_koishi.Schema.string()).default([]).description("允许发送通知的群,为空表示允许在所有群发送通知"),
|
46
|
+
defaultBotIds: import_koishi.Schema.array(import_koishi.Schema.string()).default([]).description("默认发送通知的机器人,如果不指定,通知由绑定时的机器人发送"),
|
47
|
+
botIds: import_koishi.Schema.array(import_koishi.Schema.string()).default([]).description("允许发送通知的机器人,如果先前的机器人都无法工作,将会尝试使用后面的机器人发送通知,为空表示允许所有机器人发送通知")
|
48
|
+
})
|
49
|
+
).default([]).description("平台通知设置")
|
50
|
+
}).description("通知设置")
|
51
|
+
});
|
52
|
+
|
53
|
+
// src/command.ts
|
54
|
+
function command(ctx, config) {
|
55
|
+
const logger = ctx.logger(name);
|
56
|
+
const checkSessionMiddleware = /* @__PURE__ */ __name(({ session }) => {
|
57
|
+
if (!session.guildId) {
|
58
|
+
return "请在群里使用这个命令";
|
59
|
+
}
|
60
|
+
if (config.notification.items.length) {
|
61
|
+
let found = false;
|
62
|
+
for (const { botIds, guildIds, defaultBotIds, defaultGuildId } of config.notification.items.filter(
|
63
|
+
(item) => !item.platform || item.platform === session.platform
|
64
|
+
)) {
|
65
|
+
if (botIds.length && !botIds.includes(session.selfId) && !defaultBotIds.includes(session.selfId)) {
|
66
|
+
continue;
|
67
|
+
}
|
68
|
+
if (guildIds.length && !guildIds.includes(session.guildId) && defaultGuildId !== session.guildId) {
|
69
|
+
continue;
|
70
|
+
}
|
71
|
+
found = true;
|
72
|
+
break;
|
73
|
+
}
|
74
|
+
if (!found) return "";
|
75
|
+
}
|
76
|
+
}, "checkSessionMiddleware");
|
77
|
+
ctx.command("18xx.bind <id>", "绑定 18xx.games 账号").usage("id 是个人资料页地址栏 profile 后面的数字").before(checkSessionMiddleware).action(async ({ session }, id) => {
|
78
|
+
if (Number(id)) {
|
79
|
+
const result = await ctx.database.upsert(name, [
|
80
|
+
{
|
81
|
+
id: Number(id),
|
82
|
+
userId: session.userId,
|
83
|
+
platform: session.platform,
|
84
|
+
botId: session.selfId,
|
85
|
+
guildId: session.guildId
|
86
|
+
}
|
87
|
+
]);
|
88
|
+
if (result.inserted) {
|
89
|
+
return `${id} 绑定成功`;
|
90
|
+
} else {
|
91
|
+
return `${id} 重新绑定成功`;
|
92
|
+
}
|
93
|
+
} else {
|
94
|
+
return "绑定失败";
|
95
|
+
}
|
96
|
+
});
|
97
|
+
ctx.command("18xx.unbind <id>", "取消绑定 18xx.games 账号").usage("id 是个人资料页地址栏 profile 后面的数字").action(async ({ session }, id) => {
|
98
|
+
const result = await ctx.database.remove(name, { id: Number(id), userId: session.userId });
|
99
|
+
if (!result.matched) {
|
100
|
+
return "你还没有绑定 18xx.games 账号";
|
101
|
+
}
|
102
|
+
if (result.removed) {
|
103
|
+
return `${id} 解绑成功`;
|
104
|
+
}
|
105
|
+
return "解绑失败";
|
106
|
+
});
|
107
|
+
ctx.command("18xx.list", "列出已绑定的 18xx.games 账号").alias("18xx.ls").action(async ({ session }) => {
|
108
|
+
const profiles = await ctx.database.get(name, { userId: session.userId });
|
109
|
+
if (!profiles.length) {
|
110
|
+
return "你还没有绑定 18xx.games 账号";
|
111
|
+
}
|
112
|
+
return `当前已绑定${profiles.length}个账号:
|
113
|
+
${profiles.map((p) => `${p.id}`).join("\n")}`;
|
114
|
+
});
|
115
|
+
ctx.command("18xx.on", "开启 18xx.games 通知").usage("需要先绑定 18xx.games 账号,并在个人资料页 webhook_user_id 中填入你的 id").action(async ({ session }) => {
|
116
|
+
const profiles = await ctx.database.get(name, { userId: session.userId });
|
117
|
+
if (!profiles.length) {
|
118
|
+
return "你还没有绑定 18xx.games 账号";
|
119
|
+
}
|
120
|
+
const result = await ctx.database.upsert(
|
121
|
+
name,
|
122
|
+
profiles.map((p) => ({ ...p, notify: true }))
|
123
|
+
);
|
124
|
+
if (result.matched > 1) {
|
125
|
+
return `开启了${result.matched || 0}个账号的通知`;
|
126
|
+
}
|
127
|
+
return "通知已开启";
|
128
|
+
});
|
129
|
+
ctx.command("18xx.off", "关闭 18xx.games 通知").action(async ({ session }) => {
|
130
|
+
const profiles = await ctx.database.get(name, { userId: session.userId });
|
131
|
+
if (!profiles.length) {
|
132
|
+
return "你还没有绑定 18xx.games 账号";
|
133
|
+
}
|
134
|
+
const result = await ctx.database.upsert(
|
135
|
+
name,
|
136
|
+
profiles.map((p) => ({ ...p, notify: false }))
|
137
|
+
);
|
138
|
+
if (result.matched > 1) {
|
139
|
+
return `关闭了${result.matched || 0}个账号的通知`;
|
140
|
+
}
|
141
|
+
return "通知已关闭";
|
142
|
+
});
|
143
|
+
}
|
144
|
+
__name(command, "command");
|
145
|
+
|
146
|
+
// src/server.tsx
|
147
|
+
var import_jsx_runtime = require("@satorijs/element/jsx-runtime");
|
148
|
+
var MESSAGE_REGEX = /^<@?(.*?)>\s*(.*)$/;
|
149
|
+
function server(ctx, config) {
|
150
|
+
const logger = ctx.logger(name);
|
151
|
+
if (config.notification.enable) {
|
152
|
+
ctx.server.post(config.notification.path, async (ptx, _next) => {
|
153
|
+
const { text = "" } = ptx.request.body || {};
|
154
|
+
const result = MESSAGE_REGEX.exec(text);
|
155
|
+
if (!result) {
|
156
|
+
logger.error("Webhook格式错误");
|
157
|
+
return ptx.status = 400;
|
158
|
+
}
|
159
|
+
const [, webhookId, message] = result;
|
160
|
+
if (!Number(webhookId) || !message) {
|
161
|
+
logger.error("Webhook格式错误");
|
162
|
+
return ptx.status = 400;
|
163
|
+
}
|
164
|
+
const profiles = await ctx.database.get(name, { id: Number(webhookId) });
|
165
|
+
logger.info("Webhook", webhookId, message, profiles);
|
166
|
+
const sendNotification = /* @__PURE__ */ __name(async (profile, bots = ctx.bots, guildIds = [profile.guildId]) => {
|
167
|
+
let success = false;
|
168
|
+
for (const bot of bots) {
|
169
|
+
for (const guildId of guildIds) {
|
170
|
+
try {
|
171
|
+
const result2 = await bot.sendMessage(
|
172
|
+
guildId,
|
173
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
174
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("at", { id: profile.userId, name: webhookId }),
|
175
|
+
" ",
|
176
|
+
message
|
177
|
+
] })
|
178
|
+
);
|
179
|
+
logger.info("通知发送成功", result2, message, profile);
|
180
|
+
success = true;
|
181
|
+
break;
|
182
|
+
} catch (e) {
|
183
|
+
logger.error("通知发送失败", e, message, profile);
|
184
|
+
}
|
185
|
+
}
|
186
|
+
if (success) {
|
187
|
+
break;
|
188
|
+
}
|
189
|
+
}
|
190
|
+
if (!success) {
|
191
|
+
logger.info("未能发送通知", message, profile);
|
192
|
+
}
|
193
|
+
return success;
|
194
|
+
}, "sendNotification");
|
195
|
+
for (const profile of profiles.filter((profile2) => profile2.notify)) {
|
196
|
+
if (!config.notification.items.length) {
|
197
|
+
await sendNotification(profile);
|
198
|
+
continue;
|
199
|
+
}
|
200
|
+
for (const item of config.notification.items.filter((item2) => !item2.platform || item2.platform === profile.platform)) {
|
201
|
+
if (item.botIds.length && !item.botIds.includes(profile.botId) && !item.defaultBotIds.includes(profile.botId)) {
|
202
|
+
continue;
|
203
|
+
}
|
204
|
+
if (item.guildIds.length && !item.guildIds.includes(profile.guildId) && item.defaultGuildId !== profile.guildId) {
|
205
|
+
continue;
|
206
|
+
}
|
207
|
+
const bots = Array.from(
|
208
|
+
new Set(
|
209
|
+
[
|
210
|
+
...item.defaultBotIds.map((id) => ctx.bots.find((bot) => bot.selfId === id)),
|
211
|
+
ctx.bots.find((bot) => bot.selfId === profile.botId),
|
212
|
+
...item.botIds.map((id) => ctx.bots.find((bot) => bot.selfId === id))
|
213
|
+
].filter(Boolean)
|
214
|
+
)
|
215
|
+
);
|
216
|
+
const guildIds = Array.from(new Set([item.defaultGuildId, profile.guildId, ...item.guildIds].filter(Boolean)));
|
217
|
+
if (await sendNotification(profile, bots, guildIds)) {
|
218
|
+
break;
|
219
|
+
}
|
220
|
+
}
|
221
|
+
}
|
222
|
+
return ptx.status = 200;
|
223
|
+
});
|
224
|
+
logger.info("启用通知服务");
|
225
|
+
}
|
226
|
+
}
|
227
|
+
__name(server, "server");
|
228
|
+
|
229
|
+
// src/index.ts
|
230
|
+
function apply(ctx, config) {
|
231
|
+
ctx.model.extend(name, {
|
232
|
+
id: "integer",
|
233
|
+
userId: "string",
|
234
|
+
platform: "string",
|
235
|
+
botId: "string",
|
236
|
+
guildId: "string",
|
237
|
+
notify: {
|
238
|
+
type: "boolean",
|
239
|
+
initial: true
|
240
|
+
}
|
241
|
+
});
|
242
|
+
command(ctx, config);
|
243
|
+
server(ctx, config);
|
244
|
+
}
|
245
|
+
__name(apply, "apply");
|
246
|
+
// Annotate the CommonJS export names for ESM import in node:
|
247
|
+
0 && (module.exports = {
|
248
|
+
Config,
|
249
|
+
apply,
|
250
|
+
inject,
|
251
|
+
name
|
252
|
+
});
|
package/lib/server.d.ts
ADDED
package/package.json
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
{
|
2
|
+
"name": "koishi-plugin-18xx",
|
3
|
+
"description": "18xxGames 机器人",
|
4
|
+
"version": "0.0.1",
|
5
|
+
"main": "lib/index.js",
|
6
|
+
"typings": "lib/index.d.ts",
|
7
|
+
"files": [
|
8
|
+
"lib",
|
9
|
+
"dist"
|
10
|
+
],
|
11
|
+
"contributors": [
|
12
|
+
"SeaLoong <sealoongw@foxmail.com>"
|
13
|
+
],
|
14
|
+
"license": "MIT",
|
15
|
+
"homepage": "https://github.com/SeaLoong/koishi-plugin-18xx",
|
16
|
+
"repository": {
|
17
|
+
"type": "git",
|
18
|
+
"url": "git+https://github.com/SeaLoong/koishi-plugin-18xx.git"
|
19
|
+
},
|
20
|
+
"keywords": [
|
21
|
+
"koishi",
|
22
|
+
"18xxgames",
|
23
|
+
"webhook"
|
24
|
+
],
|
25
|
+
"devDependencies": {
|
26
|
+
"@koishijs/plugin-adapter-onebot": "^6.0.2",
|
27
|
+
"@koishijs/plugin-server": "^3.2.7",
|
28
|
+
"typescript": "^5.8.3"
|
29
|
+
},
|
30
|
+
"peerDependencies": {
|
31
|
+
"koishi": "^4.18.7",
|
32
|
+
"@satorijs/element": "^3.1.8"
|
33
|
+
},
|
34
|
+
"koishi": {
|
35
|
+
"description": {
|
36
|
+
"en": "18xxGames Bot",
|
37
|
+
"zh": "18xxGames 机器人"
|
38
|
+
},
|
39
|
+
"service": {
|
40
|
+
"required": [
|
41
|
+
"server",
|
42
|
+
"database"
|
43
|
+
]
|
44
|
+
},
|
45
|
+
"locales": [
|
46
|
+
"en",
|
47
|
+
"zh"
|
48
|
+
]
|
49
|
+
}
|
50
|
+
}
|