diff --git a/src/main/java/dev/micle/loginprotection/LoginProtection.java b/src/main/java/dev/micle/loginprotection/LoginProtection.java old mode 100644 new mode 100755 index cc47576..a9803c5 --- a/src/main/java/dev/micle/loginprotection/LoginProtection.java +++ b/src/main/java/dev/micle/loginprotection/LoginProtection.java @@ -1,77 +1,31 @@ package dev.micle.loginprotection; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Blocks; +import dev.micle.loginprotection.data.ProtectedPlayers; +import dev.micle.loginprotection.setup.Config; +import dev.micle.loginprotection.setup.Registration; +import net.minecraft.resources.ResourceLocation; import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.event.RegistryEvent; -import net.minecraftforge.event.server.ServerStartingEvent; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.InterModComms; import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; -import net.minecraftforge.fml.event.lifecycle.InterModEnqueueEvent; -import net.minecraftforge.fml.event.lifecycle.InterModProcessEvent; -import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; +import net.minecraftforge.network.NetworkRegistry; +import net.minecraftforge.network.simple.SimpleChannel; -import java.util.stream.Collectors; - -// The value here should match an entry in the META-INF/mods.toml file -@Mod("loginprotection") +@Mod(LoginProtection.MOD_ID) public class LoginProtection { - - // Directly reference a log4j logger. - private static final Logger LOGGER = LogManager.getLogger(); - - public LoginProtection() { - // Register the setup method for modloading - FMLJavaModLoadingContext.get().getModEventBus().addListener(this::setup); - // Register the enqueueIMC method for modloading - FMLJavaModLoadingContext.get().getModEventBus().addListener(this::enqueueIMC); - // Register the processIMC method for modloading - FMLJavaModLoadingContext.get().getModEventBus().addListener(this::processIMC); - - // Register ourselves for server and other game events we are interested in - MinecraftForge.EVENT_BUS.register(this); - } - - private void setup(final FMLCommonSetupEvent event) { - // some preinit code - LOGGER.info("HELLO FROM PREINIT"); - LOGGER.info("DIRT BLOCK >> {}", Blocks.DIRT.getRegistryName()); - } - - private void enqueueIMC(final InterModEnqueueEvent event) { - // some example code to dispatch IMC to another mod - InterModComms.sendTo("loginprotection", "helloworld", () -> { - LOGGER.info("Hello world from the MDK"); - return "Hello world"; - }); - } - - private void processIMC(final InterModProcessEvent event) { - // some example code to receive and process InterModComms from other mods - LOGGER.info("Got IMC {}", event.getIMCStream(). - map(m -> m.messageSupplier().get()). - collect(Collectors.toList())); - } - - // You can use SubscribeEvent and let the Event Bus discover methods to call - @SubscribeEvent - public void onServerStarting(ServerStartingEvent event) { - // do something when the server starts - LOGGER.info("HELLO from server starting"); - } - - // You can use EventBusSubscriber to automatically subscribe events on the contained class (this is subscribing to the MOD - // Event bus for receiving Registry Events) - @Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD) - public static class RegistryEvents { - @SubscribeEvent - public static void onBlocksRegistry(final RegistryEvent.Register blockRegistryEvent) { - // register a new block here - LOGGER.info("HELLO from Register Block"); - } - } + public static final String MOD_ID = "loginprotection"; + public static ProtectedPlayers protected_players = new ProtectedPlayers(); + + private static final String PROTOCOL_VERSION = "1"; + public static final SimpleChannel INSTANCE = NetworkRegistry.newSimpleChannel( + new ResourceLocation(LoginProtection.MOD_ID, "main"), + () -> PROTOCOL_VERSION, + PROTOCOL_VERSION::equals, + PROTOCOL_VERSION::equals + ); + + public LoginProtection() { + Registration.register(); + Config.init(); + + MinecraftForge.EVENT_BUS.register(this); + } } diff --git a/src/main/java/dev/micle/loginprotection/data/ProtectedPlayer.java b/src/main/java/dev/micle/loginprotection/data/ProtectedPlayer.java new file mode 100755 index 0000000..87b098a --- /dev/null +++ b/src/main/java/dev/micle/loginprotection/data/ProtectedPlayer.java @@ -0,0 +1,37 @@ +package dev.micle.loginprotection.data; + +import dev.micle.loginprotection.setup.Config; + +import java.util.UUID; + +public class ProtectedPlayer { + private final UUID player_uuid; + private int grace_period; + private boolean is_loading; + + public ProtectedPlayer(UUID player_uuid) { + this.player_uuid = player_uuid; + this.grace_period = (Config.Server.POST_GRACE_DURATION.get() * 40); + this.is_loading = true; + } + + public UUID getPlayerUUID() { + return this.player_uuid; + } + + public int getGracePeriod() { + return this.grace_period; + } + + public void setGracePeriod(int new_grace_period) { + this.grace_period = new_grace_period; + } + + public boolean isLoading() { + return this.is_loading; + } + + public void setLoading(boolean new_loading) { + this.is_loading = new_loading; + } +} diff --git a/src/main/java/dev/micle/loginprotection/data/ProtectedPlayers.java b/src/main/java/dev/micle/loginprotection/data/ProtectedPlayers.java new file mode 100755 index 0000000..be4bbfb --- /dev/null +++ b/src/main/java/dev/micle/loginprotection/data/ProtectedPlayers.java @@ -0,0 +1,58 @@ +package dev.micle.loginprotection.data; + +import dev.micle.loginprotection.setup.Config; +import net.minecraft.network.chat.TextComponent; +import net.minecraft.server.level.ServerPlayer; +import net.minecraftforge.server.ServerLifecycleHooks; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +public class ProtectedPlayers { + private final List protected_players = new ArrayList<>(); + + public ProtectedPlayers() { } + + public int size() { + return protected_players.size(); + } + + public void addPlayer(UUID player_uuid) { + protected_players.add(new ProtectedPlayer(player_uuid)); + } + + public ProtectedPlayer getPlayer(UUID player_uuid) { + ProtectedPlayer player; + for (ProtectedPlayer protected_player : protected_players) { + player = protected_player; + if (player.getPlayerUUID() == player_uuid) { + return player; + } + } + return null; + } + + public void removePlayer(UUID player_uuid) { + ProtectedPlayer protected_player = getPlayer(player_uuid); + if (protected_player == null) { return; } + protected_players.remove(protected_player); + + ServerPlayer player = ServerLifecycleHooks.getCurrentServer().getPlayerList().getPlayer(player_uuid); + if (player == null) { return; } + + if (!Config.Server.POST_GRACE_ENABLED.get()) { return; } + player.sendMessage(new TextComponent("[LoginProtection] Grace period ended!"), player_uuid); + } + + public void updateGracePeriod(UUID player_uuid) { + ProtectedPlayer protected_player = getPlayer(player_uuid); + if (protected_player.isLoading()) { return; } + + int grace_period = protected_player.getGracePeriod()-1; + protected_player.setGracePeriod(grace_period); + if (grace_period <= 0) { + removePlayer(player_uuid); + } + } +} diff --git a/src/main/java/dev/micle/loginprotection/events/OnKeyPressEventHandler.java b/src/main/java/dev/micle/loginprotection/events/OnKeyPressEventHandler.java new file mode 100755 index 0000000..6fa2526 --- /dev/null +++ b/src/main/java/dev/micle/loginprotection/events/OnKeyPressEventHandler.java @@ -0,0 +1,89 @@ +package dev.micle.loginprotection.events; + +import dev.micle.loginprotection.LoginProtection; +import dev.micle.loginprotection.network.C2SKeyPress; +import dev.micle.loginprotection.setup.Config; +import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.ServerData; +import net.minecraft.client.server.IntegratedServer; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.client.event.InputEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import org.lwjgl.glfw.GLFW; + +public class OnKeyPressEventHandler { + @SubscribeEvent + @OnlyIn(Dist.CLIENT) + public void KeyPressEvent(InputEvent.KeyInputEvent event) { + Minecraft instance = Minecraft.getInstance(); + ServerData server_online = instance.getCurrentServer(); + IntegratedServer server_local = instance.getSingleplayerServer(); + if (server_online == null && server_local == null) { return; } + if (Minecraft.getInstance().screen != null) { return; } + if (checkKeyAllowed(instance, event.getKey())) { return; } + + try { + LoginProtection.INSTANCE.sendToServer(new C2SKeyPress()); + } catch (NullPointerException ignored) { } + } + + @SubscribeEvent + @OnlyIn(Dist.CLIENT) + public void MouseClickEvent(InputEvent.ClickInputEvent event) { + Minecraft instance = Minecraft.getInstance(); + ServerData server_online = instance.getCurrentServer(); + IntegratedServer server_local = instance.getSingleplayerServer(); + if (server_online == null && server_local == null) { return; } + if (Minecraft.getInstance().screen != null) { return; } + if (checkKeyAllowed(instance, event.getKeyMapping().getKey().getValue())) { return; } + + try { + LoginProtection.INSTANCE.sendToServer(new C2SKeyPress()); + } catch (NullPointerException ignored) { } + } + + @OnlyIn(Dist.CLIENT) + private static boolean checkKeyAllowed(Minecraft instance, int key) { + boolean isAllowed = false; + + if (key == GLFW.GLFW_KEY_ESCAPE) { isAllowed = Config.Server.MAIN_KEY_ALLOW_LIST.get().contains(Config.Server.KEYS.PAUSE.toString()); } + if (key == GLFW.GLFW_KEY_F3) { isAllowed = Config.Server.MAIN_KEY_ALLOW_LIST.get().contains(Config.Server.KEYS.DEBUG.toString()); } + if (key == instance.options.keyFullscreen.getKey().getValue()) { isAllowed = Config.Server.MAIN_KEY_ALLOW_LIST.get().contains(Config.Server.KEYS.FULLSCREEN.toString()); } + if (key == instance.options.keyTogglePerspective.getKey().getValue()) { isAllowed = Config.Server.MAIN_KEY_ALLOW_LIST.get().contains(Config.Server.KEYS.PERSPECTIVE.toString()); } + if (key == instance.options.keySmoothCamera.getKey().getValue()) { isAllowed = Config.Server.MAIN_KEY_ALLOW_LIST.get().contains(Config.Server.KEYS.SMOOTH_CAMERA.toString()); } + if (key == instance.options.keyScreenshot.getKey().getValue()) { isAllowed = Config.Server.MAIN_KEY_ALLOW_LIST.get().contains(Config.Server.KEYS.SCREENSHOT.toString()); } + if (key == instance.options.keySpectatorOutlines.getKey().getValue()) { isAllowed = Config.Server.MAIN_KEY_ALLOW_LIST.get().contains(Config.Server.KEYS.SPECTATOR_OUTLINES.toString()); } + if (key == instance.options.keyAdvancements.getKey().getValue()) { isAllowed = Config.Server.MAIN_KEY_ALLOW_LIST.get().contains(Config.Server.KEYS.ADVANCEMENTS.toString()); } + if (key == instance.options.keyPlayerList.getKey().getValue()) { isAllowed = Config.Server.MAIN_KEY_ALLOW_LIST.get().contains(Config.Server.KEYS.PLAYER_LIST.toString()); } + if (key == instance.options.keyChat.getKey().getValue() || + key == instance.options.keyCommand.getKey().getValue() || + key == GLFW.GLFW_KEY_ENTER) { + isAllowed = Config.Server.MAIN_KEY_ALLOW_LIST.get().contains(Config.Server.KEYS.CHAT.toString()); + } + if (key == instance.options.keySocialInteractions.getKey().getValue()) { isAllowed = Config.Server.MAIN_KEY_ALLOW_LIST.get().contains(Config.Server.KEYS.SOCIAL_INTERACTIONS.toString()); } + if (key == instance.options.keyLoadHotbarActivator.getKey().getValue()) { isAllowed = Config.Server.MAIN_KEY_ALLOW_LIST.get().contains(Config.Server.KEYS.LOAD_HOTBAR_ACTIVATOR.toString()); } + if (key == instance.options.keySaveHotbarActivator.getKey().getValue()) { isAllowed = Config.Server.MAIN_KEY_ALLOW_LIST.get().contains(Config.Server.KEYS.SAVE_HOTBAR_ACTIVATOR.toString()); } + if (key == instance.options.keySwapOffhand.getKey().getValue()) { isAllowed = Config.Server.MAIN_KEY_ALLOW_LIST.get().contains(Config.Server.KEYS.SWAP_ITEM.toString()); } + if (key == instance.options.keyInventory.getKey().getValue()) { isAllowed = Config.Server.MAIN_KEY_ALLOW_LIST.get().contains(Config.Server.KEYS.INVENTORY.toString()); } + for (int i = 0; i < instance.options.keyHotbarSlots.length; i++) { + if (key == instance.options.keyHotbarSlots[i].getKey().getValue()) { isAllowed = Config.Server.MAIN_KEY_ALLOW_LIST.get().contains(Config.Server.KEYS.HOTBAR.toString()); } + } + if (key == instance.options.keyDrop.getKey().getValue()) { isAllowed = Config.Server.MAIN_KEY_ALLOW_LIST.get().contains(Config.Server.KEYS.DROP_ITEM.toString()); } + if (key == instance.options.keyUse.getKey().getValue()) { isAllowed = Config.Server.MAIN_KEY_ALLOW_LIST.get().contains(Config.Server.KEYS.USE_ITEM.toString()); } + if (key == instance.options.keyPickItem.getKey().getValue()) { isAllowed = Config.Server.MAIN_KEY_ALLOW_LIST.get().contains(Config.Server.KEYS.PICK_BLOCK.toString()); } + if (key == instance.options.keyAttack.getKey().getValue()) { isAllowed = Config.Server.MAIN_KEY_ALLOW_LIST.get().contains(Config.Server.KEYS.ATTACK.toString()); } + if (key == instance.options.keyUp.getKey().getValue() || + key == instance.options.keyRight.getKey().getValue() || + key == instance.options.keyDown.getKey().getValue() || + key == instance.options.keyLeft.getKey().getValue() || + key == instance.options.keySprint.getKey().getValue()) { + isAllowed = Config.Server.MAIN_KEY_ALLOW_LIST.get().contains(Config.Server.KEYS.MOVE.toString()); + } + if (key == instance.options.keyShift.getKey().getValue()) { isAllowed = Config.Server.MAIN_KEY_ALLOW_LIST.get().contains(Config.Server.KEYS.SNEAK.toString()); } + if (key == instance.options.keyJump.getKey().getValue()) { isAllowed = Config.Server.MAIN_KEY_ALLOW_LIST.get().contains(Config.Server.KEYS.JUMP.toString()); } + + return isAllowed; + } + +} diff --git a/src/main/java/dev/micle/loginprotection/events/OnLivingSetAttackTargetEventHandler.java b/src/main/java/dev/micle/loginprotection/events/OnLivingSetAttackTargetEventHandler.java new file mode 100644 index 0000000..de82aea --- /dev/null +++ b/src/main/java/dev/micle/loginprotection/events/OnLivingSetAttackTargetEventHandler.java @@ -0,0 +1,23 @@ +package dev.micle.loginprotection.events; + +import dev.micle.loginprotection.LoginProtection; +import dev.micle.loginprotection.data.ProtectedPlayer; +import dev.micle.loginprotection.setup.Config; +import net.minecraft.world.entity.Mob; +import net.minecraft.world.entity.player.Player; +import net.minecraftforge.event.entity.living.LivingSetAttackTargetEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; + +public class OnLivingSetAttackTargetEventHandler { + @SubscribeEvent + public void LivingSetAttackTargetEvent(LivingSetAttackTargetEvent event) { + if (!(event.getTarget() instanceof Player target)) { return; } + + ProtectedPlayer player = LoginProtection.protected_players.getPlayer(target.getUUID()); + if (player == null) { return; } + if (player.isLoading() && !Config.Server.MAIN_IGNORE_PLAYER_ENABLED.get()) { return; } + if (!player.isLoading() && !Config.Server.POST_GRACE_IGNORE_PLAYER_ENABLED.get()) { return; } + ((Mob) event.getEntityLiving()).setTarget(null); + } + +} diff --git a/src/main/java/dev/micle/loginprotection/events/OnPlayerDamageEventHandler.java b/src/main/java/dev/micle/loginprotection/events/OnPlayerDamageEventHandler.java new file mode 100755 index 0000000..37c815a --- /dev/null +++ b/src/main/java/dev/micle/loginprotection/events/OnPlayerDamageEventHandler.java @@ -0,0 +1,18 @@ +package dev.micle.loginprotection.events; + +import dev.micle.loginprotection.LoginProtection; +import net.minecraft.world.entity.player.Player; +import net.minecraftforge.event.entity.living.LivingDamageEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; + +public class OnPlayerDamageEventHandler { + @SubscribeEvent + public void LivingDamageEvent(LivingDamageEvent event) { + if (!(event.getEntity() instanceof Player)) { return; } + Player player = (Player) event.getEntity(); + + if (LoginProtection.protected_players.getPlayer(player.getUUID()) != null) { + event.setCanceled(true); + } + } +} diff --git a/src/main/java/dev/micle/loginprotection/events/OnPlayerJoinEventHandler.java b/src/main/java/dev/micle/loginprotection/events/OnPlayerJoinEventHandler.java new file mode 100755 index 0000000..f39885d --- /dev/null +++ b/src/main/java/dev/micle/loginprotection/events/OnPlayerJoinEventHandler.java @@ -0,0 +1,17 @@ +package dev.micle.loginprotection.events; + +import dev.micle.loginprotection.LoginProtection; +import net.minecraft.world.entity.player.Player; +import net.minecraftforge.event.entity.player.PlayerEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; + +public class OnPlayerJoinEventHandler { + @SubscribeEvent + public void EntityJoinWorldEvent(PlayerEvent.PlayerLoggedInEvent event) { + if (!(event.getEntity() instanceof Player)) { return; } + Player player = (Player) event.getEntity(); + + LoginProtection.protected_players.addPlayer(player.getUUID()); + System.out.println(player.getUUID() + " (" + player.getDisplayName().getString() + ") is being protected!"); + } +} diff --git a/src/main/java/dev/micle/loginprotection/events/OnPlayerLeaveEventHandler.java b/src/main/java/dev/micle/loginprotection/events/OnPlayerLeaveEventHandler.java new file mode 100755 index 0000000..f496353 --- /dev/null +++ b/src/main/java/dev/micle/loginprotection/events/OnPlayerLeaveEventHandler.java @@ -0,0 +1,16 @@ +package dev.micle.loginprotection.events; + +import dev.micle.loginprotection.LoginProtection; +import net.minecraft.world.entity.player.Player; +import net.minecraftforge.event.entity.player.PlayerEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; + +public class OnPlayerLeaveEventHandler { + @SubscribeEvent + public void PlayerLeaveEvent(PlayerEvent.PlayerLoggedOutEvent event) { + if (!(event.getEntity() instanceof Player)) { return; } + Player player = event.getPlayer(); + + LoginProtection.protected_players.removePlayer(player.getUUID()); + } +} diff --git a/src/main/java/dev/micle/loginprotection/events/OnPlayerTickEventHandler.java b/src/main/java/dev/micle/loginprotection/events/OnPlayerTickEventHandler.java new file mode 100755 index 0000000..ab91394 --- /dev/null +++ b/src/main/java/dev/micle/loginprotection/events/OnPlayerTickEventHandler.java @@ -0,0 +1,14 @@ +package dev.micle.loginprotection.events; + +import dev.micle.loginprotection.LoginProtection; +import net.minecraftforge.event.TickEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; + +public class OnPlayerTickEventHandler { + @SubscribeEvent + public void PlayerTickEvent(TickEvent.PlayerTickEvent event) { + if (LoginProtection.protected_players.getPlayer(event.player.getUUID()) == null) { return; } + + LoginProtection.protected_players.updateGracePeriod(event.player.getUUID()); + } +} diff --git a/src/main/java/dev/micle/loginprotection/network/C2SKeyPress.java b/src/main/java/dev/micle/loginprotection/network/C2SKeyPress.java new file mode 100755 index 0000000..b623c25 --- /dev/null +++ b/src/main/java/dev/micle/loginprotection/network/C2SKeyPress.java @@ -0,0 +1,55 @@ +package dev.micle.loginprotection.network; + +import dev.micle.loginprotection.LoginProtection; +import dev.micle.loginprotection.setup.Config; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.chat.TextComponent; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.effect.MobEffectInstance; +import net.minecraft.world.effect.MobEffects; +import net.minecraftforge.network.NetworkEvent; + +import java.util.function.Supplier; + +public class C2SKeyPress { + public C2SKeyPress() { } + + public static void encode(final C2SKeyPress msg, final FriendlyByteBuf packet_buffer) { } + + public static C2SKeyPress decode(final FriendlyByteBuf packet_buffer) { + return new C2SKeyPress(); + } + + public static void handle(final C2SKeyPress msg, final Supplier context_supplier) { + final NetworkEvent.Context context = context_supplier.get(); + context.enqueueWork(() -> { + final ServerPlayer sender = context.getSender(); + if (sender == null) { return; } + if (LoginProtection.protected_players.getPlayer(sender.getUUID()) == null) { return; } + if (!LoginProtection.protected_players.getPlayer(sender.getUUID()).isLoading()) { return; } + + if (!Config.Server.POST_GRACE_ENABLED.get()) { + LoginProtection.protected_players.removePlayer(sender.getUUID()); + sender.sendMessage(new TextComponent("[LoginProtection] You are now seen as active."), sender.getUUID()); + } else { + LoginProtection.protected_players.getPlayer(sender.getUUID()).setLoading(false); + sender.sendMessage(new TextComponent("[LoginProtection] Grace period started!"), sender.getUUID()); + } + if (sender.isInWater()) { + if (Config.Server.POST_DROWN_ENABLED.get()) { + sender.setAirSupply(sender.getMaxAirSupply()); + } + if (Config.Server.POST_WATER_ENABLED.get()) { + sender.addEffect(new MobEffectInstance(MobEffects.WATER_BREATHING, Config.Server.POST_WATER_DURATION.get()*20, 0)); + } + } + if (sender.isInLava() && Config.Server.POST_LAVA_ENABLED.get()) { + sender.addEffect(new MobEffectInstance(MobEffects.FIRE_RESISTANCE, Config.Server.POST_LAVA_DURATION.get()*20, 0)); + } + if (sender.isOnFire() && Config.Server.POST_FIRE_ENABLED.get()) { + sender.addEffect(new MobEffectInstance(MobEffects.FIRE_RESISTANCE, Config.Server.POST_FIRE_DURATION.get()*20, 0)); + } + }); + context.setPacketHandled(true); + } +} diff --git a/src/main/java/dev/micle/loginprotection/setup/Config.java b/src/main/java/dev/micle/loginprotection/setup/Config.java new file mode 100644 index 0000000..203074d --- /dev/null +++ b/src/main/java/dev/micle/loginprotection/setup/Config.java @@ -0,0 +1,127 @@ +package dev.micle.loginprotection.setup; + +import com.google.common.collect.Lists; +import dev.micle.loginprotection.LoginProtection; +import net.minecraftforge.common.ForgeConfigSpec; +import net.minecraftforge.fml.ModLoadingContext; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.config.ModConfig; +import org.apache.commons.lang3.tuple.Pair; + +import java.util.List; + +@Mod.EventBusSubscriber(modid = LoginProtection.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD) +public final class Config { + public static final Server SERVER; + public static final ForgeConfigSpec SERVER_SPEC; + static { + Pair spec_pair = new ForgeConfigSpec.Builder().configure(Server::new); + SERVER = spec_pair.getLeft(); + SERVER_SPEC = spec_pair.getRight(); + } + + public static void init() { + ModLoadingContext.get().registerConfig(ModConfig.Type.SERVER, SERVER_SPEC); + } + + public static class Server { + public enum KEYS { + PAUSE, + DEBUG, + FULLSCREEN, + PERSPECTIVE, + SMOOTH_CAMERA, + SCREENSHOT, + SPECTATOR_OUTLINES, + ADVANCEMENTS, + PLAYER_LIST, + CHAT, + SOCIAL_INTERACTIONS, + LOAD_HOTBAR_ACTIVATOR, + SAVE_HOTBAR_ACTIVATOR, + SWAP_ITEM, + INVENTORY, + HOTBAR, + DROP_ITEM, + USE_ITEM, + PICK_BLOCK, + ATTACK, + MOVE, + SNEAK, + JUMP + } + + public static ForgeConfigSpec.BooleanValue POST_GRACE_ENABLED; + public static ForgeConfigSpec.BooleanValue POST_GRACE_IGNORE_PLAYER_ENABLED; + public static ForgeConfigSpec.IntValue POST_GRACE_DURATION; + public static ForgeConfigSpec.BooleanValue POST_DROWN_ENABLED; + public static ForgeConfigSpec.BooleanValue POST_WATER_ENABLED; + public static ForgeConfigSpec.IntValue POST_WATER_DURATION; + public static ForgeConfigSpec.BooleanValue POST_LAVA_ENABLED; + public static ForgeConfigSpec.IntValue POST_LAVA_DURATION; + public static ForgeConfigSpec.BooleanValue POST_FIRE_ENABLED; + public static ForgeConfigSpec.IntValue POST_FIRE_DURATION; + + public static ForgeConfigSpec.BooleanValue MAIN_IGNORE_PLAYER_ENABLED; + public static ForgeConfigSpec.ConfigValue> MAIN_KEY_ALLOW_LIST; + + Server(ForgeConfigSpec.Builder builder) { + builder.comment("Main protection settings for protecting inactive (loading) players.").push("main"); + MAIN_IGNORE_PLAYER_ENABLED = builder + .comment("Whether mobs will ignore a protected player. (They will not attack/aggro)") + .define("ignorePlayerEnabled", true); + builder.push("allow_keys"); + MAIN_KEY_ALLOW_LIST = builder + .comment("Allowed keys players can press without becoming active.\n" + + "Available values: PAUSE, DEBUG, FULLSCREEN, PERSPECTIVE, SMOOTH_CAMERA, SCREENSHOT, SPECTATOR_OUTLINES,\n" + + "ADVANCEMENTS, PLAYER_LIST, CHAT, SOCIAL_INTERACTIONS, LOAD_HOTBAR_ACTIVATOR, SAVE_HOTBAR_ACTIVATOR,\n" + + "SWAP_ITEM, INVENTORY, HOTBAR, DROP_ITEM, USE_ITEM, PICK_BLOCK, ATTACK, MOVE, SNEAK, JUMP") + .defineList("allowedKeys", Lists.newArrayList(KEYS.PAUSE.toString(), KEYS.DEBUG.toString(), KEYS.FULLSCREEN.toString(), KEYS.PERSPECTIVE.toString(), KEYS.SMOOTH_CAMERA.toString(), + KEYS.SCREENSHOT.toString(), KEYS.SPECTATOR_OUTLINES.toString(), KEYS.ADVANCEMENTS.toString(), KEYS.PLAYER_LIST.toString(), KEYS.CHAT.toString(), KEYS.SOCIAL_INTERACTIONS.toString(), + KEYS.LOAD_HOTBAR_ACTIVATOR.toString(), KEYS.SAVE_HOTBAR_ACTIVATOR.toString(), KEYS.SWAP_ITEM.toString(), KEYS.HOTBAR.toString(), KEYS.PICK_BLOCK.toString()), o -> o instanceof String); + builder.pop(); + builder.pop(); + + builder.comment("Additional protection settings that apply as soon as a player becomes active.").push("post"); + builder.push("grace_period"); + POST_GRACE_ENABLED = builder + .comment("Whether a player receives a grace period after becoming active or not.") + .define("graceEnabled", false); + POST_GRACE_DURATION = builder + .comment("Grace period duration in seconds.") + .defineInRange("graceDuration", 10, 1, Integer.MAX_VALUE/40); + POST_GRACE_IGNORE_PLAYER_ENABLED = builder + .comment("Whether mobs will ignore a player during their grace period.") + .define("graceIgnorePlayerEnabled", false); + builder.pop(); + builder.push("water_protection"); + POST_DROWN_ENABLED = builder + .comment("Whether a player's air supply gets refilled.") + .define("drownEnabled", true); + POST_WATER_ENABLED = builder + .comment("Whether a player receives water breating when in water.") + .define("waterEnabled", false); + POST_WATER_DURATION = builder + .comment("Water breathing duration in seconds.") + .defineInRange("waterDuration", 10, 1, Integer.MAX_VALUE/20); + builder.pop(); + builder.push("lava_protection"); + POST_LAVA_ENABLED = builder + .comment("Whether a player receives fire resistance when in lava.") + .define("lavaEnabled", true); + POST_LAVA_DURATION = builder + .comment("Fire resistance duration in seconds.") + .defineInRange("lavaDuration", 10, 1, Integer.MAX_VALUE/20); + builder.pop(); + builder.push("fire_protection"); + POST_FIRE_ENABLED = builder + .comment("Whether a player receives fire resistance when on fire.") + .define("fireEnabled", false); + POST_FIRE_DURATION = builder + .comment("Fire resistance duration in seconds.") + .defineInRange("fireDuration", 10, 1, Integer.MAX_VALUE/20); + builder.pop(); + builder.pop(); + } + } +} \ No newline at end of file diff --git a/src/main/java/dev/micle/loginprotection/setup/Registration.java b/src/main/java/dev/micle/loginprotection/setup/Registration.java new file mode 100755 index 0000000..fc22ca3 --- /dev/null +++ b/src/main/java/dev/micle/loginprotection/setup/Registration.java @@ -0,0 +1,29 @@ +package dev.micle.loginprotection.setup; + +import dev.micle.loginprotection.LoginProtection; +import dev.micle.loginprotection.events.*; +import dev.micle.loginprotection.network.C2SKeyPress; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.eventbus.api.IEventBus; +import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; + +public class Registration { + public static void register() { + IEventBus mod_event_bus = FMLJavaModLoadingContext.get().getModEventBus(); + + MinecraftForge.EVENT_BUS.register(new OnPlayerJoinEventHandler()); + MinecraftForge.EVENT_BUS.register(new OnPlayerDamageEventHandler()); + MinecraftForge.EVENT_BUS.register(new OnPlayerTickEventHandler()); + MinecraftForge.EVENT_BUS.register(new OnKeyPressEventHandler()); + MinecraftForge.EVENT_BUS.register(new OnPlayerLeaveEventHandler()); + MinecraftForge.EVENT_BUS.register(new OnLivingSetAttackTargetEventHandler()); + + int id = 0; + LoginProtection.INSTANCE.registerMessage(id++, + C2SKeyPress.class, + C2SKeyPress::encode, + C2SKeyPress::decode, + C2SKeyPress::handle + ); + } +} diff --git a/src/main/resources/META-INF/mods.toml b/src/main/resources/META-INF/mods.toml index ac7ae1b..3852a1f 100644 --- a/src/main/resources/META-INF/mods.toml +++ b/src/main/resources/META-INF/mods.toml @@ -21,7 +21,7 @@ modId = "loginprotection" #mandatory # see the associated build.gradle script for how to populate this completely automatically during a build version = "${file.jarVersion}" #mandatory # A display name for the mod -displayName = "LoginProtection" #mandatory +displayName = "Micle's Login Protection" #mandatory # A URL to query for updates for this mod. See the JSON update specification #updateJSONURL="http://myurl.me/" #optional # A URL for the "homepage" for this mod, displayed in the mod UI @@ -34,25 +34,25 @@ displayName = "LoginProtection" #mandatory authors = "Micle" #optional # The description text for the mod (multi line!) (#mandatory) description = ''' - +Mod for protecting players from damage while joining a server. ''' # A dependency - use the . to indicate dependency for a specific modid. Dependencies are optional. [[dependencies.loginprotection]] #optional -# the modid of the dependency -modId = "forge" #mandatory -# Does this dependency have to exist - if not, ordering below must be specified -mandatory = true #mandatory -# The version range of the dependency -versionRange = "[39,)" #mandatory -# An ordering relationship for the dependency - BEFORE or AFTER required if the relationship is not mandatory -ordering = "NONE" -# Side this dependency is applied on - BOTH, CLIENT or SERVER -side = "BOTH" + # the modid of the dependency + modId = "forge" #mandatory + # Does this dependency have to exist - if not, ordering below must be specified + mandatory = true #mandatory + # The version range of the dependency + versionRange = "[39,)" #mandatory + # An ordering relationship for the dependency - BEFORE or AFTER required if the relationship is not mandatory + ordering = "NONE" + # Side this dependency is applied on - BOTH, CLIENT or SERVER + side = "BOTH" # Here's another dependency [[dependencies.loginprotection]] -modId = "minecraft" -mandatory = true -# This version range declares a minimum of the current minecraft version up to but not including the next major version -versionRange = "[1.18.1,1.19)" -ordering = "NONE" -side = "BOTH" + modId = "minecraft" + mandatory = true + # This version range declares a minimum of the current minecraft version up to but not including the next major version + versionRange = "[1.18.1,1.19)" + ordering = "NONE" + side = "BOTH"