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> </properties>
<repositories> <repositories>
<repository>
<id>mcstats</id>
<url>https://repo.mcstats.org/content/repositories/releases/</url>
</repository>
<repository> <repository>
<id>spigotmc-repo</id> <id>spigotmc-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url> <url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
@ -45,8 +40,6 @@
<id>sytm-nexus</id> <id>sytm-nexus</id>
<url>https://repo.sytm.de/repository/maven-hosted/</url> <url>https://repo.sytm.de/repository/maven-hosted/</url>
</repository> </repository>
</repositories> </repositories>
<dependencies> <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.Permissions;
import com.jamesdpeters.minecraft.chests.misc.Utils; import com.jamesdpeters.minecraft.chests.misc.Utils;
import com.jamesdpeters.minecraft.chests.serialize.InventoryStorage; import com.jamesdpeters.minecraft.chests.serialize.InventoryStorage;
import com.jamesdpeters.minecraft.chests.sort.SortMethod;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.block.Block; import org.bukkit.block.Block;
@ -13,6 +14,7 @@ import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import javax.swing.*;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; 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!"), MENU("/chestlink menu","Open the ChestLink menu to display all groups!"),
OPEN("/chestlink open <Group>","Open the inventory of a ChestLink group"), 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!"), 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."); RENAME("/chestlink rename <group> <new-name>","Rename a ChestLink."),
//SORT("/chestlink sort <group> <sort-method>","Set the sorting option for the given 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; String description, commandHelp;
@ -61,6 +64,7 @@ public class RemoteChestCommand extends ServerCommand {
sender.sendMessage("Only a player can use this command"); sender.sendMessage("Only a player can use this command");
return false; return false;
} }
Player player = (Player) sender; Player player = (Player) sender;
if(args != null && args.length > 0) { if(args != null && args.length > 0) {
switch (OPTIONS.valueOf(args[0].toUpperCase())){ switch (OPTIONS.valueOf(args[0].toUpperCase())){
@ -75,6 +79,10 @@ public class RemoteChestCommand extends ServerCommand {
if(args.length > 1){ if(args.length > 1){
if(sender.hasPermission(Permissions.ADD)) { if(sender.hasPermission(Permissions.ADD)) {
Block targetBlock = player.getTargetBlockExact(5); 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]); if (targetBlock != null) Utils.createChestLink(player, targetBlock, args[1]);
else Messages.MUST_LOOK_AT_CHEST(player); else Messages.MUST_LOOK_AT_CHEST(player);
return true; return true;
@ -90,8 +98,13 @@ public class RemoteChestCommand extends ServerCommand {
case OPEN: case OPEN:
if(args.length > 1){ if(args.length > 1){
if(sender.hasPermission(Permissions.OPEN)) { if(sender.hasPermission(Permissions.OPEN)) {
InventoryStorage invs = Config.getInventoryStorage(player.getUniqueId(), args[1]); InventoryStorage invs;
Utils.openInventory(player, invs.getInventory()); 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; return true;
} else { } else {
Messages.NO_PERMISSION(player); Messages.NO_PERMISSION(player);
@ -127,24 +140,24 @@ public class RemoteChestCommand extends ServerCommand {
player.sendMessage(ChatColor.RED+OPTIONS.REMOVE.description); player.sendMessage(ChatColor.RED+OPTIONS.REMOVE.description);
return true; return true;
} }
// case SORT: case SORT:
// if(args.length > 1) { if(args.length > 1) {
// if (sender.hasPermission(Permissions.REMOVE)) { if (sender.hasPermission(Permissions.REMOVE)) {
// InventoryStorage storage = Config.getInventoryStorage(player.getUniqueId(),args[1]); InventoryStorage storage = Config.getInventoryStorage(player.getUniqueId(),args[1]);
// if(storage != null) { if(storage != null) {
// storage.setSortMethod(Enum.valueOf(InventoryStorage.SORT_METHOD.class, args[2])); storage.setSortMethod(Enum.valueOf(SortMethod.class, args[2]));
// storage.sort(); storage.sort();
// } }
// return true; return true;
// } else { } else {
// Messages.NO_PERMISSION(player); Messages.NO_PERMISSION(player);
// return true; return true;
// } }
// } else { } else {
// player.sendMessage(ChatColor.RED+OPTIONS.SORT.commandHelp); player.sendMessage(ChatColor.RED+OPTIONS.SORT.commandHelp);
// player.sendMessage(ChatColor.RED+OPTIONS.SORT.description); player.sendMessage(ChatColor.RED+OPTIONS.SORT.description);
// return true; return true;
// } }
case MEMBER: case MEMBER:
if(args.length > 3){ if(args.length > 3){
if(sender.hasPermission(Permissions.MEMBER)){ if(sender.hasPermission(Permissions.MEMBER)){
@ -185,28 +198,33 @@ public class RemoteChestCommand extends ServerCommand {
player.sendMessage(ChatColor.RED+OPTIONS.MEMBER.description); player.sendMessage(ChatColor.RED+OPTIONS.MEMBER.description);
return true; return true;
} }
case SETPUBLIC: case SETPUBLIC: {
if(args.length > 2){ if (args.length > 2) {
InventoryStorage storage = Config.getInventoryStorage(player.getUniqueId(), args[1]); InventoryStorage storage = Config.getInventoryStorage(player.getUniqueId(), args[1]);
if(storage != null){ if (storage != null) {
boolean setpublic = Boolean.parseBoolean(args[2]); boolean setpublic = Boolean.parseBoolean(args[2]);
storage.setPublic(setpublic); storage.setPublic(setpublic);
Messages.SET_PUBLIC(player,storage); Messages.SET_PUBLIC(player, storage);
return true; return true;
} else { } else {
Bukkit.broadcastMessage("Storage null"); Bukkit.broadcastMessage("Storage null");
} }
} else { } else {
player.sendMessage(ChatColor.RED+OPTIONS.SETPUBLIC.commandHelp); player.sendMessage(ChatColor.RED + OPTIONS.SETPUBLIC.commandHelp);
player.sendMessage(ChatColor.RED+OPTIONS.SETPUBLIC.description); player.sendMessage(ChatColor.RED + OPTIONS.SETPUBLIC.description);
return true; 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; return false;
} }
@ -223,16 +241,14 @@ public class RemoteChestCommand extends ServerCommand {
try { try {
switch (OPTIONS.valueOf(args[0].toUpperCase())) { switch (OPTIONS.valueOf(args[0].toUpperCase())) {
case ADD: case ADD:
return null;
case OPEN: case OPEN:
return Utils.getInvetoryStorageOpenableList(player);
case REMOVE: case REMOVE:
//case SORT: case SORT:
case RENAME:
return Utils.getInventoryStorageList(player); return Utils.getInventoryStorageList(player);
case MEMBER: case MEMBER:
return Arrays.asList("add","remove","list"); return Arrays.asList("add","remove","list");
// case ADDMEMBER:
// case REMOVEMEMBER:
// return new ArrayList<>(Config.getPlayer(player.getUniqueId()).keySet());
} }
} catch (IllegalArgumentException ignored) { } } catch (IllegalArgumentException ignored) { }
} }
@ -241,12 +257,8 @@ public class RemoteChestCommand extends ServerCommand {
switch (OPTIONS.valueOf(args[0].toUpperCase())) { switch (OPTIONS.valueOf(args[0].toUpperCase())) {
case MEMBER: case MEMBER:
return Utils.getInventoryStorageList(player); return Utils.getInventoryStorageList(player);
// case SORT: case SORT:
// return InventoryStorage.SORT_METHOD.valuesList; return SortMethod.valuesList;
// case ADDMEMBER:
// return Utils.getOnlinePlayers();
// case REMOVEMEMBER:
// return Utils.getPlayersAsNameList(Config.getInventoryStorage(player.getUniqueId(),args[1]).getMembers());
} }
} catch (IllegalArgumentException ignored) { } } catch (IllegalArgumentException ignored) { }
} }
@ -255,10 +267,6 @@ public class RemoteChestCommand extends ServerCommand {
switch (OPTIONS.valueOf(args[0].toUpperCase())) { switch (OPTIONS.valueOf(args[0].toUpperCase())) {
case MEMBER: case MEMBER:
return Utils.getOnlinePlayers(); return Utils.getOnlinePlayers();
// case ADDMEMBER:
// return Utils.getOnlinePlayers();
// case REMOVEMEMBER:
// return Utils.getPlayersAsNameList(Config.getInventoryStorage(player.getUniqueId(),args[1]).getMembers());
} }
} catch (IllegalArgumentException ignored) { } } 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.misc.Config;
import com.jamesdpeters.minecraft.chests.serialize.InventoryStorage; import com.jamesdpeters.minecraft.chests.serialize.InventoryStorage;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.util.UUID; import java.util.UUID;
@ -11,7 +12,7 @@ public class ChestLinkInfo {
private String group; private String group;
private UUID playerUUID; private UUID playerUUID;
private Player player; private OfflinePlayer player;
private InventoryStorage storage; private InventoryStorage storage;
public ChestLinkInfo(String playerUUID, String group){ public ChestLinkInfo(String playerUUID, String group){
@ -21,7 +22,7 @@ public class ChestLinkInfo {
public ChestLinkInfo(UUID playerUUID, String group){ public ChestLinkInfo(UUID playerUUID, String group){
this.group = group; this.group = group;
this.storage = Config.getInventoryStorage(playerUUID,group); this.storage = Config.getInventoryStorage(playerUUID,group);
this.player = Bukkit.getOfflinePlayer(playerUUID).getPlayer(); this.player = Bukkit.getOfflinePlayer(playerUUID);
this.playerUUID = playerUUID; this.playerUUID = playerUUID;
} }
@ -33,7 +34,7 @@ public class ChestLinkInfo {
return playerUUID; return playerUUID;
} }
public Player getPlayer() { public OfflinePlayer getPlayer() {
return player; return player;
} }

View File

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

View File

@ -33,12 +33,12 @@ public class ChestLinkListener implements Listener {
if (info != null) { if (info != null) {
if(event.getPlayer().hasPermission(Permissions.ADD)) { if(event.getPlayer().hasPermission(Permissions.ADD)) {
if (Utils.isValidSignPosition(event.getBlockAgainst().getLocation())) { if (Utils.isValidSignPosition(event.getBlockAgainst().getLocation())) {
Config.addChest(info.getPlayer(), info.getGroup(), event.getBlockAgainst().getLocation()); Config.addChest(event.getPlayer(), info.getGroup(), event.getBlockAgainst().getLocation(),info.getPlayer());
Messages.CHEST_ADDED(event.getPlayer(), info.getGroup(), event.getPlayer().getDisplayName()); Messages.CHEST_ADDED(event.getPlayer(), info.getGroup(), info.getPlayer().getName());
setLine(sign, signChangeEvent, 0, ChatColor.RED + ChatColor.stripColor(signChangeEvent.getLine(0))); 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, 1, ChatColor.GREEN + ChatColor.stripColor(signChangeEvent.getLine(1)));
setLine(sign, signChangeEvent, 2, ChatColor.BOLD + ChatColor.stripColor(event.getPlayer().getDisplayName())); setLine(sign, signChangeEvent, 2, ChatColor.BOLD + ChatColor.stripColor(info.getPlayer().getName()));
sign.getPersistentDataContainer().set(Values.playerUUID, PersistentDataType.STRING, event.getPlayer().getUniqueId().toString()); sign.getPersistentDataContainer().set(Values.playerUUID, PersistentDataType.STRING, info.getPlayer().getUniqueId().toString());
sign.update(); sign.update();
} else { } else {
Messages.SIGN_FRONT_OF_CHEST(event.getPlayer()); 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 block sign is placed on is a chest we can remove it.
if(chest.getState() instanceof Chest) { if(chest.getState() instanceof Chest) {
ChestLinkInfo info = Utils.getChestLinkInfo(sign,sign.getLines());
ChestLinkInfo info = Utils.getChestLinkInfo(sign,null);
if (info != null) { ; if (info != null) { ;
Config.removeChest(info.getPlayer(), info.getGroup(), chest.getLocation()); Config.removeChest(info.getPlayer(), info.getGroup(), chest.getLocation());
((Chest) chest.getState()).getInventory().clear(); ((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){ if(event.getBlock().getState() instanceof Chest){
InventoryStorage storage = Config.removeChest(event.getBlock().getLocation()); InventoryStorage storage = Config.removeChest(event.getBlock().getLocation());
if(storage != null){ 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) { if (event.getInventory().getLocation() != null) {
InventoryStorage storage = Config.getInventoryStorage(event.getInventory().getLocation()); InventoryStorage storage = Config.getInventoryStorage(event.getInventory().getLocation());
if (storage != null) { if (storage != null) {
event.setCancelled(true); event.setCancelled(true);
if (event.getPlayer().hasPermission(Permissions.OPEN) && storage.hasPermission((Player) event.getPlayer())) { if (event.getPlayer().hasPermission(Permissions.OPEN) && storage.hasPermission((Player) event.getPlayer())) {
Utils.openInventory((Player) event.getPlayer(), storage.getInventory()); 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.containers.ChestLinkInfo;
import com.jamesdpeters.minecraft.chests.serialize.InventoryStorage; import com.jamesdpeters.minecraft.chests.serialize.InventoryStorage;
import com.jamesdpeters.minecraft.chests.serialize.LinkedChest; import com.jamesdpeters.minecraft.chests.serialize.LinkedChest;
import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.OfflinePlayer;
import org.bukkit.Sound;
import org.bukkit.block.*; import org.bukkit.block.*;
import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.configuration.file.YamlConfiguration;
@ -14,10 +17,11 @@ import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.*; import java.util.*;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
public class Config { public class Config {
static LinkedChest store; private static LinkedChest store;
public Config(){ public Config(){
try { 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){ public static HashMap<String, InventoryStorage> getInventoryStorageMap(UUID playerUUID){
String id = playerUUID.toString(); String id = playerUUID.toString();
if(store.chests.containsKey(id)){ if(store.chests.containsKey(id)){
@ -70,13 +83,13 @@ public class Config {
return null; 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. //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. //Get Inventory Storage for the given group or create it if it doesnt exist.
if(!map.containsKey(identifier)){ if(!map.containsKey(identifier)){
InventoryStorage storage = new InventoryStorage(player,identifier,chestLocation); InventoryStorage storage = new InventoryStorage(owner,identifier,chestLocation);
map.put(identifier, storage); map.put(identifier, storage);
} }
InventoryStorage inventoryStorage = map.get(identifier); InventoryStorage inventoryStorage = map.get(identifier);
@ -101,6 +114,7 @@ public class Config {
if(!inventoryStorage.getLocations().contains(chestLocation)){ if(!inventoryStorage.getLocations().contains(chestLocation)){
inventoryStorage.getLocations().add(chestLocation); inventoryStorage.getLocations().add(chestLocation);
} }
player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP,1.0f,1f);
save(); save();
} }
@ -136,8 +150,8 @@ public class Config {
save(); save();
} }
public static InventoryStorage removeChest(Player player, String identifier, Location chestLocation){ public static InventoryStorage removeChest(OfflinePlayer owner, String identifier, Location chestLocation){
return removeChest(getInventoryStorageMap(player.getUniqueId()).get(identifier),chestLocation); return removeChest(getInventoryStorageMap(owner.getUniqueId()).get(identifier),chestLocation);
} }
public static InventoryStorage removeChest(Location chestLocation){ public static InventoryStorage removeChest(Location chestLocation){
@ -162,4 +176,35 @@ public class Config {
return total.get(); 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.containers.ChestLinkInfo;
import com.jamesdpeters.minecraft.chests.runnables.ChestLinkVerifier; import com.jamesdpeters.minecraft.chests.runnables.ChestLinkVerifier;
import com.jamesdpeters.minecraft.chests.serialize.InventoryStorage; import com.jamesdpeters.minecraft.chests.serialize.InventoryStorage;
import com.jamesdpeters.minecraft.chests.sort.InventorySorter;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.bukkit.*; import org.bukkit.*;
import org.bukkit.block.*; import org.bukkit.block.*;
@ -25,19 +26,6 @@ import java.util.stream.Collectors;
public class Utils { 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){ return getChestLinkInfo(sign,sign.getLines());}
public static ChestLinkInfo getChestLinkInfo(Sign sign, String[] lines){ public static ChestLinkInfo getChestLinkInfo(Sign sign, String[] lines){
@ -49,7 +37,16 @@ public class Utils {
if (lines.length >= 2 && lines[0].contains(Values.signTag)) { if (lines.length >= 2 && lines[0].contains(Values.signTag)) {
String playerUUID = sign.getPersistentDataContainer().get(Values.playerUUID, PersistentDataType.STRING); String playerUUID = sign.getPersistentDataContainer().get(Values.playerUUID, PersistentDataType.STRING);
String group = ChatColor.stripColor(StringUtils.substringBetween(lines[1], "[", "]")); 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); 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); toReplace.setType(Material.OAK_WALL_SIGN);
Sign sign = (Sign) toReplace.getState(); Sign sign = (Sign) toReplace.getState();
WallSign signBlockData = (WallSign) sign.getBlockData(); WallSign signBlockData = (WallSign) sign.getBlockData();
signBlockData.setFacing(facing); signBlockData.setFacing(facing);
sign.setBlockData(signBlockData); sign.setBlockData(signBlockData);
sign.getPersistentDataContainer().set(Values.playerUUID, PersistentDataType.STRING, player.getUniqueId().toString()); sign.getPersistentDataContainer().set(Values.playerUUID, PersistentDataType.STRING, uuid);
sign.update(); 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); BlockPlaceEvent event = new BlockPlaceEvent(sign.getBlock(),replacedBlockState,block,new ItemStack(Material.AIR),player,true, EquipmentSlot.HAND);
ChestsPlusPlus.PLUGIN.getServer().getPluginManager().callEvent(event); ChestsPlusPlus.PLUGIN.getServer().getPluginManager().callEvent(event);
if(event.isCancelled()){ if(event.isCancelled()){
@ -270,4 +288,16 @@ public class Utils {
public static List<String> getInventoryStorageList(Player player){ public static List<String> getInventoryStorageList(Player player){
return Config.getInventoryStorageMap(player.getUniqueId()).values().stream().map(InventoryStorage::getIdentifier).collect(Collectors.toList()); 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; 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.Config;
import com.jamesdpeters.minecraft.chests.misc.Permissions; import com.jamesdpeters.minecraft.chests.misc.Permissions;
import com.jamesdpeters.minecraft.chests.misc.Utils; import com.jamesdpeters.minecraft.chests.misc.Utils;
import com.jamesdpeters.minecraft.chests.interfaces.VirtualInventoryHolder; import com.jamesdpeters.minecraft.chests.interfaces.VirtualInventoryHolder;
import com.jamesdpeters.minecraft.chests.runnables.VirtualChestToHopper; 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 fr.minuskube.inv.ClickableItem;
import org.bukkit.*; import org.bukkit.*;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.Chest; import org.bukkit.block.Chest;
import org.bukkit.block.Sign;
import org.bukkit.configuration.serialization.ConfigurationSerializable; import org.bukkit.configuration.serialization.ConfigurationSerializable;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.material.Directional;
import java.util.*; import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class InventoryStorage implements ConfigurationSerializable { public class InventoryStorage implements ConfigurationSerializable {
@ -30,22 +31,10 @@ public class InventoryStorage implements ConfigurationSerializable {
List<OfflinePlayer> bukkitMembers; List<OfflinePlayer> bukkitMembers;
String inventoryName = "Chest"; String inventoryName = "Chest";
VirtualChestToHopper chestToHopper; VirtualChestToHopper chestToHopper;
Player player; OfflinePlayer player;
UUID playerUUID; UUID playerUUID;
boolean isPublic; boolean isPublic;
SORT_METHOD sortMethod = SORT_METHOD.OFF; SortMethod sortMethod = SortMethod.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());
}
}
@Override @Override
public Map<String, Object> serialize() { public Map<String, Object> serialize() {
@ -73,10 +62,10 @@ public class InventoryStorage implements ConfigurationSerializable {
locationsList.removeAll(Collections.singletonList(null)); locationsList.removeAll(Collections.singletonList(null));
playerUUID = UUID.fromString((String) map.get("playerUUID")); 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("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){ if(map.get("members") != null){
@ -90,12 +79,12 @@ public class InventoryStorage implements ConfigurationSerializable {
init(); init();
} }
public InventoryStorage(Player player, String group, Location location){ public InventoryStorage(OfflinePlayer player, String group, Location location){
this.inventoryName = group; this.inventoryName = group;
this.player = player; this.player = player;
this.playerUUID = player.getUniqueId(); this.playerUUID = player.getUniqueId();
this.isPublic = false; this.isPublic = false;
this.sortMethod = SORT_METHOD.OFF; this.sortMethod = SortMethod.OFF;
locationsList = new ArrayList<>(Collections.singleton(location)); locationsList = new ArrayList<>(Collections.singleton(location));
Block block = location.getBlock(); Block block = location.getBlock();
@ -141,7 +130,7 @@ public class InventoryStorage implements ConfigurationSerializable {
return inventoryName; return inventoryName;
} }
public Player getOwner() { public OfflinePlayer getOwner() {
return player; return player;
} }
@ -150,7 +139,7 @@ public class InventoryStorage implements ConfigurationSerializable {
return inventoryName+": "+locationsList.toString(); return inventoryName+": "+locationsList.toString();
} }
public ItemStack getIventoryIcon(){ public ItemStack getIventoryIcon(Player player){
ItemStack toReturn = null; ItemStack toReturn = null;
for(ItemStack item : inventory.getContents()){ for(ItemStack item : inventory.getContents()){
if(item != null){ if(item != null){
@ -161,7 +150,10 @@ public class InventoryStorage implements ConfigurationSerializable {
ItemMeta meta = toReturn.getItemMeta(); ItemMeta meta = toReturn.getItemMeta();
if(meta != null) { 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) { if(getMembers() != null) {
List<String> memberNames = new ArrayList<>(); List<String> memberNames = new ArrayList<>();
if(isPublic) memberNames.add(ChatColor.WHITE+"Public Chest"); if(isPublic) memberNames.add(ChatColor.WHITE+"Public Chest");
@ -176,7 +168,7 @@ public class InventoryStorage implements ConfigurationSerializable {
} }
public ClickableItem getClickableItem(Player player) { public ClickableItem getClickableItem(Player player) {
return ClickableItem.from(getIventoryIcon(), event -> { return ClickableItem.from(getIventoryIcon(player), event -> {
Utils.openInventory(player,getInventory()); Utils.openInventory(player,getInventory());
}); });
} }
@ -217,6 +209,24 @@ public class InventoryStorage implements ConfigurationSerializable {
return false; 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(){ public List<OfflinePlayer> getMembers(){
return bukkitMembers; return bukkitMembers;
} }
@ -239,24 +249,11 @@ public class InventoryStorage implements ConfigurationSerializable {
return isPublic; return isPublic;
} }
public void setSortMethod(SORT_METHOD sortMethod){ public void setSortMethod(SortMethod sortMethod){
this.sortMethod = sortMethod; this.sortMethod = sortMethod;
} }
public void sort(){ public void sort(){
// switch (sortMethod){ InventorySorter.sort(inventory, 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);
// }
// }
} }
} }

View File

@ -4,10 +4,7 @@ import org.bukkit.Location;
import org.bukkit.configuration.serialization.ConfigurationSerializable; import org.bukkit.configuration.serialization.ConfigurationSerializable;
import org.bukkit.configuration.serialization.SerializableAs; import org.bukkit.configuration.serialization.SerializableAs;
import java.util.HashMap; import java.util.*;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@SerializableAs("LinkedChest") @SerializableAs("LinkedChest")
public class LinkedChest implements ConfigurationSerializable { public class LinkedChest implements ConfigurationSerializable {
@ -24,6 +21,13 @@ public class LinkedChest implements ConfigurationSerializable {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public LinkedChest(Map<String, Object> map){ public LinkedChest(Map<String, Object> map){
chests = (HashMap<String, HashMap<String, InventoryStorage>>) map.get("chests"); chests = (HashMap<String, HashMap<String, InventoryStorage>>) map.get("chests");
validate();
}
private void validate(){
chests.forEach((s, invMap) -> {
invMap.values().removeIf(Objects::isNull);
});
} }
public LinkedChest(){ 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 name: ChestsPlusPlus
version: 1.15 v1.3 version: 1.15 v1.3
main: com.jamesdpeters.minecraft.chests.ChestsPlusPlus main: com.jamesdpeters.minecraft.chests.ChestsPlusPlus
api-version: "1.15" api-version: "1.14"
commands: commands:
chestlink: chestlink: