Init Commit!

This commit is contained in:
jameslfc19 2019-09-16 19:22:50 +01:00
commit f89ecdd13c
29 changed files with 1682 additions and 0 deletions

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
Server/
target/
*.log

2
.idea/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
# Default ignored files
/workspace.xml

13
.idea/compiler.xml Normal file
View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<annotationProcessing>
<profile name="Maven default annotation processors profile" enabled="true">
<sourceOutputDir name="target/generated-sources/annotations" />
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
<outputRelativeToContentRoot value="true" />
<module name="ChestsPlusPlus" />
</profile>
</annotationProcessing>
</component>
</project>

14
.idea/misc.xml Normal file
View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/pom.xml" />
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

124
.idea/uiDesigner.xml Normal file
View File

@ -0,0 +1,124 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Palette2">
<group name="Swing">
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
</item>
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
</item>
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true">
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
</item>
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
<initial-values>
<property name="text" value="Button" />
</initial-values>
</item>
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="RadioButton" />
</initial-values>
</item>
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="CheckBox" />
</initial-values>
</item>
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
<initial-values>
<property name="text" value="Label" />
</initial-values>
</item>
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
</item>
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
</item>
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
<preferred-size width="-1" height="20" />
</default-constraints>
</item>
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
</item>
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
</item>
</group>
</component>
</project>

6
.idea/vcs.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

2
ChestsPlusPlus.iml Normal file
View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4" />

94
pom.xml Normal file
View File

@ -0,0 +1,94 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.jamesdpeters.chests</groupId>
<artifactId>ChestsPlusPlus</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<repositories>
<repository>
<id>spigotmc-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
</repository>
<repository>
<id>ossrh</id>
<url>https://oss.sonatype.org/content/groups/public/</url>
</repository>
<repository>
<id>dmulloy2-repo</id>
<url>http://repo.dmulloy2.net/nexus/repository/public/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.14.4-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.4</version>
</dependency>
<dependency>
<groupId>com.comphenix.protocol</groupId>
<artifactId>ProtocolLib</artifactId>
<version>4.4.0</version>
</dependency>
</dependencies>
<!--Tell maven how to prepare and build our jar file from our source and dependancies-->
<build>
<!--Tell maven what plugins we want to add and what they should do-->
<plugins>
<!--Tell maven the id and version of the 'shade' plugin's jar file so it can download it from a repository-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.1.0</version>
<executions>
<!--Tell the shade plugin when it should be run during a maven build-->
<execution>
<!--Tell the shade plugin to run once during the 'package' phase of a maven build-->
<phase>package</phase>
<!--Tell the shade plugin which of it's goals to attempt to run during this phase-->
<goals>
<goal>shade</goal>
</goals>
<!--Tell the shade plugin which of it's goals to attempt to run during this phase-->
<configuration>
<!--Tell the shade plugin where to put our jar file-->
<outputFile>${project.basedir}/Server/plugins/${project.artifactId}.jar</outputFile>
<minimizeJar>true</minimizeJar>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
<!--Tell maven to enable resource filtering so we can use macros like '${project.version}' inside of our plugin.yml-->
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
</project>

View File

@ -0,0 +1,39 @@
package com.jamesdpeters.minecraft.chests;
import com.jamesdpeters.minecraft.chests.commands.RemoteChestCommand;
import com.jamesdpeters.minecraft.chests.listeners.ChestLinkListener;
import com.jamesdpeters.minecraft.chests.listeners.HopperListener;
import com.jamesdpeters.minecraft.chests.listeners.InventoryListener;
import com.jamesdpeters.minecraft.chests.serialize.InventoryStorage;
import com.jamesdpeters.minecraft.chests.serialize.LinkedChest;
import org.bukkit.configuration.serialization.ConfigurationSerialization;
import org.bukkit.plugin.java.JavaPlugin;
public class ChestsPlusPlus extends JavaPlugin {
public static JavaPlugin PLUGIN;
static {
ConfigurationSerialization.registerClass(LinkedChest.class, "LinkedChest");
ConfigurationSerialization.registerClass(InventoryStorage.class, "InventoryStorage");
}
@Override
public void onEnable() {
PLUGIN = this;
new RemoteChestCommand().register(this);
getServer().getPluginManager().registerEvents(new ChestLinkListener(),this);
getServer().getPluginManager().registerEvents(new InventoryListener(),this);
getServer().getPluginManager().registerEvents(new HopperListener(),this);
new Config();
getLogger().info("Chests++ enabled!");
}
@Override
public void onDisable() {
super.onDisable();
Config.save();
}
}

View File

