From 1720a14e080e241b6bb2c838168a23e5c94253e4 Mon Sep 17 00:00:00 2001 From: PunKeel Date: Wed, 29 Jun 2016 08:36:20 -0700 Subject: [PATCH] Store last known dimension and don't send useless respawn packets Improves server switching without lossing the advantages of the Respawn package (reset entities, for instance) Merges SpigotMC/BungeeCord#1426 --- .../0004-Configurable-Waterfall-Metrics.patch | 304 +++--------------- ...-dimension-and-don-t-send-useless-re.patch | 126 ++++++++ 2 files changed, 162 insertions(+), 268 deletions(-) create mode 100644 BungeeCord-Patches/0038-Store-last-known-dimension-and-don-t-send-useless-re.patch diff --git a/BungeeCord-Patches/0004-Configurable-Waterfall-Metrics.patch b/BungeeCord-Patches/0004-Configurable-Waterfall-Metrics.patch index f383863..05da4e0 100644 --- a/BungeeCord-Patches/0004-Configurable-Waterfall-Metrics.patch +++ b/BungeeCord-Patches/0004-Configurable-Waterfall-Metrics.patch @@ -1,4 +1,4 @@ -From 5c789d7ac0a98e7ccc5ae6bccedef59621bb9c7f Mon Sep 17 00:00:00 2001 +From 19eb33404cbd686f8361f691520885331852481d Mon Sep 17 00:00:00 2001 From: Techcable Date: Thu, 19 May 2016 10:55:20 -0700 Subject: [PATCH] Configurable Waterfall Metrics @@ -17,143 +17,46 @@ index b30541b..293ec4e 100644 + */ + boolean isMetrics(); } -diff --git a/proxy/src/main/java/io/github/waterfallmc/waterfall/Metrics.java b/proxy/src/main/java/io/github/waterfallmc/waterfall/Metrics.java -new file mode 100644 -index 0000000..ae5a2a9 ---- /dev/null +diff --git a/proxy/src/main/java/net/md_5/bungee/Metrics.java b/proxy/src/main/java/io/github/waterfallmc/waterfall/Metrics.java +similarity index 96% +rename from proxy/src/main/java/net/md_5/bungee/Metrics.java +rename to proxy/src/main/java/io/github/waterfallmc/waterfall/Metrics.java +index 9523987..ae5a2a9 100644 +--- a/proxy/src/main/java/net/md_5/bungee/Metrics.java +++ b/proxy/src/main/java/io/github/waterfallmc/waterfall/Metrics.java -@@ -0,0 +1,131 @@ +@@ -1,4 +1,4 @@ +-package net.md_5.bungee; +package io.github.waterfallmc.waterfall; -+ -+import java.io.BufferedReader; -+import java.io.IOException; -+import java.io.InputStreamReader; -+import java.io.OutputStreamWriter; -+import java.io.UnsupportedEncodingException; -+import java.net.URL; -+import java.net.URLConnection; -+import java.net.URLEncoder; -+import java.util.TimerTask; + + import java.io.BufferedReader; + import java.io.IOException; +@@ -9,6 +9,8 @@ import java.net.URL; + import java.net.URLConnection; + import java.net.URLEncoder; + import java.util.TimerTask; + +import net.md_5.bungee.BungeeCord; -+import net.md_5.bungee.api.ProxyServer; -+ -+public class Metrics extends TimerTask -+{ -+ -+ /** -+ * The current revision number -+ */ -+ private final static int REVISION = 5; -+ /** -+ * The base url of the metrics domain -+ */ -+ private static final String BASE_URL = "http://mcstats.org"; -+ /** -+ * The url used to report a server's status -+ */ -+ private static final String REPORT_URL = "/report/%s"; -+ /** -+ * Interval of time to ping (in minutes) -+ */ + import net.md_5.bungee.api.ProxyServer; + + public class Metrics extends TimerTask +@@ -29,7 +31,7 @@ public class Metrics extends TimerTask + /** + * Interval of time to ping (in minutes) + */ +- final static int PING_INTERVAL = 10; + public final static int PING_INTERVAL = 10; -+ boolean firstPost = true; -+ -+ @Override -+ public void run() -+ { -+ try -+ { -+ // We use the inverse of firstPost because if it is the first time we are posting, -+ // it is not a interval ping, so it evaluates to FALSE -+ // Each time thereafter it will evaluate to TRUE, i.e PING! -+ postPlugin( !firstPost ); -+ -+ // After the first post we set firstPost to false -+ // Each post thereafter will be a ping -+ firstPost = false; -+ } catch ( IOException ex ) -+ { -+ // ProxyServer.getInstance().getLogger().info( "[Metrics] " + ex.getMessage() ); -+ } -+ } -+ -+ /** -+ * Generic method that posts a plugin to the metrics website -+ */ -+ private void postPlugin(boolean isPing) throws IOException -+ { -+ // Construct the post data -+ final StringBuilder data = new StringBuilder(); -+ data.append( encode( "guid" ) ).append( '=' ).append( encode( BungeeCord.getInstance().config.getUuid() ) ); -+ encodeDataPair( data, "version", ProxyServer.getInstance().getVersion() ); -+ encodeDataPair( data, "server", "0" ); -+ encodeDataPair( data, "players", Integer.toString( ProxyServer.getInstance().getOnlineCount() ) ); -+ encodeDataPair( data, "revision", String.valueOf( REVISION ) ); -+ -+ // If we're pinging, append it -+ if ( isPing ) -+ { -+ encodeDataPair( data, "ping", "true" ); -+ } -+ -+ // Create the url + boolean firstPost = true; + + @Override +@@ -71,7 +73,7 @@ public class Metrics extends TimerTask + } + + // Create the url +- URL url = new URL( BASE_URL + String.format( REPORT_URL, encode( "BungeeCord" ) ) ); + URL url = new URL( BASE_URL + String.format( REPORT_URL, encode( "Waterfall" ) ) ); -+ -+ // Connect to the website -+ URLConnection connection; -+ -+ connection = url.openConnection(); -+ -+ connection.setDoOutput( true ); -+ final BufferedReader reader; -+ final String response; -+ try ( OutputStreamWriter writer = new OutputStreamWriter( connection.getOutputStream() ) ) -+ { -+ writer.write( data.toString() ); -+ writer.flush(); -+ reader = new BufferedReader( new InputStreamReader( connection.getInputStream() ) ); -+ response = reader.readLine(); -+ } -+ reader.close(); -+ -+ if ( response == null || response.startsWith( "ERR" ) ) -+ { -+ throw new IOException( response ); //Throw the exception -+ } -+ } -+ -+ /** -+ *

-+ * Encode a key/value data pair to be used in a HTTP post request. This -+ * INCLUDES a & so the first key/value pair MUST be included manually, -+ * e.g:

-+ * -+ * StringBuffer data = new StringBuffer(); -+ * data.append(encode("guid")).append('=').append(encode(guid)); -+ * encodeDataPair(data, "version", description.getVersion()); -+ * -+ * -+ * @param buffer the StringBuilder to append the data pair onto -+ * @param key the key value -+ * @param value the value -+ */ -+ private static void encodeDataPair(final StringBuilder buffer, final String key, final String value) throws UnsupportedEncodingException -+ { -+ buffer.append( '&' ).append( encode( key ) ).append( '=' ).append( encode( value ) ); -+ } -+ -+ /** -+ * Encode text as UTF-8 -+ * -+ * @param text the text to encode -+ * @return the encoded text, as UTF-8 -+ */ -+ private static String encode(final String text) throws UnsupportedEncodingException -+ { -+ return URLEncoder.encode( text, "UTF-8" ); -+ } -+} + + // Connect to the website + URLConnection connection; diff --git a/proxy/src/main/java/io/github/waterfallmc/waterfall/conf/WaterfallConfiguration.java b/proxy/src/main/java/io/github/waterfallmc/waterfall/conf/WaterfallConfiguration.java index 03160da..1fa3ecd 100644 --- a/proxy/src/main/java/io/github/waterfallmc/waterfall/conf/WaterfallConfiguration.java @@ -205,141 +108,6 @@ index 3dceb6e..3578aa4 100644 } public void startListeners() -diff --git a/proxy/src/main/java/net/md_5/bungee/Metrics.java b/proxy/src/main/java/net/md_5/bungee/Metrics.java -deleted file mode 100644 -index 9523987..0000000 ---- a/proxy/src/main/java/net/md_5/bungee/Metrics.java -+++ /dev/null -@@ -1,129 +0,0 @@ --package net.md_5.bungee; -- --import java.io.BufferedReader; --import java.io.IOException; --import java.io.InputStreamReader; --import java.io.OutputStreamWriter; --import java.io.UnsupportedEncodingException; --import java.net.URL; --import java.net.URLConnection; --import java.net.URLEncoder; --import java.util.TimerTask; --import net.md_5.bungee.api.ProxyServer; -- --public class Metrics extends TimerTask --{ -- -- /** -- * The current revision number -- */ -- private final static int REVISION = 5; -- /** -- * The base url of the metrics domain -- */ -- private static final String BASE_URL = "http://mcstats.org"; -- /** -- * The url used to report a server's status -- */ -- private static final String REPORT_URL = "/report/%s"; -- /** -- * Interval of time to ping (in minutes) -- */ -- final static int PING_INTERVAL = 10; -- boolean firstPost = true; -- -- @Override -- public void run() -- { -- try -- { -- // We use the inverse of firstPost because if it is the first time we are posting, -- // it is not a interval ping, so it evaluates to FALSE -- // Each time thereafter it will evaluate to TRUE, i.e PING! -- postPlugin( !firstPost ); -- -- // After the first post we set firstPost to false -- // Each post thereafter will be a ping -- firstPost = false; -- } catch ( IOException ex ) -- { -- // ProxyServer.getInstance().getLogger().info( "[Metrics] " + ex.getMessage() ); -- } -- } -- -- /** -- * Generic method that posts a plugin to the metrics website -- */ -- private void postPlugin(boolean isPing) throws IOException -- { -- // Construct the post data -- final StringBuilder data = new StringBuilder(); -- data.append( encode( "guid" ) ).append( '=' ).append( encode( BungeeCord.getInstance().config.getUuid() ) ); -- encodeDataPair( data, "version", ProxyServer.getInstance().getVersion() ); -- encodeDataPair( data, "server", "0" ); -- encodeDataPair( data, "players", Integer.toString( ProxyServer.getInstance().getOnlineCount() ) ); -- encodeDataPair( data, "revision", String.valueOf( REVISION ) ); -- -- // If we're pinging, append it -- if ( isPing ) -- { -- encodeDataPair( data, "ping", "true" ); -- } -- -- // Create the url -- URL url = new URL( BASE_URL + String.format( REPORT_URL, encode( "BungeeCord" ) ) ); -- -- // Connect to the website -- URLConnection connection; -- -- connection = url.openConnection(); -- -- connection.setDoOutput( true ); -- final BufferedReader reader; -- final String response; -- try ( OutputStreamWriter writer = new OutputStreamWriter( connection.getOutputStream() ) ) -- { -- writer.write( data.toString() ); -- writer.flush(); -- reader = new BufferedReader( new InputStreamReader( connection.getInputStream() ) ); -- response = reader.readLine(); -- } -- reader.close(); -- -- if ( response == null || response.startsWith( "ERR" ) ) -- { -- throw new IOException( response ); //Throw the exception -- } -- } -- -- /** -- *

-- * Encode a key/value data pair to be used in a HTTP post request. This -- * INCLUDES a & so the first key/value pair MUST be included manually, -- * e.g:

-- * -- * StringBuffer data = new StringBuffer(); -- * data.append(encode("guid")).append('=').append(encode(guid)); -- * encodeDataPair(data, "version", description.getVersion()); -- * -- * -- * @param buffer the StringBuilder to append the data pair onto -- * @param key the key value -- * @param value the value -- */ -- private static void encodeDataPair(final StringBuilder buffer, final String key, final String value) throws UnsupportedEncodingException -- { -- buffer.append( '&' ).append( encode( key ) ).append( '=' ).append( encode( value ) ); -- } -- -- /** -- * Encode text as UTF-8 -- * -- * @param text the text to encode -- * @return the encoded text, as UTF-8 -- */ -- private static String encode(final String text) throws UnsupportedEncodingException -- { -- return URLEncoder.encode( text, "UTF-8" ); -- } --} -- -2.8.3 +2.9.0 diff --git a/BungeeCord-Patches/0038-Store-last-known-dimension-and-don-t-send-useless-re.patch b/BungeeCord-Patches/0038-Store-last-known-dimension-and-don-t-send-useless-re.patch new file mode 100644 index 0000000..ae2f397 --- /dev/null +++ b/BungeeCord-Patches/0038-Store-last-known-dimension-and-don-t-send-useless-re.patch @@ -0,0 +1,126 @@ +From 25f02e9f4769d0f21d13294828c245f7422b133f Mon Sep 17 00:00:00 2001 +From: PunKeel +Date: Wed, 8 Apr 2015 22:36:33 +0200 +Subject: [PATCH] Store last known dimension and don't send useless respawn + packets + +In order to improve server switching without lossing the advantages of the Respawn package (reset entities, for instance) + +diff --git a/proxy/src/main/java/net/md_5/bungee/ServerConnector.java b/proxy/src/main/java/net/md_5/bungee/ServerConnector.java +index e327325..f1ccd72 100644 +--- a/proxy/src/main/java/net/md_5/bungee/ServerConnector.java ++++ b/proxy/src/main/java/net/md_5/bungee/ServerConnector.java +@@ -257,7 +257,10 @@ public class ServerConnector extends PacketHandler + } + user.getSentBossBars().clear(); + +- user.sendDimensionSwitch(); ++ if( user.getDimension() == login.getDimension() ){ ++ // Only change dimension to reset entities ++ user.unsafe().sendPacket( new Respawn( ( login.getDimension() == 0 ) ? 1 : 0, login.getDifficulty(), login.getGameMode(), login.getLevelType() ) ); ++ } + + user.setServerEntityId( login.getEntityId() ); + user.unsafe().sendPacket( new Respawn( login.getDimension(), login.getDifficulty(), login.getGameMode(), login.getLevelType() ) ); +@@ -280,7 +283,7 @@ public class ServerConnector extends PacketHandler + target.addPlayer( user ); + user.getPendingConnects().remove( target ); + user.setServerJoinQueue( null ); +- user.setDimensionChange( false ); ++ user.setDimension( login.getDimension() ); + + user.setServer( server ); + ch.getHandle().pipeline().get( HandlerBoss.class ).setHandler( new DownstreamBridge( bungee, user, server ) ); +@@ -316,14 +319,7 @@ public class ServerConnector extends PacketHandler + throw CancelSendSignal.INSTANCE; + } + +- String message = bungee.getTranslation( "connect_kick", target.getName(), event.getKickReason() ); +- if ( user.isDimensionChange() ) +- { +- user.disconnect( message ); +- } else +- { +- user.sendMessage( message ); +- } ++ user.sendMessage( bungee.getTranslation( "connect_kick", target.getName(), event.getKickReason() ) ); + + throw CancelSendSignal.INSTANCE; + } +diff --git a/proxy/src/main/java/net/md_5/bungee/UserConnection.java b/proxy/src/main/java/net/md_5/bungee/UserConnection.java +index 9a13f5c..195869b 100644 +--- a/proxy/src/main/java/net/md_5/bungee/UserConnection.java ++++ b/proxy/src/main/java/net/md_5/bungee/UserConnection.java +@@ -89,7 +89,7 @@ public final class UserConnection implements ProxiedPlayer + private ServerConnection server; + @Getter + @Setter +- private boolean dimensionChange = true; ++ private int dimension = 0; + @Getter + private final Collection pendingConnects = new HashSet<>(); + /*========================================================================*/ +@@ -187,7 +187,7 @@ public final class UserConnection implements ProxiedPlayer + + // No-config FML handshake marker. + // Set whether the connection has a 1.8 FML marker in the handshake. +- if (this.getPendingConnection().getExtraDataInHandshake().contains( ForgeConstants.FML_HANDSHAKE_TOKEN )) ++ if (this.getPendingConnection().getExtraDataInHandshake().contains( ForgeConstants.FML_HANDSHAKE_TOKEN )) + { + forgeClientHandler.setFmlTokenInHandshake( true ); + } +@@ -223,16 +223,8 @@ public final class UserConnection implements ProxiedPlayer + connect( target, callback, false ); + } + +- void sendDimensionSwitch() +- { +- dimensionChange = true; +- unsafe().sendPacket( PacketConstants.DIM1_SWITCH ); +- unsafe().sendPacket( PacketConstants.DIM2_SWITCH ); +- } +- + public void connectNow(ServerInfo target) + { +- sendDimensionSwitch(); + connect( target ); + } + +@@ -328,9 +320,6 @@ public final class UserConnection implements ProxiedPlayer + { + 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() ) ); +diff --git a/proxy/src/main/java/net/md_5/bungee/connection/DownstreamBridge.java b/proxy/src/main/java/net/md_5/bungee/connection/DownstreamBridge.java +index fa57f28..017c2b2 100644 +--- a/proxy/src/main/java/net/md_5/bungee/connection/DownstreamBridge.java ++++ b/proxy/src/main/java/net/md_5/bungee/connection/DownstreamBridge.java +@@ -37,6 +37,7 @@ 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.Respawn; + import net.md_5.bungee.protocol.packet.SetCompression; + import net.md_5.bungee.protocol.packet.TabCompleteResponse; + import net.md_5.bungee.tab.TabList; +@@ -501,6 +502,12 @@ public class DownstreamBridge extends PacketHandler + } + + @Override ++ public void handle(Respawn respawn) throws Exception ++ { ++ con.setDimension( respawn.getDimension() ); ++ } ++ ++ @Override + public String toString() + { + return "[" + con.getAddress() + "|" + con.getName() + "] <-> DownstreamBridge <-> [" + server.getInfo().getName() + "]"; +-- +2.9.0 +