Merge branch 'master' into master
This commit is contained in:
commit
6db1c993bb
10
app/app.ejs
10
app/app.ejs
@ -1,7 +1,9 @@
|
|||||||
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
|
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" http-equiv="Content-Security-Policy" content="script-src 'self' 'sha256-In6B8teKZQll5heMl9bS7CESTbGvuAt3VVV86BUQBDk='"/>
|
<meta charset="utf-8" http-equiv="Content-Security-Policy" content="script-src 'self' 'sha256-In6B8teKZQll5heMl9bS7CESTbGvuAt3VVV86BUQBDk='"/>
|
||||||
<title>Fromagerie Launcher</title>
|
|
||||||
|
<title><%= lang('app.title') %></title>
|
||||||
|
|
||||||
<script src="./assets/js/scripts/uicore.js"></script>
|
<script src="./assets/js/scripts/uicore.js"></script>
|
||||||
<script src="./assets/js/scripts/uibinder.js"></script>
|
<script src="./assets/js/scripts/uibinder.js"></script>
|
||||||
<link type="text/css" rel="stylesheet" href="./assets/css/launcher.css">
|
<link type="text/css" rel="stylesheet" href="./assets/css/launcher.css">
|
||||||
@ -45,11 +47,5 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
|
||||||
// Load language
|
|
||||||
for(let key of Object.keys(Lang.query('html'))){
|
|
||||||
document.getElementById(key).innerHTML = Lang.query(`html.${key}`)
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
@ -5,15 +5,17 @@ const logger = LoggerUtil.getLogger('DiscordWrapper')
|
|||||||
|
|
||||||
const { Client } = require('discord-rpc-patch')
|
const { Client } = require('discord-rpc-patch')
|
||||||
|
|
||||||
|
const Lang = require('./langloader')
|
||||||
|
|
||||||
let client
|
let client
|
||||||
let activity
|
let activity
|
||||||
|
|
||||||
exports.initRPC = function(genSettings, servSettings, initialDetails = 'Waiting for Client..'){
|
exports.initRPC = function(genSettings, servSettings, initialDetails = Lang.queryJS('discord.waiting')){
|
||||||
client = new Client({ transport: 'ipc' })
|
client = new Client({ transport: 'ipc' })
|
||||||
|
|
||||||
activity = {
|
activity = {
|
||||||
details: initialDetails,
|
details: initialDetails,
|
||||||
state: 'Server: ' + servSettings.shortId,
|
state: Lang.queryJS('discord.state', {shortId: servSettings.shortId}),
|
||||||
largeImageKey: servSettings.largeImageKey,
|
largeImageKey: servSettings.largeImageKey,
|
||||||
largeImageText: servSettings.largeImageText,
|
largeImageText: servSettings.largeImageText,
|
||||||
smallImageKey: genSettings.smallImageKey,
|
smallImageKey: genSettings.smallImageKey,
|
||||||
|
@ -1,21 +1,43 @@
|
|||||||
const fs = require('fs-extra')
|
const fs = require('fs-extra')
|
||||||
const path = require('path')
|
const path = require('path')
|
||||||
|
const toml = require('toml')
|
||||||
|
const merge = require('lodash.merge')
|
||||||
|
|
||||||
let lang
|
let lang
|
||||||
|
|
||||||
exports.loadLanguage = function(id){
|
exports.loadLanguage = function(id){
|
||||||
lang = JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'lang', `${id}.json`))) || {}
|
lang = merge(lang || {}, toml.parse(fs.readFileSync(path.join(__dirname, '..', 'lang', `${id}.toml`))) || {})
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.query = function(id){
|
exports.query = function(id, placeHolders){
|
||||||
let query = id.split('.')
|
let query = id.split('.')
|
||||||
let res = lang
|
let res = lang
|
||||||
for(let q of query){
|
for(let q of query){
|
||||||
res = res[q]
|
res = res[q]
|
||||||
}
|
}
|
||||||
return res === lang ? {} : res
|
let text = res === lang ? '' : res
|
||||||
|
if (placeHolders) {
|
||||||
|
Object.entries(placeHolders).forEach(([key, value]) => {
|
||||||
|
text = text.replace(`{${key}}`, value)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return text
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.queryJS = function(id){
|
exports.queryJS = function(id, placeHolders){
|
||||||
return exports.query(`js.${id}`)
|
return exports.query(`js.${id}`, placeHolders)
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.queryEJS = function(id, placeHolders){
|
||||||
|
return exports.query(`ejs.${id}`, placeHolders)
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.setupLanguage = function(){
|
||||||
|
// Load Language Files
|
||||||
|
exports.loadLanguage('en_US')
|
||||||
|
// Uncomment this when translations are ready
|
||||||
|
//exports.loadLanguage('xx_XX')
|
||||||
|
|
||||||
|
// Load Custom Language File for Launcher Customizer
|
||||||
|
exports.loadLanguage('_custom')
|
||||||
}
|
}
|
@ -23,7 +23,7 @@ DistroAPI['commonDir'] = ConfigManager.getCommonDirectory()
|
|||||||
DistroAPI['instanceDir'] = ConfigManager.getInstanceDirectory()
|
DistroAPI['instanceDir'] = ConfigManager.getInstanceDirectory()
|
||||||
|
|
||||||
// Load Strings
|
// Load Strings
|
||||||
LangLoader.loadLanguage('en_US')
|
LangLoader.setupLanguage()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -12,14 +12,23 @@ const ConfigManager = require('./configmanager')
|
|||||||
|
|
||||||
const logger = LoggerUtil.getLogger('ProcessBuilder')
|
const logger = LoggerUtil.getLogger('ProcessBuilder')
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Only forge and fabric are top level mod loaders.
|
||||||
|
*
|
||||||
|
* Forge 1.13+ launch logic is similar to fabrics, for now using usingFabricLoader flag to
|
||||||
|
* change minor details when needed.
|
||||||
|
*
|
||||||
|
* Rewrite of this module may be needed in the future.
|
||||||
|
*/
|
||||||
class ProcessBuilder {
|
class ProcessBuilder {
|
||||||
|
|
||||||
constructor(distroServer, versionData, forgeData, authUser, launcherVersion){
|
constructor(distroServer, vanillaManifest, modManifest, authUser, launcherVersion){
|
||||||
this.gameDir = path.join(ConfigManager.getInstanceDirectory(), distroServer.rawServer.id)
|
this.gameDir = path.join(ConfigManager.getInstanceDirectory(), distroServer.rawServer.id)
|
||||||
this.commonDir = ConfigManager.getCommonDirectory()
|
this.commonDir = ConfigManager.getCommonDirectory()
|
||||||
this.server = distroServer
|
this.server = distroServer
|
||||||
this.versionData = versionData
|
this.vanillaManifest = vanillaManifest
|
||||||
this.forgeData = forgeData
|
this.modManifest = modManifest
|
||||||
this.authUser = authUser
|
this.authUser = authUser
|
||||||
this.launcherVersion = launcherVersion
|
this.launcherVersion = launcherVersion
|
||||||
this.forgeModListFile = path.join(this.gameDir, 'forgeMods.list') // 1.13+
|
this.forgeModListFile = path.join(this.gameDir, 'forgeMods.list') // 1.13+
|
||||||
@ -28,6 +37,7 @@ class ProcessBuilder {
|
|||||||
this.libPath = path.join(this.commonDir, 'libraries')
|
this.libPath = path.join(this.commonDir, 'libraries')
|
||||||
|
|
||||||
this.usingLiteLoader = false
|
this.usingLiteLoader = false
|
||||||
|
this.usingFabricLoader = false
|
||||||
this.llPath = null
|
this.llPath = null
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -40,9 +50,12 @@ class ProcessBuilder {
|
|||||||
process.throwDeprecation = true
|
process.throwDeprecation = true
|
||||||
this.setupLiteLoader()
|
this.setupLiteLoader()
|
||||||
logger.info('Using liteloader:', this.usingLiteLoader)
|
logger.info('Using liteloader:', this.usingLiteLoader)
|
||||||
|
this.usingFabricLoader = this.server.modules.some(mdl => mdl.rawModule.type === Type.Fabric)
|
||||||
|
logger.info('Using fabric loader:', this.usingFabricLoader)
|
||||||
const modObj = this.resolveModConfiguration(ConfigManager.getModConfiguration(this.server.rawServer.id).mods, this.server.modules)
|
const modObj = this.resolveModConfiguration(ConfigManager.getModConfiguration(this.server.rawServer.id).mods, this.server.modules)
|
||||||
|
|
||||||
// Mod list below 1.13
|
// Mod list below 1.13
|
||||||
|
// Fabric only supports 1.14+
|
||||||
if(!mcVersionAtLeast('1.13', this.server.rawServer.minecraftVersion)){
|
if(!mcVersionAtLeast('1.13', this.server.rawServer.minecraftVersion)){
|
||||||
this.constructJSONModList('forge', modObj.fMods, true)
|
this.constructJSONModList('forge', modObj.fMods, true)
|
||||||
if(this.usingLiteLoader){
|
if(this.usingLiteLoader){
|
||||||
@ -166,7 +179,7 @@ class ProcessBuilder {
|
|||||||
|
|
||||||
for(let mdl of mdls){
|
for(let mdl of mdls){
|
||||||
const type = mdl.rawModule.type
|
const type = mdl.rawModule.type
|
||||||
if(type === Type.ForgeMod || type === Type.LiteMod || type === Type.LiteLoader){
|
if(type === Type.ForgeMod || type === Type.LiteMod || type === Type.LiteLoader || type === Type.FabricMod){
|
||||||
const o = !mdl.getRequired().value
|
const o = !mdl.getRequired().value
|
||||||
const e = ProcessBuilder.isModEnabled(modCfg[mdl.getVersionlessMavenIdentifier()], mdl.getRequired())
|
const e = ProcessBuilder.isModEnabled(modCfg[mdl.getVersionlessMavenIdentifier()], mdl.getRequired())
|
||||||
if(!o || (o && e)){
|
if(!o || (o && e)){
|
||||||
@ -178,7 +191,7 @@ class ProcessBuilder {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(type === Type.ForgeMod){
|
if(type === Type.ForgeMod || type === Type.FabricMod){
|
||||||
fMods.push(mdl)
|
fMods.push(mdl)
|
||||||
} else {
|
} else {
|
||||||
lMods.push(mdl)
|
lMods.push(mdl)
|
||||||
@ -194,7 +207,7 @@ class ProcessBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_lteMinorVersion(version) {
|
_lteMinorVersion(version) {
|
||||||
return Number(this.forgeData.id.split('-')[0].split('.')[1]) <= Number(version)
|
return Number(this.modManifest.id.split('-')[0].split('.')[1]) <= Number(version)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -206,7 +219,7 @@ class ProcessBuilder {
|
|||||||
if(this._lteMinorVersion(9)) {
|
if(this._lteMinorVersion(9)) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
const ver = this.forgeData.id.split('-')[2]
|
const ver = this.modManifest.id.split('-')[2]
|
||||||
const pts = ver.split('.')
|
const pts = ver.split('.')
|
||||||
const min = [14, 23, 3, 2655]
|
const min = [14, 23, 3, 2655]
|
||||||
for(let i=0; i<pts.length; i++){
|
for(let i=0; i<pts.length; i++){
|
||||||
@ -282,18 +295,21 @@ class ProcessBuilder {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct the mod argument list for forge 1.13
|
* Construct the mod argument list for forge 1.13 and Fabric
|
||||||
*
|
*
|
||||||
* @param {Array.<Object>} mods An array of mods to add to the mod list.
|
* @param {Array.<Object>} mods An array of mods to add to the mod list.
|
||||||
*/
|
*/
|
||||||
constructModList(mods) {
|
constructModList(mods) {
|
||||||
const writeBuffer = mods.map(mod => {
|
const writeBuffer = mods.map(mod => {
|
||||||
return mod.getExtensionlessMavenIdentifier()
|
return this.usingFabricLoader ? mod.getPath() : mod.getExtensionlessMavenIdentifier()
|
||||||
}).join('\n')
|
}).join('\n')
|
||||||
|
|
||||||
if(writeBuffer) {
|
if(writeBuffer) {
|
||||||
fs.writeFileSync(this.forgeModListFile, writeBuffer, 'UTF-8')
|
fs.writeFileSync(this.forgeModListFile, writeBuffer, 'UTF-8')
|
||||||
return [
|
return this.usingFabricLoader ? [
|
||||||
|
'--fabric.addMods',
|
||||||
|
`@${this.forgeModListFile}`
|
||||||
|
] : [
|
||||||
'--fml.mavenRoots',
|
'--fml.mavenRoots',
|
||||||
path.join('..', '..', 'common', 'modstore'),
|
path.join('..', '..', 'common', 'modstore'),
|
||||||
'--fml.modLists',
|
'--fml.modLists',
|
||||||
@ -307,12 +323,17 @@ class ProcessBuilder {
|
|||||||
|
|
||||||
_processAutoConnectArg(args){
|
_processAutoConnectArg(args){
|
||||||
if(ConfigManager.getAutoConnect() && this.server.rawServer.autoconnect){
|
if(ConfigManager.getAutoConnect() && this.server.rawServer.autoconnect){
|
||||||
|
if(mcVersionAtLeast('1.20', this.server.rawServer.minecraftVersion)){
|
||||||
|
args.push('--quickPlayMultiplayer')
|
||||||
|
args.push(`${this.server.hostname}:${this.server.port}`)
|
||||||
|
} else {
|
||||||
args.push('--server')
|
args.push('--server')
|
||||||
args.push(this.server.hostname)
|
args.push(this.server.hostname)
|
||||||
args.push('--port')
|
args.push('--port')
|
||||||
args.push(this.server.port)
|
args.push(this.server.port)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct the argument array that will be passed to the JVM process.
|
* Construct the argument array that will be passed to the JVM process.
|
||||||
@ -356,7 +377,7 @@ class ProcessBuilder {
|
|||||||
args.push('-Djava.library.path=' + tempNativePath)
|
args.push('-Djava.library.path=' + tempNativePath)
|
||||||
|
|
||||||
// Main Java Class
|
// Main Java Class
|
||||||
args.push(this.forgeData.mainClass)
|
args.push(this.modManifest.mainClass)
|
||||||
|
|
||||||
// Forge Arguments
|
// Forge Arguments
|
||||||
args = args.concat(this._resolveForgeArgs())
|
args = args.concat(this._resolveForgeArgs())
|
||||||
@ -379,17 +400,17 @@ class ProcessBuilder {
|
|||||||
const argDiscovery = /\${*(.*)}/
|
const argDiscovery = /\${*(.*)}/
|
||||||
|
|
||||||
// JVM Arguments First
|
// JVM Arguments First
|
||||||
let args = this.versionData.arguments.jvm
|
let args = this.vanillaManifest.arguments.jvm
|
||||||
|
|
||||||
// Debug securejarhandler
|
// Debug securejarhandler
|
||||||
// args.push('-Dbsl.debug=true')
|
// args.push('-Dbsl.debug=true')
|
||||||
|
|
||||||
if(this.forgeData.arguments.jvm != null) {
|
if(this.modManifest.arguments.jvm != null) {
|
||||||
for(const argStr of this.forgeData.arguments.jvm) {
|
for(const argStr of this.modManifest.arguments.jvm) {
|
||||||
args.push(argStr
|
args.push(argStr
|
||||||
.replaceAll('${library_directory}', this.libPath)
|
.replaceAll('${library_directory}', this.libPath)
|
||||||
.replaceAll('${classpath_separator}', ProcessBuilder.getClasspathSeparator())
|
.replaceAll('${classpath_separator}', ProcessBuilder.getClasspathSeparator())
|
||||||
.replaceAll('${version_name}', this.forgeData.id)
|
.replaceAll('${version_name}', this.modManifest.id)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -406,10 +427,10 @@ class ProcessBuilder {
|
|||||||
args = args.concat(ConfigManager.getJVMOptions(this.server.rawServer.id))
|
args = args.concat(ConfigManager.getJVMOptions(this.server.rawServer.id))
|
||||||
|
|
||||||
// Main Java Class
|
// Main Java Class
|
||||||
args.push(this.forgeData.mainClass)
|
args.push(this.modManifest.mainClass)
|
||||||
|
|
||||||
// Vanilla Arguments
|
// Vanilla Arguments
|
||||||
args = args.concat(this.versionData.arguments.game)
|
args = args.concat(this.vanillaManifest.arguments.game)
|
||||||
|
|
||||||
for(let i=0; i<args.length; i++){
|
for(let i=0; i<args.length; i++){
|
||||||
if(typeof args[i] === 'object' && args[i].rules != null){
|
if(typeof args[i] === 'object' && args[i].rules != null){
|
||||||
@ -466,7 +487,7 @@ class ProcessBuilder {
|
|||||||
val = this.authUser.displayName.trim()
|
val = this.authUser.displayName.trim()
|
||||||
break
|
break
|
||||||
case 'version_name':
|
case 'version_name':
|
||||||
//val = versionData.id
|
//val = vanillaManifest.id
|
||||||
val = this.server.rawServer.id
|
val = this.server.rawServer.id
|
||||||
break
|
break
|
||||||
case 'game_directory':
|
case 'game_directory':
|
||||||
@ -476,7 +497,7 @@ class ProcessBuilder {
|
|||||||
val = path.join(this.commonDir, 'assets')
|
val = path.join(this.commonDir, 'assets')
|
||||||
break
|
break
|
||||||
case 'assets_index_name':
|
case 'assets_index_name':
|
||||||
val = this.versionData.assets
|
val = this.vanillaManifest.assets
|
||||||
break
|
break
|
||||||
case 'auth_uuid':
|
case 'auth_uuid':
|
||||||
val = this.authUser.uuid.trim()
|
val = this.authUser.uuid.trim()
|
||||||
@ -488,7 +509,7 @@ class ProcessBuilder {
|
|||||||
val = this.authUser.type === 'microsoft' ? 'msa' : 'mojang'
|
val = this.authUser.type === 'microsoft' ? 'msa' : 'mojang'
|
||||||
break
|
break
|
||||||
case 'version_type':
|
case 'version_type':
|
||||||
val = this.versionData.type
|
val = this.vanillaManifest.type
|
||||||
break
|
break
|
||||||
case 'resolution_width':
|
case 'resolution_width':
|
||||||
val = ConfigManager.getGameWidth()
|
val = ConfigManager.getGameWidth()
|
||||||
@ -517,25 +538,11 @@ class ProcessBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Autoconnect
|
// Autoconnect
|
||||||
let isAutoconnectBroken
|
|
||||||
try {
|
|
||||||
isAutoconnectBroken = ProcessBuilder.isAutoconnectBroken(this.forgeData.id.split('-')[2])
|
|
||||||
} catch(err) {
|
|
||||||
logger.error(err)
|
|
||||||
logger.error('Forge version format changed.. assuming autoconnect works.')
|
|
||||||
logger.debug('Forge version:', this.forgeData.id)
|
|
||||||
}
|
|
||||||
|
|
||||||
if(isAutoconnectBroken) {
|
|
||||||
logger.error('Server autoconnect disabled on Forge 1.15.2 for builds earlier than 31.2.15 due to OpenGL Stack Overflow issue.')
|
|
||||||
logger.error('Please upgrade your Forge version to at least 31.2.15!')
|
|
||||||
} else {
|
|
||||||
this._processAutoConnectArg(args)
|
this._processAutoConnectArg(args)
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Forge Specific Arguments
|
// Forge Specific Arguments
|
||||||
args = args.concat(this.forgeData.arguments.game)
|
args = args.concat(this.modManifest.arguments.game)
|
||||||
|
|
||||||
// Filter null values
|
// Filter null values
|
||||||
args = args.filter(arg => {
|
args = args.filter(arg => {
|
||||||
@ -551,7 +558,7 @@ class ProcessBuilder {
|
|||||||
* @returns {Array.<string>} An array containing the arguments required by forge.
|
* @returns {Array.<string>} An array containing the arguments required by forge.
|
||||||
*/
|
*/
|
||||||
_resolveForgeArgs(){
|
_resolveForgeArgs(){
|
||||||
const mcArgs = this.forgeData.minecraftArguments.split(' ')
|
const mcArgs = this.modManifest.minecraftArguments.split(' ')
|
||||||
const argDiscovery = /\${*(.*)}/
|
const argDiscovery = /\${*(.*)}/
|
||||||
|
|
||||||
// Replace the declared variables with their proper values.
|
// Replace the declared variables with their proper values.
|
||||||
@ -564,7 +571,7 @@ class ProcessBuilder {
|
|||||||
val = this.authUser.displayName.trim()
|
val = this.authUser.displayName.trim()
|
||||||
break
|
break
|
||||||
case 'version_name':
|
case 'version_name':
|
||||||
//val = versionData.id
|
//val = vanillaManifest.id
|
||||||
val = this.server.rawServer.id
|
val = this.server.rawServer.id
|
||||||
break
|
break
|
||||||
case 'game_directory':
|
case 'game_directory':
|
||||||
@ -574,7 +581,7 @@ class ProcessBuilder {
|
|||||||
val = path.join(this.commonDir, 'assets')
|
val = path.join(this.commonDir, 'assets')
|
||||||
break
|
break
|
||||||
case 'assets_index_name':
|
case 'assets_index_name':
|
||||||
val = this.versionData.assets
|
val = this.vanillaManifest.assets
|
||||||
break
|
break
|
||||||
case 'auth_uuid':
|
case 'auth_uuid':
|
||||||
val = this.authUser.uuid.trim()
|
val = this.authUser.uuid.trim()
|
||||||
@ -589,7 +596,7 @@ class ProcessBuilder {
|
|||||||
val = '{}'
|
val = '{}'
|
||||||
break
|
break
|
||||||
case 'version_type':
|
case 'version_type':
|
||||||
val = this.versionData.type
|
val = this.vanillaManifest.type
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if(val != null){
|
if(val != null){
|
||||||
@ -664,10 +671,10 @@ class ProcessBuilder {
|
|||||||
classpathArg(mods, tempNativePath){
|
classpathArg(mods, tempNativePath){
|
||||||
let cpArgs = []
|
let cpArgs = []
|
||||||
|
|
||||||
if(!mcVersionAtLeast('1.17', this.server.rawServer.minecraftVersion)) {
|
if(!mcVersionAtLeast('1.17', this.server.rawServer.minecraftVersion) || this.usingFabricLoader) {
|
||||||
// Add the version.jar to the classpath.
|
// Add the version.jar to the classpath.
|
||||||
// Must not be added to the classpath for Forge 1.17+.
|
// Must not be added to the classpath for Forge 1.17+.
|
||||||
const version = this.versionData.id
|
const version = this.vanillaManifest.id
|
||||||
cpArgs.push(path.join(this.commonDir, 'versions', version, version + '.jar'))
|
cpArgs.push(path.join(this.commonDir, 'versions', version, version + '.jar'))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -706,7 +713,7 @@ class ProcessBuilder {
|
|||||||
const nativesRegex = /.+:natives-([^-]+)(?:-(.+))?/
|
const nativesRegex = /.+:natives-([^-]+)(?:-(.+))?/
|
||||||
const libs = {}
|
const libs = {}
|
||||||
|
|
||||||
const libArr = this.versionData.libraries
|
const libArr = this.vanillaManifest.libraries
|
||||||
fs.ensureDirSync(tempNativePath)
|
fs.ensureDirSync(tempNativePath)
|
||||||
for(let i=0; i<libArr.length; i++){
|
for(let i=0; i<libArr.length; i++){
|
||||||
const lib = libArr[i]
|
const lib = libArr[i]
|
||||||
@ -825,10 +832,10 @@ class ProcessBuilder {
|
|||||||
const mdls = this.server.modules
|
const mdls = this.server.modules
|
||||||
let libs = {}
|
let libs = {}
|
||||||
|
|
||||||
// Locate Forge/Libraries
|
// Locate Forge/Fabric/Libraries
|
||||||
for(let mdl of mdls){
|
for(let mdl of mdls){
|
||||||
const type = mdl.rawModule.type
|
const type = mdl.rawModule.type
|
||||||
if(type === Type.ForgeHosted || type === Type.Library){
|
if(type === Type.ForgeHosted || type === Type.Fabric || type === Type.Library){
|
||||||
libs[mdl.getVersionlessMavenIdentifier()] = mdl.getPath()
|
libs[mdl.getVersionlessMavenIdentifier()] = mdl.getPath()
|
||||||
if(mdl.subModules.length > 0){
|
if(mdl.subModules.length > 0){
|
||||||
const res = this._resolveModuleLibraries(mdl)
|
const res = this._resolveModuleLibraries(mdl)
|
||||||
@ -882,24 +889,6 @@ class ProcessBuilder {
|
|||||||
return libs
|
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
|
module.exports = ProcessBuilder
|
@ -2,8 +2,6 @@
|
|||||||
* Script for landing.ejs
|
* Script for landing.ejs
|
||||||
*/
|
*/
|
||||||
// Requirements
|
// Requirements
|
||||||
const cp = require('child_process')
|
|
||||||
const crypto = require('crypto')
|
|
||||||
const { URL } = require('url')
|
const { URL } = require('url')
|
||||||
const {
|
const {
|
||||||
MojangRestAPI,
|
MojangRestAPI,
|
||||||
@ -125,7 +123,7 @@ document.getElementById('launch_button').addEventListener('click', async e => {
|
|||||||
}
|
}
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
loggerLanding.error('Unhandled error in during launch process.', err)
|
loggerLanding.error('Unhandled error in during launch process.', err)
|
||||||
showLaunchFailure('Error During Launch', 'See console (CTRL + Shift + i) for more details.')
|
showLaunchFailure(Lang.queryJS('landing.launch.failureTitle'), Lang.queryJS('landing.launch.failureText'))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -145,7 +143,7 @@ document.getElementById('avatarOverlay').onclick = async e => {
|
|||||||
|
|
||||||
// Bind selected account
|
// Bind selected account
|
||||||
function updateSelectedAccount(authUser){
|
function updateSelectedAccount(authUser){
|
||||||
let username = 'No Account Selected'
|
let username = Lang.queryJS('landing.selectedAccount.noAccountSelected')
|
||||||
if(authUser != null){
|
if(authUser != null){
|
||||||
if(authUser.displayName != null){
|
if(authUser.displayName != null){
|
||||||
username = authUser.displayName
|
username = authUser.displayName
|
||||||
@ -165,14 +163,14 @@ function updateSelectedServer(serv){
|
|||||||
}
|
}
|
||||||
ConfigManager.setSelectedServer(serv != null ? serv.rawServer.id : null)
|
ConfigManager.setSelectedServer(serv != null ? serv.rawServer.id : null)
|
||||||
ConfigManager.save()
|
ConfigManager.save()
|
||||||
server_selection_button.innerHTML = '\u2022 ' + (serv != null ? serv.rawServer.name : 'No Server Selected')
|
server_selection_button.innerHTML = '• ' + (serv != null ? serv.rawServer.name : Lang.queryJS('landing.noSelection'))
|
||||||
if(getCurrentView() === VIEWS.settings){
|
if(getCurrentView() === VIEWS.settings){
|
||||||
animateSettingsTabRefresh()
|
animateSettingsTabRefresh()
|
||||||
}
|
}
|
||||||
setLaunchEnabled(serv != null)
|
setLaunchEnabled(serv != null)
|
||||||
}
|
}
|
||||||
// Real text is set in uibinder.js on distributionIndexDone.
|
// Real text is set in uibinder.js on distributionIndexDone.
|
||||||
server_selection_button.innerHTML = '\u2022 Loading..'
|
server_selection_button.innerHTML = '• ' + Lang.queryJS('landing.selectedServer.loading')
|
||||||
server_selection_button.onclick = async e => {
|
server_selection_button.onclick = async e => {
|
||||||
e.target.blur()
|
e.target.blur()
|
||||||
await toggleServerSelection(true)
|
await toggleServerSelection(true)
|
||||||
@ -201,16 +199,14 @@ const refreshMojangStatuses = async function(){
|
|||||||
for(let i=0; i<statuses.length; i++){
|
for(let i=0; i<statuses.length; i++){
|
||||||
const service = statuses[i]
|
const service = statuses[i]
|
||||||
|
|
||||||
|
const tooltipHTML = `<div class="mojangStatusContainer">
|
||||||
|
<span class="mojangStatusIcon" style="color: ${MojangRestAPI.statusToHex(service.status)};">•</span>
|
||||||
|
<span class="mojangStatusName">${service.name}</span>
|
||||||
|
</div>`
|
||||||
if(service.essential){
|
if(service.essential){
|
||||||
tooltipEssentialHTML += `<div class="mojangStatusContainer">
|
tooltipEssentialHTML += tooltipHTML
|
||||||
<span class="mojangStatusIcon" style="color: ${MojangRestAPI.statusToHex(service.status)};">•</span>
|
|
||||||
<span class="mojangStatusName">${service.name}</span>
|
|
||||||
</div>`
|
|
||||||
} else {
|
} else {
|
||||||
tooltipNonEssentialHTML += `<div class="mojangStatusContainer">
|
tooltipNonEssentialHTML += tooltipHTML
|
||||||
<span class="mojangStatusIcon" style="color: ${MojangRestAPI.statusToHex(service.status)};">•</span>
|
|
||||||
<span class="mojangStatusName">${service.name}</span>
|
|
||||||
</div>`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(service.status === 'yellow' && status !== 'red'){
|
if(service.status === 'yellow' && status !== 'red'){
|
||||||
@ -243,14 +239,15 @@ const refreshServerStatus = async (fade = false) => {
|
|||||||
loggerLanding.info('Refreshing Server Status')
|
loggerLanding.info('Refreshing Server Status')
|
||||||
const serv = (await DistroAPI.getDistribution()).getServerById(ConfigManager.getSelectedServer())
|
const serv = (await DistroAPI.getDistribution()).getServerById(ConfigManager.getSelectedServer())
|
||||||
|
|
||||||
let pLabel = 'SERVER'
|
|
||||||
let pVal = 'OFFLINE'
|
let pLabel = Lang.queryJS('landing.serverStatus.server')
|
||||||
|
let pVal = Lang.queryJS('landing.serverStatus.offline')
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
const servStat = await getServerStatus(47, serv.address, serv.port)
|
const servStat = await getServerStatus(47, serv.address, serv.port)
|
||||||
console.log(servStat)
|
console.log(servStat)
|
||||||
pLabel = 'PLAYERS'
|
pLabel = Lang.queryJS('landing.serverStatus.players')
|
||||||
pVal = servStat.players.online + '/' + servStat.players.max
|
pVal = servStat.players.online + '/' + servStat.players.max
|
||||||
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@ -288,7 +285,7 @@ function showLaunchFailure(title, desc){
|
|||||||
setOverlayContent(
|
setOverlayContent(
|
||||||
title,
|
title,
|
||||||
desc,
|
desc,
|
||||||
'Okay'
|
Lang.queryJS('landing.launch.okay')
|
||||||
)
|
)
|
||||||
setOverlayHandler(null)
|
setOverlayHandler(null)
|
||||||
toggleOverlay(true)
|
toggleOverlay(true)
|
||||||
@ -304,7 +301,7 @@ function showLaunchFailure(title, desc){
|
|||||||
*/
|
*/
|
||||||
async function asyncSystemScan(effectiveJavaOptions, launchAfter = true){
|
async function asyncSystemScan(effectiveJavaOptions, launchAfter = true){
|
||||||
|
|
||||||
setLaunchDetails('Checking system info..')
|
setLaunchDetails(Lang.queryJS('landing.systemScan.checking'))
|
||||||
toggleLaunchArea(true)
|
toggleLaunchArea(true)
|
||||||
setLaunchPercentage(0, 100)
|
setLaunchPercentage(0, 100)
|
||||||
|
|
||||||
@ -317,30 +314,30 @@ async function asyncSystemScan(effectiveJavaOptions, launchAfter = true){
|
|||||||
// If the result is null, no valid Java installation was found.
|
// If the result is null, no valid Java installation was found.
|
||||||
// Show this information to the user.
|
// Show this information to the user.
|
||||||
setOverlayContent(
|
setOverlayContent(
|
||||||
'No Compatible<br>Java Installation Found',
|
Lang.queryJS('landing.systemScan.noCompatibleJava'),
|
||||||
`In order to join WesterosCraft, you need a 64-bit installation of Java ${effectiveJavaOptions.suggestedMajor}. Would you like us to install a copy?`,
|
Lang.queryJS('landing.systemScan.installJavaMessage', { 'major': effectiveJavaOptions.suggestedMajor }),
|
||||||
'Install Java',
|
Lang.queryJS('landing.systemScan.installJava'),
|
||||||
'Install Manually'
|
Lang.queryJS('landing.systemScan.installJavaManually')
|
||||||
)
|
)
|
||||||
setOverlayHandler(() => {
|
setOverlayHandler(() => {
|
||||||
setLaunchDetails('Preparing Java Download..')
|
setLaunchDetails(Lang.queryJS('landing.systemScan.javaDownloadPrepare'))
|
||||||
toggleOverlay(false)
|
toggleOverlay(false)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
downloadJava(effectiveJavaOptions, launchAfter)
|
downloadJava(effectiveJavaOptions, launchAfter)
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
loggerLanding.error('Unhandled error in Java Download', err)
|
loggerLanding.error('Unhandled error in Java Download', err)
|
||||||
showLaunchFailure('Error During Java Download', 'See console (CTRL + Shift + i) for more details.')
|
showLaunchFailure(Lang.queryJS('landing.systemScan.javaDownloadFailureTitle'), Lang.queryJS('landing.systemScan.javaDownloadFailureText'))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
setDismissHandler(() => {
|
setDismissHandler(() => {
|
||||||
$('#overlayContent').fadeOut(250, () => {
|
$('#overlayContent').fadeOut(250, () => {
|
||||||
//$('#overlayDismiss').toggle(false)
|
//$('#overlayDismiss').toggle(false)
|
||||||
setOverlayContent(
|
setOverlayContent(
|
||||||
'Java is Required<br>to Launch',
|
Lang.queryJS('landing.systemScan.javaRequired', { 'major': effectiveJavaOptions.suggestedMajor }),
|
||||||
`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.`,
|
Lang.queryJS('landing.systemScan.javaRequiredMessage', { 'major': effectiveJavaOptions.suggestedMajor }),
|
||||||
'I Understand',
|
Lang.queryJS('landing.systemScan.javaRequiredDismiss'),
|
||||||
'Go Back'
|
Lang.queryJS('landing.systemScan.javaRequiredCancel')
|
||||||
)
|
)
|
||||||
setOverlayHandler(() => {
|
setOverlayHandler(() => {
|
||||||
toggleLaunchArea(false)
|
toggleLaunchArea(false)
|
||||||
@ -385,7 +382,7 @@ async function downloadJava(effectiveJavaOptions, launchAfter = true) {
|
|||||||
effectiveJavaOptions.distribution)
|
effectiveJavaOptions.distribution)
|
||||||
|
|
||||||
if(asset == null) {
|
if(asset == null) {
|
||||||
throw new Error('Failed to find OpenJDK distribution.')
|
throw new Error(Lang.queryJS('landing.downloadJava.findJdkFailure'))
|
||||||
}
|
}
|
||||||
|
|
||||||
let received = 0
|
let received = 0
|
||||||
@ -400,7 +397,7 @@ async function downloadJava(effectiveJavaOptions, launchAfter = true) {
|
|||||||
if(!await validateLocalFile(asset.path, asset.algo, asset.hash)) {
|
if(!await validateLocalFile(asset.path, asset.algo, asset.hash)) {
|
||||||
log.error(`Hashes do not match, ${asset.id} may be corrupted.`)
|
log.error(`Hashes do not match, ${asset.id} may be corrupted.`)
|
||||||
// Don't know how this could happen, but report it.
|
// Don't know how this could happen, but report it.
|
||||||
throw new Error('Downloaded JDK has bad hash, file may be corrupted.')
|
throw new Error(Lang.queryJS('landing.downloadJava.javaDownloadCorruptedError'))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -409,7 +406,7 @@ async function downloadJava(effectiveJavaOptions, launchAfter = true) {
|
|||||||
remote.getCurrentWindow().setProgressBar(2)
|
remote.getCurrentWindow().setProgressBar(2)
|
||||||
|
|
||||||
// Wait for extration to complete.
|
// Wait for extration to complete.
|
||||||
const eLStr = 'Extracting Java'
|
const eLStr = Lang.queryJS('landing.downloadJava.extractingJava')
|
||||||
let dotStr = ''
|
let dotStr = ''
|
||||||
setLaunchDetails(eLStr)
|
setLaunchDetails(eLStr)
|
||||||
const extractListener = setInterval(() => {
|
const extractListener = setInterval(() => {
|
||||||
@ -431,7 +428,7 @@ async function downloadJava(effectiveJavaOptions, launchAfter = true) {
|
|||||||
ConfigManager.save()
|
ConfigManager.save()
|
||||||
|
|
||||||
clearInterval(extractListener)
|
clearInterval(extractListener)
|
||||||
setLaunchDetails('Java Installed!')
|
setLaunchDetails(Lang.queryJS('landing.downloadJava.javaInstalled'))
|
||||||
|
|
||||||
// TODO Callback hell
|
// TODO Callback hell
|
||||||
// Refactor the launch functions
|
// Refactor the launch functions
|
||||||
@ -446,7 +443,7 @@ let hasRPC = false
|
|||||||
// Joined server regex
|
// Joined server regex
|
||||||
// Change this if your server uses something different.
|
// Change this if your server uses something different.
|
||||||
const GAME_JOINED_REGEX = /\[.+\]: Sound engine started/
|
const GAME_JOINED_REGEX = /\[.+\]: Sound engine started/
|
||||||
const GAME_LAUNCH_REGEX = /^\[.+\]: (?:MinecraftForge .+ Initialized|ModLauncher .+ starting: .+)$/
|
const GAME_LAUNCH_REGEX = /^\[.+\]: (?:MinecraftForge .+ Initialized|ModLauncher .+ starting: .+|Loading Minecraft .+ with Fabric Loader .+)$/
|
||||||
const MIN_LINGER = 5000
|
const MIN_LINGER = 5000
|
||||||
|
|
||||||
async function dlAsync(login = true) {
|
async function dlAsync(login = true) {
|
||||||
@ -456,7 +453,7 @@ async function dlAsync(login = true) {
|
|||||||
|
|
||||||
const loggerLaunchSuite = LoggerUtil.getLogger('LaunchSuite')
|
const loggerLaunchSuite = LoggerUtil.getLogger('LaunchSuite')
|
||||||
|
|
||||||
setLaunchDetails('Loading server information..')
|
setLaunchDetails(Lang.queryJS('landing.dlAsync.loadingServerInfo'))
|
||||||
|
|
||||||
let distro
|
let distro
|
||||||
|
|
||||||
@ -465,7 +462,7 @@ async function dlAsync(login = true) {
|
|||||||
onDistroRefresh(distro)
|
onDistroRefresh(distro)
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
loggerLaunchSuite.error('Unable to refresh distribution index.', 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.')
|
showLaunchFailure(Lang.queryJS('landing.dlAsync.fatalError'), Lang.queryJS('landing.dlAsync.unableToLoadDistributionIndex'))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -478,7 +475,7 @@ async function dlAsync(login = true) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setLaunchDetails('Please wait..')
|
setLaunchDetails(Lang.queryJS('landing.dlAsync.pleaseWait'))
|
||||||
toggleLaunchArea(true)
|
toggleLaunchArea(true)
|
||||||
setLaunchPercentage(0, 100)
|
setLaunchPercentage(0, 100)
|
||||||
|
|
||||||
@ -494,17 +491,17 @@ async function dlAsync(login = true) {
|
|||||||
|
|
||||||
fullRepairModule.childProcess.on('error', (err) => {
|
fullRepairModule.childProcess.on('error', (err) => {
|
||||||
loggerLaunchSuite.error('Error during launch', err)
|
loggerLaunchSuite.error('Error during launch', err)
|
||||||
showLaunchFailure('Error During Launch', err.message || 'See console (CTRL + Shift + i) for more details.')
|
showLaunchFailure(Lang.queryJS('landing.dlAsync.errorDuringLaunchTitle'), err.message || Lang.queryJS('landing.dlAsync.errorDuringLaunchText'))
|
||||||
})
|
})
|
||||||
fullRepairModule.childProcess.on('close', (code, _signal) => {
|
fullRepairModule.childProcess.on('close', (code, _signal) => {
|
||||||
if(code !== 0){
|
if(code !== 0){
|
||||||
loggerLaunchSuite.error(`Full Repair Module 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.')
|
showLaunchFailure(Lang.queryJS('landing.dlAsync.errorDuringLaunchTitle'), Lang.queryJS('landing.dlAsync.seeConsoleForDetails'))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
loggerLaunchSuite.info('Validating files.')
|
loggerLaunchSuite.info('Validating files.')
|
||||||
setLaunchDetails('Validating file integrity..')
|
setLaunchDetails(Lang.queryJS('landing.dlAsync.validatingFileIntegrity'))
|
||||||
let invalidFileCount = 0
|
let invalidFileCount = 0
|
||||||
try {
|
try {
|
||||||
invalidFileCount = await fullRepairModule.verifyFiles(percent => {
|
invalidFileCount = await fullRepairModule.verifyFiles(percent => {
|
||||||
@ -513,14 +510,14 @@ async function dlAsync(login = true) {
|
|||||||
setLaunchPercentage(100)
|
setLaunchPercentage(100)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
loggerLaunchSuite.error('Error during file validation.')
|
loggerLaunchSuite.error('Error during file validation.')
|
||||||
showLaunchFailure('Error During File Verification', err.displayable || 'See console (CTRL + Shift + i) for more details.')
|
showLaunchFailure(Lang.queryJS('landing.dlAsync.errorDuringFileVerificationTitle'), err.displayable || Lang.queryJS('landing.dlAsync.seeConsoleForDetails'))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if(invalidFileCount > 0) {
|
if(invalidFileCount > 0) {
|
||||||
loggerLaunchSuite.info('Downloading files.')
|
loggerLaunchSuite.info('Downloading files.')
|
||||||
setLaunchDetails('Downloading files..')
|
setLaunchDetails(Lang.queryJS('landing.dlAsync.downloadingFiles'))
|
||||||
setLaunchPercentage(0)
|
setLaunchPercentage(0)
|
||||||
try {
|
try {
|
||||||
await fullRepairModule.download(percent => {
|
await fullRepairModule.download(percent => {
|
||||||
@ -529,7 +526,7 @@ async function dlAsync(login = true) {
|
|||||||
setDownloadPercentage(100)
|
setDownloadPercentage(100)
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
loggerLaunchSuite.error('Error during file download.')
|
loggerLaunchSuite.error('Error during file download.')
|
||||||
showLaunchFailure('Error During File Download', err.displayable || 'See console (CTRL + Shift + i) for more details.')
|
showLaunchFailure(Lang.queryJS('landing.dlAsync.errorDuringFileDownloadTitle'), err.displayable || Lang.queryJS('landing.dlAsync.seeConsoleForDetails'))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -541,7 +538,7 @@ async function dlAsync(login = true) {
|
|||||||
|
|
||||||
fullRepairModule.destroyReceiver()
|
fullRepairModule.destroyReceiver()
|
||||||
|
|
||||||
setLaunchDetails('Preparing to launch..')
|
setLaunchDetails(Lang.queryJS('landing.dlAsync.preparingToLaunch'))
|
||||||
|
|
||||||
const mojangIndexProcessor = new MojangIndexProcessor(
|
const mojangIndexProcessor = new MojangIndexProcessor(
|
||||||
ConfigManager.getCommonDirectory(),
|
ConfigManager.getCommonDirectory(),
|
||||||
@ -552,14 +549,14 @@ async function dlAsync(login = true) {
|
|||||||
serv.rawServer.id
|
serv.rawServer.id
|
||||||
)
|
)
|
||||||
|
|
||||||
const forgeData = await distributionIndexProcessor.loadForgeVersionJson(serv)
|
const modLoaderData = await distributionIndexProcessor.loadModLoaderVersionJson(serv)
|
||||||
const versionData = await mojangIndexProcessor.getVersionJson()
|
const versionData = await mojangIndexProcessor.getVersionJson()
|
||||||
|
|
||||||
if(login) {
|
if(login) {
|
||||||
const authUser = ConfigManager.getSelectedAccount()
|
const authUser = ConfigManager.getSelectedAccount()
|
||||||
loggerLaunchSuite.info(`Sending selected account (${authUser.displayName}) to ProcessBuilder.`)
|
loggerLaunchSuite.info(`Sending selected account (${authUser.displayName}) to ProcessBuilder.`)
|
||||||
let pb = new ProcessBuilder(serv, versionData, forgeData, authUser, remote.app.getVersion())
|
let pb = new ProcessBuilder(serv, versionData, modLoaderData, authUser, remote.app.getVersion())
|
||||||
setLaunchDetails('Launching game..')
|
setLaunchDetails(Lang.queryJS('landing.dlAsync.launchingGame'))
|
||||||
|
|
||||||
// const SERVER_JOINED_REGEX = /\[.+\]: \[CHAT\] [a-zA-Z0-9_]{1,16} joined the game/
|
// const SERVER_JOINED_REGEX = /\[.+\]: \[CHAT\] [a-zA-Z0-9_]{1,16} joined the game/
|
||||||
const SERVER_JOINED_REGEX = new RegExp(`\\[.+\\]: \\[CHAT\\] ${authUser.displayName} joined the game`)
|
const SERVER_JOINED_REGEX = new RegExp(`\\[.+\\]: \\[CHAT\\] ${authUser.displayName} joined the game`)
|
||||||
@ -567,7 +564,7 @@ async function dlAsync(login = true) {
|
|||||||
const onLoadComplete = () => {
|
const onLoadComplete = () => {
|
||||||
toggleLaunchArea(false)
|
toggleLaunchArea(false)
|
||||||
if(hasRPC){
|
if(hasRPC){
|
||||||
DiscordWrapper.updateDetails('Loading game..')
|
DiscordWrapper.updateDetails(Lang.queryJS('landing.discord.loading'))
|
||||||
proc.stdout.on('data', gameStateChange)
|
proc.stdout.on('data', gameStateChange)
|
||||||
}
|
}
|
||||||
proc.stdout.removeListener('data', tempListener)
|
proc.stdout.removeListener('data', tempListener)
|
||||||
@ -594,9 +591,9 @@ async function dlAsync(login = true) {
|
|||||||
const gameStateChange = function(data){
|
const gameStateChange = function(data){
|
||||||
data = data.trim()
|
data = data.trim()
|
||||||
if(SERVER_JOINED_REGEX.test(data)){
|
if(SERVER_JOINED_REGEX.test(data)){
|
||||||
DiscordWrapper.updateDetails('Exploring the Realm!')
|
DiscordWrapper.updateDetails(Lang.queryJS('landing.discord.joined'))
|
||||||
} else if(GAME_JOINED_REGEX.test(data)){
|
} else if(GAME_JOINED_REGEX.test(data)){
|
||||||
DiscordWrapper.updateDetails('Sailing to Westeros!')
|
DiscordWrapper.updateDetails(Lang.queryJS('landing.discord.joining'))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -604,7 +601,7 @@ async function dlAsync(login = true) {
|
|||||||
data = data.trim()
|
data = data.trim()
|
||||||
if(data.indexOf('Could not find or load main class net.minecraft.launchwrapper.Launch') > -1){
|
if(data.indexOf('Could not find or load main class net.minecraft.launchwrapper.Launch') > -1){
|
||||||
loggerLaunchSuite.error('Game launch failed, LaunchWrapper was not downloaded properly.')
|
loggerLaunchSuite.error('Game launch failed, LaunchWrapper was not downloaded properly.')
|
||||||
showLaunchFailure('Error During Launch', 'The main file, LaunchWrapper, failed to download properly. As a result, the game cannot launch.<br><br>To fix this issue, temporarily turn off your antivirus software and launch the game again.<br><br>If you have time, please <a href="https://github.com/dscalzi/HeliosLauncher/issues">submit an issue</a> and let us know what antivirus software you use. We\'ll contact them and try to straighten things out.')
|
showLaunchFailure(Lang.queryJS('landing.dlAsync.errorDuringLaunchTitle'), Lang.queryJS('landing.dlAsync.launchWrapperNotDownloaded'))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -616,10 +613,10 @@ async function dlAsync(login = true) {
|
|||||||
proc.stdout.on('data', tempListener)
|
proc.stdout.on('data', tempListener)
|
||||||
proc.stderr.on('data', gameErrorListener)
|
proc.stderr.on('data', gameErrorListener)
|
||||||
|
|
||||||
setLaunchDetails('Done. Enjoy the server!')
|
setLaunchDetails(Lang.queryJS('landing.dlAsync.doneEnjoyServer'))
|
||||||
|
|
||||||
// Init Discord Hook
|
// Init Discord Hook
|
||||||
if(distro.rawDistribution.discord != null && serv.rawServerdiscord != null){
|
if(distro.rawDistribution.discord != null && serv.rawServer.discord != null){
|
||||||
DiscordWrapper.initRPC(distro.rawDistribution.discord, serv.rawServer.discord)
|
DiscordWrapper.initRPC(distro.rawDistribution.discord, serv.rawServer.discord)
|
||||||
hasRPC = true
|
hasRPC = true
|
||||||
proc.on('close', (code, signal) => {
|
proc.on('close', (code, signal) => {
|
||||||
@ -633,7 +630,7 @@ async function dlAsync(login = true) {
|
|||||||
} catch(err) {
|
} catch(err) {
|
||||||
|
|
||||||
loggerLaunchSuite.error('Error during launch', err)
|
loggerLaunchSuite.error('Error during launch', err)
|
||||||
showLaunchFailure('Error During Launch', 'Please check the console (CTRL + Shift + i) for more details.')
|
showLaunchFailure(Lang.queryJS('landing.dlAsync.errorDuringLaunchTitle'), Lang.queryJS('landing.dlAsync.checkConsoleForDetails'))
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -740,7 +737,7 @@ let newsLoadingListener = null
|
|||||||
*/
|
*/
|
||||||
function setNewsLoading(val){
|
function setNewsLoading(val){
|
||||||
if(val){
|
if(val){
|
||||||
const nLStr = 'Checking for News'
|
const nLStr = Lang.queryJS('landing.news.checking')
|
||||||
let dotStr = '..'
|
let dotStr = '..'
|
||||||
nELoadSpan.innerHTML = nLStr + dotStr
|
nELoadSpan.innerHTML = nLStr + dotStr
|
||||||
newsLoadingListener = setInterval(() => {
|
newsLoadingListener = setInterval(() => {
|
||||||
@ -802,6 +799,16 @@ function showNewsAlert(){
|
|||||||
$(newsButtonAlert).fadeIn(250)
|
$(newsButtonAlert).fadeIn(250)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function digestMessage(str) {
|
||||||
|
const msgUint8 = new TextEncoder().encode(str)
|
||||||
|
const hashBuffer = await crypto.subtle.digest('SHA-1', msgUint8)
|
||||||
|
const hashArray = Array.from(new Uint8Array(hashBuffer))
|
||||||
|
const hashHex = hashArray
|
||||||
|
.map((b) => b.toString(16).padStart(2, '0'))
|
||||||
|
.join('')
|
||||||
|
return hashHex
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize News UI. This will load the news and prepare
|
* Initialize News UI. This will load the news and prepare
|
||||||
* the UI accordingly.
|
* the UI accordingly.
|
||||||
@ -809,13 +816,11 @@ function showNewsAlert(){
|
|||||||
* @returns {Promise.<void>} A promise which resolves when the news
|
* @returns {Promise.<void>} A promise which resolves when the news
|
||||||
* content has finished loading and transitioning.
|
* content has finished loading and transitioning.
|
||||||
*/
|
*/
|
||||||
function initNews(){
|
async function initNews(){
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
setNewsLoading(true)
|
setNewsLoading(true)
|
||||||
|
|
||||||
let news = {}
|
const news = await loadNews()
|
||||||
loadNews().then(news => {
|
|
||||||
|
|
||||||
newsArr = news?.articles || null
|
newsArr = news?.articles || null
|
||||||
|
|
||||||
@ -823,11 +828,9 @@ function initNews(){
|
|||||||
// News Loading Failed
|
// News Loading Failed
|
||||||
setNewsLoading(false)
|
setNewsLoading(false)
|
||||||
|
|
||||||
$('#newsErrorLoading').fadeOut(250, () => {
|
await $('#newsErrorLoading').fadeOut(250).promise()
|
||||||
$('#newsErrorFailed').fadeIn(250, () => {
|
await $('#newsErrorFailed').fadeIn(250).promise()
|
||||||
resolve()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
} else if(newsArr.length === 0) {
|
} else if(newsArr.length === 0) {
|
||||||
// No News Articles
|
// No News Articles
|
||||||
setNewsLoading(false)
|
setNewsLoading(false)
|
||||||
@ -839,18 +842,15 @@ function initNews(){
|
|||||||
})
|
})
|
||||||
ConfigManager.save()
|
ConfigManager.save()
|
||||||
|
|
||||||
$('#newsErrorLoading').fadeOut(250, () => {
|
await $('#newsErrorLoading').fadeOut(250).promise()
|
||||||
$('#newsErrorNone').fadeIn(250, () => {
|
await $('#newsErrorNone').fadeIn(250).promise()
|
||||||
resolve()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
} else {
|
} else {
|
||||||
// Success
|
// Success
|
||||||
setNewsLoading(false)
|
setNewsLoading(false)
|
||||||
|
|
||||||
const lN = newsArr[0]
|
const lN = newsArr[0]
|
||||||
const cached = ConfigManager.getNewsCache()
|
const cached = ConfigManager.getNewsCache()
|
||||||
let newHash = crypto.createHash('sha1').update(lN.content).digest('hex')
|
let newHash = await digestMessage(lN.content)
|
||||||
let newDate = new Date(lN.date)
|
let newDate = new Date(lN.date)
|
||||||
let isNew = false
|
let isNew = false
|
||||||
|
|
||||||
@ -897,18 +897,12 @@ function initNews(){
|
|||||||
|
|
||||||
document.getElementById('newsNavigateRight').onclick = () => { switchHandler(true) }
|
document.getElementById('newsNavigateRight').onclick = () => { switchHandler(true) }
|
||||||
document.getElementById('newsNavigateLeft').onclick = () => { switchHandler(false) }
|
document.getElementById('newsNavigateLeft').onclick = () => { switchHandler(false) }
|
||||||
|
await $('#newsErrorContainer').fadeOut(250).promise()
|
||||||
$('#newsErrorContainer').fadeOut(250, () => {
|
|
||||||
displayArticle(newsArr[0], 1)
|
displayArticle(newsArr[0], 1)
|
||||||
$('#newsContent').fadeIn(250, () => {
|
await $('#newsContent').fadeIn(250).promise()
|
||||||
resolve()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -955,7 +949,7 @@ function displayArticle(articleObject, index){
|
|||||||
text.style.display = text.style.display === 'block' ? 'none' : 'block'
|
text.style.display = text.style.display === 'block' ? 'none' : 'block'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
newsNavigationStatus.innerHTML = index + ' of ' + newsArr.length
|
newsNavigationStatus.innerHTML = Lang.query('ejs.landing.newsNavigationStatus', {currentPage: index, totalPages: newsArr.length})
|
||||||
newsContent.setAttribute('article', index-1)
|
newsContent.setAttribute('article', index-1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -220,10 +220,7 @@ loginButton.addEventListener('click', () => {
|
|||||||
} else {
|
} else {
|
||||||
// Uh oh.
|
// Uh oh.
|
||||||
msftLoginLogger.error('Unhandled error during login.', displayableError)
|
msftLoginLogger.error('Unhandled error during login.', displayableError)
|
||||||
actualDisplayableError = {
|
actualDisplayableError = Lang.queryJS('login.error.unknown')
|
||||||
title: 'Unknown Error During Login',
|
|
||||||
desc: 'An unknown error has occurred. Please see the console for details.'
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setOverlayContent(actualDisplayableError.title, actualDisplayableError.desc, Lang.queryJS('login.tryAgain'))
|
setOverlayContent(actualDisplayableError.title, actualDisplayableError.desc, Lang.queryJS('login.tryAgain'))
|
||||||
|
@ -130,7 +130,7 @@ async function toggleServerSelection(toggleState){
|
|||||||
* @param {string} acknowledge Acknowledge button text.
|
* @param {string} acknowledge Acknowledge button text.
|
||||||
* @param {string} dismiss Dismiss button text.
|
* @param {string} dismiss Dismiss button text.
|
||||||
*/
|
*/
|
||||||
function setOverlayContent(title, description, acknowledge, dismiss = 'Dismiss'){
|
function setOverlayContent(title, description, acknowledge, dismiss = Lang.queryJS('overlay.dismiss')){
|
||||||
document.getElementById('overlayTitle').innerHTML = title
|
document.getElementById('overlayTitle').innerHTML = title
|
||||||
document.getElementById('overlayDesc').innerHTML = description
|
document.getElementById('overlayDesc').innerHTML = description
|
||||||
document.getElementById('overlayAcknowledge').innerHTML = acknowledge
|
document.getElementById('overlayAcknowledge').innerHTML = acknowledge
|
||||||
@ -289,7 +289,7 @@ async function populateServerListings(){
|
|||||||
<path class="cls-1" d="M100.93,65.54C89,62,68.18,55.65,63.54,52.13c2.7-5.23,18.8-19.2,28-27.55C81.36,31.74,63.74,43.87,58.09,45.3c-2.41-5.37-3.61-26.52-4.37-39-.77,12.46-2,33.64-4.36,39-5.7-1.46-23.3-13.57-33.49-20.72,9.26,8.37,25.39,22.36,28,27.55C39.21,55.68,18.47,62,6.52,65.55c12.32-2,33.63-6.06,39.34-4.9-.16,5.87-8.41,26.16-13.11,37.69,6.1-10.89,16.52-30.16,21-33.9,4.5,3.79,14.93,23.09,21,34C70,86.84,61.73,66.48,61.59,60.65,67.36,59.49,88.64,63.52,100.93,65.54Z"/>
|
<path class="cls-1" d="M100.93,65.54C89,62,68.18,55.65,63.54,52.13c2.7-5.23,18.8-19.2,28-27.55C81.36,31.74,63.74,43.87,58.09,45.3c-2.41-5.37-3.61-26.52-4.37-39-.77,12.46-2,33.64-4.36,39-5.7-1.46-23.3-13.57-33.49-20.72,9.26,8.37,25.39,22.36,28,27.55C39.21,55.68,18.47,62,6.52,65.55c12.32-2,33.63-6.06,39.34-4.9-.16,5.87-8.41,26.16-13.11,37.69,6.1-10.89,16.52-30.16,21-33.9,4.5,3.79,14.93,23.09,21,34C70,86.84,61.73,66.48,61.59,60.65,67.36,59.49,88.64,63.52,100.93,65.54Z"/>
|
||||||
<circle class="cls-2" cx="53.73" cy="53.9" r="38"/>
|
<circle class="cls-2" cx="53.73" cy="53.9" r="38"/>
|
||||||
</svg>
|
</svg>
|
||||||
<span class="serverListingStarTooltip">Main Server</span>
|
<span class="serverListingStarTooltip">${Lang.queryJS('settings.serverListing.mainServer')}</span>
|
||||||
</div>` : ''}
|
</div>` : ''}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -59,8 +59,8 @@ function bindFileSelectors(){
|
|||||||
|
|
||||||
if(isJavaExecSel && process.platform === 'win32') {
|
if(isJavaExecSel && process.platform === 'win32') {
|
||||||
options.filters = [
|
options.filters = [
|
||||||
{ name: 'Executables', extensions: ['exe'] },
|
{ name: Lang.queryJS('settings.fileSelectors.executables'), extensions: ['exe'] },
|
||||||
{ name: 'All Files', extensions: ['*'] }
|
{ name: Lang.queryJS('settings.fileSelectors.allFiles'), extensions: ['*'] }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -374,9 +374,9 @@ ipcRenderer.on(MSFT_OPCODE.REPLY_LOGIN, (_, ...arguments_) => {
|
|||||||
|
|
||||||
// Unexpected error.
|
// Unexpected error.
|
||||||
setOverlayContent(
|
setOverlayContent(
|
||||||
'Something Went Wrong',
|
Lang.queryJS('settings.msftLogin.errorTitle'),
|
||||||
'Microsoft authentication failed. Please try again.',
|
Lang.queryJS('settings.msftLogin.errorMessage'),
|
||||||
'OK'
|
Lang.queryJS('settings.msftLogin.okButton')
|
||||||
)
|
)
|
||||||
setOverlayHandler(() => {
|
setOverlayHandler(() => {
|
||||||
toggleOverlay(false)
|
toggleOverlay(false)
|
||||||
@ -401,7 +401,7 @@ ipcRenderer.on(MSFT_OPCODE.REPLY_LOGIN, (_, ...arguments_) => {
|
|||||||
setOverlayContent(
|
setOverlayContent(
|
||||||
error,
|
error,
|
||||||
errorDesc,
|
errorDesc,
|
||||||
'OK'
|
Lang.queryJS('settings.msftLogin.okButton')
|
||||||
)
|
)
|
||||||
setOverlayHandler(() => {
|
setOverlayHandler(() => {
|
||||||
toggleOverlay(false)
|
toggleOverlay(false)
|
||||||
@ -429,10 +429,7 @@ ipcRenderer.on(MSFT_OPCODE.REPLY_LOGIN, (_, ...arguments_) => {
|
|||||||
} else {
|
} else {
|
||||||
// Uh oh.
|
// Uh oh.
|
||||||
msftLoginLogger.error('Unhandled error during login.', displayableError)
|
msftLoginLogger.error('Unhandled error during login.', displayableError)
|
||||||
actualDisplayableError = {
|
actualDisplayableError = Lang.queryJS('login.error.unknown')
|
||||||
title: 'Unknown Error During Login',
|
|
||||||
desc: 'An unknown error has occurred. Please see the console for details.'
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switchView(getCurrentView(), viewOnClose, 500, 500, () => {
|
switchView(getCurrentView(), viewOnClose, 500, 500, () => {
|
||||||
@ -461,11 +458,11 @@ function bindAuthAccountSelect(){
|
|||||||
for(let i=0; i<selectBtns.length; i++){
|
for(let i=0; i<selectBtns.length; i++){
|
||||||
if(selectBtns[i].hasAttribute('selected')){
|
if(selectBtns[i].hasAttribute('selected')){
|
||||||
selectBtns[i].removeAttribute('selected')
|
selectBtns[i].removeAttribute('selected')
|
||||||
selectBtns[i].innerHTML = 'Select Account'
|
selectBtns[i].innerHTML = Lang.queryJS('settings.authAccountSelect.selectButton')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val.setAttribute('selected', '')
|
val.setAttribute('selected', '')
|
||||||
val.innerHTML = 'Selected Account ✔'
|
val.innerHTML = Lang.queryJS('settings.authAccountSelect.selectedButton')
|
||||||
setSelectedAccount(val.closest('.settingsAuthAccount').getAttribute('uuid'))
|
setSelectedAccount(val.closest('.settingsAuthAccount').getAttribute('uuid'))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -483,10 +480,10 @@ function bindAuthAccountLogOut(){
|
|||||||
if(Object.keys(ConfigManager.getAuthAccounts()).length === 1){
|
if(Object.keys(ConfigManager.getAuthAccounts()).length === 1){
|
||||||
isLastAccount = true
|
isLastAccount = true
|
||||||
setOverlayContent(
|
setOverlayContent(
|
||||||
'Warning<br>This is Your Last Account',
|
Lang.queryJS('settings.authAccountLogout.lastAccountWarningTitle'),
|
||||||
'In order to use the launcher you must be logged into at least one account. You will need to login again after.<br><br>Are you sure you want to log out?',
|
Lang.queryJS('settings.authAccountLogout.lastAccountWarningMessage'),
|
||||||
'I\'m Sure',
|
Lang.queryJS('settings.authAccountLogout.confirmButton'),
|
||||||
'Cancel'
|
Lang.queryJS('settings.authAccountLogout.cancelButton')
|
||||||
)
|
)
|
||||||
setOverlayHandler(() => {
|
setOverlayHandler(() => {
|
||||||
processLogOut(val, isLastAccount)
|
processLogOut(val, isLastAccount)
|
||||||
@ -555,9 +552,9 @@ ipcRenderer.on(MSFT_OPCODE.REPLY_LOGOUT, (_, ...arguments_) => {
|
|||||||
|
|
||||||
// Unexpected error.
|
// Unexpected error.
|
||||||
setOverlayContent(
|
setOverlayContent(
|
||||||
'Something Went Wrong',
|
Lang.queryJS('settings.msftLogout.errorTitle'),
|
||||||
'Microsoft logout failed. Please try again.',
|
Lang.queryJS('settings.msftLogout.errorMessage'),
|
||||||
'OK'
|
Lang.queryJS('settings.msftLogout.okButton')
|
||||||
)
|
)
|
||||||
setOverlayHandler(() => {
|
setOverlayHandler(() => {
|
||||||
toggleOverlay(false)
|
toggleOverlay(false)
|
||||||
@ -611,12 +608,12 @@ function refreshAuthAccountSelected(uuid){
|
|||||||
const selBtn = val.getElementsByClassName('settingsAuthAccountSelect')[0]
|
const selBtn = val.getElementsByClassName('settingsAuthAccountSelect')[0]
|
||||||
if(uuid === val.getAttribute('uuid')){
|
if(uuid === val.getAttribute('uuid')){
|
||||||
selBtn.setAttribute('selected', '')
|
selBtn.setAttribute('selected', '')
|
||||||
selBtn.innerHTML = 'Selected Account ✔'
|
selBtn.innerHTML = Lang.queryJS('settings.authAccountSelect.selectedButton')
|
||||||
} else {
|
} else {
|
||||||
if(selBtn.hasAttribute('selected')){
|
if(selBtn.hasAttribute('selected')){
|
||||||
selBtn.removeAttribute('selected')
|
selBtn.removeAttribute('selected')
|
||||||
}
|
}
|
||||||
selBtn.innerHTML = 'Select Account'
|
selBtn.innerHTML = Lang.queryJS('settings.authAccountSelect.selectButton')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -648,18 +645,18 @@ function populateAuthAccounts(){
|
|||||||
<div class="settingsAuthAccountRight">
|
<div class="settingsAuthAccountRight">
|
||||||
<div class="settingsAuthAccountDetails">
|
<div class="settingsAuthAccountDetails">
|
||||||
<div class="settingsAuthAccountDetailPane">
|
<div class="settingsAuthAccountDetailPane">
|
||||||
<div class="settingsAuthAccountDetailTitle">Username</div>
|
<div class="settingsAuthAccountDetailTitle">${Lang.queryJS('settings.authAccountPopulate.username')}</div>
|
||||||
<div class="settingsAuthAccountDetailValue">${acc.displayName}</div>
|
<div class="settingsAuthAccountDetailValue">${acc.displayName}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="settingsAuthAccountDetailPane">
|
<div class="settingsAuthAccountDetailPane">
|
||||||
<div class="settingsAuthAccountDetailTitle">UUID</div>
|
<div class="settingsAuthAccountDetailTitle">${Lang.queryJS('settings.authAccountPopulate.uuid')}</div>
|
||||||
<div class="settingsAuthAccountDetailValue">${acc.uuid}</div>
|
<div class="settingsAuthAccountDetailValue">${acc.uuid}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="settingsAuthAccountActions">
|
<div class="settingsAuthAccountActions">
|
||||||
<button class="settingsAuthAccountSelect" ${selectedUUID === acc.uuid ? 'selected>Selected Account ✔' : '>Select Account'}</button>
|
<button class="settingsAuthAccountSelect" ${selectedUUID === acc.uuid ? 'selected>' + Lang.queryJS('settings.authAccountPopulate.selectedAccount') : '>' + Lang.queryJS('settings.authAccountPopulate.selectAccount')}</button>
|
||||||
<div class="settingsAuthAccountWrapper">
|
<div class="settingsAuthAccountWrapper">
|
||||||
<button class="settingsAuthAccountLogOut">Log Out</button>
|
<button class="settingsAuthAccountLogOut">${Lang.queryJS('settings.authAccountPopulate.logout')}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -739,7 +736,7 @@ function parseModulesForUI(mdls, submodules, servConf){
|
|||||||
|
|
||||||
for(const mdl of mdls){
|
for(const mdl of mdls){
|
||||||
|
|
||||||
if(mdl.rawModule.type === Type.ForgeMod || mdl.rawModule.type === Type.LiteMod || mdl.rawModule.type === Type.LiteLoader){
|
if(mdl.rawModule.type === Type.ForgeMod || mdl.rawModule.type === Type.LiteMod || mdl.rawModule.type === Type.LiteLoader || mdl.rawModule.type === Type.FabricMod){
|
||||||
|
|
||||||
if(mdl.getRequired().value){
|
if(mdl.getRequired().value){
|
||||||
|
|
||||||
@ -873,7 +870,7 @@ async function resolveDropinModsForUI(){
|
|||||||
<div class="settingsModDetails">
|
<div class="settingsModDetails">
|
||||||
<span class="settingsModName">${dropin.name}</span>
|
<span class="settingsModName">${dropin.name}</span>
|
||||||
<div class="settingsDropinRemoveWrapper">
|
<div class="settingsDropinRemoveWrapper">
|
||||||
<button class="settingsDropinRemoveButton" remmod="${dropin.fullName}">Remove</button>
|
<button class="settingsDropinRemoveButton" remmod="${dropin.fullName}">${Lang.queryJS('settings.dropinMods.removeButton')}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -901,9 +898,9 @@ function bindDropinModsRemoveButton(){
|
|||||||
document.getElementById(fullName).remove()
|
document.getElementById(fullName).remove()
|
||||||
} else {
|
} else {
|
||||||
setOverlayContent(
|
setOverlayContent(
|
||||||
`Failed to Delete<br>Drop-in Mod ${fullName}`,
|
Lang.queryJS('settings.dropinMods.deleteFailedTitle', { fullName }),
|
||||||
'Make sure the file is not in use and try again.',
|
Lang.queryJS('settings.dropinMods.deleteFailedMessage'),
|
||||||
'Okay'
|
Lang.queryJS('settings.dropinMods.okButton')
|
||||||
)
|
)
|
||||||
setOverlayHandler(null)
|
setOverlayHandler(null)
|
||||||
toggleOverlay(true)
|
toggleOverlay(true)
|
||||||
@ -956,9 +953,9 @@ function saveDropinModConfiguration(){
|
|||||||
DropinModUtil.toggleDropinMod(CACHE_SETTINGS_MODS_DIR, dropin.fullName, dropinUIEnabled).catch(err => {
|
DropinModUtil.toggleDropinMod(CACHE_SETTINGS_MODS_DIR, dropin.fullName, dropinUIEnabled).catch(err => {
|
||||||
if(!isOverlayVisible()){
|
if(!isOverlayVisible()){
|
||||||
setOverlayContent(
|
setOverlayContent(
|
||||||
'Failed to Toggle<br>One or More Drop-in Mods',
|
Lang.queryJS('settings.dropinMods.failedToggleTitle'),
|
||||||
err.message,
|
err.message,
|
||||||
'Okay'
|
Lang.queryJS('settings.dropinMods.okButton')
|
||||||
)
|
)
|
||||||
setOverlayHandler(null)
|
setOverlayHandler(null)
|
||||||
toggleOverlay(true)
|
toggleOverlay(true)
|
||||||
@ -1093,7 +1090,7 @@ async function loadSelectedServerOnModsTab(){
|
|||||||
<path class="cls-1" d="M100.93,65.54C89,62,68.18,55.65,63.54,52.13c2.7-5.23,18.8-19.2,28-27.55C81.36,31.74,63.74,43.87,58.09,45.3c-2.41-5.37-3.61-26.52-4.37-39-.77,12.46-2,33.64-4.36,39-5.7-1.46-23.3-13.57-33.49-20.72,9.26,8.37,25.39,22.36,28,27.55C39.21,55.68,18.47,62,6.52,65.55c12.32-2,33.63-6.06,39.34-4.9-.16,5.87-8.41,26.16-13.11,37.69,6.1-10.89,16.52-30.16,21-33.9,4.5,3.79,14.93,23.09,21,34C70,86.84,61.73,66.48,61.59,60.65,67.36,59.49,88.64,63.52,100.93,65.54Z"/>
|
<path class="cls-1" d="M100.93,65.54C89,62,68.18,55.65,63.54,52.13c2.7-5.23,18.8-19.2,28-27.55C81.36,31.74,63.74,43.87,58.09,45.3c-2.41-5.37-3.61-26.52-4.37-39-.77,12.46-2,33.64-4.36,39-5.7-1.46-23.3-13.57-33.49-20.72,9.26,8.37,25.39,22.36,28,27.55C39.21,55.68,18.47,62,6.52,65.55c12.32-2,33.63-6.06,39.34-4.9-.16,5.87-8.41,26.16-13.11,37.69,6.1-10.89,16.52-30.16,21-33.9,4.5,3.79,14.93,23.09,21,34C70,86.84,61.73,66.48,61.59,60.65,67.36,59.49,88.64,63.52,100.93,65.54Z"/>
|
||||||
<circle class="cls-2" cx="53.73" cy="53.9" r="38"/>
|
<circle class="cls-2" cx="53.73" cy="53.9" r="38"/>
|
||||||
</svg>
|
</svg>
|
||||||
<span class="serverListingStarTooltip">Main Server</span>
|
<span class="serverListingStarTooltip">${Lang.queryJS('settings.serverListing.mainServer')}</span>
|
||||||
</div>` : ''}
|
</div>` : ''}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -1344,19 +1341,19 @@ async function populateJavaExecDetails(execPath){
|
|||||||
const details = await validateSelectedJvm(ensureJavaDirIsRoot(execPath), server.effectiveJavaOptions.supported)
|
const details = await validateSelectedJvm(ensureJavaDirIsRoot(execPath), server.effectiveJavaOptions.supported)
|
||||||
|
|
||||||
if(details != null) {
|
if(details != null) {
|
||||||
settingsJavaExecDetails.innerHTML = `Selected: Java ${details.semverStr} (${details.vendor})`
|
settingsJavaExecDetails.innerHTML = Lang.queryJS('settings.java.selectedJava', { version: details.semverStr, vendor: details.vendor })
|
||||||
} else {
|
} else {
|
||||||
settingsJavaExecDetails.innerHTML = 'Invalid Selection'
|
settingsJavaExecDetails.innerHTML = Lang.queryJS('settings.java.invalidSelection')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function populateJavaReqDesc(server) {
|
function populateJavaReqDesc(server) {
|
||||||
settingsJavaReqDesc.innerHTML = `Requires Java ${server.effectiveJavaOptions.suggestedMajor} x64.`
|
settingsJavaReqDesc.innerHTML = Lang.queryJS('settings.java.requiresJava', { major: server.effectiveJavaOptions.suggestedMajor })
|
||||||
}
|
}
|
||||||
|
|
||||||
function populateJvmOptsLink(server) {
|
function populateJvmOptsLink(server) {
|
||||||
const major = server.effectiveJavaOptions.suggestedMajor
|
const major = server.effectiveJavaOptions.suggestedMajor
|
||||||
settingsJvmOptsLink.innerHTML = `Available Options for Java ${major} (HotSpot VM)`
|
settingsJvmOptsLink.innerHTML = Lang.queryJS('settings.java.availableOptions', { major: major })
|
||||||
if(major >= 12) {
|
if(major >= 12) {
|
||||||
settingsJvmOptsLink.href = `https://docs.oracle.com/en/java/javase/${major}/docs/specs/man/java.html#extra-options-for-java`
|
settingsJvmOptsLink.href = `https://docs.oracle.com/en/java/javase/${major}/docs/specs/man/java.html#extra-options-for-java`
|
||||||
}
|
}
|
||||||
@ -1433,11 +1430,11 @@ function isPrerelease(version){
|
|||||||
function populateVersionInformation(version, valueElement, titleElement, checkElement){
|
function populateVersionInformation(version, valueElement, titleElement, checkElement){
|
||||||
valueElement.innerHTML = version
|
valueElement.innerHTML = version
|
||||||
if(isPrerelease(version)){
|
if(isPrerelease(version)){
|
||||||
titleElement.innerHTML = 'Pre-release'
|
titleElement.innerHTML = Lang.queryJS('settings.about.preReleaseTitle')
|
||||||
titleElement.style.color = '#ff886d'
|
titleElement.style.color = '#ff886d'
|
||||||
checkElement.style.background = '#ff886d'
|
checkElement.style.background = '#ff886d'
|
||||||
} else {
|
} else {
|
||||||
titleElement.innerHTML = 'Stable Release'
|
titleElement.innerHTML = Lang.queryJS('settings.about.stableReleaseTitle')
|
||||||
titleElement.style.color = null
|
titleElement.style.color = null
|
||||||
checkElement.style.background = null
|
checkElement.style.background = null
|
||||||
}
|
}
|
||||||
@ -1476,7 +1473,7 @@ function populateReleaseNotes(){
|
|||||||
},
|
},
|
||||||
timeout: 2500
|
timeout: 2500
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
settingsAboutChangelogText.innerHTML = 'Failed to load release notes.'
|
settingsAboutChangelogText.innerHTML = Lang.queryJS('settings.about.releaseNotesFailed')
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1524,27 +1521,27 @@ function settingsUpdateButtonStatus(text, disabled = false, handler = null){
|
|||||||
*/
|
*/
|
||||||
function populateSettingsUpdateInformation(data){
|
function populateSettingsUpdateInformation(data){
|
||||||
if(data != null){
|
if(data != null){
|
||||||
settingsUpdateTitle.innerHTML = `New ${isPrerelease(data.version) ? 'Pre-release' : 'Release'} Available`
|
settingsUpdateTitle.innerHTML = isPrerelease(data.version) ? Lang.queryJS('settings.updates.newPreReleaseTitle') : Lang.queryJS('settings.updates.newReleaseTitle')
|
||||||
settingsUpdateChangelogCont.style.display = null
|
settingsUpdateChangelogCont.style.display = null
|
||||||
settingsUpdateChangelogTitle.innerHTML = data.releaseName
|
settingsUpdateChangelogTitle.innerHTML = data.releaseName
|
||||||
settingsUpdateChangelogText.innerHTML = data.releaseNotes
|
settingsUpdateChangelogText.innerHTML = data.releaseNotes
|
||||||
populateVersionInformation(data.version, settingsUpdateVersionValue, settingsUpdateVersionTitle, settingsUpdateVersionCheck)
|
populateVersionInformation(data.version, settingsUpdateVersionValue, settingsUpdateVersionTitle, settingsUpdateVersionCheck)
|
||||||
|
|
||||||
if(process.platform === 'darwin'){
|
if(process.platform === 'darwin'){
|
||||||
settingsUpdateButtonStatus('Download from GitHub<span style="font-size: 10px;color: gray;text-shadow: none !important;">Close the launcher and run the dmg to update.</span>', false, () => {
|
settingsUpdateButtonStatus(Lang.queryJS('settings.updates.downloadButton'), false, () => {
|
||||||
shell.openExternal(data.darwindownload)
|
shell.openExternal(data.darwindownload)
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
settingsUpdateButtonStatus('Downloading..', true)
|
settingsUpdateButtonStatus(Lang.queryJS('settings.updates.downloadingButton'), true)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
settingsUpdateTitle.innerHTML = 'You Are Running the Latest Version'
|
settingsUpdateTitle.innerHTML = Lang.queryJS('settings.updates.latestVersionTitle')
|
||||||
settingsUpdateChangelogCont.style.display = 'none'
|
settingsUpdateChangelogCont.style.display = 'none'
|
||||||
populateVersionInformation(remote.app.getVersion(), settingsUpdateVersionValue, settingsUpdateVersionTitle, settingsUpdateVersionCheck)
|
populateVersionInformation(remote.app.getVersion(), settingsUpdateVersionValue, settingsUpdateVersionTitle, settingsUpdateVersionCheck)
|
||||||
settingsUpdateButtonStatus('Check for Updates', false, () => {
|
settingsUpdateButtonStatus(Lang.queryJS('settings.updates.checkForUpdatesButton'), false, () => {
|
||||||
if(!isDev){
|
if(!isDev){
|
||||||
ipcRenderer.send('autoUpdateAction', 'checkForUpdate')
|
ipcRenderer.send('autoUpdateAction', 'checkForUpdate')
|
||||||
settingsUpdateButtonStatus('Checking for Updates..', true)
|
settingsUpdateButtonStatus(Lang.queryJS('settings.updates.checkingForUpdatesButton'), true)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,6 @@ const { Type } = require('helios-distribution-types')
|
|||||||
const AuthManager = require('./assets/js/authmanager')
|
const AuthManager = require('./assets/js/authmanager')
|
||||||
const ConfigManager = require('./assets/js/configmanager')
|
const ConfigManager = require('./assets/js/configmanager')
|
||||||
const { DistroAPI } = require('./assets/js/distromanager')
|
const { DistroAPI } = require('./assets/js/distromanager')
|
||||||
const Lang = require('./assets/js/langloader')
|
|
||||||
|
|
||||||
let rscShouldLoad = false
|
let rscShouldLoad = false
|
||||||
let fatalStartupError = false
|
let fatalStartupError = false
|
||||||
@ -115,9 +114,9 @@ function showFatalStartupError(){
|
|||||||
$('#loadingContainer').fadeOut(250, () => {
|
$('#loadingContainer').fadeOut(250, () => {
|
||||||
document.getElementById('overlayContainer').style.background = 'none'
|
document.getElementById('overlayContainer').style.background = 'none'
|
||||||
setOverlayContent(
|
setOverlayContent(
|
||||||
'Fatal Error: Unable to Load Distribution Index',
|
Lang.queryJS('uibinder.startup.fatalErrorTitle'),
|
||||||
'A connection could not be established to our servers to download the distribution index. No local copies were available to load. <br><br>The distribution index is an essential file which provides the latest server information. The launcher is unable to start without it. Ensure you are connected to the internet and relaunch the application.',
|
Lang.queryJS('uibinder.startup.fatalErrorMessage'),
|
||||||
'Close'
|
Lang.queryJS('uibinder.startup.closeButton')
|
||||||
)
|
)
|
||||||
setOverlayHandler(() => {
|
setOverlayHandler(() => {
|
||||||
const window = remote.getCurrentWindow()
|
const window = remote.getCurrentWindow()
|
||||||
@ -164,7 +163,7 @@ function syncModConfigurations(data){
|
|||||||
for(let mdl of mdls){
|
for(let mdl of mdls){
|
||||||
const type = mdl.rawModule.type
|
const type = mdl.rawModule.type
|
||||||
|
|
||||||
if(type === Type.ForgeMod || type === Type.LiteMod || type === Type.LiteLoader){
|
if(type === Type.ForgeMod || type === Type.LiteMod || type === Type.LiteLoader || type === Type.FabricMod){
|
||||||
if(!mdl.getRequired().value){
|
if(!mdl.getRequired().value){
|
||||||
const mdlID = mdl.getVersionlessMavenIdentifier()
|
const mdlID = mdl.getVersionlessMavenIdentifier()
|
||||||
if(modsOld[mdlID] == null){
|
if(modsOld[mdlID] == null){
|
||||||
@ -199,7 +198,7 @@ function syncModConfigurations(data){
|
|||||||
|
|
||||||
for(let mdl of mdls){
|
for(let mdl of mdls){
|
||||||
const type = mdl.rawModule.type
|
const type = mdl.rawModule.type
|
||||||
if(type === Type.ForgeMod || type === Type.LiteMod || type === Type.LiteLoader){
|
if(type === Type.ForgeMod || type === Type.LiteMod || type === Type.LiteLoader || type === Type.FabricMod){
|
||||||
if(!mdl.getRequired().value){
|
if(!mdl.getRequired().value){
|
||||||
mods[mdl.getVersionlessMavenIdentifier()] = scanOptionalSubModules(mdl.subModules, mdl)
|
mods[mdl.getVersionlessMavenIdentifier()] = scanOptionalSubModules(mdl.subModules, mdl)
|
||||||
} else {
|
} else {
|
||||||
@ -254,7 +253,7 @@ function scanOptionalSubModules(mdls, origin){
|
|||||||
for(let mdl of mdls){
|
for(let mdl of mdls){
|
||||||
const type = mdl.rawModule.type
|
const type = mdl.rawModule.type
|
||||||
// Optional types.
|
// Optional types.
|
||||||
if(type === Type.ForgeMod || type === Type.LiteMod || type === Type.LiteLoader){
|
if(type === Type.ForgeMod || type === Type.LiteMod || type === Type.LiteLoader || type === Type.FabricMod){
|
||||||
// It is optional.
|
// It is optional.
|
||||||
if(!mdl.getRequired().value){
|
if(!mdl.getRequired().value){
|
||||||
mods[mdl.getVersionlessMavenIdentifier()] = scanOptionalSubModules(mdl.subModules, mdl)
|
mods[mdl.getVersionlessMavenIdentifier()] = scanOptionalSubModules(mdl.subModules, mdl)
|
||||||
@ -333,10 +332,12 @@ async function validateSelectedAccount(){
|
|||||||
ConfigManager.save()
|
ConfigManager.save()
|
||||||
const accLen = Object.keys(ConfigManager.getAuthAccounts()).length
|
const accLen = Object.keys(ConfigManager.getAuthAccounts()).length
|
||||||
setOverlayContent(
|
setOverlayContent(
|
||||||
'Failed to Refresh Login',
|
Lang.queryJS('uibinder.validateAccount.failedMessageTitle'),
|
||||||
`We were unable to refresh the login for <strong>${selectedAcc.displayName}</strong>. Please ${accLen > 0 ? 'select another account or ' : ''} login again.`,
|
accLen > 0
|
||||||
'Login',
|
? Lang.queryJS('uibinder.validateAccount.failedMessage', { 'account': selectedAcc.displayName })
|
||||||
'Select Another Account'
|
: Lang.queryJS('uibinder.validateAccount.failedMessageSelectAnotherAccount', { 'account': selectedAcc.displayName }),
|
||||||
|
Lang.queryJS('uibinder.validateAccount.loginButton'),
|
||||||
|
Lang.queryJS('uibinder.validateAccount.selectAnotherAccountButton')
|
||||||
)
|
)
|
||||||
setOverlayHandler(() => {
|
setOverlayHandler(() => {
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ const {ipcRenderer, shell, webFrame} = require('electron')
|
|||||||
const remote = require('@electron/remote')
|
const remote = require('@electron/remote')
|
||||||
const isDev = require('./assets/js/isdev')
|
const isDev = require('./assets/js/isdev')
|
||||||
const { LoggerUtil } = require('helios-core')
|
const { LoggerUtil } = require('helios-core')
|
||||||
|
const Lang = require('./assets/js/langloader')
|
||||||
|
|
||||||
const loggerUICore = LoggerUtil.getLogger('UICore')
|
const loggerUICore = LoggerUtil.getLogger('UICore')
|
||||||
const loggerAutoUpdater = LoggerUtil.getLogger('AutoUpdater')
|
const loggerAutoUpdater = LoggerUtil.getLogger('AutoUpdater')
|
||||||
@ -42,7 +43,7 @@ if(!isDev){
|
|||||||
switch(arg){
|
switch(arg){
|
||||||
case 'checking-for-update':
|
case 'checking-for-update':
|
||||||
loggerAutoUpdater.info('Checking for update..')
|
loggerAutoUpdater.info('Checking for update..')
|
||||||
settingsUpdateButtonStatus('Checking for Updates..', true)
|
settingsUpdateButtonStatus(Lang.queryJS('uicore.autoUpdate.checkingForUpdateButton'), true)
|
||||||
break
|
break
|
||||||
case 'update-available':
|
case 'update-available':
|
||||||
loggerAutoUpdater.info('New update available', info.version)
|
loggerAutoUpdater.info('New update available', info.version)
|
||||||
@ -56,7 +57,7 @@ if(!isDev){
|
|||||||
break
|
break
|
||||||
case 'update-downloaded':
|
case 'update-downloaded':
|
||||||
loggerAutoUpdater.info('Update ' + info.version + ' ready to be installed.')
|
loggerAutoUpdater.info('Update ' + info.version + ' ready to be installed.')
|
||||||
settingsUpdateButtonStatus('Install Now', false, () => {
|
settingsUpdateButtonStatus(Lang.queryJS('uicore.autoUpdate.installNowButton'), false, () => {
|
||||||
if(!isDev){
|
if(!isDev){
|
||||||
ipcRenderer.send('autoUpdateAction', 'installUpdateNow')
|
ipcRenderer.send('autoUpdateAction', 'installUpdateNow')
|
||||||
}
|
}
|
||||||
@ -65,7 +66,7 @@ if(!isDev){
|
|||||||
break
|
break
|
||||||
case 'update-not-available':
|
case 'update-not-available':
|
||||||
loggerAutoUpdater.info('No new update found.')
|
loggerAutoUpdater.info('No new update found.')
|
||||||
settingsUpdateButtonStatus('Check for Updates')
|
settingsUpdateButtonStatus(Lang.queryJS('uicore.autoUpdate.checkForUpdatesButton'))
|
||||||
break
|
break
|
||||||
case 'ready':
|
case 'ready':
|
||||||
updateCheckListener = setInterval(() => {
|
updateCheckListener = setInterval(() => {
|
||||||
|
20
app/assets/lang/_custom.toml
Normal file
20
app/assets/lang/_custom.toml
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# Custom Language File for Launcher Customizer
|
||||||
|
|
||||||
|
[ejs.app]
|
||||||
|
title = "Helios Launcher"
|
||||||
|
|
||||||
|
[ejs.landing]
|
||||||
|
mediaGitHubURL = "https://github.com/dscalzi/HeliosLauncher"
|
||||||
|
mediaTwitterURL = "#"
|
||||||
|
mediaInstagramURL = "#"
|
||||||
|
mediaYouTubeURL = "#"
|
||||||
|
mediaDiscordURL = "https://discord.gg/zNWUXdt"
|
||||||
|
|
||||||
|
[ejs.settings]
|
||||||
|
sourceGithubLink = "https://github.com/dscalZi/HeliosLauncher"
|
||||||
|
supportLink = "https://github.com/dscalZi/HeliosLauncher/issues"
|
||||||
|
|
||||||
|
[ejs.welcome]
|
||||||
|
welcomeHeader = "WELCOME TO WESTEROSCRAFT"
|
||||||
|
welcomeDescription = "Our mission is to recreate the universe imagined by author George RR Martin in his fantasy series, A Song of Ice and Fire. Through the collaborative effort of thousands of community members, we have sought to create Westeros as accurately and precisely as possible within Minecraft. The world we are creating is yours to explore. Journey from Dorne to Castle Black, and if you aren’t afraid, beyond the Wall itself, but best not delay. As the words of House Stark ominously warn: Winter is Coming."
|
||||||
|
welcomeDescCTA = "You are just a few clicks away from Westeros."
|
@ -1,49 +0,0 @@
|
|||||||
{
|
|
||||||
"html": {
|
|
||||||
"avatarOverlay": "Edit"
|
|
||||||
},
|
|
||||||
"js": {
|
|
||||||
"login": {
|
|
||||||
"error": {
|
|
||||||
"invalidValue": "* Invalid Value",
|
|
||||||
"requiredValue": "* Required",
|
|
||||||
"userMigrated": {
|
|
||||||
"title": "Error During Login:<br>Invalid Credentials",
|
|
||||||
"desc": "You've attempted to login with a migrated account. Try again using the account email as the username."
|
|
||||||
},
|
|
||||||
"invalidCredentials": {
|
|
||||||
"title": "Error During Login:<br>Invalid Credentials",
|
|
||||||
"desc": "The email or password you've entered is incorrect. Please try again."
|
|
||||||
},
|
|
||||||
"rateLimit": {
|
|
||||||
"title": "Error During Login:<br>Too Many Attempts",
|
|
||||||
"desc": "There have been too many login attempts with this account recently. Please try again later."
|
|
||||||
},
|
|
||||||
"noInternet": {
|
|
||||||
"title": "Error During Login:<br>No Internet Connection",
|
|
||||||
"desc": "You must be connected to the internet in order to login. Please connect and try again."
|
|
||||||
},
|
|
||||||
"authDown": {
|
|
||||||
"title": "Error During Login:<br>Authentication Server Offline",
|
|
||||||
"desc": "Mojang's authentication server is currently offline or unreachable. Please wait a bit and try again. You can check the status of the server on <a href=\"https://help.mojang.com/\">Mojang's help portal</a>."
|
|
||||||
},
|
|
||||||
"notPaid": {
|
|
||||||
"title": "Error During Login:<br>Game Not Purchased",
|
|
||||||
"desc": "The account you are trying to login with has not purchased a copy of Minecraft.<br>You may purchase a copy on <a href=\"https://minecraft.net/\">Minecraft.net</a>"
|
|
||||||
},
|
|
||||||
"unknown": {
|
|
||||||
"title": "Error During Login:<br>Unknown Error"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"login": "LOGIN",
|
|
||||||
"loggingIn": "LOGGING IN",
|
|
||||||
"success": "SUCCESS",
|
|
||||||
"tryAgain": "Try Again"
|
|
||||||
},
|
|
||||||
"landing": {
|
|
||||||
"launch": {
|
|
||||||
"pleaseWait": "Please wait.."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
297
app/assets/lang/en_US.toml
Normal file
297
app/assets/lang/en_US.toml
Normal file
@ -0,0 +1,297 @@
|
|||||||
|
[ejs.landing]
|
||||||
|
updateAvailableTooltip = "Update Available"
|
||||||
|
usernamePlaceholder = "Username"
|
||||||
|
usernameEditButton = "Edit"
|
||||||
|
settingsTooltip = "Settings"
|
||||||
|
serverStatus = "SERVER"
|
||||||
|
serverStatusPlaceholder = "OFFLINE"
|
||||||
|
mojangStatus = "MOJANG STATUS"
|
||||||
|
mojangStatusTooltipTitle = "Services"
|
||||||
|
mojangStatusNETitle = "Non Essential"
|
||||||
|
newsButton = "NEWS"
|
||||||
|
launchButton = "PLAY"
|
||||||
|
launchButtonPlaceholder = "• No Server Selected"
|
||||||
|
launchDetails = "Please wait.."
|
||||||
|
newsNavigationStatus = "{currentPage} of {totalPages}"
|
||||||
|
newsErrorLoadSpan = "Checking for News.."
|
||||||
|
newsErrorFailedSpan = "Failed to Load News"
|
||||||
|
newsErrorRetryButton = "Try Again"
|
||||||
|
newsErrorNoneSpan = "No News"
|
||||||
|
|
||||||
|
[ejs.login]
|
||||||
|
loginCancelText = "Cancel"
|
||||||
|
loginSubheader = "MINECRAFT LOGIN"
|
||||||
|
loginEmailError = "* Invalid Value"
|
||||||
|
loginEmailPlaceholder = "EMAIL OR USERNAME"
|
||||||
|
loginPasswordError = "* Required"
|
||||||
|
loginPasswordPlaceholder = "PASSWORD"
|
||||||
|
loginForgotPasswordLink = "https://minecraft.net/password/forgot/"
|
||||||
|
loginForgotPasswordText = "forgot password?"
|
||||||
|
loginRememberMeText = "remember me?"
|
||||||
|
loginButtonText = "LOGIN"
|
||||||
|
loginNeedAccountLink = "https://minecraft.net/store/minecraft-java-edition/"
|
||||||
|
loginNeedAccountText = "Need an Account?"
|
||||||
|
loginPasswordDisclaimer1 = "Your password is sent directly to mojang and never stored."
|
||||||
|
loginPasswordDisclaimer2 = "{appName} is not affiliated with Mojang AB."
|
||||||
|
|
||||||
|
[ejs.loginOptions]
|
||||||
|
loginOptionsTitle = "Login Options"
|
||||||
|
loginWithMicrosoft = "Login with Microsoft"
|
||||||
|
loginWithMojang = "Login with Mojang"
|
||||||
|
cancelButton = "Cancel"
|
||||||
|
|
||||||
|
[ejs.overlay]
|
||||||
|
serverSelectHeader = "Available Servers"
|
||||||
|
serverSelectConfirm = "Select"
|
||||||
|
serverSelectCancel = "Cancel"
|
||||||
|
accountSelectHeader = "Select an Account"
|
||||||
|
accountSelectConfirm = "Select"
|
||||||
|
accountSelectCancel = "Cancel"
|
||||||
|
|
||||||
|
[ejs.settings]
|
||||||
|
navHeaderText = "Settings"
|
||||||
|
navAccount = "Account"
|
||||||
|
navMinecraft = "Minecraft"
|
||||||
|
navMods = "Mods"
|
||||||
|
navJava = "Java"
|
||||||
|
navLauncher = "Launcher"
|
||||||
|
navAbout = "About"
|
||||||
|
navUpdates = "Updates"
|
||||||
|
navDone = "Done"
|
||||||
|
tabAccountHeaderText = "Account Settings"
|
||||||
|
tabAccountHeaderDesc = "Add new accounts or manage existing ones."
|
||||||
|
microsoftAccount = "Microsoft"
|
||||||
|
addMicrosoftAccount = "+ Add Microsoft Account"
|
||||||
|
mojangAccount = "Mojang"
|
||||||
|
addMojangAccount = "+ Add Mojang Account"
|
||||||
|
minecraftTabHeaderText = "Minecraft Settings"
|
||||||
|
minecraftTabHeaderDesc = "Options related to game launch."
|
||||||
|
gameResolutionTitle = "Game Resolution"
|
||||||
|
launchFullscreenTitle = "Launch in fullscreen."
|
||||||
|
autoConnectTitle = "Automatically connect to the server on launch."
|
||||||
|
launchDetachedTitle = "Launch game process detached from launcher."
|
||||||
|
launchDetachedDesc = "If the game is not detached, closing the launcher will also close the game."
|
||||||
|
tabModsHeaderText = "Mod Settings"
|
||||||
|
tabModsHeaderDesc = "Enable or disable mods."
|
||||||
|
switchServerButton = "Switch"
|
||||||
|
requiredMods = "Required Mods"
|
||||||
|
optionalMods = "Optional Mods"
|
||||||
|
dropinMods = "Drop-in Mods"
|
||||||
|
addMods = "Add Mods"
|
||||||
|
dropinRefreshNote = "(F5 to Refresh)"
|
||||||
|
shaderpacks = "Shaderpacks"
|
||||||
|
shaderpackDesc = "Enable or disable shaders. Please note, shaders will only run smoothly on powerful setups. You may add custom packs here."
|
||||||
|
selectShaderpack = "Select Shaderpack"
|
||||||
|
tabJavaHeaderText = "Java Settings"
|
||||||
|
tabJavaHeaderDesc = "Manage the Java configuration (advanced)."
|
||||||
|
memoryTitle = "Memory"
|
||||||
|
maxRAM = "Maximum RAM"
|
||||||
|
minRAM = "Minimum RAM"
|
||||||
|
memoryDesc = "The recommended minimum RAM is 3 gigabytes. Setting the minimum and maximum values to the same value may reduce lag."
|
||||||
|
memoryTotalTitle = "Total"
|
||||||
|
memoryAvailableTitle = "Available"
|
||||||
|
javaExecutableTitle = "Java Executable"
|
||||||
|
javaExecSelDialogTitle = "Select Java Executable"
|
||||||
|
javaExecSelButtonText = "Choose File"
|
||||||
|
javaExecDesc = "The Java executable is validated before game launch."
|
||||||
|
javaPathDesc = "The path should end with <strong>{pathSuffix}</strong>."
|
||||||
|
jvmOptsTitle = "Additional JVM Options"
|
||||||
|
jvmOptsDesc = "Options to be provided to the JVM at runtime. <em>-Xms</em> and <em>-Xmx</em> should not be included."
|
||||||
|
launcherTabHeaderText = "Launcher Settings"
|
||||||
|
launcherTabHeaderDesc = "Options related to the launcher itself."
|
||||||
|
allowPrereleaseTitle = "Allow Pre-Release Updates."
|
||||||
|
allowPrereleaseDesc = "Pre-Releases include new features which may have not been fully tested or integrated.<br>This will always be true if you are using a pre-release version."
|
||||||
|
dataDirectoryTitle = "Data Directory"
|
||||||
|
selectDataDirectory = "Select Data Directory"
|
||||||
|
chooseFolder = "Choose Folder"
|
||||||
|
dataDirectoryDesc = "All game files and local Java installations will be stored in the data directory.<br>Screenshots and world saves are stored in the instance folder for the corresponding server configuration."
|
||||||
|
aboutTabHeaderText = "About"
|
||||||
|
aboutTabHeaderDesc = "View information and release notes for the current version."
|
||||||
|
aboutTitle = "{appName}"
|
||||||
|
stableRelease = "Stable Release"
|
||||||
|
versionText = "Version "
|
||||||
|
sourceGithub = "Source (GitHub)"
|
||||||
|
support = "Support"
|
||||||
|
devToolsConsole = "DevTools Console"
|
||||||
|
releaseNotes = "Release Notes"
|
||||||
|
changelog = "Changelog"
|
||||||
|
noReleaseNotes = "No Release Notes"
|
||||||
|
viewReleaseNotes = "View Release Notes on GitHub"
|
||||||
|
launcherUpdatesHeaderText = "Launcher Updates"
|
||||||
|
launcherUpdatesHeaderDesc = "Download, install, and review updates for the launcher."
|
||||||
|
checkForUpdates = "Check for Updates"
|
||||||
|
whatsNew = "What's New"
|
||||||
|
updateReleaseNotes = "Update Release Notes"
|
||||||
|
|
||||||
|
[ejs.waiting]
|
||||||
|
waitingText = "Waiting for Microsoft.."
|
||||||
|
|
||||||
|
[ejs.welcome]
|
||||||
|
continueButton = "CONTINUE"
|
||||||
|
|
||||||
|
|
||||||
|
[js.discord]
|
||||||
|
waiting = "Waiting for Client.."
|
||||||
|
state = "Server: {shortId}"
|
||||||
|
|
||||||
|
[js.index]
|
||||||
|
microsoftLoginTitle = "Microsoft Login"
|
||||||
|
microsoftLogoutTitle = "Microsoft Logout"
|
||||||
|
|
||||||
|
[js.login]
|
||||||
|
login = "LOGIN"
|
||||||
|
loggingIn = "LOGGING IN"
|
||||||
|
success = "SUCCESS"
|
||||||
|
tryAgain = "Try Again"
|
||||||
|
|
||||||
|
[js.login.error]
|
||||||
|
invalidValue = "* Invalid Value"
|
||||||
|
requiredValue = "* Required"
|
||||||
|
|
||||||
|
[js.login.error.unknown]
|
||||||
|
title = "Unknown Error During Login"
|
||||||
|
desc = "An unknown error has occurred. Please see the console for details."
|
||||||
|
|
||||||
|
[js.landing.launch]
|
||||||
|
pleaseWait = "Please wait.."
|
||||||
|
failureTitle = "Error During Launch"
|
||||||
|
failureText = "See console (CTRL + Shift + i) for more details."
|
||||||
|
okay = "Okay"
|
||||||
|
|
||||||
|
[js.landing.selectedAccount]
|
||||||
|
noAccountSelected = "No Account Selected"
|
||||||
|
|
||||||
|
[js.landing.selectedServer]
|
||||||
|
noSelection = "No Server Selected"
|
||||||
|
loading = "Loading.."
|
||||||
|
|
||||||
|
[js.landing.serverStatus]
|
||||||
|
server = "SERVER"
|
||||||
|
offline = "OFFLINE"
|
||||||
|
players = "PLAYERS"
|
||||||
|
|
||||||
|
[js.landing.systemScan]
|
||||||
|
checking = "Checking system info.."
|
||||||
|
noCompatibleJava = "No Compatible<br>Java Installation Found"
|
||||||
|
installJavaMessage = "In order to launch Minecraft, you need a 64-bit installation of Java {major}. Would you like us to install a copy?"
|
||||||
|
installJava = "Install Java"
|
||||||
|
installJavaManually = "Install Manually"
|
||||||
|
javaDownloadPrepare = "Preparing Java Download.."
|
||||||
|
javaDownloadFailureTitle = "Error During Java Download"
|
||||||
|
javaDownloadFailureText = "See console (CTRL + Shift + i) for more details."
|
||||||
|
javaRequired = "Java is Required<br>to Launch"
|
||||||
|
javaRequiredMessage = 'A valid x64 installation of Java {major} 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.'
|
||||||
|
javaRequiredDismiss = "I Understand"
|
||||||
|
javaRequiredCancel = "Go Back"
|
||||||
|
|
||||||
|
[js.landing.downloadJava]
|
||||||
|
findJdkFailure = "Failed to find OpenJDK distribution."
|
||||||
|
javaDownloadCorruptedError = "Downloaded JDK has a bad hash, the file may be corrupted."
|
||||||
|
extractingJava = "Extracting Java"
|
||||||
|
javaInstalled = "Java Installed!"
|
||||||
|
|
||||||
|
[js.landing.dlAsync]
|
||||||
|
loadingServerInfo = "Loading server information.."
|
||||||
|
fatalError = "Fatal Error"
|
||||||
|
unableToLoadDistributionIndex = "Could not load a copy of the distribution index. See the console (CTRL + Shift + i) for more details."
|
||||||
|
pleaseWait = "Please wait.."
|
||||||
|
errorDuringLaunchTitle = "Error During Launch"
|
||||||
|
seeConsoleForDetails = "See console (CTRL + Shift + i) for more details."
|
||||||
|
validatingFileIntegrity = "Validating file integrity.."
|
||||||
|
errorDuringFileVerificationTitle = "Error During File Verification"
|
||||||
|
downloadingFiles = "Downloading files.."
|
||||||
|
errorDuringFileDownloadTitle = "Error During File Download"
|
||||||
|
preparingToLaunch = "Preparing to launch.."
|
||||||
|
launchingGame = "Launching game.."
|
||||||
|
launchWrapperNotDownloaded = "The main file, LaunchWrapper, failed to download properly. As a result, the game cannot launch.<br><br>To fix this issue, temporarily turn off your antivirus software and launch the game again.<br><br>If you have time, please <a href=\"https://github.com/dscalzi/HeliosLauncher/issues\">submit an issue</a> and let us know what antivirus software you use. We'll contact them and try to straighten things out."
|
||||||
|
doneEnjoyServer = "Done. Enjoy the server!"
|
||||||
|
checkConsoleForDetails = "Please check the console (CTRL + Shift + i) for more details."
|
||||||
|
|
||||||
|
[js.landing.news]
|
||||||
|
checking = "Checking for News"
|
||||||
|
|
||||||
|
[js.landing.discord]
|
||||||
|
loading = "Loading game.."
|
||||||
|
joining = "Sailing to Westeros!"
|
||||||
|
joined = "Exploring the Realm!"
|
||||||
|
|
||||||
|
[js.overlay]
|
||||||
|
dismiss = "Dismiss"
|
||||||
|
|
||||||
|
[js.settings.fileSelectors]
|
||||||
|
executables = "Executables"
|
||||||
|
allFiles = "All Files"
|
||||||
|
|
||||||
|
[js.settings.mstfLogin]
|
||||||
|
errorTitle = "Something Went Wrong"
|
||||||
|
errorMessage = "Microsoft authentication failed. Please try again."
|
||||||
|
okButton = "OK"
|
||||||
|
|
||||||
|
[js.settings.mstfLogout]
|
||||||
|
errorTitle = "Something Went Wrong"
|
||||||
|
errorMessage = "Microsoft logout failed. Please try again."
|
||||||
|
okButton = "OK"
|
||||||
|
|
||||||
|
[js.settings.authAccountSelect]
|
||||||
|
selectButton = "Select Account"
|
||||||
|
selectedButton = "Selected Account ✔"
|
||||||
|
|
||||||
|
[js.settings.authAccountLogout]
|
||||||
|
lastAccountWarningTitle = "Warning<br>This is Your Last Account"
|
||||||
|
lastAccountWarningMessage = "In order to use the launcher you must be logged into at least one account. You will need to login again after.<br><br>Are you sure you want to log out?"
|
||||||
|
confirmButton = "I'm Sure"
|
||||||
|
cancelButton = "Cancel"
|
||||||
|
|
||||||
|
[js.settings.authAccountPopulate]
|
||||||
|
username = "Username"
|
||||||
|
uuid = "UUID"
|
||||||
|
selectAccount = "Select Account"
|
||||||
|
selectedAccount = "Selected Account ✓"
|
||||||
|
logout = "Log Out"
|
||||||
|
|
||||||
|
[js.settings.dropinMods]
|
||||||
|
removeButton = "Remove"
|
||||||
|
deleteFailedTitle = "Failed to Delete<br>Drop-in Mod {fullName}"
|
||||||
|
deleteFailedMessage = "Make sure the file is not in use and try again."
|
||||||
|
failedToggleTitle = "Failed to Toggle<br>One or More Drop-in Mods"
|
||||||
|
okButton = "Okay"
|
||||||
|
|
||||||
|
[js.settings.serverListing]
|
||||||
|
mainServer = "Main Server"
|
||||||
|
|
||||||
|
[js.settings.java]
|
||||||
|
selectedJava = "Selected: Java {version} ({vendor})"
|
||||||
|
invalidSelection = "Invalid Selection"
|
||||||
|
requiresJava = "Requires Java {major} x64."
|
||||||
|
availableOptions = "Available Options for Java {major} (HotSpot VM)"
|
||||||
|
|
||||||
|
[js.settings.about]
|
||||||
|
preReleaseTitle = "Pre-release"
|
||||||
|
stableReleaseTitle = "Stable Release"
|
||||||
|
releaseNotesFailed = "Failed to load release notes."
|
||||||
|
|
||||||
|
[js.settings.updates]
|
||||||
|
newReleaseTitle = "New Release Available"
|
||||||
|
newPreReleaseTitle = "New Pre-release Available"
|
||||||
|
downloadingButton = "Downloading.."
|
||||||
|
downloadButton = 'Download from GitHub<span style="font-size: 10px;color: gray;text-shadow: none !important;">Close the launcher and run the dmg to update.</span>'
|
||||||
|
latestVersionTitle = "You Are Running the Latest Version"
|
||||||
|
checkForUpdatesButton = "Check for Updates"
|
||||||
|
checkingForUpdatesButton = "Checking for Updates.."
|
||||||
|
|
||||||
|
[js.uibinder.startup]
|
||||||
|
fatalErrorTitle = "Fatal Error: Unable to Load Distribution Index"
|
||||||
|
fatalErrorMessage = "A connection could not be established to our servers to download the distribution index. No local copies were available to load. <br><br>The distribution index is an essential file which provides the latest server information. The launcher is unable to start without it. Ensure you are connected to the internet and relaunch the application."
|
||||||
|
closeButton = "Close"
|
||||||
|
|
||||||
|
[js.uibinder.validateAccount]
|
||||||
|
failedMessageTitle = "Failed to Refresh Login"
|
||||||
|
failedMessage = "We were unable to refresh the login for <strong>{account}</strong>. Please select another account or login again."
|
||||||
|
failedMessageSelectAnotherAccount = "We were unable to refresh the login for <strong>{account}</strong>. Please login again."
|
||||||
|
loginButton = "Login"
|
||||||
|
selectAnotherAccountButton = "Select Another Account"
|
||||||
|
|
||||||
|
[js.uicore.autoUpdate]
|
||||||
|
checkingForUpdateButton = "Checking for Updates..."
|
||||||
|
installNowButton = "Install Now"
|
||||||
|
checkForUpdatesButton = "Check for Updates"
|
@ -13,7 +13,9 @@
|
|||||||
<% } else{ %>
|
<% } else{ %>
|
||||||
<div id="frameContentWin">
|
<div id="frameContentWin">
|
||||||
<div id="frameTitleDock">
|
<div id="frameTitleDock">
|
||||||
<span id="frameTitleText">Fromagerie Launcher</span>
|
|
||||||
|
<span id="frameTitleText"><%= lang('app.title') %></span>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div id="frameButtonDockWin">
|
<div id="frameButtonDockWin">
|
||||||
<button class="frameButton fMb" id="frameButton_minimize" tabIndex="-1">
|
<button class="frameButton fMb" id="frameButton_minimize" tabIndex="-1">
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
<div id="left">
|
<div id="left">
|
||||||
<div id="image_seal_container">
|
<div id="image_seal_container">
|
||||||
<img id="image_seal" src="assets/images/SealCircle.png"/>
|
<img id="image_seal" src="assets/images/SealCircle.png"/>
|
||||||
<div id="updateAvailableTooltip">Update Available</div>
|
<div id="updateAvailableTooltip"><%- lang('landing.updateAvailableTooltip') %></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="content">
|
<div id="content">
|
||||||
@ -11,9 +11,9 @@
|
|||||||
<div id="right">
|
<div id="right">
|
||||||
<div id="rightContainer">
|
<div id="rightContainer">
|
||||||
<div id="user_content">
|
<div id="user_content">
|
||||||
<span id="user_text">Username</span>
|
<span id="user_text"><%- lang('landing.usernamePlaceholder') %></span>
|
||||||
<div id="avatarContainer">
|
<div id="avatarContainer">
|
||||||
<button id="avatarOverlay">Edit</button>
|
<button id="avatarOverlay"><%- lang('landing.usernameEditButton') %></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="mediaContent">
|
<div id="mediaContent">
|
||||||
@ -23,14 +23,16 @@
|
|||||||
<svg id="settingsSVG" class="mediaSVG" viewBox="0 0 141.36 137.43">
|
<svg id="settingsSVG" class="mediaSVG" viewBox="0 0 141.36 137.43">
|
||||||
<path d="M70.70475616319865,83.36934004916053 a15.320781354859122,15.320781354859122 0 1 1 14.454501310561755,-15.296030496450625 A14.850515045097694,14.850515045097694 0 0 1 70.70475616319865,83.36934004916053 M123.25082856443602,55.425620905968366 h-12.375429204248078 A45.54157947163293,45.54157947163293 0 0 0 107.21227231573047,46.243052436416285 l8.613298726156664,-9.108315894326587 a9.727087354538993,9.727087354538993 0 0 0 0,-13.167456673319956 l-3.465120177189462,-3.6631270444574313 a8.489544434114185,8.489544434114185 0 0 0 -12.375429204248078,0 l-8.613298726156664,9.108315894326587 A40.442902639482725,40.442902639482725 0 0 0 81.99114759747292,25.427580514871032 V12.532383284044531 a9.108315894326587,9.108315894326587 0 0 0 -8.811305593424633,-9.306322761594556 h-4.950171681699231 a9.108315894326587,9.108315894326587 0 0 0 -8.811305593424633,9.306322761594556 v12.895197230826497 a40.17064319698927,40.17064319698927 0 0 0 -9.331073620003052,4.0591407789933704 l-8.613298726156664,-9.108315894326587 a8.489544434114185,8.489544434114185 0 0 0 -12.375429204248078,0 L25.58394128451018,23.967279868769744 a9.727087354538993,9.727087354538993 0 0 0 0,13.167456673319956 L34.19724001066683,46.243052436416285 a45.07131316187151,45.07131316187151 0 0 0 -3.6631270444574313,9.083565035918088 h-12.375429204248078 a9.083565035918088,9.083565035918088 0 0 0 -8.811305593424633,9.306322761594556 v5.197680265784193 a9.108315894326587,9.108315894326587 0 0 0 8.811305593424633,9.306322761594556 h11.979415469712139 a45.69008462208391,45.69008462208391 0 0 0 4.0591407789933704,10.642869115653347 l-8.613298726156664,9.108315894326587 a9.727087354538993,9.727087354538993 0 0 0 0,13.167456673319956 l3.465120177189462,3.6631270444574313 a8.489544434114185,8.489544434114185 0 0 0 12.375429204248078,0 l8.613298726156664,-9.108315894326587 a40.49240435629971,40.49240435629971 0 0 0 9.331073620003052,4.0591407789933704 v12.895197230826497 a9.083565035918088,9.083565035918088 0 0 0 8.811305593424633,9.306322761594556 h4.950171681699231 A9.083565035918088,9.083565035918088 0 0 0 81.99114759747292,123.68848839660077 V110.79329116577425 a40.78941465720167,40.78941465720167 0 0 0 9.331073620003052,-4.0591407789933704 l8.613298726156664,9.108315894326587 a8.489544434114185,8.489544434114185 0 0 0 12.375429204248078,0 l3.465120177189462,-3.6631270444574313 a9.727087354538993,9.727087354538993 0 0 0 0,-13.167456673319956 l-8.613298726156664,-9.108315894326587 a45.665333763675406,45.665333763675406 0 0 0 4.034389920584874,-10.642869115653347 h12.004166328120636 a9.108315894326587,9.108315894326587 0 0 0 8.811305593424633,-9.306322761594556 v-5.197680265784193 a9.083565035918088,9.083565035918088 0 0 0 -8.811305593424633,-9.306322761594556 " id="svg_3" class=""/>
|
<path d="M70.70475616319865,83.36934004916053 a15.320781354859122,15.320781354859122 0 1 1 14.454501310561755,-15.296030496450625 A14.850515045097694,14.850515045097694 0 0 1 70.70475616319865,83.36934004916053 M123.25082856443602,55.425620905968366 h-12.375429204248078 A45.54157947163293,45.54157947163293 0 0 0 107.21227231573047,46.243052436416285 l8.613298726156664,-9.108315894326587 a9.727087354538993,9.727087354538993 0 0 0 0,-13.167456673319956 l-3.465120177189462,-3.6631270444574313 a8.489544434114185,8.489544434114185 0 0 0 -12.375429204248078,0 l-8.613298726156664,9.108315894326587 A40.442902639482725,40.442902639482725 0 0 0 81.99114759747292,25.427580514871032 V12.532383284044531 a9.108315894326587,9.108315894326587 0 0 0 -8.811305593424633,-9.306322761594556 h-4.950171681699231 a9.108315894326587,9.108315894326587 0 0 0 -8.811305593424633,9.306322761594556 v12.895197230826497 a40.17064319698927,40.17064319698927 0 0 0 -9.331073620003052,4.0591407789933704 l-8.613298726156664,-9.108315894326587 a8.489544434114185,8.489544434114185 0 0 0 -12.375429204248078,0 L25.58394128451018,23.967279868769744 a9.727087354538993,9.727087354538993 0 0 0 0,13.167456673319956 L34.19724001066683,46.243052436416285 a45.07131316187151,45.07131316187151 0 0 0 -3.6631270444574313,9.083565035918088 h-12.375429204248078 a9.083565035918088,9.083565035918088 0 0 0 -8.811305593424633,9.306322761594556 v5.197680265784193 a9.108315894326587,9.108315894326587 0 0 0 8.811305593424633,9.306322761594556 h11.979415469712139 a45.69008462208391,45.69008462208391 0 0 0 4.0591407789933704,10.642869115653347 l-8.613298726156664,9.108315894326587 a9.727087354538993,9.727087354538993 0 0 0 0,13.167456673319956 l3.465120177189462,3.6631270444574313 a8.489544434114185,8.489544434114185 0 0 0 12.375429204248078,0 l8.613298726156664,-9.108315894326587 a40.49240435629971,40.49240435629971 0 0 0 9.331073620003052,4.0591407789933704 v12.895197230826497 a9.083565035918088,9.083565035918088 0 0 0 8.811305593424633,9.306322761594556 h4.950171681699231 A9.083565035918088,9.083565035918088 0 0 0 81.99114759747292,123.68848839660077 V110.79329116577425 a40.78941465720167,40.78941465720167 0 0 0 9.331073620003052,-4.0591407789933704 l8.613298726156664,9.108315894326587 a8.489544434114185,8.489544434114185 0 0 0 12.375429204248078,0 l3.465120177189462,-3.6631270444574313 a9.727087354538993,9.727087354538993 0 0 0 0,-13.167456673319956 l-8.613298726156664,-9.108315894326587 a45.665333763675406,45.665333763675406 0 0 0 4.034389920584874,-10.642869115653347 h12.004166328120636 a9.108315894326587,9.108315894326587 0 0 0 8.811305593424633,-9.306322761594556 v-5.197680265784193 a9.083565035918088,9.083565035918088 0 0 0 -8.811305593424633,-9.306322761594556 " id="svg_3" class=""/>
|
||||||
</svg>
|
</svg>
|
||||||
<div id="settingsTooltip">Settings</div>
|
<div id="settingsTooltip"><%- lang('landing.settingsTooltip') %></div>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="mediaDivider"></div>
|
<div class="mediaDivider"></div>
|
||||||
<div id="externalMedia">
|
<div id="externalMedia">
|
||||||
<div class="mediaContainer">
|
<div class="mediaContainer">
|
||||||
|
|
||||||
<a href="https://discord.gg/U9xmJd8rBW" class="mediaURL" id="discordURL">
|
<a href="https://discord.gg/U9xmJd8rBW" class="mediaURL" id="discordURL">
|
||||||
|
|
||||||
<svg id="discordSVG" class="mediaSVG" viewBox="35.34 34.3575 70.68 68.71500">
|
<svg id="discordSVG" class="mediaSVG" viewBox="35.34 34.3575 70.68 68.71500">
|
||||||
<g>
|
<g>
|
||||||
<path d="M81.23,78.48a6.14,6.14,0,1,1,6.14-6.14,6.14,6.14,0,0,1-6.14,6.14M60,78.48a6.14,6.14,0,1,1,6.14-6.14A6.14,6.14,0,0,1,60,78.48M104.41,73c-.92-7.7-8.24-22.9-8.24-22.9A43,43,0,0,0,88,45.59a17.88,17.88,0,0,0-8.38-1.27l-.13,1.06a23.52,23.52,0,0,1,5.8,1.95,87.59,87.59,0,0,1,8.17,4.87s-10.32-5.63-22.27-5.63a51.32,51.32,0,0,0-23.2,5.63,87.84,87.84,0,0,1,8.17-4.87,23.57,23.57,0,0,1,5.8-1.95l-.13-1.06a17.88,17.88,0,0,0-8.38,1.27,42.84,42.84,0,0,0-8.21,4.56S37.87,65.35,37,73s-.37,11.54-.37,11.54,4.22,5.68,9.9,7.14,7.7,1.47,7.7,1.47l3.75-4.68a21.22,21.22,0,0,1-4.65-2A24.47,24.47,0,0,1,47.93,82S61.16,88.4,70.68,88.4c10,0,22.75-6.44,22.75-6.44a24.56,24.56,0,0,1-5.35,4.56,21.22,21.22,0,0,1-4.65,2l3.75,4.68s2,0,7.7-1.47,9.89-7.14,9.89-7.14.55-3.85-.37-11.54"/>
|
<path d="M81.23,78.48a6.14,6.14,0,1,1,6.14-6.14,6.14,6.14,0,0,1-6.14,6.14M60,78.48a6.14,6.14,0,1,1,6.14-6.14A6.14,6.14,0,0,1,60,78.48M104.41,73c-.92-7.7-8.24-22.9-8.24-22.9A43,43,0,0,0,88,45.59a17.88,17.88,0,0,0-8.38-1.27l-.13,1.06a23.52,23.52,0,0,1,5.8,1.95,87.59,87.59,0,0,1,8.17,4.87s-10.32-5.63-22.27-5.63a51.32,51.32,0,0,0-23.2,5.63,87.84,87.84,0,0,1,8.17-4.87,23.57,23.57,0,0,1,5.8-1.95l-.13-1.06a17.88,17.88,0,0,0-8.38,1.27,42.84,42.84,0,0,0-8.21,4.56S37.87,65.35,37,73s-.37,11.54-.37,11.54,4.22,5.68,9.9,7.14,7.7,1.47,7.7,1.47l3.75-4.68a21.22,21.22,0,0,1-4.65-2A24.47,24.47,0,0,1,47.93,82S61.16,88.4,70.68,88.4c10,0,22.75-6.44,22.75-6.44a24.56,24.56,0,0,1-5.35,4.56,21.22,21.22,0,0,1-4.65,2l3.75,4.68s2,0,7.7-1.47,9.89-7.14,9.89-7.14.55-3.85-.37-11.54"/>
|
||||||
@ -48,21 +50,21 @@
|
|||||||
<div class="bot_wrapper">
|
<div class="bot_wrapper">
|
||||||
<div id="content">
|
<div id="content">
|
||||||
<div id="server_status_wrapper">
|
<div id="server_status_wrapper">
|
||||||
<span class="bot_label" id="landingPlayerLabel">SERVER</span>
|
<span class="bot_label" id="landingPlayerLabel"><%- lang('landing.serverStatus') %></span>
|
||||||
<span id="player_count">OFFLINE</span>
|
<span id="player_count"><%- lang('landing.serverStatusPlaceholder') %></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="bot_divider"></div>
|
<div class="bot_divider"></div>
|
||||||
<div id="mojangStatusWrapper">
|
<div id="mojangStatusWrapper">
|
||||||
<span class="bot_label">MOJANG STATUS</span>
|
<span class="bot_label"><%- lang('landing.mojangStatus') %></span>
|
||||||
<span id="mojang_status_icon">•</span>
|
<span id="mojang_status_icon">•</span>
|
||||||
<div id="mojangStatusTooltip">
|
<div id="mojangStatusTooltip">
|
||||||
<div id="mojangStatusTooltipTitle">Services</div>
|
<div id="mojangStatusTooltipTitle"><%- lang('landing.mojangStatusTooltipTitle') %></div>
|
||||||
<div id="mojangStatusEssentialContainer">
|
<div id="mojangStatusEssentialContainer">
|
||||||
<!-- Essential Mojang services are populated here. -->
|
<!-- Essential Mojang services are populated here. -->
|
||||||
</div>
|
</div>
|
||||||
<div id="mojangStatusNEContainer">
|
<div id="mojangStatusNEContainer">
|
||||||
<div class="mojangStatusNEBar"></div>
|
<div class="mojangStatusNEBar"></div>
|
||||||
<div id="mojangStatusNETitle">Non Essential</div>
|
<div id="mojangStatusNETitle"><%- lang('landing.mojangStatusNETitle') %></div>
|
||||||
<div class="mojangStatusNEBar"></div>
|
<div class="mojangStatusNEBar"></div>
|
||||||
</div>
|
</div>
|
||||||
<div id="mojangStatusNonEssentialContainer">
|
<div id="mojangStatusNonEssentialContainer">
|
||||||
@ -76,15 +78,16 @@
|
|||||||
<div id="center">
|
<div id="center">
|
||||||
<div class="bot_wrapper">
|
<div class="bot_wrapper">
|
||||||
<div id="content">
|
<div id="content">
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="right">
|
<div id="right">
|
||||||
<div class="bot_wrapper">
|
<div class="bot_wrapper">
|
||||||
<div id="launch_content">
|
<div id="launch_content">
|
||||||
<button id="launch_button">PLAY</button>
|
<button id="launch_button"><%- lang('landing.launchButton') %></button>
|
||||||
<div class="bot_divider"></div>
|
<div class="bot_divider"></div>
|
||||||
<button id="server_selection_button" class="bot_label">• No Server Selected</button>
|
<button id="server_selection_button" class="bot_label"><%- lang('landing.launchButtonPlaceholder') %></button>
|
||||||
</div>
|
</div>
|
||||||
<div id="launch_details">
|
<div id="launch_details">
|
||||||
<div id="launch_details_left">
|
<div id="launch_details_left">
|
||||||
@ -93,12 +96,13 @@
|
|||||||
</div>
|
</div>
|
||||||
<div id="launch_details_right">
|
<div id="launch_details_right">
|
||||||
<progress id="launch_progress" value="22" max="100"></progress>
|
<progress id="launch_progress" value="22" max="100"></progress>
|
||||||
<span id="launch_details_text" class="bot_label">Please wait..</span>
|
<span id="launch_details_text" class="bot_label"><%- lang('landing.launchDetails') %></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<script src="./assets/js/scripts/landing.js"></script>
|
<script src="./assets/js/scripts/landing.js"></script>
|
||||||
</div>
|
</div>
|
@ -2,21 +2,21 @@
|
|||||||
<div id="loginCancelContainer" style="display: none;">
|
<div id="loginCancelContainer" style="display: none;">
|
||||||
<button id="loginCancelButton">
|
<button id="loginCancelButton">
|
||||||
<div id="loginCancelIcon">X</div>
|
<div id="loginCancelIcon">X</div>
|
||||||
<span id="loginCancelText">Cancel</span>
|
<span id="loginCancelText"><%- lang('login.loginCancelText') %></span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div id="loginContent">
|
<div id="loginContent">
|
||||||
<form id="loginForm">
|
<form id="loginForm">
|
||||||
<img id="loginImageSeal" src="assets/images/SealCircle.png"/>
|
<img id="loginImageSeal" src="assets/images/SealCircle.png"/>
|
||||||
<span id="loginSubheader">MINECRAFT LOGIN</span>
|
<span id="loginSubheader"><%- lang('login.loginSubheader') %></span>
|
||||||
<div class="loginFieldContainer">
|
<div class="loginFieldContainer">
|
||||||
<svg id="profileSVG" class="loginSVG" viewBox="40 37 65.36 61.43">
|
<svg id="profileSVG" class="loginSVG" viewBox="40 37 65.36 61.43">
|
||||||
<g>
|
<g>
|
||||||
<path d="M86.77,58.12A13.79,13.79,0,1,0,73,71.91,13.79,13.79,0,0,0,86.77,58.12M97,103.67a3.41,3.41,0,0,0,3.39-3.84,27.57,27.57,0,0,0-54.61,0,3.41,3.41,0,0,0,3.39,3.84Z"/>
|
<path d="M86.77,58.12A13.79,13.79,0,1,0,73,71.91,13.79,13.79,0,0,0,86.77,58.12M97,103.67a3.41,3.41,0,0,0,3.39-3.84,27.57,27.57,0,0,0-54.61,0,3.41,3.41,0,0,0,3.39,3.84Z"/>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
<span class="loginErrorSpan" id="loginEmailError">* Invalid Value</span>
|
<span class="loginErrorSpan" id="loginEmailError"><%- lang('login.loginEmailError') %></span>
|
||||||
<input id="loginUsername" class="loginField" type="text" placeholder="EMAIL OR USERNAME"/>
|
<input id="loginUsername" class="loginField" type="text" placeholder="<%- lang('login.loginEmailPlaceholder') %>"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="loginFieldContainer">
|
<div class="loginFieldContainer">
|
||||||
<svg id="lockSVG" class="loginSVG" viewBox="40 32 60.36 70.43">
|
<svg id="lockSVG" class="loginSVG" viewBox="40 32 60.36 70.43">
|
||||||
@ -24,22 +24,22 @@
|
|||||||
<path d="M86.16,54a16.38,16.38,0,1,0-32,0H44V102.7H96V54Zm-25.9-3.39a9.89,9.89,0,1,1,19.77,0A9.78,9.78,0,0,1,79.39,54H60.89A9.78,9.78,0,0,1,60.26,50.59ZM70,96.2a6.5,6.5,0,0,1-6.5-6.5,6.39,6.39,0,0,1,3.1-5.4V67h6.5V84.11a6.42,6.42,0,0,1,3.39,5.6A6.5,6.5,0,0,1,70,96.2Z"/>
|
<path d="M86.16,54a16.38,16.38,0,1,0-32,0H44V102.7H96V54Zm-25.9-3.39a9.89,9.89,0,1,1,19.77,0A9.78,9.78,0,0,1,79.39,54H60.89A9.78,9.78,0,0,1,60.26,50.59ZM70,96.2a6.5,6.5,0,0,1-6.5-6.5,6.39,6.39,0,0,1,3.1-5.4V67h6.5V84.11a6.42,6.42,0,0,1,3.39,5.6A6.5,6.5,0,0,1,70,96.2Z"/>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
<span class="loginErrorSpan" id="loginPasswordError">* Required</span>
|
<span class="loginErrorSpan" id="loginPasswordError"><%- lang('login.loginPasswordError') %></span>
|
||||||
<input id="loginPassword" class="loginField" type="password" placeholder="PASSWORD"/>
|
<input id="loginPassword" class="loginField" type="password" placeholder="<%- lang('login.loginPasswordPlaceholder') %>"/>
|
||||||
</div>
|
</div>
|
||||||
<div id="loginOptions">
|
<div id="loginOptions">
|
||||||
<span class="loginSpanDim">
|
<span class="loginSpanDim">
|
||||||
<a href="https://minecraft.net/password/forgot/">forgot password?</a>
|
<a href="<%- lang('login.loginForgotPasswordLink') %>"><%- lang('login.loginForgotPasswordText') %></a>
|
||||||
</span>
|
</span>
|
||||||
<label id="checkmarkContainer">
|
<label id="checkmarkContainer">
|
||||||
<input id="loginRememberOption" type="checkbox" checked>
|
<input id="loginRememberOption" type="checkbox" checked>
|
||||||
<span id="loginRememberText" class="loginSpanDim">remember me?</span>
|
<span id="loginRememberText" class="loginSpanDim"><%- lang('login.loginRememberMeText') %></span>
|
||||||
<span class="loginCheckmark"></span>
|
<span class="loginCheckmark"></span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<button id="loginButton" disabled>
|
<button id="loginButton" disabled>
|
||||||
<div id="loginButtonContent">
|
<div id="loginButtonContent">
|
||||||
LOGIN
|
<%- lang('login.loginButtonText') %>
|
||||||
<svg id="loginSVG" viewBox="0 0 24.87 13.97">
|
<svg id="loginSVG" viewBox="0 0 24.87 13.97">
|
||||||
<defs>
|
<defs>
|
||||||
<style>.arrowLine{fill:none;stroke:#FFF;stroke-width:2px;transition: 0.25s ease;}</style>
|
<style>.arrowLine{fill:none;stroke:#FFF;stroke-width:2px;transition: 0.25s ease;}</style>
|
||||||
@ -54,10 +54,10 @@
|
|||||||
</button>
|
</button>
|
||||||
<div id="loginDisclaimer">
|
<div id="loginDisclaimer">
|
||||||
<span class="loginSpanDim" id="loginRegisterSpan">
|
<span class="loginSpanDim" id="loginRegisterSpan">
|
||||||
<a href="https://minecraft.net/store/minecraft-java-edition/">Need an Account?</a>
|
<a href="<%- lang('login.loginNeedAccountLink') %>"><%- lang('login.loginNeedAccountText') %></a>
|
||||||
</span>
|
</span>
|
||||||
<p class="loginDisclaimerText">Your password is sent directly to mojang and never stored.</p>
|
<p class="loginDisclaimerText"><%- lang('login.loginPasswordDisclaimer1') %></p>
|
||||||
<p class="loginDisclaimerText">Helios Launcher is not affiliated with Mojang AB.</p>
|
<p class="loginDisclaimerText"><%- lang('login.loginPasswordDisclaimer2', { appName: lang('app.title') }) %></p>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<div id="loginOptionsContainer" style="display: none;">
|
<div id="loginOptionsContainer" style="display: none;">
|
||||||
<div id="loginOptionsContent">
|
<div id="loginOptionsContent">
|
||||||
<div class="loginOptionsMainContent">
|
<div class="loginOptionsMainContent">
|
||||||
<h2>Login Options</h2>
|
<h2><%- lang('loginOptions.loginOptionsTitle') %></h2>
|
||||||
<div class="loginOptionActions">
|
<div class="loginOptionActions">
|
||||||
<div class="loginOptionButtonContainer">
|
<div class="loginOptionButtonContainer">
|
||||||
<button id="loginOptionMicrosoft" class="loginOptionButton">
|
<button id="loginOptionMicrosoft" class="loginOptionButton">
|
||||||
@ -11,7 +11,7 @@
|
|||||||
<path fill="#05a6f0" d="M1 12h10v10H1z" />
|
<path fill="#05a6f0" d="M1 12h10v10H1z" />
|
||||||
<path fill="#ffba08" d="M12 12h10v10H12z" />
|
<path fill="#ffba08" d="M12 12h10v10H12z" />
|
||||||
</svg>
|
</svg>
|
||||||
<span>Login with Microsoft</span>
|
<span><%- lang('loginOptions.loginWithMicrosoft') %></span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="loginOptionButtonContainer">
|
<div class="loginOptionButtonContainer">
|
||||||
@ -21,12 +21,12 @@
|
|||||||
<path d="M2.598.022h7.07L9.665 7c-.003 1.334-1.113 2.46-2.402 2.654H0V2.542C.134 1.2 1.3.195 2.598.022z" fill="#db2331" />
|
<path d="M2.598.022h7.07L9.665 7c-.003 1.334-1.113 2.46-2.402 2.654H0V2.542C.134 1.2 1.3.195 2.598.022z" fill="#db2331" />
|
||||||
<path d="M1.54 2.844c.314-.76 1.31-.46 1.954-.528.785-.083 1.503.272 2.1.758l.164-.9c.327.345.587.756.964 1.052.28.254.655-.342.86-.013.42.864.408 1.86.54 2.795l-.788-.373C6.9 4.17 5.126 3.052 3.656 3.685c-1.294.592-1.156 2.65.06 3.255 1.354.703 2.953.51 4.405.292-.07.42-.34.87-.834.816l-4.95.002c-.5.055-.886-.413-.838-.89l.04-4.315z" fill="#fff" />
|
<path d="M1.54 2.844c.314-.76 1.31-.46 1.954-.528.785-.083 1.503.272 2.1.758l.164-.9c.327.345.587.756.964 1.052.28.254.655-.342.86-.013.42.864.408 1.86.54 2.795l-.788-.373C6.9 4.17 5.126 3.052 3.656 3.685c-1.294.592-1.156 2.65.06 3.255 1.354.703 2.953.51 4.405.292-.07.42-.34.87-.834.816l-4.95.002c-.5.055-.886-.413-.838-.89l.04-4.315z" fill="#fff" />
|
||||||
</svg>
|
</svg>
|
||||||
<span>Login with Mojang</span>
|
<span><%- lang('loginOptions.loginWithMojang') %></span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="loginOptionCancelContainer" style="display: none;">
|
<div id="loginOptionCancelContainer" style="display: none;">
|
||||||
<button id="loginOptionCancelButton">Cancel</button>
|
<button id="loginOptionCancelButton"><%- lang('loginOptions.cancelButton') %></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,29 +1,29 @@
|
|||||||
<div id="overlayContainer" style="display: none;">
|
<div id="overlayContainer" style="display: none;">
|
||||||
<div id="serverSelectContent" style="display: none;">
|
<div id="serverSelectContent" style="display: none;">
|
||||||
<span id="serverSelectHeader">Available Servers</span>
|
<span id="serverSelectHeader"><%- lang('overlay.serverSelectHeader') %></span>
|
||||||
<div id="serverSelectList">
|
<div id="serverSelectList">
|
||||||
<div id="serverSelectListScrollable">
|
<div id="serverSelectListScrollable">
|
||||||
<!-- Server listings populated here. -->
|
<!-- Server listings populated here. -->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="serverSelectActions">
|
<div id="serverSelectActions">
|
||||||
<button id="serverSelectConfirm" class="overlayKeybindEnter" type="submit">Select</button>
|
<button id="serverSelectConfirm" class="overlayKeybindEnter" type="submit"><%- lang('overlay.serverSelectConfirm') %></button>
|
||||||
<div id="serverSelectCancelWrapper">
|
<div id="serverSelectCancelWrapper">
|
||||||
<button id="serverSelectCancel" class="overlayKeybindEsc">Cancel</button>
|
<button id="serverSelectCancel" class="overlayKeybindEsc"><%- lang('overlay.serverSelectCancel') %></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="accountSelectContent" style="display: none;">
|
<div id="accountSelectContent" style="display: none;">
|
||||||
<span id="accountSelectHeader">Select an Account</span>
|
<span id="accountSelectHeader"><%- lang('overlay.accountSelectHeader') %></span>
|
||||||
<div id="accountSelectList">
|
<div id="accountSelectList">
|
||||||
<div id="accountSelectListScrollable">
|
<div id="accountSelectListScrollable">
|
||||||
<!-- Accounts populated here. -->
|
<!-- Accounts populated here. -->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="accountSelectActions">
|
<div id="accountSelectActions">
|
||||||
<button id="accountSelectConfirm" class="overlayKeybindEnter" type="submit">Select</button>
|
<button id="accountSelectConfirm" class="overlayKeybindEnter" type="submit"><%- lang('overlay.accountSelectConfirm') %></button>
|
||||||
<div id="accountSelectCancelWrapper">
|
<div id="accountSelectCancelWrapper">
|
||||||
<button id="accountSelectCancel" class="overlayKeybindEsc">Cancel</button>
|
<button id="accountSelectCancel" class="overlayKeybindEsc"><%- lang('overlay.accountSelectCancel') %></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
152
app/settings.ejs
152
app/settings.ejs
@ -2,21 +2,21 @@
|
|||||||
<div id="settingsContainerLeft">
|
<div id="settingsContainerLeft">
|
||||||
<div id="settingsNavContainer">
|
<div id="settingsNavContainer">
|
||||||
<div id="settingsNavHeader">
|
<div id="settingsNavHeader">
|
||||||
<span id="settingsNavHeaderText">Settings</span>
|
<span id="settingsNavHeaderText"><%- lang('settings.navHeaderText') %></span>
|
||||||
</div>
|
</div>
|
||||||
<div id="settingsNavItemsContainer">
|
<div id="settingsNavItemsContainer">
|
||||||
<div id="settingsNavItemsContent">
|
<div id="settingsNavItemsContent">
|
||||||
<button class="settingsNavItem" rSc="settingsTabAccount" id="settingsNavAccount" selected>Account</button>
|
<button class="settingsNavItem" rSc="settingsTabAccount" id="settingsNavAccount" selected><%- lang('settings.navAccount') %></button>
|
||||||
<button class="settingsNavItem" rSc="settingsTabMinecraft">Minecraft</button>
|
<button class="settingsNavItem" rSc="settingsTabMinecraft"><%- lang('settings.navMinecraft') %></button>
|
||||||
<button class="settingsNavItem" rSc="settingsTabMods">Mods</button>
|
<button class="settingsNavItem" rSc="settingsTabMods"><%- lang('settings.navMods') %></button>
|
||||||
<button class="settingsNavItem" rSc="settingsTabJava">Java</button>
|
<button class="settingsNavItem" rSc="settingsTabJava"><%- lang('settings.navJava') %></button>
|
||||||
<button class="settingsNavItem" rSc="settingsTabLauncher">Launcher</button>
|
<button class="settingsNavItem" rSc="settingsTabLauncher"><%- lang('settings.navLauncher') %></button>
|
||||||
<div class="settingsNavSpacer"></div>
|
<div class="settingsNavSpacer"></div>
|
||||||
<button class="settingsNavItem" rSc="settingsTabAbout">About</button>
|
<button class="settingsNavItem" rSc="settingsTabAbout"><%- lang('settings.navAbout') %></button>
|
||||||
<button class="settingsNavItem" rSc="settingsTabUpdate" id="settingsNavUpdate">Updates</button>
|
<button class="settingsNavItem" rSc="settingsTabUpdate" id="settingsNavUpdate"><%- lang('settings.navUpdates') %></button>
|
||||||
<div id="settingsNavContentBottom">
|
<div id="settingsNavContentBottom">
|
||||||
<div class="settingsNavDivider"></div>
|
<div class="settingsNavDivider"></div>
|
||||||
<button id="settingsNavDone">Done</button>
|
<button id="settingsNavDone"><%- lang('settings.navDone') %></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -25,8 +25,8 @@
|
|||||||
<div id="settingsContainerRight">
|
<div id="settingsContainerRight">
|
||||||
<div id="settingsTabAccount" class="settingsTab">
|
<div id="settingsTabAccount" class="settingsTab">
|
||||||
<div class="settingsTabHeader">
|
<div class="settingsTabHeader">
|
||||||
<span class="settingsTabHeaderText">Account Settings</span>
|
<span class="settingsTabHeaderText"><%- lang('settings.tabAccountHeaderText') %></span>
|
||||||
<span class="settingsTabHeaderDesc">Add new accounts or manage existing ones.</span>
|
<span class="settingsTabHeaderDesc"><%- lang('settings.tabAccountHeaderDesc') %></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="settingsAuthAccountTypeContainer">
|
<div class="settingsAuthAccountTypeContainer">
|
||||||
<div class="settingsAuthAccountTypeHeader">
|
<div class="settingsAuthAccountTypeHeader">
|
||||||
@ -37,10 +37,10 @@
|
|||||||
<path fill="#05a6f0" d="M1 12h10v10H1z" />
|
<path fill="#05a6f0" d="M1 12h10v10H1z" />
|
||||||
<path fill="#ffba08" d="M12 12h10v10H12z" />
|
<path fill="#ffba08" d="M12 12h10v10H12z" />
|
||||||
</svg>
|
</svg>
|
||||||
<span>Microsoft</span>
|
<span><%- lang('settings.microsoftAccount') %></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="settingsAuthAccountTypeHeaderRight">
|
<div class="settingsAuthAccountTypeHeaderRight">
|
||||||
<button class="settingsAddAuthAccount" id="settingsAddMicrosoftAccount">+ Add Microsoft Account</button>
|
<button class="settingsAddAuthAccount" id="settingsAddMicrosoftAccount"><%- lang('settings.addMicrosoftAccount') %></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -57,10 +57,10 @@
|
|||||||
<path d="M2.598.022h7.07L9.665 7c-.003 1.334-1.113 2.46-2.402 2.654H0V2.542C.134 1.2 1.3.195 2.598.022z" fill="#db2331" />
|
<path d="M2.598.022h7.07L9.665 7c-.003 1.334-1.113 2.46-2.402 2.654H0V2.542C.134 1.2 1.3.195 2.598.022z" fill="#db2331" />
|
||||||
<path d="M1.54 2.844c.314-.76 1.31-.46 1.954-.528.785-.083 1.503.272 2.1.758l.164-.9c.327.345.587.756.964 1.052.28.254.655-.342.86-.013.42.864.408 1.86.54 2.795l-.788-.373C6.9 4.17 5.126 3.052 3.656 3.685c-1.294.592-1.156 2.65.06 3.255 1.354.703 2.953.51 4.405.292-.07.42-.34.87-.834.816l-4.95.002c-.5.055-.886-.413-.838-.89l.04-4.315z" fill="#fff" />
|
<path d="M1.54 2.844c.314-.76 1.31-.46 1.954-.528.785-.083 1.503.272 2.1.758l.164-.9c.327.345.587.756.964 1.052.28.254.655-.342.86-.013.42.864.408 1.86.54 2.795l-.788-.373C6.9 4.17 5.126 3.052 3.656 3.685c-1.294.592-1.156 2.65.06 3.255 1.354.703 2.953.51 4.405.292-.07.42-.34.87-.834.816l-4.95.002c-.5.055-.886-.413-.838-.89l.04-4.315z" fill="#fff" />
|
||||||
</svg>
|
</svg>
|
||||||
<span>Mojang</span>
|
<span><%- lang('settings.mojangAccount') %></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="settingsAuthAccountTypeHeaderRight">
|
<div class="settingsAuthAccountTypeHeaderRight">
|
||||||
<button class="settingsAddAuthAccount" id="settingsAddMojangAccount">+ Add Mojang Account</button>
|
<button class="settingsAddAuthAccount" id="settingsAddMojangAccount"><%- lang('settings.addMojangAccount') %></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -71,11 +71,11 @@
|
|||||||
</div>
|
</div>
|
||||||
<div id="settingsTabMinecraft" class="settingsTab" style="display: none;">
|
<div id="settingsTabMinecraft" class="settingsTab" style="display: none;">
|
||||||
<div class="settingsTabHeader">
|
<div class="settingsTabHeader">
|
||||||
<span class="settingsTabHeaderText">Minecraft Settings</span>
|
<span class="settingsTabHeaderText"><%- lang('settings.minecraftTabHeaderText') %></span>
|
||||||
<span class="settingsTabHeaderDesc">Options related to game launch.</span>
|
<span class="settingsTabHeaderDesc"><%- lang('settings.minecraftTabHeaderDesc') %></span>
|
||||||
</div>
|
</div>
|
||||||
<div id="settingsGameResolutionContainer">
|
<div id="settingsGameResolutionContainer">
|
||||||
<span class="settingsFieldTitle">Game Resolution</span>
|
<span class="settingsFieldTitle"><%- lang('settings.gameResolutionTitle') %></span>
|
||||||
<div id="settingsGameResolutionContent">
|
<div id="settingsGameResolutionContent">
|
||||||
<input type="number" id="settingsGameWidth" min="0" cValue="GameWidth">
|
<input type="number" id="settingsGameWidth" min="0" cValue="GameWidth">
|
||||||
<div id="settingsGameResolutionCross">✖</div>
|
<div id="settingsGameResolutionCross">✖</div>
|
||||||
@ -84,7 +84,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="settingsFieldContainer">
|
<div class="settingsFieldContainer">
|
||||||
<div class="settingsFieldLeft">
|
<div class="settingsFieldLeft">
|
||||||
<span class="settingsFieldTitle">Launch in fullscreen.</span>
|
<span class="settingsFieldTitle"><%- lang('settings.launchFullscreenTitle') %></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="settingsFieldRight">
|
<div class="settingsFieldRight">
|
||||||
<label class="toggleSwitch">
|
<label class="toggleSwitch">
|
||||||
@ -95,7 +95,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="settingsFieldContainer">
|
<div class="settingsFieldContainer">
|
||||||
<div class="settingsFieldLeft">
|
<div class="settingsFieldLeft">
|
||||||
<span class="settingsFieldTitle">Automatically connect to the server on launch.</span>
|
<span class="settingsFieldTitle"><%- lang('settings.autoConnectTitle') %></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="settingsFieldRight">
|
<div class="settingsFieldRight">
|
||||||
<label class="toggleSwitch">
|
<label class="toggleSwitch">
|
||||||
@ -106,8 +106,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="settingsFieldContainer">
|
<div class="settingsFieldContainer">
|
||||||
<div class="settingsFieldLeft">
|
<div class="settingsFieldLeft">
|
||||||
<span class="settingsFieldTitle">Launch game process detached from launcher.</span>
|
<span class="settingsFieldTitle"><%- lang('settings.launchDetachedTitle') %></span>
|
||||||
<span class="settingsFieldDesc">If the game is not detached, closing the launcher will also close the game.</span>
|
<span class="settingsFieldDesc"><%- lang('settings.launchDetachedDesc') %></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="settingsFieldRight">
|
<div class="settingsFieldRight">
|
||||||
<label class="toggleSwitch">
|
<label class="toggleSwitch">
|
||||||
@ -119,8 +119,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<div id="settingsTabMods" class="settingsTab" style="display: none;">
|
<div id="settingsTabMods" class="settingsTab" style="display: none;">
|
||||||
<div class="settingsTabHeader">
|
<div class="settingsTabHeader">
|
||||||
<span class="settingsTabHeaderText">Mod Settings</span>
|
<span class="settingsTabHeaderText"><%- lang('settings.tabModsHeaderText') %></span>
|
||||||
<span class="settingsTabHeaderDesc">Enable or disable mods.</span>
|
<span class="settingsTabHeaderDesc"><%- lang('settings.tabModsHeaderDesc') %></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="settingsSelServContainer">
|
<div class="settingsSelServContainer">
|
||||||
<div class="settingsSelServContent">
|
<div class="settingsSelServContent">
|
||||||
@ -128,37 +128,37 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="settingsSwitchServerContainer">
|
<div class="settingsSwitchServerContainer">
|
||||||
<div class="settingsSwitchServerContent">
|
<div class="settingsSwitchServerContent">
|
||||||
<button class="settingsSwitchServerButton">Switch</button>
|
<button class="settingsSwitchServerButton"><%- lang('settings.switchServerButton') %></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="settingsModsContainer">
|
<div id="settingsModsContainer">
|
||||||
<div id="settingsReqModsContainer">
|
<div id="settingsReqModsContainer">
|
||||||
<div class="settingsModsHeader">Required Mods</div>
|
<div class="settingsModsHeader"><%- lang('settings.requiredMods') %></div>
|
||||||
<div id="settingsReqModsContent">
|
<div id="settingsReqModsContent">
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="settingsOptModsContainer">
|
<div id="settingsOptModsContainer">
|
||||||
<div class="settingsModsHeader">Optional Mods</div>
|
<div class="settingsModsHeader"><%- lang('settings.optionalMods') %></div>
|
||||||
<div id="settingsOptModsContent">
|
<div id="settingsOptModsContent">
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="settingsDropinModsContainer">
|
<div id="settingsDropinModsContainer">
|
||||||
<div class="settingsModsHeader">Drop-in Mods</div>
|
<div class="settingsModsHeader"><%- lang('settings.dropinMods') %></div>
|
||||||
<button id="settingsDropinFileSystemButton">+ Add Mods <span id="settingsDropinRefreshNote">(F5 to Refresh)</span></button>
|
<button id="settingsDropinFileSystemButton"><%- lang('settings.addMods') %> <span id="settingsDropinRefreshNote"><%- lang('settings.dropinRefreshNote') %></span></button>
|
||||||
<div id="settingsDropinModsContent">
|
<div id="settingsDropinModsContent">
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="settingsShadersContainer">
|
<div id="settingsShadersContainer">
|
||||||
<div class="settingsModsHeader">Shaderpacks</div>
|
<div class="settingsModsHeader"><%- lang('settings.shaderpacks') %></div>
|
||||||
<div id="settingsShaderpackDesc">Enable or disable shaders. Please note, shaders will only run smoothly on powerful setups. You may add custom packs here.</div>
|
<div id="settingsShaderpackDesc"><%- lang('settings.shaderpackDesc') %></div>
|
||||||
<div id="settingsShaderpackWrapper">
|
<div id="settingsShaderpackWrapper">
|
||||||
<button id="settingsShaderpackButton"> + </button>
|
<button id="settingsShaderpackButton"> + </button>
|
||||||
<div class="settingsSelectContainer">
|
<div class="settingsSelectContainer">
|
||||||
<div class="settingsSelectSelected" id="settingsShadersSelected">Select Shaderpack</div>
|
<div class="settingsSelectSelected" id="settingsShadersSelected"><%- lang('settings.selectShaderpack') %></div>
|
||||||
<div class="settingsSelectOptions" id="settingsShadersOptions" hidden>
|
<div class="settingsSelectOptions" id="settingsShadersOptions" hidden>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@ -169,8 +169,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<div id="settingsTabJava" class="settingsTab" style="display: none;">
|
<div id="settingsTabJava" class="settingsTab" style="display: none;">
|
||||||
<div class="settingsTabHeader">
|
<div class="settingsTabHeader">
|
||||||
<span class="settingsTabHeaderText">Java Settings</span>
|
<span class="settingsTabHeaderText"><%- lang('settings.tabJavaHeaderText') %></span>
|
||||||
<span class="settingsTabHeaderDesc">Manage the Java configuration (advanced).</span>
|
<span class="settingsTabHeaderDesc"><%- lang('settings.tabJavaHeaderDesc') %></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="settingsSelServContainer">
|
<div class="settingsSelServContainer">
|
||||||
<div class="settingsSelServContent">
|
<div class="settingsSelServContent">
|
||||||
@ -178,16 +178,16 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="settingsSwitchServerContainer">
|
<div class="settingsSwitchServerContainer">
|
||||||
<div class="settingsSwitchServerContent">
|
<div class="settingsSwitchServerContent">
|
||||||
<button class="settingsSwitchServerButton">Switch</button>
|
<button class="settingsSwitchServerButton"><%- lang('settings.switchServerButton') %></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="settingsMemoryContainer">
|
<div id="settingsMemoryContainer">
|
||||||
<div id="settingsMemoryTitle">Memory</div>
|
<div id="settingsMemoryTitle"><%- lang('settings.memoryTitle') %></div>
|
||||||
<div id="settingsMemoryContent">
|
<div id="settingsMemoryContent">
|
||||||
<div id="settingsMemoryContentLeft">
|
<div id="settingsMemoryContentLeft">
|
||||||
<div class="settingsMemoryContentItem">
|
<div class="settingsMemoryContentItem">
|
||||||
<span class="settingsMemoryHeader">Maximum RAM</span>
|
<span class="settingsMemoryHeader"><%- lang('settings.maxRAM') %></span>
|
||||||
<div class="settingsMemoryActionContainer">
|
<div class="settingsMemoryActionContainer">
|
||||||
<div id="settingsMaxRAMRange" class="rangeSlider" cValue="MaxRAM" serverDependent min="3" max="8" value="3" step="0.5">
|
<div id="settingsMaxRAMRange" class="rangeSlider" cValue="MaxRAM" serverDependent min="3" max="8" value="3" step="0.5">
|
||||||
<div class="rangeSliderBar"></div>
|
<div class="rangeSliderBar"></div>
|
||||||
@ -197,7 +197,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="settingsMemoryContentItem">
|
<div class="settingsMemoryContentItem">
|
||||||
<span class="settingsMemoryHeader">Minimum RAM</span>
|
<span class="settingsMemoryHeader"><%- lang('settings.minRAM') %></span>
|
||||||
<div class="settingsMemoryActionContainer">
|
<div class="settingsMemoryActionContainer">
|
||||||
<div id="settingsMinRAMRange" class="rangeSlider" cValue="MinRAM" serverDependent min="3" max="8" value="3" step="0.5">
|
<div id="settingsMinRAMRange" class="rangeSlider" cValue="MinRAM" serverDependent min="3" max="8" value="3" step="0.5">
|
||||||
<div class="rangeSliderBar"></div>
|
<div class="rangeSliderBar"></div>
|
||||||
@ -206,16 +206,16 @@
|
|||||||
<span id="settingsMinRAMLabel" class="settingsMemoryLabel">3G</span>
|
<span id="settingsMinRAMLabel" class="settingsMemoryLabel">3G</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="settingsMemoryDesc">The recommended minimum RAM is 3 gigabytes. Setting the minimum and maximum values to the same value may reduce lag.</div>
|
<div id="settingsMemoryDesc"><%- lang('settings.memoryDesc') %></div>
|
||||||
</div>
|
</div>
|
||||||
<div id="settingsMemoryContentRight">
|
<div id="settingsMemoryContentRight">
|
||||||
<div id="settingsMemoryStatus">
|
<div id="settingsMemoryStatus">
|
||||||
<div class="settingsMemoryStatusContainer">
|
<div class="settingsMemoryStatusContainer">
|
||||||
<span class="settingsMemoryStatusTitle">Total</span>
|
<span class="settingsMemoryStatusTitle"><%- lang('settings.memoryTotalTitle') %></span>
|
||||||
<span id="settingsMemoryTotal" class="settingsMemoryStatusValue">16G</span>
|
<span id="settingsMemoryTotal" class="settingsMemoryStatusValue">16G</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="settingsMemoryStatusContainer">
|
<div class="settingsMemoryStatusContainer">
|
||||||
<span class="settingsMemoryStatusTitle">Available</span>
|
<span class="settingsMemoryStatusTitle"><%- lang('settings.memoryAvailableTitle') %></span>
|
||||||
<span id="settingsMemoryAvail" class="settingsMemoryStatusValue">7.3G</span>
|
<span id="settingsMemoryAvail" class="settingsMemoryStatusValue">7.3G</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -223,9 +223,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="settingsFileSelContainer">
|
<div class="settingsFileSelContainer">
|
||||||
<div class="settingsFileSelTitle">Java Executable</div>
|
<div class="settingsFileSelTitle"><%- lang('settings.javaExecutableTitle') %></div>
|
||||||
<div class="settingsFileSelContent">
|
<div class="settingsFileSelContent">
|
||||||
<div id="settingsJavaExecDetails">Selected: Java 8 Update 172 (x64)</div>
|
<div id="settingsJavaExecDetails"><!-- Invalid Selection --></div>
|
||||||
<div class="settingsFileSelActions">
|
<div class="settingsFileSelActions">
|
||||||
<div class="settingsFileSelIcon">
|
<div class="settingsFileSelIcon">
|
||||||
<svg class="settingsFileSelSVG" x="0px" y="0px" viewBox="0 0 305.001 305.001">
|
<svg class="settingsFileSelSVG" x="0px" y="0px" viewBox="0 0 305.001 305.001">
|
||||||
@ -242,13 +242,13 @@
|
|||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<input class="settingsFileSelVal" id="settingsJavaExecVal" type="text" value="null" cValue="JavaExecutable" serverDependent disabled>
|
<input class="settingsFileSelVal" id="settingsJavaExecVal" type="text" value="null" cValue="JavaExecutable" serverDependent disabled>
|
||||||
<button class="settingsFileSelButton" id="settingsJavaExecSel" dialogTitle="Select Java Executable" dialogDirectory="false">Choose File</button>
|
<button class="settingsFileSelButton" id="settingsJavaExecSel" dialogTitle="<%- lang('settings.javaExecSelDialogTitle') %>" dialogDirectory="false"><%- lang('settings.javaExecSelButtonText') %></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="settingsFileSelDesc">The Java executable is validated before game launch. <strong id="settingsJavaReqDesc">Requires Java 8 x64.</strong><br>The path should end with <strong>bin<%= process.platform === 'win32' ? '\\javaw.exe' : '/java' %></strong>.</div>
|
<div class="settingsFileSelDesc"><%- lang('settings.javaExecDesc') %> <strong id="settingsJavaReqDesc"><!-- Requires Java 8 x64. --></strong><br><%- lang('settings.javaPathDesc', {'pathSuffix': `bin${process.platform === 'win32' ? '\\javaw.exe' : '/java'}`}) %></div>
|
||||||
</div>
|
</div>
|
||||||
<div id="settingsJVMOptsContainer">
|
<div id="settingsJVMOptsContainer">
|
||||||
<div id="settingsJVMOptsTitle">Additional JVM Options</div>
|
<div id="settingsJVMOptsTitle"><%- lang('settings.jvmOptsTitle') %></div>
|
||||||
<div id="settingsJVMOptsContent">
|
<div id="settingsJVMOptsContent">
|
||||||
<div class="settingsFileSelIcon">
|
<div class="settingsFileSelIcon">
|
||||||
<svg class="settingsFileSelSVG" x="0px" y="0px" viewBox="0 0 305.001 305.001">
|
<svg class="settingsFileSelSVG" x="0px" y="0px" viewBox="0 0 305.001 305.001">
|
||||||
@ -266,18 +266,18 @@
|
|||||||
</div>
|
</div>
|
||||||
<input id="settingsJVMOptsVal" cValue="JVMOptions" serverDependent type="text">
|
<input id="settingsJVMOptsVal" cValue="JVMOptions" serverDependent type="text">
|
||||||
</div>
|
</div>
|
||||||
<div id="settingsJVMOptsDesc">Options to be provided to the JVM at runtime. <em>-Xms</em> and <em>-Xmx</em> should not be included.<br><a href="https://docs.oracle.com/javase/8/docs/technotes/tools/<%= process.platform === 'win32' ? 'windows' : 'unix' %>/java.html" id="settingsJvmOptsLink">Available Options for Java 8</a>.</div>
|
<div id="settingsJVMOptsDesc"><%- lang('settings.jvmOptsDesc') %><br><a href="#" id="settingsJvmOptsLink"><!-- Available Options --></a></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="settingsTabLauncher" class="settingsTab" style="display: none;">
|
<div id="settingsTabLauncher" class="settingsTab" style="display: none;">
|
||||||
<div class="settingsTabHeader">
|
<div class="settingsTabHeader">
|
||||||
<span class="settingsTabHeaderText">Launcher Settings</span>
|
<span class="settingsTabHeaderText"><%- lang('settings.launcherTabHeaderText') %></span>
|
||||||
<span class="settingsTabHeaderDesc">Options related to the launcher itself.</span>
|
<span class="settingsTabHeaderDesc"><%- lang('settings.launcherTabHeaderDesc') %></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="settingsFieldContainer">
|
<div class="settingsFieldContainer">
|
||||||
<div class="settingsFieldLeft">
|
<div class="settingsFieldLeft">
|
||||||
<span class="settingsFieldTitle">Allow Pre-Release Updates.</span>
|
<span class="settingsFieldTitle"><%- lang('settings.allowPrereleaseTitle') %></span>
|
||||||
<span class="settingsFieldDesc">Pre-Releases include new features which may have not been fully tested or integrated.<br>This will always be true if you are using a pre-release version.</span>
|
<span class="settingsFieldDesc"><%- lang('settings.allowPrereleaseDesc') %></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="settingsFieldRight">
|
<div class="settingsFieldRight">
|
||||||
<label class="toggleSwitch">
|
<label class="toggleSwitch">
|
||||||
@ -288,7 +288,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="settingsFileSelContainer">
|
<div class="settingsFileSelContainer">
|
||||||
<div class="settingsFileSelContent">
|
<div class="settingsFileSelContent">
|
||||||
<div class="settingsFieldTitle" id="settingsDataDirTitle">Data Directory</div>
|
<div class="settingsFieldTitle" id="settingsDataDirTitle"><%- lang('settings.dataDirectoryTitle') %></div>
|
||||||
<div class="settingsFileSelActions">
|
<div class="settingsFileSelActions">
|
||||||
<div class="settingsFileSelIcon">
|
<div class="settingsFileSelIcon">
|
||||||
<svg class="settingsFileSelSVG">
|
<svg class="settingsFileSelSVG">
|
||||||
@ -300,90 +300,90 @@
|
|||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<input class="settingsFileSelVal" type="text" value="null" cValue="DataDirectory" disabled>
|
<input class="settingsFileSelVal" type="text" value="null" cValue="DataDirectory" disabled>
|
||||||
<button class="settingsFileSelButton" dialogTitle="Select Data Directory" dialogDirectory="true">Choose Folder</button>
|
<button class="settingsFileSelButton" dialogTitle="<%- lang('settings.selectDataDirectory') %>" dialogDirectory="true"><%- lang('settings.chooseFolder') %></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="settingsFileSelDesc">All game files and local Java installations will be stored in the data directory.<br>Screenshots and world saves are stored in the instance folder for the corresponding server configuration.</div>
|
<div class="settingsFileSelDesc"><%- lang('settings.dataDirectoryDesc') %></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="settingsTabAbout" class="settingsTab" style="display: none;">
|
<div id="settingsTabAbout" class="settingsTab" style="display: none;">
|
||||||
<div class="settingsTabHeader">
|
<div class="settingsTabHeader">
|
||||||
<span class="settingsTabHeaderText">About</span>
|
<span class="settingsTabHeaderText"><%- lang('settings.aboutTabHeaderText') %></span>
|
||||||
<span class="settingsTabHeaderDesc">View information and release notes for the current version.</span>
|
<span class="settingsTabHeaderDesc"><%- lang('settings.aboutTabHeaderDesc') %></span>
|
||||||
</div>
|
</div>
|
||||||
<div id="settingsAboutCurrentContainer">
|
<div id="settingsAboutCurrentContainer">
|
||||||
<div id="settingsAboutCurrentContent">
|
<div id="settingsAboutCurrentContent">
|
||||||
<div id="settingsAboutCurrentHeadline">
|
<div id="settingsAboutCurrentHeadline">
|
||||||
<img id="settingsAboutLogo" src="./assets/images/SealCircle.png">
|
<img id="settingsAboutLogo" src="./assets/images/SealCircle.png">
|
||||||
<span id="settingsAboutTitle">Helios Launcher</span>
|
<span id="settingsAboutTitle"><%- lang('settings.aboutTitle', { appName: lang('app.title') }) %></span>
|
||||||
</div>
|
</div>
|
||||||
<div id="settingsAboutCurrentVersion">
|
<div id="settingsAboutCurrentVersion">
|
||||||
<div id="settingsAboutCurrentVersionCheck">✓</div>
|
<div id="settingsAboutCurrentVersionCheck">✓</div>
|
||||||
<div id="settingsAboutCurrentVersionDetails">
|
<div id="settingsAboutCurrentVersionDetails">
|
||||||
<span id="settingsAboutCurrentVersionTitle">Stable Release</span>
|
<span id="settingsAboutCurrentVersionTitle"><%- lang('settings.stableRelease') %></span>
|
||||||
<div id="settingsAboutCurrentVersionLine">
|
<div id="settingsAboutCurrentVersionLine">
|
||||||
<span id="settingsAboutCurrentVersionText">Version </span>
|
<span id="settingsAboutCurrentVersionText"><%- lang('settings.versionText') %></span>
|
||||||
<span id="settingsAboutCurrentVersionValue">0.0.1-alpha.12</span>
|
<span id="settingsAboutCurrentVersionValue">0.0.1-alpha.18</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="settingsAboutButtons">
|
<div id="settingsAboutButtons">
|
||||||
<a href="https://github.com/dscalZi/HeliosLauncher" id="settingsAboutSourceButton" class="settingsAboutButton">Source (GitHub)</a>
|
<a href="<%- lang('settings.sourceGithubLink') %>" id="settingsAboutSourceButton" class="settingsAboutButton"><%- lang('settings.sourceGithub') %></a>
|
||||||
<!-- The following must be included in third-party usage. -->
|
<!-- The following must be included in third-party usage. -->
|
||||||
<!-- <a href="https://github.com/dscalzi/HeliosLauncher" id="settingsAboutSourceButton" class="settingsAboutButton">Original Source</a> -->
|
<!-- <a href="https://github.com/dscalzi/HeliosLauncher" id="settingsAboutSourceButton" class="settingsAboutButton">Original Source</a> -->
|
||||||
<a href="https://github.com/dscalZi/HeliosLauncher/issues" id="settingsAboutSupportButton" class="settingsAboutButton">Support</a>
|
<a href="<%- lang('settings.supportLink') %>" id="settingsAboutSupportButton" class="settingsAboutButton"><%- lang('settings.support') %></a>
|
||||||
<a href="#" id="settingsAboutDevToolsButton" class="settingsAboutButton">DevTools Console</a>
|
<a href="#" id="settingsAboutDevToolsButton" class="settingsAboutButton"><%- lang('settings.devToolsConsole') %></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="settingsChangelogContainer">
|
<div class="settingsChangelogContainer">
|
||||||
<div class="settingsChangelogContent">
|
<div class="settingsChangelogContent">
|
||||||
<div class="settingsChangelogHeadline">
|
<div class="settingsChangelogHeadline">
|
||||||
<div class="settingsChangelogLabel">Release Notes</div>
|
<div class="settingsChangelogLabel"><%- lang('settings.releaseNotes') %></div>
|
||||||
<div class="settingsChangelogTitle">Changelog</div>
|
<div class="settingsChangelogTitle"><%- lang('settings.changelog') %></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="settingsChangelogText">
|
<div class="settingsChangelogText">
|
||||||
No Release Notes
|
<%- lang('settings.noReleaseNotes') %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="settingsChangelogActions">
|
<div class="settingsChangelogActions">
|
||||||
<a class="settingsChangelogButton settingsAboutButton" href="#">View Release Notes on GitHub</a>
|
<a class="settingsChangelogButton settingsAboutButton" href="#"><%- lang('settings.viewReleaseNotes') %></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="settingsTabUpdate" class="settingsTab" style="display: none;">
|
<div id="settingsTabUpdate" class="settingsTab" style="display: none;">
|
||||||
<div class="settingsTabHeader">
|
<div class="settingsTabHeader">
|
||||||
<span class="settingsTabHeaderText">Launcher Updates</span>
|
<span class="settingsTabHeaderText"><%- lang('settings.launcherUpdatesHeaderText') %></span>
|
||||||
<span class="settingsTabHeaderDesc">Download, install, and review updates for the launcher.</span>
|
<span class="settingsTabHeaderDesc"><%- lang('settings.launcherUpdatesHeaderDesc') %></span>
|
||||||
</div>
|
</div>
|
||||||
<div id="settingsUpdateStatusContainer">
|
<div id="settingsUpdateStatusContainer">
|
||||||
<div id="settingsUpdateStatusContent">
|
<div id="settingsUpdateStatusContent">
|
||||||
<div id="settingsUpdateStatusHeadline">
|
<div id="settingsUpdateStatusHeadline">
|
||||||
<span id="settingsUpdateTitle">You Are Running the Latest Version</span>
|
<span id="settingsUpdateTitle"><!-- You Are Running the Latest Version --></span>
|
||||||
</div>
|
</div>
|
||||||
<div id="settingsUpdateVersion">
|
<div id="settingsUpdateVersion">
|
||||||
<div id="settingsUpdateVersionCheck">✓</div>
|
<div id="settingsUpdateVersionCheck">✓</div>
|
||||||
<div id="settingsUpdateVersionDetails">
|
<div id="settingsUpdateVersionDetails">
|
||||||
<span id="settingsUpdateVersionTitle">Stable Release</span>
|
<span id="settingsUpdateVersionTitle"><%- lang('settings.stableRelease') %></span>
|
||||||
<div id="settingsUpdateVersionLine">
|
<div id="settingsUpdateVersionLine">
|
||||||
<span id="settingsUpdateVersionText">Version </span>
|
<span id="settingsUpdateVersionText"><%- lang('settings.versionText') %> </span>
|
||||||
<span id="settingsUpdateVersionValue">0.0.1-alpha.18</span>
|
<span id="settingsUpdateVersionValue">0.0.1-alpha.18</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="settingsUpdateActionContainer">
|
<div id="settingsUpdateActionContainer">
|
||||||
<button id="settingsUpdateActionButton">Check for Updates</button>
|
<button id="settingsUpdateActionButton"><%- lang('settings.checkForUpdates') %></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="settingsChangelogContainer">
|
<div class="settingsChangelogContainer">
|
||||||
<div class="settingsChangelogContent">
|
<div class="settingsChangelogContent">
|
||||||
<div class="settingsChangelogHeadline">
|
<div class="settingsChangelogHeadline">
|
||||||
<div class="settingsChangelogLabel">What's New</div>
|
<div class="settingsChangelogLabel"><%- lang('settings.whatsNew') %></div>
|
||||||
<div class="settingsChangelogTitle">Update Release Notes</div>
|
<div class="settingsChangelogTitle"><%- lang('settings.updateReleaseNotes') %></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="settingsChangelogText">
|
<div class="settingsChangelogText">
|
||||||
No Release Notes
|
<%- lang('settings.noReleaseNotes') %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<div id="waitingContent">
|
<div id="waitingContent">
|
||||||
<div class="waitingSpinner"></div>
|
<div class="waitingSpinner"></div>
|
||||||
<div id="waitingTextContainer">
|
<div id="waitingTextContainer">
|
||||||
<h2>Waiting for Microsoft..</h2>
|
<h2><%- lang('waiting.waitingText') %></h2>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
@ -5,6 +5,7 @@
|
|||||||
</div>-->
|
</div>-->
|
||||||
<div id="welcomeContent">
|
<div id="welcomeContent">
|
||||||
<img id="welcomeImageSeal" src="assets/images/SealCircle.png"/>
|
<img id="welcomeImageSeal" src="assets/images/SealCircle.png"/>
|
||||||
|
|
||||||
<span id="welcomeHeader">Bienvenue sur le launcher Fromagerie V5</span>
|
<span id="welcomeHeader">Bienvenue sur le launcher Fromagerie V5</span>
|
||||||
<span id="welcomeDescription">en vous souhaitant une agréable experience de jeux </span>
|
<span id="welcomeDescription">en vous souhaitant une agréable experience de jeux </span>
|
||||||
<br>
|
<br>
|
||||||
@ -12,6 +13,7 @@
|
|||||||
<button id="welcomeButton">
|
<button id="welcomeButton">
|
||||||
<div id="welcomeButtonContent">
|
<div id="welcomeButtonContent">
|
||||||
CONTINUER
|
CONTINUER
|
||||||
|
|
||||||
<svg id="welcomeSVG" viewBox="0 0 24.87 13.97">
|
<svg id="welcomeSVG" viewBox="0 0 24.87 13.97">
|
||||||
<defs>
|
<defs>
|
||||||
<style>.arrowLine{fill:none;stroke:#FFF;stroke-width:2px;transition: 0.25s ease;}</style>
|
<style>.arrowLine{fill:none;stroke:#FFF;stroke-width:2px;transition: 0.25s ease;}</style>
|
||||||
|
@ -360,10 +360,12 @@ The resolved/provided paths are appended to a base path depending on the module'
|
|||||||
| Type | Path |
|
| Type | Path |
|
||||||
| ---- | ---- |
|
| ---- | ---- |
|
||||||
| `ForgeHosted` | ({`commonDirectory`}/libraries/{`path` OR resolved}) |
|
| `ForgeHosted` | ({`commonDirectory`}/libraries/{`path` OR resolved}) |
|
||||||
|
| `Fabric` | ({`commonDirectory`}/libraries/{`path` OR resolved}) |
|
||||||
| `LiteLoader` | ({`commonDirectory`}/libraries/{`path` OR resolved}) |
|
| `LiteLoader` | ({`commonDirectory`}/libraries/{`path` OR resolved}) |
|
||||||
| `Library` | ({`commonDirectory`}/libraries/{`path` OR resolved}) |
|
| `Library` | ({`commonDirectory`}/libraries/{`path` OR resolved}) |
|
||||||
| `ForgeMod` | ({`commonDirectory`}/modstore/{`path` OR resolved}) |
|
| `ForgeMod` | ({`commonDirectory`}/modstore/{`path` OR resolved}) |
|
||||||
| `LiteMod` | ({`commonDirectory`}/modstore/{`path` OR resolved}) |
|
| `LiteMod` | ({`commonDirectory`}/modstore/{`path` OR resolved}) |
|
||||||
|
| `FabricMod` | ({`commonDirectory`}/mods/fabric/{`path` OR resolved}) |
|
||||||
| `File` | ({`instanceDirectory`}/{`Server.id`}/{`path` OR resolved}) |
|
| `File` | ({`instanceDirectory`}/{`Server.id`}/{`path` OR resolved}) |
|
||||||
|
|
||||||
The `commonDirectory` and `instanceDirectory` values are stored in the launcher's config.json.
|
The `commonDirectory` and `instanceDirectory` values are stored in the launcher's config.json.
|
||||||
@ -408,7 +410,7 @@ If the module is enabled by default. Has no effect unless `Required.value` is fa
|
|||||||
|
|
||||||
### ForgeHosted
|
### ForgeHosted
|
||||||
|
|
||||||
The module type `ForgeHosted` represents forge itself. Currently, the launcher only supports forge servers, as vanilla servers can be connected to via the mojang launcher. The `Hosted` part is key, this means that the forge module must declare its required libraries as submodules.
|
The module type `ForgeHosted` represents forge itself. Currently, the launcher only supports modded servers, as vanilla servers can be connected to via the mojang launcher. The `Hosted` part is key, this means that the forge module must declare its required libraries as submodules.
|
||||||
|
|
||||||
Ex.
|
Ex.
|
||||||
|
|
||||||
@ -443,6 +445,40 @@ There were plans to add a `Forge` type, in which the required libraries would be
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
### Fabric
|
||||||
|
|
||||||
|
The module type `Fabric` represents the fabric mod loader. Currently, the launcher only supports modded servers, as vanilla servers can be connected to via the mojang launcher.
|
||||||
|
|
||||||
|
Ex.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "net.fabricmc:fabric-loader:0.15.0",
|
||||||
|
"name": "Fabric (fabric-loader)",
|
||||||
|
"type": "Fabric",
|
||||||
|
"artifact": {
|
||||||
|
"size": 1196222,
|
||||||
|
"MD5": "a43d5a142246801343b6cedef1c102c4",
|
||||||
|
"url": "http://localhost:8080/repo/lib/net/fabricmc/fabric-loader/0.15.0/fabric-loader-0.15.0.jar"
|
||||||
|
},
|
||||||
|
"subModules": [
|
||||||
|
{
|
||||||
|
"id": "1.20.1-fabric-0.15.0",
|
||||||
|
"name": "Fabric (version.json)",
|
||||||
|
"type": "VersionManifest",
|
||||||
|
"artifact": {
|
||||||
|
"size": 2847,
|
||||||
|
"MD5": "69a2bd43452325ba1bc882fa0904e054",
|
||||||
|
"url": "http://localhost:8080/repo/versions/1.20.1-fabric-0.15.0/1.20.1-fabric-0.15.0.json"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Fabric works similarly to Forge 1.13+.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
### LiteLoader
|
### LiteLoader
|
||||||
|
|
||||||
The module type `LiteLoader` represents liteloader. It is handled as a library and added to the classpath at runtime. Special launch conditions are executed when liteloader is present and enabled. This module can be optional and toggled similarly to `ForgeMod` and `Litemod` modules.
|
The module type `LiteLoader` represents liteloader. It is handled as a library and added to the classpath at runtime. Special launch conditions are executed when liteloader is present and enabled. This module can be optional and toggled similarly to `ForgeMod` and `Litemod` modules.
|
||||||
|
14
index.js
14
index.js
@ -11,6 +11,10 @@ const path = require('path')
|
|||||||
const semver = require('semver')
|
const semver = require('semver')
|
||||||
const { pathToFileURL } = require('url')
|
const { pathToFileURL } = require('url')
|
||||||
const { AZURE_CLIENT_ID, MSFT_OPCODE, MSFT_REPLY_TYPE, MSFT_ERROR, SHELL_OPCODE } = require('./app/assets/js/ipcconstants')
|
const { AZURE_CLIENT_ID, MSFT_OPCODE, MSFT_REPLY_TYPE, MSFT_ERROR, SHELL_OPCODE } = require('./app/assets/js/ipcconstants')
|
||||||
|
const LangLoader = require('./app/assets/js/langloader')
|
||||||
|
|
||||||
|
// Setup Lang
|
||||||
|
LangLoader.setupLanguage()
|
||||||
|
|
||||||
// Setup auto updater.
|
// Setup auto updater.
|
||||||
function initAutoUpdater(event, data) {
|
function initAutoUpdater(event, data) {
|
||||||
@ -121,7 +125,7 @@ ipcMain.on(MSFT_OPCODE.OPEN_LOGIN, (ipcEvent, ...arguments_) => {
|
|||||||
msftAuthViewSuccess = arguments_[0]
|
msftAuthViewSuccess = arguments_[0]
|
||||||
msftAuthViewOnClose = arguments_[1]
|
msftAuthViewOnClose = arguments_[1]
|
||||||
msftAuthWindow = new BrowserWindow({
|
msftAuthWindow = new BrowserWindow({
|
||||||
title: 'Microsoft Login',
|
title: LangLoader.queryJS('index.microsoftLoginTitle'),
|
||||||
backgroundColor: '#222222',
|
backgroundColor: '#222222',
|
||||||
width: 520,
|
width: 520,
|
||||||
height: 600,
|
height: 600,
|
||||||
@ -174,7 +178,7 @@ ipcMain.on(MSFT_OPCODE.OPEN_LOGOUT, (ipcEvent, uuid, isLastAccount) => {
|
|||||||
msftLogoutSuccess = false
|
msftLogoutSuccess = false
|
||||||
msftLogoutSuccessSent = false
|
msftLogoutSuccessSent = false
|
||||||
msftLogoutWindow = new BrowserWindow({
|
msftLogoutWindow = new BrowserWindow({
|
||||||
title: 'Microsoft Logout',
|
title: LangLoader.queryJS('index.microsoftLogoutTitle'),
|
||||||
backgroundColor: '#222222',
|
backgroundColor: '#222222',
|
||||||
width: 520,
|
width: 520,
|
||||||
height: 600,
|
height: 600,
|
||||||
@ -236,7 +240,11 @@ function createWindow() {
|
|||||||
})
|
})
|
||||||
remoteMain.enable(win.webContents)
|
remoteMain.enable(win.webContents)
|
||||||
|
|
||||||
ejse.data('bkid', Math.floor((Math.random() * fs.readdirSync(path.join(__dirname, 'app', 'assets', 'images', 'backgrounds')).length)))
|
const data = {
|
||||||
|
bkid: Math.floor((Math.random() * fs.readdirSync(path.join(__dirname, 'app', 'assets', 'images', 'backgrounds')).length)),
|
||||||
|
lang: (str, placeHolders) => LangLoader.queryEJS(str, placeHolders)
|
||||||
|
}
|
||||||
|
Object.entries(data).forEach(([key, val]) => ejse.data(key, val))
|
||||||
|
|
||||||
win.loadURL(pathToFileURL(path.join(__dirname, 'app', 'app.ejs')).toString())
|
win.loadURL(pathToFileURL(path.join(__dirname, 'app', 'app.ejs')).toString())
|
||||||
|
|
||||||
|
593
package-lock.json
generated
593
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
24
package.json
24
package.json
@ -1,7 +1,9 @@
|
|||||||
{
|
{
|
||||||
|
|
||||||
"name": "FromagerieLauncher",
|
"name": "FromagerieLauncher",
|
||||||
"version": "2.0.6",
|
"version": "2.1.0",
|
||||||
"productName": "Fromagerie Launcher",
|
"productName": "Fromagerie Launcher",
|
||||||
|
|
||||||
"description": "Modded Minecraft Launcher",
|
"description": "Modded Minecraft Launcher",
|
||||||
"author": "Daniel Scalzi (https://github.com/dscalzi/)",
|
"author": "Daniel Scalzi (https://github.com/dscalzi/)",
|
||||||
"license": "UNLICENSED",
|
"license": "UNLICENSED",
|
||||||
@ -23,24 +25,26 @@
|
|||||||
"node": "18.x.x"
|
"node": "18.x.x"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@electron/remote": "^2.0.10",
|
"@electron/remote": "^2.1.0",
|
||||||
"adm-zip": "^0.5.9",
|
"adm-zip": "^0.5.9",
|
||||||
"discord-rpc-patch": "^4.0.1",
|
"discord-rpc-patch": "^4.0.1",
|
||||||
"ejs": "^3.1.9",
|
"ejs": "^3.1.9",
|
||||||
"ejs-electron": "^2.1.1",
|
"ejs-electron": "^2.1.1",
|
||||||
"electron-updater": "^6.1.1",
|
"electron-updater": "^6.1.7",
|
||||||
"fs-extra": "^11.1.1",
|
"fs-extra": "^11.1.1",
|
||||||
"github-syntax-dark": "^0.5.0",
|
"github-syntax-dark": "^0.5.0",
|
||||||
"got": "^11.8.5",
|
"got": "^11.8.5",
|
||||||
"helios-core": "~2.0.5",
|
"helios-core": "~2.1.0",
|
||||||
"helios-distribution-types": "^1.2.0",
|
"helios-distribution-types": "^1.3.0",
|
||||||
"jquery": "^3.7.0",
|
"jquery": "^3.7.1",
|
||||||
"semver": "^7.5.4"
|
"lodash.merge": "^4.6.2",
|
||||||
|
"semver": "^7.5.4",
|
||||||
|
"toml": "^3.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"electron": "^26.0.0",
|
"electron": "^27.1.3",
|
||||||
"electron-builder": "^24.6.3",
|
"electron-builder": "^24.9.1",
|
||||||
"eslint": "^8.47.0"
|
"eslint": "^8.55.0"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
Loading…
Reference in New Issue
Block a user