Skip to content

Commit e2d9f8a

Browse files
authored
Merge pull request #268 from FTBTeam/dev
Dev
2 parents b4897b1 + b34a96a commit e2d9f8a

13 files changed

+118
-17
lines changed

Diff for: CHANGELOG.md

+18-3
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,30 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7+
## [2001.2.3]
8+
9+
### Added
10+
* Added a team property to control whether PvP is permitted in a team's claims
11+
* If PvP is prevented, then if either the attacking player or the attacked player is in such a claim, PvP damage will be cancelled
12+
* Can be controlled by server admin with the server config "Allow PvP Combat"
13+
* "always" (default) allows PvP everywhere
14+
* "never" prevents PvP in all claimed chunks
15+
* "per_team" allows teams to configure PvP for their claims via new team property "Allow PvP Combat"
16+
* Not 100% guaranteed to prevent all forms of PvP damage, but direct or projectile damage is prevented where the damage source can be traced back to a player
17+
18+
### Fixed
19+
* Fixed a held item desync when an item or block right-click is prevented in a claimed area
20+
* Cleaned up stale kubjes support files (kubejs.classfilter.txt / kubejs.plugins.txt) - they're in FTB XMod Compat now
21+
722
## [2001.2.2]
823

9-
### Fixes
24+
### Fixed
1025
* Fixed crash on player disconnect if they don't have a team assigned
11-
* Should never occur under normal circumstance but could happen if external factors force a premature disconnect
26+
* Should never occur under normal circumstances but could happen if external factors force a premature disconnect
1227

1328
## [2001.2.1]
1429

15-
### Fixes
30+
### Fixed
1631
* Fixed "Show waypoints in world" client config setting being ignored for waypoint icons
1732
* It was only working to suppress beacons when set to false, now it suppresses icons too
1833
* Fixed NPE when checking for fake players which had a null name or UUID in their GameProfile

Diff for: common/src/main/java/dev/ftb/mods/ftbchunks/FTBCUtils.java

+8-4
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import net.minecraft.network.protocol.game.ClientboundContainerSetSlotPacket;
55
import net.minecraft.server.level.ServerPlayer;
66
import net.minecraft.world.InteractionHand;
7+
import net.minecraft.world.entity.player.Inventory;
78
import net.minecraft.world.level.block.Block;
89

910
public class FTBCUtils {
@@ -13,16 +14,19 @@ public static boolean isRail(Block block) {
1314
}
1415

1516

16-
1717
/**
1818
* Used after various events have been cancelled server-side; client may already have updated the held item for the
1919
* player, but it needs to be brought back in sync with the server.
20-
* @param sp the player
20+
*
21+
* @param sp the player
2122
* @param hand the hand being used
2223
*/
2324
public static void forceHeldItemSync(ServerPlayer sp, InteractionHand hand) {
2425
if (sp.connection != null) {
25-
sp.connection.send(new ClientboundContainerSetSlotPacket(-2, 0, sp.getInventory().selected, sp.getItemInHand(hand)));
26+
switch (hand) {
27+
case MAIN_HAND -> sp.connection.send(new ClientboundContainerSetSlotPacket(-2, 0, sp.getInventory().selected, sp.getItemInHand(hand)));
28+
case OFF_HAND -> sp.connection.send(new ClientboundContainerSetSlotPacket(-2, 0, Inventory.SLOT_OFFHAND, sp.getItemInHand(hand)));
29+
}
2630
}
2731
}
28-
}
32+
}

Diff for: common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunks.java

