Use components for ServerKickEvent (fixes #744) + minor refactoring

This commit is contained in:
Thinkofdeath 2013-12-06 18:26:22 +00:00
parent c20d8f9cd6
commit 2c8b15cb1e
14 changed files with 210 additions and 115 deletions

View File

@ -19,6 +19,7 @@ public interface CommandSender
* *
* @param message the message to send * @param message the message to send
*/ */
@Deprecated
public void sendMessage(String message); public void sendMessage(String message);
/** /**
@ -27,6 +28,7 @@ public interface CommandSender
* *
* @param messages the messages to send * @param messages the messages to send
*/ */
@Deprecated
public void sendMessages(String... messages); public void sendMessages(String... messages);
/** /**

View File

@ -232,6 +232,7 @@ public abstract class ProxyServer
* *
* @param message the message to broadcast * @param message the message to broadcast
*/ */
@Deprecated
public abstract void broadcast(String message); public abstract void broadcast(String message);
/** /**

View File

@ -49,6 +49,22 @@ public abstract class BaseComponent {
setObfuscated(old.isObfuscatedRaw()); setObfuscated(old.isObfuscatedRaw());
} }
public static String toLegacyText(BaseComponent[] components) {
StringBuilder builder = new StringBuilder();
for (BaseComponent msg : components) {
builder.append(msg.toLegacyText());
}
return builder.toString();
}
public static String toPlainText(BaseComponent[] components) {
StringBuilder builder = new StringBuilder();
for (BaseComponent msg : components) {
builder.append(msg.toPlainText());
}
return builder.toString();
}
/** /**
* Returns the color of this component. This uses the parent's color * Returns the color of this component. This uses the parent's color

View File

@ -6,11 +6,104 @@ import lombok.NoArgsConstructor;
import lombok.Setter; import lombok.Setter;
import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.ChatColor;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@Getter @Getter
@Setter @Setter
@AllArgsConstructor @AllArgsConstructor
@NoArgsConstructor @NoArgsConstructor
public class TextComponent extends BaseComponent { public class TextComponent extends BaseComponent {
private static final Pattern url = Pattern.compile("^(?:(https?)://)?([-\\w_\\.]{2,}\\.[a-z]{2,4})(/\\S*)?$");
public static BaseComponent[] fromLegacyText(String message) {
ArrayList<BaseComponent> components = new ArrayList<>();
StringBuilder builder = new StringBuilder();
TextComponent component = new TextComponent();
Matcher matcher = url.matcher(message);
for ( int i = 0; i < message.length(); i++ ) {
char c = message.charAt(i);
if (c == ChatColor.COLOR_CHAR) {
i++;
c = message.charAt(i);
if (c >= 'A' && c <= 'Z') {
c += 32;
}
if (builder.length() > 0) {
TextComponent old = component;
component = new TextComponent(old);
old.setText(builder.toString());
builder = new StringBuilder();
components.add(old);
}
ChatColor format = ChatColor.getByChar(c);
switch (format) {
case BOLD:
component.setBold(true);
break;
case ITALIC:
component.setItalic(true);
break;
case UNDERLINE:
component.setUnderlined(true);
break;
case STRIKETHROUGH:
component.setStrikethrough(true);
break;
case MAGIC:
component.setObfuscated(true);
break;
case RESET:
format = ChatColor.WHITE;
default:
component = new TextComponent();
component.setColor(format);
break;
}
continue;
}
int pos = message.indexOf(' ', i);
if (pos == -1) pos = message.length();
if (matcher.region(i, pos).find()) { //Web link handling
if (builder.length() > 0) {
TextComponent old = component;
component = new TextComponent(old);
old.setText(builder.toString());
builder = new StringBuilder();
components.add(old);
}
TextComponent old = component;
component = new TextComponent(old);
ClickEvent clickEvent = new ClickEvent();
clickEvent.setAction(ClickEvent.Action.OPEN_URL);
String urlString = message.substring(i, pos);
if (urlString.startsWith("http")) {
component.setText(urlString);
clickEvent.setValue(urlString);
} else {
component.setText(urlString);
clickEvent.setValue("http://" + urlString);
}
component.setClickEvent(clickEvent);
components.add(component);
i += pos - i - 1;
component = old;
continue;
}
builder.append(c);
}
if (builder.length() > 0) {
component.setText(builder.toString());
components.add(component);
}
return components.toArray(new BaseComponent[components.size()]);
}
private String text; private String text;
public TextComponent(TextComponent old) { public TextComponent(TextComponent old) {

View File

@ -1,6 +1,8 @@
package net.md_5.bungee.api.connection; package net.md_5.bungee.api.connection;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.protocol.DefinedPacket; import net.md_5.bungee.protocol.DefinedPacket;
/** /**
@ -26,8 +28,29 @@ public interface Connection
* @param reason the reason shown to the player / sent to the server on * @param reason the reason shown to the player / sent to the server on
* disconnect * disconnect
*/ */
@Deprecated
void disconnect(String reason); void disconnect(String reason);
/**
* Disconnects this end of the connection for the specified reason. If this
* is an {@link ProxiedPlayer} the respective server connection will be
* closed too.
*
* @param reason the reason shown to the player / sent to the server on
* disconnect
*/
void disconnect(BaseComponent[] reason);
/**
* Disconnects this end of the connection for the specified reason. If this
* is an {@link ProxiedPlayer} the respective server connection will be
* closed too.
*
* @param reason the reason shown to the player / sent to the server on
* disconnect
*/
void disconnect(BaseComponent reason);
/** /**
* Get the unsafe methods of this class. * Get the unsafe methods of this class.
* *

View File

@ -3,6 +3,8 @@ package net.md_5.bungee.api.event;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.ToString; import lombok.ToString;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.config.ServerInfo; import net.md_5.bungee.api.config.ServerInfo;
import net.md_5.bungee.api.connection.ProxiedPlayer; import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.api.plugin.Cancellable; import net.md_5.bungee.api.plugin.Cancellable;
@ -28,7 +30,7 @@ public class ServerKickEvent extends Event implements Cancellable
/** /**
* Kick reason. * Kick reason.
*/ */
private String kickReason; private BaseComponent[] kickReasonComponent;
/** /**
* Server to send player to if this event is cancelled. * Server to send player to if this event is cancelled.
*/ */
@ -44,16 +46,26 @@ public class ServerKickEvent extends Event implements Cancellable
CONNECTING, CONNECTED, UNKNOWN; CONNECTING, CONNECTED, UNKNOWN;
} }
public ServerKickEvent(ProxiedPlayer player, String kickReason, ServerInfo cancelServer) public ServerKickEvent(ProxiedPlayer player, BaseComponent[] kickReasonComponent, ServerInfo cancelServer)
{ {
this( player, kickReason, cancelServer, State.UNKNOWN ); this( player, kickReasonComponent, cancelServer, State.UNKNOWN );
} }
public ServerKickEvent(ProxiedPlayer player, String kickReason, ServerInfo cancelServer, State state) public ServerKickEvent(ProxiedPlayer player, BaseComponent[] kickReasonComponent, ServerInfo cancelServer, State state)
{ {
this.player = player; this.player = player;
this.kickReason = kickReason; this.kickReasonComponent = kickReasonComponent;
this.cancelServer = cancelServer; this.cancelServer = cancelServer;
this.state = state; this.state = state;
} }
@Deprecated
public String getKickReason() {
return BaseComponent.toLegacyText(kickReasonComponent);
}
@Deprecated
public void setKickReason(String reason) {
kickReasonComponent = TextComponent.fromLegacyText(reason);
}
} }

