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 Registry = require('winreg')
const request = require('request')
const targz = require('targz')
// Constants
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
* command line option -XshowSettings:properties. The output of this contains a property,
@ -717,15 +735,15 @@ class AssetGuard extends EventEmitter {
* Higher versions > Lower versions
* If versions are equal, JRE > JDK.
*
* @returns {string} The root path of a valid x64 Java installation. If none are
* found, null is returned.
* @returns {Promise.<string>} A Promise which resolves to the root path of a valid
* x64 Java installation. If none are found, null is returned.
*/
static async _win32JavaValidate(){
// Get possible paths from the registry.
const pathSet = await AssetGuard._scanRegistry()
console.log(Array.from(pathSet)) // DEBUGGING
//console.log(Array.from(pathSet)) // DEBUGGING
// Validate JAVA_HOME
const jHome = AssetGuard._scanJavaHome()
@ -736,7 +754,7 @@ class AssetGuard extends EventEmitter {
// Convert path set to an array for processing.
let pathArr = Array.from(pathSet)
console.log(pathArr) // DEBUGGING
//console.log(pathArr) // DEBUGGING
// Sorts array. Higher version numbers preceed lower. JRE preceeds JDK.
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.
for(let i=0; i<pathArr.length; i++) {
@ -780,6 +798,11 @@ class AssetGuard extends EventEmitter {
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(){
return await AssetGuard['_' + process.platform + 'JavaValidate']()
}
@ -800,31 +823,25 @@ class AssetGuard extends EventEmitter {
*/
loadVersionData(version, force = false){
const self = this
return new Promise(function(fulfill, reject){
return new Promise((resolve, reject) => {
const name = version + '.json'
const url = 'https://s3.amazonaws.com/Minecraft.Download/versions/' + version + '/' + name
const versionPath = path.join(self.basePath, 'versions', version)
const versionFile = path.join(versionPath, name)
if(!fs.existsSync(versionFile) || force){
//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.')
mkpath.sync(versionPath)
const stream = request(url).pipe(fs.createWriteStream(versionFile))
stream.on('finish', function(){
fulfill(JSON.parse(fs.readFileSync(versionFile)))
})
console.log('Preparing download of ' + version + ' assets.')
mkpath.sync(versionPath)
const stream = request(url).pipe(fs.createWriteStream(versionFile))
stream.on('finish', () => {
resolve(JSON.parse(fs.readFileSync(versionFile)))
})
} 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
// #region
@ -1193,29 +1210,91 @@ class AssetGuard extends EventEmitter {
// Java (Category=''') Validation (download) Functions
// #region
async _enqueueOracleJRE(dir){
const verData = await AssetGuard._latestJREOracle()
_enqueueOracleJRE(dir){
return new Promise((resolve, reject) => {
AssetGuard._latestJREOracle().then(verData => {
if(verData != null){
const combined = verData.uri + PLATFORM_MAP[process.platform]
const name = combined.substring(combined.lastIndexOf('/')+1)
const fDir = path.join(dir, name)
const combined = verData.uri + PLATFORM_MAP[process.platform]
const opts = {
url: combined,
headers: {
'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)
}
})
const opts = {
url: combined,
headers: {
'Cookie': 'oraclelicense=accept-securebackup-cookie'
}
}
} 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

155
package-lock.json generated
View File

@ -241,6 +241,44 @@
"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": {
"version": "3.5.1",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz",
@ -430,6 +468,11 @@
"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": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz",
@ -600,8 +643,7 @@
"core-util-is": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
"dev": true
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
},
"create-error-class": {
"version": "3.0.2",
@ -1174,6 +1216,14 @@
"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": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/env-paths/-/env-paths-1.0.0.tgz",
@ -1523,8 +1573,7 @@
"inherits": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
"dev": true
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
},
"ini": {
"version": "1.3.5",
@ -2006,7 +2055,6 @@
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"dev": true,
"requires": {
"wrappy": "1.0.2"
}
@ -2196,8 +2244,7 @@
"process-nextick-args": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
"integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==",
"dev": true
"integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw=="
},
"progress-stream": {
"version": "1.2.0",
@ -2215,6 +2262,15 @@
"integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
"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": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
@ -2661,6 +2717,85 @@
"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": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/temp-file/-/temp-file-3.1.1.tgz",
@ -2823,8 +2958,7 @@
"util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
"dev": true
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
},
"uuid": {
"version": "3.2.1",
@ -2918,8 +3052,7 @@
"wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
"dev": true
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
},
"write-file-atomic": {
"version": "2.3.0",

View File

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