diff --git a/app/assets/css/launcher.css b/app/assets/css/launcher.css index 570e5b20..1e38c605 100644 --- a/app/assets/css/launcher.css +++ b/app/assets/css/launcher.css @@ -1435,6 +1435,163 @@ input:checked + .toggleSwitchSlider:before { font-family: 'Avenir Medium'; } +/* Main container for File selectors. */ +.settingsServerCodeContainer { + display: flex; + flex-direction: column; + border-bottom: 1px solid rgba(255, 255, 255, 0.50); + margin-bottom: 20px; + margin-top: 20px; + width: 75%; +} + +/* Server Code title. */ +.settingsServerCodeTitle { + margin-bottom: 10px; + font-size: 14px; + font-family: 'Avenir Medium'; +} + +/* Wrapper container for the actionable elements. */ +.settingsServerCodeActions { + display: flex; + width: 60%; +} + +/* Enabled text field which stores the secret code if available. */ +.settingsInputServerCodeVal { + border-radius: 0px !important; + width: 100%; + padding: 5px 10px; + font-size: 12px; +} + +.settingsInputServerCodeButton { + border: 0px; + border-radius: 3px 3px 3px 3px; + font-size: 12px; + padding: 0px 5px; + margin-left: 10px; + cursor: pointer; + background: rgba(126, 126, 126, 0.57); + transition: 0.25s ease; + white-space: nowrap; + outline: none; +} +.settingsInputServerCodeButton:hover, +.settingInputServerCodeButton:focus { + text-shadow: 0px 0px 20px white; +} +.settingsInputServerCodeButton:active { + text-shadow: 0px 0px 20px rgba(255, 255, 255, 0.75); + color: rgba(255, 255, 255, 0.75); +} + +/* Description for the file selector. */ +.settingsServerCodesDesc { + margin: 20px 0px; + color: grey; + font-size: 10px; + width: 90%; +} + + +.settingsServerCodesDesc strong { + font-family: 'Avenir Medium'; +} + +#settingsServerCodesListContent { + font-size: 10px; + background: rgba(0, 0, 0, 0.25); + border-radius: 3px; + color: white; + margin-top: 10px; +} + +.settingsServerCode { + padding: 8px 0px 8px 8px; +} + +/* Main content container for server code element information. */ +.settingsServerCodeContent { + display: flex; + align-items: center; + justify-content: space-between; + transition: opacity 0.25s ease; +} + +/* Wrapper container for the left side of a server code element. */ +.settingsServerCodeMainWrapper { + display: flex; + align-items: center; +} + +.settingsServerCodeRemoveWrapper { + margin-right: 25px; +} + +/* Server code valid/invalid status. */ +.settingsServerCodeStatus { + width: 7px; + height: 7px; + border-radius: 50%; + background-color: #c32625; + margin-right: 15px; + transition: 0.25s ease; +} + +.settingsServerCode[valid] > .settingsServerCodeContent > .settingsServerCodeMainWrapper > .settingsServerCodeStatus { + background-color: #4ddd19; +} + +/* Mod details container. */ +.settingsServerCodeDetails { + display: flex; + flex-direction: column; +} + +.settingsServerCodeName { + display: flex; + flex-direction: column; + font-size: 12px; + font-weight: bold; +} + +.settingsServerCodeServerNamesContent { + max-width: 650px; +} + +.settingsServerCodeServerName { + margin-right: 35px; + font-size: 14px; +} + +.settingsServerCode:not([valid]) > .settingsServerCodeContent > .settingsServerCodeMainWrapper > .settingsServerCodeDetails > .settingsServerCodeServerNamesContent > .settingsServerCodeServerName { + color: red; +} + +/* Button to remove drop-in mods. */ +.settingsServerCodeRemoveButton { + background: none; + border: none; + font-size: 12px; + text-align: right; + padding: 0px; + color: grey; + cursor: pointer; + outline: none; + transition: 0.25s ease; + font-weight: bold; +} + +.settingsServerCodeRemoveButton:hover, +.settingsServerCodeRemoveButton:focus { + color: red; +} +.settingsServerCodeRemoveButton:active { + color: #9b1f1f; +} + /* * * * Settings View (Account Tab) * * */ @@ -1878,15 +2035,16 @@ input:checked + .toggleSwitchSlider:before { /* Mod elements. */ .settingsMod, -.settingsDropinMod { - padding: 10px; -} .settingsSubMod { padding: 10px 0px 10px 15px; margin-left: 20px; border-left: 1px solid rgba(255, 255, 255, 0.5); } +.settingsDropinMod { + padding: 10px; +} + /* Main content container for mod element information. */ .settingsModContent { display: flex; @@ -1931,7 +2089,7 @@ input:checked + .toggleSwitchSlider:before { /* Set the status color of an enabled mod. */ .settingsBaseMod[enabled] > .settingsModContent > .settingsModMainWrapper > .settingsModStatus { - background-color: rgb(165, 195, 37); + background-color: #4ddd19;; } /* Add opacity to submods of a disabled mod. */ diff --git a/app/assets/js/configmanager.js b/app/assets/js/configmanager.js index af035670..7ff28d44 100644 --- a/app/assets/js/configmanager.js +++ b/app/assets/js/configmanager.js @@ -111,7 +111,6 @@ const DEFAULT_CONFIG = { allowPrerelease: false, dataDirectory: dataPath, serverCodes: [] - } }, newsCache: { diff --git a/app/assets/js/distromanager.js b/app/assets/js/distromanager.js index 1cd08478..cb346867 100644 --- a/app/assets/js/distromanager.js +++ b/app/assets/js/distromanager.js @@ -405,6 +405,13 @@ class Server { return this.serverCode } + /** + * @returns {string} The server code for this server + */ + getServerCode(){ + return this.serverCode + } + /** * @returns {boolean} Whether or not the server is autoconnect. * by default. @@ -506,7 +513,6 @@ class DistroIndex { return null } - /** * Get a server configuration by its ID. If it does not * exist, null will be returned. @@ -525,6 +531,15 @@ class DistroIndex { return servs } + getServersFromCode(code){ + let servs = [] + for(let serv of this.servers){ + if(serv.serverCode === code){ + servs.push(serv) + } + } + return servs + } /** * Get the main server. * diff --git a/app/assets/js/scripts/landing.js b/app/assets/js/scripts/landing.js index 8264bb50..b20edeca 100644 --- a/app/assets/js/scripts/landing.js +++ b/app/assets/js/scripts/landing.js @@ -91,7 +91,7 @@ document.getElementById('launch_button').addEventListener('click', function(e){ const jExe = ConfigManager.getJavaExecutable() if(jExe == null){ asyncSystemScan(mcVersion) - }} else { + } else { setLaunchDetails(Lang.queryJS('landing.launch.pleaseWait')) toggleLaunchArea(true) @@ -107,6 +107,7 @@ document.getElementById('launch_button').addEventListener('click', function(e){ } }) } + } }) // Bind settings button document.getElementById('settingsMediaButton').onclick = (e) => { @@ -797,6 +798,39 @@ function dlAsync(login = true){ } } +/** + * Checks the current server to ensure that they still have permission to play it (checking server code, if applicable) and open up an error overlay if specified + * @Param {boolean} whether or not to show the error overlay + */ + function checkCurrentServer(errorOverlay = true){ + const selectedServId = ConfigManager.getSelectedServer() + if(selectedServId){ + const selectedServ = DistroManager.getDistribution().getServer(selectedServId) + if(selectedServ){ + if(selectedServ.getServerCode() && selectedServ.getServerCode() !== ''){ + if(!ConfigManager.getServerCodes().includes(selectedServ.getServerCode())){ + if(errorOverlay){ + setOverlayContent( + 'Current Server Restricted!', + 'It seems that you no longer have the server code required to access this server! Please switch to a different server to play on.

