mirror of
https://github.com/dscalzi/HeliosLauncher.git
synced 2024-12-22 11:42:14 -08:00
Changes to prevent cyclic dependencies.
This commit is contained in:
parent
086bfc8593
commit
0dde4bce42
@ -2,7 +2,7 @@ const mojang = require('mojang')
|
|||||||
const path = require('path')
|
const path = require('path')
|
||||||
const {AssetGuard} = require(path.join(__dirname, 'assets', 'js', 'assetguard.js'))
|
const {AssetGuard} = require(path.join(__dirname, 'assets', 'js', 'assetguard.js'))
|
||||||
const ProcessBuilder = require(path.join(__dirname, 'assets', 'js', 'processbuilder.js'))
|
const ProcessBuilder = require(path.join(__dirname, 'assets', 'js', 'processbuilder.js'))
|
||||||
const {GAME_DIRECTORY, DEFAULT_CONFIG} = require(path.join(__dirname, 'assets', 'js', 'constants.js'))
|
const {GAME_DIRECTORY, DEFAULT_CONFIG} = require(path.join(__dirname, 'assets', 'js', 'enumerator.js')).enum
|
||||||
|
|
||||||
document.addEventListener('readystatechange', function(){
|
document.addEventListener('readystatechange', function(){
|
||||||
if (document.readyState === 'interactive'){
|
if (document.readyState === 'interactive'){
|
||||||
@ -13,14 +13,9 @@ document.addEventListener('readystatechange', function(){
|
|||||||
testdownloads()
|
testdownloads()
|
||||||
})
|
})
|
||||||
|
|
||||||
if(DEFAULT_CONFIG.getSelectedServer() == null){
|
|
||||||
console.log('Determining default selected server..')
|
|
||||||
DEFAULT_CONFIG.setSelectedServer(AssetGuard.resolveSelectedServer())
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO convert this to dropdown menu.
|
// TODO convert this to dropdown menu.
|
||||||
// Bind selected server
|
// Bind selected server
|
||||||
document.getElementById('server_selection').innerHTML = '\u2022 ' + AssetGuard.getServerById(DEFAULT_CONFIG.getSelectedServer()).name
|
document.getElementById('server_selection').innerHTML = '\u2022 ' + AssetGuard.getServerById(GAME_DIRECTORY, DEFAULT_CONFIG.getSelectedServer()).name
|
||||||
|
|
||||||
}
|
}
|
||||||
}, false)
|
}, false)
|
||||||
@ -40,33 +35,34 @@ testdownloads = async function(){
|
|||||||
details.style.display = 'flex'
|
details.style.display = 'flex'
|
||||||
content.style.display = 'none'
|
content.style.display = 'none'
|
||||||
|
|
||||||
tracker = new AssetGuard()
|
console.log(DEFAULT_CONFIG.getJavaExecutable())
|
||||||
|
tracker = new AssetGuard(GAME_DIRECTORY, DEFAULT_CONFIG.getJavaExecutable())
|
||||||
|
|
||||||
det_text.innerHTML = 'Loading server information..'
|
det_text.innerHTML = 'Loading server information..'
|
||||||
const serv = await tracker.validateDistribution(DEFAULT_CONFIG.getSelectedServer(), GAME_DIRECTORY)
|
const serv = await tracker.validateDistribution(DEFAULT_CONFIG.getSelectedServer())
|
||||||
progress.setAttribute('value', 20)
|
progress.setAttribute('value', 20)
|
||||||
progress_text.innerHTML = '20%'
|
progress_text.innerHTML = '20%'
|
||||||
console.log('forge stuff done')
|
console.log('forge stuff done')
|
||||||
|
|
||||||
det_text.innerHTML = 'Loading version information..'
|
det_text.innerHTML = 'Loading version information..'
|
||||||
const versionData = await tracker.loadVersionData(serv.mc_version, GAME_DIRECTORY)
|
const versionData = await tracker.loadVersionData(serv.mc_version)
|
||||||
progress.setAttribute('value', 40)
|
progress.setAttribute('value', 40)
|
||||||
progress_text.innerHTML = '40%'
|
progress_text.innerHTML = '40%'
|
||||||
|
|
||||||
det_text.innerHTML = 'Validating asset integrity..'
|
det_text.innerHTML = 'Validating asset integrity..'
|
||||||
await tracker.validateAssets(versionData, GAME_DIRECTORY)
|
await tracker.validateAssets(versionData)
|
||||||
progress.setAttribute('value', 60)
|
progress.setAttribute('value', 60)
|
||||||
progress_text.innerHTML = '60%'
|
progress_text.innerHTML = '60%'
|
||||||
console.log('assets done')
|
console.log('assets done')
|
||||||
|
|
||||||
det_text.innerHTML = 'Validating library integrity..'
|
det_text.innerHTML = 'Validating library integrity..'
|
||||||
await tracker.validateLibraries(versionData, GAME_DIRECTORY)
|
await tracker.validateLibraries(versionData)
|
||||||
progress.setAttribute('value', 80)
|
progress.setAttribute('value', 80)
|
||||||
progress_text.innerHTML = '80%'
|
progress_text.innerHTML = '80%'
|
||||||
console.log('libs done')
|
console.log('libs done')
|
||||||
|
|
||||||
det_text.innerHTML = 'Validating miscellaneous file integrity..'
|
det_text.innerHTML = 'Validating miscellaneous file integrity..'
|
||||||
await tracker.validateMiscellaneous(versionData, GAME_DIRECTORY)
|
await tracker.validateMiscellaneous(versionData)
|
||||||
progress.setAttribute('value', 100)
|
progress.setAttribute('value', 100)
|
||||||
progress_text.innerHTML = '100%'
|
progress_text.innerHTML = '100%'
|
||||||
console.log('files done')
|
console.log('files done')
|
||||||
@ -81,7 +77,7 @@ testdownloads = async function(){
|
|||||||
tracker.on('dlcomplete', async function(){
|
tracker.on('dlcomplete', async function(){
|
||||||
|
|
||||||
det_text.innerHTML = 'Preparing to launch..'
|
det_text.innerHTML = 'Preparing to launch..'
|
||||||
const forgeData = await tracker.loadForgeData(serv.id, GAME_DIRECTORY)
|
const forgeData = await tracker.loadForgeData(serv.id)
|
||||||
const authUser = await mojang.auth('EMAIL', 'PASS', DEFAULT_CONFIG.getClientToken(), {
|
const authUser = await mojang.auth('EMAIL', 'PASS', DEFAULT_CONFIG.getClientToken(), {
|
||||||
name: 'Minecraft',
|
name: 'Minecraft',
|
||||||
version: 1
|
version: 1
|
||||||
|
@ -26,7 +26,6 @@ const AdmZip = require('adm-zip')
|
|||||||
const async = require('async')
|
const async = require('async')
|
||||||
const child_process = require('child_process')
|
const child_process = require('child_process')
|
||||||
const crypto = require('crypto')
|
const crypto = require('crypto')
|
||||||
const {DEFAULT_CONFIG, DISTRO_DIRECTORY} = require('./constants')
|
|
||||||
const EventEmitter = require('events')
|
const EventEmitter = require('events')
|
||||||
const fs = require('fs')
|
const fs = require('fs')
|
||||||
const mkpath = require('mkdirp');
|
const mkpath = require('mkdirp');
|
||||||
@ -165,11 +164,15 @@ let distributionData = null
|
|||||||
class AssetGuard extends EventEmitter {
|
class AssetGuard extends EventEmitter {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AssetGuard class should only ever have one instance which is defined in
|
* Create an instance of AssetGuard.
|
||||||
* this module. On creation the object's properties are never-null default
|
* On creation the object's properties are never-null default
|
||||||
* values. Each identifier is resolved to an empty DLTracker.
|
* values. Each identifier is resolved to an empty DLTracker.
|
||||||
|
*
|
||||||
|
* @param {String} basePath - base path for asset validation (game root).
|
||||||
|
* @param {String} javaexec - path to a java executable which will be used
|
||||||
|
* to finalize installation.
|
||||||
*/
|
*/
|
||||||
constructor(){
|
constructor(basePath, javaexec){
|
||||||
super()
|
super()
|
||||||
this.totaldlsize = 0;
|
this.totaldlsize = 0;
|
||||||
this.progress = 0;
|
this.progress = 0;
|
||||||
@ -177,6 +180,8 @@ class AssetGuard extends EventEmitter {
|
|||||||
this.libraries = new DLTracker([], 0)
|
this.libraries = new DLTracker([], 0)
|
||||||
this.files = new DLTracker([], 0)
|
this.files = new DLTracker([], 0)
|
||||||
this.forge = new DLTracker([], 0)
|
this.forge = new DLTracker([], 0)
|
||||||
|
this.basePath = basePath
|
||||||
|
this.javaexec = javaexec
|
||||||
}
|
}
|
||||||
|
|
||||||
// Static Utility Functions
|
// Static Utility Functions
|
||||||
@ -277,16 +282,17 @@ class AssetGuard extends EventEmitter {
|
|||||||
/**
|
/**
|
||||||
* Statically retrieve the distribution data.
|
* Statically retrieve the distribution data.
|
||||||
*
|
*
|
||||||
|
* @param {String} basePath - base path for asset validation (game root).
|
||||||
* @param {Boolean} cached - optional. False if the distro should be freshly downloaded, else
|
* @param {Boolean} cached - optional. False if the distro should be freshly downloaded, else
|
||||||
* a cached copy will be returned.
|
* a cached copy will be returned.
|
||||||
* @returns {Promise.<Object>} - A promise which resolves to the distribution data object.
|
* @returns {Promise.<Object>} - A promise which resolves to the distribution data object.
|
||||||
*/
|
*/
|
||||||
static retrieveDistributionData(cached = true){
|
static retrieveDistributionData(basePath, cached = true){
|
||||||
return new Promise(function(fulfill, reject){
|
return new Promise(function(fulfill, reject){
|
||||||
if(!cached || distributionData == null){
|
if(!cached || distributionData == null){
|
||||||
// TODO Download file from upstream.
|
// TODO Download file from upstream.
|
||||||
//const distroURL = 'http://mc.westeroscraft.com/WesterosCraftLauncher/westeroscraft.json'
|
//const distroURL = 'http://mc.westeroscraft.com/WesterosCraftLauncher/westeroscraft.json'
|
||||||
// TODO Save file to DISTRO_DIRECTORY
|
// TODO Save file to path.join(basePath, 'westeroscraft.json')
|
||||||
// TODO Fulfill with JSON.parse()
|
// TODO Fulfill with JSON.parse()
|
||||||
|
|
||||||
// Workaround while file is not hosted.
|
// Workaround while file is not hosted.
|
||||||
@ -303,11 +309,12 @@ class AssetGuard extends EventEmitter {
|
|||||||
/**
|
/**
|
||||||
* Statically retrieve the distribution data.
|
* Statically retrieve the distribution data.
|
||||||
*
|
*
|
||||||
|
* @param {String} basePath - base path for asset validation (game root).
|
||||||
* @param {Boolean} cached - optional. False if the distro should be freshly downloaded, else
|
* @param {Boolean} cached - optional. False if the distro should be freshly downloaded, else
|
||||||
* a cached copy will be returned.
|
* a cached copy will be returned.
|
||||||
* @returns {Object} - The distribution data object.
|
* @returns {Object} - The distribution data object.
|
||||||
*/
|
*/
|
||||||
static retrieveDistributionDataSync(cached = true){
|
static retrieveDistributionDataSync(basePath, cached = true){
|
||||||
if(!cached || distributionData == null){
|
if(!cached || distributionData == null){
|
||||||
distributionData = JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'westeroscraft.json'), 'utf-8'))
|
distributionData = JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'westeroscraft.json'), 'utf-8'))
|
||||||
}
|
}
|
||||||
@ -317,10 +324,11 @@ class AssetGuard extends EventEmitter {
|
|||||||
/**
|
/**
|
||||||
* Resolve the default selected server from the distribution index.
|
* Resolve the default selected server from the distribution index.
|
||||||
*
|
*
|
||||||
|
* @param {String} basePath - base path for asset validation (game root).
|
||||||
* @returns {Object} - An object resolving to the default selected server.
|
* @returns {Object} - An object resolving to the default selected server.
|
||||||
*/
|
*/
|
||||||
static resolveSelectedServer(){
|
static resolveSelectedServer(basePath){
|
||||||
const distro = AssetGuard.retrieveDistributionDataSync()
|
const distro = AssetGuard.retrieveDistributionDataSync(basePath)
|
||||||
const servers = distro.servers
|
const servers = distro.servers
|
||||||
for(let i=0; i<servers.length; i++){
|
for(let i=0; i<servers.length; i++){
|
||||||
if(servers[i].default_selected){
|
if(servers[i].default_selected){
|
||||||
@ -336,12 +344,13 @@ class AssetGuard extends EventEmitter {
|
|||||||
* Returns null if the ID could not be found or the distro index has
|
* Returns null if the ID could not be found or the distro index has
|
||||||
* not yet been loaded.
|
* not yet been loaded.
|
||||||
*
|
*
|
||||||
|
* @param {String} basePath - base path for asset validation (game root).
|
||||||
* @param {String} serverID - The id of the server to retrieve.
|
* @param {String} serverID - The id of the server to retrieve.
|
||||||
* @returns {Object} - The server object whose id matches the parameter.
|
* @returns {Object} - The server object whose id matches the parameter.
|
||||||
*/
|
*/
|
||||||
static getServerById(serverID){
|
static getServerById(basePath, serverID){
|
||||||
if(distributionData == null){
|
if(distributionData == null){
|
||||||
AssetGuard.retrieveDistributionDataSync(false)
|
AssetGuard.retrieveDistributionDataSync(basePath, false)
|
||||||
}
|
}
|
||||||
const servers = distributionData.servers
|
const servers = distributionData.servers
|
||||||
let serv = null
|
let serv = null
|
||||||
@ -424,11 +433,11 @@ class AssetGuard extends EventEmitter {
|
|||||||
* @param {Array.<String>} filePaths - The paths of the files to be extracted and unpacked.
|
* @param {Array.<String>} filePaths - The paths of the files to be extracted and unpacked.
|
||||||
* @returns {Promise.<Void>} - An empty promise to indicate the extraction has completed.
|
* @returns {Promise.<Void>} - An empty promise to indicate the extraction has completed.
|
||||||
*/
|
*/
|
||||||
static _extractPackXZ(filePaths){
|
static _extractPackXZ(filePaths, javaExecutable){
|
||||||
return new Promise(function(fulfill, reject){
|
return new Promise(function(fulfill, reject){
|
||||||
const libPath = path.join(__dirname, '..', 'libraries', 'java', 'PackXZExtract.jar')
|
const libPath = path.join(__dirname, '..', 'libraries', 'java', 'PackXZExtract.jar')
|
||||||
const filePath = filePaths.join(',')
|
const filePath = filePaths.join(',')
|
||||||
const child = child_process.spawn(DEFAULT_CONFIG.getJavaExecutable(), ['-jar', libPath, '-packxz', filePath])
|
const child = child_process.spawn(javaExecutable, ['-jar', libPath, '-packxz', filePath])
|
||||||
child.stdout.on('data', (data) => {
|
child.stdout.on('data', (data) => {
|
||||||
//console.log('PackXZExtract:', data.toString('utf8'))
|
//console.log('PackXZExtract:', data.toString('utf8'))
|
||||||
})
|
})
|
||||||
@ -449,7 +458,7 @@ class AssetGuard extends EventEmitter {
|
|||||||
* in a promise.
|
* in a promise.
|
||||||
*
|
*
|
||||||
* @param {Asset} asset - The Asset object representing Forge.
|
* @param {Asset} asset - The Asset object representing Forge.
|
||||||
* @param {String} basePath
|
* @param {String} basePath - Base path for asset validation (game root).
|
||||||
* @returns {Promise.<Object>} - A promise which resolves to the contents of forge's version.json.
|
* @returns {Promise.<Object>} - A promise which resolves to the contents of forge's version.json.
|
||||||
*/
|
*/
|
||||||
static _finalizeForgeAsset(asset, basePath){
|
static _finalizeForgeAsset(asset, basePath){
|
||||||
@ -557,15 +566,15 @@ class AssetGuard extends EventEmitter {
|
|||||||
* Loads the version data for a given minecraft version.
|
* Loads the version data for a given minecraft version.
|
||||||
*
|
*
|
||||||
* @param {String} version - the game version for which to load the index data.
|
* @param {String} version - the game version for which to load the index data.
|
||||||
* @param {String} basePath - the absolute file path which will be prepended to the given relative paths.
|
|
||||||
* @param {Boolean} force - optional. If true, the version index will be downloaded even if it exists locally. Defaults to false.
|
* @param {Boolean} force - optional. If true, the version index will be downloaded even if it exists locally. Defaults to false.
|
||||||
* @returns {Promise.<Object>} - Promise which resolves to the version data object.
|
* @returns {Promise.<Object>} - Promise which resolves to the version data object.
|
||||||
*/
|
*/
|
||||||
loadVersionData(version, basePath, force = false){
|
loadVersionData(version, force = false){
|
||||||
|
const self = this
|
||||||
return new Promise(function(fulfill, reject){
|
return new Promise(function(fulfill, reject){
|
||||||
const name = version + '.json'
|
const name = version + '.json'
|
||||||
const url = 'https://s3.amazonaws.com/Minecraft.Download/versions/' + version + '/' + name
|
const url = 'https://s3.amazonaws.com/Minecraft.Download/versions/' + version + '/' + name
|
||||||
const versionPath = path.join(basePath, 'versions', version)
|
const versionPath = path.join(self.basePath, 'versions', version)
|
||||||
const versionFile = path.join(versionPath, name)
|
const versionFile = path.join(versionPath, name)
|
||||||
if(!fs.existsSync(versionFile) || force){
|
if(!fs.existsSync(versionFile) || force){
|
||||||
//This download will never be tracked as it's essential and trivial.
|
//This download will never be tracked as it's essential and trivial.
|
||||||
@ -590,14 +599,13 @@ class AssetGuard extends EventEmitter {
|
|||||||
* If not, it will be added to the download queue for the 'assets' identifier.
|
* If not, it will be added to the download queue for the 'assets' identifier.
|
||||||
*
|
*
|
||||||
* @param {Object} versionData - the version data for the assets.
|
* @param {Object} versionData - the version data for the assets.
|
||||||
* @param {String} basePath - the absolute file path which will be prepended to the given relative paths.
|
|
||||||
* @param {Boolean} force - optional. If true, the asset index will be downloaded even if it exists locally. Defaults to false.
|
* @param {Boolean} force - optional. If true, the asset index will be downloaded even if it exists locally. Defaults to false.
|
||||||
* @returns {Promise.<Void>} - An empty promise to indicate the async processing has completed.
|
* @returns {Promise.<Void>} - An empty promise to indicate the async processing has completed.
|
||||||
*/
|
*/
|
||||||
validateAssets(versionData, basePath, force = false){
|
validateAssets(versionData, force = false){
|
||||||
const self = this
|
const self = this
|
||||||
return new Promise(function(fulfill, reject){
|
return new Promise(function(fulfill, reject){
|
||||||
self._assetChainIndexData(versionData, basePath, force).then(() => {
|
self._assetChainIndexData(versionData, force).then(() => {
|
||||||
fulfill()
|
fulfill()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -608,17 +616,16 @@ class AssetGuard extends EventEmitter {
|
|||||||
* Private function used to chain the asset validation process. This function retrieves
|
* Private function used to chain the asset validation process. This function retrieves
|
||||||
* the index data.
|
* the index data.
|
||||||
* @param {Object} versionData
|
* @param {Object} versionData
|
||||||
* @param {String} basePath
|
|
||||||
* @param {Boolean} force
|
* @param {Boolean} force
|
||||||
* @returns {Promise.<Void>} - An empty promise to indicate the async processing has completed.
|
* @returns {Promise.<Void>} - An empty promise to indicate the async processing has completed.
|
||||||
*/
|
*/
|
||||||
_assetChainIndexData(versionData, basePath, force = false){
|
_assetChainIndexData(versionData, force = false){
|
||||||
const self = this
|
const self = this
|
||||||
return new Promise(function(fulfill, reject){
|
return new Promise(function(fulfill, reject){
|
||||||
//Asset index constants.
|
//Asset index constants.
|
||||||
const assetIndex = versionData.assetIndex
|
const assetIndex = versionData.assetIndex
|
||||||
const name = assetIndex.id + '.json'
|
const name = assetIndex.id + '.json'
|
||||||
const indexPath = path.join(basePath, 'assets', 'indexes')
|
const indexPath = path.join(self.basePath, 'assets', 'indexes')
|
||||||
const assetIndexLoc = path.join(indexPath, name)
|
const assetIndexLoc = path.join(indexPath, name)
|
||||||
|
|
||||||
let data = null
|
let data = null
|
||||||
@ -628,13 +635,13 @@ class AssetGuard extends EventEmitter {
|
|||||||
const stream = request(assetIndex.url).pipe(fs.createWriteStream(assetIndexLoc))
|
const stream = request(assetIndex.url).pipe(fs.createWriteStream(assetIndexLoc))
|
||||||
stream.on('finish', function() {
|
stream.on('finish', function() {
|
||||||
data = JSON.parse(fs.readFileSync(assetIndexLoc, 'utf-8'))
|
data = JSON.parse(fs.readFileSync(assetIndexLoc, 'utf-8'))
|
||||||
self._assetChainValidateAssets(versionData, basePath, data).then(() => {
|
self._assetChainValidateAssets(versionData, data).then(() => {
|
||||||
fulfill()
|
fulfill()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
data = JSON.parse(fs.readFileSync(assetIndexLoc, 'utf-8'))
|
data = JSON.parse(fs.readFileSync(assetIndexLoc, 'utf-8'))
|
||||||
self._assetChainValidateAssets(versionData, basePath, data).then(() => {
|
self._assetChainValidateAssets(versionData, data).then(() => {
|
||||||
fulfill()
|
fulfill()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -645,17 +652,16 @@ class AssetGuard extends EventEmitter {
|
|||||||
* Private function used to chain the asset validation process. This function processes
|
* Private function used to chain the asset validation process. This function processes
|
||||||
* the assets and enqueues missing or invalid files.
|
* the assets and enqueues missing or invalid files.
|
||||||
* @param {Object} versionData
|
* @param {Object} versionData
|
||||||
* @param {String} basePath
|
|
||||||
* @param {Boolean} force
|
* @param {Boolean} force
|
||||||
* @returns {Promise.<Void>} - An empty promise to indicate the async processing has completed.
|
* @returns {Promise.<Void>} - An empty promise to indicate the async processing has completed.
|
||||||
*/
|
*/
|
||||||
_assetChainValidateAssets(versionData, basePath, indexData){
|
_assetChainValidateAssets(versionData, indexData){
|
||||||
const self = this
|
const self = this
|
||||||
return new Promise(function(fulfill, reject){
|
return new Promise(function(fulfill, reject){
|
||||||
|
|
||||||
//Asset constants
|
//Asset constants
|
||||||
const resourceURL = 'http://resources.download.minecraft.net/'
|
const resourceURL = 'http://resources.download.minecraft.net/'
|
||||||
const localPath = path.join(basePath, 'assets')
|
const localPath = path.join(self.basePath, 'assets')
|
||||||
const indexPath = path.join(localPath, 'indexes')
|
const indexPath = path.join(localPath, 'indexes')
|
||||||
const objectPath = path.join(localPath, 'objects')
|
const objectPath = path.join(localPath, 'objects')
|
||||||
|
|
||||||
@ -686,15 +692,14 @@ class AssetGuard extends EventEmitter {
|
|||||||
* queue for the 'libraries' identifier.
|
* queue for the 'libraries' identifier.
|
||||||
*
|
*
|
||||||
* @param {Object} versionData - the version data for the assets.
|
* @param {Object} versionData - the version data for the assets.
|
||||||
* @param {String} basePath - the absolute file path which will be prepended to the given relative paths.
|
|
||||||
* @returns {Promise.<Void>} - An empty promise to indicate the async processing has completed.
|
* @returns {Promise.<Void>} - An empty promise to indicate the async processing has completed.
|
||||||
*/
|
*/
|
||||||
validateLibraries(versionData, basePath){
|
validateLibraries(versionData){
|
||||||
const self = this
|
const self = this
|
||||||
return new Promise(function(fulfill, reject){
|
return new Promise(function(fulfill, reject){
|
||||||
|
|
||||||
const libArr = versionData.libraries
|
const libArr = versionData.libraries
|
||||||
const libPath = path.join(basePath, 'libraries')
|
const libPath = path.join(self.basePath, 'libraries')
|
||||||
|
|
||||||
const libDlQueue = []
|
const libDlQueue = []
|
||||||
let dlSize = 0
|
let dlSize = 0
|
||||||
@ -722,14 +727,13 @@ class AssetGuard extends EventEmitter {
|
|||||||
* the 'files' identifier.
|
* the 'files' identifier.
|
||||||
*
|
*
|
||||||
* @param {Object} versionData - the version data for the assets.
|
* @param {Object} versionData - the version data for the assets.
|
||||||
* @param {String} basePath - the absolute file path which will be prepended to the given relative paths.
|
|
||||||
* @returns {Promise.<Void>} - An empty promise to indicate the async processing has completed.
|
* @returns {Promise.<Void>} - An empty promise to indicate the async processing has completed.
|
||||||
*/
|
*/
|
||||||
validateMiscellaneous(versionData, basePath){
|
validateMiscellaneous(versionData){
|
||||||
const self = this
|
const self = this
|
||||||
return new Promise(async function(fulfill, reject){
|
return new Promise(async function(fulfill, reject){
|
||||||
await self.validateClient(versionData, basePath)
|
await self.validateClient(versionData)
|
||||||
await self.validateLogConfig(versionData, basePath)
|
await self.validateLogConfig(versionData)
|
||||||
fulfill()
|
fulfill()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -738,16 +742,15 @@ class AssetGuard extends EventEmitter {
|
|||||||
* Validate client file - artifact renamed from client.jar to '{version}'.jar.
|
* Validate client file - artifact renamed from client.jar to '{version}'.jar.
|
||||||
*
|
*
|
||||||
* @param {Object} versionData - the version data for the assets.
|
* @param {Object} versionData - the version data for the assets.
|
||||||
* @param {String} basePath - the absolute file path which will be prepended to the given relative paths.
|
|
||||||
* @param {Boolean} force - optional. If true, the asset index will be downloaded even if it exists locally. Defaults to false.
|
* @param {Boolean} force - optional. If true, the asset index will be downloaded even if it exists locally. Defaults to false.
|
||||||
* @returns {Promise.<Void>} - An empty promise to indicate the async processing has completed.
|
* @returns {Promise.<Void>} - An empty promise to indicate the async processing has completed.
|
||||||
*/
|
*/
|
||||||
validateClient(versionData, basePath, force = false){
|
validateClient(versionData, force = false){
|
||||||
const self = this
|
const self = this
|
||||||
return new Promise(function(fulfill, reject){
|
return new Promise(function(fulfill, reject){
|
||||||
const clientData = versionData.downloads.client
|
const clientData = versionData.downloads.client
|
||||||
const version = versionData.id
|
const version = versionData.id
|
||||||
const targetPath = path.join(basePath, 'versions', version)
|
const targetPath = path.join(self.basePath, 'versions', version)
|
||||||
const targetFile = version + '.jar'
|
const targetFile = version + '.jar'
|
||||||
|
|
||||||
let client = new Asset(version + ' client', clientData.sha1, clientData.size, clientData.url, path.join(targetPath, targetFile))
|
let client = new Asset(version + ' client', clientData.sha1, clientData.size, clientData.url, path.join(targetPath, targetFile))
|
||||||
@ -766,16 +769,15 @@ class AssetGuard extends EventEmitter {
|
|||||||
* Validate log config.
|
* Validate log config.
|
||||||
*
|
*
|
||||||
* @param {Object} versionData - the version data for the assets.
|
* @param {Object} versionData - the version data for the assets.
|
||||||
* @param {String} basePath - the absolute file path which will be prepended to the given relative paths.
|
|
||||||
* @param {Boolean} force - optional. If true, the asset index will be downloaded even if it exists locally. Defaults to false.
|
* @param {Boolean} force - optional. If true, the asset index will be downloaded even if it exists locally. Defaults to false.
|
||||||
* @returns {Promise.<Void>} - An empty promise to indicate the async processing has completed.
|
* @returns {Promise.<Void>} - An empty promise to indicate the async processing has completed.
|
||||||
*/
|
*/
|
||||||
validateLogConfig(versionData, basePath){
|
validateLogConfig(versionData){
|
||||||
const self = this
|
const self = this
|
||||||
return new Promise(function(fulfill, reject){
|
return new Promise(function(fulfill, reject){
|
||||||
const client = versionData.logging.client
|
const client = versionData.logging.client
|
||||||
const file = client.file
|
const file = client.file
|
||||||
const targetPath = path.join(basePath, 'assets', 'log_configs')
|
const targetPath = path.join(self.basePath, 'assets', 'log_configs')
|
||||||
|
|
||||||
let logConfig = new Asset(file.id, file.sha1, file.size, file.url, path.join(targetPath, file.id))
|
let logConfig = new Asset(file.id, file.sha1, file.size, file.url, path.join(targetPath, file.id))
|
||||||
|
|
||||||
@ -793,13 +795,12 @@ class AssetGuard extends EventEmitter {
|
|||||||
* Validate the distribution.
|
* Validate the distribution.
|
||||||
*
|
*
|
||||||
* @param {String} serverpackid - The id of the server to validate.
|
* @param {String} serverpackid - The id of the server to validate.
|
||||||
* @param {String} basePath - the absolute file path which will be prepended to the given relative paths.
|
|
||||||
* @returns {Promise.<Object>} - A promise which resolves to the server distribution object.
|
* @returns {Promise.<Object>} - A promise which resolves to the server distribution object.
|
||||||
*/
|
*/
|
||||||
validateDistribution(serverpackid, basePath){
|
validateDistribution(serverpackid){
|
||||||
const self = this
|
const self = this
|
||||||
return new Promise(function(fulfill, reject){
|
return new Promise(function(fulfill, reject){
|
||||||
AssetGuard.retrieveDistributionData(false).then((value) => {
|
AssetGuard.retrieveDistributionData(self.basePath, false).then((value) => {
|
||||||
/*const servers = value.servers
|
/*const servers = value.servers
|
||||||
let serv = null
|
let serv = null
|
||||||
for(let i=0; i<servers.length; i++){
|
for(let i=0; i<servers.length; i++){
|
||||||
@ -808,17 +809,17 @@ class AssetGuard extends EventEmitter {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}*/
|
}*/
|
||||||
const serv = AssetGuard.getServerById(serverpackid)
|
const serv = AssetGuard.getServerById(self.basePath, serverpackid)
|
||||||
|
|
||||||
self.forge = self._parseDistroModules(serv.modules, basePath, serv.mc_version)
|
self.forge = self._parseDistroModules(serv.modules, serv.mc_version)
|
||||||
//Correct our workaround here.
|
//Correct our workaround here.
|
||||||
let decompressqueue = self.forge.callback
|
let decompressqueue = self.forge.callback
|
||||||
self.forge.callback = function(asset){
|
self.forge.callback = function(asset){
|
||||||
if(asset.to.toLowerCase().endsWith('.pack.xz')){
|
if(asset.to.toLowerCase().endsWith('.pack.xz')){
|
||||||
AssetGuard._extractPackXZ([asset.to])
|
AssetGuard._extractPackXZ([asset.to], self.javaexec)
|
||||||
}
|
}
|
||||||
if(asset.type === 'forge-hosted' || asset.type === 'forge'){
|
if(asset.type === 'forge-hosted' || asset.type === 'forge'){
|
||||||
AssetGuard._finalizeForgeAsset(asset, basePath)
|
AssetGuard._finalizeForgeAsset(asset, self.basePath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fulfill(serv)
|
fulfill(serv)
|
||||||
@ -839,7 +840,7 @@ class AssetGuard extends EventEmitter {
|
|||||||
})
|
})
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
_parseDistroModules(modules, basePath, version){
|
_parseDistroModules(modules, version){
|
||||||
let alist = []
|
let alist = []
|
||||||
let asize = 0;
|
let asize = 0;
|
||||||
//This may be removed soon, considering the most efficient way to extract.
|
//This may be removed soon, considering the most efficient way to extract.
|
||||||
@ -853,19 +854,19 @@ class AssetGuard extends EventEmitter {
|
|||||||
case 'forge-hosted':
|
case 'forge-hosted':
|
||||||
case 'forge':
|
case 'forge':
|
||||||
case 'library':
|
case 'library':
|
||||||
obPath = path.join(basePath, 'libraries', obPath)
|
obPath = path.join(this.basePath, 'libraries', obPath)
|
||||||
break
|
break
|
||||||
case 'forgemod':
|
case 'forgemod':
|
||||||
//obPath = path.join(basePath, 'mods', obPath)
|
//obPath = path.join(this.basePath, 'mods', obPath)
|
||||||
obPath = path.join(basePath, 'modstore', obPath)
|
obPath = path.join(this.basePath, 'modstore', obPath)
|
||||||
break
|
break
|
||||||
case 'litemod':
|
case 'litemod':
|
||||||
//obPath = path.join(basePath, 'mods', version, obPath)
|
//obPath = path.join(this.basePath, 'mods', version, obPath)
|
||||||
obPath = path.join(basePath, 'modstore', obPath)
|
obPath = path.join(this.basePath, 'modstore', obPath)
|
||||||
break
|
break
|
||||||
case 'file':
|
case 'file':
|
||||||
default:
|
default:
|
||||||
obPath = path.join(basePath, obPath)
|
obPath = path.join(this.basePath, obPath)
|
||||||
}
|
}
|
||||||
let artifact = new DistroModule(ob.id, obArtifact.MD5, obArtifact.size, obArtifact.url, obPath, obType)
|
let artifact = new DistroModule(ob.id, obArtifact.MD5, obArtifact.size, obArtifact.url, obPath, obType)
|
||||||
const validationPath = obPath.toLowerCase().endsWith('.pack.xz') ? obPath.substring(0, obPath.toLowerCase().lastIndexOf('.pack.xz')) : obPath
|
const validationPath = obPath.toLowerCase().endsWith('.pack.xz') ? obPath.substring(0, obPath.toLowerCase().lastIndexOf('.pack.xz')) : obPath
|
||||||
@ -876,7 +877,7 @@ class AssetGuard extends EventEmitter {
|
|||||||
}
|
}
|
||||||
//Recursively process the submodules then combine the results.
|
//Recursively process the submodules then combine the results.
|
||||||
if(ob.sub_modules != null){
|
if(ob.sub_modules != null){
|
||||||
let dltrack = this._parseDistroModules(ob.sub_modules, basePath, version)
|
let dltrack = this._parseDistroModules(ob.sub_modules, version)
|
||||||
asize += dltrack.dlsize*1
|
asize += dltrack.dlsize*1
|
||||||
alist = alist.concat(dltrack.dlqueue)
|
alist = alist.concat(dltrack.dlqueue)
|
||||||
decompressqueue = decompressqueue.concat(dltrack.callback)
|
decompressqueue = decompressqueue.concat(dltrack.callback)
|
||||||
@ -891,13 +892,12 @@ class AssetGuard extends EventEmitter {
|
|||||||
* Loads Forge's version.json data into memory for the specified server id.
|
* Loads Forge's version.json data into memory for the specified server id.
|
||||||
*
|
*
|
||||||
* @param {String} serverpack - The id of the server to load Forge data for.
|
* @param {String} serverpack - The id of the server to load Forge data for.
|
||||||
* @param {String} basePath
|
|
||||||
* @returns {Promise.<Object>} - A promise which resolves to Forge's version.json data.
|
* @returns {Promise.<Object>} - A promise which resolves to Forge's version.json data.
|
||||||
*/
|
*/
|
||||||
loadForgeData(serverpack, basePath){
|
loadForgeData(serverpack){
|
||||||
const self = this
|
const self = this
|
||||||
return new Promise(async function(fulfill, reject){
|
return new Promise(async function(fulfill, reject){
|
||||||
let distro = AssetGuard.retrieveDistributionDataSync()
|
let distro = AssetGuard.retrieveDistributionDataSync(self.basePath)
|
||||||
|
|
||||||
const servers = distro.servers
|
const servers = distro.servers
|
||||||
let serv = null
|
let serv = null
|
||||||
@ -913,9 +913,9 @@ class AssetGuard extends EventEmitter {
|
|||||||
const ob = modules[i]
|
const ob = modules[i]
|
||||||
if(ob.type === 'forge-hosted' || ob.type === 'forge'){
|
if(ob.type === 'forge-hosted' || ob.type === 'forge'){
|
||||||
let obArtifact = ob.artifact
|
let obArtifact = ob.artifact
|
||||||
let obPath = obArtifact.path == null ? path.join(basePath, 'libraries', AssetGuard._resolvePath(ob.id, obArtifact.extension)) : obArtifact.path
|
let obPath = obArtifact.path == null ? path.join(self.basePath, 'libraries', AssetGuard._resolvePath(ob.id, obArtifact.extension)) : obArtifact.path
|
||||||
let asset = new DistroModule(ob.id, obArtifact.MD5, obArtifact.size, obArtifact.url, obPath, ob.type)
|
let asset = new DistroModule(ob.id, obArtifact.MD5, obArtifact.size, obArtifact.url, obPath, ob.type)
|
||||||
let forgeData = await AssetGuard._finalizeForgeAsset(asset, basePath)
|
let forgeData = await AssetGuard._finalizeForgeAsset(asset, self.basePath)
|
||||||
fulfill(forgeData)
|
fulfill(forgeData)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -1,13 +0,0 @@
|
|||||||
const path = require('path')
|
|
||||||
const ConfigManager = require('./configmanager')
|
|
||||||
|
|
||||||
//TODO: Resolve game directory based on windows, linux, or mac..
|
|
||||||
const GAME_DIRECTORY = path.join(__dirname, '..', '..', '..', 'target', 'test', 'mcfiles')
|
|
||||||
const DISTRO_DIRECTORY = path.join(GAME_DIRECTORY, 'westeroscraft.json')
|
|
||||||
const DEFAULT_CONFIG = new ConfigManager(path.join(GAME_DIRECTORY, 'config.json'))
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
GAME_DIRECTORY,
|
|
||||||
DISTRO_DIRECTORY,
|
|
||||||
DEFAULT_CONFIG
|
|
||||||
}
|
|
@ -1,6 +1,6 @@
|
|||||||
// Work in progress
|
// Work in progress
|
||||||
const Client = require('discord-rpc')
|
const Client = require('discord-rpc')
|
||||||
const {DEFAULT_CONFIG} = require('./constants')
|
const {DEFAULT_CONFIG} = require('./enumerator.js').enum
|
||||||
|
|
||||||
let rpc
|
let rpc
|
||||||
|
|
||||||
|
9
app/assets/js/enumerator.js
Normal file
9
app/assets/js/enumerator.js
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
/**
|
||||||
|
* Module which stores constant values. These constants are mutable, however
|
||||||
|
* generally should not be changed unless a value is being added. Values are
|
||||||
|
* typically initialized during the app's preloader.
|
||||||
|
* @module enumerator
|
||||||
|
*/
|
||||||
|
exports.enum = {
|
||||||
|
|
||||||
|
}
|
@ -1,17 +0,0 @@
|
|||||||
function _shouldInclude(mdle){
|
|
||||||
return mdle.required == null || mdle.required.value == null || mdle.required.value === true || (mdle.required.value === false && mdle.required.def === true)
|
|
||||||
}
|
|
||||||
|
|
||||||
function resolveForgeFromDistro(moduleArr){
|
|
||||||
const mods = []
|
|
||||||
|
|
||||||
for(let i=0; i<moduleArr.length; ++i){
|
|
||||||
if(moduleArr[i].type != null && moduleArr[i].type === 'forgemod'){
|
|
||||||
if(_shouldInclude(moduleArr[i])){
|
|
||||||
mods.push(moduleArr[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return mods
|
|
||||||
}
|
|
@ -1,6 +1,22 @@
|
|||||||
|
// Note: The following modules CANNOT require enumerator.js
|
||||||
const {AssetGuard} = require('./assetguard.js')
|
const {AssetGuard} = require('./assetguard.js')
|
||||||
|
const ConfigManager = require('./configmanager.js')
|
||||||
|
const constants = require('./enumerator.js').enum
|
||||||
|
const path = require('path')
|
||||||
|
|
||||||
console.log('Preloading')
|
console.log('Preloading')
|
||||||
|
|
||||||
// Ensure Distribution is downloaded and cached.
|
// Ensure Distribution is downloaded and cached.
|
||||||
AssetGuard.retrieveDistributionDataSync(false)
|
AssetGuard.retrieveDistributionDataSync(false)
|
||||||
|
|
||||||
|
// TODO: Resolve game directory based on windows, linux, or mac..
|
||||||
|
constants.GAME_DIRECTORY = path.join(__dirname, '..', '..', '..', 'target', 'test', 'mcfiles')
|
||||||
|
constants.DISTRO_DIRECTORY = path.join(constants.GAME_DIRECTORY, 'westeroscraft.json')
|
||||||
|
|
||||||
|
// Complete config setup
|
||||||
|
const conf = new ConfigManager(path.join(constants.GAME_DIRECTORY, 'config.json'))
|
||||||
|
if(conf.getSelectedServer() == null){
|
||||||
|
console.log('Determining default selected server..')
|
||||||
|
conf.setSelectedServer(AssetGuard.resolveSelectedServer(constants.GAME_DIRECTORY))
|
||||||
|
}
|
||||||
|
constants.DEFAULT_CONFIG = conf
|
@ -8,7 +8,7 @@
|
|||||||
const AdmZip = require('adm-zip')
|
const AdmZip = require('adm-zip')
|
||||||
const {AssetGuard, Library} = require('./assetguard.js')
|
const {AssetGuard, Library} = require('./assetguard.js')
|
||||||
const child_process = require('child_process')
|
const child_process = require('child_process')
|
||||||
const {DEFAULT_CONFIG} = require('./constants')
|
const {DEFAULT_CONFIG} = require('./enumerator.js').enum
|
||||||
const fs = require('fs')
|
const fs = require('fs')
|
||||||
const mkpath = require('mkdirp')
|
const mkpath = require('mkdirp')
|
||||||
const path = require('path')
|
const path = require('path')
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
/**
|
/**
|
||||||
* Core UI functions are initialized in this file. This prevents
|
* Core UI functions are initialized in this file. This prevents
|
||||||
* unexpected errors from breaking the core features.
|
* unexpected errors from breaking the core features. Specifically,
|
||||||
|
* actions in this file should not require the usage of any internal
|
||||||
|
* modules, excluding dependencies.
|
||||||
*/
|
*/
|
||||||
const $ = require('jquery');
|
const $ = require('jquery');
|
||||||
const {remote, shell} = require('electron')
|
const {remote, shell} = require('electron')
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
"servers": [
|
"servers": [
|
||||||
{
|
{
|
||||||
"id": "WesterosCraft-1.11.2",
|
"id": "WesterosCraft-1.11.2",
|
||||||
"name": "WesterosCraft Production Client",
|
"name": "WesterosCraft Production Server",
|
||||||
"news_feed": "http://www.westeroscraft.com/api/rss.php?preset_id=12700544",
|
"news_feed": "http://www.westeroscraft.com/api/rss.php?preset_id=12700544",
|
||||||
"icon_url": "http://mc.westeroscraft.com/WesterosCraftLauncher/files/server-prod.png",
|
"icon_url": "http://mc.westeroscraft.com/WesterosCraftLauncher/files/server-prod.png",
|
||||||
"revision": "0.0.1",
|
"revision": "0.0.1",
|
||||||
|
Loading…
Reference in New Issue
Block a user