Add Title API.

This commit is contained in:
Minecrell 2014-09-05 18:58:55 +02:00 committed by Thinkofdeath
parent d6b7157c1c
commit 4e353e9277
9 changed files with 393 additions and 0 deletions

View File

@ -283,4 +283,14 @@ public abstract class ProxyServer
*/ */
public abstract Collection<ProxiedPlayer> matchPlayer(String name); public abstract Collection<ProxiedPlayer> matchPlayer(String name);
/**
* Creates a new empty title configuration.
* In most cases you will want to {@link #reset()} the current title first so
* your title won't be affected by a previous one.
*
* @return A new empty title configuration.
* @see Title
*/
public abstract Title createTitle();
} }

View File

@ -0,0 +1,109 @@
package net.md_5.bungee.api;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.connection.ProxiedPlayer;
/**
* Represents a configuration of a title.
* A title in Minecraft consists of a main title and a sub title.
* It will {@link #fadeIn(int)}, {@link #stay(int)}, and {@link #fadeOut(int)}
* for a specified amount of time.
* In most cases you will want to {@link #reset()} the current title first so
* your title won't be affected by a previous one.
* <p>
* You can create a new configuration by calling {@link ProxyServer#createTitle()}.
*/
public interface Title
{
/**
* Set the title to send to the player.
*
* @param text The text to use as the title.
* @return This title configuration.
*/
public Title title(BaseComponent text);
/**
* Set the title to send to the player.
*
* @param text The text to use as the title.
* @return This title configuration.
*/
public Title title(BaseComponent... text);
/**
* Set the subtitle to send to the player.
*
* @param text The text to use as the subtitle.
* @return This title configuration.
*/
public Title subTitle(BaseComponent text);
/**
* Set the subtitle to send to the player.
*
* @param text The text to use as the subtitle.
* @return This title configuration.
*/
public Title subTitle(BaseComponent... text);
/**
* Set the duration in ticks of the fade in effect of the title.
* Once this period of time is over the title will stay for the amount
* of time specified in {@link #stay(int)}.
* The default value for the official Minecraft version is 20 (1 second).
*
* @param ticks The amount of ticks (1/20 second) for the fade in effect.
* @return This title configuration.
*/
public Title fadeIn(int ticks);
/**
* Set the duration in ticks how long the title should stay on the screen.
* Once this period of time is over the title will fade out using the duration
* specified in {@link #fadeOut(int)}.
* The default value for the official Minecraft version is 60 (3 seconds).
*
* @param ticks The amount of ticks (1/20 second) for the fade in effect.
* @return This title configuration.
*/
public Title stay(int ticks);
/**
* Set the duration in ticks of the fade out effect of the title.
* The default value for the official Minecraft version is 20 (1 second).
*
* @param ticks The amount of ticks (1/20 second) for the fade out effect.
* @return This title configuration.
*/
public Title fadeOut(int ticks);
/**
* Remove the currently displayed title from the player's screen.
* This will keep the currently used display times and will only remove the title.
*
* @return This title configuration.
*/
public Title clear();
/**
* Remove the currently displayed title from the player's screen
* and set the configuration back to the default values.
*
* @return This title configuration.
*/
public Title reset();
/**
* Send this title configuration to the specified player.
* This is the same as calling {@link ProxiedPlayer#sendTitle(Title)}.
*
* @param player The player to send the title to.
* @return This title configuration.
*/
public Title send(ProxiedPlayer player);
}

View File

@ -3,6 +3,7 @@ package net.md_5.bungee.api.connection;
import java.util.Locale; import java.util.Locale;
import net.md_5.bungee.api.Callback; import net.md_5.bungee.api.Callback;
import net.md_5.bungee.api.CommandSender; import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.Title;
import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.config.ServerInfo; import net.md_5.bungee.api.config.ServerInfo;
import java.util.UUID; import java.util.UUID;
@ -141,4 +142,13 @@ public interface ProxiedPlayer extends Connection, CommandSender
* Clears the header and footer displayed in the tab player list. * Clears the header and footer displayed in the tab player list.
*/ */
void resetTabHeader(); void resetTabHeader();
/**
* Sends a {@link Title} to this player.
* This is the same as calling {@link Title#send(ProxiedPlayer)}.
*
* @param title The title to send to the player.
* @see Title
*/
void sendTitle(Title title);
} }

View File

