'use strict'; const fs = require('fs'); const os = require('os'); const path = require('path'); function parseClientVersion(text) { const raw = String(text).match(/^ClientVersion=(\d+)\s*$/m)?.[1] || ''; if (!raw) return null; const version = Number(raw); return Number.isInteger(version) && version > 0 && version <= 0xffffffff ? version : null; } function parseVersionOverride(value) { const raw = String(value ?? '').trim(); if (!raw) return null; if (!/^\d+$/.test(raw)) throw new Error('DOTA_CLIENT_VERSION must contain digits only.'); const version = Number(raw); if (!Number.isInteger(version) || version < 1 || version > 0xffffffff) { throw new Error('DOTA_CLIENT_VERSION must be an unsigned 32-bit integer.'); } return version; } function defaultSteamInfFiles() { const home = os.homedir(); return [ process.env.DOTA_STEAM_INF, path.join(home, '.local', 'share', 'Steam', 'steamapps', 'common', 'dota 2 beta', 'game', 'dota', 'steam.inf'), path.join(home, '.steam', 'steam', 'steamapps', 'common', 'dota 2 beta', 'game', 'dota', 'steam.inf'), path.join('/steam', 'steamapps', 'common', 'dota 2 beta', 'game', 'dota', 'steam.inf'), ].filter(Boolean); } function resolveDotaClientVersion(files = defaultSteamInfFiles()) { const override = parseVersionOverride(process.env.DOTA_CLIENT_VERSION); if (override) return { version: override, source: 'environment' }; for (const file of [...new Set(files)]) { try { const version = parseClientVersion(fs.readFileSync(file, 'utf8')); if (version) return { version, source: file }; } catch (err) { if (err.code !== 'ENOENT' && err.code !== 'ENOTDIR') { console.warn(`warn: could not read Dota client version ${file}: ${err.message}`); } } } return { version: null, source: null }; } module.exports = { parseClientVersion, resolveDotaClientVersion, };