Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package net.md_5.bungee.connection;
- import com.google.common.base.Preconditions;
- import com.google.common.io.ByteArrayDataOutput;
- import com.google.common.io.ByteStreams;
- import com.mojang.brigadier.arguments.StringArgumentType;
- import com.mojang.brigadier.builder.LiteralArgumentBuilder;
- import com.mojang.brigadier.builder.RequiredArgumentBuilder;
- import com.mojang.brigadier.suggestion.SuggestionProvider;
- import com.mojang.brigadier.tree.LiteralCommandNode;
- import java.io.DataInput;
- import io.netty.buffer.ByteBuf;
- import io.netty.buffer.ByteBufAllocator;
- import io.netty.buffer.Unpooled;
- import java.util.Map;
- import lombok.RequiredArgsConstructor;
- import net.md_5.bungee.BungeeCord;
- import net.md_5.bungee.ServerConnection;
- import net.md_5.bungee.api.chat.TextComponent;
- import net.md_5.bungee.api.event.ServerDisconnectEvent;
- import net.md_5.bungee.api.event.TabCompleteResponseEvent;
- import net.md_5.bungee.UserConnection;
- import net.md_5.bungee.Util;
- import net.md_5.bungee.api.ProxyServer;
- import net.md_5.bungee.api.config.ServerInfo;
- import net.md_5.bungee.api.connection.ProxiedPlayer;
- import net.md_5.bungee.api.event.PluginMessageEvent;
- import net.md_5.bungee.api.event.ServerConnectEvent;
- import net.md_5.bungee.api.event.ServerKickEvent;
- import net.md_5.bungee.api.plugin.Command;
- import net.md_5.bungee.api.score.Objective;
- import net.md_5.bungee.api.score.Position;
- import net.md_5.bungee.api.score.Score;
- import net.md_5.bungee.api.score.Scoreboard;
- 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.PacketHandler;
- import net.md_5.bungee.protocol.DefinedPacket;
- import net.md_5.bungee.protocol.PacketWrapper;
- import net.md_5.bungee.protocol.ProtocolConstants;
- import net.md_5.bungee.protocol.packet.BossBar;
- import net.md_5.bungee.protocol.packet.Commands;
- import net.md_5.bungee.protocol.packet.KeepAlive;
- import net.md_5.bungee.protocol.packet.PlayerListItem;
- import net.md_5.bungee.protocol.packet.Respawn;
- import net.md_5.bungee.protocol.packet.ScoreboardObjective;
- import net.md_5.bungee.protocol.packet.ScoreboardScore;
- import net.md_5.bungee.protocol.packet.ScoreboardDisplay;
- import net.md_5.bungee.protocol.packet.PluginMessage;
- import net.md_5.bungee.protocol.packet.Kick;
- import net.md_5.bungee.protocol.packet.SetCompression;
- import net.md_5.bungee.protocol.packet.TabCompleteResponse;
- import net.md_5.bungee.tab.TabList;
- @RequiredArgsConstructor
- public class DownstreamBridge extends PacketHandler
- {
- private final ProxyServer bungee;
- private final UserConnection con;
- private final ServerConnection server;
- @Override
- public void exception(Throwable t) throws Exception
- {
- if ( server.isObsolete() )
- {
- // do not perform any actions if the user has already moved
- return;
- }
- ServerInfo def = con.updateAndGetNextServer( server.getInfo() );
- if ( def != null )
- {
- server.setObsolete( true );
- // con.connectNow( def, ServerConnectEvent.Reason.SERVER_DOWN_REDIRECT );
- // con.sendMessage( bungee.getTranslation( "server_went_down" ) );
- con.disconnect("§cStracono polaczenie z serwerm\n§6Sprobuj ponownie za chwile!");
- } else
- {
- con.disconnect( Util.exception( t ) );
- }
- }
- @Override
- public void disconnected(ChannelWrapper channel) throws Exception
- {
- // We lost connection to the server
- server.getInfo().removePlayer( con );
- if ( bungee.getReconnectHandler() != null )
- {
- bungee.getReconnectHandler().setServer( con );
- }
- if ( !server.isObsolete() )
- {
- con.disconnect( bungee.getTranslation( "lost_connection" ) );
- }
- ServerDisconnectEvent serverDisconnectEvent = new ServerDisconnectEvent( con, server.getInfo() );
- bungee.getPluginManager().callEvent( serverDisconnectEvent );
- }
- @Override
- public boolean shouldHandle(PacketWrapper packet) throws Exception
- {
- return !server.isObsolete();
- }
- @Override
- public void handle(PacketWrapper packet) throws Exception
- {
- con.getEntityRewrite().rewriteClientbound( packet.buf, con.getServerEntityId(), con.getClientEntityId(), con.getPendingConnection().getVersion() );
- con.sendPacket( packet );
- }
- @Override
- public void handle(KeepAlive alive) throws Exception
- {
- server.setSentPingId( alive.getRandomId() );
- con.setSentPingTime( System.currentTimeMillis() );
- }
- @Override
- public void handle(PlayerListItem playerList) throws Exception
- {
- con.getTabListHandler().onUpdate( TabList.rewrite( playerList ) );
- throw CancelSendSignal.INSTANCE; // Always throw because of profile rewriting
- }
- @Override
- public void handle(ScoreboardObjective objective) throws Exception
- {
- Scoreboard serverScoreboard = con.getServerSentScoreboard();
- switch ( objective.getAction() )
- {
- case 0:
- serverScoreboard.addObjective( new Objective( objective.getName(), objective.getValue(), objective.getType().toString() ) );
- break;
- case 1:
- serverScoreboard.removeObjective( objective.getName() );
- break;
- case 2:
- Objective oldObjective = serverScoreboard.getObjective( objective.getName() );
- if ( oldObjective != null )
- {
- oldObjective.setValue( objective.getValue() );
- oldObjective.setType( objective.getType().toString() );
- }
- break;
- default:
- throw new IllegalArgumentException( "Unknown objective action: " + objective.getAction() );
- }
- }
- @Override
- public void handle(ScoreboardScore score) throws Exception
- {
- Scoreboard serverScoreboard = con.getServerSentScoreboard();
- switch ( score.getAction() )
- {
- case 0:
- Score s = new Score( score.getItemName(), score.getScoreName(), score.getValue() );
- serverScoreboard.removeScore( score.getItemName() );
- serverScoreboard.addScore( s );
- break;
- case 1:
- serverScoreboard.removeScore( score.getItemName() );
- break;
- default:
- throw new IllegalArgumentException( "Unknown scoreboard action: " + score.getAction() );
- }
- }
- @Override
- public void handle(ScoreboardDisplay displayScoreboard) throws Exception
- {
- Scoreboard serverScoreboard = con.getServerSentScoreboard();
- serverScoreboard.setName( displayScoreboard.getName() );
- serverScoreboard.setPosition( Position.values()[displayScoreboard.getPosition()] );
- }
- @Override
- public void handle(net.md_5.bungee.protocol.packet.Team team) throws Exception
- {
- Scoreboard serverScoreboard = con.getServerSentScoreboard();
- // Remove team and move on
- if ( team.getMode() == 1 )
- {
- serverScoreboard.removeTeam( team.getName() );
- return;
- }
- // Create or get old team
- Team t;
- if ( team.getMode() == 0 )
- {
- t = new Team( team.getName() );
- serverScoreboard.addTeam( t );
- } else
- {
- t = serverScoreboard.getTeam( team.getName() );
- }
- if ( t != null )
- {
- if ( team.getMode() == 0 || team.getMode() == 2 )
- {
- t.setDisplayName( team.getDisplayName() );
- t.setPrefix( team.getPrefix() );
- t.setSuffix( team.getSuffix() );
- t.setFriendlyFire( team.getFriendlyFire() );
- t.setNameTagVisibility( team.getNameTagVisibility() );
- t.setCollisionRule( team.getCollisionRule() );
- t.setColor( team.getColor() );
- }
- if ( team.getPlayers() != null )
- {
- for ( String s : team.getPlayers() )
- {
- if ( team.getMode() == 0 || team.getMode() == 3 )
- {
- t.addPlayer( s );
- } else if ( team.getMode() == 4 )
- {
- t.removePlayer( s );
- }
- }
- }
- }
- }
- @Override
- public void handle(PluginMessage pluginMessage) throws Exception
- {
- DataInput in = pluginMessage.getStream();
- PluginMessageEvent event = new PluginMessageEvent( server, con, pluginMessage.getTag(), pluginMessage.getData().clone() );
- if ( bungee.getPluginManager().callEvent( event ).isCancelled() )
- {
- throw CancelSendSignal.INSTANCE;
- }
- if ( pluginMessage.getTag().equals( con.getPendingConnection().getVersion() >= ProtocolConstants.MINECRAFT_1_13 ? "minecraft:brand" : "MC|Brand" ) )
- {
- ByteBuf brand = Unpooled.wrappedBuffer( pluginMessage.getData() );
- String serverBrand = DefinedPacket.readString( brand );
- brand.release();
- Preconditions.checkState( !serverBrand.contains( bungee.getName() ), "Cannot connect proxy to itself!" );
- brand = ByteBufAllocator.DEFAULT.heapBuffer();
- DefinedPacket.writeString( bungee.getName() + " (" + bungee.getVersion() + ")" + " <- " + serverBrand, brand );
- pluginMessage.setData( DefinedPacket.toArray( brand ) );
- brand.release();
- // changes in the packet are ignored so we need to send it manually
- con.unsafe().sendPacket( pluginMessage );
- throw CancelSendSignal.INSTANCE;
- }
- if ( pluginMessage.getTag().equals( "BungeeCord" ) )
- {
- ByteArrayDataOutput out = ByteStreams.newDataOutput();
- String subChannel = in.readUTF();
- if ( subChannel.equals( "ForwardToPlayer" ) )
- {
- ProxiedPlayer target = bungee.getPlayer( in.readUTF() );
- if ( target != null )
- {
- // Read data from server
- String channel = in.readUTF();
- short len = in.readShort();
- byte[] data = new byte[ len ];
- in.readFully( data );
- // Prepare new data to send
- out.writeUTF( channel );
- out.writeShort( data.length );
- out.write( data );
- byte[] payload = out.toByteArray();
- target.getServer().sendData( "BungeeCord", payload );
- }
- // Null out stream, important as we don't want to send to ourselves
- out = null;
- }
- if ( subChannel.equals( "Forward" ) )
- {
- // Read data from server
- String target = in.readUTF();
- String channel = in.readUTF();
- short len = in.readShort();
- byte[] data = new byte[ len ];
- in.readFully( data );
- // Prepare new data to send
- out.writeUTF( channel );
- out.writeShort( data.length );
- out.write( data );
- byte[] payload = out.toByteArray();
- // Null out stream, important as we don't want to send to ourselves
- out = null;
- if ( target.equals( "ALL" ) )
- {
- for ( ServerInfo server : bungee.getServers().values() )
- {
- if ( server != this.server.getInfo() )
- {
- server.sendData( "BungeeCord", payload );
- }
- }
- } else if ( target.equals( "ONLINE" ) )
- {
- for ( ServerInfo server : bungee.getServers().values() )
- {
- if ( server != this.server.getInfo() )
- {
- server.sendData( "BungeeCord", payload, false );
- }
- }
- } else
- {
- ServerInfo server = bungee.getServerInfo( target );
- if ( server != null )
- {
- server.sendData( "BungeeCord", payload );
- }
- }
- }
- if ( subChannel.equals( "Connect" ) )
- {
- ServerInfo server = bungee.getServerInfo( in.readUTF() );
- if ( server != null )
- {
- con.connect( server, ServerConnectEvent.Reason.PLUGIN_MESSAGE );
- }
- }
- if ( subChannel.equals( "ConnectOther" ) )
- {
- ProxiedPlayer player = bungee.getPlayer( in.readUTF() );
- if ( player != null )
- {
- ServerInfo server = bungee.getServerInfo( in.readUTF() );
- if ( server != null )
- {
- player.connect( server );
- }
- }
- }
- if ( subChannel.equals( "IP" ) )
- {
- out.writeUTF( "IP" );
- out.writeUTF( con.getAddress().getHostString() );
- out.writeInt( con.getAddress().getPort() );
- }
- if ( subChannel.equals( "PlayerCount" ) )
- {
- String target = in.readUTF();
- out.writeUTF( "PlayerCount" );
- if ( target.equals( "ALL" ) )
- {
- out.writeUTF( "ALL" );
- out.writeInt( bungee.getOnlineCount() );
- } else
- {
- ServerInfo server = bungee.getServerInfo( target );
- if ( server != null )
- {
- out.writeUTF( server.getName() );
- out.writeInt( server.getPlayers().size() );
- }
- }
- }
- if ( subChannel.equals( "PlayerList" ) )
- {
- String target = in.readUTF();
- out.writeUTF( "PlayerList" );
- if ( target.equals( "ALL" ) )
- {
- out.writeUTF( "ALL" );
- out.writeUTF( Util.csv( bungee.getPlayers() ) );
- } else
- {
- ServerInfo server = bungee.getServerInfo( target );
- if ( server != null )
- {
- out.writeUTF( server.getName() );
- out.writeUTF( Util.csv( server.getPlayers() ) );
- }
- }
- }
- if ( subChannel.equals( "GetServers" ) )
- {
- out.writeUTF( "GetServers" );
- out.writeUTF( Util.csv( bungee.getServers().keySet() ) );
- }
- if ( subChannel.equals( "Message" ) )
- {
- String target = in.readUTF();
- String message = in.readUTF();
- if ( target.equals( "ALL" ) )
- {
- for ( ProxiedPlayer player : bungee.getPlayers() )
- {
- player.sendMessage( message );
- }
- } else
- {
- ProxiedPlayer player = bungee.getPlayer( target );
- if ( player != null )
- {
- player.sendMessage( message );
- }
- }
- }
- if ( subChannel.equals( "GetServer" ) )
- {
- out.writeUTF( "GetServer" );
- out.writeUTF( server.getInfo().getName() );
- }
- if ( subChannel.equals( "UUID" ) )
- {
- out.writeUTF( "UUID" );
- out.writeUTF( con.getUUID() );
- }
- if ( subChannel.equals( "UUIDOther" ) )
- {
- ProxiedPlayer player = bungee.getPlayer( in.readUTF() );
- if ( player != null )
- {
- out.writeUTF( "UUIDOther" );
- out.writeUTF( player.getName() );
- out.writeUTF( player.getUUID() );
- }
- }
- if ( subChannel.equals( "ServerIP" ) )
- {
- ServerInfo info = bungee.getServerInfo( in.readUTF() );
- if ( info != null && !info.getAddress().isUnresolved() )
- {
- out.writeUTF( "ServerIP" );
- out.writeUTF( info.getName() );
- out.writeUTF( info.getAddress().getAddress().getHostAddress() );
- out.writeShort( info.getAddress().getPort() );
- }
- }
- if ( subChannel.equals( "KickPlayer" ) )
- {
- ProxiedPlayer player = bungee.getPlayer( in.readUTF() );
- if ( player != null )
- {
- String kickReason = in.readUTF();
- player.disconnect( new TextComponent( kickReason ) );
- }
- }
- // Check we haven't set out to null, and we have written data, if so reply back back along the BungeeCord channel
- if ( out != null )
- {
- byte[] b = out.toByteArray();
- if ( b.length != 0 )
- {
- server.sendData( "BungeeCord", b );
- }
- }
- throw CancelSendSignal.INSTANCE;
- }
- }
- @Override
- public void handle(Kick kick) throws Exception
- {
- ServerInfo def = con.updateAndGetNextServer( server.getInfo() );
- ServerKickEvent event = bungee.getPluginManager().callEvent( new ServerKickEvent( con, server.getInfo(), ComponentSerializer.parse( kick.getMessage() ), def, ServerKickEvent.State.CONNECTED ) );
- if ( event.isCancelled() && event.getCancelServer() != null )
- {
- con.connectNow( event.getCancelServer(), ServerConnectEvent.Reason.KICK_REDIRECT );
- } else
- {
- con.disconnect0( event.getKickReasonComponent() ); // TODO: Prefix our own stuff.
- con.disconnect("§cStracono polaczenie z serwerm \n§6Powod §c" + kick.getMessage());
- }
- server.setObsolete( true );
- throw CancelSendSignal.INSTANCE;
- }
- @Override
- public void handle(SetCompression setCompression) throws Exception
- {
- server.getCh().setCompressionThreshold( setCompression.getThreshold() );
- }
- @Override
- public void handle(TabCompleteResponse tabCompleteResponse) throws Exception
- {
- if ( tabCompleteResponse.getCommands() == null )
- {
- // Passthrough on 1.13 style command responses - unclear of a sane way to process them at the moment, contributions welcome
- return;
- }
- TabCompleteResponseEvent tabCompleteResponseEvent = new TabCompleteResponseEvent( server, con, tabCompleteResponse.getCommands() );
- if ( !bungee.getPluginManager().callEvent( tabCompleteResponseEvent ).isCancelled() )
- {
- con.unsafe().sendPacket( tabCompleteResponse );
- }
- throw CancelSendSignal.INSTANCE;
- }
- @Override
- public void handle(BossBar bossBar)
- {
- switch ( bossBar.getAction() )
- {
- // Handle add bossbar
- case 0:
- con.getSentBossBars().add( bossBar.getUuid() );
- break;
- // Handle remove bossbar
- case 1:
- con.getSentBossBars().remove( bossBar.getUuid() );
- break;
- }
- }
- @Override
- public void handle(Respawn respawn)
- {
- con.setDimension( respawn.getDimension() );
- }
- @Override
- public void handle(Commands commands) throws Exception
- {
- boolean modified = false;
- if ( BungeeCord.getInstance().config.isInjectCommands() )
- {
- for ( Map.Entry<String, Command> command : bungee.getPluginManager().getCommands() )
- {
- if ( !bungee.getDisabledCommands().contains( command.getKey() ) && commands.getRoot().getChild( command.getKey() ) == null && command.getValue().hasPermission( con ) )
- {
- LiteralCommandNode dummy = LiteralArgumentBuilder.literal( command.getKey() )
- .then( RequiredArgumentBuilder.argument( "args", StringArgumentType.greedyString() )
- .suggests( Commands.SuggestionRegistry.ASK_SERVER ) )
- .build();
- commands.getRoot().addChild( dummy );
- modified = true;
- }
- }
- }
- if ( modified )
- {
- con.unsafe().sendPacket( commands );
- throw CancelSendSignal.INSTANCE;
- }
- }
- @Override
- public String toString()
- {
- return "[" + con.getName() + "] <-> DownstreamBridge <-> [" + server.getInfo().getName() + "]";
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement