Skip to content

Commit 80201be

Browse files
456devzlataovce
andauthored
feat: improve validation in Velocity plugin messaging example (#479)
* set event result, and add warnings to velocity plugin messaging docs also includes more specific diagrams for each case, fixed identifier checking, rather than by identity, and instanceof Player player style cast. * fix spelling * Apply suggestions from code review Co-authored-by: Matouš Kučera <mk@kcra.me> --------- Co-authored-by: Matouš Kučera <mk@kcra.me>
1 parent 59f4c97 commit 80201be

1 file changed

Lines changed: 91 additions & 8 deletions

File tree

docs/velocity/dev/api/plugin-messaging.mdx

Lines changed: 91 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,20 @@ flowchart LR
1717
backend -->|"3 (Incoming)"| Velocity -->|"4 (Outgoing)"| player
1818
```
1919

20+
:::warning
21+
22+
When listening to `PluginMessageEvent`, ensure the result is
23+
<Javadoc name={"com/velocitypowered/api/event/connection/PluginMessageEvent$ForwardResult#handled()"} project={"velocity"}>`ForwardResult.handled()`</Javadoc>
24+
if you do not intend the client to participate.
25+
26+
If the result is forwarded, players can impersonate the proxy to your backend servers.
27+
28+
Additionally, ensure the result is set correctly after actually handling correct messages, to prevent them from being leaked to the other party.
29+
30+
This can be achieved with unconditionally setting the result between checking the identifier and checking the source, as shown in the examples.
31+
32+
:::
33+
2034
Additionally, BungeeCord channel compatibility is included, which may remove the need for a companion Velocity plugin in certain cases.
2135

2236
## Case 1: Receiving a plugin message from a player
@@ -26,6 +40,19 @@ It will require registering with the ChannelRegistrar for the event to be fired.
2640

2741
An example use case could be logging messages from a mod that reports the enabled features.
2842

43+
```mermaid
44+
flowchart LR
45+
subgraph handle from player
46+
direction LR
47+
a[player] --> b[Velocity] ~~~ c[backend]
48+
end
49+
subgraph forward from player
50+
direction LR
51+
d[player] --> e[Velocity] --> f[backend]
52+
end
53+
```
54+
55+
2956
```java
3057
public static final MinecraftChannelIdentifier IDENTIFIER = MinecraftChannelIdentifier.from("custom:main");
3158

@@ -36,12 +63,23 @@ public void onProxyInitialization(ProxyInitializeEvent event) {
3663

3764
@Subscribe
3865
public void onPluginMessageFromPlayer(PluginMessageEvent event) {
39-
if (!(event.getSource() instanceof Player)) {
66+
// Check if the identifier matches first, no matter the source.
67+
if (!IDENTIFIER.equals(event.getIdentifier())) {
4068
return;
4169
}
42-
Player player = (Player) event.getSource();
43-
// Ensure the identifier is what you expect before trying to handle the data
44-
if (event.getIdentifier() != IDENTIFIER) {
70+
71+
// mark PluginMessage as handled, indicating that the contents
72+
// should not be forwarding to their original destination.
73+
event.setResult(PluginMessageEvent.ForwardResult.handled());
74+
75+
// Alternatively:
76+
77+
// mark PluginMessage as forwarded, indicating that the contents
78+
// should be passed through, as if Velocity is not present.
79+
//event.setResult(PluginMessageEvent.ForwardResult.forward());
80+
81+
// only attempt parsing the data if the source is a player
82+
if (!(event.getSource() instanceof Player player)) {
4583
return;
4684
}
4785

@@ -64,6 +102,15 @@ Otherwise, a player can pretend to be your proxy, and spoof them.
64102

65103
:::
66104

105+
```mermaid
106+
flowchart LR
107+
subgraph Send to Backend
108+
direction LR
109+
player ~~~ Velocity --> backend
110+
end
111+
```
112+
113+
67114
### Using any connected player
68115

69116
This is useful if you just want to communicate something relevant to the entire server,
@@ -104,6 +151,18 @@ for the event to be fired.
104151

105152
An example use case could be handing a request to transfer the player to another server.
106153

154+
```mermaid
155+
flowchart LR
156+
subgraph handle from backend
157+
direction RL
158+
a[backend] --> b[Velocity] ~~~ c[ player]
159+
end
160+
subgraph forward from backend
161+
direction RL
162+
d[backend] --> e[Velocity] --> f[player]
163+
end
164+
```
165+
107166
```java
108167
public static final MinecraftChannelIdentifier IDENTIFIER = MinecraftChannelIdentifier.from("custom:main");
109168

@@ -114,12 +173,28 @@ public void onProxyInitialization(ProxyInitializeEvent event) {
114173

115174
@Subscribe
116175
public void onPluginMessageFromBackend(PluginMessageEvent event) {
117-
if (!(event.getSource() instanceof ServerConnection)) {
176+
// Check if the identifier matches first, no matter the source.
177+
// this allows setting all messages to IDENTIFIER as handled,
178+
// preventing any client-originating messages from being forwarded.
179+
if (!IDENTIFIER.equals(event.getIdentifier())) {
118180
return;
119181
}
120-
ServerConnection backend = (ServerConnection) event.getSource();
121-
// Ensure the identifier is what you expect before trying to handle the data
122-
if (event.getIdentifier() != IDENTIFIER) {
182+
183+
// mark PluginMessage as handled, indicating that the contents
184+
// should not be forwarding to their original destination.
185+
event.setResult(PluginMessageEvent.ForwardResult.handled());
186+
187+
// Alternatively:
188+
189+
// mark PluginMessage as forwarded, indicating that the contents
190+
// should be passed through, as if Velocity is not present.
191+
//
192+
// this should be used with extreme caution,
193+
// as any client can freely send whatever it wants, pretending to be the proxy
194+
//event.setResult(PluginMessageEvent.ForwardResult.forward());
195+
196+
// only attempt parsing the data if the source is a backend server
197+
if (!(event.getSource() instanceof ServerConnection backend)) {
123198
return;
124199
}
125200

@@ -138,6 +213,14 @@ This is only really useful for when you are making client-side mods. Otherwise,
138213

139214
:::
140215

216+
```mermaid
217+
flowchart RL
218+
subgraph Send to Player
219+
direction RL
220+
backend ~~~ Velocity --> player
221+
end
222+
```
223+
141224
```java
142225
public boolean sendPluginMessageToPlayer(Player player, ChannelIdentifier identifier, byte[] data) {
143226
// On success, returns true

0 commit comments

Comments
 (0)