diff --git a/package.json b/package.json index 7cb8ac3..ed5a1fe 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,6 @@ "@nestjs/core": "^10.3.7", "@nestjs/platform-express": "^10.3.7", "@nestjs/swagger": "^7.3.1", - "axios": "^1.2.3", "cache-manager": "^5.5.1", "class-transformer": "^0.5.1", "class-validator": "^0.14.0", diff --git a/src/fivem/fivem.controller.ts b/src/fivem/fivem.controller.ts index f6effd5..4bfa328 100644 --- a/src/fivem/fivem.controller.ts +++ b/src/fivem/fivem.controller.ts @@ -1,7 +1,7 @@ import { Controller } from '@nestjs/common'; import { FivemService } from './fivem.service'; import { Get, Inject, Param } from '@nestjs/common/decorators'; -import { ApiOkResponse, ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger'; +import { ApiOkResponse, ApiOperation, ApiTags } from '@nestjs/swagger'; import { Cache } from 'cache-manager'; import ServerTrackedDto from 'src/dto/serverTrackedDto'; import ServerCfxDto from 'src/dto/serverCfxDto'; diff --git a/src/fivem/fivem.service.ts b/src/fivem/fivem.service.ts index 98485c6..25835c9 100644 --- a/src/fivem/fivem.service.ts +++ b/src/fivem/fivem.service.ts @@ -1,60 +1,105 @@ import { Injectable, Logger } from '@nestjs/common'; -import axios, { AxiosResponse } from 'axios'; import ServerCfxDto from 'src/dto/serverCfxDto'; import ServerTrackedDto from 'src/dto/serverTrackedDto'; @Injectable() export class FivemService { - async trackServer(serverTracked: ServerTrackedDto): Promise { - try { - const response: AxiosResponse = await axios.get(`http://${serverTracked.address}/dynamic.json`, { timeout: 2000 }); - return { - address: serverTracked.address, - online: true, - ...response.data - }; - } catch (err: any) { - Logger.warn(`[FiveM server | ${serverTracked.address}] ${err.name}: ${err.message}`); - return { - address: serverTracked.address, - online: false - }; + + private readonly fivemApiUrl: string = 'https://servers-frontend.fivem.net/api/servers/single/'; + + async trackServer(serverTracked: ServerTrackedDto): Promise { + try { + const response: Response = await fetch( + `http://${serverTracked.address}/dynamic.json`, + { + method: 'GET', + signal: AbortSignal.timeout(2000), } + ) + const data = await response.json(); + return { + address: serverTracked.address, + online: true, + ...data, + }; + } catch (err: any) { + Logger.warn( + `[FiveM server | ${serverTracked.address}] ${err.name}: ${err.message}`, + ); + return { + address: serverTracked.address, + online: false, + }; } + } - async trackServerByCfx(cfx: ServerCfxDto): Promise { - try { - const response: AxiosResponse = await axios.get(`https://servers-frontend.fivem.net/api/servers/single/${cfx.code}`, { timeout: 2000, headers: { 'User-Agent': 'GST API' } }); - return { - cfx: cfx.code, - online: true, - ...response.data - }; - } catch (err: any) { - Logger.warn(`[FiveM server | CFX ${cfx.code}] ${err.name}: ${err.message}`); - console.log(err); - return { - cfx: cfx.code, - online: false - }; - } + async trackServerByCfx(cfx: ServerCfxDto): Promise { + try { + let response: Response = await fetch( + `${this.fivemApiUrl}${cfx.code}`, + { + method: 'GET', + headers: { + accept: + 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8', + 'accept-language': 'en-US,en;q=0.7', + priority: 'u=0, i', + 'sec-ch-ua': + '"Not)A;Brand";v="8", "Chromium";v="138", "Brave";v="138"', + 'sec-ch-ua-mobile': '?0', + 'sec-ch-ua-platform': '"macOS"', + 'sec-fetch-dest': 'document', + 'sec-fetch-mode': 'navigate', + 'sec-fetch-site': 'none', + 'sec-fetch-user': '?1', + 'sec-gpc': '1', + 'upgrade-insecure-requests': '1', + 'user-agent': + 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36', + }, + }, + ); + const data = await response.json(); + return { + cfx: cfx.code, + online: true, + ...data, + }; + } catch (err: any) { + Logger.warn( + `[FiveM CFX][${cfx.code}] ${err.name}: ${err.message}`, + ); + return { + cfx: cfx.code, + online: false, + }; } + } - async trackPlayers(serverTracked: ServerTrackedDto): Promise { - try { - const { data }: any = await axios.get(`http://${serverTracked.address}/players.json`, { timeout: 2000 }); - return { - address: serverTracked.address, - online: true, - playersOnline: data.length, - players: data - }; - } catch (err: any) { - Logger.warn(`[FiveM server | ${serverTracked.address}] ${err.name}: ${err.message}`); - return { - address: serverTracked.address, - online: false - }; + async trackPlayers(serverTracked: ServerTrackedDto): Promise { + try { + const response: Response = await fetch( + `http://${serverTracked.address}/players.json`, + { + method: 'GET', + signal: AbortSignal.timeout(2000), } + ) + const data = await response.json(); + return { + address: serverTracked.address, + online: true, + playersOnline: data.length, + players: data, + }; + } catch (err: any) { + Logger.warn( + `[FiveM][${serverTracked.address}] ${err.name}: ${err.message}`, + ); + return { + address: serverTracked.address, + online: false, + }; } + } } diff --git a/src/main.ts b/src/main.ts index b94b397..6b20031 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,6 +1,6 @@ import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; -import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger'; +import { DocumentBuilder, OpenAPIObject, SwaggerModule } from '@nestjs/swagger'; import { Logger, ValidationPipe } from '@nestjs/common'; async function bootstrap() { @@ -12,12 +12,12 @@ async function bootstrap() { .setVersion("1.0") .setContact("BliTz_37", "https://github.com/BliTz037", "blitz@blitzlab.ninja") .build(); - const swaggerDocument = SwaggerModule.createDocument(app, swaggerConfig); + const swaggerDocument: OpenAPIObject = SwaggerModule.createDocument(app, swaggerConfig); SwaggerModule.setup('api-docs', app, swaggerDocument); app.useGlobalPipes(new ValidationPipe({ disableErrorMessages: false, whitelist: true })) app.enableCors(); await app.listen(port); - Logger.log(`GST Lametric API is running. Listening on port ${port}`, "Bootstrap"); + Logger.log(`GST API is running. Listening on port ${port}`, "Bootstrap"); } bootstrap(); diff --git a/src/middleware/logger.middleware.ts b/src/middleware/logger.middleware.ts index 52046fa..4b4b1a6 100644 --- a/src/middleware/logger.middleware.ts +++ b/src/middleware/logger.middleware.ts @@ -7,11 +7,11 @@ export class LoggerMiddleware implements NestMiddleware { use(req: Request, res: Response, next: NextFunction) { res.on("finish", () => { if (res.statusCode >= 500) - this.logger.error(`HTTP request ${req.method} ${req.url} ${res.statusCode} ${res.statusMessage}`); + this.logger.error(`[${req.method}][${req.url}][${res.statusCode}] ${res.statusMessage}`); else if (res.statusCode >= 400) - this.logger.warn(`HTTP request ${req.method} ${req.url} ${res.statusCode} ${res.statusMessage}`); + this.logger.warn(`[${req.method}][${req.url}][${res.statusCode}] ${res.statusMessage}`); else - this.logger.log(`HTTP request ${req.method} ${req.url} ${res.statusCode}`); + this.logger.log(`[${req.method}][${req.url}][${res.statusCode}]`); }); next(); } diff --git a/yarn.lock b/yarn.lock index c897d2f..0213140 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1474,15 +1474,6 @@ asynckit@^0.4.0: resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== -axios@^1.2.3: - version "1.6.8" - resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.8.tgz#66d294951f5d988a00e87a0ffb955316a619ea66" - integrity sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ== - dependencies: - follow-redirects "^1.15.6" - form-data "^4.0.0" - proxy-from-env "^1.1.0" - babel-jest@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.7.0.tgz#f4369919225b684c56085998ac63dbd05be020d5" @@ -2499,11 +2490,6 @@ flatted@^3.2.9: resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.3.1.tgz#21db470729a6734d4997002f439cb308987f567a" integrity sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw== -follow-redirects@^1.15.6: - version "1.15.6" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.6.tgz#7f815c0cda4249c74ff09e95ef97c23b5fd0399b" - integrity sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA== - foreground-child@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.1.1.tgz#1d173e776d75d2772fed08efe4a0de1ea1b12d0d" @@ -4066,11 +4052,6 @@ proxy-addr@~2.0.7: forwarded "0.2.0" ipaddr.js "1.9.1" -proxy-from-env@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" - integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== - punycode@^2.1.0: version "2.3.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" @@ -4461,7 +4442,16 @@ string-length@^4.0.1: char-regex "^1.0.2" strip-ansi "^6.0.0" -"string-width-cjs@npm:string-width@^4.2.0", string-width@4.2.3, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3, string-width@^5.0.1, string-width@^5.1.2: +"string-width-cjs@npm:string-width@^4.2.0": + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string-width@4.2.3, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3, string-width@^5.0.1, string-width@^5.1.2: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -4484,7 +4474,14 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -4935,8 +4932,7 @@ which@^2.0.1: dependencies: isexe "^2.0.0" -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: - name wrap-ansi-cjs +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -4954,6 +4950,15 @@ wrap-ansi@^6.0.1, wrap-ansi@^6.2.0: string-width "^4.1.0" strip-ansi "^6.0.0" +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + wrap-ansi@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"