Convert String to ItemStack java bukkit
Question
I am working on a bukkit plugin and am trying to save a whole inventory in a file. So I saved the file in a String using: InventoriesData.set(player.getName(), ItemStack + "");
but now it is saved as a String, I don't know how to convert it back to an ItemStack. I know I can save all the data seperate aswell but I want to save all the information and think it should be possible to convert back. So does anybody have a clue on how to do that?
it will return this btw: ItemStack{BLAZE_ROD x 1, UNSPECIFIC_META:{meta-type=UNSPECIFIC, display-name=Inventory Selector, Current:2, enchants={THORNS=3}}}
Solution
To make an itemstack, you need to have the material and the amount:
String s = /* your material string */;
Material m = Material.matchMaterial(s);
ItemStack stack = new ItemStack(m, 1);
However, note that ItemStack
is ConfigurationSerializable
, meaning you can simply save it directly to a config:
ItemStack is = /*...*/;
getConfig().set("example", is);
is = (ItemStack) getConfig().get("example");
Inventories are contextual, hence them being unserializable. If you wanted to, you could make a helper class to track the armor, and non-air (null
) stacks as a class, and then make that class itself ConfigurationSerializable
:
@SerializableAs("Inventory")
public class SInventory implements ConfigurationSerializable {
private final List<ItemStack> items = new ArrayList<>();
private ItemStack head;
private ItemStack chest;
private ItemStack legs;
private ItemStack boots;
/* Other fields */
public SInventory(Map<String, Object> config) {
List<ItemStack> items = (List<ItemStack>) config.get("inventory");
for (ItemStack item : items) {
if (item != null) {
this.items.add(item);
}
}
this.head = (ItemStack) config.get("head");
this.chest = (ItemStack) config.get("chest");
this.legs = (ItemStack) config.get("legs");
this.boots = (ItemStack) config.get("boots");
}
public static SInventory valueOf(Map<String, Object> config) {
return new SInventory(config);
}
public static SInventory deserialize(Map<String, Object> config) {
return new SInventory(config);
}
@Override
public Map<String, Object> serialize() {
Map<String, Object> back = new HashMap<>();
back.put("inventory", this.items);
back.put("head", this.head);
back.put("chest", this.chest);
back.put("legs", this.legs);
back.put("boots", this.boots);
return back;
}
The Map<String, Object>
is the section that represents this inventory. So if you save a List<ItemStack>
under the string "Inventory" when you pass it via serialize
, then you can retrieve it from the map like so:
List<ItemStack> inv = (List<ItemStack>) map.get("Inventory");
This usually leads to a much simpler and easier-managed system.