koishi-plugin-noah 1.1.6 → 1.1.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.
@@ -1,4 +1,4 @@
1
- import { SDVXScore } from '../types';
1
+ import { SDVXScore, SDVXGrade, SDVXClearType, SDVXMusicDifficulty } from '../types';
2
2
  export declare class ScoreService {
3
3
  private static instance;
4
4
  private constructor();
@@ -19,4 +19,16 @@ export declare class ScoreService {
19
19
  * @returns 包含最高 Volforce 值的分数数组(如果存在并列,可能超过 50 个)
20
20
  */
21
21
  getBest50(scores: SDVXScore[]): SDVXScore[];
22
+ /**
23
+ * 过滤 SDVXScore 数组
24
+ * @param scores - 待过滤的分数数组
25
+ * @param options - 过滤选项
26
+ * @returns 过滤后的分数数组
27
+ */
28
+ filterScores(scores: SDVXScore[], options: {
29
+ grade?: SDVXGrade | SDVXGrade[];
30
+ clearType?: SDVXClearType | SDVXClearType[];
31
+ musicDiff?: number | number[];
32
+ radarFeature?: keyof SDVXMusicDifficulty['radar'] | Array<keyof SDVXMusicDifficulty['radar']>;
33
+ }): SDVXScore[];
22
34
  }
@@ -0,0 +1 @@
1
+ export declare function parseFilterQuery(query: string): {};
package/lib/index.js CHANGED
@@ -1879,6 +1879,43 @@ var ScoreService = class _ScoreService {
1879
1879
  const fiftiethVF = sortedScores[49].extra.volforce;
1880
1880
  return sortedScores.filter((score) => score.extra.volforce >= fiftiethVF);
1881
1881
  }
1882
+ /**
1883
+ * 过滤 SDVXScore 数组
1884
+ * @param scores - 待过滤的分数数组
1885
+ * @param options - 过滤选项
1886
+ * @returns 过滤后的分数数组
1887
+ */
1888
+ filterScores(scores, options) {
1889
+ let filtered = scores;
1890
+ if (options.grade) {
1891
+ const grades = Array.isArray(options.grade) ? options.grade : [options.grade];
1892
+ filtered = filtered.filter((score) => grades.includes(score.music.score_grade));
1893
+ }
1894
+ if (options.clearType) {
1895
+ const clearTypes = Array.isArray(options.clearType) ? options.clearType : [options.clearType];
1896
+ filtered = filtered.filter((score) => clearTypes.includes(score.music.clear_type));
1897
+ }
1898
+ if (options.musicDiff !== void 0) {
1899
+ const diffs = Array.isArray(options.musicDiff) ? options.musicDiff : [options.musicDiff];
1900
+ filtered = filtered.filter((score) => diffs.includes(score.music.music_diff));
1901
+ }
1902
+ if (options.radarFeature) {
1903
+ const featureKeys = Array.isArray(options.radarFeature) ? options.radarFeature : [options.radarFeature];
1904
+ filtered = filtered.filter((score) => {
1905
+ const radar = score.difficulty_data.radar;
1906
+ let maxKey = "notes";
1907
+ let maxValue = radar["notes"];
1908
+ for (const key of Object.keys(radar)) {
1909
+ if (radar[key] > maxValue) {
1910
+ maxKey = key;
1911
+ maxValue = radar[key];
1912
+ }
1913
+ }
1914
+ return featureKeys.includes(maxKey);
1915
+ });
1916
+ }
1917
+ return filtered;
1918
+ }
1882
1919
  };
1883
1920
 
1884
1921
  // src/drawer/index.ts
@@ -2585,9 +2622,93 @@ function apply6(ctx, config) {
2585
2622
  }
2586
2623
  __name(apply6, "apply");
2587
2624
 
