Info for Developers
Source Code on Github
(If you're an experienced developer, this will likely seem a little mundane to you. If that's you, check out the JavaDocs attached to each method in the com.jojodmo.itembridge.ItemBridge class, and then take a look at the examples here)
First Steps
Download ItemBridge and add it to your plugin. If your plugin needs ItemBridge to work, make sure to modify the plugin.yml to have "ItemBridge" as a dependency. Otherwise, make sure that your plugin.yml has "ItemBridge" listed under "soft-depend".
One way to import ItemBridge to your project is to download the .jar file and add it as a dependency manually.
If you want, you can also use ItemBridge as a Maven dependency using Jitpack! Check out https://jitpack.io/#jojodmo/ItemBridge for more info
Checking if the server has ItemBridge
// An example for checking this in your Main class
public static boolean hasItemBridge;
public void onEnable(){
hasItemBridge = Bukkit.getPluginManager().getPlugin("ItemBridge") != null;
}
Getting an ItemStack using ItemBridge
Retrieving an ItemStack from a key is simple! Just use the static ItemBridge.getItemStack() methods.
Plugin plugin;
ItemBridgeKey itemBridgeKey = new ItemBridgeKey("minecraft", "DIAMOND_PICKAXE");
ItemStack item;
item = getItemStack(plugin, "itemNameFromPlugin");
item = getItemStack(itemBridgeKey);
item = getItemStack("itemKey", "itemName");
item = getItemStack("itemKey:itemName");
Letting ItemBridge recognize your plugin's items
Adding your items to ItemBridge is also easy!
First, make a class that implements the ItemBridgeListener interface. In here, there's four methods that you should implement:
@Override
public ItemBridgeListenerPriority getPriority(){
// ItemBridgeListenerPriority.MEDIUM by default.
// the higher the priority, the sooner your plugin will be checked for the
// getItemName and isItem methods.
}
@Override
public ItemStack fetchItemStack(String itemName){
// return the item from your plugin
// that has the name itemName
}
@Override
public String getItemName(ItemStack stack){
// if the ItemStack wasn't created by your plugin, you MUST return null.
// otherwise, return the name of the item
}
@Override
public boolean isItem(ItemStack stack, String name){
// return true if the item was created by your plugin, and it's name is name
//
// In general, this should be like running name.equalsIgnoreCase(getItemName(stack));
// however, there's likely a much faster implementation than that, and you may
// have some other special logic you'd like to do
}
However, if your plugin isn't adding new items to the game, there's only one method that you need to implement:
@Override
public ItemStack fetchItemStack(String itemName){
// return the item from your plugin
// that has the name itemName
}
Next, make a new ItemBridge reference with a list of keys that you want to be able to be used (typically, this will just be your plugin name along with an abbreviation or two). Then, use the ItemBridge.registerListener method to register your newly created ItemBridgeListener.
For example, here's the class that handles native Minecraft items for ItemBridge (keep in mind that "minecraft" and "mc" are both reserved ItemBridge keys, so you'll have to change them to something else if you want to use this code):
public class MinecraftItemBridge implements ItemBridgeListener{
private static ItemBridge bridge;
public static void setup(Plugin plugin){
bridge = new ItemBridge(plugin, "minecraft", "mc");
bridge.registerListener(new MinecraftItemBridge());
}
@Override
public ItemBridgeListenerPriority getPriority(){
return ItemBridgeListenerPriority.LOWEST;
}
@Override
public ItemStack fetchItemStack(String item){
Material m = Material.matchMaterial(item);
return m == null ? null : new ItemStack(m);
}
@Override
public String getItemName(ItemStack stack){
return stack == null ? null : stack.getType().name();
}
@Override
public boolean isItem(ItemStack stack, String name){
return stack.getType().name().equalsIgnoreCase(name);
}
}
Then, in the onEnable code of the Main class,
public static boolean hasItemBridge;
public void onEnable(){
hasItemBridge = Bukkit.getPluginManager().getPlugin("ItemBridge") != null;
if(hasItemBridge){
MinecraftItemBridge.setup();
}
else{
System.out.println("This server doesn't have ItemBridge!");
}
}
A walkthrough of how the internals work
Let's say we have two plugins: CustomItems and ItemDropper. CustomItems wants to make it so that other plugins can get and use its items, and ItemParty wants to let players drop items from other plugins.
This is what the code in CustomItems might look like
(Remember to call ItemBridgeCUI.setup(this) in your onEnable function)
public class ItemBridgeCUI implements ItemBridgeListener{
private static ItemBridge bridge;
static void setup(Plugin plugin){
// allow items to be looked up if they're prefixed with
// the keys "customitems:", "customitem:" or "cui:"
//
// for example, "customitems:apple" and "cui:MY_COOL_ITEM"
// will both get routed to this ItemBridge's listener (set up below)
// but "anotherPlugin:MY_COOL_ITEM" and "minecraft:apple" will not
bridge = new ItemBridge(plugin, "customitems", "customitem", "cui");
// register this class (ItemBridgeCUI) as a listener
bridge.registerListener(new ItemBridgeCUI());
}
@Override
public ItemStack fetchItemStack(String item){
// here's the code for fetching the ItemStack for
// the CustomItem with the given item name.
//
// ItemBridge routes requests with matching keys.
// so, in this example, if ItemBridge was requested
// to get the item "customitems:apple", then
// item would be "apple". If ItemBridge was requested
// to get the item "cui:MY_CUSTOM_ITEM",
// then item would be "MY_CUSTOM_ITEM".
// if ItemBridge was requested to get the item "minecraft:MY_CUSTOM_ITEM",
// this method wouldn't be called
// You should return "null" if the item doesn't exist
ItemStack stack = CustomItemHandler.getCustomItemByID(item);
return stack;
}
@Override
public String getItemName(ItemStack stack){
return CustomItemHandler.getCustomItemID(stack);
}
@Override
public boolean isItem(ItemStack stack, String item){
item.equalsIgnoreCase(getItemName(stack));
}
}
And this is what the code in ItemParty might look like
(Remember to check that the server has the ItemBridge plugin)
// give a player a bunch of items
public static void givePlayerItems(Player player){
// if CustomItems has the item "MY_COOL_ITEM", then the player will get one!
giveItem(player, ItemBridge.getItemStack("customitems:MY_COOL_ITEM"));
// if CustomItems has the item "PARTY_HAT", then the player will get one!
giveItem(player, ItemBridge.getItemStack("cui", "PARTY_HAT"));
Plugin customItemsPlugin =
Bukkit.getPluginManager().getPlugin("CustomItems");
// if CustomItems has the item "myItem", then the player will get one!
giveItem(player, ItemBridge.getItemStack(customItemsPlugin, "myItem"));
// if CustomItems has the item "anotherItem", then the player will get one!
giveItem(player, ItemBridge.getItemStack(new NamespacedKey(customItemsPlugin, "anotherItem")));
// give the player a minecraft diamond block
giveItem(player, ItemBridge.getItemStack("minecraft:DIAMOND_BLOCK"));
// give the player a minecraft gold ingot. If something doesn't have a prefix: then ItemBridge assumes that it is a Minecraft item
giveItem(player, ItemBridge.getItemStack("GOLD_INGOT"));
}
// convenience method for giving an ItemStack to the given player
public static void giveItem(Player player, ItemStack item){
if(stack == null){return;} // avoid giving players null items
player.getInventory().addItem(item);
}
Advanced Features
Both ItemBridgeListener and methods in ItemBridge have methods to accept arguments, which is a Map<String, Object>. This can be used to make it so that other plugins can pass arguments to your plugin when fetching a custom item (for example, if your plugin should be able to take in a player name and pass back the appropriate item).
public class MyClass implements ItemBridgeListener{
ItemStack fetchItemStack(@NotNull String item, @NotNull Map<String, Object> parameters){
String playerName = Objects.toString(parameters.get("playerName"));
ItemStack stack = new ItemStack(Material.GOLD_INGOT);
ItemMeta meta = stack.getItemMeta();
meta.setDisplayName(playerName + "'s " + item);
stack.setItemMeta(meta);
return stack;
}
// you must also implement this function
public ItemStack fetchItemStack(@NotNull String item){
return fetchItemStack(item, new HashMap<>());
}
}
public class AnotherClass{
public static void setup(Plugin plugin){
ItemBridge itemBridge = new ItemBridge(plugin, "myPlugin");
itemBridge.registerListener(new MyClass());
}
public static ItemStack giveExampleItem(Player player){
Map<String, Object> parameters = new HashMap<>();
parameters.put("playerName", player.getName());
ItemStack stack = ItemBridge.getItemStack("myPlugin:TEST_ITEM", parameters);
player.getInventory.addItem(stack);
}
}
Just make sure you document that you're using it and if your plugin supports/requires using arguments!