If you feel this is an error, please contact the server administrator', + 'Switch Server' + ) + setOverlayHandler(() => { + toggleServerSelection(true) + }) + setDismissHandler(() => { + toggleOverlay(false) + }) + toggleOverlay(true, true) + } + return false + } + } + } + return true + } +} + /** * News Loading Functions */ diff --git a/app/assets/js/scripts/settings.js b/app/assets/js/scripts/settings.js index 96797bf2..c1b663f9 100644 --- a/app/assets/js/scripts/settings.js +++ b/app/assets/js/scripts/settings.js @@ -137,6 +137,8 @@ function initSettingsValues(){ v.value = gFn() } else if (cVal === 'DataDirectory'){ v.value = gFn() + } else if (cVal === 'ServerCode'){ + v.value = gFn() } else if(cVal === 'JVMOptions'){ v.value = gFn().join(' ') } else if (cVal === 'ServerCode'){ @@ -429,6 +431,44 @@ ipcRenderer.on(MSFT_OPCODE.REPLY_LOGIN, (_, ...arguments_) => { } }) +/** + * Binds the functionality within the server codes section of the launcher settings + */ + function bindServerCodeButtons(){ + // Sets up the onclick listeners for the button to add codes + document.getElementById('settingsAddServerCode').onclick = () => { + for(let ele of document.getElementsByClassName('settingsInputServerCodeVal')){ + const code = ele.value + ele.value = '' + if(!ConfigManager.getServerCodes().includes(code) && code){ + ConfigManager.getServerCodes().push(code) + ConfigManager.save() + loggerSettings.log('Added server code to configuration and saved it') + prepareLauncherTab() + } else { + loggerSettings.log('Server code already exists or is empty, not adding.') + } + } + } + + // Sets up the onclick listeners for each remove code buttons + const sEls = document.querySelectorAll('[remcode]') + Array.from(sEls).map((v, index, arr) => { + v.onclick = () => { + if(v.hasAttribute('remcode')){ + const code = v.getAttribute('remcode') + if(ConfigManager.getServerCodes().includes(code)){ + ConfigManager.getServerCodes().splice(ConfigManager.getServerCodes().indexOf(code), 1) + ConfigManager.save() + loggerSettings.log('Added removed code from configuration and saved it') + prepareLauncherTab() + } + } + loggerSettings.log('Server code doesnt exist!, not removing.') + } + }) +} + /** * Bind functionality for the account selection buttons. If another account * is selected, the UI of the previously selected account will be updated. @@ -668,6 +708,14 @@ function prepareAccountsTab() { bindAuthAccountLogOut() } +/** + * Prepare the launcher tab for display. + */ + function prepareLauncherTab() { + resolveServerCodesForUI() + bindServerCodeButtons() +} + /** * Minecraft Tab */ @@ -870,6 +918,60 @@ function resolveDropinModsForUI(){ document.getElementById('settingsDropinModsContent').innerHTML = dropinMods } +function resolveServerCodesForUI(){ + /* Server Codes */ + let servCodes = '' + for(let servCode of ConfigManager.getServerCodes()){ + const servs = DistroManager.getDistribution().getServersFromCode(servCode) + const valid = servs && servs.length + servCodes += + ` +
+
+
+
+
+ ${servCode} +
+
+
+
+
+ +
+
+
+ ` + } + + document.getElementById('settingsServerCodesListContent').innerHTML = servCodes + + /* Server Names List */ + for(let ele of document.getElementsByClassName('settingsServerCodeServerNamesContent')){ + servNames = '' + const code = ele.getAttribute('code') + const servs = DistroManager.getDistribution().getServersFromCode(code) + const valid = servs && servs.length + loggerSettings.log('valid: ' + valid) + if(valid){ + for(let serv of servs){ + loggerSettings.log('server: ' + serv.getName()) + servNames += + ` + ${serv.getName()} + ` + } + } else { + servNames = + ` + Invalid Code + ` + } + + ele.innerHTML = servNames + } +} + /** * Bind the remove button for each loaded drop-in mod. */ @@ -1532,6 +1634,7 @@ function prepareSettings(first = false) { initSettingsValues() prepareAccountsTab() prepareJavaTab() + prepareLauncherTab() prepareAboutTab() } diff --git a/app/settings.ejs b/app/settings.ejs index ed4cd2ac..da409925 100644 --- a/app/settings.ejs +++ b/app/settings.ejs @@ -295,6 +295,19 @@
All game files and local Java installations will be stored in the data directory.
Screenshots and world saves are stored in the instance folder for the corresponding server configuration.
+
+
Your Server Codes
+
+
+ + +
+
+
+ +
+
Specify server codes here to grant access to hidden servers that wouldn't be available to all users by default.
+