22
33import com .earth2me .essentials .User ;
44import com .earth2me .essentials .utils .EnumUtil ;
5+ import com .earth2me .essentials .utils .MaterialUtil ;
56import com .earth2me .essentials .utils .VersionUtil ;
67import net .ess3 .api .IEssentials ;
78import org .bukkit .Material ;
89import org .bukkit .block .Block ;
10+ import org .bukkit .block .BlockFace ;
11+ import org .bukkit .block .data .Directional ;
912import org .bukkit .entity .ArmorStand ;
1013import org .bukkit .entity .EnderCrystal ;
1114import org .bukkit .entity .Entity ;
3235import org .bukkit .event .player .PlayerInteractEvent ;
3336import org .bukkit .event .player .PlayerPickupItemEvent ;
3437import org .bukkit .inventory .ItemStack ;
38+ import org .bukkit .material .Sign ;
3539
40+ import java .util .function .Predicate ;
3641import java .util .logging .Level ;
3742
3843public class EssentialsAntiBuildListener implements Listener {
@@ -107,6 +112,64 @@ private boolean metaPermCheck(final User user, final String action, final Materi
107112 return user .isAuthorized (blockPerm );
108113 }
109114
115+ private boolean wouldBreakProtectedSigns (final Block block , final User user ) {
116+ return wouldBreakAttachedSigns (block , signBlock -> isSignProtected (signBlock , user ));
117+ }
118+
119+ private boolean isSignProtected (final Block signBlock , final User user ) {
120+ final Material signType = signBlock .getType ();
121+
122+ if (prot .getSettingBool (AntiBuildConfig .disable_build ) && !user .canBuild () && !metaPermCheck (user , "break" , signBlock )) {
123+ return true ;
124+ }
125+
126+ return prot .checkProtectionItems (AntiBuildConfig .blacklist_break , signType ) && !user .isAuthorized ("essentials.protect.exemptbreak" );
127+ }
128+
129+ private BlockFace getWallSignFacing (final Block signBlock ) {
130+ if (VersionUtil .PRE_FLATTENING ) {
131+ final Sign signMat = (Sign ) signBlock .getState ().getData ();
132+ return signMat .getFacing ();
133+ }
134+
135+ final Directional signData = (Directional ) signBlock .getState ().getBlockData ();
136+ return signData .getFacing ();
137+ }
138+
139+ private boolean wouldBreakAttachedSigns (final Block block , final Predicate <Block > signChecker ) {
140+ // Check for sign posts above the block
141+ final Block signAbove = block .getRelative (BlockFace .UP );
142+ if (MaterialUtil .isSignPost (signAbove .getType ()) && signChecker .test (signAbove )) {
143+ return true ;
144+ }
145+
146+ // Check for hanging signs below the block
147+ final Block signBelow = block .getRelative (BlockFace .DOWN );
148+ if (MaterialUtil .isHangingSign (signBelow .getType ()) && signChecker .test (signBelow )) {
149+ return true ;
150+ }
151+
152+ // Check for wall signs and wall hanging signs attached to the block faces
153+ final BlockFace [] directions = new BlockFace [] {BlockFace .NORTH , BlockFace .EAST , BlockFace .SOUTH , BlockFace .WEST };
154+ for (final BlockFace blockFace : directions ) {
155+ final Block signBlock = block .getRelative (blockFace );
156+ if (MaterialUtil .isWallSign (signBlock .getType ()) || MaterialUtil .isWallHangingSign (signBlock .getType ())) {
157+ try {
158+ if (getWallSignFacing (signBlock ) == blockFace && signChecker .test (signBlock )) {
159+ return true ;
160+ }
161+ } catch (final NullPointerException ignored ) {
162+ }
163+ }
164+ }
165+
166+ return false ;
167+ }
168+
169+ private boolean wouldBreakAnySign (final Block block ) {
170+ return wouldBreakAttachedSigns (block , signBlock -> true );
171+ }
172+
110173 @ EventHandler (priority = EventPriority .HIGHEST , ignoreCancelled = true )
111174 public void onBlockPlace (final BlockPlaceEvent event ) {
112175 final User user = ess .getUser (event .getPlayer ());
@@ -145,6 +208,15 @@ public void onBlockBreak(final BlockBreakEvent event) {
145208 final Block block = event .getBlock ();
146209 final Material type = block .getType ();
147210
211+ // Check if breaking this block would cause any protected signs to break
212+ if (wouldBreakProtectedSigns (block , user )) {
213+ if (ess .getSettings ().warnOnBuildDisallow ()) {
214+ user .sendTl ("antiBuildBreak" , EssentialsAntiBuild .getNameForType (type ));
215+ }
216+ event .setCancelled (true );
217+ return ;
218+ }
219+
148220 if (prot .getSettingBool (AntiBuildConfig .disable_build ) && !user .canBuild () && !metaPermCheck (user , "break" , block )) {
149221 if (ess .getSettings ().warnOnBuildDisallow ()) {
150222 user .sendTl ("antiBuildBreak" , EssentialsAntiBuild .getNameForType (type ));
@@ -314,6 +386,11 @@ public void onBlockPistonExtend(final BlockPistonExtendEvent event) {
314386 event .setCancelled (true );
315387 return ;
316388 }
389+
390+ if (wouldBreakAnySign (block )) {
391+ event .setCancelled (true );
392+ return ;
393+ }
317394 }
318395 }
319396
@@ -327,6 +404,11 @@ public void onBlockPistonRetract(final BlockPistonRetractEvent event) {
327404 event .setCancelled (true );
328405 return ;
329406 }
407+
408+ if (wouldBreakAnySign (block )) {
409+ event .setCancelled (true );
410+ return ;
411+ }
330412 }
331413 }
332414
0 commit comments