mirror of
https://github.com/dscalzi/HeliosLauncher.git
synced 2024-12-21 19:22:13 -08:00
Compare commits
6 Commits
c6221e2afe
...
f119985211
Author | SHA1 | Date | |
---|---|---|---|
|
f119985211 | ||
|
2064e7ddd9 | ||
|
9c6d75f812 | ||
|
a2168da999 | ||
|
430e840514 | ||
|
f9e4fd8561 |
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@ -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
|
||||
|
@ -83,7 +83,7 @@ This section details the setup of a basic developmentment environment.
|
||||
|
||||
**System Requirements**
|
||||
|
||||
* [Node.js][nodejs] v14
|
||||
* [Node.js][nodejs] v16
|
||||
|
||||
---
|
||||
|
||||
|
@ -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) => {
|
||||
|
@ -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.
|
||||
|
@ -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'
|
||||
)
|
||||
|
@ -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.
|
||||
*/
|
||||
|
10
index.js
10
index.js
@ -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
6702
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
16
package.json
16
package.json
@ -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",
|
||||
|
Loading…
Reference in New Issue
Block a user