13
0
geforkt von Mirrors/Velocity

Initial commit of adventure-adapted Velocity API.

Dieser Commit ist enthalten in:
Andrew Steinborn 2020-06-28 21:23:01 -04:00
Ursprung 7fd76962f2
Commit 2e7a598916
53 geänderte Dateien mit 728 neuen und 184 gelöschten Zeilen

Datei anzeigen

@ -18,10 +18,18 @@ sourceSets {
dependencies { dependencies {
compile 'com.google.code.gson:gson:2.8.5' compile 'com.google.code.gson:gson:2.8.5'
compile "com.google.guava:guava:${guavaVersion}" compile "com.google.guava:guava:${guavaVersion}"
// DEPRECATED: Will be removed in Velocity 2.0.0
compile "net.kyori:text-api:${textVersion}" compile "net.kyori:text-api:${textVersion}"
compile "net.kyori:text-serializer-gson:${textVersion}" compile "net.kyori:text-serializer-gson:${textVersion}"
compile "net.kyori:text-serializer-legacy:${textVersion}" compile "net.kyori:text-serializer-legacy:${textVersion}"
compile "net.kyori:text-serializer-plain:${textVersion}" compile "net.kyori:text-serializer-plain:${textVersion}"
compile "net.kyori:adventure-api:${adventureVersion}"
compile "net.kyori:adventure-text-serializer-gson:${adventureVersion}"
compile "net.kyori:adventure-text-serializer-legacy:${adventureVersion}"
compile "net.kyori:adventure-text-serializer-plain:${adventureVersion}"
compile 'com.moandjiezana.toml:toml4j:0.7.2' compile 'com.moandjiezana.toml:toml4j:0.7.2'
compile "org.slf4j:slf4j-api:${slf4jVersion}" compile "org.slf4j:slf4j-api:${slf4jVersion}"
compile 'com.google.inject:guice:4.2.3' compile 'com.google.inject:guice:4.2.3'

Datei anzeigen

@ -1,17 +1,20 @@
package com.velocitypowered.api.command; package com.velocitypowered.api.command;
import com.velocitypowered.api.permission.PermissionSubject; import com.velocitypowered.api.permission.PermissionSubject;
import net.kyori.text.Component; import com.velocitypowered.api.proxy.ProxyAudience;
import net.kyori.adventure.text.Component;
/** /**
* Represents something that can be used to run a {@link Command}. * Represents something that can be used to run a {@link Command}.
*/ */
public interface CommandSource extends PermissionSubject { public interface CommandSource extends PermissionSubject, ProxyAudience {
/** /**
* Sends the specified {@code component} to the invoker. * Sends the specified {@code component} to the invoker.
* *
* @param component the text component to send * @param component the text component to send
* @deprecated Use {@link #sendMessage(Component)} instead
*/ */
void sendMessage(Component component); @Deprecated
void sendMessage(net.kyori.text.Component component);
} }

Datei anzeigen

@ -1,9 +1,10 @@
package com.velocitypowered.api.event; package com.velocitypowered.api.event;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.velocitypowered.api.util.AdventureCompat;
import java.util.Optional; import java.util.Optional;
import net.kyori.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.text.serializer.plain.PlainComponentSerializer; import net.kyori.adventure.text.serializer.plain.PlainComponentSerializer;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
/** /**
@ -92,7 +93,11 @@ public interface ResultedEvent<R extends ResultedEvent.Result> {
return status; return status;
} }
public Optional<Component> getReason() { public Optional<net.kyori.text.Component> getReason() {
return Optional.ofNullable(reason).map(AdventureCompat::asOriginalTextComponent);
}
public Optional<Component> getReasonComponent() {
return Optional.ofNullable(reason); return Optional.ofNullable(reason);
} }
@ -115,5 +120,11 @@ public interface ResultedEvent<R extends ResultedEvent.Result> {
Preconditions.checkNotNull(reason, "reason"); Preconditions.checkNotNull(reason, "reason");
return new ComponentResult(false, reason); return new ComponentResult(false, reason);
} }
@Deprecated
public static ComponentResult denied(net.kyori.text.Component reason) {
Preconditions.checkNotNull(reason, "reason");
return new ComponentResult(false, AdventureCompat.asAdventureComponent(reason));
}
} }
} }

Datei anzeigen

@ -3,8 +3,8 @@ package com.velocitypowered.api.event.connection;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.velocitypowered.api.event.ResultedEvent; import com.velocitypowered.api.event.ResultedEvent;
import com.velocitypowered.api.proxy.InboundConnection; import com.velocitypowered.api.proxy.InboundConnection;
import com.velocitypowered.api.util.AdventureCompat;
import java.util.Optional; import java.util.Optional;
import net.kyori.text.Component;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
@ -71,9 +71,10 @@ public final class PreLoginEvent implements ResultedEvent<PreLoginEvent.PreLogin
Result.FORCE_OFFLINE, null); Result.FORCE_OFFLINE, null);
private final Result result; private final Result result;
private final @Nullable Component reason; private final net.kyori.adventure.text.Component reason;
private PreLoginComponentResult(Result result, @Nullable Component reason) { private PreLoginComponentResult(Result result,
net.kyori.adventure.text.@Nullable Component reason) {
this.result = result; this.result = result;
this.reason = reason; this.reason = reason;
} }
@ -83,7 +84,12 @@ public final class PreLoginEvent implements ResultedEvent<PreLoginEvent.PreLogin
return result != Result.DISALLOWED; return result != Result.DISALLOWED;
} }
public Optional<Component> getReason() { @Deprecated
public Optional<net.kyori.text.Component> getReason() {
return Optional.ofNullable(reason).map(AdventureCompat::asOriginalTextComponent);
}
public Optional<net.kyori.adventure.text.Component> getReasonComponent() {
return Optional.ofNullable(reason); return Optional.ofNullable(reason);
} }
@ -143,9 +149,23 @@ public final class PreLoginEvent implements ResultedEvent<PreLoginEvent.PreLogin
* Denies the login with the specified reason. * Denies the login with the specified reason.
* *
* @param reason the reason for disallowing the connection * @param reason the reason for disallowing the connection
* @deprecated Use {@link #denied(net.kyori.adventure.text.Component)}
* @return a new result * @return a new result
*/ */
public static PreLoginComponentResult denied(Component reason) { @Deprecated
public static PreLoginComponentResult denied(net.kyori.text.Component reason) {
Preconditions.checkNotNull(reason, "reason");
return new PreLoginComponentResult(Result.DISALLOWED,
AdventureCompat.asAdventureComponent(reason));
}
/**
* Denies the login with the specified reason.
*
* @param reason the reason for disallowing the connection
* @return a new result
*/
public static PreLoginComponentResult denied(net.kyori.adventure.text.Component reason) {
Preconditions.checkNotNull(reason, "reason"); Preconditions.checkNotNull(reason, "reason");
return new PreLoginComponentResult(Result.DISALLOWED, reason); return new PreLoginComponentResult(Result.DISALLOWED, reason);
} }

Datei anzeigen

@ -4,6 +4,7 @@ import com.google.common.base.Preconditions;
import com.velocitypowered.api.event.ResultedEvent; import com.velocitypowered.api.event.ResultedEvent;
import com.velocitypowered.api.proxy.Player; import com.velocitypowered.api.proxy.Player;
import com.velocitypowered.api.proxy.server.RegisteredServer; import com.velocitypowered.api.proxy.server.RegisteredServer;
import com.velocitypowered.api.util.AdventureCompat;
import java.util.Optional; import java.util.Optional;
import net.kyori.text.Component; import net.kyori.text.Component;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
@ -20,7 +21,7 @@ public final class KickedFromServerEvent implements
private final Player player; private final Player player;
private final RegisteredServer server; private final RegisteredServer server;
private final @Nullable Component originalReason; private final net.kyori.adventure.text.Component originalReason;
private final boolean duringServerConnect; private final boolean duringServerConnect;
private ServerKickResult result; private ServerKickResult result;
@ -34,11 +35,7 @@ public final class KickedFromServerEvent implements
*/ */
public KickedFromServerEvent(Player player, RegisteredServer server, public KickedFromServerEvent(Player player, RegisteredServer server,
@Nullable Component originalReason, boolean duringServerConnect, Component fancyReason) { @Nullable Component originalReason, boolean duringServerConnect, Component fancyReason) {
this.player = Preconditions.checkNotNull(player, "player"); this(player, server, originalReason, duringServerConnect, Notify.create(fancyReason));
this.server = Preconditions.checkNotNull(server, "server");
this.originalReason = originalReason;
this.duringServerConnect = duringServerConnect;
this.result = new Notify(fancyReason);
} }
/** /**
@ -53,6 +50,21 @@ public final class KickedFromServerEvent implements
RegisteredServer server, RegisteredServer server,
@Nullable Component originalReason, boolean duringServerConnect, @Nullable Component originalReason, boolean duringServerConnect,
ServerKickResult result) { ServerKickResult result) {
this(player, server, AdventureCompat.asAdventureComponent(originalReason), duringServerConnect,
result);
}
/**
* Creates a {@code KickedFromServerEvent} instance.
* @param player the player affected
* @param server the server the player disconnected from
* @param originalReason the reason for being kicked, optional
* @param duringServerConnect whether or not the player was kicked during the connection process
* @param result the initial result
*/
public KickedFromServerEvent(Player player, RegisteredServer server,
net.kyori.adventure.text.Component originalReason,
boolean duringServerConnect, ServerKickResult result) {
this.player = Preconditions.checkNotNull(player, "player"); this.player = Preconditions.checkNotNull(player, "player");
this.server = Preconditions.checkNotNull(server, "server"); this.server = Preconditions.checkNotNull(server, "server");
this.originalReason = originalReason; this.originalReason = originalReason;
@ -78,7 +90,17 @@ public final class KickedFromServerEvent implements
return server; return server;
} }
/**
* Gets the reason the server kicked the player from the server.
* @return the server kicked the player from the server
* @deprecated Use {@link #getServerKickReason()} instead
*/
@Deprecated
public Optional<Component> getOriginalReason() { public Optional<Component> getOriginalReason() {
return Optional.ofNullable(originalReason).map(AdventureCompat::asOriginalTextComponent);
}
public Optional<net.kyori.adventure.text.Component> getServerKickReason() {
return Optional.ofNullable(originalReason); return Optional.ofNullable(originalReason);
} }
@ -115,9 +137,9 @@ public final class KickedFromServerEvent implements
*/ */
public static final class DisconnectPlayer implements ServerKickResult { public static final class DisconnectPlayer implements ServerKickResult {
private final Component component; private final net.kyori.adventure.text.Component component;
private DisconnectPlayer(Component component) { private DisconnectPlayer(net.kyori.adventure.text.Component component) {
this.component = Preconditions.checkNotNull(component, "component"); this.component = Preconditions.checkNotNull(component, "component");
} }
@ -126,7 +148,12 @@ public final class KickedFromServerEvent implements
return true; return true;
} }
@Deprecated
public Component getReason() { public Component getReason() {
return AdventureCompat.asOriginalTextComponent(component);
}
public net.kyori.adventure.text.Component getReasonComponent() {
return component; return component;
} }
@ -135,8 +162,20 @@ public final class KickedFromServerEvent implements
* *
* @param reason the reason to use when disconnecting the player * @param reason the reason to use when disconnecting the player
* @return the disconnect result * @return the disconnect result
* @deprecated Use {@link #create(net.kyori.adventure.text.Component)} instead
*/ */
@Deprecated
public static DisconnectPlayer create(Component reason) { public static DisconnectPlayer create(Component reason) {
return new DisconnectPlayer(AdventureCompat.asAdventureComponent(reason));
}
/**
* Creates a new {@link DisconnectPlayer} with the specified reason.
*
* @param reason the reason to use when disconnecting the player
* @return the disconnect result
*/
public static DisconnectPlayer create(net.kyori.adventure.text.Component reason) {
return new DisconnectPlayer(reason); return new DisconnectPlayer(reason);
} }
} }
@ -147,10 +186,10 @@ public final class KickedFromServerEvent implements
*/ */
public static final class RedirectPlayer implements ServerKickResult { public static final class RedirectPlayer implements ServerKickResult {
private final Component message; private final net.kyori.adventure.text.Component message;
private final RegisteredServer server; private final RegisteredServer server;
private RedirectPlayer(RegisteredServer server, @Nullable Component message) { private RedirectPlayer(RegisteredServer server, net.kyori.adventure.text.Component message) {
this.server = Preconditions.checkNotNull(server, "server"); this.server = Preconditions.checkNotNull(server, "server");
this.message = message; this.message = message;
} }
@ -164,8 +203,12 @@ public final class KickedFromServerEvent implements
return server; return server;
} }
@Nullable @Deprecated
public Component getMessage() { public Component getMessage() {
return AdventureCompat.asOriginalTextComponent(message);
}
public net.kyori.adventure.text.Component getMessageComponent() {
return message; return message;
} }
@ -174,13 +217,29 @@ public final class KickedFromServerEvent implements
* *
* @param server the server to send the player to * @param server the server to send the player to
* @return the redirect result * @return the redirect result
* @deprecated Use {@link #create(RegisteredServer, net.kyori.adventure.text.Component)}
*/ */
public static RedirectPlayer create(RegisteredServer server, @Nullable Component message) { @Deprecated
public static RedirectPlayer create(RegisteredServer server, net.kyori.text.Component message) {
if (message == null) {
return new RedirectPlayer(server, null);
}
return new RedirectPlayer(server, AdventureCompat.asAdventureComponent(message));
}
/**
* Creates a new redirect result to forward the player to the specified {@code server}.
*
* @param server the server to send the player to
* @return the redirect result
*/
public static RedirectPlayer create(RegisteredServer server,
net.kyori.adventure.text.Component message) {
return new RedirectPlayer(server, message); return new RedirectPlayer(server, message);
} }
public static ServerKickResult create(RegisteredServer server) { public static ServerKickResult create(RegisteredServer server) {
return create(server, null); return new RedirectPlayer(server, null);
} }
} }
@ -191,9 +250,10 @@ public final class KickedFromServerEvent implements
*/ */
public static final class Notify implements ServerKickResult { public static final class Notify implements ServerKickResult {
private final Component message; private final net.kyori.adventure.text.Component message;
private Notify(Component message) { @Deprecated
private Notify(net.kyori.adventure.text.Component message) {
this.message = Preconditions.checkNotNull(message, "message"); this.message = Preconditions.checkNotNull(message, "message");
} }
@ -202,7 +262,13 @@ public final class KickedFromServerEvent implements
return false; return false;
} }
@Deprecated
public Component getMessage() { public Component getMessage() {
return AdventureCompat.asOriginalTextComponent(message);
}
@Deprecated
public net.kyori.adventure.text.Component getMessageComponent() {
return message; return message;
} }
@ -211,8 +277,20 @@ public final class KickedFromServerEvent implements
* *
* @param message the server to send the player to * @param message the server to send the player to
* @return the redirect result * @return the redirect result
* @deprecated Use {@link #create(net.kyori.adventure.text.Component)} instead
*/ */
@Deprecated
public static Notify create(Component message) { public static Notify create(Component message) {
return new Notify(AdventureCompat.asAdventureComponent(message));
}
/**
* Notifies the player with the specified message but does nothing else.
*
* @param message the server to send the player to
* @return the redirect result
*/
public static Notify create(net.kyori.adventure.text.Component message) {
return new Notify(message); return new Notify(message);
} }
} }