@ -0,0 +1,139 @@
package com.jamesdpeters.minecraft.chests;
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.ChatColor;
import org.bukkit.Location;
import org.bukkit.block.*;
import org.bukkit.configuration.file.FileConfiguration;
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.util.*;
public class Config {
static LinkedChest store;
public Config(){
try {
FileConfiguration configuration = YamlConfiguration.loadConfiguration(new File("chests.yml"));
store = (LinkedChest) configuration.get("chests++", new HashMap<String, HashMap<String, List<Location>>>());
} catch (Exception e){
store = new LinkedChest();
save();
}
}
public static void save(){
FileConfiguration config = new YamlConfiguration();
config.set("chests++", store);
try {
config.save("chests.yml");
} catch (IOException e) {
e.printStackTrace();
}
}
public static HashMap<String, InventoryStorage> getPlayer(Player player){
String id = player.getUniqueId().toString();
if(store.chests.containsKey(id)){
return store.chests.get(id);
} else {
HashMap<String, InventoryStorage> hashMap = new HashMap<>();
store.chests.put(id, hashMap);
return hashMap;
}
}
public static InventoryStorage getInventoryStorage(Player player, String identifier){
HashMap<String, InventoryStorage> map = getPlayer(player);
return map.getOrDefault(identifier, null);
}
public static InventoryStorage getInventoryStorage(Location location){
if(location != null) {
Block block = location.getBlock();
if (block.getState() instanceof Chest) {
Chest chest = (Chest) block.getState();
ChestLinkInfo info = Utils.getChestLinkInfo(chest.getLocation());
if(info != null){
return info.getStorage();
}
}
}
return null;
}
public static void addChest(Player player, String identifier, Location chestLocation){
//List of groups this player has.
HashMap<String, InventoryStorage> map = getPlayer(player);
//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);
map.put(identifier, storage);
}
InventoryStorage inventoryStorage = map.get(identifier);
//Migrates that chest into InventoryStorage and if full drops it at the chest location.
Chest chest = (Chest) chestLocation.getBlock().getState();
boolean hasOverflow = false;
for(ItemStack chestItem : chest.getInventory().getContents()) {
if(chestItem != null) {
HashMap<Integer, ItemStack> overflow = inventoryStorage.getInventory().addItem(chestItem);
for (ItemStack item : overflow.values())
if (item != null){
player.getWorld().dropItemNaturally(chestLocation, item);
hasOverflow = true;
}
}
}
if(hasOverflow) Messages.CHEST_HAD_OVERFLOW(player);
chest.getInventory().clear();
//If the location isn't already part of the system add it.
if(!inventoryStorage.getLocations().contains(chestLocation)){
inventoryStorage.getLocations().add(chestLocation);
}
save();
}
public static InventoryStorage removeChest(InventoryStorage storage, Location location){
if(storage != null) {
storage.getLocations().remove(location);
if (storage.getLocations().size() == 0) {
storage.dropInventory(location);
getPlayer(storage.getOwner()).remove(storage.getIdentifier());
}
save();
return storage;
}
return null;
}
public static InventoryStorage removeChest(Player player, String identifier, Location chestLocation){
return removeChest(getPlayer(player).get(identifier),chestLocation);
}
public static InventoryStorage removeChest(Location chestLocation){
InventoryStorage storage = getInventoryStorage(chestLocation);
return removeChest(storage,chestLocation);
}
public static boolean setChests(Player player, String group, InventoryStorage storage){
HashMap<String, InventoryStorage> groups = getPlayer(player);
groups.put(group,storage);
save();
return true;
}
}

View File

@ -0,0 +1,27 @@
package com.jamesdpeters.minecraft.chests;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
public class Messages {
public static void CHEST_REMOVED(Player target, String group, String player){
target.sendMessage(ChatColor.RED+"Succesfully removed a chest from group: "+group+" for "+player);
}
public static void CHEST_ADDED(Player target, String group, String player){
target.sendMessage(ChatColor.GREEN+"Succesfully added a chest to group: "+group+" for "+player);
}
public static void CHEST_HAD_OVERFLOW(Player target){
target.sendMessage(ChatColor.GOLD+"Chest item's wouldn't all fit into ChestLink!");
}
public static void MUST_LOOK_AT_CHEST(Player target){
target.sendMessage(ChatColor.RED+"You must be looking at the chest you want to ChestLink!");
}
public static void MUST_HOLD_SIGN(Player target){
target.sendMessage(ChatColor.RED+"You must be hold a sign to do that!");
}
}

View File

