9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-31 12:56:28 +00:00

refactor(bukkit): 实现大部分功能

- 修复addEnchantment
- 差一个移动路径补偿
- 求求你们不要喷我频繁提交了,除了这次最多还会有一个实现移动路径补偿的提交,如果你不想收到提交消息可以到我这个pr去取消通知
This commit is contained in:
jhqwqmc
2025-05-10 07:04:41 +08:00
parent a7505ea902
commit 0fa9b84a22
7 changed files with 83 additions and 26 deletions

View File

@@ -309,7 +309,7 @@ public class ComponentItemFactory1_20_5 extends BukkitItemFactory<ComponentItemW
Object enchant = item.getComponent(ComponentTypes.ENCHANTMENTS);
try {
Map<String, Integer> map = EnchantmentUtils.toMap(enchant);
map.put(enchantment.toString(), enchantment.level());
map.put(enchantment.id().toString(), enchantment.level());
item.setJavaComponent(ComponentTypes.ENCHANTMENTS, map);
} catch (ReflectiveOperationException e) {
plugin.logger().warn("Failed to add enchantment", e);
@@ -321,7 +321,7 @@ public class ComponentItemFactory1_20_5 extends BukkitItemFactory<ComponentItemW
Object enchant = item.getComponent(ComponentTypes.STORED_ENCHANTMENTS);
try {
Map<String, Integer> map = EnchantmentUtils.toMap(enchant);
map.put(enchantment.toString(), enchantment.level());
map.put(enchantment.id().toString(), enchantment.level());
item.setJavaComponent(ComponentTypes.STORED_ENCHANTMENTS, map);
} catch (ReflectiveOperationException e) {
plugin.logger().warn("Failed to add stored enchantment", e);

View File

@@ -198,9 +198,9 @@ public class UniversalItemFactory extends BukkitItemFactory<LegacyItemWrapper> {
return;
}
}
item.add(Map.of("id", enchantment.toString(), "lvl", (short) enchantment.level()), "Enchantments");
item.add(Map.of("id", enchantment.id().toString(), "lvl", (short) enchantment.level()), "Enchantments");
} else {
item.set(List.of(Map.of("id", enchantment.toString(), "lvl", (short) enchantment.level())), "Enchantments");
item.set(List.of(Map.of("id", enchantment.id().toString(), "lvl", (short) enchantment.level())), "Enchantments");
}
}
@@ -214,9 +214,9 @@ public class UniversalItemFactory extends BukkitItemFactory<LegacyItemWrapper> {
return;
}
}
item.add(Map.of("id", enchantment.toString(), "lvl", (short) enchantment.level()), "StoredEnchantments");
item.add(Map.of("id", enchantment.id().toString(), "lvl", (short) enchantment.level()), "StoredEnchantments");
} else {
item.set(List.of(Map.of("id", enchantment.toString(), "lvl", (short) enchantment.level())), "StoredEnchantments");
item.set(List.of(Map.of("id", enchantment.id().toString(), "lvl", (short) enchantment.level())), "StoredEnchantments");
}
}

View File

