This commit is contained in:
James 2020-05-05 10:33:59 +01:00
commit b907b33748
10 changed files with 283 additions and 11 deletions

View File

@ -6,7 +6,7 @@
<groupId>com.jamesdpeters.chests</groupId>
<artifactId>ChestsPlusPlus</artifactId>
<version>1.15 v1.4</version>
<version>1.15 v1.4.1-DEV</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>

View File

@ -1,6 +1,7 @@
package com.jamesdpeters.minecraft.chests;
import com.jamesdpeters.minecraft.chests.commands.RemoteChestCommand;
import com.jamesdpeters.minecraft.chests.crafting.Crafting;
import com.jamesdpeters.minecraft.chests.listeners.ChestLinkListener;
import com.jamesdpeters.minecraft.chests.listeners.HopperListener;
import com.jamesdpeters.minecraft.chests.listeners.InventoryListener;
@ -11,12 +12,14 @@ import com.jamesdpeters.minecraft.chests.misc.Settings;
import com.jamesdpeters.minecraft.chests.misc.Stats;
import com.jamesdpeters.minecraft.chests.serialize.InventoryStorage;
import com.jamesdpeters.minecraft.chests.serialize.LinkedChest;
import com.jamesdpeters.minecraft.chests.serialize.SpigotConfig;
import com.jamesdpeters.minecraft.chests.versionchecker.UpdateCheck;
import com.jamesdpeters.minecraft.chests.maventemplates.BuildConstants;
import fr.minuskube.inv.InventoryManager;
import org.bstats.bukkit.Metrics;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.serialization.ConfigurationSerialization;
import org.bukkit.permissions.PermissionDefault;
import org.bukkit.plugin.java.JavaPlugin;
@ -27,6 +30,7 @@ import org.bukkit.plugin.java.annotation.plugin.ApiVersion;
import org.bukkit.plugin.java.annotation.plugin.Description;
import org.bukkit.plugin.java.annotation.plugin.Plugin;
import org.bukkit.plugin.java.annotation.plugin.author.Author;
import org.bukkit.scheduler.BukkitRunnable;
@Plugin(name = "ChestsPlusPlus", version = BuildConstants.VERSION)
@ -68,11 +72,14 @@ public class ChestsPlusPlus extends JavaPlugin {
getServer().getPluginManager().registerEvents(new HopperListener(),this);
getServer().getPluginManager().registerEvents(new WorldListener(),this);
SpigotConfig.load(this);
new Config();
INVENTORY_MANAGER = new InventoryManager(this);
INVENTORY_MANAGER.init();
Crafting.load();
boolean isDev = BuildConstants.VERSION.contains("DEV");
if(isDev) getLogger().warning("You are currently running a Dev build - update checker disabled! Build: "+BuildConstants.VERSION);

View File

@ -1,5 +1,6 @@
package com.jamesdpeters.minecraft.chests.commands;
import com.jamesdpeters.minecraft.chests.crafting.Crafting;
import com.jamesdpeters.minecraft.chests.inventories.ChestLinkMenu;
import com.jamesdpeters.minecraft.chests.serialize.Config;
import com.jamesdpeters.minecraft.chests.misc.Messages;
@ -30,7 +31,8 @@ public class RemoteChestCommand extends ServerCommand {
REMOVE("/chestlink remove <Group>", "Delete a ChestLink and drop its inventory at your feet!"),
RENAME("/chestlink rename <group> <new-name>","Rename a ChestLink."),
SETPUBLIC("/chestlink setpublic <group> <true/false>", "Set a ChestLink to be accessible by anyone."),
SORT("/chestlink sort <group> <sort-method>","Set the sorting option for the given ChestLink.");
SORT("/chestlink sort <group> <sort-method>","Set the sorting option for the given ChestLink."),
CRAFT("craft","craft");
String description, commandHelp;
@ -225,6 +227,9 @@ public class RemoteChestCommand extends ServerCommand {
return true;
}
}
case CRAFT: {
Crafting.craft(player);
}
}
}

View File