@ -0,0 +1,213 @@
package com.jamesdpeters.minecraft.chests;
import com.jamesdpeters.minecraft.chests.containers.ChestLinkInfo;
import com.jamesdpeters.minecraft.chests.runnables.ChestLinkVerifier;
import org.apache.commons.lang.StringUtils;
import org.bukkit.*;
import org.bukkit.block.*;
import org.bukkit.block.data.Directional;
import org.bukkit.block.data.type.WallSign;
import org.bukkit.entity.Entity;
import org.bukkit.entity.ItemFrame;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.block.SignChangeEvent;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.persistence.PersistentDataType;
import java.util.*;
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(Location location){
return getChestLinkInfo(location,null);
}
public static ChestLinkInfo getChestLinkInfo(Sign sign, Player player){ return getChestLinkInfo(sign,sign.getLines(),player);}
public static ChestLinkInfo getChestLinkInfo(Sign sign, String[] lines, Player player){
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){
return new ChestLinkInfo(playerUUID, group);
}
else if(player != null) return new ChestLinkInfo(player, group);
}
return null;
}
/**
* Returns ChestLinkInfo for a sign.
* @param location - Location of ChestLink to find.
* @param player - Player that ChestLink belongs to if it doesn't already exist.
* @return @{@link ChestLinkInfo}
*/
public static ChestLinkInfo getChestLinkInfo(Location location, Player player){
Block block = location.getBlock();
if(block.getBlockData() instanceof Directional) {
Directional chest = (Directional) block.getBlockData();
BlockFace facing = chest.getFacing();
Block sign = block.getRelative(facing);
if (sign.getState() instanceof Sign) {
Sign s = (Sign) sign.getState();
return getChestLinkInfo(s,player);
}
}
return null;
}
public static String locationPrettyPrint(Location location){
return "["+location.getX()+","+location.getY()+","+location.getZ()+"] in "+location.getWorld().getName();
}
public static void openInventory(Player player, Inventory inventory){
if(inventory.getLocation() != null) player.getWorld().playSound(inventory.getLocation(), Sound.BLOCK_CHEST_OPEN,0.5f,1f);
else player.getWorld().playSound(player.getLocation(), Sound.BLOCK_CHEST_OPEN,0.5f,1f);
player.openInventory(inventory);
}
public static void closeInventorySound(Player player, Inventory inventory){
if(inventory.getLocation() != null) player.getWorld().playSound(inventory.getLocation(), Sound.BLOCK_CHEST_CLOSE,0.5f,1f);
else player.getWorld().playSound(player.getLocation(), Sound.BLOCK_CHEST_CLOSE,0.5f,1f);
//player.closeInventory();
}
public static ItemStack removeStackFromInventory(Inventory inventory, int amount, List<ItemStack> filters){
ItemStack toRemove;
for(int i=0; i<inventory.getContents().length; i++){
ItemStack stack = inventory.getItem(i);
if((stack != null) && (isInFilter(filters,stack))){
toRemove = stack.clone();
toRemove.setAmount(Math.min(stack.getAmount(),amount));
stack.setAmount(stack.getAmount()-toRemove.getAmount());
return toRemove;
}
}
return null;
}
public static boolean moveToOtherInventory(Inventory from, int amount, Inventory to, List<ItemStack> filters){
ItemStack removed = removeStackFromInventory(from,amount,filters);
if(removed != null) {
HashMap<Integer, ItemStack> leftOvers = to.addItem(removed);
for (ItemStack leftOver : leftOvers.values()) {
from.addItem(leftOver);
}
return true;
}
return false;
}
public static boolean moveToOtherInventory(Inventory from, int amount, Inventory to) {
return moveToOtherInventory(from,amount,to,null);
}
public static void createChestLink(Player player, Block block, String identifier){
if(block.getState() instanceof Chest){
new ChestLinkVerifier(block).withDelay(0).check();
if(block.getBlockData() instanceof Directional) {
Directional chest = (Directional) block.getBlockData();
BlockFace facing = chest.getFacing();
Block toReplace = block.getRelative(facing);
if(toReplace.getType() == Material.AIR){
BlockState replacedBlockState = toReplace.getState();
if(player.getGameMode() == GameMode.SURVIVAL) {
if (player.getEquipment() != null) {
if (!Tag.SIGNS.isTagged(player.getEquipment().getItemInMainHand().getType())) {
Messages.MUST_HOLD_SIGN(player);
return;
}
player.getEquipment().getItemInMainHand().setAmount(player.getEquipment().getItemInMainHand().getAmount() - 1);
} else {
Messages.MUST_HOLD_SIGN(player);
return;
}
}
toReplace.setType(Material.OAK_WALL_SIGN);
Sign sign = (Sign) toReplace.getState();
WallSign signBlockData = (WallSign) sign.getBlockData();
signBlockData.setFacing(facing);
sign.setBlockData(signBlockData);
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()){
sign.setType(Material.AIR);
return;
}
SignChangeEvent signChangeEvent = new SignChangeEvent(sign.getBlock(),player,lines);
ChestsPlusPlus.PLUGIN.getServer().getPluginManager().callEvent(signChangeEvent);
}
}
}
}
public static List<ItemStack> hasFilter(Block block){
List<ItemStack> filters = new ArrayList<>();
addIfNotNull(filters,getFilter(block,1,0));
addIfNotNull(filters,getFilter(block,-1,0));
addIfNotNull(filters,getFilter(block,0,1));
addIfNotNull(filters,getFilter(block,0,-1));
return filters;
}
private static ItemStack getFilter(Block block, int xOffset, int zOffset){
Block frame = block.getRelative(xOffset, 0,zOffset);
if(frame.getState() instanceof ItemFrame){
return ((ItemFrame) frame.getState()).getItem();
}
return null;
}
private static <T> void addIfNotNull(List<T> list, T element){
if(element != null) list.add(element);
}
public static boolean isInFilter(List<ItemStack> filters, ItemStack item){
if(filters == null) return true;
if(filters.size() == 0) return true;
for(ItemStack filter : filters){
if(filter.isSimilar(item)) return true;
}
return false;
}
public static List<ItemStack> getHopperFilters(Block block){
Collection<Entity> ent = block.getLocation().getWorld().getNearbyEntities(block.getLocation(),1.01,1.01,1.01);
List<ItemStack> filters = new ArrayList<>();
for(Entity frame : ent){
if(frame instanceof ItemFrame){
Block attachedBlock = frame.getLocation().getBlock().getRelative(((ItemFrame) frame).getAttachedFace());
if(block.equals(attachedBlock)){
filters.add(((ItemFrame) frame).getItem());
}
}
}
return filters;
}
}

