Fixed keep-items not working with spectators

This commit is contained in:
Fisher2911 2022-10-17 22:51:04 -04:00
parent d8304ce0b6
commit 3d107479b5
5 changed files with 160 additions and 11 deletions

View File

@ -16,6 +16,8 @@ import com.garbagemule.MobArena.region.ArenaRegion;
import com.garbagemule.MobArena.repairable.Repairable;
import com.garbagemule.MobArena.repairable.RepairableComparator;
import com.garbagemule.MobArena.repairable.RepairableContainer;
import com.garbagemule.MobArena.steps.CompositeStep;
import com.garbagemule.MobArena.steps.KeepDropsStep;
import com.garbagemule.MobArena.steps.PlayerJoinArena;
import com.garbagemule.MobArena.steps.PlayerSpecArena;
import com.garbagemule.MobArena.steps.Step;
@ -867,6 +869,19 @@ public class ArenaImpl implements Arena {
// Clear the player's inventory, and unmount
if (arenaPlayers.remove(p)) {
unmount(p);
if (this.keepDrops) {
this.inventoryManager.removeOriginalItems(plugin, p);
final Step step = histories.get(p);
if (step != null) {
final Step keepDropsStep = KeepDropsStep.create(this).create(p);
keepDropsStep.run();
final Step composite = CompositeStep.create(
step,
keepDropsStep
).create(p);
histories.put(p, composite);
}
}
clearInv(p);
}
@ -960,16 +975,9 @@ public class ArenaImpl implements Arena {
}
try {
this.inventoryManager.removeOriginalItems(this.plugin, p);
final ItemStack[] itemStacks = p.getInventory().getContents().clone();
step.undo();
if (this.keepDrops) {
for (ItemStack itemStack : itemStacks) {
if (itemStack == null) continue;
p.getInventory().addItem(itemStack);
}
}
} catch (Exception e) {
e.printStackTrace();
plugin.getLogger().log(Level.SEVERE, () -> "Failed to revert player " + p.getName());
}
}

View File

@ -0,0 +1,34 @@
package com.garbagemule.MobArena.steps;
import org.bukkit.entity.Player;
public class CompositeStep extends PlayerStep {
private final Step original;
private final Step next;
private CompositeStep(Player player, Step original, Step next) {
super(player);
this.original = original;
this.next = next;
}
@Override
public void run() {
this.original.run();
this.next.run();
}
@Override
public void undo() {
this.original.undo();
this.next.undo();
}
public static StepFactory create(Step original, Step next) {
return player -> new CompositeStep(player, original, next);
}
}

View File

@ -0,0 +1,71 @@
package com.garbagemule.MobArena.steps;
import com.garbagemule.MobArena.framework.Arena;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.logging.Level;
public class KeepDropsStep extends PlayerStep {
private final File keepDrops;
private final Arena arena;
private ItemStack[] contents;
private File backup;
private KeepDropsStep(Player player, Arena arena) {
super(player);
this.keepDrops = new File(arena.getPlugin().getDataFolder(), "extra-drops");
this.arena = arena;
}
@Override
public void run() {
contents = player.getInventory().getContents();
createBackup();
player.getInventory().clear();
}
@Override
public void undo() {
for (ItemStack itemStack : contents) {
if (itemStack == null) continue;
player.getInventory().addItem(itemStack);
}
arena.getInventoryManager().removeKeepDrops(player);
deleteBackup();
}
private void createBackup() {
arena.getInventoryManager().removeOriginalItems(arena.getPlugin(), player);
YamlConfiguration yaml = new YamlConfiguration();
yaml.set("contents", contents);
backup = new File(keepDrops, player.getUniqueId().toString());
try {
yaml.save(backup);
} catch (IOException e) {
throw new RuntimeException("Failed to store keep-drops for " + player.getName(), e);
}
arena.getInventoryManager().putKeepDrops(player, contents);
}
private void deleteBackup() {
try {
Files.delete(backup.toPath());
} catch (IOException e) {
arena.getPlugin().getLogger().log(Level.WARNING, "Couldn't delete backup inventory file for " + player.getName(), e);
}
}
public static StepFactory create(Arena arena) {
return player -> new KeepDropsStep(player, arena);
}
}

View File

@ -13,9 +13,7 @@ import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataType;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
@ -24,15 +22,25 @@ public class InventoryManager
private static final String ORIGINAL_ITEM_KEY = "original-item";
private Map<Player, ItemStack[]> inventories;
private Map<Player, ItemStack[]> keepDrops;
public InventoryManager() {
this.inventories = new HashMap<>();
this.keepDrops = new HashMap<>();
}
public void put(Player p, ItemStack[] contents) {
inventories.put(p, contents);
}
public void putKeepDrops(Player p, ItemStack[] contents) {
keepDrops.put(p, contents);
}
public ItemStack[] getKeepDrops(Player p) {
return keepDrops.get(p);
}
public void equip(Player p) {
ItemStack[] contents = inventories.get(p);
if (contents == null) {
@ -75,6 +83,10 @@ public class InventoryManager
inventories.remove(p);
}
public void removeKeepDrops(Player p) {
keepDrops.remove(p);
}
/**
* Clear a player's inventory completely.
* @param p a player
@ -120,6 +132,8 @@ public class InventoryManager
File inventories = new File(plugin.getDataFolder(), "inventories");
File file = new File(inventories, p.getUniqueId().toString());
restoreKeepDrops(plugin, p);
if (!file.exists()) {
return false;
}
@ -137,4 +151,25 @@ public class InventoryManager
return false;
}
}
private static void restoreKeepDrops(MobArena plugin, Player p) {
try {
File inventories = new File(plugin.getDataFolder(), "keep-drops");
File file = new File(inventories, p.getUniqueId().toString());
if (!file.exists()) {
return;
}
YamlConfiguration config = new YamlConfiguration();
config.load(file);
ItemStack[] contents = config.getList("extra-drops").toArray(new ItemStack[0]);
p.getInventory().addItem(contents);
file.delete();
} catch (Exception e) {
plugin.getLogger().log(Level.SEVERE, "Failed to restore extra drops for " + p.getName(), e);
}
}
}

View File

@ -3,7 +3,8 @@ author: garbagemule
main: com.garbagemule.MobArena.MobArena
version: '${project.version}'
api-version: 1.13
softdepend: [Multiverse-Core,Towny,Heroes,MagicSpells,Vault]
softdepend: [Multiverse-Core,Towny,Heroes,MagicSpells,Vault,AdvancedEnchantments]
loadbefore: [AdvancedEnchantments]
commands:
ma:
description: Base command for MobArena