121 lines
3.2 KiB
TypeScript
121 lines
3.2 KiB
TypeScript
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);
|
||
}
|
||
})
|
||
}
|
||
}
|