add login ad multiple account support

This commit is contained in:
Dr_Dee 2021-02-05 16:49:36 +01:00
parent 731f00acc9
commit 68879fa7eb
4 changed files with 296 additions and 219 deletions

View File

@ -48,16 +48,18 @@ async function validateSelectedMicrosoft() {
const MCExpired = now > MCExpiresAt
if(MCExpired) {
const MSExpiresAt = Date.parse(ConfigManager.getMicrosoftAuth().expires_at)
const MSExpiresAt = Date.parse(current.microsoft.expires_at)
const MSExpired = now > MSExpiresAt
if (MSExpired) {
const newAccessToken = await Microsoft.refreshAccessToken(ConfigManager.getMicrosoftAuth)
ConfigManager.updateMicrosoftAuth(newAccessToken.access_token, newAccessToken.expires_at)
const newAccessToken = await Microsoft.refreshAccessToken(current.microsoft.refresh_token)
const newMCAccessToken = await Microsoft.authMinecraft(newAccessToken.access_token)
ConfigManager.updateAuthAccount(current.uuid, newMCAccessToken.access_token, newAccessToken.expires_at)
ConfigManager.save()
return true
}
const newMCAccessToken = await Microsoft.authMinecraft(ConfigManager.getMicrosoftAuth().access_token)
ConfigManager.updateAuthAccount(current.uuid, newMCAccessToken.access_token, newMCAccessToken.expires_at)
const newMCAccessToken = await Microsoft.authMinecraft(current.microsoft.access_token)
ConfigManager.updateAuthAccount(current.uuid, newMCAccessToken.access_token, current.microsoft.access_token, current.microsoft.expires_at, newMCAccessToken.expires_at)
ConfigManager.save()
return true
@ -110,6 +112,11 @@ exports.addAccount = async function(username, password){
exports.removeAccount = async function(uuid){
try {
const authAcc = ConfigManager.getAuthAccount(uuid)
if(authAcc.type === 'microsoft'){
ConfigManager.removeAuthAccount(uuid)
ConfigManager.save()
return Promise.resolve()
}
await Mojang.invalidate(authAcc.accessToken, ConfigManager.getClientToken())
ConfigManager.removeAuthAccount(uuid)
ConfigManager.save()
@ -150,7 +157,6 @@ exports.validateSelected = async function(){
exports.addMSAccount = async authCode => {
try {
const accessToken = await Microsoft.getAccessToken(authCode)
ConfigManager.setMicrosoftAuth(accessToken)
const MCAccessToken = await Microsoft.authMinecraft(accessToken.access_token)
const minecraftBuyed = await Microsoft.checkMCStore(MCAccessToken.access_token)
if(!minecraftBuyed)
@ -158,7 +164,7 @@ exports.addMSAccount = async authCode => {
message: 'You didn\'t buy Minecraft! Please use another Microsoft account or buy Minecraft.'
})
const MCProfile = await Microsoft.getMCProfile(MCAccessToken.access_token)
const ret = ConfigManager.addAuthAccount(MCProfile.id, MCAccessToken.access_token, MCProfile.name, MCProfile.name, MCAccessToken.expires_at, 'microsoft')
const ret = ConfigManager.addMsAuthAccount(MCProfile.id, MCAccessToken.access_token, MCProfile.name, MCAccessToken.expires_at, accessToken.access_token, accessToken.refresh_token)
ConfigManager.save()
return ret

View File

@ -326,14 +326,34 @@ exports.getAuthAccount = function(uuid){
*
* @returns {Object} The authenticated account object created by this action.
*/
exports.updateAuthAccount = function(uuid, accessToken, expiresAt = undefined){
exports.updateAuthAccount = function(uuid, accessToken){
config.authenticationDatabase[uuid].accessToken = accessToken
config.authenticationDatabase[uuid].expiresAt = expiresAt
return config.authenticationDatabase[uuid]
}
/**
* Adds an authenticated account to the database to be stored.
* Update the tokens of an authenticated microsoft account.
*
* @param {string} uuid The uuid of the authenticated account.
* @param {string} accessToken The new Access Token.
* @param {string} msAccessToken The new Microsoft Access Token
* @param {string} msRefreshToken The new Microsoft Refresh Token
* @param {date} msExpires The date when the microsoft access token expires
* @param {date} mcExpires The date when the mojang access token expires
*
* @returns {Object} The authenticated account object created by this action.
*/
exports.updateAuthAccount = function(uuid, accessToken, msAccessToken, msRefreshToken, msExpires, mcExpires){
config.authenticationDatabase[uuid].accessToken = accessToken
config.authenticationDatabase[uuid].expiresAt = mcExpires
config.authenticationDatabase[uuid].microsoft.access_token = msAccessToken
config.authenticationDatabase[uuid].microsoft.refresh_token = msRefreshToken
config.authenticationDatabase[uuid].microsoft.expires_at = msRefreshToken
return config.authenticationDatabase[uuid]
}
/**
* Adds an authenticated mojang account to the database to be stored.
*
* @param {string} uuid The uuid of the authenticated account.
* @param {string} accessToken The accessToken of the authenticated account.
@ -342,15 +362,45 @@ exports.updateAuthAccount = function(uuid, accessToken, expiresAt = undefined){
*
* @returns {Object} The authenticated account object created by this action.
*/
exports.addAuthAccount = function(uuid, accessToken, username, displayName, expiresAt = null, type = 'mojang'){
exports.addAuthAccount = function(uuid, accessToken, username, displayName){
config.selectedAccount = uuid
config.authenticationDatabase[uuid] = {
accessToken,
username: username.trim(),
uuid: uuid.trim(),
displayName: displayName.trim(),
expiresAt: expiresAt,
type: type
type: 'mojang'
}
return config.authenticationDatabase[uuid]
}
/**
* Adds an authenticated microsoft account to the database to be stored.
*
* @param {string} uuid The uuid of the authenticated account.
* @param {string} accessToken The accessToken of the authenticated account.
* @param {string} name The in game name of the authenticated account.
* @param {date} mcExpires The date when the mojang access token expires
* @param {string} msAccessToken The microsoft access token
* @param {string} msRefreshToken The microsoft refresh token
* @param {date} msExpires The date when the microsoft access token expires
*
* @returns {Object} The authenticated account object created by this action.
*/
exports.addMsAuthAccount = function(uuid, accessToken, name, mcExpires, msAccessToken, msRefreshToken, msExpires){
config.selectedAccount = uuid
config.authenticationDatabase[uuid] = {
accessToken,
username: name.trim(),
uuid: uuid.trim(),
displayName: name.trim(),
expiresAt: mcExpires,
type: 'microsoft',
microsoft: {
access_token: msAccessToken,
refresh_token: msRefreshToken,
expires_at: msExpires
}
}
return config.authenticationDatabase[uuid]
}
@ -689,19 +739,4 @@ exports.getAllowPrerelease = function(def = false){
*/
exports.setAllowPrerelease = function(allowPrerelease){
config.settings.launcher.allowPrerelease = allowPrerelease
}
exports.setMicrosoftAuth = microsoftAuth => {
config.microsoftAuth = microsoftAuth
}
exports.getMicrosoftAuth = () => {
return config.microsoftAuth
}
exports.updateMicrosoftAuth = (accessToken, expiresAt) => {
config.microsoftAuth.access_token = accessToken
config.microsoftAuth.expires_at = expiresAt
return config.microsoftAuth
}
}

View File

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

View File

@ -89,17 +89,15 @@ ipcMain.on('distributionIndexDone', (event, res) => {
app.disableHardwareAcceleration()
let MSALoginWindow = null
let login = false
// Open the Microsoft Account Login window
ipcMain.on('openMSALoginWindow', (ipcEvent, args) => {
login = false
if (MSALoginWindow != null) {
ipcEvent.reply('MSALoginWindowReply', 'error', 'AlreadyOpenException')
return
}
MSALoginWindow = new BrowserWindow({
title: 'Microsoft-Login',
title: 'Microsoft Login',
backgroundColor: '#222222',
width: 520,
height: 600,
@ -118,7 +116,6 @@ ipcMain.on('openMSALoginWindow', (ipcEvent, args) => {
})
MSALoginWindow.webContents.on('did-navigate', (event, uri, responseCode, statusText) => {
login = true
if (uri.startsWith(redirectUriPrefix)) {
let querys = uri.substring(redirectUriPrefix.length).split('#', 1).toString().split('&')
let queryMap = new Map()
@ -139,6 +136,27 @@ ipcMain.on('openMSALoginWindow', (ipcEvent, args) => {
MSALoginWindow.loadURL('https://login.microsoftonline.com/consumers/oauth2/v2.0/authorize?prompt=consent&client_id=' + clientID + '&response_type=code&scope=XboxLive.signin%20offline_access&redirect_uri=https://login.microsoftonline.com/common/oauth2/nativeclient')
})
let MSALogoutWindow = null
ipcMain.on('openMSALogoutWindow', (ipcEvent, args) => {
if (MSALogoutWindow == null) {
MSALogoutWindow = new BrowserWindow({
title: 'Microsoft Logout',
backgroundColor: '#222222',
width: 520,
height: 600,
frame: true,
icon: getPlatformIcon('SealCircle')
})
MSALogoutWindow.loadURL('https://login.microsoftonline.com/common/oauth2/v2.0/logout')
MSALogoutWindow.webContents.on('did-navigate', (e) => {
setTimeout(() => {
ipcEvent.reply('MSALogoutWindowReply')
}, 5000)
})
}
})
// https://github.com/electron/electron/issues/18397
app.allowRendererProcessReuse = true