소스 검색

Initial work on shader options, electron@4.

Daniel Scalzi 7 년 전
부모
커밋
a4d4b69791
7개의 변경된 파일243개의 추가작업 그리고 14개의 파일을 삭제
  1. 71 0
      app/assets/css/launcher.css
  2. 82 6
      app/assets/js/dropinmodutil.js
  3. 75 1
      app/assets/js/scripts/settings.js
  4. 8 2
      app/settings.ejs
  5. 3 1
      index.js
  6. 3 3
      package-lock.json
  7. 1 1
      package.json

+ 71 - 0
app/assets/css/launcher.css

@@ -1578,6 +1578,77 @@ input:checked + .toggleSwitchSlider:before {
     text-shadow: 0px 0px 20px #9b1f1f, 0px 0px 20px #9b1f1f, 0px 0px 20px #9b1f1f;
 }
 
+/* Main select container. */
+.settingsSelectContainer {
+    position: relative;
+    width: 50%;
+}
+
+/* Div which displays the selected option. */
+.settingsSelectSelected {
+    border-radius: 3px;
+    border-width: 1px;
+    font-size: 14px;
+    padding: 6px 16px;
+}
+
+/* Style the arrow inside the select element. */
+.settingsSelectSelected:after {
+    position: absolute;
+    content: "";
+    top: calc(50% - 3px);
+    right: 10px;
+    width: 0;
+    height: 0;
+    border: 6px solid transparent;
+    border-color: rgba(126, 126, 126, 0.57) transparent transparent transparent;
+}
+
+/* Point the arrow upwards when the select box is open (active). */
+.settingsSelectSelected.select-arrow-active:after {
+    border-color: transparent transparent rgba(126, 126, 126, 0.57) transparent;
+    top: 7px;
+}
+.settingsSelectSelected.select-arrow-active {
+    border-radius: 3px 3px 0px 0px;
+}
+
+/* Options content container. */
+.settingsSelectOptions {
+    position: absolute;
+    top: 100%;
+    left: 0;
+    right: 0;
+    z-index: 99;
+}
+/* Hide the items when the select box is closed. */
+.settingsSelectOptions[hidden] {
+    display: none;
+}
+
+/* Shared styles between options and selection div. */
+.settingsSelectOptions div,
+.settingsSelectSelected {
+    background: rgba(0, 0, 0, 0.25);
+    border-style: solid;
+    border-color: rgba(126, 126, 126, 0.57);
+    color: #ffffff;
+    cursor: pointer;
+}
+.settingsSelectOptions div {
+    border-width: 0px 1px 1px 1px;
+    font-size: 12px;
+    padding: 4px 16px;
+}
+.settingsSelectOptions .settingsSelectOption:last-child {
+    border-radius: 0px 0px 3px 3px;
+}
+
+/* Hover + selected styles. */
+.settingsSelectOptions div:hover, .settingsSelectOptions div[selected] {
+    background-color: rgba(255, 255, 255, 0.25) !important;
+}
+
 /* * *
 * Settings View (Java Tab)
 * * */

+ 82 - 6
app/assets/js/dropinmodutil.js

@@ -8,14 +8,17 @@ const { shell } = require('electron')
 const MOD_REGEX = /^(.+(jar|zip|litemod))(?:\.(disabled))?$/
 const DISABLED_EXT = '.disabled'
 
+const SHADER_REGEX = /^(.+)\.zip$/
+const SHADER_OPTION = /shaderPack=(.+)/
+
 /**
- * Validate that the given mods directory exists. If not,
- * it is created.
+ * Validate that the given directory exists. If not, it is
+ * created.
  * 
  * @param {string} modsDir The path to the mods directory.
  */
