diff --git a/src/main/java/world/bentobox/bentobox/listeners/flags/protection/LockAndBanListener.java b/src/main/java/world/bentobox/bentobox/listeners/flags/protection/LockAndBanListener.java index 8f7860c6e..c5ddbdab5 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/flags/protection/LockAndBanListener.java +++ b/src/main/java/world/bentobox/bentobox/listeners/flags/protection/LockAndBanListener.java @@ -43,13 +43,24 @@ private enum CheckResult { /** * Island is open for teleporting */ - OPEN + OPEN, + /** + * Island is locked but player has bypass permission + */ + BYPASS_LOCK; + + /** + * @return true if the player is allowed to enter the island + */ + boolean isAllowed() { + return this != BANNED && this != LOCKED; + } } // Teleport check @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) public void onPlayerTeleport(PlayerTeleportEvent e) { - e.setCancelled(!checkAndNotify(e.getPlayer(), e.getTo()).equals(CheckResult.OPEN)); + e.setCancelled(!checkAndNotify(e.getPlayer(), e.getTo()).isAllowed()); } // Movement check @@ -59,14 +70,14 @@ public void onPlayerMove(PlayerMoveEvent e) { if (e.getFrom().getBlockX() - e.getTo().getBlockX() == 0 && e.getFrom().getBlockZ() - e.getTo().getBlockZ() == 0) { return; } - if (!checkAndNotify(e.getPlayer(), e.getTo()).equals(CheckResult.OPEN)) { + if (!checkAndNotify(e.getPlayer(), e.getTo()).isAllowed()) { e.setCancelled(true); e.getPlayer().playSound(e.getFrom(), Sound.BLOCK_ANVIL_HIT, 1F, 1F); e.getPlayer().setVelocity(new Vector(0,0,0)); e.getPlayer().setGliding(false); } // Check from - just in case the player is inside the island - if (!check(e.getPlayer(), e.getFrom()).equals(CheckResult.OPEN)) { + if (!check(e.getPlayer(), e.getFrom()).isAllowed()) { // Has to be done 1 tick later otherwise it doesn't happen for some reason... Bukkit.getScheduler().runTask(BentoBox.getInstance(), () -> eject(e.getPlayer())); } @@ -81,7 +92,7 @@ public void onVehicleMove(VehicleMoveEvent e) { } // For each Player in the vehicle e.getVehicle().getPassengers().stream().filter(Player.class::isInstance).map(Player.class::cast).forEach(p -> { - if (!checkAndNotify(p, e.getTo()).equals(CheckResult.OPEN)) { + if (!checkAndNotify(p, e.getTo()).isAllowed()) { p.leaveVehicle(); p.teleport(e.getFrom()); e.getVehicle().getWorld().playSound(e.getFrom(), Sound.BLOCK_ANVIL_HIT, 1F, 1F); @@ -93,7 +104,7 @@ public void onVehicleMove(VehicleMoveEvent e) { // Login check @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) public void onPlayerLogin(PlayerJoinEvent e) { - if (!checkAndNotify(e.getPlayer(), e.getPlayer().getLocation()).equals(CheckResult.OPEN)) { + if (!checkAndNotify(e.getPlayer(), e.getPlayer().getLocation()).isAllowed()) { eject(e.getPlayer()); } } @@ -124,7 +135,7 @@ private CheckResult check(@NonNull Player player, Location loc) if (!is.isAllowed(User.getInstance(player), Flags.LOCK)) { return player.hasPermission(getIWM().getPermissionPrefix(loc.getWorld()) + "mod.bypasslock") ? - CheckResult.OPEN : CheckResult.LOCKED; + CheckResult.BYPASS_LOCK : CheckResult.LOCKED; } return CheckResult.OPEN; }). @@ -144,6 +155,8 @@ private CheckResult checkAndNotify(@NonNull Player player, Location loc) User.getInstance(player).notify("commands.island.ban.you-are-banned"); } else if (result == CheckResult.LOCKED) { User.getInstance(player).notify("protection.locked"); + } else if (result == CheckResult.BYPASS_LOCK) { + User.getInstance(player).notify("protection.locked-island-bypass"); } return result; } diff --git a/src/main/resources/locales/cs.yml b/src/main/resources/locales/cs.yml index 4954b7abf..91fd89521 100644 --- a/src/main/resources/locales/cs.yml +++ b/src/main/resources/locales/cs.yml @@ -1677,6 +1677,7 @@ protection: &a entity mimo hranice ostrova. name: Světové poškození TNT locked: '&c Tento ostrov je zamčen!' + locked-island-bypass: '&6 Tento [prefix_island] je zamčen, ale máte povolení ho obejít.' protected: '&c Ostrov chráněn: [description]' world-protected: '&c Svět chráněn: [description]' spawn-protected: '&c Spawn chráněn: [description]' diff --git a/src/main/resources/locales/de.yml b/src/main/resources/locales/de.yml index fdaa47ca0..b9469d29c 100644 --- a/src/main/resources/locales/de.yml +++ b/src/main/resources/locales/de.yml @@ -1759,6 +1759,7 @@ protection: &a verletzen. name: Welt-TNT-Schaden locked: '&c Diese Insel ist gesperrt!' + locked-island-bypass: '&6 Diese [prefix_island] ist gesperrt, aber du hast die Erlaubnis, sie zu betreten.' protected: '&c Insel geschützt: [description]' world-protected: '&c Welt geschützt: [description]' spawn-protected: '&c Spawn geschützt: [description]' diff --git a/src/main/resources/locales/en-US.yml b/src/main/resources/locales/en-US.yml index 58072be98..bb6afef2e 100644 --- a/src/main/resources/locales/en-US.yml +++ b/src/main/resources/locales/en-US.yml @@ -1730,6 +1730,7 @@ protection: &a entities outside of [prefix_island] limits. name: World TNT damage locked: '&c This [prefix_island] is locked!' + locked-island-bypass: '&6 This [prefix_island] is locked, but you have permission to bypass.' protected: '&c [prefix_Island] protected: [description].' world-protected: '&c World protected: [description].' spawn-protected: '&c Spawn protected: [description].' diff --git a/src/main/resources/locales/es.yml b/src/main/resources/locales/es.yml index 6d650f9e4..1e09c74db 100644 --- a/src/main/resources/locales/es.yml +++ b/src/main/resources/locales/es.yml @@ -1719,6 +1719,7 @@ protection: &a entidades fuera de los límites de la isla. name: Daño mundial de TNT locked: '&cEsta isla esta cerrada!' + locked-island-bypass: '&6Esta [prefix_island] está cerrada, pero tienes permiso para acceder.' protected: '&cIsla protegida: [description]' world-protected: '&cMundo protegido: [description]' spawn-protected: '&cSpawn protegido: [description]' diff --git a/src/main/resources/locales/fr.yml b/src/main/resources/locales/fr.yml index 2266f5965..bb6148ce8 100644 --- a/src/main/resources/locales/fr.yml +++ b/src/main/resources/locales/fr.yml @@ -1747,6 +1747,7 @@ protection: &a entités en dehors des limites de l’île. name: Dommages mondiaux au TNT locked: '&c Cette île est verrouillée!' + locked-island-bypass: '&6 Cette [prefix_island] est verrouillée, mais vous avez la permission de la traverser.' protected: '&c Île protégée: [description]' world-protected: '&c Monde protégé: [description]' spawn-protected: '&c Spawn protégé: [description]' diff --git a/src/main/resources/locales/hr.yml b/src/main/resources/locales/hr.yml index d2542bf8d..6ffbec809 100644 --- a/src/main/resources/locales/hr.yml +++ b/src/main/resources/locales/hr.yml @@ -1717,6 +1717,7 @@ protection: &a entiteta izvan granica otoka. name: Svjetska TNT šteta locked: '&c Ovaj otok je zaključan!' + locked-island-bypass: '&6 Ovaj [prefix_island] je zaključan, ali imate dozvolu za pristup.' protected: '&c Otok zaštićen: [opis].' world-protected: '&c Svijet zaštićen: [opis].' spawn-protected: '&c Spawn zaštićeno: [opis].' diff --git a/src/main/resources/locales/hu.yml b/src/main/resources/locales/hu.yml index 441f76545..4c69d7527 100644 --- a/src/main/resources/locales/hu.yml +++ b/src/main/resources/locales/hu.yml @@ -1776,6 +1776,7 @@ protection: &a entitások a [prefix_island] határain kívül. name: Világ TNT kár locked: '&c Ez a [prefix_island] le van zárva!' + locked-island-bypass: '&6 Ez a [prefix_island] le van zárva, de van engedélyed a belépésre.' protected: '&c [prefix_Island] védett: [description].' world-protected: '&c Világvédett: [description].' spawn-protected: '&c Spawn védett: [description].' diff --git a/src/main/resources/locales/id.yml b/src/main/resources/locales/id.yml index 8c7601d2a..cb07fcd43 100644 --- a/src/main/resources/locales/id.yml +++ b/src/main/resources/locales/id.yml @@ -1743,6 +1743,7 @@ protection: &sebuah entitas di luar batas pulau. name: Kerusakan TNT dunia locked: '&c Pulau ini terkunci!' + locked-island-bypass: '&6 [prefix_Island] ini terkunci, tetapi kamu memiliki izin untuk melewatinya.' protected: '&c Pulau dilindungi: [deskripsi].' world-protected: '&c Dunia dilindungi: [deskripsi].' spawn-protected: '&c Bibit dilindungi: [deskripsi].' diff --git a/src/main/resources/locales/it.yml b/src/main/resources/locales/it.yml index 4ab11bf5b..ff8f7ddeb 100644 --- a/src/main/resources/locales/it.yml +++ b/src/main/resources/locales/it.yml @@ -1729,6 +1729,7 @@ protection: &a entità al di fuori dei limiti di [prefix_island]. name: Danno TNT nel mondo locked: '&cQuest''isola è bloccata!' + locked-island-bypass: '&6Questa [prefix_island] è bloccata, ma hai il permesso di accedervi.' protected: '&cIsola protetta: [description]' world-protected: '&c Mondo protetto: [description]' spawn-protected: '&cSpawn protetto: [description]' diff --git a/src/main/resources/locales/ja.yml b/src/main/resources/locales/ja.yml index b4b28adce..cc1be555b 100644 --- a/src/main/resources/locales/ja.yml +++ b/src/main/resources/locales/ja.yml @@ -1590,6 +1590,7 @@ protection: &a島の制限外のエンティティ。 name: 世界のTNTダメージ locked: 島はロックされている! + locked-island-bypass: '&6この[prefix_island]はロックされていますが、あなたはバイパスする権限を持っています。' protected: '島保護: [description]' world-protected: '&c世界保護: [description]' spawn-protected: '&c保護されたスポーン: [description]' diff --git a/src/main/resources/locales/ko.yml b/src/main/resources/locales/ko.yml index 13cfec9a5..694a9951e 100644 --- a/src/main/resources/locales/ko.yml +++ b/src/main/resources/locales/ko.yml @@ -1606,6 +1606,7 @@ protection: &a 광산차를 허용하세요. name: 월드 TNT 피해 locked: '&c 이 섬은 잠겨있습니다!' + locked-island-bypass: '&6 이 [prefix_island]은 잠겨있지만, 당신은 우회할 권한이 있습니다.' protected: '&c 섬 보호: [description].' world-protected: '&c 월드 보호: [description].' spawn-protected: '&c 스폰 보호: [description].' diff --git a/src/main/resources/locales/lv.yml b/src/main/resources/locales/lv.yml index a2aea3a7f..7af022930 100644 --- a/src/main/resources/locales/lv.yml +++ b/src/main/resources/locales/lv.yml @@ -1741,6 +1741,7 @@ protection: &a ievainojumus ārpus [prefix_island] robežām. name: Pasaule TNT kaitējums locked: '&cŠī sala ir slēgta!' + locked-island-bypass: '&6Šī [prefix_island] ir slēgta, bet jums ir atļauja to apiet.' protected: '&cSala ir aizsargāta: [description]' world-protected: '&cPasaule aizsargāta: [description]' spawn-protected: '&cSākuma sala ir aizsargāta: [description]' diff --git a/src/main/resources/locales/nl.yml b/src/main/resources/locales/nl.yml index 13aad1406..1454355eb 100644 --- a/src/main/resources/locales/nl.yml +++ b/src/main/resources/locales/nl.yml @@ -1765,6 +1765,7 @@ protection: &a entiteit buiten de eilandgrenzen. name: Wereld TNT-schade locked: '&c Dit eiland is op slot!' + locked-island-bypass: '&6 Dit [prefix_island] is op slot, maar je hebt toestemming om dit te negeren.' protected: '&c Eiland beschermd: [omschrijving].' world-protected: '&c Wereld beschermd: [omschrijving].' spawn-protected: '&c Spawn beschermd: [omschrijving].' diff --git a/src/main/resources/locales/pl.yml b/src/main/resources/locales/pl.yml index e8dd0d94c..072df135b 100644 --- a/src/main/resources/locales/pl.yml +++ b/src/main/resources/locales/pl.yml @@ -1699,6 +1699,7 @@ protection: &a jednostkom poza granicami [prefix_island]. name: Świat uszkodzenia TNT locked: '&cTa wyspa jest zamknięta!' + locked-island-bypass: '&6 Ta [prefix_island] jest zamknięta, ale masz uprawnienia, by ją ominąć.' protected: '&cWyspa chroniona: [description]' world-protected: '&c Świat chroniony: [description]' spawn-protected: '&c Spawn chroniony: [description]' diff --git a/src/main/resources/locales/pt-BR.yml b/src/main/resources/locales/pt-BR.yml index e4a360e60..0440a7e25 100644 --- a/src/main/resources/locales/pt-BR.yml +++ b/src/main/resources/locales/pt-BR.yml @@ -1712,6 +1712,7 @@ protection: entidades fora dos limites de [prefix_island]. name: Dano de TNT no mundo locked: '&c Essa ilha está trancada!' + locked-island-bypass: '&6 Essa [prefix_island] está trancada, mas você tem permissão para acessá-la.' protected: '&c Ilha protegida: [description].' world-protected: '&c Mundo protegido: [description].' spawn-protected: '&c Spawn protegido: [description].' diff --git a/src/main/resources/locales/pt.yml b/src/main/resources/locales/pt.yml index 15c673913..c83a88cba 100644 --- a/src/main/resources/locales/pt.yml +++ b/src/main/resources/locales/pt.yml @@ -1737,6 +1737,7 @@ protection: &a entidades fora dos limites da ilha. name: Danos mundiais de TNT locked: '&c Esta ilha está trancada!' + locked-island-bypass: '&6 Esta [prefix_island] está trancada, mas tem permissão para aceder.' protected: '&c Ilha protegida: [descrição].' world-protected: '&c Protegido mundialmente: [descrição].' spawn-protected: '&c Spawn protegido: [descrição].' diff --git a/src/main/resources/locales/ro.yml b/src/main/resources/locales/ro.yml index 6ab779486..dafe229a2 100644 --- a/src/main/resources/locales/ro.yml +++ b/src/main/resources/locales/ro.yml @@ -1755,6 +1755,7 @@ protection: &o entități în afara limitelor insulei. name: Daune TNT mondiale locked: '&c Această insulă este blocată!' + locked-island-bypass: '&6 Această [prefix_island] este blocată, dar ai permisiunea de a o ocoli.' protected: '&c Insula protejată: [description].' world-protected: '&c Protecție mondială: [description].' spawn-protected: '&c Spawn protejat: [description].' diff --git a/src/main/resources/locales/ru.yml b/src/main/resources/locales/ru.yml index b4f879c4d..10634b823 100644 --- a/src/main/resources/locales/ru.yml +++ b/src/main/resources/locales/ru.yml @@ -1694,6 +1694,7 @@ protection: &a за пределами острова. name: Разрушение блоков через TNT locked: '&cЭтот остров заблокирован!' + locked-island-bypass: '&6 Этот [prefix_island] заблокирован, но у вас есть разрешение на вход.' protected: '&cОстров защищен: [description].' world-protected: '&cМир защищен: [description].' spawn-protected: '&cСпавн защищен: [description].' diff --git a/src/main/resources/locales/tr.yml b/src/main/resources/locales/tr.yml index 2bc4a5d74..794adbc12 100644 --- a/src/main/resources/locales/tr.yml +++ b/src/main/resources/locales/tr.yml @@ -1635,6 +1635,7 @@ protection: &a varlıklara zarar vermesine izin verin. name: Dünya TNT hasarı locked: '&4Bu ada kilitli!' + locked-island-bypass: '&6 Bu [prefix_island] kilitli, ancak geçiş izniniz var.' protected: '&4Ada korunuyor: [description]' world-protected: '&cDünya korunuyor: [description]' spawn-protected: '&4Spawn koruması: [description]' diff --git a/src/main/resources/locales/uk.yml b/src/main/resources/locales/uk.yml index 41cc2f1f6..a51c5adcf 100644 --- a/src/main/resources/locales/uk.yml +++ b/src/main/resources/locales/uk.yml @@ -1631,6 +1631,7 @@ protection: &a за межами [prefix_island]. name: Світова шкода від ТНТ locked: '&c Цей [prefix_island] заблоковано!' + locked-island-bypass: '&6 Цей [prefix_island] заблоковано, але у вас є дозвіл на вхід.' protected: '&c [prefix_Island] захищено: [description].' world-protected: '&c Світ захищено: [description].' spawn-protected: '&c Спавн захищено: [description].' diff --git a/src/main/resources/locales/vi.yml b/src/main/resources/locales/vi.yml index 985a99215..b55e282c0 100644 --- a/src/main/resources/locales/vi.yml +++ b/src/main/resources/locales/vi.yml @@ -1693,6 +1693,7 @@ protection: &a ở ngoài đảo. name: Sát thường từ TNT ngoài đảo locked: '&c Đảo đã khóa!' + locked-island-bypass: '&6 [prefix_Island] này đã bị khóa, nhưng bạn có quyền đi qua.' protected: '&c Đảo đã bảo vệ: [description].' world-protected: '&c Thế giới đã bảo vệ: [description].' spawn-protected: '&c Điểm triệu hồi đã bảo vệ: [description].' diff --git a/src/main/resources/locales/zh-CN.yml b/src/main/resources/locales/zh-CN.yml index cd1d6bbc5..7b889990c 100644 --- a/src/main/resources/locales/zh-CN.yml +++ b/src/main/resources/locales/zh-CN.yml @@ -1561,6 +1561,7 @@ protection: &#FAFAD2对岛屿保护范围之外的方块和实体造成破坏和伤害 name: '&b&l边界TNT保护' locked: '&c这个岛屿已被锁定!' + locked-island-bypass: '&6 这个[prefix_island]已被锁定,但你有权限绕过。' protected: '&c岛屿保护: [description].' world-protected: '&c世界保护: [description].' spawn-protected: '&c出生点保护: [description].' diff --git a/src/main/resources/locales/zh-HK.yml b/src/main/resources/locales/zh-HK.yml index 18bdda2e3..e44284fa1 100644 --- a/src/main/resources/locales/zh-HK.yml +++ b/src/main/resources/locales/zh-HK.yml @@ -1562,6 +1562,7 @@ protection: &7和TNT礦車破壞方塊和實體 name: '&a&l世界TNT傷害' locked: '&c本島嶼已被鎖定!' + locked-island-bypass: '&6 本[prefix_island]已被鎖定,但您有權限繞過。' protected: '&c島嶼保護:[description]' world-protected: '&c世界保護: [description].' spawn-protected: '&c生成保護:[description]' diff --git a/src/test/java/world/bentobox/bentobox/listeners/flags/protection/LockAndBanListenerTest.java b/src/test/java/world/bentobox/bentobox/listeners/flags/protection/LockAndBanListenerTest.java index d7f18a7a0..e834a2981 100644 --- a/src/test/java/world/bentobox/bentobox/listeners/flags/protection/LockAndBanListenerTest.java +++ b/src/test/java/world/bentobox/bentobox/listeners/flags/protection/LockAndBanListenerTest.java @@ -430,6 +430,7 @@ void testLoginToLockedIslandWithBypassPerm() { Player player = mock(Player.class); when(player.isOp()).thenReturn(false); when(player.hasPermission(anyString())).thenReturn(true); + when(player.getWorld()).thenReturn(world); when(player.getUniqueId()).thenReturn(uuid); // Give player an island @@ -442,8 +443,8 @@ void testLoginToLockedIslandWithBypassPerm() { // Log them in listener.onPlayerLogin(new PlayerJoinEvent(player, "join message")); - // User should not see a message - verify(notifier, never()).notify(any(), anyString()); + // User should see a bypass message + verify(notifier).notify(any(), anyString()); // User should not be teleported somewhere verify(im, never()).homeTeleportAsync(any(), eq(player)); } @@ -539,12 +540,14 @@ void testPlayerMoveIntoLockedIslandWithBypass() { when(mockPlayer.getLocation()).thenReturn(outside); // Lock island for player - when(island.isAllowed(user, Flags.LOCK)).thenReturn(false); + when(island.isAllowed(any(User.class), eq(Flags.LOCK))).thenReturn(false); // Move player PlayerMoveEvent e = new PlayerMoveEvent(mockPlayer, outside, inside); listener.onPlayerMove(e); assertFalse(e.isCancelled()); + // User should see a bypass notification + verify(notifier).notify(any(), anyString()); } @Test @@ -620,18 +623,21 @@ void testPlayerMoveInsideLockedIslandWithBypass() { when(player.getUniqueId()).thenReturn(uuid); when(player.isOp()).thenReturn(false); when(player.hasPermission(anyString())).thenReturn(true); + when(player.getWorld()).thenReturn(world); // Give player an island when(im.hasIsland(any(), eq(uuid))).thenReturn(true); // Place the player inside island when(player.getLocation()).thenReturn(inside); // Lock island for player - when(island.isAllowed(user, Flags.LOCK)).thenReturn(false); + when(island.isAllowed(any(User.class), eq(Flags.LOCK))).thenReturn(false); // Move player PlayerMoveEvent e = new PlayerMoveEvent(player, inside, inside2); listener.onPlayerMove(e); assertFalse(e.isCancelled()); + // User should see a bypass notification + verify(notifier).notify(any(), anyString()); } @Test