Solved String to respective itemstack

Discussion in 'Plugin Development' started by DogeDebugger, May 20, 2015.

Thread Status:
Not open for further replies.
  1. Offline

    DogeDebugger

    So lets say i had this string in a file

    Code:
    ItemStack{IRON_AXE x 1, UNSPECIFIC_META:{meta-type=UNSPECIFIC, display-name=&aIron , repair-cost=2}}
    How can i convert that to its respective itemstack? Which will be an iron axe with the name Iron in green :p
     
  2. Offline

    caderape

    @DogeDebugger bukkit has a method for save and load itemstack.
    config.set(path, itemstack);
    config.getItemStack(path, itemstack def);
     
  3. Offline

    DogeDebugger

    I know, but i meant actually turning the string to an itemstack after getting it.
     
  4. Offline

    Zombie_Striker

    A better way to do this would be to create your own method and create and split a string.

    1) Make a String like so
    TYPE:IRON_PICKAXE@NAME:&G Iron

    2) At first with the @s so you get each key and value, To get
    [0] = TYPE:IRON_PICKAXE
    [1] = NAME:&G Iron

    3) Then split it at ':' to get the key[0] and the value [1];
    e.g.
    [0] = Type
    [1] = IRON_PICKAXE

    4) Look to find the right method to use:
    Code:
    if(args[0].equalsIgnoreCase("TYPE")){
    ItemStack#setType(Mateerial.getMaterial(args[1]));
    }
    if(args[0].equalsIgnoreCase("NAME")){
    //ect
    }
    and turn it into the itemstack with type IronPickaxe with the name &G Iron
     
  5. Offline

    Gater12

  6. Offline

    nverdier

  7. Offline

    meguy26

    @Zombie_Striker @DogeDebugger
    Zombie_Striker, my plugin actually does this, but it has a fault, as does your method, what if the custom name has an @, or the split symbol in it. I can post the methods here, but I feel like people would hate on their horridness, I am trying to create a new way of doing this, because the current way is ugly.
     
  8. Offline

    AdamQpzm

    @meguy26 One way would be to iterate over the string and split yourself. That way, you could allow for escape characters, such as \
     
  9. Offline

    meguy26

    @AdamQpzm
    true, but I think I am just going to convert it to a SaveObject. A SaveObject is just a class I wrote that allows you to save strings to a file, it has some nifty features that neither JSON nor YAML provide...

    Anyway the way I currently do what the op is asking:
    Open to see horrible code (open)

    Code:
    /**
    * The MIT License (MIT)
    *
    * Copyright (c) 2015 neonblue858@gmail.com
    *
    * Permission is hereby granted, free of charge, to any person obtaining a
    * copy of this software and associated documentation files (the
    * "Software"), to deal in the Software without restriction, including
    * without limitation the rights to use, copy, modify, merge, publish,
    * distribute, sublicense, and/or sell copies of the Software, and to permit
    * persons to whom the Software is furnished to do so, subject to the
    * following conditions:
    *
    * The above copyright notice and this permission notice shall be included
    * in all copies or substantial portions of the Software.
    *
    * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
    * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
    * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
    * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
    * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
    * USE OR OTHER DEALINGS IN THE SOFTWARE.
    *
    * @author Meguy26 (neonblue858@gmail.com)
    */
    package com.gmail.neonblue858.mipa.pluginutil;
    
    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;
    import java.util.Map;
    
    import org.bukkit.Bukkit;
    import org.bukkit.Location;
    import org.bukkit.Material;
    import org.bukkit.enchantments.Enchantment;
    import org.bukkit.inventory.ItemStack;
    import org.bukkit.inventory.meta.ItemMeta;
    /**
    * @author meguy26
    */
    public class ValueSaver {
    
        /**
         * Converts a location to a string.
         * @param loca The location to convert.
         * @return location string
         */
        public static String serializeLocation(Location loca) {
            Location loc = loca.clone();
            return loc.getWorld().getName() + "," + String.valueOf(loc.getX())
                    + "," + String.valueOf(loc.getY()) + ","
                    + String.valueOf(loc.getZ());
        }
    
        /**
         * Converts a location from a string.
         * @param input The location string to convert to a location.
         * @return location
         */
        public static Location deSerializeLocation(String input) {
            String[] data = input.split(",");
            return new Location(Bukkit.getWorld(data[0]),
                    Double.parseDouble(data[1]), Double.parseDouble(data[2]),
                    Double.parseDouble(data[3]));
        }
    
        /**
         * Converts an itemstack to a string.
         *
         * @param it
         *            the item stack to 'serialize'
         * @return itemstack string
         * @deprecated Use as a last resort, it is not a well written method.
         */
        public static String serializeItemStack(ItemStack it) {
            if (it == null || it.getType() == null
                    || it.getType().equals(Material.AIR)) {
                return "NULL";
            } else {
                String data = "";
                data = data + it.getType().toString() + ":"
                        + String.valueOf(it.getData().getData()) + ";idsep;";
                data = data + String.valueOf(it.getAmount()) + ";idsep;";
    
                String dName = "NULLVALUE";
                if (it.hasItemMeta() && it.getItemMeta().hasDisplayName()) {
                    dName = it.getItemMeta().getDisplayName();
                }
                data = data + dName + ";idsep;";
    
                String lore = "NULLVALUE";
                if (it.hasItemMeta() && it.getItemMeta().hasLore()) {
                    lore = "";
                    List<String> lores = it.getItemMeta().getLore();
                    Iterator<String> itr = lores.iterator();
                    while (itr.hasNext()) {
                        String loren = itr.next();
                        if (itr.hasNext()) {
                            lore = lore + loren + "-loresep-";
                        } else {
                            lore = lore + loren;
                        }
                    }
                }
    
                data = data + lore + ";idsep;";
    
                String durability = String.valueOf(it.getDurability());
    
                data = data + durability + ";idsep;";
    
                String enchants = "NULLVALUE";
                if (it.hasItemMeta() && it.getItemMeta().hasEnchants()) {
                    enchants = "";
                    Map<Enchantment, Integer> enchs = it.getItemMeta()
                            .getEnchants();
                    Iterator<Enchantment> enIt = enchs.keySet().iterator();
                    while (enIt.hasNext()) {
                        Enchantment key = enIt.next();
                        Integer value = enchs.get(key);
                        if (enIt.hasNext()) {
                            enchants = enchants + key.getName() + ":"
                                    + value.toString() + ">enchsep<";
                        } else {
                            enchants = enchants + key.getName() + ":"
                                    + value.toString();
                        }
                    }
                }
    
                data = data + enchants;
                return data;
            }
        }
    
        /**
         * Converts a string to a itemstack
         *
         * @param str
         *            the string to 'de-serialize' intp an item stack.
         * @return itemstack
         * @deprecated Use as a last resort, it is not a well written method.
         */
        public static ItemStack deSerializeItemStack(String str) {
            if (!str.equalsIgnoreCase("NULL")) {
                if (str.contains(";idsep;")) {
                    String[] data = str.split(";idsep;");
    
                    String[] typeData = data[0].split(":");
                    Material type = Material.getMaterial(typeData[0].toUpperCase());
                    byte meta = (byte) Integer.parseInt(typeData[1]);
                    int amount = Integer.parseInt(data[1]);
    
                    ItemStack toReturn = new ItemStack(type);
                    toReturn.getData().setData(meta);
                    toReturn.setAmount(amount);
    
                    ItemMeta im = toReturn.getItemMeta();
                    String name = data[2];
                    if (!name.equalsIgnoreCase("NULLVALUE")) {
                        im.setDisplayName(name);
                    }
    
                    String lor = data[3];
                    if (!lor.equalsIgnoreCase("NULLVALUE")) {
                        List<String> lores = new ArrayList<String>();
                        String[] lorArray = lor.split("-loresep-");
                        for (int i = 0; i < lorArray.length; i++) {
                            lores.add(lorArray[i]);
                        }
                        im.setLore(lores);
                    }
    
                    short durability = Short.parseShort(data[4]);
                    toReturn.setDurability(durability);
    
                    String ench = data[5];
                    if (!ench.equalsIgnoreCase("NULLVALUE")) {
                        String[] enchantments = ench.split(">enchsep<");
                        for (int i = 0; i < enchantments.length; i++) {
                            String[] enchantmentData = enchantments[i].split(":");
                            Enchantment enchant = Enchantment
                                    .getByName(enchantmentData[0]);
                            im.addEnchant(enchant,
                                    Integer.parseInt(enchantmentData[1]), true);
                        }
                    }
    
                    toReturn.setItemMeta(im);
    
                    return toReturn;
                } else {
                    throw new IllegalArgumentException(
                            "String is not a serialized itemstack!");
                }
            } else {
                return new ItemStack(Material.AIR);
            }
        }
    
    }
    


    Regardless, I intend to change this to something more reliable, honestly the best way to do this would be to save it to a YAML file, it makes everything easier.
     
  10. Offline

    Zombie_Striker

    @meguy26 Then make the code even more specific, change the '@' and the ':' to this.
    Code:
    [@&111SPLIT ONE111&@]
    [@#222SPLIT TWO222#@]
    How many people will name an item to have names like this?
     
  11. Offline

    meguy26

  12. Offline

    DogeDebugger

  13. Offline

    Zombie_Striker

    @meguy26
    Then what you're saying is that there are no string sequence that you can use, and so you should not use any.

    Pick a complex one you think no one will use, and hope no one read your code to find that complex,random string.
     
  14. Offline

    meguy26

    @DogeDebugger
    well, I mean, if you want to use my class you can, but I still suggest just using the config method (config#put(Path, ItemStack)) Like @nverdier said:


    @Zombie_Striker
    Exactly, there is nothing directly excluded from the item name, so you can never be absolutely certain a custom item name will break it, granted I have not seen a custom item named ";idsep;" yet, but you never know.
     
  15. Offline

    Zombie_Striker

    @meguy26
    Then you should stop working on your plugin. There is no way to get around it, and there will never be. Either take the very, VERY, small risk someone will pick that excact string as their name, or abandon the project entirely.
     
  16. Offline

    DogeDebugger

    DIAMOND_SWORD|name |[§rhi]|{Enchantment[20, FIRE_ASPECT]=2}

    How can i split up that string? (i changed the body of the string to make it easier to understand)

    Type, name, lore, enchant
     
  17. Offline

    meguy26

    @Zombie_Striker
    There is a way to do this, but not directly as a single string, but what I have in mind will work from my plugin:
    @DogeDebugger
    Take a look at the method I posted, if you wish you can copy-paste it, but I would encourage you to figure out how to do it your self:
     
  18. Offline

    nverdier

    @DogeDebugger
    1) FileConfiguration#set(path, itemStack)
    2) FileConfiguration#getItemStack(path)

    What's wrong with that?
     
    DogeDebugger likes this.
  19. Offline

    caderape

    @DogeDebugger
    Good luck for turn that string in an itemstack. If it's from yourself, you should change your way to store it.

    Split method works with a condition. It's to separate the values with the same character for get back infos. Like type, name, enchant, lore etc.... then you can #split(",") and get each value.

    You string looks really weird. I guess you will have to split the '|', then the '{' and after i don't even know what '20, FIRE_ASPECT]=2' means.
     
  20. Offline

    meguy26


    @DogeDebugger Honestly, what is wrong with that?
     
  21. Offline

    DogeDebugger

    solved...guess i overlooked that post
     
    nverdier likes this.
Thread Status:
Not open for further replies.

Share This Page