View File

@ -0,0 +1,12 @@
package com.jamesdpeters.minecraft.chests;
import org.bukkit.NamespacedKey;
public class Values {
public final static String signTag = "[ChestLink]";
public static String identifier(String identifier){
return "["+identifier+"]";
}
public final static NamespacedKey playerUUID = new NamespacedKey(ChestsPlusPlus.PLUGIN,"playerUUID");
}

View File

@ -0,0 +1,7 @@
package com.jamesdpeters.minecraft.chests.commands;
public class CommandListener {
}

View File

@ -0,0 +1,126 @@
package com.jamesdpeters.minecraft.chests.commands;
import com.jamesdpeters.minecraft.chests.ChestsPlusPlus;
import com.jamesdpeters.minecraft.chests.Config;
import com.jamesdpeters.minecraft.chests.Messages;
import com.jamesdpeters.minecraft.chests.Utils;
import com.jamesdpeters.minecraft.chests.serialize.InventoryStorage;
import org.apache.commons.lang.StringUtils;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.block.Chest;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabCompleter;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerChatTabCompleteEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class RemoteChestCommand extends ServerCommand {
private enum OPTIONS {
ADD("/chestlink add <Group>", "Create/add a chest to a ChestLink group"),
OPEN("/chestlink open <Group>","Open the inventory of a ChestLink group");
String description, commandHelp;
static List<String> valuesList;
static {
valuesList = Stream.of(OPTIONS.values()).map(OPTIONS::toString).collect(Collectors.toList());
}
OPTIONS( String commandHelp, String description){
this.commandHelp = commandHelp;
this.description = description;
}
@Override
public String toString() {
return super.toString().toLowerCase();
}
String getCommandHelp(){
return commandHelp;
}
String getDescription(){
return description;
}
}
@Override
public String getCommandName() {
return "chestlink";
}
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if(!(sender instanceof Player)){
sender.sendMessage("Only a player can use this command");
return false;
}
Player player = (Player) sender;
if(args != null) {
switch (OPTIONS.valueOf(args[0].toUpperCase())){
case ADD:
if(args.length > 1){
Block targetBlock = player.getTargetBlockExact(5);
if(targetBlock != null) Utils.createChestLink(player,targetBlock,args[1]);
else Messages.MUST_LOOK_AT_CHEST(player);
return true;
} else {
player.sendMessage(ChatColor.RED+OPTIONS.ADD.commandHelp);
player.sendMessage(ChatColor.RED+OPTIONS.ADD.description);
return true;
}
case OPEN:
if(args.length > 1){
InventoryStorage invs = Config.getInventoryStorage(player,args[1]);
Utils.openInventory(player,invs.getInventory());
return true;
} else {
player.sendMessage(ChatColor.RED+OPTIONS.OPEN.commandHelp);
player.sendMessage(ChatColor.RED+OPTIONS.OPEN.description);
return true;
}
}
}
return false;
}
@Override
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
if((sender instanceof Player)) {
Player player = (Player) sender;
if (args.length == 1) {
return OPTIONS.valuesList;
}
try {
switch (OPTIONS.valueOf(args[0].toUpperCase())) {
case ADD:
return null;
case OPEN:
return new ArrayList<>(Config.getPlayer(player).keySet());
}
} catch (IllegalArgumentException e){
}
}
return null;
}
}

View File

@ -0,0 +1,19 @@
package com.jamesdpeters.minecraft.chests.commands;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.TabCompleter;
import org.bukkit.plugin.java.JavaPlugin;
public abstract class ServerCommand implements CommandExecutor, TabCompleter {
/**
* @param plugin Registers command to given plugin.
*/
public void register(JavaPlugin plugin){
plugin.getCommand(getCommandName()).setExecutor(this);
plugin.getCommand(getCommandName()).setTabCompleter(this);
}
public abstract String getCommandName();
}

View File

@ -0,0 +1,43 @@
package com.jamesdpeters.minecraft.chests.containers;
import com.jamesdpeters.minecraft.chests.Config;
import com.jamesdpeters.minecraft.chests.serialize.InventoryStorage;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import java.util.UUID;
public class ChestLinkInfo {
private String group;
private UUID playerUUID;
private Player player;
private InventoryStorage storage;
public ChestLinkInfo(String playerUUID, String group){
this(Bukkit.getOfflinePlayer(UUID.fromString(playerUUID)).getPlayer(),group);
}
public ChestLinkInfo(Player player, String group){
this.group = group;
this.storage = Config.getInventoryStorage(player,group);
this.player = player;
this.playerUUID = player.getUniqueId();
}
public String getGroup() {
return group;
}
public UUID getPlayerUUID() {
return playerUUID;
}
public Player getPlayer() {
return player;
}
public InventoryStorage getStorage() {
return storage;
}
}

View File

@ -0,0 +1,23 @@
package com.jamesdpeters.minecraft.chests.interfaces;
import com.jamesdpeters.minecraft.chests.serialize.InventoryStorage;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
public class VirtualInventoryHolder implements InventoryHolder {
InventoryStorage storage;
public VirtualInventoryHolder(InventoryStorage storage){
this.storage = storage;
}
@Override
public Inventory getInventory() {
return storage.getInventory();
}
public InventoryStorage getStorage(){
return storage;
}
}

