geforkt von SteamWar/BungeeCore
Porta Porting
Dieser Commit ist enthalten in:
Ursprung
c6ccaa6abb
Commit
153d354c60
@ -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'
|
||||
}
|
@ -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()));
|
||||
|
@ -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()));
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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<ByteBuf> 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<String> knownBrands = new HashSet<>();
|
||||
private final Map<String, Consumer<Player>> channelRegisterHandlers = new HashMap<>();
|
||||
private final Map<String, Parser> 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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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<UUID> 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<Mod> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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<Mod> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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<String> neededFabricMods = new HashSet<>();
|
||||
private final Set<String> 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<ProxiedPlayer, Long> entry : Storage.fabricExpectPluginMessage.entrySet()) {
|
||||
for (Map.Entry<Player, Long> 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<Mod> 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) {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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<Mod> mods = new LinkedList<>();
|
||||
|
||||
if(message.has("addons")) {
|
||||
@ -82,6 +87,6 @@ public class LabyMod {
|
||||
}
|
||||
}
|
||||
|
||||
ModUtils.handleMods(player, mods);
|
||||
utils.handleMods(player, mods);
|
||||
}
|
||||
}
|
||||
|
@ -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; }
|
||||
}
|
||||
|
@ -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<UUID,List<Mod>> playerModMap = new HashMap<>();
|
||||
private final Logger logger;
|
||||
|
||||
public static boolean handleMods(ProxiedPlayer player, List<Mod> mods) {
|
||||
@Getter
|
||||
private final Map<UUID,List<Mod>> playerModMap = new HashMap<>();
|
||||
|
||||
@Inject
|
||||
public ModUtils(Logger logger) {
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
public boolean handleMods(Player player, List<Mod> mods) {
|
||||
return handleMods(player.getUniqueId(), ChatSender.of(player).getLocale(), player::disconnect, mods);
|
||||
}
|
||||
|
||||
public static boolean handleMods(UUID uuid, Locale locale, Consumer<BaseComponent> disconnect, List<Mod> mods){
|
||||
public boolean handleMods(UUID uuid, Locale locale, Consumer<Component> disconnect, List<Mod> 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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
@ -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
|
||||
|
@ -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<String> getAliases() {
|
||||
List<String> list = new ArrayList<>(aliases.length + 1);
|
||||
list.add(name);
|
||||
list.addAll(Arrays.asList(aliases));
|
||||
return Collections.unmodifiableList(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<CommandNode<CommandSource>> 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
In neuem Issue referenzieren
Einen Benutzer sperren