Changes to prevent cyclic dependencies.

This commit is contained in:
Daniel Scalzi 2017-12-02 22:41:47 -05:00
parent 086bfc8593
commit 0dde4bce42
10 changed files with 103 additions and 110 deletions

View File

@ -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'){
@ -12,15 +12,10 @@ document.addEventListener('readystatechange', function(){
console.log('Launching game..') console.log('Launching game..')
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

View File

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

View File

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

View File

@ -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

View 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 = {
}

View File

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

View File

@ -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

View File

@ -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')

View File

@ -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')

View File

@ -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",