View File

@ -0,0 +1,105 @@
package com.jamesdpeters.minecraft.chests.listeners;
import com.jamesdpeters.minecraft.chests.*;
import com.jamesdpeters.minecraft.chests.containers.ChestLinkInfo;
import com.jamesdpeters.minecraft.chests.runnables.ChestLinkVerifier;
import com.jamesdpeters.minecraft.chests.serialize.InventoryStorage;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.NamespacedKey;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.Chest;
import org.bukkit.block.Sign;
import org.bukkit.block.data.Directional;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.block.SignChangeEvent;
import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.persistence.PersistentDataType;
import java.util.Arrays;
public class ChestLinkListener implements Listener {
@EventHandler
public void playerInteract(BlockPlaceEvent event){
if(event.getBlockPlaced().getState() instanceof Sign){
if(event.getBlockAgainst().getState() instanceof Chest) {
new TempListener(){
@EventHandler
public void onSignChange(SignChangeEvent signChangeEvent){
if(event.getBlockPlaced().getLocation().equals(signChangeEvent.getBlock().getLocation())) {
Sign sign = (Sign) signChangeEvent.getBlock().getState();
ChestLinkInfo info = Utils.getChestLinkInfo(sign, signChangeEvent.getLines(), signChangeEvent.getPlayer());
if (info != null) {
Config.addChest(info.getPlayer(), info.getGroup(), event.getBlockAgainst().getLocation());
Messages.CHEST_ADDED(event.getPlayer(), info.getGroup(), event.getPlayer().getDisplayName());
setLine(sign,signChangeEvent,0, ChatColor.RED + signChangeEvent.getLine(0));
setLine(sign,signChangeEvent,1, ChatColor.GREEN + signChangeEvent.getLine(1));
setLine(sign,signChangeEvent,2, ChatColor.BOLD + event.getPlayer().getDisplayName());
sign.getPersistentDataContainer().set(Values.playerUUID, PersistentDataType.STRING, event.getPlayer().getUniqueId().toString());
sign.update();
}
done();
}
}
};
}
}
}
@EventHandler
public void onSignBreak(BlockBreakEvent event){
if(event.getBlock().getState() instanceof Sign) {
Sign sign = (Sign) event.getBlock().getState();
//Get blockface of sign.
if(sign.getBlockData() instanceof Directional) {
BlockFace chestFace = ((Directional) sign.getBlockData()).getFacing().getOppositeFace();
Block chest = sign.getBlock().getRelative(chestFace);
//If block sign is placed on is a chest we can remove it.
if(chest.getState() instanceof Chest) {
ChestLinkInfo info = Utils.getChestLinkInfo(sign,null);
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());
}
}
}
}
}
@EventHandler
public void onChestPlace(BlockPlaceEvent event){
if(event.getBlockPlaced().getState() instanceof Chest){
new ChestLinkVerifier(event.getBlock()).check();
}
}
@EventHandler(priority = EventPriority.HIGHEST)
public void onChestBreak(BlockBreakEvent event){
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());
}
}
}
private void setLine(Sign sign, SignChangeEvent signChangeEvent, int i, String s){
sign.setLine(i,s);
signChangeEvent.setLine(i,s);
}
}

View File

@ -0,0 +1,85 @@
package com.jamesdpeters.minecraft.chests.listeners;
import com.jamesdpeters.minecraft.chests.ChestsPlusPlus;
import com.jamesdpeters.minecraft.chests.Config;
import com.jamesdpeters.minecraft.chests.Utils;
import com.jamesdpeters.minecraft.chests.serialize.InventoryStorage;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.Hopper;
import org.bukkit.entity.Entity;
import org.bukkit.entity.ItemFrame;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryMoveItemEvent;
import org.bukkit.event.inventory.InventoryPickupItemEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.scheduler.BukkitRunnable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import static com.jamesdpeters.minecraft.chests.Utils.hasFilter;
public class HopperListener implements Listener {
@EventHandler(priority = EventPriority.HIGHEST)
public void onHopperMoveEvent(InventoryMoveItemEvent event) {
//TO HOPPER
if(event.getDestination().getHolder() instanceof Hopper){
event.setCancelled(!isItemInFilter(event.getDestination().getLocation().getBlock(),event.getItem()));
}
}
@EventHandler(priority = EventPriority.HIGH)
public void fromHopper(InventoryMoveItemEvent event){
//FROM HOPPER
if (event.getInitiator().getHolder() instanceof Hopper) {
InventoryStorage storage = Config.getInventoryStorage(event.getDestination().getLocation());
if (storage != null) {
if(!event.isCancelled()) {
event.setCancelled(true);
new BukkitRunnable() {
@Override
public void run() {
Utils.moveToOtherInventory(event.getSource(), 1, storage.getInventory());
event.getDestination().getHolder().getInventory().clear();
}
}.runTaskLater(ChestsPlusPlus.PLUGIN, 1);
}
}
}
}
@EventHandler
public void onHopperPickup(InventoryPickupItemEvent event){
if(event.getInventory().getHolder() instanceof Hopper){
event.setCancelled(!isItemInFilter(event.getInventory().getLocation().getBlock(),event.getItem().getItemStack()));
}
}
public static boolean isItemInFilter(Block block, ItemStack item){
Collection<Entity> ent = block.getLocation().getWorld().getNearbyEntities(block.getLocation(),1.01,1.01,1.01);
boolean hasFilter = false;
for(Entity frame : ent){
if(frame instanceof ItemFrame){
Block attachedBlock = frame.getLocation().getBlock().getRelative(((ItemFrame) frame).getAttachedFace());
if(block.equals(attachedBlock)){
if(((ItemFrame) frame).getItem().getType() != Material.AIR) hasFilter = true;
if(item.isSimilar(((ItemFrame) frame).getItem())){
return true;
}
}
}
}
if(!hasFilter) return true;
return false;
}
}

