From 66d76c8302cfec0e52178a7202d98e03d7e67113 Mon Sep 17 00:00:00 2001 From: Henry Gross-Hellsen <6283258+cowpod@users.noreply.github.com> Date: Fri, 15 Nov 2024 14:45:18 -0800 Subject: [PATCH] api/index.php/mod: filter in db instead of php, add /loader endpoint, index.php: new description/titles/labels, index.php/modloaders: dynamic/js ui, filter out beta neoforge, add filesize to loaders, loader filenames reflect the type --- api/index.php | 45 +- ...ge-fabric.php => add-modloader-fabric.php} | 33 +- functions/add-modloader.php | 21 +- index.php | 138 ++++-- resources/js/page_modloaders.js | 406 +++++++++++------- 5 files changed, 410 insertions(+), 233 deletions(-) rename functions/{package-fabric.php => add-modloader-fabric.php} (71%) diff --git a/api/index.php b/api/index.php index 5fe34d9..ba677c5 100644 --- a/api/index.php +++ b/api/index.php @@ -79,17 +79,52 @@ $mcversion=$_GET['mcversion']; } if (!empty($loadertype) && !empty($mcversion)) { - $modq = $db->query("SELECT * FROM mods WHERE loadertype='{$loadertype}' AND ('{$mcversion}' LIKE mcversion || '%' OR mcversion LIKE '{$mcversion}' || '%')"); + $modq = $db->query("SELECT * FROM mods WHERE type='mod' AND loadertype='{$loadertype}' AND ('{$mcversion}' LIKE mcversion || '%' OR mcversion LIKE '{$mcversion}' || '%')"); } elseif (!empty($loadertype)) { - $modq = $db->query("SELECT * FROM mods WHERE loadertype='{$loadertype}'"); + $modq = $db->query("SELECT * FROM mods WHERE type='mod' AND loadertype='{$loadertype}'"); } elseif (!empty($mcversion)) { - $modq = $db->query("SELECT * FROM mods WHERE '{$mcversion}' LIKE mcversion || '%'"); + $modq = $db->query("SELECT * FROM mods WHERE type='mod' AND '{$mcversion}' LIKE mcversion || '%'"); } else { - $modq = $db->query("SELECT * FROM mods"); + $modq = $db->query("SELECT * FROM mods WHERE type='mod'"); + } + if ($modq) { + foreach ($modq as $mod) { + $filesize = isset($mod['filesize']) ? $mod['filesize'] : 0; + $modentry = [ + 'id'=>$mod['id'], + 'pretty_name'=>$mod['pretty_name'], + 'name'=>$mod['name'], + 'version'=>$mod['version'], + 'mcversion'=>$mod['mcversion'], + 'md5'=>$mod['md5'], + 'url'=>$mod['url'], + 'filesize'=>$filesize + ]; + + array_push($modslist, $modentry); + } + } + echo json_encode($modslist, JSON_UNESCAPED_SLASHES); +} +else if (preg_match("/api\/loader$/", $url)) { + $modslist=[]; + if (!empty($_GET['loadertype']) && ctype_alnum($_GET['loadertype'])) { + $loadertype=$_GET['loadertype']; + } + if (!empty($_GET['mcversion']) && preg_match('/^[a-zA-Z0-9\-\.]+$/', $_GET['mcversion'])) { + $mcversion=$_GET['mcversion']; + } + if (!empty($loadertype) && !empty($mcversion)) { + $modq = $db->query("SELECT * FROM mods WHERE type='forge' AND loadertype='{$loadertype}' AND ('{$mcversion}' LIKE mcversion || '%' OR mcversion LIKE '{$mcversion}' || '%')"); + } elseif (!empty($loadertype)) { + $modq = $db->query("SELECT * FROM mods WHERE type='forge' AND loadertype='{$loadertype}'"); + } elseif (!empty($mcversion)) { + $modq = $db->query("SELECT * FROM mods WHERE type='forge' AND '{$mcversion}' LIKE mcversion || '%'"); + } else { + $modq = $db->query("SELECT * FROM mods WHERE type='forge'"); } if ($modq) { foreach ($modq as $mod) { - if ($mod['type']!='mod') continue; $filesize = isset($mod['filesize']) ? $mod['filesize'] : 0; $modentry = [ 'id'=>$mod['id'], diff --git a/functions/package-fabric.php b/functions/add-modloader-fabric.php similarity index 71% rename from functions/package-fabric.php rename to functions/add-modloader-fabric.php index 34d1cf2..3fbed09 100644 --- a/functions/package-fabric.php +++ b/functions/add-modloader-fabric.php @@ -18,8 +18,12 @@ exit(); } +global $db; require_once("db.php"); -$db=new Db; +if (!isset($db)){ + $db=new Db; + $db->connect(); +} if (file_put_contents("../forges/modpack-".$version."/version.json", file_get_contents("https://meta.fabricmc.net/v2/versions/loader/".$mcversion."/".urlencode($version)."/profile/json"))) { $zip = new ZipArchive(); @@ -36,21 +40,34 @@ unlink("../forges/modpack-".$version."/version.json"); rmdir("../forges/modpack-".$version); $md5 = md5_file("../forges/fabric-".$version.".zip"); + $file_size=filesize("../forges/fabric-".$version.".zip"); $url = "http://".$config['host'].$config['dir']."forges/fabric-".urlencode($version).".zip"; - - $db->connect(); - $res = $db->execute("INSERT INTO `mods` (`name`,`pretty_name`,`md5`,`url`,`link`,`author`,`description`,`version`,`mcversion`,`filename`,`type`,`loadertype`) VALUES ('fabric','Fabric (alpha)','".$md5."','".$url."','https://fabricmc.net/','FabricMC Team', 'Fabric is a lightweight, experimental modding toolchain for Minecraft.', '".$version."','".$mcversion."','fabric-".$version.".zip','forge', 'fabric')"); - $db->disconnect(); - + $res = $db->execute("INSERT INTO `mods` (`name`,`pretty_name`,`md5`,`url`,`link`,`author`,`description`,`version`,`mcversion`,`filename`,`filesize`,`type`,`loadertype`) VALUES ( + 'fabric', + 'Fabric (alpha)', + '{$md5}', + '{$url}', + 'https://fabricmc.net/', + 'FabricMC Team', + 'Fabric is a lightweight, experimental modding toolchain for Minecraft.', + '{$version}', + '{$mcversion}', + 'fabric-{$version}.zip', + '{$file_size}', + 'forge', + 'fabric' + )"); if ($res) { - echo '{"status":"succ","message":"Mod has been saved."}'; + echo '{"status":"succ","message":"Loader has been saved.", "id": '.$db->insert_id().'}'; } else { - echo '{"status":"error","message":"Mod could not be added to database"}'; + echo '{"status":"error","message":"Loader could not be added to database"}'; } + } else { echo '{"status":"error","message":"File download failed."}'; unlink("../forges/modpack-".$version."/version.json"); rmdir("../forges/modpack-".$version); } +$db->disconnect(); exit(); \ No newline at end of file diff --git a/functions/add-modloader.php b/functions/add-modloader.php index 466c0be..bb32c1b 100644 --- a/functions/add-modloader.php +++ b/functions/add-modloader.php @@ -48,7 +48,7 @@ if (file_put_contents("../forges/modpack-".$version."/modpack.jar", file_get_contents($download_link))) { $zip = new ZipArchive(); - if ($zip->open("../forges/forge-".$version.".zip", ZIPARCHIVE::CREATE) !== true) { + if ($zip->open("../forges/".$type."-".$version.".zip", ZIPARCHIVE::CREATE) !== true) { echo '{"status":"error","message":"Could not open archive"}'; exit(); } @@ -60,10 +60,9 @@ $zip->close(); unlink("../forges/modpack-".$version."/modpack.jar"); rmdir("../forges/modpack-".$version); - $md5 = md5_file("../forges/forge-".$version.".zip"); - $filesize=filesize("../forges/forge-".$version.".zip"); - $url = "http://".$config['host'].$config['dir']."forges/forge-".$version.".zip"; - + $md5 = md5_file("../forges/".$type."-".$version.".zip"); + $file_size = filesize("../forges/".$type."-".$version.".zip"); + $url = "http://".$config['host'].$config['dir']."forges/".$type."-".$version.".zip"; $res = $db->execute(" INSERT INTO `mods` (`name`,`pretty_name`,`md5`,`url`,`link`,`author`,`description`,`version`,`mcversion`,`filename`,`filesize`,`type`,`loadertype`) VALUES ( @@ -76,23 +75,21 @@ '".$type_descriptions[$type]."', '".$version."', '".$mcversion."', - 'forge-".$version.".zip', - ".$filesize.", + '".$type."-".$version.".zip', + ".$file_size.", 'forge', '".$type."' ) "); - $id=$db->insert_id(); - if ($res) { - echo '{"status":"succ","message":"Mod has been saved.", "id":"'.$id.'"}'; + echo '{"status":"succ","message":"Loader has been saved.", "id":"'.$db->insert_id().'"}'; } else { - echo '{"status":"error","message":"Mod could not be added to database"}'; + echo '{"status":"error","message":"Loader could not be added to database"}'; } } else { echo '{"status":"error","message":"File download failed."}'; unlink("../forges/modpack-".$version."/modpack.jar"); rmdir("../forges/modpack-".$version); } - +$db->disconnect(); exit(); \ No newline at end of file diff --git a/index.php b/index.php index a67584d..c00b257 100644 --- a/index.php +++ b/index.php @@ -792,6 +792,7 @@ function uri($uri) { $_GET['name'] = $modpack['name']; ?> + +
-

Edit Modpack

+

Modpack details


- +
- +
type="checkbox" name="ispublic" class="custom-control-input" id="public"> - +

-
+ - -
+ +

+
+

Copy Build


@@ -1079,7 +1083,7 @@ function uri($uri) {
- +
@@ -1484,11 +1488,19 @@ function uri($uri) {
+
+

Mods

+
+ A mod is a file that does things to your game. All mods which rely on Forge, Neoforge, or Fabric are supported. +
Here, you can install mods from modrinth, or mods you've downloaded from somewhere else. +
Note you will need to install a mod loader before using a mod. +
+
-

Get mods - Modrinth

+

Modrinth


@@ -1691,7 +1703,6 @@ function uri($uri) { @@ -1756,55 +1767,68 @@ function uri($uri) { + +
+

Mod loaders

+
+ A mod loader is a mod that loads other mods. +
It is almost always required for your modpack, and must be added to a build before using any other mods. +
You can install loaders here, or, you can upload your own modpack.jar. +
+
+ -
+ -
- - --> +
+

Fabric



- + +
-
+ +
+

Forge

+
+ + +
@@ -1817,10 +1841,11 @@ function uri($uri) { +
-

Upload custom mod loader

+

Custom


@@ -1847,7 +1872,7 @@ function uri($uri) {
-

Mod loaders

+

Installed

File is too big! Check your post_max_size (current value '.ini_get('post_max_size').') and upload_max_filesize (current value '.ini_get('upload_max_filesize').') values in '.php_ini_loaded_file().''; } ?> @@ -1868,22 +1893,34 @@ function uri($uri) { query("SELECT id,name,mods FROM builds"); + $installed_loader_ids=[]; + if ($buildsq){ + foreach ($buildsq as $build){ + $mods=explode(',', $build['mods'],2); + // echo $mods[0]; + array_push($installed_loader_ids, $mods[0]); + } + } + + $used_loaders=[]; + $installed_loaders=[]; $mods = $db->query("SELECT * FROM `mods` WHERE `type` = 'forge' ORDER BY `id` DESC"); - $installed_mc_loaders=[]; if ($mods){ - foreach ($mods as $mod){ - if ($mod['loadertype']=='fabric') { - // fabric versioning is different - array_push($installed_mc_loaders, $mod['loadertype'].'-'.$mod['mcversion']); - } else { - array_push($installed_mc_loaders, $mod['loadertype'].'-'.$mod['version']); + foreach ($mods as $mod) { + if (in_array($mod['id'],$installed_loader_ids)) { + array_push($used_loaders, $mod['loadertype'].'-'.$mod['mcversion'].'-'.$mod['version']); } - ?> + array_push($installed_loaders, $mod['loadertype'].'-'.$mod['mcversion'].'-'.$mod['version']); + + $remove_box_str="{$mod['id']}, '{$mod['loadertype']}', '{$mod['mcversion']}', '{$mod['version']}', "; + ?> - + @@ -1946,7 +1990,7 @@ function uri($uri) {
-

Available Files

+

Files

diff --git a/resources/js/page_modloaders.js b/resources/js/page_modloaders.js index 2f826d4..8189e6b 100644 --- a/resources/js/page_modloaders.js +++ b/resources/js/page_modloaders.js @@ -1,10 +1,19 @@ -function remove_box(id,name) { - $("#mod-name-title").text(name); - $("#mod-name").text(name); - $("#remove-button").attr("onclick","remove("+id+",false)"); - $("#remove-button-force").attr("onclick","remove("+id+",true)"); +const CACHE_INSTALLER_TTL=3600; + +function remove_box(id,name,minecraft,version) { + if (used_loaders.includes(name+'-'+minecraft+'-'+version)) { + $("#mod-name-title").html(name+' (in use)'); + $("#mod-name").html(name+' (in use)'); + $("#remove-button").attr("onclick",`remove(${id},'${name}','${minecraft}','${version}',true)`); + $("#remove-button").text('Force delete') + } else { + $("#mod-name-title").text(name); + $("#mod-name").text(name); + $("#remove-button").attr("onclick",`remove(${id},'${name}','${minecraft}','${version}',false)`); + $("#remove-button").text('Delete') + } } -function remove(id,force) { +function remove(id,name,minecraft,version,force) { var request = new XMLHttpRequest(); request.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { @@ -12,12 +21,11 @@ function remove(id,force) { if (response['status']=='succ') { console.log('success!'); $("#mod-row-"+id).remove(); - } else { - // todo: use styled alert instead of this - // alert("Cannot delete modloader as it is used by a build."); - // $("#removeModWarn").show(); - if (confirm(response['message']+" Press OK to go to '"+response['bname']+"'")) { - window.location.href="/build?id="+response['bid']; + if (used_loaders.includes(name+'-'+minecraft+'-'+version)) { + const index = used_loaders.indexOf(name+'-'+minecraft+'-'+version); + if (index > -1) { + used_loaders.splice(index, 1); + } } } } @@ -28,7 +36,7 @@ function remove(id,force) { } // Fabric Download -let download = () => { +let download_fabric = () => { let minecraft = $("#ver").children("option:selected").val(); let version = $("#lod").children("option:selected").val(); if ($("#ver").children("option:selected").attr("disabled")!==undefined && $("#ver").children("option:selected").attr("disabled")!==false) { @@ -37,89 +45,128 @@ let download = () => { $("#sub-button").attr("disabled","true") $("#sub-button")[0].innerHTML = "" let packager = new XMLHttpRequest(); - packager.open('GET', './functions/package-fabric.php?version='+encodeURIComponent(minecraft)+"&loader="+encodeURIComponent(version)) + packager.open('GET', './functions/add-modloader-fabric.php?version='+encodeURIComponent(minecraft)+"&loader="+encodeURIComponent(version)) packager.onreadystatechange = () => { if (packager.readyState === 4) { if (packager.status === 200) { + console.log(packager.response) parsed = JSON.parse(packager.response) if (parsed["status"] === "succ") { - // $("#sub-button")[0].classList.remove("btn-primary") - // $("#sub-button")[0].classList.add("btn-success") - // $("#sub-button")[0].innerHTML = " Please reload the page." - // window.location.reload(); - $("#ver").children("option:selected").attr("disabled",true); - // $("#ver").children("option:selected").innerHTML=$("#ver").children("option:selected").innerHTML+" (installed)"; $("#sub-button")[0].innerHTML = "Install"; - - add_item(minecraft, version, 'fabric', parsed['id']); - - // $("#lod").children("option:selected").attr("disabled",true); - // $("#ver").next().attr("selected","selected"); + add_item(parsed['id'], 'fabric', minecraft, version); + $('#installfabricinfo').addClass('text-success') + $('#installfabricinfo').removeClass('text-danger') + installed_loaders.push('fabric-'+minecraft+'-'+parsed['version']) + $('#ver option:selected').attr('disabled',true); + } else { + $('#installfabricinfo').addClass('text-danger') + $('#installfabricinfo').removeClass('text-success') } - // $("#fetch-forge").removeAttr("disabled"); - // $("#fetch-neoforge").removeAttr("disabled"); $("#sub-button").removeAttr("disabled"); + $('#installfabricinfo').html(parsed['message']) + $('#installfabricinfo').show() } } } packager.send() } } + // Fetch Fabric Versions -let fetchfabric = () => { - $("#fetch-fabric").attr("disabled",true) - // $("#fetch-forge").attr("disabled",true) - // $("#fetch-neoforge").attr("disabled",true) - $("#fetch-fabric").html("Loading...") - let versions = new XMLHttpRequest() - let loaders = new XMLHttpRequest() - versions.open('GET','https://meta.fabricmc.net/v2/versions/game') - loaders.open('GET','https://meta.fabricmc.net/v2/versions/loader') - versions.onreadystatechange = () => { - if (versions.readyState === 4) { - if (versions.status === 200) { - response = JSON.parse(versions.response) - for (key in response) { - if (response[key]["stable"]) { - if (!installed_mc_loaders.includes('fabric-'+response[key]["version"])) { - ver = document.createElement("option") - ver.text = response[key]["version"] - ver.value = response[key]["version"] - $("#ver")[0].add(ver) - installed_mc_loaders.push('fabric-'+response[key]["version"]); - } - } +async function fetch_fabric() { + async function fetch_versions() { + return new Promise((resolve, reject) => { + let versions = new XMLHttpRequest() + versions.open('GET','https://meta.fabricmc.net/v2/versions/game') + versions.onreadystatechange = () => { + if (versions.readyState === 4) { + if (versions.status === 200) { + set_cached('installer_fabric_versions', versions.response, CACHE_INSTALLER_TTL) + resolve(versions.response) + return versions.response + } } } - } + versions.onerror = function() { + resolve([]); + }; + versions.send() + }); } - loaders.onreadystatechange = () => { - if (loaders.readyState === 4) { - if (loaders.status === 200) { - response = JSON.parse(loaders.response) - for (key in response) { - if (response[key]["stable"]) { - ver = document.createElement("option") - ver.text = response[key]["version"] - ver.value = response[key]["version"] - $("#lod")[0].add(ver) + async function fetch_loaders() { + return new Promise((resolve, reject) => { + let loaders = new XMLHttpRequest() + loaders.open('GET','https://meta.fabricmc.net/v2/versions/loader') + loaders.onreadystatechange = () => { + if (loaders.readyState === 4) { + if (loaders.status === 200) { + set_cached('installer_fabric_loaders', loaders.response, CACHE_INSTALLER_TTL) + // response = JSON.parse(loaders.response) + resolve(loaders.response) + return loaders.response } } - $("#fetch-fabric").html("Show Fabric Installer") - $("#fabrics")[0].style.display = "flex"; + } + loaders.onerror = function() { + resolve([]) + } + loaders.send() + }); + } + + if (get_cached('installer_fabric_versions')) { + var versions=JSON.parse(get_cached('installer_fabric_versions')); + } else { + var versions=JSON.parse(await fetch_versions()); + } + if (get_cached('installer_fabric_loaders')) { + var loaders=JSON.parse(get_cached('installer_fabric_loaders')); + } else { + var loaders=JSON.parse(await fetch_loaders()); + } + + versions = versions.filter((v) => v['stable'] == true); + loaders = loaders.filter((v) => v['stable'] == true); + + let merged = versions.map((v, i) => [v['version'], loaders[0]['version']]); + + for (v of merged) { + let minecraft=v[0]; + let loader=v[1] + // console.log($("#ver")[0]) + if (!installed_loaders.includes('fabric-'+minecraft+'-'+loader)) { + if ($(`#lod option[value='${loader}']`).length == 0) { + lod = document.createElement("option") + lod.text = loader + lod.value = loader + $("#lod")[0].add(lod) + } + if ($(`#ver option[value='${minecraft}']`).length == 0) { + mcv = document.createElement("option") + mcv.text = minecraft + mcv.value = minecraft + $("#ver")[0].add(mcv) } } + } - loaders.send() - versions.send() + + $('#sub-button').attr('disabled',false); + $('#sub-button').text('Install'); + $("#fetch-fabric").html("Show Fabric Installer") + $("#fabrics")[0].style.display = "flex"; + + } +// neoforge download let download_neoforge = () => { let VERSIONS_ENDPOINT = 'https://maven.neoforged.net/api/maven/versions/releases/' let FORGE_GAV = 'net/neoforged/neoforge' let DOWNLOAD_URL = 'https://maven.neoforged.net/releases' let version = $("#lod-neoforge").children("option:selected").val(); + // let minecraft = $("#ver-neoforge").children("option:selected").val(); let minecraft = "1."+version.slice(0,version.lastIndexOf('.')); let download_link = `${DOWNLOAD_URL}/${FORGE_GAV}/${encodeURIComponent(version)}/neoforge-${encodeURIComponent(version)}-installer.jar`; @@ -129,7 +176,7 @@ let download_neoforge = () => { return; } else { $("#sub-button-neoforge").attr("disabled","true") - $("#sub-button-neoforge-message").hide(); + $("#installneoforgeinfo").hide(); $("#sub-button-neoforge")[0].innerHTML = "" let packager = new XMLHttpRequest(); @@ -140,26 +187,27 @@ let download_neoforge = () => { console.log(packager.response); parsed = JSON.parse(packager.response) if (parsed["status"] === "succ") { - // $("#sub-button-neoforge")[0].classList.remove("btn-primary") - // $("#sub-button-neoforge")[0].classList.add("btn-success") - // $("#sub-button-neoforge")[0].innerHTML = " Please reload the page." - // window.location.reload(); $("#lod-neoforge").children("option:selected").attr("disabled",true); $("#lod-neoforge").children("option:selected").innerHTML=$("#lod-neoforge").children("option:selected").innerHTML+" (installed)"; $("#sub-button-neoforge")[0].innerHTML = "Install"; - add_item(minecraft, version, 'neoforge', parsed['id']); + add_item(parsed['id'], 'neoforge', minecraft, version); $("#lod-neoforge").next().attr("selected","selected"); + $('#installneoforgeinfo').addClass('text-success'); + $('#installneoforgeinfo').removeClass('text-danger'); + installed_loaders.push('neoforge-'+minecraft+'-'+parsed['version']) } else { $("#sub-button-neoforge").removeAttr("disabled") - $("#sub-button-neoforge-message").show(); - $("#sub-button-neoforge-message")[0].innerHTML = parsed["message"]; + $("#installneoforgeinfo").show(); + $("#installneoforgeinfo")[0].innerHTML = parsed["message"]; $("#lod-neoforge").children("option:selected").attr("disabled",true); $("#sub-button-neoforge")[0].innerHTML = "Install" + $('#installneoforgeinfo').addClass('text-danger'); + $('#installneoforgeinfo').removeClass('text-success'); } - // $("#fetch-forge").removeAttr("disabled"); - // $("#fetch-fabric").removeAttr("disabled"); $("#sub-button-neoforge").removeAttr("disabled") + $('#installneoforgeinfo').html(parsed['message']) + $('#installneoforgeinfo').show(); } } } @@ -168,10 +216,35 @@ let download_neoforge = () => { } // Fetch Neoforge Versions let fetch_neoforge = () => { - // $("#fetch-fabric").attr("disabled",true) - // $("#fetch-forge").attr("disabled",true) + function parse_versions(versions) { + for (key in versions) { + let loader = versions[key] + let minecraft = '1.'+loader.substring(0, loader.lastIndexOf('.')); + if (!installed_loaders.includes('neoforge-'+minecraft+'-'+loader)) { + if ($(`#lod-neoforge option[value='${loader}']`).length == 0) { + lod = document.createElement("option") + lod.text = minecraft+' - '+loader; + lod.value = loader + $("#lod-neoforge")[0].add(lod) + } + + // if ($(`#ver-neoforge option[value='${minecraft}']`).length == 0) { + // ver = document.createElement("option") + // ver.text = minecraft; + // ver.value = minecraft + // $("#ver-neoforge")[0].add(ver) + // } + } + } + $('#sub-button-neoforge').attr('disabled',false); + $('#sub-button-neoforge').text('Install'); + } $("#fetch-neoforge").attr("disabled",true) $("#fetch-neoforge").html("Loading...") + if (get_cached('installer_neoforge_versions')) { + let versions=JSON.parse(get_cached('installer_neoforge_versions')); + parse_versions(versions); + } let loaders = new XMLHttpRequest() loaders.open('GET','https://maven.neoforged.net/api/maven/versions/releases/net/neoforged/neoforge') loaders.onreadystatechange = () => { @@ -180,18 +253,9 @@ let fetch_neoforge = () => { response = JSON.parse(loaders.response) if (response["versions"]) { let versions = response["versions"].reverse(); - for (key in versions) { - let value = versions[key] - // if (!value.endsWith("-beta")) { - if (!installed_mc_loaders.includes('neoforge-'+value)) { - ver = document.createElement("option") - ver.text = '1.'+value.substring(0, value.lastIndexOf('.'))+' - '+value; - ver.value = value - $("#lod-neoforge")[0].add(ver) - installed_mc_loaders.push('neoforge-'+value); - } - // } - } + versions = versions.filter((v) => !v.endsWith('beta')); + set_cached('installer_neoforge_versions', JSON.stringify(versions), CACHE_INSTALLER_TTL) // 1 hour + parse_versions(versions); } $("#fetch-neoforge").html("Show Neoforge Installer"); $("#neoforges")[0].style.display = "flex"; @@ -201,12 +265,12 @@ let fetch_neoforge = () => { loaders.send() } -// add forge version -function add(v,link,mcv,id) { +// download forge version +function download_forge(id,minecraft,version,link) { $("#button-add-"+id).attr("disabled",true); $("#cog-"+id).show(); var request = new XMLHttpRequest(); - request.open('GET', './functions/add-modloader.php?type=forge&version='+v+'&dl='+link+'&mcversion='+mcv); + request.open('GET', './functions/add-modloader.php?type=forge&version='+version+'&dl='+link+'&mcversion='+minecraft); request.onreadystatechange = function() { if (request.readyState == 4) { if (request.status == 200) { @@ -216,12 +280,17 @@ function add(v,link,mcv,id) { $("#fetch-neoforge").removeAttr("disabled"); if (response['status']=="succ") { $("#check-"+id).show(); - add_item(mcv,v,'forge',response['id']); + add_item(response['id'], 'forge', minecraft, version); + $("#installforgeinfo").addClass('text-success'); + $("#installforgeinfo").removeClass('text-danger'); + installed_loaders.push('forge-'+minecraft+'-'+version) } else { $("#times-"+id).show(); - $("#info").text(response['message']); + $("#installforgeinfo").addClass('text-danger'); + $("#installforgeinfo").removeClass('text-success'); } - + $("#installforgeinfo").text(response['message']); + $("#installforgeinfo").show(); } } } @@ -232,93 +301,108 @@ const forge_link = "https://maven.minecraftforge.net/net/minecraftforge/forge"; // Fetch forge versions async function fetch_forges() { - $("#fetch-forge").attr("disabled", true); - // $("#fetch-fabric").attr("disabled", true); - // $("#fetch-neoforge").attr("disabled",true); - $("#fetch-forge").html("Loading..."); - var request = new XMLHttpRequest(); - request.open('GET', './functions/forge-links.php'); - request.onreadystatechange = async function() { - if (request.readyState == 4 && request.status == 200) { - response = JSON.parse(this.response); - - response = Object.fromEntries( - Object.entries(response).reverse() - ); - - $("#fetched-mods").show(); + async function verify_link_then_add(id,minecraft,version,link) { + console.log('verifying '+link) + // check each version and then add it to list + return new Promise((resolve, reject) => { + fetch(link, { method:'HEAD' }) + .then(response=> { + if (response.status == 404) { + reject(id); + } else if (response.status == 200) { + $("#forge-table").append(` + + + + + + + `); + resolve(true); + } + }) + .catch(error=>{ + reject(false); + }); + }).catch(error=>{ + reject(false); + }); + } + async function parse_versions(response){ + if (get_cached('installer_forge_versions')) { + let response=JSON.parse(get_cached('installer_forge_versions')); + for (var key in response) { + console.log(response[key]) + await verify_link_then_add(response[key]["id"], response[key]["mc"], response[key]['name'], response[key]["link"]); + } + } else { + let valid=[]; console.log("ignore 404s, they're supposed to be suppressed/catched with onerror") - let onesix_404ed=false; + let onesix_worked=false; for (var key in response) { - // if below problematic version 1.6.1, AND we couldn't get 1.6.1, skip the rest - if (compareVersions(key,'1.6.0')<0 && onesix_404ed) { - continue; - } else { - try { - await chf(response[key]["link"],response[key]["name"],response[key]["id"],response[key]["mc"]); - } catch (e) { - console.log(`ignoring 404 #4: '${key}'`); - if (compareVersions(key,'1.6.0')<0) { - onesix_404ed=true; + if (!installed_loaders.includes('forge-'+response[key]['minecraft']+'-'+response[key]['name'])) { + if (onesix_worked || compareVersions(key,'1.6.0')>0) { + // if 1.6.0 worked, or we are above 1.6.0 + try { + let isvalid = await verify_link_then_add(response[key]['id'], response[key]['name'], response[key]['mc'], response[key]['link']); + if (isvalid) { + valid.push(response[key]); + if (compareVersions(key,'1.6.0')<0) { + onesix_worked=false; + } + } + } catch (e) { + if (compareVersions(key,'1.6.0')<0) { + onesix_worked=false; + } } } } } - - $("#fetch-forge").html("Show Forge Installer"); - // $("#fetch-forge").removeAttr("disabled"); - // $("#fetch-fabric").removeAttr("disabled"); - // $("#fetch-neoforge").removeAttr("disabled"); + set_cached('installer_forge_versions', JSON.stringify(valid), CACHE_INSTALLER_TTL); } + $("#fetch-forge").hide(); } - - request.send(); -} -// add item to installer list -async function chf(link,name,id,mc) { - return new Promise((resolve, reject) => { - fetch(link, { method:'HEAD' }) - .then(response=> { - if (response.status == 404) { - // console.log('ignoring 404 #1'); - reject(id); - } else if (response.status == 200) { - $("#forge-table").append(` - - - - - - - `); - resolve(id); + $("#fetch-forge").attr("disabled", true); + $("#fetch-forge").html("Loading..."); + $("#table-fetched-mods").show(); + + if (get_cached('installer_forge_versions')) { + let response=JSON.parse(get_cached('installer_forge_versions')); + parse_versions(response); + } else { + var request = new XMLHttpRequest(); + request.open('GET', './functions/forge-links.php'); + request.onreadystatechange = async function() { + if (request.readyState == 4 && request.status == 200) { + response = JSON.parse(this.response); + response = Object.fromEntries(Object.entries(response).reverse()); + // cached in parse_versions + parse_versions(response); } - }) - .catch(error=>{ - // console.log('ignoring 404 #2'); - reject(id); - }); - }).catch(error=>{ - // console.log('ignoring 404 #3'); - reject(id); - }); + } + + request.send(); + } } // add item to installed list -function add_item(minecraft,version,type,dbid) { +function add_item(id,name,minecraft,version) { let item = $('', { - id: 'mod-row-'+dbid, + id: 'mod-row-'+id, html: ` - - - ` + + + ` }); $("#forge-available").append(item); } $(document).ready(function(){ $("#nav-mods").trigger('click'); + fetch_fabric() + fetch_neoforge() }); \ No newline at end of file
${minecraft}${version}${link}
${mc}${name}${link}
${minecraft} ${version}${type}${name}