-
Notifications
You must be signed in to change notification settings - Fork 72
Add support for custom tags in item meta #1366
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
PseudoKnight
merged 2 commits into
EngineHub:master
from
PseudoKnight:persistent-data-container
Oct 4, 2023
Merged
Changes from 1 commit
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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 hidden or 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 hidden or 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 hidden or 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.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.