Merge pull request #185 from lenis0012/master

Manually perform idle updates. Fixed #160 #99
This commit is contained in:
Myles 2016-03-09 21:21:59 +00:00
commit 7b36a9de51
4 changed files with 59 additions and 0 deletions

View File

@ -12,6 +12,9 @@ import us.myles.ViaVersion.packets.State;
@Getter
@Setter
public class ConnectionInfo {
private static final long IDLE_PACKET_DELAY = 50L; // Update every 50ms (20tps)
private static final long IDLE_PACKET_LIMIT = 20; // Max 20 ticks behind
private final SocketChannel channel;
private Object lastPacket;
private java.util.UUID UUID;
@ -22,6 +25,7 @@ public class ConnectionInfo {
private int entityID;
private boolean active = true;
private String username;
private long nextIdlePacket = 0L;
public ConnectionInfo(SocketChannel socketChannel) {
this.channel = socketChannel;
@ -33,6 +37,7 @@ public class ConnectionInfo {
public void setActive(boolean active) {
this.active = active;
this.nextIdlePacket = System.currentTimeMillis() + IDLE_PACKET_DELAY; // Update every 50 ticks
}
public void sendRawPacket(final ByteBuf packet, boolean currentThread) {
@ -56,4 +61,10 @@ public class ConnectionInfo {
public void closeWindow() {
this.openWindow = null;
}
public void incrementIdlePacket() {
// Notify of next update
// Allow a maximum lag spike of 1 second (20 ticks/updates)
this.nextIdlePacket = Math.max(nextIdlePacket + IDLE_PACKET_DELAY, System.currentTimeMillis() - IDLE_PACKET_DELAY * IDLE_PACKET_LIMIT);
}
}

View File

@ -0,0 +1,42 @@
package us.myles.ViaVersion;
import org.bukkit.scheduler.BukkitRunnable;
import us.myles.ViaVersion.api.ViaVersion;
import us.myles.ViaVersion.util.ReflectionUtil;
import java.util.Map;
import java.util.UUID;
public class ViaIdleThread extends BukkitRunnable {
private final Map<UUID, ConnectionInfo> portedPlayers;
private final Class<?> idlePacketClass;
public ViaIdleThread(Map<UUID, ConnectionInfo> portedPlayers) {
this.portedPlayers = portedPlayers;
try {
this.idlePacketClass = ReflectionUtil.nms("PacketPlayInFlying");
} catch(ClassNotFoundException e) {
throw new RuntimeException("Couldn't find player idle packet, help!", e);
}
}
@Override
public void run() {
for(ConnectionInfo info : portedPlayers.values()) {
long nextIdleUpdate = info.getNextIdlePacket();
if(nextIdleUpdate <= System.currentTimeMillis()) {
try {
Object packet = idlePacketClass.newInstance();
info.getChannel().pipeline().fireChannelRead(packet);
} catch(InstantiationException | IllegalAccessException e) {
System.out.println("Failed to create idle packet.");
if(ViaVersion.getInstance().isDebug()) {
e.printStackTrace();
}
} finally {
info.incrementIdlePacket();
}
}
}
}
}

View File

@ -73,6 +73,7 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaVersionAPI {
getLogger().info("ViaVersion " + getDescription().getVersion() + " is now enabled, injecting. (Allows 1.8 to be accessed via 1.9)");
injectPacketHandler();
new ViaIdleThread(portedPlayers).runTaskTimerAsynchronously(this, 1L, 1L); // Updates player's idle status
if (getConfig().getBoolean("checkforupdates"))
UpdateUtil.sendUpdateMessage(this);

View File

@ -38,6 +38,11 @@ public class ViaDecodeHandler extends ByteToMessageDecoder {
bytebuf.clear();
throw e;
}
// Update idle status (player, position, look, positionandlook)
if(id == 0x0F || id == 0x0E || id == 0x0D || id == 0x0C) {
info.incrementIdlePacket();
}
}
// call minecraft decoder
list.addAll(PacketUtil.callDecode(this.minecraftDecoder, ctx, bytebuf));