diff --git a/src/main/java/org/examp/john/AntiAbuse.java b/src/main/java/org/examp/john/AntiAbuse.java index db139a1..d445dbb 100644 --- a/src/main/java/org/examp/john/AntiAbuse.java +++ b/src/main/java/org/examp/john/AntiAbuse.java @@ -20,6 +20,7 @@ import java.util.UUID; */ public class AntiAbuse { + private static final int REPEAT_THRESHOLD = 5; private static final double DISTANCE_THRESHOLD = 50.0; private static final long TIME_WINDOW_MS = 5 * 60 * 1000; diff --git a/src/main/java/org/examp/john/MSNexus.java b/src/main/java/org/examp/john/MSNexus.java index 8eda984..4b067d9 100644 --- a/src/main/java/org/examp/john/MSNexus.java +++ b/src/main/java/org/examp/john/MSNexus.java @@ -1,8 +1,6 @@ package org.examp.john; import net.fabricmc.api.ModInitializer; -import org.examp.john.social.FakeJoinCommand; -import org.examp.john.social.FakeLeaveCommand; import org.examp.john.stealth.StealthCommand; import org.examp.john.stealth.StealthStorage; import org.slf4j.Logger; @@ -17,7 +15,5 @@ public class MSNexus implements ModInitializer { StealthStorage.load(); ChatHandler.register(); StealthCommand.register(); - FakeLeaveCommand.register(); - FakeJoinCommand.register(); } } diff --git a/src/main/java/org/examp/john/mixin/LeaveMessageMixin.java b/src/main/java/org/examp/john/mixin/LeaveMessageMixin.java deleted file mode 100644 index c39537e..0000000 --- a/src/main/java/org/examp/john/mixin/LeaveMessageMixin.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.examp.john.mixin; - -import net.minecraft.network.chat.Component; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.network.ServerGamePacketListenerImpl; -import net.minecraft.server.players.PlayerList; -import org.examp.john.social.FakeLeaveStorage; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; - -/** - * Перехоплює відправку повідомлення "гравець вийшов з гри" - * якщо гравець в стані fake leave. - * Використовує @Redirect щоб НЕ блокувати весь disconnect. - */ -@Mixin(ServerGamePacketListenerImpl.class) -public class LeaveMessageMixin { - - @Redirect( - method = "removePlayerFromWorld", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/server/players/PlayerList;broadcastSystemMessage(Lnet/minecraft/network/chat/Component;Z)V" - ) - ) - private void suppressLeaveMessage(PlayerList instance, Component message, boolean isOverlay) { - ServerGamePacketListenerImpl self = (ServerGamePacketListenerImpl) (Object) this; - if (FakeLeaveStorage.contains(self.player.getUUID())) { - FakeLeaveStorage.remove(self.player.getUUID()); - return; - } - instance.broadcastSystemMessage(message, isOverlay); - } -} diff --git a/src/main/java/org/examp/john/social/FakeJoinCommand.java b/src/main/java/org/examp/john/social/FakeJoinCommand.java deleted file mode 100644 index f54904d..0000000 --- a/src/main/java/org/examp/john/social/FakeJoinCommand.java +++ /dev/null @@ -1,88 +0,0 @@ -package org.examp.john.social; - -import com.mojang.brigadier.builder.LiteralArgumentBuilder; -import com.mojang.brigadier.context.CommandContext; -import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback; -import net.luckperms.api.LuckPerms; -import net.luckperms.api.LuckPermsProvider; -import net.luckperms.api.model.user.User; -import net.minecraft.ChatFormatting; -import net.minecraft.commands.CommandSourceStack; -import net.minecraft.commands.Commands; -import net.minecraft.network.chat.Component; -import net.minecraft.network.protocol.game.ClientboundPlayerInfoUpdatePacket; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.server.players.NameAndId; - -import java.util.Collection; -import java.util.EnumSet; -import java.util.List; -import java.util.UUID; - -/** - * /fakejoin — для опів та гравців з LuckPerms: msnexus.command.fakejoin. - * Надсилає фейкове повідомлення "приєднався до гри", повертає в таб. - */ -public class FakeJoinCommand { - - public static void register() { - CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> - dispatcher.register(buildCommand()) - ); - } - - private static LiteralArgumentBuilder buildCommand() { - return Commands.literal("fakejoin") - .requires(source -> hasPermission(source)) - .executes(FakeJoinCommand::execute); - } - - private static boolean hasPermission(CommandSourceStack source) { - if (!(source.getEntity() instanceof ServerPlayer player)) return false; - // Опка = доступ за замовчуванням - MinecraftServer server = source.getServer(); - if (server.getPlayerList().isOp(new NameAndId(player.getUUID(), player.getName().getString()))) { - return true; - } - // Інакше — через LuckPerms - try { - LuckPerms api = LuckPermsProvider.get(); - User user = api.getUserManager().getUser(player.getUUID()); - if (user == null) return false; - return user.getCachedData().getPermissionData().checkPermission("msnexus.command.fakejoin").asBoolean(); - } catch (Throwable e) { - return false; - } - } - - private static int execute(CommandContext context) { - if (!(context.getSource().getEntity() instanceof ServerPlayer player)) { - context.getSource().sendFailure( - Component.literal("Цю команду можна викликати лише в грі.")); - return 0; - } - - FakeLeaveStorage.remove(player.getUUID()); - - MinecraftServer server = player.level().getServer(); - - // Фейкове повідомлення "приєднався до гри" - server.getPlayerList().broadcastSystemMessage( - Component.translatable("multiplayer.player.joined", player.getDisplayName()) - .withStyle(ChatFormatting.YELLOW), - false - ); - - // Повернути в таб — надіслати інформацію про гравця ВСІМ - ClientboundPlayerInfoUpdatePacket addPacket = ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(List.of(player)); - for (ServerPlayer online : server.getPlayerList().getPlayers()) { - online.connection.send(addPacket); - } - - player.sendSystemMessage( - Component.literal("Fake join активовано. Вас повернуто в таб.") - .withStyle(ChatFormatting.GRAY)); - return 1; - } -} diff --git a/src/main/java/org/examp/john/social/FakeLeaveCommand.java b/src/main/java/org/examp/john/social/FakeLeaveCommand.java deleted file mode 100644 index 889d484..0000000 --- a/src/main/java/org/examp/john/social/FakeLeaveCommand.java +++ /dev/null @@ -1,91 +0,0 @@ -package org.examp.john.social; - -import com.mojang.brigadier.builder.LiteralArgumentBuilder; -import com.mojang.brigadier.context.CommandContext; -import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback; -import net.luckperms.api.LuckPerms; -import net.luckperms.api.LuckPermsProvider; -import net.luckperms.api.model.user.User; -import net.minecraft.ChatFormatting; -import net.minecraft.commands.CommandSourceStack; -import net.minecraft.commands.Commands; -import net.minecraft.network.chat.Component; -import net.minecraft.network.protocol.game.ClientboundPlayerInfoRemovePacket; -import net.minecraft.network.protocol.game.ClientboundPlayerInfoUpdatePacket; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.server.players.NameAndId; -import net.minecraft.world.level.GameType; - -import java.util.Collection; -import java.util.EnumSet; -import java.util.List; -import java.util.UUID; - -/** - * /fakeleave — для опів та гравців з LuckPerms: msnexus.command.fakeleave. - * Надсилає фейкове повідомлення "гравець вийшов", ховає з табу. - */ -public class FakeLeaveCommand { - - public static void register() { - CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> - dispatcher.register(buildCommand()) - ); - } - - private static LiteralArgumentBuilder buildCommand() { - return Commands.literal("fakeleave") - .requires(source -> hasPermission(source)) - .executes(FakeLeaveCommand::execute); - } - - private static boolean hasPermission(CommandSourceStack source) { - if (!(source.getEntity() instanceof ServerPlayer player)) return false; - // Опка = доступ за замовчуванням - MinecraftServer server = source.getServer(); - if (server.getPlayerList().isOp(new NameAndId(player.getUUID(), player.getName().getString()))) { - return true; - } - // Інакше — через LuckPerms - try { - LuckPerms api = LuckPermsProvider.get(); - User user = api.getUserManager().getUser(player.getUUID()); - if (user == null) return false; - return user.getCachedData().getPermissionData().checkPermission("msnexus.command.fakeleave").asBoolean(); - } catch (Throwable e) { - return false; - } - } - - private static int execute(CommandContext context) { - if (!(context.getSource().getEntity() instanceof ServerPlayer player)) { - context.getSource().sendFailure( - Component.literal("Цю команду можна викликати лише в грі.")); - return 0; - } - - FakeLeaveStorage.add(player.getUUID()); - - MinecraftServer server = player.level().getServer(); - - // Фейкове повідомлення "вийшов з гри" - server.getPlayerList().broadcastSystemMessage( - Component.translatable("multiplayer.player.left", player.getDisplayName()) - .withStyle(ChatFormatting.YELLOW), - false - ); - - // Прибрати з табу для ВСІХ гравців (включаючи себе) - ClientboundPlayerInfoRemovePacket removePacket = - new ClientboundPlayerInfoRemovePacket(List.of(player.getUUID())); - for (ServerPlayer online : server.getPlayerList().getPlayers()) { - online.connection.send(removePacket); - } - - player.sendSystemMessage( - Component.literal("Fake leave активовано. Вас прибрано з табу.") - .withStyle(ChatFormatting.GRAY)); - return 1; - } -} diff --git a/src/main/java/org/examp/john/social/FakeLeaveStorage.java b/src/main/java/org/examp/john/social/FakeLeaveStorage.java deleted file mode 100644 index ce85304..0000000 --- a/src/main/java/org/examp/john/social/FakeLeaveStorage.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.examp.john.social; - -import java.util.HashSet; -import java.util.Set; -import java.util.UUID; - -/** - * Трекінг гравців у стані "fake leave". - * Коли гравець використав /fakeleave, його UUID додається до цього сету. - * Коли гравець реально виходить з сервера — реальний leave message блокується. - */ -public class FakeLeaveStorage { - - private static final Set fakeLeft = new HashSet<>(); - - public static void add(UUID uuid) { - fakeLeft.add(uuid); - } - - public static void remove(UUID uuid) { - fakeLeft.remove(uuid); - } - - public static boolean contains(UUID uuid) { - return fakeLeft.contains(uuid); - } -} diff --git a/src/main/resources/msnexus.mixins.json b/src/main/resources/msnexus.mixins.json index 7fcfb16..eb1a5f0 100644 --- a/src/main/resources/msnexus.mixins.json +++ b/src/main/resources/msnexus.mixins.json @@ -4,7 +4,6 @@ "package": "org.examp.john.mixin", "compatibilityLevel": "JAVA_25", "mixins": [ - "LeaveMessageMixin" ], "injectors": { "defaultRequire": 1