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

初步清洁

This commit is contained in:
XiaoMoMi
2025-06-28 00:33:40 +08:00
parent 1445af7b82
commit 01eb7f5e21
39 changed files with 246 additions and 907 deletions

View File

@@ -53,9 +53,6 @@ public class BukkitAdvancementManager extends AbstractAdvancementManager {
if (advancements.containsKey(id)) {
throw new LocalizedResourceConfigException("warning.config.advancement.duplicate", path, id);
}
JsonElement jsonTree = GsonHelper.get().toJsonTree(section);
FastNMS.INSTANCE.registerAdvancement(id.decompose(), jsonTree);
advancements.put(id, jsonTree);
}
}
}

View File

@@ -153,7 +153,7 @@ public class BlockEventListener implements Listener {
ImmutableBlockState state = manager.getImmutableBlockStateUnsafe(stateId);
if (!state.isEmpty()) {
// double check adventure mode to prevent dupe
if (!FastNMS.INSTANCE.mayBuild(serverPlayer.serverPlayer()) && !serverPlayer.canBreak(LocationUtils.toBlockPos(location), null)) {
if (!FastNMS.INSTANCE.field$Player$mayBuild(serverPlayer.serverPlayer()) && !serverPlayer.canBreak(LocationUtils.toBlockPos(location), null)) {
return;
}

View File

@@ -74,77 +74,49 @@ public class BukkitCustomBlock extends AbstractCustomBlock {
@Override
protected void applyPlatformSettings() {
try {
for (ImmutableBlockState state : variantProvider().states()) {
if (state.vanillaBlockState() == null) {
CraftEngine.instance().logger().warn("Could not find vanilla block state for " + state + ". This might cause errors!");
for (ImmutableBlockState immutableBlockState : variantProvider().states()) {
if (immutableBlockState.vanillaBlockState() == null) {
CraftEngine.instance().logger().warn("Could not find vanilla block immutableBlockState for " + immutableBlockState + ". This might cause errors!");
continue;
} else if (state.customBlockState() == null) {
CraftEngine.instance().logger().warn("Could not find custom block state for " + state + ". This might cause errors!");
} else if (immutableBlockState.customBlockState() == null) {
CraftEngine.instance().logger().warn("Could not find custom block immutableBlockState for " + immutableBlockState + ". This might cause errors!");
continue;
}
Object mcBlockState = state.customBlockState().handle();
BlockSettings settings = state.settings();
// set block state properties
BlockStateUtils.setInstrument(mcBlockState, settings.instrument());
BlockStateUtils.setMapColor(mcBlockState, settings.mapColor());
BlockStateUtils.setLightEmission(mcBlockState, settings.luminance());
BlockStateUtils.setBurnable(mcBlockState, settings.burnable());
BlockStateUtils.setHardness(mcBlockState, settings.hardness());
BlockStateUtils.setPushReaction(mcBlockState, settings.pushReaction());
BlockStateUtils.setReplaceable(mcBlockState, settings.replaceable());
boolean canOcclude;
if (settings.canOcclude() == Tristate.TRUE) {
BlockStateUtils.setCanOcclude(mcBlockState, true);
canOcclude = true;
} else if (settings.canOcclude() == Tristate.FALSE) {
BlockStateUtils.setCanOcclude(mcBlockState, false);
canOcclude = false;
} else {
canOcclude = BlockStateUtils.isOcclude(state.vanillaBlockState().handle());
BlockStateUtils.setCanOcclude(mcBlockState, canOcclude);
}
boolean useShapeForLightOcclusion;
if (settings.useShapeForLightOcclusion() == Tristate.TRUE) {
BlockStateUtils.setUseShapeForLightOcclusion(mcBlockState, true);
useShapeForLightOcclusion = true;
} else if (settings.useShapeForLightOcclusion() == Tristate.FALSE) {
BlockStateUtils.setUseShapeForLightOcclusion(mcBlockState, false);
useShapeForLightOcclusion = false;
} else {
useShapeForLightOcclusion = CoreReflections.field$BlockStateBase$useShapeForLightOcclusion.getBoolean(state.vanillaBlockState().handle());
BlockStateUtils.setUseShapeForLightOcclusion(mcBlockState, useShapeForLightOcclusion);
}
if (settings.isRedstoneConductor() == Tristate.TRUE) {
BlockStateUtils.setIsRedstoneConductor(mcBlockState, ALWAYS_TRUE);
} else if (settings.isRedstoneConductor() == Tristate.FALSE) {
BlockStateUtils.setIsRedstoneConductor(mcBlockState, ALWAYS_FALSE);
}
if (settings.isSuffocating() == Tristate.TRUE) {
BlockStateUtils.setIsSuffocating(mcBlockState, ALWAYS_TRUE);
} else if (settings.isSuffocating() == Tristate.FALSE) {
BlockStateUtils.setIsSuffocating(mcBlockState, ALWAYS_FALSE);
}
if (settings.isViewBlocking() == Tristate.TRUE) {
BlockStateUtils.setIsViewBlocking(mcBlockState, ALWAYS_TRUE);
} else if (settings.isViewBlocking() == Tristate.FALSE) {
BlockStateUtils.setIsViewBlocking(mcBlockState, ALWAYS_FALSE);
} else {
if (settings.isSuffocating() == Tristate.TRUE) {
BlockStateUtils.setIsViewBlocking(mcBlockState, ALWAYS_TRUE);
} else if (settings.isSuffocating() == Tristate.FALSE) {
BlockStateUtils.setIsViewBlocking(mcBlockState, ALWAYS_FALSE);
}
}
CustomBlockStateHolder nmsState = (CustomBlockStateHolder) immutableBlockState.customBlockState().handle();
nmsState.setCustomBlockState(immutableBlockState);
BlockSettings settings = immutableBlockState.settings();
// set block properties
CoreReflections.field$BlockStateBase$lightEmission.set(nmsState, settings.luminance());
CoreReflections.field$BlockStateBase$burnable.set(nmsState, settings.burnable());
CoreReflections.field$BlockStateBase$hardness.set(nmsState, settings.hardness());
CoreReflections.field$BlockStateBase$replaceable.set(nmsState, settings.replaceable());
Object mcMapColor = CoreReflections.method$MapColor$byId.invoke(null, settings.mapColor().id);
CoreReflections.field$BlockStateBase$mapColor.set(nmsState, mcMapColor);
Object mcInstrument = ((Object[]) CoreReflections.method$NoteBlockInstrument$values.invoke(null))[settings.instrument().ordinal()];
CoreReflections.field$BlockStateBase$instrument.set(nmsState, mcInstrument);
Object pushReaction = ((Object[]) CoreReflections.method$PushReaction$values.invoke(null))[settings.pushReaction().ordinal()];
CoreReflections.field$BlockStateBase$pushReaction.set(nmsState, pushReaction);
boolean canOcclude = settings.canOcclude() == Tristate.UNDEFINED ? BlockStateUtils.isOcclude(immutableBlockState.vanillaBlockState().handle()) : settings.canOcclude().asBoolean();
CoreReflections.field$BlockStateBase$canOcclude.set(nmsState, canOcclude);
boolean useShapeForLightOcclusion = settings.useShapeForLightOcclusion() == Tristate.UNDEFINED ? CoreReflections.field$BlockStateBase$useShapeForLightOcclusion.getBoolean(immutableBlockState.vanillaBlockState().handle()) : settings.useShapeForLightOcclusion().asBoolean();
CoreReflections.field$BlockStateBase$useShapeForLightOcclusion.set(nmsState, useShapeForLightOcclusion);
CoreReflections.field$BlockStateBase$isRedstoneConductor.set(nmsState, settings.isRedstoneConductor().asBoolean() ? ALWAYS_TRUE : ALWAYS_FALSE);
CoreReflections.field$BlockStateBase$isSuffocating.set(nmsState, settings.isSuffocating().asBoolean() ? ALWAYS_TRUE : ALWAYS_FALSE);
CoreReflections.field$BlockStateBase$isViewBlocking.set(nmsState, settings.isViewBlocking() == Tristate.UNDEFINED ? settings.isSuffocating().asBoolean() ? ALWAYS_TRUE : ALWAYS_FALSE : (settings.isViewBlocking().asBoolean() ? ALWAYS_TRUE : ALWAYS_FALSE));
// set parent block properties
Object mcBlock = BlockStateUtils.getBlockOwner(mcBlockState);
// bind shape
Field shapeField = mcBlock.getClass().getField("shapeHolder");
@SuppressWarnings("unchecked")
ObjectHolder<BukkitBlockShape> shapeHolder = (ObjectHolder<BukkitBlockShape>) shapeField.get(mcBlock);
shapeHolder.bindValue(new BukkitBlockShape(state.vanillaBlockState().handle(), Optional.ofNullable(state.settings().supportShapeBlockState()).map(it -> {
CraftEngineNMSBlock nmsBlock = (CraftEngineNMSBlock) BlockStateUtils.getBlockOwner(nmsState);
ObjectHolder<BlockShape> shapeHolder = nmsBlock.getShapeHolder();
shapeHolder.bindValue(new BukkitBlockShape(immutableBlockState.vanillaBlockState().handle(), Optional.ofNullable(immutableBlockState.settings().supportShapeBlockState()).map(it -> {
try {
Object blockState = BlockStateUtils.blockDataToBlockState(Bukkit.createBlockData(it));
if (!BlockStateUtils.isVanillaBlock(blockState)) return null;
if (!BlockStateUtils.isVanillaBlock(blockState)) {
throw new IllegalArgumentException("BlockState is not a Vanilla block");
}
return blockState;
} catch (IllegalArgumentException e) {
CraftEngine.instance().logger().warn("Illegal shape block state: " + it, e);
@@ -152,36 +124,34 @@ public class BukkitCustomBlock extends AbstractCustomBlock {
}
}).orElse(null)));
// bind behavior
Field behaviorField = mcBlock.getClass().getField("behaviorHolder");
@SuppressWarnings("unchecked")
ObjectHolder<BlockBehavior> behaviorHolder = (ObjectHolder<BlockBehavior>) behaviorField.get(mcBlock);
ObjectHolder<BlockBehavior> behaviorHolder = nmsBlock.getBehaviorHolder();
behaviorHolder.bindValue(super.behavior);
// set block side properties
CoreReflections.field$BlockBehaviour$explosionResistance.set(mcBlock, settings.resistance());
CoreReflections.field$BlockBehaviour$soundType.set(mcBlock, SoundUtils.toSoundType(settings.sounds()));
CoreReflections.field$BlockBehaviour$explosionResistance.set(nmsBlock, settings.resistance());
CoreReflections.field$BlockBehaviour$soundType.set(nmsBlock, SoundUtils.toSoundType(settings.sounds()));
// 1.21.2以前要在init cache之前设定 isConditionallyFullOpaque
if (!VersionHelper.isOrAbove1_21_2()) {
boolean isConditionallyFullOpaque = canOcclude & useShapeForLightOcclusion;
CoreReflections.field$BlockStateBase$isConditionallyFullOpaque.set(mcBlockState, isConditionallyFullOpaque);
CoreReflections.field$BlockStateBase$isConditionallyFullOpaque.set(nmsState, isConditionallyFullOpaque);
}
// init cache
CoreReflections.method$BlockStateBase$initCache.invoke(mcBlockState);
CoreReflections.method$BlockStateBase$initCache.invoke(nmsState);
// modify cache
if (VersionHelper.isOrAbove1_21_2()) {
int blockLight = settings.blockLight() != -1 ? settings.blockLight() : CoreReflections.field$BlockStateBase$lightBlock.getInt(state.vanillaBlockState().handle());
int blockLight = settings.blockLight() != -1 ? settings.blockLight() : CoreReflections.field$BlockStateBase$lightBlock.getInt(immutableBlockState.vanillaBlockState().handle());
// set block light
CoreReflections.field$BlockStateBase$lightBlock.set(mcBlockState, blockLight);
CoreReflections.field$BlockStateBase$lightBlock.set(nmsState, blockLight);
// set propagates skylight
if (settings.propagatesSkylightDown() == Tristate.TRUE) {
CoreReflections.field$BlockStateBase$propagatesSkylightDown.set(mcBlockState, true);
CoreReflections.field$BlockStateBase$propagatesSkylightDown.set(nmsState, true);
} else if (settings.propagatesSkylightDown() == Tristate.FALSE) {
CoreReflections.field$BlockStateBase$propagatesSkylightDown.set(mcBlockState, false);
CoreReflections.field$BlockStateBase$propagatesSkylightDown.set(nmsState, false);
} else {
CoreReflections.field$BlockStateBase$propagatesSkylightDown.set(mcBlockState, CoreReflections.field$BlockStateBase$propagatesSkylightDown.getBoolean(state.vanillaBlockState().handle()));
CoreReflections.field$BlockStateBase$propagatesSkylightDown.set(nmsState, CoreReflections.field$BlockStateBase$propagatesSkylightDown.getBoolean(immutableBlockState.vanillaBlockState().handle()));
}
} else {
Object cache = CoreReflections.field$BlockStateBase$cache.get(mcBlockState);
int blockLight = settings.blockLight() != -1 ? settings.blockLight() : CoreReflections.field$BlockStateBase$Cache$lightBlock.getInt(CoreReflections.field$BlockStateBase$cache.get(state.vanillaBlockState().handle()));
Object cache = CoreReflections.field$BlockStateBase$cache.get(nmsState);
int blockLight = settings.blockLight() != -1 ? settings.blockLight() : CoreReflections.field$BlockStateBase$Cache$lightBlock.getInt(CoreReflections.field$BlockStateBase$cache.get(immutableBlockState.vanillaBlockState().handle()));
// set block light
CoreReflections.field$BlockStateBase$Cache$lightBlock.set(cache, blockLight);
// set propagates skylight
@@ -190,19 +160,19 @@ public class BukkitCustomBlock extends AbstractCustomBlock {
} else if (settings.propagatesSkylightDown() == Tristate.FALSE) {
CoreReflections.field$BlockStateBase$Cache$propagatesSkylightDown.set(cache, false);
} else {
CoreReflections.field$BlockStateBase$Cache$propagatesSkylightDown.set(cache, CoreReflections.field$BlockStateBase$Cache$propagatesSkylightDown.getBoolean(CoreReflections.field$BlockStateBase$cache.get(state.vanillaBlockState().handle())));
CoreReflections.field$BlockStateBase$Cache$propagatesSkylightDown.set(cache, CoreReflections.field$BlockStateBase$Cache$propagatesSkylightDown.getBoolean(CoreReflections.field$BlockStateBase$cache.get(immutableBlockState.vanillaBlockState().handle())));
}
}
// set fluid later
if (settings.fluidState()) {
CoreReflections.field$BlockStateBase$fluidState.set(mcBlockState, CoreReflections.method$FlowingFluid$getSource.invoke(MFluids.WATER, false));
CoreReflections.field$BlockStateBase$fluidState.set(nmsState, CoreReflections.method$FlowingFluid$getSource.invoke(MFluids.WATER, false));
} else {
CoreReflections.field$BlockStateBase$fluidState.set(mcBlockState, MFluids.EMPTY$defaultState);
CoreReflections.field$BlockStateBase$fluidState.set(nmsState, MFluids.EMPTY$defaultState);
}
// set random tick later
BlockStateUtils.setIsRandomlyTicking(mcBlockState, settings.isRandomlyTicking());
CoreReflections.field$BlockStateBase$isRandomlyTicking.set(nmsState, settings.isRandomlyTicking());
// bind tags
Object holder = BukkitCraftEngine.instance().blockManager().getMinecraftBlockHolder(state.customBlockState().registryId());
Object holder = BukkitCraftEngine.instance().blockManager().getMinecraftBlockHolder(immutableBlockState.customBlockState().registryId());
Set<Object> tags = new HashSet<>();
for (Key tag : settings.tags()) {
tags.add(CoreReflections.method$TagKey$create.invoke(null, MRegistries.BLOCK, KeyUtils.toResourceLocation(tag)));
@@ -210,9 +180,9 @@ public class BukkitCustomBlock extends AbstractCustomBlock {
CoreReflections.field$Holder$Reference$tags.set(holder, tags);
// set burning properties
if (settings.burnable()) {
CoreReflections.method$FireBlock$setFlammable.invoke(MBlocks.FIRE, mcBlock, settings.burnChance(), settings.fireSpreadChance());
CoreReflections.method$FireBlock$setFlammable.invoke(MBlocks.FIRE, nmsBlock, settings.burnChance(), settings.fireSpreadChance());
}
CoreReflections.field$BlockStateBase$requiresCorrectToolForDrops.set(mcBlockState, settings.requireCorrectTool());
CoreReflections.field$BlockStateBase$requiresCorrectToolForDrops.set(nmsState, settings.requireCorrectTool());
}
} catch (Exception e) {
CraftEngine.instance().logger().warn("Failed to init block settings", e);

View File

@@ -83,7 +83,7 @@ public class FenceGateBlockBehavior extends BukkitBlockBehavior {
public boolean isWall(Object state) {
if (state == null) return false;
return FastNMS.INSTANCE.method$BlockStateBase$isTagKeyBlock(state, MTagKeys.Block$WALLS);
return FastNMS.INSTANCE.method$BlockStateBase$is(state, MTagKeys.Block$WALLS);
}
private Object getBlockState(Object level, BlockPos blockPos) {

View File

@@ -32,7 +32,9 @@ public class GrassBlockBehavior extends BukkitBlockBehavior {
@Override
public boolean isValidBoneMealTarget(Object thisBlock, Object[] args) {
return FastNMS.INSTANCE.method$GrassBlock$isValidBonemealTarget(args[0], args[1], args[2]);
Object above = LocationUtils.above(args[1]);
Object aboveState = FastNMS.INSTANCE.method$BlockGetter$getBlockState(args[0], above);
return FastNMS.INSTANCE.method$BlockStateBase$isAir(aboveState);
}
@Override
@@ -101,7 +103,7 @@ public class GrassBlockBehavior extends BukkitBlockBehavior {
@Override
public void performBoneMeal(Object thisBlock, Object[] args) {
FastNMS.INSTANCE.method$GrassBlock$performBoneMeal(args[0], args[1], args[2], args[3], thisBlock);
// TODO 使用骨粉
}
public static class Factory implements BlockBehaviorFactory {

View File

@@ -128,7 +128,7 @@ public class PressurePlateBlockBehavior extends BukkitBlockBehavior {
case MOBS -> CoreReflections.clazz$LivingEntity;
};
Object box = FastNMS.INSTANCE.method$AABB$move(CoreReflections.instance$BasePressurePlateBlock$TOUCH_AABB, pos);
return FastNMS.INSTANCE.method$BasePressurePlateBlock$getEntityCount(level, box, clazz) > 0 ? 15 : 0;
return FastNMS.INSTANCE.method$EntityGetter$getEntitiesOfClass(level, box, clazz) > 0 ? 15 : 0;
}
private Object setSignalForState(Object state, int strength) {

View File

@@ -171,7 +171,7 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager {
BukkitFurniture furniture = this.furnitureByRealEntityId.remove(id);
if (furniture != null) {
Location location = entity.getLocation();
boolean isPreventing = FastNMS.INSTANCE.isPreventingStatusUpdates(location.getWorld(), location.getBlockX() >> 4, location.getBlockZ() >> 4);
boolean isPreventing = FastNMS.INSTANCE.method$ServerLevel$isPreventingStatusUpdates(FastNMS.INSTANCE.field$CraftWorld$ServerLevel(location.getWorld()), location.getBlockX() >> 4, location.getBlockZ() >> 4);
if (!isPreventing) {
furniture.destroySeats();
}
@@ -202,7 +202,7 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager {
Location location = display.getLocation();
boolean above1_20_1 = VersionHelper.isOrAbove1_20_2();
boolean preventChange = FastNMS.INSTANCE.isPreventingStatusUpdates(location.getWorld(), location.getBlockX() >> 4, location.getBlockZ() >> 4);
boolean preventChange = FastNMS.INSTANCE.method$ServerLevel$isPreventingStatusUpdates(FastNMS.INSTANCE.field$CraftWorld$ServerLevel(location.getWorld()), location.getBlockX() >> 4, location.getBlockZ() >> 4);
if (above1_20_1) {
if (!preventChange) {
BukkitFurniture furniture = addNewFurniture(display, customFurniture);
@@ -243,7 +243,7 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager {
World world = location.getWorld();
int chunkX = location.getBlockX() >> 4;
int chunkZ = location.getBlockZ() >> 4;
if (!FastNMS.INSTANCE.isPreventingStatusUpdates(world, chunkX, chunkZ)) {
if (!FastNMS.INSTANCE.method$ServerLevel$isPreventingStatusUpdates(FastNMS.INSTANCE.field$CraftWorld$ServerLevel(world), chunkX, chunkZ)) {
entity.remove();
return;
}
@@ -381,7 +381,6 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager {
int z = location.getBlockZ();
if (!world.getBlockAt(x, y - 1, z).getType().isSolid()) return false;
if (!world.getBlockAt(x, y, z).isPassable()) return false;
if (isEntityBlocking(location)) return false;
return world.getBlockAt(x, y + 1, z).isPassable();
}
@@ -403,18 +402,4 @@ public class BukkitFurnitureManager extends AbstractFurnitureManager {
}
return null;
}
private boolean isEntityBlocking(Location location) {
World world = location.getWorld();
if (world == null) return true;
try {
Collection<Entity> nearbyEntities = world.getNearbyEntities(location, 0.38, 2, 0.38);
for (Entity bukkitEntity : nearbyEntities) {
if (bukkitEntity instanceof Player) continue;
Object nmsEntity = FastNMS.INSTANCE.method$CraftEntity$getHandle(bukkitEntity);
return FastNMS.INSTANCE.method$Entity$canBeCollidedWith(nmsEntity);
}
} catch (Exception ignored) {}
return false;
}
}

View File

@@ -58,7 +58,7 @@ public class CustomHitBox extends AbstractHitBox {
try {
packets.accept(FastNMS.INSTANCE.constructor$ClientboundAddEntityPacket(
entityId[0], UUID.randomUUID(), position.x() + offset.x, position.y() + offset.y, position.z() - offset.z, 0, position.xRot(),
FastNMS.INSTANCE.toNMSEntityType(this.entityType), 0, CoreReflections.instance$Vec3$Zero, 0
FastNMS.INSTANCE.method$CraftEntityType$toNMSEntityType(this.entityType), 0, CoreReflections.instance$Vec3$Zero, 0
), true);
packets.accept(FastNMS.INSTANCE.constructor$ClientboundSetEntityDataPacket(entityId[0], List.copyOf(this.cachedValues)), true);
if (VersionHelper.isOrAbove1_20_5() && this.scale != 1) {

View File

@@ -122,41 +122,6 @@ public class BukkitProjectileManager implements Listener, ProjectileManager {
});
}
@EventHandler
public void onPlayerConsume(PlayerItemConsumeEvent event) {
ProjectileType type = getCustomProjectileType(event.getItem());
if (type == ProjectileType.TRIDENT) {
event.setCancelled(true);
}
}
@EventHandler
public void onPlayerStopUsingItem(PlayerStopUsingItemEvent event) {
ItemStack item = event.getItem();
ProjectileType type = getCustomProjectileType(item);
if (type == null) return;
int ticksHeldFor = event.getTicksHeldFor();
Player player = event.getPlayer();
if (type == ProjectileType.TRIDENT) {
if (ticksHeldFor < 10) return;
Object nmsItemStack = FastNMS.INSTANCE.field$CraftItemStack$handle(item);
Object nmsServerLevel = FastNMS.INSTANCE.field$CraftWorld$ServerLevel(player.getWorld());
Object nmsEntity = FastNMS.INSTANCE.method$CraftEntity$getHandle(player);
TridentRelease.releaseUsing(nmsItemStack, nmsServerLevel, nmsEntity);
}
}
@Nullable
private ProjectileType getCustomProjectileType(ItemStack item) {
Item<ItemStack> wrapped = BukkitItemManager.instance().wrap(item);
Optional<CustomItem<ItemStack>> optionalCustomItem = wrapped.getCustomItem();
if (optionalCustomItem.isEmpty()) return null;
CustomItem<ItemStack> customItem = optionalCustomItem.get();
ProjectileMeta meta = customItem.settings().projectileMeta();
if (meta == null) return null;
return meta.type();
}
public class ProjectileInjectTask implements Runnable {
private final Projectile projectile;
private final SchedulerTask task;

View File

@@ -1,514 +0,0 @@
package net.momirealms.craftengine.bukkit.entity.projectile;
import com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent;
import net.momirealms.craftengine.bukkit.nms.FastNMS;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MSoundEvents;
import net.momirealms.craftengine.core.util.MCUtils;
import net.momirealms.craftengine.core.util.VersionHelper;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
@SuppressWarnings("all")
public class TridentRelease {
private TridentRelease() {}
public static boolean releaseUsing(Object stack, Object level, Object entity) {
if (VersionHelper.isOrAbove1_21_2()) {
return releaseUsing_1_21_2(stack, level, entity);
} else if (VersionHelper.isOrAbove1_21()) {
return releaseUsing_1_21(stack, level, entity);
} else if (VersionHelper.isOrAbove1_20_5()) {
return releaseUsing_1_20_5(stack, level, entity);
} else if (VersionHelper.isOrAbove1_20_3()) {
return releaseUsing_1_20_3(stack, level, entity);
} else if (VersionHelper.isOrAbove1_20()) {
return releaseUsing_1_20(stack, level, entity);
}
return false;
}
private static boolean releaseUsing_1_21_2(Object stack, Object level, Object entity) {
Object copyStack = FastNMS.INSTANCE.method$ItemStack$copyWithCount(stack, 1);
if (FastNMS.INSTANCE.method$ItemStack$isEmpty(copyStack)) return false;
float spinStrength = FastNMS.INSTANCE.method$EnchantmentHelper$getTridentSpinAttackStrength(stack, entity);
if ((spinStrength > 0.0F && !FastNMS.INSTANCE.method$Entity$isInWaterOrRain(entity)) || FastNMS.INSTANCE.method$ItemStack$nextDamageWillBreak(stack)) {
return false;
}
FastNMS.INSTANCE.method$ItemStack$setDamageValue(copyStack, FastNMS.INSTANCE.method$ItemStack$getDamageValue(stack) + 1);
Object sound = FastNMS.INSTANCE.method$EnchantmentHelper$pickHighestLevel(stack);
if (spinStrength == 0.0F) {
Object projectile = FastNMS.INSTANCE.method$Projectile$ThrownTrident$spawnProjectileFromRotationDelayed(
level,
copyStack,
entity,
0.0F,
2.5F,
1.0F
);
PlayerLaunchProjectileEvent event = new PlayerLaunchProjectileEvent(
(Player) FastNMS.INSTANCE.method$Entity$getBukkitEntity(entity),
FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(stack),
(Projectile) FastNMS.INSTANCE.method$Entity$getBukkitEntity(FastNMS.INSTANCE.method$Projectile$Delayed$projectile(projectile))
);
if (!event.callEvent() || !FastNMS.INSTANCE.method$Projectile$Delayed$attemptSpawn(projectile)) {
FastNMS.INSTANCE.method$AbstractContainerMenu$sendAllDataToRemote(FastNMS.INSTANCE.field$Player$containerMenu(entity));
return false;
}
Object trident = FastNMS.INSTANCE.method$Projectile$Delayed$projectile(projectile);
if (event.shouldConsume()) {
FastNMS.INSTANCE.method$ItemStack$hurtWithoutBreaking(stack, 1, entity);
FastNMS.INSTANCE.method$ItemStack$consume(stack, 1, entity);
}
FastNMS.INSTANCE.field$AbstractArrow$pickupItemStack(trident, copyStack);
if (FastNMS.INSTANCE.method$Player$hasInfiniteMaterials(entity)) {
FastNMS.INSTANCE.field$AbstractArrow$pickup(trident, CoreReflections.instance$AbstractArrow$Pickup$CREATIVE_ONLY);
}
FastNMS.INSTANCE.method$Level$playSound(
level,
null,
trident,
FastNMS.INSTANCE.method$Holder$value(sound),
CoreReflections.instance$SoundSource$PLAYERS,
1.0F, 1.0F
);
return true;
}
float yaw = FastNMS.INSTANCE.method$Entity$getYRot(entity);
float pitch = FastNMS.INSTANCE.method$Entity$getXRot(entity);
float x = -MCUtils.sin(yaw * MCUtils.DEG_TO_RAD) * MCUtils.cos(pitch * MCUtils.DEG_TO_RAD);
float y = -MCUtils.sin(pitch * MCUtils.DEG_TO_RAD);
float z = MCUtils.cos(yaw * MCUtils.DEG_TO_RAD) * MCUtils.cos(pitch * MCUtils.DEG_TO_RAD);
float length = MCUtils.sqrt(x * x + y * y + z * z);
x = x / length * spinStrength;
y = y / length * spinStrength;
z = z / length * spinStrength;
FastNMS.INSTANCE.method$CraftEventFactory$callPlayerRiptideEvent(entity, stack, x, y, z);
FastNMS.INSTANCE.method$Entity$push(entity, x, y, z);
FastNMS.INSTANCE.field$Entity$hurtMarked(entity, true);
FastNMS.INSTANCE.method$ItemStack$setDamageValue(stack, FastNMS.INSTANCE.method$ItemStack$getDamageValue(stack) + 1);
FastNMS.INSTANCE.method$Player$startAutoSpinAttack(entity, 20, 8.0F, stack);
if (FastNMS.INSTANCE.method$Entity$onGround(entity)) {
FastNMS.INSTANCE.method$Entity$move(entity, CoreReflections.instance$MoverType$SELF, FastNMS.INSTANCE.constructor$Vec3(0.0D, 1.1999999D, 0.0D));
}
FastNMS.INSTANCE.method$Level$playSound(
level,
null,
entity,
FastNMS.INSTANCE.method$Holder$value(sound),
CoreReflections.instance$SoundSource$PLAYERS,
1.0F, 1.0F
);
return true;
}
private static boolean releaseUsing_1_21(Object stack, Object level, Object entity) {
Object copyStack = FastNMS.INSTANCE.method$ItemStack$copyWithCount(stack, 1);
if (FastNMS.INSTANCE.method$ItemStack$isEmpty(copyStack)) return false;
float spinStrength = FastNMS.INSTANCE.method$EnchantmentHelper$getTridentSpinAttackStrength(stack, entity);
if ((spinStrength > 0.0F && !FastNMS.INSTANCE.method$Entity$isInWaterOrRain(entity)) || FastNMS.INSTANCE.method$ItemStack$nextDamageWillBreak(stack)) {
return false;
}
FastNMS.INSTANCE.method$ItemStack$setDamageValue(copyStack, FastNMS.INSTANCE.method$ItemStack$getDamageValue(stack) + 1);
Object sound = FastNMS.INSTANCE.method$EnchantmentHelper$pickHighestLevel(stack);
if (spinStrength == 0.0F) {
Object entitythrowntrident = FastNMS.INSTANCE.constructor$ThrownTrident(level, entity, stack);
FastNMS.INSTANCE.method$ThrownTrident$shootFromRotation(
entitythrowntrident,
entity,
FastNMS.INSTANCE.method$Entity$getXRot(entity),
FastNMS.INSTANCE.method$Entity$getYRot(entity),
0.0F, 2.5F, 1.0F
);
if (FastNMS.INSTANCE.method$Player$hasInfiniteMaterials(entity)) {
FastNMS.INSTANCE.field$AbstractArrow$pickup(entitythrowntrident, CoreReflections.instance$AbstractArrow$Pickup$CREATIVE_ONLY);
}
PlayerLaunchProjectileEvent event = new PlayerLaunchProjectileEvent(
(Player) FastNMS.INSTANCE.method$Entity$getBukkitEntity(entity),
FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(stack),
(Projectile) FastNMS.INSTANCE.method$Entity$getBukkitEntity(entitythrowntrident)
);
if (!event.callEvent() || !FastNMS.INSTANCE.method$LevelWriter$addFreshEntity(level, entitythrowntrident)) {
Entity bukkitEntity = FastNMS.INSTANCE.method$Entity$getBukkitEntity(entity);
if (bukkitEntity instanceof Player player) {
player.updateInventory();
}
return false;
}
if (event.shouldConsume()) {
FastNMS.INSTANCE.method$ItemStack$hurtAndBreak(
stack, 1, entity,
FastNMS.INSTANCE.method$LivingEntity$getSlotForHand(FastNMS.INSTANCE.method$LivingEntity$getUsedItemHand(entity))
);
}
FastNMS.INSTANCE.field$AbstractArrow$pickupItemStack(entitythrowntrident, copyStack);
FastNMS.INSTANCE.method$Level$playSound(
level,
null,
entitythrowntrident,
FastNMS.INSTANCE.method$Holder$value(sound),
CoreReflections.instance$SoundSource$PLAYERS,
1.0F, 1.0F
);
if (event.shouldConsume() && !FastNMS.INSTANCE.method$Player$hasInfiniteMaterials(entity)) {
FastNMS.INSTANCE.method$Inventory$removeItem(FastNMS.INSTANCE.method$Player$getInventory(entity), stack);
}
return true;
}
float yaw = FastNMS.INSTANCE.method$Entity$getYRot(entity);
float pitch = FastNMS.INSTANCE.method$Entity$getXRot(entity);
float x = -MCUtils.sin(yaw * MCUtils.DEG_TO_RAD) * MCUtils.cos(pitch * MCUtils.DEG_TO_RAD);
float y = -MCUtils.sin(pitch * MCUtils.DEG_TO_RAD);
float z = MCUtils.cos(yaw * MCUtils.DEG_TO_RAD) * MCUtils.cos(pitch * MCUtils.DEG_TO_RAD);
float length = MCUtils.sqrt(x * x + y * y + z * z);
x = x / length * spinStrength;
y = y / length * spinStrength;
z = z / length * spinStrength;
FastNMS.INSTANCE.method$CraftEventFactory$callPlayerRiptideEvent(entity, stack, x, y, z);
FastNMS.INSTANCE.method$Entity$push(entity, x, y, z);
FastNMS.INSTANCE.field$Entity$hurtMarked(entity, true);
FastNMS.INSTANCE.method$ItemStack$setDamageValue(stack, FastNMS.INSTANCE.method$ItemStack$getDamageValue(stack) + 1);
FastNMS.INSTANCE.method$Player$startAutoSpinAttack(entity, 20, 8.0F, stack);
if (FastNMS.INSTANCE.method$Entity$onGround(entity)) {
FastNMS.INSTANCE.method$Entity$move(entity, CoreReflections.instance$MoverType$SELF, FastNMS.INSTANCE.constructor$Vec3(0.0D, 1.1999999D, 0.0D));
}
FastNMS.INSTANCE.method$Level$playSound(
level,
null,
entity,
FastNMS.INSTANCE.method$Holder$value(sound),
CoreReflections.instance$SoundSource$PLAYERS,
1.0F, 1.0F
);
return true;
}
private static boolean releaseUsing_1_20_5(Object stack, Object level, Object entity) {
Object copyStack = FastNMS.INSTANCE.method$ItemStack$copyWithCount(stack, 1);
if (FastNMS.INSTANCE.method$ItemStack$isEmpty(copyStack)) return false;
float spinStrength = FastNMS.INSTANCE.method$EnchantmentHelper$getTridentSpinAttackStrength(stack, entity);
if ((spinStrength > 0.0F && !FastNMS.INSTANCE.method$Entity$isInWaterOrRain(entity)) || FastNMS.INSTANCE.method$ItemStack$nextDamageWillBreak(stack)) {
return false;
}
FastNMS.INSTANCE.method$ItemStack$setDamageValue(copyStack, FastNMS.INSTANCE.method$ItemStack$getDamageValue(stack) + 1);
if (spinStrength == 0.0F) {
Object entitythrowntrident = FastNMS.INSTANCE.constructor$ThrownTrident(level, entity, stack);
FastNMS.INSTANCE.method$ThrownTrident$shootFromRotation(
entitythrowntrident,
entity,
FastNMS.INSTANCE.method$Entity$getXRot(entity),
FastNMS.INSTANCE.method$Entity$getYRot(entity),
0.0F, 2.5F, 1.0F
);
if (FastNMS.INSTANCE.method$Player$hasInfiniteMaterials(entity)) {
FastNMS.INSTANCE.field$AbstractArrow$pickup(entitythrowntrident, CoreReflections.instance$AbstractArrow$Pickup$CREATIVE_ONLY);
}
PlayerLaunchProjectileEvent event = new PlayerLaunchProjectileEvent(
(Player) FastNMS.INSTANCE.method$Entity$getBukkitEntity(entity),
FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(stack),
(Projectile) FastNMS.INSTANCE.method$Entity$getBukkitEntity(entitythrowntrident)
);
if (!event.callEvent() || !FastNMS.INSTANCE.method$LevelWriter$addFreshEntity(level, entitythrowntrident)) {
Entity bukkitEntity = FastNMS.INSTANCE.method$Entity$getBukkitEntity(entity);
if (bukkitEntity instanceof Player player) {
player.updateInventory();
}
return false;
}
if (event.shouldConsume()) {
FastNMS.INSTANCE.method$ItemStack$hurtAndBreak(
stack, 1, entity,
FastNMS.INSTANCE.method$LivingEntity$getSlotForHand(FastNMS.INSTANCE.method$LivingEntity$getUsedItemHand(entity))
);
}
FastNMS.INSTANCE.field$AbstractArrow$pickupItemStack(entitythrowntrident, copyStack);
FastNMS.INSTANCE.method$Level$playSound(
level,
null,
entitythrowntrident,
MSoundEvents.TRIDENT_THROW,
CoreReflections.instance$SoundSource$PLAYERS,
1.0F, 1.0F
);
if (event.shouldConsume() && !FastNMS.INSTANCE.method$Player$hasInfiniteMaterials(entity)) {
FastNMS.INSTANCE.method$Inventory$removeItem(FastNMS.INSTANCE.method$Player$getInventory(entity), stack);
}
return true;
}
float yaw = FastNMS.INSTANCE.method$Entity$getYRot(entity);
float pitch = FastNMS.INSTANCE.method$Entity$getXRot(entity);
float x = -MCUtils.sin(yaw * MCUtils.DEG_TO_RAD) * MCUtils.cos(pitch * MCUtils.DEG_TO_RAD);
float y = -MCUtils.sin(pitch * MCUtils.DEG_TO_RAD);
float z = MCUtils.cos(yaw * MCUtils.DEG_TO_RAD) * MCUtils.cos(pitch * MCUtils.DEG_TO_RAD);
float length = MCUtils.sqrt(x * x + y * y + z * z);
x = x / length * spinStrength;
y = y / length * spinStrength;
z = z / length * spinStrength;
FastNMS.INSTANCE.method$CraftEventFactory$callPlayerRiptideEvent(entity, stack, x, y, z);
FastNMS.INSTANCE.method$Entity$push(entity, x, y, z);
FastNMS.INSTANCE.field$Entity$hurtMarked(entity, true);
FastNMS.INSTANCE.method$ItemStack$setDamageValue(stack, FastNMS.INSTANCE.method$ItemStack$getDamageValue(stack) + 1);
FastNMS.INSTANCE.method$Player$startAutoSpinAttack(entity, 20, -1.0F, null);
if (FastNMS.INSTANCE.method$Entity$onGround(entity)) {
FastNMS.INSTANCE.method$Entity$move(entity, CoreReflections.instance$MoverType$SELF, FastNMS.INSTANCE.constructor$Vec3(0.0D, 1.1999999D, 0.0D));
}
Object soundeffect;
if (spinStrength >= 3) {
soundeffect = MSoundEvents.TRIDENT_RIPTIDE_3;
} else if (spinStrength == 2) {
soundeffect = MSoundEvents.TRIDENT_RIPTIDE_2;
} else {
soundeffect = MSoundEvents.TRIDENT_RIPTIDE_1;
}
FastNMS.INSTANCE.method$Level$playSound(
level,
null,
entity,
soundeffect,
CoreReflections.instance$SoundSource$PLAYERS,
1.0F, 1.0F
);
return true;
}
private static boolean releaseUsing_1_20_3(Object stack, Object level, Object entity) {
Object copyStack = FastNMS.INSTANCE.method$ItemStack$copyWithCount(stack, 1);
if (FastNMS.INSTANCE.method$ItemStack$isEmpty(copyStack)) return false;
float spinStrength = FastNMS.INSTANCE.method$EnchantmentHelper$getTridentSpinAttackStrength(stack, entity);
if ((spinStrength > 0.0F && !FastNMS.INSTANCE.method$Entity$isInWaterOrRain(entity)) || FastNMS.INSTANCE.method$ItemStack$nextDamageWillBreak(stack)) {
return false;
}
FastNMS.INSTANCE.method$ItemStack$setDamageValue(copyStack, FastNMS.INSTANCE.method$ItemStack$getDamageValue(stack) + 1);
if (spinStrength == 0.0F) {
Object entitythrowntrident = FastNMS.INSTANCE.constructor$ThrownTrident(level, entity, stack);
FastNMS.INSTANCE.method$ThrownTrident$shootFromRotation(
entitythrowntrident,
entity,
FastNMS.INSTANCE.method$Entity$getXRot(entity),
FastNMS.INSTANCE.method$Entity$getYRot(entity),
0.0F, 2.5F, 1.0F
);
if (FastNMS.INSTANCE.field$Abilities$instabuild(FastNMS.INSTANCE.method$Player$getAbilities(entity))) {
FastNMS.INSTANCE.field$AbstractArrow$pickup(entitythrowntrident, CoreReflections.instance$AbstractArrow$Pickup$CREATIVE_ONLY);
}
PlayerLaunchProjectileEvent event = new PlayerLaunchProjectileEvent(
(Player) FastNMS.INSTANCE.method$Entity$getBukkitEntity(entity),
FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(stack),
(Projectile) FastNMS.INSTANCE.method$Entity$getBukkitEntity(entitythrowntrident)
);
if (!event.callEvent() || !FastNMS.INSTANCE.method$LevelWriter$addFreshEntity(level, entitythrowntrident)) {
Entity bukkitEntity = FastNMS.INSTANCE.method$Entity$getBukkitEntity(entity);
if (bukkitEntity instanceof Player player) {
player.updateInventory();
}
return false;
}
if (event.shouldConsume()) {
FastNMS.INSTANCE.method$ItemStack$hurtAndBreak(
stack, 1, entity,
(player1) -> FastNMS.INSTANCE.method$LivingEntity$broadcastBreakEvent(player1, FastNMS.INSTANCE.method$LivingEntity$getUsedItemHand(entity))
);
}
FastNMS.INSTANCE.field$AbstractArrow$pickupItemStack(entitythrowntrident, copyStack);
FastNMS.INSTANCE.method$Level$playSound(
level,
null,
entitythrowntrident,
MSoundEvents.TRIDENT_THROW,
CoreReflections.instance$SoundSource$PLAYERS,
1.0F, 1.0F
);
if (event.shouldConsume() && !FastNMS.INSTANCE.field$Abilities$instabuild(FastNMS.INSTANCE.method$Player$getAbilities(entity))) {
FastNMS.INSTANCE.method$Inventory$removeItem(FastNMS.INSTANCE.method$Player$getInventory(entity), stack);
}
return true;
}
float yaw = FastNMS.INSTANCE.method$Entity$getYRot(entity);
float pitch = FastNMS.INSTANCE.method$Entity$getXRot(entity);
float x = -MCUtils.sin(yaw * MCUtils.DEG_TO_RAD) * MCUtils.cos(pitch * MCUtils.DEG_TO_RAD);
float y = -MCUtils.sin(pitch * MCUtils.DEG_TO_RAD);
float z = MCUtils.cos(yaw * MCUtils.DEG_TO_RAD) * MCUtils.cos(pitch * MCUtils.DEG_TO_RAD);
float length = MCUtils.sqrt(x * x + y * y + z * z);
x = x / length * spinStrength;
y = y / length * spinStrength;
z = z / length * spinStrength;
FastNMS.INSTANCE.method$CraftEventFactory$callPlayerRiptideEvent(entity, stack, x, y, z);
FastNMS.INSTANCE.method$Entity$push(entity, x, y, z);
FastNMS.INSTANCE.field$Entity$hurtMarked(entity, true);
FastNMS.INSTANCE.method$ItemStack$setDamageValue(stack, FastNMS.INSTANCE.method$ItemStack$getDamageValue(stack) + 1);
FastNMS.INSTANCE.method$Player$startAutoSpinAttack(entity, 20, -1.0F, null);
if (FastNMS.INSTANCE.method$Entity$onGround(entity)) {
FastNMS.INSTANCE.method$Entity$move(entity, CoreReflections.instance$MoverType$SELF, FastNMS.INSTANCE.constructor$Vec3(0.0D, 1.1999999D, 0.0D));
}
Object soundeffect;
if (spinStrength >= 3) {
soundeffect = MSoundEvents.TRIDENT_RIPTIDE_3;
} else if (spinStrength == 2) {
soundeffect = MSoundEvents.TRIDENT_RIPTIDE_2;
} else {
soundeffect = MSoundEvents.TRIDENT_RIPTIDE_1;
}
FastNMS.INSTANCE.method$Level$playSound(
level,
null,
entity,
soundeffect,
CoreReflections.instance$SoundSource$PLAYERS,
1.0F, 1.0F
);
return true;
}
private static boolean releaseUsing_1_20(Object stack, Object level, Object entity) {
Object copyStack = FastNMS.INSTANCE.method$ItemStack$copyWithCount(stack, 1);
if (FastNMS.INSTANCE.method$ItemStack$isEmpty(copyStack)) return false;
float spinStrength = FastNMS.INSTANCE.method$EnchantmentHelper$getTridentSpinAttackStrength(stack, entity);
if ((spinStrength > 0.0F && !FastNMS.INSTANCE.method$Entity$isInWaterOrRain(entity)) || FastNMS.INSTANCE.method$ItemStack$nextDamageWillBreak(stack)) {
return false;
}
FastNMS.INSTANCE.method$ItemStack$setDamageValue(copyStack, FastNMS.INSTANCE.method$ItemStack$getDamageValue(stack) + 1);
if (spinStrength == 0.0F) {
Object entitythrowntrident = FastNMS.INSTANCE.constructor$ThrownTrident(level, entity, stack);
FastNMS.INSTANCE.method$ThrownTrident$shootFromRotation(
entitythrowntrident,
entity,
FastNMS.INSTANCE.method$Entity$getXRot(entity),
FastNMS.INSTANCE.method$Entity$getYRot(entity),
0.0F, 2.5F, 1.0F
);
if (FastNMS.INSTANCE.field$Abilities$instabuild(FastNMS.INSTANCE.method$Player$getAbilities(entity))) {
FastNMS.INSTANCE.field$AbstractArrow$pickup(entitythrowntrident, CoreReflections.instance$AbstractArrow$Pickup$CREATIVE_ONLY);
}
PlayerLaunchProjectileEvent event = new PlayerLaunchProjectileEvent(
(Player) FastNMS.INSTANCE.method$Entity$getBukkitEntity(entity),
FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(stack),
(Projectile) FastNMS.INSTANCE.method$Entity$getBukkitEntity(entitythrowntrident)
);
if (!event.callEvent() || !FastNMS.INSTANCE.method$LevelWriter$addFreshEntity(level, entitythrowntrident)) {
Entity bukkitEntity = FastNMS.INSTANCE.method$Entity$getBukkitEntity(entity);
if (bukkitEntity instanceof Player player) {
player.updateInventory();
}
return false;
}
if (event.shouldConsume()) {
FastNMS.INSTANCE.method$ItemStack$hurtAndBreak(
stack, 1, entity,
(player1) -> FastNMS.INSTANCE.method$LivingEntity$broadcastBreakEvent(player1, FastNMS.INSTANCE.method$LivingEntity$getUsedItemHand(entity))
);
}
FastNMS.INSTANCE.field$ThrownTrident$tridentItem(entitythrowntrident, copyStack);
FastNMS.INSTANCE.method$Level$playSound(
level,
null,
entitythrowntrident,
MSoundEvents.TRIDENT_THROW,
CoreReflections.instance$SoundSource$PLAYERS,
1.0F, 1.0F
);
if (event.shouldConsume() && !FastNMS.INSTANCE.field$Abilities$instabuild(FastNMS.INSTANCE.method$Player$getAbilities(entity))) {
FastNMS.INSTANCE.method$Inventory$removeItem(FastNMS.INSTANCE.method$Player$getInventory(entity), stack);
}
return true;
}
float yaw = FastNMS.INSTANCE.method$Entity$getYRot(entity);
float pitch = FastNMS.INSTANCE.method$Entity$getXRot(entity);
float x = -MCUtils.sin(yaw * MCUtils.DEG_TO_RAD) * MCUtils.cos(pitch * MCUtils.DEG_TO_RAD);
float y = -MCUtils.sin(pitch * MCUtils.DEG_TO_RAD);
float z = MCUtils.cos(yaw * MCUtils.DEG_TO_RAD) * MCUtils.cos(pitch * MCUtils.DEG_TO_RAD);
float length = MCUtils.sqrt(x * x + y * y + z * z);
x = x / length * spinStrength;
y = y / length * spinStrength;
z = z / length * spinStrength;
FastNMS.INSTANCE.method$Entity$push(entity, x, y, z);
FastNMS.INSTANCE.field$Entity$hurtMarked(entity, true);
FastNMS.INSTANCE.method$ItemStack$setDamageValue(stack, FastNMS.INSTANCE.method$ItemStack$getDamageValue(stack) + 1);
FastNMS.INSTANCE.method$Player$startAutoSpinAttack(entity, 20, -1.0F, null);
if (FastNMS.INSTANCE.method$Entity$onGround(entity)) {
FastNMS.INSTANCE.method$Entity$move(entity, CoreReflections.instance$MoverType$SELF, FastNMS.INSTANCE.constructor$Vec3(0.0D, 1.1999999D, 0.0D));
}
Object soundeffect;
if (spinStrength >= 3) {
soundeffect = MSoundEvents.TRIDENT_RIPTIDE_3;
} else if (spinStrength == 2) {
soundeffect = MSoundEvents.TRIDENT_RIPTIDE_2;
} else {
soundeffect = MSoundEvents.TRIDENT_RIPTIDE_1;
}
FastNMS.INSTANCE.method$Level$playSound(
level,
null,
entity,
soundeffect,
CoreReflections.instance$SoundSource$PLAYERS,
1.0F, 1.0F
);
return true;
}
}

View File

@@ -215,14 +215,14 @@ public class BukkitItemManager extends AbstractItemManager<ItemStack> {
@SuppressWarnings("unchecked")
private void registerAllVanillaItems() {
try {
for (NamespacedKey item : FastNMS.INSTANCE.getAllVanillaItems()) {
if (item.getNamespace().equals("minecraft")) {
Key id = KeyUtils.namespacedKey2Key(item);
VANILLA_ITEMS.add(id);
Holder.Reference<Key> holder = BuiltInRegistries.OPTIMIZED_ITEM_ID.get(id)
for (Object item : (Iterable<?>) MBuiltInRegistries.ITEM) {
Object resourceLocation = FastNMS.INSTANCE.method$Registry$getKey(MBuiltInRegistries.ITEM, item);
Key itemKey = KeyUtils.resourceLocationToKey(resourceLocation);
if (itemKey.namespace().equals("minecraft")) {
VANILLA_ITEMS.add(itemKey);
Holder.Reference<Key> holder = BuiltInRegistries.OPTIMIZED_ITEM_ID.get(itemKey)
.orElseGet(() -> ((WritableRegistry<Key>) BuiltInRegistries.OPTIMIZED_ITEM_ID)
.register(new ResourceKey<>(BuiltInRegistries.OPTIMIZED_ITEM_ID.key().location(), id), id));
Object resourceLocation = KeyUtils.toResourceLocation(id.namespace(), id.value());
.register(new ResourceKey<>(BuiltInRegistries.OPTIMIZED_ITEM_ID.key().location(), itemKey), itemKey));
Object mcHolder = ((Optional<Object>) CoreReflections.method$Registry$getHolder1.invoke(MBuiltInRegistries.ITEM, CoreReflections.method$ResourceKey$create.invoke(null, MRegistries.ITEM, resourceLocation))).get();
Set<Object> tags = (Set<Object>) CoreReflections.field$Holder$Reference$tags.get(mcHolder);
for (Object tag : tags) {

View File

@@ -6,7 +6,10 @@ import com.mojang.serialization.DataResult;
import com.mojang.serialization.DynamicOps;
import net.momirealms.craftengine.bukkit.nms.FastNMS;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MBuiltInRegistries;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MRegistryOps;
import net.momirealms.craftengine.bukkit.util.ItemUtils;
import net.momirealms.craftengine.bukkit.util.KeyUtils;
import net.momirealms.craftengine.core.item.ItemWrapper;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.sparrow.nbt.Tag;
@@ -19,22 +22,26 @@ public class ComponentItemWrapper implements ItemWrapper<ItemStack> {
private final Object handle;
public ComponentItemWrapper(final ItemStack item) {
this.item = FastNMS.INSTANCE.ensureCraftItemStack(item);
this.item = ItemUtils.ensureCraftItemStack(item);
this.handle = FastNMS.INSTANCE.field$CraftItemStack$handle(this.item);
}
public ComponentItemWrapper(final ItemStack item, int count) {
this.item = FastNMS.INSTANCE.ensureCraftItemStack(item);
this.item = ItemUtils.ensureCraftItemStack(item);
this.item.setAmount(count);
this.handle = FastNMS.INSTANCE.field$CraftItemStack$handle(this.item);
}
public void removeComponent(Object type) {
FastNMS.INSTANCE.removeComponent(this.getLiteralObject(), ensureDataComponentType(type));
FastNMS.INSTANCE.method$ItemStack$removeComponent(this.getLiteralObject(), ensureDataComponentType(type));
}
public void resetComponent(Object type) {
FastNMS.INSTANCE.resetComponent(this.getLiteralObject(), ensureDataComponentType(type));
Object item = FastNMS.INSTANCE.method$ItemStack$getItem(this.getLiteralObject());
Object componentMap = FastNMS.INSTANCE.method$Item$components(item);
Object componentType = ensureDataComponentType(type);
Object defaultComponent = FastNMS.INSTANCE.method$DataComponentMap$get(componentMap, componentType);
FastNMS.INSTANCE.method$ItemStack$setComponent(this.getLiteralObject(), componentType, defaultComponent);
}
public void setComponent(Object type, final Object value) {
@@ -50,7 +57,7 @@ public class ComponentItemWrapper implements ItemWrapper<ItemStack> {
}
public Object getComponentExact(Object type) {
return FastNMS.INSTANCE.getComponent(getLiteralObject(), ensureDataComponentType(type));
return FastNMS.INSTANCE.method$ItemStack$getComponent(getLiteralObject(), ensureDataComponentType(type));
}
public <T> Optional<T> getJavaComponent(Object type) {
@@ -74,7 +81,7 @@ public class ComponentItemWrapper implements ItemWrapper<ItemStack> {
Object componentType = ensureDataComponentType(type);
Codec codec = FastNMS.INSTANCE.method$DataComponentType$codec(componentType);
try {
Object componentData = FastNMS.INSTANCE.getComponent(getLiteralObject(), componentType);
Object componentData = FastNMS.INSTANCE.method$ItemStack$getComponent(getLiteralObject(), componentType);
if (componentData == null) return Optional.empty();
DataResult<Object> result = codec.encodeStart(ops, componentData);
return (Optional<T>) result.result();
@@ -84,11 +91,11 @@ public class ComponentItemWrapper implements ItemWrapper<ItemStack> {
}
public boolean hasComponent(Object type) {
return FastNMS.INSTANCE.hasComponent(getLiteralObject(), ensureDataComponentType(type));
return FastNMS.INSTANCE.method$ItemStack$hasComponent(getLiteralObject(), ensureDataComponentType(type));
}
public void setComponentExact(Object type, final Object value) {
FastNMS.INSTANCE.setComponent(this.getLiteralObject(), ensureDataComponentType(type), value);
FastNMS.INSTANCE.method$ItemStack$setComponent(this.getLiteralObject(), ensureDataComponentType(type), value);
}
public void setJavaComponent(Object type, Object value) {
@@ -120,7 +127,7 @@ public class ComponentItemWrapper implements ItemWrapper<ItemStack> {
if (result.isError()) {
throw new IllegalArgumentException(result.toString());
}
result.result().ifPresent(it -> FastNMS.INSTANCE.setComponent(this.getLiteralObject(), componentType, it));
result.result().ifPresent(it -> FastNMS.INSTANCE.method$ItemStack$setComponent(this.getLiteralObject(), componentType, it));
} catch (Throwable t) {
throw new RuntimeException("Cannot parse component " + type.toString(), t);
}
@@ -129,7 +136,7 @@ public class ComponentItemWrapper implements ItemWrapper<ItemStack> {
private Object ensureDataComponentType(Object type) {
if (!CoreReflections.clazz$DataComponentType.isInstance(type)) {
Key key = Key.of(type.toString());
return FastNMS.INSTANCE.getComponentType(key.namespace(), key.value());
return FastNMS.INSTANCE.method$Registry$getValue(MBuiltInRegistries.DATA_COMPONENT_TYPE, KeyUtils.toResourceLocation(key));
}
return type;
}

View File

@@ -1,6 +1,8 @@
package net.momirealms.craftengine.bukkit.item;
import net.momirealms.craftengine.bukkit.nms.FastNMS;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MBuiltInRegistries;
import net.momirealms.craftengine.bukkit.util.KeyUtils;
import net.momirealms.craftengine.core.item.ComponentKeys;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.VersionHelper;
@@ -32,6 +34,6 @@ public class ComponentTypes {
private static Object getComponentType(Key key) {
if (!VersionHelper.isOrAbove1_20_5()) return null;
return FastNMS.INSTANCE.getComponentType(key.namespace(), key.value());
return FastNMS.INSTANCE.method$Registry$getValue(MBuiltInRegistries.DATA_COMPONENT_TYPE, KeyUtils.toResourceLocation(key));
}
}

View File

@@ -49,7 +49,6 @@ public class BukkitCommandManager extends AbstractCommandManager<CommandSender>
new DebugIsSectionInjectedCommand(this, plugin),
new DebugMigrateTemplatesCommand(this, plugin),
new DebugIsChunkPersistentLoadedCommand(this, plugin),
new DebugEntityId2UUIDCommand(this, plugin),
new TotemAnimationCommand(this, plugin),
new EnableResourceCommand(this, plugin),
new DisableResourceCommand(this, plugin),

View File

@@ -42,7 +42,9 @@ public class BukkitSenderFactory extends SenderFactory<BukkitCraftEngine, Comman
protected void sendMessage(CommandSender sender, Component message) {
// we can safely send async for players and the console - otherwise, send it sync
if (sender instanceof Player player) {
FastNMS.INSTANCE.sendPacket(FastNMS.INSTANCE.field$Player$connection$connection(FastNMS.INSTANCE.method$CraftPlayer$getHandle(player)), FastNMS.INSTANCE.constructor$ClientboundSystemChatPacket(ComponentUtils.adventureToMinecraft(message), false));
FastNMS.INSTANCE.method$Connection$send(
FastNMS.INSTANCE.field$ServerGamePacketListenerImpl$connection(FastNMS.INSTANCE.field$Player$connection(FastNMS.INSTANCE.method$CraftPlayer$getHandle(player))),
FastNMS.INSTANCE.constructor$ClientboundSystemChatPacket(ComponentUtils.adventureToMinecraft(message), false));
} else if (sender instanceof ConsoleCommandSender commandSender) {
commandSender.sendMessage(LegacyComponentSerializer.legacySection().serialize(message));
} else if (sender instanceof RemoteConsoleCommandSender commandSender) {

View File

@@ -1,59 +0,0 @@
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";
}
}

View File

@@ -1,6 +1,7 @@
package net.momirealms.craftengine.bukkit.plugin.command.feature;
import com.saicone.rtag.RtagMirror;
import com.saicone.rtag.item.ItemTagStream;
import com.saicone.rtag.tag.TagCompound;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
@@ -55,7 +56,7 @@ public class DebugItemDataCommand extends BukkitCommandFeature<CommandSender> {
}
private static Map<String, Object> toMap(ItemStack object) {
return TagCompound.getValue(RtagMirror.INSTANCE, FastNMS.INSTANCE.itemStackToCompoundTag(object));
return ItemTagStream.INSTANCE.toMap(object);
}
private List<String> mapToList(Map<String, Object> readableDataMap) {

View File

@@ -59,9 +59,7 @@ public final class BlockGenerator {
.implement(CoreReflections.clazz$BonemealableBlock)
.implement(CoreReflections.clazz$SimpleWaterloggedBlock)
// internal interfaces
.implement(BehaviorHolder.class)
.implement(ShapeHolder.class)
.implement(ChainUpdateBlockIndicator.class)
.implement(CraftEngineNMSBlock.class)
.method(ElementMatchers.named("getBehaviorHolder"))
.intercept(FieldAccessor.ofField("behaviorHolder"))
.method(ElementMatchers.named("getShapeHolder"))

View File

@@ -4,19 +4,26 @@ import com.mojang.serialization.MapCodec;
import it.unimi.dsi.fastutil.objects.Reference2ObjectArrayMap;
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.ClassFileVersion;
import net.bytebuddy.description.modifier.Visibility;
import net.bytebuddy.dynamic.DynamicType;
import net.bytebuddy.dynamic.scaffold.subclass.ConstructorStrategy;
import net.bytebuddy.implementation.FieldAccessor;
import net.bytebuddy.implementation.MethodDelegation;
import net.bytebuddy.implementation.bind.annotation.AllArguments;
import net.bytebuddy.implementation.bind.annotation.RuntimeType;
import net.bytebuddy.implementation.bind.annotation.This;
import net.bytebuddy.matcher.ElementMatchers;
import net.momirealms.craftengine.bukkit.nms.FastNMS;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections;
import net.momirealms.craftengine.core.block.CustomBlockState;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MItems;
import net.momirealms.craftengine.core.block.CustomBlockStateHolder;
import net.momirealms.craftengine.core.block.ImmutableBlockState;
import net.momirealms.craftengine.core.util.ReflectionUtils;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.util.List;
public final class BlockStateGenerator {
private static MethodHandle constructor$CraftEngineBlockState;
@@ -29,7 +36,14 @@ public final class BlockStateGenerator {
DynamicType.Builder<?> stateBuilder = byteBuddy
.subclass(CoreReflections.clazz$BlockState, ConstructorStrategy.Default.IMITATE_SUPER_CLASS_OPENING)
.name(generatedStateClassName)
.implement(CustomBlockState.class);
.defineField("immutableBlockState", ImmutableBlockState.class, Visibility.PUBLIC)
.implement(CustomBlockStateHolder.class)
.method(ElementMatchers.named("customBlockState"))
.intercept(FieldAccessor.ofField("immutableBlockState"))
.method(ElementMatchers.named("setCustomBlockState"))
.intercept(FieldAccessor.ofField("immutableBlockState"))
.method(ElementMatchers.is(CoreReflections.method$BlockStateBase$getDrops))
.intercept(MethodDelegation.to(GetDropsInterceptor.INSTANCE));
Class<?> clazz$CraftEngineBlock = stateBuilder.make().load(BlockStateGenerator.class.getClassLoader()).getLoaded();
constructor$CraftEngineBlockState = MethodHandles.publicLookup().in(clazz$CraftEngineBlock)
.findConstructor(clazz$CraftEngineBlock, MethodType.methodType(void.class, CoreReflections.clazz$Block, Reference2ObjectArrayMap.class, MapCodec.class))
@@ -47,6 +61,18 @@ public final class BlockStateGenerator {
instance$StateDefinition$Factory = ReflectionUtils.getTheOnlyConstructor(clazz$Factory).newInstance();
}
public static class GetDropsInterceptor {
public static final GetDropsInterceptor INSTANCE = new GetDropsInterceptor();
@RuntimeType
public Object intercept(@This Object thisObj, @AllArguments Object[] args) throws Throwable {
ImmutableBlockState state = ((CustomBlockStateHolder) thisObj).customBlockState();
if (state == null) return List.of();
Object builder = args[0];
return List.of(FastNMS.INSTANCE.constructor$ItemStack(MItems.WATER_BUCKET, 1));
}
}
public static class CreateStateInterceptor {
public static final CreateStateInterceptor INSTANCE = new CreateStateInterceptor();

View File

@@ -104,7 +104,7 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
// register packet handlers
this.registerPacketHandlers();
// set up packet senders
this.packetConsumer = FastNMS.INSTANCE::sendPacket;
this.packetConsumer = FastNMS.INSTANCE::method$Connection$send;
this.packetsConsumer = ((connection, packets) -> {
Object bundle = FastNMS.INSTANCE.constructor$ClientboundBundlePacket(packets);
this.packetConsumer.accept(connection, bundle);
@@ -114,7 +114,6 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
Object bundle = FastNMS.INSTANCE.constructor$ClientboundBundlePacket(packets);
this.immediatePacketConsumer.accept(channel, bundle);
};
// todo 可以删除吗
// set up mod channel
this.plugin.javaPlugin().getServer().getMessenger().registerIncomingPluginChannel(this.plugin.javaPlugin(), MOD_CHANNEL, this);
this.plugin.javaPlugin().getServer().getMessenger().registerOutgoingPluginChannel(this.plugin.javaPlugin(), MOD_CHANNEL);
@@ -302,7 +301,13 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
}
public Channel getChannel(Player player) {
return (Channel) FastNMS.INSTANCE.field$Player$connection$connection$channel(FastNMS.INSTANCE.method$CraftPlayer$getHandle(player));
return FastNMS.INSTANCE.field$Connection$channel(
FastNMS.INSTANCE.field$ServerGamePacketListenerImpl$connection(
FastNMS.INSTANCE.field$Player$connection(
FastNMS.INSTANCE.method$CraftPlayer$getHandle(player)
)
)
);
}
@Override

View File

@@ -994,7 +994,7 @@ public class PacketConsumers {
float zDist = buf.readFloat();
float maxSpeed = buf.readFloat();
int count = buf.readInt();
Object option = FastNMS.INSTANCE.method$ParticleTypes$STREAM_CODEC$decode(buf);
Object option = FastNMS.INSTANCE.method$StreamCodec$decode(NetworkReflections.instance$ParticleTypes$STREAM_CODEC, buf);
if (option == null) return;
if (!CoreReflections.clazz$BlockParticleOption.isInstance(option)) return;
Object blockState = FastNMS.INSTANCE.field$BlockParticleOption$blockState(option);
@@ -1016,7 +1016,7 @@ public class PacketConsumers {
buf.writeFloat(zDist);
buf.writeFloat(maxSpeed);
buf.writeInt(count);
FastNMS.INSTANCE.method$ParticleTypes$STREAM_CODEC$encode(buf, remappedOption);
FastNMS.INSTANCE.method$StreamCodec$encode(NetworkReflections.instance$ParticleTypes$STREAM_CODEC, buf, remappedOption);
} catch (Exception e) {
CraftEngine.instance().logger().warn("Failed to handle ClientboundLevelParticlesPacket", e);
}
@@ -1034,7 +1034,7 @@ public class PacketConsumers {
float zDist = buf.readFloat();
float maxSpeed = buf.readFloat();
int count = buf.readInt();
Object option = FastNMS.INSTANCE.method$ParticleTypes$STREAM_CODEC$decode(buf);
Object option = FastNMS.INSTANCE.method$StreamCodec$decode(NetworkReflections.instance$ParticleTypes$STREAM_CODEC, buf);
if (option == null) return;
if (!CoreReflections.clazz$BlockParticleOption.isInstance(option)) return;
Object blockState = FastNMS.INSTANCE.field$BlockParticleOption$blockState(option);
@@ -1055,7 +1055,7 @@ public class PacketConsumers {
buf.writeFloat(zDist);
buf.writeFloat(maxSpeed);
buf.writeInt(count);
FastNMS.INSTANCE.method$ParticleTypes$STREAM_CODEC$encode(buf, remappedOption);
FastNMS.INSTANCE.method$StreamCodec$encode(NetworkReflections.instance$ParticleTypes$STREAM_CODEC, buf, remappedOption);
} catch (Exception e) {
CraftEngine.instance().logger().warn("Failed to handle ClientboundLevelParticlesPacket", e);
}
@@ -1724,7 +1724,7 @@ public class PacketConsumers {
Optional<Object> optionalSound = FastNMS.INSTANCE.method$IdMap$byId(MBuiltInRegistries.SOUND_EVENT, id - 1);
if (optionalSound.isEmpty()) return;
Object soundEvent = optionalSound.get();
Key soundId = Key.of(FastNMS.INSTANCE.method$SoundEvent$location(soundEvent));
Key soundId = KeyUtils.resourceLocationToKey(FastNMS.INSTANCE.method$SoundEvent$location(soundEvent));
int source = buf.readVarInt();
int x = buf.readInt();
int y = buf.readInt();

View File

@@ -147,15 +147,4 @@ public class ProjectilePacketHandler implements EntityPacketHandler {
onGround
);
}
private Object convertCustomProjectileTeleportPacket(Object packet, int entityId) {
float xRot = MCUtils.unpackDegrees(FastNMS.INSTANCE.field$ClientboundMoveEntityPacket$xRot(packet));
float yRot = MCUtils.unpackDegrees(FastNMS.INSTANCE.field$ClientboundMoveEntityPacket$yRot(packet));
boolean onGround = FastNMS.INSTANCE.field$ClientboundMoveEntityPacket$onGround(packet);
return FastNMS.INSTANCE.constructor$ClientboundTeleportEntityPacket(
entityId, this.projectile.projectile().x(), this.projectile.projectile().y(), this.projectile.projectile().z(),
MCUtils.packDegrees(-yRot), MCUtils.packDegrees(MCUtils.clamp(-xRot, -90.0F, 90.0F)),
onGround
);
}
}

View File

@@ -30,9 +30,9 @@ public class PacketIdFinder {
}
}
} else if (VersionHelper.isOrAbove1_20_5()) {
gamePacketIdsByName.putAll(FastNMS.INSTANCE.method$getGamePacketIdsByName());
gamePacketIdsByName.putAll(FastNMS.INSTANCE.gamePacketIdsByName());
} else {
gamePacketIdsByClazz.putAll(FastNMS.INSTANCE.method$getGamePacketIdsByClazz());
gamePacketIdsByClazz.putAll(FastNMS.INSTANCE.gamePacketIdsByClazz());
}
} catch (Exception e) {
CraftEngine.instance().logger().warn("Failed to get packets", e);

View File

@@ -495,6 +495,13 @@ public final class CoreReflections {
}).orElseThrow()
);
public static final Class<?> clazz$ParticleTypes = requireNonNull(
BukkitReflectionUtils.findReobfOrMojmapClass(
"core.particles.Particles",
"core.particles.ParticleTypes"
)
);
public static final Class<?> clazz$MappedRegistry = requireNonNull(
BukkitReflectionUtils.findReobfOrMojmapClass(
"core.RegistryMaterials",
@@ -3527,4 +3534,16 @@ public final class CoreReflections {
}
}
public static final Class<?> clazz$LootParams$Builder = requireNonNull(
BukkitReflectionUtils.findReobfOrMojmapClass(
"world.level.storage.loot.LootParams$a",
"world.level.storage.loot.LootParams$Builder"
)
);
public static final Method method$BlockStateBase$getDrops = requireNonNull(
ReflectionUtils.getMethod(clazz$BlockStateBase, List.class, clazz$LootParams$Builder)
);
}

View File

@@ -1,5 +1,7 @@
package net.momirealms.craftengine.bukkit.plugin.reflection.minecraft;
import net.momirealms.craftengine.bukkit.plugin.reflection.ReflectionInitException;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
@@ -18,6 +20,7 @@ public final class MBuiltInRegistries {
public static final Object FLUID;
public static final Object RECIPE_TYPE;
public static final Object PARTICLE_TYPE;
public static final Object DATA_COMPONENT_TYPE;
static {
Field[] fields = CoreReflections.clazz$BuiltInRegistries.getDeclaredFields();
@@ -31,6 +34,7 @@ public final class MBuiltInRegistries {
Object registries$Item = null;
Object registries$Fluid = null;
Object registries$RecipeType = null;
Object registries$DataComponentType = null;
for (Field field : fields) {
Type fieldType = field.getGenericType();
if (fieldType instanceof ParameterizedType paramType) {
@@ -43,6 +47,8 @@ public final class MBuiltInRegistries {
registries$EntityType = field.get(null);
} else if (rawType == CoreReflections.clazz$RecipeType) {
registries$RecipeType = field.get(null);
} else if (rawType == CoreReflections.clazz$DataComponentType) {
registries$DataComponentType = field.get(null);
}
} else {
if (type == CoreReflections.clazz$Block) {
@@ -70,8 +76,9 @@ public final class MBuiltInRegistries {
ENTITY_TYPE = requireNonNull(registries$EntityType);
FLUID = requireNonNull(registries$Fluid);
RECIPE_TYPE = requireNonNull(registries$RecipeType);
DATA_COMPONENT_TYPE = registries$DataComponentType;
} catch (ReflectiveOperationException e) {
throw new RuntimeException(e);
throw new ReflectionInitException("Failed to init BuiltInRegistries", e);
}
}
}

View File

@@ -99,7 +99,6 @@ public final class NetworkReflections {
)
);
public static final Field field$ClientboundBossEventPacket$AddOperation$name = requireNonNull(
ReflectionUtils.getDeclaredField(clazz$ClientboundBossEventPacket$AddOperation, 0)
);
@@ -397,7 +396,6 @@ public final class NetworkReflections {
ReflectionUtils.getDeclaredField(clazz$ClientboundLevelChunkWithLightPacket, clazz$ClientboundLevelChunkPacketData, 0)
);
public static final Field field$ClientboundLevelChunkWithLightPacket$x = requireNonNull(
ReflectionUtils.getDeclaredField(clazz$ClientboundLevelChunkWithLightPacket, int.class, 0)
);
@@ -1484,4 +1482,11 @@ public final class NetworkReflections {
}
}
public static final Class<?> clazz$StreamCodec = BukkitReflectionUtils.findReobfOrMojmapClass(
"network.codec.StreamCodec",
"network.codec.StreamCodec"
);
public static final Object instance$ParticleTypes$STREAM_CODEC = !VersionHelper.isOrAbove1_20_5() ? null :
ReflectionUtils.getDeclaredField(CoreReflections.clazz$ParticleTypes, clazz$StreamCodec, 0);
}

View File

@@ -10,6 +10,7 @@ import net.momirealms.craftengine.bukkit.item.BukkitItemManager;
import net.momirealms.craftengine.bukkit.nms.FastNMS;
import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine;
import net.momirealms.craftengine.bukkit.plugin.gui.CraftEngineInventoryHolder;
import net.momirealms.craftengine.bukkit.plugin.network.BukkitNetworkManager;
import net.momirealms.craftengine.bukkit.plugin.network.payload.DiscardedPayload;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MAttributeHolders;
@@ -655,10 +656,10 @@ public class BukkitServerPlayer extends Player {
if (canBreak(hitPos, customState.vanillaBlockState().handle())) {
// Error might occur so we use try here
try {
FastNMS.INSTANCE.setMayBuild(serverPlayer, true);
FastNMS.INSTANCE.field$Player$mayBuild(serverPlayer, true);
CoreReflections.method$ServerPlayerGameMode$destroyBlock.invoke(gameMode, blockPos);
} finally {
FastNMS.INSTANCE.setMayBuild(serverPlayer, false);
FastNMS.INSTANCE.field$Player$mayBuild(serverPlayer, false);
}
}
} else {
@@ -691,7 +692,14 @@ public class BukkitServerPlayer extends Player {
double d1 = (double) hitPos.y() - otherLocation.getY();
double d2 = (double) hitPos.z() - otherLocation.getZ();
if (d0 * d0 + d1 * d1 + d2 * d2 < 1024.0D) {
FastNMS.INSTANCE.sendPacket(FastNMS.INSTANCE.field$Player$connection$connection(FastNMS.INSTANCE.method$CraftPlayer$getHandle(other)), packet);
FastNMS.INSTANCE.method$Connection$send(
FastNMS.INSTANCE.field$ServerGamePacketListenerImpl$connection(
FastNMS.INSTANCE.field$Player$connection(
FastNMS.INSTANCE.method$CraftPlayer$getHandle(player)
)
),
packet
);
}
}
}
@@ -701,7 +709,7 @@ public class BukkitServerPlayer extends Player {
if (this.lastUpdateInteractionRangeTick + 20 > gameTicks()) {
return this.cachedInteractionRange;
}
this.cachedInteractionRange = FastNMS.INSTANCE.getInteractionRange(serverPlayer());
this.cachedInteractionRange = FastNMS.INSTANCE.method$Player$getInteractionRange(serverPlayer());
this.lastUpdateInteractionRangeTick = gameTicks();
return this.cachedInteractionRange;
}
@@ -807,7 +815,9 @@ public class BukkitServerPlayer extends Player {
if (this.connection == null) {
Object serverPlayer = serverPlayer();
if (serverPlayer != null) {
this.connection = (ChannelHandler) FastNMS.INSTANCE.field$Player$connection$connection(serverPlayer);
this.connection = (ChannelHandler) FastNMS.INSTANCE.field$ServerGamePacketListenerImpl$connection(
FastNMS.INSTANCE.field$Player$connection(serverPlayer)
);
} else {
throw new IllegalStateException("Cannot init or find connection instance for player " + name());
}

View File

@@ -2,6 +2,7 @@ package net.momirealms.craftengine.bukkit.sound;
import net.momirealms.craftengine.bukkit.nms.FastNMS;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MBuiltInRegistries;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MRegistries;
import net.momirealms.craftengine.bukkit.util.ComponentUtils;
import net.momirealms.craftengine.bukkit.util.KeyUtils;
@@ -19,7 +20,10 @@ public class BukkitSoundManager extends AbstractSoundManager {
public BukkitSoundManager(CraftEngine plugin) {
super(plugin);
VANILLA_SOUND_EVENTS.addAll(FastNMS.INSTANCE.getAllVanillaSounds().stream().map(it -> Key.of(it.getNamespace(), it.getKey())).toList());
for (Object soundEvent : (Iterable<?>) MBuiltInRegistries.SOUND_EVENT) {
Object resourceLocation = FastNMS.INSTANCE.field$SoundEvent$location(soundEvent);
VANILLA_SOUND_EVENTS.add(KeyUtils.resourceLocationToKey(resourceLocation));
}
}
@Override

View File

@@ -29,7 +29,7 @@ public class AdventureModeUtils {
return false;
}
}
return FastNMS.INSTANCE.canBreakInAdventureMode(FastNMS.INSTANCE.field$CraftItemStack$handle(itemStack), blockInWorld);
return FastNMS.INSTANCE.method$ItemStack$canBreakInAdventureMode(FastNMS.INSTANCE.field$CraftItemStack$handle(itemStack), blockInWorld);
}
public static boolean canPlace(Item<?> itemStack, World world, BlockPos pos, Object state) {
@@ -44,7 +44,7 @@ public class AdventureModeUtils {
return false;
}
}
return FastNMS.INSTANCE.canPlaceInAdventureMode(item, blockInWorld);
return FastNMS.INSTANCE.method$ItemStack$canPlaceInAdventureMode(item, blockInWorld);
}
public static boolean canPlace(ItemStack itemStack, Location pos, Object state) {
@@ -58,6 +58,6 @@ public class AdventureModeUtils {
return false;
}
}
return FastNMS.INSTANCE.canPlaceInAdventureMode(FastNMS.INSTANCE.field$CraftItemStack$handle(itemStack), blockInWorld);
return FastNMS.INSTANCE.method$ItemStack$canPlaceInAdventureMode(FastNMS.INSTANCE.field$CraftItemStack$handle(itemStack), blockInWorld);
}
}

View File

@@ -104,14 +104,6 @@ public class BlockStateUtils {
}
}
public static Object createBlockUpdatePacket(BlockPos pos, ImmutableBlockState state) {
try {
return NetworkReflections.constructor$ClientboundBlockUpdatePacket.newInstance(LocationUtils.toBlockPos(pos), state.customBlockState().handle());
} catch (ReflectiveOperationException e) {
throw new RuntimeException(e);
}
}
public static BlockData fromBlockData(Object blockState) {
return FastNMS.INSTANCE.method$CraftBlockData$fromData(blockState);
}
@@ -120,28 +112,14 @@ public class BlockStateUtils {
return blockStateToId(blockDataToBlockState(blockData));
}
public static Key getBlockOwnerId(Block block) {
return getBlockOwnerIdFromData(block.getBlockData());
}
public static Key getBlockOwnerIdFromData(BlockData block) {
Object blockState = blockDataToBlockState(block);
return getBlockOwnerIdFromState(blockState);
return getBlockOwnerIdFromState(blockDataToBlockState(block));
}
public static Key getBlockOwnerIdFromState(Object blockState) {
return getBlockOwnerIdFromString(blockState.toString());
}
public static Key getBlockOwnerIdFromString(String id) {
int first = id.indexOf('{');
int last = id.indexOf('}');
if (first != -1 && last != -1 && last > first) {
String blockId = id.substring(first + 1, last);
return Key.of(blockId);
} else {
throw new IllegalArgumentException("Invalid block ID format: " + id);
}
Object blockOwner = FastNMS.INSTANCE.method$BlockState$getBlock(blockState);
Object resourceLocation = FastNMS.INSTANCE.method$Registry$getKey(MBuiltInRegistries.BLOCK, blockOwner);
return KeyUtils.resourceLocationToKey(resourceLocation);
}
public static Object blockDataToBlockState(BlockData blockData) {
@@ -160,86 +138,12 @@ public class BlockStateUtils {
return FastNMS.INSTANCE.method$BlockState$getBlock(blockState);
}
public static int physicsEventToId(BlockPhysicsEvent event) throws ReflectiveOperationException {
Object blockData = CraftBukkitReflections.field$BlockPhysicsEvent$changed.get(event);
Object blockState = CraftBukkitReflections.field$CraftBlockData$data.get(blockData);
return FastNMS.INSTANCE.method$IdMapper$getId(CoreReflections.instance$Block$BLOCK_STATE_REGISTRY, blockState);
}
public static Object physicsEventToState(BlockPhysicsEvent event) throws ReflectiveOperationException {
Object blockData = CraftBukkitReflections.field$BlockPhysicsEvent$changed.get(event);
return CraftBukkitReflections.field$CraftBlockData$data.get(blockData);
}
public static void setLightEmission(Object state, int emission) throws ReflectiveOperationException {
CoreReflections.field$BlockStateBase$lightEmission.set(state, emission);
}
public static int getLightEmission(Object state) {
return FastNMS.INSTANCE.method$BlockStateBase$getLightEmission(state);
}
public static void setMapColor(Object state, MapColor color) throws ReflectiveOperationException {
Object mcMapColor = CoreReflections.method$MapColor$byId.invoke(null, color.id);
CoreReflections.field$BlockStateBase$mapColor.set(state, mcMapColor);
}
public static void setInstrument(Object state, Instrument instrument) throws ReflectiveOperationException {
Object mcInstrument = ((Object[]) CoreReflections.method$NoteBlockInstrument$values.invoke(null))[instrument.ordinal()];
CoreReflections.field$BlockStateBase$instrument.set(state, mcInstrument);
}
public static void setHardness(Object state, float hardness) throws ReflectiveOperationException {
CoreReflections.field$BlockStateBase$hardness.set(state, hardness);
}
public static void setBurnable(Object state, boolean burnable) throws ReflectiveOperationException {
CoreReflections.field$BlockStateBase$burnable.set(state, burnable);
}
public static void setUseShapeForLightOcclusion(Object state, boolean useShapeForLightOcclusion) throws ReflectiveOperationException {
CoreReflections.field$BlockStateBase$useShapeForLightOcclusion.set(state, useShapeForLightOcclusion);
}
public static void setPushReaction(Object state, PushReaction reaction) throws ReflectiveOperationException {
Object pushReaction = ((Object[]) CoreReflections.method$PushReaction$values.invoke(null))[reaction.ordinal()];
CoreReflections.field$BlockStateBase$pushReaction.set(state, pushReaction);
}
public static void setIsRandomlyTicking(Object state, boolean randomlyTicking) throws ReflectiveOperationException {
CoreReflections.field$BlockStateBase$isRandomlyTicking.set(state, randomlyTicking);
}
public static void setReplaceable(Object state, boolean replaceable) throws ReflectiveOperationException {
CoreReflections.field$BlockStateBase$replaceable.set(state, replaceable);
}
public static boolean isReplaceable(Object state) {
try {
return (boolean) CoreReflections.field$BlockStateBase$replaceable.get(state);
} catch (ReflectiveOperationException e) {
throw new RuntimeException("Failed to get replaceable property", e);
}
}
public static void setCanOcclude(Object state, boolean canOcclude) throws ReflectiveOperationException {
CoreReflections.field$BlockStateBase$canOcclude.set(state, canOcclude);
}
public static boolean isOcclude(Object state) {
return FastNMS.INSTANCE.method$BlockStateBase$canOcclude(state);
}
public static void setIsRedstoneConductor(Object state, Object predicate) throws ReflectiveOperationException {
CoreReflections.field$BlockStateBase$isRedstoneConductor.set(state, predicate);
}
public static void setIsSuffocating(Object state, Object predicate) throws ReflectiveOperationException {
CoreReflections.field$BlockStateBase$isSuffocating.set(state, predicate);
}
public static void setIsViewBlocking(Object state, Object predicate) throws ReflectiveOperationException {
CoreReflections.field$BlockStateBase$isViewBlocking.set(state, predicate);
public static boolean isReplaceable(Object state) {
return FastNMS.INSTANCE.method$BlockStateBase$isReplaceable(state);
}
public static boolean isClientSideNoteBlock(Object state) {
@@ -247,8 +151,11 @@ public class BlockStateUtils {
}
public static boolean isVanillaBlock(Object state) {
int id = blockStateToId(state);
return id >= 0 && id < vanillaStateSize;
return !(state instanceof CustomBlockStateHolder);
}
public static boolean isCustomBlock(Object state) {
return state instanceof CustomBlockStateHolder;
}
public static boolean isVanillaBlock(int id) {

View File

@@ -1,6 +1,9 @@
package net.momirealms.craftengine.bukkit.util;
import net.momirealms.craftengine.bukkit.item.BukkitItemManager;
import net.momirealms.craftengine.bukkit.nms.FastNMS;
import net.momirealms.craftengine.bukkit.plugin.reflection.bukkit.CraftBukkitReflections;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.Contract;
@@ -33,4 +36,12 @@ public class ItemUtils {
}
return false;
}
public static ItemStack ensureCraftItemStack(ItemStack itemStack) {
if (CraftBukkitReflections.clazz$CraftItemStack.isInstance(itemStack)) {
return itemStack;
} else {
return FastNMS.INSTANCE.method$CraftItemStack$asCraftCopy(itemStack);
}
}
}

View File

@@ -4,10 +4,13 @@ import net.momirealms.craftengine.bukkit.nms.FastNMS;
import net.momirealms.craftengine.core.util.Key;
import org.bukkit.NamespacedKey;
public class KeyUtils {
public final class KeyUtils {
private KeyUtils() {}
public static Key resourceLocationToKey(Object resourceLocation) {
return Key.of(FastNMS.INSTANCE.method$ResourceLocation$namespace(resourceLocation), FastNMS.INSTANCE.method$ResourceLocation$path(resourceLocation));
}
public static Key namespacedKey2Key(NamespacedKey key) {
return Key.of(key.getNamespace(), key.getKey());
}

View File

@@ -27,7 +27,9 @@ public class LightUtils {
Object chunkPos = FastNMS.INSTANCE.constructor$ChunkPos((int) chunkKey, (int) (chunkKey >> 32));
Object lightPacket = FastNMS.INSTANCE.constructor$ClientboundLightUpdatePacket(chunkPos, lightEngine, entry.getValue(), entry.getValue());
for (Object player : players) {
FastNMS.INSTANCE.sendPacket(FastNMS.INSTANCE.field$Player$connection$connection(player), lightPacket);
FastNMS.INSTANCE.method$Connection$send(
FastNMS.INSTANCE.field$ServerGamePacketListenerImpl$connection(FastNMS.INSTANCE.field$ServerGamePacketListenerImpl$connection(player)),
lightPacket);
}
}
} catch (Exception e) {

View File

@@ -38,14 +38,9 @@ public final class ParticleUtils {
@Nullable
public static Particle getParticle(Key particle) {
return CACHE.computeIfAbsent(particle, k -> {
try {
Object nmsParticle = CoreReflections.method$Registry$get.invoke(MBuiltInRegistries.PARTICLE_TYPE, KeyUtils.toResourceLocation(particle));
if (nmsParticle == null) return null;
return FastNMS.INSTANCE.method$CraftParticle$toBukkit(nmsParticle);
} catch (ReflectiveOperationException e) {
CraftEngine.instance().logger().warn("Failed to get particle: " + particle, e);
return null;
}
Object nmsParticle = FastNMS.INSTANCE.method$Registry$getValue(MBuiltInRegistries.PARTICLE_TYPE, KeyUtils.toResourceLocation(particle));
if (nmsParticle == null) return null;
return FastNMS.INSTANCE.method$CraftParticle$toBukkit(nmsParticle);
});
}