Skip to content

Commit

Permalink
Add fabric support
Browse files Browse the repository at this point in the history
  • Loading branch information
TheBlueBurger committed Aug 26, 2024
1 parent 6a74dbe commit c7f3866
Show file tree
Hide file tree
Showing 9 changed files with 63 additions and 45 deletions.
4 changes: 3 additions & 1 deletion Server/src/db/json.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// I am really sorry for writing this absolute mess
// It works, so please do not touch it.
// unrecommended for large servers
import DatabaseProvider, { Collection, DatabaseLookupFilter, DatabaseObject, DatabaseSchema, DatabaseSchemaInnerType, DatabaseType } from "./databaseProvider.js"
import path from "node:path";
Expand Down Expand Up @@ -234,4 +236,4 @@ export class JSONCollection<T extends DatabaseType> extends Collection<T> {
}
await obj.save();
}
}
}
13 changes: 7 additions & 6 deletions Server/src/packets/plugins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export default class Plugins extends Packet {
case "search":
if(typeof data.query != "string") return "No query";
logger.log(`${client.data.auth.user?.username} is searching for plugin '${data.query}' in ${server.name}`, "debug", LogLevel.DEBUG, false);
let searchResults = await search(data.query, server.version);
let searchResults = await search(data.query, server.version, server.software);
return {
type: "searchResults",
results: searchResults?.hits as ModrinthPluginResult[]
Expand All @@ -35,7 +35,7 @@ export default class Plugins extends Packet {
case "versions":
if(typeof data.slug != "string") return "No slug";
logger.log(`${client.data.auth.user?.username} is viewing versions for plugin ${data.slug} in ${server.name}`, "debug", LogLevel.DEBUG, false);
let pluginVersions = await getVersions(data.slug, server.version);
let pluginVersions = await getVersions(data.slug, server.version, server.software);
return {
type: "pluginVersions",
versions: pluginVersions
Expand All @@ -45,18 +45,19 @@ export default class Plugins extends Packet {
if(typeof data.hash != "string") return "No sha512";
let file = await getFile(data.version, data.hash);
if(!file) return "File isnt found";
if(!await exists(server.path + "/plugins")) await fs.mkdir(server.path + "/plugins");
if(await exists(server.path + "/plugins/" + file.filename)) return "Already installed!";
let pluginFolderName = server.software == "fabric" ? "/mods/" : "/plugins/";
if(!await exists(server.path + pluginFolderName)) await fs.mkdir(server.path + pluginFolderName);
if(await exists(server.path + pluginFolderName + file.filename)) return "Already installed!";
logger.log(`${client.data.auth.user?.username} is downloading plugin ${file.filename} in ${server.name}`, "plugin.download", LogLevel.INFO);
let jar = await fetch(file.url, {
headers: mrHeaders
});
if (!jar.ok || !jar.body) return "Request isn't OK";
let jarBuffer = await jar.arrayBuffer();
await fs.writeFile(server.path + "/plugins/" + file.filename, Buffer.from(jarBuffer));
await fs.writeFile(server.path + pluginFolderName + file.filename, Buffer.from(jarBuffer));
return {
type: "downloadSuccess"
}
}
}
}
}
7 changes: 6 additions & 1 deletion Server/src/serverManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,12 @@ export default new class ServerManager {
downloadURL = versionManifest?.downloads?.server?.url;
if (!downloadURL) throw new Error("Invalid response from mojang. Could not find server download URL.");
break;
default:
case "fabric":
let fabricLoaderVersions = await (await fetch("https://meta.fabricmc.net/v2/versions/loader")).json();
let fabricInstallerVersions = await (await fetch("https://meta.fabricmc.net/v2/versions/installer")).json();
downloadURL = `https://meta.fabricmc.net/v2/versions/loader/${server.version}/${fabricLoaderVersions[0].version}/${fabricInstallerVersions[0].version}/server/jar`;
break;
default:
throw new Error("Invalid server software.");
}
let jar = await fetch(downloadURL);
Expand Down
64 changes: 37 additions & 27 deletions Server/src/util/modrinth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,42 +2,52 @@ let rootAPI = "https://api.modrinth.com/v2";
import qs from "node:querystring";
import { buildInfo } from "../../../Share/BuildInfo.js";
import { Plugin, Version } from "../../../Share/Plugin.js";
import { AllowedSoftware } from "../../../Share/Server.js";
export let mrHeaders = new Headers();
mrHeaders.append("User-Agent", `TheBlueBurger/BurgerPanel/v${buildInfo.version} (${buildInfo.gitHash})`);

let bukkitTypes = ["bukkit", "spigot", "paper"];

mrHeaders.append(
"User-Agent",
`TheBlueBurger/BurgerPanel/v${buildInfo.version} (${buildInfo.gitHash})`,
);
// https://docs.modrinth.com/docs/tutorials/api_search/
async function sendModrinthRequest(path: string) {
let res = await fetch(rootAPI + path, {
headers: mrHeaders
});
let jsonData = await res.json();
return jsonData;
let res = await fetch(rootAPI + path, {
headers: mrHeaders,
});
let jsonData = await res.json();
return jsonData;
}
export async function search(query: string, version: string) {
let encodedQS = qs.encode({
query,
facets: JSON.stringify([
["versions:" + version],
["categories:paper", "categories:bukkit", "categories:spigot"]
])
})
return await sendModrinthRequest("/search?" + encodedQS);
export async function search(query: string, version: string, software: AllowedSoftware) {
let encodedQS = qs.encode({
query,
facets: JSON.stringify([
["versions:" + version],
["server_side:required","server_side:optional"],
software != "fabric" ? bukkitTypes.map((a) => "categories:" + a): ["categories:fabric"],
]),
});
return await sendModrinthRequest("/search?" + encodedQS);
}
export async function getPluginDetails(slug: string): Promise<Plugin> {
return await sendModrinthRequest("/project/"+slug);
return await sendModrinthRequest("/project/" + slug);
}
export async function getVersions(slug: string, version: string): Promise<Version[]> {
let encodedQS = qs.encode({
loaders: JSON.stringify(["paper", "bukkit", "spigot"]),
game_versions: JSON.stringify([version])
})
return await sendModrinthRequest("/project/"+slug+"/version?" + encodedQS);
export async function getVersions(slug: string, version: string, software: AllowedSoftware): Promise<Version[]> {
let encodedQS = qs.encode({
loaders: software == "fabric" ? ["fabric"] : JSON.stringify(bukkitTypes),
game_versions: JSON.stringify([version]),
});
return await sendModrinthRequest(
"/project/" + slug + "/version?" + encodedQS,
);
}

export async function getVersion(version: string): Promise<Version> {
return await sendModrinthRequest("/version/"+version);
return await sendModrinthRequest("/version/" + version);
}
export async function getFile(version: string, sha512: string) {
let ver = await getVersion(version);
if(!ver) throw new Error("ver no exist");
return ver.files.find(f => f.hashes.sha512 == sha512);
}
let ver = await getVersion(version);
if (!ver) throw new Error("ver no exist");
return ver.files.find((f) => f.hashes.sha512 == sha512);
}
4 changes: 2 additions & 2 deletions Share/Config.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { allowedSoftwares } from "./Server.js";
import { AllowedSoftware, allowedSoftwares } from "./Server.js";

export let defaultConfig: Config = {
defaultMemory: 1024,
Expand All @@ -18,7 +18,7 @@ export interface Config {
webServerPort: number;
serverPath: string;
defaultMCVersion: string;
defaultMCSoftware: "purpur" | "paper" | "vanilla";
defaultMCSoftware: AllowedSoftware;
stopServerTimeout: number;
defaultPermissions: string;
logging_DisabledIDs: string; // comma-separated IDs
Expand Down
2 changes: 1 addition & 1 deletion Share/Server.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ServerPermissions } from "./Permission";
export const allowedSoftwares = ["purpur", "paper", "vanilla"] as const;
export const allowedSoftwares = ["purpur", "paper", "vanilla", "fabric"] as const;
export type AllowedSoftware = typeof allowedSoftwares[number];
export interface Server {
_id: string;
Expand Down
6 changes: 3 additions & 3 deletions Web/src/pages/Management/DownloadPlugins.vue
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,13 @@ async function downloadPlugin(version: MRVersion, hash: string, pluginName: stri
server: props.server,
hash
});
showInfoBox("Install success!", `The plugin ${pluginName} with version ${version.name} (${filename}) has been successfully installed to ${server.value.name}\nYou may need a server restart for the plugin to be loaded.`)
showInfoBox("Install success!", `The ${server.value.software == "fabric" ? "mod" : "plugin"} ${pluginName} with version ${version.name} (${filename}) has been successfully installed to ${server.value.name}\nYou may need a server restart for the ${server.value.software == "fabric" ? "mod" : "plugin"} to be loaded.`)
}
</script>

<template>
<div id="head">
<h1>Plugins downloader for {{ server.name }}</h1>
<h1>{{server.software == "fabric" ? "Mod" : "Plugin"}} downloader for {{ server.name }}</h1>
<form @submit.prevent="search">
<TextInput default="" :modal-mode="true" :initial-editing="true" @set="q => query = q" placeholder="Search for plugins..." />
</form>
Expand Down Expand Up @@ -260,4 +260,4 @@ async function downloadPlugin(version: MRVersion, hash: string, pluginName: stri
.md-plugin-modal::-webkit-scrollbar {
display: none;
}
</style>
</style>
2 changes: 1 addition & 1 deletion Web/src/pages/Management/Edit.vue
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ async function changeUseJVMArgs() {
server: props.server
}
}" v-if="hasServerPermission(user.user, server, 'plugins.download')">
<button>Download Plugins</button>
<button>Download {{server.software == "fabric" ? "mods" : "plugins"}}</button>
</RouterLink>
<RouterLink :to="{
name: 'integrator',
Expand Down
6 changes: 3 additions & 3 deletions Web/src/pages/Management/ServerFiles.vue
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,7 @@
</div>
</Modal>
<div v-if="!finishedLoading">

</div>
<div v-else-if="!readingFile">
<h1 class="filesin">Files in {{ server.name }}{{ path }} <RouterLink :to="{
Expand All @@ -389,7 +389,7 @@
server: props.server
}
}" v-if="path && path.toString().startsWith('/plugins') && hasServerPermission(user.user, server, 'plugins.download')">
<button class="back-server-page-btn">Download Plugins</button>
<button class="back-server-page-btn">Download {{server.software == "fabric" ? "mods" : "plugins"}}</button>
</RouterLink><button class="back-server-page-btn" @click="newName = '';showNewDialog = true">New</button></h1>
<Dropdown :create-on-cursor="true" ref="dropdown">
<div id="dropdown-inner">
Expand Down Expand Up @@ -533,4 +533,4 @@ textarea {
.slightlyWhite {
background-color: #6b6b6b;
}
</style>
</style>

0 comments on commit c7f3866

Please sign in to comment.