@ -0,0 +1,121 @@
package com.jamesdpeters.minecraft.chests.crafting;
import com.jamesdpeters.minecraft.chests.interfaces.VirtualCraftingHolder;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.inventory.CraftingInventory;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.Recipe;
import org.bukkit.inventory.RecipeChoice;
import org.bukkit.inventory.ShapedRecipe;
import org.bukkit.inventory.ShapelessRecipe;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class Crafting {
private static List<ShapedRecipe> shapedRecipes;
private static List<ShapelessRecipe> shapelessRecipes;
public static void load(){
shapedRecipes = new ArrayList<>();
shapelessRecipes = new ArrayList<>();
Bukkit.recipeIterator().forEachRemaining(recipe -> {
if(recipe instanceof ShapedRecipe) shapedRecipes.add((ShapedRecipe) recipe);
if(recipe instanceof ShapelessRecipe) shapelessRecipes.add((ShapelessRecipe) recipe);
});
Bukkit.broadcastMessage("Shaped Recipes: "+shapedRecipes.size());
Bukkit.broadcastMessage("Shapeless Recipes: "+shapelessRecipes.size());
}
public static ItemStack getResult(List<ItemStack> craftingTable){
for(ShapelessRecipe shapelessRecipe : shapelessRecipes) {
if (matchesShapeless(shapelessRecipe.getChoiceList(), craftingTable)) return shapelessRecipe.getResult();
}
// for(ShapedRecipe shapedRecipe : shapedRecipes) {
// if (matchesShaped(shapedRecipe, craftingTable)) return shapedRecipe.getResult();
// }
return null;
}
private static boolean matchesShapeless(List<RecipeChoice> choice, List<ItemStack> items) {
items = new ArrayList<>(items);
for (RecipeChoice c : choice) {
boolean match = false;
for (int i = 0; i < items.size(); i++) {
ItemStack item = items.get(i);
if (item == null || item.getType() == Material.AIR)
continue;
if (c.test(item)) {
match = true;
items.remove(i);
break;
}
}
if (!match)
return false;
}
Set<ItemStack> remainingItems = new HashSet<>(items);
return (remainingItems.size()==1&&(items.contains(new ItemStack(Material.AIR))||items.contains(null)));
}
private static boolean matchesShaped(ShapedRecipe shape, List<ItemStack> items) {
String[] map = shape.getShape();
Map<Character, RecipeChoice> choices = shape.getChoiceMap();
for (Map.Entry<Character, RecipeChoice> entry : choices.entrySet()) {
if (entry.getValue() == null)
continue;
}
int index = 0;
boolean test = true;
for (String s : map) {
if (!test)
break;
for (Character c : s.toCharArray()) {
RecipeChoice currentChoice = choices.get(c);
if (currentChoice == null) {
if (index < items.size() && items.get(index) != null
&& items.get(index).getType() != Material.AIR) {
test = false;
break;
}
index++;
continue;
}
if (index >= items.size()) {
test = false;
break;
}
if (!currentChoice.test(items.get(index))) {
test = false;
break;
}
index++;
}
}
return test;
}
public static void updateCrafting(Inventory inventory){
List<ItemStack> craftingMatrix = new ArrayList<>(Arrays.asList(inventory.getContents()));
if(craftingMatrix.get(0) != null) craftingMatrix.remove(0);
ItemStack result = getResult(craftingMatrix);
inventory.setItem(0, result);
}
public static void craft(Player player){
Inventory craft = new VirtualCraftingHolder().getInventory();
player.openInventory(craft);
}
}

View File

@ -0,0 +1,20 @@
package com.jamesdpeters.minecraft.chests.interfaces;
import org.bukkit.Bukkit;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
public class VirtualCraftingHolder implements InventoryHolder {
private Inventory inventory;
public VirtualCraftingHolder(){
inventory = Bukkit.createInventory(this, InventoryType.WORKBENCH);
}
@Override
public Inventory getInventory() {
return inventory;
}
}

View File

