koishi-plugin-noah 2.3.7 → 2.3.8
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/core/api/auth.d.ts +18 -0
- package/lib/core/api/index.d.ts +3 -0
- package/lib/core/command.d.ts +4 -1
- package/lib/core/commands/settings.d.ts +3 -0
- package/lib/core/utils/selector.d.ts +13 -0
- package/lib/index.cjs +620 -170
- package/lib/types/config.d.ts +6 -0
- package/package.json +5 -3
package/lib/index.cjs
CHANGED
|
@@ -337,12 +337,54 @@ __export(core_exports, {
|
|
|
337
337
|
});
|
|
338
338
|
var import_koishi6 = require("koishi");
|
|
339
339
|
|
|
340
|
-
// src/core/
|
|
341
|
-
var
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
340
|
+
// src/core/api/auth.ts
|
|
341
|
+
var crypto = __toESM(require("crypto"), 1);
|
|
342
|
+
function resolveApiContext(config) {
|
|
343
|
+
return {
|
|
344
|
+
secret: crypto.randomBytes(32).toString("hex"),
|
|
345
|
+
tokenTtl: config.tokenTtl ?? 1800,
|
|
346
|
+
frontendUrl: config.frontendUrl ?? "",
|
|
347
|
+
corsOrigin: config.corsOrigin ?? "*"
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
__name(resolveApiContext, "resolveApiContext");
|
|
351
|
+
var ALG = "sha256";
|
|
352
|
+
function base64url(data) {
|
|
353
|
+
const buf = typeof data === "string" ? Buffer.from(data) : data;
|
|
354
|
+
return buf.toString("base64url");
|
|
355
|
+
}
|
|
356
|
+
__name(base64url, "base64url");
|
|
357
|
+
function sign(payload, secret) {
|
|
358
|
+
const header = base64url(JSON.stringify({ alg: "HS256", typ: "JWT" }));
|
|
359
|
+
const body = base64url(payload);
|
|
360
|
+
const signature = crypto.createHmac(ALG, secret).update(`${header}.${body}`).digest("base64url");
|
|
361
|
+
return `${header}.${body}.${signature}`;
|
|
362
|
+
}
|
|
363
|
+
__name(sign, "sign");
|
|
364
|
+
function createToken(uid, secret, ttlSeconds = 1800) {
|
|
365
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
366
|
+
const payload = { uid, iat: now, exp: now + ttlSeconds };
|
|
367
|
+
return sign(JSON.stringify(payload), secret);
|
|
368
|
+
}
|
|
369
|
+
__name(createToken, "createToken");
|
|
370
|
+
function verifyToken(token, secret) {
|
|
371
|
+
const parts = token.split(".");
|
|
372
|
+
if (parts.length !== 3) return null;
|
|
373
|
+
const [header, body, signature] = parts;
|
|
374
|
+
const expected = crypto.createHmac(ALG, secret).update(`${header}.${body}`).digest("base64url");
|
|
375
|
+
if (!crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected))) return null;
|
|
376
|
+
try {
|
|
377
|
+
const payload = JSON.parse(Buffer.from(body, "base64url").toString());
|
|
378
|
+
if (payload.exp < Math.floor(Date.now() / 1e3)) return null;
|
|
379
|
+
return payload;
|
|
380
|
+
} catch {
|
|
381
|
+
return null;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
__name(verifyToken, "verifyToken");
|
|
385
|
+
|
|
386
|
+
// src/types/index.ts
|
|
387
|
+
var serverValues = ["asphyxia", "mao", "official"];
|
|
346
388
|
|
|
347
389
|
// src/core/services/card-service.ts
|
|
348
390
|
var CardService = class {
|
|
@@ -725,7 +767,7 @@ var UserService = class {
|
|
|
725
767
|
};
|
|
726
768
|
|
|
727
769
|
// src/core/utils/card.ts
|
|
728
|
-
var
|
|
770
|
+
var crypto2 = __toESM(require("crypto"), 1);
|
|
729
771
|
var KEY_STRING = "?I'llB2c.YouXXXeMeHaYpy!";
|
|
730
772
|
var KEY_BUFFER = Buffer.from(KEY_STRING, "ascii");
|
|
731
773
|
var DES3_KEY = Buffer.from(KEY_BUFFER.map((b) => b * 2 & 255));
|
|
@@ -735,7 +777,7 @@ function encDes(data) {
|
|
|
735
777
|
if (data.length !== 8) {
|
|
736
778
|
throw new Error("encDes: data must be 8 bytes");
|
|
737
779
|
}
|
|
738
|
-
const cipher =
|
|
780
|
+
const cipher = crypto2.createCipheriv("des-ede3-cbc", DES3_KEY, IV);
|
|
739
781
|
cipher.setAutoPadding(false);
|
|
740
782
|
const encrypted = Buffer.concat([cipher.update(data), cipher.final()]);
|
|
741
783
|
return encrypted;
|
|
@@ -745,7 +787,7 @@ function decDes(data) {
|
|
|
745
787
|
if (data.length !== 8) {
|
|
746
788
|
throw new Error("decDes: data must be 8 bytes");
|
|
747
789
|
}
|
|
748
|
-
const decipher =
|
|
790
|
+
const decipher = crypto2.createDecipheriv("des-ede3-cbc", DES3_KEY, IV);
|
|
749
791
|
decipher.setAutoPadding(false);
|
|
750
792
|
const decrypted = Buffer.concat([decipher.update(data), decipher.final()]);
|
|
751
793
|
return decrypted;
|
|
@@ -1034,6 +1076,337 @@ async function ensureOfficialServerForUser(ctx, serverService, userService, uid,
|
|
|
1034
1076
|
}
|
|
1035
1077
|
__name(ensureOfficialServerForUser, "ensureOfficialServerForUser");
|
|
1036
1078
|
|
|
1079
|
+
// src/core/api/index.ts
|
|
1080
|
+
function registerApiRoutes(ctx, apiCtx) {
|
|
1081
|
+
const { secret, corsOrigin } = apiCtx;
|
|
1082
|
+
function setCors(kctx) {
|
|
1083
|
+
kctx.set("Access-Control-Allow-Origin", corsOrigin);
|
|
1084
|
+
kctx.set("Access-Control-Allow-Methods", "GET, POST, PUT, PATCH, DELETE, OPTIONS");
|
|
1085
|
+
kctx.set("Access-Control-Allow-Headers", "Authorization, Content-Type");
|
|
1086
|
+
}
|
|
1087
|
+
__name(setCors, "setCors");
|
|
1088
|
+
function authenticate(kctx) {
|
|
1089
|
+
const auth = kctx.get("Authorization");
|
|
1090
|
+
if (!auth?.startsWith("Bearer ")) return null;
|
|
1091
|
+
return verifyToken(auth.slice(7), secret);
|
|
1092
|
+
}
|
|
1093
|
+
__name(authenticate, "authenticate");
|
|
1094
|
+
function unauthorized(kctx) {
|
|
1095
|
+
kctx.status = 401;
|
|
1096
|
+
kctx.body = { error: "Unauthorized" };
|
|
1097
|
+
}
|
|
1098
|
+
__name(unauthorized, "unauthorized");
|
|
1099
|
+
function badRequest(kctx, message) {
|
|
1100
|
+
kctx.status = 400;
|
|
1101
|
+
kctx.body = { error: message };
|
|
1102
|
+
}
|
|
1103
|
+
__name(badRequest, "badRequest");
|
|
1104
|
+
ctx.server.get("/noah/api/health", async (kctx) => {
|
|
1105
|
+
setCors(kctx);
|
|
1106
|
+
kctx.body = { status: "ok" };
|
|
1107
|
+
});
|
|
1108
|
+
const apiPaths = [
|
|
1109
|
+
"/noah/api/me",
|
|
1110
|
+
"/noah/api/cards",
|
|
1111
|
+
"/noah/api/cards/:id",
|
|
1112
|
+
"/noah/api/servers",
|
|
1113
|
+
"/noah/api/servers/:id",
|
|
1114
|
+
"/noah/api/defaults",
|
|
1115
|
+
"/noah/api/resolve",
|
|
1116
|
+
"/noah/api/health"
|
|
1117
|
+
];
|
|
1118
|
+
for (const path3 of apiPaths) {
|
|
1119
|
+
ctx.server.all(path3, async (kctx, next) => {
|
|
1120
|
+
setCors(kctx);
|
|
1121
|
+
if (kctx.method === "OPTIONS") {
|
|
1122
|
+
kctx.status = 204;
|
|
1123
|
+
return;
|
|
1124
|
+
}
|
|
1125
|
+
await next();
|
|
1126
|
+
});
|
|
1127
|
+
}
|
|
1128
|
+
ctx.server.get("/noah/api/me", async (kctx) => {
|
|
1129
|
+
setCors(kctx);
|
|
1130
|
+
const payload = authenticate(kctx);
|
|
1131
|
+
if (!payload) return unauthorized(kctx);
|
|
1132
|
+
const cardService = new CardService(ctx);
|
|
1133
|
+
const serverService = new ServerService(ctx);
|
|
1134
|
+
const defaultCard = await cardService.getDefaultCardByUid(payload.uid);
|
|
1135
|
+
const defaultServer = await serverService.getDefaultServerByUid(payload.uid);
|
|
1136
|
+
kctx.body = {
|
|
1137
|
+
uid: payload.uid,
|
|
1138
|
+
defaultCardId: defaultCard?.id ?? null,
|
|
1139
|
+
defaultServerId: defaultServer?.id ?? null
|
|
1140
|
+
};
|
|
1141
|
+
});
|
|
1142
|
+
ctx.server.get("/noah/api/cards", async (kctx) => {
|
|
1143
|
+
setCors(kctx);
|
|
1144
|
+
const payload = authenticate(kctx);
|
|
1145
|
+
if (!payload) return unauthorized(kctx);
|
|
1146
|
+
const cardService = new CardService(ctx);
|
|
1147
|
+
const defaultCard = await cardService.getDefaultCardByUid(payload.uid);
|
|
1148
|
+
const cards = await cardService.getCardsByUid(payload.uid);
|
|
1149
|
+
kctx.body = cards.map((card2) => ({
|
|
1150
|
+
id: card2.id,
|
|
1151
|
+
code: card2.code,
|
|
1152
|
+
name: card2.name,
|
|
1153
|
+
defaultServerId: card2.defaultServerId || null,
|
|
1154
|
+
isDefault: defaultCard?.id === card2.id
|
|
1155
|
+
}));
|
|
1156
|
+
});
|
|
1157
|
+
ctx.server.post("/noah/api/cards", async (kctx) => {
|
|
1158
|
+
setCors(kctx);
|
|
1159
|
+
const payload = authenticate(kctx);
|
|
1160
|
+
if (!payload) return unauthorized(kctx);
|
|
1161
|
+
const body = kctx.request.body;
|
|
1162
|
+
if (!body?.code || !body?.name) return badRequest(kctx, "code and name are required");
|
|
1163
|
+
const cardService = new CardService(ctx);
|
|
1164
|
+
const serverService = new ServerService(ctx);
|
|
1165
|
+
const userService = new UserService(ctx);
|
|
1166
|
+
const processed = processInputCardCode(body.code);
|
|
1167
|
+
const cardType = classifyCardId(ctx, processed);
|
|
1168
|
+
if (cardType === "invalid") return badRequest(kctx, "Invalid card code");
|
|
1169
|
+
let finalCode = processed;
|
|
1170
|
+
if (cardType === "access") {
|
|
1171
|
+
try {
|
|
1172
|
+
finalCode = await accessToUid(ctx, processed);
|
|
1173
|
+
} catch (e) {
|
|
1174
|
+
return badRequest(kctx, `Failed to convert access code: ${e.message}`);
|
|
1175
|
+
}
|
|
1176
|
+
} else if (cardType === "konamiid") {
|
|
1177
|
+
try {
|
|
1178
|
+
finalCode = konamiIdToUid(processed);
|
|
1179
|
+
} catch (e) {
|
|
1180
|
+
return badRequest(kctx, `Failed to convert Konami ID: ${e.message}`);
|
|
1181
|
+
}
|
|
1182
|
+
}
|
|
1183
|
+
const existing = await cardService.getCardByCode(finalCode);
|
|
1184
|
+
if (existing) return badRequest(kctx, "Card already exists");
|
|
1185
|
+
const card2 = await cardService.createCard(payload.uid, finalCode, body.name);
|
|
1186
|
+
if (cardType === "official") {
|
|
1187
|
+
await ensureOfficialServerForUser(ctx, serverService, userService, payload.uid);
|
|
1188
|
+
}
|
|
1189
|
+
const defaultCard = await cardService.getDefaultCardByUid(payload.uid);
|
|
1190
|
+
if (!defaultCard) {
|
|
1191
|
+
await userService.updateUserDefaultCard(payload.uid, card2.id);
|
|
1192
|
+
}
|
|
1193
|
+
kctx.status = 201;
|
|
1194
|
+
kctx.body = { id: card2.id, code: card2.code, name: card2.name, defaultServerId: null };
|
|
1195
|
+
});
|
|
1196
|
+
ctx.server.patch("/noah/api/cards/:id", async (kctx) => {
|
|
1197
|
+
setCors(kctx);
|
|
1198
|
+
const payload = authenticate(kctx);
|
|
1199
|
+
if (!payload) return unauthorized(kctx);
|
|
1200
|
+
const cardId = Number(kctx.params.id);
|
|
1201
|
+
if (isNaN(cardId)) return badRequest(kctx, "Invalid card id");
|
|
1202
|
+
const cardService = new CardService(ctx);
|
|
1203
|
+
const cards = await cardService.getCardsByUid(payload.uid);
|
|
1204
|
+
if (!cards.find((c) => c.id === cardId)) {
|
|
1205
|
+
kctx.status = 404;
|
|
1206
|
+
kctx.body = { error: "Card not found" };
|
|
1207
|
+
return;
|
|
1208
|
+
}
|
|
1209
|
+
const body = kctx.request.body ?? {};
|
|
1210
|
+
const update = {};
|
|
1211
|
+
if (body.name !== void 0) update.name = body.name;
|
|
1212
|
+
if (body.defaultServerId !== void 0) update.defaultServerId = body.defaultServerId ?? 0;
|
|
1213
|
+
if (Object.keys(update).length > 0) {
|
|
1214
|
+
await cardService.updateCard(cardId, update);
|
|
1215
|
+
}
|
|
1216
|
+
const updated = await cardService.getCardById(cardId);
|
|
1217
|
+
kctx.body = updated;
|
|
1218
|
+
});
|
|
1219
|
+
ctx.server.delete("/noah/api/cards/:id", async (kctx) => {
|
|
1220
|
+
setCors(kctx);
|
|
1221
|
+
const payload = authenticate(kctx);
|
|
1222
|
+
if (!payload) return unauthorized(kctx);
|
|
1223
|
+
const cardId = Number(kctx.params.id);
|
|
1224
|
+
if (isNaN(cardId)) return badRequest(kctx, "Invalid card id");
|
|
1225
|
+
const cardService = new CardService(ctx);
|
|
1226
|
+
const cards = await cardService.getCardsByUid(payload.uid);
|
|
1227
|
+
if (!cards.find((c) => c.id === cardId)) {
|
|
1228
|
+
kctx.status = 404;
|
|
1229
|
+
kctx.body = { error: "Card not found" };
|
|
1230
|
+
return;
|
|
1231
|
+
}
|
|
1232
|
+
await cardService.removeCard(cardId);
|
|
1233
|
+
kctx.status = 204;
|
|
1234
|
+
});
|
|
1235
|
+
ctx.server.get("/noah/api/servers", async (kctx) => {
|
|
1236
|
+
setCors(kctx);
|
|
1237
|
+
const payload = authenticate(kctx);
|
|
1238
|
+
if (!payload) return unauthorized(kctx);
|
|
1239
|
+
const serverService = new ServerService(ctx);
|
|
1240
|
+
const defaultServer = await serverService.getDefaultServerByUid(payload.uid);
|
|
1241
|
+
const servers = await serverService.getServersByUid(payload.uid);
|
|
1242
|
+
kctx.body = servers.map((s) => ({
|
|
1243
|
+
id: s.id,
|
|
1244
|
+
type: s.type,
|
|
1245
|
+
name: s.name,
|
|
1246
|
+
baseUrl: s.baseUrl,
|
|
1247
|
+
pcbid: s.pcbid ?? null,
|
|
1248
|
+
isDefault: defaultServer?.id === s.id
|
|
1249
|
+
}));
|
|
1250
|
+
});
|
|
1251
|
+
ctx.server.post("/noah/api/servers", async (kctx) => {
|
|
1252
|
+
setCors(kctx);
|
|
1253
|
+
const payload = authenticate(kctx);
|
|
1254
|
+
if (!payload) return unauthorized(kctx);
|
|
1255
|
+
const body = kctx.request.body;
|
|
1256
|
+
if (!body?.type || !body?.name) return badRequest(kctx, "type and name are required");
|
|
1257
|
+
if (!serverValues.includes(body.type)) {
|
|
1258
|
+
return badRequest(
|
|
1259
|
+
kctx,
|
|
1260
|
+
`Invalid server type. Must be one of: ${serverValues.join(", ")}`
|
|
1261
|
+
);
|
|
1262
|
+
}
|
|
1263
|
+
const serverService = new ServerService(ctx);
|
|
1264
|
+
const userService = new UserService(ctx);
|
|
1265
|
+
const server2 = await serverService.createServerForUser(
|
|
1266
|
+
{
|
|
1267
|
+
type: body.type,
|
|
1268
|
+
name: body.name,
|
|
1269
|
+
baseUrl: body.baseUrl ?? "",
|
|
1270
|
+
pcbid: body.pcbid,
|
|
1271
|
+
supportedGames: []
|
|
1272
|
+
},
|
|
1273
|
+
payload.uid
|
|
1274
|
+
);
|
|
1275
|
+
const defaultServer = await serverService.getDefaultServerByUid(payload.uid);
|
|
1276
|
+
if (!defaultServer) {
|
|
1277
|
+
await userService.updateUserDefaultServer(payload.uid, server2.id);
|
|
1278
|
+
}
|
|
1279
|
+
kctx.status = 201;
|
|
1280
|
+
kctx.body = {
|
|
1281
|
+
id: server2.id,
|
|
1282
|
+
type: server2.type,
|
|
1283
|
+
name: server2.name,
|
|
1284
|
+
baseUrl: server2.baseUrl,
|
|
1285
|
+
pcbid: server2.pcbid ?? null
|
|
1286
|
+
};
|
|
1287
|
+
});
|
|
1288
|
+
ctx.server.patch("/noah/api/servers/:id", async (kctx) => {
|
|
1289
|
+
setCors(kctx);
|
|
1290
|
+
const payload = authenticate(kctx);
|
|
1291
|
+
if (!payload) return unauthorized(kctx);
|
|
1292
|
+
const serverId = Number(kctx.params.id);
|
|
1293
|
+
if (isNaN(serverId)) return badRequest(kctx, "Invalid server id");
|
|
1294
|
+
const serverService = new ServerService(ctx);
|
|
1295
|
+
const servers = await serverService.getServersByUid(payload.uid);
|
|
1296
|
+
if (!servers.find((s) => s.id === serverId)) {
|
|
1297
|
+
kctx.status = 404;
|
|
1298
|
+
kctx.body = { error: "Server not found" };
|
|
1299
|
+
return;
|
|
1300
|
+
}
|
|
1301
|
+
const body = kctx.request.body ?? {};
|
|
1302
|
+
const update = {};
|
|
1303
|
+
if (body.name !== void 0) update.name = body.name;
|
|
1304
|
+
if (body.baseUrl !== void 0) update.baseUrl = body.baseUrl;
|
|
1305
|
+
if (body.pcbid !== void 0) update.pcbid = body.pcbid;
|
|
1306
|
+
if (Object.keys(update).length > 0) {
|
|
1307
|
+
await serverService.updateServer(serverId, update);
|
|
1308
|
+
}
|
|
1309
|
+
const updated = await serverService.getServerById(serverId);
|
|
1310
|
+
kctx.body = {
|
|
1311
|
+
id: updated.id,
|
|
1312
|
+
type: updated.type,
|
|
1313
|
+
name: updated.name,
|
|
1314
|
+
baseUrl: updated.baseUrl,
|
|
1315
|
+
pcbid: updated.pcbid ?? null
|
|
1316
|
+
};
|
|
1317
|
+
});
|
|
1318
|
+
ctx.server.delete("/noah/api/servers/:id", async (kctx) => {
|
|
1319
|
+
setCors(kctx);
|
|
1320
|
+
const payload = authenticate(kctx);
|
|
1321
|
+
if (!payload) return unauthorized(kctx);
|
|
1322
|
+
const serverId = Number(kctx.params.id);
|
|
1323
|
+
if (isNaN(serverId)) return badRequest(kctx, "Invalid server id");
|
|
1324
|
+
const serverService = new ServerService(ctx);
|
|
1325
|
+
const servers = await serverService.getServersByUid(payload.uid);
|
|
1326
|
+
if (!servers.find((s) => s.id === serverId)) {
|
|
1327
|
+
kctx.status = 404;
|
|
1328
|
+
kctx.body = { error: "Server not found" };
|
|
1329
|
+
return;
|
|
1330
|
+
}
|
|
1331
|
+
await serverService.removeServer(serverId);
|
|
1332
|
+
kctx.status = 204;
|
|
1333
|
+
});
|
|
1334
|
+
ctx.server.put("/noah/api/defaults", async (kctx) => {
|
|
1335
|
+
setCors(kctx);
|
|
1336
|
+
const payload = authenticate(kctx);
|
|
1337
|
+
if (!payload) return unauthorized(kctx);
|
|
1338
|
+
const body = kctx.request.body ?? {};
|
|
1339
|
+
const userService = new UserService(ctx);
|
|
1340
|
+
const cardService = new CardService(ctx);
|
|
1341
|
+
const serverService = new ServerService(ctx);
|
|
1342
|
+
if (body.defaultCardId !== void 0) {
|
|
1343
|
+
if (body.defaultCardId === null || body.defaultCardId === 0) {
|
|
1344
|
+
await userService.updateUserDefaultCard(payload.uid, 0);
|
|
1345
|
+
} else {
|
|
1346
|
+
const cards = await cardService.getCardsByUid(payload.uid);
|
|
1347
|
+
if (!cards.find((c) => c.id === body.defaultCardId)) {
|
|
1348
|
+
return badRequest(kctx, "Card not found");
|
|
1349
|
+
}
|
|
1350
|
+
await userService.updateUserDefaultCard(payload.uid, body.defaultCardId);
|
|
1351
|
+
}
|
|
1352
|
+
}
|
|
1353
|
+
if (body.defaultServerId !== void 0) {
|
|
1354
|
+
if (body.defaultServerId === null || body.defaultServerId === 0) {
|
|
1355
|
+
await userService.updateUserDefaultServer(payload.uid, 0);
|
|
1356
|
+
} else {
|
|
1357
|
+
const servers = await serverService.getServersByUid(payload.uid);
|
|
1358
|
+
if (!servers.find((s) => s.id === body.defaultServerId)) {
|
|
1359
|
+
return badRequest(kctx, "Server not found");
|
|
1360
|
+
}
|
|
1361
|
+
await userService.updateUserDefaultServer(payload.uid, body.defaultServerId);
|
|
1362
|
+
}
|
|
1363
|
+
}
|
|
1364
|
+
const defaultCard = await cardService.getDefaultCardByUid(payload.uid);
|
|
1365
|
+
const defaultServer = await serverService.getDefaultServerByUid(payload.uid);
|
|
1366
|
+
kctx.body = {
|
|
1367
|
+
defaultCardId: defaultCard?.id ?? null,
|
|
1368
|
+
defaultServerId: defaultServer?.id ?? null
|
|
1369
|
+
};
|
|
1370
|
+
});
|
|
1371
|
+
ctx.server.get("/noah/api/resolve", async (kctx) => {
|
|
1372
|
+
setCors(kctx);
|
|
1373
|
+
const payload = authenticate(kctx);
|
|
1374
|
+
if (!payload) return unauthorized(kctx);
|
|
1375
|
+
const cardService = new CardService(ctx);
|
|
1376
|
+
const serverService = new ServerService(ctx);
|
|
1377
|
+
const cards = await cardService.getCardsByUid(payload.uid);
|
|
1378
|
+
const defaultCard = await cardService.getDefaultCardByUid(payload.uid);
|
|
1379
|
+
const result = await Promise.all(
|
|
1380
|
+
cards.map(async (card2) => {
|
|
1381
|
+
let resolvedServer = null;
|
|
1382
|
+
if (card2.defaultServerId && card2.defaultServerId !== 0) {
|
|
1383
|
+
resolvedServer = await serverService.getServerById(card2.defaultServerId);
|
|
1384
|
+
}
|
|
1385
|
+
if (!resolvedServer) {
|
|
1386
|
+
resolvedServer = await serverService.getDefaultServerByUid(payload.uid);
|
|
1387
|
+
}
|
|
1388
|
+
return {
|
|
1389
|
+
cardId: card2.id,
|
|
1390
|
+
cardName: card2.name,
|
|
1391
|
+
isDefaultCard: defaultCard?.id === card2.id,
|
|
1392
|
+
resolvedServerId: resolvedServer?.id ?? null,
|
|
1393
|
+
resolvedServerName: resolvedServer?.name ?? null,
|
|
1394
|
+
source: card2.defaultServerId && card2.defaultServerId !== 0 ? "card" : "user-default"
|
|
1395
|
+
};
|
|
1396
|
+
})
|
|
1397
|
+
);
|
|
1398
|
+
kctx.body = result;
|
|
1399
|
+
});
|
|
1400
|
+
}
|
|
1401
|
+
__name(registerApiRoutes, "registerApiRoutes");
|
|
1402
|
+
|
|
1403
|
+
// src/core/command.ts
|
|
1404
|
+
var command_exports = {};
|
|
1405
|
+
__export(command_exports, {
|
|
1406
|
+
apply: () => apply2,
|
|
1407
|
+
name: () => name2
|
|
1408
|
+
});
|
|
1409
|
+
|
|
1037
1410
|
// src/core/commands/bind.ts
|
|
1038
1411
|
function bind(ctx, config) {
|
|
1039
1412
|
ctx.command("bind [cardCode:text]", { slash: true }).alias("绑卡").userFields(["defaultCardId", "id"]).action(async ({ session }, cardCode) => {
|
|
@@ -1603,11 +1976,6 @@ __name(maintain, "maintain");
|
|
|
1603
1976
|
|
|
1604
1977
|
// src/core/commands/server.ts
|
|
1605
1978
|
var import_koishi5 = require("koishi");
|
|
1606
|
-
|
|
1607
|
-
// src/types/index.ts
|
|
1608
|
-
var serverValues = ["asphyxia", "mao", "official"];
|
|
1609
|
-
|
|
1610
|
-
// src/core/commands/server.ts
|
|
1611
1979
|
function normalizeUrl(url) {
|
|
1612
1980
|
try {
|
|
1613
1981
|
if (!url.match(/^https?:\/\//i)) {
|
|
@@ -2014,6 +2382,17 @@ async function addServer(ctx, session, serverService, userService, from, uid, us
|
|
|
2014
2382
|
}
|
|
2015
2383
|
__name(addServer, "addServer");
|
|
2016
2384
|
|
|
2385
|
+
// src/core/commands/settings.ts
|
|
2386
|
+
function settings(ctx, apiCtx) {
|
|
2387
|
+
ctx.command("settings", { slash: true }).alias("设置").userFields(["id"]).action(async ({ session }) => {
|
|
2388
|
+
const { secret, tokenTtl, frontendUrl } = apiCtx;
|
|
2389
|
+
const token = createToken(session.user.id, secret, tokenTtl);
|
|
2390
|
+
const url = frontendUrl ? `${frontendUrl}?token=${token}` : `Token: ${token}`;
|
|
2391
|
+
return session.text(".success", { url, minutes: Math.floor(tokenTtl / 60) });
|
|
2392
|
+
});
|
|
2393
|
+
}
|
|
2394
|
+
__name(settings, "settings");
|
|
2395
|
+
|
|
2017
2396
|
// src/core/command.ts
|
|
2018
2397
|
var name2 = "command";
|
|
2019
2398
|
function apply2(ctx, config) {
|
|
@@ -2024,6 +2403,9 @@ function apply2(ctx, config) {
|
|
|
2024
2403
|
locale(ctx, config);
|
|
2025
2404
|
link(ctx, config);
|
|
2026
2405
|
maintain(ctx, config);
|
|
2406
|
+
if (config._apiCtx) {
|
|
2407
|
+
settings(ctx, config._apiCtx);
|
|
2408
|
+
}
|
|
2027
2409
|
}
|
|
2028
2410
|
__name(apply2, "apply");
|
|
2029
2411
|
|
|
@@ -2268,17 +2650,17 @@ function apply4(ctx, config) {
|
|
|
2268
2650
|
__name(apply4, "apply");
|
|
2269
2651
|
|
|
2270
2652
|
// src/core/locales/en-US.yml
|
|
2271
|
-
var en_US_default2 = { _config: { $desc: "Core Module Settings", adminUsers: "**Plugin Admin** User ID (use inspect command to get)", guildNameCards: "**Group Card** Name List", maoServerUrl: "**Mao Server** URL address", official_support_url: "**Official Support** URL address" }, commands: { maintain: { description: "Switch to maintenance mode", messages: { "no-auth": "<p>You don't have permission to use this feature~</p>", start: "<p>Entering maintenance mode</p>", "success-start": "<p>Successfully switched to maintenance mode</p>", stop: "<p>Exiting maintenance mode</p>", "success-stop": "<p>Successfully exited maintenance mode</p>" } }, timeout: "Noah didn't wait for your reply, please try again!", help: { description: "Show Noah help information", messages: { content: "<p>Guide:</p>\n<p>https://docs.logthm.cn/noah</p>", "qq-extra": "<p>Having issues? Join group 723977027 to give feedback~</p>" } }, locale: { description: "Set language", messages: { "no-auth": "<p>Only group admins can use this feature~</p>", "invalid-select": "<p>No such option!</p>", quit: "<p>Quit!</p>", "reset-channel": "<p>Reset successfully!</p>", "reset-user": "<p>Reset successfully!</p>", success: "<p>Set successfully!</p>", "set-channel": "<p>Select the default language for group chats:</p>\n<p>1. 简体中文</p>\n<p>2. English</p>\n<p>q. Quit</p>", "set-user": "<p>Select the language you use:</p>\n<p>1. 中文</p>\n<p>2. English</p>\n<p>q. Quit</p>" } }, link: { description: "Link account to another platform", options: { remove: "Unlink" }, messages: { "generated-1": `<p>The Link command can be used to link user data across multiple platforms. During the linking process, the original platform's user data is fully preserved, while the target platform's user data is overwritten.</p>
|
|
2653
|
+
var en_US_default2 = { _config: { $desc: "Core Module Settings", adminUsers: "**Plugin Admin** User ID (use inspect command to get)", guildNameCards: "**Group Card** Name List", maoServerUrl: "**Mao Server** URL address", official_support_url: "**Official Support** URL address", tokenTtl: "**Settings Panel** Link expiry time (seconds)", frontendUrl: "**Settings Panel** Frontend URL (/settings will generate a full link when set)", corsOrigin: "**Settings Panel** CORS allowed origin (set to frontend domain in production)" }, selector: { "card-not-found": "<p>You haven't bound a card yet, go bind one first~</p>", "server-not-found": "<p>No available servers, add one yourself~</p>", "menu-select": "<p>Please select the card you want to use:</p>\n{card_list}\n<p>q. Quit</p>", "server-menu-select": "<p>Please select the server you want to use:</p>\n{server_list}\n<p>q. Quit</p>", "invalid-select": "<p>No such option!</p>", quit: "<p>Quit!</p>", "default-card": "Default", "default-server": "Default" }, commands: { maintain: { description: "Switch to maintenance mode", messages: { "no-auth": "<p>You don't have permission to use this feature~</p>", start: "<p>Entering maintenance mode</p>", "success-start": "<p>Successfully switched to maintenance mode</p>", stop: "<p>Exiting maintenance mode</p>", "success-stop": "<p>Successfully exited maintenance mode</p>" } }, timeout: "Noah didn't wait for your reply, please try again!", help: { description: "Show Noah help information", messages: { content: "<p>Guide:</p>\n<p>https://docs.logthm.cn/noah</p>", "qq-extra": "<p>Having issues? Join group 723977027 to give feedback~</p>" } }, locale: { description: "Set language", messages: { "no-auth": "<p>Only group admins can use this feature~</p>", "invalid-select": "<p>No such option!</p>", quit: "<p>Quit!</p>", "reset-channel": "<p>Reset successfully!</p>", "reset-user": "<p>Reset successfully!</p>", success: "<p>Set successfully!</p>", "set-channel": "<p>Select the default language for group chats:</p>\n<p>1. 简体中文</p>\n<p>2. English</p>\n<p>q. Quit</p>", "set-user": "<p>Select the language you use:</p>\n<p>1. 中文</p>\n<p>2. English</p>\n<p>q. Quit</p>" } }, link: { description: "Link account to another platform", options: { remove: "Unlink" }, messages: { "generated-1": `<p>The Link command can be used to link user data across multiple platforms. During the linking process, the original platform's user data is fully preserved, while the target platform's user data is overwritten.</p>
|
|
2272
2654
|
<p>Please make sure the current platform is your target platform and send the following text to the bot on the original platform within 5 minutes:</p>
|
|
2273
2655
|
<p>{0}</p>
|
|
2274
|
-
<p>Once linked, you can use "link -r" to unlink at any time.</p>`, "generated-2": "<p>Token verified! Now proceeding to the second step.</p>\n<p>Please send the following text to the bot on the target platform within 5 minutes:</p>\n<p>{0}</p>\n<p>Note: The current platform is your original platform. User data here will overwrite the target platform's data.</p>", "self-1": "<p>Please enter this on the original platform.</p>", "self-2": "<p>Please enter this on the target platform.</p>", success: "<p>Account linked successfully!</p>", "remove-success": "<p>Account unlinked successfully!</p>", "remove-original": "<p>Cannot unlink: this is your original account.</p>" } }, bind: { description: "Bind card", messages: { prompt: "<p>Please enter your card number:</p>", "convert-access-failed": "<p>Failed to convert Access Code, please use 16-digit card code instead.</p>", "invalid-code": "<p>The card number is incorrect, if you don't remember it, go to the arcade to check it~</p>", name: "<p>Received! Please give this card a name, no spaces allowed:</p>", "invalid-name": "<p>No spaces allowed! Please try again o(一︿一+)o</p>", success: "<p>Bound successfully, your card information is as follows:</p>\n<p>[{cardName}]</p>\n<p>{cardCode}</p>" } }, card: { description: "Manage cards", options: { detail: "Show detailed card information" }, messages: { "invalid-code": "<p>The card number is incorrect, if you don't remember it, go to the arcade to check it~</p>", "invalid-select": "<p>No such option!</p>", "lookup-error": "Lookup failed: {message}", "lookup-error-unknown": "Lookup failed: unknown error", "menu-select": "<p>[Card Management]</p>\n{card_list}\n<p>0. Add new card</p>\n<p>Please enter the serial number:</p>", menu: "<p>[{name}]</p>\n<p>1. Set as default card</p>\n<p>2. View or modify card number</p>\n<p>3. Delete the card</p>\n<p>4. Rename the card</p>\n<p>5. Bind the card to a specified server</p>\n<p>0. Return to card selection</p>\n<p>Please enter the serial number:</p>", "menu-has-bound-server": "<p>[{name}]</p>\n<p>Bound server: {defaultServerName}</p>\n<p>1. Set as default card</p>\n<p>2. View or modify card number</p>\n<p>3. Delete the card</p>\n<p>4. Rename the card</p>\n<p>5. Bind the card to a specified server</p>\n<p>0. Return to card selection</p>\n<p>Please enter the serial number:</p>", "menu-1-success": "<p>Set successfully!</p>", "menu-1-error-duplicate": "<p>The selected card is the same as the old default card!</p>", "menu-2-prompt": "<p>Card number: {code}</p>\n<p>Please enter the new card number:</p>\n<p>Enter 0 to return</p>", "menu-2-success": "<p>Modified successfully!</p>", "menu-2-error-invalid-code": "<p>The card number is incorrect, if you don't remember it, go to the arcade to check it~</p>", "menu-3-success": "<p>Deleted successfully!</p>", "menu-4-prompt": "<p>Enter a new name, no spaces allowed:</p>", "menu-4-error-invalid-name": "<p>No spaces allowed! Please try again o(一︿一+)o</p>", "menu-4-success": "<p>Modified successfully!</p>", "menu-5": "{server_list}\n<p>Please enter the serial number:</p>", "menu-5-success": "<p>Set successfully!</p>", "menu-5-error-duplicate": "<p>The selected server is the same as the old default server!</p>" } }, server: { description: "Manage servers", messages: { "no-channel": "<p>Please use this feature in group chats~</p>", "invalid-select": "<p>No such option!</p>", "no-auth": "<p>Only group admins can use this feature~</p>", "admin-menu-select": "<p>[Group server management]</p>\n{server_list}\n<p>0. Add new server</p>\n<p>Please enter the serial number:</p>", "menu-select": "<p>[Server management]</p>\n{server_list}\n<p>0. Add new server</p>\n<p>Please enter the serial number:</p>", menu: "<p>[{name}]</p>\n<p>Type: {type}</p>\n<p>1. Set as default server</p>\n<p>2. View or modify url</p>\n<p>3. Delete the server</p>\n<p>4. Rename the server</p>\n<p>0. Return to server selection</p>\n<p>Please enter the serial number:</p>", "menu-1-success": "<p>Set successfully!</p>", "menu-1-error-duplicate": "<p>The selected server is the same as the old default server!</p>", "menu-2-prompt": "<p>The server's url: {baseUrl}</p>\n<p>Please enter the new server url:</p>\n<p>Enter 0 to return</p>", "menu-2-success": "<p>Modified successfully!</p>", "menu-2-invalid-url": "<p>Invalid URL format! Please enter a valid url address.</p>", "menu-2-too-many-attempts": "<p>Too many attempts. Operation cancelled.</p>", "menu-3-success": "<p>Deleted successfully!</p>", "menu-4-prompt": "<p>Enter a new name, no spaces allowed:</p>", "menu-4-error-invalid-name": "<p>No spaces allowed! Please try again o(一︿一+)o</p>", "menu-4-success": "<p>Modified successfully!</p>", "add-type": "<p>Please select the server type:</p>\n{server_type_list}", "add-url": "<p>Please enter the server url:</p>", "add-invalid-url": "<p>Invalid URL format! Please enter a valid url address.</p>", "add-too-many-attempts": "<p>Too many attempts. Operation cancelled.</p>", "add-name": "<p>Received! Please give the server a name, no spaces allowed:</p>", "add-invalid-name": "<p>No spaces allowed! Please try again o(一︿一+)o</p>", "add-success": "<p>Added successfully, the server information is as follows:</p>\n<p>[{serverName}]</p>\n<p>Type: {serverType}</p>" } } } };
|
|
2656
|
+
<p>Once linked, you can use "link -r" to unlink at any time.</p>`, "generated-2": "<p>Token verified! Now proceeding to the second step.</p>\n<p>Please send the following text to the bot on the target platform within 5 minutes:</p>\n<p>{0}</p>\n<p>Note: The current platform is your original platform. User data here will overwrite the target platform's data.</p>", "self-1": "<p>Please enter this on the original platform.</p>", "self-2": "<p>Please enter this on the target platform.</p>", success: "<p>Account linked successfully!</p>", "remove-success": "<p>Account unlinked successfully!</p>", "remove-original": "<p>Cannot unlink: this is your original account.</p>" } }, bind: { description: "Bind card", messages: { prompt: "<p>Please enter your card number:</p>", "convert-access-failed": "<p>Failed to convert Access Code, please use 16-digit card code instead.</p>", "invalid-code": "<p>The card number is incorrect, if you don't remember it, go to the arcade to check it~</p>", name: "<p>Received! Please give this card a name, no spaces allowed:</p>", "invalid-name": "<p>No spaces allowed! Please try again o(一︿一+)o</p>", success: "<p>Bound successfully, your card information is as follows:</p>\n<p>[{cardName}]</p>\n<p>{cardCode}</p>" } }, card: { description: "Manage cards", options: { detail: "Show detailed card information" }, messages: { "invalid-code": "<p>The card number is incorrect, if you don't remember it, go to the arcade to check it~</p>", "invalid-select": "<p>No such option!</p>", "lookup-error": "Lookup failed: {message}", "lookup-error-unknown": "Lookup failed: unknown error", "menu-select": "<p>[Card Management]</p>\n{card_list}\n<p>0. Add new card</p>\n<p>Please enter the serial number:</p>", menu: "<p>[{name}]</p>\n<p>1. Set as default card</p>\n<p>2. View or modify card number</p>\n<p>3. Delete the card</p>\n<p>4. Rename the card</p>\n<p>5. Bind the card to a specified server</p>\n<p>0. Return to card selection</p>\n<p>Please enter the serial number:</p>", "menu-has-bound-server": "<p>[{name}]</p>\n<p>Bound server: {defaultServerName}</p>\n<p>1. Set as default card</p>\n<p>2. View or modify card number</p>\n<p>3. Delete the card</p>\n<p>4. Rename the card</p>\n<p>5. Bind the card to a specified server</p>\n<p>0. Return to card selection</p>\n<p>Please enter the serial number:</p>", "menu-1-success": "<p>Set successfully!</p>", "menu-1-error-duplicate": "<p>The selected card is the same as the old default card!</p>", "menu-2-prompt": "<p>Card number: {code}</p>\n<p>Please enter the new card number:</p>\n<p>Enter 0 to return</p>", "menu-2-success": "<p>Modified successfully!</p>", "menu-2-error-invalid-code": "<p>The card number is incorrect, if you don't remember it, go to the arcade to check it~</p>", "menu-3-success": "<p>Deleted successfully!</p>", "menu-4-prompt": "<p>Enter a new name, no spaces allowed:</p>", "menu-4-error-invalid-name": "<p>No spaces allowed! Please try again o(一︿一+)o</p>", "menu-4-success": "<p>Modified successfully!</p>", "menu-5": "{server_list}\n<p>Please enter the serial number:</p>", "menu-5-success": "<p>Set successfully!</p>", "menu-5-error-duplicate": "<p>The selected server is the same as the old default server!</p>" } }, server: { description: "Manage servers", messages: { "no-channel": "<p>Please use this feature in group chats~</p>", "invalid-select": "<p>No such option!</p>", "no-auth": "<p>Only group admins can use this feature~</p>", "admin-menu-select": "<p>[Group server management]</p>\n{server_list}\n<p>0. Add new server</p>\n<p>Please enter the serial number:</p>", "menu-select": "<p>[Server management]</p>\n{server_list}\n<p>0. Add new server</p>\n<p>Please enter the serial number:</p>", menu: "<p>[{name}]</p>\n<p>Type: {type}</p>\n<p>1. Set as default server</p>\n<p>2. View or modify url</p>\n<p>3. Delete the server</p>\n<p>4. Rename the server</p>\n<p>0. Return to server selection</p>\n<p>Please enter the serial number:</p>", "menu-1-success": "<p>Set successfully!</p>", "menu-1-error-duplicate": "<p>The selected server is the same as the old default server!</p>", "menu-2-prompt": "<p>The server's url: {baseUrl}</p>\n<p>Please enter the new server url:</p>\n<p>Enter 0 to return</p>", "menu-2-success": "<p>Modified successfully!</p>", "menu-2-invalid-url": "<p>Invalid URL format! Please enter a valid url address.</p>", "menu-2-too-many-attempts": "<p>Too many attempts. Operation cancelled.</p>", "menu-3-success": "<p>Deleted successfully!</p>", "menu-4-prompt": "<p>Enter a new name, no spaces allowed:</p>", "menu-4-error-invalid-name": "<p>No spaces allowed! Please try again o(一︿一+)o</p>", "menu-4-success": "<p>Modified successfully!</p>", "add-type": "<p>Please select the server type:</p>\n{server_type_list}", "add-url": "<p>Please enter the server url:</p>", "add-invalid-url": "<p>Invalid URL format! Please enter a valid url address.</p>", "add-too-many-attempts": "<p>Too many attempts. Operation cancelled.</p>", "add-name": "<p>Received! Please give the server a name, no spaces allowed:</p>", "add-invalid-name": "<p>No spaces allowed! Please try again o(一︿一+)o</p>", "add-success": "<p>Added successfully, the server information is as follows:</p>\n<p>[{serverName}]</p>\n<p>Type: {serverType}</p>" } }, settings: { description: "Get settings panel link", messages: { success: "<p>Open the settings panel via the link below:</p>\n<p>{url}</p>\n<p>This link expires in {minutes} minutes. Do not share it.</p>" } } } };
|
|
2275
2657
|
|
|
2276
2658
|
// src/core/locales/zh-CN.yml
|
|
2277
|
-
var zh_CN_default2 = { _config: { $desc: "Core 模块设置", adminUsers: "**插件管理员** 的用户id (使用 inspect 指令获取)", guildNameCards: "**群聊卡片** 的名称列表", maoServerUrl: "**猫网服务器** 的 URL 地址", official_support_url: "**官方支持** 的 URL 地址" }, commands: { maintain: { description: "切换到维护模式", messages: { "no-auth": "<p>你没有权限使用本功能哦~</p>", start: "<p>正在进入维护模式</p>", "success-start": "<p>成功切换到维护模式</p>", stop: "<p>正在退出维护模式</p>", "success-stop": "<p>成功退出维护模式</p>" } }, timeout: "Noah 没等到你的回复,请重试!", help: { description: "显示 Noah 帮助信息", messages: { content: "<p>使用文档:</p>\n<p>https://docs.logthm.cn/noah</p>", "qq-extra": "<p>遇到问题了?加群 723977027 反馈~</p>" } }, locale: { description: "设置语言", messages: { "no-auth": "<p>只有群管理员能使用本功能哦~</p>", "invalid-select": "<p>没有该选项!</p>", quit: "<p>已退出~</p>", "reset-channel": "<p>重置成功!</p>", "reset-user": "<p>重置成功!</p>", success: "<p>设置成功!</p>", "set-channel": "<p>选择群聊默认使用的语言:</p>\n<p>1. 简体中文</p>\n<p>2. English</p>\n<p>q. 退出</p>", "set-user": "<p>选择你使用的语言:</p>\n<p>1. 简体中文</p>\n<p>2. English</p>\n<p>q. 退出</p>" } }, link: { description: "关联账号到其他平台", options: { remove: "解除关联" }, messages: { "generated-1": "<p>Link 指令可用于在多个平台间关联用户数据。关联过程中,原始平台的用户数据将完全保留,而目标平台的用户数据将被原始平台的数据所覆盖。</p>\n<p>请确认当前平台是你的目标平台,并在 5 分钟内使用你的账号在原始平台内向机器人发送以下文本:</p>\n<p>{0}</p>\n<p>关联完成后,你可以随时使用「link -r」来解除关联。</p>", "generated-2": "<p>令牌核验成功!下面将进行第二步操作。</p>\n<p>请在 5 分钟内使用你的账号在目标平台内向机器人发送以下文本:</p>\n<p>{0}</p>\n<p>注意:当前平台是你的原始平台,这里的用户数据将覆盖目标平台的数据。</p>", "self-1": "<p>请前往原始平台输入。</p>", "self-2": "<p>请前往目标平台输入。</p>", success: "<p>账号关联成功!</p>", "remove-success": "<p>账号解除关联成功!</p>", "remove-original": "<p>无法解除关联:这是你的原始账号。</p>" } }, bind: { description: "绑定卡片", messages: { prompt: "<p>请输入你的卡号:</p>", "convert-access-failed": "<p>转换 Access Code 失败,请使用 16 位卡号进行绑定。</p>", "invalid-code": "<p>卡号不对哟,不记得的话去机台刷一下吧~</p>", name: "<p>收到!为这张卡取一个名字吧,不要带空格哦:</p>", "invalid-name": "<p>名字不要带空格!重来重来 o(一︿一+)o</p>", success: "<p>绑好啦,你的卡片信息如下:</p>\n<p>[{cardName}]</p>\n<p>{cardCode}</p>" } }, card: { description: "管理卡片", options: { detail: "显示卡片详细信息" }, messages: { "invalid-code": "<p>卡号不对哟,不记得的话去机台刷一下吧~</p>", "invalid-select": "<p>没有该选项!</p>", quit: "<p>已退出~</p>", "lookup-error": "查询失败: {message}", "lookup-error-unknown": "查询失败: 未知错误", "menu-select": "<p>[卡片管理]</p>\n{card_list}\n<p>0. 添加新卡片</p>\n<p>q. 退出菜单</p>\n<p>请输入序号:</p>", menu: "<p>[{name}]</p>\n<p>1. 设为默认卡片</p>\n<p>2. 查看或修改卡号</p>\n<p>3. 删除该卡</p>\n<p>4. 重命名该卡片</p>\n<p>5. 将卡片与指定服务器绑定</p>\n<p>0. 返回卡片选择</p>\n<p>q. 退出菜单</p>\n<p>请输入序号:</p>", "menu-has-bound-server": "<p>[{name}]</p>\n<p>已绑定服务器:{defaultServerName}</p>\n<p>1. 设为默认卡片</p>\n<p>2. 查看或修改卡号</p>\n<p>3. 删除该卡</p>\n<p>4. 重命名该卡片</p>\n<p>5. 将卡片与指定服务器绑定</p>\n<p>0. 返回卡片选择</p>\n<p>q. 退出菜单</p>\n<p>请输入序号:</p>", "menu-1-success": "<p>设置成功!</p>", "menu-1-error-duplicate": "<p>选择的卡片与旧的默认卡片相同!</p>", "menu-2-prompt": "<p>卡号:{code}</p>\n<p>请输入新的卡号:</p>\n<p>0. 返回</p>\n<p>q. 退出</p>", "menu-2-success": "<p>修改成功!</p>", "menu-2-error-invalid-code": "<p>卡号不对哟,不记得的话去机台刷一下吧~</p>", "menu-3-success": "<p>已删除!</p>", "menu-4-prompt": "<p>输入一个新名字,不要带空格哦:</p>\n<p>q. 退出</p>", "menu-4-error-invalid-name": "<p>名字不要带空格!重来重来 o(一︿一+)o</p>", "menu-4-success": "<p>修改成功!</p>", "menu-5": "<p>请选择一个服务器:</p>\n{server_list}\n<p>q. 退出</p>", "menu-5-success": "<p>设置成功!</p>", "menu-5-error-duplicate": "<p>选择的服务器与旧的默认服务器相同!</p>" } }, server: { description: "管理服务器", messages: { "no-channel": "<p>请在群聊中使用本功能哦~</p>", "invalid-select": "<p>没有该选项!</p>", "no-auth": "<p>只有群管理员能使用本功能哦~</p>", quit: "<p>已退出~</p>", "admin-menu-select": "<p>[群聊服务器管理]</p>\n{server_list}\n<p>0. 添加新服务器</p>\n<p>q. 退出菜单</p>\n<p>请输入序号:</p>", "menu-select": "<p>[服务器管理]</p>\n{server_list}\n<p>0. 添加新服务器</p>\n<p>q. 退出菜单</p>\n<p>请输入序号:</p>", menu: "<p>[{name}]</p>\n<p>类型:{type}</p>\n<p>1. 设为默认服务器</p>\n<p>2. 查看或修改 url</p>\n<p>3. 删除该服务器</p>\n<p>4. 重命名该服务器</p>\n<p>0. 返回服务器选择</p>\n<p>q. 退出菜单</p>\n<p>请输入序号:</p>", "menu-1-success": "<p>设置成功!</p>", "menu-1-error-duplicate": "<p>选择的服务器与旧的默认服务器相同!</p>", "menu-2-prompt": "<p>该服务器的 url:{baseUrl}</p>\n<p>请输入新的服务器 url:</p>\n<p>0. 返回</p>\n<p>q. 退出</p>", "menu-2-success": "<p>修改成功!</p>", "menu-2-invalid-url": "<p>URL 格式不正确!请输入有效的 url 地址。</p>", "menu-2-too-many-attempts": "<p>尝试次数过多,操作已取消。</p>", "menu-3-success": "<p>已删除!</p>", "menu-4-prompt": "<p>输入一个新名字,不要带空格哦:</p>\n<p>0. 返回</p>\n<p>q. 退出</p>", "menu-4-error-invalid-name": "<p>名字不要带空格!重来重来 o(一︿一+)o</p>", "menu-4-success": "<p>修改成功!</p>", "add-type": "<p>请选择服务器的类型:</p>\n{server_type_list}\n<p>q. 退出</p>", "add-url": "<p>请输入服务器的 url:</p>\n<p>q. 退出</p>", "add-invalid-url": "<p>URL 格式不正确!请输入有效的 url 地址。</p>", "add-too-many-attempts": "<p>尝试次数过多,操作已取消。</p>", "add-name": "<p>收到!为服务器取一个名字吧,不要带空格哦:</p>\n<p>q. 退出</p>", "add-invalid-name": "<p>名字不要带空格!重来重来 o(一︿一+)o</p>", "add-success": "<p>添加成功啦,服务器信息如下:</p>\n<p>[{serverName}]</p>\n<p>类型:{serverType}</p>" } } } };
|
|
2659
|
+
var zh_CN_default2 = { _config: { $desc: "Core 模块设置", adminUsers: "**插件管理员** 的用户id (使用 inspect 指令获取)", guildNameCards: "**群聊卡片** 的名称列表", tokenTtl: "**设置面板** 链接有效期(秒)", frontendUrl: "**设置面板** 前端地址(配置后 /settings 会生成完整链接)", corsOrigin: "**设置面板** CORS 允许来源(生产环境请设为前端域名)", maoServerUrl: "**猫网服务器** 的 URL 地址", official_support_url: "**官方支持** 的 URL 地址" }, selector: { "card-not-found": "<p>你还没绑卡,去绑个卡再来吧~</p>", "server-not-found": "<p>没有可用的服务器哦,自己添加一个吧~</p>", "menu-select": "<p>请选择你要使用的卡片:</p>\n{card_list}\n<p>q. 退出</p>", "server-menu-select": "<p>请选择你要使用的服务器:</p>\n{server_list}\n<p>q. 退出</p>", "invalid-select": "<p>没有该选项!</p>", quit: "<p>已退出~</p>", "default-card": "默认卡片", "default-server": "默认服务器" }, commands: { maintain: { description: "切换到维护模式", messages: { "no-auth": "<p>你没有权限使用本功能哦~</p>", start: "<p>正在进入维护模式</p>", "success-start": "<p>成功切换到维护模式</p>", stop: "<p>正在退出维护模式</p>", "success-stop": "<p>成功退出维护模式</p>" } }, timeout: "Noah 没等到你的回复,请重试!", help: { description: "显示 Noah 帮助信息", messages: { content: "<p>使用文档:</p>\n<p>https://docs.logthm.cn/noah</p>", "qq-extra": "<p>遇到问题了?加群 723977027 反馈~</p>" } }, locale: { description: "设置语言", messages: { "no-auth": "<p>只有群管理员能使用本功能哦~</p>", "invalid-select": "<p>没有该选项!</p>", quit: "<p>已退出~</p>", "reset-channel": "<p>重置成功!</p>", "reset-user": "<p>重置成功!</p>", success: "<p>设置成功!</p>", "set-channel": "<p>选择群聊默认使用的语言:</p>\n<p>1. 简体中文</p>\n<p>2. English</p>\n<p>q. 退出</p>", "set-user": "<p>选择你使用的语言:</p>\n<p>1. 简体中文</p>\n<p>2. English</p>\n<p>q. 退出</p>" } }, link: { description: "关联账号到其他平台", options: { remove: "解除关联" }, messages: { "generated-1": "<p>Link 指令可用于在多个平台间关联用户数据。关联过程中,原始平台的用户数据将完全保留,而目标平台的用户数据将被原始平台的数据所覆盖。</p>\n<p>请确认当前平台是你的目标平台,并在 5 分钟内使用你的账号在原始平台内向机器人发送以下文本:</p>\n<p>{0}</p>\n<p>关联完成后,你可以随时使用「link -r」来解除关联。</p>", "generated-2": "<p>令牌核验成功!下面将进行第二步操作。</p>\n<p>请在 5 分钟内使用你的账号在目标平台内向机器人发送以下文本:</p>\n<p>{0}</p>\n<p>注意:当前平台是你的原始平台,这里的用户数据将覆盖目标平台的数据。</p>", "self-1": "<p>请前往原始平台输入。</p>", "self-2": "<p>请前往目标平台输入。</p>", success: "<p>账号关联成功!</p>", "remove-success": "<p>账号解除关联成功!</p>", "remove-original": "<p>无法解除关联:这是你的原始账号。</p>" } }, bind: { description: "绑定卡片", messages: { prompt: "<p>请输入你的卡号:</p>", "convert-access-failed": "<p>转换 Access Code 失败,请使用 16 位卡号进行绑定。</p>", "invalid-code": "<p>卡号不对哟,不记得的话去机台刷一下吧~</p>", name: "<p>收到!为这张卡取一个名字吧,不要带空格哦:</p>", "invalid-name": "<p>名字不要带空格!重来重来 o(一︿一+)o</p>", success: "<p>绑好啦,你的卡片信息如下:</p>\n<p>[{cardName}]</p>\n<p>{cardCode}</p>" } }, card: { description: "管理卡片", options: { detail: "显示卡片详细信息" }, messages: { "invalid-code": "<p>卡号不对哟,不记得的话去机台刷一下吧~</p>", "invalid-select": "<p>没有该选项!</p>", quit: "<p>已退出~</p>", "lookup-error": "查询失败: {message}", "lookup-error-unknown": "查询失败: 未知错误", "menu-select": "<p>[卡片管理]</p>\n{card_list}\n<p>0. 添加新卡片</p>\n<p>q. 退出菜单</p>\n<p>请输入序号:</p>", menu: "<p>[{name}]</p>\n<p>1. 设为默认卡片</p>\n<p>2. 查看或修改卡号</p>\n<p>3. 删除该卡</p>\n<p>4. 重命名该卡片</p>\n<p>5. 将卡片与指定服务器绑定</p>\n<p>0. 返回卡片选择</p>\n<p>q. 退出菜单</p>\n<p>请输入序号:</p>", "menu-has-bound-server": "<p>[{name}]</p>\n<p>已绑定服务器:{defaultServerName}</p>\n<p>1. 设为默认卡片</p>\n<p>2. 查看或修改卡号</p>\n<p>3. 删除该卡</p>\n<p>4. 重命名该卡片</p>\n<p>5. 将卡片与指定服务器绑定</p>\n<p>0. 返回卡片选择</p>\n<p>q. 退出菜单</p>\n<p>请输入序号:</p>", "menu-1-success": "<p>设置成功!</p>", "menu-1-error-duplicate": "<p>选择的卡片与旧的默认卡片相同!</p>", "menu-2-prompt": "<p>卡号:{code}</p>\n<p>请输入新的卡号:</p>\n<p>0. 返回</p>\n<p>q. 退出</p>", "menu-2-success": "<p>修改成功!</p>", "menu-2-error-invalid-code": "<p>卡号不对哟,不记得的话去机台刷一下吧~</p>", "menu-3-success": "<p>已删除!</p>", "menu-4-prompt": "<p>输入一个新名字,不要带空格哦:</p>\n<p>q. 退出</p>", "menu-4-error-invalid-name": "<p>名字不要带空格!重来重来 o(一︿一+)o</p>", "menu-4-success": "<p>修改成功!</p>", "menu-5": "<p>请选择一个服务器:</p>\n{server_list}\n<p>q. 退出</p>", "menu-5-success": "<p>设置成功!</p>", "menu-5-error-duplicate": "<p>选择的服务器与旧的默认服务器相同!</p>" } }, server: { description: "管理服务器", messages: { "no-channel": "<p>请在群聊中使用本功能哦~</p>", "invalid-select": "<p>没有该选项!</p>", "no-auth": "<p>只有群管理员能使用本功能哦~</p>", quit: "<p>已退出~</p>", "admin-menu-select": "<p>[群聊服务器管理]</p>\n{server_list}\n<p>0. 添加新服务器</p>\n<p>q. 退出菜单</p>\n<p>请输入序号:</p>", "menu-select": "<p>[服务器管理]</p>\n{server_list}\n<p>0. 添加新服务器</p>\n<p>q. 退出菜单</p>\n<p>请输入序号:</p>", menu: "<p>[{name}]</p>\n<p>类型:{type}</p>\n<p>1. 设为默认服务器</p>\n<p>2. 查看或修改 url</p>\n<p>3. 删除该服务器</p>\n<p>4. 重命名该服务器</p>\n<p>0. 返回服务器选择</p>\n<p>q. 退出菜单</p>\n<p>请输入序号:</p>", "menu-1-success": "<p>设置成功!</p>", "menu-1-error-duplicate": "<p>选择的服务器与旧的默认服务器相同!</p>", "menu-2-prompt": "<p>该服务器的 url:{baseUrl}</p>\n<p>请输入新的服务器 url:</p>\n<p>0. 返回</p>\n<p>q. 退出</p>", "menu-2-success": "<p>修改成功!</p>", "menu-2-invalid-url": "<p>URL 格式不正确!请输入有效的 url 地址。</p>", "menu-2-too-many-attempts": "<p>尝试次数过多,操作已取消。</p>", "menu-3-success": "<p>已删除!</p>", "menu-4-prompt": "<p>输入一个新名字,不要带空格哦:</p>\n<p>0. 返回</p>\n<p>q. 退出</p>", "menu-4-error-invalid-name": "<p>名字不要带空格!重来重来 o(一︿一+)o</p>", "menu-4-success": "<p>修改成功!</p>", "add-type": "<p>请选择服务器的类型:</p>\n{server_type_list}\n<p>q. 退出</p>", "add-url": "<p>请输入服务器的 url:</p>\n<p>q. 退出</p>", "add-invalid-url": "<p>URL 格式不正确!请输入有效的 url 地址。</p>", "add-too-many-attempts": "<p>尝试次数过多,操作已取消。</p>", "add-name": "<p>收到!为服务器取一个名字吧,不要带空格哦:</p>\n<p>q. 退出</p>", "add-invalid-name": "<p>名字不要带空格!重来重来 o(一︿一+)o</p>", "add-success": "<p>添加成功啦,服务器信息如下:</p>\n<p>[{serverName}]</p>\n<p>类型:{serverType}</p>" } }, settings: { description: "获取设置面板链接", messages: { success: "<p>点击下方链接打开设置面板:</p>\n<p>{url}</p>\n<p>链接有效期 {minutes} 分钟,请勿分享给他人。</p>" } } } };
|
|
2278
2660
|
|
|
2279
2661
|
// src/core/index.ts
|
|
2280
2662
|
var name5 = "Noah-Core";
|
|
2281
|
-
var inject = ["database", "globalConfig"];
|
|
2663
|
+
var inject = ["database", "globalConfig", "server"];
|
|
2282
2664
|
var logger2 = new import_koishi6.Logger("Noah-Core");
|
|
2283
2665
|
function apply5(ctx, config) {
|
|
2284
2666
|
;
|
|
@@ -2286,9 +2668,11 @@ function apply5(ctx, config) {
|
|
|
2286
2668
|
["en-US", en_US_default2],
|
|
2287
2669
|
["zh-CN", zh_CN_default2]
|
|
2288
2670
|
].forEach(([lang, file]) => ctx.i18n.define(lang, file));
|
|
2671
|
+
const apiCtx = resolveApiContext(config.core);
|
|
2289
2672
|
ctx.plugin(database_exports, config.core);
|
|
2290
|
-
ctx.plugin(command_exports, config.core);
|
|
2673
|
+
ctx.plugin(command_exports, { ...config.core, _apiCtx: apiCtx });
|
|
2291
2674
|
ctx.plugin(event_exports, config.core);
|
|
2675
|
+
registerApiRoutes(ctx, apiCtx);
|
|
2292
2676
|
}
|
|
2293
2677
|
__name(apply5, "apply");
|
|
2294
2678
|
|
|
@@ -3037,20 +3421,20 @@ var SDVXDrawer = class extends BaseDrawer {
|
|
|
3037
3421
|
ctx.save();
|
|
3038
3422
|
ctx.translate(556, 17);
|
|
3039
3423
|
ctx.beginPath();
|
|
3040
|
-
const r = 16, w = 100,
|
|
3424
|
+
const r = 16, w = 100, h11 = 200, x0 = 0, y0 = 0;
|
|
3041
3425
|
ctx.moveTo(x0 + r, y0);
|
|
3042
3426
|
ctx.lineTo(x0 + w - r, y0);
|
|
3043
3427
|
ctx.arcTo(x0 + w, y0, x0 + w, y0 + r, r);
|
|
3044
|
-
ctx.lineTo(x0 + w, y0 +
|
|
3045
|
-
ctx.arcTo(x0 + w, y0 +
|
|
3046
|
-
ctx.lineTo(x0 + r, y0 +
|
|
3047
|
-
ctx.arcTo(x0, y0 +
|
|
3428
|
+
ctx.lineTo(x0 + w, y0 + h11 - r);
|
|
3429
|
+
ctx.arcTo(x0 + w, y0 + h11, x0 + w - r, y0 + h11, r);
|
|
3430
|
+
ctx.lineTo(x0 + r, y0 + h11);
|
|
3431
|
+
ctx.arcTo(x0, y0 + h11, x0, y0 + h11 - r, r);
|
|
3048
3432
|
ctx.lineTo(x0, y0 + r);
|
|
3049
3433
|
ctx.arcTo(x0, y0, x0 + r, y0, r);
|
|
3050
3434
|
ctx.closePath();
|
|
3051
3435
|
const circleRadius = 14;
|
|
3052
3436
|
const circleX = x0 + w;
|
|
3053
|
-
const circleY = y0 +
|
|
3437
|
+
const circleY = y0 + h11 / 2;
|
|
3054
3438
|
ctx.moveTo(circleX + circleRadius, circleY);
|
|
3055
3439
|
ctx.arc(circleX, circleY, circleRadius, 0, Math.PI * 2, true);
|
|
3056
3440
|
ctx.clip();
|
|
@@ -4168,7 +4552,7 @@ __export(sdvx_exports, {
|
|
|
4168
4552
|
logger: () => logger4,
|
|
4169
4553
|
name: () => name13
|
|
4170
4554
|
});
|
|
4171
|
-
var
|
|
4555
|
+
var import_koishi19 = require("koishi");
|
|
4172
4556
|
|
|
4173
4557
|
// src/servers/index.ts
|
|
4174
4558
|
var servers_exports = {};
|
|
@@ -5982,6 +6366,66 @@ function chart(ctx, config, logger5) {
|
|
|
5982
6366
|
}
|
|
5983
6367
|
__name(chart, "chart");
|
|
5984
6368
|
|
|
6369
|
+
// src/core/utils/selector.ts
|
|
6370
|
+
var import_koishi16 = require("koishi");
|
|
6371
|
+
async function selectCard(session, cardService, uid) {
|
|
6372
|
+
const userCards = await cardService.getCardsByUid(uid);
|
|
6373
|
+
if (userCards.length === 0) {
|
|
6374
|
+
return { ok: false, message: session.text("selector.card-not-found") };
|
|
6375
|
+
}
|
|
6376
|
+
const defaultCard = await cardService.getDefaultCardByUid(uid);
|
|
6377
|
+
const defaultLabel = session.text("selector.default-card");
|
|
6378
|
+
let cardListMsg = "";
|
|
6379
|
+
for (let i = 0; i < userCards.length; i++) {
|
|
6380
|
+
if (defaultCard && userCards[i].id === defaultCard.id) {
|
|
6381
|
+
cardListMsg += `<p>${i + 1}. ${userCards[i].name} < ${defaultLabel}</p>`;
|
|
6382
|
+
} else {
|
|
6383
|
+
cardListMsg += `<p>${i + 1}. ${userCards[i].name}</p>`;
|
|
6384
|
+
}
|
|
6385
|
+
}
|
|
6386
|
+
const msg = import_koishi16.h.unescape(session.text("selector.menu-select", { card_list: cardListMsg }));
|
|
6387
|
+
await session.send(msg);
|
|
6388
|
+
const select = await session.prompt();
|
|
6389
|
+
if (!select) return { ok: false, message: session.text("commands.timeout") };
|
|
6390
|
+
if (select === "q") return { ok: false, message: session.text("selector.quit") };
|
|
6391
|
+
const selectNum = parseInt(select, 10);
|
|
6392
|
+
if (isNaN(selectNum) || selectNum < 1 || selectNum > userCards.length) {
|
|
6393
|
+
return { ok: false, message: session.text("selector.invalid-select") };
|
|
6394
|
+
}
|
|
6395
|
+
const card2 = await cardService.getCardByCode(userCards[selectNum - 1].code);
|
|
6396
|
+
return { ok: true, value: card2 };
|
|
6397
|
+
}
|
|
6398
|
+
__name(selectCard, "selectCard");
|
|
6399
|
+
async function selectServer(session, serverService, uid, channelId) {
|
|
6400
|
+
const servers = await serverService.getSelectableServers(uid, channelId);
|
|
6401
|
+
if (servers.length === 0) {
|
|
6402
|
+
return { ok: false, message: session.text("selector.server-not-found") };
|
|
6403
|
+
}
|
|
6404
|
+
const defaultServer = await serverService.getDefaultServerByUid(uid);
|
|
6405
|
+
const defaultLabel = session.text("selector.default-server");
|
|
6406
|
+
let serverListMsg = "";
|
|
6407
|
+
for (let i = 0; i < servers.length; i++) {
|
|
6408
|
+
if (defaultServer && servers[i].id === defaultServer.id) {
|
|
6409
|
+
serverListMsg += `<p>${i + 1}. ${servers[i].name} (${servers[i].type}) < ${defaultLabel}</p>`;
|
|
6410
|
+
} else {
|
|
6411
|
+
serverListMsg += `<p>${i + 1}. ${servers[i].name} (${servers[i].type})</p>`;
|
|
6412
|
+
}
|
|
6413
|
+
}
|
|
6414
|
+
const msg = import_koishi16.h.unescape(
|
|
6415
|
+
session.text("selector.server-menu-select", { server_list: serverListMsg })
|
|
6416
|
+
);
|
|
6417
|
+
await session.send(msg);
|
|
6418
|
+
const select = await session.prompt();
|
|
6419
|
+
if (!select) return { ok: false, message: session.text("commands.timeout") };
|
|
6420
|
+
if (select === "q") return { ok: false, message: session.text("selector.quit") };
|
|
6421
|
+
const selectNum = parseInt(select, 10);
|
|
6422
|
+
if (isNaN(selectNum) || selectNum < 1 || selectNum > servers.length) {
|
|
6423
|
+
return { ok: false, message: session.text("selector.invalid-select") };
|
|
6424
|
+
}
|
|
6425
|
+
return { ok: true, value: servers[selectNum - 1] };
|
|
6426
|
+
}
|
|
6427
|
+
__name(selectServer, "selectServer");
|
|
6428
|
+
|
|
5985
6429
|
// src/games/sdvx/services/score-service.ts
|
|
5986
6430
|
var ScoreService = class _ScoreService {
|
|
5987
6431
|
static {
|
|
@@ -6105,29 +6549,46 @@ var ScoreService = class _ScoreService {
|
|
|
6105
6549
|
|
|
6106
6550
|
// src/games/sdvx/commands/radar.ts
|
|
6107
6551
|
function radar(ctx, config, logger5) {
|
|
6108
|
-
ctx.command("sdvx.radar").userFields(["defaultCardId", "defaultServerId", "id"]).channelFields(["defaultServerId", "id"]).action(async ({ session }) => {
|
|
6552
|
+
ctx.command("sdvx.radar").userFields(["defaultCardId", "defaultServerId", "id"]).channelFields(["defaultServerId", "id"]).option("card", "-c").option("server", "-s").action(async ({ session, options }) => {
|
|
6109
6553
|
const atGuild = session.guildId != null;
|
|
6110
6554
|
const cardService = new CardService(ctx);
|
|
6111
6555
|
const serverService = new ServerService(ctx);
|
|
6556
|
+
const channelId = atGuild ? session.channel.id : null;
|
|
6112
6557
|
const userCards = await cardService.getCardsByUid(session.user.id);
|
|
6113
6558
|
if (userCards.length === 0) return session.text(".card-not-found");
|
|
6114
|
-
const serverRes = await serverService.getSelectableServers(
|
|
6115
|
-
session.user.id,
|
|
6116
|
-
atGuild ? session.channel.id : null
|
|
6117
|
-
);
|
|
6559
|
+
const serverRes = await serverService.getSelectableServers(session.user.id, channelId);
|
|
6118
6560
|
if (serverRes.length === 0) return session.text(".server-not-found");
|
|
6119
|
-
|
|
6120
|
-
if (
|
|
6121
|
-
|
|
6122
|
-
|
|
6123
|
-
card2
|
|
6124
|
-
|
|
6125
|
-
|
|
6126
|
-
session.
|
|
6127
|
-
|
|
6128
|
-
|
|
6129
|
-
|
|
6130
|
-
if (
|
|
6561
|
+
let card2;
|
|
6562
|
+
if (options.card) {
|
|
6563
|
+
const result = await selectCard(session, cardService, session.user.id);
|
|
6564
|
+
if (result.ok === false) return result.message;
|
|
6565
|
+
card2 = result.value;
|
|
6566
|
+
} else {
|
|
6567
|
+
const defaultCard = await cardService.getDefaultCardByUid(session.user.id);
|
|
6568
|
+
if (!defaultCard) return session.text(".card-not-found");
|
|
6569
|
+
card2 = await cardService.getCardByCode(defaultCard.code);
|
|
6570
|
+
}
|
|
6571
|
+
let server2;
|
|
6572
|
+
if (options.server) {
|
|
6573
|
+
const result = await selectServer(
|
|
6574
|
+
session,
|
|
6575
|
+
serverService,
|
|
6576
|
+
session.user.id,
|
|
6577
|
+
channelId
|
|
6578
|
+
);
|
|
6579
|
+
if (result.ok === false) return result.message;
|
|
6580
|
+
server2 = result.value;
|
|
6581
|
+
} else {
|
|
6582
|
+
server2 = await resolveServerForCard(
|
|
6583
|
+
card2,
|
|
6584
|
+
cardService,
|
|
6585
|
+
serverService,
|
|
6586
|
+
session.user.id,
|
|
6587
|
+
session.platform,
|
|
6588
|
+
channelId
|
|
6589
|
+
);
|
|
6590
|
+
if (!server2) return session.text(".server-not-found");
|
|
6591
|
+
}
|
|
6131
6592
|
const serverManager = ServerManager.getInstance();
|
|
6132
6593
|
const sdvxService = serverManager.getGameService(server2.type, "sdvx");
|
|
6133
6594
|
const scoreService = ScoreService.getInstance();
|
|
@@ -6161,56 +6622,49 @@ function radar(ctx, config, logger5) {
|
|
|
6161
6622
|
__name(radar, "radar");
|
|
6162
6623
|
|
|
6163
6624
|
// src/games/sdvx/commands/recent.ts
|
|
6164
|
-
var
|
|
6625
|
+
var import_koishi17 = require("koishi");
|
|
6165
6626
|
function recent(ctx, config, logger5) {
|
|
6166
|
-
ctx.command("sdvx.recent [count:number]").alias("sdvx.r").userFields(["defaultCardId", "defaultServerId", "id"]).channelFields(["defaultServerId", "id"]).option("lossless", "-l").option("card", "-c").action(async ({ session, options }, count) => {
|
|
6627
|
+
ctx.command("sdvx.recent [count:number]").alias("sdvx.r").userFields(["defaultCardId", "defaultServerId", "id"]).channelFields(["defaultServerId", "id"]).option("lossless", "-l").option("card", "-c").option("server", "-s").action(async ({ session, options }, count) => {
|
|
6167
6628
|
const atGuild = session.guildId != null;
|
|
6168
6629
|
if (!count) count = 1;
|
|
6169
6630
|
const cardService = new CardService(ctx);
|
|
6170
6631
|
const serverService = new ServerService(ctx);
|
|
6632
|
+
const channelId = atGuild ? session.channel.id : null;
|
|
6171
6633
|
const userCards = await cardService.getCardsByUid(session.user.id);
|
|
6172
6634
|
if (userCards.length === 0) return session.text(".card-not-found");
|
|
6173
|
-
const serverRes = await serverService.getSelectableServers(
|
|
6174
|
-
session.user.id,
|
|
6175
|
-
atGuild ? session.channel.id : null
|
|
6176
|
-
);
|
|
6635
|
+
const serverRes = await serverService.getSelectableServers(session.user.id, channelId);
|
|
6177
6636
|
if (serverRes.length === 0) return session.text(".server-not-found");
|
|
6178
|
-
let
|
|
6179
|
-
if (
|
|
6637
|
+
let card2;
|
|
6638
|
+
if (options.card) {
|
|
6639
|
+
const result = await selectCard(session, cardService, session.user.id);
|
|
6640
|
+
if (result.ok === false) return result.message;
|
|
6641
|
+
card2 = result.value;
|
|
6642
|
+
} else {
|
|
6180
6643
|
const defaultCard = await cardService.getDefaultCardByUid(session.user.id);
|
|
6181
6644
|
if (!defaultCard) return session.text(".card-not-found");
|
|
6182
|
-
|
|
6645
|
+
card2 = await cardService.getCardByCode(defaultCard.code);
|
|
6646
|
+
}
|
|
6647
|
+
let server2;
|
|
6648
|
+
if (options.server) {
|
|
6649
|
+
const result = await selectServer(
|
|
6650
|
+
session,
|
|
6651
|
+
serverService,
|
|
6652
|
+
session.user.id,
|
|
6653
|
+
channelId
|
|
6654
|
+
);
|
|
6655
|
+
if (result.ok === false) return result.message;
|
|
6656
|
+
server2 = result.value;
|
|
6183
6657
|
} else {
|
|
6184
|
-
|
|
6185
|
-
|
|
6186
|
-
|
|
6187
|
-
|
|
6188
|
-
|
|
6189
|
-
|
|
6190
|
-
|
|
6191
|
-
|
|
6192
|
-
|
|
6193
|
-
const msg = import_koishi16.h.unescape(session.text(".menu-select", { card_list: cardListMsg })).replace("< 默认卡片", "< 默认卡片");
|
|
6194
|
-
await session.send(msg);
|
|
6195
|
-
const select = await session.prompt();
|
|
6196
|
-
if (!select) return session.text("commands.timeout");
|
|
6197
|
-
if (select === "q") return session.text(".quit");
|
|
6198
|
-
const selectNum = parseInt(select, 10);
|
|
6199
|
-
if (isNaN(selectNum) || selectNum < 1 || selectNum > userCards.length) {
|
|
6200
|
-
return session.text(".invalid-select");
|
|
6201
|
-
}
|
|
6202
|
-
cardCode = userCards[selectNum - 1].code;
|
|
6658
|
+
server2 = await resolveServerForCard(
|
|
6659
|
+
card2,
|
|
6660
|
+
cardService,
|
|
6661
|
+
serverService,
|
|
6662
|
+
session.user.id,
|
|
6663
|
+
session.platform,
|
|
6664
|
+
channelId
|
|
6665
|
+
);
|
|
6666
|
+
if (!server2) return session.text(".server-not-found");
|
|
6203
6667
|
}
|
|
6204
|
-
const card2 = await cardService.getCardByCode(cardCode);
|
|
6205
|
-
const server2 = await resolveServerForCard(
|
|
6206
|
-
card2,
|
|
6207
|
-
cardService,
|
|
6208
|
-
serverService,
|
|
6209
|
-
session.user.id,
|
|
6210
|
-
session.platform,
|
|
6211
|
-
atGuild ? session.channel.id : null
|
|
6212
|
-
);
|
|
6213
|
-
if (!server2) return session.text(".server-not-found");
|
|
6214
6668
|
const serverManager = ServerManager.getInstance();
|
|
6215
6669
|
const sdvxService = serverManager.getGameService(server2.type, "sdvx");
|
|
6216
6670
|
try {
|
|
@@ -6239,9 +6693,9 @@ function recent(ctx, config, logger5) {
|
|
|
6239
6693
|
}
|
|
6240
6694
|
);
|
|
6241
6695
|
if (options.lossless) {
|
|
6242
|
-
return
|
|
6696
|
+
return import_koishi17.h.image(imageBuffer, "image/png");
|
|
6243
6697
|
}
|
|
6244
|
-
return
|
|
6698
|
+
return import_koishi17.h.image(imageBuffer, "image/jpg");
|
|
6245
6699
|
} catch (error) {
|
|
6246
6700
|
logger5.warn(error);
|
|
6247
6701
|
return session.text(".error");
|
|
@@ -6447,7 +6901,7 @@ __name(sync, "sync");
|
|
|
6447
6901
|
|
|
6448
6902
|
// src/games/sdvx/commands/vf.ts
|
|
6449
6903
|
var fs4 = __toESM(require("fs"), 1);
|
|
6450
|
-
var
|
|
6904
|
+
var import_koishi18 = require("koishi");
|
|
6451
6905
|
|
|
6452
6906
|
// src/games/sdvx/utils/filter.ts
|
|
6453
6907
|
function parseFilterQuery(query) {
|
|
@@ -6501,53 +6955,46 @@ __name(parseFilterQuery, "parseFilterQuery");
|
|
|
6501
6955
|
|
|
6502
6956
|
// src/games/sdvx/commands/vf.ts
|
|
6503
6957
|
function vf(ctx, config, logger5) {
|
|
6504
|
-
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 }) => {
|
|
6958
|
+
ctx.command("vf").userFields(["defaultCardId", "defaultServerId", "id"]).channelFields(["defaultServerId", "id"]).option("lossless", "-l").option("card", "-c").option("server", "-s").option("filter", "-f <query:text>").action(async ({ session, options }) => {
|
|
6505
6959
|
const atGuild = session.guildId != null;
|
|
6506
6960
|
const cardService = new CardService(ctx);
|
|
6507
6961
|
const serverService = new ServerService(ctx);
|
|
6962
|
+
const channelId = atGuild ? session.channel.id : null;
|
|
6508
6963
|
const userCards = await cardService.getCardsByUid(session.user.id);
|
|
6509
6964
|
if (userCards.length === 0) return session.text(".card-not-found");
|
|
6510
|
-
const serverRes = await serverService.getSelectableServers(
|
|
6511
|
-
session.user.id,
|
|
6512
|
-
atGuild ? session.channel.id : null
|
|
6513
|
-
);
|
|
6965
|
+
const serverRes = await serverService.getSelectableServers(session.user.id, channelId);
|
|
6514
6966
|
if (serverRes.length === 0) return session.text(".server-not-found");
|
|
6515
|
-
let
|
|
6516
|
-
if (
|
|
6967
|
+
let card2;
|
|
6968
|
+
if (options.card) {
|
|
6969
|
+
const result = await selectCard(session, cardService, session.user.id);
|
|
6970
|
+
if (result.ok === false) return result.message;
|
|
6971
|
+
card2 = result.value;
|
|
6972
|
+
} else {
|
|
6517
6973
|
const defaultCard = await cardService.getDefaultCardByUid(session.user.id);
|
|
6518
6974
|
if (!defaultCard) return session.text(".card-not-found");
|
|
6519
|
-
|
|
6975
|
+
card2 = await cardService.getCardByCode(defaultCard.code);
|
|
6976
|
+
}
|
|
6977
|
+
let server2;
|
|
6978
|
+
if (options.server) {
|
|
6979
|
+
const result = await selectServer(
|
|
6980
|
+
session,
|
|
6981
|
+
serverService,
|
|
6982
|
+
session.user.id,
|
|
6983
|
+
channelId
|
|
6984
|
+
);
|
|
6985
|
+
if (result.ok === false) return result.message;
|
|
6986
|
+
server2 = result.value;
|
|
6520
6987
|
} else {
|
|
6521
|
-
|
|
6522
|
-
|
|
6523
|
-
|
|
6524
|
-
|
|
6525
|
-
|
|
6526
|
-
|
|
6527
|
-
|
|
6528
|
-
|
|
6529
|
-
|
|
6530
|
-
const msg = import_koishi17.h.unescape(session.text(".menu-select", { card_list: cardListMsg })).replace("< 默认卡片", "< 默认卡片");
|
|
6531
|
-
await session.send(msg);
|
|
6532
|
-
const select = await session.prompt();
|
|
6533
|
-
if (!select) return session.text("commands.timeout");
|
|
6534
|
-
if (select === "q") return session.text(".quit");
|
|
6535
|
-
const selectNum = parseInt(select, 10);
|
|
6536
|
-
if (isNaN(selectNum) || selectNum < 1 || selectNum > userCards.length) {
|
|
6537
|
-
return session.text(".invalid-select");
|
|
6538
|
-
}
|
|
6539
|
-
cardCode = userCards[selectNum - 1].code;
|
|
6988
|
+
server2 = await resolveServerForCard(
|
|
6989
|
+
card2,
|
|
6990
|
+
cardService,
|
|
6991
|
+
serverService,
|
|
6992
|
+
session.user.id,
|
|
6993
|
+
session.platform,
|
|
6994
|
+
channelId
|
|
6995
|
+
);
|
|
6996
|
+
if (!server2) return session.text(".server-not-found");
|
|
6540
6997
|
}
|
|
6541
|
-
const card2 = await cardService.getCardByCode(cardCode);
|
|
6542
|
-
const server2 = await resolveServerForCard(
|
|
6543
|
-
card2,
|
|
6544
|
-
cardService,
|
|
6545
|
-
serverService,
|
|
6546
|
-
session.user.id,
|
|
6547
|
-
session.platform,
|
|
6548
|
-
atGuild ? session.channel.id : null
|
|
6549
|
-
);
|
|
6550
|
-
if (!server2) return session.text(".server-not-found");
|
|
6551
6998
|
const serverManager = ServerManager.getInstance();
|
|
6552
6999
|
const sdvxService = serverManager.getGameService(server2.type, "sdvx");
|
|
6553
7000
|
const scoreService = ScoreService.getInstance();
|
|
@@ -6582,9 +7029,9 @@ function vf(ctx, config, logger5) {
|
|
|
6582
7029
|
}
|
|
6583
7030
|
);
|
|
6584
7031
|
if (options.lossless) {
|
|
6585
|
-
session.send(
|
|
7032
|
+
session.send(import_koishi18.h.file(imageBuffer, "image/png"));
|
|
6586
7033
|
} else {
|
|
6587
|
-
session.send(
|
|
7034
|
+
session.send(import_koishi18.h.image(imageBuffer, "image/jpg"));
|
|
6588
7035
|
}
|
|
6589
7036
|
const sortedScores = [...best50ScoreList].sort((a, b) => b.extra.volforce - a.extra.volforce).slice(0, 50);
|
|
6590
7037
|
const total = sortedScores.reduce((sum, score) => sum + score.extra.volforce, 0);
|
|
@@ -6613,11 +7060,11 @@ function vf(ctx, config, logger5) {
|
|
|
6613
7060
|
);
|
|
6614
7061
|
if (fs4.existsSync(audioPath)) {
|
|
6615
7062
|
const audioBuffer = fs4.readFileSync(audioPath);
|
|
6616
|
-
session.send(
|
|
7063
|
+
session.send(import_koishi18.h.audio(audioBuffer, "audio/mpeg"));
|
|
6617
7064
|
}
|
|
6618
7065
|
if (fs4.existsSync(imagePath)) {
|
|
6619
7066
|
const imageBuffer2 = fs4.readFileSync(imagePath);
|
|
6620
|
-
session.send(
|
|
7067
|
+
session.send(import_koishi18.h.image(imageBuffer2, "image/png"));
|
|
6621
7068
|
}
|
|
6622
7069
|
} catch (error) {
|
|
6623
7070
|
logger5.warn(`Failed to send celebration files: ${error.message}`);
|
|
@@ -6681,15 +7128,15 @@ function apply12(ctx) {
|
|
|
6681
7128
|
__name(apply12, "apply");
|
|
6682
7129
|
|
|
6683
7130
|
// src/games/sdvx/locales/en-US.yml
|
|
6684
|
-
var en_US_default4 = { _config: { $desc: "SDVX Module Settings", sdvx_data_url: "<p>The URL of the SDVX data service</p>", sdvx_search_url: "<p>The URL of the SDVX search service</p>", official_support_url: "<p>The URL of the SDVX official support service</p>" }, commands: { vf: { description: "Show Noah help information", messages: { "card-not-found": "<p>You haven't bound a card yet, go bind a card first~</p>", "server-not-found": "<p>No available servers, add one yourself~</p>", "no-scores-found": "<p>No scores found, please check your data.</p>", error: "<p>An error occurred(っ °Д °;)っ</p>", drawing: "<p>Noah is drawing {name} [{difstr}], please wait patiently~</p>", "menu-select": "<p>Please select the card you want to use:</p>\n{card_list}\n<p>q. Exit</p>", "invalid-select": "<p>No such option!</p>", quit: "<p>Exited~</p>" } }, sdvx: { recent: { description: "Show recent scores", messages: { "menu-select": "<p>Please select the card you want to use:</p>\n{card_list}\n<p>q. Exit</p>", "invalid-select": "<p>No such option!</p>", "card-not-found": "<p>You haven't bound a card yet, go bind a card first~</p>", "server-not-found": "<p>No available servers, add one yourself~</p>", "no-scores-found": "<p>No scores found, please check your data.</p>", error: "<p>An error occurred(っ °Д °;)っ</p>", drawing: "<p>Noah is drawing, please wait patiently~</p>" } }, chart: { description: "Show SDVX chart", messages: { prompt: "<p>Which song's chart would you like to view?</p>", error: "<p>An error occurred(っ °Д °;)っ</p>", drawing: "<p>Noah is drawing, please wait patiently~</p>", "no-result": "<p>Aww, Noah couldn’t find that song~ try another keyword, okay?</p>" } }, calculate: { description: "Calculate volforce value or score", messages: { "invalid-query": "<p>Invalid query parameters, please check your input~</p>", "no-results": "<p>No results found~</p>", "too-many-results": "<p>Too many results! Found {0} results, please narrow down your query (current limit: 500 results)</p>", drawing: "<p>Noah is drawing, please wait patiently~</p>", error: "<p>An error occurred(っ °Д °;)っ</p>" } }, radar: { description: "Show player radar stats", messages: { "card-not-found": "<p>You haven't bound a card yet, go bind a card first~</p>", "server-not-found": "<p>No available servers, add one yourself~</p>", "no-scores-found": "<p>No scores found, please check your data.</p>", error: "<p>An error occurred(っ °Д °;)っ</p>", result: "<p>{name}'s Radar</p>\n<p>NOTES: {notes}</p>\n<p>PEAK: {peak}</p>\n<p>TSUMAMI: {tsumami}</p>\n<p>TRICKY: {tricky}</p>\n<p>HAND-TRIP: {hand_trip}</p>\n<p>ONE-HAND: {one_hand}</p>" } }, sync: { description: "Sync scores to Mao", messages: { "mao-not-found": "<p>Mao server not found. Please add a Mao server first, then try syncing again.</p>", "source-server-not-found": "<p>No available source servers. Please add a server first.</p>", "source-server-select": "<p>Please choose the source server:</p>\n{server_list}\n<p>q. Exit</p>", "card-not-found": "<p>You haven't bound any card yet. Please bind a card first.</p>", "source-card-select": "<p>Please choose the source card:</p>\n{card_list}\n<p>q. Exit</p>", "target-card-select": "<p>Please choose the target card (sync to Mao):</p>\n{card_list}\n<p>q. Exit</p>", "invalid-select": "<p>No such option!</p>", quit: "<p>Sync cancelled.</p>", "same-card-error": "<p>When the source server is Mao, the source card and target card cannot be the same. Please choose again.</p>", "dm-only": "<p>For security, please use this command in a private chat.</p>", "pin-prompt": "<p>Please enter the Mao PIN (4 digits):</p>\n<p>q. Exit</p>", "pin-invalid": "<p>Invalid PIN format. Please enter 4 digits.</p>", "pin-verify-failed": "<p>PIN verification failed: {message}</p>", "pin-verify-error": "<p>PIN verification error. Please try again later.</p>", "pin-too-many": "<p>Too many PIN attempts. Please try again later.</p>", "fetch-error": "<p>Failed to fetch scores from the source server. Please try again later.</p>", "no-scores": "<p>No scores available for sync.</p>", "confirm-sync": "<p>Found {score_count} scores. Start sync?</p>\n<p>Type y to confirm, any other key to cancel.</p>", "sync-error": "<p>Error occurred during sync(っ °Д °;)っ</p>", "sync-failed": "<p>Sync failed(っ °Д °;)っ</p>", "selected-summary": "<p>Sync completedヾ(≧▽≦*)o</p>\n<p>Source server: {source_server_name} ({source_server_type})</p>\n<p>Source card: {source_card_name}</p>\n<p>Target card: {target_card_name}</p>\n<p>Tracks synced: {score_count}</p>" } } } } };
|
|
7131
|
+
var en_US_default4 = { _config: { $desc: "SDVX Module Settings", sdvx_data_url: "<p>The URL of the SDVX data service</p>", sdvx_search_url: "<p>The URL of the SDVX search service</p>", official_support_url: "<p>The URL of the SDVX official support service</p>" }, commands: { vf: { description: "Show Noah help information", messages: { "card-not-found": "<p>You haven't bound a card yet, go bind a card first~</p>", "server-not-found": "<p>No available servers, add one yourself~</p>", "no-scores-found": "<p>No scores found, please check your data.</p>", error: "<p>An error occurred(っ °Д °;)っ</p>", drawing: "<p>Noah is drawing {name} [{difstr}], please wait patiently~</p>", "menu-select": "<p>Please select the card you want to use:</p>\n{card_list}\n<p>q. Exit</p>", "server-menu-select": "<p>Please select the server you want to use:</p>\n{server_list}\n<p>q. Exit</p>", "invalid-select": "<p>No such option!</p>", quit: "<p>Exited~</p>" } }, sdvx: { recent: { description: "Show recent scores", messages: { "menu-select": "<p>Please select the card you want to use:</p>\n{card_list}\n<p>q. Exit</p>", "server-menu-select": "<p>Please select the server you want to use:</p>\n{server_list}\n<p>q. Exit</p>", "invalid-select": "<p>No such option!</p>", "card-not-found": "<p>You haven't bound a card yet, go bind a card first~</p>", "server-not-found": "<p>No available servers, add one yourself~</p>", "no-scores-found": "<p>No scores found, please check your data.</p>", error: "<p>An error occurred(っ °Д °;)っ</p>", drawing: "<p>Noah is drawing, please wait patiently~</p>", quit: "<p>Exited~</p>" } }, chart: { description: "Show SDVX chart", messages: { prompt: "<p>Which song's chart would you like to view?</p>", error: "<p>An error occurred(っ °Д °;)っ</p>", drawing: "<p>Noah is drawing, please wait patiently~</p>", "no-result": "<p>Aww, Noah couldn’t find that song~ try another keyword, okay?</p>" } }, calculate: { description: "Calculate volforce value or score", messages: { "invalid-query": "<p>Invalid query parameters, please check your input~</p>", "no-results": "<p>No results found~</p>", "too-many-results": "<p>Too many results! Found {0} results, please narrow down your query (current limit: 500 results)</p>", drawing: "<p>Noah is drawing, please wait patiently~</p>", error: "<p>An error occurred(っ °Д °;)っ</p>" } }, radar: { description: "Show player radar stats", messages: { "card-not-found": "<p>You haven't bound a card yet, go bind a card first~</p>", "server-not-found": "<p>No available servers, add one yourself~</p>", "no-scores-found": "<p>No scores found, please check your data.</p>", error: "<p>An error occurred(っ °Д °;)っ</p>", "menu-select": "<p>Please select the card you want to use:</p>\n{card_list}\n<p>q. Exit</p>", "server-menu-select": "<p>Please select the server you want to use:</p>\n{server_list}\n<p>q. Exit</p>", "invalid-select": "<p>No such option!</p>", quit: "<p>Exited~</p>", result: "<p>{name}'s Radar</p>\n<p>NOTES: {notes}</p>\n<p>PEAK: {peak}</p>\n<p>TSUMAMI: {tsumami}</p>\n<p>TRICKY: {tricky}</p>\n<p>HAND-TRIP: {hand_trip}</p>\n<p>ONE-HAND: {one_hand}</p>" } }, sync: { description: "Sync scores to Mao", messages: { "mao-not-found": "<p>Mao server not found. Please add a Mao server first, then try syncing again.</p>", "source-server-not-found": "<p>No available source servers. Please add a server first.</p>", "source-server-select": "<p>Please choose the source server:</p>\n{server_list}\n<p>q. Exit</p>", "card-not-found": "<p>You haven't bound any card yet. Please bind a card first.</p>", "source-card-select": "<p>Please choose the source card:</p>\n{card_list}\n<p>q. Exit</p>", "target-card-select": "<p>Please choose the target card (sync to Mao):</p>\n{card_list}\n<p>q. Exit</p>", "invalid-select": "<p>No such option!</p>", quit: "<p>Sync cancelled.</p>", "same-card-error": "<p>When the source server is Mao, the source card and target card cannot be the same. Please choose again.</p>", "dm-only": "<p>For security, please use this command in a private chat.</p>", "pin-prompt": "<p>Please enter the Mao PIN (4 digits):</p>\n<p>q. Exit</p>", "pin-invalid": "<p>Invalid PIN format. Please enter 4 digits.</p>", "pin-verify-failed": "<p>PIN verification failed: {message}</p>", "pin-verify-error": "<p>PIN verification error. Please try again later.</p>", "pin-too-many": "<p>Too many PIN attempts. Please try again later.</p>", "fetch-error": "<p>Failed to fetch scores from the source server. Please try again later.</p>", "no-scores": "<p>No scores available for sync.</p>", "confirm-sync": "<p>Found {score_count} scores. Start sync?</p>\n<p>Type y to confirm, any other key to cancel.</p>", "sync-error": "<p>Error occurred during sync(っ °Д °;)っ</p>", "sync-failed": "<p>Sync failed(っ °Д °;)っ</p>", "selected-summary": "<p>Sync completedヾ(≧▽≦*)o</p>\n<p>Source server: {source_server_name} ({source_server_type})</p>\n<p>Source card: {source_card_name}</p>\n<p>Target card: {target_card_name}</p>\n<p>Tracks synced: {score_count}</p>" } } } } };
|
|
6685
7132
|
|
|
6686
7133
|
// src/games/sdvx/locales/zh-CN.yml
|
|
6687
|
-
var zh_CN_default4 = { _config: { $desc: "SDVX 模块设置", sdvx_data_url: "<p>SDVX 数据服务的 URL</p>", sdvx_search_url: "<p>SDVX 搜索服务的 URL</p>", official_support_url: "<p>SDVX 官方支持服务的 URL</p>" }, commands: { vf: { description: "查询 SDVX VOLFORCE", messages: { "card-not-found": "<p>你还没绑卡,去绑个卡再来吧~</p>", "server-not-found": "<p>没有可用的服务器哦,自己添加一个吧~</p>", "no-scores-found": "<p>没有找到你的分数数据哦~</p>", error: "<p>Noah 遇到了错误(っ °Д °;)っ</p>", drawing: "<p>Noah 正在画啦,请耐心等待~</p>", "menu-select": "<p>请选择你要使用的卡片:</p>\n{card_list}\n<p>q. 退出</p>", "invalid-select": "<p>没有该选项!</p>", quit: "<p>已退出~</p>" } }, sdvx: { recent: { description: "查询最近分数", messages: { "menu-select": "<p>请选择你要使用的卡片:</p>\n{card_list}\n<p>q. 退出</p>", "invalid-select": "<p>没有该选项!</p>", "card-not-found": "<p>你还没绑卡,去绑个卡再来吧~</p>", "server-not-found": "<p>没有可用的服务器哦,自己添加一个吧~</p>", "no-scores-found": "<p>没有找到你的分数数据哦~</p>", error: "<p>Noah 遇到了错误(っ °Д °;)っ</p>", drawing: "<p>Noah 正在画啦,请耐心等待~</p>" } }, chart: { description: "查询 SDVX 谱面", messages: { prompt: "<p>要查哪首歌的铺面呢?</p>", error: "<p>Noah 遇到了错误(っ °Д °;)っ</p>", drawing: "<p>Noah 正在绘制 {name} [{difstr}],请耐心等待~</p>", "no-result": "<p>Noah 没有找到这首歌,换个关键词试试吧~</p>" } }, calculate: { description: "计算 volforce 值或分数", messages: { "invalid-query": "<p>查询参数无效,请检查你的输入~</p>", "no-results": "<p>没有找到符合条件的结果~</p>", "too-many-results": "<p>结果太多啦!共找到 {0} 条结果,请缩小查询范围(当前限制:500 条)</p>", drawing: "<p>Noah 正在画啦,请耐心等待~</p>", error: "<p>Noah 遇到了错误(っ °Д °;)っ</p>" } }, radar: { description: "查询玩家六维雷达", messages: { "card-not-found": "<p>你还没绑卡,去绑个卡再来吧~</p>", "server-not-found": "<p>没有可用的服务器哦,自己添加一个吧~</p>", "no-scores-found": "<p>没有找到你的分数数据哦~</p>", error: "<p>Noah 遇到了错误(っ °Д °;)っ</p>", result: "<p>{name} 的雷达</p>\n<p>NOTES: {notes}</p>\n<p>PEAK: {peak}</p>\n<p>TSUMAMI: {tsumami}</p>\n<p>TRICKY: {tricky}</p>\n<p>HAND-TRIP: {hand_trip}</p>\n<p>ONE-HAND: {one_hand}</p>" } }, sync: { description: "同步成绩到猫网", messages: { "mao-not-found": "<p>没有找到猫网服务器,请先添加猫网服务器后再尝试同步。</p>", "source-server-not-found": "<p>没有可作为来源的服务器,请先添加服务器。</p>", "source-server-select": "<p>请选择来源服务器:</p>\n{server_list}\n<p>q. 退出</p>", "card-not-found": "<p>你还没有绑定任何卡片哦~</p>", "source-card-select": "<p>请选择来源卡片:</p>\n{card_list}\n<p>q. 退出</p>", "target-card-select": "<p>请选择目标卡片(同步到猫网):</p>\n{card_list}\n<p>q. 退出</p>", "invalid-select": "<p>没有该选项!</p>", quit: "<p>已退出同步。</p>", "same-card-error": "<p>来源服务器为猫网时,来源卡片和目标卡片不能相同,请重新选择。</p>", "dm-only": "<p>出于安全考虑,请在私聊中使用该指令。</p>", "pin-prompt": "<p>请输入猫网 PIN 码(4 位数字):</p>\n<p>q. 退出</p>", "pin-invalid": "<p>PIN 码格式不正确,请输入 4 位数字。</p>", "pin-verify-failed": "<p>PIN 验证失败:{message}</p>", "pin-verify-error": "<p>PIN 验证时出现错误,请稍后重试。</p>", "pin-too-many": "<p>PIN 验证次数过多,请稍后再试。</p>", "fetch-error": "<p>获取来源服务器成绩失败,请稍后再试。</p>", "no-scores": "<p>没有可同步的成绩。</p>", "confirm-sync": "<p>共找到 {score_count} 条成绩,是否开始同步?</p>\n<p>输入 y 确认,其他任意键取消。</p>", "sync-error": "<p>同步过程中出现了错误(っ °Д °;)っ</p>", "sync-failed": "<p>同步失败(っ °Д °;)っ</p>", "selected-summary": "<p>同步完成ヾ(≧▽≦*)o</p>\n<p>来源服务器:{source_server_name} ({source_server_type})</p>\n<p>来源卡片:{source_card_name}</p>\n<p>目标卡片:{target_card_name}</p>\n<p>同步曲目数量:{score_count}</p>" } } } } };
|
|
7134
|
+
var zh_CN_default4 = { _config: { $desc: "SDVX 模块设置", sdvx_data_url: "<p>SDVX 数据服务的 URL</p>", sdvx_search_url: "<p>SDVX 搜索服务的 URL</p>", official_support_url: "<p>SDVX 官方支持服务的 URL</p>" }, commands: { vf: { description: "查询 SDVX VOLFORCE", messages: { "card-not-found": "<p>你还没绑卡,去绑个卡再来吧~</p>", "server-not-found": "<p>没有可用的服务器哦,自己添加一个吧~</p>", "no-scores-found": "<p>没有找到你的分数数据哦~</p>", error: "<p>Noah 遇到了错误(っ °Д °;)っ</p>", drawing: "<p>Noah 正在画啦,请耐心等待~</p>", "menu-select": "<p>请选择你要使用的卡片:</p>\n{card_list}\n<p>q. 退出</p>", "server-menu-select": "<p>请选择你要使用的服务器:</p>\n{server_list}\n<p>q. 退出</p>", "invalid-select": "<p>没有该选项!</p>", quit: "<p>已退出~</p>" } }, sdvx: { recent: { description: "查询最近分数", messages: { "menu-select": "<p>请选择你要使用的卡片:</p>\n{card_list}\n<p>q. 退出</p>", "server-menu-select": "<p>请选择你要使用的服务器:</p>\n{server_list}\n<p>q. 退出</p>", "invalid-select": "<p>没有该选项!</p>", "card-not-found": "<p>你还没绑卡,去绑个卡再来吧~</p>", "server-not-found": "<p>没有可用的服务器哦,自己添加一个吧~</p>", "no-scores-found": "<p>没有找到你的分数数据哦~</p>", error: "<p>Noah 遇到了错误(っ °Д °;)っ</p>", drawing: "<p>Noah 正在画啦,请耐心等待~</p>", quit: "<p>已退出~</p>" } }, chart: { description: "查询 SDVX 谱面", messages: { prompt: "<p>要查哪首歌的铺面呢?</p>", error: "<p>Noah 遇到了错误(っ °Д °;)っ</p>", drawing: "<p>Noah 正在绘制 {name} [{difstr}],请耐心等待~</p>", "no-result": "<p>Noah 没有找到这首歌,换个关键词试试吧~</p>" } }, calculate: { description: "计算 volforce 值或分数", messages: { "invalid-query": "<p>查询参数无效,请检查你的输入~</p>", "no-results": "<p>没有找到符合条件的结果~</p>", "too-many-results": "<p>结果太多啦!共找到 {0} 条结果,请缩小查询范围(当前限制:500 条)</p>", drawing: "<p>Noah 正在画啦,请耐心等待~</p>", error: "<p>Noah 遇到了错误(っ °Д °;)っ</p>" } }, radar: { description: "查询玩家六维雷达", messages: { "card-not-found": "<p>你还没绑卡,去绑个卡再来吧~</p>", "server-not-found": "<p>没有可用的服务器哦,自己添加一个吧~</p>", "no-scores-found": "<p>没有找到你的分数数据哦~</p>", error: "<p>Noah 遇到了错误(っ °Д °;)っ</p>", "menu-select": "<p>请选择你要使用的卡片:</p>\n{card_list}\n<p>q. 退出</p>", "server-menu-select": "<p>请选择你要使用的服务器:</p>\n{server_list}\n<p>q. 退出</p>", "invalid-select": "<p>没有该选项!</p>", quit: "<p>已退出~</p>", result: "<p>{name} 的雷达</p>\n<p>NOTES: {notes}</p>\n<p>PEAK: {peak}</p>\n<p>TSUMAMI: {tsumami}</p>\n<p>TRICKY: {tricky}</p>\n<p>HAND-TRIP: {hand_trip}</p>\n<p>ONE-HAND: {one_hand}</p>" } }, sync: { description: "同步成绩到猫网", messages: { "mao-not-found": "<p>没有找到猫网服务器,请先添加猫网服务器后再尝试同步。</p>", "source-server-not-found": "<p>没有可作为来源的服务器,请先添加服务器。</p>", "source-server-select": "<p>请选择来源服务器:</p>\n{server_list}\n<p>q. 退出</p>", "card-not-found": "<p>你还没有绑定任何卡片哦~</p>", "source-card-select": "<p>请选择来源卡片:</p>\n{card_list}\n<p>q. 退出</p>", "target-card-select": "<p>请选择目标卡片(同步到猫网):</p>\n{card_list}\n<p>q. 退出</p>", "invalid-select": "<p>没有该选项!</p>", quit: "<p>已退出同步。</p>", "same-card-error": "<p>来源服务器为猫网时,来源卡片和目标卡片不能相同,请重新选择。</p>", "dm-only": "<p>出于安全考虑,请在私聊中使用该指令。</p>", "pin-prompt": "<p>请输入猫网 PIN 码(4 位数字):</p>\n<p>q. 退出</p>", "pin-invalid": "<p>PIN 码格式不正确,请输入 4 位数字。</p>", "pin-verify-failed": "<p>PIN 验证失败:{message}</p>", "pin-verify-error": "<p>PIN 验证时出现错误,请稍后重试。</p>", "pin-too-many": "<p>PIN 验证次数过多,请稍后再试。</p>", "fetch-error": "<p>获取来源服务器成绩失败,请稍后再试。</p>", "no-scores": "<p>没有可同步的成绩。</p>", "confirm-sync": "<p>共找到 {score_count} 条成绩,是否开始同步?</p>\n<p>输入 y 确认,其他任意键取消。</p>", "sync-error": "<p>同步过程中出现了错误(っ °Д °;)っ</p>", "sync-failed": "<p>同步失败(っ °Д °;)っ</p>", "selected-summary": "<p>同步完成ヾ(≧▽≦*)o</p>\n<p>来源服务器:{source_server_name} ({source_server_type})</p>\n<p>来源卡片:{source_card_name}</p>\n<p>目标卡片:{target_card_name}</p>\n<p>同步曲目数量:{score_count}</p>" } } } } };
|
|
6688
7135
|
|
|
6689
7136
|
// src/games/sdvx/index.ts
|
|
6690
7137
|
var name13 = "Noah-SDVX";
|
|
6691
7138
|
var inject3 = ["database", "globalConfig"];
|
|
6692
|
-
var logger4 = new
|
|
7139
|
+
var logger4 = new import_koishi19.Logger("Noah-SDVX");
|
|
6693
7140
|
async function apply13(ctx, config) {
|
|
6694
7141
|
;
|
|
6695
7142
|
[
|
|
@@ -6704,47 +7151,50 @@ async function apply13(ctx, config) {
|
|
|
6704
7151
|
__name(apply13, "apply");
|
|
6705
7152
|
|
|
6706
7153
|
// src/config.ts
|
|
6707
|
-
var
|
|
7154
|
+
var import_koishi27 = require("koishi");
|
|
6708
7155
|
|
|
6709
7156
|
// src/asset/config.ts
|
|
6710
|
-
var
|
|
6711
|
-
var assetConfig =
|
|
6712
|
-
data_path:
|
|
6713
|
-
auto_update:
|
|
6714
|
-
update_url:
|
|
6715
|
-
update_interval:
|
|
7157
|
+
var import_koishi20 = require("koishi");
|
|
7158
|
+
var assetConfig = import_koishi20.Schema.object({
|
|
7159
|
+
data_path: import_koishi20.Schema.string().default("noah_assets"),
|
|
7160
|
+
auto_update: import_koishi20.Schema.boolean().default(true),
|
|
7161
|
+
update_url: import_koishi20.Schema.string().default("https://github.com/logthm/noah/releases/latest/download/"),
|
|
7162
|
+
update_interval: import_koishi20.Schema.number().default(24 * 60 * 60 * 1e3),
|
|
6716
7163
|
// 24 hours in milliseconds
|
|
6717
|
-
github_token:
|
|
7164
|
+
github_token: import_koishi20.Schema.string().description("GitHub token for accessing private repositories").role("secret")
|
|
6718
7165
|
}).i18n({
|
|
6719
7166
|
"en-US": en_US_default._config,
|
|
6720
7167
|
"zh-CN": zh_CN_default._config
|
|
6721
7168
|
});
|
|
6722
7169
|
|
|
6723
7170
|
// src/core/config.ts
|
|
6724
|
-
var
|
|
6725
|
-
var coreConfig =
|
|
6726
|
-
adminUsers:
|
|
6727
|
-
guildNameCards:
|
|
7171
|
+
var import_koishi21 = require("koishi");
|
|
7172
|
+
var coreConfig = import_koishi21.Schema.object({
|
|
7173
|
+
adminUsers: import_koishi21.Schema.array(String).role("table"),
|
|
7174
|
+
guildNameCards: import_koishi21.Schema.array(String).role("table").default(["Noah | /help 获取食用指南"]),
|
|
7175
|
+
tokenTtl: import_koishi21.Schema.number().default(1800),
|
|
7176
|
+
frontendUrl: import_koishi21.Schema.string().default(""),
|
|
7177
|
+
corsOrigin: import_koishi21.Schema.string().default("*")
|
|
6728
7178
|
}).i18n({
|
|
6729
7179
|
"en-US": en_US_default2._config,
|
|
6730
7180
|
"zh-CN": zh_CN_default2._config
|
|
6731
7181
|
});
|
|
6732
7182
|
|
|
6733
7183
|
// src/fun/poke/config.ts
|
|
6734
|
-
var
|
|
6735
|
-
var pokeConfig =
|
|
6736
|
-
interval:
|
|
6737
|
-
warning:
|
|
6738
|
-
prompt:
|
|
6739
|
-
|
|
6740
|
-
content:
|
|
6741
|
-
weight:
|
|
7184
|
+
var import_koishi22 = require("koishi");
|
|
7185
|
+
var pokeConfig = import_koishi22.Schema.object({
|
|
7186
|
+
interval: import_koishi22.Schema.number().default(1e3).step(100),
|
|
7187
|
+
warning: import_koishi22.Schema.boolean().default(false),
|
|
7188
|
+
prompt: import_koishi22.Schema.array(
|
|
7189
|
+
import_koishi22.Schema.object({
|
|
7190
|
+
content: import_koishi22.Schema.string().required(),
|
|
7191
|
+
weight: import_koishi22.Schema.number().min(0).max(100).default(50)
|
|
6742
7192
|
})
|
|
6743
7193
|
).role("table"),
|
|
6744
|
-
messages:
|
|
6745
|
-
|
|
6746
|
-
content:
|
|
6747
|
-
weight:
|
|
7194
|
+
messages: import_koishi22.Schema.array(
|
|
7195
|
+
import_koishi22.Schema.object({
|
|
7196
|
+
content: import_koishi22.Schema.string().required(),
|
|
7197
|
+
weight: import_koishi22.Schema.number().min(0).max(100).default(50)
|
|
6748
7198
|
})
|
|
6749
7199
|
).role("table")
|
|
6750
7200
|
}).i18n({
|
|
@@ -6753,7 +7203,7 @@ var pokeConfig = import_koishi21.Schema.object({
|
|
|
6753
7203
|
});
|
|
6754
7204
|
|
|
6755
7205
|
// src/games/general/config.ts
|
|
6756
|
-
var
|
|
7206
|
+
var import_koishi23 = require("koishi");
|
|
6757
7207
|
|
|
6758
7208
|
// src/games/general/locales/en-US.yml
|
|
6759
7209
|
var en_US_default5 = { _config: { $desc: "General Module Settings", barcode_api_url: "<p>The URL of the barcode API</p>" } };
|
|
@@ -6762,33 +7212,33 @@ var en_US_default5 = { _config: { $desc: "General Module Settings", barcode_api_
|
|
|
6762
7212
|
var zh_CN_default5 = { _config: { $desc: "通用工具模块设置", barcode_api_url: "<p>条形码 API 地址</p>" } };
|
|
6763
7213
|
|
|
6764
7214
|
// src/games/general/config.ts
|
|
6765
|
-
var generalConfig =
|
|
6766
|
-
barcode_api_url:
|
|
7215
|
+
var generalConfig = import_koishi23.Schema.object({
|
|
7216
|
+
barcode_api_url: import_koishi23.Schema.string().required()
|
|
6767
7217
|
}).i18n({
|
|
6768
7218
|
"en-US": en_US_default5._config,
|
|
6769
7219
|
"zh-CN": zh_CN_default5._config
|
|
6770
7220
|
});
|
|
6771
7221
|
|
|
6772
7222
|
// src/games/sdvx/config.ts
|
|
6773
|
-
var
|
|
6774
|
-
var sdvxConfig =
|
|
6775
|
-
sdvx_data_url:
|
|
6776
|
-
sdvx_search_url:
|
|
7223
|
+
var import_koishi24 = require("koishi");
|
|
7224
|
+
var sdvxConfig = import_koishi24.Schema.object({
|
|
7225
|
+
sdvx_data_url: import_koishi24.Schema.string().required(),
|
|
7226
|
+
sdvx_search_url: import_koishi24.Schema.string().required()
|
|
6777
7227
|
}).i18n({
|
|
6778
7228
|
"en-US": en_US_default4._config,
|
|
6779
7229
|
"zh-CN": zh_CN_default4._config
|
|
6780
7230
|
});
|
|
6781
7231
|
|
|
6782
7232
|
// src/global/config.ts
|
|
6783
|
-
var
|
|
6784
|
-
var globalConfig =
|
|
6785
|
-
official_support_url:
|
|
6786
|
-
maoServerUrl:
|
|
6787
|
-
maoApiKey:
|
|
7233
|
+
var import_koishi25 = require("koishi");
|
|
7234
|
+
var globalConfig = import_koishi25.Schema.object({
|
|
7235
|
+
official_support_url: import_koishi25.Schema.string().default("https://noah.logthm.com"),
|
|
7236
|
+
maoServerUrl: import_koishi25.Schema.string().default("http://maomani.cn:577"),
|
|
7237
|
+
maoApiKey: import_koishi25.Schema.string().role("secret").default("")
|
|
6788
7238
|
});
|
|
6789
7239
|
|
|
6790
7240
|
// src/slash/config.ts
|
|
6791
|
-
var
|
|
7241
|
+
var import_koishi26 = require("koishi");
|
|
6792
7242
|
|
|
6793
7243
|
// src/slash/locales/en-US.yml
|
|
6794
7244
|
var en_US_default6 = { _config: { $desc: "Slash Module Settings", test_guilds: "**Guilds To Sync**", auto_sync_on_start: "**Auto Sync on Connect**" } };
|
|
@@ -6797,16 +7247,16 @@ var en_US_default6 = { _config: { $desc: "Slash Module Settings", test_guilds: "
|
|
|
6797
7247
|
var zh_CN_default6 = { _config: { $desc: "Slash 模块设置", test_guilds: "**默认同步 Guild 列表**", auto_sync_on_start: "**连接后自动同步**" } };
|
|
6798
7248
|
|
|
6799
7249
|
// src/slash/config.ts
|
|
6800
|
-
var slashConfig =
|
|
6801
|
-
test_guilds:
|
|
6802
|
-
auto_sync_on_start:
|
|
7250
|
+
var slashConfig = import_koishi26.Schema.object({
|
|
7251
|
+
test_guilds: import_koishi26.Schema.array(String).default([]),
|
|
7252
|
+
auto_sync_on_start: import_koishi26.Schema.boolean().default(true)
|
|
6803
7253
|
}).i18n({
|
|
6804
7254
|
"en-US": en_US_default6._config,
|
|
6805
7255
|
"zh-CN": zh_CN_default6._config
|
|
6806
7256
|
});
|
|
6807
7257
|
|
|
6808
7258
|
// src/config.ts
|
|
6809
|
-
var Config =
|
|
7259
|
+
var Config = import_koishi27.Schema.object({
|
|
6810
7260
|
global: globalConfig,
|
|
6811
7261
|
core: coreConfig,
|
|
6812
7262
|
sdvx: sdvxConfig,
|
|
@@ -6818,7 +7268,7 @@ var Config = import_koishi26.Schema.object({
|
|
|
6818
7268
|
|
|
6819
7269
|
// src/index.ts
|
|
6820
7270
|
var name14 = "noah";
|
|
6821
|
-
var inject4 = ["database", "skia"];
|
|
7271
|
+
var inject4 = ["database", "skia", "server"];
|
|
6822
7272
|
async function apply14(ctx, config) {
|
|
6823
7273
|
initConstants(ctx);
|
|
6824
7274
|
ctx.set("globalConfig", config.global);
|