koishi-plugin-cs2-server-query 2.6.5 → 2.6.7

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.
Files changed (2) hide show
  1. package/lib/index.js +99 -8
  2. package/package.json +1 -2
package/lib/index.js CHANGED
@@ -154,6 +154,45 @@ function apply(ctx, config) {
154
154
  saveMapStats();
155
155
  }
156
156
  __name(cleanupOldEntries, "cleanupOldEntries");
157
+ function resolveGroupNameByCommand(rawCommand) {
158
+ if (commandMappings[rawCommand]) return commandMappings[rawCommand];
159
+ const lowerCommand = rawCommand.toLowerCase();
160
+ const matched = Object.entries(commandMappings).find(
161
+ ([cmd]) => cmd.toLowerCase() === lowerCommand
162
+ );
163
+ return matched ? matched[1] : null;
164
+ }
165
+ __name(resolveGroupNameByCommand, "resolveGroupNameByCommand");
166
+ function buildWeeklyZEMapReport(groupName) {
167
+ const groupStats = mapStats[groupName];
168
+ if (!groupStats) {
169
+ return `社区 "${groupName}" 最近7天暂无地图统计数据。`;
170
+ }
171
+ const now = Date.now();
172
+ const sevenDaysAgo = now - 7 * 24 * 60 * 60 * 1e3;
173
+ const topMaps = Object.entries(groupStats).filter(([mapName]) => /^ze/i.test(mapName)).map(([mapName, timestamps]) => ({
174
+ mapName,
175
+ count: timestamps.filter((ts) => ts >= sevenDaysAgo).length
176
+ })).filter((item) => item.count > 0).sort((a, b) => b.count - a.count || a.mapName.localeCompare(b.mapName)).slice(0, 10);
177
+ if (!topMaps.length) {
178
+ return `社区 "${groupName}" 最近7天暂无 ze 开头地图记录。`;
179
+ }
180
+ const totalCount = topMaps.reduce((sum, item) => sum + item.count, 0);
181
+ const dateRange = `${new Date(sevenDaysAgo).toLocaleDateString("zh-CN")} - ${new Date(now).toLocaleDateString("zh-CN")}`;
182
+ return [
183
+ `${groupName} 地图周报(ZEmap Top10)`,
184
+ `统计周期:${dateRange}`,
185
+ "",
186
+ ...topMaps.map((item, index) => {
187
+ const translation = mapTranslations[item.mapName]?.translation;
188
+ const translated = translation ? ` (${translation})` : "";
189
+ return `${index + 1}. ${item.mapName}${translated} - ${item.count} 次`;
190
+ }),
191
+ "",
192
+ `Top10 合计出现次数:${totalCount} 次`
193
+ ].join("\n");
194
+ }
195
+ __name(buildWeeklyZEMapReport, "buildWeeklyZEMapReport");
157
196
  ctx.setInterval(() => {
158
197
  cleanupOldEntries();
159
198
  }, 24 * 60 * 60 * 1e3);
