Using object for JavaGuard. May move java downloading processes to AssetGuard as a non-default category. Very much a WIP.

This commit is contained in:
Daniel Scalzi 2018-03-29 19:45:05 -04:00
parent 2062865e7f
commit aacf15efc5
No known key found for this signature in database
GPG Key ID: 5CA2F145B63535F9
2 changed files with 292 additions and 248 deletions

View File

@ -1,69 +1,19 @@
const cp = require('child_process') const cp = require('child_process')
const EventEmitter = require('events')
const fs = require('fs') const fs = require('fs')
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 PLATFORM_MAP = {
* Attempts to find a valid x64 installation of Java on Windows machines. win32: '-windows-x64.tar.gz',
* Possible paths will be pulled from the registry and the JAVA_HOME environment darwin: '-macosx-x64.tar.gz',
* variable. The paths will be sorted with higher versions preceeding lower, and linux: '-linux-x64.tar.gz'
* JREs preceeding JDKs. The binaries at the sorted paths will then be validated.
* The first validated is returned.
*
* 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.
*/
async function _win32Validate(){
// Get possible paths from the registry.
const pathSet = await _scanRegistry()
console.log(Array.from(pathSet)) // DEBUGGING
// Validate JAVA_HOME
const jHome = _scanJavaHome()
if(jHome != null && jHome.indexOf('(x86)') === -1){
pathSet.add(jHome)
}
// Convert path set to an array for processing.
let pathArr = Array.from(pathSet)
console.log(pathArr) // DEBUGGING
// Sorts array. Higher version numbers preceed lower. JRE preceeds JDK.
pathArr = pathArr.sort((a, b) => {
// Note that Java 9+ uses semver and that will need to be accounted for in
// the future.
const aVer = parseInt(a.split('_')[1])
const bVer = parseInt(b.split('_')[1])
if(bVer === aVer){
return a.indexOf('jdk') > -1 ? 1 : 0
} else {
return bVer - aVer
}
})
console.log(pathArr) // DEBUGGING
// Validate that the binary is actually x64.
for(let i=0; i<pathArr.length; i++) {
let res = await _validateBinary(pathArr[i])
if(res){
return pathArr[i]
}
}
// No suitable candidates found.
return null;
} }
/** class JavaGuard extends EventEmitter {
/**
* 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,
* sun.arch.data.model = ARCH, in which ARCH is either 32 or 64. This option is supported * sun.arch.data.model = ARCH, in which ARCH is either 32 or 64. This option is supported
@ -76,7 +26,7 @@ async function _win32Validate(){
* @returns {Promise.<boolean>} Resolves to false only if the test is successful and the result * @returns {Promise.<boolean>} Resolves to false only if the test is successful and the result
* is less than 64. * is less than 64.
*/ */
function _validateBinary(binaryPath){ static _validateBinary(binaryPath){
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const fBp = path.join(binaryPath, 'bin', 'java.exe') const fBp = path.join(binaryPath, 'bin', 'java.exe')
@ -111,15 +61,15 @@ function _validateBinary(binaryPath){
} }
}) })
} }
/** /**
* Checks for the presence of the environment variable JAVA_HOME. If it exits, we will check * Checks for the presence of the environment variable JAVA_HOME. If it exits, we will check
* to see if the value points to a path which exists. If the path exits, the path is returned. * to see if the value points to a path which exists. If the path exits, the path is returned.
* *
* @returns {string} The path defined by JAVA_HOME, if it exists. Otherwise null. * @returns {string} The path defined by JAVA_HOME, if it exists. Otherwise null.
*/ */
function _scanJavaHome(){ static _scanJavaHome(){
const jHome = process.env.JAVA_HOME const jHome = process.env.JAVA_HOME
try { try {
let res = fs.existsSync(jHome) let res = fs.existsSync(jHome)
@ -128,16 +78,16 @@ function _scanJavaHome(){
// Malformed JAVA_HOME property. // Malformed JAVA_HOME property.
return null return null
} }
} }
/** /**
* Scans the registry for 64-bit Java entries. The paths of each entry are added to * Scans the registry for 64-bit Java entries. The paths of each entry are added to
* a set and returned. Currently, only Java 8 (1.8) is supported. * a set and returned. Currently, only Java 8 (1.8) is supported.
* *
* @returns {Promise.<Set.<string>>} A promise which resolves to a set of 64-bit Java root * @returns {Promise.<Set.<string>>} A promise which resolves to a set of 64-bit Java root
* paths found in the registry. * paths found in the registry.
*/ */
function _scanRegistry(){ static _scanRegistry(){
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
// Keys for Java v9.0.0 and later: // Keys for Java v9.0.0 and later:
@ -162,17 +112,19 @@ function _scanRegistry(){
key: regKeys[i], key: regKeys[i],
arch: 'x64' arch: 'x64'
}) })
key.keyExists((err, exists) => {
if(exists) {
key.keys((err, javaVers) => { key.keys((err, javaVers) => {
if(err){ if(err){
console.error(err) console.error(err)
if(i === regKeys.length-1){ if(i === regKeys.length-1 && cbAcc === cbTracker){
resolve(candidates) resolve(candidates)
} }
} else { } else {
cbTracker += javaVers.length cbTracker += javaVers.length
if(i === regKeys.length-1 && cbTracker === cbAcc){ if(i === regKeys.length-1 && cbTracker === cbAcc){
resolve(candidates) resolve(candidates)
} } else {
for(let j=0; j<javaVers.length; j++){ for(let j=0; j<javaVers.length; j++){
const javaVer = javaVers[j] const javaVer = javaVers[j]
const vKey = javaVer.key.substring(javaVer.key.lastIndexOf('\\')+1) const vKey = javaVer.key.substring(javaVer.key.lastIndexOf('\\')+1)
@ -182,70 +134,150 @@ function _scanRegistry(){
const jHome = res.value const jHome = res.value
if(jHome.indexOf('(x86)') === -1){ if(jHome.indexOf('(x86)') === -1){
candidates.add(jHome) candidates.add(jHome)
cbAcc++
} }
if(cbAcc === cbTracker){ cbAcc++
if(i === regKeys.length-1 && cbAcc === cbTracker){
resolve(candidates) resolve(candidates)
} }
}) })
} else {
cbAcc++
if(i === regKeys.length-1 && cbAcc === cbTracker){
resolve(candidates)
} }
} }
} }
}
}
})
} else {
if(i === regKeys.length-1 && cbAcc === cbTracker){
resolve(candidates)
}
}
}) })
} }
}) })
} }
/** /**
* Attempts to find a valid x64 installation of Java on Windows machines.
* Possible paths will be pulled from the registry and the JAVA_HOME environment
* variable. The paths will be sorted with higher versions preceeding lower, and
* JREs preceeding JDKs. The binaries at the sorted paths will then be validated.
* The first validated is returned.
*
* 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.
*/
static async _win32Validate(){
// Get possible paths from the registry.
const pathSet = await JavaGuard._scanRegistry()
console.log(Array.from(pathSet)) // DEBUGGING
// Validate JAVA_HOME
const jHome = JavaGuard._scanJavaHome()
if(jHome != null && jHome.indexOf('(x86)') === -1){
pathSet.add(jHome)
}
// Convert path set to an array for processing.
let pathArr = Array.from(pathSet)
console.log(pathArr) // DEBUGGING
// Sorts array. Higher version numbers preceed lower. JRE preceeds JDK.
pathArr = pathArr.sort((a, b) => {
// Note that Java 9+ uses semver and that will need to be accounted for in
// the future.
const aVer = parseInt(a.split('_')[1])
const bVer = parseInt(b.split('_')[1])
if(bVer === aVer){
return a.indexOf('jdk') > -1 ? 1 : 0
} else {
return bVer - aVer
}
})
console.log(pathArr) // DEBUGGING
// Validate that the binary is actually x64.
for(let i=0; i<pathArr.length; i++) {
let res = await JavaGuard._validateBinary(pathArr[i])
if(res){
return pathArr[i]
}
}
// No suitable candidates found.
return null;
}
/**
* WIP -> get a valid x64 Java path on macOS. * WIP -> get a valid x64 Java path on macOS.
*/ */
function _darwinValidate(){ static async _darwinValidate(){
return null return null
}
/**
* WIP -> get a valid x64 Java path on linux.
*/
function _linuxValidate(){
return null
}
// This will eventually return something.
async function validate(){
let res = null
const opSys = process.platform
if(opSys === 'win32'){
res = await _win32Validate()
} else if(opSys === 'darwin'){
res = _darwinValidate()
} else if(opSys === 'linux'){
res = _linuxValidate()
} }
return res; /**
* WIP -> get a valid x64 Java path on linux.
*/
static async _linuxValidate(){
return null
}
} static async validate(){
return await JavaGuard['_' + process.platform + 'Validate']()
}
const PLATFORM_MAP = { // WIP -> Downloading Suite
win32: '-windows-x64.tar.gz',
darwin: '-macosx-x64.tar.gz',
linux: '-linux-x64.tar.gz'
}
const BASE_URL = 'http://download.oracle.com/otn-pub/java/jdk/8u161-b12/2f38c3b165be4555a1fa6e98c45e0808/jre-8u161' static _latestJREOracle(){
const url = 'http://www.oracle.com/technetwork/java/javase/downloads/jre8-downloads-2133155.html'
const regex = /http:\/\/.+?(?=\/java)\/java\/jdk\/([0-9]+u[0-9]+)-(b[0-9]+)\/([a-f0-9]{32})?\/jre-\1/
return new Promise((resolve, reject) => {
request(url, (err, resp, body) => {
if(!err){
const arr = body.match(regex)
const verSplit = arr[1].split('u')
resolve({
uri: arr[0],
version: {
major: verSplit[0],
update: verSplit[1],
build: arr[2]
}
})
} else {
resolve(null)
}
})
})
}
async _downloadOracleJRE(acceptLicense, dir){
function _downloadJava(acceptLicense, dir){
if(!acceptLicense){ if(!acceptLicense){
return return
} }
// TODO -> Complete this code. See format used in assetguard.js#510 // TODO -> Complete this code. See format used in assetguard.js#510
const combined = BASE_URL + PLATFORM_MAP[process.platform] const latestData = await JavaGuard._latestJREOracle()
const combined = latestData.uri + PLATFORM_MAP[process.platform]
const name = combined.substring(combined.lastIndexOf('/')+1) const name = combined.substring(combined.lastIndexOf('/')+1)
const fDir = path.join(dir, name) const fDir = path.join(dir, name)
@ -260,15 +292,24 @@ function _downloadJava(acceptLicense, dir){
let writeStream = fs.createWriteStream(fDir) let writeStream = fs.createWriteStream(fDir)
req.pipe(writeStream) req.pipe(writeStream)
req.resume() req.resume()
}
_downloadJava(dir){
this._downloadOracleJRE(true, dir)
}
} }
async function test(){ async function test(){
console.log(await validate()) //console.log(await JavaGuard.validate())
const g = new JavaGuard()
g._downloadJava('C:\\Users\\Asus\\Desktop\\LauncherElectron\\target\\')
//console.log(JSON.stringify(await _latestJREOracle()))
} }
//test() test()
_downloadJava(true, 'C:\\Users\\Asus\\Desktop\\LauncherElectron\\target\\')
module.exports = { module.exports = {
validate JavaGuard
} }

View File

@ -5,6 +5,9 @@
"smallImageText": "WesterosCraft", "smallImageText": "WesterosCraft",
"smallImageKey": "seal-circle" "smallImageKey": "seal-circle"
}, },
"java": {
"oracle": "http://www.oracle.com/technetwork/java/javase/downloads/jre8-downloads-2133155.html"
},
"servers": [ "servers": [
{ {
"id": "WesterosCraft-1.11.2", "id": "WesterosCraft-1.11.2",