9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-29 11:59:11 +00:00

refactor(bukkit): 解决自定义三叉戟移动问题

- 接下来是设计配置文件
- 后面和优化一起推上去
This commit is contained in:
jhqwqmc
2025-05-10 09:56:42 +08:00
parent 0fa9b84a22
commit dec6cd4063
5 changed files with 58 additions and 24 deletions

View File

@@ -35,6 +35,7 @@ import net.momirealms.craftengine.core.plugin.network.ConnectionState;
import net.momirealms.craftengine.core.plugin.network.NetWorkUser;
import net.momirealms.craftengine.core.plugin.network.NetworkManager;
import net.momirealms.craftengine.core.plugin.network.ProtocolVersion;
import net.momirealms.craftengine.core.plugin.scheduler.SchedulerTask;
import net.momirealms.craftengine.core.util.*;
import net.momirealms.craftengine.core.world.BlockHitResult;
import net.momirealms.craftengine.core.world.BlockPos;
@@ -1620,7 +1621,7 @@ public class PacketConsumers {
try {
int entityId = FastNMS.INSTANCE.method$ClientboundEntityPositionSyncPacket$id(packet);
if (user.tridentView().containsKey(entityId)) {
CustomTridentUtils.modifyCustomTridentPositionSync(user, event, packet, entityId);
CustomTridentUtils.modifyCustomTridentPositionSync(event, packet, entityId);
return;
}
if (BukkitFurnitureManager.instance().isFurnitureRealEntity(entityId)) {
@@ -1651,6 +1652,10 @@ public class PacketConsumers {
int entityId = intList.getInt(i);
user.entityView().remove(entityId);
List<Integer> entities = user.furnitureView().remove(entityId);
SchedulerTask task = user.tridentTaskView().remove(entityId);
if (task != null) {
task.cancel();
}
user.tridentView().remove(entityId);
if (entities == null) continue;
for (int subEntityId : entities) {
@@ -2339,7 +2344,7 @@ public class PacketConsumers {
try {
int entityId = BukkitInjector.internalFieldAccessor().field$ClientboundMoveEntityPacket$entityId(packet);
if (user.tridentView().containsKey(entityId)) {
CustomTridentUtils.modifyCustomTridentMove(packet, user);
CustomTridentUtils.modifyCustomTridentMove(packet);
}
} catch (Exception e) {
CraftEngine.instance().logger().warn("Failed to handle ClientboundMoveEntityPacket$PosRot", e);

View File

@@ -20,6 +20,7 @@ import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.plugin.config.Config;
import net.momirealms.craftengine.core.plugin.network.ConnectionState;
import net.momirealms.craftengine.core.plugin.network.ProtocolVersion;
import net.momirealms.craftengine.core.plugin.scheduler.SchedulerTask;
import net.momirealms.craftengine.core.util.Direction;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.VersionHelper;
@@ -94,7 +95,7 @@ public class BukkitServerPlayer extends Player {
private final Map<Integer, List<Integer>> furnitureView = new ConcurrentHashMap<>();
private final Map<Integer, Object> entityTypeView = new ConcurrentHashMap<>();
private final Map<Integer, List<Object>> tridentView = new ConcurrentHashMap<>();
private final Map<Integer, Object> addTridentPacketView = new ConcurrentHashMap<>();
private final Map<Integer, SchedulerTask> addTridentPacketView = new ConcurrentHashMap<>();
public BukkitServerPlayer(BukkitCraftEngine plugin, Channel channel) {
this.channel = channel;
@@ -745,7 +746,7 @@ public class BukkitServerPlayer extends Player {
}
@Override
public Map<Integer, Object> addTridentPacketView() {
public Map<Integer, SchedulerTask> tridentTaskView() {
return this.addTridentPacketView;
}

View File

@@ -6,7 +6,9 @@ import net.momirealms.craftengine.bukkit.nms.FastNMS;
import net.momirealms.craftengine.bukkit.plugin.network.NMSPacketEvent;
import net.momirealms.craftengine.core.item.Enchantment;
import net.momirealms.craftengine.core.item.Item;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.plugin.network.NetWorkUser;
import net.momirealms.craftengine.core.plugin.scheduler.SchedulerTask;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.MCUtils;
import net.momirealms.craftengine.core.util.VersionHelper;
@@ -25,6 +27,7 @@ import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
public class CustomTridentUtils {
public static final NamespacedKey customTridentKey = Objects.requireNonNull(NamespacedKey.fromString("craftengine:custom_trident"));
@@ -35,15 +38,33 @@ public class CustomTridentUtils {
public static void handleCustomTrident(NetWorkUser user, NMSPacketEvent event, Object packet) throws IllegalAccessException {
int entityId = FastNMS.INSTANCE.field$ClientboundAddEntityPacket$entityId(packet);
Trident trident = getTridentById(user, entityId);
Object serverEntity;
Object nmsEntity = FastNMS.INSTANCE.method$CraftEntity$getHandle(trident);
Object tracker = Reflections.field$Entity$trackedEntity.get(nmsEntity);
if (tracker != null) {
serverEntity = Reflections.field$ChunkMap$TrackedEntity$serverEntity.get(tracker);
} else {
serverEntity = null;
}
if (notCustomTrident(trident)) return;
user.tridentView().put(entityId, List.of());
modifyCustomTridentPacket(packet);
user.addTridentPacketView().put(entityId, packet);
List<Object> itemDisplayValues = buildEntityDataValues(trident);
user.tridentView().put(entityId, itemDisplayValues);
user.sendPacket(packet, true);
user.sendPacket(FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(entityId, itemDisplayValues), true);
event.setCancelled(true);
if (serverEntity != null) {
// 这里直接暴力更新
SchedulerTask task = CraftEngine.instance().scheduler().asyncRepeating(() -> {
try {
Reflections.method$ServerEntity$sendChanges.invoke(serverEntity);
} catch (IllegalAccessException | InvocationTargetException e) {
CraftEngine.instance().logger().warn("Failed to send entity data packet", e);
}
}, 5, 5, TimeUnit.MILLISECONDS);
user.tridentTaskView().put(entityId, task);
}
}
@Nullable
@@ -93,8 +114,7 @@ public class CustomTridentUtils {
return itemDisplayValues;
}
// 这里需要补 ClientboundMoveEntityPacket 包 1.21.2+
public static void modifyCustomTridentPositionSync(NetWorkUser user, NMSPacketEvent event, Object packet, int entityId) throws IllegalAccessException, InvocationTargetException, InstantiationException {
public static void modifyCustomTridentPositionSync(NMSPacketEvent event, Object packet, int entityId) throws IllegalAccessException, InvocationTargetException, InstantiationException {
Object positionMoveRotation = Reflections.field$ClientboundEntityPositionSyncPacket$values.get(packet);
boolean onGround = Reflections.field$ClientboundEntityPositionSyncPacket$onGround.getBoolean(packet);
Object position = Reflections.field$PositionMoveRotation$position.get(positionMoveRotation);
@@ -103,18 +123,11 @@ public class CustomTridentUtils {
float xRot = Reflections.field$PositionMoveRotation$xRot.getFloat(positionMoveRotation);
Object newPositionMoveRotation = Reflections.constructor$PositionMoveRotation.newInstance(position, deltaMovement, -yRot, Math.clamp(-xRot, -90.0F, 90.0F));
event.replacePacket(Reflections.constructor$ClientboundEntityPositionSyncPacket.newInstance(entityId, newPositionMoveRotation, onGround));
// List<SmoothMovementPathUtils.Vector3> path = SmoothMovementPathUtils.calculatePath(start, move, yRot, xRot);
// ((Player)user.platformPlayer()).sendMessage("entityId: " + entityId + " position: " + position + " deltaMovement: " + deltaMovement + " xRot: " + xRot + " yRot: " + yRot);
}
public static void modifyCustomTridentMove(Object packet, NetWorkUser user) throws IllegalAccessException {
// int entityId = BukkitInjector.internalFieldAccessor().field$ClientboundMoveEntityPacket$entityId(packet);
// double xa = Reflections.field$ClientboundMoveEntityPacket$xa.getShort(packet);
// double ya = Reflections.field$ClientboundMoveEntityPacket$ya.getShort(packet);
// double za = Reflections.field$ClientboundMoveEntityPacket$za.getShort(packet);
public static void modifyCustomTridentMove(Object packet) throws IllegalAccessException {
float xRot = MCUtils.unpackDegrees(Reflections.field$ClientboundMoveEntityPacket$xRot.getByte(packet));
float yRot = MCUtils.unpackDegrees(Reflections.field$ClientboundMoveEntityPacket$yRot.getByte(packet));
// ((Player)user.platformPlayer()).sendMessage("entityId: " + entityId + " xa: " + xa + " ya: " + ya + " za: " + za + " xRot: " + xRot + " yRot: " + yRot);
Reflections.field$ClientboundMoveEntityPacket$xRot.setByte(packet, MCUtils.packDegrees(Math.clamp(-xRot, -90.0F, 90.0F)));
Reflections.field$ClientboundMoveEntityPacket$yRot.setByte(packet, MCUtils.packDegrees(-yRot));
}

View File

@@ -6699,21 +6699,35 @@ public class Reflections {
)
);
public static final Field field$ClientboundMoveEntityPacket$xa = requireNonNull(
ReflectionUtils.getDeclaredField(
clazz$ClientboundMoveEntityPacket, short.class, 0
public static final Class<?> clazz$ServerEntity = requireNonNull(
BukkitReflectionUtils.findReobfOrMojmapClass(
"server.level.EntityTrackerEntry",
"server.level.ServerEntity"
)
);
public static final Field field$ClientboundMoveEntityPacket$ya = requireNonNull(
ReflectionUtils.getDeclaredField(
clazz$ClientboundMoveEntityPacket, short.class, 1
public static final Method method$ServerEntity$sendChanges = requireNonNull(
ReflectionUtils.getMethod(
clazz$ServerEntity, void.class, new String[]{ "sendChanges", "a" }
)
);
public static final Field field$ClientboundMoveEntityPacket$za = requireNonNull(
public static final Class<?> clazz$ChunkMap$TrackedEntity = requireNonNull(
BukkitReflectionUtils.findReobfOrMojmapClass(
"server.level.PlayerChunkMap$EntityTracker",
"server.level.ChunkMap$TrackedEntity"
)
);
public static final Field field$Entity$trackedEntity = requireNonNull(
ReflectionUtils.getDeclaredField(
clazz$ClientboundMoveEntityPacket, short.class, 2
clazz$Entity, clazz$ChunkMap$TrackedEntity, 0
)
);
public static final Field field$ChunkMap$TrackedEntity$serverEntity = requireNonNull(
ReflectionUtils.getDeclaredField(
clazz$ChunkMap$TrackedEntity, clazz$ServerEntity, 0
)
);
}

View File

@@ -2,6 +2,7 @@ package net.momirealms.craftengine.core.plugin.network;
import io.netty.channel.Channel;
import net.momirealms.craftengine.core.plugin.Plugin;
import net.momirealms.craftengine.core.plugin.scheduler.SchedulerTask;
import net.momirealms.craftengine.core.util.Key;
import org.jetbrains.annotations.ApiStatus;
@@ -48,7 +49,7 @@ public interface NetWorkUser {
Map<Integer, List<Object>> tridentView();
Map<Integer, Object> addTridentPacketView();
Map<Integer, SchedulerTask> tridentTaskView();
boolean clientModEnabled();