feat:缓存与hash下载
This commit is contained in:
@@ -1,16 +1,20 @@
|
||||
import { createHash } from "node:crypto";
|
||||
import { Pool } from "pg";
|
||||
import { ILibraries, ILibrariesMap, IVersion, IVersionPool } from "../types/versionlist.types.js";
|
||||
|
||||
export class VersionListController {
|
||||
versionCache: Version[];
|
||||
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, 1000 * 60 * 60 * 2); // 2小时刷新缓存
|
||||
setInterval(this._refreshLib,1000*60*60*1) // 1小时刷新libmap
|
||||
}
|
||||
|
||||
async getVersionList() {
|
||||
@@ -36,19 +40,19 @@ GROUP BY mcversion."version", mcversion."Type", mcversion."Date", variation."OSb
|
||||
ORDER BY "Date" DESC
|
||||
`)
|
||||
).rows;
|
||||
result.forEach((row: VersionPool) => {
|
||||
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",
|
||||
Arch: ["x64", "x86"],
|
||||
Arch: row.arch,
|
||||
url,
|
||||
time: row.Date,
|
||||
});
|
||||
}
|
||||
});
|
||||
this.versionCache = arr;
|
||||
}
|
||||
@@ -61,6 +65,15 @@ ORDER BY "Date" DESC
|
||||
) {
|
||||
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(
|
||||
`
|
||||
@@ -75,12 +88,14 @@ LIMIT 1
|
||||
)
|
||||
).rows; // 获取版本id
|
||||
|
||||
const data = (
|
||||
const data: ILibraries[] = (
|
||||
await this.pool.query(
|
||||
`
|
||||
SELECT "filePathName"."pathName",
|
||||
"filesHash"."size",
|
||||
${this.hashList.map(hash => `encode("filesHash"."${hash}", 'hex') as "${hash}"`).join(', ')}
|
||||
${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"
|
||||
@@ -89,22 +104,16 @@ WHERE variation_files_data."variationId" = $1
|
||||
`,
|
||||
[r[0].id]
|
||||
)
|
||||
).rows;
|
||||
console.log(data);
|
||||
return data;
|
||||
).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);
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
interface VersionPool {
|
||||
id: number;
|
||||
version: string;
|
||||
Type: string;
|
||||
Date: string;
|
||||
arch: string;
|
||||
}
|
||||
|
||||
interface Version {
|
||||
id: string;
|
||||
type: string;
|
||||
url: string;
|
||||
time: string;
|
||||
}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import express from "express";
|
||||
import config from "./utils/config.js";
|
||||
import versionlistRouter from "./router/versionlist.router.js";
|
||||
import downloadRouter from "./router/download.router.js";
|
||||
|
||||
const app = express();
|
||||
|
||||
app.use('/mc',versionlistRouter)
|
||||
app.use('/download',downloadRouter)
|
||||
app.listen(config.express.port,()=>{
|
||||
console.log(`server is running on port ${config.express.port}`);
|
||||
})
|
||||
9
src/middleware/download.mw.ts
Normal file
9
src/middleware/download.mw.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { Request, Response, NextFunction } from "express";
|
||||
export function hashMiddleware(req:Request,res:Response,next:NextFunction){
|
||||
if (req.params.hash.length !== 32){
|
||||
res.sendStatus(400);
|
||||
return;
|
||||
}
|
||||
next();
|
||||
return;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import { Router, Request, Response } from "express";
|
||||
//import pool from "../utils/pgsql.js";
|
||||
import { hashMiddleware } from "../middleware/download.mw.js";
|
||||
|
||||
const router = Router();
|
||||
|
||||
//const map = new Map<string,string>();
|
||||
router.get("/:hash",hashMiddleware,(req:Request,res:Response)=>{
|
||||
const hash = req.params.hash;
|
||||
const hash1 = hash.substring(0,2)
|
||||
res.redirect(302,`r2.cloudflare.com/${hash1}/${hash}`)
|
||||
})
|
||||
|
||||
export default router;
|
||||
@@ -6,8 +6,8 @@ const versionListController = new VersionListController(pool);
|
||||
const router = Router();
|
||||
|
||||
router.get("/version_manifest", async (req: Request, res: Response) => {
|
||||
const version = await versionListController.getVersionList();
|
||||
res.status(200).json({ version });
|
||||
const versions = await versionListController.getVersionList();
|
||||
res.status(200).json({ versions });
|
||||
});
|
||||
|
||||
router.get("/version/:id/:arch", async (req: Request, res: Response) => {
|
||||
@@ -18,6 +18,6 @@ router.get("/version/:id/:arch", async (req: Request, res: Response) => {
|
||||
res.sendStatus(404);
|
||||
return;
|
||||
}
|
||||
res.status(200).json({ libraries });
|
||||
res.status(200).json(libraries);
|
||||
})
|
||||
export default router;
|
||||
|
||||
27
src/types/versionlist.types.ts
Normal file
27
src/types/versionlist.types.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
export interface IVersionPool {
|
||||
id: number;
|
||||
version: string;
|
||||
Type: string;
|
||||
Date: string;
|
||||
arch: string;
|
||||
}
|
||||
|
||||
export interface IVersion {
|
||||
id: string;
|
||||
type: string;
|
||||
url: string;
|
||||
time: string;
|
||||
}
|
||||
|
||||
export interface ILibraries {
|
||||
pathName: string;
|
||||
size: number;
|
||||
md5: string;
|
||||
sha1: string;
|
||||
sha256: string;
|
||||
}
|
||||
|
||||
export interface ILibrariesMap {
|
||||
libraries: ILibraries[];
|
||||
hits: number;
|
||||
}
|
||||
Reference in New Issue
Block a user