koishi-plugin-minecraft-search 2.0.1 → 2.0.3

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 CHANGED
@@ -16,10 +16,13 @@ export interface ApiKeyConfig {
16
16
  userId: string;
17
17
  groupId: string;
18
18
  apiKey: string;
19
+ allowMemberPowerCommands: boolean;
19
20
  }
20
21
  export interface Config {
21
22
  minekuaiApiUrl: string;
22
23
  showIpInDetail: boolean;
24
+ enablePermissionCheck: boolean;
25
+ allowMemberPowerCommands: boolean;
23
26
  }
24
27
  export declare const Config: Schema<Config>;
25
28
  export declare const inject: {
package/lib/index.js CHANGED
@@ -48,7 +48,11 @@ var Config = import_koishi.Schema.intersect([
48
48
  }).description("麦块联机配置"),
49
49
  import_koishi.Schema.object({
50
50
  showIpInDetail: import_koishi.Schema.boolean().default(true).description("在查询详细状态时显示服务器IP地址")
51
- }).description("显示配置")
51
+ }).description("显示配置"),
52
+ import_koishi.Schema.object({
53
+ enablePermissionCheck: import_koishi.Schema.boolean().default(true).description("启用权限检查"),
54
+ allowMemberPowerCommands: import_koishi.Schema.boolean().default(false).description("允许普通成员使用开服、重启、强制重启指令")
55
+ }).description("权限配置")
52
56
  ]);
