Files
minecraft_launcher/app/assets/js/distromanager.js
claude-bot 20677380b9
Some checks failed
Build / release (macos-latest) (push) Has been cancelled
Build / release (ubuntu-latest) (push) Has been cancelled
Build / release (windows-latest) (push) Has been cancelled
Windows Smoke Test / windows-smoke (push) Has been cancelled
Fix launch cache sanitization and progress layout
2026-05-06 04:58:12 +09:00

184 lines
5.4 KiB
JavaScript

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
}
})