UNPKG

@j03fr0st/pubg-ts

Version:

A comprehensive TypeScript wrapper for the PUBG API

478 lines 18.6 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.assetManager = exports.AssetManager = void 0; // Import the synced asset data and types const fuse_js_1 = __importDefault(require("fuse.js")); const damage_causer_name_json_1 = __importDefault(require("../assets/dictionaries/damage-causer-name.json")); const damage_type_category_json_1 = __importDefault(require("../assets/dictionaries/damage-type-category.json")); const game_mode_json_1 = __importDefault(require("../assets/dictionaries/game-mode.json")); const item_id_json_1 = __importDefault(require("../assets/dictionaries/item-id.json")); const map_name_json_1 = __importDefault(require("../assets/dictionaries/map-name.json")); const vehicle_id_json_1 = __importDefault(require("../assets/dictionaries/vehicle-id.json")); // Import the JSON files directly const seasons_json_1 = __importDefault(require("../assets/seasons.json")); const survival_titles_json_1 = __importDefault(require("../assets/survival-titles.json")); const errors_1 = require("../errors"); const logger_1 = require("./logger"); class AssetManager { constructor(config = {}) { this.cache = new Map(); this.itemCache = new Map(); this.vehicleCache = new Map(); this.seasonCache = new Map(); this.validateConfig(config); this.config = { baseUrl: 'https://raw.githubusercontent.com/pubg/api-assets/master', version: 'latest', cacheAssets: true, useLocalData: true, // Default to using local synced data ...config, }; // Build search indexes const allItems = Object.keys(item_id_json_1.default).map((id) => this.getItemInfo(id)); this.itemSearchIndex = new fuse_js_1.default(allItems, { keys: ['name', 'category', 'subcategory', 'description'], includeScore: true, threshold: 0.4, }); logger_1.logger.client('AssetManager initialized with search indexes', { config: this.config, usingLocalData: this.config.useLocalData, }); } /** * Get user-friendly item name with type safety */ getItemName(itemId) { if (this.config.useLocalData) { return item_id_json_1.default[itemId] || this.humanizeItemId(itemId); } // Legacy network fallback - would need async version return this.humanizeItemId(itemId); } /** * Get detailed item information with enhanced metadata */ getItemInfo(itemId) { if (!itemId || typeof itemId !== 'string') { throw new errors_1.PubgAssetError('Invalid item ID provided', itemId || 'undefined', 'item', { operation: 'get_item_info', metadata: { providedId: itemId }, }); } if (this.itemCache.has(itemId)) { return this.itemCache.get(itemId); } const name = this.getItemName(itemId); if (name === this.humanizeItemId(itemId) && !(itemId in item_id_json_1.default)) { return null; // Item doesn't exist in official data } const info = { id: itemId, name, category: this.categorizeItem(itemId), subcategory: this.subcategorizeItem(itemId), description: name, }; this.itemCache.set(itemId, info); return info; } /** * Get all items by category with type safety */ getItemsByCategory(category) { const items = []; for (const itemId of Object.keys(item_id_json_1.default)) { const info = this.getItemInfo(itemId); if (info && info.category === category) { items.push(info); } } return items.sort((a, b) => a.name.localeCompare(b.name)); } /** * Search items by name using fuzzy search. * @param query The search query. * @returns An array of item information, sorted by relevance. */ searchItems(query) { if (query.length < 2) { return []; } const results = this.itemSearchIndex.search(query); return results.map((result) => result.item); } /** * Get user-friendly vehicle name with type safety */ getVehicleName(vehicleId) { if (this.config.useLocalData) { return (vehicle_id_json_1.default[vehicleId] || this.humanizeVehicleId(vehicleId)); } return this.humanizeVehicleId(vehicleId); } /** * Get detailed vehicle information */ getVehicleInfo(vehicleId) { if (!vehicleId || typeof vehicleId !== 'string') { throw new errors_1.PubgAssetError('Invalid vehicle ID provided', vehicleId || 'undefined', 'vehicle', { operation: 'get_vehicle_info', metadata: { providedId: vehicleId }, }); } if (this.vehicleCache.has(vehicleId)) { return this.vehicleCache.get(vehicleId); } const name = this.getVehicleName(vehicleId); if (name === this.humanizeVehicleId(vehicleId) && !(vehicleId in vehicle_id_json_1.default)) { return null; } const info = { id: vehicleId, name, type: this.categorizeVehicle(vehicleId), category: 'vehicle', description: name, }; this.vehicleCache.set(vehicleId, info); return info; } /** * Get user-friendly map name with type safety */ getMapName(mapId) { if (this.config.useLocalData) { return map_name_json_1.default[mapId] || this.humanizeMapId(mapId); } return this.humanizeMapId(mapId); } /** * Get all available maps */ getAllMaps() { return Object.entries(map_name_json_1.default).map(([id, name]) => ({ id, name, })); } /** * Get season information by platform */ getSeasonsByPlatform(platform) { const validPlatforms = ['PC', 'XBOX', 'PS4', 'Stadia']; if (!validPlatforms.includes(platform)) { throw new errors_1.PubgConfigurationError(`Invalid platform '${platform}'. Valid platforms are: ${validPlatforms.join(', ')}`, 'platform', 'Platform', platform); } if (this.seasonCache.has(platform)) { return this.seasonCache.get(platform); } const platformSeasons = seasons_json_1.default[platform] || []; const enhancedSeasons = platformSeasons.map((season) => ({ id: season.id, platform, name: this.humanizeSeasonId(season.id), startDate: season.attributes.startDate, endDate: season.attributes.endDate, isActive: this.isSeasonActive(season.attributes.startDate, season.attributes.endDate), isOffseason: season.attributes.endDate === '00-00-0000', })); this.seasonCache.set(platform, enhancedSeasons); return enhancedSeasons; } /** * Get current active season for a platform */ getCurrentSeason(platform = 'PC') { if (!platform || typeof platform !== 'string') { throw new errors_1.PubgConfigurationError('Invalid platform provided', 'platform', 'Platform', platform); } const seasons = this.getSeasonsByPlatform(platform); return seasons.find((s) => s.isActive) || null; } /** * Get survival title information */ getSurvivalTitle(rating) { if (typeof rating !== 'number' || rating < 0 || !Number.isFinite(rating)) { throw new errors_1.PubgAssetError('Invalid survival rating provided', String(rating), 'survival_title', { operation: 'get_survival_title', metadata: { providedRating: rating } }); } const titles = survival_titles_json_1.default; // Find the appropriate title based on rating for (const [titleName, titleData] of Object.entries(titles)) { if (typeof titleData === 'object' && titleData !== null && titleData.levels) { const levels = titleData.levels; for (const levelInfo of levels) { if (this.isRatingInRange(rating, levelInfo.survivalPoints)) { return { title: titleName, level: levelInfo.level, pointsRequired: levelInfo.survivalPoints, description: `${titleName} Level ${levelInfo.level}`, }; } } } } return null; } /** * Get damage causer name */ getDamageCauserName(causerId) { return damage_causer_name_json_1.default[causerId] || causerId; } /** * Get damage type category */ getDamageTypeCategory(damageType) { return damage_type_category_json_1.default[damageType] || damageType; } /** * Get game mode name */ getGameModeName(gameModeId) { return game_mode_json_1.default[gameModeId] || gameModeId; } // Legacy async methods for backward compatibility /** * @deprecated Use getSeasonsByPlatform('PC') for better performance with local data. * This method will be removed in v2.0.0. * * @example * // Instead of: * const seasons = await assetManager.getSeasons(); * * // Use: * const seasons = assetManager.getSeasonsByPlatform('PC'); */ async getSeasons() { if (process.env.NODE_ENV !== 'test') { console.warn('[DEPRECATION WARNING] AssetManager.getSeasons() is deprecated. ' + 'Use getSeasonsByPlatform() for better performance with local data. ' + 'This method will be removed in v2.0.0.'); } return this.getSeasonsByPlatform('PC'); } /** * Get asset URL for items, weapons, vehicles, etc. */ getAssetUrl(category, itemId, type = 'icon') { const cleanId = this.cleanItemId(itemId); return `${this.config.baseUrl}/assets/${category}/${type}s/${cleanId}.png`; } /** * Get weapon asset URL with type safety */ getWeaponAssetUrl(weaponId, type = 'icon') { return this.getAssetUrl('weapons', weaponId, type); } /** * Get equipment asset URL with type safety */ getEquipmentAssetUrl(equipmentId, type = 'icon') { return this.getAssetUrl('equipment', equipmentId, type); } /** * Get vehicle asset URL with type safety */ getVehicleAssetUrl(vehicleId, type = 'icon') { return this.getAssetUrl('vehicles', vehicleId, type); } /** * Get statistics about the asset data */ getAssetStats() { const items = Object.keys(item_id_json_1.default); const categoryCounts = {}; for (const itemId of items) { const category = this.categorizeItem(itemId); categoryCounts[category] = (categoryCounts[category] || 0) + 1; } return { totalItems: items.length, totalVehicles: Object.keys(vehicle_id_json_1.default).length, totalMaps: Object.keys(map_name_json_1.default).length, categoryCounts, }; } /** * Clear asset cache */ clearCache() { try { this.cache.clear(); this.itemCache.clear(); this.vehicleCache.clear(); this.seasonCache.clear(); logger_1.logger.cache('All asset caches cleared'); } catch (error) { throw new errors_1.PubgCacheError('Failed to clear asset caches', 'all_caches', 'cleanup', { metadata: { originalError: error }, }); } } // Private helper methods categorizeItem(itemId) { if (itemId.includes('Weapon')) return 'weapon'; if (itemId.includes('Heal') || itemId.includes('Boost')) return 'consumable'; if (itemId.includes('Attach')) return 'attachment'; if (itemId.includes('Armor') || itemId.includes('Back')) return 'equipment'; if (itemId.includes('Ammo')) return 'ammunition'; return 'other'; } subcategorizeItem(itemId) { // Weapons if (itemId.includes('AR') || itemId.includes('AK') || itemId.includes('M416') || itemId.includes('SCAR')) return 'assault_rifle'; if (itemId.includes('SMG') || itemId.includes('UMP') || itemId.includes('Vector')) return 'smg'; if (itemId.includes('SR') || itemId.includes('Kar98') || itemId.includes('AWM')) return 'sniper_rifle'; if (itemId.includes('Shotgun') || itemId.includes('S686') || itemId.includes('S1897')) return 'shotgun'; if (itemId.includes('Pistol') || itemId.includes('P92') || itemId.includes('P1911')) return 'pistol'; // Healing if (itemId.includes('Bandage')) return 'healing'; if (itemId.includes('FirstAid')) return 'healing'; if (itemId.includes('MedKit')) return 'healing'; if (itemId.includes('Drink') || itemId.includes('Pill')) return 'boost'; // Attachments if (itemId.includes('Upper')) return 'sight'; if (itemId.includes('Lower')) return 'grip'; if (itemId.includes('Muzzle')) return 'muzzle'; if (itemId.includes('Magazine')) return 'magazine'; return 'general'; } categorizeVehicle(vehicleId) { if (vehicleId.includes('Motorbike') || vehicleId.includes('Motorcycle')) return 'two_wheeler'; if (vehicleId.includes('Car') || vehicleId.includes('Pickup') || vehicleId.includes('Van')) return 'four_wheeler'; if (vehicleId.includes('Boat') || vehicleId.includes('Ship')) return 'watercraft'; if (vehicleId.includes('Plane') || vehicleId.includes('Glider')) return 'aircraft'; return 'unknown'; } humanizeItemId(itemId) { return itemId .replace(/^Item_/, '') .replace(/_C$/, '') .replace(/_/g, ' ') .replace(/\b\w/g, (l) => l.toUpperCase()); } humanizeVehicleId(vehicleId) { return vehicleId .replace(/^BP_/, '') .replace(/_\d+_C$/, '') .replace(/_/g, ' ') .replace(/\b\w/g, (l) => l.toUpperCase()); } humanizeMapId(mapId) { return mapId.replace(/([A-Z])/g, ' $1').trim(); } humanizeSeasonId(seasonId) { // Extract season info from ID like "division.bro.official.pc-2018-01" const parts = seasonId.split('.'); const lastPart = parts[parts.length - 1]; const match = lastPart.match(/(\w+)-(\d{4})-(\d{2})/); if (match) { const [, platform, year, season] = match; return `${platform.toUpperCase()} Season ${parseInt(season)} (${year})`; } return seasonId; } isSeasonActive(startDate, endDate) { if (endDate === '00-00-0000') return true; // Ongoing season const now = new Date(); const start = this.parseDate(startDate); const end = this.parseDate(endDate); return start <= now && now <= end; } parseDate(dateStr) { if (!dateStr || typeof dateStr !== 'string') { throw new errors_1.PubgValidationError('Invalid date string provided', { operation: 'parse_date', metadata: { providedDate: dateStr }, }); } // Handle MM-DD-YYYY format const parts = dateStr.split('-'); if (parts.length !== 3) { throw new errors_1.PubgValidationError(`Invalid date format '${dateStr}'. Expected MM-DD-YYYY format`, { operation: 'parse_date', metadata: { providedDate: dateStr, format: 'MM-DD-YYYY' } }); } const [month, day, year] = parts.map(Number); if (Number.isNaN(month) || Number.isNaN(day) || Number.isNaN(year)) { throw new errors_1.PubgValidationError(`Invalid date components in '${dateStr}'. All parts must be numeric`, { operation: 'parse_date', metadata: { month, day, year } }); } return new Date(year, month - 1, day); } isRatingInRange(rating, range) { const rangeStr = String(range); if (rangeStr.includes('+')) { const minRating = parseInt(rangeStr.replace('+', '')); return rating >= minRating; } if (rangeStr.includes('-')) { const [min, max] = rangeStr.split('-').map(Number); return rating >= min && rating <= max; } // Handle exact number matches const exactNumber = parseInt(rangeStr); if (!Number.isNaN(exactNumber)) { return rating === exactNumber; } return false; } cleanItemId(itemId) { return itemId .replace(/^Item_/, '') .replace(/^BP_/, '') .replace(/_\d+_C$/, '') .replace(/_C$/, ''); } /** * Validate configuration object */ validateConfig(config) { if (config.baseUrl && typeof config.baseUrl !== 'string') { throw new errors_1.PubgConfigurationError('baseUrl must be a string', 'baseUrl', 'string', config.baseUrl); } if (config.version && typeof config.version !== 'string') { throw new errors_1.PubgConfigurationError('version must be a string', 'version', 'string', config.version); } if (config.cacheAssets !== undefined && typeof config.cacheAssets !== 'boolean') { throw new errors_1.PubgConfigurationError('cacheAssets must be a boolean', 'cacheAssets', 'boolean', config.cacheAssets); } if (config.useLocalData !== undefined && typeof config.useLocalData !== 'boolean') { throw new errors_1.PubgConfigurationError('useLocalData must be a boolean', 'useLocalData', 'boolean', config.useLocalData); } } } exports.AssetManager = AssetManager; // Export a default instance exports.assetManager = new AssetManager(); //# sourceMappingURL=assets.js.map