Keeping use mixin
This commit is contained in:
@@ -0,0 +1,14 @@
|
|||||||
|
package io.akarin.server.mixin.core;
|
||||||
|
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Overwrite;
|
||||||
|
|
||||||
|
import net.minecraft.server.PlayerConnection;
|
||||||
|
|
||||||
|
@Mixin(value = PlayerConnection.class, remap = false)
|
||||||
|
public class MixinPlayerConnection {
|
||||||
|
@Overwrite
|
||||||
|
private long d() {
|
||||||
|
return System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
package io.akarin.server.mixin.core;
|
||||||
|
|
||||||
|
import java.util.Queue;
|
||||||
|
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||||
|
|
||||||
|
import org.spongepowered.asm.mixin.Final;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Overwrite;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
|
||||||
|
import io.akarin.api.CheckedConcurrentLinkedQueue;
|
||||||
|
import io.netty.channel.Channel;
|
||||||
|
import io.netty.util.concurrent.Future;
|
||||||
|
import io.netty.util.concurrent.GenericFutureListener;
|
||||||
|
import net.minecraft.server.NetworkManager;
|
||||||
|
import net.minecraft.server.Packet;
|
||||||
|
|
||||||
|
@Mixin(value = NetworkManager.class, remap = false)
|
||||||
|
public class OptimisticNetworkManager {
|
||||||
|
@Shadow public Channel channel;
|
||||||
|
@Shadow @Final private Queue<NetworkManager.QueuedPacket> i;
|
||||||
|
@Shadow @Final private ReentrantReadWriteLock j;
|
||||||
|
|
||||||
|
@Shadow private Queue<NetworkManager.QueuedPacket> getPacketQueue() { return null; }
|
||||||
|
@Shadow private void dispatchPacket(Packet<?> packet, GenericFutureListener<? extends Future<? super Void>>[] genericFutureListeners) {}
|
||||||
|
|
||||||
|
@Overwrite
|
||||||
|
private boolean m() {
|
||||||
|
if (this.channel != null && this.channel.isOpen()) {
|
||||||
|
if (this.i.isEmpty()) { // return if the packet queue is empty so that the write lock by Anti-Xray doesn't affect the vanilla performance at all
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.j.readLock().lock();
|
||||||
|
try {
|
||||||
|
while (!this.i.isEmpty()) {
|
||||||
|
NetworkManager.QueuedPacket packet = ((CheckedConcurrentLinkedQueue) getPacketQueue()).checkedPoll();
|
||||||
|
|
||||||
|
if (packet != null) { // Fix NPE (Spigot bug caused by handleDisconnection())
|
||||||
|
if (packet == CheckedConcurrentLinkedQueue.emptyPacket) { // Check if the peeked packet is a chunk packet which is not ready
|
||||||
|
return false; // Return false if the peeked packet is a chunk packet which is not ready
|
||||||
|
} else {
|
||||||
|
dispatchPacket(packet.getPacket(), packet.getGenericFutureListeners()); // dispatch the packet
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
this.j.readLock().unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return true; // Return true if all packets were dispatched
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -240,23 +240,23 @@ public class NetworkManager extends SimpleChannelInboundHandler<Packet<?>> {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.j.readLock().lock(); // readLock -> writeLock (because of race condition between peek and poll) // Akarin - writeLock -> readLock
|
this.j.writeLock().lock(); // readLock -> writeLock (because of race condition between peek and poll)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
while (!this.i.isEmpty()) {
|
while (!this.i.isEmpty()) {
|
||||||
NetworkManager.QueuedPacket networkmanager_queuedpacket = ((CheckedConcurrentLinkedQueue) this.getPacketQueue()).checkedPoll(); // poll -> peek // Akarin
|
NetworkManager.QueuedPacket networkmanager_queuedpacket = this.getPacketQueue().peek(); // poll -> peek
|
||||||
|
|
||||||
if (networkmanager_queuedpacket != null) { // Fix NPE (Spigot bug caused by handleDisconnection())
|
if (networkmanager_queuedpacket != null) { // Fix NPE (Spigot bug caused by handleDisconnection())
|
||||||
if (networkmanager_queuedpacket == CheckedConcurrentLinkedQueue.emptyPacket) { // Check if the peeked packet is a chunk packet which is not ready // Akarin
|
if (networkmanager_queuedpacket.getPacket() instanceof PacketPlayOutMapChunk && !((PacketPlayOutMapChunk) networkmanager_queuedpacket.getPacket()).isReady()) { // Check if the peeked packet is a chunk packet which is not ready
|
||||||
return false; // Return false if the peeked packet is a chunk packet which is not ready
|
return false; // Return false if the peeked packet is a chunk packet which is not ready
|
||||||
} else {
|
} else {
|
||||||
// this.getPacketQueue().poll(); // poll here // Akarin - polled
|
this.getPacketQueue().poll(); // poll here
|
||||||
this.dispatchPacket(networkmanager_queuedpacket.getPacket(), networkmanager_queuedpacket.getGenericFutureListeners()); // dispatch the packet
|
this.dispatchPacket(networkmanager_queuedpacket.getPacket(), networkmanager_queuedpacket.getGenericFutureListeners()); // dispatch the packet
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
this.j.readLock().unlock(); // readLock -> writeLock (because of race condition between peek and poll) // Akarin - writeLock -> readLock
|
this.j.writeLock().unlock(); // readLock -> writeLock (because of race condition between peek and poll)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -372,7 +372,7 @@ public class NetworkManager extends SimpleChannelInboundHandler<Packet<?>> {
|
|||||||
public static class QueuedPacket { // Akarin - default -> public
|
public static class QueuedPacket { // Akarin - default -> public
|
||||||
|
|
||||||
private final Packet<?> a; public final Packet<?> getPacket() { return this.a; } // Paper - Anti-Xray - OBFHELPER // Akarin - private -> public
|
private final Packet<?> a; public final Packet<?> getPacket() { return this.a; } // Paper - Anti-Xray - OBFHELPER // Akarin - private -> public
|
||||||
private final GenericFutureListener<? extends Future<? super Void>>[] b; private final GenericFutureListener<? extends Future<? super Void>>[] getGenericFutureListeners() { return this.b; } // Paper - Anti-Xray - OBFHELPER
|
private final GenericFutureListener<? extends Future<? super Void>>[] b; public final GenericFutureListener<? extends Future<? super Void>>[] getGenericFutureListeners() { return this.b; } // Paper - Anti-Xray - OBFHELPER // Akarin - private -> public
|
||||||
|
|
||||||
public QueuedPacket(Packet<?> packet, GenericFutureListener<? extends Future<? super Void>>... agenericfuturelistener) {
|
public QueuedPacket(Packet<?> packet, GenericFutureListener<? extends Future<? super Void>>... agenericfuturelistener) {
|
||||||
this.a = packet;
|
this.a = packet;
|
||||||
|
|||||||
@@ -66,7 +66,6 @@ import co.aikar.timings.MinecraftTimings; // Paper
|
|||||||
* 1) Add volatile to fields<br>
|
* 1) Add volatile to fields<br>
|
||||||
* 2) Expose private members<br>
|
* 2) Expose private members<br>
|
||||||
* 3) Migrated keep alive packet handling to service thread<br>
|
* 3) Migrated keep alive packet handling to service thread<br>
|
||||||
* 4) Use currentMillis() instead of nanoTime() / 1000000
|
|
||||||
* @author cakoyo
|
* @author cakoyo
|
||||||
*/
|
*/
|
||||||
public class PlayerConnection implements PacketListenerPlayIn, ITickable {
|
public class PlayerConnection implements PacketListenerPlayIn, ITickable {
|
||||||
@@ -2299,7 +2298,7 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable {
|
|||||||
|
|
||||||
private long getCurrentMillis() { return d(); } // Paper - OBFHELPER
|
private long getCurrentMillis() { return d(); } // Paper - OBFHELPER
|
||||||
private long d() {
|
private long d() {
|
||||||
return System.currentTimeMillis(); // Akarin
|
return System.nanoTime() / 1000000L;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
"DesyncCatcher",
|
"DesyncCatcher",
|
||||||
"ParallelRegistry",
|
"ParallelRegistry",
|
||||||
"MetricsBootstrap",
|
"MetricsBootstrap",
|
||||||
|
"OptimisticNetworkManager",
|
||||||
"NonblockingServerConnection",
|
"NonblockingServerConnection",
|
||||||
|
|
||||||
"MixinMCUtil",
|
"MixinMCUtil",
|
||||||
@@ -19,6 +20,7 @@
|
|||||||
"MixinVersionCommand",
|
"MixinVersionCommand",
|
||||||
"MixinMinecraftServer",
|
"MixinMinecraftServer",
|
||||||
"MixinChunkIOExecutor",
|
"MixinChunkIOExecutor",
|
||||||
|
"MixinPlayerConnection",
|
||||||
"MixinTileEntityEnchantTable"
|
"MixinTileEntityEnchantTable"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user