53
57
  var inject = {
54
58
  required: ["database"]
@@ -72,7 +76,8 @@ function apply(ctx, config) {
72
76
  id: "unsigned",
73
77
  userId: "string",
74
78
  groupId: "string",
75
- apiKey: "string"
79
+ apiKey: "string",
80
+ allowMemberPowerCommands: "boolean"
76
81
  }, {
77
82
  autoInc: true,
78
83
  primary: "id"
@@ -165,6 +170,29 @@ function apply(ctx, config) {
165
170
  return server.name || "Minecraft 服务器";
166
171
  }
167
172
  __name(getServerName, "getServerName");
173
+ async function checkPermission(session, config2, isPowerCommand = false) {
174
+ if (!config2.enablePermissionCheck) {
175
+ return null;
176
+ }
177
+ if (isPowerCommand) {
178
+ if (config2.allowMemberPowerCommands) {
179
+ const groupId = session.guildId;
180
+ const apiKeys = await ctx.database.get("minecraft_api_key", { groupId });
181
+ if (apiKeys && apiKeys.length > 0) {
182
+ const groupConfig = apiKeys[0];
183
+ if (groupConfig.allowMemberPowerCommands) {
184
+ return null;
185
+ }
186
+ }
187
+ }
188
+ }
189
+ const memberInfo = session.event?.member?.roles;
190
+ if (!memberInfo || !memberInfo.some((role) => role.name === "admin" || role.name === "owner" || role.id === "admin" || role.id === "owner")) {
191
+ return "❌ 仅限管理员和群主使用该指令。";
192
+ }
193
+ return null;
194
+ }
195
+ __name(checkPermission, "checkPermission");
168
196
  function formatShortStatus(result, server) {
169
197
  const displayName = getServerName(server);
170
198
  if (!result.online) {
@@ -285,6 +313,10 @@ function apply(ctx, config) {
285
313
  return formatDetailedStatus(result.data, tempServer, config.showIpInDetail);
286
314
  });
287
315
  ctx.guild().command("mc/绑定 <host:string>", "绑定Minecraft服务器").option("name", "-n <name:string>", { fallback: "" }).option("timeout", "-t <timeout:number>", { fallback: 5 }).option("instance", "-i <instance:string>", { fallback: "" }).action(async ({ session, options }, host) => {
316
+ const permissionError = await checkPermission(session, config);
317
+ if (permissionError) {
318
+ return permissionError;
319
+ }
288
320
  if (!host) {
289
321
  return "请提供服务器地址,例如:绑定+IP地址(不带端口时默认为25565)";
290
322
  }
@@ -320,6 +352,10 @@ function apply(ctx, config) {
320
352
  名称: ${newServer.name || "Minecraft 服务器"}`;
321
353
  });
322
354
  ctx.guild().command("mc/绑定密钥 <apiKey:string>", "绑定麦块API密钥").action(async ({ session }, apiKey) => {
355
+ const permissionError = await checkPermission(session, config);
356
+ if (permissionError) {
357
+ return permissionError;
358
+ }
323
359
  if (!apiKey) {
324
360
  return "请提供API密钥";
325
361
  }
@@ -338,6 +374,10 @@ function apply(ctx, config) {
338
374
  return "✅ API密钥绑定成功!";
339
375
  });
340
376
  ctx.guild().command("mc/解绑 <id:number>", "解绑Minecraft服务器").action(async ({ session }, id) => {
377
+ const permissionError = await checkPermission(session, config);
378
+ if (permissionError) {
379
+ return permissionError;
380
+ }
341
381
  if (!id) {
342
382
  return "请提供服务器ID,例如:解绑 1";
343
383
  }
@@ -348,9 +388,13 @@ function apply(ctx, config) {
348
388
  return `❌ 未找到ID为 ${id} 的服务器`;
349
389
  }
350
390
  await ctx.database.remove("minecraft_server", { id });
351
- return `✅ 服务器 ${server.name} 已解绑`;
391
+ return `✅ 服务器已解绑`;
352
392
  });
353
393
  ctx.guild().command("mc/修改 <id:number>", "修改Minecraft服务器信息").option("name", "-n <name:string>", { fallback: "" }).option("timeout", "-t <timeout:number>", { fallback: 0 }).option("instance", "-i <instance:string>", { fallback: "" }).action(async ({ session, options }, id) => {
394
+ const permissionError = await checkPermission(session, config);
395
+ if (permissionError) {
396
+ return permissionError;
397
+ }
354
398
  if (!id) {
355
399
  return "请提供服务器ID,例如:修改 1";
356
400
  }
@@ -382,49 +426,61 @@ function apply(ctx, config) {
382
426
  ${parts.join("\n")}`;
383
427
  });
384
428
  ctx.guild().command("mc/开服 <id:number>", "启动麦块服务器").action(async ({ session }, id) => {
429
+ const permissionError = await checkPermission(session, config, true);
430
+ if (permissionError) {
431
+ return permissionError;
432
+ }
385
433
  if (!id) return "请提供服务器ID,例如:开服 1";
386
434
  const groupId = session.guildId;
387
435
  const servers = await ctx.database.get("minecraft_server", { groupId });
388
436
  const server = servers.find((s) => s.id === id);
389
437
  if (!server) return `❌ 未找到ID为 ${id} 的服务器,请确保操作的是本群绑定的服务器`;
390
- if (!server.minekuaiInstanceId) return `服务器 ${server.name} 未配置麦块实例ID`;
438
+ if (!server.minekuaiInstanceId) return `${server.name} 未配置麦块实例ID`;
391
439
  try {
392
440
  await minekuaiApiRequest(server.minekuaiInstanceId, "start", groupId, 3);
393
- return `✅ 已发送启动指令到服务器 ${server.name} (ID: ${id})`;
441
+ return `✅ 已发送启动指令到 ${server.name} (ID: ${id})`;
394
442
  } catch (error) {
395
- return `❌ 启动服务器 ${server.name} 失败: ${error.message}`;
443
+ return `❌ 启动服务器失败: ${error.message}`;
396
444
  }
397
445
  });
398
446
  ctx.guild().command("mc/重启 <id:number>", "重启麦块服务器").action(async ({ session }, id) => {
447
+ const permissionError = await checkPermission(session, config, true);
448
+ if (permissionError) {
449
+ return permissionError;
450
+ }
399
451
  if (!id) return "请提供服务器ID,例如:重启 1";
400
452
  const groupId = session.guildId;
401
453
  const servers = await ctx.database.get("minecraft_server", { groupId });
402
454
  const server = servers.find((s) => s.id === id);
403
455
  if (!server) return `❌ 未找到ID为 ${id} 的服务器,请确保操作的是本群绑定的服务器`;
404
- if (!server.minekuaiInstanceId) return `服务器 ${server.name} 未配置麦块实例ID`;
456
+ if (!server.minekuaiInstanceId) return `${server.name} 未配置麦块实例ID`;
405
457
  try {
406
458
  await minekuaiApiRequest(server.minekuaiInstanceId, "restart", groupId, 3);
407
- return `✅ 服务器 ${server.name} 重启指令已发送完成,请稍后检查服务器状态`;
459
+ return `✅ ${server.name} 重启指令已发送完成,请稍后检查服务器状态`;
408
460
  } catch (error) {
409
- return `❌ 重启服务器 ${server.name} 失败: ${error.message}`;
461
+ return `❌ 重启服务器失败: ${error.message}`;
410
462
  }
411
463
  });
412
464
  ctx.guild().command("mc/强制重启 <id:number>", "强制重启麦块服务器").action(async ({ session }, id) => {
465
+ const permissionError = await checkPermission(session, config, true);
466
+ if (permissionError) {
467
+ return permissionError;
468
+ }
413
469
  if (!id) return "请提供服务器ID,例如:强制重启 1";
414
470
  const groupId = session.guildId;
415
471
  const servers = await ctx.database.get("minecraft_server", { groupId });
416
472
  const server = servers.find((s) => s.id === id);
417
473
  if (!server) return `❌ 未找到ID为 ${id} 的服务器,请确保操作的是本群绑定的服务器`;
418
- if (!server.minekuaiInstanceId) return `服务器 ${server.name} 未配置麦块实例ID`;
474
+ if (!server.minekuaiInstanceId) return `${server.name} 未配置麦块实例ID`;
419
475
  try {
420
476
  await minekuaiApiRequest(server.minekuaiInstanceId, "stop", groupId, 3);
421
477
  await new Promise((resolve) => setTimeout(resolve, 1e3));
422
478
  await minekuaiApiRequest(server.minekuaiInstanceId, "kill", groupId, 3);
423
479
  await new Promise((resolve) => setTimeout(resolve, 3e3));
424
480
  await minekuaiApiRequest(server.minekuaiInstanceId, "start", groupId, 3);
425
- return `✅ 服务器 ${server.name} 强制重启指令已发送完成,请稍后检查服务器状态`;
481
+ return `✅ ${server.name} 强制重启指令已发送完成,请稍后检查服务器状态`;
426
482
  } catch (error) {
427
- return `❌ 强制重启服务器 ${server.name} 失败: ${error.message}`;
483
+ return `❌ 强制重启服务器失败: ${error.message}`;
428
484
  }
429
485
  });
430
486
  ctx.guild().command("mc/资源 <id:number>", "查看麦块服务器资源使用情况").action(async ({ session }, id) => {
@@ -433,7 +489,7 @@ ${parts.join("\n")}`;
433
489
  const servers = await ctx.database.get("minecraft_server", { groupId });
434
490
  const server = servers.find((s) => s.id === id);
435
491
  if (!server) return `❌ 未找到ID为 ${id} 的服务器,请确保操作的是本群绑定的服务器`;
436
- if (!server.minekuaiInstanceId) return `服务器 ${server.name} 未配置麦块实例ID`;
492
+ if (!server.minekuaiInstanceId) return `${server.name} 未配置麦块实例ID`;
437
493
  try {
438
494
  const apiKeys = await ctx.database.get("minecraft_api_key", { groupId });
439
495
  if (!apiKeys || apiKeys.length === 0) {
@@ -483,7 +539,7 @@ ${parts.join("\n")}`;
483
539
  message += `⏰ 查询时间: ${(/* @__PURE__ */ new Date()).toLocaleString("zh-CN")}`;
484
540
  return message;
485
541
  } catch (error) {
486
- return `❌ 查询服务器 ${server.name} 资源使用情况失败: ${error.message}`;
542
+ return `❌ 查询服务器资源使用情况失败: ${error.message}`;
487
543
  }
488
544
  });
489
545
  ctx.guild().command("mc/服务器列表", "查看已绑定的服务器列表").action(async ({ session }) => {
@@ -513,6 +569,10 @@ ${parts.join("\n")}`;
513
569
  return message.trim();
514
570
  });
515
571
  ctx.guild().command("mc/设置实例 <id:number> <instanceId:string>", "设置服务器的麦块实例ID").action(async ({ session }, id, instanceId) => {
572
+ const permissionError = await checkPermission(session, config);
573
+ if (permissionError) {
574
+ return permissionError;
575
+ }
516
576
  if (!id || !instanceId) {
517
577
  return "请提供服务器ID和实例ID,例如:设置实例 1 abc123";
518
578
  }
@@ -523,7 +583,23 @@ ${parts.join("\n")}`;
523
583
  return `❌ 未找到ID为 ${id} 的服务器`;
524
584
  }
525
585
  await ctx.database.set("minecraft_server", { id }, { minekuaiInstanceId: instanceId });
526
- return `✅ 服务器 ${server.name} 的麦块实例ID已设置为: ${instanceId}`;
586
+ return `✅ ${server.name} 的麦块实例ID已设置为: ${instanceId}`;
587
+ });
588
+ ctx.guild().command("mc/权限设置 <enabled:boolean>", "开启/关闭普通群成员使用开服、重启和强制重启指令").action(async ({ session }, enabled) => {
589
+ const permissionError = await checkPermission(session, config);
590
+ if (permissionError) {
591
+ return permissionError;
592
+ }
593
+ if (!config.allowMemberPowerCommands) {
594
+ return "❌ 请先在插件配置中开启「允许普通成员使用开服、重启、强制重启指令」选项";
595
+ }
596
+ const groupId = session.guildId;
597
+ const apiKeys = await ctx.database.get("minecraft_api_key", { groupId });
598
+ if (!apiKeys || apiKeys.length === 0) {
599
+ return "❌ 本群未配置麦块API密钥,请先使用 绑定密钥 指令";
600
+ }
601
+ await ctx.database.set("minecraft_api_key", { groupId }, { allowMemberPowerCommands: enabled });
602
+ return `✅ 已${enabled ? "开启" : "关闭"}普通群成员使用开服、重启和强制重启指令的权限`;
527
603
  });
528
604
  }
529
605
  __name(apply, "apply");
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-minecraft-search",
3
3
  "description": "使用API查询基础的mc服务器信息",
4
- "version": "2.0.1",
4
+ "version": "2.0.3",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [
package/readme.md CHANGED
@@ -53,7 +53,9 @@ npm install koishi-plugin-minecraft-search
53
53
  ```typescript
54
54
  {
55
55
  "minekuaiApiUrl": "https://minekuai.com/api/client", // 麦块API地址
56
- "showIpInDetail": true // 是否在详细状态中显示IP地址
56
+ "showIpInDetail": true, // 是否在详细状态中显示IP地址
57
+ "enablePermissionCheck": true, // 启用权限检查
58
+ "allowMemberPowerCommands": false // 允许普通成员使用开服、重启、强制重启指令
57
59
  }
58
60
  ```
59
61
 
@@ -67,6 +69,7 @@ mc/修改 <id> [-n <name>] [-t <timeout>] [-i <instance>] # 修改服务器
67
69
  mc/服务器列表 # 查看已绑定的服务器列表
68
70
  mc/设置实例 <id> <instanceId> # 设置服务器的麦块实例ID
69
71
  mc/绑定API密钥 <apiKey> # 绑定麦块API密钥
72
+ mc/权限设置 <enabled> # 开启/关闭普通群成员使用开服、重启和强制重启指令
70
73
  ```
71
74
 
72
75
  ### 查询服务器状态
@@ -138,6 +141,7 @@ mc/资源 1 # 查看ID为1的麦块服务器资源使用情况
138
141
  - **`mc/修改 <id> [-n <name>] [-t <timeout>] [-i <instance>]`**:修改服务器名称、超时时间或麦块实例ID
139
142
  - **`mc/设置实例 <id> <instanceId>`**:为服务器设置麦块实例ID,用于电源控制
140
143
  - **`mc/服务器列表`**:查看当前群组已绑定的所有服务器
144
+ - **`mc/权限设置 <enabled>`**:开启/关闭普通群成员使用开服、重启和强制重启指令,需要先在插件配置中开启 `allowMemberPowerCommands` 选项
141
145
 
142
146
  ### 服务器控制指令
143
147
  - **`mc/开服 <id>`**:启动指定服务器
@@ -153,7 +157,7 @@ mc/资源 1 # 查看ID为1的麦块服务器资源使用情况
153
157
  - ⚡ **高性能查询**:支持并行查询多个服务器
154
158
  - 🛡️ **错误处理**:完善的错误处理和用户提示
155
159
  - 🗄️ **数据库存储**:使用数据库存储服务器配置,支持多群组管理
156
- - 🔒 **权限控制**:每个群组只能管理自己绑定的服务器
160
+ - 🔒 **权限控制**:支持全局和群组级别的权限管理,每个群组只能管理自己绑定的服务器,可控制普通成员使用电源指令的权限
157
161
  - 🌐 **直接IP查询**:支持直接输入IP地址查询服务器状态
158
162
  - 🔧 **实例ID管理**:支持在绑定和修改服务器时直接设置麦块实例ID
159
163
 
@@ -184,6 +188,13 @@ mc/资源 1 # 查看ID为1的麦块服务器资源使用情况
184
188
  <details>
185
189
  <summary>点我查看更新日志详情</summary>
186
190
 
191
+ ### v2.0.3
192
+ - 新增权限检查功能,支持全局权限控制
193
+ - 新增配置项 `enablePermissionCheck` 控制是否启用权限检查
194
+ - 新增配置项 `allowMemberPowerCommands` 控制是否允许普通成员使用电源指令
195
+ - 新增 `mc/权限设置` 指令,用于每个群组独立控制普通成员权限
196
+ - 优化权限检查逻辑,支持群组级别的权限设置
197
+
187
198
  ### v2.0.1
188
199
  - 新增绑定服务器时支持 -i 选项直接设置麦块实例ID
189
200
  - 新增修改服务器时支持 -i 选项修改麦块实例ID