Skip to content

Commit 7676572

Browse files
authored
Release 14.1.1
Release 14.1.1
2 parents c86b343 + 875a4e3 commit 7676572

24 files changed

Lines changed: 3312 additions & 610 deletions

CHANGELOG.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,20 @@
11
# GameVault Backend Server Changelog
22

3+
## 14.1.1
4+
5+
### Changes
6+
7+
- Implement latest IGDB API and automatic model generation
8+
- Fix Special Game Editons not being found
9+
- [#475](https://github.com/Phalcode/gamevault-app/issues/475) Improved Partial File Downloads to be much faster
10+
11+
### Thanks
12+
13+
- @s-crypt
14+
- @magne4000
15+
- @Omni_Noesis
16+
- @Sixdd6
17+
318
## 14.1.0
419

520
### Changes

package.json

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "gamevault-backend",
3-
"version": "14.1.0",
3+
"version": "14.1.1",
44
"description": "the self-hosted gaming platform for drm-free games",
55
"author": "Alkan Alper, Schäfer Philip GbR / Phalcode",
66
"private": true,
@@ -36,7 +36,7 @@
3636
"@nestjs/typeorm": "^11.0.0",
3737
"@nestjs/websockets": "^11.0.11",
3838
"bcrypt": "^5.1.1",
39-
"better-sqlite3": "^11.7.0",
39+
"better-sqlite3": "^11.8.1",
4040
"builder-pattern": "^2.2.0",
4141
"bytes": "^3.1.2",
4242
"chokidar": "^4.0.3",
@@ -52,7 +52,7 @@
5252
"mime": "^3.0.0",
5353
"morgan": "^1.10.0",
5454
"nest-winston": "^1.10.2",
55-
"nestjs-paginate": "^11.0.1",
55+
"nestjs-paginate": "^11.1.0",
5656
"node-7z": "^3.0.0",
5757
"passport": "^0.7.0",
5858
"passport-http": "^0.3.0",
@@ -65,7 +65,7 @@
6565
"socket.io": "^4.8.1",
6666
"stream-throttle": "^0.1.3",
6767
"string-similarity-js": "^2.1.4",
68-
"ts-igdb-client": "^0.4.2",
68+
"@phalcode/ts-igdb-client": "^1.0.22",
6969
"typeorm": "^0.3.21",
7070
"typeorm-naming-strategies": "^4.1.0",
7171
"unidecode": "^1.1.0",
@@ -76,7 +76,7 @@
7676
"devDependencies": {
7777
"@eslint/compat": "^1.2.7",
7878
"@eslint/eslintrc": "^3.3.0",
79-
"@eslint/js": "^9.21.0",
79+
"@eslint/js": "^9.22.0",
8080
"@nestjs/cli": "^11.0.5",
8181
"@nestjs/schematics": "^11.0.2",
8282
"@nestjs/testing": "^11.0.11",
@@ -90,7 +90,7 @@
9090
"@types/mime": "^3.0.4",
9191
"@types/morgan": "^1.9.9",
9292
"@types/multer": "^1.4.12",
93-
"@types/node": "^22.13.9",
93+
"@types/node": "^22.13.10",
9494
"@types/node-7z": "^2.1.10",
9595
"@types/passport-http": "^0.3.11",
9696
"@types/pg": "^8.11.11",
@@ -99,14 +99,14 @@
9999
"@types/unidecode": "^0.1.3",
100100
"@typescript-eslint/eslint-plugin": "^8.26.0",
101101
"@typescript-eslint/parser": "^8.26.0",
102-
"eslint": "^9.21.0",
103-
"eslint-config-prettier": "^10.0.2",
102+
"eslint": "^9.22.0",
103+
"eslint-config-prettier": "^10.1.1",
104104
"eslint-plugin-import": "^2.31.0",
105105
"eslint-plugin-prettier": "^5.2.3",
106106
"fastify": "^4.0.0",
107107
"globals": "^16.0.0",
108108
"jest": "^29.7.0",
109-
"logform": "2.6.1",
109+
"logform": "2.7.0",
110110
"prettier": "^3.5.3",
111111
"prettier-plugin-jsdoc": "^1.3.2",
112112
"prettier-plugin-organize-imports": "^4.1.0",

pnpm-lock.yaml

Lines changed: 343 additions & 260 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/modules/database/migrations/postgres/1728421385000-v13-final.ts

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -42,30 +42,6 @@ export class V13Final1728421385000 implements MigrationInterface {
4242
- Even when the server is running after the migration, it will take a while until you see all your game data. Be patient and check the logs for inactivity.`,
4343
);
4444

45-
console.warn("⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀");
46-
console.warn("⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀");
47-
console.warn("⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀");
48-
console.warn("Alright, let's pray it all works.");
49-
console.warn("⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀");
50-
console.warn("⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣤⣤⣄⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀");
51-
console.warn("⠀⠀⠀⠀⠀⠀⠀⠀⠀⣴⣿⣿⣿⣿⣿⣿⣷⣄⠀⠀⠀⠀⠀⠀⠀⠀");
52-
console.warn("⠀⠀⠀⠀⠀⠀⠀⠀⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿⡆⠀⠀⠀⠀⠀⠀⠀");
53-
console.warn("⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⠀⠀⠀⠀⠀⠀⠀");
54-
console.warn("⠀⠀⠀⠀⠀⠀⠀⠀⢻⡿⠿⣿⣿⣿⣿⡿⠿⣿⡇⠀⠀⠀⠀⠀⠀⠀");
55-
console.warn("⠀⠀⠀⠀⠀⢀⣴⣦⡈⠻⣦⣤⣿⣿⣧⣤⣶⠏⢀⣦⣄⠀⠀⠀⠀⠀");
56-
console.warn("⠀⠀⠀⢀⣴⣿⣿⣿⣷⣤⣈⠙⠛⠛⠛⢉⣠⣴⣿⣿⣿⣷⣄⠀⠀⠀");
57-
console.warn("⠀⠀⢠⣿⣿⣿⣿⠟⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡟⢻⣿⣿⣿⣆⠀⠀");
58-
console.warn("⠀⢀⣿⣿⣿⣿⠃⣰⣿⣿⡿⠛⠋⠉⠛⠻⣿⣿⣷⡀⠹⣿⣿⣿⡆⠀");
59-
console.warn("⠀⣸⣿⣿⣿⠃⣰⣿⣿⠋⣠⣾⡇⢸⣷⣦⠈⣿⣿⣿⡄⢹⣿⣿⣿⠀");
60-
console.warn("⠀⣿⣿⣿⠋⠀⠉⠉⠉⠀⣿⣿⡇⢸⣿⣿⡇⠉⠉⠉⠁⠀⢻⣿⣿⡆");
61-
console.warn("⢰⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇");
62-
console.warn("⠀⠙⠛⠛⠛⠛⠛⠛⠛⠛⠛⠛⠃⠘⠛⠛⠛⠛⠛⠛⠛⠛⠛⠛⠛⠁");
63-
console.warn("⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀⠀ ");
64-
console.warn("⠀⠀⠀⠀⠀⠀⠈⠛⠛⠛⠛⠛⠛⠛⠛⠛⠛⠛⠛⠃⠀⠀⠀⠀⠀⠀ ");
65-
console.warn("⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀");
66-
console.warn("⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀");
67-
console.warn("⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀");
68-
6945
this.logger.log(
7046
`Step ${currentStep}/${totalSteps}: Renaming tables - Running...`,
7147
);

src/modules/database/migrations/sqlite/1728421385000-v13-final.ts

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -44,31 +44,6 @@ export class V13Final1728421385000 implements MigrationInterface {
4444
- Restarting the server will restart the migration.
4545
- Even when the server is running after the migration, it will take a while until you see all your game data. Be patient and check the logs for inactivity.`,
4646
);
47-
48-
console.warn("⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀");
49-
console.warn("⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀");
50-
console.warn("⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀");
51-
console.warn("Alright, let's pray it all works.");
52-
console.warn("⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀");
53-
console.warn("⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣤⣤⣄⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀");
54-
console.warn("⠀⠀⠀⠀⠀⠀⠀⠀⠀⣴⣿⣿⣿⣿⣿⣿⣷⣄⠀⠀⠀⠀⠀⠀⠀⠀");
55-
console.warn("⠀⠀⠀⠀⠀⠀⠀⠀⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿⡆⠀⠀⠀⠀⠀⠀⠀");
56-
console.warn("⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⠀⠀⠀⠀⠀⠀⠀");
57-
console.warn("⠀⠀⠀⠀⠀⠀⠀⠀⢻⡿⠿⣿⣿⣿⣿⡿⠿⣿⡇⠀⠀⠀⠀⠀⠀⠀");
58-
console.warn("⠀⠀⠀⠀⠀⢀⣴⣦⡈⠻⣦⣤⣿⣿⣧⣤⣶⠏⢀⣦⣄⠀⠀⠀⠀⠀");
59-
console.warn("⠀⠀⠀⢀⣴⣿⣿⣿⣷⣤⣈⠙⠛⠛⠛⢉⣠⣴⣿⣿⣿⣷⣄⠀⠀⠀");
60-
console.warn("⠀⠀⢠⣿⣿⣿⣿⠟⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡟⢻⣿⣿⣿⣆⠀⠀");
61-
console.warn("⠀⢀⣿⣿⣿⣿⠃⣰⣿⣿⡿⠛⠋⠉⠛⠻⣿⣿⣷⡀⠹⣿⣿⣿⡆⠀");
62-
console.warn("⠀⣸⣿⣿⣿⠃⣰⣿⣿⠋⣠⣾⡇⢸⣷⣦⠈⣿⣿⣿⡄⢹⣿⣿⣿⠀");
63-
console.warn("⠀⣿⣿⣿⠋⠀⠉⠉⠉⠀⣿⣿⡇⢸⣿⣿⡇⠉⠉⠉⠁⠀⢻⣿⣿⡆");
64-
console.warn("⢰⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇");
65-
console.warn("⠀⠙⠛⠛⠛⠛⠛⠛⠛⠛⠛⠛⠃⠘⠛⠛⠛⠛⠛⠛⠛⠛⠛⠛⠛⠁");
66-
console.warn("⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀⠀ ");
67-
console.warn("⠀⠀⠀⠀⠀⠀⠈⠛⠛⠛⠛⠛⠛⠛⠛⠛⠛⠛⠛⠃⠀⠀⠀⠀⠀⠀ ");
68-
console.warn("⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀");
69-
console.warn("⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀");
70-
console.warn("⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀");
71-
7247
this.logger.log(
7348
`Step ${currentStep}/${totalSteps}: Synchronizing - Running...`,
7449
);

src/modules/games/files.service.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ import { MetadataService } from "../metadata/metadata.service";
2727
import mock from "./games.mock";
2828
import { GamesService } from "./games.service";
2929
import { GamevaultGame } from "./gamevault-game.entity";
30-
import ByteRangeStream from "./models/byte-range-stream";
3130
import { File } from "./models/file.model";
3231
import { GameExistence } from "./models/game-existence.enum";
3332
import { GameType } from "./models/game-type.enum";
@@ -646,9 +645,6 @@ export class FilesService implements OnApplicationBootstrap {
646645
);
647646
}
648647

649-
// Read the file and apply speed limit if necessary.
650-
let file: Readable = createReadStream(fileDownloadPath);
651-
652648
// Apply range header if provided otherwise returns the entire file
653649
const range = this.calculateRange(
654650
rangeHeader,
@@ -659,9 +655,12 @@ export class FilesService implements OnApplicationBootstrap {
659655
rangeHeader,
660656
range,
661657
});
662-
file = file.pipe(
663-
new ByteRangeStream(BigInt(range.start), BigInt(range.end)),
664-
);
658+
659+
// Read the file and apply speed limit if necessary.
660+
let file: Readable = createReadStream(fileDownloadPath, {
661+
start: range.start,
662+
end: range.end,
663+
});
665664

666665
response.setHeader("X-Download-Size", range.size);
667666

src/modules/games/models/byte-range-stream.ts

Lines changed: 0 additions & 37 deletions
This file was deleted.

src/modules/metadata/providers/igdb/igdb.metadata-provider.service.ts

Lines changed: 9 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ import { Injectable } from "@nestjs/common";
22
import {
33
fields,
44
igdb,
5+
proto as igdbModels,
56
search,
67
twitchAccessToken,
78
where,
8-
whereIn,
9-
} from "ts-igdb-client";
9+
} from "@phalcode/ts-igdb-client";
1010

