Skip to content

Commit

Permalink
add playerOperationLimiter
Browse files Browse the repository at this point in the history
  • Loading branch information
plusls committed Sep 5, 2021
1 parent 6180b7c commit be4295a
Show file tree
Hide file tree
Showing 9 changed files with 165 additions and 1 deletion.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ carpet >= 1.4.45+v210811
- [白天睡觉](#白天睡觉-sleepingDuringTheDay)
- [发射器修复铁傀儡](#发射器修复铁傀儡-dispenserFixIronGolem)
- [发射器收集经验](#发射器收集经验-dispenserCollectXp)
- [玩家操作限制器](#玩家操作限制器-playerOperationLimiter)
- [PCA 调试模式](#PCA-调试模式-pcaDebug)

## 规则列表
Expand Down Expand Up @@ -232,6 +233,15 @@ Carpet 默认实现的潜影盒可堆叠只能让潜影盒在地面上堆叠,
- 参考选项: `true`, `false`
- 分类: `PCA`, `feature`, `dispenser`

### 玩家操作限制器 (playerOperationLimiter)

每 gt 玩家可以放置 2 个方块,秒破 1 个方块,这两个操作每 gt 只能做一种(用于防人肉盾构机和玩家自动破基岩 mod)

- 类型: `boolean`
- 默认值: `false`
- 参考选项: `true`, `false`
- 分类: `PCA`, `feature`

### PCA 调试模式 (pcaDebug)

开启后会打印调试信息
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ loader_version=0.11.6
# carpet_core_version=1.4.45+v210811
carpet_core_version=3422601
# Mod Properties
mod_version=0.2.0
mod_version=0.2.1
maven_group=net.fabricmc
archives_base_name=plusls-carpet-addition
# Dependencies
Expand Down
6 changes: 6 additions & 0 deletions src/main/java/com/plusls/carpet/PcaSettings.java
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,12 @@ public enum PCA_SPAWN_BIOME {
)
public static boolean dispenserCollectXp = false;

@Rule(
desc = "One tick player can place 2 block, insta break 1 block, can't do it at the same tick",
category = {PCA, RuleCategory.FEATURE}
)
public static boolean playerOperationLimiter = false;

// debug
@Rule(
desc = "pcaDebug mode",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package com.plusls.carpet.mixin.rule.playerOperationLimiter;

import com.plusls.carpet.PcaSettings;
import com.plusls.carpet.util.rule.playerOperationLimiter.SafeServerPlayerEntity;
import net.minecraft.block.BlockState;
import net.minecraft.item.BlockItem;
import net.minecraft.item.Item;
import net.minecraft.item.ItemPlacementContext;
import net.minecraft.util.ActionResult;
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(BlockItem.class)
public abstract class MixinBlockItem extends Item {
public MixinBlockItem(Settings settings) {
super(settings);
}

@Shadow
public abstract ItemPlacementContext getPlacementContext(ItemPlacementContext context);

@Shadow
protected abstract BlockState getPlacementState(ItemPlacementContext context);

@Inject(method = "place(Lnet/minecraft/item/ItemPlacementContext;)Lnet/minecraft/util/ActionResult;", at = @At(value = "HEAD"), cancellable = true)
private void checkOperationCountPerTick(ItemPlacementContext context, CallbackInfoReturnable<ActionResult> cir) {
if (!PcaSettings.playerOperationLimiter || context.getWorld().isClient()) {
return;
}

if (context.canPlace()) {
ItemPlacementContext itemPlacementContext = this.getPlacementContext(context);
SafeServerPlayerEntity safeServerPlayerEntity = (SafeServerPlayerEntity) context.getPlayer();
if (safeServerPlayerEntity != null && itemPlacementContext != null && this.getPlacementState(itemPlacementContext) != null) {
safeServerPlayerEntity.addPlaceBlockCountPerTick();
if (!safeServerPlayerEntity.allowOperation()) {
cir.setReturnValue(ActionResult.FAIL);
}
}

}

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.plusls.carpet.mixin.rule.playerOperationLimiter;

import com.plusls.carpet.util.rule.playerOperationLimiter.SafeServerPlayerEntity;
import net.minecraft.server.network.ServerPlayerEntity;
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(ServerPlayerEntity.class)
public class MixinServerPlayerEntity implements SafeServerPlayerEntity {
private int instaBreakCountPerTick = 0;
private int placeBlockCountPerTick = 0;

@Inject(method = "tick", at = @At(value = "HEAD"))
private void resetOperationCountPerTick(CallbackInfo ci) {
instaBreakCountPerTick = 0;
placeBlockCountPerTick = 0;
}

@Override
public int getInstaBreakCountPerTick() {
return instaBreakCountPerTick;
}

@Override
public int getPlaceBlockCountPerTick() {
return placeBlockCountPerTick;
}

@Override
public void addInstaBreakCountPerTick() {
++instaBreakCountPerTick;
}

@Override
public void addPlaceBlockCountPerTick() {
++placeBlockCountPerTick;
}

@Override
public boolean allowOperation() {
return (instaBreakCountPerTick == 0 || placeBlockCountPerTick == 0) && (instaBreakCountPerTick <= 1 && placeBlockCountPerTick <= 2);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.plusls.carpet.mixin.rule.playerOperationLimiter;

import com.plusls.carpet.PcaSettings;
import com.plusls.carpet.util.rule.playerOperationLimiter.SafeServerPlayerEntity;
import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket;
import net.minecraft.network.packet.s2c.play.PlayerActionResponseS2CPacket;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.network.ServerPlayerInteractionManager;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
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.CallbackInfo;

@Mixin(ServerPlayerInteractionManager.class)
public class MixinServerPlayerInteractionManager {

@Final
@Shadow
protected ServerPlayerEntity player;

@Shadow
protected ServerWorld world;

@Inject(method = "processBlockBreakingAction", at=@At(value = "INVOKE", target = "Lnet/minecraft/server/network/ServerPlayerInteractionManager;finishMining(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/network/packet/c2s/play/PlayerActionC2SPacket$Action;Ljava/lang/String;)V", ordinal = 1), cancellable = true)
private void checkOperationCountPerTick(BlockPos pos, PlayerActionC2SPacket.Action action, Direction direction, int worldHeight, CallbackInfo ci) {
if (!PcaSettings.playerOperationLimiter) {
return;
}
SafeServerPlayerEntity safeServerPlayerEntity = (SafeServerPlayerEntity)player;
safeServerPlayerEntity.addInstaBreakCountPerTick();
if (!safeServerPlayerEntity.allowOperation()) {
this.player.networkHandler.sendPacket(new PlayerActionResponseS2CPacket(pos, this.world.getBlockState(pos), action, false, "insta mine"));
ci.cancel();
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.plusls.carpet.util.rule.playerOperationLimiter;

public interface SafeServerPlayerEntity {
int getInstaBreakCountPerTick();
int getPlaceBlockCountPerTick();
void addInstaBreakCountPerTick();
void addPlaceBlockCountPerTick();
boolean allowOperation();
}
2 changes: 2 additions & 0 deletions src/main/resources/assets/pca/lang/zh_cn.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@
"rule.dispenserFixIronGolem.desc": "发射器可以使用铁锭来修复铁傀儡",
"rule.dispenserCollectXp.name": "发射器收集经验",
"rule.dispenserCollectXp.desc": "发射器消耗玻璃瓶来收集经验,产出附魔之瓶",
"rule.playerOperationLimiter.name": "玩家操作限制器",
"rule.playerOperationLimiter.desc": "每 gt 玩家可以放置 2 个方块,秒破 1 个方块,这两个操作每 gt 只能做一种(用于防人肉盾构机和玩家自动破基岩 mod)",
"rule.pcaDebug.name": "PCA调试模式",
"rule.pcaDebug.desc": "打印更多调试信息"
}
Expand Down
3 changes: 3 additions & 0 deletions src/main/resources/pca.mixins.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
"rule.flippingTotemOfUndying.MixinBlockRotator",
"rule.gravestone.MixinPlayerSkullBlock",
"rule.gravestone.MixinSkullBlockEntity",
"rule.playerOperationLimiter.MixinBlockItem",
"rule.playerOperationLimiter.MixinServerPlayerEntity",
"rule.playerOperationLimiter.MixinServerPlayerInteractionManager",
"rule.pcaSyncProtocol.block.MixinAbstractFurnaceBlockEntity",
"rule.pcaSyncProtocol.block.MixinBarrelBlockEntity",
"rule.pcaSyncProtocol.block.MixinBeehiveBlockEntity",
Expand Down

0 comments on commit be4295a

Please sign in to comment.