ItemStack to Gson works except for books and other items & Custom Key String Value

Turning an ItemStack into a json format to save into a sql table. The item stack is from the players hand.

Using the below code:

String to(ItemStack I){
	StringWriter sink = new StringWriter();
	GsonConfigurationLoader gLoad = GsonConfigurationLoader.builder().setSink(() -> new BufferedWriter(sink)).build();
	ConfigurationNode node = gLoad.createEmptyNode();
	try {
		node.getNode("item").setValue(TypeToken.of(ItemStack.class), I);
		gLoad.save(node);
	} catch (ObjectMappingException | IOException e) {
		e.printStackTrace();
		return null;
	}
	return(sink.toString());
}

This works fine with regular items like wool, dirt, quite a few modded items. But soon as I use a enchanted book it trows a exception. Just tested it with an enchanted bow and got same exception.

java.lang.IllegalArgumentException: Configuration does not accept objects of type class java.lang.Short
at ninja.leaping.configurate.ScalarConfigValue.setValue(ScalarConfigValue.java:42)

I have tried the same. I did it differently. However there are problems at the deserialization: Deserialization of config node fails at data manipulators

Try use DataView: Serializing Data — Sponge 7.2.0 documentation

But there is another problem, all enchantment will convert to protect I. I will post this issue later.

Edit:
Code is show at Enchantments couldn't retreat due ItemStack serialization
afaik, this can handle all except enchant item and shulker box.

Ah I see, well kinda, I did manage to get it working with DataView. Works as I expected and can save and reload back to database.

I’ve got quite a few problems to overcome, Used to code a lot of bukkit plugins so this switch for me has been interesting. Still typing Bukkit.get and then scrambling to delete it! Also I have only really learned java 6 and just started with 7, so all this optional stuff is well meh to me. Slowly starting to get it.

I do seem to have another problem I am not fully understanding how to add a custom key to an itemstack, I want the key value to some string value, and to read it back later. It must be hidden from players so using lore, display name, etc won’t do.

Just can’t think of a simple way to do this so far I have…

public Key<Value> SomeKey = KeyFactory.makeSingleKey(TypeToken.of(String.class), new TypeToken<Value>() {} , DataQuery.of(‘.’, “Don’t know”), “Item 1?”, “Item 2?”);
ItemStack Stack = ItemStack.builder().itemType(ItemTypes.SPONGE).build();
Stack.offer(SomeKey.getValueToken().getType(),“I dont know what I am doing”);

It can’t be that hard to just add a key of type string onto an itemstack, also don’t need to save it the database, if server reboots I don’t care what happens to this item or its key value.

It isn’t simple(in my eyes). There is a PR about this: Custom Data Generation by gabizou · Pull Request #1198 · SpongePowered/SpongeAPI · GitHub

Having to write 3 classes just to store a String onto an Entity or ItemStack is a bit excessive.

This helped me a lot: DataManipulatorGenerator

Three!? That seems excessive if all I want to do is save a simple string value, man if I’m going this far as saving a string, I might as well make it save an int as well hope that doesn’t require another three classes.

Well I just got home so gonna give this a poke, had a bad enough time with the whole stack to database issue. I used just use base64 and turn a stack into an obj then to string and back again. Well least I’m having fun learning all this new stuff.

[Edit]
Well I seem to be using 4… what in the world am I doing wrong lol.

StringKeys
StingData
Immutable
Builder

I also have

@Listener
public void onInitialization(GameInitializationEvent event) {
Sponge.getDataManager().register(StringData.class, Immutable.class, new Builder());
}

In my main class, So its registred, got 3, well 4 files and am using

  		ItemStack Stack = ItemStack.builder().itemType(ItemTypes.ANVIL).build();
  		Stack.offer(Keys.DISPLAY_NAME, Text.of("Testing Anvil"));
  		Stack.offer(StringKeys.STRING_STORAGE, "I am a String Key!");
  		player.sendMessage(Text.of(Stack.get(StringKeys.STRING_STORAGE).get()));

And get a good ole

java.util.NoSuchElementException: No value present

But I just set one? Didn’t I? Pokes code with a stick

This is a very recent change to the registration of CustomData. I haven’t tried it myself yet. But you should use the new builder method to register data(when developing for Sponge 5.2.0-SNAPSHOT or 6.0.0-SNAPSHOT). But that’s not the problem.

You have to offer the DataManipulator itself the first time. Like stack.offer(new StringData("I am a String key!"));. When saving custom data I never use the keys because of that. I only use it to get it. Maybe that gets changed in the future.

Sorry for late reply, Well got it all working thou I still have one related issue that persists and can;t seem to get rid of it.Using this…along with the needed three classes idk why I had 4 before.

Stack.offer(((DataHolder) Stack).getOrCreate(sKeyData.class).get().set(sKeys.StringKey, “Button”));

Got menu inventory and there is a item that when clicked that closes the inventory but you end up with the close button in your inventory, this also happens with a pre / next page button, they end up in the new inventory instead of the players. Anyway to null a cursor transaction?