Commit 2264b8a3 authored by Chunchi Che's avatar Chunchi Che

add env 408 cdb

parent 4d3a42d2
Pipeline #30287 failed with stages
in 8 minutes and 6 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",
......
......@@ -12,10 +12,11 @@ import {
import { CONTAINERS } from ".";
import { Context } from "./context";
import { Container } from "./impl";
import { YgoCdb } from "@/middleware/sqlite";
const UI_KEY = "NEOS_UI";
export function initUIContainer(conn: WebSocketStream) {
export function initUIContainer(conn: WebSocketStream, cdb: YgoCdb) {
const context = new Context({
matStore,
cardStore,
......@@ -25,7 +26,7 @@ export function initUIContainer(conn: WebSocketStream) {
sideStore,
historyStore,
});
const container = new Container(context, conn);
const container = new Container(context, conn, cdb);
CONTAINERS.set(UI_KEY, container);
}
......
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(
......@@ -193,3 +167,6 @@ export function constructCardMeta(
text,
};
}
export const OCG_CDB: YgoCdb = new YgoCdb();
export const ENV_408_CDB: YgoCdb = new YgoCdb();
......@@ -10,26 +10,39 @@ import {
} from "@/api";
import { useConfig } from "@/config";
import { useEnv } from "@/hook";
import sqliteMiddleWare, { sqliteCmd } from "@/middleware/sqlite";
import { accountStore, deckStore, initStore, type User } from "@/stores";
const { releaseResource, preReleaseResource } = useConfig();
import { ENV_408_CDB, OCG_CDB } from "@/middleware/sqlite";
const { releaseResource, preReleaseResource, env408Resource } = useConfig();
const { BASE_URL } = useEnv();
/** 加载ygodb */
export const initSqlite = async () => {
/** 加载 OCG ygodb */
export const initOCGCdb = async () => {
if (!initStore.sqlite.progress) {
const { sqlite } = initStore;
const progressCallback = (progress: number) =>
(sqlite.progress = progress * 0.9);
sqlite.progress = 0.01;
await sqliteMiddleWare({
cmd: sqliteCmd.INIT,
initInfo: {
releaseDbUrl: releaseResource.cdb,
preReleaseDbUrl: preReleaseResource.cdb,
progressCallback,
},
await OCG_CDB.init({
main: releaseResource.cdb, sub: preReleaseResource.cdb, i18n: true, progressCallback
});
sqlite.progress = 1;
}
};
/** 加载 408 环境 ygodb */
export const init408Cdb = async () => {
if (!initStore.sqlite.progress) {
const { sqlite } = initStore;
const progressCallback = (progress: number) =>
(sqlite.progress = progress * 0.9);
sqlite.progress = 0.01;
await ENV_408_CDB.init({
main: env408Resource.cdb, i18n: false, progressCallback
});
sqlite.progress = 1;
}
};
......
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