Auto add default placeholders for GameModeAddons (#616)

https://github.com/BentoBoxWorld/BentoBox/issues/322
This commit is contained in:
tastybento 2019-03-24 07:30:58 -07:00 committed by Florian CUNY
parent 1eadddee47
commit 2912ae18d2
8 changed files with 235 additions and 3 deletions

View File

@ -30,6 +30,7 @@ import world.bentobox.bentobox.listeners.StandardSpawnProtectionListener;
import world.bentobox.bentobox.managers.AddonsManager;
import world.bentobox.bentobox.managers.CommandsManager;
import world.bentobox.bentobox.managers.FlagsManager;
import world.bentobox.bentobox.managers.GameModePlaceholderManager;
import world.bentobox.bentobox.managers.HooksManager;
import world.bentobox.bentobox.managers.IslandDeletionManager;
import world.bentobox.bentobox.managers.IslandWorldManager;
@ -154,6 +155,10 @@ public class BentoBox extends JavaPlugin {
addonsManager.loadAddons();
// Enable addons
addonsManager.enableAddons();
// Register default gamemode placeholders
GameModePlaceholderManager gmp = new GameModePlaceholderManager(this);
addonsManager.getGameModeAddons().forEach(gmp::registerGameModePlaceholders);
getServer().getScheduler().runTask(instance, () -> {
// Register Listeners

View File

@ -49,4 +49,14 @@ abstract class BasicPlaceholderExpansion extends PlaceholderExpansion {
}
return null;
}
/**
* Checks if a placeholder with this name is already registered
* @param placeholder - name of placeholder
* @return <tt>true</tt> if a placeholder with this name is already registered
* @since 1.4.0
*/
public boolean isPlaceholder(@NonNull String placeholder) {
return placeholders.containsKey(placeholder);
}
}

View File

@ -107,4 +107,15 @@ public class PlaceholderAPIHook extends Hook {
public void registerAddonPlaceholder(Addon addon, String placeholder, PlaceholderReplacer replacer) {
registerPlaceholder(addon, placeholder, replacer);
}
/**
* Checks if a placeholder with this name is already registered
* @param addon the addon, not null
* @param placeholder - name of placeholder
* @return <tt>true</tt> if a placeholder with this name is already registered
* @since 1.4.0
*/
public boolean isPlaceholder(@NonNull Addon addon, @NonNull String placeholder) {
return addonsExpansions.containsKey(addon) ? addonsExpansions.get(addon).isPlaceholder(placeholder) : false;
}
}

View File

@ -0,0 +1,22 @@
package world.bentobox.bentobox.lists;
public enum GameModePlaceholders {
WORLD_FRIENDLY_NAME("world-friendlyname"),
ISLAND_DISTANCE("island-distance"),
ISLAND_PROTECTION_RANGE("island-protection-range"),
ISLAND_OWNER("island-owner"),
ISLAND_CREATION_DATE("island-creation-date"),
ISLAND_SPAWNPOINT("island-spawnpoint"),
ISLAND_NAME("island-name");
private String placeholder;
GameModePlaceholders(String placeholder) {
this.placeholder = placeholder;
}
public String getPlaceholder() {
return placeholder;
}
}

View File

@ -0,0 +1,84 @@
package world.bentobox.bentobox.managers;
import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.api.addons.GameModeAddon;
import world.bentobox.bentobox.api.placeholders.PlaceholderReplacer;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.database.objects.Island;
import world.bentobox.bentobox.lists.GameModePlaceholders;
import world.bentobox.bentobox.util.Util;
import java.text.DateFormat;
import java.time.Instant;
import java.util.Arrays;
import java.util.Date;
import java.util.EnumMap;
import java.util.Map;
/**
*
* Registers default placeholders for all GameModes. Will not overwrite any that the gamemode addon itself implements.
* @author tastybento
*
*/
public class GameModePlaceholderManager {
private BentoBox plugin;
public GameModePlaceholderManager(BentoBox plugin) {
super();
this.plugin = plugin;
}
public void registerGameModePlaceholders(GameModeAddon addon) {
String prefix = addon.getDescription().getName().toLowerCase();
Map<GameModePlaceholders, String> placeholders = new EnumMap<>(GameModePlaceholders.class);
Arrays.stream(GameModePlaceholders.values()).forEach(placeholder -> placeholders.put(placeholder, prefix + "-" + placeholder.getPlaceholder()));
// Register placeholders only if they have not already been registered by the addon itself
placeholders.entrySet().stream().filter(en -> !plugin.getPlaceholdersManager().isPlaceholder(addon, en.getValue()))
.forEach(en -> plugin.getPlaceholdersManager().registerPlaceholder(en.getValue(), new DefaultPlaceholder(addon, en.getKey())));
}
}
class DefaultPlaceholder implements PlaceholderReplacer {
private final GameModeAddon addon;
private final GameModePlaceholders type;
public DefaultPlaceholder(GameModeAddon addon, GameModePlaceholders type) {
super();
this.addon = addon;
this.type = type;
}
/* (non-Javadoc)
* @see world.bentobox.bentobox.api.placeholders.PlaceholderReplacer#onReplace(world.bentobox.bentobox.api.user.User)
*/
@Override
public String onReplace(User user) {
if (user == null) {
return "";
}
Island island = addon.getIslands().getIsland(addon.getOverWorld(), user);
switch (type) {
case WORLD_FRIENDLY_NAME:
return addon.getWorldSettings().getFriendlyName();
case ISLAND_CREATION_DATE:
return island == null ? "" : DateFormat.getInstance().format(Date.from(Instant.ofEpochMilli(island.getCreatedDate())));
case ISLAND_DISTANCE:
return String.valueOf(addon.getWorldSettings().getIslandDistance());
case ISLAND_NAME:
return island == null ? "" : (island.getName() == null ? "" : island.getName());
case ISLAND_OWNER:
return island == null ? "" : addon.getPlayers().getName(island.getOwner());
case ISLAND_PROTECTION_RANGE:
return island == null ? "" : String.valueOf(island.getProtectionRange());
case ISLAND_SPAWNPOINT:
return island == null ? "" : Util.xyz(island.getCenter().toVector());
default:
return "";
}
}
}

View File

@ -1,7 +1,5 @@
package world.bentobox.bentobox.managers;
import com.mongodb.lang.NonNull;
import com.mongodb.lang.Nullable;
import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.api.addons.Addon;
import world.bentobox.bentobox.api.placeholders.PlaceholderReplacer;
@ -9,6 +7,9 @@ import world.bentobox.bentobox.hooks.PlaceholderAPIHook;
import java.util.Optional;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
/**
* Manages placeholder integration.
*
@ -85,4 +86,15 @@ public class PlaceholdersManager {
private Optional<PlaceholderAPIHook> getPlaceholderAPIHook() {
return plugin.getHooks().getHook("PlaceholderAPI").map(hook -> (PlaceholderAPIHook) hook);
}
/**
* Checks if a placeholder with this name is already registered
* @param addon the addon, not null
* @param placeholder - name of placeholder
* @return <tt>true</tt> if a placeholder with this name is already registered
* @since 1.4.0
*/
public boolean isPlaceholder(@NonNull Addon addon, @NonNull String placeholder) {
return addon == null ? false : getPlaceholderAPIHook().map(h -> h.isPlaceholder(addon, placeholder)).orElse(false);
}
}

View File

@ -16,7 +16,7 @@ import world.bentobox.bentobox.BentoBox;
@PrepareForTest( { BentoBox.class} )
public class AddonsManagerTest {
private static BentoBox plugin;
private BentoBox plugin;
@Before
public void setup() {

View File

@ -0,0 +1,88 @@
/**
*
*/
package world.bentobox.bentobox.managers;
import static org.mockito.Mockito.when;
import org.eclipse.jdt.annotation.NonNull;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.api.addons.AddonDescription;
import world.bentobox.bentobox.api.addons.GameModeAddon;
/**
* @author tastybento
*
*/
@RunWith(PowerMockRunner.class)
@PrepareForTest( {BentoBox.class} )
public class GameModePlaceholderManagerTest {
@Mock
private BentoBox plugin;
@Mock
private GameModeAddon addon;
@Mock
private PlaceholdersManager pm;
private GameModePlaceholderManager gpm;
/**
* @throws java.lang.Exception
*/
@Before
public void setUp() throws Exception {
gpm = new GameModePlaceholderManager(plugin);
// Addon
@NonNull
AddonDescription desc = new AddonDescription.Builder("main", "bskyblock", "1.0").build();
when(addon.getDescription()).thenReturn(desc);
when(plugin.getPlaceholdersManager()).thenReturn(pm);
// No placeholders registered yet
when(pm.isPlaceholder(Mockito.any(), Mockito.any())).thenReturn(false);
}
/**
* @throws java.lang.Exception
*/
@After
public void tearDown() throws Exception {
}
/**
* Test method for {@link world.bentobox.bentobox.managers.GameModePlaceholderManager#registerGameModePlaceholders(world.bentobox.bentobox.api.addons.GameModeAddon)}.
*/
@Test
public void testRegisterGameModePlaceholdersAllDefaults() {
gpm.registerGameModePlaceholders(addon);
// 7 registrations for this addon
Mockito.verify(pm, Mockito.times(7)).registerPlaceholder(Mockito.anyString(), Mockito.any());
}
/**
* Test method for {@link world.bentobox.bentobox.managers.GameModePlaceholderManager#registerGameModePlaceholders(world.bentobox.bentobox.api.addons.GameModeAddon)}.
*/
@Test
public void testRegisterGameModePlaceholdersSomePreregistered() {
// Some duplicates
when(pm.isPlaceholder(Mockito.any(), Mockito.any())).thenReturn(false, true, true, false, false, true, false);
gpm.registerGameModePlaceholders(addon);
// 3 registrations for this addon
Mockito.verify(pm, Mockito.times(4)).registerPlaceholder(Mockito.anyString(), Mockito.any());
}
}