Revert "Merge branch 'master' of github.com:dscalzi/HeliosLauncher into dscalzi-master"
This reverts commit 6c7196ad2cf86e0289cc8ca9e3d4f1ea3ad0dd9a, reversing changes made to 3d3055560f06ad47d6c5d3663254852cce1bb9fb.
This commit is contained in:
parent
2643830278
commit
b23c9d0317
@ -5,17 +5,15 @@ const logger = LoggerUtil.getLogger('DiscordWrapper')
|
||||
|
||||
const { Client } = require('discord-rpc-patch')
|
||||
|
||||
const Lang = require('./langloader')
|
||||
|
||||
let client
|
||||
let activity
|
||||
|
||||
exports.initRPC = function(genSettings, servSettings, initialDetails = Lang.queryJS('discord.waiting')){
|
||||
exports.initRPC = function(genSettings, servSettings, initialDetails = 'Waiting for Client..'){
|
||||
client = new Client({ transport: 'ipc' })
|
||||
|
||||
activity = {
|
||||
details: initialDetails,
|
||||
state: Lang.queryJS('discord.state', {shortId: servSettings.shortId}),
|
||||
state: 'Server: ' + servSettings.shortId,
|
||||
largeImageKey: servSettings.largeImageKey,
|
||||
largeImageText: servSettings.largeImageText,
|
||||
smallImageKey: genSettings.smallImageKey,
|
||||
|
@ -1,27 +1,19 @@
|
||||
const fs = require('fs-extra')
|
||||
const path = require('path')
|
||||
const toml = require('toml')
|
||||
const merge = require('lodash.merge')
|
||||
|
||||
let lang
|
||||
|
||||
exports.loadLanguage = function(id){
|
||||
lang = merge(lang || {}, toml.parse(fs.readFileSync(path.join(__dirname, '..', 'lang', `${id}.toml`))) || {})
|
||||
lang = JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'lang', `${id}.json`))) || {}
|
||||
}
|
||||
|
||||
exports.query = function(id, placeHolders){
|
||||
exports.query = function(id){
|
||||
let query = id.split('.')
|
||||
let res = lang
|
||||
for(let q of query){
|
||||
res = res[q]
|
||||
}
|
||||
let text = res === lang ? '' : res
|
||||
if (placeHolders) {
|
||||
Object.entries(placeHolders).forEach(([key, value]) => {
|
||||
text = text.replace(`{${key}}`, value)
|
||||
})
|
||||
}
|
||||
return text
|
||||
return res === lang ? {} : res
|
||||
}
|
||||
|
||||
exports.queryJS = function(id, placeHolders){
|
||||
|
@ -12,23 +12,14 @@ const ConfigManager = require('./configmanager')
|
||||
|
||||
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 {
|
||||
|
||||
constructor(distroServer, vanillaManifest, modManifest, authUser, launcherVersion){
|
||||
constructor(distroServer, versionData, forgeData, authUser, launcherVersion){
|
||||
this.gameDir = path.join(ConfigManager.getInstanceDirectory(), distroServer.rawServer.id)
|
||||
this.commonDir = ConfigManager.getCommonDirectory()
|
||||
this.server = distroServer
|
||||
this.vanillaManifest = vanillaManifest
|
||||
this.modManifest = modManifest
|
||||
this.versionData = versionData
|
||||
this.forgeData = forgeData
|
||||
this.authUser = authUser
|
||||
this.launcherVersion = launcherVersion
|
||||
this.forgeModListFile = path.join(this.gameDir, 'forgeMods.list') // 1.13+
|
||||
@ -37,7 +28,6 @@ class ProcessBuilder {
|
||||
this.libPath = path.join(this.commonDir, 'libraries')
|
||||
|
||||
this.usingLiteLoader = false
|
||||
this.usingFabricLoader = false
|
||||
this.llPath = null
|
||||
}
|
||||
|
||||
@ -50,12 +40,9 @@ class ProcessBuilder {
|
||||
process.throwDeprecation = true
|
||||
this.setupLiteLoader()
|
||||
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)
|
||||
|
||||
// Mod list below 1.13
|
||||
// Fabric only supports 1.14+
|
||||
if(!mcVersionAtLeast('1.13', this.server.rawServer.minecraftVersion)){
|
||||
this.constructJSONModList('forge', modObj.fMods, true)
|
||||
if(this.usingLiteLoader){
|
||||
@ -179,7 +166,7 @@ class ProcessBuilder {
|
||||
|
||||
for(let mdl of mdls){
|
||||
const type = mdl.rawModule.type
|
||||
if(type === Type.ForgeMod || type === Type.LiteMod || type === Type.LiteLoader || type === Type.FabricMod){
|
||||
if(type === Type.ForgeMod || type === Type.LiteMod || type === Type.LiteLoader){
|
||||
const o = !mdl.getRequired().value
|
||||
const e = ProcessBuilder.isModEnabled(modCfg[mdl.getVersionlessMavenIdentifier()], mdl.getRequired())
|
||||
if(!o || (o && e)){
|
||||
@ -191,7 +178,7 @@ class ProcessBuilder {
|
||||
continue
|
||||
}
|
||||
}
|
||||
if(type === Type.ForgeMod || type === Type.FabricMod){
|
||||
if(type === Type.ForgeMod){
|
||||
fMods.push(mdl)
|
||||
} else {
|
||||
lMods.push(mdl)
|
||||
@ -207,7 +194,7 @@ class ProcessBuilder {
|
||||
}
|
||||
|
||||
_lteMinorVersion(version) {
|
||||
return Number(this.modManifest.id.split('-')[0].split('.')[1]) <= Number(version)
|
||||
return Number(this.forgeData.id.split('-')[0].split('.')[1]) <= Number(version)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -219,7 +206,7 @@ class ProcessBuilder {
|
||||
if(this._lteMinorVersion(9)) {
|
||||
return false
|
||||
}
|
||||
const ver = this.modManifest.id.split('-')[2]
|
||||
const ver = this.forgeData.id.split('-')[2]
|
||||
const pts = ver.split('.')
|
||||
const min = [14, 23, 3, 2655]
|
||||
for(let i=0; i<pts.length; i++){
|
||||
@ -295,21 +282,18 @@ class ProcessBuilder {
|
||||
// }
|
||||
|
||||
/**
|
||||
* Construct the mod argument list for forge 1.13 and Fabric
|
||||
* Construct the mod argument list for forge 1.13
|
||||
*
|
||||
* @param {Array.<Object>} mods An array of mods to add to the mod list.
|
||||
*/
|
||||
constructModList(mods) {
|
||||
const writeBuffer = mods.map(mod => {
|
||||
return this.usingFabricLoader ? mod.getPath() : mod.getExtensionlessMavenIdentifier()
|
||||
return mod.getExtensionlessMavenIdentifier()
|
||||
}).join('\n')
|
||||
|
||||
if(writeBuffer) {
|
||||
fs.writeFileSync(this.forgeModListFile, writeBuffer, 'UTF-8')
|
||||
return this.usingFabricLoader ? [
|
||||
'--fabric.addMods',
|
||||
`@${this.forgeModListFile}`
|
||||
] : [
|
||||
return [
|
||||
'--fml.mavenRoots',
|
||||
path.join('..', '..', 'common', 'modstore'),
|
||||
'--fml.modLists',
|
||||
@ -323,17 +307,12 @@ class ProcessBuilder {
|
||||
|
||||
_processAutoConnectArg(args){
|
||||
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(this.server.hostname)
|
||||
args.push('--port')
|
||||
args.push(this.server.port)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct the argument array that will be passed to the JVM process.
|
||||
@ -377,7 +356,7 @@ class ProcessBuilder {
|
||||
args.push('-Djava.library.path=' + tempNativePath)
|
||||
|
||||
// Main Java Class
|
||||
args.push(this.modManifest.mainClass)
|
||||
args.push(this.forgeData.mainClass)
|
||||
|
||||
// Forge Arguments
|
||||
args = args.concat(this._resolveForgeArgs())
|
||||
@ -400,17 +379,17 @@ class ProcessBuilder {
|
||||
const argDiscovery = /\${*(.*)}/
|
||||
|
||||
// JVM Arguments First
|
||||
let args = this.vanillaManifest.arguments.jvm
|
||||
let args = this.versionData.arguments.jvm
|
||||
|
||||
// Debug securejarhandler
|
||||
// args.push('-Dbsl.debug=true')
|
||||
|
||||
if(this.modManifest.arguments.jvm != null) {
|
||||
for(const argStr of this.modManifest.arguments.jvm) {
|
||||
if(this.forgeData.arguments.jvm != null) {
|
||||
for(const argStr of this.forgeData.arguments.jvm) {
|
||||
args.push(argStr
|
||||
.replaceAll('${library_directory}', this.libPath)
|
||||
.replaceAll('${classpath_separator}', ProcessBuilder.getClasspathSeparator())
|
||||
.replaceAll('${version_name}', this.modManifest.id)
|
||||
.replaceAll('${version_name}', this.forgeData.id)
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -427,10 +406,10 @@ class ProcessBuilder {
|
||||
args = args.concat(ConfigManager.getJVMOptions(this.server.rawServer.id))
|
||||
|
||||
// Main Java Class
|
||||
args.push(this.modManifest.mainClass)
|
||||
args.push(this.forgeData.mainClass)
|
||||
|
||||
// Vanilla Arguments
|
||||
args = args.concat(this.vanillaManifest.arguments.game)
|
||||
args = args.concat(this.versionData.arguments.game)
|
||||
|
||||
for(let i=0; i<args.length; i++){
|
||||
if(typeof args[i] === 'object' && args[i].rules != null){
|
||||
@ -487,7 +466,7 @@ class ProcessBuilder {
|
||||
val = this.authUser.displayName.trim()
|
||||
break
|
||||
case 'version_name':
|
||||
//val = vanillaManifest.id
|
||||
//val = versionData.id
|
||||
val = this.server.rawServer.id
|
||||
break
|
||||
case 'game_directory':
|
||||
@ -497,7 +476,7 @@ class ProcessBuilder {
|
||||
val = path.join(this.commonDir, 'assets')
|
||||
break
|
||||
case 'assets_index_name':
|
||||
val = this.vanillaManifest.assets
|
||||
val = this.versionData.assets
|
||||
break
|
||||
case 'auth_uuid':
|
||||
val = this.authUser.uuid.trim()
|
||||
@ -509,7 +488,7 @@ class ProcessBuilder {
|
||||
val = this.authUser.type === 'microsoft' ? 'msa' : 'mojang'
|
||||
break
|
||||
case 'version_type':
|
||||
val = this.vanillaManifest.type
|
||||
val = this.versionData.type
|
||||
break
|
||||
case 'resolution_width':
|
||||
val = ConfigManager.getGameWidth()
|
||||
@ -538,11 +517,25 @@ class ProcessBuilder {
|
||||
}
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
|
||||
// Forge Specific Arguments
|
||||
args = args.concat(this.modManifest.arguments.game)
|
||||
args = args.concat(this.forgeData.arguments.game)
|
||||
|
||||
// Filter null values
|
||||
args = args.filter(arg => {
|
||||
@ -558,7 +551,7 @@ class ProcessBuilder {
|
||||
* @returns {Array.<string>} An array containing the arguments required by forge.
|
||||
*/
|
||||
_resolveForgeArgs(){
|
||||
const mcArgs = this.modManifest.minecraftArguments.split(' ')
|
||||
const mcArgs = this.forgeData.minecraftArguments.split(' ')
|
||||
const argDiscovery = /\${*(.*)}/
|
||||
|
||||
// Replace the declared variables with their proper values.
|
||||
@ -571,7 +564,7 @@ class ProcessBuilder {
|
||||
val = this.authUser.displayName.trim()
|
||||
break
|
||||
case 'version_name':
|
||||
//val = vanillaManifest.id
|
||||
//val = versionData.id
|
||||
val = this.server.rawServer.id
|
||||
break
|
||||
case 'game_directory':
|
||||
@ -581,7 +574,7 @@ class ProcessBuilder {
|
||||
val = path.join(this.commonDir, 'assets')
|
||||
break
|
||||
case 'assets_index_name':
|
||||
val = this.vanillaManifest.assets
|
||||
val = this.versionData.assets
|
||||
break
|
||||
case 'auth_uuid':
|
||||
val = this.authUser.uuid.trim()
|
||||
@ -596,7 +589,7 @@ class ProcessBuilder {
|
||||
val = '{}'
|
||||
break
|
||||
case 'version_type':
|
||||
val = this.vanillaManifest.type
|
||||
val = this.versionData.type
|
||||
break
|
||||
}
|
||||
if(val != null){
|
||||
@ -671,10 +664,10 @@ class ProcessBuilder {
|
||||
classpathArg(mods, tempNativePath){
|
||||
let cpArgs = []
|
||||
|
||||
if(!mcVersionAtLeast('1.17', this.server.rawServer.minecraftVersion) || this.usingFabricLoader) {
|
||||
if(!mcVersionAtLeast('1.17', this.server.rawServer.minecraftVersion)) {
|
||||
// Add the version.jar to the classpath.
|
||||
// Must not be added to the classpath for Forge 1.17+.
|
||||
const version = this.vanillaManifest.id
|
||||
const version = this.versionData.id
|
||||
cpArgs.push(path.join(this.commonDir, 'versions', version, version + '.jar'))
|
||||
}
|
||||
|
||||
@ -713,7 +706,7 @@ class ProcessBuilder {
|
||||
const nativesRegex = /.+:natives-([^-]+)(?:-(.+))?/
|
||||
const libs = {}
|
||||
|
||||
const libArr = this.vanillaManifest.libraries
|
||||
const libArr = this.versionData.libraries
|
||||
fs.ensureDirSync(tempNativePath)
|
||||
for(let i=0; i<libArr.length; i++){
|
||||
const lib = libArr[i]
|
||||
@ -832,10 +825,10 @@ class ProcessBuilder {
|
||||
const mdls = this.server.modules
|
||||
let libs = {}
|
||||
|
||||
// Locate Forge/Fabric/Libraries
|
||||
// Locate Forge/Libraries
|
||||
for(let mdl of mdls){
|
||||
const type = mdl.rawModule.type
|
||||
if(type === Type.ForgeHosted || type === Type.Fabric || type === Type.Library){
|
||||
if(type === Type.ForgeHosted || type === Type.Library){
|
||||
libs[mdl.getVersionlessMavenIdentifier()] = mdl.getPath()
|
||||
if(mdl.subModules.length > 0){
|
||||
const res = this._resolveModuleLibraries(mdl)
|
||||
@ -889,6 +882,24 @@ class ProcessBuilder {
|
||||
return libs
|
||||
}
|
||||
|
||||
static isAutoconnectBroken(forgeVersion) {
|
||||
|
||||
const minWorking = [31, 2, 15]
|
||||
const verSplit = forgeVersion.split('.').map(v => Number(v))
|
||||
|
||||
if(verSplit[0] === 31) {
|
||||
for(let i=0; i<minWorking.length; i++) {
|
||||
if(verSplit[i] > minWorking[i]) {
|
||||
return false
|
||||
} else if(verSplit[i] < minWorking[i]) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = ProcessBuilder
|
@ -220,7 +220,10 @@ loginButton.addEventListener('click', () => {
|
||||
} else {
|
||||
// Uh oh.
|
||||
msftLoginLogger.error('Unhandled error during login.', displayableError)
|
||||
actualDisplayableError = Lang.queryJS('login.error.unknown')
|
||||
actualDisplayableError = {
|
||||
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'))
|
||||
|
@ -130,7 +130,7 @@ async function toggleServerSelection(toggleState){
|
||||
* @param {string} acknowledge Acknowledge button text.
|
||||
* @param {string} dismiss Dismiss button text.
|
||||
*/
|
||||
function setOverlayContent(title, description, acknowledge, dismiss = Lang.queryJS('overlay.dismiss')){
|
||||
function setOverlayContent(title, description, acknowledge, dismiss = 'Dismiss'){
|
||||
document.getElementById('overlayTitle').innerHTML = title
|
||||
document.getElementById('overlayDesc').innerHTML = description
|
||||
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"/>
|
||||
<circle class="cls-2" cx="53.73" cy="53.9" r="38"/>
|
||||
</svg>
|
||||
<span class="serverListingStarTooltip">${Lang.queryJS('settings.serverListing.mainServer')}</span>
|
||||
<span class="serverListingStarTooltip">Main Server</span>
|
||||
</div>` : ''}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -59,8 +59,8 @@ function bindFileSelectors(){
|
||||
|
||||
if(isJavaExecSel && process.platform === 'win32') {
|
||||
options.filters = [
|
||||
{ name: Lang.queryJS('settings.fileSelectors.executables'), extensions: ['exe'] },
|
||||
{ name: Lang.queryJS('settings.fileSelectors.allFiles'), extensions: ['*'] }
|
||||
{ name: 'Executables', extensions: ['exe'] },
|
||||
{ name: 'All Files', extensions: ['*'] }
|
||||
]
|
||||
}
|
||||
|
||||
@ -374,9 +374,9 @@ ipcRenderer.on(MSFT_OPCODE.REPLY_LOGIN, (_, ...arguments_) => {
|
||||
|
||||
// Unexpected error.
|
||||
setOverlayContent(
|
||||
Lang.queryJS('settings.msftLogin.errorTitle'),
|
||||
Lang.queryJS('settings.msftLogin.errorMessage'),
|
||||
Lang.queryJS('settings.msftLogin.okButton')
|
||||
'Something Went Wrong',
|
||||
'Microsoft authentication failed. Please try again.',
|
||||
'OK'
|
||||
)
|
||||
setOverlayHandler(() => {
|
||||
toggleOverlay(false)
|
||||
@ -401,7 +401,7 @@ ipcRenderer.on(MSFT_OPCODE.REPLY_LOGIN, (_, ...arguments_) => {
|
||||
setOverlayContent(
|
||||
error,
|
||||
errorDesc,
|
||||
Lang.queryJS('settings.msftLogin.okButton')
|
||||
'OK'
|
||||
)
|
||||
setOverlayHandler(() => {
|
||||
toggleOverlay(false)
|
||||
@ -429,7 +429,10 @@ ipcRenderer.on(MSFT_OPCODE.REPLY_LOGIN, (_, ...arguments_) => {
|
||||
} else {
|
||||
// Uh oh.
|
||||
msftLoginLogger.error('Unhandled error during login.', displayableError)
|
||||
actualDisplayableError = Lang.queryJS('login.error.unknown')
|
||||
actualDisplayableError = {
|
||||
title: 'Unknown Error During Login',
|
||||
desc: 'An unknown error has occurred. Please see the console for details.'
|
||||
}
|
||||
}
|
||||
|
||||
switchView(getCurrentView(), viewOnClose, 500, 500, () => {
|
||||
@ -458,11 +461,11 @@ function bindAuthAccountSelect(){
|
||||
for(let i=0; i<selectBtns.length; i++){
|
||||
if(selectBtns[i].hasAttribute('selected')){
|
||||
selectBtns[i].removeAttribute('selected')
|
||||
selectBtns[i].innerHTML = Lang.queryJS('settings.authAccountSelect.selectButton')
|
||||
selectBtns[i].innerHTML = 'Select Account'
|
||||
}
|
||||
}
|
||||
val.setAttribute('selected', '')
|
||||
val.innerHTML = Lang.queryJS('settings.authAccountSelect.selectedButton')
|
||||
val.innerHTML = 'Selected Account ✔'
|
||||
setSelectedAccount(val.closest('.settingsAuthAccount').getAttribute('uuid'))
|
||||
}
|
||||
})
|
||||
@ -480,10 +483,10 @@ function bindAuthAccountLogOut(){
|
||||
if(Object.keys(ConfigManager.getAuthAccounts()).length === 1){
|
||||
isLastAccount = true
|
||||
setOverlayContent(
|
||||
Lang.queryJS('settings.authAccountLogout.lastAccountWarningTitle'),
|
||||
Lang.queryJS('settings.authAccountLogout.lastAccountWarningMessage'),
|
||||
Lang.queryJS('settings.authAccountLogout.confirmButton'),
|
||||
Lang.queryJS('settings.authAccountLogout.cancelButton')
|
||||
'Warning<br>This is Your Last Account',
|
||||
'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?',
|
||||
'I\'m Sure',
|
||||
'Cancel'
|
||||
)
|
||||
setOverlayHandler(() => {
|
||||
processLogOut(val, isLastAccount)
|
||||
@ -552,9 +555,9 @@ ipcRenderer.on(MSFT_OPCODE.REPLY_LOGOUT, (_, ...arguments_) => {
|
||||
|
||||
// Unexpected error.
|
||||
setOverlayContent(
|
||||
Lang.queryJS('settings.msftLogout.errorTitle'),
|
||||
Lang.queryJS('settings.msftLogout.errorMessage'),
|
||||
Lang.queryJS('settings.msftLogout.okButton')
|
||||
'Something Went Wrong',
|
||||
'Microsoft logout failed. Please try again.',
|
||||
'OK'
|
||||
)
|
||||
setOverlayHandler(() => {
|
||||
toggleOverlay(false)
|
||||
@ -608,12 +611,12 @@ function refreshAuthAccountSelected(uuid){
|
||||
const selBtn = val.getElementsByClassName('settingsAuthAccountSelect')[0]
|
||||
if(uuid === val.getAttribute('uuid')){
|
||||
selBtn.setAttribute('selected', '')
|
||||
selBtn.innerHTML = Lang.queryJS('settings.authAccountSelect.selectedButton')
|
||||
selBtn.innerHTML = 'Selected Account ✔'
|
||||
} else {
|
||||
if(selBtn.hasAttribute('selected')){
|
||||
selBtn.removeAttribute('selected')
|
||||
}
|
||||
selBtn.innerHTML = Lang.queryJS('settings.authAccountSelect.selectButton')
|
||||
selBtn.innerHTML = 'Select Account'
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -645,18 +648,18 @@ function populateAuthAccounts(){
|
||||
<div class="settingsAuthAccountRight">
|
||||
<div class="settingsAuthAccountDetails">
|
||||
<div class="settingsAuthAccountDetailPane">
|
||||
<div class="settingsAuthAccountDetailTitle">${Lang.queryJS('settings.authAccountPopulate.username')}</div>
|
||||
<div class="settingsAuthAccountDetailTitle">Username</div>
|
||||
<div class="settingsAuthAccountDetailValue">${acc.displayName}</div>
|
||||
</div>
|
||||
<div class="settingsAuthAccountDetailPane">
|
||||
<div class="settingsAuthAccountDetailTitle">${Lang.queryJS('settings.authAccountPopulate.uuid')}</div>
|
||||
<div class="settingsAuthAccountDetailTitle">UUID</div>
|
||||
<div class="settingsAuthAccountDetailValue">${acc.uuid}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="settingsAuthAccountActions">
|
||||
<button class="settingsAuthAccountSelect" ${selectedUUID === acc.uuid ? 'selected>' + Lang.queryJS('settings.authAccountPopulate.selectedAccount') : '>' + Lang.queryJS('settings.authAccountPopulate.selectAccount')}</button>
|
||||
<button class="settingsAuthAccountSelect" ${selectedUUID === acc.uuid ? 'selected>Selected Account ✔' : '>Select Account'}</button>
|
||||
<div class="settingsAuthAccountWrapper">
|
||||
<button class="settingsAuthAccountLogOut">${Lang.queryJS('settings.authAccountPopulate.logout')}</button>
|
||||
<button class="settingsAuthAccountLogOut">Log Out</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -736,7 +739,7 @@ function parseModulesForUI(mdls, submodules, servConf){
|
||||
|
||||
for(const mdl of mdls){
|
||||
|
||||
if(mdl.rawModule.type === Type.ForgeMod || mdl.rawModule.type === Type.LiteMod || mdl.rawModule.type === Type.LiteLoader || mdl.rawModule.type === Type.FabricMod){
|
||||
if(mdl.rawModule.type === Type.ForgeMod || mdl.rawModule.type === Type.LiteMod || mdl.rawModule.type === Type.LiteLoader){
|
||||
|
||||
if(mdl.getRequired().value){
|
||||
|
||||
@ -870,7 +873,7 @@ async function resolveDropinModsForUI(){
|
||||
<div class="settingsModDetails">
|
||||
<span class="settingsModName">${dropin.name}</span>
|
||||
<div class="settingsDropinRemoveWrapper">
|
||||
<button class="settingsDropinRemoveButton" remmod="${dropin.fullName}">${Lang.queryJS('settings.dropinMods.removeButton')}</button>
|
||||
<button class="settingsDropinRemoveButton" remmod="${dropin.fullName}">Remove</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -898,9 +901,9 @@ function bindDropinModsRemoveButton(){
|
||||
document.getElementById(fullName).remove()
|
||||
} else {
|
||||
setOverlayContent(
|
||||
Lang.queryJS('settings.dropinMods.deleteFailedTitle', { fullName }),
|
||||
Lang.queryJS('settings.dropinMods.deleteFailedMessage'),
|
||||
Lang.queryJS('settings.dropinMods.okButton')
|
||||
`Failed to Delete<br>Drop-in Mod ${fullName}`,
|
||||
'Make sure the file is not in use and try again.',
|
||||
'Okay'
|
||||
)
|
||||
setOverlayHandler(null)
|
||||
toggleOverlay(true)
|
||||
@ -953,9 +956,9 @@ function saveDropinModConfiguration(){
|
||||
DropinModUtil.toggleDropinMod(CACHE_SETTINGS_MODS_DIR, dropin.fullName, dropinUIEnabled).catch(err => {
|
||||
if(!isOverlayVisible()){
|
||||
setOverlayContent(
|
||||
Lang.queryJS('settings.dropinMods.failedToggleTitle'),
|
||||
'Failed to Toggle<br>One or More Drop-in Mods',
|
||||
err.message,
|
||||
Lang.queryJS('settings.dropinMods.okButton')
|
||||
'Okay'
|
||||
)
|
||||
setOverlayHandler(null)
|
||||
toggleOverlay(true)
|
||||
@ -1090,7 +1093,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"/>
|
||||
<circle class="cls-2" cx="53.73" cy="53.9" r="38"/>
|
||||
</svg>
|
||||
<span class="serverListingStarTooltip">${Lang.queryJS('settings.serverListing.mainServer')}</span>
|
||||
<span class="serverListingStarTooltip">Main Server</span>
|
||||
</div>` : ''}
|
||||
</div>
|
||||
</div>
|
||||
@ -1341,19 +1344,19 @@ async function populateJavaExecDetails(execPath){
|
||||
const details = await validateSelectedJvm(ensureJavaDirIsRoot(execPath), server.effectiveJavaOptions.supported)
|
||||
|
||||
if(details != null) {
|
||||
settingsJavaExecDetails.innerHTML = Lang.queryJS('settings.java.selectedJava', { version: details.semverStr, vendor: details.vendor })
|
||||
settingsJavaExecDetails.innerHTML = `Selected: Java ${details.semverStr} (${details.vendor})`
|
||||
} else {
|
||||
settingsJavaExecDetails.innerHTML = Lang.queryJS('settings.java.invalidSelection')
|
||||
settingsJavaExecDetails.innerHTML = 'Invalid Selection'
|
||||
}
|
||||
}
|
||||
|
||||
function populateJavaReqDesc(server) {
|
||||
settingsJavaReqDesc.innerHTML = Lang.queryJS('settings.java.requiresJava', { major: server.effectiveJavaOptions.suggestedMajor })
|
||||
settingsJavaReqDesc.innerHTML = `Requires Java ${server.effectiveJavaOptions.suggestedMajor} x64.`
|
||||
}
|
||||
|
||||
function populateJvmOptsLink(server) {
|
||||
const major = server.effectiveJavaOptions.suggestedMajor
|
||||
settingsJvmOptsLink.innerHTML = Lang.queryJS('settings.java.availableOptions', { major: major })
|
||||
settingsJvmOptsLink.innerHTML = `Available Options for Java ${major} (HotSpot VM)`
|
||||
if(major >= 12) {
|
||||
settingsJvmOptsLink.href = `https://docs.oracle.com/en/java/javase/${major}/docs/specs/man/java.html#extra-options-for-java`
|
||||
}
|
||||
@ -1430,11 +1433,11 @@ function isPrerelease(version){
|
||||
function populateVersionInformation(version, valueElement, titleElement, checkElement){
|
||||
valueElement.innerHTML = version
|
||||
if(isPrerelease(version)){
|
||||
titleElement.innerHTML = Lang.queryJS('settings.about.preReleaseTitle')
|
||||
titleElement.innerHTML = 'Pre-release'
|
||||
titleElement.style.color = '#ff886d'
|
||||
checkElement.style.background = '#ff886d'
|
||||
} else {
|
||||
titleElement.innerHTML = Lang.queryJS('settings.about.stableReleaseTitle')
|
||||
titleElement.innerHTML = 'Stable Release'
|
||||
titleElement.style.color = null
|
||||
checkElement.style.background = null
|
||||
}
|
||||
@ -1473,7 +1476,7 @@ function populateReleaseNotes(){
|
||||
},
|
||||
timeout: 2500
|
||||
}).catch(err => {
|
||||
settingsAboutChangelogText.innerHTML = Lang.queryJS('settings.about.releaseNotesFailed')
|
||||
settingsAboutChangelogText.innerHTML = 'Failed to load release notes.'
|
||||
})
|
||||
}
|
||||
|
||||
@ -1521,27 +1524,27 @@ function settingsUpdateButtonStatus(text, disabled = false, handler = null){
|
||||
*/
|
||||
function populateSettingsUpdateInformation(data){
|
||||
if(data != null){
|
||||
settingsUpdateTitle.innerHTML = isPrerelease(data.version) ? Lang.queryJS('settings.updates.newPreReleaseTitle') : Lang.queryJS('settings.updates.newReleaseTitle')
|
||||
settingsUpdateTitle.innerHTML = `New ${isPrerelease(data.version) ? 'Pre-release' : 'Release'} Available`
|
||||
settingsUpdateChangelogCont.style.display = null
|
||||
settingsUpdateChangelogTitle.innerHTML = data.releaseName
|
||||
settingsUpdateChangelogText.innerHTML = data.releaseNotes
|
||||
populateVersionInformation(data.version, settingsUpdateVersionValue, settingsUpdateVersionTitle, settingsUpdateVersionCheck)
|
||||
|
||||
if(process.platform === 'darwin'){
|
||||
settingsUpdateButtonStatus(Lang.queryJS('settings.updates.downloadButton'), false, () => {
|
||||
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, () => {
|
||||
shell.openExternal(data.darwindownload)
|
||||
})
|
||||
} else {
|
||||
settingsUpdateButtonStatus(Lang.queryJS('settings.updates.downloadingButton'), true)
|
||||
settingsUpdateButtonStatus('Downloading..', true)
|
||||
}
|
||||
} else {
|
||||
settingsUpdateTitle.innerHTML = Lang.queryJS('settings.updates.latestVersionTitle')
|
||||
settingsUpdateTitle.innerHTML = 'You Are Running the Latest Version'
|
||||
settingsUpdateChangelogCont.style.display = 'none'
|
||||
populateVersionInformation(remote.app.getVersion(), settingsUpdateVersionValue, settingsUpdateVersionTitle, settingsUpdateVersionCheck)
|
||||
settingsUpdateButtonStatus(Lang.queryJS('settings.updates.checkForUpdatesButton'), false, () => {
|
||||
settingsUpdateButtonStatus('Check for Updates', false, () => {
|
||||
if(!isDev){
|
||||
ipcRenderer.send('autoUpdateAction', 'checkForUpdate')
|
||||
settingsUpdateButtonStatus(Lang.queryJS('settings.updates.checkingForUpdatesButton'), true)
|
||||
settingsUpdateButtonStatus('Checking for Updates..', true)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ const { Type } = require('helios-distribution-types')
|
||||
const AuthManager = require('./assets/js/authmanager')
|
||||
const ConfigManager = require('./assets/js/configmanager')
|
||||
const { DistroAPI } = require('./assets/js/distromanager')
|
||||
const Lang = require('./assets/js/langloader')
|
||||
|
||||
let rscShouldLoad = false
|
||||
let fatalStartupError = false
|
||||
@ -114,9 +115,9 @@ function showFatalStartupError(){
|
||||
$('#loadingContainer').fadeOut(250, () => {
|
||||
document.getElementById('overlayContainer').style.background = 'none'
|
||||
setOverlayContent(
|
||||
Lang.queryJS('uibinder.startup.fatalErrorTitle'),
|
||||
Lang.queryJS('uibinder.startup.fatalErrorMessage'),
|
||||
Lang.queryJS('uibinder.startup.closeButton')
|
||||
'Fatal Error: Unable to Load Distribution Index',
|
||||
'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.',
|
||||
'Close'
|
||||
)
|
||||
setOverlayHandler(() => {
|
||||
const window = remote.getCurrentWindow()
|
||||
@ -163,7 +164,7 @@ function syncModConfigurations(data){
|
||||
for(let mdl of mdls){
|
||||
const type = mdl.rawModule.type
|
||||
|
||||
if(type === Type.ForgeMod || type === Type.LiteMod || type === Type.LiteLoader || type === Type.FabricMod){
|
||||
if(type === Type.ForgeMod || type === Type.LiteMod || type === Type.LiteLoader){
|
||||
if(!mdl.getRequired().value){
|
||||
const mdlID = mdl.getVersionlessMavenIdentifier()
|
||||
if(modsOld[mdlID] == null){
|
||||
@ -198,7 +199,7 @@ function syncModConfigurations(data){
|
||||
|
||||
for(let mdl of mdls){
|
||||
const type = mdl.rawModule.type
|
||||
if(type === Type.ForgeMod || type === Type.LiteMod || type === Type.LiteLoader || type === Type.FabricMod){
|
||||
if(type === Type.ForgeMod || type === Type.LiteMod || type === Type.LiteLoader){
|
||||
if(!mdl.getRequired().value){
|
||||
mods[mdl.getVersionlessMavenIdentifier()] = scanOptionalSubModules(mdl.subModules, mdl)
|
||||
} else {
|
||||
@ -253,7 +254,7 @@ function scanOptionalSubModules(mdls, origin){
|
||||
for(let mdl of mdls){
|
||||
const type = mdl.rawModule.type
|
||||
// Optional types.
|
||||
if(type === Type.ForgeMod || type === Type.LiteMod || type === Type.LiteLoader || type === Type.FabricMod){
|
||||
if(type === Type.ForgeMod || type === Type.LiteMod || type === Type.LiteLoader){
|
||||
// It is optional.
|
||||
if(!mdl.getRequired().value){
|
||||
mods[mdl.getVersionlessMavenIdentifier()] = scanOptionalSubModules(mdl.subModules, mdl)
|
||||
@ -332,12 +333,10 @@ async function validateSelectedAccount(){
|
||||
ConfigManager.save()
|
||||
const accLen = Object.keys(ConfigManager.getAuthAccounts()).length
|
||||
setOverlayContent(
|
||||
Lang.queryJS('uibinder.validateAccount.failedMessageTitle'),
|
||||
accLen > 0
|
||||
? Lang.queryJS('uibinder.validateAccount.failedMessage', { 'account': selectedAcc.displayName })
|
||||
: Lang.queryJS('uibinder.validateAccount.failedMessageSelectAnotherAccount', { 'account': selectedAcc.displayName }),
|
||||
Lang.queryJS('uibinder.validateAccount.loginButton'),
|
||||
Lang.queryJS('uibinder.validateAccount.selectAnotherAccountButton')
|
||||
'Failed to Refresh Login',
|
||||
`We were unable to refresh the login for <strong>${selectedAcc.displayName}</strong>. Please ${accLen > 0 ? 'select another account or ' : ''} login again.`,
|
||||
'Login',
|
||||
'Select Another Account'
|
||||
)
|
||||
setOverlayHandler(() => {
|
||||
|
||||
|
@ -10,7 +10,6 @@ const {ipcRenderer, shell, webFrame} = require('electron')
|
||||
const remote = require('@electron/remote')
|
||||
const isDev = require('./assets/js/isdev')
|
||||
const { LoggerUtil } = require('helios-core')
|
||||
const Lang = require('./assets/js/langloader')
|
||||
|
||||
const loggerUICore = LoggerUtil.getLogger('UICore')
|
||||
const loggerAutoUpdater = LoggerUtil.getLogger('AutoUpdater')
|
||||
@ -43,7 +42,7 @@ if(!isDev){
|
||||
switch(arg){
|
||||
case 'checking-for-update':
|
||||
loggerAutoUpdater.info('Checking for update..')
|
||||
settingsUpdateButtonStatus(Lang.queryJS('uicore.autoUpdate.checkingForUpdateButton'), true)
|
||||
settingsUpdateButtonStatus('Checking for Updates..', true)
|
||||
break
|
||||
case 'update-available':
|
||||
loggerAutoUpdater.info('New update available', info.version)
|
||||
@ -57,7 +56,7 @@ if(!isDev){
|
||||
break
|
||||
case 'update-downloaded':
|
||||
loggerAutoUpdater.info('Update ' + info.version + ' ready to be installed.')
|
||||
settingsUpdateButtonStatus(Lang.queryJS('uicore.autoUpdate.installNowButton'), false, () => {
|
||||
settingsUpdateButtonStatus('Install Now', false, () => {
|
||||
if(!isDev){
|
||||
ipcRenderer.send('autoUpdateAction', 'installUpdateNow')
|
||||
}
|
||||
@ -66,7 +65,7 @@ if(!isDev){
|
||||
break
|
||||
case 'update-not-available':
|
||||
loggerAutoUpdater.info('No new update found.')
|
||||
settingsUpdateButtonStatus(Lang.queryJS('uicore.autoUpdate.checkForUpdatesButton'))
|
||||
settingsUpdateButtonStatus('Check for Updates')
|
||||
break
|
||||
case 'ready':
|
||||
updateCheckListener = setInterval(() => {
|
||||
|
@ -1,20 +0,0 @@
|
||||
# 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."
|
49
app/assets/lang/en_US.json
Normal file
49
app/assets/lang/en_US.json
Normal file
@ -0,0 +1,49 @@
|
||||
{
|
||||
"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.."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
<div id="loginOptionsContainer" style="display: none;">
|
||||
<div id="loginOptionsContent">
|
||||
<div class="loginOptionsMainContent">
|
||||
<h2><%- lang('loginOptions.loginOptionsTitle') %></h2>
|
||||
<h2>Login Options</h2>
|
||||
<div class="loginOptionActions">
|
||||
<div class="loginOptionButtonContainer">
|
||||
<button id="loginOptionMicrosoft" class="loginOptionButton">
|
||||
@ -11,7 +11,7 @@
|
||||
<path fill="#05a6f0" d="M1 12h10v10H1z" />
|
||||
<path fill="#ffba08" d="M12 12h10v10H12z" />
|
||||
</svg>
|
||||
<span><%- lang('loginOptions.loginWithMicrosoft') %></span>
|
||||
<span>Login with Microsoft</span>
|
||||
</button>
|
||||
</div>
|
||||
<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="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>
|
||||
<span><%- lang('loginOptions.loginWithMojang') %></span>
|
||||
<span>Login with Mojang</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="loginOptionCancelContainer" style="display: none;">
|
||||
<button id="loginOptionCancelButton"><%- lang('loginOptions.cancelButton') %></button>
|
||||
<button id="loginOptionCancelButton">Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,29 +1,29 @@
|
||||
<div id="overlayContainer" style="display: none;">
|
||||
<div id="serverSelectContent" style="display: none;">
|
||||
<span id="serverSelectHeader"><%- lang('overlay.serverSelectHeader') %></span>
|
||||
<span id="serverSelectHeader">Available Servers</span>
|
||||
<div id="serverSelectList">
|
||||
<div id="serverSelectListScrollable">
|
||||
<!-- Server listings populated here. -->
|
||||
</div>
|
||||
</div>
|
||||
<div id="serverSelectActions">
|
||||
<button id="serverSelectConfirm" class="overlayKeybindEnter" type="submit"><%- lang('overlay.serverSelectConfirm') %></button>
|
||||
<button id="serverSelectConfirm" class="overlayKeybindEnter" type="submit">Select</button>
|
||||
<div id="serverSelectCancelWrapper">
|
||||
<button id="serverSelectCancel" class="overlayKeybindEsc"><%- lang('overlay.serverSelectCancel') %></button>
|
||||
<button id="serverSelectCancel" class="overlayKeybindEsc">Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="accountSelectContent" style="display: none;">
|
||||
<span id="accountSelectHeader"><%- lang('overlay.accountSelectHeader') %></span>
|
||||
<span id="accountSelectHeader">Select an Account</span>
|
||||
<div id="accountSelectList">
|
||||
<div id="accountSelectListScrollable">
|
||||
<!-- Accounts populated here. -->
|
||||
</div>
|
||||
</div>
|
||||
<div id="accountSelectActions">
|
||||
<button id="accountSelectConfirm" class="overlayKeybindEnter" type="submit"><%- lang('overlay.accountSelectConfirm') %></button>
|
||||
<button id="accountSelectConfirm" class="overlayKeybindEnter" type="submit">Select</button>
|
||||
<div id="accountSelectCancelWrapper">
|
||||
<button id="accountSelectCancel" class="overlayKeybindEsc"><%- lang('overlay.accountSelectCancel') %></button>
|
||||
<button id="accountSelectCancel" class="overlayKeybindEsc">Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -2,7 +2,7 @@
|
||||
<div id="waitingContent">
|
||||
<div class="waitingSpinner"></div>
|
||||
<div id="waitingTextContainer">
|
||||
<h2><%- lang('waiting.waitingText') %></h2>
|
||||
<h2>Waiting for Microsoft..</h2>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -5,13 +5,13 @@
|
||||
</div>-->
|
||||
<div id="welcomeContent">
|
||||
<img id="welcomeImageSeal" src="assets/images/SealCircle.png"/>
|
||||
<span id="welcomeHeader"><%- lang('welcome.welcomeHeader') %></span>
|
||||
<span id="welcomeDescription"><%- lang('welcome.welcomeDescription') %></span>
|
||||
<span id="welcomeHeader">WELCOME TO WESTEROSCRAFT</span>
|
||||
<span id="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.</span>
|
||||
<br>
|
||||
<span id="welcomeDescCTA"><%- lang('welcome.welcomeDescCTA') %></span>
|
||||
<span id="welcomeDescCTA">You are just a few clicks away from Westeros.</span>
|
||||
<button id="welcomeButton">
|
||||
<div id="welcomeButtonContent">
|
||||
<%- lang('welcome.continueButton') %>
|
||||
CONTINUE
|
||||
<svg id="welcomeSVG" viewBox="0 0 24.87 13.97">
|
||||
<defs>
|
||||
<style>.arrowLine{fill:none;stroke:#FFF;stroke-width:2px;transition: 0.25s ease;}</style>
|
||||
|
@ -360,12 +360,10 @@ The resolved/provided paths are appended to a base path depending on the module'
|
||||
| Type | Path |
|
||||
| ---- | ---- |
|
||||
| `ForgeHosted` | ({`commonDirectory`}/libraries/{`path` OR resolved}) |
|
||||
| `Fabric` | ({`commonDirectory`}/libraries/{`path` OR resolved}) |
|
||||
| `LiteLoader` | ({`commonDirectory`}/libraries/{`path` OR resolved}) |
|
||||
| `Library` | ({`commonDirectory`}/libraries/{`path` OR resolved}) |
|
||||
| `ForgeMod` | ({`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}) |
|
||||
|
||||
The `commonDirectory` and `instanceDirectory` values are stored in the launcher's config.json.
|
||||
@ -410,7 +408,7 @@ If the module is enabled by default. Has no effect unless `Required.value` is fa
|
||||
|
||||
### ForgeHosted
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
Ex.
|
||||
|
||||
@ -445,40 +443,6 @@ 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
|
||||
|
||||
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,10 +11,6 @@ const path = require('path')
|
||||
const semver = require('semver')
|
||||
const { pathToFileURL } = require('url')
|
||||
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.
|
||||
function initAutoUpdater(event, data) {
|
||||
@ -125,7 +121,7 @@ ipcMain.on(MSFT_OPCODE.OPEN_LOGIN, (ipcEvent, ...arguments_) => {
|
||||
msftAuthViewSuccess = arguments_[0]
|
||||
msftAuthViewOnClose = arguments_[1]
|
||||
msftAuthWindow = new BrowserWindow({
|
||||
title: LangLoader.queryJS('index.microsoftLoginTitle'),
|
||||
title: 'Microsoft Login',
|
||||
backgroundColor: '#222222',
|
||||
width: 520,
|
||||
height: 600,
|
||||
@ -178,7 +174,7 @@ ipcMain.on(MSFT_OPCODE.OPEN_LOGOUT, (ipcEvent, uuid, isLastAccount) => {
|
||||
msftLogoutSuccess = false
|
||||
msftLogoutSuccessSent = false
|
||||
msftLogoutWindow = new BrowserWindow({
|
||||
title: LangLoader.queryJS('index.microsoftLogoutTitle'),
|
||||
title: 'Microsoft Logout',
|
||||
backgroundColor: '#222222',
|
||||
width: 520,
|
||||
height: 600,
|
||||
@ -240,11 +236,7 @@ function createWindow() {
|
||||
})
|
||||
remoteMain.enable(win.webContents)
|
||||
|
||||
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))
|
||||
ejse.data('bkid', Math.floor((Math.random() * fs.readdirSync(path.join(__dirname, 'app', 'assets', 'images', 'backgrounds')).length)))
|
||||
|
||||
win.loadURL(pathToFileURL(path.join(__dirname, 'app', 'app.ejs')).toString())
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user