commit
22233831dc
6
.github/workflows/build.yml
vendored
6
.github/workflows/build.yml
vendored
@ -12,15 +12,15 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Check out Git repository
|
||||
uses: actions/checkout@v1
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@v1
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v2
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: 3.x
|
||||
|
||||
|
@ -3772,6 +3772,7 @@ input:checked + .toggleSwitchSlider:before {
|
||||
font-size: 10px;
|
||||
line-height: 10px;
|
||||
font-weight: bold;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
/* Content container for the server listing's information. */
|
||||
|
@ -1,74 +0,0 @@
|
||||
let target = require('./assetguard')[process.argv[2]]
|
||||
if(target == null){
|
||||
process.send({context: 'error', data: null, error: 'Invalid class name'})
|
||||
console.error('Invalid class name passed to argv[2], cannot continue.')
|
||||
process.exit(1)
|
||||
}
|
||||
let tracker = new target(...(process.argv.splice(3)))
|
||||
|
||||
const { LoggerUtil } = require('helios-core')
|
||||
const logger = LoggerUtil.getLogger('AssetExec')
|
||||
|
||||
//const tracker = new AssetGuard(process.argv[2], process.argv[3])
|
||||
logger.info('AssetExec Started')
|
||||
|
||||
// Temporary for debug purposes.
|
||||
process.on('unhandledRejection', r => console.log(r))
|
||||
|
||||
let percent = 0
|
||||
function assignListeners(){
|
||||
tracker.on('validate', (data) => {
|
||||
process.send({context: 'validate', data})
|
||||
})
|
||||
tracker.on('progress', (data, acc, total) => {
|
||||
const currPercent = parseInt((acc/total) * 100)
|
||||
if (currPercent !== percent) {
|
||||
percent = currPercent
|
||||
process.send({context: 'progress', data, value: acc, total, percent})
|
||||
}
|
||||
})
|
||||
tracker.on('complete', (data, ...args) => {
|
||||
process.send({context: 'complete', data, args})
|
||||
})
|
||||
tracker.on('error', (data, error) => {
|
||||
process.send({context: 'error', data, error})
|
||||
})
|
||||
}
|
||||
|
||||
assignListeners()
|
||||
|
||||
process.on('message', (msg) => {
|
||||
if(msg.task === 'execute'){
|
||||
const func = msg.function
|
||||
let nS = tracker[func] // Nonstatic context
|
||||
let iS = target[func] // Static context
|
||||
if(typeof nS === 'function' || typeof iS === 'function'){
|
||||
const f = typeof nS === 'function' ? nS : iS
|
||||
const res = f.apply(f === nS ? tracker : null, msg.argsArr)
|
||||
if(res instanceof Promise){
|
||||
res.then((v) => {
|
||||
process.send({result: v, context: func})
|
||||
}).catch((err) => {
|
||||
process.send({result: err.message || err, context: func})
|
||||
})
|
||||
} else {
|
||||
process.send({result: res, context: func})
|
||||
}
|
||||
} else {
|
||||
process.send({context: 'error', data: null, error: `Function ${func} not found on ${process.argv[2]}`})
|
||||
}
|
||||
} else if(msg.task === 'changeContext'){
|
||||
target = require('./assetguard')[msg.class]
|
||||
if(target == null){
|
||||
process.send({context: 'error', data: null, error: `Invalid class ${msg.class}`})
|
||||
} else {
|
||||
tracker = new target(...(msg.args))
|
||||
assignListeners()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
process.on('disconnect', () => {
|
||||
logger.info('AssetExec Disconnected')
|
||||
process.exit(0)
|
||||
})
|
File diff suppressed because it is too large
Load Diff
@ -6,11 +6,10 @@ const path = require('path')
|
||||
const logger = LoggerUtil.getLogger('ConfigManager')
|
||||
|
||||
const sysRoot = process.env.APPDATA || (process.platform == 'darwin' ? process.env.HOME + '/Library/Application Support' : process.env.HOME)
|
||||
// TODO change
|
||||
|
||||
const dataPath = path.join(sysRoot, '.helioslauncher')
|
||||
|
||||
// Forked processes do not have access to electron, so we have this workaround.
|
||||
const launcherDir = process.env.CONFIG_DIRECT_PATH || require('@electron/remote').app.getPath('userData')
|
||||
const launcherDir = require('@electron/remote').app.getPath('userData')
|
||||
|
||||
/**
|
||||
* Retrieve the absolute path of the launcher directory.
|
||||
@ -44,45 +43,30 @@ const configPath = path.join(exports.getLauncherDirectory(), 'config.json')
|
||||
const configPathLEGACY = path.join(dataPath, 'config.json')
|
||||
const firstLaunch = !fs.existsSync(configPath) && !fs.existsSync(configPathLEGACY)
|
||||
|
||||
exports.getAbsoluteMinRAM = function(){
|
||||
exports.getAbsoluteMinRAM = function(ram){
|
||||
if(ram?.minimum != null) {
|
||||
return ram.minimum/1024
|
||||
} else {
|
||||
// Legacy behavior
|
||||
const mem = os.totalmem()
|
||||
return mem >= 6000000000 ? 3 : 2
|
||||
}
|
||||
|
||||
exports.getAbsoluteMaxRAM = function(){
|
||||
const mem = os.totalmem()
|
||||
const gT16 = mem-16000000000
|
||||
return Math.floor((mem-1000000000-(gT16 > 0 ? (Number.parseInt(gT16/8) + 16000000000/4) : mem/4))/1000000000)
|
||||
}
|
||||
|
||||
function resolveMaxRAM(){
|
||||
const mem = os.totalmem()
|
||||
return mem >= 8000000000 ? '4G' : (mem >= 6000000000 ? '3G' : '2G')
|
||||
}
|
||||
|
||||
function resolveMinRAM(){
|
||||
return resolveMaxRAM()
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO Copy pasted, should be in a utility file.
|
||||
*
|
||||
* Returns true if the actual version is greater than
|
||||
* or equal to the desired version.
|
||||
*
|
||||
* @param {string} desired The desired version.
|
||||
* @param {string} actual The actual version.
|
||||
*/
|
||||
function mcVersionAtLeast(desired, actual){
|
||||
const des = desired.split('.')
|
||||
const act = actual.split('.')
|
||||
|
||||
for(let i=0; i<des.length; i++){
|
||||
if(!(parseInt(act[i]) >= parseInt(des[i]))){
|
||||
return false
|
||||
return mem >= (6*1073741824) ? 3 : 2
|
||||
}
|
||||
}
|
||||
|
||||
exports.getAbsoluteMaxRAM = function(ram){
|
||||
const mem = os.totalmem()
|
||||
const gT16 = mem-(16*1073741824)
|
||||
return Math.floor((mem-(gT16 > 0 ? (Number.parseInt(gT16/8) + (16*1073741824)/4) : mem/4))/1073741824)
|
||||
}
|
||||
|
||||
function resolveSelectedRAM(ram) {
|
||||
if(ram?.recommended != null) {
|
||||
return `${ram.recommended}M`
|
||||
} else {
|
||||
// Legacy behavior
|
||||
const mem = os.totalmem()
|
||||
return mem >= (8*1073741824) ? '4G' : (mem >= (6*1073741824) ? '3G' : '2G')
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
@ -523,18 +507,18 @@ exports.setModConfiguration = function(serverid, configuration){
|
||||
|
||||
// Java Settings
|
||||
|
||||
function defaultJavaConfig(mcVersion) {
|
||||
if(mcVersionAtLeast('1.17', mcVersion)) {
|
||||
return defaultJavaConfig117()
|
||||
function defaultJavaConfig(effectiveJavaOptions, ram) {
|
||||
if(effectiveJavaOptions.suggestedMajor > 8) {
|
||||
return defaultJavaConfig17(ram)
|
||||
} else {
|
||||
return defaultJavaConfigBelow117()
|
||||
return defaultJavaConfig8(ram)
|
||||
}
|
||||
}
|
||||
|
||||
function defaultJavaConfigBelow117() {
|
||||
function defaultJavaConfig8(ram) {
|
||||
return {
|
||||
minRAM: resolveMinRAM(),
|
||||
maxRAM: resolveMaxRAM(), // Dynamic
|
||||
minRAM: resolveSelectedRAM(ram),
|
||||
maxRAM: resolveSelectedRAM(ram),
|
||||
executable: null,
|
||||
jvmOptions: [
|
||||
'-XX:+UseConcMarkSweepGC',
|
||||
@ -545,10 +529,10 @@ function defaultJavaConfigBelow117() {
|
||||
}
|
||||
}
|
||||
|
||||
function defaultJavaConfig117() {
|
||||
function defaultJavaConfig17(ram) {
|
||||
return {
|
||||
minRAM: resolveMinRAM(),
|
||||
maxRAM: resolveMaxRAM(), // Dynamic
|
||||
minRAM: resolveSelectedRAM(ram),
|
||||
maxRAM: resolveSelectedRAM(ram),
|
||||
executable: null,
|
||||
jvmOptions: [
|
||||
'-XX:+UnlockExperimentalVMOptions',
|
||||
@ -567,9 +551,9 @@ function defaultJavaConfig117() {
|
||||
* @param {string} serverid The server id.
|
||||
* @param {*} mcVersion The minecraft version of the server.
|
||||
*/
|
||||
exports.ensureJavaConfig = function(serverid, mcVersion) {
|
||||
exports.ensureJavaConfig = function(serverid, effectiveJavaOptions, ram) {
|
||||
if(!Object.prototype.hasOwnProperty.call(config.javaConfig, serverid)) {
|
||||
config.javaConfig[serverid] = defaultJavaConfig(mcVersion)
|
||||
config.javaConfig[serverid] = defaultJavaConfig(effectiveJavaOptions, ram)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,621 +1,17 @@
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
const request = require('request')
|
||||
const { LoggerUtil } = require('helios-core')
|
||||
const { DistributionAPI } = require('helios-core/common')
|
||||
|
||||
const ConfigManager = require('./configmanager')
|
||||
|
||||
const logger = LoggerUtil.getLogger('DistroManager')
|
||||
|
||||
/**
|
||||
* Represents the download information
|
||||
* for a specific module.
|
||||
*/
|
||||
class Artifact {
|
||||
|
||||
/**
|
||||
* Parse a JSON object into an Artifact.
|
||||
*
|
||||
* @param {Object} json A JSON object representing an Artifact.
|
||||
*
|
||||
* @returns {Artifact} The parsed Artifact.
|
||||
*/
|
||||
static fromJSON(json){
|
||||
return Object.assign(new Artifact(), json)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the MD5 hash of the artifact. This value may
|
||||
* be undefined for artifacts which are not to be
|
||||
* validated and updated.
|
||||
*
|
||||
* @returns {string} The MD5 hash of the Artifact or undefined.
|
||||
*/
|
||||
getHash(){
|
||||
return this.MD5
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {number} The download size of the artifact.
|
||||
*/
|
||||
getSize(){
|
||||
return this.size
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string} The download url of the artifact.
|
||||
*/
|
||||
getURL(){
|
||||
return this.url
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string} The artifact's destination path.
|
||||
*/
|
||||
getPath(){
|
||||
return this.path
|
||||
}
|
||||
|
||||
}
|
||||
exports.Artifact
|
||||
|
||||
/**
|
||||
* Represents a the requirement status
|
||||
* of a module.
|
||||
*/
|
||||
class Required {
|
||||
|
||||
/**
|
||||
* Parse a JSON object into a Required object.
|
||||
*
|
||||
* @param {Object} json A JSON object representing a Required object.
|
||||
*
|
||||
* @returns {Required} The parsed Required object.
|
||||
*/
|
||||
static fromJSON(json){
|
||||
if(json == null){
|
||||
return new Required(true, true)
|
||||
} else {
|
||||
return new Required(json.value == null ? true : json.value, json.def == null ? true : json.def)
|
||||
}
|
||||
}
|
||||
|
||||
constructor(value, def){
|
||||
this.value = value
|
||||
this.default = def
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default value for a required object. If a module
|
||||
* is not required, this value determines whether or not
|
||||
* it is enabled by default.
|
||||
*
|
||||
* @returns {boolean} The default enabled value.
|
||||
*/
|
||||
isDefault(){
|
||||
return this.default
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {boolean} Whether or not the module is required.
|
||||
*/
|
||||
isRequired(){
|
||||
return this.value
|
||||
}
|
||||
|
||||
}
|
||||
exports.Required
|
||||
|
||||
/**
|
||||
* Represents a module.
|
||||
*/
|
||||
class Module {
|
||||
|
||||
/**
|
||||
* Parse a JSON object into a Module.
|
||||
*
|
||||
* @param {Object} json A JSON object representing a Module.
|
||||
* @param {string} serverid The ID of the server to which this module belongs.
|
||||
*
|
||||
* @returns {Module} The parsed Module.
|
||||
*/
|
||||
static fromJSON(json, serverid){
|
||||
return new Module(json.id, json.name, json.type, json.classpath, json.required, json.artifact, json.subModules, serverid)
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the default extension for a specific module type.
|
||||
*
|
||||
* @param {string} type The type of the module.
|
||||
*
|
||||
* @return {string} The default extension for the given type.
|
||||
*/
|
||||
static _resolveDefaultExtension(type){
|
||||
switch (type) {
|
||||
case exports.Types.Library:
|
||||
case exports.Types.ForgeHosted:
|
||||
case exports.Types.LiteLoader:
|
||||
case exports.Types.ForgeMod:
|
||||
return 'jar'
|
||||
case exports.Types.LiteMod:
|
||||
return 'litemod'
|
||||
case exports.Types.File:
|
||||
default:
|
||||
return 'jar' // There is no default extension really.
|
||||
}
|
||||
}
|
||||
|
||||
constructor(id, name, type, classpath, required, artifact, subModules, serverid) {
|
||||
this.identifier = id
|
||||
this.type = type
|
||||
this.classpath = classpath
|
||||
this._resolveMetaData()
|
||||
this.name = name
|
||||
this.required = Required.fromJSON(required)
|
||||
this.artifact = Artifact.fromJSON(artifact)
|
||||
this._resolveArtifactPath(artifact.path, serverid)
|
||||
this._resolveSubModules(subModules, serverid)
|
||||
}
|
||||
|
||||
_resolveMetaData(){
|
||||
try {
|
||||
|
||||
const m0 = this.identifier.split('@')
|
||||
|
||||
this.artifactExt = m0[1] || Module._resolveDefaultExtension(this.type)
|
||||
|
||||
const m1 = m0[0].split(':')
|
||||
|
||||
this.artifactClassifier = m1[3] || undefined
|
||||
this.artifactVersion = m1[2] || '???'
|
||||
this.artifactID = m1[1] || '???'
|
||||
this.artifactGroup = m1[0] || '???'
|
||||
|
||||
} catch (err) {
|
||||
// Improper identifier
|
||||
logger.error('Improper ID for module', this.identifier, err)
|
||||
}
|
||||
}
|
||||
|
||||
_resolveArtifactPath(artifactPath, serverid){
|
||||
const pth = artifactPath == null ? path.join(...this.getGroup().split('.'), this.getID(), this.getVersion(), `${this.getID()}-${this.getVersion()}${this.artifactClassifier != undefined ? `-${this.artifactClassifier}` : ''}.${this.getExtension()}`) : artifactPath
|
||||
|
||||
switch (this.type){
|
||||
case exports.Types.Library:
|
||||
case exports.Types.ForgeHosted:
|
||||
case exports.Types.LiteLoader:
|
||||
this.artifact.path = path.join(ConfigManager.getCommonDirectory(), 'libraries', pth)
|
||||
break
|
||||
case exports.Types.ForgeMod:
|
||||
case exports.Types.LiteMod:
|
||||
this.artifact.path = path.join(ConfigManager.getCommonDirectory(), 'modstore', pth)
|
||||
break
|
||||
case exports.Types.VersionManifest:
|
||||
this.artifact.path = path.join(ConfigManager.getCommonDirectory(), 'versions', this.getIdentifier(), `${this.getIdentifier()}.json`)
|
||||
break
|
||||
case exports.Types.File:
|
||||
default:
|
||||
this.artifact.path = path.join(ConfigManager.getInstanceDirectory(), serverid, pth)
|
||||
break
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
_resolveSubModules(json, serverid){
|
||||
const arr = []
|
||||
if(json != null){
|
||||
for(let sm of json){
|
||||
arr.push(Module.fromJSON(sm, serverid))
|
||||
}
|
||||
}
|
||||
this.subModules = arr.length > 0 ? arr : null
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string} The full, unparsed module identifier.
|
||||
*/
|
||||
getIdentifier(){
|
||||
return this.identifier
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string} The name of the module.
|
||||
*/
|
||||
getName(){
|
||||
return this.name
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Required} The required object declared by this module.
|
||||
*/
|
||||
getRequired(){
|
||||
return this.required
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Artifact} The artifact declared by this module.
|
||||
*/
|
||||
getArtifact(){
|
||||
return this.artifact
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string} The maven identifier of this module's artifact.
|
||||
*/
|
||||
getID(){
|
||||
return this.artifactID
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string} The maven group of this module's artifact.
|
||||
*/
|
||||
getGroup(){
|
||||
return this.artifactGroup
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string} The identifier without he version or extension.
|
||||
*/
|
||||
getVersionlessID(){
|
||||
return this.getGroup() + ':' + this.getID()
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string} The identifier without the extension.
|
||||
*/
|
||||
getExtensionlessID(){
|
||||
return this.getIdentifier().split('@')[0]
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string} The version of this module's artifact.
|
||||
*/
|
||||
getVersion(){
|
||||
return this.artifactVersion
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string} The classifier of this module's artifact
|
||||
*/
|
||||
getClassifier(){
|
||||
return this.artifactClassifier
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string} The extension of this module's artifact.
|
||||
*/
|
||||
getExtension(){
|
||||
return this.artifactExt
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {boolean} Whether or not this module has sub modules.
|
||||
*/
|
||||
hasSubModules(){
|
||||
return this.subModules != null
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Array.<Module>} An array of sub modules.
|
||||
*/
|
||||
getSubModules(){
|
||||
return this.subModules
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string} The type of the module.
|
||||
*/
|
||||
getType(){
|
||||
return this.type
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {boolean} Whether or not this library should be on the classpath.
|
||||
*/
|
||||
getClasspath(){
|
||||
return this.classpath ?? true
|
||||
}
|
||||
|
||||
}
|
||||
exports.Module
|
||||
|
||||
/**
|
||||
* Represents a server configuration.
|
||||
*/
|
||||
class Server {
|
||||
|
||||
/**
|
||||
* Parse a JSON object into a Server.
|
||||
*
|
||||
* @param {Object} json A JSON object representing a Server.
|
||||
*
|
||||
* @returns {Server} The parsed Server object.
|
||||
*/
|
||||
static fromJSON(json){
|
||||
|
||||
const mdls = json.modules
|
||||
json.modules = []
|
||||
|
||||
const serv = Object.assign(new Server(), json)
|
||||
serv._resolveModules(mdls)
|
||||
|
||||
return serv
|
||||
}
|
||||
|
||||
_resolveModules(json){
|
||||
const arr = []
|
||||
for(let m of json){
|
||||
arr.push(Module.fromJSON(m, this.getID()))
|
||||
}
|
||||
this.modules = arr
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string} The ID of the server.
|
||||
*/
|
||||
getID(){
|
||||
return this.id
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string} The name of the server.
|
||||
*/
|
||||
getName(){
|
||||
return this.name
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string} The description of the server.
|
||||
*/
|
||||
getDescription(){
|
||||
return this.description
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string} The URL of the server's icon.
|
||||
*/
|
||||
getIcon(){
|
||||
return this.icon
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string} The version of the server configuration.
|
||||
*/
|
||||
getVersion(){
|
||||
return this.version
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string} The IP address of the server.
|
||||
*/
|
||||
getAddress(){
|
||||
return this.address
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string} The minecraft version of the server.
|
||||
*/
|
||||
getMinecraftVersion(){
|
||||
return this.minecraftVersion
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {boolean} Whether or not this server is the main
|
||||
* server. The main server is selected by the launcher when
|
||||
* no valid server is selected.
|
||||
*/
|
||||
isMainServer(){
|
||||
return this.mainServer
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {boolean} Whether or not the server is autoconnect.
|
||||
* by default.
|
||||
*/
|
||||
isAutoConnect(){
|
||||
return this.autoconnect
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Array.<Module>} An array of modules for this server.
|
||||
*/
|
||||
getModules(){
|
||||
return this.modules
|
||||
}
|
||||
|
||||
}
|
||||
exports.Server
|
||||
|
||||
/**
|
||||
* Represents the Distribution Index.
|
||||
*/
|
||||
class DistroIndex {
|
||||
|
||||
/**
|
||||
* Parse a JSON object into a DistroIndex.
|
||||
*
|
||||
* @param {Object} json A JSON object representing a DistroIndex.
|
||||
*
|
||||
* @returns {DistroIndex} The parsed Server object.
|
||||
*/
|
||||
static fromJSON(json){
|
||||
|
||||
const servers = json.servers
|
||||
json.servers = []
|
||||
|
||||
const distro = Object.assign(new DistroIndex(), json)
|
||||
distro._resolveServers(servers)
|
||||
distro._resolveMainServer()
|
||||
|
||||
return distro
|
||||
}
|
||||
|
||||
_resolveServers(json){
|
||||
const arr = []
|
||||
for(let s of json){
|
||||
arr.push(Server.fromJSON(s))
|
||||
}
|
||||
this.servers = arr
|
||||
}
|
||||
|
||||
_resolveMainServer(){
|
||||
|
||||
for(let serv of this.servers){
|
||||
if(serv.mainServer){
|
||||
this.mainServer = serv.id
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// If no server declares default_selected, default to the first one declared.
|
||||
this.mainServer = (this.servers.length > 0) ? this.servers[0].getID() : null
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string} The version of the distribution index.
|
||||
*/
|
||||
getVersion(){
|
||||
return this.version
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string} The URL to the news RSS feed.
|
||||
*/
|
||||
getRSS(){
|
||||
return this.rss
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Array.<Server>} An array of declared server configurations.
|
||||
*/
|
||||
getServers(){
|
||||
return this.servers
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a server configuration by its ID. If it does not
|
||||
* exist, null will be returned.
|
||||
*
|
||||
* @param {string} id The ID of the server.
|
||||
*
|
||||
* @returns {Server} The server configuration with the given ID or null.
|
||||
*/
|
||||
getServer(id){
|
||||
for(let serv of this.servers){
|
||||
if(serv.id === id){
|
||||
return serv
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the main server.
|
||||
*
|
||||
* @returns {Server} The main server.
|
||||
*/
|
||||
getMainServer(){
|
||||
return this.mainServer != null ? this.getServer(this.mainServer) : null
|
||||
}
|
||||
|
||||
}
|
||||
exports.DistroIndex
|
||||
|
||||
exports.Types = {
|
||||
Library: 'Library',
|
||||
ForgeHosted: 'ForgeHosted',
|
||||
Forge: 'Forge', // Unimplemented
|
||||
LiteLoader: 'LiteLoader',
|
||||
ForgeMod: 'ForgeMod',
|
||||
LiteMod: 'LiteMod',
|
||||
File: 'File',
|
||||
VersionManifest: 'VersionManifest'
|
||||
}
|
||||
|
||||
let DEV_MODE = false
|
||||
|
||||
const DISTRO_PATH = path.join(ConfigManager.getLauncherDirectory(), 'distribution.json')
|
||||
const DEV_PATH = path.join(ConfigManager.getLauncherDirectory(), 'dev_distribution.json')
|
||||
|
||||
let data = null
|
||||
|
||||
/**
|
||||
* @returns {Promise.<DistroIndex>}
|
||||
*/
|
||||
exports.pullRemote = function(){
|
||||
if(DEV_MODE){
|
||||
return exports.pullLocal()
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
const distroURL = 'http://mc.westeroscraft.com/WesterosCraftLauncher/distribution.json'
|
||||
//const distroURL = 'https://gist.githubusercontent.com/dscalzi/53b1ba7a11d26a5c353f9d5ae484b71b/raw/'
|
||||
const opts = {
|
||||
url: distroURL,
|
||||
timeout: 2500
|
||||
}
|
||||
const distroDest = path.join(ConfigManager.getLauncherDirectory(), 'distribution.json')
|
||||
request(opts, (error, resp, body) => {
|
||||
if(!error){
|
||||
|
||||
try {
|
||||
data = DistroIndex.fromJSON(JSON.parse(body))
|
||||
} catch (e) {
|
||||
reject(e)
|
||||
return
|
||||
}
|
||||
|
||||
fs.writeFile(distroDest, body, 'utf-8', (err) => {
|
||||
if(!err){
|
||||
resolve(data)
|
||||
return
|
||||
} else {
|
||||
reject(err)
|
||||
return
|
||||
}
|
||||
})
|
||||
} else {
|
||||
reject(error)
|
||||
return
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Promise.<DistroIndex>}
|
||||
*/
|
||||
exports.pullLocal = function(){
|
||||
return new Promise((resolve, reject) => {
|
||||
fs.readFile(DEV_MODE ? DEV_PATH : DISTRO_PATH, 'utf-8', (err, d) => {
|
||||
if(!err){
|
||||
data = DistroIndex.fromJSON(JSON.parse(d))
|
||||
resolve(data)
|
||||
return
|
||||
} else {
|
||||
reject(err)
|
||||
return
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
exports.setDevMode = function(value){
|
||||
if(value){
|
||||
logger.info('Developer mode enabled.')
|
||||
logger.info('If you don\'t know what that means, revert immediately.')
|
||||
} else {
|
||||
logger.info('Developer mode disabled.')
|
||||
}
|
||||
DEV_MODE = value
|
||||
}
|
||||
|
||||
exports.isDevMode = function(){
|
||||
return DEV_MODE
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {DistroIndex}
|
||||
*/
|
||||
exports.getDistribution = function(){
|
||||
return data
|
||||
}
|
||||
// Old WesterosCraft url.
|
||||
// exports.REMOTE_DISTRO_URL = 'http://mc.westeroscraft.com/WesterosCraftLauncher/distribution.json'
|
||||
exports.REMOTE_DISTRO_URL = 'https://helios-files.geekcorner.eu.org/distribution.json'
|
||||
|
||||
const api = new DistributionAPI(
|
||||
ConfigManager.getLauncherDirectory(),
|
||||
null, // Injected forcefully by the preloader.
|
||||
null, // Injected forcefully by the preloader.
|
||||
exports.REMOTE_DISTRO_URL,
|
||||
false
|
||||
)
|
||||
|
||||
exports.DistroAPI = api
|
@ -4,9 +4,11 @@ const os = require('os')
|
||||
const path = require('path')
|
||||
|
||||
const ConfigManager = require('./configmanager')
|
||||
const DistroManager = require('./distromanager')
|
||||
const { DistroAPI } = require('./distromanager')
|
||||
const LangLoader = require('./langloader')
|
||||
const { LoggerUtil } = require('helios-core')
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const { HeliosDistribution } = require('helios-core/common')
|
||||
|
||||
const logger = LoggerUtil.getLogger('Preloader')
|
||||
|
||||
@ -15,16 +17,25 @@ logger.info('Loading..')
|
||||
// Load ConfigManager
|
||||
ConfigManager.load()
|
||||
|
||||
// Yuck!
|
||||
// TODO Fix this
|
||||
DistroAPI['commonDir'] = ConfigManager.getCommonDirectory()
|
||||
DistroAPI['instanceDir'] = ConfigManager.getInstanceDirectory()
|
||||
|
||||
// Load Strings
|
||||
LangLoader.loadLanguage('en_US')
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {HeliosDistribution} data
|
||||
*/
|
||||
function onDistroLoad(data){
|
||||
if(data != null){
|
||||
|
||||
// Resolve the selected server if its value has yet to be set.
|
||||
if(ConfigManager.getSelectedServer() == null || data.getServer(ConfigManager.getSelectedServer()) == null){
|
||||
if(ConfigManager.getSelectedServer() == null || data.getServerById(ConfigManager.getSelectedServer()) == null){
|
||||
logger.info('Determining default selected server..')
|
||||
ConfigManager.setSelectedServer(data.getMainServer().getID())
|
||||
ConfigManager.setSelectedServer(data.getMainServer().rawServer.id)
|
||||
ConfigManager.save()
|
||||
}
|
||||
}
|
||||
@ -32,35 +43,20 @@ function onDistroLoad(data){
|
||||
}
|
||||
|
||||
// Ensure Distribution is downloaded and cached.
|
||||
DistroManager.pullRemote().then((data) => {
|
||||
DistroAPI.getDistribution()
|
||||
.then(heliosDistro => {
|
||||
logger.info('Loaded distribution index.')
|
||||
|
||||
onDistroLoad(data)
|
||||
|
||||
}).catch((err) => {
|
||||
logger.info('Failed to load distribution index.')
|
||||
logger.error(err)
|
||||
|
||||
logger.info('Attempting to load an older version of the distribution index.')
|
||||
// Try getting a local copy, better than nothing.
|
||||
DistroManager.pullLocal().then((data) => {
|
||||
logger.info('Successfully loaded an older version of the distribution index.')
|
||||
|
||||
onDistroLoad(data)
|
||||
|
||||
|
||||
}).catch((err) => {
|
||||
|
||||
onDistroLoad(heliosDistro)
|
||||
})
|
||||
.catch(err => {
|
||||
logger.info('Failed to load an older version of the distribution index.')
|
||||
logger.info('Application cannot run.')
|
||||
logger.error(err)
|
||||
|
||||
onDistroLoad(null)
|
||||
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
// Clean up temp dir incase previous launches ended unexpectedly.
|
||||
fs.remove(path.join(os.tmpdir(), ConfigManager.getTempNativeFolder()), (err) => {
|
||||
if(err){
|
||||
|
@ -3,20 +3,19 @@ const child_process = require('child_process')
|
||||
const crypto = require('crypto')
|
||||
const fs = require('fs-extra')
|
||||
const { LoggerUtil } = require('helios-core')
|
||||
const { getMojangOS, isLibraryCompatible, mcVersionAtLeast } = require('helios-core/common')
|
||||
const { Type } = require('helios-distribution-types')
|
||||
const os = require('os')
|
||||
const path = require('path')
|
||||
const { URL } = require('url')
|
||||
|
||||
const { Util, Library } = require('./assetguard')
|
||||
const ConfigManager = require('./configmanager')
|
||||
const DistroManager = require('./distromanager')
|
||||
|
||||
const logger = LoggerUtil.getLogger('ProcessBuilder')
|
||||
|
||||
class ProcessBuilder {
|
||||
|
||||
constructor(distroServer, versionData, forgeData, authUser, launcherVersion){
|
||||
this.gameDir = path.join(ConfigManager.getInstanceDirectory(), distroServer.getID())
|
||||
this.gameDir = path.join(ConfigManager.getInstanceDirectory(), distroServer.rawServer.id)
|
||||
this.commonDir = ConfigManager.getCommonDirectory()
|
||||
this.server = distroServer
|
||||
this.versionData = versionData
|
||||
@ -41,10 +40,10 @@ class ProcessBuilder {
|
||||
process.throwDeprecation = true
|
||||
this.setupLiteLoader()
|
||||
logger.info('Using liteloader:', this.usingLiteLoader)
|
||||
const modObj = this.resolveModConfiguration(ConfigManager.getModConfiguration(this.server.getID()).mods, this.server.getModules())
|
||||
const modObj = this.resolveModConfiguration(ConfigManager.getModConfiguration(this.server.rawServer.id).mods, this.server.modules)
|
||||
|
||||
// Mod list below 1.13
|
||||
if(!Util.mcVersionAtLeast('1.13', this.server.getMinecraftVersion())){
|
||||
if(!mcVersionAtLeast('1.13', this.server.rawServer.minecraftVersion)){
|
||||
this.constructJSONModList('forge', modObj.fMods, true)
|
||||
if(this.usingLiteLoader){
|
||||
this.constructJSONModList('liteloader', modObj.lMods, true)
|
||||
@ -54,14 +53,14 @@ class ProcessBuilder {
|
||||
const uberModArr = modObj.fMods.concat(modObj.lMods)
|
||||
let args = this.constructJVMArguments(uberModArr, tempNativePath)
|
||||
|
||||
if(Util.mcVersionAtLeast('1.13', this.server.getMinecraftVersion())){
|
||||
if(mcVersionAtLeast('1.13', this.server.rawServer.minecraftVersion)){
|
||||
//args = args.concat(this.constructModArguments(modObj.fMods))
|
||||
args = args.concat(this.constructModList(modObj.fMods))
|
||||
}
|
||||
|
||||
logger.info('Launch Arguments:', args)
|
||||
|
||||
const child = child_process.spawn(ConfigManager.getJavaExecutable(this.server.getID()), args, {
|
||||
const child = child_process.spawn(ConfigManager.getJavaExecutable(this.server.rawServer.id), args, {
|
||||
cwd: this.gameDir,
|
||||
detached: ConfigManager.getLaunchDetached()
|
||||
})
|
||||
@ -122,7 +121,7 @@ class ProcessBuilder {
|
||||
* @returns {boolean} True if the mod is enabled, false otherwise.
|
||||
*/
|
||||
static isModEnabled(modCfg, required = null){
|
||||
return modCfg != null ? ((typeof modCfg === 'boolean' && modCfg) || (typeof modCfg === 'object' && (typeof modCfg.value !== 'undefined' ? modCfg.value : true))) : required != null ? required.isDefault() : true
|
||||
return modCfg != null ? ((typeof modCfg === 'boolean' && modCfg) || (typeof modCfg === 'object' && (typeof modCfg.value !== 'undefined' ? modCfg.value : true))) : required != null ? required.def : true
|
||||
}
|
||||
|
||||
/**
|
||||
@ -132,20 +131,20 @@ class ProcessBuilder {
|
||||
* mod. It must not be declared as a submodule.
|
||||
*/
|
||||
setupLiteLoader(){
|
||||
for(let ll of this.server.getModules()){
|
||||
if(ll.getType() === DistroManager.Types.LiteLoader){
|
||||
if(!ll.getRequired().isRequired()){
|
||||
const modCfg = ConfigManager.getModConfiguration(this.server.getID()).mods
|
||||
if(ProcessBuilder.isModEnabled(modCfg[ll.getVersionlessID()], ll.getRequired())){
|
||||
if(fs.existsSync(ll.getArtifact().getPath())){
|
||||
for(let ll of this.server.modules){
|
||||
if(ll.rawModule.type === Type.LiteLoader){
|
||||
if(!ll.getRequired().value){
|
||||
const modCfg = ConfigManager.getModConfiguration(this.server.rawServer.id).mods
|
||||
if(ProcessBuilder.isModEnabled(modCfg[ll.getVersionlessMavenIdentifier()], ll.getRequired())){
|
||||
if(fs.existsSync(ll.getPath())){
|
||||
this.usingLiteLoader = true
|
||||
this.llPath = ll.getArtifact().getPath()
|
||||
this.llPath = ll.getPath()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(fs.existsSync(ll.getArtifact().getPath())){
|
||||
if(fs.existsSync(ll.getPath())){
|
||||
this.usingLiteLoader = true
|
||||
this.llPath = ll.getArtifact().getPath()
|
||||
this.llPath = ll.getPath()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -166,20 +165,20 @@ class ProcessBuilder {
|
||||
let lMods = []
|
||||
|
||||
for(let mdl of mdls){
|
||||
const type = mdl.getType()
|
||||
if(type === DistroManager.Types.ForgeMod || type === DistroManager.Types.LiteMod || type === DistroManager.Types.LiteLoader){
|
||||
const o = !mdl.getRequired().isRequired()
|
||||
const e = ProcessBuilder.isModEnabled(modCfg[mdl.getVersionlessID()], mdl.getRequired())
|
||||
const type = mdl.rawModule.type
|
||||
if(type === Type.ForgeMod || type === Type.LiteMod || type === Type.LiteLoader){
|
||||
const o = !mdl.getRequired().value
|
||||
const e = ProcessBuilder.isModEnabled(modCfg[mdl.getVersionlessMavenIdentifier()], mdl.getRequired())
|
||||
if(!o || (o && e)){
|
||||
if(mdl.hasSubModules()){
|
||||
const v = this.resolveModConfiguration(modCfg[mdl.getVersionlessID()].mods, mdl.getSubModules())
|
||||
if(mdl.subModules.length > 0){
|
||||
const v = this.resolveModConfiguration(modCfg[mdl.getVersionlessMavenIdentifier()].mods, mdl.subModules)
|
||||
fMods = fMods.concat(v.fMods)
|
||||
lMods = lMods.concat(v.lMods)
|
||||
if(mdl.type === DistroManager.Types.LiteLoader){
|
||||
if(type === Type.LiteLoader){
|
||||
continue
|
||||
}
|
||||
}
|
||||
if(mdl.type === DistroManager.Types.ForgeMod){
|
||||
if(type === Type.ForgeMod){
|
||||
fMods.push(mdl)
|
||||
} else {
|
||||
lMods.push(mdl)
|
||||
@ -242,11 +241,11 @@ class ProcessBuilder {
|
||||
const ids = []
|
||||
if(type === 'forge'){
|
||||
for(let mod of mods){
|
||||
ids.push(mod.getExtensionlessID())
|
||||
ids.push(mod.getExtensionlessMavenIdentifier())
|
||||
}
|
||||
} else {
|
||||
for(let mod of mods){
|
||||
ids.push(mod.getExtensionlessID() + '@' + mod.getExtension())
|
||||
ids.push(mod.getMavenIdentifier())
|
||||
}
|
||||
}
|
||||
modList.modRef = ids
|
||||
@ -266,7 +265,7 @@ class ProcessBuilder {
|
||||
// */
|
||||
// constructModArguments(mods){
|
||||
// const argStr = mods.map(mod => {
|
||||
// return mod.getExtensionlessID()
|
||||
// return mod.getExtensionlessMavenIdentifier()
|
||||
// }).join(',')
|
||||
|
||||
// if(argStr){
|
||||
@ -289,7 +288,7 @@ class ProcessBuilder {
|
||||
*/
|
||||
constructModList(mods) {
|
||||
const writeBuffer = mods.map(mod => {
|
||||
return mod.getExtensionlessID()
|
||||
return mod.getExtensionlessMavenIdentifier()
|
||||
}).join('\n')
|
||||
|
||||
if(writeBuffer) {
|
||||
@ -307,14 +306,11 @@ class ProcessBuilder {
|
||||
}
|
||||
|
||||
_processAutoConnectArg(args){
|
||||
if(ConfigManager.getAutoConnect() && this.server.isAutoConnect()){
|
||||
const serverURL = new URL('my://' + this.server.getAddress())
|
||||
if(ConfigManager.getAutoConnect() && this.server.rawServer.autoconnect){
|
||||
args.push('--server')
|
||||
args.push(serverURL.hostname)
|
||||
if(serverURL.port){
|
||||
args.push(this.server.hostname)
|
||||
args.push('--port')
|
||||
args.push(serverURL.port)
|
||||
}
|
||||
args.push(this.server.port)
|
||||
}
|
||||
}
|
||||
|
||||
@ -326,7 +322,7 @@ class ProcessBuilder {
|
||||
* @returns {Array.<string>} An array containing the full JVM arguments for this process.
|
||||
*/
|
||||
constructJVMArguments(mods, tempNativePath){
|
||||
if(Util.mcVersionAtLeast('1.13', this.server.getMinecraftVersion())){
|
||||
if(mcVersionAtLeast('1.13', this.server.rawServer.minecraftVersion)){
|
||||
return this._constructJVMArguments113(mods, tempNativePath)
|
||||
} else {
|
||||
return this._constructJVMArguments112(mods, tempNativePath)
|
||||
@ -354,9 +350,9 @@ class ProcessBuilder {
|
||||
args.push('-Xdock:name=HeliosLauncher')
|
||||
args.push('-Xdock:icon=' + path.join(__dirname, '..', 'images', 'minecraft.icns'))
|
||||
}
|
||||
args.push('-Xmx' + ConfigManager.getMaxRAM(this.server.getID()))
|
||||
args.push('-Xms' + ConfigManager.getMinRAM(this.server.getID()))
|
||||
args = args.concat(ConfigManager.getJVMOptions(this.server.getID()))
|
||||
args.push('-Xmx' + ConfigManager.getMaxRAM(this.server.rawServer.id))
|
||||
args.push('-Xms' + ConfigManager.getMinRAM(this.server.rawServer.id))
|
||||
args = args.concat(ConfigManager.getJVMOptions(this.server.rawServer.id))
|
||||
args.push('-Djava.library.path=' + tempNativePath)
|
||||
|
||||
// Main Java Class
|
||||
@ -405,9 +401,9 @@ class ProcessBuilder {
|
||||
args.push('-Xdock:name=HeliosLauncher')
|
||||
args.push('-Xdock:icon=' + path.join(__dirname, '..', 'images', 'minecraft.icns'))
|
||||
}
|
||||
args.push('-Xmx' + ConfigManager.getMaxRAM(this.server.getID()))
|
||||
args.push('-Xms' + ConfigManager.getMinRAM(this.server.getID()))
|
||||
args = args.concat(ConfigManager.getJVMOptions(this.server.getID()))
|
||||
args.push('-Xmx' + ConfigManager.getMaxRAM(this.server.rawServer.id))
|
||||
args.push('-Xms' + ConfigManager.getMinRAM(this.server.rawServer.id))
|
||||
args = args.concat(ConfigManager.getJVMOptions(this.server.rawServer.id))
|
||||
|
||||
// Main Java Class
|
||||
args.push(this.forgeData.mainClass)
|
||||
@ -421,7 +417,7 @@ class ProcessBuilder {
|
||||
let checksum = 0
|
||||
for(let rule of args[i].rules){
|
||||
if(rule.os != null){
|
||||
if(rule.os.name === Library.mojangFriendlyOS()
|
||||
if(rule.os.name === getMojangOS()
|
||||
&& (rule.os.version == null || new RegExp(rule.os.version).test(os.release))){
|
||||
if(rule.action === 'allow'){
|
||||
checksum++
|
||||
@ -471,7 +467,7 @@ class ProcessBuilder {
|
||||
break
|
||||
case 'version_name':
|
||||
//val = versionData.id
|
||||
val = this.server.getID()
|
||||
val = this.server.rawServer.id
|
||||
break
|
||||
case 'game_directory':
|
||||
val = this.gameDir
|
||||
@ -523,7 +519,7 @@ class ProcessBuilder {
|
||||
// Autoconnect
|
||||
let isAutoconnectBroken
|
||||
try {
|
||||
isAutoconnectBroken = Util.isAutoconnectBroken(this.forgeData.id.split('-')[2])
|
||||
isAutoconnectBroken = ProcessBuilder.isAutoconnectBroken(this.forgeData.id.split('-')[2])
|
||||
} catch(err) {
|
||||
logger.error(err)
|
||||
logger.error('Forge version format changed.. assuming autoconnect works.')
|
||||
@ -569,7 +565,7 @@ class ProcessBuilder {
|
||||
break
|
||||
case 'version_name':
|
||||
//val = versionData.id
|
||||
val = this.server.getID()
|
||||
val = this.server.rawServer.id
|
||||
break
|
||||
case 'game_directory':
|
||||
val = this.gameDir
|
||||
@ -668,7 +664,7 @@ class ProcessBuilder {
|
||||
classpathArg(mods, tempNativePath){
|
||||
let cpArgs = []
|
||||
|
||||
if(!Util.mcVersionAtLeast('1.17', this.server.getMinecraftVersion())) {
|
||||
if(!mcVersionAtLeast('1.17', this.server.rawServer.minecraftVersion)) {
|
||||
// Add the version.jar to the classpath.
|
||||
// Must not be added to the classpath for Forge 1.17+.
|
||||
const version = this.versionData.id
|
||||
@ -714,13 +710,13 @@ class ProcessBuilder {
|
||||
fs.ensureDirSync(tempNativePath)
|
||||
for(let i=0; i<libArr.length; i++){
|
||||
const lib = libArr[i]
|
||||
if(Library.validateRules(lib.rules, lib.natives)){
|
||||
if(isLibraryCompatible(lib.rules, lib.natives)){
|
||||
|
||||
// Pre-1.19 has a natives object.
|
||||
if(lib.natives != null) {
|
||||
// Extract the native library.
|
||||
const exclusionArr = lib.extract != null ? lib.extract.exclude : ['META-INF/']
|
||||
const artifact = lib.downloads.classifiers[lib.natives[Library.mojangFriendlyOS()].replace('${arch}', process.arch.replace('x', ''))]
|
||||
const artifact = lib.downloads.classifiers[lib.natives[getMojangOS()].replace('${arch}', process.arch.replace('x', ''))]
|
||||
|
||||
// Location of native zip.
|
||||
const to = path.join(this.libPath, artifact.path)
|
||||
@ -826,15 +822,15 @@ class ProcessBuilder {
|
||||
* @returns {{[id: string]: string}} An object containing the paths of each library this server requires.
|
||||
*/
|
||||
_resolveServerLibraries(mods){
|
||||
const mdls = this.server.getModules()
|
||||
const mdls = this.server.modules
|
||||
let libs = {}
|
||||
|
||||
// Locate Forge/Libraries
|
||||
for(let mdl of mdls){
|
||||
const type = mdl.getType()
|
||||
if(type === DistroManager.Types.ForgeHosted || type === DistroManager.Types.Library){
|
||||
libs[mdl.getVersionlessID()] = mdl.getArtifact().getPath()
|
||||
if(mdl.hasSubModules()){
|
||||
const type = mdl.rawModule.type
|
||||
if(type === Type.ForgeHosted || type === Type.Library){
|
||||
libs[mdl.getVersionlessMavenIdentifier()] = mdl.getPath()
|
||||
if(mdl.subModules.length > 0){
|
||||
const res = this._resolveModuleLibraries(mdl)
|
||||
if(res.length > 0){
|
||||
libs = {...libs, ...res}
|
||||
@ -863,20 +859,20 @@ class ProcessBuilder {
|
||||
* @returns {Array.<string>} An array containing the paths of each library this module requires.
|
||||
*/
|
||||
_resolveModuleLibraries(mdl){
|
||||
if(!mdl.hasSubModules()){
|
||||
if(!mdl.subModules.length > 0){
|
||||
return []
|
||||
}
|
||||
let libs = []
|
||||
for(let sm of mdl.getSubModules()){
|
||||
if(sm.getType() === DistroManager.Types.Library){
|
||||
for(let sm of mdl.subModules){
|
||||
if(sm.rawModule.type === Type.Library){
|
||||
|
||||
if(sm.getClasspath()) {
|
||||
libs.push(sm.getArtifact().getPath())
|
||||
if(sm.rawModule.classpath ?? true) {
|
||||
libs.push(sm.getPath())
|
||||
}
|
||||
}
|
||||
// If this module has submodules, we need to resolve the libraries for those.
|
||||
// To avoid unnecessary recursive calls, base case is checked here.
|
||||
if(mdl.hasSubModules()){
|
||||
if(mdl.subModules.length > 0){
|
||||
const res = this._resolveModuleLibraries(sm)
|
||||
if(res.length > 0){
|
||||
libs = libs.concat(res)
|
||||
@ -886,6 +882,24 @@ class ProcessBuilder {
|
||||
return libs
|
||||
}
|
||||
|
||||
static isAutoconnectBroken(forgeVersion) {
|
||||
|
||||
const minWorking = [31, 2, 15]
|
||||
const verSplit = forgeVersion.split('.').map(v => Number(v))
|
||||
|
||||
if(verSplit[0] === 31) {
|
||||
for(let i=0; i<minWorking.length; i++) {
|
||||
if(verSplit[i] > minWorking[i]) {
|
||||
return false
|
||||
} else if(verSplit[i] < minWorking[i]) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = ProcessBuilder
|
@ -5,14 +5,33 @@
|
||||
const cp = require('child_process')
|
||||
const crypto = require('crypto')
|
||||
const { URL } = require('url')
|
||||
const { MojangRestAPI, getServerStatus } = require('helios-core/mojang')
|
||||
const {
|
||||
MojangRestAPI,
|
||||
getServerStatus
|
||||
} = require('helios-core/mojang')
|
||||
const {
|
||||
RestResponseStatus,
|
||||
isDisplayableError,
|
||||
validateLocalFile
|
||||
} = require('helios-core/common')
|
||||
const {
|
||||
FullRepair,
|
||||
DistributionIndexProcessor,
|
||||
MojangIndexProcessor,
|
||||
downloadFile
|
||||
} = require('helios-core/dl')
|
||||
const {
|
||||
validateSelectedJvm,
|
||||
ensureJavaDirIsRoot,
|
||||
javaExecFromRoot,
|
||||
discoverBestJvmInstallation,
|
||||
latestOpenJDK,
|
||||
extractJdk
|
||||
} = require('helios-core/java')
|
||||
|
||||
// Internal Requirements
|
||||
const DiscordWrapper = require('./assets/js/discordwrapper')
|
||||
const ProcessBuilder = require('./assets/js/processbuilder')
|
||||
const { Util } = require('./assets/js/assetguard')
|
||||
const { RestResponseStatus, isDisplayableError } = require('helios-core/common')
|
||||
const { stdout } = require('process')
|
||||
|
||||
// Launch Elements
|
||||
const launch_content = document.getElementById('launch_content')
|
||||
@ -54,26 +73,22 @@ function setLaunchDetails(details){
|
||||
/**
|
||||
* Set the value of the loading progress bar and display that value.
|
||||
*
|
||||
* @param {number} value The progress value.
|
||||
* @param {number} max The total size.
|
||||
* @param {number|string} percent Optional. The percentage to display on the progress label.
|
||||
* @param {number} percent Percentage (0-100)
|
||||
*/
|
||||
function setLaunchPercentage(value, max, percent = ((value/max)*100)){
|
||||
launch_progress.setAttribute('max', max)
|
||||
launch_progress.setAttribute('value', value)
|
||||
function setLaunchPercentage(percent){
|
||||
launch_progress.setAttribute('max', 100)
|
||||
launch_progress.setAttribute('value', percent)
|
||||
launch_progress_label.innerHTML = percent + '%'
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of the OS progress bar and display that on the UI.
|
||||
*
|
||||
* @param {number} value The progress value.
|
||||
* @param {number} max The total download size.
|
||||
* @param {number|string} percent Optional. The percentage to display on the progress label.
|
||||
* @param {number} percent Percentage (0-100)
|
||||
*/
|
||||
function setDownloadPercentage(value, max, percent = ((value/max)*100)){
|
||||
remote.getCurrentWindow().setProgressBar(value/max)
|
||||
setLaunchPercentage(value, max, percent)
|
||||
function setDownloadPercentage(percent){
|
||||
remote.getCurrentWindow().setProgressBar(percent/100)
|
||||
setLaunchPercentage(percent)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -86,39 +101,43 @@ function setLaunchEnabled(val){
|
||||
}
|
||||
|
||||
// Bind launch button
|
||||
document.getElementById('launch_button').addEventListener('click', function(e){
|
||||
document.getElementById('launch_button').addEventListener('click', async e => {
|
||||
loggerLanding.info('Launching game..')
|
||||
const mcVersion = DistroManager.getDistribution().getServer(ConfigManager.getSelectedServer()).getMinecraftVersion()
|
||||
try {
|
||||
const server = (await DistroAPI.getDistribution()).getServerById(ConfigManager.getSelectedServer())
|
||||
const jExe = ConfigManager.getJavaExecutable(ConfigManager.getSelectedServer())
|
||||
if(jExe == null){
|
||||
asyncSystemScan(mcVersion)
|
||||
await asyncSystemScan(server.effectiveJavaOptions)
|
||||
} else {
|
||||
|
||||
setLaunchDetails(Lang.queryJS('landing.launch.pleaseWait'))
|
||||
toggleLaunchArea(true)
|
||||
setLaunchPercentage(0, 100)
|
||||
|
||||
const jg = new JavaGuard(mcVersion)
|
||||
jg._validateJavaBinary(jExe).then((v) => {
|
||||
loggerLanding.info('Java version meta', v)
|
||||
if(v.valid){
|
||||
dlAsync()
|
||||
const details = await validateSelectedJvm(ensureJavaDirIsRoot(jExe), server.effectiveJavaOptions.supported)
|
||||
if(details != null){
|
||||
loggerLanding.info('Jvm Details', details)
|
||||
await dlAsync()
|
||||
|
||||
} else {
|
||||
asyncSystemScan(mcVersion)
|
||||
await asyncSystemScan(server.effectiveJavaOptions)
|
||||
}
|
||||
})
|
||||
}
|
||||
} catch(err) {
|
||||
loggerLanding.error('Unhandled error in during launch process.', err)
|
||||
showLaunchFailure('Error During Launch', 'See console (CTRL + Shift + i) for more details.')
|
||||
}
|
||||
})
|
||||
|
||||
// Bind settings button
|
||||
document.getElementById('settingsMediaButton').onclick = (e) => {
|
||||
prepareSettings()
|
||||
document.getElementById('settingsMediaButton').onclick = async e => {
|
||||
await prepareSettings()
|
||||
switchView(getCurrentView(), VIEWS.settings)
|
||||
}
|
||||
|
||||
// Bind avatar overlay button.
|
||||
document.getElementById('avatarOverlay').onclick = (e) => {
|
||||
prepareSettings()
|
||||
document.getElementById('avatarOverlay').onclick = async e => {
|
||||
await prepareSettings()
|
||||
switchView(getCurrentView(), VIEWS.settings, 500, 500, () => {
|
||||
settingsNavItemListener(document.getElementById('settingsNavAccount'), false)
|
||||
})
|
||||
@ -144,9 +163,9 @@ function updateSelectedServer(serv){
|
||||
if(getCurrentView() === VIEWS.settings){
|
||||
fullSettingsSave()
|
||||
}
|
||||
ConfigManager.setSelectedServer(serv != null ? serv.getID() : null)
|
||||
ConfigManager.setSelectedServer(serv != null ? serv.rawServer.id : null)
|
||||
ConfigManager.save()
|
||||
server_selection_button.innerHTML = '\u2022 ' + (serv != null ? serv.getName() : 'No Server Selected')
|
||||
server_selection_button.innerHTML = '\u2022 ' + (serv != null ? serv.rawServer.name : 'No Server Selected')
|
||||
if(getCurrentView() === VIEWS.settings){
|
||||
animateSettingsTabRefresh()
|
||||
}
|
||||
@ -154,9 +173,9 @@ function updateSelectedServer(serv){
|
||||
}
|
||||
// Real text is set in uibinder.js on distributionIndexDone.
|
||||
server_selection_button.innerHTML = '\u2022 Loading..'
|
||||
server_selection_button.onclick = (e) => {
|
||||
server_selection_button.onclick = async e => {
|
||||
e.target.blur()
|
||||
toggleServerSelection(true)
|
||||
await toggleServerSelection(true)
|
||||
}
|
||||
|
||||
// Update Mojang Status Color
|
||||
@ -220,17 +239,16 @@ const refreshMojangStatuses = async function(){
|
||||
document.getElementById('mojang_status_icon').style.color = MojangRestAPI.statusToHex(status)
|
||||
}
|
||||
|
||||
const refreshServerStatus = async function(fade = false){
|
||||
const refreshServerStatus = async (fade = false) => {
|
||||
loggerLanding.info('Refreshing Server Status')
|
||||
const serv = DistroManager.getDistribution().getServer(ConfigManager.getSelectedServer())
|
||||
const serv = (await DistroAPI.getDistribution()).getServerById(ConfigManager.getSelectedServer())
|
||||
|
||||
let pLabel = 'SERVER'
|
||||
let pVal = 'OFFLINE'
|
||||
|
||||
try {
|
||||
const serverURL = new URL('my://' + serv.getAddress())
|
||||
|
||||
const servStat = await getServerStatus(47, serverURL.hostname, Number(serverURL.port))
|
||||
const servStat = await getServerStatus(47, serv.hostname, serv.port)
|
||||
console.log(servStat)
|
||||
pLabel = 'PLAYERS'
|
||||
pVal = servStat.players.online + '/' + servStat.players.max
|
||||
@ -279,71 +297,48 @@ function showLaunchFailure(title, desc){
|
||||
|
||||
/* System (Java) Scan */
|
||||
|
||||
let sysAEx
|
||||
let scanAt
|
||||
|
||||
let extractListener
|
||||
|
||||
/**
|
||||
* Asynchronously scan the system for valid Java installations.
|
||||
*
|
||||
* @param {string} mcVersion The Minecraft version we are scanning for.
|
||||
* @param {boolean} launchAfter Whether we should begin to launch after scanning.
|
||||
*/
|
||||
function asyncSystemScan(mcVersion, launchAfter = true){
|
||||
async function asyncSystemScan(effectiveJavaOptions, launchAfter = true){
|
||||
|
||||
setLaunchDetails('Please wait..')
|
||||
setLaunchDetails('Checking system info..')
|
||||
toggleLaunchArea(true)
|
||||
setLaunchPercentage(0, 100)
|
||||
|
||||
const forkEnv = JSON.parse(JSON.stringify(process.env))
|
||||
forkEnv.CONFIG_DIRECT_PATH = ConfigManager.getLauncherDirectory()
|
||||
const jvmDetails = await discoverBestJvmInstallation(
|
||||
ConfigManager.getDataDirectory(),
|
||||
effectiveJavaOptions.supported
|
||||
)
|
||||
|
||||
// Fork a process to run validations.
|
||||
sysAEx = cp.fork(path.join(__dirname, 'assets', 'js', 'assetexec.js'), [
|
||||
'JavaGuard',
|
||||
mcVersion
|
||||
], {
|
||||
env: forkEnv,
|
||||
stdio: 'pipe'
|
||||
})
|
||||
// Stdout
|
||||
sysAEx.stdio[1].setEncoding('utf8')
|
||||
sysAEx.stdio[1].on('data', (data) => {
|
||||
console.log(`\x1b[32m[SysAEx]\x1b[0m ${data}`)
|
||||
})
|
||||
// Stderr
|
||||
sysAEx.stdio[2].setEncoding('utf8')
|
||||
sysAEx.stdio[2].on('data', (data) => {
|
||||
console.log(`\x1b[31m[SysAEx]\x1b[0m ${data}`)
|
||||
})
|
||||
|
||||
const javaVer = Util.mcVersionAtLeast('1.17', mcVersion) ? '17' : '8'
|
||||
|
||||
sysAEx.on('message', (m) => {
|
||||
|
||||
if(m.context === 'validateJava'){
|
||||
if(m.result == null){
|
||||
if(jvmDetails == null) {
|
||||
// If the result is null, no valid Java installation was found.
|
||||
// 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 ${javaVer}. Would you like us to install a copy?`,
|
||||
`In order to join WesterosCraft, you need a 64-bit installation of Java ${effectiveJavaOptions.suggestedMajor}. Would you like us to install a copy?`,
|
||||
'Install Java',
|
||||
'Install Manually'
|
||||
)
|
||||
setOverlayHandler(() => {
|
||||
setLaunchDetails('Preparing Java Download..')
|
||||
sysAEx.send({task: 'changeContext', class: 'AssetGuard', args: [ConfigManager.getCommonDirectory(),ConfigManager.getJavaExecutable(ConfigManager.getSelectedServer())]})
|
||||
sysAEx.send({task: 'execute', function: '_enqueueOpenJDK', argsArr: [ConfigManager.getDataDirectory(), mcVersion]})
|
||||
toggleOverlay(false)
|
||||
|
||||
try {
|
||||
downloadJava(effectiveJavaOptions, launchAfter)
|
||||
} catch(err) {
|
||||
loggerLanding.error('Unhandled error in Java Download', err)
|
||||
showLaunchFailure('Error During Java Download', 'See console (CTRL + Shift + i) for more details.')
|
||||
}
|
||||
})
|
||||
setDismissHandler(() => {
|
||||
$('#overlayContent').fadeOut(250, () => {
|
||||
//$('#overlayDismiss').toggle(false)
|
||||
setOverlayContent(
|
||||
'Java is Required<br>to Launch',
|
||||
`A valid x64 installation of Java ${javaVer} is required to launch.<br><br>Please refer to our <a href="https://github.com/dscalzi/HeliosLauncher/wiki/Java-Management#manually-installing-a-valid-version-of-java">Java Management Guide</a> for instructions on how to manually install Java.`,
|
||||
`A valid x64 installation of Java ${effectiveJavaOptions.suggestedMajor} is required to launch.<br><br>Please refer to our <a href="https://github.com/dscalzi/HeliosLauncher/wiki/Java-Management#manually-installing-a-valid-version-of-java">Java Management Guide</a> for instructions on how to manually install Java.`,
|
||||
'I Understand',
|
||||
'Go Back'
|
||||
)
|
||||
@ -353,75 +348,71 @@ function asyncSystemScan(mcVersion, launchAfter = true){
|
||||
})
|
||||
setDismissHandler(() => {
|
||||
toggleOverlay(false, true)
|
||||
asyncSystemScan()
|
||||
|
||||
asyncSystemScan(effectiveJavaOptions, launchAfter)
|
||||
})
|
||||
$('#overlayContent').fadeIn(250)
|
||||
})
|
||||
})
|
||||
toggleOverlay(true, true)
|
||||
|
||||
} else {
|
||||
// Java installation found, use this to launch the game.
|
||||
ConfigManager.setJavaExecutable(ConfigManager.getSelectedServer(), m.result)
|
||||
const javaExec = javaExecFromRoot(jvmDetails.path)
|
||||
ConfigManager.setJavaExecutable(ConfigManager.getSelectedServer(), javaExec)
|
||||
ConfigManager.save()
|
||||
|
||||
// We need to make sure that the updated value is on the settings UI.
|
||||
// Just incase the settings UI is already open.
|
||||
settingsJavaExecVal.value = m.result
|
||||
populateJavaExecDetails(settingsJavaExecVal.value)
|
||||
settingsJavaExecVal.value = javaExec
|
||||
await populateJavaExecDetails(settingsJavaExecVal.value)
|
||||
|
||||
// TODO Callback hell, refactor
|
||||
// TODO Move this out, separate concerns.
|
||||
if(launchAfter){
|
||||
dlAsync()
|
||||
await dlAsync()
|
||||
}
|
||||
sysAEx.disconnect()
|
||||
}
|
||||
} else if(m.context === '_enqueueOpenJDK'){
|
||||
|
||||
if(m.result === true){
|
||||
}
|
||||
|
||||
// Oracle JRE enqueued successfully, begin download.
|
||||
setLaunchDetails('Downloading Java..')
|
||||
sysAEx.send({task: 'execute', function: 'processDlQueues', argsArr: [[{id:'java', limit:1}]]})
|
||||
async function downloadJava(effectiveJavaOptions, launchAfter = true) {
|
||||
|
||||
} else {
|
||||
// TODO Error handling.
|
||||
// asset can be null.
|
||||
const asset = await latestOpenJDK(
|
||||
effectiveJavaOptions.suggestedMajor,
|
||||
ConfigManager.getDataDirectory(),
|
||||
effectiveJavaOptions.distribution)
|
||||
|
||||
// Oracle JRE enqueue failed. Probably due to a change in their website format.
|
||||
// User will have to follow the guide to install Java.
|
||||
setOverlayContent(
|
||||
'Unexpected Issue:<br>Java Download Failed',
|
||||
'Unfortunately we\'ve encountered an issue while attempting to install Java. You will need to manually install a copy. Please check out our <a href="https://github.com/dscalzi/HeliosLauncher/wiki">Troubleshooting Guide</a> for more details and instructions.',
|
||||
'I Understand'
|
||||
)
|
||||
setOverlayHandler(() => {
|
||||
toggleOverlay(false)
|
||||
toggleLaunchArea(false)
|
||||
if(asset == null) {
|
||||
throw new Error('Failed to find OpenJDK distribution.')
|
||||
}
|
||||
|
||||
let received = 0
|
||||
await downloadFile(asset.url, asset.path, ({ transferred }) => {
|
||||
received = transferred
|
||||
setDownloadPercentage(Math.trunc((transferred/asset.size)*100))
|
||||
})
|
||||
toggleOverlay(true)
|
||||
sysAEx.disconnect()
|
||||
setDownloadPercentage(100)
|
||||
|
||||
if(received != asset.size) {
|
||||
loggerLanding.warn(`Java Download: Expected ${asset.size} bytes but received ${received}`)
|
||||
if(!await validateLocalFile(asset.path, asset.algo, asset.hash)) {
|
||||
log.error(`Hashes do not match, ${asset.id} may be corrupted.`)
|
||||
// Don't know how this could happen, but report it.
|
||||
throw new Error('Downloaded JDK has bad hash, file may be corrupted.')
|
||||
}
|
||||
}
|
||||
|
||||
} else if(m.context === 'progress'){
|
||||
|
||||
switch(m.data){
|
||||
case 'download':
|
||||
// Downloading..
|
||||
setDownloadPercentage(m.value, m.total, m.percent)
|
||||
break
|
||||
}
|
||||
|
||||
} else if(m.context === 'complete'){
|
||||
|
||||
switch(m.data){
|
||||
case 'download': {
|
||||
// Extract
|
||||
// Show installing progress bar.
|
||||
remote.getCurrentWindow().setProgressBar(2)
|
||||
|
||||
// Wait for extration to complete.
|
||||
const eLStr = 'Extracting'
|
||||
const eLStr = 'Extracting Java'
|
||||
let dotStr = ''
|
||||
setLaunchDetails(eLStr)
|
||||
extractListener = setInterval(() => {
|
||||
const extractListener = setInterval(() => {
|
||||
if(dotStr.length >= 3){
|
||||
dotStr = ''
|
||||
} else {
|
||||
@ -429,39 +420,22 @@ function asyncSystemScan(mcVersion, launchAfter = true){
|
||||
}
|
||||
setLaunchDetails(eLStr + dotStr)
|
||||
}, 750)
|
||||
break
|
||||
}
|
||||
case 'java':
|
||||
// Download & extraction complete, remove the loading from the OS progress bar.
|
||||
|
||||
const newJavaExec = await extractJdk(asset.path)
|
||||
|
||||
// Extraction complete, remove the loading from the OS progress bar.
|
||||
remote.getCurrentWindow().setProgressBar(-1)
|
||||
|
||||
// Extraction completed successfully.
|
||||
ConfigManager.setJavaExecutable(ConfigManager.getSelectedServer(), m.args[0])
|
||||
ConfigManager.setJavaExecutable(ConfigManager.getSelectedServer(), newJavaExec)
|
||||
ConfigManager.save()
|
||||
|
||||
if(extractListener != null){
|
||||
clearInterval(extractListener)
|
||||
extractListener = null
|
||||
}
|
||||
|
||||
setLaunchDetails('Java Installed!')
|
||||
|
||||
if(launchAfter){
|
||||
dlAsync()
|
||||
}
|
||||
|
||||
sysAEx.disconnect()
|
||||
break
|
||||
}
|
||||
|
||||
} else if(m.context === 'error'){
|
||||
console.log(m.error)
|
||||
}
|
||||
})
|
||||
|
||||
// Begin system Java scan.
|
||||
setLaunchDetails('Checking system info..')
|
||||
sysAEx.send({task: 'execute', function: 'validateJava', argsArr: [ConfigManager.getDataDirectory()]})
|
||||
// TODO Callback hell
|
||||
// Refactor the launch functions
|
||||
asyncSystemScan(effectiveJavaOptions, launchAfter)
|
||||
|
||||
}
|
||||
|
||||
@ -475,18 +449,28 @@ const GAME_JOINED_REGEX = /\[.+\]: Sound engine started/
|
||||
const GAME_LAUNCH_REGEX = /^\[.+\]: (?:MinecraftForge .+ Initialized|ModLauncher .+ starting: .+)$/
|
||||
const MIN_LINGER = 5000
|
||||
|
||||
let aEx
|
||||
let serv
|
||||
let versionData
|
||||
let forgeData
|
||||
|
||||
let progressListener
|
||||
|
||||
function dlAsync(login = true){
|
||||
async function dlAsync(login = true) {
|
||||
|
||||
// Login parameter is temporary for debug purposes. Allows testing the validation/downloads without
|
||||
// launching the game.
|
||||
|
||||
const loggerLaunchSuite = LoggerUtil.getLogger('LaunchSuite')
|
||||
|
||||
setLaunchDetails('Loading server information..')
|
||||
|
||||
let distro
|
||||
|
||||
try {
|
||||
distro = await DistroAPI.refreshDistributionOrFallback()
|
||||
onDistroRefresh(distro)
|
||||
} catch(err) {
|
||||
loggerLaunchSuite.error('Unable to refresh distribution index.', err)
|
||||
showLaunchFailure('Fatal Error', 'Could not load a copy of the distribution index. See the console (CTRL + Shift + i) for more details.')
|
||||
return
|
||||
}
|
||||
|
||||
const serv = distro.getServerById(ConfigManager.getSelectedServer())
|
||||
|
||||
if(login) {
|
||||
if(ConfigManager.getSelectedAccount() == null){
|
||||
loggerLanding.error('You must be logged into an account.')
|
||||
@ -498,155 +482,80 @@ function dlAsync(login = true){
|
||||
toggleLaunchArea(true)
|
||||
setLaunchPercentage(0, 100)
|
||||
|
||||
const loggerLaunchSuite = LoggerUtil.getLogger('LaunchSuite')
|
||||
|
||||
const forkEnv = JSON.parse(JSON.stringify(process.env))
|
||||
forkEnv.CONFIG_DIRECT_PATH = ConfigManager.getLauncherDirectory()
|
||||
|
||||
// Start AssetExec to run validations and downloads in a forked process.
|
||||
aEx = cp.fork(path.join(__dirname, 'assets', 'js', 'assetexec.js'), [
|
||||
'AssetGuard',
|
||||
const fullRepairModule = new FullRepair(
|
||||
ConfigManager.getCommonDirectory(),
|
||||
ConfigManager.getJavaExecutable(ConfigManager.getSelectedServer())
|
||||
], {
|
||||
env: forkEnv,
|
||||
stdio: 'pipe'
|
||||
})
|
||||
// Stdout
|
||||
aEx.stdio[1].setEncoding('utf8')
|
||||
aEx.stdio[1].on('data', (data) => {
|
||||
console.log(`\x1b[32m[AEx]\x1b[0m ${data}`)
|
||||
})
|
||||
// Stderr
|
||||
aEx.stdio[2].setEncoding('utf8')
|
||||
aEx.stdio[2].on('data', (data) => {
|
||||
console.log(`\x1b[31m[AEx]\x1b[0m ${data}`)
|
||||
})
|
||||
aEx.on('error', (err) => {
|
||||
ConfigManager.getInstanceDirectory(),
|
||||
ConfigManager.getLauncherDirectory(),
|
||||
ConfigManager.getSelectedServer(),
|
||||
DistroAPI.isDevMode()
|
||||
)
|
||||
|
||||
fullRepairModule.spawnReceiver()
|
||||
|
||||
fullRepairModule.childProcess.on('error', (err) => {
|
||||
loggerLaunchSuite.error('Error during launch', err)
|
||||
showLaunchFailure('Error During Launch', err.message || 'See console (CTRL + Shift + i) for more details.')
|
||||
})
|
||||
aEx.on('close', (code, signal) => {
|
||||
fullRepairModule.childProcess.on('close', (code, _signal) => {
|
||||
if(code !== 0){
|
||||
loggerLaunchSuite.error(`AssetExec exited with code ${code}, assuming error.`)
|
||||
loggerLaunchSuite.error(`Full Repair Module exited with code ${code}, assuming error.`)
|
||||
showLaunchFailure('Error During Launch', 'See console (CTRL + Shift + i) for more details.')
|
||||
}
|
||||
})
|
||||
|
||||
// Establish communications between the AssetExec and current process.
|
||||
aEx.on('message', (m) => {
|
||||
loggerLaunchSuite.info('Validating files.')
|
||||
setLaunchDetails('Validating file integrity..')
|
||||
let invalidFileCount = 0
|
||||
try {
|
||||
invalidFileCount = await fullRepairModule.verifyFiles(percent => {
|
||||
setLaunchPercentage(percent)
|
||||
})
|
||||
setLaunchPercentage(100)
|
||||
} catch (err) {
|
||||
loggerLaunchSuite.error('Error during file validation.')
|
||||
showLaunchFailure('Error During File Verification', err.displayable || 'See console (CTRL + Shift + i) for more details.')
|
||||
return
|
||||
}
|
||||
|
||||
if(m.context === 'validate'){
|
||||
switch(m.data){
|
||||
case 'distribution':
|
||||
setLaunchPercentage(20, 100)
|
||||
loggerLaunchSuite.info('Validated distibution index.')
|
||||
setLaunchDetails('Loading version information..')
|
||||
break
|
||||
case 'version':
|
||||
setLaunchPercentage(40, 100)
|
||||
loggerLaunchSuite.info('Version data loaded.')
|
||||
setLaunchDetails('Validating asset integrity..')
|
||||
break
|
||||
case 'assets':
|
||||
setLaunchPercentage(60, 100)
|
||||
loggerLaunchSuite.info('Asset Validation Complete')
|
||||
setLaunchDetails('Validating library integrity..')
|
||||
break
|
||||
case 'libraries':
|
||||
setLaunchPercentage(80, 100)
|
||||
loggerLaunchSuite.info('Library validation complete.')
|
||||
setLaunchDetails('Validating miscellaneous file integrity..')
|
||||
break
|
||||
case 'files':
|
||||
setLaunchPercentage(100, 100)
|
||||
loggerLaunchSuite.info('File validation complete.')
|
||||
|
||||
if(invalidFileCount > 0) {
|
||||
loggerLaunchSuite.info('Downloading files.')
|
||||
setLaunchDetails('Downloading files..')
|
||||
break
|
||||
setLaunchPercentage(0)
|
||||
try {
|
||||
await fullRepairModule.download(percent => {
|
||||
setDownloadPercentage(percent)
|
||||
})
|
||||
setDownloadPercentage(100)
|
||||
} catch(err) {
|
||||
loggerLaunchSuite.error('Error during file download.')
|
||||
showLaunchFailure('Error During File Download', err.displayable || 'See console (CTRL + Shift + i) for more details.')
|
||||
return
|
||||
}
|
||||
} else if(m.context === 'progress'){
|
||||
switch(m.data){
|
||||
case 'assets': {
|
||||
const perc = (m.value/m.total)*20
|
||||
setLaunchPercentage(40+perc, 100, parseInt(40+perc))
|
||||
break
|
||||
}
|
||||
case 'download':
|
||||
setDownloadPercentage(m.value, m.total, m.percent)
|
||||
break
|
||||
case 'extract': {
|
||||
// Show installing progress bar.
|
||||
remote.getCurrentWindow().setProgressBar(2)
|
||||
|
||||
// Download done, extracting.
|
||||
const eLStr = 'Extracting libraries'
|
||||
let dotStr = ''
|
||||
setLaunchDetails(eLStr)
|
||||
progressListener = setInterval(() => {
|
||||
if(dotStr.length >= 3){
|
||||
dotStr = ''
|
||||
} else {
|
||||
dotStr += '.'
|
||||
loggerLaunchSuite.info('No invalid files, skipping download.')
|
||||
}
|
||||
setLaunchDetails(eLStr + dotStr)
|
||||
}, 750)
|
||||
break
|
||||
}
|
||||
}
|
||||
} else if(m.context === 'complete'){
|
||||
switch(m.data){
|
||||
case 'download':
|
||||
// Download and extraction complete, remove the loading from the OS progress bar.
|
||||
|
||||
// Remove download bar.
|
||||
remote.getCurrentWindow().setProgressBar(-1)
|
||||
if(progressListener != null){
|
||||
clearInterval(progressListener)
|
||||
progressListener = null
|
||||
}
|
||||
|
||||
fullRepairModule.destroyReceiver()
|
||||
|
||||
setLaunchDetails('Preparing to launch..')
|
||||
break
|
||||
}
|
||||
} else if(m.context === 'error'){
|
||||
switch(m.data){
|
||||
case 'download':
|
||||
loggerLaunchSuite.error('Error while downloading:', m.error)
|
||||
|
||||
if(m.error.code === 'ENOENT'){
|
||||
showLaunchFailure(
|
||||
'Download Error',
|
||||
'Could not connect to the file server. Ensure that you are connected to the internet and try again.'
|
||||
const mojangIndexProcessor = new MojangIndexProcessor(
|
||||
ConfigManager.getCommonDirectory(),
|
||||
serv.rawServer.minecraftVersion)
|
||||
const distributionIndexProcessor = new DistributionIndexProcessor(
|
||||
ConfigManager.getCommonDirectory(),
|
||||
distro,
|
||||
serv.rawServer.id
|
||||
)
|
||||
} else {
|
||||
showLaunchFailure(
|
||||
'Download Error',
|
||||
'Check the console (CTRL + Shift + i) for more details. Please try again.'
|
||||
)
|
||||
}
|
||||
|
||||
remote.getCurrentWindow().setProgressBar(-1)
|
||||
const forgeData = await distributionIndexProcessor.loadForgeVersionJson(serv)
|
||||
const versionData = await mojangIndexProcessor.getVersionJson()
|
||||
|
||||
// Disconnect from AssetExec
|
||||
aEx.disconnect()
|
||||
break
|
||||
}
|
||||
} else if(m.context === 'validateEverything'){
|
||||
|
||||
let allGood = true
|
||||
|
||||
// If these properties are not defined it's likely an error.
|
||||
if(m.result.forgeData == null || m.result.versionData == null){
|
||||
loggerLaunchSuite.error('Error during validation:', m.result)
|
||||
|
||||
loggerLaunchSuite.error('Error during launch', m.result.error)
|
||||
showLaunchFailure('Error During Launch', 'Please check the console (CTRL + Shift + i) for more details.')
|
||||
|
||||
allGood = false
|
||||
}
|
||||
|
||||
forgeData = m.result.forgeData
|
||||
versionData = m.result.versionData
|
||||
|
||||
if(login && allGood) {
|
||||
if(login) {
|
||||
const authUser = ConfigManager.getSelectedAccount()
|
||||
loggerLaunchSuite.info(`Sending selected account (${authUser.displayName}) to ProcessBuilder.`)
|
||||
let pb = new ProcessBuilder(serv, versionData, forgeData, authUser, remote.app.getVersion())
|
||||
@ -659,8 +568,8 @@ function dlAsync(login = true){
|
||||
toggleLaunchArea(false)
|
||||
if(hasRPC){
|
||||
DiscordWrapper.updateDetails('Loading game..')
|
||||
}
|
||||
proc.stdout.on('data', gameStateChange)
|
||||
}
|
||||
proc.stdout.removeListener('data', tempListener)
|
||||
proc.stderr.removeListener('data', gameErrorListener)
|
||||
}
|
||||
@ -710,9 +619,8 @@ function dlAsync(login = true){
|
||||
setLaunchDetails('Done. Enjoy the server!')
|
||||
|
||||
// Init Discord Hook
|
||||
const distro = DistroManager.getDistribution()
|
||||
if(distro.discord != null && serv.discord != null){
|
||||
DiscordWrapper.initRPC(distro.discord, serv.discord)
|
||||
if(distro.rawDistribution.discord != null && serv.rawServerdiscord != null){
|
||||
DiscordWrapper.initRPC(distro.rawDistribution.discord, serv.rawServer.discord)
|
||||
hasRPC = true
|
||||
proc.on('close', (code, signal) => {
|
||||
loggerLaunchSuite.info('Shutting down Discord Rich Presence..')
|
||||
@ -730,40 +638,6 @@ function dlAsync(login = true){
|
||||
}
|
||||
}
|
||||
|
||||
// Disconnect from AssetExec
|
||||
aEx.disconnect()
|
||||
|
||||
}
|
||||
})
|
||||
|
||||
// Begin Validations
|
||||
|
||||
// Validate Forge files.
|
||||
setLaunchDetails('Loading server information..')
|
||||
|
||||
refreshDistributionIndex(true, (data) => {
|
||||
onDistroRefresh(data)
|
||||
serv = data.getServer(ConfigManager.getSelectedServer())
|
||||
aEx.send({task: 'execute', function: 'validateEverything', argsArr: [ConfigManager.getSelectedServer(), DistroManager.isDevMode()]})
|
||||
}, (err) => {
|
||||
loggerLaunchSuite.info('Error while fetching a fresh copy of the distribution index.', err)
|
||||
refreshDistributionIndex(false, (data) => {
|
||||
onDistroRefresh(data)
|
||||
serv = data.getServer(ConfigManager.getSelectedServer())
|
||||
aEx.send({task: 'execute', function: 'validateEverything', argsArr: [ConfigManager.getSelectedServer(), DistroManager.isDevMode()]})
|
||||
}, (err) => {
|
||||
loggerLaunchSuite.error('Unable to refresh distribution index.', err)
|
||||
if(DistroManager.getDistribution() == null){
|
||||
showLaunchFailure('Fatal Error', 'Could not load a copy of the distribution index. See the console (CTRL + Shift + i) for more details.')
|
||||
|
||||
// Disconnect from AssetExec
|
||||
aEx.disconnect()
|
||||
} else {
|
||||
serv = data.getServer(ConfigManager.getSelectedServer())
|
||||
aEx.send({task: 'execute', function: 'validateEverything', argsArr: [ConfigManager.getSelectedServer(), DistroManager.isDevMode()]})
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
@ -943,7 +817,7 @@ function initNews(){
|
||||
let news = {}
|
||||
loadNews().then(news => {
|
||||
|
||||
newsArr = news.articles || null
|
||||
newsArr = news?.articles || null
|
||||
|
||||
if(newsArr == null){
|
||||
// News Loading Failed
|
||||
@ -1089,10 +963,17 @@ function displayArticle(articleObject, index){
|
||||
* Load news information from the RSS feed specified in the
|
||||
* distribution index.
|
||||
*/
|
||||
function loadNews(){
|
||||
return new Promise((resolve, reject) => {
|
||||
const distroData = DistroManager.getDistribution()
|
||||
const newsFeed = distroData.getRSS()
|
||||
async function loadNews(){
|
||||
|
||||
const distroData = await DistroAPI.getDistribution()
|
||||
if(!distroData.rawDistribution.rss) {
|
||||
loggerLanding.debug('No RSS feed provided.')
|
||||
return null
|
||||
}
|
||||
|
||||
const promise = new Promise((resolve, reject) => {
|
||||
|
||||
const newsFeed = distroData.rawDistribution.rss
|
||||
const newsHost = new URL(newsFeed).origin + '/'
|
||||
$.ajax({
|
||||
url: newsFeed,
|
||||
@ -1147,4 +1028,6 @@ function loadNews(){
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
return await promise
|
||||
}
|
||||
|
@ -193,10 +193,10 @@ loginButton.addEventListener('click', () => {
|
||||
$('.circle-loader').toggleClass('load-complete')
|
||||
$('.checkmark').toggle()
|
||||
setTimeout(() => {
|
||||
switchView(VIEWS.login, loginViewOnSuccess, 500, 500, () => {
|
||||
switchView(VIEWS.login, loginViewOnSuccess, 500, 500, async () => {
|
||||
// Temporary workaround
|
||||
if(loginViewOnSuccess === VIEWS.settings){
|
||||
prepareSettings()
|
||||
await prepareSettings()
|
||||
}
|
||||
loginViewOnSuccess = VIEWS.landing // Reset this for good measure.
|
||||
loginCancelEnabled(false) // Reset this for good measure.
|
||||
|
@ -117,8 +117,8 @@ function toggleOverlay(toggleState, dismissable = false, content = 'overlayConte
|
||||
}
|
||||
}
|
||||
|
||||
function toggleServerSelection(toggleState){
|
||||
prepareServerSelectionList()
|
||||
async function toggleServerSelection(toggleState){
|
||||
await prepareServerSelectionList()
|
||||
toggleOverlay(toggleState, true, 'serverSelectContent')
|
||||
}
|
||||
|
||||
@ -171,11 +171,11 @@ function setDismissHandler(handler){
|
||||
|
||||
/* Server Select View */
|
||||
|
||||
document.getElementById('serverSelectConfirm').addEventListener('click', () => {
|
||||
document.getElementById('serverSelectConfirm').addEventListener('click', async () => {
|
||||
const listings = document.getElementsByClassName('serverListing')
|
||||
for(let i=0; i<listings.length; i++){
|
||||
if(listings[i].hasAttribute('selected')){
|
||||
const serv = DistroManager.getDistribution().getServer(listings[i].getAttribute('servid'))
|
||||
const serv = (await DistroAPI.getDistribution()).getServerById(listings[i].getAttribute('servid'))
|
||||
updateSelectedServer(serv)
|
||||
refreshServerStatus(true)
|
||||
toggleOverlay(false)
|
||||
@ -184,13 +184,13 @@ document.getElementById('serverSelectConfirm').addEventListener('click', () => {
|
||||
}
|
||||
// None are selected? Not possible right? Meh, handle it.
|
||||
if(listings.length > 0){
|
||||
const serv = DistroManager.getDistribution().getServer(listings[i].getAttribute('servid'))
|
||||
const serv = (await DistroAPI.getDistribution()).getServerById(listings[i].getAttribute('servid'))
|
||||
updateSelectedServer(serv)
|
||||
toggleOverlay(false)
|
||||
}
|
||||
})
|
||||
|
||||
document.getElementById('accountSelectConfirm').addEventListener('click', () => {
|
||||
document.getElementById('accountSelectConfirm').addEventListener('click', async () => {
|
||||
const listings = document.getElementsByClassName('accountListing')
|
||||
for(let i=0; i<listings.length; i++){
|
||||
if(listings[i].hasAttribute('selected')){
|
||||
@ -198,7 +198,7 @@ document.getElementById('accountSelectConfirm').addEventListener('click', () =>
|
||||
ConfigManager.save()
|
||||
updateSelectedAccount(authAcc)
|
||||
if(getCurrentView() === VIEWS.settings) {
|
||||
prepareSettings()
|
||||
await prepareSettings()
|
||||
}
|
||||
toggleOverlay(false)
|
||||
validateSelectedAccount()
|
||||
@ -211,7 +211,7 @@ document.getElementById('accountSelectConfirm').addEventListener('click', () =>
|
||||
ConfigManager.save()
|
||||
updateSelectedAccount(authAcc)
|
||||
if(getCurrentView() === VIEWS.settings) {
|
||||
prepareSettings()
|
||||
await prepareSettings()
|
||||
}
|
||||
toggleOverlay(false)
|
||||
validateSelectedAccount()
|
||||
@ -267,21 +267,21 @@ function setAccountListingHandlers(){
|
||||
})
|
||||
}
|
||||
|
||||
function populateServerListings(){
|
||||
const distro = DistroManager.getDistribution()
|
||||
async function populateServerListings(){
|
||||
const distro = await DistroAPI.getDistribution()
|
||||
const giaSel = ConfigManager.getSelectedServer()
|
||||
const servers = distro.getServers()
|
||||
const servers = distro.servers
|
||||
let htmlString = ''
|
||||
for(const serv of servers){
|
||||
htmlString += `<button class="serverListing" servid="${serv.getID()}" ${serv.getID() === giaSel ? 'selected' : ''}>
|
||||
<img class="serverListingImg" src="${serv.getIcon()}"/>
|
||||
htmlString += `<button class="serverListing" servid="${serv.rawServer.id}" ${serv.rawServer.id === giaSel ? 'selected' : ''}>
|
||||
<img class="serverListingImg" src="${serv.rawServer.icon}"/>
|
||||
<div class="serverListingDetails">
|
||||
<span class="serverListingName">${serv.getName()}</span>
|
||||
<span class="serverListingDescription">${serv.getDescription()}</span>
|
||||
<span class="serverListingName">${serv.rawServer.name}</span>
|
||||
<span class="serverListingDescription">${serv.rawServer.description}</span>
|
||||
<div class="serverListingInfo">
|
||||
<div class="serverListingVersion">${serv.getMinecraftVersion()}</div>
|
||||
<div class="serverListingRevision">${serv.getVersion()}</div>
|
||||
${serv.isMainServer() ? `<div class="serverListingStarWrapper">
|
||||
<div class="serverListingVersion">${serv.rawServer.minecraftVersion}</div>
|
||||
<div class="serverListingRevision">${serv.rawServer.version}</div>
|
||||
${serv.rawServer.mainServer ? `<div class="serverListingStarWrapper">
|
||||
<svg id="Layer_1" viewBox="0 0 107.45 104.74" width="20px" height="20px">
|
||||
<defs>
|
||||
<style>.cls-1{fill:#fff;}.cls-2{fill:none;stroke:#fff;stroke-miterlimit:10;}</style>
|
||||
@ -313,8 +313,8 @@ function populateAccountListings(){
|
||||
|
||||
}
|
||||
|
||||
function prepareServerSelectionList(){
|
||||
populateServerListings()
|
||||
async function prepareServerSelectionList(){
|
||||
await populateServerListings()
|
||||
setServerListingHandlers()
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,6 @@
|
||||
const os = require('os')
|
||||
const semver = require('semver')
|
||||
|
||||
const { JavaGuard } = require('./assets/js/assetguard')
|
||||
const DropinModUtil = require('./assets/js/dropinmodutil')
|
||||
const { MSFT_OPCODE, MSFT_REPLY_TYPE, MSFT_ERROR } = require('./assets/js/ipcconstants')
|
||||
|
||||
@ -69,7 +68,7 @@ function bindFileSelectors(){
|
||||
if(!res.canceled) {
|
||||
ele.previousElementSibling.value = res.filePaths[0]
|
||||
if(isJavaExecSel) {
|
||||
populateJavaExecDetails(ele.previousElementSibling.value)
|
||||
await populateJavaExecDetails(ele.previousElementSibling.value)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -123,9 +122,10 @@ function initSettingsValidators(){
|
||||
/**
|
||||
* Load configuration values onto the UI. This is an automated process.
|
||||
*/
|
||||
function initSettingsValues(){
|
||||
async function initSettingsValues(){
|
||||
const sEls = document.getElementById('settingsContainer').querySelectorAll('[cValue]')
|
||||
Array.from(sEls).map((v, index, arr) => {
|
||||
|
||||
for(const v of sEls) {
|
||||
const cVal = v.getAttribute('cValue')
|
||||
const serverDependent = v.hasAttribute('serverDependent') // Means the first argument is the server id.
|
||||
const gFn = ConfigManager['get' + cVal]
|
||||
@ -139,7 +139,7 @@ function initSettingsValues(){
|
||||
// Special Conditions
|
||||
if(cVal === 'JavaExecutable'){
|
||||
v.value = gFn.apply(null, gFnOpts)
|
||||
populateJavaExecDetails(v.value)
|
||||
await populateJavaExecDetails(v.value)
|
||||
} else if (cVal === 'DataDirectory'){
|
||||
v.value = gFn.apply(null, gFnOpts)
|
||||
} else if(cVal === 'JVMOptions'){
|
||||
@ -156,7 +156,7 @@ function initSettingsValues(){
|
||||
if(cVal === 'MinRAM' || cVal === 'MaxRAM'){
|
||||
let val = gFn.apply(null, gFnOpts)
|
||||
if(val.endsWith('M')){
|
||||
val = Number(val.substring(0, val.length-1))/1000
|
||||
val = Number(val.substring(0, val.length-1))/1024
|
||||
} else {
|
||||
val = Number.parseFloat(val)
|
||||
}
|
||||
@ -168,8 +168,8 @@ function initSettingsValues(){
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
@ -416,8 +416,8 @@ ipcRenderer.on(MSFT_OPCODE.REPLY_LOGIN, (_, ...arguments_) => {
|
||||
const authCode = queryMap.code
|
||||
AuthManager.addMicrosoftAccount(authCode).then(value => {
|
||||
updateSelectedAccount(value)
|
||||
switchView(getCurrentView(), viewOnClose, 500, 500, () => {
|
||||
prepareSettings()
|
||||
switchView(getCurrentView(), viewOnClose, 500, 500, async () => {
|
||||
await prepareSettings()
|
||||
})
|
||||
})
|
||||
.catch((displayableError) => {
|
||||
@ -713,13 +713,13 @@ const settingsModsContainer = document.getElementById('settingsModsContainer')
|
||||
/**
|
||||
* Resolve and update the mods on the UI.
|
||||
*/
|
||||
function resolveModsForUI(){
|
||||
async function resolveModsForUI(){
|
||||
const serv = ConfigManager.getSelectedServer()
|
||||
|
||||
const distro = DistroManager.getDistribution()
|
||||
const distro = await DistroAPI.getDistribution()
|
||||
const servConf = ConfigManager.getModConfiguration(serv)
|
||||
|
||||
const modStr = parseModulesForUI(distro.getServer(serv).getModules(), false, servConf.mods)
|
||||
const modStr = parseModulesForUI(distro.getServerById(serv).modules, false, servConf.mods)
|
||||
|
||||
document.getElementById('settingsReqModsContent').innerHTML = modStr.reqMods
|
||||
document.getElementById('settingsOptModsContent').innerHTML = modStr.optMods
|
||||
@ -739,17 +739,17 @@ function parseModulesForUI(mdls, submodules, servConf){
|
||||
|
||||
for(const mdl of mdls){
|
||||
|
||||
if(mdl.getType() === DistroManager.Types.ForgeMod || mdl.getType() === DistroManager.Types.LiteMod || mdl.getType() === DistroManager.Types.LiteLoader){
|
||||
if(mdl.rawModule.type === Type.ForgeMod || mdl.rawModule.type === Type.LiteMod || mdl.rawModule.type === Type.LiteLoader){
|
||||
|
||||
if(mdl.getRequired().isRequired()){
|
||||
if(mdl.getRequired().value){
|
||||
|
||||
reqMods += `<div id="${mdl.getVersionlessID()}" class="settingsBaseMod settings${submodules ? 'Sub' : ''}Mod" enabled>
|
||||
reqMods += `<div id="${mdl.getVersionlessMavenIdentifier()}" class="settingsBaseMod settings${submodules ? 'Sub' : ''}Mod" enabled>
|
||||
<div class="settingsModContent">
|
||||
<div class="settingsModMainWrapper">
|
||||
<div class="settingsModStatus"></div>
|
||||
<div class="settingsModDetails">
|
||||
<span class="settingsModName">${mdl.getName()}</span>
|
||||
<span class="settingsModVersion">v${mdl.getVersion()}</span>
|
||||
<span class="settingsModName">${mdl.rawModule.name}</span>
|
||||
<span class="settingsModVersion">v${mdl.mavenComponents.version}</span>
|
||||
</div>
|
||||
</div>
|
||||
<label class="toggleSwitch" reqmod>
|
||||
@ -757,32 +757,32 @@ function parseModulesForUI(mdls, submodules, servConf){
|
||||
<span class="toggleSwitchSlider"></span>
|
||||
</label>
|
||||
</div>
|
||||
${mdl.hasSubModules() ? `<div class="settingsSubModContainer">
|
||||
${Object.values(parseModulesForUI(mdl.getSubModules(), true, servConf[mdl.getVersionlessID()])).join('')}
|
||||
${mdl.subModules.length > 0 ? `<div class="settingsSubModContainer">
|
||||
${Object.values(parseModulesForUI(mdl.subModules, true, servConf[mdl.getVersionlessMavenIdentifier()])).join('')}
|
||||
</div>` : ''}
|
||||
</div>`
|
||||
|
||||
} else {
|
||||
|
||||
const conf = servConf[mdl.getVersionlessID()]
|
||||
const conf = servConf[mdl.getVersionlessMavenIdentifier()]
|
||||
const val = typeof conf === 'object' ? conf.value : conf
|
||||
|
||||
optMods += `<div id="${mdl.getVersionlessID()}" class="settingsBaseMod settings${submodules ? 'Sub' : ''}Mod" ${val ? 'enabled' : ''}>
|
||||
optMods += `<div id="${mdl.getVersionlessMavenIdentifier()}" class="settingsBaseMod settings${submodules ? 'Sub' : ''}Mod" ${val ? 'enabled' : ''}>
|
||||
<div class="settingsModContent">
|
||||
<div class="settingsModMainWrapper">
|
||||
<div class="settingsModStatus"></div>
|
||||
<div class="settingsModDetails">
|
||||
<span class="settingsModName">${mdl.getName()}</span>
|
||||
<span class="settingsModVersion">v${mdl.getVersion()}</span>
|
||||
<span class="settingsModName">${mdl.rawModule.name}</span>
|
||||
<span class="settingsModVersion">v${mdl.mavenComponents.version}</span>
|
||||
</div>
|
||||
</div>
|
||||
<label class="toggleSwitch">
|
||||
<input type="checkbox" formod="${mdl.getVersionlessID()}" ${val ? 'checked' : ''}>
|
||||
<input type="checkbox" formod="${mdl.getVersionlessMavenIdentifier()}" ${val ? 'checked' : ''}>
|
||||
<span class="toggleSwitchSlider"></span>
|
||||
</label>
|
||||
</div>
|
||||
${mdl.hasSubModules() ? `<div class="settingsSubModContainer">
|
||||
${Object.values(parseModulesForUI(mdl.getSubModules(), true, conf.mods)).join('')}
|
||||
${mdl.subModules.length > 0 ? `<div class="settingsSubModContainer">
|
||||
${Object.values(parseModulesForUI(mdl.subModules, true, conf.mods)).join('')}
|
||||
</div>` : ''}
|
||||
</div>`
|
||||
|
||||
@ -858,10 +858,10 @@ let CACHE_DROPIN_MODS
|
||||
* Resolve any located drop-in mods for this server and
|
||||
* populate the results onto the UI.
|
||||
*/
|
||||
function resolveDropinModsForUI(){
|
||||
const serv = DistroManager.getDistribution().getServer(ConfigManager.getSelectedServer())
|
||||
CACHE_SETTINGS_MODS_DIR = path.join(ConfigManager.getInstanceDirectory(), serv.getID(), 'mods')
|
||||
CACHE_DROPIN_MODS = DropinModUtil.scanForDropinMods(CACHE_SETTINGS_MODS_DIR, serv.getMinecraftVersion())
|
||||
async function resolveDropinModsForUI(){
|
||||
const serv = (await DistroAPI.getDistribution()).getServerById(ConfigManager.getSelectedServer())
|
||||
CACHE_SETTINGS_MODS_DIR = path.join(ConfigManager.getInstanceDirectory(), serv.rawServer.id, 'mods')
|
||||
CACHE_DROPIN_MODS = DropinModUtil.scanForDropinMods(CACHE_SETTINGS_MODS_DIR, serv.rawServer.minecraftVersion)
|
||||
|
||||
let dropinMods = ''
|
||||
|
||||
@ -934,12 +934,12 @@ function bindDropinModFileSystemButton(){
|
||||
fsBtn.removeAttribute('drag')
|
||||
}
|
||||
|
||||
fsBtn.ondrop = e => {
|
||||
fsBtn.ondrop = async e => {
|
||||
fsBtn.removeAttribute('drag')
|
||||
e.preventDefault()
|
||||
|
||||
DropinModUtil.addDropinMods(e.dataTransfer.files, CACHE_SETTINGS_MODS_DIR)
|
||||
reloadDropinMods()
|
||||
await reloadDropinMods()
|
||||
}
|
||||
}
|
||||
|
||||
@ -971,18 +971,18 @@ function saveDropinModConfiguration(){
|
||||
|
||||
// Refresh the drop-in mods when F5 is pressed.
|
||||
// Only active on the mods tab.
|
||||
document.addEventListener('keydown', (e) => {
|
||||
document.addEventListener('keydown', async (e) => {
|
||||
if(getCurrentView() === VIEWS.settings && selectedSettingsTab === 'settingsTabMods'){
|
||||
if(e.key === 'F5'){
|
||||
reloadDropinMods()
|
||||
await reloadDropinMods()
|
||||
saveShaderpackSettings()
|
||||
resolveShaderpacksForUI()
|
||||
await resolveShaderpacksForUI()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
function reloadDropinMods(){
|
||||
resolveDropinModsForUI()
|
||||
async function reloadDropinMods(){
|
||||
await resolveDropinModsForUI()
|
||||
bindDropinModsRemoveButton()
|
||||
bindDropinModFileSystemButton()
|
||||
bindModsToggleSwitch()
|
||||
@ -997,9 +997,9 @@ let CACHE_SELECTED_SHADERPACK
|
||||
/**
|
||||
* Load shaderpack information.
|
||||
*/
|
||||
function resolveShaderpacksForUI(){
|
||||
const serv = DistroManager.getDistribution().getServer(ConfigManager.getSelectedServer())
|
||||
CACHE_SETTINGS_INSTANCE_DIR = path.join(ConfigManager.getInstanceDirectory(), serv.getID())
|
||||
async function resolveShaderpacksForUI(){
|
||||
const serv = (await DistroAPI.getDistribution()).getServerById(ConfigManager.getSelectedServer())
|
||||
CACHE_SETTINGS_INSTANCE_DIR = path.join(ConfigManager.getInstanceDirectory(), serv.rawServer.id)
|
||||
CACHE_SHADERPACKS = DropinModUtil.scanForShaderpacks(CACHE_SETTINGS_INSTANCE_DIR)
|
||||
CACHE_SELECTED_SHADERPACK = DropinModUtil.getEnabledShaderpack(CACHE_SETTINGS_INSTANCE_DIR)
|
||||
|
||||
@ -1058,13 +1058,13 @@ function bindShaderpackButton() {
|
||||
spBtn.removeAttribute('drag')
|
||||
}
|
||||
|
||||
spBtn.ondrop = e => {
|
||||
spBtn.ondrop = async e => {
|
||||
spBtn.removeAttribute('drag')
|
||||
e.preventDefault()
|
||||
|
||||
DropinModUtil.addShaderpacks(e.dataTransfer.files, CACHE_SETTINGS_INSTANCE_DIR)
|
||||
saveShaderpackSettings()
|
||||
resolveShaderpacksForUI()
|
||||
await resolveShaderpacksForUI()
|
||||
}
|
||||
}
|
||||
|
||||
@ -1073,19 +1073,19 @@ function bindShaderpackButton() {
|
||||
/**
|
||||
* Load the currently selected server information onto the mods tab.
|
||||
*/
|
||||
function loadSelectedServerOnModsTab(){
|
||||
const serv = DistroManager.getDistribution().getServer(ConfigManager.getSelectedServer())
|
||||
async function loadSelectedServerOnModsTab(){
|
||||
const serv = (await DistroAPI.getDistribution()).getServerById(ConfigManager.getSelectedServer())
|
||||
|
||||
for(const el of document.getElementsByClassName('settingsSelServContent')) {
|
||||
el.innerHTML = `
|
||||
<img class="serverListingImg" src="${serv.getIcon()}"/>
|
||||
<img class="serverListingImg" src="${serv.rawServer.icon}"/>
|
||||
<div class="serverListingDetails">
|
||||
<span class="serverListingName">${serv.getName()}</span>
|
||||
<span class="serverListingDescription">${serv.getDescription()}</span>
|
||||
<span class="serverListingName">${serv.rawServer.name}</span>
|
||||
<span class="serverListingDescription">${serv.rawServer.description}</span>
|
||||
<div class="serverListingInfo">
|
||||
<div class="serverListingVersion">${serv.getMinecraftVersion()}</div>
|
||||
<div class="serverListingRevision">${serv.getVersion()}</div>
|
||||
${serv.isMainServer() ? `<div class="serverListingStarWrapper">
|
||||
<div class="serverListingVersion">${serv.rawServer.minecraftVersion}</div>
|
||||
<div class="serverListingRevision">${serv.rawServer.version}</div>
|
||||
${serv.rawServer.mainServer ? `<div class="serverListingStarWrapper">
|
||||
<svg id="Layer_1" viewBox="0 0 107.45 104.74" width="20px" height="20px">
|
||||
<defs>
|
||||
<style>.cls-1{fill:#fff;}.cls-2{fill:none;stroke:#fff;stroke-miterlimit:10;}</style>
|
||||
@ -1103,9 +1103,9 @@ function loadSelectedServerOnModsTab(){
|
||||
|
||||
// Bind functionality to the server switch button.
|
||||
Array.from(document.getElementsByClassName('settingsSwitchServerButton')).forEach(el => {
|
||||
el.addEventListener('click', (e) => {
|
||||
el.addEventListener('click', async e => {
|
||||
e.target.blur()
|
||||
toggleServerSelection(true)
|
||||
await toggleServerSelection(true)
|
||||
})
|
||||
})
|
||||
|
||||
@ -1123,8 +1123,8 @@ function saveAllModConfigurations(){
|
||||
* server is changed.
|
||||
*/
|
||||
function animateSettingsTabRefresh(){
|
||||
$(`#${selectedSettingsTab}`).fadeOut(500, () => {
|
||||
prepareSettings()
|
||||
$(`#${selectedSettingsTab}`).fadeOut(500, async () => {
|
||||
await prepareSettings()
|
||||
$(`#${selectedSettingsTab}`).fadeIn(500)
|
||||
})
|
||||
}
|
||||
@ -1132,15 +1132,15 @@ function animateSettingsTabRefresh(){
|
||||
/**
|
||||
* Prepare the Mods tab for display.
|
||||
*/
|
||||
function prepareModsTab(first){
|
||||
resolveModsForUI()
|
||||
resolveDropinModsForUI()
|
||||
resolveShaderpacksForUI()
|
||||
async function prepareModsTab(first){
|
||||
await resolveModsForUI()
|
||||
await resolveDropinModsForUI()
|
||||
await resolveShaderpacksForUI()
|
||||
bindDropinModsRemoveButton()
|
||||
bindDropinModFileSystemButton()
|
||||
bindShaderpackButton()
|
||||
bindModsToggleSwitch()
|
||||
loadSelectedServerOnModsTab()
|
||||
await loadSelectedServerOnModsTab()
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1158,16 +1158,6 @@ const settingsJavaExecDetails = document.getElementById('settingsJavaExecDetails
|
||||
const settingsJavaReqDesc = document.getElementById('settingsJavaReqDesc')
|
||||
const settingsJvmOptsLink = document.getElementById('settingsJvmOptsLink')
|
||||
|
||||
// Store maximum memory values.
|
||||
const SETTINGS_MAX_MEMORY = ConfigManager.getAbsoluteMaxRAM()
|
||||
const SETTINGS_MIN_MEMORY = ConfigManager.getAbsoluteMinRAM()
|
||||
|
||||
// Set the max and min values for the ranged sliders.
|
||||
settingsMaxRAMRange.setAttribute('max', SETTINGS_MAX_MEMORY)
|
||||
settingsMaxRAMRange.setAttribute('min', SETTINGS_MIN_MEMORY)
|
||||
settingsMinRAMRange.setAttribute('max', SETTINGS_MAX_MEMORY)
|
||||
settingsMinRAMRange.setAttribute('min', SETTINGS_MIN_MEMORY )
|
||||
|
||||
// Bind on change event for min memory container.
|
||||
settingsMinRAMRange.onchange = (e) => {
|
||||
|
||||
@ -1178,7 +1168,7 @@ settingsMinRAMRange.onchange = (e) => {
|
||||
// Get reference to range bar.
|
||||
const bar = e.target.getElementsByClassName('rangeSliderBar')[0]
|
||||
// Calculate effective total memory.
|
||||
const max = (os.totalmem()-1000000000)/1000000000
|
||||
const max = os.totalmem()/1073741824
|
||||
|
||||
// Change range bar color based on the selected value.
|
||||
if(sMinV >= max/2){
|
||||
@ -1210,7 +1200,7 @@ settingsMaxRAMRange.onchange = (e) => {
|
||||
// Get reference to range bar.
|
||||
const bar = e.target.getElementsByClassName('rangeSliderBar')[0]
|
||||
// Calculate effective total memory.
|
||||
const max = (os.totalmem()-1000000000)/1000000000
|
||||
const max = os.totalmem()/1073741824
|
||||
|
||||
// Change range bar color based on the selected value.
|
||||
if(sMaxV >= max/2){
|
||||
@ -1338,8 +1328,8 @@ function updateRangedSlider(element, value, notch){
|
||||
* Display the total and available RAM.
|
||||
*/
|
||||
function populateMemoryStatus(){
|
||||
settingsMemoryTotal.innerHTML = Number((os.totalmem()-1000000000)/1000000000).toFixed(1) + 'G'
|
||||
settingsMemoryAvail.innerHTML = Number(os.freemem()/1000000000).toFixed(1) + 'G'
|
||||
settingsMemoryTotal.innerHTML = Number((os.totalmem()-1073741824)/1073741824).toFixed(1) + 'G'
|
||||
settingsMemoryAvail.innerHTML = Number(os.freemem()/1073741824).toFixed(1) + 'G'
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1348,50 +1338,61 @@ function populateMemoryStatus(){
|
||||
*
|
||||
* @param {string} execPath The executable path to populate against.
|
||||
*/
|
||||
function populateJavaExecDetails(execPath){
|
||||
const jg = new JavaGuard(DistroManager.getDistribution().getServer(ConfigManager.getSelectedServer()).getMinecraftVersion())
|
||||
jg._validateJavaBinary(execPath).then(v => {
|
||||
if(v.valid){
|
||||
const vendor = v.vendor != null ? ` (${v.vendor})` : ''
|
||||
if(v.version.major < 9) {
|
||||
settingsJavaExecDetails.innerHTML = `Selected: Java ${v.version.major} Update ${v.version.update} (x${v.arch})${vendor}`
|
||||
} else {
|
||||
settingsJavaExecDetails.innerHTML = `Selected: Java ${v.version.major}.${v.version.minor}.${v.version.revision} (x${v.arch})${vendor}`
|
||||
}
|
||||
async function populateJavaExecDetails(execPath){
|
||||
const server = (await DistroAPI.getDistribution()).getServerById(ConfigManager.getSelectedServer())
|
||||
|
||||
const details = await validateSelectedJvm(ensureJavaDirIsRoot(execPath), server.effectiveJavaOptions.supported)
|
||||
|
||||
if(details != null) {
|
||||
settingsJavaExecDetails.innerHTML = `Selected: Java ${details.semverStr} (${details.vendor})`
|
||||
} else {
|
||||
settingsJavaExecDetails.innerHTML = 'Invalid Selection'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function populateJavaReqDesc() {
|
||||
const mcVer = DistroManager.getDistribution().getServer(ConfigManager.getSelectedServer()).getMinecraftVersion()
|
||||
if(Util.mcVersionAtLeast('1.17', mcVer)) {
|
||||
settingsJavaReqDesc.innerHTML = 'Requires Java 17 x64.'
|
||||
} else {
|
||||
settingsJavaReqDesc.innerHTML = 'Requires Java 8 x64.'
|
||||
function populateJavaReqDesc(server) {
|
||||
settingsJavaReqDesc.innerHTML = `Requires Java ${server.effectiveJavaOptions.suggestedMajor} x64.`
|
||||
}
|
||||
|
||||
function populateJvmOptsLink(server) {
|
||||
const major = server.effectiveJavaOptions.suggestedMajor
|
||||
settingsJvmOptsLink.innerHTML = `Available Options for Java ${major} (HotSpot VM)`
|
||||
if(major >= 12) {
|
||||
settingsJvmOptsLink.href = `https://docs.oracle.com/en/java/javase/${major}/docs/specs/man/java.html#extra-options-for-java`
|
||||
}
|
||||
else if(major >= 11) {
|
||||
settingsJvmOptsLink.href = 'https://docs.oracle.com/en/java/javase/11/tools/java.html#GUID-3B1CE181-CD30-4178-9602-230B800D4FAE'
|
||||
}
|
||||
else if(major >= 9) {
|
||||
settingsJvmOptsLink.href = `https://docs.oracle.com/javase/${major}/tools/java.htm`
|
||||
}
|
||||
else {
|
||||
settingsJvmOptsLink.href = `https://docs.oracle.com/javase/${major}/docs/technotes/tools/${process.platform === 'win32' ? 'windows' : 'unix'}/java.html`
|
||||
}
|
||||
}
|
||||
|
||||
function populateJvmOptsLink() {
|
||||
const mcVer = DistroManager.getDistribution().getServer(ConfigManager.getSelectedServer()).getMinecraftVersion()
|
||||
if(Util.mcVersionAtLeast('1.17', mcVer)) {
|
||||
settingsJvmOptsLink.innerHTML = 'Available Options for Java 17 (HotSpot VM)'
|
||||
settingsJvmOptsLink.href = 'https://docs.oracle.com/en/java/javase/17/docs/specs/man/java.html#extra-options-for-java'
|
||||
} else {
|
||||
settingsJvmOptsLink.innerHTML = 'Available Options for Java 8 (HotSpot VM)'
|
||||
settingsJvmOptsLink.href = `https://docs.oracle.com/javase/8/docs/technotes/tools/${process.platform === 'win32' ? 'windows' : 'unix'}/java.html`
|
||||
}
|
||||
function bindMinMaxRam(server) {
|
||||
// Store maximum memory values.
|
||||
const SETTINGS_MAX_MEMORY = ConfigManager.getAbsoluteMaxRAM(server.rawServer.javaOptions?.ram)
|
||||
const SETTINGS_MIN_MEMORY = ConfigManager.getAbsoluteMinRAM(server.rawServer.javaOptions?.ram)
|
||||
|
||||
// Set the max and min values for the ranged sliders.
|
||||
settingsMaxRAMRange.setAttribute('max', SETTINGS_MAX_MEMORY)
|
||||
settingsMaxRAMRange.setAttribute('min', SETTINGS_MIN_MEMORY)
|
||||
settingsMinRAMRange.setAttribute('max', SETTINGS_MAX_MEMORY)
|
||||
settingsMinRAMRange.setAttribute('min', SETTINGS_MIN_MEMORY)
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare the Java tab for display.
|
||||
*/
|
||||
function prepareJavaTab(){
|
||||
bindRangeSlider()
|
||||
async function prepareJavaTab(){
|
||||
const server = (await DistroAPI.getDistribution()).getServerById(ConfigManager.getSelectedServer())
|
||||
bindMinMaxRam(server)
|
||||
bindRangeSlider(server)
|
||||
populateMemoryStatus()
|
||||
populateJavaReqDesc()
|
||||
populateJvmOptsLink()
|
||||
populateJavaReqDesc(server)
|
||||
populateJvmOptsLink(server)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1567,17 +1568,17 @@ function prepareUpdateTab(data = null){
|
||||
*
|
||||
* @param {boolean} first Whether or not it is the first load.
|
||||
*/
|
||||
function prepareSettings(first = false) {
|
||||
async function prepareSettings(first = false) {
|
||||
if(first){
|
||||
setupSettingsTabs()
|
||||
initSettingsValidators()
|
||||
prepareUpdateTab()
|
||||
} else {
|
||||
prepareModsTab()
|
||||
await prepareModsTab()
|
||||
}
|
||||
initSettingsValues()
|
||||
await initSettingsValues()
|
||||
prepareAccountsTab()
|
||||
prepareJavaTab()
|
||||
await prepareJavaTab()
|
||||
prepareAboutTab()
|
||||
}
|
||||
|
||||
|
@ -4,10 +4,11 @@
|
||||
*/
|
||||
// Requirements
|
||||
const path = require('path')
|
||||
const { Type } = require('helios-distribution-types')
|
||||
|
||||
const AuthManager = require('./assets/js/authmanager')
|
||||
const ConfigManager = require('./assets/js/configmanager')
|
||||
const DistroManager = require('./assets/js/distromanager')
|
||||
const { DistroAPI } = require('./assets/js/distromanager')
|
||||
const Lang = require('./assets/js/langloader')
|
||||
|
||||
let rscShouldLoad = false
|
||||
@ -40,10 +41,10 @@ let currentView
|
||||
*/
|
||||
function switchView(current, next, currentFadeTime = 500, nextFadeTime = 500, onCurrentFade = () => {}, onNextFade = () => {}){
|
||||
currentView = next
|
||||
$(`${current}`).fadeOut(currentFadeTime, () => {
|
||||
onCurrentFade()
|
||||
$(`${next}`).fadeIn(nextFadeTime, () => {
|
||||
onNextFade()
|
||||
$(`${current}`).fadeOut(currentFadeTime, async () => {
|
||||
await onCurrentFade()
|
||||
$(`${next}`).fadeIn(nextFadeTime, async () => {
|
||||
await onNextFade()
|
||||
})
|
||||
})
|
||||
}
|
||||
@ -57,15 +58,15 @@ function getCurrentView(){
|
||||
return currentView
|
||||
}
|
||||
|
||||
function showMainUI(data){
|
||||
async function showMainUI(data){
|
||||
|
||||
if(!isDev){
|
||||
loggerAutoUpdater.info('Initializing..')
|
||||
ipcRenderer.send('autoUpdateAction', 'initAutoUpdater', ConfigManager.getAllowPrerelease())
|
||||
}
|
||||
|
||||
prepareSettings(true)
|
||||
updateSelectedServer(data.getServer(ConfigManager.getSelectedServer()))
|
||||
await prepareSettings(true)
|
||||
updateSelectedServer(data.getServerById(ConfigManager.getSelectedServer()))
|
||||
refreshServerStatus()
|
||||
setTimeout(() => {
|
||||
document.getElementById('frameBar').style.backgroundColor = 'rgba(0, 0, 0, 0.5)'
|
||||
@ -133,7 +134,7 @@ function showFatalStartupError(){
|
||||
* @param {Object} data The distro index object.
|
||||
*/
|
||||
function onDistroRefresh(data){
|
||||
updateSelectedServer(data.getServer(ConfigManager.getSelectedServer()))
|
||||
updateSelectedServer(data.getServerById(ConfigManager.getSelectedServer()))
|
||||
refreshServerStatus()
|
||||
initNews()
|
||||
syncModConfigurations(data)
|
||||
@ -149,10 +150,10 @@ function syncModConfigurations(data){
|
||||
|
||||
const syncedCfgs = []
|
||||
|
||||
for(let serv of data.getServers()){
|
||||
for(let serv of data.servers){
|
||||
|
||||
const id = serv.getID()
|
||||
const mdls = serv.getModules()
|
||||
const id = serv.rawServer.id
|
||||
const mdls = serv.modules
|
||||
const cfg = ConfigManager.getModConfiguration(id)
|
||||
|
||||
if(cfg != null){
|
||||
@ -161,20 +162,20 @@ function syncModConfigurations(data){
|
||||
const mods = {}
|
||||
|
||||
for(let mdl of mdls){
|
||||
const type = mdl.getType()
|
||||
const type = mdl.rawModule.type
|
||||
|
||||
if(type === DistroManager.Types.ForgeMod || type === DistroManager.Types.LiteMod || type === DistroManager.Types.LiteLoader){
|
||||
if(!mdl.getRequired().isRequired()){
|
||||
const mdlID = mdl.getVersionlessID()
|
||||
if(type === Type.ForgeMod || type === Type.LiteMod || type === Type.LiteLoader){
|
||||
if(!mdl.getRequired().value){
|
||||
const mdlID = mdl.getVersionlessMavenIdentifier()
|
||||
if(modsOld[mdlID] == null){
|
||||
mods[mdlID] = scanOptionalSubModules(mdl.getSubModules(), mdl)
|
||||
mods[mdlID] = scanOptionalSubModules(mdl.subModules, mdl)
|
||||
} else {
|
||||
mods[mdlID] = mergeModConfiguration(modsOld[mdlID], scanOptionalSubModules(mdl.getSubModules(), mdl), false)
|
||||
mods[mdlID] = mergeModConfiguration(modsOld[mdlID], scanOptionalSubModules(mdl.subModules, mdl), false)
|
||||
}
|
||||
} else {
|
||||
if(mdl.hasSubModules()){
|
||||
const mdlID = mdl.getVersionlessID()
|
||||
const v = scanOptionalSubModules(mdl.getSubModules(), mdl)
|
||||
if(mdl.subModules.length > 0){
|
||||
const mdlID = mdl.getVersionlessMavenIdentifier()
|
||||
const v = scanOptionalSubModules(mdl.subModules, mdl)
|
||||
if(typeof v === 'object'){
|
||||
if(modsOld[mdlID] == null){
|
||||
mods[mdlID] = v
|
||||
@ -197,15 +198,15 @@ function syncModConfigurations(data){
|
||||
const mods = {}
|
||||
|
||||
for(let mdl of mdls){
|
||||
const type = mdl.getType()
|
||||
if(type === DistroManager.Types.ForgeMod || type === DistroManager.Types.LiteMod || type === DistroManager.Types.LiteLoader){
|
||||
if(!mdl.getRequired().isRequired()){
|
||||
mods[mdl.getVersionlessID()] = scanOptionalSubModules(mdl.getSubModules(), mdl)
|
||||
const type = mdl.rawModule.type
|
||||
if(type === Type.ForgeMod || type === Type.LiteMod || type === Type.LiteLoader){
|
||||
if(!mdl.getRequired().value){
|
||||
mods[mdl.getVersionlessMavenIdentifier()] = scanOptionalSubModules(mdl.subModules, mdl)
|
||||
} else {
|
||||
if(mdl.hasSubModules()){
|
||||
const v = scanOptionalSubModules(mdl.getSubModules(), mdl)
|
||||
if(mdl.subModules.length > 0){
|
||||
const v = scanOptionalSubModules(mdl.subModules, mdl)
|
||||
if(typeof v === 'object'){
|
||||
mods[mdl.getVersionlessID()] = v
|
||||
mods[mdl.getVersionlessMavenIdentifier()] = v
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -232,8 +233,8 @@ function syncModConfigurations(data){
|
||||
function ensureJavaSettings(data) {
|
||||
|
||||
// Nothing too fancy for now.
|
||||
for(const serv of data.getServers()){
|
||||
ConfigManager.ensureJavaConfig(serv.getID(), serv.getMinecraftVersion())
|
||||
for(const serv of data.servers){
|
||||
ConfigManager.ensureJavaConfig(serv.rawServer.id, serv.effectiveJavaOptions, serv.rawServer.javaOptions?.ram)
|
||||
}
|
||||
|
||||
ConfigManager.save()
|
||||
@ -251,17 +252,17 @@ function scanOptionalSubModules(mdls, origin){
|
||||
const mods = {}
|
||||
|
||||
for(let mdl of mdls){
|
||||
const type = mdl.getType()
|
||||
const type = mdl.rawModule.type
|
||||
// Optional types.
|
||||
if(type === DistroManager.Types.ForgeMod || type === DistroManager.Types.LiteMod || type === DistroManager.Types.LiteLoader){
|
||||
if(type === Type.ForgeMod || type === Type.LiteMod || type === Type.LiteLoader){
|
||||
// It is optional.
|
||||
if(!mdl.getRequired().isRequired()){
|
||||
mods[mdl.getVersionlessID()] = scanOptionalSubModules(mdl.getSubModules(), mdl)
|
||||
if(!mdl.getRequired().value){
|
||||
mods[mdl.getVersionlessMavenIdentifier()] = scanOptionalSubModules(mdl.subModules, mdl)
|
||||
} else {
|
||||
if(mdl.hasSubModules()){
|
||||
const v = scanOptionalSubModules(mdl.getSubModules(), mdl)
|
||||
const v = scanOptionalSubModules(mdl.subModules, mdl)
|
||||
if(typeof v === 'object'){
|
||||
mods[mdl.getVersionlessID()] = v
|
||||
mods[mdl.getVersionlessMavenIdentifier()] = v
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -272,13 +273,13 @@ function scanOptionalSubModules(mdls, origin){
|
||||
const ret = {
|
||||
mods
|
||||
}
|
||||
if(!origin.getRequired().isRequired()){
|
||||
ret.value = origin.getRequired().isDefault()
|
||||
if(!origin.getRequired().value){
|
||||
ret.value = origin.getRequired().def
|
||||
}
|
||||
return ret
|
||||
}
|
||||
}
|
||||
return origin.getRequired().isDefault()
|
||||
return origin.getRequired().def
|
||||
}
|
||||
|
||||
/**
|
||||
@ -323,18 +324,6 @@ function mergeModConfiguration(o, n, nReq = false){
|
||||
return n
|
||||
}
|
||||
|
||||
function refreshDistributionIndex(remote, onSuccess, onError){
|
||||
if(remote){
|
||||
DistroManager.pullRemote()
|
||||
.then(onSuccess)
|
||||
.catch(onError)
|
||||
} else {
|
||||
DistroManager.pullLocal()
|
||||
.then(onSuccess)
|
||||
.catch(onError)
|
||||
}
|
||||
}
|
||||
|
||||
async function validateSelectedAccount(){
|
||||
const selectedAcc = ConfigManager.getSelectedAccount()
|
||||
if(selectedAcc != null){
|
||||
@ -429,14 +418,14 @@ function setSelectedAccount(uuid){
|
||||
}
|
||||
|
||||
// Synchronous Listener
|
||||
document.addEventListener('readystatechange', function(){
|
||||
document.addEventListener('readystatechange', async () => {
|
||||
|
||||
if (document.readyState === 'interactive' || document.readyState === 'complete'){
|
||||
if(rscShouldLoad){
|
||||
rscShouldLoad = false
|
||||
if(!fatalStartupError){
|
||||
const data = DistroManager.getDistribution()
|
||||
showMainUI(data)
|
||||
const data = await DistroAPI.getDistribution()
|
||||
await showMainUI(data)
|
||||
} else {
|
||||
showFatalStartupError()
|
||||
}
|
||||
@ -446,13 +435,13 @@ document.addEventListener('readystatechange', function(){
|
||||
}, false)
|
||||
|
||||
// Actions that must be performed after the distribution index is downloaded.
|
||||
ipcRenderer.on('distributionIndexDone', (event, res) => {
|
||||
ipcRenderer.on('distributionIndexDone', async (event, res) => {
|
||||
if(res) {
|
||||
const data = DistroManager.getDistribution()
|
||||
const data = await DistroAPI.getDistribution()
|
||||
syncModConfigurations(data)
|
||||
ensureJavaSettings(data)
|
||||
if(document.readyState === 'interactive' || document.readyState === 'complete'){
|
||||
showMainUI(data)
|
||||
await showMainUI(data)
|
||||
} else {
|
||||
rscShouldLoad = true
|
||||
}
|
||||
@ -467,11 +456,10 @@ ipcRenderer.on('distributionIndexDone', (event, res) => {
|
||||
})
|
||||
|
||||
// Util for development
|
||||
function devModeToggle() {
|
||||
DistroManager.setDevMode(true)
|
||||
DistroManager.pullLocal().then((data) => {
|
||||
async function devModeToggle() {
|
||||
DistroAPI.toggleDevMode(true)
|
||||
const data = await DistroAPI.refreshDistributionOrFallback()
|
||||
ensureJavaSettings(data)
|
||||
updateSelectedServer(data.getServers()[0])
|
||||
updateSelectedServer(data.servers[0])
|
||||
syncModConfigurations(data)
|
||||
})
|
||||
}
|
||||
|
112
docs/distro.md
112
docs/distro.md
@ -2,6 +2,8 @@
|
||||
|
||||
You can use [Nebula](https://github.com/dscalzi/Nebula) to automate the generation of a distribution index.
|
||||
|
||||
The most up to date and accurate descriptions of the distribution spec can be viewed in [helios-distribution-types](https://github.com/dscalzi/helios-distribution-types).
|
||||
|
||||
The distribution index is written in JSON. The general format of the index is as posted below.
|
||||
|
||||
```json
|
||||
@ -143,12 +145,122 @@ Only one server in the array should have the `mainServer` property enabled. This
|
||||
|
||||
Whether or not the server can be autoconnected to. If false, the server will not be autoconnected to even when the user has the autoconnect setting enabled.
|
||||
|
||||
### `Server.javaOptions: JavaOptions`
|
||||
|
||||
**OPTIONAL**
|
||||
|
||||
Sever-specific Java options. If not provided, defaults are used by the client.
|
||||
|
||||
### `Server.modules: Module[]`
|
||||
|
||||
An array of module objects.
|
||||
|
||||
---
|
||||
|
||||
## JavaOptions Object
|
||||
|
||||
Server-specific Java options.
|
||||
|
||||
#### Example
|
||||
```JSON
|
||||
{
|
||||
"supported": ">=17",
|
||||
"suggestedMajor": 17,
|
||||
"platformOptions": [
|
||||
{
|
||||
"platform": "darwin",
|
||||
"architecture": "arm64",
|
||||
"distribution": "CORRETTO"
|
||||
}
|
||||
],
|
||||
"ram": {
|
||||
"recommended": 3072,
|
||||
"minimum": 2048
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### `JavaOptions.platformOptions: JavaPlatformOptions[]`
|
||||
|
||||
**OPTIONAL**
|
||||
|
||||
Platform-specific java rules for this server configuration. Validation rules will be delegated to the client for any undefined properties. Java validation can be configured for specific platforms and architectures. The most specific ruleset will be applied.
|
||||
|
||||
Maxtrix Precedence (Highest - Lowest)
|
||||
- Current platform, current architecture (ex. win32 x64).
|
||||
- Current platform, any architecture (ex. win32).
|
||||
- Java Options base properties.
|
||||
- Client logic (default logic in the client).
|
||||
|
||||
Properties:
|
||||
|
||||
- `platformOptions.platform: string` - The platform that this validation matrix applies to.
|
||||
- `platformOptions.architecture: string` - Optional. The architecture that this validation matrix applies to. If omitted, applies to all architectures.
|
||||
- `platformOptions.distribution: string` - Optional. See `JavaOptions.distribution`.
|
||||
- `platformOptions.supported: string` - Optional. See `JavaOptions.supported`.
|
||||
- `platformOptions.suggestedMajor: number` - Optional. See `JavaOptions.suggestedMajor`.
|
||||
|
||||
### `JavaOptions.ram: object`
|
||||
|
||||
**OPTIONAL**
|
||||
|
||||
This allows you to require a minimum and recommended amount of RAM per server instance. The minimum is the smallest value the user can select in the settings slider. The recommended value will be the default value selected for that server. These values are specified in megabytes and must be an interval of 512. This allows configuration in intervals of half gigabytes. In the above example, the recommended ram value is 3 GB (3072 MB) and the minimum is 2 GB (2048 MB).
|
||||
|
||||
- `ram.recommended: number` - The recommended amount of RAM in megabytes. Must be an interval of 512.
|
||||
- `ram.minimum: number` - The absolute minimum amount of RAM in megabytes. Must be an interval of 512.
|
||||
|
||||
### `JavaOptions.distribution: string`
|
||||
|
||||
**OPTIONAL**
|
||||
|
||||
Preferred JDK distribution to download if no applicable installation could be found. If omitted, the client will decide (decision may be platform-specific).
|
||||
|
||||
### `JavaOptions.supported: string`
|
||||
|
||||
**OPTIONAL**
|
||||
|
||||
A semver range of supported JDK versions.
|
||||
|
||||
Java version syntax is platform dependent.
|
||||
|
||||
JDK 8 and prior
|
||||
```
|
||||
1.{major}.{minor}_{patch}-b{build}
|
||||
Ex. 1.8.0_152-b16
|
||||
```
|
||||
|
||||
JDK 9+
|
||||
```
|
||||
{major}.{minor}.{patch}+{build}
|
||||
Ex. 11.0.12+7
|
||||
```
|
||||
|
||||
For processing, all versions will be translated into a semver compliant string. JDK 9+ is already semver. For versions 8 and below, `1.{major}.{minor}_{patch}-b{build}` will be translated to `{major}.{minor}.{patch}+{build}`.
|
||||
|
||||
If specified, you must also specify suggestedMajor.
|
||||
|
||||
If omitted, the client will decide based on the game version.
|
||||
|
||||
### `JavaOptions.suggestedMajor: number`
|
||||
|
||||
**OPTIONAL**
|
||||
|
||||
The suggested major Java version. The suggested major should comply with the version range specified by supported, if defined. This will be used in messages displayed to the end user, and to automatically fetch a Java version.
|
||||
|
||||
NOTE If supported is specified, suggestedMajor must be set. The launcher's default value may not comply with your custom major supported range.
|
||||
|
||||
Common use case:
|
||||
- supported: '>=17.x'
|
||||
- suggestedMajor: 17
|
||||
|
||||
More involved:
|
||||
- supported: '>=16 <20'
|
||||
- suggestedMajor: 17
|
||||
|
||||
Given a wider support range, it becomes necessary to specify which major version in the range is the suggested.
|
||||
|
||||
---
|
||||
|
||||
## Module Object
|
||||
|
||||
A module is a generic representation of a file required to run the minecraft client.
|
||||
|
562
package-lock.json
generated
562
package-lock.json
generated
@ -1,37 +1,32 @@
|
||||
{
|
||||
"name": "helioslauncher",
|
||||
"version": "1.10.0",
|
||||
"version": "2.0.0-rc.3",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "helioslauncher",
|
||||
"version": "1.10.0",
|
||||
"version": "2.0.0-rc.3",
|
||||
"license": "UNLICENSED",
|
||||
"dependencies": {
|
||||
"@electron/remote": "^2.0.8",
|
||||
"adm-zip": "^0.5.9",
|
||||
"async": "^3.2.4",
|
||||
"discord-rpc-patch": "^4.0.1",
|
||||
"ejs": "^3.1.8",
|
||||
"ejs": "^3.1.9",
|
||||
"ejs-electron": "^2.1.1",
|
||||
"electron-updater": "^5.3.0",
|
||||
"fs-extra": "^11.1.0",
|
||||
"fs-extra": "^11.1.1",
|
||||
"github-syntax-dark": "^0.5.0",
|
||||
"got": "^11.8.5",
|
||||
"helios-core": "~0.1.2",
|
||||
"jquery": "^3.6.1",
|
||||
"node-disk-info": "^1.3.0",
|
||||
"node-stream-zip": "^1.15.0",
|
||||
"request": "^2.88.2",
|
||||
"semver": "^7.3.8",
|
||||
"tar-fs": "^2.1.1",
|
||||
"winreg": "^1.2.4"
|
||||
"helios-core": "~2.0.0",
|
||||
"helios-distribution-types": "^1.2.0",
|
||||
"jquery": "^3.6.4",
|
||||
"semver": "^7.3.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"electron": "^23.0.0",
|
||||
"electron": "^23.2.0",
|
||||
"electron-builder": "^23.6.0",
|
||||
"eslint": "^8.34.0"
|
||||
"eslint": "^8.36.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "18.x.x"
|
||||
@ -170,15 +165,39 @@
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint-community/eslint-utils": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.3.0.tgz",
|
||||
"integrity": "sha512-v3oplH6FYCULtFuCeqyuTd9D2WKO937Dxdq+GmHOLL72TTRriLxz2VLlNfkZRsvj6PKnOPAtuT6dwrs/pA5DvA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"eslint-visitor-keys": "^3.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint-community/regexpp": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.4.0.tgz",
|
||||
"integrity": "sha512-A9983Q0LnDGdLPjxyXQ00sbV+K+O+ko2Dr+CZigbHWtX9pNfxlaBkMR8X1CztI73zuEyEBXTVjx7CE+/VSwDiQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": "^12.0.0 || ^14.0.0 || >=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint/eslintrc": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.1.tgz",
|
||||
"integrity": "sha512-XXrH9Uarn0stsyldqDYq8r++mROmWRI1xKMXa640Bb//SY1+ECYX6VzT6Lcx5frD0V30XieqJ0oX9I2Xj5aoMA==",
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.1.tgz",
|
||||
"integrity": "sha512-eFRmABvW2E5Ho6f5fHLqgena46rOj7r7OKHYfLElqcBfGFHHpjBhivyi5+jOEQuSpdc/1phIZJlbC2te+tZNIw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ajv": "^6.12.4",
|
||||
"debug": "^4.3.2",
|
||||
"espree": "^9.4.0",
|
||||
"espree": "^9.5.0",
|
||||
"globals": "^13.19.0",
|
||||
"ignore": "^5.2.0",
|
||||
"import-fresh": "^3.2.1",
|
||||
@ -193,6 +212,15 @@
|
||||
"url": "https://opencollective.com/eslint"
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint/js": {
|
||||
"version": "8.36.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.36.0.tgz",
|
||||
"integrity": "sha512-lxJ9R5ygVm8ZWgYdUweoq5ownDlJ4upvoWmO4eLxBYHdMo+vZ/Rx0EN6MbKWDJOSUGrqJy2Gt+Dyv/VKml0fjg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@humanwhocodes/config-array": {
|
||||
"version": "0.11.8",
|
||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz",
|
||||
@ -411,9 +439,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "16.18.12",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.12.tgz",
|
||||
"integrity": "sha512-vzLe5NaNMjIE3mcddFVGlAXN1LEWueUsMsOJWaT6wWMJGyljHAWHznqfnKUQWGzu7TLPrGvWdNAsvQYW+C0xtw=="
|
||||
"version": "16.18.16",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.16.tgz",
|
||||
"integrity": "sha512-ZOzvDRWp8dCVBmgnkIqYCArgdFOO9YzocZp8Ra25N/RStKiWvMOXHMz+GjSeVNe5TstaTmTWPucGJkDw0XXJWA=="
|
||||
},
|
||||
"node_modules/@types/plist": {
|
||||
"version": "3.0.2",
|
||||
@ -526,6 +554,7 @@
|
||||
"version": "6.12.6",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
|
||||
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"fast-deep-equal": "^3.1.1",
|
||||
"fast-json-stable-stringify": "^2.0.0",
|
||||
@ -653,18 +682,12 @@
|
||||
"@types/glob": "^7.1.1"
|
||||
}
|
||||
},
|
||||
"node_modules/asn1": {
|
||||
"version": "0.2.6",
|
||||
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz",
|
||||
"integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==",
|
||||
"dependencies": {
|
||||
"safer-buffer": "~2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/assert-plus": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
|
||||
"integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"engines": {
|
||||
"node": ">=0.8"
|
||||
}
|
||||
@ -696,7 +719,8 @@
|
||||
"node_modules/asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
|
||||
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/at-least-node": {
|
||||
"version": "1.0.0",
|
||||
@ -707,19 +731,6 @@
|
||||
"node": ">= 4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/aws-sign2": {
|
||||
"version": "0.7.0",
|
||||
"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
|
||||
"integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==",
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/aws4": {
|
||||
"version": "1.12.0",
|
||||
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz",
|
||||
"integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg=="
|
||||
},
|
||||
"node_modules/balanced-match": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||
@ -744,14 +755,6 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"node_modules/bcrypt-pbkdf": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
|
||||
"integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==",
|
||||
"dependencies": {
|
||||
"tweetnacl": "^0.14.3"
|
||||
}
|
||||
},
|
||||
"node_modules/bl": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
|
||||
@ -945,11 +948,6 @@
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/caseless": {
|
||||
"version": "0.12.0",
|
||||
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
|
||||
"integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw=="
|
||||
},
|
||||
"node_modules/chalk": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
|
||||
@ -1106,6 +1104,7 @@
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"delayed-stream": "~1.0.0"
|
||||
},
|
||||
@ -1139,7 +1138,9 @@
|
||||
"node_modules/core-util-is": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
|
||||
"integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ=="
|
||||
"integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/crc": {
|
||||
"version": "3.8.0",
|
||||
@ -1165,17 +1166,6 @@
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/dashdash": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
|
||||
"integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==",
|
||||
"dependencies": {
|
||||
"assert-plus": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/debug": {
|
||||
"version": "4.3.4",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
|
||||
@ -1251,6 +1241,7 @@
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
@ -1393,19 +1384,10 @@
|
||||
"integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/ecc-jsbn": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
|
||||
"integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==",
|
||||
"dependencies": {
|
||||
"jsbn": "~0.1.0",
|
||||
"safer-buffer": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ejs": {
|
||||
"version": "3.1.8",
|
||||
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.8.tgz",
|
||||
"integrity": "sha512-/sXZeMlhS0ArkfX2Aw780gJzXSMPnKjtspYZv+f3NiKLlubezAHDU5+9xz6gd3/NhG3txQCo6xlglmTS+oTGEQ==",
|
||||
"version": "3.1.9",
|
||||
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz",
|
||||
"integrity": "sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==",
|
||||
"dependencies": {
|
||||
"jake": "^10.8.5"
|
||||
},
|
||||
@ -1426,9 +1408,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/electron": {
|
||||
"version": "23.0.0",
|
||||
"resolved": "https://registry.npmjs.org/electron/-/electron-23.0.0.tgz",
|
||||
"integrity": "sha512-S6hVtTAjauMiiWP9sBVR5RpcUC464cNZ06I2EMUjeZBq+KooS6tLmNsfw0zLpAXDp1qosjlBP3v71NTZ3gd9iA==",
|
||||
"version": "23.2.0",
|
||||
"resolved": "https://registry.npmjs.org/electron/-/electron-23.2.0.tgz",
|
||||
"integrity": "sha512-De9e21cri0QYct/w6tTNOnKyCt9RVKUw5F8PEN4FPzGR9tr6IT53uyt42uH754uJWrZeLMCAdoXy6/0GmMmYZA==",
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"@electron/get": "^2.0.0",
|
||||
@ -1645,12 +1627,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/eslint": {
|
||||
"version": "8.34.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.34.0.tgz",
|
||||
"integrity": "sha512-1Z8iFsucw+7kSqXNZVslXS8Ioa4u2KM7GPwuKtkTFAqZ/cHMcEaR+1+Br0wLlot49cNxIiZk5wp8EAbPcYZxTg==",
|
||||
"version": "8.36.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.36.0.tgz",
|
||||
"integrity": "sha512-Y956lmS7vDqomxlaaQAHVmeb4tNMp2FWIvU/RnU5BD3IKMD/MJPr76xdyr68P8tV1iNMvN2mRK0yy3c+UjL+bw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@eslint/eslintrc": "^1.4.1",
|
||||
"@eslint-community/eslint-utils": "^4.2.0",
|
||||
"@eslint-community/regexpp": "^4.4.0",
|
||||
"@eslint/eslintrc": "^2.0.1",
|
||||
"@eslint/js": "8.36.0",
|
||||
"@humanwhocodes/config-array": "^0.11.8",
|
||||
"@humanwhocodes/module-importer": "^1.0.1",
|
||||
"@nodelib/fs.walk": "^1.2.8",
|
||||
@ -1661,10 +1646,9 @@
|
||||
"doctrine": "^3.0.0",
|
||||
"escape-string-regexp": "^4.0.0",
|
||||
"eslint-scope": "^7.1.1",
|
||||
"eslint-utils": "^3.0.0",
|
||||
"eslint-visitor-keys": "^3.3.0",
|
||||
"espree": "^9.4.0",
|
||||
"esquery": "^1.4.0",
|
||||
"espree": "^9.5.0",
|
||||
"esquery": "^1.4.2",
|
||||
"esutils": "^2.0.2",
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
"file-entry-cache": "^6.0.1",
|
||||
@ -1685,7 +1669,6 @@
|
||||
"minimatch": "^3.1.2",
|
||||
"natural-compare": "^1.4.0",
|
||||
"optionator": "^0.9.1",
|
||||
"regexpp": "^3.2.0",
|
||||
"strip-ansi": "^6.0.1",
|
||||
"strip-json-comments": "^3.1.0",
|
||||
"text-table": "^0.2.0"
|
||||
@ -1713,33 +1696,6 @@
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-utils": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz",
|
||||
"integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"eslint-visitor-keys": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^10.0.0 || ^12.0.0 || >= 14.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/mysticatea"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"eslint": ">=5"
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-utils/node_modules/eslint-visitor-keys": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz",
|
||||
"integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-visitor-keys": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz",
|
||||
@ -1750,9 +1706,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/espree": {
|
||||
"version": "9.4.1",
|
||||
"resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz",
|
||||
"integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==",
|
||||
"version": "9.5.0",
|
||||
"resolved": "https://registry.npmjs.org/espree/-/espree-9.5.0.tgz",
|
||||
"integrity": "sha512-JPbJGhKc47++oo4JkEoTe2wjy4fmMwvFpgJT9cQzmfXKp22Dr6Hf1tdCteLz1h0P3t+mGvWZ+4Uankvh8+c6zw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"acorn": "^8.8.0",
|
||||
@ -1767,9 +1723,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/esquery": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz",
|
||||
"integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==",
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz",
|
||||
"integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"estraverse": "^5.1.0"
|
||||
@ -1808,11 +1764,6 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/extend": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
|
||||
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
|
||||
},
|
||||
"node_modules/extract-zip": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz",
|
||||
@ -1833,22 +1784,26 @@
|
||||
}
|
||||
},
|
||||
"node_modules/extsprintf": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
|
||||
"integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==",
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.1.tgz",
|
||||
"integrity": "sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA==",
|
||||
"dev": true,
|
||||
"engines": [
|
||||
"node >=0.6.0"
|
||||
]
|
||||
],
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/fast-deep-equal": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
||||
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
|
||||
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/fast-json-stable-stringify": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
|
||||
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
|
||||
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/fast-levenshtein": {
|
||||
"version": "2.0.6",
|
||||
@ -1860,7 +1815,6 @@
|
||||
"version": "1.15.0",
|
||||
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz",
|
||||
"integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"reusify": "^1.0.4"
|
||||
}
|
||||
@ -1957,14 +1911,6 @@
|
||||
"resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz",
|
||||
"integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw=="
|
||||
},
|
||||
"node_modules/forever-agent": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
|
||||
"integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==",
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/form-data": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
|
||||
@ -1985,9 +1931,9 @@
|
||||
"integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow=="
|
||||
},
|
||||
"node_modules/fs-extra": {
|
||||
"version": "11.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.0.tgz",
|
||||
"integrity": "sha512-0rcTq621PD5jM/e0a3EJoGC/1TC5ZBCERW82LQuwfGnCa1V8w7dpYH1yNu+SLb6E5dkeCBzKEyLGlFrnr+dUyw==",
|
||||
"version": "11.1.1",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.1.tgz",
|
||||
"integrity": "sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==",
|
||||
"dependencies": {
|
||||
"graceful-fs": "^4.2.0",
|
||||
"jsonfile": "^6.0.1",
|
||||
@ -2070,14 +2016,6 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/getpass": {
|
||||
"version": "0.1.7",
|
||||
"resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
|
||||
"integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==",
|
||||
"dependencies": {
|
||||
"assert-plus": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/github-syntax-dark": {
|
||||
"version": "0.5.0",
|
||||
"resolved": "https://registry.npmjs.org/github-syntax-dark/-/github-syntax-dark-0.5.0.tgz",
|
||||
@ -2187,9 +2125,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/graceful-fs": {
|
||||
"version": "4.2.10",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
|
||||
"integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA=="
|
||||
"version": "4.2.11",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
|
||||
"integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="
|
||||
},
|
||||
"node_modules/graceful-readlink": {
|
||||
"version": "1.0.1",
|
||||
@ -2203,27 +2141,6 @@
|
||||
"integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/har-schema": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
|
||||
"integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==",
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/har-validator": {
|
||||
"version": "5.1.5",
|
||||
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz",
|
||||
"integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==",
|
||||
"deprecated": "this library is no longer supported",
|
||||
"dependencies": {
|
||||
"ajv": "^6.12.3",
|
||||
"har-schema": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/has": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
|
||||
@ -2269,29 +2186,27 @@
|
||||
}
|
||||
},
|
||||
"node_modules/helios-core": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/helios-core/-/helios-core-0.1.2.tgz",
|
||||
"integrity": "sha512-xM3+nZcymy9iS36Z5odmuFZAsrSuyviQUh+dffXc+utXOP/Ox7m2HUo76t86cN8R1tLjJ/OzQJLzILACVaRryg==",
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/helios-core/-/helios-core-2.0.0.tgz",
|
||||
"integrity": "sha512-KmObKL9JZutHzTp9Pv344Ab7CdYvf0pOhwxjuxw+/QdtJQlmCIrPF7eX9J6I1CUSheIM4lRk76LQbG28H7zqeg==",
|
||||
"dependencies": {
|
||||
"fs-extra": "^10.1.0",
|
||||
"got": "^11.8.5",
|
||||
"luxon": "^3.1.0",
|
||||
"fastq": "^1.15.0",
|
||||
"fs-extra": "^11.1.1",
|
||||
"got": "^11.8.6",
|
||||
"luxon": "^3.3.0",
|
||||
"node-disk-info": "^1.3.0",
|
||||
"node-stream-zip": "^1.15.0",
|
||||
"semver": "^7.3.8",
|
||||
"tar-fs": "^2.1.1",
|
||||
"triple-beam": "^1.3.0",
|
||||
"winreg": "^1.2.4",
|
||||
"winston": "^3.8.2"
|
||||
}
|
||||
},
|
||||
"node_modules/helios-core/node_modules/fs-extra": {
|
||||
"version": "10.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
|
||||
"integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
|
||||
"dependencies": {
|
||||
"graceful-fs": "^4.2.0",
|
||||
"jsonfile": "^6.0.1",
|
||||
"universalify": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
"node_modules/helios-distribution-types": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/helios-distribution-types/-/helios-distribution-types-1.2.0.tgz",
|
||||
"integrity": "sha512-C8mRJGK0zAc7rRnA06Sj0LYwVqhY445UYNTmXU876AmfBirRR2F+A3LsD3osdgTxRMzrgkxBXvYZ0QbYW6j+6Q=="
|
||||
},
|
||||
"node_modules/hosted-git-info": {
|
||||
"version": "4.1.0",
|
||||
@ -2324,20 +2239,6 @@
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/http-signature": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
|
||||
"integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==",
|
||||
"dependencies": {
|
||||
"assert-plus": "^1.0.0",
|
||||
"jsprim": "^1.2.2",
|
||||
"sshpk": "^1.7.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.8",
|
||||
"npm": ">=1.3.7"
|
||||
}
|
||||
},
|
||||
"node_modules/http2-wrapper": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz",
|
||||
@ -2526,11 +2427,6 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/is-typedarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
|
||||
"integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA=="
|
||||
},
|
||||
"node_modules/isbinaryfile": {
|
||||
"version": "4.0.10",
|
||||
"resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz",
|
||||
@ -2549,11 +2445,6 @@
|
||||
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/isstream": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
|
||||
"integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g=="
|
||||
},
|
||||
"node_modules/jake": {
|
||||
"version": "10.8.5",
|
||||
"resolved": "https://registry.npmjs.org/jake/-/jake-10.8.5.tgz",
|
||||
@ -2572,9 +2463,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/jquery": {
|
||||
"version": "3.6.3",
|
||||
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.3.tgz",
|
||||
"integrity": "sha512-bZ5Sy3YzKo9Fyc8wH2iIQK4JImJ6R0GWI9kL1/k7Z91ZBNgkRXE6U0JfHIizZbort8ZunhSI3jw9I6253ahKfg=="
|
||||
"version": "3.6.4",
|
||||
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.4.tgz",
|
||||
"integrity": "sha512-v28EW9DWDFpzcD9O5iyJXg3R3+q+mET5JhnjJzQUZMHOv67bpSIHq81GEYpPNZHG+XXHsfSme3nxp/hndKEcsQ=="
|
||||
},
|
||||
"node_modules/js-sdsl": {
|
||||
"version": "4.3.0",
|
||||
@ -2597,25 +2488,16 @@
|
||||
"js-yaml": "bin/js-yaml.js"
|
||||
}
|
||||
},
|
||||
"node_modules/jsbn": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
|
||||
"integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg=="
|
||||
},
|
||||
"node_modules/json-buffer": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
|
||||
"integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="
|
||||
},
|
||||
"node_modules/json-schema": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
|
||||
"integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA=="
|
||||
},
|
||||
"node_modules/json-schema-traverse": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
|
||||
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
|
||||
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/json-stable-stringify-without-jsonify": {
|
||||
"version": "1.0.1",
|
||||
@ -2626,7 +2508,8 @@
|
||||
"node_modules/json-stringify-safe": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
|
||||
"integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA=="
|
||||
"integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/json5": {
|
||||
"version": "2.2.3",
|
||||
@ -2651,33 +2534,6 @@
|
||||
"graceful-fs": "^4.1.6"
|
||||
}
|
||||
},
|
||||
"node_modules/jsprim": {
|
||||
"version": "1.4.2",
|
||||
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz",
|
||||
"integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==",
|
||||
"dependencies": {
|
||||
"assert-plus": "1.0.0",
|
||||
"extsprintf": "1.3.0",
|
||||
"json-schema": "0.4.0",
|
||||
"verror": "1.10.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/jsprim/node_modules/verror": {
|
||||
"version": "1.10.0",
|
||||
"resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
|
||||
"integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==",
|
||||
"engines": [
|
||||
"node >=0.6.0"
|
||||
],
|
||||
"dependencies": {
|
||||
"assert-plus": "^1.0.0",
|
||||
"core-util-is": "1.0.2",
|
||||
"extsprintf": "^1.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/keyv": {
|
||||
"version": "4.5.2",
|
||||
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.2.tgz",
|
||||
@ -2779,9 +2635,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/luxon": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/luxon/-/luxon-3.2.1.tgz",
|
||||
"integrity": "sha512-QrwPArQCNLAKGO/C+ZIilgIuDnEnKx5QYODdDtbFaxzsbZcc/a7WFq7MhsVYgRlwawLtvOUESTlfJ+hc/USqPg==",
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/luxon/-/luxon-3.3.0.tgz",
|
||||
"integrity": "sha512-An0UCfG/rSiqtAIiBPO0Y9/zAnHUZxAMiCpTd5h2smgsj7GGmcenvrvww2cqNA8/4A5ZrD1gJpHN2mIHZQF+Mg==",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
@ -2813,6 +2669,7 @@
|
||||
"version": "1.52.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
|
||||
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
@ -2821,6 +2678,7 @@
|
||||
"version": "2.1.35",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
|
||||
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"mime-db": "1.52.0"
|
||||
},
|
||||
@ -2857,9 +2715,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/minipass": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/minipass/-/minipass-4.0.3.tgz",
|
||||
"integrity": "sha512-OW2r4sQ0sI+z5ckEt5c1Tri4xTgZwYDxpE54eqWlQloQRoWtXjqt9udJ5Z4dSv7wK+nfFI7FRXyCpBSft+gpFw==",
|
||||
"version": "4.2.5",
|
||||
"resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.5.tgz",
|
||||
"integrity": "sha512-+yQl7SX3bIT83Lhb4BVorMAHVuqsskxRdlmO9kTpyukp8vsm2Sn/fUOV9xlnG8/a5JsypJzap21lz/y3FBMJ8Q==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
@ -2978,14 +2836,6 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/oauth-sign": {
|
||||
"version": "0.9.0",
|
||||
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
|
||||
"integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/object-keys": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
|
||||
@ -3110,11 +2960,6 @@
|
||||
"resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
|
||||
"integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg=="
|
||||
},
|
||||
"node_modules/performance-now": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
|
||||
"integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow=="
|
||||
},
|
||||
"node_modules/plist": {
|
||||
"version": "3.0.6",
|
||||
"resolved": "https://registry.npmjs.org/plist/-/plist-3.0.6.tgz",
|
||||
@ -3145,11 +2990,6 @@
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/psl": {
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz",
|
||||
"integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag=="
|
||||
},
|
||||
"node_modules/pump": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
|
||||
@ -3163,18 +3003,11 @@
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
|
||||
"integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/qs": {
|
||||
"version": "6.5.3",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz",
|
||||
"integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==",
|
||||
"engines": {
|
||||
"node": ">=0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/queue-microtask": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
|
||||
@ -3223,9 +3056,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/readable-stream": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
|
||||
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
|
||||
"version": "3.6.2",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
|
||||
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
|
||||
"dependencies": {
|
||||
"inherits": "^2.0.3",
|
||||
"string_decoder": "^1.1.1",
|
||||
@ -3235,62 +3068,6 @@
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/regexpp": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz",
|
||||
"integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/mysticatea"
|
||||
}
|
||||
},
|
||||
"node_modules/request": {
|
||||
"version": "2.88.2",
|
||||
"resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
|
||||
"integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==",
|
||||
"deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142",
|
||||
"dependencies": {
|
||||
"aws-sign2": "~0.7.0",
|
||||
"aws4": "^1.8.0",
|
||||
"caseless": "~0.12.0",
|
||||
"combined-stream": "~1.0.6",
|
||||
"extend": "~3.0.2",
|
||||
"forever-agent": "~0.6.1",
|
||||
"form-data": "~2.3.2",
|
||||
"har-validator": "~5.1.3",
|
||||
"http-signature": "~1.2.0",
|
||||
"is-typedarray": "~1.0.0",
|
||||
"isstream": "~0.1.2",
|
||||
"json-stringify-safe": "~5.0.1",
|
||||
"mime-types": "~2.1.19",
|
||||
"oauth-sign": "~0.9.0",
|
||||
"performance-now": "^2.1.0",
|
||||
"qs": "~6.5.2",
|
||||
"safe-buffer": "^5.1.2",
|
||||
"tough-cookie": "~2.5.0",
|
||||
"tunnel-agent": "^0.6.0",
|
||||
"uuid": "^3.3.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/request/node_modules/form-data": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
|
||||
"integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
|
||||
"dependencies": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.6",
|
||||
"mime-types": "^2.1.12"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.12"
|
||||
}
|
||||
},
|
||||
"node_modules/require-directory": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
|
||||
@ -3329,7 +3106,6 @@
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
|
||||
"integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"iojs": ">=1.0.0",
|
||||
"node": ">=0.10.0"
|
||||
@ -3419,9 +3195,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/safe-stable-stringify": {
|
||||
"version": "2.4.2",
|
||||
"resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.2.tgz",
|
||||
"integrity": "sha512-gMxvPJYhP0O9n2pvcfYfIuYgbledAOJFcqRThtPRmjscaipiwcwPPKLytpVzMkG2HAN87Qmo2d4PtGiri1dSLA==",
|
||||
"version": "2.4.3",
|
||||
"resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz",
|
||||
"integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
@ -3593,30 +3369,6 @@
|
||||
"integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/sshpk": {
|
||||
"version": "1.17.0",
|
||||
"resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz",
|
||||
"integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==",
|
||||
"dependencies": {
|
||||
"asn1": "~0.2.3",
|
||||
"assert-plus": "^1.0.0",
|
||||
"bcrypt-pbkdf": "^1.0.0",
|
||||
"dashdash": "^1.12.0",
|
||||
"ecc-jsbn": "~0.1.1",
|
||||
"getpass": "^0.1.1",
|
||||
"jsbn": "~0.1.0",
|
||||
"safer-buffer": "^2.0.2",
|
||||
"tweetnacl": "~0.14.0"
|
||||
},
|
||||
"bin": {
|
||||
"sshpk-conv": "bin/sshpk-conv",
|
||||
"sshpk-sign": "bin/sshpk-sign",
|
||||
"sshpk-verify": "bin/sshpk-verify"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/stack-trace": {
|
||||
"version": "0.0.10",
|
||||
"resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz",
|
||||
@ -3806,18 +3558,6 @@
|
||||
"tmp": "^0.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/tough-cookie": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
|
||||
"integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
|
||||
"dependencies": {
|
||||
"psl": "^1.1.28",
|
||||
"punycode": "^2.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/tr46": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
||||
@ -3843,22 +3583,6 @@
|
||||
"integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/tunnel-agent": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
|
||||
"integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==",
|
||||
"dependencies": {
|
||||
"safe-buffer": "^5.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/tweetnacl": {
|
||||
"version": "0.14.5",
|
||||
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
|
||||
"integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA=="
|
||||
},
|
||||
"node_modules/type-check": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
|
||||
@ -3903,6 +3627,7 @@
|
||||
"version": "4.4.1",
|
||||
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
|
||||
"integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"punycode": "^2.1.0"
|
||||
}
|
||||
@ -3918,15 +3643,6 @@
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
|
||||
},
|
||||
"node_modules/uuid": {
|
||||
"version": "3.4.0",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
|
||||
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
|
||||
"deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.",
|
||||
"bin": {
|
||||
"uuid": "bin/uuid"
|
||||
}
|
||||
},
|
||||
"node_modules/verror": {
|
||||
"version": "1.10.1",
|
||||
"resolved": "https://registry.npmjs.org/verror/-/verror-1.10.1.tgz",
|
||||
@ -4085,9 +3801,9 @@
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
|
||||
},
|
||||
"node_modules/yargs": {
|
||||
"version": "17.6.2",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz",
|
||||
"integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==",
|
||||
"version": "17.7.1",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz",
|
||||
"integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"cliui": "^8.0.1",
|
||||
|
23
package.json
23
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "helioslauncher",
|
||||
"version": "1.10.0",
|
||||
"version": "2.0.0-rc.3",
|
||||
"productName": "Helios Launcher",
|
||||
"description": "Modded Minecraft Launcher",
|
||||
"author": "Daniel Scalzi (https://github.com/dscalzi/)",
|
||||
@ -25,27 +25,22 @@
|
||||
"dependencies": {
|
||||
"@electron/remote": "^2.0.8",
|
||||
"adm-zip": "^0.5.9",
|
||||
"async": "^3.2.4",
|
||||
"discord-rpc-patch": "^4.0.1",
|
||||
"ejs": "^3.1.8",
|
||||
"ejs": "^3.1.9",
|
||||
"ejs-electron": "^2.1.1",
|
||||
"electron-updater": "^5.3.0",
|
||||
"fs-extra": "^11.1.0",
|
||||
"fs-extra": "^11.1.1",
|
||||
"github-syntax-dark": "^0.5.0",
|
||||
"got": "^11.8.5",
|
||||
"helios-core": "~0.1.2",
|
||||
"jquery": "^3.6.1",
|
||||
"node-disk-info": "^1.3.0",
|
||||
"node-stream-zip": "^1.15.0",
|
||||
"request": "^2.88.2",
|
||||
"semver": "^7.3.8",
|
||||
"tar-fs": "^2.1.1",
|
||||
"winreg": "^1.2.4"
|
||||
"helios-core": "~2.0.0",
|
||||
"helios-distribution-types": "^1.2.0",
|
||||
"jquery": "^3.6.4",
|
||||
"semver": "^7.3.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"electron": "^23.0.0",
|
||||
"electron": "^23.2.0",
|
||||
"electron-builder": "^23.6.0",
|
||||
"eslint": "^8.34.0"
|
||||
"eslint": "^8.36.0"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
Loading…
Reference in New Issue
Block a user