mirror of
https://github.com/PaperMC/Paper.git
synced 2025-01-03 23:07:40 +01:00
parent
ac5e815b3e
commit
fbea3cdc0c
@ -33,6 +33,7 @@ import org.bukkit.craftbukkit.entity.CraftWolf;
|
||||
import org.bukkit.craftbukkit.generator.structure.CraftStructure;
|
||||
import org.bukkit.craftbukkit.generator.structure.CraftStructureType;
|
||||
import org.bukkit.craftbukkit.inventory.CraftItemType;
|
||||
import org.bukkit.craftbukkit.inventory.CraftMenuType;
|
||||
import org.bukkit.craftbukkit.inventory.trim.CraftTrimMaterial;
|
||||
import org.bukkit.craftbukkit.inventory.trim.CraftTrimPattern;
|
||||
import org.bukkit.craftbukkit.legacy.FieldRename;
|
||||
@ -51,6 +52,7 @@ import org.bukkit.entity.Wolf;
|
||||
import org.bukkit.generator.structure.Structure;
|
||||
import org.bukkit.generator.structure.StructureType;
|
||||
import org.bukkit.inventory.ItemType;
|
||||
import org.bukkit.inventory.MenuType;
|
||||
import org.bukkit.inventory.meta.trim.TrimMaterial;
|
||||
import org.bukkit.inventory.meta.trim.TrimPattern;
|
||||
import org.bukkit.map.MapCursor;
|
||||
@ -138,6 +140,9 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> {
|
||||
if (bukkitClass == MusicInstrument.class) {
|
||||
return new CraftRegistry<>(MusicInstrument.class, registryHolder.registryOrThrow(Registries.INSTRUMENT), CraftMusicInstrument::new, FieldRename.NONE);
|
||||
}
|
||||
if (bukkitClass == MenuType.class) {
|
||||
return new CraftRegistry<>(MenuType.class, registryHolder.registryOrThrow(Registries.MENU), CraftMenuType::new, FieldRename.NONE);
|
||||
}
|
||||
if (bukkitClass == PotionEffectType.class) {
|
||||
return new CraftRegistry<>(PotionEffectType.class, registryHolder.registryOrThrow(Registries.MOB_EFFECT), CraftPotionEffectType::new, FieldRename.NONE);
|
||||
}
|
||||
|
@ -30,6 +30,7 @@ import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.event.inventory.InventoryType;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.InventoryView;
|
||||
import org.bukkit.inventory.MenuType;
|
||||
|
||||
public class CraftContainer extends Container {
|
||||
|
||||
@ -98,7 +99,8 @@ public class CraftContainer extends Container {
|
||||
}
|
||||
|
||||
public static Containers getNotchInventoryType(Inventory inventory) {
|
||||
switch (inventory.getType()) {
|
||||
final InventoryType type = inventory.getType();
|
||||
switch (type) {
|
||||
case PLAYER:
|
||||
case CHEST:
|
||||
case ENDER_CHEST:
|
||||
@ -120,52 +122,13 @@ public class CraftContainer extends Container {
|
||||
default:
|
||||
throw new IllegalArgumentException("Unsupported custom inventory size " + inventory.getSize());
|
||||
}
|
||||
case WORKBENCH:
|
||||
return Containers.CRAFTING;
|
||||
case FURNACE:
|
||||
return Containers.FURNACE;
|
||||
case DISPENSER:
|
||||
return Containers.GENERIC_3x3;
|
||||
case ENCHANTING:
|
||||
return Containers.ENCHANTMENT;
|
||||
case BREWING:
|
||||
return Containers.BREWING_STAND;
|
||||
case BEACON:
|
||||
return Containers.BEACON;
|
||||
case ANVIL:
|
||||
return Containers.ANVIL;
|
||||
case HOPPER:
|
||||
return Containers.HOPPER;
|
||||
case DROPPER:
|
||||
return Containers.GENERIC_3x3;
|
||||
case SHULKER_BOX:
|
||||
return Containers.SHULKER_BOX;
|
||||
case BLAST_FURNACE:
|
||||
return Containers.BLAST_FURNACE;
|
||||
case LECTERN:
|
||||
return Containers.LECTERN;
|
||||
case SMOKER:
|
||||
return Containers.SMOKER;
|
||||
case LOOM:
|
||||
return Containers.LOOM;
|
||||
case CARTOGRAPHY:
|
||||
return Containers.CARTOGRAPHY_TABLE;
|
||||
case GRINDSTONE:
|
||||
return Containers.GRINDSTONE;
|
||||
case STONECUTTER:
|
||||
return Containers.STONECUTTER;
|
||||
case SMITHING:
|
||||
case SMITHING_NEW:
|
||||
return Containers.SMITHING;
|
||||
case CREATIVE:
|
||||
case CRAFTING:
|
||||
case MERCHANT:
|
||||
throw new IllegalArgumentException("Can't open a " + inventory.getType() + " inventory!");
|
||||
case CRAFTER:
|
||||
return Containers.CRAFTER_3x3;
|
||||
default:
|
||||
// TODO: If it reaches the default case, should we throw an error?
|
||||
return Containers.GENERIC_9x3;
|
||||
final MenuType menu = type.getMenuType();
|
||||
if (menu == null) {
|
||||
return Containers.GENERIC_9x3;
|
||||
} else {
|
||||
return ((CraftMenuType<?>) menu).getHandle();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,89 @@
|
||||
package org.bukkit.craftbukkit.inventory;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.base.Suppliers;
|
||||
import java.util.function.Supplier;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.server.level.EntityPlayer;
|
||||
import net.minecraft.world.inventory.Container;
|
||||
import net.minecraft.world.inventory.Containers;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.Registry;
|
||||
import org.bukkit.craftbukkit.CraftRegistry;
|
||||
import org.bukkit.craftbukkit.entity.CraftHumanEntity;
|
||||
import org.bukkit.craftbukkit.inventory.util.CraftMenus;
|
||||
import org.bukkit.craftbukkit.util.CraftChatMessage;
|
||||
import org.bukkit.craftbukkit.util.Handleable;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.inventory.InventoryView;
|
||||
import org.bukkit.inventory.MenuType;
|
||||
|
||||
public class CraftMenuType<V extends InventoryView> implements MenuType.Typed<V>, Handleable<Containers<?>> {
|
||||
|
||||
private final NamespacedKey key;
|
||||
private final Containers<?> handle;
|
||||
private final Supplier<CraftMenus.MenuTypeData<V>> typeData;
|
||||
|
||||
public CraftMenuType(NamespacedKey key, Containers<?> handle) {
|
||||
this.key = key;
|
||||
this.handle = handle;
|
||||
this.typeData = Suppliers.memoize(() -> CraftMenus.getMenuTypeData(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Containers<?> getHandle() {
|
||||
return this.handle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public V create(final HumanEntity player, final String title) {
|
||||
Preconditions.checkArgument(player != null, "The given player must not be null");
|
||||
Preconditions.checkArgument(title != null, "The given title must not be null");
|
||||
Preconditions.checkArgument(player instanceof CraftHumanEntity, "The given player must be a CraftHumanEntity");
|
||||
final CraftHumanEntity craftHuman = (CraftHumanEntity) player;
|
||||
Preconditions.checkArgument(craftHuman.getHandle() instanceof EntityPlayer, "The given player must be an EntityPlayer");
|
||||
final EntityPlayer serverPlayer = (EntityPlayer) craftHuman.getHandle();
|
||||
|
||||
final Container container = typeData.get().menuBuilder().build(serverPlayer, this.handle);
|
||||
container.setTitle(CraftChatMessage.fromString(title)[0]);
|
||||
container.checkReachable = false;
|
||||
return (V) container.getBukkitView();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Typed<InventoryView> typed() {
|
||||
return this.typed(InventoryView.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <V extends InventoryView> Typed<V> typed(Class<V> clazz) {
|
||||
if (clazz.isAssignableFrom(typeData.get().viewClass())) {
|
||||
return (Typed<V>) this;
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Cannot type InventoryView " + this.key.toString() + " to InventoryView type " + clazz.getSimpleName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends InventoryView> getInventoryViewClass() {
|
||||
return typeData.get().viewClass();
|
||||
}
|
||||
|
||||
@Override
|
||||
public NamespacedKey getKey() {
|
||||
return this.key;
|
||||
}
|
||||
|
||||
public static Containers<?> bukkitToMinecraft(MenuType bukkit) {
|
||||
return CraftRegistry.bukkitToMinecraft(bukkit);
|
||||
}
|
||||
|
||||
public static MenuType minecraftToBukkit(Containers<?> minecraft) {
|
||||
return CraftRegistry.minecraftToBukkit(minecraft, Registries.MENU, Registry.MENU);
|
||||
}
|
||||
|
||||
public static MenuType minecraftHolderToBukkit(Holder<Containers<?>> minecraft) {
|
||||
return minecraftToBukkit(minecraft.value());
|
||||
}
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
package org.bukkit.craftbukkit.inventory.util;
|
||||
|
||||
import net.minecraft.core.BlockPosition;
|
||||
import net.minecraft.server.level.EntityPlayer;
|
||||
import net.minecraft.world.ITileInventory;
|
||||
import net.minecraft.world.entity.player.PlayerInventory;
|
||||
import net.minecraft.world.inventory.Container;
|
||||
import net.minecraft.world.inventory.ContainerAccess;
|
||||
import net.minecraft.world.inventory.Containers;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.IBlockData;
|
||||
|
||||
public interface CraftMenuBuilder {
|
||||
|
||||
Container build(EntityPlayer player, Containers<?> type);
|
||||
|
||||
static CraftMenuBuilder worldAccess(LocationBoundContainerBuilder builder) {
|
||||
return (EntityPlayer player, Containers<?> type) -> {
|
||||
return builder.build(player.nextContainerCounter(), player.getInventory(), ContainerAccess.create(player.level(), player.blockPosition()));
|
||||
};
|
||||
}
|
||||
|
||||
static CraftMenuBuilder tileEntity(TileEntityObjectBuilder objectBuilder, Block block) {
|
||||
return (EntityPlayer player, Containers<?> type) -> {
|
||||
return objectBuilder.build(player.blockPosition(), block.defaultBlockState()).createMenu(player.nextContainerCounter(), player.getInventory(), player);
|
||||
};
|
||||
}
|
||||
|
||||
interface TileEntityObjectBuilder {
|
||||
|
||||
ITileInventory build(BlockPosition blockPosition, IBlockData blockData);
|
||||
}
|
||||
|
||||
interface LocationBoundContainerBuilder {
|
||||
|
||||
Container build(int syncId, PlayerInventory inventory, ContainerAccess access);
|
||||
}
|
||||
}
|
@ -0,0 +1,115 @@
|
||||
package org.bukkit.craftbukkit.inventory.util;
|
||||
|
||||
import static org.bukkit.craftbukkit.inventory.util.CraftMenuBuilder.*;
|
||||
import net.minecraft.network.chat.IChatBaseComponent;
|
||||
import net.minecraft.world.TileInventory;
|
||||
import net.minecraft.world.inventory.ContainerAnvil;
|
||||
import net.minecraft.world.inventory.ContainerCartography;
|
||||
import net.minecraft.world.inventory.ContainerEnchantTable;
|
||||
import net.minecraft.world.inventory.ContainerGrindstone;
|
||||
import net.minecraft.world.inventory.ContainerSmithing;
|
||||
import net.minecraft.world.inventory.ContainerStonecutter;
|
||||
import net.minecraft.world.inventory.ContainerWorkbench;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.entity.CrafterBlockEntity;
|
||||
import net.minecraft.world.level.block.entity.TileEntityBeacon;
|
||||
import net.minecraft.world.level.block.entity.TileEntityBlastFurnace;
|
||||
import net.minecraft.world.level.block.entity.TileEntityBrewingStand;
|
||||
import net.minecraft.world.level.block.entity.TileEntityDispenser;
|
||||
import net.minecraft.world.level.block.entity.TileEntityFurnaceFurnace;
|
||||
import net.minecraft.world.level.block.entity.TileEntityHopper;
|
||||
import net.minecraft.world.level.block.entity.TileEntityLectern;
|
||||
import net.minecraft.world.level.block.entity.TileEntitySmoker;
|
||||
import org.bukkit.craftbukkit.inventory.CraftMenuType;
|
||||
import org.bukkit.inventory.InventoryView;
|
||||
import org.bukkit.inventory.MenuType;
|
||||
import org.bukkit.inventory.view.AnvilView;
|
||||
import org.bukkit.inventory.view.BeaconView;
|
||||
import org.bukkit.inventory.view.BrewingStandView;
|
||||
import org.bukkit.inventory.view.CrafterView;
|
||||
import org.bukkit.inventory.view.EnchantmentView;
|
||||
import org.bukkit.inventory.view.FurnaceView;
|
||||
import org.bukkit.inventory.view.LecternView;
|
||||
import org.bukkit.inventory.view.LoomView;
|
||||
import org.bukkit.inventory.view.MerchantView;
|
||||
import org.bukkit.inventory.view.StonecutterView;
|
||||
|
||||
public final class CraftMenus {
|
||||
|
||||
public record MenuTypeData<V extends InventoryView>(Class<V> viewClass, CraftMenuBuilder menuBuilder) {
|
||||
}
|
||||
|
||||
private static final CraftMenuBuilder STANDARD = (player, menuType) -> menuType.create(player.nextContainerCounter(), player.getInventory());
|
||||
|
||||
public static <V extends InventoryView> MenuTypeData<V> getMenuTypeData(CraftMenuType<?> menuType) {
|
||||
// this isn't ideal as both dispenser and dropper are 3x3, InventoryType can't currently handle generic 3x3s with size 9
|
||||
// this needs to be removed when inventory creation is overhauled
|
||||
if (menuType == MenuType.GENERIC_3X3) {
|
||||
return asType(new MenuTypeData<>(InventoryView.class, tileEntity(TileEntityDispenser::new, Blocks.DISPENSER)));
|
||||
}
|
||||
if (menuType == MenuType.CRAFTER_3X3) {
|
||||
return asType(new MenuTypeData<>(CrafterView.class, tileEntity(CrafterBlockEntity::new, Blocks.CRAFTER)));
|
||||
}
|
||||
if (menuType == MenuType.ANVIL) {
|
||||
return asType(new MenuTypeData<>(AnvilView.class, worldAccess(ContainerAnvil::new)));
|
||||
}
|
||||
if (menuType == MenuType.BEACON) {
|
||||
return asType(new MenuTypeData<>(BeaconView.class, tileEntity(TileEntityBeacon::new, Blocks.BEACON)));
|
||||
}
|
||||
if (menuType == MenuType.BLAST_FURNACE) {
|
||||
return asType(new MenuTypeData<>(FurnaceView.class, tileEntity(TileEntityBlastFurnace::new, Blocks.BLAST_FURNACE)));
|
||||
}
|
||||
if (menuType == MenuType.BREWING_STAND) {
|
||||
return asType(new MenuTypeData<>(BrewingStandView.class, tileEntity(TileEntityBrewingStand::new, Blocks.BREWING_STAND)));
|
||||
}
|
||||
if (menuType == MenuType.CRAFTING) {
|
||||
return asType(new MenuTypeData<>(InventoryView.class, worldAccess(ContainerWorkbench::new)));
|
||||
}
|
||||
if (menuType == MenuType.ENCHANTMENT) {
|
||||
return asType(new MenuTypeData<>(EnchantmentView.class, (player, type) -> {
|
||||
return new TileInventory((syncId, inventory, human) -> {
|
||||
return worldAccess(ContainerEnchantTable::new).build(player, type);
|
||||
}, IChatBaseComponent.empty()).createMenu(player.nextContainerCounter(), player.getInventory(), player);
|
||||
}));
|
||||
}
|
||||
if (menuType == MenuType.FURNACE) {
|
||||
return asType(new MenuTypeData<>(FurnaceView.class, tileEntity(TileEntityFurnaceFurnace::new, Blocks.FURNACE)));
|
||||
}
|
||||
if (menuType == MenuType.GRINDSTONE) {
|
||||
return asType(new MenuTypeData<>(InventoryView.class, worldAccess(ContainerGrindstone::new)));
|
||||
}
|
||||
// We really don't need to be creating a tile entity for hopper but currently InventoryType doesn't have capacity
|
||||
// to understand otherwise
|
||||
if (menuType == MenuType.HOPPER) {
|
||||
return asType(new MenuTypeData<>(InventoryView.class, tileEntity(TileEntityHopper::new, Blocks.HOPPER)));
|
||||
}
|
||||
// We also don't need to create a tile entity for lectern, but again InventoryType isn't smart enough to know any better
|
||||
if (menuType == MenuType.LECTERN) {
|
||||
return asType(new MenuTypeData<>(LecternView.class, tileEntity(TileEntityLectern::new, Blocks.LECTERN)));
|
||||
}
|
||||
if (menuType == MenuType.LOOM) {
|
||||
return asType(new MenuTypeData<>(LoomView.class, STANDARD));
|
||||
}
|
||||
if (menuType == MenuType.MERCHANT) {
|
||||
return asType(new MenuTypeData<>(MerchantView.class, STANDARD));
|
||||
}
|
||||
if (menuType == MenuType.SMITHING) {
|
||||
return asType(new MenuTypeData<>(InventoryView.class, worldAccess(ContainerSmithing::new)));
|
||||
}
|
||||
if (menuType == MenuType.SMOKER) {
|
||||
return asType(new MenuTypeData<>(FurnaceView.class, tileEntity(TileEntitySmoker::new, Blocks.SMOKER)));
|
||||
}
|
||||
if (menuType == MenuType.CARTOGRAPHY_TABLE) {
|
||||
return asType(new MenuTypeData<>(InventoryView.class, worldAccess(ContainerCartography::new)));
|
||||
}
|
||||
if (menuType == MenuType.STONECUTTER) {
|
||||
return asType(new MenuTypeData<>(StonecutterView.class, worldAccess(ContainerStonecutter::new)));
|
||||
}
|
||||
|
||||
return asType(new MenuTypeData<>(InventoryView.class, STANDARD));
|
||||
}
|
||||
|
||||
private static <V extends InventoryView> MenuTypeData<V> asType(MenuTypeData<?> data) {
|
||||
return (MenuTypeData<V>) data;
|
||||
}
|
||||
}
|
@ -11,6 +11,7 @@ import net.minecraft.world.entity.animal.FrogVariant;
|
||||
import net.minecraft.world.entity.animal.WolfVariant;
|
||||
import net.minecraft.world.entity.npc.VillagerProfession;
|
||||
import net.minecraft.world.entity.npc.VillagerType;
|
||||
import net.minecraft.world.inventory.Containers;
|
||||
import net.minecraft.world.item.Instrument;
|
||||
import net.minecraft.world.level.block.entity.EnumBannerPatternType;
|
||||
import net.minecraft.world.level.saveddata.maps.MapDecorationType;
|
||||
@ -33,6 +34,7 @@ import org.bukkit.craftbukkit.entity.CraftWolf;
|
||||
import org.bukkit.craftbukkit.generator.structure.CraftStructure;
|
||||
import org.bukkit.craftbukkit.generator.structure.CraftStructureType;
|
||||
import org.bukkit.craftbukkit.inventory.CraftItemType;
|
||||
import org.bukkit.craftbukkit.inventory.CraftMenuType;
|
||||
import org.bukkit.craftbukkit.inventory.trim.CraftTrimMaterial;
|
||||
import org.bukkit.craftbukkit.inventory.trim.CraftTrimPattern;
|
||||
import org.bukkit.craftbukkit.map.CraftMapCursor;
|
||||
@ -46,6 +48,7 @@ import org.bukkit.entity.Wolf;
|
||||
import org.bukkit.generator.structure.Structure;
|
||||
import org.bukkit.generator.structure.StructureType;
|
||||
import org.bukkit.inventory.ItemType;
|
||||
import org.bukkit.inventory.MenuType;
|
||||
import org.bukkit.inventory.meta.trim.TrimMaterial;
|
||||
import org.bukkit.inventory.meta.trim.TrimPattern;
|
||||
import org.bukkit.map.MapCursor;
|
||||
@ -63,6 +66,7 @@ public class RegistriesArgumentProvider implements ArgumentsProvider {
|
||||
register(Enchantment.class, Registries.ENCHANTMENT, CraftEnchantment.class, net.minecraft.world.item.enchantment.Enchantment.class);
|
||||
register(GameEvent.class, Registries.GAME_EVENT, CraftGameEvent.class, net.minecraft.world.level.gameevent.GameEvent.class);
|
||||
register(MusicInstrument.class, Registries.INSTRUMENT, CraftMusicInstrument.class, Instrument.class);
|
||||
register(MenuType.class, Registries.MENU, CraftMenuType.class, Containers.class);
|
||||
register(PotionEffectType.class, Registries.MOB_EFFECT, CraftPotionEffectType.class, MobEffectList.class);
|
||||
register(Structure.class, Registries.STRUCTURE, CraftStructure.class, net.minecraft.world.level.levelgen.structure.Structure.class);
|
||||
register(StructureType.class, Registries.STRUCTURE_TYPE, CraftStructureType.class, net.minecraft.world.level.levelgen.structure.StructureType.class);
|
||||
|
Loading…
Reference in New Issue
Block a user