Datei anzeigen

@ -67,9 +67,18 @@ public interface ConnectionRequestBuilder {
* Returns an (optional) textual reason for the failure to connect to the server. * Returns an (optional) textual reason for the failure to connect to the server.
* *
* @return the reason why the user could not connect to the server * @return the reason why the user could not connect to the server
* @deprecated Use {@link #getReasonComponent()} instead
*/ */
@Deprecated
Optional<Component> getReason(); Optional<Component> getReason();
/**
* Returns an (optional) textual reason for the failure to connect to the server.
*
* @return the reason why the user could not connect to the server
*/
Optional<net.kyori.adventure.text.Component> getReasonComponent();
/** /**
* Returns the server we actually tried to connect to. * Returns the server we actually tried to connect to.
* *

Datei anzeigen

@ -14,7 +14,7 @@ import com.velocitypowered.api.util.title.Title;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.UUID; import java.util.UUID;
import net.kyori.text.Component; import net.kyori.adventure.text.Component;
/** /**
* Represents a player who is connected to the proxy. * Represents a player who is connected to the proxy.
@ -76,9 +76,11 @@ public interface Player extends CommandSource, InboundConnection, ChannelMessage
* Sends a chat message to the player's client. * Sends a chat message to the player's client.
* *
* @param component the chat message to send * @param component the chat message to send
* @deprecated Use {@link #sendMessage(net.kyori.adventure.text.Component)}
*/ */
@Deprecated
@Override @Override
default void sendMessage(Component component) { default void sendMessage(net.kyori.text.Component component) {
sendMessage(component, MessagePosition.CHAT); sendMessage(component, MessagePosition.CHAT);
} }
@ -87,8 +89,11 @@ public interface Player extends CommandSource, InboundConnection, ChannelMessage
* *
* @param component the chat message to send * @param component the chat message to send
* @param position the position for the message * @param position the position for the message
* @deprecated Use @deprecated Use {@link #sendMessage(net.kyori.adventure.text.Component)} or
* {@link #sendActionBar(net.kyori.adventure.text.Component)}
*/ */
void sendMessage(Component component, MessagePosition position); @Deprecated
void sendMessage(net.kyori.text.Component component, MessagePosition position);
/** /**
* Creates a new connection request so that the player can connect to another server. * Creates a new connection request so that the player can connect to another server.
@ -127,7 +132,7 @@ public interface Player extends CommandSource, InboundConnection, ChannelMessage
* @deprecated Use {@link TabList#setHeaderAndFooter(Component, Component)}. * @deprecated Use {@link TabList#setHeaderAndFooter(Component, Component)}.
*/ */
@Deprecated @Deprecated
void setHeaderAndFooter(Component header, Component footer); void setHeaderAndFooter(net.kyori.text.Component header, net.kyori.text.Component footer);
/** /**
* Clears the tab list header and footer for the player. * Clears the tab list header and footer for the player.
@ -149,14 +154,26 @@ public interface Player extends CommandSource, InboundConnection, ChannelMessage
* other {@link Player} methods will become undefined. * other {@link Player} methods will become undefined.
* *
* @param reason component with the reason * @param reason component with the reason
* @deprecated Use {@link #disconnect(Component)} instead
*/ */
void disconnect(Component reason); @Deprecated
void disconnect(net.kyori.text.Component reason);
/**
* Disconnects the player with the specified reason. Once this method is called, further calls to
* other {@link Player} methods will become undefined.
*
* @param reason component with the reason
*/
void disconnect(net.kyori.adventure.text.Component reason);
/** /**
* Sends the specified title to the client. * Sends the specified title to the client.
* *
* @param title the title to send * @param title the title to send
* @deprecated Use {@link #showTitle(net.kyori.adventure.title.Title)} and {@link #resetTitle()}
*/ */
@Deprecated
void sendTitle(Title title); void sendTitle(Title title);
/** /**

Datei anzeigen

@ -0,0 +1,71 @@
package com.velocitypowered.api.proxy;
import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.bossbar.BossBar;
import net.kyori.adventure.inventory.Book;
import net.kyori.adventure.sound.Sound;
import net.kyori.adventure.sound.SoundStop;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.title.Title;
import org.checkerframework.checker.nullness.qual.NonNull;
/**
* Indicates an {@link Audience} that is on the proxy. This interface contains no-op default methods
* that are used to bridge compatibility issues with the new adventure API. This interface will go
* away in Velocity 2.0.0.
*/
public interface ProxyAudience extends Audience {
@Override
void sendMessage(@NonNull Component message);
@Override
default void sendActionBar(@NonNull Component message) {
}
@Override
default void showTitle(@NonNull Title title) {
}
@Override
default void clearTitle() {
}
@Override
default void resetTitle() {
}
@Override
default void showBossBar(@NonNull BossBar bar) {
}
@Override
default void hideBossBar(@NonNull BossBar bar) {
}
@Override
default void playSound(@NonNull Sound sound) {
}
@Override
default void playSound(@NonNull Sound sound, double x, double y, double z) {
}
@Override
default void stopSound(@NonNull SoundStop stop) {
}
@Override
default void openBook(@NonNull Book book) {
}
}

Datei anzeigen

@ -17,13 +17,13 @@ import java.net.InetSocketAddress;
import java.util.Collection; import java.util.Collection;
import java.util.Optional; import java.util.Optional;
import java.util.UUID; import java.util.UUID;
import net.kyori.text.Component; import net.kyori.adventure.text.Component;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
/** /**
* Provides an interface to a Minecraft server proxy. * Provides an interface to a Minecraft server proxy.
*/ */
public interface ProxyServer { public interface ProxyServer extends ProxyAudience {
/** /**
* Retrieves the player currently connected to this proxy by their Minecraft username. The search * Retrieves the player currently connected to this proxy by their Minecraft username. The search
@ -46,8 +46,10 @@ public interface ProxyServer {
* Broadcasts a message to all players currently online. * Broadcasts a message to all players currently online.
* *
* @param component the message to send * @param component the message to send
* @deprecated Use {@link #sendMessage(Component)} instead
*/ */
void broadcast(Component component); @Deprecated
void broadcast(net.kyori.text.Component component);
/** /**
* Retrieves all players currently connected to this proxy. This call may or may not be a snapshot * Retrieves all players currently connected to this proxy. This call may or may not be a snapshot
@ -186,8 +188,10 @@ public interface ProxyServer {
* @param overlay boss bar overlay * @param overlay boss bar overlay
* @param progress boss bar progress * @param progress boss bar progress
* @return a completely new and fresh boss bar * @return a completely new and fresh boss bar
* @deprecated Use {@link net.kyori.adventure.bossbar.BossBar} instead
*/ */
@Deprecated
@NonNull @NonNull
BossBar createBossBar(@NonNull Component title, @NonNull BossBarColor color, BossBar createBossBar(net.kyori.text.Component title, @NonNull BossBarColor color,
@NonNull BossBarOverlay overlay, float progress); @NonNull BossBarOverlay overlay, float progress);
} }

Datei anzeigen

@ -5,7 +5,6 @@ import com.velocitypowered.api.util.Favicon;
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 net.kyori.text.Component;
/** /**
* Exposes certain proxy configuration information that plugins may use. * Exposes certain proxy configuration information that plugins may use.
@ -44,8 +43,17 @@ public interface ProxyConfig {
* Get the MOTD component shown in the tab list. * Get the MOTD component shown in the tab list.
* *
* @return the motd component * @return the motd component
* @deprecated Use {@link #getMotd()} instead
*/ */
Component getMotdComponent(); @Deprecated
net.kyori.text.Component getMotdComponent();
/**
* Get the MOTD component shown in the tab list.
*
* @return the motd component
*/
net.kyori.adventure.text.Component getMotd();
/** /**
* Get the maximum players shown in the tab list. * Get the maximum players shown in the tab list.

Datei anzeigen

@ -5,7 +5,7 @@ import com.velocitypowered.api.util.GameProfile;
import java.util.Collection; import java.util.Collection;
import java.util.Optional; import java.util.Optional;
import java.util.UUID; import java.util.UUID;
import net.kyori.text.Component; import net.kyori.adventure.text.Component;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
/** /**
@ -13,6 +13,16 @@ import org.checkerframework.checker.nullness.qual.Nullable;
*/ */
public interface TabList { public interface TabList {
/**
* Sets the tab list header and footer for the player.
*
* @param header the header component
* @param footer the footer component
* @deprecated Use {@link #setHeaderAndFooter(Component, Component)} instead
*/
@Deprecated
void setHeaderAndFooter(net.kyori.text.Component header, net.kyori.text.Component footer);
/** /**
* Sets the tab list header and footer for the player. * Sets the tab list header and footer for the player.
* *

Datei anzeigen

@ -1,8 +1,9 @@
package com.velocitypowered.api.proxy.player; package com.velocitypowered.api.proxy.player;
import com.velocitypowered.api.util.AdventureCompat;
import com.velocitypowered.api.util.GameProfile; import com.velocitypowered.api.util.GameProfile;
import java.util.Optional; import java.util.Optional;
import net.kyori.text.Component; import net.kyori.adventure.text.Component;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
/** /**
@ -27,12 +28,35 @@ public interface TabListEntry {
GameProfile getProfile(); GameProfile getProfile();
/** /**
* Returns {@link Optional} text {@link Component}, which if present is the text displayed for * Returns {@link Optional} text {@link net.kyori.text.Component}, which if present is the text
* {@code this} entry in the {@link TabList}, otherwise {@link GameProfile#getName()} is shown. * displayed for {@code this} entry in the {@link TabList}, otherwise
* {@link GameProfile#getName()} is shown.
*
* @return {@link Optional} text {@link net.kyori.text.Component} of name displayed in the tab
* list
* *
* @return {@link Optional} text {@link Component} of name displayed in the tab list
*/ */
Optional<Component> getDisplayName(); Optional<net.kyori.text.Component> getDisplayName();
/**
* Returns {@link Optional} text {@link net.kyori.text.Component}, which if present is the text
* displayed for {@code this} entry in the {@link TabList}, otherwise
* {@link GameProfile#getName()} is shown.
*
* @return {@link Optional} text {@link net.kyori.text.Component} of name displayed in the tab
* list
*/
Optional<Component> getDisplayNameComponent();
/**
* Sets the text {@link net.kyori.text.Component} to be displayed for {@code this}
* {@link TabListEntry}. If {@code null}, {@link GameProfile#getName()} will be shown.
*
* @param displayName to show in the {@link TabList} for {@code this} entry
* @return {@code this}, for chaining
* @deprecated Use {@link #setDisplayName(Component)} instead
*/
TabListEntry setDisplayName(net.kyori.text.Component displayName);
/** /**
* Sets the text {@link Component} to be displayed for {@code this} {@link TabListEntry}. If * Sets the text {@link Component} to be displayed for {@code this} {@link TabListEntry}. If
@ -149,6 +173,19 @@ public interface TabListEntry {
* @param displayName to set * @param displayName to set
* @return {@code this}, for chaining * @return {@code this}, for chaining
* @see TabListEntry#getDisplayName() * @see TabListEntry#getDisplayName()
* @deprecated Use {@link #displayName(Component)} instead
*/
@Deprecated
public Builder displayName(net.kyori.text.Component displayName) {
return displayName(AdventureCompat.asAdventureComponent(displayName));
}
/**
* Sets the displayed name of the {@link TabListEntry}.
*
* @param displayName to set
* @return {@code this}, for chaining
* @see TabListEntry#getDisplayNameComponent() ()
*/ */
public Builder displayName(@Nullable Component displayName) { public Builder displayName(@Nullable Component displayName) {
this.displayName = displayName; this.displayName = displayName;

Datei anzeigen

@ -49,7 +49,7 @@ public final class QueryResponse {
/** /**
* Get hostname which will be used to reply to the query. By default it is {@link * Get hostname which will be used to reply to the query. By default it is {@link
* ProxyConfig#getMotdComponent()} in plain text without colour codes. * ProxyConfig#getMotd()} in plain text without colour codes.
* *
* @return hostname * @return hostname
*/ */

Datei anzeigen

@ -1,14 +1,17 @@
package com.velocitypowered.api.proxy.server; package com.velocitypowered.api.proxy.server;
import com.velocitypowered.api.proxy.Player; import com.velocitypowered.api.proxy.Player;
import com.velocitypowered.api.proxy.ProxyAudience;
import com.velocitypowered.api.proxy.messages.ChannelMessageSink; import com.velocitypowered.api.proxy.messages.ChannelMessageSink;
import java.util.Collection; import java.util.Collection;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
/** /**
* Represents a server that has been registered with the proxy. * Represents a server that has been registered with the proxy. The {@code Audience} associated with
* a {@code RegisteredServer} represent all players on the server connected to this proxy and do not
* interact with the server in any way.
*/ */
public interface RegisteredServer extends ChannelMessageSink { public interface RegisteredServer extends ChannelMessageSink, ProxyAudience {
/** /**
* Returns the {@link ServerInfo} for this server. * Returns the {@link ServerInfo} for this server.

Datei anzeigen

@ -3,6 +3,7 @@ package com.velocitypowered.api.proxy.server;
import com.google.common.base.MoreObjects; import com.google.common.base.MoreObjects;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.velocitypowered.api.util.AdventureCompat;
import com.velocitypowered.api.util.Favicon; import com.velocitypowered.api.util.Favicon;
import com.velocitypowered.api.util.ModInfo; import com.velocitypowered.api.util.ModInfo;
import java.util.ArrayList; import java.util.ArrayList;
@ -12,7 +13,6 @@ import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import java.util.UUID; import java.util.UUID;
import net.kyori.text.Component;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
/** /**
@ -22,12 +22,19 @@ public final class ServerPing {
private final Version version; private final Version version;
private final @Nullable Players players; private final @Nullable Players players;
private final Component description; private final net.kyori.adventure.text.Component description;
private final @Nullable Favicon favicon; private final @Nullable Favicon favicon;
private final @Nullable ModInfo modinfo; private final @Nullable ModInfo modinfo;
public ServerPing(Version version, @Nullable Players players, Component description, @Deprecated
@Nullable Favicon favicon) { public ServerPing(Version version, @Nullable Players players,
net.kyori.text.Component description, @Nullable Favicon favicon) {
this(version, players, AdventureCompat.asAdventureComponent(description), favicon,
ModInfo.DEFAULT);
}
public ServerPing(Version version, @Nullable Players players,
net.kyori.adventure.text.Component description, @Nullable Favicon favicon) {
this(version, players, description, favicon, ModInfo.DEFAULT); this(version, players, description, favicon, ModInfo.DEFAULT);
} }
@ -40,8 +47,25 @@ public final class ServerPing {
* @param favicon the server's favicon * @param favicon the server's favicon
* @param modinfo the mods this server runs * @param modinfo the mods this server runs
*/ */
public ServerPing(Version version, @Nullable Players players, Component description, @Deprecated
@Nullable Favicon favicon, @Nullable ModInfo modinfo) { public ServerPing(Version version, @Nullable Players players,
net.kyori.text.Component description, @Nullable Favicon favicon,
@Nullable ModInfo modinfo) {
this(version, players, AdventureCompat.asAdventureComponent(description), favicon, modinfo);
}
/**
* Constructs a ServerPing instance.
*
* @param version the version of the server
* @param players the players on the server
* @param description the MOTD for the server
* @param favicon the server's favicon
* @param modinfo the mods this server runs
*/
public ServerPing(Version version, @Nullable Players players,
net.kyori.adventure.text.Component description, @Nullable Favicon favicon,
@Nullable ModInfo modinfo) {
this.version = Preconditions.checkNotNull(version, "version"); this.version = Preconditions.checkNotNull(version, "version");
this.players = players; this.players = players;
this.description = Preconditions.checkNotNull(description, "description"); this.description = Preconditions.checkNotNull(description, "description");
@ -57,7 +81,12 @@ public final class ServerPing {
return Optional.ofNullable(players); return Optional.ofNullable(players);
} }
public Component getDescription() { @Deprecated
public net.kyori.text.Component getDescription() {
return AdventureCompat.asOriginalTextComponent(description);
}
public net.kyori.adventure.text.Component getDescriptionComponent() {
return description; return description;
} }
@ -143,7 +172,7 @@ public final class ServerPing {
private final List<SamplePlayer> samplePlayers = new ArrayList<>(); private final List<SamplePlayer> samplePlayers = new ArrayList<>();
private String modType = "FML"; private String modType = "FML";
private final List<ModInfo.Mod> mods = new ArrayList<>(); private final List<ModInfo.Mod> mods = new ArrayList<>();
private @Nullable Component description; private net.kyori.adventure.text.Component description;
private @Nullable Favicon favicon; private @Nullable Favicon favicon;
private boolean nullOutPlayers; private boolean nullOutPlayers;
private boolean nullOutModinfo; private boolean nullOutModinfo;
@ -215,7 +244,13 @@ public final class ServerPing {
return this; return this;
} }
public Builder description(Component description) { @Deprecated
public Builder description(net.kyori.text.Component description) {
this.description(AdventureCompat.asAdventureComponent(description));
return this;
}
public Builder description(net.kyori.adventure.text.Component description) {
this.description = Preconditions.checkNotNull(description, "description"); this.description = Preconditions.checkNotNull(description, "description");
return this; return this;
} }
@ -258,7 +293,11 @@ public final class ServerPing {
return samplePlayers; return samplePlayers;
} }
public Optional<Component> getDescription() { public Optional<net.kyori.text.Component> getDescription() {
return Optional.ofNullable(description).map(AdventureCompat::asOriginalTextComponent);
}
public Optional<net.kyori.adventure.text.Component> getDescriptionComponent() {
return Optional.ofNullable(description); return Optional.ofNullable(description);
} }

Datei anzeigen

@ -0,0 +1,29 @@
package com.velocitypowered.api.util;
/**
* Utilities to convert from adventure {@link net.kyori.adventure.text.Component}s to text
* {@link net.kyori.text.Component}s and vice versa.
*
* @deprecated Provided only as a transitional aid, will be removed in Velocity 2.0.0
*/
@Deprecated
public class AdventureCompat {
private AdventureCompat() {
throw new AssertionError("Do not create instances of this class.");
}
public static net.kyori.adventure.text.Component asAdventureComponent(
net.kyori.text.Component component) {
String json = net.kyori.text.serializer.gson.GsonComponentSerializer.INSTANCE
.serialize(component);
return net.kyori.adventure.text.serializer.gson.GsonComponentSerializer.gson()
.deserialize(json);
}
public static net.kyori.text.Component asOriginalTextComponent(
net.kyori.adventure.text.Component component) {
String json = net.kyori.adventure.text.serializer.gson.GsonComponentSerializer
.colorDownsamplingGson().serialize(component);
return net.kyori.text.serializer.gson.GsonComponentSerializer.INSTANCE.deserialize(json);
}
}

Datei anzeigen

@ -7,7 +7,10 @@ import net.kyori.text.Component;
/** /**
* Represents a boss bar, which can be send to a (group of) player(s). * Represents a boss bar, which can be send to a (group of) player(s).
* <b>Boss bars only work on 1.9 and above.</b> * <b>Boss bars only work on 1.9 and above.</b>
*
* @deprecated Replaced with {@link net.kyori.adventure.bossbar.BossBar}
*/ */
@Deprecated
public interface BossBar { public interface BossBar {
/** /**

Datei anzeigen

@ -2,7 +2,10 @@ package com.velocitypowered.api.util.bossbar;
/** /**
* Represents a color of a {@link BossBar}. * Represents a color of a {@link BossBar}.
*
* @deprecated Replaced with {@link net.kyori.adventure.bossbar.BossBar.Color}
*/ */
@Deprecated
public enum BossBarColor { public enum BossBarColor {
PINK, PINK,
BLUE, BLUE,

Datei anzeigen

@ -2,7 +2,10 @@ package com.velocitypowered.api.util.bossbar;
/** /**
* Represents any {@link BossBar}'s flags. * Represents any {@link BossBar}'s flags.
*
* @deprecated Replaced with {@link net.kyori.adventure.bossbar.BossBar.Flag}
*/ */
@Deprecated
public enum BossBarFlag { public enum BossBarFlag {
DARKEN_SCREEN, DARKEN_SCREEN,
PLAY_BOSS_MUSIC, PLAY_BOSS_MUSIC,

Datei anzeigen

@ -2,7 +2,10 @@ package com.velocitypowered.api.util.bossbar;
/** /**
* Represents a overlay of a {@link BossBar}. * Represents a overlay of a {@link BossBar}.
*
* @deprecated Replaced with {@link net.kyori.adventure.bossbar.BossBar.Overlay}
*/ */
@Deprecated
public enum BossBarOverlay { public enum BossBarOverlay {
PROGRESS, PROGRESS,
NOTCHED_6, NOTCHED_6,

Datei anzeigen

@ -9,7 +9,10 @@ import org.checkerframework.checker.nullness.qual.Nullable;
/** /**
* Represents a "full" title, including all components. This class is immutable. * Represents a "full" title, including all components. This class is immutable.
*
* @deprecated Replaced with {@link net.kyori.adventure.title.Title}
*/ */
@Deprecated
public final class TextTitle implements Title { public final class TextTitle implements Title {
private final @Nullable Component title; private final @Nullable Component title;

Datei anzeigen

@ -2,7 +2,10 @@ package com.velocitypowered.api.util.title;
/** /**
* Represents a title that can be sent to a Minecraft client. * Represents a title that can be sent to a Minecraft client.
*
* @deprecated Replaced with {@link net.kyori.adventure.title.Title}
*/ */
@Deprecated
public interface Title { public interface Title {
} }

Datei anzeigen

@ -2,7 +2,10 @@ package com.velocitypowered.api.util.title;
/** /**
* Provides special-purpose titles. * Provides special-purpose titles.
*
* @deprecated Replaced with {@link net.kyori.adventure.title.Title}
*/ */
@Deprecated
public final class Titles { public final class Titles {
private Titles() { private Titles() {

Datei anzeigen

@ -1,4 +1,6 @@
/** /**
* Provides data structures for creating and manipulating titles. * Provides data structures for creating and manipulating titles.
*
* @deprecated Replaced with {@link net.kyori.adventure.title}
*/ */
package com.velocitypowered.api.util.title; package com.velocitypowered.api.util.title;

Datei anzeigen

@ -18,6 +18,7 @@ allprojects {
ext { ext {
// dependency versions // dependency versions
textVersion = '3.0.3' textVersion = '3.0.3'
adventureVersion = '4.0.0-SNAPSHOT'
junitVersion = '5.3.0-M1' junitVersion = '5.3.0-M1'
slf4jVersion = '1.7.25' slf4jVersion = '1.7.25'
log4jVersion = '2.11.2' log4jVersion = '2.11.2'

Datei anzeigen

@ -224,7 +224,7 @@ public class Metrics {
) )
) )
) { ) {
VelocityServer.GSON.toJson(object, writer); VelocityServer.GENERAL_GSON.toJson(object, writer);
} catch (IOException e) { } catch (IOException e) {
throw e; throw e;
} }

Datei anzeigen

@ -8,6 +8,7 @@ import com.google.gson.GsonBuilder;
import com.velocitypowered.api.event.EventManager; import com.velocitypowered.api.event.EventManager;
import com.velocitypowered.api.event.proxy.ProxyInitializeEvent; import com.velocitypowered.api.event.proxy.ProxyInitializeEvent;
import com.velocitypowered.api.event.proxy.ProxyReloadEvent; import com.velocitypowered.api.event.proxy.ProxyReloadEvent;
import com.velocitypowered.api.network.ProtocolVersion;
import com.velocitypowered.api.plugin.PluginContainer; import com.velocitypowered.api.plugin.PluginContainer;
import com.velocitypowered.api.plugin.PluginManager; import com.velocitypowered.api.plugin.PluginManager;
import com.velocitypowered.api.proxy.Player; import com.velocitypowered.api.proxy.Player;
@ -68,10 +69,10 @@ import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.IntFunction; import java.util.function.IntFunction;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import net.kyori.text.Component; import net.kyori.text.Component;
import net.kyori.text.TextComponent; import net.kyori.text.TextComponent;
import net.kyori.text.TranslatableComponent; import net.kyori.text.TranslatableComponent;
import net.kyori.text.serializer.gson.GsonComponentSerializer;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.asynchttpclient.AsyncHttpClient; import org.asynchttpclient.AsyncHttpClient;
@ -83,10 +84,18 @@ import org.checkerframework.checker.nullness.qual.Nullable;
public class VelocityServer implements ProxyServer { public class VelocityServer implements ProxyServer {
private static final Logger logger = LogManager.getLogger(VelocityServer.class); private static final Logger logger = LogManager.getLogger(VelocityServer.class);
public static final Gson GSON = GsonComponentSerializer.populate(new GsonBuilder()) public static final Gson GENERAL_GSON = new GsonBuilder()
.registerTypeHierarchyAdapter(Favicon.class, new FaviconSerializer()) .registerTypeHierarchyAdapter(Favicon.class, new FaviconSerializer())
.registerTypeHierarchyAdapter(GameProfile.class, new GameProfileSerializer()) .registerTypeHierarchyAdapter(GameProfile.class, new GameProfileSerializer())
.create(); .create();
private static final Gson PRE_1_16_COMPONENT_SERIALIZER =
wrapAndAddTextSerializers(GsonComponentSerializer.colorDownsamplingGson())
.registerTypeHierarchyAdapter(Favicon.class, new FaviconSerializer())
.create();
private static final Gson POST_1_16_COMPONENT_SERIALIZER =
wrapAndAddTextSerializers(GsonComponentSerializer.gson())
.registerTypeHierarchyAdapter(Favicon.class, new FaviconSerializer())
.create();
private final ConnectionManager cm; private final ConnectionManager cm;
private final ProxyOptions options; private final ProxyOptions options;
@ -594,4 +603,22 @@ public class VelocityServer implements ProxyServer {
} }
return configuration.getBind(); return configuration.getBind();
} }
@Override
public void sendMessage(net.kyori.adventure.text.@NonNull Component message) {
Preconditions.checkNotNull(message, "message");
for (ConnectedPlayer player : connectionsByUuid.values()) {
player.sendMessage(message);
}
}
public static Gson getGsonInstance(ProtocolVersion version) {
return version.compareTo(ProtocolVersion.MINECRAFT_1_16) >= 0 ? POST_1_16_COMPONENT_SERIALIZER
: PRE_1_16_COMPONENT_SERIALIZER;
}
private static GsonBuilder wrapAndAddTextSerializers(GsonComponentSerializer serializer) {
return net.kyori.text.serializer.gson.GsonComponentSerializer
.populate(serializer.serializer().newBuilder());
}
} }

Datei anzeigen

@ -1,19 +1,16 @@
package com.velocitypowered.proxy.config; package com.velocitypowered.proxy.config;
import com.electronwill.nightconfig.core.CommentedConfig; import com.electronwill.nightconfig.core.CommentedConfig;
import com.electronwill.nightconfig.core.Config;
import com.electronwill.nightconfig.core.UnmodifiableConfig; import com.electronwill.nightconfig.core.UnmodifiableConfig;
import com.electronwill.nightconfig.core.file.CommentedFileConfig; import com.electronwill.nightconfig.core.file.CommentedFileConfig;
import com.google.common.base.MoreObjects; import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.moandjiezana.toml.Toml;
import com.velocitypowered.api.proxy.config.ProxyConfig; import com.velocitypowered.api.proxy.config.ProxyConfig;
import com.velocitypowered.api.util.AdventureCompat;
import com.velocitypowered.api.util.Favicon; import com.velocitypowered.api.util.Favicon;
import com.velocitypowered.proxy.Velocity;
import com.velocitypowered.proxy.util.AddressUtil; import com.velocitypowered.proxy.util.AddressUtil;
import java.io.IOException; import java.io.IOException;
import java.io.Reader;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.nio.file.Files; import java.nio.file.Files;
@ -22,14 +19,12 @@ import java.nio.file.Paths;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.Random; import java.util.Random;
import java.util.UUID; import java.util.UUID;
import net.kyori.text.Component; import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import net.kyori.text.serializer.gson.GsonComponentSerializer; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import net.kyori.text.serializer.legacy.LegacyComponentSerializer;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull; import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
@ -54,7 +49,7 @@ public class VelocityConfiguration implements ProxyConfig {
private final Advanced advanced; private final Advanced advanced;
private final Query query; private final Query query;
private final Metrics metrics; private final Metrics metrics;
private @MonotonicNonNull Component motdAsComponent; private net.kyori.adventure.text.@MonotonicNonNull Component motdAsComponent;
private @Nullable Favicon favicon; private @Nullable Favicon favicon;
private VelocityConfiguration(Servers servers, ForcedHosts forcedHosts, Advanced advanced, private VelocityConfiguration(Servers servers, ForcedHosts forcedHosts, Advanced advanced,
@ -161,7 +156,7 @@ public class VelocityConfiguration implements ProxyConfig {
} }
try { try {
getMotdComponent(); getMotd();
} catch (Exception e) { } catch (Exception e) {
logger.error("Can't parse your MOTD", e); logger.error("Can't parse your MOTD", e);
valid = false; valid = false;
@ -228,22 +223,23 @@ public class VelocityConfiguration implements ProxyConfig {
return query.shouldQueryShowPlugins(); return query.shouldQueryShowPlugins();
} }
public String getMotd() {
return motd;
}
/** /**
* Returns the proxy's MOTD. * Returns the proxy's MOTD.
* *
* @return the MOTD * @return the MOTD
*/ */
@Override @Override
public Component getMotdComponent() { public net.kyori.text.Component getMotdComponent() {
return AdventureCompat.asOriginalTextComponent(this.getMotd());
}
@Override
public net.kyori.adventure.text.Component getMotd() {
if (motdAsComponent == null) { if (motdAsComponent == null) {
if (motd.startsWith("{")) { if (motd.startsWith("{")) {
motdAsComponent = GsonComponentSerializer.INSTANCE.deserialize(motd); motdAsComponent = GsonComponentSerializer.gson().deserialize(motd);
} else { } else {
motdAsComponent = LegacyComponentSerializer.legacy().deserialize(motd, '&'); motdAsComponent = LegacyComponentSerializer.legacy('&').deserialize(motd);
} }
} }
return motdAsComponent; return motdAsComponent;

Datei anzeigen

@ -9,6 +9,7 @@ import com.mojang.brigadier.builder.RequiredArgumentBuilder;
import com.mojang.brigadier.tree.LiteralCommandNode; import com.mojang.brigadier.tree.LiteralCommandNode;
import com.velocitypowered.api.event.command.PlayerAvailableCommandsEvent; import com.velocitypowered.api.event.command.PlayerAvailableCommandsEvent;
import com.velocitypowered.api.event.connection.PluginMessageEvent; import com.velocitypowered.api.event.connection.PluginMessageEvent;
import com.velocitypowered.api.network.ProtocolVersion;
import com.velocitypowered.api.proxy.messages.ChannelIdentifier; import com.velocitypowered.api.proxy.messages.ChannelIdentifier;
import com.velocitypowered.proxy.VelocityServer; import com.velocitypowered.proxy.VelocityServer;
import com.velocitypowered.proxy.connection.MinecraftConnection; import com.velocitypowered.proxy.connection.MinecraftConnection;
@ -216,7 +217,8 @@ public class BackendPlaySessionHandler implements MinecraftSessionHandler {
serverConn.getServer().removePlayer(serverConn.getPlayer()); serverConn.getServer().removePlayer(serverConn.getPlayer());
if (!serverConn.isGracefulDisconnect() && !exceptionTriggered) { if (!serverConn.isGracefulDisconnect() && !exceptionTriggered) {
serverConn.getPlayer().handleConnectionException(serverConn.getServer(), serverConn.getPlayer().handleConnectionException(serverConn.getServer(),
Disconnect.create(ConnectionMessages.UNEXPECTED_DISCONNECT), true); Disconnect.create(ConnectionMessages.UNEXPECTED_DISCONNECT,
ProtocolVersion.MINECRAFT_1_16), true);
} }
} }
} }

Datei anzeigen

@ -26,7 +26,7 @@ import java.util.concurrent.CompletableFuture;
import javax.crypto.Mac; import javax.crypto.Mac;
import javax.crypto.SecretKey; import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec; import javax.crypto.spec.SecretKeySpec;
import net.kyori.text.TextComponent; import net.kyori.adventure.text.TextComponent;
public class LoginSessionHandler implements MinecraftSessionHandler { public class LoginSessionHandler implements MinecraftSessionHandler {

Datei anzeigen

@ -1,6 +1,6 @@
package com.velocitypowered.proxy.connection.backend; package com.velocitypowered.proxy.connection.backend;
import static com.velocitypowered.proxy.VelocityServer.GSON; import static com.velocitypowered.proxy.VelocityServer.GENERAL_GSON;
import static com.velocitypowered.proxy.connection.forge.legacy.LegacyForgeConstants.HANDSHAKE_HOSTNAME_TOKEN; import static com.velocitypowered.proxy.connection.forge.legacy.LegacyForgeConstants.HANDSHAKE_HOSTNAME_TOKEN;
import static com.velocitypowered.proxy.network.Connections.HANDLER; import static com.velocitypowered.proxy.network.Connections.HANDLER;
@ -105,7 +105,8 @@ public class VelocityServerConnection implements MinecraftConnectionAssociation,
.append('\0') .append('\0')
.append(proxyPlayer.getGameProfile().getUndashedId()) .append(proxyPlayer.getGameProfile().getUndashedId())
.append('\0'); .append('\0');
GSON.toJson(propertiesTransform.apply(proxyPlayer.getGameProfile().getProperties()), data); GENERAL_GSON
.toJson(propertiesTransform.apply(proxyPlayer.getGameProfile().getProperties()), data);
return data.toString(); return data.toString();
} }

Datei anzeigen

@ -4,6 +4,8 @@ import static com.velocitypowered.proxy.connection.util.ConnectionRequestResults
import static java.util.concurrent.CompletableFuture.completedFuture; import static java.util.concurrent.CompletableFuture.completedFuture;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.google.common.base.Verify;
import com.google.gson.Gson;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import com.velocitypowered.api.event.connection.DisconnectEvent; import com.velocitypowered.api.event.connection.DisconnectEvent;
import com.velocitypowered.api.event.player.KickedFromServerEvent; import com.velocitypowered.api.event.player.KickedFromServerEvent;
@ -61,18 +63,19 @@ import java.util.Optional;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException; import java.util.concurrent.CompletionException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ThreadLocalRandom;
import net.kyori.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.text.TextComponent; import net.kyori.adventure.text.TextComponent;
import net.kyori.text.TranslatableComponent; import net.kyori.adventure.text.TranslatableComponent;
import net.kyori.text.format.TextColor; import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.text.serializer.gson.GsonComponentSerializer; import net.kyori.adventure.text.format.TextColor;
import net.kyori.text.serializer.legacy.LegacyComponentSerializer; import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import net.kyori.text.serializer.plain.PlainComponentSerializer; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import net.kyori.adventure.text.serializer.plain.PlainComponentSerializer;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull; import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
public class ConnectedPlayer implements MinecraftConnectionAssociation, Player { public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
@ -218,7 +221,7 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
} }
@Override @Override
public void sendMessage(Component component, MessagePosition position) { public void sendMessage(net.kyori.text.Component component, MessagePosition position) {
Preconditions.checkNotNull(component, "component"); Preconditions.checkNotNull(component, "component");
Preconditions.checkNotNull(position, "position"); Preconditions.checkNotNull(position, "position");
@ -229,18 +232,20 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
// We can use the title packet instead. // We can use the title packet instead.
TitlePacket pkt = new TitlePacket(); TitlePacket pkt = new TitlePacket();
pkt.setAction(TitlePacket.SET_ACTION_BAR); pkt.setAction(TitlePacket.SET_ACTION_BAR);
pkt.setComponent(GsonComponentSerializer.INSTANCE.serialize(component)); pkt.setComponent(net.kyori.text.serializer.gson.GsonComponentSerializer.INSTANCE
.serialize(component));
connection.write(pkt); connection.write(pkt);
return; return;
} else { } else {
// Due to issues with action bar packets, we'll need to convert the text message into a // Due to issues with action bar packets, we'll need to convert the text message into a
// legacy message and then inject the legacy text into a component... yuck! // legacy message and then inject the legacy text into a component... yuck!
JsonObject object = new JsonObject(); JsonObject object = new JsonObject();
object.addProperty("text", LegacyComponentSerializer.legacy().serialize(component)); object.addProperty("text", net.kyori.text.serializer.legacy
.LegacyComponentSerializer.legacy().serialize(component));
json = object.toString(); json = object.toString();
} }
} else { } else {
json = GsonComponentSerializer.INSTANCE.serialize(component); json = net.kyori.text.serializer.gson.GsonComponentSerializer.INSTANCE.serialize(component);
} }
Chat chat = new Chat(); Chat chat = new Chat();
@ -249,6 +254,31 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
connection.write(chat); connection.write(chat);
} }
@Override
public void sendMessage(net.kyori.adventure.text.@NonNull Component message) {
connection.write(Chat.createClientbound(message, this.getProtocolVersion()));
}
@Override
public void sendActionBar(net.kyori.adventure.text.@NonNull Component message) {
if (getProtocolVersion().compareTo(ProtocolVersion.MINECRAFT_1_11) >= 0) {
// We can use the title packet instead.
TitlePacket pkt = new TitlePacket();
pkt.setAction(TitlePacket.SET_ACTION_BAR);
pkt.setComponent(VelocityServer.getGsonInstance(this.getProtocolVersion()).toJson(message));
connection.write(pkt);
} else {
// Due to issues with action bar packets, we'll need to convert the text message into a
// legacy message and then inject the legacy text into a component... yuck!
JsonObject object = new JsonObject();
object.addProperty("text", LegacyComponentSerializer.legacy().serialize(message));
Chat chat = new Chat();
chat.setMessage(object.toString());
chat.setType((byte) 1);
connection.write(chat);
}
}
@Override @Override
public ConnectionRequestBuilder createConnectionRequest(RegisteredServer server) { public ConnectionRequestBuilder createConnectionRequest(RegisteredServer server) {
return new ConnectionRequestBuilderImpl(server); return new ConnectionRequestBuilderImpl(server);
@ -265,7 +295,7 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
} }
@Override @Override
public void setHeaderAndFooter(Component header, Component footer) { public void setHeaderAndFooter(net.kyori.text.Component header, net.kyori.text.Component footer) {
tabList.setHeaderAndFooter(header, footer); tabList.setHeaderAndFooter(header, footer);
} }
@ -288,6 +318,26 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
} }
} }
@Override
public void disconnect(net.kyori.text.Component reason) {
if (connection.eventLoop().inEventLoop()) {
disconnect0(reason, false);
} else {
connection.eventLoop().execute(() -> disconnect0(reason, false));
}
}
/**
* Disconnects the player from the proxy.
* @param reason the reason for disconnecting the player
* @param duringLogin whether the disconnect happened during login
*/
public void disconnect0(net.kyori.text.Component reason, boolean duringLogin) {
logger.info("{} has disconnected: {}", this,
net.kyori.text.serializer.legacy.LegacyComponentSerializer.legacy().serialize(reason));
connection.closeWith(Disconnect.create(reason));
}
/** /**
* Disconnects the player from the proxy. * Disconnects the player from the proxy.
* @param reason the reason for disconnecting the player * @param reason the reason for disconnecting the player
@ -296,7 +346,7 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
public void disconnect0(Component reason, boolean duringLogin) { public void disconnect0(Component reason, boolean duringLogin) {
logger.info("{} has disconnected: {}", this, logger.info("{} has disconnected: {}", this,
LegacyComponentSerializer.legacy().serialize(reason)); LegacyComponentSerializer.legacy().serialize(reason));
connection.closeWith(Disconnect.create(reason)); connection.closeWith(Disconnect.create(reason, this.getProtocolVersion()));
} }
@Override @Override
@ -310,24 +360,25 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
connection.write(TitlePacket.hideForProtocolVersion(protocolVersion)); connection.write(TitlePacket.hideForProtocolVersion(protocolVersion));
} else if (title instanceof TextTitle) { } else if (title instanceof TextTitle) {
TextTitle tt = (TextTitle) title; TextTitle tt = (TextTitle) title;
Gson gson = VelocityServer.getGsonInstance(this.getProtocolVersion());
if (tt.isResetBeforeSend()) { if (tt.isResetBeforeSend()) {
connection.delayedWrite(TitlePacket.resetForProtocolVersion(protocolVersion)); connection.delayedWrite(TitlePacket.resetForProtocolVersion(protocolVersion));
} }
Optional<Component> titleText = tt.getTitle(); Optional<net.kyori.text.Component> titleText = tt.getTitle();
if (titleText.isPresent()) { if (titleText.isPresent()) {
TitlePacket titlePkt = new TitlePacket(); TitlePacket titlePkt = new TitlePacket();
titlePkt.setAction(TitlePacket.SET_TITLE); titlePkt.setAction(TitlePacket.SET_TITLE);
titlePkt.setComponent(GsonComponentSerializer.INSTANCE.serialize(titleText.get())); titlePkt.setComponent(gson.toJson(titleText.get()));
connection.delayedWrite(titlePkt); connection.delayedWrite(titlePkt);
} }
Optional<Component> subtitleText = tt.getSubtitle(); Optional<net.kyori.text.Component> subtitleText = tt.getSubtitle();
if (subtitleText.isPresent()) { if (subtitleText.isPresent()) {
TitlePacket titlePkt = new TitlePacket(); TitlePacket titlePkt = new TitlePacket();
titlePkt.setAction(TitlePacket.SET_SUBTITLE); titlePkt.setAction(TitlePacket.SET_SUBTITLE);
titlePkt.setComponent(GsonComponentSerializer.INSTANCE.serialize(subtitleText.get())); titlePkt.setComponent(gson.toJson(subtitleText.get()));
connection.delayedWrite(titlePkt); connection.delayedWrite(titlePkt);
} }
@ -391,7 +442,8 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
userMessage = "Unable to connect to " + server.getServerInfo().getName() + ". Try again " userMessage = "Unable to connect to " + server.getServerInfo().getName() + ". Try again "
+ "later."; + "later.";
} }
handleConnectionException(server, null, TextComponent.of(userMessage, TextColor.RED), safe); handleConnectionException(server, null, TextComponent.of(userMessage,
NamedTextColor.RED), safe);
} }
/** /**
@ -407,15 +459,14 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
return; return;
} }
Component disconnectReason = GsonComponentSerializer.INSTANCE.deserialize( Component disconnectReason = GsonComponentSerializer.gson().deserialize(disconnect.getReason());
disconnect.getReason());
String plainTextReason = PASS_THRU_TRANSLATE.serialize(disconnectReason); String plainTextReason = PASS_THRU_TRANSLATE.serialize(disconnectReason);
if (connectedServer != null && connectedServer.getServerInfo().equals(server.getServerInfo())) { if (connectedServer != null && connectedServer.getServerInfo().equals(server.getServerInfo())) {
logger.error("{}: kicked from server {}: {}", this, server.getServerInfo().getName(), logger.error("{}: kicked from server {}: {}", this, server.getServerInfo().getName(),
plainTextReason); plainTextReason);
handleConnectionException(server, disconnectReason, TextComponent.builder() handleConnectionException(server, disconnectReason, TextComponent.builder()
.content("Kicked from " + server.getServerInfo().getName() + ": ") .content("Kicked from " + server.getServerInfo().getName() + ": ")
.color(TextColor.RED) .color(NamedTextColor.RED)
.append(disconnectReason) .append(disconnectReason)
.build(), safe); .build(), safe);
} else { } else {
@ -423,7 +474,7 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
server.getServerInfo().getName(), plainTextReason); server.getServerInfo().getName(), plainTextReason);
handleConnectionException(server, disconnectReason, TextComponent.builder() handleConnectionException(server, disconnectReason, TextComponent.builder()
.content("Can't connect to server " + server.getServerInfo().getName() + ": ") .content("Can't connect to server " + server.getServerInfo().getName() + ": ")
.color(TextColor.RED) .color(NamedTextColor.RED)
.append(disconnectReason) .append(disconnectReason)
.build(), safe); .build(), safe);
} }
@ -448,7 +499,7 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
ServerKickResult result; ServerKickResult result;
if (kickedFromCurrent) { if (kickedFromCurrent) {
Optional<RegisteredServer> next = getNextServerToTry(rs); Optional<RegisteredServer> next = getNextServerToTry(rs);
result = next.<ServerKickResult>map(RedirectPlayer::create) result = next.map(RedirectPlayer::create)
.orElseGet(() -> DisconnectPlayer.create(friendlyReason)); .orElseGet(() -> DisconnectPlayer.create(friendlyReason));
} else { } else {
// If we were kicked by going to another server, the connection should not be in flight // If we were kicked by going to another server, the connection should not be in flight
@ -479,10 +530,10 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
if (newResult == null || !newResult) { if (newResult == null || !newResult) {
disconnect(friendlyReason); disconnect(friendlyReason);
} else { } else {
if (res.getMessage() == null) { if (res.getMessageComponent() == null) {
sendMessage(VelocityMessages.MOVED_TO_NEW_SERVER.append(friendlyReason)); sendMessage(VelocityMessages.MOVED_TO_NEW_SERVER.append(friendlyReason));
} else { } else {
sendMessage(res.getMessage()); sendMessage(res.getMessageComponent());
} }
} }
}, connection.eventLoop()); }, connection.eventLoop());
@ -816,8 +867,10 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
// Ignored; the plugin probably already handled this. // Ignored; the plugin probably already handled this.
break; break;
case SERVER_DISCONNECTED: case SERVER_DISCONNECTED:
handleConnectionException(toConnect, Disconnect.create(status.getReason() Component reason = status.getReasonComponent()
.orElse(ConnectionMessages.INTERNAL_SERVER_CONNECTION_ERROR)), status.isSafe()); .orElse(ConnectionMessages.INTERNAL_SERVER_CONNECTION_ERROR);
handleConnectionException(toConnect, Disconnect.create(reason,
getProtocolVersion()), status.isSafe());
break; break;
default: default:
// The only remaining value is successful (no need to do anything!) // The only remaining value is successful (no need to do anything!)

Datei anzeigen

@ -23,9 +23,10 @@ import io.netty.buffer.ByteBuf;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.util.Optional; import java.util.Optional;
import net.kyori.text.TextComponent; import net.kyori.adventure.text.Component;
import net.kyori.text.TranslatableComponent; import net.kyori.adventure.text.TextComponent;
import net.kyori.text.format.TextColor; import net.kyori.adventure.text.TranslatableComponent;
import net.kyori.adventure.text.format.NamedTextColor;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
@ -55,7 +56,7 @@ public class HandshakeSessionHandler implements MinecraftSessionHandler {
@Override @Override
public boolean handle(LegacyHandshake packet) { public boolean handle(LegacyHandshake packet) {
connection.closeWith(LegacyDisconnect connection.closeWith(LegacyDisconnect
.from(TextComponent.of("Your client is old, please upgrade!", TextColor.RED))); .from(TextComponent.of("Your client is old, please upgrade!", NamedTextColor.RED)));
return true; return true;
} }
@ -101,15 +102,13 @@ public class HandshakeSessionHandler implements MinecraftSessionHandler {
private void handleLogin(Handshake handshake, InitialInboundConnection ic) { private void handleLogin(Handshake handshake, InitialInboundConnection ic) {
if (!ProtocolVersion.isSupported(handshake.getProtocolVersion())) { if (!ProtocolVersion.isSupported(handshake.getProtocolVersion())) {
connection.closeWith(Disconnect ic.disconnectQuietly(TranslatableComponent.of("multiplayer.disconnect.outdated_client"));
.create(TranslatableComponent.of("multiplayer.disconnect.outdated_client")));
return; return;
} }
InetAddress address = ((InetSocketAddress) connection.getRemoteAddress()).getAddress(); InetAddress address = ((InetSocketAddress) connection.getRemoteAddress()).getAddress();
if (!server.getIpAttemptLimiter().attempt(address)) { if (!server.getIpAttemptLimiter().attempt(address)) {
connection.closeWith( ic.disconnectQuietly(TextComponent.of("You are logging in too fast, try again later."));
Disconnect.create(TextComponent.of("You are logging in too fast, try again later.")));
return; return;
} }
@ -119,8 +118,7 @@ public class HandshakeSessionHandler implements MinecraftSessionHandler {
// and lower, otherwise IP information will never get forwarded. // and lower, otherwise IP information will never get forwarded.
if (server.getConfiguration().getPlayerInfoForwardingMode() == PlayerInfoForwarding.MODERN if (server.getConfiguration().getPlayerInfoForwardingMode() == PlayerInfoForwarding.MODERN
&& handshake.getProtocolVersion().compareTo(ProtocolVersion.MINECRAFT_1_13) < 0) { && handshake.getProtocolVersion().compareTo(ProtocolVersion.MINECRAFT_1_13) < 0) {
connection.closeWith(Disconnect ic.disconnectQuietly(TextComponent.of("This server is only compatible with 1.13 and above."));
.create(TextComponent.of("This server is only compatible with 1.13 and above.")));
return; return;
} }

Datei anzeigen

@ -8,8 +8,8 @@ import com.velocitypowered.proxy.protocol.packet.Disconnect;
import com.velocitypowered.proxy.protocol.packet.Handshake; import com.velocitypowered.proxy.protocol.packet.Handshake;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.util.Optional; import java.util.Optional;
import net.kyori.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.text.serializer.legacy.LegacyComponentSerializer; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
@ -61,6 +61,14 @@ public final class InitialInboundConnection implements InboundConnection,
public void disconnect(Component reason) { public void disconnect(Component reason) {
logger.info("{} has disconnected: {}", this, logger.info("{} has disconnected: {}", this,
LegacyComponentSerializer.legacy().serialize(reason)); LegacyComponentSerializer.legacy().serialize(reason));
connection.closeWith(Disconnect.create(reason)); connection.closeWith(Disconnect.create(reason, getProtocolVersion()));
}
/**
* Disconnects the connection from the server silently.
* @param reason the reason for disconnecting
*/
public void disconnectQuietly(Component reason) {
connection.closeWith(Disconnect.create(reason, getProtocolVersion()));
} }
} }

Datei anzeigen

@ -2,7 +2,7 @@ package com.velocitypowered.proxy.connection.client;
import static com.google.common.net.UrlEscapers.urlFormParameterEscaper; import static com.google.common.net.UrlEscapers.urlFormParameterEscaper;
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_8; import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_8;
import static com.velocitypowered.proxy.VelocityServer.GSON; import static com.velocitypowered.proxy.VelocityServer.GENERAL_GSON;
import static com.velocitypowered.proxy.connection.VelocityConstants.EMPTY_BYTE_ARRAY; import static com.velocitypowered.proxy.connection.VelocityConstants.EMPTY_BYTE_ARRAY;
import static com.velocitypowered.proxy.util.EncryptionUtils.decryptRsa; import static com.velocitypowered.proxy.util.EncryptionUtils.decryptRsa;
import static com.velocitypowered.proxy.util.EncryptionUtils.generateServerId; import static com.velocitypowered.proxy.util.EncryptionUtils.generateServerId;
@ -124,7 +124,7 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
Response profileResponse = hasJoinedResponse.get(); Response profileResponse = hasJoinedResponse.get();
if (profileResponse.getStatusCode() == 200) { if (profileResponse.getStatusCode() == 200) {
// All went well, initialize the session. // All went well, initialize the session.
initializePlayer(GSON.fromJson(profileResponse.getResponseBody(), GameProfile.class), initializePlayer(GENERAL_GSON.fromJson(profileResponse.getResponseBody(), GameProfile.class),
true); true);
} else if (profileResponse.getStatusCode() == 204) { } else if (profileResponse.getStatusCode() == 204) {
// Apparently an offline-mode user logged onto this online-mode proxy. // Apparently an offline-mode user logged onto this online-mode proxy.

Datei anzeigen

@ -1,12 +1,14 @@
package com.velocitypowered.proxy.connection.client; package com.velocitypowered.proxy.connection.client;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.gson.Gson;
import com.spotify.futures.CompletableFutures; import com.spotify.futures.CompletableFutures;
import com.velocitypowered.api.event.proxy.ProxyPingEvent; import com.velocitypowered.api.event.proxy.ProxyPingEvent;
import com.velocitypowered.api.network.ProtocolVersion; import com.velocitypowered.api.network.ProtocolVersion;
import com.velocitypowered.api.proxy.InboundConnection; import com.velocitypowered.api.proxy.InboundConnection;
import com.velocitypowered.api.proxy.server.RegisteredServer; import com.velocitypowered.api.proxy.server.RegisteredServer;
import com.velocitypowered.api.proxy.server.ServerPing; import com.velocitypowered.api.proxy.server.ServerPing;
import com.velocitypowered.api.util.Favicon;
import com.velocitypowered.api.util.ModInfo; import com.velocitypowered.api.util.ModInfo;
import com.velocitypowered.proxy.VelocityServer; import com.velocitypowered.proxy.VelocityServer;
import com.velocitypowered.proxy.config.PingPassthroughMode; import com.velocitypowered.proxy.config.PingPassthroughMode;
@ -18,6 +20,7 @@ import com.velocitypowered.proxy.protocol.packet.LegacyPing;
import com.velocitypowered.proxy.protocol.packet.StatusPing; import com.velocitypowered.proxy.protocol.packet.StatusPing;
import com.velocitypowered.proxy.protocol.packet.StatusRequest; import com.velocitypowered.proxy.protocol.packet.StatusRequest;
import com.velocitypowered.proxy.protocol.packet.StatusResponse; import com.velocitypowered.proxy.protocol.packet.StatusResponse;
import com.velocitypowered.proxy.protocol.util.FaviconSerializer;
import com.velocitypowered.proxy.server.VelocityRegisteredServer; import com.velocitypowered.proxy.server.VelocityRegisteredServer;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
@ -25,11 +28,23 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
public class StatusSessionHandler implements MinecraftSessionHandler { public class StatusSessionHandler implements MinecraftSessionHandler {
private static final Gson PRE_1_16_PING_SERIALIZER = GsonComponentSerializer
.colorDownsamplingGson()
.serializer()
.newBuilder()
.registerTypeHierarchyAdapter(Favicon.class, new FaviconSerializer())
.create();
private static final Gson POST_1_16_PING_SERIALIZER = GsonComponentSerializer.gson()
.serializer()
.newBuilder()
.registerTypeHierarchyAdapter(Favicon.class, new FaviconSerializer())
.create();
private static final Logger logger = LogManager.getLogger(StatusSessionHandler.class); private static final Logger logger = LogManager.getLogger(StatusSessionHandler.class);
private final VelocityServer server; private final VelocityServer server;
@ -58,7 +73,7 @@ public class StatusSessionHandler implements MinecraftSessionHandler {
"Velocity " + ProtocolVersion.SUPPORTED_VERSION_STRING), "Velocity " + ProtocolVersion.SUPPORTED_VERSION_STRING),
new ServerPing.Players(server.getPlayerCount(), configuration.getShowMaxPlayers(), new ServerPing.Players(server.getPlayerCount(), configuration.getShowMaxPlayers(),
ImmutableList.of()), ImmutableList.of()),
configuration.getMotdComponent(), configuration.getMotd(),
configuration.getFavicon().orElse(null), configuration.getFavicon().orElse(null),
configuration.isAnnounceForge() ? ModInfo.DEFAULT : null configuration.isAnnounceForge() ? ModInfo.DEFAULT : null
); );
@ -119,7 +134,7 @@ public class StatusSessionHandler implements MinecraftSessionHandler {
return new ServerPing( return new ServerPing(
fallback.getVersion(), fallback.getVersion(),
fallback.getPlayers().orElse(null), fallback.getPlayers().orElse(null),
response.getDescription(), response.getDescriptionComponent(),
fallback.getFavicon().orElse(null), fallback.getFavicon().orElse(null),
response.getModinfo().orElse(null) response.getModinfo().orElse(null)
); );
@ -173,7 +188,8 @@ public class StatusSessionHandler implements MinecraftSessionHandler {
.thenAcceptAsync( .thenAcceptAsync(
(event) -> { (event) -> {
StringBuilder json = new StringBuilder(); StringBuilder json = new StringBuilder();
VelocityServer.GSON.toJson(event.getPing(), json); VelocityServer.getGsonInstance(connection.getProtocolVersion())
.toJson(event.getPing(), json);
connection.write(new StatusResponse(json)); connection.write(new StatusResponse(json));
}, },
connection.eventLoop()); connection.eventLoop());

Datei anzeigen

@ -1,14 +1,14 @@
package com.velocitypowered.proxy.connection.util; package com.velocitypowered.proxy.connection.util;
import net.kyori.text.TextComponent; import net.kyori.adventure.text.TextComponent;
import net.kyori.text.format.TextColor; import net.kyori.adventure.text.format.NamedTextColor;
public class ConnectionMessages { public class ConnectionMessages {
public static final TextComponent ALREADY_CONNECTED = TextComponent public static final TextComponent ALREADY_CONNECTED = TextComponent
.of("You are already connected to this server!", TextColor.RED); .of("You are already connected to this server!", NamedTextColor.RED);
public static final TextComponent IN_PROGRESS = TextComponent public static final TextComponent IN_PROGRESS = TextComponent
.of("You are already connecting to a server!", TextColor.RED); .of("You are already connecting to a server!", NamedTextColor.RED);
public static final TextComponent INTERNAL_SERVER_CONNECTION_ERROR = TextComponent public static final TextComponent INTERNAL_SERVER_CONNECTION_ERROR = TextComponent
.of("Internal server connection error"); .of("Internal server connection error");
public static final TextComponent UNEXPECTED_DISCONNECT = TextComponent public static final TextComponent UNEXPECTED_DISCONNECT = TextComponent

Datei anzeigen

@ -3,11 +3,12 @@ package com.velocitypowered.proxy.connection.util;
import com.velocitypowered.api.proxy.ConnectionRequestBuilder; import com.velocitypowered.api.proxy.ConnectionRequestBuilder;
import com.velocitypowered.api.proxy.ConnectionRequestBuilder.Status; import com.velocitypowered.api.proxy.ConnectionRequestBuilder.Status;
import com.velocitypowered.api.proxy.server.RegisteredServer; import com.velocitypowered.api.proxy.server.RegisteredServer;
import com.velocitypowered.api.util.AdventureCompat;
import com.velocitypowered.proxy.protocol.packet.Disconnect; import com.velocitypowered.proxy.protocol.packet.Disconnect;
import java.util.Optional; import java.util.Optional;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import net.kyori.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.text.serializer.gson.GsonComponentSerializer; import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
public class ConnectionRequestResults { public class ConnectionRequestResults {
@ -42,19 +43,19 @@ public class ConnectionRequestResults {
} }
public static Impl forDisconnect(Disconnect disconnect, RegisteredServer server) { public static Impl forDisconnect(Disconnect disconnect, RegisteredServer server) {
Component deserialized = GsonComponentSerializer.INSTANCE.deserialize(disconnect.getReason()); Component deserialized = GsonComponentSerializer.gson().deserialize(disconnect.getReason());
return forDisconnect(deserialized, server); return forDisconnect(deserialized, server);
} }
public static Impl forUnsafeDisconnect(Disconnect disconnect, RegisteredServer server) { public static Impl forUnsafeDisconnect(Disconnect disconnect, RegisteredServer server) {
Component deserialized = GsonComponentSerializer.INSTANCE.deserialize(disconnect.getReason()); Component deserialized = GsonComponentSerializer.gson().deserialize(disconnect.getReason());
return new Impl(Status.SERVER_DISCONNECTED, deserialized, server, false); return new Impl(Status.SERVER_DISCONNECTED, deserialized, server, false);
} }
public static class Impl implements ConnectionRequestBuilder.Result { public static class Impl implements ConnectionRequestBuilder.Result {
private final Status status; private final Status status;
private final @Nullable Component component; private final @Nullable net.kyori.adventure.text.Component component;
private final RegisteredServer attemptedConnection; private final RegisteredServer attemptedConnection;
private final boolean safe; private final boolean safe;
@ -72,7 +73,12 @@ public class ConnectionRequestResults {
} }
@Override @Override
public Optional<Component> getReason() { public Optional<net.kyori.text.Component> getReason() {
return Optional.ofNullable(component).map(AdventureCompat::asOriginalTextComponent);
}
@Override
public Optional<Component> getReasonComponent() {
return Optional.ofNullable(component); return Optional.ofNullable(component);
} }

Datei anzeigen

@ -8,10 +8,8 @@ import com.velocitypowered.api.permission.Tristate;
import com.velocitypowered.api.proxy.ConsoleCommandSource; import com.velocitypowered.api.proxy.ConsoleCommandSource;
import com.velocitypowered.proxy.VelocityServer; import com.velocitypowered.proxy.VelocityServer;
import java.util.List; import java.util.List;
import net.kyori.text.Component;
import net.kyori.text.TextComponent; import net.kyori.text.TextComponent;
import net.kyori.text.format.TextColor; import net.kyori.text.format.TextColor;
import net.kyori.text.serializer.legacy.LegacyComponentSerializer;
import net.minecrell.terminalconsole.SimpleTerminalConsole; import net.minecrell.terminalconsole.SimpleTerminalConsole;
import org.apache.logging.log4j.Level; import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
@ -34,8 +32,15 @@ public final class VelocityConsole extends SimpleTerminalConsole implements Cons
} }
@Override @Override
public void sendMessage(Component component) { public void sendMessage(net.kyori.text.Component component) {
logger.info(LegacyComponentSerializer.legacy().serialize(component)); logger.info(net.kyori.text.serializer.legacy.LegacyComponentSerializer.legacy()
.serialize(component));
}
@Override
public void sendMessage(net.kyori.adventure.text.@NonNull Component message) {
logger.info(net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacy()
.serialize(message));
} }
@Override @Override
@ -103,5 +108,4 @@ public final class VelocityConsole extends SimpleTerminalConsole implements Cons
protected void shutdown() { protected void shutdown() {
this.server.shutdown(true); this.server.shutdown(true);
} }
} }

Datei anzeigen

@ -117,7 +117,7 @@ public class JavaPluginLoader implements PluginLoader {
while ((entry = in.getNextJarEntry()) != null) { while ((entry = in.getNextJarEntry()) != null) {
if (entry.getName().equals("velocity-plugin.json")) { if (entry.getName().equals("velocity-plugin.json")) {
try (Reader pluginInfoReader = new InputStreamReader(in, StandardCharsets.UTF_8)) { try (Reader pluginInfoReader = new InputStreamReader(in, StandardCharsets.UTF_8)) {
return Optional.of(VelocityServer.GSON return Optional.of(VelocityServer.GENERAL_GSON
.fromJson(pluginInfoReader, SerializedPluginDescription.class)); .fromJson(pluginInfoReader, SerializedPluginDescription.class));
} }
} }

Datei anzeigen

@ -26,7 +26,7 @@ import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import net.kyori.text.serializer.plain.PlainComponentSerializer; import net.kyori.adventure.text.serializer.plain.PlainComponentSerializer;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull; import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
@ -72,8 +72,7 @@ public class GS4QueryHandler extends SimpleChannelInboundHandler<DatagramPacket>
private QueryResponse createInitialResponse() { private QueryResponse createInitialResponse() {
return QueryResponse.builder() return QueryResponse.builder()
.hostname(PlainComponentSerializer.INSTANCE .hostname(PlainComponentSerializer.INSTANCE.serialize(server.getConfiguration().getMotd()))
.serialize(server.getConfiguration().getMotdComponent()))
.gameVersion(ProtocolVersion.SUPPORTED_VERSION_STRING) .gameVersion(ProtocolVersion.SUPPORTED_VERSION_STRING)
.map(server.getConfiguration().getQueryMap()) .map(server.getConfiguration().getQueryMap())
.currentPlayers(server.getPlayerCount()) .currentPlayers(server.getPlayerCount())

Datei anzeigen

@ -2,12 +2,11 @@ package com.velocitypowered.proxy.protocol.packet;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.velocitypowered.api.network.ProtocolVersion; import com.velocitypowered.api.network.ProtocolVersion;
import com.velocitypowered.proxy.VelocityServer;
import com.velocitypowered.proxy.connection.MinecraftSessionHandler; import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
import com.velocitypowered.proxy.protocol.MinecraftPacket; import com.velocitypowered.proxy.protocol.MinecraftPacket;
import com.velocitypowered.proxy.protocol.ProtocolUtils; import com.velocitypowered.proxy.protocol.ProtocolUtils;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import net.kyori.text.Component;
import net.kyori.text.serializer.gson.GsonComponentSerializer;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
import java.util.UUID; import java.util.UUID;
@ -97,13 +96,27 @@ public class Chat implements MinecraftPacket {
return handler.handle(this); return handler.handle(this);
} }
public static Chat createClientbound(Component component) { @Deprecated
public static Chat createClientbound(net.kyori.text.Component component) {
return createClientbound(component, CHAT_TYPE, EMPTY_SENDER); return createClientbound(component, CHAT_TYPE, EMPTY_SENDER);
} }
public static Chat createClientbound(Component component, byte type, UUID sender) { @Deprecated
public static Chat createClientbound(net.kyori.text.Component component, byte type, UUID sender) {
Preconditions.checkNotNull(component, "component"); Preconditions.checkNotNull(component, "component");
return new Chat(GsonComponentSerializer.INSTANCE.serialize(component), type, sender); return new Chat(net.kyori.text.serializer.gson.GsonComponentSerializer.INSTANCE
.serialize(component), type, sender);
}
public static Chat createClientbound(net.kyori.adventure.text.Component component,
ProtocolVersion version) {
return createClientbound(component, CHAT_TYPE, EMPTY_SENDER, version);
}
public static Chat createClientbound(net.kyori.adventure.text.Component component, byte type,
UUID sender, ProtocolVersion version) {
Preconditions.checkNotNull(component, "component");
return new Chat(VelocityServer.getGsonInstance(version).toJson(component), type, sender);
} }
public static Chat createServerbound(String message) { public static Chat createServerbound(String message) {

Datei anzeigen

@ -2,6 +2,7 @@ package com.velocitypowered.proxy.protocol.packet;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.velocitypowered.api.network.ProtocolVersion; import com.velocitypowered.api.network.ProtocolVersion;
import com.velocitypowered.proxy.VelocityServer;
import com.velocitypowered.proxy.connection.MinecraftSessionHandler; import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
import com.velocitypowered.proxy.protocol.MinecraftPacket; import com.velocitypowered.proxy.protocol.MinecraftPacket;
import com.velocitypowered.proxy.protocol.ProtocolUtils; import com.velocitypowered.proxy.protocol.ProtocolUtils;
@ -57,8 +58,15 @@ public class Disconnect implements MinecraftPacket {
return handler.handle(this); return handler.handle(this);
} }
@Deprecated
public static Disconnect create(Component component) { public static Disconnect create(Component component) {
Preconditions.checkNotNull(component, "component"); Preconditions.checkNotNull(component, "component");
return new Disconnect(GsonComponentSerializer.INSTANCE.serialize(component)); return new Disconnect(GsonComponentSerializer.INSTANCE.serialize(component));
} }
public static Disconnect create(net.kyori.adventure.text.Component component,
ProtocolVersion version) {
Preconditions.checkNotNull(component, "component");
return new Disconnect(VelocityServer.getGsonInstance(version).toJson(component));
}
} }

Datei anzeigen

@ -3,7 +3,9 @@ package com.velocitypowered.proxy.protocol.packet;
import static com.velocitypowered.proxy.protocol.ProtocolUtils.writeString; import static com.velocitypowered.proxy.protocol.ProtocolUtils.writeString;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.google.gson.Gson;
import com.velocitypowered.api.network.ProtocolVersion; import com.velocitypowered.api.network.ProtocolVersion;
import com.velocitypowered.proxy.VelocityServer;
import com.velocitypowered.proxy.connection.MinecraftSessionHandler; import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
import com.velocitypowered.proxy.protocol.MinecraftPacket; import com.velocitypowered.proxy.protocol.MinecraftPacket;
import com.velocitypowered.proxy.protocol.ProtocolUtils; import com.velocitypowered.proxy.protocol.ProtocolUtils;
@ -58,6 +60,12 @@ public class HeaderAndFooter implements MinecraftPacket {
return new HeaderAndFooter(json.serialize(header), json.serialize(footer)); return new HeaderAndFooter(json.serialize(header), json.serialize(footer));
} }
public static HeaderAndFooter create(net.kyori.adventure.text.Component header,
net.kyori.adventure.text.Component footer, ProtocolVersion protocolVersion) {
Gson serializer = VelocityServer.getGsonInstance(protocolVersion);
return new HeaderAndFooter(serializer.toJson(header), serializer.toJson(footer));
}
public static HeaderAndFooter reset() { public static HeaderAndFooter reset() {
return RESET; return RESET;
} }

Datei anzeigen

@ -4,9 +4,9 @@ import com.google.common.collect.ImmutableList;
import com.velocitypowered.api.proxy.server.ServerPing; import com.velocitypowered.api.proxy.server.ServerPing;
import com.velocitypowered.api.proxy.server.ServerPing.Players; import com.velocitypowered.api.proxy.server.ServerPing.Players;
import com.velocitypowered.proxy.protocol.packet.legacyping.LegacyMinecraftPingVersion; import com.velocitypowered.proxy.protocol.packet.legacyping.LegacyMinecraftPingVersion;
import net.kyori.text.TextComponent; import net.kyori.adventure.text.TextComponent;
import net.kyori.text.serializer.legacy.LegacyComponentSerializer; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import net.kyori.text.serializer.plain.PlainComponentSerializer; import net.kyori.adventure.text.serializer.plain.PlainComponentSerializer;
public class LegacyDisconnect { public class LegacyDisconnect {
@ -36,7 +36,8 @@ public class LegacyDisconnect {
// remove all section symbols, along with fetching just the first line of an (unformatted) // remove all section symbols, along with fetching just the first line of an (unformatted)
// MOTD. // MOTD.
return new LegacyDisconnect(String.join(LEGACY_COLOR_CODE, return new LegacyDisconnect(String.join(LEGACY_COLOR_CODE,
cleanSectionSymbol(getFirstLine(PlainComponentSerializer.INSTANCE.serialize(response.getDescription()))), cleanSectionSymbol(getFirstLine(PlainComponentSerializer.INSTANCE.serialize(
response.getDescriptionComponent()))),
Integer.toString(players.getOnline()), Integer.toString(players.getOnline()),
Integer.toString(players.getMax()))); Integer.toString(players.getMax())));
case MINECRAFT_1_4: case MINECRAFT_1_4:
@ -46,7 +47,8 @@ public class LegacyDisconnect {
LEGACY_COLOR_CODE + "1", LEGACY_COLOR_CODE + "1",
Integer.toString(response.getVersion().getProtocol()), Integer.toString(response.getVersion().getProtocol()),
response.getVersion().getName(), response.getVersion().getName(),
getFirstLine(LegacyComponentSerializer.legacy().serialize(response.getDescription())), getFirstLine(LegacyComponentSerializer.legacy().serialize(response
.getDescriptionComponent())),
Integer.toString(players.getOnline()), Integer.toString(players.getOnline()),
Integer.toString(players.getMax()) Integer.toString(players.getMax())
)); ));

Datei anzeigen

@ -4,6 +4,7 @@ import com.google.common.collect.ImmutableList;
import com.velocitypowered.api.network.ProtocolVersion; import com.velocitypowered.api.network.ProtocolVersion;
import com.velocitypowered.api.proxy.player.TabListEntry; import com.velocitypowered.api.proxy.player.TabListEntry;
import com.velocitypowered.api.util.GameProfile; import com.velocitypowered.api.util.GameProfile;
import com.velocitypowered.proxy.VelocityServer;
import com.velocitypowered.proxy.connection.MinecraftSessionHandler; import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
import com.velocitypowered.proxy.protocol.MinecraftPacket; import com.velocitypowered.proxy.protocol.MinecraftPacket;
import com.velocitypowered.proxy.protocol.ProtocolUtils; import com.velocitypowered.proxy.protocol.ProtocolUtils;
@ -11,9 +12,9 @@ import io.netty.buffer.ByteBuf;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import net.kyori.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.text.serializer.gson.GsonComponentSerializer; import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import net.kyori.text.serializer.legacy.LegacyComponentSerializer; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
public class PlayerListItem implements MinecraftPacket { public class PlayerListItem implements MinecraftPacket {
@ -86,7 +87,7 @@ public class PlayerListItem implements MinecraftPacket {
private static @Nullable Component readOptionalComponent(ByteBuf buf) { private static @Nullable Component readOptionalComponent(ByteBuf buf) {
if (buf.readBoolean()) { if (buf.readBoolean()) {
return GsonComponentSerializer.INSTANCE.deserialize(ProtocolUtils.readString(buf)); return GsonComponentSerializer.gson().deserialize(ProtocolUtils.readString(buf));
} }
return null; return null;
} }
@ -105,7 +106,7 @@ public class PlayerListItem implements MinecraftPacket {
ProtocolUtils.writeVarInt(buf, item.getGameMode()); ProtocolUtils.writeVarInt(buf, item.getGameMode());
ProtocolUtils.writeVarInt(buf, item.getLatency()); ProtocolUtils.writeVarInt(buf, item.getLatency());
writeDisplayName(buf, item.getDisplayName()); writeDisplayName(buf, item.getDisplayName(), version);
break; break;
case UPDATE_GAMEMODE: case UPDATE_GAMEMODE:
ProtocolUtils.writeVarInt(buf, item.getGameMode()); ProtocolUtils.writeVarInt(buf, item.getGameMode());
@ -114,10 +115,10 @@ public class PlayerListItem implements MinecraftPacket {
ProtocolUtils.writeVarInt(buf, item.getLatency()); ProtocolUtils.writeVarInt(buf, item.getLatency());
break; break;
case UPDATE_DISPLAY_NAME: case UPDATE_DISPLAY_NAME:
writeDisplayName(buf, item.getDisplayName()); writeDisplayName(buf, item.getDisplayName(), version);
break; break;
case REMOVE_PLAYER: case REMOVE_PLAYER:
//Do nothing, all that is needed is the uuid // Do nothing, all that is needed is the uuid
break; break;
default: default:
throw new UnsupportedOperationException("Unknown action " + action); throw new UnsupportedOperationException("Unknown action " + action);
@ -142,10 +143,11 @@ public class PlayerListItem implements MinecraftPacket {
return handler.handle(this); return handler.handle(this);
} }
private void writeDisplayName(ByteBuf buf, @Nullable Component displayName) { private void writeDisplayName(ByteBuf buf, @Nullable Component displayName,
ProtocolVersion version) {
buf.writeBoolean(displayName != null); buf.writeBoolean(displayName != null);
if (displayName != null) { if (displayName != null) {
ProtocolUtils.writeString(buf, GsonComponentSerializer.INSTANCE.serialize(displayName)); ProtocolUtils.writeString(buf, VelocityServer.getGsonInstance(version).toJson(displayName));
} }
} }
@ -172,7 +174,7 @@ public class PlayerListItem implements MinecraftPacket {
.setProperties(entry.getProfile().getProperties()) .setProperties(entry.getProfile().getProperties())
.setLatency(entry.getLatency()) .setLatency(entry.getLatency())
.setGameMode(entry.getGameMode()) .setGameMode(entry.getGameMode())
.setDisplayName(entry.getDisplayName().orElse(null)); .setDisplayName(entry.getDisplayNameComponent().orElse(null));
} }
public @Nullable UUID getUuid() { public @Nullable UUID getUuid() {

Datei anzeigen

@ -50,7 +50,8 @@ public class PingSessionHandler implements MinecraftSessionHandler {
completed = true; completed = true;
connection.close(true); connection.close(true);
ServerPing ping = VelocityServer.GSON.fromJson(packet.getStatus(), ServerPing.class); ServerPing ping = VelocityServer.getGsonInstance(version).fromJson(packet.getStatus(),
ServerPing.class);
result.complete(ping); result.complete(ping);
return true; return true;
} }

Datei anzeigen

@ -37,6 +37,8 @@ import java.util.Set;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import net.kyori.adventure.text.Component;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
public class VelocityRegisteredServer implements RegisteredServer { public class VelocityRegisteredServer implements RegisteredServer {
@ -145,4 +147,11 @@ public class VelocityRegisteredServer implements RegisteredServer {
public String toString() { public String toString() {
return "registered server: " + serverInfo; return "registered server: " + serverInfo;
} }
@Override
public void sendMessage(@NonNull Component message) {
for (ConnectedPlayer player : players) {
player.sendMessage(message);
}
}
} }

Datei anzeigen

@ -34,6 +34,14 @@ public class VelocityTabList implements TabList {
connection.write(HeaderAndFooter.create(header, footer)); connection.write(HeaderAndFooter.create(header, footer));
} }
@Override
public void setHeaderAndFooter(net.kyori.adventure.text.Component header,
net.kyori.adventure.text.Component footer) {
Preconditions.checkNotNull(header, "header");
Preconditions.checkNotNull(footer, "footer");
connection.write(HeaderAndFooter.create(header, footer, connection.getProtocolVersion()));
}
@Override @Override
public void clearHeaderAndFooter() { public void clearHeaderAndFooter() {
connection.write(HeaderAndFooter.reset()); connection.write(HeaderAndFooter.reset());
@ -97,8 +105,8 @@ public class VelocityTabList implements TabList {
} }
@Override @Override
public TabListEntry buildEntry(GameProfile profile, @Nullable Component displayName, int latency, public TabListEntry buildEntry(GameProfile profile,
int gameMode) { net.kyori.adventure.text.@Nullable Component displayName, int latency, int gameMode) {
return new VelocityTabListEntry(this, profile, displayName, latency, gameMode); return new VelocityTabListEntry(this, profile, displayName, latency, gameMode);
} }

Datei anzeigen

@ -2,6 +2,7 @@ package com.velocitypowered.proxy.tablist;
import com.velocitypowered.api.proxy.player.TabList; import com.velocitypowered.api.proxy.player.TabList;
import com.velocitypowered.api.proxy.player.TabListEntry; import com.velocitypowered.api.proxy.player.TabListEntry;
import com.velocitypowered.api.util.AdventureCompat;
import com.velocitypowered.api.util.GameProfile; import com.velocitypowered.api.util.GameProfile;
import com.velocitypowered.proxy.protocol.packet.PlayerListItem; import com.velocitypowered.proxy.protocol.packet.PlayerListItem;
import java.util.Optional; import java.util.Optional;
@ -12,12 +13,12 @@ public class VelocityTabListEntry implements TabListEntry {
private final VelocityTabList tabList; private final VelocityTabList tabList;
private final GameProfile profile; private final GameProfile profile;
private @Nullable Component displayName; private net.kyori.adventure.text.Component displayName;
private int latency; private int latency;
private int gameMode; private int gameMode;
VelocityTabListEntry(VelocityTabList tabList, GameProfile profile, VelocityTabListEntry(VelocityTabList tabList, GameProfile profile,
@Nullable Component displayName, int latency, int gameMode) { net.kyori.adventure.text.@Nullable Component displayName, int latency, int gameMode) {
this.tabList = tabList; this.tabList = tabList;
this.profile = profile; this.profile = profile;
this.displayName = displayName; this.displayName = displayName;
@ -37,17 +38,27 @@ public class VelocityTabListEntry implements TabListEntry {
@Override @Override
public Optional<Component> getDisplayName() { public Optional<Component> getDisplayName() {
return Optional.ofNullable(displayName).map(AdventureCompat::asOriginalTextComponent);
}
@Override
public Optional<net.kyori.adventure.text.Component> getDisplayNameComponent() {
return Optional.ofNullable(displayName); return Optional.ofNullable(displayName);
} }
@Override @Override
public TabListEntry setDisplayName(@Nullable Component displayName) { public TabListEntry setDisplayName(@Nullable Component displayName) {
return this.setDisplayName(AdventureCompat.asAdventureComponent(displayName));
}
@Override
public TabListEntry setDisplayName(net.kyori.adventure.text.@Nullable Component displayName) {
this.displayName = displayName; this.displayName = displayName;
tabList.updateEntry(PlayerListItem.UPDATE_DISPLAY_NAME, this); tabList.updateEntry(PlayerListItem.UPDATE_DISPLAY_NAME, this);
return this; return this;
} }
void setDisplayNameInternal(@Nullable Component displayName) { void setDisplayNameInternal(net.kyori.adventure.text.@Nullable Component displayName) {
this.displayName = displayName; this.displayName = displayName;
} }

Datei anzeigen

@ -2,7 +2,7 @@ package com.velocitypowered.proxy.tablist;
import com.velocitypowered.api.proxy.player.TabListEntry; import com.velocitypowered.api.proxy.player.TabListEntry;
import com.velocitypowered.api.util.GameProfile; import com.velocitypowered.api.util.GameProfile;
import net.kyori.text.Component; import net.kyori.adventure.text.Component;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
public class VelocityTabListEntryLegacy extends VelocityTabListEntry { public class VelocityTabListEntryLegacy extends VelocityTabListEntry {

Datei anzeigen

@ -11,7 +11,7 @@ import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import net.kyori.text.Component; import net.kyori.adventure.text.Component;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
public class VelocityTabListLegacy extends VelocityTabList { public class VelocityTabListLegacy extends VelocityTabList {
@ -22,6 +22,10 @@ public class VelocityTabListLegacy extends VelocityTabList {
super(connection); super(connection);
} }
@Override
public void setHeaderAndFooter(net.kyori.text.Component header, net.kyori.text.Component footer) {
}
@Override @Override
public void setHeaderAndFooter(Component header, Component footer) { public void setHeaderAndFooter(Component header, Component footer) {
} }
@ -55,7 +59,6 @@ public class VelocityTabListLegacy extends VelocityTabList {
@Override @Override
public void processBackendPacket(PlayerListItem packet) { public void processBackendPacket(PlayerListItem packet) {
Item item = packet.getItems().get(0); // Only one item per packet in 1.7 Item item = packet.getItems().get(0); // Only one item per packet in 1.7
switch (packet.getAction()) { switch (packet.getAction()) {

Datei anzeigen

@ -1,27 +1,25 @@
package com.velocitypowered.proxy.util; package com.velocitypowered.proxy.util;
import net.kyori.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.text.TextComponent; import net.kyori.adventure.text.TextComponent;
import net.kyori.text.format.TextColor; import net.kyori.adventure.text.format.NamedTextColor;
public class VelocityMessages { public class VelocityMessages {
public static final Component ONLINE_MODE_ONLY = TextComponent public static final Component ONLINE_MODE_ONLY = TextComponent
.builder("This server only accepts connections from online-mode clients.") .builder("This server only accepts connections from online-mode clients.")
.color(TextColor.RED) .color(NamedTextColor.RED)
.append( .append(
TextComponent.of("\n\nDid you change your username? Sign out of Minecraft, sign back in, " TextComponent.of("\n\nDid you change your username? Sign out of Minecraft, sign back in, "
+ "and try again.", TextColor.GRAY) + "and try again.", NamedTextColor.GRAY)
) )
.build(); .build();
public static final Component NO_PROXY_BEHIND_PROXY = TextComponent
.of("Running Velocity behind Velocity isn't supported.", TextColor.RED);
public static final Component NO_AVAILABLE_SERVERS = TextComponent public static final Component NO_AVAILABLE_SERVERS = TextComponent
.of("No available servers", TextColor.RED); .of("No available servers", NamedTextColor.RED);
public static final Component ALREADY_CONNECTED = TextComponent public static final Component ALREADY_CONNECTED = TextComponent
.of("You are already connected to this proxy!", TextColor.RED); .of("You are already connected to this proxy!", NamedTextColor.RED);
public static final Component MOVED_TO_NEW_SERVER = TextComponent public static final Component MOVED_TO_NEW_SERVER = TextComponent
.of("The server you were on kicked you: ", TextColor.RED); .of("The server you were on kicked you: ", NamedTextColor.RED);
private VelocityMessages() { private VelocityMessages() {
throw new AssertionError(); throw new AssertionError();