+30-6
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,12 @@
1111
import dev.architectury.utils.Env;
1212
import dev.architectury.utils.EnvExecutor;
1313
import dev.architectury.utils.value.IntValue;
14+
import dev.ftb.mods.ftbchunks.api.ClaimedChunk;
1415
import dev.ftb.mods.ftbchunks.api.FTBChunksAPI;
1516
import dev.ftb.mods.ftbchunks.api.FTBChunksProperties;
1617
import dev.ftb.mods.ftbchunks.api.Protection;
1718
import dev.ftb.mods.ftbchunks.client.FTBChunksClient;
18-
import dev.ftb.mods.ftbchunks.data.ChunkTeamDataImpl;
19-
import dev.ftb.mods.ftbchunks.data.ClaimExpirationManager;
20-
import dev.ftb.mods.ftbchunks.data.ClaimedChunkImpl;
21-
import dev.ftb.mods.ftbchunks.data.ClaimedChunkManagerImpl;
19+
import dev.ftb.mods.ftbchunks.data.*;
2220
import dev.ftb.mods.ftbchunks.net.*;
2321
import dev.ftb.mods.ftblibrary.integration.stages.StageHelper;
2422
import dev.ftb.mods.ftblibrary.math.ChunkDimPos;
@@ -28,17 +26,20 @@
2826
import dev.ftb.mods.ftblibrary.snbt.config.ConfigUtil;
2927
import dev.ftb.mods.ftbteams.api.FTBTeamsAPI;
3028
import dev.ftb.mods.ftbteams.api.event.*;
29+
import net.minecraft.ChatFormatting;
3130
import net.minecraft.Util;
3231
import net.minecraft.commands.CommandSourceStack;
3332
import net.minecraft.core.BlockPos;
3433
import net.minecraft.core.Direction;
3534
import net.minecraft.core.registries.Registries;
35+
import net.minecraft.network.chat.Component;
3636
import net.minecraft.resources.ResourceKey;
3737
import net.minecraft.server.MinecraftServer;
3838
import net.minecraft.server.level.ServerLevel;
3939
import net.minecraft.server.level.ServerPlayer;
4040
import net.minecraft.stats.Stats;
4141
import net.minecraft.world.InteractionHand;
42+
import net.minecraft.world.damagesource.DamageSource;
4243
import net.minecraft.world.entity.Entity;
4344
import net.minecraft.world.entity.LivingEntity;
4445
import net.minecraft.world.entity.MobSpawnType;
@@ -122,6 +123,7 @@ public FTBChunks() {
122123

123124
EntityEvent.ENTER_SECTION.register(this::enterSection);
124125
EntityEvent.LIVING_CHECK_SPAWN.register(this::checkSpawn);
126+
EntityEvent.LIVING_HURT.register(this::onLivingHurt);
125127

126128
ExplosionEvent.DETONATE.register(this::explosionDetonate);
127129

@@ -136,13 +138,34 @@ public FTBChunks() {
136138
private EventResult playerAttackEntity(Player player, Level level, Entity entity, InteractionHand interactionHand, @Nullable EntityHitResult entityHitResult) {
137139
// note: intentionally does not prevent attacking living entities;
138140
// this is for preventing griefing of entities like paintings & item frames
139-
if (player instanceof ServerPlayer && !(entity instanceof LivingEntity) && ClaimedChunkManagerImpl.getInstance().shouldPreventInteraction(player, interactionHand, entity.blockPosition(), Protection.ATTACK_NONLIVING_ENTITY, entity)) {
140-
return EventResult.interruptFalse();
141+
if (player instanceof ServerPlayer) {
142+
if (!(entity instanceof LivingEntity) && ClaimedChunkManagerImpl.getInstance().shouldPreventInteraction(player, interactionHand, entity.blockPosition(), Protection.ATTACK_NONLIVING_ENTITY, entity)) {
143+
return EventResult.interruptFalse();
144+
}
141145
}
142146

143147
return EventResult.pass();
144148
}
145149

150+
private EventResult onLivingHurt(LivingEntity living, DamageSource damageSource, float dmg) {
151+
if (!living.level().isClientSide() && living instanceof Player target && damageSource.getEntity() instanceof Player attacker) {
152+
PvPMode mode = FTBChunksWorldConfig.PVP_MODE.get();
153+
if (mode == PvPMode.ALWAYS) {
154+
return EventResult.pass();
155+
}
156+
if (isPvPProtectedChunk(mode, attacker) || isPvPProtectedChunk(mode, target)) {
157+
PlayerNotifier.notifyWithCooldown(attacker, Component.translatable("ftbchunks.message.no_pvp").withStyle(ChatFormatting.GOLD), 3000L);
158+
return EventResult.interruptFalse();
159+
}
160+
}
161+
return EventResult.pass();
162+
}
163+
164+
private boolean isPvPProtectedChunk(PvPMode mode, Player player) {
165+
ClaimedChunk cc = ClaimedChunkManagerImpl.getInstance().getChunk(new ChunkDimPos(player.level(), player.blockPosition()));
166+
return cc != null && (mode == PvPMode.NEVER || !cc.getTeamData().allowPVP());
167+
}
168+
146169
private void playerTickPost(Player player) {
147170
if (player.level().isClientSide && player.level().getGameTime() % 20 == 0) {
148171
FTBChunksClient.INSTANCE.maybeClearDeathpoint(player);
@@ -408,6 +431,7 @@ private void teamConfig(TeamCollectPropertiesEvent event) {
408431
event.add(FTBChunksProperties.ALLOW_ALL_FAKE_PLAYERS);
409432
event.add(FTBChunksProperties.ALLOW_NAMED_FAKE_PLAYERS);
410433
event.add(FTBChunksProperties.ALLOW_FAKE_PLAYERS_BY_ID);
434+
event.add(FTBChunksProperties.ALLOW_PVP);
411435

412436
// block edit/interact properties vary on forge & fabric
413437
FTBChunksExpected.getPlatformSpecificProperties(event);

Diff for: common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksWorldConfig.java

+2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import dev.ftb.mods.ftbchunks.data.AllyMode;
66
import dev.ftb.mods.ftbchunks.data.ForceLoadMode;
77
import dev.ftb.mods.ftbchunks.data.PartyLimitMode;
8+
import dev.ftb.mods.ftbchunks.data.PvPMode;
89
import dev.ftb.mods.ftbchunks.integration.PermissionsHelper;
910
import dev.ftb.mods.ftbchunks.util.DimensionFilter;
1011
import dev.ftb.mods.ftblibrary.config.NameMap;
@@ -24,6 +25,7 @@ public interface FTBChunksWorldConfig {
2425
EnumValue<ForceLoadMode> FORCE_LOAD_MODE = CONFIG.addEnum("force_load_mode", ForceLoadMode.NAME_MAP).comment("Control how force-loaded chunks work.","NEVER: only allow chunk force-loading if the owning team has at least one online player.","ALWAYS: always allow force-loading, even if no players are online.","DEFAULT: allow force-loading IF the team has at least one player with the 'ftbchunks.chunk_load_offline' FTB Ranks permission.");
2526
BooleanValue DISABLE_PROTECTION = CONFIG.addBoolean("disable_protection", false).comment("Disables all land protection. Useful for private servers where everyone is trusted and claims are only used for force-loading");
2627
EnumValue<AllyMode> ALLY_MODE = CONFIG.addEnum("ally_mode", AllyMode.NAME_MAP).comment("Forced modes won't let players change their ally settings");
28+
EnumValue<PvPMode> PVP_MODE = CONFIG.addEnum("pvp_mode", PvPMode.NAME_MAP).comment("Should PvP combat be allowed in claimed chunks? Default is ALWAYS; NEVER prevents it in all claimed chunks; PER_TEAM allows teams to decide if PvP is allowed in their claims");
2729
StringListValue CLAIM_DIMENSION_BLACKLIST = CONFIG.addStringList("claim_dimension_blacklist", Collections.emptyList()).comment("Dimension ID's where chunks may not be claimed. Add \"minecraft:the_end\" to this list if you want to disable chunk claiming in The End, or \"othermod:*\" to disable chunk claiming in *all* dimensions added by \"othermod\"");
2830
StringListValue CLAIM_DIMENSION_WHITELIST = CONFIG.addStringList("claim_dimension_whitelist", Collections.emptyList()).comment("Dimension ID's where chunks may be claimed. If non-empty, chunks may be claimed *only* in these dimensions (and the dimension is not in \"claim_dimension_blacklist\"). Same syntax as for \"claim_dimension_blacklist\".");
2931
BooleanValue NO_WILDERNESS = CONFIG.addBoolean("no_wilderness", false).comment("Requires you to claim chunks in order to edit and interact with blocks");
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package dev.ftb.mods.ftbchunks;
2+
3+
import it.unimi.dsi.fastutil.objects.Object2LongMap;
4+
import it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap;
5+
import net.minecraft.network.chat.Component;
6+
import net.minecraft.world.entity.player.Player;
7+
8+
import java.util.UUID;
9+
10+
public class PlayerNotifier {
11+
private static final Object2LongMap<UUID> lastNotified = new Object2LongOpenHashMap<>();
12+
13+
public static void notifyWithCooldown(Player player, Component msg, long cooldownMS) {
14+
long now = System.currentTimeMillis();
15+
if (now - lastNotified.getOrDefault(player.getUUID(), 0L) > cooldownMS) {
16+
player.displayClientMessage(msg, true);
17+
lastNotified.put(player.getUUID(), now);
18+
}
19+
}
20+
}

Diff for: common/src/main/java/dev/ftb/mods/ftbchunks/api/ChunkTeamData.java

+14
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,20 @@ public interface ChunkTeamData {
198198
*/
199199
boolean allowMobGriefing();
200200

201+
/**
202+
* Is player-vs-player damage allowed in chunks claimed by this team? This is a convenience method to check
203+
* the value of the {@link FTBChunksProperties#ALLOW_PVP} team property.
204+
* <p>
205+
* If PvP is not allowed, then if either the attacker or the victim are in a claimed chunk, PvP damage will
206+
* be cancelled. Note this is not 100% foolproof, e.g. it won't prevent a player pouring a bucket of lava
207+
* over another player, for example.
208+
* <p>
209+
* This is also dependent on the server's "Allow PvP Combat" setting being set to "per_team".
210+
*
211+
* @return true if PvP os permitted, false if not
212+
*/
213+
boolean allowPVP();
214+
201215
/**
202216
* Get the time (milliseconds since the epoch) that any member of this team logged in to the server. This time is
203217
* used when chunk claiming and force-load expiry is in effect on this server.

Diff for: common/src/main/java/dev/ftb/mods/ftbchunks/api/FTBChunksProperties.java

+2
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ public class FTBChunksProperties {
3131
= new PrivacyProperty(new ResourceLocation(FTBChunks.MOD_ID, "claim_visibility"), PrivacyMode.PUBLIC);
3232
public static final PrivacyProperty LOCATION_MODE
3333
= new PrivacyProperty(new ResourceLocation(FTBChunks.MOD_ID, "location_mode"), PrivacyMode.ALLIES);
34+
public static final BooleanProperty ALLOW_PVP
35+
= new BooleanProperty(new ResourceLocation(FTBChunks.MOD_ID, "allow_pvp"), true);
3436

3537
// FTB Chunks on Forge adds two separate block edit & interact properties
3638
public static final PrivacyProperty BLOCK_EDIT_MODE

Diff for: common/src/main/java/dev/ftb/mods/ftbchunks/data/ChunkTeamDataImpl.java

+5
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,11 @@ public boolean allowMobGriefing() {
511511
return team.getProperty(FTBChunksProperties.ALLOW_MOB_GRIEFING);
512512
}
513513

514+
@Override
515+
public boolean allowPVP() {
516+
return team.getProperty(FTBChunksProperties.ALLOW_PVP);
517+
}
518+
514519
public void setLastLoginTime(long when) {
515520
this.lastLoginTime = when;
516521
markDirty();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package dev.ftb.mods.ftbchunks.data;
2+
3+
import dev.ftb.mods.ftblibrary.config.NameMap;
4+
5+
public enum PvPMode {
6+
ALWAYS,
7+
NEVER,
8+
PER_TEAM,
9+
;
10+
11+
public static final NameMap<PvPMode> NAME_MAP = NameMap.of(ALWAYS, values()).create();
12+
}

Diff for: common/src/main/resources/assets/ftbchunks/lang/en_us.json

+6-1
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,8 @@
119119
"ftbteamsconfig.ftbchunks.allow_fake_players_by_id.tooltip": "Allows fake players which have the ID of a real player access to your claims, IF that real player would be permitted, either as ally or team member. Set this to true if you're unsure.",
120120
"ftbteamsconfig.ftbchunks.allow_explosions": "Allow Explosion Damage",
121121
"ftbteamsconfig.ftbchunks.allow_explosions.tooltip": "Should explosions be able to damage blocks in claimed areas?",
122+
"ftbteamsconfig.ftbchunks.allow_pvp": "Allow PvP Combat",
123+
"ftbteamsconfig.ftbchunks.allow_pvp.tooltip": "Should player-vs-player combat be allowed in claimed areas?\nServer config setting 'Allow PvP Combat' must be 'per_team' for this to function\nNot guaranteed to protect against 100%% of indirect attacks; requires that damage sources can be attributed to a player",
122124
"ftbteamsconfig.ftbchunks.allow_mob_griefing": "Allow Mob Griefing Actions",
123125
"ftbteamsconfig.ftbchunks.allow_mob_griefing.tooltip": "Should mobs be allowed to damage blocks in claimed areas?\nNote: currently Endermen only; may include other mobs in future\nCreeper explosions are protected against via \"Allow Explosions\"",
124126
"ftbteamsconfig.ftbchunks.block_edit_and_interact_mode": "Block Edit/Interact Mode",
@@ -146,6 +148,8 @@
146148
"ftbchunks.force_load_mode.tooltip": "NEVER: only allow chunk force-loading if the owning team has at least one online player\nALWAYS: always allow force-loading, even if no players are online\nDEFAULT: allow force-loading IF the team has at least one player with the FTB Ranks 'ftbchunks.chunk_load_offline' permission",
147149
"ftbchunks.disable_protection": "Disable Claim Protection",
148150
"ftbchunks.disable_protection.tooltip": "Useful for private servers where everyone is trusted, and claims are only used for force-loading",
151+
"ftbchunks.pvp_mode": "Allow PvP Combat in Claimed Chunks",
152+
"ftbchunks.pvp_mode.tooltip": "ALWAYS: allow PvP combat in all claimed chunks\nNEVER: prevent PvP in all claimed chunks\nPER_TEAM: teams can decide if PvP is allowed in their claims via team property",
149153
"ftbchunks.ally_mode": "Allow Player to Change Ally Settings",
150154
"ftbchunks.ally_mode.tooltip": "DEFAULT: FTB Teams ally status is checked to decide if players are allied\nFORCED_ALL: all players are always considered to be allied\nFORCED_NONE: no players are ever considered to be allied",
151155
"ftbchunks.claim_dimension_blacklist": "Dimension Blacklist",
@@ -188,5 +192,6 @@
188192
"ftbchunks.claim_result.not_loaded": "Chunk not loaded",
189193
"ftbchunks.need_to_claim_chunk": "You need to claim this chunk to interact with blocks here!",
190194
"ftbchunks.label.show": "Show",
191-
"ftbchunks.label.hide": "Hide"
195+
"ftbchunks.label.hide": "Hide",
196+
"ftbchunks.message.no_pvp": "PvP combat is disabled here"
192197
}

Diff for: common/src/main/resources/kubejs.classfilter.txt

-1
This file was deleted.

Diff for: common/src/main/resources/kubejs.plugins.txt

-1
This file was deleted.

Diff for: gradle.properties

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ org.gradle.daemon=false
55
mod_id=ftbchunks
66
archives_base_name=ftb-chunks
77
maven_group=dev.ftb.mods
8-
mod_version=2001.2.2
8+
mod_version=2001.2.3
99
mod_author=FTB Team
1010

1111
minecraft_version=1.20.1

0 commit comments

Comments
 (0)