mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-19 15:09:15 +00:00
@@ -7,20 +7,21 @@ public interface EntityData<T> {
|
||||
Object serializer();
|
||||
int id();
|
||||
T defaultValue();
|
||||
Object entityDataAccessor();
|
||||
|
||||
default Object createEntityDataIfNotDefaultValue(T value) {
|
||||
if (defaultValue().equals(value)) return null;
|
||||
return EntityDataValue.create(id(), serializer(), value);
|
||||
return EntityDataValue.create(id(), serializer(), entityDataAccessor(), value);
|
||||
}
|
||||
|
||||
default void addEntityDataIfNotDefaultValue(T value, List<Object> list) {
|
||||
if (!defaultValue().equals(value)) {
|
||||
list.add(EntityDataValue.create(id(), serializer(), value));
|
||||
list.add(EntityDataValue.create(id(), serializer(), entityDataAccessor(), value));
|
||||
}
|
||||
}
|
||||
|
||||
default void addEntityData(T value, List<Object> list) {
|
||||
list.add(EntityDataValue.create(id(), serializer(), value));
|
||||
list.add(EntityDataValue.create(id(), serializer(), entityDataAccessor(), value));
|
||||
}
|
||||
|
||||
static <T> EntityData<T> of(int id, Object serializer, T defaultValue) {
|
||||
|
||||
@@ -98,8 +98,7 @@ public class EntityDataValue {
|
||||
throw new IllegalAccessError("Utility class");
|
||||
}
|
||||
|
||||
public static Object create(int id, Object serializer, Object value) {
|
||||
Object entityDataAccessor = FastNMS.INSTANCE.constructor$EntityDataAccessor(id, serializer);
|
||||
public static Object create(int id, Object serializer, Object entityDataAccessor, Object value) {
|
||||
return FastNMS.INSTANCE.method$SynchedEntityData$DataValue$create(entityDataAccessor, value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
package net.momirealms.craftengine.bukkit.entity.data;
|
||||
|
||||
import net.momirealms.craftengine.bukkit.nms.FastNMS;
|
||||
|
||||
public class SimpleEntityData<T> implements EntityData<T> {
|
||||
private final int id;
|
||||
private final Object serializer;
|
||||
private final T defaultValue;
|
||||
private final Object entityDataAccessor;
|
||||
|
||||
public SimpleEntityData(int id, Object serializer, T defaultValue) {
|
||||
this.id = id;
|
||||
this.serializer = serializer;
|
||||
this.defaultValue = defaultValue;
|
||||
this.entityDataAccessor = FastNMS.INSTANCE.constructor$EntityDataAccessor(id, serializer);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -25,4 +29,9 @@ public class SimpleEntityData<T> implements EntityData<T> {
|
||||
public T defaultValue() {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object entityDataAccessor() {
|
||||
return entityDataAccessor;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ import org.joml.Vector3f;
|
||||
import java.io.IOException;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class BukkitFurniture implements Furniture {
|
||||
private final Key id;
|
||||
@@ -130,6 +131,7 @@ public class BukkitFurniture implements Furniture {
|
||||
Object world = FastNMS.INSTANCE.field$CraftWorld$ServerLevel(this.location.getWorld());
|
||||
for (Collider entity : this.colliderEntities) {
|
||||
FastNMS.INSTANCE.method$LevelWriter$addFreshEntity(world, entity.handle());
|
||||
injectFurnitureEntity(entity.handle());
|
||||
Entity bukkitEntity = FastNMS.INSTANCE.method$Entity$getBukkitEntity(entity.handle());
|
||||
bukkitEntity.getPersistentDataContainer().set(BukkitFurnitureManager.FURNITURE_COLLISION, PersistentDataType.BYTE, (byte) 1);
|
||||
}
|
||||
@@ -359,4 +361,24 @@ public class BukkitFurniture implements Furniture {
|
||||
newLocation.add(offset.x, offset.y + 0.6, -offset.z);
|
||||
return newLocation;
|
||||
}
|
||||
|
||||
public static void injectFurnitureEntity(Object nmsEntity) {
|
||||
try {
|
||||
Object trackedEntity = FastNMS.INSTANCE.field$Entity$trackedEntity(nmsEntity);
|
||||
Object serverEntity = FastNMS.INSTANCE.filed$ChunkMap$TrackedEntity$serverEntity(trackedEntity);
|
||||
CoreReflections.handle$ServerEntity$broadcastSetter.invokeExact(serverEntity, Handlers.DO_NOTHING);
|
||||
CoreReflections.handle$ServerEntity$updateIntervalSetter.invokeExact(serverEntity, Integer.MAX_VALUE);
|
||||
} catch (Throwable e) {
|
||||
CraftEngine.instance().logger().warn("Failed to inject collider", e);
|
||||
}
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface Handlers extends Consumer<Object> {
|
||||
Consumer<Object> DO_NOTHING = doNothing();
|
||||
|
||||
static Handlers doNothing() {
|
||||
return (packet) -> {};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,6 +86,7 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager {
|
||||
SoundData data = furniture.settings().sounds().placeSound();
|
||||
location.getWorld().playSound(location, data.id().toString(), SoundCategory.BLOCKS, data.volume(), data.pitch());
|
||||
}
|
||||
BukkitFurniture.injectFurnitureEntity(FastNMS.INSTANCE.method$CraftEntity$getHandle(furnitureEntity));
|
||||
return loadedFurnitureByRealEntityId(furnitureEntity.getEntityId());
|
||||
}
|
||||
|
||||
@@ -101,6 +102,7 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager {
|
||||
for (Entity entity : entities) {
|
||||
if (entity instanceof ItemDisplay display) {
|
||||
handleBaseEntityLoadEarly(display);
|
||||
BukkitFurniture.injectFurnitureEntity(FastNMS.INSTANCE.method$CraftEntity$getHandle(display));
|
||||
} else if (entity instanceof Interaction interaction) {
|
||||
handleCollisionEntityLoadOnEntitiesLoad(interaction);
|
||||
} else if (entity instanceof Boat boat) {
|
||||
@@ -208,6 +210,7 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager {
|
||||
furniture.initializeColliders();
|
||||
}
|
||||
}
|
||||
BukkitFurniture.injectFurnitureEntity(FastNMS.INSTANCE.method$CraftEntity$getHandle(display));
|
||||
if (depth > 2) return;
|
||||
this.plugin.scheduler().sync().runLater(() -> handleBaseEntityLoadLate(display, depth + 1), 1, location.getWorld(), location.getBlockX() >> 4, location.getBlockZ() >> 4);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package net.momirealms.craftengine.bukkit.entity.furniture;
|
||||
|
||||
import com.destroystokyo.paper.event.entity.EntityAddToWorldEvent;
|
||||
import com.destroystokyo.paper.event.entity.EntityRemoveFromWorldEvent;
|
||||
import net.momirealms.craftengine.bukkit.nms.FastNMS;
|
||||
import org.bukkit.entity.ArmorStand;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.ItemDisplay;
|
||||
@@ -36,6 +37,7 @@ public class FurnitureEventListener implements Listener {
|
||||
for (Entity entity : entities) {
|
||||
if (entity instanceof ItemDisplay itemDisplay) {
|
||||
this.manager.handleBaseEntityLoadEarly(itemDisplay);
|
||||
BukkitFurniture.injectFurnitureEntity(FastNMS.INSTANCE.method$CraftEntity$getHandle(itemDisplay));
|
||||
} else if (BukkitFurnitureManager.COLLISION_ENTITY_CLASS.isInstance(entity)) {
|
||||
this.manager.handleCollisionEntityLoadOnEntitiesLoad(entity);
|
||||
}
|
||||
@@ -48,6 +50,7 @@ public class FurnitureEventListener implements Listener {
|
||||
for (Entity entity : entities) {
|
||||
if (entity instanceof ItemDisplay itemDisplay) {
|
||||
this.manager.handleBaseEntityLoadEarly(itemDisplay);
|
||||
BukkitFurniture.injectFurnitureEntity(FastNMS.INSTANCE.method$CraftEntity$getHandle(itemDisplay));
|
||||
} else if (BukkitFurnitureManager.COLLISION_ENTITY_CLASS.isInstance(entity)) {
|
||||
this.manager.handleCollisionEntityLoadOnEntitiesLoad(entity);
|
||||
}
|
||||
|
||||
@@ -161,7 +161,10 @@ public class BukkitProjectileManager implements Listener, ProjectileManager {
|
||||
public class ProjectileInjectTask implements Runnable {
|
||||
private final Projectile projectile;
|
||||
private final SchedulerTask task;
|
||||
private Object cachedServerEntity;
|
||||
private boolean injected;
|
||||
private int lastInjectedInterval = -1;
|
||||
private boolean wasInGround;
|
||||
|
||||
public ProjectileInjectTask(Projectile projectile) {
|
||||
this.projectile = projectile;
|
||||
@@ -180,30 +183,49 @@ public class BukkitProjectileManager implements Listener, ProjectileManager {
|
||||
}
|
||||
Object nmsEntity = FastNMS.INSTANCE.method$CraftEntity$getHandle(this.projectile);
|
||||
if (!this.injected) {
|
||||
Object trackedEntity = FastNMS.INSTANCE.field$Entity$trackedEntity(nmsEntity);
|
||||
if (trackedEntity == null) {
|
||||
return;
|
||||
}
|
||||
Object serverEntity = FastNMS.INSTANCE.filed$ChunkMap$TrackedEntity$serverEntity(trackedEntity);
|
||||
if (serverEntity == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
CoreReflections.field$ServerEntity$updateInterval.set(serverEntity, 1);
|
||||
this.injected = true;
|
||||
} catch (ReflectiveOperationException e) {
|
||||
plugin.logger().warn("Failed to update server entity tracking interval", e);
|
||||
}
|
||||
injectProjectile(nmsEntity, 1);
|
||||
this.injected = true;
|
||||
this.lastInjectedInterval = 1;
|
||||
}
|
||||
if (canSpawnParticle(nmsEntity)) {
|
||||
boolean inGround = FastNMS.INSTANCE.method$AbstractArrow$isInGround(nmsEntity);
|
||||
if (canSpawnParticle(nmsEntity, inGround)) {
|
||||
this.projectile.getWorld().spawnParticle(ParticleUtils.BUBBLE, this.projectile.getLocation(), 3, 0.1, 0.1, 0.1, 0);
|
||||
}
|
||||
projectileByEntityId(this.projectile.getEntityId()).ifPresent(customProjectile -> {
|
||||
customProjectile.setInGroundTime(inGround ? customProjectile.inGroundTime() + 1 : 0);
|
||||
if (customProjectile.inGroundTime() > 5) {
|
||||
if (lastInjectedInterval != Integer.MAX_VALUE) {
|
||||
injectProjectile(nmsEntity, Integer.MAX_VALUE);
|
||||
}
|
||||
} else if (!inGround && wasInGround) {
|
||||
if (lastInjectedInterval != 1) {
|
||||
injectProjectile(nmsEntity, 1);
|
||||
}
|
||||
}
|
||||
this.wasInGround = inGround;
|
||||
});
|
||||
}
|
||||
|
||||
private void injectProjectile(Object entity, int updateInterval) {
|
||||
if (this.cachedServerEntity == null) {
|
||||
Object trackedEntity = FastNMS.INSTANCE.field$Entity$trackedEntity(entity);
|
||||
if (trackedEntity == null) return;
|
||||
Object serverEntity = FastNMS.INSTANCE.filed$ChunkMap$TrackedEntity$serverEntity(trackedEntity);
|
||||
if (serverEntity == null) return;
|
||||
this.cachedServerEntity = serverEntity;
|
||||
}
|
||||
try {
|
||||
CoreReflections.handle$ServerEntity$updateIntervalSetter.invokeExact(this.cachedServerEntity, updateInterval);
|
||||
this.lastInjectedInterval = updateInterval;
|
||||
} catch (Throwable e) {
|
||||
plugin.logger().warn("Failed to update server entity tracking interval", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean canSpawnParticle(Object nmsEntity) {
|
||||
private static boolean canSpawnParticle(Object nmsEntity, boolean inGround) {
|
||||
if (!FastNMS.INSTANCE.field$Entity$wasTouchingWater(nmsEntity)) return false;
|
||||
if (CoreReflections.clazz$AbstractArrow.isInstance(nmsEntity)) {
|
||||
return !FastNMS.INSTANCE.method$AbstractArrow$isInGround(nmsEntity);
|
||||
return !inGround;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import net.momirealms.craftengine.bukkit.nms.FastNMS;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MRegistryOps;
|
||||
import net.momirealms.craftengine.core.item.ItemWrapper;
|
||||
import net.momirealms.craftengine.core.plugin.locale.TranslationManager;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.sparrow.nbt.Tag;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
@@ -111,6 +112,10 @@ public class ComponentItemWrapper implements ItemWrapper<ItemStack> {
|
||||
private void setComponentInternal(Object type, DynamicOps ops, Object value) {
|
||||
if (value == null) return;
|
||||
Object componentType = ensureDataComponentType(type);
|
||||
if (componentType == null) {
|
||||
TranslationManager.instance().log("warning.config.item.component_notfound", type.toString());
|
||||
return;
|
||||
}
|
||||
Codec codec = FastNMS.INSTANCE.method$DataComponentType$codec(componentType);
|
||||
try {
|
||||
DataResult<Object> result = codec.parse(ops, value);
|
||||
|
||||
@@ -48,6 +48,7 @@ public class BukkitCommandManager extends AbstractCommandManager<CommandSender>
|
||||
new DebugSpawnFurnitureCommand(this, plugin),
|
||||
new DebugTargetBlockCommand(this, plugin),
|
||||
new DebugIsSectionInjectedCommand(this, plugin),
|
||||
new DebugEntityId2UUIDCommand(this, plugin),
|
||||
new TotemAnimationCommand(this, plugin),
|
||||
new EnableResourceCommand(this, plugin),
|
||||
new DisableResourceCommand(this, plugin),
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
package net.momirealms.craftengine.bukkit.plugin.command.feature;
|
||||
|
||||
import net.momirealms.craftengine.bukkit.nms.FastNMS;
|
||||
import net.momirealms.craftengine.bukkit.plugin.command.BukkitCommandFeature;
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
import net.momirealms.craftengine.core.plugin.command.CraftEngineCommandManager;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.incendo.cloud.Command;
|
||||
import org.incendo.cloud.CommandManager;
|
||||
import org.incendo.cloud.bukkit.parser.WorldParser;
|
||||
import org.incendo.cloud.parser.standard.IntegerParser;
|
||||
|
||||
public class DebugEntityId2UUIDCommand extends BukkitCommandFeature<CommandSender> {
|
||||
|
||||
public DebugEntityId2UUIDCommand(CraftEngineCommandManager<CommandSender> commandManager, CraftEngine plugin) {
|
||||
super(commandManager, plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Command.Builder<? extends CommandSender> assembleCommand(CommandManager<CommandSender> manager, Command.Builder<CommandSender> builder) {
|
||||
return builder
|
||||
.required("world", WorldParser.worldParser())
|
||||
.required("entityId", IntegerParser.integerParser())
|
||||
.handler(context -> {
|
||||
World world = context.get("world");
|
||||
int entityId = context.get("entityId");
|
||||
Entity entity = FastNMS.INSTANCE.getBukkitEntityById(world, entityId);
|
||||
if (entity == null) {
|
||||
context.sender().sendMessage("entity not found");
|
||||
return;
|
||||
}
|
||||
Location location = entity.getLocation();
|
||||
context.sender().sendMessage(
|
||||
String.format(
|
||||
"""
|
||||
===========================
|
||||
uuid: %s
|
||||
name: %s
|
||||
location: %s,%s,%s
|
||||
type: %s
|
||||
===========================
|
||||
""",
|
||||
entity.getUniqueId(),
|
||||
entity.getName(),
|
||||
location.x(), location.y(), location.z(),
|
||||
entity.getType()
|
||||
)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFeatureID() {
|
||||
return "debug_entity_id_to_uuid";
|
||||
}
|
||||
}
|
||||
@@ -148,7 +148,6 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
|
||||
registerNMSPacketConsumer(PacketConsumers.LOGIN, NetworkReflections.clazz$ClientboundLoginPacket);
|
||||
registerNMSPacketConsumer(PacketConsumers.RESPAWN, NetworkReflections.clazz$ClientboundRespawnPacket);
|
||||
registerNMSPacketConsumer(PacketConsumers.SYNC_ENTITY_POSITION, NetworkReflections.clazz$ClientboundEntityPositionSyncPacket);
|
||||
registerNMSPacketConsumer(PacketConsumers.MOVE_POS_ENTITY, NetworkReflections.clazz$ClientboundMoveEntityPacket$Pos);
|
||||
registerNMSPacketConsumer(PacketConsumers.PICK_ITEM_FROM_ENTITY, NetworkReflections.clazz$ServerboundPickItemFromEntityPacket);
|
||||
registerNMSPacketConsumer(PacketConsumers.RENAME_ITEM, NetworkReflections.clazz$ServerboundRenameItemPacket);
|
||||
registerNMSPacketConsumer(PacketConsumers.SIGN_UPDATE, NetworkReflections.clazz$ServerboundSignUpdatePacket);
|
||||
@@ -176,7 +175,7 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
|
||||
registerS2CByteBufPacketConsumer(VersionHelper.isOrAbove1_20_3() ? PacketConsumers.SET_OBJECTIVE_1_20_3 : PacketConsumers.SET_OBJECTIVE_1_20, this.packetIds.clientboundSetObjectivePacket());
|
||||
registerS2CByteBufPacketConsumer(PacketConsumers.SET_SCORE_1_20_3, VersionHelper.isOrAbove1_20_3() ? this.packetIds.clientboundSetScorePacket() : -1);
|
||||
registerS2CByteBufPacketConsumer(PacketConsumers.REMOVE_ENTITY, this.packetIds.clientboundRemoveEntitiesPacket());
|
||||
registerS2CByteBufPacketConsumer(PacketConsumers.ADD_ENTITY_BYTEBUFFER, this.packetIds.clientboundAddEntityPacket());
|
||||
registerS2CByteBufPacketConsumer(PacketConsumers.ADD_ENTITY, this.packetIds.clientboundAddEntityPacket());
|
||||
registerS2CByteBufPacketConsumer(PacketConsumers.SOUND, this.packetIds.clientboundSoundPacket());
|
||||
registerS2CByteBufPacketConsumer(PacketConsumers.SET_ENTITY_DATA, this.packetIds.clientboundSetEntityDataPacket());
|
||||
registerS2CByteBufPacketConsumer(PacketConsumers.CONTAINER_SET_CONTENT, this.packetIds.clientboundContainerSetContentPacket());
|
||||
|
||||
@@ -70,7 +70,6 @@ import org.bukkit.util.RayTraceResult;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
import java.util.function.BiConsumer;
|
||||
@@ -163,7 +162,6 @@ public class PacketConsumers {
|
||||
BukkitFurniture furniture = BukkitFurnitureManager.instance().loadedFurnitureByRealEntityId(id);
|
||||
if (furniture != null) {
|
||||
event.setCancelled(true);
|
||||
user.entityPacketHandlers().put(id, FurnitureCollisionPacketHandler.INSTANCE);
|
||||
}
|
||||
};
|
||||
ADD_ENTITY_HANDLERS[MEntityTypes.OAK_BOAT$registryId] = (user, event) -> {
|
||||
@@ -174,7 +172,6 @@ public class PacketConsumers {
|
||||
BukkitFurniture furniture = BukkitFurnitureManager.instance().loadedFurnitureByRealEntityId(id);
|
||||
if (furniture != null) {
|
||||
event.setCancelled(true);
|
||||
user.entityPacketHandlers().put(id, FurnitureCollisionPacketHandler.INSTANCE);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -1172,21 +1169,21 @@ public class PacketConsumers {
|
||||
public static final TriConsumer<NetWorkUser, NMSPacketEvent, Object> HELLO_C2S = (user, event, packet) -> {
|
||||
try {
|
||||
BukkitServerPlayer player = (BukkitServerPlayer) user;
|
||||
String name = (String) NetworkReflections.field$ServerboundHelloPacket$name.get(packet);
|
||||
String name = (String) NetworkReflections.handle$ServerboundHelloPacket$nameGetter.invokeExact(packet);
|
||||
player.setName(name);
|
||||
if (VersionHelper.isOrAbove1_20_2()) {
|
||||
UUID uuid = (UUID) NetworkReflections.field$ServerboundHelloPacket$uuid.get(packet);
|
||||
UUID uuid = (UUID) NetworkReflections.handle$ServerboundHelloPacket$uuidGetter.invokeExact(packet);
|
||||
player.setUUID(uuid);
|
||||
} else {
|
||||
@SuppressWarnings("unchecked")
|
||||
Optional<UUID> uuid = (Optional<UUID>) NetworkReflections.field$ServerboundHelloPacket$uuid.get(packet);
|
||||
Optional<UUID> uuid = (Optional<UUID>) NetworkReflections.handle$ServerboundHelloPacket$uuidGetter.invokeExact(packet);
|
||||
if (uuid.isPresent()) {
|
||||
player.setUUID(uuid.get());
|
||||
} else {
|
||||
player.setUUID(UUID.nameUUIDFromBytes(("OfflinePlayer:" + name).getBytes(StandardCharsets.UTF_8)));
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
} catch (Throwable e) {
|
||||
CraftEngine.instance().logger().warn("Failed to handle ServerboundHelloPacket", e);
|
||||
}
|
||||
};
|
||||
@@ -1223,10 +1220,10 @@ public class PacketConsumers {
|
||||
player.clearView();
|
||||
Object dimensionKey;
|
||||
if (!VersionHelper.isOrAbove1_20_2()) {
|
||||
dimensionKey = NetworkReflections.field$ClientboundRespawnPacket$dimension.get(packet);
|
||||
dimensionKey = NetworkReflections.handle$ClientboundRespawnPacket$dimensionGetter.invokeExact(packet);
|
||||
} else {
|
||||
Object commonInfo = NetworkReflections.field$ClientboundRespawnPacket$commonPlayerSpawnInfo.get(packet);
|
||||
dimensionKey = NetworkReflections.field$CommonPlayerSpawnInfo$dimension.get(commonInfo);
|
||||
Object commonInfo = NetworkReflections.handle$ClientboundRespawnPacket$commonPlayerSpawnInfoGetter.invokeExact(packet);
|
||||
dimensionKey = NetworkReflections.handle$CommonPlayerSpawnInfo$dimensionGetter.invokeExact(commonInfo);
|
||||
}
|
||||
Object location = FastNMS.INSTANCE.field$ResourceKey$location(dimensionKey);
|
||||
World world = Bukkit.getWorld(Objects.requireNonNull(NamespacedKey.fromString(location.toString())));
|
||||
@@ -1237,7 +1234,7 @@ public class PacketConsumers {
|
||||
} else {
|
||||
CraftEngine.instance().logger().warn("Failed to handle ClientboundRespawnPacket: World " + location + " does not exist");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
} catch (Throwable e) {
|
||||
CraftEngine.instance().logger().warn("Failed to handle ClientboundRespawnPacket", e);
|
||||
}
|
||||
};
|
||||
@@ -1251,10 +1248,10 @@ public class PacketConsumers {
|
||||
if (BukkitNetworkManager.hasViaVersion()) {
|
||||
user.setProtocolVersion(CraftEngine.instance().compatibilityManager().getPlayerProtocolVersion(player.uuid()));
|
||||
}
|
||||
dimensionKey = NetworkReflections.field$ClientboundLoginPacket$dimension.get(packet);
|
||||
dimensionKey = NetworkReflections.handle$ClientboundLoginPacket$dimensionGetter.invokeExact(packet);
|
||||
} else {
|
||||
Object commonInfo = NetworkReflections.field$ClientboundLoginPacket$commonPlayerSpawnInfo.get(packet);
|
||||
dimensionKey = NetworkReflections.field$CommonPlayerSpawnInfo$dimension.get(commonInfo);
|
||||
Object commonInfo = NetworkReflections.handle$ClientboundLoginPacket$commonPlayerSpawnInfoGetter.invokeExact(packet);
|
||||
dimensionKey = NetworkReflections.handle$CommonPlayerSpawnInfo$dimensionGetter.invokeExact(commonInfo);
|
||||
}
|
||||
Object location = FastNMS.INSTANCE.field$ResourceKey$location(dimensionKey);
|
||||
World world = Bukkit.getWorld(Objects.requireNonNull(NamespacedKey.fromString(location.toString())));
|
||||
@@ -1265,7 +1262,7 @@ public class PacketConsumers {
|
||||
} else {
|
||||
CraftEngine.instance().logger().warn("Failed to handle ClientboundLoginPacket: World " + location + " does not exist");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
} catch (Throwable e) {
|
||||
CraftEngine.instance().logger().warn("Failed to handle ClientboundLoginPacket", e);
|
||||
}
|
||||
};
|
||||
@@ -1282,25 +1279,25 @@ public class PacketConsumers {
|
||||
player.platformPlayer().getScheduler().run(BukkitCraftEngine.instance().javaPlugin(), (t) -> {
|
||||
try {
|
||||
handleSetCreativeSlotPacketOnMainThread(player, packet);
|
||||
} catch (Exception e) {
|
||||
} catch (Throwable e) {
|
||||
CraftEngine.instance().logger().warn("Failed to handle ServerboundSetCreativeModeSlotPacket", e);
|
||||
}
|
||||
}, () -> {});
|
||||
} else {
|
||||
handleSetCreativeSlotPacketOnMainThread(player, packet);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
} catch (Throwable e) {
|
||||
CraftEngine.instance().logger().warn("Failed to handle ServerboundSetCreativeModeSlotPacket", e);
|
||||
}
|
||||
};
|
||||
|
||||
private static void handleSetCreativeSlotPacketOnMainThread(BukkitServerPlayer player, Object packet) throws Exception {
|
||||
private static void handleSetCreativeSlotPacketOnMainThread(BukkitServerPlayer player, Object packet) throws Throwable {
|
||||
Player bukkitPlayer = player.platformPlayer();
|
||||
if (bukkitPlayer == null) return;
|
||||
if (bukkitPlayer.getGameMode() != GameMode.CREATIVE) return;
|
||||
int slot = VersionHelper.isOrAbove1_20_5() ? NetworkReflections.field$ServerboundSetCreativeModeSlotPacket$slotNum.getShort(packet) : NetworkReflections.field$ServerboundSetCreativeModeSlotPacket$slotNum.getInt(packet);
|
||||
int slot = VersionHelper.isOrAbove1_20_5() ? (short) NetworkReflections.handle$ServerboundSetCreativeModeSlotPacket$slotNumGetter.invokeExact(packet) : (int) NetworkReflections.handle$ServerboundSetCreativeModeSlotPacket$slotNumGetter.invokeExact(packet);
|
||||
if (slot < 36 || slot > 44) return;
|
||||
ItemStack item = FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(NetworkReflections.field$ServerboundSetCreativeModeSlotPacket$itemStack.get(packet));
|
||||
ItemStack item = FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(NetworkReflections.handle$ServerboundSetCreativeModeSlotPacket$itemStackGetter.invokeExact(packet));
|
||||
if (ItemUtils.isEmpty(item)) return;
|
||||
if (slot - 36 != bukkitPlayer.getInventory().getHeldItemSlot()) {
|
||||
return;
|
||||
@@ -1373,14 +1370,14 @@ public class PacketConsumers {
|
||||
if (!user.isOnline()) return;
|
||||
Player player = (Player) user.platformPlayer();
|
||||
if (player == null) return;
|
||||
Object pos = NetworkReflections.field$ServerboundPickItemFromBlockPacket$pos.get(packet);
|
||||
Object pos = NetworkReflections.handle$ServerboundPickItemFromBlockPacket$posGetter.invokeExact(packet);
|
||||
if (VersionHelper.isFolia()) {
|
||||
int x = FastNMS.INSTANCE.field$Vec3i$x(pos);
|
||||
int z = FastNMS.INSTANCE.field$Vec3i$z(pos);
|
||||
BukkitCraftEngine.instance().scheduler().sync().run(() -> {
|
||||
try {
|
||||
handlePickItemFromBlockPacketOnMainThread(player, pos);
|
||||
} catch (Exception e) {
|
||||
} catch (Throwable e) {
|
||||
CraftEngine.instance().logger().warn("Failed to handle ServerboundPickItemFromBlockPacket", e);
|
||||
}
|
||||
}, player.getWorld(), x >> 4, z >> 4);
|
||||
@@ -1388,17 +1385,17 @@ public class PacketConsumers {
|
||||
BukkitCraftEngine.instance().scheduler().sync().run(() -> {
|
||||
try {
|
||||
handlePickItemFromBlockPacketOnMainThread(player, pos);
|
||||
} catch (Exception e) {
|
||||
} catch (Throwable e) {
|
||||
CraftEngine.instance().logger().warn("Failed to handle ServerboundPickItemFromBlockPacket", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
} catch (Exception e) {
|
||||
} catch (Throwable e) {
|
||||
CraftEngine.instance().logger().warn("Failed to handle ServerboundPickItemFromBlockPacket", e);
|
||||
}
|
||||
};
|
||||
|
||||
private static void handlePickItemFromBlockPacketOnMainThread(Player player, Object pos) throws Exception {
|
||||
private static void handlePickItemFromBlockPacketOnMainThread(Player player, Object pos) throws Throwable {
|
||||
Object serverLevel = FastNMS.INSTANCE.field$CraftWorld$ServerLevel(player.getWorld());
|
||||
Object blockState = FastNMS.INSTANCE.method$BlockGetter$getBlockState(serverLevel, pos);
|
||||
ImmutableBlockState state = BukkitBlockManager.instance().getImmutableBlockState(BlockStateUtils.blockStateToId(blockState));
|
||||
@@ -1411,7 +1408,7 @@ public class PacketConsumers {
|
||||
// 1.21.4+
|
||||
public static final TriConsumer<NetWorkUser, NMSPacketEvent, Object> PICK_ITEM_FROM_ENTITY = (user, event, packet) -> {
|
||||
try {
|
||||
int entityId = (int) NetworkReflections.field$ServerboundPickItemFromEntityPacket$id.get(packet);
|
||||
int entityId = (int) NetworkReflections.handle$ServerboundPickItemFromEntityPacket$idGetter.invokeExact(packet);
|
||||
BukkitFurniture furniture = BukkitFurnitureManager.instance().loadedFurnitureByEntityId(entityId);
|
||||
if (furniture == null) return;
|
||||
Player player = (Player) user.platformPlayer();
|
||||
@@ -1420,7 +1417,7 @@ public class PacketConsumers {
|
||||
player.getScheduler().run(BukkitCraftEngine.instance().javaPlugin(), (t) -> {
|
||||
try {
|
||||
handlePickItemFromEntityOnMainThread(player, furniture);
|
||||
} catch (Exception e) {
|
||||
} catch (Throwable e) {
|
||||
CraftEngine.instance().logger().warn("Failed to handle ServerboundPickItemFromEntityPacket", e);
|
||||
}
|
||||
}, () -> {});
|
||||
@@ -1428,23 +1425,23 @@ public class PacketConsumers {
|
||||
BukkitCraftEngine.instance().scheduler().sync().run(() -> {
|
||||
try {
|
||||
handlePickItemFromEntityOnMainThread(player, furniture);
|
||||
} catch (Exception e) {
|
||||
} catch (Throwable e) {
|
||||
CraftEngine.instance().logger().warn("Failed to handle ServerboundPickItemFromEntityPacket", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
} catch (Exception e) {
|
||||
} catch (Throwable e) {
|
||||
CraftEngine.instance().logger().warn("Failed to handle ServerboundPickItemFromEntityPacket", e);
|
||||
}
|
||||
};
|
||||
|
||||
private static void handlePickItemFromEntityOnMainThread(Player player, BukkitFurniture furniture) throws Exception {
|
||||
private static void handlePickItemFromEntityOnMainThread(Player player, BukkitFurniture furniture) throws Throwable {
|
||||
Key itemId = furniture.config().settings().itemId();
|
||||
if (itemId == null) return;
|
||||
pickItem(player, itemId, null, FastNMS.INSTANCE.method$CraftEntity$getHandle(furniture.baseEntity()));
|
||||
}
|
||||
|
||||
private static void pickItem(Player player, Key itemId, @Nullable Object blockPos, @Nullable Object entity) throws IllegalAccessException, InvocationTargetException {
|
||||
private static void pickItem(Player player, Key itemId, @Nullable Object blockPos, @Nullable Object entity) throws Throwable {
|
||||
ItemStack itemStack = BukkitCraftEngine.instance().itemManager().buildCustomItemStack(itemId, BukkitCraftEngine.instance().adapt(player));
|
||||
if (itemStack == null) {
|
||||
CraftEngine.instance().logger().warn("Item: " + itemId + " is not a valid item");
|
||||
@@ -1453,15 +1450,15 @@ public class PacketConsumers {
|
||||
assert CoreReflections.method$ServerGamePacketListenerImpl$tryPickItem != null;
|
||||
if (VersionHelper.isOrAbove1_21_5()) {
|
||||
CoreReflections.method$ServerGamePacketListenerImpl$tryPickItem.invoke(
|
||||
CoreReflections.field$ServerPlayer$connection.get(FastNMS.INSTANCE.method$CraftPlayer$getHandle(player)),
|
||||
CoreReflections.handle$ServerPlayer$connectionGetter.invokeExact(FastNMS.INSTANCE.method$CraftPlayer$getHandle(player)),
|
||||
FastNMS.INSTANCE.method$CraftItemStack$asNMSCopy(itemStack), blockPos, entity, true);
|
||||
} else {
|
||||
CoreReflections.method$ServerGamePacketListenerImpl$tryPickItem.invoke(
|
||||
CoreReflections.field$ServerPlayer$connection.get(FastNMS.INSTANCE.method$CraftPlayer$getHandle(player)), FastNMS.INSTANCE.method$CraftItemStack$asNMSCopy(itemStack));
|
||||
CoreReflections.handle$ServerPlayer$connectionGetter.invokeExact(FastNMS.INSTANCE.method$CraftPlayer$getHandle(player)), FastNMS.INSTANCE.method$CraftItemStack$asNMSCopy(itemStack));
|
||||
}
|
||||
}
|
||||
|
||||
public static final BiConsumer<NetWorkUser, ByteBufPacketEvent> ADD_ENTITY_BYTEBUFFER = (user, event) -> {
|
||||
public static final BiConsumer<NetWorkUser, ByteBufPacketEvent> ADD_ENTITY = (user, event) -> {
|
||||
try {
|
||||
FriendlyByteBuf buf = event.getBuffer();
|
||||
buf.readVarInt();
|
||||
@@ -1665,7 +1662,7 @@ public class PacketConsumers {
|
||||
} else {
|
||||
BukkitCraftEngine.instance().scheduler().executeSync(mainThreadTask);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
} catch (Throwable e) {
|
||||
CraftEngine.instance().logger().warn("Failed to handle ServerboundInteractPacket", e);
|
||||
}
|
||||
};
|
||||
@@ -1750,20 +1747,20 @@ public class PacketConsumers {
|
||||
if (((BukkitServerPlayer) user).hasPermission(FontManager.BYPASS_ANVIL)) {
|
||||
return;
|
||||
}
|
||||
String message = (String) NetworkReflections.field$ServerboundRenameItemPacket$name.get(packet);
|
||||
String message = (String) NetworkReflections.handle$ServerboundRenameItemPacket$nameGetter.invokeExact(packet);
|
||||
if (message != null && !message.isEmpty()) {
|
||||
// check bypass
|
||||
FontManager manager = CraftEngine.instance().fontManager();
|
||||
IllegalCharacterProcessResult result = manager.processIllegalCharacters(message);
|
||||
if (result.has()) {
|
||||
try {
|
||||
NetworkReflections.field$ServerboundRenameItemPacket$name.set(packet, result.text());
|
||||
NetworkReflections.handle$ServerboundRenameItemPacket$nameSetter.invokeExact(packet, result.text());
|
||||
} catch (ReflectiveOperationException e) {
|
||||
CraftEngine.instance().logger().warn("Failed to replace chat", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
} catch (Throwable e) {
|
||||
CraftEngine.instance().logger().warn("Failed to handle ServerboundRenameItemPacket", e);
|
||||
}
|
||||
};
|
||||
@@ -1776,7 +1773,7 @@ public class PacketConsumers {
|
||||
if (((BukkitServerPlayer) user).hasPermission(FontManager.BYPASS_SIGN)) {
|
||||
return;
|
||||
}
|
||||
String[] lines = (String[]) NetworkReflections.field$ServerboundSignUpdatePacket$lines.get(packet);
|
||||
String[] lines = (String[]) NetworkReflections.handle$ServerboundSignUpdatePacket$linesGetter.invokeExact(packet);
|
||||
FontManager manager = CraftEngine.instance().fontManager();
|
||||
if (!manager.isDefaultFontInUse()) return;
|
||||
for (int i = 0; i < lines.length; i++) {
|
||||
@@ -1788,7 +1785,7 @@ public class PacketConsumers {
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
} catch (Throwable e) {
|
||||
CraftEngine.instance().logger().warn("Failed to handle ServerboundSignUpdatePacket", e);
|
||||
}
|
||||
};
|
||||
@@ -1807,9 +1804,9 @@ public class PacketConsumers {
|
||||
|
||||
boolean changed = false;
|
||||
|
||||
List<String> pages = (List<String>) NetworkReflections.field$ServerboundEditBookPacket$pages.get(packet);
|
||||
List<String> pages = (List<String>) NetworkReflections.handleServerboundEditBookPacket$pagesGetter.invokeExact(packet);
|
||||
List<String> newPages = new ArrayList<>(pages.size());
|
||||
Optional<String> title = (Optional<String>) NetworkReflections.field$ServerboundEditBookPacket$title.get(packet);
|
||||
Optional<String> title = (Optional<String>) NetworkReflections.handle$ServerboundEditBookPacket$titleGetter.invokeExact(packet);
|
||||
Optional<String> newTitle;
|
||||
|
||||
if (title.isPresent()) {
|
||||
@@ -1833,13 +1830,13 @@ public class PacketConsumers {
|
||||
|
||||
if (changed) {
|
||||
Object newPacket = NetworkReflections.constructor$ServerboundEditBookPacket.newInstance(
|
||||
NetworkReflections.field$ServerboundEditBookPacket$slot.get(packet),
|
||||
(int) NetworkReflections.handle$ServerboundEditBookPacket$slotGetter.invokeExact(packet),
|
||||
newPages,
|
||||
newTitle
|
||||
);
|
||||
event.replacePacket(newPacket);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
} catch (Throwable e) {
|
||||
CraftEngine.instance().logger().warn("Failed to handle ServerboundEditBookPacket", e);
|
||||
}
|
||||
};
|
||||
@@ -1866,7 +1863,7 @@ public class PacketConsumers {
|
||||
public static final TriConsumer<NetWorkUser, NMSPacketEvent, Object> CUSTOM_PAYLOAD = (user, event, packet) -> {
|
||||
try {
|
||||
if (!VersionHelper.isOrAbove1_20_5()) return;
|
||||
Object payload = NetworkReflections.field$ServerboundCustomPayloadPacket$payload.get(packet);
|
||||
Object payload = NetworkReflections.handle$ServerboundCustomPayloadPacket$payloadGetter.invokeExact(packet);
|
||||
if (NetworkReflections.clazz$DiscardedPayload.isInstance(payload)) {
|
||||
Payload discardedPayload = DiscardedPayload.from(payload);
|
||||
if (discardedPayload == null || !discardedPayload.channel().equals(NetworkManager.MOD_CHANNEL_KEY))
|
||||
@@ -1895,7 +1892,7 @@ public class PacketConsumers {
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
} catch (Throwable e) {
|
||||
CraftEngine.instance().logger().warn("Failed to handle ServerboundCustomPayloadPacket", e);
|
||||
}
|
||||
};
|
||||
@@ -2285,9 +2282,9 @@ public class PacketConsumers {
|
||||
public static final TriConsumer<NetWorkUser, NMSPacketEvent, Object> HANDSHAKE_C2S = (user, event, packet) -> {
|
||||
try {
|
||||
if (BukkitNetworkManager.hasViaVersion()) return;
|
||||
int protocolVersion = NetworkReflections.field$ClientIntentionPacket$protocolVersion.getInt(packet);
|
||||
int protocolVersion = (int) NetworkReflections.handle$ClientIntentionPacket$protocolVersionGetter.invokeExact(packet);
|
||||
user.setProtocolVersion(protocolVersion);
|
||||
} catch (Exception e) {
|
||||
} catch (Throwable e) {
|
||||
CraftEngine.instance().logger().warn("Failed to handle ClientIntentionPacket", e);
|
||||
}
|
||||
};
|
||||
@@ -2305,7 +2302,7 @@ public class PacketConsumers {
|
||||
public static final TriConsumer<NetWorkUser, NMSPacketEvent, Object> RESOURCE_PACK_RESPONSE = (user, event, packet) -> {
|
||||
try {
|
||||
if (user.sentResourcePack() || !Config.sendPackOnJoin() || !Config.kickOnDeclined()) return;
|
||||
Object action = NetworkReflections.field$ServerboundResourcePackPacket$action.get(packet);
|
||||
Object action = NetworkReflections.handle$ServerboundResourcePackPacket$actionGetter.invokeExact(packet);
|
||||
if (action == null) return;
|
||||
if (action == NetworkReflections.instance$ServerboundResourcePackPacket$Action$DECLINED
|
||||
|| action == NetworkReflections.instance$ServerboundResourcePackPacket$Action$FAILED_DOWNLOAD) {
|
||||
@@ -2318,7 +2315,7 @@ public class PacketConsumers {
|
||||
if (action == NetworkReflections.instance$ServerboundResourcePackPacket$Action$SUCCESSFULLY_LOADED) {
|
||||
user.setSentResourcePack(true);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
} catch (Throwable e) {
|
||||
CraftEngine.instance().logger().warn("Failed to handle ServerboundResourcePackPacket", e);
|
||||
}
|
||||
};
|
||||
@@ -2327,28 +2324,17 @@ public class PacketConsumers {
|
||||
try {
|
||||
Object player = user.serverPlayer();
|
||||
if (player == null) return;
|
||||
int entityId = NetworkReflections.field$ClientboundEntityEventPacket$entityId.getInt(packet);
|
||||
int entityId = (int) NetworkReflections.handle$ClientboundEntityEventPacket$entityIdGetter.invokeExact(packet);
|
||||
if (entityId != FastNMS.INSTANCE.method$Entity$getId(player)) return;
|
||||
byte eventId = NetworkReflections.field$ClientboundEntityEventPacket$eventId.getByte(packet);
|
||||
byte eventId = (byte) NetworkReflections.handle$ClientboundEntityEventPacket$eventIdGetter.invokeExact(packet);
|
||||
if (eventId >= 24 && eventId <= 28) {
|
||||
CraftEngine.instance().fontManager().refreshEmojiSuggestions(user.uuid());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
} catch (Throwable e) {
|
||||
CraftEngine.instance().logger().warn("Failed to handle ClientboundEntityEventPacket", e);
|
||||
}
|
||||
};
|
||||
|
||||
public static final TriConsumer<NetWorkUser, NMSPacketEvent, Object> MOVE_POS_ENTITY = (user, event, packet) -> {
|
||||
try {
|
||||
int entityId = ProtectedFieldVisitor.get().field$ClientboundMoveEntityPacket$entityId(packet);
|
||||
if (BukkitFurnitureManager.instance().isFurnitureRealEntity(entityId)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
CraftEngine.instance().logger().warn("Failed to handle ClientboundMoveEntityPacket", e);
|
||||
}
|
||||
};
|
||||
|
||||
public static final TriConsumer<NetWorkUser, NMSPacketEvent, Object> MOVE_POS_AND_ROTATE_ENTITY = (user, event, packet) -> {
|
||||
try {
|
||||
int entityId = ProtectedFieldVisitor.get().field$ClientboundMoveEntityPacket$entityId(packet);
|
||||
|
||||
@@ -5,6 +5,7 @@ import net.momirealms.craftengine.bukkit.nms.FastNMS;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections;
|
||||
import net.momirealms.craftengine.bukkit.plugin.user.BukkitServerPlayer;
|
||||
import net.momirealms.craftengine.bukkit.util.EntityDataUtils;
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
import net.momirealms.craftengine.core.plugin.network.ByteBufPacketEvent;
|
||||
import net.momirealms.craftengine.core.plugin.network.EntityPacketHandler;
|
||||
import net.momirealms.craftengine.core.plugin.network.NetWorkUser;
|
||||
@@ -26,9 +27,13 @@ public class CommonItemPacketHandler implements EntityPacketHandler {
|
||||
for (int i = 0; i < packedItems.size(); i++) {
|
||||
Object packedItem = packedItems.get(i);
|
||||
int entityDataId = FastNMS.INSTANCE.field$SynchedEntityData$DataValue$id(packedItem);
|
||||
// TODO 检查为什么会导致问题,难道是其他插件乱发entity id?
|
||||
if (entityDataId == EntityDataUtils.ITEM_DATA_ID && CoreReflections.clazz$ItemStack.isInstance(packedItem)) {
|
||||
if (entityDataId == EntityDataUtils.ITEM_DATA_ID) {
|
||||
Object nmsItemStack = FastNMS.INSTANCE.field$SynchedEntityData$DataValue$value(packedItem);
|
||||
// TODO 检查为什么会导致问题,难道是其他插件乱发entity id?
|
||||
if (!CoreReflections.clazz$ItemStack.isInstance(nmsItemStack)) {
|
||||
CraftEngine.instance().logger().warn("Invalid item data for entity " + id);
|
||||
continue;
|
||||
}
|
||||
ItemStack itemStack = FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(nmsItemStack);
|
||||
Optional<ItemStack> optional = BukkitItemManager.instance().s2c(itemStack, (BukkitServerPlayer) user);
|
||||
if (optional.isPresent()) {
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
package net.momirealms.craftengine.bukkit.plugin.network.handler;
|
||||
|
||||
import net.momirealms.craftengine.core.plugin.network.EntityPacketHandler;
|
||||
import net.momirealms.craftengine.core.plugin.network.NMSPacketEvent;
|
||||
import net.momirealms.craftengine.core.plugin.network.NetWorkUser;
|
||||
|
||||
public class FurnitureCollisionPacketHandler implements EntityPacketHandler {
|
||||
public static final FurnitureCollisionPacketHandler INSTANCE = new FurnitureCollisionPacketHandler();
|
||||
|
||||
@Override
|
||||
public void handleSyncEntityPosition(NetWorkUser user, NMSPacketEvent event, Object packet) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
@@ -2,8 +2,6 @@ package net.momirealms.craftengine.bukkit.plugin.network.handler;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.IntList;
|
||||
import net.momirealms.craftengine.core.plugin.network.EntityPacketHandler;
|
||||
import net.momirealms.craftengine.core.plugin.network.NMSPacketEvent;
|
||||
import net.momirealms.craftengine.core.plugin.network.NetWorkUser;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -19,9 +17,4 @@ public class FurniturePacketHandler implements EntityPacketHandler {
|
||||
entityIds.addAll(this.fakeEntities);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleSyncEntityPosition(NetWorkUser user, NMSPacketEvent event, Object packet) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,8 @@ import net.momirealms.craftengine.core.util.ReflectionUtils;
|
||||
import net.momirealms.craftengine.core.util.VersionHelper;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodType;
|
||||
import java.lang.invoke.VarHandle;
|
||||
import java.lang.reflect.*;
|
||||
import java.util.*;
|
||||
@@ -3265,4 +3267,33 @@ public final class CoreReflections {
|
||||
public static final Method method$Registry$asLookup = ReflectionUtils.getMethod(
|
||||
clazz$Registry, clazz$HolderLookup$RegistryLookup, new String[]{"asLookup", "p"}
|
||||
);
|
||||
|
||||
public static final Field field$ServerEntity$broadcast = requireNonNull(
|
||||
ReflectionUtils.getDeclaredField(
|
||||
clazz$ServerEntity, Consumer.class, 0
|
||||
)
|
||||
);
|
||||
|
||||
public static final MethodHandle handle$ServerEntity$broadcastSetter;
|
||||
public static final MethodHandle handle$ServerEntity$updateIntervalSetter;
|
||||
public static final MethodHandle handle$ServerPlayer$connectionGetter;
|
||||
|
||||
static {
|
||||
try {
|
||||
handle$ServerEntity$broadcastSetter = requireNonNull(
|
||||
ReflectionUtils.unreflectSetter(field$ServerEntity$broadcast)
|
||||
.asType(MethodType.methodType(void.class, Object.class, Consumer.class))
|
||||
);
|
||||
handle$ServerEntity$updateIntervalSetter = requireNonNull(
|
||||
ReflectionUtils.unreflectSetter(field$ServerEntity$updateInterval)
|
||||
.asType(MethodType.methodType(void.class, Object.class, int.class))
|
||||
);
|
||||
handle$ServerPlayer$connectionGetter = requireNonNull(
|
||||
ReflectionUtils.unreflectGetter(field$ServerPlayer$connection)
|
||||
.asType(MethodType.methodType(Object.class, Object.class))
|
||||
);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new ReflectionInitException("Failed to initialize reflection", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
package net.momirealms.craftengine.bukkit.plugin.reflection.minecraft;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.ReflectionInitException;
|
||||
import net.momirealms.craftengine.bukkit.util.BukkitReflectionUtils;
|
||||
import net.momirealms.craftengine.core.util.ReflectionUtils;
|
||||
import net.momirealms.craftengine.core.util.VersionHelper;
|
||||
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodType;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
@@ -968,7 +971,7 @@ public final class NetworkReflections {
|
||||
);
|
||||
|
||||
public static final Field field$ServerboundEditBookPacket$slot = requireNonNull(
|
||||
ReflectionUtils.getDeclaredField(clazz$ServerboundEditBookPacket, int.class, 0)
|
||||
ReflectionUtils.getDeclaredField(clazz$ServerboundEditBookPacket, int.class, VersionHelper.isOrAbove1_20_5() ? 0 : 4)
|
||||
);
|
||||
|
||||
public static final Field field$ServerboundEditBookPacket$pages = requireNonNull(
|
||||
@@ -1300,4 +1303,170 @@ public final class NetworkReflections {
|
||||
"network.protocol.game.ClientboundBlockEventPacket"
|
||||
)
|
||||
);
|
||||
|
||||
public static final MethodHandle handle$ServerboundRenameItemPacket$nameGetter;
|
||||
public static final MethodHandle handle$ServerboundRenameItemPacket$nameSetter;
|
||||
public static final MethodHandle handle$ServerboundHelloPacket$nameGetter;
|
||||
public static final MethodHandle handle$ServerboundHelloPacket$uuidGetter;
|
||||
public static final MethodHandle handle$ServerboundSetCreativeModeSlotPacket$itemStackGetter;
|
||||
public static final MethodHandle handle$ServerboundSetCreativeModeSlotPacket$slotNumGetter;
|
||||
public static final MethodHandle handle$ServerboundInteractPacket$actionGetter;
|
||||
public static final MethodHandle handle$ServerboundInteractPacket$InteractionAtLocationAction$handGetter;
|
||||
public static final MethodHandle handle$ServerboundInteractPacket$InteractionAtLocationAction$locationGetter;
|
||||
public static final MethodHandle handle$ServerboundSignUpdatePacket$linesGetter;
|
||||
public static final MethodHandle handleServerboundEditBookPacket$pagesGetter;
|
||||
public static final MethodHandle handle$ServerboundEditBookPacket$titleGetter;
|
||||
public static final MethodHandle handle$ServerboundEditBookPacket$slotGetter;
|
||||
public static final MethodHandle handle$ServerboundResourcePackPacket$actionGetter;
|
||||
public static final MethodHandle handle$ClientboundEntityEventPacket$entityIdGetter;
|
||||
public static final MethodHandle handle$ClientboundEntityEventPacket$eventIdGetter;
|
||||
public static final MethodHandle handle$ClientIntentionPacket$protocolVersionGetter;
|
||||
public static final MethodHandle handle$ClientboundRespawnPacket$dimensionGetter;
|
||||
public static final MethodHandle handle$ClientboundRespawnPacket$commonPlayerSpawnInfoGetter;
|
||||
public static final MethodHandle handle$CommonPlayerSpawnInfo$dimensionGetter;
|
||||
public static final MethodHandle handle$ClientboundLoginPacket$dimensionGetter;
|
||||
public static final MethodHandle handle$ClientboundLoginPacket$commonPlayerSpawnInfoGetter;
|
||||
public static final MethodHandle handle$ServerboundPickItemFromBlockPacket$posGetter;
|
||||
public static final MethodHandle handle$ServerboundPickItemFromEntityPacket$idGetter;
|
||||
public static final MethodHandle handle$ServerboundCustomPayloadPacket$payloadGetter;
|
||||
|
||||
static {
|
||||
try {
|
||||
handle$ServerboundRenameItemPacket$nameGetter = requireNonNull(
|
||||
ReflectionUtils.unreflectGetter(field$ServerboundRenameItemPacket$name)
|
||||
.asType(MethodType.methodType(String.class, Object.class))
|
||||
);
|
||||
handle$ServerboundRenameItemPacket$nameSetter = requireNonNull(
|
||||
ReflectionUtils.unreflectSetter(field$ServerboundRenameItemPacket$name)
|
||||
.asType(MethodType.methodType(void.class, Object.class, String.class))
|
||||
);
|
||||
handle$ServerboundHelloPacket$nameGetter = requireNonNull(
|
||||
ReflectionUtils.unreflectGetter(field$ServerboundHelloPacket$name)
|
||||
.asType(MethodType.methodType(String.class, Object.class))
|
||||
);
|
||||
handle$ServerboundHelloPacket$uuidGetter = requireNonNull(
|
||||
ReflectionUtils.unreflectGetter(field$ServerboundHelloPacket$uuid)
|
||||
.asType(MethodType.methodType(VersionHelper.isOrAbove1_20_2() ? UUID.class : Optional.class, Object.class))
|
||||
);
|
||||
handle$ServerboundSetCreativeModeSlotPacket$itemStackGetter = requireNonNull(
|
||||
ReflectionUtils.unreflectGetter(field$ServerboundSetCreativeModeSlotPacket$itemStack)
|
||||
.asType(MethodType.methodType(Object.class, Object.class))
|
||||
);
|
||||
handle$ServerboundSetCreativeModeSlotPacket$slotNumGetter = requireNonNull(
|
||||
ReflectionUtils.unreflectGetter(field$ServerboundSetCreativeModeSlotPacket$slotNum)
|
||||
.asType(MethodType.methodType(VersionHelper.isOrAbove1_20_5() ? short.class : int.class, Object.class))
|
||||
);
|
||||
handle$ServerboundInteractPacket$actionGetter = requireNonNull(
|
||||
ReflectionUtils.unreflectGetter(field$ServerboundInteractPacket$action)
|
||||
.asType(MethodType.methodType(Object.class, Object.class))
|
||||
);
|
||||
handle$ServerboundInteractPacket$InteractionAtLocationAction$handGetter = requireNonNull(
|
||||
ReflectionUtils.unreflectGetter(field$ServerboundInteractPacket$InteractionAtLocationAction$hand)
|
||||
.asType(MethodType.methodType(Object.class, Object.class))
|
||||
);
|
||||
handle$ServerboundInteractPacket$InteractionAtLocationAction$locationGetter = requireNonNull(
|
||||
ReflectionUtils.unreflectGetter(field$ServerboundInteractPacket$InteractionAtLocationAction$location)
|
||||
.asType(MethodType.methodType(Object.class, Object.class))
|
||||
);
|
||||
handle$ServerboundSignUpdatePacket$linesGetter = requireNonNull(
|
||||
ReflectionUtils.unreflectGetter(field$ServerboundSignUpdatePacket$lines)
|
||||
.asType(MethodType.methodType(String[].class, Object.class))
|
||||
);
|
||||
handleServerboundEditBookPacket$pagesGetter = requireNonNull(
|
||||
ReflectionUtils.unreflectGetter(field$ServerboundEditBookPacket$pages)
|
||||
.asType(MethodType.methodType(List.class, Object.class))
|
||||
);
|
||||
handle$ServerboundEditBookPacket$titleGetter = requireNonNull(
|
||||
ReflectionUtils.unreflectGetter(field$ServerboundEditBookPacket$title)
|
||||
.asType(MethodType.methodType(Optional.class, Object.class))
|
||||
);
|
||||
handle$ServerboundEditBookPacket$slotGetter = requireNonNull(
|
||||
ReflectionUtils.unreflectGetter(field$ServerboundEditBookPacket$slot)
|
||||
.asType(MethodType.methodType(int.class, Object.class))
|
||||
);
|
||||
handle$ServerboundResourcePackPacket$actionGetter = requireNonNull(
|
||||
ReflectionUtils.unreflectGetter(field$ServerboundResourcePackPacket$action)
|
||||
.asType(MethodType.methodType(Object.class, Object.class))
|
||||
);
|
||||
handle$ClientboundEntityEventPacket$entityIdGetter = requireNonNull(
|
||||
ReflectionUtils.unreflectGetter(field$ClientboundEntityEventPacket$entityId)
|
||||
.asType(MethodType.methodType(int.class, Object.class))
|
||||
);
|
||||
handle$ClientboundEntityEventPacket$eventIdGetter = requireNonNull(
|
||||
ReflectionUtils.unreflectGetter(field$ClientboundEntityEventPacket$eventId)
|
||||
.asType(MethodType.methodType(byte.class, Object.class))
|
||||
);
|
||||
handle$ClientIntentionPacket$protocolVersionGetter = requireNonNull(
|
||||
ReflectionUtils.unreflectGetter(field$ClientIntentionPacket$protocolVersion)
|
||||
.asType(MethodType.methodType(int.class, Object.class))
|
||||
);
|
||||
if (field$ServerboundCustomPayloadPacket$payload != null) {
|
||||
handle$ServerboundCustomPayloadPacket$payloadGetter = requireNonNull(
|
||||
ReflectionUtils.unreflectGetter(field$ServerboundCustomPayloadPacket$payload)
|
||||
.asType(MethodType.methodType(Object.class, Object.class))
|
||||
);
|
||||
} else {
|
||||
handle$ServerboundCustomPayloadPacket$payloadGetter = null;
|
||||
}
|
||||
if (field$ServerboundPickItemFromEntityPacket$id != null) {
|
||||
handle$ServerboundPickItemFromEntityPacket$idGetter = requireNonNull(
|
||||
ReflectionUtils.unreflectGetter(field$ServerboundPickItemFromEntityPacket$id)
|
||||
.asType(MethodType.methodType(int.class, Object.class))
|
||||
);
|
||||
} else {
|
||||
handle$ServerboundPickItemFromEntityPacket$idGetter = null;
|
||||
}
|
||||
if (field$ServerboundPickItemFromBlockPacket$pos != null) {
|
||||
handle$ServerboundPickItemFromBlockPacket$posGetter = requireNonNull(
|
||||
ReflectionUtils.unreflectGetter(field$ServerboundPickItemFromBlockPacket$pos)
|
||||
.asType(MethodType.methodType(Object.class, Object.class))
|
||||
);
|
||||
} else {
|
||||
handle$ServerboundPickItemFromBlockPacket$posGetter = null;
|
||||
}
|
||||
if (field$ClientboundLoginPacket$commonPlayerSpawnInfo != null) {
|
||||
handle$ClientboundLoginPacket$commonPlayerSpawnInfoGetter = requireNonNull(
|
||||
ReflectionUtils.unreflectGetter(field$ClientboundLoginPacket$commonPlayerSpawnInfo)
|
||||
.asType(MethodType.methodType(Object.class, Object.class))
|
||||
);
|
||||
} else {
|
||||
handle$ClientboundLoginPacket$commonPlayerSpawnInfoGetter = null;
|
||||
}
|
||||
if (field$ClientboundLoginPacket$dimension != null) {
|
||||
handle$ClientboundLoginPacket$dimensionGetter = requireNonNull(
|
||||
ReflectionUtils.unreflectGetter(field$ClientboundLoginPacket$dimension)
|
||||
.asType(MethodType.methodType(Object.class, Object.class))
|
||||
);
|
||||
} else {
|
||||
handle$ClientboundLoginPacket$dimensionGetter = null;
|
||||
}
|
||||
if (field$CommonPlayerSpawnInfo$dimension != null) {
|
||||
handle$CommonPlayerSpawnInfo$dimensionGetter = requireNonNull(
|
||||
ReflectionUtils.unreflectGetter(field$CommonPlayerSpawnInfo$dimension)
|
||||
.asType(MethodType.methodType(Object.class, Object.class))
|
||||
);
|
||||
} else {
|
||||
handle$CommonPlayerSpawnInfo$dimensionGetter = null;
|
||||
}
|
||||
if (field$ClientboundRespawnPacket$commonPlayerSpawnInfo != null) {
|
||||
handle$ClientboundRespawnPacket$commonPlayerSpawnInfoGetter = requireNonNull(
|
||||
ReflectionUtils.unreflectGetter(field$ClientboundRespawnPacket$commonPlayerSpawnInfo)
|
||||
.asType(MethodType.methodType(Object.class, Object.class))
|
||||
);
|
||||
} else {
|
||||
handle$ClientboundRespawnPacket$commonPlayerSpawnInfoGetter = null;
|
||||
}
|
||||
if (field$ClientboundRespawnPacket$dimension != null) {
|
||||
handle$ClientboundRespawnPacket$dimensionGetter = requireNonNull(
|
||||
ReflectionUtils.unreflectGetter(field$ClientboundRespawnPacket$dimension)
|
||||
.asType(MethodType.methodType(Object.class, Object.class))
|
||||
);
|
||||
} else {
|
||||
handle$ClientboundRespawnPacket$dimensionGetter = null;
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
throw new ReflectionInitException("Failed to initialize reflection", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -182,6 +182,13 @@ debug_clear_cooldown:
|
||||
- /craftengine debug clear-cooldown
|
||||
- /ce debug clear-cooldown
|
||||
|
||||
debug_entity_id_to_uuid:
|
||||
enable: true
|
||||
permission: ce.command.debug.entity_id_to_uuid
|
||||
usage:
|
||||
- /craftengine debug entity-id-to-uuid
|
||||
- /ce debug entity-id-to-uuid
|
||||
|
||||
debug_test:
|
||||
enable: true
|
||||
permission: ce.command.debug.test
|
||||
|
||||
@@ -156,6 +156,7 @@ warning.config.item.invalid_material: "<yellow>Issue found in file <arg:0> - The
|
||||
warning.config.item.invalid_custom_model_data: "<yellow>Issue found in file <arg:0> - The item '<arg:1>' is using a negative custom model data '<arg:2>' which is invalid.</yellow>"
|
||||
warning.config.item.bad_custom_model_data: "<yellow>Issue found in file <arg:0> - The item '<arg:1>' is using a custom model data '<arg:2>' that is too large. It's recommended to use a value lower than 16,777,216.</yellow>"
|
||||
warning.config.item.custom_model_data_conflict: "<yellow>Issue found in file <arg:0> - The item '<arg:1>' is using a custom model data '<arg:2>' that has been occupied by item '<arg:3>'.</yellow>"
|
||||
warning.config.item.component_notfound: "<yellow>Issue found - Have item using a component '<arg:0>' that does not exist.</yellow>"
|
||||
warning.config.item.missing_model_id: "<yellow>Issue found in file <arg:0> - The item '<arg:1>' is missing the required 'custom-model-data' or 'item-model' argument.</yellow>"
|
||||
warning.config.item.missing_model: "<yellow>Issue found in file <arg:0> - The item '<arg:1>' is missing the required 'model' section for 1.21.4+ resource pack support.</yellow>"
|
||||
warning.config.item.behavior.missing_type: "<yellow>Issue found in file <arg:0> - The item '<arg:1>' is missing the required 'type' argument for its item behavior.</yellow>"
|
||||
|
||||
@@ -156,6 +156,7 @@ warning.config.item.invalid_material: "<yellow>在文件 <arg:0> 发现问题 -
|
||||
warning.config.item.invalid_custom_model_data: "<yellow>在文件 <arg:0> 发现问题 - 物品 '<arg:1>' 使用了无效的负数模型值 '<arg:2>'.</yellow>"
|
||||
warning.config.item.bad_custom_model_data: "<yellow>在文件 <arg:0> 发现问题 - 物品 '<arg:1>' 使用的自定义模型数据 '<arg:2>' 数值过大 建议使用小于 16,777,216 的值</yellow>"
|
||||
warning.config.item.custom_model_data_conflict: "<yellow>在文件 <arg:0> 发现问题 - 物品 '<arg:1>' 使用的自定义模型数据 '<arg:2>' 已被物品 '<arg:3>' 占用</yellow>"
|
||||
warning.config.item.component_notfound: "<yellow>发现问题 - 有物品使用了未知的组件 '<arg:0>'</yellow>"
|
||||
warning.config.item.missing_model_id: "<yellow>在文件 <arg:0> 发现问题 - 物品 '<arg:1>' 缺少必需的 'custom-model-data' 或 'item-model' 参数</yellow>"
|
||||
warning.config.item.missing_model: "<yellow>在文件 <arg:0> 中发现问题 - 物品 '<arg:1>' 缺少支持 1.21.4+ 资源包必需的 'model' 配置项</yellow>"
|
||||
warning.config.item.behavior.missing_type: "<yellow>在文件 <arg:0> 发现问题 - 物品 '<arg:1>' 的行为配置缺少必需的 'type' 参数</yellow>"
|
||||
|
||||
@@ -6,6 +6,7 @@ public abstract class AbstractCustomProjectile implements CustomProjectile {
|
||||
protected final ProjectileMeta meta;
|
||||
protected final Projectile projectile;
|
||||
protected final Item<?> item;
|
||||
private int inGroundTime;
|
||||
|
||||
protected AbstractCustomProjectile(ProjectileMeta meta, Projectile projectile, Item<?> item) {
|
||||
this.meta = meta;
|
||||
@@ -27,4 +28,14 @@ public abstract class AbstractCustomProjectile implements CustomProjectile {
|
||||
public Item<?> item() {
|
||||
return item;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int inGroundTime() {
|
||||
return inGroundTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInGroundTime(int inGroundTime) {
|
||||
this.inGroundTime = inGroundTime;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,4 +9,8 @@ public interface CustomProjectile {
|
||||
Projectile projectile();
|
||||
|
||||
Item<?> item();
|
||||
|
||||
int inGroundTime();
|
||||
|
||||
void setInGroundTime(int inGroundTime);
|
||||
}
|
||||
|
||||
@@ -494,6 +494,15 @@ public class ReflectionUtils {
|
||||
}
|
||||
}
|
||||
|
||||
public static MethodHandle unreflectSetter(Field field) throws IllegalAccessException {
|
||||
try {
|
||||
return LOOKUP.unreflectSetter(field);
|
||||
} catch (IllegalAccessException e) {
|
||||
field.setAccessible(true);
|
||||
return LOOKUP.unreflectSetter(field);
|
||||
}
|
||||
}
|
||||
|
||||
public static MethodHandle unreflectMethod(Method method) throws IllegalAccessException {
|
||||
try {
|
||||
return LOOKUP.unreflect(method);
|
||||
|
||||
@@ -3,7 +3,7 @@ org.gradle.jvmargs=-Xmx1G
|
||||
# Project settings
|
||||
# Rule: [major update].[feature update].[bug fix]
|
||||
project_version=0.0.56.3
|
||||
config_version=34
|
||||
config_version=35
|
||||
lang_version=15
|
||||
project_group=net.momirealms
|
||||
latest_supported_version=1.21.5
|
||||
|
||||
Reference in New Issue
Block a user