View File

@ -2,6 +2,7 @@ package net.md_5.bungee;
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;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.chat.ComponentSerializer; import net.md_5.bungee.chat.ComponentSerializer;
import net.md_5.bungee.log.BungeeLogger; import net.md_5.bungee.log.BungeeLogger;
import net.md_5.bungee.reconnect.YamlReconnectHandler; import net.md_5.bungee.reconnect.YamlReconnectHandler;
@ -489,17 +490,13 @@ public class BungeeCord extends ProxyServer
public void broadcast(String message) public void broadcast(String message)
{ {
getConsole().sendMessage( message ); getConsole().sendMessage( message );
broadcast(ComponentSerializer.fromLegacyChat(message)); broadcast(TextComponent.fromLegacyText(message));
} }
@Override @Override
public void broadcast(BaseComponent[] message) { public void broadcast(BaseComponent[] message) {
StringBuilder constr = new StringBuilder(); getConsole().sendMessage(BaseComponent.toLegacyText(message));
for (BaseComponent msg : message) { broadcast(new Chat(ComponentSerializer.toString(message)));
constr.append( msg.toLegacyText() );
}
getConsole().sendMessage( constr.toString() );
broadcast( new Chat(ComponentSerializer.toString(message)) );
} }
@Override @Override

View File

