Merge remote-tracking branch 'upstream/dev/4.0.0'
# Conflicts: # proxy/src/main/java/com/velocitypowered/proxy/connection/backend/BackendPlaySessionHandler.java
This commit is contained in:
@@ -18,7 +18,7 @@ java {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnlyApi(libs.jspecify)
|
||||
api(libs.jspecify)
|
||||
|
||||
api(libs.gson)
|
||||
api(libs.guava)
|
||||
|
||||
@@ -97,6 +97,16 @@ public class PluginAnnotationProcessor extends AbstractProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
for (String provided : plugin.provides()) {
|
||||
if (!SerializedPluginDescription.ID_PATTERN.matcher(provided).matches()) {
|
||||
environment.getMessager().printMessage(Diagnostic.Kind.ERROR,
|
||||
"Invalid provided ID '" + provided + "' for plugin " + qualifiedName
|
||||
+ ". IDs must start alphabetically, have lowercase alphanumeric characters, and "
|
||||
+ "can contain dashes or underscores.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// All good, generate the velocity-plugin.json.
|
||||
SerializedPluginDescription description = SerializedPluginDescription
|
||||
.from(plugin, qualifiedName.toString());
|
||||
|
||||
@@ -35,11 +35,12 @@ public final class SerializedPluginDescription {
|
||||
private final @Nullable String url;
|
||||
private final @Nullable List<String> authors;
|
||||
private final @Nullable List<Dependency> dependencies;
|
||||
private final @Nullable List<String> provides;
|
||||
private final String main;
|
||||
|
||||
private SerializedPluginDescription(String id, String name, String version, String description,
|
||||
String url,
|
||||
List<String> authors, List<Dependency> dependencies, String main) {
|
||||
List<String> authors, List<Dependency> dependencies, List<String> provides, String main) {
|
||||
Preconditions.checkNotNull(id, "id");
|
||||
Preconditions.checkArgument(ID_PATTERN.matcher(id).matches(), "id is not valid");
|
||||
this.id = id;
|
||||
@@ -50,6 +51,7 @@ public final class SerializedPluginDescription {
|
||||
this.authors = authors == null || authors.isEmpty() ? ImmutableList.of() : authors;
|
||||
this.dependencies =
|
||||
dependencies == null || dependencies.isEmpty() ? ImmutableList.of() : dependencies;
|
||||
this.provides = provides == null || provides.isEmpty() ? ImmutableList.of() : provides;
|
||||
this.main = Preconditions.checkNotNull(main, "main");
|
||||
}
|
||||
|
||||
@@ -61,7 +63,9 @@ public final class SerializedPluginDescription {
|
||||
return new SerializedPluginDescription(plugin.id(), plugin.name(), plugin.version(),
|
||||
plugin.description(), plugin.url(),
|
||||
Arrays.stream(plugin.authors()).filter(author -> !author.isEmpty())
|
||||
.collect(Collectors.toList()), dependencies, qualifiedName);
|
||||
.collect(Collectors.toList()), dependencies,
|
||||
Arrays.stream(plugin.provides()).filter(provided -> !provided.isEmpty())
|
||||
.collect(Collectors.toList()), qualifiedName);
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
@@ -92,6 +96,10 @@ public final class SerializedPluginDescription {
|
||||
return dependencies == null ? ImmutableList.of() : dependencies;
|
||||
}
|
||||
|
||||
public List<String> getProvides() {
|
||||
return provides == null ? ImmutableList.of() : provides;
|
||||
}
|
||||
|
||||
public String getMain() {
|
||||
return main;
|
||||
}
|
||||
@@ -112,12 +120,13 @@ public final class SerializedPluginDescription {
|
||||
&& Objects.equals(url, that.url)
|
||||
&& Objects.equals(authors, that.authors)
|
||||
&& Objects.equals(dependencies, that.dependencies)
|
||||
&& Objects.equals(provides, that.provides)
|
||||
&& Objects.equals(main, that.main);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id, name, version, description, url, authors, dependencies);
|
||||
return Objects.hash(id, name, version, description, url, authors, dependencies, provides);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -130,6 +139,7 @@ public final class SerializedPluginDescription {
|
||||
+ ", url='" + url + '\''
|
||||
+ ", authors=" + authors
|
||||
+ ", dependencies=" + dependencies
|
||||
+ ", provides=" + provides
|
||||
+ ", main='" + main + '\''
|
||||
+ '}';
|
||||
}
|
||||
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2026 Velocity Contributors
|
||||
*
|
||||
* The Velocity API is licensed under the terms of the MIT License. For more details,
|
||||
* reference the LICENSE file in the api top-level directory.
|
||||
*/
|
||||
|
||||
package com.velocitypowered.api.event.player;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.velocitypowered.api.proxy.Player;
|
||||
|
||||
/**
|
||||
* Called when a player is marked as loaded by the client.
|
||||
*
|
||||
* <p>This event is fired once per {@link com.velocitypowered.api.proxy.ServerConnection}
|
||||
* when the player explicitly notifies the server after loading the world (closing the downloading terrain screen)
|
||||
*
|
||||
* @implNote Unlike Paper this event will <u>not</u> fire due to a timeout nor respawning.
|
||||
* Though plugins can implement a timeout by scheduling a task in {@link ServerPostConnectEvent}
|
||||
* and checking {@link com.velocitypowered.api.proxy.ServerConnection#isClientLoaded()}.
|
||||
* @sinceMinecraft 1.21.4
|
||||
* @since 4.1.0
|
||||
*/
|
||||
@Beta
|
||||
public final class PlayerClientLoadedWorldEvent {
|
||||
|
||||
private final Player player;
|
||||
|
||||
public PlayerClientLoadedWorldEvent(Player player) {
|
||||
this.player = Preconditions.checkNotNull(player, "player");
|
||||
}
|
||||
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PlayerClientLoadedWorldEvent{"
|
||||
+ "player=" + player
|
||||
+ '}';
|
||||
}
|
||||
}
|
||||
@@ -72,4 +72,12 @@ public @interface Plugin {
|
||||
* @return the plugin dependencies
|
||||
*/
|
||||
Dependency[] dependencies() default {};
|
||||
|
||||
/**
|
||||
* The plugin IDs this plugin "provides" for. Each ID must match
|
||||
* {@link SerializedPluginDescription#ID_PATTERN_STRING}.
|
||||
*
|
||||
* @return the provided IDs
|
||||
*/
|
||||
String[] provides() default {};
|
||||
}
|
||||
|
||||
@@ -100,6 +100,16 @@ public interface PluginDescription {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a {@link Collection} of the provided IDs of the {@link Plugin} within this container.
|
||||
*
|
||||
* @return the provided plugins IDs, can be empty
|
||||
* @see Plugin#provides()
|
||||
*/
|
||||
default Collection<String> getProvidedIds() {
|
||||
return ImmutableSet.of();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the source the plugin was loaded from.
|
||||
*
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
package com.velocitypowered.api.proxy;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.velocitypowered.api.proxy.messages.ChannelMessageSink;
|
||||
import com.velocitypowered.api.proxy.messages.ChannelMessageSource;
|
||||
import com.velocitypowered.api.proxy.server.RegisteredServer;
|
||||
@@ -40,6 +41,17 @@ public interface ServerConnection extends ChannelMessageSource, ChannelMessageSi
|
||||
*/
|
||||
ServerInfo getServerInfo();
|
||||
|
||||
/**
|
||||
* Returns whether the client notified this connection of having loaded the world.
|
||||
*
|
||||
* @return true if the client has loaded the world
|
||||
* @implNote This is purely client-dependent; see {@link com.velocitypowered.api.event.player.PlayerClientLoadedWorldEvent}.
|
||||
* @sinceMinecraft 1.21.4
|
||||
* @since 4.1.0
|
||||
*/
|
||||
@Beta
|
||||
boolean isClientLoaded();
|
||||
|
||||
/**
|
||||
* Returns the player that this connection is associated with.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user