mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-29 03:49:15 +00:00
Merge remote-tracking branch 'origin/dev' into dev
# Conflicts: # bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/listener/ItemEventListener.java # core/src/main/java/net/momirealms/craftengine/core/item/ItemSettings.java # gradle.properties
This commit is contained in:
@@ -28,7 +28,6 @@ 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;
|
||||
@@ -131,7 +130,6 @@ 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);
|
||||
}
|
||||
@@ -361,24 +359,4 @@ 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.field$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,7 +86,6 @@ 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());
|
||||
}
|
||||
|
||||
@@ -102,7 +101,6 @@ 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) {
|
||||
|
||||
@@ -2,7 +2,6 @@ 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;
|
||||
@@ -37,7 +36,6 @@ 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);
|
||||
}
|
||||
@@ -50,7 +48,6 @@ 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);
|
||||
}
|
||||
@@ -62,7 +59,6 @@ public class FurnitureEventListener implements Listener {
|
||||
Entity entity = event.getEntity();
|
||||
if (entity instanceof ItemDisplay itemDisplay) {
|
||||
this.manager.handleBaseEntityLoadLate(itemDisplay, 0);
|
||||
BukkitFurniture.injectFurnitureEntity(FastNMS.INSTANCE.method$CraftEntity$getHandle(itemDisplay));
|
||||
} else if (BukkitFurnitureManager.COLLISION_ENTITY_CLASS.isInstance(entity)) {
|
||||
this.manager.handleCollisionEntityLoadLate(entity, 0);
|
||||
}
|
||||
|
||||
@@ -205,7 +205,7 @@ public class BukkitProjectileManager implements Listener, ProjectileManager {
|
||||
private void updateProjectileUpdateInterval(int updateInterval) {
|
||||
if (this.lastInjectedInterval == updateInterval) return;
|
||||
try {
|
||||
CoreReflections.handle$ServerEntity$updateIntervalSetter.invokeExact(this.cachedServerEntity, updateInterval);
|
||||
CoreReflections.methodHandle$ServerEntity$updateIntervalSetter.invokeExact(this.cachedServerEntity, updateInterval);
|
||||
this.lastInjectedInterval = updateInterval;
|
||||
} catch (Throwable e) {
|
||||
BukkitProjectileManager.this.plugin.logger().warn("Failed to update server entity update interval for " + this.projectile.getType().getKey() + "[" + this.projectile.getUniqueId() + "]", e);
|
||||
|
||||
@@ -2,6 +2,7 @@ package net.momirealms.craftengine.bukkit.item;
|
||||
|
||||
import com.saicone.rtag.item.ItemTagStream;
|
||||
import net.momirealms.craftengine.bukkit.item.behavior.BucketItemBehavior;
|
||||
import net.momirealms.craftengine.bukkit.item.behavior.FlintAndSteelItemBehavior;
|
||||
import net.momirealms.craftengine.bukkit.item.behavior.WaterBucketItemBehavior;
|
||||
import net.momirealms.craftengine.bukkit.item.factory.BukkitItemFactory;
|
||||
import net.momirealms.craftengine.bukkit.item.listener.ArmorEventListener;
|
||||
@@ -43,6 +44,7 @@ public class BukkitItemManager extends AbstractItemManager<ItemStack> {
|
||||
static {
|
||||
registerVanillaItemExtraBehavior(WaterBucketItemBehavior.INSTANCE, ItemKeys.WATER_BUCKETS);
|
||||
registerVanillaItemExtraBehavior(BucketItemBehavior.INSTANCE, ItemKeys.BUCKET);
|
||||
registerVanillaItemExtraBehavior(FlintAndSteelItemBehavior.INSTANCE, ItemKeys.FLINT_AND_STEEL);
|
||||
}
|
||||
|
||||
private static BukkitItemManager instance;
|
||||
|
||||
@@ -8,7 +8,6 @@ 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;
|
||||
@@ -113,7 +112,6 @@ public class ComponentItemWrapper implements ItemWrapper<ItemStack> {
|
||||
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);
|
||||
|
||||
@@ -10,6 +10,7 @@ public class BukkitItemBehaviors extends ItemBehaviors {
|
||||
public static final Key FURNITURE_ITEM = Key.from("craftengine:furniture_item");
|
||||
public static final Key WATER_BUCKET_ITEM = Key.from("craftengine:water_bucket_item");
|
||||
public static final Key BUCKET_ITEM = Key.from("craftengine:bucket_item");
|
||||
public static final Key FLINT_AND_STEEL_ITEM = Key.from("craftengine:flint_and_steel_item");
|
||||
|
||||
public static void init() {
|
||||
register(EMPTY, EmptyItemBehavior.FACTORY);
|
||||
@@ -18,5 +19,6 @@ public class BukkitItemBehaviors extends ItemBehaviors {
|
||||
register(FURNITURE_ITEM, FurnitureItemBehavior.FACTORY);
|
||||
register(WATER_BUCKET_ITEM, WaterBucketItemBehavior.FACTORY);
|
||||
register(BUCKET_ITEM, BucketItemBehavior.FACTORY);
|
||||
register(FLINT_AND_STEEL_ITEM, FlintAndSteelItemBehavior.FACTORY);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,167 @@
|
||||
package net.momirealms.craftengine.bukkit.item.behavior;
|
||||
|
||||
import net.momirealms.craftengine.bukkit.block.BukkitBlockManager;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections;
|
||||
import net.momirealms.craftengine.bukkit.util.BlockStateUtils;
|
||||
import net.momirealms.craftengine.bukkit.util.DirectionUtils;
|
||||
import net.momirealms.craftengine.bukkit.util.InteractUtils;
|
||||
import net.momirealms.craftengine.bukkit.util.LocationUtils;
|
||||
import net.momirealms.craftengine.bukkit.world.BukkitBlockInWorld;
|
||||
import net.momirealms.craftengine.core.block.ImmutableBlockState;
|
||||
import net.momirealms.craftengine.core.entity.player.InteractionResult;
|
||||
import net.momirealms.craftengine.core.item.Item;
|
||||
import net.momirealms.craftengine.core.item.behavior.ItemBehavior;
|
||||
import net.momirealms.craftengine.core.item.behavior.ItemBehaviorFactory;
|
||||
import net.momirealms.craftengine.core.item.context.UseOnContext;
|
||||
import net.momirealms.craftengine.core.pack.Pack;
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
import net.momirealms.craftengine.core.sound.SoundSource;
|
||||
import net.momirealms.craftengine.core.util.Direction;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.RandomUtils;
|
||||
import net.momirealms.craftengine.core.world.BlockPos;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.Map;
|
||||
|
||||
public class FlintAndSteelItemBehavior extends ItemBehavior {
|
||||
public static final FlintAndSteelItemBehavior INSTANCE = new FlintAndSteelItemBehavior();
|
||||
public static final Factory FACTORY = new Factory();
|
||||
private static final Key FLINT_SOUND = Key.of("item.flintandsteel.use");
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public InteractionResult useOnBlock(UseOnContext context) {
|
||||
BlockPos clickedPos = context.getClickedPos();
|
||||
BukkitBlockInWorld clicked = (BukkitBlockInWorld) context.getLevel().getBlockAt(clickedPos);
|
||||
Block block = clicked.block();
|
||||
BlockPos firePos = clickedPos.relative(context.getClickedFace());
|
||||
Direction direction = context.getHorizontalDirection();
|
||||
|
||||
// 最基础的判断能不能着火,不能着火都是扯蛋
|
||||
try {
|
||||
if (!(boolean) CoreReflections.method$BaseFireBlock$canBePlacedAt.invoke(null, context.getLevel().serverWorld(), LocationUtils.toBlockPos(firePos), DirectionUtils.toNMSDirection(direction))) {
|
||||
return InteractionResult.PASS;
|
||||
}
|
||||
} catch (ReflectiveOperationException e) {
|
||||
CraftEngine.instance().logger().warn("Failed to call BaseFireBlock$canBePlacedAt", e);
|
||||
return InteractionResult.PASS;
|
||||
}
|
||||
|
||||
// 判断点击的方块是否可燃
|
||||
BlockData clickedBlockData = block.getBlockData();
|
||||
Object clickedBlockState = BlockStateUtils.blockDataToBlockState(clickedBlockData);
|
||||
boolean isClickedBlockBurnable;
|
||||
try {
|
||||
isClickedBlockBurnable = BlockStateUtils.isBurnable(clickedBlockState) ||
|
||||
(context.getClickedFace() == Direction.UP && (boolean) CoreReflections.method$BlockStateBase$isFaceSturdy.invoke(
|
||||
clickedBlockState, context.getLevel().serverWorld(), LocationUtils.toBlockPos(clickedPos), CoreReflections.instance$Direction$UP, CoreReflections.instance$SupportType$FULL));
|
||||
} catch (ReflectiveOperationException e) {
|
||||
CraftEngine.instance().logger().warn("Failed to call method$BlockStateBase$isFaceSturdy", e);
|
||||
return InteractionResult.PASS;
|
||||
}
|
||||
|
||||
net.momirealms.craftengine.core.entity.player.Player player = context.getPlayer();
|
||||
// 点击对象直接可燃,则忽略
|
||||
if (isClickedBlockBurnable) {
|
||||
int stateId = BlockStateUtils.blockStateToId(clickedBlockState);
|
||||
if (BlockStateUtils.isVanillaBlock(stateId)) {
|
||||
return InteractionResult.PASS;
|
||||
} else {
|
||||
// 点击对象为自定义方块
|
||||
ImmutableBlockState immutableBlockState = BukkitBlockManager.instance().getImmutableBlockStateUnsafe(stateId);
|
||||
// 原版外观也可燃
|
||||
if (BlockStateUtils.isBurnable(immutableBlockState.vanillaBlockState().handle())) {
|
||||
return InteractionResult.PASS;
|
||||
}
|
||||
BlockData vanillaBlockState = BlockStateUtils.fromBlockData(immutableBlockState.vanillaBlockState().handle());
|
||||
// 点击的是方块上面,则只需要判断shift和可交互
|
||||
if (direction == Direction.UP) {
|
||||
// 客户端层面必须可交互
|
||||
if (!InteractUtils.isInteractable((Player) player.platformPlayer(), vanillaBlockState,
|
||||
context.getHitResult(), (Item<ItemStack>) context.getItem())) {
|
||||
return InteractionResult.PASS;
|
||||
}
|
||||
// 且没有shift
|
||||
if (!player.isSecondaryUseActive()) {
|
||||
player.playSound(FLINT_SOUND, firePos, SoundSource.BLOCK, 1f, RandomUtils.generateRandomFloat(0.8f, 1.2f));
|
||||
}
|
||||
} else {
|
||||
// 玩家觉得自定义方块不可燃,且点击了侧面,那么就要判断火源下方的方块是否可燃,如果不可燃,则补发声音
|
||||
BlockPos belowFirePos = firePos.relative(Direction.DOWN);
|
||||
BukkitBlockInWorld belowFireBlock = (BukkitBlockInWorld) context.getLevel().getBlockAt(belowFirePos);
|
||||
boolean belowCanBurn;
|
||||
try {
|
||||
Block belowBlock = belowFireBlock.block();
|
||||
belowCanBurn = BlockStateUtils.isBurnable(BlockStateUtils.blockDataToBlockState(belowBlock.getBlockData())) ||
|
||||
(boolean) CoreReflections.method$BlockStateBase$isFaceSturdy.invoke(
|
||||
BlockStateUtils.blockDataToBlockState(belowFireBlock.block().getBlockData()), context.getLevel().serverWorld(), LocationUtils.toBlockPos(belowFirePos), CoreReflections.instance$Direction$UP, CoreReflections.instance$SupportType$FULL);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
CraftEngine.instance().logger().warn("Failed to call method$BlockStateBase$isFaceSturdy", e);
|
||||
return InteractionResult.PASS;
|
||||
}
|
||||
|
||||
// 客户端觉得这玩意可交互,就会忽略声音
|
||||
if (InteractUtils.isInteractable((Player) player.platformPlayer(), vanillaBlockState, context.getHitResult(), (Item<ItemStack>) context.getItem())) {
|
||||
// 如果按住了shift,则代表尝试对侧面方块点火
|
||||
if (player.isSecondaryUseActive()) {
|
||||
// 如果底部不能燃烧,则燃烧点位为侧面,需要补发
|
||||
if (!belowCanBurn) {
|
||||
player.playSound(FLINT_SOUND, firePos, SoundSource.BLOCK, 1f, RandomUtils.generateRandomFloat(0.8f, 1.2f));
|
||||
player.swingHand(context.getHand());
|
||||
}
|
||||
} else {
|
||||
player.playSound(FLINT_SOUND, firePos, SoundSource.BLOCK, 1f, RandomUtils.generateRandomFloat(0.8f, 1.2f));
|
||||
}
|
||||
} else {
|
||||
// 如果底部方块不可燃烧才补发
|
||||
if (!belowCanBurn) {
|
||||
player.playSound(FLINT_SOUND, firePos, SoundSource.BLOCK, 1f, RandomUtils.generateRandomFloat(0.8f, 1.2f));
|
||||
player.swingHand(context.getHand());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 如果点击的方块不可燃烧,但是服务端却认为可以放置火源,则可燃烧的方块一定位于火源的六个方向之一。
|
||||
Direction relativeDirection = direction.opposite();
|
||||
for (Direction dir : Direction.values()) {
|
||||
if (dir == relativeDirection) continue;
|
||||
BlockPos relPos = firePos.relative(dir);
|
||||
BukkitBlockInWorld nearByBlock = (BukkitBlockInWorld) context.getLevel().getBlockAt(relPos);
|
||||
BlockData nearbyBlockData = nearByBlock.block().getBlockData();
|
||||
Object nearbyBlockState = BlockStateUtils.blockDataToBlockState(nearbyBlockData);
|
||||
int stateID = BlockStateUtils.blockStateToId(nearbyBlockState);
|
||||
if (BlockStateUtils.isVanillaBlock(stateID)) {
|
||||
if (BlockStateUtils.isBurnable(nearbyBlockState)) {
|
||||
return InteractionResult.PASS;
|
||||
}
|
||||
try {
|
||||
if (dir == Direction.DOWN && (boolean) CoreReflections.method$BlockStateBase$isFaceSturdy.invoke(
|
||||
nearbyBlockState, context.getLevel().serverWorld(), LocationUtils.toBlockPos(relPos), CoreReflections.instance$Direction$UP, CoreReflections.instance$SupportType$FULL)) {
|
||||
return InteractionResult.PASS;
|
||||
}
|
||||
} catch (ReflectiveOperationException e) {
|
||||
CraftEngine.instance().logger().warn("Failed to call method$BlockStateBase$isFaceSturdy", e);
|
||||
return InteractionResult.PASS;
|
||||
}
|
||||
}
|
||||
}
|
||||
player.playSound(FLINT_SOUND, firePos, SoundSource.BLOCK, 1f, RandomUtils.generateRandomFloat(0.8f, 1.2f));
|
||||
player.swingHand(context.getHand());
|
||||
}
|
||||
return InteractionResult.PASS;
|
||||
}
|
||||
|
||||
public static class Factory implements ItemBehaviorFactory {
|
||||
@Override
|
||||
public ItemBehavior create(Pack pack, Path path, Key id, Map<String, Object> arguments) {
|
||||
return INSTANCE;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -34,6 +34,7 @@ import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.block.BlockIgniteEvent;
|
||||
import org.bukkit.event.entity.EntityDamageEvent;
|
||||
import org.bukkit.event.entity.FoodLevelChangeEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEntityEvent;
|
||||
|
||||
@@ -33,6 +33,7 @@ import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.Campfire;
|
||||
import org.bukkit.block.Furnace;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
@@ -790,6 +791,48 @@ public class RecipeEventListener implements Listener {
|
||||
return new Pair<>(first, second);
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
|
||||
public void onCraft(CraftItemEvent event) {
|
||||
org.bukkit.inventory.Recipe recipe = event.getRecipe();
|
||||
if (!(recipe instanceof ShapelessRecipe) && !(recipe instanceof ShapedRecipe)) return;
|
||||
HumanEntity humanEntity = event.getWhoClicked();
|
||||
if (!(humanEntity instanceof Player player)) return;
|
||||
CraftingInventory inventory = event.getInventory();
|
||||
ItemStack result = inventory.getResult();
|
||||
if (result == null) return;
|
||||
ItemStack[] usedItems = inventory.getMatrix();
|
||||
ItemStack[] replacements = new ItemStack[usedItems.length];
|
||||
boolean hasReplacement = false;
|
||||
for (int i = 0; i < usedItems.length; i++) {
|
||||
ItemStack usedItem = usedItems[i];
|
||||
if (ItemUtils.isEmpty(usedItem)) continue;
|
||||
if (usedItem.getAmount() != 1) continue;
|
||||
Item<ItemStack> wrapped = BukkitItemManager.instance().wrap(usedItem);
|
||||
if (wrapped == null) continue;
|
||||
Optional<CustomItem<ItemStack>> optionalCustomItem = wrapped.getCustomItem();
|
||||
if (optionalCustomItem.isPresent()) {
|
||||
CustomItem<ItemStack> customItem = optionalCustomItem.get();
|
||||
Key remainingItem = customItem.settings().craftRemainder();
|
||||
if (remainingItem != null) {
|
||||
replacements[i] = BukkitItemManager.instance().buildItemStack(remainingItem, this.plugin.adapt(player));
|
||||
hasReplacement = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!hasReplacement) return;
|
||||
Runnable delayedTask = () -> {
|
||||
for (int i = 0; i < replacements.length; i++) {
|
||||
if (replacements[i] == null) continue;
|
||||
inventory.setItem(i + 1, replacements[i]);
|
||||
}
|
||||
};
|
||||
if (VersionHelper.isFolia()) {
|
||||
player.getScheduler().run(this.plugin.javaPlugin(), (t) -> delayedTask.run(), () -> {});
|
||||
} else {
|
||||
this.plugin.scheduler().sync().runDelayed(delayedTask);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onCraftingRecipe(PrepareItemCraftEvent event) {
|
||||
if (!Config.enableRecipeSystem()) return;
|
||||
|
||||
@@ -48,6 +48,7 @@ public class BukkitCommandManager extends AbstractCommandManager<CommandSender>
|
||||
new DebugSpawnFurnitureCommand(this, plugin),
|
||||
new DebugTargetBlockCommand(this, plugin),
|
||||
new DebugIsSectionInjectedCommand(this, plugin),
|
||||
new DebugMigrateTemplatesCommand(this, plugin),
|
||||
new DebugEntityId2UUIDCommand(this, plugin),
|
||||
new TotemAnimationCommand(this, plugin),
|
||||
new EnableResourceCommand(this, plugin),
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
package net.momirealms.craftengine.bukkit.plugin.command.feature;
|
||||
|
||||
import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine;
|
||||
import net.momirealms.craftengine.bukkit.plugin.command.BukkitCommandFeature;
|
||||
import net.momirealms.craftengine.core.pack.Pack;
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
import net.momirealms.craftengine.core.plugin.command.CraftEngineCommandManager;
|
||||
import net.momirealms.craftengine.core.util.FileUtils;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.incendo.cloud.Command;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class DebugMigrateTemplatesCommand extends BukkitCommandFeature<CommandSender> {
|
||||
private static final Pattern PATTERN = Pattern.compile("(?<!\\$)\\{([^}]+)}");
|
||||
|
||||
public DebugMigrateTemplatesCommand(CraftEngineCommandManager<CommandSender> commandManager, CraftEngine plugin) {
|
||||
super(commandManager, plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Command.Builder<? extends CommandSender> assembleCommand(org.incendo.cloud.CommandManager<CommandSender> manager, Command.Builder<CommandSender> builder) {
|
||||
return builder
|
||||
.handler(context -> {
|
||||
for (Pack pack : BukkitCraftEngine.instance().packManager().loadedPacks()) {
|
||||
for (Path file : FileUtils.getYmlConfigsDeeply(pack.configurationFolder())) {
|
||||
try {
|
||||
Files.writeString(file, replacePlaceholders(Files.readString(file)));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
context.sender().sendMessage("Done");
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFeatureID() {
|
||||
return "debug_migrate_templates";
|
||||
}
|
||||
|
||||
private static String replacePlaceholders(String input) {
|
||||
if (input == null) {
|
||||
return null;
|
||||
}
|
||||
Matcher matcher = PATTERN.matcher(input);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
while (matcher.find()) {
|
||||
// 将 {xxx} 替换为 ${xxx}
|
||||
matcher.appendReplacement(sb, "\\${" + matcher.group(1) + "}");
|
||||
}
|
||||
matcher.appendTail(sb);
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
@@ -82,7 +82,7 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
|
||||
|
||||
private static final String CONNECTION_HANDLER_NAME = "craftengine_connection_handler";
|
||||
private static final String SERVER_CHANNEL_HANDLER_NAME = "craftengine_server_channel_handler";
|
||||
private static final String PLAYER_CHANNEL_HANDLER_NAME = "craftengine_player_packet_handler";
|
||||
private static final String PLAYER_CHANNEL_HANDLER_NAME = "craftengine_player_channel_handler";
|
||||
private static final String PACKET_ENCODER = "craftengine_encoder";
|
||||
private static final String PACKET_DECODER = "craftengine_decoder";
|
||||
|
||||
@@ -159,6 +159,7 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
|
||||
registerNMSPacketConsumer(PacketConsumers.RESOURCE_PACK_RESPONSE, NetworkReflections.clazz$ServerboundResourcePackPacket);
|
||||
registerNMSPacketConsumer(PacketConsumers.ENTITY_EVENT, NetworkReflections.clazz$ClientboundEntityEventPacket);
|
||||
registerNMSPacketConsumer(PacketConsumers.MOVE_POS_AND_ROTATE_ENTITY, NetworkReflections.clazz$ClientboundMoveEntityPacket$PosRot);
|
||||
registerNMSPacketConsumer(PacketConsumers.MOVE_POS_ENTITY, NetworkReflections.clazz$ClientboundMoveEntityPacket$Pos);
|
||||
registerS2CByteBufPacketConsumer(PacketConsumers.LEVEL_CHUNK_WITH_LIGHT, this.packetIds.clientboundLevelChunkWithLightPacket());
|
||||
registerS2CByteBufPacketConsumer(PacketConsumers.SECTION_BLOCK_UPDATE, this.packetIds.clientboundSectionBlocksUpdatePacket());
|
||||
registerS2CByteBufPacketConsumer(PacketConsumers.BLOCK_UPDATE, this.packetIds.clientboundBlockUpdatePacket());
|
||||
|
||||
@@ -162,6 +162,7 @@ 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) -> {
|
||||
@@ -172,6 +173,7 @@ public class PacketConsumers {
|
||||
BukkitFurniture furniture = BukkitFurnitureManager.instance().loadedFurnitureByRealEntityId(id);
|
||||
if (furniture != null) {
|
||||
event.setCancelled(true);
|
||||
user.entityPacketHandlers().put(id, FurnitureCollisionPacketHandler.INSTANCE);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -1169,14 +1171,14 @@ public class PacketConsumers {
|
||||
public static final TriConsumer<NetWorkUser, NMSPacketEvent, Object> HELLO_C2S = (user, event, packet) -> {
|
||||
try {
|
||||
BukkitServerPlayer player = (BukkitServerPlayer) user;
|
||||
String name = (String) NetworkReflections.handle$ServerboundHelloPacket$nameGetter.invokeExact(packet);
|
||||
String name = (String) NetworkReflections.methodHandle$ServerboundHelloPacket$nameGetter.invokeExact(packet);
|
||||
player.setName(name);
|
||||
if (VersionHelper.isOrAbove1_20_2()) {
|
||||
UUID uuid = (UUID) NetworkReflections.handle$ServerboundHelloPacket$uuidGetter.invokeExact(packet);
|
||||
UUID uuid = (UUID) NetworkReflections.methodHandle$ServerboundHelloPacket$uuidGetter.invokeExact(packet);
|
||||
player.setUUID(uuid);
|
||||
} else {
|
||||
@SuppressWarnings("unchecked")
|
||||
Optional<UUID> uuid = (Optional<UUID>) NetworkReflections.handle$ServerboundHelloPacket$uuidGetter.invokeExact(packet);
|
||||
Optional<UUID> uuid = (Optional<UUID>) NetworkReflections.methodHandle$ServerboundHelloPacket$uuidGetter.invokeExact(packet);
|
||||
if (uuid.isPresent()) {
|
||||
player.setUUID(uuid.get());
|
||||
} else {
|
||||
@@ -1220,10 +1222,10 @@ public class PacketConsumers {
|
||||
player.clearView();
|
||||
Object dimensionKey;
|
||||
if (!VersionHelper.isOrAbove1_20_2()) {
|
||||
dimensionKey = NetworkReflections.handle$ClientboundRespawnPacket$dimensionGetter.invokeExact(packet);
|
||||
dimensionKey = NetworkReflections.methodHandle$ClientboundRespawnPacket$dimensionGetter.invokeExact(packet);
|
||||
} else {
|
||||
Object commonInfo = NetworkReflections.handle$ClientboundRespawnPacket$commonPlayerSpawnInfoGetter.invokeExact(packet);
|
||||
dimensionKey = NetworkReflections.handle$CommonPlayerSpawnInfo$dimensionGetter.invokeExact(commonInfo);
|
||||
Object commonInfo = NetworkReflections.methodHandle$ClientboundRespawnPacket$commonPlayerSpawnInfoGetter.invokeExact(packet);
|
||||
dimensionKey = NetworkReflections.methodHandle$CommonPlayerSpawnInfo$dimensionGetter.invokeExact(commonInfo);
|
||||
}
|
||||
Object location = FastNMS.INSTANCE.field$ResourceKey$location(dimensionKey);
|
||||
World world = Bukkit.getWorld(Objects.requireNonNull(NamespacedKey.fromString(location.toString())));
|
||||
@@ -1248,10 +1250,10 @@ public class PacketConsumers {
|
||||
if (BukkitNetworkManager.hasViaVersion()) {
|
||||
user.setProtocolVersion(CraftEngine.instance().compatibilityManager().getPlayerProtocolVersion(player.uuid()));
|
||||
}
|
||||
dimensionKey = NetworkReflections.handle$ClientboundLoginPacket$dimensionGetter.invokeExact(packet);
|
||||
dimensionKey = NetworkReflections.methodHandle$ClientboundLoginPacket$dimensionGetter.invokeExact(packet);
|
||||
} else {
|
||||
Object commonInfo = NetworkReflections.handle$ClientboundLoginPacket$commonPlayerSpawnInfoGetter.invokeExact(packet);
|
||||
dimensionKey = NetworkReflections.handle$CommonPlayerSpawnInfo$dimensionGetter.invokeExact(commonInfo);
|
||||
Object commonInfo = NetworkReflections.methodHandle$ClientboundLoginPacket$commonPlayerSpawnInfoGetter.invokeExact(packet);
|
||||
dimensionKey = NetworkReflections.methodHandle$CommonPlayerSpawnInfo$dimensionGetter.invokeExact(commonInfo);
|
||||
}
|
||||
Object location = FastNMS.INSTANCE.field$ResourceKey$location(dimensionKey);
|
||||
World world = Bukkit.getWorld(Objects.requireNonNull(NamespacedKey.fromString(location.toString())));
|
||||
@@ -1295,9 +1297,9 @@ public class PacketConsumers {
|
||||
Player bukkitPlayer = player.platformPlayer();
|
||||
if (bukkitPlayer == null) return;
|
||||
if (bukkitPlayer.getGameMode() != GameMode.CREATIVE) return;
|
||||
int slot = VersionHelper.isOrAbove1_20_5() ? (short) NetworkReflections.handle$ServerboundSetCreativeModeSlotPacket$slotNumGetter.invokeExact(packet) : (int) NetworkReflections.handle$ServerboundSetCreativeModeSlotPacket$slotNumGetter.invokeExact(packet);
|
||||
int slot = VersionHelper.isOrAbove1_20_5() ? (short) NetworkReflections.methodHandle$ServerboundSetCreativeModeSlotPacket$slotNumGetter.invokeExact(packet) : (int) NetworkReflections.methodHandle$ServerboundSetCreativeModeSlotPacket$slotNumGetter.invokeExact(packet);
|
||||
if (slot < 36 || slot > 44) return;
|
||||
ItemStack item = FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(NetworkReflections.handle$ServerboundSetCreativeModeSlotPacket$itemStackGetter.invokeExact(packet));
|
||||
ItemStack item = FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(NetworkReflections.methodHandle$ServerboundSetCreativeModeSlotPacket$itemStackGetter.invokeExact(packet));
|
||||
if (ItemUtils.isEmpty(item)) return;
|
||||
if (slot - 36 != bukkitPlayer.getInventory().getHeldItemSlot()) {
|
||||
return;
|
||||
@@ -1370,7 +1372,7 @@ public class PacketConsumers {
|
||||
if (!user.isOnline()) return;
|
||||
Player player = (Player) user.platformPlayer();
|
||||
if (player == null) return;
|
||||
Object pos = NetworkReflections.handle$ServerboundPickItemFromBlockPacket$posGetter.invokeExact(packet);
|
||||
Object pos = NetworkReflections.methodHandle$ServerboundPickItemFromBlockPacket$posGetter.invokeExact(packet);
|
||||
if (VersionHelper.isFolia()) {
|
||||
int x = FastNMS.INSTANCE.field$Vec3i$x(pos);
|
||||
int z = FastNMS.INSTANCE.field$Vec3i$z(pos);
|
||||
@@ -1408,7 +1410,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.handle$ServerboundPickItemFromEntityPacket$idGetter.invokeExact(packet);
|
||||
int entityId = (int) NetworkReflections.methodHandle$ServerboundPickItemFromEntityPacket$idGetter.invokeExact(packet);
|
||||
BukkitFurniture furniture = BukkitFurnitureManager.instance().loadedFurnitureByEntityId(entityId);
|
||||
if (furniture == null) return;
|
||||
Player player = (Player) user.platformPlayer();
|
||||
@@ -1450,11 +1452,11 @@ public class PacketConsumers {
|
||||
assert CoreReflections.method$ServerGamePacketListenerImpl$tryPickItem != null;
|
||||
if (VersionHelper.isOrAbove1_21_5()) {
|
||||
CoreReflections.method$ServerGamePacketListenerImpl$tryPickItem.invoke(
|
||||
CoreReflections.handle$ServerPlayer$connectionGetter.invokeExact(FastNMS.INSTANCE.method$CraftPlayer$getHandle(player)),
|
||||
CoreReflections.methodHandle$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.handle$ServerPlayer$connectionGetter.invokeExact(FastNMS.INSTANCE.method$CraftPlayer$getHandle(player)), FastNMS.INSTANCE.method$CraftItemStack$asNMSCopy(itemStack));
|
||||
CoreReflections.methodHandle$ServerPlayer$connectionGetter.invokeExact(FastNMS.INSTANCE.method$CraftPlayer$getHandle(player)), FastNMS.INSTANCE.method$CraftItemStack$asNMSCopy(itemStack));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1747,14 +1749,14 @@ public class PacketConsumers {
|
||||
if (((BukkitServerPlayer) user).hasPermission(FontManager.BYPASS_ANVIL)) {
|
||||
return;
|
||||
}
|
||||
String message = (String) NetworkReflections.handle$ServerboundRenameItemPacket$nameGetter.invokeExact(packet);
|
||||
String message = (String) NetworkReflections.methodHandle$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.handle$ServerboundRenameItemPacket$nameSetter.invokeExact(packet, result.text());
|
||||
NetworkReflections.methodHandle$ServerboundRenameItemPacket$nameSetter.invokeExact(packet, result.text());
|
||||
} catch (ReflectiveOperationException e) {
|
||||
CraftEngine.instance().logger().warn("Failed to replace chat", e);
|
||||
}
|
||||
@@ -1773,7 +1775,7 @@ public class PacketConsumers {
|
||||
if (((BukkitServerPlayer) user).hasPermission(FontManager.BYPASS_SIGN)) {
|
||||
return;
|
||||
}
|
||||
String[] lines = (String[]) NetworkReflections.handle$ServerboundSignUpdatePacket$linesGetter.invokeExact(packet);
|
||||
String[] lines = (String[]) NetworkReflections.methodHandle$ServerboundSignUpdatePacket$linesGetter.invokeExact(packet);
|
||||
FontManager manager = CraftEngine.instance().fontManager();
|
||||
if (!manager.isDefaultFontInUse()) return;
|
||||
for (int i = 0; i < lines.length; i++) {
|
||||
@@ -1804,9 +1806,9 @@ public class PacketConsumers {
|
||||
|
||||
boolean changed = false;
|
||||
|
||||
List<String> pages = (List<String>) NetworkReflections.handleServerboundEditBookPacket$pagesGetter.invokeExact(packet);
|
||||
List<String> pages = (List<String>) NetworkReflections.methodHandle$ServerboundEditBookPacket$pagesGetter.invokeExact(packet);
|
||||
List<String> newPages = new ArrayList<>(pages.size());
|
||||
Optional<String> title = (Optional<String>) NetworkReflections.handle$ServerboundEditBookPacket$titleGetter.invokeExact(packet);
|
||||
Optional<String> title = (Optional<String>) NetworkReflections.methodHandle$ServerboundEditBookPacket$titleGetter.invokeExact(packet);
|
||||
Optional<String> newTitle;
|
||||
|
||||
if (title.isPresent()) {
|
||||
@@ -1830,7 +1832,7 @@ public class PacketConsumers {
|
||||
|
||||
if (changed) {
|
||||
Object newPacket = NetworkReflections.constructor$ServerboundEditBookPacket.newInstance(
|
||||
(int) NetworkReflections.handle$ServerboundEditBookPacket$slotGetter.invokeExact(packet),
|
||||
(int) NetworkReflections.methodHandle$ServerboundEditBookPacket$slotGetter.invokeExact(packet),
|
||||
newPages,
|
||||
newTitle
|
||||
);
|
||||
@@ -1863,7 +1865,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.handle$ServerboundCustomPayloadPacket$payloadGetter.invokeExact(packet);
|
||||
Object payload = NetworkReflections.methodHandle$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))
|
||||
@@ -2282,7 +2284,7 @@ public class PacketConsumers {
|
||||
public static final TriConsumer<NetWorkUser, NMSPacketEvent, Object> HANDSHAKE_C2S = (user, event, packet) -> {
|
||||
try {
|
||||
if (BukkitNetworkManager.hasViaVersion()) return;
|
||||
int protocolVersion = (int) NetworkReflections.handle$ClientIntentionPacket$protocolVersionGetter.invokeExact(packet);
|
||||
int protocolVersion = (int) NetworkReflections.methodHandle$ClientIntentionPacket$protocolVersionGetter.invokeExact(packet);
|
||||
user.setProtocolVersion(protocolVersion);
|
||||
} catch (Throwable e) {
|
||||
CraftEngine.instance().logger().warn("Failed to handle ClientIntentionPacket", e);
|
||||
@@ -2302,7 +2304,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.handle$ServerboundResourcePackPacket$actionGetter.invokeExact(packet);
|
||||
Object action = NetworkReflections.methodHandle$ServerboundResourcePackPacket$actionGetter.invokeExact(packet);
|
||||
if (action == null) return;
|
||||
if (action == NetworkReflections.instance$ServerboundResourcePackPacket$Action$DECLINED
|
||||
|| action == NetworkReflections.instance$ServerboundResourcePackPacket$Action$FAILED_DOWNLOAD) {
|
||||
@@ -2324,9 +2326,9 @@ public class PacketConsumers {
|
||||
try {
|
||||
Object player = user.serverPlayer();
|
||||
if (player == null) return;
|
||||
int entityId = (int) NetworkReflections.handle$ClientboundEntityEventPacket$entityIdGetter.invokeExact(packet);
|
||||
int entityId = (int) NetworkReflections.methodHandle$ClientboundEntityEventPacket$entityIdGetter.invokeExact(packet);
|
||||
if (entityId != FastNMS.INSTANCE.method$Entity$getId(player)) return;
|
||||
byte eventId = (byte) NetworkReflections.handle$ClientboundEntityEventPacket$eventIdGetter.invokeExact(packet);
|
||||
byte eventId = (byte) NetworkReflections.methodHandle$ClientboundEntityEventPacket$eventIdGetter.invokeExact(packet);
|
||||
if (eventId >= 24 && eventId <= 28) {
|
||||
CraftEngine.instance().fontManager().refreshEmojiSuggestions(user.uuid());
|
||||
}
|
||||
@@ -2346,4 +2348,16 @@ public class PacketConsumers {
|
||||
CraftEngine.instance().logger().warn("Failed to handle ClientboundMoveEntityPacket$PosRot", e);
|
||||
}
|
||||
};
|
||||
|
||||
public static final TriConsumer<NetWorkUser, NMSPacketEvent, Object> MOVE_POS_ENTITY = (user, event, packet) -> {
|
||||
try {
|
||||
int entityId = ProtectedFieldVisitor.get().field$ClientboundMoveEntityPacket$entityId(packet);
|
||||
EntityPacketHandler handler = user.entityPacketHandlers().get(entityId);
|
||||
if (handler != null) {
|
||||
handler.handleMove(user, event, packet);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
CraftEngine.instance().logger().warn("Failed to handle ClientboundMoveEntityPacket", e);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMove(NetWorkUser user, NMSPacketEvent event, Object packet) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,8 @@ 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;
|
||||
|
||||
@@ -17,4 +19,14 @@ public class FurniturePacketHandler implements EntityPacketHandler {
|
||||
entityIds.addAll(this.fakeEntities);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleSyncEntityPosition(NetWorkUser user, NMSPacketEvent event, Object packet) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMove(NetWorkUser user, NMSPacketEvent event, Object packet) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.google.gson.JsonElement;
|
||||
import com.mojang.serialization.DynamicOps;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.ReflectionInitException;
|
||||
import net.momirealms.craftengine.bukkit.util.BukkitReflectionUtils;
|
||||
import net.momirealms.craftengine.core.util.ReflectionUtils;
|
||||
@@ -3274,21 +3275,21 @@ public final class CoreReflections {
|
||||
)
|
||||
);
|
||||
|
||||
public static final MethodHandle handle$ServerEntity$broadcastSetter;
|
||||
public static final MethodHandle handle$ServerEntity$updateIntervalSetter;
|
||||
public static final MethodHandle handle$ServerPlayer$connectionGetter;
|
||||
public static final MethodHandle methodHandle$ServerEntity$broadcastSetter;
|
||||
public static final MethodHandle methodHandle$ServerEntity$updateIntervalSetter;
|
||||
public static final MethodHandle methodHandle$ServerPlayer$connectionGetter;
|
||||
|
||||
static {
|
||||
try {
|
||||
handle$ServerEntity$broadcastSetter = requireNonNull(
|
||||
methodHandle$ServerEntity$broadcastSetter = requireNonNull(
|
||||
ReflectionUtils.unreflectSetter(field$ServerEntity$broadcast)
|
||||
.asType(MethodType.methodType(void.class, Object.class, Consumer.class))
|
||||
);
|
||||
handle$ServerEntity$updateIntervalSetter = requireNonNull(
|
||||
methodHandle$ServerEntity$updateIntervalSetter = requireNonNull(
|
||||
ReflectionUtils.unreflectSetter(field$ServerEntity$updateInterval)
|
||||
.asType(MethodType.methodType(void.class, Object.class, int.class))
|
||||
);
|
||||
handle$ServerPlayer$connectionGetter = requireNonNull(
|
||||
methodHandle$ServerPlayer$connectionGetter = requireNonNull(
|
||||
ReflectionUtils.unreflectGetter(field$ServerPlayer$connection)
|
||||
.asType(MethodType.methodType(Object.class, Object.class))
|
||||
);
|
||||
@@ -3296,4 +3297,19 @@ public final class CoreReflections {
|
||||
throw new ReflectionInitException("Failed to initialize reflection", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static final Class<?> clazz$BaseFireBlock = requireNonNull(
|
||||
BukkitReflectionUtils.findReobfOrMojmapClass(
|
||||
"world.level.block.BlockFireAbstract",
|
||||
"world.level.block.BaseFireBlock"
|
||||
)
|
||||
);
|
||||
|
||||
public static final Method method$BaseFireBlock$canBePlacedAt = requireNonNull(
|
||||
ReflectionUtils.getStaticMethod(clazz$BaseFireBlock, boolean.class, clazz$Level, clazz$BlockPos, clazz$Direction)
|
||||
);
|
||||
|
||||
public static final Field field$FireBlock$igniteOdds = requireNonNull(
|
||||
ReflectionUtils.getDeclaredField(clazz$FireBlock, Object2IntMap.class, 0)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1304,165 +1304,165 @@ public final class NetworkReflections {
|
||||
)
|
||||
);
|
||||
|
||||
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;
|
||||
public static final MethodHandle methodHandle$ServerboundRenameItemPacket$nameGetter;
|
||||
public static final MethodHandle methodHandle$ServerboundRenameItemPacket$nameSetter;
|
||||
public static final MethodHandle methodHandle$ServerboundHelloPacket$nameGetter;
|
||||
public static final MethodHandle methodHandle$ServerboundHelloPacket$uuidGetter;
|
||||
public static final MethodHandle methodHandle$ServerboundSetCreativeModeSlotPacket$itemStackGetter;
|
||||
public static final MethodHandle methodHandle$ServerboundSetCreativeModeSlotPacket$slotNumGetter;
|
||||
public static final MethodHandle methodHandle$ServerboundInteractPacket$actionGetter;
|
||||
public static final MethodHandle methodHandle$ServerboundInteractPacket$InteractionAtLocationAction$handGetter;
|
||||
public static final MethodHandle methodHandle$ServerboundInteractPacket$InteractionAtLocationAction$locationGetter;
|
||||
public static final MethodHandle methodHandle$ServerboundSignUpdatePacket$linesGetter;
|
||||
public static final MethodHandle methodHandle$ServerboundEditBookPacket$pagesGetter;
|
||||
public static final MethodHandle methodHandle$ServerboundEditBookPacket$titleGetter;
|
||||
public static final MethodHandle methodHandle$ServerboundEditBookPacket$slotGetter;
|
||||
public static final MethodHandle methodHandle$ServerboundResourcePackPacket$actionGetter;
|
||||
public static final MethodHandle methodHandle$ClientboundEntityEventPacket$entityIdGetter;
|
||||
public static final MethodHandle methodHandle$ClientboundEntityEventPacket$eventIdGetter;
|
||||
public static final MethodHandle methodHandle$ClientIntentionPacket$protocolVersionGetter;
|
||||
public static final MethodHandle methodHandle$ClientboundRespawnPacket$dimensionGetter;
|
||||
public static final MethodHandle methodHandle$ClientboundRespawnPacket$commonPlayerSpawnInfoGetter;
|
||||
public static final MethodHandle methodHandle$CommonPlayerSpawnInfo$dimensionGetter;
|
||||
public static final MethodHandle methodHandle$ClientboundLoginPacket$dimensionGetter;
|
||||
public static final MethodHandle methodHandle$ClientboundLoginPacket$commonPlayerSpawnInfoGetter;
|
||||
public static final MethodHandle methodHandle$ServerboundPickItemFromBlockPacket$posGetter;
|
||||
public static final MethodHandle methodHandle$ServerboundPickItemFromEntityPacket$idGetter;
|
||||
public static final MethodHandle methodHandle$ServerboundCustomPayloadPacket$payloadGetter;
|
||||
|
||||
static {
|
||||
try {
|
||||
handle$ServerboundRenameItemPacket$nameGetter = requireNonNull(
|
||||
methodHandle$ServerboundRenameItemPacket$nameGetter = requireNonNull(
|
||||
ReflectionUtils.unreflectGetter(field$ServerboundRenameItemPacket$name)
|
||||
.asType(MethodType.methodType(String.class, Object.class))
|
||||
);
|
||||
handle$ServerboundRenameItemPacket$nameSetter = requireNonNull(
|
||||
methodHandle$ServerboundRenameItemPacket$nameSetter = requireNonNull(
|
||||
ReflectionUtils.unreflectSetter(field$ServerboundRenameItemPacket$name)
|
||||
.asType(MethodType.methodType(void.class, Object.class, String.class))
|
||||
);
|
||||
handle$ServerboundHelloPacket$nameGetter = requireNonNull(
|
||||
methodHandle$ServerboundHelloPacket$nameGetter = requireNonNull(
|
||||
ReflectionUtils.unreflectGetter(field$ServerboundHelloPacket$name)
|
||||
.asType(MethodType.methodType(String.class, Object.class))
|
||||
);
|
||||
handle$ServerboundHelloPacket$uuidGetter = requireNonNull(
|
||||
methodHandle$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(
|
||||
methodHandle$ServerboundSetCreativeModeSlotPacket$itemStackGetter = requireNonNull(
|
||||
ReflectionUtils.unreflectGetter(field$ServerboundSetCreativeModeSlotPacket$itemStack)
|
||||
.asType(MethodType.methodType(Object.class, Object.class))
|
||||
);
|
||||
handle$ServerboundSetCreativeModeSlotPacket$slotNumGetter = requireNonNull(
|
||||
methodHandle$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(
|
||||
methodHandle$ServerboundInteractPacket$actionGetter = requireNonNull(
|
||||
ReflectionUtils.unreflectGetter(field$ServerboundInteractPacket$action)
|
||||
.asType(MethodType.methodType(Object.class, Object.class))
|
||||
);
|
||||
handle$ServerboundInteractPacket$InteractionAtLocationAction$handGetter = requireNonNull(
|
||||
methodHandle$ServerboundInteractPacket$InteractionAtLocationAction$handGetter = requireNonNull(
|
||||
ReflectionUtils.unreflectGetter(field$ServerboundInteractPacket$InteractionAtLocationAction$hand)
|
||||
.asType(MethodType.methodType(Object.class, Object.class))
|
||||
);
|
||||
handle$ServerboundInteractPacket$InteractionAtLocationAction$locationGetter = requireNonNull(
|
||||
methodHandle$ServerboundInteractPacket$InteractionAtLocationAction$locationGetter = requireNonNull(
|
||||
ReflectionUtils.unreflectGetter(field$ServerboundInteractPacket$InteractionAtLocationAction$location)
|
||||
.asType(MethodType.methodType(Object.class, Object.class))
|
||||
);
|
||||
handle$ServerboundSignUpdatePacket$linesGetter = requireNonNull(
|
||||
methodHandle$ServerboundSignUpdatePacket$linesGetter = requireNonNull(
|
||||
ReflectionUtils.unreflectGetter(field$ServerboundSignUpdatePacket$lines)
|
||||
.asType(MethodType.methodType(String[].class, Object.class))
|
||||
);
|
||||
handleServerboundEditBookPacket$pagesGetter = requireNonNull(
|
||||
methodHandle$ServerboundEditBookPacket$pagesGetter = requireNonNull(
|
||||
ReflectionUtils.unreflectGetter(field$ServerboundEditBookPacket$pages)
|
||||
.asType(MethodType.methodType(List.class, Object.class))
|
||||
);
|
||||
handle$ServerboundEditBookPacket$titleGetter = requireNonNull(
|
||||
methodHandle$ServerboundEditBookPacket$titleGetter = requireNonNull(
|
||||
ReflectionUtils.unreflectGetter(field$ServerboundEditBookPacket$title)
|
||||
.asType(MethodType.methodType(Optional.class, Object.class))
|
||||
);
|
||||
handle$ServerboundEditBookPacket$slotGetter = requireNonNull(
|
||||
methodHandle$ServerboundEditBookPacket$slotGetter = requireNonNull(
|
||||
ReflectionUtils.unreflectGetter(field$ServerboundEditBookPacket$slot)
|
||||
.asType(MethodType.methodType(int.class, Object.class))
|
||||
);
|
||||
handle$ServerboundResourcePackPacket$actionGetter = requireNonNull(
|
||||
methodHandle$ServerboundResourcePackPacket$actionGetter = requireNonNull(
|
||||
ReflectionUtils.unreflectGetter(field$ServerboundResourcePackPacket$action)
|
||||
.asType(MethodType.methodType(Object.class, Object.class))
|
||||
);
|
||||
handle$ClientboundEntityEventPacket$entityIdGetter = requireNonNull(
|
||||
methodHandle$ClientboundEntityEventPacket$entityIdGetter = requireNonNull(
|
||||
ReflectionUtils.unreflectGetter(field$ClientboundEntityEventPacket$entityId)
|
||||
.asType(MethodType.methodType(int.class, Object.class))
|
||||
);
|
||||
handle$ClientboundEntityEventPacket$eventIdGetter = requireNonNull(
|
||||
methodHandle$ClientboundEntityEventPacket$eventIdGetter = requireNonNull(
|
||||
ReflectionUtils.unreflectGetter(field$ClientboundEntityEventPacket$eventId)
|
||||
.asType(MethodType.methodType(byte.class, Object.class))
|
||||
);
|
||||
handle$ClientIntentionPacket$protocolVersionGetter = requireNonNull(
|
||||
methodHandle$ClientIntentionPacket$protocolVersionGetter = requireNonNull(
|
||||
ReflectionUtils.unreflectGetter(field$ClientIntentionPacket$protocolVersion)
|
||||
.asType(MethodType.methodType(int.class, Object.class))
|
||||
);
|
||||
if (field$ServerboundCustomPayloadPacket$payload != null) {
|
||||
handle$ServerboundCustomPayloadPacket$payloadGetter = requireNonNull(
|
||||
methodHandle$ServerboundCustomPayloadPacket$payloadGetter = requireNonNull(
|
||||
ReflectionUtils.unreflectGetter(field$ServerboundCustomPayloadPacket$payload)
|
||||
.asType(MethodType.methodType(Object.class, Object.class))
|
||||
);
|
||||
} else {
|
||||
handle$ServerboundCustomPayloadPacket$payloadGetter = null;
|
||||
methodHandle$ServerboundCustomPayloadPacket$payloadGetter = null;
|
||||
}
|
||||
if (field$ServerboundPickItemFromEntityPacket$id != null) {
|
||||
handle$ServerboundPickItemFromEntityPacket$idGetter = requireNonNull(
|
||||
methodHandle$ServerboundPickItemFromEntityPacket$idGetter = requireNonNull(
|
||||
ReflectionUtils.unreflectGetter(field$ServerboundPickItemFromEntityPacket$id)
|
||||
.asType(MethodType.methodType(int.class, Object.class))
|
||||
);
|
||||
} else {
|
||||
handle$ServerboundPickItemFromEntityPacket$idGetter = null;
|
||||
methodHandle$ServerboundPickItemFromEntityPacket$idGetter = null;
|
||||
}
|
||||
if (field$ServerboundPickItemFromBlockPacket$pos != null) {
|
||||
handle$ServerboundPickItemFromBlockPacket$posGetter = requireNonNull(
|
||||
methodHandle$ServerboundPickItemFromBlockPacket$posGetter = requireNonNull(
|
||||
ReflectionUtils.unreflectGetter(field$ServerboundPickItemFromBlockPacket$pos)
|
||||
.asType(MethodType.methodType(Object.class, Object.class))
|
||||
);
|
||||
} else {
|
||||
handle$ServerboundPickItemFromBlockPacket$posGetter = null;
|
||||
methodHandle$ServerboundPickItemFromBlockPacket$posGetter = null;
|
||||
}
|
||||
if (field$ClientboundLoginPacket$commonPlayerSpawnInfo != null) {
|
||||
handle$ClientboundLoginPacket$commonPlayerSpawnInfoGetter = requireNonNull(
|
||||
methodHandle$ClientboundLoginPacket$commonPlayerSpawnInfoGetter = requireNonNull(
|
||||
ReflectionUtils.unreflectGetter(field$ClientboundLoginPacket$commonPlayerSpawnInfo)
|
||||
.asType(MethodType.methodType(Object.class, Object.class))
|
||||
);
|
||||
} else {
|
||||
handle$ClientboundLoginPacket$commonPlayerSpawnInfoGetter = null;
|
||||
methodHandle$ClientboundLoginPacket$commonPlayerSpawnInfoGetter = null;
|
||||
}
|
||||
if (field$ClientboundLoginPacket$dimension != null) {
|
||||
handle$ClientboundLoginPacket$dimensionGetter = requireNonNull(
|
||||
methodHandle$ClientboundLoginPacket$dimensionGetter = requireNonNull(
|
||||
ReflectionUtils.unreflectGetter(field$ClientboundLoginPacket$dimension)
|
||||
.asType(MethodType.methodType(Object.class, Object.class))
|
||||
);
|
||||
} else {
|
||||
handle$ClientboundLoginPacket$dimensionGetter = null;
|
||||
methodHandle$ClientboundLoginPacket$dimensionGetter = null;
|
||||
}
|
||||
if (field$CommonPlayerSpawnInfo$dimension != null) {
|
||||
handle$CommonPlayerSpawnInfo$dimensionGetter = requireNonNull(
|
||||
methodHandle$CommonPlayerSpawnInfo$dimensionGetter = requireNonNull(
|
||||
ReflectionUtils.unreflectGetter(field$CommonPlayerSpawnInfo$dimension)
|
||||
.asType(MethodType.methodType(Object.class, Object.class))
|
||||
);
|
||||
} else {
|
||||
handle$CommonPlayerSpawnInfo$dimensionGetter = null;
|
||||
methodHandle$CommonPlayerSpawnInfo$dimensionGetter = null;
|
||||
}
|
||||
if (field$ClientboundRespawnPacket$commonPlayerSpawnInfo != null) {
|
||||
handle$ClientboundRespawnPacket$commonPlayerSpawnInfoGetter = requireNonNull(
|
||||
methodHandle$ClientboundRespawnPacket$commonPlayerSpawnInfoGetter = requireNonNull(
|
||||
ReflectionUtils.unreflectGetter(field$ClientboundRespawnPacket$commonPlayerSpawnInfo)
|
||||
.asType(MethodType.methodType(Object.class, Object.class))
|
||||
);
|
||||
} else {
|
||||
handle$ClientboundRespawnPacket$commonPlayerSpawnInfoGetter = null;
|
||||
methodHandle$ClientboundRespawnPacket$commonPlayerSpawnInfoGetter = null;
|
||||
}
|
||||
if (field$ClientboundRespawnPacket$dimension != null) {
|
||||
handle$ClientboundRespawnPacket$dimensionGetter = requireNonNull(
|
||||
methodHandle$ClientboundRespawnPacket$dimensionGetter = requireNonNull(
|
||||
ReflectionUtils.unreflectGetter(field$ClientboundRespawnPacket$dimension)
|
||||
.asType(MethodType.methodType(Object.class, Object.class))
|
||||
);
|
||||
} else {
|
||||
handle$ClientboundRespawnPacket$dimensionGetter = null;
|
||||
methodHandle$ClientboundRespawnPacket$dimensionGetter = null;
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
throw new ReflectionInitException("Failed to initialize reflection", e);
|
||||
|
||||
@@ -30,10 +30,12 @@ import net.momirealms.craftengine.core.plugin.context.CooldownData;
|
||||
import net.momirealms.craftengine.core.plugin.network.ConnectionState;
|
||||
import net.momirealms.craftengine.core.plugin.network.EntityPacketHandler;
|
||||
import net.momirealms.craftengine.core.plugin.network.ProtocolVersion;
|
||||
import net.momirealms.craftengine.core.sound.SoundSource;
|
||||
import net.momirealms.craftengine.core.util.Direction;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.VersionHelper;
|
||||
import net.momirealms.craftengine.core.world.BlockPos;
|
||||
import net.momirealms.craftengine.core.world.Position;
|
||||
import net.momirealms.craftengine.core.world.World;
|
||||
import net.momirealms.craftengine.core.world.WorldEvents;
|
||||
import org.bukkit.*;
|
||||
@@ -283,8 +285,13 @@ public class BukkitServerPlayer extends Player {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playSound(Key sound, float volume, float pitch) {
|
||||
platformPlayer().playSound(platformPlayer(), sound.toString(), SoundCategory.MASTER, volume, pitch);
|
||||
public void playSound(Key sound, SoundSource source, float volume, float pitch) {
|
||||
platformPlayer().playSound(platformPlayer(), sound.toString(), SoundUtils.toBukkit(source), volume, pitch);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playSound(Key sound, BlockPos blockPos, SoundSource source, float volume, float pitch) {
|
||||
platformPlayer().playSound(new Location(null, blockPos.x() + 0.5, blockPos.y() + 0.5, blockPos.z() + 0.5), sound.toString(), SoundUtils.toBukkit(source), volume, pitch);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -2,8 +2,10 @@ package net.momirealms.craftengine.bukkit.util;
|
||||
|
||||
import net.momirealms.craftengine.bukkit.block.BukkitBlockManager;
|
||||
import net.momirealms.craftengine.bukkit.nms.FastNMS;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.ReflectionInitException;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.bukkit.CraftBukkitReflections;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MBlocks;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MBuiltInRegistries;
|
||||
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.NetworkReflections;
|
||||
import net.momirealms.craftengine.core.block.*;
|
||||
@@ -22,18 +24,26 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
public class BlockStateUtils {
|
||||
public static final IdentityHashMap<Object, Object> CLIENT_SIDE_NOTE_BLOCKS = new IdentityHashMap<>();
|
||||
private static int vanillaStateSize;
|
||||
private static boolean hasInit;
|
||||
public static Map<Object, Integer> IGNITE_ODDS;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static void init(int size) {
|
||||
if (hasInit) {
|
||||
throw new IllegalStateException("BlockStateUtils has already been initialized");
|
||||
}
|
||||
vanillaStateSize = size;
|
||||
try {
|
||||
IGNITE_ODDS = (Map<Object, Integer>) CoreReflections.field$FireBlock$igniteOdds.get(MBlocks.FIRE);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new ReflectionInitException("Failed to initialize instance$FireBlock$igniteOdds", e);
|
||||
}
|
||||
hasInit = true;
|
||||
}
|
||||
|
||||
@@ -248,4 +258,9 @@ public class BlockStateUtils {
|
||||
public static int vanillaStateSize() {
|
||||
return vanillaStateSize;
|
||||
}
|
||||
|
||||
public static boolean isBurnable(Object state) {
|
||||
Object blockOwner = getBlockOwner(state);
|
||||
return IGNITE_ODDS.getOrDefault(blockOwner, 0) > 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,6 +189,13 @@ debug_entity_id_to_uuid:
|
||||
- /craftengine debug entity-id-to-uuid
|
||||
- /ce debug entity-id-to-uuid
|
||||
|
||||
debug_migrate_templates:
|
||||
enable: true
|
||||
permission: ce.command.debug.migrate_templates
|
||||
usage:
|
||||
- /craftengine debug migrate-templates
|
||||
- /ce debug migrate-templates
|
||||
|
||||
debug_test:
|
||||
enable: true
|
||||
permission: ce.command.debug.test
|
||||
|
||||
@@ -167,7 +167,7 @@ items#misc:
|
||||
template: "default:loot_table/self"
|
||||
settings:
|
||||
template:
|
||||
- default:sound/sand
|
||||
- default:sound/stone
|
||||
- default:pickaxe_power/level_1
|
||||
- default:settings/solid_1x1x1
|
||||
overrides:
|
||||
|
||||
@@ -2,7 +2,7 @@ templates:
|
||||
default:emoji/basic:
|
||||
content: "<hover:show_text:'<i18n:emoji.tip>'><!shadow><white><arg:emoji></white></!shadow></hover>"
|
||||
default:emoji/addition_info:
|
||||
content: "<hover:show_text:'<i18n:emoji.tip>'><!shadow><white><arg:emoji></white></!shadow>{text}</hover>"
|
||||
content: "<hover:show_text:'<i18n:emoji.tip>'><!shadow><white><arg:emoji></white></!shadow>${text}</hover>"
|
||||
|
||||
emoji:
|
||||
default:emoji_location:
|
||||
|
||||
@@ -229,16 +229,16 @@ items#topaz_gears:
|
||||
|
||||
templates:
|
||||
default:armor/topaz:
|
||||
material: "chainmail_{part}"
|
||||
material: "chainmail_${part}"
|
||||
custom-model-data: 1000
|
||||
data:
|
||||
item-name: "<!i><#FF8C00><i18n:item.topaz_{part}>"
|
||||
item-name: "<!i><#FF8C00><i18n:item.topaz_${part}>"
|
||||
tooltip-style: minecraft:topaz
|
||||
settings:
|
||||
tags:
|
||||
- "default:topaz_tools"
|
||||
equippable:
|
||||
slot: "{slot}"
|
||||
slot: "${slot}"
|
||||
asset-id: topaz
|
||||
humanoid: "minecraft:topaz"
|
||||
humanoid-leggings: "minecraft:topaz"
|
||||
@@ -247,111 +247,111 @@ templates:
|
||||
property: minecraft:trim_material
|
||||
fallback:
|
||||
type: minecraft:model
|
||||
path: "minecraft:item/custom/topaz_{part}"
|
||||
path: "minecraft:item/custom/topaz_${part}"
|
||||
generation:
|
||||
parent: "minecraft:item/generated"
|
||||
textures:
|
||||
"layer0": "minecraft:item/custom/topaz_{part}"
|
||||
"layer0": "minecraft:item/custom/topaz_${part}"
|
||||
cases:
|
||||
- when: minecraft:quartz
|
||||
model:
|
||||
type: minecraft:model
|
||||
path: "minecraft:item/custom/topaz_{part}_quartz_trim"
|
||||
path: "minecraft:item/custom/topaz_${part}_quartz_trim"
|
||||
generation:
|
||||
parent: "minecraft:item/generated"
|
||||
textures:
|
||||
"layer0": "minecraft:item/custom/topaz_{part}"
|
||||
"layer1": "minecraft:trims/items/{part}_trim_quartz"
|
||||
"layer0": "minecraft:item/custom/topaz_${part}"
|
||||
"layer1": "minecraft:trims/items/${part}_trim_quartz"
|
||||
- when: minecraft:iron
|
||||
model:
|
||||
type: minecraft:model
|
||||
path: "minecraft:item/custom/topaz_{part}_iron_trim"
|
||||
path: "minecraft:item/custom/topaz_${part}_iron_trim"
|
||||
generation:
|
||||
parent: "minecraft:item/generated"
|
||||
textures:
|
||||
"layer0": "minecraft:item/custom/topaz_{part}"
|
||||
"layer1": "minecraft:trims/items/{part}_trim_iron"
|
||||
"layer0": "minecraft:item/custom/topaz_${part}"
|
||||
"layer1": "minecraft:trims/items/${part}_trim_iron"
|
||||
- when: minecraft:netherite
|
||||
model:
|
||||
type: minecraft:model
|
||||
path: "minecraft:item/custom/topaz_{part}_netherite_trim"
|
||||
path: "minecraft:item/custom/topaz_${part}_netherite_trim"
|
||||
generation:
|
||||
parent: "minecraft:item/generated"
|
||||
textures:
|
||||
"layer0": "minecraft:item/custom/topaz_{part}"
|
||||
"layer1": "minecraft:trims/items/{part}_trim_netherite"
|
||||
"layer0": "minecraft:item/custom/topaz_${part}"
|
||||
"layer1": "minecraft:trims/items/${part}_trim_netherite"
|
||||
- when: minecraft:redstone
|
||||
model:
|
||||
type: minecraft:model
|
||||
path: "minecraft:item/custom/topaz_{part}_redstone_trim"
|
||||
path: "minecraft:item/custom/topaz_${part}_redstone_trim"
|
||||
generation:
|
||||
parent: "minecraft:item/generated"
|
||||
textures:
|
||||
"layer0": "minecraft:item/custom/topaz_{part}"
|
||||
"layer1": "minecraft:trims/items/{part}_trim_redstone"
|
||||
"layer0": "minecraft:item/custom/topaz_${part}"
|
||||
"layer1": "minecraft:trims/items/${part}_trim_redstone"
|
||||
- when: minecraft:copper
|
||||
model:
|
||||
type: minecraft:model
|
||||
path: "minecraft:item/custom/topaz_{part}_copper_trim"
|
||||
path: "minecraft:item/custom/topaz_${part}_copper_trim"
|
||||
generation:
|
||||
parent: "minecraft:item/generated"
|
||||
textures:
|
||||
"layer0": "minecraft:item/custom/topaz_{part}"
|
||||
"layer1": "minecraft:trims/items/{part}_trim_copper"
|
||||
"layer0": "minecraft:item/custom/topaz_${part}"
|
||||
"layer1": "minecraft:trims/items/${part}_trim_copper"
|
||||
- when: minecraft:gold
|
||||
model:
|
||||
type: minecraft:model
|
||||
path: "minecraft:item/custom/topaz_{part}_gold_trim"
|
||||
path: "minecraft:item/custom/topaz_${part}_gold_trim"
|
||||
generation:
|
||||
parent: "minecraft:item/generated"
|
||||
textures:
|
||||
"layer0": "minecraft:item/custom/topaz_{part}"
|
||||
"layer1": "minecraft:trims/items/{part}_trim_gold"
|
||||
"layer0": "minecraft:item/custom/topaz_${part}"
|
||||
"layer1": "minecraft:trims/items/${part}_trim_gold"
|
||||
- when: minecraft:emerald
|
||||
model:
|
||||
type: minecraft:model
|
||||
path: "minecraft:item/custom/topaz_{part}_emerald_trim"
|
||||
path: "minecraft:item/custom/topaz_${part}_emerald_trim"
|
||||
generation:
|
||||
parent: "minecraft:item/generated"
|
||||
textures:
|
||||
"layer0": "minecraft:item/custom/topaz_{part}"
|
||||
"layer1": "minecraft:trims/items/{part}_trim_emerald"
|
||||
"layer0": "minecraft:item/custom/topaz_${part}"
|
||||
"layer1": "minecraft:trims/items/${part}_trim_emerald"
|
||||
- when: minecraft:diamond
|
||||
model:
|
||||
type: minecraft:model
|
||||
path: "minecraft:item/custom/topaz_{part}_diamond_trim"
|
||||
path: "minecraft:item/custom/topaz_${part}_diamond_trim"
|
||||
generation:
|
||||
parent: "minecraft:item/generated"
|
||||
textures:
|
||||
"layer0": "minecraft:item/custom/topaz_{part}"
|
||||
"layer1": "minecraft:trims/items/{part}_trim_diamond"
|
||||
"layer0": "minecraft:item/custom/topaz_${part}"
|
||||
"layer1": "minecraft:trims/items/${part}_trim_diamond"
|
||||
- when: minecraft:lapis
|
||||
model:
|
||||
type: minecraft:model
|
||||
path: "minecraft:item/custom/topaz_{part}_lapis_trim"
|
||||
path: "minecraft:item/custom/topaz_${part}_lapis_trim"
|
||||
generation:
|
||||
parent: "minecraft:item/generated"
|
||||
textures:
|
||||
"layer0": "minecraft:item/custom/topaz_{part}"
|
||||
"layer1": "minecraft:trims/items/{part}_trim_lapis"
|
||||
"layer0": "minecraft:item/custom/topaz_${part}"
|
||||
"layer1": "minecraft:trims/items/${part}_trim_lapis"
|
||||
- when: minecraft:amethyst
|
||||
model:
|
||||
type: minecraft:model
|
||||
path: "minecraft:item/custom/topaz_{part}_amethyst_trim"
|
||||
path: "minecraft:item/custom/topaz_${part}_amethyst_trim"
|
||||
generation:
|
||||
parent: "minecraft:item/generated"
|
||||
textures:
|
||||
"layer0": "minecraft:item/custom/topaz_{part}"
|
||||
"layer1": "minecraft:trims/items/{part}_trim_amethyst"
|
||||
"layer0": "minecraft:item/custom/topaz_${part}"
|
||||
"layer1": "minecraft:trims/items/${part}_trim_amethyst"
|
||||
- when: minecraft:resin
|
||||
model:
|
||||
type: minecraft:model
|
||||
path: "minecraft:item/custom/topaz_{part}_resin_trim"
|
||||
path: "minecraft:item/custom/topaz_${part}_resin_trim"
|
||||
generation:
|
||||
parent: "minecraft:item/generated"
|
||||
textures:
|
||||
"layer0": "minecraft:item/custom/topaz_{part}"
|
||||
"layer1": "minecraft:trims/items/{part}_trim_resin"
|
||||
"layer0": "minecraft:item/custom/topaz_${part}"
|
||||
"layer1": "minecraft:trims/items/${part}_trim_resin"
|
||||
|
||||
recipes#11:
|
||||
default:topaz_shovel:
|
||||
|
||||
@@ -7,32 +7,32 @@ templates#models#block:
|
||||
# model: model_path
|
||||
# texture: texture_path
|
||||
default:model/cube_all:
|
||||
path: "{model}"
|
||||
path: "${model}"
|
||||
generation:
|
||||
parent: "minecraft:block/cube_all"
|
||||
textures:
|
||||
"all": "{texture}"
|
||||
"all": "${texture}"
|
||||
# template: default:model/simplified_cube_all
|
||||
# arguments:
|
||||
# path: [model/texture]_path
|
||||
default:model/simplified_cube_all:
|
||||
path: "{path}"
|
||||
path: "${path}"
|
||||
generation:
|
||||
parent: "minecraft:block/cube_all"
|
||||
textures:
|
||||
"all": "{path}"
|
||||
"all": "${path}"
|
||||
# template: default:model/cube_column
|
||||
# arguments:
|
||||
# model: model_path
|
||||
# end_texture: end_texture_path
|
||||
# side_texture: side_texture_path
|
||||
default:model/cube_column:
|
||||
path: "{model}"
|
||||
path: "${model}"
|
||||
generation:
|
||||
parent: "minecraft:block/cube_column"
|
||||
textures:
|
||||
"end": "{end_texture}"
|
||||
"side": "{side_texture}"
|
||||
"end": "${end_texture}"
|
||||
"side": "${side_texture}"
|
||||
# template: default:model/cube
|
||||
# arguments:
|
||||
# model: model_path
|
||||
@@ -44,7 +44,7 @@ templates#models#block:
|
||||
# south_texture: south_texture_path
|
||||
# west_texture: west_texture_path
|
||||
default:model/cube:
|
||||
path: "{model}"
|
||||
path: "${model}"
|
||||
generation:
|
||||
parent: "minecraft:block/cube_column"
|
||||
textures:
|
||||
@@ -64,21 +64,21 @@ templates#models#2d:
|
||||
# texture: texture_path
|
||||
default:model/generated:
|
||||
type: "minecraft:model"
|
||||
path: "{model}"
|
||||
path: "${model}"
|
||||
generation:
|
||||
parent: "minecraft:item/generated"
|
||||
textures:
|
||||
"layer0": "{texture}"
|
||||
"layer0": "${texture}"
|
||||
# template: default:model/simplified_generated
|
||||
# arguments:
|
||||
# path: [model/texture]_path
|
||||
default:model/simplified_generated:
|
||||
type: "minecraft:model"
|
||||
path: "{path}"
|
||||
path: "${path}"
|
||||
generation:
|
||||
parent: "minecraft:item/generated"
|
||||
textures:
|
||||
"layer0": "{path}"
|
||||
"layer0": "${path}"
|
||||
# template: default:model/2_layer_generated
|
||||
# arguments:
|
||||
# model: model_path
|
||||
@@ -86,33 +86,33 @@ templates#models#2d:
|
||||
# layer1: texture_path
|
||||
default:model/2_layer_generated:
|
||||
type: "minecraft:model"
|
||||
path: "{model}"
|
||||
path: "${model}"
|
||||
generation:
|
||||
parent: "minecraft:item/generated"
|
||||
textures:
|
||||
"layer0": "{layer0}"
|
||||
"layer1": "{layer1}"
|
||||
"layer0": "${layer0}"
|
||||
"layer1": "${layer1}"
|
||||
# template: default:model/handheld
|
||||
# arguments:
|
||||
# model: model_path
|
||||
# texture: texture_path
|
||||
default:model/handheld:
|
||||
type: "minecraft:model"
|
||||
path: "{model}"
|
||||
path: "${model}"
|
||||
generation:
|
||||
parent: "minecraft:item/handheld"
|
||||
textures:
|
||||
"layer0": "{texture}"
|
||||
"layer0": "${texture}"
|
||||
# template: default:model/simplified_handheld
|
||||
# arguments:
|
||||
# path: [model/texture]_path
|
||||
default:model/simplified_handheld:
|
||||
type: "minecraft:model"
|
||||
path: "{path}"
|
||||
path: "${path}"
|
||||
generation:
|
||||
parent: "minecraft:item/handheld"
|
||||
textures:
|
||||
"layer0": "{path}"
|
||||
"layer0": "${path}"
|
||||
# template: default:model/elytra
|
||||
# arguments:
|
||||
# model: model_path
|
||||
@@ -123,17 +123,17 @@ templates#models#2d:
|
||||
type: "minecraft:condition"
|
||||
property: minecraft:broken
|
||||
on-false:
|
||||
path: "{model}"
|
||||
path: "${model}"
|
||||
generation:
|
||||
parent: "minecraft:item/generated"
|
||||
textures:
|
||||
"layer0": "{texture}"
|
||||
"layer0": "${texture}"
|
||||
on-true:
|
||||
path: "{broken_model}"
|
||||
path: "${broken_model}"
|
||||
generation:
|
||||
parent: "minecraft:item/generated"
|
||||
textures:
|
||||
"layer0": "{broken_texture}"
|
||||
"layer0": "${broken_texture}"
|
||||
# template: default:model/simplified_elytra
|
||||
# arguments:
|
||||
# path: [model/texture]_path
|
||||
@@ -141,10 +141,10 @@ templates#models#2d:
|
||||
default:model/simplified_elytra:
|
||||
template: default:model/elytra
|
||||
arguments:
|
||||
model: "{path}"
|
||||
texture: "{path}"
|
||||
broken_model: "{broken_path}"
|
||||
broken_texture: "{broken_path}"
|
||||
model: "${path}"
|
||||
texture: "${path}"
|
||||
broken_model: "${broken_path}"
|
||||
broken_texture: "${broken_path}"
|
||||
|
||||
# shield
|
||||
templates#models#shield:
|
||||
@@ -157,10 +157,10 @@ templates#models#shield:
|
||||
property: "minecraft:using_item"
|
||||
on-false:
|
||||
type: minecraft:model
|
||||
path: "{model}"
|
||||
path: "${model}"
|
||||
on-true:
|
||||
type: minecraft:model
|
||||
path: "{block_model}"
|
||||
path: "${block_model}"
|
||||
|
||||
# fishing rods
|
||||
templates#models#fishing_rod:
|
||||
@@ -173,10 +173,10 @@ templates#models#fishing_rod:
|
||||
property: "minecraft:fishing_rod/cast"
|
||||
on-false:
|
||||
type: "minecraft:model"
|
||||
path: "{model}"
|
||||
path: "${model}"
|
||||
on-true:
|
||||
type: "minecraft:model"
|
||||
path: "{cast_model}"
|
||||
path: "${cast_model}"
|
||||
# template: default:model/fishing_rod_2d
|
||||
# arguments:
|
||||
# model: rod_model_path
|
||||
@@ -188,18 +188,18 @@ templates#models#fishing_rod:
|
||||
property: "minecraft:fishing_rod/cast"
|
||||
on-false:
|
||||
type: "minecraft:model"
|
||||
path: "{model}"
|
||||
path: "${model}"
|
||||
generation:
|
||||
parent: "minecraft:item/fishing_rod"
|
||||
textures:
|
||||
"layer0": "{texture}"
|
||||
"layer0": "${texture}"
|
||||
on-true:
|
||||
type: "minecraft:model"
|
||||
path: "{cast_model}"
|
||||
path: "${cast_model}"
|
||||
generation:
|
||||
parent: "minecraft:item/fishing_rod"
|
||||
textures:
|
||||
"layer0": "{cast_texture}"
|
||||
"layer0": "${cast_texture}"
|
||||
# template: default:model/simplified_fishing_rod_2d
|
||||
# arguments:
|
||||
# path: rod_[model/texture]_path
|
||||
@@ -207,10 +207,10 @@ templates#models#fishing_rod:
|
||||
default:model/simplified_fishing_rod_2d:
|
||||
template: default:model/fishing_rod_2d
|
||||
arguments:
|
||||
texture: "{path}"
|
||||
model: "{path}"
|
||||
cast_texture: "{cast_path}"
|
||||
cast_model: "{cast_path}"
|
||||
texture: "${path}"
|
||||
model: "${path}"
|
||||
cast_texture: "${cast_path}"
|
||||
cast_model: "${cast_path}"
|
||||
|
||||
# bows
|
||||
templates#models#bow:
|
||||
@@ -225,7 +225,7 @@ templates#models#bow:
|
||||
property: "minecraft:using_item"
|
||||
on-false:
|
||||
type: "minecraft:model"
|
||||
path: "{model}"
|
||||
path: "${model}"
|
||||
on-true:
|
||||
type: "minecraft:range_dispatch"
|
||||
property: "minecraft:use_duration"
|
||||
@@ -233,15 +233,15 @@ templates#models#bow:
|
||||
entries:
|
||||
- model:
|
||||
type: minecraft:model
|
||||
path: "{pulling_1_model}"
|
||||
path: "${pulling_1_model}"
|
||||
threshold: 0.65
|
||||
- model:
|
||||
type: minecraft:model
|
||||
path: "{pulling_2_model}"
|
||||
path: "${pulling_2_model}"
|
||||
threshold: 0.9
|
||||
fallback:
|
||||
type: minecraft:model
|
||||
path: "{pulling_0_model}"
|
||||
path: "${pulling_0_model}"
|
||||
# template: default:model/bow_2d
|
||||
# arguments:
|
||||
# model: bow_model_path
|
||||
@@ -257,11 +257,11 @@ templates#models#bow:
|
||||
property: "minecraft:using_item"
|
||||
on-false:
|
||||
type: "minecraft:model"
|
||||
path: "{model}"
|
||||
path: "${model}"
|
||||
generation:
|
||||
parent: "minecraft:item/bow"
|
||||
textures:
|
||||
"layer0": "{texture}"
|
||||
"layer0": "${texture}"
|
||||
on-true:
|
||||
type: "minecraft:range_dispatch"
|
||||
property: "minecraft:use_duration"
|
||||
@@ -269,27 +269,27 @@ templates#models#bow:
|
||||
entries:
|
||||
- model:
|
||||
type: minecraft:model
|
||||
path: "{pulling_1_model}"
|
||||
path: "${pulling_1_model}"
|
||||
generation:
|
||||
parent: "minecraft:item/bow_pulling_1"
|
||||
textures:
|
||||
"layer0": "{pulling_1_texture}"
|
||||
"layer0": "${pulling_1_texture}"
|
||||
threshold: 0.65
|
||||
- model:
|
||||
type: minecraft:model
|
||||
path: "{pulling_2_model}"
|
||||
path: "${pulling_2_model}"
|
||||
generation:
|
||||
parent: "minecraft:item/bow_pulling_2"
|
||||
textures:
|
||||
"layer0": "{pulling_2_texture}"
|
||||
"layer0": "${pulling_2_texture}"
|
||||
threshold: 0.9
|
||||
fallback:
|
||||
type: minecraft:model
|
||||
path: "{pulling_0_model}"
|
||||
path: "${pulling_0_model}"
|
||||
generation:
|
||||
parent: "minecraft:item/bow_pulling_0"
|
||||
textures:
|
||||
"layer0": "{pulling_0_texture}"
|
||||
"layer0": "${pulling_0_texture}"
|
||||
# template: default:model/simplified_bow_2d
|
||||
# arguments:
|
||||
# path: bow_[model/texture]_path
|
||||
@@ -299,14 +299,14 @@ templates#models#bow:
|
||||
default:model/simplified_bow_2d:
|
||||
template: default:model/bow_2d
|
||||
arguments:
|
||||
model: "{path}"
|
||||
pulling_0_model: "{pulling_0_path}"
|
||||
pulling_1_model: "{pulling_1_path}"
|
||||
pulling_2_model: "{pulling_2_path}"
|
||||
texture: "{path}"
|
||||
pulling_0_texture: "{pulling_0_path}"
|
||||
pulling_1_texture: "{pulling_1_path}"
|
||||
pulling_2_texture: "{pulling_2_path}"
|
||||
model: "${path}"
|
||||
pulling_0_model: "${pulling_0_path}"
|
||||
pulling_1_model: "${pulling_1_path}"
|
||||
pulling_2_model: "${pulling_2_path}"
|
||||
texture: "${path}"
|
||||
pulling_0_texture: "${pulling_0_path}"
|
||||
pulling_1_texture: "${pulling_1_path}"
|
||||
pulling_2_texture: "${pulling_2_path}"
|
||||
|
||||
# crossbows
|
||||
templates#models#crossbow:
|
||||
@@ -328,29 +328,29 @@ templates#models#crossbow:
|
||||
- when: arrow
|
||||
model:
|
||||
type: minecraft:model
|
||||
path: "{arrow_model}"
|
||||
path: "${arrow_model}"
|
||||
- when: rocket
|
||||
model:
|
||||
type: minecraft:model
|
||||
path: "{firework_model}"
|
||||
path: "${firework_model}"
|
||||
fallback:
|
||||
type: minecraft:model
|
||||
path: "{model}"
|
||||
path: "${model}"
|
||||
on-true:
|
||||
type: "minecraft:range_dispatch"
|
||||
property: "minecraft:crossbow/pull"
|
||||
entries:
|
||||
- model:
|
||||
type: minecraft:model
|
||||
path: "{pulling_1_model}"
|
||||
path: "${pulling_1_model}"
|
||||
threshold: 0.58
|
||||
- model:
|
||||
type: minecraft:model
|
||||
path: "{pulling_2_model}"
|
||||
path: "${pulling_2_model}"
|
||||
threshold: 1.0
|
||||
fallback:
|
||||
type: minecraft:model
|
||||
path: "{pulling_0_model}"
|
||||
path: "${pulling_0_model}"
|
||||
# template: default:model/crossbow_2d
|
||||
# arguments:
|
||||
# model: crossbow_model_path
|
||||
@@ -375,53 +375,53 @@ templates#models#crossbow:
|
||||
- when: arrow
|
||||
model:
|
||||
type: minecraft:model
|
||||
path: "{arrow_model}"
|
||||
path: "${arrow_model}"
|
||||
generation:
|
||||
parent: "minecraft:item/crossbow_arrow"
|
||||
textures:
|
||||
"layer0": "{arrow_texture}"
|
||||
"layer0": "${arrow_texture}"
|
||||
- when: rocket
|
||||
model:
|
||||
type: minecraft:model
|
||||
path: "{firework_model}"
|
||||
path: "${firework_model}"
|
||||
generation:
|
||||
parent: "minecraft:item/crossbow_firework"
|
||||
textures:
|
||||
"layer0": "{firework_texture}"
|
||||
"layer0": "${firework_texture}"
|
||||
fallback:
|
||||
type: minecraft:model
|
||||
path: "{model}"
|
||||
path: "${model}"
|
||||
generation:
|
||||
parent: "minecraft:item/crossbow"
|
||||
textures:
|
||||
"layer0": "{texture}"
|
||||
"layer0": "${texture}"
|
||||
on-true:
|
||||
type: "minecraft:range_dispatch"
|
||||
property: "minecraft:crossbow/pull"
|
||||
entries:
|
||||
- model:
|
||||
type: minecraft:model
|
||||
path: "{pulling_1_model}"
|
||||
path: "${pulling_1_model}"
|
||||
generation:
|
||||
parent: "minecraft:item/crossbow_pulling_1"
|
||||
textures:
|
||||
"layer0": "{pulling_1_texture}"
|
||||
"layer0": "${pulling_1_texture}"
|
||||
threshold: 0.58
|
||||
- model:
|
||||
type: minecraft:model
|
||||
path: "{pulling_2_model}"
|
||||
path: "${pulling_2_model}"
|
||||
generation:
|
||||
parent: "minecraft:item/crossbow_pulling_2"
|
||||
textures:
|
||||
"layer0": "{pulling_2_texture}"
|
||||
"layer0": "${pulling_2_texture}"
|
||||
threshold: 1.0
|
||||
fallback:
|
||||
type: minecraft:model
|
||||
path: "{pulling_0_model}"
|
||||
path: "${pulling_0_model}"
|
||||
generation:
|
||||
parent: "minecraft:item/crossbow_pulling_0"
|
||||
textures:
|
||||
"layer0": "{pulling_0_texture}"
|
||||
"layer0": "${pulling_0_texture}"
|
||||
# template: default:model/simplified_crossbow_2d
|
||||
# arguments:
|
||||
# path: crossbow_[model/texture]_path
|
||||
@@ -433,28 +433,28 @@ templates#models#crossbow:
|
||||
default:model/simplified_crossbow_2d:
|
||||
template: default:model/crossbow_2d
|
||||
arguments:
|
||||
model: "{path}"
|
||||
texture: "{path}"
|
||||
arrow_model: "{arrow_path}"
|
||||
arrow_texture: "{arrow_path}"
|
||||
firework_model: "{firework_path}"
|
||||
firework_texture: "{firework_path}"
|
||||
pulling_0_model: "{pulling_0_path}"
|
||||
pulling_0_texture: "{pulling_0_path}"
|
||||
pulling_1_model: "{pulling_1_path}"
|
||||
pulling_1_texture: "{pulling_1_path}"
|
||||
pulling_2_model: "{pulling_2_path}"
|
||||
pulling_2_texture: "{pulling_2_path}"
|
||||
model: "${path}"
|
||||
texture: "${path}"
|
||||
arrow_model: "${arrow_path}"
|
||||
arrow_texture: "${arrow_path}"
|
||||
firework_model: "${firework_path}"
|
||||
firework_texture: "${firework_path}"
|
||||
pulling_0_model: "${pulling_0_path}"
|
||||
pulling_0_texture: "${pulling_0_path}"
|
||||
pulling_1_model: "${pulling_1_path}"
|
||||
pulling_1_texture: "${pulling_1_path}"
|
||||
pulling_2_model: "${pulling_2_path}"
|
||||
pulling_2_texture: "${pulling_2_path}"
|
||||
|
||||
# sounds
|
||||
templates#settings#sounds:
|
||||
default:sound/block_template:
|
||||
sounds:
|
||||
break: "minecraft:block.{block_type}.break"
|
||||
step: "minecraft:block.{block_type}.step"
|
||||
place: "minecraft:block.{block_type}.place"
|
||||
hit: "minecraft:block.{block_type}.hit"
|
||||
fall: "minecraft:block.{block_type}.fall"
|
||||
break: "minecraft:block.${block_type}.break"
|
||||
step: "minecraft:block.${block_type}.step"
|
||||
place: "minecraft:block.${block_type}.place"
|
||||
hit: "minecraft:block.${block_type}.hit"
|
||||
fall: "minecraft:block.${block_type}.fall"
|
||||
default:sound/crop:
|
||||
sounds:
|
||||
break: "minecraft:block.crop.break"
|
||||
@@ -614,7 +614,7 @@ templates#settings#break_level:
|
||||
# block settings
|
||||
templates#settings#blocks:
|
||||
default:settings/middle_click_pick_itself:
|
||||
item: "{__NAMESPACE__}:{__ID__}"
|
||||
item: "${__NAMESPACE__}:${__ID__}"
|
||||
default:settings/solid_1x1x1:
|
||||
is-suffocating: true
|
||||
replaceable: false
|
||||
@@ -696,7 +696,7 @@ templates#settings#blocks:
|
||||
default:settings/ore:
|
||||
template:
|
||||
- "default:sound/stone"
|
||||
- "default:pickaxe_power/level_{break_power}"
|
||||
- "default:pickaxe_power/level_${break_power}"
|
||||
overrides:
|
||||
hardness: 3.0
|
||||
resistance: 3.0
|
||||
@@ -712,7 +712,7 @@ templates#settings#blocks:
|
||||
default:settings/deepslate_ore:
|
||||
template:
|
||||
- "default:sound/deepslate"
|
||||
- "default:pickaxe_power/level_{break_power}"
|
||||
- "default:pickaxe_power/level_${break_power}"
|
||||
overrides:
|
||||
hardness: 4.5
|
||||
resistance: 3.0
|
||||
@@ -735,45 +735,45 @@ templates#block_states:
|
||||
default: y
|
||||
appearances:
|
||||
axisY:
|
||||
state: "{base_block}:{vanilla_id}"
|
||||
state: "${base_block}:${vanilla_id}"
|
||||
model:
|
||||
path: "{model_vertical_path}"
|
||||
path: "${model_vertical_path}"
|
||||
generation:
|
||||
parent: "minecraft:block/cube_column"
|
||||
textures:
|
||||
"end": "{texture_top_path}"
|
||||
"side": "{texture_side_path}"
|
||||
"end": "${texture_top_path}"
|
||||
"side": "${texture_side_path}"
|
||||
axisX:
|
||||
state: "{base_block}:{vanilla_id}"
|
||||
state: "${base_block}:${vanilla_id}"
|
||||
model:
|
||||
x: 90
|
||||
y: 90
|
||||
path: "{model_horizontal_path}"
|
||||
path: "${model_horizontal_path}"
|
||||
generation:
|
||||
parent: "minecraft:block/cube_column_horizontal"
|
||||
textures:
|
||||
"end": "{texture_top_path}"
|
||||
"side": "{texture_side_path}"
|
||||
"end": "${texture_top_path}"
|
||||
"side": "${texture_side_path}"
|
||||
axisZ:
|
||||
state: "{base_block}:{vanilla_id}"
|
||||
state: "${base_block}:${vanilla_id}"
|
||||
model:
|
||||
x: 90
|
||||
path: "{model_horizontal_path}"
|
||||
path: "${model_horizontal_path}"
|
||||
generation:
|
||||
parent: "minecraft:block/cube_column_horizontal"
|
||||
textures:
|
||||
"end": "{texture_top_path}"
|
||||
"side": "{texture_side_path}"
|
||||
"end": "${texture_top_path}"
|
||||
"side": "${texture_side_path}"
|
||||
variants:
|
||||
axis=x:
|
||||
appearance: axisX
|
||||
id: "{internal_id}"
|
||||
id: "${internal_id}"
|
||||
axis=y:
|
||||
appearance: axisY
|
||||
id: "{internal_id}"
|
||||
id: "${internal_id}"
|
||||
axis=z:
|
||||
appearance: axisZ
|
||||
id: "{internal_id}"
|
||||
id: "${internal_id}"
|
||||
default:block_state/leaves:
|
||||
properties:
|
||||
waterlogged:
|
||||
@@ -788,107 +788,107 @@ templates#block_states:
|
||||
range: 1~7
|
||||
appearances:
|
||||
default:
|
||||
state: "{default_state}"
|
||||
state: "${default_state}"
|
||||
model:
|
||||
path: "{model_path}"
|
||||
path: "${model_path}"
|
||||
generation:
|
||||
parent: "minecraft:block/leaves"
|
||||
textures:
|
||||
"all": "{texture_path}"
|
||||
"all": "${texture_path}"
|
||||
waterlogged:
|
||||
state: "{waterlogged_state}"
|
||||
state: "${waterlogged_state}"
|
||||
model:
|
||||
path: "{model_path}"
|
||||
path: "${model_path}"
|
||||
variants:
|
||||
distance=1,persistent=false,waterlogged=false:
|
||||
appearance: "default"
|
||||
id: "{internal_id}"
|
||||
id: "${internal_id}"
|
||||
distance=2,persistent=false,waterlogged=false:
|
||||
appearance: "default"
|
||||
id: "{internal_id}"
|
||||
id: "${internal_id}"
|
||||
distance=3,persistent=false,waterlogged=false:
|
||||
appearance: "default"
|
||||
id: "{internal_id}"
|
||||
id: "${internal_id}"
|
||||
distance=4,persistent=false,waterlogged=false:
|
||||
appearance: "default"
|
||||
id: "{internal_id}"
|
||||
id: "${internal_id}"
|
||||
distance=5,persistent=false,waterlogged=false:
|
||||
appearance: "default"
|
||||
id: "{internal_id}"
|
||||
id: "${internal_id}"
|
||||
distance=6,persistent=false,waterlogged=false:
|
||||
appearance: "default"
|
||||
id: "{internal_id}"
|
||||
id: "${internal_id}"
|
||||
distance=7,persistent=false,waterlogged=false:
|
||||
appearance: "default"
|
||||
id: "{internal_id}"
|
||||
id: "${internal_id}"
|
||||
settings:
|
||||
is-randomly-ticking: true
|
||||
distance=1,persistent=true,waterlogged=false:
|
||||
appearance: "default"
|
||||
id: "{internal_id}"
|
||||
id: "${internal_id}"
|
||||
distance=2,persistent=true,waterlogged=false:
|
||||
appearance: "default"
|
||||
id: "{internal_id}"
|
||||
id: "${internal_id}"
|
||||
distance=3,persistent=true,waterlogged=false:
|
||||
appearance: "default"
|
||||
id: "{internal_id}"
|
||||
id: "${internal_id}"
|
||||
distance=4,persistent=true,waterlogged=false:
|
||||
appearance: "default"
|
||||
id: "{internal_id}"
|
||||
id: "${internal_id}"
|
||||
distance=5,persistent=true,waterlogged=false:
|
||||
appearance: "default"
|
||||
id: "{internal_id}"
|
||||
id: "${internal_id}"
|
||||
distance=6,persistent=true,waterlogged=false:
|
||||
appearance: "default"
|
||||
id: "{internal_id}"
|
||||
id: "${internal_id}"
|
||||
distance=7,persistent=true,waterlogged=false:
|
||||
appearance: "default"
|
||||
id: "{internal_id}"
|
||||
id: "${internal_id}"
|
||||
distance=1,persistent=false,waterlogged=true:
|
||||
appearance: "waterlogged"
|
||||
id: "{internal_id}"
|
||||
id: "${internal_id}"
|
||||
settings:
|
||||
resistance: 1200.0
|
||||
burnable: false
|
||||
fluid-state: water
|
||||
distance=2,persistent=false,waterlogged=true:
|
||||
appearance: "waterlogged"
|
||||
id: "{internal_id}"
|
||||
id: "${internal_id}"
|
||||
settings:
|
||||
resistance: 1200.0
|
||||
burnable: false
|
||||
fluid-state: water
|
||||
distance=3,persistent=false,waterlogged=true:
|
||||
appearance: "waterlogged"
|
||||
id: "{internal_id}"
|
||||
id: "${internal_id}"
|
||||
settings:
|
||||
resistance: 1200.0
|
||||
burnable: false
|
||||
fluid-state: water
|
||||
distance=4,persistent=false,waterlogged=true:
|
||||
appearance: "waterlogged"
|
||||
id: "{internal_id}"
|
||||
id: "${internal_id}"
|
||||
settings:
|
||||
resistance: 1200.0
|
||||
burnable: false
|
||||
fluid-state: water
|
||||
distance=5,persistent=false,waterlogged=true:
|
||||
appearance: "waterlogged"
|
||||
id: "{internal_id}"
|
||||
id: "${internal_id}"
|
||||
settings:
|
||||
resistance: 1200.0
|
||||
burnable: false
|
||||
fluid-state: water
|
||||
distance=6,persistent=false,waterlogged=true:
|
||||
appearance: "waterlogged"
|
||||
id: "{internal_id}"
|
||||
id: "${internal_id}"
|
||||
settings:
|
||||
resistance: 1200.0
|
||||
burnable: false
|
||||
fluid-state: water
|
||||
distance=7,persistent=false,waterlogged=true:
|
||||
appearance: "waterlogged"
|
||||
id: "{internal_id}"
|
||||
id: "${internal_id}"
|
||||
settings:
|
||||
resistance: 1200.0
|
||||
burnable: false
|
||||
@@ -896,49 +896,49 @@ templates#block_states:
|
||||
fluid-state: water
|
||||
distance=1,persistent=true,waterlogged=true:
|
||||
appearance: "waterlogged"
|
||||
id: "{internal_id}"
|
||||
id: "${internal_id}"
|
||||
settings:
|
||||
resistance: 1200.0
|
||||
burnable: false
|
||||
fluid-state: water
|
||||
distance=2,persistent=true,waterlogged=true:
|
||||
appearance: "waterlogged"
|
||||
id: "{internal_id}"
|
||||
id: "${internal_id}"
|
||||
settings:
|
||||
resistance: 1200.0
|
||||
burnable: false
|
||||
fluid-state: water
|
||||
distance=3,persistent=true,waterlogged=true:
|
||||
appearance: "waterlogged"
|
||||
id: "{internal_id}"
|
||||
id: "${internal_id}"
|
||||
settings:
|
||||
resistance: 1200.0
|
||||
burnable: false
|
||||
fluid-state: water
|
||||
distance=4,persistent=true,waterlogged=true:
|
||||
appearance: "waterlogged"
|
||||
id: "{internal_id}"
|
||||
id: "${internal_id}"
|
||||
settings:
|
||||
resistance: 1200.0
|
||||
burnable: false
|
||||
fluid-state: water
|
||||
distance=5,persistent=true,waterlogged=true:
|
||||
appearance: "waterlogged"
|
||||
id: "{internal_id}"
|
||||
id: "${internal_id}"
|
||||
settings:
|
||||
resistance: 1200.0
|
||||
burnable: false
|
||||
fluid-state: water
|
||||
distance=6,persistent=true,waterlogged=true:
|
||||
appearance: "waterlogged"
|
||||
id: "{internal_id}"
|
||||
id: "${internal_id}"
|
||||
settings:
|
||||
resistance: 1200.0
|
||||
burnable: false
|
||||
fluid-state: water
|
||||
distance=7,persistent=true,waterlogged=true:
|
||||
appearance: "waterlogged"
|
||||
id: "{internal_id}"
|
||||
id: "${internal_id}"
|
||||
settings:
|
||||
resistance: 1200.0
|
||||
burnable: false
|
||||
@@ -951,9 +951,9 @@ templates#recipes:
|
||||
category: building
|
||||
group: planks
|
||||
ingredients:
|
||||
A: "#default:{wood_type}_logs"
|
||||
A: "#default:${wood_type}_logs"
|
||||
result:
|
||||
id: "default:{wood_type}_planks"
|
||||
id: "default:${wood_type}_planks"
|
||||
count: 4
|
||||
default:recipe/log_2_wood:
|
||||
type: shaped
|
||||
@@ -963,29 +963,29 @@ templates#recipes:
|
||||
- "AA"
|
||||
- "AA"
|
||||
ingredients:
|
||||
A: "default:{wood_type}_log"
|
||||
A: "default:${wood_type}_log"
|
||||
result:
|
||||
id: "default:{wood_type}_wood"
|
||||
id: "default:${wood_type}_wood"
|
||||
count: 3
|
||||
default:recipe/smelting_ore:
|
||||
type: smelting
|
||||
experience: "{exp}"
|
||||
experience: "${exp}"
|
||||
category: misc
|
||||
group: topaz
|
||||
time: 200
|
||||
ingredient: "{ingredient}"
|
||||
ingredient: "${ingredient}"
|
||||
result:
|
||||
id: "{result}"
|
||||
id: "${result}"
|
||||
count: 1
|
||||
default:recipe/blasting_ore:
|
||||
type: blasting
|
||||
experience: "{exp}"
|
||||
experience: "${exp}"
|
||||
category: misc
|
||||
group: topaz
|
||||
time: 100
|
||||
ingredient: "{ingredient}"
|
||||
ingredient: "${ingredient}"
|
||||
result:
|
||||
id: "{result}"
|
||||
id: "${result}"
|
||||
count: 1
|
||||
|
||||
# loot tables
|
||||
@@ -1001,7 +1001,7 @@ templates#loot_tables:
|
||||
- type: survives_explosion
|
||||
entries:
|
||||
- type: item
|
||||
item: "{__NAMESPACE__}:{__ID__}"
|
||||
item: "${__NAMESPACE__}:${__ID__}"
|
||||
|
||||
# drop one item
|
||||
|
||||
@@ -1015,7 +1015,7 @@ templates#loot_tables:
|
||||
- type: survives_explosion
|
||||
entries:
|
||||
- type: item
|
||||
item: "{item}"
|
||||
item: "${item}"
|
||||
|
||||
# drop the original furniture item or a fallback item
|
||||
|
||||
@@ -1027,7 +1027,7 @@ templates#loot_tables:
|
||||
- rolls: 1
|
||||
entries:
|
||||
- type: furniture_item
|
||||
item: "{item}"
|
||||
item: "${item}"
|
||||
|
||||
# drop with silk touch
|
||||
|
||||
@@ -1042,7 +1042,7 @@ templates#loot_tables:
|
||||
predicate: minecraft:silk_touch>=1
|
||||
entries:
|
||||
- type: item
|
||||
item: "{item}"
|
||||
item: "${item}"
|
||||
|
||||
# crop drops
|
||||
|
||||
@@ -1058,21 +1058,21 @@ templates#loot_tables:
|
||||
- type: alternatives
|
||||
children:
|
||||
- type: item
|
||||
item: "{crop_item}"
|
||||
item: "${crop_item}"
|
||||
conditions:
|
||||
- type: match_block_property
|
||||
properties:
|
||||
age: "{ripe_age}"
|
||||
age: "${ripe_age}"
|
||||
- type: item
|
||||
item: "{crop_seed}"
|
||||
item: "${crop_seed}"
|
||||
- rolls: 1
|
||||
conditions:
|
||||
- type: match_block_property
|
||||
properties:
|
||||
age: "{ripe_age}"
|
||||
age: "${ripe_age}"
|
||||
entries:
|
||||
- type: item
|
||||
item: "{crop_seed}"
|
||||
item: "${crop_seed}"
|
||||
functions:
|
||||
- type: apply_bonus
|
||||
enchantment: minecraft:fortune
|
||||
@@ -1090,15 +1090,15 @@ templates#loot_tables:
|
||||
- rolls: 1
|
||||
entries:
|
||||
- type: item
|
||||
item: "{crop_item}"
|
||||
item: "${crop_item}"
|
||||
- rolls: 1
|
||||
conditions:
|
||||
- type: match_block_property
|
||||
properties:
|
||||
age: "{ripe_age}"
|
||||
age: "${ripe_age}"
|
||||
entries:
|
||||
- type: item
|
||||
item: "{crop_item}"
|
||||
item: "${crop_item}"
|
||||
functions:
|
||||
- type: apply_bonus
|
||||
enchantment: minecraft:fortune
|
||||
@@ -1122,12 +1122,12 @@ templates#loot_tables:
|
||||
- type: alternatives
|
||||
children:
|
||||
- type: item
|
||||
item: "{ore_block}"
|
||||
item: "${ore_block}"
|
||||
conditions:
|
||||
- type: enchantment
|
||||
predicate: minecraft:silk_touch>=1
|
||||
- type: item
|
||||
item: "{ore_drop}"
|
||||
item: "${ore_drop}"
|
||||
functions:
|
||||
- type: apply_bonus
|
||||
enchantment: minecraft:fortune
|
||||
@@ -1137,8 +1137,8 @@ templates#loot_tables:
|
||||
- type: drop_exp
|
||||
count:
|
||||
type: uniform
|
||||
min: "{min_exp}"
|
||||
max: "{max_exp}"
|
||||
min: "${min_exp:-2}"
|
||||
max: "${max_exp:-4}"
|
||||
|
||||
# template: default:loot_table/ore_no_exp
|
||||
# arguments:
|
||||
@@ -1151,12 +1151,12 @@ templates#loot_tables:
|
||||
- type: alternatives
|
||||
children:
|
||||
- type: item
|
||||
item: "{ore_block}"
|
||||
item: "${ore_block}"
|
||||
conditions:
|
||||
- type: enchantment
|
||||
predicate: minecraft:silk_touch>=1
|
||||
- type: item
|
||||
item: "{ore_drop}"
|
||||
item: "${ore_drop}"
|
||||
functions:
|
||||
- type: apply_bonus
|
||||
enchantment: minecraft:fortune
|
||||
@@ -1177,7 +1177,7 @@ templates#loot_tables:
|
||||
- type: alternatives
|
||||
children:
|
||||
- type: item
|
||||
item: "{leaves}"
|
||||
item: "${leaves}"
|
||||
conditions:
|
||||
- type: any_of
|
||||
terms:
|
||||
@@ -1186,7 +1186,7 @@ templates#loot_tables:
|
||||
- type: enchantment
|
||||
predicate: minecraft:silk_touch>=1
|
||||
- type: item
|
||||
item: "{sapling}"
|
||||
item: "${sapling}"
|
||||
conditions:
|
||||
- type: survives_explosion
|
||||
- type: table_bonus
|
||||
|
||||
@@ -69,21 +69,21 @@ images:
|
||||
templates:
|
||||
internal:icon/2d:
|
||||
material: arrow
|
||||
custom-model-data: "{model_data}"
|
||||
custom-model-data: "${model_data}"
|
||||
data:
|
||||
item-name: "{name}"
|
||||
lore: "{lore}"
|
||||
item-name: "${name}"
|
||||
lore: "${lore}"
|
||||
model:
|
||||
template: "internal:model/simplified_generated"
|
||||
arguments:
|
||||
path: "minecraft:item/custom/gui/{texture}"
|
||||
path: "minecraft:item/custom/gui/${texture}"
|
||||
internal:model/simplified_generated:
|
||||
type: "minecraft:model"
|
||||
path: "{path}"
|
||||
path: "${path}"
|
||||
generation:
|
||||
parent: "minecraft:item/generated"
|
||||
textures:
|
||||
"layer0": "{path}"
|
||||
"layer0": "${path}"
|
||||
|
||||
items:
|
||||
internal:next_page_0:
|
||||
|
||||
@@ -159,7 +159,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.invalid_component: "<yellow>Issue found in file <arg:0> - The item '<arg:1>' is using a non-existing component type '<arg:2>'.</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>"
|
||||
|
||||
@@ -159,7 +159,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.invalid_component: "<yellow>在文件 <arg:0> 发现问题 - 物品 '<arg:1>' 使用了未知的数据组件 '<arg:2>'</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>"
|
||||
|
||||
@@ -5,8 +5,10 @@ import net.momirealms.craftengine.core.entity.AbstractEntity;
|
||||
import net.momirealms.craftengine.core.item.Item;
|
||||
import net.momirealms.craftengine.core.plugin.context.CooldownData;
|
||||
import net.momirealms.craftengine.core.plugin.network.NetWorkUser;
|
||||
import net.momirealms.craftengine.core.sound.SoundSource;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.world.BlockPos;
|
||||
import net.momirealms.craftengine.core.world.Position;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
@@ -81,7 +83,13 @@ public abstract class Player extends AbstractEntity implements NetWorkUser {
|
||||
playSound(sound, 1f, 1f);
|
||||
}
|
||||
|
||||
public abstract void playSound(Key sound, float volume, float pitch);
|
||||
public void playSound(Key sound, float volume, float pitch) {
|
||||
playSound(sound, SoundSource.MASTER, volume, pitch);
|
||||
}
|
||||
|
||||
public abstract void playSound(Key sound, SoundSource source, float volume, float pitch);
|
||||
|
||||
public abstract void playSound(Key sound, BlockPos pos, SoundSource source, float volume, float pitch);
|
||||
|
||||
public abstract void giveItem(Item<?> item);
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import net.momirealms.craftengine.core.util.Key;
|
||||
|
||||
public class ItemKeys {
|
||||
public static final Key AIR = Key.of("minecraft:air");
|
||||
public static final Key FLINT_AND_STEEL = Key.of("minecraft:flint_and_steel");
|
||||
public static final Key STONE = Key.of("minecraft:stone");
|
||||
public static final Key TRIDENT = Key.of("minecraft:trident");
|
||||
public static final Key SHIELD = Key.of("minecraft:shield");
|
||||
|
||||
@@ -34,6 +34,7 @@ public class ItemSettings {
|
||||
Helmet helmet = null;
|
||||
FoodData foodData = null;
|
||||
Key consumeReplacement = null;
|
||||
Key craftRemainder = null;
|
||||
List<DamageCause> invulnerable = List.of();
|
||||
|
||||
private ItemSettings() {}
|
||||
@@ -72,6 +73,7 @@ public class ItemSettings {
|
||||
newSettings.helmet = settings.helmet;
|
||||
newSettings.foodData = settings.foodData;
|
||||
newSettings.consumeReplacement = settings.consumeReplacement;
|
||||
newSettings.craftRemainder = settings.craftRemainder;
|
||||
newSettings.invulnerable = settings.invulnerable;
|
||||
return newSettings;
|
||||
}
|
||||
@@ -130,6 +132,11 @@ public class ItemSettings {
|
||||
return consumeReplacement;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Key craftRemainder() {
|
||||
return craftRemainder;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Helmet helmet() {
|
||||
return helmet;
|
||||
@@ -154,6 +161,11 @@ public class ItemSettings {
|
||||
return this;
|
||||
}
|
||||
|
||||
public ItemSettings craftRemainder(Key key) {
|
||||
this.craftRemainder = key;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ItemSettings canRepair(boolean canRepair) {
|
||||
this.canRepair = canRepair;
|
||||
return this;
|
||||
@@ -248,7 +260,14 @@ public class ItemSettings {
|
||||
int intValue = ResourceConfigUtils.getAsInt(value, "fuel-time");
|
||||
return settings -> settings.fuelTime(intValue);
|
||||
}));
|
||||
registerFactory("consume-replacement", (value -> settings -> settings.consumeReplacement(Key.of(value.toString()))));
|
||||
registerFactory("consume-replacement", (value -> settings -> {
|
||||
if (value == null) settings.consumeReplacement(null);
|
||||
else settings.consumeReplacement(Key.of(value.toString()));
|
||||
}));
|
||||
registerFactory("craft-remaining-item", (value -> settings -> {
|
||||
if (value == null) settings.craftRemainder(null);
|
||||
else settings.craftRemainder(Key.of(value.toString()));
|
||||
}));
|
||||
registerFactory("tags", (value -> {
|
||||
List<String> tags = MiscUtils.getAsStringList(value);
|
||||
return settings -> settings.tags(tags.stream().map(Key::of).collect(Collectors.toSet()));
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package net.momirealms.craftengine.core.pack;
|
||||
|
||||
import com.google.common.collect.*;
|
||||
import com.google.common.collect.ArrayListMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.jimfs.Configuration;
|
||||
import com.google.common.jimfs.Jimfs;
|
||||
import com.google.gson.*;
|
||||
@@ -21,7 +22,6 @@ import net.momirealms.craftengine.core.pack.model.LegacyOverridesModel;
|
||||
import net.momirealms.craftengine.core.pack.model.generation.ModelGeneration;
|
||||
import net.momirealms.craftengine.core.pack.model.generation.ModelGenerator;
|
||||
import net.momirealms.craftengine.core.pack.obfuscation.ObfA;
|
||||
import net.momirealms.craftengine.core.pack.obfuscation.ObfH;
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
import net.momirealms.craftengine.core.plugin.config.Config;
|
||||
import net.momirealms.craftengine.core.plugin.config.ConfigParser;
|
||||
|
||||
@@ -50,7 +50,7 @@ public class ExpressionTemplateArgument implements TemplateArgument {
|
||||
}
|
||||
|
||||
public Function<EvaluationValue, Object> formatter() {
|
||||
return formatter;
|
||||
return this.formatter;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -66,16 +66,17 @@ public interface TemplateManager extends Manageable {
|
||||
private final String rawText;
|
||||
private final Object defaultValue;
|
||||
|
||||
public Placeholder(String placeholder) {
|
||||
this.rawText = "{" + placeholder + "}";
|
||||
int first = placeholder.indexOf(':');
|
||||
if (first == -1) {
|
||||
this.placeholder = placeholder;
|
||||
public Placeholder(String placeholderContent) {
|
||||
this.rawText = "${" + placeholderContent + "}";
|
||||
int separatorIndex = placeholderContent.indexOf(":-");
|
||||
if (separatorIndex == -1) {
|
||||
this.placeholder = placeholderContent;
|
||||
this.defaultValue = this.rawText;
|
||||
} else {
|
||||
this.placeholder = placeholder.substring(0, first);
|
||||
this.placeholder = placeholderContent.substring(0, separatorIndex);
|
||||
String defaultValueString = placeholderContent.substring(separatorIndex + 2);
|
||||
try {
|
||||
this.defaultValue = CraftEngine.instance().platform().nbt2Java(placeholder.substring(first + 1));
|
||||
this.defaultValue = CraftEngine.instance().platform().nbt2Java(defaultValueString);
|
||||
} catch (LocalizedResourceConfigException e) {
|
||||
e.appendTailArgument(this.placeholder);
|
||||
throw e;
|
||||
@@ -220,42 +221,33 @@ public interface TemplateManager extends Manageable {
|
||||
while (i < n) {
|
||||
char c = input.charAt(i);
|
||||
|
||||
// --- 1. 处理转义字符 ---
|
||||
if (c == '\\') {
|
||||
// 只在'\'后面是'{'或'}'时才作为转义处理
|
||||
if (i + 1 < n && (input.charAt(i + 1) == '{' || input.charAt(i + 1) == '}')) {
|
||||
currentLiteral.append(input.charAt(i + 1)); // 添加花括号
|
||||
i += 2; // 跳过'\'和花括号
|
||||
} else {
|
||||
// 对于所有其他情况 (如 \\, \n), 将'\'视为普通字符
|
||||
currentLiteral.append(c);
|
||||
i++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// --- 1. 优先检测占位符触发器 ---
|
||||
if (c == '$' && i + 1 < n && input.charAt(i + 1) == '{') {
|
||||
|
||||
// --- 2. 处理占位符 {key} ---
|
||||
if (c == '{') {
|
||||
// 如果在占位符之前有普通文本,先提交它
|
||||
// a. 提交之前的普通文本
|
||||
if (!currentLiteral.isEmpty()) {
|
||||
arguments.add(Literal.literal(currentLiteral.toString()));
|
||||
currentLiteral.setLength(0); // 清空
|
||||
currentLiteral.setLength(0);
|
||||
}
|
||||
|
||||
// 开始解析占位符内部
|
||||
// b. 解析占位符内部,此处的逻辑拥有自己的转义规则
|
||||
int contentStartIndex = i + 2;
|
||||
StringBuilder keyBuilder = new StringBuilder();
|
||||
int depth = 1;
|
||||
int j = i + 1;
|
||||
int j = contentStartIndex;
|
||||
boolean foundMatch = false;
|
||||
|
||||
while (j < n) {
|
||||
char innerChar = input.charAt(j);
|
||||
if (innerChar == '\\') { // 处理占位符内部的转义
|
||||
|
||||
// --- 占位符内部的转义逻辑 ---
|
||||
if (innerChar == '\\') {
|
||||
if (j + 1 < n && (input.charAt(j + 1) == '{' || input.charAt(j + 1) == '}')) {
|
||||
keyBuilder.append(input.charAt(j + 1));
|
||||
j += 2;
|
||||
} else {
|
||||
keyBuilder.append(innerChar); // 将'\'视为普通字符
|
||||
// 在占位符内部,一个无法识别的转义\依旧被当作普通\处理
|
||||
keyBuilder.append(innerChar);
|
||||
j++;
|
||||
}
|
||||
} else if (innerChar == '{') {
|
||||
@@ -266,11 +258,11 @@ public interface TemplateManager extends Manageable {
|
||||
depth--;
|
||||
if (depth == 0) { // 找到匹配的闭合括号
|
||||
arguments.add(Placeholder.placeholder(keyBuilder.toString()));
|
||||
i = j + 1; // 将主循环的索引跳到占位符之后
|
||||
i = j + 1;
|
||||
foundMatch = true;
|
||||
break;
|
||||
}
|
||||
keyBuilder.append(innerChar); // 嵌套的 '}'
|
||||
keyBuilder.append(innerChar);
|
||||
j++;
|
||||
} else {
|
||||
keyBuilder.append(innerChar);
|
||||
@@ -279,27 +271,31 @@ public interface TemplateManager extends Manageable {
|
||||
}
|
||||
|
||||
if (foundMatch) {
|
||||
continue; // 成功解析占位符,继续主循环
|
||||
continue;
|
||||
} else {
|
||||
// 没有找到匹配的 '}',将起始的 '{' 视为普通文本
|
||||
// 未找到闭合括号,将 '$' 视为普通字符
|
||||
currentLiteral.append(c);
|
||||
i++;
|
||||
}
|
||||
} else {
|
||||
// --- 3. 处理普通字符 ---
|
||||
}
|
||||
// --- 2. 其次,只处理对触发器'$'的转义 ---
|
||||
else if (c == '\\' && i + 1 < n && input.charAt(i + 1) == '$') {
|
||||
currentLiteral.append('$'); // 直接添加 '$'
|
||||
i += 2; // 跳过 '\' 和 '$'
|
||||
}
|
||||
// --- 3. 处理所有其他字符(包括独立的'\'和'{')为普通文本 ---
|
||||
else {
|
||||
currentLiteral.append(c);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
// 添加循环结束后剩余的任何普通文本
|
||||
if (!currentLiteral.isEmpty()) {
|
||||
arguments.add(Literal.literal(currentLiteral.toString()));
|
||||
}
|
||||
|
||||
// 根据解析出的参数数量返回最终结果
|
||||
return switch (arguments.size()) {
|
||||
case 0 -> Literal.literal(""); // 处理 input = "{}" 等情况
|
||||
case 0 -> Literal.literal("");
|
||||
case 1 -> arguments.getFirst();
|
||||
case 2 -> new Complex2(input, arguments.get(0), arguments.get(1));
|
||||
default -> new Complex(input, arguments);
|
||||
|
||||
@@ -33,7 +33,7 @@ public abstract class AbstractCommonContext implements Context {
|
||||
public TagResolver[] tagResolvers() {
|
||||
if (this.tagResolvers == null) {
|
||||
this.tagResolvers = new TagResolver[]{ShiftTag.INSTANCE, ImageTag.INSTANCE, new I18NTag(this), new NamedArgumentTag(this),
|
||||
new PlaceholderTag(null), new ExpressionTag(this), new GlobalVariableTag(this)};
|
||||
new PlaceholderTag(this), new ExpressionTag(this), new GlobalVariableTag(this)};
|
||||
}
|
||||
return this.tagResolvers;
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ public class PlayerOptionalContext extends AbstractChainParameterContext impleme
|
||||
@NotNull
|
||||
public TagResolver[] tagResolvers() {
|
||||
if (this.tagResolvers == null) {
|
||||
this.tagResolvers = new TagResolver[]{ShiftTag.INSTANCE, ImageTag.INSTANCE, new PlaceholderTag(this.player), new I18NTag(this),
|
||||
this.tagResolvers = new TagResolver[]{ShiftTag.INSTANCE, ImageTag.INSTANCE, new PlaceholderTag(this), new I18NTag(this),
|
||||
new NamedArgumentTag(this), new ExpressionTag(this), new GlobalVariableTag(this)};
|
||||
}
|
||||
return this.tagResolvers;
|
||||
|
||||
@@ -53,19 +53,15 @@ public class ViewerContext implements RelationalContext {
|
||||
@Override
|
||||
public TagResolver[] tagResolvers() {
|
||||
if (this.tagResolvers == null) {
|
||||
Player optionalOwner = null;
|
||||
if (this.owner instanceof PlayerOptionalContext context) {
|
||||
optionalOwner = context.player();
|
||||
}
|
||||
if (optionalOwner != null && this.viewer.player != null) {
|
||||
this.tagResolvers = new TagResolver[]{new RelationalPlaceholderTag(optionalOwner, this.viewer.player),
|
||||
if (this.owner instanceof PlayerOptionalContext context && context.player != null && this.viewer.player != null) {
|
||||
this.tagResolvers = new TagResolver[]{new RelationalPlaceholderTag(context.player, this.viewer.player, this),
|
||||
ShiftTag.INSTANCE, ImageTag.INSTANCE,
|
||||
new PlaceholderTag(optionalOwner), new ViewerPlaceholderTag(this.viewer.player()),
|
||||
new PlaceholderTag(this.owner), new ViewerPlaceholderTag(this.viewer),
|
||||
new NamedArgumentTag(this.owner), new ViewerNamedArgumentTag(this.viewer),
|
||||
new I18NTag(this), new ExpressionTag(this), new GlobalVariableTag(this)};
|
||||
} else {
|
||||
this.tagResolvers = new TagResolver[]{ShiftTag.INSTANCE, ImageTag.INSTANCE,
|
||||
new PlaceholderTag(optionalOwner), new ViewerPlaceholderTag(this.viewer.player()),
|
||||
new PlaceholderTag(this.owner), new ViewerPlaceholderTag(this.viewer),
|
||||
new NamedArgumentTag(this.owner), new ViewerNamedArgumentTag(this.viewer),
|
||||
new I18NTag(this), new ExpressionTag(this), new GlobalVariableTag(this)};
|
||||
}
|
||||
|
||||
@@ -16,4 +16,7 @@ public interface EntityPacketHandler {
|
||||
|
||||
default void handleMoveAndRotate(NetWorkUser user, NMSPacketEvent event, Object packet) {
|
||||
}
|
||||
|
||||
default void handleMove(NetWorkUser user, NMSPacketEvent event, Object packet) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,17 +5,17 @@ import net.kyori.adventure.text.minimessage.ParsingException;
|
||||
import net.kyori.adventure.text.minimessage.tag.Tag;
|
||||
import net.kyori.adventure.text.minimessage.tag.resolver.ArgumentQueue;
|
||||
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
|
||||
import net.momirealms.craftengine.core.entity.player.Player;
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
import net.momirealms.craftengine.core.plugin.context.PlayerOptionalContext;
|
||||
import net.momirealms.craftengine.core.util.AdventureHelper;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class PlaceholderTag implements TagResolver {
|
||||
private final Player player;
|
||||
private final net.momirealms.craftengine.core.plugin.context.Context context;
|
||||
|
||||
public PlaceholderTag(@Nullable Player player) {
|
||||
this.player = player;
|
||||
public PlaceholderTag(@NotNull net.momirealms.craftengine.core.plugin.context.Context context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -23,8 +23,10 @@ public class PlaceholderTag implements TagResolver {
|
||||
if (!this.has(name) || !CraftEngine.instance().compatibilityManager().hasPlaceholderAPI()) {
|
||||
return null;
|
||||
}
|
||||
String placeholder = "%" + arguments.popOr("No argument placeholder provided") + "%";
|
||||
String parsed = CraftEngine.instance().compatibilityManager().parse(player, placeholder);
|
||||
String rawArgument = arguments.popOr("No argument relational placeholder provided").toString();
|
||||
if (rawArgument.contains("<")) rawArgument = AdventureHelper.resolvePlainStringTags(rawArgument, this.context.tagResolvers());
|
||||
String placeholder = "%" + rawArgument + "%";
|
||||
String parsed = this.context instanceof PlayerOptionalContext playerOptionalContext ? CraftEngine.instance().compatibilityManager().parse(playerOptionalContext.player(), placeholder) : CraftEngine.instance().compatibilityManager().parse(null, placeholder);
|
||||
if (parsed.equals(placeholder)) {
|
||||
parsed = arguments.popOr("No default papi value provided").toString();
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@ import net.kyori.adventure.text.minimessage.tag.resolver.ArgumentQueue;
|
||||
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
|
||||
import net.momirealms.craftengine.core.entity.player.Player;
|
||||
import net.momirealms.craftengine.core.plugin.CraftEngine;
|
||||
import net.momirealms.craftengine.core.plugin.context.PlayerOptionalContext;
|
||||
import net.momirealms.craftengine.core.plugin.context.RelationalContext;
|
||||
import net.momirealms.craftengine.core.util.AdventureHelper;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -14,10 +16,12 @@ import org.jetbrains.annotations.Nullable;
|
||||
public class RelationalPlaceholderTag implements TagResolver {
|
||||
private final Player player1;
|
||||
private final Player player2;
|
||||
private final RelationalContext context;
|
||||
|
||||
public RelationalPlaceholderTag(@NotNull Player player1, @NotNull Player player2) {
|
||||
public RelationalPlaceholderTag(@NotNull Player player1, @NotNull Player player2, RelationalContext context) {
|
||||
this.player1 = player1;
|
||||
this.player2 = player2;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -25,8 +29,10 @@ public class RelationalPlaceholderTag implements TagResolver {
|
||||
if (!this.has(name) || !CraftEngine.instance().compatibilityManager().hasPlaceholderAPI()) {
|
||||
return null;
|
||||
}
|
||||
String placeholder = "%" + arguments.popOr("No argument placeholder provided") + "%";
|
||||
String parsed = CraftEngine.instance().compatibilityManager().parse(player1, player2, placeholder);
|
||||
String rawArgument = arguments.popOr("No argument placeholder provided").toString();
|
||||
if (rawArgument.contains("<")) rawArgument = AdventureHelper.resolvePlainStringTags(rawArgument, this.context.tagResolvers());
|
||||
String placeholder = "%" + rawArgument + "%";
|
||||
String parsed = CraftEngine.instance().compatibilityManager().parse(this.player1, this.player2, placeholder);
|
||||
if (parsed.equals(placeholder)) {
|
||||
parsed = arguments.popOr("No default papi value provided").toString();
|
||||
}
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
package net.momirealms.craftengine.core.plugin.text.minimessage;
|
||||
|
||||
import net.momirealms.craftengine.core.entity.player.Player;
|
||||
import net.momirealms.craftengine.core.plugin.context.Context;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class ViewerPlaceholderTag extends PlaceholderTag {
|
||||
|
||||
public ViewerPlaceholderTag(@Nullable Player player) {
|
||||
public ViewerPlaceholderTag(@NotNull Context player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
|
||||
@@ -316,6 +316,11 @@ public class AdventureHelper {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static String resolvePlainStringTags(String raw, TagResolver... resolvers) {
|
||||
Component resultComponent = AdventureHelper.customMiniMessage().deserialize(raw, resolvers);
|
||||
return AdventureHelper.plainTextContent(resultComponent);
|
||||
}
|
||||
|
||||
public static Component replaceText(Component text, Map<String, Component> replacements) {
|
||||
String patternString = replacements.keySet().stream()
|
||||
.map(Pattern::quote)
|
||||
|
||||
@@ -104,7 +104,7 @@ public class MiscUtils {
|
||||
public static void deepMergeMaps(Map<String, Object> baseMap, Map<String, Object> mapToMerge) {
|
||||
for (Map.Entry<String, Object> entry : mapToMerge.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
if (!key.isEmpty() && key.charAt(0) == '$') {
|
||||
if (key.length() > 2 && key.charAt(0) == '$' && key.charAt(1) == '$') {
|
||||
Object value = entry.getValue();
|
||||
baseMap.put(key.substring(1), value);
|
||||
} else {
|
||||
|
||||
@@ -2,8 +2,8 @@ org.gradle.jvmargs=-Xmx1G
|
||||
|
||||
# Project settings
|
||||
# Rule: [major update].[feature update].[bug fix]
|
||||
project_version=0.0.56.5
|
||||
config_version=36
|
||||
project_version=0.0.56.7
|
||||
config_version=37
|
||||
lang_version=16
|
||||
project_group=net.momirealms
|
||||
latest_supported_version=1.21.5
|
||||
@@ -51,7 +51,7 @@ byte_buddy_version=1.17.5
|
||||
ahocorasick_version=0.6.3
|
||||
snake_yaml_version=2.4
|
||||
anti_grief_version=0.17
|
||||
nms_helper_version=0.67.3
|
||||
nms_helper_version=0.67.7
|
||||
evalex_version=3.5.0
|
||||
reactive_streams_version=1.0.4
|
||||
amazon_awssdk_version=2.31.23
|
||||
|
||||
Reference in New Issue
Block a user