Lazy tags + get / set tiles

Lazy tags means tiles/ents are not translated into the nms NBTBase until it is needed. Should be faster in cases where getFullBlock is called, but nbt is not always needed.
Commands like Copy and Paste, where the input/output are both nms worlds, can entirely bypass WorldEdit translating to and from the WorldEdit JNBT classes.
This commit is contained in:
Jesse Boyd
2019-11-20 03:40:52 +00:00
parent 60759934a3
commit 144ea2ef34
40 changed files with 298 additions and 172 deletions

View File

@ -15,7 +15,7 @@ import java.util.concurrent.Future;
/**
* An interface for getting blocks.
*/
public interface IChunkGet extends IBlocks, Trimable, InputExtent {
public interface IChunkGet extends IBlocks, Trimable, InputExtent, ITileInput {
@Override
BaseBlock getFullBlock(int x, int y, int z);
@ -26,6 +26,7 @@ public interface IChunkGet extends IBlocks, Trimable, InputExtent {
@Override
BlockState getBlock(int x, int y, int z);
@Override
CompoundTag getTag(int x, int y, int z);
@Override

View File

@ -0,0 +1,7 @@
package com.boydti.fawe.beta;
import com.sk89q.jnbt.CompoundTag;
public interface ITileInput {
CompoundTag getTag(int x, int y, int z);
}

View File

@ -2,6 +2,7 @@ package com.boydti.fawe.beta.implementation.blocks;
import com.boydti.fawe.beta.IChunkGet;
import com.boydti.fawe.beta.IChunkSet;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockTypes;
@ -11,7 +12,8 @@ public abstract class CharGetBlocks extends CharBlocks implements IChunkGet {
@Override
public BaseBlock getFullBlock(int x, int y, int z) {
return BlockTypesCache.states[get(x, y, z)].toBaseBlock();
BlockState state = BlockTypesCache.states[get(x, y, z)];
return state.toBaseBlock(this, x, y, z);
}
@Override

View File

@ -101,7 +101,7 @@ public class CharSetBlocks extends CharBlocks implements IChunkSet {
@Override
public boolean setTile(int x, int y, int z, CompoundTag tile) {
if (tiles == null) {
tiles = new BlockVector3ChunkMap<CompoundTag>();
tiles = new BlockVector3ChunkMap<>();
}
tiles.put(x, y, z, tile);
return true;

View File

@ -1213,8 +1213,6 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
char combined = block.getDefaultState().getOrdinalChar();
mainArr[index] = combined;
floorArr[index] = combined;
} else {
System.out.println("Block is null " + color + " | " + textureUtil.getClass());
}
index++;
}

View File

@ -7,12 +7,12 @@ public class MutablePair<K, V> implements Map.Entry<K, V> {
private V value;
@Override
public K getKey() {
return null;
return key;
}
@Override
public V getValue() {
return null;
return value;
}
@Override

View File

@ -4,6 +4,7 @@ import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.RegionFunction;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.block.BaseBlock;
public class SimpleBlockCopy implements RegionFunction {

View File

@ -25,6 +25,15 @@ import java.util.Locale;
* The {@code TAG_Byte_Array} tag.
*/
public final class ByteArrayTag extends Tag {
@Override
public String getTypeName() {
return "TAG_Byte_Array";
}
@Override
public int getTypeCode() {
return NBTConstants.TYPE_BYTE_ARRAY;
}
private final byte[] value;

View File

@ -23,6 +23,14 @@ package com.sk89q.jnbt;
* The {@code TAG_Byte} tag.
*/
public final class ByteTag extends NumberTag {
@Override
public int getTypeCode() {
return NBTConstants.TYPE_BYTE;
}
@Override
public String getTypeName() {
return "TAG_Byte";
}
private final byte value;

View File

@ -32,6 +32,15 @@ import java.util.UUID;
* The {@code TAG_Compound} tag.
*/
public class CompoundTag extends Tag {
@Override
public String getTypeName() {
return "TAG_Compound";
}
@Override
public int getTypeCode() {
return NBTConstants.TYPE_COMPOUND;
}
private Map<String, Tag> value;

View File

@ -24,6 +24,14 @@ package com.sk89q.jnbt;
*
*/
public final class DoubleTag extends NumberTag {
@Override
public int getTypeCode() {
return NBTConstants.TYPE_DOUBLE;
}
@Override
public String getTypeName() {
return "TAG_Double";
}
private final double value;

View File

@ -23,6 +23,15 @@ package com.sk89q.jnbt;
* The {@code TAG_End} tag.
*/
public final class EndTag extends Tag {
@Override
public String getTypeName() {
return "TAG_End";
}
@Override
public int getTypeCode() {
return NBTConstants.TYPE_END;
}
@Override
public Object getValue() {

View File

@ -23,6 +23,14 @@ package com.sk89q.jnbt;
* The {@code TAG_Float} tag.
*/
public final class FloatTag extends NumberTag {
@Override
public int getTypeCode() {
return NBTConstants.TYPE_FLOAT;
}
@Override
public String getTypeName() {
return "TAG_Float";
}
private final float value;

View File

@ -29,6 +29,15 @@ import java.util.Locale;
* The {@code TAG_Int_Array} tag.
*/
public final class IntArrayTag extends Tag {
@Override
public String getTypeName() {
return "TAG_Int_Array";
}
@Override
public int getTypeCode() {
return NBTConstants.TYPE_INT_ARRAY;
}
private final int[] value;

View File

@ -23,6 +23,14 @@ package com.sk89q.jnbt;
* The {@code TAG_Int} tag.
*/
public final class IntTag extends NumberTag {
@Override
public int getTypeCode() {
return NBTConstants.TYPE_INT;
}
@Override
public String getTypeName() {
return "TAG_Int";
}
private final int value;

View File

@ -31,6 +31,15 @@ import javax.annotation.Nullable;
* The {@code TAG_List} tag.
*/
public class ListTag extends Tag {
@Override
public String getTypeName() {
return "TAG_List";
}
@Override
public int getTypeCode() {
return NBTConstants.TYPE_LIST;
}
private final Class<? extends Tag> type;
private final List<Tag> value;
@ -432,7 +441,7 @@ public class ListTag extends Tag {
@Override
public String toString() {
StringBuilder bldr = new StringBuilder();
bldr.append("TAG_List").append(": ").append(value.size()).append(" entries of type ").append(NBTUtils.getTypeName(type)).append("\r\n{\r\n");
bldr.append("TAG_List").append(": ").append(value.size()).append(" entries of type ").append(type.getTypeName()).append("\r\n{\r\n");
for (Tag t : value) {
bldr.append(" ").append(t.toString().replaceAll("\r\n", "\r\n ")).append("\r\n");
}

View File

@ -29,6 +29,15 @@ import java.util.Locale;
* The {@code TAG_Long_Array} tag.
*/
public class LongArrayTag extends Tag {
@Override
public String getTypeName() {
return "TAG_Long_Array";
}
@Override
public int getTypeCode() {
return NBTConstants.TYPE_LONG_ARRAY;
}
private final long[] value;

View File

@ -24,6 +24,14 @@ package com.sk89q.jnbt;
*
*/
public final class LongTag extends NumberTag {
@Override
public int getTypeCode() {
return NBTConstants.TYPE_LONG;
}
@Override
public String getTypeName() {
return "TAG_Long";
}
private final long value;

View File

@ -90,7 +90,7 @@ public final class NBTOutputStream extends OutputStream implements Closeable, Da
checkNotNull(name);
checkNotNull(tag);
int type = NBTUtils.getTypeCode(tag.getClass());
int type = tag.getTypeCode();
writeNamedTagName(name, type);
if (type == NBTConstants.TYPE_END) {
@ -189,7 +189,7 @@ public final class NBTOutputStream extends OutputStream implements Closeable, Da
}
public void writeTag(Tag tag) throws IOException {
int type = NBTUtils.getTypeCode(tag.getClass());
int type = tag.getTypeCode();
os.writeByte(type);
writeTagPayload(tag);
}
@ -207,7 +207,7 @@ public final class NBTOutputStream extends OutputStream implements Closeable, Da
* if an I/O error occurs.
*/
public void writeTagPayload(Tag tag) throws IOException {
int type = NBTUtils.getTypeCode(tag.getClass());
int type = tag.getTypeCode();
switch (type) {
case NBTConstants.TYPE_END:
writeEndTagPayload((EndTag) tag);
@ -311,7 +311,7 @@ public final class NBTOutputStream extends OutputStream implements Closeable, Da
int size = tags.size();
if (!tags.isEmpty()) {
Tag tag0 = tags.get(0);
os.writeByte(NBTUtils.getTypeCode(tag0.getClass()));
os.writeByte(tag0.getTypeCode());
} else {
os.writeByte(NBTUtils.getTypeCode(clazz));
}

View File

@ -49,7 +49,7 @@ public final class NBTUtils {
return "TAG_Byte_Array";
} else if (clazz.equals(ByteTag.class)) {
return "TAG_Byte";
} else if (clazz.equals(CompoundTag.class)) {
} else if (CompoundTag.class.isAssignableFrom(clazz)) {
return "TAG_Compound";
} else if (clazz.equals(DoubleTag.class)) {
return "TAG_Double";
@ -89,7 +89,7 @@ public final class NBTUtils {
return NBTConstants.TYPE_BYTE_ARRAY;
} else if (clazz.equals(ByteTag.class)) {
return NBTConstants.TYPE_BYTE;
} else if (clazz.equals(CompoundTag.class)) {
} else if (CompoundTag.class.isAssignableFrom(clazz)) {
return NBTConstants.TYPE_COMPOUND;
} else if (clazz.equals(DoubleTag.class)) {
return NBTConstants.TYPE_DOUBLE;

View File

@ -23,6 +23,14 @@ package com.sk89q.jnbt;
* The {@code TAG_Short} tag.
*/
public final class ShortTag extends NumberTag {
@Override
public int getTypeCode() {
return NBTConstants.TYPE_SHORT;
}
@Override
public String getTypeName() {
return "TAG_Short";
}
private final short value;

View File

@ -25,6 +25,15 @@ import static com.google.common.base.Preconditions.checkNotNull;
* The {@code TAG_String} tag.
*/
public final class StringTag extends Tag {
@Override
public String getTypeName() {
return "TAG_String";
}
@Override
public int getTypeCode() {
return NBTConstants.TYPE_STRING;
}
private final String value;

View File

@ -35,4 +35,8 @@ public abstract class Tag {
return getValue();
}
public abstract int getTypeCode();
public abstract String getTypeName();
}

View File

@ -154,15 +154,6 @@ public class BrushCommands {
this.worldEdit = worldEdit;
}
@Command(
name = "none",
aliases = "unbind",
desc = "Unbind a bound brush from your current item"
)
void none(Player player, LocalSession session) throws WorldEditException {
ToolCommands.setToolNone(player, session, "Brush");
}
@Command(
name = "blendball",
aliases = {"bb", "blend"},
@ -959,52 +950,6 @@ public class BrushCommands {
return process(player, arguments, bs);
}
@Command(
name = "forest",
desc = "Forest brush, creates a forest in the area"
)
@CommandPermissions("worldedit.brush.forest")
public void forest(Player player, LocalSession localSession,
@Arg(desc = "The shape of the region")
RegionFactory shape,
@Arg(desc = "The size of the brush", def = "5")
Expression radius,
@Arg(desc = "The density of the brush", def = "20")
double density,
@Arg(desc = "The type of tree to use")
TreeGenerator.TreeType type) throws WorldEditException, EvaluationException {
setOperationBasedBrush(player, localSession, radius,
new Paint(new TreeGeneratorFactory(type), density / 100), shape, "worldedit.brush.forest");
}
@Command(
name = "raise",
desc = "Raise brush, raise all blocks by one"
)
@CommandPermissions("worldedit.brush.raise")
public void raise(Player player, LocalSession localSession,
@Arg(desc = "The shape of the region")
RegionFactory shape,
@Arg(desc = "The size of the brush", def = "5")
Expression radius) throws WorldEditException, EvaluationException {
setOperationBasedBrush(player, localSession, radius,
new Deform("y-=1"), shape, "worldedit.brush.raise");
}
@Command(
name = "lower",
desc = "Lower brush, lower all blocks by one"
)
@CommandPermissions("worldedit.brush.lower")
public void lower(Player player, LocalSession localSession,
@Arg(desc = "The shape of the region")
RegionFactory shape,
@Arg(desc = "The size of the brush", def = "5")
Expression radius) throws WorldEditException, EvaluationException {
setOperationBasedBrush(player, localSession, radius,
new Deform("y+=1"), shape, "worldedit.brush.lower");
}
@Command(
name = "savebrush",
aliases = {"save"},
@ -1139,7 +1084,7 @@ public class BrushCommands {
@Arg(desc = "The shape of the region")
RegionFactory shape,
@Arg(desc = "The size of the brush", def = "5")
double radius,
Expression radius,
@Arg(desc = "The pattern of blocks to set")
Pattern pattern) throws WorldEditException {
setOperationBasedBrush(player, localSession, radius,
@ -1155,7 +1100,7 @@ public class BrushCommands {
@Arg(desc = "The shape of the region")
RegionFactory shape,
@Arg(desc = "The size of the brush", def = "5")
double radius,
Expression radius,
@Arg(desc = "The density of the brush", def = "20")
double density,
@Arg(desc = "The type of tree to use")
@ -1173,7 +1118,7 @@ public class BrushCommands {
@Arg(desc = "The shape of the region")
RegionFactory shape,
@Arg(desc = "The size of the brush", def = "5")
double radius) throws WorldEditException {
Expression radius) throws WorldEditException {
setOperationBasedBrush(player, localSession, radius,
new Deform("y-=1"), shape, "worldedit.brush.raise");
}
@ -1187,7 +1132,7 @@ public class BrushCommands {
@Arg(desc = "The shape of the region")
RegionFactory shape,
@Arg(desc = "The size of the brush", def = "5")
double radius) throws WorldEditException {
Expression radius) throws WorldEditException {
setOperationBasedBrush(player, localSession, radius,
new Deform("y+=1"), shape, "worldedit.brush.lower");
}

View File

@ -110,28 +110,26 @@ public class RegionCommands {
}
@Command(
name = "/set",
desc = "Sets all the blocks in the region"
name = "/set",
aliases = {"/"},
desc = "Sets all the blocks in the region"
)
@CommandPermissions("worldedit.region.set")
@Logging(REGION)
public int set(Actor actor, EditSession editSession,
@Selection Region region,
@Arg(desc = "The pattern of blocks to set")
Pattern pattern) {
RegionFunction set = new BlockReplace(editSession, pattern);
RegionVisitor visitor = new RegionVisitor(region, set);
Operations.completeBlindly(visitor);
List<String> messages = Lists.newArrayList();
visitor.addStatusMessages(messages);
if (messages.isEmpty()) {
actor.print("Operation completed.");
} else {
actor.print("Operation completed (" + Joiner.on(", ").join(messages) + ").");
}
return visitor.getAffected();
Pattern pattern,
InjectedValueAccess context) {
actor.checkConfirmationRegion(() -> {
int affected = editSession.setBlocks(region, pattern);
if (affected != 0) {
BBC.OPERATION.send(actor, affected);
if (!actor.hasPermission("fawe.tips"))
BBC.TIP_FAST.or(BBC.TIP_CANCEL, BBC.TIP_MASK, BBC.TIP_MASK_ANGLE, BBC.TIP_SET_LINEAR, BBC.TIP_SURFACE_SPREAD, BBC.TIP_SET_HAND).send(actor);
}
}, getArguments(context), region, context);
return 0;
}
@Command(
@ -147,27 +145,6 @@ public class RegionCommands {
set(actor, editSession, region, BlockTypes.AIR, context);
}
@Command(
name = "/set",
aliases = {"/"},
desc = "Sets all the blocks in the region"
)
@CommandPermissions("worldedit.region.set")
@Logging(REGION)
public void set(Actor actor, EditSession editSession,
@Selection Region region,
@Arg(desc = "The pattern of blocks to set")
Pattern pattern, InjectedValueAccess context) throws WorldEditException {
actor.checkConfirmationRegion(() -> {
int affected = editSession.setBlocks(region, pattern);
if (affected != 0) {
BBC.OPERATION.send(actor, affected);
if (!actor.hasPermission("fawe.tips"))
BBC.TIP_FAST.or(BBC.TIP_CANCEL, BBC.TIP_MASK, BBC.TIP_MASK_ANGLE, BBC.TIP_SET_LINEAR, BBC.TIP_SURFACE_SPREAD, BBC.TIP_SET_HAND).send(actor);
}
}, getArguments(context), region, context);
}
@Command(
name = "/test",
desc = "test region"
@ -175,13 +152,11 @@ public class RegionCommands {
@CommandPermissions("worldedit.region.test")
@Logging(REGION)
public void test(Player player, EditSession editSession, @Selection Region region, @Arg(desc = "hello there") BiomeType biome) throws WorldEditException {
System.out.println("Test start");
editSession.addProcessor(new ChunkSendProcessor(editSession.getWorld(), () -> Collections.singleton(player)));
editSession.addProcessor(NullProcessor.INSTANCE);
FlatRegionFunction replace = new BiomeReplace(editSession, biome);
FlatRegionVisitor visitor = new FlatRegionVisitor(Regions.asFlatRegion(region), replace);
Operations.completeLegacy(visitor);
System.out.println("Test end");
}
@Command(

View File

@ -179,9 +179,9 @@ public class ToolUtilCommands {
}
@Command(
name = "/",
aliases = { "," },
desc = "Toggle the super pickaxe function"
name = "/superpickaxe",
aliases = {",", "/sp", "/pickaxe"},
desc = "Toggle the super pickaxe function"
)
@CommandPermissions("worldedit.superpickaxe")
public void togglePickaxe(Player player, LocalSession session,

View File

@ -56,7 +56,7 @@ import org.enginehub.piston.annotation.param.Arg;
import org.enginehub.piston.annotation.param.ArgFlag;
import org.enginehub.piston.annotation.param.Switch;
@CommandContainer(superTypes = CommandPermissionsConditionGenerator.Registration.class)
@CommandContainer(superTypes = {CommandPermissionsConditionGenerator.Registration.class, CommandQueuedConditionGenerator.Registration.class})
public class WorldEditCommands {
private static final DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss z");

View File

@ -79,6 +79,7 @@ public enum Capability {
* The capability of a platform to perform modifications to a world.
*/
WORLD_EDITING {
/*
@Override
void initialize(PlatformManager platformManager, Platform platform) {
BlockRegistry blockRegistry = platform.getRegistries().getBlockRegistry();
@ -93,6 +94,7 @@ public enum Capability {
void unload(PlatformManager platformManager, Platform platform) {
BlockStateIdAccess.clear();
}
*/
};
void initialize(PlatformManager platformManager, Platform platform) {

View File

@ -31,7 +31,7 @@ import java.util.OptionalInt;
import static com.google.common.base.Preconditions.checkState;
public final class BlockStateIdAccess {
/*
private static final BiMap<BlockState, Integer> ASSIGNED_IDS = HashBiMap.create(2 << 13);
public static OptionalInt getBlockStateId(BlockState holder) {
@ -49,7 +49,7 @@ public final class BlockStateIdAccess {
* {@link OptionalInt#empty()}. In those cases, we will use our own ID system,
* since it's useful for other entries as well.
* @return an unused ID in WorldEdit's ID tracker
*/
/
private static int provideUnusedWorldEditId() {
return usedIds.nextClearBit(0);
}
@ -73,5 +73,12 @@ public final class BlockStateIdAccess {
private BlockStateIdAccess() {
}
*/
public static OptionalInt getBlockStateId(BlockState holder) {
return OptionalInt.of(holder.getOrdinal());
}
public static @Nullable BlockState getBlockStateById(int id) {
return BlockState.getFromOrdinal(id);
}
}

View File

@ -21,6 +21,7 @@ package com.sk89q.worldedit.world.block;
import static com.google.common.base.Preconditions.checkNotNull;
import com.boydti.fawe.beta.ITileInput;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.StringTag;
import com.sk89q.jnbt.Tag;
@ -162,11 +163,6 @@ public class BaseBlock implements BlockStateHolder<BaseBlock>, TileEntityBlock {
return this.nbtData;
}
@Override
public void setNbtData(@Nullable CompoundTag nbtData) {
throw new UnsupportedOperationException("This class is immutable.");
}
/**
* Checks whether the type ID and data value are equal.
*/

View File

@ -19,6 +19,7 @@
package com.sk89q.worldedit.world.block;
import com.boydti.fawe.beta.ITileInput;
import com.boydti.fawe.command.SuggestInputParseException;
import com.boydti.fawe.object.string.MutableCharSequence;
import com.boydti.fawe.util.StringMan;
@ -53,7 +54,8 @@ public class BlockState implements BlockStateHolder<BlockState>, FawePattern {
private final char ordinalChar;
private final BlockType blockType;
private BlockMaterial material;
private BaseBlock emptyBaseBlock;
private final BaseBlock emptyBaseBlock;
private CompoundInput compoundInput = CompoundInput.NULL;
protected BlockState(BlockType blockType, int internalId, int ordinal) {
this.blockType = blockType;
@ -196,7 +198,6 @@ public class BlockState implements BlockStateHolder<BlockState>, FawePattern {
case '=': {
charSequence.setSubstring(last, i);
property = (AbstractProperty) type.getPropertyMap().get(charSequence);
if (property == null) System.out.println("No prop " + charSequence + " | " + type.getPropertyMap());
last = i + 1;
break;
}
@ -356,6 +357,9 @@ public class BlockState implements BlockStateHolder<BlockState>, FawePattern {
return this.material = blockType.getMaterial();
}
this.material = WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.GAME_HOOKS).getRegistries().getBlockRegistry().getMaterial(this);
if (this.material.hasContainer()) {
this.compoundInput = CompoundInput.CONTAINER;
}
}
return material;
}
@ -388,4 +392,17 @@ public class BlockState implements BlockStateHolder<BlockState>, FawePattern {
public int hashCode() {
return getOrdinal();
}
public boolean isAir() {
try {
return material.isAir();
} catch (NullPointerException ignore) {
return getMaterial().isAir();
}
}
@Override
public BaseBlock toBaseBlock(ITileInput input, int x, int y, int z) {
return compoundInput.get(this, input, x, y, z);
}
}

View File

@ -19,7 +19,9 @@
package com.sk89q.worldedit.world.block;
import com.boydti.fawe.beta.ITileInput;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.blocks.TileEntityBlock;
import com.sk89q.worldedit.extent.OutputExtent;
@ -203,6 +205,10 @@ public interface BlockStateHolder<B extends BlockStateHolder<B>> extends FawePat
throw new UnsupportedOperationException("State is immutable");
}
default BaseBlock toBaseBlock(ITileInput input, int x, int y, int z) {
throw new UnsupportedOperationException("State is immutable");
}
default String getAsString() {
if (getStates().isEmpty()) {
return this.getBlockType().getId();

View File

@ -0,0 +1,18 @@
package com.sk89q.worldedit.world.block;
import com.boydti.fawe.beta.ITileInput;
public enum CompoundInput {
NULL,
CONTAINER() {
@Override
public BaseBlock get(BlockState state, ITileInput input, int x, int y, int z) {
return state.toBaseBlock(input.getTag(x, y, z));
}
}
;
public BaseBlock get(BlockState state, ITileInput input, int x, int y, int z) {
return state.toBaseBlock();
}
}

View File

@ -1,5 +1,6 @@
package com.sk89q.worldedit.world.block;
import com.boydti.fawe.beta.ITileInput;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.extent.Extent;

View File

@ -934,7 +934,6 @@ public final class ItemTypes {
}
String name = fieldsTmp[initIndex++].getName().toLowerCase(Locale.ROOT);
CharSequence fullName = joined.init(ItemType.REGISTRY.getDefaultNamespace(), ':', name);
System.out.println("Name " + fullName + " | " + ItemType.REGISTRY.getMap().get(fullName));
return ItemType.REGISTRY.getMap().get(fullName);
} catch (Throwable e) {
e.printStackTrace();