@ -27,6 +27,7 @@ import net.md_5.bungee.protocol.packet.PingPacket;
import net.md_5.bungee.protocol.packet.StatusRequest; import net.md_5.bungee.protocol.packet.StatusRequest;
import net.md_5.bungee.protocol.packet.StatusResponse; import net.md_5.bungee.protocol.packet.StatusResponse;
import net.md_5.bungee.protocol.packet.TabCompleteResponse; import net.md_5.bungee.protocol.packet.TabCompleteResponse;
import net.md_5.bungee.protocol.packet.Title;
public abstract class AbstractPacketHandler public abstract class AbstractPacketHandler
{ {
@ -115,6 +116,10 @@ public abstract class AbstractPacketHandler
{ {
} }
public void handle(Title title) throws Exception
{
}
public void handle(PluginMessage pluginMessage) throws Exception public void handle(PluginMessage pluginMessage) throws Exception
{ {
} }

View File

@ -32,6 +32,7 @@ import net.md_5.bungee.protocol.packet.StatusResponse;
import net.md_5.bungee.protocol.packet.TabCompleteRequest; import net.md_5.bungee.protocol.packet.TabCompleteRequest;
import net.md_5.bungee.protocol.packet.TabCompleteResponse; import net.md_5.bungee.protocol.packet.TabCompleteResponse;
import net.md_5.bungee.protocol.packet.Team; import net.md_5.bungee.protocol.packet.Team;
import net.md_5.bungee.protocol.packet.Title;
public enum Protocol public enum Protocol
{ {
@ -61,6 +62,7 @@ public enum Protocol
TO_CLIENT.registerPacket( 0x3E, Team.class ); TO_CLIENT.registerPacket( 0x3E, Team.class );
TO_CLIENT.registerPacket( 0x3F, PluginMessage.class ); TO_CLIENT.registerPacket( 0x3F, PluginMessage.class );
TO_CLIENT.registerPacket( 0x40, Kick.class ); TO_CLIENT.registerPacket( 0x40, Kick.class );
TO_CLIENT.registerPacket( 0x45, Title.class );
TO_CLIENT.registerPacket( 0x46, SetCompression.class ); TO_CLIENT.registerPacket( 0x46, SetCompression.class );
TO_CLIENT.registerPacket( 0x47, PlayerListHeaderFooter.class ); TO_CLIENT.registerPacket( 0x47, PlayerListHeaderFooter.class );

View File

@ -0,0 +1,77 @@
package net.md_5.bungee.protocol.packet;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import io.netty.buffer.ByteBuf;
import net.md_5.bungee.protocol.AbstractPacketHandler;
import net.md_5.bungee.protocol.DefinedPacket;
import net.md_5.bungee.protocol.ProtocolConstants;
@Data
@NoArgsConstructor
@EqualsAndHashCode(callSuper = false)
public class Title extends DefinedPacket
{
private Action action;
// TITLE & SUBTITLE
private String text;
// TIMES
private int fadeIn;
private int stay;
private int fadeOut;
@Override
public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion)
{
action = Action.values()[readVarInt( buf )];
switch ( action )
{
case TITLE:
case SUBTITLE:
text = readString( buf );
break;
case TIMES:
fadeIn = buf.readInt();
stay = buf.readInt();
fadeOut = buf.readInt();
break;
}
}
@Override
public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion)
{
writeVarInt( action.ordinal(), buf );
switch ( action )
{
case TITLE:
case SUBTITLE:
writeString( text, buf );
break;
case TIMES:
buf.writeInt( fadeIn );
buf.writeInt( stay );
buf.writeInt( fadeOut );
break;
}
}
@Override
public void handle(AbstractPacketHandler handler) throws Exception
{
handler.handle( this );
}
public static enum Action
{
TITLE,
SUBTITLE,
TIMES,
CLEAR,
RESET
}
}

View File

@ -9,6 +9,7 @@ import com.google.common.collect.Sets;
import com.google.gson.GsonBuilder; import com.google.gson.GsonBuilder;
import net.md_5.bungee.api.Favicon; import net.md_5.bungee.api.Favicon;
import net.md_5.bungee.api.ServerPing; import net.md_5.bungee.api.ServerPing;
import net.md_5.bungee.api.Title;
import net.md_5.bungee.module.ModuleManager; import net.md_5.bungee.module.ModuleManager;
import com.google.common.io.ByteStreams; import com.google.common.io.ByteStreams;
import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.api.chat.BaseComponent;
@ -636,4 +637,10 @@ public class BungeeCord extends ProxyServer
} }
} ) ); } ) );
} }
@Override
public Title createTitle()
{
return new BungeeTitle();
}
} }