2625
+ // src/games/sdvx/utils/filter.ts
2626
+ function parseFilterQuery(query) {
2627
+ const clearTypeList = ["S-PUC", "PUC", "UC", "HC", "NC", "PLAYED", "NO PLAY"];
2628
+ const clearTypeMap = {
2629
+ "spuc": "S-PUC",
2630
+ "puc": "PUC",
2631
+ "uc": "UC",
2632
+ "hc": "HC",
2633
+ "nc": "NC",
2634
+ "played": "PLAYED",
2635
+ "noplay": "NO PLAY"
2636
+ };
2637
+ const gradeList = ["S", "AAA+", "AAA", "AA+", "AA", "A+", "A", "B", "C", "D"];
2638
+ const radarList = ["notes", "peak", "tsumami", "tricky", "hand_trip", "one_hand"];
2639
+ const result = {
2640
+ grade: [],
2641
+ clearType: [],
2642
+ musicDiff: [],
2643
+ radarFeature: []
2644
+ };
2645
+ if (!query) return {};
2646
+ const items = query.split(/\s+/).map((s) => s.trim().toLowerCase()).filter(Boolean);
2647
+ for (const item of items) {
2648
+ if (/^[a-z\-]+-[a-z\-]+$/.test(item)) {
2649
+ const [startRaw, endRaw] = item.split("-");
2650
+ const start = clearTypeList.findIndex((t) => t.toLowerCase() === (clearTypeMap[startRaw] || startRaw));
2651
+ const end = clearTypeList.findIndex((t) => t.toLowerCase() === (clearTypeMap[endRaw] || endRaw));
2652
+ if (start !== -1 && end !== -1) {
2653
+ const from = Math.min(start, end);
2654
+ const to = Math.max(start, end);
2655
+ for (let i = from; i <= to; i++) result.clearType.push(clearTypeList[i]);
2656
+ if (result.clearType.includes("PUC") && !result.clearType.includes("S-PUC")) {
2657
+ result.clearType.push("S-PUC");
2658
+ }
2659
+ continue;
2660
+ }
2661
+ }
2662
+ if (clearTypeMap[item]) {
2663
+ result.clearType.push(clearTypeMap[item]);
2664
+ if (clearTypeMap[item] === "PUC" && !result.clearType.includes("S-PUC")) {
2665
+ result.clearType.push("S-PUC");
2666
+ }
2667
+ continue;
2668
+ }
2669
+ if (/^[a-ds][a-z+]*-[a-ds][a-z+]*$/.test(item)) {
2670
+ const [startRaw, endRaw] = item.split("-");
2671
+ const start = gradeList.findIndex((g) => g.toLowerCase() === startRaw);
2672
+ const end = gradeList.findIndex((g) => g.toLowerCase() === endRaw);
2673
+ if (start !== -1 && end !== -1) {
2674
+ const from = Math.min(start, end);
2675
+ const to = Math.max(start, end);
2676
+ for (let i = from; i <= to; i++) result.grade.push(gradeList[i]);
2677
+ continue;
2678
+ }
2679
+ }
2680
+ const grade = gradeList.find((g) => g.toLowerCase() === item);
2681
+ if (grade) {
2682
+ result.grade.push(grade);
2683
+ continue;
2684
+ }
2685
+ if (/^\d{1,2}-\d{1,2}$/.test(item)) {
2686
+ const [a, b] = item.split("-").map(Number);
2687
+ const from = Math.min(a, b);
2688
+ const to = Math.max(a, b);
2689
+ for (let i = from; i <= to; i++) result.musicDiff.push(i);
2690
+ continue;
2691
+ }
2692
+ if (/^\d{1,2}$/.test(item)) {
2693
+ result.musicDiff.push(Number(item));
2694
+ continue;
2695
+ }
2696
+ if (radarList.includes(item)) {
2697
+ result.radarFeature.push(item);
2698
+ continue;
2699
+ }
2700
+ }
2701
+ if (result.grade.length === 0) delete result.grade;
2702
+ if (result.clearType.length === 0) delete result.clearType;
2703
+ if (result.musicDiff.length === 0) delete result.musicDiff;
2704
+ if (result.radarFeature.length === 0) delete result.radarFeature;
2705
+ return result;
2706
+ }
2707
+ __name(parseFilterQuery, "parseFilterQuery");
2708
+
2588
2709
  // src/games/sdvx/commands/vf.ts
2589
2710
  function vf(ctx, config) {
2590
- ctx.command("vf").userFields(["defaultCardId", "defaultServerId", "id"]).channelFields(["defaultServerId", "id"]).option("lossless", "-l").option("card", "-c").action(async ({ session, options }) => {
2711
+ ctx.command("vf").userFields(["defaultCardId", "defaultServerId", "id"]).channelFields(["defaultServerId", "id"]).option("lossless", "-l").option("card", "-c").option("filter", "-f <query:text>").action(async ({ session, options }) => {
2591
2712
  const model = config.default_model;
2592
2713
  const cardService = new CardService(ctx);
2593
2714
  const serverService = new ServerService(ctx);
@@ -2643,7 +2764,13 @@ function vf(ctx, config) {
2643
2764
  if (scoreList.length === 0) {
2644
2765
  return session.text(".no-scores-found");
2645
2766
  }
2646
- const best50ScoreList = scoreService.getBest50(scoreList);
2767
+ let best50ScoreList = scoreService.getBest50(scoreList);
2768
+ if (options.filter) {
2769
+ const filterOptions = parseFilterQuery(options.filter);
2770
+ if (Object.keys(filterOptions).length > 0) {
2771
+ best50ScoreList = scoreService.filterScores(best50ScoreList, filterOptions);
2772
+ }
2773
+ }
2647
2774
  session.send(session.text(".drawing"));
2648
2775
  const drawerManager = DrawerManager.getInstance(ctx);
2649
2776
  const sdvxDrawer = drawerManager.getDrawer("sdvx");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "koishi-plugin-noah",
3
- "version": "1.1.6",
3
+ "version": "1.1.7",
4
4
  "contributors": [
5
5
  "Logthm <logthm@outlook.com>"
6
6
  ],