adds forge support, fixes some critical errors

This commit is contained in:
2023-10-08 13:38:00 -06:00
parent 6944cbb9f7
commit ad4629576c
21 changed files with 3484 additions and 132 deletions

View File

@@ -0,0 +1,43 @@
import { Handler, Handlers } from "$fresh/server.ts";
import { SERVER_STATE } from "../../../state/serverState.ts";
import { downloadFile } from "../../../util/download.ts";
export const handler: Handlers = {
async GET(_req, _ctx) {
const gameVersions = JSON.parse(
await Deno.readTextFile("./fabric/versions/game.json"),
);
const installerVersions = JSON.parse(
await Deno.readTextFile("./fabric/versions/installer.json"),
);
const loaderVersions = JSON.parse(
await Deno.readTextFile("./fabric/versions/loader.json"),
);
return new Response(JSON.stringify({
gameVersions,
installerVersions,
loaderVersions,
}));
},
async POST(req, _ctx) {
try {
const data = await req.formData();
const game = data.get("game");
const installer = data.get("installer");
const loader = data.get("loader");
await downloadFile(`https://meta.fabricmc.net/v2/versions/loader/${game}/${loader}/${installer}/server/jar`, './server/server.jar')
SERVER_STATE.serverType = 'fabric';
SERVER_STATE.startMCServer();
const url = new URL(req.url);
return Response.redirect(url.origin + "/setup/eula", 303);
} catch (e) {
console.log(e)
return new Response("Something bad happened", { status: 500 });
}
},
};

78
routes/api/forge/index.ts Normal file
View File

@@ -0,0 +1,78 @@
import { Handlers } from "$fresh/server.ts";
import { SERVER_STATE } from "../../../state/serverState.ts";
import { downloadFile } from "../../../util/download.ts";
import { getForgeDownload } from "../../../util/forge.ts";
import { getGameVersions } from "../../../util/gameVersions.ts";
export const handler: Handlers = {
async GET(_req, _ctx) {
const gameVersions = await getGameVersions();
return new Response(JSON.stringify({
gameVersions,
}));
},
async POST(req, _ctx) {
try {
const data = await req.formData();
// TODO: update for instances
await downloadFile(
await getForgeDownload(data.get("game") as string || "1.20.1"),
"./server/installer.jar",
);
const installer = new Deno.Command("java", {
args: [
"-Xmx2G",
"-jar",
"./installer.jar",
"--installServer",
],
stderr: "piped",
stdout: "piped",
cwd: "./server",
});
// const process = installer.spawn();
// process.stderr.pipeTo(Deno.stderr.writable);
// process.stdout.pipeTo(Deno.stdout.writable);
const { success } = await installer.output();
if (!success) throw "failed to install forge server";
const argFile = "./server/user_jvm_args.txt";
const jvmArgs = await Deno.readTextFile(argFile);
const memArgRx = /^(#\s)?(-Xmx)(.+)$/m;
await Deno.writeTextFile(
argFile,
jvmArgs.replace(
memArgRx,
jvmArgs.match(memArgRx)?.at(0)?.replace(/#\s?/, "") || "-Xmx4G",
),
);
const runFiles = ["./server/run.sh", "./server/run.bat"];
for (const runFile of runFiles) {
const file = (await Deno.readTextFile(runFile))
.replace("_args.txt", (e) => e + " nogui");
await Deno.writeTextFile(runFile, file);
}
SERVER_STATE.serverType = "forge";
await SERVER_STATE.startMCServer();
const url = new URL(req.url);
return Response.redirect(url.origin + "/setup/eula", 303);
// return Response.redirect(url.origin + "/terminal", 303);
} catch (e) {
console.log(e);
return new Response("Something bad happened", { status: 500 });
}
},
};

View File

@@ -5,6 +5,7 @@ export enum ManageAction {
start = "start",
stop = "stop",
restart = "restart",
kill="kill"
}
export const handler: Handlers = {
@@ -17,6 +18,9 @@ export const handler: Handlers = {
case ManageAction.stop:
SERVER_STATE.gracefullyStopMCServer();
return new Response("stopped");
case ManageAction.kill:
SERVER_STATE.forceStopMCServer();
return new Response("stopped");
case ManageAction.restart:
SERVER_STATE.restartMCServer();
return new Response("restarted");

View File

@@ -40,27 +40,38 @@ export const handler: Handlers = {
return Response.redirect(req.url);
},
async GET(_, ctx) {
const activeMods: string[] = [];
const disabledMods: string[] = [];
if (
SERVER_STATE.serverType !== "unset" &&
SERVER_STATE.serverType !== "vanilla"
) {
for await (const fileEntry of Deno.readDir("./server/mods")) {
if (fileEntry.isFile) {
activeMods.push(fileEntry.name);
}
}
await ensureDir("./server/disabled-mods");
for await (const fileEntry of Deno.readDir("./server/disabled-mods")) {
if (fileEntry.isFile) {
disabledMods.push(fileEntry.name);
}
}
}
return ctx.render({
activeMods,
disabledMods,
});
},
};
export default async function ModsFolder({ url }: PageProps) {
const activeMods: string[] = [];
const disabledMods: string[] = [];
if (
SERVER_STATE.serverType !== "unset" && SERVER_STATE.serverType !== "vanilla"
) {
for await (const fileEntry of Deno.readDir("./server/mods")) {
if (fileEntry.isFile) {
activeMods.push(fileEntry.name);
}
}
ensureDir("./server/disabled-mods");
for await (const fileEntry of Deno.readDir("./server/disabled-mods")) {
if (fileEntry.isFile) {
disabledMods.push(fileEntry.name);
}
}
}
export default function ModsFolder(
{ url, data: { activeMods, disabledMods } }: PageProps<
{ activeMods: string[]; disabledMods: string[] }
>,
) {
return (
<div className="container p-8 flex flex-col gap-8">
<Content>

14
routes/setup/forge.tsx Normal file
View File

@@ -0,0 +1,14 @@
import { Content } from "../../components/Content.tsx";
import { ForgeVersions } from "../../islands/forgeVersions.tsx";
export default function ForgeSetup() {
return (
<div class="container p-8">
<Content>
<h2 class="font-pixel text-2xl">Forge Setup</h2>
<p>Select the game version you wish to create a server for.</p>
<ForgeVersions />
</Content>
</div>
);
}