From 153d354c60c45e04f301dd387a2779edd94da8e9 Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Thu, 11 Apr 2024 00:22:55 +0200 Subject: [PATCH] Porta Porting --- build.gradle | 5 + src/de/steamwar/bungeecore/ServerStarter.java | 2 +- .../steamwar/bungeecore/SubserverSystem.java | 7 +- src/de/steamwar/bungeecore/VelocityCore.java | 7 - .../bungeecore/listeners/IPSanitizer.java | 42 +++--- .../bungeecore/listeners/PluginMessage.java | 46 ++++-- src/de/steamwar/bungeecore/mods/Badlion.java | 14 +- .../steamwar/bungeecore/mods/Controlify.java | 14 +- src/de/steamwar/bungeecore/mods/FML.java | 88 ++++++++---- src/de/steamwar/bungeecore/mods/FML2.java | 132 +++++++++--------- .../bungeecore/mods/FabricModSender.java | 55 +++++--- src/de/steamwar/bungeecore/mods/Feather.java | 10 +- src/de/steamwar/bungeecore/mods/LabyMod.java | 27 ++-- src/de/steamwar/bungeecore/mods/Lunar.java | 30 ++-- src/de/steamwar/bungeecore/mods/ModUtils.java | 31 ++-- .../bungeecore/mods/WorldDownloader.java | 6 +- .../bungeecore/network/ServerMetaInfo.java | 2 +- src/de/steamwar/bungeecore/util/BauLock.java | 27 ++-- src/de/steamwar/bungeecore/util/Chat19.java | 29 ++-- .../bungeecore/util/SteamWarModule.java | 10 +- .../steamwar/command/CommandRegistering.java | 55 +++++++- 21 files changed, 399 insertions(+), 240 deletions(-) diff --git a/build.gradle b/build.gradle index 885077d..93dfbab 100644 --- a/build.gradle +++ b/build.gradle @@ -73,6 +73,7 @@ repositories { includeGroup 'com.lunarclient' } } + mavenLocal() } shadowJar { @@ -92,6 +93,7 @@ dependencies { compileOnly 'com.velocitypowered:velocity-api:3.3.0-SNAPSHOT' annotationProcessor 'com.velocitypowered:velocity-api:3.3.0-SNAPSHOT' + compileOnly 'com.velocitypowered:velocity-proxy:3.3.0-SNAPSHOT' compileOnly 'de.steamwar:persistentbungeecore:RELEASE' implementation("net.dv8tion:JDA:4.4.0_352") { @@ -104,4 +106,7 @@ dependencies { implementation 'com.lunarclient:apollo-common:1.1.0' implementation 'org.reflections:reflections:0.10.2' + + compileOnly 'io.netty:netty-buffer:4.1.106.Final' + compileOnly 'io.netty:netty-transport:4.1.106.Final' } \ No newline at end of file diff --git a/src/de/steamwar/bungeecore/ServerStarter.java b/src/de/steamwar/bungeecore/ServerStarter.java index 10c1ebf..7b2fad7 100644 --- a/src/de/steamwar/bungeecore/ServerStarter.java +++ b/src/de/steamwar/bungeecore/ServerStarter.java @@ -68,7 +68,7 @@ public class ServerStarter { public ServerStarter event(EventFight eventFight) { arena(ArenaMode.getByInternal(eventFight.getSpielmodus()), eventFight.getMap()); - node = VelocityCore.local; + node = Node.LocalNode.getNode(); worldDir = EVENT_PATH; worldCleanup = () -> {}; arguments.put("fightID", String.valueOf(eventFight.getFightID())); diff --git a/src/de/steamwar/bungeecore/SubserverSystem.java b/src/de/steamwar/bungeecore/SubserverSystem.java index bea874e..1e3d5a5 100644 --- a/src/de/steamwar/bungeecore/SubserverSystem.java +++ b/src/de/steamwar/bungeecore/SubserverSystem.java @@ -25,9 +25,6 @@ import de.steamwar.bungeecore.network.handlers.FightInfoHandler; import de.steamwar.sql.IgnoreSystem; import de.steamwar.sql.SteamwarUser; import de.steamwar.network.packets.server.StartingServerPacket; -import net.md_5.bungee.api.ProxyServer; -import net.md_5.bungee.api.chat.ClickEvent; -import net.md_5.bungee.api.connection.ProxiedPlayer; import java.util.UUID; @@ -50,12 +47,12 @@ public class SubserverSystem { return; } - Message.send("SERVER_ADD_MEMBER", o, p.getName()); + Message.send("SERVER_ADD_MEMBER", o, p.getUsername()); Message.sendPrefixless("SERVER_ADD_MESSAGE", o, Message.parse("SERVER_ADD_MESSAGE_HOVER", o, p.getName()), new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/bau addmember " + p.getName())); } - public static void sendPlayer(Subserver subserver, ProxiedPlayer player) { + public static void sendPlayer(Subserver subserver, Player player) { subserver.sendPlayer(player); if(!subserver.hasStarted() && FightInfoHandler.onLobby(player)) NetworkSender.send(player, new StartingServerPacket(SteamwarUser.get(player.getUniqueId()).getId())); diff --git a/src/de/steamwar/bungeecore/VelocityCore.java b/src/de/steamwar/bungeecore/VelocityCore.java index 86db31a..3637240 100644 --- a/src/de/steamwar/bungeecore/VelocityCore.java +++ b/src/de/steamwar/bungeecore/VelocityCore.java @@ -131,13 +131,6 @@ public class VelocityCore { } }); - new PluginMessage(); - new Schematica(); - new Badlion(); - new FabricModSender(); - new ReplayMod(); - new FML2(); - new ConnectionListener(); new ChatListener(); new BanListener(); diff --git a/src/de/steamwar/bungeecore/listeners/IPSanitizer.java b/src/de/steamwar/bungeecore/listeners/IPSanitizer.java index 4cf33fb..fad4489 100644 --- a/src/de/steamwar/bungeecore/listeners/IPSanitizer.java +++ b/src/de/steamwar/bungeecore/listeners/IPSanitizer.java @@ -19,48 +19,56 @@ package de.steamwar.bungeecore.listeners; +import com.velocitypowered.api.event.Subscribe; +import com.velocitypowered.api.event.connection.PreLoginEvent; +import com.velocitypowered.api.proxy.InboundConnection; +import com.velocitypowered.proxy.connection.MinecraftConnection; +import com.velocitypowered.proxy.connection.client.InitialInboundConnection; +import com.velocitypowered.proxy.connection.client.LoginInboundConnection; import de.steamwar.bungeecore.VelocityCore; -import net.md_5.bungee.api.connection.PendingConnection; -import net.md_5.bungee.api.event.LoginEvent; -import net.md_5.bungee.connection.InitialHandler; -import net.md_5.bungee.event.EventHandler; -import net.md_5.bungee.netty.ChannelWrapper; import java.lang.reflect.Field; import java.net.InetAddress; import java.net.InetSocketAddress; import java.util.logging.Level; -public class IPSanitizer extends BasicListener { +public class IPSanitizer { - private static final Field initialHandlerCh; + private static final Field delegateField; + private static final Field remoteAddressField; static { try { - initialHandlerCh = InitialHandler.class.getDeclaredField("ch"); + delegateField = LoginInboundConnection.class.getDeclaredField("delegate"); + remoteAddressField = MinecraftConnection.class.getDeclaredField("remoteAddress"); } catch (NoSuchFieldException e) { throw new SecurityException("Could not initialize Reflection", e); } - initialHandlerCh.setAccessible(true); + delegateField.setAccessible(true); + remoteAddressField.setAccessible(true); } - public static ChannelWrapper getChannelWrapper(PendingConnection connection) { + public static MinecraftConnection getChannelWrapper(InboundConnection connection) { try { - return (ChannelWrapper) initialHandlerCh.get(connection); + return ((InitialInboundConnection) delegateField.get(connection)).getConnection(); } catch (IllegalAccessException e) { throw new SecurityException("Could not get channel wrapper", e); } } - public static InetAddress getTrueAddress(PendingConnection connection) { - return ((InetSocketAddress) getChannelWrapper(connection).getHandle().remoteAddress()).getAddress(); + public static InetAddress getTrueAddress(InboundConnection connection) { + return ((InetSocketAddress) getChannelWrapper(connection).getRemoteAddress()).getAddress(); } private final InetSocketAddress sanitized = new InetSocketAddress("127.127.127.127", 25565); - @EventHandler - public void loginEvent(LoginEvent e) { - VelocityCore.get().getLogger().log(Level.INFO, e.getConnection().getSocketAddress() + " has logged in with user name " + e.getConnection().getName()); - getChannelWrapper(e.getConnection()).setRemoteAddress(sanitized); + @Subscribe + public void loginEvent(PreLoginEvent e) { + VelocityCore.get().getLogger().log(Level.INFO, e.getConnection().getRemoteAddress().getAddress().toString() + " has logged in with user name " + e.getUsername()); + try { + remoteAddressField.set(getChannelWrapper(e.getConnection()), sanitized); + } catch (IllegalAccessException ex) { + throw new SecurityException("Could not set remote address", ex); + } } } diff --git a/src/de/steamwar/bungeecore/listeners/PluginMessage.java b/src/de/steamwar/bungeecore/listeners/PluginMessage.java index 89ee68f..ae3da20 100644 --- a/src/de/steamwar/bungeecore/listeners/PluginMessage.java +++ b/src/de/steamwar/bungeecore/listeners/PluginMessage.java @@ -19,9 +19,11 @@ package de.steamwar.bungeecore.listeners; +import com.google.inject.Inject; import com.lunarclient.apollo.ApolloManager; import com.velocitypowered.api.event.connection.PluginMessageEvent; import com.velocitypowered.api.proxy.Player; +import com.velocitypowered.api.proxy.ServerConnection; import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier; import de.steamwar.bungeecore.VelocityCore; import de.steamwar.bungeecore.Message; @@ -31,10 +33,14 @@ import de.steamwar.bungeecore.network.ServerMetaInfo; import de.steamwar.bungeecore.util.annotations.Create; import de.steamwar.messages.ChatSender; import de.steamwar.network.packets.NetworkPacket; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import net.kyori.adventure.text.Component; import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.util.*; import java.util.function.Consumer; import java.util.logging.Level; @@ -42,6 +48,12 @@ import java.util.logging.Level; @Create public class PluginMessage { + private final Lunar lunar; + private final LabyMod labyMod; + private final WorldDownloader wdl; + private final FabricModSender fms; + private final FML flm; + public static void send(Player player, String legacyChannel, String channel, byte[] data) { // 1.12 format change send(player, player.getProtocolVersion().getProtocol() > 340 ? channel : legacyChannel, data); @@ -51,6 +63,15 @@ public class PluginMessage { player.sendPluginMessage(MinecraftChannelIdentifier.from(channel), data); } + public static byte[] genBufPacket(Consumer generator) { + ByteBuf buf = Unpooled.buffer(); + generator.accept(buf); + + byte[] packet = new byte[buf.readableBytes()]; + buf.readBytes(packet); + return packet; + } + public static byte[] genStreamPacket(StreamConsumer generator) { ByteArrayOutputStream stream = new ByteArrayOutputStream(); DataOutputStream out = new DataOutputStream(stream); @@ -75,16 +96,17 @@ public class PluginMessage { private static final Parser PASS_THROUGH = event -> event.setResult(PluginMessageEvent.ForwardResult.forward()); private static final Parser DROP = event -> event.setResult(PluginMessageEvent.ForwardResult.handled()); - private final Lunar lunar = new Lunar(); - private final Set knownBrands = new HashSet<>(); private final Map> channelRegisterHandlers = new HashMap<>(); private final Map handlers = new HashMap<>(); - public PluginMessage() { - //TODO interface generalisation - LabyMod labyMod = new LabyMod(); - WorldDownloader wdl = new WorldDownloader(); + @Inject + public PluginMessage(Lunar lunar, LabyMod labyMod, WorldDownloader wdl, FabricModSender fms, FML flm) { + this.lunar = lunar; + this.labyMod = labyMod; + this.wdl = wdl; + this.fms = fms; + this.flm = flm; knownBrands.addAll(Arrays.asList("vanilla", "fabric", "quilt", "forge", "optifine", "Geyser", "labymod", "Feather Fabric")); @@ -136,12 +158,12 @@ public class PluginMessage { } channelRegisterHandlers.put(ApolloManager.PLUGIN_MESSAGE_CHANNEL, lunar::sendRestrictions); - channelRegisterHandlers.put(Feather.CHANNEL, new Feather()::sendRestrictions); - channelRegisterHandlers.put("xaerominimap:main", player -> player.sendMessage(ChatMessageType.SYSTEM, new TextComponent("§n§o§m§i§n§i§m§a§p"))); //https://www.curseforge.com/minecraft/mc-mods/xaeros-minimap + channelRegisterHandlers.put(Feather.CHANNEL.getId(), new Feather()::sendRestrictions); + channelRegisterHandlers.put("xaerominimap:main", player -> player.sendMessage(Component.text("§n§o§m§i§n§i§m§a§p"))); //https://www.curseforge.com/minecraft/mc-mods/xaeros-minimap channelRegisterHandlers.put("litemoretica:init_easy_place", player -> player.disconnect(ChatSender.of(player).parseToComponent(false, new Message("MOD_YELLOW_SING", "litematica")))); //https://github.com/Earthcomputer/litemoretica/tree/master channelRegisterHandlers.put("voxelmap:settings", player -> player.disconnect(ChatSender.of(player).parseToComponent(false, new Message("MOD_YELLOW_SING", "voxelmap")))); //https://modrinth.com/mod/voxelmap-updated undocumented channelRegisterHandlers.put("worldinfo:world_id", player -> player.disconnect(ChatSender.of(player).parseToComponent(false, new Message("MOD_YELLOW_SING", "minimap")))); // JourneyMap and VoxelMap - channelRegisterHandlers.put(Controlify.CHANNEL, new Controlify()::onRegister); + channelRegisterHandlers.put(Controlify.CHANNEL.getId(), new Controlify()::onRegister); registerBiDirPassthrough("worldedit:cui"); @@ -181,9 +203,9 @@ public class PluginMessage { register("minecraft:brand", false, directional(this::steamWarBrand, this::userBrand)); //Needs to be registered cause paper refuses to send PluginMessages on unregistered channels... - register("sw:bridge", true, directional(onlySWSource(async(event -> NetworkPacket.handle(new ServerMetaInfo(((Server) event.getSender()).getInfo()), event.getData()))), UNKNOWN)); + register("sw:bridge", true, directional(onlySWSource(async(event -> NetworkPacket.handle(new ServerMetaInfo(((ServerConnection) event.getSource()).getServerInfo()), event.getData()))), UNKNOWN)); register("sw:hotkeys", false, directional(UNKNOWN, PASS_THROUGH)); - register("fabricmodsender:mods", true, directional(UNKNOWN, async(new FabricModSender()::handlePluginMessage))); + register("fabricmodsender:mods", true, directional(UNKNOWN, async(fms::handlePluginMessage))); register("WDL|INIT", true, directional(UNKNOWN, wdl::handlePluginMessage)); register("wdl:init", true, directional(UNKNOWN, wdl::handlePluginMessage)); @@ -192,7 +214,7 @@ public class PluginMessage { register("LMC", true, directional(UNKNOWN, async(labyMod::handlePluginMessage))); register("labymod3:main", true, directional(UNKNOWN, async(labyMod::handlePluginMessage))); register("labymod:neo", false, directional(UNKNOWN, DROP)); //undocumented, JSON format "0" byte, packetlängen byte, {"version":"4.1.25"} - register(FML.CHANNEL, true, directional(UNKNOWN, async(new FML()::handlePluginMessage))); + register(FML.CHANNEL, true, directional(UNKNOWN, async(flm::handlePluginMessage))); //vanilla does not register any channels (sends only one minecraft:brand vanilla, nothing else (potential spoofed client detection)) //Forge interestingly registers all channels the server registers diff --git a/src/de/steamwar/bungeecore/mods/Badlion.java b/src/de/steamwar/bungeecore/mods/Badlion.java index 4a58f0f..7c6de73 100644 --- a/src/de/steamwar/bungeecore/mods/Badlion.java +++ b/src/de/steamwar/bungeecore/mods/Badlion.java @@ -20,11 +20,13 @@ package de.steamwar.bungeecore.mods; import com.google.gson.JsonObject; -import de.steamwar.bungeecore.listeners.BasicListener; -import net.md_5.bungee.api.event.PostLoginEvent; -import net.md_5.bungee.event.EventHandler; +import com.velocitypowered.api.event.Subscribe; +import com.velocitypowered.api.event.connection.PostLoginEvent; +import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier; +import de.steamwar.bungeecore.util.annotations.Create; -public class Badlion extends BasicListener { +@Create +public class Badlion { // https://github.com/BadlionClient/BadlionClientModAPI private final byte[] packet; @@ -50,8 +52,8 @@ public class Badlion extends BasicListener { packet = json.toString().getBytes(); } - @EventHandler + @Subscribe public void onPostLogin(PostLoginEvent event) { - event.getPlayer().sendData("badlion:mods", packet); + event.getPlayer().sendPluginMessage(MinecraftChannelIdentifier.from("badlion:mods"), packet); } } diff --git a/src/de/steamwar/bungeecore/mods/Controlify.java b/src/de/steamwar/bungeecore/mods/Controlify.java index 2c24017..6dfded4 100644 --- a/src/de/steamwar/bungeecore/mods/Controlify.java +++ b/src/de/steamwar/bungeecore/mods/Controlify.java @@ -19,16 +19,18 @@ package de.steamwar.bungeecore.mods; +import com.velocitypowered.api.proxy.Player; +import com.velocitypowered.api.proxy.messages.ChannelIdentifier; +import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier; +import com.velocitypowered.proxy.protocol.ProtocolUtils; import de.steamwar.bungeecore.listeners.PluginMessage; -import net.md_5.bungee.api.connection.ProxiedPlayer; -import net.md_5.bungee.protocol.DefinedPacket; public class Controlify { //https://modrinth.com/mod/controlify //https://github.com/isXander/Controlify/blob/1.20.x/dev/src/main/java/dev/isxander/controlify/server/ServerPolicyPacket.java //https://github.com/isXander/Controlify/blob/1.20.x/dev/src/main/java/dev/isxander/controlify/server/ServerPolicies.java - public static final String CHANNEL = "controlify:server_policy"; + public static final ChannelIdentifier CHANNEL = MinecraftChannelIdentifier.from("controlify:server_policy"); private final byte[][] packets; public Controlify() { @@ -40,13 +42,13 @@ public class Controlify { private byte[] restrict(String name) { return PluginMessage.genBufPacket(buf -> { - DefinedPacket.writeString(name, buf); + ProtocolUtils.writeString(buf, name); buf.writeBoolean(false); }); } - public void onRegister(ProxiedPlayer player) { + public void onRegister(Player player) { for(byte[] packet : packets) - player.sendData(CHANNEL, packet); + player.sendPluginMessage(CHANNEL, packet); } } diff --git a/src/de/steamwar/bungeecore/mods/FML.java b/src/de/steamwar/bungeecore/mods/FML.java index c4df2d7..fe38d83 100644 --- a/src/de/steamwar/bungeecore/mods/FML.java +++ b/src/de/steamwar/bungeecore/mods/FML.java @@ -19,31 +19,68 @@ package de.steamwar.bungeecore.mods; +import com.google.inject.Inject; +import com.velocitypowered.api.event.Subscribe; +import com.velocitypowered.api.event.connection.ConnectionHandshakeEvent; +import com.velocitypowered.api.event.connection.PluginMessageEvent; +import com.velocitypowered.api.event.connection.PostLoginEvent; +import com.velocitypowered.api.proxy.LoginPhaseConnection; +import com.velocitypowered.api.proxy.Player; +import com.velocitypowered.api.proxy.ProxyServer; +import com.velocitypowered.api.proxy.messages.ChannelIdentifier; +import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier; +import com.velocitypowered.proxy.connection.ConnectionType; +import com.velocitypowered.proxy.connection.ConnectionTypes; +import com.velocitypowered.proxy.connection.client.ConnectedPlayer; +import com.velocitypowered.proxy.connection.client.InitialInboundConnection; +import com.velocitypowered.proxy.connection.client.LoginInboundConnection; +import com.velocitypowered.proxy.protocol.ProtocolUtils; +import com.velocitypowered.proxy.protocol.packet.HandshakePacket; import de.steamwar.bungeecore.VelocityCore; -import de.steamwar.bungeecore.listeners.BasicListener; +import de.steamwar.bungeecore.util.annotations.Create; import de.steamwar.sql.Mod; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; -import net.md_5.bungee.api.ProxyServer; -import net.md_5.bungee.api.connection.PendingConnection; -import net.md_5.bungee.api.connection.ProxiedPlayer; -import net.md_5.bungee.api.event.PluginMessageEvent; -import net.md_5.bungee.api.event.PostLoginEvent; -import net.md_5.bungee.connection.InitialHandler; -import net.md_5.bungee.event.EventHandler; -import net.md_5.bungee.protocol.DefinedPacket; +import lombok.SneakyThrows; +import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; +import java.lang.reflect.Field; import java.util.*; import java.util.concurrent.TimeUnit; -public class FML extends BasicListener { +@Create +public class FML { // https://wiki.vg/Minecraft_Forge_Handshake#FML_protocol_.281.7_-_1.12.29 - public static boolean isFML(PendingConnection connection, String type) { - return ((InitialHandler)connection).getExtraDataInHandshake().equals("\0" + type); + private static final Field delegateField; + private static final Field handshakeField; + + static { + try { + delegateField = LoginInboundConnection.class.getDeclaredField("delegate"); + handshakeField = InitialInboundConnection.class.getDeclaredField("handshake"); + } catch (NoSuchFieldException e) { + throw new RuntimeException(e); + } } - public static final String CHANNEL = "FML|HS"; + private final ModUtils utils; + private final ProxyServer proxyServer; + private final VelocityCore core; + + @Inject + public FML(ModUtils utils, ProxyServer proxyServer, VelocityCore core) { + this.utils = utils; + this.proxyServer = proxyServer; + this.core = core; + } + + @SneakyThrows + public static boolean isFML(LoginPhaseConnection connection, String type) { + return handshakeField.get(delegateField.get(connection)) instanceof HandshakePacket packet && packet.getServerAddress().endsWith("\0" + type); + } + + public static final ChannelIdentifier CHANNEL = MinecraftChannelIdentifier.from("FML|HS"); private final byte[] helloPacket = new byte[]{ /* Packet type: ServerHello */ 0, /* FML protocol version */ 2, @@ -52,9 +89,9 @@ public class FML extends BasicListener { private static final Set unlocked = new HashSet<>(); - @EventHandler + @Subscribe public void onPostLogin(PostLoginEvent event) { - ProxiedPlayer player = event.getPlayer(); + Player player = event.getPlayer(); synchronized (unlocked) { if(unlocked.contains(player.getUniqueId())){ @@ -63,35 +100,36 @@ public class FML extends BasicListener { } } - if(isFML(player.getPendingConnection(), "FML\0")) - player.sendData(CHANNEL, helloPacket); + if(((ConnectedPlayer) event.getPlayer()).getConnection().getType() == ConnectionTypes.LEGACY_FORGE) { + player.sendPluginMessage(CHANNEL, helloPacket); + } } public void handlePluginMessage(PluginMessageEvent event) { - ProxiedPlayer p = (ProxiedPlayer) event.getSender(); + Player p = (Player) event.getSource(); ByteBuf buf = Unpooled.wrappedBuffer(event.getData()); if (buf.readByte() == /* ModList */ 2) { - int numMods = DefinedPacket.readVarInt(buf); + int numMods = ProtocolUtils.readVarInt(buf); List mods = new ArrayList<>(); for(int i = 0; i < numMods; i++) { - String name = DefinedPacket.readString(buf); - DefinedPacket.readString(buf); // version + String name = ProtocolUtils.readString(buf); + ProtocolUtils.readString(buf); // version mods.add(Mod.getOrCreate(name, Mod.Platform.FORGE)); } - if (ModUtils.handleMods(p, mods)) { + if (utils.handleMods(p, mods)) { synchronized (unlocked) { unlocked.add(p.getUniqueId()); } - p.disconnect(VelocityCore.stringToText("§7Deine installierten Mods wurden überprüft\n§aDu kannst nun §eSteam§8War §abetreten")); - ProxyServer.getInstance().getScheduler().schedule(VelocityCore.get(), () -> { + p.disconnect(LegacyComponentSerializer.legacySection().deserialize("§7Deine installierten Mods wurden überprüft\n§aDu kannst nun §eSteam§8War §abetreten")); + proxyServer.getScheduler().buildTask(core, () -> { synchronized (unlocked) { unlocked.remove(p.getUniqueId()); } - }, 30, TimeUnit.SECONDS); + }).delay(30, TimeUnit.SECONDS); } } } diff --git a/src/de/steamwar/bungeecore/mods/FML2.java b/src/de/steamwar/bungeecore/mods/FML2.java index de899be..f3d6cec 100644 --- a/src/de/steamwar/bungeecore/mods/FML2.java +++ b/src/de/steamwar/bungeecore/mods/FML2.java @@ -19,29 +19,30 @@ package de.steamwar.bungeecore.mods; +import com.google.inject.Inject; +import com.velocitypowered.api.event.Subscribe; +import com.velocitypowered.api.event.connection.PreLoginEvent; +import com.velocitypowered.api.proxy.LoginPhaseConnection; +import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier; +import com.velocitypowered.proxy.connection.client.LoginInboundConnection; +import com.velocitypowered.proxy.protocol.ProtocolUtils; +import com.velocitypowered.proxy.protocol.StateRegistry; import de.steamwar.bungeecore.VelocityCore; -import de.steamwar.bungeecore.listeners.BasicListener; import de.steamwar.bungeecore.listeners.IPSanitizer; import de.steamwar.bungeecore.listeners.PluginMessage; +import de.steamwar.bungeecore.util.annotations.Create; import de.steamwar.sql.Mod; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; -import net.md_5.bungee.api.chat.TextComponent; -import net.md_5.bungee.api.connection.PendingConnection; -import net.md_5.bungee.api.event.LoginEvent; -import net.md_5.bungee.event.EventHandler; -import net.md_5.bungee.netty.HandlerBoss; -import net.md_5.bungee.netty.PacketHandler; -import net.md_5.bungee.protocol.DefinedPacket; -import net.md_5.bungee.protocol.packet.LoginPayloadRequest; -import net.md_5.bungee.protocol.packet.LoginPayloadResponse; +import org.checkerframework.checker.nullness.qual.Nullable; -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; +import java.util.*; import java.util.logging.Level; -public class FML2 extends BasicListener { +@Create +public class FML2 { + + protected final ModUtils modUtils; // FML2: https://wiki.vg/Minecraft_Forge_Handshake#FML2_protocol_.281.13_-_Current.29 // FML3: https://github.com/adde0109/Ambassador/tree/non-api/src/main/java/org/adde0109/ambassador/forge @@ -53,25 +54,27 @@ public class FML2 extends BasicListener { private final byte[] fml3ModListPacket; private final byte[] forgeModListPacket; - public FML2() { + @Inject + public FML2(ModUtils modUtils) { + this.modUtils = modUtils; fml2ModListPacket = generateModListPacket(false); fml3ModListPacket = generateModListPacket(true); forgeModListPacket = PluginMessage.genBufPacket(buf -> { buf.writeByte(0); // Login wrapper packet - DefinedPacket.writeString("forge:handshake", buf); + ProtocolUtils.writeString(buf, "forge:handshake"); ByteBuf packet = Unpooled.buffer(); packet.writeByte(1); // Mod list packet - DefinedPacket.writeVarInt(0, packet); // Mod amount + ProtocolUtils.writeVarInt(packet, 0); // Mod amount - DefinedPacket.writeVarInt(packet.readableBytes(), buf); + ProtocolUtils.writeVarInt(buf, packet.readableBytes()); buf.writeBytes(packet); }); } - @EventHandler - public void onLogin(LoginEvent event) { - PendingConnection connection = event.getConnection(); + @Subscribe + public void onLogin(PreLoginEvent event) { + LoginInboundConnection connection = (LoginInboundConnection) event.getConnection(); boolean fml2 = FML.isFML(connection, "FML2\0"); boolean fml3 = FML.isFML(connection, "FML3\0"); @@ -79,45 +82,49 @@ public class FML2 extends BasicListener { if(!fml2 && !fml3 && !forge) return; - IPSanitizer.getChannelWrapper(connection).getHandle().pipeline().get(HandlerBoss.class).setHandler(new FML2LoginHandler(event)); + FML2LoginHandler handler = new FML2LoginHandler(connection, event.getUniqueId(), forge); - event.registerIntent(VelocityCore.get()); - if(forge) - connection.unsafe().sendPacket(new LoginPayloadRequest(1, "forge:login", forgeModListPacket)); - else - connection.unsafe().sendPacket(new LoginPayloadRequest(1, "fml:loginwrapper", fml3 ? fml3ModListPacket : fml2ModListPacket)); + if(forge) { + ((LoginInboundConnection) event.getConnection()).sendLoginPluginMessage(MinecraftChannelIdentifier.from("forge:login"), forgeModListPacket, handler); + } else { + ((LoginInboundConnection) event.getConnection()).sendLoginPluginMessage(MinecraftChannelIdentifier.from("fml:loginwrapper"), fml3 ? fml3ModListPacket : fml2ModListPacket, handler); + } } private byte[] generateModListPacket(boolean fml3) { return PluginMessage.genBufPacket(buf -> { - DefinedPacket.writeString("fml:handshake", buf); + ProtocolUtils.writeString(buf, "fml:handshake"); ByteBuf packet = Unpooled.buffer(); packet.writeByte(1); // Mod list packet - DefinedPacket.writeVarInt(0, packet); // Mod amount + ProtocolUtils.writeVarInt(packet, 0); // Mod amount if(fml3) { - DefinedPacket.writeVarInt(1, packet); // Channel amount - DefinedPacket.writeString("forge:tier_sorting", packet); - DefinedPacket.writeString("1.0", packet); + ProtocolUtils.writeVarInt(packet,1); // Channel amount + ProtocolUtils.writeString(packet, "forge:tier_sorting"); + ProtocolUtils.writeString(packet, "1.0"); } else { - DefinedPacket.writeVarInt(0, packet); // Channel amount + ProtocolUtils.writeVarInt(packet, 0); // Channel amount } - DefinedPacket.writeVarInt(0, packet); // Registries amount + ProtocolUtils.writeVarInt(packet, 0); // Registries amount if(fml3) - DefinedPacket.writeVarInt(0, packet); // DataPacks amount + ProtocolUtils.writeVarInt(packet, 0); // DataPacks amount - DefinedPacket.writeVarInt(packet.readableBytes(), buf); + ProtocolUtils.writeVarInt(buf, packet.readableBytes()); buf.writeBytes(packet); }); } - private static class FML2LoginHandler extends PacketHandler { - private final LoginEvent event; + private class FML2LoginHandler implements LoginPhaseConnection.MessageConsumer { + private final LoginInboundConnection connection; + private final UUID uuid; + private final boolean forge; - public FML2LoginHandler(LoginEvent event) { - this.event = event; + private FML2LoginHandler(LoginInboundConnection connection, UUID uuid, boolean forge) { + this.connection = connection; + this.uuid = uuid; + this.forge = forge; } @Override @@ -125,59 +132,52 @@ public class FML2 extends BasicListener { return "SteamWar Forge Handler"; } + private void abort(byte[] response, String error) { + + VelocityCore.get().getLogger().log(Level.SEVERE, () -> error + "\n" + Base64.getEncoder().encodeToString(response)); + } + @Override - public void handle(LoginPayloadResponse response) { - boolean forge = FML.isFML(event.getConnection(), "FORGE"); - byte[] data = response.getData(); + public void onMessageResponse(byte @Nullable [] data) { if(data == null) { - abort(response, "Not FML2/3 client"); + abort(null, "Not FML2/3 client"); return; } ByteBuf buf = Unpooled.wrappedBuffer(data); if(forge && buf.readByte() != 0) { - abort(response, "Not FORGE login wrapper"); + abort(data, "Not FORGE login wrapper"); return; } - if(!DefinedPacket.readString(buf).equals(forge ? "forge:handshake" : "fml:handshake")) { - abort(response, "Not FML2/3/FORGE handshake response"); + if(!ProtocolUtils.readString(buf).equals(forge ? "forge:handshake" : "fml:handshake")) { + abort(data, "Not FML2/3/FORGE handshake response"); return; } - if(DefinedPacket.readVarInt(buf) != buf.readableBytes()) { - abort(response, "FML2/3/FORGE packet size mismatch"); + if(ProtocolUtils.readVarInt(buf) != buf.readableBytes()) { + abort(data, "FML2/3/FORGE packet size mismatch"); return; } - if(DefinedPacket.readVarInt(buf) != (forge ? /* Mod Versions */ 1 : /* Mod List Reply */ 2)) { - abort(response, "Not FML2/3/FORGE mod list reply"); + if(ProtocolUtils.readVarInt(buf) != (forge ? /* Mod Versions */ 1 : /* Mod List Reply */ 2)) { + abort(data, "Not FML2/3/FORGE mod list reply"); return; } List mods = new ArrayList<>(); - int modCount = DefinedPacket.readVarInt(buf); + int modCount = ProtocolUtils.readVarInt(buf); for(int i = 0; i < modCount; i++) { - mods.add(Mod.getOrCreate(DefinedPacket.readString(buf), Mod.Platform.FORGE)); + mods.add(Mod.getOrCreate(ProtocolUtils.readString(buf), Mod.Platform.FORGE)); if(forge) { - DefinedPacket.readString(buf); // Human readable name - DefinedPacket.readString(buf); // Version + ProtocolUtils.readString(buf); // Human readable name + ProtocolUtils.readString(buf); // Version } } - if(!ModUtils.handleMods(event.getConnection().getUniqueId(), Locale.getDefault(), event::setReason, mods)) - event.setCancelled(true); - - event.completeIntent(VelocityCore.get()); - } - - private void abort(LoginPayloadResponse response, String error) { - event.setReason(TextComponent.fromLegacy(error)); - event.setCancelled(true); - event.completeIntent(VelocityCore.get()); - VelocityCore.get().getLogger().log(Level.SEVERE, () -> error + "\n" + response); + modUtils.handleMods(uuid, Locale.getDefault(), connection::disconnect, mods); } } } diff --git a/src/de/steamwar/bungeecore/mods/FabricModSender.java b/src/de/steamwar/bungeecore/mods/FabricModSender.java index 93f54fa..13ff553 100644 --- a/src/de/steamwar/bungeecore/mods/FabricModSender.java +++ b/src/de/steamwar/bungeecore/mods/FabricModSender.java @@ -22,31 +22,42 @@ package de.steamwar.bungeecore.mods; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonParser; +import com.google.inject.Inject; +import com.velocitypowered.api.event.Subscribe; +import com.velocitypowered.api.event.connection.DisconnectEvent; +import com.velocitypowered.api.event.connection.PluginMessageEvent; +import com.velocitypowered.api.event.player.ServerConnectedEvent; +import com.velocitypowered.api.event.player.ServerPostConnectEvent; +import com.velocitypowered.api.proxy.Player; +import com.velocitypowered.api.proxy.ProxyServer; +import com.velocitypowered.proxy.protocol.ProtocolUtils; import de.steamwar.bungeecore.VelocityCore; import de.steamwar.bungeecore.Storage; -import de.steamwar.bungeecore.listeners.BasicListener; +import de.steamwar.bungeecore.util.annotations.Create; import de.steamwar.sql.Mod; import de.steamwar.sql.SWException; import de.steamwar.sql.SteamwarUser; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; -import net.md_5.bungee.BungeeCord; -import net.md_5.bungee.api.connection.ProxiedPlayer; -import net.md_5.bungee.api.event.PlayerDisconnectEvent; -import net.md_5.bungee.api.event.PluginMessageEvent; -import net.md_5.bungee.api.event.ServerSwitchEvent; -import net.md_5.bungee.event.EventHandler; -import net.md_5.bungee.protocol.DefinedPacket; import java.util.*; import java.util.concurrent.TimeUnit; -public class FabricModSender extends BasicListener { +@Create +public class FabricModSender { + + private final ModUtils utils; + private final ProxyServer proxyServer; + private final VelocityCore core; private final Set neededFabricMods = new HashSet<>(); private final Set neededQuiltMods = new HashSet<>(); - public FabricModSender() { + @Inject + public FabricModSender(ModUtils utils, ProxyServer proxyServer, VelocityCore core) { + this.utils = utils; + this.proxyServer = proxyServer; + this.core = core; neededFabricMods.add("java"); neededFabricMods.add("minecraft"); neededFabricMods.add("steamwarmodsender"); @@ -55,9 +66,9 @@ public class FabricModSender extends BasicListener { neededFabricMods.add("fabricloader"); neededQuiltMods.add("quilt_loader"); - BungeeCord.getInstance().getScheduler().schedule(VelocityCore.get(), () -> { + proxyServer.getScheduler().buildTask(VelocityCore.get(), () -> { synchronized (Storage.fabricExpectPluginMessage) { - for (Map.Entry entry : Storage.fabricExpectPluginMessage.entrySet()) { + for (Map.Entry entry : Storage.fabricExpectPluginMessage.entrySet()) { if (!Storage.fabricCheckedPlayers.containsKey(entry.getKey())) { continue; } @@ -67,11 +78,11 @@ public class FabricModSender extends BasicListener { } } } - }, 0, 1, TimeUnit.SECONDS); + }).repeat(1, TimeUnit.SECONDS); } public void handlePluginMessage(PluginMessageEvent e){ - ProxiedPlayer player = (ProxiedPlayer) e.getSender(); + Player player = (Player) e.getSource(); SteamwarUser user = SteamwarUser.get(player.getUniqueId()); if (!Storage.fabricCheckedPlayers.containsKey(player)) { @@ -87,7 +98,7 @@ public class FabricModSender extends BasicListener { List mods = new ArrayList<>(); ByteBuf buf = Unpooled.wrappedBuffer(e.getData()); - String data = DefinedPacket.readString(buf, 1024*1024); + String data = ProtocolUtils.readString(buf, 1024*1024); if(buf.readableBytes() > 0) { logMessage(user, "Invalid message length", Arrays.toString(e.getData())); return; @@ -104,7 +115,7 @@ public class FabricModSender extends BasicListener { return; } - if(!ModUtils.handleMods(player,mods)) + if(!utils.handleMods(player,mods)) return; if (!Storage.fabricCheckedPlayers.containsKey(player)) { @@ -114,17 +125,17 @@ public class FabricModSender extends BasicListener { } } - @EventHandler - public void onServerSwitchEvent(ServerSwitchEvent e) { - if (e.getFrom() == null) return; + @Subscribe + public void onServerSwitchEvent(ServerConnectedEvent e) { + if (e.getPreviousServer().isEmpty()) return; synchronized (Storage.fabricExpectPluginMessage) { Storage.fabricExpectPluginMessage.put(e.getPlayer(), System.currentTimeMillis()); } } - @EventHandler - public void onDisconnect(PlayerDisconnectEvent e) { - ProxiedPlayer player = e.getPlayer(); + @Subscribe + public void onDisconnect(DisconnectEvent e) { + Player player = e.getPlayer(); Storage.fabricCheckedPlayers.remove(player); synchronized (Storage.fabricExpectPluginMessage) { diff --git a/src/de/steamwar/bungeecore/mods/Feather.java b/src/de/steamwar/bungeecore/mods/Feather.java index c7d2b65..1325ffb 100644 --- a/src/de/steamwar/bungeecore/mods/Feather.java +++ b/src/de/steamwar/bungeecore/mods/Feather.java @@ -21,12 +21,14 @@ package de.steamwar.bungeecore.mods; import com.google.gson.JsonArray; import com.google.gson.JsonObject; -import net.md_5.bungee.api.connection.ProxiedPlayer; +import com.velocitypowered.api.proxy.Player; +import com.velocitypowered.api.proxy.messages.ChannelIdentifier; +import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier; public class Feather { //https://github.com/Koupah/Feather-Client-API/blob/main/src/club/koupah/feather/packets/FeatherMod.java //https://archive.org/details/feather-server-api - public static final String CHANNEL = "feather:client"; + public static final ChannelIdentifier CHANNEL = MinecraftChannelIdentifier.from("feather:client"); private final byte[] packet; public Feather() { @@ -50,7 +52,7 @@ public class Feather { packet = obj.toString().getBytes(); } - public void sendRestrictions(ProxiedPlayer player) { - player.sendData(CHANNEL, packet); + public void sendRestrictions(Player player) { + player.sendPluginMessage(CHANNEL, packet); } } diff --git a/src/de/steamwar/bungeecore/mods/LabyMod.java b/src/de/steamwar/bungeecore/mods/LabyMod.java index 16f597a..8ac12ec 100644 --- a/src/de/steamwar/bungeecore/mods/LabyMod.java +++ b/src/de/steamwar/bungeecore/mods/LabyMod.java @@ -22,48 +22,53 @@ package de.steamwar.bungeecore.mods; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; +import com.velocitypowered.api.event.connection.PluginMessageEvent; +import com.velocitypowered.api.proxy.Player; +import com.velocitypowered.proxy.protocol.ProtocolUtils; import de.steamwar.bungeecore.VelocityCore; import de.steamwar.bungeecore.listeners.PluginMessage; +import de.steamwar.bungeecore.util.annotations.Create; import de.steamwar.sql.Mod; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; -import net.md_5.bungee.api.connection.ProxiedPlayer; -import net.md_5.bungee.api.event.PluginMessageEvent; -import net.md_5.bungee.protocol.DefinedPacket; import java.util.LinkedList; import java.util.List; import java.util.logging.Level; +@Create public class LabyMod { // https://docs.labymod.net/pages/server/introduction/ // https://github.com/LabyMod/labymod-server-api // https://dl.labymod.net/addons.json + private final ModUtils utils; + private final byte[] gameInfoPacket; - public LabyMod() { + public LabyMod(ModUtils utils) { + this.utils = utils; gameInfoPacket = PluginMessage.genBufPacket(buf -> { - DefinedPacket.writeString("discord_rpc", buf); + ProtocolUtils.writeString(buf, "discord_rpc"); JsonObject json = new JsonObject(); json.addProperty("hasGame", true); json.addProperty("game_mode", "steamwar.de"); json.addProperty("game_startTime", 0); json.addProperty("game_endTime", 0); - DefinedPacket.writeString(json.toString(), buf); + ProtocolUtils.writeString(buf, json.toString()); }); } public void handlePluginMessage(PluginMessageEvent event) { - ProxiedPlayer player = (ProxiedPlayer) event.getSender(); - player.sendData(event.getTag(), gameInfoPacket); + Player player = (Player) event.getSource(); + player.sendPluginMessage(event.getIdentifier(), gameInfoPacket); ByteBuf buf = Unpooled.wrappedBuffer(event.getData()); - String purpose = DefinedPacket.readString(buf); + String purpose = ProtocolUtils.readString(buf); if(!"INFO".equals(purpose)) return; - JsonObject message = JsonParser.parseString(DefinedPacket.readString(buf)).getAsJsonObject(); + JsonObject message = JsonParser.parseString(ProtocolUtils.readString(buf)).getAsJsonObject(); List mods = new LinkedList<>(); if(message.has("addons")) { @@ -82,6 +87,6 @@ public class LabyMod { } } - ModUtils.handleMods(player, mods); + utils.handleMods(player, mods); } } diff --git a/src/de/steamwar/bungeecore/mods/Lunar.java b/src/de/steamwar/bungeecore/mods/Lunar.java index 7eb0d29..9b8f147 100644 --- a/src/de/steamwar/bungeecore/mods/Lunar.java +++ b/src/de/steamwar/bungeecore/mods/Lunar.java @@ -32,11 +32,14 @@ import com.lunarclient.apollo.option.Options; import com.lunarclient.apollo.player.AbstractApolloPlayer; import com.lunarclient.apollo.player.v1.ModMessage; import com.lunarclient.apollo.player.v1.PlayerHandshakeMessage; +import com.velocitypowered.api.event.connection.PluginMessageEvent; +import com.velocitypowered.api.proxy.Player; +import com.velocitypowered.api.proxy.messages.ChannelIdentifier; +import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier; import de.steamwar.bungeecore.VelocityCore; +import de.steamwar.bungeecore.util.annotations.Create; import de.steamwar.sql.Mod; import lombok.AllArgsConstructor; -import net.md_5.bungee.api.connection.ProxiedPlayer; -import net.md_5.bungee.api.event.PluginMessageEvent; import java.util.ArrayList; import java.util.List; @@ -44,13 +47,16 @@ import java.util.UUID; import java.util.function.Consumer; import java.util.logging.Level; +@Create public class Lunar { // https://lunarclient.dev/apollo/introduction // https://github.com/LunarClient/Apollo private final ApolloModuleManager manager = new ApolloModuleManagerImpl().addModule(ModSettingModule.class); - public Lunar() { //TODO seems defunct + private final ModUtils utils; + + public Lunar(ModUtils utils) { //TODO seems defunct Options modSettings = manager.getModule(ModSettingModule.class).getOptions(); modSettings.set(ModReplaymod.ENABLED, false); // TODO check if restrictions working modSettings.set(ModFreelook.ENABLED, false); @@ -60,14 +66,16 @@ public class Lunar { modSettings.set(ModTeamView.ENABLED, false); modSettings.set(ModTntCountdown.ENABLED, false); modSettings.set(ModToggleSneak.TOGGLE_SNEAK_CONTAINER, false); + + this.utils = utils; } - public void sendRestrictions(ProxiedPlayer player) { + public void sendRestrictions(Player player) { NetworkOptions.sendOptions(manager.getModules(), true, new SWApolloPlayer(player)); } public void handlePluginMessage(PluginMessageEvent event) { - ProxiedPlayer player = (ProxiedPlayer) event.getSender(); + Player player = (Player) event.getSource(); Any packet; try { @@ -94,12 +102,12 @@ public class Lunar { case TYPE_UNSPECIFIED: case UNRECOGNIZED: default: - VelocityCore.get().getLogger().log(Level.INFO, () -> player.getName() + " uses Lunar mod with unknown type " + mod); + VelocityCore.get().getLogger().log(Level.INFO, () -> player.getUsername() + " uses Lunar mod with unknown type " + mod); break; } } - ModUtils.handleMods(player, mods); + utils.handleMods(player, mods); }); } @@ -112,7 +120,9 @@ public class Lunar { @AllArgsConstructor private static class SWApolloPlayer extends AbstractApolloPlayer { - private final ProxiedPlayer player; + private static final ChannelIdentifier CHANNEL = MinecraftChannelIdentifier.from(ApolloManager.PLUGIN_MESSAGE_CHANNEL); + + private final Player player; @Override public void sendPacket(Message message) { @@ -121,11 +131,11 @@ public class Lunar { @Override public void sendPacket(byte[] bytes) { - player.sendData(ApolloManager.PLUGIN_MESSAGE_CHANNEL, bytes); + player.sendPluginMessage(CHANNEL, bytes); } @Override public UUID getUniqueId() { return player.getUniqueId(); } - @Override public String getName() { return player.getName(); } + @Override public String getName() { return player.getUsername(); } @Override public boolean hasPermission(String s) { return player.hasPermission(s); } @Override public Object getPlayer() { return player; } } diff --git a/src/de/steamwar/bungeecore/mods/ModUtils.java b/src/de/steamwar/bungeecore/mods/ModUtils.java index e4aad3b..2534605 100644 --- a/src/de/steamwar/bungeecore/mods/ModUtils.java +++ b/src/de/steamwar/bungeecore/mods/ModUtils.java @@ -19,19 +19,20 @@ package de.steamwar.bungeecore.mods; +import com.google.inject.Inject; +import com.velocitypowered.api.proxy.Player; import de.steamwar.bungeecore.VelocityCore; import de.steamwar.bungeecore.Message; import de.steamwar.bungeecore.commands.PunishmentCommand; +import de.steamwar.bungeecore.util.annotations.Create; import de.steamwar.sql.SteamwarUser; import de.steamwar.messages.ChatSender; import de.steamwar.sql.Mod; import de.steamwar.sql.Mod.ModType; import de.steamwar.sql.UserPerm; import lombok.Getter; -import lombok.experimental.UtilityClass; -import net.md_5.bungee.api.chat.BaseComponent; -import net.md_5.bungee.api.chat.TextComponent; -import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import java.sql.Timestamp; import java.time.Instant; @@ -39,19 +40,27 @@ import java.time.temporal.ChronoUnit; import java.util.*; import java.util.function.Consumer; import java.util.logging.Level; +import java.util.logging.Logger; import java.util.stream.Collectors; -@UtilityClass +@Create public class ModUtils { - @Getter - private static final Map> playerModMap = new HashMap<>(); + private final Logger logger; - public static boolean handleMods(ProxiedPlayer player, List mods) { + @Getter + private final Map> playerModMap = new HashMap<>(); + + @Inject + public ModUtils(Logger logger) { + this.logger = logger; + } + + public boolean handleMods(Player player, List mods) { return handleMods(player.getUniqueId(), ChatSender.of(player).getLocale(), player::disconnect, mods); } - public static boolean handleMods(UUID uuid, Locale locale, Consumer disconnect, List mods){ + public boolean handleMods(UUID uuid, Locale locale, Consumer disconnect, List mods){ SteamwarUser user = SteamwarUser.get(uuid); playerModMap.put(uuid,new ArrayList<>(mods)); VelocityCore.get().getLogger().log(Level.INFO, user.getUserName() + " declares mods: " + mods.stream().map(mod -> mod.getPlatform() + ":" + mod.getModName()).collect(Collectors.joining(" "))); @@ -83,10 +92,10 @@ public class ModUtils { if(max == ModType.RED) { PunishmentCommand.ban(user, Timestamp.from(Instant.now().plus(7, ChronoUnit.DAYS)), message, SteamwarUser.get(-1), false); - VelocityCore.log(Level.SEVERE, user.getUserName() + " " + user.getId() + " wurde automatisch wegen der Mods " + modList + " gebannt."); + logger.log(Level.SEVERE, user.getUserName() + " " + user.getId() + " wurde automatisch wegen der Mods " + modList + " gebannt."); } - disconnect.accept(TextComponent.fromLegacy(message)); + disconnect.accept(LegacyComponentSerializer.legacySection().deserialize(message)); return false; } } diff --git a/src/de/steamwar/bungeecore/mods/WorldDownloader.java b/src/de/steamwar/bungeecore/mods/WorldDownloader.java index d18be4c..45e2f04 100644 --- a/src/de/steamwar/bungeecore/mods/WorldDownloader.java +++ b/src/de/steamwar/bungeecore/mods/WorldDownloader.java @@ -19,9 +19,9 @@ package de.steamwar.bungeecore.mods; +import com.velocitypowered.api.event.connection.PluginMessageEvent; +import com.velocitypowered.api.proxy.Player; import de.steamwar.bungeecore.listeners.PluginMessage; -import net.md_5.bungee.api.connection.ProxiedPlayer; -import net.md_5.bungee.api.event.PluginMessageEvent; public class WorldDownloader { // https://wiki.vg/Plugin_channels/World_downloader @@ -43,6 +43,6 @@ public class WorldDownloader { } public void handlePluginMessage(PluginMessageEvent event) { - PluginMessage.send((ProxiedPlayer) event.getSender(), "WDL|CONTROL", "wdl:control", controlPacket); + PluginMessage.send((Player) event.getSource(), "WDL|CONTROL", "wdl:control", controlPacket); } } diff --git a/src/de/steamwar/bungeecore/network/ServerMetaInfo.java b/src/de/steamwar/bungeecore/network/ServerMetaInfo.java index 5f38da1..6f0e870 100644 --- a/src/de/steamwar/bungeecore/network/ServerMetaInfo.java +++ b/src/de/steamwar/bungeecore/network/ServerMetaInfo.java @@ -19,8 +19,8 @@ package de.steamwar.bungeecore.network; +import com.velocitypowered.api.proxy.server.ServerInfo; import de.steamwar.network.packets.MetaInfos; -import net.md_5.bungee.api.config.ServerInfo; public class ServerMetaInfo implements MetaInfos { diff --git a/src/de/steamwar/bungeecore/util/BauLock.java b/src/de/steamwar/bungeecore/util/BauLock.java index e47dabe..65c64ae 100644 --- a/src/de/steamwar/bungeecore/util/BauLock.java +++ b/src/de/steamwar/bungeecore/util/BauLock.java @@ -19,26 +19,35 @@ package de.steamwar.bungeecore.util; +import com.google.inject.Inject; +import com.velocitypowered.api.proxy.Player; +import com.velocitypowered.api.proxy.ProxyServer; import de.steamwar.bungeecore.Message; +import de.steamwar.bungeecore.util.annotations.Create; import de.steamwar.messages.ChatSender; import de.steamwar.sql.SteamwarUser; import de.steamwar.sql.UserConfig; import de.steamwar.sql.UserPerm; -import lombok.experimental.UtilityClass; -import net.md_5.bungee.api.ProxyServer; -import net.md_5.bungee.api.connection.ProxiedPlayer; -@UtilityClass +@Create public class BauLock { - private static final String BAU_LOCK_CONFIG_NAME = "baulockstate"; - public static void setLocked(ProxiedPlayer p, BauLockState state) { + private final ProxyServer proxy; + + private final String BAU_LOCK_CONFIG_NAME = "baulockstate"; + + @Inject + public BauLock(ProxyServer proxy) { + this.proxy = proxy; + } + + public void setLocked(Player p, BauLockState state) { SteamwarUser owner = SteamwarUser.get(p.getUniqueId()); UserConfig.updatePlayerConfig(owner.getId(), BAU_LOCK_CONFIG_NAME, state == BauLockState.OPEN ? null : state.name()); Message.send("BAU_LOCKED_" + state.name(), p); } - public static boolean checkNotifyLocked(SteamwarUser owner, ProxiedPlayer player) { + public boolean checkNotifyLocked(SteamwarUser owner, Player player) { ChatSender sender = ChatSender.of(player); SteamwarUser target = sender.user(); if (owner.getId() == target.getId()) @@ -70,9 +79,7 @@ public class BauLock { if(locked) { sender.system("BAU_LOCKED_NOALLOWED"); - ProxiedPlayer ownerPlayer = ProxyServer.getInstance().getPlayer(owner.getUUID()); - if(ownerPlayer != null) - ChatSender.of(ownerPlayer).system("BAU_LOCK_BLOCKED", player.getName()); + proxy.getPlayer(owner.getUUID()).ifPresent(ownerPlayer -> ChatSender.of(ownerPlayer).system("BAU_LOCK_BLOCKED", player.getUsername())); } return locked; diff --git a/src/de/steamwar/bungeecore/util/Chat19.java b/src/de/steamwar/bungeecore/util/Chat19.java index a543f74..ec75070 100644 --- a/src/de/steamwar/bungeecore/util/Chat19.java +++ b/src/de/steamwar/bungeecore/util/Chat19.java @@ -19,30 +19,19 @@ package de.steamwar.bungeecore.util; -import net.md_5.bungee.ServerConnection; -import net.md_5.bungee.api.connection.ProxiedPlayer; -import net.md_5.bungee.protocol.ChatChain; -import net.md_5.bungee.protocol.ProtocolConstants; -import net.md_5.bungee.protocol.SeenMessages; -import net.md_5.bungee.protocol.packet.ClientChat; -import net.md_5.bungee.protocol.packet.ClientCommand; +import com.velocitypowered.api.proxy.Player; +import com.velocitypowered.proxy.connection.client.ConnectedPlayer; -import java.util.BitSet; -import java.util.Collections; +import java.time.Instant; public class Chat19 { private Chat19(){} - public static void chat(ProxiedPlayer p, String message) { - int version = p.getPendingConnection().getVersion(); - if(version >= ProtocolConstants.MINECRAFT_1_19) { - if(message.startsWith("/")) { - ((ServerConnection) p.getServer()).getCh().write(new ClientCommand(message.substring(1), System.currentTimeMillis(), 0, Collections.emptyMap(), false, new ChatChain(Collections.emptyList(), null), new SeenMessages(0, new BitSet(0)))); - } else { - ((ServerConnection) p.getServer()).getCh().write(new ClientChat(message, System.currentTimeMillis(), 0, version < ProtocolConstants.MINECRAFT_1_19_3 ? new byte[0] : null, false, new ChatChain(Collections.emptyList(), null), new SeenMessages(0, new BitSet(0)))); - } - } else { - p.chat(message); - } + public static void chat(Player p, String message) { + ((ConnectedPlayer) p).getChatBuilderFactory().builder() + .setTimestamp(Instant.now()) + .asPlayer(p) + .message(message) + .toServer(); } } \ No newline at end of file diff --git a/src/de/steamwar/bungeecore/util/SteamWarModule.java b/src/de/steamwar/bungeecore/util/SteamWarModule.java index 8db72a7..a3950c5 100644 --- a/src/de/steamwar/bungeecore/util/SteamWarModule.java +++ b/src/de/steamwar/bungeecore/util/SteamWarModule.java @@ -21,10 +21,12 @@ package de.steamwar.bungeecore.util; import com.google.inject.AbstractModule; import com.google.inject.Provides; +import com.google.inject.Scopes; import com.google.inject.Singleton; import de.steamwar.bungeecore.Node; import de.steamwar.bungeecore.VelocityCore; import de.steamwar.bungeecore.commands.HelpCommand; +import de.steamwar.bungeecore.mods.*; import org.jetbrains.annotations.NotNull; public final class SteamWarModule extends AbstractModule { @@ -38,7 +40,13 @@ public final class SteamWarModule extends AbstractModule { @Override protected void configure() { bind(VelocityCore.class).toInstance(core); - bind(HelpCommand.class).in(Singleton.class); + bind(HelpCommand.class).in(Scopes.SINGLETON); + bind(ModUtils.class).in(Scopes.SINGLETON); + bind(LabyMod.class).in(Scopes.SINGLETON); + bind(WorldDownloader.class).in(Scopes.SINGLETON); + bind(FML.class).in(Scopes.SINGLETON); + bind(FML2.class).in(Scopes.SINGLETON); + bind(BauLock.class).in(Scopes.SINGLETON); } @Provides diff --git a/src/de/steamwar/command/CommandRegistering.java b/src/de/steamwar/command/CommandRegistering.java index 57a9694..135da53 100644 --- a/src/de/steamwar/command/CommandRegistering.java +++ b/src/de/steamwar/command/CommandRegistering.java @@ -19,18 +19,69 @@ package de.steamwar.command; +import com.mojang.brigadier.tree.CommandNode; import com.velocitypowered.api.command.Command; +import com.velocitypowered.api.command.CommandManager; +import com.velocitypowered.api.command.CommandMeta; +import com.velocitypowered.api.command.CommandSource; import de.steamwar.bungeecore.VelocityCore; +import lombok.EqualsAndHashCode; +import lombok.ToString; import lombok.experimental.UtilityClass; +import org.checkerframework.checker.nullness.qual.Nullable; + +import java.util.*; @UtilityClass class CommandRegistering { static void unregister(String name) { - VelocityCore.getProxy().getCommandManager().unregister(name); + VelocityCore.get().getProxyServer().getCommandManager().unregister(name); } static void register(Command command, String name, String... aliases) { - VelocityCore.getProxy().getCommandManager().register(name, command, aliases); + VelocityCore.get().getProxyServer().getCommandManager().register(new SWCommandMeta(name, aliases), command); + } + + private record SWCommandMeta(String name, String[] aliases) implements CommandMeta { + + @Override + public Collection getAliases() { + List list = new ArrayList<>(aliases.length + 1); + list.add(name); + list.addAll(Arrays.asList(aliases)); + return Collections.unmodifiableList(list); + } + + @Override + public Collection> getHints() { + return List.of(); + } + + @Override + public @Nullable Object getPlugin() { + return VelocityCore.get(); + } + + @Override + public String toString() { + return "SWCommandMeta{" + + "name='" + name + '\'' + + ", aliases=" + Arrays.toString(aliases) + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + SWCommandMeta that = (SWCommandMeta) o; + return Objects.equals(name, that.name) && Objects.deepEquals(aliases, that.aliases); + } + + @Override + public int hashCode() { + return Objects.hash(name, Arrays.hashCode(aliases)); + } } }