1.17.x ItemStack enchant in Base64 is different

Discussion in 'Spigot Plugin Development' started by GeraldFrito, Jun 13, 2021.

  1. Hi guys

    I developed a plugin called Backpack that open a inventory to save and load items that you want to.

    The problem comes when I want to remove one specific. When some items has Mending enchantment and this has his durability lower than the maximum of it, the item's base64 text is not the same as before saved on database. But the item doesn't change its data during player close his inventory, so why its base64 text is different. Get my code:

    This method runs on InventoryCloseEvent
    Note: The "getAllPlayerItems" comes from Database
    Code (Java):
    if (e.getView().getTitle().equals("§1§lMochila")) {
                    int size = 54;//UserAccount.hasVIP(player.getName()) ? 27 : 9;
                    ArrayList<ItemStack> itemssaved = BackpackManager.getAllPlayerItems(player.getName());
                    Main.getPluginLogger().info("Items saved on BD before removing or changing: "+itemssaved.toString());
                    boolean hasItemNotAllowed = false;
                    for (int slot = 0; slot < size; slot++) {
                        ItemStack current = inventory.getItem(slot);
                        if (slot < itemssaved.size()) {
                            if(BackpackManager.removeItem(player.getName(), itemssaved.get(slot))) {
                                Main.getPluginLogger().info("Item removed: "+itemssaved.get(slot).toString());
                            }
                        }
                        if (current != null) {
                            if(BackpackManager.addItem(player.getName(), current)) {
                                Main.getPluginLogger().info("Item added at the same time: "+current.toString());
                            }
                        }
                    }
                    Main.getPluginLogger().info("All items on BD after closed inventory: "+BackpackManager.getAllPlayerItems(player.getName()).toString());
                    if (hasItemNotAllowed) {
                        player.sendMessage("No puedes guardar este objeto. Lo hemos tirado al suelo.");
                    }
                }

    This method has to remove the item:
    Code (Java):
    public static boolean removeItem(String owner, ItemStack item) {
            try {
                int id = getID(owner, item);
                /*if (id < 0)
                    return false;*/

                String item_encoded = encodeItemStack(item);
                ps = DatabaseConnection.getConnection().prepareStatement("DELETE FROM user_backpack WHERE owner=? AND item=?");
                ps.setString(1, owner);
                ps.setString(2, item_encoded);
                int result = ps.executeUpdate();
                ps.close();
                return (result > 0);
            } catch (SQLException e) {
                e.printStackTrace();
                return false;
            }
        }
    With this method I convert the item to base64 text.
    Code (Java):
    private static String encodeItemStack(ItemStack item) {
            try {
                ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                BukkitObjectOutputStream dataOutput = new BukkitObjectOutputStream(outputStream);
                dataOutput.writeObject(item);
                dataOutput.close();
                return Base64Coder.encodeLines(outputStream.toByteArray());
            } catch (IOException e) {
                throw new IllegalStateException("No se ha podido guardar el ItemStack", e);
            }
        }
     
  2. The "item_encoded" is not the same, for that reason it doesn't recognize it exists on DB to remove it. The item base64 text is 95% the same of is saved on database. It changes at the end of that text. Some words are different and I don't know why, because the item data has not been changed.