koishi-plugin-echo-cave 1.23.0 → 1.24.1

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.
@@ -1,5 +1,5 @@
1
1
  import { Config } from '../../config/config';
2
2
  import { Context, Session } from 'koishi';
3
- export type Period = 'lday' | 'lweek' | 'lmonth' | 'day' | 'week' | 'month' | 'all';
4
- export declare const SUPPORTED_PERIODS: Period[];
3
+ export type Period = 'lday' | 'lweek' | 'lmonth' | 'day' | 'week' | 'month' | 'all' | string;
4
+ export declare const PREDEFINED_PERIODS: Array<Period>;
5
5
  export declare function getRanking(ctx: Context, session: Session, cfg: Config, period?: string): Promise<void>;
package/lib/index.cjs CHANGED
@@ -178,7 +178,7 @@ var require_zh_CN2 = __commonJS({
178
178
  "cave.rank": {
179
179
  description: "\u67E5\u770B\u56DE\u58F0\u6D1E\u6392\u884C\u699C",
180
180
  messages: {
181
- invalidPeriod: "\u65E0\u6548\u7684\u65F6\u95F4\u6BB5\u53C2\u6570\u3002\u652F\u6301\u7684\u65F6\u95F4\u6BB5\uFF1A{0}",
181
+ invalidPeriod: "\u65E0\u6548\u7684\u65F6\u95F4\u6BB5\u53C2\u6570\u3002\u652F\u6301\u7684\u65F6\u95F4\u6BB5\uFF1A{0}\uFF0C\u6216\u81EA\u5B9A\u4E49\u65F6\u95F4\u683C\u5F0F(\u5982: 1d, 2d5h, 30m)",
182
182
  rankingTitle: "\u{1F4CA} \u56DE\u58F0\u6D1E\u6392\u884C\u699C ({0})",
183
183
  noData: "\u6682\u65E0\u6570\u636E",
184
184
  rankFormat: "{rankEmoji} {userName}\uFF1A{count} \u4E2A\u56DE\u58F0\u6D1E",
@@ -898,7 +898,7 @@ async function bindUsersToCave(ctx, session, id, userIds) {
898
898
  }
899
899
 
900
900
  // src/core/command/rank.ts
901
- var SUPPORTED_PERIODS = [
901
+ var PREDEFINED_PERIODS = [
902
902
  "lday",
903
903
  "lweek",
904
904
  "lmonth",
@@ -907,9 +907,48 @@ var SUPPORTED_PERIODS = [
907
907
  "month",
908
908
  "all"
909
909
  ];
910
- function getStartTime(period) {
910
+ var TIME_UNITS = {
911
+ m: 60 * 1e3,
912
+ // minutes
913
+ h: 60 * 60 * 1e3,
914
+ // hours
915
+ d: 24 * 60 * 60 * 1e3,
916
+ // days
917
+ w: 7 * 24 * 60 * 60 * 1e3,
918
+ // weeks
919
+ M: 30 * 24 * 60 * 60 * 1e3
920
+ // months (approximate)
921
+ };
922
+ function parseCustomTime(timeStr) {
923
+ const regex = /(\d+)([mhdwM])/g;
924
+ let match;
925
+ let totalMs = 0;
926
+ let lastUnit = "";
927
+ const unitOrder = ["M", "w", "d", "h", "m"];
928
+ if (!/^(\d+[mhdwM])+$/.test(timeStr)) {
929
+ return null;
930
+ }
931
+ while ((match = regex.exec(timeStr)) !== null) {
932
+ const [, value, unit] = match;
933
+ const num = parseInt(value, 10);
934
+ const currentIndex = unitOrder.indexOf(unit);
935
+ const lastIndex = unitOrder.indexOf(lastUnit);
936
+ if (lastUnit && currentIndex > lastIndex) {
937
+ return null;
938
+ }
939
+ totalMs += num * TIME_UNITS[unit];
940
+ lastUnit = unit;
941
+ }
942
+ return totalMs;
943
+ }
944
+ function getStartTime(period, customTimeMs) {
911
945
  const now = /* @__PURE__ */ new Date();
912
946
  const startTime = /* @__PURE__ */ new Date();
947
+ const customTime = customTimeMs !== void 0 ? customTimeMs : parseCustomTime(period);
948
+ if (customTime !== null) {
949
+ startTime.setTime(now.getTime() - customTime);
950
+ return startTime;
951
+ }
913
952
  switch (period) {
914
953
  // Last day/week/month (previous 24h, 7d, 30d)
915
954
  case "lday":
@@ -939,6 +978,10 @@ function getStartTime(period) {
939
978
  case "all":
940
979
  startTime.setTime(0);
941
980
  break;
981
+ // Default case (should not happen due to validation)
982
+ default:
983
+ startTime.setTime(0);
984
+ break;
942
985
  }
943
986
  return startTime;
944
987
  }
@@ -995,12 +1038,13 @@ async function getRanking(ctx, session, cfg, period = "all") {
995
1038
  return;
996
1039
  }
997
1040
  const normalizedPeriod = period.toLowerCase();
998
- if (!SUPPORTED_PERIODS.includes(normalizedPeriod)) {
999
- await session.send(session.text(".invalidPeriod", [SUPPORTED_PERIODS.join(", ")]));
1041
+ const customTimeMs = parseCustomTime(normalizedPeriod);
1042
+ if (!PREDEFINED_PERIODS.includes(normalizedPeriod) && customTimeMs === null) {
1043
+ await session.send(session.text(".invalidPeriod", [PREDEFINED_PERIODS.join(", ")]));
1000
1044
  return;
1001
1045
  }
1002
1046
  const { channelId } = session;
1003
- const startTime = getStartTime(normalizedPeriod);
1047
+ const startTime = getStartTime(normalizedPeriod, customTimeMs);
1004
1048
  const topCount = cfg.rankingTopCount || 10;
1005
1049
  const caves = await ctx.database.get("echo_cave_v2", {
1006
1050
  channelId,
@@ -1010,8 +1054,13 @@ async function getRanking(ctx, session, cfg, period = "all") {
1010
1054
  });
1011
1055
  const countMap = countUserOccurrences(caves);
1012
1056
  const rankingText = await generateRankingText(ctx, session, countMap, topCount);
1013
- const botName = await getUserName(this.ctx, session, session.bot?.userId) || "Bot";
1014
- const periodText = session.text(`.period.${period}`);
1057
+ const botName = await getUserName(ctx, session, session.bot?.userId) || "Bot";
1058
+ let periodText;
1059
+ if (customTimeMs !== null) {
1060
+ periodText = normalizedPeriod;
1061
+ } else {
1062
+ periodText = session.text(`.period.${normalizedPeriod}`);
1063
+ }
1015
1064
  let title = session.text(".rankingTitle", [periodText]);
1016
1065
  await session.onebot.sendGroupForwardMsg(channelId, [
1017
1066
  createTextMsgNode(session.bot?.userId || session.userId, botName, title),
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-echo-cave",
3
3
  "description": "Group echo cave",
4
- "version": "1.23.0",
4
+ "version": "1.24.1",
5
5
  "main": "lib/index.cjs",
6
6
  "typings": "lib/index.d.ts",
7
7
  "type": "module",