@@ -197,8 +236,22 @@ function apply(ctx, config) {
197
236
  async function generateServerImage(group, mapTranslations2) {
198
237
  const browser = await import_puppeteer.default.launch({ args: ["--no-sandbox", "--disable-setuid-sandbox"] });
199
238
  const page = await browser.newPage();
200
- const totalPlayers = group.servers.reduce((sum, server) => sum + (server.status === "在线" ? server.players : 0), 0);
201
- const totalMaxPlayers = group.servers.reduce((sum, server) => sum + (server.status === "在线" ? server.maxPlayers : 0), 0);
239
+ const totalPlayers = group.servers.reduce((sum, server) => {
240
+ if (server.status !== "在线") return sum;
241
+ let players = server.players;
242
+ if (server.name.includes("PVE") || server.name.includes("pve")) {
243
+ players = Math.min(players, 32);
244
+ }
245
+ return sum + players;
246
+ }, 0);
247
+ const totalMaxPlayers = group.servers.reduce((sum, server) => {
248
+ if (server.status !== "在线") return sum;
249
+ let maxPlayers = server.maxPlayers;
250
+ if (server.name.includes("PVE") || server.name.includes("pve")) {
251
+ maxPlayers = Math.min(maxPlayers, 32);
252
+ }
253
+ return sum + maxPlayers;
254
+ }, 0);
202
255
  const onlineServers = group.servers.filter((server) => server.status === "在线").length;
203
256
  const baseHeight = 150;
204
257
  const rowHeight = 50;
@@ -307,6 +360,12 @@ function apply(ctx, config) {
307
360
  const translation = mapTranslations2[server.map];
308
361
  const difficulty = translation?.difficulty;
309
362
  const difficultyColor = difficulty ? difficultyColors[difficulty] : "#000000";
363
+ let displayPlayers = server.players;
364
+ let displayMaxPlayers = server.maxPlayers;
365
+ if (server.name.includes("PVE") || server.name.includes("pve")) {
366
+ displayPlayers = Math.min(displayPlayers, 32);
367
+ displayMaxPlayers = Math.min(displayMaxPlayers, 32);
368
+ }
310
369
  const mapDuration = server.status === "在线" ? Math.floor((Date.now() - server.mapChangeTime) / 6e4) : 0;
311
370
  const recentCount = (mapStats[group.name]?.[server.map] || []).filter(
312
371
  (ts) => Date.now() - ts <= 7 * 24 * 60 * 60 * 1e3
@@ -325,11 +384,11 @@ function apply(ctx, config) {
325
384
  </td>
326
385
  <td style="color: ${(() => {
327
386
  if (server.status !== "在线") return "#888";
328
- const ratio = server.players / server.maxPlayers;
387
+ const ratio = displayPlayers / displayMaxPlayers;
329
388
  if (ratio <= 0.5) return "#33cc00";
330
389
  if (ratio <= 0.8) return "#ffcc00";
331
390
  return "#ff4444";
332
- })()}">${server.status === "在线" ? `${server.players}/${server.maxPlayers}` : "-"}</td>
391
+ })()}">${server.status === "在线" ? `${displayPlayers}/${displayMaxPlayers}` : "-"}</td>
333
392
  <td>${server.status === "在线" ? `${mapDuration}分钟` : "-"}</td>
334
393
  <td class="status-${server.status === "在线" ? "online" : "offline"}">${server.status}</td>
335
394
  <td><code>${server.ip}</code></td>
@@ -353,6 +412,12 @@ function apply(ctx, config) {
353
412
  }
354
413
  __name(generateServerImage, "generateServerImage");
355
414
  async function generatePushImage(server, mapTranslations2) {
415
+ let displayPlayers = server.players;
416
+ let displayMaxPlayers = server.maxPlayers;
417
+ if (server.name.includes("PVE") || server.name.includes("pve")) {
418
+ displayPlayers = Math.min(server.players, 32);
419
+ displayMaxPlayers = Math.min(server.maxPlayers, 32);
420
+ }
356
421
  const browser = await import_puppeteer.default.launch({ args: ["--no-sandbox", "--disable-setuid-sandbox"] });
357
422
  const page = await browser.newPage();
358
423
  const html = `
@@ -404,12 +469,12 @@ function apply(ctx, config) {
404
469
  <p>地图: <span class="map-name">${server.map}</span> (${mapTranslations2[server.map]?.translation || "无翻译"})</p>
405
470
  <p>当前人数:
406
471
  <span class="player-count" style="color: ${(() => {
407
- const ratio = server.players / server.maxPlayers;
472
+ const ratio = displayPlayers / displayMaxPlayers;
408
473
  if (ratio <= 0.5) return "#33cc00";
409
474
  if (ratio <= 0.9) return "#ffcc00";
410
475
  return "#ff4444";
411
476
  })()}">
412
- ${server.players}/${server.maxPlayers}
477
+ ${displayPlayers}/${displayMaxPlayers}
413
478
  </span>
414
479
  </p>
415
480
  </div>
@@ -509,6 +574,13 @@ function apply(ctx, config) {
509
574
  __name(handleOfflineServers, "handleOfflineServers");
510
575
  ctx.middleware(async (session, next) => {
511
576
  const content = session.content.trim();
577
+ const weeklyReportMatch = content.match(/^(.+?)周报$/);
578
+ if (weeklyReportMatch) {
579
+ const reportCommand = weeklyReportMatch[1].trim();
580
+ const groupName2 = resolveGroupNameByCommand(reportCommand);
581
+ if (!groupName2) return next();
582
+ return buildWeeklyZEMapReport(groupName2);
583
+ }
512
584
  const commandMatch = content.match(/^(.+?)(\s+(\d+))?$/);
513
585
  if (!commandMatch) return next();
514
586
  const command = commandMatch[1];
@@ -675,6 +747,12 @@ connect ${server.ip}`;
675
747
  if (Object.keys(commandMappings).length === 0) return "未找到任何指令映射。";
676
748
  return `指令映射列表:${Object.entries(commandMappings).map(([command, groupName]) => `${command} -> ${groupName}`).join(", ")}`;
677
749
  });
