Fix Forge handshake taking extremely long time with many payloads
This commit is contained in:
parent
18dc488ab9
commit
79d2b28d5b
|
|
@ -0,0 +1,56 @@
|
|||
package org.embeddedt.modernfix.common.mixin.perf.fix_handshake_stall;
|
||||
|
||||
import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod;
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
|
||||
import net.minecraftforge.network.HandshakeHandler;
|
||||
import net.minecraftforge.network.NetworkRegistry;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Slice;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mixin(value = HandshakeHandler.class, remap = false)
|
||||
public class HandshakeHandlerMixin {
|
||||
@Shadow
|
||||
private int packetPosition;
|
||||
|
||||
@Shadow
|
||||
private List<NetworkRegistry.LoginPayload> messageList;
|
||||
|
||||
@Shadow
|
||||
private List<Integer> sentMessages;
|
||||
|
||||
/**
|
||||
* @author embeddedt
|
||||
* @reason Forge only sends one login payload per tick. It takes many seconds to send all the payloads at this rate.
|
||||
* During this time, the game remains frozen on the chunk loading screen with almost zero CPU usage.
|
||||
* To fix this, we re-tick the handshake handler until the packetPosition stops advancing or the handler indicates
|
||||
* it no longer needs ticking.
|
||||
*/
|
||||
@WrapMethod(method = "tickServer")
|
||||
private boolean modernfix$retick(Operation<Boolean> original) {
|
||||
boolean isDoneTicking;
|
||||
int prevPacketPosition;
|
||||
do {
|
||||
prevPacketPosition = this.packetPosition;
|
||||
isDoneTicking = original.call();
|
||||
} while(!isDoneTicking && this.packetPosition > prevPacketPosition);
|
||||
return isDoneTicking;
|
||||
}
|
||||
|
||||
/**
|
||||
* @author embeddedt
|
||||
* @reason The original HandshakeHandler has an off-by-one error in its completion check. We patch this to prevent
|
||||
* our optimization from potentially triggering it more often due to the timing change.
|
||||
*/
|
||||
@WrapOperation(method = "tickServer", at = @At(value = "INVOKE", target = "Ljava/util/List;isEmpty()Z", ordinal = 0), slice = @Slice(from = @At(value = "INVOKE", target = "Ljava/util/List;removeIf(Ljava/util/function/Predicate;)Z", ordinal = 0)))
|
||||
private boolean preventEarlyExit(List<?> instance, Operation<Boolean> original) {
|
||||
if (instance != this.sentMessages) {
|
||||
throw new AssertionError("Injector is misplaced");
|
||||
}
|
||||
return original.call(instance) && this.packetPosition >= this.messageList.size();
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user