I am working on a statue plugin for Spigot 1.20.4 (Java) that creates NPC statues. Currently, when you create a statue, you can use a consumer to define what happens when said NPC is right clicked.
Statue.StatueBuilder builder = new Statue.StatueBuilder(entityType)
.setName("Test")
.setOnClick(connectionPlayer -> System.out.println("TEST " + new Random().nextInt()));
Statue statue = builder.build();
The #setOnClick takes in a StatueAction, which is defined as:
public interface StatueAction {
void perform(ConnectionPlayer player);
}
I need to save this data (either yml, json, etc) so when the server restarts, the statues will be spawned again. However, I cant serialize the consumer. Tried with YML and JSON. I understand why, but not how to get around it.
Any ideas on how to save the onClick action to a file? Or if this is not a good approach, any ideas for other approaches I might take to achieve a similar goal? I did look into How to serialize a lambda?, however it seems none of those are working correctly (for me), meaning I must be doing something incorrect.
Here is how i am currently trying to serialize it
StatueAction<ConnectionPlayer> r = (connectionPlayer) -> System.out.println("Hello");
Statue.StatueBuilder builder = new Statue.StatueBuilder(entityType).setName("Test").setOnClick(r);
Statue statue = builder.build();
statue.spawn(player.getLocation());
statue.createDefaultAttribs();
System.out.println(statue.serialize());
And the output is
{"name":"Test","entityType":"ARMOR_STAND","entityUUID":"6c2a484c-3168-4fb8-a3ee-8c2d93bddf1d","textDisplaysID":[],"onClick":{}}
The Statue serialization method is defined as
public static class StatueSerializer implements JsonSerializer<Statue> {
@Override
public JsonElement serialize(Statue statue, Type type, JsonSerializationContext jsonSerializationContext) {
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("name", statue.name);
jsonObject.addProperty("entityType", statue.entityType.name());
jsonObject.addProperty("entityUUID", statue.getEntityUUID().toString());
jsonObject.add("textDisplaysID", jsonSerializationContext.serialize(statue.getTextDisplaysID()));
// Serialize the CustomAction using its own serialization logic
jsonObject.add("onClick", jsonSerializationContext.serialize(statue.getOnClick()));
return jsonObject;
}
}
public String serialize() {
Gson gson = new GsonBuilder()
.registerTypeAdapter(Statue.class, new Statue.StatueSerializer())
.create();
return gson.toJson(this);
}