#3864: Add ServerLinks API

This commit is contained in:
Outfluencer
2025-07-23 19:13:03 +10:00
committed by md_5
parent 8e99a4c5bf
commit e62fc6c291
4 changed files with 111 additions and 20 deletions

View File

@@ -0,0 +1,77 @@
package net.md_5.bungee.api;
import lombok.AccessLevel;
import lombok.Data;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import net.md_5.bungee.api.chat.BaseComponent;
/**
* Represents a server link which may be sent to the client.
*/
@Data
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
public final class ServerLink
{
/**
* The links type.
*
* Note: This value is nullable, if null, label is non-null.
*/
private final LinkType type;
/**
* The label for the link.
*
* Note: This value is nullable, if null, type is non-null.
*/
private final BaseComponent label;
/**
* The URL that is displayed.
*/
@NonNull
private final String url;
/**
* Creates a link with a specified type and URL.
*
* @param type the type of the link
* @param url the URL to be displayed
*/
public ServerLink(@NonNull LinkType type, @NonNull String url)
{
this.type = type;
this.label = null;
this.url = url;
}
/**
* Creates a link with a label and URL.
*
* @param label the label to be displayed
* @param url the URL to be displayed
*/
public ServerLink(@NonNull BaseComponent label, @NonNull String url)
{
this.type = null;
this.label = label;
this.url = url;
}
public enum LinkType
{
REPORT_BUG,
COMMUNITY_GUIDELINES,
SUPPORT,
STATUS,
FEEDBACK,
COMMUNITY,
WEBSITE,
FORUMS,
NEWS,
ANNOUNCEMENTS;
}
}

View File

@@ -1,5 +1,6 @@
package net.md_5.bungee.api.connection; package net.md_5.bungee.api.connection;
import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
@@ -8,6 +9,7 @@ import net.md_5.bungee.api.Callback;
import net.md_5.bungee.api.ChatMessageType; import net.md_5.bungee.api.ChatMessageType;
import net.md_5.bungee.api.CommandSender; import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.ServerConnectRequest; import net.md_5.bungee.api.ServerConnectRequest;
import net.md_5.bungee.api.ServerLink;
import net.md_5.bungee.api.SkinConfiguration; import net.md_5.bungee.api.SkinConfiguration;
import net.md_5.bungee.api.Title; import net.md_5.bungee.api.Title;
import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.api.chat.BaseComponent;
@@ -411,4 +413,16 @@ public interface ProxiedPlayer extends Connection, CommandSender
*/ */
@ApiStatus.Experimental @ApiStatus.Experimental
void showDialog(Dialog dialog); void showDialog(Dialog dialog);
/**
* Sends server links to the player.
*
* Note: The links already sent to the player will be overwritten. Also, the
* backend server is able to override links sent by the proxy.
*
* @param serverLinks the server links to send
* @throws IllegalStateException if the player's version is not at least
* 1.21
*/
void sendServerLinks(List<ServerLink> serverLinks);
} }

View File

@@ -27,10 +27,10 @@ public class ServerLinks extends DefinedPacket
links = new Link[ len ]; links = new Link[ len ];
for ( int i = 0; i < len; i++ ) for ( int i = 0; i < len; i++ )
{ {
Either<LinkType, BaseComponent> type; Either<Integer, BaseComponent> type;
if ( buf.readBoolean() ) if ( buf.readBoolean() )
{ {
type = Either.left( LinkType.values()[readVarInt( buf )] ); type = Either.left( readVarInt( buf ) );
} else } else
{ {
type = Either.right( readBaseComponent( buf, protocolVersion ) ); type = Either.right( readBaseComponent( buf, protocolVersion ) );
@@ -47,11 +47,11 @@ public class ServerLinks extends DefinedPacket
writeVarInt( links.length, buf ); writeVarInt( links.length, buf );
for ( Link link : links ) for ( Link link : links )
{ {
Either<LinkType, BaseComponent> type = link.getType(); Either<Integer, BaseComponent> type = link.getType();
if ( type.isLeft() ) if ( type.isLeft() )
{ {
buf.writeBoolean( true ); buf.writeBoolean( true );
writeVarInt( type.getLeft().ordinal(), buf ); writeVarInt( type.getLeft(), buf );
} else } else
{ {
buf.writeBoolean( false ); buf.writeBoolean( false );
@@ -67,26 +67,11 @@ public class ServerLinks extends DefinedPacket
handler.handle( this ); handler.handle( this );
} }
public enum LinkType
{
REPORT_BUG,
COMMUNITY_GUIDELINES,
SUPPORT,
STATUS,
FEEDBACK,
COMMUNITY,
WEBSITE,
FORUMS,
NEWS,
ANNOUNCEMENTS;
}
@Data @Data
public static class Link public static class Link
{ {
private final Either<LinkType, BaseComponent> type; private final Either<Integer, BaseComponent> type;
private final String url; private final String url;
} }
} }

View File

@@ -14,6 +14,7 @@ import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
@@ -29,6 +30,7 @@ import net.md_5.bungee.api.Callback;
import net.md_5.bungee.api.ChatMessageType; import net.md_5.bungee.api.ChatMessageType;
import net.md_5.bungee.api.ProxyServer; import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.api.ServerConnectRequest; import net.md_5.bungee.api.ServerConnectRequest;
import net.md_5.bungee.api.ServerLink;
import net.md_5.bungee.api.SkinConfiguration; import net.md_5.bungee.api.SkinConfiguration;
import net.md_5.bungee.api.Title; import net.md_5.bungee.api.Title;
import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.api.chat.BaseComponent;
@@ -59,6 +61,7 @@ import net.md_5.bungee.protocol.packet.ClientSettings;
import net.md_5.bungee.protocol.packet.Kick; import net.md_5.bungee.protocol.packet.Kick;
import net.md_5.bungee.protocol.packet.PlayerListHeaderFooter; import net.md_5.bungee.protocol.packet.PlayerListHeaderFooter;
import net.md_5.bungee.protocol.packet.PluginMessage; import net.md_5.bungee.protocol.packet.PluginMessage;
import net.md_5.bungee.protocol.packet.ServerLinks;
import net.md_5.bungee.protocol.packet.SetCompression; import net.md_5.bungee.protocol.packet.SetCompression;
import net.md_5.bungee.protocol.packet.ShowDialog; import net.md_5.bungee.protocol.packet.ShowDialog;
import net.md_5.bungee.protocol.packet.ShowDialogDirect; import net.md_5.bungee.protocol.packet.ShowDialogDirect;
@@ -860,4 +863,16 @@ public final class UserConnection implements ProxiedPlayer
unsafe.sendPacket( new ShowDialog( Either.right( dialog ) ) ); unsafe.sendPacket( new ShowDialog( Either.right( dialog ) ) );
} }
@Override
public void sendServerLinks(List<ServerLink> serverLinks)
{
Preconditions.checkState( getPendingConnection().getVersion() >= ProtocolConstants.MINECRAFT_1_21, "Server links are only supported in 1.21 and above" );
ServerLinks.Link[] links = serverLinks.stream()
.map( link -> new ServerLinks.Link( link.getType() != null ? Either.left( link.getType().ordinal() ) : Either.right( link.getLabel() ), link.getUrl() ) )
.toArray( ServerLinks.Link[]::new );
unsafe.sendPacket( new ServerLinks( links ) );
}
} }