feat: add some *base* placeholders and util classes
This commit is contained in:
4 files changed
+478
No files matched your search
@@ -0,0 +1,291 @@
|
||||
package at.helpch.placeholderapi.expansion.player;
|
||||
|
||||
import at.helpch.placeholderapi.expansion.player.util.ItemUtil;
|
||||
import at.helpch.placeholderapi.expansion.player.util.PlayerUtil;
|
||||
import at.helpch.placeholderapi.expansion.player.util.VersionHelper;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import me.clip.placeholderapi.expansion.Configurable;
|
||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
public final class PlayerExpansion extends PlaceholderExpansion implements Configurable {
|
||||
|
||||
@Override
|
||||
public @NotNull String getIdentifier() {
|
||||
return "player";
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getAuthor() {
|
||||
return "HelpChat";
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getVersion() {
|
||||
return "3.0.0";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getDefaults() {
|
||||
return ImmutableMap.<String, Object>builder()
|
||||
.put("ping_color.high", "&c")
|
||||
.put("ping_color.medium", "&e")
|
||||
.put("ping_color.low", "&a")
|
||||
.put("ping_value.medium", 50)
|
||||
.put("ping_value.high", 100)
|
||||
.put("direction.north", "N")
|
||||
.put("direction.north_east", "NE")
|
||||
.put("direction.east", "E")
|
||||
.put("direction.south_east", "SE")
|
||||
.put("direction.south", "S")
|
||||
.put("direction.south_west", "SW")
|
||||
.put("direction.west", "W")
|
||||
.put("direction.north_west", "NW")
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canRegister() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format a {@code boolean} as {@link PlaceholderAPIPlugin#booleanTrue()} or {@link PlaceholderAPIPlugin#booleanFalse()}
|
||||
*
|
||||
* @param bool boolean
|
||||
* @return {@link PlaceholderAPIPlugin#booleanTrue()} if the boolean is true, otherwise {@link PlaceholderAPIPlugin#booleanFalse()}
|
||||
*/
|
||||
private @NotNull String bool(final boolean bool) {
|
||||
return bool ? PlaceholderAPIPlugin.booleanTrue() : PlaceholderAPIPlugin.booleanFalse();
|
||||
}
|
||||
|
||||
private @NotNull String getItemInfo(@Nullable final ItemStack item, @NotNull final String args) {
|
||||
switch (args) {
|
||||
case "_name":
|
||||
return ItemUtil.getName(item);
|
||||
case "_data":
|
||||
return String.valueOf(ItemUtil.getData(item));
|
||||
case "_durability":
|
||||
return String.valueOf(ItemUtil.getDurability(item));
|
||||
default:
|
||||
return ItemUtil.getMaterialName(item);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("SpellCheckingInspection")
|
||||
@Override
|
||||
public @Nullable String onRequest(OfflinePlayer offlinePlayer, @NotNull String params) {
|
||||
//TODO: add target ping placeholders
|
||||
|
||||
if (offlinePlayer == null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
switch (params) {
|
||||
case "name":
|
||||
return offlinePlayer.getName();
|
||||
case "uuid":
|
||||
return offlinePlayer.getUniqueId().toString();
|
||||
case "has_played_before":
|
||||
return bool(offlinePlayer.hasPlayedBefore());
|
||||
case "is_whitelisted":
|
||||
return bool(offlinePlayer.isWhitelisted());
|
||||
case "is_banned":
|
||||
return bool(offlinePlayer.isBanned());
|
||||
case "is_op":
|
||||
return bool(offlinePlayer.isOnline());
|
||||
case "first_played":
|
||||
case "first_join":
|
||||
return String.valueOf(offlinePlayer.getFirstPlayed());
|
||||
case "first_played_formatted":
|
||||
case "first_join_date":
|
||||
return PlaceholderAPIPlugin.getDateFormat().format(new Date(offlinePlayer.getFirstPlayed()));
|
||||
case "last_played":
|
||||
case "last_join":
|
||||
//noinspection deprecation
|
||||
return String.valueOf(offlinePlayer.getLastPlayed());
|
||||
case "last_played_formatted":
|
||||
case "last_join_date":
|
||||
//noinspection deprecation
|
||||
return PlaceholderAPIPlugin.getDateFormat().format(new Date(offlinePlayer.getLastPlayed()));
|
||||
|
||||
//<editor-fold desc="Bed location placeholders">
|
||||
case "bed_x":
|
||||
return PlayerUtil.getBedCoordinate(offlinePlayer, Location::getX);
|
||||
case "bed_y":
|
||||
return PlayerUtil.getBedCoordinate(offlinePlayer, Location::getY);
|
||||
case "bed_z":
|
||||
return PlayerUtil.getBedCoordinate(offlinePlayer, Location::getZ);
|
||||
case "bed_world":
|
||||
return Optional.ofNullable(offlinePlayer.getBedSpawnLocation())
|
||||
.map(Location::getWorld)
|
||||
.map(World::getName)
|
||||
.orElse("");
|
||||
//</editor-fold>
|
||||
}
|
||||
|
||||
if (!offlinePlayer.isOnline()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
final Player player = offlinePlayer.getPlayer();
|
||||
|
||||
// To get rid of IDE warnings
|
||||
if (player == null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
switch (params) {
|
||||
case "displayname":
|
||||
//noinspection deprecation
|
||||
return player.getDisplayName();
|
||||
case "custom_name":
|
||||
return Optional.ofNullable(player.getCustomName()).orElseGet(player::getName);
|
||||
case "list_name":
|
||||
//noinspection deprecation
|
||||
return player.getPlayerListName();
|
||||
case "gamemode":
|
||||
return player.getGameMode().name();
|
||||
|
||||
//<editor-fold desc="Location / position placeholders">
|
||||
//TODO: add direction and direction_xz
|
||||
case "world":
|
||||
return player.getWorld().getName();
|
||||
case "world_type": {
|
||||
final World.Environment environment = player.getWorld().getEnvironment();
|
||||
if (environment == World.Environment.NETHER) {
|
||||
return "Nether";
|
||||
} else if (environment == World.Environment.THE_END) {
|
||||
return "The End";
|
||||
} else if (environment == World.Environment.NORMAL) {
|
||||
return "Overworld";
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
case "x":
|
||||
return String.valueOf(player.getLocation().getBlockX());
|
||||
case "x_long":
|
||||
return String.valueOf(player.getLocation().getX());
|
||||
case "y":
|
||||
return String.valueOf(player.getLocation().getBlockY());
|
||||
case "y_long":
|
||||
return String.valueOf(player.getLocation().getY());
|
||||
case "z":
|
||||
return String.valueOf(player.getLocation().getBlockZ());
|
||||
case "z_long":
|
||||
return String.valueOf(player.getLocation().getZ());
|
||||
case "yaw":
|
||||
return String.valueOf(player.getLocation().getYaw());
|
||||
case "pitch":
|
||||
return String.valueOf(player.getLocation().getPitch());
|
||||
case "block_underneath":
|
||||
return String.valueOf(
|
||||
player.getLocation()
|
||||
.clone()
|
||||
.subtract(0, 1, 0)
|
||||
.getBlock()
|
||||
.getType()
|
||||
);
|
||||
case "compass_x":
|
||||
return PlayerUtil.getCompassCoordinate(player, Location::getBlockX);
|
||||
case "compass_y":
|
||||
return PlayerUtil.getCompassCoordinate(player, Location::getBlockY);
|
||||
case "compass_z":
|
||||
return PlayerUtil.getCompassCoordinate(player, Location::getBlockZ);
|
||||
case "compass_world":
|
||||
//noinspection OptionalOfNullableMisuse
|
||||
return Optional.ofNullable(player.getCompassTarget())
|
||||
.map(Location::getWorld)
|
||||
.map(World::getName)
|
||||
.orElse("");
|
||||
//</editor-fold>
|
||||
|
||||
//TODO: exp placeholders
|
||||
case "fly_speed":
|
||||
return String.valueOf(player.getFlySpeed());
|
||||
case "food_level":
|
||||
return String.valueOf(player.getFoodLevel());
|
||||
case "health":
|
||||
return String.valueOf(player.getHealth());
|
||||
case "health_rounded":
|
||||
return String.valueOf(Math.round(player.getHealth()));
|
||||
case "health_scale":
|
||||
return String.valueOf(player.getHealthScale());
|
||||
case "has_health_boost":
|
||||
return bool(player.hasPotionEffect(PotionEffectType.HEALTH_BOOST));
|
||||
case "health_boost": {
|
||||
if (player.getHealthScale() > 20) {
|
||||
return Double.toString(player.getHealthScale() - 20);
|
||||
} else {
|
||||
return "0";
|
||||
}
|
||||
}
|
||||
case "absorption": {
|
||||
if (VersionHelper.HAS_ABSORPTION_METHODS) {
|
||||
return String.valueOf((int) player.getAbsorptionAmount());
|
||||
} else {
|
||||
return "-1";
|
||||
}
|
||||
}
|
||||
|
||||
//<editor-fold desc="Inventory placeholders">
|
||||
case "has_empty_slot":
|
||||
return bool(player.getInventory().firstEmpty() > -1);
|
||||
case "empty_slots":
|
||||
return String.valueOf(PlayerUtil.getEmptySlots(player));
|
||||
|
||||
case "item_in_hand":
|
||||
case "item_in_hand_name":
|
||||
case "item_in_hand_data":
|
||||
case "item_in_hand_durability":
|
||||
return getItemInfo(PlayerUtil.getItemInMainHand(player), params.substring("item_in_hand".length()));
|
||||
|
||||
case "item_in_offhand":
|
||||
case "item_in_offhand_name":
|
||||
case "item_in_offhand_data":
|
||||
case "item_in_offhand_durability":
|
||||
return getItemInfo(player.getInventory().getItemInOffHand(), params.substring("item_in_offhand".length()));
|
||||
|
||||
case "armor_helmet":
|
||||
case "armor_helmet_name":
|
||||
case "armor_helmet_data":
|
||||
case "armor_helmet_durability":
|
||||
return getItemInfo(player.getInventory().getHelmet(), params.substring("armor_helmet".length()));
|
||||
|
||||
case "armor_chestplate":
|
||||
case "armor_chestplate_name":
|
||||
case "armor_chestplate_data":
|
||||
case "armor_chestplate_durability":
|
||||
return getItemInfo(player.getInventory().getChestplate(), params.substring("armor_chestplate".length()));
|
||||
|
||||
case "armor_leggings":
|
||||
case "armor_leggings_name":
|
||||
case "armor_leggings_data":
|
||||
case "armor_leggings_durability":
|
||||
return getItemInfo(player.getInventory().getLeggings(), params.substring("armor_leggings".length()));
|
||||
|
||||
case "armor_boots":
|
||||
case "armor_boots_name":
|
||||
case "armor_boots_data":
|
||||
case "armor_boots_durability":
|
||||
return getItemInfo(player.getInventory().getBoots(), params.substring("armor_boots".length()));
|
||||
//</editor-fold>
|
||||
}
|
||||
|
||||
return super.onRequest(offlinePlayer, params);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package at.helpch.placeholderapi.expansion.player.util;
|
||||
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.Damageable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public final class ItemUtil {
|
||||
|
||||
public static boolean isNullOrAir(@Nullable final ItemStack itemStack) {
|
||||
return itemStack == null || itemStack.getType().name().contains("_AIR");
|
||||
}
|
||||
|
||||
public static @NotNull String getMaterialName(@Nullable final ItemStack item) {
|
||||
return isNullOrAir(item) ? "" : item.getType().name();
|
||||
}
|
||||
|
||||
public static @NotNull String getName(@Nullable final ItemStack item) {
|
||||
if (isNullOrAir(item)) {
|
||||
return "";
|
||||
}
|
||||
|
||||
//noinspection deprecation
|
||||
return item.hasItemMeta() ? item.getItemMeta().getDisplayName() : "";
|
||||
}
|
||||
|
||||
public static int getData(@Nullable final ItemStack item) {
|
||||
if (isNullOrAir(item)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (VersionHelper.HAS_DAMAGEABLE_ITEM_META) {
|
||||
return item.hasItemMeta() ? ((Damageable) item.getItemMeta()).getDamage() : 0;
|
||||
} else {
|
||||
//noinspection deprecation
|
||||
return item.getDurability();
|
||||
}
|
||||
}
|
||||
|
||||
public static int getDurability(@Nullable final ItemStack item) {
|
||||
return isNullOrAir(item) ? 0 : item.getType().getMaxDurability() - getData(item);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package at.helpch.placeholderapi.expansion.player.util;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.PlayerInventory;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
|
||||
public final class PlayerUtil {
|
||||
|
||||
private static final BlockFace[] radial = {
|
||||
BlockFace.NORTH, BlockFace.NORTH_EAST,
|
||||
BlockFace.EAST, BlockFace.SOUTH_EAST,
|
||||
BlockFace.SOUTH, BlockFace.SOUTH_WEST,
|
||||
BlockFace.WEST, BlockFace.NORTH_WEST
|
||||
};
|
||||
|
||||
@SuppressWarnings({"DataFlowIssue", "deprecation"})
|
||||
public static @Nullable ItemStack getItemInMainHand(@NotNull final Player player) {
|
||||
return VersionHelper.HAS_OFF_HAND ? player.getInventory().getItemInMainHand() : player.getItemInHand();
|
||||
}
|
||||
|
||||
public static @NotNull String getBedCoordinate(
|
||||
@NotNull final OfflinePlayer player, @NotNull final Function<@NotNull Location, @NotNull Number> function
|
||||
) {
|
||||
return Optional.ofNullable(player.getBedSpawnLocation())
|
||||
.map(function)
|
||||
.map(String::valueOf)
|
||||
.orElse("0");
|
||||
}
|
||||
|
||||
@SuppressWarnings("OptionalOfNullableMisuse")
|
||||
public static @NotNull String getCompassCoordinate(
|
||||
@NotNull final Player player, @NotNull final Function<@NotNull Location, @NotNull Number> function
|
||||
) {
|
||||
return Optional.ofNullable(player.getCompassTarget())
|
||||
.map(function)
|
||||
.map(String::valueOf)
|
||||
.orElse("0");
|
||||
}
|
||||
|
||||
public static int getEmptySlots(@NotNull final Player player) {
|
||||
final PlayerInventory inventory = player.getInventory();
|
||||
final List<ItemStack> items = new ArrayList<>(Arrays.asList(inventory.getContents()));
|
||||
items.add(inventory.getHelmet());
|
||||
items.add(inventory.getChestplate());
|
||||
items.add(inventory.getLeggings());
|
||||
items.add(inventory.getBoots());
|
||||
|
||||
if (VersionHelper.HAS_OFF_HAND) {
|
||||
items.add(inventory.getItemInOffHand());
|
||||
}
|
||||
|
||||
return (int) items.stream().filter(ItemUtil::isNullOrAir).count();
|
||||
}
|
||||
|
||||
public static @NotNull BlockFace getDirection(@NotNull final Player player) {
|
||||
return radial[Math.round(player.getLocation().getYaw() / 45f) & 0x7].getOppositeFace();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package at.helpch.placeholderapi.expansion.player.util;
|
||||
|
||||
import com.google.common.primitives.Ints;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Damageable;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.PlayerInventory;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* @author Matt (<a href="https://github.com/lichthund">@LichtHund</a>)
|
||||
*/
|
||||
public final class VersionHelper {
|
||||
|
||||
private static final int VERSION = getCurrentVersion();
|
||||
|
||||
/**
|
||||
* @see PlayerInventory#getItemInOffHand()
|
||||
* @since MC 1.9
|
||||
*/
|
||||
public static final boolean HAS_OFF_HAND = VERSION >= 1_9_0;
|
||||
|
||||
/**
|
||||
* @see org.bukkit.inventory.meta.Damageable
|
||||
* @since MC 1.13
|
||||
*/
|
||||
public static final boolean HAS_DAMAGEABLE_ITEM_META = VERSION >= 1_13_0;
|
||||
|
||||
/**
|
||||
* @see Damageable#getAbsorptionAmount()
|
||||
* @since MC 1.15
|
||||
*/
|
||||
public static final boolean HAS_ABSORPTION_METHODS = VERSION >= 1_15_0;
|
||||
|
||||
/**
|
||||
* @see Player#getPing()
|
||||
* @since MC 1.17
|
||||
*/
|
||||
public static final boolean HAS_PLAYER_PING_METHOD = VERSION >= 1_17_0;
|
||||
|
||||
private VersionHelper() { }
|
||||
|
||||
/**
|
||||
* Gets the current server version
|
||||
*
|
||||
* @return A protocol like number representing the version, for example 1.16.5 - 1165
|
||||
*/
|
||||
private static int getCurrentVersion() {
|
||||
// No need to cache since will only run once
|
||||
final Matcher matcher = Pattern.compile("(?<version>\\d+\\.\\d+)(?<patch>\\.\\d+)?").matcher(Bukkit.getBukkitVersion());
|
||||
final StringBuilder stringBuilder = new StringBuilder();
|
||||
|
||||
if (matcher.find()) {
|
||||
final String patch = matcher.group("patch");
|
||||
|
||||
stringBuilder
|
||||
.append(matcher.group("version").replace(".", ""))
|
||||
.append((patch == null) ? "0" : patch.replace(".", ""));
|
||||
}
|
||||
|
||||
final Integer version = Ints.tryParse(stringBuilder.toString());
|
||||
|
||||
// Should never fail
|
||||
if (version == null) {
|
||||
throw new IllegalArgumentException("Could not retrieve server version!");
|
||||
}
|
||||
|
||||
return version;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user