geforkt von SteamWar/BungeeCore
Porta Porting
Dieser Commit ist enthalten in:
Ursprung
c6ccaa6abb
Commit
153d354c60
@ -73,6 +73,7 @@ repositories {
|
|||||||
includeGroup 'com.lunarclient'
|
includeGroup 'com.lunarclient'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
mavenLocal()
|
||||||
}
|
}
|
||||||
|
|
||||||
shadowJar {
|
shadowJar {
|
||||||
@ -92,6 +93,7 @@ dependencies {
|
|||||||
|
|
||||||
compileOnly 'com.velocitypowered:velocity-api:3.3.0-SNAPSHOT'
|
compileOnly 'com.velocitypowered:velocity-api:3.3.0-SNAPSHOT'
|
||||||
annotationProcessor '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'
|
compileOnly 'de.steamwar:persistentbungeecore:RELEASE'
|
||||||
implementation("net.dv8tion:JDA:4.4.0_352") {
|
implementation("net.dv8tion:JDA:4.4.0_352") {
|
||||||
@ -104,4 +106,7 @@ dependencies {
|
|||||||
implementation 'com.lunarclient:apollo-common:1.1.0'
|
implementation 'com.lunarclient:apollo-common:1.1.0'
|
||||||
|
|
||||||
implementation 'org.reflections:reflections:0.10.2'
|
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) {
|
public ServerStarter event(EventFight eventFight) {
|
||||||
arena(ArenaMode.getByInternal(eventFight.getSpielmodus()), eventFight.getMap());
|
arena(ArenaMode.getByInternal(eventFight.getSpielmodus()), eventFight.getMap());
|
||||||
node = VelocityCore.local;
|
node = Node.LocalNode.getNode();
|
||||||
worldDir = EVENT_PATH;
|
worldDir = EVENT_PATH;
|
||||||
worldCleanup = () -> {};
|
worldCleanup = () -> {};
|
||||||
arguments.put("fightID", String.valueOf(eventFight.getFightID()));
|
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.IgnoreSystem;
|
||||||
import de.steamwar.sql.SteamwarUser;
|
import de.steamwar.sql.SteamwarUser;
|
||||||
import de.steamwar.network.packets.server.StartingServerPacket;
|
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;
|
import java.util.UUID;
|
||||||
|
|
||||||
@ -50,12 +47,12 @@ public class SubserverSystem {
|
|||||||
return;
|
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()),
|
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()));
|
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);
|
subserver.sendPlayer(player);
|
||||||
if(!subserver.hasStarted() && FightInfoHandler.onLobby(player))
|
if(!subserver.hasStarted() && FightInfoHandler.onLobby(player))
|
||||||
NetworkSender.send(player, new StartingServerPacket(SteamwarUser.get(player.getUniqueId()).getId()));
|
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 ConnectionListener();
|
||||||
new ChatListener();
|
new ChatListener();
|
||||||
new BanListener();
|
new BanListener();
|
||||||
|
@ -19,48 +19,56 @@
|
|||||||
|
|
||||||
package de.steamwar.bungeecore.listeners;
|
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 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.lang.reflect.Field;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.util.logging.Level;
|
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 {
|
static {
|
||||||
try {
|
try {
|
||||||
initialHandlerCh = InitialHandler.class.getDeclaredField("ch");
|
delegateField = LoginInboundConnection.class.getDeclaredField("delegate");
|
||||||
|
remoteAddressField = MinecraftConnection.class.getDeclaredField("remoteAddress");
|
||||||
} catch (NoSuchFieldException e) {
|
} catch (NoSuchFieldException e) {
|
||||||
throw new SecurityException("Could not initialize Reflection", 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 {
|
try {
|
||||||
return (ChannelWrapper) initialHandlerCh.get(connection);
|
return ((InitialInboundConnection) delegateField.get(connection)).getConnection();
|
||||||
} catch (IllegalAccessException e) {
|
} catch (IllegalAccessException e) {
|
||||||
throw new SecurityException("Could not get channel wrapper", e);
|
throw new SecurityException("Could not get channel wrapper", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static InetAddress getTrueAddress(PendingConnection connection) {
|
public static InetAddress getTrueAddress(InboundConnection connection) {
|
||||||
return ((InetSocketAddress) getChannelWrapper(connection).getHandle().remoteAddress()).getAddress();
|
return ((InetSocketAddress) getChannelWrapper(connection).getRemoteAddress()).getAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private final InetSocketAddress sanitized = new InetSocketAddress("127.127.127.127", 25565);
|
private final InetSocketAddress sanitized = new InetSocketAddress("127.127.127.127", 25565);
|
||||||
|
|
||||||
@EventHandler
|
@Subscribe
|
||||||
public void loginEvent(LoginEvent e) {
|
public void loginEvent(PreLoginEvent e) {
|
||||||
VelocityCore.get().getLogger().log(Level.INFO, e.getConnection().getSocketAddress() + " has logged in with user name " + e.getConnection().getName());
|
VelocityCore.get().getLogger().log(Level.INFO, e.getConnection().getRemoteAddress().getAddress().toString() + " has logged in with user name " + e.getUsername());
|
||||||
getChannelWrapper(e.getConnection()).setRemoteAddress(sanitized);
|
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;
|
package de.steamwar.bungeecore.listeners;
|
||||||
|
|
||||||
|
import com.google.inject.Inject;
|
||||||
import com.lunarclient.apollo.ApolloManager;
|
import com.lunarclient.apollo.ApolloManager;
|
||||||
import com.velocitypowered.api.event.connection.PluginMessageEvent;
|
import com.velocitypowered.api.event.connection.PluginMessageEvent;
|
||||||
import com.velocitypowered.api.proxy.Player;
|
import com.velocitypowered.api.proxy.Player;
|
||||||
|
import com.velocitypowered.api.proxy.ServerConnection;
|
||||||
import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier;
|
import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier;
|
||||||
import de.steamwar.bungeecore.VelocityCore;
|
import de.steamwar.bungeecore.VelocityCore;
|
||||||
import de.steamwar.bungeecore.Message;
|
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.bungeecore.util.annotations.Create;
|
||||||
import de.steamwar.messages.ChatSender;
|
import de.steamwar.messages.ChatSender;
|
||||||
import de.steamwar.network.packets.NetworkPacket;
|
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.ByteArrayOutputStream;
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
@ -42,6 +48,12 @@ import java.util.logging.Level;
|
|||||||
@Create
|
@Create
|
||||||
public class PluginMessage {
|
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) {
|
public static void send(Player player, String legacyChannel, String channel, byte[] data) {
|
||||||
// 1.12 format change
|
// 1.12 format change
|
||||||
send(player, player.getProtocolVersion().getProtocol() > 340 ? channel : legacyChannel, data);
|
send(player, player.getProtocolVersion().getProtocol() > 340 ? channel : legacyChannel, data);
|
||||||
@ -51,6 +63,15 @@ public class PluginMessage {
|
|||||||
player.sendPluginMessage(MinecraftChannelIdentifier.from(channel), data);
|
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) {
|
public static byte[] genStreamPacket(StreamConsumer generator) {
|
||||||
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
||||||
DataOutputStream out = new DataOutputStream(stream);
|
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 PASS_THROUGH = event -> event.setResult(PluginMessageEvent.ForwardResult.forward());
|
||||||
private static final Parser DROP = event -> event.setResult(PluginMessageEvent.ForwardResult.handled());
|
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 Set<String> knownBrands = new HashSet<>();
|
||||||
private final Map<String, Consumer<Player>> channelRegisterHandlers = new HashMap<>();
|
private final Map<String, Consumer<Player>> channelRegisterHandlers = new HashMap<>();
|
||||||
private final Map<String, Parser> handlers = new HashMap<>();
|
private final Map<String, Parser> handlers = new HashMap<>();
|
||||||
|
|
||||||
public PluginMessage() {
|
@Inject
|
||||||
//TODO interface generalisation
|
public PluginMessage(Lunar lunar, LabyMod labyMod, WorldDownloader wdl, FabricModSender fms, FML flm) {
|
||||||
LabyMod labyMod = new LabyMod();
|
this.lunar = lunar;
|
||||||
WorldDownloader wdl = new WorldDownloader();
|
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"));
|
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(ApolloManager.PLUGIN_MESSAGE_CHANNEL, lunar::sendRestrictions);
|
||||||
channelRegisterHandlers.put(Feather.CHANNEL, new Feather()::sendRestrictions);
|
channelRegisterHandlers.put(Feather.CHANNEL.getId(), 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("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("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("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("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");
|
registerBiDirPassthrough("worldedit:cui");
|
||||||
|
|
||||||
@ -181,9 +203,9 @@ public class PluginMessage {
|
|||||||
register("minecraft:brand", false, directional(this::steamWarBrand, this::userBrand));
|
register("minecraft:brand", false, directional(this::steamWarBrand, this::userBrand));
|
||||||
|
|
||||||
//Needs to be registered cause paper refuses to send PluginMessages on unregistered channels...
|
//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("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));
|
||||||
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("LMC", true, directional(UNKNOWN, async(labyMod::handlePluginMessage)));
|
||||||
register("labymod3:main", 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("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))
|
//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
|
//Forge interestingly registers all channels the server registers
|
||||||
|
@ -20,11 +20,13 @@
|
|||||||
package de.steamwar.bungeecore.mods;
|
package de.steamwar.bungeecore.mods;
|
||||||
|
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import de.steamwar.bungeecore.listeners.BasicListener;
|
import com.velocitypowered.api.event.Subscribe;
|
||||||
import net.md_5.bungee.api.event.PostLoginEvent;
|
import com.velocitypowered.api.event.connection.PostLoginEvent;
|
||||||
import net.md_5.bungee.event.EventHandler;
|
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
|
// https://github.com/BadlionClient/BadlionClientModAPI
|
||||||
|
|
||||||
private final byte[] packet;
|
private final byte[] packet;
|
||||||
@ -50,8 +52,8 @@ public class Badlion extends BasicListener {
|
|||||||
packet = json.toString().getBytes();
|
packet = json.toString().getBytes();
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@Subscribe
|
||||||
public void onPostLogin(PostLoginEvent event) {
|
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;
|
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 de.steamwar.bungeecore.listeners.PluginMessage;
|
||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
|
||||||
import net.md_5.bungee.protocol.DefinedPacket;
|
|
||||||
|
|
||||||
public class Controlify {
|
public class Controlify {
|
||||||
//https://modrinth.com/mod/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/ServerPolicyPacket.java
|
||||||
//https://github.com/isXander/Controlify/blob/1.20.x/dev/src/main/java/dev/isxander/controlify/server/ServerPolicies.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;
|
private final byte[][] packets;
|
||||||
public Controlify() {
|
public Controlify() {
|
||||||
@ -40,13 +42,13 @@ public class Controlify {
|
|||||||
|
|
||||||
private byte[] restrict(String name) {
|
private byte[] restrict(String name) {
|
||||||
return PluginMessage.genBufPacket(buf -> {
|
return PluginMessage.genBufPacket(buf -> {
|
||||||
DefinedPacket.writeString(name, buf);
|
ProtocolUtils.writeString(buf, name);
|
||||||
buf.writeBoolean(false);
|
buf.writeBoolean(false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onRegister(ProxiedPlayer player) {
|
public void onRegister(Player player) {
|
||||||
for(byte[] packet : packets)
|
for(byte[] packet : packets)
|
||||||
player.sendData(CHANNEL, packet);
|
player.sendPluginMessage(CHANNEL, packet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,31 +19,68 @@
|
|||||||
|
|
||||||
package de.steamwar.bungeecore.mods;
|
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.VelocityCore;
|
||||||
import de.steamwar.bungeecore.listeners.BasicListener;
|
import de.steamwar.bungeecore.util.annotations.Create;
|
||||||
import de.steamwar.sql.Mod;
|
import de.steamwar.sql.Mod;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import net.md_5.bungee.api.ProxyServer;
|
import lombok.SneakyThrows;
|
||||||
import net.md_5.bungee.api.connection.PendingConnection;
|
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||||
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 java.lang.reflect.Field;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.TimeUnit;
|
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
|
// https://wiki.vg/Minecraft_Forge_Handshake#FML_protocol_.281.7_-_1.12.29
|
||||||
|
|
||||||
public static boolean isFML(PendingConnection connection, String type) {
|
private static final Field delegateField;
|
||||||
return ((InitialHandler)connection).getExtraDataInHandshake().equals("\0" + type);
|
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[]{
|
private final byte[] helloPacket = new byte[]{
|
||||||
/* Packet type: ServerHello */ 0,
|
/* Packet type: ServerHello */ 0,
|
||||||
/* FML protocol version */ 2,
|
/* FML protocol version */ 2,
|
||||||
@ -52,9 +89,9 @@ public class FML extends BasicListener {
|
|||||||
|
|
||||||
private static final Set<UUID> unlocked = new HashSet<>();
|
private static final Set<UUID> unlocked = new HashSet<>();
|
||||||
|
|
||||||
@EventHandler
|
@Subscribe
|
||||||
public void onPostLogin(PostLoginEvent event) {
|
public void onPostLogin(PostLoginEvent event) {
|
||||||
ProxiedPlayer player = event.getPlayer();
|
Player player = event.getPlayer();
|
||||||
|
|
||||||
synchronized (unlocked) {
|
synchronized (unlocked) {
|
||||||
if(unlocked.contains(player.getUniqueId())){
|
if(unlocked.contains(player.getUniqueId())){
|
||||||
@ -63,35 +100,36 @@ public class FML extends BasicListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isFML(player.getPendingConnection(), "FML\0"))
|
if(((ConnectedPlayer) event.getPlayer()).getConnection().getType() == ConnectionTypes.LEGACY_FORGE) {
|
||||||
player.sendData(CHANNEL, helloPacket);
|
player.sendPluginMessage(CHANNEL, helloPacket);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handlePluginMessage(PluginMessageEvent event) {
|
public void handlePluginMessage(PluginMessageEvent event) {
|
||||||
ProxiedPlayer p = (ProxiedPlayer) event.getSender();
|
Player p = (Player) event.getSource();
|
||||||
ByteBuf buf = Unpooled.wrappedBuffer(event.getData());
|
ByteBuf buf = Unpooled.wrappedBuffer(event.getData());
|
||||||
|
|
||||||
if (buf.readByte() == /* ModList */ 2) {
|
if (buf.readByte() == /* ModList */ 2) {
|
||||||
int numMods = DefinedPacket.readVarInt(buf);
|
int numMods = ProtocolUtils.readVarInt(buf);
|
||||||
|
|
||||||
List<Mod> mods = new ArrayList<>();
|
List<Mod> mods = new ArrayList<>();
|
||||||
for(int i = 0; i < numMods; i++) {
|
for(int i = 0; i < numMods; i++) {
|
||||||
String name = DefinedPacket.readString(buf);
|
String name = ProtocolUtils.readString(buf);
|
||||||
DefinedPacket.readString(buf); // version
|
ProtocolUtils.readString(buf); // version
|
||||||
|
|
||||||
mods.add(Mod.getOrCreate(name, Mod.Platform.FORGE));
|
mods.add(Mod.getOrCreate(name, Mod.Platform.FORGE));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ModUtils.handleMods(p, mods)) {
|
if (utils.handleMods(p, mods)) {
|
||||||
synchronized (unlocked) {
|
synchronized (unlocked) {
|
||||||
unlocked.add(p.getUniqueId());
|
unlocked.add(p.getUniqueId());
|
||||||
}
|
}
|
||||||
p.disconnect(VelocityCore.stringToText("§7Deine installierten Mods wurden überprüft\n§aDu kannst nun §eSteam§8War §abetreten"));
|
p.disconnect(LegacyComponentSerializer.legacySection().deserialize("§7Deine installierten Mods wurden überprüft\n§aDu kannst nun §eSteam§8War §abetreten"));
|
||||||
ProxyServer.getInstance().getScheduler().schedule(VelocityCore.get(), () -> {
|
proxyServer.getScheduler().buildTask(core, () -> {
|
||||||
synchronized (unlocked) {
|
synchronized (unlocked) {
|
||||||
unlocked.remove(p.getUniqueId());
|
unlocked.remove(p.getUniqueId());
|
||||||
}
|
}
|
||||||
}, 30, TimeUnit.SECONDS);
|
}).delay(30, TimeUnit.SECONDS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,29 +19,30 @@
|
|||||||
|
|
||||||
package de.steamwar.bungeecore.mods;
|
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.VelocityCore;
|
||||||
import de.steamwar.bungeecore.listeners.BasicListener;
|
|
||||||
import de.steamwar.bungeecore.listeners.IPSanitizer;
|
import de.steamwar.bungeecore.listeners.IPSanitizer;
|
||||||
import de.steamwar.bungeecore.listeners.PluginMessage;
|
import de.steamwar.bungeecore.listeners.PluginMessage;
|
||||||
|
import de.steamwar.bungeecore.util.annotations.Create;
|
||||||
import de.steamwar.sql.Mod;
|
import de.steamwar.sql.Mod;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import net.md_5.bungee.api.chat.TextComponent;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
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 java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.logging.Level;
|
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
|
// 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
|
// 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[] fml3ModListPacket;
|
||||||
private final byte[] forgeModListPacket;
|
private final byte[] forgeModListPacket;
|
||||||
|
|
||||||
public FML2() {
|
@Inject
|
||||||
|
public FML2(ModUtils modUtils) {
|
||||||
|
this.modUtils = modUtils;
|
||||||
fml2ModListPacket = generateModListPacket(false);
|
fml2ModListPacket = generateModListPacket(false);
|
||||||
fml3ModListPacket = generateModListPacket(true);
|
fml3ModListPacket = generateModListPacket(true);
|
||||||
forgeModListPacket = PluginMessage.genBufPacket(buf -> {
|
forgeModListPacket = PluginMessage.genBufPacket(buf -> {
|
||||||
buf.writeByte(0); // Login wrapper packet
|
buf.writeByte(0); // Login wrapper packet
|
||||||
DefinedPacket.writeString("forge:handshake", buf);
|
ProtocolUtils.writeString(buf, "forge:handshake");
|
||||||
|
|
||||||
ByteBuf packet = Unpooled.buffer();
|
ByteBuf packet = Unpooled.buffer();
|
||||||
packet.writeByte(1); // Mod list packet
|
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);
|
buf.writeBytes(packet);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@Subscribe
|
||||||
public void onLogin(LoginEvent event) {
|
public void onLogin(PreLoginEvent event) {
|
||||||
PendingConnection connection = event.getConnection();
|
LoginInboundConnection connection = (LoginInboundConnection) event.getConnection();
|
||||||
|
|
||||||
boolean fml2 = FML.isFML(connection, "FML2\0");
|
boolean fml2 = FML.isFML(connection, "FML2\0");
|
||||||
boolean fml3 = FML.isFML(connection, "FML3\0");
|
boolean fml3 = FML.isFML(connection, "FML3\0");
|
||||||
@ -79,45 +82,49 @@ public class FML2 extends BasicListener {
|
|||||||
if(!fml2 && !fml3 && !forge)
|
if(!fml2 && !fml3 && !forge)
|
||||||
return;
|
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) {
|
||||||
if(forge)
|
((LoginInboundConnection) event.getConnection()).sendLoginPluginMessage(MinecraftChannelIdentifier.from("forge:login"), forgeModListPacket, handler);
|
||||||
connection.unsafe().sendPacket(new LoginPayloadRequest(1, "forge:login", forgeModListPacket));
|
} else {
|
||||||
else
|
((LoginInboundConnection) event.getConnection()).sendLoginPluginMessage(MinecraftChannelIdentifier.from("fml:loginwrapper"), fml3 ? fml3ModListPacket : fml2ModListPacket, handler);
|
||||||
connection.unsafe().sendPacket(new LoginPayloadRequest(1, "fml:loginwrapper", fml3 ? fml3ModListPacket : fml2ModListPacket));
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte[] generateModListPacket(boolean fml3) {
|
private byte[] generateModListPacket(boolean fml3) {
|
||||||
return PluginMessage.genBufPacket(buf -> {
|
return PluginMessage.genBufPacket(buf -> {
|
||||||
DefinedPacket.writeString("fml:handshake", buf);
|
ProtocolUtils.writeString(buf, "fml:handshake");
|
||||||
|
|
||||||
ByteBuf packet = Unpooled.buffer();
|
ByteBuf packet = Unpooled.buffer();
|
||||||
packet.writeByte(1); // Mod list packet
|
packet.writeByte(1); // Mod list packet
|
||||||
DefinedPacket.writeVarInt(0, packet); // Mod amount
|
ProtocolUtils.writeVarInt(packet, 0); // Mod amount
|
||||||
|
|
||||||
if(fml3) {
|
if(fml3) {
|
||||||
DefinedPacket.writeVarInt(1, packet); // Channel amount
|
ProtocolUtils.writeVarInt(packet,1); // Channel amount
|
||||||
DefinedPacket.writeString("forge:tier_sorting", packet);
|
ProtocolUtils.writeString(packet, "forge:tier_sorting");
|
||||||
DefinedPacket.writeString("1.0", packet);
|
ProtocolUtils.writeString(packet, "1.0");
|
||||||
} else {
|
} 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)
|
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);
|
buf.writeBytes(packet);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class FML2LoginHandler extends PacketHandler {
|
private class FML2LoginHandler implements LoginPhaseConnection.MessageConsumer {
|
||||||
private final LoginEvent event;
|
private final LoginInboundConnection connection;
|
||||||
|
private final UUID uuid;
|
||||||
|
private final boolean forge;
|
||||||
|
|
||||||
public FML2LoginHandler(LoginEvent event) {
|
private FML2LoginHandler(LoginInboundConnection connection, UUID uuid, boolean forge) {
|
||||||
this.event = event;
|
this.connection = connection;
|
||||||
|
this.uuid = uuid;
|
||||||
|
this.forge = forge;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -125,59 +132,52 @@ public class FML2 extends BasicListener {
|
|||||||
return "SteamWar Forge Handler";
|
return "SteamWar Forge Handler";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void abort(byte[] response, String error) {
|
||||||
|
|
||||||
|
VelocityCore.get().getLogger().log(Level.SEVERE, () -> error + "\n" + Base64.getEncoder().encodeToString(response));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handle(LoginPayloadResponse response) {
|
public void onMessageResponse(byte @Nullable [] data) {
|
||||||
boolean forge = FML.isFML(event.getConnection(), "FORGE");
|
|
||||||
byte[] data = response.getData();
|
|
||||||
if(data == null) {
|
if(data == null) {
|
||||||
abort(response, "Not FML2/3 client");
|
abort(null, "Not FML2/3 client");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ByteBuf buf = Unpooled.wrappedBuffer(data);
|
ByteBuf buf = Unpooled.wrappedBuffer(data);
|
||||||
if(forge && buf.readByte() != 0) {
|
if(forge && buf.readByte() != 0) {
|
||||||
abort(response, "Not FORGE login wrapper");
|
abort(data, "Not FORGE login wrapper");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!DefinedPacket.readString(buf).equals(forge ? "forge:handshake" : "fml:handshake")) {
|
if(!ProtocolUtils.readString(buf).equals(forge ? "forge:handshake" : "fml:handshake")) {
|
||||||
abort(response, "Not FML2/3/FORGE handshake response");
|
abort(data, "Not FML2/3/FORGE handshake response");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(DefinedPacket.readVarInt(buf) != buf.readableBytes()) {
|
if(ProtocolUtils.readVarInt(buf) != buf.readableBytes()) {
|
||||||
abort(response, "FML2/3/FORGE packet size mismatch");
|
abort(data, "FML2/3/FORGE packet size mismatch");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(DefinedPacket.readVarInt(buf) != (forge ? /* Mod Versions */ 1 : /* Mod List Reply */ 2)) {
|
if(ProtocolUtils.readVarInt(buf) != (forge ? /* Mod Versions */ 1 : /* Mod List Reply */ 2)) {
|
||||||
abort(response, "Not FML2/3/FORGE mod list reply");
|
abort(data, "Not FML2/3/FORGE mod list reply");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Mod> mods = new ArrayList<>();
|
List<Mod> mods = new ArrayList<>();
|
||||||
|
|
||||||
int modCount = DefinedPacket.readVarInt(buf);
|
int modCount = ProtocolUtils.readVarInt(buf);
|
||||||
for(int i = 0; i < modCount; i++) {
|
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) {
|
if(forge) {
|
||||||
DefinedPacket.readString(buf); // Human readable name
|
ProtocolUtils.readString(buf); // Human readable name
|
||||||
DefinedPacket.readString(buf); // Version
|
ProtocolUtils.readString(buf); // Version
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!ModUtils.handleMods(event.getConnection().getUniqueId(), Locale.getDefault(), event::setReason, mods))
|
modUtils.handleMods(uuid, Locale.getDefault(), connection::disconnect, 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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,31 +22,42 @@ package de.steamwar.bungeecore.mods;
|
|||||||
import com.google.gson.JsonArray;
|
import com.google.gson.JsonArray;
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
import com.google.gson.JsonParser;
|
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.VelocityCore;
|
||||||
import de.steamwar.bungeecore.Storage;
|
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.Mod;
|
||||||
import de.steamwar.sql.SWException;
|
import de.steamwar.sql.SWException;
|
||||||
import de.steamwar.sql.SteamwarUser;
|
import de.steamwar.sql.SteamwarUser;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.Unpooled;
|
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.*;
|
||||||
import java.util.concurrent.TimeUnit;
|
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> neededFabricMods = new HashSet<>();
|
||||||
private final Set<String> neededQuiltMods = 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("java");
|
||||||
neededFabricMods.add("minecraft");
|
neededFabricMods.add("minecraft");
|
||||||
neededFabricMods.add("steamwarmodsender");
|
neededFabricMods.add("steamwarmodsender");
|
||||||
@ -55,9 +66,9 @@ public class FabricModSender extends BasicListener {
|
|||||||
neededFabricMods.add("fabricloader");
|
neededFabricMods.add("fabricloader");
|
||||||
neededQuiltMods.add("quilt_loader");
|
neededQuiltMods.add("quilt_loader");
|
||||||
|
|
||||||
BungeeCord.getInstance().getScheduler().schedule(VelocityCore.get(), () -> {
|
proxyServer.getScheduler().buildTask(VelocityCore.get(), () -> {
|
||||||
synchronized (Storage.fabricExpectPluginMessage) {
|
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())) {
|
if (!Storage.fabricCheckedPlayers.containsKey(entry.getKey())) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -67,11 +78,11 @@ public class FabricModSender extends BasicListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, 0, 1, TimeUnit.SECONDS);
|
}).repeat(1, TimeUnit.SECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handlePluginMessage(PluginMessageEvent e){
|
public void handlePluginMessage(PluginMessageEvent e){
|
||||||
ProxiedPlayer player = (ProxiedPlayer) e.getSender();
|
Player player = (Player) e.getSource();
|
||||||
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
||||||
|
|
||||||
if (!Storage.fabricCheckedPlayers.containsKey(player)) {
|
if (!Storage.fabricCheckedPlayers.containsKey(player)) {
|
||||||
@ -87,7 +98,7 @@ public class FabricModSender extends BasicListener {
|
|||||||
List<Mod> mods = new ArrayList<>();
|
List<Mod> mods = new ArrayList<>();
|
||||||
|
|
||||||
ByteBuf buf = Unpooled.wrappedBuffer(e.getData());
|
ByteBuf buf = Unpooled.wrappedBuffer(e.getData());
|
||||||
String data = DefinedPacket.readString(buf, 1024*1024);
|
String data = ProtocolUtils.readString(buf, 1024*1024);
|
||||||
if(buf.readableBytes() > 0) {
|
if(buf.readableBytes() > 0) {
|
||||||
logMessage(user, "Invalid message length", Arrays.toString(e.getData()));
|
logMessage(user, "Invalid message length", Arrays.toString(e.getData()));
|
||||||
return;
|
return;
|
||||||
@ -104,7 +115,7 @@ public class FabricModSender extends BasicListener {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!ModUtils.handleMods(player,mods))
|
if(!utils.handleMods(player,mods))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!Storage.fabricCheckedPlayers.containsKey(player)) {
|
if (!Storage.fabricCheckedPlayers.containsKey(player)) {
|
||||||
@ -114,17 +125,17 @@ public class FabricModSender extends BasicListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@Subscribe
|
||||||
public void onServerSwitchEvent(ServerSwitchEvent e) {
|
public void onServerSwitchEvent(ServerConnectedEvent e) {
|
||||||
if (e.getFrom() == null) return;
|
if (e.getPreviousServer().isEmpty()) return;
|
||||||
synchronized (Storage.fabricExpectPluginMessage) {
|
synchronized (Storage.fabricExpectPluginMessage) {
|
||||||
Storage.fabricExpectPluginMessage.put(e.getPlayer(), System.currentTimeMillis());
|
Storage.fabricExpectPluginMessage.put(e.getPlayer(), System.currentTimeMillis());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@Subscribe
|
||||||
public void onDisconnect(PlayerDisconnectEvent e) {
|
public void onDisconnect(DisconnectEvent e) {
|
||||||
ProxiedPlayer player = e.getPlayer();
|
Player player = e.getPlayer();
|
||||||
|
|
||||||
Storage.fabricCheckedPlayers.remove(player);
|
Storage.fabricCheckedPlayers.remove(player);
|
||||||
synchronized (Storage.fabricExpectPluginMessage) {
|
synchronized (Storage.fabricExpectPluginMessage) {
|
||||||
|
@ -21,12 +21,14 @@ package de.steamwar.bungeecore.mods;
|
|||||||
|
|
||||||
import com.google.gson.JsonArray;
|
import com.google.gson.JsonArray;
|
||||||
import com.google.gson.JsonObject;
|
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 {
|
public class Feather {
|
||||||
//https://github.com/Koupah/Feather-Client-API/blob/main/src/club/koupah/feather/packets/FeatherMod.java
|
//https://github.com/Koupah/Feather-Client-API/blob/main/src/club/koupah/feather/packets/FeatherMod.java
|
||||||
//https://archive.org/details/feather-server-api
|
//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;
|
private final byte[] packet;
|
||||||
public Feather() {
|
public Feather() {
|
||||||
@ -50,7 +52,7 @@ public class Feather {
|
|||||||
packet = obj.toString().getBytes();
|
packet = obj.toString().getBytes();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendRestrictions(ProxiedPlayer player) {
|
public void sendRestrictions(Player player) {
|
||||||
player.sendData(CHANNEL, packet);
|
player.sendPluginMessage(CHANNEL, packet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,48 +22,53 @@ package de.steamwar.bungeecore.mods;
|
|||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import com.google.gson.JsonParser;
|
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.VelocityCore;
|
||||||
import de.steamwar.bungeecore.listeners.PluginMessage;
|
import de.steamwar.bungeecore.listeners.PluginMessage;
|
||||||
|
import de.steamwar.bungeecore.util.annotations.Create;
|
||||||
import de.steamwar.sql.Mod;
|
import de.steamwar.sql.Mod;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.Unpooled;
|
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.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
@Create
|
||||||
public class LabyMod {
|
public class LabyMod {
|
||||||
// https://docs.labymod.net/pages/server/introduction/
|
// https://docs.labymod.net/pages/server/introduction/
|
||||||
// https://github.com/LabyMod/labymod-server-api
|
// https://github.com/LabyMod/labymod-server-api
|
||||||
// https://dl.labymod.net/addons.json
|
// https://dl.labymod.net/addons.json
|
||||||
|
|
||||||
|
private final ModUtils utils;
|
||||||
|
|
||||||
private final byte[] gameInfoPacket;
|
private final byte[] gameInfoPacket;
|
||||||
public LabyMod() {
|
public LabyMod(ModUtils utils) {
|
||||||
|
this.utils = utils;
|
||||||
gameInfoPacket = PluginMessage.genBufPacket(buf -> {
|
gameInfoPacket = PluginMessage.genBufPacket(buf -> {
|
||||||
DefinedPacket.writeString("discord_rpc", buf);
|
ProtocolUtils.writeString(buf, "discord_rpc");
|
||||||
|
|
||||||
JsonObject json = new JsonObject();
|
JsonObject json = new JsonObject();
|
||||||
json.addProperty("hasGame", true);
|
json.addProperty("hasGame", true);
|
||||||
json.addProperty("game_mode", "steamwar.de");
|
json.addProperty("game_mode", "steamwar.de");
|
||||||
json.addProperty("game_startTime", 0);
|
json.addProperty("game_startTime", 0);
|
||||||
json.addProperty("game_endTime", 0);
|
json.addProperty("game_endTime", 0);
|
||||||
DefinedPacket.writeString(json.toString(), buf);
|
ProtocolUtils.writeString(buf, json.toString());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handlePluginMessage(PluginMessageEvent event) {
|
public void handlePluginMessage(PluginMessageEvent event) {
|
||||||
ProxiedPlayer player = (ProxiedPlayer) event.getSender();
|
Player player = (Player) event.getSource();
|
||||||
player.sendData(event.getTag(), gameInfoPacket);
|
player.sendPluginMessage(event.getIdentifier(), gameInfoPacket);
|
||||||
|
|
||||||
ByteBuf buf = Unpooled.wrappedBuffer(event.getData());
|
ByteBuf buf = Unpooled.wrappedBuffer(event.getData());
|
||||||
String purpose = DefinedPacket.readString(buf);
|
String purpose = ProtocolUtils.readString(buf);
|
||||||
if(!"INFO".equals(purpose))
|
if(!"INFO".equals(purpose))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
JsonObject message = JsonParser.parseString(DefinedPacket.readString(buf)).getAsJsonObject();
|
JsonObject message = JsonParser.parseString(ProtocolUtils.readString(buf)).getAsJsonObject();
|
||||||
List<Mod> mods = new LinkedList<>();
|
List<Mod> mods = new LinkedList<>();
|
||||||
|
|
||||||
if(message.has("addons")) {
|
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.AbstractApolloPlayer;
|
||||||
import com.lunarclient.apollo.player.v1.ModMessage;
|
import com.lunarclient.apollo.player.v1.ModMessage;
|
||||||
import com.lunarclient.apollo.player.v1.PlayerHandshakeMessage;
|
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.VelocityCore;
|
||||||
|
import de.steamwar.bungeecore.util.annotations.Create;
|
||||||
import de.steamwar.sql.Mod;
|
import de.steamwar.sql.Mod;
|
||||||
import lombok.AllArgsConstructor;
|
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.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -44,13 +47,16 @@ import java.util.UUID;
|
|||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
@Create
|
||||||
public class Lunar {
|
public class Lunar {
|
||||||
// https://lunarclient.dev/apollo/introduction
|
// https://lunarclient.dev/apollo/introduction
|
||||||
// https://github.com/LunarClient/Apollo
|
// https://github.com/LunarClient/Apollo
|
||||||
|
|
||||||
private final ApolloModuleManager manager = new ApolloModuleManagerImpl().addModule(ModSettingModule.class);
|
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();
|
Options modSettings = manager.getModule(ModSettingModule.class).getOptions();
|
||||||
modSettings.set(ModReplaymod.ENABLED, false); // TODO check if restrictions working
|
modSettings.set(ModReplaymod.ENABLED, false); // TODO check if restrictions working
|
||||||
modSettings.set(ModFreelook.ENABLED, false);
|
modSettings.set(ModFreelook.ENABLED, false);
|
||||||
@ -60,14 +66,16 @@ public class Lunar {
|
|||||||
modSettings.set(ModTeamView.ENABLED, false);
|
modSettings.set(ModTeamView.ENABLED, false);
|
||||||
modSettings.set(ModTntCountdown.ENABLED, false);
|
modSettings.set(ModTntCountdown.ENABLED, false);
|
||||||
modSettings.set(ModToggleSneak.TOGGLE_SNEAK_CONTAINER, 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));
|
NetworkOptions.sendOptions(manager.getModules(), true, new SWApolloPlayer(player));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handlePluginMessage(PluginMessageEvent event) {
|
public void handlePluginMessage(PluginMessageEvent event) {
|
||||||
ProxiedPlayer player = (ProxiedPlayer) event.getSender();
|
Player player = (Player) event.getSource();
|
||||||
Any packet;
|
Any packet;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -94,12 +102,12 @@ public class Lunar {
|
|||||||
case TYPE_UNSPECIFIED:
|
case TYPE_UNSPECIFIED:
|
||||||
case UNRECOGNIZED:
|
case UNRECOGNIZED:
|
||||||
default:
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ModUtils.handleMods(player, mods);
|
utils.handleMods(player, mods);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,7 +120,9 @@ public class Lunar {
|
|||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
private static class SWApolloPlayer extends AbstractApolloPlayer {
|
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
|
@Override
|
||||||
public void sendPacket(Message message) {
|
public void sendPacket(Message message) {
|
||||||
@ -121,11 +131,11 @@ public class Lunar {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendPacket(byte[] bytes) {
|
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 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 boolean hasPermission(String s) { return player.hasPermission(s); }
|
||||||
@Override public Object getPlayer() { return player; }
|
@Override public Object getPlayer() { return player; }
|
||||||
}
|
}
|
||||||
|
@ -19,19 +19,20 @@
|
|||||||
|
|
||||||
package de.steamwar.bungeecore.mods;
|
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.VelocityCore;
|
||||||
import de.steamwar.bungeecore.Message;
|
import de.steamwar.bungeecore.Message;
|
||||||
import de.steamwar.bungeecore.commands.PunishmentCommand;
|
import de.steamwar.bungeecore.commands.PunishmentCommand;
|
||||||
|
import de.steamwar.bungeecore.util.annotations.Create;
|
||||||
import de.steamwar.sql.SteamwarUser;
|
import de.steamwar.sql.SteamwarUser;
|
||||||
import de.steamwar.messages.ChatSender;
|
import de.steamwar.messages.ChatSender;
|
||||||
import de.steamwar.sql.Mod;
|
import de.steamwar.sql.Mod;
|
||||||
import de.steamwar.sql.Mod.ModType;
|
import de.steamwar.sql.Mod.ModType;
|
||||||
import de.steamwar.sql.UserPerm;
|
import de.steamwar.sql.UserPerm;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.experimental.UtilityClass;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.md_5.bungee.api.chat.BaseComponent;
|
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||||
import net.md_5.bungee.api.chat.TextComponent;
|
|
||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
|
||||||
|
|
||||||
import java.sql.Timestamp;
|
import java.sql.Timestamp;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
@ -39,19 +40,27 @@ import java.time.temporal.ChronoUnit;
|
|||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@UtilityClass
|
@Create
|
||||||
public class ModUtils {
|
public class ModUtils {
|
||||||
|
|
||||||
@Getter
|
private final Logger logger;
|
||||||
private static final Map<UUID,List<Mod>> playerModMap = new HashMap<>();
|
|
||||||
|
|
||||||
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);
|
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);
|
SteamwarUser user = SteamwarUser.get(uuid);
|
||||||
playerModMap.put(uuid,new ArrayList<>(mods));
|
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(" ")));
|
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) {
|
if(max == ModType.RED) {
|
||||||
PunishmentCommand.ban(user, Timestamp.from(Instant.now().plus(7, ChronoUnit.DAYS)), message, SteamwarUser.get(-1), false);
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,9 +19,9 @@
|
|||||||
|
|
||||||
package de.steamwar.bungeecore.mods;
|
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 de.steamwar.bungeecore.listeners.PluginMessage;
|
||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
|
||||||
import net.md_5.bungee.api.event.PluginMessageEvent;
|
|
||||||
|
|
||||||
public class WorldDownloader {
|
public class WorldDownloader {
|
||||||
// https://wiki.vg/Plugin_channels/World_downloader
|
// https://wiki.vg/Plugin_channels/World_downloader
|
||||||
@ -43,6 +43,6 @@ public class WorldDownloader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void handlePluginMessage(PluginMessageEvent event) {
|
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;
|
package de.steamwar.bungeecore.network;
|
||||||
|
|
||||||
|
import com.velocitypowered.api.proxy.server.ServerInfo;
|
||||||
import de.steamwar.network.packets.MetaInfos;
|
import de.steamwar.network.packets.MetaInfos;
|
||||||
import net.md_5.bungee.api.config.ServerInfo;
|
|
||||||
|
|
||||||
public class ServerMetaInfo implements MetaInfos {
|
public class ServerMetaInfo implements MetaInfos {
|
||||||
|
|
||||||
|
@ -19,26 +19,35 @@
|
|||||||
|
|
||||||
package de.steamwar.bungeecore.util;
|
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.Message;
|
||||||
|
import de.steamwar.bungeecore.util.annotations.Create;
|
||||||
import de.steamwar.messages.ChatSender;
|
import de.steamwar.messages.ChatSender;
|
||||||
import de.steamwar.sql.SteamwarUser;
|
import de.steamwar.sql.SteamwarUser;
|
||||||
import de.steamwar.sql.UserConfig;
|
import de.steamwar.sql.UserConfig;
|
||||||
import de.steamwar.sql.UserPerm;
|
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 {
|
public class BauLock {
|
||||||
|
|
||||||
private static final String BAU_LOCK_CONFIG_NAME = "baulockstate";
|
private final ProxyServer proxy;
|
||||||
public static void setLocked(ProxiedPlayer p, BauLockState state) {
|
|
||||||
|
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());
|
SteamwarUser owner = SteamwarUser.get(p.getUniqueId());
|
||||||
UserConfig.updatePlayerConfig(owner.getId(), BAU_LOCK_CONFIG_NAME, state == BauLockState.OPEN ? null : state.name());
|
UserConfig.updatePlayerConfig(owner.getId(), BAU_LOCK_CONFIG_NAME, state == BauLockState.OPEN ? null : state.name());
|
||||||
Message.send("BAU_LOCKED_" + state.name(), p);
|
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);
|
ChatSender sender = ChatSender.of(player);
|
||||||
SteamwarUser target = sender.user();
|
SteamwarUser target = sender.user();
|
||||||
if (owner.getId() == target.getId())
|
if (owner.getId() == target.getId())
|
||||||
@ -70,9 +79,7 @@ public class BauLock {
|
|||||||
if(locked) {
|
if(locked) {
|
||||||
sender.system("BAU_LOCKED_NOALLOWED");
|
sender.system("BAU_LOCKED_NOALLOWED");
|
||||||
|
|
||||||
ProxiedPlayer ownerPlayer = ProxyServer.getInstance().getPlayer(owner.getUUID());
|
proxy.getPlayer(owner.getUUID()).ifPresent(ownerPlayer -> ChatSender.of(ownerPlayer).system("BAU_LOCK_BLOCKED", player.getUsername()));
|
||||||
if(ownerPlayer != null)
|
|
||||||
ChatSender.of(ownerPlayer).system("BAU_LOCK_BLOCKED", player.getName());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return locked;
|
return locked;
|
||||||
|
@ -19,30 +19,19 @@
|
|||||||
|
|
||||||
package de.steamwar.bungeecore.util;
|
package de.steamwar.bungeecore.util;
|
||||||
|
|
||||||
import net.md_5.bungee.ServerConnection;
|
import com.velocitypowered.api.proxy.Player;
|
||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
|
||||||
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 java.util.BitSet;
|
import java.time.Instant;
|
||||||
import java.util.Collections;
|
|
||||||
|
|
||||||
public class Chat19 {
|
public class Chat19 {
|
||||||
private Chat19(){}
|
private Chat19(){}
|
||||||
|
|
||||||
public static void chat(ProxiedPlayer p, String message) {
|
public static void chat(Player p, String message) {
|
||||||
int version = p.getPendingConnection().getVersion();
|
((ConnectedPlayer) p).getChatBuilderFactory().builder()
|
||||||
if(version >= ProtocolConstants.MINECRAFT_1_19) {
|
.setTimestamp(Instant.now())
|
||||||
if(message.startsWith("/")) {
|
.asPlayer(p)
|
||||||
((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))));
|
.message(message)
|
||||||
} else {
|
.toServer();
|
||||||
((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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -21,10 +21,12 @@ package de.steamwar.bungeecore.util;
|
|||||||
|
|
||||||
import com.google.inject.AbstractModule;
|
import com.google.inject.AbstractModule;
|
||||||
import com.google.inject.Provides;
|
import com.google.inject.Provides;
|
||||||
|
import com.google.inject.Scopes;
|
||||||
import com.google.inject.Singleton;
|
import com.google.inject.Singleton;
|
||||||
import de.steamwar.bungeecore.Node;
|
import de.steamwar.bungeecore.Node;
|
||||||
import de.steamwar.bungeecore.VelocityCore;
|
import de.steamwar.bungeecore.VelocityCore;
|
||||||
import de.steamwar.bungeecore.commands.HelpCommand;
|
import de.steamwar.bungeecore.commands.HelpCommand;
|
||||||
|
import de.steamwar.bungeecore.mods.*;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
public final class SteamWarModule extends AbstractModule {
|
public final class SteamWarModule extends AbstractModule {
|
||||||
@ -38,7 +40,13 @@ public final class SteamWarModule extends AbstractModule {
|
|||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
bind(VelocityCore.class).toInstance(core);
|
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
|
@Provides
|
||||||
|
@ -19,18 +19,69 @@
|
|||||||
|
|
||||||
package de.steamwar.command;
|
package de.steamwar.command;
|
||||||
|
|
||||||
|
import com.mojang.brigadier.tree.CommandNode;
|
||||||
import com.velocitypowered.api.command.Command;
|
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 de.steamwar.bungeecore.VelocityCore;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.ToString;
|
||||||
import lombok.experimental.UtilityClass;
|
import lombok.experimental.UtilityClass;
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
@UtilityClass
|
@UtilityClass
|
||||||
class CommandRegistering {
|
class CommandRegistering {
|
||||||
|
|
||||||
static void unregister(String name) {
|
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) {
|
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