const { DistributionAPI, HeliosDistribution } = require('helios-core/common') const ConfigManager = require('./configmanager') const DEFAULT_REMOTE_DISTRO_URL = 'https://cdn.mysticred.space/launcher/distribution.json' let remoteDistroUrl = DEFAULT_REMOTE_DISTRO_URL let activeApi = createApi(remoteDistroUrl) function distributionsDiffer(left, right){ return JSON.stringify(left) !== JSON.stringify(right) } function sanitizeServer(rawServer){ const nextServer = { ...rawServer } if(typeof nextServer.address !== 'string' || nextServer.address.trim().length === 0){ nextServer.address = '127.0.0.1:25565' } else { nextServer.address = nextServer.address.trim() } if(!Array.isArray(nextServer.modules)){ nextServer.modules = [] } if(typeof nextServer.minecraftVersion !== 'string' || nextServer.minecraftVersion.trim().length === 0){ nextServer.minecraftVersion = typeof nextServer.version === 'string' && nextServer.version.trim().length > 0 ? nextServer.version.trim() : '1.20.1' } return nextServer } function sanitizeDistribution(rawDistribution){ const nextDistribution = rawDistribution == null ? { version: '1.0.0', rss: '', servers: [] } : { ...rawDistribution } nextDistribution.servers = Array.isArray(nextDistribution.servers) ? nextDistribution.servers.map((server) => sanitizeServer(server)) : [] return nextDistribution } function buildDistribution(api, rawDistribution){ const sanitizedDistribution = sanitizeDistribution(rawDistribution) api.rawDistribution = sanitizedDistribution api.distribution = new HeliosDistribution(sanitizedDistribution, api.commonDir, api.instanceDir) return api.distribution } function patchDistributionApi(api){ const originalPullRemote = api.pullRemote.bind(api) const originalPullLocal = api.pullLocal.bind(api) const originalWriteDistributionToDisk = api.writeDistributionToDisk.bind(api) api.writeDistributionToDisk = async function(distribution){ const sanitizedDistribution = sanitizeDistribution(distribution) await originalWriteDistributionToDisk(sanitizedDistribution) } api.pullRemote = async function(){ const response = await originalPullRemote() if(response?.data != null){ response.data = sanitizeDistribution(response.data) } return response } api.pullLocal = async function(){ const rawDistribution = await originalPullLocal() if(rawDistribution == null){ return rawDistribution } const sanitizedDistribution = sanitizeDistribution(rawDistribution) if(distributionsDiffer(rawDistribution, sanitizedDistribution)){ await originalWriteDistributionToDisk(sanitizedDistribution) } return sanitizedDistribution } api.getDistribution = async function(){ if(this.rawDistribution == null || this.distribution == null){ const rawDistribution = await this.loadDistribution() return buildDistribution(this, rawDistribution) } return this.distribution } api.getDistributionLocalLoadOnly = async function(){ if(this.rawDistribution == null || this.distribution == null){ const rawDistribution = await this.pullLocal() if(rawDistribution == null){ throw new Error('FATAL: Unable to load distribution from local disk.') } return buildDistribution(this, rawDistribution) } return this.distribution } api.refreshDistributionOrFallback = async function(){ const rawDistribution = await this._loadDistributionNullable() if(rawDistribution == null){ return this.distribution } return buildDistribution(this, rawDistribution) } return api } function createApi(url) { const api = new DistributionAPI( ConfigManager.getLauncherDirectory(), null, null, url, false ) return patchDistributionApi(api) } function replaceApi(url) { const nextApi = createApi(url) if(activeApi != null){ if(typeof activeApi.commonDir !== 'undefined'){ nextApi.commonDir = activeApi.commonDir } if(typeof activeApi.instanceDir !== 'undefined'){ nextApi.instanceDir = activeApi.instanceDir } if(typeof activeApi.isDevMode === 'function' && activeApi.isDevMode()){ nextApi.toggleDevMode(true) } } activeApi = nextApi remoteDistroUrl = url } exports.DEFAULT_REMOTE_DISTRO_URL = DEFAULT_REMOTE_DISTRO_URL exports.getRemoteDistributionUrl = function() { return remoteDistroUrl } exports.setRemoteDistributionUrl = function(url) { if(url != null && url.trim().length > 0 && url !== remoteDistroUrl){ replaceApi(url) } return remoteDistroUrl } exports.resetRemoteDistributionUrl = function() { replaceApi(DEFAULT_REMOTE_DISTRO_URL) return remoteDistroUrl } exports.DistroAPI = new Proxy({}, { get(_target, prop) { const value = activeApi[prop] if(typeof value === 'function'){ return value.bind(activeApi) } return value }, set(_target, prop, value) { activeApi[prop] = value return true }, has(_target, prop) { return prop in activeApi } })