@ -5,7 +5,10 @@ import java.util.concurrent.TimeUnit;
import lombok.Getter; import lombok.Getter;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.Setter; import lombok.Setter;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.connection.Server; import net.md_5.bungee.api.connection.Server;
import net.md_5.bungee.chat.ComponentSerializer;
import net.md_5.bungee.netty.ChannelWrapper; import net.md_5.bungee.netty.ChannelWrapper;
import net.md_5.bungee.protocol.DefinedPacket; import net.md_5.bungee.protocol.DefinedPacket;
import net.md_5.bungee.protocol.packet.PluginMessage; import net.md_5.bungee.protocol.packet.PluginMessage;
@ -40,10 +43,15 @@ public class ServerConnection implements Server
@Override @Override
public synchronized void disconnect(String reason) public synchronized void disconnect(String reason)
{ {
disconnect( TextComponent.fromLegacyText(reason) );
}
@Override
public void disconnect(BaseComponent[] reason) {
if ( !ch.isClosed() ) if ( !ch.isClosed() )
{ {
// TODO: Can we just use a future here? // TODO: Can we just use a future here?
unsafe().sendPacket( new Kick( reason ) ); unsafe().sendPacket( new Kick(ComponentSerializer.toString(reason) ) );
ch.getHandle().eventLoop().schedule( new Runnable() ch.getHandle().eventLoop().schedule( new Runnable()
{ {
@Override @Override
@ -53,6 +61,12 @@ public class ServerConnection implements Server
} }
}, 100, TimeUnit.MILLISECONDS ); }, 100, TimeUnit.MILLISECONDS );
} }
}
@Override
public void disconnect(BaseComponent reason) {
disconnect(new BaseComponent[]{reason});
} }
@Override @Override

View File