View File

@ -0,0 +1,61 @@
package com.jamesdpeters.minecraft.chests.listeners;
import com.comphenix.protocol.wrappers.BlockPosition;
import com.jamesdpeters.minecraft.chests.Config;
import com.jamesdpeters.minecraft.chests.Utils;
import com.jamesdpeters.minecraft.chests.interfaces.VirtualInventoryHolder;
import com.jamesdpeters.minecraft.chests.protocollib.WrapperPlayServerBlockAction;
import com.jamesdpeters.minecraft.chests.serialize.InventoryStorage;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.event.inventory.InventoryOpenEvent;
public class InventoryListener implements Listener {
@EventHandler(priority = EventPriority.LOWEST)
public void onInventoryPlayerUpdate(InventoryClickEvent event){
if(event.getInventory().getHolder() instanceof VirtualInventoryHolder){
Config.save();
}
}
@EventHandler
public void onInventoryOpen(InventoryOpenEvent event){
if(event.getInventory().getLocation() != null){
InventoryStorage storage = Config.getInventoryStorage(event.getInventory().getLocation());
if(storage != null){
event.setCancelled(true);
Location chestLocation = event.getInventory().getLocation();
BlockPosition blockPosition = new BlockPosition((int) chestLocation.getX(),(int)chestLocation.getY(),(int)chestLocation.getZ());
WrapperPlayServerBlockAction packet = new WrapperPlayServerBlockAction();
packet.setLocation(blockPosition);
packet.setBlockType(event.getInventory().getLocation().getBlock().getType());
packet.setByte1(1);
packet.setByte2(1);
packet.broadcastPacket();
packet.sendPacket((Player) event.getPlayer());
Utils.openInventory((Player) event.getPlayer(),storage.getInventory());
}
}
}
@EventHandler
public void onInventoryClose(InventoryCloseEvent event){
if(event.getInventory().getLocation() == null){
Utils.closeInventorySound((Player) event.getPlayer(),event.getInventory());
}
if(event.getInventory().getHolder() instanceof VirtualInventoryHolder){
Config.save();
}
}
}

View File

@ -0,0 +1,23 @@
package com.jamesdpeters.minecraft.chests.listeners;
import com.jamesdpeters.minecraft.chests.ChestsPlusPlus;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.plugin.Plugin;
public class TempListener implements Listener {
public TempListener(){
this(ChestsPlusPlus.PLUGIN);
}
public TempListener(Plugin plugin){
plugin.getServer().getPluginManager().registerEvents(this,plugin);
}
public void done(){
HandlerList.unregisterAll(this);
}
}

View File

@ -0,0 +1,115 @@
package com.jamesdpeters.minecraft.chests.protocollib;
/**
* PacketWrapper - ProtocolLib wrappers for Minecraft packets
* Copyright (C) dmulloy2 <http://dmulloy2.net>
* Copyright (C) Kristian S. Strangeland
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import java.lang.reflect.InvocationTargetException;
import org.bukkit.entity.Player;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.events.PacketContainer;
import com.google.common.base.Objects;
public abstract class AbstractPacket {
// The packet we will be modifying
protected PacketContainer handle;
/**
* Constructs a new strongly typed wrapper for the given packet.
*
* @param handle - handle to the raw packet data.
* @param type - the packet type.
*/
protected AbstractPacket(PacketContainer handle, PacketType type) {
// Make sure we're given a valid packet
if (handle == null)
throw new IllegalArgumentException("Packet handle cannot be NULL.");
if (!Objects.equal(handle.getType(), type))
throw new IllegalArgumentException(handle.getHandle()
+ " is not a packet of type " + type);
this.handle = handle;
}
/**
* Retrieve a handle to the raw packet data.
*
* @return Raw packet data.
*/
public PacketContainer getHandle() {
return handle;
}
/**
* Send the current packet to the given receiver.
*
* @param receiver - the receiver.
* @throws RuntimeException If the packet cannot be sent.
*/
public void sendPacket(Player receiver) {
try {
ProtocolLibrary.getProtocolManager().sendServerPacket(receiver,
getHandle());
} catch (InvocationTargetException e) {
throw new RuntimeException("Cannot send packet.", e);
}
}
/**
* Send the current packet to all online players.
*/
public void broadcastPacket() {
ProtocolLibrary.getProtocolManager().broadcastServerPacket(getHandle());
}
/**
* Simulate receiving the current packet from the given sender.
*
* @param sender - the sender.
* @throws RuntimeException If the packet cannot be received.
* @deprecated Misspelled. recieve to receive
* @see #receivePacket(Player)
*/
@Deprecated
public void recievePacket(Player sender) {
try {
ProtocolLibrary.getProtocolManager().recieveClientPacket(sender,
getHandle());
} catch (Exception e) {
throw new RuntimeException("Cannot recieve packet.", e);
}
}
/**
* Simulate receiving the current packet from the given sender.
*
* @param sender - the sender.
* @throws RuntimeException if the packet cannot be received.
*/
public void receivePacket(Player sender) {
try {
ProtocolLibrary.getProtocolManager().recieveClientPacket(sender,
getHandle());
} catch (Exception e) {
throw new RuntimeException("Cannot receive packet.", e);
}
}
}

