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:
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user