koishi-plugin-ggcevo-game 2.0.8 → 2.0.10
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/database.d.ts +11 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +329 -18
- package/package.json +1 -1
package/lib/database.d.ts
CHANGED
|
@@ -28,6 +28,8 @@ declare module 'koishi' {
|
|
|
28
28
|
ggcevo_explore: explore;
|
|
29
29
|
ggcevo_global_stats: GlobalStats;
|
|
30
30
|
ggcevo_guess: guess;
|
|
31
|
+
roulettes: Roulette;
|
|
32
|
+
roulette_groups: RouletteGroup;
|
|
31
33
|
}
|
|
32
34
|
}
|
|
33
35
|
export interface Backpack {
|
|
@@ -248,3 +250,12 @@ export interface bossweights {
|
|
|
248
250
|
weight: number;
|
|
249
251
|
lastSpawn: Date;
|
|
250
252
|
}
|
|
253
|
+
export interface Roulette {
|
|
254
|
+
id: number;
|
|
255
|
+
items: string[];
|
|
256
|
+
}
|
|
257
|
+
export interface RouletteGroup {
|
|
258
|
+
id: number;
|
|
259
|
+
name: string;
|
|
260
|
+
items: number[];
|
|
261
|
+
}
|
package/lib/index.d.ts
CHANGED
|
@@ -21,6 +21,7 @@ export interface Config {
|
|
|
21
21
|
enablePlayRequirement: boolean;
|
|
22
22
|
enableGuguBattle: boolean;
|
|
23
23
|
enableMatchesRequirement: boolean;
|
|
24
|
+
signInGroupId: string[];
|
|
24
25
|
}
|
|
25
26
|
export declare const Config: Schema<Config>;
|
|
26
27
|
export declare function apply(ctx: Context, config: Config): void;
|
package/lib/index.js
CHANGED
|
@@ -7474,7 +7474,7 @@ var Config = import_koishi.Schema.intersect([
|
|
|
7474
7474
|
proxyAgent: import_koishi.Schema.string().description("代理服务器地址"),
|
|
7475
7475
|
enablePlayRequirement: import_koishi.Schema.boolean().description("开启签到需3天游戏记录(关闭时无限制)").default(false),
|
|
7476
7476
|
enableCurfew: import_koishi.Schema.boolean().description("是否开启宵禁模式(18:00-24:00禁止群聊指令)").default(false),
|
|
7477
|
-
enableGuguBattle: import_koishi.Schema.boolean().description("
|
|
7477
|
+
enableGuguBattle: import_koishi.Schema.boolean().description("是否开启咕咕之战游戏功能").default(true)
|
|
7478
7478
|
}).description("基础设置"),
|
|
7479
7479
|
// 赛季与兑换配置组
|
|
7480
7480
|
import_koishi.Schema.object({
|
|
@@ -7494,11 +7494,15 @@ var Config = import_koishi.Schema.intersect([
|
|
|
7494
7494
|
}).description("对战限制"),
|
|
7495
7495
|
// 通知系统配置组 - 新增违规提醒开关
|
|
7496
7496
|
import_koishi.Schema.object({
|
|
7497
|
-
groupId: import_koishi.Schema.array(import_koishi.Schema.string()).description("
|
|
7497
|
+
groupId: import_koishi.Schema.array(import_koishi.Schema.string()).description("咕咕之战广播通知群组").default([]),
|
|
7498
7498
|
checkInterval: import_koishi.Schema.number().description("大厅监控检查间隔(秒)").default(60),
|
|
7499
7499
|
enableViolationAlert: import_koishi.Schema.boolean().description("启用违规玩家房间提醒").default(false)
|
|
7500
7500
|
// 新增配置项
|
|
7501
|
-
}).description("通知设置").collapse()
|
|
7501
|
+
}).description("通知设置").collapse(),
|
|
7502
|
+
// 新增:签到配置组
|
|
7503
|
+
import_koishi.Schema.object({
|
|
7504
|
+
signInGroupId: import_koishi.Schema.array(import_koishi.Schema.string()).description("允许签到的群组ID列表(为空则不限制)").default([])
|
|
7505
|
+
}).description("签到设置")
|
|
7502
7506
|
]);
|
|
7503
7507
|
function apply(ctx, config) {
|
|
7504
7508
|
ctx.model.extend("ggcevo_backpack", {
|
|
@@ -7804,6 +7808,21 @@ function apply(ctx, config) {
|
|
|
7804
7808
|
}, {
|
|
7805
7809
|
primary: ["handle", "itemId"]
|
|
7806
7810
|
});
|
|
7811
|
+
ctx.model.extend("roulettes", {
|
|
7812
|
+
id: "unsigned",
|
|
7813
|
+
items: "list"
|
|
7814
|
+
}, {
|
|
7815
|
+
primary: "id",
|
|
7816
|
+
autoInc: true
|
|
7817
|
+
});
|
|
7818
|
+
ctx.model.extend("roulette_groups", {
|
|
7819
|
+
id: "unsigned",
|
|
7820
|
+
name: "string",
|
|
7821
|
+
items: "json"
|
|
7822
|
+
}, {
|
|
7823
|
+
primary: "id",
|
|
7824
|
+
autoInc: true
|
|
7825
|
+
});
|
|
7807
7826
|
ctx.setInterval(async () => {
|
|
7808
7827
|
const now = /* @__PURE__ */ new Date();
|
|
7809
7828
|
await ctx.database.set(
|
|
@@ -8048,8 +8067,20 @@ function apply(ctx, config) {
|
|
|
8048
8067
|
});
|
|
8049
8068
|
}, 24 * 60 * 60 * 1e3);
|
|
8050
8069
|
}
|
|
8070
|
+
const checkGroupAccess = /* @__PURE__ */ __name((session, featureName = "该功能") => {
|
|
8071
|
+
if (!config.signInGroupId?.length) return null;
|
|
8072
|
+
if (session.isDirect) {
|
|
8073
|
+
return `⛔ ${featureName}仅限在指定群组中使用,请前往指定的QQ群进行操作。`;
|
|
8074
|
+
}
|
|
8075
|
+
if (!config.signInGroupId.includes(session.guildId)) {
|
|
8076
|
+
return `⛔ 当前群组不允许使用${featureName},请前往指定的QQ群进行操作。`;
|
|
8077
|
+
}
|
|
8078
|
+
return null;
|
|
8079
|
+
}, "checkGroupAccess");
|
|
8051
8080
|
ctx.command("ggcevo/抽奖").action(async (argv) => {
|
|
8052
8081
|
const session = argv.session;
|
|
8082
|
+
const accessError = checkGroupAccess(session, "抽奖");
|
|
8083
|
+
if (accessError) return accessError;
|
|
8053
8084
|
let winCount = 0;
|
|
8054
8085
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId, isActive: true });
|
|
8055
8086
|
if (!profile) {
|
|
@@ -8088,6 +8119,8 @@ function apply(ctx, config) {
|
|
|
8088
8119
|
});
|
|
8089
8120
|
ctx.command("ggcevo/单抽").action(async (argv) => {
|
|
8090
8121
|
const session = argv.session;
|
|
8122
|
+
const accessError = checkGroupAccess(session, "单抽");
|
|
8123
|
+
if (accessError) return accessError;
|
|
8091
8124
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId, isActive: true });
|
|
8092
8125
|
if (!profile) {
|
|
8093
8126
|
return "🔒 需要先绑定游戏句柄。";
|
|
@@ -8115,6 +8148,8 @@ function apply(ctx, config) {
|
|
|
8115
8148
|
});
|
|
8116
8149
|
ctx.command("ggcevo/十连抽").action(async (argv) => {
|
|
8117
8150
|
const session = argv.session;
|
|
8151
|
+
const accessError = checkGroupAccess(session, "十连抽");
|
|
8152
|
+
if (accessError) return accessError;
|
|
8118
8153
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId, isActive: true });
|
|
8119
8154
|
if (!profile) {
|
|
8120
8155
|
return "🔒 需要先绑定游戏句柄。";
|
|
@@ -8147,6 +8182,8 @@ function apply(ctx, config) {
|
|
|
8147
8182
|
});
|
|
8148
8183
|
ctx.command("ggcevo/背包").action(async (argv) => {
|
|
8149
8184
|
const session = argv.session;
|
|
8185
|
+
const accessError = checkGroupAccess(session, "背包");
|
|
8186
|
+
if (accessError) return accessError;
|
|
8150
8187
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId, isActive: true });
|
|
8151
8188
|
if (!profile) return "🔒 需要先绑定游戏句柄。";
|
|
8152
8189
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
@@ -8167,6 +8204,8 @@ ${itemDetails.join("\n")}`;
|
|
|
8167
8204
|
ctx.command("ggcevo/签到").action(async (argv) => {
|
|
8168
8205
|
try {
|
|
8169
8206
|
const session = argv.session;
|
|
8207
|
+
const accessError = checkGroupAccess(session, "签到");
|
|
8208
|
+
if (accessError) return accessError;
|
|
8170
8209
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId, isActive: true });
|
|
8171
8210
|
if (!profile) return "🔒 需要先绑定游戏句柄。";
|
|
8172
8211
|
const { regionId, realmId, profileId } = profile;
|
|
@@ -8325,6 +8364,8 @@ ${ticketMessage}${effectMessage}`;
|
|
|
8325
8364
|
ctx.command("ggcevo/补签").action(async (argv) => {
|
|
8326
8365
|
try {
|
|
8327
8366
|
const session = argv.session;
|
|
8367
|
+
const accessError = checkGroupAccess(session, "补签");
|
|
8368
|
+
if (accessError) return accessError;
|
|
8328
8369
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId, isActive: true });
|
|
8329
8370
|
if (!profile) return "🔒 需要先绑定游戏句柄。";
|
|
8330
8371
|
const { regionId, realmId, profileId } = profile;
|
|
@@ -8380,6 +8421,8 @@ ${ticketMessage}${effectMessage}`;
|
|
|
8380
8421
|
});
|
|
8381
8422
|
ctx.guild().command("ggcevo/每月津贴").action(async (argv) => {
|
|
8382
8423
|
const session = argv.session;
|
|
8424
|
+
const accessError = checkGroupAccess(session, "每月津贴");
|
|
8425
|
+
if (accessError) return accessError;
|
|
8383
8426
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId, isActive: true });
|
|
8384
8427
|
if (!profile) return "🔒 需要先绑定游戏句柄。";
|
|
8385
8428
|
const { regionId, realmId, profileId } = profile;
|
|
@@ -8420,6 +8463,8 @@ ${ticketMessage}${effectMessage}`;
|
|
|
8420
8463
|
});
|
|
8421
8464
|
ctx.command("ggcevo/领取 [name]").action(async (argv, name2) => {
|
|
8422
8465
|
const session = argv.session;
|
|
8466
|
+
const accessError = checkGroupAccess(session, "领取");
|
|
8467
|
+
if (accessError) return accessError;
|
|
8423
8468
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
8424
8469
|
if (!profile) return "🔒 需要先绑定游戏句柄。";
|
|
8425
8470
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
@@ -8504,6 +8549,8 @@ ${ticketMessage}${effectMessage}`;
|
|
|
8504
8549
|
return `活动【${activityName}】创建成功!奖励内容:${itemName} x${quantity}。`;
|
|
8505
8550
|
});
|
|
8506
8551
|
ctx.command("ggcevo/活动列表").action(async ({ session }) => {
|
|
8552
|
+
const accessError = checkGroupAccess(session, "活动列表");
|
|
8553
|
+
if (accessError) return accessError;
|
|
8507
8554
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
8508
8555
|
if (!profile) return "🔒 需要先绑定游戏句柄。";
|
|
8509
8556
|
const activities = await ctx.database.get(
|
|
@@ -8588,6 +8635,8 @@ ${ticketMessage}${effectMessage}`;
|
|
|
8588
8635
|
}
|
|
8589
8636
|
});
|
|
8590
8637
|
ctx.command("ggcevo/胜点榜 [page]").alias("排行榜").usage("输入 胜点榜 [页码] 查看对应页的排行榜,每页10条").action(async ({ session }, page) => {
|
|
8638
|
+
const accessError = checkGroupAccess(session, "胜点榜");
|
|
8639
|
+
if (accessError) return accessError;
|
|
8591
8640
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
8592
8641
|
if (!profile) return "🔒 需要先绑定游戏句柄。";
|
|
8593
8642
|
const pageNum = parseInt(page) || 1;
|
|
@@ -8731,6 +8780,8 @@ ${ticketMessage}${effectMessage}`;
|
|
|
8731
8780
|
});
|
|
8732
8781
|
ctx.command("ggcevo/排名 [player]", "查询个人排名").alias("rank").usage("输入“排名”查看自己的排名信息").action(async (argv, player) => {
|
|
8733
8782
|
const session = argv.session;
|
|
8783
|
+
const accessError = checkGroupAccess(session, "排名");
|
|
8784
|
+
if (accessError) return accessError;
|
|
8734
8785
|
const ctx2 = session.bot.ctx;
|
|
8735
8786
|
let handle;
|
|
8736
8787
|
if (!player) {
|
|
@@ -8799,6 +8850,8 @@ ${ticketMessage}${effectMessage}`;
|
|
|
8799
8850
|
});
|
|
8800
8851
|
ctx.command("ggcevo/违规记录 [user]", "违规记录查询").usage("输入 违规记录 [@玩家] -p 页码 查看处罚记录,每页1条").option("p", "-p <page:number> 指定页码").action(async (argv) => {
|
|
8801
8852
|
const session = argv.session;
|
|
8853
|
+
const accessError = checkGroupAccess(session, "违规记录");
|
|
8854
|
+
if (accessError) return accessError;
|
|
8802
8855
|
const pageNum = argv.options.p ? argv.options.p : 1;
|
|
8803
8856
|
const user = argv.args[0];
|
|
8804
8857
|
let handle;
|
|
@@ -8851,6 +8904,8 @@ ${ticketMessage}${effectMessage}`;
|
|
|
8851
8904
|
].join("\n");
|
|
8852
8905
|
});
|
|
8853
8906
|
ctx.command("ggcevo/兑换赞助物品", "兑换赞助物品").action(async ({ session }) => {
|
|
8907
|
+
const accessError = checkGroupAccess(session, "兑换赞助物品");
|
|
8908
|
+
if (accessError) return accessError;
|
|
8854
8909
|
try {
|
|
8855
8910
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId, isActive: true });
|
|
8856
8911
|
if (!profile) return "🔒 需要先绑定游戏句柄。";
|
|
@@ -9018,6 +9073,8 @@ ${items.join("、")}
|
|
|
9018
9073
|
}
|
|
9019
9074
|
});
|
|
9020
9075
|
ctx.command("ggcevo/兑换扭蛋币").action(async ({ session }) => {
|
|
9076
|
+
const accessError = checkGroupAccess(session, "兑换扭蛋币");
|
|
9077
|
+
if (accessError) return accessError;
|
|
9021
9078
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId });
|
|
9022
9079
|
if (!profile) return "🔒 需要先绑定游戏句柄。";
|
|
9023
9080
|
const handle = `${profile.regionId}-S2-${profile.realmId}-${profile.profileId}`;
|
|
@@ -9047,6 +9104,8 @@ ${items.join("、")}
|
|
|
9047
9104
|
});
|
|
9048
9105
|
ctx.command("ggcevo/扭蛋").action(async (argv) => {
|
|
9049
9106
|
const session = argv.session;
|
|
9107
|
+
const accessError = checkGroupAccess(session, "兑换扭蛋币");
|
|
9108
|
+
if (accessError) return accessError;
|
|
9050
9109
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId, isActive: true });
|
|
9051
9110
|
if (!profile) {
|
|
9052
9111
|
return "🔒 需要先绑定游戏句柄。";
|
|
@@ -9162,6 +9221,8 @@ ${items.join("、")}
|
|
|
9162
9221
|
});
|
|
9163
9222
|
ctx.command("ggcevo/个人信息").action(async (argv) => {
|
|
9164
9223
|
const session = argv.session;
|
|
9224
|
+
const accessError = checkGroupAccess(session, "个人信息");
|
|
9225
|
+
if (accessError) return accessError;
|
|
9165
9226
|
const output = [];
|
|
9166
9227
|
const [profile] = await ctx.database.get("sc2arcade_player", { userId: session.userId, isActive: true });
|
|
9167
9228
|
if (!profile) return "🔒 需要先绑定游戏句柄。";
|
|
@@ -13082,18 +13143,17 @@ ${validBossNames.join("、")}`;
|
|
|
13082
13143
|
return "查询BOSS权重时发生错误,请检查服务器日志";
|
|
13083
13144
|
}
|
|
13084
13145
|
});
|
|
13085
|
-
|
|
13086
|
-
|
|
13087
|
-
return `
|
|
13146
|
+
ctx.command("ggcevo/签到奖励").action(({}) => {
|
|
13147
|
+
return `
|
|
13088
13148
|
签到金币奖励:
|
|
13089
13149
|
每天获得50-100金币
|
|
13090
13150
|
--------------
|
|
13091
13151
|
签到红晶奖励(辛迪加财务经理职业加成):
|
|
13092
13152
|
每天签到获得5枚红晶
|
|
13093
13153
|
`.trim();
|
|
13094
|
-
|
|
13095
|
-
|
|
13096
|
-
|
|
13154
|
+
});
|
|
13155
|
+
ctx.command("ggcevo/pk规则").action(({}) => {
|
|
13156
|
+
return `
|
|
13097
13157
|
⚔️【全新PK规则】⚔️
|
|
13098
13158
|
1️⃣ 阵营限制
|
|
13099
13159
|
仅限「人类联盟」与「辛迪加海盗」成员参与PK
|
|
@@ -13139,9 +13199,9 @@ PK同玩家限战:1次/日
|
|
|
13139
13199
|
清洁工,辛迪加财务经理,计算机专家,指挥官,装甲兵,破坏者,征募官:+3000
|
|
13140
13200
|
能量武器专家,枪手,猩红杀手,纵火狂:+4000
|
|
13141
13201
|
`.trim();
|
|
13142
|
-
|
|
13143
|
-
|
|
13144
|
-
|
|
13202
|
+
});
|
|
13203
|
+
ctx.command("ggcevo/击败奖励").alias("击杀奖励").action(({}) => {
|
|
13204
|
+
return `
|
|
13145
13205
|
🌟 异形主宰击败奖励规则 🌟
|
|
13146
13206
|
🏆 伤害榜奖励(按伤害排名):
|
|
13147
13207
|
1️⃣ 第1名:
|
|
@@ -13166,9 +13226,9 @@ PK同玩家限战:1次/日
|
|
|
13166
13226
|
2. 精灵双倍祈愿可通过“祈愿”指令概率获得
|
|
13167
13227
|
3. 排名根据实际造成伤害计算
|
|
13168
13228
|
`.trim();
|
|
13169
|
-
|
|
13170
|
-
|
|
13171
|
-
|
|
13229
|
+
});
|
|
13230
|
+
ctx.command("ggcevo/祈愿系统").action(({}) => {
|
|
13231
|
+
return `
|
|
13172
13232
|
🎋 祈愿系统
|
|
13173
13233
|
祈愿是连接星界的神秘仪式,消耗50金币可换取随机祈愿效果!通过智慧与运气的交织,助你在咕咕之战路上突破瓶颈。效果持续7天 ,冷却期间无法再次祈愿。
|
|
13174
13234
|
|
|
@@ -13186,9 +13246,9 @@ PK同玩家限战:1次/日
|
|
|
13186
13246
|
🎵 暴击韵律:攻击暴击率提高20%
|
|
13187
13247
|
⚠️ 酥手空空:立即失去50枚金币(可触发彩蛋)
|
|
13188
13248
|
`.trim();
|
|
13189
|
-
|
|
13190
|
-
|
|
13191
|
-
|
|
13249
|
+
});
|
|
13250
|
+
ctx.command("ggcevo/赛季奖励").alias("排名奖励").action(({}) => {
|
|
13251
|
+
return `
|
|
13192
13252
|
🏆 赛季排名奖励规则:
|
|
13193
13253
|
🥇 第1名:
|
|
13194
13254
|
100 咕咕币 + 🥇 赛季冠军勋章
|
|
@@ -13214,6 +13274,257 @@ PK同玩家限战:1次/日
|
|
|
13214
13274
|
2. 勋章可通过背包查看
|
|
13215
13275
|
3. 每个赛季持续2个月,可通过“胜点榜”指令查看
|
|
13216
13276
|
`.trim();
|
|
13277
|
+
});
|
|
13278
|
+
}
|
|
13279
|
+
ctx.command("roulette/创建轮盘 <items:text>", "创建轮盘(用逗号分隔选项)", { authority: 3 }).action(async ({ session }, items) => {
|
|
13280
|
+
if (!items) return "请输入轮盘选项,用逗号分隔。\n示例:roulette/创建轮盘 选项1,选项2,选项3";
|
|
13281
|
+
const itemsArray = items.split(",").map((item) => item.trim()).filter((item) => item);
|
|
13282
|
+
if (itemsArray.length === 0) return "至少需要一个有效的选项";
|
|
13283
|
+
try {
|
|
13284
|
+
const roulette = await ctx.model.create("roulettes", {
|
|
13285
|
+
items: itemsArray
|
|
13286
|
+
});
|
|
13287
|
+
return `轮盘创建成功!ID: ${roulette.id}
|
|
13288
|
+
包含选项:${itemsArray.join("、")}`;
|
|
13289
|
+
} catch (error) {
|
|
13290
|
+
return "创建轮盘失败:" + error.message;
|
|
13291
|
+
}
|
|
13292
|
+
});
|
|
13293
|
+
ctx.command("roulette/轮盘列表 [page:number]", "查看轮盘列表").option("group", "-g 查看轮盘组列表").action(async ({ session, options }, page = 1) => {
|
|
13294
|
+
const pageSize = 10;
|
|
13295
|
+
if (options.group) {
|
|
13296
|
+
const groups = await ctx.model.get("roulette_groups", {});
|
|
13297
|
+
const total = groups.length;
|
|
13298
|
+
const start = (page - 1) * pageSize;
|
|
13299
|
+
const end = start + pageSize;
|
|
13300
|
+
const pagedGroups = groups.slice(start, end);
|
|
13301
|
+
if (pagedGroups.length === 0) {
|
|
13302
|
+
return "暂无轮盘组";
|
|
13303
|
+
}
|
|
13304
|
+
let message = "轮盘组列表:\n";
|
|
13305
|
+
pagedGroups.forEach((group) => {
|
|
13306
|
+
message += `ID: ${group.id} | 名称: ${group.name} | 包含轮盘数: ${group.items.length}
|
|
13307
|
+
`;
|
|
13308
|
+
});
|
|
13309
|
+
message += `
|
|
13310
|
+
第${page}页,共${Math.ceil(total / pageSize)}页`;
|
|
13311
|
+
return message;
|
|
13312
|
+
} else {
|
|
13313
|
+
const roulettes = await ctx.model.get("roulettes", {});
|
|
13314
|
+
const total = roulettes.length;
|
|
13315
|
+
const start = (page - 1) * pageSize;
|
|
13316
|
+
const end = start + pageSize;
|
|
13317
|
+
const pagedRoulettes = roulettes.slice(start, end);
|
|
13318
|
+
if (pagedRoulettes.length === 0) {
|
|
13319
|
+
return "暂无轮盘";
|
|
13320
|
+
}
|
|
13321
|
+
let message = "轮盘列表:\n";
|
|
13322
|
+
pagedRoulettes.forEach((roulette) => {
|
|
13323
|
+
message += `ID: ${roulette.id} | 选项数: ${roulette.items.length}
|
|
13324
|
+
`;
|
|
13325
|
+
message += `选项: ${roulette.items.join("、")}
|
|
13326
|
+
|
|
13327
|
+
`;
|
|
13328
|
+
});
|
|
13329
|
+
message += `第${page}页,共${Math.ceil(total / pageSize)}页`;
|
|
13330
|
+
return message;
|
|
13331
|
+
}
|
|
13332
|
+
});
|
|
13333
|
+
ctx.command("roulette/创建轮盘组 <name> <rouletteIds:text>", "创建轮盘组(轮盘ID用逗号分隔)", { authority: 3 }).action(async ({ session }, name2, rouletteIds) => {
|
|
13334
|
+
if (!name2) return "请输入轮盘组名称";
|
|
13335
|
+
if (!rouletteIds) return "请输入轮盘ID,用逗号分隔";
|
|
13336
|
+
const ids = rouletteIds.split(",").map((id) => parseInt(id.trim())).filter((id) => !isNaN(id));
|
|
13337
|
+
if (ids.length === 0) return "至少需要一个有效的轮盘ID";
|
|
13338
|
+
for (const id of ids) {
|
|
13339
|
+
const roulette = await ctx.model.get("roulettes", { id });
|
|
13340
|
+
if (!roulette || roulette.length === 0) {
|
|
13341
|
+
return `轮盘 ID ${id} 不存在`;
|
|
13342
|
+
}
|
|
13343
|
+
}
|
|
13344
|
+
try {
|
|
13345
|
+
const existingGroup = await ctx.model.get("roulette_groups", { name: name2 });
|
|
13346
|
+
if (existingGroup && existingGroup.length > 0) {
|
|
13347
|
+
return "轮盘组名称已存在";
|
|
13348
|
+
}
|
|
13349
|
+
const group = await ctx.model.create("roulette_groups", {
|
|
13350
|
+
name: name2,
|
|
13351
|
+
items: ids
|
|
13352
|
+
});
|
|
13353
|
+
return `轮盘组创建成功!
|
|
13354
|
+
名称: ${group.name}
|
|
13355
|
+
ID: ${group.id}
|
|
13356
|
+
包含轮盘: ${ids.join("、")}`;
|
|
13357
|
+
} catch (error) {
|
|
13358
|
+
return "创建轮盘组失败:" + error.message;
|
|
13359
|
+
}
|
|
13360
|
+
});
|
|
13361
|
+
ctx.command("roulette/轮盘抽奖 <target>", "抽奖(输入轮盘ID或轮盘组名称)").option("count", "-c <count:number> 抽奖次数,默认1次", { fallback: 1 }).action(async ({ session, options }, target) => {
|
|
13362
|
+
if (!target) return "请输入轮盘ID(数字)或轮盘组名称(中文)";
|
|
13363
|
+
const count = Math.min(Math.max(1, options.count || 1), 10);
|
|
13364
|
+
const isNumeric = /^\d+$/.test(target);
|
|
13365
|
+
if (isNumeric) {
|
|
13366
|
+
const roulette = await ctx.model.get("roulettes", { id: parseInt(target) });
|
|
13367
|
+
if (!roulette || roulette.length === 0) {
|
|
13368
|
+
return `轮盘 ID ${target} 不存在`;
|
|
13369
|
+
}
|
|
13370
|
+
const items = roulette[0].items;
|
|
13371
|
+
if (items.length === 0) {
|
|
13372
|
+
return "该轮盘没有可抽奖的选项";
|
|
13373
|
+
}
|
|
13374
|
+
const results = [];
|
|
13375
|
+
for (let i = 0; i < count; i++) {
|
|
13376
|
+
const randomIndex = Math.floor(Math.random() * items.length);
|
|
13377
|
+
results.push(items[randomIndex]);
|
|
13378
|
+
}
|
|
13379
|
+
let message = `轮盘 ID: ${target}
|
|
13380
|
+
抽奖结果:
|
|
13381
|
+
`;
|
|
13382
|
+
if (count === 1) {
|
|
13383
|
+
message += `🎉 ${results[0]} 🎉`;
|
|
13384
|
+
} else {
|
|
13385
|
+
results.forEach((result, index) => {
|
|
13386
|
+
message += `${index + 1}. ${result}
|
|
13387
|
+
`;
|
|
13388
|
+
});
|
|
13389
|
+
}
|
|
13390
|
+
return message;
|
|
13391
|
+
} else {
|
|
13392
|
+
const group = await ctx.model.get("roulette_groups", { name: target });
|
|
13393
|
+
if (!group || group.length === 0) {
|
|
13394
|
+
return `轮盘组 "${target}" 不存在`;
|
|
13395
|
+
}
|
|
13396
|
+
const rouletteIds = group[0].items;
|
|
13397
|
+
if (rouletteIds.length === 0) {
|
|
13398
|
+
return "该轮盘组没有可抽奖的轮盘";
|
|
13399
|
+
}
|
|
13400
|
+
const roulettes = await Promise.all(
|
|
13401
|
+
rouletteIds.map(async (id) => {
|
|
13402
|
+
const roulette = await ctx.model.get("roulettes", { id });
|
|
13403
|
+
return roulette && roulette.length > 0 ? roulette[0] : null;
|
|
13404
|
+
})
|
|
13405
|
+
);
|
|
13406
|
+
const validRoulettes = roulettes.filter((roulette) => roulette !== null);
|
|
13407
|
+
if (validRoulettes.length === 0) {
|
|
13408
|
+
return "轮盘组中的轮盘已不存在";
|
|
13409
|
+
}
|
|
13410
|
+
const results = validRoulettes.map((roulette) => {
|
|
13411
|
+
if (roulette.items.length === 0) {
|
|
13412
|
+
return { id: roulette.id, result: "(无选项)" };
|
|
13413
|
+
}
|
|
13414
|
+
const randomIndex = Math.floor(Math.random() * roulette.items.length);
|
|
13415
|
+
return { id: roulette.id, result: roulette.items[randomIndex] };
|
|
13416
|
+
});
|
|
13417
|
+
let finalResults;
|
|
13418
|
+
if (count <= validRoulettes.length) {
|
|
13419
|
+
finalResults = results.slice(0, count);
|
|
13420
|
+
} else {
|
|
13421
|
+
finalResults = [...results];
|
|
13422
|
+
for (let i = validRoulettes.length; i < count; i++) {
|
|
13423
|
+
const randomRouletteIndex = Math.floor(Math.random() * validRoulettes.length);
|
|
13424
|
+
const roulette = validRoulettes[randomRouletteIndex];
|
|
13425
|
+
if (roulette.items.length > 0) {
|
|
13426
|
+
const randomIndex = Math.floor(Math.random() * roulette.items.length);
|
|
13427
|
+
finalResults.push({
|
|
13428
|
+
id: roulette.id,
|
|
13429
|
+
result: roulette.items[randomIndex],
|
|
13430
|
+
isAdditional: true
|
|
13431
|
+
});
|
|
13432
|
+
}
|
|
13433
|
+
}
|
|
13434
|
+
}
|
|
13435
|
+
let message = `轮盘组: ${target}
|
|
13436
|
+
`;
|
|
13437
|
+
message += `抽奖结果(从${finalResults.length}个轮盘中各抽取1个):
|
|
13438
|
+
|
|
13439
|
+
`;
|
|
13440
|
+
finalResults.forEach((item, index) => {
|
|
13441
|
+
const prefix = item.isAdditional ? `附加${index - validRoulettes.length + 1}.` : `${index + 1}.`;
|
|
13442
|
+
message += `${prefix} [轮盘ID: ${item.id}] ${item.result}
|
|
13443
|
+
`;
|
|
13444
|
+
});
|
|
13445
|
+
return message;
|
|
13446
|
+
}
|
|
13447
|
+
});
|
|
13448
|
+
ctx.command("roulette/删除轮盘 <id:number>", "删除轮盘", { authority: 3 }).option("group", "-g 删除轮盘组").action(async ({ session, options }, id) => {
|
|
13449
|
+
if (!id) return "请输入要删除的ID";
|
|
13450
|
+
if (options.group) {
|
|
13451
|
+
const deleted = await ctx.model.remove("roulette_groups", { id });
|
|
13452
|
+
if (deleted) {
|
|
13453
|
+
return "轮盘组删除成功";
|
|
13454
|
+
} else {
|
|
13455
|
+
return "轮盘组不存在";
|
|
13456
|
+
}
|
|
13457
|
+
} else {
|
|
13458
|
+
const deleted = await ctx.model.remove("roulettes", { id });
|
|
13459
|
+
if (deleted) {
|
|
13460
|
+
return "轮盘删除成功";
|
|
13461
|
+
} else {
|
|
13462
|
+
return "轮盘不存在";
|
|
13463
|
+
}
|
|
13464
|
+
}
|
|
13465
|
+
});
|
|
13466
|
+
ctx.command("roulette/轮盘详情 <target>", "查看轮盘或轮盘组详情").action(async ({ session }, target) => {
|
|
13467
|
+
if (!target) return "请输入轮盘ID(数字)或轮盘组名称(中文)";
|
|
13468
|
+
const isNumeric = /^\d+$/.test(target);
|
|
13469
|
+
if (isNumeric) {
|
|
13470
|
+
const roulette = await ctx.model.get("roulettes", { id: parseInt(target) });
|
|
13471
|
+
if (!roulette || roulette.length === 0) {
|
|
13472
|
+
return `轮盘 ID ${target} 不存在`;
|
|
13473
|
+
}
|
|
13474
|
+
const data = roulette[0];
|
|
13475
|
+
return `轮盘 ID: ${data.id}
|
|
13476
|
+
选项数: ${data.items.length}
|
|
13477
|
+
选项列表:
|
|
13478
|
+
${data.items.map((item, index) => `${index + 1}. ${item}`).join("\n")}`;
|
|
13479
|
+
} else {
|
|
13480
|
+
const group = await ctx.model.get("roulette_groups", { name: target });
|
|
13481
|
+
if (!group || group.length === 0) {
|
|
13482
|
+
return `轮盘组 "${target}" 不存在`;
|
|
13483
|
+
}
|
|
13484
|
+
const data = group[0];
|
|
13485
|
+
let roulettesInfo = "";
|
|
13486
|
+
for (const rouletteId of data.items) {
|
|
13487
|
+
const roulette = await ctx.model.get("roulettes", { id: rouletteId });
|
|
13488
|
+
if (roulette && roulette.length > 0) {
|
|
13489
|
+
roulettesInfo += `
|
|
13490
|
+
- 轮盘 ID ${rouletteId}: ${roulette[0].items.length} 个选项`;
|
|
13491
|
+
} else {
|
|
13492
|
+
roulettesInfo += `
|
|
13493
|
+
- 轮盘 ID ${rouletteId}: 已删除`;
|
|
13494
|
+
}
|
|
13495
|
+
}
|
|
13496
|
+
return `轮盘组: ${data.name}
|
|
13497
|
+
ID: ${data.id}
|
|
13498
|
+
包含轮盘数: ${data.items.length}
|
|
13499
|
+
轮盘列表:${roulettesInfo}`;
|
|
13500
|
+
}
|
|
13501
|
+
});
|
|
13502
|
+
ctx.command("roulette/批量轮盘抽奖 <ids:text>", "从多个轮盘中各抽一次奖(ID用逗号分隔)").action(async ({ session }, idsText) => {
|
|
13503
|
+
if (!idsText) return "请输入轮盘ID,用逗号分隔\n示例:roulette/multi 1,3,5";
|
|
13504
|
+
const ids = idsText.split(",").map((id) => parseInt(id.trim())).filter((id) => !isNaN(id));
|
|
13505
|
+
if (ids.length === 0) return "请输入有效的轮盘ID";
|
|
13506
|
+
let message = "批量抽奖结果:\n\n";
|
|
13507
|
+
for (const id of ids) {
|
|
13508
|
+
const roulette = await ctx.model.get("roulettes", { id });
|
|
13509
|
+
if (!roulette || roulette.length === 0) {
|
|
13510
|
+
message += `轮盘 ID ${id}: 不存在
|
|
13511
|
+
|
|
13512
|
+
`;
|
|
13513
|
+
continue;
|
|
13514
|
+
}
|
|
13515
|
+
const items = roulette[0].items;
|
|
13516
|
+
if (items.length === 0) {
|
|
13517
|
+
message += `轮盘 ID ${id}: 无选项
|
|
13518
|
+
|
|
13519
|
+
`;
|
|
13520
|
+
continue;
|
|
13521
|
+
}
|
|
13522
|
+
const randomIndex = Math.floor(Math.random() * items.length);
|
|
13523
|
+
message += `轮盘 ID ${id}: ${items[randomIndex]}
|
|
13524
|
+
|
|
13525
|
+
`;
|
|
13526
|
+
}
|
|
13527
|
+
return message;
|
|
13217
13528
|
});
|
|
13218
13529
|
}
|
|
13219
13530
|
__name(apply, "apply");
|