@sfmc-bds/db-server 0.2.0-beta.13 → 0.2.0-beta.15
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/dist/domain/bridge.d.ts +1 -5
- package/dist/domain/bridge.d.ts.map +1 -1
- package/dist/domain/bridge.js +15 -14
- package/dist/domain/bridge.js.map +2 -2
- package/dist/domain/installed-content.d.ts +84 -0
- package/dist/domain/installed-content.d.ts.map +1 -0
- package/dist/domain/installed-content.js +149 -0
- package/dist/domain/installed-content.js.map +7 -0
- package/dist/domain/qq-account-profile.d.ts +51 -0
- package/dist/domain/qq-account-profile.d.ts.map +1 -0
- package/dist/domain/qq-account-profile.js +129 -0
- package/dist/domain/qq-account-profile.js.map +7 -0
- package/dist/domain/qq-events.d.ts +2 -2
- package/dist/domain/qq-events.d.ts.map +1 -1
- package/dist/domain/qq-events.js +6 -3
- package/dist/domain/qq-events.js.map +2 -2
- package/dist/domain/schema.d.ts.map +1 -1
- package/dist/domain/schema.js +13 -0
- package/dist/domain/schema.js.map +2 -2
- package/dist/domain/system-status.d.ts +3 -0
- package/dist/domain/system-status.d.ts.map +1 -1
- package/dist/domain/system-status.js +27 -12
- package/dist/domain/system-status.js.map +2 -2
- package/dist/env.d.ts +0 -2
- package/dist/env.d.ts.map +1 -1
- package/dist/env.js +12 -24
- package/dist/env.js.map +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +73 -21
- package/dist/index.js.map +3 -3
- package/dist/routes/config.d.ts +1 -1
- package/dist/routes/config.d.ts.map +1 -1
- package/dist/routes/config.js +0 -4
- package/dist/routes/config.js.map +2 -2
- package/dist/routes/content.d.ts +23 -0
- package/dist/routes/content.d.ts.map +1 -0
- package/dist/routes/content.js +19 -0
- package/dist/routes/content.js.map +7 -0
- package/dist/routes/messages.d.ts +14 -6
- package/dist/routes/messages.d.ts.map +1 -1
- package/dist/routes/messages.js +22 -8
- package/dist/routes/messages.js.map +2 -2
- package/dist/routes/qq-bind.d.ts.map +1 -1
- package/dist/routes/qq-bind.js +29 -1
- package/dist/routes/qq-bind.js.map +2 -2
- package/dist/routes/qq-events.d.ts +6 -2
- package/dist/routes/qq-events.d.ts.map +1 -1
- package/dist/routes/qq-events.js +35 -1
- package/dist/routes/qq-events.js.map +3 -3
- package/dist/routes/qq-join.js +1 -1
- package/dist/routes/qq-join.js.map +2 -2
- package/dist/routes/status.d.ts +3 -11
- package/dist/routes/status.d.ts.map +1 -1
- package/dist/routes/status.js +39 -49
- package/dist/routes/status.js.map +2 -2
- package/package.json +4 -5
- package/dist/domain/bridge.test.d.ts +0 -2
- package/dist/domain/bridge.test.d.ts.map +0 -1
- package/dist/domain/bridge.test.js +0 -87
- package/dist/domain/bridge.test.js.map +0 -7
- package/dist/domain/messages-bridge-filter.test.d.ts +0 -5
- package/dist/domain/messages-bridge-filter.test.d.ts.map +0 -1
- package/dist/domain/messages-bridge-filter.test.js +0 -20
- package/dist/domain/messages-bridge-filter.test.js.map +0 -7
- package/dist/domain/player-session.test.d.ts +0 -2
- package/dist/domain/player-session.test.d.ts.map +0 -1
- package/dist/domain/player-session.test.js +0 -33
- package/dist/domain/player-session.test.js.map +0 -7
- package/dist/domain/qq-bind-status.test.d.ts +0 -2
- package/dist/domain/qq-bind-status.test.d.ts.map +0 -1
- package/dist/domain/qq-bind-status.test.js +0 -211
- package/dist/domain/qq-bind-status.test.js.map +0 -7
- package/dist/domain/qq-events.test.d.ts +0 -5
- package/dist/domain/qq-events.test.d.ts.map +0 -1
- package/dist/domain/qq-events.test.js +0 -170
- package/dist/domain/qq-events.test.js.map +0 -7
- package/dist/domain/qq-join.test.d.ts +0 -2
- package/dist/domain/qq-join.test.d.ts.map +0 -1
- package/dist/domain/qq-join.test.js +0 -353
- package/dist/domain/qq-join.test.js.map +0 -7
- package/dist/domain/system-status.test.d.ts +0 -5
- package/dist/domain/system-status.test.d.ts.map +0 -1
- package/dist/domain/system-status.test.js +0 -19
- package/dist/domain/system-status.test.js.map +0 -7
- package/dist/runtime.test.d.ts +0 -2
- package/dist/runtime.test.d.ts.map +0 -1
- package/dist/runtime.test.js +0 -477
- package/dist/runtime.test.js.map +0 -7
package/dist/routes/status.js
CHANGED
|
@@ -1,68 +1,58 @@
|
|
|
1
|
-
import { SQL } from "sql-template-strings";
|
|
2
|
-
import { PROJECT_ROOT } from "../project-root.js";
|
|
3
1
|
import { collectSystemStatus } from "../domain/system-status.js";
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
import { PROJECT_ROOT } from "../project-root.js";
|
|
3
|
+
import { body, json } from "./_shared.js";
|
|
4
|
+
const FRESH_MS = 6e4;
|
|
5
|
+
function createStatusRoutes({ collectSystem, projectRoot }) {
|
|
7
6
|
const root = projectRoot ?? PROJECT_ROOT;
|
|
8
7
|
const collect = collectSystem ?? collectSystemStatus;
|
|
9
|
-
|
|
8
|
+
let live = null;
|
|
9
|
+
return async function handle({ path, method, req, res }) {
|
|
10
|
+
if (path === "/api/sfmc/status/live") {
|
|
11
|
+
if (method !== "POST") {
|
|
12
|
+
json(res, { success: false, error: "not_found" }, 404);
|
|
13
|
+
return true;
|
|
14
|
+
}
|
|
15
|
+
const data = await body(req);
|
|
16
|
+
const raw = data.players;
|
|
17
|
+
const day = data.day;
|
|
18
|
+
const difficulty = data.difficulty;
|
|
19
|
+
if (!Array.isArray(raw) || raw.length > 1e3 || !raw.every((name) => typeof name === "string" && name.trim().length > 0 && name.length <= 64) || typeof day !== "number" || !Number.isSafeInteger(day) || day < 0 || typeof difficulty !== "string" || difficulty.length > 32) {
|
|
20
|
+
json(res, { success: false, error: "invalid_live_status" }, 400);
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
live = {
|
|
24
|
+
online: raw.map((name) => ({ name: name.trim() })),
|
|
25
|
+
world: { day, difficulty },
|
|
26
|
+
updatedAt: Date.now()
|
|
27
|
+
};
|
|
28
|
+
json(res, { success: true });
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
10
31
|
if (path !== "/api/sfmc/status") return false;
|
|
11
32
|
if (method !== "GET") {
|
|
12
33
|
json(res, { success: false, error: "not_found" }, 404);
|
|
13
34
|
return true;
|
|
14
35
|
}
|
|
15
|
-
const now = Date.now();
|
|
16
|
-
let world = null;
|
|
17
|
-
let worldUpdatedAt = null;
|
|
18
|
-
try {
|
|
19
|
-
const worlds = query(SQL`SELECT * FROM sfmc_world LIMIT 1`);
|
|
20
|
-
if (worlds.length > 0 && worlds[0]) {
|
|
21
|
-
world = {
|
|
22
|
-
day: worlds[0].day ?? null,
|
|
23
|
-
difficulty: worlds[0].difficulty ?? null,
|
|
24
|
-
absolute_time: worlds[0].absolute_time ?? null,
|
|
25
|
-
moon_phase: worlds[0].moon_phase ?? null
|
|
26
|
-
};
|
|
27
|
-
worldUpdatedAt = worlds[0].updated_at ?? null;
|
|
28
|
-
}
|
|
29
|
-
} catch {
|
|
30
|
-
world = null;
|
|
31
|
-
}
|
|
32
|
-
let players = [];
|
|
33
|
-
try {
|
|
34
|
-
const rows = query(
|
|
35
|
-
SQL`SELECT id, name, updated_at FROM sfmc_players ORDER BY updated_at DESC LIMIT 64`
|
|
36
|
-
);
|
|
37
|
-
players = rows.map((r) => ({
|
|
38
|
-
id: String(r.id ?? ""),
|
|
39
|
-
name: String(r.name ?? ""),
|
|
40
|
-
updated_at: Number(r.updated_at) || 0
|
|
41
|
-
}));
|
|
42
|
-
} catch {
|
|
43
|
-
players = [];
|
|
44
|
-
}
|
|
45
|
-
const fresh = players.filter((p) => p.updated_at > 0 && now - p.updated_at <= FRESH_MS);
|
|
46
|
-
const online = fresh.map((p) => ({ id: p.id, name: p.name }));
|
|
47
|
-
const newestPlayer = players[0]?.updated_at ?? 0;
|
|
48
|
-
const updatedAt = Math.max(newestPlayer, typeof worldUpdatedAt === "number" ? worldUpdatedAt : 0) || now;
|
|
49
36
|
let system = null;
|
|
50
37
|
try {
|
|
51
38
|
system = await collect(root);
|
|
52
39
|
} catch {
|
|
53
40
|
system = null;
|
|
54
41
|
}
|
|
42
|
+
const now = Date.now();
|
|
43
|
+
const bds = system?.bds;
|
|
44
|
+
const bdsAgeMs = typeof bds?.uptimeSec === "number" ? bds.uptimeSec * 1e3 : null;
|
|
45
|
+
const snapshot = live;
|
|
46
|
+
const fresh = snapshot !== null && bds?.state === "running" && now - snapshot.updatedAt <= FRESH_MS && (bdsAgeMs === null || now - snapshot.updatedAt <= bdsAgeMs + 2e3);
|
|
47
|
+
const current = fresh ? snapshot : null;
|
|
55
48
|
json(res, {
|
|
56
|
-
online,
|
|
57
|
-
world,
|
|
58
|
-
updatedAt,
|
|
49
|
+
online: current?.online ?? [],
|
|
50
|
+
world: current?.world ?? null,
|
|
51
|
+
updatedAt: current?.updatedAt ?? null,
|
|
59
52
|
host: system?.host ?? null,
|
|
60
|
-
processes: system ? {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
} : null,
|
|
64
|
-
source: "sfmc_players/sfmc_world+os",
|
|
65
|
-
note: online.length === 0 ? "\u6682\u65E0\u65B0\u9C9C\u5728\u7EBF\u6570\u636E\uFF08\u9700 BDS \u540C\u6B65\u73A9\u5BB6\u8868\uFF0C\u6216\u6570\u636E\u8D85\u8FC7 5 \u5206\u949F\uFF09" : void 0
|
|
53
|
+
processes: system ? { db: system.db, bds: system.bds } : null,
|
|
54
|
+
source: "bds_script_live",
|
|
55
|
+
note: fresh ? void 0 : bds?.state === "stopped" ? "\u670D\u52A1\u5668\u672A\u8FD0\u884C" : "\u7B49\u5F85\u6E38\u620F\u5B9E\u65F6\u72B6\u6001\u540C\u6B65"
|
|
66
56
|
});
|
|
67
57
|
return true;
|
|
68
58
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/routes/status.ts"],
|
|
4
|
-
"sourcesContent": ["
|
|
5
|
-
"mappings": "
|
|
4
|
+
"sourcesContent": ["/** GET /api/sfmc/status \u4E0E BDS \u5B9E\u65F6\u5FEB\u7167\u5165\u53E3\u3002 */\n\nimport { collectSystemStatus, type SystemStatusSnapshot } from \"../domain/system-status.js\";\nimport { PROJECT_ROOT } from \"../project-root.js\";\nimport { body, json, type RouteFactory } from \"./_shared.js\";\n\nconst FRESH_MS = 60_000;\n\ninterface LiveSnapshot {\n online: Array<{ name: string }>;\n world: { day: number; difficulty: string };\n updatedAt: number;\n}\n\ninterface Deps {\n collectSystem?: (projectRoot: string) => Promise<SystemStatusSnapshot>;\n projectRoot?: string;\n}\n\nfunction createStatusRoutes({ collectSystem, projectRoot }: Deps): ReturnType<RouteFactory> {\n const root = projectRoot ?? PROJECT_ROOT;\n const collect = collectSystem ?? collectSystemStatus;\n let live: LiveSnapshot | null = null;\n\n return async function handle({ path, method, req, res }): Promise<boolean> {\n if (path === \"/api/sfmc/status/live\") {\n if (method !== \"POST\") {\n json(res, { success: false, error: \"not_found\" }, 404);\n return true;\n }\n const data = await body(req);\n const raw = data.players;\n const day = data.day;\n const difficulty = data.difficulty;\n if (\n !Array.isArray(raw) || raw.length > 1000 ||\n !raw.every((name) => typeof name === \"string\" && name.trim().length > 0 && name.length <= 64) ||\n typeof day !== \"number\" || !Number.isSafeInteger(day) || day < 0 ||\n typeof difficulty !== \"string\" || difficulty.length > 32\n ) {\n json(res, { success: false, error: \"invalid_live_status\" }, 400);\n return true;\n }\n live = {\n online: raw.map((name: string) => ({ name: name.trim() })),\n world: { day, difficulty },\n updatedAt: Date.now(),\n };\n json(res, { success: true });\n return true;\n }\n\n if (path !== \"/api/sfmc/status\") return false;\n if (method !== \"GET\") {\n json(res, { success: false, error: \"not_found\" }, 404);\n return true;\n }\n\n let system: SystemStatusSnapshot | null = null;\n try {\n system = await collect(root);\n } catch {\n system = null;\n }\n\n const now = Date.now();\n const bds = system?.bds;\n const bdsAgeMs = typeof bds?.uptimeSec === \"number\" ? bds.uptimeSec * 1000 : null;\n const snapshot = live;\n const fresh = snapshot !== null &&\n bds?.state === \"running\" &&\n now - snapshot.updatedAt <= FRESH_MS &&\n (bdsAgeMs === null || now - snapshot.updatedAt <= bdsAgeMs + 2_000);\n const current = fresh ? snapshot : null;\n\n json(res, {\n online: current?.online ?? [],\n world: current?.world ?? null,\n updatedAt: current?.updatedAt ?? null,\n host: system?.host ?? null,\n processes: system ? { db: system.db, bds: system.bds } : null,\n source: \"bds_script_live\",\n note: fresh ? undefined : bds?.state === \"stopped\" ? \"\u670D\u52A1\u5668\u672A\u8FD0\u884C\" : \"\u7B49\u5F85\u6E38\u620F\u5B9E\u65F6\u72B6\u6001\u540C\u6B65\",\n });\n return true;\n };\n}\n\nexport { createStatusRoutes, FRESH_MS };\n"],
|
|
5
|
+
"mappings": "AAEA,SAAS,2BAAsD;AAC/D,SAAS,oBAAoB;AAC7B,SAAS,MAAM,YAA+B;AAE9C,MAAM,WAAW;AAajB,SAAS,mBAAmB,EAAE,eAAe,YAAY,GAAmC;AAC1F,QAAM,OAAO,eAAe;AAC5B,QAAM,UAAU,iBAAiB;AACjC,MAAI,OAA4B;AAEhC,SAAO,eAAe,OAAO,EAAE,MAAM,QAAQ,KAAK,IAAI,GAAqB;AACzE,QAAI,SAAS,yBAAyB;AACpC,UAAI,WAAW,QAAQ;AACrB,aAAK,KAAK,EAAE,SAAS,OAAO,OAAO,YAAY,GAAG,GAAG;AACrD,eAAO;AAAA,MACT;AACA,YAAM,OAAO,MAAM,KAAK,GAAG;AAC3B,YAAM,MAAM,KAAK;AACjB,YAAM,MAAM,KAAK;AACjB,YAAM,aAAa,KAAK;AACxB,UACE,CAAC,MAAM,QAAQ,GAAG,KAAK,IAAI,SAAS,OACpC,CAAC,IAAI,MAAM,CAAC,SAAS,OAAO,SAAS,YAAY,KAAK,KAAK,EAAE,SAAS,KAAK,KAAK,UAAU,EAAE,KAC5F,OAAO,QAAQ,YAAY,CAAC,OAAO,cAAc,GAAG,KAAK,MAAM,KAC/D,OAAO,eAAe,YAAY,WAAW,SAAS,IACtD;AACA,aAAK,KAAK,EAAE,SAAS,OAAO,OAAO,sBAAsB,GAAG,GAAG;AAC/D,eAAO;AAAA,MACT;AACA,aAAO;AAAA,QACL,QAAQ,IAAI,IAAI,CAAC,UAAkB,EAAE,MAAM,KAAK,KAAK,EAAE,EAAE;AAAA,QACzD,OAAO,EAAE,KAAK,WAAW;AAAA,QACzB,WAAW,KAAK,IAAI;AAAA,MACtB;AACA,WAAK,KAAK,EAAE,SAAS,KAAK,CAAC;AAC3B,aAAO;AAAA,IACT;AAEA,QAAI,SAAS,mBAAoB,QAAO;AACxC,QAAI,WAAW,OAAO;AACpB,WAAK,KAAK,EAAE,SAAS,OAAO,OAAO,YAAY,GAAG,GAAG;AACrD,aAAO;AAAA,IACT;AAEA,QAAI,SAAsC;AAC1C,QAAI;AACF,eAAS,MAAM,QAAQ,IAAI;AAAA,IAC7B,QAAQ;AACN,eAAS;AAAA,IACX;AAEA,UAAM,MAAM,KAAK,IAAI;AACrB,UAAM,MAAM,QAAQ;AACpB,UAAM,WAAW,OAAO,KAAK,cAAc,WAAW,IAAI,YAAY,MAAO;AAC7E,UAAM,WAAW;AACjB,UAAM,QAAQ,aAAa,QACzB,KAAK,UAAU,aACf,MAAM,SAAS,aAAa,aAC3B,aAAa,QAAQ,MAAM,SAAS,aAAa,WAAW;AAC/D,UAAM,UAAU,QAAQ,WAAW;AAEnC,SAAK,KAAK;AAAA,MACR,QAAQ,SAAS,UAAU,CAAC;AAAA,MAC5B,OAAO,SAAS,SAAS;AAAA,MACzB,WAAW,SAAS,aAAa;AAAA,MACjC,MAAM,QAAQ,QAAQ;AAAA,MACtB,WAAW,SAAS,EAAE,IAAI,OAAO,IAAI,KAAK,OAAO,IAAI,IAAI;AAAA,MACzD,QAAQ;AAAA,MACR,MAAM,QAAQ,SAAY,KAAK,UAAU,YAAY,yCAAW;AAAA,IAClE,CAAC;AACD,WAAO;AAAA,EACT;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sfmc-bds/db-server",
|
|
3
|
-
"version": "0.2.0-beta.
|
|
3
|
+
"version": "0.2.0-beta.15",
|
|
4
4
|
"description": "SFMC SQLite HTTP REST backend — configs, modules, gameplay data",
|
|
5
5
|
"author": "Shiroha7z",
|
|
6
6
|
"license": "AGPL-3.0-only",
|
|
@@ -32,10 +32,11 @@
|
|
|
32
32
|
],
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"sql-template-strings": "^2.2.2",
|
|
35
|
-
"@sfmc-bds/
|
|
35
|
+
"@sfmc-bds/bds-tools": "0.2.0-beta.18",
|
|
36
|
+
"@sfmc-bds/sdk": "0.2.0-beta.18"
|
|
36
37
|
},
|
|
37
38
|
"devDependencies": {
|
|
38
|
-
"@sfmc-bds/tools": "0.2.0-beta.
|
|
39
|
+
"@sfmc-bds/tools": "0.2.0-beta.19"
|
|
39
40
|
},
|
|
40
41
|
"publishConfig": {
|
|
41
42
|
"access": "public",
|
|
@@ -47,8 +48,6 @@
|
|
|
47
48
|
"dev": "tsx src/index.ts",
|
|
48
49
|
"format": "prettier --write \"src/**/*.{ts,tsx,js,json}\"",
|
|
49
50
|
"start": "node dist/index.js",
|
|
50
|
-
"test": "node --test dist/**/*.test.js dist/*.test.js",
|
|
51
|
-
"test:api": "pnpm run build && node scripts/test-db-api.mjs",
|
|
52
51
|
"typecheck": "tsc7 --noEmit"
|
|
53
52
|
}
|
|
54
53
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"bridge.test.d.ts","sourceRoot":"","sources":["../../src/domain/bridge.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
import assert from "node:assert/strict";
|
|
2
|
-
import test from "node:test";
|
|
3
|
-
import { makeLLBotConfig, makeOutboundConfig, forwardToQQBridge } from "./bridge.js";
|
|
4
|
-
test("makeOutboundConfig\uFF1Aofficial / llbot \u5206\u652F", () => {
|
|
5
|
-
const official = makeOutboundConfig({
|
|
6
|
-
QQ_BACKEND: "official",
|
|
7
|
-
LLBOT_HOST: "127.0.0.1",
|
|
8
|
-
LLBOT_PORT: 3004,
|
|
9
|
-
LLBOT_TOKEN: "",
|
|
10
|
-
QQ_GROUP_ID: "123",
|
|
11
|
-
QQ_APP_ID: "app",
|
|
12
|
-
QQ_APP_SECRET: "sec",
|
|
13
|
-
QQ_SANDBOX: true,
|
|
14
|
-
QQ_GROUP_OPENID: "GOPEN",
|
|
15
|
-
MCTOQQ_PREFIX: "[MC]"
|
|
16
|
-
});
|
|
17
|
-
assert.equal(official.backend, "official");
|
|
18
|
-
if (official.backend === "official") {
|
|
19
|
-
assert.equal(official.groupOpenid, "GOPEN");
|
|
20
|
-
assert.equal(official.creds.sandbox, true);
|
|
21
|
-
assert.equal(official.prefix, "[MC]");
|
|
22
|
-
}
|
|
23
|
-
const llbot = makeOutboundConfig({
|
|
24
|
-
QQ_BACKEND: "llbot",
|
|
25
|
-
LLBOT_HOST: "127.0.0.1",
|
|
26
|
-
LLBOT_PORT: 3004,
|
|
27
|
-
LLBOT_TOKEN: "t",
|
|
28
|
-
QQ_GROUP_ID: "99",
|
|
29
|
-
QQ_APP_ID: "",
|
|
30
|
-
QQ_APP_SECRET: "",
|
|
31
|
-
QQ_SANDBOX: false,
|
|
32
|
-
QQ_GROUP_OPENID: "",
|
|
33
|
-
MCTOQQ_PREFIX: "[X]"
|
|
34
|
-
});
|
|
35
|
-
assert.equal(llbot.backend, "llbot");
|
|
36
|
-
if (llbot.backend === "llbot") {
|
|
37
|
-
assert.equal(llbot.llbot.groupId, "99");
|
|
38
|
-
assert.equal(llbot.llbot.prefix, "[X]");
|
|
39
|
-
}
|
|
40
|
-
});
|
|
41
|
-
test("makeLLBotConfig \u4F7F\u7528 mctoqq_prefix", () => {
|
|
42
|
-
const cfg = makeLLBotConfig({
|
|
43
|
-
LLBOT_HOST: "h",
|
|
44
|
-
LLBOT_PORT: 1,
|
|
45
|
-
LLBOT_TOKEN: "",
|
|
46
|
-
QQ_GROUP_ID: "1",
|
|
47
|
-
MCTOQQ_PREFIX: "[P]"
|
|
48
|
-
});
|
|
49
|
-
assert.equal(cfg.prefix, "[P]");
|
|
50
|
-
});
|
|
51
|
-
test("forwardToQQBridge official\uFF1A\u7F3A group_openid \u4E0D\u629B\u9519", () => {
|
|
52
|
-
assert.doesNotThrow(() => {
|
|
53
|
-
forwardToQQBridge(
|
|
54
|
-
{
|
|
55
|
-
backend: "official",
|
|
56
|
-
creds: { appId: "a", appSecret: "s" },
|
|
57
|
-
groupOpenid: "",
|
|
58
|
-
prefix: "[MC]"
|
|
59
|
-
},
|
|
60
|
-
"ch",
|
|
61
|
-
"Steve",
|
|
62
|
-
"hi",
|
|
63
|
-
"xuid"
|
|
64
|
-
);
|
|
65
|
-
});
|
|
66
|
-
});
|
|
67
|
-
test("forwardToQQBridge llbot\uFF1A\u7F3A\u7FA4\u53F7\u4E0D\u629B\u9519", () => {
|
|
68
|
-
assert.doesNotThrow(() => {
|
|
69
|
-
forwardToQQBridge(
|
|
70
|
-
{
|
|
71
|
-
backend: "llbot",
|
|
72
|
-
llbot: {
|
|
73
|
-
host: "127.0.0.1",
|
|
74
|
-
port: 3004,
|
|
75
|
-
token: "",
|
|
76
|
-
groupId: "0",
|
|
77
|
-
prefix: "[MC]"
|
|
78
|
-
}
|
|
79
|
-
},
|
|
80
|
-
"ch",
|
|
81
|
-
"Steve",
|
|
82
|
-
"hi",
|
|
83
|
-
"xuid"
|
|
84
|
-
);
|
|
85
|
-
});
|
|
86
|
-
});
|
|
87
|
-
//# sourceMappingURL=bridge.test.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/domain/bridge.test.ts"],
|
|
4
|
-
"sourcesContent": ["import assert from \"node:assert/strict\";\r\nimport test from \"node:test\";\r\nimport { makeLLBotConfig, makeOutboundConfig, forwardToQQBridge } from \"./bridge.js\";\r\n\r\ntest(\"makeOutboundConfig\uFF1Aofficial / llbot \u5206\u652F\", () => {\r\n const official = makeOutboundConfig({\r\n QQ_BACKEND: \"official\",\r\n LLBOT_HOST: \"127.0.0.1\",\r\n LLBOT_PORT: 3004,\r\n LLBOT_TOKEN: \"\",\r\n QQ_GROUP_ID: \"123\",\r\n QQ_APP_ID: \"app\",\r\n QQ_APP_SECRET: \"sec\",\r\n QQ_SANDBOX: true,\r\n QQ_GROUP_OPENID: \"GOPEN\",\r\n MCTOQQ_PREFIX: \"[MC]\",\r\n });\r\n assert.equal(official.backend, \"official\");\r\n if (official.backend === \"official\") {\r\n assert.equal(official.groupOpenid, \"GOPEN\");\r\n assert.equal(official.creds.sandbox, true);\r\n assert.equal(official.prefix, \"[MC]\");\r\n }\r\n\r\n const llbot = makeOutboundConfig({\r\n QQ_BACKEND: \"llbot\",\r\n LLBOT_HOST: \"127.0.0.1\",\r\n LLBOT_PORT: 3004,\r\n LLBOT_TOKEN: \"t\",\r\n QQ_GROUP_ID: \"99\",\r\n QQ_APP_ID: \"\",\r\n QQ_APP_SECRET: \"\",\r\n QQ_SANDBOX: false,\r\n QQ_GROUP_OPENID: \"\",\r\n MCTOQQ_PREFIX: \"[X]\",\r\n });\r\n assert.equal(llbot.backend, \"llbot\");\r\n if (llbot.backend === \"llbot\") {\r\n assert.equal(llbot.llbot.groupId, \"99\");\r\n assert.equal(llbot.llbot.prefix, \"[X]\");\r\n }\r\n});\r\n\r\ntest(\"makeLLBotConfig \u4F7F\u7528 mctoqq_prefix\", () => {\r\n const cfg = makeLLBotConfig({\r\n LLBOT_HOST: \"h\",\r\n LLBOT_PORT: 1,\r\n LLBOT_TOKEN: \"\",\r\n QQ_GROUP_ID: \"1\",\r\n MCTOQQ_PREFIX: \"[P]\",\r\n });\r\n assert.equal(cfg.prefix, \"[P]\");\r\n});\r\n\r\ntest(\"forwardToQQBridge official\uFF1A\u7F3A group_openid \u4E0D\u629B\u9519\", () => {\r\n assert.doesNotThrow(() => {\r\n forwardToQQBridge(\r\n {\r\n backend: \"official\",\r\n creds: { appId: \"a\", appSecret: \"s\" },\r\n groupOpenid: \"\",\r\n prefix: \"[MC]\",\r\n },\r\n \"ch\",\r\n \"Steve\",\r\n \"hi\",\r\n \"xuid\"\r\n );\r\n });\r\n});\r\n\r\ntest(\"forwardToQQBridge llbot\uFF1A\u7F3A\u7FA4\u53F7\u4E0D\u629B\u9519\", () => {\r\n assert.doesNotThrow(() => {\r\n forwardToQQBridge(\r\n {\r\n backend: \"llbot\",\r\n llbot: {\r\n host: \"127.0.0.1\",\r\n port: 3004,\r\n token: \"\",\r\n groupId: \"0\",\r\n prefix: \"[MC]\",\r\n },\r\n },\r\n \"ch\",\r\n \"Steve\",\r\n \"hi\",\r\n \"xuid\"\r\n );\r\n });\r\n});\r\n\r"],
|
|
5
|
-
"mappings": "AAAA,OAAO,YAAY;AACnB,OAAO,UAAU;AACjB,SAAS,iBAAiB,oBAAoB,yBAAyB;AAEvE,KAAK,yDAA0C,MAAM;AACnD,QAAM,WAAW,mBAAmB;AAAA,IAClC,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,aAAa;AAAA,IACb,aAAa;AAAA,IACb,WAAW;AAAA,IACX,eAAe;AAAA,IACf,YAAY;AAAA,IACZ,iBAAiB;AAAA,IACjB,eAAe;AAAA,EACjB,CAAC;AACD,SAAO,MAAM,SAAS,SAAS,UAAU;AACzC,MAAI,SAAS,YAAY,YAAY;AACnC,WAAO,MAAM,SAAS,aAAa,OAAO;AAC1C,WAAO,MAAM,SAAS,MAAM,SAAS,IAAI;AACzC,WAAO,MAAM,SAAS,QAAQ,MAAM;AAAA,EACtC;AAEA,QAAM,QAAQ,mBAAmB;AAAA,IAC/B,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,aAAa;AAAA,IACb,aAAa;AAAA,IACb,WAAW;AAAA,IACX,eAAe;AAAA,IACf,YAAY;AAAA,IACZ,iBAAiB;AAAA,IACjB,eAAe;AAAA,EACjB,CAAC;AACD,SAAO,MAAM,MAAM,SAAS,OAAO;AACnC,MAAI,MAAM,YAAY,SAAS;AAC7B,WAAO,MAAM,MAAM,MAAM,SAAS,IAAI;AACtC,WAAO,MAAM,MAAM,MAAM,QAAQ,KAAK;AAAA,EACxC;AACF,CAAC;AAED,KAAK,8CAAoC,MAAM;AAC7C,QAAM,MAAM,gBAAgB;AAAA,IAC1B,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,aAAa;AAAA,IACb,aAAa;AAAA,IACb,eAAe;AAAA,EACjB,CAAC;AACD,SAAO,MAAM,IAAI,QAAQ,KAAK;AAChC,CAAC;AAED,KAAK,0EAAiD,MAAM;AAC1D,SAAO,aAAa,MAAM;AACxB;AAAA,MACE;AAAA,QACE,SAAS;AAAA,QACT,OAAO,EAAE,OAAO,KAAK,WAAW,IAAI;AAAA,QACpC,aAAa;AAAA,QACb,QAAQ;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF,CAAC;AACH,CAAC;AAED,KAAK,qEAAkC,MAAM;AAC3C,SAAO,aAAa,MAAM;AACxB;AAAA,MACE;AAAA,QACE,SAAS;AAAA,QACT,OAAO;AAAA,UACL,MAAM;AAAA,UACN,MAAM;AAAA,UACN,OAAO;AAAA,UACP,SAAS;AAAA,UACT,QAAQ;AAAA,QACV;AAAA,MACF;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF,CAAC;AACH,CAAC;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"messages-bridge-filter.test.d.ts","sourceRoot":"","sources":["../../src/domain/messages-bridge-filter.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import assert from "node:assert/strict";
|
|
2
|
-
import test from "node:test";
|
|
3
|
-
import { shouldForwardChatToQQ } from "../routes/messages.js";
|
|
4
|
-
test("shouldForwardChatToQQ\uFF1A\u672A\u914D bridge \u4E0D\u51FA\u7AD9", () => {
|
|
5
|
-
assert.equal(shouldForwardChatToQQ("", "bridge", "xuid"), false);
|
|
6
|
-
});
|
|
7
|
-
test("shouldForwardChatToQQ\uFF1A\u9891\u9053\u4E0D\u5339\u914D\u4E0D\u51FA\u7AD9", () => {
|
|
8
|
-
assert.equal(shouldForwardChatToQQ("bridge", "other", "xuid"), false);
|
|
9
|
-
});
|
|
10
|
-
test("shouldForwardChatToQQ\uFF1Aqq_ \u6765\u6E90\u4E0D\u51FA\u7AD9\uFF08\u9632\u56DE\u73AF\uFF09", () => {
|
|
11
|
-
assert.equal(shouldForwardChatToQQ("bridge", "bridge", "qq_123"), false);
|
|
12
|
-
});
|
|
13
|
-
test("shouldForwardChatToQQ\uFF1A\u7A7A fromId \u4E0D\u51FA\u7AD9", () => {
|
|
14
|
-
assert.equal(shouldForwardChatToQQ("bridge", "bridge", ""), false);
|
|
15
|
-
assert.equal(shouldForwardChatToQQ("bridge", "bridge", " "), false);
|
|
16
|
-
});
|
|
17
|
-
test("shouldForwardChatToQQ\uFF1A\u5339\u914D\u9891\u9053\u7684\u73A9\u5BB6\u6D88\u606F\u51FA\u7AD9", () => {
|
|
18
|
-
assert.equal(shouldForwardChatToQQ("bridge", "bridge", "player-1"), true);
|
|
19
|
-
});
|
|
20
|
-
//# sourceMappingURL=messages-bridge-filter.test.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/domain/messages-bridge-filter.test.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * messages \u51FA\u7AD9\u8FC7\u6EE4\u5355\u6D4B\n */\n\nimport assert from \"node:assert/strict\";\nimport test from \"node:test\";\nimport { shouldForwardChatToQQ } from \"../routes/messages.js\";\n\ntest(\"shouldForwardChatToQQ\uFF1A\u672A\u914D bridge \u4E0D\u51FA\u7AD9\", () => {\n assert.equal(shouldForwardChatToQQ(\"\", \"bridge\", \"xuid\"), false);\n});\n\ntest(\"shouldForwardChatToQQ\uFF1A\u9891\u9053\u4E0D\u5339\u914D\u4E0D\u51FA\u7AD9\", () => {\n assert.equal(shouldForwardChatToQQ(\"bridge\", \"other\", \"xuid\"), false);\n});\n\ntest(\"shouldForwardChatToQQ\uFF1Aqq_ \u6765\u6E90\u4E0D\u51FA\u7AD9\uFF08\u9632\u56DE\u73AF\uFF09\", () => {\n assert.equal(shouldForwardChatToQQ(\"bridge\", \"bridge\", \"qq_123\"), false);\n});\n\ntest(\"shouldForwardChatToQQ\uFF1A\u7A7A fromId \u4E0D\u51FA\u7AD9\", () => {\n assert.equal(shouldForwardChatToQQ(\"bridge\", \"bridge\", \"\"), false);\n assert.equal(shouldForwardChatToQQ(\"bridge\", \"bridge\", \" \"), false);\n});\n\ntest(\"shouldForwardChatToQQ\uFF1A\u5339\u914D\u9891\u9053\u7684\u73A9\u5BB6\u6D88\u606F\u51FA\u7AD9\", () => {\n assert.equal(shouldForwardChatToQQ(\"bridge\", \"bridge\", \"player-1\"), true);\n});\n"],
|
|
5
|
-
"mappings": "AAIA,OAAO,YAAY;AACnB,OAAO,UAAU;AACjB,SAAS,6BAA6B;AAEtC,KAAK,qEAAuC,MAAM;AAChD,SAAO,MAAM,sBAAsB,IAAI,UAAU,MAAM,GAAG,KAAK;AACjE,CAAC;AAED,KAAK,+EAAkC,MAAM;AAC3C,SAAO,MAAM,sBAAsB,UAAU,SAAS,MAAM,GAAG,KAAK;AACtE,CAAC;AAED,KAAK,+FAAwC,MAAM;AACjD,SAAO,MAAM,sBAAsB,UAAU,UAAU,QAAQ,GAAG,KAAK;AACzE,CAAC;AAED,KAAK,+DAAsC,MAAM;AAC/C,SAAO,MAAM,sBAAsB,UAAU,UAAU,EAAE,GAAG,KAAK;AACjE,SAAO,MAAM,sBAAsB,UAAU,UAAU,KAAK,GAAG,KAAK;AACtE,CAAC;AAED,KAAK,iGAAqC,MAAM;AAC9C,SAAO,MAAM,sBAAsB,UAAU,UAAU,UAAU,GAAG,IAAI;AAC1E,CAAC;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"player-session.test.d.ts","sourceRoot":"","sources":["../../src/domain/player-session.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import assert from "node:assert/strict";
|
|
2
|
-
import { DatabaseSync } from "node:sqlite";
|
|
3
|
-
import test from "node:test";
|
|
4
|
-
import { createQuery } from "../lib/sqlite.js";
|
|
5
|
-
import { syncPlayerSession } from "./player-session.js";
|
|
6
|
-
import { initSchema } from "./schema.js";
|
|
7
|
-
test("initSchema \u4E3A\u65E7\u73A9\u5BB6\u8868\u8865\u9F50\u5FEB\u7167\u5B57\u6BB5", () => {
|
|
8
|
-
const db = new DatabaseSync(":memory:");
|
|
9
|
-
db.exec("CREATE TABLE sfmc_players (id TEXT PRIMARY KEY, name TEXT, xuid TEXT)");
|
|
10
|
-
initSchema(db);
|
|
11
|
-
const columns = db.prepare('PRAGMA table_info("sfmc_players")').all();
|
|
12
|
-
const names = new Set(columns.map((column) => column.name));
|
|
13
|
-
for (const name of [
|
|
14
|
-
"spawn_dimension",
|
|
15
|
-
"spawn_x",
|
|
16
|
-
"dimension",
|
|
17
|
-
"game_mode",
|
|
18
|
-
"snapshot_hash",
|
|
19
|
-
"active_channel",
|
|
20
|
-
"subscribed_channels"
|
|
21
|
-
]) {
|
|
22
|
-
assert.equal(names.has(name), true, name);
|
|
23
|
-
}
|
|
24
|
-
});
|
|
25
|
-
test("BDS \u73A9\u5BB6\u4F1A\u8BDD\u5199\u5165\u5E76\u5237\u65B0 XUID", () => {
|
|
26
|
-
const db = new DatabaseSync(":memory:");
|
|
27
|
-
initSchema(db);
|
|
28
|
-
const query = createQuery(db);
|
|
29
|
-
syncPlayerSession(query, { playerName: "Steve", xuid: "123" }, 42);
|
|
30
|
-
const row = db.prepare("SELECT id, name, xuid, last_online FROM sfmc_players WHERE id = ?").get("123");
|
|
31
|
-
assert.deepEqual({ ...row }, { id: "123", name: "Steve", xuid: "123", last_online: 42 });
|
|
32
|
-
});
|
|
33
|
-
//# sourceMappingURL=player-session.test.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/domain/player-session.test.ts"],
|
|
4
|
-
"sourcesContent": ["import assert from \"node:assert/strict\";\nimport { DatabaseSync } from \"node:sqlite\";\nimport test from \"node:test\";\nimport { createQuery } from \"../lib/sqlite.js\";\nimport { syncPlayerSession } from \"./player-session.js\";\nimport { initSchema } from \"./schema.js\";\n\ntest(\"initSchema \u4E3A\u65E7\u73A9\u5BB6\u8868\u8865\u9F50\u5FEB\u7167\u5B57\u6BB5\", () => {\n const db = new DatabaseSync(\":memory:\");\n db.exec(\"CREATE TABLE sfmc_players (id TEXT PRIMARY KEY, name TEXT, xuid TEXT)\");\n initSchema(db);\n const columns = db.prepare('PRAGMA table_info(\"sfmc_players\")').all() as Array<{ name: string }>;\n const names = new Set(columns.map((column) => column.name));\n for (const name of [\n \"spawn_dimension\",\n \"spawn_x\",\n \"dimension\",\n \"game_mode\",\n \"snapshot_hash\",\n \"active_channel\",\n \"subscribed_channels\",\n ]) {\n assert.equal(names.has(name), true, name);\n }\n});\n\ntest(\"BDS \u73A9\u5BB6\u4F1A\u8BDD\u5199\u5165\u5E76\u5237\u65B0 XUID\", () => {\n const db = new DatabaseSync(\":memory:\");\n initSchema(db);\n const query = createQuery(db);\n syncPlayerSession(query, { playerName: \"Steve\", xuid: \"123\" }, 42);\n const row = db.prepare(\"SELECT id, name, xuid, last_online FROM sfmc_players WHERE id = ?\").get(\"123\");\n assert.deepEqual({ ...row }, { id: \"123\", name: \"Steve\", xuid: \"123\", last_online: 42 });\n});\n"],
|
|
5
|
-
"mappings": "AAAA,OAAO,YAAY;AACnB,SAAS,oBAAoB;AAC7B,OAAO,UAAU;AACjB,SAAS,mBAAmB;AAC5B,SAAS,yBAAyB;AAClC,SAAS,kBAAkB;AAE3B,KAAK,iFAA0B,MAAM;AACnC,QAAM,KAAK,IAAI,aAAa,UAAU;AACtC,KAAG,KAAK,uEAAuE;AAC/E,aAAW,EAAE;AACb,QAAM,UAAU,GAAG,QAAQ,mCAAmC,EAAE,IAAI;AACpE,QAAM,QAAQ,IAAI,IAAI,QAAQ,IAAI,CAAC,WAAW,OAAO,IAAI,CAAC;AAC1D,aAAW,QAAQ;AAAA,IACjB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAAG;AACD,WAAO,MAAM,MAAM,IAAI,IAAI,GAAG,MAAM,IAAI;AAAA,EAC1C;AACF,CAAC;AAED,KAAK,mEAAsB,MAAM;AAC/B,QAAM,KAAK,IAAI,aAAa,UAAU;AACtC,aAAW,EAAE;AACb,QAAM,QAAQ,YAAY,EAAE;AAC5B,oBAAkB,OAAO,EAAE,YAAY,SAAS,MAAM,MAAM,GAAG,EAAE;AACjE,QAAM,MAAM,GAAG,QAAQ,mEAAmE,EAAE,IAAI,KAAK;AACrG,SAAO,UAAU,EAAE,GAAG,IAAI,GAAG,EAAE,IAAI,OAAO,MAAM,SAAS,MAAM,OAAO,aAAa,GAAG,CAAC;AACzF,CAAC;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"qq-bind-status.test.d.ts","sourceRoot":"","sources":["../../src/domain/qq-bind-status.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,211 +0,0 @@
|
|
|
1
|
-
import assert from "node:assert/strict";
|
|
2
|
-
import test from "node:test";
|
|
3
|
-
import { DatabaseSync } from "node:sqlite";
|
|
4
|
-
import { SQL } from "sql-template-strings";
|
|
5
|
-
import { initSchema } from "./schema.js";
|
|
6
|
-
import { createQuery } from "../lib/sqlite.js";
|
|
7
|
-
import { createStatusRoutes, FRESH_MS } from "../routes/status.js";
|
|
8
|
-
import { createQqBindRoutes } from "../routes/qq-bind.js";
|
|
9
|
-
function memDb() {
|
|
10
|
-
const db = new DatabaseSync(":memory:");
|
|
11
|
-
initSchema(db);
|
|
12
|
-
return { db, query: createQuery(db) };
|
|
13
|
-
}
|
|
14
|
-
function mockRes() {
|
|
15
|
-
let status = 200;
|
|
16
|
-
let body = {};
|
|
17
|
-
return {
|
|
18
|
-
res: {
|
|
19
|
-
writeHead(code) {
|
|
20
|
-
status = code;
|
|
21
|
-
},
|
|
22
|
-
end(s) {
|
|
23
|
-
body = JSON.parse(s);
|
|
24
|
-
},
|
|
25
|
-
setHeader() {
|
|
26
|
-
}
|
|
27
|
-
},
|
|
28
|
-
get status() {
|
|
29
|
-
return status;
|
|
30
|
-
},
|
|
31
|
-
get body() {
|
|
32
|
-
return body;
|
|
33
|
-
}
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
test("initSchema \u542B qq bind \u8868", () => {
|
|
37
|
-
const { db } = memDb();
|
|
38
|
-
const tables = db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name LIKE 'sfmc_qq_%' ORDER BY name").all();
|
|
39
|
-
const names = tables.map((t) => t.name);
|
|
40
|
-
assert.ok(names.includes("sfmc_qq_bind_pending"));
|
|
41
|
-
assert.ok(names.includes("sfmc_qq_bindings"));
|
|
42
|
-
assert.ok(names.includes("sfmc_qq_join_requests"));
|
|
43
|
-
assert.ok(names.includes("sfmc_qq_admin_actions"));
|
|
44
|
-
assert.ok(FRESH_MS > 0);
|
|
45
|
-
});
|
|
46
|
-
test("GET /api/sfmc/status \u7A7A\u8868\u4E0D\u629B\u9519", async () => {
|
|
47
|
-
const { query } = memDb();
|
|
48
|
-
const handle = createStatusRoutes({
|
|
49
|
-
query,
|
|
50
|
-
collectSystem: async () => ({
|
|
51
|
-
host: {
|
|
52
|
-
hostname: "test-host",
|
|
53
|
-
platform: "win32",
|
|
54
|
-
arch: "x64",
|
|
55
|
-
release: "10.0",
|
|
56
|
-
uptimeSec: 3600,
|
|
57
|
-
uptimeText: "1\u65F60\u5206",
|
|
58
|
-
cpu: { model: "Test CPU", cores: 4 },
|
|
59
|
-
memory: { totalMb: 8192, freeMb: 4096, usedMb: 4096, usedPercent: 50 },
|
|
60
|
-
loadavg: [0, 0, 0]
|
|
61
|
-
},
|
|
62
|
-
db: { pid: 1, running: true, uptimeSec: 10, uptimeText: "10\u79D2" },
|
|
63
|
-
bds: { state: "stopped", running: false, pid: 0, uptimeSec: null, uptimeText: "\u672A\u8FD0\u884C" }
|
|
64
|
-
})
|
|
65
|
-
});
|
|
66
|
-
const m = mockRes();
|
|
67
|
-
const ok = await handle({
|
|
68
|
-
path: "/api/sfmc/status",
|
|
69
|
-
method: "GET",
|
|
70
|
-
params: new URLSearchParams(),
|
|
71
|
-
req: {},
|
|
72
|
-
res: m.res
|
|
73
|
-
});
|
|
74
|
-
assert.equal(ok, true);
|
|
75
|
-
assert.equal(m.status, 200);
|
|
76
|
-
assert.ok(Array.isArray(m.body.online));
|
|
77
|
-
assert.equal(m.body.online.length, 0);
|
|
78
|
-
assert.equal(m.body.host.hostname, "test-host");
|
|
79
|
-
assert.equal(m.body.processes.bds.state, "stopped");
|
|
80
|
-
});
|
|
81
|
-
test("bind request \u2192 confirm \u2192 me \u2192 unbind + \u51B2\u7A81", async () => {
|
|
82
|
-
const { query } = memDb();
|
|
83
|
-
let bodyData = {};
|
|
84
|
-
const handle = createQqBindRoutes({
|
|
85
|
-
query,
|
|
86
|
-
body: async () => bodyData,
|
|
87
|
-
json: (res, data, status = 200) => {
|
|
88
|
-
res.writeHead(status);
|
|
89
|
-
res.end(JSON.stringify(data));
|
|
90
|
-
}
|
|
91
|
-
});
|
|
92
|
-
bodyData = { openid: "oa", qq_backend: "official" };
|
|
93
|
-
let m = mockRes();
|
|
94
|
-
await handle({
|
|
95
|
-
path: "/api/sfmc/qq/bind/request",
|
|
96
|
-
method: "POST",
|
|
97
|
-
params: new URLSearchParams(),
|
|
98
|
-
req: {},
|
|
99
|
-
res: m.res
|
|
100
|
-
});
|
|
101
|
-
assert.equal(m.body.success, true);
|
|
102
|
-
const code = String(m.body.code);
|
|
103
|
-
assert.match(code, /^\d{6}$/);
|
|
104
|
-
bodyData = { code, xuid: "x1", name: "Steve" };
|
|
105
|
-
m = mockRes();
|
|
106
|
-
await handle({
|
|
107
|
-
path: "/api/sfmc/qq/bind/confirm",
|
|
108
|
-
method: "POST",
|
|
109
|
-
params: new URLSearchParams(),
|
|
110
|
-
req: {},
|
|
111
|
-
res: m.res
|
|
112
|
-
});
|
|
113
|
-
assert.equal(m.body.success, true);
|
|
114
|
-
m = mockRes();
|
|
115
|
-
await handle({
|
|
116
|
-
path: "/api/sfmc/qq/bind/me",
|
|
117
|
-
method: "GET",
|
|
118
|
-
params: new URLSearchParams("openid=oa"),
|
|
119
|
-
req: {},
|
|
120
|
-
res: m.res
|
|
121
|
-
});
|
|
122
|
-
assert.equal(m.body.bound, true);
|
|
123
|
-
assert.equal(m.body.binding.player_name, "Steve");
|
|
124
|
-
bodyData = { openid: "ob", qq_backend: "official" };
|
|
125
|
-
m = mockRes();
|
|
126
|
-
await handle({
|
|
127
|
-
path: "/api/sfmc/qq/bind/request",
|
|
128
|
-
method: "POST",
|
|
129
|
-
params: new URLSearchParams(),
|
|
130
|
-
req: {},
|
|
131
|
-
res: m.res
|
|
132
|
-
});
|
|
133
|
-
const code2 = String(m.body.code);
|
|
134
|
-
bodyData = { code: code2, xuid: "x1", name: "Alex" };
|
|
135
|
-
m = mockRes();
|
|
136
|
-
await handle({
|
|
137
|
-
path: "/api/sfmc/qq/bind/confirm",
|
|
138
|
-
method: "POST",
|
|
139
|
-
params: new URLSearchParams(),
|
|
140
|
-
req: {},
|
|
141
|
-
res: m.res
|
|
142
|
-
});
|
|
143
|
-
assert.equal(m.body.success, false);
|
|
144
|
-
assert.equal(m.body.error, "player_already_bound");
|
|
145
|
-
bodyData = { openid: "oa" };
|
|
146
|
-
m = mockRes();
|
|
147
|
-
await handle({
|
|
148
|
-
path: "/api/sfmc/qq/bind/unbind",
|
|
149
|
-
method: "POST",
|
|
150
|
-
params: new URLSearchParams(),
|
|
151
|
-
req: {},
|
|
152
|
-
res: m.res
|
|
153
|
-
});
|
|
154
|
-
assert.equal(m.body.unbound, true);
|
|
155
|
-
bodyData = { openid: "oa", qq_backend: "official" };
|
|
156
|
-
m = mockRes();
|
|
157
|
-
await handle({
|
|
158
|
-
path: "/api/sfmc/qq/bind/request",
|
|
159
|
-
method: "POST",
|
|
160
|
-
params: new URLSearchParams(),
|
|
161
|
-
req: {},
|
|
162
|
-
res: m.res
|
|
163
|
-
});
|
|
164
|
-
assert.equal(m.body.success, true);
|
|
165
|
-
});
|
|
166
|
-
test("status \u65B0\u9C9C\u73A9\u5BB6\u8BA1\u5165 online", async () => {
|
|
167
|
-
const { query } = memDb();
|
|
168
|
-
const now = Date.now();
|
|
169
|
-
query(
|
|
170
|
-
SQL`INSERT INTO sfmc_players (id, name, updated_at) VALUES ('p1', 'Steve', ${now})`
|
|
171
|
-
);
|
|
172
|
-
query(
|
|
173
|
-
SQL`INSERT INTO sfmc_world (day, difficulty, updated_at) VALUES (3, 'normal', ${String(now)})`
|
|
174
|
-
);
|
|
175
|
-
const handle = createStatusRoutes({
|
|
176
|
-
query,
|
|
177
|
-
collectSystem: async () => ({
|
|
178
|
-
host: {
|
|
179
|
-
hostname: "h",
|
|
180
|
-
platform: "linux",
|
|
181
|
-
arch: "x64",
|
|
182
|
-
release: "6",
|
|
183
|
-
uptimeSec: 1,
|
|
184
|
-
uptimeText: "1\u79D2",
|
|
185
|
-
cpu: { model: "c", cores: 2 },
|
|
186
|
-
memory: { totalMb: 1, freeMb: 1, usedMb: 0, usedPercent: 0 },
|
|
187
|
-
loadavg: [0, 0, 0]
|
|
188
|
-
},
|
|
189
|
-
db: { pid: 1, running: true, uptimeSec: 1, uptimeText: "1\u79D2" },
|
|
190
|
-
bds: {
|
|
191
|
-
state: "running",
|
|
192
|
-
running: true,
|
|
193
|
-
pid: 99,
|
|
194
|
-
uptimeSec: 120,
|
|
195
|
-
uptimeText: "2\u52060\u79D2"
|
|
196
|
-
}
|
|
197
|
-
})
|
|
198
|
-
});
|
|
199
|
-
const m = mockRes();
|
|
200
|
-
await handle({
|
|
201
|
-
path: "/api/sfmc/status",
|
|
202
|
-
method: "GET",
|
|
203
|
-
params: new URLSearchParams(),
|
|
204
|
-
req: {},
|
|
205
|
-
res: m.res
|
|
206
|
-
});
|
|
207
|
-
assert.equal(m.body.online.length, 1);
|
|
208
|
-
assert.equal(m.body.world.day, 3);
|
|
209
|
-
assert.equal(m.body.processes.bds.pid, 99);
|
|
210
|
-
});
|
|
211
|
-
//# sourceMappingURL=qq-bind-status.test.js.map
|