183 lines
4.9 KiB
JavaScript
183 lines
4.9 KiB
JavaScript
const logger = require('../utils/logger');
|
|
|
|
/**
|
|
* API Mod Service - Handles mod management through API communication with GameServer
|
|
* This service acts as a client to the GameServer's mod functionality
|
|
*/
|
|
class ApiModService {
|
|
constructor() {
|
|
// Use service discovery - try multiple common GameServer locations
|
|
this.gameServerUrls = [
|
|
process.env.GAME_SERVER_URL,
|
|
'http://localhost:3002',
|
|
'http://127.0.0.1:3002',
|
|
'http://game-server:3002' // Docker service name
|
|
].filter(url => url); // Remove null/undefined values
|
|
|
|
this.currentUrlIndex = 0;
|
|
}
|
|
|
|
async getGameServerUrl() {
|
|
// Try each URL until we find a working one
|
|
for (let i = 0; i < this.gameServerUrls.length; i++) {
|
|
const url = this.gameServerUrls[i];
|
|
try {
|
|
const response = await fetch(`${url}/health`, {
|
|
timeout: 5000 // 5 second timeout
|
|
});
|
|
if (response.ok) {
|
|
this.currentUrlIndex = i;
|
|
return url;
|
|
}
|
|
} catch (error) {
|
|
logger.debug(`[API MOD SERVICE] GameServer at ${url} not available:`, error.message);
|
|
}
|
|
}
|
|
|
|
throw new Error('No GameServer instances available');
|
|
}
|
|
|
|
async makeRequest(endpoint, options = {}) {
|
|
const url = await this.getGameServerUrl();
|
|
const fullUrl = `${url}${endpoint}`;
|
|
|
|
const defaultOptions = {
|
|
timeout: 10000, // 10 second timeout
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'User-Agent': 'API-ModService/1.0'
|
|
}
|
|
};
|
|
|
|
const finalOptions = { ...defaultOptions, ...options };
|
|
|
|
try {
|
|
const response = await fetch(fullUrl, finalOptions);
|
|
if (!response.ok) {
|
|
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
}
|
|
return await response.json();
|
|
} catch (error) {
|
|
logger.error(`[API MOD SERVICE] Request to ${fullUrl} failed:`, error);
|
|
|
|
// If request failed, try next GameServer URL
|
|
this.currentUrlIndex = (this.currentUrlIndex + 1) % this.gameServerUrls.length;
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
async getMods(enabledOnly = false) {
|
|
try {
|
|
const endpoint = `/api/mods${enabledOnly ? '?enabledOnly=true' : ''}`;
|
|
return await this.makeRequest(endpoint);
|
|
} catch (error) {
|
|
logger.error('[API MOD SERVICE] Error getting mods:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
async getMod(id) {
|
|
try {
|
|
return await this.makeRequest(`/api/mods/${id}`);
|
|
} catch (error) {
|
|
logger.error('[API MOD SERVICE] Error getting mod:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
async enableMod(id) {
|
|
try {
|
|
return await this.makeRequest(`/api/mods/${id}/enable`, {
|
|
method: 'POST'
|
|
});
|
|
} catch (error) {
|
|
logger.error('[API MOD SERVICE] Error enabling mod:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
async disableMod(id) {
|
|
try {
|
|
return await this.makeRequest(`/api/mods/${id}/disable`, {
|
|
method: 'POST'
|
|
});
|
|
} catch (error) {
|
|
logger.error('[API MOD SERVICE] Error disabling mod:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
async getModAssets(assetType) {
|
|
try {
|
|
return await this.makeRequest(`/api/mods/assets/${assetType}`);
|
|
} catch (error) {
|
|
logger.error('[API MOD SERVICE] Error getting mod assets:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
async getModAsset(assetType, assetId) {
|
|
try {
|
|
return await this.makeRequest(`/api/mods/assets/${assetType}/${assetId}`);
|
|
} catch (error) {
|
|
logger.error('[API MOD SERVICE] Error getting mod asset:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
async getLoadOrder() {
|
|
try {
|
|
return await this.makeRequest('/api/mods/load-order');
|
|
} catch (error) {
|
|
logger.error('[API MOD SERVICE] Error getting load order:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
async setLoadOrder(modIds) {
|
|
try {
|
|
return await this.makeRequest('/api/mods/load-order', {
|
|
method: 'POST',
|
|
body: JSON.stringify({ modIds })
|
|
});
|
|
} catch (error) {
|
|
logger.error('[API MOD SERVICE] Error setting load order:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
async getServerPreferences() {
|
|
try {
|
|
return await this.makeRequest('/api/mods/preferences/server');
|
|
} catch (error) {
|
|
logger.error('[API MOD SERVICE] Error getting server preferences:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
async setServerPreference(key, value) {
|
|
try {
|
|
return await this.makeRequest('/api/mods/preferences/server', {
|
|
method: 'POST',
|
|
body: JSON.stringify({ key, value })
|
|
});
|
|
} catch (error) {
|
|
logger.error('[API MOD SERVICE] Error setting server preference:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
async reloadMods() {
|
|
try {
|
|
return await this.makeRequest('/api/mods/reload', {
|
|
method: 'POST'
|
|
});
|
|
} catch (error) {
|
|
logger.error('[API MOD SERVICE] Error reloading mods:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
}
|
|
|
|
module.exports = new ApiModService();
|