[EXPAND] [[messages]] messageTitle = "QB Update for GT 2.8 (#681)" messageBody = """ [QB] [DETAILS] details = ["Fixes many Quest Book issues", "Updates QB with changes in GT 2.8"] [DETAILS] """ [[messages]] messageTitle = "Buildscript Refactor (#681)" messageBody = """ [INTERNAL] [DETAILS] details = ["**Important: Buildscript has changed from `npx gulp...` or `gulp...` to `npm run gulp...`**!", "Moves to Node 16 Package Management + Typescript Strict Mode", "New Port QB, Check QB and Fix QB Tasks"] [DETAILS] """ [EXPAND] Co-authored-by: Integer Limit <103940576+IntegerLimit@users.noreply.github.com> Co-authored-by: Ghzdude <44148655+ghzdude@users.noreply.github.com> Co-authored-by: SparkedTheorem <162088357+SparkedTheorem@users.noreply.github.com>
279 lines
6.7 KiB
TypeScript
279 lines
6.7 KiB
TypeScript
import upath from "upath";
|
|
import unzip from "unzipper";
|
|
import through from "through2";
|
|
import mustache from "mustache";
|
|
import gulp, { src, dest, symlink } from "gulp";
|
|
import fs from "fs";
|
|
import buildConfig from "#buildConfig";
|
|
import { ForgeProfile } from "#types/forgeProfile.ts";
|
|
import { FileDef } from "#types/fileDef.ts";
|
|
import {
|
|
downloadOrRetrieveFileDef,
|
|
getForgeJar,
|
|
getVersionManifest,
|
|
} from "#utils/util.ts";
|
|
import {
|
|
modDestDirectory,
|
|
modpackManifest,
|
|
serverDestDirectory,
|
|
sharedDestDirectory,
|
|
} from "#globals";
|
|
import { deleteAsync } from "del";
|
|
import { updateBuildServerProperties } from "../misc/transformFiles.ts";
|
|
import logInfo, { logWarn } from "#utils/log.ts";
|
|
import filter from "gulp-filter";
|
|
|
|
let g_forgeJar: string | undefined = undefined;
|
|
|
|
async function serverCleanUp() {
|
|
return deleteAsync(upath.join(serverDestDirectory, "*"), { force: true });
|
|
}
|
|
|
|
/**
|
|
* Checks and creates all necessary directories so we can build the server safely.
|
|
*/
|
|
async function createServerDirs() {
|
|
if (!fs.existsSync(serverDestDirectory)) {
|
|
return fs.promises.mkdir(serverDestDirectory, { recursive: true });
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Download the Forge jar.
|
|
*
|
|
* Extract, parse the profile data and download required libraries.
|
|
*/
|
|
async function downloadForge() {
|
|
const { forgeJar, forgeUniversalPath } = await getForgeJar();
|
|
|
|
/**
|
|
* Parse the profile manifest.
|
|
*/
|
|
let forgeUniversalJar: Buffer | undefined = undefined;
|
|
let forgeProfile: ForgeProfile | undefined = undefined;
|
|
const files = (await unzip.Open.buffer(forgeJar))?.files;
|
|
|
|
logInfo("Extracting Forge installation profile & jar...");
|
|
|
|
if (!files) {
|
|
throw new Error("Malformed Forge installation jar.");
|
|
}
|
|
|
|
for (const file of files) {
|
|
// Look for the universal jar.
|
|
if (!forgeUniversalJar && file.path == forgeUniversalPath) {
|
|
forgeUniversalJar = await file.buffer();
|
|
}
|
|
// Look for the installation profile.
|
|
else if (!forgeProfile && file.path == "version.json") {
|
|
forgeProfile = JSON.parse((await file.buffer()).toString());
|
|
}
|
|
|
|
if (forgeUniversalJar && forgeProfile) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!forgeProfile || !forgeProfile.libraries) {
|
|
throw new Error("Malformed Forge installation profile.");
|
|
}
|
|
|
|
if (!forgeUniversalJar) {
|
|
throw new Error(
|
|
"Couldn't find the universal Forge jar in the installation jar.",
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Move the universal jar into the dist folder.
|
|
*/
|
|
logInfo("Extracting the Forge jar...");
|
|
await fs.promises.writeFile(
|
|
upath.join(serverDestDirectory, upath.basename(forgeUniversalPath)),
|
|
forgeUniversalJar,
|
|
);
|
|
|
|
/**
|
|
* Save the universal jar file name for later.
|
|
*
|
|
* We will need it to process launchscripts.
|
|
*/
|
|
g_forgeJar = upath.basename(forgeUniversalPath);
|
|
|
|
/**
|
|
* Finally, fetch libraries.
|
|
*/
|
|
const libraries = forgeProfile.libraries.filter((x) =>
|
|
Boolean(x?.downloads?.artifact?.url),
|
|
);
|
|
logInfo(`Fetching ${libraries.length} server libraries...`);
|
|
|
|
await Promise.all(
|
|
libraries.map(async (library) => {
|
|
const libraryPath = library.downloads.artifact.path;
|
|
|
|
const def: FileDef = {
|
|
url: library.downloads.artifact.url,
|
|
};
|
|
|
|
if (library.downloads.artifact.sha1) {
|
|
def.hashes = [
|
|
{ id: "sha1", hashes: [library.downloads.artifact.sha1] },
|
|
];
|
|
}
|
|
|
|
const destPath = upath.join(
|
|
serverDestDirectory,
|
|
"libraries",
|
|
libraryPath,
|
|
);
|
|
|
|
await fs.promises.mkdir(upath.dirname(destPath), { recursive: true });
|
|
return fs.promises.copyFile(
|
|
(await downloadOrRetrieveFileDef(def)).cachePath,
|
|
destPath,
|
|
);
|
|
}),
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Download the server jar.
|
|
*/
|
|
async function downloadMinecraftServer() {
|
|
logInfo("Fetching the Minecraft version manifest...");
|
|
const versionManifest = await getVersionManifest(
|
|
modpackManifest.minecraft.version,
|
|
);
|
|
if (!versionManifest) {
|
|
throw new Error(`No manifest found for Minecraft ${versionManifest}`);
|
|
}
|
|
|
|
/**
|
|
* Fetch the server jar file.
|
|
*
|
|
* Pass SHA1 hash to compare against the downloaded file.
|
|
*/
|
|
const serverJar = await downloadOrRetrieveFileDef({
|
|
url: versionManifest.downloads.server.url,
|
|
hashes: [{ id: "sha1", hashes: versionManifest.downloads.server.sha1 }],
|
|
});
|
|
|
|
if (!(versionManifest.downloads && versionManifest.downloads.server)) {
|
|
throw new Error(`No server jar file found for ${versionManifest.id}`);
|
|
}
|
|
|
|
const dest = upath.join(
|
|
serverDestDirectory,
|
|
`minecraft_server.${versionManifest.id}.jar`,
|
|
);
|
|
await fs.promises.symlink(upath.resolve(serverJar.cachePath), dest);
|
|
}
|
|
|
|
/**
|
|
* Copies server & shared mods.
|
|
*/
|
|
async function copyServerMods() {
|
|
const f = filter((f) => !f.isDirectory());
|
|
return src(["*", upath.join("server", "*")], {
|
|
cwd: modDestDirectory,
|
|
resolveSymlinks: true,
|
|
})
|
|
.pipe(f)
|
|
.pipe(symlink(upath.join(serverDestDirectory, "mods")));
|
|
}
|
|
|
|
/**
|
|
* Copies modpack overrides.
|
|
*/
|
|
function copyServerOverrides() {
|
|
const f = filter((f) => !f.isDirectory());
|
|
return src(buildConfig.copyFromSharedServerGlobs, {
|
|
cwd: sharedDestDirectory,
|
|
allowEmpty: true,
|
|
resolveSymlinks: true,
|
|
})
|
|
.pipe(f)
|
|
.pipe(symlink(upath.join(serverDestDirectory)));
|
|
}
|
|
|
|
/**
|
|
* Copies files from ./serverfiles into dest folder.
|
|
*/
|
|
function copyServerFiles() {
|
|
return src(["../serverfiles/**"]).pipe(dest(serverDestDirectory));
|
|
}
|
|
|
|
/**
|
|
* Copies the license file.
|
|
*/
|
|
function copyServerLicense() {
|
|
return src("../LICENSE").pipe(dest(serverDestDirectory));
|
|
}
|
|
|
|
/**
|
|
* Copies the update notes file.
|
|
*/
|
|
function copyServerUpdateNotes() {
|
|
return src("../UPDATENOTES.md", { allowEmpty: true }).pipe(
|
|
dest(serverDestDirectory),
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Copies the changelog file.
|
|
*/
|
|
function copyServerChangelog() {
|
|
return src(
|
|
upath.join(buildConfig.buildDestinationDirectory, "CHANGELOG.md"),
|
|
).pipe(dest(serverDestDirectory));
|
|
}
|
|
|
|
/**
|
|
* Copies files from ./launchscripts into dest folder and processes them using mustache.
|
|
*
|
|
* Replaces jvmArgs, minRAM, maxRAM and forgeJar.
|
|
*/
|
|
function processLaunchscripts() {
|
|
const rules = {
|
|
jvmArgs: buildConfig.launchscriptsJVMArgs,
|
|
minRAM: buildConfig.launchscriptsMinRAM,
|
|
maxRAM: buildConfig.launchscriptsMaxRAM,
|
|
forgeJar: "",
|
|
};
|
|
|
|
if (g_forgeJar) {
|
|
rules.forgeJar = g_forgeJar;
|
|
} else {
|
|
logWarn("No forgeJar specified!");
|
|
logWarn("Did downloadForge task fail?");
|
|
}
|
|
|
|
return src(["../launchscripts/**"])
|
|
.pipe(
|
|
through.obj((file, _, callback) => {
|
|
if (file.isBuffer()) {
|
|
const rendered = mustache.render(file.contents.toString(), rules);
|
|
file.contents = Buffer.from(rendered);
|
|
}
|
|
callback(null, file);
|
|
}),
|
|
)
|
|
.pipe(dest(serverDestDirectory));
|
|
}
|
|
|
|
export default gulp.series(
|
|
serverCleanUp,
|
|
createServerDirs,
|
|
downloadForge,
|
|
downloadMinecraftServer,
|
|
copyServerMods,
|
|
copyServerOverrides,
|
|
copyServerFiles,
|
|
copyServerLicense,
|
|
copyServerChangelog,
|
|
copyServerUpdateNotes,
|
|
processLaunchscripts,
|
|
updateBuildServerProperties,
|
|
);
|