View File

@ -0,0 +1,120 @@
package com.jamesdpeters.minecraft.chests.protocollib;
/**
* PacketWrapper - ProtocolLib wrappers for Minecraft packets
* Copyright (C) dmulloy2 <http://dmulloy2.net>
* Copyright (C) Kristian S. Strangeland
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import org.bukkit.Material;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.wrappers.BlockPosition;
public class WrapperPlayServerBlockAction extends AbstractPacket {
public static final PacketType TYPE = PacketType.Play.Server.BLOCK_ACTION;
public WrapperPlayServerBlockAction() {
super(new PacketContainer(TYPE), TYPE);
handle.getModifier().writeDefaults();
}
public WrapperPlayServerBlockAction(PacketContainer packet) {
super(packet, TYPE);
}
/**
* Retrieve Location.
* <p>
* Notes: block Coordinates
*
* @return The current Location
*/
public BlockPosition getLocation() {
return handle.getBlockPositionModifier().read(0);
}
/**
* Set Location.
*
* @param value - new value.
*/
public void setLocation(BlockPosition value) {
handle.getBlockPositionModifier().write(0, value);
}
/**
* Retrieve Byte 1.
* <p>
* Notes: varies depending on block - see Block_Actions
*
* @return The current Byte 1
*/
public int getByte1() {
return handle.getIntegers().read(0);
}
/**
* Set Byte 1.
*
* @param value - new value.
*/
public void setByte1(int value) {
handle.getIntegers().write(0, value);
}
/**
* Retrieve Byte 2.
* <p>
* Notes: varies depending on block - see Block_Actions
*
* @return The current Byte 2
*/
public int getByte2() {
return handle.getIntegers().read(1);
}
/**
* Set Byte 2.
*
* @param value - new value.
*/
public void setByte2(int value) {
handle.getIntegers().write(1, value);
}
/**
* Retrieve Block Type.
* <p>
* Notes: the block type for the block
*
* @return The current Block Type
*/
public Material getBlockType() {
return handle.getBlocks().read(0);
}
/**
* Set Block Type.
*
* @param value - new value.
*/
public void setBlockType(Material value) {
handle.getBlocks().write(0, value);
}
}

View File

@ -0,0 +1,66 @@
package com.jamesdpeters.minecraft.chests.runnables;
import com.jamesdpeters.minecraft.chests.ChestsPlusPlus;
import com.jamesdpeters.minecraft.chests.Config;
import com.jamesdpeters.minecraft.chests.serialize.InventoryStorage;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.block.Chest;
import org.bukkit.block.DoubleChest;
import org.bukkit.inventory.Inventory;
import org.bukkit.scheduler.BukkitRunnable;
public class ChestLinkVerifier extends BukkitRunnable {
private Block block;
private int delay = 1;
public ChestLinkVerifier(Block block){
this.block = block;
}
public void check(){
runTaskLater(ChestsPlusPlus.PLUGIN,delay);
}
public ChestLinkVerifier withDelay(int delay){
this.delay = delay;
return this;
}
@Override
public void run() {
Chest chest = (Chest) block.getState();
if(chest.getInventory().getHolder() instanceof DoubleChest) {
DoubleChest doubleChest = (DoubleChest) chest.getInventory().getHolder();
if(isChestLinked(doubleChest)) {
convertToSingleChest(doubleChest.getRightSide().getInventory());
convertToSingleChest(doubleChest.getLeftSide().getInventory());
convertToSingleChest(doubleChest.getRightSide().getInventory());
}
}
}
public void convertToSingleChest(Inventory inventory){
if(inventory != null) {
org.bukkit.block.data.type.Chest blockData = (org.bukkit.block.data.type.Chest) inventory.getLocation().getBlock().getBlockData();
blockData.setType(org.bukkit.block.data.type.Chest.Type.SINGLE);
inventory.getLocation().getBlock().setBlockData(blockData);
}
}
public boolean isChestLinked(DoubleChest chest){
Location chestSide1 = block.getLocation();
Location diff = chest.getLocation().clone().subtract(chestSide1).multiply(2);
Location chestSide2 = chestSide1.clone().add(diff);
InventoryStorage leftStorage = Config.getInventoryStorage(chestSide1);
InventoryStorage rightStorage = Config.getInventoryStorage(chestSide2);
if((leftStorage != null) || (rightStorage != null)){
return true;
}
return false;
}
}

