Implement CustomItems support.

This commit is contained in:
Vatuu 2023-03-13 13:19:37 +01:00
parent 20ceaead09
commit cc90f42deb
No known key found for this signature in database
GPG Key ID: C6F07B79B2ED9150
12 changed files with 293 additions and 116 deletions

1
.gitignore vendored
View File

@ -1,5 +1,6 @@
build/
libs/
.gradle/

View File

@ -136,6 +136,7 @@ dependencies {
implementation 'com.github.oraxen:oraxen:1.152.5'
implementation 'com.github.LoneDev6:api-itemsadder:3.2.5'
implementation 'me.clip:placeholderapi:2.11.1'
implementation files('libs/CustomItems.jar')
// Shaded
implementation 'com.dfsek:Paralithic:0.4.0'

View File

@ -0,0 +1,102 @@
package com.volmit.iris.core.link;
import com.jojodmo.customitems.api.CustomItemsAPI;
import com.jojodmo.customitems.item.custom.CustomItem;
import com.jojodmo.customitems.item.custom.block.CustomMushroomBlock;
import com.jojodmo.customitems.version.SafeMaterial;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.reflect.WrappedField;
import com.volmit.iris.util.reflect.WrappedReturningMethod;
import org.bukkit.block.BlockFace;
import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.MultipleFacing;
import org.bukkit.inventory.ItemStack;
import java.util.Map;
import java.util.MissingResourceException;
public class CustomItemsDataProvider extends ExternalDataProvider {
private static final String FIELD_FACES = "faces";
private static final String METHOD_GET_MATERIAL = "getMaterial";
private WrappedField<CustomMushroomBlock, Map<Integer, boolean[]>> mushroomFaces;
private WrappedReturningMethod<CustomMushroomBlock, SafeMaterial> mushroomMaterial;
public CustomItemsDataProvider() {
super("CustomItems");
}
@Override
public void init() {
this.mushroomFaces = new WrappedField<>(CustomMushroomBlock.class, FIELD_FACES);
this.mushroomMaterial = new WrappedReturningMethod<>(CustomMushroomBlock.class, METHOD_GET_MATERIAL);
}
@Override
public BlockData getBlockData(Identifier blockId) throws MissingResourceException {
CustomItem item = CustomItem.get(blockId.key());
if(item == null) {
throw new MissingResourceException("Failed to find BlockData!", blockId.namespace(), blockId.key());
} else if(item.getBlockTexture().isSpawner()) {
throw new MissingResourceException("Iris does not yet support SpawnerBlocks from CustomItems.", blockId.namespace(), blockId.key());
} else if(item.getBlockTexture() != null && item.getBlockTexture().isValid()) {
throw new MissingResourceException("Tried to fetch BlockData for a CustomItem that is not placeable!", blockId.namespace(), blockId.key());
}
return getMushroomData(item);
}
@Override
public ItemStack getItemStack(Identifier itemId) throws MissingResourceException {
ItemStack stack = CustomItemsAPI.getCustomItem(itemId.key());
if(stack == null) {
throw new MissingResourceException("Failed to find ItemData!", itemId.namespace(), itemId.key());
}
return stack;
}
@Override
public Identifier[] getBlockTypes() {
KList<Identifier> names = new KList<>();
for (String name : CustomItemsAPI.listBlockCustomItemIDs()) {
try {
Identifier key = new Identifier("cui", name);
if (getItemStack(key) != null)
names.add(key);
} catch (MissingResourceException ignored) { }
}
return names.toArray(new Identifier[0]);
}
@Override
public Identifier[] getItemTypes() {
KList<Identifier> names = new KList<>();
for (String name : CustomItemsAPI.listCustomItemIDs()) {
try {
Identifier key = new Identifier("cui", name);
if (getItemStack(key) != null)
names.add(key);
} catch (MissingResourceException ignored) { }
}
return names.toArray(new Identifier[0]);
}
@Override
public boolean isValidProvider(Identifier key, boolean isItem) {
return key.namespace().equalsIgnoreCase("cui");
}
private BlockData getMushroomData(CustomItem item) {
MultipleFacing data = (MultipleFacing)mushroomMaterial.invoke(item.getBlockTexture().getMushroomId()).parseMaterial().createBlockData();
boolean[] values = mushroomFaces.get().get(item.getBlockTexture().getMushroomId());
data.setFace(BlockFace.DOWN, values[0]);
data.setFace(BlockFace.EAST, values[1]);
data.setFace(BlockFace.NORTH, values[2]);
data.setFace(BlockFace.SOUTH, values[3]);
data.setFace(BlockFace.UP, values[4]);
data.setFace(BlockFace.WEST, values[5]);
return data;
}
}

View File

@ -26,13 +26,13 @@ public abstract class ExternalDataProvider {
public abstract void init();
public abstract BlockData getBlockData(NamespacedKey blockId) throws MissingResourceException;
public abstract BlockData getBlockData(Identifier blockId) throws MissingResourceException;
public abstract ItemStack getItemStack(NamespacedKey itemId) throws MissingResourceException;
public abstract ItemStack getItemStack(Identifier itemId) throws MissingResourceException;
public abstract NamespacedKey[] getBlockTypes();
public abstract Identifier[] getBlockTypes();
public abstract NamespacedKey[] getItemTypes();
public abstract Identifier[] getItemTypes();
public abstract boolean isValidProvider(NamespacedKey namespace, boolean isItem);
public abstract boolean isValidProvider(Identifier id, boolean isItem);
}

View File

@ -0,0 +1,33 @@
package com.volmit.iris.core.link;
import org.bukkit.NamespacedKey;
public record Identifier(String namespace, String key) {
private static final String DEFAULT_NAMESPACE = "minecraft";
public static Identifier fromString(String id) {
String[] strings = id.split(":", 1);
if(strings.length == 1) {
return new Identifier(DEFAULT_NAMESPACE, strings[0]);
} else {
return new Identifier(strings[0], strings[1]);
}
}
@Override
public String toString() {
return namespace + ":" + key;
}
@Override
public boolean equals(Object obj) {
if(obj instanceof Identifier i) {
return i.namespace().equals(this.namespace) && i.key().equals(this.key);
} else if(obj instanceof NamespacedKey i) {
return i.getNamespace().equals(this.namespace) && i.getKey().equals(this.key);
} else {
return false;
}
}
}

View File

@ -3,7 +3,6 @@ package com.volmit.iris.core.link;
import com.volmit.iris.util.collection.KList;
import dev.lone.itemsadder.api.CustomBlock;
import dev.lone.itemsadder.api.CustomStack;
import org.bukkit.NamespacedKey;
import org.bukkit.block.data.BlockData;
import org.bukkit.inventory.ItemStack;
@ -11,52 +10,59 @@ import java.util.MissingResourceException;
public class ItemAdderDataProvider extends ExternalDataProvider {
private KList<String> itemNamespaces, blockNamespaces;
public ItemAdderDataProvider() {
super("ItemsAdder");
}
@Override
public void init() { }
public void init() {
this.itemNamespaces = new KList<>();
this.blockNamespaces = new KList<>();
for(Identifier i : getItemTypes()) {
itemNamespaces.addIfMissing(i.namespace());
}
for(Identifier i : getBlockTypes()) {
blockNamespaces.addIfMissing(i.namespace());
}
}
@Override
public BlockData getBlockData(NamespacedKey blockId) throws MissingResourceException {
public BlockData getBlockData(Identifier blockId) throws MissingResourceException {
return CustomBlock.getBaseBlockData(blockId.toString());
}
@Override
public ItemStack getItemStack(NamespacedKey itemId) throws MissingResourceException {
public ItemStack getItemStack(Identifier itemId) throws MissingResourceException {
CustomStack stack = CustomStack.getInstance(itemId.toString());
if (stack == null) {
throw new MissingResourceException("Failed to find ItemData!", itemId.getNamespace(), itemId.getKey());
throw new MissingResourceException("Failed to find ItemData!", itemId.namespace(), itemId.key());
}
return stack.getItemStack();
}
@Override
public NamespacedKey[] getBlockTypes() {
KList<NamespacedKey> keys = new KList<>();
public Identifier[] getBlockTypes() {
KList<Identifier> keys = new KList<>();
for (String s : CustomBlock.getNamespacedIdsInRegistry()) {
keys.add(NamespacedKey.fromString(s));
keys.add(Identifier.fromString(s));
}
return keys.toArray(new NamespacedKey[0]);
return keys.toArray(new Identifier[0]);
}
@Override
public NamespacedKey[] getItemTypes() {
KList<NamespacedKey> keys = new KList<>();
public Identifier[] getItemTypes() {
KList<Identifier> keys = new KList<>();
for (String s : CustomStack.getNamespacedIdsInRegistry()) {
keys.add(NamespacedKey.fromString(s));
keys.add(Identifier.fromString(s));
}
return keys.toArray(new NamespacedKey[0]);
return keys.toArray(new Identifier[0]);
}
@Override
public boolean isValidProvider(NamespacedKey blockId, boolean isItem) {
for (NamespacedKey k : (isItem ? getItemTypes() : getBlockTypes())) {
if (k.equals(blockId)) {
return true;
}
}
return false;
public boolean isValidProvider(Identifier id, boolean isItem) {
return isItem ? this.itemNamespaces.contains(id.namespace()) : this.blockNamespaces.contains(id.namespace());
}
}

View File

@ -1,44 +0,0 @@
package com.volmit.iris.core.link;
import org.bukkit.NamespacedKey;
import org.bukkit.block.data.BlockData;
import org.bukkit.inventory.ItemStack;
import java.util.MissingResourceException;
public class MMOItemsDataProvider extends ExternalDataProvider {
public MMOItemsDataProvider(String pluginId) {
super(pluginId);
}
@Override
public void init() {
}
@Override
public BlockData getBlockData(NamespacedKey blockId) throws MissingResourceException {
return null;
}
@Override
public ItemStack getItemStack(NamespacedKey itemId) throws MissingResourceException {
return null;
}
@Override
public NamespacedKey[] getBlockTypes() {
return new NamespacedKey[0];
}
@Override
public NamespacedKey[] getItemTypes() {
return new NamespacedKey[0];
}
@Override
public boolean isValidProvider(NamespacedKey namespace, boolean isItem) {
return false;
}
}

View File

@ -20,6 +20,7 @@ package com.volmit.iris.core.link;
import com.volmit.iris.Iris;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.reflect.WrappedField;
import io.th0rgal.oraxen.api.OraxenItems;
import io.th0rgal.oraxen.items.ItemBuilder;
import io.th0rgal.oraxen.mechanics.MechanicFactory;
@ -30,7 +31,6 @@ import io.th0rgal.oraxen.mechanics.provided.gameplay.noteblock.NoteBlockMechanic
import io.th0rgal.oraxen.mechanics.provided.gameplay.stringblock.StringBlockMechanicFactory;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.MultipleFacing;
import org.bukkit.inventory.ItemStack;
@ -44,7 +44,7 @@ public class OraxenDataProvider extends ExternalDataProvider {
private static final String FIELD_FACTORIES_MAP = "FACTORIES_BY_MECHANIC_ID";
private Map<String, MechanicFactory> factories;
private WrappedField<MechanicsManager, Map<String, MechanicFactory>> factories;
public OraxenDataProvider() {
super("Oraxen");
@ -52,63 +52,59 @@ public class OraxenDataProvider extends ExternalDataProvider {
@Override
public void init() {
try {
Field f = MechanicsManager.class.getDeclaredField(FIELD_FACTORIES_MAP);
f.setAccessible(true);
factories = (Map<String, MechanicFactory>) f.get(null);
} catch (NoSuchFieldException | IllegalAccessException e) {
Iris.error("Failed to set up Oraxen Link:");
Iris.error("\t" + e.getClass().getSimpleName());
this.factories = new WrappedField<>(MechanicsManager.class, FIELD_FACTORIES_MAP);
if(this.factories.hasFailed()) {
Iris.error("Failed to set up Oraxen Link: Unable to fetch MechanicFactoriesMap!");
}
}
@Override
public BlockData getBlockData(NamespacedKey blockId) throws MissingResourceException {
public BlockData getBlockData(Identifier blockId) throws MissingResourceException {
MechanicFactory factory = getFactory(blockId);
if (factory instanceof NoteBlockMechanicFactory f)
return f.createNoteBlockData(blockId.getKey());
return f.createNoteBlockData(blockId.key());
else if (factory instanceof BlockMechanicFactory f) {
MultipleFacing newBlockData = (MultipleFacing) Bukkit.createBlockData(Material.MUSHROOM_STEM);
BlockMechanic.setBlockFacing(newBlockData, ((BlockMechanic) f.getMechanic(blockId.getKey())).getCustomVariation());
BlockMechanic.setBlockFacing(newBlockData, ((BlockMechanic) f.getMechanic(blockId.key())).getCustomVariation());
return newBlockData;
} else if (factory instanceof StringBlockMechanicFactory f) {
return f.createTripwireData(blockId.getKey());
return f.createTripwireData(blockId.key());
} else
throw new MissingResourceException("Failed to find BlockData!", blockId.getNamespace(), blockId.getKey());
throw new MissingResourceException("Failed to find BlockData!", blockId.namespace(), blockId.key());
}
@Override
public ItemStack getItemStack(NamespacedKey itemId) throws MissingResourceException {
Optional<ItemBuilder> opt = OraxenItems.getOptionalItemById(itemId.getKey());
return opt.orElseThrow(() -> new MissingResourceException("Failed to find ItemData!", itemId.getNamespace(), itemId.getKey())).build();
public ItemStack getItemStack(Identifier itemId) throws MissingResourceException {
Optional<ItemBuilder> opt = OraxenItems.getOptionalItemById(itemId.key());
return opt.orElseThrow(() -> new MissingResourceException("Failed to find ItemData!", itemId.namespace(), itemId.key())).build();
}
@Override
public NamespacedKey[] getBlockTypes() {
KList<NamespacedKey> names = new KList<>();
public Identifier[] getBlockTypes() {
KList<Identifier> names = new KList<>();
for (String name : OraxenItems.getItemNames()) {
try {
NamespacedKey key = new NamespacedKey("oraxen", name);
Identifier key = new Identifier("oraxen", name);
if (getBlockData(key) != null)
names.add(key);
} catch (MissingResourceException ignored) { }
}
return names.toArray(new NamespacedKey[0]);
return names.toArray(new Identifier[0]);
}
@Override
public NamespacedKey[] getItemTypes() {
KList<NamespacedKey> names = new KList<>();
public Identifier[] getItemTypes() {
KList<Identifier> names = new KList<>();
for (String name : OraxenItems.getItemNames()) {
try {
NamespacedKey key = new NamespacedKey("oraxen", name);
Identifier key = new Identifier("oraxen", name);
if (getItemStack(key) != null)
names.add(key);
} catch (MissingResourceException ignored) { }
}
return names.toArray(new NamespacedKey[0]);
return names.toArray(new Identifier[0]);
}
@Override
@ -117,14 +113,14 @@ public class OraxenDataProvider extends ExternalDataProvider {
}
@Override
public boolean isValidProvider(NamespacedKey key, boolean isItem) {
return key.getNamespace().equalsIgnoreCase("oraxen");
public boolean isValidProvider(Identifier key, boolean isItem) {
return key.namespace().equalsIgnoreCase("oraxen");
}
private MechanicFactory getFactory(NamespacedKey key) throws MissingResourceException {
return factories.values().stream()
.filter(i -> i.getItems().contains(key.getKey()))
private MechanicFactory getFactory(Identifier key) throws MissingResourceException {
return factories.get().values().stream()
.filter(i -> i.getItems().contains(key.key()))
.findFirst()
.orElseThrow(() -> new MissingResourceException("Failed to find BlockData!", key.getNamespace(), key.getKey()));
.orElseThrow(() -> new MissingResourceException("Failed to find BlockData!", key.namespace(), key.key()));
}
}

View File

@ -19,9 +19,7 @@
package com.volmit.iris.core.service;
import com.volmit.iris.Iris;
import com.volmit.iris.core.link.ExternalDataProvider;
import com.volmit.iris.core.link.ItemAdderDataProvider;
import com.volmit.iris.core.link.OraxenDataProvider;
import com.volmit.iris.core.link.*;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.plugin.IrisService;
import lombok.Data;
@ -39,7 +37,10 @@ public class ExternalDataSVC implements IrisService {
@Override
public void onEnable() {
addProvider(new OraxenDataProvider(), new ItemAdderDataProvider());
addProvider(
new OraxenDataProvider(),
new ItemAdderDataProvider(),
new CustomItemsDataProvider());
}
@Override
@ -55,7 +56,7 @@ public class ExternalDataSVC implements IrisService {
}
}
public Optional<BlockData> getBlockData(NamespacedKey key) {
public Optional<BlockData> getBlockData(Identifier key) {
Optional<ExternalDataProvider> provider = providers.stream().filter(p -> p.isPresent() && p.isValidProvider(key, false)).findFirst();
if (provider.isEmpty())
return Optional.empty();
@ -67,7 +68,7 @@ public class ExternalDataSVC implements IrisService {
}
}
public Optional<ItemStack> getItemStack(NamespacedKey key) {
public Optional<ItemStack> getItemStack(Identifier key) {
Optional<ExternalDataProvider> provider = providers.stream().filter(p -> p.isPresent() && p.isValidProvider(key, true)).findFirst();
if (provider.isEmpty()) {
Iris.warn("No matching Provider found for modded material \"%s\"!", key);
@ -81,15 +82,15 @@ public class ExternalDataSVC implements IrisService {
}
}
public NamespacedKey[] getAllBlockIdentifiers() {
KList<NamespacedKey> names = new KList<>();
public Identifier[] getAllBlockIdentifiers() {
KList<Identifier> names = new KList<>();
providers.stream().filter(ExternalDataProvider::isPresent).forEach(p -> names.add(p.getBlockTypes()));
return names.toArray(new NamespacedKey[0]);
return names.toArray(new Identifier[0]);
}
public NamespacedKey[] getAllItemIdentifiers() {
KList<NamespacedKey> names = new KList<>();
public Identifier[] getAllItemIdentifiers() {
KList<Identifier> names = new KList<>();
providers.stream().filter(ExternalDataProvider::isPresent).forEach(p -> names.add(p.getItemTypes()));
return names.toArray(new NamespacedKey[0]);
return names.toArray(new Identifier[0]);
}
}

View File

@ -20,6 +20,7 @@ package com.volmit.iris.util.data;
import com.volmit.iris.Iris;
import com.volmit.iris.core.IrisSettings;
import com.volmit.iris.core.link.Identifier;
import com.volmit.iris.core.service.ExternalDataSVC;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.collection.KMap;
@ -27,7 +28,6 @@ import com.volmit.iris.util.scheduling.ChronoLatch;
import it.unimi.dsi.fastutil.ints.*;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.Waterlogged;
import org.bukkit.block.data.type.Leaves;
@ -471,7 +471,7 @@ public class B {
BlockData bx = null;
if (!ix.startsWith("minecraft:") && ix.contains(":")) {
NamespacedKey key = NamespacedKey.fromString(ix);
Identifier key = Identifier.fromString(ix);
Optional<BlockData> bd = Iris.service(ExternalDataSVC.class).getBlockData(key);
if (bd.isPresent())
bx = bd.get();
@ -647,7 +647,7 @@ public class B {
}
}
for (NamespacedKey id : Iris.service(ExternalDataSVC.class).getAllBlockIdentifiers())
for (Identifier id : Iris.service(ExternalDataSVC.class).getAllBlockIdentifiers())
bt.add(id.toString());
bt.addAll(custom.k());
@ -662,7 +662,7 @@ public class B {
bt.add(v);
}
for (NamespacedKey id : Iris.service(ExternalDataSVC.class).getAllItemIdentifiers())
for (Identifier id : Iris.service(ExternalDataSVC.class).getAllItemIdentifiers())
bt.add(id.toString());
return bt.toArray(new String[0]);

View File

@ -0,0 +1,42 @@
package com.volmit.iris.util.reflect;
import com.volmit.iris.Iris;
import java.lang.reflect.Field;
public class WrappedField<C, T> {
private final Field field;
public WrappedField(Class<C> origin, String methodName) {
Field f = null;
try {
f = origin.getDeclaredField(methodName);
f.setAccessible(true);
} catch(NoSuchFieldException e) {
Iris.error("Failed to created WrappedField %s#%s: %s%s", origin.getSimpleName(), methodName, e.getClass().getSimpleName(), e.getMessage().equals("") ? "" : " | " + e.getMessage());
}
this.field = f;
}
public T get() {
return get(null);
}
public T get(C instance) {
if(field == null) {
return null;
}
try {
return (T)field.get(instance);
} catch(IllegalAccessException e) {
Iris.error("Failed to get WrappedField %s#%s: %s%s", field.getDeclaringClass().getSimpleName(), field.getName(), e.getClass().getSimpleName(), e.getMessage().equals("") ? "" : " | " + e.getMessage());
return null;
}
}
public boolean hasFailed() {
return field == null;
}
}

View File

@ -0,0 +1,39 @@
package com.volmit.iris.util.reflect;
import com.volmit.iris.Iris;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public final class WrappedReturningMethod<C, R> {
private final Method method;
public WrappedReturningMethod(Class<C> origin, String methodName, Class<?>... paramTypes) {
Method m = null;
try {
m = origin.getDeclaredMethod(methodName, paramTypes);
m.setAccessible(true);
} catch(NoSuchMethodException e) {
Iris.error("Failed to created WrappedMethod %s#%s: %s%s", origin.getSimpleName(), methodName, e.getClass().getSimpleName(), e.getMessage().equals("") ? "" : " | " + e.getMessage());
}
this.method = m;
}
public R invoke(Object... args) {
return invoke(null, args);
}
public R invoke(C instance, Object... args) {
if(method == null) {
return null;
}
try {
return (R)method.invoke(instance, args);
} catch(InvocationTargetException | IllegalAccessException e) {
Iris.error("Failed to invoke WrappedMethod %s#%s: %s%s", method.getDeclaringClass().getSimpleName(), method.getName(), e.getClass().getSimpleName(), e.getMessage().equals("") ? "" : " | " + e.getMessage());
return null;
}
}
}