From aa35b3cb8ae76de0bbe63d7f4cbb3440d865469f Mon Sep 17 00:00:00 2001 From: 1whohears <1whohears28@gmail.com> Date: Tue, 12 Nov 2024 23:05:11 -0600 Subject: [PATCH 01/17] added some new optional features to the config including offline only protection mode, max destroy blocks rate, living entity attack blacklist tag, and more --- .../dev/ftb/mods/ftbchunks/FTBChunks.java | 29 ++- .../ftb/mods/ftbchunks/FTBChunksExpected.java | 5 + .../mods/ftbchunks/FTBChunksWorldConfig.java | 5 + .../ftb/mods/ftbchunks/data/FTBChunksAPI.java | 2 + .../ftbchunks/data/FTBChunksTeamData.java | 166 +++++++++++++++++- .../ftb/mods/ftbchunks/data/Protection.java | 89 ++++++++++ .../assets/ftbchunks/lang/en_us.json | 6 +- .../living_entity_attack_blacklist.json | 9 + .../fabric/FTBChunksExpectedImpl.java | 6 +- .../forge/FTBChunksExpectedImpl.java | 6 +- 10 files changed, 313 insertions(+), 10 deletions(-) create mode 100644 common/src/main/resources/data/ftbchunks/tags/entity_types/living_entity_attack_blacklist.json diff --git a/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunks.java b/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunks.java index f22fe090..644bfea7 100644 --- a/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunks.java +++ b/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunks.java @@ -36,6 +36,7 @@ import net.minecraft.server.level.ServerPlayer; import net.minecraft.stats.Stats; import net.minecraft.world.InteractionHand; +import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.MobSpawnType; @@ -118,10 +119,11 @@ public FTBChunks() { PlayerEvent.FILL_BUCKET.register(this::fillBucket); PlayerEvent.PLAYER_CLONE.register(this::playerCloned); PlayerEvent.CHANGE_DIMENSION.register(this::playerChangedDimension); - PlayerEvent.ATTACK_ENTITY.register(this::playerAttackEntity); + PlayerEvent.ATTACK_ENTITY.register(this::playerAttackNonLivingEntity); EntityEvent.ENTER_SECTION.register(this::enterSection); EntityEvent.LIVING_CHECK_SPAWN.register(this::checkSpawn); + EntityEvent.LIVING_HURT.register(this::livingEntityHurt); ExplosionEvent.DETONATE.register(this::explosionDetonate); @@ -137,7 +139,7 @@ public FTBChunks() { } } - private EventResult playerAttackEntity(Player player, Level level, Entity entity, InteractionHand interactionHand, @Nullable EntityHitResult entityHitResult) { + private EventResult playerAttackNonLivingEntity(Player player, Level level, Entity entity, InteractionHand interactionHand, @Nullable EntityHitResult entityHitResult) { // note: intentionally does not prevent attacking living entities; // this is for preventing griefing of entities like paintings & item frames if (player instanceof ServerPlayer && !(entity instanceof LivingEntity) && FTBChunksAPI.getManager().protect(player, interactionHand, entity.blockPosition(), Protection.ATTACK_NONLIVING_ENTITY, entity)) { @@ -147,6 +149,22 @@ private EventResult playerAttackEntity(Player player, Level level, Entity entity return EventResult.pass(); } + private EventResult livingEntityHurt(LivingEntity livingEntity, DamageSource damageSource, float damage) { + if (livingEntity.level.isClientSide || !FTBChunksAPI.isManagerLoaded()) return EventResult.pass(); + if (damageSource.getEntity() instanceof ServerPlayer player) { + if (FTBChunksAPI.getManager().protect(player, player.swingingArm, livingEntity.blockPosition(), Protection.ATTACK_LIVING_ENTITY, livingEntity)) { + return EventResult.interruptFalse(); + } + } else if (livingEntity.getType().is(FTBChunksAPI.LIVING_ENTITY_ATTACK_BLACKLIST_TAG)) { // this block protects the entities from unknown sources + ClaimedChunk chunk = FTBChunksAPI.getManager().getChunk(new ChunkDimPos(livingEntity.level, livingEntity.blockPosition())); + if (chunk != null) { + return EventResult.interruptFalse(); + } + } + + return EventResult.pass(); + } + private void playerTickPost(Player player) { if (player.level.isClientSide && player.level.getGameTime() % 20 == 0) { FTBChunks.PROXY.maybeClearDeathpoint(player); @@ -234,6 +252,8 @@ public void loggedOut(ServerPlayer player) { // last player on the team to log out; unforce chunks if the team can't do offline chunk-loading data.updateChunkTickets(false); } + + data.setLastLogoffTime(System.currentTimeMillis()); } private void teamCreated(TeamCreatedEvent teamEvent) { @@ -251,10 +271,9 @@ private void teamSaved(TeamEvent teamEvent) { public EventResult blockLeftClick(Player player, InteractionHand hand, BlockPos pos, Direction face) { // calling architectury stub method //noinspection ConstantConditions - if (player instanceof ServerPlayer && FTBChunksAPI.getManager().protect(player, hand, pos, FTBChunksExpected.getBlockBreakProtection(), null)) { + if (player instanceof ServerPlayer && FTBChunksAPI.getManager().protect(player, hand, pos, FTBChunksExpected.getBlockLeftClickProtection(), null)) { return EventResult.interruptFalse(); } - return EventResult.pass(); } @@ -291,7 +310,6 @@ public EventResult blockBreak(Level level, BlockPos pos, BlockState blockState, if (FTBChunksAPI.getManager().protect(player, InteractionHand.MAIN_HAND, pos, FTBChunksExpected.getBlockBreakProtection(), null)) { return EventResult.interruptFalse(); } - return EventResult.pass(); } @@ -436,6 +454,7 @@ private void teamConfig(TeamCollectPropertiesEvent event) { event.add(FTBChunksTeamData.ALLOW_ALL_FAKE_PLAYERS); event.add(FTBChunksTeamData.ALLOW_NAMED_FAKE_PLAYERS); event.add(FTBChunksTeamData.ALLOW_FAKE_PLAYERS_BY_ID); + event.add(FTBChunksTeamData.ALLOW_ATTACK_BLACKLISTED_ENTITIES); // block edit/interact properties vary on forge & fabric FTBChunksExpected.getPlatformSpecificProperties(event); diff --git a/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksExpected.java b/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksExpected.java index bc80b72f..2dfc4789 100644 --- a/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksExpected.java +++ b/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksExpected.java @@ -34,4 +34,9 @@ public static Protection getBlockInteractProtection() { public static Protection getBlockBreakProtection() { throw new AssertionError(); } + + @ExpectPlatform + public static Protection getBlockLeftClickProtection() { + throw new AssertionError(); + } } diff --git a/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksWorldConfig.java b/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksWorldConfig.java index cadc1690..7547e230 100644 --- a/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksWorldConfig.java +++ b/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksWorldConfig.java @@ -38,6 +38,11 @@ public interface FTBChunksWorldConfig { EnumValue PARTY_LIMIT_MODE = CONFIG.getEnum("party_limit_mode", PartyLimitMode.NAME_MAP).comment("Method by which party claim & force-load limits are calculated.","LARGEST: use the limits of the member with the largest limits","SUM: add up all the members' limits","OWNER: use the party owner's limits only","AVERAGE: use the average of all members' limits."); BooleanValue REQUIRE_GAME_STAGE = CONFIG.getBoolean("require_game_stage", false).comment("If true, the player must have the 'ftbchunks_mapping' Game stage to be able to use the map and minimap.\nRequires KubeJS and/or Gamestages to be installed."); BooleanValue LOCATION_MODE_OVERRIDE = CONFIG.getBoolean("location_mode_override", false).comment("If true, \"Location Visibility\" team settings are ignored, and all players can see each other anywhere on the map."); + BooleanValue OFFLINE_PROTECTION_ONLY = CONFIG.getBoolean("offline_protection_only", false).comment("If enabled and disable_protection = false enemy players will ONLY be able to damage your claimed chunks if you or your team mates are online."); + IntValue OFFLINE_PROTECTION_BUFFER = CONFIG.getInt("offline_protection_buffer", 30).comment("If offline_protection_only = true, the time in SECONDS after all members of a team log off, before chunk protection turns on. This setting is meant to discourage combat logging. Set to 0 to disable. Set to -1 for unlimited block breaking if offline_protection_only = true."); + IntValue MAX_DESTROY_BLOCKS_PER_HOUR = CONFIG.getInt("max_destroy_blocks_per_hour", 0).comment("If disable_protection = false, this many blocks can still be destroyed per hour be enemy players. 0 disables this."); + IntValue DESTROY_BLOCKS_COUNT_PERIOD = CONFIG.getInt("destroy_blocks_count_period", 300).comment("If max_destroy_blocks_per_hour > 0, the groups of time in seconds where the number of blocks broken are counted. Groups younger than an hour contribute to the total blocks broken. Groups older than an hour are removed."); + BooleanValue PROTECT_ENTITIES_OFFLINE_ONLY = CONFIG.getBoolean("protect_entities_offline_only", true).comment("Only protect the living entities listed in the living_entity_attack_blacklist tag when all team members are offline."); static int getMaxClaimedChunks(FTBChunksTeamData playerData, ServerPlayer player) { if (player != null) { diff --git a/common/src/main/java/dev/ftb/mods/ftbchunks/data/FTBChunksAPI.java b/common/src/main/java/dev/ftb/mods/ftbchunks/data/FTBChunksAPI.java index 8d05259e..74d51c95 100644 --- a/common/src/main/java/dev/ftb/mods/ftbchunks/data/FTBChunksAPI.java +++ b/common/src/main/java/dev/ftb/mods/ftbchunks/data/FTBChunksAPI.java @@ -22,10 +22,12 @@ */ public class FTBChunksAPI { public static final TagKey EDIT_WHITELIST_TAG = TagKey.create(Registry.BLOCK_REGISTRY, new ResourceLocation(FTBChunks.MOD_ID, "edit_whitelist")); + public static final TagKey EDIT_BLACKLIST_TAG = TagKey.create(Registry.BLOCK_REGISTRY, new ResourceLocation(FTBChunks.MOD_ID, "edit_blacklist")); public static final TagKey INTERACT_WHITELIST_TAG = TagKey.create(Registry.BLOCK_REGISTRY, new ResourceLocation(FTBChunks.MOD_ID, "interact_whitelist")); public static final TagKey RIGHT_CLICK_BLACKLIST_TAG = TagKey.create(Registry.ITEM_REGISTRY, new ResourceLocation(FTBChunks.MOD_ID, "right_click_blacklist")); public static final TagKey RIGHT_CLICK_WHITELIST_TAG = TagKey.create(Registry.ITEM_REGISTRY, new ResourceLocation(FTBChunks.MOD_ID, "right_click_whitelist")); public static final TagKey> ENTITY_INTERACT_WHITELIST_TAG = TagKey.create(Registry.ENTITY_TYPE_REGISTRY, new ResourceLocation(FTBChunks.MOD_ID, "entity_interact_whitelist")); + public static final TagKey> LIVING_ENTITY_ATTACK_BLACKLIST_TAG = TagKey.create(Registry.ENTITY_TYPE_REGISTRY, new ResourceLocation(FTBChunks.MOD_ID, "living_entity_attack_blacklist")); public static final TagKey> NONLIVING_ENTITY_ATTACK_WHITELIST_TAG = TagKey.create(Registry.ENTITY_TYPE_REGISTRY, new ResourceLocation(FTBChunks.MOD_ID, "nonliving_entity_attack_whitelist")); public static final TicketType FORCE_LOADED_TICKET = TicketType.create(FTBChunks.MOD_ID + ":force_loaded", Comparator.comparingLong(ChunkPos::toLong)); diff --git a/common/src/main/java/dev/ftb/mods/ftbchunks/data/FTBChunksTeamData.java b/common/src/main/java/dev/ftb/mods/ftbchunks/data/FTBChunksTeamData.java index 9d8ddb9f..08b1d71f 100644 --- a/common/src/main/java/dev/ftb/mods/ftbchunks/data/FTBChunksTeamData.java +++ b/common/src/main/java/dev/ftb/mods/ftbchunks/data/FTBChunksTeamData.java @@ -28,6 +28,8 @@ import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.ListTag; import net.minecraft.nbt.Tag; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.Style; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.MinecraftServer; @@ -59,6 +61,8 @@ public class FTBChunksTeamData { public static final BooleanProperty ALLOW_MOB_GRIEFING = new BooleanProperty(new ResourceLocation(FTBChunks.MOD_ID, "allow_mob_griefing"), false); public static final PrivacyProperty CLAIM_VISIBILITY = new PrivacyProperty(new ResourceLocation(FTBChunks.MOD_ID, "claim_visibility"), PrivacyMode.PUBLIC); + public static final PrivacyProperty ALLOW_ATTACK_BLACKLISTED_ENTITIES = new PrivacyProperty(new ResourceLocation(FTBChunks.MOD_ID, "allow_attack_blacklisted_entities"), PrivacyMode.ALLIES); + // public static final PrivacyProperty MINIMAP_MODE = new PrivacyProperty(new ResourceLocation(FTBChunks.MOD_ID, "minimap_mode"), PrivacyMode.ALLIES); public static final PrivacyProperty LOCATION_MODE = new PrivacyProperty(new ResourceLocation(FTBChunks.MOD_ID, "location_mode"), PrivacyMode.ALLIES); @@ -76,7 +80,9 @@ public class FTBChunksTeamData { public int prevChunkX = Integer.MAX_VALUE, prevChunkZ = Integer.MAX_VALUE; public String lastChunkID = ""; private long lastLoginTime; + private long lastLogoffTime; private Set fakePlayerNameCache; + private final BrokenBlocksCounter brokenBlocksCounter; public FTBChunksTeamData(ClaimedChunkManager m, Path f, Team t) { manager = m; @@ -88,7 +94,9 @@ public FTBChunksTeamData(ClaimedChunkManager m, Path f, Team t) { extraClaimChunks = 0; extraForceLoadChunks = 0; lastLoginTime = 0L; + lastLogoffTime = 0L; memberData = new HashMap<>(); + brokenBlocksCounter = new BrokenBlocksCounter(); } @Override @@ -282,7 +290,7 @@ public boolean isAlly(UUID p) { return team.isAlly(p); } - public boolean canUse(ServerPlayer p, PrivacyProperty property) { + protected boolean baseUseCheck(ServerPlayer p, PrivacyProperty property, boolean offlineCheck) { PrivacyMode mode = team.getProperty(property); if (mode == PrivacyMode.PUBLIC) { @@ -294,8 +302,41 @@ public boolean canUse(ServerPlayer p, PrivacyProperty property) { } else if (mode == PrivacyMode.ALLIES) { return isAlly(p.getUUID()); } else { - return team.isMember(p.getUUID()); + if (team.isMember(p.getUUID())) return true; + if (offlineCheck && FTBChunksWorldConfig.OFFLINE_PROTECTION_ONLY.get()) { + return canUseOffline(); + } + return false; + } + } + + public boolean canUseOffline() { + if (!team.getOnlineMembers().isEmpty()) { + return true; + } + long buffer = FTBChunksWorldConfig.OFFLINE_PROTECTION_BUFFER.get(); + long now = System.currentTimeMillis(); + long timeDiff = now - getLastLogoffTime(); + return timeDiff < buffer * 1000; + } + + public boolean canUse(ServerPlayer p, PrivacyProperty property) { + return baseUseCheck(p, property, true); + } + + public boolean canAttackBlackListedEntity(ServerPlayer p, PrivacyProperty property) { + if (baseUseCheck(p, property, true)) return true; + return FTBChunksWorldConfig.PROTECT_ENTITIES_OFFLINE_ONLY.get() && canUseOffline(); + } + + public boolean canBreak(ServerPlayer p, PrivacyProperty property, boolean leftClick) { + if (baseUseCheck(p, property, false)) return true; + if (FTBChunksWorldConfig.OFFLINE_PROTECTION_ONLY.get() && !canUseOffline()) return false; + if (brokenBlocksCounter.canBreakBlock(p, leftClick)) { + if (!leftClick) save(); + return true; } + return false; } private boolean canFakePlayerUse(Player player, PrivacyMode mode) { @@ -338,6 +379,7 @@ public SNBTCompoundTag serializeNBT() { if (extraClaimChunks > 0 && !(team instanceof PartyTeam)) tag.putInt("extra_claim_chunks", extraClaimChunks); if (extraForceLoadChunks > 0 && !(team instanceof PartyTeam)) tag.putInt("extra_force_load_chunks", extraForceLoadChunks); tag.putLong("last_login_time", lastLoginTime); + tag.putLong("last_logoff_time", lastLogoffTime); CompoundTag chunksTag = new CompoundTag(); for (ClaimedChunk chunk : getClaimedChunks()) { @@ -356,6 +398,8 @@ public SNBTCompoundTag serializeNBT() { tag.put("member_data", memberTag); } + tag.put("broken_blocks_counter", brokenBlocksCounter.serializeNBT()); + return tag; } @@ -365,6 +409,7 @@ public void deserializeNBT(CompoundTag tag) { extraClaimChunks = tag.getInt("extra_claim_chunks"); extraForceLoadChunks = tag.getInt("extra_force_load_chunks"); lastLoginTime = tag.getLong("last_login_time"); + lastLogoffTime = tag.getLong("last_logoff_time"); canForceLoadChunks = null; CompoundTag chunksTag = tag.getCompound("chunks"); @@ -391,6 +436,8 @@ public void deserializeNBT(CompoundTag tag) { e.printStackTrace(); } } + + brokenBlocksCounter.deserializeNBT(tag.getCompound("broken_blocks_counter")); } public int getExtraClaimChunks() { @@ -494,6 +541,15 @@ public long getLastLoginTime() { return lastLoginTime; } + public long getLastLogoffTime() { + return lastLogoffTime; + } + + public void setLastLogoffTime(long when) { + this.lastLogoffTime = when; + save(); + } + public boolean shouldHideClaims() { return getTeam().getProperty(CLAIM_VISIBILITY) != PrivacyMode.PUBLIC; } @@ -641,4 +697,110 @@ public void deleteMemberData(UUID playerId) { save(); } } + + public static final Style WARNING_STYLE = Style.EMPTY.withColor(0xFFFF55); + public static final int HOUR_TICKS = 60 * 60 * 20; + + public static class BrokenBlocksCounter { + private final List groups = new ArrayList<>(); + public BrokenBlocksCounter() {} + public boolean canBreakBlock(ServerPlayer p, boolean leftClick) { + long time = p.getLevel().getGameTime(); + int blocks_per_hour = FTBChunksWorldConfig.MAX_DESTROY_BLOCKS_PER_HOUR.get(); + if (blocks_per_hour == -1) + return true; + int total = getTotalBrokenBlocks(time); + if (total >= blocks_per_hour) + return false; + if (!leftClick) { + int group_period_tick = FTBChunksWorldConfig.DESTROY_BLOCKS_COUNT_PERIOD.get() * 20; + BrokenBlocksGroup group = getCurrentGroup(time, group_period_tick); + group.addBrokenBlock(); + if (total+1 >= blocks_per_hour) { + p.sendSystemMessage(Component.translatable("ftbchunks.block_break_limit_reached") + .setStyle(WARNING_STYLE)); + } + } + return true; + } + public int getTotalBrokenBlocks(long time) { + removeOldGroups(time); + int total = 0; + for (BrokenBlocksGroup group : groups) + total += group.getBrokenBlocks(); + return total; + } + private BrokenBlocksGroup getCurrentGroup(long time, int length) { + if (groups.isEmpty()) return addGroup(time, length); + BrokenBlocksGroup group = groups.get(0); + if (!group.isCurrentGroup(time)) return addGroup(time, length); + return group; + } + private BrokenBlocksGroup addGroup(long time, int length) { + BrokenBlocksGroup group = new BrokenBlocksGroup(time, length); + groups.add(0, group); + return group; + } + private void removeOldGroups(long time) { + for (int i = 0; i < groups.size(); ++i) + if (groups.get(i).isOutdated(time)) + groups.remove(i--); + } + public SNBTCompoundTag serializeNBT() { + SNBTCompoundTag tag = new SNBTCompoundTag(); + ListTag list = new ListTag(); + for (BrokenBlocksGroup group : groups) list.add(group.serializeNBT()); + tag.put("groups", list); + return tag; + } + public void deserializeNBT(CompoundTag tag) { + ListTag list = tag.getList("groups", 10); + for (int i = 0; i < list.size(); ++i){ + CompoundTag groupNBT = list.getCompound(i); + BrokenBlocksGroup group = new BrokenBlocksGroup(); + group.deserializeNBT(groupNBT); + groups.add(group); + } + } + } + + public static class BrokenBlocksGroup { + private long startTime; + private int brokenBlocks, length; + private BrokenBlocksGroup() {} + public BrokenBlocksGroup(long startTime, int length) { + this.startTime = startTime; + this.length = length; + } + public long getStartTime() { + return startTime; + } + public int getBrokenBlocks() { + return brokenBlocks; + } + public void addBrokenBlock() { + ++brokenBlocks; + } + public int getLength() { + return length; + } + public boolean isOutdated(long time) { + return time - (getStartTime() + getLength()) > HOUR_TICKS; + } + public boolean isCurrentGroup(long time) { + return getStartTime() + getLength() > time; + } + public SNBTCompoundTag serializeNBT() { + SNBTCompoundTag tag = new SNBTCompoundTag(); + tag.putLong("start_time", startTime); + tag.putInt("broken_blocks", brokenBlocks); + tag.putInt("length", length); + return tag; + } + public void deserializeNBT(CompoundTag tag) { + startTime = tag.getLong("start_time"); + brokenBlocks = tag.getInt("broken_blocks"); + length = tag.getInt("length"); + } + } } diff --git a/common/src/main/java/dev/ftb/mods/ftbchunks/data/Protection.java b/common/src/main/java/dev/ftb/mods/ftbchunks/data/Protection.java index 8559ed36..e9192a9b 100644 --- a/common/src/main/java/dev/ftb/mods/ftbchunks/data/Protection.java +++ b/common/src/main/java/dev/ftb/mods/ftbchunks/data/Protection.java @@ -14,6 +14,10 @@ public interface Protection { Protection EDIT_BLOCK = (player, pos, hand, chunk, entity) -> { BlockState blockState = player.level.getBlockState(pos); + if (blockState.is(FTBChunksAPI.EDIT_BLACKLIST_TAG)) { + return ProtectionOverride.CHECK; + } + if (blockState.is(FTBChunksAPI.EDIT_WHITELIST_TAG)) { return ProtectionOverride.ALLOW; } @@ -25,6 +29,42 @@ public interface Protection { return ProtectionOverride.CHECK; }; + Protection BREAK_BLOCK = (player, pos, hand, chunk, entity) -> { + BlockState blockState = player.level.getBlockState(pos); + + if (blockState.is(FTBChunksAPI.EDIT_BLACKLIST_TAG)) { + return ProtectionOverride.CHECK; + } + + if (blockState.is(FTBChunksAPI.EDIT_WHITELIST_TAG)) { + return ProtectionOverride.ALLOW; + } + System.out.println("BREAK_BLOCK "+player); + if (chunk != null && chunk.teamData.canBreak(player, FTBChunksTeamData.BLOCK_EDIT_MODE, false)) { + return ProtectionOverride.ALLOW; + } + + return ProtectionOverride.CHECK; + }; + + Protection LEFT_CLICK_BLOCK = (player, pos, hand, chunk, entity) -> { + BlockState blockState = player.level.getBlockState(pos); + + if (blockState.is(FTBChunksAPI.EDIT_BLACKLIST_TAG)) { + return ProtectionOverride.CHECK; + } + + if (blockState.is(FTBChunksAPI.EDIT_WHITELIST_TAG)) { + return ProtectionOverride.ALLOW; + } + + if (chunk != null && chunk.teamData.canBreak(player, FTBChunksTeamData.BLOCK_EDIT_MODE, true)) { + return ProtectionOverride.ALLOW; + } + + return ProtectionOverride.CHECK; + }; + Protection INTERACT_BLOCK = (player, pos, hand, chunk, entity) -> { BlockState blockState = player.level.getBlockState(pos); @@ -81,10 +121,23 @@ public interface Protection { return ProtectionOverride.CHECK; }; + Protection ATTACK_LIVING_ENTITY = (player, pos, hand, chunk, entity) -> { + if (entity != null && entity.getType().is(FTBChunksAPI.LIVING_ENTITY_ATTACK_BLACKLIST_TAG) + && chunk != null && !chunk.teamData.canAttackBlackListedEntity(player, FTBChunksTeamData.ALLOW_ATTACK_BLACKLISTED_ENTITIES)) { + return ProtectionOverride.CHECK; + } + + return ProtectionOverride.ALLOW; + }; + // for use on Fabric Protection EDIT_AND_INTERACT_BLOCK = (player, pos, hand, chunk, entity) -> { BlockState blockState = player.level.getBlockState(pos); + if (blockState.is(FTBChunksAPI.EDIT_BLACKLIST_TAG)) { + return ProtectionOverride.CHECK; + } + if (blockState.is(FTBChunksAPI.INTERACT_WHITELIST_TAG)) { return ProtectionOverride.ALLOW; } @@ -96,5 +149,41 @@ public interface Protection { return ProtectionOverride.CHECK; }; + Protection BREAK_BLOCK_FABRIC = (player, pos, hand, chunk, entity) -> { + BlockState blockState = player.level.getBlockState(pos); + + if (blockState.is(FTBChunksAPI.EDIT_BLACKLIST_TAG)) { + return ProtectionOverride.CHECK; + } + + if (blockState.is(FTBChunksAPI.INTERACT_WHITELIST_TAG)) { + return ProtectionOverride.ALLOW; + } + + if (chunk != null && chunk.teamData.canBreak(player, FTBChunksTeamData.BLOCK_EDIT_AND_INTERACT_MODE, false)) { + return ProtectionOverride.ALLOW; + } + + return ProtectionOverride.CHECK; + }; + + Protection LEFT_CLICK_BLOCK_FABRIC = (player, pos, hand, chunk, entity) -> { + BlockState blockState = player.level.getBlockState(pos); + + if (blockState.is(FTBChunksAPI.EDIT_BLACKLIST_TAG)) { + return ProtectionOverride.CHECK; + } + + if (blockState.is(FTBChunksAPI.INTERACT_WHITELIST_TAG)) { + return ProtectionOverride.ALLOW; + } + + if (chunk != null && chunk.teamData.canBreak(player, FTBChunksTeamData.BLOCK_EDIT_AND_INTERACT_MODE, true)) { + return ProtectionOverride.ALLOW; + } + + return ProtectionOverride.CHECK; + }; + ProtectionOverride override(ServerPlayer player, BlockPos pos, InteractionHand hand, @Nullable ClaimedChunk chunk, @Nullable Entity entity); } diff --git a/common/src/main/resources/assets/ftbchunks/lang/en_us.json b/common/src/main/resources/assets/ftbchunks/lang/en_us.json index 5514896f..43ebb427 100644 --- a/common/src/main/resources/assets/ftbchunks/lang/en_us.json +++ b/common/src/main/resources/assets/ftbchunks/lang/en_us.json @@ -122,6 +122,8 @@ "ftbteamsconfig.ftbchunks.location_mode.tooltip": "Controls who can see you on the map or minimap (outside the normal vanilla tracking range)", "ftbteamsconfig.ftbchunks.claim_visibility": "Claim Visibility", "ftbteamsconfig.ftbchunks.claim_visibility.tooltip": "Controls who can see your claims on the map or minimap", + "ftbteamsconfig.ftbchunks.allow_attack_blacklisted_entities": "Allow Attack Black Listed Entities", + "ftbteamsconfig.ftbchunks.allow_attack_blacklisted_entities.tooltip": "Allow enemy players to attack living entities the server owner gave protection too. Server owner must enable this setting and modify the entity_attack_blacklist tag.", "ftbchunks.fake_players": "Allow Fake Players", "ftbchunks.fake_players.tooltip": "CHECK: check fake player access like any real player\nDENY: never allow fake players\nALLOW: always allow fake players", "ftbchunks.max_claimed_chunks": "Max Claimed Chunks per Player", @@ -177,5 +179,7 @@ "ftbchunks.claim_result.dimension_forbidden": "Claiming forbidden in this dimension", "ftbchunks.claim_result.not_claimed": "Chunk not claimed", "ftbchunks.claim_result.already_loaded": "Chunk already loaded", - "ftbchunks.claim_result.not_loaded": "Chunk not loaded" + "ftbchunks.claim_result.not_loaded": "Chunk not loaded", + "ftbchunks.cant_break_offline": "You can't break this block while this team is offline!", + "ftbchunks.block_break_limit_reached": "The blocks broken per hour limit for this territory has been reached!" } \ No newline at end of file diff --git a/common/src/main/resources/data/ftbchunks/tags/entity_types/living_entity_attack_blacklist.json b/common/src/main/resources/data/ftbchunks/tags/entity_types/living_entity_attack_blacklist.json new file mode 100644 index 00000000..da9bd3b8 --- /dev/null +++ b/common/src/main/resources/data/ftbchunks/tags/entity_types/living_entity_attack_blacklist.json @@ -0,0 +1,9 @@ +{ + "replace": false, + "values": [ + { + "id": "minecraft:villager", + "required": false + } + ] +} \ No newline at end of file diff --git a/fabric/src/main/java/dev/ftb/mods/ftbchunks/fabric/FTBChunksExpectedImpl.java b/fabric/src/main/java/dev/ftb/mods/ftbchunks/fabric/FTBChunksExpectedImpl.java index 44803677..168e33ab 100644 --- a/fabric/src/main/java/dev/ftb/mods/ftbchunks/fabric/FTBChunksExpectedImpl.java +++ b/fabric/src/main/java/dev/ftb/mods/ftbchunks/fabric/FTBChunksExpectedImpl.java @@ -35,6 +35,10 @@ public static Protection getBlockInteractProtection() { } public static Protection getBlockBreakProtection() { - return Protection.EDIT_AND_INTERACT_BLOCK; + return Protection.BREAK_BLOCK_FABRIC; + } + + public static Protection getBlockLeftClickProtection() { + return Protection.LEFT_CLICK_BLOCK_FABRIC; } } diff --git a/forge/src/main/java/dev/ftb/mods/ftbchunks/forge/FTBChunksExpectedImpl.java b/forge/src/main/java/dev/ftb/mods/ftbchunks/forge/FTBChunksExpectedImpl.java index 15817455..80c0d584 100644 --- a/forge/src/main/java/dev/ftb/mods/ftbchunks/forge/FTBChunksExpectedImpl.java +++ b/forge/src/main/java/dev/ftb/mods/ftbchunks/forge/FTBChunksExpectedImpl.java @@ -29,6 +29,10 @@ public static Protection getBlockInteractProtection() { } public static Protection getBlockBreakProtection() { - return Protection.EDIT_BLOCK; + return Protection.BREAK_BLOCK; + } + + public static Protection getBlockLeftClickProtection() { + return Protection.LEFT_CLICK_BLOCK; } } From 9055b7171149774ec6ed4c52a7501190b6393108 Mon Sep 17 00:00:00 2001 From: 1whohears <1whohears28@gmail.com> Date: Tue, 12 Nov 2024 23:30:21 -0600 Subject: [PATCH 02/17] added reset_block_break_counter admin command --- .../ftb/mods/ftbchunks/FTBChunksCommands.java | 19 +++++++++++++++++++ .../ftbchunks/data/ClaimedChunkManager.java | 4 ++++ .../ftbchunks/data/FTBChunksTeamData.java | 8 ++++++++ 3 files changed, 31 insertions(+) diff --git a/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksCommands.java b/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksCommands.java index fd9499ca..1612c76c 100644 --- a/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksCommands.java +++ b/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksCommands.java @@ -41,6 +41,7 @@ import net.minecraft.util.Mth; import net.minecraft.world.level.Level; import net.minecraft.world.phys.Vec3; +import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.Comparator; @@ -173,6 +174,14 @@ public static void registerCommands(CommandDispatcher dispat .executes(context -> viewLoadedChunks(context.getSource(), DimensionArgument.getDimension(context, "dimension"))) ) ) + .then(Commands.literal("reset_block_break_counter") + .then(Commands.literal("all") + .executes(context -> resetBlockBreakCounter(context.getSource(), null)) + ) + .then(Commands.argument("team", TeamArgument.create()) + .executes(context -> resetBlockBreakCounter(context.getSource(), TeamArgument.get(context, "team"))) + ) + ) ) .then(Commands.literal("block_color") .requires(source -> source.getServer().isSingleplayer()) @@ -505,4 +514,14 @@ private static ColumnPos toColumn(Vec3 pos) { private static Team selfTeam(CommandSourceStack source) throws CommandSyntaxException { return FTBTeamsAPI.getPlayerTeam(source.getPlayerOrException()); } + + private static int resetBlockBreakCounter(CommandSourceStack source, @Nullable Team team) { + if (team == null) { + FTBChunksAPI.getManager().getAllTeamData().forEach(FTBChunksTeamData::resetBrokenBlocksCounter); + } else { + FTBChunksTeamData data = FTBChunksAPI.getManager().getData(team); + data.resetBrokenBlocksCounter(); + } + return 1; + } } diff --git a/common/src/main/java/dev/ftb/mods/ftbchunks/data/ClaimedChunkManager.java b/common/src/main/java/dev/ftb/mods/ftbchunks/data/ClaimedChunkManager.java index cbfefd15..48599959 100644 --- a/common/src/main/java/dev/ftb/mods/ftbchunks/data/ClaimedChunkManager.java +++ b/common/src/main/java/dev/ftb/mods/ftbchunks/data/ClaimedChunkManager.java @@ -267,4 +267,8 @@ public void registerClaim(ChunkDimPos pos, ClaimedChunk chunk) { public void unregisterClaim(ChunkDimPos pos) { claimedChunks.remove(pos); } + + public Collection getAllTeamData() { + return teamData.values(); + } } diff --git a/common/src/main/java/dev/ftb/mods/ftbchunks/data/FTBChunksTeamData.java b/common/src/main/java/dev/ftb/mods/ftbchunks/data/FTBChunksTeamData.java index 08b1d71f..8511daf4 100644 --- a/common/src/main/java/dev/ftb/mods/ftbchunks/data/FTBChunksTeamData.java +++ b/common/src/main/java/dev/ftb/mods/ftbchunks/data/FTBChunksTeamData.java @@ -698,6 +698,11 @@ public void deleteMemberData(UUID playerId) { } } + public void resetBrokenBlocksCounter() { + brokenBlocksCounter.reset(); + save(); + } + public static final Style WARNING_STYLE = Style.EMPTY.withColor(0xFFFF55); public static final int HOUR_TICKS = 60 * 60 * 20; @@ -746,6 +751,9 @@ private void removeOldGroups(long time) { if (groups.get(i).isOutdated(time)) groups.remove(i--); } + public void reset() { + groups.clear(); + } public SNBTCompoundTag serializeNBT() { SNBTCompoundTag tag = new SNBTCompoundTag(); ListTag list = new ListTag(); From ae35cd5640537b03e452f8d075afddb912e0e54f Mon Sep 17 00:00:00 2001 From: 1whohears <1whohears28@gmail.com> Date: Wed, 13 Nov 2024 00:29:16 -0600 Subject: [PATCH 03/17] fixed block black list tag logical error. should only check if on black list after it is known that the player doesn't own those chunks. --- .../ftbchunks/data/FTBChunksTeamData.java | 4 ++- .../ftb/mods/ftbchunks/data/Protection.java | 30 ++++--------------- 2 files changed, 8 insertions(+), 26 deletions(-) diff --git a/common/src/main/java/dev/ftb/mods/ftbchunks/data/FTBChunksTeamData.java b/common/src/main/java/dev/ftb/mods/ftbchunks/data/FTBChunksTeamData.java index 8511daf4..ddf13d1d 100644 --- a/common/src/main/java/dev/ftb/mods/ftbchunks/data/FTBChunksTeamData.java +++ b/common/src/main/java/dev/ftb/mods/ftbchunks/data/FTBChunksTeamData.java @@ -37,6 +37,7 @@ import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.state.BlockState; import org.jetbrains.annotations.NotNull; import java.nio.file.Path; @@ -329,9 +330,10 @@ public boolean canAttackBlackListedEntity(ServerPlayer p, PrivacyProperty proper return FTBChunksWorldConfig.PROTECT_ENTITIES_OFFLINE_ONLY.get() && canUseOffline(); } - public boolean canBreak(ServerPlayer p, PrivacyProperty property, boolean leftClick) { + public boolean canBreak(ServerPlayer p, PrivacyProperty property, boolean leftClick, BlockState state) { if (baseUseCheck(p, property, false)) return true; if (FTBChunksWorldConfig.OFFLINE_PROTECTION_ONLY.get() && !canUseOffline()) return false; + if (state.is(FTBChunksAPI.EDIT_BLACKLIST_TAG)) return false; if (brokenBlocksCounter.canBreakBlock(p, leftClick)) { if (!leftClick) save(); return true; diff --git a/common/src/main/java/dev/ftb/mods/ftbchunks/data/Protection.java b/common/src/main/java/dev/ftb/mods/ftbchunks/data/Protection.java index e9192a9b..1ea58b6b 100644 --- a/common/src/main/java/dev/ftb/mods/ftbchunks/data/Protection.java +++ b/common/src/main/java/dev/ftb/mods/ftbchunks/data/Protection.java @@ -32,15 +32,11 @@ public interface Protection { Protection BREAK_BLOCK = (player, pos, hand, chunk, entity) -> { BlockState blockState = player.level.getBlockState(pos); - if (blockState.is(FTBChunksAPI.EDIT_BLACKLIST_TAG)) { - return ProtectionOverride.CHECK; - } - if (blockState.is(FTBChunksAPI.EDIT_WHITELIST_TAG)) { return ProtectionOverride.ALLOW; } - System.out.println("BREAK_BLOCK "+player); - if (chunk != null && chunk.teamData.canBreak(player, FTBChunksTeamData.BLOCK_EDIT_MODE, false)) { + + if (chunk != null && chunk.teamData.canBreak(player, FTBChunksTeamData.BLOCK_EDIT_MODE, false, blockState)) { return ProtectionOverride.ALLOW; } @@ -50,15 +46,11 @@ public interface Protection { Protection LEFT_CLICK_BLOCK = (player, pos, hand, chunk, entity) -> { BlockState blockState = player.level.getBlockState(pos); - if (blockState.is(FTBChunksAPI.EDIT_BLACKLIST_TAG)) { - return ProtectionOverride.CHECK; - } - if (blockState.is(FTBChunksAPI.EDIT_WHITELIST_TAG)) { return ProtectionOverride.ALLOW; } - if (chunk != null && chunk.teamData.canBreak(player, FTBChunksTeamData.BLOCK_EDIT_MODE, true)) { + if (chunk != null && chunk.teamData.canBreak(player, FTBChunksTeamData.BLOCK_EDIT_MODE, true, blockState)) { return ProtectionOverride.ALLOW; } @@ -134,10 +126,6 @@ public interface Protection { Protection EDIT_AND_INTERACT_BLOCK = (player, pos, hand, chunk, entity) -> { BlockState blockState = player.level.getBlockState(pos); - if (blockState.is(FTBChunksAPI.EDIT_BLACKLIST_TAG)) { - return ProtectionOverride.CHECK; - } - if (blockState.is(FTBChunksAPI.INTERACT_WHITELIST_TAG)) { return ProtectionOverride.ALLOW; } @@ -152,15 +140,11 @@ public interface Protection { Protection BREAK_BLOCK_FABRIC = (player, pos, hand, chunk, entity) -> { BlockState blockState = player.level.getBlockState(pos); - if (blockState.is(FTBChunksAPI.EDIT_BLACKLIST_TAG)) { - return ProtectionOverride.CHECK; - } - if (blockState.is(FTBChunksAPI.INTERACT_WHITELIST_TAG)) { return ProtectionOverride.ALLOW; } - if (chunk != null && chunk.teamData.canBreak(player, FTBChunksTeamData.BLOCK_EDIT_AND_INTERACT_MODE, false)) { + if (chunk != null && chunk.teamData.canBreak(player, FTBChunksTeamData.BLOCK_EDIT_AND_INTERACT_MODE, false, blockState)) { return ProtectionOverride.ALLOW; } @@ -170,15 +154,11 @@ public interface Protection { Protection LEFT_CLICK_BLOCK_FABRIC = (player, pos, hand, chunk, entity) -> { BlockState blockState = player.level.getBlockState(pos); - if (blockState.is(FTBChunksAPI.EDIT_BLACKLIST_TAG)) { - return ProtectionOverride.CHECK; - } - if (blockState.is(FTBChunksAPI.INTERACT_WHITELIST_TAG)) { return ProtectionOverride.ALLOW; } - if (chunk != null && chunk.teamData.canBreak(player, FTBChunksTeamData.BLOCK_EDIT_AND_INTERACT_MODE, true)) { + if (chunk != null && chunk.teamData.canBreak(player, FTBChunksTeamData.BLOCK_EDIT_AND_INTERACT_MODE, true, blockState)) { return ProtectionOverride.ALLOW; } From f6d67e5edb58a6beca9bfe22ff97afd40c9ef57e Mon Sep 17 00:00:00 2001 From: 1whohears <1whohears28@gmail.com> Date: Wed, 13 Nov 2024 22:52:30 -0600 Subject: [PATCH 04/17] added protect named living entity option --- .../java/dev/ftb/mods/ftbchunks/FTBChunksWorldConfig.java | 1 + .../src/main/java/dev/ftb/mods/ftbchunks/data/Protection.java | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksWorldConfig.java b/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksWorldConfig.java index 7547e230..82f71a2e 100644 --- a/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksWorldConfig.java +++ b/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksWorldConfig.java @@ -43,6 +43,7 @@ public interface FTBChunksWorldConfig { IntValue MAX_DESTROY_BLOCKS_PER_HOUR = CONFIG.getInt("max_destroy_blocks_per_hour", 0).comment("If disable_protection = false, this many blocks can still be destroyed per hour be enemy players. 0 disables this."); IntValue DESTROY_BLOCKS_COUNT_PERIOD = CONFIG.getInt("destroy_blocks_count_period", 300).comment("If max_destroy_blocks_per_hour > 0, the groups of time in seconds where the number of blocks broken are counted. Groups younger than an hour contribute to the total blocks broken. Groups older than an hour are removed."); BooleanValue PROTECT_ENTITIES_OFFLINE_ONLY = CONFIG.getBoolean("protect_entities_offline_only", true).comment("Only protect the living entities listed in the living_entity_attack_blacklist tag when all team members are offline."); + BooleanValue PROTECT_NAMED_ENTITIES = CONFIG.getBoolean("protect_named_entities", false).comment("Protect entities that have a name tag."); static int getMaxClaimedChunks(FTBChunksTeamData playerData, ServerPlayer player) { if (player != null) { diff --git a/common/src/main/java/dev/ftb/mods/ftbchunks/data/Protection.java b/common/src/main/java/dev/ftb/mods/ftbchunks/data/Protection.java index 1ea58b6b..be98691c 100644 --- a/common/src/main/java/dev/ftb/mods/ftbchunks/data/Protection.java +++ b/common/src/main/java/dev/ftb/mods/ftbchunks/data/Protection.java @@ -1,6 +1,7 @@ package dev.ftb.mods.ftbchunks.data; import dev.ftb.mods.ftbchunks.FTBCUtils; +import dev.ftb.mods.ftbchunks.FTBChunksWorldConfig; import net.minecraft.core.BlockPos; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.InteractionHand; @@ -114,7 +115,8 @@ public interface Protection { }; Protection ATTACK_LIVING_ENTITY = (player, pos, hand, chunk, entity) -> { - if (entity != null && entity.getType().is(FTBChunksAPI.LIVING_ENTITY_ATTACK_BLACKLIST_TAG) + if (entity != null && (entity.getType().is(FTBChunksAPI.LIVING_ENTITY_ATTACK_BLACKLIST_TAG) + || (FTBChunksWorldConfig.PROTECT_NAMED_ENTITIES.get() && entity.hasCustomName())) && chunk != null && !chunk.teamData.canAttackBlackListedEntity(player, FTBChunksTeamData.ALLOW_ATTACK_BLACKLISTED_ENTITIES)) { return ProtectionOverride.CHECK; } From 4ffe86948c7e8e1832bf7f1b070b7e59f821f0a0 Mon Sep 17 00:00:00 2001 From: 1whohears <1whohears28@gmail.com> Date: Sun, 24 Nov 2024 02:38:25 -0600 Subject: [PATCH 05/17] if the block breaker is null, protect the block. I will be submitting a PR to the create mod so that the drills will always fire the block break event. drills do not have an "owner" so the block break player will be null. however without this commit, FTB would still allow drills to break the block because the block break event is not canceled when the player is null. --- .../java/dev/ftb/mods/ftbchunks/FTBChunks.java | 2 +- .../mods/ftbchunks/FTBChunksWorldConfig.java | 1 + .../ftbchunks/data/ClaimedChunkManager.java | 18 ++++++++++++++++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunks.java b/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunks.java index 644bfea7..1bf08126 100644 --- a/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunks.java +++ b/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunks.java @@ -307,7 +307,7 @@ private EventResult interactEntity(Player player, Entity entity, InteractionHand } public EventResult blockBreak(Level level, BlockPos pos, BlockState blockState, ServerPlayer player, @Nullable IntValue intValue) { - if (FTBChunksAPI.getManager().protect(player, InteractionHand.MAIN_HAND, pos, FTBChunksExpected.getBlockBreakProtection(), null)) { + if (FTBChunksAPI.getManager().protect(player, InteractionHand.MAIN_HAND, pos, FTBChunksExpected.getBlockBreakProtection(), null, true)) { return EventResult.interruptFalse(); } return EventResult.pass(); diff --git a/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksWorldConfig.java b/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksWorldConfig.java index 82f71a2e..fdc50da1 100644 --- a/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksWorldConfig.java +++ b/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksWorldConfig.java @@ -44,6 +44,7 @@ public interface FTBChunksWorldConfig { IntValue DESTROY_BLOCKS_COUNT_PERIOD = CONFIG.getInt("destroy_blocks_count_period", 300).comment("If max_destroy_blocks_per_hour > 0, the groups of time in seconds where the number of blocks broken are counted. Groups younger than an hour contribute to the total blocks broken. Groups older than an hour are removed."); BooleanValue PROTECT_ENTITIES_OFFLINE_ONLY = CONFIG.getBoolean("protect_entities_offline_only", true).comment("Only protect the living entities listed in the living_entity_attack_blacklist tag when all team members are offline."); BooleanValue PROTECT_NAMED_ENTITIES = CONFIG.getBoolean("protect_named_entities", false).comment("Protect entities that have a name tag."); + BooleanValue PROTECT_UNKNOWN_BLOCK_BREAKER = CONFIG.getBoolean("protect_unknown_block_breaker", true).comment("Protect blocks if the owner of the block breaker is not defined."); static int getMaxClaimedChunks(FTBChunksTeamData playerData, ServerPlayer player) { if (player != null) { diff --git a/common/src/main/java/dev/ftb/mods/ftbchunks/data/ClaimedChunkManager.java b/common/src/main/java/dev/ftb/mods/ftbchunks/data/ClaimedChunkManager.java index 48599959..d0e7a98e 100644 --- a/common/src/main/java/dev/ftb/mods/ftbchunks/data/ClaimedChunkManager.java +++ b/common/src/main/java/dev/ftb/mods/ftbchunks/data/ClaimedChunkManager.java @@ -194,6 +194,24 @@ public void setBypassProtection(UUID player, boolean bypass) { * @return true to prevent the interaction, false to permit it */ public boolean protect(@Nullable Entity entity, InteractionHand hand, BlockPos pos, Protection protection, @Nullable Entity targetEntity) { + return protect(entity, hand, pos, protection, targetEntity, false); + } + + /** + * Check if the intended interaction should be prevented from occurring. + * + * @param entity the entity performing the interaction + * @param hand the actor's hand + * @param pos the block position at which the action will be performed + * @param protection the type of protection being checked for + * @param targetEntity the entity being acted upon, if any (e.g. a painting, armor stand etc.) + * @param protectIfNullEntity if true, and entity = null, will return true + * @return true to prevent the interaction, false to permit it + */ + public boolean protect(@Nullable Entity entity, InteractionHand hand, BlockPos pos, Protection protection, @Nullable Entity targetEntity, boolean protectIfNullEntity) { + if (protectIfNullEntity && entity == null && FTBChunksWorldConfig.PROTECT_UNKNOWN_BLOCK_BREAKER.get()) { + return true; + } if (!(entity instanceof ServerPlayer player) || FTBChunksWorldConfig.DISABLE_PROTECTION.get() || player.level == null) { return false; } From c98908eb50d1d111cea3a8e419f8664862469bad Mon Sep 17 00:00:00 2001 From: 1whohears <1whohears28@gmail.com> Date: Wed, 11 Dec 2024 20:22:44 -0600 Subject: [PATCH 06/17] added allow_unknown_breaks_in_force_loads config. I was originally going to try to assign owner players to all of the contraptioins that can break blocks in create. but thankfully I came up with a much simpler solution. create machines are only breaking blocks in force loaded chunks on servers anyway. this option then prevents enemy tunnel bores from getting into a base because friendly force loaded chunks should be surrounded by regular claimed chunks that act as a protective buffer. a version of create that fires the block break event with a null player is still required, but only on the server side...but of course this all assumes all mods have a null check in their block break listeners... --- .../java/dev/ftb/mods/ftbchunks/FTBChunks.java | 2 +- .../ftb/mods/ftbchunks/FTBChunksWorldConfig.java | 1 + .../mods/ftbchunks/data/ClaimedChunkManager.java | 14 +++++++++++--- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunks.java b/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunks.java index 1bf08126..39d0b2e6 100644 --- a/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunks.java +++ b/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunks.java @@ -307,7 +307,7 @@ private EventResult interactEntity(Player player, Entity entity, InteractionHand } public EventResult blockBreak(Level level, BlockPos pos, BlockState blockState, ServerPlayer player, @Nullable IntValue intValue) { - if (FTBChunksAPI.getManager().protect(player, InteractionHand.MAIN_HAND, pos, FTBChunksExpected.getBlockBreakProtection(), null, true)) { + if (FTBChunksAPI.getManager().protect(player, InteractionHand.MAIN_HAND, pos, FTBChunksExpected.getBlockBreakProtection(), null, true, level)) { return EventResult.interruptFalse(); } return EventResult.pass(); diff --git a/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksWorldConfig.java b/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksWorldConfig.java index fdc50da1..2b187338 100644 --- a/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksWorldConfig.java +++ b/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksWorldConfig.java @@ -45,6 +45,7 @@ public interface FTBChunksWorldConfig { BooleanValue PROTECT_ENTITIES_OFFLINE_ONLY = CONFIG.getBoolean("protect_entities_offline_only", true).comment("Only protect the living entities listed in the living_entity_attack_blacklist tag when all team members are offline."); BooleanValue PROTECT_NAMED_ENTITIES = CONFIG.getBoolean("protect_named_entities", false).comment("Protect entities that have a name tag."); BooleanValue PROTECT_UNKNOWN_BLOCK_BREAKER = CONFIG.getBoolean("protect_unknown_block_breaker", true).comment("Protect blocks if the owner of the block breaker is not defined."); + BooleanValue ALLOW_UNKNOWN_BREAKS_IN_FORCE_LOADS = CONFIG.getBoolean("allow_unknown_breaks_in_force_loads", true).comment("Allow blocks to be broken by unknown (null) players in force loaded chunks."); static int getMaxClaimedChunks(FTBChunksTeamData playerData, ServerPlayer player) { if (player != null) { diff --git a/common/src/main/java/dev/ftb/mods/ftbchunks/data/ClaimedChunkManager.java b/common/src/main/java/dev/ftb/mods/ftbchunks/data/ClaimedChunkManager.java index d0e7a98e..732ed4e0 100644 --- a/common/src/main/java/dev/ftb/mods/ftbchunks/data/ClaimedChunkManager.java +++ b/common/src/main/java/dev/ftb/mods/ftbchunks/data/ClaimedChunkManager.java @@ -194,7 +194,7 @@ public void setBypassProtection(UUID player, boolean bypass) { * @return true to prevent the interaction, false to permit it */ public boolean protect(@Nullable Entity entity, InteractionHand hand, BlockPos pos, Protection protection, @Nullable Entity targetEntity) { - return protect(entity, hand, pos, protection, targetEntity, false); + return protect(entity, hand, pos, protection, targetEntity, false, null); } /** @@ -208,8 +208,16 @@ public boolean protect(@Nullable Entity entity, InteractionHand hand, BlockPos p * @param protectIfNullEntity if true, and entity = null, will return true * @return true to prevent the interaction, false to permit it */ - public boolean protect(@Nullable Entity entity, InteractionHand hand, BlockPos pos, Protection protection, @Nullable Entity targetEntity, boolean protectIfNullEntity) { - if (protectIfNullEntity && entity == null && FTBChunksWorldConfig.PROTECT_UNKNOWN_BLOCK_BREAKER.get()) { + public boolean protect(@Nullable Entity entity, InteractionHand hand, BlockPos pos, Protection protection, @Nullable Entity targetEntity, + boolean protectIfNullEntity, @Nullable Level level) { + if (protectIfNullEntity && entity == null && level != null && FTBChunksWorldConfig.PROTECT_UNKNOWN_BLOCK_BREAKER.get()) { + ClaimedChunk chunk = getChunk(new ChunkDimPos(level, pos)); + if (chunk == null) { + return false; + } + if (FTBChunksWorldConfig.ALLOW_UNKNOWN_BREAKS_IN_FORCE_LOADS.get()) { + return !chunk.isActuallyForceLoaded(); + } return true; } if (!(entity instanceof ServerPlayer player) || FTBChunksWorldConfig.DISABLE_PROTECTION.get() || player.level == null) { From a09c07091f9abdfe6b653baf39cf4c4cb02f72d8 Mon Sep 17 00:00:00 2001 From: 1whohears <1whohears28@gmail.com> Date: Wed, 11 Dec 2024 21:52:02 -0600 Subject: [PATCH 07/17] making create fire the event with a fake player instead and using the same "allow if in force loaded chunk" logic. this is the messiest code logic to date. I will fix it later. --- .../ftbchunks/data/ClaimedChunkManager.java | 3 +++ .../mods/ftbchunks/data/FTBChunksTeamData.java | 18 +++++++++++------- .../ftb/mods/ftbchunks/data/Protection.java | 12 ++++++------ .../resources/assets/ftbchunks/lang/en_us.json | 2 ++ 4 files changed, 22 insertions(+), 13 deletions(-) diff --git a/common/src/main/java/dev/ftb/mods/ftbchunks/data/ClaimedChunkManager.java b/common/src/main/java/dev/ftb/mods/ftbchunks/data/ClaimedChunkManager.java index 732ed4e0..96db4769 100644 --- a/common/src/main/java/dev/ftb/mods/ftbchunks/data/ClaimedChunkManager.java +++ b/common/src/main/java/dev/ftb/mods/ftbchunks/data/ClaimedChunkManager.java @@ -210,6 +210,8 @@ public boolean protect(@Nullable Entity entity, InteractionHand hand, BlockPos p */ public boolean protect(@Nullable Entity entity, InteractionHand hand, BlockPos pos, Protection protection, @Nullable Entity targetEntity, boolean protectIfNullEntity, @Nullable Level level) { + // this block may not be needed if create uses fake players instead + // ******** if (protectIfNullEntity && entity == null && level != null && FTBChunksWorldConfig.PROTECT_UNKNOWN_BLOCK_BREAKER.get()) { ClaimedChunk chunk = getChunk(new ChunkDimPos(level, pos)); if (chunk == null) { @@ -220,6 +222,7 @@ public boolean protect(@Nullable Entity entity, InteractionHand hand, BlockPos p } return true; } + // ******** if (!(entity instanceof ServerPlayer player) || FTBChunksWorldConfig.DISABLE_PROTECTION.get() || player.level == null) { return false; } diff --git a/common/src/main/java/dev/ftb/mods/ftbchunks/data/FTBChunksTeamData.java b/common/src/main/java/dev/ftb/mods/ftbchunks/data/FTBChunksTeamData.java index ddf13d1d..a5aeefb4 100644 --- a/common/src/main/java/dev/ftb/mods/ftbchunks/data/FTBChunksTeamData.java +++ b/common/src/main/java/dev/ftb/mods/ftbchunks/data/FTBChunksTeamData.java @@ -63,6 +63,7 @@ public class FTBChunksTeamData { public static final PrivacyProperty CLAIM_VISIBILITY = new PrivacyProperty(new ResourceLocation(FTBChunks.MOD_ID, "claim_visibility"), PrivacyMode.PUBLIC); public static final PrivacyProperty ALLOW_ATTACK_BLACKLISTED_ENTITIES = new PrivacyProperty(new ResourceLocation(FTBChunks.MOD_ID, "allow_attack_blacklisted_entities"), PrivacyMode.ALLIES); + public static final BooleanProperty ALLOW_ANY_FAKE_PLAYER_BREAK_IF_FORCE_LOADED = new BooleanProperty(new ResourceLocation(FTBChunks.MOD_ID, "allow_any_fake_player_break_if_force_loaded"), true); // public static final PrivacyProperty MINIMAP_MODE = new PrivacyProperty(new ResourceLocation(FTBChunks.MOD_ID, "minimap_mode"), PrivacyMode.ALLIES); @@ -291,7 +292,7 @@ public boolean isAlly(UUID p) { return team.isAlly(p); } - protected boolean baseUseCheck(ServerPlayer p, PrivacyProperty property, boolean offlineCheck) { + protected boolean baseUseCheck(ServerPlayer p, PrivacyProperty property, boolean offlineCheck, boolean forceLoadedChunk) { PrivacyMode mode = team.getProperty(property); if (mode == PrivacyMode.PUBLIC) { @@ -299,7 +300,7 @@ protected boolean baseUseCheck(ServerPlayer p, PrivacyProperty property, boolean } if (PlayerHooks.isFake(p)) { - return canFakePlayerUse(p, mode); + return canFakePlayerUse(p, mode, forceLoadedChunk); } else if (mode == PrivacyMode.ALLIES) { return isAlly(p.getUUID()); } else { @@ -322,16 +323,16 @@ public boolean canUseOffline() { } public boolean canUse(ServerPlayer p, PrivacyProperty property) { - return baseUseCheck(p, property, true); + return baseUseCheck(p, property, true, false); } public boolean canAttackBlackListedEntity(ServerPlayer p, PrivacyProperty property) { - if (baseUseCheck(p, property, true)) return true; + if (baseUseCheck(p, property, true, false)) return true; return FTBChunksWorldConfig.PROTECT_ENTITIES_OFFLINE_ONLY.get() && canUseOffline(); } - public boolean canBreak(ServerPlayer p, PrivacyProperty property, boolean leftClick, BlockState state) { - if (baseUseCheck(p, property, false)) return true; + public boolean canBreak(ServerPlayer p, PrivacyProperty property, boolean leftClick, BlockState state, boolean forceLoadedChunk) { + if (baseUseCheck(p, property, false, forceLoadedChunk)) return true; if (FTBChunksWorldConfig.OFFLINE_PROTECTION_ONLY.get() && !canUseOffline()) return false; if (state.is(FTBChunksAPI.EDIT_BLACKLIST_TAG)) return false; if (brokenBlocksCounter.canBreakBlock(p, leftClick)) { @@ -341,10 +342,13 @@ public boolean canBreak(ServerPlayer p, PrivacyProperty property, boolean leftCl return false; } - private boolean canFakePlayerUse(Player player, PrivacyMode mode) { + private boolean canFakePlayerUse(Player player, PrivacyMode mode, boolean forceLoadedChunk) { if (team.getProperty(FTBChunksTeamData.ALLOW_ALL_FAKE_PLAYERS)) { return mode == PrivacyMode.ALLIES; } + if (forceLoadedChunk && team.getProperty(FTBChunksTeamData.ALLOW_ANY_FAKE_PLAYER_BREAK_IF_FORCE_LOADED)) { + return true; + } boolean checkById = team.getProperty(FTBChunksTeamData.ALLOW_FAKE_PLAYERS_BY_ID) && player.getUUID() != null; if (mode == PrivacyMode.ALLIES) { diff --git a/common/src/main/java/dev/ftb/mods/ftbchunks/data/Protection.java b/common/src/main/java/dev/ftb/mods/ftbchunks/data/Protection.java index be98691c..c16e5d8a 100644 --- a/common/src/main/java/dev/ftb/mods/ftbchunks/data/Protection.java +++ b/common/src/main/java/dev/ftb/mods/ftbchunks/data/Protection.java @@ -37,7 +37,7 @@ public interface Protection { return ProtectionOverride.ALLOW; } - if (chunk != null && chunk.teamData.canBreak(player, FTBChunksTeamData.BLOCK_EDIT_MODE, false, blockState)) { + if (chunk != null && chunk.teamData.canBreak(player, FTBChunksTeamData.BLOCK_EDIT_MODE, false, blockState, chunk.isActuallyForceLoaded())) { return ProtectionOverride.ALLOW; } @@ -51,7 +51,7 @@ public interface Protection { return ProtectionOverride.ALLOW; } - if (chunk != null && chunk.teamData.canBreak(player, FTBChunksTeamData.BLOCK_EDIT_MODE, true, blockState)) { + if (chunk != null && chunk.teamData.canBreak(player, FTBChunksTeamData.BLOCK_EDIT_MODE, true, blockState, chunk.isActuallyForceLoaded())) { return ProtectionOverride.ALLOW; } @@ -142,11 +142,11 @@ public interface Protection { Protection BREAK_BLOCK_FABRIC = (player, pos, hand, chunk, entity) -> { BlockState blockState = player.level.getBlockState(pos); - if (blockState.is(FTBChunksAPI.INTERACT_WHITELIST_TAG)) { + if (blockState.is(FTBChunksAPI.EDIT_WHITELIST_TAG)) { return ProtectionOverride.ALLOW; } - if (chunk != null && chunk.teamData.canBreak(player, FTBChunksTeamData.BLOCK_EDIT_AND_INTERACT_MODE, false, blockState)) { + if (chunk != null && chunk.teamData.canBreak(player, FTBChunksTeamData.BLOCK_EDIT_AND_INTERACT_MODE, false, blockState, chunk.isActuallyForceLoaded())) { return ProtectionOverride.ALLOW; } @@ -156,11 +156,11 @@ public interface Protection { Protection LEFT_CLICK_BLOCK_FABRIC = (player, pos, hand, chunk, entity) -> { BlockState blockState = player.level.getBlockState(pos); - if (blockState.is(FTBChunksAPI.INTERACT_WHITELIST_TAG)) { + if (blockState.is(FTBChunksAPI.EDIT_WHITELIST_TAG)) { return ProtectionOverride.ALLOW; } - if (chunk != null && chunk.teamData.canBreak(player, FTBChunksTeamData.BLOCK_EDIT_AND_INTERACT_MODE, true, blockState)) { + if (chunk != null && chunk.teamData.canBreak(player, FTBChunksTeamData.BLOCK_EDIT_AND_INTERACT_MODE, true, blockState, chunk.isActuallyForceLoaded())) { return ProtectionOverride.ALLOW; } diff --git a/common/src/main/resources/assets/ftbchunks/lang/en_us.json b/common/src/main/resources/assets/ftbchunks/lang/en_us.json index 43ebb427..7422baec 100644 --- a/common/src/main/resources/assets/ftbchunks/lang/en_us.json +++ b/common/src/main/resources/assets/ftbchunks/lang/en_us.json @@ -124,6 +124,8 @@ "ftbteamsconfig.ftbchunks.claim_visibility.tooltip": "Controls who can see your claims on the map or minimap", "ftbteamsconfig.ftbchunks.allow_attack_blacklisted_entities": "Allow Attack Black Listed Entities", "ftbteamsconfig.ftbchunks.allow_attack_blacklisted_entities.tooltip": "Allow enemy players to attack living entities the server owner gave protection too. Server owner must enable this setting and modify the entity_attack_blacklist tag.", + "ftbteamsconfig.ftbchunks.allow_any_fake_player_break_if_force_loaded": "Allow any Fake Player Block Break if Chunk is Force Loaded", + "ftbteamsconfig.ftbchunks.allow_any_fake_player_break_if_force_loaded.tooltip": "Allows any Fake Player Block Break if Chunk is Force Loaded. Beta builds of Create use fake players for block breaks.", "ftbchunks.fake_players": "Allow Fake Players", "ftbchunks.fake_players.tooltip": "CHECK: check fake player access like any real player\nDENY: never allow fake players\nALLOW: always allow fake players", "ftbchunks.max_claimed_chunks": "Max Claimed Chunks per Player", From c0f0d2f068a010d468f46e41a7e341701ed89b55 Mon Sep 17 00:00:00 2001 From: 1whohears <1whohears28@gmail.com> Date: Wed, 11 Dec 2024 21:58:23 -0600 Subject: [PATCH 08/17] forgot to register ALLOW_ANY_FAKE_PLAYER_BREAK_IF_FORCE_LOADED --- common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunks.java | 1 + 1 file changed, 1 insertion(+) diff --git a/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunks.java b/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunks.java index 39d0b2e6..5ef3e1a1 100644 --- a/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunks.java +++ b/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunks.java @@ -455,6 +455,7 @@ private void teamConfig(TeamCollectPropertiesEvent event) { event.add(FTBChunksTeamData.ALLOW_NAMED_FAKE_PLAYERS); event.add(FTBChunksTeamData.ALLOW_FAKE_PLAYERS_BY_ID); event.add(FTBChunksTeamData.ALLOW_ATTACK_BLACKLISTED_ENTITIES); + event.add(FTBChunksTeamData.ALLOW_ANY_FAKE_PLAYER_BREAK_IF_FORCE_LOADED); // block edit/interact properties vary on forge & fabric FTBChunksExpected.getPlatformSpecificProperties(event); From 055f1ac4108fca1c708f8795b8064f8cc9dc3c57 Mon Sep 17 00:00:00 2001 From: 1whohears <1whohears28@gmail.com> Date: Wed, 18 Dec 2024 16:24:32 -0600 Subject: [PATCH 09/17] added allow_explode_break_count config where if enabled, blocks can be broken by player caused explosions and they contribute to the max block break per hour. --- .../dev/ftb/mods/ftbchunks/FTBChunks.java | 32 ++++++++++++++++--- .../ftb/mods/ftbchunks/FTBChunksCommands.java | 17 ++++++++++ .../mods/ftbchunks/FTBChunksWorldConfig.java | 1 + .../ftbchunks/data/FTBChunksTeamData.java | 7 ++++ 4 files changed, 53 insertions(+), 4 deletions(-) diff --git a/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunks.java b/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunks.java index 5ef3e1a1..f1410546 100644 --- a/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunks.java +++ b/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunks.java @@ -415,15 +415,39 @@ public void explosionDetonate(Level level, Explosion explosion, List aff List list = new ArrayList<>(explosion.getToBlow()); explosion.clearToBlow(); - Map map = new HashMap<>(); + //Map map = new HashMap<>(); + ServerPlayer player = explosion.getDamageSource().getEntity() instanceof ServerPlayer p ? p : null; + int k = 0; for (BlockPos pos : list) { - if (map.computeIfAbsent(new ChunkDimPos(level, pos), cpos -> { + if (level.getBlockState(pos).isAir()) continue; + ChunkDimPos cdpos = new ChunkDimPos(level, pos); + ClaimedChunk chunk = FTBChunksAPI.getManager().getChunk(cdpos); + if (chunk == null || chunk.allowExplosions()) { + explosion.getToBlow().add(pos); + continue; + } + if (player != null && FTBChunksWorldConfig.ALLOW_EXPLODE_BREAK_COUNT.get()) { + Protection protection = FTBChunksExpected.getBlockBreakProtection(); + ProtectionOverride override = protection.override(player, pos, InteractionHand.MAIN_HAND, chunk, null); + if (!override.getProtect()) { + explosion.getToBlow().add(pos); + } + } + // this map was used for performance reasons, but it doesn't allow counting all the broken blocks + /*if (map.computeIfAbsent(new ChunkDimPos(level, pos), cpos -> { ClaimedChunk chunk = FTBChunksAPI.getManager().getChunk(cpos); - return chunk == null || chunk.allowExplosions(); + if (chunk == null) return true; + if (chunk.allowExplosions()) return true; + if (player != null && FTBChunksWorldConfig.ALLOW_EXPLODE_BREAK_COUNT.get()) { + Protection protection = FTBChunksExpected.getBlockBreakProtection(); + ProtectionOverride override = protection.override(player, pos, InteractionHand.MAIN_HAND, chunk, null); + return !override.getProtect(); + } + return false; })) { explosion.getToBlow().add(pos); - } + }*/ } } diff --git a/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksCommands.java b/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksCommands.java index 1612c76c..e7375975 100644 --- a/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksCommands.java +++ b/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksCommands.java @@ -89,6 +89,9 @@ public static void registerCommands(CommandDispatcher dispat ) ) ) + .then(Commands.literal("query_block_breaks") + .executes(context -> infoBlockBreaks(context.getSource(), new ChunkDimPos(context.getSource().getLevel(), new BlockPos(context.getSource().getPosition())))) + ) .then(Commands.literal("admin") .requires(source -> source.hasPermission(2)) .then(Commands.literal("bypass_protection") @@ -368,6 +371,20 @@ private static int info(CommandSourceStack source, ChunkDimPos pos) { return 1; } + private static int infoBlockBreaks(CommandSourceStack source, ChunkDimPos pos) { + ClaimedChunk chunk = FTBChunksAPI.getManager().getChunk(pos); + + if (chunk == null) { + source.sendSuccess(Component.literal("Chunk not claimed!"), true); + return 0; + } + + int remain = chunk.getTeamData().getRemainingBreakableBlocksNum(source.getLevel()); + source.sendSuccess(Component.literal("Enemy players are currently able to break "+remain+" blocks!"), true); + + return 1; + } + private static int getExtraClaimChunks(CommandSourceStack source, ServerPlayer player) { FTBChunksTeamData personalData = FTBChunksAPI.getManager().getPersonalData(player); if (personalData == null) { diff --git a/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksWorldConfig.java b/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksWorldConfig.java index 2b187338..ecd0115c 100644 --- a/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksWorldConfig.java +++ b/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksWorldConfig.java @@ -46,6 +46,7 @@ public interface FTBChunksWorldConfig { BooleanValue PROTECT_NAMED_ENTITIES = CONFIG.getBoolean("protect_named_entities", false).comment("Protect entities that have a name tag."); BooleanValue PROTECT_UNKNOWN_BLOCK_BREAKER = CONFIG.getBoolean("protect_unknown_block_breaker", true).comment("Protect blocks if the owner of the block breaker is not defined."); BooleanValue ALLOW_UNKNOWN_BREAKS_IN_FORCE_LOADS = CONFIG.getBoolean("allow_unknown_breaks_in_force_loads", true).comment("Allow blocks to be broken by unknown (null) players in force loaded chunks."); + BooleanValue ALLOW_EXPLODE_BREAK_COUNT = CONFIG.getBoolean("allow_explode_break_count", false).comment("Allow blocks to be broken by known explosions and contribute to max_destroy_blocks_per_hour."); static int getMaxClaimedChunks(FTBChunksTeamData playerData, ServerPlayer player) { if (player != null) { diff --git a/common/src/main/java/dev/ftb/mods/ftbchunks/data/FTBChunksTeamData.java b/common/src/main/java/dev/ftb/mods/ftbchunks/data/FTBChunksTeamData.java index a5aeefb4..0f563fd9 100644 --- a/common/src/main/java/dev/ftb/mods/ftbchunks/data/FTBChunksTeamData.java +++ b/common/src/main/java/dev/ftb/mods/ftbchunks/data/FTBChunksTeamData.java @@ -709,6 +709,13 @@ public void resetBrokenBlocksCounter() { save(); } + public int getRemainingBreakableBlocksNum(Level level) { + long time = level.getGameTime(); + int blocks_per_hour = FTBChunksWorldConfig.MAX_DESTROY_BLOCKS_PER_HOUR.get(); + int total = brokenBlocksCounter.getTotalBrokenBlocks(time); + return blocks_per_hour - total; + } + public static final Style WARNING_STYLE = Style.EMPTY.withColor(0xFFFF55); public static final int HOUR_TICKS = 60 * 60 * 20; From e68b103b61ce761d6da918f7dad1ddc0347b7962 Mon Sep 17 00:00:00 2001 From: 1whohears <1whohears28@gmail.com> Date: Sat, 28 Dec 2024 17:24:04 -0600 Subject: [PATCH 10/17] fixed private privacy setting not working --- .../java/dev/ftb/mods/ftbchunks/data/FTBChunksTeamData.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/src/main/java/dev/ftb/mods/ftbchunks/data/FTBChunksTeamData.java b/common/src/main/java/dev/ftb/mods/ftbchunks/data/FTBChunksTeamData.java index 0f563fd9..091d448f 100644 --- a/common/src/main/java/dev/ftb/mods/ftbchunks/data/FTBChunksTeamData.java +++ b/common/src/main/java/dev/ftb/mods/ftbchunks/data/FTBChunksTeamData.java @@ -323,7 +323,7 @@ public boolean canUseOffline() { } public boolean canUse(ServerPlayer p, PrivacyProperty property) { - return baseUseCheck(p, property, true, false); + return baseUseCheck(p, property, false, false); } public boolean canAttackBlackListedEntity(ServerPlayer p, PrivacyProperty property) { From 03ff65175b823a6b057a38541eaebfb1a1943b63 Mon Sep 17 00:00:00 2001 From: 1whohears <1whohears28@gmail.com> Date: Tue, 31 Dec 2024 01:32:26 -0600 Subject: [PATCH 11/17] revert explosion wack --- .../dev/ftb/mods/ftbchunks/FTBChunks.java | 29 ++++++++----------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunks.java b/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunks.java index f1410546..c5c477d8 100644 --- a/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunks.java +++ b/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunks.java @@ -415,9 +415,18 @@ public void explosionDetonate(Level level, Explosion explosion, List aff List list = new ArrayList<>(explosion.getToBlow()); explosion.clearToBlow(); - //Map map = new HashMap<>(); - ServerPlayer player = explosion.getDamageSource().getEntity() instanceof ServerPlayer p ? p : null; + Map map = new HashMap<>(); + for (BlockPos pos : list) { + if (map.computeIfAbsent(new ChunkDimPos(level, pos), cpos -> { + ClaimedChunk chunk = FTBChunksAPI.getManager().getChunk(cpos); + return chunk == null || chunk.allowExplosions(); + })) { + explosion.getToBlow().add(pos); + } + } + + /*ServerPlayer player = explosion.getDamageSource().getEntity() instanceof ServerPlayer p ? p : null; int k = 0; for (BlockPos pos : list) { if (level.getBlockState(pos).isAir()) continue; @@ -434,21 +443,7 @@ public void explosionDetonate(Level level, Explosion explosion, List aff explosion.getToBlow().add(pos); } } - // this map was used for performance reasons, but it doesn't allow counting all the broken blocks - /*if (map.computeIfAbsent(new ChunkDimPos(level, pos), cpos -> { - ClaimedChunk chunk = FTBChunksAPI.getManager().getChunk(cpos); - if (chunk == null) return true; - if (chunk.allowExplosions()) return true; - if (player != null && FTBChunksWorldConfig.ALLOW_EXPLODE_BREAK_COUNT.get()) { - Protection protection = FTBChunksExpected.getBlockBreakProtection(); - ProtectionOverride override = protection.override(player, pos, InteractionHand.MAIN_HAND, chunk, null); - return !override.getProtect(); - } - return false; - })) { - explosion.getToBlow().add(pos); - }*/ - } + }*/ } private void playerCloned(ServerPlayer oldPlayer, ServerPlayer newPlayer, boolean wonGame) { From ede1bd470fa87c56de4aa86febd1eb086355f816 Mon Sep 17 00:00:00 2001 From: 1whohears <1whohears28@gmail.com> Date: Sat, 4 Jan 2025 01:22:46 -0600 Subject: [PATCH 12/17] return explosion wack with a small opt --- .../dev/ftb/mods/ftbchunks/FTBChunks.java | 21 ++++++++++++------- .../mods/ftbchunks/FTBChunksWorldConfig.java | 4 +++- .../ftbchunks/data/FTBChunksTeamData.java | 18 +++++++++------- 3 files changed, 27 insertions(+), 16 deletions(-) diff --git a/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunks.java b/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunks.java index c5c477d8..7d65cb4f 100644 --- a/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunks.java +++ b/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunks.java @@ -415,7 +415,7 @@ public void explosionDetonate(Level level, Explosion explosion, List aff List list = new ArrayList<>(explosion.getToBlow()); explosion.clearToBlow(); - Map map = new HashMap<>(); + /*Map map = new HashMap<>(); for (BlockPos pos : list) { if (map.computeIfAbsent(new ChunkDimPos(level, pos), cpos -> { @@ -424,18 +424,23 @@ public void explosionDetonate(Level level, Explosion explosion, List aff })) { explosion.getToBlow().add(pos); } - } - - /*ServerPlayer player = explosion.getDamageSource().getEntity() instanceof ServerPlayer p ? p : null; - int k = 0; + }*/ + Map map = new HashMap<>(); + ServerPlayer player = explosion.getDamageSource().getEntity() instanceof ServerPlayer p ? p : null; for (BlockPos pos : list) { if (level.getBlockState(pos).isAir()) continue; ChunkDimPos cdpos = new ChunkDimPos(level, pos); - ClaimedChunk chunk = FTBChunksAPI.getManager().getChunk(cdpos); - if (chunk == null || chunk.allowExplosions()) { + ClaimedChunk chunk = null; + if (!map.containsKey(cdpos)) { + chunk = FTBChunksAPI.getManager().getChunk(cdpos); + boolean allow = chunk == null || chunk.allowExplosions(); + map.put(cdpos, allow); + } + if (map.get(cdpos)) { explosion.getToBlow().add(pos); continue; } + if (chunk == null) chunk = FTBChunksAPI.getManager().getChunk(cdpos); if (player != null && FTBChunksWorldConfig.ALLOW_EXPLODE_BREAK_COUNT.get()) { Protection protection = FTBChunksExpected.getBlockBreakProtection(); ProtectionOverride override = protection.override(player, pos, InteractionHand.MAIN_HAND, chunk, null); @@ -443,7 +448,7 @@ public void explosionDetonate(Level level, Explosion explosion, List aff explosion.getToBlow().add(pos); } } - }*/ + } } private void playerCloned(ServerPlayer oldPlayer, ServerPlayer newPlayer, boolean wonGame) { diff --git a/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksWorldConfig.java b/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksWorldConfig.java index ecd0115c..c130b280 100644 --- a/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksWorldConfig.java +++ b/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksWorldConfig.java @@ -38,7 +38,8 @@ public interface FTBChunksWorldConfig { EnumValue PARTY_LIMIT_MODE = CONFIG.getEnum("party_limit_mode", PartyLimitMode.NAME_MAP).comment("Method by which party claim & force-load limits are calculated.","LARGEST: use the limits of the member with the largest limits","SUM: add up all the members' limits","OWNER: use the party owner's limits only","AVERAGE: use the average of all members' limits."); BooleanValue REQUIRE_GAME_STAGE = CONFIG.getBoolean("require_game_stage", false).comment("If true, the player must have the 'ftbchunks_mapping' Game stage to be able to use the map and minimap.\nRequires KubeJS and/or Gamestages to be installed."); BooleanValue LOCATION_MODE_OVERRIDE = CONFIG.getBoolean("location_mode_override", false).comment("If true, \"Location Visibility\" team settings are ignored, and all players can see each other anywhere on the map."); - BooleanValue OFFLINE_PROTECTION_ONLY = CONFIG.getBoolean("offline_protection_only", false).comment("If enabled and disable_protection = false enemy players will ONLY be able to damage your claimed chunks if you or your team mates are online."); + BooleanValue OFFLINE_PROTECTION_ONLY_ALL = CONFIG.getBoolean("offline_protection_only_all", false).comment("If enabled and disable_protection = false all protections will be disabled when the team is online."); + BooleanValue OFFLINE_PROTECTION_ONLY_BLOCKS = CONFIG.getBoolean("offline_protection_only_blocks", false).comment("If enabled and disable_protection = false block protection ONLY will be disabled when a team is online."); IntValue OFFLINE_PROTECTION_BUFFER = CONFIG.getInt("offline_protection_buffer", 30).comment("If offline_protection_only = true, the time in SECONDS after all members of a team log off, before chunk protection turns on. This setting is meant to discourage combat logging. Set to 0 to disable. Set to -1 for unlimited block breaking if offline_protection_only = true."); IntValue MAX_DESTROY_BLOCKS_PER_HOUR = CONFIG.getInt("max_destroy_blocks_per_hour", 0).comment("If disable_protection = false, this many blocks can still be destroyed per hour be enemy players. 0 disables this."); IntValue DESTROY_BLOCKS_COUNT_PERIOD = CONFIG.getInt("destroy_blocks_count_period", 300).comment("If max_destroy_blocks_per_hour > 0, the groups of time in seconds where the number of blocks broken are counted. Groups younger than an hour contribute to the total blocks broken. Groups older than an hour are removed."); @@ -47,6 +48,7 @@ public interface FTBChunksWorldConfig { BooleanValue PROTECT_UNKNOWN_BLOCK_BREAKER = CONFIG.getBoolean("protect_unknown_block_breaker", true).comment("Protect blocks if the owner of the block breaker is not defined."); BooleanValue ALLOW_UNKNOWN_BREAKS_IN_FORCE_LOADS = CONFIG.getBoolean("allow_unknown_breaks_in_force_loads", true).comment("Allow blocks to be broken by unknown (null) players in force loaded chunks."); BooleanValue ALLOW_EXPLODE_BREAK_COUNT = CONFIG.getBoolean("allow_explode_break_count", false).comment("Allow blocks to be broken by known explosions and contribute to max_destroy_blocks_per_hour."); + //BooleanValue DISABLE_PROTECTION_IN_COMBAT = CONFIG.getBoolean("disable_protection_in_combat", false).comment("If enabled, protection will be removed if players from both factions attack each other."); static int getMaxClaimedChunks(FTBChunksTeamData playerData, ServerPlayer player) { if (player != null) { diff --git a/common/src/main/java/dev/ftb/mods/ftbchunks/data/FTBChunksTeamData.java b/common/src/main/java/dev/ftb/mods/ftbchunks/data/FTBChunksTeamData.java index 091d448f..54085ed0 100644 --- a/common/src/main/java/dev/ftb/mods/ftbchunks/data/FTBChunksTeamData.java +++ b/common/src/main/java/dev/ftb/mods/ftbchunks/data/FTBChunksTeamData.java @@ -302,12 +302,12 @@ protected boolean baseUseCheck(ServerPlayer p, PrivacyProperty property, boolean if (PlayerHooks.isFake(p)) { return canFakePlayerUse(p, mode, forceLoadedChunk); } else if (mode == PrivacyMode.ALLIES) { - return isAlly(p.getUUID()); + if (isAlly(p.getUUID())) return true; + if (offlineCheck) return canUseOffline(); + return false; } else { if (team.isMember(p.getUUID())) return true; - if (offlineCheck && FTBChunksWorldConfig.OFFLINE_PROTECTION_ONLY.get()) { - return canUseOffline(); - } + if (offlineCheck) return canUseOffline(); return false; } } @@ -323,17 +323,17 @@ public boolean canUseOffline() { } public boolean canUse(ServerPlayer p, PrivacyProperty property) { - return baseUseCheck(p, property, false, false); + return baseUseCheck(p, property, FTBChunksWorldConfig.OFFLINE_PROTECTION_ONLY_ALL.get(), false); } public boolean canAttackBlackListedEntity(ServerPlayer p, PrivacyProperty property) { - if (baseUseCheck(p, property, true, false)) return true; + if (baseUseCheck(p, property, FTBChunksWorldConfig.OFFLINE_PROTECTION_ONLY_ALL.get(), false)) return true; return FTBChunksWorldConfig.PROTECT_ENTITIES_OFFLINE_ONLY.get() && canUseOffline(); } public boolean canBreak(ServerPlayer p, PrivacyProperty property, boolean leftClick, BlockState state, boolean forceLoadedChunk) { if (baseUseCheck(p, property, false, forceLoadedChunk)) return true; - if (FTBChunksWorldConfig.OFFLINE_PROTECTION_ONLY.get() && !canUseOffline()) return false; + if (isOnlineBlockProtectionDisabled() && !canUseOffline()) return false; if (state.is(FTBChunksAPI.EDIT_BLACKLIST_TAG)) return false; if (brokenBlocksCounter.canBreakBlock(p, leftClick)) { if (!leftClick) save(); @@ -342,6 +342,10 @@ public boolean canBreak(ServerPlayer p, PrivacyProperty property, boolean leftCl return false; } + private boolean isOnlineBlockProtectionDisabled() { + return FTBChunksWorldConfig.OFFLINE_PROTECTION_ONLY_BLOCKS.get() || FTBChunksWorldConfig.OFFLINE_PROTECTION_ONLY_ALL.get(); + } + private boolean canFakePlayerUse(Player player, PrivacyMode mode, boolean forceLoadedChunk) { if (team.getProperty(FTBChunksTeamData.ALLOW_ALL_FAKE_PLAYERS)) { return mode == PrivacyMode.ALLIES; From 58b6addcedcc600533d15cdaf74f84dcacf39d37 Mon Sep 17 00:00:00 2001 From: 1whohears <1whohears28@gmail.com> Date: Thu, 20 Feb 2025 01:26:49 -0600 Subject: [PATCH 13/17] config that prevents ops from seeing all nearby players on the minimap --- .../java/dev/ftb/mods/ftbchunks/FTBChunksWorldConfig.java | 2 ++ .../ftb/mods/ftbchunks/net/SendVisiblePlayerListPacket.java | 4 +++- forge/src/main/resources/META-INF/mods.toml | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksWorldConfig.java b/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksWorldConfig.java index c130b280..a52d64fd 100644 --- a/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksWorldConfig.java +++ b/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksWorldConfig.java @@ -49,6 +49,8 @@ public interface FTBChunksWorldConfig { BooleanValue ALLOW_UNKNOWN_BREAKS_IN_FORCE_LOADS = CONFIG.getBoolean("allow_unknown_breaks_in_force_loads", true).comment("Allow blocks to be broken by unknown (null) players in force loaded chunks."); BooleanValue ALLOW_EXPLODE_BREAK_COUNT = CONFIG.getBoolean("allow_explode_break_count", false).comment("Allow blocks to be broken by known explosions and contribute to max_destroy_blocks_per_hour."); //BooleanValue DISABLE_PROTECTION_IN_COMBAT = CONFIG.getBoolean("disable_protection_in_combat", false).comment("If enabled, protection will be removed if players from both factions attack each other."); + BooleanValue OPS_SEE_ALL_PLAYERS_MAP = CONFIG.getBoolean("ops_see_all_players_map", false).comment("Allow ops to see all nearby players on the minimap."); + //fix the block break black list static int getMaxClaimedChunks(FTBChunksTeamData playerData, ServerPlayer player) { if (player != null) { diff --git a/common/src/main/java/dev/ftb/mods/ftbchunks/net/SendVisiblePlayerListPacket.java b/common/src/main/java/dev/ftb/mods/ftbchunks/net/SendVisiblePlayerListPacket.java index 220d99b5..406da3dd 100644 --- a/common/src/main/java/dev/ftb/mods/ftbchunks/net/SendVisiblePlayerListPacket.java +++ b/common/src/main/java/dev/ftb/mods/ftbchunks/net/SendVisiblePlayerListPacket.java @@ -69,11 +69,13 @@ public static void syncToPlayers(List players) { .collect(Collectors.toList()); boolean override = FTBChunksWorldConfig.LOCATION_MODE_OVERRIDE.get(); + boolean allowOps = FTBChunksWorldConfig.OPS_SEE_ALL_PLAYERS_MAP.get(); for (VisiblePlayerItem recipient : playerList) { List playerIds = new ArrayList<>(); for (VisiblePlayerItem other : playerList) { - if (override || recipient.player.hasPermissions(2) || other.data.canUse(recipient.player, FTBChunksTeamData.LOCATION_MODE)) { + if (override || (allowOps && recipient.player.hasPermissions(2)) + || other.data.canUse(recipient.player, FTBChunksTeamData.LOCATION_MODE)) { playerIds.add(other.player.getUUID()); } } diff --git a/forge/src/main/resources/META-INF/mods.toml b/forge/src/main/resources/META-INF/mods.toml index 39856168..ff500a67 100644 --- a/forge/src/main/resources/META-INF/mods.toml +++ b/forge/src/main/resources/META-INF/mods.toml @@ -13,6 +13,7 @@ Mapping, chunk claim protection and chunk loading all in one! ''' # logoFile="logo.png" license = "All Rights Reserved" +displayTest = "MATCH_VERSION" [[dependencies.ftbchunks]] modId = "forge" From 4eef775a0ff32d12bdf28ed8c38903c85762b6ec Mon Sep 17 00:00:00 2001 From: 1whohears <1whohears28@gmail.com> Date: Thu, 20 Feb 2025 01:53:24 -0600 Subject: [PATCH 14/17] fixed edit blacklist tag --- .../ftb/mods/ftbchunks/FTBChunksWorldConfig.java | 1 - .../dev/ftb/mods/ftbchunks/data/Protection.java | 4 ---- .../data/ftbchunks/tags/blocks/edit_blacklist.json | 13 +++++++++++++ 3 files changed, 13 insertions(+), 5 deletions(-) create mode 100644 common/src/main/resources/data/ftbchunks/tags/blocks/edit_blacklist.json diff --git a/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksWorldConfig.java b/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksWorldConfig.java index a52d64fd..ae37adc7 100644 --- a/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksWorldConfig.java +++ b/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksWorldConfig.java @@ -50,7 +50,6 @@ public interface FTBChunksWorldConfig { BooleanValue ALLOW_EXPLODE_BREAK_COUNT = CONFIG.getBoolean("allow_explode_break_count", false).comment("Allow blocks to be broken by known explosions and contribute to max_destroy_blocks_per_hour."); //BooleanValue DISABLE_PROTECTION_IN_COMBAT = CONFIG.getBoolean("disable_protection_in_combat", false).comment("If enabled, protection will be removed if players from both factions attack each other."); BooleanValue OPS_SEE_ALL_PLAYERS_MAP = CONFIG.getBoolean("ops_see_all_players_map", false).comment("Allow ops to see all nearby players on the minimap."); - //fix the block break black list static int getMaxClaimedChunks(FTBChunksTeamData playerData, ServerPlayer player) { if (player != null) { diff --git a/common/src/main/java/dev/ftb/mods/ftbchunks/data/Protection.java b/common/src/main/java/dev/ftb/mods/ftbchunks/data/Protection.java index c16e5d8a..d59fc257 100644 --- a/common/src/main/java/dev/ftb/mods/ftbchunks/data/Protection.java +++ b/common/src/main/java/dev/ftb/mods/ftbchunks/data/Protection.java @@ -15,10 +15,6 @@ public interface Protection { Protection EDIT_BLOCK = (player, pos, hand, chunk, entity) -> { BlockState blockState = player.level.getBlockState(pos); - if (blockState.is(FTBChunksAPI.EDIT_BLACKLIST_TAG)) { - return ProtectionOverride.CHECK; - } - if (blockState.is(FTBChunksAPI.EDIT_WHITELIST_TAG)) { return ProtectionOverride.ALLOW; } diff --git a/common/src/main/resources/data/ftbchunks/tags/blocks/edit_blacklist.json b/common/src/main/resources/data/ftbchunks/tags/blocks/edit_blacklist.json new file mode 100644 index 00000000..debe8f4d --- /dev/null +++ b/common/src/main/resources/data/ftbchunks/tags/blocks/edit_blacklist.json @@ -0,0 +1,13 @@ +{ + "replace": false, + "values": [ + { + "id": "#minecraft:beds", + "required": false + }, + { + "id": "minecraft:ender_chest", + "required": false + } + ] +} \ No newline at end of file From a357cd90b577a37a184e3216c1feedffda38db45 Mon Sep 17 00:00:00 2001 From: 1whohears <1whohears28@gmail.com> Date: Sat, 22 Feb 2025 12:13:03 -0600 Subject: [PATCH 15/17] added force_public_claim_visibility config option. disabled by default. --- common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunks.java | 2 +- .../main/java/dev/ftb/mods/ftbchunks/FTBChunksWorldConfig.java | 2 ++ .../java/dev/ftb/mods/ftbchunks/data/FTBChunksTeamData.java | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunks.java b/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunks.java index 7d65cb4f..90652544 100644 --- a/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunks.java +++ b/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunks.java @@ -218,7 +218,7 @@ private void loggedIn(PlayerLoggedInAfterTeamEvent event) { chunksToSend.forEach((dimensionAndId, chunkPackets) -> { Team team = FTBTeamsAPI.getManager().getTeamByID(dimensionAndId.getRight()); FTBChunksTeamData teamData = FTBChunksAPI.getManager().getData(team); - if (teamData.canUse(player, FTBChunksTeamData.CLAIM_VISIBILITY)) { + if (FTBChunksWorldConfig.FORCE_PUBLIC_CLAIM_VISIBILITY.get() || teamData.canUse(player, FTBChunksTeamData.CLAIM_VISIBILITY)) { SendManyChunksPacket packet = new SendManyChunksPacket(dimensionAndId.getLeft(), dimensionAndId.getRight(), chunkPackets); packet.sendTo(player); } diff --git a/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksWorldConfig.java b/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksWorldConfig.java index ae37adc7..f8e9928b 100644 --- a/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksWorldConfig.java +++ b/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksWorldConfig.java @@ -42,6 +42,7 @@ public interface FTBChunksWorldConfig { BooleanValue OFFLINE_PROTECTION_ONLY_BLOCKS = CONFIG.getBoolean("offline_protection_only_blocks", false).comment("If enabled and disable_protection = false block protection ONLY will be disabled when a team is online."); IntValue OFFLINE_PROTECTION_BUFFER = CONFIG.getInt("offline_protection_buffer", 30).comment("If offline_protection_only = true, the time in SECONDS after all members of a team log off, before chunk protection turns on. This setting is meant to discourage combat logging. Set to 0 to disable. Set to -1 for unlimited block breaking if offline_protection_only = true."); IntValue MAX_DESTROY_BLOCKS_PER_HOUR = CONFIG.getInt("max_destroy_blocks_per_hour", 0).comment("If disable_protection = false, this many blocks can still be destroyed per hour be enemy players. 0 disables this."); + // 2nd destroy blocks for hour group IntValue DESTROY_BLOCKS_COUNT_PERIOD = CONFIG.getInt("destroy_blocks_count_period", 300).comment("If max_destroy_blocks_per_hour > 0, the groups of time in seconds where the number of blocks broken are counted. Groups younger than an hour contribute to the total blocks broken. Groups older than an hour are removed."); BooleanValue PROTECT_ENTITIES_OFFLINE_ONLY = CONFIG.getBoolean("protect_entities_offline_only", true).comment("Only protect the living entities listed in the living_entity_attack_blacklist tag when all team members are offline."); BooleanValue PROTECT_NAMED_ENTITIES = CONFIG.getBoolean("protect_named_entities", false).comment("Protect entities that have a name tag."); @@ -50,6 +51,7 @@ public interface FTBChunksWorldConfig { BooleanValue ALLOW_EXPLODE_BREAK_COUNT = CONFIG.getBoolean("allow_explode_break_count", false).comment("Allow blocks to be broken by known explosions and contribute to max_destroy_blocks_per_hour."); //BooleanValue DISABLE_PROTECTION_IN_COMBAT = CONFIG.getBoolean("disable_protection_in_combat", false).comment("If enabled, protection will be removed if players from both factions attack each other."); BooleanValue OPS_SEE_ALL_PLAYERS_MAP = CONFIG.getBoolean("ops_see_all_players_map", false).comment("Allow ops to see all nearby players on the minimap."); + BooleanValue FORCE_PUBLIC_CLAIM_VISIBILITY = CONFIG.getBoolean("force_public_claim_visibility", false).comment("All claims will be visible to everyone if enabled."); static int getMaxClaimedChunks(FTBChunksTeamData playerData, ServerPlayer player) { if (player != null) { diff --git a/common/src/main/java/dev/ftb/mods/ftbchunks/data/FTBChunksTeamData.java b/common/src/main/java/dev/ftb/mods/ftbchunks/data/FTBChunksTeamData.java index 54085ed0..97bf4417 100644 --- a/common/src/main/java/dev/ftb/mods/ftbchunks/data/FTBChunksTeamData.java +++ b/common/src/main/java/dev/ftb/mods/ftbchunks/data/FTBChunksTeamData.java @@ -561,7 +561,7 @@ public void setLastLogoffTime(long when) { } public boolean shouldHideClaims() { - return getTeam().getProperty(CLAIM_VISIBILITY) != PrivacyMode.PUBLIC; + return !FTBChunksWorldConfig.FORCE_PUBLIC_CLAIM_VISIBILITY.get() && getTeam().getProperty(CLAIM_VISIBILITY) != PrivacyMode.PUBLIC; } public void syncChunksToPlayer(ServerPlayer recipient) { From 523f0f719c8380889fc2712b7c6a21749a87347e Mon Sep 17 00:00:00 2001 From: 1whohears <1whohears28@gmail.com> Date: Sat, 22 Feb 2025 13:02:45 -0600 Subject: [PATCH 16/17] added 2 other block breaking groups with configurable block breaking rates --- .../ftb/mods/ftbchunks/FTBChunksCommands.java | 11 +++- .../mods/ftbchunks/FTBChunksWorldConfig.java | 5 +- .../ftb/mods/ftbchunks/data/FTBChunksAPI.java | 2 + .../ftbchunks/data/FTBChunksTeamData.java | 59 +++++++++++++++---- .../ftbchunks/tags/blocks/count_breaks_1.json | 45 ++++++++++++++ .../ftbchunks/tags/blocks/count_breaks_2.json | 25 ++++++++ 6 files changed, 129 insertions(+), 18 deletions(-) create mode 100644 common/src/main/resources/data/ftbchunks/tags/blocks/count_breaks_1.json create mode 100644 common/src/main/resources/data/ftbchunks/tags/blocks/count_breaks_2.json diff --git a/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksCommands.java b/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksCommands.java index e7375975..76a62b9b 100644 --- a/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksCommands.java +++ b/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksCommands.java @@ -375,12 +375,17 @@ private static int infoBlockBreaks(CommandSourceStack source, ChunkDimPos pos) { ClaimedChunk chunk = FTBChunksAPI.getManager().getChunk(pos); if (chunk == null) { - source.sendSuccess(Component.literal("Chunk not claimed!"), true); + source.sendSuccess(Component.literal("Chunk not claimed!"), false); return 0; } - int remain = chunk.getTeamData().getRemainingBreakableBlocksNum(source.getLevel()); - source.sendSuccess(Component.literal("Enemy players are currently able to break "+remain+" blocks!"), true); + int[] remain = chunk.getTeamData().getRemainingBreakableBlocksNum(source.getLevel()); + for (int i = remain.length-1; i >= 0; --i) { + String text; + if (i == 0) text = "Enemy players are currently able to break "+remain[i]+" blocks from all other groups!"; + else text = "Enemy players are currently able to break "+remain[i]+" blocks from group "+i+"!"; + source.sendSuccess(Component.literal(text), false); + } return 1; } diff --git a/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksWorldConfig.java b/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksWorldConfig.java index f8e9928b..a0b1b882 100644 --- a/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksWorldConfig.java +++ b/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksWorldConfig.java @@ -41,8 +41,9 @@ public interface FTBChunksWorldConfig { BooleanValue OFFLINE_PROTECTION_ONLY_ALL = CONFIG.getBoolean("offline_protection_only_all", false).comment("If enabled and disable_protection = false all protections will be disabled when the team is online."); BooleanValue OFFLINE_PROTECTION_ONLY_BLOCKS = CONFIG.getBoolean("offline_protection_only_blocks", false).comment("If enabled and disable_protection = false block protection ONLY will be disabled when a team is online."); IntValue OFFLINE_PROTECTION_BUFFER = CONFIG.getInt("offline_protection_buffer", 30).comment("If offline_protection_only = true, the time in SECONDS after all members of a team log off, before chunk protection turns on. This setting is meant to discourage combat logging. Set to 0 to disable. Set to -1 for unlimited block breaking if offline_protection_only = true."); - IntValue MAX_DESTROY_BLOCKS_PER_HOUR = CONFIG.getInt("max_destroy_blocks_per_hour", 0).comment("If disable_protection = false, this many blocks can still be destroyed per hour be enemy players. 0 disables this."); - // 2nd destroy blocks for hour group + IntValue MAX_DESTROY_BLOCKS_PER_HOUR_OTHER = CONFIG.getInt("max_destroy_blocks_per_hour_other", 0).comment("If disable_protection = false, this many blocks that aren't in sub group tags can still be destroyed per hour be enemy players. 0 disables this."); + IntValue MAX_DESTROY_BLOCKS_PER_HOUR_GROUP_1 = CONFIG.getInt("max_destroy_blocks_per_hour_group_1", 0).comment("If disable_protection = false, this many blocks in the count_breaks_1 tag can still be destroyed per hour be enemy players. 0 disables this."); + IntValue MAX_DESTROY_BLOCKS_PER_HOUR_GROUP_2 = CONFIG.getInt("max_destroy_blocks_per_hour_group_2", 0).comment("If disable_protection = false, this many blocks in the count_breaks_2 tag can still be destroyed per hour be enemy players. 0 disables this."); IntValue DESTROY_BLOCKS_COUNT_PERIOD = CONFIG.getInt("destroy_blocks_count_period", 300).comment("If max_destroy_blocks_per_hour > 0, the groups of time in seconds where the number of blocks broken are counted. Groups younger than an hour contribute to the total blocks broken. Groups older than an hour are removed."); BooleanValue PROTECT_ENTITIES_OFFLINE_ONLY = CONFIG.getBoolean("protect_entities_offline_only", true).comment("Only protect the living entities listed in the living_entity_attack_blacklist tag when all team members are offline."); BooleanValue PROTECT_NAMED_ENTITIES = CONFIG.getBoolean("protect_named_entities", false).comment("Protect entities that have a name tag."); diff --git a/common/src/main/java/dev/ftb/mods/ftbchunks/data/FTBChunksAPI.java b/common/src/main/java/dev/ftb/mods/ftbchunks/data/FTBChunksAPI.java index 74d51c95..0755b892 100644 --- a/common/src/main/java/dev/ftb/mods/ftbchunks/data/FTBChunksAPI.java +++ b/common/src/main/java/dev/ftb/mods/ftbchunks/data/FTBChunksAPI.java @@ -24,6 +24,8 @@ public class FTBChunksAPI { public static final TagKey EDIT_WHITELIST_TAG = TagKey.create(Registry.BLOCK_REGISTRY, new ResourceLocation(FTBChunks.MOD_ID, "edit_whitelist")); public static final TagKey EDIT_BLACKLIST_TAG = TagKey.create(Registry.BLOCK_REGISTRY, new ResourceLocation(FTBChunks.MOD_ID, "edit_blacklist")); public static final TagKey INTERACT_WHITELIST_TAG = TagKey.create(Registry.BLOCK_REGISTRY, new ResourceLocation(FTBChunks.MOD_ID, "interact_whitelist")); + public static final TagKey COUNT_BREAKS_1 = TagKey.create(Registry.BLOCK_REGISTRY, new ResourceLocation(FTBChunks.MOD_ID, "count_breaks_1")); + public static final TagKey COUNT_BREAKS_2 = TagKey.create(Registry.BLOCK_REGISTRY, new ResourceLocation(FTBChunks.MOD_ID, "count_breaks_2")); public static final TagKey RIGHT_CLICK_BLACKLIST_TAG = TagKey.create(Registry.ITEM_REGISTRY, new ResourceLocation(FTBChunks.MOD_ID, "right_click_blacklist")); public static final TagKey RIGHT_CLICK_WHITELIST_TAG = TagKey.create(Registry.ITEM_REGISTRY, new ResourceLocation(FTBChunks.MOD_ID, "right_click_whitelist")); public static final TagKey> ENTITY_INTERACT_WHITELIST_TAG = TagKey.create(Registry.ENTITY_TYPE_REGISTRY, new ResourceLocation(FTBChunks.MOD_ID, "entity_interact_whitelist")); diff --git a/common/src/main/java/dev/ftb/mods/ftbchunks/data/FTBChunksTeamData.java b/common/src/main/java/dev/ftb/mods/ftbchunks/data/FTBChunksTeamData.java index 97bf4417..37f6c135 100644 --- a/common/src/main/java/dev/ftb/mods/ftbchunks/data/FTBChunksTeamData.java +++ b/common/src/main/java/dev/ftb/mods/ftbchunks/data/FTBChunksTeamData.java @@ -42,6 +42,7 @@ import java.nio.file.Path; import java.util.*; +import java.util.function.Supplier; import java.util.stream.Collectors; /** @@ -84,7 +85,9 @@ public class FTBChunksTeamData { private long lastLoginTime; private long lastLogoffTime; private Set fakePlayerNameCache; - private final BrokenBlocksCounter brokenBlocksCounter; + private final BrokenBlocksCounter brokenBlocksCounterGroup1; + private final BrokenBlocksCounter brokenBlocksCounterGroup2; + private final BrokenBlocksCounter brokenBlocksCounterOther; public FTBChunksTeamData(ClaimedChunkManager m, Path f, Team t) { manager = m; @@ -98,7 +101,9 @@ public FTBChunksTeamData(ClaimedChunkManager m, Path f, Team t) { lastLoginTime = 0L; lastLogoffTime = 0L; memberData = new HashMap<>(); - brokenBlocksCounter = new BrokenBlocksCounter(); + brokenBlocksCounterGroup1 = new BrokenBlocksCounter(FTBChunksWorldConfig.MAX_DESTROY_BLOCKS_PER_HOUR_GROUP_1::get); + brokenBlocksCounterGroup2 = new BrokenBlocksCounter(FTBChunksWorldConfig.MAX_DESTROY_BLOCKS_PER_HOUR_GROUP_2::get); + brokenBlocksCounterOther = new BrokenBlocksCounter(FTBChunksWorldConfig.MAX_DESTROY_BLOCKS_PER_HOUR_OTHER::get); } @Override @@ -335,7 +340,15 @@ public boolean canBreak(ServerPlayer p, PrivacyProperty property, boolean leftCl if (baseUseCheck(p, property, false, forceLoadedChunk)) return true; if (isOnlineBlockProtectionDisabled() && !canUseOffline()) return false; if (state.is(FTBChunksAPI.EDIT_BLACKLIST_TAG)) return false; - if (brokenBlocksCounter.canBreakBlock(p, leftClick)) { + if (state.is(FTBChunksAPI.COUNT_BREAKS_1)) + return checkGroup(brokenBlocksCounterGroup1, p, leftClick); + if (state.is(FTBChunksAPI.COUNT_BREAKS_2)) + return checkGroup(brokenBlocksCounterGroup2, p, leftClick); + return checkGroup(brokenBlocksCounterOther, p, leftClick); + } + + private boolean checkGroup(BrokenBlocksCounter counter, ServerPlayer player, boolean leftClick) { + if (counter.canBreakBlock(player, leftClick)) { if (!leftClick) save(); return true; } @@ -408,7 +421,9 @@ public SNBTCompoundTag serializeNBT() { tag.put("member_data", memberTag); } - tag.put("broken_blocks_counter", brokenBlocksCounter.serializeNBT()); + tag.put("broken_blocks_counter_group_1", brokenBlocksCounterGroup1.serializeNBT()); + tag.put("broken_blocks_counter_group_2", brokenBlocksCounterGroup2.serializeNBT()); + tag.put("broken_blocks_counter_other", brokenBlocksCounterOther.serializeNBT()); return tag; } @@ -447,7 +462,9 @@ public void deserializeNBT(CompoundTag tag) { } } - brokenBlocksCounter.deserializeNBT(tag.getCompound("broken_blocks_counter")); + brokenBlocksCounterGroup1.deserializeNBT(tag.getCompound("broken_blocks_counter_group_1")); + brokenBlocksCounterGroup2.deserializeNBT(tag.getCompound("broken_blocks_counter_group_2")); + brokenBlocksCounterOther.deserializeNBT(tag.getCompound("broken_blocks_counter_other")); } public int getExtraClaimChunks() { @@ -709,15 +726,19 @@ public void deleteMemberData(UUID playerId) { } public void resetBrokenBlocksCounter() { - brokenBlocksCounter.reset(); + brokenBlocksCounterGroup1.reset(); + brokenBlocksCounterGroup2.reset(); + brokenBlocksCounterOther.reset(); save(); } - public int getRemainingBreakableBlocksNum(Level level) { - long time = level.getGameTime(); - int blocks_per_hour = FTBChunksWorldConfig.MAX_DESTROY_BLOCKS_PER_HOUR.get(); - int total = brokenBlocksCounter.getTotalBrokenBlocks(time); - return blocks_per_hour - total; + /** + * @return index 0 = remaining for ungrouped blocks, index 1 = remaining for group 1, index 2 = remaining for group 2. + */ + public int[] getRemainingBreakableBlocksNum(Level level) { + return new int[] {brokenBlocksCounterOther.getRemainingBreaks(level), + brokenBlocksCounterGroup1.getRemainingBreaks(level), + brokenBlocksCounterGroup2.getRemainingBreaks(level)}; } public static final Style WARNING_STYLE = Style.EMPTY.withColor(0xFFFF55); @@ -725,10 +746,13 @@ public int getRemainingBreakableBlocksNum(Level level) { public static class BrokenBlocksCounter { private final List groups = new ArrayList<>(); - public BrokenBlocksCounter() {} + private final Supplier maxBlocksPerHour; + public BrokenBlocksCounter(Supplier maxBlocksPerHour) { + this.maxBlocksPerHour = maxBlocksPerHour; + } public boolean canBreakBlock(ServerPlayer p, boolean leftClick) { long time = p.getLevel().getGameTime(); - int blocks_per_hour = FTBChunksWorldConfig.MAX_DESTROY_BLOCKS_PER_HOUR.get(); + int blocks_per_hour = getMaxBlockBreaksPerHour(); if (blocks_per_hour == -1) return true; int total = getTotalBrokenBlocks(time); @@ -771,6 +795,15 @@ private void removeOldGroups(long time) { public void reset() { groups.clear(); } + public int getRemainingBreaks(Level level) { + long time = level.getGameTime(); + int blocks_per_hour = getMaxBlockBreaksPerHour(); + int total = getTotalBrokenBlocks(time); + return blocks_per_hour - total; + } + public int getMaxBlockBreaksPerHour() { + return maxBlocksPerHour.get(); + } public SNBTCompoundTag serializeNBT() { SNBTCompoundTag tag = new SNBTCompoundTag(); ListTag list = new ListTag(); diff --git a/common/src/main/resources/data/ftbchunks/tags/blocks/count_breaks_1.json b/common/src/main/resources/data/ftbchunks/tags/blocks/count_breaks_1.json new file mode 100644 index 00000000..e16d480c --- /dev/null +++ b/common/src/main/resources/data/ftbchunks/tags/blocks/count_breaks_1.json @@ -0,0 +1,45 @@ +{ + "replace": false, + "values": [ + { + "id": "#forge:chests", + "required": false + }, + { + "id": "#storagedrawers:drawers", + "required": false + }, + { + "id": "ironchest:iron_chest", + "required": false + }, + { + "id": "ironchest:gold_chest", + "required": false + }, + { + "id": "ironchest:diamond_chest", + "required": false + }, + { + "id": "ironchest:copper_chest", + "required": false + }, + { + "id": "ironchest:crystal_chest", + "required": false + }, + { + "id": "ironchest:obsidian_chest", + "required": false + }, + { + "id": "ironchest:dirt_chest", + "required": false + }, + { + "id": "ae2:drive", + "required": false + } + ] +} \ No newline at end of file diff --git a/common/src/main/resources/data/ftbchunks/tags/blocks/count_breaks_2.json b/common/src/main/resources/data/ftbchunks/tags/blocks/count_breaks_2.json new file mode 100644 index 00000000..ad5c59a8 --- /dev/null +++ b/common/src/main/resources/data/ftbchunks/tags/blocks/count_breaks_2.json @@ -0,0 +1,25 @@ +{ + "replace": false, + "values": [ + { + "id": "#createaddition:plants", + "required": false + }, + { + "id": "#supplementaries:flower_box_plantable", + "required": false + }, + { + "id": "#minecraft:flowers", + "required": false + }, + { + "id": "minecraft:tall_grass", + "required": false + }, + { + "id": "#minecraft:leaves", + "required": false + } + ] +} \ No newline at end of file From 8a77d6416be9b1a03de82edb8debb60bfd1f9a72 Mon Sep 17 00:00:00 2001 From: 1whohears <1whohears28@gmail.com> Date: Sun, 23 Feb 2025 16:49:36 -0600 Subject: [PATCH 17/17] fixed offhand item overwriting main hand item when client syncing item packets are sent. a common issue when in an enemy chunk is when you eat while holding a shield in the off hand and while looking at a block, the shield replaces the food item on the client side. --- .../java/dev/ftb/mods/ftbchunks/FTBCUtils.java | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/common/src/main/java/dev/ftb/mods/ftbchunks/FTBCUtils.java b/common/src/main/java/dev/ftb/mods/ftbchunks/FTBCUtils.java index b4e08886..83480697 100644 --- a/common/src/main/java/dev/ftb/mods/ftbchunks/FTBCUtils.java +++ b/common/src/main/java/dev/ftb/mods/ftbchunks/FTBCUtils.java @@ -1,15 +1,21 @@ package dev.ftb.mods.ftbchunks; +import com.mojang.datafixers.util.Pair; import dev.architectury.injectables.annotations.ExpectPlatform; import net.minecraft.network.protocol.game.ClientboundContainerSetSlotPacket; +import net.minecraft.network.protocol.game.ClientboundSetEquipmentPacket; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.InteractionHand; import net.minecraft.world.effect.MobEffectCategory; +import net.minecraft.world.entity.EquipmentSlot; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.PotionItem; import net.minecraft.world.item.alchemy.PotionUtils; import net.minecraft.world.level.block.Block; +import java.util.ArrayList; +import java.util.List; + public class FTBCUtils { @ExpectPlatform public static boolean isRail(Block block) { @@ -28,8 +34,14 @@ public static boolean isBeneficialPotion(ItemStack stack) { * @param hand the hand being used */ public static void forceHeldItemSync(ServerPlayer sp, InteractionHand hand) { - if (sp.connection != null) { - sp.connection.send(new ClientboundContainerSetSlotPacket(-2, 0, sp.getInventory().selected, sp.getItemInHand(hand))); + if (sp.connection == null) return; + if (hand == InteractionHand.MAIN_HAND) { + sp.connection.send(new ClientboundContainerSetSlotPacket(-2, 0, + sp.getInventory().selected, sp.getItemInHand(hand))); + } else if (hand == InteractionHand.OFF_HAND) { + List> slots = new ArrayList<>(); + slots.add(new Pair<>(EquipmentSlot.OFFHAND, sp.getInventory().offhand.get(0))); + sp.connection.send(new ClientboundSetEquipmentPacket(sp.getId(), slots)); } } }