Skip to content

Commit e05c721

Browse files
committed
add rule: optimizeTeleport
1 parent 0bf667e commit e05c721

File tree

5 files changed

+126
-1
lines changed

5 files changed

+126
-1
lines changed

src/main/java/io/github/optijava/opt_carpet_addition/OptCarpetSettings.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,4 +131,10 @@ public class OptCarpetSettings {
131131
category = {RuleCategory.OPTIMIZATION, RuleCategory.EXPERIMENTAL}
132132
)
133133
public static boolean optimizePlayerConnect = false;
134+
135+
@Rule(
136+
desc = "Handle player teleport in a new thread to reduce the lag.",
137+
category = {RuleCategory.OPTIMIZATION, RuleCategory.EXPERIMENTAL}
138+
)
139+
public static boolean optimizeTeleport = false;
134140
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package io.github.optijava.opt_carpet_addition.mixins.async.optimizeTeleport;
2+
3+
import io.github.optijava.opt_carpet_addition.OptCarpetSettings;
4+
import io.github.optijava.opt_carpet_addition.utils.threading.Threading;
5+
import net.minecraft.network.packet.s2c.play.PlayerPositionLookS2CPacket;
6+
import net.minecraft.server.network.ServerPlayNetworkHandler;
7+
import net.minecraft.server.network.ServerPlayerEntity;
8+
import net.minecraft.util.math.Vec3d;
9+
import org.spongepowered.asm.mixin.Mixin;
10+
import org.spongepowered.asm.mixin.Shadow;
11+
import org.spongepowered.asm.mixin.injection.At;
12+
import org.spongepowered.asm.mixin.injection.Inject;
13+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
14+
15+
import java.util.Set;
16+
17+
@Mixin(
18+
value = ServerPlayNetworkHandler.class,
19+
priority = 900
20+
)
21+
public abstract class ServerPlayNetworkHandler_Mixin {
22+
23+
@Shadow
24+
private Vec3d requestedTeleportPos;
25+
@Shadow
26+
private int requestedTeleportId;
27+
@Shadow
28+
private int teleportRequestTick;
29+
@Shadow
30+
public ServerPlayerEntity player;
31+
@Shadow
32+
private int ticks;
33+
34+
@Inject(
35+
method = "requestTeleport(DDDFFLjava/util/Set;Z)V",
36+
at = @At("HEAD"),
37+
cancellable = true
38+
)
39+
public void injectRequestTeleport(double x, double y, double z, float yaw, float pitch, Set<PlayerPositionLookS2CPacket.Flag> flags, boolean shouldDismount, CallbackInfo ci) {
40+
if (OptCarpetSettings.optimizeTeleport) {
41+
Threading.THREAD_POOL.submit(() -> {
42+
double d = flags.contains((Object) PlayerPositionLookS2CPacket.Flag.X) ? this.player.getX() : 0.0;
43+
double e = flags.contains((Object) PlayerPositionLookS2CPacket.Flag.Y) ? this.player.getY() : 0.0;
44+
double f = flags.contains((Object) PlayerPositionLookS2CPacket.Flag.Z) ? this.player.getZ() : 0.0;
45+
float g = flags.contains((Object) PlayerPositionLookS2CPacket.Flag.Y_ROT) ? this.player.getYaw() : 0.0f;
46+
float h = flags.contains((Object) PlayerPositionLookS2CPacket.Flag.X_ROT) ? this.player.getPitch() : 0.0f;
47+
this.requestedTeleportPos = new Vec3d(x, y, z);
48+
if (++this.requestedTeleportId == Integer.MAX_VALUE) {
49+
this.requestedTeleportId = 0;
50+
}
51+
this.teleportRequestTick = this.ticks;
52+
this.player.updatePositionAndAngles(x, y, z, yaw, pitch);
53+
this.player.networkHandler.sendPacket(new PlayerPositionLookS2CPacket(x - d, y - e, z - f, yaw - g, pitch - h, flags, this.requestedTeleportId, shouldDismount));
54+
});
55+
ci.cancel();
56+
}
57+
}
58+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package io.github.optijava.opt_carpet_addition.mixins.async.optimizeTeleport;
2+
3+
import io.github.optijava.opt_carpet_addition.OptCarpetSettings;
4+
import io.github.optijava.opt_carpet_addition.utils.threading.Threading;
5+
import net.minecraft.entity.Entity;
6+
import net.minecraft.network.packet.s2c.play.DifficultyS2CPacket;
7+
import net.minecraft.network.packet.s2c.play.PlayerRespawnS2CPacket;
8+
import net.minecraft.server.network.ServerPlayerEntity;
9+
import net.minecraft.server.world.ServerWorld;
10+
import net.minecraft.world.WorldProperties;
11+
import net.minecraft.world.biome.source.BiomeAccess;
12+
import org.spongepowered.asm.mixin.Mixin;
13+
import org.spongepowered.asm.mixin.injection.At;
14+
import org.spongepowered.asm.mixin.injection.Inject;
15+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
16+
17+
@Mixin(
18+
value = ServerPlayerEntity.class,
19+
priority = 900
20+
)
21+
public abstract class ServerPlayerEntity_Mixin {
22+
23+
@Inject(
24+
method = "teleport",
25+
at = @At("HEAD"),
26+
cancellable = true
27+
)
28+
public void injectTeleport(ServerWorld targetWorld, double x, double y, double z, float yaw, float pitch, CallbackInfo ci) {
29+
if (OptCarpetSettings.optimizeTeleport) {
30+
Threading.THREAD_POOL.submit(() -> {
31+
ServerPlayerEntity thisInstance = ((ServerPlayerEntity) (Object) this);
32+
33+
thisInstance.setCameraEntity(thisInstance);
34+
thisInstance.stopRiding();
35+
if (targetWorld == thisInstance.world) {
36+
thisInstance.networkHandler.requestTeleport(x, y, z, yaw, pitch);
37+
} else {
38+
ServerWorld serverWorld = thisInstance.getServerWorld();
39+
WorldProperties worldProperties = targetWorld.getLevelProperties();
40+
thisInstance.networkHandler.sendPacket(new PlayerRespawnS2CPacket(targetWorld.getDimension(), targetWorld.getRegistryKey(), BiomeAccess.hashSeed(targetWorld.getSeed()), thisInstance.interactionManager.getGameMode(), thisInstance.interactionManager.getPreviousGameMode(), targetWorld.isDebugWorld(), targetWorld.isFlat(), true));
41+
thisInstance.networkHandler.sendPacket(new DifficultyS2CPacket(worldProperties.getDifficulty(), worldProperties.isDifficultyLocked()));
42+
thisInstance.server.getPlayerManager().sendCommandTree(thisInstance);
43+
serverWorld.removePlayer(thisInstance, Entity.RemovalReason.CHANGED_DIMENSION);
44+
thisInstance.unsetRemoved();
45+
thisInstance.refreshPositionAndAngles(x, y, z, yaw, pitch);
46+
thisInstance.setWorld(targetWorld);
47+
targetWorld.onPlayerTeleport(thisInstance);
48+
thisInstance.worldChanged(serverWorld);
49+
thisInstance.networkHandler.requestTeleport(x, y, z, yaw, pitch);
50+
thisInstance.server.getPlayerManager().sendWorldInfo(thisInstance, targetWorld);
51+
thisInstance.server.getPlayerManager().sendPlayerStatus(thisInstance);
52+
}
53+
});
54+
ci.cancel();
55+
}
56+
}
57+
}

src/main/resources/opt-carpet-addition.accesswidener

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,6 @@ accessible class net/minecraft/entity/mob/EndermanEntity$PickUpBlockGoal
33
accessible class net/minecraft/entity/mob/EndermanEntity$PlaceBlockGoal
44
mutable field net/minecraft/network/packet/c2s/play/ChatMessageC2SPacket chatMessage Ljava/lang/String;
55
accessible field net/minecraft/network/packet/c2s/play/ChatMessageC2SPacket chatMessage Ljava/lang/String;
6-
accessible field net/minecraft/server/network/ServerLoginNetworkHandler server Lnet/minecraft/server/MinecraftServer;
6+
accessible field net/minecraft/server/network/ServerLoginNetworkHandler server Lnet/minecraft/server/MinecraftServer;
7+
accessible method net/minecraft/entity/Entity unsetRemoved ()V
8+
accessible method net/minecraft/server/network/ServerPlayerEntity worldChanged (Lnet/minecraft/server/world/ServerWorld;)V

src/main/resources/opt-carpet-addition.mixins.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
"compatibilityLevel": "JAVA_16",
66
"mixins": [
77
"async.optimizePlayerConnect.ServerLoginNetworkHandler_Mixin",
8+
"async.optimizeTeleport.ServerPlayerEntity_Mixin",
9+
"async.optimizeTeleport.ServerPlayNetworkHandler_Mixin",
810
"disabledEnderManPickupGoal.EnderManEntity_Mixin",
911
"disabledEnderManPlaceBlockGoal.EndermanEntity_Mixin",
1012
"disabledEntityTick.ServerWorld_Mixin",

0 commit comments

Comments
 (0)