Bump to v1.8.2

This commit is contained in:
Freshmilkymilk 2021-10-03 18:11:50 -06:00
commit ab2409d926
11 changed files with 728 additions and 952 deletions

21
LICENSE.txt Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2017-2021 Daniel D. Scalzi
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -178,14 +178,7 @@ Note that you **cannot** open the DevTools window while using this debug configu
### Note on Third-Party Usage ### Note on Third-Party Usage
You may use this software in your own project so long as the following conditions are met. Please give credit to the original author and provide a link to the original source. This is free software, please do at least this much.
* Credit is expressly given to the original authors (Daniel Scalzi).
* Include a link to the original source on the launcher's About page.
* Credit the authors and provide a link to the original source in any publications or download pages.
* The source code remain **public** as a fork of this repository.
We reserve the right to update these conditions at any time, please check back periodically.
--- ---

View File

@ -92,14 +92,17 @@ exports.addDropinMods = function(files, modsdir) {
* @param {string} modsDir The path to the mods directory. * @param {string} modsDir The path to the mods directory.
* @param {string} fullName The fullName of the discovered mod to delete. * @param {string} fullName The fullName of the discovered mod to delete.
* *
* @returns {boolean} True if the mod was deleted, otherwise false. * @returns {Promise.<boolean>} True if the mod was deleted, otherwise false.
*/ */
exports.deleteDropinMod = function(modsDir, fullName){ exports.deleteDropinMod = async function(modsDir, fullName){
const res = shell.moveItemToTrash(path.join(modsDir, fullName)) try {
if(!res){ await shell.trashItem(path.join(modsDir, fullName))
return true
} catch(error) {
shell.beep() shell.beep()
console.error('Error deleting drop-in mod.', error)
return false
} }
return res
} }
/** /**

View File

@ -130,7 +130,7 @@ function updateSelectedAccount(authUser){
username = authUser.displayName username = authUser.displayName
} }
if(authUser.uuid != null){ if(authUser.uuid != null){
document.getElementById('avatarContainer').style.backgroundImage = `url('https://crafatar.com/renders/body/${authUser.uuid}')` document.getElementById('avatarContainer').style.backgroundImage = `url('https://mc-heads.net/body/${authUser.uuid}/right')`
} }
} }
user_text.innerHTML = username user_text.innerHTML = username

View File

@ -9,7 +9,7 @@
* *
* @returns {boolean} Whether or not the overlay is visible. * @returns {boolean} Whether or not the overlay is visible.
*/ */
function isOverlayVisible() { function isOverlayVisible(){
return document.getElementById('main').hasAttribute('overlay') return document.getElementById('main').hasAttribute('overlay')
} }
@ -20,8 +20,8 @@ let overlayHandlerContent
* *
* @param {KeyboardEvent} e The keydown event. * @param {KeyboardEvent} e The keydown event.
*/ */
function overlayKeyHandler(e) { function overlayKeyHandler (e){
if (e.key === 'Enter' || e.key === 'Escape') { if(e.key === 'Enter' || e.key === 'Escape'){
document.getElementById(overlayHandlerContent).getElementsByClassName('overlayKeybindEnter')[0].click() document.getElementById(overlayHandlerContent).getElementsByClassName('overlayKeybindEnter')[0].click()
} }
} }
@ -30,10 +30,10 @@ function overlayKeyHandler(e) {
* *
* @param {KeyboardEvent} e The keydown event. * @param {KeyboardEvent} e The keydown event.
*/ */
function overlayKeyDismissableHandler(e) { function overlayKeyDismissableHandler (e){
if (e.key === 'Enter') { if(e.key === 'Enter'){
document.getElementById(overlayHandlerContent).getElementsByClassName('overlayKeybindEnter')[0].click() document.getElementById(overlayHandlerContent).getElementsByClassName('overlayKeybindEnter')[0].click()
} else if (e.key === 'Escape') { } else if(e.key === 'Escape'){
document.getElementById(overlayHandlerContent).getElementsByClassName('overlayKeybindEsc')[0].click() document.getElementById(overlayHandlerContent).getElementsByClassName('overlayKeybindEsc')[0].click()
} }
} }
@ -45,12 +45,12 @@ function overlayKeyDismissableHandler(e) {
* @param {string} content The overlay content which will be shown. * @param {string} content The overlay content which will be shown.
* @param {boolean} dismissable Whether or not the overlay is dismissable * @param {boolean} dismissable Whether or not the overlay is dismissable
*/ */
function bindOverlayKeys(state, content, dismissable) { function bindOverlayKeys(state, content, dismissable){
overlayHandlerContent = content overlayHandlerContent = content
document.removeEventListener('keydown', overlayKeyHandler) document.removeEventListener('keydown', overlayKeyHandler)
document.removeEventListener('keydown', overlayKeyDismissableHandler) document.removeEventListener('keydown', overlayKeyDismissableHandler)
if (state) { if(state){
if (dismissable) { if(dismissable){
document.addEventListener('keydown', overlayKeyDismissableHandler) document.addEventListener('keydown', overlayKeyDismissableHandler)
} else { } else {
document.addEventListener('keydown', overlayKeyHandler) document.addEventListener('keydown', overlayKeyHandler)
@ -65,22 +65,22 @@ function bindOverlayKeys(state, content, dismissable) {
* @param {boolean} dismissable Optional. True to show the dismiss option, otherwise false. * @param {boolean} dismissable Optional. True to show the dismiss option, otherwise false.
* @param {string} content Optional. The content div to be shown. * @param {string} content Optional. The content div to be shown.
*/ */
function toggleOverlay(toggleState, dismissable = false, content = 'overlayContent') { function toggleOverlay(toggleState, dismissable = false, content = 'overlayContent'){
if (toggleState == null) { if(toggleState == null){
toggleState = !document.getElementById('main').hasAttribute('overlay') toggleState = !document.getElementById('main').hasAttribute('overlay')
} }
if (typeof dismissable === 'string') { if(typeof dismissable === 'string'){
content = dismissable content = dismissable
dismissable = false dismissable = false
} }
bindOverlayKeys(toggleState, content, dismissable) bindOverlayKeys(toggleState, content, dismissable)
if (toggleState) { if(toggleState){
document.getElementById('main').setAttribute('overlay', true) document.getElementById('main').setAttribute('overlay', true)
// Make things untabbable. // Make things untabbable.
$('#main *').attr('tabindex', '-1') $('#main *').attr('tabindex', '-1')
$('#' + content).parent().children().hide() $('#' + content).parent().children().hide()
$('#' + content).show() $('#' + content).show()
if (dismissable) { if(dismissable){
$('#overlayDismiss').show() $('#overlayDismiss').show()
} else { } else {
$('#overlayDismiss').hide() $('#overlayDismiss').hide()
@ -88,7 +88,7 @@ function toggleOverlay(toggleState, dismissable = false, content = 'overlayConte
$('#overlayContainer').fadeIn({ $('#overlayContainer').fadeIn({
duration: 250, duration: 250,
start: () => { start: () => {
if (getCurrentView() === VIEWS.settings) { if(getCurrentView() === VIEWS.settings){
document.getElementById('settingsContainer').style.backgroundColor = 'transparent' document.getElementById('settingsContainer').style.backgroundColor = 'transparent'
} }
} }
@ -100,14 +100,14 @@ function toggleOverlay(toggleState, dismissable = false, content = 'overlayConte
$('#overlayContainer').fadeOut({ $('#overlayContainer').fadeOut({
duration: 250, duration: 250,
start: () => { start: () => {
if (getCurrentView() === VIEWS.settings) { if(getCurrentView() === VIEWS.settings){
document.getElementById('settingsContainer').style.backgroundColor = 'rgba(0, 0, 0, 0.50)' document.getElementById('settingsContainer').style.backgroundColor = 'rgba(0, 0, 0, 0.50)'
} }
}, },
complete: () => { complete: () => {
$('#' + content).parent().children().hide() $('#' + content).parent().children().hide()
$('#' + content).show() $('#' + content).show()
if (dismissable) { if(dismissable){
$('#overlayDismiss').show() $('#overlayDismiss').show()
} else { } else {
$('#overlayDismiss').hide() $('#overlayDismiss').hide()
@ -117,7 +117,7 @@ function toggleOverlay(toggleState, dismissable = false, content = 'overlayConte
} }
} }
function toggleServerSelection(toggleState) { function toggleServerSelection(toggleState){
prepareServerSelectionList() prepareServerSelectionList()
toggleOverlay(toggleState, true, 'serverSelectContent') toggleOverlay(toggleState, true, 'serverSelectContent')
} }
@ -130,7 +130,7 @@ 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 = '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
@ -143,8 +143,8 @@ function setOverlayContent(title, description, acknowledge, dismiss = 'Dismiss')
* *
* @param {function} handler * @param {function} handler
*/ */
function setOverlayHandler(handler) { function setOverlayHandler(handler){
if (handler == null) { if(handler == null){
document.getElementById('overlayAcknowledge').onclick = () => { document.getElementById('overlayAcknowledge').onclick = () => {
toggleOverlay(false) toggleOverlay(false)
} }
@ -159,8 +159,8 @@ function setOverlayHandler(handler) {
* *
* @param {function} handler * @param {function} handler
*/ */
function setDismissHandler(handler) { function setDismissHandler(handler){
if (handler == null) { if(handler == null){
document.getElementById('overlayDismiss').onclick = () => { document.getElementById('overlayDismiss').onclick = () => {
toggleOverlay(false) toggleOverlay(false)
} }
@ -173,8 +173,8 @@ function setDismissHandler(handler) {
document.getElementById('serverSelectConfirm').addEventListener('click', () => { document.getElementById('serverSelectConfirm').addEventListener('click', () => {
const listings = document.getElementsByClassName('serverListing') const listings = document.getElementsByClassName('serverListing')
for (let i = 0; i < listings.length; i++) { for(let i=0; i<listings.length; i++){
if (listings[i].hasAttribute('selected')) { if(listings[i].hasAttribute('selected')){
const serv = DistroManager.getDistribution().getServer(listings[i].getAttribute('servid')) const serv = DistroManager.getDistribution().getServer(listings[i].getAttribute('servid'))
updateSelectedServer(serv) updateSelectedServer(serv)
refreshServerStatus(true) refreshServerStatus(true)
@ -183,7 +183,7 @@ document.getElementById('serverSelectConfirm').addEventListener('click', () => {
} }
} }
// None are selected? Not possible right? Meh, handle it. // None are selected? Not possible right? Meh, handle it.
if (listings.length > 0) { if(listings.length > 0){
const serv = DistroManager.getDistribution().getServer(listings[i].getAttribute('servid')) const serv = DistroManager.getDistribution().getServer(listings[i].getAttribute('servid'))
updateSelectedServer(serv) updateSelectedServer(serv)
toggleOverlay(false) toggleOverlay(false)
@ -192,8 +192,8 @@ document.getElementById('serverSelectConfirm').addEventListener('click', () => {
document.getElementById('accountSelectConfirm').addEventListener('click', () => { document.getElementById('accountSelectConfirm').addEventListener('click', () => {
const listings = document.getElementsByClassName('accountListing') const listings = document.getElementsByClassName('accountListing')
for (let i = 0; i < listings.length; i++) { for(let i=0; i<listings.length; i++){
if (listings[i].hasAttribute('selected')) { if(listings[i].hasAttribute('selected')){
const authAcc = ConfigManager.setSelectedAccount(listings[i].getAttribute('uuid')) const authAcc = ConfigManager.setSelectedAccount(listings[i].getAttribute('uuid'))
ConfigManager.save() ConfigManager.save()
updateSelectedAccount(authAcc) updateSelectedAccount(authAcc)
@ -203,7 +203,7 @@ document.getElementById('accountSelectConfirm').addEventListener('click', () =>
} }
} }
// None are selected? Not possible right? Meh, handle it. // None are selected? Not possible right? Meh, handle it.
if (listings.length > 0) { if(listings.length > 0){
const authAcc = ConfigManager.setSelectedAccount(listings[0].getAttribute('uuid')) const authAcc = ConfigManager.setSelectedAccount(listings[0].getAttribute('uuid'))
ConfigManager.save() ConfigManager.save()
updateSelectedAccount(authAcc) updateSelectedAccount(authAcc)
@ -223,16 +223,16 @@ document.getElementById('accountSelectCancel').addEventListener('click', () => {
}) })
}) })
function setServerListingHandlers() { function setServerListingHandlers(){
const listings = Array.from(document.getElementsByClassName('serverListing')) const listings = Array.from(document.getElementsByClassName('serverListing'))
listings.map((val) => { listings.map((val) => {
val.onclick = e => { val.onclick = e => {
if (val.hasAttribute('selected')) { if(val.hasAttribute('selected')){
return return
} }
const cListings = document.getElementsByClassName('serverListing') const cListings = document.getElementsByClassName('serverListing')
for (let i = 0; i < cListings.length; i++) { for(let i=0; i<cListings.length; i++){
if (cListings[i].hasAttribute('selected')) { if(cListings[i].hasAttribute('selected')){
cListings[i].removeAttribute('selected') cListings[i].removeAttribute('selected')
} }
} }
@ -242,16 +242,16 @@ function setServerListingHandlers() {
}) })
} }
function setAccountListingHandlers() { function setAccountListingHandlers(){
const listings = Array.from(document.getElementsByClassName('accountListing')) const listings = Array.from(document.getElementsByClassName('accountListing'))
listings.map((val) => { listings.map((val) => {
val.onclick = e => { val.onclick = e => {
if (val.hasAttribute('selected')) { if(val.hasAttribute('selected')){
return return
} }
const cListings = document.getElementsByClassName('accountListing') const cListings = document.getElementsByClassName('accountListing')
for (let i = 0; i < cListings.length; i++) { for(let i=0; i<cListings.length; i++){
if (cListings[i].hasAttribute('selected')) { if(cListings[i].hasAttribute('selected')){
cListings[i].removeAttribute('selected') cListings[i].removeAttribute('selected')
} }
} }
@ -261,12 +261,12 @@ function setAccountListingHandlers() {
}) })
} }
function populateServerListings() { function populateServerListings(){
const distro = DistroManager.getDistribution() const distro = DistroManager.getDistribution()
const giaSel = ConfigManager.getSelectedServer() const giaSel = ConfigManager.getSelectedServer()
const servers = distro.getServers() const servers = distro.getServers()
let htmlString = '' let htmlString = ''
for (const serv of servers) { for(const serv of servers){
htmlString += `<button class="serverListing" servid="${serv.getID()}" ${serv.getID() === giaSel ? 'selected' : ''}> htmlString += `<button class="serverListing" servid="${serv.getID()}" ${serv.getID() === giaSel ? 'selected' : ''}>
<img class="serverListingImg" src="${serv.getIcon()}"/> <img class="serverListingImg" src="${serv.getIcon()}"/>
<div class="serverListingDetails"> <div class="serverListingDetails">
@ -293,13 +293,13 @@ function populateServerListings() {
} }
function populateAccountListings() { function populateAccountListings(){
const accountsObj = ConfigManager.getAuthAccounts() const accountsObj = ConfigManager.getAuthAccounts()
const accounts = Array.from(Object.keys(accountsObj), v => accountsObj[v]) const accounts = Array.from(Object.keys(accountsObj), v=>accountsObj[v])
let htmlString = '' let htmlString = ''
for (let i = 0; i < accounts.length; i++) { for(let i=0; i<accounts.length; i++){
htmlString += `<button class="accountListing" uuid="${accounts[i].uuid}" ${i === 0 ? 'selected' : ''}> htmlString += `<button class="accountListing" uuid="${accounts[i].uuid}" ${i===0 ? 'selected' : ''}>
<img src="https://crafatar.com/renders/head/${accounts[i].uuid}?scale=2&default=MHF_Steve&overlay"> <img src="https://mc-heads.net/head/${accounts[i].uuid}/40">
<div class="accountListingName">${accounts[i].displayName}</div> <div class="accountListingName">${accounts[i].displayName}</div>
</button>` </button>`
} }
@ -307,12 +307,12 @@ function populateAccountListings() {
} }
function prepareServerSelectionList() { function prepareServerSelectionList(){
populateServerListings() populateServerListings()
setServerListingHandlers() setServerListingHandlers()
} }
function prepareAccountSelectionList() { function prepareAccountSelectionList(){
populateAccountListings() populateAccountListings()
setAccountListingHandlers() setAccountListingHandlers()
} }

View File

@ -1,16 +1,16 @@
// Requirements // Requirements
const os = require('os') const os = require('os')
const semver = require('semver') const semver = require('semver')
const { JavaGuard } = require('./assets/js/assetguard') const { JavaGuard } = require('./assets/js/assetguard')
const DropinModUtil = require('./assets/js/dropinmodutil') const DropinModUtil = require('./assets/js/dropinmodutil')
const settingsState = { const settingsState = {
invalid: new Set() invalid: new Set()
} }
function bindSettingsSelect() { function bindSettingsSelect(){
for (let ele of document.getElementsByClassName('settingsSelectContainer')) { for(let ele of document.getElementsByClassName('settingsSelectContainer')) {
const selectedDiv = ele.getElementsByClassName('settingsSelectSelected')[0] const selectedDiv = ele.getElementsByClassName('settingsSelectSelected')[0]
selectedDiv.onclick = (e) => { selectedDiv.onclick = (e) => {
@ -22,12 +22,12 @@ function bindSettingsSelect() {
} }
} }
function closeSettingsSelect(el) { function closeSettingsSelect(el){
for (let ele of document.getElementsByClassName('settingsSelectContainer')) { for(let ele of document.getElementsByClassName('settingsSelectContainer')) {
const selectedDiv = ele.getElementsByClassName('settingsSelectSelected')[0] const selectedDiv = ele.getElementsByClassName('settingsSelectSelected')[0]
const optionsDiv = ele.getElementsByClassName('settingsSelectOptions')[0] const optionsDiv = ele.getElementsByClassName('settingsSelectOptions')[0]
if (!(selectedDiv === el)) { if(!(selectedDiv === el)) {
selectedDiv.classList.remove('select-arrow-active') selectedDiv.classList.remove('select-arrow-active')
optionsDiv.setAttribute('hidden', '') optionsDiv.setAttribute('hidden', '')
} }
@ -41,9 +41,9 @@ document.addEventListener('click', closeSettingsSelect)
bindSettingsSelect() bindSettingsSelect()
function bindFileSelectors() { function bindFileSelectors(){
for (let ele of document.getElementsByClassName('settingsFileSelButton')) { for(let ele of document.getElementsByClassName('settingsFileSelButton')){
ele.onclick = async e => { ele.onclick = async e => {
const isJavaExecSel = ele.id === 'settingsJavaExecSel' const isJavaExecSel = ele.id === 'settingsJavaExecSel'
const directoryDialog = ele.hasAttribute('dialogDirectory') && ele.getAttribute('dialogDirectory') == 'true' const directoryDialog = ele.hasAttribute('dialogDirectory') && ele.getAttribute('dialogDirectory') == 'true'
@ -53,11 +53,11 @@ function bindFileSelectors() {
properties properties
} }
if (ele.hasAttribute('dialogTitle')) { if(ele.hasAttribute('dialogTitle')) {
options.title = ele.getAttribute('dialogTitle') options.title = ele.getAttribute('dialogTitle')
} }
if (isJavaExecSel && process.platform === 'win32') { if(isJavaExecSel && process.platform === 'win32') {
options.filters = [ options.filters = [
{ name: 'Executables', extensions: ['exe'] }, { name: 'Executables', extensions: ['exe'] },
{ name: 'All Files', extensions: ['*'] } { name: 'All Files', extensions: ['*'] }
@ -65,9 +65,9 @@ function bindFileSelectors() {
} }
const res = await remote.dialog.showOpenDialog(remote.getCurrentWindow(), options) const res = await remote.dialog.showOpenDialog(remote.getCurrentWindow(), options)
if (!res.canceled) { if(!res.canceled) {
ele.previousElementSibling.value = res.filePaths[0] ele.previousElementSibling.value = res.filePaths[0]
if (isJavaExecSel) { if(isJavaExecSel) {
populateJavaExecDetails(ele.previousElementSibling.value) populateJavaExecDetails(ele.previousElementSibling.value)
} }
} }
@ -89,24 +89,24 @@ bindFileSelectors()
* will be disabled until the value is corrected. This is an automated * will be disabled until the value is corrected. This is an automated
* process. More complex UI may need to be bound separately. * process. More complex UI may need to be bound separately.
*/ */
function initSettingsValidators() { function initSettingsValidators(){
const sEls = document.getElementById('settingsContainer').querySelectorAll('[cValue]') const sEls = document.getElementById('settingsContainer').querySelectorAll('[cValue]')
Array.from(sEls).map((v, index, arr) => { Array.from(sEls).map((v, index, arr) => {
const vFn = ConfigManager['validate' + v.getAttribute('cValue')] const vFn = ConfigManager['validate' + v.getAttribute('cValue')]
if (typeof vFn === 'function') { if(typeof vFn === 'function'){
if (v.tagName === 'INPUT') { if(v.tagName === 'INPUT'){
if (v.type === 'number' || v.type === 'text') { if(v.type === 'number' || v.type === 'text'){
v.addEventListener('keyup', (e) => { v.addEventListener('keyup', (e) => {
const v = e.target const v = e.target
if (!vFn(v.value)) { if(!vFn(v.value)){
settingsState.invalid.add(v.id) settingsState.invalid.add(v.id)
v.setAttribute('error', '') v.setAttribute('error', '')
settingsSaveDisabled(true) settingsSaveDisabled(true)
} else { } else {
if (v.hasAttribute('error')) { if(v.hasAttribute('error')){
v.removeAttribute('error') v.removeAttribute('error')
settingsState.invalid.delete(v.id) settingsState.invalid.delete(v.id)
if (settingsState.invalid.size === 0) { if(settingsState.invalid.size === 0){
settingsSaveDisabled(false) settingsSaveDisabled(false)
} }
} }
@ -122,35 +122,35 @@ function initSettingsValidators() {
/** /**
* Load configuration values onto the UI. This is an automated process. * Load configuration values onto the UI. This is an automated process.
*/ */
function initSettingsValues() { function initSettingsValues(){
const sEls = document.getElementById('settingsContainer').querySelectorAll('[cValue]') const sEls = document.getElementById('settingsContainer').querySelectorAll('[cValue]')
Array.from(sEls).map((v, index, arr) => { Array.from(sEls).map((v, index, arr) => {
const cVal = v.getAttribute('cValue') const cVal = v.getAttribute('cValue')
const gFn = ConfigManager['get' + cVal] const gFn = ConfigManager['get' + cVal]
if (typeof gFn === 'function') { if(typeof gFn === 'function'){
if (v.tagName === 'INPUT') { if(v.tagName === 'INPUT'){
if (v.type === 'number' || v.type === 'text') { if(v.type === 'number' || v.type === 'text'){
// Special Conditions // Special Conditions
if (cVal === 'JavaExecutable') { if(cVal === 'JavaExecutable'){
populateJavaExecDetails(v.value) populateJavaExecDetails(v.value)
v.value = gFn() v.value = gFn()
} else if (cVal === 'DataDirectory') { } else if (cVal === 'DataDirectory'){
v.value = gFn() v.value = gFn()
} else if (cVal === 'JVMOptions') { } else if(cVal === 'JVMOptions'){
v.value = gFn().join(' ') v.value = gFn().join(' ')
} else { } else {
v.value = gFn() v.value = gFn()
} }
} else if (v.type === 'checkbox') { } else if(v.type === 'checkbox'){
v.checked = gFn() v.checked = gFn()
} }
} else if (v.tagName === 'DIV') { } else if(v.tagName === 'DIV'){
if (v.classList.contains('rangeSlider')) { if(v.classList.contains('rangeSlider')){
// Special Conditions // Special Conditions
if (cVal === 'MinRAM' || cVal === 'MaxRAM') { if(cVal === 'MinRAM' || cVal === 'MaxRAM'){
let val = gFn() let val = gFn()
if (val.endsWith('M')) { if(val.endsWith('M')){
val = Number(val.substring(0, val.length - 1)) / 1000 val = Number(val.substring(0, val.length-1))/1000
} else { } else {
val = Number.parseFloat(val) val = Number.parseFloat(val)
} }
@ -169,34 +169,34 @@ function initSettingsValues() {
/** /**
* Save the settings values. * Save the settings values.
*/ */
function saveSettingsValues() { function saveSettingsValues(){
const sEls = document.getElementById('settingsContainer').querySelectorAll('[cValue]') const sEls = document.getElementById('settingsContainer').querySelectorAll('[cValue]')
Array.from(sEls).map((v, index, arr) => { Array.from(sEls).map((v, index, arr) => {
const cVal = v.getAttribute('cValue') const cVal = v.getAttribute('cValue')
const sFn = ConfigManager['set' + cVal] const sFn = ConfigManager['set' + cVal]
if (typeof sFn === 'function') { if(typeof sFn === 'function'){
if (v.tagName === 'INPUT') { if(v.tagName === 'INPUT'){
if (v.type === 'number' || v.type === 'text') { if(v.type === 'number' || v.type === 'text'){
// Special Conditions // Special Conditions
if (cVal === 'JVMOptions') { if(cVal === 'JVMOptions'){
sFn(v.value.split(' ')) sFn(v.value.split(' '))
} else { } else {
sFn(v.value) sFn(v.value)
} }
} else if (v.type === 'checkbox') { } else if(v.type === 'checkbox'){
sFn(v.checked) sFn(v.checked)
// Special Conditions // Special Conditions
if (cVal === 'AllowPrerelease') { if(cVal === 'AllowPrerelease'){
changeAllowPrerelease(v.checked) changeAllowPrerelease(v.checked)
} }
} }
} else if (v.tagName === 'DIV') { } else if(v.tagName === 'DIV'){
if (v.classList.contains('rangeSlider')) { if(v.classList.contains('rangeSlider')){
// Special Conditions // Special Conditions
if (cVal === 'MinRAM' || cVal === 'MaxRAM') { if(cVal === 'MinRAM' || cVal === 'MaxRAM'){
let val = Number(v.getAttribute('value')) let val = Number(v.getAttribute('value'))
if (val % 1 > 0) { if(val%1 > 0){
val = val * 1000 + 'M' val = val*1000 + 'M'
} else { } else {
val = val + 'G' val = val + 'G'
} }
@ -219,8 +219,8 @@ let selectedSettingsTab = 'settingsTabAccount'
* *
* @param {UIEvent} e The scroll event. * @param {UIEvent} e The scroll event.
*/ */
function settingsTabScrollListener(e) { function settingsTabScrollListener(e){
if (e.target.scrollTop > Number.parseFloat(getComputedStyle(e.target.firstElementChild).marginTop)) { if(e.target.scrollTop > Number.parseFloat(getComputedStyle(e.target.firstElementChild).marginTop)){
document.getElementById('settingsContainer').setAttribute('scrolled', '') document.getElementById('settingsContainer').setAttribute('scrolled', '')
} else { } else {
document.getElementById('settingsContainer').removeAttribute('scrolled') document.getElementById('settingsContainer').removeAttribute('scrolled')
@ -230,9 +230,9 @@ function settingsTabScrollListener(e) {
/** /**
* Bind functionality for the settings navigation items. * Bind functionality for the settings navigation items.
*/ */
function setupSettingsTabs() { function setupSettingsTabs(){
Array.from(document.getElementsByClassName('settingsNavItem')).map((val) => { Array.from(document.getElementsByClassName('settingsNavItem')).map((val) => {
if (val.hasAttribute('rSc')) { if(val.hasAttribute('rSc')){
val.onclick = () => { val.onclick = () => {
settingsNavItemListener(val) settingsNavItemListener(val)
} }
@ -247,13 +247,13 @@ function setupSettingsTabs() {
* @param {Element} ele The nav item which has been clicked. * @param {Element} ele The nav item which has been clicked.
* @param {boolean} fade Optional. True to fade transition. * @param {boolean} fade Optional. True to fade transition.
*/ */
function settingsNavItemListener(ele, fade = true) { function settingsNavItemListener(ele, fade = true){
if (ele.hasAttribute('selected')) { if(ele.hasAttribute('selected')){
return return
} }
const navItems = document.getElementsByClassName('settingsNavItem') const navItems = document.getElementsByClassName('settingsNavItem')
for (let i = 0; i < navItems.length; i++) { for(let i=0; i<navItems.length; i++){
if (navItems[i].hasAttribute('selected')) { if(navItems[i].hasAttribute('selected')){
navItems[i].removeAttribute('selected') navItems[i].removeAttribute('selected')
} }
} }
@ -264,7 +264,7 @@ function settingsNavItemListener(ele, fade = true) {
document.getElementById(prevTab).onscroll = null document.getElementById(prevTab).onscroll = null
document.getElementById(selectedSettingsTab).onscroll = settingsTabScrollListener document.getElementById(selectedSettingsTab).onscroll = settingsTabScrollListener
if (fade) { if(fade){
$(`#${prevTab}`).fadeOut(250, () => { $(`#${prevTab}`).fadeOut(250, () => {
$(`#${selectedSettingsTab}`).fadeIn({ $(`#${selectedSettingsTab}`).fadeIn({
duration: 250, duration: 250,
@ -296,7 +296,7 @@ const settingsNavDone = document.getElementById('settingsNavDone')
* *
* @param {boolean} v True to disable, false to enable. * @param {boolean} v True to disable, false to enable.
*/ */
function settingsSaveDisabled(v) { function settingsSaveDisabled(v){
settingsNavDone.disabled = v settingsNavDone.disabled = v
} }
@ -327,15 +327,15 @@ document.getElementById('settingsAddAccount').onclick = (e) => {
* Bind functionality for the account selection buttons. If another account * Bind functionality for the account selection buttons. If another account
* is selected, the UI of the previously selected account will be updated. * is selected, the UI of the previously selected account will be updated.
*/ */
function bindAuthAccountSelect() { function bindAuthAccountSelect(){
Array.from(document.getElementsByClassName('settingsAuthAccountSelect')).map((val) => { Array.from(document.getElementsByClassName('settingsAuthAccountSelect')).map((val) => {
val.onclick = (e) => { val.onclick = (e) => {
if (val.hasAttribute('selected')) { if(val.hasAttribute('selected')){
return return
} }
const selectBtns = document.getElementsByClassName('settingsAuthAccountSelect') const selectBtns = document.getElementsByClassName('settingsAuthAccountSelect')
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 = 'Select Account'
} }
@ -352,11 +352,11 @@ function bindAuthAccountSelect() {
* the selected account, another account will be selected and the UI will * the selected account, another account will be selected and the UI will
* be updated accordingly. * be updated accordingly.
*/ */
function bindAuthAccountLogOut() { function bindAuthAccountLogOut(){
Array.from(document.getElementsByClassName('settingsAuthAccountLogOut')).map((val) => { Array.from(document.getElementsByClassName('settingsAuthAccountLogOut')).map((val) => {
val.onclick = (e) => { val.onclick = (e) => {
let isLastAccount = false let isLastAccount = false
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', 'Warning<br>This is Your Last Account',
@ -376,7 +376,7 @@ function bindAuthAccountLogOut() {
} else { } else {
processLogOut(val, isLastAccount) processLogOut(val, isLastAccount)
} }
} }
}) })
} }
@ -405,7 +405,7 @@ function processLogOut(val, isLastAccount, skip = false) {
} }
const prevSelAcc = ConfigManager.getSelectedAccount() const prevSelAcc = ConfigManager.getSelectedAccount()
AuthManager.removeAccount(uuid).then(() => { AuthManager.removeAccount(uuid).then(() => {
if (!isLastAccount && uuid === prevSelAcc.uuid) { if(!isLastAccount && uuid === prevSelAcc.uuid){
const selAcc = ConfigManager.getSelectedAccount() const selAcc = ConfigManager.getSelectedAccount()
refreshAuthAccountSelected(selAcc.uuid) refreshAuthAccountSelected(selAcc.uuid)
updateSelectedAccount(selAcc) updateSelectedAccount(selAcc)
@ -428,14 +428,14 @@ ipcRenderer.on('MSALogoutWindowReply', (event, ...args) => {
* *
* @param {string} uuid The UUID of the new selected account. * @param {string} uuid The UUID of the new selected account.
*/ */
function refreshAuthAccountSelected(uuid) { function refreshAuthAccountSelected(uuid){
Array.from(document.getElementsByClassName('settingsAuthAccount')).map((val) => { Array.from(document.getElementsByClassName('settingsAuthAccount')).map((val) => {
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 &#10004;' selBtn.innerHTML = 'Selected Account &#10004;'
} else { } else {
if (selBtn.hasAttribute('selected')) { if(selBtn.hasAttribute('selected')){
selBtn.removeAttribute('selected') selBtn.removeAttribute('selected')
} }
selBtn.innerHTML = 'Select Account' selBtn.innerHTML = 'Select Account'
@ -448,10 +448,10 @@ const settingsCurrentAccounts = document.getElementById('settingsCurrentAccounts
/** /**
* Add auth account elements for each one stored in the authentication database. * Add auth account elements for each one stored in the authentication database.
*/ */
function populateAuthAccounts() { function populateAuthAccounts(){
const authAccounts = ConfigManager.getAuthAccounts() const authAccounts = ConfigManager.getAuthAccounts()
const authKeys = Object.keys(authAccounts) const authKeys = Object.keys(authAccounts)
if (authKeys.length === 0) { if(authKeys.length === 0){
return return
} }
const selectedUUID = ConfigManager.getSelectedAccount().uuid const selectedUUID = ConfigManager.getSelectedAccount().uuid
@ -462,7 +462,7 @@ function populateAuthAccounts() {
const acc = authAccounts[val] const acc = authAccounts[val]
authAccountStr += `<div class="settingsAuthAccount" uuid="${acc.uuid}"> authAccountStr += `<div class="settingsAuthAccount" uuid="${acc.uuid}">
<div class="settingsAuthAccountLeft"> <div class="settingsAuthAccountLeft">
<img class="settingsAuthAccountImage" alt="${acc.displayName}" src="https://crafatar.com/renders/body/${acc.uuid}?scale=3&default=MHF_Steve&overlay"> <img class="settingsAuthAccountImage" alt="${acc.displayName}" src="https://mc-heads.net/body/${acc.uuid}/60">
</div> </div>
<div class="settingsAuthAccountRight"> <div class="settingsAuthAccountRight">
<div class="settingsAuthAccountDetails"> <div class="settingsAuthAccountDetails">
@ -505,12 +505,12 @@ function prepareAccountsTab() {
* Disable decimals, negative signs, and scientific notation. * Disable decimals, negative signs, and scientific notation.
*/ */
document.getElementById('settingsGameWidth').addEventListener('keydown', (e) => { document.getElementById('settingsGameWidth').addEventListener('keydown', (e) => {
if (/^[-.eE]$/.test(e.key)) { if(/^[-.eE]$/.test(e.key)){
e.preventDefault() e.preventDefault()
} }
}) })
document.getElementById('settingsGameHeight').addEventListener('keydown', (e) => { document.getElementById('settingsGameHeight').addEventListener('keydown', (e) => {
if (/^[-.eE]$/.test(e.key)) { if(/^[-.eE]$/.test(e.key)){
e.preventDefault() e.preventDefault()
} }
}) })
@ -524,7 +524,7 @@ const settingsModsContainer = document.getElementById('settingsModsContainer')
/** /**
* Resolve and update the mods on the UI. * Resolve and update the mods on the UI.
*/ */
function resolveModsForUI() { function resolveModsForUI(){
const serv = ConfigManager.getSelectedServer() const serv = ConfigManager.getSelectedServer()
const distro = DistroManager.getDistribution() const distro = DistroManager.getDistribution()
@ -543,16 +543,16 @@ function resolveModsForUI() {
* @param {boolean} submodules Whether or not we are parsing submodules. * @param {boolean} submodules Whether or not we are parsing submodules.
* @param {Object} servConf The server configuration object for this module level. * @param {Object} servConf The server configuration object for this module level.
*/ */
function parseModulesForUI(mdls, submodules, servConf) { function parseModulesForUI(mdls, submodules, servConf){
let reqMods = '' let reqMods = ''
let optMods = '' let optMods = ''
for (const mdl of mdls) { for(const mdl of mdls){
if (mdl.getType() === DistroManager.Types.ForgeMod || mdl.getType() === DistroManager.Types.LiteMod || mdl.getType() === DistroManager.Types.LiteLoader) { if(mdl.getType() === DistroManager.Types.ForgeMod || mdl.getType() === DistroManager.Types.LiteMod || mdl.getType() === DistroManager.Types.LiteLoader){
if (mdl.getRequired().isRequired()) { if(mdl.getRequired().isRequired()){
reqMods += `<div id="${mdl.getVersionlessID()}" class="settingsBaseMod settings${submodules ? 'Sub' : ''}Mod" enabled> reqMods += `<div id="${mdl.getVersionlessID()}" class="settingsBaseMod settings${submodules ? 'Sub' : ''}Mod" enabled>
<div class="settingsModContent"> <div class="settingsModContent">
@ -612,11 +612,11 @@ function parseModulesForUI(mdls, submodules, servConf) {
* Bind functionality to mod config toggle switches. Switching the value * Bind functionality to mod config toggle switches. Switching the value
* will also switch the status color on the left of the mod UI. * will also switch the status color on the left of the mod UI.
*/ */
function bindModsToggleSwitch() { function bindModsToggleSwitch(){
const sEls = settingsModsContainer.querySelectorAll('[formod]') const sEls = settingsModsContainer.querySelectorAll('[formod]')
Array.from(sEls).map((v, index, arr) => { Array.from(sEls).map((v, index, arr) => {
v.onchange = () => { v.onchange = () => {
if (v.checked) { if(v.checked) {
document.getElementById(v.getAttribute('formod')).setAttribute('enabled', '') document.getElementById(v.getAttribute('formod')).setAttribute('enabled', '')
} else { } else {
document.getElementById(v.getAttribute('formod')).removeAttribute('enabled') document.getElementById(v.getAttribute('formod')).removeAttribute('enabled')
@ -629,7 +629,7 @@ function bindModsToggleSwitch() {
/** /**
* Save the mod configuration based on the UI values. * Save the mod configuration based on the UI values.
*/ */
function saveModConfiguration() { function saveModConfiguration(){
const serv = ConfigManager.getSelectedServer() const serv = ConfigManager.getSelectedServer()
const modConf = ConfigManager.getModConfiguration(serv) const modConf = ConfigManager.getModConfiguration(serv)
modConf.mods = _saveModConfiguration(modConf.mods) modConf.mods = _saveModConfiguration(modConf.mods)
@ -641,15 +641,15 @@ function saveModConfiguration() {
* *
* @param {Object} modConf Mod config object to save. * @param {Object} modConf Mod config object to save.
*/ */
function _saveModConfiguration(modConf) { function _saveModConfiguration(modConf){
for (let m of Object.entries(modConf)) { for(let m of Object.entries(modConf)){
const tSwitch = settingsModsContainer.querySelectorAll(`[formod='${m[0]}']`) const tSwitch = settingsModsContainer.querySelectorAll(`[formod='${m[0]}']`)
if (!tSwitch[0].hasAttribute('dropin')) { if(!tSwitch[0].hasAttribute('dropin')){
if (typeof m[1] === 'boolean') { if(typeof m[1] === 'boolean'){
modConf[m[0]] = tSwitch[0].checked modConf[m[0]] = tSwitch[0].checked
} else { } else {
if (m[1] != null) { if(m[1] != null){
if (tSwitch.length > 0) { if(tSwitch.length > 0){
modConf[m[0]].value = tSwitch[0].checked modConf[m[0]].value = tSwitch[0].checked
} }
modConf[m[0]].mods = _saveModConfiguration(modConf[m[0]].mods) modConf[m[0]].mods = _saveModConfiguration(modConf[m[0]].mods)
@ -669,14 +669,14 @@ let CACHE_DROPIN_MODS
* Resolve any located drop-in mods for this server and * Resolve any located drop-in mods for this server and
* populate the results onto the UI. * populate the results onto the UI.
*/ */
function resolveDropinModsForUI() { function resolveDropinModsForUI(){
const serv = DistroManager.getDistribution().getServer(ConfigManager.getSelectedServer()) const serv = DistroManager.getDistribution().getServer(ConfigManager.getSelectedServer())
CACHE_SETTINGS_MODS_DIR = path.join(ConfigManager.getInstanceDirectory(), serv.getID(), 'mods') CACHE_SETTINGS_MODS_DIR = path.join(ConfigManager.getInstanceDirectory(), serv.getID(), 'mods')
CACHE_DROPIN_MODS = DropinModUtil.scanForDropinMods(CACHE_SETTINGS_MODS_DIR, serv.getMinecraftVersion()) CACHE_DROPIN_MODS = DropinModUtil.scanForDropinMods(CACHE_SETTINGS_MODS_DIR, serv.getMinecraftVersion())
let dropinMods = '' let dropinMods = ''
for (dropin of CACHE_DROPIN_MODS) { for(dropin of CACHE_DROPIN_MODS){
dropinMods += `<div id="${dropin.fullName}" class="settingsBaseMod settingsDropinMod" ${!dropin.disabled ? 'enabled' : ''}> dropinMods += `<div id="${dropin.fullName}" class="settingsBaseMod settingsDropinMod" ${!dropin.disabled ? 'enabled' : ''}>
<div class="settingsModContent"> <div class="settingsModContent">
<div class="settingsModMainWrapper"> <div class="settingsModMainWrapper">
@ -702,13 +702,13 @@ function resolveDropinModsForUI() {
/** /**
* Bind the remove button for each loaded drop-in mod. * Bind the remove button for each loaded drop-in mod.
*/ */
function bindDropinModsRemoveButton() { function bindDropinModsRemoveButton(){
const sEls = settingsModsContainer.querySelectorAll('[remmod]') const sEls = settingsModsContainer.querySelectorAll('[remmod]')
Array.from(sEls).map((v, index, arr) => { Array.from(sEls).map((v, index, arr) => {
v.onclick = () => { v.onclick = async () => {
const fullName = v.getAttribute('remmod') const fullName = v.getAttribute('remmod')
const res = DropinModUtil.deleteDropinMod(CACHE_SETTINGS_MODS_DIR, fullName) const res = await DropinModUtil.deleteDropinMod(CACHE_SETTINGS_MODS_DIR, fullName)
if (res) { if(res){
document.getElementById(fullName).remove() document.getElementById(fullName).remove()
} else { } else {
setOverlayContent( setOverlayContent(
@ -727,7 +727,7 @@ function bindDropinModsRemoveButton() {
* Bind functionality to the file system button for the selected * Bind functionality to the file system button for the selected
* server configuration. * server configuration.
*/ */
function bindDropinModFileSystemButton() { function bindDropinModFileSystemButton(){
const fsBtn = document.getElementById('settingsDropinFileSystemButton') const fsBtn = document.getElementById('settingsDropinFileSystemButton')
fsBtn.onclick = () => { fsBtn.onclick = () => {
DropinModUtil.validateDir(CACHE_SETTINGS_MODS_DIR) DropinModUtil.validateDir(CACHE_SETTINGS_MODS_DIR)
@ -758,14 +758,14 @@ function bindDropinModFileSystemButton() {
* Save drop-in mod states. Enabling and disabling is just a matter * Save drop-in mod states. Enabling and disabling is just a matter
* of adding/removing the .disabled extension. * of adding/removing the .disabled extension.
*/ */
function saveDropinModConfiguration() { function saveDropinModConfiguration(){
for (dropin of CACHE_DROPIN_MODS) { for(dropin of CACHE_DROPIN_MODS){
const dropinUI = document.getElementById(dropin.fullName) const dropinUI = document.getElementById(dropin.fullName)
if (dropinUI != null) { if(dropinUI != null){
const dropinUIEnabled = dropinUI.hasAttribute('enabled') const dropinUIEnabled = dropinUI.hasAttribute('enabled')
if (DropinModUtil.isDropinModEnabled(dropin.fullName) != dropinUIEnabled) { if(DropinModUtil.isDropinModEnabled(dropin.fullName) != dropinUIEnabled){
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', 'Failed to Toggle<br>One or More Drop-in Mods',
err.message, err.message,
@ -783,8 +783,8 @@ function saveDropinModConfiguration() {
// Refresh the drop-in mods when F5 is pressed. // Refresh the drop-in mods when F5 is pressed.
// Only active on the mods tab. // Only active on the mods tab.
document.addEventListener('keydown', (e) => { document.addEventListener('keydown', (e) => {
if (getCurrentView() === VIEWS.settings && selectedSettingsTab === 'settingsTabMods') { if(getCurrentView() === VIEWS.settings && selectedSettingsTab === 'settingsTabMods'){
if (e.key === 'F5') { if(e.key === 'F5'){
reloadDropinMods() reloadDropinMods()
saveShaderpackSettings() saveShaderpackSettings()
resolveShaderpacksForUI() resolveShaderpacksForUI()
@ -792,7 +792,7 @@ document.addEventListener('keydown', (e) => {
} }
}) })
function reloadDropinMods() { function reloadDropinMods(){
resolveDropinModsForUI() resolveDropinModsForUI()
bindDropinModsRemoveButton() bindDropinModsRemoveButton()
bindDropinModFileSystemButton() bindDropinModFileSystemButton()
@ -808,7 +808,7 @@ let CACHE_SELECTED_SHADERPACK
/** /**
* Load shaderpack information. * Load shaderpack information.
*/ */
function resolveShaderpacksForUI() { function resolveShaderpacksForUI(){
const serv = DistroManager.getDistribution().getServer(ConfigManager.getSelectedServer()) const serv = DistroManager.getDistribution().getServer(ConfigManager.getSelectedServer())
CACHE_SETTINGS_INSTANCE_DIR = path.join(ConfigManager.getInstanceDirectory(), serv.getID()) CACHE_SETTINGS_INSTANCE_DIR = path.join(ConfigManager.getInstanceDirectory(), serv.getID())
CACHE_SHADERPACKS = DropinModUtil.scanForShaderpacks(CACHE_SETTINGS_INSTANCE_DIR) CACHE_SHADERPACKS = DropinModUtil.scanForShaderpacks(CACHE_SETTINGS_INSTANCE_DIR)
@ -817,20 +817,20 @@ function resolveShaderpacksForUI() {
setShadersOptions(CACHE_SHADERPACKS, CACHE_SELECTED_SHADERPACK) setShadersOptions(CACHE_SHADERPACKS, CACHE_SELECTED_SHADERPACK)
} }
function setShadersOptions(arr, selected) { function setShadersOptions(arr, selected){
const cont = document.getElementById('settingsShadersOptions') const cont = document.getElementById('settingsShadersOptions')
cont.innerHTML = '' cont.innerHTML = ''
for (let opt of arr) { for(let opt of arr) {
const d = document.createElement('DIV') const d = document.createElement('DIV')
d.innerHTML = opt.name d.innerHTML = opt.name
d.setAttribute('value', opt.fullName) d.setAttribute('value', opt.fullName)
if (opt.fullName === selected) { if(opt.fullName === selected) {
d.setAttribute('selected', '') d.setAttribute('selected', '')
document.getElementById('settingsShadersSelected').innerHTML = opt.name document.getElementById('settingsShadersSelected').innerHTML = opt.name
} }
d.addEventListener('click', function (e) { d.addEventListener('click', function(e) {
this.parentNode.previousElementSibling.innerHTML = this.innerHTML this.parentNode.previousElementSibling.innerHTML = this.innerHTML
for (let sib of this.parentNode.children) { for(let sib of this.parentNode.children){
sib.removeAttribute('selected') sib.removeAttribute('selected')
} }
this.setAttribute('selected', '') this.setAttribute('selected', '')
@ -840,10 +840,10 @@ function setShadersOptions(arr, selected) {
} }
} }
function saveShaderpackSettings() { function saveShaderpackSettings(){
let sel = 'OFF' let sel = 'OFF'
for (let opt of document.getElementById('settingsShadersOptions').childNodes) { for(let opt of document.getElementById('settingsShadersOptions').childNodes){
if (opt.hasAttribute('selected')) { if(opt.hasAttribute('selected')){
sel = opt.getAttribute('value') sel = opt.getAttribute('value')
} }
} }
@ -884,7 +884,7 @@ function bindShaderpackButton() {
/** /**
* Load the currently selected server information onto the mods tab. * Load the currently selected server information onto the mods tab.
*/ */
function loadSelectedServerOnModsTab() { function loadSelectedServerOnModsTab(){
const serv = DistroManager.getDistribution().getServer(ConfigManager.getSelectedServer()) const serv = DistroManager.getDistribution().getServer(ConfigManager.getSelectedServer())
document.getElementById('settingsSelServContent').innerHTML = ` document.getElementById('settingsSelServContent').innerHTML = `
@ -919,7 +919,7 @@ document.getElementById('settingsSwitchServerButton').addEventListener('click',
/** /**
* Save mod configuration for the current selected server. * Save mod configuration for the current selected server.
*/ */
function saveAllModConfigurations() { function saveAllModConfigurations(){
saveModConfiguration() saveModConfiguration()
ConfigManager.save() ConfigManager.save()
saveDropinModConfiguration() saveDropinModConfiguration()
@ -929,7 +929,7 @@ function saveAllModConfigurations() {
* Function to refresh the mods tab whenever the selected * Function to refresh the mods tab whenever the selected
* server is changed. * server is changed.
*/ */
function animateModsTabRefresh() { function animateModsTabRefresh(){
$('#settingsTabMods').fadeOut(500, () => { $('#settingsTabMods').fadeOut(500, () => {
prepareModsTab() prepareModsTab()
$('#settingsTabMods').fadeIn(500) $('#settingsTabMods').fadeIn(500)
@ -939,7 +939,7 @@ function animateModsTabRefresh() {
/** /**
* Prepare the Mods tab for display. * Prepare the Mods tab for display.
*/ */
function prepareModsTab(first) { function prepareModsTab(first){
resolveModsForUI() resolveModsForUI()
resolveDropinModsForUI() resolveDropinModsForUI()
resolveShaderpacksForUI() resolveShaderpacksForUI()
@ -955,12 +955,12 @@ function prepareModsTab(first) {
*/ */
// DOM Cache // DOM Cache
const settingsMaxRAMRange = document.getElementById('settingsMaxRAMRange') const settingsMaxRAMRange = document.getElementById('settingsMaxRAMRange')
const settingsMinRAMRange = document.getElementById('settingsMinRAMRange') const settingsMinRAMRange = document.getElementById('settingsMinRAMRange')
const settingsMaxRAMLabel = document.getElementById('settingsMaxRAMLabel') const settingsMaxRAMLabel = document.getElementById('settingsMaxRAMLabel')
const settingsMinRAMLabel = document.getElementById('settingsMinRAMLabel') const settingsMinRAMLabel = document.getElementById('settingsMinRAMLabel')
const settingsMemoryTotal = document.getElementById('settingsMemoryTotal') const settingsMemoryTotal = document.getElementById('settingsMemoryTotal')
const settingsMemoryAvail = document.getElementById('settingsMemoryAvail') const settingsMemoryAvail = document.getElementById('settingsMemoryAvail')
const settingsJavaExecDetails = document.getElementById('settingsJavaExecDetails') const settingsJavaExecDetails = document.getElementById('settingsJavaExecDetails')
// Store maximum memory values. // Store maximum memory values.
@ -971,7 +971,7 @@ const SETTINGS_MIN_MEMORY = ConfigManager.getAbsoluteMinRAM()
settingsMaxRAMRange.setAttribute('max', SETTINGS_MAX_MEMORY) settingsMaxRAMRange.setAttribute('max', SETTINGS_MAX_MEMORY)
settingsMaxRAMRange.setAttribute('min', SETTINGS_MIN_MEMORY) settingsMaxRAMRange.setAttribute('min', SETTINGS_MIN_MEMORY)
settingsMinRAMRange.setAttribute('max', SETTINGS_MAX_MEMORY) settingsMinRAMRange.setAttribute('max', SETTINGS_MAX_MEMORY)
settingsMinRAMRange.setAttribute('min', SETTINGS_MIN_MEMORY) settingsMinRAMRange.setAttribute('min', SETTINGS_MIN_MEMORY )
// Bind on change event for min memory container. // Bind on change event for min memory container.
settingsMinRAMRange.onchange = (e) => { settingsMinRAMRange.onchange = (e) => {
@ -983,22 +983,22 @@ settingsMinRAMRange.onchange = (e) => {
// Get reference to range bar. // Get reference to range bar.
const bar = e.target.getElementsByClassName('rangeSliderBar')[0] const bar = e.target.getElementsByClassName('rangeSliderBar')[0]
// Calculate effective total memory. // Calculate effective total memory.
const max = (os.totalmem() - 1000000000) / 1000000000 const max = (os.totalmem()-1000000000)/1000000000
// Change range bar color based on the selected value. // Change range bar color based on the selected value.
if (sMinV >= max / 2) { if(sMinV >= max/2){
bar.style.background = '#e86060' bar.style.background = '#e86060'
} else if (sMinV >= max / 4) { } else if(sMinV >= max/4) {
bar.style.background = '#e8e18b' bar.style.background = '#e8e18b'
} else { } else {
bar.style.background = null bar.style.background = null
} }
// Increase maximum memory if the minimum exceeds its value. // Increase maximum memory if the minimum exceeds its value.
if (sMaxV < sMinV) { if(sMaxV < sMinV){
const sliderMeta = calculateRangeSliderMeta(settingsMaxRAMRange) const sliderMeta = calculateRangeSliderMeta(settingsMaxRAMRange)
updateRangedSlider(settingsMaxRAMRange, sMinV, updateRangedSlider(settingsMaxRAMRange, sMinV,
((sMinV - sliderMeta.min) / sliderMeta.step) * sliderMeta.inc) ((sMinV-sliderMeta.min)/sliderMeta.step)*sliderMeta.inc)
settingsMaxRAMLabel.innerHTML = sMinV.toFixed(1) + 'G' settingsMaxRAMLabel.innerHTML = sMinV.toFixed(1) + 'G'
} }
@ -1015,22 +1015,22 @@ settingsMaxRAMRange.onchange = (e) => {
// Get reference to range bar. // Get reference to range bar.
const bar = e.target.getElementsByClassName('rangeSliderBar')[0] const bar = e.target.getElementsByClassName('rangeSliderBar')[0]
// Calculate effective total memory. // Calculate effective total memory.
const max = (os.totalmem() - 1000000000) / 1000000000 const max = (os.totalmem()-1000000000)/1000000000
// Change range bar color based on the selected value. // Change range bar color based on the selected value.
if (sMaxV >= max / 2) { if(sMaxV >= max/2){
bar.style.background = '#e86060' bar.style.background = '#e86060'
} else if (sMaxV >= max / 4) { } else if(sMaxV >= max/4) {
bar.style.background = '#e8e18b' bar.style.background = '#e8e18b'
} else { } else {
bar.style.background = null bar.style.background = null
} }
// Decrease the minimum memory if the maximum value is less. // Decrease the minimum memory if the maximum value is less.
if (sMaxV < sMinV) { if(sMaxV < sMinV){
const sliderMeta = calculateRangeSliderMeta(settingsMaxRAMRange) const sliderMeta = calculateRangeSliderMeta(settingsMaxRAMRange)
updateRangedSlider(settingsMinRAMRange, sMaxV, updateRangedSlider(settingsMinRAMRange, sMaxV,
((sMaxV - sliderMeta.min) / sliderMeta.step) * sliderMeta.inc) ((sMaxV-sliderMeta.min)/sliderMeta.step)*sliderMeta.inc)
settingsMinRAMLabel.innerHTML = sMaxV.toFixed(1) + 'G' settingsMinRAMLabel.innerHTML = sMaxV.toFixed(1) + 'G'
} }
settingsMaxRAMLabel.innerHTML = sMaxV.toFixed(1) + 'G' settingsMaxRAMLabel.innerHTML = sMaxV.toFixed(1) + 'G'
@ -1042,14 +1042,14 @@ settingsMaxRAMRange.onchange = (e) => {
* @param {Element} v The range slider to calculate against. * @param {Element} v The range slider to calculate against.
* @returns {Object} An object with meta values for the provided ranged slider. * @returns {Object} An object with meta values for the provided ranged slider.
*/ */
function calculateRangeSliderMeta(v) { function calculateRangeSliderMeta(v){
const val = { const val = {
max: Number(v.getAttribute('max')), max: Number(v.getAttribute('max')),
min: Number(v.getAttribute('min')), min: Number(v.getAttribute('min')),
step: Number(v.getAttribute('step')), step: Number(v.getAttribute('step')),
} }
val.ticks = (val.max - val.min) / val.step val.ticks = (val.max-val.min)/val.step
val.inc = 100 / val.ticks val.inc = 100/val.ticks
return val return val
} }
@ -1057,7 +1057,7 @@ function calculateRangeSliderMeta(v) {
* Binds functionality to the ranged sliders. They're more than * Binds functionality to the ranged sliders. They're more than
* just divs now :'). * just divs now :').
*/ */
function bindRangeSlider() { function bindRangeSlider(){
Array.from(document.getElementsByClassName('rangeSlider')).map((v) => { Array.from(document.getElementsByClassName('rangeSlider')).map((v) => {
// Reference the track (thumb). // Reference the track (thumb).
@ -1067,7 +1067,7 @@ function bindRangeSlider() {
const value = v.getAttribute('value') const value = v.getAttribute('value')
const sliderMeta = calculateRangeSliderMeta(v) const sliderMeta = calculateRangeSliderMeta(v)
updateRangedSlider(v, value, ((value - sliderMeta.min) / sliderMeta.step) * sliderMeta.inc) updateRangedSlider(v, value, ((value-sliderMeta.min)/sliderMeta.step)*sliderMeta.inc)
// The magic happens when we click on the track. // The magic happens when we click on the track.
track.onmousedown = (e) => { track.onmousedown = (e) => {
@ -1082,24 +1082,24 @@ function bindRangeSlider() {
document.onmousemove = (e) => { document.onmousemove = (e) => {
// Distance from the beginning of the bar in pixels. // Distance from the beginning of the bar in pixels.
const diff = e.pageX - v.offsetLeft - track.offsetWidth / 2 const diff = e.pageX - v.offsetLeft - track.offsetWidth/2
// Don't move the track off the bar. // Don't move the track off the bar.
if (diff >= 0 && diff <= v.offsetWidth - track.offsetWidth / 2) { if(diff >= 0 && diff <= v.offsetWidth-track.offsetWidth/2){
// Convert the difference to a percentage. // Convert the difference to a percentage.
const perc = (diff / v.offsetWidth) * 100 const perc = (diff/v.offsetWidth)*100
// Calculate the percentage of the closest notch. // Calculate the percentage of the closest notch.
const notch = Number(perc / sliderMeta.inc).toFixed(0) * sliderMeta.inc const notch = Number(perc/sliderMeta.inc).toFixed(0)*sliderMeta.inc
// If we're close to that notch, stick to it. // If we're close to that notch, stick to it.
if (Math.abs(perc - notch) < sliderMeta.inc / 2) { if(Math.abs(perc-notch) < sliderMeta.inc/2){
updateRangedSlider(v, sliderMeta.min + (sliderMeta.step * (notch / sliderMeta.inc)), notch) updateRangedSlider(v, sliderMeta.min+(sliderMeta.step*(notch/sliderMeta.inc)), notch)
} }
} }
} }
} }
}) })
} }
/** /**
@ -1109,16 +1109,16 @@ function bindRangeSlider() {
* @param {string | number} value The new value for the ranged slider. * @param {string | number} value The new value for the ranged slider.
* @param {number} notch The notch that the slider should now be at. * @param {number} notch The notch that the slider should now be at.
*/ */
function updateRangedSlider(element, value, notch) { function updateRangedSlider(element, value, notch){
const oldVal = element.getAttribute('value') const oldVal = element.getAttribute('value')
const bar = element.getElementsByClassName('rangeSliderBar')[0] const bar = element.getElementsByClassName('rangeSliderBar')[0]
const track = element.getElementsByClassName('rangeSliderTrack')[0] const track = element.getElementsByClassName('rangeSliderTrack')[0]
element.setAttribute('value', value) element.setAttribute('value', value)
if (notch < 0) { if(notch < 0){
notch = 0 notch = 0
} else if (notch > 100) { } else if(notch > 100) {
notch = 100 notch = 100
} }
@ -1131,7 +1131,7 @@ function updateRangedSlider(element, value, notch) {
let cancelled = !element.dispatchEvent(event) let cancelled = !element.dispatchEvent(event)
if (!cancelled) { if(!cancelled){
track.style.left = notch + '%' track.style.left = notch + '%'
bar.style.width = notch + '%' bar.style.width = notch + '%'
} else { } else {
@ -1142,9 +1142,9 @@ function updateRangedSlider(element, value, notch) {
/** /**
* Display the total and available RAM. * Display the total and available RAM.
*/ */
function populateMemoryStatus() { function populateMemoryStatus(){
settingsMemoryTotal.innerHTML = Number((os.totalmem() - 1000000000) / 1000000000).toFixed(1) + 'G' settingsMemoryTotal.innerHTML = Number((os.totalmem()-1000000000)/1000000000).toFixed(1) + 'G'
settingsMemoryAvail.innerHTML = Number(os.freemem() / 1000000000).toFixed(1) + 'G' settingsMemoryAvail.innerHTML = Number(os.freemem()/1000000000).toFixed(1) + 'G'
} }
/** /**
@ -1153,12 +1153,12 @@ function populateMemoryStatus() {
* *
* @param {string} execPath The executable path to populate against. * @param {string} execPath The executable path to populate against.
*/ */
function populateJavaExecDetails(execPath) { function populateJavaExecDetails(execPath){
const jg = new JavaGuard(DistroManager.getDistribution().getServer(ConfigManager.getSelectedServer()).getMinecraftVersion()) const jg = new JavaGuard(DistroManager.getDistribution().getServer(ConfigManager.getSelectedServer()).getMinecraftVersion())
jg._validateJavaBinary(execPath).then(v => { jg._validateJavaBinary(execPath).then(v => {
if (v.valid) { if(v.valid){
const vendor = v.vendor != null ? ` (${v.vendor})` : '' const vendor = v.vendor != null ? ` (${v.vendor})` : ''
if (v.version.major < 9) { if(v.version.major < 9) {
settingsJavaExecDetails.innerHTML = `Selected: Java ${v.version.major} Update ${v.version.update} (x${v.arch})${vendor}` settingsJavaExecDetails.innerHTML = `Selected: Java ${v.version.major} Update ${v.version.update} (x${v.arch})${vendor}`
} else { } else {
settingsJavaExecDetails.innerHTML = `Selected: Java ${v.version.major}.${v.version.minor}.${v.version.revision} (x${v.arch})${vendor}` settingsJavaExecDetails.innerHTML = `Selected: Java ${v.version.major}.${v.version.minor}.${v.version.revision} (x${v.arch})${vendor}`
@ -1172,7 +1172,7 @@ function populateJavaExecDetails(execPath) {
/** /**
* Prepare the Java tab for display. * Prepare the Java tab for display.
*/ */
function prepareJavaTab() { function prepareJavaTab(){
bindRangeSlider() bindRangeSlider()
populateMemoryStatus() populateMemoryStatus()
} }
@ -1181,9 +1181,9 @@ function prepareJavaTab() {
* About Tab * About Tab
*/ */
const settingsTabAbout = document.getElementById('settingsTabAbout') const settingsTabAbout = document.getElementById('settingsTabAbout')
const settingsAboutChangelogTitle = settingsTabAbout.getElementsByClassName('settingsChangelogTitle')[0] const settingsAboutChangelogTitle = settingsTabAbout.getElementsByClassName('settingsChangelogTitle')[0]
const settingsAboutChangelogText = settingsTabAbout.getElementsByClassName('settingsChangelogText')[0] const settingsAboutChangelogText = settingsTabAbout.getElementsByClassName('settingsChangelogText')[0]
const settingsAboutChangelogButton = settingsTabAbout.getElementsByClassName('settingsChangelogButton')[0] const settingsAboutChangelogButton = settingsTabAbout.getElementsByClassName('settingsChangelogButton')[0]
// Bind the devtools toggle button. // Bind the devtools toggle button.
@ -1198,7 +1198,7 @@ document.getElementById('settingsAboutDevToolsButton').onclick = (e) => {
* @param {string} version The semver version to test. * @param {string} version The semver version to test.
* @returns {boolean} True if the version is a prerelease, otherwise false. * @returns {boolean} True if the version is a prerelease, otherwise false.
*/ */
function isPrerelease(version) { function isPrerelease(version){
const preRelComp = semver.prerelease(version) const preRelComp = semver.prerelease(version)
return preRelComp != null && preRelComp.length > 0 return preRelComp != null && preRelComp.length > 0
} }
@ -1212,9 +1212,9 @@ function isPrerelease(version) {
* @param {Element} titleElement The title element. * @param {Element} titleElement The title element.
* @param {Element} checkElement The check mark element. * @param {Element} checkElement The check mark element.
*/ */
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 = 'Pre-release'
titleElement.style.color = '#ff886d' titleElement.style.color = '#ff886d'
checkElement.style.background = '#ff886d' checkElement.style.background = '#ff886d'
@ -1228,7 +1228,7 @@ function populateVersionInformation(version, valueElement, titleElement, checkEl
/** /**
* Retrieve the version information and display it on the UI. * Retrieve the version information and display it on the UI.
*/ */
function populateAboutVersionInformation() { function populateAboutVersionInformation(){
populateVersionInformation(remote.app.getVersion(), document.getElementById('settingsAboutCurrentVersionValue'), document.getElementById('settingsAboutCurrentVersionTitle'), document.getElementById('settingsAboutCurrentVersionCheck')) populateVersionInformation(remote.app.getVersion(), document.getElementById('settingsAboutCurrentVersionValue'), document.getElementById('settingsAboutCurrentVersionTitle'), document.getElementById('settingsAboutCurrentVersionCheck'))
} }
@ -1236,19 +1236,19 @@ function populateAboutVersionInformation() {
* Fetches the GitHub atom release feed and parses it for the release notes * Fetches the GitHub atom release feed and parses it for the release notes
* of the current version. This value is displayed on the UI. * of the current version. This value is displayed on the UI.
*/ */
function populateReleaseNotes() { function populateReleaseNotes(){
$.ajax({ $.ajax({
url: 'https://github.com/ArdaCraft/ArdaCraftLauncher/releases.atom', url: 'https://github.com/ArdaCraft/ArdaCraftLauncher/releases.atom',
success: (data) => { success: (data) => {
const version = 'v' + remote.app.getVersion() const version = 'v' + remote.app.getVersion()
const entries = $(data).find('entry') const entries = $(data).find('entry')
for (let i = 0; i < entries.length; i++) { for(let i=0; i<entries.length; i++){
const entry = $(entries[i]) const entry = $(entries[i])
let id = entry.find('id').text() let id = entry.find('id').text()
id = id.substring(id.lastIndexOf('/') + 1) id = id.substring(id.lastIndexOf('/')+1)
if (id === version) { if(id === version){
settingsAboutChangelogTitle.innerHTML = entry.find('title').text() settingsAboutChangelogTitle.innerHTML = entry.find('title').text()
settingsAboutChangelogText.innerHTML = entry.find('content').text() settingsAboutChangelogText.innerHTML = entry.find('content').text()
settingsAboutChangelogButton.href = entry.find('link').attr('href') settingsAboutChangelogButton.href = entry.find('link').attr('href')
@ -1265,7 +1265,7 @@ function populateReleaseNotes() {
/** /**
* Prepare account tab for display. * Prepare account tab for display.
*/ */
function prepareAboutTab() { function prepareAboutTab(){
populateAboutVersionInformation() populateAboutVersionInformation()
populateReleaseNotes() populateReleaseNotes()
} }
@ -1274,15 +1274,15 @@ function prepareAboutTab() {
* Update Tab * Update Tab
*/ */
const settingsTabUpdate = document.getElementById('settingsTabUpdate') const settingsTabUpdate = document.getElementById('settingsTabUpdate')
const settingsUpdateTitle = document.getElementById('settingsUpdateTitle') const settingsUpdateTitle = document.getElementById('settingsUpdateTitle')
const settingsUpdateVersionCheck = document.getElementById('settingsUpdateVersionCheck') const settingsUpdateVersionCheck = document.getElementById('settingsUpdateVersionCheck')
const settingsUpdateVersionTitle = document.getElementById('settingsUpdateVersionTitle') const settingsUpdateVersionTitle = document.getElementById('settingsUpdateVersionTitle')
const settingsUpdateVersionValue = document.getElementById('settingsUpdateVersionValue') const settingsUpdateVersionValue = document.getElementById('settingsUpdateVersionValue')
const settingsUpdateChangelogTitle = settingsTabUpdate.getElementsByClassName('settingsChangelogTitle')[0] const settingsUpdateChangelogTitle = settingsTabUpdate.getElementsByClassName('settingsChangelogTitle')[0]
const settingsUpdateChangelogText = settingsTabUpdate.getElementsByClassName('settingsChangelogText')[0] const settingsUpdateChangelogText = settingsTabUpdate.getElementsByClassName('settingsChangelogText')[0]
const settingsUpdateChangelogCont = settingsTabUpdate.getElementsByClassName('settingsChangelogContainer')[0] const settingsUpdateChangelogCont = settingsTabUpdate.getElementsByClassName('settingsChangelogContainer')[0]
const settingsUpdateActionButton = document.getElementById('settingsUpdateActionButton') const settingsUpdateActionButton = document.getElementById('settingsUpdateActionButton')
/** /**
* Update the properties of the update action button. * Update the properties of the update action button.
@ -1291,10 +1291,10 @@ const settingsUpdateActionButton = document.getElementById('settingsUpdateAction
* @param {boolean} disabled Optional. Disable or enable the button * @param {boolean} disabled Optional. Disable or enable the button
* @param {function} handler Optional. New button event handler. * @param {function} handler Optional. New button event handler.
*/ */
function settingsUpdateButtonStatus(text, disabled = false, handler = null) { function settingsUpdateButtonStatus(text, disabled = false, handler = null){
settingsUpdateActionButton.innerHTML = text settingsUpdateActionButton.innerHTML = text
settingsUpdateActionButton.disabled = disabled settingsUpdateActionButton.disabled = disabled
if (handler != null) { if(handler != null){
settingsUpdateActionButton.onclick = handler settingsUpdateActionButton.onclick = handler
} }
} }
@ -1304,15 +1304,15 @@ function settingsUpdateButtonStatus(text, disabled = false, handler = null) {
* *
* @param {Object} data The update data. * @param {Object} data The update data.
*/ */
function populateSettingsUpdateInformation(data) { function populateSettingsUpdateInformation(data){
if (data != null) { if(data != null){
settingsUpdateTitle.innerHTML = `New ${isPrerelease(data.version) ? 'Pre-release' : 'Release'} Available` settingsUpdateTitle.innerHTML = `New ${isPrerelease(data.version) ? 'Pre-release' : 'Release'} Available`
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('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) shell.openExternal(data.darwindownload)
}) })
@ -1324,7 +1324,7 @@ function populateSettingsUpdateInformation(data) {
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('Check for Updates', false, () => {
if (!isDev) { if(!isDev){
ipcRenderer.send('autoUpdateAction', 'checkForUpdate') ipcRenderer.send('autoUpdateAction', 'checkForUpdate')
settingsUpdateButtonStatus('Checking for Updates..', true) settingsUpdateButtonStatus('Checking for Updates..', true)
} }
@ -1337,7 +1337,7 @@ function populateSettingsUpdateInformation(data) {
* *
* @param {Object} data The update data. * @param {Object} data The update data.
*/ */
function prepareUpdateTab(data = null) { function prepareUpdateTab(data = null){
populateSettingsUpdateInformation(data) populateSettingsUpdateInformation(data)
} }
@ -1351,7 +1351,7 @@ function prepareUpdateTab(data = null) {
* @param {boolean} first Whether or not it is the first load. * @param {boolean} first Whether or not it is the first load.
*/ */
function prepareSettings(first = false) { function prepareSettings(first = false) {
if (first) { if(first){
setupSettingsTabs() setupSettingsTabs()
initSettingsValidators() initSettingsValidators()
prepareUpdateTab() prepareUpdateTab()

View File

@ -31,7 +31,7 @@
</div> </div>
<div id="loginOptions"> <div id="loginOptions">
<span class="loginSpanDim"> <span class="loginSpanDim">
<a href="https://my.minecraft.net/en-us/password/forgot/">forgot password?</a> <a href="https://minecraft.net/password/forgot/">forgot password?</a>
</span> </span>
<label id="checkmarkContainer"> <label id="checkmarkContainer">
<input id="loginRememberOption" type="checkbox" checked /> <input id="loginRememberOption" type="checkbox" checked />
@ -75,7 +75,7 @@
</svg></button> </svg></button>
<div id="loginDisclaimer"> <div id="loginDisclaimer">
<span class="loginSpanDim" id="loginRegisterSpan"> <span class="loginSpanDim" id="loginRegisterSpan">
<a href="https://www.minecraft.net/en-us/store/minecraft-java-edition">Need an Account?</a> <a href="https://minecraft.net/store/minecraft-java-edition/">Need an Account?</a>
</span> </span>
<p class="loginDisclaimerText"> <p class="loginDisclaimerText">
Your password is sent directly to Mojang and never stored. Your password is sent directly to Mojang and never stored.
@ -87,4 +87,4 @@
</form> </form>
</div> </div>
<script src="./assets/js/scripts/login.js"></script> <script src="./assets/js/scripts/login.js"></script>
</div> </div>

View File

@ -1,14 +1,15 @@
require('@electron/remote/main').initialize() const remoteMain = require('@electron/remote/main')
remoteMain.initialize()
// Requirements // Requirements
const { app, BrowserWindow, ipcMain, Menu } = require('electron') const { app, BrowserWindow, ipcMain, Menu } = require('electron')
const autoUpdater = require('electron-updater').autoUpdater const autoUpdater = require('electron-updater').autoUpdater
const ejse = require('ejs-electron') const ejse = require('ejs-electron')
const fs = require('fs') const fs = require('fs')
const isDev = require('./app/assets/js/isdev') const isDev = require('./app/assets/js/isdev')
const path = require('path') const path = require('path')
const semver = require('semver') const semver = require('semver')
const url = require('url') const { pathToFileURL } = require('url')
const redirectUriPrefix = 'https://login.microsoftonline.com/common/oauth2/nativeclient?' const redirectUriPrefix = 'https://login.microsoftonline.com/common/oauth2/nativeclient?'
const clientID = '0c7c8228-98ff-4ed8-ae28-af41852ba6ab' const clientID = '0c7c8228-98ff-4ed8-ae28-af41852ba6ab'
@ -16,18 +17,18 @@ const clientID = '0c7c8228-98ff-4ed8-ae28-af41852ba6ab'
// Setup auto updater. // Setup auto updater.
function initAutoUpdater(event, data) { function initAutoUpdater(event, data) {
if (data) { if(data){
autoUpdater.allowPrerelease = true autoUpdater.allowPrerelease = true
} else { } else {
// Defaults to true if application version contains prerelease components (e.g. 0.12.1-alpha.1) // Defaults to true if application version contains prerelease components (e.g. 0.12.1-alpha.1)
// autoUpdater.allowPrerelease = true // autoUpdater.allowPrerelease = true
} }
if (isDev) { if(isDev){
autoUpdater.autoInstallOnAppQuit = false autoUpdater.autoInstallOnAppQuit = false
autoUpdater.updateConfigPath = path.join(__dirname, 'dev-app-update.yml') autoUpdater.updateConfigPath = path.join(__dirname, 'dev-app-update.yml')
} }
if (process.platform === 'darwin') { if(process.platform === 'darwin'){
autoUpdater.autoDownload = false autoUpdater.autoDownload = false
} }
autoUpdater.on('update-available', (info) => { autoUpdater.on('update-available', (info) => {
@ -44,12 +45,12 @@ function initAutoUpdater(event, data) {
}) })
autoUpdater.on('error', (err) => { autoUpdater.on('error', (err) => {
event.sender.send('autoUpdateNotification', 'realerror', err) event.sender.send('autoUpdateNotification', 'realerror', err)
}) })
} }
// Open channel to listen for update actions. // Open channel to listen for update actions.
ipcMain.on('autoUpdateAction', (event, arg, data) => { ipcMain.on('autoUpdateAction', (event, arg, data) => {
switch (arg) { switch(arg){
case 'initAutoUpdater': case 'initAutoUpdater':
console.log('Initializing auto updater.') console.log('Initializing auto updater.')
initAutoUpdater(event, data) initAutoUpdater(event, data)
@ -62,9 +63,9 @@ ipcMain.on('autoUpdateAction', (event, arg, data) => {
}) })
break break
case 'allowPrereleaseChange': case 'allowPrereleaseChange':
if (!data) { if(!data){
const preRelComp = semver.prerelease(app.getVersion()) const preRelComp = semver.prerelease(app.getVersion())
if (preRelComp != null && preRelComp.length > 0) { if(preRelComp != null && preRelComp.length > 0){
autoUpdater.allowPrerelease = true autoUpdater.allowPrerelease = true
} else { } else {
autoUpdater.allowPrerelease = data autoUpdater.allowPrerelease = data
@ -177,20 +178,15 @@ function createWindow() {
webPreferences: { webPreferences: {
preload: path.join(__dirname, 'app', 'assets', 'js', 'preloader.js'), preload: path.join(__dirname, 'app', 'assets', 'js', 'preloader.js'),
nodeIntegration: true, nodeIntegration: true,
contextIsolation: false, contextIsolation: false
enableRemoteModule: true,
worldSafeExecuteJavaScript: true
}, },
backgroundColor: '#171614' backgroundColor: '#171614'
}) })
remoteMain.enable(win.webContents)
ejse.data('bkid', Math.floor((Math.random() * fs.readdirSync(path.join(__dirname, 'app', 'assets', 'images', 'backgrounds')).length))) ejse.data('bkid', Math.floor((Math.random() * fs.readdirSync(path.join(__dirname, 'app', 'assets', 'images', 'backgrounds')).length)))
win.loadURL(url.format({ win.loadURL(pathToFileURL(path.join(__dirname, 'app', 'app.ejs')).toString())
pathname: path.join(__dirname, 'app', 'app.ejs'),
protocol: 'file:',
slashes: true
}))
/*win.once('ready-to-show', () => { /*win.once('ready-to-show', () => {
win.show() win.show()
@ -206,8 +202,8 @@ function createWindow() {
} }
function createMenu() { function createMenu() {
if (process.platform === 'darwin') { if(process.platform === 'darwin') {
// Extend default included application menu to continue support for quit keyboard shortcut // Extend default included application menu to continue support for quit keyboard shortcut
let applicationSubMenu = { let applicationSubMenu = {
@ -269,9 +265,9 @@ function createMenu() {
} }
function getPlatformIcon(filename) { function getPlatformIcon(filename){
let ext let ext
switch (process.platform) { switch(process.platform) {
case 'win32': case 'win32':
ext = 'ico' ext = 'ico'
break break

Binary file not shown.

1101
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -23,9 +23,9 @@
"node": "14.x.x" "node": "14.x.x"
}, },
"dependencies": { "dependencies": {
"@electron/remote": "^1.1.0", "@electron/remote": "^2.0.1",
"adm-zip": "^0.5.5", "adm-zip": "^0.5.7",
"async": "^3.2.0", "async": "^3.2.1",
"discord-rpc": "^3.2.0", "discord-rpc": "^3.2.0",
"ejs": "^3.1.6", "ejs": "^3.1.6",
"ejs-electron": "^2.1.1", "ejs-electron": "^2.1.1",
@ -39,9 +39,9 @@
"winreg": "^1.2.4" "winreg": "^1.2.4"
}, },
"devDependencies": { "devDependencies": {
"electron": "^12.0.7", "electron": "^13.5.1",
"electron-builder": "^22.10.5", "electron-builder": "^22.11.7",
"eslint": "^7.26.0" "eslint": "^7.32.0"
}, },
"repository": { "repository": {
"type": "git", "type": "git",