1111
import { isNumberString } from "class-validator";
1212
import { isEmpty, toLower } from "lodash";
@@ -18,13 +18,7 @@ import { GenreMetadata } from "../../genres/genre.metadata.entity";
1818
import { PublisherMetadata } from "../../publishers/publisher.metadata.entity";
1919
import { TagMetadata } from "../../tags/tag.metadata.entity";
2020
import { MetadataProvider } from "../abstract.metadata-provider.service";
21-
import {
22-
GameVaultIgdbAgeRatingMap,
23-
IgdbAgeRating,
24-
} from "./models/igdb-age-rating.interface";
25-
import { IgdbGameCategory } from "./models/igdb-game-category.enum";
26-
import { IgdbGameStatus } from "./models/igdb-game-status.enum";
27-
import { IgdbGame } from "./models/igdb-game.interface";
21+
import { GameVaultIgdbAgeRatingMap } from "./models/gamevault-igdb-age-rating.map";
2822

2923
@Injectable()
3024
export class IgdbMetadataProviderService extends MetadataProvider {
@@ -47,17 +41,6 @@ export class IgdbMetadataProviderService extends MetadataProvider {
4741
"themes.*",
4842
"websites.*",
4943
];
50-
readonly categoriesToInclude = [
51-
IgdbGameCategory.main_game,
52-
IgdbGameCategory.standalone_expansion,
53-
IgdbGameCategory.episode,
54-
IgdbGameCategory.season,
55-
IgdbGameCategory.remake,
56-
IgdbGameCategory.remaster,
57-
IgdbGameCategory.expanded_game,
58-
IgdbGameCategory.port,
59-
IgdbGameCategory.fork,
60-
];
6144

6245
override async onModuleInit(): Promise<void> {
6346
if (
@@ -93,7 +76,6 @@ export class IgdbMetadataProviderService extends MetadataProvider {
9376
"cover.*",
9477
]),
9578
search(query),
96-
whereIn("category", this.categoriesToInclude),
9779
)
9880
.execute();
9981

@@ -127,7 +109,7 @@ export class IgdbMetadataProviderService extends MetadataProvider {
127109
const minimalGameMetadata = [];
128110
for (const game of found_games) {
129111
minimalGameMetadata.push(
130-
await this.mapMinimalGameMetadata(game as IgdbGame),
112+
await this.mapMinimalGameMetadata(game as igdbModels.IGame),
131113
);
132114
}
133115
return minimalGameMetadata;
@@ -146,10 +128,10 @@ export class IgdbMetadataProviderService extends MetadataProvider {
146128
where("id", "=", Number(provider_data_id)),
147129
)
148130
.execute();
149-
return this.mapGameMetadata(update.data[0] as IgdbGame);
131+
return this.mapGameMetadata(update.data[0] as igdbModels.IGame);
150132
}
151133

152-
private async mapGameMetadata(game: IgdbGame): Promise<GameMetadata> {
134+
private async mapGameMetadata(game: igdbModels.IGame): Promise<GameMetadata> {
153135
return {
154136
age_rating: this.calculateAverageAgeRating(game.age_ratings, game.name),
155137
provider_slug: this.slug,
@@ -165,11 +147,7 @@ export class IgdbMetadataProviderService extends MetadataProvider {
165147
: game.summary || game.storyline || null,
166148
rating: game.total_rating,
167149
url_websites: game.websites?.map((website) => website.url),
168-
early_access: [
169-
IgdbGameStatus.alpha,
170-
IgdbGameStatus.beta,
171-
IgdbGameStatus.early_access,
172-
].includes(game.status),
150+
early_access: [2, 3, 4].includes(game.status),
173151
url_screenshots: [
174152
...(game.screenshots || []),
175153
...(game.artworks || []),
@@ -248,7 +226,7 @@ export class IgdbMetadataProviderService extends MetadataProvider {
248226
}
249227

250228
private async mapMinimalGameMetadata(
251-
game: IgdbGame,
229+
game: igdbModels.IGame,
252230
): Promise<MinimalGameMetadataDto> {
253231
return {
254232
provider_slug: "igdb",
@@ -285,7 +263,7 @@ export class IgdbMetadataProviderService extends MetadataProvider {
285263
}
286264

287265
private calculateAverageAgeRating(
288-
ageRatings: IgdbAgeRating[],
266+
ageRatings: igdbModels.IAgeRating[],
289267
gameTitle: string = "Unknown Game",
290268
): number {
291269
if (isEmpty(ageRatings)) {

src/modules/metadata/providers/igdb/models/igdb-age-rating.interface.ts renamed to src/modules/metadata/providers/igdb/models/gamevault-igdb-age-rating.map.ts

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,10 @@
1-
export type AgeRatingMapEntry = {
1+
type AgeRatingMapEntry = {
22
system: string;
33
name: string;
44
minAge: number;
55
igdbEnumValue: number;
66
};
77

8-
export interface IgdbAgeRating {
9-
id: number;
10-
category: number;
11-
content_descriptions: number[];
12-
rating: number;
13-
synopsis: string;
14-
checksum: string;
15-
}
16-
178
export const GameVaultIgdbAgeRatingMap: AgeRatingMapEntry[] = [
189
{ system: "PEGI", name: "Three", minAge: 3, igdbEnumValue: 1 },
1910
{ system: "PEGI", name: "Seven", minAge: 7, igdbEnumValue: 2 },

src/modules/metadata/providers/igdb/models/igdb-artwork.interface.ts

Lines changed: 0 additions & 11 deletions
This file was deleted.

0 commit comments

Comments
 (0)