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

曲线救营火配方

This commit is contained in:
XiaoMoMi
2025-02-15 21:25:04 +08:00
parent 5f2d85668b
commit 7631adf448
11 changed files with 265 additions and 36 deletions

View File

@@ -31,6 +31,7 @@ blocks:
instrument: HARP
luminance: 15
map-color: 36
item: default:chinese_lantern
sounds:
break: minecraft:block.wood.break
step: minecraft:block.wood.step

View File

@@ -4,11 +4,7 @@ import net.momirealms.craftengine.bukkit.entity.DisplayEntityData;
import net.momirealms.craftengine.bukkit.entity.InteractionEntityData;
import net.momirealms.craftengine.bukkit.item.BukkitItemManager;
import net.momirealms.craftengine.bukkit.item.behavior.FurnitureItemBehavior;
import net.momirealms.craftengine.bukkit.util.LegacyAttributeUtils;
import net.momirealms.craftengine.bukkit.util.EntityUtils;
import net.momirealms.craftengine.bukkit.util.ItemUtils;
import net.momirealms.craftengine.bukkit.util.LocationUtils;
import net.momirealms.craftengine.bukkit.util.Reflections;
import net.momirealms.craftengine.bukkit.util.*;
import net.momirealms.craftengine.bukkit.world.BukkitWorld;
import net.momirealms.craftengine.core.entity.furniture.AnchorType;
import net.momirealms.craftengine.core.entity.furniture.FurnitureElement;

View File

@@ -8,6 +8,8 @@ import net.momirealms.craftengine.core.item.ItemWrapper;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.SkullUtils;
import org.bukkit.NamespacedKey;
import org.bukkit.Registry;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
@@ -186,17 +188,12 @@ public class UniversalItemFactory extends BukkitItemFactory {
}
}
@SuppressWarnings("deprecation")
@Override
protected Optional<Enchantment> getEnchantment(ItemWrapper<ItemStack> item, Key key) {
Object enchantments = item.getExact("Enchantments");
if (enchantments != null) {
for (Object enchant : TagList.getValue(enchantments)) {
if (TagBase.getValue(TagCompound.get(enchant, "id")).equals(enchant.toString())) {
return Optional.of(new Enchantment(key, (int) TagBase.getValue(TagCompound.get(enchant, "lvl"))));
}
}
}
return Optional.empty();
int level = item.getItem().getEnchantmentLevel(Objects.requireNonNull(Registry.ENCHANTMENT.get(new NamespacedKey(key.namespace(), key.value()))));
if (level <= 0) return Optional.empty();
return Optional.of(new Enchantment(key, level));
}
@Override

View File

