@fanyue1117/koishi-plugin-trial-role 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 ADDED
@@ -0,0 +1,23 @@
1
+ declare const Schema: any;
2
+ declare module 'koishi' {
3
+ interface Tables {
4
+ trial_record: {
5
+ id: number;
6
+ userId: string;
7
+ guildId: string;
8
+ lastTrialTime: number;
9
+ createdAt: Date;
10
+ updatedAt: Date;
11
+ };
12
+ }
13
+ }
14
+ declare const pluginName = "trial-role";
15
+ interface Config {
16
+ trialRoleId: string;
17
+ successMessage: string;
18
+ errorMessage: string;
19
+ cooldownDays: number;
20
+ durationHours: number;
21
+ }
22
+ declare const Config: any;
23
+ declare function apply(ctx: any, config: any): void;
package/lib/index.js ADDED
@@ -0,0 +1,278 @@
1
+ const { Schema } = require('koishi');
2
+ const pluginName = 'trial-role';
3
+ const Config = Schema.object({
4
+ trialRoleId: Schema.string().description('试用角色的ID').required(),
5
+ successMessage: Schema.string().description('添加角色成功后的提示消息').default('已成功为您添加试用角色!有效期为1小时。'),
6
+ errorMessage: Schema.string().description('添加角色失败后的提示消息').default('添加试用角色失败,请联系管理员。'),
7
+ cooldownDays: Schema.number().description('重复试用的冷却天数').default(3),
8
+ durationHours: Schema.number().description('试用角色的有效期(小时)').default(1),
9
+ });
10
+ function apply(ctx, config) {
11
+ // 输出插件加载信息
12
+ console.log('=== 试用角色插件加载中 ===');
13
+ // 使用 ctx.model.extend 定义表结构
14
+ ctx.model.extend('trial_record', {
15
+ id: 'unsigned',
16
+ userId: 'string',
17
+ guildId: 'string',
18
+ lastTrialTime: 'integer',
19
+ createdAt: 'timestamp',
20
+ updatedAt: 'timestamp'
21
+ }, {
22
+ primary: 'id',
23
+ unique: [['userId', 'guildId']],
24
+ autoInc: true
25
+ });
26
+ console.log('=== 表结构定义完成 ===');
27
+ // 等待所有服务就绪
28
+ ctx.on('ready', async () => {
29
+ console.log('=== 所有服务就绪 ===');
30
+ if (!ctx.model) {
31
+ console.error('=== 模型对象不存在 ===');
32
+ }
33
+ else {
34
+ console.log('=== 模型对象已就绪 ===');
35
+ }
36
+ });
37
+ // 试用指令
38
+ console.log('=== 注册试用指令 ===');
39
+ ctx.command('试用', '申请试用角色')
40
+ .action(async ({ session }) => {
41
+ if (!session.guildId) {
42
+ return '请在服务器内使用此指令。';
43
+ }
44
+ if (session.bot.platform !== 'kook') {
45
+ return '此指令仅支持Kook平台。';
46
+ }
47
+ try {
48
+ console.log('=== 试用指令执行 ===', session.userId, session.guildId);
49
+ // 检查用户是否在冷却期内
50
+ const now = Date.now();
51
+ const cooldownMs = config.cooldownDays * 24 * 60 * 60 * 1000;
52
+ const durationMs = config.durationHours * 60 * 60 * 1000;
53
+ // 记录试用时间到数据库
54
+ try {
55
+ if (!ctx.model) {
56
+ console.error('=== 模型对象不存在 ===');
57
+ return '数据库服务未就绪,请稍后再试。';
58
+ }
59
+ // 尝试创建记录,会自动创建表
60
+ console.log('=== 尝试创建或更新试用记录 ===');
61
+ const existingRecords = await ctx.model.get('trial_record', {
62
+ userId: { $eq: session.userId },
63
+ guildId: { $eq: session.guildId }
64
+ });
65
+ if (existingRecords.length > 0) {
66
+ const record = existingRecords[0];
67
+ const lastTrialTime = typeof record.lastTrialTime === 'number' ? record.lastTrialTime : parseInt(record.lastTrialTime);
68
+ console.log('=== 用户最后试用时间 ===', lastTrialTime);
69
+ if (now - lastTrialTime < cooldownMs) {
70
+ const remainingTime = Math.ceil((cooldownMs - (now - lastTrialTime)) / (24 * 60 * 60 * 1000));
71
+ console.log('=== 用户在冷却期内 ===', remainingTime);
72
+ return `您已经使用过试用角色,${remainingTime}天后可再次使用。`;
73
+ }
74
+ // 更新记录
75
+ console.log('=== 更新试用记录 ===', record.id);
76
+ await ctx.model.set('trial_record', record.id, {
77
+ lastTrialTime: now,
78
+ updatedAt: new Date()
79
+ });
80
+ }
81
+ else {
82
+ // 创建新记录
83
+ console.log('=== 创建试用记录 ===');
84
+ await ctx.model.create('trial_record', {
85
+ userId: session.userId,
86
+ guildId: session.guildId,
87
+ lastTrialTime: now,
88
+ createdAt: new Date(),
89
+ updatedAt: new Date()
90
+ });
91
+ }
92
+ console.log('=== 数据库记录成功 ===');
93
+ }
94
+ catch (error) {
95
+ console.error('=== 数据库操作失败 ===', error);
96
+ return '数据库操作失败,请联系管理员。';
97
+ }
98
+ // 添加角色
99
+ console.log('=== 添加试用角色 ===', config.trialRoleId);
100
+ await session.bot.setGuildMemberRole(session.guildId, session.userId, config.trialRoleId);
101
+ // 设置定时器,到期后移除角色
102
+ setTimeout(async () => {
103
+ try {
104
+ console.log('=== 移除试用角色 ===');
105
+ await session.bot.setGuildMemberRole(session.guildId, session.userId, config.trialRoleId, false);
106
+ }
107
+ catch (error) {
108
+ console.error('=== 移除角色失败 ===', error);
109
+ }
110
+ }, durationMs);
111
+ return config.successMessage;
112
+ }
113
+ catch (error) {
114
+ console.error('=== 试用指令执行失败 ===', error);
115
+ return config.errorMessage;
116
+ }
117
+ });
118
+ // 清除冷却指令
119
+ console.log('=== 注册清除冷却指令 ===');
120
+ ctx.command('清除冷却', '清除指定用户的试用冷却时间')
121
+ .usage('清除冷却 @用户')
122
+ .action(async ({ session }, user) => {
123
+ if (!session.guildId) {
124
+ return '请在服务器内使用此指令。';
125
+ }
126
+ if (session.bot.platform !== 'kook') {
127
+ return '此指令仅支持Kook平台。';
128
+ }
129
+ if (!user) {
130
+ return '请正确提及用户,格式为:清除冷却 @用户';
131
+ }
132
+ // 提取用户ID
133
+ let targetUserId;
134
+ const match = user.match(/id="([^"]+)"/);
135
+ if (match) {
136
+ targetUserId = match[1];
137
+ }
138
+ else {
139
+ return '请正确提及用户,格式为:清除冷却 @用户';
140
+ }
141
+ try {
142
+ console.log('=== 清除冷却指令执行 ===', targetUserId, session.guildId);
143
+ if (!ctx.model) {
144
+ console.error('=== 模型对象不存在 ===');
145
+ return '数据库服务未就绪,请稍后再试。';
146
+ }
147
+ // 清除冷却
148
+ const records = await ctx.model.get('trial_record', {
149
+ userId: { $eq: targetUserId },
150
+ guildId: { $eq: session.guildId }
151
+ });
152
+ console.log('=== 查询冷却记录 ===', records.length);
153
+ if (records.length > 0) {
154
+ const record = records[0];
155
+ console.log('=== 移除冷却记录 ===', record.id);
156
+ await ctx.model.remove('trial_record', record.id);
157
+ return `已成功清除用户 ${user} 的试用冷却时间。`;
158
+ }
159
+ else {
160
+ return `用户 ${user} 目前没有冷却时间。`;
161
+ }
162
+ }
163
+ catch (error) {
164
+ console.error('=== 清除冷却失败 ===', error);
165
+ return '清除冷却失败,请联系管理员。';
166
+ }
167
+ });
168
+ // 检查数据库状态的调试指令
169
+ console.log('=== 注册检查数据库指令 ===');
170
+ ctx.command('检查数据库', '检查试用角色数据库状态')
171
+ .action(async ({ session }) => {
172
+ try {
173
+ console.log('=== 检查数据库状态 ===');
174
+ if (!ctx.model) {
175
+ console.error('=== 模型对象不存在 ===');
176
+ return '数据库服务未就绪,请稍后再试。';
177
+ }
178
+ // 尝试查询记录,会自动创建表
179
+ try {
180
+ console.log('=== 查询记录数量 ===');
181
+ const records = await ctx.model.get('trial_record', {});
182
+ console.log('=== 记录数量 ===', records.length);
183
+ return `数据库表存在,有 ${records.length} 条试用记录。`;
184
+ }
185
+ catch (error) {
186
+ console.error('=== 表不存在 ===', error);
187
+ return '数据库表不存在,请联系管理员。';
188
+ }
189
+ }
190
+ catch (error) {
191
+ console.error('=== 检查数据库失败 ===', error);
192
+ return '查询数据库失败,请联系管理员。';
193
+ }
194
+ });
195
+ // 发放角色指令
196
+ console.log('=== 注册发放角色指令 ===');
197
+ ctx.command('发放角色', '为指定用户发放试用角色')
198
+ .usage('发放角色 @用户')
199
+ .action(async ({ session }, user) => {
200
+ if (!session.guildId) {
201
+ return '请在服务器内使用此指令。';
202
+ }
203
+ if (session.bot.platform !== 'kook') {
204
+ return '此指令仅支持Kook平台。';
205
+ }
206
+ if (!user) {
207
+ return '请正确提及用户,格式为:发放角色 @用户';
208
+ }
209
+ // 提取用户ID
210
+ let targetUserId;
211
+ const match = user.match(/id="([^"]+)"/);
212
+ if (match) {
213
+ targetUserId = match[1];
214
+ }
215
+ else {
216
+ return '请正确提及用户,格式为:发放角色 @用户';
217
+ }
218
+ try {
219
+ console.log('=== 发放角色指令执行 ===', targetUserId, session.guildId);
220
+ const durationMs = config.durationHours * 60 * 60 * 1000;
221
+ // 添加角色
222
+ console.log('=== 为用户发放试用角色 ===', targetUserId, config.trialRoleId);
223
+ await session.bot.setGuildMemberRole(session.guildId, targetUserId, config.trialRoleId);
224
+ // 设置定时器,到期后移除角色
225
+ setTimeout(async () => {
226
+ try {
227
+ console.log('=== 移除试用角色 ===', targetUserId);
228
+ await session.bot.setGuildMemberRole(session.guildId, targetUserId, config.trialRoleId, false);
229
+ }
230
+ catch (error) {
231
+ console.error('=== 移除角色失败 ===', error);
232
+ }
233
+ }, durationMs);
234
+ return `已成功为用户 ${user} 发放试用角色!有效期为 ${config.durationHours} 小时。`;
235
+ }
236
+ catch (error) {
237
+ console.error('=== 发放角色失败 ===', error);
238
+ return '发放角色失败,请联系管理员。';
239
+ }
240
+ });
241
+ // 删除角色指令
242
+ console.log('=== 注册删除角色指令 ===');
243
+ ctx.command('删除角色', '删除指定用户的试用角色')
244
+ .usage('删除角色 @用户')
245
+ .action(async ({ session }, user) => {
246
+ if (!session.guildId) {
247
+ return '请在服务器内使用此指令。';
248
+ }
249
+ if (session.bot.platform !== 'kook') {
250
+ return '此指令仅支持Kook平台。';
251
+ }
252
+ if (!user) {
253
+ return '请正确提及用户,格式为:删除角色 @用户';
254
+ }
255
+ // 提取用户ID
256
+ let targetUserId;
257
+ const match = user.match(/id="([^"]+)"/);
258
+ if (match) {
259
+ targetUserId = match[1];
260
+ }
261
+ else {
262
+ return '请正确提及用户,格式为:删除角色 @用户';
263
+ }
264
+ try {
265
+ console.log('=== 删除角色指令执行 ===', targetUserId, session.guildId);
266
+ // 移除角色
267
+ console.log('=== 为用户删除试用角色 ===', targetUserId, config.trialRoleId);
268
+ await session.bot.setGuildMemberRole(session.guildId, targetUserId, config.trialRoleId, false);
269
+ return `已成功删除用户 ${user} 的试用角色。`;
270
+ }
271
+ catch (error) {
272
+ console.error('=== 删除角色失败 ===', error);
273
+ return '删除角色失败,请联系管理员。';
274
+ }
275
+ });
276
+ console.log('=== 试用角色插件加载完成 ===');
277
+ }
278
+ module.exports = { name: pluginName, Config, apply };
package/package.json ADDED
@@ -0,0 +1,16 @@
1
+ {
2
+ "name": "@fanyue1117/koishi-plugin-trial-role",
3
+ "version": "1.0.0",
4
+ "description": "Kook机器人试用角色插件",
5
+ "main": "lib/index.js",
6
+ "typings": "lib/index.d.ts",
7
+ "files": [
8
+ "lib",
9
+ "dist"
10
+ ],
11
+ "author": "",
12
+ "license": "MIT",
13
+ "peerDependencies": {
14
+ "koishi": "^4.0.0"
15
+ }
16
+ }