View File

@ -0,0 +1,43 @@
package com.jamesdpeters.minecraft.chests.runnables;
import com.jamesdpeters.minecraft.chests.ChestsPlusPlus;
import com.jamesdpeters.minecraft.chests.Utils;
import com.jamesdpeters.minecraft.chests.interfaces.VirtualInventoryHolder;
import com.jamesdpeters.minecraft.chests.serialize.InventoryStorage;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.block.Hopper;
import org.bukkit.inventory.Inventory;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.scheduler.BukkitTask;
import java.util.List;
public class VirtualChestToHopper extends BukkitRunnable {
InventoryStorage storage;
BukkitTask task;
public VirtualChestToHopper(InventoryStorage storage){
this.storage = storage;
}
public void start(){
task = runTaskTimer(ChestsPlusPlus.PLUGIN,1,8);
}
public void stop(){
task.cancel();
}
@Override
public void run() {
for(Location location : storage.getLocations()) {
Location below = location.clone().subtract(0, 1, 0);
if (below.getBlock().getState() instanceof Hopper) {
Hopper hopper = (Hopper) below.getBlock().getState();
Utils.moveToOtherInventory(storage.getInventory(),1,hopper.getInventory(),Utils.getHopperFilters(below.getBlock()));
}
}
}
}

View File

@ -0,0 +1,113 @@
package com.jamesdpeters.minecraft.chests.serialize;
import com.jamesdpeters.minecraft.chests.Messages;
import com.jamesdpeters.minecraft.chests.interfaces.VirtualInventoryHolder;
import com.jamesdpeters.minecraft.chests.runnables.VirtualChestToHopper;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.block.Chest;
import org.bukkit.configuration.serialization.ConfigurationSerializable;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import java.lang.reflect.Array;
import java.util.*;
public class InventoryStorage implements ConfigurationSerializable {
Inventory inventory;
ArrayList<Location> locationsList;
String inventoryName = "Chest";
VirtualChestToHopper chestToHopper;
Player player;
UUID playerUUID;
@Override
public Map<String, Object> serialize() {
LinkedHashMap<String, Object> hashMap = new LinkedHashMap<>();
hashMap.put("inventory",inventory.getContents());
hashMap.put("locations",locationsList);
hashMap.put("inventoryName",inventoryName);
hashMap.put("playerUUID",playerUUID.toString());
return hashMap;
}
@SuppressWarnings("unchecked")
public InventoryStorage(Map<String, Object> map){
String tempName = (String) map.get("inventoryName");
if(tempName != null) inventoryName = tempName;
inventory = initInventory();
ItemStack[] itemStacks = ((ArrayList<ItemStack>) map.get("inventory")).toArray(new ItemStack[0]);
inventory.setContents(itemStacks);
locationsList = (ArrayList<Location>) map.get("locations");
playerUUID = UUID.fromString((String) map.get("playerUUID"));
player = Bukkit.getOfflinePlayer(playerUUID).getPlayer();
init();
}
public InventoryStorage(Player player, String group, Location location){
this.inventoryName = group;
this.player = player;
this.playerUUID = player.getUniqueId();
locationsList = new ArrayList<>(Collections.singleton(location));
Block block = location.getBlock();
if(block.getState() instanceof Chest){
Chest chest = (Chest) block.getState();
inventory = initInventory();
inventory.setContents(chest.getInventory().getContents());
chest.getInventory().clear();
}
init();
}
private void init(){
chestToHopper = new VirtualChestToHopper(this);
chestToHopper.start();
}
private Inventory initInventory(){
return Bukkit.createInventory(new VirtualInventoryHolder(this), 54,inventoryName);
}
public Inventory getInventory() {
return inventory;
}
public List<Location> getLocations() {
return locationsList;
}
public void dropInventory(Location location){
for(ItemStack item : inventory.getContents()) {
if(location.getWorld() != null){
if(item != null) {
location.getWorld().dropItemNaturally(location, item);
inventory.remove(item);
}
}
}
}
public String getIdentifier() {
return inventoryName;
}
public Player getOwner() {
return player;
}
@Override
public String toString() {
return inventoryName+": "+locationsList.toString();
}
}

View File

@ -0,0 +1,33 @@
package com.jamesdpeters.minecraft.chests.serialize;
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;
@SerializableAs("LinkedChest")
public class LinkedChest implements ConfigurationSerializable {
public HashMap<String, HashMap<String, InventoryStorage>> chests;
@Override
public Map<String, Object> serialize() {
LinkedHashMap<String, Object> hashMap = new LinkedHashMap<>();
hashMap.put("chests",chests);
return hashMap;
}
@SuppressWarnings("unchecked")
public LinkedChest(Map<String, Object> map){
chests = (HashMap<String, HashMap<String, InventoryStorage>>) map.get("chests");
}
public LinkedChest(){
chests = new HashMap<>();
}
}

View File

@ -0,0 +1,11 @@
name: ChestsPlusPlus
version: 1.14.4-v1
main: com.jamesdpeters.minecraft.chests.ChestsPlusPlus
api-version: "1.14"
depend: [ProtocolLib]
commands:
chestlink:
description: Chest++ Commands.
usage: Use /chestlink help for more info.