Latest Update

Fixed wrong spigot api in pom
Added Inventory sorter
Added rename ability
Added ability to add/open chests you are a member of.
Menu now shows Chests you are a member of.
Chests.yml now gets validated when opened. i.e any objects that are null are removed.
API set back to 1.14 to work with that.
This commit is contained in:
jameslfc19 2020-04-26 20:50:08 +01:00
parent c4fa121c7e
commit ddeb1c0200
14 changed files with 334 additions and 138 deletions

View File

@ -16,11 +16,6 @@
</properties>
<repositories>
<repository>
<id>mcstats</id>
<url>https://repo.mcstats.org/content/repositories/releases/</url>
</repository>
<repository>
<id>spigotmc-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
@ -45,8 +40,6 @@
<id>sytm-nexus</id>
<url>https://repo.sytm.de/repository/maven-hosted/</url>
</repository>
</repositories>
<dependencies>

View File

@ -6,6 +6,7 @@ import com.jamesdpeters.minecraft.chests.misc.Messages;
import com.jamesdpeters.minecraft.chests.misc.Permissions;
import com.jamesdpeters.minecraft.chests.misc.Utils;
import com.jamesdpeters.minecraft.chests.serialize.InventoryStorage;
import com.jamesdpeters.minecraft.chests.sort.SortMethod;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.block.Block;
@ -13,6 +14,7 @@ import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import javax.swing.*;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@ -27,8 +29,9 @@ public class RemoteChestCommand extends ServerCommand {
MENU("/chestlink menu","Open the ChestLink menu to display all groups!"),
OPEN("/chestlink open <Group>","Open the inventory of a ChestLink group"),
REMOVE("/chestlink remove <Group>", "Delete a ChestLink and drop its inventory at your feet!"),
SETPUBLIC("/chestlink setpublic <group> <true/false>", "Set a ChestLink to be accessible by anyone.");
//SORT("/chestlink sort <group> <sort-method>","Set the sorting option for the given ChestLink.");
RENAME("/chestlink rename <group> <new-name>","Rename a ChestLink."),
SETPUBLIC("/chestlink setpublic <group> <true/false>", "Set a ChestLink to be accessible by anyone."),
SORT("/chestlink sort <group> <sort-method>","Set the sorting option for the given ChestLink.");
String description, commandHelp;
@ -61,6 +64,7 @@ public class RemoteChestCommand extends ServerCommand {
sender.sendMessage("Only a player can use this command");
return false;
}
Player player = (Player) sender;
if(args != null && args.length > 0) {
switch (OPTIONS.valueOf(args[0].toUpperCase())){
@ -75,6 +79,10 @@ public class RemoteChestCommand extends ServerCommand {
if(args.length > 1){
if(sender.hasPermission(Permissions.ADD)) {
Block targetBlock = player.getTargetBlockExact(5);
// if(!Utils.validateChestID(args[1])){
// Messages.INVALID_CHESTID(player);
// return true;
// }
if (targetBlock != null) Utils.createChestLink(player, targetBlock, args[1]);
else Messages.MUST_LOOK_AT_CHEST(player);
return true;
@ -90,8 +98,13 @@ public class RemoteChestCommand extends ServerCommand {
case OPEN:
if(args.length > 1){
if(sender.hasPermission(Permissions.OPEN)) {
InventoryStorage invs = Config.getInventoryStorage(player.getUniqueId(), args[1]);
Utils.openInventory(player, invs.getInventory());
InventoryStorage invs;
if(args[1].contains(":")){
invs = Config.getInventoryStorage(player,args[1]);
} else {
invs = Config.getInventoryStorage(player.getUniqueId(), args[1]);
}
if(invs != null) Utils.openInventory(player, invs.getInventory());
return true;
} else {
Messages.NO_PERMISSION(player);
@ -127,24 +140,24 @@ public class RemoteChestCommand extends ServerCommand {
player.sendMessage(ChatColor.RED+OPTIONS.REMOVE.description);
return true;
}
// case SORT:
// if(args.length > 1) {
// if (sender.hasPermission(Permissions.REMOVE)) {
// InventoryStorage storage = Config.getInventoryStorage(player.getUniqueId(),args[1]);
// if(storage != null) {
// storage.setSortMethod(Enum.valueOf(InventoryStorage.SORT_METHOD.class, args[2]));
// storage.sort();
// }
// return true;
// } else {
// Messages.NO_PERMISSION(player);
// return true;
// }
// } else {
// player.sendMessage(ChatColor.RED+OPTIONS.SORT.commandHelp);
// player.sendMessage(ChatColor.RED+OPTIONS.SORT.description);
// return true;
// }
case SORT:
if(args.length > 1) {
if (sender.hasPermission(Permissions.REMOVE)) {
InventoryStorage storage = Config.getInventoryStorage(player.getUniqueId(),args[1]);
if(storage != null) {
storage.setSortMethod(Enum.valueOf(SortMethod.class, args[2]));
storage.sort();
}
return true;
} else {
Messages.NO_PERMISSION(player);
return true;
}
} else {
player.sendMessage(ChatColor.RED+OPTIONS.SORT.commandHelp);
player.sendMessage(ChatColor.RED+OPTIONS.SORT.description);
return true;
}
case MEMBER:
if(args.length > 3){
if(sender.hasPermission(Permissions.MEMBER)){
@ -185,28 +198,33 @@ public class RemoteChestCommand extends ServerCommand {
player.sendMessage(ChatColor.RED+OPTIONS.MEMBER.description);
return true;
}
case SETPUBLIC:
if(args.length > 2){
case SETPUBLIC: {
if (args.length > 2) {
InventoryStorage storage = Config.getInventoryStorage(player.getUniqueId(), args[1]);
if(storage != null){
if (storage != null) {
boolean setpublic = Boolean.parseBoolean(args[2]);
storage.setPublic(setpublic);
Messages.SET_PUBLIC(player,storage);
Messages.SET_PUBLIC(player, storage);
return true;
} else {
Bukkit.broadcastMessage("Storage null");
}
} else {
player.sendMessage(ChatColor.RED+OPTIONS.SETPUBLIC.commandHelp);
player.sendMessage(ChatColor.RED+OPTIONS.SETPUBLIC.description);
player.sendMessage(ChatColor.RED + OPTIONS.SETPUBLIC.commandHelp);
player.sendMessage(ChatColor.RED + OPTIONS.SETPUBLIC.description);
return true;
}
}
case RENAME: {
if(args.length > 2){
String group = args[1];
String newIdentifier = args[2];
Config.renameInventoryStorage(player,group,newIdentifier);
return true;
}
}
}
}
else {
}
return false;
}
@ -223,16 +241,14 @@ public class RemoteChestCommand extends ServerCommand {
try {
switch (OPTIONS.valueOf(args[0].toUpperCase())) {
case ADD:
return null;
case OPEN:
return Utils.getInvetoryStorageOpenableList(player);
case REMOVE:
//case SORT:
case SORT:
case RENAME:
return Utils.getInventoryStorageList(player);
case MEMBER:
return Arrays.asList("add","remove","list");
// case ADDMEMBER:
// case REMOVEMEMBER:
// return new ArrayList<>(Config.getPlayer(player.getUniqueId()).keySet());
}
} catch (IllegalArgumentException ignored) { }
}
@ -241,12 +257,8 @@ public class RemoteChestCommand extends ServerCommand {
switch (OPTIONS.valueOf(args[0].toUpperCase())) {
case MEMBER:
return Utils.getInventoryStorageList(player);
// case SORT:
// return InventoryStorage.SORT_METHOD.valuesList;
// case ADDMEMBER:
// return Utils.getOnlinePlayers();
// case REMOVEMEMBER:
// return Utils.getPlayersAsNameList(Config.getInventoryStorage(player.getUniqueId(),args[1]).getMembers());
case SORT:
return SortMethod.valuesList;
}
} catch (IllegalArgumentException ignored) { }
}
@ -255,10 +267,6 @@ public class RemoteChestCommand extends ServerCommand {
switch (OPTIONS.valueOf(args[0].toUpperCase())) {
case MEMBER:
return Utils.getOnlinePlayers();
// case ADDMEMBER:
// return Utils.getOnlinePlayers();
// case REMOVEMEMBER:
// return Utils.getPlayersAsNameList(Config.getInventoryStorage(player.getUniqueId(),args[1]).getMembers());
}
} catch (IllegalArgumentException ignored) { }
}

View File

@ -3,6 +3,7 @@ package com.jamesdpeters.minecraft.chests.containers;
import com.jamesdpeters.minecraft.chests.misc.Config;
import com.jamesdpeters.minecraft.chests.serialize.InventoryStorage;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import java.util.UUID;
@ -11,7 +12,7 @@ public class ChestLinkInfo {
private String group;
private UUID playerUUID;
private Player player;
private OfflinePlayer player;
private InventoryStorage storage;
public ChestLinkInfo(String playerUUID, String group){
@ -21,7 +22,7 @@ public class ChestLinkInfo {
public ChestLinkInfo(UUID playerUUID, String group){
this.group = group;
this.storage = Config.getInventoryStorage(playerUUID,group);
this.player = Bukkit.getOfflinePlayer(playerUUID).getPlayer();
this.player = Bukkit.getOfflinePlayer(playerUUID);
this.playerUUID = playerUUID;
}
@ -33,7 +34,7 @@ public class ChestLinkInfo {
return playerUUID;
}
public Player getPlayer() {
public OfflinePlayer getPlayer() {
return player;
}

View File

@ -9,6 +9,7 @@ import fr.minuskube.inv.SmartInventory;
import fr.minuskube.inv.content.InventoryContents;
import fr.minuskube.inv.content.InventoryProvider;
import fr.minuskube.inv.content.Pagination;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
@ -56,6 +57,11 @@ public class ChestLinkMenu implements InventoryProvider {
ClickableItem item = storage.getClickableItem(player);
itemList.add(item);
}
List<InventoryStorage> memberOfStorage = Config.getInventoryStorageMemberOf(player);
for(InventoryStorage storage : memberOfStorage){
ClickableItem item = storage.getClickableItem(player);
itemList.add(item);
}
pagination.setItems(itemList.toArray(new ClickableItem[0]));
pagination.setItemsPerPage(54);

View File

@ -33,12 +33,12 @@ public class ChestLinkListener implements Listener {
if (info != null) {
if(event.getPlayer().hasPermission(Permissions.ADD)) {
if (Utils.isValidSignPosition(event.getBlockAgainst().getLocation())) {
Config.addChest(info.getPlayer(), info.getGroup(), event.getBlockAgainst().getLocation());
Messages.CHEST_ADDED(event.getPlayer(), info.getGroup(), event.getPlayer().getDisplayName());
Config.addChest(event.getPlayer(), info.getGroup(), event.getBlockAgainst().getLocation(),info.getPlayer());
Messages.CHEST_ADDED(event.getPlayer(), info.getGroup(), info.getPlayer().getName());
setLine(sign, signChangeEvent, 0, ChatColor.RED + ChatColor.stripColor(signChangeEvent.getLine(0)));
setLine(sign, signChangeEvent, 1, ChatColor.GREEN + ChatColor.stripColor(signChangeEvent.getLine(1)));
setLine(sign, signChangeEvent, 2, ChatColor.BOLD + ChatColor.stripColor(event.getPlayer().getDisplayName()));
sign.getPersistentDataContainer().set(Values.playerUUID, PersistentDataType.STRING, event.getPlayer().getUniqueId().toString());
setLine(sign, signChangeEvent, 2, ChatColor.BOLD + ChatColor.stripColor(info.getPlayer().getName()));
sign.getPersistentDataContainer().set(Values.playerUUID, PersistentDataType.STRING, info.getPlayer().getUniqueId().toString());
sign.update();
} else {
Messages.SIGN_FRONT_OF_CHEST(event.getPlayer());
@ -71,13 +71,11 @@ public class ChestLinkListener implements Listener {
//If block sign is placed on is a chest we can remove it.
if(chest.getState() instanceof Chest) {
ChestLinkInfo info = Utils.getChestLinkInfo(sign,null);
ChestLinkInfo info = Utils.getChestLinkInfo(sign,sign.getLines());
if (info != null) { ;
Config.removeChest(info.getPlayer(), info.getGroup(), chest.getLocation());
((Chest) chest.getState()).getInventory().clear();
Messages.CHEST_REMOVED(event.getPlayer(),info.getGroup(),info.getPlayer().getDisplayName());
Messages.CHEST_REMOVED(event.getPlayer(),info.getGroup(),info.getPlayer().getName());
}
}
}
@ -97,7 +95,7 @@ public class ChestLinkListener implements Listener {
if(event.getBlock().getState() instanceof Chest){
InventoryStorage storage = Config.removeChest(event.getBlock().getLocation());
if(storage != null){
Messages.CHEST_REMOVED(event.getPlayer(),storage.getIdentifier(),storage.getOwner().getDisplayName());
Messages.CHEST_REMOVED(event.getPlayer(),storage.getIdentifier(),storage.getOwner().getName());
}
}
}

View File

@ -32,7 +32,6 @@ public class InventoryListener implements Listener {
if (event.getInventory().getLocation() != null) {
InventoryStorage storage = Config.getInventoryStorage(event.getInventory().getLocation());
if (storage != null) {
event.setCancelled(true);
if (event.getPlayer().hasPermission(Permissions.OPEN) && storage.hasPermission((Player) event.getPlayer())) {
Utils.openInventory((Player) event.getPlayer(), storage.getInventory());

View File

@ -3,7 +3,10 @@ package com.jamesdpeters.minecraft.chests.misc;
import com.jamesdpeters.minecraft.chests.containers.ChestLinkInfo;
import com.jamesdpeters.minecraft.chests.serialize.InventoryStorage;
import com.jamesdpeters.minecraft.chests.serialize.LinkedChest;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.OfflinePlayer;
import org.bukkit.Sound;
import org.bukkit.block.*;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
@ -14,10 +17,11 @@ import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
public class Config {
static LinkedChest store;
private static LinkedChest store;
public Config(){
try {
@ -40,6 +44,15 @@ public class Config {
}
}
public static List<InventoryStorage> getInventoryStorageMemberOf(Player player){
return store.chests.entrySet().stream().flatMap(map -> map.getValue().values().stream().filter(storage -> {
if(storage.isPublic()) return false;
if(storage.getOwner().getUniqueId().equals(player.getUniqueId())) return false;
if(storage.getMembers() == null) return false;
return storage.getMembers().stream().anyMatch(p -> p.getUniqueId().equals(player.getUniqueId()));
})).collect(Collectors.toList());
}
public static HashMap<String, InventoryStorage> getInventoryStorageMap(UUID playerUUID){
String id = playerUUID.toString();
if(store.chests.containsKey(id)){
@ -70,13 +83,13 @@ public class Config {
return null;
}
public static void addChest(Player player, String identifier, Location chestLocation){
public static void addChest(Player player, String identifier, Location chestLocation, OfflinePlayer owner){
//List of groups this player has.
HashMap<String, InventoryStorage> map = getInventoryStorageMap(player.getUniqueId());
HashMap<String, InventoryStorage> map = getInventoryStorageMap(owner.getUniqueId());
//Get Inventory Storage for the given group or create it if it doesnt exist.
if(!map.containsKey(identifier)){
InventoryStorage storage = new InventoryStorage(player,identifier,chestLocation);
InventoryStorage storage = new InventoryStorage(owner,identifier,chestLocation);
map.put(identifier, storage);
}
InventoryStorage inventoryStorage = map.get(identifier);
@ -101,6 +114,7 @@ public class Config {
if(!inventoryStorage.getLocations().contains(chestLocation)){
inventoryStorage.getLocations().add(chestLocation);
}
player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP,1.0f,1f);
save();
}
@ -136,8 +150,8 @@ public class Config {
save();
}
public static InventoryStorage removeChest(Player player, String identifier, Location chestLocation){
return removeChest(getInventoryStorageMap(player.getUniqueId()).get(identifier),chestLocation);
public static InventoryStorage removeChest(OfflinePlayer owner, String identifier, Location chestLocation){
return removeChest(getInventoryStorageMap(owner.getUniqueId()).get(identifier),chestLocation);
}
public static InventoryStorage removeChest(Location chestLocation){
@ -162,4 +176,35 @@ public class Config {
return total.get();
}
public static InventoryStorage getInventoryStorage(Player member, String playerChestID){
if(playerChestID.contains(":")) {
String[] args = playerChestID.split(":");
String playerName = args[0];
String chestlinkID = args[1];
Optional<InventoryStorage> invStorage = getInventoryStorageMemberOf(member).stream().filter(storage -> {
if (storage.getOwner().getName().equals(playerName) && storage.getIdentifier().equals(chestlinkID)) return true;
return false;
}).findFirst();
if(invStorage.isPresent()) return invStorage.get();
}
return null;
}
public static OfflinePlayer getOfflinePlayer(String name){
for(String uuid : store.chests.keySet()){
OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(UUID.fromString(uuid));
if(offlinePlayer.getName() != null && offlinePlayer.getName().equals(name)) return offlinePlayer;
}
return null;
}
public static void renameInventoryStorage(Player player, String oldIdentifier, String newIdentifier){
HashMap<String,InventoryStorage> map = getInventoryStorageMap(player.getUniqueId());
InventoryStorage storage = map.get(oldIdentifier);
storage.rename(newIdentifier);
map.remove(oldIdentifier);
map.put(newIdentifier,storage);
save();
}
}

View File

@ -90,4 +90,9 @@ public class Messages {
}
}
}
public static void INVALID_CHESTID(Player target){
target.sendMessage(ChatColor.RED+"Invalid ChestLink ID! Must not contain a colon ':' unless you are referencing another players group that you are a member off");
target.sendMessage(ChatColor.RED+"/chestlink add <owner>:<group>");
}
}

View File

@ -4,6 +4,7 @@ import com.jamesdpeters.minecraft.chests.ChestsPlusPlus;
import com.jamesdpeters.minecraft.chests.containers.ChestLinkInfo;
import com.jamesdpeters.minecraft.chests.runnables.ChestLinkVerifier;
import com.jamesdpeters.minecraft.chests.serialize.InventoryStorage;
import com.jamesdpeters.minecraft.chests.sort.InventorySorter;
import org.apache.commons.lang.StringUtils;
import org.bukkit.*;
import org.bukkit.block.*;
@ -25,19 +26,6 @@ import java.util.stream.Collectors;
public class Utils {
// public static String[] getChestLinkInfo(String[] lines){
// if(lines.length < 2){
// return null;
// }
// if(lines[0].contains(Values.signTag)) {
// String id = StringUtils.substringBetween(lines[1], "[", "]");
// String username = ChatColor.stripColor(lines[2]);
// return new String[]{id,username};
// }
// return null;
// }
public static ChestLinkInfo getChestLinkInfo(Sign sign){ return getChestLinkInfo(sign,sign.getLines());}
public static ChestLinkInfo getChestLinkInfo(Sign sign, String[] lines){
@ -49,7 +37,16 @@ public class Utils {
if (lines.length >= 2 && lines[0].contains(Values.signTag)) {
String playerUUID = sign.getPersistentDataContainer().get(Values.playerUUID, PersistentDataType.STRING);
String group = ChatColor.stripColor(StringUtils.substringBetween(lines[1], "[", "]"));
if(playerUUID == null) playerUUID = uuid.toString();
if(playerUUID == null){
playerUUID = uuid.toString();
if(lines[2] != null){
OfflinePlayer owner = Config.getOfflinePlayer(lines[2]);
if(owner != null){
InventoryStorage storage = Config.getInventoryStorage(owner.getUniqueId(),group);
if(storage.hasPermission(Bukkit.getPlayer(uuid))) playerUUID = owner.getUniqueId().toString();
}
}
}
return new ChestLinkInfo(playerUUID, group);
}
}
@ -157,18 +154,39 @@ public class Utils {
}
}
String uuid, group, owner = null;
if(identifier.contains(":")){
String[] args = identifier.split(":");
owner = args[0];
group = args[1];
OfflinePlayer ownerPlayer = Config.getOfflinePlayer(owner);
if(ownerPlayer != null){
uuid = ownerPlayer.getUniqueId().toString();
} else {
Messages.INVALID_CHESTID(player);
return;
}
} else {
group = identifier;
uuid = player.getUniqueId().toString();
}
String[] lines = new String[4];
lines[0] = Values.signTag;
lines[1] = Values.identifier(group);
if(owner != null) {
lines[2] = owner;
}
toReplace.setType(Material.OAK_WALL_SIGN);
Sign sign = (Sign) toReplace.getState();
WallSign signBlockData = (WallSign) sign.getBlockData();
signBlockData.setFacing(facing);
sign.setBlockData(signBlockData);
sign.getPersistentDataContainer().set(Values.playerUUID, PersistentDataType.STRING, player.getUniqueId().toString());
sign.getPersistentDataContainer().set(Values.playerUUID, PersistentDataType.STRING, uuid);
sign.update();
String[] lines = new String[4];
lines[0] = Values.signTag;
lines[1] = Values.identifier(identifier);
BlockPlaceEvent event = new BlockPlaceEvent(sign.getBlock(),replacedBlockState,block,new ItemStack(Material.AIR),player,true, EquipmentSlot.HAND);
ChestsPlusPlus.PLUGIN.getServer().getPluginManager().callEvent(event);
if(event.isCancelled()){
@ -270,4 +288,16 @@ public class Utils {
public static List<String> getInventoryStorageList(Player player){
return Config.getInventoryStorageMap(player.getUniqueId()).values().stream().map(InventoryStorage::getIdentifier).collect(Collectors.toList());
}
public static List<String> getInvetoryStorageOpenableList(Player player){
List<String> playerList = getInventoryStorageList(player);
List<String> memberList = Config.getInventoryStorageMemberOf(player).stream().map(storage -> storage.getOwner().getName()+":"+storage.getIdentifier()).collect(Collectors.toList());
playerList.addAll(memberList);
return playerList;
}
public static boolean validateChestID(String id){
return !id.contains(":");
}
}

View File

@ -1,26 +1,27 @@
package com.jamesdpeters.minecraft.chests.serialize;
import com.jamesdpeters.minecraft.chests.commands.RemoteChestCommand;
import com.jamesdpeters.minecraft.chests.misc.Config;
import com.jamesdpeters.minecraft.chests.misc.Permissions;
import com.jamesdpeters.minecraft.chests.misc.Utils;
import com.jamesdpeters.minecraft.chests.interfaces.VirtualInventoryHolder;
import com.jamesdpeters.minecraft.chests.runnables.VirtualChestToHopper;
import com.jamesdpeters.minecraft.chests.sort.InventorySorter;
import com.jamesdpeters.minecraft.chests.sort.SortMethod;
import fr.minuskube.inv.ClickableItem;
import org.bukkit.*;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.Chest;
import org.bukkit.block.Sign;
import org.bukkit.configuration.serialization.ConfigurationSerializable;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.material.Directional;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class InventoryStorage implements ConfigurationSerializable {
@ -30,22 +31,10 @@ public class InventoryStorage implements ConfigurationSerializable {
List<OfflinePlayer> bukkitMembers;
String inventoryName = "Chest";
VirtualChestToHopper chestToHopper;
Player player;
OfflinePlayer player;
UUID playerUUID;
boolean isPublic;
SORT_METHOD sortMethod = SORT_METHOD.OFF;
public enum SORT_METHOD {
OFF,
ID,
AMOUNT;
public static List<String> valuesList;
static {
valuesList = Stream.of(SORT_METHOD.values()).map(SORT_METHOD::toString).collect(Collectors.toList());
}
}
SortMethod sortMethod = SortMethod.OFF;
@Override
public Map<String, Object> serialize() {
@ -73,10 +62,10 @@ public class InventoryStorage implements ConfigurationSerializable {
locationsList.removeAll(Collections.singletonList(null));
playerUUID = UUID.fromString((String) map.get("playerUUID"));
player = Bukkit.getOfflinePlayer(playerUUID).getPlayer();
player = Bukkit.getOfflinePlayer(playerUUID);
if(map.containsKey("isPublic")) isPublic = (boolean) map.get("isPublic");
if(map.containsKey("sortMethod")) sortMethod = Enum.valueOf(SORT_METHOD.class, (String) map.get("sortMethod"));
if(map.containsKey("sortMethod")) sortMethod = Enum.valueOf(SortMethod.class, (String) map.get("sortMethod"));
if(map.get("members") != null){
@ -90,12 +79,12 @@ public class InventoryStorage implements ConfigurationSerializable {
init();
}
public InventoryStorage(Player player, String group, Location location){
public InventoryStorage(OfflinePlayer player, String group, Location location){
this.inventoryName = group;
this.player = player;
this.playerUUID = player.getUniqueId();
this.isPublic = false;
this.sortMethod = SORT_METHOD.OFF;
this.sortMethod = SortMethod.OFF;
locationsList = new ArrayList<>(Collections.singleton(location));
Block block = location.getBlock();
@ -141,7 +130,7 @@ public class InventoryStorage implements ConfigurationSerializable {
return inventoryName;
}
public Player getOwner() {
public OfflinePlayer getOwner() {
return player;
}
@ -150,7 +139,7 @@ public class InventoryStorage implements ConfigurationSerializable {
return inventoryName+": "+locationsList.toString();
}
public ItemStack getIventoryIcon(){
public ItemStack getIventoryIcon(Player player){
ItemStack toReturn = null;
for(ItemStack item : inventory.getContents()){
if(item != null){
@ -161,7 +150,10 @@ public class InventoryStorage implements ConfigurationSerializable {
ItemMeta meta = toReturn.getItemMeta();
if(meta != null) {
meta.setDisplayName(ChatColor.BOLD + "" + ChatColor.GREEN + "" + getIdentifier() + ": " +ChatColor.WHITE+ ""+getTotalItems()+" items");
String dispName = ChatColor.GREEN + "" + getIdentifier() + ": " +ChatColor.WHITE+ ""+getTotalItems()+" items";
if(player.getUniqueId().equals(playerUUID)) meta.setDisplayName(dispName);
else meta.setDisplayName(getOwner().getName()+": "+dispName);
if(getMembers() != null) {
List<String> memberNames = new ArrayList<>();
if(isPublic) memberNames.add(ChatColor.WHITE+"Public Chest");
@ -176,7 +168,7 @@ public class InventoryStorage implements ConfigurationSerializable {
}
public ClickableItem getClickableItem(Player player) {
return ClickableItem.from(getIventoryIcon(), event -> {
return ClickableItem.from(getIventoryIcon(player), event -> {
Utils.openInventory(player,getInventory());
});
}
@ -217,6 +209,24 @@ public class InventoryStorage implements ConfigurationSerializable {
return false;
}
public void rename(String newIdentifier){
this.inventoryName = newIdentifier;
ItemStack[] items = inventory.getContents();
inventory = initInventory();
inventory.setContents(items);
locationsList.forEach(location -> {
Block block = location.getBlock();
if(block.getBlockData() instanceof org.bukkit.block.data.type.Chest) {
org.bukkit.block.data.type.Chest chest = (org.bukkit.block.data.type.Chest) block.getBlockData();
BlockFace blockFace = chest.getFacing();
Block signBlock = block.getRelative(blockFace);
Sign sign = (Sign) signBlock.getState();
sign.setLine(1,ChatColor.GREEN + ChatColor.stripColor("[" + newIdentifier + "]"));
sign.update();
}
});
}
public List<OfflinePlayer> getMembers(){
return bukkitMembers;
}
@ -239,24 +249,11 @@ public class InventoryStorage implements ConfigurationSerializable {
return isPublic;
}
public void setSortMethod(SORT_METHOD sortMethod){
public void setSortMethod(SortMethod sortMethod){
this.sortMethod = sortMethod;
}
public void sort(){
// switch (sortMethod){
// case OFF: return;
// case ID: {
// ItemStack[] sorted = inventory.getContents();
// Arrays.sort(sorted, (item1, item2) -> {
// if(item1 == null) return 1;
// if(item2 == null) return -1;
// else {
// return item1.getType().getKey().getKey().compareTo(item2.getType().getKey().getKey());
// }
// });
// inventory.setContents(sorted);
// }
// }
InventorySorter.sort(inventory, sortMethod);
}
}

View File

@ -4,10 +4,7 @@ import org.bukkit.Location;
import org.bukkit.configuration.serialization.ConfigurationSerializable;
import org.bukkit.configuration.serialization.SerializableAs;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
@SerializableAs("LinkedChest")
public class LinkedChest implements ConfigurationSerializable {
@ -24,6 +21,13 @@ public class LinkedChest implements ConfigurationSerializable {
@SuppressWarnings("unchecked")
public LinkedChest(Map<String, Object> map){
chests = (HashMap<String, HashMap<String, InventoryStorage>>) map.get("chests");
validate();
}
private void validate(){
chests.forEach((s, invMap) -> {
invMap.values().removeIf(Objects::isNull);
});
}
public LinkedChest(){

View File

@ -0,0 +1,92 @@
package com.jamesdpeters.minecraft.chests.sort;
import org.bukkit.Material;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class InventorySorter {
public static void sort(Inventory inventory, SortMethod sortMethod){
switch (sortMethod){
case OFF: return;
case NAME: {
List<ItemStack> condensed = condenseInventory(inventory.getContents());
condensed.sort((item1, item2) -> {
if (item1 == null) return 1;
if (item2 == null) return -1;
else {
return item1.getType().name().compareTo(item2.getType().name());
}
});
ItemStack[] itemStacks = condensed.toArray(new ItemStack[0]);
inventory.setContents(itemStacks);
return;
}
case AMOUNT_DESC: {
sortByAmount(inventory,true);
return;
}
case AMOUNT_ASC: {
sortByAmount(inventory,false);
}
}
}
private static void sortByAmount(Inventory inventory, boolean descending){
HashMap<Material,Integer> itemAmounts = getItemAmounts(inventory.getContents());
List<ItemStack> condensed = condenseInventory(inventory.getContents());
condensed.sort((item1, item2) -> {
if (item1 == null) return 1;
if (item2 == null) return -1;
int itemOrder = itemAmounts.get(item1.getType()).compareTo(itemAmounts.get(item2.getType()));
if(descending) itemOrder *= -1;
return itemOrder;
});
ItemStack[] itemStacks = condensed.toArray(new ItemStack[0]);
inventory.setContents(itemStacks);
}
private static HashMap<Material,Integer> getItemAmounts(ItemStack[] itemStacks){
HashMap<Material,Integer> itemAmounts = new HashMap<>();
for(ItemStack itemStack : itemStacks){
if(itemStack == null) continue;
int amount;
if(!itemAmounts.containsKey(itemStack.getType())){
amount = itemStack.getAmount();
} else {
amount = itemAmounts.get(itemStack.getType()) + itemStack.getAmount();
}
itemAmounts.put(itemStack.getType(),amount);
}
return itemAmounts;
}
private static List<ItemStack> condenseInventory(ItemStack[] itemStacks){
HashMap<Material,Integer> itemAmounts = getItemAmounts(itemStacks);
return condenseInventory(itemAmounts);
}
private static List<ItemStack> condenseInventory(HashMap<Material,Integer> itemAmounts){
List<ItemStack> condensedItems = new ArrayList<>();
itemAmounts.forEach((material, amount) -> {
int maxStack = material.getMaxStackSize();
int amountOfMaxStacks = amount/maxStack;
int remainder = amount % maxStack;
for(int i=0; i<amountOfMaxStacks; i++){
condensedItems.add(new ItemStack(material,maxStack));
}
if(remainder != 0) condensedItems.add(new ItemStack(material,remainder));
});
return condensedItems;
}
}

View File

@ -0,0 +1,18 @@
package com.jamesdpeters.minecraft.chests.sort;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public enum SortMethod {
OFF,
NAME,
AMOUNT_DESC,
AMOUNT_ASC;
public static List<String> valuesList;
static {
valuesList = Stream.of(SortMethod.values()).map(SortMethod::toString).collect(Collectors.toList());
}
}

View File

@ -1,7 +1,7 @@
name: ChestsPlusPlus
version: 1.15 v1.3
main: com.jamesdpeters.minecraft.chests.ChestsPlusPlus
api-version: "1.15"
api-version: "1.14"
commands:
chestlink: