// src/services/PlayerService.js const axios = require('axios'); class PlayerService { constructor() { this.baseUrl = 'https://www.vrbattles.gg'; } async findUserByUsername(username) { try { console.log(`Fetching data for username: ${username}`); const url = `${this.baseUrl}/api/get_player_data_by_username/${encodeURIComponent(username)}`; console.log(`API URL: ${url}`); const response = await axios.get(url, { timeout: 5000 }); console.log('API Response:', JSON.stringify(response.data, null, 2)); if (response.data && response.data.success) { // Parse player_data if it's a string if (typeof response.data.player_data === 'string') { try { response.data.player_data = JSON.parse(response.data.player_data); } catch (parseError) { console.error('Error parsing player_data:', parseError); } } } return response.data; } catch (error) { console.error('Error fetching user data:', { message: error.message, response: error.response?.data, status: error.response?.status }); return null; } } getBadgeImageUrl(badgeName) { if (!badgeName) { return `${this.baseUrl}/assets/images/badges/xp_badges/A/BADGE_A1_72p.png`; } badgeName = badgeName.toUpperCase().replace(/ /g, '_'); let badgeUrl = `${this.baseUrl}/assets/images/badges/xp_badges/`; if (badgeName.startsWith('A')) { badgeUrl += 'A/'; } else if (badgeName.startsWith('B')) { badgeUrl += 'B/'; } else if (badgeName.startsWith('C')) { badgeUrl += 'C/'; } else if (badgeName.startsWith('D')) { badgeUrl += 'D/'; } else if (badgeName.startsWith('E')) { badgeUrl += 'E/'; } else if (badgeName.startsWith('F')) { badgeUrl += 'F/'; } else { badgeUrl += 'A/'; // Default to A tier } badgeUrl += `BADGE_${badgeName}_72p.png`; return badgeUrl; } getProfileUrl(username) { return `${this.baseUrl}/profile/${username}`; } getStatsUrl(username) { return `${this.baseUrl}/profile/${username}/stats`; } async getTournamentsData() { try { console.log('Fetching tournaments data...'); const url = `${this.baseUrl}/api/fetch/tournaments`; console.log(`API URL: ${url}`); const response = await axios.get(url, { timeout: 5000, headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' }, validateStatus: function (status) { return status >= 200 && status < 300; } }); console.log('Tournaments API Response:', JSON.stringify(response.data, null, 2)); return response.data; } catch (error) { console.error('Error fetching tournaments data:', { message: error.message, response: error.response?.data, status: error.response?.status }); return { success: false, error: 'Failed to fetch tournaments data' }; } } async getTournamentData(tournamentId) { const url = `${this.baseUrl}/api/get_tournament_data/${tournamentId}`; const response = await axios.get(url); return response.data; } async findTeamByName(teamName, gameFilter) { try { // Double-check sanitization here as well for defense in depth if (!teamName || typeof teamName !== 'string') { throw new Error('Invalid team name provided'); } // Additional sanitization at the service level const sanitizedTeamName = teamName .replace(/[^a-zA-Z0-9\s\-_.]/g, '') .trim() .slice(0, 100); if (!sanitizedTeamName) { throw new Error('Invalid team name after sanitization'); } // Use URL encoding for the query parameters const encodedTeamName = encodeURIComponent(sanitizedTeamName); const url = `${this.baseUrl}/api/get_team_data_by_name/${encodedTeamName}`; const response = await axios.get(url, { timeout: 5000, // 5 second timeout headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' }, validateStatus: function (status) { return status >= 200 && status < 300; // Only accept success status codes } }); // Validate response structure if (!response.data || typeof response.data !== 'object') { throw new Error('Invalid response format from API'); } // If game filter is provided, filter the teams if (gameFilter && response.data.teams) { response.data.teams = response.data.teams.filter( team => team.game_name === gameFilter ); } return response.data; } catch (error) { this.logger.error('Error in findTeamByName:', { error: error.message, teamName, gameFilter, timestamp: new Date().toISOString() }); return { success: false, error: 'Failed to fetch team data' }; } } } module.exports = PlayerService;