commit b2c00edfcad272cb0c0f73f8ff048dbadda20d1a Author: Rother Date: Wed May 28 00:40:46 2025 +0200 push diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..53af10e --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +demos +node_modules diff --git a/dist/app/downloadDemoFile.js b/dist/app/downloadDemoFile.js new file mode 100644 index 0000000..0b8546f --- /dev/null +++ b/dist/app/downloadDemoFile.js @@ -0,0 +1,167 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.downloadDemoFile = downloadDemoFile; +const fs_1 = __importDefault(require("fs")); +const path_1 = __importDefault(require("path")); +const https_1 = __importDefault(require("https")); +const http_1 = __importDefault(require("http")); +const stream_1 = require("stream"); +const util_1 = require("util"); +const unbzip2_stream_1 = __importDefault(require("unbzip2-stream")); +const pipe = (0, util_1.promisify)(stream_1.pipeline); +/** + * Entpackt eine .bz2-Datei mithilfe von Streams nach .dem + */ +async function extractBz2Safe(srcPath, destPath) { + try { + await pipe(fs_1.default.createReadStream(srcPath), (0, unbzip2_stream_1.default)(), fs_1.default.createWriteStream(destPath)); + } + catch (err) { + console.log('❌ Fehler beim Entpacken (pipe):', err); + throw new Error('Entpackung fehlgeschlagen'); + } +} +/** + * Lädt eine Datei per HTTPS, speichert sie unter `dest`, zeigt optional Fortschritt. + */ +function downloadWithHttps(url, dest, onProgress, maxRetries = 3, retryDelay = 3000) { + return new Promise((resolve, reject) => { + let attempt = 0; + const tryDownload = () => { + const file = fs_1.default.createWriteStream(dest); + const client = url.startsWith('https') ? https_1.default : http_1.default; + let downloaded = 0; + let total = 0; + let lastPercent = -1; + const request = client.get(url, (res) => { + if (res.statusCode !== 200) { + res.resume(); + file.close(); + file.destroy(); + if ([502, 503, 504].includes(res.statusCode) && attempt < maxRetries) { + process.stdout.write(`🔁 Retry ${attempt + 1}/${maxRetries} – HTTP ${res.statusCode}\r`); + attempt++; + setTimeout(tryDownload, retryDelay); + return; + } + if (attempt >= maxRetries) { + console.log(`❌ Max. Versuche erreicht (${maxRetries}), Datei wird übersprungen`); + return resolve(false); + } + return reject(new Error(`HTTP ${res.statusCode}`)); + } + total = parseInt(res.headers['content-length'] || '0', 10); + res.on('data', (chunk) => { + downloaded += chunk.length; + if (onProgress && total) { + const percent = Math.floor((downloaded / total) * 100); + if (percent !== lastPercent) { + lastPercent = percent; + onProgress(percent); + } + } + }); + res.pipe(file); + file.on('finish', () => { + file.close((err) => { + if (err) + return reject(err); + resolve(true); + }); + }); + res.on('error', reject); + file.on('error', reject); + }); + request.on('error', (err) => { + if (attempt < maxRetries) { + console.log(`🔁 Retry ${attempt + 1}/${maxRetries} wegen Verbindungsfehler: ${err.message}`); + attempt++; + setTimeout(tryDownload, retryDelay); + } + else { + reject(err); + } + }); + }; + tryDownload(); + }); +} +/** + * Hauptfunktion: lädt und entpackt eine CS2-Demo (.bz2), mit Fortschrittsanzeige. + */ +async function downloadDemoFile(match, steamId, outputBaseDir = 'demos', onProgress) { + if (!outputBaseDir || outputBaseDir.trim() === '') { + outputBaseDir = 'demos'; + } + const appId = 730; + const matchId = match.matchid; + const timestamp = match.matchtime; + const matchDate = new Date(timestamp * 1000).toISOString().split('T')[0]; + const lastRound = match.roundstatsall?.at(-1); + const demoUrl = typeof lastRound?.map === 'string' && lastRound.map.endsWith('.bz2') + ? lastRound.map + : undefined; + const mapName = lastRound?.reservation?.map || + lastRound?.mapname || + match.watchablematchinfo?.game_map || + 'unknownmap'; + if (!demoUrl) { + throw new Error('❌ Keine Demo-URL im Match vorhanden'); + } + const isPremier = !!lastRound?.b_switched_teams; + const matchType = isPremier ? 'premier' : 'competitive'; + const tempDir = path_1.default.join(outputBaseDir, 'temp'); + const tempFileName = `match${appId}_${mapName}_${matchId}_${matchType}.bz2`; + const baseName = path_1.default.parse(tempFileName).name; + const tempFile = path_1.default.join(tempDir, tempFileName); + const finalDir = path_1.default.join(outputBaseDir, steamId, matchDate); + const finalFile = path_1.default.join(finalDir, `${baseName}.dem`); + const finalFileName = path_1.default.basename(finalFile); + fs_1.default.mkdirSync(tempDir, { recursive: true }); + fs_1.default.mkdirSync(finalDir, { recursive: true }); + console.log(`📥 Lade Demo von ${demoUrl}...`); + try { + const success = await downloadWithHttps(demoUrl, tempFile, onProgress); + if (!success || !fs_1.default.existsSync(tempFile) || fs_1.default.statSync(tempFile).size === 0) { + console.warn(`⚠️ Download fehlgeschlagen oder Datei leer – lösche ${tempFileName}`); + try { + if (fs_1.default.existsSync(tempFile)) + fs_1.default.unlinkSync(tempFile); + } + catch { + console.warn(`⚠️ Konnte leere Datei nicht löschen: ${tempFileName}`); + } + return ''; + } + } + catch (err) { + throw new Error(`❌ Fehler beim Download: ${err instanceof Error ? err.message : err}`); + } + console.log(`✅ Gespeichert als ${tempFileName}`); + const entpackZeile = `🗜️ Entpacke ${finalFileName}...`; + process.stdout.write(entpackZeile); + await extractBz2Safe(tempFile, finalFile); + const successMessage = `✅ Entpackt: ${finalFileName}`; + const failMessage = `❌ Entpackung fehlgeschlagen – Datei nicht vorhanden`; + // Max-Zeichenlänge bestimmen + const maxLength = Math.max(entpackZeile.length, successMessage.length, failMessage.length); + if (!fs_1.default.existsSync(finalFile)) { + const paddedFail = failMessage.padEnd(maxLength, ' '); + process.stdout.write(`\r${paddedFail}\n`); + throw new Error(failMessage); + } + const paddedSuccess = successMessage.padEnd(maxLength, ' '); + process.stdout.write(`\r${paddedSuccess}\n`); + // Aufräumen + try { + fs_1.default.unlinkSync(tempFile); + console.log(`🧹 Gelöscht: ${tempFileName}`); + } + catch { + console.log(`⚠️ Konnte temporäre Datei nicht löschen: ${tempFileName}`); + } + return finalFile; +} diff --git a/dist/app/fetchMatchFromSharecode.js b/dist/app/fetchMatchFromSharecode.js new file mode 100644 index 0000000..a25efad --- /dev/null +++ b/dist/app/fetchMatchFromSharecode.js @@ -0,0 +1,17 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.fetchMatchFromShareCode = fetchMatchFromShareCode; +const csgo_sharecode_1 = require("csgo-sharecode"); +async function fetchMatchFromShareCode(shareCode, session) { + const { csgo } = session; + const decoded = (0, csgo_sharecode_1.decodeMatchShareCode)(shareCode); + return new Promise((resolve, reject) => { + csgo.once('matchList', (matches) => { + const match = matches.find((m) => m.matchid === decoded.matchId.toString()); + if (!match) + return reject(new Error('❌ Kein Match gefunden')); + resolve(match); + }); + csgo.requestGame(shareCode); + }); +} diff --git a/dist/app/steamSession.js b/dist/app/steamSession.js new file mode 100644 index 0000000..5544b4f --- /dev/null +++ b/dist/app/steamSession.js @@ -0,0 +1,44 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.createSteamSession = createSteamSession; +const steam_user_1 = __importDefault(require("steam-user")); +const globaloffensive_1 = __importDefault(require("globaloffensive")); +async function createSteamSession(username, password, mfa) { + const client = new steam_user_1.default(); + const csgo = new globaloffensive_1.default(client); + const loginPromise = new Promise((resolve, reject) => { + client.logOn({ + accountName: username, + password, + twoFactorCode: mfa, + }); + client.once('loggedOn', () => { + console.log('✅ Eingeloggt bei Steam'); + client.setPersona(steam_user_1.default.EPersonaState.Online); + client.gamesPlayed(730); + }); + client.on('friendRelationship', (steamID, relationship) => { + if (relationship === steam_user_1.default.EFriendRelationship.RequestRecipient) { + console.log(`➕ Freundschaftsanfrage von ${steamID.getSteamID64()} erhalten – wird akzeptiert`); + client.addFriend(steamID, (err) => { + if (err) { + console.error(`❌ Fehler beim Akzeptieren von ${steamID.getSteamID64()}:`, err); + } + else { + console.log(`✅ Freund hinzugefügt: ${steamID.getSteamID64()}`); + } + }); + } + }); + csgo.once('connectedToGC', () => { + console.log('🎮 Verbunden mit dem Game Coordinator'); + resolve(); + }); + client.once('error', reject); + }); + await loginPromise; + return { client, csgo }; +} diff --git a/dist/cs2-demo-downloader-linux b/dist/cs2-demo-downloader-linux new file mode 100644 index 0000000..645ebb1 Binary files /dev/null and b/dist/cs2-demo-downloader-linux differ diff --git a/dist/cs2-demo-downloader-macos b/dist/cs2-demo-downloader-macos new file mode 100644 index 0000000..2506399 Binary files /dev/null and b/dist/cs2-demo-downloader-macos differ diff --git a/dist/cs2-demo-downloader-win.exe b/dist/cs2-demo-downloader-win.exe new file mode 100644 index 0000000..592a8fe Binary files /dev/null and b/dist/cs2-demo-downloader-win.exe differ diff --git a/dist/main.js b/dist/main.js new file mode 100644 index 0000000..693f9da --- /dev/null +++ b/dist/main.js @@ -0,0 +1,69 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const yargs_1 = __importDefault(require("yargs")); +const helpers_1 = require("yargs/helpers"); +const steamSession_1 = require("./app/steamSession"); +const fetchMatchFromSharecode_1 = require("./app/fetchMatchFromSharecode"); +const downloadDemoFile_1 = require("./app/downloadDemoFile"); +const http_1 = __importDefault(require("http")); +const fs_1 = __importDefault(require("fs")); +const path_1 = __importDefault(require("path")); +const argv = (0, yargs_1.default)((0, helpers_1.hideBin)(process.argv)).options({ + username: { type: 'string', demandOption: true }, + password: { type: 'string', demandOption: true }, + mfa: { type: 'string', demandOption: false }, + authCode: { type: 'string', demandOption: false }, + port: { type: 'number', default: 4000, demandOption: false }, + demoPath: { + type: 'string', + default: 'demos', + demandOption: false, + description: 'Zielverzeichnis für heruntergeladene Demos', + }, +}).parseSync(); +const PORT = argv.port; +const resolvedDemoPath = path_1.default.resolve(argv.demoPath); +if (!fs_1.default.existsSync(resolvedDemoPath)) { + fs_1.default.mkdirSync(resolvedDemoPath, { recursive: true }); + console.log(`📂 Verzeichnis erstellt: ${resolvedDemoPath}`); +} +async function start() { + const session = await (0, steamSession_1.createSteamSession)(argv.username, argv.password, argv.mfa); + console.log(`🚀 Server läuft auf http://localhost:${PORT}`); + http_1.default + .createServer(async (req, res) => { + if (req.method === 'POST' && req.url === '/download') { + let body = ''; + req.on('data', (chunk) => (body += chunk)); + req.on('end', async () => { + try { + const { shareCode, steamId } = JSON.parse(body); + console.log(`📦 ShareCode empfangen: ${shareCode}`); + const match = await (0, fetchMatchFromSharecode_1.fetchMatchFromShareCode)(shareCode, session); + const path = await (0, downloadDemoFile_1.downloadDemoFile)(match, steamId, resolvedDemoPath, (percent) => { + process.stdout.write(`📶 Fortschritt: ${percent}%\r`); + if (percent === 100) { + console.log('✅ Download abgeschlossen'); + } + }); + res.writeHead(200, { 'Content-Type': 'application/json' }); + res.end(JSON.stringify({ success: true, path })); + } + catch (err) { + console.error('❌ Fehler:', err); + res.writeHead(500, { 'Content-Type': 'application/json' }); + res.end(JSON.stringify({ success: false, error: err instanceof Error ? err.message : err })); + } + }); + } + else { + res.writeHead(404); + res.end(); + } + }) + .listen(PORT); +} +start(); diff --git a/dist/types/types.js b/dist/types/types.js new file mode 100644 index 0000000..c8ad2e5 --- /dev/null +++ b/dist/types/types.js @@ -0,0 +1,2 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..01ad4f8 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1685 @@ +{ + "name": "cs2-demo-downloader", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "cs2-demo-downloader", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "csgo-sharecode": "^3.1.2", + "decompress": "^4.2.1", + "decompress-bzip2": "^4.0.0", + "dotenv": "^16.5.0", + "globaloffensive": "^3.2.0", + "lzma": "^2.3.2", + "steam-session": "^1.9.3", + "steam-totp": "^2.1.2", + "steam-user": "^5.2.1", + "unbzip2-stream": "^1.4.3", + "undici": "^6.21.2", + "yargs": "^17.7.2" + }, + "bin": { + "cs2-demo-downloader": "dist/main.js" + }, + "devDependencies": { + "@types/decompress": "^4.2.7", + "@types/globaloffensive": "^2.3.4", + "@types/node": "^22.15.16", + "@types/steam-user": "^5.0.4", + "@types/unbzip2-stream": "^1.4.3", + "@types/yargs": "^17.0.33", + "ts-node": "^10.9.2", + "typescript": "^5.8.3" + } + }, + "node_modules/@bbob/parser": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/@bbob/parser/-/parser-2.9.0.tgz", + "integrity": "sha512-tldSYsMoEclke/B1nqL7+HbYMWZHTKvpbEHRSHuY+sZvS1o7Jpdfjb+KPpwP9wLI3p3r7GPv69/wGy+Xibs9yA==", + "license": "MIT", + "dependencies": { + "@bbob/plugin-helper": "^2.9.0" + } + }, + "node_modules/@bbob/plugin-helper": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/@bbob/plugin-helper/-/plugin-helper-2.9.0.tgz", + "integrity": "sha512-idpUcNQ2co6T1oU/7/DG/ZRfipSSkTn9Ozw9f5vaXH7nzV3qhqZnhFVlHTzGGnRlzKlBwWOBzOdWi4Zeqg1c5A==", + "license": "MIT" + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@doctormckay/stdlib": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@doctormckay/stdlib/-/stdlib-2.10.0.tgz", + "integrity": "sha512-bwy+gPn6oa2KTpfxJKX3leZoV/wHDVtO0/gq3usPvqPswG//dcf3jVB8LcbRRsKO3BXCt5DqctOQ+Xb07ivxnw==", + "license": "MIT", + "dependencies": { + "psl": "^1.9.0" + }, + "engines": { + "node": ">=12.22.0" + } + }, + "node_modules/@doctormckay/steam-crypto": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@doctormckay/steam-crypto/-/steam-crypto-1.2.0.tgz", + "integrity": "sha512-lsxgLw640gEdZBOXpVIcYWcYD+V+QbtEsMPzRvjmjz2XXKc7QeEMyHL07yOFRmay+cUwO4ObKTJO0dSInEuq5g==", + "license": "MIT" + }, + "node_modules/@doctormckay/user-agents": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@doctormckay/user-agents/-/user-agents-1.0.0.tgz", + "integrity": "sha512-F+sL1YmebZTY2CnjoR9BXFEULpq7y8dxyLx48LZVa0BSDseXdLG/DtPISfM1iNv1XKCeiBzVNfAT/MOQ69v1Zw==", + "license": "MIT" + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", + "license": "BSD-3-Clause" + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/bytebuffer": { + "version": "5.0.49", + "resolved": "https://registry.npmjs.org/@types/bytebuffer/-/bytebuffer-5.0.49.tgz", + "integrity": "sha512-lV4YLiolMdD4upDmr4vnfiwV/FN9Jg33eNTSFMkHqyMKqTIAn5TmFTYsARwXwUXeFU7yzRpECmWV1SOhIvdkRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/long": "^3.0.0", + "@types/node": "*" + } + }, + "node_modules/@types/bytebuffer/node_modules/@types/long": { + "version": "3.0.32", + "resolved": "https://registry.npmjs.org/@types/long/-/long-3.0.32.tgz", + "integrity": "sha512-ZXyOOm83p7X8p3s0IYM3VeueNmHpkk/yMlP8CLeOnEcu6hIwPH7YjZBvhQkR0ZFS2DqZAxKtJ/M5fcuv3OU5BA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/decompress": { + "version": "4.2.7", + "resolved": "https://registry.npmjs.org/@types/decompress/-/decompress-4.2.7.tgz", + "integrity": "sha512-9z+8yjKr5Wn73Pt17/ldnmQToaFHZxK0N1GHysuk/JIPT8RIdQeoInM01wWPgypRcvb6VH1drjuFpQ4zmY437g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/file-manager": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/file-manager/-/file-manager-2.0.3.tgz", + "integrity": "sha512-gEq6de+iMbjmkL3Wj183JQ651h9b331wQ3svXp2K6RkgBg+TtiyIZTMols/a3UtXllVV9kSelz/N3Rgh0n6S4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/globaloffensive": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/@types/globaloffensive/-/globaloffensive-2.3.4.tgz", + "integrity": "sha512-EZXpLWLK1UoIlbAg+bgwIJ9s2ORw1NqKrnIU7ob8MtxwfoU7LVb6iVZNv6cKK/foQGh0ntlA6XLprgPOI9JwHg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/steam-user": "*", + "@types/steamid": "*" + } + }, + "node_modules/@types/long": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", + "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==", + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "22.15.16", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.16.tgz", + "integrity": "sha512-3pr+KjwpVujqWqOKT8mNR+rd09FqhBLwg+5L/4t0cNYBzm/yEiYGCxWttjaPBsLtAo+WFNoXzGJfolM1JuRXoA==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/steam-user": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@types/steam-user/-/steam-user-5.0.4.tgz", + "integrity": "sha512-afPMGfYNJ28ttNsFX8gOBlNcgCNUr60zIEr+84MyuvAMKYknmyxHl6I9Qen7aSRARJc1VTr2SpDxPetuVJgNoQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/bytebuffer": "*", + "@types/file-manager": "*", + "@types/node": "*", + "@types/steamid": "*" + } + }, + "node_modules/@types/steamid": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/steamid/-/steamid-2.0.3.tgz", + "integrity": "sha512-ozNMQViUYLU+NBN4v7X0bV1O8uTL1bA+WvfHtt9IKcydS4tyYKH7w1vq+xcPGWGL0PRhGtY7C1Zhaeyj2IsETw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/through": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/@types/through/-/through-0.0.33.tgz", + "integrity": "sha512-HsJ+z3QuETzP3cswwtzt2vEIiHBk/dCcHGhbmG5X3ecnwFD/lPrMpliGXxSCg03L9AhrdwA4Oz/qfspkDW+xGQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/unbzip2-stream": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@types/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", + "integrity": "sha512-D8X5uuJRISqc8YtwL8jNW2FpPdUOCYXbfD6zNROCTbVXK9nawucxh10tVXE3MPjnHdRA1LvB0zDxVya/lBsnYw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/through": "*" + } + }, + "node_modules/@types/yargs": { + "version": "17.0.33", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", + "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/acorn": { + "version": "8.14.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", + "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", + "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/adm-zip": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.16.tgz", + "integrity": "sha512-TGw5yVi4saajsSEgz25grObGHEUaDrniwvA2qwSC060KfqGPdglhvPMA2lPIoxs3PQIItj2iag35fONcQqgUaQ==", + "license": "MIT", + "engines": { + "node": ">=12.0" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "license": "MIT", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true, + "license": "MIT" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/big-number": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/big-number/-/big-number-2.0.0.tgz", + "integrity": "sha512-C67Su0g+XsmXADX/UM9L/+xSbqqwq0D/qGJs2ky6Noy2FDuCZnC38ZSXODiaBvqWma2VYRZEXgm4H74PS6tCDg==", + "license": "MIT" + }, + "node_modules/binarykvparser": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binarykvparser/-/binarykvparser-2.3.0.tgz", + "integrity": "sha512-B1N5ZxC8I9oSLis7Rg36DxsZJoIikUGU2XwpI0FKFCaPIJIEYi0B9UeIk3QU006axzq0TI9KC3iXelfGGgnWew==", + "bundleDependencies": [ + "long" + ], + "license": "MIT", + "dependencies": { + "long": "^3.2.0" + } + }, + "node_modules/bl": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.3.tgz", + "integrity": "sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==", + "license": "MIT", + "dependencies": { + "readable-stream": "^2.3.5", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-alloc": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", + "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", + "license": "MIT", + "dependencies": { + "buffer-alloc-unsafe": "^1.1.0", + "buffer-fill": "^1.0.0" + } + }, + "node_modules/buffer-alloc-unsafe": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", + "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", + "license": "MIT" + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/buffer-fill": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", + "integrity": "sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ==", + "license": "MIT" + }, + "node_modules/bytebuffer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/bytebuffer/-/bytebuffer-5.0.1.tgz", + "integrity": "sha512-IuzSdmADppkZ6DlpycMkm8l9zeEq16fWtLvunEwFiYciR/BHo4E8/xs5piFquG+Za8OWmMqHF8zuRviz2LHvRQ==", + "license": "Apache-2.0", + "dependencies": { + "long": "~3" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/bytebuffer/node_modules/long": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/long/-/long-3.2.0.tgz", + "integrity": "sha512-ZYvPPOMqUwPoDsbJaR10iQJYnMuZhRTvHYl62ErLIEX7RgFlziSBUUvrt3OVfc47QlHHpzPZYP17g3Fv7oeJkg==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "license": "MIT" + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "license": "MIT" + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/csgo-sharecode": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/csgo-sharecode/-/csgo-sharecode-3.1.2.tgz", + "integrity": "sha512-uaSkf6jmAR4Iqn5Tavo7HWJ+epyaGUk1iiTkjh7v/E2CcrHrCglH4RUPF6qCN95Wv2G/aVZNqPUZJ5NOW3LSYw==", + "license": "GPL-2.0", + "engines": { + "node": ">=10.8.0" + } + }, + "node_modules/cuint": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/cuint/-/cuint-0.2.2.tgz", + "integrity": "sha512-d4ZVpCW31eWwCMe1YT3ur7mUDnTXbgwyzaL320DrcRT45rfjYxkt5QWLrmOJ+/UEAI2+fQgKe/fCjR8l4TpRgw==", + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decompress": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/decompress/-/decompress-4.2.1.tgz", + "integrity": "sha512-e48kc2IjU+2Zw8cTb6VZcJQ3lgVbS4uuB1TfCHbiZIP/haNXm+SVyhu+87jts5/3ROpd82GSVCoNs/z8l4ZOaQ==", + "license": "MIT", + "dependencies": { + "decompress-tar": "^4.0.0", + "decompress-tarbz2": "^4.0.0", + "decompress-targz": "^4.0.0", + "decompress-unzip": "^4.0.1", + "graceful-fs": "^4.1.10", + "make-dir": "^1.0.0", + "pify": "^2.3.0", + "strip-dirs": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-bzip2": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decompress-bzip2/-/decompress-bzip2-4.0.0.tgz", + "integrity": "sha512-RwEcbZWaM7F5EiYfsAXUmZ/KLEVAPjYXfGbb5bztXZQ3d5PMpXYxa/1j04QL/gjotRdmzpHh++/cxz+rNZ4AZg==", + "license": "MIT", + "dependencies": { + "file-type": "^4.3.0", + "seek-bzip": "^1.0.5" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-tar": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-4.1.1.tgz", + "integrity": "sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==", + "license": "MIT", + "dependencies": { + "file-type": "^5.2.0", + "is-stream": "^1.1.0", + "tar-stream": "^1.5.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-tar/node_modules/file-type": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", + "integrity": "sha512-Iq1nJ6D2+yIO4c8HHg4fyVb8mAJieo1Oloy1mLLaB2PvezNedhBVm+QU7g0qM42aiMbRXTxKKwGD17rjKNJYVQ==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-tarbz2": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz", + "integrity": "sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A==", + "license": "MIT", + "dependencies": { + "decompress-tar": "^4.1.0", + "file-type": "^6.1.0", + "is-stream": "^1.1.0", + "seek-bzip": "^1.0.5", + "unbzip2-stream": "^1.0.9" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-tarbz2/node_modules/file-type": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-6.2.0.tgz", + "integrity": "sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-targz": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/decompress-targz/-/decompress-targz-4.1.1.tgz", + "integrity": "sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==", + "license": "MIT", + "dependencies": { + "decompress-tar": "^4.1.1", + "file-type": "^5.2.0", + "is-stream": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-targz/node_modules/file-type": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", + "integrity": "sha512-Iq1nJ6D2+yIO4c8HHg4fyVb8mAJieo1Oloy1mLLaB2PvezNedhBVm+QU7g0qM42aiMbRXTxKKwGD17rjKNJYVQ==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-unzip": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-4.0.1.tgz", + "integrity": "sha512-1fqeluvxgnn86MOh66u8FjbtJpAFv5wgCT9Iw8rcBqQcCo5tO8eiJw7NNTrvt9n4CRBVq7CstiS922oPgyGLrw==", + "license": "MIT", + "dependencies": { + "file-type": "^3.8.0", + "get-stream": "^2.2.0", + "pify": "^2.3.0", + "yauzl": "^2.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-unzip/node_modules/file-type": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", + "integrity": "sha512-RLoqTXE8/vPmMuTI88DAzhMYC99I8BWv7zYP4A1puo5HIjEJ5EX48ighy4ZyKMG9EDXxBgW6e++cn7d1xuFghA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dotenv": { + "version": "16.5.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.5.0.tgz", + "integrity": "sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "license": "MIT", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "license": "MIT", + "dependencies": { + "pend": "~1.2.0" + } + }, + "node_modules/file-manager": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/file-manager/-/file-manager-2.0.1.tgz", + "integrity": "sha512-y/K/1OCha04OXOxzo3cXJYtIzEk/CUMBb7Okipxueu0u+xCiuoocbwPyh1smUBasOobo4GAYmjgjD9Vh5zI51w==", + "license": "MIT", + "dependencies": { + "@doctormckay/stdlib": "^1.14.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/file-manager/node_modules/@doctormckay/stdlib": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/@doctormckay/stdlib/-/stdlib-1.16.1.tgz", + "integrity": "sha512-XhuUOzElz6fnNdt70IYNKqhPAEpGaL4JHOhAvklRh0hAhVPW+/wLxaWT3DWUbaG5Dta5YvIp7+cZK3GhIpAuug==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/file-type": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-4.4.0.tgz", + "integrity": "sha512-f2UbFQEk7LXgWpi5ntcO86OeA/cC80fuDDDaX/fZ2ZGel+AF7leRQqBBW1eJNiiQkrZlAoM6P+VYP5P6bOlDEQ==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "license": "MIT" + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-stream": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", + "integrity": "sha512-AUGhbbemXxrZJRD5cDvKtQxLuYaIbNtDTK8YqupCI393Q2KSTreEsLUN3ZxAWFGiKTzL6nKuzfcIvieflUX9qA==", + "license": "MIT", + "dependencies": { + "object-assign": "^4.0.1", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/globaloffensive": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/globaloffensive/-/globaloffensive-3.2.0.tgz", + "integrity": "sha512-4k1pCfWK7UYM18f3sYULTtT37owEPtDIHHLd6uBl4yTtHK+Px31+eiZ6Syt5/J6+/SF9gpMp7cIRrKhsjQkUZg==", + "license": "MIT", + "dependencies": { + "bytebuffer": "^5.0.1", + "globaloffensive-sharecode": "^1.1.1", + "long": "^5.2.3", + "protobufjs": "^7.2.5", + "steamid": "^2.0.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "steam-user": ">=4.2.0" + } + }, + "node_modules/globaloffensive-sharecode": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/globaloffensive-sharecode/-/globaloffensive-sharecode-1.1.1.tgz", + "integrity": "sha512-L04gw1d1nNEJVLuXulo/+NeJUAFkvsO85vMiuHqArRNs8LvLKjC/6eLzxgMPl9v+0KMxjWp/6wITznWGZ0fRXQ==", + "license": "WTFPL", + "dependencies": { + "big-number": "^2.0.0" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/ip-address": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", + "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", + "license": "MIT", + "dependencies": { + "jsbn": "1.1.0", + "sprintf-js": "^1.1.3" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-natural-number": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-natural-number/-/is-natural-number-4.0.1.tgz", + "integrity": "sha512-Y4LTamMe0DDQIIAlaer9eKebAlDSV6huy+TWhJVPlzZh2o4tRP5SQWFlLn5N0To4mDD22/qdOq+veo1cSISLgQ==", + "license": "MIT" + }, + "node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "license": "MIT" + }, + "node_modules/jsbn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", + "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", + "license": "MIT" + }, + "node_modules/kvparser": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/kvparser/-/kvparser-1.0.2.tgz", + "integrity": "sha512-5P/5qpTAHjVYWqcI55B3yQwSY2FUrYYrJj5i65V1Wmg7/4W4OnBcaodaEvLyVuugeOnS+BAaKm9LbPazGJcRyA==", + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/long": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", + "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", + "license": "Apache-2.0" + }, + "node_modules/lzma": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/lzma/-/lzma-2.3.2.tgz", + "integrity": "sha512-DcfiawQ1avYbW+hsILhF38IKAlnguc/fjHrychs9hdxe4qLykvhT5VTGNs5YRWgaNePh7NTxGD4uv4gKsRomCQ==", + "license": "MIT", + "bin": { + "lzma.js": "bin/lzma.js" + } + }, + "node_modules/make-dir": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", + "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "license": "MIT", + "dependencies": { + "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/make-dir/node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true, + "license": "ISC" + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/node-bignumber": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/node-bignumber/-/node-bignumber-1.2.2.tgz", + "integrity": "sha512-VoTZHmdFQpZH1+q1dz2qcHNCwTWsJg2T3PYwlAyDNFOfVhSYUKQBLFcCpCud+wJBGgCttGavZILaIggDIKqEQQ==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "license": "MIT" + }, + "node_modules/permessage-deflate": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/permessage-deflate/-/permessage-deflate-0.1.7.tgz", + "integrity": "sha512-EUNi/RIsyJ1P1u9QHFwMOUWMYetqlE22ZgGbad7YP856WF4BFF0B7DuNy6vEGsgNNud6c/SkdWzkne71hH8MjA==", + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "*" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", + "license": "MIT", + "dependencies": { + "pinkie": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "license": "MIT" + }, + "node_modules/protobufjs": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.4.0.tgz", + "integrity": "sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw==", + "hasInstallScript": true, + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/node": ">=13.7.0", + "long": "^5.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/psl": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz", + "integrity": "sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==", + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "funding": { + "url": "https://github.com/sponsors/lupomontero" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/readable-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/seek-bzip": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.6.tgz", + "integrity": "sha512-e1QtP3YL5tWww8uKaOCQ18UxIT2laNBXHjV/S2WYCiK4udiv8lkG89KRIoCjUagnAmCBurjF4zEVX2ByBbnCjQ==", + "license": "MIT", + "dependencies": { + "commander": "^2.8.1" + }, + "bin": { + "seek-bunzip": "bin/seek-bunzip", + "seek-table": "bin/seek-bzip-table" + } + }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "license": "MIT", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks": { + "version": "2.8.4", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.4.tgz", + "integrity": "sha512-D3YaD0aRxR3mEcqnidIs7ReYJFVzWdd6fXJYUM8ixcQcJRGTka/b3saV0KflYhyVJXKhb947GndU35SxYNResQ==", + "license": "MIT", + "dependencies": { + "ip-address": "^9.0.5", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz", + "integrity": "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==", + "license": "MIT", + "dependencies": { + "agent-base": "^6.0.2", + "debug": "^4.3.3", + "socks": "^2.6.2" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", + "license": "BSD-3-Clause" + }, + "node_modules/steam-appticket": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/steam-appticket/-/steam-appticket-1.0.2.tgz", + "integrity": "sha512-zwDwZALGv3RanE8RHNYcQU3u4Ez23EzMuQ4Lh15uIHddpDh6TI6uFGbC0HNyt6y+UJYSILe77A33VhFZKQiaqQ==", + "license": "MIT", + "dependencies": { + "@doctormckay/stdlib": "^1.6.0", + "@doctormckay/steam-crypto": "^1.2.0", + "bytebuffer": "^5.0.1", + "protobufjs": "^6.8.8", + "steamid": "^1.1.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/steam-appticket/node_modules/@doctormckay/stdlib": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/@doctormckay/stdlib/-/stdlib-1.16.1.tgz", + "integrity": "sha512-XhuUOzElz6fnNdt70IYNKqhPAEpGaL4JHOhAvklRh0hAhVPW+/wLxaWT3DWUbaG5Dta5YvIp7+cZK3GhIpAuug==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/steam-appticket/node_modules/long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", + "license": "Apache-2.0" + }, + "node_modules/steam-appticket/node_modules/protobufjs": { + "version": "6.11.4", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.4.tgz", + "integrity": "sha512-5kQWPaJHi1WoCpjTGszzQ32PG2F4+wRY6BmAT4Vfw56Q2FZ4YZzK20xUYQH4YkfehY1e6QSICrJquM6xXZNcrw==", + "hasInstallScript": true, + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.1", + "@types/node": ">=13.7.0", + "long": "^4.0.0" + }, + "bin": { + "pbjs": "bin/pbjs", + "pbts": "bin/pbts" + } + }, + "node_modules/steam-appticket/node_modules/steamid": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/steamid/-/steamid-1.1.3.tgz", + "integrity": "sha512-t86YjtP1LtPt8D+TaIARm6PtC9tBnF1FhxQeLFs6ohG7vDUfQuy/M8II14rx1TTUkVuYoWHP/7DlvTtoCGULcw==", + "license": "MIT", + "dependencies": { + "cuint": "^0.2.1" + } + }, + "node_modules/steam-session": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/steam-session/-/steam-session-1.9.3.tgz", + "integrity": "sha512-leunJ8205CpEg/QW98S3LS+18qWHGb6wfe1oh2y4v/EChW0gq7Hd/buKb4R/TVh7VbFvb4taMUbwPvMkNaOPyg==", + "license": "MIT", + "dependencies": { + "@doctormckay/stdlib": "^2.9.0", + "@doctormckay/user-agents": "^1.0.0", + "debug": "^4.3.4", + "kvparser": "^1.0.1", + "node-bignumber": "^1.2.2", + "protobufjs": "^7.1.0", + "socks-proxy-agent": "^7.0.0", + "steamid": "^2.0.0", + "tiny-typed-emitter": "^2.1.0", + "websocket13": "^4.0.0" + }, + "engines": { + "node": ">=12.22.0" + } + }, + "node_modules/steam-totp": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/steam-totp/-/steam-totp-2.1.2.tgz", + "integrity": "sha512-bTKlc/NoIUQId+my+O556s55DDsNNXfVIPWFDNVu68beql7AJhV0c+GTjFxfwCDYfdc4NkAme+0WrDdnY2D2VA==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/steam-user": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/steam-user/-/steam-user-5.2.1.tgz", + "integrity": "sha512-fv3SS3vPXCYi+uxIvtHjTnqGFSyAAqfSURyCLQMbBfRP//6gK4mRFDAbrcjMM4ixpCkP7ZsTMvNHr2plScmroQ==", + "license": "MIT", + "dependencies": { + "@bbob/parser": "^2.2.0", + "@doctormckay/stdlib": "^2.9.1", + "@doctormckay/steam-crypto": "^1.2.0", + "adm-zip": "^0.5.10", + "binarykvparser": "^2.2.0", + "bytebuffer": "^5.0.0", + "file-manager": "^2.0.0", + "kvparser": "^1.0.1", + "lzma": "^2.3.2", + "protobufjs": "^7.2.4", + "socks-proxy-agent": "^7.0.0", + "steam-appticket": "^1.0.1", + "steam-session": "^1.8.0", + "steam-totp": "^2.0.1", + "steamid": "^2.0.0", + "websocket13": "^4.0.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/steamid": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/steamid/-/steamid-2.1.0.tgz", + "integrity": "sha512-ndt1cvuuSC+i8fcxVsmeyRlgGsR1QsoAuIXz+eabj8/Y4GIWE2+mgHA7Hys61JDHOxttfWtXHtN2m5TNYTlORg==", + "license": "MIT", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/string_decoder/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-dirs": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/strip-dirs/-/strip-dirs-2.1.0.tgz", + "integrity": "sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g==", + "license": "MIT", + "dependencies": { + "is-natural-number": "^4.0.1" + } + }, + "node_modules/tar-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", + "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==", + "license": "MIT", + "dependencies": { + "bl": "^1.0.0", + "buffer-alloc": "^1.2.0", + "end-of-stream": "^1.0.0", + "fs-constants": "^1.0.0", + "readable-stream": "^2.3.0", + "to-buffer": "^1.1.1", + "xtend": "^4.0.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "license": "MIT" + }, + "node_modules/tiny-typed-emitter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tiny-typed-emitter/-/tiny-typed-emitter-2.1.0.tgz", + "integrity": "sha512-qVtvMxeXbVej0cQWKqVSSAHmKZEHAvxdF8HEUBFWts8h+xEo5m/lEiPakuyZ3BnCBjOD8i24kzNOiOLLgsSxhA==", + "license": "MIT" + }, + "node_modules/to-buffer": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", + "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==", + "license": "MIT" + }, + "node_modules/ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/typescript": { + "version": "5.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", + "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/unbzip2-stream": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", + "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", + "license": "MIT", + "dependencies": { + "buffer": "^5.2.1", + "through": "^2.3.8" + } + }, + "node_modules/undici": { + "version": "6.21.2", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.21.2.tgz", + "integrity": "sha512-uROZWze0R0itiAKVPsYhFov9LxrPMHLMEQFszeI2gCN6bnIIZ8twzBCJcN2LJrBBLfrP0t1FW0g+JmKVl8Vk1g==", + "license": "MIT", + "engines": { + "node": ">=18.17" + } + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "license": "MIT" + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true, + "license": "MIT" + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket13": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/websocket13/-/websocket13-4.0.0.tgz", + "integrity": "sha512-/ujP9ZfihyAZIXKGxcYpoe7Gj4r5o3WYSfP93o9lVNhhqoBtYba4m1s3mxdjKZu/HOhX5Mcqrt89dv/gC3b06A==", + "license": "MIT", + "dependencies": { + "@doctormckay/stdlib": "^2.7.1", + "bytebuffer": "^5.0.1", + "permessage-deflate": "^0.1.7", + "tiny-typed-emitter": "^2.1.0", + "websocket-extensions": "^0.1.4" + }, + "engines": { + "node": ">=12.22.0" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "license": "ISC" + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "license": "MIT", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "license": "MIT", + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..d0d9fe9 --- /dev/null +++ b/package.json @@ -0,0 +1,44 @@ +{ + "name": "cs2-demo-downloader", + "version": "1.1.0", + "description": "", + "main": "index.js", + "bin": "dist/main.js", + "scripts": { + "build": "tsc && pkg . --targets node18-win-x64,node18-linux-x64,node18-macos-x64 --out-path dist" + }, + "keywords": [], + "author": "", + "license": "ISC", + "type": "commonjs", + "dependencies": { + "csgo-sharecode": "^3.1.2", + "decompress": "^4.2.1", + "decompress-bzip2": "^4.0.0", + "dotenv": "^16.5.0", + "globaloffensive": "^3.2.0", + "lzma": "^2.3.2", + "steam-session": "^1.9.3", + "steam-totp": "^2.1.2", + "steam-user": "^5.2.1", + "unbzip2-stream": "^1.4.3", + "undici": "^6.21.2", + "yargs": "^17.7.2" + }, + "devDependencies": { + "@types/decompress": "^4.2.7", + "@types/globaloffensive": "^2.3.4", + "@types/node": "^22.15.16", + "@types/steam-user": "^5.0.4", + "@types/unbzip2-stream": "^1.4.3", + "@types/yargs": "^17.0.33", + "ts-node": "^10.9.2", + "typescript": "^5.8.3" + }, + "pkg": { + "assets": [ + "node_modules/lzma/src/lzma_worker.js", + "node_modules/@doctormckay/steam-crypto/system.pem" + ] + } +} diff --git a/src/app/downloadDemoFile.ts b/src/app/downloadDemoFile.ts new file mode 100644 index 0000000..b3e1380 --- /dev/null +++ b/src/app/downloadDemoFile.ts @@ -0,0 +1,212 @@ +import fs from 'fs'; +import path from 'path'; +import https from 'https'; +import http from 'http'; +import { pipeline } from 'stream'; +import { promisify } from 'util'; +import bz2 from 'unbzip2-stream'; + +const pipe = promisify(pipeline); + +/** + * Entpackt eine .bz2-Datei mithilfe von Streams nach .dem + */ +async function extractBz2Safe(srcPath: string, destPath: string) { + try { + await pipe( + fs.createReadStream(srcPath), + bz2(), + fs.createWriteStream(destPath) + ); + } catch (err) { + console.log('❌ Fehler beim Entpacken (pipe):', err); + throw new Error('Entpackung fehlgeschlagen'); + } +} + +/** + * Lädt eine Datei per HTTPS, speichert sie unter `dest`, zeigt optional Fortschritt. + */ +function downloadWithHttps( + url: string, + dest: string, + onProgress?: (percent: number) => void, + maxRetries = 3, + retryDelay = 3000 +): Promise { + return new Promise((resolve, reject) => { + let attempt = 0; + + const tryDownload = () => { + const file = fs.createWriteStream(dest); + const client = url.startsWith('https') ? https : http; + + let downloaded = 0; + let total = 0; + let lastPercent = -1; + + const request = client.get(url, (res) => { + if (res.statusCode !== 200) { + res.resume(); + file.close(); + file.destroy(); + + if ([502, 503, 504].includes(res.statusCode!) && attempt < maxRetries) { + process.stdout.write(`🔁 Retry ${attempt + 1}/${maxRetries} – HTTP ${res.statusCode}\r`); + attempt++; + setTimeout(tryDownload, retryDelay); + return; + } + + if (attempt >= maxRetries) { + console.log(`❌ Max. Versuche erreicht (${maxRetries}), Datei wird übersprungen (HTTP ${res.statusCode})`); + return resolve(false); + } + + return reject(new Error(`HTTP ${res.statusCode}`)); + } + + total = parseInt(res.headers['content-length'] || '0', 10); + + res.on('data', (chunk) => { + downloaded += chunk.length; + if (onProgress && total) { + const percent = Math.floor((downloaded / total) * 100); + if (percent !== lastPercent) { + lastPercent = percent; + onProgress(percent); + } + } + }); + + res.pipe(file); + + file.on('finish', () => { + file.close((err) => { + if (err) return reject(err); + resolve(true); + }); + }); + + res.on('error', reject); + file.on('error', reject); + }); + + request.on('error', (err) => { + if (attempt < maxRetries) { + console.log(`🔁 Retry ${attempt + 1}/${maxRetries} wegen Verbindungsfehler: ${err.message}`); + attempt++; + setTimeout(tryDownload, retryDelay); + } else { + reject(err); + } + }); + }; + + tryDownload(); + }); +} + + + +/** + * Hauptfunktion: lädt und entpackt eine CS2-Demo (.bz2), mit Fortschrittsanzeige. + */ +export async function downloadDemoFile( + match: any, + steamId: string, + outputBaseDir = 'demos', + onProgress?: (percent: number) => void +): Promise { + if (!outputBaseDir || outputBaseDir.trim() === '') { + outputBaseDir = 'demos'; + } + + const appId = 730; + const matchId = match.matchid; + const timestamp = match.matchtime; + const matchDate = new Date(timestamp * 1000).toISOString().split('T')[0]; + + const lastRound = match.roundstatsall?.at(-1); + const demoUrl = + typeof lastRound?.map === 'string' && lastRound.map.endsWith('.bz2') + ? lastRound.map + : undefined; + + const mapName = + lastRound?.reservation?.map || + lastRound?.mapname || + match.watchablematchinfo?.game_map || + 'unknownmap'; + + if (!demoUrl) { + throw new Error('❌ Keine Demo-URL im Match vorhanden'); + } + + const isPremier = !!lastRound?.b_switched_teams; + const matchType = isPremier ? 'premier' : 'competitive'; + + const tempDir = path.join(outputBaseDir, 'temp'); + const tempFileName = `match${appId}_${mapName}_${matchId}_${matchType}.bz2`; + const baseName = path.parse(tempFileName).name; + const tempFile = path.join(tempDir, tempFileName); + + const finalDir = path.join(outputBaseDir, steamId, matchDate); + const finalFile = path.join(finalDir, `${baseName}.dem`); + const finalFileName = path.basename(finalFile) + + fs.mkdirSync(tempDir, { recursive: true }); + fs.mkdirSync(finalDir, { recursive: true }); + + console.log(`📥 Lade Demo von ${demoUrl}...`); + + try { + const success = await downloadWithHttps(demoUrl, tempFile, onProgress); + if (!success || !fs.existsSync(tempFile) || fs.statSync(tempFile).size === 0) { + console.warn(`⚠️ Download fehlgeschlagen oder Datei leer – lösche ${tempFileName}`); + + try { + if (fs.existsSync(tempFile)) fs.unlinkSync(tempFile); + } catch { + console.warn(`⚠️ Konnte leere Datei nicht löschen: ${tempFileName}`); + } + + return ''; + } + } catch (err) { + throw new Error(`❌ Fehler beim Download: ${err instanceof Error ? err.message : err}`); + } + + + console.log(`✅ Gespeichert als ${tempFileName}`); + + const entpackZeile = `🗜️ Entpacke ${finalFileName}...`; + process.stdout.write(entpackZeile); + + await extractBz2Safe(tempFile, finalFile); + + const successMessage = `✅ Entpackt: ${finalFileName}`; + const failMessage = `❌ Entpackung fehlgeschlagen – Datei nicht vorhanden`; + + // Max-Zeichenlänge bestimmen + const maxLength = Math.max(entpackZeile.length, successMessage.length, failMessage.length); + + if (!fs.existsSync(finalFile)) { + const paddedFail = failMessage.padEnd(maxLength, ' '); + process.stdout.write(`\r${paddedFail}\n`); + throw new Error(failMessage); + } + + const paddedSuccess = successMessage.padEnd(maxLength, ' '); + process.stdout.write(`\r${paddedSuccess}\n`); + + // Aufräumen + try { + fs.unlinkSync(tempFile); + console.log(`🧹 Gelöscht: ${tempFileName}`); + } catch { + console.log(`⚠️ Konnte temporäre Datei nicht löschen: ${tempFileName}`); + } + + return finalFile; +} diff --git a/src/app/fetchMatchFromSharecode.ts b/src/app/fetchMatchFromSharecode.ts new file mode 100644 index 0000000..eb1d4f5 --- /dev/null +++ b/src/app/fetchMatchFromSharecode.ts @@ -0,0 +1,21 @@ +import { decodeMatchShareCode } from 'csgo-sharecode'; +import { createSteamSession } from './steamSession'; +import { SteamSession } from '../types/types'; + +export async function fetchMatchFromShareCode( + shareCode: string, + session: SteamSession +): Promise { + const { csgo } = session; + const decoded = decodeMatchShareCode(shareCode); + + return new Promise((resolve, reject) => { + csgo.once('matchList', (matches) => { + const match = matches.find((m) => m.matchid === decoded.matchId.toString()); + if (!match) return reject(new Error('❌ Kein Match gefunden')); + resolve(match); + }); + + csgo.requestGame(shareCode); + }); +} \ No newline at end of file diff --git a/src/app/steamSession.ts b/src/app/steamSession.ts new file mode 100644 index 0000000..133b2d5 --- /dev/null +++ b/src/app/steamSession.ts @@ -0,0 +1,49 @@ +import SteamUser from 'steam-user'; +import GlobalOffensive from 'globaloffensive'; +import { SteamSession } from '../types/types'; + +export async function createSteamSession( + username: string, + password: string, + mfa?: string +): Promise { + const client = new SteamUser(); + const csgo = new GlobalOffensive(client); + + const loginPromise = new Promise((resolve, reject) => { + client.logOn({ + accountName: username, + password, + twoFactorCode: mfa, + }); + + client.once('loggedOn', () => { + console.log('✅ Eingeloggt bei Steam'); + client.setPersona(SteamUser.EPersonaState.Online); + client.gamesPlayed(730); + }); + + client.on('friendRelationship', (steamID, relationship) => { + if (relationship === SteamUser.EFriendRelationship.RequestRecipient) { + console.log(`➕ Freundschaftsanfrage von ${steamID.getSteamID64()} erhalten – wird akzeptiert`); + client.addFriend(steamID, (err) => { + if (err) { + console.error(`❌ Fehler beim Akzeptieren von ${steamID.getSteamID64()}:`, err); + } else { + console.log(`✅ Freund hinzugefügt: ${steamID.getSteamID64()}`); + } + }); + } + }); + + csgo.once('connectedToGC', () => { + console.log('🎮 Verbunden mit dem Game Coordinator'); + resolve(); + }); + + client.once('error', reject); + }); + + await loginPromise; + return { client, csgo }; +} \ No newline at end of file diff --git a/src/main.ts b/src/main.ts new file mode 100644 index 0000000..3de9332 --- /dev/null +++ b/src/main.ts @@ -0,0 +1,77 @@ +import yargs from 'yargs'; +import { hideBin } from 'yargs/helpers'; +import { createSteamSession } from './app/steamSession'; +import { fetchMatchFromShareCode } from './app/fetchMatchFromSharecode'; +import { downloadDemoFile } from './app/downloadDemoFile'; +import http from 'http'; +import fs from 'fs'; +import path from 'path'; + +const argv = yargs(hideBin(process.argv)).options({ + username: { type: 'string', demandOption: true }, + password: { type: 'string', demandOption: true }, + mfa: { type: 'string', demandOption: false }, + authCode: { type: 'string', demandOption: false }, + port: { type: 'number', default: 4000, demandOption: false }, + demoPath: { + type: 'string', + default: 'demos', + demandOption: false, + description: 'Zielverzeichnis für heruntergeladene Demos', + }, +}).parseSync(); + +const PORT = argv.port; + +const resolvedDemoPath = path.resolve(argv.demoPath); +if (!fs.existsSync(resolvedDemoPath)) { + fs.mkdirSync(resolvedDemoPath, { recursive: true }); + console.log(`📂 Verzeichnis erstellt: ${resolvedDemoPath}`); +} + +async function start() { + + const session = await createSteamSession(argv.username, argv.password, argv.mfa); + + console.log(`🚀 Server läuft auf http://localhost:${PORT}`); + http + .createServer(async (req, res) => { + if (req.method === 'POST' && req.url === '/download') { + let body = ''; + req.on('data', (chunk) => (body += chunk)); + req.on('end', async () => { + try { + const { shareCode, steamId } = JSON.parse(body); + console.log(`📦 ShareCode empfangen: ${shareCode}`); + + const match = await fetchMatchFromShareCode(shareCode, session); + const path = await downloadDemoFile( + match, + steamId, + resolvedDemoPath, + (percent: number) => { + process.stdout.write(`📶 Fortschritt: ${percent}%\r`); + if (percent === 100) { + console.log('✅ Download abgeschlossen'); + } + } + ); + + + res.writeHead(200, { 'Content-Type': 'application/json' }); + res.end(JSON.stringify({ success: true, path })); + } catch (err) { + console.error('❌ Fehler:', err); + res.writeHead(500, { 'Content-Type': 'application/json' }); + res.end(JSON.stringify({ success: false, error: err instanceof Error ? err.message : err })); + } + }); + } else { + res.writeHead(404); + res.end(); + } + }) + .listen(PORT); +} + +start(); diff --git a/src/types/types.ts b/src/types/types.ts new file mode 100644 index 0000000..a73cb3a --- /dev/null +++ b/src/types/types.ts @@ -0,0 +1,21 @@ +import SteamUser from 'steam-user'; +import GlobalOffensive from 'globaloffensive'; + +export type DecodedShareCode = { + matchId: bigint; + reservationId: bigint; + tvPort: number; + }; + +export type DownloadParams = { + decoded: DecodedShareCode; + username: string; + password: string; + authCode?: string; + outputPath: string; +}; + +export type SteamSession = { + client: SteamUser; + csgo: GlobalOffensive; +}; \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..ea0f0e5 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "outDir": "dist", + "rootDir": "src", + "target": "es2020", + "module": "commonjs", + "strict": true, + "esModuleInterop": true, + "moduleResolution": "node", + "types": ["node"] + }, + "include": ["src/**/*"] +}