Advertisement
Guest User

Untitled

a guest
Jan 21st, 2019
131
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 21.56 KB | None | 0 0
  1. package net.md_5.bungee.connection;
  2.  
  3. import com.google.common.base.Preconditions;
  4. import com.google.common.io.ByteArrayDataOutput;
  5. import com.google.common.io.ByteStreams;
  6. import com.mojang.brigadier.arguments.StringArgumentType;
  7. import com.mojang.brigadier.builder.LiteralArgumentBuilder;
  8. import com.mojang.brigadier.builder.RequiredArgumentBuilder;
  9. import com.mojang.brigadier.suggestion.SuggestionProvider;
  10. import com.mojang.brigadier.tree.LiteralCommandNode;
  11. import java.io.DataInput;
  12. import io.netty.buffer.ByteBuf;
  13. import io.netty.buffer.ByteBufAllocator;
  14. import io.netty.buffer.Unpooled;
  15. import java.util.Map;
  16. import lombok.RequiredArgsConstructor;
  17. import net.md_5.bungee.BungeeCord;
  18. import net.md_5.bungee.ServerConnection;
  19. import net.md_5.bungee.api.chat.TextComponent;
  20. import net.md_5.bungee.api.event.ServerDisconnectEvent;
  21. import net.md_5.bungee.api.event.TabCompleteResponseEvent;
  22. import net.md_5.bungee.UserConnection;
  23. import net.md_5.bungee.Util;
  24. import net.md_5.bungee.api.ProxyServer;
  25. import net.md_5.bungee.api.config.ServerInfo;
  26. import net.md_5.bungee.api.connection.ProxiedPlayer;
  27. import net.md_5.bungee.api.event.PluginMessageEvent;
  28. import net.md_5.bungee.api.event.ServerConnectEvent;
  29. import net.md_5.bungee.api.event.ServerKickEvent;
  30. import net.md_5.bungee.api.plugin.Command;
  31. import net.md_5.bungee.api.score.Objective;
  32. import net.md_5.bungee.api.score.Position;
  33. import net.md_5.bungee.api.score.Score;
  34. import net.md_5.bungee.api.score.Scoreboard;
  35. import net.md_5.bungee.api.score.Team;
  36. import net.md_5.bungee.chat.ComponentSerializer;
  37. import net.md_5.bungee.netty.ChannelWrapper;
  38. import net.md_5.bungee.netty.PacketHandler;
  39. import net.md_5.bungee.protocol.DefinedPacket;
  40. import net.md_5.bungee.protocol.PacketWrapper;
  41. import net.md_5.bungee.protocol.ProtocolConstants;
  42. import net.md_5.bungee.protocol.packet.BossBar;
  43. import net.md_5.bungee.protocol.packet.Commands;
  44. import net.md_5.bungee.protocol.packet.KeepAlive;
  45. import net.md_5.bungee.protocol.packet.PlayerListItem;
  46. import net.md_5.bungee.protocol.packet.Respawn;
  47. import net.md_5.bungee.protocol.packet.ScoreboardObjective;
  48. import net.md_5.bungee.protocol.packet.ScoreboardScore;
  49. import net.md_5.bungee.protocol.packet.ScoreboardDisplay;
  50. import net.md_5.bungee.protocol.packet.PluginMessage;
  51. import net.md_5.bungee.protocol.packet.Kick;
  52. import net.md_5.bungee.protocol.packet.SetCompression;
  53. import net.md_5.bungee.protocol.packet.TabCompleteResponse;
  54. import net.md_5.bungee.tab.TabList;
  55.  
  56. @RequiredArgsConstructor
  57. public class DownstreamBridge extends PacketHandler
  58. {
  59.  
  60. private final ProxyServer bungee;
  61. private final UserConnection con;
  62. private final ServerConnection server;
  63.  
  64. @Override
  65. public void exception(Throwable t) throws Exception
  66. {
  67. if ( server.isObsolete() )
  68. {
  69. // do not perform any actions if the user has already moved
  70. return;
  71. }
  72.  
  73. ServerInfo def = con.updateAndGetNextServer( server.getInfo() );
  74. if ( def != null )
  75. {
  76. server.setObsolete( true );
  77. // con.connectNow( def, ServerConnectEvent.Reason.SERVER_DOWN_REDIRECT );
  78. // con.sendMessage( bungee.getTranslation( "server_went_down" ) );
  79. con.disconnect("§cStracono polaczenie z serwerm\n§6Sprobuj ponownie za chwile!");
  80.  
  81. } else
  82. {
  83. con.disconnect( Util.exception( t ) );
  84. }
  85. }
  86.  
  87. @Override
  88. public void disconnected(ChannelWrapper channel) throws Exception
  89. {
  90. // We lost connection to the server
  91. server.getInfo().removePlayer( con );
  92. if ( bungee.getReconnectHandler() != null )
  93. {
  94. bungee.getReconnectHandler().setServer( con );
  95. }
  96.  
  97. if ( !server.isObsolete() )
  98. {
  99. con.disconnect( bungee.getTranslation( "lost_connection" ) );
  100. }
  101.  
  102. ServerDisconnectEvent serverDisconnectEvent = new ServerDisconnectEvent( con, server.getInfo() );
  103. bungee.getPluginManager().callEvent( serverDisconnectEvent );
  104. }
  105.  
  106. @Override
  107. public boolean shouldHandle(PacketWrapper packet) throws Exception
  108. {
  109. return !server.isObsolete();
  110. }
  111.  
  112. @Override
  113. public void handle(PacketWrapper packet) throws Exception
  114. {
  115. con.getEntityRewrite().rewriteClientbound( packet.buf, con.getServerEntityId(), con.getClientEntityId(), con.getPendingConnection().getVersion() );
  116. con.sendPacket( packet );
  117. }
  118.  
  119. @Override
  120. public void handle(KeepAlive alive) throws Exception
  121. {
  122. server.setSentPingId( alive.getRandomId() );
  123. con.setSentPingTime( System.currentTimeMillis() );
  124. }
  125.  
  126. @Override
  127. public void handle(PlayerListItem playerList) throws Exception
  128. {
  129. con.getTabListHandler().onUpdate( TabList.rewrite( playerList ) );
  130. throw CancelSendSignal.INSTANCE; // Always throw because of profile rewriting
  131. }
  132.  
  133. @Override
  134. public void handle(ScoreboardObjective objective) throws Exception
  135. {
  136. Scoreboard serverScoreboard = con.getServerSentScoreboard();
  137. switch ( objective.getAction() )
  138. {
  139. case 0:
  140. serverScoreboard.addObjective( new Objective( objective.getName(), objective.getValue(), objective.getType().toString() ) );
  141. break;
  142. case 1:
  143. serverScoreboard.removeObjective( objective.getName() );
  144. break;
  145. case 2:
  146. Objective oldObjective = serverScoreboard.getObjective( objective.getName() );
  147. if ( oldObjective != null )
  148. {
  149. oldObjective.setValue( objective.getValue() );
  150. oldObjective.setType( objective.getType().toString() );
  151. }
  152. break;
  153. default:
  154. throw new IllegalArgumentException( "Unknown objective action: " + objective.getAction() );
  155. }
  156. }
  157.  
  158. @Override
  159. public void handle(ScoreboardScore score) throws Exception
  160. {
  161. Scoreboard serverScoreboard = con.getServerSentScoreboard();
  162. switch ( score.getAction() )
  163. {
  164. case 0:
  165. Score s = new Score( score.getItemName(), score.getScoreName(), score.getValue() );
  166. serverScoreboard.removeScore( score.getItemName() );
  167. serverScoreboard.addScore( s );
  168. break;
  169. case 1:
  170. serverScoreboard.removeScore( score.getItemName() );
  171. break;
  172. default:
  173. throw new IllegalArgumentException( "Unknown scoreboard action: " + score.getAction() );
  174. }
  175. }
  176.  
  177. @Override
  178. public void handle(ScoreboardDisplay displayScoreboard) throws Exception
  179. {
  180. Scoreboard serverScoreboard = con.getServerSentScoreboard();
  181. serverScoreboard.setName( displayScoreboard.getName() );
  182. serverScoreboard.setPosition( Position.values()[displayScoreboard.getPosition()] );
  183. }
  184.  
  185. @Override
  186. public void handle(net.md_5.bungee.protocol.packet.Team team) throws Exception
  187. {
  188. Scoreboard serverScoreboard = con.getServerSentScoreboard();
  189. // Remove team and move on
  190. if ( team.getMode() == 1 )
  191. {
  192. serverScoreboard.removeTeam( team.getName() );
  193. return;
  194. }
  195.  
  196. // Create or get old team
  197. Team t;
  198. if ( team.getMode() == 0 )
  199. {
  200. t = new Team( team.getName() );
  201. serverScoreboard.addTeam( t );
  202. } else
  203. {
  204. t = serverScoreboard.getTeam( team.getName() );
  205. }
  206.  
  207. if ( t != null )
  208. {
  209. if ( team.getMode() == 0 || team.getMode() == 2 )
  210. {
  211. t.setDisplayName( team.getDisplayName() );
  212. t.setPrefix( team.getPrefix() );
  213. t.setSuffix( team.getSuffix() );
  214. t.setFriendlyFire( team.getFriendlyFire() );
  215. t.setNameTagVisibility( team.getNameTagVisibility() );
  216. t.setCollisionRule( team.getCollisionRule() );
  217. t.setColor( team.getColor() );
  218. }
  219. if ( team.getPlayers() != null )
  220. {
  221. for ( String s : team.getPlayers() )
  222. {
  223. if ( team.getMode() == 0 || team.getMode() == 3 )
  224. {
  225. t.addPlayer( s );
  226. } else if ( team.getMode() == 4 )
  227. {
  228. t.removePlayer( s );
  229. }
  230. }
  231. }
  232. }
  233. }
  234.  
  235. @Override
  236. public void handle(PluginMessage pluginMessage) throws Exception
  237. {
  238. DataInput in = pluginMessage.getStream();
  239. PluginMessageEvent event = new PluginMessageEvent( server, con, pluginMessage.getTag(), pluginMessage.getData().clone() );
  240.  
  241. if ( bungee.getPluginManager().callEvent( event ).isCancelled() )
  242. {
  243. throw CancelSendSignal.INSTANCE;
  244. }
  245.  
  246. if ( pluginMessage.getTag().equals( con.getPendingConnection().getVersion() >= ProtocolConstants.MINECRAFT_1_13 ? "minecraft:brand" : "MC|Brand" ) )
  247. {
  248. ByteBuf brand = Unpooled.wrappedBuffer( pluginMessage.getData() );
  249. String serverBrand = DefinedPacket.readString( brand );
  250. brand.release();
  251.  
  252. Preconditions.checkState( !serverBrand.contains( bungee.getName() ), "Cannot connect proxy to itself!" );
  253.  
  254. brand = ByteBufAllocator.DEFAULT.heapBuffer();
  255. DefinedPacket.writeString( bungee.getName() + " (" + bungee.getVersion() + ")" + " <- " + serverBrand, brand );
  256. pluginMessage.setData( DefinedPacket.toArray( brand ) );
  257. brand.release();
  258. // changes in the packet are ignored so we need to send it manually
  259. con.unsafe().sendPacket( pluginMessage );
  260. throw CancelSendSignal.INSTANCE;
  261. }
  262.  
  263. if ( pluginMessage.getTag().equals( "BungeeCord" ) )
  264. {
  265. ByteArrayDataOutput out = ByteStreams.newDataOutput();
  266. String subChannel = in.readUTF();
  267.  
  268. if ( subChannel.equals( "ForwardToPlayer" ) )
  269. {
  270. ProxiedPlayer target = bungee.getPlayer( in.readUTF() );
  271. if ( target != null )
  272. {
  273. // Read data from server
  274. String channel = in.readUTF();
  275. short len = in.readShort();
  276. byte[] data = new byte[ len ];
  277. in.readFully( data );
  278.  
  279. // Prepare new data to send
  280. out.writeUTF( channel );
  281. out.writeShort( data.length );
  282. out.write( data );
  283. byte[] payload = out.toByteArray();
  284.  
  285. target.getServer().sendData( "BungeeCord", payload );
  286. }
  287.  
  288. // Null out stream, important as we don't want to send to ourselves
  289. out = null;
  290. }
  291. if ( subChannel.equals( "Forward" ) )
  292. {
  293. // Read data from server
  294. String target = in.readUTF();
  295. String channel = in.readUTF();
  296. short len = in.readShort();
  297. byte[] data = new byte[ len ];
  298. in.readFully( data );
  299.  
  300. // Prepare new data to send
  301. out.writeUTF( channel );
  302. out.writeShort( data.length );
  303. out.write( data );
  304. byte[] payload = out.toByteArray();
  305.  
  306. // Null out stream, important as we don't want to send to ourselves
  307. out = null;
  308.  
  309. if ( target.equals( "ALL" ) )
  310. {
  311. for ( ServerInfo server : bungee.getServers().values() )
  312. {
  313. if ( server != this.server.getInfo() )
  314. {
  315. server.sendData( "BungeeCord", payload );
  316. }
  317. }
  318. } else if ( target.equals( "ONLINE" ) )
  319. {
  320. for ( ServerInfo server : bungee.getServers().values() )
  321. {
  322. if ( server != this.server.getInfo() )
  323. {
  324. server.sendData( "BungeeCord", payload, false );
  325. }
  326. }
  327. } else
  328. {
  329. ServerInfo server = bungee.getServerInfo( target );
  330. if ( server != null )
  331. {
  332. server.sendData( "BungeeCord", payload );
  333. }
  334. }
  335. }
  336. if ( subChannel.equals( "Connect" ) )
  337. {
  338. ServerInfo server = bungee.getServerInfo( in.readUTF() );
  339. if ( server != null )
  340. {
  341. con.connect( server, ServerConnectEvent.Reason.PLUGIN_MESSAGE );
  342. }
  343. }
  344. if ( subChannel.equals( "ConnectOther" ) )
  345. {
  346. ProxiedPlayer player = bungee.getPlayer( in.readUTF() );
  347. if ( player != null )
  348. {
  349. ServerInfo server = bungee.getServerInfo( in.readUTF() );
  350. if ( server != null )
  351. {
  352. player.connect( server );
  353. }
  354. }
  355. }
  356. if ( subChannel.equals( "IP" ) )
  357. {
  358. out.writeUTF( "IP" );
  359. out.writeUTF( con.getAddress().getHostString() );
  360. out.writeInt( con.getAddress().getPort() );
  361. }
  362. if ( subChannel.equals( "PlayerCount" ) )
  363. {
  364. String target = in.readUTF();
  365. out.writeUTF( "PlayerCount" );
  366. if ( target.equals( "ALL" ) )
  367. {
  368. out.writeUTF( "ALL" );
  369. out.writeInt( bungee.getOnlineCount() );
  370. } else
  371. {
  372. ServerInfo server = bungee.getServerInfo( target );
  373. if ( server != null )
  374. {
  375. out.writeUTF( server.getName() );
  376. out.writeInt( server.getPlayers().size() );
  377. }
  378. }
  379. }
  380. if ( subChannel.equals( "PlayerList" ) )
  381. {
  382. String target = in.readUTF();
  383. out.writeUTF( "PlayerList" );
  384. if ( target.equals( "ALL" ) )
  385. {
  386. out.writeUTF( "ALL" );
  387. out.writeUTF( Util.csv( bungee.getPlayers() ) );
  388. } else
  389. {
  390. ServerInfo server = bungee.getServerInfo( target );
  391. if ( server != null )
  392. {
  393. out.writeUTF( server.getName() );
  394. out.writeUTF( Util.csv( server.getPlayers() ) );
  395. }
  396. }
  397. }
  398. if ( subChannel.equals( "GetServers" ) )
  399. {
  400. out.writeUTF( "GetServers" );
  401. out.writeUTF( Util.csv( bungee.getServers().keySet() ) );
  402. }
  403. if ( subChannel.equals( "Message" ) )
  404. {
  405. String target = in.readUTF();
  406. String message = in.readUTF();
  407. if ( target.equals( "ALL" ) )
  408. {
  409. for ( ProxiedPlayer player : bungee.getPlayers() )
  410. {
  411. player.sendMessage( message );
  412. }
  413. } else
  414. {
  415. ProxiedPlayer player = bungee.getPlayer( target );
  416. if ( player != null )
  417. {
  418. player.sendMessage( message );
  419. }
  420. }
  421. }
  422. if ( subChannel.equals( "GetServer" ) )
  423. {
  424. out.writeUTF( "GetServer" );
  425. out.writeUTF( server.getInfo().getName() );
  426. }
  427. if ( subChannel.equals( "UUID" ) )
  428. {
  429. out.writeUTF( "UUID" );
  430. out.writeUTF( con.getUUID() );
  431. }
  432. if ( subChannel.equals( "UUIDOther" ) )
  433. {
  434. ProxiedPlayer player = bungee.getPlayer( in.readUTF() );
  435. if ( player != null )
  436. {
  437. out.writeUTF( "UUIDOther" );
  438. out.writeUTF( player.getName() );
  439. out.writeUTF( player.getUUID() );
  440. }
  441. }
  442. if ( subChannel.equals( "ServerIP" ) )
  443. {
  444. ServerInfo info = bungee.getServerInfo( in.readUTF() );
  445. if ( info != null && !info.getAddress().isUnresolved() )
  446. {
  447. out.writeUTF( "ServerIP" );
  448. out.writeUTF( info.getName() );
  449. out.writeUTF( info.getAddress().getAddress().getHostAddress() );
  450. out.writeShort( info.getAddress().getPort() );
  451. }
  452. }
  453. if ( subChannel.equals( "KickPlayer" ) )
  454. {
  455. ProxiedPlayer player = bungee.getPlayer( in.readUTF() );
  456. if ( player != null )
  457. {
  458. String kickReason = in.readUTF();
  459. player.disconnect( new TextComponent( kickReason ) );
  460. }
  461. }
  462.  
  463. // Check we haven't set out to null, and we have written data, if so reply back back along the BungeeCord channel
  464. if ( out != null )
  465. {
  466. byte[] b = out.toByteArray();
  467. if ( b.length != 0 )
  468. {
  469. server.sendData( "BungeeCord", b );
  470. }
  471. }
  472.  
  473. throw CancelSendSignal.INSTANCE;
  474. }
  475. }
  476.  
  477. @Override
  478. public void handle(Kick kick) throws Exception
  479. {
  480. ServerInfo def = con.updateAndGetNextServer( server.getInfo() );
  481. ServerKickEvent event = bungee.getPluginManager().callEvent( new ServerKickEvent( con, server.getInfo(), ComponentSerializer.parse( kick.getMessage() ), def, ServerKickEvent.State.CONNECTED ) );
  482. if ( event.isCancelled() && event.getCancelServer() != null )
  483. {
  484. con.connectNow( event.getCancelServer(), ServerConnectEvent.Reason.KICK_REDIRECT );
  485. } else
  486. {
  487. con.disconnect0( event.getKickReasonComponent() ); // TODO: Prefix our own stuff.
  488. con.disconnect("§cStracono polaczenie z serwerm \n§6Powod §c" + kick.getMessage());
  489. }
  490. server.setObsolete( true );
  491. throw CancelSendSignal.INSTANCE;
  492. }
  493.  
  494. @Override
  495. public void handle(SetCompression setCompression) throws Exception
  496. {
  497. server.getCh().setCompressionThreshold( setCompression.getThreshold() );
  498. }
  499.  
  500. @Override
  501. public void handle(TabCompleteResponse tabCompleteResponse) throws Exception
  502. {
  503. if ( tabCompleteResponse.getCommands() == null )
  504. {
  505. // Passthrough on 1.13 style command responses - unclear of a sane way to process them at the moment, contributions welcome
  506. return;
  507. }
  508.  
  509. TabCompleteResponseEvent tabCompleteResponseEvent = new TabCompleteResponseEvent( server, con, tabCompleteResponse.getCommands() );
  510.  
  511. if ( !bungee.getPluginManager().callEvent( tabCompleteResponseEvent ).isCancelled() )
  512. {
  513. con.unsafe().sendPacket( tabCompleteResponse );
  514. }
  515.  
  516. throw CancelSendSignal.INSTANCE;
  517. }
  518.  
  519. @Override
  520. public void handle(BossBar bossBar)
  521. {
  522. switch ( bossBar.getAction() )
  523. {
  524. // Handle add bossbar
  525. case 0:
  526. con.getSentBossBars().add( bossBar.getUuid() );
  527. break;
  528. // Handle remove bossbar
  529. case 1:
  530. con.getSentBossBars().remove( bossBar.getUuid() );
  531. break;
  532. }
  533. }
  534.  
  535. @Override
  536. public void handle(Respawn respawn)
  537. {
  538. con.setDimension( respawn.getDimension() );
  539. }
  540.  
  541. @Override
  542. public void handle(Commands commands) throws Exception
  543. {
  544. boolean modified = false;
  545.  
  546. if ( BungeeCord.getInstance().config.isInjectCommands() )
  547. {
  548. for ( Map.Entry<String, Command> command : bungee.getPluginManager().getCommands() )
  549. {
  550. if ( !bungee.getDisabledCommands().contains( command.getKey() ) && commands.getRoot().getChild( command.getKey() ) == null && command.getValue().hasPermission( con ) )
  551. {
  552. LiteralCommandNode dummy = LiteralArgumentBuilder.literal( command.getKey() )
  553. .then( RequiredArgumentBuilder.argument( "args", StringArgumentType.greedyString() )
  554. .suggests( Commands.SuggestionRegistry.ASK_SERVER ) )
  555. .build();
  556. commands.getRoot().addChild( dummy );
  557.  
  558. modified = true;
  559. }
  560. }
  561. }
  562.  
  563. if ( modified )
  564. {
  565. con.unsafe().sendPacket( commands );
  566. throw CancelSendSignal.INSTANCE;
  567. }
  568. }
  569.  
  570. @Override
  571. public String toString()
  572. {
  573. return "[" + con.getName() + "] <-> DownstreamBridge <-> [" + server.getInfo().getName() + "]";
  574. }
  575. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement