Skip to content

Commit f099d81

Browse files
committed
Merge branch 'dev/3.0.0' into forwarding-mode
# Conflicts: # proxy/src/main/java/com/velocitypowered/proxy/connection/backend/LoginSessionHandler.java
2 parents f615f29 + ebc418f commit f099d81

20 files changed

+331
-118
lines changed

api/build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ tasks {
6767
"https://google.github.io/guice/api-docs/${libs.guice.get().version}/javadoc/",
6868
"https://docs.oracle.com/en/java/javase/17/docs/api/",
6969
"https://jd.advntr.dev/api/${libs.adventure.bom.get().version}/",
70-
"https://javadoc.io/doc/com.github.ben-manes.caffeine/caffeine"
70+
"https://javadoc.io/doc/com.github.ben-manes.caffeine/caffeine/${libs.caffeine.get().version}/"
7171
)
7272

7373
o.tags(

api/src/main/java/com/velocitypowered/api/command/CommandManager.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public interface CommandManager {
4444
* @param otherAliases additional aliases
4545
* @throws IllegalArgumentException if one of the given aliases is already registered, or
4646
* the given command does not implement a registrable {@link Command} subinterface
47-
* @see Command for a list of registrable {@link Command} subinterfaces
47+
* @see Command for a list of registrable Command subinterfaces
4848
*/
4949
default void register(String alias, Command command, String... otherAliases) {
5050
register(metaBuilder(alias).aliases(otherAliases).build(), command);
@@ -65,7 +65,7 @@ default void register(String alias, Command command, String... otherAliases) {
6565
* @param command the command to register
6666
* @throws IllegalArgumentException if one of the given aliases is already registered, or
6767
* the given command does not implement a registrable {@link Command} subinterface
68-
* @see Command for a list of registrable {@link Command} subinterfaces
68+
* @see Command for a list of registrable Command subinterfaces
6969
*/
7070
void register(CommandMeta meta, Command command);
7171

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/*
2+
* Copyright (C) 2018-2023 Velocity Contributors
3+
*
4+
* The Velocity API is licensed under the terms of the MIT License. For more details,
5+
* reference the LICENSE file in the api top-level directory.
6+
*/
7+
8+
package com.velocitypowered.api.event.player;
9+
10+
import com.google.common.base.Preconditions;
11+
import com.velocitypowered.api.event.ResultedEvent;
12+
import com.velocitypowered.api.event.annotation.AwaitingEvent;
13+
import com.velocitypowered.api.proxy.ServerConnection;
14+
import java.util.UUID;
15+
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
16+
import org.checkerframework.checker.nullness.qual.Nullable;
17+
18+
/**
19+
* This event is fired when the downstream server tries to remove a resource pack from player
20+
* or clear all of them. The proxy will wait on this event to finish before forwarding the
21+
* action to the user. If this event is denied, no resource packs will be removed from player.
22+
*/
23+
@AwaitingEvent
24+
public class ServerResourcePackRemoveEvent implements ResultedEvent<ResultedEvent.GenericResult> {
25+
26+
private GenericResult result;
27+
private final @MonotonicNonNull UUID packId;
28+
private final ServerConnection serverConnection;
29+
30+
/**
31+
* Instantiates this event.
32+
*/
33+
public ServerResourcePackRemoveEvent(UUID packId, ServerConnection serverConnection) {
34+
this.result = ResultedEvent.GenericResult.allowed();
35+
this.packId = packId;
36+
this.serverConnection = serverConnection;
37+
}
38+
39+
/**
40+
* Returns the id of the resource pack, if it's null all the resource packs
41+
* from player will be cleared.
42+
*
43+
* @return the id
44+
*/
45+
@Nullable
46+
public UUID getPackId() {
47+
return packId;
48+
}
49+
50+
/**
51+
* Returns the server that tries to remove a resource pack from player or clear all of them.
52+
*
53+
* @return the server connection
54+
*/
55+
public ServerConnection getServerConnection() {
56+
return serverConnection;
57+
}
58+
59+
@Override
60+
public GenericResult getResult() {
61+
return this.result;
62+
}
63+
64+
@Override
65+
public void setResult(GenericResult result) {
66+
this.result = Preconditions.checkNotNull(result, "result");
67+
}
68+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* Copyright (C) 2024 Velocity Contributors
3+
*
4+
* The Velocity API is licensed under the terms of the MIT License. For more details,
5+
* reference the LICENSE file in the api top-level directory.
6+
*/
7+
8+
package com.velocitypowered.api.event.player.configuration;
9+
10+
import com.velocitypowered.api.event.annotation.AwaitingEvent;
11+
import com.velocitypowered.api.proxy.Player;
12+
import com.velocitypowered.api.proxy.ServerConnection;
13+
import org.jetbrains.annotations.NotNull;
14+
15+
/**
16+
* This event is executed when a player entered the configuration state and can be configured by Velocity.
17+
* <p>Velocity will wait for this event before continuing/ending the configuration state.</p>
18+
*
19+
* @param player The player who can be configured.
20+
* @param server The server that is currently configuring the player.
21+
* @since 3.3.0
22+
* @sinceMinecraft 1.20.2
23+
*/
24+
@AwaitingEvent
25+
public record PlayerConfigurationEvent(@NotNull Player player, ServerConnection server) {
26+
}

api/src/main/java/com/velocitypowered/api/event/player/configuration/PlayerEnterConfigurationEvent.java

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,23 @@
77

88
package com.velocitypowered.api.event.player.configuration;
99

10-
import com.velocitypowered.api.network.ProtocolState;
10+
import com.velocitypowered.api.event.annotation.AwaitingEvent;
1111
import com.velocitypowered.api.proxy.Player;
1212
import com.velocitypowered.api.proxy.ServerConnection;
1313
import org.jetbrains.annotations.NotNull;
1414

1515
/**
16-
* This event is executed when a player with version 1.20.2 or higher enters the configuration phase.
17-
* <p>From this moment on, until the {@link PlayerFinishedConfigurationEvent} is executed,
18-
* the {@linkplain Player#getProtocolState()} method is guaranteed
19-
* to return {@link ProtocolState#CONFIGURATION}.</p>
16+
* This event is executed when a player is about to enter the configuration state.
17+
* It is <b>not</b> called for the initial configuration of a player after login.
18+
* <p>Velocity will wait for this event before asking the client to enter configuration state.
19+
* However due to backend server being unable to keep the connection alive during state changes,
20+
* Velocity will only wait for a maximum of 5 seconds.</p>
2021
*
21-
* @param player The player that has entered the configuration phase.
22-
* @param server The server that will now (re-)configure the player.
22+
* @param player The player who is about to enter configuration state.
23+
* @param server The server that wants to reconfigure the player.
2324
* @since 3.3.0
2425
* @sinceMinecraft 1.20.2
2526
*/
27+
@AwaitingEvent
2628
public record PlayerEnterConfigurationEvent(@NotNull Player player, ServerConnection server) {
2729
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* Copyright (C) 2024 Velocity Contributors
3+
*
4+
* The Velocity API is licensed under the terms of the MIT License. For more details,
5+
* reference the LICENSE file in the api top-level directory.
6+
*/
7+
8+
package com.velocitypowered.api.event.player.configuration;
9+
10+
import com.velocitypowered.api.network.ProtocolState;
11+
import com.velocitypowered.api.proxy.Player;
12+
import com.velocitypowered.api.proxy.ServerConnection;
13+
import org.jetbrains.annotations.NotNull;
14+
15+
/**
16+
* This event is executed when a player has entered the configuration state.
17+
* <p>From this moment on, until the {@link PlayerFinishedConfigurationEvent} is executed,
18+
* the {@linkplain Player#getProtocolState()} method is guaranteed
19+
* to return {@link ProtocolState#CONFIGURATION}.</p>
20+
*
21+
* @param player The player who has entered the configuration state.
22+
* @param server The server that will now (re-)configure the player.
23+
* @since 3.3.0
24+
* @sinceMinecraft 1.20.2
25+
*/
26+
public record PlayerEnteredConfigurationEvent(@NotNull Player player, ServerConnection server) {
27+
}

api/src/main/java/com/velocitypowered/api/event/player/configuration/PlayerFinishConfigurationEvent.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,14 @@
1313
import org.jetbrains.annotations.NotNull;
1414

1515
/**
16-
* This event is executed when the player is about to finish the Configuration state.
17-
* <p>Velocity will wait for this event to finish the configuration phase on the client.</p>
16+
* This event is executed when a player is about to finish the configuration state.
17+
* <p>Velocity will wait for this event before asking the client to finish the configuration state.
18+
* However due to backend server being unable to keep the connection alive during state changes,
19+
* Velocity will only wait for a maximum of 5 seconds. If you need to hold a player in configuration
20+
* state, use the {@link PlayerConfigurationEvent}.</p>
1821
*
19-
* @param player The player who is about to complete the configuration phase.
20-
* @param server The server that is currently (re-)configuring the player.
22+
* @param player The player who is about to finish the configuration phase.
23+
* @param server The server that has (re-)configured the player.
2124
* @since 3.3.0
2225
* @sinceMinecraft 1.20.2
2326
*/

api/src/main/java/com/velocitypowered/api/event/player/configuration/PlayerFinishedConfigurationEvent.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@
1313
import org.jetbrains.annotations.NotNull;
1414

1515
/**
16-
* Event executed when a player of version 1.20.2 or higher finishes the Configuration state.
16+
* This event is executed when a player has finished the configuration state.
1717
* <p>From this moment on, the {@link Player#getProtocolState()} method
1818
* will return {@link ProtocolState#PLAY}.</p>
1919
*
20-
* @param player The player who has completed the Configuration state
20+
* @param player The player who has finished the configuration state.
2121
* @param server The server that has (re-)configured the player.
2222
* @since 3.3.0
2323
* @sinceMinecraft 1.20.2

gradle/libs.versions.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ shadow = "io.github.goooler.shadow:8.1.5"
1111
spotless = "com.diffplug.spotless:6.25.0"
1212

1313
[libraries]
14-
adventure-bom = "net.kyori:adventure-bom:4.16.0"
14+
adventure-bom = "net.kyori:adventure-bom:4.17.0"
1515
adventure-facet = "net.kyori:adventure-platform-facet:4.3.2"
1616
asm = "org.ow2.asm:asm:9.6"
1717
auto-service = "com.google.auto.service:auto-service:1.0.1"

proxy/src/main/java/com/velocitypowered/proxy/connection/backend/BackendPlaySessionHandler.java

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import com.velocitypowered.api.event.player.CookieRequestEvent;
3030
import com.velocitypowered.api.event.player.CookieStoreEvent;
3131
import com.velocitypowered.api.event.player.PlayerResourcePackStatusEvent;
32+
import com.velocitypowered.api.event.player.ServerResourcePackRemoveEvent;
3233
import com.velocitypowered.api.event.player.ServerResourcePackSendEvent;
3334
import com.velocitypowered.api.event.proxy.ProxyPingEvent;
3435
import com.velocitypowered.api.network.ProtocolVersion;
@@ -258,14 +259,26 @@ public boolean handle(final ResourcePackRequestPacket packet) {
258259

259260
@Override
260261
public boolean handle(RemoveResourcePackPacket packet) {
261-
final ConnectedPlayer player = serverConn.getPlayer();
262-
final ResourcePackHandler handler = player.resourcePackHandler();
263-
if (packet.getId() != null) {
264-
handler.remove(packet.getId());
265-
} else {
266-
handler.clearAppliedResourcePacks();
267-
}
268-
playerConnection.write(packet);
262+
final ServerResourcePackRemoveEvent event = new ServerResourcePackRemoveEvent(
263+
packet.getId(), this.serverConn);
264+
server.getEventManager().fire(event).thenAcceptAsync(serverResourcePackRemoveEvent -> {
265+
if (playerConnection.isClosed()) {
266+
return;
267+
}
268+
if (serverResourcePackRemoveEvent.getResult().isAllowed()) {
269+
final ConnectedPlayer player = serverConn.getPlayer();
270+
final ResourcePackHandler handler = player.resourcePackHandler();
271+
if (packet.getId() != null) {
272+
handler.remove(packet.getId());
273+
} else {
274+
handler.clearAppliedResourcePacks();
275+
}
276+
playerConnection.write(packet);
277+
}
278+
}, playerConnection.eventLoop()).exceptionally((ex) -> {
279+
logger.error("Exception while handling resource pack remove for {}", playerConnection, ex);
280+
return null;
281+
});
269282
return true;
270283
}
271284

0 commit comments

Comments
 (0)