Commit b0857ffd authored by Chunchi Che's avatar Chunchi Che

add env 408 cdb

parent 4d3a42d2
Pipeline #30286 failed with stages
in 9 seconds
......@@ -39,6 +39,10 @@
"lflist": "https://cdn02.moecube.com:444/ygopro-database/zh-CN/lflist.conf",
"config": "https://cdn02.moecube.com:444/ygopro-super-pre/data/test-release-v2.json"
},
"env408Resource": {
"cdb": "https://cdn02.moecube.com:444/cn-database/env408-zh-CN/expansions/env408.cdb",
"lflist": "https://cdn02.moecube.com:444/cn-database/env408-zh-CN/expansions/lflist.conf"
},
"stringsUrl": "https://cdn02.moecube.com:444/ygopro-database/zh-CN/strings.conf",
"replayUrl": "replay.neos.moe",
"loginUrl": "https://accounts.moecube.com/signin",
......
......@@ -39,6 +39,10 @@
"lflist": "https://cdn02.moecube.com:444/ygopro-database/zh-CN/lflist.conf",
"config": "https://cdn02.moecube.com:444/ygopro-super-pre/data/test-release-v2.json"
},
"env408Resource": {
"cdb": "https://cdn02.moecube.com:444/cn-database/env408-zh-CN/expansions/env408.cdb",
"lflist": "https://cdn02.moecube.com:444/cn-database/env408-zh-CN/expansions/lflist.conf"
},
"stringsUrl": "https://cdn02.moecube.com:444/ygopro-database/zh-CN/strings.conf",
"replayUrl": "replay.neos.moe",
"loginUrl": "https://accounts.moecube.com/signin",
......
import { WebSocketStream } from "@/infra";
import { Context } from "./context";
import { YgoCdb } from "@/middleware/sqlite";
export class Container {
public context: Context;
public conn: WebSocketStream;
public cdb: YgoCdb;
// ref: https://yugioh.fandom.com/wiki/Kuriboh
private enableKuriboh: boolean = false;
constructor(context: Context, conn: WebSocketStream) {
constructor(context: Context, conn: WebSocketStream, cdb: YgoCdb) {
this.context = context;
this.conn = conn;
this.cdb = cdb;
}
public setEnableKuriboh(value: boolean) {
......
......@@ -39,6 +39,13 @@ export interface sqliteAction<T extends sqliteCmd> {
};
}
interface CdbInitInfo {
main: string;
sub?: string;
i18n: boolean;
progressCallback?: (progress: number) => void; // 用于获取读取进度
}
export interface sqliteResult {
selectResult?: CardMeta;
ftsResult?: CardMeta[];
......@@ -48,23 +55,88 @@ const sqlPromise = initSqlJs({
locateFile: (file) => `${NeosConfig.assetsPath}/${file}`,
});
export default function <T extends sqliteCmd>(
action: sqliteAction<T>,
): T extends sqliteCmd.INIT ? Promise<void> : sqliteResult {
return helper(action) as any;
}
export class YgoCdb {
private main?: Database;
private sub?: Database;
// TODO: may defining a class be better?
interface YgoDbs {
release: Database | null;
preRelease: Database | null;
}
constructor() {}
public async init(info: CdbInitInfo): Promise<void> {
if (info.i18n) {
const language = localStorage.getItem("language") ?? "cn";
// Update URLs based on the language
updateDbUrls(info, language);
}
const promises = [pfetch(info.main, {
progressCallback: info.progressCallback,
}).then((res) => res.arrayBuffer())];
if (info.sub !== undefined) {
promises.push(pfetch(info.sub, {
progressCallback: info.progressCallback,
}).then((res) => res.arrayBuffer()));
}
const sql = await sqlPromise;
let YGODBS: YgoDbs = { release: null, preRelease: null };
return Promise.all(promises).then(([mainBuffer, subBuffer]) => {
this.main = new sql.Database(new Uint8Array(mainBuffer));
this.sub = new sql.Database(
new Uint8Array(subBuffer),
);
console.log("YGODB inited!");
});
}
public select(code: number): sqliteResult {
if (
this.main
) {
const db = isSuperReleaseCard(code)
? this.sub! // must be initialized when `isSuperReleaseCard` return true
: this.main;
const dataStmt = db.prepare("SELECT * FROM datas WHERE ID = $id");
const dataResult = dataStmt.getAsObject({ $id: code });
const textStmt = db.prepare("SELECT * FROM texts WHERE ID = $id");
const textResult = textStmt.getAsObject({ $id: code });
return {
selectResult: constructCardMeta(code, dataResult, textResult),
};
} else {
console.warn("ygo cdb not init!");
return {};
}
}
public fts(params: FtsParams): sqliteResult {
if (
this.main
) {
let metas = invokeFts(
this.main,
params,
);
if (this.sub !== undefined) {
metas = metas.concat(invokeFts(this.sub, params));
}
return { ftsResult: metas };
} else {
console.warn("ygo db not init!");
return {};
}
}
}
//It currently only supports en-US, es-ES, ja-JP, ko-KR, zh-CN
// Function to update URLs based on the language
function updateDbUrls(info: any, language: string): void {
//
// Note: it currently only supports en-US, es-ES, ja-JP, ko-KR, zh-CN for main cdb
function updateDbUrls(info: CdbInitInfo, language: string): void {
const languageMap: { [key: string]: string } = {
en: "en-US",
br: "en-US",
......@@ -75,106 +147,8 @@ function updateDbUrls(info: any, language: string): void {
es: "es-ES",
};
const locale = languageMap[language] || "zh-CN";
info.releaseDbUrl = info.releaseDbUrl.replace("zh-CN", locale);
info.preReleaseDbUrl = info.preReleaseDbUrl.replace("zh-CN", locale);
}
// FIXME: 应该有个返回值,告诉业务方本次请求的结果,比如初始化DB失败
function helper<T extends sqliteCmd>(action: sqliteAction<T>) {
switch (action.cmd) {
case sqliteCmd.INIT: {
const info = action.initInfo;
if (info) {
const language = localStorage.getItem("language") || "cn";
// Update URLs based on the language
updateDbUrls(info, language);
const releasePromise = pfetch(info.releaseDbUrl, {
progressCallback: action.initInfo?.progressCallback,
}).then((res) => res.arrayBuffer()); // TODO: i18n
const preReleasePromise = pfetch(info.preReleaseDbUrl, {
progressCallback: action.initInfo?.progressCallback,
}).then((res) => res.arrayBuffer());
return Promise.all([
sqlPromise,
releasePromise,
preReleasePromise,
]).then(([SQL, releaseBuffer, preReleaseBuffer]) => {
YGODBS.release = new SQL.Database(new Uint8Array(releaseBuffer));
YGODBS.preRelease = new SQL.Database(
new Uint8Array(preReleaseBuffer),
);
console.log("YGODB inited!");
});
} else {
console.warn("init YGODB action without initInfo");
return {};
}
}
case sqliteCmd.SELECT: {
if (
YGODBS.release &&
YGODBS.preRelease &&
action.payload &&
action.payload.id
) {
const code = action.payload.id;
const db = isSuperReleaseCard(code)
? YGODBS.preRelease
: YGODBS.release;
const dataStmt = db.prepare("SELECT * FROM datas WHERE ID = $id");
const dataResult = dataStmt.getAsObject({ $id: code });
const textStmt = db.prepare("SELECT * FROM texts WHERE ID = $id");
const textResult = textStmt.getAsObject({ $id: code });
return {
selectResult: constructCardMeta(code, dataResult, textResult),
};
} else {
if (action.payload?.id !== 0) {
// 0是无效的卡片ID,不需要报错,返回空即可
console.warn("ygo db not init or id not provied!");
}
}
return {};
}
case sqliteCmd.FTS: {
if (
YGODBS.release &&
YGODBS.preRelease &&
action.payload &&
action.payload.ftsParams
) {
const releaseMetas = invokeFts(
YGODBS.release,
action.payload.ftsParams,
);
const preReleaseMetas = invokeFts(
YGODBS.preRelease,
action.payload.ftsParams,
);
const metas = releaseMetas.concat(preReleaseMetas);
return { ftsResult: metas };
} else {
console.warn("ygo db not init or query not provied!");
}
return {};
}
default: {
console.warn(`Unhandled sqlite command: ${action.cmd}`);
return {};
}
}
const locale = languageMap[language] ?? "zh-CN";
info.main = info.main.replace("zh-CN", locale);
}
export function constructCardMeta(
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment