56 Commits
Author SHA1 Message Date
darbyjack b516ac0d4e fix: update version in main class as well 2023-06-10 09:50:00 -05:00
darbyjack 60bc8fabed feat: add support for player ping in 1.20 2023-06-10 08:27:34 -05:00
darbyjack 0ffb15aeb7 Bump to 2.0.4 2023-02-19 12:24:45 -06:00
Glare a2f5da710d Merge pull request #72 from kforbro/master 2023-02-19 12:20:32 -06:00
Glare 86b860e3ff Merge pull request #74 from WildTooth/master 2023-02-19 12:19:34 -06:00
WildTooth bbdb93199b Added %has_health_boost% and %health_boost% placeholders 2023-01-31 20:24:12 +01:00
kforbro b870442d19 fix %player_colored_ping_{name}% 2023-01-24 04:20:20 +03:00
Glare dabc840d90 Update PlayerExpansion.java 2022-07-07 09:33:51 -05:00
Gabriel Dumitru f8c4afbe4a Merge pull request #38 from stonar96/feature/player-list-name
Add %player_list_name% placeholder
2021-10-04 18:12:09 +03:00
Gabriel Dumitru cd6b0e368a Merge branch 'master' into feature/player-list-name 2021-10-04 18:11:52 +03:00
iGabyTM be1998ced3 increase version to 2.0.3 2021-10-01 13:22:16 +03:00
Gabriel Dumitru ab4bc1fa2f Merge pull request #62 from PlaceholderAPI/001-gaby-add-absorption-placeholder
add %player_absorption%
2021-10-01 12:41:41 +03:00
iGabyTM 1499333583 add %player_absorption% (closes #35) 2021-10-01 12:37:52 +03:00
iGabyTM 9b2c4b9cd8 add Matt's VersionHelper util 2021-10-01 12:37:12 +03:00
BlitzOffline 642c6fd755 Merge pull request #60 from BlitzOffline/master
Made direction output configurable
2021-09-05 23:48:06 +03:00
BlitzOffline 2133751f82 Made direction output configurable 2021-09-05 23:44:10 +03:00
BlitzOffline eb47b359d1 Merge pull request #58 from eDexiam/master
Ability to change "high" and "medium" ping values
2021-09-05 15:06:08 +03:00
BlitzOffline 9fcb92271f Merge pull request #45 from Wesley51/patch-1
Add new Placeholder block_underneath
2021-09-05 15:02:26 +03:00
BlitzOffline c00f74e758 Use p instead of player. 2021-09-05 15:00:38 +03:00
BlitzOffline 671a1f3159 Merge pull request #41 from RobinDeBaets/master 2021-09-05 14:57:15 +03:00
BlitzOffline 513b29a28a Merge pull request #59 from BlitzOffline/master 2021-09-05 14:56:40 +03:00
BlitzOffline c0a1780fba Added durability placeholders. 2021-09-05 14:43:44 +03:00
eDexiam 6772d34776 Restored default values from the official repo. 2021-08-03 21:48:52 +02:00
eDexiam a5b1a0dc10 Added ability to configure which ping threshold triggers what color. 2021-08-03 21:46:51 +02:00
darbyjack 473f637e0c Push to 2.0.2 to fix versioning issue. 2021-07-12 09:48:05 -05:00
Gabriel Dumitru 4e659ede76 Version 2.0.1 2021-07-12 05:36:29 +03:00
Gabriel Dumitru a95eb4a3a0 Add %player_(x/y/z)_long%
Unlike `%player_(x/y/z)%`, this placeholder will show player's exact location, including decimals
2021-07-12 05:35:24 +03:00
Glare 6782ea8c20 Merge pull request #54 from PlaceholderAPI/1.17 2021-06-20 18:29:48 -05:00
darbyjack e178109ecd Initial 1.17 support 2021-06-12 14:35:50 -05:00
Glare 51e2b7cab2 Merge pull request #51 from Maximvdw/master 2021-06-12 14:33:09 -05:00
Maxim Van de Wynckel fc6314ad59 fix: player ping on 1.17 2021-06-12 20:49:25 +02:00
Glare 62af0e19f2 Merge pull request #48 from Maximvdw/master
feat: added extra locale placeholders and online player flags for com…
2021-06-09 08:37:24 -05:00
Maxim Van de Wynckel bb3c3d1263 feat: added extra locale placeholders and online player flags for common actions 2021-06-09 15:09:20 +02:00
AliveSteve d249df9ba2 Add new Placeholder block_underneath
block_underneath will return the block the player that is directly underneath the player. May add one in later update that adds an extra placeholder that will not return blocks like lava, air. water, etc.
2021-03-28 21:29:10 -04:00
darbyjack 73cc29bc13 Manually set the expansion version 2021-03-28 13:55:33 -05:00
RobinDeBaets 81f5e8a846 Fixes #40 2020-12-12 13:29:02 +01:00
stonar96 55a9110683 Add %player_list_name% placeholder 2020-11-24 01:40:45 +01:00
darbyjack e2972eca90 Push to 1.8.0 2020-10-03 11:36:25 -05:00
Glare 8abf652099 Merge pull request #29 from PegasisForever/master 2020-09-28 10:45:44 -05:00
pegasis bda11eb9ac Merge remote-tracking branch 'upstream/master' into master
# Conflicts:
#	src/main/java/com/extendedclip/papi/expansion/player/PlayerExpansion.java
#	src/main/java/com/extendedclip/papi/expansion/player/PlayerUtil.java
2020-09-25 22:34:50 -04:00
darbyjack 6f3fc09c88 Implemented PRed pom changes
Closes #31
2020-09-25 19:26:23 -05:00
Glare 5ce42d7769 Merge pull request #34 from Frcsty/master
Added %player_yaw% and %player_pitch% placeholders
2020-09-25 19:22:14 -05:00
Glare 70d0b26591 Merge pull request #32 from PlaceholderAPI/fixes 2020-09-25 19:21:12 -05:00
pegasis 134e21af64 fix biome_capitalized again 2020-08-25 10:25:12 -04:00
pegasis 4c3982f872 solve some warnings 2020-08-25 10:00:53 -04:00
pegasis f27e675ce1 fix underscore in biome_capitalized 2020-08-25 09:37:55 -04:00
Frosty 9f1e5740ba Added %player_yaw% and %player_pitch% placeholders 2020-07-27 12:40:25 +02:00
Sxtanna 48842a7f9d updated player ping resolution to use cached reflection, and to color properly 2020-07-22 16:32:45 -04:00
Sxtanna d088649a1c added override annotation to onRequest :/ 2020-07-22 15:56:13 -04:00
Sxtanna 219833eb00 made classes final, made playerutil non instantiable 2020-07-22 15:54:54 -04:00
Sxtanna 1a59b183c8 updated gitignore to match papi's 2020-07-22 15:53:29 -04:00
pegasis fc4fe06fd5 use world environment to get world type instead of world name (thanks discord Illusion... Maybe?#2824) 2020-06-02 09:51:30 -04:00
pegasis c227977470 change biome_capitalize to biome_capitalized 2020-05-31 21:12:05 -04:00
pegasis 763f4f08cf fix getXZDirection 2020-05-31 20:57:00 -04:00
pegasis 0cf0b6aea5 add "world_type" 2020-05-31 20:56:51 -04:00
pegasis d8d639bbab add "direction_xz", "biome_capitalize", "light_level" 2020-05-31 20:35:56 -04:00
5 changed files with 473 additions and 162 deletions

No files matched your search

+7 -2
View File
@@ -12,6 +12,8 @@ local.properties
.loadpath
.recommenders
/.idea/
# External tool builders
.externalToolBuilders/
@@ -114,7 +116,7 @@ fabric.properties
### Intellij Patch ###
# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
# *.iml
*.iml
# modules.xml
# .idea/misc.xml
# *.ipr
@@ -143,4 +145,7 @@ nbbuild/
dist/
nbdist/
.nb-gradle/
nbactions.xml
nbactions.xml
### Piggy's Debugging Shit ###
server/
+20 -21
View File
@@ -1,11 +1,19 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.extendedclip.papi.expansion.player</groupId>
<artifactId>player-expansion</artifactId>
<version>1.7.3</version>
<version>2.0.5</version>
<name>PAPI-Expansion-Player</name>
<description>PlaceholderAPI expansion for player placeholders</description>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<repositories>
<repository>
<id>spigot-repo</id>
@@ -13,32 +21,34 @@
</repository>
<repository>
<id>placeholderapi</id>
<url>http://repo.extendedclip.com/content/repositories/placeholderapi/</url>
<url>https://repo.extendedclip.com/content/repositories/placeholderapi/</url>
</repository>
</repositories>
</repositories>
<dependencies>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.12-R0.1-SNAPSHOT</version>
<scope>compile</scope>
<version>1.20-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>me.clip</groupId>
<artifactId>placeholderapi</artifactId>
<version>2.10.9</version>
<version>2.11.3</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<finalName>${name}</finalName>
<finalName>${project.name}</finalName>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
@@ -47,17 +57,6 @@
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.2</version>
<configuration>
<target>1.8</target>
<source>1.8</source>
<encoding>UTF-8</encoding>
<useIncrementalCompilation>false</useIncrementalCompilation>
</configuration>
</plugin>
</plugins>
</build>
</project>
@@ -21,9 +21,6 @@
package com.extendedclip.papi.expansion.player;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import me.clip.placeholderapi.PlaceholderAPIPlugin;
import me.clip.placeholderapi.expansion.Configurable;
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
@@ -31,19 +28,41 @@ import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.OfflinePlayer;
import org.bukkit.World;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
import org.bukkit.potion.PotionEffectType;
import java.util.Date;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static com.extendedclip.papi.expansion.player.PlayerUtil.durability;
import static com.extendedclip.papi.expansion.player.PlayerUtil.format12;
import static com.extendedclip.papi.expansion.player.PlayerUtil.format24;
import static com.extendedclip.papi.expansion.player.PlayerUtil.getBiome;
import static com.extendedclip.papi.expansion.player.PlayerUtil.getCapitalizedBiome;
import static com.extendedclip.papi.expansion.player.PlayerUtil.getEmptySlots;
import static com.extendedclip.papi.expansion.player.PlayerUtil.getDirection;
import static com.extendedclip.papi.expansion.player.PlayerUtil.getTotalExperience;
import static com.extendedclip.papi.expansion.player.PlayerUtil.getXZDirection;
import static com.extendedclip.papi.expansion.player.PlayerUtil.itemInHand;
import static com.extendedclip.papi.expansion.player.PlayerUtil.*;
public final class PlayerExpansion extends PlaceholderExpansion implements Configurable {
private String low;
private String medium;
private String high;
public class PlayerExpansion extends PlaceholderExpansion implements Configurable {
private int mediumValue;
private int highValue;
private final String VERSION = getClass().getPackage().getImplementationVersion();
private String low, medium, high;
private String north;
private String northEast;
private String east;
private String southEast;
private String south;
private String southWest;
private String west;
private String northWest;
@Override
public String getIdentifier() {
@@ -57,43 +76,37 @@ public class PlayerExpansion extends PlaceholderExpansion implements Configurabl
@Override
public String getVersion() {
return VERSION;
return "2.0.5";
}
@Override
public Map<String, Object> getDefaults() {
Map<String, Object> defaults = new HashMap<>();
defaults.put("ping_color.high", "&a");
defaults.put("ping_color.high", "&c");
defaults.put("ping_color.medium", "&e");
defaults.put("ping_color.low", "&c");
defaults.put("ping_color.low", "&a");
defaults.put("ping_value.medium", 50);
defaults.put("ping_value.high", 100);
defaults.put("direction.north", "N");
defaults.put("direction.north_east", "NE");
defaults.put("direction.east", "E");
defaults.put("direction.south_east", "SE");
defaults.put("direction.south", "S");
defaults.put("direction.south_west", "SW");
defaults.put("direction.west", "W");
defaults.put("direction.north_west", "NW");
return defaults;
}
@Override
public String onRequest(OfflinePlayer player, String identifier) {
high = this.getString("ping_color.high", "&a");
medium = this.getString("ping_color.medium", "&e");
low = this.getString("ping_color.low", "&c");
if (identifier.startsWith("ping_")) {
if (identifier.split("ping_").length > 1) {
identifier = identifier.split("ping_")[1];
Player t = Bukkit.getPlayer(identifier);
if (t != null) {
return getPing(t);
}
}
return "0";
}
if (identifier.startsWith("colored_ping_")) {
if (identifier.split("colored_ping_").length > 1) {
identifier = identifier.split("colored_ping_")[1];
Player t = Bukkit.getPlayer(identifier);
if (t != null) {
int p = Integer.valueOf(getPing(t));
return ChatColor.translateAlternateColorCodes('&', p > 100 ? low : p >= 50 ? medium : high) + getPing(t);
}
}
return "0";
final boolean targetedPing = identifier.startsWith("ping_");
final boolean targetedColoredPing = identifier.startsWith("colored_ping_");
if (targetedPing || targetedColoredPing) {
final Player target = Bukkit.getPlayer(identifier.substring(targetedPing ? 5 : 13)); // yes, I know, magic value
return target == null ? "0" : retrievePing(target, targetedColoredPing);
}
if (player == null) {
@@ -137,6 +150,7 @@ public class PlayerExpansion extends PlaceholderExpansion implements Configurabl
case "bed_world":
return player.getBedSpawnLocation() != null ? player.getBedSpawnLocation().getWorld()
.getName() : "";
}
// online placeholders
@@ -146,6 +160,11 @@ public class PlayerExpansion extends PlaceholderExpansion implements Configurabl
Player p = player.getPlayer();
// to get rid of IDE warnings
if (p == null) {
return "";
}
if (identifier.startsWith("has_permission_")) {
if (identifier.split("has_permission_").length > 1) {
String perm = identifier.split("has_permission_")[1];
@@ -153,23 +172,23 @@ public class PlayerExpansion extends PlaceholderExpansion implements Configurabl
}
return bool(false);
}
if (identifier.startsWith("has_potioneffect_")) {
if (identifier.split("has_potioneffect_").length > 1) {
String effect = identifier.split("has_potioneffect_")[1];
PotionEffectType potion = PotionEffectType.getByName(effect);
return bool(p.hasPotionEffect(potion));
}
if (identifier.split("has_potioneffect_").length > 1) {
String effect = identifier.split("has_potioneffect_")[1];
PotionEffectType potion = PotionEffectType.getByName(effect);
return bool(p.hasPotionEffect(potion));
}
}
if (identifier.startsWith("item_in_hand_level_")){
if (identifier.split("item_in_hand_level_").length > 1){
if (identifier.startsWith("item_in_hand_level_")) {
if (identifier.split("item_in_hand_level_").length > 1) {
String enchantment = identifier.split("item_in_hand_level_")[1];
return String.valueOf(itemInHand(p).getEnchantmentLevel(Enchantment.getByName(enchantment)));
}
return "0";
}
if (identifier.startsWith("item_in_offhand_level_")){
if (identifier.startsWith("item_in_offhand_level_")) {
if (identifier.split("item_in_offhand_level_").length > 1) {
String enchantment = identifier.split("item_in_offhand_level_")[1];
return String.valueOf(p.getInventory().getItemInOffHand().getEnchantmentLevel(Enchantment.getByName(enchantment)));
@@ -177,9 +196,43 @@ public class PlayerExpansion extends PlaceholderExpansion implements Configurabl
return "0";
}
if (identifier.startsWith("locale")) {
String localeStr = PlayerUtil.getLocale(p);
String localeStrISO = localeStr.replace("_", "-");
switch (identifier) {
case "locale":
return localeStr;
case "locale_country":
Locale locale = Locale.forLanguageTag(localeStrISO);
if (locale == null)
return "";
return locale.getCountry();
case "locale_display_country":
locale = Locale.forLanguageTag(localeStrISO);
if (locale == null)
return "";
return locale.getDisplayCountry();
case "locale_display_name":
locale = Locale.forLanguageTag(localeStrISO);
if (locale == null)
return "";
return locale.getDisplayName();
case "locale_short":
return localeStr.substring(0, localeStr.indexOf("_"));
}
}
switch (identifier) {
case "absorption": {
if (VersionHelper.HAS_ABSORPTION_METHODS) {
return Integer.toString((int) p.getAbsorptionAmount());
} else {
return "-1";
}
}
case "has_empty_slot":
return bool(p.getInventory().firstEmpty() > - 1);
return bool(p.getInventory().firstEmpty() > -1);
case "empty_slots":
return String.valueOf(getEmptySlots(p));
case "server":
@@ -187,22 +240,66 @@ public class PlayerExpansion extends PlaceholderExpansion implements Configurabl
return "now available in the server expansion";
case "displayname":
return p.getDisplayName();
case "locale":
return p.getLocale();
case "list_name":
return p.getPlayerListName();
case "gamemode":
return p.getGameMode().name();
case "direction":
return getCardinalDirection(p);
switch (getDirection(p)) {
case NORTH:
return north;
case NORTH_EAST:
return northEast;
case EAST:
return east;
case SOUTH_EAST:
return southEast;
case SOUTH:
return south;
case SOUTH_WEST:
return southWest;
case WEST:
return west;
case NORTH_WEST:
return northWest;
}
return "";
case "direction_xz":
return getXZDirection(p);
case "world":
return p.getWorld().getName();
case "world_type":
World.Environment environment = p.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";
}
return "";
case "x":
return String.valueOf(p.getLocation().getBlockX());
case "x_long":
return String.valueOf(p.getLocation().getX());
case "y":
return String.valueOf(p.getLocation().getBlockY());
case "y_long":
return String.valueOf(p.getLocation().getY());
case "z":
return String.valueOf(p.getLocation().getBlockZ());
case "z_long":
return String.valueOf(p.getLocation().getZ());
case "yaw":
return String.valueOf(p.getLocation().getYaw());
case "pitch":
return String.valueOf(p.getLocation().getPitch());
case "biome":
return String.valueOf(p.getLocation().getBlock().getBiome());
return getBiome(p);
case "biome_capitalized":
return getCapitalizedBiome(p);
case "light_level":
return String.valueOf(p.getLocation().getBlock().getLightLevel());
case "ip":
return p.getAddress().getAddress().getHostAddress();
case "allow_flight":
@@ -217,6 +314,8 @@ public class PlayerExpansion extends PlaceholderExpansion implements Configurabl
return p.getCompassTarget() != null ? String.valueOf(p.getCompassTarget().getBlockZ()) : "";
case "compass_world":
return p.getCompassTarget() != null ? p.getCompassTarget().getWorld().getName() : "";
case "block_underneath":
return String.valueOf(p.getLocation().clone().subtract(0, 1, 0).getBlock().getType());
case "custom_name":
return p.getCustomName() != null ? p.getCustomName() : p.getName();
case "exp":
@@ -239,18 +338,31 @@ public class PlayerExpansion extends PlaceholderExpansion implements Configurabl
return String.valueOf(Math.round(p.getHealth()));
case "health_scale":
return String.valueOf(p.getHealthScale());
case "has_health_boost":
return bool(p.hasPotionEffect(PotionEffectType.HEALTH_BOOST));
case "health_boost": {
if (p.getHealthScale() > 20) {
return Double.toString(p.getHealthScale() - 20);
} else {
return "0";
}
}
case "item_in_hand":
return String.valueOf(itemInHand(p).getType());
case "item_in_hand_name":
return itemInHand(p).getType() != Material.AIR && itemInHand(p).getItemMeta().hasDisplayName() ? itemInHand(p).getItemMeta().getDisplayName() : "";
case "item_in_hand_data":
return itemInHand(p).getType() != Material.AIR ? String.valueOf(itemInHand(p).getDurability()) : "0";
case "item_in_hand_durability":
return String.valueOf(durability(itemInHand(p)));
case "item_in_offhand":
return String.valueOf(p.getInventory().getItemInOffHand().getType());
case "item_in_offhand_name":
return p.getInventory().getItemInOffHand().getType() != Material.AIR && p.getInventory().getItemInOffHand().getItemMeta().hasDisplayName() ? p.getInventory().getItemInOffHand().getItemMeta().getDisplayName() : "";
case "item_in_offhand_data":
return p.getInventory().getItemInOffHand().getType() != Material.AIR ? String.valueOf(p.getInventory().getItemInOffHand().getDurability()) : "0";
case "item_in_offhand_durability":
return String.valueOf(durability(p.getInventory().getItemInOffHand()));
case "last_damage":
return String.valueOf(p.getLastDamage());
case "max_health":
@@ -267,23 +379,30 @@ public class PlayerExpansion extends PlaceholderExpansion implements Configurabl
return Optional.ofNullable(p.getInventory().getHelmet()).map(a -> a.getItemMeta().getDisplayName()).orElse("");
case "armor_helmet_data":
return p.getInventory().getHelmet() != null ? String.valueOf(p.getInventory().getHelmet().getDurability()) : "0";
case "armor_helmet_durability":
return String.valueOf(durability(p.getInventory().getHelmet()));
case "armor_chestplate_name":
return Optional.ofNullable(p.getInventory().getChestplate()).map(a -> a.getItemMeta().getDisplayName()).orElse("");
case "armor_chestplate_data":
return p.getInventory().getChestplate() != null ? String.valueOf(p.getInventory().getChestplate().getDurability()) : "0";
case "armor_chestplate_durability":
return String.valueOf(durability(p.getInventory().getChestplate()));
case "armor_leggings_name":
return Optional.ofNullable(p.getInventory().getLeggings()).map(a -> a.getItemMeta().getDisplayName()).orElse("");
case "armor_leggings_data":
return p.getInventory().getLeggings() != null ? String.valueOf(p.getInventory().getLeggings().getDurability()) : "0";
case "armor_leggings_durability":
return String.valueOf(durability(p.getInventory().getLeggings()));
case "armor_boots_name":
return Optional.ofNullable(p.getInventory().getBoots()).map(a -> a.getItemMeta().getDisplayName()).orElse("");
case "armor_boots_data":
return p.getInventory().getBoots() != null ? String.valueOf(p.getInventory().getBoots().getDurability()) : "0";
case "armor_boots_durability":
return String.valueOf(durability(p.getInventory().getBoots()));
case "ping":
return getPing(p);
return retrievePing(p, false);
case "colored_ping":
int ping = Integer.valueOf(getPing(p));
return ChatColor.translateAlternateColorCodes('&', ping > 100 ? low : ping >= 50 ? medium : high) + getPing(p);
return retrievePing(p, true);
case "time":
return String.valueOf(p.getPlayerTime());
case "time_offset":
@@ -299,9 +418,9 @@ public class PlayerExpansion extends PlaceholderExpansion implements Configurabl
case "ticks_lived":
return String.valueOf(p.getTicksLived());
case "seconds_lived":
return String.valueOf(p.getTicksLived() * 20);
return String.valueOf(p.getTicksLived() / 20);
case "minutes_lived":
return String.valueOf((p.getTicksLived() * 20) / 60);
return String.valueOf((p.getTicksLived() / 20) / 60);
case "walk_speed":
return String.valueOf(p.getWalkSpeed());
case "weather_duration":
@@ -312,13 +431,59 @@ public class PlayerExpansion extends PlaceholderExpansion implements Configurabl
return format12(p.getWorld().getTime());
case "world_time_24":
return format24(p.getWorld().getTime());
case "is_flying":
return bool(p.isFlying());
case "is_sleeping":
return bool(p.isSleeping());
case "is_conversing":
return bool(p.isConversing());
case "is_dead":
return bool(p.isDead());
case "is_sneaking":
return bool(p.isSneaking());
case "is_sprinting":
return bool(p.isSprinting());
case "is_leashed":
return bool(p.isLeashed());
case "is_inside_vehicle":
return bool(p.isInsideVehicle());
}
// return null for unknown placeholders
return null;
}
@Override
public boolean register() {
low = this.getString("ping_color.low", "&a");
medium = this.getString("ping_color.medium", "&e");
high = this.getString("ping_color.high", "&c");
mediumValue = this.getInt("ping_value.medium", 50);
highValue = this.getInt("ping_value.high", 100);
north = this.getString("direction.north", "N");
northEast = this.getString("direction.north_east", "NE");
east = this.getString("direction.east", "E");
southEast = this.getString("direction.south_east", "SE");
south = this.getString("direction.south", "S");
southWest = this.getString("direction.south_west", "SW");
west = this.getString("direction.west", "W");
northWest = this.getString("direction.north_west", "NW");
return super.register();
}
public String bool(boolean b) {
return b ? PlaceholderAPIPlugin.booleanTrue() : PlaceholderAPIPlugin.booleanFalse();
}
}
private String retrievePing(final Player player, final boolean colored) {
final int ping = PlayerUtil.getPing(player);
if (!colored) {
return String.valueOf(ping);
}
return ChatColor.translateAlternateColorCodes('&', ping > highValue ? high : ping > mediumValue ? medium : low) + ping;
}
}
@@ -2,15 +2,18 @@ package com.extendedclip.papi.expansion.player;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Locale;
import java.util.function.Function;
/*
*
@@ -32,93 +35,163 @@ import java.util.Locale;
*
*
*/
public class PlayerUtil {
public final class PlayerUtil {
public static final int ticksAtMidnight = 18000;
public static final int ticksPerDay = 24000;
public static final int ticksPerHour = 1000;
public static final double ticksPerMinute = 1000d / 60d;
public static final double ticksPerSecond = 1000d / 60d / 60d;
private static final SimpleDateFormat twentyFour = new SimpleDateFormat("HH:mm", Locale.ENGLISH);
private static final SimpleDateFormat twelve = new SimpleDateFormat("h:mm aa", Locale.ENGLISH);
public static final int ticksAtMidnight = 18000;
public static final int ticksPerDay = 24000;
public static final int ticksPerHour = 1000;
public static final double ticksPerMinute = 1000d / 60d;
private static final SimpleDateFormat twentyFour = new SimpleDateFormat("HH:mm", Locale.ENGLISH);
private static final SimpleDateFormat twelve = new SimpleDateFormat("h:mm aa", Locale.ENGLISH);
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 };
public static String getPing(Player p) {
try {
Method getHandleMethod = p.getClass().getDeclaredMethod("getHandle", new Class[0]);
Object nmsplayer = getHandleMethod.invoke(p, new Object[0]);
Field pingField = nmsplayer.getClass().getDeclaredField("ping");
return String.valueOf(pingField.getInt(nmsplayer));
} catch (Exception e) {
e.printStackTrace();
}
return "0";
}
private PlayerUtil() { }
public static String format12(long ticks) {
try {
return twelve.format(twentyFour.parse(ticksToTime(ticks)));
} catch (ParseException e) {
return ticksToTime(ticks);
}
}
private static final Function<Player, Integer> PLAYER_GET_PING = new Function<Player, Integer>() {
public static String format24(long ticks) {
return ticksToTime(ticks);
}
private Field ping;
private Method getHandle;
private static String ticksToTime(long ticks) {
ticks = ticks - ticksAtMidnight + ticksPerDay;
long hours = ticks / ticksPerHour;
ticks -= hours * ticksPerHour;
long mins = (long) Math.floor(ticks / ticksPerMinute);
if (hours >= 24) {
hours = hours - 24;
}
return (hours < 10 ? "0" + hours : hours) + ":" + (mins < 10 ? "0" + mins : mins);
}
@Override
public Integer apply(final Player player) {
if (ping == null) {
try {
cacheReflection(player);
} catch (InvocationTargetException | NoSuchMethodException | IllegalAccessException | NoSuchFieldException ex) {
ex.printStackTrace();
}
}
public static String getCardinalDirection(Player player) {
double rotation = player.getLocation().getYaw() - 180.0F;
if (rotation < 0.0D) {
rotation += 360.0D;
}
if ((0.0D <= rotation) && (rotation < 22.5D)) {
return "N";
}
if ((22.5D <= rotation) && (rotation < 67.5D)) {
return "NE";
}
if ((67.5D <= rotation) && (rotation < 112.5D)) {
return "E";
}
if ((112.5D <= rotation) && (rotation < 157.5D)) {
return "SE";
}
if ((157.5D <= rotation) && (rotation < 202.5D)) {
return "S";
}
if ((202.5D <= rotation) && (rotation < 247.5D) || (rotation <= -119.33) && (rotation > -179)) {
return "SW";
}
if ((247.5D <= rotation) && (rotation < 292.5D) || (rotation <= -59.66) && (rotation > -119.33)) {
return "W";
}
if ((292.5D <= rotation) && (rotation < 337.5D) || (rotation <= -0.0) && (rotation > -59.66)) {
return "NW";
}
if ((337.5D <= rotation) && (rotation < 360.0D)) {
return "N";
}
return "";
}
try {
return ping.getInt(getHandle.invoke(player));
} catch (final IllegalAccessException | InvocationTargetException ex) {
ex.printStackTrace();
}
return -1;
}
public static ItemStack itemInHand(Player p) {
try {
return p.getInventory().getItemInMainHand();
} catch (NoSuchMethodError e) {
return p.getInventory().getItemInHand();
private void cacheReflection(final Player player) throws NoSuchFieldException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
getHandle = player.getClass().getDeclaredMethod("getHandle");
getHandle.setAccessible(true);
final Object entityPlayer = getHandle.invoke(player);
String pingFieldName;
if (VersionHelper.IS_1_20_OR_NEWER) {
pingFieldName = "f";
} else if (VersionHelper.IS_1_17_OR_NEWER) {
pingFieldName = "e";
} else {
pingFieldName = "ping";
}
ping = entityPlayer.getClass().getDeclaredField(pingFieldName);
ping.setAccessible(true);
}
};
private static final Function<Player, String> PLAYER_GET_LOCALE = new Function<Player, String>() {
private Field locale;
private Method getHandle;
@Override
public String apply(final Player player) {
if (locale == null) {
try {
cacheReflection(player);
} catch (InvocationTargetException | NoSuchMethodException | IllegalAccessException | NoSuchFieldException ex) {
ex.printStackTrace();
}
}
try {
final Object entityPlayer = getHandle.invoke(player);
return (String) locale.get(entityPlayer);
} catch (final IllegalAccessException | InvocationTargetException ex) {
ex.printStackTrace();
}
return "en_US";
}
private void cacheReflection(final Player player) throws NoSuchFieldException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
getHandle = player.getClass().getDeclaredMethod("getHandle");
getHandle.setAccessible(true);
final Object entityPlayer = getHandle.invoke(player);
locale = entityPlayer.getClass().getField("locale");
}
};
public static int getPing(final Player player) {
return PLAYER_GET_PING.apply(player);
}
public static String getLocale(final Player player) {
return PLAYER_GET_LOCALE.apply(player);
}
public static String format12(long ticks) {
try {
return twelve.format(twentyFour.parse(ticksToTime(ticks)));
} catch (ParseException e) {
return ticksToTime(ticks);
}
}
public static String format24(long ticks) {
return ticksToTime(ticks);
}
private static String ticksToTime(long ticks) {
ticks = ticks - ticksAtMidnight + ticksPerDay;
long hours = ticks / ticksPerHour;
ticks -= hours * ticksPerHour;
long mins = (long) Math.floor(ticks / ticksPerMinute);
if (hours >= 24) {
hours = hours - 24;
}
return (hours < 10 ? "0" + hours : hours) + ":" + (mins < 10 ? "0" + mins : mins);
}
public static BlockFace getDirection(Player player) {
return radial[Math.round(player.getLocation().getYaw() / 45f) & 0x7].getOppositeFace();
}
public static String getXZDirection(Player player) {
double rotation = player.getLocation().getYaw();
if (rotation < 0.0D) {
rotation += 360.0D;
}
if (Math.abs(rotation) <= 45 || Math.abs(rotation - 360) <= 45) {
return "+Z";
} else if (Math.abs(rotation - 90) <= 45) {
return "-X";
} else if (Math.abs(rotation - 180) <= 45) {
return "-Z";
} else if (Math.abs(rotation - 270) <= 45) {
return "+X";
}
return "";
}
public static ItemStack itemInHand(Player p) {
try {
return p.getInventory().getItemInMainHand();
} catch (NoSuchMethodError e) {
return p.getInventory().getItemInHand();
}
}
public static int durability(ItemStack item) {
return item != null ? item.getType().getMaxDurability() - item.getDurability() : 0;
}
}
public static int getEmptySlots(Player p) {
int slots = 0;
@@ -128,11 +201,11 @@ public class PlayerUtil {
}
if (!Bukkit.getBukkitVersion().contains("1.7") && !Bukkit.getBukkitVersion().contains("1.8")) {
if (inv.getItemInOffHand() == null || inv.getItemInOffHand().getType() == Material.AIR) slots--;
if (inv.getHelmet() == null) slots--;
if (inv.getChestplate() == null) slots--;
if (inv.getLeggings() == null) slots--;
if (inv.getBoots() == null) slots--;
if (inv.getItemInOffHand() == null || inv.getItemInOffHand().getType() == Material.AIR) slots--;
if (inv.getHelmet() == null) slots--;
if (inv.getChestplate() == null) slots--;
if (inv.getLeggings() == null) slots--;
if (inv.getBoots() == null) slots--;
}
return slots;
}
@@ -159,4 +232,16 @@ public class PlayerUtil {
}
return experience;
}
public static String getBiome(Player p) {
return String.valueOf(p.getLocation().getBlock().getBiome());
}
public static String getCapitalizedBiome(Player p) {
String[] biomeWords = getBiome(p).split("_");
for (int i = 0; i < biomeWords.length; i++) {
biomeWords[i] = biomeWords[i].substring(0, 1).toUpperCase() + biomeWords[i].substring(1).toLowerCase();
}
return String.join(" ", biomeWords);
}
}
@@ -0,0 +1,57 @@
package com.extendedclip.papi.expansion.player;
import com.google.common.primitives.Ints;
import org.bukkit.Bukkit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author Matt (<a href="https://github.com/ipsk">@ipsk</a>)
*/
public final class VersionHelper {
private static final int VERSION = getCurrentVersion();
/**
* <a href="https://docs.docdex.helpch.at/1.15/org/bukkit/entity/Damageable.html#getAbsorptionAmount--">
* Damageable#getAbsorptionAmount
* </a>
*/
public static final boolean HAS_ABSORPTION_METHODS = VERSION >= 1_15_0;
public static final boolean IS_1_17_OR_NEWER = VERSION >= 1_17_0;
public static final boolean IS_1_20_OR_NEWER = VERSION >= 1_20_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;
}
}