World context settings (#2271)

* WIP to having admin setting world based on the command

and not the location of the user.

* Make world settings depend on the world of the command

Previous code based world on the location of the user when they ran the
command.

* Remove unused import

* Fix JavaDoc

* Remove unused import.
This commit is contained in:
tastybento 2024-01-12 20:28:07 -08:00 committed by GitHub
parent 76a36e685e
commit 4bfbe41956
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 55 additions and 49 deletions

View File

@ -377,12 +377,13 @@ public class Flag implements Comparable<Flag> {
* Converts a flag to a panel item. The content of the flag will change depending on who the user is and where they are.
* @param plugin - plugin
* @param user - user that will see this flag
* @param world - the world this flag is being shown for. If island is present, then world is the same as the island.
* @param island - target island, if any
* @param invisible - true if this flag is not visible to players
* @return - PanelItem for this flag or null if item is invisible to user
*/
@Nullable
public PanelItem toPanelItem(BentoBox plugin, User user, @Nullable Island island, boolean invisible) {
public PanelItem toPanelItem(BentoBox plugin, User user, World world, @Nullable Island island, boolean invisible) {
// Invisibility
if (!user.isOp() && invisible) {
return null;
@ -400,12 +401,13 @@ public class Flag implements Comparable<Flag> {
return switch (getType()) {
case PROTECTION -> createProtectionFlag(plugin, user, island, pib).build();
case SETTING -> createSettingFlag(user, island, pib).build();
case WORLD_SETTING -> createWorldSettingFlag(user, pib).build();
case WORLD_SETTING -> createWorldSettingFlag(user, world, pib).build();
};
}
private PanelItemBuilder createWorldSettingFlag(User user, PanelItemBuilder pib) {
String worldSetting = this.isSetForWorld(user.getWorld()) ? user.getTranslation("protection.panel.flag-item.setting-active")
private PanelItemBuilder createWorldSettingFlag(User user, World world, PanelItemBuilder pib) {
String worldSetting = this.isSetForWorld(world)
? user.getTranslation("protection.panel.flag-item.setting-active")
: user.getTranslation("protection.panel.flag-item.setting-disabled");
pib.description(user.getTranslation("protection.panel.flag-item.setting-layout", TextVariables.DESCRIPTION, user.getTranslation(getDescriptionReference())
, "[setting]", worldSetting));
@ -679,11 +681,11 @@ public class Flag implements Comparable<Flag> {
public Flag build() {
// If no clickHandler has been set, then apply default ones
if (clickHandler == null) {
switch (type) {
case SETTING -> clickHandler = new IslandToggleClick(id);
case WORLD_SETTING -> clickHandler = new WorldToggleClick(id);
default -> clickHandler = new CycleClick(id);
}
clickHandler = switch (type) {
case SETTING -> new IslandToggleClick(id);
case WORLD_SETTING -> new WorldToggleClick(id);
default -> new CycleClick(id);
};
}
return new Flag(this);

View File

@ -2,6 +2,7 @@ package world.bentobox.bentobox.api.flags.clicklisteners;
import org.bukkit.Bukkit;
import org.bukkit.Sound;
import org.bukkit.World;
import org.bukkit.event.inventory.ClickType;
import world.bentobox.bentobox.BentoBox;
@ -32,12 +33,8 @@ public class WorldToggleClick implements ClickHandler {
@Override
public boolean onClick(Panel panel, User user, ClickType click, int slot) {
// Get the world
if (!plugin.getIWM().inWorld(user.getLocation())) {
user.sendMessage("general.errors.wrong-world");
return true;
}
String reqPerm = plugin.getIWM().getPermissionPrefix(Util.getWorld(user.getWorld())) + "admin.world.settings." + id;
World world = panel.getWorld().orElse(null);
String reqPerm = plugin.getIWM().getPermissionPrefix(world) + "admin.world.settings." + id;
if (!user.hasPermission(reqPerm)) {
user.sendMessage("general.errors.no-permission", TextVariables.PERMISSION, reqPerm);
user.getPlayer().playSound(user.getLocation(), Sound.BLOCK_METAL_HIT, 1F, 1F);
@ -46,31 +43,34 @@ public class WorldToggleClick implements ClickHandler {
// Get flag
plugin.getFlagsManager().getFlag(id).ifPresent(flag -> {
if (click.equals(ClickType.SHIFT_LEFT) && user.isOp()) {
if (!plugin.getIWM().getHiddenFlags(user.getWorld()).contains(flag.getID())) {
plugin.getIWM().getHiddenFlags(user.getWorld()).add(flag.getID());
if (!plugin.getIWM().getHiddenFlags(world).contains(flag.getID())) {
plugin.getIWM().getHiddenFlags(world).add(flag.getID());
user.getPlayer().playSound(user.getLocation(), Sound.BLOCK_GLASS_BREAK, 1F, 1F);
} else {
plugin.getIWM().getHiddenFlags(user.getWorld()).remove(flag.getID());
plugin.getIWM().getHiddenFlags(world).remove(flag.getID());
user.getPlayer().playSound(user.getLocation(), Sound.BLOCK_NOTE_BLOCK_CHIME, 1F, 1F);
}
// Save changes
plugin.getIWM().getAddon(user.getWorld()).ifPresent(GameModeAddon::saveWorldSettings);
plugin.getIWM().getAddon(world).ifPresent(GameModeAddon::saveWorldSettings);
} else {
// Toggle flag
flag.setSetting(user.getWorld(), !flag.isSetForWorld(user.getWorld()));
flag.setSetting(world, !flag.isSetForWorld(world));
user.getPlayer().playSound(user.getLocation(), Sound.BLOCK_STONE_BUTTON_CLICK_ON, 1F, 1F);
// Fire event
Bukkit.getPluginManager().callEvent(new FlagWorldSettingChangeEvent(user.getWorld(), user.getUniqueId(), flag, flag.isSetForWorld(user.getWorld())));
Bukkit.getPluginManager().callEvent(
new FlagWorldSettingChangeEvent(world, user.getUniqueId(), flag, flag.isSetForWorld(world)));
// Subflag support
if (flag.hasSubflags()) {
// Fire events for all subflags as well
flag.getSubflags().forEach(subflag -> Bukkit.getPluginManager().callEvent(new FlagWorldSettingChangeEvent(user.getWorld(), user.getUniqueId(), subflag, subflag.isSetForWorld(user.getWorld()))));
flag.getSubflags().forEach(
subflag -> Bukkit.getPluginManager().callEvent(new FlagWorldSettingChangeEvent(world,
user.getUniqueId(), subflag, subflag.isSetForWorld(world))));
}
}
// Save world settings
plugin.getIWM().getAddon(Util.getWorld(user.getWorld())).ifPresent(GameModeAddon::saveWorldSettings);
plugin.getIWM().getAddon(Util.getWorld(world)).ifPresent(GameModeAddon::saveWorldSettings);
});
return true;
}

View File

@ -43,6 +43,7 @@ public class TabbedPanel extends Panel implements PanelListener {
*/
public TabbedPanel(TabbedPanelBuilder tpb) {
this.tpb = tpb;
// Set world
this.setWorld(tpb.getWorld());
// Set island context in Panel
this.setIsland(tpb.getIsland());

View File

@ -125,7 +125,8 @@ public class SettingsTab implements Tab, ClickHandler {
flags = getFlags();
}
return flags.stream().map(
(f -> f.toPanelItem(plugin, user, island, plugin.getIWM().getHiddenFlags(world).contains(f.getID()))))
(f -> f.toPanelItem(plugin, user, world, island,
plugin.getIWM().getHiddenFlags(world).contains(f.getID()))))
.toList();
}
@ -134,8 +135,8 @@ public class SettingsTab implements Tab, ClickHandler {
Map<Integer, PanelItem> icons = new HashMap<>();
// Add the lock icon - we want it to be displayed no matter the tab
if (island != null) {
icons.put(4, Flags.CHANGE_SETTINGS.toPanelItem(plugin, user, island, false));
icons.put(5, Flags.LOCK.toPanelItem(plugin, user, island, false));
icons.put(4, Flags.CHANGE_SETTINGS.toPanelItem(plugin, user, world, island, false));
icons.put(5, Flags.LOCK.toPanelItem(plugin, user, world, island, false));
}
// Add the mode icon
switch (plugin.getPlayers().getFlagsDisplayMode(user.getUniqueId())) {
@ -235,7 +236,6 @@ public class SettingsTab implements Tab, ClickHandler {
this.parent = parent;
this.island = parent.getIsland();
this.world = parent.getWorld().orElse(this.world);
}
}

View File

@ -71,11 +71,12 @@ public class WorldDefaultSettingsTab extends SettingsTab implements Tab {
public @NonNull List<PanelItem> getPanelItems() {
// Different description and click handlers
return getFlags().stream().map(f -> {
PanelItem i = f.toPanelItem(plugin, user, null, false);
PanelItem i = f.toPanelItem(plugin, user, world, island, false);
// Replace the click handler with WorldToggleClick
i.setClickHandler(new WorldToggleClick(f.getID()));
// Replace the description
String worldSetting = f.isSetForWorld(user.getWorld()) ? user.getTranslation("protection.panel.flag-item.setting-active")
String worldSetting = f.isSetForWorld(world)
? user.getTranslation("protection.panel.flag-item.setting-active")
: user.getTranslation("protection.panel.flag-item.setting-disabled");
i.setDescription(Arrays.asList(user.getTranslation("protection.panel.flag-item.setting-layout",
TextVariables.DESCRIPTION, user.getTranslation(f.getDescriptionReference()),

View File

@ -383,7 +383,7 @@ public class FlagTest {
when(rm.getRank(RanksManager.OWNER_RANK)).thenReturn("Owner");
PanelItem pi = f.toPanelItem(plugin, user, island, false);
PanelItem pi = f.toPanelItem(plugin, user, world, island, false);
verify(user).getTranslation("protection.flags.flagID.name");
verify(user).getTranslation(eq("protection.panel.flag-item.name-layout"), any());

View File

@ -1,7 +1,10 @@
package world.bentobox.bentobox.api.flags.clicklisteners;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@ -51,6 +54,8 @@ public class WorldToggleClickTest {
private GameModeAddon addon;
@Mock
private PluginManager pim;
@Mock
private World world;
/**
*/
@ -63,7 +68,7 @@ public class WorldToggleClickTest {
// Island World Manager
when(iwm.inWorld(any(World.class))).thenReturn(true);
when(iwm.inWorld(any(Location.class))).thenReturn(true);
when(iwm.getPermissionPrefix(Mockito.any())).thenReturn("bskyblock.");
when(iwm.getPermissionPrefix(any())).thenReturn("bskyblock.");
Optional<GameModeAddon> optionalAddon = Optional.of(addon);
when(iwm.getAddon(Mockito.any())).thenReturn(optionalAddon);
when(plugin.getIWM()).thenReturn(iwm);
@ -75,18 +80,18 @@ public class WorldToggleClickTest {
// User
// Sometimes use Mockito.withSettings().verboseLogging()
when(user.getWorld()).thenReturn(mock(World.class));
when(user.getWorld()).thenReturn(world);
when(user.getLocation()).thenReturn(mock(Location.class));
when(user.getPlayer()).thenReturn(mock(Player.class));
// Util
PowerMockito.mockStatic(Util.class);
when(Util.getWorld(Mockito.any())).thenReturn(mock(World.class));
when(Util.getWorld(any())).thenReturn(world);
// Flags Manager
FlagsManager fm = mock(FlagsManager.class);
flag = mock(Flag.class);
when(flag.isSetForWorld(Mockito.any())).thenReturn(false);
when(flag.isSetForWorld(any())).thenReturn(false);
when(fm.getFlag(Mockito.anyString())).thenReturn(Optional.of(flag));
when(plugin.getFlagsManager()).thenReturn(fm);
@ -101,28 +106,25 @@ public class WorldToggleClickTest {
Mockito.framework().clearInlineMocks();
}
@Test
public void testOnClickWrongWorld() {
when(iwm.inWorld(any(World.class))).thenReturn(false);
when(iwm.inWorld(any(Location.class))).thenReturn(false);
listener.onClick(panel, user, ClickType.LEFT, 0);
verify(user).sendMessage("general.errors.wrong-world");
verify(addon, Mockito.never()).saveWorldSettings();
}
/**
* Test for {@link WorldToggleClick#onClick(Panel, User, ClickType, int)}
*/
@Test
public void testOnClickNoPermission() {
when(user.hasPermission(Mockito.anyString())).thenReturn(false);
when(user.hasPermission(anyString())).thenReturn(false);
listener.onClick(panel, user, ClickType.LEFT, 0);
verify(user).sendMessage("general.errors.no-permission", "[permission]", "bskyblock.admin.world.settings.test");
verify(addon, Mockito.never()).saveWorldSettings();
verify(addon, never()).saveWorldSettings();
}
/**
* Test for {@link WorldToggleClick#onClick(Panel, User, ClickType, int)}
*/
@Test
public void testOnClick() {
when(user.hasPermission(Mockito.anyString())).thenReturn(true);
when(user.hasPermission(anyString())).thenReturn(true);
listener.onClick(panel, user, ClickType.LEFT, 0);
verify(flag).setSetting(Mockito.any(), Mockito.eq(true));
verify(flag).setSetting(any(), eq(true));
verify(addon).saveWorldSettings();
verify(pim).callEvent(any(FlagWorldSettingChangeEvent.class));
}

View File

@ -172,7 +172,7 @@ public class PVPListenerTest {
when(flag.isSetForWorld(any())).thenReturn(false);
PanelItem item = mock(PanelItem.class);
when(item.getItem()).thenReturn(mock(ItemStack.class));
when(flag.toPanelItem(any(), any(), any(), eq(false))).thenReturn(item);
when(flag.toPanelItem(any(), any(), any(), any(), eq(false))).thenReturn(item);
when(fm.getFlag(Mockito.anyString())).thenReturn(Optional.of(flag));
when(plugin.getFlagsManager()).thenReturn(fm);

View File

@ -144,7 +144,7 @@ public class InvincibleVisitorsListenerTest {
when(flag.isSetForWorld(any())).thenReturn(false);
PanelItem item = mock(PanelItem.class);
when(item.getItem()).thenReturn(mock(ItemStack.class));
when(flag.toPanelItem(any(), eq(user), any(), eq(false))).thenReturn(item);
when(flag.toPanelItem(any(), eq(user), any(), any(), eq(false))).thenReturn(item);
when(fm.getFlag(anyString())).thenReturn(Optional.of(flag));
when(plugin.getFlagsManager()).thenReturn(fm);