koishi-plugin-ll-brick 1.0.0
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/index.d.ts +36 -0
- package/lib/index.js +252 -0
- package/package.json +29 -0
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { Context, Schema } from 'koishi';
|
|
2
|
+
export declare const name = "ll-brick";
|
|
3
|
+
export declare const usage = "\u70E7\u7816\u62CD\u4EBA\u63D2\u4EF6\uFF08\u514B\u9686\u81EA koishi-plugin-brick\uFF09\n\u70E7\u5236\u7816\u5757\uFF0C\u7136\u540E\u62CD\u6655\u7FA4\u53CB\uFF01\u5982\u679C\u673A\u5668\u4EBA\u6CA1\u6709\u7981\u8A00\u6743\u9650\uFF0C\u4F1A\u63D0\u793A\"\u6CA1\u4EC0\u4E48\u5375\u7528\"\u3002\n\u5F00\u59CB\u70E7\u5236\u4E4B\u540E\uFF0C\u7FA4\u5185\u5176\u4ED6\u7FA4\u53CB\u53D1\u9001\u4E00\u5B9A\u6570\u91CF\u7684\u6D88\u606F\u5C31\u80FD\u5B8C\u6210\u70E7\u5236\uFF01";
|
|
4
|
+
export interface Brick {
|
|
5
|
+
id: number;
|
|
6
|
+
userId: string;
|
|
7
|
+
guildId: string;
|
|
8
|
+
brick: number;
|
|
9
|
+
lastSlap: number;
|
|
10
|
+
checkingDay: string;
|
|
11
|
+
}
|
|
12
|
+
declare module 'koishi' {
|
|
13
|
+
interface Tables {
|
|
14
|
+
brick: Brick;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
interface SpecialUser {
|
|
18
|
+
[userId: string]: number;
|
|
19
|
+
}
|
|
20
|
+
export interface Config {
|
|
21
|
+
maxBrick: number;
|
|
22
|
+
cost: number;
|
|
23
|
+
cooldown: number;
|
|
24
|
+
minMuteTime: number;
|
|
25
|
+
maxMuteTime: number;
|
|
26
|
+
ignoreMuted: boolean;
|
|
27
|
+
reverse: number;
|
|
28
|
+
specialUser: SpecialUser;
|
|
29
|
+
checking: boolean;
|
|
30
|
+
minGain?: number;
|
|
31
|
+
maxGain?: number;
|
|
32
|
+
}
|
|
33
|
+
export declare const Config: Schema<Config>;
|
|
34
|
+
export declare const inject: string[];
|
|
35
|
+
export declare function apply(ctx: Context, config: Config): Promise<void>;
|
|
36
|
+
export {};
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.inject = exports.Config = exports.usage = exports.name = void 0;
|
|
4
|
+
exports.apply = apply;
|
|
5
|
+
const koishi_1 = require("koishi");
|
|
6
|
+
exports.name = 'll-brick';
|
|
7
|
+
exports.usage = `烧砖拍人插件(克隆自 koishi-plugin-brick)
|
|
8
|
+
烧制砖块,然后拍晕群友!如果机器人没有禁言权限,会提示"没什么卵用"。
|
|
9
|
+
开始烧制之后,群内其他群友发送一定数量的消息就能完成烧制!`;
|
|
10
|
+
exports.Config = koishi_1.Schema.intersect([
|
|
11
|
+
koishi_1.Schema.object({
|
|
12
|
+
maxBrick: koishi_1.Schema.number()
|
|
13
|
+
.default(1)
|
|
14
|
+
.description('砖块最多持有量'),
|
|
15
|
+
cost: koishi_1.Schema.number()
|
|
16
|
+
.required()
|
|
17
|
+
.description('多少条消息能烧好一块砖'),
|
|
18
|
+
cooldown: koishi_1.Schema.number()
|
|
19
|
+
.default(60)
|
|
20
|
+
.description('拍砖冷却时间(秒)'),
|
|
21
|
+
minMuteTime: koishi_1.Schema.number()
|
|
22
|
+
.default(10)
|
|
23
|
+
.description('最小禁言时间(秒)'),
|
|
24
|
+
maxMuteTime: koishi_1.Schema.number()
|
|
25
|
+
.default(120)
|
|
26
|
+
.description('最大禁言时间(秒)'),
|
|
27
|
+
ignoreMuted: koishi_1.Schema.boolean()
|
|
28
|
+
.default(false)
|
|
29
|
+
.description("是否不使用内置计时器判断用户是否被禁言(开启时,用户被拍晕后未被禁言也能正常使用bot以及再被拍晕)"),
|
|
30
|
+
reverse: koishi_1.Schema.number()
|
|
31
|
+
.default(10)
|
|
32
|
+
.max(100)
|
|
33
|
+
.description('反被拍晕的默认概率(%)'),
|
|
34
|
+
specialUser: koishi_1.Schema.dict(Number)
|
|
35
|
+
.role('table')
|
|
36
|
+
.description('键为用户ID,值为被拍时的反击概率(%)<br/>不设置则使用默认概率'),
|
|
37
|
+
}),
|
|
38
|
+
koishi_1.Schema.object({
|
|
39
|
+
checking: koishi_1.Schema.boolean()
|
|
40
|
+
.default(false)
|
|
41
|
+
.description('是否开启每日签到(获取随机数量的砖头)'),
|
|
42
|
+
}),
|
|
43
|
+
koishi_1.Schema.union([
|
|
44
|
+
koishi_1.Schema.object({
|
|
45
|
+
checking: koishi_1.Schema.const(true).required(),
|
|
46
|
+
minGain: koishi_1.Schema.number().required().description('最小获取数量'),
|
|
47
|
+
maxGain: koishi_1.Schema.number().required().description('最大获取数量'),
|
|
48
|
+
}),
|
|
49
|
+
koishi_1.Schema.object({
|
|
50
|
+
checking: koishi_1.Schema.const(false)
|
|
51
|
+
})
|
|
52
|
+
])
|
|
53
|
+
]);
|
|
54
|
+
exports.inject = ["database"];
|
|
55
|
+
async function apply(ctx, config) {
|
|
56
|
+
ctx.model.extend('brick', {
|
|
57
|
+
id: 'unsigned',
|
|
58
|
+
userId: 'string',
|
|
59
|
+
guildId: 'string',
|
|
60
|
+
brick: 'integer',
|
|
61
|
+
lastSlap: 'unsigned',
|
|
62
|
+
checkingDay: 'string'
|
|
63
|
+
}, { primary: 'id', autoInc: true });
|
|
64
|
+
const users = {};
|
|
65
|
+
ctx.command("砖头");
|
|
66
|
+
ctx.command("砖头.烧砖", "烧点砖头拍人")
|
|
67
|
+
.alias("烧砖")
|
|
68
|
+
.action(async ({ session }) => {
|
|
69
|
+
const user = `${session.guildId}:${session.userId}`;
|
|
70
|
+
if (!users[user]) {
|
|
71
|
+
users[user] = { burning: false, muted: false };
|
|
72
|
+
}
|
|
73
|
+
const brickData = await ctx.database.get('brick', {
|
|
74
|
+
userId: session.userId,
|
|
75
|
+
guildId: session.guildId
|
|
76
|
+
});
|
|
77
|
+
if (brickData.length === 0) {
|
|
78
|
+
await ctx.database.create('brick', {
|
|
79
|
+
userId: session.userId,
|
|
80
|
+
guildId: session.guildId,
|
|
81
|
+
brick: 0
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
else if (brickData[0].brick >= config.maxBrick) {
|
|
85
|
+
return `你最多只能拥有${config.maxBrick}块砖`;
|
|
86
|
+
}
|
|
87
|
+
else if (users[user].burning) {
|
|
88
|
+
return `已经在烧砖了`;
|
|
89
|
+
}
|
|
90
|
+
users[user].burning = true;
|
|
91
|
+
await session.send(`现在开始烧砖啦,群友每发送${config.cost}条消息就烧好一块砖`);
|
|
92
|
+
let messageCount = 0;
|
|
93
|
+
const dispose = ctx.guild(session.guildId).middleware(async (session_in, next) => {
|
|
94
|
+
if (![session.selfId, session.userId].includes(session_in.userId)) {
|
|
95
|
+
messageCount += 1;
|
|
96
|
+
if (messageCount >= config.cost) {
|
|
97
|
+
dispose();
|
|
98
|
+
await ctx.database.upsert('brick', (row) => [{
|
|
99
|
+
userId: session.userId,
|
|
100
|
+
guildId: session.guildId,
|
|
101
|
+
brick: koishi_1.$.add(row.brick, 1),
|
|
102
|
+
}], ["userId", "guildId"]);
|
|
103
|
+
users[user].burning = false;
|
|
104
|
+
await session.send(`${koishi_1.h.at(session.userId)} 砖已经烧好啦`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return next();
|
|
108
|
+
}, true);
|
|
109
|
+
});
|
|
110
|
+
ctx.command("砖头.拍人 <user:user>", "拍晕(禁言)对方随机时间,有概率被反将一军", { checkArgCount: true })
|
|
111
|
+
.alias("拍人")
|
|
112
|
+
.example("拍人 @koishi")
|
|
113
|
+
.action(async ({ session }, user) => {
|
|
114
|
+
const targetUserId = user.split(":")[1];
|
|
115
|
+
const userKey = `${session.guildId}:${session.userId}`;
|
|
116
|
+
const targetUserKey = `${session.guildId}:${targetUserId}`;
|
|
117
|
+
if (!users[userKey]) {
|
|
118
|
+
users[userKey] = { burning: false, muted: false };
|
|
119
|
+
}
|
|
120
|
+
if (!users[targetUserKey]) {
|
|
121
|
+
users[targetUserKey] = { burning: false, muted: false };
|
|
122
|
+
}
|
|
123
|
+
const brickData = await ctx.database.get('brick', {
|
|
124
|
+
userId: session.userId,
|
|
125
|
+
guildId: session.guildId
|
|
126
|
+
});
|
|
127
|
+
if (brickData.length === 0 || brickData[0].brick <= 0) {
|
|
128
|
+
return "你在这个群还没有砖头,使用 砖头.烧砖 烧点砖头吧";
|
|
129
|
+
}
|
|
130
|
+
const diff = Math.trunc(Date.now() / 1000 - brickData[0].lastSlap);
|
|
131
|
+
if (diff < config.cooldown) {
|
|
132
|
+
return `${Math.abs(diff - config.cooldown)} 秒后才能再拍人哦`;
|
|
133
|
+
}
|
|
134
|
+
if (users[targetUserKey].muted && !config.ignoreMuted) {
|
|
135
|
+
return "他已经晕了...";
|
|
136
|
+
}
|
|
137
|
+
await ctx.database.upsert('brick', (row) => [{
|
|
138
|
+
userId: session.userId,
|
|
139
|
+
guildId: session.guildId,
|
|
140
|
+
brick: koishi_1.$.subtract(row.brick, 1),
|
|
141
|
+
lastSlap: Date.now() / 1000
|
|
142
|
+
}], ["userId", "guildId"]);
|
|
143
|
+
const muteTime = koishi_1.Random.int(config.minMuteTime, config.maxMuteTime);
|
|
144
|
+
const muteTimeMs = muteTime * 1000;
|
|
145
|
+
const probability = config.specialUser[targetUserId] !== undefined
|
|
146
|
+
? config.specialUser[targetUserId] / 100
|
|
147
|
+
: config.reverse / 100;
|
|
148
|
+
const brickImg = koishi_1.h.image('https://img3.tofaka.com/autoupload/ontjZmlK09ZHnuFOv9znC7KXl_QqVl-bpSwqP4fJO68/20260624/lOIl/240X240/images.jpg/webp');
|
|
149
|
+
if (koishi_1.Random.bool(probability)) {
|
|
150
|
+
const muteErr = await tryMute(session.userId);
|
|
151
|
+
let msg = `${brickImg}${koishi_1.h.at(targetUserId)} 夺过你的砖头,把你拍晕了 ${muteTime} 秒`;
|
|
152
|
+
if (muteErr)
|
|
153
|
+
msg += '\n因为我不是群管理员,所以并没什么卵用';
|
|
154
|
+
return msg;
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
const muteErr = await tryMute(targetUserId);
|
|
158
|
+
let msg = `${brickImg}${koishi_1.h.at(targetUserId)} 你被 ${koishi_1.h.at(session.userId)} 拍晕了 ${muteTime} 秒`;
|
|
159
|
+
if (muteErr)
|
|
160
|
+
msg += '\n因为我不是群管理员,所以并没什么卵用';
|
|
161
|
+
return msg;
|
|
162
|
+
}
|
|
163
|
+
async function tryMute(slapedUserId) {
|
|
164
|
+
users[`${session.guildId}:${slapedUserId}`].muted = true;
|
|
165
|
+
try {
|
|
166
|
+
await session.bot.muteGuildMember(session.guildId, slapedUserId, muteTimeMs);
|
|
167
|
+
if (!config.ignoreMuted) {
|
|
168
|
+
silent(slapedUserId, muteTimeMs);
|
|
169
|
+
}
|
|
170
|
+
return false;
|
|
171
|
+
}
|
|
172
|
+
catch {
|
|
173
|
+
return true;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
function silent(slapedUserId, time) {
|
|
177
|
+
const dispose = ctx.guild(session.guildId).middleware((session, next) => {
|
|
178
|
+
if (session.userId !== slapedUserId) {
|
|
179
|
+
return next();
|
|
180
|
+
}
|
|
181
|
+
}, true);
|
|
182
|
+
ctx.setTimeout(() => {
|
|
183
|
+
dispose();
|
|
184
|
+
users[`${session.guildId}:${slapedUserId}`].muted = false;
|
|
185
|
+
}, time);
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
ctx.command("砖头.随机拍人", "随机拍晕(禁言)某个群友随机时间,有概率被反将一军")
|
|
189
|
+
.alias("随机拍人")
|
|
190
|
+
.action(async ({ session }) => {
|
|
191
|
+
const guildMember = [];
|
|
192
|
+
for await (const member of session.bot.getGuildMemberIter(session.guildId)) {
|
|
193
|
+
guildMember.push(member?.user.id);
|
|
194
|
+
}
|
|
195
|
+
await session.execute(`砖头.拍人 ${koishi_1.h.at(koishi_1.Random.pick(guildMember))}`);
|
|
196
|
+
});
|
|
197
|
+
ctx.command("砖头.查看", "看看自己在这个群有多少砖头")
|
|
198
|
+
.alias("查看砖头")
|
|
199
|
+
.action(async ({ session }) => {
|
|
200
|
+
const brickData = await ctx.database.get('brick', {
|
|
201
|
+
userId: session.userId,
|
|
202
|
+
guildId: session.guildId,
|
|
203
|
+
});
|
|
204
|
+
if (brickData.length === 0 || brickData[0].brick === 0) {
|
|
205
|
+
return `你还没有砖头,使用 砖头.烧砖 烧点吧`;
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
return `你有 ${brickData[0].brick}/${config.maxBrick} 块砖头`;
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
if (config.checking) {
|
|
212
|
+
ctx.command("砖头.签到")
|
|
213
|
+
.alias("砖头签到")
|
|
214
|
+
.action(async ({ session }) => {
|
|
215
|
+
const date = new Date();
|
|
216
|
+
const today = `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`;
|
|
217
|
+
let brick = koishi_1.Random.int(config.minGain, config.maxGain + 1);
|
|
218
|
+
const userData = await ctx.database.get('brick', {
|
|
219
|
+
userId: session.userId,
|
|
220
|
+
guildId: session.guildId,
|
|
221
|
+
});
|
|
222
|
+
if (userData.length === 0) {
|
|
223
|
+
await ctx.database.create('brick', {
|
|
224
|
+
userId: session.userId,
|
|
225
|
+
guildId: session.guildId,
|
|
226
|
+
brick: brick,
|
|
227
|
+
checkingDay: today
|
|
228
|
+
});
|
|
229
|
+
return `签到成功,你获得了 ${brick} 块砖头,现在有${brick}/${config.maxBrick}块砖头`;
|
|
230
|
+
}
|
|
231
|
+
if (userData[0].checkingDay === today) {
|
|
232
|
+
return "你今天已经签到过了";
|
|
233
|
+
}
|
|
234
|
+
if (userData[0].brick >= config.maxBrick) {
|
|
235
|
+
return `你的砖头已经到上限了,用掉再签到吧`;
|
|
236
|
+
}
|
|
237
|
+
if (userData[0].brick + brick > config.maxBrick) {
|
|
238
|
+
brick = config.maxBrick - userData[0].brick;
|
|
239
|
+
}
|
|
240
|
+
else if (userData[0].brick + brick < 0) {
|
|
241
|
+
brick = -userData[0].brick;
|
|
242
|
+
}
|
|
243
|
+
await ctx.database.upsert('brick', (row) => [{
|
|
244
|
+
userId: session.userId,
|
|
245
|
+
guildId: session.guildId,
|
|
246
|
+
brick: koishi_1.$.add(row.brick, brick),
|
|
247
|
+
checkingDay: today
|
|
248
|
+
}], ["userId", "guildId"]);
|
|
249
|
+
return `签到成功,你获得了 ${brick} 块砖头,现在有 ${userData[0].brick + brick}/${config.maxBrick} 块砖头`;
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "koishi-plugin-ll-brick",
|
|
3
|
+
"description": "砖头拍人插件(克隆自 koishi-plugin-brick),非管理员时会提示",
|
|
4
|
+
"version": "1.0.0",
|
|
5
|
+
"main": "lib/index.js",
|
|
6
|
+
"typings": "lib/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"lib"
|
|
9
|
+
],
|
|
10
|
+
"author": "lee",
|
|
11
|
+
"license": "MIT",
|
|
12
|
+
"koishi": {
|
|
13
|
+
"description": {
|
|
14
|
+
"zh": "砖头拍人插件:烧砖、拍人、随机拍人、签到,修复了异步禁言bug,非管理员会提示"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"keywords": [
|
|
18
|
+
"koishi",
|
|
19
|
+
"koishi-plugin",
|
|
20
|
+
"brick"
|
|
21
|
+
],
|
|
22
|
+
"peerDependencies": {
|
|
23
|
+
"koishi": "^4.18.9"
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"koishi": "^4.18.9",
|
|
27
|
+
"typescript": "^5.4.0"
|
|
28
|
+
}
|
|
29
|
+
}
|