Files
YoumiHaAPI/src/controller/versionlist.controller.ts

121 lines
3.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { createHash } from "node:crypto";
import { Pool } from "pg";
import { ILibraries, ILibrariesMap, IVersion, IVersionPool } from "../types/versionlist.types.js";
export class VersionListController {
versionCache: IVersion[];
private pool: Pool;
hashList: string[];
libmap: Map<string, ILibrariesMap>;
constructor(pool: Pool) {
this.pool = pool;
this.versionCache = [];
this.hashList = ["md5", "sha1", "sha256"];
this.libmap = new Map();
this._refreshCache(); // 初始化缓存
setInterval(this._refreshCache.bind(this), 1000 * 60 * 60 * 2); // 2小时刷新缓存傻逼this
setInterval(this._refreshLib.bind(this),1000*60*60*1) // 1小时刷新libmap
}
async getVersionList() {
if (this.versionCache.length === 0) {
await this._refreshCache();
}
console.log("use cache");
return this.versionCache;
}
private async _refreshCache() {
const arr: any[] = [];
const result = (
await this.pool.query(`
SELECT mcversion."version",
mcversion."Type",
mcversion."Date",
array_agg(DISTINCT variation.arch) as arch,
variation."OSbuild"
FROM variation
LEFT JOIN mcversion ON mcversion.id = variation."MCVId"
GROUP BY mcversion."version", mcversion."Type", mcversion."Date", variation."OSbuild"
ORDER BY "Date" DESC
`)
).rows;
result.forEach((row: IVersionPool) => {
const url: string[] = [];
for (const arch of row.arch) {
url.push(`./mc/version/${row.version}/${arch}`);
}
arr.push({
id: row.version,
type: row.Type,
BuildType: "UWP",
OSBuild: row.OSbuild,
Arch: row.arch,
url,
time: row.Date,
});
});
this.versionCache = arr;
}
async getLibraries(id: string, arch: string) {
const archs = ["x64", "x86", "arm"];
if (
!archs.includes(arch) ||
this.versionCache.filter((v) => v.id === id).length === 0
) {
return;
}
const ver = `${id}-${arch}`
let value = this.libmap.get(ver)
if (value){
value.hits++
console.log("lib hits"+value.hits)
return {libraries:value.libraries}
}
const r = (
await this.pool.query(
`
SELECT variation.id
FROM variation
LEFT JOIN mcversion ON mcversion.id = variation."MCVId"
WHERE mcversion."versionHash" = $1
AND variation.arch = $2
LIMIT 1
`,
[createHash("sha256").update(id).digest(), arch]
)
).rows; // 获取版本id
const data: ILibraries[] = (
await this.pool.query(
`
SELECT "filePathName"."pathName",
"filesHash"."size",
${this.hashList
.map((hash) => `encode("filesHash"."${hash}", 'hex') as "${hash}"`)
.join(", ")}
FROM variation_files_data
LEFT JOIN files ON files.id = variation_files_data."filesId"
LEFT JOIN "filePathName" ON "filePathName".id = files."pathNameId"
LEFT JOIN "filesHash" ON "filesHash".id = files."hashId"
WHERE variation_files_data."variationId" = $1
`,
[r[0].id]
)
).rows; //获取信息
this.libmap.set(ver,{libraries:data,hits:0}) //初始化
return { libraries: data};
}
_refreshLib(){
this.libmap.forEach((val,key)=>{
if (val.hits<15){
this.libmap.delete(key);
}
})
}
}