@ -15,6 +15,7 @@ import net.md_5.bungee.api.event.ServerSwitchEvent;
import net.md_5.bungee.api.score.Objective; import net.md_5.bungee.api.score.Objective;
import net.md_5.bungee.api.score.Scoreboard; import net.md_5.bungee.api.score.Scoreboard;
import net.md_5.bungee.api.score.Team; import net.md_5.bungee.api.score.Team;
import net.md_5.bungee.chat.ComponentSerializer;
import net.md_5.bungee.connection.CancelSendSignal; import net.md_5.bungee.connection.CancelSendSignal;
import net.md_5.bungee.connection.DownstreamBridge; import net.md_5.bungee.connection.DownstreamBridge;
import net.md_5.bungee.netty.HandlerBoss; import net.md_5.bungee.netty.HandlerBoss;
@ -211,7 +212,7 @@ public class ServerConnector extends PacketHandler
{ {
def = null; def = null;
} }
ServerKickEvent event = bungee.getPluginManager().callEvent( new ServerKickEvent( user, kick.getMessage(), def, ServerKickEvent.State.CONNECTING ) ); ServerKickEvent event = bungee.getPluginManager().callEvent( new ServerKickEvent( user, ComponentSerializer.parse(kick.getMessage()), def, ServerKickEvent.State.CONNECTING ) );
if ( event.isCancelled() && event.getCancelServer() != null ) if ( event.isCancelled() && event.getCancelServer() != null )
{ {
user.connect( event.getCancelServer() ); user.connect( event.getCancelServer() );

View File

@ -21,6 +21,7 @@ import lombok.RequiredArgsConstructor;
import lombok.Setter; import lombok.Setter;
import net.md_5.bungee.api.ProxyServer; import net.md_5.bungee.api.ProxyServer;
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.config.ServerInfo; import net.md_5.bungee.api.config.ServerInfo;
import net.md_5.bungee.api.connection.ProxiedPlayer; import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.api.event.PermissionCheckEvent; import net.md_5.bungee.api.event.PermissionCheckEvent;
@ -258,15 +259,25 @@ public final class UserConnection implements ProxiedPlayer
@Override @Override
public synchronized void disconnect(String reason) public synchronized void disconnect(String reason)
{ {
disconnect0( ComponentSerializer.toString( ComponentSerializer.fromLegacyChat( reason ) ) ); disconnect0( TextComponent.fromLegacyText(reason) );
} }
public synchronized void disconnect0(String reason) @Override
public void disconnect(BaseComponent[] reason) {
disconnect0( reason );
}
@Override
public void disconnect(BaseComponent reason) {
disconnect0(new BaseComponent[]{reason});
}
public synchronized void disconnect0(BaseComponent[] reason)
{ {
if ( ch.getHandle().isActive() ) if ( ch.getHandle().isActive() )
{ {
bungee.getLogger().log( Level.INFO, "[" + getName() + "] disconnected with: " + reason ); bungee.getLogger().log( Level.INFO, "[" + getName() + "] disconnected with: " + BaseComponent.toLegacyText(reason) );
unsafe().sendPacket( new Kick( reason ) ); unsafe().sendPacket( new Kick( ComponentSerializer.toString(reason) ) );
ch.close(); ch.close();
if ( server != null ) if ( server != null )
{ {
@ -285,7 +296,7 @@ public final class UserConnection implements ProxiedPlayer
@Override @Override
public void sendMessage(String message) public void sendMessage(String message)
{ {
sendMessage(ComponentSerializer.fromLegacyChat(message)); sendMessage(TextComponent.fromLegacyText(message));
} }
@Override @Override

View File

@ -25,8 +25,6 @@ public class ComponentSerializer implements JsonSerializer<BaseComponent>, JsonD
registerTypeAdapter(TranslatableComponent.class, new TranslatableComponentSerializer()). registerTypeAdapter(TranslatableComponent.class, new TranslatableComponentSerializer()).
create(); create();
private static final Pattern url = Pattern.compile("^(?:(https?)://)?([-\\w_\\.]{2,}\\.[a-z]{2,4})(/\\S*)?$");
public static BaseComponent[] parse(String json) { public static BaseComponent[] parse(String json) {
if (json.startsWith("[")) { //Array if (json.startsWith("[")) { //Array
return gson.fromJson(json, BaseComponent[].class); return gson.fromJson(json, BaseComponent[].class);
@ -42,92 +40,6 @@ public class ComponentSerializer implements JsonSerializer<BaseComponent>, JsonD
return gson.toJson(components); return gson.toJson(components);
} }
public static BaseComponent[] fromLegacyChat(String message) {
ArrayList<BaseComponent> components = new ArrayList<>();
StringBuilder builder = new StringBuilder();
TextComponent component = new TextComponent();
Matcher matcher = url.matcher(message);
for ( int i = 0; i < message.length(); i++ ) {
char c = message.charAt(i);
if (c == ChatColor.COLOR_CHAR) {
i++;
c = message.charAt(i);
if (c >= 'A' && c <= 'Z') {
c += 32;
}
if (builder.length() > 0) {
TextComponent old = component;
component = new TextComponent(old);
old.setText(builder.toString());
builder = new StringBuilder();
components.add(old);
}
ChatColor format = ChatColor.getByChar(c);
switch (format) {
case BOLD:
component.setBold(true);
break;
case ITALIC:
component.setItalic(true);
break;
case UNDERLINE:
component.setUnderlined(true);
break;
case STRIKETHROUGH:
component.setStrikethrough(true);
break;
case MAGIC:
component.setObfuscated(true);
break;
case RESET:
format = ChatColor.WHITE;
default:
component = new TextComponent();
component.setColor(format);
break;
}
continue;
}
int pos = message.indexOf(' ', i);
if (pos == -1) pos = message.length();
if (matcher.region(i, pos).find()) { //Web link handling
if (builder.length() > 0) {
TextComponent old = component;
component = new TextComponent(old);
old.setText(builder.toString());
builder = new StringBuilder();
components.add(old);
}
TextComponent old = component;
component = new TextComponent(old);
ClickEvent clickEvent = new ClickEvent();
clickEvent.setAction(ClickEvent.Action.OPEN_URL);
String urlString = message.substring(i, pos);
if (urlString.startsWith("http")) {
component.setText(urlString);
clickEvent.setValue(urlString);
} else {
component.setText(urlString);
clickEvent.setValue("http://" + urlString);
}
component.setClickEvent(clickEvent);
components.add(component);
i += pos - i - 1;
component = old;
continue;
}
builder.append(c);
}
if (builder.length() > 0) {
component.setText(builder.toString());
components.add(component);
}
return components.toArray(new BaseComponent[components.size()]);
}
@Override @Override
public BaseComponent deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { public BaseComponent deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
if (json.isJsonPrimitive()) { if (json.isJsonPrimitive()) {

View File

@ -37,11 +37,7 @@ public class ConsoleCommandSender implements CommandSender
@Override @Override
public void sendMessage(BaseComponent[] message) { public void sendMessage(BaseComponent[] message) {
StringBuilder constr = new StringBuilder(); sendMessage(BaseComponent.toLegacyText(message));
for (BaseComponent msg : message) {
constr.append( msg.toLegacyText() );
}
sendMessage( constr.toString() );
} }
@Override @Override

View File

@ -22,6 +22,7 @@ import net.md_5.bungee.api.score.Position;
import net.md_5.bungee.api.score.Score; import net.md_5.bungee.api.score.Score;
import net.md_5.bungee.api.score.Scoreboard; import net.md_5.bungee.api.score.Scoreboard;
import net.md_5.bungee.api.score.Team; import net.md_5.bungee.api.score.Team;
import net.md_5.bungee.chat.ComponentSerializer;
import net.md_5.bungee.netty.ChannelWrapper; import net.md_5.bungee.netty.ChannelWrapper;
import net.md_5.bungee.netty.PacketHandler; import net.md_5.bungee.netty.PacketHandler;
import net.md_5.bungee.protocol.PacketWrapper; import net.md_5.bungee.protocol.PacketWrapper;
@ -357,13 +358,13 @@ public class DownstreamBridge extends PacketHandler
{ {
def = null; def = null;
} }
ServerKickEvent event = bungee.getPluginManager().callEvent( new ServerKickEvent( con, kick.getMessage(), def, ServerKickEvent.State.CONNECTED ) ); ServerKickEvent event = bungee.getPluginManager().callEvent( new ServerKickEvent( con, ComponentSerializer.parse(kick.getMessage()), def, ServerKickEvent.State.CONNECTED ) );
if ( event.isCancelled() && event.getCancelServer() != null ) if ( event.isCancelled() && event.getCancelServer() != null )
{ {
con.connectNow( event.getCancelServer() ); con.connectNow( event.getCancelServer() );
} else } else
{ {
con.disconnect0( event.getKickReason() ); // TODO: Json concat util method // TODO: Prefix our own stuff. con.disconnect0( event.getKickReasonComponent() ); // TODO: Prefix our own stuff.
} }
server.setObsolete( true ); server.setObsolete( true );
throw new CancelSendSignal(); throw new CancelSendSignal();

View File

@ -16,6 +16,8 @@ import net.md_5.bungee.api.Callback;
import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.ProxyServer; import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.api.ServerPing; import net.md_5.bungee.api.ServerPing;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.config.ListenerInfo; import net.md_5.bungee.api.config.ListenerInfo;
import net.md_5.bungee.api.config.ServerInfo; import net.md_5.bungee.api.config.ServerInfo;
import net.md_5.bungee.api.connection.PendingConnection; import net.md_5.bungee.api.connection.PendingConnection;
@ -398,11 +400,25 @@ public class InitialHandler extends PacketHandler implements PendingConnection
{ {
if ( !ch.isClosed() ) if ( !ch.isClosed() )
{ {
unsafe().sendPacket( new Kick( ComponentSerializer.toString(ComponentSerializer.fromLegacyChat(reason)) ) ); unsafe().sendPacket( new Kick( ComponentSerializer.toString(TextComponent.fromLegacyText(reason)) ) );
ch.close(); ch.close();
} }
} }
@Override
public void disconnect(BaseComponent[] reason) {
if ( !ch.isClosed() )
{
unsafe().sendPacket( new Kick( ComponentSerializer.toString(reason) ) );
ch.close();
}
}
@Override
public void disconnect(BaseComponent reason) {
disconnect(new BaseComponent[]{reason});
}
@Override @Override
public String getName() public String getName()
{ {