koishi-plugin-adapter-onebot-multi 0.0.16 → 0.0.17

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.js CHANGED
@@ -3353,6 +3353,54 @@ var LoadBalancer = class {
3353
3353
  botStats
3354
3354
  };
3355
3355
  }
3356
+ /**
3357
+ * 获取详细的负载均衡状态(供指令使用)
3358
+ */
3359
+ getDetailedStatus() {
3360
+ const onlineBots = this.getOnlineBots();
3361
+ const unassignedValue = this.config.unassignedValue || "";
3362
+ let assignedChannels = 0;
3363
+ let unassignedChannels = 0;
3364
+ for (const [, assignee] of this.lastAssignees.entries()) {
3365
+ if (assignee && assignee !== unassignedValue) {
3366
+ assignedChannels++;
3367
+ } else {
3368
+ unassignedChannels++;
3369
+ }
3370
+ }
3371
+ const bots = [];
3372
+ for (const botId of onlineBots) {
3373
+ const channels = this.botChannels.get(botId) || /* @__PURE__ */ new Set();
3374
+ let assignedCount = 0;
3375
+ for (const [, assignee] of this.lastAssignees.entries()) {
3376
+ if (assignee === botId) {
3377
+ assignedCount++;
3378
+ }
3379
+ }
3380
+ const maxLoad = this.getBotMaxLoad(botId);
3381
+ const remaining = maxLoad === 0 ? -1 : Math.max(0, maxLoad - assignedCount);
3382
+ const botInstance = this.ctx.bots.find((b) => b.selfId === botId && b.platform === "onebot");
3383
+ const nickname = botInstance?.user?.name || botId;
3384
+ const avatarUrl = `http://q.qlogo.cn/headimg_dl?dst_uin=${botId}&spec=640`;
3385
+ bots.push({
3386
+ selfId: botId,
3387
+ nickname,
3388
+ avatarUrl,
3389
+ channelCount: channels.size,
3390
+ assignedCount,
3391
+ maxLoad,
3392
+ remaining
3393
+ });
3394
+ }
3395
+ bots.sort((a, b) => b.assignedCount - a.assignedCount);
3396
+ return {
3397
+ onlineBots: onlineBots.length,
3398
+ totalChannels: this.allChannels.size,
3399
+ assignedChannels,
3400
+ unassignedChannels,
3401
+ bots
3402
+ };
3403
+ }
3356
3404
  };
3357
3405
 
3358
3406
  // src/index.ts
@@ -3402,10 +3450,51 @@ function apply(ctx, config) {
3402
3450
  if (config.panel?.enabled) {
3403
3451
  new StatusPanel(ctx, config.panel, statusManager, configManager);
3404
3452
  }
3453
+ let loadBalancer = null;
3405
3454
  if (config.loadBalance?.enabled) {
3406
- new LoadBalancer(ctx, config.loadBalance, statusManager);
3455
+ loadBalancer = new LoadBalancer(ctx, config.loadBalance, statusManager);
3407
3456
  logger.info("负载均衡已启用");
3408
3457
  }
3458
+ ctx.command("onebot.balance", "查看 OneBot 负载均衡状态").alias("ob.balance").alias("负载均衡").action(async () => {
3459
+ if (!loadBalancer || !config.loadBalance?.enabled) {
3460
+ return "负载均衡未启用。";
3461
+ }
3462
+ const status = loadBalancer.getDetailedStatus();
3463
+ const elements = [];
3464
+ elements.push(import_koishi12.h.text("═══ OneBot 负载均衡状态 ═══\n\n"));
3465
+ elements.push(import_koishi12.h.text(`📊 总览
3466
+ `));
3467
+ elements.push(import_koishi12.h.text(` 在线 Bot: ${status.onlineBots} 个
3468
+ `));
3469
+ elements.push(import_koishi12.h.text(` 管理群数: ${status.totalChannels} 个
3470
+ `));
3471
+ elements.push(import_koishi12.h.text(` 已分配群: ${status.assignedChannels} 个
3472
+ `));
3473
+ elements.push(import_koishi12.h.text(` 未分配群: ${status.unassignedChannels} 个
3474
+
3475
+ `));
3476
+ elements.push(import_koishi12.h.text(`🤖 Bot 负载详情
3477
+ `));
3478
+ for (const bot of status.bots) {
3479
+ const maxLoadStr = bot.maxLoad === 0 ? "无限制" : `${bot.maxLoad}`;
3480
+ const remainingStr = bot.maxLoad === 0 ? "∞" : `${bot.remaining}`;
3481
+ const barLength = 20;
3482
+ const usedLength = bot.maxLoad === 0 ? Math.min(Math.round(bot.assignedCount / Math.max(bot.channelCount, 1) * barLength), barLength) : Math.round(bot.assignedCount / bot.maxLoad * barLength);
3483
+ const bar = "█".repeat(usedLength) + "░".repeat(barLength - usedLength);
3484
+ elements.push(import_koishi12.h.image(bot.avatarUrl));
3485
+ elements.push(import_koishi12.h.text("\n"));
3486
+ elements.push(import_koishi12.h.text(` ${bot.nickname} (${bot.selfId})
3487
+ `));
3488
+ elements.push(import_koishi12.h.text(` 所在群: ${bot.channelCount} | 负责群: ${bot.assignedCount} | 上限: ${maxLoadStr}
3489
+ `));
3490
+ elements.push(import_koishi12.h.text(` 剩余容量: ${remainingStr}
3491
+ `));
3492
+ elements.push(import_koishi12.h.text(` [${bar}]
3493
+
3494
+ `));
3495
+ }
3496
+ return elements;
3497
+ });
3409
3498
  ctx.inject(["console"], (ctx2) => {
3410
3499
  ctx2.console.addEntry({
3411
3500
  dev: (0, import_path.resolve)(__dirname, "../client/index.ts"),
@@ -85,4 +85,22 @@ export declare class LoadBalancer {
85
85
  assignedCount: number;
86
86
  }>;
87
87
  };
88
+ /**
89
+ * 获取详细的负载均衡状态(供指令使用)
90
+ */
91
+ getDetailedStatus(): {
92
+ onlineBots: number;
93
+ totalChannels: number;
94
+ assignedChannels: number;
95
+ unassignedChannels: number;
96
+ bots: {
97
+ selfId: string;
98
+ nickname: string;
99
+ avatarUrl: string;
100
+ channelCount: number;
101
+ assignedCount: number;
102
+ maxLoad: number;
103
+ remaining: number;
104
+ }[];
105
+ };
88
106
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-adapter-onebot-multi",
3
3
  "description": "奶龙bot定制版onebot适配器,支持自动负载均衡,适配器级黑名单/白名单,提供webui,可指定端口",
4
- "version": "0.0.16",
4
+ "version": "0.0.17",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [