diff --git a/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/api/commands/CraterCommand.java b/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/api/commands/CraterCommand.java index cc4969e..ee66687 100644 --- a/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/api/commands/CraterCommand.java +++ b/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/api/commands/CraterCommand.java @@ -1,53 +1,156 @@ package com.hypherionmc.craterlib.api.commands; +import com.hypherionmc.craterlib.compat.LuckPermsCompat; +import com.hypherionmc.craterlib.core.platform.ModloaderEnvironment; import com.hypherionmc.craterlib.nojang.authlib.BridgedGameProfile; import com.hypherionmc.craterlib.nojang.commands.BridgedCommandSourceStack; import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer; import com.hypherionmc.craterlib.utils.TriConsumer; -import com.mojang.brigadier.arguments.ArgumentType; -import lombok.Getter; +import com.mojang.brigadier.CommandDispatcher; +import com.mojang.brigadier.arguments.BoolArgumentType; +import com.mojang.brigadier.arguments.IntegerArgumentType; +import com.mojang.brigadier.arguments.StringArgumentType; +import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import net.minecraft.commands.CommandSourceStack; +import net.minecraft.commands.Commands; import net.minecraft.commands.arguments.GameProfileArgument; -import org.apache.commons.lang3.tuple.Pair; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.entity.player.Player; +import org.jetbrains.annotations.ApiStatus; -import java.util.HashMap; -import java.util.LinkedHashMap; import java.util.List; import java.util.function.Consumer; -@Getter public class CraterCommand { - private final HashMap, TriConsumer>> arguments = new LinkedHashMap<>(); - private Consumer executor; + private final LiteralArgumentBuilder mojangCommand; + private int permLevel = 4; + private String luckPermNode = ""; - private final String commandName; - private int permissionLevel = 4; - - CraterCommand(String commandName) { - this.commandName = commandName; + CraterCommand(LiteralArgumentBuilder cmd) { + this.mojangCommand = cmd; } public static CraterCommand literal(String commandName) { - return new CraterCommand(commandName); + return new CraterCommand(Commands.literal(commandName)); } public CraterCommand requiresPermission(int perm) { - this.permissionLevel = perm; + this.permLevel = perm; + this.mojangCommand.requires(this::checkPermission); return this; } - public CraterCommand withGameProfileArgument(String key, TriConsumer, BridgedCommandSourceStack> executor) { - arguments.put(key, Pair.of(GameProfileArgument.gameProfile(), executor)); + public CraterCommand withNode(String key) { + this.luckPermNode = key; return this; } + public CraterCommand then(CraterCommand child) { + this.mojangCommand.then(child.mojangCommand); + return this; + } + + public CraterCommand withGameProfilesArgument(String key, CommandExecutorWithArgs> executor) { + this.mojangCommand.then(Commands.argument(key, GameProfileArgument.gameProfile()) + .executes(context -> executor.run( + BridgedPlayer.of(context.getSource().getPlayerOrException()), + GameProfileArgument.getGameProfiles(context, key).stream().map(BridgedGameProfile::of).toList(), + BridgedCommandSourceStack.of(context.getSource())) + )); + return this; + } + + public CraterCommand withBoolArgument(String key, CommandExecutorWithArgs executor) { + this.mojangCommand.then(Commands.argument(key, BoolArgumentType.bool()) + .executes(context -> executor.run( + BridgedPlayer.of(context.getSource().getPlayerOrException()), + BoolArgumentType.getBool(context, key), + BridgedCommandSourceStack.of(context.getSource()) + ))); + return this; + } + + public CraterCommand withWordArgument(String key, CommandExecutorWithArgs executor) { + this.mojangCommand.then(Commands.argument(key, StringArgumentType.word()) + .executes(context -> executor.run( + BridgedPlayer.of(context.getSource().getPlayerOrException()), + StringArgumentType.getString(context, key), + BridgedCommandSourceStack.of(context.getSource()) + ))); + return this; + } + + public CraterCommand withStringArgument(String key, CommandExecutorWithArgs executor) { + this.mojangCommand.then(Commands.argument(key, StringArgumentType.string()) + .executes(context -> executor.run( + BridgedPlayer.of(context.getSource().getPlayerOrException()), + StringArgumentType.getString(context, key), + BridgedCommandSourceStack.of(context.getSource()) + ))); + return this; + } + + public CraterCommand withPhraseArgument(String key, CommandExecutorWithArgs executor) { + this.mojangCommand.then(Commands.argument(key, StringArgumentType.greedyString()) + .executes(context -> executor.run( + BridgedPlayer.of(context.getSource().getPlayerOrException()), + StringArgumentType.getString(context, key), + BridgedCommandSourceStack.of(context.getSource()) + ))); + return this; + } + + public CraterCommand withIntegerArgument(String key, CommandExecutorWithArgs executor) { + this.mojangCommand.then(Commands.argument(key, IntegerArgumentType.integer()) + .executes(context -> executor.run( + BridgedPlayer.of(context.getSource().getPlayerOrException()), + IntegerArgumentType.getInteger(context, key), + BridgedCommandSourceStack.of(context.getSource()) + ))); + return this; + } + + public CraterCommand execute(SingleCommandExecutor executor) { + this.mojangCommand.executes(context -> executor.run(BridgedCommandSourceStack.of(context.getSource()))); + return this; + } + + @Deprecated(forRemoval = true) public CraterCommand executes(Consumer ctx) { - executor = ctx; - return this; + return this.execute(stack -> { + ctx.accept(stack); + return 1; + }); } - public boolean hasArguments() { - return !arguments.isEmpty(); + @Deprecated(forRemoval = true) + public CraterCommand withGameProfileArgument(String key, TriConsumer, BridgedCommandSourceStack> executor) { + return this.withGameProfilesArgument(key, (player, argument, stack) -> { + executor.accept(player, argument, stack); + return 1; + }); } + @ApiStatus.Internal + public void register(CommandDispatcher stack) { + stack.register(this.mojangCommand); + } + + private boolean checkPermission(CommandSourceStack stack) { + if (!ModloaderEnvironment.INSTANCE.isModLoaded("luckperms") || !(stack.getEntity() instanceof Player) || luckPermNode.isEmpty()) + return stack.hasPermission(this.permLevel); + + return LuckPermsCompat.INSTANCE.hasPermission((ServerPlayer) stack.getEntity(), this.luckPermNode) || stack.hasPermission(this.permLevel); + } + + @FunctionalInterface + public interface CommandExecutorWithArgs { + int run(BridgedPlayer player, S argument, BridgedCommandSourceStack stack); + } + + @FunctionalInterface + public interface SingleCommandExecutor { + int run(S stack); + } } diff --git a/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterPlayerEvent.java b/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterPlayerEvent.java index 94be675..9e7d7a2 100644 --- a/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterPlayerEvent.java +++ b/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterPlayerEvent.java @@ -4,7 +4,6 @@ import com.hypherionmc.craterlib.core.event.CraterEvent; import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer; import lombok.Getter; import lombok.RequiredArgsConstructor; -import lombok.Setter; @RequiredArgsConstructor @Getter diff --git a/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterRegisterCommandEvent.java b/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterRegisterCommandEvent.java index 269065a..5adac03 100644 --- a/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterRegisterCommandEvent.java +++ b/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterRegisterCommandEvent.java @@ -2,14 +2,17 @@ package com.hypherionmc.craterlib.api.events.server; import com.hypherionmc.craterlib.api.commands.CraterCommand; import com.hypherionmc.craterlib.core.event.CraterEvent; -import com.hypherionmc.craterlib.nojang.commands.CommandsRegistry; -import lombok.NoArgsConstructor; +import com.mojang.brigadier.CommandDispatcher; +import lombok.AllArgsConstructor; +import net.minecraft.commands.CommandSourceStack; -@NoArgsConstructor +@AllArgsConstructor public class CraterRegisterCommandEvent extends CraterEvent { + private final CommandDispatcher stack; + public void registerCommand(CraterCommand cmd) { - CommandsRegistry.INSTANCE.registerCommand(cmd); + cmd.register(stack); } } diff --git a/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/ServerStatusEvent.java b/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/ServerStatusEvent.java new file mode 100644 index 0000000..b58dafa --- /dev/null +++ b/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/ServerStatusEvent.java @@ -0,0 +1,35 @@ +package com.hypherionmc.craterlib.api.events.server; + +import com.hypherionmc.craterlib.core.event.CraterEvent; +import com.hypherionmc.craterlib.nojang.network.protocol.status.WrappedServerStatus; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.Setter; +import net.kyori.adventure.text.Component; +import org.jetbrains.annotations.Nullable; + +import java.util.Optional; + +public class ServerStatusEvent { + + @RequiredArgsConstructor + @Getter + @Setter + public static class StatusRequestEvent extends CraterEvent { + + private final Component status; + @Nullable + private Component newStatus = null; + + } + + @RequiredArgsConstructor + @Getter + @Setter + public static class FaviconRequestEvent extends CraterEvent { + + private final Optional favicon; + private Optional newIcon = Optional.empty(); + + } +} diff --git a/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/CraterConfigScreen.java b/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/CraterConfigScreen.java index fbabb4b..8b3da68 100644 --- a/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/CraterConfigScreen.java +++ b/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/CraterConfigScreen.java @@ -2,7 +2,7 @@ package com.hypherionmc.craterlib.client.gui.config; import com.hypherionmc.craterlib.CraterConstants; import com.hypherionmc.craterlib.client.gui.config.widgets.*; -import com.hypherionmc.craterlib.core.config.ModuleConfig; +import com.hypherionmc.craterlib.core.config.AbstractConfig; import com.hypherionmc.craterlib.core.config.annotations.HideFromScreen; import com.hypherionmc.craterlib.core.config.annotations.SubConfig; import com.hypherionmc.craterlib.core.config.annotations.Tooltip; @@ -45,11 +45,11 @@ public class CraterConfigScreen extends Screen { private static final int BOTTOM = 24; private final Screen parent; private final List> options = new ArrayList<>(); - private final ModuleConfig config; + private final AbstractConfig config; public double scrollerAmount; private boolean dragging; - public CraterConfigScreen(ModuleConfig config, Screen parent, Object subConfig) { + public CraterConfigScreen(AbstractConfig config, Screen parent, Object subConfig) { super(new TranslatableComponent("cl." + config.getClass().getSimpleName().toLowerCase() + ".title")); this.parent = parent; this.config = config; @@ -60,7 +60,7 @@ public class CraterConfigScreen extends Screen { } } - public CraterConfigScreen(ModuleConfig config, Screen parent) { + public CraterConfigScreen(AbstractConfig config, Screen parent) { this(config, parent, null); } diff --git a/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/SubConfigWidget.java b/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/SubConfigWidget.java index b4fa4f9..db60620 100644 --- a/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/SubConfigWidget.java +++ b/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/SubConfigWidget.java @@ -1,7 +1,7 @@ package com.hypherionmc.craterlib.client.gui.config.widgets; import com.hypherionmc.craterlib.client.gui.config.CraterConfigScreen; -import com.hypherionmc.craterlib.core.config.ModuleConfig; +import com.hypherionmc.craterlib.core.config.AbstractConfig; import com.mojang.blaze3d.vertex.PoseStack; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Font; @@ -15,10 +15,10 @@ import net.minecraft.network.chat.TranslatableComponent; public class SubConfigWidget extends AbstractConfigWidget { private final Object subConfig; - private final ModuleConfig config; + private final AbstractConfig config; private final Screen screen; - public SubConfigWidget(ModuleConfig config, Screen screen, Object subConfig) { + public SubConfigWidget(AbstractConfig config, Screen screen, Object subConfig) { this.config = config; this.subConfig = subConfig; this.screen = screen; diff --git a/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/compat/LuckPermsCompat.java b/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/compat/LuckPermsCompat.java new file mode 100644 index 0000000..a77e1f4 --- /dev/null +++ b/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/compat/LuckPermsCompat.java @@ -0,0 +1,20 @@ +package com.hypherionmc.craterlib.compat; + +import net.luckperms.api.LuckPerms; +import net.luckperms.api.LuckPermsProvider; +import net.luckperms.api.model.user.User; +import net.minecraft.server.level.ServerPlayer; + +public class LuckPermsCompat { + + public static final LuckPermsCompat INSTANCE = new LuckPermsCompat(); + private final LuckPerms luckPerms = LuckPermsProvider.get(); + + LuckPermsCompat() {} + + public boolean hasPermission(ServerPlayer player, String perm) { + User luckPermsUser = luckPerms.getPlayerAdapter(ServerPlayer.class).getUser(player); + return luckPermsUser.getCachedData().getPermissionData().checkPermission(perm).asBoolean(); + } + +} diff --git a/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/core/config/AbstractConfig.java b/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/core/config/AbstractConfig.java new file mode 100644 index 0000000..eceac79 --- /dev/null +++ b/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/core/config/AbstractConfig.java @@ -0,0 +1,71 @@ +package com.hypherionmc.craterlib.core.config; + +import com.hypherionmc.craterlib.core.config.formats.AbstractConfigFormat; +import com.hypherionmc.craterlib.core.config.formats.JsonConfigFormat; +import com.hypherionmc.craterlib.core.config.formats.TomlConfigFormat; +import lombok.Getter; +import lombok.Setter; +import me.hypherionmc.moonconfig.core.Config; +import org.jetbrains.annotations.Nullable; + +import java.io.File; + +@Getter +public abstract class AbstractConfig { + + /* Final Variables */ + private final transient File configPath; + private final transient String networkID; + private final transient String configName; + private final transient String modId; + private transient boolean wasSaveCalled = false; + + @Setter + private transient AbstractConfigFormat configFormat; + + public AbstractConfig(String modId, String configName) { + this(modId, null, configName); + } + + public AbstractConfig(String modId, @Nullable String subFolder, String configName) { + Config.setInsertionOrderPreserved(true); + + if (!configName.endsWith(".toml") && !configName.endsWith(".json")) + configName = configName + ".toml"; + + File configDir = new File("config" + (subFolder == null ? "" : File.separator + subFolder)); + configPath = new File(configDir, configName); + this.modId = modId; + this.networkID = modId + ":conf_" + configName.replace(".toml", "").replace(".json", "").replace("-", "_").toLowerCase(); + this.configName = configName.replace(".toml", "").replace(".json", ""); + configDir.mkdirs(); + + configFormat = configName.endsWith(".json") ? new JsonConfigFormat<>(configPath, this::onSave) : new TomlConfigFormat<>(configPath, this::onSave); + } + + public void registerAndSetup(S config) { + configFormat.register(config); + ConfigController.register_config(this); + this.configReloaded(); + } + + public void saveConfig(S config) { + this.wasSaveCalled = true; + configFormat.saveConfig(config); + } + + private void onSave() { + this.configReloaded(); + this.wasSaveCalled = false; + } + + public S readConfig(S config) { + return configFormat.readConfig(config); + } + + public void migrateConfig(S config) { + configFormat.migrateConfig(config); + } + + public abstract void configReloaded(); +} diff --git a/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/core/config/ConfigController.java b/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/core/config/ConfigController.java index 41c9471..760ca93 100644 --- a/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/core/config/ConfigController.java +++ b/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/core/config/ConfigController.java @@ -3,6 +3,7 @@ package com.hypherionmc.craterlib.core.config; import com.hypherionmc.craterlib.CraterConstants; import lombok.Getter; import me.hypherionmc.moonconfig.core.file.FileWatcher; +import org.apache.commons.lang3.tuple.Pair; import org.jetbrains.annotations.ApiStatus; import java.io.Serializable; @@ -18,7 +19,7 @@ public final class ConfigController implements Serializable { * Cache of registered configs */ @Getter - private static final HashMap monitoredConfigs = new HashMap<>(); + private static final HashMap> watchedConfigs = new HashMap<>(); /** * INTERNAL METHOD - Register and watch the config @@ -26,23 +27,34 @@ public final class ConfigController implements Serializable { * @param config - The config class to register and watch */ @ApiStatus.Internal + @Deprecated public static void register_config(ModuleConfig config) { - if (monitoredConfigs.containsKey(config)) { - CraterConstants.LOG.error("Failed to register " + config.getConfigPath().getName() + ". Config already registered"); + register_config((AbstractConfig) config); + } + + /** + * INTERNAL METHOD - Register and watch the config + * + * @param config - The config class to register and watch + */ + @ApiStatus.Internal + public static void register_config(AbstractConfig config) { + if (watchedConfigs.containsKey(config.getConfigPath().toString())) { + CraterConstants.LOG.error("Failed to register {}. Config already registered", config.getConfigPath().getName()); } else { FileWatcher configWatcher = new FileWatcher(); try { configWatcher.setWatch(config.getConfigPath(), () -> { - if (!config.isSaveCalled()) { - CraterConstants.LOG.info("Sending Reload Event for: " + config.getConfigPath().getName()); + if (!config.isWasSaveCalled()) { + CraterConstants.LOG.info("Sending Reload Event for: {}", config.getConfigPath().getName()); config.configReloaded(); } }); } catch (Exception e) { - CraterConstants.LOG.error("Failed to register " + config.getConfigPath().getName() + " for auto reloading. " + e.getMessage()); + CraterConstants.LOG.error("Failed to register {} for auto reloading. {}", config.getConfigPath().getName(), e.getMessage()); } - monitoredConfigs.put(config, configWatcher); - CraterConstants.LOG.info("Registered " + config.getConfigPath().getName() + " successfully!"); + watchedConfigs.put(config.getConfigPath().toString(), Pair.of(config, configWatcher)); + CraterConstants.LOG.info("Registered {} successfully!", config.getConfigPath().getName()); } } diff --git a/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/core/config/ModuleConfig.java b/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/core/config/ModuleConfig.java index 181efdc..e4850bf 100644 --- a/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/core/config/ModuleConfig.java +++ b/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/core/config/ModuleConfig.java @@ -1,9 +1,7 @@ package com.hypherionmc.craterlib.core.config; +import com.hypherionmc.craterlib.core.config.formats.TomlConfigFormat; import me.hypherionmc.moonconfig.core.CommentedConfig; -import me.hypherionmc.moonconfig.core.Config; -import me.hypherionmc.moonconfig.core.conversion.ObjectConverter; -import me.hypherionmc.moonconfig.core.file.CommentedFileConfig; import java.io.File; @@ -12,17 +10,8 @@ import java.io.File; * Base Config class containing the save, upgrading and loading logic. * All config classes must extend this class */ -public class ModuleConfig { - - /* Final Variables */ - private final transient File configPath; - private final transient String networkID; - - private final transient String configName; - - private final transient String modId; - - private transient boolean isSaveCalled = false; +@Deprecated +public class ModuleConfig extends AbstractConfig { /** * Set up the config @@ -35,20 +24,7 @@ public class ModuleConfig { } public ModuleConfig(String modId, String subFolder, String configName) { - /* Preserve the order of the config values */ - Config.setInsertionOrderPreserved(true); - - /* Configure Paths and Network SYNC ID */ - File configDir = new File("config" + (subFolder.isEmpty() ? "" : File.separator + subFolder)); - configPath = new File(configDir + File.separator + configName + ".toml"); - networkID = modId + ":conf_" + configName.replace("-", "_"); - this.modId = modId; - this.configName = configName; - - /* Check if the required directories exists, otherwise we create them */ - if (!configDir.exists()) { - configDir.mkdirs(); - } + super(modId, subFolder.isEmpty() ? null : subFolder, configName); } /** @@ -57,14 +33,7 @@ public class ModuleConfig { * @param config - The config class to use */ public void registerAndSetup(ModuleConfig config) { - if (!configPath.exists() || configPath.length() < 2) { - saveConfig(config); - } else { - migrateConfig(config); - } - /* Register the Config for Watching and events */ - ConfigController.register_config(this); - this.configReloaded(); + super.registerAndSetup(config); } /** @@ -73,16 +42,7 @@ public class ModuleConfig { * @param conf - The config class to serialize and save */ public void saveConfig(ModuleConfig conf) { - this.isSaveCalled = true; - /* Set up the Serializer and Config Object */ - ObjectConverter converter = new ObjectConverter(); - CommentedFileConfig config = CommentedFileConfig.builder(configPath).build(); - - /* Save the config and fire the reload events */ - converter.toConfig(conf, config); - config.save(); - configReloaded(); - this.isSaveCalled = false; + super.registerAndSetup(conf); } /** @@ -92,14 +52,7 @@ public class ModuleConfig { * @return - Returns the loaded version of the class */ public T loadConfig(Object conf) { - /* Set up the Serializer and Config Object */ - ObjectConverter converter = new ObjectConverter(); - CommentedFileConfig config = CommentedFileConfig.builder(configPath).build(); - config.load(); - - /* Load the config and return the loaded config */ - converter.toObject(config, conf); - return (T) conf; + return (T) super.readConfig(conf); } /** @@ -108,31 +61,13 @@ public class ModuleConfig { * @param conf - The config class to load */ public void migrateConfig(ModuleConfig conf) { - /* Set up the Serializer and Config Objects */ - CommentedFileConfig config = CommentedFileConfig.builder(configPath).build(); - CommentedFileConfig newConfig = CommentedFileConfig.builder(configPath).build(); - config.load(); - - /* Upgrade the config */ - new ObjectConverter().toConfig(conf, newConfig); - updateConfigValues(config, newConfig, newConfig, ""); - newConfig.save(); - - config.close(); - newConfig.close(); + super.migrateConfig(conf); } public void updateConfigValues(CommentedConfig oldConfig, CommentedConfig newConfig, CommentedConfig outputConfig, String subKey) { - /* Loop over the config keys and check what has changed */ - newConfig.valueMap().forEach((key, value) -> { - String finalKey = subKey + (subKey.isEmpty() ? "" : ".") + key; - if (value instanceof CommentedConfig commentedConfig) { - updateConfigValues(oldConfig, commentedConfig, outputConfig, finalKey); - } else { - outputConfig.set(finalKey, - oldConfig.contains(finalKey) ? oldConfig.get(finalKey) : value); - } - }); + if (getConfigFormat() instanceof TomlConfigFormat t) { + t.updateConfigValues(oldConfig, newConfig, outputConfig, subKey); + } } /** @@ -141,7 +76,7 @@ public class ModuleConfig { * @return - The FILE object containing the config file */ public File getConfigPath() { - return configPath; + return super.getConfigPath(); } /** @@ -150,12 +85,13 @@ public class ModuleConfig { * @return - Returns the Sync ID in format modid:config_name */ public String getNetworkID() { - return networkID; + return super.getNetworkID(); } /** * Fired whenever changes to the config are detected */ + @Override public void configReloaded() { } @@ -166,7 +102,7 @@ public class ModuleConfig { * @return */ public String getConfigName() { - return configName; + return super.getConfigName(); } /** @@ -175,10 +111,10 @@ public class ModuleConfig { * @return */ public String getModId() { - return modId; + return super.getModId(); } public boolean isSaveCalled() { - return isSaveCalled; + return super.isWasSaveCalled(); } } diff --git a/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/core/config/formats/AbstractConfigFormat.java b/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/core/config/formats/AbstractConfigFormat.java new file mode 100644 index 0000000..20511ba --- /dev/null +++ b/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/core/config/formats/AbstractConfigFormat.java @@ -0,0 +1,32 @@ +package com.hypherionmc.craterlib.core.config.formats; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import me.hypherionmc.moonconfig.core.Config; + +import java.io.File; + +@RequiredArgsConstructor +@Getter +public abstract class AbstractConfigFormat { + + private final File configPath; + private final Runnable onSave; + + public void register(S conf) { + if (!configPath.exists() || configPath.length() < 2) { + saveConfig(conf); + } else { + migrateConfig(conf); + } + } + + public boolean wasConfigChanged(Config old, Config newConfig) { + return true; + } + + public abstract void saveConfig(S config); + public abstract S readConfig(S config); + public abstract void migrateConfig(S config); + +} diff --git a/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/core/config/formats/JsonConfigFormat.java b/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/core/config/formats/JsonConfigFormat.java new file mode 100644 index 0000000..0db35fa --- /dev/null +++ b/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/core/config/formats/JsonConfigFormat.java @@ -0,0 +1,67 @@ +package com.hypherionmc.craterlib.core.config.formats; + +import me.hypherionmc.moonconfig.core.Config; +import me.hypherionmc.moonconfig.core.conversion.ObjectConverter; +import me.hypherionmc.moonconfig.core.file.FileConfig; + +import java.io.File; + +public class JsonConfigFormat extends AbstractConfigFormat { + + public JsonConfigFormat(File configPath, Runnable afterSave) { + super(configPath, afterSave); + } + + @Override + public void saveConfig(S conf) { + ObjectConverter converter = new ObjectConverter(); + FileConfig config = FileConfig.builder(getConfigPath()).sync().build(); + + converter.toConfig(conf, config); + config.save(); + getOnSave().run(); + } + + @Override + public S readConfig(S conf) { + /* Set up the Serializer and Config Object */ + ObjectConverter converter = new ObjectConverter(); + FileConfig config = FileConfig.builder(getConfigPath()).build(); + config.load(); + + /* Load the config and return the loaded config */ + converter.toObject(config, conf); + return conf; + } + + @Override + public void migrateConfig(S conf) { + /* Set up the Serializer and Config Objects */ + FileConfig config = FileConfig.builder(getConfigPath()).build(); + FileConfig newConfig = FileConfig.builder(getConfigPath()).sync().build(); + config.load(); + + /* Upgrade the config */ + if (wasConfigChanged(config, newConfig)) { + new ObjectConverter().toConfig(conf, newConfig); + updateConfigValues(config, newConfig, newConfig, ""); + newConfig.save(); + } + + config.close(); + newConfig.close(); + } + + public void updateConfigValues(Config oldConfig, Config newConfig, Config outputConfig, String subKey) { + /* Loop over the config keys and check what has changed */ + newConfig.valueMap().forEach((key, value) -> { + String finalKey = subKey + (subKey.isEmpty() ? "" : ".") + key; + if (value instanceof Config commentedConfig) { + updateConfigValues(oldConfig, commentedConfig, outputConfig, finalKey); + } else { + outputConfig.set(finalKey, + oldConfig.contains(finalKey) ? oldConfig.get(finalKey) : value); + } + }); + } +} diff --git a/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/core/config/formats/TomlConfigFormat.java b/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/core/config/formats/TomlConfigFormat.java new file mode 100644 index 0000000..e3f9763 --- /dev/null +++ b/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/core/config/formats/TomlConfigFormat.java @@ -0,0 +1,67 @@ +package com.hypherionmc.craterlib.core.config.formats; + +import me.hypherionmc.moonconfig.core.CommentedConfig; +import me.hypherionmc.moonconfig.core.conversion.ObjectConverter; +import me.hypherionmc.moonconfig.core.file.CommentedFileConfig; + +import java.io.File; + +public class TomlConfigFormat extends AbstractConfigFormat { + + public TomlConfigFormat(File configPath, Runnable onSave) { + super(configPath, onSave); + } + + @Override + public void saveConfig(S conf) { + ObjectConverter converter = new ObjectConverter(); + CommentedFileConfig config = CommentedFileConfig.builder(getConfigPath()).sync().build(); + + converter.toConfig(conf, config); + config.save(); + getOnSave().run(); + } + + @Override + public S readConfig(S conf) { + /* Set up the Serializer and Config Object */ + ObjectConverter converter = new ObjectConverter(); + CommentedFileConfig config = CommentedFileConfig.builder(getConfigPath()).build(); + config.load(); + + /* Load the config and return the loaded config */ + converter.toObject(config, conf); + return conf; + } + + @Override + public void migrateConfig(S conf) { + /* Set up the Serializer and Config Objects */ + CommentedFileConfig config = CommentedFileConfig.builder(getConfigPath()).build(); + CommentedFileConfig newConfig = CommentedFileConfig.builder(getConfigPath()).sync().build(); + config.load(); + + /* Upgrade the config */ + if (wasConfigChanged(config, newConfig)) { + new ObjectConverter().toConfig(conf, newConfig); + updateConfigValues(config, newConfig, newConfig, ""); + newConfig.save(); + } + + config.close(); + newConfig.close(); + } + + public void updateConfigValues(CommentedConfig oldConfig, CommentedConfig newConfig, CommentedConfig outputConfig, String subKey) { + /* Loop over the config keys and check what has changed */ + newConfig.valueMap().forEach((key, value) -> { + String finalKey = subKey + (subKey.isEmpty() ? "" : ".") + key; + if (value instanceof CommentedConfig commentedConfig) { + updateConfigValues(oldConfig, commentedConfig, outputConfig, finalKey); + } else { + outputConfig.set(finalKey, + oldConfig.contains(finalKey) ? oldConfig.get(finalKey) : value); + } + }); + } +} diff --git a/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/ServerStatusMixin.java b/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/ServerStatusMixin.java new file mode 100644 index 0000000..2d3999c --- /dev/null +++ b/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/ServerStatusMixin.java @@ -0,0 +1,27 @@ +package com.hypherionmc.craterlib.mixin.events; + +import com.hypherionmc.craterlib.api.events.server.ServerStatusEvent; +import com.hypherionmc.craterlib.core.event.CraterEventBus; +import com.hypherionmc.craterlib.nojang.network.protocol.status.WrappedServerStatus; +import net.minecraft.network.protocol.status.ServerStatus; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import java.util.Optional; + +@Mixin(ServerStatus.class) +public class ServerStatusMixin { + + @Inject(method = "getFavicon", at = @At("RETURN"), cancellable = true) + private void injectIconEvent(CallbackInfoReturnable cir) { + ServerStatusEvent.FaviconRequestEvent event = new ServerStatusEvent.FaviconRequestEvent(cir.getReturnValue().isEmpty() ? Optional.empty() : Optional.of(new WrappedServerStatus.WrappedFavicon(cir.getReturnValue()))); + CraterEventBus.INSTANCE.postEvent(event); + + if (event.getNewIcon().isPresent()) { + cir.setReturnValue(event.getNewIcon().get().toMojang()); + } + } + +} diff --git a/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/ServerStatusPacketListenerMixin.java b/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/ServerStatusPacketListenerMixin.java new file mode 100644 index 0000000..0a18a4f --- /dev/null +++ b/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/ServerStatusPacketListenerMixin.java @@ -0,0 +1,46 @@ +package com.hypherionmc.craterlib.mixin.events; + +import com.hypherionmc.craterlib.api.events.server.ServerStatusEvent; +import com.hypherionmc.craterlib.core.event.CraterEventBus; +import com.hypherionmc.craterlib.utils.ChatUtils; +import net.minecraft.network.Connection; +import net.minecraft.network.protocol.status.ClientboundStatusResponsePacket; +import net.minecraft.network.protocol.status.ServerStatus; +import net.minecraft.network.protocol.status.ServerboundStatusRequestPacket; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.network.ServerStatusPacketListenerImpl; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(ServerStatusPacketListenerImpl.class) +public class ServerStatusPacketListenerMixin { + + @Shadow @Final private Connection connection; + + @Shadow @Final private MinecraftServer server; + + @Inject(method = "handleStatusRequest", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/network/Connection;send(Lnet/minecraft/network/protocol/Packet;)V", + shift = At.Shift.BEFORE), + cancellable = true + ) + private void injectHandleStatusRequest(ServerboundStatusRequestPacket arg, CallbackInfo ci) { + ServerStatusEvent.StatusRequestEvent event = new ServerStatusEvent.StatusRequestEvent(ChatUtils.mojangToAdventure(server.getStatus().getDescription())); + CraterEventBus.INSTANCE.postEvent(event); + + if (event.getNewStatus() != null) { + ci.cancel(); + ServerStatus serverStatus = this.server.getStatus(); + serverStatus.setDescription(ChatUtils.adventureToMojang(event.getNewStatus())); + + this.connection.send(new ClientboundStatusResponsePacket(serverStatus)); + } + } + +} \ No newline at end of file diff --git a/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/BridgedCommandSourceStack.java b/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/BridgedCommandSourceStack.java index b14e484..d50bf58 100644 --- a/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/BridgedCommandSourceStack.java +++ b/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/BridgedCommandSourceStack.java @@ -16,6 +16,10 @@ public class BridgedCommandSourceStack { internal.sendSuccess(ChatUtils.adventureToMojang(supplier.get()), bl); } + public void sendFailure(Component text) { + internal.sendFailure(ChatUtils.adventureToMojang(text)); + } + public CommandSourceStack toMojang() { return internal; } diff --git a/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/CommandsRegistry.java b/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/CommandsRegistry.java deleted file mode 100644 index 7e777f7..0000000 --- a/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/CommandsRegistry.java +++ /dev/null @@ -1,85 +0,0 @@ -package com.hypherionmc.craterlib.nojang.commands; - -import com.hypherionmc.craterlib.api.commands.CraterCommand; -import com.hypherionmc.craterlib.nojang.authlib.BridgedGameProfile; -import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer; -import com.hypherionmc.craterlib.utils.TriConsumer; -import com.mojang.authlib.GameProfile; -import com.mojang.brigadier.CommandDispatcher; -import com.mojang.brigadier.builder.LiteralArgumentBuilder; -import lombok.AccessLevel; -import lombok.NoArgsConstructor; -import net.minecraft.commands.CommandSourceStack; -import net.minecraft.commands.Commands; -import net.minecraft.commands.arguments.GameProfileArgument; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -@NoArgsConstructor(access = AccessLevel.PRIVATE) -public class CommandsRegistry { - - public static final CommandsRegistry INSTANCE = new CommandsRegistry(); - - private final List commands = new ArrayList<>(); - - public void registerCommand(CraterCommand cmd) { - commands.add(cmd); - } - - public void registerCommands(CommandDispatcher stack) { - commands.forEach(cmd -> { - if (cmd.hasArguments()) { - CommandWithArguments.register(cmd, stack); - } else { - CommandWithoutArguments.register(cmd, stack); - } - }); - } - - static class CommandWithoutArguments { - - public static void register(CraterCommand cmd, CommandDispatcher dispatcher) { - LiteralArgumentBuilder command = Commands.literal(cmd.getCommandName()) - .requires(source -> source.hasPermission(cmd.getPermissionLevel())) - .executes(context -> { - cmd.getExecutor().accept(BridgedCommandSourceStack.of(context.getSource())); - return 1; - }); - - dispatcher.register(command); - } - - } - - @SuppressWarnings("unchecked") - static class CommandWithArguments { - - public static void register(CraterCommand cmd, CommandDispatcher dispatcher) { - LiteralArgumentBuilder command = Commands.literal(cmd.getCommandName()) - .requires(source -> source.hasPermission(cmd.getPermissionLevel())); - - cmd.getArguments().forEach((key, pair) -> command.then(Commands.argument(key, pair.getLeft()).executes(context -> { - - // This is FUCKING UGLY.... Need to improve this in the future - if (pair.getLeft() instanceof GameProfileArgument) { - Collection profiles = GameProfileArgument.getGameProfiles(context, key); - List bridgedGameProfiles = new ArrayList<>(); - - profiles.forEach(p -> bridgedGameProfiles.add(BridgedGameProfile.of(p))); - - ((TriConsumer, BridgedCommandSourceStack>) pair.getRight()) - .accept(BridgedPlayer.of(context.getSource().getPlayerOrException()), bridgedGameProfiles, BridgedCommandSourceStack.of(context.getSource())); - return 1; - } - - return 1; - }))); - - dispatcher.register(command); - } - - } - -} diff --git a/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/nojang/network/protocol/status/WrappedServerStatus.java b/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/nojang/network/protocol/status/WrappedServerStatus.java new file mode 100644 index 0000000..38cad97 --- /dev/null +++ b/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/nojang/network/protocol/status/WrappedServerStatus.java @@ -0,0 +1,42 @@ +package com.hypherionmc.craterlib.nojang.network.protocol.status; + +import org.jetbrains.annotations.ApiStatus; + +import java.nio.charset.StandardCharsets; +import java.util.Base64; + +public final class WrappedServerStatus { + + public static final class WrappedFavicon { + + private final String internal; + private final byte[] iconBytes; + + public WrappedFavicon(byte[] iconBytes) { + this.iconBytes = iconBytes; + + if (iconBytes != null) { + byte[] encoded = Base64.getEncoder().encode(iconBytes); + internal = "data:image/png;base64," + new String(encoded, StandardCharsets.UTF_8); + } else { + internal = null; + } + } + + @ApiStatus.Internal + public WrappedFavicon(String internal) { + this.internal = internal; + this.iconBytes = new byte[0]; + } + + public byte[] iconBytes() { + return iconBytes; + } + + public String toMojang() { + return internal; + } + + } + +} diff --git a/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/nojang/world/entity/player/BridgedPlayer.java b/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/nojang/world/entity/player/BridgedPlayer.java index 8aa6d49..2241836 100644 --- a/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/nojang/world/entity/player/BridgedPlayer.java +++ b/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/nojang/world/entity/player/BridgedPlayer.java @@ -57,6 +57,11 @@ public class BridgedPlayer { return null; } + public void disconnect(Component message) { + if (isServerPlayer()) + toMojangServerPlayer().connection.disconnect(ChatUtils.adventureToMojang(message)); + } + public ServerPlayer toMojangServerPlayer() { return (ServerPlayer) internal; } diff --git a/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/utils/ChatUtils.java b/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/utils/ChatUtils.java index 634d857..508a905 100644 --- a/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/utils/ChatUtils.java +++ b/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/utils/ChatUtils.java @@ -95,4 +95,11 @@ public class ChatUtils { return mojangToAdventure(new TranslatableComponent(Util.makeDescriptionId("biome", identifier.toMojang()))); } + public static net.kyori.adventure.text.Component format(String value) { + return net.kyori.adventure.text.Component.translatable(convertFormattingCodes(value)); + } + + private static String convertFormattingCodes(String input) { + return input.replaceAll("§([0-9a-fklmnor])", "\u00A7$1"); + } } diff --git a/1.18.2/Common/src/main/resources/craterlib.mixins.json b/1.18.2/Common/src/main/resources/craterlib.mixins.json index 1a739db..1462775 100644 --- a/1.18.2/Common/src/main/resources/craterlib.mixins.json +++ b/1.18.2/Common/src/main/resources/craterlib.mixins.json @@ -16,7 +16,9 @@ "events.CommandMixin", "events.PlayerAdvancementsMixin", "events.PlayerListMixin", - "events.ServerPlayerMixin" + "events.ServerPlayerMixin", + "events.ServerStatusMixin", + "events.ServerStatusPacketListenerMixin" ], "injectors": { "defaultRequire": 1 diff --git a/1.18.2/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibInitializer.java b/1.18.2/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibInitializer.java index f951a1c..92bceff 100644 --- a/1.18.2/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibInitializer.java +++ b/1.18.2/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibInitializer.java @@ -9,7 +9,6 @@ import com.hypherionmc.craterlib.core.networking.CraterPacketNetwork; import com.hypherionmc.craterlib.core.networking.data.PacketSide; import com.hypherionmc.craterlib.core.platform.ModloaderEnvironment; import com.hypherionmc.craterlib.network.CraterFabricNetworkHandler; -import com.hypherionmc.craterlib.nojang.commands.CommandsRegistry; import com.hypherionmc.craterlib.nojang.server.BridgedMinecraftServer; import net.fabricmc.api.ModInitializer; import net.fabricmc.fabric.api.command.v1.CommandRegistrationCallback; @@ -21,8 +20,7 @@ public class CraterLibInitializer implements ModInitializer { public void onInitialize() { new CraterPacketNetwork(new CraterFabricNetworkHandler(PacketSide.SERVER)); CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess) -> { - CraterEventBus.INSTANCE.postEvent(new CraterRegisterCommandEvent()); - CommandsRegistry.INSTANCE.registerCommands(dispatcher); + CraterEventBus.INSTANCE.postEvent(new CraterRegisterCommandEvent(dispatcher)); }); diff --git a/1.18.2/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibModMenuIntegration.java b/1.18.2/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibModMenuIntegration.java index 6615352..5b34ff1 100644 --- a/1.18.2/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibModMenuIntegration.java +++ b/1.18.2/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibModMenuIntegration.java @@ -2,7 +2,6 @@ package com.hypherionmc.craterlib; import com.hypherionmc.craterlib.client.gui.config.CraterConfigScreen; import com.hypherionmc.craterlib.core.config.ConfigController; -import com.hypherionmc.craterlib.core.config.ModuleConfig; import com.hypherionmc.craterlib.core.config.annotations.NoConfigScreen; import com.terraformersmc.modmenu.api.ConfigScreenFactory; import com.terraformersmc.modmenu.api.ModMenuApi; @@ -19,9 +18,9 @@ public class CraterLibModMenuIntegration implements ModMenuApi { public Map> getProvidedConfigScreenFactories() { Map> configScreens = new HashMap<>(); - ConfigController.getMonitoredConfigs().forEach((conf, watcher) -> { + ConfigController.getWatchedConfigs().forEach((conf, watcher) -> { if (!conf.getClass().isAnnotationPresent(NoConfigScreen.class)) { - configScreens.put(((ModuleConfig) conf).getModId(), screen -> new CraterConfigScreen((ModuleConfig) conf, screen)); + configScreens.put(watcher.getLeft().getModId(), screen -> new CraterConfigScreen(watcher.getLeft(), screen)); } }); diff --git a/1.18.2/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeServerEvents.java b/1.18.2/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeServerEvents.java index f354ddc..37ddf87 100644 --- a/1.18.2/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeServerEvents.java +++ b/1.18.2/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeServerEvents.java @@ -3,7 +3,6 @@ package com.hypherionmc.craterlib.common; import com.hypherionmc.craterlib.api.events.server.CraterRegisterCommandEvent; import com.hypherionmc.craterlib.api.events.server.CraterServerLifecycleEvent; import com.hypherionmc.craterlib.core.event.CraterEventBus; -import com.hypherionmc.craterlib.nojang.commands.CommandsRegistry; import com.hypherionmc.craterlib.nojang.server.BridgedMinecraftServer; import net.minecraftforge.event.RegisterCommandsEvent; import net.minecraftforge.event.server.ServerStartedEvent; @@ -36,8 +35,7 @@ public class ForgeServerEvents { @SubscribeEvent public void onCommandRegister(RegisterCommandsEvent event) { - CraterEventBus.INSTANCE.postEvent(new CraterRegisterCommandEvent()); - CommandsRegistry.INSTANCE.registerCommands(event.getDispatcher()); + CraterEventBus.INSTANCE.postEvent(new CraterRegisterCommandEvent(event.getDispatcher())); } } diff --git a/1.18.2/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java b/1.18.2/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java index c61993f..df8a51a 100644 --- a/1.18.2/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java +++ b/1.18.2/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java @@ -1,8 +1,8 @@ package com.hypherionmc.craterlib.mixin; import com.hypherionmc.craterlib.client.gui.config.CraterConfigScreen; +import com.hypherionmc.craterlib.core.config.AbstractConfig; import com.hypherionmc.craterlib.core.config.ConfigController; -import com.hypherionmc.craterlib.core.config.ModuleConfig; import com.hypherionmc.craterlib.core.config.annotations.NoConfigScreen; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.screens.Screen; @@ -28,9 +28,9 @@ public class ConfigScreenHandlerMixin { */ @Inject(at = @At("RETURN"), method = "getGuiFactoryFor", cancellable = true, remap = false) private static void injectConfigScreen(IModInfo selectedMod, CallbackInfoReturnable>> cir) { - ConfigController.getMonitoredConfigs().forEach((conf, watcher) -> { + ConfigController.getWatchedConfigs().forEach((conf, watcher) -> { if (!conf.getClass().isAnnotationPresent(NoConfigScreen.class)) { - ModuleConfig config = (ModuleConfig) conf; + AbstractConfig config = watcher.getLeft(); if (config.getModId().equals(selectedMod.getModId())) { cir.setReturnValue( Optional.of((minecraft, screen) -> new CraterConfigScreen(config, screen)) diff --git a/1.18.2/NeoForge/src/main/resources/craterlib_logo.png b/1.18.2/NeoForge/src/main/resources/craterlib_logo.png deleted file mode 100644 index ce0159c..0000000 Binary files a/1.18.2/NeoForge/src/main/resources/craterlib_logo.png and /dev/null differ diff --git a/1.18.2/README.md b/1.18.2/README.md index 49c0699..4b18d17 100644 --- a/1.18.2/README.md +++ b/1.18.2/README.md @@ -15,7 +15,7 @@ A Library mod and modding api for easier multi-version minecraft and mod loader | < 1.18.2 | ❌ | | 1.18.2-1.20.2 | ✳️ | | 1.20.4 | ✳️ | -| 1.21 | 🚧 | +| 1.21.x | ✳️ | - ❌ - Not Supported; no bug fixes or new features. - 🚧 - Work in Progress; not ready for release. diff --git a/1.18.2/build.gradle b/1.18.2/build.gradle index 3fb1410..c222e4f 100644 --- a/1.18.2/build.gradle +++ b/1.18.2/build.gradle @@ -57,11 +57,13 @@ subprojects { // All Projects shade "me.hypherionmc.moon-config:core:${moon_config}" shade "me.hypherionmc.moon-config:toml:${moon_config}" + shade "me.hypherionmc.moon-config:json:${moon_config}" shade "com.hypherionmc:rpcsdk:${rpc_sdk}" shade "me.hypherionmc.sdlink:mcdiscordformatter-1.18.1:${discord_formatter}" shade "net.kyori:adventure-api:${adventure}" shade "net.kyori:adventure-text-serializer-gson:${adventure}" + compileOnly 'net.luckperms:api:5.4' compileOnly("org.projectlombok:lombok:${lombok}") annotationProcessor("org.projectlombok:lombok:${lombok}") } diff --git a/1.18.2/gradle.properties b/1.18.2/gradle.properties index bf52fa4..4882a58 100644 --- a/1.18.2/gradle.properties +++ b/1.18.2/gradle.properties @@ -1,7 +1,7 @@ #Project version_major=2 -version_minor=0 -version_patch=3 +version_minor=1 +version_patch=0 version_build=0 #Mod diff --git a/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/api/commands/CraterCommand.java b/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/api/commands/CraterCommand.java index cc4969e..35f29f0 100644 --- a/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/api/commands/CraterCommand.java +++ b/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/api/commands/CraterCommand.java @@ -1,53 +1,155 @@ package com.hypherionmc.craterlib.api.commands; +import com.hypherionmc.craterlib.compat.LuckPermsCompat; +import com.hypherionmc.craterlib.core.platform.ModloaderEnvironment; import com.hypherionmc.craterlib.nojang.authlib.BridgedGameProfile; import com.hypherionmc.craterlib.nojang.commands.BridgedCommandSourceStack; import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer; import com.hypherionmc.craterlib.utils.TriConsumer; -import com.mojang.brigadier.arguments.ArgumentType; -import lombok.Getter; +import com.mojang.brigadier.CommandDispatcher; +import com.mojang.brigadier.arguments.BoolArgumentType; +import com.mojang.brigadier.arguments.IntegerArgumentType; +import com.mojang.brigadier.arguments.StringArgumentType; +import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import net.minecraft.commands.CommandSourceStack; +import net.minecraft.commands.Commands; import net.minecraft.commands.arguments.GameProfileArgument; -import org.apache.commons.lang3.tuple.Pair; +import net.minecraft.world.entity.player.Player; +import org.jetbrains.annotations.ApiStatus; -import java.util.HashMap; -import java.util.LinkedHashMap; import java.util.List; import java.util.function.Consumer; -@Getter public class CraterCommand { - private final HashMap, TriConsumer>> arguments = new LinkedHashMap<>(); - private Consumer executor; + private final LiteralArgumentBuilder mojangCommand; + private int permLevel = 4; + private String luckPermNode = ""; - private final String commandName; - private int permissionLevel = 4; - - CraterCommand(String commandName) { - this.commandName = commandName; + CraterCommand(LiteralArgumentBuilder cmd) { + this.mojangCommand = cmd; } public static CraterCommand literal(String commandName) { - return new CraterCommand(commandName); + return new CraterCommand(Commands.literal(commandName)); } public CraterCommand requiresPermission(int perm) { - this.permissionLevel = perm; + this.permLevel = perm; + this.mojangCommand.requires(this::checkPermission); return this; } - public CraterCommand withGameProfileArgument(String key, TriConsumer, BridgedCommandSourceStack> executor) { - arguments.put(key, Pair.of(GameProfileArgument.gameProfile(), executor)); + public CraterCommand withNode(String key) { + this.luckPermNode = key; return this; } + public CraterCommand then(CraterCommand child) { + this.mojangCommand.then(child.mojangCommand); + return this; + } + + public CraterCommand withGameProfilesArgument(String key, CommandExecutorWithArgs> executor) { + this.mojangCommand.then(Commands.argument(key, GameProfileArgument.gameProfile()) + .executes(context -> executor.run( + BridgedPlayer.of(context.getSource().getPlayer()), + GameProfileArgument.getGameProfiles(context, key).stream().map(BridgedGameProfile::of).toList(), + BridgedCommandSourceStack.of(context.getSource())) + )); + return this; + } + + public CraterCommand withBoolArgument(String key, CommandExecutorWithArgs executor) { + this.mojangCommand.then(Commands.argument(key, BoolArgumentType.bool()) + .executes(context -> executor.run( + BridgedPlayer.of(context.getSource().getPlayer()), + BoolArgumentType.getBool(context, key), + BridgedCommandSourceStack.of(context.getSource()) + ))); + return this; + } + + public CraterCommand withWordArgument(String key, CommandExecutorWithArgs executor) { + this.mojangCommand.then(Commands.argument(key, StringArgumentType.word()) + .executes(context -> executor.run( + BridgedPlayer.of(context.getSource().getPlayer()), + StringArgumentType.getString(context, key), + BridgedCommandSourceStack.of(context.getSource()) + ))); + return this; + } + + public CraterCommand withStringArgument(String key, CommandExecutorWithArgs executor) { + this.mojangCommand.then(Commands.argument(key, StringArgumentType.string()) + .executes(context -> executor.run( + BridgedPlayer.of(context.getSource().getPlayer()), + StringArgumentType.getString(context, key), + BridgedCommandSourceStack.of(context.getSource()) + ))); + return this; + } + + public CraterCommand withPhraseArgument(String key, CommandExecutorWithArgs executor) { + this.mojangCommand.then(Commands.argument(key, StringArgumentType.greedyString()) + .executes(context -> executor.run( + BridgedPlayer.of(context.getSource().getPlayer()), + StringArgumentType.getString(context, key), + BridgedCommandSourceStack.of(context.getSource()) + ))); + return this; + } + + public CraterCommand withIntegerArgument(String key, CommandExecutorWithArgs executor) { + this.mojangCommand.then(Commands.argument(key, IntegerArgumentType.integer()) + .executes(context -> executor.run( + BridgedPlayer.of(context.getSource().getPlayer()), + IntegerArgumentType.getInteger(context, key), + BridgedCommandSourceStack.of(context.getSource()) + ))); + return this; + } + + public CraterCommand execute(SingleCommandExecutor executor) { + this.mojangCommand.executes(context -> executor.run(BridgedCommandSourceStack.of(context.getSource()))); + return this; + } + + @Deprecated(forRemoval = true) public CraterCommand executes(Consumer ctx) { - executor = ctx; - return this; + return this.execute(stack -> { + ctx.accept(stack); + return 1; + }); } - public boolean hasArguments() { - return !arguments.isEmpty(); + @Deprecated(forRemoval = true) + public CraterCommand withGameProfileArgument(String key, TriConsumer, BridgedCommandSourceStack> executor) { + return this.withGameProfilesArgument(key, (player, argument, stack) -> { + executor.accept(player, argument, stack); + return 1; + }); } + @ApiStatus.Internal + public void register(CommandDispatcher stack) { + stack.register(this.mojangCommand); + } + + private boolean checkPermission(CommandSourceStack stack) { + if (!ModloaderEnvironment.INSTANCE.isModLoaded("luckperms") || !stack.isPlayer() || luckPermNode.isEmpty()) + return stack.hasPermission(this.permLevel); + + return LuckPermsCompat.INSTANCE.hasPermission(stack.getPlayer(), this.luckPermNode) || stack.hasPermission(this.permLevel); + } + + @FunctionalInterface + public interface CommandExecutorWithArgs { + int run(BridgedPlayer player, S argument, BridgedCommandSourceStack stack); + } + + @FunctionalInterface + public interface SingleCommandExecutor { + int run(S stack); + } } diff --git a/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterPlayerEvent.java b/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterPlayerEvent.java index 94be675..9e7d7a2 100644 --- a/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterPlayerEvent.java +++ b/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterPlayerEvent.java @@ -4,7 +4,6 @@ import com.hypherionmc.craterlib.core.event.CraterEvent; import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer; import lombok.Getter; import lombok.RequiredArgsConstructor; -import lombok.Setter; @RequiredArgsConstructor @Getter diff --git a/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterRegisterCommandEvent.java b/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterRegisterCommandEvent.java index 269065a..5adac03 100644 --- a/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterRegisterCommandEvent.java +++ b/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterRegisterCommandEvent.java @@ -2,14 +2,17 @@ package com.hypherionmc.craterlib.api.events.server; import com.hypherionmc.craterlib.api.commands.CraterCommand; import com.hypherionmc.craterlib.core.event.CraterEvent; -import com.hypherionmc.craterlib.nojang.commands.CommandsRegistry; -import lombok.NoArgsConstructor; +import com.mojang.brigadier.CommandDispatcher; +import lombok.AllArgsConstructor; +import net.minecraft.commands.CommandSourceStack; -@NoArgsConstructor +@AllArgsConstructor public class CraterRegisterCommandEvent extends CraterEvent { + private final CommandDispatcher stack; + public void registerCommand(CraterCommand cmd) { - CommandsRegistry.INSTANCE.registerCommand(cmd); + cmd.register(stack); } } diff --git a/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/ServerStatusEvent.java b/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/ServerStatusEvent.java new file mode 100644 index 0000000..b58dafa --- /dev/null +++ b/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/ServerStatusEvent.java @@ -0,0 +1,35 @@ +package com.hypherionmc.craterlib.api.events.server; + +import com.hypherionmc.craterlib.core.event.CraterEvent; +import com.hypherionmc.craterlib.nojang.network.protocol.status.WrappedServerStatus; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.Setter; +import net.kyori.adventure.text.Component; +import org.jetbrains.annotations.Nullable; + +import java.util.Optional; + +public class ServerStatusEvent { + + @RequiredArgsConstructor + @Getter + @Setter + public static class StatusRequestEvent extends CraterEvent { + + private final Component status; + @Nullable + private Component newStatus = null; + + } + + @RequiredArgsConstructor + @Getter + @Setter + public static class FaviconRequestEvent extends CraterEvent { + + private final Optional favicon; + private Optional newIcon = Optional.empty(); + + } +} diff --git a/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/CraterConfigScreen.java b/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/CraterConfigScreen.java index 823f2f5..4345c2d 100644 --- a/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/CraterConfigScreen.java +++ b/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/CraterConfigScreen.java @@ -2,7 +2,7 @@ package com.hypherionmc.craterlib.client.gui.config; import com.hypherionmc.craterlib.CraterConstants; import com.hypherionmc.craterlib.client.gui.config.widgets.*; -import com.hypherionmc.craterlib.core.config.ModuleConfig; +import com.hypherionmc.craterlib.core.config.AbstractConfig; import com.hypherionmc.craterlib.core.config.annotations.HideFromScreen; import com.hypherionmc.craterlib.core.config.annotations.SubConfig; import com.hypherionmc.craterlib.core.config.annotations.Tooltip; @@ -43,11 +43,11 @@ public class CraterConfigScreen extends Screen { private static final int BOTTOM = 24; private final Screen parent; private final List> options = new ArrayList<>(); - private final ModuleConfig config; + private final AbstractConfig config; public double scrollerAmount; private boolean dragging; - public CraterConfigScreen(ModuleConfig config, Screen parent, Object subConfig) { + public CraterConfigScreen(AbstractConfig config, Screen parent, Object subConfig) { super(Component.translatable("cl." + config.getClass().getSimpleName().toLowerCase() + ".title")); this.parent = parent; this.config = config; @@ -58,7 +58,7 @@ public class CraterConfigScreen extends Screen { } } - public CraterConfigScreen(ModuleConfig config, Screen parent) { + public CraterConfigScreen(AbstractConfig config, Screen parent) { this(config, parent, null); } diff --git a/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/SubConfigWidget.java b/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/SubConfigWidget.java index a4d229d..6ead50a 100644 --- a/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/SubConfigWidget.java +++ b/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/SubConfigWidget.java @@ -1,7 +1,7 @@ package com.hypherionmc.craterlib.client.gui.config.widgets; import com.hypherionmc.craterlib.client.gui.config.CraterConfigScreen; -import com.hypherionmc.craterlib.core.config.ModuleConfig; +import com.hypherionmc.craterlib.core.config.AbstractConfig; import com.mojang.blaze3d.vertex.PoseStack; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Font; @@ -15,10 +15,10 @@ import net.minecraft.network.chat.Component; public class SubConfigWidget extends AbstractConfigWidget { private final Object subConfig; - private final ModuleConfig config; + private final AbstractConfig config; private final Screen screen; - public SubConfigWidget(ModuleConfig config, Screen screen, Object subConfig) { + public SubConfigWidget(AbstractConfig config, Screen screen, Object subConfig) { this.config = config; this.subConfig = subConfig; this.screen = screen; diff --git a/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/compat/LuckPermsCompat.java b/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/compat/LuckPermsCompat.java new file mode 100644 index 0000000..a77e1f4 --- /dev/null +++ b/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/compat/LuckPermsCompat.java @@ -0,0 +1,20 @@ +package com.hypherionmc.craterlib.compat; + +import net.luckperms.api.LuckPerms; +import net.luckperms.api.LuckPermsProvider; +import net.luckperms.api.model.user.User; +import net.minecraft.server.level.ServerPlayer; + +public class LuckPermsCompat { + + public static final LuckPermsCompat INSTANCE = new LuckPermsCompat(); + private final LuckPerms luckPerms = LuckPermsProvider.get(); + + LuckPermsCompat() {} + + public boolean hasPermission(ServerPlayer player, String perm) { + User luckPermsUser = luckPerms.getPlayerAdapter(ServerPlayer.class).getUser(player); + return luckPermsUser.getCachedData().getPermissionData().checkPermission(perm).asBoolean(); + } + +} diff --git a/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/core/config/AbstractConfig.java b/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/core/config/AbstractConfig.java new file mode 100644 index 0000000..eceac79 --- /dev/null +++ b/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/core/config/AbstractConfig.java @@ -0,0 +1,71 @@ +package com.hypherionmc.craterlib.core.config; + +import com.hypherionmc.craterlib.core.config.formats.AbstractConfigFormat; +import com.hypherionmc.craterlib.core.config.formats.JsonConfigFormat; +import com.hypherionmc.craterlib.core.config.formats.TomlConfigFormat; +import lombok.Getter; +import lombok.Setter; +import me.hypherionmc.moonconfig.core.Config; +import org.jetbrains.annotations.Nullable; + +import java.io.File; + +@Getter +public abstract class AbstractConfig { + + /* Final Variables */ + private final transient File configPath; + private final transient String networkID; + private final transient String configName; + private final transient String modId; + private transient boolean wasSaveCalled = false; + + @Setter + private transient AbstractConfigFormat configFormat; + + public AbstractConfig(String modId, String configName) { + this(modId, null, configName); + } + + public AbstractConfig(String modId, @Nullable String subFolder, String configName) { + Config.setInsertionOrderPreserved(true); + + if (!configName.endsWith(".toml") && !configName.endsWith(".json")) + configName = configName + ".toml"; + + File configDir = new File("config" + (subFolder == null ? "" : File.separator + subFolder)); + configPath = new File(configDir, configName); + this.modId = modId; + this.networkID = modId + ":conf_" + configName.replace(".toml", "").replace(".json", "").replace("-", "_").toLowerCase(); + this.configName = configName.replace(".toml", "").replace(".json", ""); + configDir.mkdirs(); + + configFormat = configName.endsWith(".json") ? new JsonConfigFormat<>(configPath, this::onSave) : new TomlConfigFormat<>(configPath, this::onSave); + } + + public void registerAndSetup(S config) { + configFormat.register(config); + ConfigController.register_config(this); + this.configReloaded(); + } + + public void saveConfig(S config) { + this.wasSaveCalled = true; + configFormat.saveConfig(config); + } + + private void onSave() { + this.configReloaded(); + this.wasSaveCalled = false; + } + + public S readConfig(S config) { + return configFormat.readConfig(config); + } + + public void migrateConfig(S config) { + configFormat.migrateConfig(config); + } + + public abstract void configReloaded(); +} diff --git a/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/core/config/ConfigController.java b/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/core/config/ConfigController.java index 41c9471..760ca93 100644 --- a/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/core/config/ConfigController.java +++ b/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/core/config/ConfigController.java @@ -3,6 +3,7 @@ package com.hypherionmc.craterlib.core.config; import com.hypherionmc.craterlib.CraterConstants; import lombok.Getter; import me.hypherionmc.moonconfig.core.file.FileWatcher; +import org.apache.commons.lang3.tuple.Pair; import org.jetbrains.annotations.ApiStatus; import java.io.Serializable; @@ -18,7 +19,7 @@ public final class ConfigController implements Serializable { * Cache of registered configs */ @Getter - private static final HashMap monitoredConfigs = new HashMap<>(); + private static final HashMap> watchedConfigs = new HashMap<>(); /** * INTERNAL METHOD - Register and watch the config @@ -26,23 +27,34 @@ public final class ConfigController implements Serializable { * @param config - The config class to register and watch */ @ApiStatus.Internal + @Deprecated public static void register_config(ModuleConfig config) { - if (monitoredConfigs.containsKey(config)) { - CraterConstants.LOG.error("Failed to register " + config.getConfigPath().getName() + ". Config already registered"); + register_config((AbstractConfig) config); + } + + /** + * INTERNAL METHOD - Register and watch the config + * + * @param config - The config class to register and watch + */ + @ApiStatus.Internal + public static void register_config(AbstractConfig config) { + if (watchedConfigs.containsKey(config.getConfigPath().toString())) { + CraterConstants.LOG.error("Failed to register {}. Config already registered", config.getConfigPath().getName()); } else { FileWatcher configWatcher = new FileWatcher(); try { configWatcher.setWatch(config.getConfigPath(), () -> { - if (!config.isSaveCalled()) { - CraterConstants.LOG.info("Sending Reload Event for: " + config.getConfigPath().getName()); + if (!config.isWasSaveCalled()) { + CraterConstants.LOG.info("Sending Reload Event for: {}", config.getConfigPath().getName()); config.configReloaded(); } }); } catch (Exception e) { - CraterConstants.LOG.error("Failed to register " + config.getConfigPath().getName() + " for auto reloading. " + e.getMessage()); + CraterConstants.LOG.error("Failed to register {} for auto reloading. {}", config.getConfigPath().getName(), e.getMessage()); } - monitoredConfigs.put(config, configWatcher); - CraterConstants.LOG.info("Registered " + config.getConfigPath().getName() + " successfully!"); + watchedConfigs.put(config.getConfigPath().toString(), Pair.of(config, configWatcher)); + CraterConstants.LOG.info("Registered {} successfully!", config.getConfigPath().getName()); } } diff --git a/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/core/config/ModuleConfig.java b/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/core/config/ModuleConfig.java index 181efdc..e4850bf 100644 --- a/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/core/config/ModuleConfig.java +++ b/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/core/config/ModuleConfig.java @@ -1,9 +1,7 @@ package com.hypherionmc.craterlib.core.config; +import com.hypherionmc.craterlib.core.config.formats.TomlConfigFormat; import me.hypherionmc.moonconfig.core.CommentedConfig; -import me.hypherionmc.moonconfig.core.Config; -import me.hypherionmc.moonconfig.core.conversion.ObjectConverter; -import me.hypherionmc.moonconfig.core.file.CommentedFileConfig; import java.io.File; @@ -12,17 +10,8 @@ import java.io.File; * Base Config class containing the save, upgrading and loading logic. * All config classes must extend this class */ -public class ModuleConfig { - - /* Final Variables */ - private final transient File configPath; - private final transient String networkID; - - private final transient String configName; - - private final transient String modId; - - private transient boolean isSaveCalled = false; +@Deprecated +public class ModuleConfig extends AbstractConfig { /** * Set up the config @@ -35,20 +24,7 @@ public class ModuleConfig { } public ModuleConfig(String modId, String subFolder, String configName) { - /* Preserve the order of the config values */ - Config.setInsertionOrderPreserved(true); - - /* Configure Paths and Network SYNC ID */ - File configDir = new File("config" + (subFolder.isEmpty() ? "" : File.separator + subFolder)); - configPath = new File(configDir + File.separator + configName + ".toml"); - networkID = modId + ":conf_" + configName.replace("-", "_"); - this.modId = modId; - this.configName = configName; - - /* Check if the required directories exists, otherwise we create them */ - if (!configDir.exists()) { - configDir.mkdirs(); - } + super(modId, subFolder.isEmpty() ? null : subFolder, configName); } /** @@ -57,14 +33,7 @@ public class ModuleConfig { * @param config - The config class to use */ public void registerAndSetup(ModuleConfig config) { - if (!configPath.exists() || configPath.length() < 2) { - saveConfig(config); - } else { - migrateConfig(config); - } - /* Register the Config for Watching and events */ - ConfigController.register_config(this); - this.configReloaded(); + super.registerAndSetup(config); } /** @@ -73,16 +42,7 @@ public class ModuleConfig { * @param conf - The config class to serialize and save */ public void saveConfig(ModuleConfig conf) { - this.isSaveCalled = true; - /* Set up the Serializer and Config Object */ - ObjectConverter converter = new ObjectConverter(); - CommentedFileConfig config = CommentedFileConfig.builder(configPath).build(); - - /* Save the config and fire the reload events */ - converter.toConfig(conf, config); - config.save(); - configReloaded(); - this.isSaveCalled = false; + super.registerAndSetup(conf); } /** @@ -92,14 +52,7 @@ public class ModuleConfig { * @return - Returns the loaded version of the class */ public T loadConfig(Object conf) { - /* Set up the Serializer and Config Object */ - ObjectConverter converter = new ObjectConverter(); - CommentedFileConfig config = CommentedFileConfig.builder(configPath).build(); - config.load(); - - /* Load the config and return the loaded config */ - converter.toObject(config, conf); - return (T) conf; + return (T) super.readConfig(conf); } /** @@ -108,31 +61,13 @@ public class ModuleConfig { * @param conf - The config class to load */ public void migrateConfig(ModuleConfig conf) { - /* Set up the Serializer and Config Objects */ - CommentedFileConfig config = CommentedFileConfig.builder(configPath).build(); - CommentedFileConfig newConfig = CommentedFileConfig.builder(configPath).build(); - config.load(); - - /* Upgrade the config */ - new ObjectConverter().toConfig(conf, newConfig); - updateConfigValues(config, newConfig, newConfig, ""); - newConfig.save(); - - config.close(); - newConfig.close(); + super.migrateConfig(conf); } public void updateConfigValues(CommentedConfig oldConfig, CommentedConfig newConfig, CommentedConfig outputConfig, String subKey) { - /* Loop over the config keys and check what has changed */ - newConfig.valueMap().forEach((key, value) -> { - String finalKey = subKey + (subKey.isEmpty() ? "" : ".") + key; - if (value instanceof CommentedConfig commentedConfig) { - updateConfigValues(oldConfig, commentedConfig, outputConfig, finalKey); - } else { - outputConfig.set(finalKey, - oldConfig.contains(finalKey) ? oldConfig.get(finalKey) : value); - } - }); + if (getConfigFormat() instanceof TomlConfigFormat t) { + t.updateConfigValues(oldConfig, newConfig, outputConfig, subKey); + } } /** @@ -141,7 +76,7 @@ public class ModuleConfig { * @return - The FILE object containing the config file */ public File getConfigPath() { - return configPath; + return super.getConfigPath(); } /** @@ -150,12 +85,13 @@ public class ModuleConfig { * @return - Returns the Sync ID in format modid:config_name */ public String getNetworkID() { - return networkID; + return super.getNetworkID(); } /** * Fired whenever changes to the config are detected */ + @Override public void configReloaded() { } @@ -166,7 +102,7 @@ public class ModuleConfig { * @return */ public String getConfigName() { - return configName; + return super.getConfigName(); } /** @@ -175,10 +111,10 @@ public class ModuleConfig { * @return */ public String getModId() { - return modId; + return super.getModId(); } public boolean isSaveCalled() { - return isSaveCalled; + return super.isWasSaveCalled(); } } diff --git a/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/core/config/formats/AbstractConfigFormat.java b/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/core/config/formats/AbstractConfigFormat.java new file mode 100644 index 0000000..20511ba --- /dev/null +++ b/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/core/config/formats/AbstractConfigFormat.java @@ -0,0 +1,32 @@ +package com.hypherionmc.craterlib.core.config.formats; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import me.hypherionmc.moonconfig.core.Config; + +import java.io.File; + +@RequiredArgsConstructor +@Getter +public abstract class AbstractConfigFormat { + + private final File configPath; + private final Runnable onSave; + + public void register(S conf) { + if (!configPath.exists() || configPath.length() < 2) { + saveConfig(conf); + } else { + migrateConfig(conf); + } + } + + public boolean wasConfigChanged(Config old, Config newConfig) { + return true; + } + + public abstract void saveConfig(S config); + public abstract S readConfig(S config); + public abstract void migrateConfig(S config); + +} diff --git a/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/core/config/formats/JsonConfigFormat.java b/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/core/config/formats/JsonConfigFormat.java new file mode 100644 index 0000000..0db35fa --- /dev/null +++ b/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/core/config/formats/JsonConfigFormat.java @@ -0,0 +1,67 @@ +package com.hypherionmc.craterlib.core.config.formats; + +import me.hypherionmc.moonconfig.core.Config; +import me.hypherionmc.moonconfig.core.conversion.ObjectConverter; +import me.hypherionmc.moonconfig.core.file.FileConfig; + +import java.io.File; + +public class JsonConfigFormat extends AbstractConfigFormat { + + public JsonConfigFormat(File configPath, Runnable afterSave) { + super(configPath, afterSave); + } + + @Override + public void saveConfig(S conf) { + ObjectConverter converter = new ObjectConverter(); + FileConfig config = FileConfig.builder(getConfigPath()).sync().build(); + + converter.toConfig(conf, config); + config.save(); + getOnSave().run(); + } + + @Override + public S readConfig(S conf) { + /* Set up the Serializer and Config Object */ + ObjectConverter converter = new ObjectConverter(); + FileConfig config = FileConfig.builder(getConfigPath()).build(); + config.load(); + + /* Load the config and return the loaded config */ + converter.toObject(config, conf); + return conf; + } + + @Override + public void migrateConfig(S conf) { + /* Set up the Serializer and Config Objects */ + FileConfig config = FileConfig.builder(getConfigPath()).build(); + FileConfig newConfig = FileConfig.builder(getConfigPath()).sync().build(); + config.load(); + + /* Upgrade the config */ + if (wasConfigChanged(config, newConfig)) { + new ObjectConverter().toConfig(conf, newConfig); + updateConfigValues(config, newConfig, newConfig, ""); + newConfig.save(); + } + + config.close(); + newConfig.close(); + } + + public void updateConfigValues(Config oldConfig, Config newConfig, Config outputConfig, String subKey) { + /* Loop over the config keys and check what has changed */ + newConfig.valueMap().forEach((key, value) -> { + String finalKey = subKey + (subKey.isEmpty() ? "" : ".") + key; + if (value instanceof Config commentedConfig) { + updateConfigValues(oldConfig, commentedConfig, outputConfig, finalKey); + } else { + outputConfig.set(finalKey, + oldConfig.contains(finalKey) ? oldConfig.get(finalKey) : value); + } + }); + } +} diff --git a/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/core/config/formats/TomlConfigFormat.java b/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/core/config/formats/TomlConfigFormat.java new file mode 100644 index 0000000..e3f9763 --- /dev/null +++ b/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/core/config/formats/TomlConfigFormat.java @@ -0,0 +1,67 @@ +package com.hypherionmc.craterlib.core.config.formats; + +import me.hypherionmc.moonconfig.core.CommentedConfig; +import me.hypherionmc.moonconfig.core.conversion.ObjectConverter; +import me.hypherionmc.moonconfig.core.file.CommentedFileConfig; + +import java.io.File; + +public class TomlConfigFormat extends AbstractConfigFormat { + + public TomlConfigFormat(File configPath, Runnable onSave) { + super(configPath, onSave); + } + + @Override + public void saveConfig(S conf) { + ObjectConverter converter = new ObjectConverter(); + CommentedFileConfig config = CommentedFileConfig.builder(getConfigPath()).sync().build(); + + converter.toConfig(conf, config); + config.save(); + getOnSave().run(); + } + + @Override + public S readConfig(S conf) { + /* Set up the Serializer and Config Object */ + ObjectConverter converter = new ObjectConverter(); + CommentedFileConfig config = CommentedFileConfig.builder(getConfigPath()).build(); + config.load(); + + /* Load the config and return the loaded config */ + converter.toObject(config, conf); + return conf; + } + + @Override + public void migrateConfig(S conf) { + /* Set up the Serializer and Config Objects */ + CommentedFileConfig config = CommentedFileConfig.builder(getConfigPath()).build(); + CommentedFileConfig newConfig = CommentedFileConfig.builder(getConfigPath()).sync().build(); + config.load(); + + /* Upgrade the config */ + if (wasConfigChanged(config, newConfig)) { + new ObjectConverter().toConfig(conf, newConfig); + updateConfigValues(config, newConfig, newConfig, ""); + newConfig.save(); + } + + config.close(); + newConfig.close(); + } + + public void updateConfigValues(CommentedConfig oldConfig, CommentedConfig newConfig, CommentedConfig outputConfig, String subKey) { + /* Loop over the config keys and check what has changed */ + newConfig.valueMap().forEach((key, value) -> { + String finalKey = subKey + (subKey.isEmpty() ? "" : ".") + key; + if (value instanceof CommentedConfig commentedConfig) { + updateConfigValues(oldConfig, commentedConfig, outputConfig, finalKey); + } else { + outputConfig.set(finalKey, + oldConfig.contains(finalKey) ? oldConfig.get(finalKey) : value); + } + }); + } +} diff --git a/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/ServerStatusMixin.java b/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/ServerStatusMixin.java new file mode 100644 index 0000000..2d3999c --- /dev/null +++ b/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/ServerStatusMixin.java @@ -0,0 +1,27 @@ +package com.hypherionmc.craterlib.mixin.events; + +import com.hypherionmc.craterlib.api.events.server.ServerStatusEvent; +import com.hypherionmc.craterlib.core.event.CraterEventBus; +import com.hypherionmc.craterlib.nojang.network.protocol.status.WrappedServerStatus; +import net.minecraft.network.protocol.status.ServerStatus; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import java.util.Optional; + +@Mixin(ServerStatus.class) +public class ServerStatusMixin { + + @Inject(method = "getFavicon", at = @At("RETURN"), cancellable = true) + private void injectIconEvent(CallbackInfoReturnable cir) { + ServerStatusEvent.FaviconRequestEvent event = new ServerStatusEvent.FaviconRequestEvent(cir.getReturnValue().isEmpty() ? Optional.empty() : Optional.of(new WrappedServerStatus.WrappedFavicon(cir.getReturnValue()))); + CraterEventBus.INSTANCE.postEvent(event); + + if (event.getNewIcon().isPresent()) { + cir.setReturnValue(event.getNewIcon().get().toMojang()); + } + } + +} diff --git a/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/ServerStatusPacketListenerMixin.java b/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/ServerStatusPacketListenerMixin.java new file mode 100644 index 0000000..0a18a4f --- /dev/null +++ b/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/ServerStatusPacketListenerMixin.java @@ -0,0 +1,46 @@ +package com.hypherionmc.craterlib.mixin.events; + +import com.hypherionmc.craterlib.api.events.server.ServerStatusEvent; +import com.hypherionmc.craterlib.core.event.CraterEventBus; +import com.hypherionmc.craterlib.utils.ChatUtils; +import net.minecraft.network.Connection; +import net.minecraft.network.protocol.status.ClientboundStatusResponsePacket; +import net.minecraft.network.protocol.status.ServerStatus; +import net.minecraft.network.protocol.status.ServerboundStatusRequestPacket; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.network.ServerStatusPacketListenerImpl; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(ServerStatusPacketListenerImpl.class) +public class ServerStatusPacketListenerMixin { + + @Shadow @Final private Connection connection; + + @Shadow @Final private MinecraftServer server; + + @Inject(method = "handleStatusRequest", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/network/Connection;send(Lnet/minecraft/network/protocol/Packet;)V", + shift = At.Shift.BEFORE), + cancellable = true + ) + private void injectHandleStatusRequest(ServerboundStatusRequestPacket arg, CallbackInfo ci) { + ServerStatusEvent.StatusRequestEvent event = new ServerStatusEvent.StatusRequestEvent(ChatUtils.mojangToAdventure(server.getStatus().getDescription())); + CraterEventBus.INSTANCE.postEvent(event); + + if (event.getNewStatus() != null) { + ci.cancel(); + ServerStatus serverStatus = this.server.getStatus(); + serverStatus.setDescription(ChatUtils.adventureToMojang(event.getNewStatus())); + + this.connection.send(new ClientboundStatusResponsePacket(serverStatus)); + } + } + +} \ No newline at end of file diff --git a/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/BridgedCommandSourceStack.java b/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/BridgedCommandSourceStack.java index b14e484..d50bf58 100644 --- a/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/BridgedCommandSourceStack.java +++ b/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/BridgedCommandSourceStack.java @@ -16,6 +16,10 @@ public class BridgedCommandSourceStack { internal.sendSuccess(ChatUtils.adventureToMojang(supplier.get()), bl); } + public void sendFailure(Component text) { + internal.sendFailure(ChatUtils.adventureToMojang(text)); + } + public CommandSourceStack toMojang() { return internal; } diff --git a/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/CommandsRegistry.java b/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/CommandsRegistry.java deleted file mode 100644 index 37ad15b..0000000 --- a/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/CommandsRegistry.java +++ /dev/null @@ -1,85 +0,0 @@ -package com.hypherionmc.craterlib.nojang.commands; - -import com.hypherionmc.craterlib.api.commands.CraterCommand; -import com.hypherionmc.craterlib.nojang.authlib.BridgedGameProfile; -import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer; -import com.hypherionmc.craterlib.utils.TriConsumer; -import com.mojang.authlib.GameProfile; -import com.mojang.brigadier.CommandDispatcher; -import com.mojang.brigadier.builder.LiteralArgumentBuilder; -import lombok.AccessLevel; -import lombok.NoArgsConstructor; -import net.minecraft.commands.CommandSourceStack; -import net.minecraft.commands.Commands; -import net.minecraft.commands.arguments.GameProfileArgument; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -@NoArgsConstructor(access = AccessLevel.PRIVATE) -public class CommandsRegistry { - - public static final CommandsRegistry INSTANCE = new CommandsRegistry(); - - private final List commands = new ArrayList<>(); - - public void registerCommand(CraterCommand cmd) { - commands.add(cmd); - } - - public void registerCommands(CommandDispatcher stack) { - commands.forEach(cmd -> { - if (cmd.hasArguments()) { - CommandWithArguments.register(cmd, stack); - } else { - CommandWithoutArguments.register(cmd, stack); - } - }); - } - - static class CommandWithoutArguments { - - public static void register(CraterCommand cmd, CommandDispatcher dispatcher) { - LiteralArgumentBuilder command = Commands.literal(cmd.getCommandName()) - .requires(source -> source.hasPermission(cmd.getPermissionLevel())) - .executes(context -> { - cmd.getExecutor().accept(BridgedCommandSourceStack.of(context.getSource())); - return 1; - }); - - dispatcher.register(command); - } - - } - - @SuppressWarnings("unchecked") - static class CommandWithArguments { - - public static void register(CraterCommand cmd, CommandDispatcher dispatcher) { - LiteralArgumentBuilder command = Commands.literal(cmd.getCommandName()) - .requires(source -> source.hasPermission(cmd.getPermissionLevel())); - - cmd.getArguments().forEach((key, pair) -> command.then(Commands.argument(key, pair.getLeft()).executes(context -> { - - // This is FUCKING UGLY.... Need to improve this in the future - if (pair.getLeft() instanceof GameProfileArgument) { - Collection profiles = GameProfileArgument.getGameProfiles(context, key); - List bridgedGameProfiles = new ArrayList<>(); - - profiles.forEach(p -> bridgedGameProfiles.add(BridgedGameProfile.of(p))); - - ((TriConsumer, BridgedCommandSourceStack>) pair.getRight()) - .accept(BridgedPlayer.of(context.getSource().getPlayer()), bridgedGameProfiles, BridgedCommandSourceStack.of(context.getSource())); - return 1; - } - - return 1; - }))); - - dispatcher.register(command); - } - - } - -} diff --git a/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/nojang/network/protocol/status/WrappedServerStatus.java b/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/nojang/network/protocol/status/WrappedServerStatus.java new file mode 100644 index 0000000..12e79c7 --- /dev/null +++ b/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/nojang/network/protocol/status/WrappedServerStatus.java @@ -0,0 +1,43 @@ +package com.hypherionmc.craterlib.nojang.network.protocol.status; + +import net.minecraft.network.protocol.status.ServerStatus; +import org.jetbrains.annotations.ApiStatus; + +import java.nio.charset.StandardCharsets; +import java.util.Base64; + +public final class WrappedServerStatus { + + public static final class WrappedFavicon { + + private final String internal; + private final byte[] iconBytes; + + public WrappedFavicon(byte[] iconBytes) { + this.iconBytes = iconBytes; + + if (iconBytes != null) { + byte[] encoded = Base64.getEncoder().encode(iconBytes); + internal = "data:image/png;base64," + new String(encoded, StandardCharsets.UTF_8); + } else { + internal = null; + } + } + + @ApiStatus.Internal + public WrappedFavicon(String internal) { + this.internal = internal; + this.iconBytes = new byte[0]; + } + + public byte[] iconBytes() { + return iconBytes; + } + + public String toMojang() { + return internal; + } + + } + +} diff --git a/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/nojang/world/entity/player/BridgedPlayer.java b/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/nojang/world/entity/player/BridgedPlayer.java index 8aa6d49..2241836 100644 --- a/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/nojang/world/entity/player/BridgedPlayer.java +++ b/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/nojang/world/entity/player/BridgedPlayer.java @@ -57,6 +57,11 @@ public class BridgedPlayer { return null; } + public void disconnect(Component message) { + if (isServerPlayer()) + toMojangServerPlayer().connection.disconnect(ChatUtils.adventureToMojang(message)); + } + public ServerPlayer toMojangServerPlayer() { return (ServerPlayer) internal; } diff --git a/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/utils/ChatUtils.java b/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/utils/ChatUtils.java index af9736d..5759fde 100644 --- a/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/utils/ChatUtils.java +++ b/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/utils/ChatUtils.java @@ -92,4 +92,11 @@ public class ChatUtils { return mojangToAdventure(Component.translatable(Util.makeDescriptionId("biome", identifier.toMojang()))); } + public static net.kyori.adventure.text.Component format(String value) { + return net.kyori.adventure.text.Component.translatable(convertFormattingCodes(value)); + } + + private static String convertFormattingCodes(String input) { + return input.replaceAll("§([0-9a-fklmnor])", "\u00A7$1"); + } } diff --git a/1.19.2/Common/src/main/resources/craterlib.mixins.json b/1.19.2/Common/src/main/resources/craterlib.mixins.json index 1a739db..1462775 100644 --- a/1.19.2/Common/src/main/resources/craterlib.mixins.json +++ b/1.19.2/Common/src/main/resources/craterlib.mixins.json @@ -16,7 +16,9 @@ "events.CommandMixin", "events.PlayerAdvancementsMixin", "events.PlayerListMixin", - "events.ServerPlayerMixin" + "events.ServerPlayerMixin", + "events.ServerStatusMixin", + "events.ServerStatusPacketListenerMixin" ], "injectors": { "defaultRequire": 1 diff --git a/1.19.2/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibInitializer.java b/1.19.2/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibInitializer.java index c66c210..5e93a3a 100644 --- a/1.19.2/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibInitializer.java +++ b/1.19.2/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibInitializer.java @@ -9,7 +9,6 @@ import com.hypherionmc.craterlib.core.networking.CraterPacketNetwork; import com.hypherionmc.craterlib.core.networking.data.PacketSide; import com.hypherionmc.craterlib.core.platform.ModloaderEnvironment; import com.hypherionmc.craterlib.network.CraterFabricNetworkHandler; -import com.hypherionmc.craterlib.nojang.commands.CommandsRegistry; import com.hypherionmc.craterlib.nojang.server.BridgedMinecraftServer; import net.fabricmc.api.ModInitializer; import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback; @@ -21,8 +20,7 @@ public class CraterLibInitializer implements ModInitializer { public void onInitialize() { new CraterPacketNetwork(new CraterFabricNetworkHandler(PacketSide.SERVER)); CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> { - CraterEventBus.INSTANCE.postEvent(new CraterRegisterCommandEvent()); - CommandsRegistry.INSTANCE.registerCommands(dispatcher); + CraterEventBus.INSTANCE.postEvent(new CraterRegisterCommandEvent(dispatcher)); }); diff --git a/1.19.2/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibModMenuIntegration.java b/1.19.2/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibModMenuIntegration.java index 6615352..5b34ff1 100644 --- a/1.19.2/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibModMenuIntegration.java +++ b/1.19.2/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibModMenuIntegration.java @@ -2,7 +2,6 @@ package com.hypherionmc.craterlib; import com.hypherionmc.craterlib.client.gui.config.CraterConfigScreen; import com.hypherionmc.craterlib.core.config.ConfigController; -import com.hypherionmc.craterlib.core.config.ModuleConfig; import com.hypherionmc.craterlib.core.config.annotations.NoConfigScreen; import com.terraformersmc.modmenu.api.ConfigScreenFactory; import com.terraformersmc.modmenu.api.ModMenuApi; @@ -19,9 +18,9 @@ public class CraterLibModMenuIntegration implements ModMenuApi { public Map> getProvidedConfigScreenFactories() { Map> configScreens = new HashMap<>(); - ConfigController.getMonitoredConfigs().forEach((conf, watcher) -> { + ConfigController.getWatchedConfigs().forEach((conf, watcher) -> { if (!conf.getClass().isAnnotationPresent(NoConfigScreen.class)) { - configScreens.put(((ModuleConfig) conf).getModId(), screen -> new CraterConfigScreen((ModuleConfig) conf, screen)); + configScreens.put(watcher.getLeft().getModId(), screen -> new CraterConfigScreen(watcher.getLeft(), screen)); } }); diff --git a/1.19.2/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeServerEvents.java b/1.19.2/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeServerEvents.java index f354ddc..37ddf87 100644 --- a/1.19.2/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeServerEvents.java +++ b/1.19.2/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeServerEvents.java @@ -3,7 +3,6 @@ package com.hypherionmc.craterlib.common; import com.hypherionmc.craterlib.api.events.server.CraterRegisterCommandEvent; import com.hypherionmc.craterlib.api.events.server.CraterServerLifecycleEvent; import com.hypherionmc.craterlib.core.event.CraterEventBus; -import com.hypherionmc.craterlib.nojang.commands.CommandsRegistry; import com.hypherionmc.craterlib.nojang.server.BridgedMinecraftServer; import net.minecraftforge.event.RegisterCommandsEvent; import net.minecraftforge.event.server.ServerStartedEvent; @@ -36,8 +35,7 @@ public class ForgeServerEvents { @SubscribeEvent public void onCommandRegister(RegisterCommandsEvent event) { - CraterEventBus.INSTANCE.postEvent(new CraterRegisterCommandEvent()); - CommandsRegistry.INSTANCE.registerCommands(event.getDispatcher()); + CraterEventBus.INSTANCE.postEvent(new CraterRegisterCommandEvent(event.getDispatcher())); } } diff --git a/1.19.2/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java b/1.19.2/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java index 927bd23..d77853c 100644 --- a/1.19.2/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java +++ b/1.19.2/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java @@ -1,8 +1,8 @@ package com.hypherionmc.craterlib.mixin; import com.hypherionmc.craterlib.client.gui.config.CraterConfigScreen; +import com.hypherionmc.craterlib.core.config.AbstractConfig; import com.hypherionmc.craterlib.core.config.ConfigController; -import com.hypherionmc.craterlib.core.config.ModuleConfig; import com.hypherionmc.craterlib.core.config.annotations.NoConfigScreen; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.screens.Screen; @@ -28,9 +28,9 @@ public class ConfigScreenHandlerMixin { */ @Inject(at = @At("RETURN"), method = "getScreenFactoryFor", cancellable = true, remap = false) private static void injectConfigScreen(IModInfo selectedMod, CallbackInfoReturnable>> cir) { - ConfigController.getMonitoredConfigs().forEach((conf, watcher) -> { + ConfigController.getWatchedConfigs().forEach((conf, watcher) -> { if (!conf.getClass().isAnnotationPresent(NoConfigScreen.class)) { - ModuleConfig config = (ModuleConfig) conf; + AbstractConfig config = watcher.getLeft(); if (config.getModId().equals(selectedMod.getModId())) { cir.setReturnValue( Optional.of((minecraft, screen) -> new CraterConfigScreen(config, screen)) diff --git a/1.19.2/NeoForge/src/main/resources/craterlib_logo.png b/1.19.2/NeoForge/src/main/resources/craterlib_logo.png deleted file mode 100644 index ce0159c..0000000 Binary files a/1.19.2/NeoForge/src/main/resources/craterlib_logo.png and /dev/null differ diff --git a/1.19.2/README.md b/1.19.2/README.md index 49c0699..4b18d17 100644 --- a/1.19.2/README.md +++ b/1.19.2/README.md @@ -15,7 +15,7 @@ A Library mod and modding api for easier multi-version minecraft and mod loader | < 1.18.2 | ❌ | | 1.18.2-1.20.2 | ✳️ | | 1.20.4 | ✳️ | -| 1.21 | 🚧 | +| 1.21.x | ✳️ | - ❌ - Not Supported; no bug fixes or new features. - 🚧 - Work in Progress; not ready for release. diff --git a/1.19.2/build.gradle b/1.19.2/build.gradle index f099442..1c776ad 100644 --- a/1.19.2/build.gradle +++ b/1.19.2/build.gradle @@ -57,11 +57,13 @@ subprojects { // All Projects shade "me.hypherionmc.moon-config:core:${moon_config}" shade "me.hypherionmc.moon-config:toml:${moon_config}" + shade "me.hypherionmc.moon-config:json:${moon_config}" shade "com.hypherionmc:rpcsdk:${rpc_sdk}" shade "me.hypherionmc.sdlink:mcdiscordformatter-1.19.1:${discord_formatter}" shade "net.kyori:adventure-api:${adventure}" shade "net.kyori:adventure-text-serializer-gson:${adventure}" + compileOnly 'net.luckperms:api:5.4' compileOnly("org.projectlombok:lombok:${lombok}") annotationProcessor("org.projectlombok:lombok:${lombok}") } diff --git a/1.19.2/gradle.properties b/1.19.2/gradle.properties index 2b87c39..d681dac 100644 --- a/1.19.2/gradle.properties +++ b/1.19.2/gradle.properties @@ -1,7 +1,7 @@ #Project version_major=2 -version_minor=0 -version_patch=3 +version_minor=1 +version_patch=0 version_build=0 #Mod diff --git a/1.19.3/.jenkins/Jenkinsfile.snapshot b/1.19.3/.jenkins/Jenkinsfile.snapshot index 00ddd21..1f67c23 100644 --- a/1.19.3/.jenkins/Jenkinsfile.snapshot +++ b/1.19.3/.jenkins/Jenkinsfile.snapshot @@ -3,7 +3,7 @@ def projectIcon = "https://cdn.modrinth.com/data/Nn8Wasaq/a172c634683a11a2e9ae59 def JDK = "17"; def majorMc = "1.19.3"; def modLoaders = "forge|fabric|quilt"; -def supportedMc = "1.19.3|1.19.4"; +def supportedMc = "1.19.4"; def reltype = "snapshot"; pipeline { diff --git a/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/api/commands/CraterCommand.java b/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/api/commands/CraterCommand.java index cc4969e..35f29f0 100644 --- a/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/api/commands/CraterCommand.java +++ b/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/api/commands/CraterCommand.java @@ -1,53 +1,155 @@ package com.hypherionmc.craterlib.api.commands; +import com.hypherionmc.craterlib.compat.LuckPermsCompat; +import com.hypherionmc.craterlib.core.platform.ModloaderEnvironment; import com.hypherionmc.craterlib.nojang.authlib.BridgedGameProfile; import com.hypherionmc.craterlib.nojang.commands.BridgedCommandSourceStack; import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer; import com.hypherionmc.craterlib.utils.TriConsumer; -import com.mojang.brigadier.arguments.ArgumentType; -import lombok.Getter; +import com.mojang.brigadier.CommandDispatcher; +import com.mojang.brigadier.arguments.BoolArgumentType; +import com.mojang.brigadier.arguments.IntegerArgumentType; +import com.mojang.brigadier.arguments.StringArgumentType; +import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import net.minecraft.commands.CommandSourceStack; +import net.minecraft.commands.Commands; import net.minecraft.commands.arguments.GameProfileArgument; -import org.apache.commons.lang3.tuple.Pair; +import net.minecraft.world.entity.player.Player; +import org.jetbrains.annotations.ApiStatus; -import java.util.HashMap; -import java.util.LinkedHashMap; import java.util.List; import java.util.function.Consumer; -@Getter public class CraterCommand { - private final HashMap, TriConsumer>> arguments = new LinkedHashMap<>(); - private Consumer executor; + private final LiteralArgumentBuilder mojangCommand; + private int permLevel = 4; + private String luckPermNode = ""; - private final String commandName; - private int permissionLevel = 4; - - CraterCommand(String commandName) { - this.commandName = commandName; + CraterCommand(LiteralArgumentBuilder cmd) { + this.mojangCommand = cmd; } public static CraterCommand literal(String commandName) { - return new CraterCommand(commandName); + return new CraterCommand(Commands.literal(commandName)); } public CraterCommand requiresPermission(int perm) { - this.permissionLevel = perm; + this.permLevel = perm; + this.mojangCommand.requires(this::checkPermission); return this; } - public CraterCommand withGameProfileArgument(String key, TriConsumer, BridgedCommandSourceStack> executor) { - arguments.put(key, Pair.of(GameProfileArgument.gameProfile(), executor)); + public CraterCommand withNode(String key) { + this.luckPermNode = key; return this; } + public CraterCommand then(CraterCommand child) { + this.mojangCommand.then(child.mojangCommand); + return this; + } + + public CraterCommand withGameProfilesArgument(String key, CommandExecutorWithArgs> executor) { + this.mojangCommand.then(Commands.argument(key, GameProfileArgument.gameProfile()) + .executes(context -> executor.run( + BridgedPlayer.of(context.getSource().getPlayer()), + GameProfileArgument.getGameProfiles(context, key).stream().map(BridgedGameProfile::of).toList(), + BridgedCommandSourceStack.of(context.getSource())) + )); + return this; + } + + public CraterCommand withBoolArgument(String key, CommandExecutorWithArgs executor) { + this.mojangCommand.then(Commands.argument(key, BoolArgumentType.bool()) + .executes(context -> executor.run( + BridgedPlayer.of(context.getSource().getPlayer()), + BoolArgumentType.getBool(context, key), + BridgedCommandSourceStack.of(context.getSource()) + ))); + return this; + } + + public CraterCommand withWordArgument(String key, CommandExecutorWithArgs executor) { + this.mojangCommand.then(Commands.argument(key, StringArgumentType.word()) + .executes(context -> executor.run( + BridgedPlayer.of(context.getSource().getPlayer()), + StringArgumentType.getString(context, key), + BridgedCommandSourceStack.of(context.getSource()) + ))); + return this; + } + + public CraterCommand withStringArgument(String key, CommandExecutorWithArgs executor) { + this.mojangCommand.then(Commands.argument(key, StringArgumentType.string()) + .executes(context -> executor.run( + BridgedPlayer.of(context.getSource().getPlayer()), + StringArgumentType.getString(context, key), + BridgedCommandSourceStack.of(context.getSource()) + ))); + return this; + } + + public CraterCommand withPhraseArgument(String key, CommandExecutorWithArgs executor) { + this.mojangCommand.then(Commands.argument(key, StringArgumentType.greedyString()) + .executes(context -> executor.run( + BridgedPlayer.of(context.getSource().getPlayer()), + StringArgumentType.getString(context, key), + BridgedCommandSourceStack.of(context.getSource()) + ))); + return this; + } + + public CraterCommand withIntegerArgument(String key, CommandExecutorWithArgs executor) { + this.mojangCommand.then(Commands.argument(key, IntegerArgumentType.integer()) + .executes(context -> executor.run( + BridgedPlayer.of(context.getSource().getPlayer()), + IntegerArgumentType.getInteger(context, key), + BridgedCommandSourceStack.of(context.getSource()) + ))); + return this; + } + + public CraterCommand execute(SingleCommandExecutor executor) { + this.mojangCommand.executes(context -> executor.run(BridgedCommandSourceStack.of(context.getSource()))); + return this; + } + + @Deprecated(forRemoval = true) public CraterCommand executes(Consumer ctx) { - executor = ctx; - return this; + return this.execute(stack -> { + ctx.accept(stack); + return 1; + }); } - public boolean hasArguments() { - return !arguments.isEmpty(); + @Deprecated(forRemoval = true) + public CraterCommand withGameProfileArgument(String key, TriConsumer, BridgedCommandSourceStack> executor) { + return this.withGameProfilesArgument(key, (player, argument, stack) -> { + executor.accept(player, argument, stack); + return 1; + }); } + @ApiStatus.Internal + public void register(CommandDispatcher stack) { + stack.register(this.mojangCommand); + } + + private boolean checkPermission(CommandSourceStack stack) { + if (!ModloaderEnvironment.INSTANCE.isModLoaded("luckperms") || !stack.isPlayer() || luckPermNode.isEmpty()) + return stack.hasPermission(this.permLevel); + + return LuckPermsCompat.INSTANCE.hasPermission(stack.getPlayer(), this.luckPermNode) || stack.hasPermission(this.permLevel); + } + + @FunctionalInterface + public interface CommandExecutorWithArgs { + int run(BridgedPlayer player, S argument, BridgedCommandSourceStack stack); + } + + @FunctionalInterface + public interface SingleCommandExecutor { + int run(S stack); + } } diff --git a/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterPlayerEvent.java b/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterPlayerEvent.java index 94be675..9e7d7a2 100644 --- a/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterPlayerEvent.java +++ b/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterPlayerEvent.java @@ -4,7 +4,6 @@ import com.hypherionmc.craterlib.core.event.CraterEvent; import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer; import lombok.Getter; import lombok.RequiredArgsConstructor; -import lombok.Setter; @RequiredArgsConstructor @Getter diff --git a/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterRegisterCommandEvent.java b/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterRegisterCommandEvent.java index 269065a..5adac03 100644 --- a/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterRegisterCommandEvent.java +++ b/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterRegisterCommandEvent.java @@ -2,14 +2,17 @@ package com.hypherionmc.craterlib.api.events.server; import com.hypherionmc.craterlib.api.commands.CraterCommand; import com.hypherionmc.craterlib.core.event.CraterEvent; -import com.hypherionmc.craterlib.nojang.commands.CommandsRegistry; -import lombok.NoArgsConstructor; +import com.mojang.brigadier.CommandDispatcher; +import lombok.AllArgsConstructor; +import net.minecraft.commands.CommandSourceStack; -@NoArgsConstructor +@AllArgsConstructor public class CraterRegisterCommandEvent extends CraterEvent { + private final CommandDispatcher stack; + public void registerCommand(CraterCommand cmd) { - CommandsRegistry.INSTANCE.registerCommand(cmd); + cmd.register(stack); } } diff --git a/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/ServerStatusEvent.java b/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/ServerStatusEvent.java new file mode 100644 index 0000000..b58dafa --- /dev/null +++ b/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/ServerStatusEvent.java @@ -0,0 +1,35 @@ +package com.hypherionmc.craterlib.api.events.server; + +import com.hypherionmc.craterlib.core.event.CraterEvent; +import com.hypherionmc.craterlib.nojang.network.protocol.status.WrappedServerStatus; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.Setter; +import net.kyori.adventure.text.Component; +import org.jetbrains.annotations.Nullable; + +import java.util.Optional; + +public class ServerStatusEvent { + + @RequiredArgsConstructor + @Getter + @Setter + public static class StatusRequestEvent extends CraterEvent { + + private final Component status; + @Nullable + private Component newStatus = null; + + } + + @RequiredArgsConstructor + @Getter + @Setter + public static class FaviconRequestEvent extends CraterEvent { + + private final Optional favicon; + private Optional newIcon = Optional.empty(); + + } +} diff --git a/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/CraterConfigScreen.java b/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/CraterConfigScreen.java index d0e31a6..4f0d773 100644 --- a/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/CraterConfigScreen.java +++ b/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/CraterConfigScreen.java @@ -2,7 +2,7 @@ package com.hypherionmc.craterlib.client.gui.config; import com.hypherionmc.craterlib.CraterConstants; import com.hypherionmc.craterlib.client.gui.config.widgets.*; -import com.hypherionmc.craterlib.core.config.ModuleConfig; +import com.hypherionmc.craterlib.core.config.AbstractConfig; import com.hypherionmc.craterlib.core.config.annotations.HideFromScreen; import com.hypherionmc.craterlib.core.config.annotations.SubConfig; import com.hypherionmc.craterlib.core.config.annotations.Tooltip; @@ -43,11 +43,11 @@ public class CraterConfigScreen extends Screen { private static final int BOTTOM = 24; private final Screen parent; private final List> options = new ArrayList<>(); - private final ModuleConfig config; + private final AbstractConfig config; public double scrollerAmount; private boolean dragging; - public CraterConfigScreen(ModuleConfig config, Screen parent, Object subConfig) { + public CraterConfigScreen(AbstractConfig config, Screen parent, Object subConfig) { super(Component.translatable("cl." + config.getClass().getSimpleName().toLowerCase() + ".title")); this.parent = parent; this.config = config; @@ -58,7 +58,7 @@ public class CraterConfigScreen extends Screen { } } - public CraterConfigScreen(ModuleConfig config, Screen parent) { + public CraterConfigScreen(AbstractConfig config, Screen parent) { this(config, parent, null); } diff --git a/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/SubConfigWidget.java b/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/SubConfigWidget.java index c284781..55b8ba1 100644 --- a/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/SubConfigWidget.java +++ b/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/SubConfigWidget.java @@ -1,7 +1,7 @@ package com.hypherionmc.craterlib.client.gui.config.widgets; import com.hypherionmc.craterlib.client.gui.config.CraterConfigScreen; -import com.hypherionmc.craterlib.core.config.ModuleConfig; +import com.hypherionmc.craterlib.core.config.AbstractConfig; import com.mojang.blaze3d.vertex.PoseStack; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Font; @@ -15,10 +15,10 @@ import net.minecraft.network.chat.Component; public class SubConfigWidget extends AbstractConfigWidget { private final Object subConfig; - private final ModuleConfig config; + private final AbstractConfig config; private final Screen screen; - public SubConfigWidget(ModuleConfig config, Screen screen, Object subConfig) { + public SubConfigWidget(AbstractConfig config, Screen screen, Object subConfig) { this.config = config; this.subConfig = subConfig; this.screen = screen; diff --git a/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/compat/LuckPermsCompat.java b/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/compat/LuckPermsCompat.java new file mode 100644 index 0000000..a77e1f4 --- /dev/null +++ b/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/compat/LuckPermsCompat.java @@ -0,0 +1,20 @@ +package com.hypherionmc.craterlib.compat; + +import net.luckperms.api.LuckPerms; +import net.luckperms.api.LuckPermsProvider; +import net.luckperms.api.model.user.User; +import net.minecraft.server.level.ServerPlayer; + +public class LuckPermsCompat { + + public static final LuckPermsCompat INSTANCE = new LuckPermsCompat(); + private final LuckPerms luckPerms = LuckPermsProvider.get(); + + LuckPermsCompat() {} + + public boolean hasPermission(ServerPlayer player, String perm) { + User luckPermsUser = luckPerms.getPlayerAdapter(ServerPlayer.class).getUser(player); + return luckPermsUser.getCachedData().getPermissionData().checkPermission(perm).asBoolean(); + } + +} diff --git a/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/core/config/AbstractConfig.java b/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/core/config/AbstractConfig.java new file mode 100644 index 0000000..eceac79 --- /dev/null +++ b/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/core/config/AbstractConfig.java @@ -0,0 +1,71 @@ +package com.hypherionmc.craterlib.core.config; + +import com.hypherionmc.craterlib.core.config.formats.AbstractConfigFormat; +import com.hypherionmc.craterlib.core.config.formats.JsonConfigFormat; +import com.hypherionmc.craterlib.core.config.formats.TomlConfigFormat; +import lombok.Getter; +import lombok.Setter; +import me.hypherionmc.moonconfig.core.Config; +import org.jetbrains.annotations.Nullable; + +import java.io.File; + +@Getter +public abstract class AbstractConfig { + + /* Final Variables */ + private final transient File configPath; + private final transient String networkID; + private final transient String configName; + private final transient String modId; + private transient boolean wasSaveCalled = false; + + @Setter + private transient AbstractConfigFormat configFormat; + + public AbstractConfig(String modId, String configName) { + this(modId, null, configName); + } + + public AbstractConfig(String modId, @Nullable String subFolder, String configName) { + Config.setInsertionOrderPreserved(true); + + if (!configName.endsWith(".toml") && !configName.endsWith(".json")) + configName = configName + ".toml"; + + File configDir = new File("config" + (subFolder == null ? "" : File.separator + subFolder)); + configPath = new File(configDir, configName); + this.modId = modId; + this.networkID = modId + ":conf_" + configName.replace(".toml", "").replace(".json", "").replace("-", "_").toLowerCase(); + this.configName = configName.replace(".toml", "").replace(".json", ""); + configDir.mkdirs(); + + configFormat = configName.endsWith(".json") ? new JsonConfigFormat<>(configPath, this::onSave) : new TomlConfigFormat<>(configPath, this::onSave); + } + + public void registerAndSetup(S config) { + configFormat.register(config); + ConfigController.register_config(this); + this.configReloaded(); + } + + public void saveConfig(S config) { + this.wasSaveCalled = true; + configFormat.saveConfig(config); + } + + private void onSave() { + this.configReloaded(); + this.wasSaveCalled = false; + } + + public S readConfig(S config) { + return configFormat.readConfig(config); + } + + public void migrateConfig(S config) { + configFormat.migrateConfig(config); + } + + public abstract void configReloaded(); +} diff --git a/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/core/config/ConfigController.java b/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/core/config/ConfigController.java index 41c9471..760ca93 100644 --- a/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/core/config/ConfigController.java +++ b/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/core/config/ConfigController.java @@ -3,6 +3,7 @@ package com.hypherionmc.craterlib.core.config; import com.hypherionmc.craterlib.CraterConstants; import lombok.Getter; import me.hypherionmc.moonconfig.core.file.FileWatcher; +import org.apache.commons.lang3.tuple.Pair; import org.jetbrains.annotations.ApiStatus; import java.io.Serializable; @@ -18,7 +19,7 @@ public final class ConfigController implements Serializable { * Cache of registered configs */ @Getter - private static final HashMap monitoredConfigs = new HashMap<>(); + private static final HashMap> watchedConfigs = new HashMap<>(); /** * INTERNAL METHOD - Register and watch the config @@ -26,23 +27,34 @@ public final class ConfigController implements Serializable { * @param config - The config class to register and watch */ @ApiStatus.Internal + @Deprecated public static void register_config(ModuleConfig config) { - if (monitoredConfigs.containsKey(config)) { - CraterConstants.LOG.error("Failed to register " + config.getConfigPath().getName() + ". Config already registered"); + register_config((AbstractConfig) config); + } + + /** + * INTERNAL METHOD - Register and watch the config + * + * @param config - The config class to register and watch + */ + @ApiStatus.Internal + public static void register_config(AbstractConfig config) { + if (watchedConfigs.containsKey(config.getConfigPath().toString())) { + CraterConstants.LOG.error("Failed to register {}. Config already registered", config.getConfigPath().getName()); } else { FileWatcher configWatcher = new FileWatcher(); try { configWatcher.setWatch(config.getConfigPath(), () -> { - if (!config.isSaveCalled()) { - CraterConstants.LOG.info("Sending Reload Event for: " + config.getConfigPath().getName()); + if (!config.isWasSaveCalled()) { + CraterConstants.LOG.info("Sending Reload Event for: {}", config.getConfigPath().getName()); config.configReloaded(); } }); } catch (Exception e) { - CraterConstants.LOG.error("Failed to register " + config.getConfigPath().getName() + " for auto reloading. " + e.getMessage()); + CraterConstants.LOG.error("Failed to register {} for auto reloading. {}", config.getConfigPath().getName(), e.getMessage()); } - monitoredConfigs.put(config, configWatcher); - CraterConstants.LOG.info("Registered " + config.getConfigPath().getName() + " successfully!"); + watchedConfigs.put(config.getConfigPath().toString(), Pair.of(config, configWatcher)); + CraterConstants.LOG.info("Registered {} successfully!", config.getConfigPath().getName()); } } diff --git a/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/core/config/ModuleConfig.java b/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/core/config/ModuleConfig.java index 181efdc..e4850bf 100644 --- a/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/core/config/ModuleConfig.java +++ b/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/core/config/ModuleConfig.java @@ -1,9 +1,7 @@ package com.hypherionmc.craterlib.core.config; +import com.hypherionmc.craterlib.core.config.formats.TomlConfigFormat; import me.hypherionmc.moonconfig.core.CommentedConfig; -import me.hypherionmc.moonconfig.core.Config; -import me.hypherionmc.moonconfig.core.conversion.ObjectConverter; -import me.hypherionmc.moonconfig.core.file.CommentedFileConfig; import java.io.File; @@ -12,17 +10,8 @@ import java.io.File; * Base Config class containing the save, upgrading and loading logic. * All config classes must extend this class */ -public class ModuleConfig { - - /* Final Variables */ - private final transient File configPath; - private final transient String networkID; - - private final transient String configName; - - private final transient String modId; - - private transient boolean isSaveCalled = false; +@Deprecated +public class ModuleConfig extends AbstractConfig { /** * Set up the config @@ -35,20 +24,7 @@ public class ModuleConfig { } public ModuleConfig(String modId, String subFolder, String configName) { - /* Preserve the order of the config values */ - Config.setInsertionOrderPreserved(true); - - /* Configure Paths and Network SYNC ID */ - File configDir = new File("config" + (subFolder.isEmpty() ? "" : File.separator + subFolder)); - configPath = new File(configDir + File.separator + configName + ".toml"); - networkID = modId + ":conf_" + configName.replace("-", "_"); - this.modId = modId; - this.configName = configName; - - /* Check if the required directories exists, otherwise we create them */ - if (!configDir.exists()) { - configDir.mkdirs(); - } + super(modId, subFolder.isEmpty() ? null : subFolder, configName); } /** @@ -57,14 +33,7 @@ public class ModuleConfig { * @param config - The config class to use */ public void registerAndSetup(ModuleConfig config) { - if (!configPath.exists() || configPath.length() < 2) { - saveConfig(config); - } else { - migrateConfig(config); - } - /* Register the Config for Watching and events */ - ConfigController.register_config(this); - this.configReloaded(); + super.registerAndSetup(config); } /** @@ -73,16 +42,7 @@ public class ModuleConfig { * @param conf - The config class to serialize and save */ public void saveConfig(ModuleConfig conf) { - this.isSaveCalled = true; - /* Set up the Serializer and Config Object */ - ObjectConverter converter = new ObjectConverter(); - CommentedFileConfig config = CommentedFileConfig.builder(configPath).build(); - - /* Save the config and fire the reload events */ - converter.toConfig(conf, config); - config.save(); - configReloaded(); - this.isSaveCalled = false; + super.registerAndSetup(conf); } /** @@ -92,14 +52,7 @@ public class ModuleConfig { * @return - Returns the loaded version of the class */ public T loadConfig(Object conf) { - /* Set up the Serializer and Config Object */ - ObjectConverter converter = new ObjectConverter(); - CommentedFileConfig config = CommentedFileConfig.builder(configPath).build(); - config.load(); - - /* Load the config and return the loaded config */ - converter.toObject(config, conf); - return (T) conf; + return (T) super.readConfig(conf); } /** @@ -108,31 +61,13 @@ public class ModuleConfig { * @param conf - The config class to load */ public void migrateConfig(ModuleConfig conf) { - /* Set up the Serializer and Config Objects */ - CommentedFileConfig config = CommentedFileConfig.builder(configPath).build(); - CommentedFileConfig newConfig = CommentedFileConfig.builder(configPath).build(); - config.load(); - - /* Upgrade the config */ - new ObjectConverter().toConfig(conf, newConfig); - updateConfigValues(config, newConfig, newConfig, ""); - newConfig.save(); - - config.close(); - newConfig.close(); + super.migrateConfig(conf); } public void updateConfigValues(CommentedConfig oldConfig, CommentedConfig newConfig, CommentedConfig outputConfig, String subKey) { - /* Loop over the config keys and check what has changed */ - newConfig.valueMap().forEach((key, value) -> { - String finalKey = subKey + (subKey.isEmpty() ? "" : ".") + key; - if (value instanceof CommentedConfig commentedConfig) { - updateConfigValues(oldConfig, commentedConfig, outputConfig, finalKey); - } else { - outputConfig.set(finalKey, - oldConfig.contains(finalKey) ? oldConfig.get(finalKey) : value); - } - }); + if (getConfigFormat() instanceof TomlConfigFormat t) { + t.updateConfigValues(oldConfig, newConfig, outputConfig, subKey); + } } /** @@ -141,7 +76,7 @@ public class ModuleConfig { * @return - The FILE object containing the config file */ public File getConfigPath() { - return configPath; + return super.getConfigPath(); } /** @@ -150,12 +85,13 @@ public class ModuleConfig { * @return - Returns the Sync ID in format modid:config_name */ public String getNetworkID() { - return networkID; + return super.getNetworkID(); } /** * Fired whenever changes to the config are detected */ + @Override public void configReloaded() { } @@ -166,7 +102,7 @@ public class ModuleConfig { * @return */ public String getConfigName() { - return configName; + return super.getConfigName(); } /** @@ -175,10 +111,10 @@ public class ModuleConfig { * @return */ public String getModId() { - return modId; + return super.getModId(); } public boolean isSaveCalled() { - return isSaveCalled; + return super.isWasSaveCalled(); } } diff --git a/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/core/config/formats/AbstractConfigFormat.java b/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/core/config/formats/AbstractConfigFormat.java new file mode 100644 index 0000000..20511ba --- /dev/null +++ b/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/core/config/formats/AbstractConfigFormat.java @@ -0,0 +1,32 @@ +package com.hypherionmc.craterlib.core.config.formats; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import me.hypherionmc.moonconfig.core.Config; + +import java.io.File; + +@RequiredArgsConstructor +@Getter +public abstract class AbstractConfigFormat { + + private final File configPath; + private final Runnable onSave; + + public void register(S conf) { + if (!configPath.exists() || configPath.length() < 2) { + saveConfig(conf); + } else { + migrateConfig(conf); + } + } + + public boolean wasConfigChanged(Config old, Config newConfig) { + return true; + } + + public abstract void saveConfig(S config); + public abstract S readConfig(S config); + public abstract void migrateConfig(S config); + +} diff --git a/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/core/config/formats/JsonConfigFormat.java b/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/core/config/formats/JsonConfigFormat.java new file mode 100644 index 0000000..0db35fa --- /dev/null +++ b/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/core/config/formats/JsonConfigFormat.java @@ -0,0 +1,67 @@ +package com.hypherionmc.craterlib.core.config.formats; + +import me.hypherionmc.moonconfig.core.Config; +import me.hypherionmc.moonconfig.core.conversion.ObjectConverter; +import me.hypherionmc.moonconfig.core.file.FileConfig; + +import java.io.File; + +public class JsonConfigFormat extends AbstractConfigFormat { + + public JsonConfigFormat(File configPath, Runnable afterSave) { + super(configPath, afterSave); + } + + @Override + public void saveConfig(S conf) { + ObjectConverter converter = new ObjectConverter(); + FileConfig config = FileConfig.builder(getConfigPath()).sync().build(); + + converter.toConfig(conf, config); + config.save(); + getOnSave().run(); + } + + @Override + public S readConfig(S conf) { + /* Set up the Serializer and Config Object */ + ObjectConverter converter = new ObjectConverter(); + FileConfig config = FileConfig.builder(getConfigPath()).build(); + config.load(); + + /* Load the config and return the loaded config */ + converter.toObject(config, conf); + return conf; + } + + @Override + public void migrateConfig(S conf) { + /* Set up the Serializer and Config Objects */ + FileConfig config = FileConfig.builder(getConfigPath()).build(); + FileConfig newConfig = FileConfig.builder(getConfigPath()).sync().build(); + config.load(); + + /* Upgrade the config */ + if (wasConfigChanged(config, newConfig)) { + new ObjectConverter().toConfig(conf, newConfig); + updateConfigValues(config, newConfig, newConfig, ""); + newConfig.save(); + } + + config.close(); + newConfig.close(); + } + + public void updateConfigValues(Config oldConfig, Config newConfig, Config outputConfig, String subKey) { + /* Loop over the config keys and check what has changed */ + newConfig.valueMap().forEach((key, value) -> { + String finalKey = subKey + (subKey.isEmpty() ? "" : ".") + key; + if (value instanceof Config commentedConfig) { + updateConfigValues(oldConfig, commentedConfig, outputConfig, finalKey); + } else { + outputConfig.set(finalKey, + oldConfig.contains(finalKey) ? oldConfig.get(finalKey) : value); + } + }); + } +} diff --git a/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/core/config/formats/TomlConfigFormat.java b/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/core/config/formats/TomlConfigFormat.java new file mode 100644 index 0000000..e3f9763 --- /dev/null +++ b/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/core/config/formats/TomlConfigFormat.java @@ -0,0 +1,67 @@ +package com.hypherionmc.craterlib.core.config.formats; + +import me.hypherionmc.moonconfig.core.CommentedConfig; +import me.hypherionmc.moonconfig.core.conversion.ObjectConverter; +import me.hypherionmc.moonconfig.core.file.CommentedFileConfig; + +import java.io.File; + +public class TomlConfigFormat extends AbstractConfigFormat { + + public TomlConfigFormat(File configPath, Runnable onSave) { + super(configPath, onSave); + } + + @Override + public void saveConfig(S conf) { + ObjectConverter converter = new ObjectConverter(); + CommentedFileConfig config = CommentedFileConfig.builder(getConfigPath()).sync().build(); + + converter.toConfig(conf, config); + config.save(); + getOnSave().run(); + } + + @Override + public S readConfig(S conf) { + /* Set up the Serializer and Config Object */ + ObjectConverter converter = new ObjectConverter(); + CommentedFileConfig config = CommentedFileConfig.builder(getConfigPath()).build(); + config.load(); + + /* Load the config and return the loaded config */ + converter.toObject(config, conf); + return conf; + } + + @Override + public void migrateConfig(S conf) { + /* Set up the Serializer and Config Objects */ + CommentedFileConfig config = CommentedFileConfig.builder(getConfigPath()).build(); + CommentedFileConfig newConfig = CommentedFileConfig.builder(getConfigPath()).sync().build(); + config.load(); + + /* Upgrade the config */ + if (wasConfigChanged(config, newConfig)) { + new ObjectConverter().toConfig(conf, newConfig); + updateConfigValues(config, newConfig, newConfig, ""); + newConfig.save(); + } + + config.close(); + newConfig.close(); + } + + public void updateConfigValues(CommentedConfig oldConfig, CommentedConfig newConfig, CommentedConfig outputConfig, String subKey) { + /* Loop over the config keys and check what has changed */ + newConfig.valueMap().forEach((key, value) -> { + String finalKey = subKey + (subKey.isEmpty() ? "" : ".") + key; + if (value instanceof CommentedConfig commentedConfig) { + updateConfigValues(oldConfig, commentedConfig, outputConfig, finalKey); + } else { + outputConfig.set(finalKey, + oldConfig.contains(finalKey) ? oldConfig.get(finalKey) : value); + } + }); + } +} diff --git a/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/ServerStatusMixin.java b/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/ServerStatusMixin.java new file mode 100644 index 0000000..53985e7 --- /dev/null +++ b/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/ServerStatusMixin.java @@ -0,0 +1,27 @@ +package com.hypherionmc.craterlib.mixin.events; + +import com.hypherionmc.craterlib.api.events.server.ServerStatusEvent; +import com.hypherionmc.craterlib.core.event.CraterEventBus; +import com.hypherionmc.craterlib.nojang.network.protocol.status.WrappedServerStatus; +import net.minecraft.network.protocol.status.ServerStatus; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import java.util.Optional; + +@Mixin(ServerStatus.class) +public class ServerStatusMixin { + + @Inject(method = "favicon", at = @At("RETURN"), cancellable = true) + private void injectIconEvent(CallbackInfoReturnable> cir) { + ServerStatusEvent.FaviconRequestEvent event = new ServerStatusEvent.FaviconRequestEvent(cir.getReturnValue().isEmpty() ? Optional.empty() : Optional.of(new WrappedServerStatus.WrappedFavicon(cir.getReturnValue().get()))); + CraterEventBus.INSTANCE.postEvent(event); + + if (event.getNewIcon().isPresent()) { + cir.setReturnValue(Optional.of(event.getNewIcon().get().toMojang())); + } + } + +} diff --git a/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/BridgedCommandSourceStack.java b/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/BridgedCommandSourceStack.java index b14e484..d50bf58 100644 --- a/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/BridgedCommandSourceStack.java +++ b/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/BridgedCommandSourceStack.java @@ -16,6 +16,10 @@ public class BridgedCommandSourceStack { internal.sendSuccess(ChatUtils.adventureToMojang(supplier.get()), bl); } + public void sendFailure(Component text) { + internal.sendFailure(ChatUtils.adventureToMojang(text)); + } + public CommandSourceStack toMojang() { return internal; } diff --git a/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/CommandsRegistry.java b/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/CommandsRegistry.java deleted file mode 100644 index 37ad15b..0000000 --- a/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/CommandsRegistry.java +++ /dev/null @@ -1,85 +0,0 @@ -package com.hypherionmc.craterlib.nojang.commands; - -import com.hypherionmc.craterlib.api.commands.CraterCommand; -import com.hypherionmc.craterlib.nojang.authlib.BridgedGameProfile; -import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer; -import com.hypherionmc.craterlib.utils.TriConsumer; -import com.mojang.authlib.GameProfile; -import com.mojang.brigadier.CommandDispatcher; -import com.mojang.brigadier.builder.LiteralArgumentBuilder; -import lombok.AccessLevel; -import lombok.NoArgsConstructor; -import net.minecraft.commands.CommandSourceStack; -import net.minecraft.commands.Commands; -import net.minecraft.commands.arguments.GameProfileArgument; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -@NoArgsConstructor(access = AccessLevel.PRIVATE) -public class CommandsRegistry { - - public static final CommandsRegistry INSTANCE = new CommandsRegistry(); - - private final List commands = new ArrayList<>(); - - public void registerCommand(CraterCommand cmd) { - commands.add(cmd); - } - - public void registerCommands(CommandDispatcher stack) { - commands.forEach(cmd -> { - if (cmd.hasArguments()) { - CommandWithArguments.register(cmd, stack); - } else { - CommandWithoutArguments.register(cmd, stack); - } - }); - } - - static class CommandWithoutArguments { - - public static void register(CraterCommand cmd, CommandDispatcher dispatcher) { - LiteralArgumentBuilder command = Commands.literal(cmd.getCommandName()) - .requires(source -> source.hasPermission(cmd.getPermissionLevel())) - .executes(context -> { - cmd.getExecutor().accept(BridgedCommandSourceStack.of(context.getSource())); - return 1; - }); - - dispatcher.register(command); - } - - } - - @SuppressWarnings("unchecked") - static class CommandWithArguments { - - public static void register(CraterCommand cmd, CommandDispatcher dispatcher) { - LiteralArgumentBuilder command = Commands.literal(cmd.getCommandName()) - .requires(source -> source.hasPermission(cmd.getPermissionLevel())); - - cmd.getArguments().forEach((key, pair) -> command.then(Commands.argument(key, pair.getLeft()).executes(context -> { - - // This is FUCKING UGLY.... Need to improve this in the future - if (pair.getLeft() instanceof GameProfileArgument) { - Collection profiles = GameProfileArgument.getGameProfiles(context, key); - List bridgedGameProfiles = new ArrayList<>(); - - profiles.forEach(p -> bridgedGameProfiles.add(BridgedGameProfile.of(p))); - - ((TriConsumer, BridgedCommandSourceStack>) pair.getRight()) - .accept(BridgedPlayer.of(context.getSource().getPlayer()), bridgedGameProfiles, BridgedCommandSourceStack.of(context.getSource())); - return 1; - } - - return 1; - }))); - - dispatcher.register(command); - } - - } - -} diff --git a/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/nojang/network/protocol/status/WrappedServerStatus.java b/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/nojang/network/protocol/status/WrappedServerStatus.java new file mode 100644 index 0000000..ae6f773 --- /dev/null +++ b/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/nojang/network/protocol/status/WrappedServerStatus.java @@ -0,0 +1,31 @@ +package com.hypherionmc.craterlib.nojang.network.protocol.status; + +import net.minecraft.network.protocol.status.ServerStatus; +import org.jetbrains.annotations.ApiStatus; + +public final class WrappedServerStatus { + + public static final class WrappedFavicon { + + private final ServerStatus.Favicon internal; + + public WrappedFavicon(byte[] iconBytes) { + internal = new ServerStatus.Favicon(iconBytes); + } + + @ApiStatus.Internal + public WrappedFavicon(ServerStatus.Favicon internal) { + this.internal = internal; + } + + public byte[] iconBytes() { + return internal.iconBytes(); + } + + public ServerStatus.Favicon toMojang() { + return internal; + } + + } + +} diff --git a/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/nojang/world/entity/player/BridgedPlayer.java b/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/nojang/world/entity/player/BridgedPlayer.java index 8aa6d49..2241836 100644 --- a/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/nojang/world/entity/player/BridgedPlayer.java +++ b/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/nojang/world/entity/player/BridgedPlayer.java @@ -57,6 +57,11 @@ public class BridgedPlayer { return null; } + public void disconnect(Component message) { + if (isServerPlayer()) + toMojangServerPlayer().connection.disconnect(ChatUtils.adventureToMojang(message)); + } + public ServerPlayer toMojangServerPlayer() { return (ServerPlayer) internal; } diff --git a/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/utils/ChatUtils.java b/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/utils/ChatUtils.java index af9736d..5759fde 100644 --- a/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/utils/ChatUtils.java +++ b/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/utils/ChatUtils.java @@ -92,4 +92,11 @@ public class ChatUtils { return mojangToAdventure(Component.translatable(Util.makeDescriptionId("biome", identifier.toMojang()))); } + public static net.kyori.adventure.text.Component format(String value) { + return net.kyori.adventure.text.Component.translatable(convertFormattingCodes(value)); + } + + private static String convertFormattingCodes(String input) { + return input.replaceAll("§([0-9a-fklmnor])", "\u00A7$1"); + } } diff --git a/1.19.3/Common/src/main/resources/craterlib.mixins.json b/1.19.3/Common/src/main/resources/craterlib.mixins.json index 1a739db..c910ed2 100644 --- a/1.19.3/Common/src/main/resources/craterlib.mixins.json +++ b/1.19.3/Common/src/main/resources/craterlib.mixins.json @@ -16,7 +16,8 @@ "events.CommandMixin", "events.PlayerAdvancementsMixin", "events.PlayerListMixin", - "events.ServerPlayerMixin" + "events.ServerPlayerMixin", + "events.ServerStatusMixin" ], "injectors": { "defaultRequire": 1 diff --git a/1.19.3/Fabric/build.gradle b/1.19.3/Fabric/build.gradle index 0641b33..bfa9be2 100644 --- a/1.19.3/Fabric/build.gradle +++ b/1.19.3/Fabric/build.gradle @@ -113,8 +113,8 @@ publisher { setVersionType("release") setChangelog("https://raw.githubusercontent.com/hypherionmc/changelogs/main/craterlib/changelog-fabric.md") setProjectVersion("${minecraft_version}-${project.version}") - setDisplayName("[FABRIC/QUILT 1.19.3/1.19.4] CraterLib - ${project.version}") - setGameVersions("1.19.3", "1.19.4") + setDisplayName("[FABRIC/QUILT 1.19.4] CraterLib - ${project.version}") + setGameVersions("1.19.4") setLoaders("fabric", "quilt") setArtifact(remapJar) setCurseEnvironment("both") diff --git a/1.19.3/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibInitializer.java b/1.19.3/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibInitializer.java index c66c210..5e93a3a 100644 --- a/1.19.3/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibInitializer.java +++ b/1.19.3/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibInitializer.java @@ -9,7 +9,6 @@ import com.hypherionmc.craterlib.core.networking.CraterPacketNetwork; import com.hypherionmc.craterlib.core.networking.data.PacketSide; import com.hypherionmc.craterlib.core.platform.ModloaderEnvironment; import com.hypherionmc.craterlib.network.CraterFabricNetworkHandler; -import com.hypherionmc.craterlib.nojang.commands.CommandsRegistry; import com.hypherionmc.craterlib.nojang.server.BridgedMinecraftServer; import net.fabricmc.api.ModInitializer; import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback; @@ -21,8 +20,7 @@ public class CraterLibInitializer implements ModInitializer { public void onInitialize() { new CraterPacketNetwork(new CraterFabricNetworkHandler(PacketSide.SERVER)); CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> { - CraterEventBus.INSTANCE.postEvent(new CraterRegisterCommandEvent()); - CommandsRegistry.INSTANCE.registerCommands(dispatcher); + CraterEventBus.INSTANCE.postEvent(new CraterRegisterCommandEvent(dispatcher)); }); diff --git a/1.19.3/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibModMenuIntegration.java b/1.19.3/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibModMenuIntegration.java index 6615352..5b34ff1 100644 --- a/1.19.3/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibModMenuIntegration.java +++ b/1.19.3/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibModMenuIntegration.java @@ -2,7 +2,6 @@ package com.hypherionmc.craterlib; import com.hypherionmc.craterlib.client.gui.config.CraterConfigScreen; import com.hypherionmc.craterlib.core.config.ConfigController; -import com.hypherionmc.craterlib.core.config.ModuleConfig; import com.hypherionmc.craterlib.core.config.annotations.NoConfigScreen; import com.terraformersmc.modmenu.api.ConfigScreenFactory; import com.terraformersmc.modmenu.api.ModMenuApi; @@ -19,9 +18,9 @@ public class CraterLibModMenuIntegration implements ModMenuApi { public Map> getProvidedConfigScreenFactories() { Map> configScreens = new HashMap<>(); - ConfigController.getMonitoredConfigs().forEach((conf, watcher) -> { + ConfigController.getWatchedConfigs().forEach((conf, watcher) -> { if (!conf.getClass().isAnnotationPresent(NoConfigScreen.class)) { - configScreens.put(((ModuleConfig) conf).getModId(), screen -> new CraterConfigScreen((ModuleConfig) conf, screen)); + configScreens.put(watcher.getLeft().getModId(), screen -> new CraterConfigScreen(watcher.getLeft(), screen)); } }); diff --git a/1.19.3/Fabric/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java b/1.19.3/Fabric/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java new file mode 100644 index 0000000..f3dc866 --- /dev/null +++ b/1.19.3/Fabric/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java @@ -0,0 +1,52 @@ +package com.hypherionmc.craterlib.mixin; + +import com.hypherionmc.craterlib.api.events.server.ServerStatusEvent; +import com.hypherionmc.craterlib.core.event.CraterEventBus; +import com.hypherionmc.craterlib.utils.ChatUtils; +import net.minecraft.network.Connection; +import net.minecraft.network.protocol.status.ClientboundStatusResponsePacket; +import net.minecraft.network.protocol.status.ServerStatus; +import net.minecraft.network.protocol.status.ServerboundStatusRequestPacket; +import net.minecraft.server.network.ServerStatusPacketListenerImpl; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(ServerStatusPacketListenerImpl.class) +public class ServerStatusPacketListenerMixin { + + @Shadow + @Final + private ServerStatus status; + + @Shadow @Final private Connection connection; + + @Inject(method = "handleStatusRequest", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/network/Connection;send(Lnet/minecraft/network/protocol/Packet;)V", + shift = At.Shift.BEFORE), + cancellable = true + ) + private void injectHandleStatusRequest(ServerboundStatusRequestPacket arg, CallbackInfo ci) { + ServerStatusEvent.StatusRequestEvent event = new ServerStatusEvent.StatusRequestEvent(ChatUtils.mojangToAdventure(status.description())); + CraterEventBus.INSTANCE.postEvent(event); + + if (event.getNewStatus() != null) { + ci.cancel(); + this.connection.send(new ClientboundStatusResponsePacket( + new ServerStatus(ChatUtils.adventureToMojang( + event.getNewStatus()), + status.players(), + status.version(), + status.favicon(), + status.enforcesSecureChat() + ) + )); + } + } + +} \ No newline at end of file diff --git a/1.19.3/Fabric/src/main/resources/craterlib.fabric.mixins.json b/1.19.3/Fabric/src/main/resources/craterlib.fabric.mixins.json index 7c59043..a6d0bc1 100644 --- a/1.19.3/Fabric/src/main/resources/craterlib.fabric.mixins.json +++ b/1.19.3/Fabric/src/main/resources/craterlib.fabric.mixins.json @@ -9,7 +9,8 @@ "TutorialMixin" ], "server": [ - "ServerGamePacketListenerImplMixin" + "ServerGamePacketListenerImplMixin", + "ServerStatusPacketListenerMixin" ], "injectors": { "defaultRequire": 1 diff --git a/1.19.3/Fabric/src/main/resources/fabric.mod.json b/1.19.3/Fabric/src/main/resources/fabric.mod.json index 1f3ba7c..4ff5872 100644 --- a/1.19.3/Fabric/src/main/resources/fabric.mod.json +++ b/1.19.3/Fabric/src/main/resources/fabric.mod.json @@ -33,7 +33,7 @@ "depends": { "fabricloader": ">=0.15.0", "fabric-api": "*", - "minecraft": ">=1.19.3", + "minecraft": ">=1.19.4", "java": ">=17" } } diff --git a/1.19.3/Forge/build.gradle b/1.19.3/Forge/build.gradle index 76719c8..59bf756 100644 --- a/1.19.3/Forge/build.gradle +++ b/1.19.3/Forge/build.gradle @@ -107,8 +107,8 @@ publisher { setVersionType("release") setChangelog("https://raw.githubusercontent.com/hypherionmc/changelogs/main/craterlib/changelog-forge.md") setProjectVersion("${minecraft_version}-${project.version}") - setDisplayName("[Forge 1.19.3/1.19.4] CraterLib - ${project.version}") - setGameVersions("1.19.3", "1.19.4") + setDisplayName("[Forge 1.19.4] CraterLib - ${project.version}") + setGameVersions("1.19.4") setLoaders("forge") setArtifact(remapJar) setCurseEnvironment("both") diff --git a/1.19.3/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeServerEvents.java b/1.19.3/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeServerEvents.java index f354ddc..37ddf87 100644 --- a/1.19.3/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeServerEvents.java +++ b/1.19.3/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeServerEvents.java @@ -3,7 +3,6 @@ package com.hypherionmc.craterlib.common; import com.hypherionmc.craterlib.api.events.server.CraterRegisterCommandEvent; import com.hypherionmc.craterlib.api.events.server.CraterServerLifecycleEvent; import com.hypherionmc.craterlib.core.event.CraterEventBus; -import com.hypherionmc.craterlib.nojang.commands.CommandsRegistry; import com.hypherionmc.craterlib.nojang.server.BridgedMinecraftServer; import net.minecraftforge.event.RegisterCommandsEvent; import net.minecraftforge.event.server.ServerStartedEvent; @@ -36,8 +35,7 @@ public class ForgeServerEvents { @SubscribeEvent public void onCommandRegister(RegisterCommandsEvent event) { - CraterEventBus.INSTANCE.postEvent(new CraterRegisterCommandEvent()); - CommandsRegistry.INSTANCE.registerCommands(event.getDispatcher()); + CraterEventBus.INSTANCE.postEvent(new CraterRegisterCommandEvent(event.getDispatcher())); } } diff --git a/1.19.3/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java b/1.19.3/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java index 927bd23..78fb62b 100644 --- a/1.19.3/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java +++ b/1.19.3/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java @@ -1,6 +1,7 @@ package com.hypherionmc.craterlib.mixin; import com.hypherionmc.craterlib.client.gui.config.CraterConfigScreen; +import com.hypherionmc.craterlib.core.config.AbstractConfig; import com.hypherionmc.craterlib.core.config.ConfigController; import com.hypherionmc.craterlib.core.config.ModuleConfig; import com.hypherionmc.craterlib.core.config.annotations.NoConfigScreen; @@ -28,9 +29,9 @@ public class ConfigScreenHandlerMixin { */ @Inject(at = @At("RETURN"), method = "getScreenFactoryFor", cancellable = true, remap = false) private static void injectConfigScreen(IModInfo selectedMod, CallbackInfoReturnable>> cir) { - ConfigController.getMonitoredConfigs().forEach((conf, watcher) -> { + ConfigController.getWatchedConfigs().forEach((conf, watcher) -> { if (!conf.getClass().isAnnotationPresent(NoConfigScreen.class)) { - ModuleConfig config = (ModuleConfig) conf; + AbstractConfig config = watcher.getLeft(); if (config.getModId().equals(selectedMod.getModId())) { cir.setReturnValue( Optional.of((minecraft, screen) -> new CraterConfigScreen(config, screen)) diff --git a/1.19.3/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java b/1.19.3/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java new file mode 100644 index 0000000..969b05d --- /dev/null +++ b/1.19.3/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java @@ -0,0 +1,53 @@ +package com.hypherionmc.craterlib.mixin; + +import com.hypherionmc.craterlib.api.events.server.ServerStatusEvent; +import com.hypherionmc.craterlib.core.event.CraterEventBus; +import com.hypherionmc.craterlib.utils.ChatUtils; +import net.minecraft.network.Connection; +import net.minecraft.network.protocol.status.ClientboundStatusResponsePacket; +import net.minecraft.network.protocol.status.ServerStatus; +import net.minecraft.network.protocol.status.ServerboundStatusRequestPacket; +import net.minecraft.server.network.ServerStatusPacketListenerImpl; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(ServerStatusPacketListenerImpl.class) +public class ServerStatusPacketListenerMixin { + + @Shadow + @Final + private ServerStatus status; + + @Shadow @Final private Connection connection; + + @Inject(method = "handleStatusRequest", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/network/Connection;send(Lnet/minecraft/network/protocol/Packet;)V", + shift = At.Shift.BEFORE), + cancellable = true + ) + private void injectHandleStatusRequest(ServerboundStatusRequestPacket arg, CallbackInfo ci) { + ServerStatusEvent.StatusRequestEvent event = new ServerStatusEvent.StatusRequestEvent(ChatUtils.mojangToAdventure(status.description())); + CraterEventBus.INSTANCE.postEvent(event); + + if (event.getNewStatus() != null) { + ci.cancel(); + this.connection.send(new ClientboundStatusResponsePacket( + new ServerStatus(ChatUtils.adventureToMojang( + event.getNewStatus()), + status.players(), + status.version(), + status.favicon(), + status.enforcesSecureChat(), + status.forgeData() + ) + )); + } + } + +} diff --git a/1.19.3/Forge/src/main/resources/META-INF/mods.toml b/1.19.3/Forge/src/main/resources/META-INF/mods.toml index e6ebdd7..3d712a0 100644 --- a/1.19.3/Forge/src/main/resources/META-INF/mods.toml +++ b/1.19.3/Forge/src/main/resources/META-INF/mods.toml @@ -1,5 +1,5 @@ modLoader = "javafml" -loaderVersion = "[44,)" +loaderVersion = "[45,)" license = "MIT" issueTrackerURL = "https://github.com/firstdarkdev/craterLib/issues" @@ -19,13 +19,13 @@ issueTrackerURL = "https://github.com/firstdarkdev/craterLib/issues" [[dependencies.${ mod_id }]] modId = "forge" mandatory = true - versionRange = "[44,)" + versionRange = "[45,)" ordering = "NONE" side = "BOTH" [[dependencies.${ mod_id }]] modId = "minecraft" mandatory = true - versionRange = "[1.19.3,1.20)" + versionRange = "[1.19.4,1.20)" ordering = "NONE" side = "BOTH" diff --git a/1.19.3/Forge/src/main/resources/craterlib.forge.mixins.json b/1.19.3/Forge/src/main/resources/craterlib.forge.mixins.json index aa072d1..892f6d7 100644 --- a/1.19.3/Forge/src/main/resources/craterlib.forge.mixins.json +++ b/1.19.3/Forge/src/main/resources/craterlib.forge.mixins.json @@ -9,7 +9,8 @@ "ConfigScreenHandlerMixin" ], "server": [ - "ServerGamePacketListenerImplMixin" + "ServerGamePacketListenerImplMixin", + "ServerStatusPacketListenerMixin" ], "injectors": { "defaultRequire": 1 diff --git a/1.19.3/NeoForge/src/main/resources/craterlib_logo.png b/1.19.3/NeoForge/src/main/resources/craterlib_logo.png deleted file mode 100644 index ce0159c..0000000 Binary files a/1.19.3/NeoForge/src/main/resources/craterlib_logo.png and /dev/null differ diff --git a/1.19.3/README.md b/1.19.3/README.md index 1e3cffb..5cf4e46 100644 --- a/1.19.3/README.md +++ b/1.19.3/README.md @@ -15,8 +15,8 @@ A Library mod and modding api for easier multi-version minecraft and mod loader | < 1.18.2 | ❌ | | 1.18.2-1.20.2 | ✳️ | | 1.20.4 | ✳️ | -| 1.21 | ✳️ | -| 1.21 | 🚧 | +| 1.21.x | ✳️ | + - ❌ - Not Supported; no bug fixes or new features. - 🚧 - Work in Progress; not ready for release. diff --git a/1.19.3/build.gradle b/1.19.3/build.gradle index f099442..1c776ad 100644 --- a/1.19.3/build.gradle +++ b/1.19.3/build.gradle @@ -57,11 +57,13 @@ subprojects { // All Projects shade "me.hypherionmc.moon-config:core:${moon_config}" shade "me.hypherionmc.moon-config:toml:${moon_config}" + shade "me.hypherionmc.moon-config:json:${moon_config}" shade "com.hypherionmc:rpcsdk:${rpc_sdk}" shade "me.hypherionmc.sdlink:mcdiscordformatter-1.19.1:${discord_formatter}" shade "net.kyori:adventure-api:${adventure}" shade "net.kyori:adventure-text-serializer-gson:${adventure}" + compileOnly 'net.luckperms:api:5.4' compileOnly("org.projectlombok:lombok:${lombok}") annotationProcessor("org.projectlombok:lombok:${lombok}") } diff --git a/1.19.3/gradle.properties b/1.19.3/gradle.properties index e7a3770..48d04f3 100644 --- a/1.19.3/gradle.properties +++ b/1.19.3/gradle.properties @@ -1,7 +1,7 @@ #Project version_major=2 -version_minor=0 -version_patch=3 +version_minor=1 +version_patch=0 version_build=0 #Mod @@ -10,15 +10,15 @@ mod_id=craterlib mod_name=CraterLib # Shared -minecraft_version=1.19.3 +minecraft_version=1.19.4 project_group=com.hypherionmc.craterlib # Fabric fabric_loader=0.15.11 -fabric_api=0.76.1+1.19.3 +fabric_api=0.87.2+1.19.4 # Forge -forge_version=44.1.0 +forge_version=45.3.0 # Dependencies moon_config=1.0.9 diff --git a/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/api/commands/CraterCommand.java b/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/api/commands/CraterCommand.java index cc4969e..35f29f0 100644 --- a/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/api/commands/CraterCommand.java +++ b/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/api/commands/CraterCommand.java @@ -1,53 +1,155 @@ package com.hypherionmc.craterlib.api.commands; +import com.hypherionmc.craterlib.compat.LuckPermsCompat; +import com.hypherionmc.craterlib.core.platform.ModloaderEnvironment; import com.hypherionmc.craterlib.nojang.authlib.BridgedGameProfile; import com.hypherionmc.craterlib.nojang.commands.BridgedCommandSourceStack; import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer; import com.hypherionmc.craterlib.utils.TriConsumer; -import com.mojang.brigadier.arguments.ArgumentType; -import lombok.Getter; +import com.mojang.brigadier.CommandDispatcher; +import com.mojang.brigadier.arguments.BoolArgumentType; +import com.mojang.brigadier.arguments.IntegerArgumentType; +import com.mojang.brigadier.arguments.StringArgumentType; +import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import net.minecraft.commands.CommandSourceStack; +import net.minecraft.commands.Commands; import net.minecraft.commands.arguments.GameProfileArgument; -import org.apache.commons.lang3.tuple.Pair; +import net.minecraft.world.entity.player.Player; +import org.jetbrains.annotations.ApiStatus; -import java.util.HashMap; -import java.util.LinkedHashMap; import java.util.List; import java.util.function.Consumer; -@Getter public class CraterCommand { - private final HashMap, TriConsumer>> arguments = new LinkedHashMap<>(); - private Consumer executor; + private final LiteralArgumentBuilder mojangCommand; + private int permLevel = 4; + private String luckPermNode = ""; - private final String commandName; - private int permissionLevel = 4; - - CraterCommand(String commandName) { - this.commandName = commandName; + CraterCommand(LiteralArgumentBuilder cmd) { + this.mojangCommand = cmd; } public static CraterCommand literal(String commandName) { - return new CraterCommand(commandName); + return new CraterCommand(Commands.literal(commandName)); } public CraterCommand requiresPermission(int perm) { - this.permissionLevel = perm; + this.permLevel = perm; + this.mojangCommand.requires(this::checkPermission); return this; } - public CraterCommand withGameProfileArgument(String key, TriConsumer, BridgedCommandSourceStack> executor) { - arguments.put(key, Pair.of(GameProfileArgument.gameProfile(), executor)); + public CraterCommand withNode(String key) { + this.luckPermNode = key; return this; } + public CraterCommand then(CraterCommand child) { + this.mojangCommand.then(child.mojangCommand); + return this; + } + + public CraterCommand withGameProfilesArgument(String key, CommandExecutorWithArgs> executor) { + this.mojangCommand.then(Commands.argument(key, GameProfileArgument.gameProfile()) + .executes(context -> executor.run( + BridgedPlayer.of(context.getSource().getPlayer()), + GameProfileArgument.getGameProfiles(context, key).stream().map(BridgedGameProfile::of).toList(), + BridgedCommandSourceStack.of(context.getSource())) + )); + return this; + } + + public CraterCommand withBoolArgument(String key, CommandExecutorWithArgs executor) { + this.mojangCommand.then(Commands.argument(key, BoolArgumentType.bool()) + .executes(context -> executor.run( + BridgedPlayer.of(context.getSource().getPlayer()), + BoolArgumentType.getBool(context, key), + BridgedCommandSourceStack.of(context.getSource()) + ))); + return this; + } + + public CraterCommand withWordArgument(String key, CommandExecutorWithArgs executor) { + this.mojangCommand.then(Commands.argument(key, StringArgumentType.word()) + .executes(context -> executor.run( + BridgedPlayer.of(context.getSource().getPlayer()), + StringArgumentType.getString(context, key), + BridgedCommandSourceStack.of(context.getSource()) + ))); + return this; + } + + public CraterCommand withStringArgument(String key, CommandExecutorWithArgs executor) { + this.mojangCommand.then(Commands.argument(key, StringArgumentType.string()) + .executes(context -> executor.run( + BridgedPlayer.of(context.getSource().getPlayer()), + StringArgumentType.getString(context, key), + BridgedCommandSourceStack.of(context.getSource()) + ))); + return this; + } + + public CraterCommand withPhraseArgument(String key, CommandExecutorWithArgs executor) { + this.mojangCommand.then(Commands.argument(key, StringArgumentType.greedyString()) + .executes(context -> executor.run( + BridgedPlayer.of(context.getSource().getPlayer()), + StringArgumentType.getString(context, key), + BridgedCommandSourceStack.of(context.getSource()) + ))); + return this; + } + + public CraterCommand withIntegerArgument(String key, CommandExecutorWithArgs executor) { + this.mojangCommand.then(Commands.argument(key, IntegerArgumentType.integer()) + .executes(context -> executor.run( + BridgedPlayer.of(context.getSource().getPlayer()), + IntegerArgumentType.getInteger(context, key), + BridgedCommandSourceStack.of(context.getSource()) + ))); + return this; + } + + public CraterCommand execute(SingleCommandExecutor executor) { + this.mojangCommand.executes(context -> executor.run(BridgedCommandSourceStack.of(context.getSource()))); + return this; + } + + @Deprecated(forRemoval = true) public CraterCommand executes(Consumer ctx) { - executor = ctx; - return this; + return this.execute(stack -> { + ctx.accept(stack); + return 1; + }); } - public boolean hasArguments() { - return !arguments.isEmpty(); + @Deprecated(forRemoval = true) + public CraterCommand withGameProfileArgument(String key, TriConsumer, BridgedCommandSourceStack> executor) { + return this.withGameProfilesArgument(key, (player, argument, stack) -> { + executor.accept(player, argument, stack); + return 1; + }); } + @ApiStatus.Internal + public void register(CommandDispatcher stack) { + stack.register(this.mojangCommand); + } + + private boolean checkPermission(CommandSourceStack stack) { + if (!ModloaderEnvironment.INSTANCE.isModLoaded("luckperms") || !stack.isPlayer() || luckPermNode.isEmpty()) + return stack.hasPermission(this.permLevel); + + return LuckPermsCompat.INSTANCE.hasPermission(stack.getPlayer(), this.luckPermNode) || stack.hasPermission(this.permLevel); + } + + @FunctionalInterface + public interface CommandExecutorWithArgs { + int run(BridgedPlayer player, S argument, BridgedCommandSourceStack stack); + } + + @FunctionalInterface + public interface SingleCommandExecutor { + int run(S stack); + } } diff --git a/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterPlayerEvent.java b/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterPlayerEvent.java index 94be675..9e7d7a2 100644 --- a/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterPlayerEvent.java +++ b/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterPlayerEvent.java @@ -4,7 +4,6 @@ import com.hypherionmc.craterlib.core.event.CraterEvent; import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer; import lombok.Getter; import lombok.RequiredArgsConstructor; -import lombok.Setter; @RequiredArgsConstructor @Getter diff --git a/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterRegisterCommandEvent.java b/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterRegisterCommandEvent.java index 269065a..5adac03 100644 --- a/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterRegisterCommandEvent.java +++ b/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterRegisterCommandEvent.java @@ -2,14 +2,17 @@ package com.hypherionmc.craterlib.api.events.server; import com.hypherionmc.craterlib.api.commands.CraterCommand; import com.hypherionmc.craterlib.core.event.CraterEvent; -import com.hypherionmc.craterlib.nojang.commands.CommandsRegistry; -import lombok.NoArgsConstructor; +import com.mojang.brigadier.CommandDispatcher; +import lombok.AllArgsConstructor; +import net.minecraft.commands.CommandSourceStack; -@NoArgsConstructor +@AllArgsConstructor public class CraterRegisterCommandEvent extends CraterEvent { + private final CommandDispatcher stack; + public void registerCommand(CraterCommand cmd) { - CommandsRegistry.INSTANCE.registerCommand(cmd); + cmd.register(stack); } } diff --git a/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/ServerStatusEvent.java b/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/ServerStatusEvent.java new file mode 100644 index 0000000..b58dafa --- /dev/null +++ b/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/ServerStatusEvent.java @@ -0,0 +1,35 @@ +package com.hypherionmc.craterlib.api.events.server; + +import com.hypherionmc.craterlib.core.event.CraterEvent; +import com.hypherionmc.craterlib.nojang.network.protocol.status.WrappedServerStatus; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.Setter; +import net.kyori.adventure.text.Component; +import org.jetbrains.annotations.Nullable; + +import java.util.Optional; + +public class ServerStatusEvent { + + @RequiredArgsConstructor + @Getter + @Setter + public static class StatusRequestEvent extends CraterEvent { + + private final Component status; + @Nullable + private Component newStatus = null; + + } + + @RequiredArgsConstructor + @Getter + @Setter + public static class FaviconRequestEvent extends CraterEvent { + + private final Optional favicon; + private Optional newIcon = Optional.empty(); + + } +} diff --git a/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/CraterConfigScreen.java b/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/CraterConfigScreen.java index 81a9ed7..1132e07 100644 --- a/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/CraterConfigScreen.java +++ b/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/CraterConfigScreen.java @@ -2,7 +2,7 @@ package com.hypherionmc.craterlib.client.gui.config; import com.hypherionmc.craterlib.CraterConstants; import com.hypherionmc.craterlib.client.gui.config.widgets.*; -import com.hypherionmc.craterlib.core.config.ModuleConfig; +import com.hypherionmc.craterlib.core.config.AbstractConfig; import com.hypherionmc.craterlib.core.config.annotations.HideFromScreen; import com.hypherionmc.craterlib.core.config.annotations.SubConfig; import com.hypherionmc.craterlib.core.config.annotations.Tooltip; @@ -44,11 +44,11 @@ public class CraterConfigScreen extends Screen { private static final int BOTTOM = 24; private final Screen parent; private final List> options = new ArrayList<>(); - private final ModuleConfig config; + private final AbstractConfig config; public double scrollerAmount; private boolean dragging; - public CraterConfigScreen(ModuleConfig config, Screen parent, Object subConfig) { + public CraterConfigScreen(AbstractConfig config, Screen parent, Object subConfig) { super(Component.translatable("cl." + config.getClass().getSimpleName().toLowerCase() + ".title")); this.parent = parent; this.config = config; @@ -59,7 +59,7 @@ public class CraterConfigScreen extends Screen { } } - public CraterConfigScreen(ModuleConfig config, Screen parent) { + public CraterConfigScreen(AbstractConfig config, Screen parent) { this(config, parent, null); } diff --git a/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/SubConfigWidget.java b/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/SubConfigWidget.java index 9426ccf..056f32c 100644 --- a/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/SubConfigWidget.java +++ b/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/SubConfigWidget.java @@ -1,7 +1,7 @@ package com.hypherionmc.craterlib.client.gui.config.widgets; import com.hypherionmc.craterlib.client.gui.config.CraterConfigScreen; -import com.hypherionmc.craterlib.core.config.ModuleConfig; +import com.hypherionmc.craterlib.core.config.AbstractConfig; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Font; import net.minecraft.client.gui.GuiGraphics; @@ -15,10 +15,10 @@ import net.minecraft.network.chat.Component; public class SubConfigWidget extends AbstractConfigWidget { private final Object subConfig; - private final ModuleConfig config; + private final AbstractConfig config; private final Screen screen; - public SubConfigWidget(ModuleConfig config, Screen screen, Object subConfig) { + public SubConfigWidget(AbstractConfig config, Screen screen, Object subConfig) { this.config = config; this.subConfig = subConfig; this.screen = screen; diff --git a/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/compat/LuckPermsCompat.java b/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/compat/LuckPermsCompat.java new file mode 100644 index 0000000..a77e1f4 --- /dev/null +++ b/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/compat/LuckPermsCompat.java @@ -0,0 +1,20 @@ +package com.hypherionmc.craterlib.compat; + +import net.luckperms.api.LuckPerms; +import net.luckperms.api.LuckPermsProvider; +import net.luckperms.api.model.user.User; +import net.minecraft.server.level.ServerPlayer; + +public class LuckPermsCompat { + + public static final LuckPermsCompat INSTANCE = new LuckPermsCompat(); + private final LuckPerms luckPerms = LuckPermsProvider.get(); + + LuckPermsCompat() {} + + public boolean hasPermission(ServerPlayer player, String perm) { + User luckPermsUser = luckPerms.getPlayerAdapter(ServerPlayer.class).getUser(player); + return luckPermsUser.getCachedData().getPermissionData().checkPermission(perm).asBoolean(); + } + +} diff --git a/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/core/config/AbstractConfig.java b/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/core/config/AbstractConfig.java new file mode 100644 index 0000000..eceac79 --- /dev/null +++ b/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/core/config/AbstractConfig.java @@ -0,0 +1,71 @@ +package com.hypherionmc.craterlib.core.config; + +import com.hypherionmc.craterlib.core.config.formats.AbstractConfigFormat; +import com.hypherionmc.craterlib.core.config.formats.JsonConfigFormat; +import com.hypherionmc.craterlib.core.config.formats.TomlConfigFormat; +import lombok.Getter; +import lombok.Setter; +import me.hypherionmc.moonconfig.core.Config; +import org.jetbrains.annotations.Nullable; + +import java.io.File; + +@Getter +public abstract class AbstractConfig { + + /* Final Variables */ + private final transient File configPath; + private final transient String networkID; + private final transient String configName; + private final transient String modId; + private transient boolean wasSaveCalled = false; + + @Setter + private transient AbstractConfigFormat configFormat; + + public AbstractConfig(String modId, String configName) { + this(modId, null, configName); + } + + public AbstractConfig(String modId, @Nullable String subFolder, String configName) { + Config.setInsertionOrderPreserved(true); + + if (!configName.endsWith(".toml") && !configName.endsWith(".json")) + configName = configName + ".toml"; + + File configDir = new File("config" + (subFolder == null ? "" : File.separator + subFolder)); + configPath = new File(configDir, configName); + this.modId = modId; + this.networkID = modId + ":conf_" + configName.replace(".toml", "").replace(".json", "").replace("-", "_").toLowerCase(); + this.configName = configName.replace(".toml", "").replace(".json", ""); + configDir.mkdirs(); + + configFormat = configName.endsWith(".json") ? new JsonConfigFormat<>(configPath, this::onSave) : new TomlConfigFormat<>(configPath, this::onSave); + } + + public void registerAndSetup(S config) { + configFormat.register(config); + ConfigController.register_config(this); + this.configReloaded(); + } + + public void saveConfig(S config) { + this.wasSaveCalled = true; + configFormat.saveConfig(config); + } + + private void onSave() { + this.configReloaded(); + this.wasSaveCalled = false; + } + + public S readConfig(S config) { + return configFormat.readConfig(config); + } + + public void migrateConfig(S config) { + configFormat.migrateConfig(config); + } + + public abstract void configReloaded(); +} diff --git a/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/core/config/ConfigController.java b/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/core/config/ConfigController.java index 41c9471..760ca93 100644 --- a/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/core/config/ConfigController.java +++ b/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/core/config/ConfigController.java @@ -3,6 +3,7 @@ package com.hypherionmc.craterlib.core.config; import com.hypherionmc.craterlib.CraterConstants; import lombok.Getter; import me.hypherionmc.moonconfig.core.file.FileWatcher; +import org.apache.commons.lang3.tuple.Pair; import org.jetbrains.annotations.ApiStatus; import java.io.Serializable; @@ -18,7 +19,7 @@ public final class ConfigController implements Serializable { * Cache of registered configs */ @Getter - private static final HashMap monitoredConfigs = new HashMap<>(); + private static final HashMap> watchedConfigs = new HashMap<>(); /** * INTERNAL METHOD - Register and watch the config @@ -26,23 +27,34 @@ public final class ConfigController implements Serializable { * @param config - The config class to register and watch */ @ApiStatus.Internal + @Deprecated public static void register_config(ModuleConfig config) { - if (monitoredConfigs.containsKey(config)) { - CraterConstants.LOG.error("Failed to register " + config.getConfigPath().getName() + ". Config already registered"); + register_config((AbstractConfig) config); + } + + /** + * INTERNAL METHOD - Register and watch the config + * + * @param config - The config class to register and watch + */ + @ApiStatus.Internal + public static void register_config(AbstractConfig config) { + if (watchedConfigs.containsKey(config.getConfigPath().toString())) { + CraterConstants.LOG.error("Failed to register {}. Config already registered", config.getConfigPath().getName()); } else { FileWatcher configWatcher = new FileWatcher(); try { configWatcher.setWatch(config.getConfigPath(), () -> { - if (!config.isSaveCalled()) { - CraterConstants.LOG.info("Sending Reload Event for: " + config.getConfigPath().getName()); + if (!config.isWasSaveCalled()) { + CraterConstants.LOG.info("Sending Reload Event for: {}", config.getConfigPath().getName()); config.configReloaded(); } }); } catch (Exception e) { - CraterConstants.LOG.error("Failed to register " + config.getConfigPath().getName() + " for auto reloading. " + e.getMessage()); + CraterConstants.LOG.error("Failed to register {} for auto reloading. {}", config.getConfigPath().getName(), e.getMessage()); } - monitoredConfigs.put(config, configWatcher); - CraterConstants.LOG.info("Registered " + config.getConfigPath().getName() + " successfully!"); + watchedConfigs.put(config.getConfigPath().toString(), Pair.of(config, configWatcher)); + CraterConstants.LOG.info("Registered {} successfully!", config.getConfigPath().getName()); } } diff --git a/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/core/config/ModuleConfig.java b/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/core/config/ModuleConfig.java index 181efdc..e4850bf 100644 --- a/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/core/config/ModuleConfig.java +++ b/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/core/config/ModuleConfig.java @@ -1,9 +1,7 @@ package com.hypherionmc.craterlib.core.config; +import com.hypherionmc.craterlib.core.config.formats.TomlConfigFormat; import me.hypherionmc.moonconfig.core.CommentedConfig; -import me.hypherionmc.moonconfig.core.Config; -import me.hypherionmc.moonconfig.core.conversion.ObjectConverter; -import me.hypherionmc.moonconfig.core.file.CommentedFileConfig; import java.io.File; @@ -12,17 +10,8 @@ import java.io.File; * Base Config class containing the save, upgrading and loading logic. * All config classes must extend this class */ -public class ModuleConfig { - - /* Final Variables */ - private final transient File configPath; - private final transient String networkID; - - private final transient String configName; - - private final transient String modId; - - private transient boolean isSaveCalled = false; +@Deprecated +public class ModuleConfig extends AbstractConfig { /** * Set up the config @@ -35,20 +24,7 @@ public class ModuleConfig { } public ModuleConfig(String modId, String subFolder, String configName) { - /* Preserve the order of the config values */ - Config.setInsertionOrderPreserved(true); - - /* Configure Paths and Network SYNC ID */ - File configDir = new File("config" + (subFolder.isEmpty() ? "" : File.separator + subFolder)); - configPath = new File(configDir + File.separator + configName + ".toml"); - networkID = modId + ":conf_" + configName.replace("-", "_"); - this.modId = modId; - this.configName = configName; - - /* Check if the required directories exists, otherwise we create them */ - if (!configDir.exists()) { - configDir.mkdirs(); - } + super(modId, subFolder.isEmpty() ? null : subFolder, configName); } /** @@ -57,14 +33,7 @@ public class ModuleConfig { * @param config - The config class to use */ public void registerAndSetup(ModuleConfig config) { - if (!configPath.exists() || configPath.length() < 2) { - saveConfig(config); - } else { - migrateConfig(config); - } - /* Register the Config for Watching and events */ - ConfigController.register_config(this); - this.configReloaded(); + super.registerAndSetup(config); } /** @@ -73,16 +42,7 @@ public class ModuleConfig { * @param conf - The config class to serialize and save */ public void saveConfig(ModuleConfig conf) { - this.isSaveCalled = true; - /* Set up the Serializer and Config Object */ - ObjectConverter converter = new ObjectConverter(); - CommentedFileConfig config = CommentedFileConfig.builder(configPath).build(); - - /* Save the config and fire the reload events */ - converter.toConfig(conf, config); - config.save(); - configReloaded(); - this.isSaveCalled = false; + super.registerAndSetup(conf); } /** @@ -92,14 +52,7 @@ public class ModuleConfig { * @return - Returns the loaded version of the class */ public T loadConfig(Object conf) { - /* Set up the Serializer and Config Object */ - ObjectConverter converter = new ObjectConverter(); - CommentedFileConfig config = CommentedFileConfig.builder(configPath).build(); - config.load(); - - /* Load the config and return the loaded config */ - converter.toObject(config, conf); - return (T) conf; + return (T) super.readConfig(conf); } /** @@ -108,31 +61,13 @@ public class ModuleConfig { * @param conf - The config class to load */ public void migrateConfig(ModuleConfig conf) { - /* Set up the Serializer and Config Objects */ - CommentedFileConfig config = CommentedFileConfig.builder(configPath).build(); - CommentedFileConfig newConfig = CommentedFileConfig.builder(configPath).build(); - config.load(); - - /* Upgrade the config */ - new ObjectConverter().toConfig(conf, newConfig); - updateConfigValues(config, newConfig, newConfig, ""); - newConfig.save(); - - config.close(); - newConfig.close(); + super.migrateConfig(conf); } public void updateConfigValues(CommentedConfig oldConfig, CommentedConfig newConfig, CommentedConfig outputConfig, String subKey) { - /* Loop over the config keys and check what has changed */ - newConfig.valueMap().forEach((key, value) -> { - String finalKey = subKey + (subKey.isEmpty() ? "" : ".") + key; - if (value instanceof CommentedConfig commentedConfig) { - updateConfigValues(oldConfig, commentedConfig, outputConfig, finalKey); - } else { - outputConfig.set(finalKey, - oldConfig.contains(finalKey) ? oldConfig.get(finalKey) : value); - } - }); + if (getConfigFormat() instanceof TomlConfigFormat t) { + t.updateConfigValues(oldConfig, newConfig, outputConfig, subKey); + } } /** @@ -141,7 +76,7 @@ public class ModuleConfig { * @return - The FILE object containing the config file */ public File getConfigPath() { - return configPath; + return super.getConfigPath(); } /** @@ -150,12 +85,13 @@ public class ModuleConfig { * @return - Returns the Sync ID in format modid:config_name */ public String getNetworkID() { - return networkID; + return super.getNetworkID(); } /** * Fired whenever changes to the config are detected */ + @Override public void configReloaded() { } @@ -166,7 +102,7 @@ public class ModuleConfig { * @return */ public String getConfigName() { - return configName; + return super.getConfigName(); } /** @@ -175,10 +111,10 @@ public class ModuleConfig { * @return */ public String getModId() { - return modId; + return super.getModId(); } public boolean isSaveCalled() { - return isSaveCalled; + return super.isWasSaveCalled(); } } diff --git a/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/core/config/formats/AbstractConfigFormat.java b/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/core/config/formats/AbstractConfigFormat.java new file mode 100644 index 0000000..20511ba --- /dev/null +++ b/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/core/config/formats/AbstractConfigFormat.java @@ -0,0 +1,32 @@ +package com.hypherionmc.craterlib.core.config.formats; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import me.hypherionmc.moonconfig.core.Config; + +import java.io.File; + +@RequiredArgsConstructor +@Getter +public abstract class AbstractConfigFormat { + + private final File configPath; + private final Runnable onSave; + + public void register(S conf) { + if (!configPath.exists() || configPath.length() < 2) { + saveConfig(conf); + } else { + migrateConfig(conf); + } + } + + public boolean wasConfigChanged(Config old, Config newConfig) { + return true; + } + + public abstract void saveConfig(S config); + public abstract S readConfig(S config); + public abstract void migrateConfig(S config); + +} diff --git a/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/core/config/formats/JsonConfigFormat.java b/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/core/config/formats/JsonConfigFormat.java new file mode 100644 index 0000000..0db35fa --- /dev/null +++ b/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/core/config/formats/JsonConfigFormat.java @@ -0,0 +1,67 @@ +package com.hypherionmc.craterlib.core.config.formats; + +import me.hypherionmc.moonconfig.core.Config; +import me.hypherionmc.moonconfig.core.conversion.ObjectConverter; +import me.hypherionmc.moonconfig.core.file.FileConfig; + +import java.io.File; + +public class JsonConfigFormat extends AbstractConfigFormat { + + public JsonConfigFormat(File configPath, Runnable afterSave) { + super(configPath, afterSave); + } + + @Override + public void saveConfig(S conf) { + ObjectConverter converter = new ObjectConverter(); + FileConfig config = FileConfig.builder(getConfigPath()).sync().build(); + + converter.toConfig(conf, config); + config.save(); + getOnSave().run(); + } + + @Override + public S readConfig(S conf) { + /* Set up the Serializer and Config Object */ + ObjectConverter converter = new ObjectConverter(); + FileConfig config = FileConfig.builder(getConfigPath()).build(); + config.load(); + + /* Load the config and return the loaded config */ + converter.toObject(config, conf); + return conf; + } + + @Override + public void migrateConfig(S conf) { + /* Set up the Serializer and Config Objects */ + FileConfig config = FileConfig.builder(getConfigPath()).build(); + FileConfig newConfig = FileConfig.builder(getConfigPath()).sync().build(); + config.load(); + + /* Upgrade the config */ + if (wasConfigChanged(config, newConfig)) { + new ObjectConverter().toConfig(conf, newConfig); + updateConfigValues(config, newConfig, newConfig, ""); + newConfig.save(); + } + + config.close(); + newConfig.close(); + } + + public void updateConfigValues(Config oldConfig, Config newConfig, Config outputConfig, String subKey) { + /* Loop over the config keys and check what has changed */ + newConfig.valueMap().forEach((key, value) -> { + String finalKey = subKey + (subKey.isEmpty() ? "" : ".") + key; + if (value instanceof Config commentedConfig) { + updateConfigValues(oldConfig, commentedConfig, outputConfig, finalKey); + } else { + outputConfig.set(finalKey, + oldConfig.contains(finalKey) ? oldConfig.get(finalKey) : value); + } + }); + } +} diff --git a/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/core/config/formats/TomlConfigFormat.java b/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/core/config/formats/TomlConfigFormat.java new file mode 100644 index 0000000..e3f9763 --- /dev/null +++ b/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/core/config/formats/TomlConfigFormat.java @@ -0,0 +1,67 @@ +package com.hypherionmc.craterlib.core.config.formats; + +import me.hypherionmc.moonconfig.core.CommentedConfig; +import me.hypherionmc.moonconfig.core.conversion.ObjectConverter; +import me.hypherionmc.moonconfig.core.file.CommentedFileConfig; + +import java.io.File; + +public class TomlConfigFormat extends AbstractConfigFormat { + + public TomlConfigFormat(File configPath, Runnable onSave) { + super(configPath, onSave); + } + + @Override + public void saveConfig(S conf) { + ObjectConverter converter = new ObjectConverter(); + CommentedFileConfig config = CommentedFileConfig.builder(getConfigPath()).sync().build(); + + converter.toConfig(conf, config); + config.save(); + getOnSave().run(); + } + + @Override + public S readConfig(S conf) { + /* Set up the Serializer and Config Object */ + ObjectConverter converter = new ObjectConverter(); + CommentedFileConfig config = CommentedFileConfig.builder(getConfigPath()).build(); + config.load(); + + /* Load the config and return the loaded config */ + converter.toObject(config, conf); + return conf; + } + + @Override + public void migrateConfig(S conf) { + /* Set up the Serializer and Config Objects */ + CommentedFileConfig config = CommentedFileConfig.builder(getConfigPath()).build(); + CommentedFileConfig newConfig = CommentedFileConfig.builder(getConfigPath()).sync().build(); + config.load(); + + /* Upgrade the config */ + if (wasConfigChanged(config, newConfig)) { + new ObjectConverter().toConfig(conf, newConfig); + updateConfigValues(config, newConfig, newConfig, ""); + newConfig.save(); + } + + config.close(); + newConfig.close(); + } + + public void updateConfigValues(CommentedConfig oldConfig, CommentedConfig newConfig, CommentedConfig outputConfig, String subKey) { + /* Loop over the config keys and check what has changed */ + newConfig.valueMap().forEach((key, value) -> { + String finalKey = subKey + (subKey.isEmpty() ? "" : ".") + key; + if (value instanceof CommentedConfig commentedConfig) { + updateConfigValues(oldConfig, commentedConfig, outputConfig, finalKey); + } else { + outputConfig.set(finalKey, + oldConfig.contains(finalKey) ? oldConfig.get(finalKey) : value); + } + }); + } +} diff --git a/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/ServerStatusMixin.java b/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/ServerStatusMixin.java new file mode 100644 index 0000000..53985e7 --- /dev/null +++ b/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/ServerStatusMixin.java @@ -0,0 +1,27 @@ +package com.hypherionmc.craterlib.mixin.events; + +import com.hypherionmc.craterlib.api.events.server.ServerStatusEvent; +import com.hypherionmc.craterlib.core.event.CraterEventBus; +import com.hypherionmc.craterlib.nojang.network.protocol.status.WrappedServerStatus; +import net.minecraft.network.protocol.status.ServerStatus; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import java.util.Optional; + +@Mixin(ServerStatus.class) +public class ServerStatusMixin { + + @Inject(method = "favicon", at = @At("RETURN"), cancellable = true) + private void injectIconEvent(CallbackInfoReturnable> cir) { + ServerStatusEvent.FaviconRequestEvent event = new ServerStatusEvent.FaviconRequestEvent(cir.getReturnValue().isEmpty() ? Optional.empty() : Optional.of(new WrappedServerStatus.WrappedFavicon(cir.getReturnValue().get()))); + CraterEventBus.INSTANCE.postEvent(event); + + if (event.getNewIcon().isPresent()) { + cir.setReturnValue(Optional.of(event.getNewIcon().get().toMojang())); + } + } + +} diff --git a/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/BridgedCommandSourceStack.java b/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/BridgedCommandSourceStack.java index 5a15402..5529824 100644 --- a/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/BridgedCommandSourceStack.java +++ b/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/BridgedCommandSourceStack.java @@ -16,6 +16,10 @@ public class BridgedCommandSourceStack { internal.sendSuccess(() -> ChatUtils.adventureToMojang(supplier.get()), bl); } + public void sendFailure(Component text) { + internal.sendFailure(ChatUtils.adventureToMojang(text)); + } + public CommandSourceStack toMojang() { return internal; } diff --git a/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/CommandsRegistry.java b/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/CommandsRegistry.java deleted file mode 100644 index 37ad15b..0000000 --- a/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/CommandsRegistry.java +++ /dev/null @@ -1,85 +0,0 @@ -package com.hypherionmc.craterlib.nojang.commands; - -import com.hypherionmc.craterlib.api.commands.CraterCommand; -import com.hypherionmc.craterlib.nojang.authlib.BridgedGameProfile; -import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer; -import com.hypherionmc.craterlib.utils.TriConsumer; -import com.mojang.authlib.GameProfile; -import com.mojang.brigadier.CommandDispatcher; -import com.mojang.brigadier.builder.LiteralArgumentBuilder; -import lombok.AccessLevel; -import lombok.NoArgsConstructor; -import net.minecraft.commands.CommandSourceStack; -import net.minecraft.commands.Commands; -import net.minecraft.commands.arguments.GameProfileArgument; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -@NoArgsConstructor(access = AccessLevel.PRIVATE) -public class CommandsRegistry { - - public static final CommandsRegistry INSTANCE = new CommandsRegistry(); - - private final List commands = new ArrayList<>(); - - public void registerCommand(CraterCommand cmd) { - commands.add(cmd); - } - - public void registerCommands(CommandDispatcher stack) { - commands.forEach(cmd -> { - if (cmd.hasArguments()) { - CommandWithArguments.register(cmd, stack); - } else { - CommandWithoutArguments.register(cmd, stack); - } - }); - } - - static class CommandWithoutArguments { - - public static void register(CraterCommand cmd, CommandDispatcher dispatcher) { - LiteralArgumentBuilder command = Commands.literal(cmd.getCommandName()) - .requires(source -> source.hasPermission(cmd.getPermissionLevel())) - .executes(context -> { - cmd.getExecutor().accept(BridgedCommandSourceStack.of(context.getSource())); - return 1; - }); - - dispatcher.register(command); - } - - } - - @SuppressWarnings("unchecked") - static class CommandWithArguments { - - public static void register(CraterCommand cmd, CommandDispatcher dispatcher) { - LiteralArgumentBuilder command = Commands.literal(cmd.getCommandName()) - .requires(source -> source.hasPermission(cmd.getPermissionLevel())); - - cmd.getArguments().forEach((key, pair) -> command.then(Commands.argument(key, pair.getLeft()).executes(context -> { - - // This is FUCKING UGLY.... Need to improve this in the future - if (pair.getLeft() instanceof GameProfileArgument) { - Collection profiles = GameProfileArgument.getGameProfiles(context, key); - List bridgedGameProfiles = new ArrayList<>(); - - profiles.forEach(p -> bridgedGameProfiles.add(BridgedGameProfile.of(p))); - - ((TriConsumer, BridgedCommandSourceStack>) pair.getRight()) - .accept(BridgedPlayer.of(context.getSource().getPlayer()), bridgedGameProfiles, BridgedCommandSourceStack.of(context.getSource())); - return 1; - } - - return 1; - }))); - - dispatcher.register(command); - } - - } - -} diff --git a/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/nojang/network/protocol/status/WrappedServerStatus.java b/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/nojang/network/protocol/status/WrappedServerStatus.java new file mode 100644 index 0000000..ae6f773 --- /dev/null +++ b/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/nojang/network/protocol/status/WrappedServerStatus.java @@ -0,0 +1,31 @@ +package com.hypherionmc.craterlib.nojang.network.protocol.status; + +import net.minecraft.network.protocol.status.ServerStatus; +import org.jetbrains.annotations.ApiStatus; + +public final class WrappedServerStatus { + + public static final class WrappedFavicon { + + private final ServerStatus.Favicon internal; + + public WrappedFavicon(byte[] iconBytes) { + internal = new ServerStatus.Favicon(iconBytes); + } + + @ApiStatus.Internal + public WrappedFavicon(ServerStatus.Favicon internal) { + this.internal = internal; + } + + public byte[] iconBytes() { + return internal.iconBytes(); + } + + public ServerStatus.Favicon toMojang() { + return internal; + } + + } + +} diff --git a/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/nojang/world/entity/player/BridgedPlayer.java b/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/nojang/world/entity/player/BridgedPlayer.java index 8aa6d49..2241836 100644 --- a/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/nojang/world/entity/player/BridgedPlayer.java +++ b/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/nojang/world/entity/player/BridgedPlayer.java @@ -57,6 +57,11 @@ public class BridgedPlayer { return null; } + public void disconnect(Component message) { + if (isServerPlayer()) + toMojangServerPlayer().connection.disconnect(ChatUtils.adventureToMojang(message)); + } + public ServerPlayer toMojangServerPlayer() { return (ServerPlayer) internal; } diff --git a/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/utils/ChatUtils.java b/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/utils/ChatUtils.java index af9736d..5759fde 100644 --- a/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/utils/ChatUtils.java +++ b/1.20.2/Common/src/main/java/com/hypherionmc/craterlib/utils/ChatUtils.java @@ -92,4 +92,11 @@ public class ChatUtils { return mojangToAdventure(Component.translatable(Util.makeDescriptionId("biome", identifier.toMojang()))); } + public static net.kyori.adventure.text.Component format(String value) { + return net.kyori.adventure.text.Component.translatable(convertFormattingCodes(value)); + } + + private static String convertFormattingCodes(String input) { + return input.replaceAll("§([0-9a-fklmnor])", "\u00A7$1"); + } } diff --git a/1.20.2/Common/src/main/resources/craterlib.mixins.json b/1.20.2/Common/src/main/resources/craterlib.mixins.json index 1a739db..c910ed2 100644 --- a/1.20.2/Common/src/main/resources/craterlib.mixins.json +++ b/1.20.2/Common/src/main/resources/craterlib.mixins.json @@ -16,7 +16,8 @@ "events.CommandMixin", "events.PlayerAdvancementsMixin", "events.PlayerListMixin", - "events.ServerPlayerMixin" + "events.ServerPlayerMixin", + "events.ServerStatusMixin" ], "injectors": { "defaultRequire": 1 diff --git a/1.20.2/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibInitializer.java b/1.20.2/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibInitializer.java index c66c210..5e93a3a 100644 --- a/1.20.2/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibInitializer.java +++ b/1.20.2/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibInitializer.java @@ -9,7 +9,6 @@ import com.hypherionmc.craterlib.core.networking.CraterPacketNetwork; import com.hypherionmc.craterlib.core.networking.data.PacketSide; import com.hypherionmc.craterlib.core.platform.ModloaderEnvironment; import com.hypherionmc.craterlib.network.CraterFabricNetworkHandler; -import com.hypherionmc.craterlib.nojang.commands.CommandsRegistry; import com.hypherionmc.craterlib.nojang.server.BridgedMinecraftServer; import net.fabricmc.api.ModInitializer; import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback; @@ -21,8 +20,7 @@ public class CraterLibInitializer implements ModInitializer { public void onInitialize() { new CraterPacketNetwork(new CraterFabricNetworkHandler(PacketSide.SERVER)); CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> { - CraterEventBus.INSTANCE.postEvent(new CraterRegisterCommandEvent()); - CommandsRegistry.INSTANCE.registerCommands(dispatcher); + CraterEventBus.INSTANCE.postEvent(new CraterRegisterCommandEvent(dispatcher)); }); diff --git a/1.20.2/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibModMenuIntegration.java b/1.20.2/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibModMenuIntegration.java index 6615352..5b34ff1 100644 --- a/1.20.2/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibModMenuIntegration.java +++ b/1.20.2/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibModMenuIntegration.java @@ -2,7 +2,6 @@ package com.hypherionmc.craterlib; import com.hypherionmc.craterlib.client.gui.config.CraterConfigScreen; import com.hypherionmc.craterlib.core.config.ConfigController; -import com.hypherionmc.craterlib.core.config.ModuleConfig; import com.hypherionmc.craterlib.core.config.annotations.NoConfigScreen; import com.terraformersmc.modmenu.api.ConfigScreenFactory; import com.terraformersmc.modmenu.api.ModMenuApi; @@ -19,9 +18,9 @@ public class CraterLibModMenuIntegration implements ModMenuApi { public Map> getProvidedConfigScreenFactories() { Map> configScreens = new HashMap<>(); - ConfigController.getMonitoredConfigs().forEach((conf, watcher) -> { + ConfigController.getWatchedConfigs().forEach((conf, watcher) -> { if (!conf.getClass().isAnnotationPresent(NoConfigScreen.class)) { - configScreens.put(((ModuleConfig) conf).getModId(), screen -> new CraterConfigScreen((ModuleConfig) conf, screen)); + configScreens.put(watcher.getLeft().getModId(), screen -> new CraterConfigScreen(watcher.getLeft(), screen)); } }); diff --git a/1.20.2/Fabric/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java b/1.20.2/Fabric/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java index ec01614..7c644d4 100644 --- a/1.20.2/Fabric/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java +++ b/1.20.2/Fabric/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java @@ -27,8 +27,8 @@ public class ServerGamePacketListenerImplMixin { cancellable = true ) private void injectChatEvent(PlayerChatMessage arg, Component arg2, FilteredText arg3, CallbackInfo ci) { - Component finalArg = arg2 == null ? arg.decoratedContent() : arg2; - CraterServerChatEvent event = new CraterServerChatEvent(BridgedPlayer.of(this.player), finalArg.getString(), ChatUtils.mojangToAdventure(finalArg)); + Component finalcomp = arg2 == null ? arg.decoratedContent() : arg2; + CraterServerChatEvent event = new CraterServerChatEvent(BridgedPlayer.of(this.player), finalcomp.getString(), ChatUtils.mojangToAdventure(finalcomp)); CraterEventBus.INSTANCE.postEvent(event); if (event.wasCancelled()) ci.cancel(); diff --git a/1.20.2/Fabric/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java b/1.20.2/Fabric/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java new file mode 100644 index 0000000..f3dc866 --- /dev/null +++ b/1.20.2/Fabric/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java @@ -0,0 +1,52 @@ +package com.hypherionmc.craterlib.mixin; + +import com.hypherionmc.craterlib.api.events.server.ServerStatusEvent; +import com.hypherionmc.craterlib.core.event.CraterEventBus; +import com.hypherionmc.craterlib.utils.ChatUtils; +import net.minecraft.network.Connection; +import net.minecraft.network.protocol.status.ClientboundStatusResponsePacket; +import net.minecraft.network.protocol.status.ServerStatus; +import net.minecraft.network.protocol.status.ServerboundStatusRequestPacket; +import net.minecraft.server.network.ServerStatusPacketListenerImpl; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(ServerStatusPacketListenerImpl.class) +public class ServerStatusPacketListenerMixin { + + @Shadow + @Final + private ServerStatus status; + + @Shadow @Final private Connection connection; + + @Inject(method = "handleStatusRequest", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/network/Connection;send(Lnet/minecraft/network/protocol/Packet;)V", + shift = At.Shift.BEFORE), + cancellable = true + ) + private void injectHandleStatusRequest(ServerboundStatusRequestPacket arg, CallbackInfo ci) { + ServerStatusEvent.StatusRequestEvent event = new ServerStatusEvent.StatusRequestEvent(ChatUtils.mojangToAdventure(status.description())); + CraterEventBus.INSTANCE.postEvent(event); + + if (event.getNewStatus() != null) { + ci.cancel(); + this.connection.send(new ClientboundStatusResponsePacket( + new ServerStatus(ChatUtils.adventureToMojang( + event.getNewStatus()), + status.players(), + status.version(), + status.favicon(), + status.enforcesSecureChat() + ) + )); + } + } + +} \ No newline at end of file diff --git a/1.20.2/Fabric/src/main/resources/craterlib.fabric.mixins.json b/1.20.2/Fabric/src/main/resources/craterlib.fabric.mixins.json index 7c59043..a6d0bc1 100644 --- a/1.20.2/Fabric/src/main/resources/craterlib.fabric.mixins.json +++ b/1.20.2/Fabric/src/main/resources/craterlib.fabric.mixins.json @@ -9,7 +9,8 @@ "TutorialMixin" ], "server": [ - "ServerGamePacketListenerImplMixin" + "ServerGamePacketListenerImplMixin", + "ServerStatusPacketListenerMixin" ], "injectors": { "defaultRequire": 1 diff --git a/1.20.2/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeServerEvents.java b/1.20.2/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeServerEvents.java index f354ddc..37ddf87 100644 --- a/1.20.2/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeServerEvents.java +++ b/1.20.2/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeServerEvents.java @@ -3,7 +3,6 @@ package com.hypherionmc.craterlib.common; import com.hypherionmc.craterlib.api.events.server.CraterRegisterCommandEvent; import com.hypherionmc.craterlib.api.events.server.CraterServerLifecycleEvent; import com.hypherionmc.craterlib.core.event.CraterEventBus; -import com.hypherionmc.craterlib.nojang.commands.CommandsRegistry; import com.hypherionmc.craterlib.nojang.server.BridgedMinecraftServer; import net.minecraftforge.event.RegisterCommandsEvent; import net.minecraftforge.event.server.ServerStartedEvent; @@ -36,8 +35,7 @@ public class ForgeServerEvents { @SubscribeEvent public void onCommandRegister(RegisterCommandsEvent event) { - CraterEventBus.INSTANCE.postEvent(new CraterRegisterCommandEvent()); - CommandsRegistry.INSTANCE.registerCommands(event.getDispatcher()); + CraterEventBus.INSTANCE.postEvent(new CraterRegisterCommandEvent(event.getDispatcher())); } } diff --git a/1.20.2/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java b/1.20.2/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java index 927bd23..78fb62b 100644 --- a/1.20.2/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java +++ b/1.20.2/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java @@ -1,6 +1,7 @@ package com.hypherionmc.craterlib.mixin; import com.hypherionmc.craterlib.client.gui.config.CraterConfigScreen; +import com.hypherionmc.craterlib.core.config.AbstractConfig; import com.hypherionmc.craterlib.core.config.ConfigController; import com.hypherionmc.craterlib.core.config.ModuleConfig; import com.hypherionmc.craterlib.core.config.annotations.NoConfigScreen; @@ -28,9 +29,9 @@ public class ConfigScreenHandlerMixin { */ @Inject(at = @At("RETURN"), method = "getScreenFactoryFor", cancellable = true, remap = false) private static void injectConfigScreen(IModInfo selectedMod, CallbackInfoReturnable>> cir) { - ConfigController.getMonitoredConfigs().forEach((conf, watcher) -> { + ConfigController.getWatchedConfigs().forEach((conf, watcher) -> { if (!conf.getClass().isAnnotationPresent(NoConfigScreen.class)) { - ModuleConfig config = (ModuleConfig) conf; + AbstractConfig config = watcher.getLeft(); if (config.getModId().equals(selectedMod.getModId())) { cir.setReturnValue( Optional.of((minecraft, screen) -> new CraterConfigScreen(config, screen)) diff --git a/1.20.2/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java b/1.20.2/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java index c9b024b..8a0fcfb 100644 --- a/1.20.2/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java +++ b/1.20.2/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java @@ -27,8 +27,8 @@ public class ServerGamePacketListenerImplMixin { cancellable = true ) private void injectChatEvent(Component component, PlayerChatMessage arg, FilteredText p_296589_, CallbackInfo ci) { - Component finalArg = component == null ? arg.decoratedContent() : component; - CraterServerChatEvent event = new CraterServerChatEvent(BridgedPlayer.of(this.player), finalArg.getString(), ChatUtils.mojangToAdventure(finalArg)); + Component finalcomp = component == null ? arg.decoratedContent() : component; + CraterServerChatEvent event = new CraterServerChatEvent(BridgedPlayer.of(this.player), finalcomp.getString(), ChatUtils.mojangToAdventure(finalcomp)); CraterEventBus.INSTANCE.postEvent(event); if (event.wasCancelled()) ci.cancel(); diff --git a/1.20.2/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java b/1.20.2/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java new file mode 100644 index 0000000..969b05d --- /dev/null +++ b/1.20.2/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java @@ -0,0 +1,53 @@ +package com.hypherionmc.craterlib.mixin; + +import com.hypherionmc.craterlib.api.events.server.ServerStatusEvent; +import com.hypherionmc.craterlib.core.event.CraterEventBus; +import com.hypherionmc.craterlib.utils.ChatUtils; +import net.minecraft.network.Connection; +import net.minecraft.network.protocol.status.ClientboundStatusResponsePacket; +import net.minecraft.network.protocol.status.ServerStatus; +import net.minecraft.network.protocol.status.ServerboundStatusRequestPacket; +import net.minecraft.server.network.ServerStatusPacketListenerImpl; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(ServerStatusPacketListenerImpl.class) +public class ServerStatusPacketListenerMixin { + + @Shadow + @Final + private ServerStatus status; + + @Shadow @Final private Connection connection; + + @Inject(method = "handleStatusRequest", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/network/Connection;send(Lnet/minecraft/network/protocol/Packet;)V", + shift = At.Shift.BEFORE), + cancellable = true + ) + private void injectHandleStatusRequest(ServerboundStatusRequestPacket arg, CallbackInfo ci) { + ServerStatusEvent.StatusRequestEvent event = new ServerStatusEvent.StatusRequestEvent(ChatUtils.mojangToAdventure(status.description())); + CraterEventBus.INSTANCE.postEvent(event); + + if (event.getNewStatus() != null) { + ci.cancel(); + this.connection.send(new ClientboundStatusResponsePacket( + new ServerStatus(ChatUtils.adventureToMojang( + event.getNewStatus()), + status.players(), + status.version(), + status.favicon(), + status.enforcesSecureChat(), + status.forgeData() + ) + )); + } + } + +} diff --git a/1.20.2/Forge/src/main/resources/craterlib.forge.mixins.json b/1.20.2/Forge/src/main/resources/craterlib.forge.mixins.json index aa072d1..892f6d7 100644 --- a/1.20.2/Forge/src/main/resources/craterlib.forge.mixins.json +++ b/1.20.2/Forge/src/main/resources/craterlib.forge.mixins.json @@ -9,7 +9,8 @@ "ConfigScreenHandlerMixin" ], "server": [ - "ServerGamePacketListenerImplMixin" + "ServerGamePacketListenerImplMixin", + "ServerStatusPacketListenerMixin" ], "injectors": { "defaultRequire": 1 diff --git a/1.20.2/NeoForge/src/main/resources/craterlib_logo.png b/1.20.2/NeoForge/src/main/resources/craterlib_logo.png deleted file mode 100644 index ce0159c..0000000 Binary files a/1.20.2/NeoForge/src/main/resources/craterlib_logo.png and /dev/null differ diff --git a/1.20.2/README.md b/1.20.2/README.md index 49c0699..4b18d17 100644 --- a/1.20.2/README.md +++ b/1.20.2/README.md @@ -15,7 +15,7 @@ A Library mod and modding api for easier multi-version minecraft and mod loader | < 1.18.2 | ❌ | | 1.18.2-1.20.2 | ✳️ | | 1.20.4 | ✳️ | -| 1.21 | 🚧 | +| 1.21.x | ✳️ | - ❌ - Not Supported; no bug fixes or new features. - 🚧 - Work in Progress; not ready for release. diff --git a/1.20.2/build.gradle b/1.20.2/build.gradle index f099442..1c776ad 100644 --- a/1.20.2/build.gradle +++ b/1.20.2/build.gradle @@ -57,11 +57,13 @@ subprojects { // All Projects shade "me.hypherionmc.moon-config:core:${moon_config}" shade "me.hypherionmc.moon-config:toml:${moon_config}" + shade "me.hypherionmc.moon-config:json:${moon_config}" shade "com.hypherionmc:rpcsdk:${rpc_sdk}" shade "me.hypherionmc.sdlink:mcdiscordformatter-1.19.1:${discord_formatter}" shade "net.kyori:adventure-api:${adventure}" shade "net.kyori:adventure-text-serializer-gson:${adventure}" + compileOnly 'net.luckperms:api:5.4' compileOnly("org.projectlombok:lombok:${lombok}") annotationProcessor("org.projectlombok:lombok:${lombok}") } diff --git a/1.20.2/gradle.properties b/1.20.2/gradle.properties index 46f844f..a9ef4cf 100644 --- a/1.20.2/gradle.properties +++ b/1.20.2/gradle.properties @@ -1,7 +1,7 @@ #Project version_major=2 -version_minor=0 -version_patch=3 +version_minor=1 +version_patch=0 version_build=0 #Mod diff --git a/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/api/commands/CraterCommand.java b/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/api/commands/CraterCommand.java index cc4969e..35f29f0 100644 --- a/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/api/commands/CraterCommand.java +++ b/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/api/commands/CraterCommand.java @@ -1,53 +1,155 @@ package com.hypherionmc.craterlib.api.commands; +import com.hypherionmc.craterlib.compat.LuckPermsCompat; +import com.hypherionmc.craterlib.core.platform.ModloaderEnvironment; import com.hypherionmc.craterlib.nojang.authlib.BridgedGameProfile; import com.hypherionmc.craterlib.nojang.commands.BridgedCommandSourceStack; import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer; import com.hypherionmc.craterlib.utils.TriConsumer; -import com.mojang.brigadier.arguments.ArgumentType; -import lombok.Getter; +import com.mojang.brigadier.CommandDispatcher; +import com.mojang.brigadier.arguments.BoolArgumentType; +import com.mojang.brigadier.arguments.IntegerArgumentType; +import com.mojang.brigadier.arguments.StringArgumentType; +import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import net.minecraft.commands.CommandSourceStack; +import net.minecraft.commands.Commands; import net.minecraft.commands.arguments.GameProfileArgument; -import org.apache.commons.lang3.tuple.Pair; +import net.minecraft.world.entity.player.Player; +import org.jetbrains.annotations.ApiStatus; -import java.util.HashMap; -import java.util.LinkedHashMap; import java.util.List; import java.util.function.Consumer; -@Getter public class CraterCommand { - private final HashMap, TriConsumer>> arguments = new LinkedHashMap<>(); - private Consumer executor; + private final LiteralArgumentBuilder mojangCommand; + private int permLevel = 4; + private String luckPermNode = ""; - private final String commandName; - private int permissionLevel = 4; - - CraterCommand(String commandName) { - this.commandName = commandName; + CraterCommand(LiteralArgumentBuilder cmd) { + this.mojangCommand = cmd; } public static CraterCommand literal(String commandName) { - return new CraterCommand(commandName); + return new CraterCommand(Commands.literal(commandName)); } public CraterCommand requiresPermission(int perm) { - this.permissionLevel = perm; + this.permLevel = perm; + this.mojangCommand.requires(this::checkPermission); return this; } - public CraterCommand withGameProfileArgument(String key, TriConsumer, BridgedCommandSourceStack> executor) { - arguments.put(key, Pair.of(GameProfileArgument.gameProfile(), executor)); + public CraterCommand withNode(String key) { + this.luckPermNode = key; return this; } + public CraterCommand then(CraterCommand child) { + this.mojangCommand.then(child.mojangCommand); + return this; + } + + public CraterCommand withGameProfilesArgument(String key, CommandExecutorWithArgs> executor) { + this.mojangCommand.then(Commands.argument(key, GameProfileArgument.gameProfile()) + .executes(context -> executor.run( + BridgedPlayer.of(context.getSource().getPlayer()), + GameProfileArgument.getGameProfiles(context, key).stream().map(BridgedGameProfile::of).toList(), + BridgedCommandSourceStack.of(context.getSource())) + )); + return this; + } + + public CraterCommand withBoolArgument(String key, CommandExecutorWithArgs executor) { + this.mojangCommand.then(Commands.argument(key, BoolArgumentType.bool()) + .executes(context -> executor.run( + BridgedPlayer.of(context.getSource().getPlayer()), + BoolArgumentType.getBool(context, key), + BridgedCommandSourceStack.of(context.getSource()) + ))); + return this; + } + + public CraterCommand withWordArgument(String key, CommandExecutorWithArgs executor) { + this.mojangCommand.then(Commands.argument(key, StringArgumentType.word()) + .executes(context -> executor.run( + BridgedPlayer.of(context.getSource().getPlayer()), + StringArgumentType.getString(context, key), + BridgedCommandSourceStack.of(context.getSource()) + ))); + return this; + } + + public CraterCommand withStringArgument(String key, CommandExecutorWithArgs executor) { + this.mojangCommand.then(Commands.argument(key, StringArgumentType.string()) + .executes(context -> executor.run( + BridgedPlayer.of(context.getSource().getPlayer()), + StringArgumentType.getString(context, key), + BridgedCommandSourceStack.of(context.getSource()) + ))); + return this; + } + + public CraterCommand withPhraseArgument(String key, CommandExecutorWithArgs executor) { + this.mojangCommand.then(Commands.argument(key, StringArgumentType.greedyString()) + .executes(context -> executor.run( + BridgedPlayer.of(context.getSource().getPlayer()), + StringArgumentType.getString(context, key), + BridgedCommandSourceStack.of(context.getSource()) + ))); + return this; + } + + public CraterCommand withIntegerArgument(String key, CommandExecutorWithArgs executor) { + this.mojangCommand.then(Commands.argument(key, IntegerArgumentType.integer()) + .executes(context -> executor.run( + BridgedPlayer.of(context.getSource().getPlayer()), + IntegerArgumentType.getInteger(context, key), + BridgedCommandSourceStack.of(context.getSource()) + ))); + return this; + } + + public CraterCommand execute(SingleCommandExecutor executor) { + this.mojangCommand.executes(context -> executor.run(BridgedCommandSourceStack.of(context.getSource()))); + return this; + } + + @Deprecated(forRemoval = true) public CraterCommand executes(Consumer ctx) { - executor = ctx; - return this; + return this.execute(stack -> { + ctx.accept(stack); + return 1; + }); } - public boolean hasArguments() { - return !arguments.isEmpty(); + @Deprecated(forRemoval = true) + public CraterCommand withGameProfileArgument(String key, TriConsumer, BridgedCommandSourceStack> executor) { + return this.withGameProfilesArgument(key, (player, argument, stack) -> { + executor.accept(player, argument, stack); + return 1; + }); } + @ApiStatus.Internal + public void register(CommandDispatcher stack) { + stack.register(this.mojangCommand); + } + + private boolean checkPermission(CommandSourceStack stack) { + if (!ModloaderEnvironment.INSTANCE.isModLoaded("luckperms") || !stack.isPlayer() || luckPermNode.isEmpty()) + return stack.hasPermission(this.permLevel); + + return LuckPermsCompat.INSTANCE.hasPermission(stack.getPlayer(), this.luckPermNode) || stack.hasPermission(this.permLevel); + } + + @FunctionalInterface + public interface CommandExecutorWithArgs { + int run(BridgedPlayer player, S argument, BridgedCommandSourceStack stack); + } + + @FunctionalInterface + public interface SingleCommandExecutor { + int run(S stack); + } } diff --git a/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterPlayerEvent.java b/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterPlayerEvent.java index 94be675..9e7d7a2 100644 --- a/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterPlayerEvent.java +++ b/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterPlayerEvent.java @@ -4,7 +4,6 @@ import com.hypherionmc.craterlib.core.event.CraterEvent; import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer; import lombok.Getter; import lombok.RequiredArgsConstructor; -import lombok.Setter; @RequiredArgsConstructor @Getter diff --git a/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterRegisterCommandEvent.java b/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterRegisterCommandEvent.java index 269065a..5adac03 100644 --- a/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterRegisterCommandEvent.java +++ b/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterRegisterCommandEvent.java @@ -2,14 +2,17 @@ package com.hypherionmc.craterlib.api.events.server; import com.hypherionmc.craterlib.api.commands.CraterCommand; import com.hypherionmc.craterlib.core.event.CraterEvent; -import com.hypherionmc.craterlib.nojang.commands.CommandsRegistry; -import lombok.NoArgsConstructor; +import com.mojang.brigadier.CommandDispatcher; +import lombok.AllArgsConstructor; +import net.minecraft.commands.CommandSourceStack; -@NoArgsConstructor +@AllArgsConstructor public class CraterRegisterCommandEvent extends CraterEvent { + private final CommandDispatcher stack; + public void registerCommand(CraterCommand cmd) { - CommandsRegistry.INSTANCE.registerCommand(cmd); + cmd.register(stack); } } diff --git a/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/ServerStatusEvent.java b/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/ServerStatusEvent.java new file mode 100644 index 0000000..b58dafa --- /dev/null +++ b/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/ServerStatusEvent.java @@ -0,0 +1,35 @@ +package com.hypherionmc.craterlib.api.events.server; + +import com.hypherionmc.craterlib.core.event.CraterEvent; +import com.hypherionmc.craterlib.nojang.network.protocol.status.WrappedServerStatus; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.Setter; +import net.kyori.adventure.text.Component; +import org.jetbrains.annotations.Nullable; + +import java.util.Optional; + +public class ServerStatusEvent { + + @RequiredArgsConstructor + @Getter + @Setter + public static class StatusRequestEvent extends CraterEvent { + + private final Component status; + @Nullable + private Component newStatus = null; + + } + + @RequiredArgsConstructor + @Getter + @Setter + public static class FaviconRequestEvent extends CraterEvent { + + private final Optional favicon; + private Optional newIcon = Optional.empty(); + + } +} diff --git a/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/CraterConfigScreen.java b/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/CraterConfigScreen.java index 81a9ed7..1132e07 100644 --- a/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/CraterConfigScreen.java +++ b/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/CraterConfigScreen.java @@ -2,7 +2,7 @@ package com.hypherionmc.craterlib.client.gui.config; import com.hypherionmc.craterlib.CraterConstants; import com.hypherionmc.craterlib.client.gui.config.widgets.*; -import com.hypherionmc.craterlib.core.config.ModuleConfig; +import com.hypherionmc.craterlib.core.config.AbstractConfig; import com.hypherionmc.craterlib.core.config.annotations.HideFromScreen; import com.hypherionmc.craterlib.core.config.annotations.SubConfig; import com.hypherionmc.craterlib.core.config.annotations.Tooltip; @@ -44,11 +44,11 @@ public class CraterConfigScreen extends Screen { private static final int BOTTOM = 24; private final Screen parent; private final List> options = new ArrayList<>(); - private final ModuleConfig config; + private final AbstractConfig config; public double scrollerAmount; private boolean dragging; - public CraterConfigScreen(ModuleConfig config, Screen parent, Object subConfig) { + public CraterConfigScreen(AbstractConfig config, Screen parent, Object subConfig) { super(Component.translatable("cl." + config.getClass().getSimpleName().toLowerCase() + ".title")); this.parent = parent; this.config = config; @@ -59,7 +59,7 @@ public class CraterConfigScreen extends Screen { } } - public CraterConfigScreen(ModuleConfig config, Screen parent) { + public CraterConfigScreen(AbstractConfig config, Screen parent) { this(config, parent, null); } diff --git a/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/SubConfigWidget.java b/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/SubConfigWidget.java index 9426ccf..056f32c 100644 --- a/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/SubConfigWidget.java +++ b/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/SubConfigWidget.java @@ -1,7 +1,7 @@ package com.hypherionmc.craterlib.client.gui.config.widgets; import com.hypherionmc.craterlib.client.gui.config.CraterConfigScreen; -import com.hypherionmc.craterlib.core.config.ModuleConfig; +import com.hypherionmc.craterlib.core.config.AbstractConfig; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Font; import net.minecraft.client.gui.GuiGraphics; @@ -15,10 +15,10 @@ import net.minecraft.network.chat.Component; public class SubConfigWidget extends AbstractConfigWidget { private final Object subConfig; - private final ModuleConfig config; + private final AbstractConfig config; private final Screen screen; - public SubConfigWidget(ModuleConfig config, Screen screen, Object subConfig) { + public SubConfigWidget(AbstractConfig config, Screen screen, Object subConfig) { this.config = config; this.subConfig = subConfig; this.screen = screen; diff --git a/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/compat/LuckPermsCompat.java b/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/compat/LuckPermsCompat.java new file mode 100644 index 0000000..a77e1f4 --- /dev/null +++ b/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/compat/LuckPermsCompat.java @@ -0,0 +1,20 @@ +package com.hypherionmc.craterlib.compat; + +import net.luckperms.api.LuckPerms; +import net.luckperms.api.LuckPermsProvider; +import net.luckperms.api.model.user.User; +import net.minecraft.server.level.ServerPlayer; + +public class LuckPermsCompat { + + public static final LuckPermsCompat INSTANCE = new LuckPermsCompat(); + private final LuckPerms luckPerms = LuckPermsProvider.get(); + + LuckPermsCompat() {} + + public boolean hasPermission(ServerPlayer player, String perm) { + User luckPermsUser = luckPerms.getPlayerAdapter(ServerPlayer.class).getUser(player); + return luckPermsUser.getCachedData().getPermissionData().checkPermission(perm).asBoolean(); + } + +} diff --git a/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/core/config/AbstractConfig.java b/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/core/config/AbstractConfig.java new file mode 100644 index 0000000..eceac79 --- /dev/null +++ b/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/core/config/AbstractConfig.java @@ -0,0 +1,71 @@ +package com.hypherionmc.craterlib.core.config; + +import com.hypherionmc.craterlib.core.config.formats.AbstractConfigFormat; +import com.hypherionmc.craterlib.core.config.formats.JsonConfigFormat; +import com.hypherionmc.craterlib.core.config.formats.TomlConfigFormat; +import lombok.Getter; +import lombok.Setter; +import me.hypherionmc.moonconfig.core.Config; +import org.jetbrains.annotations.Nullable; + +import java.io.File; + +@Getter +public abstract class AbstractConfig { + + /* Final Variables */ + private final transient File configPath; + private final transient String networkID; + private final transient String configName; + private final transient String modId; + private transient boolean wasSaveCalled = false; + + @Setter + private transient AbstractConfigFormat configFormat; + + public AbstractConfig(String modId, String configName) { + this(modId, null, configName); + } + + public AbstractConfig(String modId, @Nullable String subFolder, String configName) { + Config.setInsertionOrderPreserved(true); + + if (!configName.endsWith(".toml") && !configName.endsWith(".json")) + configName = configName + ".toml"; + + File configDir = new File("config" + (subFolder == null ? "" : File.separator + subFolder)); + configPath = new File(configDir, configName); + this.modId = modId; + this.networkID = modId + ":conf_" + configName.replace(".toml", "").replace(".json", "").replace("-", "_").toLowerCase(); + this.configName = configName.replace(".toml", "").replace(".json", ""); + configDir.mkdirs(); + + configFormat = configName.endsWith(".json") ? new JsonConfigFormat<>(configPath, this::onSave) : new TomlConfigFormat<>(configPath, this::onSave); + } + + public void registerAndSetup(S config) { + configFormat.register(config); + ConfigController.register_config(this); + this.configReloaded(); + } + + public void saveConfig(S config) { + this.wasSaveCalled = true; + configFormat.saveConfig(config); + } + + private void onSave() { + this.configReloaded(); + this.wasSaveCalled = false; + } + + public S readConfig(S config) { + return configFormat.readConfig(config); + } + + public void migrateConfig(S config) { + configFormat.migrateConfig(config); + } + + public abstract void configReloaded(); +} diff --git a/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/core/config/ConfigController.java b/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/core/config/ConfigController.java index 41c9471..760ca93 100644 --- a/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/core/config/ConfigController.java +++ b/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/core/config/ConfigController.java @@ -3,6 +3,7 @@ package com.hypherionmc.craterlib.core.config; import com.hypherionmc.craterlib.CraterConstants; import lombok.Getter; import me.hypherionmc.moonconfig.core.file.FileWatcher; +import org.apache.commons.lang3.tuple.Pair; import org.jetbrains.annotations.ApiStatus; import java.io.Serializable; @@ -18,7 +19,7 @@ public final class ConfigController implements Serializable { * Cache of registered configs */ @Getter - private static final HashMap monitoredConfigs = new HashMap<>(); + private static final HashMap> watchedConfigs = new HashMap<>(); /** * INTERNAL METHOD - Register and watch the config @@ -26,23 +27,34 @@ public final class ConfigController implements Serializable { * @param config - The config class to register and watch */ @ApiStatus.Internal + @Deprecated public static void register_config(ModuleConfig config) { - if (monitoredConfigs.containsKey(config)) { - CraterConstants.LOG.error("Failed to register " + config.getConfigPath().getName() + ". Config already registered"); + register_config((AbstractConfig) config); + } + + /** + * INTERNAL METHOD - Register and watch the config + * + * @param config - The config class to register and watch + */ + @ApiStatus.Internal + public static void register_config(AbstractConfig config) { + if (watchedConfigs.containsKey(config.getConfigPath().toString())) { + CraterConstants.LOG.error("Failed to register {}. Config already registered", config.getConfigPath().getName()); } else { FileWatcher configWatcher = new FileWatcher(); try { configWatcher.setWatch(config.getConfigPath(), () -> { - if (!config.isSaveCalled()) { - CraterConstants.LOG.info("Sending Reload Event for: " + config.getConfigPath().getName()); + if (!config.isWasSaveCalled()) { + CraterConstants.LOG.info("Sending Reload Event for: {}", config.getConfigPath().getName()); config.configReloaded(); } }); } catch (Exception e) { - CraterConstants.LOG.error("Failed to register " + config.getConfigPath().getName() + " for auto reloading. " + e.getMessage()); + CraterConstants.LOG.error("Failed to register {} for auto reloading. {}", config.getConfigPath().getName(), e.getMessage()); } - monitoredConfigs.put(config, configWatcher); - CraterConstants.LOG.info("Registered " + config.getConfigPath().getName() + " successfully!"); + watchedConfigs.put(config.getConfigPath().toString(), Pair.of(config, configWatcher)); + CraterConstants.LOG.info("Registered {} successfully!", config.getConfigPath().getName()); } } diff --git a/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/core/config/ModuleConfig.java b/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/core/config/ModuleConfig.java index 181efdc..e4850bf 100644 --- a/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/core/config/ModuleConfig.java +++ b/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/core/config/ModuleConfig.java @@ -1,9 +1,7 @@ package com.hypherionmc.craterlib.core.config; +import com.hypherionmc.craterlib.core.config.formats.TomlConfigFormat; import me.hypherionmc.moonconfig.core.CommentedConfig; -import me.hypherionmc.moonconfig.core.Config; -import me.hypherionmc.moonconfig.core.conversion.ObjectConverter; -import me.hypherionmc.moonconfig.core.file.CommentedFileConfig; import java.io.File; @@ -12,17 +10,8 @@ import java.io.File; * Base Config class containing the save, upgrading and loading logic. * All config classes must extend this class */ -public class ModuleConfig { - - /* Final Variables */ - private final transient File configPath; - private final transient String networkID; - - private final transient String configName; - - private final transient String modId; - - private transient boolean isSaveCalled = false; +@Deprecated +public class ModuleConfig extends AbstractConfig { /** * Set up the config @@ -35,20 +24,7 @@ public class ModuleConfig { } public ModuleConfig(String modId, String subFolder, String configName) { - /* Preserve the order of the config values */ - Config.setInsertionOrderPreserved(true); - - /* Configure Paths and Network SYNC ID */ - File configDir = new File("config" + (subFolder.isEmpty() ? "" : File.separator + subFolder)); - configPath = new File(configDir + File.separator + configName + ".toml"); - networkID = modId + ":conf_" + configName.replace("-", "_"); - this.modId = modId; - this.configName = configName; - - /* Check if the required directories exists, otherwise we create them */ - if (!configDir.exists()) { - configDir.mkdirs(); - } + super(modId, subFolder.isEmpty() ? null : subFolder, configName); } /** @@ -57,14 +33,7 @@ public class ModuleConfig { * @param config - The config class to use */ public void registerAndSetup(ModuleConfig config) { - if (!configPath.exists() || configPath.length() < 2) { - saveConfig(config); - } else { - migrateConfig(config); - } - /* Register the Config for Watching and events */ - ConfigController.register_config(this); - this.configReloaded(); + super.registerAndSetup(config); } /** @@ -73,16 +42,7 @@ public class ModuleConfig { * @param conf - The config class to serialize and save */ public void saveConfig(ModuleConfig conf) { - this.isSaveCalled = true; - /* Set up the Serializer and Config Object */ - ObjectConverter converter = new ObjectConverter(); - CommentedFileConfig config = CommentedFileConfig.builder(configPath).build(); - - /* Save the config and fire the reload events */ - converter.toConfig(conf, config); - config.save(); - configReloaded(); - this.isSaveCalled = false; + super.registerAndSetup(conf); } /** @@ -92,14 +52,7 @@ public class ModuleConfig { * @return - Returns the loaded version of the class */ public T loadConfig(Object conf) { - /* Set up the Serializer and Config Object */ - ObjectConverter converter = new ObjectConverter(); - CommentedFileConfig config = CommentedFileConfig.builder(configPath).build(); - config.load(); - - /* Load the config and return the loaded config */ - converter.toObject(config, conf); - return (T) conf; + return (T) super.readConfig(conf); } /** @@ -108,31 +61,13 @@ public class ModuleConfig { * @param conf - The config class to load */ public void migrateConfig(ModuleConfig conf) { - /* Set up the Serializer and Config Objects */ - CommentedFileConfig config = CommentedFileConfig.builder(configPath).build(); - CommentedFileConfig newConfig = CommentedFileConfig.builder(configPath).build(); - config.load(); - - /* Upgrade the config */ - new ObjectConverter().toConfig(conf, newConfig); - updateConfigValues(config, newConfig, newConfig, ""); - newConfig.save(); - - config.close(); - newConfig.close(); + super.migrateConfig(conf); } public void updateConfigValues(CommentedConfig oldConfig, CommentedConfig newConfig, CommentedConfig outputConfig, String subKey) { - /* Loop over the config keys and check what has changed */ - newConfig.valueMap().forEach((key, value) -> { - String finalKey = subKey + (subKey.isEmpty() ? "" : ".") + key; - if (value instanceof CommentedConfig commentedConfig) { - updateConfigValues(oldConfig, commentedConfig, outputConfig, finalKey); - } else { - outputConfig.set(finalKey, - oldConfig.contains(finalKey) ? oldConfig.get(finalKey) : value); - } - }); + if (getConfigFormat() instanceof TomlConfigFormat t) { + t.updateConfigValues(oldConfig, newConfig, outputConfig, subKey); + } } /** @@ -141,7 +76,7 @@ public class ModuleConfig { * @return - The FILE object containing the config file */ public File getConfigPath() { - return configPath; + return super.getConfigPath(); } /** @@ -150,12 +85,13 @@ public class ModuleConfig { * @return - Returns the Sync ID in format modid:config_name */ public String getNetworkID() { - return networkID; + return super.getNetworkID(); } /** * Fired whenever changes to the config are detected */ + @Override public void configReloaded() { } @@ -166,7 +102,7 @@ public class ModuleConfig { * @return */ public String getConfigName() { - return configName; + return super.getConfigName(); } /** @@ -175,10 +111,10 @@ public class ModuleConfig { * @return */ public String getModId() { - return modId; + return super.getModId(); } public boolean isSaveCalled() { - return isSaveCalled; + return super.isWasSaveCalled(); } } diff --git a/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/core/config/formats/AbstractConfigFormat.java b/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/core/config/formats/AbstractConfigFormat.java new file mode 100644 index 0000000..20511ba --- /dev/null +++ b/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/core/config/formats/AbstractConfigFormat.java @@ -0,0 +1,32 @@ +package com.hypherionmc.craterlib.core.config.formats; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import me.hypherionmc.moonconfig.core.Config; + +import java.io.File; + +@RequiredArgsConstructor +@Getter +public abstract class AbstractConfigFormat { + + private final File configPath; + private final Runnable onSave; + + public void register(S conf) { + if (!configPath.exists() || configPath.length() < 2) { + saveConfig(conf); + } else { + migrateConfig(conf); + } + } + + public boolean wasConfigChanged(Config old, Config newConfig) { + return true; + } + + public abstract void saveConfig(S config); + public abstract S readConfig(S config); + public abstract void migrateConfig(S config); + +} diff --git a/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/core/config/formats/JsonConfigFormat.java b/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/core/config/formats/JsonConfigFormat.java new file mode 100644 index 0000000..0db35fa --- /dev/null +++ b/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/core/config/formats/JsonConfigFormat.java @@ -0,0 +1,67 @@ +package com.hypherionmc.craterlib.core.config.formats; + +import me.hypherionmc.moonconfig.core.Config; +import me.hypherionmc.moonconfig.core.conversion.ObjectConverter; +import me.hypherionmc.moonconfig.core.file.FileConfig; + +import java.io.File; + +public class JsonConfigFormat extends AbstractConfigFormat { + + public JsonConfigFormat(File configPath, Runnable afterSave) { + super(configPath, afterSave); + } + + @Override + public void saveConfig(S conf) { + ObjectConverter converter = new ObjectConverter(); + FileConfig config = FileConfig.builder(getConfigPath()).sync().build(); + + converter.toConfig(conf, config); + config.save(); + getOnSave().run(); + } + + @Override + public S readConfig(S conf) { + /* Set up the Serializer and Config Object */ + ObjectConverter converter = new ObjectConverter(); + FileConfig config = FileConfig.builder(getConfigPath()).build(); + config.load(); + + /* Load the config and return the loaded config */ + converter.toObject(config, conf); + return conf; + } + + @Override + public void migrateConfig(S conf) { + /* Set up the Serializer and Config Objects */ + FileConfig config = FileConfig.builder(getConfigPath()).build(); + FileConfig newConfig = FileConfig.builder(getConfigPath()).sync().build(); + config.load(); + + /* Upgrade the config */ + if (wasConfigChanged(config, newConfig)) { + new ObjectConverter().toConfig(conf, newConfig); + updateConfigValues(config, newConfig, newConfig, ""); + newConfig.save(); + } + + config.close(); + newConfig.close(); + } + + public void updateConfigValues(Config oldConfig, Config newConfig, Config outputConfig, String subKey) { + /* Loop over the config keys and check what has changed */ + newConfig.valueMap().forEach((key, value) -> { + String finalKey = subKey + (subKey.isEmpty() ? "" : ".") + key; + if (value instanceof Config commentedConfig) { + updateConfigValues(oldConfig, commentedConfig, outputConfig, finalKey); + } else { + outputConfig.set(finalKey, + oldConfig.contains(finalKey) ? oldConfig.get(finalKey) : value); + } + }); + } +} diff --git a/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/core/config/formats/TomlConfigFormat.java b/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/core/config/formats/TomlConfigFormat.java new file mode 100644 index 0000000..e3f9763 --- /dev/null +++ b/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/core/config/formats/TomlConfigFormat.java @@ -0,0 +1,67 @@ +package com.hypherionmc.craterlib.core.config.formats; + +import me.hypherionmc.moonconfig.core.CommentedConfig; +import me.hypherionmc.moonconfig.core.conversion.ObjectConverter; +import me.hypherionmc.moonconfig.core.file.CommentedFileConfig; + +import java.io.File; + +public class TomlConfigFormat extends AbstractConfigFormat { + + public TomlConfigFormat(File configPath, Runnable onSave) { + super(configPath, onSave); + } + + @Override + public void saveConfig(S conf) { + ObjectConverter converter = new ObjectConverter(); + CommentedFileConfig config = CommentedFileConfig.builder(getConfigPath()).sync().build(); + + converter.toConfig(conf, config); + config.save(); + getOnSave().run(); + } + + @Override + public S readConfig(S conf) { + /* Set up the Serializer and Config Object */ + ObjectConverter converter = new ObjectConverter(); + CommentedFileConfig config = CommentedFileConfig.builder(getConfigPath()).build(); + config.load(); + + /* Load the config and return the loaded config */ + converter.toObject(config, conf); + return conf; + } + + @Override + public void migrateConfig(S conf) { + /* Set up the Serializer and Config Objects */ + CommentedFileConfig config = CommentedFileConfig.builder(getConfigPath()).build(); + CommentedFileConfig newConfig = CommentedFileConfig.builder(getConfigPath()).sync().build(); + config.load(); + + /* Upgrade the config */ + if (wasConfigChanged(config, newConfig)) { + new ObjectConverter().toConfig(conf, newConfig); + updateConfigValues(config, newConfig, newConfig, ""); + newConfig.save(); + } + + config.close(); + newConfig.close(); + } + + public void updateConfigValues(CommentedConfig oldConfig, CommentedConfig newConfig, CommentedConfig outputConfig, String subKey) { + /* Loop over the config keys and check what has changed */ + newConfig.valueMap().forEach((key, value) -> { + String finalKey = subKey + (subKey.isEmpty() ? "" : ".") + key; + if (value instanceof CommentedConfig commentedConfig) { + updateConfigValues(oldConfig, commentedConfig, outputConfig, finalKey); + } else { + outputConfig.set(finalKey, + oldConfig.contains(finalKey) ? oldConfig.get(finalKey) : value); + } + }); + } +} diff --git a/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/ServerStatusMixin.java b/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/ServerStatusMixin.java new file mode 100644 index 0000000..53985e7 --- /dev/null +++ b/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/ServerStatusMixin.java @@ -0,0 +1,27 @@ +package com.hypherionmc.craterlib.mixin.events; + +import com.hypherionmc.craterlib.api.events.server.ServerStatusEvent; +import com.hypherionmc.craterlib.core.event.CraterEventBus; +import com.hypherionmc.craterlib.nojang.network.protocol.status.WrappedServerStatus; +import net.minecraft.network.protocol.status.ServerStatus; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import java.util.Optional; + +@Mixin(ServerStatus.class) +public class ServerStatusMixin { + + @Inject(method = "favicon", at = @At("RETURN"), cancellable = true) + private void injectIconEvent(CallbackInfoReturnable> cir) { + ServerStatusEvent.FaviconRequestEvent event = new ServerStatusEvent.FaviconRequestEvent(cir.getReturnValue().isEmpty() ? Optional.empty() : Optional.of(new WrappedServerStatus.WrappedFavicon(cir.getReturnValue().get()))); + CraterEventBus.INSTANCE.postEvent(event); + + if (event.getNewIcon().isPresent()) { + cir.setReturnValue(Optional.of(event.getNewIcon().get().toMojang())); + } + } + +} diff --git a/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/BridgedCommandSourceStack.java b/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/BridgedCommandSourceStack.java index 5a15402..5529824 100644 --- a/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/BridgedCommandSourceStack.java +++ b/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/BridgedCommandSourceStack.java @@ -16,6 +16,10 @@ public class BridgedCommandSourceStack { internal.sendSuccess(() -> ChatUtils.adventureToMojang(supplier.get()), bl); } + public void sendFailure(Component text) { + internal.sendFailure(ChatUtils.adventureToMojang(text)); + } + public CommandSourceStack toMojang() { return internal; } diff --git a/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/CommandsRegistry.java b/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/CommandsRegistry.java deleted file mode 100644 index 37ad15b..0000000 --- a/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/CommandsRegistry.java +++ /dev/null @@ -1,85 +0,0 @@ -package com.hypherionmc.craterlib.nojang.commands; - -import com.hypherionmc.craterlib.api.commands.CraterCommand; -import com.hypherionmc.craterlib.nojang.authlib.BridgedGameProfile; -import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer; -import com.hypherionmc.craterlib.utils.TriConsumer; -import com.mojang.authlib.GameProfile; -import com.mojang.brigadier.CommandDispatcher; -import com.mojang.brigadier.builder.LiteralArgumentBuilder; -import lombok.AccessLevel; -import lombok.NoArgsConstructor; -import net.minecraft.commands.CommandSourceStack; -import net.minecraft.commands.Commands; -import net.minecraft.commands.arguments.GameProfileArgument; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -@NoArgsConstructor(access = AccessLevel.PRIVATE) -public class CommandsRegistry { - - public static final CommandsRegistry INSTANCE = new CommandsRegistry(); - - private final List commands = new ArrayList<>(); - - public void registerCommand(CraterCommand cmd) { - commands.add(cmd); - } - - public void registerCommands(CommandDispatcher stack) { - commands.forEach(cmd -> { - if (cmd.hasArguments()) { - CommandWithArguments.register(cmd, stack); - } else { - CommandWithoutArguments.register(cmd, stack); - } - }); - } - - static class CommandWithoutArguments { - - public static void register(CraterCommand cmd, CommandDispatcher dispatcher) { - LiteralArgumentBuilder command = Commands.literal(cmd.getCommandName()) - .requires(source -> source.hasPermission(cmd.getPermissionLevel())) - .executes(context -> { - cmd.getExecutor().accept(BridgedCommandSourceStack.of(context.getSource())); - return 1; - }); - - dispatcher.register(command); - } - - } - - @SuppressWarnings("unchecked") - static class CommandWithArguments { - - public static void register(CraterCommand cmd, CommandDispatcher dispatcher) { - LiteralArgumentBuilder command = Commands.literal(cmd.getCommandName()) - .requires(source -> source.hasPermission(cmd.getPermissionLevel())); - - cmd.getArguments().forEach((key, pair) -> command.then(Commands.argument(key, pair.getLeft()).executes(context -> { - - // This is FUCKING UGLY.... Need to improve this in the future - if (pair.getLeft() instanceof GameProfileArgument) { - Collection profiles = GameProfileArgument.getGameProfiles(context, key); - List bridgedGameProfiles = new ArrayList<>(); - - profiles.forEach(p -> bridgedGameProfiles.add(BridgedGameProfile.of(p))); - - ((TriConsumer, BridgedCommandSourceStack>) pair.getRight()) - .accept(BridgedPlayer.of(context.getSource().getPlayer()), bridgedGameProfiles, BridgedCommandSourceStack.of(context.getSource())); - return 1; - } - - return 1; - }))); - - dispatcher.register(command); - } - - } - -} diff --git a/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/nojang/network/protocol/status/WrappedServerStatus.java b/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/nojang/network/protocol/status/WrappedServerStatus.java new file mode 100644 index 0000000..ae6f773 --- /dev/null +++ b/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/nojang/network/protocol/status/WrappedServerStatus.java @@ -0,0 +1,31 @@ +package com.hypherionmc.craterlib.nojang.network.protocol.status; + +import net.minecraft.network.protocol.status.ServerStatus; +import org.jetbrains.annotations.ApiStatus; + +public final class WrappedServerStatus { + + public static final class WrappedFavicon { + + private final ServerStatus.Favicon internal; + + public WrappedFavicon(byte[] iconBytes) { + internal = new ServerStatus.Favicon(iconBytes); + } + + @ApiStatus.Internal + public WrappedFavicon(ServerStatus.Favicon internal) { + this.internal = internal; + } + + public byte[] iconBytes() { + return internal.iconBytes(); + } + + public ServerStatus.Favicon toMojang() { + return internal; + } + + } + +} diff --git a/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/nojang/world/entity/player/BridgedPlayer.java b/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/nojang/world/entity/player/BridgedPlayer.java index 8aa6d49..2241836 100644 --- a/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/nojang/world/entity/player/BridgedPlayer.java +++ b/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/nojang/world/entity/player/BridgedPlayer.java @@ -57,6 +57,11 @@ public class BridgedPlayer { return null; } + public void disconnect(Component message) { + if (isServerPlayer()) + toMojangServerPlayer().connection.disconnect(ChatUtils.adventureToMojang(message)); + } + public ServerPlayer toMojangServerPlayer() { return (ServerPlayer) internal; } diff --git a/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/utils/ChatUtils.java b/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/utils/ChatUtils.java index af9736d..5759fde 100644 --- a/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/utils/ChatUtils.java +++ b/1.20.4/Common/src/main/java/com/hypherionmc/craterlib/utils/ChatUtils.java @@ -92,4 +92,11 @@ public class ChatUtils { return mojangToAdventure(Component.translatable(Util.makeDescriptionId("biome", identifier.toMojang()))); } + public static net.kyori.adventure.text.Component format(String value) { + return net.kyori.adventure.text.Component.translatable(convertFormattingCodes(value)); + } + + private static String convertFormattingCodes(String input) { + return input.replaceAll("§([0-9a-fklmnor])", "\u00A7$1"); + } } diff --git a/1.20.4/Common/src/main/resources/craterlib.mixins.json b/1.20.4/Common/src/main/resources/craterlib.mixins.json index 1a739db..c910ed2 100644 --- a/1.20.4/Common/src/main/resources/craterlib.mixins.json +++ b/1.20.4/Common/src/main/resources/craterlib.mixins.json @@ -16,7 +16,8 @@ "events.CommandMixin", "events.PlayerAdvancementsMixin", "events.PlayerListMixin", - "events.ServerPlayerMixin" + "events.ServerPlayerMixin", + "events.ServerStatusMixin" ], "injectors": { "defaultRequire": 1 diff --git a/1.20.4/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibInitializer.java b/1.20.4/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibInitializer.java index c66c210..5e93a3a 100644 --- a/1.20.4/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibInitializer.java +++ b/1.20.4/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibInitializer.java @@ -9,7 +9,6 @@ import com.hypherionmc.craterlib.core.networking.CraterPacketNetwork; import com.hypherionmc.craterlib.core.networking.data.PacketSide; import com.hypherionmc.craterlib.core.platform.ModloaderEnvironment; import com.hypherionmc.craterlib.network.CraterFabricNetworkHandler; -import com.hypherionmc.craterlib.nojang.commands.CommandsRegistry; import com.hypherionmc.craterlib.nojang.server.BridgedMinecraftServer; import net.fabricmc.api.ModInitializer; import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback; @@ -21,8 +20,7 @@ public class CraterLibInitializer implements ModInitializer { public void onInitialize() { new CraterPacketNetwork(new CraterFabricNetworkHandler(PacketSide.SERVER)); CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> { - CraterEventBus.INSTANCE.postEvent(new CraterRegisterCommandEvent()); - CommandsRegistry.INSTANCE.registerCommands(dispatcher); + CraterEventBus.INSTANCE.postEvent(new CraterRegisterCommandEvent(dispatcher)); }); diff --git a/1.20.4/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibModMenuIntegration.java b/1.20.4/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibModMenuIntegration.java index 6615352..5b34ff1 100644 --- a/1.20.4/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibModMenuIntegration.java +++ b/1.20.4/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibModMenuIntegration.java @@ -2,7 +2,6 @@ package com.hypherionmc.craterlib; import com.hypherionmc.craterlib.client.gui.config.CraterConfigScreen; import com.hypherionmc.craterlib.core.config.ConfigController; -import com.hypherionmc.craterlib.core.config.ModuleConfig; import com.hypherionmc.craterlib.core.config.annotations.NoConfigScreen; import com.terraformersmc.modmenu.api.ConfigScreenFactory; import com.terraformersmc.modmenu.api.ModMenuApi; @@ -19,9 +18,9 @@ public class CraterLibModMenuIntegration implements ModMenuApi { public Map> getProvidedConfigScreenFactories() { Map> configScreens = new HashMap<>(); - ConfigController.getMonitoredConfigs().forEach((conf, watcher) -> { + ConfigController.getWatchedConfigs().forEach((conf, watcher) -> { if (!conf.getClass().isAnnotationPresent(NoConfigScreen.class)) { - configScreens.put(((ModuleConfig) conf).getModId(), screen -> new CraterConfigScreen((ModuleConfig) conf, screen)); + configScreens.put(watcher.getLeft().getModId(), screen -> new CraterConfigScreen(watcher.getLeft(), screen)); } }); diff --git a/1.20.4/Fabric/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java b/1.20.4/Fabric/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java index ec01614..7c644d4 100644 --- a/1.20.4/Fabric/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java +++ b/1.20.4/Fabric/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java @@ -27,8 +27,8 @@ public class ServerGamePacketListenerImplMixin { cancellable = true ) private void injectChatEvent(PlayerChatMessage arg, Component arg2, FilteredText arg3, CallbackInfo ci) { - Component finalArg = arg2 == null ? arg.decoratedContent() : arg2; - CraterServerChatEvent event = new CraterServerChatEvent(BridgedPlayer.of(this.player), finalArg.getString(), ChatUtils.mojangToAdventure(finalArg)); + Component finalcomp = arg2 == null ? arg.decoratedContent() : arg2; + CraterServerChatEvent event = new CraterServerChatEvent(BridgedPlayer.of(this.player), finalcomp.getString(), ChatUtils.mojangToAdventure(finalcomp)); CraterEventBus.INSTANCE.postEvent(event); if (event.wasCancelled()) ci.cancel(); diff --git a/1.20.4/Fabric/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java b/1.20.4/Fabric/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java new file mode 100644 index 0000000..f3dc866 --- /dev/null +++ b/1.20.4/Fabric/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java @@ -0,0 +1,52 @@ +package com.hypherionmc.craterlib.mixin; + +import com.hypherionmc.craterlib.api.events.server.ServerStatusEvent; +import com.hypherionmc.craterlib.core.event.CraterEventBus; +import com.hypherionmc.craterlib.utils.ChatUtils; +import net.minecraft.network.Connection; +import net.minecraft.network.protocol.status.ClientboundStatusResponsePacket; +import net.minecraft.network.protocol.status.ServerStatus; +import net.minecraft.network.protocol.status.ServerboundStatusRequestPacket; +import net.minecraft.server.network.ServerStatusPacketListenerImpl; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(ServerStatusPacketListenerImpl.class) +public class ServerStatusPacketListenerMixin { + + @Shadow + @Final + private ServerStatus status; + + @Shadow @Final private Connection connection; + + @Inject(method = "handleStatusRequest", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/network/Connection;send(Lnet/minecraft/network/protocol/Packet;)V", + shift = At.Shift.BEFORE), + cancellable = true + ) + private void injectHandleStatusRequest(ServerboundStatusRequestPacket arg, CallbackInfo ci) { + ServerStatusEvent.StatusRequestEvent event = new ServerStatusEvent.StatusRequestEvent(ChatUtils.mojangToAdventure(status.description())); + CraterEventBus.INSTANCE.postEvent(event); + + if (event.getNewStatus() != null) { + ci.cancel(); + this.connection.send(new ClientboundStatusResponsePacket( + new ServerStatus(ChatUtils.adventureToMojang( + event.getNewStatus()), + status.players(), + status.version(), + status.favicon(), + status.enforcesSecureChat() + ) + )); + } + } + +} \ No newline at end of file diff --git a/1.20.4/Fabric/src/main/resources/craterlib.fabric.mixins.json b/1.20.4/Fabric/src/main/resources/craterlib.fabric.mixins.json index 7c59043..a6d0bc1 100644 --- a/1.20.4/Fabric/src/main/resources/craterlib.fabric.mixins.json +++ b/1.20.4/Fabric/src/main/resources/craterlib.fabric.mixins.json @@ -9,7 +9,8 @@ "TutorialMixin" ], "server": [ - "ServerGamePacketListenerImplMixin" + "ServerGamePacketListenerImplMixin", + "ServerStatusPacketListenerMixin" ], "injectors": { "defaultRequire": 1 diff --git a/1.20.4/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeServerEvents.java b/1.20.4/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeServerEvents.java index f354ddc..37ddf87 100644 --- a/1.20.4/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeServerEvents.java +++ b/1.20.4/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeServerEvents.java @@ -3,7 +3,6 @@ package com.hypherionmc.craterlib.common; import com.hypherionmc.craterlib.api.events.server.CraterRegisterCommandEvent; import com.hypherionmc.craterlib.api.events.server.CraterServerLifecycleEvent; import com.hypherionmc.craterlib.core.event.CraterEventBus; -import com.hypherionmc.craterlib.nojang.commands.CommandsRegistry; import com.hypherionmc.craterlib.nojang.server.BridgedMinecraftServer; import net.minecraftforge.event.RegisterCommandsEvent; import net.minecraftforge.event.server.ServerStartedEvent; @@ -36,8 +35,7 @@ public class ForgeServerEvents { @SubscribeEvent public void onCommandRegister(RegisterCommandsEvent event) { - CraterEventBus.INSTANCE.postEvent(new CraterRegisterCommandEvent()); - CommandsRegistry.INSTANCE.registerCommands(event.getDispatcher()); + CraterEventBus.INSTANCE.postEvent(new CraterRegisterCommandEvent(event.getDispatcher())); } } diff --git a/1.20.4/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java b/1.20.4/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java index 927bd23..d77853c 100644 --- a/1.20.4/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java +++ b/1.20.4/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java @@ -1,8 +1,8 @@ package com.hypherionmc.craterlib.mixin; import com.hypherionmc.craterlib.client.gui.config.CraterConfigScreen; +import com.hypherionmc.craterlib.core.config.AbstractConfig; import com.hypherionmc.craterlib.core.config.ConfigController; -import com.hypherionmc.craterlib.core.config.ModuleConfig; import com.hypherionmc.craterlib.core.config.annotations.NoConfigScreen; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.screens.Screen; @@ -28,9 +28,9 @@ public class ConfigScreenHandlerMixin { */ @Inject(at = @At("RETURN"), method = "getScreenFactoryFor", cancellable = true, remap = false) private static void injectConfigScreen(IModInfo selectedMod, CallbackInfoReturnable>> cir) { - ConfigController.getMonitoredConfigs().forEach((conf, watcher) -> { + ConfigController.getWatchedConfigs().forEach((conf, watcher) -> { if (!conf.getClass().isAnnotationPresent(NoConfigScreen.class)) { - ModuleConfig config = (ModuleConfig) conf; + AbstractConfig config = watcher.getLeft(); if (config.getModId().equals(selectedMod.getModId())) { cir.setReturnValue( Optional.of((minecraft, screen) -> new CraterConfigScreen(config, screen)) diff --git a/1.20.4/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java b/1.20.4/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java index c9b024b..8a0fcfb 100644 --- a/1.20.4/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java +++ b/1.20.4/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java @@ -27,8 +27,8 @@ public class ServerGamePacketListenerImplMixin { cancellable = true ) private void injectChatEvent(Component component, PlayerChatMessage arg, FilteredText p_296589_, CallbackInfo ci) { - Component finalArg = component == null ? arg.decoratedContent() : component; - CraterServerChatEvent event = new CraterServerChatEvent(BridgedPlayer.of(this.player), finalArg.getString(), ChatUtils.mojangToAdventure(finalArg)); + Component finalcomp = component == null ? arg.decoratedContent() : component; + CraterServerChatEvent event = new CraterServerChatEvent(BridgedPlayer.of(this.player), finalcomp.getString(), ChatUtils.mojangToAdventure(finalcomp)); CraterEventBus.INSTANCE.postEvent(event); if (event.wasCancelled()) ci.cancel(); diff --git a/1.20.4/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java b/1.20.4/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java new file mode 100644 index 0000000..969b05d --- /dev/null +++ b/1.20.4/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java @@ -0,0 +1,53 @@ +package com.hypherionmc.craterlib.mixin; + +import com.hypherionmc.craterlib.api.events.server.ServerStatusEvent; +import com.hypherionmc.craterlib.core.event.CraterEventBus; +import com.hypherionmc.craterlib.utils.ChatUtils; +import net.minecraft.network.Connection; +import net.minecraft.network.protocol.status.ClientboundStatusResponsePacket; +import net.minecraft.network.protocol.status.ServerStatus; +import net.minecraft.network.protocol.status.ServerboundStatusRequestPacket; +import net.minecraft.server.network.ServerStatusPacketListenerImpl; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(ServerStatusPacketListenerImpl.class) +public class ServerStatusPacketListenerMixin { + + @Shadow + @Final + private ServerStatus status; + + @Shadow @Final private Connection connection; + + @Inject(method = "handleStatusRequest", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/network/Connection;send(Lnet/minecraft/network/protocol/Packet;)V", + shift = At.Shift.BEFORE), + cancellable = true + ) + private void injectHandleStatusRequest(ServerboundStatusRequestPacket arg, CallbackInfo ci) { + ServerStatusEvent.StatusRequestEvent event = new ServerStatusEvent.StatusRequestEvent(ChatUtils.mojangToAdventure(status.description())); + CraterEventBus.INSTANCE.postEvent(event); + + if (event.getNewStatus() != null) { + ci.cancel(); + this.connection.send(new ClientboundStatusResponsePacket( + new ServerStatus(ChatUtils.adventureToMojang( + event.getNewStatus()), + status.players(), + status.version(), + status.favicon(), + status.enforcesSecureChat(), + status.forgeData() + ) + )); + } + } + +} diff --git a/1.20.4/Forge/src/main/resources/craterlib.forge.mixins.json b/1.20.4/Forge/src/main/resources/craterlib.forge.mixins.json index aa072d1..892f6d7 100644 --- a/1.20.4/Forge/src/main/resources/craterlib.forge.mixins.json +++ b/1.20.4/Forge/src/main/resources/craterlib.forge.mixins.json @@ -9,7 +9,8 @@ "ConfigScreenHandlerMixin" ], "server": [ - "ServerGamePacketListenerImplMixin" + "ServerGamePacketListenerImplMixin", + "ServerStatusPacketListenerMixin" ], "injectors": { "defaultRequire": 1 diff --git a/1.20.4/NeoForge/src/main/java/com/hypherionmc/craterlib/common/NeoForgeServerEvents.java b/1.20.4/NeoForge/src/main/java/com/hypherionmc/craterlib/common/NeoForgeServerEvents.java index 91ca5b7..868b89f 100644 --- a/1.20.4/NeoForge/src/main/java/com/hypherionmc/craterlib/common/NeoForgeServerEvents.java +++ b/1.20.4/NeoForge/src/main/java/com/hypherionmc/craterlib/common/NeoForgeServerEvents.java @@ -3,7 +3,6 @@ package com.hypherionmc.craterlib.common; import com.hypherionmc.craterlib.api.events.server.CraterRegisterCommandEvent; import com.hypherionmc.craterlib.api.events.server.CraterServerLifecycleEvent; import com.hypherionmc.craterlib.core.event.CraterEventBus; -import com.hypherionmc.craterlib.nojang.commands.CommandsRegistry; import com.hypherionmc.craterlib.nojang.server.BridgedMinecraftServer; import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.neoforge.event.RegisterCommandsEvent; @@ -36,8 +35,7 @@ public class NeoForgeServerEvents { @SubscribeEvent public void onCommandRegister(RegisterCommandsEvent event) { - CraterEventBus.INSTANCE.postEvent(new CraterRegisterCommandEvent()); - CommandsRegistry.INSTANCE.registerCommands(event.getDispatcher()); + CraterEventBus.INSTANCE.postEvent(new CraterRegisterCommandEvent(event.getDispatcher())); } } diff --git a/1.20.4/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java b/1.20.4/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java index 809671b..619565c 100644 --- a/1.20.4/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java +++ b/1.20.4/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java @@ -1,6 +1,7 @@ package com.hypherionmc.craterlib.mixin; import com.hypherionmc.craterlib.client.gui.config.CraterConfigScreen; +import com.hypherionmc.craterlib.core.config.AbstractConfig; import com.hypherionmc.craterlib.core.config.ConfigController; import com.hypherionmc.craterlib.core.config.ModuleConfig; import com.hypherionmc.craterlib.core.config.annotations.NoConfigScreen; @@ -28,9 +29,9 @@ public class ConfigScreenHandlerMixin { */ @Inject(at = @At("RETURN"), method = "getScreenFactoryFor", cancellable = true, remap = false) private static void injectConfigScreen(IModInfo selectedMod, CallbackInfoReturnable>> cir) { - ConfigController.getMonitoredConfigs().forEach((conf, watcher) -> { + ConfigController.getWatchedConfigs().forEach((conf, watcher) -> { if (!conf.getClass().isAnnotationPresent(NoConfigScreen.class)) { - ModuleConfig config = (ModuleConfig) conf; + AbstractConfig config = watcher.getLeft(); if (config.getModId().equals(selectedMod.getModId())) { cir.setReturnValue( Optional.of((minecraft, screen) -> new CraterConfigScreen(config, screen)) diff --git a/1.20.4/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java b/1.20.4/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java index c9b024b..8a0fcfb 100644 --- a/1.20.4/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java +++ b/1.20.4/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java @@ -27,8 +27,8 @@ public class ServerGamePacketListenerImplMixin { cancellable = true ) private void injectChatEvent(Component component, PlayerChatMessage arg, FilteredText p_296589_, CallbackInfo ci) { - Component finalArg = component == null ? arg.decoratedContent() : component; - CraterServerChatEvent event = new CraterServerChatEvent(BridgedPlayer.of(this.player), finalArg.getString(), ChatUtils.mojangToAdventure(finalArg)); + Component finalcomp = component == null ? arg.decoratedContent() : component; + CraterServerChatEvent event = new CraterServerChatEvent(BridgedPlayer.of(this.player), finalcomp.getString(), ChatUtils.mojangToAdventure(finalcomp)); CraterEventBus.INSTANCE.postEvent(event); if (event.wasCancelled()) ci.cancel(); diff --git a/1.20.4/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java b/1.20.4/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java new file mode 100644 index 0000000..cb697db --- /dev/null +++ b/1.20.4/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java @@ -0,0 +1,53 @@ +package com.hypherionmc.craterlib.mixin; + +import com.hypherionmc.craterlib.api.events.server.ServerStatusEvent; +import com.hypherionmc.craterlib.core.event.CraterEventBus; +import com.hypherionmc.craterlib.utils.ChatUtils; +import net.minecraft.network.Connection; +import net.minecraft.network.protocol.status.ClientboundStatusResponsePacket; +import net.minecraft.network.protocol.status.ServerStatus; +import net.minecraft.network.protocol.status.ServerboundStatusRequestPacket; +import net.minecraft.server.network.ServerStatusPacketListenerImpl; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(ServerStatusPacketListenerImpl.class) +public class ServerStatusPacketListenerMixin { + + @Shadow + @Final + private ServerStatus status; + + @Shadow @Final private Connection connection; + + @Inject(method = "handleStatusRequest", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/network/Connection;send(Lnet/minecraft/network/protocol/Packet;)V", + shift = At.Shift.BEFORE), + cancellable = true + ) + private void injectHandleStatusRequest(ServerboundStatusRequestPacket arg, CallbackInfo ci) { + ServerStatusEvent.StatusRequestEvent event = new ServerStatusEvent.StatusRequestEvent(ChatUtils.mojangToAdventure(status.description())); + CraterEventBus.INSTANCE.postEvent(event); + + if (event.getNewStatus() != null) { + ci.cancel(); + this.connection.send(new ClientboundStatusResponsePacket( + new ServerStatus(ChatUtils.adventureToMojang( + event.getNewStatus()), + status.players(), + status.version(), + status.favicon(), + status.enforcesSecureChat(), + status.isModded() + ) + )); + } + } + +} \ No newline at end of file diff --git a/1.20.4/NeoForge/src/main/resources/craterlib.neoforge.mixins.json b/1.20.4/NeoForge/src/main/resources/craterlib.neoforge.mixins.json index aa072d1..892f6d7 100644 --- a/1.20.4/NeoForge/src/main/resources/craterlib.neoforge.mixins.json +++ b/1.20.4/NeoForge/src/main/resources/craterlib.neoforge.mixins.json @@ -9,7 +9,8 @@ "ConfigScreenHandlerMixin" ], "server": [ - "ServerGamePacketListenerImplMixin" + "ServerGamePacketListenerImplMixin", + "ServerStatusPacketListenerMixin" ], "injectors": { "defaultRequire": 1 diff --git a/1.20.4/README.md b/1.20.4/README.md index 49c0699..4b18d17 100644 --- a/1.20.4/README.md +++ b/1.20.4/README.md @@ -15,7 +15,7 @@ A Library mod and modding api for easier multi-version minecraft and mod loader | < 1.18.2 | ❌ | | 1.18.2-1.20.2 | ✳️ | | 1.20.4 | ✳️ | -| 1.21 | 🚧 | +| 1.21.x | ✳️ | - ❌ - Not Supported; no bug fixes or new features. - 🚧 - Work in Progress; not ready for release. diff --git a/1.20.4/build.gradle b/1.20.4/build.gradle index e7f9017..f37e586 100644 --- a/1.20.4/build.gradle +++ b/1.20.4/build.gradle @@ -57,11 +57,13 @@ subprojects { // All Projects shade "me.hypherionmc.moon-config:core:${moon_config}" shade "me.hypherionmc.moon-config:toml:${moon_config}" + shade "me.hypherionmc.moon-config:json:${moon_config}" shade "com.hypherionmc:rpcsdk:${rpc_sdk}" shade "me.hypherionmc.sdlink:mcdiscordformatter-1.20.3:${discord_formatter}" shade "net.kyori:adventure-api:${adventure}" shade "net.kyori:adventure-text-serializer-gson:${adventure}" + compileOnly 'net.luckperms:api:5.4' compileOnly("org.projectlombok:lombok:${lombok}") annotationProcessor("org.projectlombok:lombok:${lombok}") } diff --git a/1.20.4/gradle.properties b/1.20.4/gradle.properties index 1b37337..792dfe7 100644 --- a/1.20.4/gradle.properties +++ b/1.20.4/gradle.properties @@ -1,7 +1,7 @@ #Project version_major=2 -version_minor=0 -version_patch=3 +version_minor=1 +version_patch=0 version_build=0 #Mod diff --git a/1.20/Common/src/main/java/com/hypherionmc/craterlib/api/commands/CraterCommand.java b/1.20/Common/src/main/java/com/hypherionmc/craterlib/api/commands/CraterCommand.java index cc4969e..35f29f0 100644 --- a/1.20/Common/src/main/java/com/hypherionmc/craterlib/api/commands/CraterCommand.java +++ b/1.20/Common/src/main/java/com/hypherionmc/craterlib/api/commands/CraterCommand.java @@ -1,53 +1,155 @@ package com.hypherionmc.craterlib.api.commands; +import com.hypherionmc.craterlib.compat.LuckPermsCompat; +import com.hypherionmc.craterlib.core.platform.ModloaderEnvironment; import com.hypherionmc.craterlib.nojang.authlib.BridgedGameProfile; import com.hypherionmc.craterlib.nojang.commands.BridgedCommandSourceStack; import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer; import com.hypherionmc.craterlib.utils.TriConsumer; -import com.mojang.brigadier.arguments.ArgumentType; -import lombok.Getter; +import com.mojang.brigadier.CommandDispatcher; +import com.mojang.brigadier.arguments.BoolArgumentType; +import com.mojang.brigadier.arguments.IntegerArgumentType; +import com.mojang.brigadier.arguments.StringArgumentType; +import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import net.minecraft.commands.CommandSourceStack; +import net.minecraft.commands.Commands; import net.minecraft.commands.arguments.GameProfileArgument; -import org.apache.commons.lang3.tuple.Pair; +import net.minecraft.world.entity.player.Player; +import org.jetbrains.annotations.ApiStatus; -import java.util.HashMap; -import java.util.LinkedHashMap; import java.util.List; import java.util.function.Consumer; -@Getter public class CraterCommand { - private final HashMap, TriConsumer>> arguments = new LinkedHashMap<>(); - private Consumer executor; + private final LiteralArgumentBuilder mojangCommand; + private int permLevel = 4; + private String luckPermNode = ""; - private final String commandName; - private int permissionLevel = 4; - - CraterCommand(String commandName) { - this.commandName = commandName; + CraterCommand(LiteralArgumentBuilder cmd) { + this.mojangCommand = cmd; } public static CraterCommand literal(String commandName) { - return new CraterCommand(commandName); + return new CraterCommand(Commands.literal(commandName)); } public CraterCommand requiresPermission(int perm) { - this.permissionLevel = perm; + this.permLevel = perm; + this.mojangCommand.requires(this::checkPermission); return this; } - public CraterCommand withGameProfileArgument(String key, TriConsumer, BridgedCommandSourceStack> executor) { - arguments.put(key, Pair.of(GameProfileArgument.gameProfile(), executor)); + public CraterCommand withNode(String key) { + this.luckPermNode = key; return this; } + public CraterCommand then(CraterCommand child) { + this.mojangCommand.then(child.mojangCommand); + return this; + } + + public CraterCommand withGameProfilesArgument(String key, CommandExecutorWithArgs> executor) { + this.mojangCommand.then(Commands.argument(key, GameProfileArgument.gameProfile()) + .executes(context -> executor.run( + BridgedPlayer.of(context.getSource().getPlayer()), + GameProfileArgument.getGameProfiles(context, key).stream().map(BridgedGameProfile::of).toList(), + BridgedCommandSourceStack.of(context.getSource())) + )); + return this; + } + + public CraterCommand withBoolArgument(String key, CommandExecutorWithArgs executor) { + this.mojangCommand.then(Commands.argument(key, BoolArgumentType.bool()) + .executes(context -> executor.run( + BridgedPlayer.of(context.getSource().getPlayer()), + BoolArgumentType.getBool(context, key), + BridgedCommandSourceStack.of(context.getSource()) + ))); + return this; + } + + public CraterCommand withWordArgument(String key, CommandExecutorWithArgs executor) { + this.mojangCommand.then(Commands.argument(key, StringArgumentType.word()) + .executes(context -> executor.run( + BridgedPlayer.of(context.getSource().getPlayer()), + StringArgumentType.getString(context, key), + BridgedCommandSourceStack.of(context.getSource()) + ))); + return this; + } + + public CraterCommand withStringArgument(String key, CommandExecutorWithArgs executor) { + this.mojangCommand.then(Commands.argument(key, StringArgumentType.string()) + .executes(context -> executor.run( + BridgedPlayer.of(context.getSource().getPlayer()), + StringArgumentType.getString(context, key), + BridgedCommandSourceStack.of(context.getSource()) + ))); + return this; + } + + public CraterCommand withPhraseArgument(String key, CommandExecutorWithArgs executor) { + this.mojangCommand.then(Commands.argument(key, StringArgumentType.greedyString()) + .executes(context -> executor.run( + BridgedPlayer.of(context.getSource().getPlayer()), + StringArgumentType.getString(context, key), + BridgedCommandSourceStack.of(context.getSource()) + ))); + return this; + } + + public CraterCommand withIntegerArgument(String key, CommandExecutorWithArgs executor) { + this.mojangCommand.then(Commands.argument(key, IntegerArgumentType.integer()) + .executes(context -> executor.run( + BridgedPlayer.of(context.getSource().getPlayer()), + IntegerArgumentType.getInteger(context, key), + BridgedCommandSourceStack.of(context.getSource()) + ))); + return this; + } + + public CraterCommand execute(SingleCommandExecutor executor) { + this.mojangCommand.executes(context -> executor.run(BridgedCommandSourceStack.of(context.getSource()))); + return this; + } + + @Deprecated(forRemoval = true) public CraterCommand executes(Consumer ctx) { - executor = ctx; - return this; + return this.execute(stack -> { + ctx.accept(stack); + return 1; + }); } - public boolean hasArguments() { - return !arguments.isEmpty(); + @Deprecated(forRemoval = true) + public CraterCommand withGameProfileArgument(String key, TriConsumer, BridgedCommandSourceStack> executor) { + return this.withGameProfilesArgument(key, (player, argument, stack) -> { + executor.accept(player, argument, stack); + return 1; + }); } + @ApiStatus.Internal + public void register(CommandDispatcher stack) { + stack.register(this.mojangCommand); + } + + private boolean checkPermission(CommandSourceStack stack) { + if (!ModloaderEnvironment.INSTANCE.isModLoaded("luckperms") || !stack.isPlayer() || luckPermNode.isEmpty()) + return stack.hasPermission(this.permLevel); + + return LuckPermsCompat.INSTANCE.hasPermission(stack.getPlayer(), this.luckPermNode) || stack.hasPermission(this.permLevel); + } + + @FunctionalInterface + public interface CommandExecutorWithArgs { + int run(BridgedPlayer player, S argument, BridgedCommandSourceStack stack); + } + + @FunctionalInterface + public interface SingleCommandExecutor { + int run(S stack); + } } diff --git a/1.20/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterPlayerEvent.java b/1.20/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterPlayerEvent.java index 94be675..9e7d7a2 100644 --- a/1.20/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterPlayerEvent.java +++ b/1.20/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterPlayerEvent.java @@ -4,7 +4,6 @@ import com.hypherionmc.craterlib.core.event.CraterEvent; import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer; import lombok.Getter; import lombok.RequiredArgsConstructor; -import lombok.Setter; @RequiredArgsConstructor @Getter diff --git a/1.20/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterRegisterCommandEvent.java b/1.20/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterRegisterCommandEvent.java index 269065a..5adac03 100644 --- a/1.20/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterRegisterCommandEvent.java +++ b/1.20/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterRegisterCommandEvent.java @@ -2,14 +2,17 @@ package com.hypherionmc.craterlib.api.events.server; import com.hypherionmc.craterlib.api.commands.CraterCommand; import com.hypherionmc.craterlib.core.event.CraterEvent; -import com.hypherionmc.craterlib.nojang.commands.CommandsRegistry; -import lombok.NoArgsConstructor; +import com.mojang.brigadier.CommandDispatcher; +import lombok.AllArgsConstructor; +import net.minecraft.commands.CommandSourceStack; -@NoArgsConstructor +@AllArgsConstructor public class CraterRegisterCommandEvent extends CraterEvent { + private final CommandDispatcher stack; + public void registerCommand(CraterCommand cmd) { - CommandsRegistry.INSTANCE.registerCommand(cmd); + cmd.register(stack); } } diff --git a/1.20/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/ServerStatusEvent.java b/1.20/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/ServerStatusEvent.java new file mode 100644 index 0000000..b58dafa --- /dev/null +++ b/1.20/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/ServerStatusEvent.java @@ -0,0 +1,35 @@ +package com.hypherionmc.craterlib.api.events.server; + +import com.hypherionmc.craterlib.core.event.CraterEvent; +import com.hypherionmc.craterlib.nojang.network.protocol.status.WrappedServerStatus; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.Setter; +import net.kyori.adventure.text.Component; +import org.jetbrains.annotations.Nullable; + +import java.util.Optional; + +public class ServerStatusEvent { + + @RequiredArgsConstructor + @Getter + @Setter + public static class StatusRequestEvent extends CraterEvent { + + private final Component status; + @Nullable + private Component newStatus = null; + + } + + @RequiredArgsConstructor + @Getter + @Setter + public static class FaviconRequestEvent extends CraterEvent { + + private final Optional favicon; + private Optional newIcon = Optional.empty(); + + } +} diff --git a/1.20/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/CraterConfigScreen.java b/1.20/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/CraterConfigScreen.java index 50fb3cf..c4ea3a4 100644 --- a/1.20/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/CraterConfigScreen.java +++ b/1.20/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/CraterConfigScreen.java @@ -2,7 +2,7 @@ package com.hypherionmc.craterlib.client.gui.config; import com.hypherionmc.craterlib.CraterConstants; import com.hypherionmc.craterlib.client.gui.config.widgets.*; -import com.hypherionmc.craterlib.core.config.ModuleConfig; +import com.hypherionmc.craterlib.core.config.AbstractConfig; import com.hypherionmc.craterlib.core.config.annotations.HideFromScreen; import com.hypherionmc.craterlib.core.config.annotations.SubConfig; import com.hypherionmc.craterlib.core.config.annotations.Tooltip; @@ -44,11 +44,11 @@ public class CraterConfigScreen extends Screen { private static final int BOTTOM = 24; private final Screen parent; private final List> options = new ArrayList<>(); - private final ModuleConfig config; + private final AbstractConfig config; public double scrollerAmount; private boolean dragging; - public CraterConfigScreen(ModuleConfig config, Screen parent, Object subConfig) { + public CraterConfigScreen(AbstractConfig config, Screen parent, Object subConfig) { super(Component.translatable("cl." + config.getClass().getSimpleName().toLowerCase() + ".title")); this.parent = parent; this.config = config; @@ -59,7 +59,7 @@ public class CraterConfigScreen extends Screen { } } - public CraterConfigScreen(ModuleConfig config, Screen parent) { + public CraterConfigScreen(AbstractConfig config, Screen parent) { this(config, parent, null); } diff --git a/1.20/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/SubConfigWidget.java b/1.20/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/SubConfigWidget.java index 9426ccf..056f32c 100644 --- a/1.20/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/SubConfigWidget.java +++ b/1.20/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/SubConfigWidget.java @@ -1,7 +1,7 @@ package com.hypherionmc.craterlib.client.gui.config.widgets; import com.hypherionmc.craterlib.client.gui.config.CraterConfigScreen; -import com.hypherionmc.craterlib.core.config.ModuleConfig; +import com.hypherionmc.craterlib.core.config.AbstractConfig; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Font; import net.minecraft.client.gui.GuiGraphics; @@ -15,10 +15,10 @@ import net.minecraft.network.chat.Component; public class SubConfigWidget extends AbstractConfigWidget { private final Object subConfig; - private final ModuleConfig config; + private final AbstractConfig config; private final Screen screen; - public SubConfigWidget(ModuleConfig config, Screen screen, Object subConfig) { + public SubConfigWidget(AbstractConfig config, Screen screen, Object subConfig) { this.config = config; this.subConfig = subConfig; this.screen = screen; diff --git a/1.20/Common/src/main/java/com/hypherionmc/craterlib/compat/LuckPermsCompat.java b/1.20/Common/src/main/java/com/hypherionmc/craterlib/compat/LuckPermsCompat.java new file mode 100644 index 0000000..a77e1f4 --- /dev/null +++ b/1.20/Common/src/main/java/com/hypherionmc/craterlib/compat/LuckPermsCompat.java @@ -0,0 +1,20 @@ +package com.hypherionmc.craterlib.compat; + +import net.luckperms.api.LuckPerms; +import net.luckperms.api.LuckPermsProvider; +import net.luckperms.api.model.user.User; +import net.minecraft.server.level.ServerPlayer; + +public class LuckPermsCompat { + + public static final LuckPermsCompat INSTANCE = new LuckPermsCompat(); + private final LuckPerms luckPerms = LuckPermsProvider.get(); + + LuckPermsCompat() {} + + public boolean hasPermission(ServerPlayer player, String perm) { + User luckPermsUser = luckPerms.getPlayerAdapter(ServerPlayer.class).getUser(player); + return luckPermsUser.getCachedData().getPermissionData().checkPermission(perm).asBoolean(); + } + +} diff --git a/1.20/Common/src/main/java/com/hypherionmc/craterlib/core/config/AbstractConfig.java b/1.20/Common/src/main/java/com/hypherionmc/craterlib/core/config/AbstractConfig.java new file mode 100644 index 0000000..eceac79 --- /dev/null +++ b/1.20/Common/src/main/java/com/hypherionmc/craterlib/core/config/AbstractConfig.java @@ -0,0 +1,71 @@ +package com.hypherionmc.craterlib.core.config; + +import com.hypherionmc.craterlib.core.config.formats.AbstractConfigFormat; +import com.hypherionmc.craterlib.core.config.formats.JsonConfigFormat; +import com.hypherionmc.craterlib.core.config.formats.TomlConfigFormat; +import lombok.Getter; +import lombok.Setter; +import me.hypherionmc.moonconfig.core.Config; +import org.jetbrains.annotations.Nullable; + +import java.io.File; + +@Getter +public abstract class AbstractConfig { + + /* Final Variables */ + private final transient File configPath; + private final transient String networkID; + private final transient String configName; + private final transient String modId; + private transient boolean wasSaveCalled = false; + + @Setter + private transient AbstractConfigFormat configFormat; + + public AbstractConfig(String modId, String configName) { + this(modId, null, configName); + } + + public AbstractConfig(String modId, @Nullable String subFolder, String configName) { + Config.setInsertionOrderPreserved(true); + + if (!configName.endsWith(".toml") && !configName.endsWith(".json")) + configName = configName + ".toml"; + + File configDir = new File("config" + (subFolder == null ? "" : File.separator + subFolder)); + configPath = new File(configDir, configName); + this.modId = modId; + this.networkID = modId + ":conf_" + configName.replace(".toml", "").replace(".json", "").replace("-", "_").toLowerCase(); + this.configName = configName.replace(".toml", "").replace(".json", ""); + configDir.mkdirs(); + + configFormat = configName.endsWith(".json") ? new JsonConfigFormat<>(configPath, this::onSave) : new TomlConfigFormat<>(configPath, this::onSave); + } + + public void registerAndSetup(S config) { + configFormat.register(config); + ConfigController.register_config(this); + this.configReloaded(); + } + + public void saveConfig(S config) { + this.wasSaveCalled = true; + configFormat.saveConfig(config); + } + + private void onSave() { + this.configReloaded(); + this.wasSaveCalled = false; + } + + public S readConfig(S config) { + return configFormat.readConfig(config); + } + + public void migrateConfig(S config) { + configFormat.migrateConfig(config); + } + + public abstract void configReloaded(); +} diff --git a/1.20/Common/src/main/java/com/hypherionmc/craterlib/core/config/ConfigController.java b/1.20/Common/src/main/java/com/hypherionmc/craterlib/core/config/ConfigController.java index 41c9471..760ca93 100644 --- a/1.20/Common/src/main/java/com/hypherionmc/craterlib/core/config/ConfigController.java +++ b/1.20/Common/src/main/java/com/hypherionmc/craterlib/core/config/ConfigController.java @@ -3,6 +3,7 @@ package com.hypherionmc.craterlib.core.config; import com.hypherionmc.craterlib.CraterConstants; import lombok.Getter; import me.hypherionmc.moonconfig.core.file.FileWatcher; +import org.apache.commons.lang3.tuple.Pair; import org.jetbrains.annotations.ApiStatus; import java.io.Serializable; @@ -18,7 +19,7 @@ public final class ConfigController implements Serializable { * Cache of registered configs */ @Getter - private static final HashMap monitoredConfigs = new HashMap<>(); + private static final HashMap> watchedConfigs = new HashMap<>(); /** * INTERNAL METHOD - Register and watch the config @@ -26,23 +27,34 @@ public final class ConfigController implements Serializable { * @param config - The config class to register and watch */ @ApiStatus.Internal + @Deprecated public static void register_config(ModuleConfig config) { - if (monitoredConfigs.containsKey(config)) { - CraterConstants.LOG.error("Failed to register " + config.getConfigPath().getName() + ". Config already registered"); + register_config((AbstractConfig) config); + } + + /** + * INTERNAL METHOD - Register and watch the config + * + * @param config - The config class to register and watch + */ + @ApiStatus.Internal + public static void register_config(AbstractConfig config) { + if (watchedConfigs.containsKey(config.getConfigPath().toString())) { + CraterConstants.LOG.error("Failed to register {}. Config already registered", config.getConfigPath().getName()); } else { FileWatcher configWatcher = new FileWatcher(); try { configWatcher.setWatch(config.getConfigPath(), () -> { - if (!config.isSaveCalled()) { - CraterConstants.LOG.info("Sending Reload Event for: " + config.getConfigPath().getName()); + if (!config.isWasSaveCalled()) { + CraterConstants.LOG.info("Sending Reload Event for: {}", config.getConfigPath().getName()); config.configReloaded(); } }); } catch (Exception e) { - CraterConstants.LOG.error("Failed to register " + config.getConfigPath().getName() + " for auto reloading. " + e.getMessage()); + CraterConstants.LOG.error("Failed to register {} for auto reloading. {}", config.getConfigPath().getName(), e.getMessage()); } - monitoredConfigs.put(config, configWatcher); - CraterConstants.LOG.info("Registered " + config.getConfigPath().getName() + " successfully!"); + watchedConfigs.put(config.getConfigPath().toString(), Pair.of(config, configWatcher)); + CraterConstants.LOG.info("Registered {} successfully!", config.getConfigPath().getName()); } } diff --git a/1.20/Common/src/main/java/com/hypherionmc/craterlib/core/config/ModuleConfig.java b/1.20/Common/src/main/java/com/hypherionmc/craterlib/core/config/ModuleConfig.java index 181efdc..e4850bf 100644 --- a/1.20/Common/src/main/java/com/hypherionmc/craterlib/core/config/ModuleConfig.java +++ b/1.20/Common/src/main/java/com/hypherionmc/craterlib/core/config/ModuleConfig.java @@ -1,9 +1,7 @@ package com.hypherionmc.craterlib.core.config; +import com.hypherionmc.craterlib.core.config.formats.TomlConfigFormat; import me.hypherionmc.moonconfig.core.CommentedConfig; -import me.hypherionmc.moonconfig.core.Config; -import me.hypherionmc.moonconfig.core.conversion.ObjectConverter; -import me.hypherionmc.moonconfig.core.file.CommentedFileConfig; import java.io.File; @@ -12,17 +10,8 @@ import java.io.File; * Base Config class containing the save, upgrading and loading logic. * All config classes must extend this class */ -public class ModuleConfig { - - /* Final Variables */ - private final transient File configPath; - private final transient String networkID; - - private final transient String configName; - - private final transient String modId; - - private transient boolean isSaveCalled = false; +@Deprecated +public class ModuleConfig extends AbstractConfig { /** * Set up the config @@ -35,20 +24,7 @@ public class ModuleConfig { } public ModuleConfig(String modId, String subFolder, String configName) { - /* Preserve the order of the config values */ - Config.setInsertionOrderPreserved(true); - - /* Configure Paths and Network SYNC ID */ - File configDir = new File("config" + (subFolder.isEmpty() ? "" : File.separator + subFolder)); - configPath = new File(configDir + File.separator + configName + ".toml"); - networkID = modId + ":conf_" + configName.replace("-", "_"); - this.modId = modId; - this.configName = configName; - - /* Check if the required directories exists, otherwise we create them */ - if (!configDir.exists()) { - configDir.mkdirs(); - } + super(modId, subFolder.isEmpty() ? null : subFolder, configName); } /** @@ -57,14 +33,7 @@ public class ModuleConfig { * @param config - The config class to use */ public void registerAndSetup(ModuleConfig config) { - if (!configPath.exists() || configPath.length() < 2) { - saveConfig(config); - } else { - migrateConfig(config); - } - /* Register the Config for Watching and events */ - ConfigController.register_config(this); - this.configReloaded(); + super.registerAndSetup(config); } /** @@ -73,16 +42,7 @@ public class ModuleConfig { * @param conf - The config class to serialize and save */ public void saveConfig(ModuleConfig conf) { - this.isSaveCalled = true; - /* Set up the Serializer and Config Object */ - ObjectConverter converter = new ObjectConverter(); - CommentedFileConfig config = CommentedFileConfig.builder(configPath).build(); - - /* Save the config and fire the reload events */ - converter.toConfig(conf, config); - config.save(); - configReloaded(); - this.isSaveCalled = false; + super.registerAndSetup(conf); } /** @@ -92,14 +52,7 @@ public class ModuleConfig { * @return - Returns the loaded version of the class */ public T loadConfig(Object conf) { - /* Set up the Serializer and Config Object */ - ObjectConverter converter = new ObjectConverter(); - CommentedFileConfig config = CommentedFileConfig.builder(configPath).build(); - config.load(); - - /* Load the config and return the loaded config */ - converter.toObject(config, conf); - return (T) conf; + return (T) super.readConfig(conf); } /** @@ -108,31 +61,13 @@ public class ModuleConfig { * @param conf - The config class to load */ public void migrateConfig(ModuleConfig conf) { - /* Set up the Serializer and Config Objects */ - CommentedFileConfig config = CommentedFileConfig.builder(configPath).build(); - CommentedFileConfig newConfig = CommentedFileConfig.builder(configPath).build(); - config.load(); - - /* Upgrade the config */ - new ObjectConverter().toConfig(conf, newConfig); - updateConfigValues(config, newConfig, newConfig, ""); - newConfig.save(); - - config.close(); - newConfig.close(); + super.migrateConfig(conf); } public void updateConfigValues(CommentedConfig oldConfig, CommentedConfig newConfig, CommentedConfig outputConfig, String subKey) { - /* Loop over the config keys and check what has changed */ - newConfig.valueMap().forEach((key, value) -> { - String finalKey = subKey + (subKey.isEmpty() ? "" : ".") + key; - if (value instanceof CommentedConfig commentedConfig) { - updateConfigValues(oldConfig, commentedConfig, outputConfig, finalKey); - } else { - outputConfig.set(finalKey, - oldConfig.contains(finalKey) ? oldConfig.get(finalKey) : value); - } - }); + if (getConfigFormat() instanceof TomlConfigFormat t) { + t.updateConfigValues(oldConfig, newConfig, outputConfig, subKey); + } } /** @@ -141,7 +76,7 @@ public class ModuleConfig { * @return - The FILE object containing the config file */ public File getConfigPath() { - return configPath; + return super.getConfigPath(); } /** @@ -150,12 +85,13 @@ public class ModuleConfig { * @return - Returns the Sync ID in format modid:config_name */ public String getNetworkID() { - return networkID; + return super.getNetworkID(); } /** * Fired whenever changes to the config are detected */ + @Override public void configReloaded() { } @@ -166,7 +102,7 @@ public class ModuleConfig { * @return */ public String getConfigName() { - return configName; + return super.getConfigName(); } /** @@ -175,10 +111,10 @@ public class ModuleConfig { * @return */ public String getModId() { - return modId; + return super.getModId(); } public boolean isSaveCalled() { - return isSaveCalled; + return super.isWasSaveCalled(); } } diff --git a/1.20/Common/src/main/java/com/hypherionmc/craterlib/core/config/formats/AbstractConfigFormat.java b/1.20/Common/src/main/java/com/hypherionmc/craterlib/core/config/formats/AbstractConfigFormat.java new file mode 100644 index 0000000..20511ba --- /dev/null +++ b/1.20/Common/src/main/java/com/hypherionmc/craterlib/core/config/formats/AbstractConfigFormat.java @@ -0,0 +1,32 @@ +package com.hypherionmc.craterlib.core.config.formats; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import me.hypherionmc.moonconfig.core.Config; + +import java.io.File; + +@RequiredArgsConstructor +@Getter +public abstract class AbstractConfigFormat { + + private final File configPath; + private final Runnable onSave; + + public void register(S conf) { + if (!configPath.exists() || configPath.length() < 2) { + saveConfig(conf); + } else { + migrateConfig(conf); + } + } + + public boolean wasConfigChanged(Config old, Config newConfig) { + return true; + } + + public abstract void saveConfig(S config); + public abstract S readConfig(S config); + public abstract void migrateConfig(S config); + +} diff --git a/1.20/Common/src/main/java/com/hypherionmc/craterlib/core/config/formats/JsonConfigFormat.java b/1.20/Common/src/main/java/com/hypherionmc/craterlib/core/config/formats/JsonConfigFormat.java new file mode 100644 index 0000000..0db35fa --- /dev/null +++ b/1.20/Common/src/main/java/com/hypherionmc/craterlib/core/config/formats/JsonConfigFormat.java @@ -0,0 +1,67 @@ +package com.hypherionmc.craterlib.core.config.formats; + +import me.hypherionmc.moonconfig.core.Config; +import me.hypherionmc.moonconfig.core.conversion.ObjectConverter; +import me.hypherionmc.moonconfig.core.file.FileConfig; + +import java.io.File; + +public class JsonConfigFormat extends AbstractConfigFormat { + + public JsonConfigFormat(File configPath, Runnable afterSave) { + super(configPath, afterSave); + } + + @Override + public void saveConfig(S conf) { + ObjectConverter converter = new ObjectConverter(); + FileConfig config = FileConfig.builder(getConfigPath()).sync().build(); + + converter.toConfig(conf, config); + config.save(); + getOnSave().run(); + } + + @Override + public S readConfig(S conf) { + /* Set up the Serializer and Config Object */ + ObjectConverter converter = new ObjectConverter(); + FileConfig config = FileConfig.builder(getConfigPath()).build(); + config.load(); + + /* Load the config and return the loaded config */ + converter.toObject(config, conf); + return conf; + } + + @Override + public void migrateConfig(S conf) { + /* Set up the Serializer and Config Objects */ + FileConfig config = FileConfig.builder(getConfigPath()).build(); + FileConfig newConfig = FileConfig.builder(getConfigPath()).sync().build(); + config.load(); + + /* Upgrade the config */ + if (wasConfigChanged(config, newConfig)) { + new ObjectConverter().toConfig(conf, newConfig); + updateConfigValues(config, newConfig, newConfig, ""); + newConfig.save(); + } + + config.close(); + newConfig.close(); + } + + public void updateConfigValues(Config oldConfig, Config newConfig, Config outputConfig, String subKey) { + /* Loop over the config keys and check what has changed */ + newConfig.valueMap().forEach((key, value) -> { + String finalKey = subKey + (subKey.isEmpty() ? "" : ".") + key; + if (value instanceof Config commentedConfig) { + updateConfigValues(oldConfig, commentedConfig, outputConfig, finalKey); + } else { + outputConfig.set(finalKey, + oldConfig.contains(finalKey) ? oldConfig.get(finalKey) : value); + } + }); + } +} diff --git a/1.20/Common/src/main/java/com/hypherionmc/craterlib/core/config/formats/TomlConfigFormat.java b/1.20/Common/src/main/java/com/hypherionmc/craterlib/core/config/formats/TomlConfigFormat.java new file mode 100644 index 0000000..e3f9763 --- /dev/null +++ b/1.20/Common/src/main/java/com/hypherionmc/craterlib/core/config/formats/TomlConfigFormat.java @@ -0,0 +1,67 @@ +package com.hypherionmc.craterlib.core.config.formats; + +import me.hypherionmc.moonconfig.core.CommentedConfig; +import me.hypherionmc.moonconfig.core.conversion.ObjectConverter; +import me.hypherionmc.moonconfig.core.file.CommentedFileConfig; + +import java.io.File; + +public class TomlConfigFormat extends AbstractConfigFormat { + + public TomlConfigFormat(File configPath, Runnable onSave) { + super(configPath, onSave); + } + + @Override + public void saveConfig(S conf) { + ObjectConverter converter = new ObjectConverter(); + CommentedFileConfig config = CommentedFileConfig.builder(getConfigPath()).sync().build(); + + converter.toConfig(conf, config); + config.save(); + getOnSave().run(); + } + + @Override + public S readConfig(S conf) { + /* Set up the Serializer and Config Object */ + ObjectConverter converter = new ObjectConverter(); + CommentedFileConfig config = CommentedFileConfig.builder(getConfigPath()).build(); + config.load(); + + /* Load the config and return the loaded config */ + converter.toObject(config, conf); + return conf; + } + + @Override + public void migrateConfig(S conf) { + /* Set up the Serializer and Config Objects */ + CommentedFileConfig config = CommentedFileConfig.builder(getConfigPath()).build(); + CommentedFileConfig newConfig = CommentedFileConfig.builder(getConfigPath()).sync().build(); + config.load(); + + /* Upgrade the config */ + if (wasConfigChanged(config, newConfig)) { + new ObjectConverter().toConfig(conf, newConfig); + updateConfigValues(config, newConfig, newConfig, ""); + newConfig.save(); + } + + config.close(); + newConfig.close(); + } + + public void updateConfigValues(CommentedConfig oldConfig, CommentedConfig newConfig, CommentedConfig outputConfig, String subKey) { + /* Loop over the config keys and check what has changed */ + newConfig.valueMap().forEach((key, value) -> { + String finalKey = subKey + (subKey.isEmpty() ? "" : ".") + key; + if (value instanceof CommentedConfig commentedConfig) { + updateConfigValues(oldConfig, commentedConfig, outputConfig, finalKey); + } else { + outputConfig.set(finalKey, + oldConfig.contains(finalKey) ? oldConfig.get(finalKey) : value); + } + }); + } +} diff --git a/1.20/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/ServerStatusMixin.java b/1.20/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/ServerStatusMixin.java new file mode 100644 index 0000000..53985e7 --- /dev/null +++ b/1.20/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/ServerStatusMixin.java @@ -0,0 +1,27 @@ +package com.hypherionmc.craterlib.mixin.events; + +import com.hypherionmc.craterlib.api.events.server.ServerStatusEvent; +import com.hypherionmc.craterlib.core.event.CraterEventBus; +import com.hypherionmc.craterlib.nojang.network.protocol.status.WrappedServerStatus; +import net.minecraft.network.protocol.status.ServerStatus; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import java.util.Optional; + +@Mixin(ServerStatus.class) +public class ServerStatusMixin { + + @Inject(method = "favicon", at = @At("RETURN"), cancellable = true) + private void injectIconEvent(CallbackInfoReturnable> cir) { + ServerStatusEvent.FaviconRequestEvent event = new ServerStatusEvent.FaviconRequestEvent(cir.getReturnValue().isEmpty() ? Optional.empty() : Optional.of(new WrappedServerStatus.WrappedFavicon(cir.getReturnValue().get()))); + CraterEventBus.INSTANCE.postEvent(event); + + if (event.getNewIcon().isPresent()) { + cir.setReturnValue(Optional.of(event.getNewIcon().get().toMojang())); + } + } + +} diff --git a/1.20/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/BridgedCommandSourceStack.java b/1.20/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/BridgedCommandSourceStack.java index 5a15402..5529824 100644 --- a/1.20/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/BridgedCommandSourceStack.java +++ b/1.20/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/BridgedCommandSourceStack.java @@ -16,6 +16,10 @@ public class BridgedCommandSourceStack { internal.sendSuccess(() -> ChatUtils.adventureToMojang(supplier.get()), bl); } + public void sendFailure(Component text) { + internal.sendFailure(ChatUtils.adventureToMojang(text)); + } + public CommandSourceStack toMojang() { return internal; } diff --git a/1.20/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/CommandsRegistry.java b/1.20/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/CommandsRegistry.java deleted file mode 100644 index 37ad15b..0000000 --- a/1.20/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/CommandsRegistry.java +++ /dev/null @@ -1,85 +0,0 @@ -package com.hypherionmc.craterlib.nojang.commands; - -import com.hypherionmc.craterlib.api.commands.CraterCommand; -import com.hypherionmc.craterlib.nojang.authlib.BridgedGameProfile; -import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer; -import com.hypherionmc.craterlib.utils.TriConsumer; -import com.mojang.authlib.GameProfile; -import com.mojang.brigadier.CommandDispatcher; -import com.mojang.brigadier.builder.LiteralArgumentBuilder; -import lombok.AccessLevel; -import lombok.NoArgsConstructor; -import net.minecraft.commands.CommandSourceStack; -import net.minecraft.commands.Commands; -import net.minecraft.commands.arguments.GameProfileArgument; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -@NoArgsConstructor(access = AccessLevel.PRIVATE) -public class CommandsRegistry { - - public static final CommandsRegistry INSTANCE = new CommandsRegistry(); - - private final List commands = new ArrayList<>(); - - public void registerCommand(CraterCommand cmd) { - commands.add(cmd); - } - - public void registerCommands(CommandDispatcher stack) { - commands.forEach(cmd -> { - if (cmd.hasArguments()) { - CommandWithArguments.register(cmd, stack); - } else { - CommandWithoutArguments.register(cmd, stack); - } - }); - } - - static class CommandWithoutArguments { - - public static void register(CraterCommand cmd, CommandDispatcher dispatcher) { - LiteralArgumentBuilder command = Commands.literal(cmd.getCommandName()) - .requires(source -> source.hasPermission(cmd.getPermissionLevel())) - .executes(context -> { - cmd.getExecutor().accept(BridgedCommandSourceStack.of(context.getSource())); - return 1; - }); - - dispatcher.register(command); - } - - } - - @SuppressWarnings("unchecked") - static class CommandWithArguments { - - public static void register(CraterCommand cmd, CommandDispatcher dispatcher) { - LiteralArgumentBuilder command = Commands.literal(cmd.getCommandName()) - .requires(source -> source.hasPermission(cmd.getPermissionLevel())); - - cmd.getArguments().forEach((key, pair) -> command.then(Commands.argument(key, pair.getLeft()).executes(context -> { - - // This is FUCKING UGLY.... Need to improve this in the future - if (pair.getLeft() instanceof GameProfileArgument) { - Collection profiles = GameProfileArgument.getGameProfiles(context, key); - List bridgedGameProfiles = new ArrayList<>(); - - profiles.forEach(p -> bridgedGameProfiles.add(BridgedGameProfile.of(p))); - - ((TriConsumer, BridgedCommandSourceStack>) pair.getRight()) - .accept(BridgedPlayer.of(context.getSource().getPlayer()), bridgedGameProfiles, BridgedCommandSourceStack.of(context.getSource())); - return 1; - } - - return 1; - }))); - - dispatcher.register(command); - } - - } - -} diff --git a/1.20/Common/src/main/java/com/hypherionmc/craterlib/nojang/network/protocol/status/WrappedServerStatus.java b/1.20/Common/src/main/java/com/hypherionmc/craterlib/nojang/network/protocol/status/WrappedServerStatus.java new file mode 100644 index 0000000..ae6f773 --- /dev/null +++ b/1.20/Common/src/main/java/com/hypherionmc/craterlib/nojang/network/protocol/status/WrappedServerStatus.java @@ -0,0 +1,31 @@ +package com.hypherionmc.craterlib.nojang.network.protocol.status; + +import net.minecraft.network.protocol.status.ServerStatus; +import org.jetbrains.annotations.ApiStatus; + +public final class WrappedServerStatus { + + public static final class WrappedFavicon { + + private final ServerStatus.Favicon internal; + + public WrappedFavicon(byte[] iconBytes) { + internal = new ServerStatus.Favicon(iconBytes); + } + + @ApiStatus.Internal + public WrappedFavicon(ServerStatus.Favicon internal) { + this.internal = internal; + } + + public byte[] iconBytes() { + return internal.iconBytes(); + } + + public ServerStatus.Favicon toMojang() { + return internal; + } + + } + +} diff --git a/1.20/Common/src/main/java/com/hypherionmc/craterlib/nojang/world/entity/player/BridgedPlayer.java b/1.20/Common/src/main/java/com/hypherionmc/craterlib/nojang/world/entity/player/BridgedPlayer.java index 8aa6d49..2241836 100644 --- a/1.20/Common/src/main/java/com/hypherionmc/craterlib/nojang/world/entity/player/BridgedPlayer.java +++ b/1.20/Common/src/main/java/com/hypherionmc/craterlib/nojang/world/entity/player/BridgedPlayer.java @@ -57,6 +57,11 @@ public class BridgedPlayer { return null; } + public void disconnect(Component message) { + if (isServerPlayer()) + toMojangServerPlayer().connection.disconnect(ChatUtils.adventureToMojang(message)); + } + public ServerPlayer toMojangServerPlayer() { return (ServerPlayer) internal; } diff --git a/1.20/Common/src/main/java/com/hypherionmc/craterlib/utils/ChatUtils.java b/1.20/Common/src/main/java/com/hypherionmc/craterlib/utils/ChatUtils.java index af9736d..5759fde 100644 --- a/1.20/Common/src/main/java/com/hypherionmc/craterlib/utils/ChatUtils.java +++ b/1.20/Common/src/main/java/com/hypherionmc/craterlib/utils/ChatUtils.java @@ -92,4 +92,11 @@ public class ChatUtils { return mojangToAdventure(Component.translatable(Util.makeDescriptionId("biome", identifier.toMojang()))); } + public static net.kyori.adventure.text.Component format(String value) { + return net.kyori.adventure.text.Component.translatable(convertFormattingCodes(value)); + } + + private static String convertFormattingCodes(String input) { + return input.replaceAll("§([0-9a-fklmnor])", "\u00A7$1"); + } } diff --git a/1.20/Common/src/main/resources/craterlib.mixins.json b/1.20/Common/src/main/resources/craterlib.mixins.json index 1a739db..c910ed2 100644 --- a/1.20/Common/src/main/resources/craterlib.mixins.json +++ b/1.20/Common/src/main/resources/craterlib.mixins.json @@ -16,7 +16,8 @@ "events.CommandMixin", "events.PlayerAdvancementsMixin", "events.PlayerListMixin", - "events.ServerPlayerMixin" + "events.ServerPlayerMixin", + "events.ServerStatusMixin" ], "injectors": { "defaultRequire": 1 diff --git a/1.20/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibInitializer.java b/1.20/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibInitializer.java index c66c210..5e93a3a 100644 --- a/1.20/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibInitializer.java +++ b/1.20/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibInitializer.java @@ -9,7 +9,6 @@ import com.hypherionmc.craterlib.core.networking.CraterPacketNetwork; import com.hypherionmc.craterlib.core.networking.data.PacketSide; import com.hypherionmc.craterlib.core.platform.ModloaderEnvironment; import com.hypherionmc.craterlib.network.CraterFabricNetworkHandler; -import com.hypherionmc.craterlib.nojang.commands.CommandsRegistry; import com.hypherionmc.craterlib.nojang.server.BridgedMinecraftServer; import net.fabricmc.api.ModInitializer; import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback; @@ -21,8 +20,7 @@ public class CraterLibInitializer implements ModInitializer { public void onInitialize() { new CraterPacketNetwork(new CraterFabricNetworkHandler(PacketSide.SERVER)); CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> { - CraterEventBus.INSTANCE.postEvent(new CraterRegisterCommandEvent()); - CommandsRegistry.INSTANCE.registerCommands(dispatcher); + CraterEventBus.INSTANCE.postEvent(new CraterRegisterCommandEvent(dispatcher)); }); diff --git a/1.20/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibModMenuIntegration.java b/1.20/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibModMenuIntegration.java index 6615352..5b34ff1 100644 --- a/1.20/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibModMenuIntegration.java +++ b/1.20/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibModMenuIntegration.java @@ -2,7 +2,6 @@ package com.hypherionmc.craterlib; import com.hypherionmc.craterlib.client.gui.config.CraterConfigScreen; import com.hypherionmc.craterlib.core.config.ConfigController; -import com.hypherionmc.craterlib.core.config.ModuleConfig; import com.hypherionmc.craterlib.core.config.annotations.NoConfigScreen; import com.terraformersmc.modmenu.api.ConfigScreenFactory; import com.terraformersmc.modmenu.api.ModMenuApi; @@ -19,9 +18,9 @@ public class CraterLibModMenuIntegration implements ModMenuApi { public Map> getProvidedConfigScreenFactories() { Map> configScreens = new HashMap<>(); - ConfigController.getMonitoredConfigs().forEach((conf, watcher) -> { + ConfigController.getWatchedConfigs().forEach((conf, watcher) -> { if (!conf.getClass().isAnnotationPresent(NoConfigScreen.class)) { - configScreens.put(((ModuleConfig) conf).getModId(), screen -> new CraterConfigScreen((ModuleConfig) conf, screen)); + configScreens.put(watcher.getLeft().getModId(), screen -> new CraterConfigScreen(watcher.getLeft(), screen)); } }); diff --git a/1.20/Fabric/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java b/1.20/Fabric/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java new file mode 100644 index 0000000..f3dc866 --- /dev/null +++ b/1.20/Fabric/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java @@ -0,0 +1,52 @@ +package com.hypherionmc.craterlib.mixin; + +import com.hypherionmc.craterlib.api.events.server.ServerStatusEvent; +import com.hypherionmc.craterlib.core.event.CraterEventBus; +import com.hypherionmc.craterlib.utils.ChatUtils; +import net.minecraft.network.Connection; +import net.minecraft.network.protocol.status.ClientboundStatusResponsePacket; +import net.minecraft.network.protocol.status.ServerStatus; +import net.minecraft.network.protocol.status.ServerboundStatusRequestPacket; +import net.minecraft.server.network.ServerStatusPacketListenerImpl; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(ServerStatusPacketListenerImpl.class) +public class ServerStatusPacketListenerMixin { + + @Shadow + @Final + private ServerStatus status; + + @Shadow @Final private Connection connection; + + @Inject(method = "handleStatusRequest", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/network/Connection;send(Lnet/minecraft/network/protocol/Packet;)V", + shift = At.Shift.BEFORE), + cancellable = true + ) + private void injectHandleStatusRequest(ServerboundStatusRequestPacket arg, CallbackInfo ci) { + ServerStatusEvent.StatusRequestEvent event = new ServerStatusEvent.StatusRequestEvent(ChatUtils.mojangToAdventure(status.description())); + CraterEventBus.INSTANCE.postEvent(event); + + if (event.getNewStatus() != null) { + ci.cancel(); + this.connection.send(new ClientboundStatusResponsePacket( + new ServerStatus(ChatUtils.adventureToMojang( + event.getNewStatus()), + status.players(), + status.version(), + status.favicon(), + status.enforcesSecureChat() + ) + )); + } + } + +} \ No newline at end of file diff --git a/1.20/Fabric/src/main/resources/craterlib.fabric.mixins.json b/1.20/Fabric/src/main/resources/craterlib.fabric.mixins.json index 7c59043..a6d0bc1 100644 --- a/1.20/Fabric/src/main/resources/craterlib.fabric.mixins.json +++ b/1.20/Fabric/src/main/resources/craterlib.fabric.mixins.json @@ -9,7 +9,8 @@ "TutorialMixin" ], "server": [ - "ServerGamePacketListenerImplMixin" + "ServerGamePacketListenerImplMixin", + "ServerStatusPacketListenerMixin" ], "injectors": { "defaultRequire": 1 diff --git a/1.20/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeServerEvents.java b/1.20/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeServerEvents.java index f354ddc..37ddf87 100644 --- a/1.20/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeServerEvents.java +++ b/1.20/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeServerEvents.java @@ -3,7 +3,6 @@ package com.hypherionmc.craterlib.common; import com.hypherionmc.craterlib.api.events.server.CraterRegisterCommandEvent; import com.hypherionmc.craterlib.api.events.server.CraterServerLifecycleEvent; import com.hypherionmc.craterlib.core.event.CraterEventBus; -import com.hypherionmc.craterlib.nojang.commands.CommandsRegistry; import com.hypherionmc.craterlib.nojang.server.BridgedMinecraftServer; import net.minecraftforge.event.RegisterCommandsEvent; import net.minecraftforge.event.server.ServerStartedEvent; @@ -36,8 +35,7 @@ public class ForgeServerEvents { @SubscribeEvent public void onCommandRegister(RegisterCommandsEvent event) { - CraterEventBus.INSTANCE.postEvent(new CraterRegisterCommandEvent()); - CommandsRegistry.INSTANCE.registerCommands(event.getDispatcher()); + CraterEventBus.INSTANCE.postEvent(new CraterRegisterCommandEvent(event.getDispatcher())); } } diff --git a/1.20/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java b/1.20/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java index 927bd23..d77853c 100644 --- a/1.20/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java +++ b/1.20/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java @@ -1,8 +1,8 @@ package com.hypherionmc.craterlib.mixin; import com.hypherionmc.craterlib.client.gui.config.CraterConfigScreen; +import com.hypherionmc.craterlib.core.config.AbstractConfig; import com.hypherionmc.craterlib.core.config.ConfigController; -import com.hypherionmc.craterlib.core.config.ModuleConfig; import com.hypherionmc.craterlib.core.config.annotations.NoConfigScreen; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.screens.Screen; @@ -28,9 +28,9 @@ public class ConfigScreenHandlerMixin { */ @Inject(at = @At("RETURN"), method = "getScreenFactoryFor", cancellable = true, remap = false) private static void injectConfigScreen(IModInfo selectedMod, CallbackInfoReturnable>> cir) { - ConfigController.getMonitoredConfigs().forEach((conf, watcher) -> { + ConfigController.getWatchedConfigs().forEach((conf, watcher) -> { if (!conf.getClass().isAnnotationPresent(NoConfigScreen.class)) { - ModuleConfig config = (ModuleConfig) conf; + AbstractConfig config = watcher.getLeft(); if (config.getModId().equals(selectedMod.getModId())) { cir.setReturnValue( Optional.of((minecraft, screen) -> new CraterConfigScreen(config, screen)) diff --git a/1.20/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java b/1.20/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java new file mode 100644 index 0000000..969b05d --- /dev/null +++ b/1.20/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java @@ -0,0 +1,53 @@ +package com.hypherionmc.craterlib.mixin; + +import com.hypherionmc.craterlib.api.events.server.ServerStatusEvent; +import com.hypherionmc.craterlib.core.event.CraterEventBus; +import com.hypherionmc.craterlib.utils.ChatUtils; +import net.minecraft.network.Connection; +import net.minecraft.network.protocol.status.ClientboundStatusResponsePacket; +import net.minecraft.network.protocol.status.ServerStatus; +import net.minecraft.network.protocol.status.ServerboundStatusRequestPacket; +import net.minecraft.server.network.ServerStatusPacketListenerImpl; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(ServerStatusPacketListenerImpl.class) +public class ServerStatusPacketListenerMixin { + + @Shadow + @Final + private ServerStatus status; + + @Shadow @Final private Connection connection; + + @Inject(method = "handleStatusRequest", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/network/Connection;send(Lnet/minecraft/network/protocol/Packet;)V", + shift = At.Shift.BEFORE), + cancellable = true + ) + private void injectHandleStatusRequest(ServerboundStatusRequestPacket arg, CallbackInfo ci) { + ServerStatusEvent.StatusRequestEvent event = new ServerStatusEvent.StatusRequestEvent(ChatUtils.mojangToAdventure(status.description())); + CraterEventBus.INSTANCE.postEvent(event); + + if (event.getNewStatus() != null) { + ci.cancel(); + this.connection.send(new ClientboundStatusResponsePacket( + new ServerStatus(ChatUtils.adventureToMojang( + event.getNewStatus()), + status.players(), + status.version(), + status.favicon(), + status.enforcesSecureChat(), + status.forgeData() + ) + )); + } + } + +} diff --git a/1.20/Forge/src/main/resources/craterlib.forge.mixins.json b/1.20/Forge/src/main/resources/craterlib.forge.mixins.json index aa072d1..892f6d7 100644 --- a/1.20/Forge/src/main/resources/craterlib.forge.mixins.json +++ b/1.20/Forge/src/main/resources/craterlib.forge.mixins.json @@ -9,7 +9,8 @@ "ConfigScreenHandlerMixin" ], "server": [ - "ServerGamePacketListenerImplMixin" + "ServerGamePacketListenerImplMixin", + "ServerStatusPacketListenerMixin" ], "injectors": { "defaultRequire": 1 diff --git a/1.20/NeoForge/src/main/resources/craterlib_logo.png b/1.20/NeoForge/src/main/resources/craterlib_logo.png deleted file mode 100644 index ce0159c..0000000 Binary files a/1.20/NeoForge/src/main/resources/craterlib_logo.png and /dev/null differ diff --git a/1.20/README.md b/1.20/README.md index 49c0699..4b18d17 100644 --- a/1.20/README.md +++ b/1.20/README.md @@ -15,7 +15,7 @@ A Library mod and modding api for easier multi-version minecraft and mod loader | < 1.18.2 | ❌ | | 1.18.2-1.20.2 | ✳️ | | 1.20.4 | ✳️ | -| 1.21 | 🚧 | +| 1.21.x | ✳️ | - ❌ - Not Supported; no bug fixes or new features. - 🚧 - Work in Progress; not ready for release. diff --git a/1.20/build.gradle b/1.20/build.gradle index 5d2a5e0..24084aa 100644 --- a/1.20/build.gradle +++ b/1.20/build.gradle @@ -56,11 +56,13 @@ subprojects { // All Projects shade "me.hypherionmc.moon-config:core:${moon_config}" shade "me.hypherionmc.moon-config:toml:${moon_config}" + shade "me.hypherionmc.moon-config:json:${moon_config}" shade "com.hypherionmc:rpcsdk:${rpc_sdk}" shade "me.hypherionmc.sdlink:mcdiscordformatter-1.19.1:${discord_formatter}" shade "net.kyori:adventure-api:${adventure}" shade "net.kyori:adventure-text-serializer-gson:${adventure}" + compileOnly 'net.luckperms:api:5.4' compileOnly("org.projectlombok:lombok:${lombok}") annotationProcessor("org.projectlombok:lombok:${lombok}") } diff --git a/1.20/gradle.properties b/1.20/gradle.properties index 79b3647..8221d09 100644 --- a/1.20/gradle.properties +++ b/1.20/gradle.properties @@ -1,7 +1,7 @@ #Project version_major=2 -version_minor=0 -version_patch=3 +version_minor=1 +version_patch=0 version_build=0 #Mod diff --git a/1.21/Common/src/main/java/com/hypherionmc/craterlib/api/commands/CraterCommand.java b/1.21/Common/src/main/java/com/hypherionmc/craterlib/api/commands/CraterCommand.java index cc4969e..35f29f0 100644 --- a/1.21/Common/src/main/java/com/hypherionmc/craterlib/api/commands/CraterCommand.java +++ b/1.21/Common/src/main/java/com/hypherionmc/craterlib/api/commands/CraterCommand.java @@ -1,53 +1,155 @@ package com.hypherionmc.craterlib.api.commands; +import com.hypherionmc.craterlib.compat.LuckPermsCompat; +import com.hypherionmc.craterlib.core.platform.ModloaderEnvironment; import com.hypherionmc.craterlib.nojang.authlib.BridgedGameProfile; import com.hypherionmc.craterlib.nojang.commands.BridgedCommandSourceStack; import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer; import com.hypherionmc.craterlib.utils.TriConsumer; -import com.mojang.brigadier.arguments.ArgumentType; -import lombok.Getter; +import com.mojang.brigadier.CommandDispatcher; +import com.mojang.brigadier.arguments.BoolArgumentType; +import com.mojang.brigadier.arguments.IntegerArgumentType; +import com.mojang.brigadier.arguments.StringArgumentType; +import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import net.minecraft.commands.CommandSourceStack; +import net.minecraft.commands.Commands; import net.minecraft.commands.arguments.GameProfileArgument; -import org.apache.commons.lang3.tuple.Pair; +import net.minecraft.world.entity.player.Player; +import org.jetbrains.annotations.ApiStatus; -import java.util.HashMap; -import java.util.LinkedHashMap; import java.util.List; import java.util.function.Consumer; -@Getter public class CraterCommand { - private final HashMap, TriConsumer>> arguments = new LinkedHashMap<>(); - private Consumer executor; + private final LiteralArgumentBuilder mojangCommand; + private int permLevel = 4; + private String luckPermNode = ""; - private final String commandName; - private int permissionLevel = 4; - - CraterCommand(String commandName) { - this.commandName = commandName; + CraterCommand(LiteralArgumentBuilder cmd) { + this.mojangCommand = cmd; } public static CraterCommand literal(String commandName) { - return new CraterCommand(commandName); + return new CraterCommand(Commands.literal(commandName)); } public CraterCommand requiresPermission(int perm) { - this.permissionLevel = perm; + this.permLevel = perm; + this.mojangCommand.requires(this::checkPermission); return this; } - public CraterCommand withGameProfileArgument(String key, TriConsumer, BridgedCommandSourceStack> executor) { - arguments.put(key, Pair.of(GameProfileArgument.gameProfile(), executor)); + public CraterCommand withNode(String key) { + this.luckPermNode = key; return this; } + public CraterCommand then(CraterCommand child) { + this.mojangCommand.then(child.mojangCommand); + return this; + } + + public CraterCommand withGameProfilesArgument(String key, CommandExecutorWithArgs> executor) { + this.mojangCommand.then(Commands.argument(key, GameProfileArgument.gameProfile()) + .executes(context -> executor.run( + BridgedPlayer.of(context.getSource().getPlayer()), + GameProfileArgument.getGameProfiles(context, key).stream().map(BridgedGameProfile::of).toList(), + BridgedCommandSourceStack.of(context.getSource())) + )); + return this; + } + + public CraterCommand withBoolArgument(String key, CommandExecutorWithArgs executor) { + this.mojangCommand.then(Commands.argument(key, BoolArgumentType.bool()) + .executes(context -> executor.run( + BridgedPlayer.of(context.getSource().getPlayer()), + BoolArgumentType.getBool(context, key), + BridgedCommandSourceStack.of(context.getSource()) + ))); + return this; + } + + public CraterCommand withWordArgument(String key, CommandExecutorWithArgs executor) { + this.mojangCommand.then(Commands.argument(key, StringArgumentType.word()) + .executes(context -> executor.run( + BridgedPlayer.of(context.getSource().getPlayer()), + StringArgumentType.getString(context, key), + BridgedCommandSourceStack.of(context.getSource()) + ))); + return this; + } + + public CraterCommand withStringArgument(String key, CommandExecutorWithArgs executor) { + this.mojangCommand.then(Commands.argument(key, StringArgumentType.string()) + .executes(context -> executor.run( + BridgedPlayer.of(context.getSource().getPlayer()), + StringArgumentType.getString(context, key), + BridgedCommandSourceStack.of(context.getSource()) + ))); + return this; + } + + public CraterCommand withPhraseArgument(String key, CommandExecutorWithArgs executor) { + this.mojangCommand.then(Commands.argument(key, StringArgumentType.greedyString()) + .executes(context -> executor.run( + BridgedPlayer.of(context.getSource().getPlayer()), + StringArgumentType.getString(context, key), + BridgedCommandSourceStack.of(context.getSource()) + ))); + return this; + } + + public CraterCommand withIntegerArgument(String key, CommandExecutorWithArgs executor) { + this.mojangCommand.then(Commands.argument(key, IntegerArgumentType.integer()) + .executes(context -> executor.run( + BridgedPlayer.of(context.getSource().getPlayer()), + IntegerArgumentType.getInteger(context, key), + BridgedCommandSourceStack.of(context.getSource()) + ))); + return this; + } + + public CraterCommand execute(SingleCommandExecutor executor) { + this.mojangCommand.executes(context -> executor.run(BridgedCommandSourceStack.of(context.getSource()))); + return this; + } + + @Deprecated(forRemoval = true) public CraterCommand executes(Consumer ctx) { - executor = ctx; - return this; + return this.execute(stack -> { + ctx.accept(stack); + return 1; + }); } - public boolean hasArguments() { - return !arguments.isEmpty(); + @Deprecated(forRemoval = true) + public CraterCommand withGameProfileArgument(String key, TriConsumer, BridgedCommandSourceStack> executor) { + return this.withGameProfilesArgument(key, (player, argument, stack) -> { + executor.accept(player, argument, stack); + return 1; + }); } + @ApiStatus.Internal + public void register(CommandDispatcher stack) { + stack.register(this.mojangCommand); + } + + private boolean checkPermission(CommandSourceStack stack) { + if (!ModloaderEnvironment.INSTANCE.isModLoaded("luckperms") || !stack.isPlayer() || luckPermNode.isEmpty()) + return stack.hasPermission(this.permLevel); + + return LuckPermsCompat.INSTANCE.hasPermission(stack.getPlayer(), this.luckPermNode) || stack.hasPermission(this.permLevel); + } + + @FunctionalInterface + public interface CommandExecutorWithArgs { + int run(BridgedPlayer player, S argument, BridgedCommandSourceStack stack); + } + + @FunctionalInterface + public interface SingleCommandExecutor { + int run(S stack); + } } diff --git a/1.21/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterPlayerEvent.java b/1.21/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterPlayerEvent.java index 94be675..9e7d7a2 100644 --- a/1.21/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterPlayerEvent.java +++ b/1.21/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterPlayerEvent.java @@ -4,7 +4,6 @@ import com.hypherionmc.craterlib.core.event.CraterEvent; import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer; import lombok.Getter; import lombok.RequiredArgsConstructor; -import lombok.Setter; @RequiredArgsConstructor @Getter diff --git a/1.21/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterRegisterCommandEvent.java b/1.21/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterRegisterCommandEvent.java index 269065a..5adac03 100644 --- a/1.21/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterRegisterCommandEvent.java +++ b/1.21/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/CraterRegisterCommandEvent.java @@ -2,14 +2,17 @@ package com.hypherionmc.craterlib.api.events.server; import com.hypherionmc.craterlib.api.commands.CraterCommand; import com.hypherionmc.craterlib.core.event.CraterEvent; -import com.hypherionmc.craterlib.nojang.commands.CommandsRegistry; -import lombok.NoArgsConstructor; +import com.mojang.brigadier.CommandDispatcher; +import lombok.AllArgsConstructor; +import net.minecraft.commands.CommandSourceStack; -@NoArgsConstructor +@AllArgsConstructor public class CraterRegisterCommandEvent extends CraterEvent { + private final CommandDispatcher stack; + public void registerCommand(CraterCommand cmd) { - CommandsRegistry.INSTANCE.registerCommand(cmd); + cmd.register(stack); } } diff --git a/1.21/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/ServerStatusEvent.java b/1.21/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/ServerStatusEvent.java new file mode 100644 index 0000000..b58dafa --- /dev/null +++ b/1.21/Common/src/main/java/com/hypherionmc/craterlib/api/events/server/ServerStatusEvent.java @@ -0,0 +1,35 @@ +package com.hypherionmc.craterlib.api.events.server; + +import com.hypherionmc.craterlib.core.event.CraterEvent; +import com.hypherionmc.craterlib.nojang.network.protocol.status.WrappedServerStatus; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.Setter; +import net.kyori.adventure.text.Component; +import org.jetbrains.annotations.Nullable; + +import java.util.Optional; + +public class ServerStatusEvent { + + @RequiredArgsConstructor + @Getter + @Setter + public static class StatusRequestEvent extends CraterEvent { + + private final Component status; + @Nullable + private Component newStatus = null; + + } + + @RequiredArgsConstructor + @Getter + @Setter + public static class FaviconRequestEvent extends CraterEvent { + + private final Optional favicon; + private Optional newIcon = Optional.empty(); + + } +} diff --git a/1.21/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/CraterConfigScreen.java b/1.21/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/CraterConfigScreen.java index c9e70ca..4072ea9 100644 --- a/1.21/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/CraterConfigScreen.java +++ b/1.21/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/CraterConfigScreen.java @@ -2,7 +2,7 @@ package com.hypherionmc.craterlib.client.gui.config; import com.hypherionmc.craterlib.CraterConstants; import com.hypherionmc.craterlib.client.gui.config.widgets.*; -import com.hypherionmc.craterlib.core.config.ModuleConfig; +import com.hypherionmc.craterlib.core.config.AbstractConfig; import com.hypherionmc.craterlib.core.config.annotations.HideFromScreen; import com.hypherionmc.craterlib.core.config.annotations.SubConfig; import com.hypherionmc.craterlib.core.config.annotations.Tooltip; @@ -44,11 +44,11 @@ public class CraterConfigScreen extends Screen { private static final int BOTTOM = 24; private final Screen parent; private final List> options = new ArrayList<>(); - private final ModuleConfig config; + private final AbstractConfig config; public double scrollerAmount; private boolean dragging; - public CraterConfigScreen(ModuleConfig config, Screen parent, Object subConfig) { + public CraterConfigScreen(AbstractConfig config, Screen parent, Object subConfig) { super(Component.translatable("cl." + config.getClass().getSimpleName().toLowerCase() + ".title")); this.parent = parent; this.config = config; @@ -59,7 +59,7 @@ public class CraterConfigScreen extends Screen { } } - public CraterConfigScreen(ModuleConfig config, Screen parent) { + public CraterConfigScreen(AbstractConfig config, Screen parent) { this(config, parent, null); } diff --git a/1.21/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/SubConfigWidget.java b/1.21/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/SubConfigWidget.java index 9426ccf..056f32c 100644 --- a/1.21/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/SubConfigWidget.java +++ b/1.21/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/SubConfigWidget.java @@ -1,7 +1,7 @@ package com.hypherionmc.craterlib.client.gui.config.widgets; import com.hypherionmc.craterlib.client.gui.config.CraterConfigScreen; -import com.hypherionmc.craterlib.core.config.ModuleConfig; +import com.hypherionmc.craterlib.core.config.AbstractConfig; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Font; import net.minecraft.client.gui.GuiGraphics; @@ -15,10 +15,10 @@ import net.minecraft.network.chat.Component; public class SubConfigWidget extends AbstractConfigWidget { private final Object subConfig; - private final ModuleConfig config; + private final AbstractConfig config; private final Screen screen; - public SubConfigWidget(ModuleConfig config, Screen screen, Object subConfig) { + public SubConfigWidget(AbstractConfig config, Screen screen, Object subConfig) { this.config = config; this.subConfig = subConfig; this.screen = screen; diff --git a/1.21/Common/src/main/java/com/hypherionmc/craterlib/compat/LuckPermsCompat.java b/1.21/Common/src/main/java/com/hypherionmc/craterlib/compat/LuckPermsCompat.java new file mode 100644 index 0000000..a77e1f4 --- /dev/null +++ b/1.21/Common/src/main/java/com/hypherionmc/craterlib/compat/LuckPermsCompat.java @@ -0,0 +1,20 @@ +package com.hypherionmc.craterlib.compat; + +import net.luckperms.api.LuckPerms; +import net.luckperms.api.LuckPermsProvider; +import net.luckperms.api.model.user.User; +import net.minecraft.server.level.ServerPlayer; + +public class LuckPermsCompat { + + public static final LuckPermsCompat INSTANCE = new LuckPermsCompat(); + private final LuckPerms luckPerms = LuckPermsProvider.get(); + + LuckPermsCompat() {} + + public boolean hasPermission(ServerPlayer player, String perm) { + User luckPermsUser = luckPerms.getPlayerAdapter(ServerPlayer.class).getUser(player); + return luckPermsUser.getCachedData().getPermissionData().checkPermission(perm).asBoolean(); + } + +} diff --git a/1.21/Common/src/main/java/com/hypherionmc/craterlib/core/config/AbstractConfig.java b/1.21/Common/src/main/java/com/hypherionmc/craterlib/core/config/AbstractConfig.java new file mode 100644 index 0000000..eceac79 --- /dev/null +++ b/1.21/Common/src/main/java/com/hypherionmc/craterlib/core/config/AbstractConfig.java @@ -0,0 +1,71 @@ +package com.hypherionmc.craterlib.core.config; + +import com.hypherionmc.craterlib.core.config.formats.AbstractConfigFormat; +import com.hypherionmc.craterlib.core.config.formats.JsonConfigFormat; +import com.hypherionmc.craterlib.core.config.formats.TomlConfigFormat; +import lombok.Getter; +import lombok.Setter; +import me.hypherionmc.moonconfig.core.Config; +import org.jetbrains.annotations.Nullable; + +import java.io.File; + +@Getter +public abstract class AbstractConfig { + + /* Final Variables */ + private final transient File configPath; + private final transient String networkID; + private final transient String configName; + private final transient String modId; + private transient boolean wasSaveCalled = false; + + @Setter + private transient AbstractConfigFormat configFormat; + + public AbstractConfig(String modId, String configName) { + this(modId, null, configName); + } + + public AbstractConfig(String modId, @Nullable String subFolder, String configName) { + Config.setInsertionOrderPreserved(true); + + if (!configName.endsWith(".toml") && !configName.endsWith(".json")) + configName = configName + ".toml"; + + File configDir = new File("config" + (subFolder == null ? "" : File.separator + subFolder)); + configPath = new File(configDir, configName); + this.modId = modId; + this.networkID = modId + ":conf_" + configName.replace(".toml", "").replace(".json", "").replace("-", "_").toLowerCase(); + this.configName = configName.replace(".toml", "").replace(".json", ""); + configDir.mkdirs(); + + configFormat = configName.endsWith(".json") ? new JsonConfigFormat<>(configPath, this::onSave) : new TomlConfigFormat<>(configPath, this::onSave); + } + + public void registerAndSetup(S config) { + configFormat.register(config); + ConfigController.register_config(this); + this.configReloaded(); + } + + public void saveConfig(S config) { + this.wasSaveCalled = true; + configFormat.saveConfig(config); + } + + private void onSave() { + this.configReloaded(); + this.wasSaveCalled = false; + } + + public S readConfig(S config) { + return configFormat.readConfig(config); + } + + public void migrateConfig(S config) { + configFormat.migrateConfig(config); + } + + public abstract void configReloaded(); +} diff --git a/1.21/Common/src/main/java/com/hypherionmc/craterlib/core/config/ConfigController.java b/1.21/Common/src/main/java/com/hypherionmc/craterlib/core/config/ConfigController.java index 41c9471..760ca93 100644 --- a/1.21/Common/src/main/java/com/hypherionmc/craterlib/core/config/ConfigController.java +++ b/1.21/Common/src/main/java/com/hypherionmc/craterlib/core/config/ConfigController.java @@ -3,6 +3,7 @@ package com.hypherionmc.craterlib.core.config; import com.hypherionmc.craterlib.CraterConstants; import lombok.Getter; import me.hypherionmc.moonconfig.core.file.FileWatcher; +import org.apache.commons.lang3.tuple.Pair; import org.jetbrains.annotations.ApiStatus; import java.io.Serializable; @@ -18,7 +19,7 @@ public final class ConfigController implements Serializable { * Cache of registered configs */ @Getter - private static final HashMap monitoredConfigs = new HashMap<>(); + private static final HashMap> watchedConfigs = new HashMap<>(); /** * INTERNAL METHOD - Register and watch the config @@ -26,23 +27,34 @@ public final class ConfigController implements Serializable { * @param config - The config class to register and watch */ @ApiStatus.Internal + @Deprecated public static void register_config(ModuleConfig config) { - if (monitoredConfigs.containsKey(config)) { - CraterConstants.LOG.error("Failed to register " + config.getConfigPath().getName() + ". Config already registered"); + register_config((AbstractConfig) config); + } + + /** + * INTERNAL METHOD - Register and watch the config + * + * @param config - The config class to register and watch + */ + @ApiStatus.Internal + public static void register_config(AbstractConfig config) { + if (watchedConfigs.containsKey(config.getConfigPath().toString())) { + CraterConstants.LOG.error("Failed to register {}. Config already registered", config.getConfigPath().getName()); } else { FileWatcher configWatcher = new FileWatcher(); try { configWatcher.setWatch(config.getConfigPath(), () -> { - if (!config.isSaveCalled()) { - CraterConstants.LOG.info("Sending Reload Event for: " + config.getConfigPath().getName()); + if (!config.isWasSaveCalled()) { + CraterConstants.LOG.info("Sending Reload Event for: {}", config.getConfigPath().getName()); config.configReloaded(); } }); } catch (Exception e) { - CraterConstants.LOG.error("Failed to register " + config.getConfigPath().getName() + " for auto reloading. " + e.getMessage()); + CraterConstants.LOG.error("Failed to register {} for auto reloading. {}", config.getConfigPath().getName(), e.getMessage()); } - monitoredConfigs.put(config, configWatcher); - CraterConstants.LOG.info("Registered " + config.getConfigPath().getName() + " successfully!"); + watchedConfigs.put(config.getConfigPath().toString(), Pair.of(config, configWatcher)); + CraterConstants.LOG.info("Registered {} successfully!", config.getConfigPath().getName()); } } diff --git a/1.21/Common/src/main/java/com/hypherionmc/craterlib/core/config/ModuleConfig.java b/1.21/Common/src/main/java/com/hypherionmc/craterlib/core/config/ModuleConfig.java index 181efdc..e4850bf 100644 --- a/1.21/Common/src/main/java/com/hypherionmc/craterlib/core/config/ModuleConfig.java +++ b/1.21/Common/src/main/java/com/hypherionmc/craterlib/core/config/ModuleConfig.java @@ -1,9 +1,7 @@ package com.hypherionmc.craterlib.core.config; +import com.hypherionmc.craterlib.core.config.formats.TomlConfigFormat; import me.hypherionmc.moonconfig.core.CommentedConfig; -import me.hypherionmc.moonconfig.core.Config; -import me.hypherionmc.moonconfig.core.conversion.ObjectConverter; -import me.hypherionmc.moonconfig.core.file.CommentedFileConfig; import java.io.File; @@ -12,17 +10,8 @@ import java.io.File; * Base Config class containing the save, upgrading and loading logic. * All config classes must extend this class */ -public class ModuleConfig { - - /* Final Variables */ - private final transient File configPath; - private final transient String networkID; - - private final transient String configName; - - private final transient String modId; - - private transient boolean isSaveCalled = false; +@Deprecated +public class ModuleConfig extends AbstractConfig { /** * Set up the config @@ -35,20 +24,7 @@ public class ModuleConfig { } public ModuleConfig(String modId, String subFolder, String configName) { - /* Preserve the order of the config values */ - Config.setInsertionOrderPreserved(true); - - /* Configure Paths and Network SYNC ID */ - File configDir = new File("config" + (subFolder.isEmpty() ? "" : File.separator + subFolder)); - configPath = new File(configDir + File.separator + configName + ".toml"); - networkID = modId + ":conf_" + configName.replace("-", "_"); - this.modId = modId; - this.configName = configName; - - /* Check if the required directories exists, otherwise we create them */ - if (!configDir.exists()) { - configDir.mkdirs(); - } + super(modId, subFolder.isEmpty() ? null : subFolder, configName); } /** @@ -57,14 +33,7 @@ public class ModuleConfig { * @param config - The config class to use */ public void registerAndSetup(ModuleConfig config) { - if (!configPath.exists() || configPath.length() < 2) { - saveConfig(config); - } else { - migrateConfig(config); - } - /* Register the Config for Watching and events */ - ConfigController.register_config(this); - this.configReloaded(); + super.registerAndSetup(config); } /** @@ -73,16 +42,7 @@ public class ModuleConfig { * @param conf - The config class to serialize and save */ public void saveConfig(ModuleConfig conf) { - this.isSaveCalled = true; - /* Set up the Serializer and Config Object */ - ObjectConverter converter = new ObjectConverter(); - CommentedFileConfig config = CommentedFileConfig.builder(configPath).build(); - - /* Save the config and fire the reload events */ - converter.toConfig(conf, config); - config.save(); - configReloaded(); - this.isSaveCalled = false; + super.registerAndSetup(conf); } /** @@ -92,14 +52,7 @@ public class ModuleConfig { * @return - Returns the loaded version of the class */ public T loadConfig(Object conf) { - /* Set up the Serializer and Config Object */ - ObjectConverter converter = new ObjectConverter(); - CommentedFileConfig config = CommentedFileConfig.builder(configPath).build(); - config.load(); - - /* Load the config and return the loaded config */ - converter.toObject(config, conf); - return (T) conf; + return (T) super.readConfig(conf); } /** @@ -108,31 +61,13 @@ public class ModuleConfig { * @param conf - The config class to load */ public void migrateConfig(ModuleConfig conf) { - /* Set up the Serializer and Config Objects */ - CommentedFileConfig config = CommentedFileConfig.builder(configPath).build(); - CommentedFileConfig newConfig = CommentedFileConfig.builder(configPath).build(); - config.load(); - - /* Upgrade the config */ - new ObjectConverter().toConfig(conf, newConfig); - updateConfigValues(config, newConfig, newConfig, ""); - newConfig.save(); - - config.close(); - newConfig.close(); + super.migrateConfig(conf); } public void updateConfigValues(CommentedConfig oldConfig, CommentedConfig newConfig, CommentedConfig outputConfig, String subKey) { - /* Loop over the config keys and check what has changed */ - newConfig.valueMap().forEach((key, value) -> { - String finalKey = subKey + (subKey.isEmpty() ? "" : ".") + key; - if (value instanceof CommentedConfig commentedConfig) { - updateConfigValues(oldConfig, commentedConfig, outputConfig, finalKey); - } else { - outputConfig.set(finalKey, - oldConfig.contains(finalKey) ? oldConfig.get(finalKey) : value); - } - }); + if (getConfigFormat() instanceof TomlConfigFormat t) { + t.updateConfigValues(oldConfig, newConfig, outputConfig, subKey); + } } /** @@ -141,7 +76,7 @@ public class ModuleConfig { * @return - The FILE object containing the config file */ public File getConfigPath() { - return configPath; + return super.getConfigPath(); } /** @@ -150,12 +85,13 @@ public class ModuleConfig { * @return - Returns the Sync ID in format modid:config_name */ public String getNetworkID() { - return networkID; + return super.getNetworkID(); } /** * Fired whenever changes to the config are detected */ + @Override public void configReloaded() { } @@ -166,7 +102,7 @@ public class ModuleConfig { * @return */ public String getConfigName() { - return configName; + return super.getConfigName(); } /** @@ -175,10 +111,10 @@ public class ModuleConfig { * @return */ public String getModId() { - return modId; + return super.getModId(); } public boolean isSaveCalled() { - return isSaveCalled; + return super.isWasSaveCalled(); } } diff --git a/1.21/Common/src/main/java/com/hypherionmc/craterlib/core/config/formats/AbstractConfigFormat.java b/1.21/Common/src/main/java/com/hypherionmc/craterlib/core/config/formats/AbstractConfigFormat.java new file mode 100644 index 0000000..20511ba --- /dev/null +++ b/1.21/Common/src/main/java/com/hypherionmc/craterlib/core/config/formats/AbstractConfigFormat.java @@ -0,0 +1,32 @@ +package com.hypherionmc.craterlib.core.config.formats; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import me.hypherionmc.moonconfig.core.Config; + +import java.io.File; + +@RequiredArgsConstructor +@Getter +public abstract class AbstractConfigFormat { + + private final File configPath; + private final Runnable onSave; + + public void register(S conf) { + if (!configPath.exists() || configPath.length() < 2) { + saveConfig(conf); + } else { + migrateConfig(conf); + } + } + + public boolean wasConfigChanged(Config old, Config newConfig) { + return true; + } + + public abstract void saveConfig(S config); + public abstract S readConfig(S config); + public abstract void migrateConfig(S config); + +} diff --git a/1.21/Common/src/main/java/com/hypherionmc/craterlib/core/config/formats/JsonConfigFormat.java b/1.21/Common/src/main/java/com/hypherionmc/craterlib/core/config/formats/JsonConfigFormat.java new file mode 100644 index 0000000..0db35fa --- /dev/null +++ b/1.21/Common/src/main/java/com/hypherionmc/craterlib/core/config/formats/JsonConfigFormat.java @@ -0,0 +1,67 @@ +package com.hypherionmc.craterlib.core.config.formats; + +import me.hypherionmc.moonconfig.core.Config; +import me.hypherionmc.moonconfig.core.conversion.ObjectConverter; +import me.hypherionmc.moonconfig.core.file.FileConfig; + +import java.io.File; + +public class JsonConfigFormat extends AbstractConfigFormat { + + public JsonConfigFormat(File configPath, Runnable afterSave) { + super(configPath, afterSave); + } + + @Override + public void saveConfig(S conf) { + ObjectConverter converter = new ObjectConverter(); + FileConfig config = FileConfig.builder(getConfigPath()).sync().build(); + + converter.toConfig(conf, config); + config.save(); + getOnSave().run(); + } + + @Override + public S readConfig(S conf) { + /* Set up the Serializer and Config Object */ + ObjectConverter converter = new ObjectConverter(); + FileConfig config = FileConfig.builder(getConfigPath()).build(); + config.load(); + + /* Load the config and return the loaded config */ + converter.toObject(config, conf); + return conf; + } + + @Override + public void migrateConfig(S conf) { + /* Set up the Serializer and Config Objects */ + FileConfig config = FileConfig.builder(getConfigPath()).build(); + FileConfig newConfig = FileConfig.builder(getConfigPath()).sync().build(); + config.load(); + + /* Upgrade the config */ + if (wasConfigChanged(config, newConfig)) { + new ObjectConverter().toConfig(conf, newConfig); + updateConfigValues(config, newConfig, newConfig, ""); + newConfig.save(); + } + + config.close(); + newConfig.close(); + } + + public void updateConfigValues(Config oldConfig, Config newConfig, Config outputConfig, String subKey) { + /* Loop over the config keys and check what has changed */ + newConfig.valueMap().forEach((key, value) -> { + String finalKey = subKey + (subKey.isEmpty() ? "" : ".") + key; + if (value instanceof Config commentedConfig) { + updateConfigValues(oldConfig, commentedConfig, outputConfig, finalKey); + } else { + outputConfig.set(finalKey, + oldConfig.contains(finalKey) ? oldConfig.get(finalKey) : value); + } + }); + } +} diff --git a/1.21/Common/src/main/java/com/hypherionmc/craterlib/core/config/formats/TomlConfigFormat.java b/1.21/Common/src/main/java/com/hypherionmc/craterlib/core/config/formats/TomlConfigFormat.java new file mode 100644 index 0000000..e3f9763 --- /dev/null +++ b/1.21/Common/src/main/java/com/hypherionmc/craterlib/core/config/formats/TomlConfigFormat.java @@ -0,0 +1,67 @@ +package com.hypherionmc.craterlib.core.config.formats; + +import me.hypherionmc.moonconfig.core.CommentedConfig; +import me.hypherionmc.moonconfig.core.conversion.ObjectConverter; +import me.hypherionmc.moonconfig.core.file.CommentedFileConfig; + +import java.io.File; + +public class TomlConfigFormat extends AbstractConfigFormat { + + public TomlConfigFormat(File configPath, Runnable onSave) { + super(configPath, onSave); + } + + @Override + public void saveConfig(S conf) { + ObjectConverter converter = new ObjectConverter(); + CommentedFileConfig config = CommentedFileConfig.builder(getConfigPath()).sync().build(); + + converter.toConfig(conf, config); + config.save(); + getOnSave().run(); + } + + @Override + public S readConfig(S conf) { + /* Set up the Serializer and Config Object */ + ObjectConverter converter = new ObjectConverter(); + CommentedFileConfig config = CommentedFileConfig.builder(getConfigPath()).build(); + config.load(); + + /* Load the config and return the loaded config */ + converter.toObject(config, conf); + return conf; + } + + @Override + public void migrateConfig(S conf) { + /* Set up the Serializer and Config Objects */ + CommentedFileConfig config = CommentedFileConfig.builder(getConfigPath()).build(); + CommentedFileConfig newConfig = CommentedFileConfig.builder(getConfigPath()).sync().build(); + config.load(); + + /* Upgrade the config */ + if (wasConfigChanged(config, newConfig)) { + new ObjectConverter().toConfig(conf, newConfig); + updateConfigValues(config, newConfig, newConfig, ""); + newConfig.save(); + } + + config.close(); + newConfig.close(); + } + + public void updateConfigValues(CommentedConfig oldConfig, CommentedConfig newConfig, CommentedConfig outputConfig, String subKey) { + /* Loop over the config keys and check what has changed */ + newConfig.valueMap().forEach((key, value) -> { + String finalKey = subKey + (subKey.isEmpty() ? "" : ".") + key; + if (value instanceof CommentedConfig commentedConfig) { + updateConfigValues(oldConfig, commentedConfig, outputConfig, finalKey); + } else { + outputConfig.set(finalKey, + oldConfig.contains(finalKey) ? oldConfig.get(finalKey) : value); + } + }); + } +} diff --git a/1.21/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/ServerStatusMixin.java b/1.21/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/ServerStatusMixin.java new file mode 100644 index 0000000..53985e7 --- /dev/null +++ b/1.21/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/ServerStatusMixin.java @@ -0,0 +1,27 @@ +package com.hypherionmc.craterlib.mixin.events; + +import com.hypherionmc.craterlib.api.events.server.ServerStatusEvent; +import com.hypherionmc.craterlib.core.event.CraterEventBus; +import com.hypherionmc.craterlib.nojang.network.protocol.status.WrappedServerStatus; +import net.minecraft.network.protocol.status.ServerStatus; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import java.util.Optional; + +@Mixin(ServerStatus.class) +public class ServerStatusMixin { + + @Inject(method = "favicon", at = @At("RETURN"), cancellable = true) + private void injectIconEvent(CallbackInfoReturnable> cir) { + ServerStatusEvent.FaviconRequestEvent event = new ServerStatusEvent.FaviconRequestEvent(cir.getReturnValue().isEmpty() ? Optional.empty() : Optional.of(new WrappedServerStatus.WrappedFavicon(cir.getReturnValue().get()))); + CraterEventBus.INSTANCE.postEvent(event); + + if (event.getNewIcon().isPresent()) { + cir.setReturnValue(Optional.of(event.getNewIcon().get().toMojang())); + } + } + +} diff --git a/1.21/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/BridgedCommandSourceStack.java b/1.21/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/BridgedCommandSourceStack.java index 5a15402..5529824 100644 --- a/1.21/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/BridgedCommandSourceStack.java +++ b/1.21/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/BridgedCommandSourceStack.java @@ -16,6 +16,10 @@ public class BridgedCommandSourceStack { internal.sendSuccess(() -> ChatUtils.adventureToMojang(supplier.get()), bl); } + public void sendFailure(Component text) { + internal.sendFailure(ChatUtils.adventureToMojang(text)); + } + public CommandSourceStack toMojang() { return internal; } diff --git a/1.21/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/CommandsRegistry.java b/1.21/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/CommandsRegistry.java deleted file mode 100644 index 37ad15b..0000000 --- a/1.21/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/CommandsRegistry.java +++ /dev/null @@ -1,85 +0,0 @@ -package com.hypherionmc.craterlib.nojang.commands; - -import com.hypherionmc.craterlib.api.commands.CraterCommand; -import com.hypherionmc.craterlib.nojang.authlib.BridgedGameProfile; -import com.hypherionmc.craterlib.nojang.world.entity.player.BridgedPlayer; -import com.hypherionmc.craterlib.utils.TriConsumer; -import com.mojang.authlib.GameProfile; -import com.mojang.brigadier.CommandDispatcher; -import com.mojang.brigadier.builder.LiteralArgumentBuilder; -import lombok.AccessLevel; -import lombok.NoArgsConstructor; -import net.minecraft.commands.CommandSourceStack; -import net.minecraft.commands.Commands; -import net.minecraft.commands.arguments.GameProfileArgument; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -@NoArgsConstructor(access = AccessLevel.PRIVATE) -public class CommandsRegistry { - - public static final CommandsRegistry INSTANCE = new CommandsRegistry(); - - private final List commands = new ArrayList<>(); - - public void registerCommand(CraterCommand cmd) { - commands.add(cmd); - } - - public void registerCommands(CommandDispatcher stack) { - commands.forEach(cmd -> { - if (cmd.hasArguments()) { - CommandWithArguments.register(cmd, stack); - } else { - CommandWithoutArguments.register(cmd, stack); - } - }); - } - - static class CommandWithoutArguments { - - public static void register(CraterCommand cmd, CommandDispatcher dispatcher) { - LiteralArgumentBuilder command = Commands.literal(cmd.getCommandName()) - .requires(source -> source.hasPermission(cmd.getPermissionLevel())) - .executes(context -> { - cmd.getExecutor().accept(BridgedCommandSourceStack.of(context.getSource())); - return 1; - }); - - dispatcher.register(command); - } - - } - - @SuppressWarnings("unchecked") - static class CommandWithArguments { - - public static void register(CraterCommand cmd, CommandDispatcher dispatcher) { - LiteralArgumentBuilder command = Commands.literal(cmd.getCommandName()) - .requires(source -> source.hasPermission(cmd.getPermissionLevel())); - - cmd.getArguments().forEach((key, pair) -> command.then(Commands.argument(key, pair.getLeft()).executes(context -> { - - // This is FUCKING UGLY.... Need to improve this in the future - if (pair.getLeft() instanceof GameProfileArgument) { - Collection profiles = GameProfileArgument.getGameProfiles(context, key); - List bridgedGameProfiles = new ArrayList<>(); - - profiles.forEach(p -> bridgedGameProfiles.add(BridgedGameProfile.of(p))); - - ((TriConsumer, BridgedCommandSourceStack>) pair.getRight()) - .accept(BridgedPlayer.of(context.getSource().getPlayer()), bridgedGameProfiles, BridgedCommandSourceStack.of(context.getSource())); - return 1; - } - - return 1; - }))); - - dispatcher.register(command); - } - - } - -} diff --git a/1.21/Common/src/main/java/com/hypherionmc/craterlib/nojang/network/protocol/status/WrappedServerStatus.java b/1.21/Common/src/main/java/com/hypherionmc/craterlib/nojang/network/protocol/status/WrappedServerStatus.java new file mode 100644 index 0000000..ae6f773 --- /dev/null +++ b/1.21/Common/src/main/java/com/hypherionmc/craterlib/nojang/network/protocol/status/WrappedServerStatus.java @@ -0,0 +1,31 @@ +package com.hypherionmc.craterlib.nojang.network.protocol.status; + +import net.minecraft.network.protocol.status.ServerStatus; +import org.jetbrains.annotations.ApiStatus; + +public final class WrappedServerStatus { + + public static final class WrappedFavicon { + + private final ServerStatus.Favicon internal; + + public WrappedFavicon(byte[] iconBytes) { + internal = new ServerStatus.Favicon(iconBytes); + } + + @ApiStatus.Internal + public WrappedFavicon(ServerStatus.Favicon internal) { + this.internal = internal; + } + + public byte[] iconBytes() { + return internal.iconBytes(); + } + + public ServerStatus.Favicon toMojang() { + return internal; + } + + } + +} diff --git a/1.21/Common/src/main/java/com/hypherionmc/craterlib/nojang/world/entity/player/BridgedPlayer.java b/1.21/Common/src/main/java/com/hypherionmc/craterlib/nojang/world/entity/player/BridgedPlayer.java index 8aa6d49..2241836 100644 --- a/1.21/Common/src/main/java/com/hypherionmc/craterlib/nojang/world/entity/player/BridgedPlayer.java +++ b/1.21/Common/src/main/java/com/hypherionmc/craterlib/nojang/world/entity/player/BridgedPlayer.java @@ -57,6 +57,11 @@ public class BridgedPlayer { return null; } + public void disconnect(Component message) { + if (isServerPlayer()) + toMojangServerPlayer().connection.disconnect(ChatUtils.adventureToMojang(message)); + } + public ServerPlayer toMojangServerPlayer() { return (ServerPlayer) internal; } diff --git a/1.21/Common/src/main/java/com/hypherionmc/craterlib/utils/ChatUtils.java b/1.21/Common/src/main/java/com/hypherionmc/craterlib/utils/ChatUtils.java index 02ddae4..c09982c 100644 --- a/1.21/Common/src/main/java/com/hypherionmc/craterlib/utils/ChatUtils.java +++ b/1.21/Common/src/main/java/com/hypherionmc/craterlib/utils/ChatUtils.java @@ -108,4 +108,11 @@ public class ChatUtils { return mojangToAdventure(Component.translatable(Util.makeDescriptionId("biome", identifier.toMojang()))); } + public static net.kyori.adventure.text.Component format(String value) { + return net.kyori.adventure.text.Component.translatable(convertFormattingCodes(value)); + } + + private static String convertFormattingCodes(String input) { + return input.replaceAll("§([0-9a-fklmnor])", "\u00A7$1"); + } } diff --git a/1.21/Common/src/main/resources/craterlib.mixins.json b/1.21/Common/src/main/resources/craterlib.mixins.json index 1a739db..c910ed2 100644 --- a/1.21/Common/src/main/resources/craterlib.mixins.json +++ b/1.21/Common/src/main/resources/craterlib.mixins.json @@ -16,7 +16,8 @@ "events.CommandMixin", "events.PlayerAdvancementsMixin", "events.PlayerListMixin", - "events.ServerPlayerMixin" + "events.ServerPlayerMixin", + "events.ServerStatusMixin" ], "injectors": { "defaultRequire": 1 diff --git a/1.21/Fabric/build.gradle b/1.21/Fabric/build.gradle index d3a187f..0fd9480 100644 --- a/1.21/Fabric/build.gradle +++ b/1.21/Fabric/build.gradle @@ -113,8 +113,8 @@ publisher { setVersionType("release") setChangelog("https://raw.githubusercontent.com/hypherionmc/changelogs/main/craterlib/changelog-fabric.md") setProjectVersion("${minecraft_version}-${project.version}") - setDisplayName("[FABRIC/QUILT 1.21.0] CraterLib - ${project.version}") - setGameVersions("1.21") + setDisplayName("[FABRIC/QUILT 1.21.x] CraterLib - ${project.version}") + setGameVersions("1.21", "1.21.1") setLoaders("fabric", "quilt") setArtifact(remapJar) setCurseEnvironment("both") diff --git a/1.21/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibInitializer.java b/1.21/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibInitializer.java index c66c210..5e93a3a 100644 --- a/1.21/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibInitializer.java +++ b/1.21/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibInitializer.java @@ -9,7 +9,6 @@ import com.hypherionmc.craterlib.core.networking.CraterPacketNetwork; import com.hypherionmc.craterlib.core.networking.data.PacketSide; import com.hypherionmc.craterlib.core.platform.ModloaderEnvironment; import com.hypherionmc.craterlib.network.CraterFabricNetworkHandler; -import com.hypherionmc.craterlib.nojang.commands.CommandsRegistry; import com.hypherionmc.craterlib.nojang.server.BridgedMinecraftServer; import net.fabricmc.api.ModInitializer; import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback; @@ -21,8 +20,7 @@ public class CraterLibInitializer implements ModInitializer { public void onInitialize() { new CraterPacketNetwork(new CraterFabricNetworkHandler(PacketSide.SERVER)); CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> { - CraterEventBus.INSTANCE.postEvent(new CraterRegisterCommandEvent()); - CommandsRegistry.INSTANCE.registerCommands(dispatcher); + CraterEventBus.INSTANCE.postEvent(new CraterRegisterCommandEvent(dispatcher)); }); diff --git a/1.21/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibModMenuIntegration.java b/1.21/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibModMenuIntegration.java index 6615352..5b34ff1 100644 --- a/1.21/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibModMenuIntegration.java +++ b/1.21/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibModMenuIntegration.java @@ -2,7 +2,6 @@ package com.hypherionmc.craterlib; import com.hypherionmc.craterlib.client.gui.config.CraterConfigScreen; import com.hypherionmc.craterlib.core.config.ConfigController; -import com.hypherionmc.craterlib.core.config.ModuleConfig; import com.hypherionmc.craterlib.core.config.annotations.NoConfigScreen; import com.terraformersmc.modmenu.api.ConfigScreenFactory; import com.terraformersmc.modmenu.api.ModMenuApi; @@ -19,9 +18,9 @@ public class CraterLibModMenuIntegration implements ModMenuApi { public Map> getProvidedConfigScreenFactories() { Map> configScreens = new HashMap<>(); - ConfigController.getMonitoredConfigs().forEach((conf, watcher) -> { + ConfigController.getWatchedConfigs().forEach((conf, watcher) -> { if (!conf.getClass().isAnnotationPresent(NoConfigScreen.class)) { - configScreens.put(((ModuleConfig) conf).getModId(), screen -> new CraterConfigScreen((ModuleConfig) conf, screen)); + configScreens.put(watcher.getLeft().getModId(), screen -> new CraterConfigScreen(watcher.getLeft(), screen)); } }); diff --git a/1.21/Fabric/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java b/1.21/Fabric/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java index 91b157b..576a276 100644 --- a/1.21/Fabric/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java +++ b/1.21/Fabric/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java @@ -27,8 +27,8 @@ public class ServerGamePacketListenerImplMixin { cancellable = true ) private void injectChatEvent(PlayerChatMessage arg, Component arg2, FilteredText arg3, CallbackInfo ci) { - Component finalArg = arg2 == null ? arg.decoratedContent() : arg2; - CraterServerChatEvent event = new CraterServerChatEvent(BridgedPlayer.of(this.player), finalArg.getString(), ChatUtils.mojangToAdventure(finalArg)); + Component finalcomp = arg2 == null ? arg.decoratedContent() : arg2; + CraterServerChatEvent event = new CraterServerChatEvent(BridgedPlayer.of(this.player), finalcomp.getString(), ChatUtils.mojangToAdventure(finalcomp)); CraterEventBus.INSTANCE.postEvent(event); if (event.wasCancelled()) ci.cancel(); diff --git a/1.21/Fabric/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java b/1.21/Fabric/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java new file mode 100644 index 0000000..f3dc866 --- /dev/null +++ b/1.21/Fabric/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java @@ -0,0 +1,52 @@ +package com.hypherionmc.craterlib.mixin; + +import com.hypherionmc.craterlib.api.events.server.ServerStatusEvent; +import com.hypherionmc.craterlib.core.event.CraterEventBus; +import com.hypherionmc.craterlib.utils.ChatUtils; +import net.minecraft.network.Connection; +import net.minecraft.network.protocol.status.ClientboundStatusResponsePacket; +import net.minecraft.network.protocol.status.ServerStatus; +import net.minecraft.network.protocol.status.ServerboundStatusRequestPacket; +import net.minecraft.server.network.ServerStatusPacketListenerImpl; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(ServerStatusPacketListenerImpl.class) +public class ServerStatusPacketListenerMixin { + + @Shadow + @Final + private ServerStatus status; + + @Shadow @Final private Connection connection; + + @Inject(method = "handleStatusRequest", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/network/Connection;send(Lnet/minecraft/network/protocol/Packet;)V", + shift = At.Shift.BEFORE), + cancellable = true + ) + private void injectHandleStatusRequest(ServerboundStatusRequestPacket arg, CallbackInfo ci) { + ServerStatusEvent.StatusRequestEvent event = new ServerStatusEvent.StatusRequestEvent(ChatUtils.mojangToAdventure(status.description())); + CraterEventBus.INSTANCE.postEvent(event); + + if (event.getNewStatus() != null) { + ci.cancel(); + this.connection.send(new ClientboundStatusResponsePacket( + new ServerStatus(ChatUtils.adventureToMojang( + event.getNewStatus()), + status.players(), + status.version(), + status.favicon(), + status.enforcesSecureChat() + ) + )); + } + } + +} \ No newline at end of file diff --git a/1.21/Fabric/src/main/resources/craterlib.fabric.mixins.json b/1.21/Fabric/src/main/resources/craterlib.fabric.mixins.json index 7c59043..a6d0bc1 100644 --- a/1.21/Fabric/src/main/resources/craterlib.fabric.mixins.json +++ b/1.21/Fabric/src/main/resources/craterlib.fabric.mixins.json @@ -9,7 +9,8 @@ "TutorialMixin" ], "server": [ - "ServerGamePacketListenerImplMixin" + "ServerGamePacketListenerImplMixin", + "ServerStatusPacketListenerMixin" ], "injectors": { "defaultRequire": 1 diff --git a/1.21/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java b/1.21/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java index 7adbbe1..012b6ff 100644 --- a/1.21/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java +++ b/1.21/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java @@ -27,8 +27,8 @@ public class ServerGamePacketListenerImplMixin { cancellable = true ) private void injectChatEvent(Component component, PlayerChatMessage arg, FilteredText p_296589_, CallbackInfo ci) { - Component finalArg = component == null ? arg.decoratedContent() : component; - CraterServerChatEvent event = new CraterServerChatEvent(BridgedPlayer.of(this.player), finalArg.getString(), ChatUtils.mojangToAdventure(finalArg)); + Component finalcomp = component == null ? arg.decoratedContent() : component; + CraterServerChatEvent event = new CraterServerChatEvent(BridgedPlayer.of(this.player), finalcomp.getString(), ChatUtils.mojangToAdventure(finalcomp)); CraterEventBus.INSTANCE.postEvent(event); if (event.wasCancelled()) ci.cancel(); diff --git a/1.21/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java b/1.21/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java new file mode 100644 index 0000000..cb697db --- /dev/null +++ b/1.21/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java @@ -0,0 +1,53 @@ +package com.hypherionmc.craterlib.mixin; + +import com.hypherionmc.craterlib.api.events.server.ServerStatusEvent; +import com.hypherionmc.craterlib.core.event.CraterEventBus; +import com.hypherionmc.craterlib.utils.ChatUtils; +import net.minecraft.network.Connection; +import net.minecraft.network.protocol.status.ClientboundStatusResponsePacket; +import net.minecraft.network.protocol.status.ServerStatus; +import net.minecraft.network.protocol.status.ServerboundStatusRequestPacket; +import net.minecraft.server.network.ServerStatusPacketListenerImpl; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(ServerStatusPacketListenerImpl.class) +public class ServerStatusPacketListenerMixin { + + @Shadow + @Final + private ServerStatus status; + + @Shadow @Final private Connection connection; + + @Inject(method = "handleStatusRequest", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/network/Connection;send(Lnet/minecraft/network/protocol/Packet;)V", + shift = At.Shift.BEFORE), + cancellable = true + ) + private void injectHandleStatusRequest(ServerboundStatusRequestPacket arg, CallbackInfo ci) { + ServerStatusEvent.StatusRequestEvent event = new ServerStatusEvent.StatusRequestEvent(ChatUtils.mojangToAdventure(status.description())); + CraterEventBus.INSTANCE.postEvent(event); + + if (event.getNewStatus() != null) { + ci.cancel(); + this.connection.send(new ClientboundStatusResponsePacket( + new ServerStatus(ChatUtils.adventureToMojang( + event.getNewStatus()), + status.players(), + status.version(), + status.favicon(), + status.enforcesSecureChat(), + status.isModded() + ) + )); + } + } + +} \ No newline at end of file diff --git a/1.21/Forge/src/main/resources/craterlib.forge.mixins.json b/1.21/Forge/src/main/resources/craterlib.forge.mixins.json index aa072d1..892f6d7 100644 --- a/1.21/Forge/src/main/resources/craterlib.forge.mixins.json +++ b/1.21/Forge/src/main/resources/craterlib.forge.mixins.json @@ -9,7 +9,8 @@ "ConfigScreenHandlerMixin" ], "server": [ - "ServerGamePacketListenerImplMixin" + "ServerGamePacketListenerImplMixin", + "ServerStatusPacketListenerMixin" ], "injectors": { "defaultRequire": 1 diff --git a/1.21/NeoForge/build.gradle b/1.21/NeoForge/build.gradle index b3b5659..f6ef5c7 100644 --- a/1.21/NeoForge/build.gradle +++ b/1.21/NeoForge/build.gradle @@ -106,8 +106,8 @@ publisher { setVersionType("release") setChangelog("https://raw.githubusercontent.com/hypherionmc/changelogs/main/craterlib/changelog-forge.md") setProjectVersion("${minecraft_version}-${project.version}") - setDisplayName("[NeoForge 1.21.0] CraterLib - ${project.version}") - setGameVersions("1.21") + setDisplayName("[NeoForge 1.21.x] CraterLib - ${project.version}") + setGameVersions("1.21", "1.21.1") setLoaders("neoforge") setArtifact(remapJar) setCurseEnvironment("both") diff --git a/1.21/NeoForge/src/main/java/com/hypherionmc/craterlib/client/NeoForgeClientHelper.java b/1.21/NeoForge/src/main/java/com/hypherionmc/craterlib/client/NeoForgeClientHelper.java index 5aeb1fd..e7d9013 100644 --- a/1.21/NeoForge/src/main/java/com/hypherionmc/craterlib/client/NeoForgeClientHelper.java +++ b/1.21/NeoForge/src/main/java/com/hypherionmc/craterlib/client/NeoForgeClientHelper.java @@ -2,8 +2,8 @@ package com.hypherionmc.craterlib.client; import com.hypherionmc.craterlib.api.events.client.LateInitEvent; import com.hypherionmc.craterlib.client.gui.config.CraterConfigScreen; +import com.hypherionmc.craterlib.core.config.AbstractConfig; import com.hypherionmc.craterlib.core.config.ConfigController; -import com.hypherionmc.craterlib.core.config.ModuleConfig; import com.hypherionmc.craterlib.core.config.annotations.NoConfigScreen; import com.hypherionmc.craterlib.core.event.CraterEventBus; import com.hypherionmc.craterlib.core.platform.ClientPlatform; @@ -51,9 +51,9 @@ public class NeoForgeClientHelper implements ClientPlatform { LateInitEvent event = new LateInitEvent(new BridgedMinecraft(), BridgedOptions.of(Minecraft.getInstance().options)); CraterEventBus.INSTANCE.postEvent(event); - ConfigController.getMonitoredConfigs().forEach((conf, watcher) -> { + ConfigController.getWatchedConfigs().forEach((conf, watcher) -> { if (!conf.getClass().isAnnotationPresent(NoConfigScreen.class)) { - ModuleConfig config = (ModuleConfig) conf; + AbstractConfig config = watcher.getLeft(); ModList.get().getModContainerById(config.getModId()).ifPresent(c -> c.registerExtensionPoint(IConfigScreenFactory.class, ((minecraft, screen) -> new CraterConfigScreen(config, screen)))); } }); diff --git a/1.21/NeoForge/src/main/java/com/hypherionmc/craterlib/common/NeoForgeServerEvents.java b/1.21/NeoForge/src/main/java/com/hypherionmc/craterlib/common/NeoForgeServerEvents.java index 91ca5b7..868b89f 100644 --- a/1.21/NeoForge/src/main/java/com/hypherionmc/craterlib/common/NeoForgeServerEvents.java +++ b/1.21/NeoForge/src/main/java/com/hypherionmc/craterlib/common/NeoForgeServerEvents.java @@ -3,7 +3,6 @@ package com.hypherionmc.craterlib.common; import com.hypherionmc.craterlib.api.events.server.CraterRegisterCommandEvent; import com.hypherionmc.craterlib.api.events.server.CraterServerLifecycleEvent; import com.hypherionmc.craterlib.core.event.CraterEventBus; -import com.hypherionmc.craterlib.nojang.commands.CommandsRegistry; import com.hypherionmc.craterlib.nojang.server.BridgedMinecraftServer; import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.neoforge.event.RegisterCommandsEvent; @@ -36,8 +35,7 @@ public class NeoForgeServerEvents { @SubscribeEvent public void onCommandRegister(RegisterCommandsEvent event) { - CraterEventBus.INSTANCE.postEvent(new CraterRegisterCommandEvent()); - CommandsRegistry.INSTANCE.registerCommands(event.getDispatcher()); + CraterEventBus.INSTANCE.postEvent(new CraterRegisterCommandEvent(event.getDispatcher())); } } diff --git a/1.21/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java b/1.21/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java index 7adbbe1..012b6ff 100644 --- a/1.21/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java +++ b/1.21/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java @@ -27,8 +27,8 @@ public class ServerGamePacketListenerImplMixin { cancellable = true ) private void injectChatEvent(Component component, PlayerChatMessage arg, FilteredText p_296589_, CallbackInfo ci) { - Component finalArg = component == null ? arg.decoratedContent() : component; - CraterServerChatEvent event = new CraterServerChatEvent(BridgedPlayer.of(this.player), finalArg.getString(), ChatUtils.mojangToAdventure(finalArg)); + Component finalcomp = component == null ? arg.decoratedContent() : component; + CraterServerChatEvent event = new CraterServerChatEvent(BridgedPlayer.of(this.player), finalcomp.getString(), ChatUtils.mojangToAdventure(finalcomp)); CraterEventBus.INSTANCE.postEvent(event); if (event.wasCancelled()) ci.cancel(); diff --git a/1.21/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java b/1.21/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java new file mode 100644 index 0000000..cb697db --- /dev/null +++ b/1.21/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java @@ -0,0 +1,53 @@ +package com.hypherionmc.craterlib.mixin; + +import com.hypherionmc.craterlib.api.events.server.ServerStatusEvent; +import com.hypherionmc.craterlib.core.event.CraterEventBus; +import com.hypherionmc.craterlib.utils.ChatUtils; +import net.minecraft.network.Connection; +import net.minecraft.network.protocol.status.ClientboundStatusResponsePacket; +import net.minecraft.network.protocol.status.ServerStatus; +import net.minecraft.network.protocol.status.ServerboundStatusRequestPacket; +import net.minecraft.server.network.ServerStatusPacketListenerImpl; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(ServerStatusPacketListenerImpl.class) +public class ServerStatusPacketListenerMixin { + + @Shadow + @Final + private ServerStatus status; + + @Shadow @Final private Connection connection; + + @Inject(method = "handleStatusRequest", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/network/Connection;send(Lnet/minecraft/network/protocol/Packet;)V", + shift = At.Shift.BEFORE), + cancellable = true + ) + private void injectHandleStatusRequest(ServerboundStatusRequestPacket arg, CallbackInfo ci) { + ServerStatusEvent.StatusRequestEvent event = new ServerStatusEvent.StatusRequestEvent(ChatUtils.mojangToAdventure(status.description())); + CraterEventBus.INSTANCE.postEvent(event); + + if (event.getNewStatus() != null) { + ci.cancel(); + this.connection.send(new ClientboundStatusResponsePacket( + new ServerStatus(ChatUtils.adventureToMojang( + event.getNewStatus()), + status.players(), + status.version(), + status.favicon(), + status.enforcesSecureChat(), + status.isModded() + ) + )); + } + } + +} \ No newline at end of file diff --git a/1.21/NeoForge/src/main/resources/craterlib.neoforge.mixins.json b/1.21/NeoForge/src/main/resources/craterlib.neoforge.mixins.json index e1af981..147f7e0 100644 --- a/1.21/NeoForge/src/main/resources/craterlib.neoforge.mixins.json +++ b/1.21/NeoForge/src/main/resources/craterlib.neoforge.mixins.json @@ -7,7 +7,8 @@ ], "client": [], "server": [ - "ServerGamePacketListenerImplMixin" + "ServerGamePacketListenerImplMixin", + "ServerStatusPacketListenerMixin" ], "injectors": { "defaultRequire": 1 diff --git a/1.21/README.md b/1.21/README.md index 63c4aed..4b18d17 100644 --- a/1.21/README.md +++ b/1.21/README.md @@ -15,8 +15,7 @@ A Library mod and modding api for easier multi-version minecraft and mod loader | < 1.18.2 | ❌ | | 1.18.2-1.20.2 | ✳️ | | 1.20.4 | ✳️ | -| 1.20.6 | ❌ | -| 1.21 | ✳️ | +| 1.21.x | ✳️ | - ❌ - Not Supported; no bug fixes or new features. - 🚧 - Work in Progress; not ready for release. diff --git a/1.21/build.gradle b/1.21/build.gradle index c4a979f..861a660 100644 --- a/1.21/build.gradle +++ b/1.21/build.gradle @@ -57,11 +57,13 @@ subprojects { // All Projects shade "me.hypherionmc.moon-config:core:${moon_config}" shade "me.hypherionmc.moon-config:toml:${moon_config}" + shade "me.hypherionmc.moon-config:json:${moon_config}" shade "com.hypherionmc:rpcsdk:${rpc_sdk}" shade "me.hypherionmc.sdlink:mcdiscordformatter-1.20.3:${discord_formatter}" shade "net.kyori:adventure-api:${adventure}" shade "net.kyori:adventure-text-serializer-gson:${adventure}" + compileOnly 'net.luckperms:api:5.4' compileOnly("org.projectlombok:lombok:${lombok}") annotationProcessor("org.projectlombok:lombok:${lombok}") } diff --git a/1.21/gradle.properties b/1.21/gradle.properties index f086dac..080e29d 100644 --- a/1.21/gradle.properties +++ b/1.21/gradle.properties @@ -1,7 +1,7 @@ #Project version_major=2 -version_minor=0 -version_patch=3 +version_minor=1 +version_patch=0 version_build=0 #Mod diff --git a/commit.sha b/commit.sha index 38347a2..646d8ca 100644 --- a/commit.sha +++ b/commit.sha @@ -1 +1 @@ -2c13d507c30a460256f006d30428d7ead5da2719 \ No newline at end of file +0dbf07de46f6156b78fe826379cde3739981546f \ No newline at end of file diff --git a/patches/1.18.2/.jenkins/Jenkinsfile.snapshot.patch b/patches/1.18.2/.jenkins/Jenkinsfile.snapshot.patch index 0a87493..4c6053c 100644 --- a/patches/1.18.2/.jenkins/Jenkinsfile.snapshot.patch +++ b/patches/1.18.2/.jenkins/Jenkinsfile.snapshot.patch @@ -6,7 +6,7 @@ -def JDK = "21"; -def majorMc = "1.21"; -def modLoaders = "neoforge|fabric|quilt"; --def supportedMc = "1.21"; +-def supportedMc = "1.21|1.21.1"; -def reltype = "port"; +def JDK = "17"; +def majorMc = "1.18.2"; diff --git a/patches/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/api/commands/CraterCommand.java.patch b/patches/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/api/commands/CraterCommand.java.patch new file mode 100644 index 0000000..2149294 --- /dev/null +++ b/patches/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/api/commands/CraterCommand.java.patch @@ -0,0 +1,77 @@ +--- a/Common/src/main/java/com/hypherionmc/craterlib/api/commands/CraterCommand.java ++++ b/Common/src/main/java/com/hypherionmc/craterlib/api/commands/CraterCommand.java +@@ -14,6 +14,7 @@ + import net.minecraft.commands.CommandSourceStack; + import net.minecraft.commands.Commands; + import net.minecraft.commands.arguments.GameProfileArgument; ++import net.minecraft.server.level.ServerPlayer; + import net.minecraft.world.entity.player.Player; + import org.jetbrains.annotations.ApiStatus; + +@@ -53,7 +54,7 @@ + public CraterCommand withGameProfilesArgument(String key, CommandExecutorWithArgs> executor) { + this.mojangCommand.then(Commands.argument(key, GameProfileArgument.gameProfile()) + .executes(context -> executor.run( +- BridgedPlayer.of(context.getSource().getPlayer()), ++ BridgedPlayer.of(context.getSource().getPlayerOrException()), + GameProfileArgument.getGameProfiles(context, key).stream().map(BridgedGameProfile::of).toList(), + BridgedCommandSourceStack.of(context.getSource())) + )); +@@ -63,7 +64,7 @@ + public CraterCommand withBoolArgument(String key, CommandExecutorWithArgs executor) { + this.mojangCommand.then(Commands.argument(key, BoolArgumentType.bool()) + .executes(context -> executor.run( +- BridgedPlayer.of(context.getSource().getPlayer()), ++ BridgedPlayer.of(context.getSource().getPlayerOrException()), + BoolArgumentType.getBool(context, key), + BridgedCommandSourceStack.of(context.getSource()) + ))); +@@ -73,7 +74,7 @@ + public CraterCommand withWordArgument(String key, CommandExecutorWithArgs executor) { + this.mojangCommand.then(Commands.argument(key, StringArgumentType.word()) + .executes(context -> executor.run( +- BridgedPlayer.of(context.getSource().getPlayer()), ++ BridgedPlayer.of(context.getSource().getPlayerOrException()), + StringArgumentType.getString(context, key), + BridgedCommandSourceStack.of(context.getSource()) + ))); +@@ -83,7 +84,7 @@ + public CraterCommand withStringArgument(String key, CommandExecutorWithArgs executor) { + this.mojangCommand.then(Commands.argument(key, StringArgumentType.string()) + .executes(context -> executor.run( +- BridgedPlayer.of(context.getSource().getPlayer()), ++ BridgedPlayer.of(context.getSource().getPlayerOrException()), + StringArgumentType.getString(context, key), + BridgedCommandSourceStack.of(context.getSource()) + ))); +@@ -93,7 +94,7 @@ + public CraterCommand withPhraseArgument(String key, CommandExecutorWithArgs executor) { + this.mojangCommand.then(Commands.argument(key, StringArgumentType.greedyString()) + .executes(context -> executor.run( +- BridgedPlayer.of(context.getSource().getPlayer()), ++ BridgedPlayer.of(context.getSource().getPlayerOrException()), + StringArgumentType.getString(context, key), + BridgedCommandSourceStack.of(context.getSource()) + ))); +@@ -103,7 +104,7 @@ + public CraterCommand withIntegerArgument(String key, CommandExecutorWithArgs executor) { + this.mojangCommand.then(Commands.argument(key, IntegerArgumentType.integer()) + .executes(context -> executor.run( +- BridgedPlayer.of(context.getSource().getPlayer()), ++ BridgedPlayer.of(context.getSource().getPlayerOrException()), + IntegerArgumentType.getInteger(context, key), + BridgedCommandSourceStack.of(context.getSource()) + ))); +@@ -137,10 +138,10 @@ + } + + private boolean checkPermission(CommandSourceStack stack) { +- if (!ModloaderEnvironment.INSTANCE.isModLoaded("luckperms") || !stack.isPlayer() || luckPermNode.isEmpty()) ++ if (!ModloaderEnvironment.INSTANCE.isModLoaded("luckperms") || !(stack.getEntity() instanceof Player) || luckPermNode.isEmpty()) + return stack.hasPermission(this.permLevel); + +- return LuckPermsCompat.INSTANCE.hasPermission(stack.getPlayer(), this.luckPermNode) || stack.hasPermission(this.permLevel); ++ return LuckPermsCompat.INSTANCE.hasPermission((ServerPlayer) stack.getEntity(), this.luckPermNode) || stack.hasPermission(this.permLevel); + } + + @FunctionalInterface diff --git a/patches/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/CraterConfigScreen.java.patch b/patches/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/CraterConfigScreen.java.patch index 4f8722e..fcd7323 100644 --- a/patches/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/CraterConfigScreen.java.patch +++ b/patches/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/CraterConfigScreen.java.patch @@ -26,7 +26,7 @@ @@ -49,7 +50,7 @@ private boolean dragging; - public CraterConfigScreen(ModuleConfig config, Screen parent, Object subConfig) { + public CraterConfigScreen(AbstractConfig config, Screen parent, Object subConfig) { - super(Component.translatable("cl." + config.getClass().getSimpleName().toLowerCase() + ".title")); + super(new TranslatableComponent("cl." + config.getClass().getSimpleName().toLowerCase() + ".title")); this.parent = parent; diff --git a/patches/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/SubConfigWidget.java.patch b/patches/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/SubConfigWidget.java.patch index 8c4deff..01902bf 100644 --- a/patches/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/SubConfigWidget.java.patch +++ b/patches/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/SubConfigWidget.java.patch @@ -3,7 +3,7 @@ @@ -2,12 +2,12 @@ import com.hypherionmc.craterlib.client.gui.config.CraterConfigScreen; - import com.hypherionmc.craterlib.core.config.ModuleConfig; + import com.hypherionmc.craterlib.core.config.AbstractConfig; +import com.mojang.blaze3d.vertex.PoseStack; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Font; diff --git a/patches/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/ServerStatusMixin.java.patch b/patches/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/ServerStatusMixin.java.patch new file mode 100644 index 0000000..19f9b0f --- /dev/null +++ b/patches/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/ServerStatusMixin.java.patch @@ -0,0 +1,20 @@ +--- a/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/ServerStatusMixin.java ++++ b/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/ServerStatusMixin.java +@@ -14,13 +14,13 @@ + @Mixin(ServerStatus.class) + public class ServerStatusMixin { + +- @Inject(method = "favicon", at = @At("RETURN"), cancellable = true) +- private void injectIconEvent(CallbackInfoReturnable> cir) { +- ServerStatusEvent.FaviconRequestEvent event = new ServerStatusEvent.FaviconRequestEvent(cir.getReturnValue().isEmpty() ? Optional.empty() : Optional.of(new WrappedServerStatus.WrappedFavicon(cir.getReturnValue().get()))); ++ @Inject(method = "getFavicon", at = @At("RETURN"), cancellable = true) ++ private void injectIconEvent(CallbackInfoReturnable cir) { ++ ServerStatusEvent.FaviconRequestEvent event = new ServerStatusEvent.FaviconRequestEvent(cir.getReturnValue().isEmpty() ? Optional.empty() : Optional.of(new WrappedServerStatus.WrappedFavicon(cir.getReturnValue()))); + CraterEventBus.INSTANCE.postEvent(event); + + if (event.getNewIcon().isPresent()) { +- cir.setReturnValue(Optional.of(event.getNewIcon().get().toMojang())); ++ cir.setReturnValue(event.getNewIcon().get().toMojang()); + } + } + diff --git a/patches/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/ServerStatusPacketListenerMixin.java.patch b/patches/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/ServerStatusPacketListenerMixin.java.patch new file mode 100644 index 0000000..0a78917 --- /dev/null +++ b/patches/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/ServerStatusPacketListenerMixin.java.patch @@ -0,0 +1,49 @@ +--- /dev/null ++++ b/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/ServerStatusPacketListenerMixin.java +@@ -1,0 +1,46 @@ ++package com.hypherionmc.craterlib.mixin.events; ++ ++import com.hypherionmc.craterlib.api.events.server.ServerStatusEvent; ++import com.hypherionmc.craterlib.core.event.CraterEventBus; ++import com.hypherionmc.craterlib.utils.ChatUtils; ++import net.minecraft.network.Connection; ++import net.minecraft.network.protocol.status.ClientboundStatusResponsePacket; ++import net.minecraft.network.protocol.status.ServerStatus; ++import net.minecraft.network.protocol.status.ServerboundStatusRequestPacket; ++import net.minecraft.server.MinecraftServer; ++import net.minecraft.server.network.ServerStatusPacketListenerImpl; ++import org.spongepowered.asm.mixin.Final; ++import org.spongepowered.asm.mixin.Mixin; ++import org.spongepowered.asm.mixin.Shadow; ++import org.spongepowered.asm.mixin.injection.At; ++import org.spongepowered.asm.mixin.injection.Inject; ++import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; ++ ++@Mixin(ServerStatusPacketListenerImpl.class) ++public class ServerStatusPacketListenerMixin { ++ ++ @Shadow @Final private Connection connection; ++ ++ @Shadow @Final private MinecraftServer server; ++ ++ @Inject(method = "handleStatusRequest", ++ at = @At( ++ value = "INVOKE", ++ target = "Lnet/minecraft/network/Connection;send(Lnet/minecraft/network/protocol/Packet;)V", ++ shift = At.Shift.BEFORE), ++ cancellable = true ++ ) ++ private void injectHandleStatusRequest(ServerboundStatusRequestPacket arg, CallbackInfo ci) { ++ ServerStatusEvent.StatusRequestEvent event = new ServerStatusEvent.StatusRequestEvent(ChatUtils.mojangToAdventure(server.getStatus().getDescription())); ++ CraterEventBus.INSTANCE.postEvent(event); ++ ++ if (event.getNewStatus() != null) { ++ ci.cancel(); ++ ServerStatus serverStatus = this.server.getStatus(); ++ serverStatus.setDescription(ChatUtils.adventureToMojang(event.getNewStatus())); ++ ++ this.connection.send(new ClientboundStatusResponsePacket(serverStatus)); ++ } ++ } ++ ++} diff --git a/patches/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/BridgedCommandSourceStack.java.patch b/patches/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/BridgedCommandSourceStack.java.patch index 2decb2b..bcb0d0f 100644 --- a/patches/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/BridgedCommandSourceStack.java.patch +++ b/patches/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/BridgedCommandSourceStack.java.patch @@ -8,4 +8,4 @@ + internal.sendSuccess(ChatUtils.adventureToMojang(supplier.get()), bl); } - public CommandSourceStack toMojang() { + public void sendFailure(Component text) { diff --git a/patches/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/CommandsRegistry.java.patch b/patches/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/CommandsRegistry.java.patch deleted file mode 100644 index 2222357..0000000 --- a/patches/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/CommandsRegistry.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/CommandsRegistry.java -+++ b/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/CommandsRegistry.java -@@ -70,7 +70,7 @@ - profiles.forEach(p -> bridgedGameProfiles.add(BridgedGameProfile.of(p))); - - ((TriConsumer, BridgedCommandSourceStack>) pair.getRight()) -- .accept(BridgedPlayer.of(context.getSource().getPlayer()), bridgedGameProfiles, BridgedCommandSourceStack.of(context.getSource())); -+ .accept(BridgedPlayer.of(context.getSource().getPlayerOrException()), bridgedGameProfiles, BridgedCommandSourceStack.of(context.getSource())); - return 1; - } - diff --git a/patches/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/nojang/network/protocol/status/WrappedServerStatus.java.patch b/patches/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/nojang/network/protocol/status/WrappedServerStatus.java.patch new file mode 100644 index 0000000..2149f59 --- /dev/null +++ b/patches/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/nojang/network/protocol/status/WrappedServerStatus.java.patch @@ -0,0 +1,48 @@ +--- a/Common/src/main/java/com/hypherionmc/craterlib/nojang/network/protocol/status/WrappedServerStatus.java ++++ b/Common/src/main/java/com/hypherionmc/craterlib/nojang/network/protocol/status/WrappedServerStatus.java +@@ -1,28 +1,39 @@ + package com.hypherionmc.craterlib.nojang.network.protocol.status; + +-import net.minecraft.network.protocol.status.ServerStatus; + import org.jetbrains.annotations.ApiStatus; + ++import java.nio.charset.StandardCharsets; ++import java.util.Base64; ++ + public final class WrappedServerStatus { + + public static final class WrappedFavicon { + +- private final ServerStatus.Favicon internal; ++ private final String internal; ++ private final byte[] iconBytes; + + public WrappedFavicon(byte[] iconBytes) { +- internal = new ServerStatus.Favicon(iconBytes); ++ this.iconBytes = iconBytes; ++ ++ if (iconBytes != null) { ++ byte[] encoded = Base64.getEncoder().encode(iconBytes); ++ internal = "data:image/png;base64," + new String(encoded, StandardCharsets.UTF_8); ++ } else { ++ internal = null; ++ } + } + + @ApiStatus.Internal +- public WrappedFavicon(ServerStatus.Favicon internal) { ++ public WrappedFavicon(String internal) { + this.internal = internal; ++ this.iconBytes = new byte[0]; + } + + public byte[] iconBytes() { +- return internal.iconBytes(); ++ return iconBytes; + } + +- public ServerStatus.Favicon toMojang() { ++ public String toMojang() { + return internal; + } + diff --git a/patches/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/utils/ChatUtils.java.patch b/patches/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/utils/ChatUtils.java.patch index cd829ff..2c72ec3 100644 --- a/patches/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/utils/ChatUtils.java.patch +++ b/patches/1.18.2/Common/src/main/java/com/hypherionmc/craterlib/utils/ChatUtils.java.patch @@ -73,4 +73,4 @@ + return mojangToAdventure(new TranslatableComponent(Util.makeDescriptionId("biome", identifier.toMojang()))); } - } + public static net.kyori.adventure.text.Component format(String value) { diff --git a/patches/1.18.2/Common/src/main/resources/craterlib.mixins.json.patch b/patches/1.18.2/Common/src/main/resources/craterlib.mixins.json.patch new file mode 100644 index 0000000..30e41c2 --- /dev/null +++ b/patches/1.18.2/Common/src/main/resources/craterlib.mixins.json.patch @@ -0,0 +1,12 @@ +--- a/Common/src/main/resources/craterlib.mixins.json ++++ b/Common/src/main/resources/craterlib.mixins.json +@@ -17,7 +17,8 @@ + "events.PlayerAdvancementsMixin", + "events.PlayerListMixin", + "events.ServerPlayerMixin", +- "events.ServerStatusMixin" ++ "events.ServerStatusMixin", ++ "events.ServerStatusPacketListenerMixin" + ], + "injectors": { + "defaultRequire": 1 diff --git a/patches/1.18.2/Fabric/build.gradle.patch b/patches/1.18.2/Fabric/build.gradle.patch index 29cbdf2..19cd43d 100644 --- a/patches/1.18.2/Fabric/build.gradle.patch +++ b/patches/1.18.2/Fabric/build.gradle.patch @@ -4,8 +4,8 @@ setVersionType("release") setChangelog("https://raw.githubusercontent.com/hypherionmc/changelogs/main/craterlib/changelog-fabric.md") setProjectVersion("${minecraft_version}-${project.version}") -- setDisplayName("[FABRIC/QUILT 1.21.0] CraterLib - ${project.version}") -- setGameVersions("1.21") +- setDisplayName("[FABRIC/QUILT 1.21.x] CraterLib - ${project.version}") +- setGameVersions("1.21", "1.21.1") + setDisplayName("[FABRIC/QUILT 1.18.2] CraterLib - ${project.version}") + setGameVersions("1.18.2") setLoaders("fabric", "quilt") diff --git a/patches/1.18.2/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibInitializer.java.patch b/patches/1.18.2/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibInitializer.java.patch index bce76ef..2a761ad 100644 --- a/patches/1.18.2/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibInitializer.java.patch +++ b/patches/1.18.2/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibInitializer.java.patch @@ -1,7 +1,7 @@ --- a/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibInitializer.java +++ b/Fabric/src/main/java/com/hypherionmc/craterlib/CraterLibInitializer.java -@@ -12,7 +12,7 @@ - import com.hypherionmc.craterlib.nojang.commands.CommandsRegistry; +@@ -11,7 +11,7 @@ + import com.hypherionmc.craterlib.network.CraterFabricNetworkHandler; import com.hypherionmc.craterlib.nojang.server.BridgedMinecraftServer; import net.fabricmc.api.ModInitializer; -import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback; @@ -9,12 +9,12 @@ import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; public class CraterLibInitializer implements ModInitializer { -@@ -20,7 +20,7 @@ +@@ -19,7 +19,7 @@ @Override public void onInitialize() { new CraterPacketNetwork(new CraterFabricNetworkHandler(PacketSide.SERVER)); - CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> { + CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess) -> { - CraterEventBus.INSTANCE.postEvent(new CraterRegisterCommandEvent()); - CommandsRegistry.INSTANCE.registerCommands(dispatcher); + CraterEventBus.INSTANCE.postEvent(new CraterRegisterCommandEvent(dispatcher)); }); + diff --git a/patches/1.18.2/Fabric/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java.patch b/patches/1.18.2/Fabric/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java.patch index 5378caa..01c6e16 100644 --- a/patches/1.18.2/Fabric/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java.patch +++ b/patches/1.18.2/Fabric/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java.patch @@ -24,8 +24,8 @@ cancellable = true ) - private void injectChatEvent(PlayerChatMessage arg, Component arg2, FilteredText arg3, CallbackInfo ci) { -- Component finalArg = arg2 == null ? arg.decoratedContent() : arg2; -- CraterServerChatEvent event = new CraterServerChatEvent(BridgedPlayer.of(this.player), finalArg.getString(), ChatUtils.mojangToAdventure(finalArg)); +- Component finalcomp = arg2 == null ? arg.decoratedContent() : arg2; +- CraterServerChatEvent event = new CraterServerChatEvent(BridgedPlayer.of(this.player), finalcomp.getString(), ChatUtils.mojangToAdventure(finalcomp)); + private void injectChatEvent(TextFilter.FilteredText arg, CallbackInfo ci) { + Component message = new TextComponent(arg.getRaw()); + if (message.getString().startsWith("/")) diff --git a/patches/1.18.2/Fabric/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java.patch b/patches/1.18.2/Fabric/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java.patch new file mode 100644 index 0000000..3026880 --- /dev/null +++ b/patches/1.18.2/Fabric/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java.patch @@ -0,0 +1,55 @@ +--- a/Fabric/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java ++++ /dev/null +@@ -1,52 +1,0 @@ +-package com.hypherionmc.craterlib.mixin; +- +-import com.hypherionmc.craterlib.api.events.server.ServerStatusEvent; +-import com.hypherionmc.craterlib.core.event.CraterEventBus; +-import com.hypherionmc.craterlib.utils.ChatUtils; +-import net.minecraft.network.Connection; +-import net.minecraft.network.protocol.status.ClientboundStatusResponsePacket; +-import net.minecraft.network.protocol.status.ServerStatus; +-import net.minecraft.network.protocol.status.ServerboundStatusRequestPacket; +-import net.minecraft.server.network.ServerStatusPacketListenerImpl; +-import org.spongepowered.asm.mixin.Final; +-import org.spongepowered.asm.mixin.Mixin; +-import org.spongepowered.asm.mixin.Shadow; +-import org.spongepowered.asm.mixin.injection.At; +-import org.spongepowered.asm.mixin.injection.Inject; +-import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +- +-@Mixin(ServerStatusPacketListenerImpl.class) +-public class ServerStatusPacketListenerMixin { +- +- @Shadow +- @Final +- private ServerStatus status; +- +- @Shadow @Final private Connection connection; +- +- @Inject(method = "handleStatusRequest", +- at = @At( +- value = "INVOKE", +- target = "Lnet/minecraft/network/Connection;send(Lnet/minecraft/network/protocol/Packet;)V", +- shift = At.Shift.BEFORE), +- cancellable = true +- ) +- private void injectHandleStatusRequest(ServerboundStatusRequestPacket arg, CallbackInfo ci) { +- ServerStatusEvent.StatusRequestEvent event = new ServerStatusEvent.StatusRequestEvent(ChatUtils.mojangToAdventure(status.description())); +- CraterEventBus.INSTANCE.postEvent(event); +- +- if (event.getNewStatus() != null) { +- ci.cancel(); +- this.connection.send(new ClientboundStatusResponsePacket( +- new ServerStatus(ChatUtils.adventureToMojang( +- event.getNewStatus()), +- status.players(), +- status.version(), +- status.favicon(), +- status.enforcesSecureChat() +- ) +- )); +- } +- } +- +-} diff --git a/patches/1.18.2/Fabric/src/main/resources/craterlib.fabric.mixins.json.patch b/patches/1.18.2/Fabric/src/main/resources/craterlib.fabric.mixins.json.patch new file mode 100644 index 0000000..8586f71 --- /dev/null +++ b/patches/1.18.2/Fabric/src/main/resources/craterlib.fabric.mixins.json.patch @@ -0,0 +1,12 @@ +--- a/Fabric/src/main/resources/craterlib.fabric.mixins.json ++++ b/Fabric/src/main/resources/craterlib.fabric.mixins.json +@@ -9,8 +9,7 @@ + "TutorialMixin" + ], + "server": [ +- "ServerGamePacketListenerImplMixin", +- "ServerStatusPacketListenerMixin" ++ "ServerGamePacketListenerImplMixin" + ], + "injectors": { + "defaultRequire": 1 diff --git a/patches/1.18.2/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeServerEvents.java.patch b/patches/1.18.2/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeServerEvents.java.patch new file mode 100644 index 0000000..c99194b --- /dev/null +++ b/patches/1.18.2/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeServerEvents.java.patch @@ -0,0 +1,20 @@ +--- a/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeServerEvents.java ++++ b/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeServerEvents.java +@@ -3,7 +3,6 @@ + import com.hypherionmc.craterlib.api.events.server.CraterRegisterCommandEvent; + import com.hypherionmc.craterlib.api.events.server.CraterServerLifecycleEvent; + import com.hypherionmc.craterlib.core.event.CraterEventBus; +-import com.hypherionmc.craterlib.nojang.commands.CommandsRegistry; + import com.hypherionmc.craterlib.nojang.server.BridgedMinecraftServer; + import net.minecraftforge.event.RegisterCommandsEvent; + import net.minecraftforge.event.server.ServerStartedEvent; +@@ -36,8 +35,7 @@ + + @SubscribeEvent + public void onCommandRegister(RegisterCommandsEvent event) { +- CraterEventBus.INSTANCE.postEvent(new CraterRegisterCommandEvent()); +- CommandsRegistry.INSTANCE.registerCommands(event.getDispatcher()); ++ CraterEventBus.INSTANCE.postEvent(new CraterRegisterCommandEvent(event.getDispatcher())); + } + + } diff --git a/patches/1.18.2/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java.patch b/patches/1.18.2/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java.patch index 972d75d..1f38ae1 100644 --- a/patches/1.18.2/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java.patch +++ b/patches/1.18.2/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java.patch @@ -1,6 +1,12 @@ --- a/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java +++ b/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java -@@ -6,7 +6,7 @@ +@@ -1,12 +1,12 @@ + package com.hypherionmc.craterlib.mixin; + + import com.hypherionmc.craterlib.client.gui.config.CraterConfigScreen; ++import com.hypherionmc.craterlib.core.config.AbstractConfig; + import com.hypherionmc.craterlib.core.config.ConfigController; +-import com.hypherionmc.craterlib.core.config.ModuleConfig; import com.hypherionmc.craterlib.core.config.annotations.NoConfigScreen; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.screens.Screen; @@ -9,7 +15,7 @@ import net.minecraftforge.forgespi.language.IModInfo; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; -@@ -19,14 +19,14 @@ +@@ -19,18 +19,18 @@ /** * @author HypherionSA */ @@ -24,5 +30,11 @@ - @Inject(at = @At("RETURN"), method = "getScreenFactoryFor", cancellable = true, remap = false) + @Inject(at = @At("RETURN"), method = "getGuiFactoryFor", cancellable = true, remap = false) private static void injectConfigScreen(IModInfo selectedMod, CallbackInfoReturnable>> cir) { - ConfigController.getMonitoredConfigs().forEach((conf, watcher) -> { +- ConfigController.getMonitoredConfigs().forEach((conf, watcher) -> { ++ ConfigController.getWatchedConfigs().forEach((conf, watcher) -> { if (!conf.getClass().isAnnotationPresent(NoConfigScreen.class)) { +- ModuleConfig config = (ModuleConfig) conf; ++ AbstractConfig config = watcher.getLeft(); + if (config.getModId().equals(selectedMod.getModId())) { + cir.setReturnValue( + Optional.of((minecraft, screen) -> new CraterConfigScreen(config, screen)) diff --git a/patches/1.18.2/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java.patch b/patches/1.18.2/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java.patch index 4cf20de..d5d74d2 100644 --- a/patches/1.18.2/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java.patch +++ b/patches/1.18.2/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java.patch @@ -24,8 +24,8 @@ cancellable = true ) - private void injectChatEvent(Component component, PlayerChatMessage arg, FilteredText p_296589_, CallbackInfo ci) { -- Component finalArg = component == null ? arg.decoratedContent() : component; -- CraterServerChatEvent event = new CraterServerChatEvent(BridgedPlayer.of(this.player), finalArg.getString(), ChatUtils.mojangToAdventure(finalArg)); +- Component finalcomp = component == null ? arg.decoratedContent() : component; +- CraterServerChatEvent event = new CraterServerChatEvent(BridgedPlayer.of(this.player), finalcomp.getString(), ChatUtils.mojangToAdventure(finalcomp)); + private void injectChatEvent(TextFilter.FilteredText arg, CallbackInfo ci) { + Component message = new TextComponent(arg.getRaw()); + if (message.getString().startsWith("/")) diff --git a/patches/1.18.2/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java.patch b/patches/1.18.2/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java.patch new file mode 100644 index 0000000..e22d953 --- /dev/null +++ b/patches/1.18.2/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java.patch @@ -0,0 +1,56 @@ +--- a/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java ++++ /dev/null +@@ -1,53 +1,0 @@ +-package com.hypherionmc.craterlib.mixin; +- +-import com.hypherionmc.craterlib.api.events.server.ServerStatusEvent; +-import com.hypherionmc.craterlib.core.event.CraterEventBus; +-import com.hypherionmc.craterlib.utils.ChatUtils; +-import net.minecraft.network.Connection; +-import net.minecraft.network.protocol.status.ClientboundStatusResponsePacket; +-import net.minecraft.network.protocol.status.ServerStatus; +-import net.minecraft.network.protocol.status.ServerboundStatusRequestPacket; +-import net.minecraft.server.network.ServerStatusPacketListenerImpl; +-import org.spongepowered.asm.mixin.Final; +-import org.spongepowered.asm.mixin.Mixin; +-import org.spongepowered.asm.mixin.Shadow; +-import org.spongepowered.asm.mixin.injection.At; +-import org.spongepowered.asm.mixin.injection.Inject; +-import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +- +-@Mixin(ServerStatusPacketListenerImpl.class) +-public class ServerStatusPacketListenerMixin { +- +- @Shadow +- @Final +- private ServerStatus status; +- +- @Shadow @Final private Connection connection; +- +- @Inject(method = "handleStatusRequest", +- at = @At( +- value = "INVOKE", +- target = "Lnet/minecraft/network/Connection;send(Lnet/minecraft/network/protocol/Packet;)V", +- shift = At.Shift.BEFORE), +- cancellable = true +- ) +- private void injectHandleStatusRequest(ServerboundStatusRequestPacket arg, CallbackInfo ci) { +- ServerStatusEvent.StatusRequestEvent event = new ServerStatusEvent.StatusRequestEvent(ChatUtils.mojangToAdventure(status.description())); +- CraterEventBus.INSTANCE.postEvent(event); +- +- if (event.getNewStatus() != null) { +- ci.cancel(); +- this.connection.send(new ClientboundStatusResponsePacket( +- new ServerStatus(ChatUtils.adventureToMojang( +- event.getNewStatus()), +- status.players(), +- status.version(), +- status.favicon(), +- status.enforcesSecureChat(), +- status.isModded() +- ) +- )); +- } +- } +- +-} diff --git a/patches/1.18.2/Forge/src/main/resources/craterlib.forge.mixins.json.patch b/patches/1.18.2/Forge/src/main/resources/craterlib.forge.mixins.json.patch new file mode 100644 index 0000000..1c81cc5 --- /dev/null +++ b/patches/1.18.2/Forge/src/main/resources/craterlib.forge.mixins.json.patch @@ -0,0 +1,12 @@ +--- a/Forge/src/main/resources/craterlib.forge.mixins.json ++++ b/Forge/src/main/resources/craterlib.forge.mixins.json +@@ -9,8 +9,7 @@ + "ConfigScreenHandlerMixin" + ], + "server": [ +- "ServerGamePacketListenerImplMixin", +- "ServerStatusPacketListenerMixin" ++ "ServerGamePacketListenerImplMixin" + ], + "injectors": { + "defaultRequire": 1 diff --git a/patches/1.18.2/NeoForge/build.gradle.patch b/patches/1.18.2/NeoForge/build.gradle.patch index 4a155d8..2ee2c57 100644 --- a/patches/1.18.2/NeoForge/build.gradle.patch +++ b/patches/1.18.2/NeoForge/build.gradle.patch @@ -109,8 +109,8 @@ - setVersionType("release") - setChangelog("https://raw.githubusercontent.com/hypherionmc/changelogs/main/craterlib/changelog-forge.md") - setProjectVersion("${minecraft_version}-${project.version}") -- setDisplayName("[NeoForge 1.21.0] CraterLib - ${project.version}") -- setGameVersions("1.21") +- setDisplayName("[NeoForge 1.21.x] CraterLib - ${project.version}") +- setGameVersions("1.21", "1.21.1") - setLoaders("neoforge") - setArtifact(remapJar) - setCurseEnvironment("both") diff --git a/patches/1.18.2/NeoForge/src/main/java/com/hypherionmc/craterlib/client/NeoForgeClientHelper.java.patch b/patches/1.18.2/NeoForge/src/main/java/com/hypherionmc/craterlib/client/NeoForgeClientHelper.java.patch index a0d386b..6f63513 100644 --- a/patches/1.18.2/NeoForge/src/main/java/com/hypherionmc/craterlib/client/NeoForgeClientHelper.java.patch +++ b/patches/1.18.2/NeoForge/src/main/java/com/hypherionmc/craterlib/client/NeoForgeClientHelper.java.patch @@ -5,8 +5,8 @@ - -import com.hypherionmc.craterlib.api.events.client.LateInitEvent; -import com.hypherionmc.craterlib.client.gui.config.CraterConfigScreen; +-import com.hypherionmc.craterlib.core.config.AbstractConfig; -import com.hypherionmc.craterlib.core.config.ConfigController; --import com.hypherionmc.craterlib.core.config.ModuleConfig; -import com.hypherionmc.craterlib.core.config.annotations.NoConfigScreen; -import com.hypherionmc.craterlib.core.event.CraterEventBus; -import com.hypherionmc.craterlib.core.platform.ClientPlatform; @@ -54,9 +54,9 @@ - LateInitEvent event = new LateInitEvent(new BridgedMinecraft(), BridgedOptions.of(Minecraft.getInstance().options)); - CraterEventBus.INSTANCE.postEvent(event); - -- ConfigController.getMonitoredConfigs().forEach((conf, watcher) -> { +- ConfigController.getWatchedConfigs().forEach((conf, watcher) -> { - if (!conf.getClass().isAnnotationPresent(NoConfigScreen.class)) { -- ModuleConfig config = (ModuleConfig) conf; +- AbstractConfig config = watcher.getLeft(); - ModList.get().getModContainerById(config.getModId()).ifPresent(c -> c.registerExtensionPoint(IConfigScreenFactory.class, ((minecraft, screen) -> new CraterConfigScreen(config, screen)))); - } - }); diff --git a/patches/1.18.2/NeoForge/src/main/java/com/hypherionmc/craterlib/common/NeoForgeServerEvents.java.patch b/patches/1.18.2/NeoForge/src/main/java/com/hypherionmc/craterlib/common/NeoForgeServerEvents.java.patch index 0dab07e..3176ade 100644 --- a/patches/1.18.2/NeoForge/src/main/java/com/hypherionmc/craterlib/common/NeoForgeServerEvents.java.patch +++ b/patches/1.18.2/NeoForge/src/main/java/com/hypherionmc/craterlib/common/NeoForgeServerEvents.java.patch @@ -1,12 +1,11 @@ --- a/NeoForge/src/main/java/com/hypherionmc/craterlib/common/NeoForgeServerEvents.java +++ /dev/null -@@ -1,43 +1,0 @@ +@@ -1,41 +1,0 @@ -package com.hypherionmc.craterlib.common; - -import com.hypherionmc.craterlib.api.events.server.CraterRegisterCommandEvent; -import com.hypherionmc.craterlib.api.events.server.CraterServerLifecycleEvent; -import com.hypherionmc.craterlib.core.event.CraterEventBus; --import com.hypherionmc.craterlib.nojang.commands.CommandsRegistry; -import com.hypherionmc.craterlib.nojang.server.BridgedMinecraftServer; -import net.neoforged.bus.api.SubscribeEvent; -import net.neoforged.neoforge.event.RegisterCommandsEvent; @@ -39,8 +38,7 @@ - - @SubscribeEvent - public void onCommandRegister(RegisterCommandsEvent event) { -- CraterEventBus.INSTANCE.postEvent(new CraterRegisterCommandEvent()); -- CommandsRegistry.INSTANCE.registerCommands(event.getDispatcher()); +- CraterEventBus.INSTANCE.postEvent(new CraterRegisterCommandEvent(event.getDispatcher())); - } - -} diff --git a/patches/1.18.2/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java.patch b/patches/1.18.2/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java.patch index 631e6a6..2f716b8 100644 --- a/patches/1.18.2/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java.patch +++ b/patches/1.18.2/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java.patch @@ -30,8 +30,8 @@ - cancellable = true - ) - private void injectChatEvent(Component component, PlayerChatMessage arg, FilteredText p_296589_, CallbackInfo ci) { -- Component finalArg = component == null ? arg.decoratedContent() : component; -- CraterServerChatEvent event = new CraterServerChatEvent(BridgedPlayer.of(this.player), finalArg.getString(), ChatUtils.mojangToAdventure(finalArg)); +- Component finalcomp = component == null ? arg.decoratedContent() : component; +- CraterServerChatEvent event = new CraterServerChatEvent(BridgedPlayer.of(this.player), finalcomp.getString(), ChatUtils.mojangToAdventure(finalcomp)); - CraterEventBus.INSTANCE.postEvent(event); - if (event.wasCancelled()) - ci.cancel(); diff --git a/patches/1.18.2/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java.patch b/patches/1.18.2/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java.patch new file mode 100644 index 0000000..555de60 --- /dev/null +++ b/patches/1.18.2/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java.patch @@ -0,0 +1,56 @@ +--- a/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java ++++ /dev/null +@@ -1,53 +1,0 @@ +-package com.hypherionmc.craterlib.mixin; +- +-import com.hypherionmc.craterlib.api.events.server.ServerStatusEvent; +-import com.hypherionmc.craterlib.core.event.CraterEventBus; +-import com.hypherionmc.craterlib.utils.ChatUtils; +-import net.minecraft.network.Connection; +-import net.minecraft.network.protocol.status.ClientboundStatusResponsePacket; +-import net.minecraft.network.protocol.status.ServerStatus; +-import net.minecraft.network.protocol.status.ServerboundStatusRequestPacket; +-import net.minecraft.server.network.ServerStatusPacketListenerImpl; +-import org.spongepowered.asm.mixin.Final; +-import org.spongepowered.asm.mixin.Mixin; +-import org.spongepowered.asm.mixin.Shadow; +-import org.spongepowered.asm.mixin.injection.At; +-import org.spongepowered.asm.mixin.injection.Inject; +-import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +- +-@Mixin(ServerStatusPacketListenerImpl.class) +-public class ServerStatusPacketListenerMixin { +- +- @Shadow +- @Final +- private ServerStatus status; +- +- @Shadow @Final private Connection connection; +- +- @Inject(method = "handleStatusRequest", +- at = @At( +- value = "INVOKE", +- target = "Lnet/minecraft/network/Connection;send(Lnet/minecraft/network/protocol/Packet;)V", +- shift = At.Shift.BEFORE), +- cancellable = true +- ) +- private void injectHandleStatusRequest(ServerboundStatusRequestPacket arg, CallbackInfo ci) { +- ServerStatusEvent.StatusRequestEvent event = new ServerStatusEvent.StatusRequestEvent(ChatUtils.mojangToAdventure(status.description())); +- CraterEventBus.INSTANCE.postEvent(event); +- +- if (event.getNewStatus() != null) { +- ci.cancel(); +- this.connection.send(new ClientboundStatusResponsePacket( +- new ServerStatus(ChatUtils.adventureToMojang( +- event.getNewStatus()), +- status.players(), +- status.version(), +- status.favicon(), +- status.enforcesSecureChat(), +- status.isModded() +- ) +- )); +- } +- } +- +-} diff --git a/patches/1.18.2/NeoForge/src/main/resources/craterlib.neoforge.mixins.json.patch b/patches/1.18.2/NeoForge/src/main/resources/craterlib.neoforge.mixins.json.patch index 3732d52..075f957 100644 --- a/patches/1.18.2/NeoForge/src/main/resources/craterlib.neoforge.mixins.json.patch +++ b/patches/1.18.2/NeoForge/src/main/resources/craterlib.neoforge.mixins.json.patch @@ -1,6 +1,6 @@ --- a/NeoForge/src/main/resources/craterlib.neoforge.mixins.json +++ /dev/null -@@ -1,15 +1,0 @@ +@@ -1,16 +1,0 @@ -{ - "required": true, - "minVersion": "0.8", @@ -10,7 +10,8 @@ - ], - "client": [], - "server": [ -- "ServerGamePacketListenerImplMixin" +- "ServerGamePacketListenerImplMixin", +- "ServerStatusPacketListenerMixin" - ], - "injectors": { - "defaultRequire": 1 diff --git a/patches/1.18.2/README.md.patch b/patches/1.18.2/README.md.patch index 5fd4d92..4aea58e 100644 --- a/patches/1.18.2/README.md.patch +++ b/patches/1.18.2/README.md.patch @@ -1,12 +1,10 @@ --- a/README.md +++ b/README.md -@@ -15,8 +15,7 @@ +@@ -15,7 +15,6 @@ | < 1.18.2 | ❌ | | 1.18.2-1.20.2 | ✳️ | | 1.20.4 | ✳️ | -| 1.20.6 | ❌ | --| 1.21 | ✳️ | -+| 1.21 | 🚧 | + | 1.21.x | ✳️ | - ❌ - Not Supported; no bug fixes or new features. - - 🚧 - Work in Progress; not ready for release. diff --git a/patches/1.18.2/build.gradle.patch b/patches/1.18.2/build.gradle.patch index 879d507..890499e 100644 --- a/patches/1.18.2/build.gradle.patch +++ b/patches/1.18.2/build.gradle.patch @@ -11,9 +11,9 @@ group = rootProject.group -@@ -58,7 +58,7 @@ - shade "me.hypherionmc.moon-config:core:${moon_config}" +@@ -59,7 +59,7 @@ shade "me.hypherionmc.moon-config:toml:${moon_config}" + shade "me.hypherionmc.moon-config:json:${moon_config}" shade "com.hypherionmc:rpcsdk:${rpc_sdk}" - shade "me.hypherionmc.sdlink:mcdiscordformatter-1.20.3:${discord_formatter}" + shade "me.hypherionmc.sdlink:mcdiscordformatter-1.18.1:${discord_formatter}" diff --git a/patches/1.19.2/.jenkins/Jenkinsfile.snapshot.patch b/patches/1.19.2/.jenkins/Jenkinsfile.snapshot.patch index 43a8aa4..2c388f3 100644 --- a/patches/1.19.2/.jenkins/Jenkinsfile.snapshot.patch +++ b/patches/1.19.2/.jenkins/Jenkinsfile.snapshot.patch @@ -6,7 +6,7 @@ -def JDK = "21"; -def majorMc = "1.21"; -def modLoaders = "neoforge|fabric|quilt"; --def supportedMc = "1.21"; +-def supportedMc = "1.21|1.21.1"; -def reltype = "port"; +def JDK = "17"; +def majorMc = "1.19.2"; diff --git a/patches/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/SubConfigWidget.java.patch b/patches/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/SubConfigWidget.java.patch index 608d425..4863fd7 100644 --- a/patches/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/SubConfigWidget.java.patch +++ b/patches/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/SubConfigWidget.java.patch @@ -3,7 +3,7 @@ @@ -2,9 +2,9 @@ import com.hypherionmc.craterlib.client.gui.config.CraterConfigScreen; - import com.hypherionmc.craterlib.core.config.ModuleConfig; + import com.hypherionmc.craterlib.core.config.AbstractConfig; +import com.mojang.blaze3d.vertex.PoseStack; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Font; diff --git a/patches/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/ServerStatusMixin.java.patch b/patches/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/ServerStatusMixin.java.patch new file mode 100644 index 0000000..19f9b0f --- /dev/null +++ b/patches/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/ServerStatusMixin.java.patch @@ -0,0 +1,20 @@ +--- a/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/ServerStatusMixin.java ++++ b/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/ServerStatusMixin.java +@@ -14,13 +14,13 @@ + @Mixin(ServerStatus.class) + public class ServerStatusMixin { + +- @Inject(method = "favicon", at = @At("RETURN"), cancellable = true) +- private void injectIconEvent(CallbackInfoReturnable> cir) { +- ServerStatusEvent.FaviconRequestEvent event = new ServerStatusEvent.FaviconRequestEvent(cir.getReturnValue().isEmpty() ? Optional.empty() : Optional.of(new WrappedServerStatus.WrappedFavicon(cir.getReturnValue().get()))); ++ @Inject(method = "getFavicon", at = @At("RETURN"), cancellable = true) ++ private void injectIconEvent(CallbackInfoReturnable cir) { ++ ServerStatusEvent.FaviconRequestEvent event = new ServerStatusEvent.FaviconRequestEvent(cir.getReturnValue().isEmpty() ? Optional.empty() : Optional.of(new WrappedServerStatus.WrappedFavicon(cir.getReturnValue()))); + CraterEventBus.INSTANCE.postEvent(event); + + if (event.getNewIcon().isPresent()) { +- cir.setReturnValue(Optional.of(event.getNewIcon().get().toMojang())); ++ cir.setReturnValue(event.getNewIcon().get().toMojang()); + } + } + diff --git a/patches/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/ServerStatusPacketListenerMixin.java.patch b/patches/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/ServerStatusPacketListenerMixin.java.patch new file mode 100644 index 0000000..0a78917 --- /dev/null +++ b/patches/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/ServerStatusPacketListenerMixin.java.patch @@ -0,0 +1,49 @@ +--- /dev/null ++++ b/Common/src/main/java/com/hypherionmc/craterlib/mixin/events/ServerStatusPacketListenerMixin.java +@@ -1,0 +1,46 @@ ++package com.hypherionmc.craterlib.mixin.events; ++ ++import com.hypherionmc.craterlib.api.events.server.ServerStatusEvent; ++import com.hypherionmc.craterlib.core.event.CraterEventBus; ++import com.hypherionmc.craterlib.utils.ChatUtils; ++import net.minecraft.network.Connection; ++import net.minecraft.network.protocol.status.ClientboundStatusResponsePacket; ++import net.minecraft.network.protocol.status.ServerStatus; ++import net.minecraft.network.protocol.status.ServerboundStatusRequestPacket; ++import net.minecraft.server.MinecraftServer; ++import net.minecraft.server.network.ServerStatusPacketListenerImpl; ++import org.spongepowered.asm.mixin.Final; ++import org.spongepowered.asm.mixin.Mixin; ++import org.spongepowered.asm.mixin.Shadow; ++import org.spongepowered.asm.mixin.injection.At; ++import org.spongepowered.asm.mixin.injection.Inject; ++import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; ++ ++@Mixin(ServerStatusPacketListenerImpl.class) ++public class ServerStatusPacketListenerMixin { ++ ++ @Shadow @Final private Connection connection; ++ ++ @Shadow @Final private MinecraftServer server; ++ ++ @Inject(method = "handleStatusRequest", ++ at = @At( ++ value = "INVOKE", ++ target = "Lnet/minecraft/network/Connection;send(Lnet/minecraft/network/protocol/Packet;)V", ++ shift = At.Shift.BEFORE), ++ cancellable = true ++ ) ++ private void injectHandleStatusRequest(ServerboundStatusRequestPacket arg, CallbackInfo ci) { ++ ServerStatusEvent.StatusRequestEvent event = new ServerStatusEvent.StatusRequestEvent(ChatUtils.mojangToAdventure(server.getStatus().getDescription())); ++ CraterEventBus.INSTANCE.postEvent(event); ++ ++ if (event.getNewStatus() != null) { ++ ci.cancel(); ++ ServerStatus serverStatus = this.server.getStatus(); ++ serverStatus.setDescription(ChatUtils.adventureToMojang(event.getNewStatus())); ++ ++ this.connection.send(new ClientboundStatusResponsePacket(serverStatus)); ++ } ++ } ++ ++} diff --git a/patches/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/BridgedCommandSourceStack.java.patch b/patches/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/BridgedCommandSourceStack.java.patch index 2decb2b..bcb0d0f 100644 --- a/patches/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/BridgedCommandSourceStack.java.patch +++ b/patches/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/BridgedCommandSourceStack.java.patch @@ -8,4 +8,4 @@ + internal.sendSuccess(ChatUtils.adventureToMojang(supplier.get()), bl); } - public CommandSourceStack toMojang() { + public void sendFailure(Component text) { diff --git a/patches/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/nojang/network/protocol/status/WrappedServerStatus.java.patch b/patches/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/nojang/network/protocol/status/WrappedServerStatus.java.patch new file mode 100644 index 0000000..ee6270f --- /dev/null +++ b/patches/1.19.2/Common/src/main/java/com/hypherionmc/craterlib/nojang/network/protocol/status/WrappedServerStatus.java.patch @@ -0,0 +1,46 @@ +--- a/Common/src/main/java/com/hypherionmc/craterlib/nojang/network/protocol/status/WrappedServerStatus.java ++++ b/Common/src/main/java/com/hypherionmc/craterlib/nojang/network/protocol/status/WrappedServerStatus.java +@@ -3,26 +3,38 @@ + import net.minecraft.network.protocol.status.ServerStatus; + import org.jetbrains.annotations.ApiStatus; + ++import java.nio.charset.StandardCharsets; ++import java.util.Base64; ++ + public final class WrappedServerStatus { + + public static final class WrappedFavicon { + +- private final ServerStatus.Favicon internal; ++ private final String internal; ++ private final byte[] iconBytes; + + public WrappedFavicon(byte[] iconBytes) { +- internal = new ServerStatus.Favicon(iconBytes); ++ this.iconBytes = iconBytes; ++ ++ if (iconBytes != null) { ++ byte[] encoded = Base64.getEncoder().encode(iconBytes); ++ internal = "data:image/png;base64," + new String(encoded, StandardCharsets.UTF_8); ++ } else { ++ internal = null; ++ } + } + + @ApiStatus.Internal +- public WrappedFavicon(ServerStatus.Favicon internal) { ++ public WrappedFavicon(String internal) { + this.internal = internal; ++ this.iconBytes = new byte[0]; + } + + public byte[] iconBytes() { +- return internal.iconBytes(); ++ return iconBytes; + } + +- public ServerStatus.Favicon toMojang() { ++ public String toMojang() { + return internal; + } + diff --git a/patches/1.19.2/Common/src/main/resources/craterlib.mixins.json.patch b/patches/1.19.2/Common/src/main/resources/craterlib.mixins.json.patch new file mode 100644 index 0000000..30e41c2 --- /dev/null +++ b/patches/1.19.2/Common/src/main/resources/craterlib.mixins.json.patch @@ -0,0 +1,12 @@ +--- a/Common/src/main/resources/craterlib.mixins.json ++++ b/Common/src/main/resources/craterlib.mixins.json +@@ -17,7 +17,8 @@ + "events.PlayerAdvancementsMixin", + "events.PlayerListMixin", + "events.ServerPlayerMixin", +- "events.ServerStatusMixin" ++ "events.ServerStatusMixin", ++ "events.ServerStatusPacketListenerMixin" + ], + "injectors": { + "defaultRequire": 1 diff --git a/patches/1.19.2/Fabric/build.gradle.patch b/patches/1.19.2/Fabric/build.gradle.patch index 5af4dbc..6d35248 100644 --- a/patches/1.19.2/Fabric/build.gradle.patch +++ b/patches/1.19.2/Fabric/build.gradle.patch @@ -4,8 +4,8 @@ setVersionType("release") setChangelog("https://raw.githubusercontent.com/hypherionmc/changelogs/main/craterlib/changelog-fabric.md") setProjectVersion("${minecraft_version}-${project.version}") -- setDisplayName("[FABRIC/QUILT 1.21.0] CraterLib - ${project.version}") -- setGameVersions("1.21") +- setDisplayName("[FABRIC/QUILT 1.21.x] CraterLib - ${project.version}") +- setGameVersions("1.21", "1.21.1") + setDisplayName("[FABRIC/QUILT 1.19.2] CraterLib - ${project.version}") + setGameVersions("1.19.2") setLoaders("fabric", "quilt") diff --git a/patches/1.19.2/Fabric/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java.patch b/patches/1.19.2/Fabric/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java.patch index 73b23d3..f078d8c 100644 --- a/patches/1.19.2/Fabric/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java.patch +++ b/patches/1.19.2/Fabric/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java.patch @@ -30,8 +30,8 @@ cancellable = true ) - private void injectChatEvent(PlayerChatMessage arg, Component arg2, FilteredText arg3, CallbackInfo ci) { -- Component finalArg = arg2 == null ? arg.decoratedContent() : arg2; -- CraterServerChatEvent event = new CraterServerChatEvent(BridgedPlayer.of(this.player), finalArg.getString(), ChatUtils.mojangToAdventure(finalArg)); +- Component finalcomp = arg2 == null ? arg.decoratedContent() : arg2; +- CraterServerChatEvent event = new CraterServerChatEvent(BridgedPlayer.of(this.player), finalcomp.getString(), ChatUtils.mojangToAdventure(finalcomp)); + private void injectChatEvent(PlayerChatMessage arg, CallbackInfoReturnable ci) { + CraterServerChatEvent event = new CraterServerChatEvent(BridgedPlayer.of(this.player), arg.serverContent().getString(), ChatUtils.mojangToAdventure(arg.serverContent())); CraterEventBus.INSTANCE.postEvent(event); diff --git a/patches/1.19.2/Fabric/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java.patch b/patches/1.19.2/Fabric/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java.patch new file mode 100644 index 0000000..3026880 --- /dev/null +++ b/patches/1.19.2/Fabric/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java.patch @@ -0,0 +1,55 @@ +--- a/Fabric/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java ++++ /dev/null +@@ -1,52 +1,0 @@ +-package com.hypherionmc.craterlib.mixin; +- +-import com.hypherionmc.craterlib.api.events.server.ServerStatusEvent; +-import com.hypherionmc.craterlib.core.event.CraterEventBus; +-import com.hypherionmc.craterlib.utils.ChatUtils; +-import net.minecraft.network.Connection; +-import net.minecraft.network.protocol.status.ClientboundStatusResponsePacket; +-import net.minecraft.network.protocol.status.ServerStatus; +-import net.minecraft.network.protocol.status.ServerboundStatusRequestPacket; +-import net.minecraft.server.network.ServerStatusPacketListenerImpl; +-import org.spongepowered.asm.mixin.Final; +-import org.spongepowered.asm.mixin.Mixin; +-import org.spongepowered.asm.mixin.Shadow; +-import org.spongepowered.asm.mixin.injection.At; +-import org.spongepowered.asm.mixin.injection.Inject; +-import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +- +-@Mixin(ServerStatusPacketListenerImpl.class) +-public class ServerStatusPacketListenerMixin { +- +- @Shadow +- @Final +- private ServerStatus status; +- +- @Shadow @Final private Connection connection; +- +- @Inject(method = "handleStatusRequest", +- at = @At( +- value = "INVOKE", +- target = "Lnet/minecraft/network/Connection;send(Lnet/minecraft/network/protocol/Packet;)V", +- shift = At.Shift.BEFORE), +- cancellable = true +- ) +- private void injectHandleStatusRequest(ServerboundStatusRequestPacket arg, CallbackInfo ci) { +- ServerStatusEvent.StatusRequestEvent event = new ServerStatusEvent.StatusRequestEvent(ChatUtils.mojangToAdventure(status.description())); +- CraterEventBus.INSTANCE.postEvent(event); +- +- if (event.getNewStatus() != null) { +- ci.cancel(); +- this.connection.send(new ClientboundStatusResponsePacket( +- new ServerStatus(ChatUtils.adventureToMojang( +- event.getNewStatus()), +- status.players(), +- status.version(), +- status.favicon(), +- status.enforcesSecureChat() +- ) +- )); +- } +- } +- +-} diff --git a/patches/1.19.2/Fabric/src/main/resources/craterlib.fabric.mixins.json.patch b/patches/1.19.2/Fabric/src/main/resources/craterlib.fabric.mixins.json.patch new file mode 100644 index 0000000..8586f71 --- /dev/null +++ b/patches/1.19.2/Fabric/src/main/resources/craterlib.fabric.mixins.json.patch @@ -0,0 +1,12 @@ +--- a/Fabric/src/main/resources/craterlib.fabric.mixins.json ++++ b/Fabric/src/main/resources/craterlib.fabric.mixins.json +@@ -9,8 +9,7 @@ + "TutorialMixin" + ], + "server": [ +- "ServerGamePacketListenerImplMixin", +- "ServerStatusPacketListenerMixin" ++ "ServerGamePacketListenerImplMixin" + ], + "injectors": { + "defaultRequire": 1 diff --git a/patches/1.19.2/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeServerEvents.java.patch b/patches/1.19.2/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeServerEvents.java.patch new file mode 100644 index 0000000..c99194b --- /dev/null +++ b/patches/1.19.2/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeServerEvents.java.patch @@ -0,0 +1,20 @@ +--- a/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeServerEvents.java ++++ b/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeServerEvents.java +@@ -3,7 +3,6 @@ + import com.hypherionmc.craterlib.api.events.server.CraterRegisterCommandEvent; + import com.hypherionmc.craterlib.api.events.server.CraterServerLifecycleEvent; + import com.hypherionmc.craterlib.core.event.CraterEventBus; +-import com.hypherionmc.craterlib.nojang.commands.CommandsRegistry; + import com.hypherionmc.craterlib.nojang.server.BridgedMinecraftServer; + import net.minecraftforge.event.RegisterCommandsEvent; + import net.minecraftforge.event.server.ServerStartedEvent; +@@ -36,8 +35,7 @@ + + @SubscribeEvent + public void onCommandRegister(RegisterCommandsEvent event) { +- CraterEventBus.INSTANCE.postEvent(new CraterRegisterCommandEvent()); +- CommandsRegistry.INSTANCE.registerCommands(event.getDispatcher()); ++ CraterEventBus.INSTANCE.postEvent(new CraterRegisterCommandEvent(event.getDispatcher())); + } + + } diff --git a/patches/1.19.2/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java.patch b/patches/1.19.2/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java.patch new file mode 100644 index 0000000..b5243f2 --- /dev/null +++ b/patches/1.19.2/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java.patch @@ -0,0 +1,24 @@ +--- a/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java ++++ b/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java +@@ -1,8 +1,8 @@ + package com.hypherionmc.craterlib.mixin; + + import com.hypherionmc.craterlib.client.gui.config.CraterConfigScreen; ++import com.hypherionmc.craterlib.core.config.AbstractConfig; + import com.hypherionmc.craterlib.core.config.ConfigController; +-import com.hypherionmc.craterlib.core.config.ModuleConfig; + import com.hypherionmc.craterlib.core.config.annotations.NoConfigScreen; + import net.minecraft.client.Minecraft; + import net.minecraft.client.gui.screens.Screen; +@@ -28,9 +28,9 @@ + */ + @Inject(at = @At("RETURN"), method = "getScreenFactoryFor", cancellable = true, remap = false) + private static void injectConfigScreen(IModInfo selectedMod, CallbackInfoReturnable>> cir) { +- ConfigController.getMonitoredConfigs().forEach((conf, watcher) -> { ++ ConfigController.getWatchedConfigs().forEach((conf, watcher) -> { + if (!conf.getClass().isAnnotationPresent(NoConfigScreen.class)) { +- ModuleConfig config = (ModuleConfig) conf; ++ AbstractConfig config = watcher.getLeft(); + if (config.getModId().equals(selectedMod.getModId())) { + cir.setReturnValue( + Optional.of((minecraft, screen) -> new CraterConfigScreen(config, screen)) diff --git a/patches/1.19.2/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java.patch b/patches/1.19.2/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java.patch index e153a68..e62e699 100644 --- a/patches/1.19.2/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java.patch +++ b/patches/1.19.2/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java.patch @@ -30,8 +30,8 @@ cancellable = true ) - private void injectChatEvent(Component component, PlayerChatMessage arg, FilteredText p_296589_, CallbackInfo ci) { -- Component finalArg = component == null ? arg.decoratedContent() : component; -- CraterServerChatEvent event = new CraterServerChatEvent(BridgedPlayer.of(this.player), finalArg.getString(), ChatUtils.mojangToAdventure(finalArg)); +- Component finalcomp = component == null ? arg.decoratedContent() : component; +- CraterServerChatEvent event = new CraterServerChatEvent(BridgedPlayer.of(this.player), finalcomp.getString(), ChatUtils.mojangToAdventure(finalcomp)); + private void injectChatEvent(PlayerChatMessage arg, CallbackInfoReturnable ci) { + CraterServerChatEvent event = new CraterServerChatEvent(BridgedPlayer.of(this.player), arg.serverContent().getString(), ChatUtils.mojangToAdventure(arg.serverContent())); CraterEventBus.INSTANCE.postEvent(event); diff --git a/patches/1.19.2/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java.patch b/patches/1.19.2/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java.patch new file mode 100644 index 0000000..e22d953 --- /dev/null +++ b/patches/1.19.2/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java.patch @@ -0,0 +1,56 @@ +--- a/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java ++++ /dev/null +@@ -1,53 +1,0 @@ +-package com.hypherionmc.craterlib.mixin; +- +-import com.hypherionmc.craterlib.api.events.server.ServerStatusEvent; +-import com.hypherionmc.craterlib.core.event.CraterEventBus; +-import com.hypherionmc.craterlib.utils.ChatUtils; +-import net.minecraft.network.Connection; +-import net.minecraft.network.protocol.status.ClientboundStatusResponsePacket; +-import net.minecraft.network.protocol.status.ServerStatus; +-import net.minecraft.network.protocol.status.ServerboundStatusRequestPacket; +-import net.minecraft.server.network.ServerStatusPacketListenerImpl; +-import org.spongepowered.asm.mixin.Final; +-import org.spongepowered.asm.mixin.Mixin; +-import org.spongepowered.asm.mixin.Shadow; +-import org.spongepowered.asm.mixin.injection.At; +-import org.spongepowered.asm.mixin.injection.Inject; +-import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +- +-@Mixin(ServerStatusPacketListenerImpl.class) +-public class ServerStatusPacketListenerMixin { +- +- @Shadow +- @Final +- private ServerStatus status; +- +- @Shadow @Final private Connection connection; +- +- @Inject(method = "handleStatusRequest", +- at = @At( +- value = "INVOKE", +- target = "Lnet/minecraft/network/Connection;send(Lnet/minecraft/network/protocol/Packet;)V", +- shift = At.Shift.BEFORE), +- cancellable = true +- ) +- private void injectHandleStatusRequest(ServerboundStatusRequestPacket arg, CallbackInfo ci) { +- ServerStatusEvent.StatusRequestEvent event = new ServerStatusEvent.StatusRequestEvent(ChatUtils.mojangToAdventure(status.description())); +- CraterEventBus.INSTANCE.postEvent(event); +- +- if (event.getNewStatus() != null) { +- ci.cancel(); +- this.connection.send(new ClientboundStatusResponsePacket( +- new ServerStatus(ChatUtils.adventureToMojang( +- event.getNewStatus()), +- status.players(), +- status.version(), +- status.favicon(), +- status.enforcesSecureChat(), +- status.isModded() +- ) +- )); +- } +- } +- +-} diff --git a/patches/1.19.2/Forge/src/main/resources/craterlib.forge.mixins.json.patch b/patches/1.19.2/Forge/src/main/resources/craterlib.forge.mixins.json.patch new file mode 100644 index 0000000..1c81cc5 --- /dev/null +++ b/patches/1.19.2/Forge/src/main/resources/craterlib.forge.mixins.json.patch @@ -0,0 +1,12 @@ +--- a/Forge/src/main/resources/craterlib.forge.mixins.json ++++ b/Forge/src/main/resources/craterlib.forge.mixins.json +@@ -9,8 +9,7 @@ + "ConfigScreenHandlerMixin" + ], + "server": [ +- "ServerGamePacketListenerImplMixin", +- "ServerStatusPacketListenerMixin" ++ "ServerGamePacketListenerImplMixin" + ], + "injectors": { + "defaultRequire": 1 diff --git a/patches/1.19.2/NeoForge/build.gradle.patch b/patches/1.19.2/NeoForge/build.gradle.patch index 4a155d8..2ee2c57 100644 --- a/patches/1.19.2/NeoForge/build.gradle.patch +++ b/patches/1.19.2/NeoForge/build.gradle.patch @@ -109,8 +109,8 @@ - setVersionType("release") - setChangelog("https://raw.githubusercontent.com/hypherionmc/changelogs/main/craterlib/changelog-forge.md") - setProjectVersion("${minecraft_version}-${project.version}") -- setDisplayName("[NeoForge 1.21.0] CraterLib - ${project.version}") -- setGameVersions("1.21") +- setDisplayName("[NeoForge 1.21.x] CraterLib - ${project.version}") +- setGameVersions("1.21", "1.21.1") - setLoaders("neoforge") - setArtifact(remapJar) - setCurseEnvironment("both") diff --git a/patches/1.19.2/NeoForge/src/main/java/com/hypherionmc/craterlib/client/NeoForgeClientHelper.java.patch b/patches/1.19.2/NeoForge/src/main/java/com/hypherionmc/craterlib/client/NeoForgeClientHelper.java.patch index a0d386b..6f63513 100644 --- a/patches/1.19.2/NeoForge/src/main/java/com/hypherionmc/craterlib/client/NeoForgeClientHelper.java.patch +++ b/patches/1.19.2/NeoForge/src/main/java/com/hypherionmc/craterlib/client/NeoForgeClientHelper.java.patch @@ -5,8 +5,8 @@ - -import com.hypherionmc.craterlib.api.events.client.LateInitEvent; -import com.hypherionmc.craterlib.client.gui.config.CraterConfigScreen; +-import com.hypherionmc.craterlib.core.config.AbstractConfig; -import com.hypherionmc.craterlib.core.config.ConfigController; --import com.hypherionmc.craterlib.core.config.ModuleConfig; -import com.hypherionmc.craterlib.core.config.annotations.NoConfigScreen; -import com.hypherionmc.craterlib.core.event.CraterEventBus; -import com.hypherionmc.craterlib.core.platform.ClientPlatform; @@ -54,9 +54,9 @@ - LateInitEvent event = new LateInitEvent(new BridgedMinecraft(), BridgedOptions.of(Minecraft.getInstance().options)); - CraterEventBus.INSTANCE.postEvent(event); - -- ConfigController.getMonitoredConfigs().forEach((conf, watcher) -> { +- ConfigController.getWatchedConfigs().forEach((conf, watcher) -> { - if (!conf.getClass().isAnnotationPresent(NoConfigScreen.class)) { -- ModuleConfig config = (ModuleConfig) conf; +- AbstractConfig config = watcher.getLeft(); - ModList.get().getModContainerById(config.getModId()).ifPresent(c -> c.registerExtensionPoint(IConfigScreenFactory.class, ((minecraft, screen) -> new CraterConfigScreen(config, screen)))); - } - }); diff --git a/patches/1.19.2/NeoForge/src/main/java/com/hypherionmc/craterlib/common/NeoForgeServerEvents.java.patch b/patches/1.19.2/NeoForge/src/main/java/com/hypherionmc/craterlib/common/NeoForgeServerEvents.java.patch index 0dab07e..3176ade 100644 --- a/patches/1.19.2/NeoForge/src/main/java/com/hypherionmc/craterlib/common/NeoForgeServerEvents.java.patch +++ b/patches/1.19.2/NeoForge/src/main/java/com/hypherionmc/craterlib/common/NeoForgeServerEvents.java.patch @@ -1,12 +1,11 @@ --- a/NeoForge/src/main/java/com/hypherionmc/craterlib/common/NeoForgeServerEvents.java +++ /dev/null -@@ -1,43 +1,0 @@ +@@ -1,41 +1,0 @@ -package com.hypherionmc.craterlib.common; - -import com.hypherionmc.craterlib.api.events.server.CraterRegisterCommandEvent; -import com.hypherionmc.craterlib.api.events.server.CraterServerLifecycleEvent; -import com.hypherionmc.craterlib.core.event.CraterEventBus; --import com.hypherionmc.craterlib.nojang.commands.CommandsRegistry; -import com.hypherionmc.craterlib.nojang.server.BridgedMinecraftServer; -import net.neoforged.bus.api.SubscribeEvent; -import net.neoforged.neoforge.event.RegisterCommandsEvent; @@ -39,8 +38,7 @@ - - @SubscribeEvent - public void onCommandRegister(RegisterCommandsEvent event) { -- CraterEventBus.INSTANCE.postEvent(new CraterRegisterCommandEvent()); -- CommandsRegistry.INSTANCE.registerCommands(event.getDispatcher()); +- CraterEventBus.INSTANCE.postEvent(new CraterRegisterCommandEvent(event.getDispatcher())); - } - -} diff --git a/patches/1.19.2/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java.patch b/patches/1.19.2/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java.patch index 631e6a6..2f716b8 100644 --- a/patches/1.19.2/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java.patch +++ b/patches/1.19.2/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java.patch @@ -30,8 +30,8 @@ - cancellable = true - ) - private void injectChatEvent(Component component, PlayerChatMessage arg, FilteredText p_296589_, CallbackInfo ci) { -- Component finalArg = component == null ? arg.decoratedContent() : component; -- CraterServerChatEvent event = new CraterServerChatEvent(BridgedPlayer.of(this.player), finalArg.getString(), ChatUtils.mojangToAdventure(finalArg)); +- Component finalcomp = component == null ? arg.decoratedContent() : component; +- CraterServerChatEvent event = new CraterServerChatEvent(BridgedPlayer.of(this.player), finalcomp.getString(), ChatUtils.mojangToAdventure(finalcomp)); - CraterEventBus.INSTANCE.postEvent(event); - if (event.wasCancelled()) - ci.cancel(); diff --git a/patches/1.19.2/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java.patch b/patches/1.19.2/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java.patch new file mode 100644 index 0000000..555de60 --- /dev/null +++ b/patches/1.19.2/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java.patch @@ -0,0 +1,56 @@ +--- a/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java ++++ /dev/null +@@ -1,53 +1,0 @@ +-package com.hypherionmc.craterlib.mixin; +- +-import com.hypherionmc.craterlib.api.events.server.ServerStatusEvent; +-import com.hypherionmc.craterlib.core.event.CraterEventBus; +-import com.hypherionmc.craterlib.utils.ChatUtils; +-import net.minecraft.network.Connection; +-import net.minecraft.network.protocol.status.ClientboundStatusResponsePacket; +-import net.minecraft.network.protocol.status.ServerStatus; +-import net.minecraft.network.protocol.status.ServerboundStatusRequestPacket; +-import net.minecraft.server.network.ServerStatusPacketListenerImpl; +-import org.spongepowered.asm.mixin.Final; +-import org.spongepowered.asm.mixin.Mixin; +-import org.spongepowered.asm.mixin.Shadow; +-import org.spongepowered.asm.mixin.injection.At; +-import org.spongepowered.asm.mixin.injection.Inject; +-import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +- +-@Mixin(ServerStatusPacketListenerImpl.class) +-public class ServerStatusPacketListenerMixin { +- +- @Shadow +- @Final +- private ServerStatus status; +- +- @Shadow @Final private Connection connection; +- +- @Inject(method = "handleStatusRequest", +- at = @At( +- value = "INVOKE", +- target = "Lnet/minecraft/network/Connection;send(Lnet/minecraft/network/protocol/Packet;)V", +- shift = At.Shift.BEFORE), +- cancellable = true +- ) +- private void injectHandleStatusRequest(ServerboundStatusRequestPacket arg, CallbackInfo ci) { +- ServerStatusEvent.StatusRequestEvent event = new ServerStatusEvent.StatusRequestEvent(ChatUtils.mojangToAdventure(status.description())); +- CraterEventBus.INSTANCE.postEvent(event); +- +- if (event.getNewStatus() != null) { +- ci.cancel(); +- this.connection.send(new ClientboundStatusResponsePacket( +- new ServerStatus(ChatUtils.adventureToMojang( +- event.getNewStatus()), +- status.players(), +- status.version(), +- status.favicon(), +- status.enforcesSecureChat(), +- status.isModded() +- ) +- )); +- } +- } +- +-} diff --git a/patches/1.19.2/NeoForge/src/main/resources/craterlib.neoforge.mixins.json.patch b/patches/1.19.2/NeoForge/src/main/resources/craterlib.neoforge.mixins.json.patch index 3732d52..075f957 100644 --- a/patches/1.19.2/NeoForge/src/main/resources/craterlib.neoforge.mixins.json.patch +++ b/patches/1.19.2/NeoForge/src/main/resources/craterlib.neoforge.mixins.json.patch @@ -1,6 +1,6 @@ --- a/NeoForge/src/main/resources/craterlib.neoforge.mixins.json +++ /dev/null -@@ -1,15 +1,0 @@ +@@ -1,16 +1,0 @@ -{ - "required": true, - "minVersion": "0.8", @@ -10,7 +10,8 @@ - ], - "client": [], - "server": [ -- "ServerGamePacketListenerImplMixin" +- "ServerGamePacketListenerImplMixin", +- "ServerStatusPacketListenerMixin" - ], - "injectors": { - "defaultRequire": 1 diff --git a/patches/1.19.2/README.md.patch b/patches/1.19.2/README.md.patch index 5fd4d92..4aea58e 100644 --- a/patches/1.19.2/README.md.patch +++ b/patches/1.19.2/README.md.patch @@ -1,12 +1,10 @@ --- a/README.md +++ b/README.md -@@ -15,8 +15,7 @@ +@@ -15,7 +15,6 @@ | < 1.18.2 | ❌ | | 1.18.2-1.20.2 | ✳️ | | 1.20.4 | ✳️ | -| 1.20.6 | ❌ | --| 1.21 | ✳️ | -+| 1.21 | 🚧 | + | 1.21.x | ✳️ | - ❌ - Not Supported; no bug fixes or new features. - - 🚧 - Work in Progress; not ready for release. diff --git a/patches/1.19.2/build.gradle.patch b/patches/1.19.2/build.gradle.patch index 4252ab9..b6610ca 100644 --- a/patches/1.19.2/build.gradle.patch +++ b/patches/1.19.2/build.gradle.patch @@ -11,9 +11,9 @@ group = rootProject.group -@@ -58,7 +58,7 @@ - shade "me.hypherionmc.moon-config:core:${moon_config}" +@@ -59,7 +59,7 @@ shade "me.hypherionmc.moon-config:toml:${moon_config}" + shade "me.hypherionmc.moon-config:json:${moon_config}" shade "com.hypherionmc:rpcsdk:${rpc_sdk}" - shade "me.hypherionmc.sdlink:mcdiscordformatter-1.20.3:${discord_formatter}" + shade "me.hypherionmc.sdlink:mcdiscordformatter-1.19.1:${discord_formatter}" diff --git a/patches/1.19.3/.jenkins/Jenkinsfile.snapshot.patch b/patches/1.19.3/.jenkins/Jenkinsfile.snapshot.patch index 72841ab..29cfe6e 100644 --- a/patches/1.19.3/.jenkins/Jenkinsfile.snapshot.patch +++ b/patches/1.19.3/.jenkins/Jenkinsfile.snapshot.patch @@ -6,12 +6,12 @@ -def JDK = "21"; -def majorMc = "1.21"; -def modLoaders = "neoforge|fabric|quilt"; --def supportedMc = "1.21"; +-def supportedMc = "1.21|1.21.1"; -def reltype = "port"; +def JDK = "17"; +def majorMc = "1.19.3"; +def modLoaders = "forge|fabric|quilt"; -+def supportedMc = "1.19.3|1.19.4"; ++def supportedMc = "1.19.4"; +def reltype = "snapshot"; pipeline { diff --git a/patches/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/SubConfigWidget.java.patch b/patches/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/SubConfigWidget.java.patch index 1a77936..ebe8f79 100644 --- a/patches/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/SubConfigWidget.java.patch +++ b/patches/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/client/gui/config/widgets/SubConfigWidget.java.patch @@ -3,7 +3,7 @@ @@ -2,9 +2,9 @@ import com.hypherionmc.craterlib.client.gui.config.CraterConfigScreen; - import com.hypherionmc.craterlib.core.config.ModuleConfig; + import com.hypherionmc.craterlib.core.config.AbstractConfig; +import com.mojang.blaze3d.vertex.PoseStack; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Font; diff --git a/patches/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/BridgedCommandSourceStack.java.patch b/patches/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/BridgedCommandSourceStack.java.patch index 2decb2b..bcb0d0f 100644 --- a/patches/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/BridgedCommandSourceStack.java.patch +++ b/patches/1.19.3/Common/src/main/java/com/hypherionmc/craterlib/nojang/commands/BridgedCommandSourceStack.java.patch @@ -8,4 +8,4 @@ + internal.sendSuccess(ChatUtils.adventureToMojang(supplier.get()), bl); } - public CommandSourceStack toMojang() { + public void sendFailure(Component text) { diff --git a/patches/1.19.3/Fabric/build.gradle.patch b/patches/1.19.3/Fabric/build.gradle.patch index 33b5cca..2f95c6e 100644 --- a/patches/1.19.3/Fabric/build.gradle.patch +++ b/patches/1.19.3/Fabric/build.gradle.patch @@ -4,10 +4,10 @@ setVersionType("release") setChangelog("https://raw.githubusercontent.com/hypherionmc/changelogs/main/craterlib/changelog-fabric.md") setProjectVersion("${minecraft_version}-${project.version}") -- setDisplayName("[FABRIC/QUILT 1.21.0] CraterLib - ${project.version}") -- setGameVersions("1.21") -+ setDisplayName("[FABRIC/QUILT 1.19.3/1.19.4] CraterLib - ${project.version}") -+ setGameVersions("1.19.3", "1.19.4") +- setDisplayName("[FABRIC/QUILT 1.21.x] CraterLib - ${project.version}") +- setGameVersions("1.21", "1.21.1") ++ setDisplayName("[FABRIC/QUILT 1.19.4] CraterLib - ${project.version}") ++ setGameVersions("1.19.4") setLoaders("fabric", "quilt") setArtifact(remapJar) setCurseEnvironment("both") diff --git a/patches/1.19.3/Fabric/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java.patch b/patches/1.19.3/Fabric/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java.patch index 8dbf2df..b3e764e 100644 --- a/patches/1.19.3/Fabric/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java.patch +++ b/patches/1.19.3/Fabric/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java.patch @@ -21,11 +21,12 @@ cancellable = true ) - private void injectChatEvent(PlayerChatMessage arg, Component arg2, FilteredText arg3, CallbackInfo ci) { -- Component finalArg = arg2 == null ? arg.decoratedContent() : arg2; +- Component finalcomp = arg2 == null ? arg.decoratedContent() : arg2; +- CraterServerChatEvent event = new CraterServerChatEvent(BridgedPlayer.of(this.player), finalcomp.getString(), ChatUtils.mojangToAdventure(finalcomp)); + private void injectChatEvent(CompletableFuture completableFuture, CompletableFuture completableFuture2, PlayerChatMessage arg, Executor executor, CallbackInfoReturnable cir) { + Component comp2 = completableFuture2.join(); + Component finalArg = comp2 == null ? arg.decoratedContent() : comp2; - CraterServerChatEvent event = new CraterServerChatEvent(BridgedPlayer.of(this.player), finalArg.getString(), ChatUtils.mojangToAdventure(finalArg)); ++ CraterServerChatEvent event = new CraterServerChatEvent(BridgedPlayer.of(this.player), finalArg.getString(), ChatUtils.mojangToAdventure(finalArg)); CraterEventBus.INSTANCE.postEvent(event); if (event.wasCancelled()) - ci.cancel(); diff --git a/patches/1.19.3/Fabric/src/main/resources/fabric.mod.json.patch b/patches/1.19.3/Fabric/src/main/resources/fabric.mod.json.patch index 4cd15d4..7c75111 100644 --- a/patches/1.19.3/Fabric/src/main/resources/fabric.mod.json.patch +++ b/patches/1.19.3/Fabric/src/main/resources/fabric.mod.json.patch @@ -6,7 +6,7 @@ "fabric-api": "*", - "minecraft": ">=1.21", - "java": ">=21" -+ "minecraft": ">=1.19.3", ++ "minecraft": ">=1.19.4", + "java": ">=17" } } diff --git a/patches/1.19.3/Forge/build.gradle.patch b/patches/1.19.3/Forge/build.gradle.patch index ec5adc7..0cbfa3b 100644 --- a/patches/1.19.3/Forge/build.gradle.patch +++ b/patches/1.19.3/Forge/build.gradle.patch @@ -15,8 +15,8 @@ setProjectVersion("${minecraft_version}-${project.version}") - setDisplayName("[Forge 1.20.6] CraterLib - ${project.version}") - setGameVersions("1.20.6") -+ setDisplayName("[Forge 1.19.3/1.19.4] CraterLib - ${project.version}") -+ setGameVersions("1.19.3", "1.19.4") ++ setDisplayName("[Forge 1.19.4] CraterLib - ${project.version}") ++ setGameVersions("1.19.4") setLoaders("forge") setArtifact(remapJar) setCurseEnvironment("both") diff --git a/patches/1.19.3/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeServerEvents.java.patch b/patches/1.19.3/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeServerEvents.java.patch new file mode 100644 index 0000000..c99194b --- /dev/null +++ b/patches/1.19.3/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeServerEvents.java.patch @@ -0,0 +1,20 @@ +--- a/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeServerEvents.java ++++ b/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeServerEvents.java +@@ -3,7 +3,6 @@ + import com.hypherionmc.craterlib.api.events.server.CraterRegisterCommandEvent; + import com.hypherionmc.craterlib.api.events.server.CraterServerLifecycleEvent; + import com.hypherionmc.craterlib.core.event.CraterEventBus; +-import com.hypherionmc.craterlib.nojang.commands.CommandsRegistry; + import com.hypherionmc.craterlib.nojang.server.BridgedMinecraftServer; + import net.minecraftforge.event.RegisterCommandsEvent; + import net.minecraftforge.event.server.ServerStartedEvent; +@@ -36,8 +35,7 @@ + + @SubscribeEvent + public void onCommandRegister(RegisterCommandsEvent event) { +- CraterEventBus.INSTANCE.postEvent(new CraterRegisterCommandEvent()); +- CommandsRegistry.INSTANCE.registerCommands(event.getDispatcher()); ++ CraterEventBus.INSTANCE.postEvent(new CraterRegisterCommandEvent(event.getDispatcher())); + } + + } diff --git a/patches/1.19.3/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java.patch b/patches/1.19.3/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java.patch new file mode 100644 index 0000000..5f8832b --- /dev/null +++ b/patches/1.19.3/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java.patch @@ -0,0 +1,22 @@ +--- a/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java ++++ b/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java +@@ -1,6 +1,7 @@ + package com.hypherionmc.craterlib.mixin; + + import com.hypherionmc.craterlib.client.gui.config.CraterConfigScreen; ++import com.hypherionmc.craterlib.core.config.AbstractConfig; + import com.hypherionmc.craterlib.core.config.ConfigController; + import com.hypherionmc.craterlib.core.config.ModuleConfig; + import com.hypherionmc.craterlib.core.config.annotations.NoConfigScreen; +@@ -28,9 +29,9 @@ + */ + @Inject(at = @At("RETURN"), method = "getScreenFactoryFor", cancellable = true, remap = false) + private static void injectConfigScreen(IModInfo selectedMod, CallbackInfoReturnable>> cir) { +- ConfigController.getMonitoredConfigs().forEach((conf, watcher) -> { ++ ConfigController.getWatchedConfigs().forEach((conf, watcher) -> { + if (!conf.getClass().isAnnotationPresent(NoConfigScreen.class)) { +- ModuleConfig config = (ModuleConfig) conf; ++ AbstractConfig config = watcher.getLeft(); + if (config.getModId().equals(selectedMod.getModId())) { + cir.setReturnValue( + Optional.of((minecraft, screen) -> new CraterConfigScreen(config, screen)) diff --git a/patches/1.19.3/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java.patch b/patches/1.19.3/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java.patch index 411181d..aac1c84 100644 --- a/patches/1.19.3/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java.patch +++ b/patches/1.19.3/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java.patch @@ -9,7 +9,7 @@ @Mixin(value = ServerGamePacketListenerImpl.class, priority = Integer.MIN_VALUE) public class ServerGamePacketListenerImplMixin { -@@ -22,12 +24,13 @@ +@@ -22,13 +24,14 @@ public ServerPlayer player; @Inject( @@ -19,10 +19,12 @@ cancellable = true ) - private void injectChatEvent(Component component, PlayerChatMessage arg, FilteredText p_296589_, CallbackInfo ci) { -- Component finalArg = component == null ? arg.decoratedContent() : component; +- Component finalcomp = component == null ? arg.decoratedContent() : component; +- CraterServerChatEvent event = new CraterServerChatEvent(BridgedPlayer.of(this.player), finalcomp.getString(), ChatUtils.mojangToAdventure(finalcomp)); + private void injectChatEvent(CompletableFuture completablefuture1, PlayerChatMessage arg, CompletableFuture completablefuture, Void p_248218_, CallbackInfo ci) { + Component comp2 = completablefuture1.join(); + Component finalArg = comp2 == null ? arg.decoratedContent() : comp2; - CraterServerChatEvent event = new CraterServerChatEvent(BridgedPlayer.of(this.player), finalArg.getString(), ChatUtils.mojangToAdventure(finalArg)); ++ CraterServerChatEvent event = new CraterServerChatEvent(BridgedPlayer.of(this.player), finalArg.getString(), ChatUtils.mojangToAdventure(finalArg)); CraterEventBus.INSTANCE.postEvent(event); if (event.wasCancelled()) + ci.cancel(); diff --git a/patches/1.19.3/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java.patch b/patches/1.19.3/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java.patch new file mode 100644 index 0000000..5c0e6b2 --- /dev/null +++ b/patches/1.19.3/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java.patch @@ -0,0 +1,11 @@ +--- a/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java ++++ b/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java +@@ -44,7 +44,7 @@ + status.version(), + status.favicon(), + status.enforcesSecureChat(), +- status.isModded() ++ status.forgeData() + ) + )); + } diff --git a/patches/1.19.3/Forge/src/main/resources/META-INF/mods.toml.patch b/patches/1.19.3/Forge/src/main/resources/META-INF/mods.toml.patch index 4130163..1268483 100644 --- a/patches/1.19.3/Forge/src/main/resources/META-INF/mods.toml.patch +++ b/patches/1.19.3/Forge/src/main/resources/META-INF/mods.toml.patch @@ -3,7 +3,7 @@ @@ -1,5 +1,5 @@ modLoader = "javafml" -loaderVersion = "[50,)" -+loaderVersion = "[44,)" ++loaderVersion = "[45,)" license = "MIT" issueTrackerURL = "https://github.com/firstdarkdev/craterLib/issues" @@ -12,7 +12,7 @@ modId = "forge" mandatory = true - versionRange = "[50,)" -+ versionRange = "[44,)" ++ versionRange = "[45,)" ordering = "NONE" side = "BOTH" @@ -20,6 +20,6 @@ modId = "minecraft" mandatory = true - versionRange = "[1.20.6,1.21)" -+ versionRange = "[1.19.3,1.20)" ++ versionRange = "[1.19.4,1.20)" ordering = "NONE" side = "BOTH" diff --git a/patches/1.19.3/NeoForge/build.gradle.patch b/patches/1.19.3/NeoForge/build.gradle.patch index 4a155d8..2ee2c57 100644 --- a/patches/1.19.3/NeoForge/build.gradle.patch +++ b/patches/1.19.3/NeoForge/build.gradle.patch @@ -109,8 +109,8 @@ - setVersionType("release") - setChangelog("https://raw.githubusercontent.com/hypherionmc/changelogs/main/craterlib/changelog-forge.md") - setProjectVersion("${minecraft_version}-${project.version}") -- setDisplayName("[NeoForge 1.21.0] CraterLib - ${project.version}") -- setGameVersions("1.21") +- setDisplayName("[NeoForge 1.21.x] CraterLib - ${project.version}") +- setGameVersions("1.21", "1.21.1") - setLoaders("neoforge") - setArtifact(remapJar) - setCurseEnvironment("both") diff --git a/patches/1.19.3/NeoForge/src/main/java/com/hypherionmc/craterlib/client/NeoForgeClientHelper.java.patch b/patches/1.19.3/NeoForge/src/main/java/com/hypherionmc/craterlib/client/NeoForgeClientHelper.java.patch index a0d386b..6f63513 100644 --- a/patches/1.19.3/NeoForge/src/main/java/com/hypherionmc/craterlib/client/NeoForgeClientHelper.java.patch +++ b/patches/1.19.3/NeoForge/src/main/java/com/hypherionmc/craterlib/client/NeoForgeClientHelper.java.patch @@ -5,8 +5,8 @@ - -import com.hypherionmc.craterlib.api.events.client.LateInitEvent; -import com.hypherionmc.craterlib.client.gui.config.CraterConfigScreen; +-import com.hypherionmc.craterlib.core.config.AbstractConfig; -import com.hypherionmc.craterlib.core.config.ConfigController; --import com.hypherionmc.craterlib.core.config.ModuleConfig; -import com.hypherionmc.craterlib.core.config.annotations.NoConfigScreen; -import com.hypherionmc.craterlib.core.event.CraterEventBus; -import com.hypherionmc.craterlib.core.platform.ClientPlatform; @@ -54,9 +54,9 @@ - LateInitEvent event = new LateInitEvent(new BridgedMinecraft(), BridgedOptions.of(Minecraft.getInstance().options)); - CraterEventBus.INSTANCE.postEvent(event); - -- ConfigController.getMonitoredConfigs().forEach((conf, watcher) -> { +- ConfigController.getWatchedConfigs().forEach((conf, watcher) -> { - if (!conf.getClass().isAnnotationPresent(NoConfigScreen.class)) { -- ModuleConfig config = (ModuleConfig) conf; +- AbstractConfig config = watcher.getLeft(); - ModList.get().getModContainerById(config.getModId()).ifPresent(c -> c.registerExtensionPoint(IConfigScreenFactory.class, ((minecraft, screen) -> new CraterConfigScreen(config, screen)))); - } - }); diff --git a/patches/1.19.3/NeoForge/src/main/java/com/hypherionmc/craterlib/common/NeoForgeServerEvents.java.patch b/patches/1.19.3/NeoForge/src/main/java/com/hypherionmc/craterlib/common/NeoForgeServerEvents.java.patch index 0dab07e..3176ade 100644 --- a/patches/1.19.3/NeoForge/src/main/java/com/hypherionmc/craterlib/common/NeoForgeServerEvents.java.patch +++ b/patches/1.19.3/NeoForge/src/main/java/com/hypherionmc/craterlib/common/NeoForgeServerEvents.java.patch @@ -1,12 +1,11 @@ --- a/NeoForge/src/main/java/com/hypherionmc/craterlib/common/NeoForgeServerEvents.java +++ /dev/null -@@ -1,43 +1,0 @@ +@@ -1,41 +1,0 @@ -package com.hypherionmc.craterlib.common; - -import com.hypherionmc.craterlib.api.events.server.CraterRegisterCommandEvent; -import com.hypherionmc.craterlib.api.events.server.CraterServerLifecycleEvent; -import com.hypherionmc.craterlib.core.event.CraterEventBus; --import com.hypherionmc.craterlib.nojang.commands.CommandsRegistry; -import com.hypherionmc.craterlib.nojang.server.BridgedMinecraftServer; -import net.neoforged.bus.api.SubscribeEvent; -import net.neoforged.neoforge.event.RegisterCommandsEvent; @@ -39,8 +38,7 @@ - - @SubscribeEvent - public void onCommandRegister(RegisterCommandsEvent event) { -- CraterEventBus.INSTANCE.postEvent(new CraterRegisterCommandEvent()); -- CommandsRegistry.INSTANCE.registerCommands(event.getDispatcher()); +- CraterEventBus.INSTANCE.postEvent(new CraterRegisterCommandEvent(event.getDispatcher())); - } - -} diff --git a/patches/1.19.3/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java.patch b/patches/1.19.3/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java.patch index 631e6a6..2f716b8 100644 --- a/patches/1.19.3/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java.patch +++ b/patches/1.19.3/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java.patch @@ -30,8 +30,8 @@ - cancellable = true - ) - private void injectChatEvent(Component component, PlayerChatMessage arg, FilteredText p_296589_, CallbackInfo ci) { -- Component finalArg = component == null ? arg.decoratedContent() : component; -- CraterServerChatEvent event = new CraterServerChatEvent(BridgedPlayer.of(this.player), finalArg.getString(), ChatUtils.mojangToAdventure(finalArg)); +- Component finalcomp = component == null ? arg.decoratedContent() : component; +- CraterServerChatEvent event = new CraterServerChatEvent(BridgedPlayer.of(this.player), finalcomp.getString(), ChatUtils.mojangToAdventure(finalcomp)); - CraterEventBus.INSTANCE.postEvent(event); - if (event.wasCancelled()) - ci.cancel(); diff --git a/patches/1.19.3/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java.patch b/patches/1.19.3/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java.patch new file mode 100644 index 0000000..555de60 --- /dev/null +++ b/patches/1.19.3/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java.patch @@ -0,0 +1,56 @@ +--- a/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java ++++ /dev/null +@@ -1,53 +1,0 @@ +-package com.hypherionmc.craterlib.mixin; +- +-import com.hypherionmc.craterlib.api.events.server.ServerStatusEvent; +-import com.hypherionmc.craterlib.core.event.CraterEventBus; +-import com.hypherionmc.craterlib.utils.ChatUtils; +-import net.minecraft.network.Connection; +-import net.minecraft.network.protocol.status.ClientboundStatusResponsePacket; +-import net.minecraft.network.protocol.status.ServerStatus; +-import net.minecraft.network.protocol.status.ServerboundStatusRequestPacket; +-import net.minecraft.server.network.ServerStatusPacketListenerImpl; +-import org.spongepowered.asm.mixin.Final; +-import org.spongepowered.asm.mixin.Mixin; +-import org.spongepowered.asm.mixin.Shadow; +-import org.spongepowered.asm.mixin.injection.At; +-import org.spongepowered.asm.mixin.injection.Inject; +-import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +- +-@Mixin(ServerStatusPacketListenerImpl.class) +-public class ServerStatusPacketListenerMixin { +- +- @Shadow +- @Final +- private ServerStatus status; +- +- @Shadow @Final private Connection connection; +- +- @Inject(method = "handleStatusRequest", +- at = @At( +- value = "INVOKE", +- target = "Lnet/minecraft/network/Connection;send(Lnet/minecraft/network/protocol/Packet;)V", +- shift = At.Shift.BEFORE), +- cancellable = true +- ) +- private void injectHandleStatusRequest(ServerboundStatusRequestPacket arg, CallbackInfo ci) { +- ServerStatusEvent.StatusRequestEvent event = new ServerStatusEvent.StatusRequestEvent(ChatUtils.mojangToAdventure(status.description())); +- CraterEventBus.INSTANCE.postEvent(event); +- +- if (event.getNewStatus() != null) { +- ci.cancel(); +- this.connection.send(new ClientboundStatusResponsePacket( +- new ServerStatus(ChatUtils.adventureToMojang( +- event.getNewStatus()), +- status.players(), +- status.version(), +- status.favicon(), +- status.enforcesSecureChat(), +- status.isModded() +- ) +- )); +- } +- } +- +-} diff --git a/patches/1.19.3/NeoForge/src/main/resources/craterlib.neoforge.mixins.json.patch b/patches/1.19.3/NeoForge/src/main/resources/craterlib.neoforge.mixins.json.patch index 3732d52..075f957 100644 --- a/patches/1.19.3/NeoForge/src/main/resources/craterlib.neoforge.mixins.json.patch +++ b/patches/1.19.3/NeoForge/src/main/resources/craterlib.neoforge.mixins.json.patch @@ -1,6 +1,6 @@ --- a/NeoForge/src/main/resources/craterlib.neoforge.mixins.json +++ /dev/null -@@ -1,15 +1,0 @@ +@@ -1,16 +1,0 @@ -{ - "required": true, - "minVersion": "0.8", @@ -10,7 +10,8 @@ - ], - "client": [], - "server": [ -- "ServerGamePacketListenerImplMixin" +- "ServerGamePacketListenerImplMixin", +- "ServerStatusPacketListenerMixin" - ], - "injectors": { - "defaultRequire": 1 diff --git a/patches/1.19.3/README.md.patch b/patches/1.19.3/README.md.patch index c98b984..f5eeb1f 100644 --- a/patches/1.19.3/README.md.patch +++ b/patches/1.19.3/README.md.patch @@ -5,8 +5,8 @@ | 1.18.2-1.20.2 | ✳️ | | 1.20.4 | ✳️ | -| 1.20.6 | ❌ | - | 1.21 | ✳️ | -+| 1.21 | 🚧 | + | 1.21.x | ✳️ | ++ - ❌ - Not Supported; no bug fixes or new features. - 🚧 - Work in Progress; not ready for release. diff --git a/patches/1.19.3/build.gradle.patch b/patches/1.19.3/build.gradle.patch index 4252ab9..b6610ca 100644 --- a/patches/1.19.3/build.gradle.patch +++ b/patches/1.19.3/build.gradle.patch @@ -11,9 +11,9 @@ group = rootProject.group -@@ -58,7 +58,7 @@ - shade "me.hypherionmc.moon-config:core:${moon_config}" +@@ -59,7 +59,7 @@ shade "me.hypherionmc.moon-config:toml:${moon_config}" + shade "me.hypherionmc.moon-config:json:${moon_config}" shade "com.hypherionmc:rpcsdk:${rpc_sdk}" - shade "me.hypherionmc.sdlink:mcdiscordformatter-1.20.3:${discord_formatter}" + shade "me.hypherionmc.sdlink:mcdiscordformatter-1.19.1:${discord_formatter}" diff --git a/patches/1.19.3/gradle.properties.patch b/patches/1.19.3/gradle.properties.patch index 8961938..c5f3e52 100644 --- a/patches/1.19.3/gradle.properties.patch +++ b/patches/1.19.3/gradle.properties.patch @@ -5,20 +5,20 @@ # Shared -minecraft_version=1.21 -+minecraft_version=1.19.3 ++minecraft_version=1.19.4 project_group=com.hypherionmc.craterlib # Fabric fabric_loader=0.15.11 -fabric_api=0.100.1+1.21 -+fabric_api=0.76.1+1.19.3 ++fabric_api=0.87.2+1.19.4 # Forge -forge_version=50.0.6 - -# NeoForged -neoforge_version=0.0-beta -+forge_version=44.1.0 ++forge_version=45.3.0 # Dependencies moon_config=1.0.9 diff --git a/patches/1.20.2/.jenkins/Jenkinsfile.snapshot.patch b/patches/1.20.2/.jenkins/Jenkinsfile.snapshot.patch index 4f29309..a0f8ec2 100644 --- a/patches/1.20.2/.jenkins/Jenkinsfile.snapshot.patch +++ b/patches/1.20.2/.jenkins/Jenkinsfile.snapshot.patch @@ -6,7 +6,7 @@ -def JDK = "21"; -def majorMc = "1.21"; -def modLoaders = "neoforge|fabric|quilt"; --def supportedMc = "1.21"; +-def supportedMc = "1.21|1.21.1"; -def reltype = "port"; +def JDK = "17"; +def majorMc = "1.20.2"; diff --git a/patches/1.20.2/Fabric/build.gradle.patch b/patches/1.20.2/Fabric/build.gradle.patch index a95e752..8951b6c 100644 --- a/patches/1.20.2/Fabric/build.gradle.patch +++ b/patches/1.20.2/Fabric/build.gradle.patch @@ -4,8 +4,8 @@ setVersionType("release") setChangelog("https://raw.githubusercontent.com/hypherionmc/changelogs/main/craterlib/changelog-fabric.md") setProjectVersion("${minecraft_version}-${project.version}") -- setDisplayName("[FABRIC/QUILT 1.21.0] CraterLib - ${project.version}") -- setGameVersions("1.21") +- setDisplayName("[FABRIC/QUILT 1.21.x] CraterLib - ${project.version}") +- setGameVersions("1.21", "1.21.1") + setDisplayName("[FABRIC/QUILT 1.20.2] CraterLib - ${project.version}") + setGameVersions("1.20.2") setLoaders("fabric", "quilt") diff --git a/patches/1.20.2/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeServerEvents.java.patch b/patches/1.20.2/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeServerEvents.java.patch new file mode 100644 index 0000000..c99194b --- /dev/null +++ b/patches/1.20.2/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeServerEvents.java.patch @@ -0,0 +1,20 @@ +--- a/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeServerEvents.java ++++ b/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeServerEvents.java +@@ -3,7 +3,6 @@ + import com.hypherionmc.craterlib.api.events.server.CraterRegisterCommandEvent; + import com.hypherionmc.craterlib.api.events.server.CraterServerLifecycleEvent; + import com.hypherionmc.craterlib.core.event.CraterEventBus; +-import com.hypherionmc.craterlib.nojang.commands.CommandsRegistry; + import com.hypherionmc.craterlib.nojang.server.BridgedMinecraftServer; + import net.minecraftforge.event.RegisterCommandsEvent; + import net.minecraftforge.event.server.ServerStartedEvent; +@@ -36,8 +35,7 @@ + + @SubscribeEvent + public void onCommandRegister(RegisterCommandsEvent event) { +- CraterEventBus.INSTANCE.postEvent(new CraterRegisterCommandEvent()); +- CommandsRegistry.INSTANCE.registerCommands(event.getDispatcher()); ++ CraterEventBus.INSTANCE.postEvent(new CraterRegisterCommandEvent(event.getDispatcher())); + } + + } diff --git a/patches/1.20.2/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java.patch b/patches/1.20.2/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java.patch new file mode 100644 index 0000000..5f8832b --- /dev/null +++ b/patches/1.20.2/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java.patch @@ -0,0 +1,22 @@ +--- a/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java ++++ b/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java +@@ -1,6 +1,7 @@ + package com.hypherionmc.craterlib.mixin; + + import com.hypherionmc.craterlib.client.gui.config.CraterConfigScreen; ++import com.hypherionmc.craterlib.core.config.AbstractConfig; + import com.hypherionmc.craterlib.core.config.ConfigController; + import com.hypherionmc.craterlib.core.config.ModuleConfig; + import com.hypherionmc.craterlib.core.config.annotations.NoConfigScreen; +@@ -28,9 +29,9 @@ + */ + @Inject(at = @At("RETURN"), method = "getScreenFactoryFor", cancellable = true, remap = false) + private static void injectConfigScreen(IModInfo selectedMod, CallbackInfoReturnable>> cir) { +- ConfigController.getMonitoredConfigs().forEach((conf, watcher) -> { ++ ConfigController.getWatchedConfigs().forEach((conf, watcher) -> { + if (!conf.getClass().isAnnotationPresent(NoConfigScreen.class)) { +- ModuleConfig config = (ModuleConfig) conf; ++ AbstractConfig config = watcher.getLeft(); + if (config.getModId().equals(selectedMod.getModId())) { + cir.setReturnValue( + Optional.of((minecraft, screen) -> new CraterConfigScreen(config, screen)) diff --git a/patches/1.20.2/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java.patch b/patches/1.20.2/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java.patch new file mode 100644 index 0000000..5c0e6b2 --- /dev/null +++ b/patches/1.20.2/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java.patch @@ -0,0 +1,11 @@ +--- a/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java ++++ b/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java +@@ -44,7 +44,7 @@ + status.version(), + status.favicon(), + status.enforcesSecureChat(), +- status.isModded() ++ status.forgeData() + ) + )); + } diff --git a/patches/1.20.2/NeoForge/build.gradle.patch b/patches/1.20.2/NeoForge/build.gradle.patch index 4a155d8..2ee2c57 100644 --- a/patches/1.20.2/NeoForge/build.gradle.patch +++ b/patches/1.20.2/NeoForge/build.gradle.patch @@ -109,8 +109,8 @@ - setVersionType("release") - setChangelog("https://raw.githubusercontent.com/hypherionmc/changelogs/main/craterlib/changelog-forge.md") - setProjectVersion("${minecraft_version}-${project.version}") -- setDisplayName("[NeoForge 1.21.0] CraterLib - ${project.version}") -- setGameVersions("1.21") +- setDisplayName("[NeoForge 1.21.x] CraterLib - ${project.version}") +- setGameVersions("1.21", "1.21.1") - setLoaders("neoforge") - setArtifact(remapJar) - setCurseEnvironment("both") diff --git a/patches/1.20.2/NeoForge/src/main/java/com/hypherionmc/craterlib/client/NeoForgeClientHelper.java.patch b/patches/1.20.2/NeoForge/src/main/java/com/hypherionmc/craterlib/client/NeoForgeClientHelper.java.patch index a0d386b..6f63513 100644 --- a/patches/1.20.2/NeoForge/src/main/java/com/hypherionmc/craterlib/client/NeoForgeClientHelper.java.patch +++ b/patches/1.20.2/NeoForge/src/main/java/com/hypherionmc/craterlib/client/NeoForgeClientHelper.java.patch @@ -5,8 +5,8 @@ - -import com.hypherionmc.craterlib.api.events.client.LateInitEvent; -import com.hypherionmc.craterlib.client.gui.config.CraterConfigScreen; +-import com.hypherionmc.craterlib.core.config.AbstractConfig; -import com.hypherionmc.craterlib.core.config.ConfigController; --import com.hypherionmc.craterlib.core.config.ModuleConfig; -import com.hypherionmc.craterlib.core.config.annotations.NoConfigScreen; -import com.hypherionmc.craterlib.core.event.CraterEventBus; -import com.hypherionmc.craterlib.core.platform.ClientPlatform; @@ -54,9 +54,9 @@ - LateInitEvent event = new LateInitEvent(new BridgedMinecraft(), BridgedOptions.of(Minecraft.getInstance().options)); - CraterEventBus.INSTANCE.postEvent(event); - -- ConfigController.getMonitoredConfigs().forEach((conf, watcher) -> { +- ConfigController.getWatchedConfigs().forEach((conf, watcher) -> { - if (!conf.getClass().isAnnotationPresent(NoConfigScreen.class)) { -- ModuleConfig config = (ModuleConfig) conf; +- AbstractConfig config = watcher.getLeft(); - ModList.get().getModContainerById(config.getModId()).ifPresent(c -> c.registerExtensionPoint(IConfigScreenFactory.class, ((minecraft, screen) -> new CraterConfigScreen(config, screen)))); - } - }); diff --git a/patches/1.20.2/NeoForge/src/main/java/com/hypherionmc/craterlib/common/NeoForgeServerEvents.java.patch b/patches/1.20.2/NeoForge/src/main/java/com/hypherionmc/craterlib/common/NeoForgeServerEvents.java.patch index 0dab07e..3176ade 100644 --- a/patches/1.20.2/NeoForge/src/main/java/com/hypherionmc/craterlib/common/NeoForgeServerEvents.java.patch +++ b/patches/1.20.2/NeoForge/src/main/java/com/hypherionmc/craterlib/common/NeoForgeServerEvents.java.patch @@ -1,12 +1,11 @@ --- a/NeoForge/src/main/java/com/hypherionmc/craterlib/common/NeoForgeServerEvents.java +++ /dev/null -@@ -1,43 +1,0 @@ +@@ -1,41 +1,0 @@ -package com.hypherionmc.craterlib.common; - -import com.hypherionmc.craterlib.api.events.server.CraterRegisterCommandEvent; -import com.hypherionmc.craterlib.api.events.server.CraterServerLifecycleEvent; -import com.hypherionmc.craterlib.core.event.CraterEventBus; --import com.hypherionmc.craterlib.nojang.commands.CommandsRegistry; -import com.hypherionmc.craterlib.nojang.server.BridgedMinecraftServer; -import net.neoforged.bus.api.SubscribeEvent; -import net.neoforged.neoforge.event.RegisterCommandsEvent; @@ -39,8 +38,7 @@ - - @SubscribeEvent - public void onCommandRegister(RegisterCommandsEvent event) { -- CraterEventBus.INSTANCE.postEvent(new CraterRegisterCommandEvent()); -- CommandsRegistry.INSTANCE.registerCommands(event.getDispatcher()); +- CraterEventBus.INSTANCE.postEvent(new CraterRegisterCommandEvent(event.getDispatcher())); - } - -} diff --git a/patches/1.20.2/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java.patch b/patches/1.20.2/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java.patch index 631e6a6..2f716b8 100644 --- a/patches/1.20.2/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java.patch +++ b/patches/1.20.2/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java.patch @@ -30,8 +30,8 @@ - cancellable = true - ) - private void injectChatEvent(Component component, PlayerChatMessage arg, FilteredText p_296589_, CallbackInfo ci) { -- Component finalArg = component == null ? arg.decoratedContent() : component; -- CraterServerChatEvent event = new CraterServerChatEvent(BridgedPlayer.of(this.player), finalArg.getString(), ChatUtils.mojangToAdventure(finalArg)); +- Component finalcomp = component == null ? arg.decoratedContent() : component; +- CraterServerChatEvent event = new CraterServerChatEvent(BridgedPlayer.of(this.player), finalcomp.getString(), ChatUtils.mojangToAdventure(finalcomp)); - CraterEventBus.INSTANCE.postEvent(event); - if (event.wasCancelled()) - ci.cancel(); diff --git a/patches/1.20.2/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java.patch b/patches/1.20.2/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java.patch new file mode 100644 index 0000000..555de60 --- /dev/null +++ b/patches/1.20.2/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java.patch @@ -0,0 +1,56 @@ +--- a/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java ++++ /dev/null +@@ -1,53 +1,0 @@ +-package com.hypherionmc.craterlib.mixin; +- +-import com.hypherionmc.craterlib.api.events.server.ServerStatusEvent; +-import com.hypherionmc.craterlib.core.event.CraterEventBus; +-import com.hypherionmc.craterlib.utils.ChatUtils; +-import net.minecraft.network.Connection; +-import net.minecraft.network.protocol.status.ClientboundStatusResponsePacket; +-import net.minecraft.network.protocol.status.ServerStatus; +-import net.minecraft.network.protocol.status.ServerboundStatusRequestPacket; +-import net.minecraft.server.network.ServerStatusPacketListenerImpl; +-import org.spongepowered.asm.mixin.Final; +-import org.spongepowered.asm.mixin.Mixin; +-import org.spongepowered.asm.mixin.Shadow; +-import org.spongepowered.asm.mixin.injection.At; +-import org.spongepowered.asm.mixin.injection.Inject; +-import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +- +-@Mixin(ServerStatusPacketListenerImpl.class) +-public class ServerStatusPacketListenerMixin { +- +- @Shadow +- @Final +- private ServerStatus status; +- +- @Shadow @Final private Connection connection; +- +- @Inject(method = "handleStatusRequest", +- at = @At( +- value = "INVOKE", +- target = "Lnet/minecraft/network/Connection;send(Lnet/minecraft/network/protocol/Packet;)V", +- shift = At.Shift.BEFORE), +- cancellable = true +- ) +- private void injectHandleStatusRequest(ServerboundStatusRequestPacket arg, CallbackInfo ci) { +- ServerStatusEvent.StatusRequestEvent event = new ServerStatusEvent.StatusRequestEvent(ChatUtils.mojangToAdventure(status.description())); +- CraterEventBus.INSTANCE.postEvent(event); +- +- if (event.getNewStatus() != null) { +- ci.cancel(); +- this.connection.send(new ClientboundStatusResponsePacket( +- new ServerStatus(ChatUtils.adventureToMojang( +- event.getNewStatus()), +- status.players(), +- status.version(), +- status.favicon(), +- status.enforcesSecureChat(), +- status.isModded() +- ) +- )); +- } +- } +- +-} diff --git a/patches/1.20.2/NeoForge/src/main/resources/craterlib.neoforge.mixins.json.patch b/patches/1.20.2/NeoForge/src/main/resources/craterlib.neoforge.mixins.json.patch index 3732d52..075f957 100644 --- a/patches/1.20.2/NeoForge/src/main/resources/craterlib.neoforge.mixins.json.patch +++ b/patches/1.20.2/NeoForge/src/main/resources/craterlib.neoforge.mixins.json.patch @@ -1,6 +1,6 @@ --- a/NeoForge/src/main/resources/craterlib.neoforge.mixins.json +++ /dev/null -@@ -1,15 +1,0 @@ +@@ -1,16 +1,0 @@ -{ - "required": true, - "minVersion": "0.8", @@ -10,7 +10,8 @@ - ], - "client": [], - "server": [ -- "ServerGamePacketListenerImplMixin" +- "ServerGamePacketListenerImplMixin", +- "ServerStatusPacketListenerMixin" - ], - "injectors": { - "defaultRequire": 1 diff --git a/patches/1.20.2/README.md.patch b/patches/1.20.2/README.md.patch index 5fd4d92..4aea58e 100644 --- a/patches/1.20.2/README.md.patch +++ b/patches/1.20.2/README.md.patch @@ -1,12 +1,10 @@ --- a/README.md +++ b/README.md -@@ -15,8 +15,7 @@ +@@ -15,7 +15,6 @@ | < 1.18.2 | ❌ | | 1.18.2-1.20.2 | ✳️ | | 1.20.4 | ✳️ | -| 1.20.6 | ❌ | --| 1.21 | ✳️ | -+| 1.21 | 🚧 | + | 1.21.x | ✳️ | - ❌ - Not Supported; no bug fixes or new features. - - 🚧 - Work in Progress; not ready for release. diff --git a/patches/1.20.2/build.gradle.patch b/patches/1.20.2/build.gradle.patch index 4252ab9..b6610ca 100644 --- a/patches/1.20.2/build.gradle.patch +++ b/patches/1.20.2/build.gradle.patch @@ -11,9 +11,9 @@ group = rootProject.group -@@ -58,7 +58,7 @@ - shade "me.hypherionmc.moon-config:core:${moon_config}" +@@ -59,7 +59,7 @@ shade "me.hypherionmc.moon-config:toml:${moon_config}" + shade "me.hypherionmc.moon-config:json:${moon_config}" shade "com.hypherionmc:rpcsdk:${rpc_sdk}" - shade "me.hypherionmc.sdlink:mcdiscordformatter-1.20.3:${discord_formatter}" + shade "me.hypherionmc.sdlink:mcdiscordformatter-1.19.1:${discord_formatter}" diff --git a/patches/1.20.4/.jenkins/Jenkinsfile.snapshot.patch b/patches/1.20.4/.jenkins/Jenkinsfile.snapshot.patch index 2256e1d..4480a99 100644 --- a/patches/1.20.4/.jenkins/Jenkinsfile.snapshot.patch +++ b/patches/1.20.4/.jenkins/Jenkinsfile.snapshot.patch @@ -6,7 +6,7 @@ -def JDK = "21"; -def majorMc = "1.21"; -def modLoaders = "neoforge|fabric|quilt"; --def supportedMc = "1.21"; +-def supportedMc = "1.21|1.21.1"; -def reltype = "port"; +def JDK = "17"; +def majorMc = "1.20.4"; diff --git a/patches/1.20.4/Fabric/build.gradle.patch b/patches/1.20.4/Fabric/build.gradle.patch index 896ec96..3d01528 100644 --- a/patches/1.20.4/Fabric/build.gradle.patch +++ b/patches/1.20.4/Fabric/build.gradle.patch @@ -4,8 +4,8 @@ setVersionType("release") setChangelog("https://raw.githubusercontent.com/hypherionmc/changelogs/main/craterlib/changelog-fabric.md") setProjectVersion("${minecraft_version}-${project.version}") -- setDisplayName("[FABRIC/QUILT 1.21.0] CraterLib - ${project.version}") -- setGameVersions("1.21") +- setDisplayName("[FABRIC/QUILT 1.21.x] CraterLib - ${project.version}") +- setGameVersions("1.21", "1.21.1") + setDisplayName("[FABRIC/QUILT 1.20.4] CraterLib - ${project.version}") + setGameVersions("1.20.4") setLoaders("fabric", "quilt") diff --git a/patches/1.20.4/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeServerEvents.java.patch b/patches/1.20.4/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeServerEvents.java.patch new file mode 100644 index 0000000..c99194b --- /dev/null +++ b/patches/1.20.4/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeServerEvents.java.patch @@ -0,0 +1,20 @@ +--- a/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeServerEvents.java ++++ b/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeServerEvents.java +@@ -3,7 +3,6 @@ + import com.hypherionmc.craterlib.api.events.server.CraterRegisterCommandEvent; + import com.hypherionmc.craterlib.api.events.server.CraterServerLifecycleEvent; + import com.hypherionmc.craterlib.core.event.CraterEventBus; +-import com.hypherionmc.craterlib.nojang.commands.CommandsRegistry; + import com.hypherionmc.craterlib.nojang.server.BridgedMinecraftServer; + import net.minecraftforge.event.RegisterCommandsEvent; + import net.minecraftforge.event.server.ServerStartedEvent; +@@ -36,8 +35,7 @@ + + @SubscribeEvent + public void onCommandRegister(RegisterCommandsEvent event) { +- CraterEventBus.INSTANCE.postEvent(new CraterRegisterCommandEvent()); +- CommandsRegistry.INSTANCE.registerCommands(event.getDispatcher()); ++ CraterEventBus.INSTANCE.postEvent(new CraterRegisterCommandEvent(event.getDispatcher())); + } + + } diff --git a/patches/1.20.4/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java.patch b/patches/1.20.4/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java.patch new file mode 100644 index 0000000..b5243f2 --- /dev/null +++ b/patches/1.20.4/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java.patch @@ -0,0 +1,24 @@ +--- a/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java ++++ b/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java +@@ -1,8 +1,8 @@ + package com.hypherionmc.craterlib.mixin; + + import com.hypherionmc.craterlib.client.gui.config.CraterConfigScreen; ++import com.hypherionmc.craterlib.core.config.AbstractConfig; + import com.hypherionmc.craterlib.core.config.ConfigController; +-import com.hypherionmc.craterlib.core.config.ModuleConfig; + import com.hypherionmc.craterlib.core.config.annotations.NoConfigScreen; + import net.minecraft.client.Minecraft; + import net.minecraft.client.gui.screens.Screen; +@@ -28,9 +28,9 @@ + */ + @Inject(at = @At("RETURN"), method = "getScreenFactoryFor", cancellable = true, remap = false) + private static void injectConfigScreen(IModInfo selectedMod, CallbackInfoReturnable>> cir) { +- ConfigController.getMonitoredConfigs().forEach((conf, watcher) -> { ++ ConfigController.getWatchedConfigs().forEach((conf, watcher) -> { + if (!conf.getClass().isAnnotationPresent(NoConfigScreen.class)) { +- ModuleConfig config = (ModuleConfig) conf; ++ AbstractConfig config = watcher.getLeft(); + if (config.getModId().equals(selectedMod.getModId())) { + cir.setReturnValue( + Optional.of((minecraft, screen) -> new CraterConfigScreen(config, screen)) diff --git a/patches/1.20.4/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java.patch b/patches/1.20.4/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java.patch new file mode 100644 index 0000000..5c0e6b2 --- /dev/null +++ b/patches/1.20.4/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java.patch @@ -0,0 +1,11 @@ +--- a/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java ++++ b/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java +@@ -44,7 +44,7 @@ + status.version(), + status.favicon(), + status.enforcesSecureChat(), +- status.isModded() ++ status.forgeData() + ) + )); + } diff --git a/patches/1.20.4/NeoForge/build.gradle.patch b/patches/1.20.4/NeoForge/build.gradle.patch index a551cad..ab54863 100644 --- a/patches/1.20.4/NeoForge/build.gradle.patch +++ b/patches/1.20.4/NeoForge/build.gradle.patch @@ -13,8 +13,8 @@ setVersionType("release") setChangelog("https://raw.githubusercontent.com/hypherionmc/changelogs/main/craterlib/changelog-forge.md") setProjectVersion("${minecraft_version}-${project.version}") -- setDisplayName("[NeoForge 1.21.0] CraterLib - ${project.version}") -- setGameVersions("1.21") +- setDisplayName("[NeoForge 1.21.x] CraterLib - ${project.version}") +- setGameVersions("1.21", "1.21.1") + setDisplayName("[NeoForge 1.20.4] CraterLib - ${project.version}") + setGameVersions("1.20.4") setLoaders("neoforge") diff --git a/patches/1.20.4/NeoForge/src/main/java/com/hypherionmc/craterlib/client/NeoForgeClientHelper.java.patch b/patches/1.20.4/NeoForge/src/main/java/com/hypherionmc/craterlib/client/NeoForgeClientHelper.java.patch index 82b6d77..e6c55f8 100644 --- a/patches/1.20.4/NeoForge/src/main/java/com/hypherionmc/craterlib/client/NeoForgeClientHelper.java.patch +++ b/patches/1.20.4/NeoForge/src/main/java/com/hypherionmc/craterlib/client/NeoForgeClientHelper.java.patch @@ -5,8 +5,8 @@ -import com.hypherionmc.craterlib.api.events.client.LateInitEvent; -import com.hypherionmc.craterlib.client.gui.config.CraterConfigScreen; +-import com.hypherionmc.craterlib.core.config.AbstractConfig; -import com.hypherionmc.craterlib.core.config.ConfigController; --import com.hypherionmc.craterlib.core.config.ModuleConfig; -import com.hypherionmc.craterlib.core.config.annotations.NoConfigScreen; -import com.hypherionmc.craterlib.core.event.CraterEventBus; import com.hypherionmc.craterlib.core.platform.ClientPlatform; @@ -31,9 +31,9 @@ - LateInitEvent event = new LateInitEvent(new BridgedMinecraft(), BridgedOptions.of(Minecraft.getInstance().options)); - CraterEventBus.INSTANCE.postEvent(event); - -- ConfigController.getMonitoredConfigs().forEach((conf, watcher) -> { +- ConfigController.getWatchedConfigs().forEach((conf, watcher) -> { - if (!conf.getClass().isAnnotationPresent(NoConfigScreen.class)) { -- ModuleConfig config = (ModuleConfig) conf; +- AbstractConfig config = watcher.getLeft(); - ModList.get().getModContainerById(config.getModId()).ifPresent(c -> c.registerExtensionPoint(IConfigScreenFactory.class, ((minecraft, screen) -> new CraterConfigScreen(config, screen)))); - } - }); diff --git a/patches/1.20.4/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java.patch b/patches/1.20.4/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java.patch index c701073..4ccd39a 100644 --- a/patches/1.20.4/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java.patch +++ b/patches/1.20.4/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java.patch @@ -1,9 +1,10 @@ --- /dev/null +++ b/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java -@@ -1,0 +1,43 @@ +@@ -1,0 +1,44 @@ +package com.hypherionmc.craterlib.mixin; + +import com.hypherionmc.craterlib.client.gui.config.CraterConfigScreen; ++import com.hypherionmc.craterlib.core.config.AbstractConfig; +import com.hypherionmc.craterlib.core.config.ConfigController; +import com.hypherionmc.craterlib.core.config.ModuleConfig; +import com.hypherionmc.craterlib.core.config.annotations.NoConfigScreen; @@ -31,9 +32,9 @@ + */ + @Inject(at = @At("RETURN"), method = "getScreenFactoryFor", cancellable = true, remap = false) + private static void injectConfigScreen(IModInfo selectedMod, CallbackInfoReturnable>> cir) { -+ ConfigController.getMonitoredConfigs().forEach((conf, watcher) -> { ++ ConfigController.getWatchedConfigs().forEach((conf, watcher) -> { + if (!conf.getClass().isAnnotationPresent(NoConfigScreen.class)) { -+ ModuleConfig config = (ModuleConfig) conf; ++ AbstractConfig config = watcher.getLeft(); + if (config.getModId().equals(selectedMod.getModId())) { + cir.setReturnValue( + Optional.of((minecraft, screen) -> new CraterConfigScreen(config, screen)) diff --git a/patches/1.20.4/NeoForge/src/main/resources/craterlib.neoforge.mixins.json.patch b/patches/1.20.4/NeoForge/src/main/resources/craterlib.neoforge.mixins.json.patch index f9348e6..0320eef 100644 --- a/patches/1.20.4/NeoForge/src/main/resources/craterlib.neoforge.mixins.json.patch +++ b/patches/1.20.4/NeoForge/src/main/resources/craterlib.neoforge.mixins.json.patch @@ -9,5 +9,5 @@ + "ConfigScreenHandlerMixin" + ], "server": [ - "ServerGamePacketListenerImplMixin" - ], + "ServerGamePacketListenerImplMixin", + "ServerStatusPacketListenerMixin" diff --git a/patches/1.20.4/README.md.patch b/patches/1.20.4/README.md.patch index 5fd4d92..4aea58e 100644 --- a/patches/1.20.4/README.md.patch +++ b/patches/1.20.4/README.md.patch @@ -1,12 +1,10 @@ --- a/README.md +++ b/README.md -@@ -15,8 +15,7 @@ +@@ -15,7 +15,6 @@ | < 1.18.2 | ❌ | | 1.18.2-1.20.2 | ✳️ | | 1.20.4 | ✳️ | -| 1.20.6 | ❌ | --| 1.21 | ✳️ | -+| 1.21 | 🚧 | + | 1.21.x | ✳️ | - ❌ - Not Supported; no bug fixes or new features. - - 🚧 - Work in Progress; not ready for release. diff --git a/patches/1.20/.jenkins/Jenkinsfile.snapshot.patch b/patches/1.20/.jenkins/Jenkinsfile.snapshot.patch index 003cf75..9ac7e31 100644 --- a/patches/1.20/.jenkins/Jenkinsfile.snapshot.patch +++ b/patches/1.20/.jenkins/Jenkinsfile.snapshot.patch @@ -6,7 +6,7 @@ -def JDK = "21"; -def majorMc = "1.21"; -def modLoaders = "neoforge|fabric|quilt"; --def supportedMc = "1.21"; +-def supportedMc = "1.21|1.21.1"; -def reltype = "port"; +def JDK = "17"; +def majorMc = "1.20"; diff --git a/patches/1.20/Fabric/build.gradle.patch b/patches/1.20/Fabric/build.gradle.patch index ce24ce9..8fec041 100644 --- a/patches/1.20/Fabric/build.gradle.patch +++ b/patches/1.20/Fabric/build.gradle.patch @@ -4,8 +4,8 @@ setVersionType("release") setChangelog("https://raw.githubusercontent.com/hypherionmc/changelogs/main/craterlib/changelog-fabric.md") setProjectVersion("${minecraft_version}-${project.version}") -- setDisplayName("[FABRIC/QUILT 1.21.0] CraterLib - ${project.version}") -- setGameVersions("1.21") +- setDisplayName("[FABRIC/QUILT 1.21.x] CraterLib - ${project.version}") +- setGameVersions("1.21", "1.21.1") + setDisplayName("[FABRIC/QUILT 1.20/1.20.1] CraterLib - ${project.version}") + setGameVersions("1.20", "1.20.1") setLoaders("fabric", "quilt") diff --git a/patches/1.20/Fabric/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java.patch b/patches/1.20/Fabric/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java.patch index 3c8670d..efab272 100644 --- a/patches/1.20/Fabric/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java.patch +++ b/patches/1.20/Fabric/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java.patch @@ -9,7 +9,7 @@ @Mixin(value = ServerGamePacketListenerImpl.class, priority = Integer.MIN_VALUE) public class ServerGamePacketListenerImplMixin { -@@ -22,11 +24,12 @@ +@@ -22,13 +24,14 @@ public ServerPlayer player; @Inject( @@ -19,8 +19,12 @@ cancellable = true ) - private void injectChatEvent(PlayerChatMessage arg, Component arg2, FilteredText arg3, CallbackInfo ci) { +- Component finalcomp = arg2 == null ? arg.decoratedContent() : arg2; +- CraterServerChatEvent event = new CraterServerChatEvent(BridgedPlayer.of(this.player), finalcomp.getString(), ChatUtils.mojangToAdventure(finalcomp)); + private void injectChatEvent(PlayerChatMessage arg, CompletableFuture completableFuture, CompletableFuture completableFuture2, Void void_, CallbackInfo ci) { + Component arg2 = completableFuture2.join(); - Component finalArg = arg2 == null ? arg.decoratedContent() : arg2; - CraterServerChatEvent event = new CraterServerChatEvent(BridgedPlayer.of(this.player), finalArg.getString(), ChatUtils.mojangToAdventure(finalArg)); ++ Component finalArg = arg2 == null ? arg.decoratedContent() : arg2; ++ CraterServerChatEvent event = new CraterServerChatEvent(BridgedPlayer.of(this.player), finalArg.getString(), ChatUtils.mojangToAdventure(finalArg)); CraterEventBus.INSTANCE.postEvent(event); + if (event.wasCancelled()) + ci.cancel(); diff --git a/patches/1.20/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeServerEvents.java.patch b/patches/1.20/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeServerEvents.java.patch new file mode 100644 index 0000000..c99194b --- /dev/null +++ b/patches/1.20/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeServerEvents.java.patch @@ -0,0 +1,20 @@ +--- a/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeServerEvents.java ++++ b/Forge/src/main/java/com/hypherionmc/craterlib/common/ForgeServerEvents.java +@@ -3,7 +3,6 @@ + import com.hypherionmc.craterlib.api.events.server.CraterRegisterCommandEvent; + import com.hypherionmc.craterlib.api.events.server.CraterServerLifecycleEvent; + import com.hypherionmc.craterlib.core.event.CraterEventBus; +-import com.hypherionmc.craterlib.nojang.commands.CommandsRegistry; + import com.hypherionmc.craterlib.nojang.server.BridgedMinecraftServer; + import net.minecraftforge.event.RegisterCommandsEvent; + import net.minecraftforge.event.server.ServerStartedEvent; +@@ -36,8 +35,7 @@ + + @SubscribeEvent + public void onCommandRegister(RegisterCommandsEvent event) { +- CraterEventBus.INSTANCE.postEvent(new CraterRegisterCommandEvent()); +- CommandsRegistry.INSTANCE.registerCommands(event.getDispatcher()); ++ CraterEventBus.INSTANCE.postEvent(new CraterRegisterCommandEvent(event.getDispatcher())); + } + + } diff --git a/patches/1.20/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java.patch b/patches/1.20/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java.patch new file mode 100644 index 0000000..b5243f2 --- /dev/null +++ b/patches/1.20/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java.patch @@ -0,0 +1,24 @@ +--- a/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java ++++ b/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ConfigScreenHandlerMixin.java +@@ -1,8 +1,8 @@ + package com.hypherionmc.craterlib.mixin; + + import com.hypherionmc.craterlib.client.gui.config.CraterConfigScreen; ++import com.hypherionmc.craterlib.core.config.AbstractConfig; + import com.hypherionmc.craterlib.core.config.ConfigController; +-import com.hypherionmc.craterlib.core.config.ModuleConfig; + import com.hypherionmc.craterlib.core.config.annotations.NoConfigScreen; + import net.minecraft.client.Minecraft; + import net.minecraft.client.gui.screens.Screen; +@@ -28,9 +28,9 @@ + */ + @Inject(at = @At("RETURN"), method = "getScreenFactoryFor", cancellable = true, remap = false) + private static void injectConfigScreen(IModInfo selectedMod, CallbackInfoReturnable>> cir) { +- ConfigController.getMonitoredConfigs().forEach((conf, watcher) -> { ++ ConfigController.getWatchedConfigs().forEach((conf, watcher) -> { + if (!conf.getClass().isAnnotationPresent(NoConfigScreen.class)) { +- ModuleConfig config = (ModuleConfig) conf; ++ AbstractConfig config = watcher.getLeft(); + if (config.getModId().equals(selectedMod.getModId())) { + cir.setReturnValue( + Optional.of((minecraft, screen) -> new CraterConfigScreen(config, screen)) diff --git a/patches/1.20/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java.patch b/patches/1.20/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java.patch index d9ab294..7903104 100644 --- a/patches/1.20/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java.patch +++ b/patches/1.20/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java.patch @@ -9,7 +9,7 @@ @Mixin(value = ServerGamePacketListenerImpl.class, priority = Integer.MIN_VALUE) public class ServerGamePacketListenerImplMixin { -@@ -22,11 +24,12 @@ +@@ -22,13 +24,14 @@ public ServerPlayer player; @Inject( @@ -19,8 +19,12 @@ cancellable = true ) - private void injectChatEvent(Component component, PlayerChatMessage arg, FilteredText p_296589_, CallbackInfo ci) { +- Component finalcomp = component == null ? arg.decoratedContent() : component; +- CraterServerChatEvent event = new CraterServerChatEvent(BridgedPlayer.of(this.player), finalcomp.getString(), ChatUtils.mojangToAdventure(finalcomp)); + private void injectChatEvent(CompletableFuture completablefuture1, PlayerChatMessage arg, CompletableFuture completablefuture, Void p_248218_, CallbackInfo ci) { + Component component = completablefuture1.join(); - Component finalArg = component == null ? arg.decoratedContent() : component; - CraterServerChatEvent event = new CraterServerChatEvent(BridgedPlayer.of(this.player), finalArg.getString(), ChatUtils.mojangToAdventure(finalArg)); ++ Component finalArg = component == null ? arg.decoratedContent() : component; ++ CraterServerChatEvent event = new CraterServerChatEvent(BridgedPlayer.of(this.player), finalArg.getString(), ChatUtils.mojangToAdventure(finalArg)); CraterEventBus.INSTANCE.postEvent(event); + if (event.wasCancelled()) + ci.cancel(); diff --git a/patches/1.20/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java.patch b/patches/1.20/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java.patch new file mode 100644 index 0000000..5c0e6b2 --- /dev/null +++ b/patches/1.20/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java.patch @@ -0,0 +1,11 @@ +--- a/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java ++++ b/Forge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java +@@ -44,7 +44,7 @@ + status.version(), + status.favicon(), + status.enforcesSecureChat(), +- status.isModded() ++ status.forgeData() + ) + )); + } diff --git a/patches/1.20/NeoForge/build.gradle.patch b/patches/1.20/NeoForge/build.gradle.patch index 4a155d8..2ee2c57 100644 --- a/patches/1.20/NeoForge/build.gradle.patch +++ b/patches/1.20/NeoForge/build.gradle.patch @@ -109,8 +109,8 @@ - setVersionType("release") - setChangelog("https://raw.githubusercontent.com/hypherionmc/changelogs/main/craterlib/changelog-forge.md") - setProjectVersion("${minecraft_version}-${project.version}") -- setDisplayName("[NeoForge 1.21.0] CraterLib - ${project.version}") -- setGameVersions("1.21") +- setDisplayName("[NeoForge 1.21.x] CraterLib - ${project.version}") +- setGameVersions("1.21", "1.21.1") - setLoaders("neoforge") - setArtifact(remapJar) - setCurseEnvironment("both") diff --git a/patches/1.20/NeoForge/src/main/java/com/hypherionmc/craterlib/client/NeoForgeClientHelper.java.patch b/patches/1.20/NeoForge/src/main/java/com/hypherionmc/craterlib/client/NeoForgeClientHelper.java.patch index a0d386b..6f63513 100644 --- a/patches/1.20/NeoForge/src/main/java/com/hypherionmc/craterlib/client/NeoForgeClientHelper.java.patch +++ b/patches/1.20/NeoForge/src/main/java/com/hypherionmc/craterlib/client/NeoForgeClientHelper.java.patch @@ -5,8 +5,8 @@ - -import com.hypherionmc.craterlib.api.events.client.LateInitEvent; -import com.hypherionmc.craterlib.client.gui.config.CraterConfigScreen; +-import com.hypherionmc.craterlib.core.config.AbstractConfig; -import com.hypherionmc.craterlib.core.config.ConfigController; --import com.hypherionmc.craterlib.core.config.ModuleConfig; -import com.hypherionmc.craterlib.core.config.annotations.NoConfigScreen; -import com.hypherionmc.craterlib.core.event.CraterEventBus; -import com.hypherionmc.craterlib.core.platform.ClientPlatform; @@ -54,9 +54,9 @@ - LateInitEvent event = new LateInitEvent(new BridgedMinecraft(), BridgedOptions.of(Minecraft.getInstance().options)); - CraterEventBus.INSTANCE.postEvent(event); - -- ConfigController.getMonitoredConfigs().forEach((conf, watcher) -> { +- ConfigController.getWatchedConfigs().forEach((conf, watcher) -> { - if (!conf.getClass().isAnnotationPresent(NoConfigScreen.class)) { -- ModuleConfig config = (ModuleConfig) conf; +- AbstractConfig config = watcher.getLeft(); - ModList.get().getModContainerById(config.getModId()).ifPresent(c -> c.registerExtensionPoint(IConfigScreenFactory.class, ((minecraft, screen) -> new CraterConfigScreen(config, screen)))); - } - }); diff --git a/patches/1.20/NeoForge/src/main/java/com/hypherionmc/craterlib/common/NeoForgeServerEvents.java.patch b/patches/1.20/NeoForge/src/main/java/com/hypherionmc/craterlib/common/NeoForgeServerEvents.java.patch index 0dab07e..3176ade 100644 --- a/patches/1.20/NeoForge/src/main/java/com/hypherionmc/craterlib/common/NeoForgeServerEvents.java.patch +++ b/patches/1.20/NeoForge/src/main/java/com/hypherionmc/craterlib/common/NeoForgeServerEvents.java.patch @@ -1,12 +1,11 @@ --- a/NeoForge/src/main/java/com/hypherionmc/craterlib/common/NeoForgeServerEvents.java +++ /dev/null -@@ -1,43 +1,0 @@ +@@ -1,41 +1,0 @@ -package com.hypherionmc.craterlib.common; - -import com.hypherionmc.craterlib.api.events.server.CraterRegisterCommandEvent; -import com.hypherionmc.craterlib.api.events.server.CraterServerLifecycleEvent; -import com.hypherionmc.craterlib.core.event.CraterEventBus; --import com.hypherionmc.craterlib.nojang.commands.CommandsRegistry; -import com.hypherionmc.craterlib.nojang.server.BridgedMinecraftServer; -import net.neoforged.bus.api.SubscribeEvent; -import net.neoforged.neoforge.event.RegisterCommandsEvent; @@ -39,8 +38,7 @@ - - @SubscribeEvent - public void onCommandRegister(RegisterCommandsEvent event) { -- CraterEventBus.INSTANCE.postEvent(new CraterRegisterCommandEvent()); -- CommandsRegistry.INSTANCE.registerCommands(event.getDispatcher()); +- CraterEventBus.INSTANCE.postEvent(new CraterRegisterCommandEvent(event.getDispatcher())); - } - -} diff --git a/patches/1.20/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java.patch b/patches/1.20/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java.patch index 631e6a6..2f716b8 100644 --- a/patches/1.20/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java.patch +++ b/patches/1.20/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ServerGamePacketListenerImplMixin.java.patch @@ -30,8 +30,8 @@ - cancellable = true - ) - private void injectChatEvent(Component component, PlayerChatMessage arg, FilteredText p_296589_, CallbackInfo ci) { -- Component finalArg = component == null ? arg.decoratedContent() : component; -- CraterServerChatEvent event = new CraterServerChatEvent(BridgedPlayer.of(this.player), finalArg.getString(), ChatUtils.mojangToAdventure(finalArg)); +- Component finalcomp = component == null ? arg.decoratedContent() : component; +- CraterServerChatEvent event = new CraterServerChatEvent(BridgedPlayer.of(this.player), finalcomp.getString(), ChatUtils.mojangToAdventure(finalcomp)); - CraterEventBus.INSTANCE.postEvent(event); - if (event.wasCancelled()) - ci.cancel(); diff --git a/patches/1.20/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java.patch b/patches/1.20/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java.patch new file mode 100644 index 0000000..555de60 --- /dev/null +++ b/patches/1.20/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java.patch @@ -0,0 +1,56 @@ +--- a/NeoForge/src/main/java/com/hypherionmc/craterlib/mixin/ServerStatusPacketListenerMixin.java ++++ /dev/null +@@ -1,53 +1,0 @@ +-package com.hypherionmc.craterlib.mixin; +- +-import com.hypherionmc.craterlib.api.events.server.ServerStatusEvent; +-import com.hypherionmc.craterlib.core.event.CraterEventBus; +-import com.hypherionmc.craterlib.utils.ChatUtils; +-import net.minecraft.network.Connection; +-import net.minecraft.network.protocol.status.ClientboundStatusResponsePacket; +-import net.minecraft.network.protocol.status.ServerStatus; +-import net.minecraft.network.protocol.status.ServerboundStatusRequestPacket; +-import net.minecraft.server.network.ServerStatusPacketListenerImpl; +-import org.spongepowered.asm.mixin.Final; +-import org.spongepowered.asm.mixin.Mixin; +-import org.spongepowered.asm.mixin.Shadow; +-import org.spongepowered.asm.mixin.injection.At; +-import org.spongepowered.asm.mixin.injection.Inject; +-import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +- +-@Mixin(ServerStatusPacketListenerImpl.class) +-public class ServerStatusPacketListenerMixin { +- +- @Shadow +- @Final +- private ServerStatus status; +- +- @Shadow @Final private Connection connection; +- +- @Inject(method = "handleStatusRequest", +- at = @At( +- value = "INVOKE", +- target = "Lnet/minecraft/network/Connection;send(Lnet/minecraft/network/protocol/Packet;)V", +- shift = At.Shift.BEFORE), +- cancellable = true +- ) +- private void injectHandleStatusRequest(ServerboundStatusRequestPacket arg, CallbackInfo ci) { +- ServerStatusEvent.StatusRequestEvent event = new ServerStatusEvent.StatusRequestEvent(ChatUtils.mojangToAdventure(status.description())); +- CraterEventBus.INSTANCE.postEvent(event); +- +- if (event.getNewStatus() != null) { +- ci.cancel(); +- this.connection.send(new ClientboundStatusResponsePacket( +- new ServerStatus(ChatUtils.adventureToMojang( +- event.getNewStatus()), +- status.players(), +- status.version(), +- status.favicon(), +- status.enforcesSecureChat(), +- status.isModded() +- ) +- )); +- } +- } +- +-} diff --git a/patches/1.20/NeoForge/src/main/resources/craterlib.neoforge.mixins.json.patch b/patches/1.20/NeoForge/src/main/resources/craterlib.neoforge.mixins.json.patch index 3732d52..075f957 100644 --- a/patches/1.20/NeoForge/src/main/resources/craterlib.neoforge.mixins.json.patch +++ b/patches/1.20/NeoForge/src/main/resources/craterlib.neoforge.mixins.json.patch @@ -1,6 +1,6 @@ --- a/NeoForge/src/main/resources/craterlib.neoforge.mixins.json +++ /dev/null -@@ -1,15 +1,0 @@ +@@ -1,16 +1,0 @@ -{ - "required": true, - "minVersion": "0.8", @@ -10,7 +10,8 @@ - ], - "client": [], - "server": [ -- "ServerGamePacketListenerImplMixin" +- "ServerGamePacketListenerImplMixin", +- "ServerStatusPacketListenerMixin" - ], - "injectors": { - "defaultRequire": 1 diff --git a/patches/1.20/README.md.patch b/patches/1.20/README.md.patch index 5fd4d92..4aea58e 100644 --- a/patches/1.20/README.md.patch +++ b/patches/1.20/README.md.patch @@ -1,12 +1,10 @@ --- a/README.md +++ b/README.md -@@ -15,8 +15,7 @@ +@@ -15,7 +15,6 @@ | < 1.18.2 | ❌ | | 1.18.2-1.20.2 | ✳️ | | 1.20.4 | ✳️ | -| 1.20.6 | ❌ | --| 1.21 | ✳️ | -+| 1.21 | 🚧 | + | 1.21.x | ✳️ | - ❌ - Not Supported; no bug fixes or new features. - - 🚧 - Work in Progress; not ready for release. diff --git a/patches/1.20/build.gradle.patch b/patches/1.20/build.gradle.patch index e17823d..02a0314 100644 --- a/patches/1.20/build.gradle.patch +++ b/patches/1.20/build.gradle.patch @@ -19,9 +19,9 @@ group = rootProject.group -@@ -58,7 +57,7 @@ - shade "me.hypherionmc.moon-config:core:${moon_config}" +@@ -59,7 +58,7 @@ shade "me.hypherionmc.moon-config:toml:${moon_config}" + shade "me.hypherionmc.moon-config:json:${moon_config}" shade "com.hypherionmc:rpcsdk:${rpc_sdk}" - shade "me.hypherionmc.sdlink:mcdiscordformatter-1.20.3:${discord_formatter}" + shade "me.hypherionmc.sdlink:mcdiscordformatter-1.19.1:${discord_formatter}" diff --git a/patches/1.21/.jenkins/Jenkinsfile.snapshot.patch b/patches/1.21/.jenkins/Jenkinsfile.snapshot.patch index 0c85330..c82758c 100644 --- a/patches/1.21/.jenkins/Jenkinsfile.snapshot.patch +++ b/patches/1.21/.jenkins/Jenkinsfile.snapshot.patch @@ -1,12 +1,10 @@ --- a/.jenkins/Jenkinsfile.snapshot +++ b/.jenkins/Jenkinsfile.snapshot -@@ -3,8 +3,8 @@ - def JDK = "21"; +@@ -4,7 +4,7 @@ def majorMc = "1.21"; def modLoaders = "neoforge|fabric|quilt"; --def supportedMc = "1.21"; + def supportedMc = "1.21|1.21.1"; -def reltype = "port"; -+def supportedMc = "1.21|1.21.1"; +def reltype = "snapshot"; pipeline { diff --git a/patches/1.21/README.md.patch b/patches/1.21/README.md.patch new file mode 100644 index 0000000..4aea58e --- /dev/null +++ b/patches/1.21/README.md.patch @@ -0,0 +1,10 @@ +--- a/README.md ++++ b/README.md +@@ -15,7 +15,6 @@ + | < 1.18.2 | ❌ | + | 1.18.2-1.20.2 | ✳️ | + | 1.20.4 | ✳️ | +-| 1.20.6 | ❌ | + | 1.21.x | ✳️ | + + - ❌ - Not Supported; no bug fixes or new features.