diff --git a/src/main/java/modchest/block/custom/denkMalBlock.java b/src/main/java/modchest/block/custom/denkMalBlock.java index 94fce6a..ff8a436 100644 --- a/src/main/java/modchest/block/custom/denkMalBlock.java +++ b/src/main/java/modchest/block/custom/denkMalBlock.java @@ -18,6 +18,9 @@ import net.minecraft.world.World; import net.minecraft.world.WorldAccess; import net.minecraft.world.explosion.Explosion; import org.jetbrains.annotations.Nullable; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mutable; +import org.spongepowered.asm.mixin.Shadow; import static modchest.block.modBlocks.denk_mal_block_placeholder; @@ -138,4 +141,10 @@ public class denkMalBlock extends BlockWithEntity { //Item soll nicht crafta } } } + + @Mutable + @Final protected BlockPos worldPosition; + public void setCMPos(BlockPos newPos) { + worldPosition = newPos; + } } diff --git a/src/main/java/modchest/event/playerBreakBlockEvents.java b/src/main/java/modchest/event/playerBreakBlockEvents.java new file mode 100644 index 0000000..1fabcf5 --- /dev/null +++ b/src/main/java/modchest/event/playerBreakBlockEvents.java @@ -0,0 +1,18 @@ +package modchest.event; + +import modchest.util.denkMalBlockUtil; +import net.fabricmc.fabric.api.event.player.PlayerBlockBreakEvents; +import net.minecraft.block.BlockState; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import org.jetbrains.annotations.Nullable; + +public class playerBreakBlockEvents implements PlayerBlockBreakEvents.Before { + @Override + public boolean beforeBlockBreak(World world, PlayerEntity player, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity) { + denkMalBlockUtil util = new denkMalBlockUtil(); + return util.allowBlocks(world, player, pos); + } +} diff --git a/src/main/java/modchest/mixin/flintAndSteelItemMixin.java b/src/main/java/modchest/mixin/flintAndSteelItemMixin.java new file mode 100644 index 0000000..b64ad73 --- /dev/null +++ b/src/main/java/modchest/mixin/flintAndSteelItemMixin.java @@ -0,0 +1,41 @@ +package modchest.mixin; + +import modchest.REServerMod; +import modchest.util.denkMalBlockUtil; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.FlintAndSteelItem; +import net.minecraft.item.ItemUsageContext; +import net.minecraft.util.ActionResult; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(FlintAndSteelItem.class) +public class flintAndSteelItemMixin { + + @Inject(method = "useOnBlock", at = @At("HEAD"), cancellable = true) + public void useOnBlock(ItemUsageContext context, CallbackInfoReturnable cir) { + if(!callPlaceable(context)) { + cir.setReturnValue(ActionResult.FAIL); + } + } + + @Unique + private boolean callPlaceable(ItemUsageContext context) { + try { + PlayerEntity player = context.getPlayer(); + World world = context.getWorld(); + BlockPos pos = context.getBlockPos(); + denkMalBlockUtil util = new denkMalBlockUtil(); + return util.allowBlocks(world, player, pos); + } catch (Exception e) { + REServerMod.LOGGER.info("Exception in variables: " + e.toString()); + } + return false; + } + +} diff --git a/src/main/java/modchest/mixin/itemMixin.java b/src/main/java/modchest/mixin/itemMixin.java new file mode 100644 index 0000000..61f1886 --- /dev/null +++ b/src/main/java/modchest/mixin/itemMixin.java @@ -0,0 +1,41 @@ +package modchest.mixin; + +import modchest.REServerMod; +import modchest.util.denkMalBlockUtil; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.Item; +import net.minecraft.item.ItemUsageContext; +import net.minecraft.util.ActionResult; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(Item.class) +public class itemMixin { + + @Inject(method = "useOnBlock", at = @At("HEAD"), cancellable = true) + public void useOnBlock(ItemUsageContext context, CallbackInfoReturnable cir) { + if(!callPlaceable(context)) { + cir.setReturnValue(ActionResult.FAIL); + } + } + + @Unique + private boolean callPlaceable(ItemUsageContext context) { + try { + PlayerEntity player = context.getPlayer(); + World world = context.getWorld(); + BlockPos pos = context.getBlockPos(); + denkMalBlockUtil util = new denkMalBlockUtil(); + return util.allowBlocks(world, player, pos); + } catch (Exception e) { + REServerMod.LOGGER.info("Exception in variables: " + e.toString()); + } + return false; + } + +} diff --git a/src/main/java/modchest/mixin/playerPlaceBlockMixin.java b/src/main/java/modchest/mixin/playerPlaceBlockMixin.java new file mode 100644 index 0000000..a33512b --- /dev/null +++ b/src/main/java/modchest/mixin/playerPlaceBlockMixin.java @@ -0,0 +1,34 @@ +package modchest.mixin; + +import modchest.util.denkMalBlockUtil; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.BlockItem; +import net.minecraft.item.ItemPlacementContext; +import net.minecraft.util.ActionResult; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(BlockItem.class) +public class playerPlaceBlockMixin { + @Inject(method = "place(Lnet/minecraft/item/ItemPlacementContext;)Lnet/minecraft/util/ActionResult;", at = @At("HEAD"), cancellable = true) + public void canPlace(ItemPlacementContext context, CallbackInfoReturnable cir) { + if(!callPlaceable(context)) { + cir.setReturnValue(ActionResult.FAIL); + } + } + + @Unique + private boolean callPlaceable(ItemPlacementContext context) { + PlayerEntity player = context.getPlayer(); + World world = context.getWorld(); + BlockPos pos = context.getBlockPos(); + + denkMalBlockUtil util = new denkMalBlockUtil(); + return util.allowBlocks(world, player, pos); + } +} diff --git a/src/main/java/modchest/util/denkMalBlockUtil.java b/src/main/java/modchest/util/denkMalBlockUtil.java index dc2ff1a..da9bac4 100644 --- a/src/main/java/modchest/util/denkMalBlockUtil.java +++ b/src/main/java/modchest/util/denkMalBlockUtil.java @@ -1,31 +1,39 @@ package modchest.util; +import net.minecraft.entity.player.PlayerEntity; import net.minecraft.nbt.NbtCompound; +import net.minecraft.text.Text; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; import java.util.Arrays; +import java.util.Set; + +import static java.lang.Math.abs; public class denkMalBlockUtil extends dataSaverIO{ public denkMalBlockUtil() {} + public void addBlock(int[] pos, int[] range) { //fuegt bloecke der Liste an abbauverhindernden Bloecke hinzu - NbtCompound tempNbt = new NbtCompound(); //Nbt in dem die Lockdaten gespeichert werden + NbtCompound tempNbt = new NbtCompound(); //Nbt in dem die Blockdaten gespeichert werden + NbtCompound nbt = returnLoadedNbt(); //holt sich den denkmalblock nbt tempNbt.putIntArray("position", pos); tempNbt.putIntArray("range", range); - NbtCompound nbt = returnloadedNbt(); //holt sich den denkmalblock nbt - nbt.put(Arrays.toString(pos), tempNbt); //speichert die daten des neuen Blocks ab + nbt.put(Arrays.toString(pos), tempNbt); //speichert die daten des neuen Blocks ab saveInNbt(nbt); //speichert den editierten denkmalblock-nbt ab } public void removeBlock(int[] posString) { //loescht bloecke aus Liste an abbauverhindernden Bloecken - NbtCompound nbt = returnloadedNbt(); //holt sich den denkmalblock nbt + NbtCompound nbt = returnLoadedNbt(); //holt sich den denkmalblock nbt nbt.remove(Arrays.toString(posString)); //entfernt diesen block saveInNbt(nbt); //speichert den editierten denkmalblock-nbt ab } - private NbtCompound returnloadedNbt() { //gibt den denkmalblock nbt zurueck + private NbtCompound returnLoadedNbt() { //gibt den denkmalblock nbt zurueck NbtCompound nbt = getFromNbt(); //laedt den gesamten reServerNbt - nbt = (NbtCompound) nbt.get("denkmalblock"); //nimmt den denkmalblocknbt und laedt diesen + nbt = (NbtCompound) nbt.get("denkmalblock");//nimmt den denkmalblocknbt und laedt diesen if (nbt == null) { //sollte der nbt noch nicht existieren wird er erstellt nbt = new NbtCompound(); } @@ -37,4 +45,40 @@ public class denkMalBlockUtil extends dataSaverIO{ reServerNbt.put("denkmalblock", nbt); //schreibt den denkmalblock nbt ab writeToNbt(reServerNbt); //schreibt den editierten reServerNbt } + + public boolean allowBlocks(World world, PlayerEntity player, BlockPos pos) { + if (world.getRegistryKey() == World.OVERWORLD) { + if (!player.isCreative()) { + NbtCompound nbt = returnLoadedNbt(); + Set set = nbt.getKeys(); + String[] keys = set.toArray(new String[0]);//erzeugt einen String-Array mit allen keys + + for (String key : keys) { + if (inRange((NbtCompound) nbt.get(key), pos)) { + if (!world.isClient) { + player.sendMessage(Text.of("Can't change Blocks here! This area is protected!")); + } + return false; + } + } + } + } + return true; + } + + private boolean inRange(NbtCompound nbt, BlockPos pos) { + int[] denkPos = nbt.getIntArray("position"); + int[] denkRange = nbt.getIntArray("range"); + int[] blockPos = new int[3]; + blockPos[0] = pos.getX(); + blockPos[1] = pos.getY(); + blockPos[2] = pos.getZ(); + for(int i = 0; i < 3; i++) { + int dif = (denkPos[i] - blockPos[i]); + if (abs(dif) > denkRange[i]) { + return false; + } + } + return true; + } } diff --git a/src/main/java/modchest/util/initializer.java b/src/main/java/modchest/util/initializer.java index 5c11196..7ad0cb5 100644 --- a/src/main/java/modchest/util/initializer.java +++ b/src/main/java/modchest/util/initializer.java @@ -3,10 +3,12 @@ package modchest.util; import modchest.block.entity.modBlockEntities; import modchest.block.modBlocks; import modchest.event.playerAfterRespawnEvent; +import modchest.event.playerBreakBlockEvents; import modchest.item.modItemGroup; import modchest.item.modItems; import modchest.networking.modNetworkingServer; import net.fabricmc.fabric.api.entity.event.v1.ServerPlayerEvents; +import net.fabricmc.fabric.api.event.player.PlayerBlockBreakEvents; public class initializer { public static void itemGroups() { @@ -22,6 +24,7 @@ public class initializer { public static void events() { //Events, bei denen custom Code ausgefuehrt wird, werden eingefuehrt ServerPlayerEvents.AFTER_RESPAWN.register(new playerAfterRespawnEvent()); + PlayerBlockBreakEvents.BEFORE.register(new playerBreakBlockEvents()); } public static void networking() { //Identifier unter denen der Server zuhoert werden registriert diff --git a/src/main/resources/reservermod.mixins.json b/src/main/resources/reservermod.mixins.json index f8038fc..c132e08 100644 --- a/src/main/resources/reservermod.mixins.json +++ b/src/main/resources/reservermod.mixins.json @@ -4,8 +4,11 @@ "compatibilityLevel": "JAVA_17", "mixins": [ "bedBlockMixin", + "flintAndSteelItemMixin", + "itemMixin", "LevelStorageMixin", "MinecraftServerMixin", + "playerPlaceBlockMixin", "ServerPlayerEntityMixin" ], "injectors": {