diff --git a/src/main/java/net/pietru/cookie_utils/api/Area.java b/src/main/java/net/pietru/cookie_utils/api/Area.java
index 9e98759..b6a2529 100644
--- a/src/main/java/net/pietru/cookie_utils/api/Area.java
+++ b/src/main/java/net/pietru/cookie_utils/api/Area.java
@@ -6,10 +6,22 @@ import com.badlogic.gdx.math.collision.BoundingBox;
public class Area {
BoundingBox space = new BoundingBox();
+ public boolean enabled = true;
+
+ public boolean canPlace = false;
+ public boolean canBreak = false;
+ public boolean canInteract = false;
+
+ public int piority = 0;
+
public BoundingBox getBox() {
return space;
}
+ public int get_piority(){
+ return piority;
+ }
+
public void setCorners(Vector3 a, Vector3 b){
space.set(a,b);
}
@@ -17,4 +29,17 @@ public class Area {
public boolean does_intersect(Vector3 c){
return space.contains(c);
}
+
+ public boolean get_action_bool(String action){
+ switch (action){
+ case "place":
+ return canPlace;
+ case "break":
+ return canBreak;
+ case "interact":
+ return canInteract;
+ }
+ return false;
+ }
+
}
diff --git a/src/main/java/net/pietru/cookie_utils/api/Region.java b/src/main/java/net/pietru/cookie_utils/api/Region.java
index b7bd39f..c4f6699 100644
--- a/src/main/java/net/pietru/cookie_utils/api/Region.java
+++ b/src/main/java/net/pietru/cookie_utils/api/Region.java
@@ -1,26 +1,93 @@
package net.pietru.cookie_utils.api;
+import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.utils.Array;
+import com.badlogic.gdx.utils.JsonReader;
+import com.badlogic.gdx.utils.JsonValue;
+import com.badlogic.gdx.utils.Sort;
+import finalforeach.cosmicreach.GameAssetLoader;
import finalforeach.cosmicreach.blocks.BlockPosition;
+import finalforeach.cosmicreach.io.SaveLocation;
import finalforeach.cosmicreach.world.Zone;
+import java.io.File;
+import java.util.Comparator;
+
public class Region {
+ static JsonReader jsonReader = new JsonReader();
public static Array areas = new Array<>();
- public static boolean can_edit_block(BlockPosition position){
+ public static boolean is_not_reloading = true;
+
+ public static boolean can_edit_block(BlockPosition position,String action){
Zone z = position.getZone();
Vector3 g_position = new Vector3(position.getGlobalX(),position.getGlobalY(),position.getGlobalZ());
- boolean can = true;
+ boolean can = is_not_reloading;
for (Area a : areas){
- if (a.does_intersect(g_position)){
- can=false;
+ if (a.enabled && a.does_intersect(g_position)){
+ can=a.get_action_bool(action);
break;
}
}
return can;
}
+
+ public static void reload_regions(){
+ is_not_reloading=false;
+
+ areas.clear();
+
+ File regions_folder = new File(SaveLocation.getSaveFolder(),"regions");
+ if (!regions_folder.exists())
+ regions_folder.mkdirs();
+ File[] regions = regions_folder.listFiles(((dir, name) -> name.endsWith(".json")));
+ if (regions!=null) {
+ System.out.println("[REGIONS] Trying to load %s areas.".replace("%s",String.valueOf(regions.length)));
+ for (File f : regions) {
+ JsonValue region;
+ try {
+ region=jsonReader.parse(Gdx.files.absolute(f.getPath()));
+ } catch (Exception ignored){
+ System.out.println("[REGIONS] Region file \"%s\" had encountered exception while loading...".replace("%s", f.getPath()));
+ continue;
+ }
+ Area area = new Area();
+ if (!region.has("x1") || !region.has("y1") || !region.has("z1")) {
+ System.out.println("[REGIONS] Region file \"%s\" missing x1, y1 or z1.".replace("%s", f.getPath()));
+ continue;
+ }
+ if (!region.has("x2") || !region.has("y2") || !region.has("z2")) {
+ System.out.println("[REGIONS] Region file \"%s\" missing x2, y2 or z2.".replace("%s", f.getPath()));
+ continue;
+ }
+ Vector3 a = new Vector3(region.getFloat("x1"), region.getFloat("y1"), region.getFloat("z1"));
+ Vector3 b = new Vector3(region.getFloat("x2"), region.getFloat("y2"), region.getFloat("z2"));
+ area.setCorners(a, b);
+
+
+ area.enabled=region.getBoolean("enabled",true);
+
+ area.canPlace=region.getBoolean("canPlace",false);
+ area.canBreak=region.getBoolean("canBreak",false);
+ area.canInteract=region.getBoolean("canInteract",false);
+
+
+ area.piority=region.getInt("piority",0);
+
+ areas.add(area);
+ }
+ }
+
+ Sort sorter = Sort.instance();
+
+ sorter.sort(areas,(a,b)->b.piority-a.piority);
+
+ is_not_reloading=true;
+
+ System.out.println("[REGIONS] Loaded %s areas.".replace("%s",String.valueOf(areas.size)));
+ }
}
diff --git a/src/main/java/net/pietru/cookie_utils/api/TextCommands.java b/src/main/java/net/pietru/cookie_utils/api/TextCommands.java
new file mode 100644
index 0000000..0cd15b6
--- /dev/null
+++ b/src/main/java/net/pietru/cookie_utils/api/TextCommands.java
@@ -0,0 +1,47 @@
+package net.pietru.cookie_utils.api;
+
+import com.badlogic.gdx.math.Vector3;
+import finalforeach.cosmicreach.accounts.Account;
+import finalforeach.cosmicreach.entities.player.Player;
+import finalforeach.cosmicreach.networking.netty.packets.MessagePacket;
+import finalforeach.cosmicreach.networking.server.ServerSingletons;
+import finalforeach.cosmicreach.savelib.utils.TriConsumer;
+import io.netty.channel.ChannelHandlerContext;
+import finalforeach.cosmicreach.networking.common.NetworkIdentity;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static net.pietru.cookie_utils.api.Region.reload_regions;
+
+public class TextCommands {
+ public static final Map> commands = new HashMap<>();
+
+ public static void run(String[] args, NetworkIdentity id, ChannelHandlerContext ctx){
+ if (args.length==0)
+ return;
+ if (!commands.containsKey(args[0]))
+ return;
+ TriConsumer cmd = commands.get(args[0]);
+ cmd.accept(args, id, ctx);
+ }
+
+ static {
+ commands.put("gpos",(args, networkIdentity, channelHandlerContext) -> {
+ Player player = ServerSingletons.getPlayer(networkIdentity);
+ Account account = ServerSingletons.getAccount(networkIdentity);
+
+ Vector3 pos = player.getPosition();
+ MessagePacket packet = new MessagePacket("You are at "+(int)pos.x+" "+(int)pos.y+" "+(int)pos.z);
+ packet.playerUniqueId=account.getUniqueId();
+ packet.setupAndSend(channelHandlerContext);
+ });
+ commands.put("reload_regions",(args, networkIdentity, channelHandlerContext) -> {
+ reload_regions();
+ Account account = ServerSingletons.getAccount(networkIdentity);
+ MessagePacket packet = new MessagePacket("Reloaded regions...");
+ packet.playerUniqueId=account.getUniqueId();
+ packet.setupAndSend(channelHandlerContext);
+ });
+ }
+}
diff --git a/src/main/java/net/pietru/cookie_utils/mixins/BlockBreakMixin.java b/src/main/java/net/pietru/cookie_utils/mixins/BlockBreakMixin.java
index ba34513..4be7903 100644
--- a/src/main/java/net/pietru/cookie_utils/mixins/BlockBreakMixin.java
+++ b/src/main/java/net/pietru/cookie_utils/mixins/BlockBreakMixin.java
@@ -1,11 +1,14 @@
package net.pietru.cookie_utils.mixins;
import com.llamalad7.mixinextras.sugar.Local;
+import finalforeach.cosmicreach.accounts.Account;
import finalforeach.cosmicreach.blocks.BlockPosition;
import finalforeach.cosmicreach.blocks.BlockState;
import finalforeach.cosmicreach.networking.common.NetworkIdentity;
import finalforeach.cosmicreach.networking.common.NetworkSide;
+import finalforeach.cosmicreach.networking.netty.packets.MessagePacket;
import finalforeach.cosmicreach.networking.netty.packets.blocks.BreakBlockPacket;
+import finalforeach.cosmicreach.networking.server.ServerSingletons;
import finalforeach.cosmicreach.world.Zone;
import io.netty.channel.ChannelHandlerContext;
import org.spongepowered.asm.mixin.Mixin;
@@ -15,6 +18,7 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import static net.pietru.cookie_utils.api.Region.can_edit_block;
+import static net.pietru.cookie_utils.api.Region.is_not_reloading;
@Mixin(BreakBlockPacket.class)
public class BlockBreakMixin {
@@ -26,10 +30,15 @@ public class BlockBreakMixin {
BlockState brokenBlockState;
@Inject(method = "handle", at = @At("HEAD"), cancellable = true)
- private void event_block_break(@Local NetworkIdentity identity, @Local ChannelHandlerContext ctx, CallbackInfo ci){
+ private void event_block_break(CallbackInfo ci, @Local NetworkIdentity identity, @Local ChannelHandlerContext ctx){
if (identity.getSide() != NetworkSide.CLIENT) {
- if (!can_edit_block(blockPos)) {
+ if (!can_edit_block(blockPos,"break")) {
ci.cancel();
+
+ Account account = ServerSingletons.getAccount(identity);
+ MessagePacket packet = new MessagePacket("[Server] " + (is_not_reloading ? "Sorry, but this area is under protection." : "Sorry but you can't do this action right now. [Config Reload In Progress]"));
+ packet.playerUniqueId=account.getUniqueId();
+ packet.setupAndSend(ctx);
}
}
}
diff --git a/src/main/java/net/pietru/cookie_utils/mixins/BlockPlaceMixin.java b/src/main/java/net/pietru/cookie_utils/mixins/BlockPlaceMixin.java
index fd3b7e2..0205a89 100644
--- a/src/main/java/net/pietru/cookie_utils/mixins/BlockPlaceMixin.java
+++ b/src/main/java/net/pietru/cookie_utils/mixins/BlockPlaceMixin.java
@@ -1,11 +1,15 @@
package net.pietru.cookie_utils.mixins;
import com.llamalad7.mixinextras.sugar.Local;
+import finalforeach.cosmicreach.accounts.Account;
import finalforeach.cosmicreach.blocks.BlockPosition;
import finalforeach.cosmicreach.blocks.BlockState;
+import finalforeach.cosmicreach.entities.player.Player;
import finalforeach.cosmicreach.networking.common.NetworkIdentity;
import finalforeach.cosmicreach.networking.common.NetworkSide;
+import finalforeach.cosmicreach.networking.netty.packets.MessagePacket;
import finalforeach.cosmicreach.networking.netty.packets.blocks.PlaceBlockPacket;
+import finalforeach.cosmicreach.networking.server.ServerSingletons;
import finalforeach.cosmicreach.world.Zone;
import io.netty.channel.ChannelHandlerContext;
import org.spongepowered.asm.mixin.Mixin;
@@ -15,6 +19,7 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import static net.pietru.cookie_utils.api.Region.can_edit_block;
+import static net.pietru.cookie_utils.api.Region.is_not_reloading;
@Mixin(PlaceBlockPacket.class)
public class BlockPlaceMixin {
@@ -26,10 +31,15 @@ public class BlockPlaceMixin {
BlockState targetBlockState;
@Inject(method = "handle", at = @At("HEAD"), cancellable = true)
- private void event_block_place(@Local NetworkIdentity identity, @Local ChannelHandlerContext ctx, CallbackInfo ci){
+ private void event_block_place(CallbackInfo ci, @Local NetworkIdentity identity, @Local ChannelHandlerContext ctx){
if (identity.getSide() != NetworkSide.CLIENT) {
- if (!can_edit_block(blockPos)) {
+ if (!can_edit_block(blockPos,"place")) {
ci.cancel();
+
+ Account account = ServerSingletons.getAccount(identity);
+ MessagePacket packet = new MessagePacket("[Server] " + (is_not_reloading ? "Sorry, but this area is under protection." : "Sorry but you can't do this action right now. [Config Reload In Progress]"));
+ packet.playerUniqueId=account.getUniqueId();
+ packet.setupAndSend(ctx);
}
}
}
diff --git a/src/main/java/net/pietru/cookie_utils/mixins/InteractBlockMixin.java b/src/main/java/net/pietru/cookie_utils/mixins/InteractBlockMixin.java
new file mode 100644
index 0000000..e2503e7
--- /dev/null
+++ b/src/main/java/net/pietru/cookie_utils/mixins/InteractBlockMixin.java
@@ -0,0 +1,45 @@
+package net.pietru.cookie_utils.mixins;
+
+import com.llamalad7.mixinextras.sugar.Local;
+import finalforeach.cosmicreach.accounts.Account;
+import finalforeach.cosmicreach.blocks.BlockPosition;
+import finalforeach.cosmicreach.blocks.BlockState;
+import finalforeach.cosmicreach.networking.common.NetworkIdentity;
+import finalforeach.cosmicreach.networking.common.NetworkSide;
+import finalforeach.cosmicreach.networking.netty.packets.MessagePacket;
+import finalforeach.cosmicreach.networking.netty.packets.blocks.InteractBlockPacket;
+import finalforeach.cosmicreach.networking.server.ServerSingletons;
+import finalforeach.cosmicreach.world.Zone;
+import io.netty.channel.ChannelHandlerContext;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Shadow;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+
+import static net.pietru.cookie_utils.api.Region.can_edit_block;
+import static net.pietru.cookie_utils.api.Region.is_not_reloading;
+
+@Mixin(InteractBlockPacket.class)
+public class InteractBlockMixin {
+ @Shadow
+ Zone zone;
+ @Shadow
+ BlockPosition blockPos;
+ @Shadow
+ BlockState blockState;
+
+ @Inject(method = "handle", at = @At("HEAD"), cancellable = true)
+ private void event_block_interact(CallbackInfo ci, @Local NetworkIdentity identity, @Local ChannelHandlerContext ctx){
+ if (identity.getSide() != NetworkSide.CLIENT) {
+ if (!can_edit_block(blockPos,"interact")) {
+ ci.cancel();
+
+ Account account = ServerSingletons.getAccount(identity);
+ MessagePacket packet = new MessagePacket("[Server] " + (is_not_reloading ? "Sorry, but this area is under protection." : "Sorry but you can't do this action right now. [Config Reload In Progress]"));
+ packet.playerUniqueId=account.getUniqueId();
+ packet.setupAndSend(ctx);
+ }
+ }
+ }
+}
diff --git a/src/main/java/net/pietru/cookie_utils/mixins/MessagePacketMixin.java b/src/main/java/net/pietru/cookie_utils/mixins/MessagePacketMixin.java
new file mode 100644
index 0000000..09e1b6c
--- /dev/null
+++ b/src/main/java/net/pietru/cookie_utils/mixins/MessagePacketMixin.java
@@ -0,0 +1,37 @@
+package net.pietru.cookie_utils.mixins;
+
+import com.badlogic.gdx.utils.Array;
+import com.llamalad7.mixinextras.sugar.Local;
+import finalforeach.cosmicreach.blocks.BlockPosition;
+import finalforeach.cosmicreach.blocks.BlockState;
+import finalforeach.cosmicreach.networking.common.NetworkIdentity;
+import finalforeach.cosmicreach.networking.common.NetworkSide;
+import finalforeach.cosmicreach.networking.netty.packets.MessagePacket;
+import finalforeach.cosmicreach.world.Zone;
+import io.netty.channel.ChannelHandlerContext;
+import net.pietru.cookie_utils.api.TextCommands;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Shadow;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+
+import static net.pietru.cookie_utils.api.Region.can_edit_block;
+
+@Mixin(MessagePacket.class)
+public class MessagePacketMixin {
+
+ @Shadow public String message;
+
+ @Inject(method = "handle", at = @At("HEAD"), cancellable = true)
+ private void event_on_message(CallbackInfo ci, @Local NetworkIdentity identity, @Local ChannelHandlerContext ctx){
+ if (identity.getSide() != NetworkSide.CLIENT) {
+ if (message.startsWith(":")) {
+ String cmd = message.replaceFirst(":","");
+ String[] data = cmd.split(" ");
+ TextCommands.run(data,identity,ctx);
+ ci.cancel();
+ }
+ }
+ }
+}
diff --git a/src/main/java/net/pietru/cookie_utils/mixins/ServerSingletonsMixin.java b/src/main/java/net/pietru/cookie_utils/mixins/ServerSingletonsMixin.java
new file mode 100644
index 0000000..dd8264f
--- /dev/null
+++ b/src/main/java/net/pietru/cookie_utils/mixins/ServerSingletonsMixin.java
@@ -0,0 +1,18 @@
+package net.pietru.cookie_utils.mixins;
+
+import com.llamalad7.mixinextras.sugar.Local;
+import finalforeach.cosmicreach.networking.server.ServerSingletons;
+import net.pietru.cookie_utils.api.Region;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+
+@Mixin(ServerSingletons.class)
+public class ServerSingletonsMixin {
+
+ @Inject(method = "create", at = @At("HEAD"))
+ private static void on_singletons_create(CallbackInfo ci){
+ Region.reload_regions();
+ }
+}
diff --git a/src/main/resources/cookie_utils.mixins.json b/src/main/resources/cookie_utils.mixins.json
index 53a608b..8a5d1db 100644
--- a/src/main/resources/cookie_utils.mixins.json
+++ b/src/main/resources/cookie_utils.mixins.json
@@ -5,7 +5,10 @@
"compatibilityLevel": "JAVA_17",
"mixins": [
"BlockBreakMixin",
- "BlockPlaceMixin"
+ "BlockPlaceMixin",
+ "InteractBlockMixin",
+ "MessagePacketMixin",
+ "ServerSingletonsMixin"
],
"client": [],
"injectors": {