Compare commits

...

6 Commits

Author SHA1 Message Date
Daniel Scalzi
f119985211
Add version.jar to cp until 1.17. 2021-11-14 13:10:09 -05:00
Daniel Scalzi
2064e7ddd9
Patches to get 1.17 working, need to revise into real solutions. 2021-11-14 13:09:53 -05:00
Daniel Scalzi
9c6d75f812
Implement helios-core and use Server List Ping protocol. 2021-10-31 02:20:03 -04:00
Daniel Scalzi
a2168da999
Update eletron to v15, target node 16 to match. 2021-10-14 23:55:31 -04:00
Daniel Scalzi
430e840514
Update JDK handling to account for AdoptOpenJDK migration to Adoptium.
Fix bug with AdmZip by replacing it for the jdk extraction task. It will have to eventually be replaced for everything else.
Remove disclaimer about Oracle JDK, as it is no longer used.
2021-10-14 23:17:40 -04:00
Daniel Scalzi
f9e4fd8561
Fix Let's Encrypt DST Root CA X3 certificate expiration. 2021-10-01 21:57:22 -04:00
10 changed files with 5673 additions and 1297 deletions

View File

@ -17,7 +17,7 @@ jobs:
- name: Install Node.js, NPM and Yarn
uses: actions/setup-node@v1
with:
node-version: 14
node-version: 16
- name: Build/release Electron app
uses: samuelmeuli/action-electron-builder@v1

2
.nvmrc
View File

@ -1 +1 @@
14
16

View File

@ -83,7 +83,7 @@ This section details the setup of a basic developmentment environment.
**System Requirements**
* [Node.js][nodejs] v14
* [Node.js][nodejs] v16
---

View File

