From 10de5248f3f1f9db4a1b27047dcf8d028f8ea6f4 Mon Sep 17 00:00:00 2001
From: Henry Gross-Hellsen <6283258+cowpod@users.noreply.github.com>
Date: Wed, 13 Nov 2024 01:43:57 -0800
Subject: [PATCH] modrinth integration (plus md support), dynamic ui changes
---
functions/add-modv.php | 64 ++-
index.php | 138 ++++--
resources/js/marked.min.js | 6 +
.../{page_add-mods.js => page_add-remote.js} | 0
resources/js/page_lib-mods.js | 413 +++++++++++++++++-
resources/js/page_mod.js | 2 +-
6 files changed, 563 insertions(+), 60 deletions(-)
create mode 100644 resources/js/marked.min.js
rename resources/js/{page_add-mods.js => page_add-remote.js} (100%)
diff --git a/functions/add-modv.php b/functions/add-modv.php
index e58935e..283e75c 100644
--- a/functions/add-modv.php
+++ b/functions/add-modv.php
@@ -2,32 +2,35 @@
session_start();
if (empty($_POST['pretty_name'])) {
- die("Name not specified.");
+ die('{"status":"error","message":"Pretty name not specified."}');
}
if (empty($_POST['name'])) {
- die("Slug not specified.");
+ die('{"status":"error","message":"Slug not specified."}');
}
if (empty($_POST['version'])) {
- die("Version not specified.");
+ die('{"status":"error","message":"Version not specified."}');
}
if (empty($_POST['url'])) {
- die("URL not specified.");
+ die('{"status":"error","message":"File URL not specified."}');
}
if (empty($_POST['md5'])) {
- die("Md5 not specified.");
+ die('{"status":"error","message":"MD5 not specified."}');
+}
+if (empty($_POST['filesize'])) {
+ die('{"status":"error","message":"Filesize not specified."}');
}
if (empty($_POST['mcversion'])) {
- die("Minecraft version not specified.");
+ die('{"status":"error","message":"Minecraft version not specified."}');
}
if (empty($_POST['loadertype'])) {
- die("Loader type not specified.");
+ die('{"status":"error","message":"Loader type not specified."}');
}
if (!$_SESSION['user']||$_SESSION['user']=="") {
- die("Unauthorized request or login session has expired!");
+ die('{"status":"error","message":"Unauthorized request or login session has expired!"}');
}
if (substr($_SESSION['perms'], 3, 1)!=="1") {
- die("Insufficient permission!");
+ die('{"status":"error","message":"Insufficient permission!"}');
}
$config = require("./config.php");
@@ -38,26 +41,39 @@
$db->connect();
}
+$name = $db->sanitize($_POST['name']);
+$md5 = $db->sanitize($_POST['md5']);
+$filesize = $db->sanitize($_POST['filesize']);
$link = isset($_POST['link']) ? $db->sanitize($_POST['link']) : '';
$auth = isset($_POST['author']) ? $db->sanitize($_POST['author']) : '';
$desc = isset($_POST['description']) ? $db->sanitize($_POST['description']) : '';
$donlink = isset($_POST['donlink']) ? $db->sanitize($_POST['donlink']) : '';
-$db->execute("INSERT INTO `mods`
- (`name`, `pretty_name`, `md5`, `url`, `link`, `author`, `donlink`, `description`, `version`, `mcversion`, `type`, `loadertype`) VALUES (
- '".$db->sanitize($_POST['name'])."',
- '".$db->sanitize($_POST['pretty_name'])."',
- '".$db->sanitize($_POST['md5'])."',
- '".$db->sanitize($_POST['url'])."',
- '".$link."',
- '".$auth."',
- '".$donlink."',
- '".$desc."',
- '".$db->sanitize($_POST['version'])."',
- '".$db->sanitize($_POST['mcversion'])."',
+// we use name (slug) and md5 to determine if its already installed.
+// since we have md5. otherwise we should check version,mcversion,name/slug,type,loadertype
+$existsq = $db->query("SELECT 1 FROM mods WHERE name='{$name}' AND md5='{$md5}'");
+if ($existsq && sizeof($existsq)>=1) {
+ die('{"status":"succ","message":"Mod is already added."}');
+}
+
+$addq = $db->execute("INSERT INTO `mods`
+ (`name`, `pretty_name`, `md5`, `filesize`, `url`, `link`, `author`, `donlink`, `description`, `version`, `mcversion`, `type`, `loadertype`) VALUES (
+ '{$name}',
+ '{$db->sanitize($_POST['pretty_name'])}',
+ '{$md5}',
+ '{$filesize}',
+ '{$db->sanitize($_POST['url'])}',
+ '{$link}',
+ '{$auth}',
+ '{$donlink}',
+ '{$desc}',
+ '{$db->sanitize($_POST['version'])}',
+ '{$db->sanitize($_POST['mcversion'])}',
'mod',
- '".$db->sanitize($_POST['loadertype'])."',
+ '{$db->sanitize($_POST['loadertype'])}'
)");
+if ($addq) {
+ die('{"status":"succ","message":"Mod successfully added."}');
+}
-header("Location: ".$config['dir']."lib-mods");
-exit();
+die('{"status":"error","message":"Could not add mod."}');
diff --git a/index.php b/index.php
index 9dcbb5b..4eea14d 100644
--- a/index.php
+++ b/index.php
@@ -123,6 +123,7 @@ function uri($uri) {
+
@@ -1328,17 +1329,18 @@ function uri($uri) {
}
?>
-
id="mod-">
+
id="mod-">
: Mod does not exist! Please remove from this build.';
- } elseif (!$userModVersionOK) {
- echo ': For Minecraft '.$mod['mcversion'].', you have '.$user['minecraft'].'. May not be compatible!';
} elseif(empty($mod['version'])) {
echo ': Missing version! You must set it in mod details.';
+ } elseif(empty($mod['mcversion'])) {
+ echo ': Missing mcversion! You must set it in mod details.';
+ } elseif (!$userModVersionOK) {
+ echo ': For Minecraft '.$mod['mcversion'].', you have '.$user['minecraft'].'. May not be compatible!';
}
-
?>
query("SELECT * FROM mods WHERE type = 'mod' AND loadertype = '".$loadertype."'");
// todo: use a group-by?
@@ -1478,8 +1478,8 @@ function uri($uri) {
foreach ($version_details as $vals) {
[$id,$version,$mcversion] = $vals;
if (in_range($mcversion, $user['minecraft'])|| (!empty($_SESSION['showall']) && $_SESSION['showall'])) {
- if (empty($version)) {
- echo "";
+ if (empty($version) || empty($mcversion)) {
+ echo "";
$num_missing_version+=1;
} else {
echo "";
@@ -1495,7 +1495,11 @@ function uri($uri) {
-
+
query("SELECT * FROM `mods` WHERE `type` = 'mod' ORDER BY `id` DESC");
if ($mods){
@@ -1641,8 +1728,8 @@ function uri($uri) {
foreach ($modsi as $mod) {
?>
-
-
Unknown"; } ?>
+
>Unknown" : $mod['pretty_name'] ?>
+
>Unknown"; } ?>
@@ -1684,7 +1771,7 @@ function uri($uri) {
-
+
+
@@ -1758,10 +1846,10 @@ function uri($uri) {
\n`}tablecell(e){const t=this.parser.parseInline(e.tokens),n=e.header?"th":"td";return(e.align?`<${n} align="${e.align}">`:`<${n}>`)+t+`${n}>\n`}strong({tokens:e}){return`${this.parser.parseInline(e)}`}em({tokens:e}){return`${this.parser.parseInline(e)}`}codespan({text:e}){return`${G(e,!0)}`}br(e){return" "}del({tokens:e}){return`${this.parser.parseInline(e)}`}link({href:e,title:t,tokens:n}){const s=this.parser.parseInline(n),r=H(e);if(null===r)return s;let i='"+s+"",i}image({href:e,title:t,text:n}){const s=H(e);if(null===s)return G(n);let r=`",r}text(e){return"tokens"in e&&e.tokens?this.parser.parseInline(e.tokens):"escaped"in e&&e.escaped?e.text:G(e.text)}}class W{strong({text:e}){return e}em({text:e}){return e}codespan({text:e}){return e}del({text:e}){return e}html({text:e}){return e}text({text:e}){return e}link({text:e}){return""+e}image({text:e}){return""+e}br(){return""}}class Y{options;renderer;textRenderer;constructor(t){this.options=t||e.defaults,this.options.renderer=this.options.renderer||new V,this.renderer=this.options.renderer,this.renderer.options=this.options,this.renderer.parser=this,this.textRenderer=new W}static parse(e,t){return new Y(t).parse(e)}static parseInline(e,t){return new Y(t).parseInline(e)}parse(e,t=!0){let n="";for(let s=0;s{const r=e[s].flat(1/0);n=n.concat(this.walkTokens(r,t))})):e.tokens&&(n=n.concat(this.walkTokens(e.tokens,t)))}}return n}use(...e){const t=this.defaults.extensions||{renderers:{},childTokens:{}};return e.forEach((e=>{const n={...e};if(n.async=this.defaults.async||n.async||!1,e.extensions&&(e.extensions.forEach((e=>{if(!e.name)throw new Error("extension name required");if("renderer"in e){const n=t.renderers[e.name];t.renderers[e.name]=n?function(...t){let s=e.renderer.apply(this,t);return!1===s&&(s=n.apply(this,t)),s}:e.renderer}if("tokenizer"in e){if(!e.level||"block"!==e.level&&"inline"!==e.level)throw new Error("extension level must be 'block' or 'inline'");const n=t[e.level];n?n.unshift(e.tokenizer):t[e.level]=[e.tokenizer],e.start&&("block"===e.level?t.startBlock?t.startBlock.push(e.start):t.startBlock=[e.start]:"inline"===e.level&&(t.startInline?t.startInline.push(e.start):t.startInline=[e.start]))}"childTokens"in e&&e.childTokens&&(t.childTokens[e.name]=e.childTokens)})),n.extensions=t),e.renderer){const t=this.defaults.renderer||new V(this.defaults);for(const n in e.renderer){if(!(n in t))throw new Error(`renderer '${n}' does not exist`);if(["options","parser"].includes(n))continue;const s=n,r=e.renderer[s],i=t[s];t[s]=(...e)=>{let n=r.apply(t,e);return!1===n&&(n=i.apply(t,e)),n||""}}n.renderer=t}if(e.tokenizer){const t=this.defaults.tokenizer||new J(this.defaults);for(const n in e.tokenizer){if(!(n in t))throw new Error(`tokenizer '${n}' does not exist`);if(["options","rules","lexer"].includes(n))continue;const s=n,r=e.tokenizer[s],i=t[s];t[s]=(...e)=>{let n=r.apply(t,e);return!1===n&&(n=i.apply(t,e)),n}}n.tokenizer=t}if(e.hooks){const t=this.defaults.hooks||new ee;for(const n in e.hooks){if(!(n in t))throw new Error(`hook '${n}' does not exist`);if(["options","block"].includes(n))continue;const s=n,r=e.hooks[s],i=t[s];ee.passThroughHooks.has(n)?t[s]=e=>{if(this.defaults.async)return Promise.resolve(r.call(t,e)).then((e=>i.call(t,e)));const n=r.call(t,e);return i.call(t,n)}:t[s]=(...e)=>{let n=r.apply(t,e);return!1===n&&(n=i.apply(t,e)),n}}n.hooks=t}if(e.walkTokens){const t=this.defaults.walkTokens,s=e.walkTokens;n.walkTokens=function(e){let n=[];return n.push(s.call(this,e)),t&&(n=n.concat(t.call(this,e))),n}}this.defaults={...this.defaults,...n}})),this}setOptions(e){return this.defaults={...this.defaults,...e},this}lexer(e,t){return K.lex(e,t??this.defaults)}parser(e,t){return Y.parse(e,t??this.defaults)}parseMarkdown(e){return(t,n)=>{const s={...n},r={...this.defaults,...s},i=this.onError(!!r.silent,!!r.async);if(!0===this.defaults.async&&!1===s.async)return i(new Error("marked(): The async option was set to true by an extension. Remove async: false from the parse options object to return a Promise."));if(null==t)return i(new Error("marked(): input parameter is undefined or null"));if("string"!=typeof t)return i(new Error("marked(): input parameter is of type "+Object.prototype.toString.call(t)+", string expected"));r.hooks&&(r.hooks.options=r,r.hooks.block=e);const l=r.hooks?r.hooks.provideLexer():e?K.lex:K.lexInline,o=r.hooks?r.hooks.provideParser():e?Y.parse:Y.parseInline;if(r.async)return Promise.resolve(r.hooks?r.hooks.preprocess(t):t).then((e=>l(e,r))).then((e=>r.hooks?r.hooks.processAllTokens(e):e)).then((e=>r.walkTokens?Promise.all(this.walkTokens(e,r.walkTokens)).then((()=>e)):e)).then((e=>o(e,r))).then((e=>r.hooks?r.hooks.postprocess(e):e)).catch(i);try{r.hooks&&(t=r.hooks.preprocess(t));let e=l(t,r);r.hooks&&(e=r.hooks.processAllTokens(e)),r.walkTokens&&this.walkTokens(e,r.walkTokens);let n=o(e,r);return r.hooks&&(n=r.hooks.postprocess(n)),n}catch(e){return i(e)}}}onError(e,t){return n=>{if(n.message+="\nPlease report this to https://github.com/markedjs/marked.",e){const e="
An error occurred:
"+G(n.message+"",!0)+"
";return t?Promise.resolve(e):e}if(t)return Promise.reject(n);throw n}}}const ne=new te;function se(e,t){return ne.parse(e,t)}se.options=se.setOptions=function(e){return ne.setOptions(e),se.defaults=ne.defaults,n(se.defaults),se},se.getDefaults=t,se.defaults=e.defaults,se.use=function(...e){return ne.use(...e),se.defaults=ne.defaults,n(se.defaults),se},se.walkTokens=function(e,t){return ne.walkTokens(e,t)},se.parseInline=ne.parseInline,se.Parser=Y,se.parser=Y.parse,se.Renderer=V,se.TextRenderer=W,se.Lexer=K,se.lexer=K.lex,se.Tokenizer=J,se.Hooks=ee,se.parse=se;const re=se.options,ie=se.setOptions,le=se.use,oe=se.walkTokens,ae=se.parseInline,ce=se,he=Y.parse,pe=K.lex;e.Hooks=ee,e.Lexer=K,e.Marked=te,e.Parser=Y,e.Renderer=V,e.TextRenderer=W,e.Tokenizer=J,e.getDefaults=t,e.lexer=pe,e.marked=se,e.options=re,e.parse=ce,e.parseInline=ae,e.parser=he,e.setOptions=ie,e.use=le,e.walkTokens=oe}));
diff --git a/resources/js/page_add-mods.js b/resources/js/page_add-remote.js
similarity index 100%
rename from resources/js/page_add-mods.js
rename to resources/js/page_add-remote.js
diff --git a/resources/js/page_lib-mods.js b/resources/js/page_lib-mods.js
index ade69ed..97088b7 100644
--- a/resources/js/page_lib-mods.js
+++ b/resources/js/page_lib-mods.js
@@ -1,3 +1,5 @@
+const SEARCH_LIMIT=20;
+
function remove_box(name) {
$("#mod-name-title").text(name);
$("#mod-name").text(name);
@@ -91,14 +93,15 @@ function sendFile(file, i) {
break;
}
}
- let num_versions = response['modid'].length;
- let author = response['author'];
- let name = response['name'];
- let pretty_name = response['pretty_name'];
- let mcversion = response['mcversion'];
- let version = response['version'];
+
// console.log(response['status']);
if (response['status']!="error") {
+ let num_versions = response['modid'].length;
+ let author = response['author'];
+ let name = response['name'];
+ let pretty_name = response['pretty_name'];
+ let mcversion = response['mcversion'];
+ let version = response['version'];
// console.log('add new row');
let i=0;
// for (let id of response['modid']) {
@@ -155,7 +158,390 @@ $("#search").on('keyup',function(){
function showFile(file, i) {
$("#table-mods").append('
' + file.name + '
');
}
+
+
+var results={};
+var details={};
+var versions={};
+var installed=null;
+
+function addrow(hit) {
+ let description = hit['description'];
+ if (description.length>80) {
+ description = description.substring(0,200)+"...";
+ }
+ let categories = hit['display_categories'].join(', ');
+ if (categories.length>40) {
+ categories = categories.substring(0,40)+"...";
+ }
+
+ let author = hit['author'];
+ let instv=is_installed(hit['title']);
+ if (instv) {
+ if (instv['mcversion']==''||instv['version']=='') {
+ var btn=`Issue(s)`;
+ } else {
+ var btn = `Installed`;
+ }
+ } else {
+ var btn = `Install`;
+ }
+ var row = `
+