From dbb9dc90725b58757305d2faa94b9472062981a7 Mon Sep 17 00:00:00 2001 From: DeJayDev Date: Sun, 2 Oct 2022 17:29:44 -0500 Subject: [PATCH 1/7] Sending Plugin Messages --- config/sidebar.velocity.ts | 2 +- docs/velocity/dev/how-to/plugin-messaging.md | 69 ++++++++++++++++++++ 2 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 docs/velocity/dev/how-to/plugin-messaging.md diff --git a/config/sidebar.velocity.ts b/config/sidebar.velocity.ts index b51fba8a9..ce9ba53c6 100644 --- a/config/sidebar.velocity.ts +++ b/config/sidebar.velocity.ts @@ -84,7 +84,7 @@ const velocity: SidebarsConfig = { type: "generated-index", slug: "/cat/dev/how-to-guides", }, - items: ["dev/how-to/dependencies", "dev/how-to/porting-from-velocity-1"], + items: ["dev/how-to/dependencies", "dev/how-to/porting-from-velocity-1", "dev/how-to/plugin-messaging"], }, { type: "category", diff --git a/docs/velocity/dev/how-to/plugin-messaging.md b/docs/velocity/dev/how-to/plugin-messaging.md new file mode 100644 index 000000000..2c0b2a31f --- /dev/null +++ b/docs/velocity/dev/how-to/plugin-messaging.md @@ -0,0 +1,69 @@ +--- +slug: /dev/plugin-messaging +--- + +# Plugin Messaging + +Plugin messaging is a way for Paper plugins to communicate with clients, and when your servers are behind a proxy, it will allow your Paper plugins to communicate with the proxy server. + +By default, your Velocity server will respond to the `bungeecord:main` channel unless you have disabled `bungee-plugin-message-channel` in the Velocity configuration. Let's take a look at how plugin messaging works, and more importantly - how your Velocity server is already prepared to handle it. + +## Sending Plugin Messages + +First, we're actually going take a look at your Java server. Your Java server plugin will need to register that it will be sending on any given plugin channel. You'll should to do this alongside your other event listener registrations. + +```java +public final class PluginMessagingSample extends JavaPlugin { + + @Override + public void onEnable() { + getServer().getMessenger().registerOutgoingPluginChannel(this, "bungeecord:main"); + } + +} +``` + +Now that we're registered, we can send messages on the `bungeecord:main` channel. + +:::tip The "bungeecord" and "bungeecord:main" channel + +By now, you may have noticed that we're using `bungeecord:main` instead of `velocity:main`. Many plugins are already setup for use in BungeeCord (or Waterfall) environments (communicating over a channel called `BungeeCord`), and to ease your transition to using Velocity, Velocity will respond on these channels as well. If your plugins are already using BungeeCord plugin messaging, you won't need to change anything! + +::: + +Plugin messages are formatted as byte arrays, and can be sent using the `sendPluginMessage` method on a `Player` object. Let's take a look at an example of sending a plugin message to the `bungeecord:main` channel to send our player to another server. + +```java +public final class PluginMessagingSample extends JavaPlugin implements Listener { + + @Override + public void onEnable() { + getServer().getPluginManager().registerEvents(this, this); + + getServer().getMessenger().registerOutgoingPluginChannel(this, "bungeecord:main"); + } + + @EventHandler + public void onPlayerJump(PlayerJumpEvent event) { + Player player = event.getPlayer(); + + ByteArrayDataOutput out = ByteStreams.newDataOutput(); + out.writeUTF("Connect"); + out.writeUTF("hub2"); + player.sendPluginMessage(this, "bungeecord:main", out.toByteArray()); + } + +} +``` + +### What did we just do? + +We sent a plugin message on the `bungeecord:main` channel! The message we sent was a byte array that contained two strings converted to bytes: `Connect` and `hub2`. + +Our Velocity proxy received the message through the player who triggered the `PlayerJumpEvent` on our Java server. Then, Velocity recognized the channel as it's own, and in alignment with BungeeCord's format sent our player to `hub2`. + +For BungeeCord, we can think of this message as a case sensitive command with arguments. Here, our command is `Connect` and our only argument is `hub2` but some "commands" may have multiple arguments. For other channels introduced by client side mods, refer to their documentation to best understand how to format your messages. + +### BungeeCord Plugin Message Types + +Although we sent a `Connect` message to the proxy there are a few other cases that Velocity will act on. You can find a list of them in the [BungeeCord documentation](https://www.spigotmc.org/wiki/bukkit-bungee-plugin-messaging-channel/#bungeecord-subchannel-specificationd). From c624064f73d8e1a0de66f88b7b5e42a855c75462 Mon Sep 17 00:00:00 2001 From: Ollie <69084614+olijeffers0n@users.noreply.github.com> Date: Thu, 13 Jul 2023 12:18:22 +0100 Subject: [PATCH 2/7] Plugin Messaging Docs --- config/sidebar.paper.ts | 1 + config/sidebar.velocity.ts | 8 +- docs/paper/dev/api/plugin-messaging.md | 183 +++++++++++++++++++ docs/velocity/dev/how-to/plugin-messaging.md | 79 ++++---- 4 files changed, 231 insertions(+), 40 deletions(-) create mode 100644 docs/paper/dev/api/plugin-messaging.md diff --git a/config/sidebar.paper.ts b/config/sidebar.paper.ts index 2cc454828..e4346e090 100644 --- a/config/sidebar.paper.ts +++ b/config/sidebar.paper.ts @@ -118,6 +118,7 @@ const paper: SidebarsConfig = { "dev/api/roadmap", "dev/api/pdc", "dev/api/custom-inventory-holder", + "dev/api/plugin-messaging", ], }, ], diff --git a/config/sidebar.velocity.ts b/config/sidebar.velocity.ts index 075eb4dca..822379009 100644 --- a/config/sidebar.velocity.ts +++ b/config/sidebar.velocity.ts @@ -84,7 +84,10 @@ const velocity: SidebarsConfig = { type: "generated-index", slug: "/cat/dev/how-to-guides", }, - items: ["dev/how-to/dependencies", "dev/how-to/porting-from-velocity-1", "dev/how-to/plugin-messaging"], + items: [ + "dev/how-to/dependencies", + "dev/how-to/porting-from-velocity-1", + ], }, { type: "category", @@ -104,7 +107,8 @@ const velocity: SidebarsConfig = { }, "dev/api/event", "dev/api/command", - "dev/api/scheduler" + "dev/api/scheduler", + "dev/how-to/plugin-messaging", ], }, ], diff --git a/docs/paper/dev/api/plugin-messaging.md b/docs/paper/dev/api/plugin-messaging.md new file mode 100644 index 000000000..05b327c31 --- /dev/null +++ b/docs/paper/dev/api/plugin-messaging.md @@ -0,0 +1,183 @@ +--- +slug: /dev/plugin-messaging +--- + +# Plugin Messaging + +First introduced in [2012](https://web.archive.org/web/20220711204310/https://dinnerbone.com/blog/2012/01/13/minecraft-plugin-channels-messaging/), +Plugin messaging is a way for Paper plugins to communicate with clients. When your servers are behind a proxy, +it will allow your Paper plugins to communicate with the proxy server. + +## Sending Plugin Messages + +First, we're actually going take a look at your Paper server. Your Paper server plugin will need to register that it +will be sending on any given plugin channel. You'll should to do this alongside your other event listener registrations. + +```java +public final class PluginMessagingSample extends JavaPlugin { + + @Override + public void onEnable() { + getServer().getMessenger().registerOutgoingPluginChannel(this, "bungeecord:main"); + // Blah blah blah... + } + +} +``` + +Now that we're registered, we can send messages on the `bungeecord:main` channel. + +:::tip[The "bungeecord" and "bungeecord:main" channel] + +Most plugins are setup for use in BungeeCord (or Waterfall) environments (communicating over a channel called `BungeeCord`). +We recommend Velocity over BungeeCord, and to ease your transition to using Velocity, it will also respond on these channels as well. + +::: + +Plugin messages are formatted as byte arrays, and can be sent using the `sendPluginMessage` method on a `Player` object. +Let's take a look at an example of sending a plugin message to the `bungeecord:main` channel to send our player to another server. + +```java +public final class PluginMessagingSample extends JavaPlugin implements Listener { + + @Override + public void onEnable() { + getServer().getPluginManager().registerEvents(this, this); + getServer().getMessenger().registerOutgoingPluginChannel(this, "bungeecord:main"); + } + + @EventHandler + public void onPlayerJump(PlayerJumpEvent event) { + Player player = event.getPlayer(); + + ByteArrayDataOutput out = ByteStreams.newDataOutput(); + out.writeUTF("Connect"); + out.writeUTF("hub2"); + player.sendPluginMessage(this, "bungeecord:main", out.toByteArray()); + } + +} +``` + +:::tip + +These channels rely on the Minecraft protocol, and are sent as a special type of packet called a +[Plugin Message](https://wiki.vg/Plugin_channels#Plugin_Messages). They piggyback on player connections, so if a player +is not connected to the server, the server will not be able to send or receive plugin messages. + +::: + +### What did we just do? + +We sent a plugin message on the `bungeecord:main` channel! The message we sent was a byte array that contained two strings converted to bytes: `Connect` and `hub2`. + +Our proxy server received the message through the player who triggered the `PlayerJumpEvent` on our Java server. +Then, it recognized the channel as it's own, and in alignment with BungeeCord's format sent our player to the `hub2` server. + +For BungeeCord, we can think of this message as a case-sensitive command with arguments. +Here, our command is `Connect` and our only argument is `hub2` but some "commands" may have multiple arguments. +For other channels introduced by client side mods, refer to their documentation to best understand how to format your messages. + +### BungeeCord Plugin Message Types + +Although we sent a `Connect` message to the proxy there are a few other cases that proxies will act on. +These are the following: + +| Message Type | Description | Arguments | Response | +|:------------------|:-------------------------------------------------------|:-----------------------------------------------------------------|:--------------------------------------------------| +| `Connect` | Connects the player to the specified server. | `server name` | N/A | +| `ConnectOther` | Connects another player to the specified server. | `player name`, `server name` | N/A | +| `IP` | Returns the IP of the specified player. | `player name` | `IP`, `port` | +| `PlayerCount` | Returns the number of players on the specified server. | `server name` | `server name`, player count` | +| `PlayerList` | Returns a list of players on the specified server. | `server name` | `server name`, `CSV player names` | +| `GetServers` | Returns a list of all servers. | N/A | `CSV server names` | +| `Message` | Sends a message to the specified player. | `player name`, `message` | N/A | +| `GetServer` | Returns the server the player is connected to. | N/A | `server name` | +| `UUID` | Returns the UUID of player. | N/A | `UUID` | +| `UUIDOther` | Returns the UUID of the specified player. | `player name` | `player name`, `UUID` | +| `ServerIp` | Returns the IP of the specified server. | `server name` | `server name`, `IP`, `port` | +| `KickPlayer` | Kicks the specified player. | `player name`, `reason` | N/A | +| `Forward` | Forwards a plugin message to another server. | `server`, `subchannel`, `size of plugin message`, `message` | `subchannel`, `size of plugin message`, `message` | +| `ForwardToPlayer` | Forwards a plugin message to another player. | `player name`, `subchannel`, `size of plugin message`, `message` | `subchannel`, `size of plugin message`, `message` | + +##### Example: `PlayerCount` + +```java +public class MyPlugin extends JavaPlugin implements PluginMessageListener { + + @Override + public void onEnable() { + this.getServer().getMessenger().registerOutgoingPluginChannel(this, "BungeeCord"); + this.getServer().getMessenger().registerIncomingPluginChannel(this, "BungeeCord", this); + + Player player = ...; + ByteArrayDataOutput out = ByteStreams.newDataOutput(); + out.writeUTF("PlayerCount"); + out.writeUTF("lobby"); + player.sendPluginMessage(this, "BungeeCord", out.toByteArray()); + // The response will be handled in onPluginMessageReceived + } + + @Override + public void onPluginMessageReceived(String channel, Player player, byte[] message) { + if (!channel.equals("BungeeCord")) { + return; + } + ByteArrayDataInput in = ByteStreams.newDataInput(message); + String subchannel = in.readUTF(); + if (subchannel.equals("PlayerCount")) { + // This is our response to the PlayerCount request + String server = in.readUTF(); + int playerCount = in.readInt(); + } + } +} +``` + +##### Example: `Forward` + +```java +public class MyPlugin extends JavaPlugin implements PluginMessageListener { + + @Override + public void onEnable() { + this.getServer().getMessenger().registerOutgoingPluginChannel(this, "BungeeCord"); + this.getServer().getMessenger().registerIncomingPluginChannel(this, "BungeeCord", this); + + Player player = ...; + ByteArrayDataOutput out = ByteStreams.newDataOutput(); + out.writeUTF("Forward"); + out.writeUTF("ALL"); // This is the target server. "ALL" will message all servers appart from the one sending the message + out.writeUTF("SecretInternalChannel"); // This is the channel. + + ByteArrayOutputStream msgbytes = new ByteArrayOutputStream(); + DataOutputStream msgout = new DataOutputStream(msgbytes); + msgout.writeUTF("Paper is the meaning of life"); // You can do anything you want with msgout + msgout.writeShort(42); + + out.writeShort(msgbytes.toByteArray().length); // This is the length. + out.write(msgbytes.toByteArray()); // This is the message. + + player.sendPluginMessage(this, "BungeeCord", out.toByteArray()); + // The response will be handled in onPluginMessageReceived + } + + @Override + public void onPluginMessageReceived(String channel, Player player, byte[] message) { + if (!channel.equals("BungeeCord")) { + return; + } + ByteArrayDataInput in = ByteStreams.newDataInput(message); + String subchannel = in.readUTF(); + if (subchannel.equals("SecretInternalChannel")) { + short len = in.readShort(); + byte[] msgbytes = new byte[len]; + in.readFully(msgbytes); + + DataInputStream msgIn = new DataInputStream(new ByteArrayInputStream(msgbytes)); + String secretMessage = msgIn.readUTF(); // Read the data in the same way you wrote it + short meaningofLife = msgIn.readShort(); + } + } +} +``` diff --git a/docs/velocity/dev/how-to/plugin-messaging.md b/docs/velocity/dev/how-to/plugin-messaging.md index 2c0b2a31f..f8d7055ff 100644 --- a/docs/velocity/dev/how-to/plugin-messaging.md +++ b/docs/velocity/dev/how-to/plugin-messaging.md @@ -4,66 +4,69 @@ slug: /dev/plugin-messaging # Plugin Messaging -Plugin messaging is a way for Paper plugins to communicate with clients, and when your servers are behind a proxy, it will allow your Paper plugins to communicate with the proxy server. +First introduced in [2012](https://web.archive.org/web/20220711204310/https://dinnerbone.com/blog/2012/01/13/minecraft-plugin-channels-messaging/), +Plugin messaging is a way for Paper plugins to communicate with clients. -By default, your Velocity server will respond to the `bungeecord:main` channel unless you have disabled `bungee-plugin-message-channel` in the Velocity configuration. Let's take a look at how plugin messaging works, and more importantly - how your Velocity server is already prepared to handle it. +## Compatibility with BungeeCord + +When your servers are behind a proxy, it will allow your Paper plugins to communicate with the proxy server. +By default, your Velocity server will respond to the `bungeecord:main` channel unless you have disabled +`bungee-plugin-message-channel` in the Velocity configuration. Let's take a look at how plugin messaging works, and more importantly - how your Velocity server is already prepared to handle it. ## Sending Plugin Messages -First, we're actually going take a look at your Java server. Your Java server plugin will need to register that it will be sending on any given plugin channel. You'll should to do this alongside your other event listener registrations. +Firstly, our velocity server will need to register that it will be sending on any given plugin channel. +You'll should to do this alongside your other event listener registrations: ```java -public final class PluginMessagingSample extends JavaPlugin { - - @Override - public void onEnable() { - getServer().getMessenger().registerOutgoingPluginChannel(this, "bungeecord:main"); - } +@Subscribe +public void onProxyInitialization(ProxyInitializeEvent event) { + proxyServer.getChannelRegistrar().register(MinecraftChannelIdentifier.from("bungeecord:main")); } ``` -Now that we're registered, we can send messages on the `bungeecord:main` channel. +Then, you can send messages on the `bungeecord:main` channel. +Plugin messages are formatted as byte arrays, and can be sent using the `sendPluginMessage` method on a `Player` object. -:::tip The "bungeecord" and "bungeecord:main" channel +Let's take a look at an example of sending a plugin message to the `bungeecord:main` channel to send our player to another server. -By now, you may have noticed that we're using `bungeecord:main` instead of `velocity:main`. Many plugins are already setup for use in BungeeCord (or Waterfall) environments (communicating over a channel called `BungeeCord`), and to ease your transition to using Velocity, Velocity will respond on these channels as well. If your plugins are already using BungeeCord plugin messaging, you won't need to change anything! +```java +@Subscribe +public void onPlayerChat(PlayerChatEvent event) { + Player player = event.getPlayer(); + + ByteArrayDataOutput out = ByteStreams.newDataOutput(); + out.writeUTF("Connect"); + out.writeUTF("hub2"); + player.sendPluginMessage(plugin, "bungeecord:main", out.toByteArray()); +} +``` -::: +## Receiving Plugin Messages -Plugin messages are formatted as byte arrays, and can be sent using the `sendPluginMessage` method on a `Player` object. Let's take a look at an example of sending a plugin message to the `bungeecord:main` channel to send our player to another server. +Now that we've sent a plugin message, we'll need to receive it on the other end. +This is done by registering a listener for the PluginMessageEvent. ```java -public final class PluginMessagingSample extends JavaPlugin implements Listener { - - @Override - public void onEnable() { - getServer().getPluginManager().registerEvents(this, this); - - getServer().getMessenger().registerOutgoingPluginChannel(this, "bungeecord:main"); +@Subscribe +public void onPluginMessage(PluginMessageEvent event) { + if (!event.getIdentifier().getId().equals("identifier")) { + return; } - @EventHandler - public void onPlayerJump(PlayerJumpEvent event) { - Player player = event.getPlayer(); + ByteArrayDataInput in = ByteStreams.newDataInput(event.getData()); + String subChannel = in.readUTF(); - ByteArrayDataOutput out = ByteStreams.newDataOutput(); - out.writeUTF("Connect"); - out.writeUTF("hub2"); - player.sendPluginMessage(this, "bungeecord:main", out.toByteArray()); + if (subChannel.equals("Connect")) { + String server = in.readUTF(); + // Do something with the server name } - } ``` -### What did we just do? - -We sent a plugin message on the `bungeecord:main` channel! The message we sent was a byte array that contained two strings converted to bytes: `Connect` and `hub2`. - -Our Velocity proxy received the message through the player who triggered the `PlayerJumpEvent` on our Java server. Then, Velocity recognized the channel as it's own, and in alignment with BungeeCord's format sent our player to `hub2`. - -For BungeeCord, we can think of this message as a case sensitive command with arguments. Here, our command is `Connect` and our only argument is `hub2` but some "commands" may have multiple arguments. For other channels introduced by client side mods, refer to their documentation to best understand how to format your messages. +:::tip[The "bungeecord" specification] -### BungeeCord Plugin Message Types +See [here](/paper/dev/plugin-messaging#bungeecord-plugin-message-types) for a list of all the plugin messages that BungeeCord / Velocity supports. -Although we sent a `Connect` message to the proxy there are a few other cases that Velocity will act on. You can find a list of them in the [BungeeCord documentation](https://www.spigotmc.org/wiki/bukkit-bungee-plugin-messaging-channel/#bungeecord-subchannel-specificationd). +::: \ No newline at end of file From 3443a4c42140dddae81ad1c4a0bc614e774f6ff1 Mon Sep 17 00:00:00 2001 From: Ollie <69084614+olijeffers0n@users.noreply.github.com> Date: Thu, 13 Jul 2023 13:34:52 +0100 Subject: [PATCH 3/7] Apply suggestions from code review Co-authored-by: Nassim Jahnke --- docs/paper/dev/api/plugin-messaging.md | 16 ++++++++-------- docs/velocity/dev/how-to/plugin-messaging.md | 8 ++++---- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/paper/dev/api/plugin-messaging.md b/docs/paper/dev/api/plugin-messaging.md index 05b327c31..2aeb45244 100644 --- a/docs/paper/dev/api/plugin-messaging.md +++ b/docs/paper/dev/api/plugin-messaging.md @@ -10,8 +10,8 @@ it will allow your Paper plugins to communicate with the proxy server. ## Sending Plugin Messages -First, we're actually going take a look at your Paper server. Your Paper server plugin will need to register that it -will be sending on any given plugin channel. You'll should to do this alongside your other event listener registrations. +First, we're going to take a look at your Paper server. Your Paper server plugin will need to register that it +will be sending on any given plugin channel. You should to do this alongside your other event listener registrations. ```java public final class PluginMessagingSample extends JavaPlugin { @@ -34,7 +34,7 @@ We recommend Velocity over BungeeCord, and to ease your transition to using Velo ::: -Plugin messages are formatted as byte arrays, and can be sent using the `sendPluginMessage` method on a `Player` object. +Plugin messages are formatted as byte arrays and can be sent using the `sendPluginMessage` method on a `Player` object. Let's take a look at an example of sending a plugin message to the `bungeecord:main` channel to send our player to another server. ```java @@ -62,8 +62,8 @@ public final class PluginMessagingSample extends JavaPlugin implements Listener :::tip These channels rely on the Minecraft protocol, and are sent as a special type of packet called a -[Plugin Message](https://wiki.vg/Plugin_channels#Plugin_Messages). They piggyback on player connections, so if a player -is not connected to the server, the server will not be able to send or receive plugin messages. +[Plugin Message](https://wiki.vg/Plugin_channels#Plugin_Messages). They piggyback on player connections, so if there is no +player connected to the server, it will not be able to send or receive plugin messages. ::: @@ -72,15 +72,15 @@ is not connected to the server, the server will not be able to send or receive p We sent a plugin message on the `bungeecord:main` channel! The message we sent was a byte array that contained two strings converted to bytes: `Connect` and `hub2`. Our proxy server received the message through the player who triggered the `PlayerJumpEvent` on our Java server. -Then, it recognized the channel as it's own, and in alignment with BungeeCord's format sent our player to the `hub2` server. +Then, it recognized the channel as its own and in alignment with BungeeCord's format sent our player to the `hub2` server. For BungeeCord, we can think of this message as a case-sensitive command with arguments. -Here, our command is `Connect` and our only argument is `hub2` but some "commands" may have multiple arguments. +Here, our command is `Connect` and our only argument is `hub2`, but some "commands" may have multiple arguments. For other channels introduced by client side mods, refer to their documentation to best understand how to format your messages. ### BungeeCord Plugin Message Types -Although we sent a `Connect` message to the proxy there are a few other cases that proxies will act on. +Although we sent a `Connect` message to the proxy, there are a few other cases that proxies will act on. These are the following: | Message Type | Description | Arguments | Response | diff --git a/docs/velocity/dev/how-to/plugin-messaging.md b/docs/velocity/dev/how-to/plugin-messaging.md index f8d7055ff..b96e69820 100644 --- a/docs/velocity/dev/how-to/plugin-messaging.md +++ b/docs/velocity/dev/how-to/plugin-messaging.md @@ -11,12 +11,12 @@ Plugin messaging is a way for Paper plugins to communicate with clients. When your servers are behind a proxy, it will allow your Paper plugins to communicate with the proxy server. By default, your Velocity server will respond to the `bungeecord:main` channel unless you have disabled -`bungee-plugin-message-channel` in the Velocity configuration. Let's take a look at how plugin messaging works, and more importantly - how your Velocity server is already prepared to handle it. +`bungee-plugin-message-channel` in the Velocity configuration. Let's take a look at how plugin messaging works, and more importantly, how your Velocity server is already prepared to handle it. ## Sending Plugin Messages -Firstly, our velocity server will need to register that it will be sending on any given plugin channel. -You'll should to do this alongside your other event listener registrations: +Firstly, our Velocity server will need to register that it will be sending on any given plugin channel. +You should to do this alongside your other event listener registrations: ```java @@ -27,7 +27,7 @@ public void onProxyInitialization(ProxyInitializeEvent event) { ``` Then, you can send messages on the `bungeecord:main` channel. -Plugin messages are formatted as byte arrays, and can be sent using the `sendPluginMessage` method on a `Player` object. +Plugin messages are formatted as byte arrays and can be sent using the `sendPluginMessage` method on a `Player` object. Let's take a look at an example of sending a plugin message to the `bungeecord:main` channel to send our player to another server. From 681fceb3ca7f40b99d4b0536efb7df60acc6fb84 Mon Sep 17 00:00:00 2001 From: Ollie <69084614+olijeffers0n@users.noreply.github.com> Date: Thu, 13 Jul 2023 15:01:31 +0100 Subject: [PATCH 4/7] Update docs/paper/dev/api/plugin-messaging.md Co-authored-by: the456gamer --- docs/paper/dev/api/plugin-messaging.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/paper/dev/api/plugin-messaging.md b/docs/paper/dev/api/plugin-messaging.md index 2aeb45244..a155caf4f 100644 --- a/docs/paper/dev/api/plugin-messaging.md +++ b/docs/paper/dev/api/plugin-messaging.md @@ -27,7 +27,7 @@ public final class PluginMessagingSample extends JavaPlugin { Now that we're registered, we can send messages on the `bungeecord:main` channel. -:::tip[The "bungeecord" and "bungeecord:main" channel] +:::tip[The "bungeecord" and "bungeecord\:main" channel] Most plugins are setup for use in BungeeCord (or Waterfall) environments (communicating over a channel called `BungeeCord`). We recommend Velocity over BungeeCord, and to ease your transition to using Velocity, it will also respond on these channels as well. From 5becef47fa8831d1bce45b2a7c020dcc7b12ef09 Mon Sep 17 00:00:00 2001 From: Ollie <69084614+olijeffers0n@users.noreply.github.com> Date: Sun, 16 Jul 2023 14:21:16 +0100 Subject: [PATCH 5/7] Add Note to the forward example --- docs/paper/dev/api/plugin-messaging.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/docs/paper/dev/api/plugin-messaging.md b/docs/paper/dev/api/plugin-messaging.md index 05b327c31..6b5233007 100644 --- a/docs/paper/dev/api/plugin-messaging.md +++ b/docs/paper/dev/api/plugin-messaging.md @@ -136,6 +136,16 @@ public class MyPlugin extends JavaPlugin implements PluginMessageListener { ##### Example: `Forward` +Forwards a plugin message to another server. This is useful for server-to-server communication within a proxy network. +For example, if a certain player is banned on one server, you can forward a message to all other servers to ban them there too. + +:::caution[Example of banning a player on all servers] + +This is not a recommended way to ban players due to the fact that there may not be anyone online on the target servers, +but it is an example of how this can be used. + +::: + ```java public class MyPlugin extends JavaPlugin implements PluginMessageListener { @@ -153,7 +163,7 @@ public class MyPlugin extends JavaPlugin implements PluginMessageListener { ByteArrayOutputStream msgbytes = new ByteArrayOutputStream(); DataOutputStream msgout = new DataOutputStream(msgbytes); msgout.writeUTF("Paper is the meaning of life"); // You can do anything you want with msgout - msgout.writeShort(42); + msgout.writeShort(42); // Writing a random short out.writeShort(msgbytes.toByteArray().length); // This is the length. out.write(msgbytes.toByteArray()); // This is the message. From 22978d1f711b7c82620a1e6efda1a708cbf85136 Mon Sep 17 00:00:00 2001 From: Ollie <69084614+olijeffers0n@users.noreply.github.com> Date: Sun, 16 Jul 2023 14:43:48 +0100 Subject: [PATCH 6/7] Use `BungeeCord` everywhere --- docs/paper/dev/api/plugin-messaging.md | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/docs/paper/dev/api/plugin-messaging.md b/docs/paper/dev/api/plugin-messaging.md index 35bc48955..1bf3fa005 100644 --- a/docs/paper/dev/api/plugin-messaging.md +++ b/docs/paper/dev/api/plugin-messaging.md @@ -18,24 +18,26 @@ public final class PluginMessagingSample extends JavaPlugin { @Override public void onEnable() { - getServer().getMessenger().registerOutgoingPluginChannel(this, "bungeecord:main"); + getServer().getMessenger().registerOutgoingPluginChannel(this, "BungeeCord"); // Blah blah blah... } } ``` -Now that we're registered, we can send messages on the `bungeecord:main` channel. +Now that we're registered, we can send messages on the `BungeeCord` channel. -:::tip[The "bungeecord" and "bungeecord\:main" channel] +:::tip[The "BungeeCord" and "bungeecord\:main" channel] Most plugins are setup for use in BungeeCord (or Waterfall) environments (communicating over a channel called `BungeeCord`). We recommend Velocity over BungeeCord, and to ease your transition to using Velocity, it will also respond on these channels as well. +`BungeeCord` and `bungeecord:main` will generally operate the same way, but we recommend using `BungeeCord` with Paper. + ::: Plugin messages are formatted as byte arrays and can be sent using the `sendPluginMessage` method on a `Player` object. -Let's take a look at an example of sending a plugin message to the `bungeecord:main` channel to send our player to another server. +Let's take a look at an example of sending a plugin message to the `BungeeCord` channel to send our player to another server. ```java public final class PluginMessagingSample extends JavaPlugin implements Listener { @@ -43,7 +45,7 @@ public final class PluginMessagingSample extends JavaPlugin implements Listener @Override public void onEnable() { getServer().getPluginManager().registerEvents(this, this); - getServer().getMessenger().registerOutgoingPluginChannel(this, "bungeecord:main"); + getServer().getMessenger().registerOutgoingPluginChannel(this, "BungeeCord"); } @EventHandler @@ -53,7 +55,7 @@ public final class PluginMessagingSample extends JavaPlugin implements Listener ByteArrayDataOutput out = ByteStreams.newDataOutput(); out.writeUTF("Connect"); out.writeUTF("hub2"); - player.sendPluginMessage(this, "bungeecord:main", out.toByteArray()); + player.sendPluginMessage(this, "BungeeCord", out.toByteArray()); } } @@ -69,7 +71,7 @@ player connected to the server, it will not be able to send or receive plugin me ### What did we just do? -We sent a plugin message on the `bungeecord:main` channel! The message we sent was a byte array that contained two strings converted to bytes: `Connect` and `hub2`. +We sent a plugin message on the `BungeeCord` channel! The message we sent was a byte array that contained two strings converted to bytes: `Connect` and `hub2`. Our proxy server received the message through the player who triggered the `PlayerJumpEvent` on our Java server. Then, it recognized the channel as its own and in alignment with BungeeCord's format sent our player to the `hub2` server. From be70f0d53dc4e6110a6f71518fc953b4c5c9a49e Mon Sep 17 00:00:00 2001 From: Ollie <69084614+olijeffers0n@users.noreply.github.com> Date: Sun, 16 Jul 2023 16:06:51 +0100 Subject: [PATCH 7/7] Add a bungee channel explanation --- docs/paper/dev/api/plugin-messaging.md | 45 ++++++++++---------- docs/velocity/dev/how-to/plugin-messaging.md | 4 +- 2 files changed, 25 insertions(+), 24 deletions(-) diff --git a/docs/paper/dev/api/plugin-messaging.md b/docs/paper/dev/api/plugin-messaging.md index 1bf3fa005..b9d3316ad 100644 --- a/docs/paper/dev/api/plugin-messaging.md +++ b/docs/paper/dev/api/plugin-messaging.md @@ -8,9 +8,19 @@ First introduced in [2012](https://web.archive.org/web/20220711204310/https://di Plugin messaging is a way for Paper plugins to communicate with clients. When your servers are behind a proxy, it will allow your Paper plugins to communicate with the proxy server. +## BungeeCord Channel + +The BungeeCord channel is used for communication between your Paper server and a BungeeCord (Or protocol supporting) proxy. + +Originally, the channel supported by the BungeeCord proxy was called `BungeeCord`. In versions 1.13 and above, +the channel was renamed to `bungeecord:main` to create a key structure for plugin messaging channels. + +Paper handles this change internally, and automatically changes any messages sent on the `BungeeCord` channel +to the `bungeecord:main` channel. This means that your Paper plugins should continue to use the `BungeeCord` channel. + ## Sending Plugin Messages -First, we're going to take a look at your Paper server. Your Paper server plugin will need to register that it +First, we're going to take a look at your Paper server. Your Paper plugin will need to register that it will be sending on any given plugin channel. You should to do this alongside your other event listener registrations. ```java @@ -27,15 +37,6 @@ public final class PluginMessagingSample extends JavaPlugin { Now that we're registered, we can send messages on the `BungeeCord` channel. -:::tip[The "BungeeCord" and "bungeecord\:main" channel] - -Most plugins are setup for use in BungeeCord (or Waterfall) environments (communicating over a channel called `BungeeCord`). -We recommend Velocity over BungeeCord, and to ease your transition to using Velocity, it will also respond on these channels as well. - -`BungeeCord` and `bungeecord:main` will generally operate the same way, but we recommend using `BungeeCord` with Paper. - -::: - Plugin messages are formatted as byte arrays and can be sent using the `sendPluginMessage` method on a `Player` object. Let's take a look at an example of sending a plugin message to the `BungeeCord` channel to send our player to another server. @@ -102,7 +103,7 @@ These are the following: | `Forward` | Forwards a plugin message to another server. | `server`, `subchannel`, `size of plugin message`, `message` | `subchannel`, `size of plugin message`, `message` | | `ForwardToPlayer` | Forwards a plugin message to another player. | `player name`, `subchannel`, `size of plugin message`, `message` | `subchannel`, `size of plugin message`, `message` | -##### Example: `PlayerCount` +#### Example: `PlayerCount` ```java public class MyPlugin extends JavaPlugin implements PluginMessageListener { @@ -136,17 +137,7 @@ public class MyPlugin extends JavaPlugin implements PluginMessageListener { } ``` -##### Example: `Forward` - -Forwards a plugin message to another server. This is useful for server-to-server communication within a proxy network. -For example, if a certain player is banned on one server, you can forward a message to all other servers to ban them there too. - -:::caution[Example of banning a player on all servers] - -This is not a recommended way to ban players due to the fact that there may not be anyone online on the target servers, -but it is an example of how this can be used. - -::: +#### Example: `Forward` ```java public class MyPlugin extends JavaPlugin implements PluginMessageListener { @@ -193,3 +184,13 @@ public class MyPlugin extends JavaPlugin implements PluginMessageListener { } } ``` + +This message is used to forward a plugin message to another server. This is useful for server-to-server communication within a proxy network. +For example, if a certain player is banned on one server, you can forward a message to all other servers to ban them there too. + +:::caution[Example of banning a player on all servers] + +This is not a recommended way to ban players due to the fact that there may not be anyone online on the target servers, +but it is an example of how this can be used. + +::: diff --git a/docs/velocity/dev/how-to/plugin-messaging.md b/docs/velocity/dev/how-to/plugin-messaging.md index b96e69820..527e1748d 100644 --- a/docs/velocity/dev/how-to/plugin-messaging.md +++ b/docs/velocity/dev/how-to/plugin-messaging.md @@ -11,7 +11,8 @@ Plugin messaging is a way for Paper plugins to communicate with clients. When your servers are behind a proxy, it will allow your Paper plugins to communicate with the proxy server. By default, your Velocity server will respond to the `bungeecord:main` channel unless you have disabled -`bungee-plugin-message-channel` in the Velocity configuration. Let's take a look at how plugin messaging works, and more importantly, how your Velocity server is already prepared to handle it. +`bungee-plugin-message-channel` in the Velocity configuration. Let's take a look at how plugin messaging works, +and more importantly, how your Velocity server is already prepared to handle it. ## Sending Plugin Messages @@ -19,7 +20,6 @@ Firstly, our Velocity server will need to register that it will be sending on an You should to do this alongside your other event listener registrations: ```java - @Subscribe public void onProxyInitialization(ProxyInitializeEvent event) { proxyServer.getChannelRegistrar().register(MinecraftChannelIdentifier.from("bungeecord:main"));