-exports.validateModsDir = function(modsDir) {
-    fs.ensureDirSync(modsDir)
+exports.validateDir = function(dir) {
+    fs.ensureDirSync(dir)
 }
 
 /**
@@ -71,7 +74,7 @@ exports.scanForDropinMods = function(modsDir, version) {
  */
 exports.addDropinMods = function(files, modsdir) {
 
-    exports.validateModsDir(modsdir)
+    exports.validateDir(modsdir)
 
     for(let f of files) {
         if(MOD_REGEX.exec(f.name) != null) {
@@ -131,4 +134,77 @@ exports.toggleDropinMod = function(modsDir, fullName, enable){
  */
 exports.isDropinModEnabled = function(fullName){
     return !fullName.endsWith(DISABLED_EXT)
-}
+}
+
+/**
+ * Scan for shaderpacks inside the shaderpacks folder.
+ * 
+ * @param {string} instanceDir The path to the server instance directory.
+ * 
+ * @returns {{fullName: string, name: string}[]}
+ * An array of objects storing metadata about each discovered shaderpack.
+ */
+exports.scanForShaderpacks = function(instanceDir){
+    const shaderDir = path.join(instanceDir, 'shaderpacks')
+    const packsDiscovered = [{
+        fullName: 'OFF',
+        name: 'No Shaderpack'
+    }]
+    if(fs.existsSync(shaderDir)){
+        let modCandidates = fs.readdirSync(shaderDir)
+        for(let file of modCandidates){
+            const match = SHADER_REGEX.exec(file)
+            if(match != null){
+                packsDiscovered.push({
+                    fullName: match[0],
+                    name: match[1]
+                })
+            }
+        }
+    }
+    return packsDiscovered
+}
+
+/**
+ * Read the optionsshaders.txt file to locate the current
+ * enabled pack. If the file does not exist, OFF is returned.
+ * 
+ * @param {string} instanceDir The path to the server instance directory.
+ * 
+ * @returns {string} The file name of the enabled shaderpack.
+ */
+exports.getEnabledShaderpack = function(instanceDir){
+    exports.validateDir(instanceDir)
+
+    const optionsShaders = path.join(instanceDir, 'optionsshaders.txt')
+    if(fs.existsSync(optionsShaders)){
+        const buf = fs.readFileSync(optionsShaders, {encoding: 'utf-8'})
+        const match = SHADER_OPTION.exec(buf)
+        if(match != null){
+            return match[1]
+        } else {
+            console.warn('WARNING: Shaderpack regex failed.')
+        }
+    }
+    return 'OFF'
+}
+
+/**
+ * Set the enabled shaderpack.
+ * 
+ * @param {string} instanceDir The path to the server instance directory.
+ * @param {string} pack the file name of the shaderpack.
+ */
+exports.setEnabledShaderpack = function(instanceDir, pack){
+    exports.validateDir(instanceDir)
+
+    const optionsShaders = path.join(instanceDir, 'optionsshaders.txt')
+    let buf
+    if(fs.existsSync(optionsShaders)){
+        buf = fs.readFileSync(optionsShaders, {encoding: 'utf-8'})
+        buf = buf.replace(SHADER_OPTION, `shaderPack=${pack}`)
+    } else {
+        buf = `shaderPack=${pack}`
+    }
+    fs.writeFileSync(optionsShaders, buf, {encoding: 'utf-8'})
+}

+ 75 - 1
app/assets/js/scripts/settings.js

@@ -9,6 +9,38 @@ const settingsState = {
     invalid: new Set()
 }
 
+function bindSettingsSelect(){
+    for(let ele of document.getElementsByClassName('settingsSelectContainer')) {
+        const selectedDiv = ele.getElementsByClassName('settingsSelectSelected')[0]
+
+        selectedDiv.onclick = (e) => {
+            e.stopPropagation()
+            closeSettingsSelect(e.target)
+            e.target.nextElementSibling.toggleAttribute('hidden')
+            e.target.classList.toggle('select-arrow-active')
+        }
+    }
+}
+
+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)) {
+            selectedDiv.classList.remove('select-arrow-active')
+            optionsDiv.setAttribute('hidden', '')
+        }
+    }
+}
+
+/* If the user clicks anywhere outside the select box,
+then close all select boxes: */
+document.addEventListener('click', closeSettingsSelect)
+
+bindSettingsSelect()
+
+
 /**
  * General Settings Functions
  */
