-
Notifications
You must be signed in to change notification settings - Fork 71
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for custom tags in item meta
- Loading branch information
1 parent
91618b7
commit 1a9de89
Showing
8 changed files
with
484 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
67 changes: 67 additions & 0 deletions
67
src/main/java/com/laytonsmith/abstraction/MCTagContainer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
package com.laytonsmith.abstraction; | ||
|
||
import com.laytonsmith.abstraction.enums.MCTagType; | ||
|
||
import java.util.Collection; | ||
|
||
/** | ||
* Minecraft NBT containers that can be used to read and modify tags in supported game objects. | ||
* This includes item meta, entities, block entities, chunks, worlds, etc. | ||
*/ | ||
public interface MCTagContainer extends AbstractionObject { | ||
|
||
/** | ||
* Returns whether the tag container does not contain any tags. | ||
* @return whether container is empty | ||
*/ | ||
boolean isEmpty(); | ||
|
||
/** | ||
* Gets a set of key objects for each tag that exists in this container. | ||
* These are minecraft formatted namespaced keys. (e.g. "namespace:key") | ||
* These key objects can be passed to other methods in this class. | ||
* @return a set of keys | ||
*/ | ||
Collection getKeys(); | ||
|
||
/** | ||
* Returns the tag type with the given key. | ||
* MCTagType can be used to convert tags to and from MethodScript constructs. | ||
* Returns null if a tag with that key does not exist. | ||
* @param key the tag key | ||
* @return the type for the tag | ||
*/ | ||
MCTagType getType(Object key); | ||
|
||
/** | ||
* Returns the tag value with the given key and tag type. | ||
* Returns null if a tag with that key and type does not exist. | ||
* @param key the tag key | ||
* @param type the tag type | ||
* @return the value for the tag | ||
*/ | ||
Object get(Object key, MCTagType type); | ||
|
||
/** | ||
* Sets the tag value with the given key and tag type. | ||
* Throws an IllegalArgumentException if the type and value do not match. | ||
* @param key the tag key | ||
* @param type the tag type | ||
* @param value the tag value | ||
*/ | ||
void set(Object key, MCTagType type, Object value); | ||
|
||
/** | ||
* Deletes the tag with the given key from this container. | ||
* @param key the tag key | ||
*/ | ||
void remove(Object key); | ||
|
||
/** | ||
* Creates a new tag container from this container context. | ||
* This can then be used to nest a tag container with the {@link #set} method. | ||
* @return a new tag container | ||
*/ | ||
MCTagContainer newContainer(); | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
164 changes: 164 additions & 0 deletions
164
src/main/java/com/laytonsmith/abstraction/bukkit/BukkitMCTagContainer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
package com.laytonsmith.abstraction.bukkit; | ||
|
||
import com.laytonsmith.abstraction.MCTagContainer; | ||
import com.laytonsmith.abstraction.enums.MCTagType; | ||
import com.laytonsmith.commandhelper.CommandHelperPlugin; | ||
import org.bukkit.NamespacedKey; | ||
import org.bukkit.persistence.PersistentDataContainer; | ||
import org.bukkit.persistence.PersistentDataType; | ||
|
||
import java.util.Collection; | ||
|
||
public class BukkitMCTagContainer implements MCTagContainer { | ||
|
||
PersistentDataContainer pdc; | ||
|
||
public BukkitMCTagContainer(PersistentDataContainer pdc) { | ||
this.pdc = pdc; | ||
} | ||
|
||
@Override | ||
public MCTagContainer newContainer() { | ||
return new BukkitMCTagContainer(pdc.getAdapterContext().newPersistentDataContainer()); | ||
} | ||
|
||
@Override | ||
public boolean isEmpty() { | ||
return this.pdc.isEmpty(); | ||
} | ||
|
||
@Override | ||
public Collection getKeys() { | ||
return pdc.getKeys(); | ||
} | ||
|
||
@Override | ||
public MCTagType getType(Object key) { | ||
NamespacedKey namespacedKey = NamespacedKey(key); | ||
// Check tag types in order of most frequently used | ||
if(pdc.has(namespacedKey, PersistentDataType.STRING)) { | ||
return MCTagType.STRING; | ||
} else if(pdc.has(namespacedKey, PersistentDataType.INTEGER)) { | ||
return MCTagType.INTEGER; | ||
} else if(pdc.has(namespacedKey, PersistentDataType.BYTE)) { | ||
return MCTagType.BYTE; | ||
} else if(pdc.has(namespacedKey, PersistentDataType.DOUBLE)) { | ||
return MCTagType.DOUBLE; | ||
} else if(pdc.has(namespacedKey, PersistentDataType.LONG)) { | ||
return MCTagType.LONG; | ||
} else if(pdc.has(namespacedKey, PersistentDataType.FLOAT)) { | ||
return MCTagType.FLOAT; | ||
} else if(pdc.has(namespacedKey, PersistentDataType.TAG_CONTAINER)) { | ||
return MCTagType.TAG_CONTAINER; | ||
} else if(pdc.has(namespacedKey, PersistentDataType.BYTE_ARRAY)) { | ||
return MCTagType.BYTE_ARRAY; | ||
} else if(pdc.has(namespacedKey, PersistentDataType.SHORT)) { | ||
return MCTagType.SHORT; | ||
} else if(pdc.has(namespacedKey, PersistentDataType.INTEGER_ARRAY)) { | ||
return MCTagType.INTEGER_ARRAY; | ||
} else if(pdc.has(namespacedKey, PersistentDataType.LONG_ARRAY)) { | ||
return MCTagType.LONG_ARRAY; | ||
} else if(pdc.has(namespacedKey, PersistentDataType.TAG_CONTAINER_ARRAY)) { | ||
return MCTagType.TAG_CONTAINER_ARRAY; | ||
} | ||
return null; | ||
} | ||
|
||
@Override | ||
public Object get(Object key, MCTagType type) { | ||
PersistentDataType bukkitType = GetPersistentDataType(type); | ||
Object value = pdc.get(NamespacedKey(key), bukkitType); | ||
if(value instanceof PersistentDataContainer) { | ||
return new BukkitMCTagContainer((PersistentDataContainer) value); | ||
} else if(value instanceof PersistentDataContainer[] concreteContainers) { | ||
MCTagContainer[] abstractContainers = new MCTagContainer[concreteContainers.length]; | ||
for(int i = 0; i < concreteContainers.length; i++) { | ||
abstractContainers[i] = new BukkitMCTagContainer(concreteContainers[i]); | ||
} | ||
return abstractContainers; | ||
} | ||
return value; | ||
} | ||
|
||
@Override | ||
public void set(Object key, MCTagType type, Object value) { | ||
PersistentDataType bukkitType = GetPersistentDataType(type); | ||
if(value instanceof MCTagContainer) { | ||
value = ((MCTagContainer) value).getHandle(); | ||
} else if(value instanceof MCTagContainer[] abstractContainers) { | ||
PersistentDataContainer[] concreteContainers = new PersistentDataContainer[abstractContainers.length]; | ||
for(int i = 0; i < abstractContainers.length; i++) { | ||
concreteContainers[i] = (PersistentDataContainer) abstractContainers[i].getHandle(); | ||
} | ||
value = concreteContainers; | ||
} | ||
pdc.set(NamespacedKey(key), bukkitType, value); | ||
} | ||
|
||
@Override | ||
public void remove(Object key) { | ||
pdc.remove(NamespacedKey(key)); | ||
} | ||
|
||
private static NamespacedKey NamespacedKey(Object key) { | ||
if(key instanceof NamespacedKey) { | ||
return (NamespacedKey) key; | ||
} else if(key instanceof String) { | ||
NamespacedKey namespacedKey = NamespacedKey.fromString((String) key, CommandHelperPlugin.self); | ||
if(namespacedKey != null) { | ||
return namespacedKey; | ||
} | ||
} | ||
throw new IllegalArgumentException("Invalid namespaced key."); | ||
} | ||
|
||
private static PersistentDataType GetPersistentDataType(MCTagType type) { | ||
switch(type) { | ||
case BYTE: | ||
return PersistentDataType.BYTE; | ||
case BYTE_ARRAY: | ||
return PersistentDataType.BYTE_ARRAY; | ||
case DOUBLE: | ||
return PersistentDataType.DOUBLE; | ||
case FLOAT: | ||
return PersistentDataType.FLOAT; | ||
case INTEGER: | ||
return PersistentDataType.INTEGER; | ||
case INTEGER_ARRAY: | ||
return PersistentDataType.INTEGER_ARRAY; | ||
case LONG: | ||
return PersistentDataType.LONG; | ||
case LONG_ARRAY: | ||
return PersistentDataType.LONG_ARRAY; | ||
case SHORT: | ||
return PersistentDataType.SHORT; | ||
case STRING: | ||
return PersistentDataType.STRING; | ||
case TAG_CONTAINER: | ||
return PersistentDataType.TAG_CONTAINER; | ||
case TAG_CONTAINER_ARRAY: | ||
return PersistentDataType.TAG_CONTAINER_ARRAY; | ||
} | ||
throw new IllegalArgumentException("Invalid persistent data type: " + type.name()); | ||
} | ||
|
||
@Override | ||
public Object getHandle() { | ||
return pdc; | ||
} | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
return o instanceof MCTagContainer && this.pdc.equals(((MCTagContainer) o).getHandle()); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return pdc.hashCode(); | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return pdc.toString(); | ||
} | ||
} |
Oops, something went wrong.