diff --git a/pom.xml b/pom.xml
index 17f5b986..19193202 100644
--- a/pom.xml
+++ b/pom.xml
@@ -124,8 +124,8 @@
https://jitpack.io
- jeff-media-public
- https://hub.jeff-media.com/nexus/repository/jeff-media-public/
+ jeffMediaPublic
+ https://repo.jeff-media.com/public
mcmmo-repo
@@ -148,7 +148,7 @@
com.github.Slimefun
Slimefun4
- 03e5b9a
+ f1363ceadf
provided
diff --git a/src/main/java/io/github/sefiraat/networks/listeners/SyncListener.java b/src/main/java/io/github/sefiraat/networks/listeners/SyncListener.java
new file mode 100644
index 00000000..1edc999b
--- /dev/null
+++ b/src/main/java/io/github/sefiraat/networks/listeners/SyncListener.java
@@ -0,0 +1,23 @@
+package io.github.sefiraat.networks.listeners;
+
+import javax.annotation.Nonnull;
+
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.EventPriority;
+import org.bukkit.event.block.BlockBreakEvent;
+import org.bukkit.event.block.BlockPlaceEvent;
+
+import io.github.sefiraat.networks.utils.NetworkUtils;
+
+public class SyncListener {
+
+ @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
+ public void onBlockBreak(@Nonnull BlockBreakEvent event) {
+ NetworkUtils.clearNetwork(event.getBlock().getLocation());
+ }
+
+ @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
+ public void onBlockPlace(@Nonnull BlockPlaceEvent event) {
+ NetworkUtils.clearNetwork(event.getBlock().getLocation());
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/io/github/sefiraat/networks/network/NetworkNode.java b/src/main/java/io/github/sefiraat/networks/network/NetworkNode.java
index 96438540..8e9e01a1 100644
--- a/src/main/java/io/github/sefiraat/networks/network/NetworkNode.java
+++ b/src/main/java/io/github/sefiraat/networks/network/NetworkNode.java
@@ -2,6 +2,7 @@
import io.github.sefiraat.networks.NetworkStorage;
import io.github.sefiraat.networks.Networks;
+import io.github.sefiraat.networks.slimefun.network.NetworkController;
import io.github.sefiraat.networks.slimefun.network.NetworkPowerNode;
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem;
import me.mrCookieSlime.Slimefun.api.BlockStorage;
@@ -103,6 +104,7 @@ public void addAllChildren() {
// Kill additional controllers if it isn't the root
if (testType == NodeType.CONTROLLER && !testLocation.equals(getRoot().nodePosition)) {
killAdditionalController(testLocation);
+ continue;
}
// Check if it's in the network already and, if not, create a child node and propagate further.
@@ -132,7 +134,7 @@ public void run() {
}
};
runnable.runTask(Networks.getInstance());
- NetworkStorage.getAllNetworkObjects().remove(location);
+ NetworkController.wipeNetwork(location);
}
}
diff --git a/src/main/java/io/github/sefiraat/networks/network/NetworkRoot.java b/src/main/java/io/github/sefiraat/networks/network/NetworkRoot.java
index 2387bd6f..271a24fe 100644
--- a/src/main/java/io/github/sefiraat/networks/network/NetworkRoot.java
+++ b/src/main/java/io/github/sefiraat/networks/network/NetworkRoot.java
@@ -37,6 +37,7 @@ public class NetworkRoot extends NetworkNode {
private final int maxNodes;
private boolean isOverburdened = false;
+ private Location controller = null;
private final Set bridges = ConcurrentHashMap.newKeySet();
private final Set monitors = ConcurrentHashMap.newKeySet();
private final Set importers = ConcurrentHashMap.newKeySet();
@@ -69,14 +70,13 @@ public NetworkRoot(@Nonnull Location location, @Nonnull NodeType type, int maxNo
super(location, type);
this.maxNodes = maxNodes;
this.root = this;
+ registerNode(location, type);
}
public void registerNode(@Nonnull Location location, @Nonnull NodeType type) {
nodeLocations.add(location);
switch (type) {
- case CONTROLLER -> {
- // Nothing here guvnor
- }
+ case CONTROLLER -> this.controller = location;
case BRIDGE -> bridges.add(location);
case STORAGE_MONITOR -> monitors.add(location);
case IMPORT -> importers.add(location);
@@ -131,6 +131,11 @@ public void setOverburdened(boolean overburdened) {
this.isOverburdened = overburdened;
}
+ @Nullable
+ public Location getController() {
+ return controller;
+ }
+
public Set getBridges() {
return this.bridges;
}
diff --git a/src/main/java/io/github/sefiraat/networks/slimefun/network/NetworkController.java b/src/main/java/io/github/sefiraat/networks/slimefun/network/NetworkController.java
index eeb1f04a..06728d55 100644
--- a/src/main/java/io/github/sefiraat/networks/slimefun/network/NetworkController.java
+++ b/src/main/java/io/github/sefiraat/networks/slimefun/network/NetworkController.java
@@ -3,7 +3,10 @@
import io.github.sefiraat.networks.NetworkStorage;
import io.github.sefiraat.networks.network.NetworkNode;
import io.github.sefiraat.networks.network.NetworkRoot;
+import io.github.sefiraat.networks.network.NodeDefinition;
import io.github.sefiraat.networks.network.NodeType;
+import io.github.sefiraat.networks.utils.Theme;
+import io.github.thebusybiscuit.slimefun4.api.events.PlayerRightClickEvent;
import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting;
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem;
@@ -15,12 +18,14 @@
import me.mrCookieSlime.Slimefun.api.BlockStorage;
import org.bukkit.Location;
import org.bukkit.block.Block;
+import org.bukkit.block.BlockFace;
import org.bukkit.inventory.ItemStack;
import javax.annotation.Nonnull;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
+import java.util.Optional;
import java.util.Set;
public class NetworkController extends NetworkObject {
@@ -57,6 +62,11 @@ public void tick(Block block, SlimefunItem item, Config data) {
NetworkRoot networkRoot = new NetworkRoot(block.getLocation(), NodeType.CONTROLLER, maxNodes.getValue());
networkRoot.addAllChildren();
+ NodeDefinition definition = NetworkStorage.getAllNetworkObjects().get(block.getLocation());
+ if (definition != null) {
+ definition.setNode(networkRoot);
+ }
+
boolean crayon = CRAYONS.contains(block.getLocation());
if (crayon) {
networkRoot.setDisplayParticles(true);
@@ -68,6 +78,45 @@ public void tick(Block block, SlimefunItem item, Config data) {
);
}
+ @Override
+ protected void prePlace(@Nonnull PlayerRightClickEvent event) {
+ Optional blockOptional = event.getClickedBlock();
+
+ if (blockOptional.isPresent()) {
+ Block block = blockOptional.get();
+ Block target = block.getRelative(event.getClickedFace());
+
+ for (BlockFace checkFace : CHECK_FACES) {
+ Block checkBlock = target.getRelative(checkFace);
+ SlimefunItem slimefunItem = BlockStorage.check(checkBlock);
+
+ // For directly adjacent controllers
+ if (slimefunItem instanceof NetworkController) {
+ cancelPlace(event);
+ return;
+ }
+
+ // Check for node definitions. If there isn't one, we don't care
+ NodeDefinition definition = NetworkStorage.getAllNetworkObjects().get(checkBlock.getLocation());
+ if (definition == null) {
+ continue;
+ }
+
+ // There is a definition, if it has a node, then it's part of an active network.
+ if (definition.getNode() != null) {
+ cancelPlace(event);
+ return;
+ }
+ }
+ }
+ }
+
+ @Override
+ protected void cancelPlace(PlayerRightClickEvent event) {
+ event.getPlayer().sendMessage(Theme.ERROR.getColor() + "This network already has a controller!");
+ event.cancel();
+ }
+
private void onFirstTick(@Nonnull Block block, @Nonnull Config data) {
final String crayon = data.getString(CRAYON);
if (Boolean.parseBoolean(crayon)) {
@@ -98,8 +147,11 @@ public static boolean hasCrayon(@Nonnull Location location) {
}
public static void wipeNetwork(@Nonnull Location location) {
- for (NetworkNode node : NETWORKS.remove(location).getChildrenNodes()) {
- NetworkStorage.removeNode(node.getNodePosition());
+ NetworkRoot networkRoot = NETWORKS.remove(location);
+ if (networkRoot != null) {
+ for (NetworkNode node : networkRoot.getChildrenNodes()) {
+ NetworkStorage.removeNode(node.getNodePosition());
+ }
}
}
}
diff --git a/src/main/java/io/github/sefiraat/networks/slimefun/network/NetworkObject.java b/src/main/java/io/github/sefiraat/networks/slimefun/network/NetworkObject.java
index 9a0ee817..f9a32d56 100644
--- a/src/main/java/io/github/sefiraat/networks/slimefun/network/NetworkObject.java
+++ b/src/main/java/io/github/sefiraat/networks/slimefun/network/NetworkObject.java
@@ -1,13 +1,20 @@
package io.github.sefiraat.networks.slimefun.network;
import io.github.sefiraat.networks.NetworkStorage;
+import io.github.sefiraat.networks.network.NetworkRoot;
import io.github.sefiraat.networks.network.NodeDefinition;
import io.github.sefiraat.networks.network.NodeType;
+import io.github.sefiraat.networks.utils.Theme;
+import io.github.thebusybiscuit.slimefun4.api.events.PlayerRightClickEvent;
import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem;
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
import io.github.thebusybiscuit.slimefun4.core.handlers.BlockBreakHandler;
+import io.github.thebusybiscuit.slimefun4.core.handlers.BlockPlaceHandler;
+import io.github.thebusybiscuit.slimefun4.core.handlers.ItemUseHandler;
+import io.github.thebusybiscuit.slimefun4.implementation.items.blocks.UnplaceableBlock;
+
import lombok.Getter;
import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config;
import me.mrCookieSlime.Slimefun.Objects.handlers.BlockTicker;
@@ -15,13 +22,17 @@
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
import org.bukkit.Location;
import org.bukkit.block.Block;
+import org.bukkit.block.BlockFace;
import org.bukkit.event.block.BlockBreakEvent;
+import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.inventory.ItemStack;
import javax.annotation.Nonnull;
import javax.annotation.ParametersAreNonnullByDefault;
import java.util.ArrayList;
import java.util.List;
+import java.util.Optional;
+import java.util.Set;
public abstract class NetworkObject extends SlimefunItem implements AdminDebuggable {
@@ -30,6 +41,16 @@ public abstract class NetworkObject extends SlimefunItem implements AdminDebugga
@Getter
private final List slotsToDrop = new ArrayList<>();
+ protected static final Set CHECK_FACES = Set.of(
+ BlockFace.UP,
+ BlockFace.DOWN,
+ BlockFace.NORTH,
+ BlockFace.SOUTH,
+ BlockFace.EAST,
+ BlockFace.WEST
+ );
+
+
protected NetworkObject(ItemGroup itemGroup, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, NodeType type) {
this(itemGroup, item, recipeType, recipe, null, type);
}
@@ -57,6 +78,18 @@ public void onPlayerBreak(BlockBreakEvent event, ItemStack item, List
preBreak(event);
onBreak(event);
}
+ },
+ new BlockPlaceHandler(false) {
+ @Override
+ public void onPlayerPlace(@Nonnull BlockPlaceEvent blockPlaceEvent) {
+ onPlace(blockPlaceEvent);
+ }
+ },
+ new ItemUseHandler() {
+ @Override
+ public void onRightClick(PlayerRightClickEvent playerRightClickEvent) {
+ prePlace(playerRightClickEvent);
+ }
}
);
}
@@ -81,13 +114,55 @@ protected void onBreak(@Nonnull BlockBreakEvent event) {
blockMenu.dropItems(location, i);
}
}
- NetworkStorage.removeNode(location);
+// NetworkStorage.removeNode(location);
+//
+// if (this.nodeType == NodeType.CONTROLLER) {
+// NetworkController.wipeNetwork(location);
+// }
+
+ BlockStorage.clearBlockInfo(location);
+ }
- if (this.nodeType == NodeType.CONTROLLER) {
- NetworkController.wipeNetwork(location);
+ protected void prePlace(@Nonnull PlayerRightClickEvent event) {
+ Optional blockOptional = event.getClickedBlock();
+ Location controllerLocation = null;
+
+ if (blockOptional.isPresent()) {
+ Block block = blockOptional.get();
+ Block target = block.getRelative(event.getClickedFace());
+
+ addToRegistry(block);
+ for (BlockFace checkFace : CHECK_FACES) {
+ Block checkBlock = target.getRelative(checkFace);
+
+ // Check for node definitions. If there isn't one, we don't care
+ NodeDefinition definition = NetworkStorage.getAllNetworkObjects().get(checkBlock.getLocation());
+ if (definition == null) {
+ continue;
+ }
+
+ // There is a definition, if it has a node, then it's part of an active network.
+ if (definition.getNode() != null) {
+ NetworkRoot networkRoot = definition.getNode().getRoot();
+ if (controllerLocation == null) {
+ // First network found, store root location
+ controllerLocation = networkRoot.getController();
+ } else if (!controllerLocation.equals(networkRoot.getController())) {
+ // Location differs from that previously recorded, would result in two controllers
+ cancelPlace(event);
+ }
+ }
+ }
}
+ }
+
+ protected void cancelPlace(PlayerRightClickEvent event) {
+ event.getPlayer().sendMessage(Theme.ERROR.getColor() + "This placement would connect two controllers!");
+ event.cancel();
+ }
+
+ protected void onPlace(@Nonnull BlockPlaceEvent event) {
- BlockStorage.clearBlockInfo(location);
}
public boolean runSync() {
diff --git a/src/main/java/io/github/sefiraat/networks/slimefun/tools/CraftingBlueprint.java b/src/main/java/io/github/sefiraat/networks/slimefun/tools/CraftingBlueprint.java
index aa47359a..bfe35e31 100644
--- a/src/main/java/io/github/sefiraat/networks/slimefun/tools/CraftingBlueprint.java
+++ b/src/main/java/io/github/sefiraat/networks/slimefun/tools/CraftingBlueprint.java
@@ -9,21 +9,28 @@
import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup;
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack;
import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType;
+import io.github.thebusybiscuit.slimefun4.core.attributes.DistinctiveItem;
import io.github.thebusybiscuit.slimefun4.implementation.items.blocks.UnplaceableBlock;
import org.bukkit.ChatColor;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
+import javax.annotation.Nonnull;
import javax.annotation.ParametersAreNonnullByDefault;
import java.util.ArrayList;
import java.util.List;
-public class CraftingBlueprint extends UnplaceableBlock {
+public class CraftingBlueprint extends UnplaceableBlock implements DistinctiveItem {
public CraftingBlueprint(ItemGroup itemGroup, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(itemGroup, item, recipeType, recipe);
}
+ @Override
+ public boolean canStack(@Nonnull ItemMeta itemMetaOne, @Nonnull ItemMeta itemMetaTwo) {
+ return itemMetaOne.getPersistentDataContainer().equals(itemMetaTwo.getPersistentDataContainer());
+ }
+
@ParametersAreNonnullByDefault
public static void setBlueprint(ItemStack blueprint, ItemStack[] recipe, ItemStack output) {
final ItemMeta itemMeta = blueprint.getItemMeta();
diff --git a/src/main/java/io/github/sefiraat/networks/utils/NetworkUtils.java b/src/main/java/io/github/sefiraat/networks/utils/NetworkUtils.java
index 50372f6a..63de55a7 100644
--- a/src/main/java/io/github/sefiraat/networks/utils/NetworkUtils.java
+++ b/src/main/java/io/github/sefiraat/networks/utils/NetworkUtils.java
@@ -1,12 +1,20 @@
package io.github.sefiraat.networks.utils;
import de.jeff_media.morepersistentdatatypes.DataType;
+
+import io.github.sefiraat.networks.NetworkStorage;
+import io.github.sefiraat.networks.network.NetworkNode;
+import io.github.sefiraat.networks.network.NodeDefinition;
+import io.github.sefiraat.networks.network.NodeType;
+import io.github.sefiraat.networks.slimefun.network.NetworkController;
import io.github.sefiraat.networks.slimefun.network.NetworkDirectional;
import io.github.sefiraat.networks.slimefun.network.NetworkPusher;
import io.github.sefiraat.networks.slimefun.tools.NetworkConfigurator;
import io.github.sefiraat.networks.utils.datatypes.DataTypeMethods;
import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem;
import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu;
+
+import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Player;
@@ -76,4 +84,20 @@ public static void applyConfig(@Nonnull NetworkDirectional directional, @Nonnull
player.sendMessage(Theme.WARNING + "Items: " + Theme.PASSIVE + "No items in stored config");
}
}
+
+ public static void clearNetwork(Location location) {
+ NodeDefinition definition = NetworkStorage.getAllNetworkObjects().get(location);
+
+ if (definition == null || definition.getNode() == null) {
+ return;
+ }
+
+ NetworkNode node = definition.getNode();
+
+ if (node != null && node.getNodeType() == NodeType.CONTROLLER) {
+ NetworkController.wipeNetwork(location);
+ }
+
+ NetworkStorage.removeNode(location);
+ }
}