@@ -1620,7 +1620,7 @@ public class PacketConsumers {
try {
int entityId = FastNMS.INSTANCE.method$ClientboundEntityPositionSyncPacket$id(packet);
if (user.tridentView().containsKey(entityId)) {
CustomTridentUtils.modifyCustomTridentPositionSync(event, packet, entityId);
CustomTridentUtils.modifyCustomTridentPositionSync(user, event, packet, entityId);
return;
}
if (BukkitFurnitureManager.instance().isFurnitureRealEntity(entityId)) {
@@ -2329,9 +2329,7 @@ public class PacketConsumers {
public static final TriConsumer<NetWorkUser, NMSPacketEvent, Object> SET_ENTITY_DATA = (user, event, packet) -> {
try {
int entityId = Reflections.field$clazz$ClientboundSetEntityDataPacket$id.getInt(packet);
if (user.tridentView().containsKey(entityId)) {
CustomTridentUtils.modifyCustomTridentSetEntityData(user, event, entityId);
}
CustomTridentUtils.modifyCustomTridentSetEntityData(user, event, entityId);
} catch (Exception e) {
CraftEngine.instance().logger().warn("Failed to handle ClientboundSetEntityDataPacket", e);
}
@@ -2341,7 +2339,7 @@ public class PacketConsumers {
try {
int entityId = BukkitInjector.internalFieldAccessor().field$ClientboundMoveEntityPacket$entityId(packet);
if (user.tridentView().containsKey(entityId)) {
CustomTridentUtils.modifyCustomTridentMove(packet);
CustomTridentUtils.modifyCustomTridentMove(packet, user);
}
} catch (Exception e) {
CraftEngine.instance().logger().warn("Failed to handle ClientboundMoveEntityPacket$PosRot", e);

View File

@@ -94,6 +94,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<>();
public BukkitServerPlayer(BukkitCraftEngine plugin, Channel channel) {
this.channel = channel;
@@ -743,6 +744,11 @@ public class BukkitServerPlayer extends Player {
return this.tridentView;
}
@Override
public Map<Integer, Object> addTridentPacketView() {
return this.addTridentPacketView;
}
public void setResendSound() {
resentSoundTick = gameTicks();
}

View File

@@ -4,12 +4,14 @@ import net.momirealms.craftengine.bukkit.entity.data.ItemDisplayEntityData;
import net.momirealms.craftengine.bukkit.item.BukkitItemManager;
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.network.NetWorkUser;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.MCUtils;
import net.momirealms.craftengine.core.util.VersionHelper;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Trident;
import org.bukkit.inventory.ItemStack;
@@ -33,25 +35,30 @@ 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);
if (!isCustomTrident(trident)) return;
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);
event.addDelayedTask(() -> user.sendPacket(FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(entityId, itemDisplayValues), true));
user.sendPacket(packet, true);
user.sendPacket(FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(entityId, itemDisplayValues), true);
event.setCancelled(true);
}
@Nullable
public static Trident getTridentById(NetWorkUser user, int entityId) {
Player player = (Player) user.platformPlayer();
return (Trident) FastNMS.INSTANCE.getBukkitEntityById(player.getWorld(), entityId);
Entity entity = FastNMS.INSTANCE.getBukkitEntityById(player.getWorld(), entityId);
if (entity instanceof Trident trident) return trident;
return null;
}
public static boolean isCustomTrident(Trident trident) {
if (trident == null) return false;
public static boolean notCustomTrident(Trident trident) {
if (trident == null) return true;
PersistentDataContainer container = trident.getItemStack().getItemMeta().getPersistentDataContainer();
String customTrident = container.get(customTridentKey, PersistentDataType.STRING);
return customTrident != null;
return customTrident == null;
}
public static void modifyCustomTridentPacket(Object packet) throws IllegalAccessException {
@@ -64,9 +71,11 @@ public class CustomTridentUtils {
public static List<Object> buildEntityDataValues(Trident trident) {
List<Object> itemDisplayValues = new ArrayList<>();
PersistentDataContainer container = trident.getItemStack().getItemMeta().getPersistentDataContainer();
ItemStack itemStack = trident.getItemStack();
PersistentDataContainer container = itemStack.getItemMeta().getPersistentDataContainer();
String customTrident = container.get(customTridentKey, PersistentDataType.STRING);
Item<ItemStack> item = BukkitItemManager.instance().createWrappedItem(Key.of(customTrident), null);
itemStack.getEnchantments().forEach((enchantment, level) -> item.addEnchantment(new Enchantment(Key.of(enchantment.getKey().toString()), level)));
Integer interpolationDelay = container.get(interpolationDelayKey, PersistentDataType.INTEGER);
Integer transformationInterpolationDuration = container.get(transformationInterpolationDurationaKey, PersistentDataType.INTEGER);
Integer positionRotationInterpolationDuration = container.get(positionRotationInterpolationDurationKey, PersistentDataType.INTEGER);
@@ -85,7 +94,7 @@ public class CustomTridentUtils {
}
// 这里需要补 ClientboundMoveEntityPacket 包 1.21.2+
public static void modifyCustomTridentPositionSync(NMSPacketEvent event, Object packet, int entityId) throws IllegalAccessException, InvocationTargetException, InstantiationException {
public static void modifyCustomTridentPositionSync(NetWorkUser user, 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);
@@ -94,11 +103,18 @@ 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) throws IllegalAccessException {
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);
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));
}
@@ -107,7 +123,7 @@ public class CustomTridentUtils {
List<Object> newData = user.tridentView().getOrDefault(entityId, List.of());
if (newData.isEmpty()) {
Trident trident = getTridentById(user, entityId);
if (!isCustomTrident(trident)) return null;
if (notCustomTrident(trident)) return null;
newData = buildEntityDataValues(trident);
user.tridentView().put(entityId, newData);
}
@@ -115,8 +131,17 @@ public class CustomTridentUtils {
}
public static void modifyCustomTridentSetEntityData(NetWorkUser user, NMSPacketEvent event, int entityId) {
Object packet = buildCustomTridentSetEntityDataPacket(user, entityId);
if (packet == null) return;
event.replacePacket(packet);
if (user.tridentView().containsKey(entityId)) {
Object packet = buildCustomTridentSetEntityDataPacket(user, entityId);
if (packet == null) return;
event.replacePacket(packet);
} else {
Trident trident = getTridentById(user, entityId);
if (trident == null) return;
if (notCustomTrident(trident)) return;
Object packet = buildCustomTridentSetEntityDataPacket(user, entityId);
if (packet == null) return;
event.replacePacket(packet);
}
}
}

View File

@@ -6103,6 +6103,10 @@ public class Reflections {
)
);
public static final Constructor<?> constructor$ClientboundMoveEntityPacket$PosRot = requireNonNull(
ReflectionUtils.getTheOnlyConstructor(clazz$ClientboundMoveEntityPacket$PosRot)
);
public static final Class<?> clazz$ClientboundRotateHeadPacket = requireNonNull(
BukkitReflectionUtils.findReobfOrMojmapClass(
"network.protocol.game.PacketPlayOutEntityHeadRotation",
@@ -6400,14 +6404,18 @@ public class Reflections {
);
public static final int instance$EntityType$BLOCK_DISPLAY$registryId;
public static final int instance$EntityType$ITEM_DISPLAY$registryId;
public static final int instance$EntityType$TEXT_DISPLAY$registryId;
public static final int instance$EntityType$FALLING_BLOCK$registryId;
public static final int instance$EntityType$TRIDENT$registryId;
static {
try {
instance$EntityType$BLOCK_DISPLAY$registryId = (int) Reflections.method$Registry$getId.invoke(Reflections.instance$BuiltInRegistries$ENTITY_TYPE, instance$EntityType$BLOCK_DISPLAY);
instance$EntityType$ITEM_DISPLAY$registryId = (int) Reflections.method$Registry$getId.invoke(Reflections.instance$BuiltInRegistries$ENTITY_TYPE, instance$EntityType$ITEM_DISPLAY);
instance$EntityType$TEXT_DISPLAY$registryId = (int) Reflections.method$Registry$getId.invoke(Reflections.instance$BuiltInRegistries$ENTITY_TYPE, instance$EntityType$TEXT_DISPLAY);
instance$EntityType$FALLING_BLOCK$registryId = (int) Reflections.method$Registry$getId.invoke(Reflections.instance$BuiltInRegistries$ENTITY_TYPE, instance$EntityType$FALLING_BLOCK);
instance$EntityType$TRIDENT$registryId = (int) Reflections.method$Registry$getId.invoke(Reflections.instance$BuiltInRegistries$ENTITY_TYPE, instance$EntityType$TRIDENT);
} catch (Exception e) {
throw new RuntimeException(e);
}
@@ -6636,7 +6644,7 @@ public class Reflections {
);
public static final Constructor<?> constructor$PositionMoveRotation = Optional.ofNullable(clazz$PositionMoveRotation)
.map(it -> ReflectionUtils.getTheOnlyConstructor(it))
.map(ReflectionUtils::getTheOnlyConstructor)
.orElse(null);
public static final Field field$ClientboundEntityPositionSyncPacket$values = Optional.ofNullable(clazz$ClientboundEntityPositionSyncPacket)
@@ -6664,7 +6672,7 @@ public class Reflections {
.orElse(null);
public static final Constructor<?> constructor$ClientboundEntityPositionSyncPacket = Optional.ofNullable(clazz$ClientboundEntityPositionSyncPacket)
.map(it -> ReflectionUtils.getTheOnlyConstructor(it))
.map(ReflectionUtils::getTheOnlyConstructor)
.orElse(null);
public static final Field field$ClientboundAddEntityPacket$xRot = requireNonNull(
@@ -6690,4 +6698,22 @@ public class Reflections {
clazz$ClientboundMoveEntityPacket, byte.class, 0
)
);
public static final Field field$ClientboundMoveEntityPacket$xa = requireNonNull(
ReflectionUtils.getDeclaredField(
clazz$ClientboundMoveEntityPacket, short.class, 0
)
);
public static final Field field$ClientboundMoveEntityPacket$ya = requireNonNull(
ReflectionUtils.getDeclaredField(
clazz$ClientboundMoveEntityPacket, short.class, 1
)
);
public static final Field field$ClientboundMoveEntityPacket$za = requireNonNull(
ReflectionUtils.getDeclaredField(
clazz$ClientboundMoveEntityPacket, short.class, 2
)
);
}