diff --git a/core/src/main/java/pl/skidam/automodpack_core/netty/HttpServer.java b/core/src/main/java/pl/skidam/automodpack_core/netty/HttpServer.java index 9d07c05d..2b8fa606 100644 --- a/core/src/main/java/pl/skidam/automodpack_core/netty/HttpServer.java +++ b/core/src/main/java/pl/skidam/automodpack_core/netty/HttpServer.java @@ -162,6 +162,7 @@ private boolean canStart() { } LOGGER.info("Starting modpack host server on port {}", serverConfig.hostPort); + return true; } } diff --git a/gradle.properties b/gradle.properties index 8f071211..31c8286b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,7 +9,7 @@ fabric_versions = 1.18.2, 1.19.2, 1.19.4, 1.20.1, 1.20.4, 1.20.6, 1.21.1, 1.21.3 neoforge_versions = 1.20.4, 1.20.6, 1.21.1, 1.21.3 forge_versions = 1.18.2, 1.19.2, 1.19.4, 1.20.1 -core_modules = core, fabric-core, fabric-15, fabric-16, forge-fml40, forge-fml47, neoforge-fml2, neoforge-fml4 +core_modules = core, fabric-core, fabric-15, fabric-16, forge-fml40, forge-fml47, neoforge-fml2, neoforge-fml4, velocity loader_fabric = 0.15.11 mixin_extras = 0.3.6 diff --git a/loader/core/src/main/java/pl/skidam/automodpack_loader_core/Preload.java b/loader/core/src/main/java/pl/skidam/automodpack_loader_core/Preload.java index e791182a..1699edc9 100644 --- a/loader/core/src/main/java/pl/skidam/automodpack_loader_core/Preload.java +++ b/loader/core/src/main/java/pl/skidam/automodpack_loader_core/Preload.java @@ -82,13 +82,13 @@ private void updateAll() { private void initializeGlobalVariables() { // Initialize global variables preload = true; - LOADER_MANAGER = new LoaderManager(); +// LOADER_MANAGER = new LoaderManager(); MODPACK_LOADER = new ModpackLoader(); - MC_VERSION = LOADER_MANAGER.getModVersion("minecraft"); +// MC_VERSION = LOADER_MANAGER.getModVersion("minecraft"); // TODO: reenable it // Can't get via automodpack version though loader methods since this mod isn't loaded yet... At least on forge... AM_VERSION = ManifestReader.getAutoModpackVersion(); - LOADER_VERSION = LOADER_MANAGER.getLoaderVersion(); - LOADER = LOADER_MANAGER.getPlatformType().toString().toLowerCase(); +// LOADER_VERSION = LOADER_MANAGER.getLoaderVersion(); // TODO: reenable it +// LOADER = LOADER_MANAGER.getPlatformType().toString().toLowerCase(); // TODO: reenable it AUTOMODPACK_JAR = FileInspection.getAutoModpackJar(); MODS_DIR = AUTOMODPACK_JAR.getParent(); @@ -168,4 +168,4 @@ private void loadConfigs() { LOGGER.info("Loaded config! took " + (System.currentTimeMillis() - startTime) + "ms"); } -} +} \ No newline at end of file diff --git a/loader/forge/fml47/src/main/java/pl/skidam/automodpack_loader_core_forge/EarlyModLocator.java b/loader/forge/fml47/src/main/java/pl/skidam/automodpack_loader_core_forge/EarlyModLocator.java index 71462a55..c57a80fc 100644 --- a/loader/forge/fml47/src/main/java/pl/skidam/automodpack_loader_core_forge/EarlyModLocator.java +++ b/loader/forge/fml47/src/main/java/pl/skidam/automodpack_loader_core_forge/EarlyModLocator.java @@ -47,7 +47,7 @@ public Stream scanCandidates() { new Preload(); - ModpackLoader.modsToAdd.forEach(path -> LOGGER.info("Adding mod: {}", path.getFileName())); + ModpackLoader.modsToAdd.forEach(path -> LOGGER.info(" Adding mod: {}", path.getFileName())); // we would need to force load there e.g. connector mod and its locators to loader // and in the lazy mod locator load its dependency locator diff --git a/loader/loader-velocity.gradle.kts b/loader/loader-velocity.gradle.kts new file mode 100644 index 00000000..81120bbc --- /dev/null +++ b/loader/loader-velocity.gradle.kts @@ -0,0 +1,71 @@ +import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar + +plugins { + java + id("com.github.johnrengelman.shadow") +} + +base { + archivesName = property("mod_id") as String + project.name.replace("loader", "") + version = property("mod_version") as String + group = property("mod_group") as String +} + +repositories { + mavenCentral() + maven { url = uri("https://repo.papermc.io/repository/maven-public/") } +} + +dependencies { + compileOnly("com.velocitypowered:velocity-api:3.4.0-SNAPSHOT") + annotationProcessor("com.velocitypowered:velocity-api:3.4.0-SNAPSHOT") + + implementation(project(":core")) + implementation(project(":loader-core")) + + // our needed dependencies + implementation("com.google.code.gson:gson:2.10.1") + implementation("org.apache.logging.log4j:log4j-core:2.20.0") + implementation("org.tomlj:tomlj:1.1.1") +} + +configurations { + create("shadowImplementation") { + extendsFrom(configurations.getByName("implementation")) + isCanBeResolved = true + } +} + +tasks.named("shadowJar") { + archiveClassifier.set("") + mergeServiceFiles() + + // Include the tomlj dependency in the shadow jar + configurations = listOf(project.configurations.getByName("shadowImplementation")) + + relocate("org.antlr.v4", "reloc.org.antlr.v4") + relocate("org.tomlj", "reloc.org.tomlj") + relocate("org.checkerframework", "reloc.org.checkerframework") + + exclude("log4j2.xml") + + manifest { + attributes["AutoModpack-Version"] = version + } +} + +java { + // leave it on java 17 to be compatible with older versions and we dont really need 21 there anyway + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 + + withSourcesJar() +} + +tasks.withType { + options.encoding = "UTF-8" +} + +tasks.named("assemble") { + dependsOn("shadowJar") +} \ No newline at end of file diff --git a/loader/velocity/src/main/java/pl/skidam/automodpack_loader_velocity/Commands.java b/loader/velocity/src/main/java/pl/skidam/automodpack_loader_velocity/Commands.java new file mode 100644 index 00000000..1384c39c --- /dev/null +++ b/loader/velocity/src/main/java/pl/skidam/automodpack_loader_velocity/Commands.java @@ -0,0 +1,205 @@ +package pl.skidam.automodpack_loader_velocity; + +import com.mojang.brigadier.Command; +import com.mojang.brigadier.tree.LiteralCommandNode; +import com.velocitypowered.api.command.BrigadierCommand; +import com.velocitypowered.api.command.CommandSource; +import com.velocitypowered.api.proxy.ProxyServer; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; + +public class Commands { + + public static BrigadierCommand register(final ProxyServer proxy) { + LiteralCommandNode commandNode = BrigadierCommand.literalArgumentBuilder("automodpack") + .executes(context -> { + CommandSource source = context.getSource(); + Component message = Component.text("AutoModpack", NamedTextColor.GREEN); + source.sendMessage(message); + return Command.SINGLE_SUCCESS; + }) + .then(BrigadierCommand.literalArgumentBuilder("generate") + .requires(source -> source.hasPermission("automodpack.generate")) + .executes(context -> { + CommandSource source = context.getSource(); + // Add your generateModpack logic here + source.sendMessage(Component.text("Generating Modpack...", NamedTextColor.YELLOW)); + return Command.SINGLE_SUCCESS; + }) + ) + .then(BrigadierCommand.literalArgumentBuilder("host") + .requires(source -> source.hasPermission("automodpack.host")) + .executes(context -> { + CommandSource source = context.getSource(); + // Add your modpackHostAbout logic here + source.sendMessage(Component.text("Modpack hosting status", NamedTextColor.GREEN)); + return Command.SINGLE_SUCCESS; + }) + .then(BrigadierCommand.literalArgumentBuilder("start") + .requires(source -> source.hasPermission("automodpack.host.start")) + .executes(context -> { + CommandSource source = context.getSource(); + // Add your startModpackHost logic here + source.sendMessage(Component.text("Starting modpack hosting...", NamedTextColor.YELLOW)); + return Command.SINGLE_SUCCESS; + }) + ) + .then(BrigadierCommand.literalArgumentBuilder("stop") + .requires(source -> source.hasPermission("automodpack.host.stop")) + .executes(context -> { + CommandSource source = context.getSource(); + // Add your stopModpackHost logic here + source.sendMessage(Component.text("Stopping modpack hosting...", NamedTextColor.RED)); + return Command.SINGLE_SUCCESS; + }) + ) + .then(BrigadierCommand.literalArgumentBuilder("restart") + .requires(source -> source.hasPermission("automodpack.host.restart")) + .executes(context -> { + CommandSource source = context.getSource(); + // Add your restartModpackHost logic here + source.sendMessage(Component.text("Restarting modpack hosting...", NamedTextColor.YELLOW)); + return Command.SINGLE_SUCCESS; + }) + ) + ) + .then(BrigadierCommand.literalArgumentBuilder("config") + .requires(source -> source.hasPermission("automodpack.config")) + .then(BrigadierCommand.literalArgumentBuilder("reload") + .requires(source -> source.hasPermission("automodpack.config.reload")) + .executes(context -> { + CommandSource source = context.getSource(); + // Add your reload logic here + source.sendMessage(Component.text("AutoModpack server config reloaded!", NamedTextColor.GREEN)); + return Command.SINGLE_SUCCESS; + }) + ) + ) + .build(); + + return new BrigadierCommand(commandNode); + } + + +// TODO: implement the following methods + +// private static int reload(CommandSource context) { +// Util.getMainWorkerExecutor().execute(() -> { +// serverConfig = ConfigTools.load(serverConfigFile, Jsons.ServerConfigFields.class); +// send(context, "AutoModpack server config reloaded!", Formatting.GREEN, true); +// }); +// +// return Command.SINGLE_SUCCESS; +// } +// +// private static int startModpackHost(CommandContext context) { +// Util.getMainWorkerExecutor().execute(() -> { +// if (!httpServer.shouldRunInternally()) { +// send(context, "Starting modpack hosting...", Formatting.YELLOW, true); +// httpServer.start(); +// if (httpServer.shouldRunInternally()) { +// send(context, "Modpack hosting started!", Formatting.GREEN, true); +// } else { +// send(context, "Couldn't start server!", Formatting.RED, true); +// } +// } else { +// send(context, "Modpack hosting is already running!", Formatting.RED, false); +// } +// }); +// +// return Command.SINGLE_SUCCESS; +// } +// +// private static int stopModpackHost(CommandContext context) { +// Util.getMainWorkerExecutor().execute(() -> { +// if (httpServer.shouldRunInternally()) { +// send(context, "Stopping modpack hosting...", Formatting.RED, true); +// if (httpServer.stop()) { +// send(context, "Modpack hosting stopped!", Formatting.RED, true); +// } else { +// send(context, "Couldn't stop server!", Formatting.RED, true); +// } +// } else { +// send(context, "Modpack hosting is not running!", Formatting.RED, false); +// } +// }); +// +// return Command.SINGLE_SUCCESS; +// } +// +// private static int restartModpackHost(CommandContext context) { +// Util.getMainWorkerExecutor().execute(() -> { +// send(context, "Restarting modpack hosting...", Formatting.YELLOW, true); +// boolean needStop = httpServer.shouldRunInternally(); +// boolean stopped = false; +// if (needStop) { +// stopped = httpServer.stop(); +// } +// +// if (needStop && !stopped) { +// send(context, "Couldn't restart server!", Formatting.RED, true); +// } else { +// httpServer.start(); +// if (httpServer.shouldRunInternally()) { +// send(context, "Modpack hosting restarted!", Formatting.GREEN, true); +// } else { +// send(context, "Couldn't restart server!", Formatting.RED, true); +// } +// } +// }); +// +// return Command.SINGLE_SUCCESS; +// } +// +// +// private static int modpackHostAbout(CommandContext context) { +// Formatting statusColor = httpServer.shouldRunInternally() ? Formatting.GREEN : Formatting.RED; +// String status = httpServer.shouldRunInternally() ? "running" : "not running"; +// send(context, "Modpack hosting status", Formatting.GREEN, status, statusColor, false); +// return Command.SINGLE_SUCCESS; +// } +// +// private static int about(CommandContext context) { +// send(context, "AutoModpack", Formatting.GREEN, AM_VERSION, Formatting.WHITE, false); +// send(context, "/automodpack generate", Formatting.YELLOW, false); +// send(context, "/automodpack host start/stop/restart", Formatting.YELLOW, false); +// send(context, "/automodpack config reload", Formatting.YELLOW, false); +// return Command.SINGLE_SUCCESS; +// } +// +// private static int generateModpack(CommandContext context) { +// Util.getMainWorkerExecutor().execute(() -> { +// if (modpack.isGenerating()) { +// send(context, "Modpack is already generating! Please wait!", Formatting.RED, false); +// return; +// } +// send(context, "Generating Modpack...", Formatting.YELLOW, true); +// long start = System.currentTimeMillis(); +// if (modpack.generateNew()) { +// send(context, "Modpack generated! took " + (System.currentTimeMillis() - start) + "ms", Formatting.GREEN, true); +// } else { +// send(context, "Modpack generation failed! Check logs for more info.", Formatting.RED, true); +// } +// }); +// +// return Command.SINGLE_SUCCESS; +// } +// +// private static void send(CommandContext context, String msg, Formatting msgColor, boolean broadcast) { +// VersionedCommandSource.sendFeedback(context, +// VersionedText.literal(msg) +// .formatted(msgColor), +// broadcast); +// } +// +// private static void send(CommandContext context, String msg, Formatting msgColor, String appendMsg, Formatting appendMsgColor, boolean broadcast) { +// VersionedCommandSource.sendFeedback(context, +// VersionedText.literal(msg) +// .formatted(msgColor) +// .append(VersionedText.literal(" - ") +// .formatted(Formatting.WHITE)) +// .append(VersionedText.literal(appendMsg) +// .formatted(appendMsgColor)), +// broadcast); +// } +} diff --git a/loader/velocity/src/main/java/pl/skidam/automodpack_loader_velocity/Initializer.java b/loader/velocity/src/main/java/pl/skidam/automodpack_loader_velocity/Initializer.java new file mode 100644 index 00000000..586ff4f6 --- /dev/null +++ b/loader/velocity/src/main/java/pl/skidam/automodpack_loader_velocity/Initializer.java @@ -0,0 +1,111 @@ +package pl.skidam.automodpack_loader_velocity; + +import com.google.inject.Inject; +import com.velocitypowered.api.command.BrigadierCommand; +import com.velocitypowered.api.command.CommandManager; +import com.velocitypowered.api.command.CommandMeta; +import com.velocitypowered.api.event.Subscribe; +import com.velocitypowered.api.event.proxy.ProxyInitializeEvent; +import com.velocitypowered.api.event.proxy.ProxyShutdownEvent; +import com.velocitypowered.api.plugin.Plugin; +import com.velocitypowered.api.proxy.ProxyServer; +import org.slf4j.Logger; +import pl.skidam.automodpack_core.config.ConfigTools; +import pl.skidam.automodpack_core.modpack.Modpack; +import pl.skidam.automodpack_core.netty.HttpServer; +import pl.skidam.automodpack_loader_core.Preload; +import pl.skidam.automodpack_loader_velocity.loader.VelocityLoaderManager; + +import static pl.skidam.automodpack_core.GlobalVariables.*; + +@Plugin(id = "automodpack", name = "AutoModpack", version = "4.0.0", authors = {"Skidam"}) +public class Initializer { + + private final ProxyServer proxy; + private final Logger logger; + + @Inject + public Initializer(ProxyServer proxy, Logger logger) { + this.proxy = proxy; + this.logger = logger; + + LOADER_MANAGER = new VelocityLoaderManager(); + + // Set those variables for the time being + MC_VERSION = "1.21.3"; + LOADER = "velocity"; + LOADER_VERSION = "3.4.0"; + + new Preload(); + + // Set port to 30037 for time being + serverConfig.hostPort = 30037; + // Currently not supported + serverConfig.hostModpackOnMinecraftPort = false; + // save config + ConfigTools.save(serverConfigFile, serverConfig); + } + + @Subscribe + public void onProxyInitialize(ProxyInitializeEvent event) { + + preload = false; + + long start = System.currentTimeMillis(); + LOGGER.info("Launching AutoModpack..."); + + httpServer = new HttpServer(); + modpack = new Modpack(); + + if (serverConfig.generateModpackOnStart) { + LOGGER.info("Generating modpack..."); + long genStart = System.currentTimeMillis(); + if (modpack.generateNew()) { + LOGGER.info("Modpack generated! took " + (System.currentTimeMillis() - genStart) + "ms"); + } else { + LOGGER.error("Failed to generate modpack!"); + } + } else { + LOGGER.info("Loading last modpack..."); + long genStart = System.currentTimeMillis(); + if (modpack.loadLast()) { + LOGGER.info("Modpack loaded! took " + (System.currentTimeMillis() - genStart) + "ms"); + } else { + LOGGER.error("Failed to load modpack!"); + } + } + + // TODO: Login mod packets! +// ModPackets.registerS2CPackets(); + + // TODO: Make these commands actually do something + CommandManager commandManager = proxy.getCommandManager(); + // Here you can add meta for the command, as aliases and the plugin to which it belongs (RECOMMENDED) + CommandMeta commandMeta = commandManager.metaBuilder("automodpack") + // This will create a new alias for the command "/test" + // with the same arguments and functionality + .plugin(this) + .build(); + + // You can replace this with "new EchoCommand()" or "new TestCommand()" + // SimpleCommand simpleCommand = new TestCommand(); + // RawCommand rawCommand = new EchoCommand(); + // The registration is done in the same way, since all 3 interfaces implement "Command" + BrigadierCommand commandToRegister = Commands.register(proxy); + + // Finally, you can register the command + commandManager.register(commandMeta, commandToRegister); + + + LOGGER.info("AutoModpack launched! took " + (System.currentTimeMillis() - start) + "ms"); + + httpServer.start(); + } + + // on server shutdown + @Subscribe + public void onProxyShutdown(ProxyShutdownEvent event) { + httpServer.stop(); + modpack.shutdownExecutor(); + } +} diff --git a/loader/velocity/src/main/java/pl/skidam/automodpack_loader_velocity/loader/VelocityLoaderManager.java b/loader/velocity/src/main/java/pl/skidam/automodpack_loader_velocity/loader/VelocityLoaderManager.java new file mode 100644 index 00000000..dd4c7022 --- /dev/null +++ b/loader/velocity/src/main/java/pl/skidam/automodpack_loader_velocity/loader/VelocityLoaderManager.java @@ -0,0 +1,83 @@ +package pl.skidam.automodpack_loader_velocity.loader; + +import pl.skidam.automodpack_core.loader.LoaderManagerService; +import pl.skidam.automodpack_core.utils.FileInspection; + +import java.nio.file.Path; +import java.util.Collection; +import java.util.List; + +// Test values for now +public class VelocityLoaderManager implements LoaderManagerService { + + @Override + public ModPlatform getPlatformType() { + return ModPlatform.FABRIC; + } + + // No mod will be loaded on velocity + @Override + public boolean isModLoaded(String modId) { + return false; + } + + @Override + public Collection getModList() { + return List.of(); + } + + @Override + public Mod getMod(String modId) { + return null; + } + + @Override + public Mod getMod(Path file) { + return null; + } + + @Override + public String getLoaderVersion() { + return "3.4.0"; + } + + @Override + public Path getModPath(String modId) { + return null; + } + + @Override + public EnvironmentType getEnvironmentType() { + return EnvironmentType.SERVER; + } + + @Override + public EnvironmentType getModEnvironmentFromNotLoadedJar(Path file) { + return FileInspection.getModEnvironment(file); + } + + @Override + public String getModVersion(String modId) { + return null; + } + + @Override + public String getModVersion(Path file) { + return FileInspection.getModVersion(file); + } + + @Override + public boolean isDevelopmentEnvironment() { + return false; + } + + @Override + public EnvironmentType getModEnvironment(String modId) { + return null; + } + + @Override + public String getModIdFromNotLoadedJar(Path file) { + return FileInspection.getModID(file); + } +} diff --git a/settings.gradle.kts b/settings.gradle.kts index 4b311618..703602c2 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -32,6 +32,7 @@ coreModules.forEach { module -> "fabric-core" -> project.buildFileName = "../../loader-fabric-core.gradle.kts" "fabric-15", "fabric-16" -> project.buildFileName = "../../loader-fabric.gradle.kts" "forge-fml40", "forge-fml47", "neoforge-fml2", "neoforge-fml4" -> project.buildFileName = "../../loader-forge.gradle.kts" + "velocity" -> project.buildFileName = "../loader-velocity.gradle.kts" } } diff --git a/stonecutter.gradle.kts b/stonecutter.gradle.kts index 70d00002..bee006e2 100644 --- a/stonecutter.gradle.kts +++ b/stonecutter.gradle.kts @@ -71,6 +71,14 @@ tasks.register("mergeJars") { doLast { mergedDir.mkdirs() + + // Check if velocity is present, if so copy build to merged + val velocityJar = File("${rootProject.projectDir}/loader/velocity/build/libs").listFiles() + ?.single { it.isFile && !it.name.endsWith("-sources.jar") && it.name.endsWith(".jar") } + + velocityJar?.copyTo(File("$mergedDir/${velocityJar.name}"), overwrite = true) + + // Scan all minecraft versions and match them with the loaders val jarsToMerge = File("$rootDir/versions").listFiles() ?.flatMap { File("$it/build/libs").listFiles()