mirror of
				https://github.com/OpenFusionProject/Client.git
				synced 2025-10-31 03:10:11 +00:00 
			
		
		
		
	Compare commits
	
		
			15 Commits
		
	
	
		
			d52e149192
			...
			main
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 1117c9bd68 | ||
|   | bd27433535 | ||
|   | 72ea6bdaca | ||
|   | d4a1ecebc7 | ||
|   | 323b5a3385 | ||
|   | c898cacd7c | ||
|   | e5b20f57ce | ||
|   | 1eee35b230 | ||
|   | d8363b61a6 | ||
|   | 6239f383bc | ||
|   | 19e036ddf9 | ||
| 4503c9268e | |||
| 947c231b12 | |||
| 37699e38f8 | |||
|   | 451cb4a2af | 
							
								
								
									
										76
									
								
								.github/workflows/build.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										76
									
								
								.github/workflows/build.yml
									
									
									
									
										vendored
									
									
								
							| @@ -1,47 +1,47 @@ | ||||
| name: Publish Build | ||||
|  | ||||
| on: | ||||
|   push: | ||||
|     branches: [ "main" ] | ||||
|     tags: '*' | ||||
|     push: | ||||
|         branches: ["main"] | ||||
|         tags: "*" | ||||
|  | ||||
| permissions: | ||||
|   contents: write | ||||
|     contents: write | ||||
|  | ||||
| jobs: | ||||
|   build: | ||||
|     runs-on: windows-2022 | ||||
|     build: | ||||
|         runs-on: windows-2022 | ||||
|  | ||||
|     steps: | ||||
|     - uses: actions/checkout@v4 | ||||
|       with: | ||||
|         fetch-depth: 0 | ||||
|     - name: Set up Node.js 20.x | ||||
|       uses: actions/setup-node@v4 | ||||
|       with: | ||||
|         node-version: 20.x | ||||
|         cache: 'npm' | ||||
|     - name: Install dependencies | ||||
|       run: npm install | ||||
|     - name: Pack into zip and create installer | ||||
|       run: npm run dist | ||||
|     - name: Upload Artifacts | ||||
|       uses: actions/upload-artifact@master | ||||
|       with: | ||||
|         path: dist | ||||
|         steps: | ||||
|             - uses: actions/checkout@v4 | ||||
|               with: | ||||
|                   fetch-depth: 0 | ||||
|             - name: Set up Node.js 20.x | ||||
|               uses: actions/setup-node@v4 | ||||
|               with: | ||||
|                   node-version: 20.x | ||||
|                   cache: "npm" | ||||
|             - name: Install dependencies | ||||
|               run: npm install | ||||
|             - name: Pack into zip and create installer | ||||
|               run: npm run dist | ||||
|             - name: Upload Artifacts | ||||
|               uses: actions/upload-artifact@master | ||||
|               with: | ||||
|                   path: dist | ||||
|  | ||||
|   publish-release: | ||||
|     if: contains(github.ref, 'refs/tags/') | ||||
|     runs-on: ubuntu-latest | ||||
|     needs: build | ||||
|      | ||||
|     steps: | ||||
|     - name: Download artifact | ||||
|       uses: actions/download-artifact@master | ||||
|     - name: Create release | ||||
|       uses: ncipollo/release-action@v1 | ||||
|       with: | ||||
|         artifacts: "artifact/*-ia32-win.zip,artifact/*.exe" | ||||
|       env: | ||||
|         GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||||
|         GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||||
|     publish-release: | ||||
|         if: contains(github.ref, 'refs/tags/') | ||||
|         runs-on: ubuntu-latest | ||||
|         needs: build | ||||
|  | ||||
|         steps: | ||||
|             - name: Download artifact | ||||
|               uses: actions/download-artifact@master | ||||
|             - name: Create release | ||||
|               uses: ncipollo/release-action@v1 | ||||
|               with: | ||||
|                   artifacts: "artifact/*-ia32-win.zip,artifact/*.exe" | ||||
|               env: | ||||
|                   GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||||
|                   GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||||
|   | ||||
							
								
								
									
										3
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| { | ||||
|     "editor.formatOnSave": true | ||||
| } | ||||
| @@ -59,12 +59,24 @@ body { | ||||
|         "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; | ||||
| } | ||||
|  | ||||
| #of-versionnumberdiv { | ||||
| #of-about-button-div { | ||||
|     position: fixed; | ||||
|     bottom: 4px; | ||||
|     right: 8px; | ||||
| } | ||||
|  | ||||
| #of-about-flash-div { | ||||
|     position: fixed; | ||||
|     bottom: 4px; | ||||
|     right: 8px; | ||||
| } | ||||
|  | ||||
| #of-config-button-div { | ||||
|     position: fixed; | ||||
|     bottom: 4px; | ||||
|     left: 8px; | ||||
| } | ||||
|  | ||||
| .btn-primary { | ||||
|     background-image: url("../../assets/img/btn-primary-bg.png"); | ||||
|     background-repeat: repeat; | ||||
| @@ -85,6 +97,18 @@ body { | ||||
|     background-repeat: repeat; | ||||
| } | ||||
|  | ||||
| .form-check-input { | ||||
|     width: 25px; | ||||
|     height: 25px; | ||||
| } | ||||
|  | ||||
| .form-check-label { | ||||
|     height: 25px; | ||||
|     margin-top: 5px; | ||||
|     margin-left: 10px; | ||||
|     font-size: 1rem; | ||||
| } | ||||
|  | ||||
| #of-aboutmodal > .modal-dialog > .modal-content { | ||||
|     background-color: #093363; | ||||
|     border-color: #6699ff; | ||||
| @@ -186,3 +210,19 @@ button > i { | ||||
|     background: #000; | ||||
|     clear: both; | ||||
| } | ||||
|  | ||||
| @keyframes pulse { | ||||
|     0% { | ||||
|         opacity: 1; | ||||
|     } | ||||
|     50% { | ||||
|         opacity: 0; | ||||
|     } | ||||
|     100% { | ||||
|         opacity: 1; | ||||
|     } | ||||
| } | ||||
|  | ||||
| .pulsing { | ||||
|     animation: pulse 2s infinite; | ||||
| } | ||||
|   | ||||
| @@ -10,11 +10,8 @@ var userData = remote.require("app").getPath("userData"); | ||||
| var configPath = path.join(userData, "config.json"); | ||||
| var serversPath = path.join(userData, "servers.json"); | ||||
| var versionsPath = path.join(userData, "versions.json"); | ||||
| var cacheRoot = path.join( | ||||
|     userData, | ||||
|     "/../../LocalLow/Unity/Web Player/Cache" | ||||
| ); | ||||
| var offlineRootDefault = path.join(cacheRoot, "Offline"); | ||||
| var cacheRoot = path.join(userData, "/../../LocalLow/Unity/Web Player/Cache"); | ||||
| var offlineRootDefault = path.join(cacheRoot, "../OfflineCache"); | ||||
| var offlineRoot = offlineRootDefault; | ||||
|  | ||||
| var cdnString = "http://cdn.dexlabs.systems/ff/big"; | ||||
| @@ -81,7 +78,36 @@ function getAppVersion() { | ||||
|  | ||||
| function setAppVersionText() { | ||||
|     $("#of-aboutversionnumber").text("Version " + getAppVersion()); | ||||
|     $("#of-versionnumber").text("v" + getAppVersion()); | ||||
| } | ||||
|  | ||||
| function checkForNewAppVersion() { | ||||
|     $("#of-about-button").removeClass("pulsing"); | ||||
|     setAppVersionText(); | ||||
|     if (config["autoupdate-check"] === true) { | ||||
|         $.getJSON( | ||||
|             "https://api.github.com/repos/OpenFusionProject/OpenFusionClient/releases/latest", | ||||
|             {}, | ||||
|             function (data) { | ||||
|                 $.each(data, function (index, element) { | ||||
|                     if (index === "tag_name" && element != remote.require("app").getVersion()) { | ||||
|                         console.log("New version available: " + element); | ||||
|                         var downloadPage = | ||||
|                             "https://github.com/OpenFusionProject/OpenFusionClient/releases/latest"; | ||||
|                         $("#of-aboutversionnumber").html( | ||||
|                             "Version " + | ||||
|                                 getAppVersion() + | ||||
|                                 `<br>A new version is available! ` + | ||||
|                                 `Click <a href="#" onclick='remote.require("shell").openExternal("` + | ||||
|                                 downloadPage + | ||||
|                                 `");'>here</a> to download.` | ||||
|                         ); | ||||
|                         $("#of-about-button").addClass("pulsing"); | ||||
|                         return false; // break out of loop early | ||||
|                     } | ||||
|                 }); | ||||
|             } | ||||
|         ); | ||||
|     } | ||||
| } | ||||
|  | ||||
| function validateServerSave(modalName) { | ||||
| @@ -95,14 +121,15 @@ function validateServerSave(modalName) { | ||||
|     ipInput.classList.remove("invalidinput"); | ||||
|  | ||||
|     if ( | ||||
|         descInput.value.length < parseInt(descInput.getAttribute("minlength")) || | ||||
|         descInput.value.length < | ||||
|             parseInt(descInput.getAttribute("minlength")) || | ||||
|         descInput.value.length > parseInt(descInput.getAttribute("maxlength")) | ||||
|     ) { | ||||
|         descInput.classList.add("invalidinput"); | ||||
|         valid = false; | ||||
|     } | ||||
|  | ||||
|     if (!(new RegExp(ipInput.getAttribute("pattern"))).test(ipInput.value)) { | ||||
|     if (!new RegExp(ipInput.getAttribute("pattern")).test(ipInput.value)) { | ||||
|         ipInput.classList.add("invalidinput"); | ||||
|         valid = false; | ||||
|     } | ||||
| @@ -193,17 +220,17 @@ function validateVersionSave(modalName) { | ||||
|     var matchingVersions = versionArray.filter(function (obj) { | ||||
|         return obj.name === nameInput.value; | ||||
|     }); | ||||
|     var allowedMatches = (modalName === "edit") ? 1 : 0; | ||||
|     var allowedMatches = modalName === "edit" ? 1 : 0; | ||||
|  | ||||
|     if ( | ||||
|         matchingVersions.length > allowedMatches || | ||||
|         !(new RegExp(nameInput.getAttribute("pattern"))).test(nameInput.value) | ||||
|         !new RegExp(nameInput.getAttribute("pattern")).test(nameInput.value) | ||||
|     ) { | ||||
|         nameInput.classList.add("invalidinput"); | ||||
|         valid = false; | ||||
|     } | ||||
|  | ||||
|     if (!(new RegExp(urlInput.getAttribute("pattern"))).test(urlInput.value)) { | ||||
|     if (!new RegExp(urlInput.getAttribute("pattern")).test(urlInput.value)) { | ||||
|         urlInput.classList.add("invalidinput"); | ||||
|         valid = false; | ||||
|     } | ||||
| @@ -246,7 +273,10 @@ function editVersion() { | ||||
|     var editedVersionString = null; | ||||
|  | ||||
|     $.each(jsonToModify["versions"], function (key, value) { | ||||
|         if (value["name"] == getSelectedVersion() && !defaultHashes.hasOwnProperty(value["name"])) { | ||||
|         if ( | ||||
|             value["name"] == getSelectedVersion() && | ||||
|             !defaultHashes.hasOwnProperty(value["name"]) | ||||
|         ) { | ||||
|             value["name"] = | ||||
|                 $("#editversion-nameinput").val().length == 0 | ||||
|                     ? value["name"] | ||||
| @@ -296,18 +326,27 @@ function restoreDefaultVersions() { | ||||
| function editConfig() { | ||||
|     var jsonToModify = JSON.parse(remotefs.readFileSync(configPath)); | ||||
|  | ||||
|     jsonToModify["autoupdate-check"] = $("#editconfig-autoupdate").prop("checked"); | ||||
|     jsonToModify["cache-swapping"] = $("#editconfig-cacheswapping").prop("checked"); | ||||
|     jsonToModify["enable-offline-cache"] = $("#editconfig-enableofflinecache").prop("checked"); | ||||
|     jsonToModify["verify-offline-cache"] = $("#editconfig-verifyofflinecache").prop("checked"); | ||||
|     jsonToModify["autoupdate-check"] = $("#editconfig-autoupdate").prop( | ||||
|         "checked" | ||||
|     ); | ||||
|     jsonToModify["cache-swapping"] = $("#editconfig-cacheswapping").prop( | ||||
|         "checked" | ||||
|     ); | ||||
|     jsonToModify["enable-offline-cache"] = $( | ||||
|         "#editconfig-enableofflinecache" | ||||
|     ).prop("checked"); | ||||
|     jsonToModify["verify-offline-cache"] = $( | ||||
|         "#editconfig-verifyofflinecache" | ||||
|     ).prop("checked"); | ||||
|  | ||||
|     var dirInput = $("#editconfig-offlinecachelocation:text").val(); | ||||
|     var shouldChangeRoot = ( | ||||
|     var shouldChangeRoot = | ||||
|         remotefs.existsSync(dirInput) && | ||||
|         remotefs.statSync(dirInput).isDirectory() | ||||
|     ); | ||||
|         remotefs.statSync(dirInput).isDirectory(); | ||||
|  | ||||
|     jsonToModify["offline-cache-location"] = shouldChangeRoot ? dirInput : offlineRoot; | ||||
|     jsonToModify["offline-cache-location"] = shouldChangeRoot | ||||
|         ? dirInput | ||||
|         : offlineRoot; | ||||
|  | ||||
|     remotefs.writeFileSync(configPath, JSON.stringify(jsonToModify, null, 4)); | ||||
|  | ||||
| @@ -319,11 +358,23 @@ function editConfig() { | ||||
| function validateCacheLocation() { | ||||
|     var input = document.getElementById("editconfig-offlinecachelocation"); | ||||
|     var button = document.getElementById("editconfig-savebutton"); | ||||
|     var parent = path.join(input.value, "/.."); | ||||
|  | ||||
|     input.classList.remove("invalidinput"); | ||||
|     button.removeAttribute("disabled"); | ||||
|  | ||||
|     if (!remotefs.existsSync(input.value) || !remotefs.statSync(input.value).isDirectory()) { | ||||
|     // Parent MUST exist and be a directory | ||||
|     // If the target exists, check that is also a directory | ||||
|     // Also, prevent putting the offline cache inside of | ||||
|     // the normal cache folder to prevent shenanigans | ||||
|     if ( | ||||
|         !remotefs.existsSync(parent) || | ||||
|         !remotefs.statSync(parent).isDirectory() || | ||||
|         (remotefs.existsSync(input.value) && | ||||
|             !remotefs.statSync(input.value).isDirectory()) || | ||||
|         path.join(input.value, ".") === path.join(cacheRoot, "/..") || | ||||
|         path.join(input.value, ".").startsWith(path.join(cacheRoot)) | ||||
|     ) { | ||||
|         input.classList.add("invalidinput"); | ||||
|         button.setAttribute("disabled", ""); | ||||
|     } | ||||
| @@ -348,13 +399,20 @@ function loadConfig() { | ||||
|  | ||||
|     $("#editconfig-autoupdate").prop("checked", config["autoupdate-check"]); | ||||
|     $("#editconfig-cacheswapping").prop("checked", config["cache-swapping"]); | ||||
|     $("#editconfig-enableofflinecache").prop("checked", config["enable-offline-cache"]); | ||||
|     $("#editconfig-verifyofflinecache").prop("checked", config["verify-offline-cache"]); | ||||
|     $("#editconfig-enableofflinecache").prop( | ||||
|         "checked", | ||||
|         config["enable-offline-cache"] | ||||
|     ); | ||||
|     $("#editconfig-verifyofflinecache").prop( | ||||
|         "checked", | ||||
|         config["verify-offline-cache"] | ||||
|     ); | ||||
|  | ||||
|     // alter offline root globally | ||||
|     offlineRoot = config["offline-cache-location"] || offlineRootDefault; | ||||
|     $("#editconfig-offlinecachelocation:text").val(offlineRoot); | ||||
|  | ||||
|     checkForNewAppVersion(); | ||||
|     validateCacheLocation(); | ||||
| } | ||||
|  | ||||
| @@ -395,10 +453,9 @@ function loadCacheList() { | ||||
|  | ||||
|     // load default hashes.json for reference while running the cache handler | ||||
|     if (!defaultHashes) { | ||||
|         defaultHashes = remotefs.readJsonSync(path.join( | ||||
|             __dirname, | ||||
|             "/defaults/hashes.json" | ||||
|         )); | ||||
|         defaultHashes = remotefs.readJsonSync( | ||||
|             path.join(__dirname, "/defaults/hashes.json") | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     deselectVersion(); // Remove selection and disable buttons until another server is selected | ||||
| @@ -406,7 +463,7 @@ function loadCacheList() { | ||||
|  | ||||
|     $.each(versionArray, function (key, value) { | ||||
|         var row = document.createElement("tr"); | ||||
|         row.className = "cache-listing-entry" | ||||
|         row.className = "cache-listing-entry"; | ||||
|         row.setAttribute("id", value.name); | ||||
|  | ||||
|         var cellVersion = document.createElement("td"); | ||||
| @@ -430,24 +487,34 @@ function loadCacheList() { | ||||
| } | ||||
|  | ||||
| function getCacheElemID(versionString, cacheMode, elementName) { | ||||
|     return [versionString, cacheMode, "cache", elementName].filter(function (value) { | ||||
|         return typeof value !== "undefined"; | ||||
|     }).join("-"); | ||||
|     return [versionString, cacheMode, "cache", elementName] | ||||
|         .filter(function (value) { | ||||
|             return typeof value !== "undefined"; | ||||
|         }) | ||||
|         .join("-"); | ||||
| } | ||||
|  | ||||
| function getCacheButtonID(versionString, cacheMode, buttonMode) { | ||||
|     return [getCacheElemID(versionString, cacheMode), buttonMode, "button"].join("-"); | ||||
|     return [ | ||||
|         getCacheElemID(versionString, cacheMode), | ||||
|         buttonMode, | ||||
|         "button", | ||||
|     ].join("-"); | ||||
| } | ||||
|  | ||||
| function getCacheLabelText(sizes) { | ||||
|     if (!sizes || sizes.total === 0) | ||||
|         return "?.?? GB / ?.?? GB"; | ||||
|     if (!sizes || sizes.total === 0) return "?.?? GB / ?.?? GB"; | ||||
|  | ||||
|     var gb = 1 << 30; | ||||
|     var labelText = (sizes.intact / gb).toFixed(2) + " / " + (sizes.total / gb).toFixed(2) + " GB"; | ||||
|     var labelText = | ||||
|         (sizes.intact / gb).toFixed(2) + | ||||
|         " / " + | ||||
|         (sizes.total / gb).toFixed(2) + | ||||
|         " GB"; | ||||
|  | ||||
|     if (sizes.altered > 0) { | ||||
|         labelText += "<br/>(" + (sizes.altered / gb).toFixed(2) + " GB Altered)"; | ||||
|         labelText += | ||||
|             "<br/>(" + (sizes.altered / gb).toFixed(2) + " GB Altered)"; | ||||
|     } | ||||
|  | ||||
|     return labelText; | ||||
| @@ -461,18 +528,18 @@ function getCacheInfoCell(versionString, cacheMode) { | ||||
|         download: { | ||||
|             icon: "fas fa-download", | ||||
|             class: "btn btn-success mr-1", | ||||
|             tooltip: "Download Cache" | ||||
|             tooltip: "Download Cache", | ||||
|         }, | ||||
|         fix: { | ||||
|             icon: "fas fa-hammer", | ||||
|             class: "btn btn-warning mr-1", | ||||
|             tooltip: "Fix Altered Files in Cache" | ||||
|             tooltip: "Fix Altered Files in Cache", | ||||
|         }, | ||||
|         delete: { | ||||
|             icon: "fas fa-trash-alt", | ||||
|             class: "btn btn-danger mr-1", | ||||
|             tooltip: "Delete Cache" | ||||
|         } | ||||
|             tooltip: "Delete Cache", | ||||
|         }, | ||||
|     }; | ||||
|  | ||||
|     var cellCache = document.createElement("td"); | ||||
| @@ -483,9 +550,9 @@ function getCacheInfoCell(versionString, cacheMode) { | ||||
|     labelCache.setAttribute("for", divID); | ||||
|     // pull existing info from cacheSizes when available | ||||
|     labelCache.innerHTML = getCacheLabelText( | ||||
|         (cacheSizes && cacheSizes[versionString]) ? | ||||
|         cacheSizes[versionString][cacheMode] : | ||||
|         null | ||||
|         cacheSizes && cacheSizes[versionString] | ||||
|             ? cacheSizes[versionString][cacheMode] | ||||
|             : null | ||||
|     ); | ||||
|  | ||||
|     var divCacheButtons = document.createElement("div"); | ||||
| @@ -508,7 +575,16 @@ function getCacheInfoCell(versionString, cacheMode) { | ||||
|         buttonCache.setAttribute("title", config.tooltip); | ||||
|         buttonCache.setAttribute("type", "button"); | ||||
|         // handler setup | ||||
|         buttonCache.setAttribute("onclick", "handleCache(\"" + buttonMode + "\", \"" + versionString + "\", \"" + cacheMode + "\");"); | ||||
|         buttonCache.setAttribute( | ||||
|             "onclick", | ||||
|             'handleCache("' + | ||||
|                 buttonMode + | ||||
|                 '", "' + | ||||
|                 versionString + | ||||
|                 '", "' + | ||||
|                 cacheMode + | ||||
|                 '");' | ||||
|         ); | ||||
|         buttonCache.appendChild(iconItalic); | ||||
|  | ||||
|         divCacheButtons.appendChild(buttonCache); | ||||
| @@ -526,13 +602,12 @@ function storageLoadingStart(vString, cMode) { | ||||
|     var versionStrings = []; | ||||
|     $.each(versionArray, function (key, value) { | ||||
|         if (vString) { | ||||
|             if (vString === value.name) | ||||
|                 versionStrings.push(value.name); | ||||
|             if (vString === value.name) versionStrings.push(value.name); | ||||
|         } else { | ||||
|             versionStrings.push(value.name); | ||||
|         } | ||||
|     }); | ||||
|     var cacheModes = (cMode) ? [cMode] : ["offline", "playable"]; | ||||
|     var cacheModes = cMode ? [cMode] : ["offline", "playable"]; | ||||
|  | ||||
|     // deselect and disable the add version button until they are re-enabled | ||||
|     deselectVersion(); | ||||
| @@ -541,21 +616,36 @@ function storageLoadingStart(vString, cMode) { | ||||
|     // turn buttons into spinners | ||||
|     $.each(versionStrings, function (vKey, versionString) { | ||||
|         $.each(cacheModes, function (cKey, cacheMode) { | ||||
|             var buttonDelete = document.getElementById(getCacheButtonID(versionString, cacheMode, "delete")); | ||||
|             var buttonDownload = document.getElementById(getCacheButtonID(versionString, cacheMode, "download")); | ||||
|             var buttonFix = document.getElementById(getCacheButtonID(versionString, cacheMode, "fix")); | ||||
|             var buttonDelete = document.getElementById( | ||||
|                 getCacheButtonID(versionString, cacheMode, "delete") | ||||
|             ); | ||||
|             var buttonDownload = document.getElementById( | ||||
|                 getCacheButtonID(versionString, cacheMode, "download") | ||||
|             ); | ||||
|             var buttonFix = document.getElementById( | ||||
|                 getCacheButtonID(versionString, cacheMode, "fix") | ||||
|             ); | ||||
|  | ||||
|             if (!buttonDelete) return; | ||||
|  | ||||
|             buttonDelete.setAttribute("disabled", ""); | ||||
|             buttonDelete.children[0].setAttribute("class", "fas fa-spinner fa-spin fa-fw"); | ||||
|             buttonDelete.children[0].setAttribute( | ||||
|                 "class", | ||||
|                 "fas fa-spinner fa-spin fa-fw" | ||||
|             ); | ||||
|  | ||||
|             if (cacheMode === "offline") { | ||||
|                 buttonDownload.setAttribute("disabled", ""); | ||||
|                 buttonDownload.children[0].setAttribute("class", "fas fa-spinner fa-spin fa-fw"); | ||||
|                 buttonDownload.children[0].setAttribute( | ||||
|                     "class", | ||||
|                     "fas fa-spinner fa-spin fa-fw" | ||||
|                 ); | ||||
|  | ||||
|                 buttonFix.setAttribute("disabled", ""); | ||||
|                 buttonFix.children[0].setAttribute("class", "fas fa-spinner fa-spin fa-fw"); | ||||
|                 buttonFix.children[0].setAttribute( | ||||
|                     "class", | ||||
|                     "fas fa-spinner fa-spin fa-fw" | ||||
|                 ); | ||||
|             } | ||||
|         }); | ||||
|     }); | ||||
| @@ -565,7 +655,9 @@ function storageLoadingUpdate(allSizes) { | ||||
|     // update cacheSizes and display results | ||||
|     $.each(allSizes, function (versionString, vSizes) { | ||||
|         $.each(vSizes, function (cacheMode, sizes) { | ||||
|             var label = document.getElementById(getCacheElemID(versionString, cacheMode, "label")); | ||||
|             var label = document.getElementById( | ||||
|                 getCacheElemID(versionString, cacheMode, "label") | ||||
|             ); | ||||
|  | ||||
|             cacheSizes = cacheSizes || {}; | ||||
|             cacheSizes[versionString] = cacheSizes[versionString] || {}; | ||||
| @@ -582,16 +674,25 @@ function storageLoadingComplete(allSizes) { | ||||
|     // re-enable buttons according to the sizes that were read | ||||
|     $.each(allSizes, function (versionString, vSizes) { | ||||
|         $.each(vSizes, function (cacheMode, sizes) { | ||||
|             var buttonDelete = document.getElementById(getCacheButtonID(versionString, cacheMode, "delete")); | ||||
|             var buttonDownload = document.getElementById(getCacheButtonID(versionString, cacheMode, "download")); | ||||
|             var buttonFix = document.getElementById(getCacheButtonID(versionString, cacheMode, "fix")); | ||||
|             var buttonDelete = document.getElementById( | ||||
|                 getCacheButtonID(versionString, cacheMode, "delete") | ||||
|             ); | ||||
|             var buttonDownload = document.getElementById( | ||||
|                 getCacheButtonID(versionString, cacheMode, "download") | ||||
|             ); | ||||
|             var buttonFix = document.getElementById( | ||||
|                 getCacheButtonID(versionString, cacheMode, "fix") | ||||
|             ); | ||||
|  | ||||
|             if (!buttonDelete) return; | ||||
|  | ||||
|             buttonDelete.children[0].setAttribute("class", "fas fa-trash-alt"); | ||||
|  | ||||
|             if (cacheMode === "offline") { | ||||
|                 buttonDownload.children[0].setAttribute("class", "fas fa-download"); | ||||
|                 buttonDownload.children[0].setAttribute( | ||||
|                     "class", | ||||
|                     "fas fa-download" | ||||
|                 ); | ||||
|                 buttonFix.children[0].setAttribute("class", "fas fa-hammer"); | ||||
|             } | ||||
|  | ||||
| @@ -626,7 +727,7 @@ function handleCache(operation, versionString, cacheMode, callback) { | ||||
|         return obj.name === versionString; | ||||
|     }); | ||||
|     // pull version url from the found object, if none found, use the default cdn link | ||||
|     var cdnRoot = (versions.length === 0) ? cdnString : versions[0].url; | ||||
|     var cdnRoot = versions.length === 0 ? cdnString : versions[0].url; | ||||
|  | ||||
|     var lastSizes = { intact: 0, altered: 0, total: 0 }; | ||||
|     var buf = ""; | ||||
| @@ -665,28 +766,42 @@ function handleCache(operation, versionString, cacheMode, callback) { | ||||
|         spawn( | ||||
|             path.join(__dirname, "lib", "cache_handler.exe"), | ||||
|             [ | ||||
|                 "--operation", operation, | ||||
|                 "--operation", | ||||
|                 operation, | ||||
|                 // roots below contain version-agnostic main directories for caches | ||||
|                 "--playable-root", cacheRoot, | ||||
|                 "--offline-root", offlineRoot, | ||||
|                 "--user-dir", userData, | ||||
|                 "--playable-root", | ||||
|                 cacheRoot, | ||||
|                 "--offline-root", | ||||
|                 offlineRoot, | ||||
|                 "--user-dir", | ||||
|                 userData, | ||||
|                 // CDN root contains version-specific directory, unless cacheMode is "all" | ||||
|                 "--cdn-root", cdnRoot, | ||||
|                 "--cache-mode", cacheMode || "all", | ||||
|                 "--cache-version", versionString || "all", | ||||
|                 "--cdn-root", | ||||
|                 cdnRoot, | ||||
|                 "--cache-mode", | ||||
|                 cacheMode || "all", | ||||
|                 "--cache-version", | ||||
|                 versionString || "all", | ||||
|                 // learn port from the server object and tell the script where to connect | ||||
|                 "--port", server.address().port, | ||||
|                 "--port", | ||||
|                 server.address().port, | ||||
|                 // tell the script which versions and caches are official | ||||
|                 "--official-caches" | ||||
|                 "--official-caches", | ||||
|             ].concat(Object.keys(defaultHashes)), | ||||
|             { | ||||
|                 stdio: "inherit" | ||||
|                 stdio: "inherit", | ||||
|             } | ||||
|         ).on("exit", function (code, signal) { | ||||
|             if (code !== 0 || signal) { | ||||
|                 dialog.showErrorBox( | ||||
|                     "Sorry!", | ||||
|                     "Process \"" + operation + "\" failed with code " + code + " and signal " + signal + "." | ||||
|                     'Process "' + | ||||
|                         operation + | ||||
|                         '" failed with code ' + | ||||
|                         code + | ||||
|                         " and signal " + | ||||
|                         signal + | ||||
|                         "." | ||||
|                 ); | ||||
|             } | ||||
|  | ||||
| @@ -713,7 +828,10 @@ function performCacheSwap(newVersion) { | ||||
|     if (remotefs.existsSync(currentCache)) { | ||||
|         // Cache already exists, find out what version it belongs to | ||||
|         if (remotefs.existsSync(record)) { | ||||
|             var lastVersion = remotefs.readFileSync(record, (encoding = "utf8")); | ||||
|             var lastVersion = remotefs.readFileSync( | ||||
|                 record, | ||||
|                 (encoding = "utf8") | ||||
|             ); | ||||
|             if (lastVersion != newVersion) { | ||||
|                 // Remove the directory we're trying to store the | ||||
|                 // existing cache to if it already exists for whatever | ||||
| @@ -773,23 +891,33 @@ function prepGameInfo(serverUUID) { | ||||
|  | ||||
|     if (config["verify-offline-cache"]) { | ||||
|         // if required, do a full hash check, and use the offline cache only if it is fully intact | ||||
|         handleCache("hash-check", versionInfo.name, "offline", function (sizes) { | ||||
|             var versionURL = (sizes.intact < sizes.total) ? versionInfo.url : offlineURL; | ||||
|             setGameInfo(serverInfo, versionURL); | ||||
|         }); | ||||
|         handleCache( | ||||
|             "hash-check", | ||||
|             versionInfo.name, | ||||
|             "offline", | ||||
|             function (sizes) { | ||||
|                 var versionURL = | ||||
|                     sizes.intact < sizes.total ? versionInfo.url : offlineURL; | ||||
|                 setGameInfo(serverInfo, versionURL); | ||||
|             } | ||||
|         ); | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     // otherwise, if main.unity3d is present, use the offline cache | ||||
|     var mainPath = path.join(offlinePath, "main.unity3d"); | ||||
|     var versionURL = !remotefs.existsSync(mainPath) ? versionInfo.url : offlineURL; | ||||
|     var versionURL = !remotefs.existsSync(mainPath) | ||||
|         ? versionInfo.url | ||||
|         : offlineURL; | ||||
|     setGameInfo(serverInfo, versionURL); | ||||
| } | ||||
|  | ||||
| // For writing loginInfo.php, assetInfo.php, etc. | ||||
| function setGameInfo(serverInfo, versionURL) { | ||||
|     // slash fix if people mess it up via text editors | ||||
|     var versionURLRoot = versionURL.endsWith("/") ? versionURL : versionURL + "/"; | ||||
|     var versionURLRoot = versionURL.endsWith("/") | ||||
|         ? versionURL | ||||
|         : versionURL + "/"; | ||||
|     window.assetUrl = versionURLRoot; // game-client.js needs to access this | ||||
|     console.log("Cache will expand from " + versionURLRoot); | ||||
|  | ||||
| @@ -860,6 +988,17 @@ function prepConnection(address, port) { | ||||
|     launchGame(); | ||||
| } | ||||
|  | ||||
| function browseOfflineCache() { | ||||
|     var browsePath = dialog.showOpenDialog({ properties: ["openDirectory"] }); | ||||
|     var offlineCacheInput = document.getElementById( | ||||
|         "editconfig-offlinecachelocation" | ||||
|     ); | ||||
|     if (browsePath && offlineCacheInput) { | ||||
|         offlineCacheInput.value = browsePath; | ||||
|         validateCacheLocation(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| // Returns the UUID of the server with the selected background color. | ||||
| // Yes, there are probably better ways to go about this, but it works well enough. | ||||
| function getSelectedServer() { | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| <?xml version="1.0" encoding="UTF-8" standalone="yes"?> | ||||
| <asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3"> | ||||
|   <assemblyIdentity type="win32" name="OpenFusion.Client" version="1.5.2.0" processorArchitecture="x86" /> | ||||
|   <assemblyIdentity type="win32" name="OpenFusion.Client" version="1.6.0.0" processorArchitecture="x86" /> | ||||
|   <dependency> | ||||
|     <dependentAssembly> | ||||
|       <assemblyIdentity type="Win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"> | ||||
|   | ||||
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										2
									
								
								defaults/config.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								defaults/config.json
									
									
									
									
										vendored
									
									
								
							| @@ -1,7 +1,7 @@ | ||||
| { | ||||
|     "autoupdate-check": true, | ||||
|     "cache-swapping": true, | ||||
|     "enable-offline-cache": false, | ||||
|     "enable-offline-cache": true, | ||||
|     "verify-offline-cache": false, | ||||
|     "last-version-initialized": "1.6" | ||||
| } | ||||
|   | ||||
							
								
								
									
										2
									
								
								defaults/hashes.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								defaults/hashes.json
									
									
									
									
										vendored
									
									
								
							| @@ -35692,4 +35692,4 @@ | ||||
|             "rankurl.txt": "af5f2afb22027ad9729cd475ecc50ffdce2199b15300f80efe914ccd98a75105" | ||||
|         } | ||||
|     } | ||||
| } | ||||
| } | ||||
|   | ||||
							
								
								
									
										180
									
								
								index.html
									
									
									
									
									
								
							
							
						
						
									
										180
									
								
								index.html
									
									
									
									
									
								
							| @@ -1,4 +1,4 @@ | ||||
| <!DOCTYPE html> | ||||
| <!doctype html> | ||||
| <html> | ||||
|     <head> | ||||
|         <meta charset="utf-8" /> | ||||
| @@ -108,18 +108,6 @@ | ||||
|                         </button> | ||||
|                     </div> | ||||
|                     <div class="col-4 d-inline-flex justify-content-end"> | ||||
|                         <button | ||||
|                             class="btn btn-primary mr-1" | ||||
|                             data-toggle="modal" | ||||
|                             data-bs-tooltip="" | ||||
|                             data-placement="bottom" | ||||
|                             id="of-editconfig-button" | ||||
|                             type="button" | ||||
|                             title="Edit Configuration" | ||||
|                             data-target="#of-editconfigmodal" | ||||
|                         > | ||||
|                             <i class="fas fa-cog"></i> | ||||
|                         </button> | ||||
|                         <button | ||||
|                             class="btn btn-primary mr-1" | ||||
|                             data-toggle="modal" | ||||
| @@ -183,6 +171,7 @@ | ||||
|                                 data-target="#of-restoreserversmodal" | ||||
|                                 >Reset to Default Servers</a | ||||
|                             > | ||||
|                             <br /> | ||||
|                             <a | ||||
|                                 href="#of-restoreversionsmodal" | ||||
|                                 onclick="$('#of-aboutmodal').modal('toggle')" | ||||
| @@ -501,43 +490,80 @@ | ||||
|                             </button> | ||||
|                         </div> | ||||
|                         <div class="modal-body"> | ||||
|                             <form id="editconfig-form" class="needs-validation"> | ||||
|                                 <label for="editconfig-autoupdate" | ||||
|                                     >Automatically update the client:</label | ||||
|                                 ><input | ||||
|                                     class="form-control form-row w-75" | ||||
|                                     type="checkbox" | ||||
|                                     id="editconfig-autoupdate" | ||||
|                                 /> | ||||
|                                 <label for="editconfig-cacheswapping" | ||||
|                                     >Swap game caches to avoid unnecessary downloads:</label | ||||
|                                 ><input | ||||
|                                     class="form-control form-row w-75" | ||||
|                                     type="checkbox" | ||||
|                                     id="editconfig-cacheswapping" | ||||
|                                 /> | ||||
|                                 <label for="editconfig-enableofflinecache" | ||||
|                                     >Use offline caches when they are available:</label | ||||
|                                 ><input | ||||
|                                     class="form-control form-row w-75" | ||||
|                                     type="checkbox" | ||||
|                                     id="editconfig-enableofflinecache" | ||||
|                                 /> | ||||
|                                 <label for="editconfig-verifyofflinecache" | ||||
|                                     >Verify offline caches every time they are loaded:</label | ||||
|                                 ><input | ||||
|                                     class="form-control form-row w-75" | ||||
|                                     type="checkbox" | ||||
|                                     id="editconfig-verifyofflinecache" | ||||
|                                 /> | ||||
|                             <form | ||||
|                                 id="editconfig-form" | ||||
|                                 class="needs-validation form-group" | ||||
|                             > | ||||
|                                 <div class="form-check form-row"> | ||||
|                                     <input | ||||
|                                         class="form-check-input" | ||||
|                                         type="checkbox" | ||||
|                                         id="editconfig-autoupdate" | ||||
|                                     /> | ||||
|                                     <label | ||||
|                                         class="form-check-label" | ||||
|                                         for="editconfig-autoupdate" | ||||
|                                         >Automatically check for updates</label | ||||
|                                     > | ||||
|                                 </div> | ||||
|                                 <div class="form-check form-row"> | ||||
|                                     <input | ||||
|                                         class="form-check-input" | ||||
|                                         type="checkbox" | ||||
|                                         id="editconfig-cacheswapping" | ||||
|                                     /> | ||||
|                                     <label | ||||
|                                         class="form-check-label" | ||||
|                                         for="editconfig-cacheswapping" | ||||
|                                         >Swap game caches to avoid unnecessary | ||||
|                                         downloads</label | ||||
|                                     > | ||||
|                                 </div> | ||||
|                                 <div class="form-check form-row"> | ||||
|                                     <input | ||||
|                                         class="form-check-input" | ||||
|                                         type="checkbox" | ||||
|                                         id="editconfig-enableofflinecache" | ||||
|                                     /> | ||||
|                                     <label | ||||
|                                         class="form-check-label" | ||||
|                                         for="editconfig-enableofflinecache" | ||||
|                                         >Use offline caches when they are | ||||
|                                         available</label | ||||
|                                     > | ||||
|                                 </div> | ||||
|                                 <div class="form-check form-row mb-3"> | ||||
|                                     <input | ||||
|                                         class="form-check-input" | ||||
|                                         type="checkbox" | ||||
|                                         id="editconfig-verifyofflinecache" | ||||
|                                     /> | ||||
|                                     <label | ||||
|                                         class="form-check-label" | ||||
|                                         for="editconfig-verifyofflinecache" | ||||
|                                         >Verify offline caches every time they | ||||
|                                         are loaded</label | ||||
|                                     > | ||||
|                                 </div> | ||||
|                                 <label for="editconfig-offlinecachelocation" | ||||
|                                     >Select Offline Cache Location:</label | ||||
|                                 ><input | ||||
|                                     class="form-control form-row w-75" | ||||
|                                     id="editconfig-offlinecachelocation" | ||||
|                                     type="text" | ||||
|                                     oninput="validateCacheLocation()" | ||||
|                                 /> | ||||
|                                     ><h5>Offline Cache Location:</h5></label | ||||
|                                 > | ||||
|                                 <div class="form-row"> | ||||
|                                     <input | ||||
|                                         class="form-control w-75" | ||||
|                                         id="editconfig-offlinecachelocation" | ||||
|                                         type="text" | ||||
|                                         oninput="validateCacheLocation()" | ||||
|                                     /> | ||||
|                                     <button | ||||
|                                         type="button" | ||||
|                                         class="btn btn-primary ml-1" | ||||
|                                         onclick="browseOfflineCache()" | ||||
|                                         title="Browse" | ||||
|                                     > | ||||
|                                         <i class="fas fa-folder"></i> | ||||
|                                     </button> | ||||
|                                 </div> | ||||
|                             </form> | ||||
|                         </div> | ||||
|                         <div class="modal-footer"> | ||||
| @@ -568,7 +594,10 @@ | ||||
|                 tabindex="-1" | ||||
|                 id="of-editcacheconfigmodal" | ||||
|             > | ||||
|                 <div class="modal-dialog modal-dialog-centered modal-lg" role="document"> | ||||
|                 <div | ||||
|                     class="modal-dialog modal-dialog-centered modal-lg" | ||||
|                     role="document" | ||||
|                 > | ||||
|                     <div class="modal-content"> | ||||
|                         <div class="modal-header"> | ||||
|                             <h4 class="modal-title">Edit Game Builds</h4> | ||||
| @@ -636,7 +665,9 @@ | ||||
|                                 class="table-responsive text-center border rounded border-primary" | ||||
|                                 id="cache-table" | ||||
|                             > | ||||
|                                 <table class="table table-striped table-hover mb-0"> | ||||
|                                 <table | ||||
|                                     class="table table-striped table-hover mb-0" | ||||
|                                 > | ||||
|                                     <thead> | ||||
|                                         <tr> | ||||
|                                             <th>Game Version</th> | ||||
| @@ -644,8 +675,7 @@ | ||||
|                                             <th>Offline Cache</th> | ||||
|                                         </tr> | ||||
|                                     </thead> | ||||
|                                     <tbody id="cache-tablebody"> | ||||
|                                     </tbody> | ||||
|                                     <tbody id="cache-tablebody"></tbody> | ||||
|                                 </table> | ||||
|                             </div> | ||||
|                         </div> | ||||
| @@ -661,7 +691,7 @@ | ||||
|                 <div class="modal-dialog modal-dialog-centered" role="document"> | ||||
|                     <div class="modal-content"> | ||||
|                         <div class="modal-header"> | ||||
|                             <h4 class="modal-title">Add Server</h4> | ||||
|                             <h4 class="modal-title">Add Version</h4> | ||||
|                             <button | ||||
|                                 type="button" | ||||
|                                 class="close" | ||||
| @@ -738,7 +768,10 @@ | ||||
|                             </button> | ||||
|                         </div> | ||||
|                         <div class="modal-body"> | ||||
|                             <form id="editversion-form" class="needs-validation"> | ||||
|                             <form | ||||
|                                 id="editversion-form" | ||||
|                                 class="needs-validation" | ||||
|                             > | ||||
|                                 <label for="editversion-nameinput" | ||||
|                                     >Version Name</label | ||||
|                                 ><input | ||||
| @@ -876,15 +909,38 @@ | ||||
|                     </div> | ||||
|                 </div> | ||||
|             </div> | ||||
|             <div id="of-versionnumberdiv"> | ||||
|                 <a | ||||
|                     id="of-versionnumber" | ||||
|                     class="text-monospace text-secondary" | ||||
|                     href="#of-aboutmodal" | ||||
|             <div id="of-config-button-div"> | ||||
|                 <button | ||||
|                     class="btn btn-primary mr-1" | ||||
|                     data-toggle="modal" | ||||
|                     data-target="#of-aboutmodal" | ||||
|                     >v0</a | ||||
|                     data-bs-tooltip="" | ||||
|                     data-placement="right" | ||||
|                     id="of-editconfig-button" | ||||
|                     type="button" | ||||
|                     title="Edit Configuration" | ||||
|                     data-target="#of-editconfigmodal" | ||||
|                 > | ||||
|                     <i class="fas fa-cog"></i> | ||||
|                 </button> | ||||
|             </div> | ||||
|             <div id="of-about-button-div"> | ||||
|                 <button | ||||
|                     class="btn btn-primary mr-1" | ||||
|                     data-toggle="modal" | ||||
|                     data-bs-tooltip="" | ||||
|                     data-placement="left" | ||||
|                     id="of-about-button" | ||||
|                     type="button" | ||||
|                     title="About OpenFusionClient" | ||||
|                     data-target="#of-aboutmodal" | ||||
|                 > | ||||
|                     <i class="fas fa-info-circle"></i> | ||||
|                 </button> | ||||
|             </div> | ||||
|             <div id="of-about-flash-div" style="z-index: -1"> | ||||
|                 <button class="btn btn-warning mr-1" tabindex="-1" type="button"> | ||||
|                     <i class="fas fa-info-circle"></i> | ||||
|                 </button> | ||||
|             </div> | ||||
|         </section> | ||||
|         <section> | ||||
|   | ||||
							
								
								
									
										76
									
								
								index.js
									
									
									
									
									
								
							
							
						
						
									
										76
									
								
								index.js
									
									
									
									
									
								
							| @@ -30,25 +30,83 @@ var serversPath = path.join(userData, "servers.json"); | ||||
| var versionsPath = path.join(userData, "versions.json"); | ||||
| var hashPath = path.join(userData, "hashes.json"); | ||||
|  | ||||
| function backup() { | ||||
|     if (fs.existsSync(configPath)) fs.copySync(configPath, configPath + ".bak"); | ||||
|     if (fs.existsSync(serversPath)) | ||||
|         fs.copySync(serversPath, serversPath + ".bak"); | ||||
|     if (fs.existsSync(versionsPath)) | ||||
|         fs.copySync(versionsPath, versionsPath + ".bak"); | ||||
|     if (fs.existsSync(hashPath)) fs.copySync(hashPath, hashPath + ".bak"); | ||||
| } | ||||
|  | ||||
| function patchVersions() { | ||||
|     var current = fs.readJsonSync(versionsPath); | ||||
|     var newDefaults = fs.readJsonSync( | ||||
|         path.join(__dirname, "/defaults/versions.json") | ||||
|     ); | ||||
|     for (var i = 0; i < newDefaults["versions"].length; i++) { | ||||
|         var newDefault = newDefaults["versions"][i]; | ||||
|         var found = false; | ||||
|         for (var j = 0; j < current["versions"].length; j++) { | ||||
|             var version = current["versions"][j]; | ||||
|             if (newDefault["name"] === version["name"]) { | ||||
|                 current["versions"][j] = newDefault; | ||||
|                 found = true; | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|         if (!found) { | ||||
|             current["versions"].push(newDefault); | ||||
|         } | ||||
|     } | ||||
|     fs.writeFileSync(versionsPath, JSON.stringify(current, null, 4)); | ||||
| } | ||||
|  | ||||
| function patchServers() { | ||||
|     var current = fs.readJsonSync(serversPath); | ||||
|     var newDefaults = fs.readJsonSync( | ||||
|         path.join(__dirname, "/defaults/servers.json") | ||||
|     ); | ||||
|     for (var i = 0; i < newDefaults["servers"].length; i++) { | ||||
|         var newDefault = newDefaults["servers"][i]; | ||||
|         var found = false; | ||||
|         for (var j = 0; j < current["servers"].length; j++) { | ||||
|             var server = current["servers"][j]; | ||||
|             if (newDefault["uuid"] === server["uuid"]) { | ||||
|                 current["servers"][j] = newDefault; | ||||
|                 found = true; | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|         if (!found) { | ||||
|             current["servers"].push(newDefault); | ||||
|         } | ||||
|     } | ||||
|     fs.writeFileSync(serversPath, JSON.stringify(current, null, 4)); | ||||
| } | ||||
|  | ||||
| function initialSetup(firstTime) { | ||||
|     if (!firstTime) { | ||||
|         // Migration from pre-1.6 | ||||
|         // Back everything up, just in case | ||||
|         if (fs.existsSync(configPath)) fs.copySync(configPath, configPath + ".bak"); | ||||
|         if (fs.existsSync(serversPath)) fs.copySync(serversPath, serversPath + ".bak"); | ||||
|         if (fs.existsSync(versionsPath)) fs.copySync(versionsPath, versionsPath + ".bak"); | ||||
|         if (fs.existsSync(hashPath)) fs.copySync(hashPath, hashPath + ".bak"); | ||||
|     } else { | ||||
|     backup(); | ||||
|  | ||||
|     if (firstTime) { | ||||
|         // First-time setup | ||||
|         // Copy default servers | ||||
|         fs.copySync( | ||||
|             path.join(__dirname, "/defaults/servers.json"), | ||||
|             serversPath | ||||
|         ); | ||||
|         fs.copySync( | ||||
|             path.join(__dirname, "/defaults/versions.json"), | ||||
|             versionsPath | ||||
|         ); | ||||
|     } else if (fs.existsSync(serversPath)) { | ||||
|         // Migration | ||||
|         // Update default servers and versions | ||||
|         patchVersions(); | ||||
|         patchServers(); | ||||
|     } | ||||
|  | ||||
|     // Copy default versions and config | ||||
|     fs.copySync(path.join(__dirname, "/defaults/versions.json"), versionsPath); | ||||
|     fs.copySync(path.join(__dirname, "/defaults/config.json"), configPath); | ||||
|     fs.copySync(path.join(__dirname, "/defaults/hashes.json"), hashPath); | ||||
|  | ||||
|   | ||||
							
								
								
									
										421
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										421
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @@ -1,12 +1,12 @@ | ||||
| { | ||||
|     "name": "OpenFusionClient", | ||||
|     "version": "1.5.2", | ||||
|     "version": "1.6.0", | ||||
|     "lockfileVersion": 2, | ||||
|     "requires": true, | ||||
|     "packages": { | ||||
|         "": { | ||||
|             "name": "OpenFusionClient", | ||||
|             "version": "1.5.2", | ||||
|             "version": "1.6.0", | ||||
|             "hasInstallScript": true, | ||||
|             "license": "MIT", | ||||
|             "dependencies": { | ||||
| @@ -15,8 +15,8 @@ | ||||
|             "devDependencies": { | ||||
|                 "electron-builder": "^22.14.13", | ||||
|                 "electron-prebuilt": "^0.31.2", | ||||
|                 "patch-package": "^6.5.1", | ||||
|                 "prettier": "^2.7.1" | ||||
|                 "patch-package": "^7.0.2", | ||||
|                 "prettier": "^3.3.3" | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/@develar/schema-utils": { | ||||
| @@ -112,65 +112,6 @@ | ||||
|                 "node": ">= 10" | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/@malept/cross-spawn-promise/node_modules/cross-spawn": { | ||||
|             "version": "7.0.3", | ||||
|             "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", | ||||
|             "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", | ||||
|             "dev": true, | ||||
|             "dependencies": { | ||||
|                 "path-key": "^3.1.0", | ||||
|                 "shebang-command": "^2.0.0", | ||||
|                 "which": "^2.0.1" | ||||
|             }, | ||||
|             "engines": { | ||||
|                 "node": ">= 8" | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/@malept/cross-spawn-promise/node_modules/path-key": { | ||||
|             "version": "3.1.1", | ||||
|             "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", | ||||
|             "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", | ||||
|             "dev": true, | ||||
|             "engines": { | ||||
|                 "node": ">=8" | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/@malept/cross-spawn-promise/node_modules/shebang-command": { | ||||
|             "version": "2.0.0", | ||||
|             "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", | ||||
|             "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", | ||||
|             "dev": true, | ||||
|             "dependencies": { | ||||
|                 "shebang-regex": "^3.0.0" | ||||
|             }, | ||||
|             "engines": { | ||||
|                 "node": ">=8" | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/@malept/cross-spawn-promise/node_modules/shebang-regex": { | ||||
|             "version": "3.0.0", | ||||
|             "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", | ||||
|             "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", | ||||
|             "dev": true, | ||||
|             "engines": { | ||||
|                 "node": ">=8" | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/@malept/cross-spawn-promise/node_modules/which": { | ||||
|             "version": "2.0.2", | ||||
|             "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", | ||||
|             "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", | ||||
|             "dev": true, | ||||
|             "dependencies": { | ||||
|                 "isexe": "^2.0.0" | ||||
|             }, | ||||
|             "bin": { | ||||
|                 "node-which": "bin/node-which" | ||||
|             }, | ||||
|             "engines": { | ||||
|                 "node": ">= 8" | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/@malept/flatpak-bundler": { | ||||
|             "version": "0.4.0", | ||||
|             "resolved": "https://registry.npmjs.org/@malept/flatpak-bundler/-/flatpak-bundler-0.4.0.tgz", | ||||
| @@ -996,20 +937,6 @@ | ||||
|                 "node": ">=8" | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/builder-util/node_modules/cross-spawn": { | ||||
|             "version": "7.0.3", | ||||
|             "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", | ||||
|             "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", | ||||
|             "dev": true, | ||||
|             "dependencies": { | ||||
|                 "path-key": "^3.1.0", | ||||
|                 "shebang-command": "^2.0.0", | ||||
|                 "which": "^2.0.1" | ||||
|             }, | ||||
|             "engines": { | ||||
|                 "node": ">= 8" | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/builder-util/node_modules/debug": { | ||||
|             "version": "4.3.4", | ||||
|             "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", | ||||
| @@ -1059,51 +986,6 @@ | ||||
|             "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", | ||||
|             "dev": true | ||||
|         }, | ||||
|         "node_modules/builder-util/node_modules/path-key": { | ||||
|             "version": "3.1.1", | ||||
|             "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", | ||||
|             "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", | ||||
|             "dev": true, | ||||
|             "engines": { | ||||
|                 "node": ">=8" | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/builder-util/node_modules/shebang-command": { | ||||
|             "version": "2.0.0", | ||||
|             "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", | ||||
|             "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", | ||||
|             "dev": true, | ||||
|             "dependencies": { | ||||
|                 "shebang-regex": "^3.0.0" | ||||
|             }, | ||||
|             "engines": { | ||||
|                 "node": ">=8" | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/builder-util/node_modules/shebang-regex": { | ||||
|             "version": "3.0.0", | ||||
|             "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", | ||||
|             "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", | ||||
|             "dev": true, | ||||
|             "engines": { | ||||
|                 "node": ">=8" | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/builder-util/node_modules/which": { | ||||
|             "version": "2.0.2", | ||||
|             "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", | ||||
|             "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", | ||||
|             "dev": true, | ||||
|             "dependencies": { | ||||
|                 "isexe": "^2.0.0" | ||||
|             }, | ||||
|             "bin": { | ||||
|                 "node-which": "bin/node-which" | ||||
|             }, | ||||
|             "engines": { | ||||
|                 "node": ">= 8" | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/cacheable-request": { | ||||
|             "version": "6.1.0", | ||||
|             "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", | ||||
| @@ -1423,19 +1305,17 @@ | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/cross-spawn": { | ||||
|             "version": "6.0.5", | ||||
|             "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", | ||||
|             "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", | ||||
|             "version": "7.0.3", | ||||
|             "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", | ||||
|             "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", | ||||
|             "dev": true, | ||||
|             "dependencies": { | ||||
|                 "nice-try": "^1.0.4", | ||||
|                 "path-key": "^2.0.1", | ||||
|                 "semver": "^5.5.0", | ||||
|                 "shebang-command": "^1.2.0", | ||||
|                 "which": "^1.2.9" | ||||
|                 "path-key": "^3.1.0", | ||||
|                 "shebang-command": "^2.0.0", | ||||
|                 "which": "^2.0.1" | ||||
|             }, | ||||
|             "engines": { | ||||
|                 "node": ">=4.8" | ||||
|                 "node": ">= 8" | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/crypto-random-string": { | ||||
| @@ -2597,7 +2477,7 @@ | ||||
|         "node_modules/isexe": { | ||||
|             "version": "2.0.0", | ||||
|             "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", | ||||
|             "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", | ||||
|             "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", | ||||
|             "dev": true | ||||
|         }, | ||||
|         "node_modules/isstream": { | ||||
| @@ -2968,12 +2848,6 @@ | ||||
|                 "ncp": "bin/ncp" | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/nice-try": { | ||||
|             "version": "1.0.5", | ||||
|             "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", | ||||
|             "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", | ||||
|             "dev": true | ||||
|         }, | ||||
|         "node_modules/node-addon-api": { | ||||
|             "version": "1.7.2", | ||||
|             "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz", | ||||
| @@ -3124,34 +2998,49 @@ | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/patch-package": { | ||||
|             "version": "6.5.1", | ||||
|             "resolved": "https://registry.npmjs.org/patch-package/-/patch-package-6.5.1.tgz", | ||||
|             "integrity": "sha512-I/4Zsalfhc6bphmJTlrLoOcAF87jcxko4q0qsv4bGcurbr8IskEOtdnt9iCmsQVGL1B+iUhSQqweyTLJfCF9rA==", | ||||
|             "version": "7.0.2", | ||||
|             "resolved": "https://registry.npmjs.org/patch-package/-/patch-package-7.0.2.tgz", | ||||
|             "integrity": "sha512-PMYfL8LXxGIRmxXLqlEaBxzKPu7/SdP13ld6GSfAUJUZRmBDPp8chZs0dpzaAFn9TSPnFiMwkC6PJt6pBiAl8Q==", | ||||
|             "dev": true, | ||||
|             "dependencies": { | ||||
|                 "@yarnpkg/lockfile": "^1.1.0", | ||||
|                 "chalk": "^4.1.2", | ||||
|                 "cross-spawn": "^6.0.5", | ||||
|                 "ci-info": "^3.7.0", | ||||
|                 "cross-spawn": "^7.0.3", | ||||
|                 "find-yarn-workspace-root": "^2.0.0", | ||||
|                 "fs-extra": "^9.0.0", | ||||
|                 "is-ci": "^2.0.0", | ||||
|                 "klaw-sync": "^6.0.0", | ||||
|                 "minimist": "^1.2.6", | ||||
|                 "open": "^7.4.2", | ||||
|                 "rimraf": "^2.6.3", | ||||
|                 "semver": "^5.6.0", | ||||
|                 "semver": "^7.5.3", | ||||
|                 "slash": "^2.0.0", | ||||
|                 "tmp": "^0.0.33", | ||||
|                 "yaml": "^1.10.2" | ||||
|                 "yaml": "^2.2.2" | ||||
|             }, | ||||
|             "bin": { | ||||
|                 "patch-package": "index.js" | ||||
|             }, | ||||
|             "engines": { | ||||
|                 "node": ">=10", | ||||
|                 "node": ">=14", | ||||
|                 "npm": ">5" | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/patch-package/node_modules/ci-info": { | ||||
|             "version": "3.9.0", | ||||
|             "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", | ||||
|             "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", | ||||
|             "dev": true, | ||||
|             "funding": [ | ||||
|                 { | ||||
|                     "type": "github", | ||||
|                     "url": "https://github.com/sponsors/sibiraj-s" | ||||
|                 } | ||||
|             ], | ||||
|             "engines": { | ||||
|                 "node": ">=8" | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/patch-package/node_modules/fs-extra": { | ||||
|             "version": "9.1.0", | ||||
|             "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", | ||||
| @@ -3199,6 +3088,18 @@ | ||||
|                 "rimraf": "bin.js" | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/patch-package/node_modules/semver": { | ||||
|             "version": "7.6.2", | ||||
|             "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", | ||||
|             "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", | ||||
|             "dev": true, | ||||
|             "bin": { | ||||
|                 "semver": "bin/semver.js" | ||||
|             }, | ||||
|             "engines": { | ||||
|                 "node": ">=10" | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/path-exists": { | ||||
|             "version": "1.0.0", | ||||
|             "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-1.0.0.tgz", | ||||
| @@ -3218,12 +3119,12 @@ | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/path-key": { | ||||
|             "version": "2.0.1", | ||||
|             "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", | ||||
|             "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", | ||||
|             "version": "3.1.1", | ||||
|             "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", | ||||
|             "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", | ||||
|             "dev": true, | ||||
|             "engines": { | ||||
|                 "node": ">=4" | ||||
|                 "node": ">=8" | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/path-parse": { | ||||
| @@ -3323,15 +3224,15 @@ | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/prettier": { | ||||
|             "version": "2.7.1", | ||||
|             "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", | ||||
|             "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==", | ||||
|             "version": "3.3.3", | ||||
|             "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", | ||||
|             "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", | ||||
|             "dev": true, | ||||
|             "bin": { | ||||
|                 "prettier": "bin-prettier.js" | ||||
|                 "prettier": "bin/prettier.cjs" | ||||
|             }, | ||||
|             "engines": { | ||||
|                 "node": ">=10.13.0" | ||||
|                 "node": ">=14" | ||||
|             }, | ||||
|             "funding": { | ||||
|                 "url": "https://github.com/prettier/prettier?sponsor=1" | ||||
| @@ -3681,24 +3582,24 @@ | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/shebang-command": { | ||||
|             "version": "1.2.0", | ||||
|             "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", | ||||
|             "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", | ||||
|             "version": "2.0.0", | ||||
|             "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", | ||||
|             "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", | ||||
|             "dev": true, | ||||
|             "dependencies": { | ||||
|                 "shebang-regex": "^1.0.0" | ||||
|                 "shebang-regex": "^3.0.0" | ||||
|             }, | ||||
|             "engines": { | ||||
|                 "node": ">=0.10.0" | ||||
|                 "node": ">=8" | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/shebang-regex": { | ||||
|             "version": "1.0.0", | ||||
|             "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", | ||||
|             "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", | ||||
|             "version": "3.0.0", | ||||
|             "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", | ||||
|             "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", | ||||
|             "dev": true, | ||||
|             "engines": { | ||||
|                 "node": ">=0.10.0" | ||||
|                 "node": ">=8" | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/signal-exit": { | ||||
| @@ -4314,15 +4215,18 @@ | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/which": { | ||||
|             "version": "1.3.1", | ||||
|             "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", | ||||
|             "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", | ||||
|             "version": "2.0.2", | ||||
|             "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", | ||||
|             "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", | ||||
|             "dev": true, | ||||
|             "dependencies": { | ||||
|                 "isexe": "^2.0.0" | ||||
|             }, | ||||
|             "bin": { | ||||
|                 "which": "bin/which" | ||||
|                 "node-which": "bin/node-which" | ||||
|             }, | ||||
|             "engines": { | ||||
|                 "node": ">= 8" | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/widest-line": { | ||||
| @@ -4439,12 +4343,15 @@ | ||||
|             "dev": true | ||||
|         }, | ||||
|         "node_modules/yaml": { | ||||
|             "version": "1.10.2", | ||||
|             "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", | ||||
|             "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", | ||||
|             "version": "2.4.5", | ||||
|             "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.5.tgz", | ||||
|             "integrity": "sha512-aBx2bnqDzVOyNKfsysjA2ms5ZlnjSAW2eG3/L5G/CSujfjLJTJsEw1bGw8kCf04KodQWk1pxlGnZ56CRxiawmg==", | ||||
|             "dev": true, | ||||
|             "bin": { | ||||
|                 "yaml": "bin.mjs" | ||||
|             }, | ||||
|             "engines": { | ||||
|                 "node": ">= 6" | ||||
|                 "node": ">= 14" | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/yargs": { | ||||
| @@ -4545,49 +4452,6 @@ | ||||
|             "dev": true, | ||||
|             "requires": { | ||||
|                 "cross-spawn": "^7.0.1" | ||||
|             }, | ||||
|             "dependencies": { | ||||
|                 "cross-spawn": { | ||||
|                     "version": "7.0.3", | ||||
|                     "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", | ||||
|                     "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", | ||||
|                     "dev": true, | ||||
|                     "requires": { | ||||
|                         "path-key": "^3.1.0", | ||||
|                         "shebang-command": "^2.0.0", | ||||
|                         "which": "^2.0.1" | ||||
|                     } | ||||
|                 }, | ||||
|                 "path-key": { | ||||
|                     "version": "3.1.1", | ||||
|                     "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", | ||||
|                     "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", | ||||
|                     "dev": true | ||||
|                 }, | ||||
|                 "shebang-command": { | ||||
|                     "version": "2.0.0", | ||||
|                     "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", | ||||
|                     "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", | ||||
|                     "dev": true, | ||||
|                     "requires": { | ||||
|                         "shebang-regex": "^3.0.0" | ||||
|                     } | ||||
|                 }, | ||||
|                 "shebang-regex": { | ||||
|                     "version": "3.0.0", | ||||
|                     "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", | ||||
|                     "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", | ||||
|                     "dev": true | ||||
|                 }, | ||||
|                 "which": { | ||||
|                     "version": "2.0.2", | ||||
|                     "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", | ||||
|                     "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", | ||||
|                     "dev": true, | ||||
|                     "requires": { | ||||
|                         "isexe": "^2.0.0" | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         }, | ||||
|         "@malept/flatpak-bundler": { | ||||
| @@ -5207,17 +5071,6 @@ | ||||
|                     "integrity": "sha512-4jYS4MOAaCIStSRwiuxc4B8MYhIe676yO1sYGzARnjXkWpmzZMMYxY6zu8WYWDhSuth5zhrQ1rhNSibyyvv4/w==", | ||||
|                     "dev": true | ||||
|                 }, | ||||
|                 "cross-spawn": { | ||||
|                     "version": "7.0.3", | ||||
|                     "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", | ||||
|                     "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", | ||||
|                     "dev": true, | ||||
|                     "requires": { | ||||
|                         "path-key": "^3.1.0", | ||||
|                         "shebang-command": "^2.0.0", | ||||
|                         "which": "^2.0.1" | ||||
|                     } | ||||
|                 }, | ||||
|                 "debug": { | ||||
|                     "version": "4.3.4", | ||||
|                     "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", | ||||
| @@ -5252,36 +5105,6 @@ | ||||
|                     "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", | ||||
|                     "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", | ||||
|                     "dev": true | ||||
|                 }, | ||||
|                 "path-key": { | ||||
|                     "version": "3.1.1", | ||||
|                     "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", | ||||
|                     "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", | ||||
|                     "dev": true | ||||
|                 }, | ||||
|                 "shebang-command": { | ||||
|                     "version": "2.0.0", | ||||
|                     "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", | ||||
|                     "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", | ||||
|                     "dev": true, | ||||
|                     "requires": { | ||||
|                         "shebang-regex": "^3.0.0" | ||||
|                     } | ||||
|                 }, | ||||
|                 "shebang-regex": { | ||||
|                     "version": "3.0.0", | ||||
|                     "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", | ||||
|                     "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", | ||||
|                     "dev": true | ||||
|                 }, | ||||
|                 "which": { | ||||
|                     "version": "2.0.2", | ||||
|                     "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", | ||||
|                     "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", | ||||
|                     "dev": true, | ||||
|                     "requires": { | ||||
|                         "isexe": "^2.0.0" | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         }, | ||||
| @@ -5571,16 +5394,14 @@ | ||||
|             } | ||||
|         }, | ||||
|         "cross-spawn": { | ||||
|             "version": "6.0.5", | ||||
|             "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", | ||||
|             "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", | ||||
|             "version": "7.0.3", | ||||
|             "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", | ||||
|             "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", | ||||
|             "dev": true, | ||||
|             "requires": { | ||||
|                 "nice-try": "^1.0.4", | ||||
|                 "path-key": "^2.0.1", | ||||
|                 "semver": "^5.5.0", | ||||
|                 "shebang-command": "^1.2.0", | ||||
|                 "which": "^1.2.9" | ||||
|                 "path-key": "^3.1.0", | ||||
|                 "shebang-command": "^2.0.0", | ||||
|                 "which": "^2.0.1" | ||||
|             } | ||||
|         }, | ||||
|         "crypto-random-string": { | ||||
| @@ -6486,7 +6307,7 @@ | ||||
|         "isexe": { | ||||
|             "version": "2.0.0", | ||||
|             "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", | ||||
|             "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", | ||||
|             "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", | ||||
|             "dev": true | ||||
|         }, | ||||
|         "isstream": { | ||||
| @@ -6776,12 +6597,6 @@ | ||||
|             "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=", | ||||
|             "dev": true | ||||
|         }, | ||||
|         "nice-try": { | ||||
|             "version": "1.0.5", | ||||
|             "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", | ||||
|             "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", | ||||
|             "dev": true | ||||
|         }, | ||||
|         "node-addon-api": { | ||||
|             "version": "1.7.2", | ||||
|             "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz", | ||||
| @@ -6901,27 +6716,33 @@ | ||||
|             } | ||||
|         }, | ||||
|         "patch-package": { | ||||
|             "version": "6.5.1", | ||||
|             "resolved": "https://registry.npmjs.org/patch-package/-/patch-package-6.5.1.tgz", | ||||
|             "integrity": "sha512-I/4Zsalfhc6bphmJTlrLoOcAF87jcxko4q0qsv4bGcurbr8IskEOtdnt9iCmsQVGL1B+iUhSQqweyTLJfCF9rA==", | ||||
|             "version": "7.0.2", | ||||
|             "resolved": "https://registry.npmjs.org/patch-package/-/patch-package-7.0.2.tgz", | ||||
|             "integrity": "sha512-PMYfL8LXxGIRmxXLqlEaBxzKPu7/SdP13ld6GSfAUJUZRmBDPp8chZs0dpzaAFn9TSPnFiMwkC6PJt6pBiAl8Q==", | ||||
|             "dev": true, | ||||
|             "requires": { | ||||
|                 "@yarnpkg/lockfile": "^1.1.0", | ||||
|                 "chalk": "^4.1.2", | ||||
|                 "cross-spawn": "^6.0.5", | ||||
|                 "ci-info": "^3.7.0", | ||||
|                 "cross-spawn": "^7.0.3", | ||||
|                 "find-yarn-workspace-root": "^2.0.0", | ||||
|                 "fs-extra": "^9.0.0", | ||||
|                 "is-ci": "^2.0.0", | ||||
|                 "klaw-sync": "^6.0.0", | ||||
|                 "minimist": "^1.2.6", | ||||
|                 "open": "^7.4.2", | ||||
|                 "rimraf": "^2.6.3", | ||||
|                 "semver": "^5.6.0", | ||||
|                 "semver": "^7.5.3", | ||||
|                 "slash": "^2.0.0", | ||||
|                 "tmp": "^0.0.33", | ||||
|                 "yaml": "^1.10.2" | ||||
|                 "yaml": "^2.2.2" | ||||
|             }, | ||||
|             "dependencies": { | ||||
|                 "ci-info": { | ||||
|                     "version": "3.9.0", | ||||
|                     "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", | ||||
|                     "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", | ||||
|                     "dev": true | ||||
|                 }, | ||||
|                 "fs-extra": { | ||||
|                     "version": "9.1.0", | ||||
|                     "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", | ||||
| @@ -6956,6 +6777,12 @@ | ||||
|                     "requires": { | ||||
|                         "glob": "^7.1.3" | ||||
|                     } | ||||
|                 }, | ||||
|                 "semver": { | ||||
|                     "version": "7.6.2", | ||||
|                     "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", | ||||
|                     "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", | ||||
|                     "dev": true | ||||
|                 } | ||||
|             } | ||||
|         }, | ||||
| @@ -6972,9 +6799,9 @@ | ||||
|             "dev": true | ||||
|         }, | ||||
|         "path-key": { | ||||
|             "version": "2.0.1", | ||||
|             "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", | ||||
|             "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", | ||||
|             "version": "3.1.1", | ||||
|             "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", | ||||
|             "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", | ||||
|             "dev": true | ||||
|         }, | ||||
|         "path-parse": { | ||||
| @@ -7050,9 +6877,9 @@ | ||||
|             "dev": true | ||||
|         }, | ||||
|         "prettier": { | ||||
|             "version": "2.7.1", | ||||
|             "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", | ||||
|             "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==", | ||||
|             "version": "3.3.3", | ||||
|             "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", | ||||
|             "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", | ||||
|             "dev": true | ||||
|         }, | ||||
|         "pretty-bytes": { | ||||
| @@ -7326,18 +7153,18 @@ | ||||
|             } | ||||
|         }, | ||||
|         "shebang-command": { | ||||
|             "version": "1.2.0", | ||||
|             "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", | ||||
|             "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", | ||||
|             "version": "2.0.0", | ||||
|             "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", | ||||
|             "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", | ||||
|             "dev": true, | ||||
|             "requires": { | ||||
|                 "shebang-regex": "^1.0.0" | ||||
|                 "shebang-regex": "^3.0.0" | ||||
|             } | ||||
|         }, | ||||
|         "shebang-regex": { | ||||
|             "version": "1.0.0", | ||||
|             "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", | ||||
|             "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", | ||||
|             "version": "3.0.0", | ||||
|             "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", | ||||
|             "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", | ||||
|             "dev": true | ||||
|         }, | ||||
|         "signal-exit": { | ||||
| @@ -7833,9 +7660,9 @@ | ||||
|             } | ||||
|         }, | ||||
|         "which": { | ||||
|             "version": "1.3.1", | ||||
|             "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", | ||||
|             "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", | ||||
|             "version": "2.0.2", | ||||
|             "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", | ||||
|             "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", | ||||
|             "dev": true, | ||||
|             "requires": { | ||||
|                 "isexe": "^2.0.0" | ||||
| @@ -7930,9 +7757,9 @@ | ||||
|             "dev": true | ||||
|         }, | ||||
|         "yaml": { | ||||
|             "version": "1.10.2", | ||||
|             "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", | ||||
|             "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", | ||||
|             "version": "2.4.5", | ||||
|             "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.5.tgz", | ||||
|             "integrity": "sha512-aBx2bnqDzVOyNKfsysjA2ms5ZlnjSAW2eG3/L5G/CSujfjLJTJsEw1bGw8kCf04KodQWk1pxlGnZ56CRxiawmg==", | ||||
|             "dev": true | ||||
|         }, | ||||
|         "yargs": { | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "OpenFusionClient", | ||||
|     "version": "1.5.2", | ||||
|     "version": "1.6.1", | ||||
|     "description": "OpenFusionClient", | ||||
|     "main": "index.js", | ||||
|     "scripts": { | ||||
| @@ -15,8 +15,8 @@ | ||||
|     "devDependencies": { | ||||
|         "electron-builder": "^22.14.13", | ||||
|         "electron-prebuilt": "^0.31.2", | ||||
|         "patch-package": "^6.5.1", | ||||
|         "prettier": "^2.7.1" | ||||
|         "patch-package": "^7.0.2", | ||||
|         "prettier": "^3.3.3" | ||||
|     }, | ||||
|     "repository": { | ||||
|         "type": "git", | ||||
| @@ -25,7 +25,7 @@ | ||||
|     "build": { | ||||
|         "appId": "xyz.openfusion.client", | ||||
|         "productName": "OpenFusionClient", | ||||
|         "copyright": "© 2020-2023 OpenFusion Contributors", | ||||
|         "copyright": "© 2020-2024 OpenFusion Contributors", | ||||
|         "electronDownload": { | ||||
|             "version": "0.31.2", | ||||
|             "platform": "win32", | ||||
|   | ||||
		Reference in New Issue
	
	Block a user