mirror of
https://github.com/PaperMC/Paper.git
synced 2025-07-26 09:42:06 -07:00
Allow listening to plugin messages during configuration phase (#12775)
This commit is contained in:
@@ -1,9 +1,11 @@
|
|||||||
package org.bukkit.plugin.messaging;
|
package org.bukkit.plugin.messaging;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import io.papermc.paper.connection.PlayerConnection;
|
||||||
import org.bukkit.NamespacedKey;
|
import org.bukkit.NamespacedKey;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -230,4 +232,14 @@ public interface Messenger {
|
|||||||
* @param message Raw payload of the message.
|
* @param message Raw payload of the message.
|
||||||
*/
|
*/
|
||||||
public void dispatchIncomingMessage(@NotNull Player source, @NotNull String channel, byte @NotNull [] message);
|
public void dispatchIncomingMessage(@NotNull Player source, @NotNull String channel, byte @NotNull [] message);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dispatches the specified incoming message to any registered listeners.
|
||||||
|
*
|
||||||
|
* @param source Source of the message.
|
||||||
|
* @param channel Channel that the message was sent by.
|
||||||
|
* @param message Raw payload of the message.
|
||||||
|
*/
|
||||||
|
@ApiStatus.Experimental
|
||||||
|
public void dispatchIncomingMessage(@NotNull PlayerConnection source, @NotNull String channel, byte @NotNull [] message);
|
||||||
}
|
}
|
||||||
|
@@ -1,7 +1,9 @@
|
|||||||
package org.bukkit.plugin.messaging;
|
package org.bukkit.plugin.messaging;
|
||||||
|
|
||||||
import io.papermc.paper.connection.PlayerCommonConnection;
|
import io.papermc.paper.connection.PlayerCommonConnection;
|
||||||
|
import io.papermc.paper.connection.PlayerConnection;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -28,7 +30,8 @@ public interface PluginMessageListener {
|
|||||||
* @param connection Source of the message.
|
* @param connection Source of the message.
|
||||||
* @param message The raw message that was sent.
|
* @param message The raw message that was sent.
|
||||||
*/
|
*/
|
||||||
default void onPluginMessageReceived(@NotNull String channel, @NotNull PlayerCommonConnection connection, byte @NotNull [] message) {
|
@ApiStatus.Experimental
|
||||||
|
default void onPluginMessageReceived(@NotNull String channel, @NotNull PlayerConnection connection, byte @NotNull [] message) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -8,6 +8,7 @@ import java.util.Locale;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
import io.papermc.paper.connection.PlayerConnection;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@@ -462,6 +463,30 @@ public class StandardMessenger implements Messenger {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void dispatchIncomingMessage(@NotNull PlayerConnection source, @NotNull String channel, byte @NotNull [] message) {
|
||||||
|
if (source == null) {
|
||||||
|
throw new IllegalArgumentException("Player source cannot be null");
|
||||||
|
}
|
||||||
|
if (message == null) {
|
||||||
|
throw new IllegalArgumentException("Message cannot be null");
|
||||||
|
}
|
||||||
|
channel = validateAndCorrectChannel(channel);
|
||||||
|
|
||||||
|
Set<PluginMessageListenerRegistration> registrations = getIncomingChannelRegistrations(channel);
|
||||||
|
|
||||||
|
for (PluginMessageListenerRegistration registration : registrations) {
|
||||||
|
try {
|
||||||
|
registration.getListener().onPluginMessageReceived(channel, source, message);
|
||||||
|
} catch (Throwable t) {
|
||||||
|
registration.getPlugin().getLogger().log(Level.WARNING,
|
||||||
|
String.format("Plugin %s generated an exception whilst handling plugin message",
|
||||||
|
registration.getPlugin().getDescription().getFullName()
|
||||||
|
), t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates a Plugin Channel name.
|
* Validates a Plugin Channel name.
|
||||||
*
|
*
|
||||||
|
@@ -85,22 +85,22 @@ index 0000000000000000000000000000000000000000..4a2520f554c2ee74faf86d7c93baccf0
|
|||||||
+ }
|
+ }
|
||||||
+}
|
+}
|
||||||
diff --git a/net/minecraft/server/network/CommonListenerCookie.java b/net/minecraft/server/network/CommonListenerCookie.java
|
diff --git a/net/minecraft/server/network/CommonListenerCookie.java b/net/minecraft/server/network/CommonListenerCookie.java
|
||||||
index b94988d6dd98bfb7d3d2f08c2adaa96d7c7a8b55..7e61c8222d567feb8c2b988699e1cfe83bf4be31 100644
|
index 962084054c0208470d0c3c99c5dca6327c9b8752..2abc21102bbd2da79dc0c50826cff7da01a0f9bc 100644
|
||||||
--- a/net/minecraft/server/network/CommonListenerCookie.java
|
--- a/net/minecraft/server/network/CommonListenerCookie.java
|
||||||
+++ b/net/minecraft/server/network/CommonListenerCookie.java
|
+++ b/net/minecraft/server/network/CommonListenerCookie.java
|
||||||
@@ -3,8 +3,8 @@ package net.minecraft.server.network;
|
@@ -3,8 +3,8 @@ package net.minecraft.server.network;
|
||||||
import com.mojang.authlib.GameProfile;
|
import com.mojang.authlib.GameProfile;
|
||||||
import net.minecraft.server.level.ClientInformation;
|
import net.minecraft.server.level.ClientInformation;
|
||||||
|
|
||||||
-public record CommonListenerCookie(GameProfile gameProfile, int latency, ClientInformation clientInformation, boolean transferred, @org.jetbrains.annotations.Nullable String brandName) { // Paper
|
-public record CommonListenerCookie(GameProfile gameProfile, int latency, ClientInformation clientInformation, boolean transferred, @org.jetbrains.annotations.Nullable String brandName, java.util.Set<String> channels) { // Paper
|
||||||
+public record CommonListenerCookie(GameProfile gameProfile, int latency, ClientInformation clientInformation, boolean transferred, @org.jetbrains.annotations.Nullable String brandName, io.papermc.paper.util.KeepAlive keepAlive) { // Paper
|
+public record CommonListenerCookie(GameProfile gameProfile, int latency, ClientInformation clientInformation, boolean transferred, @org.jetbrains.annotations.Nullable String brandName, java.util.Set<String> channels, io.papermc.paper.util.KeepAlive keepAlive) { // Paper
|
||||||
public static CommonListenerCookie createInitial(GameProfile gameProfile, boolean transferred) {
|
public static CommonListenerCookie createInitial(GameProfile gameProfile, boolean transferred) {
|
||||||
- return new CommonListenerCookie(gameProfile, 0, ClientInformation.createDefault(), transferred, null); // Paper
|
- return new CommonListenerCookie(gameProfile, 0, ClientInformation.createDefault(), transferred, null, new java.util.HashSet<>()); // Paper
|
||||||
+ return new CommonListenerCookie(gameProfile, 0, ClientInformation.createDefault(), transferred, null, new io.papermc.paper.util.KeepAlive()); // Paper
|
+ return new CommonListenerCookie(gameProfile, 0, ClientInformation.createDefault(), transferred, null, new java.util.HashSet<>(), new io.papermc.paper.util.KeepAlive()); // Paper
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
diff --git a/net/minecraft/server/network/ServerCommonPacketListenerImpl.java b/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
diff --git a/net/minecraft/server/network/ServerCommonPacketListenerImpl.java b/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
||||||
index fae1523404b7afa2b904faad9242273b3c406aac..16962ccab91d0941e428a2e53aa37e9ca975f62f 100644
|
index ab2bcd5b547c8db418de7ea0b7f144058aa8b0f4..1ae3724eec5fac852c6cc6bb88b1ecb9f0b790f0 100644
|
||||||
--- a/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
--- a/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
||||||
+++ b/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
+++ b/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
||||||
@@ -38,12 +38,13 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
|
@@ -38,12 +38,13 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
|
||||||
@@ -121,7 +121,7 @@ index fae1523404b7afa2b904faad9242273b3c406aac..16962ccab91d0941e428a2e53aa37e9c
|
|||||||
private volatile boolean suspendFlushingOnServerThread = false;
|
private volatile boolean suspendFlushingOnServerThread = false;
|
||||||
// CraftBukkit start
|
// CraftBukkit start
|
||||||
protected final org.bukkit.craftbukkit.CraftServer cserver;
|
protected final org.bukkit.craftbukkit.CraftServer cserver;
|
||||||
@@ -57,12 +58,13 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
|
@@ -60,13 +61,14 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
|
||||||
public ServerCommonPacketListenerImpl(MinecraftServer server, Connection connection, CommonListenerCookie cookie) {
|
public ServerCommonPacketListenerImpl(MinecraftServer server, Connection connection, CommonListenerCookie cookie) {
|
||||||
this.server = server;
|
this.server = server;
|
||||||
this.connection = connection;
|
this.connection = connection;
|
||||||
@@ -132,11 +132,12 @@ index fae1523404b7afa2b904faad9242273b3c406aac..16962ccab91d0941e428a2e53aa37e9c
|
|||||||
// Paper start
|
// Paper start
|
||||||
this.playerBrand = cookie.brandName();
|
this.playerBrand = cookie.brandName();
|
||||||
this.cserver = server.server;
|
this.cserver = server.server;
|
||||||
|
this.pluginMessagerChannels = cookie.channels();
|
||||||
+ this.keepAlive = cookie.keepAlive();
|
+ this.keepAlive = cookie.keepAlive();
|
||||||
// Paper end
|
// Paper end
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,13 +91,41 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
|
@@ -93,13 +95,41 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleKeepAlive(ServerboundKeepAlivePacket packet) {
|
public void handleKeepAlive(ServerboundKeepAlivePacket packet) {
|
||||||
@@ -184,7 +185,7 @@ index fae1523404b7afa2b904faad9242273b3c406aac..16962ccab91d0941e428a2e53aa37e9c
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -148,20 +178,23 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
|
@@ -225,20 +255,23 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
|
||||||
protected void keepConnectionAlive() {
|
protected void keepConnectionAlive() {
|
||||||
Profiler.get().push("keepAlive");
|
Profiler.get().push("keepAlive");
|
||||||
long millis = Util.getMillis();
|
long millis = Util.getMillis();
|
||||||
@@ -222,13 +223,11 @@ index fae1523404b7afa2b904faad9242273b3c406aac..16962ccab91d0941e428a2e53aa37e9c
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -341,6 +374,6 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
|
@@ -418,6 +451,6 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
|
||||||
}
|
}
|
||||||
|
|
||||||
protected CommonListenerCookie createCookie(ClientInformation clientInformation) {
|
protected CommonListenerCookie createCookie(ClientInformation clientInformation) {
|
||||||
- return new CommonListenerCookie(this.playerProfile(), this.latency, clientInformation, this.transferred, this.playerBrand); // Paper
|
- return new CommonListenerCookie(this.playerProfile(), this.latency, clientInformation, this.transferred, this.playerBrand, this.pluginMessagerChannels); // Paper
|
||||||
+ return new CommonListenerCookie(this.playerProfile(), this.latency, clientInformation, this.transferred, this.playerBrand, this.keepAlive); // Paper
|
+ return new CommonListenerCookie(this.playerProfile(), this.latency, clientInformation, this.transferred, this.playerBrand, this.pluginMessagerChannels, this.keepAlive); // Paper
|
||||||
}
|
}
|
||||||
-}
|
}
|
||||||
+}
|
|
||||||
\ No newline at end of file
|
|
||||||
|
@@ -5,9 +5,9 @@
|
|||||||
import net.minecraft.server.level.ClientInformation;
|
import net.minecraft.server.level.ClientInformation;
|
||||||
|
|
||||||
-public record CommonListenerCookie(GameProfile gameProfile, int latency, ClientInformation clientInformation, boolean transferred) {
|
-public record CommonListenerCookie(GameProfile gameProfile, int latency, ClientInformation clientInformation, boolean transferred) {
|
||||||
+public record CommonListenerCookie(GameProfile gameProfile, int latency, ClientInformation clientInformation, boolean transferred, @org.jetbrains.annotations.Nullable String brandName) { // Paper
|
+public record CommonListenerCookie(GameProfile gameProfile, int latency, ClientInformation clientInformation, boolean transferred, @org.jetbrains.annotations.Nullable String brandName, java.util.Set<String> channels) { // Paper
|
||||||
public static CommonListenerCookie createInitial(GameProfile gameProfile, boolean transferred) {
|
public static CommonListenerCookie createInitial(GameProfile gameProfile, boolean transferred) {
|
||||||
- return new CommonListenerCookie(gameProfile, 0, ClientInformation.createDefault(), transferred);
|
- return new CommonListenerCookie(gameProfile, 0, ClientInformation.createDefault(), transferred);
|
||||||
+ return new CommonListenerCookie(gameProfile, 0, ClientInformation.createDefault(), transferred, null); // Paper
|
+ return new CommonListenerCookie(gameProfile, 0, ClientInformation.createDefault(), transferred, null, new java.util.HashSet<>()); // Paper
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -9,7 +9,7 @@
|
|||||||
private final boolean transferred;
|
private final boolean transferred;
|
||||||
private long keepAliveTime;
|
private long keepAliveTime;
|
||||||
private boolean keepAlivePending;
|
private boolean keepAlivePending;
|
||||||
@@ -45,6 +_,14 @@
|
@@ -45,6 +_,17 @@
|
||||||
private boolean closed = false;
|
private boolean closed = false;
|
||||||
private int latency;
|
private int latency;
|
||||||
private volatile boolean suspendFlushingOnServerThread = false;
|
private volatile boolean suspendFlushingOnServerThread = false;
|
||||||
@@ -20,17 +20,21 @@
|
|||||||
+ public final java.util.Map<java.util.UUID, net.kyori.adventure.resource.ResourcePackCallback> packCallbacks = new java.util.concurrent.ConcurrentHashMap<>(); // Paper - adventure resource pack callbacks
|
+ public final java.util.Map<java.util.UUID, net.kyori.adventure.resource.ResourcePackCallback> packCallbacks = new java.util.concurrent.ConcurrentHashMap<>(); // Paper - adventure resource pack callbacks
|
||||||
+ private static final long KEEPALIVE_LIMIT = Long.getLong("paper.playerconnection.keepalive", 30) * 1000; // Paper - provide property to set keepalive limit
|
+ private static final long KEEPALIVE_LIMIT = Long.getLong("paper.playerconnection.keepalive", 30) * 1000; // Paper - provide property to set keepalive limit
|
||||||
+ protected static final net.minecraft.resources.ResourceLocation MINECRAFT_BRAND = net.minecraft.resources.ResourceLocation.withDefaultNamespace("brand"); // Paper - Brand support
|
+ protected static final net.minecraft.resources.ResourceLocation MINECRAFT_BRAND = net.minecraft.resources.ResourceLocation.withDefaultNamespace("brand"); // Paper - Brand support
|
||||||
+ public @Nullable String playerBrand; // Paper
|
+ // Paper start - retain certain values
|
||||||
|
+ public @Nullable String playerBrand;
|
||||||
|
+ public final java.util.Set<String> pluginMessagerChannels;
|
||||||
|
+ // Paper end - retain certain values
|
||||||
|
|
||||||
public ServerCommonPacketListenerImpl(MinecraftServer server, Connection connection, CommonListenerCookie cookie) {
|
public ServerCommonPacketListenerImpl(MinecraftServer server, Connection connection, CommonListenerCookie cookie) {
|
||||||
this.server = server;
|
this.server = server;
|
||||||
@@ -52,6 +_,10 @@
|
@@ -52,6 +_,11 @@
|
||||||
this.keepAliveTime = Util.getMillis();
|
this.keepAliveTime = Util.getMillis();
|
||||||
this.latency = cookie.latency();
|
this.latency = cookie.latency();
|
||||||
this.transferred = cookie.transferred();
|
this.transferred = cookie.transferred();
|
||||||
+ // Paper start
|
+ // Paper start
|
||||||
+ this.playerBrand = cookie.brandName();
|
+ this.playerBrand = cookie.brandName();
|
||||||
+ this.cserver = server.server;
|
+ this.cserver = server.server;
|
||||||
|
+ this.pluginMessagerChannels = cookie.channels();
|
||||||
+ // Paper end
|
+ // Paper end
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,6 +48,88 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -90,8 +_,81 @@
|
||||||
|
public void handlePong(ServerboundPongPacket packet) {
|
||||||
|
}
|
||||||
|
|
||||||
|
+ // Paper start
|
||||||
|
+ public static final net.minecraft.resources.ResourceLocation CUSTOM_REGISTER = net.minecraft.resources.ResourceLocation.withDefaultNamespace("register");
|
||||||
|
+ private static final net.minecraft.resources.ResourceLocation CUSTOM_UNREGISTER = net.minecraft.resources.ResourceLocation.withDefaultNamespace("unregister");
|
||||||
|
+ // Paper end
|
||||||
|
+
|
||||||
|
@Override
|
||||||
|
public void handleCustomPayload(ServerboundCustomPayloadPacket packet) {
|
||||||
|
+ // Paper start
|
||||||
|
+ if (!(packet.payload() instanceof final net.minecraft.network.protocol.common.custom.DiscardedPayload discardedPayload)) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ net.minecraft.network.protocol.PacketUtils.ensureRunningOnSameThread(packet, this, this.server);
|
||||||
|
+
|
||||||
|
+ final net.minecraft.resources.ResourceLocation identifier = packet.payload().type().id();
|
||||||
|
+ final byte[] data = discardedPayload.data();
|
||||||
|
+ try {
|
||||||
|
+ final boolean registerChannel = CUSTOM_REGISTER.equals(identifier);
|
||||||
|
+ if (registerChannel || CUSTOM_UNREGISTER.equals(identifier)) {
|
||||||
|
+ // Strings separated by zeros instead of length prefixes
|
||||||
|
+ int startIndex = 0;
|
||||||
|
+ for (int i = 0; i < data.length; i++) {
|
||||||
|
+ final byte b = data[i];
|
||||||
|
+ if (b != 0) {
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ readChannelIdentifier(data, startIndex, i, registerChannel);
|
||||||
|
+ startIndex = i + 1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ // Read the last one
|
||||||
|
+ readChannelIdentifier(data, startIndex, data.length, registerChannel);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (identifier.equals(MINECRAFT_BRAND)) {
|
||||||
|
+ this.playerBrand = new net.minecraft.network.FriendlyByteBuf(io.netty.buffer.Unpooled.wrappedBuffer(data)).readUtf(256);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+ if (this instanceof ServerGamePacketListenerImpl gamePacketListener) {
|
||||||
|
+ this.cserver.getMessenger().dispatchIncomingMessage(gamePacketListener.player.getBukkitEntity(), identifier.toString(), data);
|
||||||
|
+ } else if (this instanceof ServerConfigurationPacketListenerImpl configurationPacketListener) {
|
||||||
|
+ this.cserver.getMessenger().dispatchIncomingMessage(configurationPacketListener.paperConnection, identifier.toString(), data);
|
||||||
|
+ }
|
||||||
|
+ } catch (final Exception e) {
|
||||||
|
+ ServerGamePacketListenerImpl.LOGGER.error("Couldn't handle custom payload on channel {}", identifier, e);
|
||||||
|
+ this.disconnect(net.minecraft.network.chat.Component.literal("Invalid custom payload payload!"), io.papermc.paper.connection.DisconnectionReason.INVALID_PAYLOAD); // Paper - kick event cause
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ private void readChannelIdentifier(final byte[] data, final int from, final int to, final boolean register) {
|
||||||
|
+ io.papermc.paper.connection.PluginMessageBridgeImpl bridge = switch (this) {
|
||||||
|
+ case ServerGamePacketListenerImpl gamePacketListener -> gamePacketListener.player.getBukkitEntity();
|
||||||
|
+ case ServerConfigurationPacketListenerImpl commonPacketListener -> commonPacketListener.paperConnection;
|
||||||
|
+ default -> null;
|
||||||
|
+ };
|
||||||
|
+ if (bridge == null) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+ final int length = to - from;
|
||||||
|
+ if (length == 0) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ final String channel = new String(data, from, length, java.nio.charset.StandardCharsets.US_ASCII);
|
||||||
|
+ if (register) {
|
||||||
|
+ bridge.addChannel(channel);
|
||||||
|
+ } else {
|
||||||
|
+ bridge.removeChannel(channel);
|
||||||
|
+ }
|
||||||
|
+ // Paper end
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
@@ -105,21 +_,46 @@
|
@@ -105,21 +_,46 @@
|
||||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.server);
|
PacketUtils.ensureRunningOnSameThread(packet, this, this.server);
|
||||||
if (packet.action() == ServerboundResourcePackPacket.Action.DECLINED && this.server.isResourcePackRequired()) {
|
if (packet.action() == ServerboundResourcePackPacket.Action.DECLINED && this.server.isResourcePackRequired()) {
|
||||||
@@ -245,6 +331,6 @@
|
|||||||
|
|
||||||
protected CommonListenerCookie createCookie(ClientInformation clientInformation) {
|
protected CommonListenerCookie createCookie(ClientInformation clientInformation) {
|
||||||
- return new CommonListenerCookie(this.playerProfile(), this.latency, clientInformation, this.transferred);
|
- return new CommonListenerCookie(this.playerProfile(), this.latency, clientInformation, this.transferred);
|
||||||
+ return new CommonListenerCookie(this.playerProfile(), this.latency, clientInformation, this.transferred, this.playerBrand); // Paper
|
+ return new CommonListenerCookie(this.playerProfile(), this.latency, clientInformation, this.transferred, this.playerBrand, this.pluginMessagerChannels); // Paper
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -99,7 +99,7 @@
|
|||||||
this.connection.send(new ClientboundDisconnectPacket(DISCONNECT_REASON_INVALID_DATA));
|
this.connection.send(new ClientboundDisconnectPacket(DISCONNECT_REASON_INVALID_DATA));
|
||||||
this.connection.disconnect(DISCONNECT_REASON_INVALID_DATA);
|
this.connection.disconnect(DISCONNECT_REASON_INVALID_DATA);
|
||||||
}
|
}
|
||||||
@@ -180,4 +_,31 @@
|
@@ -180,4 +_,29 @@
|
||||||
this.startNextTask();
|
this.startNextTask();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -125,9 +125,7 @@
|
|||||||
+
|
+
|
||||||
+ @Override
|
+ @Override
|
||||||
+ public void handleCustomPayload(net.minecraft.network.protocol.common.ServerboundCustomPayloadPacket packet) {
|
+ public void handleCustomPayload(net.minecraft.network.protocol.common.ServerboundCustomPayloadPacket packet) {
|
||||||
+ if (packet.payload() instanceof net.minecraft.network.protocol.common.custom.BrandPayload(String brand)) {
|
+ super.handleCustomPayload(packet);
|
||||||
+ this.playerBrand = brand;
|
|
||||||
+ }
|
|
||||||
+ }
|
+ }
|
||||||
+ // Paper end
|
+ // Paper end
|
||||||
}
|
}
|
||||||
|
@@ -2576,7 +2576,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2027,27 +_,27 @@
|
@@ -2027,27 +_,32 @@
|
||||||
|
|
||||||
private void resetPlayerChatState(RemoteChatSession chatSession) {
|
private void resetPlayerChatState(RemoteChatSession chatSession) {
|
||||||
this.chatSession = chatSession;
|
this.chatSession = chatSession;
|
||||||
@@ -2596,10 +2596,11 @@
|
|||||||
+ });
|
+ });
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
- }
|
}
|
||||||
-
|
|
||||||
- @Override
|
@Override
|
||||||
- public void handleCustomPayload(ServerboundCustomPayloadPacket packet) {
|
public void handleCustomPayload(ServerboundCustomPayloadPacket packet) {
|
||||||
|
+ super.handleCustomPayload(packet); // Paper
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -2609,7 +2610,7 @@
|
|||||||
if (!this.receivedMovementThisTick) {
|
if (!this.receivedMovementThisTick) {
|
||||||
this.player.setKnownMovement(Vec3.ZERO);
|
this.player.setKnownMovement(Vec3.ZERO);
|
||||||
}
|
}
|
||||||
@@ -2078,4 +_,157 @@
|
@@ -2078,4 +_,93 @@
|
||||||
interface EntityInteraction {
|
interface EntityInteraction {
|
||||||
InteractionResult run(ServerPlayer player, Entity entity, InteractionHand hand);
|
InteractionResult run(ServerPlayer player, Entity entity, InteractionHand hand);
|
||||||
}
|
}
|
||||||
@@ -2661,70 +2662,6 @@
|
|||||||
+ });
|
+ });
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ // Paper start
|
|
||||||
+ public static final ResourceLocation CUSTOM_REGISTER = ResourceLocation.withDefaultNamespace("register"); // CraftBukkit
|
|
||||||
+ private static final ResourceLocation CUSTOM_UNREGISTER = ResourceLocation.withDefaultNamespace("unregister"); // CraftBukkit
|
|
||||||
+
|
|
||||||
+ @Override
|
|
||||||
+ public void handleCustomPayload(ServerboundCustomPayloadPacket packet) {
|
|
||||||
+ // Paper start
|
|
||||||
+ if (packet.payload() instanceof net.minecraft.network.protocol.common.custom.BrandPayload(String brand)) {
|
|
||||||
+ this.playerBrand = brand;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (!(packet.payload() instanceof final net.minecraft.network.protocol.common.custom.DiscardedPayload discardedPayload)) {
|
|
||||||
+ return;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level());
|
|
||||||
+
|
|
||||||
+ final net.minecraft.resources.ResourceLocation identifier = packet.payload().type().id();
|
|
||||||
+ final byte[] data = discardedPayload.data();
|
|
||||||
+ try {
|
|
||||||
+ final boolean registerChannel = CUSTOM_REGISTER.equals(identifier);
|
|
||||||
+ if (registerChannel || CUSTOM_UNREGISTER.equals(identifier)) {
|
|
||||||
+ // Strings separated by zeros instead of length prefixes
|
|
||||||
+ int startIndex = 0;
|
|
||||||
+ for (int i = 0; i < data.length; i++) {
|
|
||||||
+ final byte b = data[i];
|
|
||||||
+ if (b != 0) {
|
|
||||||
+ continue;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ readChannelIdentifier(data, startIndex, i, registerChannel);
|
|
||||||
+ startIndex = i + 1;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ // Read the last one
|
|
||||||
+ readChannelIdentifier(data, startIndex, data.length, registerChannel);
|
|
||||||
+ return;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (identifier.equals(MINECRAFT_BRAND)) {
|
|
||||||
+ this.player.connection.playerBrand = new net.minecraft.network.FriendlyByteBuf(io.netty.buffer.Unpooled.wrappedBuffer(data)).readUtf(256);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ this.cserver.getMessenger().dispatchIncomingMessage(this.player.getBukkitEntity(), identifier.toString(), data);
|
|
||||||
+ } catch (final Exception e) {
|
|
||||||
+ ServerGamePacketListenerImpl.LOGGER.error("Couldn't handle custom payload on channel {}", identifier, e);
|
|
||||||
+ this.disconnect(Component.literal("Invalid custom payload payload!"), org.bukkit.event.player.PlayerKickEvent.Cause.INVALID_PAYLOAD); // Paper - kick event cause
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ private void readChannelIdentifier(final byte[] data, final int from, final int to, final boolean register) {
|
|
||||||
+ final int length = to - from;
|
|
||||||
+ if (length == 0) {
|
|
||||||
+ return;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ final String channel = new String(data, from, length, java.nio.charset.StandardCharsets.US_ASCII);
|
|
||||||
+ if (register) {
|
|
||||||
+ this.getCraftPlayer().addChannel(channel);
|
|
||||||
+ } else {
|
|
||||||
+ this.getCraftPlayer().removeChannel(channel);
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ public final boolean isDisconnected() {
|
+ public final boolean isDisconnected() {
|
||||||
+ return (!this.player.joining && !this.connection.isConnected()) || this.processedDisconnect; // Paper - Fix duplication bugs
|
+ return (!this.player.joining && !this.connection.isConnected()) || this.processedDisconnect; // Paper - Fix duplication bugs
|
||||||
+ }
|
+ }
|
||||||
|
@@ -11,6 +11,7 @@ public interface DisconnectionReason {
|
|||||||
DisconnectionReason RESOURCE_PACK_REJECTION = game(PlayerKickEvent.Cause.RESOURCE_PACK_REJECTION);
|
DisconnectionReason RESOURCE_PACK_REJECTION = game(PlayerKickEvent.Cause.RESOURCE_PACK_REJECTION);
|
||||||
DisconnectionReason INVALID_COOKIE = game(PlayerKickEvent.Cause.INVALID_COOKIE);
|
DisconnectionReason INVALID_COOKIE = game(PlayerKickEvent.Cause.INVALID_COOKIE);
|
||||||
DisconnectionReason DUPLICATE_LOGIN_MESSAGE = game(PlayerKickEvent.Cause.DUPLICATE_LOGIN);
|
DisconnectionReason DUPLICATE_LOGIN_MESSAGE = game(PlayerKickEvent.Cause.DUPLICATE_LOGIN);
|
||||||
|
DisconnectionReason INVALID_PAYLOAD = game(PlayerKickEvent.Cause.INVALID_PAYLOAD);
|
||||||
|
|
||||||
Optional<PlayerKickEvent.Cause> game();
|
Optional<PlayerKickEvent.Cause> game();
|
||||||
|
|
||||||
|
@@ -1,7 +1,5 @@
|
|||||||
package io.papermc.paper.connection;
|
package io.papermc.paper.connection;
|
||||||
|
|
||||||
import com.destroystokyo.paper.ClientOption;
|
|
||||||
import com.destroystokyo.paper.PaperSkinParts;
|
|
||||||
import com.destroystokyo.paper.profile.CraftPlayerProfile;
|
import com.destroystokyo.paper.profile.CraftPlayerProfile;
|
||||||
import com.destroystokyo.paper.profile.PlayerProfile;
|
import com.destroystokyo.paper.profile.PlayerProfile;
|
||||||
import io.papermc.paper.adventure.PaperAdventure;
|
import io.papermc.paper.adventure.PaperAdventure;
|
||||||
@@ -19,11 +17,13 @@ import net.minecraft.server.network.ConfigurationTask;
|
|||||||
import net.minecraft.server.network.ServerConfigurationPacketListenerImpl;
|
import net.minecraft.server.network.ServerConfigurationPacketListenerImpl;
|
||||||
import org.jspecify.annotations.Nullable;
|
import org.jspecify.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public class PaperPlayerConfigurationConnection extends PaperCommonConnection<ServerConfigurationPacketListenerImpl> implements PlayerConfigurationConnection, Audience {
|
public class PaperPlayerConfigurationConnection extends PaperCommonConnection<ServerConfigurationPacketListenerImpl> implements PlayerConfigurationConnection, Audience, PluginMessageBridgeImpl {
|
||||||
|
|
||||||
private @Nullable Pointers adventurePointers;
|
private @Nullable Pointers adventurePointers;
|
||||||
|
|
||||||
@@ -101,4 +101,9 @@ public class PaperPlayerConfigurationConnection extends PaperCommonConnection<Se
|
|||||||
|
|
||||||
this.handle.returnToWorld();
|
this.handle.returnToWorld();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<String> channels() {
|
||||||
|
return this.handle.pluginMessagerChannels;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,43 @@
|
|||||||
|
package io.papermc.paper.connection;
|
||||||
|
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.craftbukkit.entity.CraftPlayer;
|
||||||
|
import org.bukkit.event.player.PlayerRegisterChannelEvent;
|
||||||
|
import org.bukkit.event.player.PlayerUnregisterChannelEvent;
|
||||||
|
import org.bukkit.plugin.messaging.StandardMessenger;
|
||||||
|
import org.jspecify.annotations.NullMarked;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
@NullMarked
|
||||||
|
public interface PluginMessageBridgeImpl {
|
||||||
|
|
||||||
|
boolean DISABLE_CHANNEL_LIMIT = System.getProperty("paper.disableChannelLimit") != null; // Paper - add a flag to disable the channel limit
|
||||||
|
|
||||||
|
default boolean addChannel(String channel) {
|
||||||
|
Preconditions.checkState(DISABLE_CHANNEL_LIMIT || this.channels().size() < 128, "Cannot register channel. Too many channels registered!"); // Paper - flag to disable channel limit
|
||||||
|
channel = StandardMessenger.validateAndCorrectChannel(channel);
|
||||||
|
if (channels().add(channel)) {
|
||||||
|
if (this instanceof CraftPlayer player) {
|
||||||
|
Bukkit.getPluginManager().callEvent(new PlayerRegisterChannelEvent(player, channel));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean removeChannel(String channel) {
|
||||||
|
channel = StandardMessenger.validateAndCorrectChannel(channel);
|
||||||
|
if (channels().remove(channel)) {
|
||||||
|
if (this instanceof CraftPlayer player) {
|
||||||
|
Bukkit.getPluginManager().callEvent(new PlayerUnregisterChannelEvent(player, channel));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
Set<String> channels();
|
||||||
|
}
|
@@ -8,8 +8,8 @@ import com.google.common.io.BaseEncoding;
|
|||||||
import com.mojang.authlib.GameProfile;
|
import com.mojang.authlib.GameProfile;
|
||||||
import com.mojang.datafixers.util.Pair;
|
import com.mojang.datafixers.util.Pair;
|
||||||
import io.papermc.paper.FeatureHooks;
|
import io.papermc.paper.FeatureHooks;
|
||||||
import io.papermc.paper.configuration.GlobalConfiguration;
|
|
||||||
import io.papermc.paper.connection.PlayerGameConnection;
|
import io.papermc.paper.connection.PlayerGameConnection;
|
||||||
|
import io.papermc.paper.connection.PluginMessageBridgeImpl;
|
||||||
import io.papermc.paper.entity.LookAnchor;
|
import io.papermc.paper.entity.LookAnchor;
|
||||||
import io.papermc.paper.entity.PaperPlayerGiveResult;
|
import io.papermc.paper.entity.PaperPlayerGiveResult;
|
||||||
import io.papermc.paper.entity.PlayerGiveResult;
|
import io.papermc.paper.entity.PlayerGiveResult;
|
||||||
@@ -33,11 +33,9 @@ import java.util.HashMap;
|
|||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Queue;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.WeakHashMap;
|
import java.util.WeakHashMap;
|
||||||
@@ -54,20 +52,13 @@ import net.minecraft.commands.Commands;
|
|||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.Holder;
|
import net.minecraft.core.Holder;
|
||||||
import net.minecraft.core.SectionPos;
|
import net.minecraft.core.SectionPos;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
|
||||||
import net.minecraft.network.ConnectionProtocol;
|
|
||||||
import net.minecraft.network.chat.Component;
|
import net.minecraft.network.chat.Component;
|
||||||
import net.minecraft.network.chat.PlayerChatMessage;
|
import net.minecraft.network.chat.PlayerChatMessage;
|
||||||
import net.minecraft.network.protocol.Packet;
|
|
||||||
import net.minecraft.network.protocol.common.ClientboundCustomPayloadPacket;
|
import net.minecraft.network.protocol.common.ClientboundCustomPayloadPacket;
|
||||||
import net.minecraft.network.protocol.common.ClientboundResourcePackPopPacket;
|
import net.minecraft.network.protocol.common.ClientboundResourcePackPopPacket;
|
||||||
import net.minecraft.network.protocol.common.ClientboundResourcePackPushPacket;
|
import net.minecraft.network.protocol.common.ClientboundResourcePackPushPacket;
|
||||||
import net.minecraft.network.protocol.common.ClientboundServerLinksPacket;
|
import net.minecraft.network.protocol.common.ClientboundServerLinksPacket;
|
||||||
import net.minecraft.network.protocol.common.ClientboundStoreCookiePacket;
|
|
||||||
import net.minecraft.network.protocol.common.ClientboundTransferPacket;
|
|
||||||
import net.minecraft.network.protocol.common.custom.DiscardedPayload;
|
import net.minecraft.network.protocol.common.custom.DiscardedPayload;
|
||||||
import net.minecraft.network.protocol.cookie.ClientboundCookieRequestPacket;
|
|
||||||
import net.minecraft.network.protocol.cookie.ServerboundCookieResponsePacket;
|
|
||||||
import net.minecraft.network.protocol.game.ClientboundBlockDestructionPacket;
|
import net.minecraft.network.protocol.game.ClientboundBlockDestructionPacket;
|
||||||
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
|
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
|
||||||
import net.minecraft.network.protocol.game.ClientboundBlockUpdatePacket;
|
import net.minecraft.network.protocol.game.ClientboundBlockUpdatePacket;
|
||||||
@@ -196,10 +187,8 @@ import org.bukkit.entity.LivingEntity;
|
|||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.player.PlayerExpCooldownChangeEvent;
|
import org.bukkit.event.player.PlayerExpCooldownChangeEvent;
|
||||||
import org.bukkit.event.player.PlayerHideEntityEvent;
|
import org.bukkit.event.player.PlayerHideEntityEvent;
|
||||||
import org.bukkit.event.player.PlayerRegisterChannelEvent;
|
|
||||||
import org.bukkit.event.player.PlayerShowEntityEvent;
|
import org.bukkit.event.player.PlayerShowEntityEvent;
|
||||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||||
import org.bukkit.event.player.PlayerUnregisterChannelEvent;
|
|
||||||
import org.bukkit.inventory.EquipmentSlot;
|
import org.bukkit.inventory.EquipmentSlot;
|
||||||
import org.bukkit.inventory.InventoryView.Property;
|
import org.bukkit.inventory.InventoryView.Property;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
@@ -215,7 +204,7 @@ import org.jspecify.annotations.NonNull;
|
|||||||
import org.jspecify.annotations.Nullable;
|
import org.jspecify.annotations.Nullable;
|
||||||
|
|
||||||
@DelegateDeserialization(CraftOfflinePlayer.class)
|
@DelegateDeserialization(CraftOfflinePlayer.class)
|
||||||
public class CraftPlayer extends CraftHumanEntity implements Player {
|
public class CraftPlayer extends CraftHumanEntity implements Player, PluginMessageBridgeImpl {
|
||||||
private static final PointersSupplier<Player> POINTERS_SUPPLIER = PointersSupplier.<Player>builder()
|
private static final PointersSupplier<Player> POINTERS_SUPPLIER = PointersSupplier.<Player>builder()
|
||||||
.parent(CraftEntity.POINTERS_SUPPLIER)
|
.parent(CraftEntity.POINTERS_SUPPLIER)
|
||||||
.resolving(Identity.NAME, Player::getName)
|
.resolving(Identity.NAME, Player::getName)
|
||||||
@@ -227,7 +216,6 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
|||||||
private long lastPlayed = 0;
|
private long lastPlayed = 0;
|
||||||
private boolean hasPlayedBefore = false;
|
private boolean hasPlayedBefore = false;
|
||||||
private final ConversationTracker conversationTracker = new ConversationTracker();
|
private final ConversationTracker conversationTracker = new ConversationTracker();
|
||||||
private final Set<String> channels = new HashSet<String>();
|
|
||||||
private final Map<UUID, Set<WeakReference<Plugin>>> invertedVisibilityEntities = new HashMap<>();
|
private final Map<UUID, Set<WeakReference<Plugin>>> invertedVisibilityEntities = new HashMap<>();
|
||||||
private final Set<UUID> unlistedEntities = new HashSet<>(); // Paper - Add Listing API for Player
|
private final Set<UUID> unlistedEntities = new HashSet<>(); // Paper - Add Listing API for Player
|
||||||
private static final WeakHashMap<Plugin, WeakReference<Plugin>> pluginWeakReferences = new WeakHashMap<>();
|
private static final WeakHashMap<Plugin, WeakReference<Plugin>> pluginWeakReferences = new WeakHashMap<>();
|
||||||
@@ -238,7 +226,6 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
|||||||
private CraftWorldBorder clientWorldBorder = null;
|
private CraftWorldBorder clientWorldBorder = null;
|
||||||
private BorderChangeListener clientWorldBorderListener = this.createWorldBorderListener();
|
private BorderChangeListener clientWorldBorderListener = this.createWorldBorderListener();
|
||||||
public org.bukkit.event.player.PlayerResourcePackStatusEvent.Status resourcePackStatus; // Paper - more resource pack API
|
public org.bukkit.event.player.PlayerResourcePackStatusEvent.Status resourcePackStatus; // Paper - more resource pack API
|
||||||
private static final boolean DISABLE_CHANNEL_LIMIT = System.getProperty("paper.disableChannelLimit") != null; // Paper - add a flag to disable the channel limit
|
|
||||||
private long lastSaveTime; // Paper - getLastPlayed replacement API
|
private long lastSaveTime; // Paper - getLastPlayed replacement API
|
||||||
|
|
||||||
public CraftPlayer(CraftServer server, ServerPlayer entity) {
|
public CraftPlayer(CraftServer server, ServerPlayer entity) {
|
||||||
@@ -2378,7 +2365,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
|||||||
StandardMessenger.validatePluginMessage(this.server.getMessenger(), source, channel, message);
|
StandardMessenger.validatePluginMessage(this.server.getMessenger(), source, channel, message);
|
||||||
if (this.getHandle().connection == null) return;
|
if (this.getHandle().connection == null) return;
|
||||||
|
|
||||||
if (this.channels.contains(channel)) {
|
if (this.channels().contains(channel)) {
|
||||||
ResourceLocation id = ResourceLocation.parse(StandardMessenger.validateAndCorrectChannel(channel));
|
ResourceLocation id = ResourceLocation.parse(StandardMessenger.validateAndCorrectChannel(channel));
|
||||||
this.sendCustomPayload(id, message);
|
this.sendCustomPayload(id, message);
|
||||||
}
|
}
|
||||||
@@ -2530,24 +2517,16 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
|||||||
this.getHandle().connection.send(resourcePackPushPacket);
|
this.getHandle().connection.send(resourcePackPushPacket);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addChannel(String channel) {
|
@Override
|
||||||
Preconditions.checkState(DISABLE_CHANNEL_LIMIT || this.channels.size() < 128, "Cannot register channel. Too many channels registered!"); // Paper - flag to disable channel limit
|
public Set<String> channels() {
|
||||||
channel = StandardMessenger.validateAndCorrectChannel(channel);
|
if (this.getHandle().connection == null) return new HashSet<>();
|
||||||
if (this.channels.add(channel)) {
|
|
||||||
this.server.getPluginManager().callEvent(new PlayerRegisterChannelEvent(this, channel));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeChannel(String channel) {
|
return this.getHandle().connection.pluginMessagerChannels;
|
||||||
channel = StandardMessenger.validateAndCorrectChannel(channel);
|
|
||||||
if (this.channels.remove(channel)) {
|
|
||||||
this.server.getPluginManager().callEvent(new PlayerUnregisterChannelEvent(this, channel));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<String> getListeningPluginChannels() {
|
public Set<String> getListeningPluginChannels() {
|
||||||
return ImmutableSet.copyOf(this.channels);
|
return ImmutableSet.copyOf(this.channels());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendSupportedChannels() {
|
public void sendSupportedChannels() {
|
||||||
|
Reference in New Issue
Block a user