Rough completion of JRE downloads from oracle.

Mojang fallback cannot be implemented due to limitations of decompressing large lzma files in node.js. This can probably be worked around by packaging with some command line binary, but it honestly it not worth it.
This commit is contained in:
Daniel Scalzi 2018-03-31 20:45:24 -04:00
parent ae387757bc
commit 7fb33c6813
No known key found for this signature in database
GPG Key ID: 5CA2F145B63535F9
3 changed files with 260 additions and 47 deletions

View File

@ -32,6 +32,7 @@ const mkpath = require('mkdirp');
const path = require('path') const path = require('path')
const Registry = require('winreg') const Registry = require('winreg')
const request = require('request') const request = require('request')
const targz = require('targz')
// Constants // Constants
const PLATFORM_MAP = { const PLATFORM_MAP = {
@ -557,6 +558,23 @@ class AssetGuard extends EventEmitter {
}) })
} }
/**
* Load Mojang's launcher.json file.
*
* @returns {Promise.<Object>} Promise which resolves to Mojang's launcher.json object.
*/
static loadMojangLauncherData(){
return new Promise((resolve, reject) => {
request.get('https://launchermeta.mojang.com/mc/launcher.json', (err, resp, body) => {
if(err){
resolve(null)
} else {
resolve(JSON.parse(body))
}
})
})
}
/** /**
* Validates that a Java binary is at least 64 bit. This makes use of the non-standard * Validates that a Java binary is at least 64 bit. This makes use of the non-standard
* command line option -XshowSettings:properties. The output of this contains a property, * command line option -XshowSettings:properties. The output of this contains a property,
@ -717,15 +735,15 @@ class AssetGuard extends EventEmitter {
* Higher versions > Lower versions * Higher versions > Lower versions
* If versions are equal, JRE > JDK. * If versions are equal, JRE > JDK.
* *
* @returns {string} The root path of a valid x64 Java installation. If none are * @returns {Promise.<string>} A Promise which resolves to the root path of a valid
* found, null is returned. * x64 Java installation. If none are found, null is returned.
*/ */
static async _win32JavaValidate(){ static async _win32JavaValidate(){
// Get possible paths from the registry. // Get possible paths from the registry.
const pathSet = await AssetGuard._scanRegistry() const pathSet = await AssetGuard._scanRegistry()
console.log(Array.from(pathSet)) // DEBUGGING //console.log(Array.from(pathSet)) // DEBUGGING
// Validate JAVA_HOME // Validate JAVA_HOME
const jHome = AssetGuard._scanJavaHome() const jHome = AssetGuard._scanJavaHome()
@ -736,7 +754,7 @@ class AssetGuard extends EventEmitter {
// Convert path set to an array for processing. // Convert path set to an array for processing.
let pathArr = Array.from(pathSet) let pathArr = Array.from(pathSet)
console.log(pathArr) // DEBUGGING //console.log(pathArr) // DEBUGGING
// Sorts array. Higher version numbers preceed lower. JRE preceeds JDK. // Sorts array. Higher version numbers preceed lower. JRE preceeds JDK.
pathArr = pathArr.sort((a, b) => { pathArr = pathArr.sort((a, b) => {
@ -751,7 +769,7 @@ class AssetGuard extends EventEmitter {
} }
}) })
console.log(pathArr) // DEBUGGING //console.log(pathArr) // DEBUGGING
// Validate that the binary is actually x64. // Validate that the binary is actually x64.
for(let i=0; i<pathArr.length; i++) { for(let i=0; i<pathArr.length; i++) {
@ -780,6 +798,11 @@ class AssetGuard extends EventEmitter {
return null return null
} }
/**
* Retrieve the path of a valid x64 Java installation.
*
* @returns {string} A path to a valid x64 Java installation, null if none found.
*/
static async validateJava(){ static async validateJava(){
return await AssetGuard['_' + process.platform + 'JavaValidate']() return await AssetGuard['_' + process.platform + 'JavaValidate']()
} }
@ -800,31 +823,25 @@ class AssetGuard extends EventEmitter {
*/ */
loadVersionData(version, force = false){ loadVersionData(version, force = false){
const self = this const self = this
return new Promise(function(fulfill, reject){ return new Promise((resolve, 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(self.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.
request.head(url, function(err, res, body){ console.log('Preparing download of ' + version + ' assets.')
console.log('Preparing download of ' + version + ' assets.') mkpath.sync(versionPath)
mkpath.sync(versionPath) const stream = request(url).pipe(fs.createWriteStream(versionFile))
const stream = request(url).pipe(fs.createWriteStream(versionFile)) stream.on('finish', () => {
stream.on('finish', function(){ resolve(JSON.parse(fs.readFileSync(versionFile)))
fulfill(JSON.parse(fs.readFileSync(versionFile)))
})
}) })
} else { } else {
fulfill(JSON.parse(fs.readFileSync(versionFile))) resolve(JSON.parse(fs.readFileSync(versionFile)))
} }
}) })
} }
loadMojangLauncherData(){
//https://launchermeta.mojang.com/mc/launcher.json
}
// Asset (Category=''') Validation Functions // Asset (Category=''') Validation Functions
// #region // #region
@ -1193,29 +1210,91 @@ class AssetGuard extends EventEmitter {
// Java (Category=''') Validation (download) Functions // Java (Category=''') Validation (download) Functions
// #region // #region
async _enqueueOracleJRE(dir){ _enqueueOracleJRE(dir){
const verData = await AssetGuard._latestJREOracle() return new Promise((resolve, reject) => {
AssetGuard._latestJREOracle().then(verData => {
if(verData != null){
const combined = verData.uri + PLATFORM_MAP[process.platform] const combined = verData.uri + PLATFORM_MAP[process.platform]
const name = combined.substring(combined.lastIndexOf('/')+1)
const fDir = path.join(dir, name)
const opts = { const opts = {
url: combined, url: combined,
headers: { headers: {
'Cookie': 'oraclelicense=accept-securebackup-cookie' 'Cookie': 'oraclelicense=accept-securebackup-cookie'
} }
} }
request.head(opts, (err, resp, body) => {
if(err){
resolve(false)
} else {
const name = combined.substring(combined.lastIndexOf('/')+1)
const fDir = path.join(dir, name)
const jre = new Asset(name, null, resp.headers['content-length'], opts, fDir)
this.java = new DLTracker([jre], jre.size, a => {
targz.decompress({
src: a.to,
dest: dir
}, err => {
if(err){
console.log(err)
} else {
fs.unlink(a.to, err => {
if(err){
console.log(err)
}
})
}
})
})
resolve(true)
}
})
} else {
resolve(false)
}
})
})
if(verData != null){
const jre = new Asset(name, null, 0, opts, fDir)
this.java = new DLTracker([jre], jre.size)
return true
} else {
return false
}
} }
/*_enqueueMojangJRE(dir){
return new Promise((resolve, reject) => {
// Mojang does not host the JRE for linux.
if(process.platform === 'linux'){
resolve(false)
}
AssetGuard.loadMojangLauncherData().then(data => {
if(data != null) {
try {
const mJRE = data[Library.mojangFriendlyOS()]['64'].jre
const url = mJRE.url
request.head(url, (err, resp, body) => {
if(err){
resolve(false)
} else {
const name = url.substring(url.lastIndexOf('/')+1)
const fDir = path.join(dir, name)
const jre = new Asset('jre' + mJRE.version, mJRE.sha1, resp.headers['content-length'], url, fDir)
this.java = new DLTracker([jre], jre.size, a => {
fs.readFile(a.to, (err, data) => {
// Data buffer needs to be decompressed from lzma,
// not really possible using node.js
})
})
}
})
} catch (err){
resolve(false)
}
}
})
})
}*/
// #endregion // #endregion

155
package-lock.json generated
View File

@ -241,6 +241,44 @@
"tweetnacl": "0.14.5" "tweetnacl": "0.14.5"
} }
}, },
"bl": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz",
"integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==",
"requires": {
"readable-stream": "2.3.5",
"safe-buffer": "5.1.1"
},
"dependencies": {
"isarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
},
"readable-stream": {
"version": "2.3.5",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.5.tgz",
"integrity": "sha512-tK0yDhrkygt/knjowCUiWP9YdV7c5R+8cR0r/kt9ZhBU906Fs6RpQJCEilamRJj1Nx2rWI6LkW9gKqjTkshhEw==",
"requires": {
"core-util-is": "1.0.2",
"inherits": "2.0.3",
"isarray": "1.0.0",
"process-nextick-args": "2.0.0",
"safe-buffer": "5.1.1",
"string_decoder": "1.0.3",
"util-deprecate": "1.0.2"
}
},
"string_decoder": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
"integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
"requires": {
"safe-buffer": "5.1.1"
}
}
}
},
"bluebird": { "bluebird": {
"version": "3.5.1", "version": "3.5.1",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz",
@ -430,6 +468,11 @@
"supports-color": "5.3.0" "supports-color": "5.3.0"
} }
}, },
"chownr": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/chownr/-/chownr-1.0.1.tgz",
"integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE="
},
"chromium-pickle-js": { "chromium-pickle-js": {
"version": "0.2.0", "version": "0.2.0",
"resolved": "https://registry.npmjs.org/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz", "resolved": "https://registry.npmjs.org/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz",
@ -600,8 +643,7 @@
"core-util-is": { "core-util-is": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
"dev": true
}, },
"create-error-class": { "create-error-class": {
"version": "3.0.2", "version": "3.0.2",
@ -1174,6 +1216,14 @@
"mime": "2.2.0" "mime": "2.2.0"
} }
}, },
"end-of-stream": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz",
"integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==",
"requires": {
"once": "1.4.0"
}
},
"env-paths": { "env-paths": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/env-paths/-/env-paths-1.0.0.tgz", "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-1.0.0.tgz",
@ -1523,8 +1573,7 @@
"inherits": { "inherits": {
"version": "2.0.3", "version": "2.0.3",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
"dev": true
}, },
"ini": { "ini": {
"version": "1.3.5", "version": "1.3.5",
@ -2006,7 +2055,6 @@
"version": "1.4.0", "version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"dev": true,
"requires": { "requires": {
"wrappy": "1.0.2" "wrappy": "1.0.2"
} }
@ -2196,8 +2244,7 @@
"process-nextick-args": { "process-nextick-args": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
"integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw=="
"dev": true
}, },
"progress-stream": { "progress-stream": {
"version": "1.2.0", "version": "1.2.0",
@ -2215,6 +2262,15 @@
"integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
"dev": true "dev": true
}, },
"pump": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/pump/-/pump-1.0.3.tgz",
"integrity": "sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw==",
"requires": {
"end-of-stream": "1.4.1",
"once": "1.4.0"
}
},
"punycode": { "punycode": {
"version": "1.4.1", "version": "1.4.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
@ -2661,6 +2717,85 @@
"has-flag": "3.0.0" "has-flag": "3.0.0"
} }
}, },
"tar-fs": {
"version": "1.16.0",
"resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-1.16.0.tgz",
"integrity": "sha512-I9rb6v7mjWLtOfCau9eH5L7sLJyU2BnxtEZRQ5Mt+eRKmf1F0ohXmT/Jc3fr52kDvjJ/HV5MH3soQfPL5bQ0Yg==",
"requires": {
"chownr": "1.0.1",
"mkdirp": "0.5.1",
"pump": "1.0.3",
"tar-stream": "1.5.5"
},
"dependencies": {
"minimist": {
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
},
"mkdirp": {
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
"requires": {
"minimist": "0.0.8"
}
}
}
},
"tar-stream": {
"version": "1.5.5",
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.5.5.tgz",
"integrity": "sha512-mQdgLPc/Vjfr3VWqWbfxW8yQNiJCbAZ+Gf6GDu1Cy0bdb33ofyiNGBtAY96jHFhDuivCwgW1H9DgTON+INiXgg==",
"requires": {
"bl": "1.2.2",
"end-of-stream": "1.4.1",
"readable-stream": "2.3.5",
"xtend": "4.0.1"
},
"dependencies": {
"isarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
},
"readable-stream": {
"version": "2.3.5",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.5.tgz",
"integrity": "sha512-tK0yDhrkygt/knjowCUiWP9YdV7c5R+8cR0r/kt9ZhBU906Fs6RpQJCEilamRJj1Nx2rWI6LkW9gKqjTkshhEw==",
"requires": {
"core-util-is": "1.0.2",
"inherits": "2.0.3",
"isarray": "1.0.0",
"process-nextick-args": "2.0.0",
"safe-buffer": "5.1.1",
"string_decoder": "1.0.3",
"util-deprecate": "1.0.2"
}
},
"string_decoder": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
"integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
"requires": {
"safe-buffer": "5.1.1"
}
},
"xtend": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
"integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68="
}
}
},
"targz": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/targz/-/targz-1.0.1.tgz",
"integrity": "sha1-j3alI2lM3t+7XWCkB2/27uzFOY8=",
"requires": {
"tar-fs": "1.16.0"
}
},
"temp-file": { "temp-file": {
"version": "3.1.1", "version": "3.1.1",
"resolved": "https://registry.npmjs.org/temp-file/-/temp-file-3.1.1.tgz", "resolved": "https://registry.npmjs.org/temp-file/-/temp-file-3.1.1.tgz",
@ -2823,8 +2958,7 @@
"util-deprecate": { "util-deprecate": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
"dev": true
}, },
"uuid": { "uuid": {
"version": "3.2.1", "version": "3.2.1",
@ -2918,8 +3052,7 @@
"wrappy": { "wrappy": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
"dev": true
}, },
"write-file-atomic": { "write-file-atomic": {
"version": "2.3.0", "version": "2.3.0",

View File

@ -33,6 +33,7 @@
"ejs-electron": "^2.0.1", "ejs-electron": "^2.0.1",
"jquery": "^3.3.1", "jquery": "^3.3.1",
"request-promise-native": "^1.0.5", "request-promise-native": "^1.0.5",
"targz": "^1.0.1",
"uuid": "^3.2.1", "uuid": "^3.2.1",
"winreg": "^1.2.4" "winreg": "^1.2.4"
}, },