View File

@ -0,0 +1,166 @@
package net.md_5.bungee;
import net.md_5.bungee.api.Title;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.chat.ComponentSerializer;
import net.md_5.bungee.protocol.DefinedPacket;
import net.md_5.bungee.protocol.ProtocolConstants;
import net.md_5.bungee.protocol.packet.Title.Action;
public class BungeeTitle implements Title
{
private net.md_5.bungee.protocol.packet.Title title, subtitle, times, clear, reset;
private static net.md_5.bungee.protocol.packet.Title createPacket(Action action)
{
net.md_5.bungee.protocol.packet.Title title = new net.md_5.bungee.protocol.packet.Title();
title.setAction( action );
if ( action == Action.TIMES )
{
// Set packet to default values first
title.setFadeIn( 20 );
title.setStay( 60 );
title.setFadeOut( 20 );
}
return title;
}
@Override
public Title title(BaseComponent text)
{
if ( title == null )
{
title = createPacket( Action.TITLE );
}
title.setText( ComponentSerializer.toString( text ) );
return this;
}
@Override
public Title title(BaseComponent... text)
{
if ( title == null )
{
title = createPacket( Action.TITLE );
}
title.setText( ComponentSerializer.toString( text ) );
return this;
}
@Override
public Title subTitle(BaseComponent text)
{
if ( subtitle == null )
{
subtitle = createPacket( Action.SUBTITLE );
}
subtitle.setText( ComponentSerializer.toString( text ) );
return this;
}
@Override
public Title subTitle(BaseComponent... text)
{
if ( subtitle == null )
{
subtitle = createPacket( Action.SUBTITLE );
}
subtitle.setText( ComponentSerializer.toString( text ) );
return this;
}
@Override
public Title fadeIn(int ticks)
{
if ( times == null )
{
times = createPacket( Action.TIMES );
}
times.setFadeIn( ticks );
return this;
}
@Override
public Title stay(int ticks)
{
if ( times == null )
{
times = createPacket( Action.TIMES );
}
times.setStay( ticks );
return this;
}
@Override
public Title fadeOut(int ticks)
{
if ( times == null )
{
times = createPacket( Action.TIMES );
}
times.setFadeOut( ticks );
return this;
}
@Override
public Title clear()
{
if ( clear == null )
{
clear = createPacket( Action.CLEAR );
}
title = null; // No need to send title if we clear it after that again
return this;
}
@Override
public Title reset()
{
if ( reset == null )
{
reset = createPacket( Action.RESET );
}
// No need to send these packets if we reset them later
title = null;
subtitle = null;
times = null;
return this;
}
private static void sendPacket(ProxiedPlayer player, DefinedPacket packet)
{
if ( packet != null )
{
player.unsafe().sendPacket( packet );
}
}
@Override
public Title send(ProxiedPlayer player)
{
if ( player.getPendingConnection().getVersion() >= ProtocolConstants.MINECRAFT_SNAPSHOT )
{
// Send the packets in the correct order
sendPacket( player, clear );
sendPacket( player, reset );
sendPacket( player, times );
sendPacket( player, subtitle );
sendPacket( player, title );
}
return this;
}
}

View File

@ -23,6 +23,7 @@ import lombok.RequiredArgsConstructor;
import lombok.Setter; import lombok.Setter;
import net.md_5.bungee.api.Callback; import net.md_5.bungee.api.Callback;
import net.md_5.bungee.api.ProxyServer; import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.api.Title;
import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.TextComponent; import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.config.ServerInfo; import net.md_5.bungee.api.config.ServerInfo;
@ -504,6 +505,12 @@ public final class UserConnection implements ProxiedPlayer
setTabHeader( (BaseComponent) null, null ); setTabHeader( (BaseComponent) null, null );
} }
@Override
public void sendTitle(Title title)
{
title.send( this );
}
public void setCompressionThreshold(int compressionThreshold) public void setCompressionThreshold(int compressionThreshold)
{ {
if ( this.compressionThreshold == -1 ) if ( this.compressionThreshold == -1 )