This PR updates Nomi-Labs to 0.7.0, allowing for associate updates to GT, GCYM, GrS and Architecture Craft, as well as the removal of Random Patches, Just Enough Dimensions, and Difficulty Lock. Although GT 2.8.10 also fixed Extreme RAM Usage in Alfheim 1.3, (See PR https://github.com/GregTechCEu/GregTech/pull/2475) this PR **does not** update Alfheim to 1.3. This is because Alfheim 1.3, although not consuming large amounts of memory, still consumes more memory than 1.1.1, and causes fps spikes. Also, because Nomi-Labs now implements a native and better difficulty lock, of which works on dedicated servers, `server.properties` overrides, as well as previously changed parts in README and Pack Mode Switchers (in https://github.com/Nomi-CEu/Nomi-CEu/pull/292), have been removed. This PR also fixes an issue with corrupted images and jar files in built packs. /* Github Stuff */ [FIXUP] [[fixes]] sha = "bd58b9072f45d647734ae66168cbd27bf9b2f220" newTitle = "Update GT and Related Mods for 1.7" newBody = ''' [EXPAND] [[messages]] messageTitle = "Update GT to 2.8+, add Nomi Labs" messageBody = """ [BREAKING] [DETAILS] details = [ \"**Please DO NOT revert any saves that have been loaded in this release to 1.6.1b, 1.6.1a, or prior!**\", \"**Lots of Recipes have been moved to the Assembly Line, and now require Assembly Line Research.**\", \"Adds Assembly Line Research\", \"Adds ME Hatches and Buses, for combining Multiblocks with AE Networks\", \"Adds Filtered Output Hatches\", \"Adds EU Multiblock Power Storage\", \"Adds Multiblock Transformer and Laser Power Transfer\", \"Adds Long Distance Pipes\", \"Creating Waypoints in the Prospector\", \"Fixing many Bugs\", \"And many more!\" ] [DETAILS] [PRIORITY] priority = 100 [PRIORITY] """ [[messages]] messageTitle = "Multiblock Changes" messageBody = """ [BREAKING] [DETAILS] details = [ \"Multiblocks accept a new **maximum** of 2 Energy Hatches.\", \"All Custom Multiblocks, such as Naquadah Reactors and Multiverse Projectors, now have **minimum casing requirements** and a **maintenance hatch**.\", \"Some Custom Multiblocks now have Distinct Mode\", \"All Custom Multiblocks now have custom Front Overlays\", \"Reworked & Improved Multiblock UIs\" ] [DETAILS] [PRIORITY] priority = 50 [PRIORITY] """ [EXPAND] ''' [FIXUP] [EXPAND] [[messages]] messageTitle = "Upgrade AE2 Stuff to AE2 Stuff Unofficial" messageBody = ''' [BREAKING] [DETAILS] details = [ "Pattern Encoders have been Removed!", "Any existing Pattern Encoders, whether items, in patterns or placed, have been remapped to AE2 Interfaces.", "All Usages in Recipes have also been changed to AE2 Interfaces!", ] [DETAILS] [PRIORITY] priority=25 [PRIORITY] ''' [[messages]] messageTitle = "Update GT to 2.8.10" messageBody = ''' [BREAKING] [DETAILS] details = [ "Allows GregTech Data Sticks to Copy ME Hatch Settings", "Adds an 'Stocking' Version of ME Hatches and Buses", "Support for Displaying Power Substation on Central Monitor", ] [DETAILS] [PRIORITY] priority=20 [PRIORITY] [IGNORE] checks = { compareBefore = "1.7-alpha-4" } # Only apply this if the commit being compared against is 1.7-alpha-4 or newer [IGNORE] ''' [[messages]] messageTitle = "Update Nomi Labs to 0.7.0" messageBody = ''' [BREAKING] [DETAILS] details = [ "Improvement of DME Simulation Chamber (now increases Tiers and Data Counts of Models)", "Custom Implementation of Difficulty Lock, now works on Dedicated Servers", "Replacement of the Void Dimension, fixing issues with Difficulty Changing", "Replacement of Custom Window Titles and Logos, Allowing the Removal of Random Patches", "Improvements to FTB Utils and Effortless Building", "Allows Setting of Default Keybinds for New Players", ] [DETAILS] [PRIORITY] priority=15 [PRIORITY] [IGNORE] checks = { compareBefore = "1.7-alpha-4" } # Only apply this if the commit being compared against is 1.7-alpha-4 or newer [IGNORE] ''' [EXPAND] [MOD INFO] [[infos]] projectID = 254317 info = "Replaced by Nomi Labs" [[infos]] projectID = 285612 info = "Replaced by Nomi Labs" [[infos]] projectID = 390886 info = "Replaced by Nomi Labs" [[infos]] projectID = 538092 info = "Replaced by Betterer P2P" [MOD INFO]
289 lines
6.8 KiB
TypeScript
289 lines
6.8 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 {
|
|
updateFilesBuildSetup,
|
|
updateServerProperties,
|
|
} 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,
|
|
encoding: false,
|
|
})
|
|
.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,
|
|
encoding: false,
|
|
})
|
|
.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));
|
|
}
|
|
|
|
const updateBuildServerProperties = async () => {
|
|
await updateServerProperties(serverDestDirectory);
|
|
};
|
|
|
|
export default gulp.series(
|
|
serverCleanUp,
|
|
createServerDirs,
|
|
downloadForge,
|
|
downloadMinecraftServer,
|
|
copyServerMods,
|
|
copyServerOverrides,
|
|
copyServerFiles,
|
|
copyServerLicense,
|
|
copyServerChangelog,
|
|
copyServerUpdateNotes,
|
|
processLaunchscripts,
|
|
updateFilesBuildSetup,
|
|
updateBuildServerProperties,
|
|
);
|