@Override public void handle(Chat chat) throws Exception { ChatEvent chatEvent = new ChatEvent(con, con.getServer(), chat.getMessage()); if (!bungee.getPluginManager().callEvent(chatEvent).isCancelled()) { chat.setMessage(chatEvent.getMessage()); if (!chatEvent.isCommand() || !bungee.getPluginManager().dispatchCommand(con, chat.getMessage().substring(1))) { con.getServer().unsafe().sendPacket(chat); } } throw new CancelSendSignal(); }
@Override public boolean hasPermission(String permission) { return bungee .getPluginManager() .callEvent(new PermissionCheckEvent(this, permission, permissions.contains(permission))) .hasPermission(); }
@Override public void disconnected(ChannelWrapper channel) throws Exception { // We lost connection to the client PlayerDisconnectEvent event = new PlayerDisconnectEvent(con); bungee.getPluginManager().callEvent(event); con.getTabList().onDisconnect(); BungeeCord.getInstance().removeConnection(con); if (con.getServer() != null) { con.getServer().disconnect("Quitting"); } }
@Override public void handle(TabCompleteRequest tabComplete) throws Exception { if (tabComplete.getCursor().startsWith("/")) { List<String> results = new ArrayList<>(); bungee.getPluginManager().dispatchCommand(con, tabComplete.getCursor().substring(1), results); if (!results.isEmpty()) { con.unsafe() .sendPacket(new TabCompleteResponse(results.toArray(new String[results.size()]))); throw new CancelSendSignal(); } } }
@Override public void handle(PacketFAPluginMessage pluginMessage) throws Exception { if (pluginMessage.getTag().equals("BungeeCord")) { throw new CancelSendSignal(); } // Hack around Forge race conditions if (pluginMessage.getTag().equals("FML") && (pluginMessage.getData()[0] & 0xFF) == 1) { throw new CancelSendSignal(); } PluginMessageEvent event = new PluginMessageEvent( con, con.getServer(), pluginMessage.getTag(), pluginMessage.getData().clone()); if (bungee.getPluginManager().callEvent(event).isCancelled()) { throw new CancelSendSignal(); } }
@Override public void handle(PluginMessage pluginMessage) throws Exception { if (pluginMessage.getTag().equals("BungeeCord")) { throw new CancelSendSignal(); } // Hack around Forge race conditions if (pluginMessage.getTag().equals("FML") && pluginMessage.getStream().readUnsignedByte() == 1) { throw new CancelSendSignal(); } PluginMessageEvent event = new PluginMessageEvent( con, con.getServer(), pluginMessage.getTag(), pluginMessage.getData().clone()); if (bungee.getPluginManager().callEvent(event).isCancelled()) { throw new CancelSendSignal(); } // TODO: Unregister as well? if (pluginMessage.getTag().equals("REGISTER")) { con.getPendingConnection().getRegisterMessages().add(pluginMessage); } }
public void connect(ServerInfo info, final Callback<Boolean> callback, final boolean retry) { Preconditions.checkNotNull(info, "info"); ServerConnectEvent event = new ServerConnectEvent(this, info); if (bungee.getPluginManager().callEvent(event).isCancelled()) { return; } final BungeeServerInfo target = (BungeeServerInfo) event.getTarget(); // Update in case the event changed target if (getServer() != null && Objects.equals(getServer().getInfo(), target)) { sendMessage(bungee.getTranslation("already_connected")); return; } if (pendingConnects.contains(target)) { sendMessage(bungee.getTranslation("already_connecting")); return; } pendingConnects.add(target); ChannelInitializer initializer = new ChannelInitializer() { @Override protected void initChannel(Channel ch) throws Exception { PipelineUtils.BASE.initChannel(ch); ch.pipeline() .addAfter( PipelineUtils.FRAME_DECODER, PipelineUtils.PACKET_DECODER, new MinecraftDecoder( Protocol.HANDSHAKE, false, getPendingConnection().getVersion())); ch.pipeline() .addAfter( PipelineUtils.FRAME_PREPENDER, PipelineUtils.PACKET_ENCODER, new MinecraftEncoder( Protocol.HANDSHAKE, false, getPendingConnection().getVersion())); ch.pipeline() .get(HandlerBoss.class) .setHandler(new ServerConnector(bungee, UserConnection.this, target)); } }; ChannelFutureListener listener = new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) throws Exception { if (callback != null) { callback.done(future.isSuccess(), future.cause()); } if (!future.isSuccess()) { future.channel().close(); pendingConnects.remove(target); ServerInfo def = ProxyServer.getInstance() .getServers() .get(getPendingConnection().getListener().getFallbackServer()); if (retry && target != def && (getServer() == null || def != getServer().getInfo())) { sendMessage(bungee.getTranslation("fallback_lobby")); connect(def, null, false); } else { if (dimensionChange) { disconnect( bungee.getTranslation("fallback_kick") + future.cause().getClass().getName()); } else { sendMessage( bungee.getTranslation("fallback_kick") + future.cause().getClass().getName()); } } } } }; Bootstrap b = new Bootstrap() .channel(NioSocketChannel.class) .group(ch.getHandle().eventLoop()) .handler(initializer) .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000) // TODO: Configurable .remoteAddress(target.getAddress()); // Windows is bugged, multi homed users will just have to live with random connecting IPs if (getPendingConnection().getListener().isSetLocalAddress() && !PlatformDependent.isWindows()) { b.localAddress(getPendingConnection().getListener().getHost().getHostString(), 0); } b.connect().addListener(listener); }