@@ -640,7 +672,7 @@ function bindDropinModsRemoveButton(){
 function bindDropinModFileSystemButton(){
     const fsBtn = document.getElementById('settingsDropinFileSystemButton')
     fsBtn.onclick = () => {
-        DropinModUtil.validateModsDir(CACHE_SETTINGS_MODS_DIR)
+        DropinModUtil.validateDir(CACHE_SETTINGS_MODS_DIR)
         shell.openItem(CACHE_SETTINGS_MODS_DIR)
     }
     fsBtn.ondragenter = e => {
@@ -707,6 +739,47 @@ function reloadDropinMods(){
     bindModsToggleSwitch()
 }
 
+// Shaderpack
+
+let CACHE_SETTINGS_INSTANCE_DIR
+let CACHE_SHADERPACKS
+let CACHE_SELECTED_SHADERPACK
+
+/**
+ * Load shaderpack information.
+ */
+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)
+    CACHE_SELECTED_SHADERPACK = DropinModUtil.getEnabledShaderpack(CACHE_SETTINGS_INSTANCE_DIR)
+
+    setShadersOptions(CACHE_SHADERPACKS, CACHE_SELECTED_SHADERPACK)
+}
+
+function setShadersOptions(arr, selected){
+    const cont = document.getElementById('settingsShadersOptions')
+    cont.innerHTML = ''
+    for(let opt of arr) {
+        const d = document.createElement('DIV')
+        d.innerHTML = opt.name
+        d.setAttribute('value', opt.fullName)
+        if(opt.fullName === selected) {
+            d.setAttribute('selected', '')
+            document.getElementById('settingsShadersSelected').innerHTML = opt.name
+        }
+        d.addEventListener('click', function(e) {
+            this.parentNode.previousElementSibling.innerHTML = this.innerHTML
+            for(let sib of this.parentNode.children){
+                sib.removeAttribute('selected')
+            }
+            this.setAttribute('selected', '')
+            closeSettingsSelect()
+        })
+        cont.appendChild(d)
+    }
+}
+
 // Server status bar functions.
 
 /**
@@ -770,6 +843,7 @@ function animateModsTabRefresh(){
 function prepareModsTab(first){
     resolveModsForUI()
     resolveDropinModsForUI()
+    resolveShaderpacksForUI()
     bindDropinModsRemoveButton()
     bindDropinModFileSystemButton()
     bindModsToggleSwitch()

+ 8 - 2
app/settings.ejs

@@ -126,9 +126,15 @@
                         
                     </div>
                 </div>
-                <!--<div id="settingsShadersContainer">
+                <div id="settingsShadersContainer">
                     <div class="settingsModsHeader">Shaderpacks</div>
-                </div>-->
+                    <div class="settingsSelectContainer">
+                        <div class="settingsSelectSelected" id="settingsShadersSelected">Select Shaderpack</div>
+                        <div class="settingsSelectOptions" id="settingsShadersOptions" hidden>
+
+                        </div>
+                    </div>
+                </div>
             </div>
         </div>
         <div id="settingsTabJava" class="settingsTab" style="display: none;">

+ 3 - 1
index.js

@@ -98,7 +98,9 @@ function createWindow() {
         icon: getPlatformIcon('WesterosSealSquare'),
         frame: false,
         webPreferences: {
-            preload: path.join(__dirname, 'app', 'assets', 'js', 'preloader.js')
+            preload: path.join(__dirname, 'app', 'assets', 'js', 'preloader.js'),
+            nodeIntegration: true,
+            contextIsolation: false
         },
         backgroundColor: '#171614'
     })

+ 3 - 3
package-lock.json

@@ -908,9 +908,9 @@
       }
     },
     "electron": {
-      "version": "3.0.13",
-      "resolved": "https://registry.npmjs.org/electron/-/electron-3.0.13.tgz",
-      "integrity": "sha512-tfx5jFgXhCmpe6oPjcesaRj7geHqQxrJdbpseanRzL9BbyYUtsj0HoxwPAUvCx4+52P6XryBwWTvne/1eBVf9Q==",
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/electron/-/electron-4.0.0.tgz",
+      "integrity": "sha512-3XPG/3IXlvnT1oe1K6zEushoD0SKbP8xwdrL10EWGe6k2iOV4hSHqJ8vWnR8yZ7VbSXmBRfomEFDNAo/q/cwKw==",
       "dev": true,
       "requires": {
         "@types/node": "^8.0.24",

+ 1 - 1
package.json

@@ -41,7 +41,7 @@
   },
   "devDependencies": {
     "cross-env": "^5.2.0",
-    "electron": "^3.0.13",
+    "electron": "^4.0.0",
     "electron-builder": "^20.38.4",
     "eslint": "^5.10.0"
   },