@ -5,6 +5,7 @@ const child_process = require('child_process')
const crypto = require('crypto')
const EventEmitter = require('events')
const fs = require('fs-extra')
const StreamZip = require('node-stream-zip')
const path = require('path')
const Registry = require('winreg')
const request = require('request')
@ -222,42 +223,6 @@ class JavaGuard extends EventEmitter {
this.mcVersion = mcVersion
}
// /**
// * @typedef OracleJREData
// * @property {string} uri The base uri of the JRE.
// * @property {{major: string, update: string, build: string}} version Object containing version information.
// */
// /**
// * Resolves the latest version of Oracle's JRE and parses its download link.
// *
// * @returns {Promise.<OracleJREData>} Promise which resolved to an object containing the JRE download data.
// */
// static _latestJREOracle(){
// const url = 'https://www.oracle.com/technetwork/java/javase/downloads/jre8-downloads-2133155.html'
// const regex = /https:\/\/.+?(?=\/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)
// }
// })
// })
// }
/**
* @typedef OpenJDKData
* @property {string} uri The base uri of the JRE.
@ -281,30 +246,41 @@ class JavaGuard extends EventEmitter {
if(process.platform === 'darwin') {
return this._latestCorretto(major)
} else {
return this._latestAdoptOpenJDK(major)
return this._latestAdoptium(major)
}
}
static _latestAdoptOpenJDK(major) {
static _latestAdoptium(major) {
const majorNum = Number(major)
const sanitizedOS = process.platform === 'win32' ? 'windows' : (process.platform === 'darwin' ? 'mac' : process.platform)
const url = `https://api.adoptium.net/v3/assets/latest/${major}/hotspot?vendor=eclipse`
const url = `https://api.adoptopenjdk.net/v2/latestAssets/nightly/openjdk${major}?os=${sanitizedOS}&arch=x64&heap_size=normal&openjdk_impl=hotspot&type=jre`
return new Promise((resolve, reject) => {
request({url, json: true}, (err, resp, body) => {
if(!err && body.length > 0){
resolve({
uri: body[0].binary_link,
size: body[0].binary_size,
name: body[0].binary_name
const targetBinary = body.find(entry => {
return entry.version.major === majorNum
&& entry.binary.os === sanitizedOS
&& entry.binary.image_type === 'jdk'
&& entry.binary.architecture === 'x64'
})
if(targetBinary != null) {
resolve({
uri: targetBinary.binary.package.link,
size: targetBinary.binary.package.size,
name: targetBinary.binary.package.name
})
} else {
resolve(null)
}
} else {
resolve(null)
}
})
})
}
static _latestCorretto(major) {
@ -499,15 +475,15 @@ class JavaGuard extends EventEmitter {
break
}
}
} else {
} else if(verOb.major >= 16) {
// TODO Make this logic better. Make java 16 required.
// Java 9+
if(Util.mcVersionAtLeast('1.13', this.mcVersion)){
console.log('Java 9+ not yet tested.')
/* meta.version = verOb
if(Util.mcVersionAtLeast('1.17', this.mcVersion)){
meta.version = verOb
++checksum
if(checksum === goal){
break
} */
}
}
}
// Space included so we get only the vendor.
@ -839,6 +815,7 @@ class JavaGuard extends EventEmitter {
pathSet1 = new Set([
...pathSet1,
...(await JavaGuard._scanFileSystem('C:\\Program Files\\Java')),
...(await JavaGuard._scanFileSystem('C:\\Program Files\\Eclipse Foundation')),
...(await JavaGuard._scanFileSystem('C:\\Program Files\\AdoptOpenJDK'))
])
}
@ -1583,21 +1560,7 @@ class AssetGuard extends EventEmitter {
this.java = new DLTracker([jre], jre.size, (a, self) => {
if(verData.name.endsWith('zip')){
const zip = new AdmZip(a.to)
const pos = path.join(dataDir, zip.getEntries()[0].entryName)
zip.extractAllToAsync(dataDir, true, (err) => {
if(err){
console.log(err)
self.emit('complete', 'java', JavaGuard.javaExecFromRoot(pos))
} else {
fs.unlink(a.to, err => {
if(err){
console.log(err)
}
self.emit('complete', 'java', JavaGuard.javaExecFromRoot(pos))
})
}
})
this._extractJdkZip(a.to, dataDir, self)
} else {
// Tar.gz
@ -1638,67 +1601,31 @@ class AssetGuard extends EventEmitter {
}
// _enqueueOracleJRE(dataDir){
// return new Promise((resolve, reject) => {
// JavaGuard._latestJREOracle().then(verData => {
// if(verData != null){
async _extractJdkZip(zipPath, runtimeDir, self) {
const zip = new StreamZip.async({
file: zipPath,
storeEntries: true
})
// 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 {
// dataDir = path.join(dataDir, 'runtime', 'x64')
// const name = combined.substring(combined.lastIndexOf('/')+1)
// const fDir = path.join(dataDir, name)
// const jre = new Asset(name, null, parseInt(resp.headers['content-length']), opts, fDir)
// this.java = new DLTracker([jre], jre.size, (a, self) => {
// let h = null
// fs.createReadStream(a.to)
// .on('error', err => console.log(err))
// .pipe(zlib.createGunzip())
// .on('error', err => console.log(err))
// .pipe(tar.extract(dataDir, {
// map: (header) => {
// if(h == null){
// h = header.name
// }
// }
// }))
// .on('error', err => console.log(err))
// .on('finish', () => {
// fs.unlink(a.to, err => {
// if(err){
// console.log(err)
// }
// if(h.indexOf('/') > -1){
// h = h.substring(0, h.indexOf('/'))
// }
// const pos = path.join(dataDir, h)
// self.emit('complete', 'java', JavaGuard.javaExecFromRoot(pos))
// })
// })
// })
// resolve(true)
// }
// })
let pos = ''
try {
const entries = await zip.entries()
pos = path.join(runtimeDir, Object.keys(entries)[0])
// } else {
// resolve(false)
// }
// })
// })
console.log('Extracting jdk..')
await zip.extract(null, runtimeDir)
console.log('Cleaning up..')
await fs.remove(zipPath)
console.log('Jdk extraction complete.')
// }
} catch(err) {
console.log(err)
} finally {
zip.close()
self.emit('complete', 'java', JavaGuard.javaExecFromRoot(pos))
}
}
// _enqueueMojangJRE(dir){
// return new Promise((resolve, reject) => {

View File

@ -96,6 +96,16 @@ class ProcessBuilder {
return child
}
/**
* Get the platform specific classpath separator. On windows, this is a semicolon.
* On Unix, this is a colon.
*
* @returns {string} The classpath separator for the current operating system.
*/
static getClasspathSeparator() {
return process.platform === 'win32' ? ';' : ':'
}
/**
* Determine if an optional mod is enabled from its configuration value. If the
* configuration value is null, the required object will be used to
@ -339,7 +349,7 @@ class ProcessBuilder {
// Classpath Argument
args.push('-cp')
args.push(this.classpathArg(mods, tempNativePath).join(process.platform === 'win32' ? ';' : ':'))
args.push(this.classpathArg(mods, tempNativePath).join(ProcessBuilder.getClasspathSeparator()))
// Java Arguments
if(process.platform === 'darwin'){
@ -377,6 +387,19 @@ class ProcessBuilder {
// JVM Arguments First
let args = this.versionData.arguments.jvm
// Debug securejarhandler
// args.push('-Dbsl.debug=true')
if(this.forgeData.arguments.jvm != null) {
for(const argStr of this.forgeData.arguments.jvm) {
args.push(argStr
.replaceAll('${library_directory}', this.libPath)
.replaceAll('${classpath_separator}', ProcessBuilder.getClasspathSeparator())
.replaceAll('${version_name}', this.forgeData.id)
)
}
}
//args.push('-Dlog4j.configurationFile=D:\\WesterosCraft\\game\\common\\assets\\log_configs\\client-1.12.xml')
// Java Arguments
@ -489,7 +512,7 @@ class ProcessBuilder {
val = args[i].replace(argDiscovery, this.launcherVersion)
break
case 'classpath':
val = this.classpathArg(mods, tempNativePath).join(process.platform === 'win32' ? ';' : ':')
val = this.classpathArg(mods, tempNativePath).join(ProcessBuilder.getClasspathSeparator())
break
}
if(val != null){
@ -647,9 +670,13 @@ class ProcessBuilder {
classpathArg(mods, tempNativePath){
let cpArgs = []
// Add the version.jar to the classpath.
const version = this.versionData.id
cpArgs.push(path.join(this.commonDir, 'versions', version, version + '.jar'))
if(!Util.mcVersionAtLeast('1.17', this.server.getMinecraftVersion())) {
// Add the version.jar to the classpath.
// Must not be added to the classpath for Forge 1.17+.
const version = this.versionData.id
cpArgs.push(path.join(this.commonDir, 'versions', version, version + '.jar'))
}
if(this.usingLiteLoader){
cpArgs.push(this.llPath)
@ -788,6 +815,15 @@ class ProcessBuilder {
let libs = []
for(let sm of mdl.getSubModules()){
if(sm.getType() === DistroManager.Types.Library){
// TODO Add as file or something.
const x = sm.getIdentifier()
console.log(x)
if(x.includes(':universal') || x.includes(':slim') || x.includes(':extra') || x.includes(':srg') || x.includes(':client')) {
console.log('SKIPPING ' + x)
continue
}
libs.push(sm.getArtifact().getPath())
}
// If this module has submodules, we need to resolve the libraries for those.

View File

@ -4,7 +4,8 @@
// Requirements
const cp = require('child_process')
const crypto = require('crypto')
const {URL} = require('url')
const { URL } = require('url')
const { getServerStatus } = require('helios-core')
// Internal Requirements
const DiscordWrapper = require('./assets/js/discordwrapper')
@ -225,11 +226,11 @@ const refreshServerStatus = async function(fade = false){
try {
const serverURL = new URL('my://' + serv.getAddress())
const servStat = await ServerStatus.getStatus(serverURL.hostname, serverURL.port)
if(servStat.online){
pLabel = 'PLAYERS'
pVal = servStat.onlinePlayers + '/' + servStat.maxPlayers
}
const servStat = await getServerStatus(47, serverURL.hostname, Number(serverURL.port))
console.log(servStat)
pLabel = 'PLAYERS'
pVal = servStat.players.online + '/' + servStat.players.max
} catch (err) {
loggerLanding.warn('Unable to refresh server status, assuming offline.')
@ -323,7 +324,7 @@ function asyncSystemScan(mcVersion, launchAfter = true){
// Show this information to the user.
setOverlayContent(
'No Compatible<br>Java Installation Found',
'In order to join WesterosCraft, you need a 64-bit installation of Java 8. Would you like us to install a copy? By installing, you accept <a href="http://www.oracle.com/technetwork/java/javase/terms/license/index.html">Oracle\'s license agreement</a>.',
'In order to join WesterosCraft, you need a 64-bit installation of Java 8. Would you like us to install a copy?',
'Install Java',
'Install Manually'
)

View File

@ -85,7 +85,7 @@ bindFileSelectors()
/**
* Bind value validators to the settings UI elements. These will
* validate against the criteria defined in the ConfigManager (if
* and). If the value is invalid, the UI will reflect this and saving
* any). If the value is invalid, the UI will reflect this and saving
* will be disabled until the value is corrected. This is an automated
* process. More complex UI may need to be bound separately.
*/

View File

@ -1,4 +1,5 @@
require('@electron/remote/main').initialize()
const remoteMain = require('@electron/remote/main')
remoteMain.initialize()
// Requirements
const { app, BrowserWindow, ipcMain, Menu } = require('electron')
@ -87,9 +88,6 @@ ipcMain.on('distributionIndexDone', (event, res) => {
// https://electronjs.org/docs/tutorial/offscreen-rendering
app.disableHardwareAcceleration()
// https://github.com/electron/electron/issues/18397
app.allowRendererProcessReuse = true
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let win
@ -104,11 +102,11 @@ function createWindow() {
webPreferences: {
preload: path.join(__dirname, 'app', 'assets', 'js', 'preloader.js'),
nodeIntegration: true,
contextIsolation: false,
enableRemoteModule: true
contextIsolation: false
},
backgroundColor: '#171614'
})
remoteMain.enable(win.webContents)
ejse.data('bkid', Math.floor((Math.random() * fs.readdirSync(path.join(__dirname, 'app', 'assets', 'images', 'backgrounds')).length)))

6702
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -20,28 +20,30 @@
"lint": "eslint --config .eslintrc.json ."
},
"engines": {
"node": "14.x.x"
"node": "16.x.x"
},
"dependencies": {
"@electron/remote": "^1.2.0",
"adm-zip": "^0.5.5",
"async": "^3.2.0",
"@electron/remote": "^2.0.1",
"adm-zip": "^0.5.9",
"async": "^3.2.1",
"discord-rpc": "^3.2.0",
"ejs": "^3.1.6",
"ejs-electron": "^2.1.1",
"electron-updater": "^4.3.9",
"fs-extra": "^10.0.0",
"github-syntax-dark": "^0.5.0",
"helios-core": "^0.1.0-alpha.3",
"jquery": "^3.6.0",
"node-stream-zip": "^1.15.0",
"request": "^2.88.2",
"semver": "^7.3.5",
"tar-fs": "^2.1.1",
"winreg": "^1.2.4"
},
"devDependencies": {
"electron": "^13.1.4",
"electron-builder": "^22.11.7",
"eslint": "^7.29.0"
"electron": "^15.2.0",
"electron-builder": "^22.13.1",
"eslint": "^8.0.1"
},
"repository": {
"type": "git",