Saving a players inventory in a HashMap

Discussion in 'Plugin Development' started by joehot2000, Apr 22, 2013.

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

    joehot2000

    Hi, is it possible i could get some code to save an inventory in a hashmap? i add the itemstack to the hashmap, and when trying to give it to the player, it does not work.

    Thanks for any help!
     
  2. Offline

    chasechocolate

    Code:java
    1. HashMap<String, ItemStack[]> inventoryContents = new HashMap<String, ItemStack[]>();
    2. HashMap<String, ItemStack[]> inventoryArmorContents = new HashMap<String, ItemStack[]>();
    3.  
    4. //Setting
    5. inventoryContents.put(player.getName(), player.getInventory().getContents());
    6. inventoryArmorContents.put(player.getName(), player.getInventory().getArmorContents());
    7.  
    8. //Getting
    9. if(inventoryContents.containsKey(player.getName() && inventoryArmorContents.containsKey(player.getName())){
    10. player.getInventory().clear();
    11. player.getInventory().setContents(inventoryContents.get(player.getName()));
    12. player.getInventory().setArmorContents(inventoryArmorContents.get(player.getName());
    13. }
     
  3. Offline

    Tirelessly

    That will be a reference. When the players inventory changes, it will change in the map too. Hence, when you try and give it back, it seems like it doesn't work.
     
  4. Offline

    joehot2000

    Thanks man!! :D

    player.updateInventory(); would fix this?

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 1, 2016
  5. Offline

    Tirelessly

    No.
     
  6. Offline

    joehot2000

    Dammit, so what would i do to fix it?
     
  7. Offline

    RainoBoy97

    That's never been the case for me. I used this method and it worked fine last time I did it. This was in 1.4.7 tho!
     
  8. Clone the contents... just add .clone() at the end when setting :)

    But references won't be useful if used as mirrors to inventory either, because if an item is removed the slot will become null but the item will still exist in your array, therefore not an actual mirror of the inventory. So my point is don't try to use it as mirror like that, if you want a link to player's inventory you only need player's name, safest way.

    EDIT Tirelessly right, thanks for the heads up.
     
  9. Offline

    Tirelessly

    Digi clone is a shallow copy and probably wouldn't work in this case. Try Arrays.deepCopy or System.arrayCopy I'm not sure the name exactly
     
  10. Tirelessly
    Yeah, about that, I've done some tests... it seems System.arraycopy() does NOT clone the elements and Arrays.copyOf() is just a shortcut for that method.

    I had to loop through elements and clone each individual one in order to get a full clone.

    code used for testing (open)
    Code:
        private void test()
        {
            ItemStack[] original = new ItemStack[]
            {
                new ItemStack(Material.APPLE),
                new ItemStack(Material.ANVIL),
                new ItemStack(Material.BED),
            };
            
            ItemStack[] quickClone = original.clone();
            
            ItemStack[] arrayCopyOf = Arrays.copyOf(original, original.length);
            
            ItemStack[] arraycopy = new ItemStack[original.length];
            System.arraycopy(original, 0, arraycopy, 0, original.length);
            
            ItemStack[] loopClone = new ItemStack[original.length];
            for(int i = 0; i < loopClone.length; i++)
            {
                loopClone[i] = original[i].clone();
            }
            
            original[0].setType(Material.DIAMOND);
            
            System.out.print("original     = " + Arrays.toString(original));
            System.out.print("quickClone   = " + Arrays.toString(quickClone));
            System.out.print("arraycopy    = " + Arrays.toString(arraycopy));
            System.out.print("arrayCopyOf  = " + Arrays.toString(arrayCopyOf));
            System.out.print("loopClone    = " + Arrays.toString(loopClone));
        }
    
    Results:
    Code:
    16:07:59 [INFO] original     = [ItemStack{DIAMOND x 1}, ItemStack{ANVIL x 1}, ItemStack{BED x 1}]
    16:07:59 [INFO] quickClone   = [ItemStack{DIAMOND x 1}, ItemStack{ANVIL x 1}, ItemStack{BED x 1}]
    16:07:59 [INFO] arraycopy    = [ItemStack{DIAMOND x 1}, ItemStack{ANVIL x 1}, ItemStack{BED x 1}]
    16:07:59 [INFO] arrayCopyOf  = [ItemStack{DIAMOND x 1}, ItemStack{ANVIL x 1}, ItemStack{BED x 1}]
    16:07:59 [INFO] loopClone    = [ItemStack{APPLE x 1}, ItemStack{ANVIL x 1}, ItemStack{BED x 1}]
    
     
  11. Offline

    joehot2000

    Digi Tirelessly
    Decompiled the plugin BattleNight.
    Here is the code they use.

    private static Map<String, PlayerData> storage = new HashMap();


    public static void store(Player player) {
    PlayerData data = new PlayerData();

    for (Player p : Bukkit.getServer().getOnlinePlayers()) {
    if (!player.canSee(p)) {
    data.vanishedPlayers.add(p.getName());
    }
    }

    data.potionEffects = player.getActivePotionEffects();
    data.allowFlight = player.getAllowFlight();
    data.compassTarget = player.getCompassTarget();
    data.displayName = player.getDisplayName();
    data.enderItems = player.getEnderChest().getContents();
    data.exaustion = player.getExhaustion();
    data.exp = player.getExp();
    data.fallDistance = player.getFallDistance();
    data.fireTicks = player.getFireTicks();
    data.flySpeed = player.getFlySpeed();
    data.foodLevel = player.getFoodLevel();
    data.gameMode = player.getGameMode().getValue();
    data.health = player.getHealth();
    data.invItems = player.getInventory().getContents();
    data.invArmour = player.getInventory().getArmorContents();
    data.level = player.getLevel();
    data.location = player.getLocation().clone();
    data.playerListName = player.getPlayerListName();
    data.playerTimeOffset = player.getPlayerTimeOffset();
    data.remainingAir = player.getRemainingAir();
    data.saturation = player.getSaturation();
    data.ticksLived = player.getTicksLived();
    data.velocity = player.getVelocity();
    data.walkSpeed = player.getWalkSpeed();
    data.flying = player.isFlying();
    data.playerTimeRelative = player.isPlayerTimeRelative();
    data.sleepingIgnored = player.isSleepingIgnored();
    data.sneaking = player.isSneaking();
    data.sprinting = player.isSprinting();

    storage.put(player.getName(), data);
    }
    }

    And, to restore

    public static boolean restore(Player player, boolean teleport, boolean keepInMemory)
    {
    String name = player.getName();
    if (!storage.containsKey(name)) {
    api.getMessenger().debug(Level.SEVERE, "Failed to restore " + name + "!");
    return false;
    }

    PlayerData data = (PlayerData)storage.get(name);

    if (teleport) {
    Waypoint wp = api.getArenaManager().getExit();
    if ((ConfigManager.get(ConfigManager.Config.MAIN).getBoolean("ExitWaypoint", false)) && (wp.isSet()))
    SafeTeleporter.tp(player, wp.getLocation());
    else {
    SafeTeleporter.tp(player, data.location);
    }
    }

    for (Player p : Bukkit.getServer().getOnlinePlayers()) {
    if (data.vanishedPlayers.contains(p.getName()))
    player.hidePlayer(p);
    else {
    player.showPlayer(p);
    }
    }

    for (PotionEffect effect : player.getActivePotionEffects()) {
    player.addPotionEffect(new PotionEffect(effect.getType(), 0, 0), true);
    }

    player.addPotionEffects(data.potionEffects);
    player.setAllowFlight(data.allowFlight);

    player.setCompassTarget(data.compassTarget);
    player.setDisplayName(data.displayName);
    player.getEnderChest().setContents(data.enderItems);
    player.setExhaustion(data.exaustion);
    player.setExp(data.exp);
    player.setFallDistance(data.fallDistance);
    player.setFireTicks(data.fireTicks);
    player.setFlySpeed(data.flySpeed);
    player.setFoodLevel(data.foodLevel);

    GameMode gamemode = GameMode.getByValue(data.gameMode);
    if (player.getGameMode() != gamemode) {
    player.setGameMode(gamemode);
    }

    player.setHealth(data.health);
    player.getInventory().setContents(data.invItems);
    player.getInventory().setArmorContents(data.invArmour);
    player.setLevel(data.level);
    player.setPlayerListName(data.playerListName);

    if (!data.playerTimeRelative)
    player.setPlayerTime(data.playerTimeOffset, true);
    else {
    player.resetPlayerTime();
    }

    player.setRemainingAir(data.remainingAir);
    player.setSaturation(data.saturation);
    player.setTicksLived(data.ticksLived);
    player.setVelocity(data.velocity);
    player.setWalkSpeed(data.walkSpeed);
    player.setFlying(data.flying);
    player.setSleepingIgnored(data.sleepingIgnored);
    player.setSneaking(data.sneaking);
    player.setSprinting(data.sprinting);

    if (!keepInMemory) {
    storage.remove(name);
    }
    return true;
    }

    Pretty clever :confused:

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 1, 2016
Thread Status:
Not open for further replies.

Share This Page