750
+ ctx.command("cs2周报 <groupCommand>", "查看指定社区最近7天 ze 地图出现次数 Top10(例:cs2周报 exg)").action((_, groupCommand) => {
751
+ if (!groupCommand) return "请提供社区指令,例如:cs2周报 exg";
752
+ const groupName = resolveGroupNameByCommand(groupCommand.trim());
753
+ if (!groupName) return `未找到指令 "${groupCommand}" 对应的社区。`;
754
+ return buildWeeklyZEMapReport(groupName);
755
+ });
678
756
  function fuzzyMatchMap(input) {
679
757
  const lowerInput = input.toLowerCase();
680
758
  const maps = Object.keys(mapTranslations);
@@ -1184,7 +1262,14 @@ ${mapList}
1184
1262
  server.status = "离线";
1185
1263
  }
1186
1264
  }
1187
- const totalPlayers = group.servers.reduce((sum, server) => sum + (server.status === "在线" ? server.players : 0), 0);
1265
+ const totalPlayers = group.servers.reduce((sum, server) => {
1266
+ if (server.status !== "在线") return sum;
1267
+ let players = server.players;
1268
+ if (server.name.includes("PVE") || server.name.includes("pve")) {
1269
+ players = Math.min(players, 32);
1270
+ }
1271
+ return sum + players;
1272
+ }, 0);
1188
1273
  if (!communityStats[group.name]) {
1189
1274
  communityStats[group.name] = [];
1190
1275
  }
@@ -1198,7 +1283,13 @@ ${mapList}
1198
1283
  const zeServers = group.servers.filter(
1199
1284
  (server) => server.status === "在线" && (server.name.includes("僵尸逃跑") || server.name.includes("ZE") || server.name.includes("Zombie") || server.name.includes("ZOMBIE"))
1200
1285
  );
1201
- const zeTotalPlayers = zeServers.reduce((sum, server) => sum + server.players, 0);
1286
+ const zeTotalPlayers = zeServers.reduce((sum, server) => {
1287
+ let players = server.players;
1288
+ if (server.name.includes("PVE") || server.name.includes("pve")) {
1289
+ players = Math.min(players, 32);
1290
+ }
1291
+ return sum + players;
1292
+ }, 0);
1202
1293
  if (zeServers.length > 0) {
1203
1294
  if (!zeStats[group.name]) {
1204
1295
  zeStats[group.name] = [];
package/package.json CHANGED
@@ -1,8 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-cs2-server-query",
3
- "private": false,
4
3
  "description": "自用,不推荐下载",
5
- "version": "2.6.5",
4
+ "version": "2.6.7",
6
5
  "main": "lib/index.js",
7
6
  "typings": "lib/index.d.ts",
8
7
  "files": [