mirror of
https://github.com/dmulloy2/ProtocolLib.git
synced 2025-01-18 22:31:31 +01:00
Add BlockEntityType support. (#2111)
This commit is contained in:
parent
38bbd764cc
commit
46f6e76f91
@ -29,6 +29,7 @@ import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.MerchantRecipe;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public abstract class AbstractStructure {
|
||||
protected transient Object handle;
|
||||
@ -308,6 +309,31 @@ public abstract class AbstractStructure {
|
||||
BlockPosition.getConverter());
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a read/write structure for registrable objects.
|
||||
*
|
||||
* @param registrableClass The registrable object's class.
|
||||
* @return A modifier for a registrable objects.
|
||||
* @see MinecraftReflection#getBlockEntityTypeClass()
|
||||
*/
|
||||
public StructureModifier<WrappedRegistrable> getRegistrableModifier(
|
||||
@NotNull final Class<?> registrableClass
|
||||
) {
|
||||
// Convert to and from the Bukkit wrapper
|
||||
return structureModifier.withType(
|
||||
registrableClass,
|
||||
BukkitConverters.getWrappedRegistrable(registrableClass));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a read/write structure for BlockEntityType.
|
||||
* @return A modifier for a BlockEntityType.
|
||||
*/
|
||||
public StructureModifier<WrappedRegistrable> getBlockEntityTypeModifier() {
|
||||
// Convert to and from the Bukkit wrapper
|
||||
return getRegistrableModifier(MinecraftReflection.getBlockEntityTypeClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a read/write structure for wrapped ChunkCoordIntPairs.
|
||||
* @return A modifier for ChunkCoordIntPair.
|
||||
|
@ -77,6 +77,7 @@ import org.bukkit.inventory.MerchantRecipe;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import static com.comphenix.protocol.utility.MinecraftReflection.getCraftBukkitClass;
|
||||
import static com.comphenix.protocol.utility.MinecraftReflection.getMinecraftClass;
|
||||
@ -587,7 +588,23 @@ public class BukkitConverters {
|
||||
public static EquivalentConverter<WrappedBlockData> getWrappedBlockDataConverter() {
|
||||
return ignoreNull(handle(WrappedBlockData::getHandle, WrappedBlockData::fromHandle, WrappedBlockData.class));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieve a converter for wrapped block entity type.
|
||||
* @return Wrapped block entity type.
|
||||
*/
|
||||
public static EquivalentConverter<WrappedRegistrable> getWrappedRegistrable(
|
||||
@NotNull final Class<?> registrableClass
|
||||
) {
|
||||
return ignoreNull(
|
||||
handle(
|
||||
WrappedRegistrable::getHandle,
|
||||
handle -> WrappedRegistrable.fromHandle(registrableClass, handle),
|
||||
WrappedRegistrable.class
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a converter for wrapped attribute snapshots.
|
||||
* @return Wrapped attribute snapshot converter.
|
||||
|
@ -0,0 +1,185 @@
|
||||
/**
|
||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||
* Copyright (C) 2015 dmulloy2
|
||||
* <p>
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
* <p>
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
* <p>
|
||||
* You should have received a copy of the GNU General Public License along with this program;
|
||||
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
* 02111-1307 USA
|
||||
*/
|
||||
package com.comphenix.protocol.wrappers;
|
||||
|
||||
import com.comphenix.protocol.reflect.FuzzyReflection;
|
||||
import com.comphenix.protocol.reflect.accessors.Accessors;
|
||||
import com.comphenix.protocol.reflect.accessors.FieldAccessor;
|
||||
import com.comphenix.protocol.reflect.fuzzy.FuzzyFieldContract;
|
||||
import com.comphenix.protocol.utility.MinecraftReflection;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* Represents a wrapper around registrable objects.
|
||||
*
|
||||
* @author portlek
|
||||
*/
|
||||
public final class WrappedRegistrable extends AbstractWrapper implements ClonableWrapper {
|
||||
|
||||
@NotNull
|
||||
private final Factory factory;
|
||||
|
||||
private WrappedRegistrable(
|
||||
@NotNull final Factory factory,
|
||||
@NotNull final Object handle
|
||||
) {
|
||||
super(factory.registrableClass);
|
||||
this.factory = factory;
|
||||
setHandle(handle);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static WrappedRegistrable fromHandle(
|
||||
@NotNull final Factory factory,
|
||||
@NotNull final Object handle
|
||||
) {
|
||||
return new WrappedRegistrable(factory, handle);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static WrappedRegistrable fromHandle(
|
||||
@NotNull final Class<?> registrableClass,
|
||||
@NotNull final Object handle
|
||||
) {
|
||||
return fromHandle(Factory.getOrCreate(registrableClass), handle);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static WrappedRegistrable fromClassAndKey(
|
||||
@NotNull final Class<?> registrableClass,
|
||||
@NotNull final MinecraftKey key
|
||||
) {
|
||||
final Factory factory = Factory.getOrCreate(registrableClass);
|
||||
return fromHandle(factory, factory.getHandle(key));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static WrappedRegistrable fromClassAndKey(
|
||||
@NotNull final Class<?> registrableClass,
|
||||
@NotNull final String key
|
||||
) {
|
||||
return fromClassAndKey(registrableClass, new MinecraftKey(key));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static WrappedRegistrable blockEntityType(
|
||||
@NotNull final MinecraftKey key
|
||||
) {
|
||||
return fromClassAndKey(MinecraftReflection.getBlockEntityTypeClass(), key);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static WrappedRegistrable blockEntityType(
|
||||
@NotNull final String key
|
||||
) {
|
||||
return blockEntityType(new MinecraftKey(key));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this registrable object's Minecraft key
|
||||
*
|
||||
* @return The Minecraft key
|
||||
*/
|
||||
public MinecraftKey getKey() {
|
||||
return factory.getKey(handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this registrable object's Minecraft key
|
||||
*
|
||||
* @param key Minecraft key
|
||||
*/
|
||||
public void setKey(MinecraftKey key) {
|
||||
setHandle(factory.getHandle(key));
|
||||
}
|
||||
|
||||
public WrappedRegistrable deepClone() {
|
||||
return fromHandle(factory, handle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "WrappedRegistrable[handle=" + handle + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + getKey().hashCode();
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o == this) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof WrappedRegistrable)) {
|
||||
return false;
|
||||
}
|
||||
final WrappedRegistrable that = (WrappedRegistrable) o;
|
||||
return handle.equals(that.handle) || (getKey() == that.getKey());
|
||||
}
|
||||
|
||||
private static final class Factory {
|
||||
|
||||
private static final Map<Class<?>, Factory> CACHE = new ConcurrentHashMap<>();
|
||||
|
||||
@NotNull
|
||||
private final Class<?> registrableClass;
|
||||
|
||||
@NotNull
|
||||
private final WrappedRegistry registry;
|
||||
|
||||
@NotNull
|
||||
private final FieldAccessor fieldAccessor;
|
||||
|
||||
private Factory(@NotNull final Class<?> registrableClass) {
|
||||
this.registrableClass = registrableClass;
|
||||
this.registry = WrappedRegistry.getRegistry(registrableClass);
|
||||
this.fieldAccessor = Accessors.getFieldAccessor(
|
||||
FuzzyReflection.fromClass(registrableClass, true)
|
||||
.getField(
|
||||
FuzzyFieldContract.newBuilder()
|
||||
.typeExact(registrableClass)
|
||||
.build()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Factory getOrCreate(
|
||||
@NotNull final Class<?> registrableClass
|
||||
) {
|
||||
return CACHE.computeIfAbsent(registrableClass, Factory::new);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public MinecraftKey getKey(@NotNull final Object handle) {
|
||||
return registry.getKey(fieldAccessor.get(handle));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Object getHandle(MinecraftKey key) {
|
||||
return registry.get(key);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user