Dieser Commit ist enthalten in:
Ursprung
ef71323b05
Commit
a1d8ec806f
@ -96,6 +96,7 @@ dependencies {
|
||||
|
||||
compileOnly 'com.velocitypowered:velocity-api:3.3.0-SNAPSHOT'
|
||||
annotationProcessor 'com.velocitypowered:velocity-api:3.3.0-SNAPSHOT'
|
||||
// TODO: Add velocity-proxy as a compileOnly dependency to steamwar-maven
|
||||
//compileOnly 'com.velocitypowered:velocity-proxy:3.3.0-SNAPSHOT'
|
||||
|
||||
//implementation 'org.reflections:reflections:0.10.2'
|
||||
@ -105,6 +106,7 @@ dependencies {
|
||||
|
||||
implementation 'org.yaml:snakeyaml:2.2'
|
||||
|
||||
// TODO: Monorepo?
|
||||
compileOnly files('persistentvelocitycore.jar')
|
||||
implementation("net.dv8tion:JDA:4.4.0_352") {
|
||||
exclude module: 'opus-java'
|
||||
|
@ -19,27 +19,25 @@
|
||||
|
||||
package de.steamwar.bungeecore.listeners;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.lunarclient.apollo.ApolloManager;
|
||||
import com.velocitypowered.api.event.Subscribe;
|
||||
import com.velocitypowered.api.event.connection.PluginMessageEvent;
|
||||
import com.velocitypowered.api.network.ProtocolVersion;
|
||||
import com.velocitypowered.api.proxy.Player;
|
||||
import com.velocitypowered.api.proxy.ServerConnection;
|
||||
import com.velocitypowered.api.proxy.messages.ChannelMessageSource;
|
||||
import com.velocitypowered.api.proxy.messages.LegacyChannelIdentifier;
|
||||
import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier;
|
||||
import de.steamwar.bungeecore.VelocityCore;
|
||||
import de.steamwar.messages.Message;
|
||||
import de.steamwar.bungeecore.commands.TeamCommand;
|
||||
import de.steamwar.bungeecore.mods.*;
|
||||
import de.steamwar.bungeecore.network.ServerMetaInfo;
|
||||
import de.steamwar.messages.Chatter;
|
||||
import de.steamwar.network.packets.NetworkPacket;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.ByteBufAllocator;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import net.md_5.bungee.api.ChatMessageType;
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
import net.md_5.bungee.api.chat.TextComponent;
|
||||
import net.md_5.bungee.api.connection.Connection;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import net.md_5.bungee.api.connection.Server;
|
||||
import net.md_5.bungee.api.event.PluginMessageEvent;
|
||||
import net.md_5.bungee.connection.InitialHandler;
|
||||
import net.md_5.bungee.event.EventHandler;
|
||||
import net.md_5.bungee.protocol.DefinedPacket;
|
||||
import net.kyori.adventure.text.Component;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataOutputStream;
|
||||
@ -48,16 +46,21 @@ import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class PluginMessage extends BasicListener {
|
||||
public class PluginMessage {
|
||||
|
||||
public static void send(ProxiedPlayer player, String legacyChannel, String channel, byte[] data) {
|
||||
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.getPendingConnection().getVersion() > 340 ? channel : legacyChannel, data);
|
||||
send(player, player.getProtocolVersion().getProtocol() > 340 ? channel : legacyChannel, data);
|
||||
}
|
||||
|
||||
public static void send(ProxiedPlayer player, String channel, byte[] data) {
|
||||
if(((InitialHandler)player.getPendingConnection()).getRegisteredChannels().contains(channel))
|
||||
player.sendData(channel, data);
|
||||
public static void send(Player player, String channel, byte[] data) {
|
||||
player.sendPluginMessage(MinecraftChannelIdentifier.from(channel), data);
|
||||
}
|
||||
|
||||
public static byte[] genBufPacket(Consumer<ByteBuf> generator) {
|
||||
@ -86,20 +89,25 @@ public class PluginMessage extends BasicListener {
|
||||
void accept(DataOutputStream out) throws IOException;
|
||||
}
|
||||
|
||||
private static final Parser UNKNOWN = event -> VelocityCore.getLogger().log(Level.WARNING, () -> "Undefined PluginMessage on channel " + event.getTag() + " from " + event.getSender() + " received.\n" + new String(event.getData()) + "\n" + Arrays.toString(event.getData()));
|
||||
private static final Parser PASS_THROUGH = event -> event.setCancelled(false);
|
||||
private static final Parser DROP = event -> {};
|
||||
|
||||
private final Lunar lunar = new Lunar();
|
||||
private static final Parser UNKNOWN = event -> {
|
||||
VelocityCore.get().getLogger().log(Level.WARNING, () -> "Undefined PluginMessage on channel " + event.getIdentifier().getId() + " from " + (event.getSource() instanceof Player pl ? pl.getUsername() : event.getSource().toString()) + " received.\n" + new String(event.getData()) + "\n" + Arrays.toString(event.getData()));
|
||||
event.setResult(PluginMessageEvent.ForwardResult.handled());
|
||||
};
|
||||
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 Set<String> knownBrands = new HashSet<>();
|
||||
private final Map<String, Consumer<ProxiedPlayer>> channelRegisterHandlers = new HashMap<>();
|
||||
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();
|
||||
ModUtils utils = new ModUtils();
|
||||
|
||||
this.lunar = new Lunar(utils);
|
||||
this.labyMod = new LabyMod(utils);
|
||||
this.wdl = new WorldDownloader();
|
||||
this.fms = new FabricModSender(utils);
|
||||
this.flm = new FML(utils);
|
||||
|
||||
knownBrands.addAll(Arrays.asList("vanilla", "fabric", "quilt", "forge", "optifine", "Geyser", "labymod", "Feather Fabric"));
|
||||
|
||||
@ -107,7 +115,7 @@ public class PluginMessage extends BasicListener {
|
||||
"fabric:container/open", "fabric:registry/sync/direct", "fabric:registry/sync",
|
||||
"fabric-screen-handler-api-v1:open_screen",
|
||||
|
||||
FML.CHANNEL, "fml:loginwrapper", "fml:handshake", "fml:play", "forge:tier_sorting", "forge:split",
|
||||
FML.CHANNEL.getId(), "fml:loginwrapper", "fml:handshake", "fml:play", "forge:tier_sorting", "forge:split",
|
||||
"forge:login", "forge:handshake",
|
||||
|
||||
"labymod3:main", "labymod:neo",
|
||||
@ -145,16 +153,18 @@ public class PluginMessage extends BasicListener {
|
||||
"noxesium-v1:reset", "noxesium-v1:change_server_rules", "noxesium-v1:server_info",
|
||||
"noxesium-v1:mcc_server", "noxesium-v1:mcc_game_state", "noxesium-v1:reset_server_rules",
|
||||
"noxesium-v1:stop_sound", "noxesium-v1:start_sound", "noxesium-v1:modify_sound"
|
||||
))
|
||||
channelRegisterHandlers.put(channel, player -> {});
|
||||
)) {
|
||||
channelRegisterHandlers.put(channel, player -> {
|
||||
});
|
||||
}
|
||||
|
||||
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("litemoretica:init_easy_place", player -> player.disconnect(Chatter.of(player).parse(false, new Message("MOD_YELLOW_SING", "litematica")))); //https://github.com/Earthcomputer/litemoretica/tree/master
|
||||
channelRegisterHandlers.put("voxelmap:settings", player -> player.disconnect(Chatter.of(player).parse(false, new Message("MOD_YELLOW_SING", "voxelmap")))); //https://modrinth.com/mod/voxelmap-updated undocumented
|
||||
channelRegisterHandlers.put("worldinfo:world_id", player -> player.disconnect(Chatter.of(player).parse(false, new Message("MOD_YELLOW_SING", "minimap")))); // JourneyMap and VoxelMap
|
||||
channelRegisterHandlers.put(Controlify.CHANNEL, new Controlify()::onRegister);
|
||||
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.getId(), new Controlify()::onRegister);
|
||||
|
||||
registerBiDirPassthrough("worldedit:cui");
|
||||
|
||||
@ -194,9 +204,9 @@ public class PluginMessage extends BasicListener {
|
||||
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()).getServer()), 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));
|
||||
@ -205,7 +215,7 @@ public class PluginMessage extends BasicListener {
|
||||
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.getId(), 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
|
||||
@ -214,12 +224,12 @@ public class PluginMessage extends BasicListener {
|
||||
// Hackclientlike modsuppressor for labymod: https://github.com/Neocraftr/LabyMod-NeoEssentials (Potentially recognizable from NO Addons/NO Mods?) https://github.com/Neocraftr/LabyMod-NeoEssentials/blob/master/src/main/java/de/neocraftr/neoessentials/utils/BytecodeMethods.java
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
@Subscribe
|
||||
public void onPluginMessage(PluginMessageEvent event) {
|
||||
event.setCancelled(true);
|
||||
event.setResult(PluginMessageEvent.ForwardResult.handled());
|
||||
|
||||
try {
|
||||
handlers.getOrDefault(event.getTag(), UNKNOWN).handle(event);
|
||||
handlers.getOrDefault(event.getIdentifier().getId(), UNKNOWN).handle(event);
|
||||
} catch (Exception e) {
|
||||
throw new SecurityException("PluginMessage handling exception: " + event + "\n" + Arrays.toString(event.getData()), e);
|
||||
}
|
||||
@ -247,34 +257,34 @@ public class PluginMessage extends BasicListener {
|
||||
private void register(String channel, boolean clientSideRegister, Parser handler) {
|
||||
handlers.put(channel, handler);
|
||||
if(clientSideRegister)
|
||||
ProxyServer.getInstance().registerChannel(channel);
|
||||
VelocityCore.get().getProxyServer().getChannelRegistrar().register(MinecraftChannelIdentifier.from(channel));
|
||||
}
|
||||
|
||||
private void clientRegistersChannel(PluginMessageEvent event) {
|
||||
ProxiedPlayer player = (ProxiedPlayer) event.getSender();
|
||||
Player player = (Player) event.getSource();
|
||||
|
||||
for(String channel : new String(event.getData()).split("\0")) {
|
||||
channelRegisterHandlers.getOrDefault(channel, p -> VelocityCore.getLogger().log(Level.WARNING, () -> p.getName() + " registered unknown channel " + channel)).accept(player);
|
||||
channelRegisterHandlers.getOrDefault(channel, p -> VelocityCore.get().getLogger().log(Level.WARNING, () -> p.getUsername() + " registered unknown channel " + channel)).accept(player);
|
||||
}
|
||||
|
||||
PASS_THROUGH.handle(event);
|
||||
}
|
||||
|
||||
private void serverRegistersChannel(PluginMessageEvent event) {
|
||||
ProxiedPlayer player = (ProxiedPlayer)event.getReceiver();
|
||||
Player player = (Player) event.getTarget();
|
||||
|
||||
List<String> channels = new ArrayList<>(Arrays.asList(new String(event.getData()).split("\0")));
|
||||
channels.removeIf(channel -> channel.equals("sw:bridge"));
|
||||
player.sendData((player).getPendingConnection().getVersion() > 340 ? "minecraft:register" : "REGISTER", String.join("\0", channels).getBytes());
|
||||
player.sendPluginMessage((player).getProtocolVersion().greaterThan(ProtocolVersion.MINECRAFT_1_12_2) ? MinecraftChannelIdentifier.from("minecraft:register") : new LegacyChannelIdentifier("REGISTER"), String.join("\0", channels).getBytes());
|
||||
}
|
||||
|
||||
private void userBrand(PluginMessageEvent event) {
|
||||
ProxiedPlayer player = (ProxiedPlayer) event.getSender();
|
||||
Player player = (Player) event.getSource();
|
||||
ByteBuf buf = Unpooled.wrappedBuffer(event.getData());
|
||||
String brand = DefinedPacket.readString(buf);
|
||||
String brand = ProtocolUtils.readString(buf);
|
||||
boolean lunarclient = brand.startsWith("lunarclient:");
|
||||
|
||||
VelocityCore.getLogger().log(knownBrands.contains(brand) || lunarclient ? Level.INFO : Level.WARNING, () -> player.getName() + " joins with brand: " + brand);
|
||||
VelocityCore.get().getLogger().log(knownBrands.contains(brand) || lunarclient ? Level.INFO : Level.WARNING, () -> player.getUsername() + " joins with brand: " + brand);
|
||||
if(lunarclient)
|
||||
lunar.sendRestrictions(player);
|
||||
|
||||
@ -282,30 +292,29 @@ public class PluginMessage extends BasicListener {
|
||||
}
|
||||
|
||||
private void steamWarBrand(PluginMessageEvent event) {
|
||||
ProxiedPlayer player = (ProxiedPlayer) event.getReceiver();
|
||||
String brandString = Chatter.of(player).parseToLegacy("STEAMWAR_BRAND", ProxyServer.getInstance().getName(), player.getServer().getInfo().getName(), new String(event.getData(), 1, event.getData().length - 1));
|
||||
Player player = (Player) event.getTarget();
|
||||
String brandString = ChatSender.of(player).parseToLegacy("STEAMWAR_BRAND", "Velocity", player.getCurrentServer().map(serverConnection -> serverConnection.getServerInfo().getName()).orElse(""), new String(event.getData(), 1, event.getData().length - 1));
|
||||
|
||||
ByteBuf brand = ByteBufAllocator.DEFAULT.heapBuffer();
|
||||
DefinedPacket.writeString(brandString, brand);
|
||||
player.sendData(event.getTag(), DefinedPacket.toArray(brand));
|
||||
ProtocolUtils.writeString(brand, brandString);
|
||||
player.sendPluginMessage(event.getIdentifier(), brand.array());
|
||||
brand.release();
|
||||
}
|
||||
|
||||
|
||||
private Parser directional(Parser fromServer, Parser fromPlayer) {
|
||||
return event -> {
|
||||
if(event.getSender() instanceof ProxiedPlayer)
|
||||
if(event.getSource() instanceof Player)
|
||||
fromPlayer.handle(event);
|
||||
else
|
||||
fromServer.handle(event);
|
||||
};
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private Parser onlySWSource(Parser parser) {
|
||||
return event -> {
|
||||
Connection sender = event.getSender();
|
||||
if(TeamCommand.isLocalhost(sender instanceof ProxiedPlayer ? IPSanitizer.getTrueAddress(((ProxiedPlayer) sender).getPendingConnection()) : sender.getAddress().getAddress()))
|
||||
ChannelMessageSource sender = event.getSource();
|
||||
if(TeamCommand.isLocalhost(sender instanceof Player player ? IPSanitizer.getTrueAddress((player)) : ((ServerConnection) sender).getServerInfo().getAddress().getAddress()))
|
||||
parser.handle(event);
|
||||
else
|
||||
UNKNOWN.handle(event);
|
||||
@ -313,7 +322,7 @@ public class PluginMessage extends BasicListener {
|
||||
}
|
||||
|
||||
private Parser async(Parser parser) {
|
||||
return event -> ProxyServer.getInstance().getScheduler().runAsync(VelocityCore.get(), () -> parser.handle(event));
|
||||
return event -> VelocityCore.get().getProxyServer().getScheduler().buildTask(VelocityCore.get(), () -> parser.handle(event)).schedule();
|
||||
}
|
||||
|
||||
private interface Parser {
|
||||
|
@ -20,11 +20,11 @@
|
||||
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;
|
||||
|
||||
public class Badlion extends BasicListener {
|
||||
public class Badlion {
|
||||
// https://github.com/BadlionClient/BadlionClientModAPI
|
||||
|
||||
private final byte[] packet;
|
||||
@ -50,8 +50,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,32 +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.messages.Chatter;
|
||||
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) {
|
||||
this.utils = utils;
|
||||
this.proxyServer = VelocityCore.getProxy();
|
||||
this.core = VelocityCore.get();
|
||||
}
|
||||
|
||||
@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,
|
||||
@ -53,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())){
|
||||
@ -64,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());
|
||||
}
|
||||
Chatter.disconnect(p).system("MODS_CHECKED");
|
||||
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,29 @@
|
||||
|
||||
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 {
|
||||
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
|
||||
|
||||
@ -54,24 +54,25 @@ public class FML2 extends BasicListener {
|
||||
private final byte[] forgeModListPacket;
|
||||
|
||||
public FML2() {
|
||||
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 +80,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 +130,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.getLogger().log(Level.SEVERE, () -> error + "\n" + response);
|
||||
modUtils.handleMods(uuid, Locale.getDefault(), connection::disconnect, mods);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -22,31 +22,40 @@ 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 Set<String> neededFabricMods = new HashSet<>();
|
||||
private final Set<String> neededQuiltMods = new HashSet<>();
|
||||
|
||||
public FabricModSender() {
|
||||
@Inject
|
||||
public FabricModSender(ModUtils utils) {
|
||||
this.utils = utils;
|
||||
this.proxyServer = VelocityCore.getProxy();
|
||||
neededFabricMods.add("java");
|
||||
neededFabricMods.add("minecraft");
|
||||
neededFabricMods.add("steamwarmodsender");
|
||||
@ -55,9 +64,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 +76,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 +96,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 +113,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 +123,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);
|
||||
}
|
||||
}
|
||||
|
@ -19,20 +19,19 @@
|
||||
|
||||
package de.steamwar.bungeecore.mods;
|
||||
|
||||
import com.velocitypowered.api.event.Subscribe;
|
||||
import com.velocitypowered.api.event.proxy.ProxyPingEvent;
|
||||
import de.steamwar.bungeecore.VelocityCore;
|
||||
import de.steamwar.bungeecore.listeners.BasicListener;
|
||||
import net.md_5.bungee.api.event.PlayerHandshakeEvent;
|
||||
import net.md_5.bungee.connection.InitialHandler;
|
||||
import net.md_5.bungee.event.EventHandler;
|
||||
import de.steamwar.bungeecore.util.annotations.Create;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class Hostname extends BasicListener {
|
||||
@Create
|
||||
public class Hostname {
|
||||
|
||||
private final Set<String> knownHostnames = new HashSet<>();
|
||||
private final Set<String> knownExtraData = new HashSet<>();
|
||||
|
||||
public Hostname() {
|
||||
knownHostnames.add("steamwar.de");
|
||||
@ -45,22 +44,13 @@ public class Hostname extends BasicListener {
|
||||
knownHostnames.add("wtf.mynx.lol"); //https://discord.com/invite/serverseeker
|
||||
knownHostnames.add("masscan");
|
||||
knownHostnames.add("aaa");
|
||||
|
||||
knownExtraData.add("");
|
||||
knownExtraData.add("\0FML\0");
|
||||
knownExtraData.add("\0FML2\0");
|
||||
knownExtraData.add("\0FML3\0");
|
||||
knownExtraData.add("\0FORGE");
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onHandshake(PlayerHandshakeEvent event) {
|
||||
String hostname = event.getHandshake().getHost().toLowerCase();
|
||||
String extraDataInHandshake = ((InitialHandler) event.getConnection()).getExtraDataInHandshake();
|
||||
@Subscribe
|
||||
public void onHandshake(ProxyPingEvent event) {
|
||||
String hostname = event.getConnection().getVirtualHost().map(inetSocketAddress -> inetSocketAddress.getHostName()).orElse("");
|
||||
if (!knownHostnames.contains(hostname) && !hostname.endsWith(".steamwar.de")) {
|
||||
VelocityCore.getLogger().log(Level.WARNING, () -> event.getConnection().getSocketAddress() + " connected with unknown hostname " + event.getHandshake() + " " + extraDataInHandshake);
|
||||
} else if (!knownExtraData.contains(extraDataInHandshake)) {
|
||||
VelocityCore.getLogger().log(Level.WARNING, () -> event.getConnection().getSocketAddress() + " connected with unknown extra data " + event.getHandshake() + " " + extraDataInHandshake);
|
||||
VelocityCore.get().getLogger().log(Level.WARNING, () -> event.getConnection().getRemoteAddress().toString() + " connected with unknown hostname '" + hostname + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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")) {
|
||||
@ -74,7 +79,7 @@ public class LabyMod {
|
||||
}
|
||||
|
||||
if(message.has("mods")) {
|
||||
VelocityCore.getLogger().log(Level.WARNING, () -> "LabyMod External Mods for debugging: " + message.getAsJsonArray("mods"));
|
||||
VelocityCore.get().getLogger().log(Level.WARNING, () -> "LabyMod External Mods for debugging: " + message.getAsJsonArray("mods"));
|
||||
for(JsonElement element : message.getAsJsonArray("mods")) {
|
||||
JsonObject addon = element.getAsJsonObject();
|
||||
//TODO observe: FORGE and FABRIC mods available, do they always and with .jar? (would equal new mod platform)
|
||||
@ -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.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,18 +19,17 @@
|
||||
|
||||
package de.steamwar.bungeecore.mods;
|
||||
|
||||
import com.velocitypowered.api.proxy.Player;
|
||||
import de.steamwar.bungeecore.VelocityCore;
|
||||
import de.steamwar.bungeecore.commands.PunishmentCommand;
|
||||
import de.steamwar.messages.Chatter;
|
||||
import de.steamwar.messages.Message;
|
||||
import de.steamwar.sql.SteamwarUser;
|
||||
import de.steamwar.sql.Mod;
|
||||
import de.steamwar.sql.Mod.ModType;
|
||||
import de.steamwar.sql.SteamwarUser;
|
||||
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;
|
||||
@ -38,23 +37,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
|
||||
public class ModUtils {
|
||||
private final Logger logger;
|
||||
|
||||
@Getter
|
||||
private static final Map<UUID,List<Mod>> playerModMap = new HashMap<>();
|
||||
private final Map<UUID,List<Mod>> playerModMap = new HashMap<>();
|
||||
|
||||
public static boolean handleMods(ProxiedPlayer player, List<Mod> mods) {
|
||||
return handleMods(player.getUniqueId(), Chatter.of(player).getLocale(), player::disconnect, mods);
|
||||
public ModUtils() {
|
||||
this.logger = VelocityCore.getLogger();
|
||||
}
|
||||
|
||||
public static boolean handleMods(UUID uuid, Locale locale, Consumer<BaseComponent> disconnect, List<Mod> mods){
|
||||
Chatter sender = Chatter.of(uuid);
|
||||
SteamwarUser user = sender.user();
|
||||
public boolean handleMods(Player player, List<Mod> mods) {
|
||||
return handleMods(player.getUniqueId(), ChatSender.of(player).getLocale(), player::disconnect, 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.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(" ")));
|
||||
|
||||
ModType max = ModType.YELLOW;
|
||||
Iterator<Mod> it = mods.iterator();
|
||||
@ -76,17 +79,17 @@ public class ModUtils {
|
||||
String message;
|
||||
|
||||
if(mods.size() == 1) {
|
||||
message = sender.parseToLegacy(max == ModType.RED ? "MOD_RED_SING" : "MOD_YELLOW_SING", locale, modList);
|
||||
message = Message.parse(max == ModType.RED ? "MOD_RED_SING" : "MOD_YELLOW_SING", locale, modList);
|
||||
} else {
|
||||
message = sender.parseToLegacy(max == ModType.RED ? "MOD_RED_PLUR" : "MOD_YELLOW_PLUR", locale, modList);
|
||||
message = Message.parse(max == ModType.RED ? "MOD_RED_PLUR" : "MOD_YELLOW_PLUR", locale, modList);
|
||||
}
|
||||
|
||||
if(max == ModType.RED) {
|
||||
PunishmentCommand.ban(user, Timestamp.from(Instant.now().plus(7, ChronoUnit.DAYS)), message, SteamwarUser.get(-1), false);
|
||||
VelocityCore.getLogger().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;
|
||||
}
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ public class ReplayMod extends BasicListener {
|
||||
public void onPlayerJoin(ServerSwitchEvent event) {
|
||||
ProxiedPlayer player = event.getPlayer();
|
||||
ServerInfo server = player.getServer().getInfo();
|
||||
if(ProxyServer.getInstance().getServerInfo(VelocityCore.get().getConfig().getLobbyserver()) == server)
|
||||
if(ProxyServer.getInstance().getServerInfo(VelocityCore.LOBBY_SERVER) == server)
|
||||
return;
|
||||
|
||||
Subserver subserver = Subserver.getSubserver(server);
|
||||
|
@ -19,9 +19,10 @@
|
||||
|
||||
package de.steamwar.bungeecore.mods;
|
||||
|
||||
import com.velocitypowered.api.event.Subscribe;
|
||||
import com.velocitypowered.api.event.connection.PostLoginEvent;
|
||||
import com.velocitypowered.api.proxy.messages.LegacyChannelIdentifier;
|
||||
import de.steamwar.bungeecore.listeners.BasicListener;
|
||||
import net.md_5.bungee.api.event.PostLoginEvent;
|
||||
import net.md_5.bungee.event.EventHandler;
|
||||
|
||||
public class Schematica extends BasicListener {
|
||||
// https://github.com/Lunatrius/SchematicaPlugin/blob/master/src/main/java/com/github/lunatrius/schematica/plugin/SchematicaPlugin.java
|
||||
@ -33,8 +34,8 @@ public class Schematica extends BasicListener {
|
||||
/* PERM_LOAD */ 1
|
||||
};
|
||||
|
||||
@EventHandler
|
||||
@Subscribe
|
||||
public void onPostLogin(PostLoginEvent event) {
|
||||
event.getPlayer().sendData("schematica", packet);
|
||||
event.getPlayer().sendPluginMessage(new LegacyChannelIdentifier("schematica"), packet);
|
||||
}
|
||||
}
|
||||
|
@ -20,44 +20,64 @@
|
||||
package de.steamwar.bungeecore.mods;
|
||||
|
||||
import com.google.gson.*;
|
||||
import de.steamwar.bungeecore.listeners.BasicListener;
|
||||
import net.md_5.bungee.BungeeCord;
|
||||
import net.md_5.bungee.api.ServerPing;
|
||||
import com.velocitypowered.api.proxy.ProxyServer;
|
||||
import com.velocitypowered.api.proxy.server.ServerPing;
|
||||
import de.steamwar.bungeecore.VelocityCore;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
public class ServerListPing extends BasicListener implements JsonSerializer<ServerPing>, JsonDeserializer<ServerPing> {
|
||||
public class ServerListPing {
|
||||
// https://github.com/Aizistral-Studios/No-Chat-Reports/discussions/206
|
||||
// https://github.com/Aizistral-Studios/No-Chat-Reports/wiki/How-to-Get-Safe-Server-Status
|
||||
|
||||
private final Gson gson;
|
||||
@SuppressWarnings("unused")
|
||||
private final ProxyServer proxyServer;
|
||||
|
||||
private static final String[] FIELDS_TO_OVERRIDE = new String[] {
|
||||
"PRE_1_16_PING_SERIALIZER",
|
||||
"PRE_1_20_3_PING_SERIALIZER",
|
||||
"MODERN_PING_SERIALIZER"
|
||||
};
|
||||
|
||||
public ServerListPing() {
|
||||
BungeeCord bungeeCord = BungeeCord.getInstance();
|
||||
gson = bungeeCord.gson;
|
||||
this.proxyServer = VelocityCore.getProxy();
|
||||
|
||||
try {
|
||||
Field gsonField = BungeeCord.class.getDeclaredField("gson");
|
||||
gsonField.setAccessible(true);
|
||||
gsonField.set(bungeeCord, gson.newBuilder().registerTypeAdapter(ServerPing.class, this).create());
|
||||
for (String fieldName : FIELDS_TO_OVERRIDE) {
|
||||
Field field = proxyServer.getClass().getDeclaredField(fieldName);
|
||||
field.setAccessible(true);
|
||||
Object obj = field.get(null);
|
||||
if (obj instanceof Gson gsonOld) {
|
||||
Gson gsonNew = new GsonBuilder()
|
||||
.registerTypeAdapter(ServerPing.class, new ServerListPingSerializer(gsonOld))
|
||||
.create();
|
||||
field.set(null, gsonNew);
|
||||
} else {
|
||||
throw new SecurityException("Failed to inject ServerListPing in " + fieldName);
|
||||
}
|
||||
}
|
||||
} catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
|
||||
throw new SecurityException("Failed to inject ServerListPing", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonElement serialize(ServerPing ping, Type type, JsonSerializationContext context) {
|
||||
JsonElement element = gson.toJsonTree(ping, type);
|
||||
private record ServerListPingSerializer(
|
||||
Gson gson) implements JsonSerializer<ServerPing>, JsonDeserializer<ServerPing> {
|
||||
|
||||
JsonObject object = element.getAsJsonObject();
|
||||
object.addProperty("preventsChatReports", true);
|
||||
@Override
|
||||
public JsonElement serialize(ServerPing ping, Type type, JsonSerializationContext context) {
|
||||
JsonElement element = gson.toJsonTree(ping, type);
|
||||
|
||||
return element;
|
||||
}
|
||||
JsonObject object = element.getAsJsonObject();
|
||||
object.addProperty("preventsChatReports", true);
|
||||
|
||||
@Override
|
||||
public ServerPing deserialize(JsonElement element, Type type, JsonDeserializationContext context) throws JsonParseException {
|
||||
return gson.fromJson(element, ServerPing.class);
|
||||
}
|
||||
return element;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServerPing deserialize(JsonElement element, Type type, JsonDeserializationContext context) throws JsonParseException {
|
||||
return gson.fromJson(element, ServerPing.class);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -21,13 +21,12 @@ package de.steamwar.bungeecore.network.handlers;
|
||||
|
||||
import com.velocitypowered.api.proxy.Player;
|
||||
import com.velocitypowered.api.proxy.server.RegisteredServer;
|
||||
import com.velocitypowered.api.proxy.server.ServerInfo;
|
||||
import de.steamwar.bungeecore.network.NetworkSender;
|
||||
import de.steamwar.bungeecore.network.ServerMetaInfo;
|
||||
import de.steamwar.bungeecore.tablist.TablistManager;
|
||||
import de.steamwar.network.packets.PacketHandler;
|
||||
import de.steamwar.network.packets.common.FightInfoPacket;
|
||||
import net.md_5.bungee.api.config.ServerInfo;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
@ -47,16 +46,16 @@ public class FightInfoHandler extends PacketHandler {
|
||||
|
||||
@Handler
|
||||
public void handle(FightInfoPacket packet) {
|
||||
ServerInfo info = ((ServerMetaInfo) packet.getMetaInfos()).getSender();
|
||||
RegisteredServer info = ((ServerMetaInfo) packet.getMetaInfos()).getSender().getServer();
|
||||
|
||||
FightInfoPacket lobbyPacket = packet.withServerName(info.getName());
|
||||
FightInfoPacket lobbyPacket = packet.withServerName(info.getServerInfo().getName());
|
||||
|
||||
TablistManager.newFightInfo(info, packet);
|
||||
|
||||
Iterator<ServerInfo> lobbyIt = lobbys.iterator();
|
||||
Iterator<RegisteredServer> lobbyIt = lobbys.iterator();
|
||||
while(lobbyIt.hasNext()) {
|
||||
ServerInfo lobby = lobbyIt.next();
|
||||
Iterator<ProxiedPlayer> it = lobby.getPlayers().iterator();
|
||||
RegisteredServer lobby = lobbyIt.next();
|
||||
Iterator<Player> it = lobby.getPlayersConnected().iterator();
|
||||
if(!it.hasNext()){
|
||||
lobbyIt.remove();
|
||||
continue;
|
||||
|
@ -19,40 +19,32 @@
|
||||
|
||||
package de.steamwar.bungeecore.tablist;
|
||||
|
||||
import com.velocitypowered.api.proxy.Player;
|
||||
import com.velocitypowered.api.proxy.server.RegisteredServer;
|
||||
import de.steamwar.bungeecore.VelocityCore;
|
||||
import de.steamwar.bungeecore.Servertype;
|
||||
import de.steamwar.bungeecore.Storage;
|
||||
import de.steamwar.bungeecore.Subserver;
|
||||
import de.steamwar.bungeecore.listeners.BasicListener;
|
||||
import de.steamwar.network.packets.common.FightInfoPacket;
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
import net.md_5.bungee.api.config.ServerInfo;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import net.md_5.bungee.api.event.PlayerDisconnectEvent;
|
||||
import net.md_5.bungee.api.event.PostLoginEvent;
|
||||
import net.md_5.bungee.api.event.ServerSwitchEvent;
|
||||
import net.md_5.bungee.event.EventHandler;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class TablistManager extends BasicListener {
|
||||
|
||||
private static final Map<ServerInfo, FightInfoPacket> fightInfos = new HashMap<>();
|
||||
private static final Map<RegisteredServer, FightInfoPacket> fightInfos = new HashMap<>();
|
||||
|
||||
public static synchronized void newFightInfo(ServerInfo info, FightInfoPacket packet) {
|
||||
public static synchronized void newFightInfo(RegisteredServer info, FightInfoPacket packet) {
|
||||
fightInfos.put(info, packet);
|
||||
fightInfos.keySet().removeIf(serverInfo -> serverInfo.getPlayers().isEmpty());
|
||||
fightInfos.keySet().removeIf(serverInfo -> serverInfo.getPlayersConnected().isEmpty());
|
||||
}
|
||||
|
||||
private final Map<ProxiedPlayer, Tablist> tablists = new HashMap<>();
|
||||
private final Map<Player, Tablist> tablists = new HashMap<>();
|
||||
|
||||
private int seconds = 0;
|
||||
|
||||
public TablistManager() {
|
||||
ProxyServer.getInstance().getScheduler().schedule(VelocityCore.get(), this::updateTablist, 1, 1, TimeUnit.SECONDS);
|
||||
VelocityCore.schedule(this::updateTablist).repeat(1, TimeUnit.SECONDS);
|
||||
synchronized (tablists) {
|
||||
ProxyServer.getInstance().getPlayers().forEach(player -> tablists.put(player, new Tablist(player)));
|
||||
VelocityCore.getProxy().getAllPlayers().forEach(player -> tablists.put(player, new Tablist(player)));
|
||||
}
|
||||
}
|
||||
|
||||
|
In neuem Issue referenzieren
Einen Benutzer sperren