diff --git a/src/main/java/us/myles/ViaVersion/ViaVersionPlugin.java b/src/main/java/us/myles/ViaVersion/ViaVersionPlugin.java index 34f53fae0..a85c23f9d 100644 --- a/src/main/java/us/myles/ViaVersion/ViaVersionPlugin.java +++ b/src/main/java/us/myles/ViaVersion/ViaVersionPlugin.java @@ -7,8 +7,6 @@ import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelPipeline; import io.netty.channel.socket.SocketChannel; import org.bukkit.Bukkit; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; @@ -25,10 +23,10 @@ import us.myles.ViaVersion.update.UpdateListener; import us.myles.ViaVersion.update.UpdateUtil; import us.myles.ViaVersion.util.ReflectionUtil; -import java.io.File; -import java.io.IOException; import java.lang.reflect.Field; -import java.util.*; +import java.util.List; +import java.util.Map; +import java.util.UUID; import java.util.concurrent.Callable; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; @@ -125,6 +123,11 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaVersionAPI { return this.debug; } + @Override + public boolean isSyncedChunks() { + return getConfig().getBoolean("sync-chunks", true); + } + public void setDebug(boolean value) { this.debug = value; } @@ -154,4 +157,19 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaVersionAPI { return null; } } + + public void run(final Runnable runnable) { + try { + Bukkit.getScheduler().callSyncMethod(Bukkit.getPluginManager().getPlugin("ViaVersion"), new Callable() { + @Override + public Boolean call() throws Exception { + runnable.run(); + return true; + } + }).get(10, TimeUnit.SECONDS); + } catch (Exception e) { + System.out.println("Failed to run task."); + e.printStackTrace(); + } + } } diff --git a/src/main/java/us/myles/ViaVersion/api/ViaVersionAPI.java b/src/main/java/us/myles/ViaVersion/api/ViaVersionAPI.java index 4e84170c1..f80186838 100644 --- a/src/main/java/us/myles/ViaVersion/api/ViaVersionAPI.java +++ b/src/main/java/us/myles/ViaVersion/api/ViaVersionAPI.java @@ -30,4 +30,10 @@ public interface ViaVersionAPI { * @return true if debug is enabled */ boolean isDebug(); + + /** + * Obtains if syncing chunks is on + * @return true if it is + */ + boolean isSyncedChunks(); } diff --git a/src/main/java/us/myles/ViaVersion/handlers/ViaEncodeHandler.java b/src/main/java/us/myles/ViaVersion/handlers/ViaEncodeHandler.java index 1f9178c6a..5c26ef5a8 100644 --- a/src/main/java/us/myles/ViaVersion/handlers/ViaEncodeHandler.java +++ b/src/main/java/us/myles/ViaVersion/handlers/ViaEncodeHandler.java @@ -5,11 +5,14 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.MessageToByteEncoder; import us.myles.ViaVersion.CancelException; import us.myles.ViaVersion.ConnectionInfo; +import us.myles.ViaVersion.ViaVersionPlugin; +import us.myles.ViaVersion.api.ViaVersion; import us.myles.ViaVersion.transformers.OutgoingTransformer; import us.myles.ViaVersion.util.PacketUtil; import us.myles.ViaVersion.util.ReflectionUtil; import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; public class ViaEncodeHandler extends MessageToByteEncoder { private final ConnectionInfo info; @@ -24,25 +27,50 @@ public class ViaEncodeHandler extends MessageToByteEncoder { @Override - protected void encode(ChannelHandlerContext ctx, Object o, ByteBuf bytebuf) throws Exception { + protected void encode(final ChannelHandlerContext ctx, Object o, final ByteBuf bytebuf) throws Exception { // handle the packet type if (!(o instanceof ByteBuf)) { info.setLastPacket(o); /* This transformer is more for fixing issues which we find hard at packet level :) */ if (o.getClass().getName().endsWith("PacketPlayOutMapChunkBulk") && info.isActive()) { - int[] locX = ReflectionUtil.get(o, "a", int[].class); - int[] locZ = ReflectionUtil.get(o, "b", int[].class); + final int[] locX = ReflectionUtil.get(o, "a", int[].class); + final int[] locZ = ReflectionUtil.get(o, "b", int[].class); - Object world = ReflectionUtil.get(o, "world", ReflectionUtil.nms("World")); + final Object world = ReflectionUtil.get(o, "world", ReflectionUtil.nms("World")); Class mapChunk = ReflectionUtil.nms("PacketPlayOutMapChunk"); - Constructor constructor = mapChunk.getDeclaredConstructor(ReflectionUtil.nms("Chunk"), boolean.class, int.class); - for (int i = 0; i < locX.length; i++) { - int x = locX[i]; - int z = locZ[i]; - // world invoke function - Object chunk = ReflectionUtil.nms("World").getDeclaredMethod("getChunkAt", int.class, int.class).invoke(world, x, z); - Object packet = constructor.newInstance(chunk, true, 65535); - ctx.pipeline().writeAndFlush(packet); + final Constructor constructor = mapChunk.getDeclaredConstructor(ReflectionUtil.nms("Chunk"), boolean.class, int.class); + Runnable chunks = new Runnable() { + + @Override + public void run() { + + for (int i = 0; i < locX.length; i++) { + int x = locX[i]; + int z = locZ[i]; + // world invoke function + try { + Object chunk = ReflectionUtil.nms("World").getDeclaredMethod("getChunkAt", int.class, int.class).invoke(world, x, z); + Object packet = constructor.newInstance(chunk, true, 65535); + ctx.pipeline().writeAndFlush(packet); + } catch (InstantiationException e) { + e.printStackTrace(); + } catch (InvocationTargetException e) { + e.printStackTrace(); + } catch (NoSuchMethodException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } + } + } + }; + // Synced allows timings to work properly. + if (ViaVersion.getInstance().isSyncedChunks()) { + ((ViaVersionPlugin) ViaVersion.getInstance()).run(chunks); + } else { + chunks.run(); } bytebuf.readBytes(bytebuf.readableBytes()); throw new CancelException(); diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 5f02e58e1..3f4712790 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -1,2 +1,4 @@ -#Should ViaVersion check for updates? -checkforupdates: true \ No newline at end of file +# Should ViaVersion check for updates? +checkforupdates: true +# Should we send any bulk chunks, in sync (may be slower but fixes timings) +sync-chunks: true