ItemStack from String with custom data manipulators

So I’m storing ItemStacks in a database. I’m using these methods for serialization.

public static String serialize(ItemStack itemStack) {
	try {
		StringWriter sink = new StringWriter();
		GsonConfigurationLoader loader = GsonConfigurationLoader.builder().setSink(() -> new BufferedWriter(sink)).build();
		ConfigurationNode node = loader.createEmptyNode();
		node.setValue(TypeToken.of(ItemStack.class), itemStack);
		loader.save(node);
		return sink.toString();
	} catch (Exception e) {
		e.printStackTrace();
		return null;
	}
}

public static ItemStack deserialize(String item) {
	try {
		StringReader source = new StringReader(item);
		GsonConfigurationLoader loader = GsonConfigurationLoader.builder().setSource(() -> new BufferedReader(source)).build();
		ConfigurationNode node = loader.load();
		return node.getValue(TypeToken.of(ItemStack.class));
	} catch (Exception e) {
		e.printStackTrace();
		return null;
	}
}

Seems to work fine on the surface, however if custom data manipulators are stored on an ItemStack, that data does not get deserialized with the ItemStack. I see it stored in the database so it’s serializing fine.

This presents a problem for me. If another plugin adds data to ItemStack’s my plugin will break them and I would like to ensure complete compatibility.

Is there a better way to accomplish this task without losing custom data?

1 Like

Do you have a DataManipulatorBuilder registered for your DataManipulator?

Don’t think you understand. The data is from other plugins. It’s not a specific data manipulator its all custom data from any plugin.

Does the data implement toContainer? If it doesn’t, it doesn’t get serialized. If it does, then it does.

As stated it’s visible in the database so yes. It’s not the data that’s the problem.

To further explain, this is how I’m serializing player inventories in Project Inventories to a database. If there was any problems with whatever data manipulators it would present itself regardless when player re-logged. It only occurs when using the above methods. The ItemStack serializes fine. The container in the database shows the stack and it’s data, it just won’t deserialize. I don’t get any errors just a ItemStack stripped of custom data.

This is still an issue…

Are you certain that it’s not an issue with the other plugins not deserializing their own data properly? I would take a look at the source of the plugins in question, or try manually adding their data to an itemstack to test serializing/deserializing it. Serializing to a configuration node as you do still ends up going through toContainer, so the issue is probably in how the other plugin handles deserialization.

As I said before, it only occurs with my plugin installed. If it was a problem with other plugins Data then the problem would occur when the item stack was deserialized from playerdata file, would it not? It still goes through the same deserialzation process during player login, right?

Let me do some testing and I’ll get back to you but I’m certain the result is going to be same.

Just did some testing and here’s an example. I’ve been working on a backpack plugin. This plugin has no data issues. After installing Project Inventories which is using the methods in main thread, if player logs off and logs back in, or switches between inventories data is lost.

https://github.com/trentech/BetterBackpacks/tree/master/src/main/java/com/gmail/trentech/betterbackpacks