diff --git a/src/main/java/me/unurled/sacredrealms/sr/components/player/PlayerManager.java b/src/main/java/me/unurled/sacredrealms/sr/components/player/PlayerManager.java index ed05f28..420c84d 100644 --- a/src/main/java/me/unurled/sacredrealms/sr/components/player/PlayerManager.java +++ b/src/main/java/me/unurled/sacredrealms/sr/components/player/PlayerManager.java @@ -3,14 +3,21 @@ package me.unurled.sacredrealms.sr.components.player; import static me.unurled.sacredrealms.sr.utils.Logger.error; import com.google.gson.Gson; +import com.google.gson.GsonBuilder; import java.util.HashMap; import java.util.UUID; import me.unurled.sacredrealms.sr.data.DataHandler; import me.unurled.sacredrealms.sr.data.DataManager; +import me.unurled.sacredrealms.sr.data.gson.InventoryDeserializer; +import me.unurled.sacredrealms.sr.data.gson.InventorySerializer; +import me.unurled.sacredrealms.sr.data.gson.PotionEffectDeserializer; +import me.unurled.sacredrealms.sr.data.gson.PotionEffectSerializer; import me.unurled.sacredrealms.sr.managers.Manager; import org.bukkit.event.EventHandler; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.potion.PotionEffect; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -32,13 +39,11 @@ public class PlayerManager extends Manager { return; } DataHandler dh = dm.getDataHandler(); - Gson gson = new Gson(); - dh.set("sr.players", gson.toJson(players)); } /** Load the data */ - @Override - public void loadData() {} + /*@Override + public void loadData() {}*/ @Nullable public SRPlayer getPlayer(UUID uuid) { @@ -59,20 +64,30 @@ public class PlayerManager extends Manager { @EventHandler public void onPlayerJoin(PlayerJoinEvent e) { - SRPlayer player = new SRPlayer(e.getPlayer()); // load data from db // TODO: test this after redis cache - /*DataManager dm = (DataManager) DataManager.getInstance(DataManager.class); + DataManager dm = (DataManager) DataManager.getInstance(DataManager.class); if (dm == null) { error("DataManager is null, Can't load player " + e.getPlayer().getName() + "'s data" + "."); return; } DataHandler dh = dm.getDataHandler(); - Gson gson = new Gson(); - Object json = dh.getGson("sr.players." + e.getPlayer().getUniqueId());*/ - addPlayer(player); + Gson gson = + new GsonBuilder() + .registerTypeAdapter(Inventory.class, new InventoryDeserializer()) + .registerTypeAdapter(PotionEffect.class, new PotionEffectDeserializer()) + .excludeFieldsWithoutExposeAnnotation() + .create(); + String json = dh.get("sr.players." + e.getPlayer().getUniqueId()); + SRPlayer srPlayer = gson.fromJson(json, SRPlayer.class); + + addPlayer(srPlayer); + + e.getPlayer().getInventory().clear(); + e.getPlayer().getInventory().setContents(srPlayer.getInventory().getContents()); + + e.getPlayer().updateInventory(); } - // TODO: test if it works, i have a doubt about the jsonAppend (key + path seems weird) @EventHandler public void onPlayerQuit(PlayerQuitEvent e) { SRPlayer player = getPlayer(e.getPlayer().getUniqueId()); @@ -86,7 +101,12 @@ public class PlayerManager extends Manager { return; } DataHandler dh = dm.getDataHandler(); - Gson gson = new Gson(); + Gson gson = + new GsonBuilder() + .excludeFieldsWithoutExposeAnnotation() + .registerTypeAdapter(Inventory.class, new InventorySerializer()) + .registerTypeAdapter(PotionEffect.class, new PotionEffectSerializer()) + .create(); dh.set("sr.players." + e.getPlayer().getUniqueId(), gson.toJson(player)); removePlayer(e.getPlayer().getUniqueId()); diff --git a/src/main/java/me/unurled/sacredrealms/sr/data/gson/InventoryDeserializer.java b/src/main/java/me/unurled/sacredrealms/sr/data/gson/InventoryDeserializer.java new file mode 100644 index 0000000..9967a67 --- /dev/null +++ b/src/main/java/me/unurled/sacredrealms/sr/data/gson/InventoryDeserializer.java @@ -0,0 +1,42 @@ +package me.unurled.sacredrealms.sr.data.gson; + +import static me.unurled.sacredrealms.sr.utils.Logger.log; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonParseException; +import java.lang.reflect.Type; +import java.util.Arrays; +import org.bukkit.Bukkit; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; + +public class InventoryDeserializer implements JsonDeserializer { + + @Override + public Inventory deserialize(JsonElement jsonElement, Type type, + JsonDeserializationContext jsonDeserializationContext) throws JsonParseException { + Inventory inv = Bukkit.createInventory(null, InventoryType.PLAYER); + // parse from a string, to a list of string + String[] contents = jsonElement.getAsString().split(";"); + // iterate through the list of strings and create ItemStacks with deserialize() + Gson gson = + new GsonBuilder() + .registerTypeAdapter(ItemStack.class, new ItemStackDeserializer()) + .create(); + for (int i = 0; i < contents.length; i++) { + if (contents[i].equals("null")) { + inv.setItem(i, null); + } else { + ItemStack item = gson.fromJson(contents[i], ItemStack.class); + if (item != null) + inv.setItem(i, item); + } + } + return inv; + } +} diff --git a/src/main/java/me/unurled/sacredrealms/sr/data/gson/InventorySerializer.java b/src/main/java/me/unurled/sacredrealms/sr/data/gson/InventorySerializer.java new file mode 100644 index 0000000..f73fdab --- /dev/null +++ b/src/main/java/me/unurled/sacredrealms/sr/data/gson/InventorySerializer.java @@ -0,0 +1,27 @@ +package me.unurled.sacredrealms.sr.data.gson; + +import static me.unurled.sacredrealms.sr.utils.Logger.error; + +import com.google.gson.JsonElement; +import com.google.gson.JsonPrimitive; +import com.google.gson.JsonSerializationContext; +import com.google.gson.JsonSerializer; +import java.lang.reflect.Type; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; +import org.bukkit.inventory.Inventory; + +public class InventorySerializer implements JsonSerializer { + + @Override + public JsonElement serialize(Inventory itemStacks, Type type, + JsonSerializationContext jsonSerializationContext) { + List collect = Arrays.stream(itemStacks.getContents()) + .map(item -> item == null ? "null" : Arrays.toString(item.serializeAsBytes())).collect(Collectors.toList()); + + String s = String.join(";", collect); + return new JsonPrimitive(s); + } +} diff --git a/src/main/java/me/unurled/sacredrealms/sr/data/gson/ItemStackDeserializer.java b/src/main/java/me/unurled/sacredrealms/sr/data/gson/ItemStackDeserializer.java new file mode 100644 index 0000000..98abd90 --- /dev/null +++ b/src/main/java/me/unurled/sacredrealms/sr/data/gson/ItemStackDeserializer.java @@ -0,0 +1,26 @@ +package me.unurled.sacredrealms.sr.data.gson; + +import com.google.common.reflect.TypeToken; +import com.google.gson.Gson; +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonParseException; +import java.lang.reflect.Type; +import java.util.Map; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; + +public class ItemStackDeserializer implements JsonDeserializer { + + @Override + public ItemStack deserialize(JsonElement jsonElement, Type type, + JsonDeserializationContext jsonDeserializationContext) throws JsonParseException { + Gson gson = new Gson(); + byte[] mm = gson.fromJson(jsonElement, byte[].class); + if (mm != null) { + return ItemStack.deserializeBytes(mm); + } + return null; + } +} diff --git a/src/main/java/me/unurled/sacredrealms/sr/data/gson/PotionEffectDeserializer.java b/src/main/java/me/unurled/sacredrealms/sr/data/gson/PotionEffectDeserializer.java new file mode 100644 index 0000000..cbb71dc --- /dev/null +++ b/src/main/java/me/unurled/sacredrealms/sr/data/gson/PotionEffectDeserializer.java @@ -0,0 +1,37 @@ +package me.unurled.sacredrealms.sr.data.gson; + +import static me.unurled.sacredrealms.sr.utils.Logger.error; + +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonParseException; +import java.lang.reflect.Type; +import org.bukkit.NamespacedKey; +import org.bukkit.Registry; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +public class PotionEffectDeserializer implements JsonDeserializer { + + @Override + public PotionEffect deserialize(JsonElement jsonElement, Type type, + JsonDeserializationContext jsonDeserializationContext) throws JsonParseException { + try { + String pot = jsonElement.getAsString(); + pot = pot.replace("{", "").replace("}", ""); + String[] parts = pot.split(","); + // find the potion effect type from the string part[0] is a key + PotionEffectType pet = Registry.POTION_EFFECT_TYPE.get(new NamespacedKey("minecraft", + parts[0])); + int duration = Integer.parseInt(parts[1]); + int amplifier = Integer.parseInt(parts[2]); + boolean particles = Boolean.parseBoolean(parts[3]); + + return new PotionEffect(pet, duration, amplifier, false, particles, false); + } catch(Exception e) { + error("Error deserializing potion effect: " + e.getMessage()); + } + return null; + } +} diff --git a/src/main/java/me/unurled/sacredrealms/sr/data/gson/PotionEffectSerializer.java b/src/main/java/me/unurled/sacredrealms/sr/data/gson/PotionEffectSerializer.java new file mode 100644 index 0000000..ddc4b48 --- /dev/null +++ b/src/main/java/me/unurled/sacredrealms/sr/data/gson/PotionEffectSerializer.java @@ -0,0 +1,27 @@ +package me.unurled.sacredrealms.sr.data.gson; + +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonPrimitive; +import com.google.gson.JsonSerializationContext; +import com.google.gson.JsonSerializer; +import java.lang.reflect.Type; +import org.bukkit.potion.PotionEffect; + +public class PotionEffectSerializer implements JsonSerializer { + + @Override + public JsonElement serialize(PotionEffect potionEffect, Type type, + JsonSerializationContext jsonSerializationContext) { + StringBuilder sb = new StringBuilder(); + sb.append("{"); + sb.append(potionEffect.getType().key()); + sb.append(","); + sb.append(potionEffect.getDuration()); + sb.append(","); + sb.append(potionEffect.getAmplifier()); + sb.append(",").append(potionEffect.hasParticles()); + sb.append("}"); + return new JsonPrimitive(sb.toString()); + } +}