diff --git a/bukkit/src/main/java/us/myles/ViaVersion/bukkit/BukkitViaLoader.java b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/BukkitViaLoader.java index 34ad57130..48e76ed00 100644 --- a/bukkit/src/main/java/us/myles/ViaVersion/bukkit/BukkitViaLoader.java +++ b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/BukkitViaLoader.java @@ -50,8 +50,6 @@ public class BukkitViaLoader implements ViaPlatformLoader { plugin.getLogger().info("Enabling PaperSpigot/TacoSpigot patch: Fixes block placement."); new PaperPatch(plugin).register(); } - if (plugin.getConf().isStimulatePlayerTick()) - new ViaIdleThread(Via.getManager().getPortedPlayers()).runTaskTimer(plugin, 1L, 1L); // Updates player's idle status if (plugin.getConf().isItemCache()) { new HandItemCache().runTaskTimerAsynchronously(plugin, 2L, 2L); // Updates player's items :) HandItemCache.CACHE = true; diff --git a/bukkit/src/main/java/us/myles/ViaVersion/bukkit/BukkitViaMovementTransmitter.java b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/BukkitViaMovementTransmitter.java new file mode 100644 index 000000000..3bc4544d6 --- /dev/null +++ b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/BukkitViaMovementTransmitter.java @@ -0,0 +1,99 @@ +package us.myles.ViaVersion.bukkit; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import us.myles.ViaVersion.api.Via; +import us.myles.ViaVersion.api.data.UserConnection; +import us.myles.ViaVersion.protocols.base.ProtocolInfo; +import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.MovementTransmitterProvider; +import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.MovementTracker; +import us.myles.ViaVersion.util.ReflectionUtil; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +public class BukkitViaMovementTransmitter extends MovementTransmitterProvider { + private static boolean USE_NMS = true; + // Used for packet mode + private Object idlePacket; + private Object idlePacket2; + // Use for nms + private Method getHandle; + private Field connection; + private Method handleFlying; + + public BukkitViaMovementTransmitter() { + USE_NMS = Via.getConfig().isNMSPlayerTicking(); + + Class idlePacketClass; + try { + idlePacketClass = ReflectionUtil.nms("PacketPlayInFlying"); + } catch (ClassNotFoundException e) { + throw new RuntimeException("Couldn't find idle packet, help!", e); + } + try { + idlePacket = idlePacketClass.newInstance(); + idlePacket2 = idlePacketClass.newInstance(); + + Field flying = idlePacketClass.getDeclaredField("f"); + flying.setAccessible(true); + + flying.set(idlePacket2, true); + } catch (NoSuchFieldException | InstantiationException | IllegalArgumentException | IllegalAccessException e) { + throw new RuntimeException("Couldn't make player idle packet, help!", e); + } + if (USE_NMS) { + try { + getHandle = ReflectionUtil.obc("entity.CraftPlayer").getDeclaredMethod("getHandle"); + } catch (NoSuchMethodException | ClassNotFoundException e) { + throw new RuntimeException("Couldn't find CraftPlayer", e); + } + + try { + connection = ReflectionUtil.nms("EntityPlayer").getDeclaredField("playerConnection"); + } catch (NoSuchFieldException | ClassNotFoundException e) { + throw new RuntimeException("Couldn't find Player Connection", e); + } + + try { + handleFlying = ReflectionUtil.nms("PlayerConnection").getDeclaredMethod("a", idlePacketClass); + } catch (NoSuchMethodException | ClassNotFoundException e) { + throw new RuntimeException("Couldn't find CraftPlayer", e); + } + } + } + + @Override + public Object getFlyingPacket() { + return idlePacket2; + } + + @Override + public Object getGroundPacket() { + return idlePacket; + } + + @Override + public void sendPlayer(UserConnection info) { + if (USE_NMS) { + Player player = Bukkit.getPlayer(info.get(ProtocolInfo.class).getUuid()); + if (player != null) { + try { + // Tick player + Object entityPlayer = getHandle.invoke(player); + Object pc = connection.get(entityPlayer); + if (pc != null) { + handleFlying.invoke(pc, (info.get(MovementTracker.class).isGround() ? idlePacket2 : idlePacket)); + // Tick world + info.get(MovementTracker.class).incrementIdlePacket(); + } + } catch (IllegalAccessException | InvocationTargetException e) { + e.printStackTrace(); + } + } + } else { + super.sendPlayer(info); + } + } +} diff --git a/common/src/main/java/us/myles/ViaVersion/api/platform/ViaPlatform.java b/common/src/main/java/us/myles/ViaVersion/api/platform/ViaPlatform.java index 3e1f10629..59ad00051 100644 --- a/common/src/main/java/us/myles/ViaVersion/api/platform/ViaPlatform.java +++ b/common/src/main/java/us/myles/ViaVersion/api/platform/ViaPlatform.java @@ -23,6 +23,8 @@ public interface ViaPlatform { public void runSync(Runnable runnable); + public void runRepeatingSync(Runnable runnable, Long ticks); + public ViaCommandSender[] getOnlinePlayers(); public void sendMessage(UUID uuid, String message); diff --git a/common/src/main/java/us/myles/ViaVersion/api/protocol/Protocol.java b/common/src/main/java/us/myles/ViaVersion/api/protocol/Protocol.java index ea56d6191..bac2b30be 100644 --- a/common/src/main/java/us/myles/ViaVersion/api/protocol/Protocol.java +++ b/common/src/main/java/us/myles/ViaVersion/api/protocol/Protocol.java @@ -57,11 +57,11 @@ public abstract class Protocol { } /** - * Register providers for this protocol + * Handle protocol registration phase, use this to register providers / tasks. * * @param providers The current providers */ - protected void registerProviders(ViaProviders providers) { + protected void register(ViaProviders providers) { } /** diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/Protocol1_9TO1_8.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/Protocol1_9TO1_8.java index 82a3c1939..3a14a4340 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/Protocol1_9TO1_8.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/Protocol1_9TO1_8.java @@ -16,6 +16,7 @@ import us.myles.ViaVersion.api.type.types.version.Metadata1_8Type; import us.myles.ViaVersion.api.type.types.version.MetadataList1_8Type; import us.myles.ViaVersion.protocols.protocol1_9to1_8.packets.*; import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.HandItemProvider; +import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.MovementTransmitterProvider; import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.*; import java.util.List; @@ -78,8 +79,12 @@ public class Protocol1_9TO1_8 extends Protocol { } @Override - protected void registerProviders(ViaProviders providers) { + protected void register(ViaProviders providers) { providers.register(HandItemProvider.class, new HandItemProvider()); + providers.require(MovementTransmitterProvider.class); + if (Via.getConfig().isStimulatePlayerTick()) { + Via.getPlatform().runRepeatingSync(new ViaIdleThread(), 1L); + } } @Override diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/ViaIdleThread.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/ViaIdleThread.java index 2e3d086d0..cfc9c6de5 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/ViaIdleThread.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/ViaIdleThread.java @@ -1,111 +1,20 @@ package us.myles.ViaVersion.protocols.protocol1_9to1_8; -import io.netty.channel.ChannelHandlerContext; -import org.bukkit.Bukkit; -import org.bukkit.entity.Player; -import org.bukkit.scheduler.BukkitRunnable; import us.myles.ViaVersion.api.Via; -import us.myles.ViaVersion.api.ViaVersion; import us.myles.ViaVersion.api.data.UserConnection; import us.myles.ViaVersion.protocols.base.ProtocolInfo; +import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.MovementTransmitterProvider; import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.MovementTracker; -import us.myles.ViaVersion.util.PipelineUtil; -import us.myles.ViaVersion.util.ReflectionUtil; - -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.Map; -import java.util.UUID; - -public class ViaIdleThread extends BukkitRunnable { - private static boolean USE_NMS = true; - private final Map portedPlayers; - // Used for packet mode - private Object idlePacket; - private Object idlePacket2; - // Use for nms - private Method getHandle; - private Field connection; - private Method handleFlying; - - public ViaIdleThread(Map portedPlayers) { - USE_NMS = Via.getConfig().isNMSPlayerTicking(); - - this.portedPlayers = portedPlayers; - Class idlePacketClass; - try { - idlePacketClass = ReflectionUtil.nms("PacketPlayInFlying"); - } catch (ClassNotFoundException e) { - throw new RuntimeException("Couldn't find idle packet, help!", e); - } - try { - idlePacket = idlePacketClass.newInstance(); - idlePacket2 = idlePacketClass.newInstance(); - - Field flying = idlePacketClass.getDeclaredField("f"); - flying.setAccessible(true); - - flying.set(idlePacket2, true); - } catch (NoSuchFieldException | InstantiationException | IllegalArgumentException | IllegalAccessException e) { - throw new RuntimeException("Couldn't make player idle packet, help!", e); - } - if (USE_NMS) { - try { - getHandle = ReflectionUtil.obc("entity.CraftPlayer").getDeclaredMethod("getHandle"); - } catch (NoSuchMethodException | ClassNotFoundException e) { - throw new RuntimeException("Couldn't find CraftPlayer", e); - } - - try { - connection = ReflectionUtil.nms("EntityPlayer").getDeclaredField("playerConnection"); - } catch (NoSuchFieldException | ClassNotFoundException e) { - throw new RuntimeException("Couldn't find Player Connection", e); - } - - try { - handleFlying = ReflectionUtil.nms("PlayerConnection").getDeclaredMethod("a", idlePacketClass); - } catch (NoSuchMethodException | ClassNotFoundException e) { - throw new RuntimeException("Couldn't find CraftPlayer", e); - } - } - } +public class ViaIdleThread implements Runnable { @Override public void run() { - for (UserConnection info : portedPlayers.values()) { + for (UserConnection info : Via.getManager().getPortedPlayers().values()) { if (info.get(ProtocolInfo.class).getPipeline().contains(Protocol1_9TO1_8.class)) { long nextIdleUpdate = info.get(MovementTracker.class).getNextIdlePacket(); if (nextIdleUpdate <= System.currentTimeMillis()) { if (info.getChannel().isOpen()) { - if (USE_NMS) { - Player player = Bukkit.getPlayer(info.get(ProtocolInfo.class).getUuid()); - if (player != null) { - try { - // Tick player - Object entityPlayer = getHandle.invoke(player); - Object pc = connection.get(entityPlayer); - if (pc != null) { - handleFlying.invoke(pc, (info.get(MovementTracker.class).isGround() ? idlePacket2 : idlePacket)); - // Tick world - info.get(MovementTracker.class).incrementIdlePacket(); - } - } catch (IllegalAccessException | InvocationTargetException e) { - e.printStackTrace(); - } - } - } else { - // Old method using packets. - ChannelHandlerContext context = PipelineUtil.getContextBefore("decoder", info.getChannel().pipeline()); - if (context != null) { - if (info.get(MovementTracker.class).isGround()) { - context.fireChannelRead(idlePacket2); - } else { - context.fireChannelRead(idlePacket); - } - info.get(MovementTracker.class).incrementIdlePacket(); - } - } + Via.getManager().getProviders().get(MovementTransmitterProvider.class).sendPlayer(info); } } } diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/providers/MovementTransmitterProvider.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/providers/MovementTransmitterProvider.java new file mode 100644 index 000000000..311859e90 --- /dev/null +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_9to1_8/providers/MovementTransmitterProvider.java @@ -0,0 +1,26 @@ +package us.myles.ViaVersion.protocols.protocol1_9to1_8.providers; + +import io.netty.channel.ChannelHandlerContext; +import us.myles.ViaVersion.api.data.UserConnection; +import us.myles.ViaVersion.api.platform.providers.Provider; +import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.MovementTracker; +import us.myles.ViaVersion.util.PipelineUtil; + +public abstract class MovementTransmitterProvider implements Provider { + public abstract Object getFlyingPacket(); + + public abstract Object getGroundPacket(); + + public void sendPlayer(UserConnection userConnection) { + // Old method using packets. + ChannelHandlerContext context = PipelineUtil.getContextBefore("decoder", userConnection.getChannel().pipeline()); + if (context != null) { + if (userConnection.get(MovementTracker.class).isGround()) { + context.fireChannelRead(getGroundPacket()); + } else { + context.fireChannelRead(getFlyingPacket()); + } + userConnection.get(MovementTracker.class).incrementIdlePacket(); + } + } +}