@@ -1,5 +1,6 @@
package net.momirealms.craftengine.bukkit.item.recipe;
import net.momirealms.craftengine.bukkit.item.BukkitItemManager;
import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine;
import net.momirealms.craftengine.bukkit.plugin.injector.BukkitInjector;
import net.momirealms.craftengine.bukkit.plugin.user.BukkitServerPlayer;
@@ -7,9 +8,11 @@ import net.momirealms.craftengine.bukkit.util.ItemUtils;
import net.momirealms.craftengine.bukkit.util.Reflections;
import net.momirealms.craftengine.core.item.Item;
import net.momirealms.craftengine.core.item.ItemManager;
import net.momirealms.craftengine.core.item.recipe.CustomCampfireRecipe;
import net.momirealms.craftengine.core.item.recipe.OptimizedIDItem;
import net.momirealms.craftengine.core.item.recipe.Recipe;
import net.momirealms.craftengine.core.item.recipe.RecipeTypes;
import net.momirealms.craftengine.core.item.recipe.input.CookingInput;
import net.momirealms.craftengine.core.item.recipe.input.CraftingInput;
import net.momirealms.craftengine.core.registry.BuiltInRegistries;
import net.momirealms.craftengine.core.registry.Holder;
@@ -17,15 +20,17 @@ import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.VersionHelper;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.Campfire;
import org.bukkit.block.Furnace;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.block.*;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryOpenEvent;
import org.bukkit.event.inventory.PrepareItemCraftEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.*;
import java.util.ArrayList;
@@ -52,12 +57,30 @@ public class RecipeEventListener implements Listener {
Furnace furnace = furnaceInventory.getHolder();
try {
Object blockEntity = Reflections.field$CraftBlockEntityState$tileEntity.get(furnace);
BukkitInjector.injectFurnaceBlockEntity(blockEntity);
BukkitInjector.injectCookingBlockEntity(blockEntity);
} catch (Exception e) {
plugin.logger().warn("Failed to inject cooking block entity", e);
}
}
// for 1.20.1-1.21.1
@EventHandler(ignoreCancelled = true)
public void onBlockIgnite(BlockIgniteEvent event) {
if (VersionHelper.isVersionNewerThan1_21_2()) return;
Block block = event.getBlock();
Material material = block.getType();
if (material == Material.CAMPFIRE) {
if (block.getState() instanceof Campfire campfire) {
try {
Object blockEntity = Reflections.field$CraftBlockEntityState$tileEntity.get(campfire);
BukkitInjector.injectCookingBlockEntity(blockEntity);
} catch (Exception e) {
this.plugin.logger().warn("Failed to inject cooking block entity", e);
}
}
}
}
@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
public void onPlaceBlock(BlockPlaceEvent event) {
Block block = event.getBlock();
@@ -66,21 +89,141 @@ public class RecipeEventListener implements Listener {
if (block.getState() instanceof Furnace furnace) {
try {
Object blockEntity = Reflections.field$CraftBlockEntityState$tileEntity.get(furnace);
BukkitInjector.injectFurnaceBlockEntity(blockEntity);
BukkitInjector.injectCookingBlockEntity(blockEntity);
} catch (Exception e) {
plugin.logger().warn("Failed to inject cooking block entity", e);
}
}
} else if (!VersionHelper.isVersionNewerThan1_21_2() && material == Material.CAMPFIRE) {
if (block.getState() instanceof Campfire campfire) {
try {
Object blockEntity = Reflections.field$CraftBlockEntityState$tileEntity.get(campfire);
BukkitInjector.injectCookingBlockEntity(blockEntity);
} catch (Exception e) {
this.plugin.logger().warn("Failed to inject cooking block entity", e);
}
}
}
}
// for 1.21.2+
@EventHandler(ignoreCancelled = true)
public void onPutItemOnCampfire(PlayerInteractEvent event) {
if (!VersionHelper.isVersionNewerThan1_21_2()) return;
if (event.getAction() != Action.RIGHT_CLICK_BLOCK) return;
Block clicked = event.getClickedBlock();
if (clicked == null) return;
Material type = clicked.getType();
if (type != Material.CAMPFIRE && type != Material.SOUL_CAMPFIRE) return;
if (!VersionHelper.isVersionNewerThan1_21_2()) {
if (clicked.getState() instanceof Campfire campfire) {
try {
Object blockEntity = Reflections.field$CraftBlockEntityState$tileEntity.get(campfire);
BukkitInjector.injectCookingBlockEntity(blockEntity);
} catch (Exception e) {
this.plugin.logger().warn("Failed to inject cooking block entity", e);
}
}
}
ItemStack itemStack = event.getItem();
if (ItemUtils.isEmpty(itemStack)) return;
try {
@SuppressWarnings("unchecked")
Optional<Object> optionalMCRecipe = (Optional<Object>) Reflections.method$RecipeManager$getRecipeFor1.invoke(
BukkitRecipeManager.minecraftRecipeManager(),
Reflections.instance$RecipeType$CAMPFIRE_COOKING,
Reflections.constructor$SingleRecipeInput.newInstance(Reflections.method$CraftItemStack$asNMSMirror.invoke(null, itemStack)),
Reflections.field$CraftWorld$ServerLevel.get(event.getPlayer().getWorld()),
null
);
if (optionalMCRecipe.isEmpty()) {
return;
}
Item<ItemStack> wrappedItem = BukkitItemManager.instance().wrap(itemStack);
Optional<Holder.Reference<Key>> idHolder = BuiltInRegistries.OPTIMIZED_ITEM_ID.get(wrappedItem.id());
if (idHolder.isEmpty()) {
return;
}
CookingInput<ItemStack> input = new CookingInput<>(new OptimizedIDItem<>(idHolder.get(), itemStack));
CustomCampfireRecipe<ItemStack> ceRecipe = (CustomCampfireRecipe<ItemStack>) this.recipeManager.getRecipe(RecipeTypes.CAMPFIRE_COOKING, input);
if (ceRecipe == null) {
event.setCancelled(true);
}
} catch (Exception e) {
this.plugin.logger().warn("Failed to handle interact campfire", e);
}
}
// for 1.21.2+
@EventHandler(ignoreCancelled = true)
public void onCampfireCook(CampfireStartEvent event) {
if (!VersionHelper.isVersionNewerThan1_21_2()) return;
CampfireRecipe recipe = event.getRecipe();
Key recipeId = new Key(recipe.getKey().namespace(), recipe.getKey().value());
boolean isCustom = this.recipeManager.isCustomRecipe(recipeId);
if (!isCustom) {
return;
}
ItemStack itemStack = event.getSource();
Item<ItemStack> wrappedItem = BukkitItemManager.instance().wrap(itemStack);
Optional<Holder.Reference<Key>> idHolder = BuiltInRegistries.OPTIMIZED_ITEM_ID.get(wrappedItem.id());
if (idHolder.isEmpty()) {
event.setTotalCookTime(Integer.MAX_VALUE);
return;
}
CookingInput<ItemStack> input = new CookingInput<>(new OptimizedIDItem<>(idHolder.get(), itemStack));
CustomCampfireRecipe<ItemStack> ceRecipe = (CustomCampfireRecipe<ItemStack>) this.recipeManager.getRecipe(RecipeTypes.CAMPFIRE_COOKING, input);
if (ceRecipe == null) {
event.setTotalCookTime(Integer.MAX_VALUE);
return;
}
event.setTotalCookTime(ceRecipe.cookingTime());
}
// for 1.21.2+
@EventHandler(ignoreCancelled = true)
public void onCampfireCook(BlockCookEvent event) {
if (!VersionHelper.isVersionNewerThan1_21_2()) return;
Material type = event.getBlock().getType();
if (type != Material.CAMPFIRE && type != Material.SOUL_CAMPFIRE) return;
CampfireRecipe recipe = (CampfireRecipe) event.getRecipe();
Key recipeId = new Key(recipe.getKey().namespace(), recipe.getKey().value());
boolean isCustom = this.recipeManager.isCustomRecipe(recipeId);
if (!isCustom) {
return;
}
ItemStack itemStack = event.getSource();
Item<ItemStack> wrappedItem = BukkitItemManager.instance().wrap(itemStack);
Optional<Holder.Reference<Key>> idHolder = BuiltInRegistries.OPTIMIZED_ITEM_ID.get(wrappedItem.id());
if (idHolder.isEmpty()) {
event.setCancelled(true);
return;
}
CookingInput<ItemStack> input = new CookingInput<>(new OptimizedIDItem<>(idHolder.get(), itemStack));
CustomCampfireRecipe<ItemStack> ceRecipe = (CustomCampfireRecipe<ItemStack>) this.recipeManager.getRecipe(RecipeTypes.CAMPFIRE_COOKING, input);
if (ceRecipe == null) {
event.setCancelled(true);
return;
}
event.setResult(ceRecipe.getResult(null));
}
@EventHandler(ignoreCancelled = true)
public void onClickCartographyTable(InventoryClickEvent event) {
if (VersionHelper.isPaper()) return;
if (!(event.getClickedInventory() instanceof CartographyInventory cartographyInventory)) {
return;
}
plugin.scheduler().sync().runDelayed(() -> {
this.plugin.scheduler().sync().runDelayed(() -> {
if (ItemUtils.hasCustomItem(cartographyInventory.getContents())) {
cartographyInventory.setResult(new ItemStack(Material.AIR));
}

View File

@@ -255,14 +255,21 @@ public class BukkitInjector {
}
}
public static void injectFurnaceBlockEntity(Object entity) throws ReflectiveOperationException {
if (!Reflections.clazz$AbstractFurnaceBlockEntity.isInstance(entity)) return;
Object quickCheck = Reflections.field$AbstractFurnaceBlockEntity$quickCheck.get(entity);
if (clazz$InjectedCacheChecker.isInstance(quickCheck)) return; // already injected
Object recipeType = Reflections.field$AbstractFurnaceBlockEntity$recipeType.get(entity);
Object injectedChecker = Reflections.UNSAFE.allocateInstance(clazz$InjectedCacheChecker);
field$InjectedCacheChecker$recipeType.set(injectedChecker, recipeType);
Reflections.field$AbstractFurnaceBlockEntity$quickCheck.set(entity, injectedChecker);
public static void injectCookingBlockEntity(Object entity) throws ReflectiveOperationException {
if (Reflections.clazz$AbstractFurnaceBlockEntity.isInstance(entity)) {
Object quickCheck = Reflections.field$AbstractFurnaceBlockEntity$quickCheck.get(entity);
if (clazz$InjectedCacheChecker.isInstance(quickCheck)) return; // already injected
Object recipeType = Reflections.field$AbstractFurnaceBlockEntity$recipeType.get(entity);
Object injectedChecker = Reflections.UNSAFE.allocateInstance(clazz$InjectedCacheChecker);
field$InjectedCacheChecker$recipeType.set(injectedChecker, recipeType);
Reflections.field$AbstractFurnaceBlockEntity$quickCheck.set(entity, injectedChecker);
} else if (!VersionHelper.isVersionNewerThan1_21_2() && Reflections.clazz$CampfireBlockEntity.isInstance(entity)) {
Object quickCheck = Reflections.field$CampfireBlockEntity$quickCheck.get(entity);
if (clazz$InjectedCacheChecker.isInstance(quickCheck)) return; // already injected
Object injectedChecker = Reflections.UNSAFE.allocateInstance(clazz$InjectedCacheChecker);
field$InjectedCacheChecker$recipeType.set(injectedChecker, Reflections.instance$RecipeType$CAMPFIRE_COOKING);
Reflections.field$CampfireBlockEntity$quickCheck.set(entity, injectedChecker);
}
}
public static Object getOptimizedItemDisplayFactory() {
@@ -321,8 +328,15 @@ public class BukkitInjector {
Object resourceLocation = pair.getFirst();
Key recipeId = Key.of(resourceLocation.toString());
BukkitRecipeManager recipeManager = BukkitRecipeManager.instance();
List<Object> items = (List<Object>) Reflections.field$AbstractFurnaceBlockEntity$items.get(args[0]);
ItemStack itemStack = (ItemStack) Reflections.method$CraftItemStack$asCraftMirror.invoke(null, items.get(0));
ItemStack itemStack;
List<Object> items;
if (type == Reflections.instance$RecipeType$CAMPFIRE_COOKING) {
items = (List<Object>) Reflections.field$SimpleContainer$items.get(args[0]);
} else {
items = (List<Object>) Reflections.field$AbstractFurnaceBlockEntity$items.get(args[0]);
}
itemStack = (ItemStack) Reflections.method$CraftItemStack$asCraftMirror.invoke(null, items.get(0));
// it's a recipe from other plugins
boolean isCustom = recipeManager.isCustomRecipe(recipeId);
@@ -346,7 +360,9 @@ public class BukkitInjector {
ceRecipe = (net.momirealms.craftengine.core.item.recipe.CookingRecipe<ItemStack>) recipeManager.getRecipe(RecipeTypes.BLASTING, input, lastCustomRecipe);
} else if (type == Reflections.instance$RecipeType$SMOKING) {
ceRecipe = (net.momirealms.craftengine.core.item.recipe.CookingRecipe<ItemStack>) recipeManager.getRecipe(RecipeTypes.SMOKING, input, lastCustomRecipe);
} else {
} else if (type == Reflections.instance$RecipeType$CAMPFIRE_COOKING) {
ceRecipe = (net.momirealms.craftengine.core.item.recipe.CookingRecipe<ItemStack>) recipeManager.getRecipe(RecipeTypes.CAMPFIRE_COOKING, input, lastCustomRecipe);
} else {
return Optional.empty();
}
if (ceRecipe == null) {
@@ -379,8 +395,15 @@ public class BukkitInjector {
Object id = Reflections.field$RecipeHolder$id.get(holder);
Key recipeId = Key.of(id.toString());
BukkitRecipeManager recipeManager = BukkitRecipeManager.instance();
List<Object> items = (List<Object>) Reflections.field$AbstractFurnaceBlockEntity$items.get(args[0]);
ItemStack itemStack = (ItemStack) Reflections.method$CraftItemStack$asCraftMirror.invoke(null, items.get(0));
ItemStack itemStack;
List<Object> items;
if (type == Reflections.instance$RecipeType$CAMPFIRE_COOKING) {
items = (List<Object>) Reflections.field$SimpleContainer$items.get(args[0]);
} else {
items = (List<Object>) Reflections.field$AbstractFurnaceBlockEntity$items.get(args[0]);
}
itemStack = (ItemStack) Reflections.method$CraftItemStack$asCraftMirror.invoke(null, items.get(0));
// it's a recipe from other plugins
boolean isCustom = recipeManager.isCustomRecipe(recipeId);
@@ -404,7 +427,9 @@ public class BukkitInjector {
ceRecipe = (net.momirealms.craftengine.core.item.recipe.CookingRecipe<ItemStack>) recipeManager.getRecipe(RecipeTypes.BLASTING, input, lastCustomRecipe);
} else if (type == Reflections.instance$RecipeType$SMOKING) {
ceRecipe = (net.momirealms.craftengine.core.item.recipe.CookingRecipe<ItemStack>) recipeManager.getRecipe(RecipeTypes.SMOKING, input, lastCustomRecipe);
} else {
} else if (type == Reflections.instance$RecipeType$CAMPFIRE_COOKING) {
ceRecipe = (net.momirealms.craftengine.core.item.recipe.CookingRecipe<ItemStack>) recipeManager.getRecipe(RecipeTypes.CAMPFIRE_COOKING, input, lastCustomRecipe);
} else {
return Optional.empty();
}
if (ceRecipe == null) {
@@ -461,7 +486,9 @@ public class BukkitInjector {
ceRecipe = (net.momirealms.craftengine.core.item.recipe.CookingRecipe<ItemStack>) recipeManager.getRecipe(RecipeTypes.BLASTING, input, lastCustomRecipe);
} else if (type == Reflections.instance$RecipeType$SMOKING) {
ceRecipe = (net.momirealms.craftengine.core.item.recipe.CookingRecipe<ItemStack>) recipeManager.getRecipe(RecipeTypes.SMOKING, input, lastCustomRecipe);
} else {
} else if (type == Reflections.instance$RecipeType$CAMPFIRE_COOKING) {
ceRecipe = (net.momirealms.craftengine.core.item.recipe.CookingRecipe<ItemStack>) recipeManager.getRecipe(RecipeTypes.CAMPFIRE_COOKING, input, lastCustomRecipe);
} else {
return Optional.empty();
}
if (ceRecipe == null) {

View File

@@ -1,8 +1,15 @@
package net.momirealms.craftengine.bukkit.util;
import net.momirealms.craftengine.bukkit.item.recipe.BukkitRecipeManager;
import net.momirealms.craftengine.core.block.BlockKeys;
import net.momirealms.craftengine.core.item.Item;
import net.momirealms.craftengine.core.item.recipe.OptimizedIDItem;
import net.momirealms.craftengine.core.item.recipe.RecipeTypes;
import net.momirealms.craftengine.core.item.recipe.input.CookingInput;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.plugin.config.ConfigManager;
import net.momirealms.craftengine.core.registry.BuiltInRegistries;
import net.momirealms.craftengine.core.registry.Holder;
import net.momirealms.craftengine.core.util.Direction;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.QuadFunction;
@@ -15,6 +22,7 @@ import org.bukkit.inventory.ItemStack;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
public class InteractUtils {
private static final Map<Key, QuadFunction<Player, Item<ItemStack>, BlockData, BlockHitResult, Boolean>> INTERACTIONS = new HashMap<>();
@@ -68,6 +76,20 @@ public class InteractUtils {
}
return false;
});
register(BlockKeys.SOUL_CAMPFIRE, (player, item, blockState, result) -> {
if (!ConfigManager.enableRecipeSystem()) return false;
Optional<Holder.Reference<Key>> optional = BuiltInRegistries.OPTIMIZED_ITEM_ID.get(item.id());
return optional.filter(keyReference -> BukkitRecipeManager.instance().getRecipe(RecipeTypes.CAMPFIRE_COOKING, new CookingInput<>(new OptimizedIDItem<>(
keyReference, item.getItem()
))) != null).isPresent();
});
register(BlockKeys.CAMPFIRE, (player, item, blockState, result) -> {
if (!ConfigManager.enableRecipeSystem()) return false;
Optional<Holder.Reference<Key>> optional = BuiltInRegistries.OPTIMIZED_ITEM_ID.get(item.id());
return optional.filter(keyReference -> BukkitRecipeManager.instance().getRecipe(RecipeTypes.CAMPFIRE_COOKING, new CookingInput<>(new OptimizedIDItem<>(
keyReference, item.getItem()
))) != null).isPresent();
});
register(BlockKeys.HOPPER, (player, item, blockState, result) -> true);
register(BlockKeys.DISPENSER, (player, item, blockState, result) -> true);
register(BlockKeys.DROPPER, (player, item, blockState, result) -> true);

View File

@@ -21,6 +21,11 @@ public class ParticleUtils {
try {
Object world = Reflections.field$CraftWorld$ServerLevel.get(bukkitWorld);
Object shape = Reflections.method$BlockState$getShape.invoke(state, world, pos, Reflections.method$CollisionContext$empty.invoke(null));
boolean isEmpty = (boolean) Reflections.method$VoxelShape$isEmpty.invoke(shape);
if (isEmpty) {
return;
}
Object aabb = Reflections.method$VoxelShape$bounds.invoke(shape);
double minX = Reflections.field$AABB$minX.getDouble(aabb);
double minY = Reflections.field$AABB$minY.getDouble(aabb);

View File

@@ -1725,6 +1725,13 @@ public class Reflections {
)
);
public static final Class<?> clazz$CampfireBlockEntity = requireNonNull(
ReflectionUtils.getClazz(
BukkitReflectionUtils.assembleMCClass("world.level.block.entity.CampfireBlockEntity"),
BukkitReflectionUtils.assembleMCClass("world.level.block.entity.TileEntityCampfire")
)
);
public static final Field field$ChunkAccess$blockEntities;
static {
@@ -3436,6 +3443,12 @@ public class Reflections {
)
);
public static final Method method$VoxelShape$isEmpty = requireNonNull(
ReflectionUtils.getMethod(
clazz$VoxelShape, boolean.class
)
);
public static final Method method$VoxelShape$bounds = requireNonNull(
ReflectionUtils.getMethod(
clazz$VoxelShape, clazz$AABB
@@ -4340,6 +4353,12 @@ public class Reflections {
)
);
// 1.20.1-1.21.1
public static final Field field$CampfireBlockEntity$quickCheck =
ReflectionUtils.getDeclaredField(
clazz$CampfireBlockEntity, clazz$RecipeManager$CachedCheck, 0
);
// 1.21+
public static final Class<?> clazz$RecipeInput = ReflectionUtils.getClazz(
BukkitReflectionUtils.assembleMCClass("world.item.crafting.RecipeInput")
@@ -4349,6 +4368,10 @@ public class Reflections {
BukkitReflectionUtils.assembleMCClass("world.item.crafting.SingleRecipeInput")
);
public static final Constructor<?> constructor$SingleRecipeInput = Optional.ofNullable(clazz$SingleRecipeInput)
.map(it -> ReflectionUtils.getConstructor(it, clazz$ItemStack))
.orElse(null);
// 1.20.1-1.21.1
public static final Method method$RecipeManager$getRecipeFor0 =
ReflectionUtils.getMethod(
@@ -4383,4 +4406,17 @@ public class Reflections {
clazz$CraftBlockEntityState, 0
)
);
public static final Class<?> clazz$SimpleContainer = requireNonNull(
ReflectionUtils.getClazz(
BukkitReflectionUtils.assembleMCClass("world.SimpleContainer"),
BukkitReflectionUtils.assembleMCClass("world.InventorySubcontainer")
)
);
public static final Field field$SimpleContainer$items = requireNonNull(
ReflectionUtils.getDeclaredField(
clazz$SimpleContainer, clazz$NonNullList, 0
)
);
}

View File

@@ -273,7 +273,7 @@ public class BukkitWorldManager implements WorldManager, Listener {
@SuppressWarnings("unchecked")
Map<Object, Object> blockEntities = (Map<Object, Object>) Reflections.field$ChunkAccess$blockEntities.get(levelChunk);
for (Object blockEntity : blockEntities.values()) {
BukkitInjector.injectFurnaceBlockEntity(blockEntity);
BukkitInjector.injectCookingBlockEntity(blockEntity);
}
}
} catch (ReflectiveOperationException e) {

View File

@@ -22,6 +22,8 @@ public class BlockKeys {
public static final Key BREWING_STAND = Key.of("minecraft:brewing_stand");
public static final Key BEACON = Key.of("minecraft:beacon");
public static final Key CHEST = Key.of("minecraft:chest");
public static final Key CAMPFIRE = Key.of("minecraft:campfire");
public static final Key SOUL_CAMPFIRE = Key.of("minecraft:soul_campfire");
public static final Key ENDER_CHEST = Key.of("minecraft:ender_chest");
public static final Key TRAPPED_CHEST = Key.of("minecraft:trapped_chest");
public static final Key DAYLIGHT_DETECTOR = Key.of("minecraft:daylight_detector");

View File

@@ -106,7 +106,7 @@ public class PackManagerImpl implements PackManager {
}
Pack pack = new Pack(path, new PackMeta(author, description, version, namespace));
this.loadedPacks.put(path.getFileName().toString(), pack);
this.plugin.logger().info("Loaded pack: " + pack.folder().getFileName());
this.plugin.logger().info("Loaded pack: " + pack.folder().getFileName() + ". Default namespace: " + namespace);
}
}
} catch (IOException e) {
@@ -234,7 +234,7 @@ public class PackManagerImpl implements PackManager {
}
}
long t2 = System.nanoTime();
this.plugin.logger().info("Loaded config type: " + parser.sectionId() + ". Took " + String.format("%.2f", ((t2 - t1) / 1_000_000.0)) + " ms");
this.plugin.logger().info("Loaded " + parser.sectionId() + " in " + String.format("%.2f", ((t2 - t1) / 1_000_000.0)) + " ms");
}
}