@ -5,7 +5,10 @@ import com.jamesdpeters.minecraft.chests.filters.HopperFilter;
import com.jamesdpeters.minecraft.chests.serialize.Config;
import com.jamesdpeters.minecraft.chests.misc.Utils;
import com.jamesdpeters.minecraft.chests.serialize.InventoryStorage;
import com.jamesdpeters.minecraft.chests.serialize.SpigotConfig;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Rotation;
import org.bukkit.block.Block;
import org.bukkit.block.Hopper;
@ -36,14 +39,16 @@ public class HopperListener implements Listener {
public void fromHopper(InventoryMoveItemEvent event){
//FROM HOPPER
if (event.getInitiator().getHolder() instanceof Hopper) {
InventoryStorage storage = Config.getInventoryStorage(event.getDestination().getLocation());
Location location = event.getDestination().getLocation();
InventoryStorage storage = Config.getInventoryStorage(location);
if (storage != null) {
if(!event.isCancelled()) {
event.setCancelled(true);
new BukkitRunnable() {
@Override
public void run() {
Utils.moveToOtherInventory(event.getSource(), 1, storage.getInventory());
int hopperAmount = SpigotConfig.getWorldSettings(location.getWorld().getName()).getHopperAmount();
Utils.moveToOtherInventory(event.getSource(), hopperAmount, storage.getInventory());
event.getDestination().getHolder().getInventory().clear();
storage.sort();
}

View File

@ -1,6 +1,8 @@
package com.jamesdpeters.minecraft.chests.listeners;
import com.jamesdpeters.minecraft.chests.ChestsPlusPlus;
import com.jamesdpeters.minecraft.chests.crafting.Crafting;
import com.jamesdpeters.minecraft.chests.interfaces.VirtualCraftingHolder;
import com.jamesdpeters.minecraft.chests.serialize.Config;
import com.jamesdpeters.minecraft.chests.misc.Messages;
import com.jamesdpeters.minecraft.chests.misc.Permissions;
@ -13,15 +15,16 @@ import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.*;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.CraftingInventory;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
public class InventoryListener implements Listener {
@EventHandler(priority = EventPriority.LOWEST)
public void onInventoryPlayerUpdate(InventoryClickEvent event){
if(event.getInventory().getHolder() instanceof VirtualInventoryHolder){
inventoryUpdate(event);
}
inventoryUpdate(event);
}
@EventHandler (priority = EventPriority.LOWEST)
@ -58,17 +61,59 @@ public class InventoryListener implements Listener {
}
public void inventoryUpdate(InventoryInteractEvent event){
if(event.getInventory().getHolder() instanceof VirtualInventoryHolder){
InventoryHolder holder = event.getInventory().getHolder();
if(holder instanceof VirtualInventoryHolder){
Bukkit.getScheduler().scheduleSyncDelayedTask(ChestsPlusPlus.PLUGIN, () -> ((VirtualInventoryHolder) event.getInventory().getHolder()).getStorage().sort(),1);
}
}
@EventHandler(priority = EventPriority.LOWEST)
public void onInventoryPlayerUpdate(InventoryDragEvent event){
if(event.getInventory().getHolder() instanceof VirtualInventoryHolder){
inventoryUpdate(event);
inventoryUpdate(event);
craftingUpdate(event);
}
//CRAFTING
@EventHandler(priority = EventPriority.HIGHEST)
public void inventoryDragEvent(InventoryDragEvent event){
Inventory inventory = event.getInventory();
if(inventory.getHolder() instanceof VirtualCraftingHolder){
event.setCancelled(true);
}
}
@EventHandler(priority = EventPriority.HIGHEST)
public void onCraftingPlayerUpdate(InventoryClickEvent event){
Inventory inventory = event.getClickedInventory();
if(inventory != null && event.getInventory().getHolder() instanceof VirtualCraftingHolder){
if(event.getClick() == ClickType.DOUBLE_CLICK){
if(event.getClickedInventory() == event.getView().getBottomInventory()){
event.getInventory().setItem(event.getSlot(),event.getCurrentItem());
event.setCurrentItem(null);
}
event.setCancelled(true);
}
if(event.getClickedInventory() == event.getView().getTopInventory()){
if(event.getSlot() >= 1 && event.getSlot() <= 9){
Bukkit.broadcastMessage("Click: "+event.getSlot());
event.getClickedInventory().setItem(event.getSlot(),event.getCurrentItem());
}
event.setCancelled(true);
craftingUpdate(event);
}
}
}
private void craftingUpdate(InventoryInteractEvent event){
InventoryHolder holder = event.getInventory().getHolder();
if(holder instanceof VirtualCraftingHolder){
Bukkit.getScheduler().scheduleSyncDelayedTask(ChestsPlusPlus.PLUGIN, () -> Crafting.updateCrafting(holder.getInventory()),1);
}
}
}

View File

@ -4,6 +4,7 @@ import com.jamesdpeters.minecraft.chests.ChestsPlusPlus;
import com.jamesdpeters.minecraft.chests.filters.HopperFilter;
import com.jamesdpeters.minecraft.chests.misc.Utils;
import com.jamesdpeters.minecraft.chests.serialize.InventoryStorage;
import com.jamesdpeters.minecraft.chests.serialize.SpigotConfig;
import org.bukkit.Location;
import org.bukkit.block.Hopper;
import org.bukkit.scheduler.BukkitRunnable;
@ -36,7 +37,8 @@ public class VirtualChestToHopper extends BukkitRunnable {
if(below.getBlock().isBlockIndirectlyPowered()|| below.getBlock().isBlockPowered()){
continue;
}
Utils.moveToOtherInventory(storage.getInventory(), 1, hopper.getInventory(), HopperFilter.getHopperFilters(below.getBlock()));
int hopperAmount = SpigotConfig.getWorldSettings(location.getWorld().getName()).getHopperAmount();
Utils.moveToOtherInventory(storage.getInventory(), hopperAmount , hopper.getInventory(), HopperFilter.getHopperFilters(below.getBlock()));
storage.sort();
}
}

View File

@ -0,0 +1,42 @@
package com.jamesdpeters.minecraft.chests.serialize;
import org.bukkit.World;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.plugin.java.JavaPlugin;
import java.util.HashMap;
public class SpigotConfig {
private static HashMap<String,WorldSettings> worlds;
private static WorldSettings default_;
public static void load(JavaPlugin plugin){
worlds = new HashMap<>();
try {
//Check if we're using the Spigot API.
Class.forName("org.spigotmc.SpigotConfig");
ConfigurationSection worldSettings = plugin.getServer().spigot().getConfig().getConfigurationSection("world-settings");
if(worldSettings != null) {
worldSettings.getValues(false).forEach((worldName, o) -> {
ConfigurationSection worldSetting = worldSettings.getConfigurationSection(worldName);
if (!worldName.equals("default") && worldSetting != null)
worlds.put(worldName, new WorldSettings(worldSetting));
});
ConfigurationSection section = worldSettings.getConfigurationSection("default");
if(section != null) default_ = new WorldSettings(section);
}
if(default_ == null) default_ = new WorldSettings();
} catch (ClassNotFoundException e){
//Not using the Spigot API so fallback to defaults
default_ = new WorldSettings();
}
}
public static WorldSettings getDefault(){ return default_; }
public static WorldSettings getWorldSettings(String worldName){
return worlds.getOrDefault(worldName,default_);
}
}

View File

@ -0,0 +1,25 @@
package com.jamesdpeters.minecraft.chests.serialize;
import org.bukkit.configuration.ConfigurationSection;
public class WorldSettings{
//Values
private int ticksPerHopperTransfer, hopperAmount;
public WorldSettings(ConfigurationSection settings){
ticksPerHopperTransfer = settings.getInt("ticks-per.hopper-transfer");
hopperAmount = settings.getInt("hopper-amount");
}
//Default class used as a fallback if Spigot isn't being used etc.
public WorldSettings(){
ticksPerHopperTransfer = 8;
hopperAmount = 1;
}
public int getTicksPerHopperTransfer(){
return ticksPerHopperTransfer;
}
public int getHopperAmount() { return hopperAmount; }
}