Skip to content

Commit

Permalink
add: anti build module + update: github wiki
Browse files Browse the repository at this point in the history
  • Loading branch information
sakurawald committed Jul 13, 2024
1 parent 393d9e7 commit 4e6bad9
Show file tree
Hide file tree
Showing 10 changed files with 300 additions and 46 deletions.
2 changes: 1 addition & 1 deletion fuji-fabric.wiki
3 changes: 1 addition & 2 deletions src/main/java/io/github/sakurawald/Fuji.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,10 @@
// TODO: invsee module
// TODO: condense module
// TODO: use aop style
// TODO: a program to generate module reference DAG
// TODO: powertool module
// TODO: refactor chat module to use prefix/suffix metas

// TODO: add anti build module -> place, use, break, piston. (facility: alert, permission, black/white list)
// TODO: a program to generate module reference DAG

public class Fuji implements ModInitializer {
public static final String MOD_ID = "fuji";
Expand Down
80 changes: 78 additions & 2 deletions src/main/java/io/github/sakurawald/config/model/ConfigModel.java
Original file line number Diff line number Diff line change
Expand Up @@ -878,7 +878,7 @@ public class OverridePower {
For a max level of enchant table, it requires 15 power providers.""")
public int power_provider_amount = 15;
}

}

@Documentation("This module provides `/anvil` command.")
Expand Down Expand Up @@ -1003,9 +1003,85 @@ public class Protect {
}

public AntiBuild anti_build = new AntiBuild();

@Documentation("""
This module provides anti-build purpose.
Use-case: ban some item/block/entity
Anti types:
- break_block
- place_block
- interact_item
- interact_block
- interact_entity
For example, let's say you want to ban TNT:
1. add `minecraft:tnt` into `place_block` list
And it's done.
Use `/lp user <player> permission set fuji.anti_build.place_block.bypass.minecraft:tnt` to
allow a player place the tnt.
""")
public class AntiBuild {
public boolean enable = false;
}

public Anti anti = new Anti();

public class Anti {

public Break break_block = new Break();

public class Break {
public Set<String> id = new HashSet<>() {
{
this.add("minecraft:gold_block");
}
};
}

public Place place_block = new Place();

public class Place {
public Set<String> id = new HashSet<>() {
{
this.add("minecraft:tnt");
}
};
}

public InteractItem interact_item = new InteractItem();

public class InteractItem {
public Set<String> id = new HashSet<>() {
{
this.add("minecraft:lava_bucket");
}
};
}

public InteractBlock interact_block = new InteractBlock();

public class InteractBlock {
public Set<String> id = new HashSet<>() {
{
this.add("minecraft:lever");
}
};
}

public InteractEntity interact_entity = new InteractEntity();
public class InteractEntity {
public Set<String> id = new HashSet<>() {
{
this.add("minecraft:villager");
}
};

}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package io.github.sakurawald.module.mixin.anti_build;

import io.github.sakurawald.config.Configs;
import io.github.sakurawald.util.IdentifierUtil;
import io.github.sakurawald.util.MessageUtil;
import me.lucko.fabric.api.permissions.v0.Permissions;
import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.BlockItem;
import net.minecraft.item.ItemPlacementContext;
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.CallbackInfoReturnable;

@Mixin(BlockItem.class)
public class BlockMixin {

@Inject(method = "canPlace", at = @At("RETURN"), cancellable = true)
public void $canPlace(ItemPlacementContext itemPlacementContext, BlockState blockState, CallbackInfoReturnable<Boolean> cir) {
PlayerEntity player = itemPlacementContext.getPlayer();
if (player == null) return;

String id = IdentifierUtil.getItemStackIdentifier(itemPlacementContext.getStack());
if (Configs.configHandler.model().modules.anti_build.anti.place_block.id.contains(id)
&& !Permissions.check(player, "fuji.anti_build.%s.bypass.%s".formatted("place_block", id))
) {
MessageUtil.sendMessageToPlayerEntity(player, "anti_build.disallow");
cir.setReturnValue(false);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package io.github.sakurawald.module.mixin.anti_build;

import io.github.sakurawald.config.Configs;
import io.github.sakurawald.util.IdentifierUtil;
import io.github.sakurawald.util.MessageUtil;
import lombok.extern.slf4j.Slf4j;
import me.lucko.fabric.api.permissions.v0.Permissions;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.math.Vec3d;
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.CallbackInfoReturnable;


@Mixin(Entity.class)
public class EntityMixin {
@Inject(method = "interact", at = @At("HEAD"), cancellable = true)
void $interact(PlayerEntity player, Hand hand, CallbackInfoReturnable<ActionResult> cir){
Entity entity = (Entity) (Object) this;
String id = IdentifierUtil.getEntityTypeIdentifier(entity);

if (Configs.configHandler.model().modules.anti_build.anti.interact_entity.id.contains(id)
&& !Permissions.check(player, "fuji.anti_build.%s.bypass.%s".formatted("interact_entity", id))
) {

if (hand == Hand.MAIN_HAND) {
MessageUtil.sendMessageToPlayerEntity(player, "anti_build.disallow");
}

cir.setReturnValue(ActionResult.FAIL);
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package io.github.sakurawald.module.mixin.anti_build;

import io.github.sakurawald.config.Configs;
import io.github.sakurawald.util.IdentifierUtil;
import io.github.sakurawald.util.MessageUtil;
import me.lucko.fabric.api.permissions.v0.Permissions;
import net.minecraft.block.BlockState;
import net.minecraft.item.ItemStack;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.network.ServerPlayerInteractionManager;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import org.spongepowered.asm.mixin.Final;
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.CallbackInfoReturnable;

@Mixin(ServerPlayerInteractionManager.class)
public class ServerPlayerInteractionManagerMixin {

@Shadow
protected ServerWorld world;

@Shadow
@Final
protected ServerPlayerEntity player;

@Inject(method = "tryBreakBlock", at = @At("HEAD"), cancellable = true)
void $tryBreak(BlockPos blockPos, CallbackInfoReturnable<Boolean> cir) {
BlockState blockState = this.world.getBlockState(blockPos);

String id = IdentifierUtil.getBlockStateIdentifier(blockState);
if (Configs.configHandler.model().modules.anti_build.anti.break_block.id.contains(id)
&& !Permissions.check(player, "fuji.anti_build.%s.bypass.%s".formatted("break_block", id))
) {
MessageUtil.sendMessage(player, "anti_build.disallow");
cir.setReturnValue(false);
}

}

@Inject(method = "interactItem", at = @At("HEAD"), cancellable = true)
void $interactItem(ServerPlayerEntity serverPlayerEntity, World world, ItemStack itemStack, Hand hand, CallbackInfoReturnable<ActionResult> cir) {
String id = IdentifierUtil.getItemStackIdentifier(itemStack);

if (Configs.configHandler.model().modules.anti_build.anti.interact_item.id.contains(id)
&& !Permissions.check(player, "fuji.anti_build.%s.bypass.%s".formatted("interact_item", id))
) {
MessageUtil.sendMessage(player, "anti_build.disallow");
cir.setReturnValue(ActionResult.FAIL);
}
}

@Inject(method = "interactBlock", at = @At("HEAD"), cancellable = true)
void $interactBlock(ServerPlayerEntity serverPlayerEntity, World world, ItemStack itemStack, Hand hand, BlockHitResult blockHitResult, CallbackInfoReturnable<ActionResult> cir) {
BlockPos blockPos = blockHitResult.getBlockPos();
BlockState blockState = world.getBlockState(blockPos);
String id = IdentifierUtil.getBlockStateIdentifier(blockState);

if (Configs.configHandler.model().modules.anti_build.anti.interact_block.id.contains(id)
&& !Permissions.check(player, "fuji.anti_build.%s.bypass.%s".formatted("interact_block", id))
) {
MessageUtil.sendMessage(player, "anti_build.disallow");
cir.setReturnValue(ActionResult.FAIL);
}
}

}
30 changes: 30 additions & 0 deletions src/main/java/io/github/sakurawald/util/IdentifierUtil.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package io.github.sakurawald.util;

import lombok.experimental.UtilityClass;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.entity.Entity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.registry.Registries;

@UtilityClass
public class IdentifierUtil {

public static String getItemStackIdentifier(ItemStack itemStack) {
Item item = itemStack.getItem().asItem();
return Registries.ITEM.getId(item).toString();
}

public static String getBlockStateIdentifier(BlockState blockState) {
return getBlockIdentifier(blockState.getBlock());
}

public static String getBlockIdentifier(Block block) {
return Registries.BLOCK.getId(block).toString();
}
public static String getEntityTypeIdentifier(Entity entity) {
return Registries.ENTITY_TYPE.getId(entity.getType()).toString();
}

}
3 changes: 2 additions & 1 deletion src/main/resources/assets/fuji/lang/en_us.json
Original file line number Diff line number Diff line change
Expand Up @@ -176,5 +176,6 @@
"chat.current_pos": "Current Position",
"chat.xaero_waypoint_add": "Click to add a Xaero's minimap waypoint",
"chat.xaero_waypoint_add.command": "/xaero_waypoint_add:Waypoint:·:%d:%s:%d:0:false:0:Internal_%s_waypoints",
"realname": "<gold>Real name is %s"
"realname": "<gold>Real name is %s",
"anti_build.disallow": "<red> This action is canceled by anti build."
}
3 changes: 2 additions & 1 deletion src/main/resources/assets/fuji/lang/zh_cn.json
Original file line number Diff line number Diff line change
Expand Up @@ -176,5 +176,6 @@
"chat.current_pos": "当前位置",
"chat.xaero_waypoint_add": "点击添加小地图路径点",
"chat.xaero_waypoint_add.command": "/xaero_waypoint_add:路径点:·:%d:%s:%d:0:false:0:Internal_%s_waypoints",
"realname": "<gold>Real name is %s"
"realname": "<gold>Real name is %s",
"anti_build.disallow": "<red> This action is disallow by anti build."
}
Loading

0 comments on commit 4e6bad9

Please sign in to comment.