Saltar al contenido principal

Objectos custom

Con Rtag puedes establecer objetos custom como NBT y obtenerlos según el tipo de objeto requerido, dependiendo en tus necesdiades existen diferentes opciones para (de)serializar objetos.

Serializador Gson​

Al usar la librería Gson dentro del código de Bukkit, es posible (de)serializar objetos mediante el siguiente proceso:

Serializer (establecer): Objeto custom -> String en Json -> Map -> CompoundTag

Deserializer (obtener): CompoundTag -> Map -> String en Json -> Objeto custom

// Crear tu objeto custom
MyObject myObj = ...;

// --- Obtenerlo desde una instancia de Rtag
Rtag rtag = ...;
Object compount = ...;
// Establecer en "my -> object -> path"
rtag.set(compound, myObj, "my", "object", "path");
// Obtener desde "my <- object <- path"
MyObject sameObj = rtag.getOptional(compount, "my", "object", "path").as(MyObject.class);


// --- Obtenerlo desde una instancia de RtagEditor
RtagEditor tag = ...;
// Establecer en "my -> object -> path"
tag.set(myObj, "my", "object", "path");
// Obtener desde "my <- object <- path"
MyObject sameObj = tag.getOptional("my", "object", "path").as(MyObject.class);

Registro en Rtag​

Rtag por defecto solo tiene soporte con objetos normales de Java (String, Integer, List... etc), si quieres establecer y obtener objetos custom puedes registrar un (de)serializador en la instancia de Rtag.

RtagSerializer: Instancia para convertir el objeto custom en un Map.

RtagDeserializer: Instancia para converir el Map en un objeto custom.

info

Esta conversión establece un key adicional en el tag guardado para detectarlo usando el ID proporcionado.

Ejemplo​

Supongamos que tienes un objeto custom llamado CustomData para guardar datos adicionales en tus items:

package my.plugin;

public class CustomData {

private final String type;
private int level;
private boolean broken;

public CustomData(String type, int level, boolean broken) {
this.type = type;
this.level = level;
this.broken = broken;
}

public String getType() {
return type;
}

public int getLevel() {
return level;
}

public boolean isBroken() {
return broken;
}

public void setLevel(int level) {
this.level = level;
}

public void setBroken(boolean broken) {
this.broken = broken;
}

public boolean equals(Object object) {
if (object instanceof CustomData) {
CustomData data = (CustomData) object;
return data.getType().equals(type) && data.getLevel == level && data.isBroken == broken;
}
return false;
}
}

Ahora debes crear un class que funcione como serializador y deserializador:

package my.plugin;

import java.util.HashMap;
import java.util.Map;

public class CustomDataSerializer implements RtagSerializer<CustomData>, RtagDeserializer<CustomData> {

// ID usado para convertir el objeto custom en un Map
// CustomData -> Map
@Override
public String getInID() {
return "myplugin:CustomData";
}

// ID usado para convertir un Map en un objeto custom
// Map -> CustomData
@Override
public String getOutID() {
return "myplugin:CustomData";
}

// Convertir el objeto de CustomData en un Map
@Override
public Map<String, Object> serialize(CustomData data) {
Map<String, Object> map = new HashMap();
map.put("type", data.getType());
map.put("level", data.getLevel());
map.put("broken", data.isBroken());
return map;
}

// Convertir el Map en un objeto de CustomData
@Override
public CustomData deserialize(Map<String, Object> map) {
String type = map.get("type");
Integer level = map.get("level");
Boolean broken = map.get("broken");

if (type == null || level == null || broken == null) {
return null;
} else {
return new CustomData(type, level, broken);
}
}
}
tip

Se sugiere usar un ID con el formado de <plugin>:<objeto> para evitar incompatibilidad con otros plugins.

Luego debes registrar el class en la instancia de Rtag que estás utilizando:

Rtag rtag = ...;
CustomDataSerializer serializer = new CustomDataSerializer();

rtag.putSerializer(CustomData.class, serializer);
rtag.putDeserializer(serializer);

Ahora al utilizar la instancia de Rtag donde registraste el CustomDataSerializer podrás guardar y almacenar el objeto de CustomData.

En este ejemplo se usará un RtagItem con la instancia de Rtag que tiene registrado el CustomDataSerializer:

private final Rtag rtag = initRtag();

private Rtag initRtag() {
Rtag rtag = new Rtag();
CustomDataConversion serializer = new CustomDataConversion();
rtag.putSerializer(CustomData.class, serializer);
rtag.putDeserializer(serializer);
return rtag;
}

public void example(ItemStack item) {
RtagItem tag = new RtagItem(rtag, item);

// -- Guardar data custom en el ItemStack

// Data para el item
CustomData data = new CustomData("EPIC", 30, false);
// Establecer en la ruta "custom -> data"
tag.set(data, "custom", "data");

// Los cambios serán cargados en el item original
tag.load();


// -- Obtener la data custom desde un ItemStack

// Obtener la data desde "custom" -> "data" sin una conversión explícita
CustomData itemData = tag.get("custom", "data");
// Revisar si son iguales
System.out.println(data.equals(itemData));
}