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 b6a2529..0afd758 100644 --- a/src/main/java/net/pietru/cookie_utils/api/Area.java +++ b/src/main/java/net/pietru/cookie_utils/api/Area.java @@ -11,6 +11,7 @@ public class Area { public boolean canPlace = false; public boolean canBreak = false; public boolean canInteract = false; + public boolean canExplode = false; public int piority = 0; @@ -38,6 +39,8 @@ public class Area { return canBreak; case "interact": return canInteract; + case "explode": + return canExplode; } return false; } diff --git a/src/main/java/net/pietru/cookie_utils/api/Delay.java b/src/main/java/net/pietru/cookie_utils/api/Delay.java new file mode 100644 index 0000000..ee172c7 --- /dev/null +++ b/src/main/java/net/pietru/cookie_utils/api/Delay.java @@ -0,0 +1,44 @@ +package net.pietru.cookie_utils.api; + +import org.jetbrains.annotations.Nullable; + +import java.util.HashMap; +import java.util.Map; + +public class Delay implements Runnable { + + float secondsToSleep; + String mode; + Map args = new HashMap<>(); + + public Delay(float seconds, String mode) { + this.secondsToSleep=seconds; + this.mode=mode; + } + + public Delay(float seconds, String mode, Map dt) { + this.secondsToSleep=seconds; + this.mode=mode; + this.args=dt; + } + + @Override + public void run() { + try { + Thread.sleep((long) (secondsToSleep * 1000)); // convert seconds to milliseconds + switch (mode){ + case "reset_permission_code": + Permissions.code=""; + System.out.println("[Permissions] Code reset..."); + break; + case "revoke_usr_perm": + String id = args.get("id"); + Permissions.clear_user_perm(id,false); + System.out.println("[Permissions] Users %s permission revoked - time out...".replace("%s",id)); + break; + } + } catch (InterruptedException ie) { + Thread.currentThread().interrupt(); + } + } +} diff --git a/src/main/java/net/pietru/cookie_utils/api/Permissions.java b/src/main/java/net/pietru/cookie_utils/api/Permissions.java new file mode 100644 index 0000000..c793dde --- /dev/null +++ b/src/main/java/net/pietru/cookie_utils/api/Permissions.java @@ -0,0 +1,72 @@ +package net.pietru.cookie_utils.api; + +import com.badlogic.gdx.utils.Array; + +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.Random; + +public class Permissions { + public static Array playerUniqueIds = new Array<>(); + + public static String code = ""; + + static Thread t; + static Map player_revoke_perm_timer = new HashMap<>(); + + public static void generate_new_code(){ + code = generateRandomString(6); + System.out.println("[Permissions] New perm code is %s".replace("%s",code)); + // Create a new Thread object + t = new Thread(new Delay(60,"reset_permission_code")); + + // Start the thread + t.start(); + } + + public static void check_code_and_add_user(String cd, String playerId){ + if (playerUniqueIds.contains(playerId,false)) { + System.out.println("[Permissions] Player %s tried re-verificate too early...".replace("%s", playerId)); + return; + } + if (code.isEmpty()) + return; + if (!Objects.equals(cd, code)) + return; + t.interrupt(); + code=""; + System.out.println("[Permissions] Player %s passed verification...".replace("%s",playerId)); + Map data = new HashMap<>(); + data.put("id",playerId); + Thread player_t = new Thread(new Delay(60*2,"revoke_usr_perm",data)); + player_t.start(); + player_revoke_perm_timer.put(playerId,player_t); + playerUniqueIds.add(playerId); + } + + public static void clear_user_perm(String playerId, boolean stop_thread){ + while (Permissions.playerUniqueIds.contains(playerId,false)) + Permissions.playerUniqueIds.removeValue(playerId,false); + if (stop_thread && Permissions.player_revoke_perm_timer.containsKey(playerId)) + Permissions.player_revoke_perm_timer.get(playerId).interrupt(); + Permissions.player_revoke_perm_timer.remove(playerId); + } + + public static boolean has_user_special_perm(String playerId){ + return playerUniqueIds.contains(playerId,false); + } + + + + private static final String CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + + public static String generateRandomString(int length) { + StringBuilder sb = new StringBuilder(length); + Random random = new Random(); + for (int i = 0; i < length; i++) { + sb.append(CHARACTERS.charAt(random.nextInt(CHARACTERS.length()))); + } + return sb.toString(); + } +} 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 c4f6699..0ec9fa4 100644 --- a/src/main/java/net/pietru/cookie_utils/api/Region.java +++ b/src/main/java/net/pietru/cookie_utils/api/Region.java @@ -75,6 +75,8 @@ public class Region { area.canBreak=region.getBoolean("canBreak",false); area.canInteract=region.getBoolean("canInteract",false); + area.canExplode=region.getBoolean("canExplode",false); + area.piority=region.getInt("piority",0); diff --git a/src/main/java/net/pietru/cookie_utils/api/TextCommands.java b/src/main/java/net/pietru/cookie_utils/api/TextCommands.java index 0d2b588..ed1b5b9 100644 --- a/src/main/java/net/pietru/cookie_utils/api/TextCommands.java +++ b/src/main/java/net/pietru/cookie_utils/api/TextCommands.java @@ -52,5 +52,21 @@ public class TextCommands { packet.playerUniqueId=account.getUniqueId(); packet.setupAndSend(channelHandlerContext); }); + + commands.put("perm_code",(args, networkIdentity, channelHandlerContext) -> { + Account account = ServerSingletons.getAccount(networkIdentity); + if (args.length==1) + Permissions.generate_new_code(); + if (args.length==2) + Permissions.check_code_and_add_user(args[1],account.getUniqueId()); + }); + + commands.put("perm_clear",(args, networkIdentity, channelHandlerContext) -> { + Account account = ServerSingletons.getAccount(networkIdentity); + if (args.length==1) { + Permissions.clear_user_perm(account.getUniqueId(),true); + System.out.println("[Permissions] Users %s permission revoked - user request...".replace("%s",account.getUniqueId())); + } + }); } } diff --git a/src/main/java/net/pietru/cookie_utils/mixins/BlockActionExplodeMixin.java b/src/main/java/net/pietru/cookie_utils/mixins/BlockActionExplodeMixin.java new file mode 100644 index 0000000..61dbd0e --- /dev/null +++ b/src/main/java/net/pietru/cookie_utils/mixins/BlockActionExplodeMixin.java @@ -0,0 +1,54 @@ +package net.pietru.cookie_utils.mixins; + +import com.badlogic.gdx.math.Vector3; +import com.llamalad7.mixinextras.sugar.Local; +import finalforeach.cosmicreach.blockevents.actions.BlockActionExplode; +import finalforeach.cosmicreach.blocks.BlockPosition; +import finalforeach.cosmicreach.world.Zone; +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(BlockActionExplode.class) +public class BlockActionExplodeMixin { + @Shadow + public int xOff; + @Shadow + public int yOff; + @Shadow + public int zOff; + @Shadow + public float radius; + + @Inject(method = "Lfinalforeach/cosmicreach/blockevents/actions/BlockActionExplode;act(Lfinalforeach/cosmicreach/blocks/BlockState;Lfinalforeach/cosmicreach/blockevents/BlockEventTrigger;Lfinalforeach/cosmicreach/world/Zone;Lfinalforeach/cosmicreach/blocks/BlockPosition;)V", at = @At("HEAD"), cancellable = true) + private void event_block_action_explode(CallbackInfo ci, @Local Zone zone, @Local BlockPosition sourcePos){ + float radiusSq = radius * radius; + + boolean cancel = false; + + for(float i = -radius; i <= radius; ++i) { + if (cancel) + break; + for(float j = -radius; j <= radius; ++j) { + if (cancel) + break; + for(float k = -radius; k <= radius; ++k) { + float workingRadiusSq = Vector3.len2(i, j, k); + if (workingRadiusSq <= radiusSq) { + BlockPosition pos = sourcePos.getOffsetBlockPos(zone, (int)((float)this.xOff + i), (int)((float)this.yOff + j), (int)((float)this.zOff + k)); + + if (!can_edit_block(pos,"explode")) { + cancel=true; + ci.cancel(); + break; + } + } + } + } + } + } +} 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 4be7903..3e3ba17 100644 --- a/src/main/java/net/pietru/cookie_utils/mixins/BlockBreakMixin.java +++ b/src/main/java/net/pietru/cookie_utils/mixins/BlockBreakMixin.java @@ -11,6 +11,7 @@ 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 net.pietru.cookie_utils.api.Permissions; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; @@ -32,10 +33,10 @@ public class BlockBreakMixin { @Inject(method = "handle", at = @At("HEAD"), cancellable = true) private void event_block_break(CallbackInfo ci, @Local NetworkIdentity identity, @Local ChannelHandlerContext ctx){ if (identity.getSide() != NetworkSide.CLIENT) { - if (!can_edit_block(blockPos,"break")) { + Account account = ServerSingletons.getAccount(identity); + if (!Permissions.has_user_special_perm(account.getUniqueId()) && !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 0205a89..2dd25f3 100644 --- a/src/main/java/net/pietru/cookie_utils/mixins/BlockPlaceMixin.java +++ b/src/main/java/net/pietru/cookie_utils/mixins/BlockPlaceMixin.java @@ -12,6 +12,7 @@ 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 net.pietru.cookie_utils.api.Permissions; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; @@ -33,10 +34,10 @@ public class BlockPlaceMixin { @Inject(method = "handle", at = @At("HEAD"), cancellable = true) private void event_block_place(CallbackInfo ci, @Local NetworkIdentity identity, @Local ChannelHandlerContext ctx){ if (identity.getSide() != NetworkSide.CLIENT) { - if (!can_edit_block(blockPos,"place")) { + Account account = ServerSingletons.getAccount(identity); + if (!Permissions.has_user_special_perm(account.getUniqueId()) && !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 index e2503e7..a3e59ea 100644 --- a/src/main/java/net/pietru/cookie_utils/mixins/InteractBlockMixin.java +++ b/src/main/java/net/pietru/cookie_utils/mixins/InteractBlockMixin.java @@ -11,6 +11,7 @@ import finalforeach.cosmicreach.networking.netty.packets.blocks.InteractBlockPac import finalforeach.cosmicreach.networking.server.ServerSingletons; import finalforeach.cosmicreach.world.Zone; import io.netty.channel.ChannelHandlerContext; +import net.pietru.cookie_utils.api.Permissions; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; @@ -32,10 +33,10 @@ public class InteractBlockMixin { @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")) { + Account account = ServerSingletons.getAccount(identity); + if (!Permissions.has_user_special_perm(account.getUniqueId()) && !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 index 09e1b6c..678783b 100644 --- a/src/main/java/net/pietru/cookie_utils/mixins/MessagePacketMixin.java +++ b/src/main/java/net/pietru/cookie_utils/mixins/MessagePacketMixin.java @@ -20,7 +20,8 @@ import static net.pietru.cookie_utils.api.Region.can_edit_block; @Mixin(MessagePacket.class) public class MessagePacketMixin { - + @Shadow + public String playerUniqueId; @Shadow public String message; @Inject(method = "handle", at = @At("HEAD"), cancellable = true) diff --git a/src/main/resources/cookie_utils.mixins.json b/src/main/resources/cookie_utils.mixins.json index 8a5d1db..5707d31 100644 --- a/src/main/resources/cookie_utils.mixins.json +++ b/src/main/resources/cookie_utils.mixins.json @@ -8,7 +8,8 @@ "BlockPlaceMixin", "InteractBlockMixin", "MessagePacketMixin", - "ServerSingletonsMixin" + "ServerSingletonsMixin", + "BlockActionExplodeMixin" ], "client": [], "injectors": {