/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.royaldev.royalcommands;
import com.onarandombox.MultiverseCore.api.MultiverseWorld;
import net.milkbowl.vault.chat.Chat;
import org.bukkit.BanList;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.OfflinePlayer;
import org.bukkit.Sound;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.command.Command;
import org.bukkit.command.CommandMap;
import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Animals;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Vehicle;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.plugin.Plugin;
import org.bukkit.util.Vector;
import org.royaldev.royalchat.RoyalChat;
import org.royaldev.royalcommands.configuration.GeneralConfiguration;
import org.royaldev.royalcommands.configuration.PlayerConfiguration;
import org.royaldev.royalcommands.configuration.PlayerConfigurationManager;
import org.royaldev.royalcommands.exceptions.InvalidItemNameException;
import org.royaldev.royalcommands.listeners.BackpackListener;
import org.royaldev.royalcommands.rcommands.CmdBack;
import org.royaldev.royalcommands.shaded.mkremins.fanciful.FancyMessage;
import org.royaldev.royalcommands.spawninfo.SpawnInfo;
import org.royaldev.royalcommands.tools.NameFetcher;
import org.royaldev.royalcommands.tools.UUIDFetcher;
import java.io.File;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.Enumeration;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.regex.Pattern;
@SuppressWarnings("unused")
public final class RUtils {
public static final Set<Material> AIR_MATERIALS = new HashSet<>();
static {
for (final Material m : Material.values()) {
if (m.isSolid()) continue;
AIR_MATERIALS.add(m);
}
}
private static final Map<String, Integer> teleRunners = new HashMap<>();
private static final List<String> teleAllowed = new ArrayList<>();
public static FancyMessage addCommandTo(FancyMessage fm, String command) {
return RUtils.addDataTo(fm, new String[]{"clickActionName", "clickActionData"}, "run_command", command);
}
public static FancyMessage addDataTo(FancyMessage fm, String[] fields, Object... values) {
final Iterator i = fm.iterator();
for (final Object o : fm) {
try {
RUtils.setFields(o, fields, values);
} catch (ReflectiveOperationException ex) {
ex.printStackTrace();
return fm;
}
}
return fm;
}
/**
* Adds lore to an ItemStack.
*
* @param is ItemStack to add lore to
* @param newLore Lore to add
* @return ItemStack with added lore
*/
public static ItemStack addLore(ItemStack is, String newLore) {
if (is == null) throw new IllegalArgumentException("ItemStack cannot be null!");
if (newLore == null) return is;
ItemMeta im = is.getItemMeta();
List<String> lores = im.getLore();
if (lores == null) lores = new ArrayList<>();
lores.add(newLore);
im.setLore(lores);
is.setItemMeta(im);
return is;
}
public static ItemStack applySpawnLore(ItemStack stack) {
final ItemMeta im = stack.getItemMeta();
final List<String> lore = (im.hasLore()) ? im.getLore() : new ArrayList<String>();
for (String s : Config.itemSpawnTagLore) lore.add(RUtils.colorize(s));
im.setLore(lore);
stack.setItemMeta(im);
return stack;
}
public static void banIP(String ip, CommandSender cs, String reason) {
final BanList bl = Bukkit.getBanList(BanList.Type.IP);
bl.addBan(ip, reason, null, cs.getName());
}
/**
* Bans a player. Message is not sent to banned player or person who banned.
* Message is broadcasted to those with rcmds.see.ban
* Kicks banned player if they're online.
* <p/>
* This is only used for permabans.
*
* @param t Player to ban
* @param cs CommandSender who issued the ban
* @param reason Reason for the ban
*/
public static void banPlayer(OfflinePlayer t, CommandSender cs, String reason) {
reason = colorize(reason);
final BanList bl = Bukkit.getBanList(BanList.Type.NAME);
bl.addBan(t.getName(), reason, null, cs.getName());
writeBanHistory(t);
String inGameFormat = Config.igBanFormat;
String outFormat = Config.banFormat;
executeBanActions(t, cs, reason);
Bukkit.getServer().broadcast(getInGameMessage(inGameFormat, reason, t, cs), "rcmds.see.ban");
if (t.isOnline()) ((Player) t).kickPlayer(getMessage(outFormat, reason, cs));
}
public static void cancelTeleportRunner(final Player p) {
synchronized (teleRunners) {
if (teleRunners.containsKey(p.getName())) {
Bukkit.getScheduler().cancelTask(teleRunners.get(p.getName()));
teleRunners.remove(p.getName());
}
}
}
/**
* Charges a CommandSender an amount of money
*
* @param cs CommandSender to charge
* @param amount Amount to charge cs
* @return true if transaction was successful, false if otherwise
*/
public static boolean chargePlayer(CommandSender cs, double amount) {
if (!(cs instanceof OfflinePlayer)) return false;
final OfflinePlayer op = (OfflinePlayer) cs;
if (!RoyalCommands.getInstance().vh.usingVault() || RoyalCommands.getInstance().vh.getEconomy() == null) {
cs.sendMessage(MessageColor.NEGATIVE + "No economy! Continuing without charging.");
return true;
}
if (!RoyalCommands.getInstance().vh.getEconomy().hasAccount(op)) {
cs.sendMessage(MessageColor.NEGATIVE + "You don't have a bank account!");
return false;
}
if (RoyalCommands.getInstance().vh.getEconomy().getBalance(op) < amount) {
cs.sendMessage(MessageColor.NEGATIVE + "You don't have enough money!");
return false;
}
RoyalCommands.getInstance().vh.getEconomy().withdrawPlayer(op, amount);
cs.sendMessage(MessageColor.POSITIVE + "You have had " + MessageColor.NEUTRAL + RoyalCommands.getInstance().vh.getEconomy().format(amount) + MessageColor.POSITIVE + " removed from your account.");
return true;
}
public static void checkMail(Player p) {
PlayerConfiguration pcm = PlayerConfigurationManager.getConfiguration(p);
if (!pcm.getStringList("mail").isEmpty()) {
int count = pcm.getStringList("mail").size();
String poss = (count != 1) ? "s" : "";
p.sendMessage(MessageColor.POSITIVE + "Your mailbox contains " + MessageColor.NEUTRAL + count + MessageColor.POSITIVE + " message" + poss + ".");
if (RoyalCommands.getInstance().ah.isAuthorized(p, "rcmds.mail"))
p.sendMessage(MessageColor.POSITIVE + "View mail with " + MessageColor.NEUTRAL + "/mail read" + MessageColor.POSITIVE + ".");
}
}
/**
* Clears lore on an ItemStack.
*
* @param is ItemStack to clear lore from
* @return ItemStack with no lore
*/
public static ItemStack clearLore(ItemStack is) {
if (is == null) throw new IllegalArgumentException("ItemStack cannot be null!");
ItemMeta im = is.getItemMeta();
im.setLore(null);
is.setItemMeta(im);
return is;
}
/**
* Replaces raw color codes with processed color codes
*
* @param text String with codes to be converted
* @return Processed string
*/
public static String colorize(final String text) {
if (text == null) return null;
return ChatColor.translateAlternateColorCodes('&', text);
// return text.replaceAll("(?i)&([a-f0-9k-or])", ChatColor.COLOR_CHAR + "$1");
}
/**
* Returns an empty inventory for use.
*
* @param handler May be null - owner of inventory
* @param size Size of inventory - MUST be divisible by 9
* @param name May be null (default to Chest) - name of inventory to open
* @return Inventory or null if size not divisible by 9
*/
public static Inventory createInv(InventoryHolder handler, Integer size, String name) {
if (size == null) size = 27;
//if (size % 9 != 0) return null;
final Inventory i = Bukkit.getServer().createInventory(handler, size, name);
i.clear();
return i;
}
private static int dateDiff(int type, Calendar fromDate, Calendar toDate, boolean future) {
int diff = 0;
long savedDate = fromDate.getTimeInMillis();
while ((future && !fromDate.after(toDate)) || (!future && !fromDate.before(toDate))) {
savedDate = fromDate.getTimeInMillis();
fromDate.add(type, future ? 1 : -1);
diff++;
}
diff--;
fromDate.setTimeInMillis(savedDate);
return diff;
}
/**
* Removes color codes that have not been processed yet (&char)
* <p/>
* This fixes a common exploit where color codes can be embedded into other codes:
* &&aa (replaces &a, and the other letters combine to make &a again)
*
* @param message String with raw color codes
* @return String without raw color codes
*/
public static String decolorize(String message) {
final Pattern p = Pattern.compile("(?i)&[a-f0-9k-or]");
boolean contains = p.matcher(message).find();
while (contains) {
message = message.replaceAll("(?i)&[a-f0-9k-or]", "");
contains = p.matcher(message).find();
}
return message;
}
/**
* Recursively deletes a directory.
*
* @param f Directory to delete
* @return If all files were deleted, true, else false
*/
public static boolean deleteDirectory(File f) {
boolean success = true;
if (!f.isDirectory()) return false;
File[] files = f.listFiles();
if (files == null) return false;
for (File delete : files) {
if (delete.isDirectory()) {
boolean recur = deleteDirectory(delete);
if (success) success = recur; // if all has been okay, set to new value.
continue;
}
if (!delete.delete()) {
RoyalCommands.getInstance().getLogger().warning("Could not delete " + delete.getAbsolutePath());
success = false;
}
}
if (success) success = f.delete(); // don't delete directory if files still remain
return success;
}
/**
* Sends the standard message of no permission to console and command sender
*
* @param cs CommandSender to send message to
*/
public static void dispNoPerms(CommandSender cs) {
cs.sendMessage(MessageColor.NEGATIVE + "You don't have permission for that!");
RoyalCommands.getInstance().getLogger().warning(cs.getName() + " was denied access to that!");
}
/**
* Displays a no permissions message to the command sender and console/
*
* @param cs CommandSender to send message to
* @param message Custom message to send
*/
public static void dispNoPerms(CommandSender cs, String message) {
cs.sendMessage(message);
RoyalCommands.getInstance().getLogger().warning(cs.getName() + " was denied access to that!");
}
public static void dispNoPerms(CommandSender cs, String... permissionsNeeded) {
final List<FancyMessage> tooltip = new ArrayList<>();
tooltip.add(new FancyMessage("Missing permissions").color(MessageColor.NEGATIVE._()).style(ChatColor.BOLD, ChatColor.UNDERLINE));
for (final String missingPermission : permissionsNeeded)
tooltip.add(new FancyMessage(missingPermission).color(MessageColor.NEUTRAL._()));
// @formatter:off
new FancyMessage("You don't have permission for that!")
.color(MessageColor.NEGATIVE._())
.formattedTooltip(tooltip)
.send(cs);
// @formatter:on
RoyalCommands.getInstance().getLogger().warning(cs.getName() + " was denied access to that!");
}
private static void executeBanActions(OfflinePlayer banned, CommandSender banner, String reason) {
if (!RoyalCommands.getInstance().getConfig().getKeys(false).contains("on_ban"))
return; // default values are not welcome here
final List<String> banActions = Config.onBanActions;
if (banActions == null || banActions.isEmpty()) return;
for (String command : banActions) {
if (command.trim().isEmpty()) continue;
boolean fromConsole = command.startsWith("@");
if (fromConsole) command = command.substring(1);
command = command.replace("{name}", banned.getName());
command = command.replace("{dispname}", (banned.isOnline()) ? ((Player) banned).getDisplayName() : banned.getName());
command = command.replace("{banner}", banner.getName());
command = command.replace("{bannerdispname}", (banner instanceof Player) ? ((Player) banner).getDisplayName() : banner.getName());
command = command.replace("{reason}", reason);
CommandSender sendFrom = (fromConsole) ? Bukkit.getConsoleSender() : banner;
Bukkit.dispatchCommand(sendFrom, command);
}
}
public static String forceGetName(UUID u) {
String name;
try {
name = RUtils.getName(u);
} catch (Exception ex) {
name = u.toString();
}
return name;
}
public static String formatDateDiff(long date) {
Calendar c = new GregorianCalendar();
c.setTimeInMillis(date);
Calendar now = new GregorianCalendar();
return formatDateDiff(now, c);
}
public static String formatDateDiff(Calendar fromDate, Calendar toDate) {
boolean future = false;
if (toDate.equals(fromDate)) return " now";
if (toDate.after(fromDate)) future = true;
StringBuilder sb = new StringBuilder();
int[] types = new int[]{Calendar.YEAR, Calendar.MONTH, Calendar.DAY_OF_MONTH, Calendar.HOUR_OF_DAY, Calendar.MINUTE, Calendar.SECOND};
String[] names = new String[]{"year", "years", "month", "months", "day", "days", "hour", "hours", "minute", "minutes", "second", "seconds"};
for (int i = 0; i < types.length; i++) {
int diff = dateDiff(types[i], fromDate, toDate, future);
if (diff > 0) sb.append(" ").append(diff).append(" ").append(names[i * 2 + (diff > 1 ? 1 : 0)]);
}
if (sb.length() == 0) return " now";
return sb.toString();
}
public static List<String> getAssignment(ItemStack is, GeneralConfiguration gcf) {
return gcf.getStringList(getAssignmentPath(is));
}
public static String getAssignmentPath(ItemStack is) {
return getAssignmentPath(is, Config.assignUseDisplayNames, Config.assignUseDurability);
}
public static String getAssignmentPath(ItemStack is, boolean customNames, boolean durability) {
StringBuilder path = new StringBuilder("assign.");
path.append(is.getType().name());
if (customNames) {
ItemMeta im = is.getItemMeta();
if (im != null) {
String displayName = im.getDisplayName();
if (displayName != null) path.append(".").append(displayName.replace('.', ',')).append(".");
List<String> lore = im.getLore();
if (lore != null && !lore.isEmpty()) {
for (String l : lore) {
path.append(l.replace('.', ','));
path.append(".");
}
}
}
}
if (durability) path.append(is.getDurability()).append(".");
path.append("commands");
return path.toString();
}
/**
* Gets a player backpack
*
* @param u UUID of player to get backpack for
* @return Backpack - never null
* @deprecated Use {@link org.royaldev.royalcommands.wrappers.player.MemoryRPlayer#getBackpack}.
*/
@Deprecated
public static Inventory getBackpack(UUID u, World w) {
PlayerConfiguration pcm = PlayerConfigurationManager.getConfiguration(u);
String worldGroup = WorldManager.il.getWorldGroup(w);
if (worldGroup == null) worldGroup = "w-" + w.getName();
if (!pcm.exists()) pcm.createFile();
int invSize = pcm.getInt("backpack." + worldGroup + ".size", -1);
if (invSize < 9) invSize = 36;
if (invSize % 9 != 0) invSize = 36;
final Inventory i = Bukkit.createInventory(new BackpackListener.BackpackHolder(u, w), invSize, "Backpack");
if (!pcm.isSet("backpack." + worldGroup + ".item")) return i;
for (int slot = 0; slot < invSize; slot++) {
ItemStack is = pcm.getItemStack("backpack." + worldGroup + ".item." + slot);
if (is == null) continue;
i.setItem(slot, is);
}
return i;
}
/**
* Gets a player backpack
*
* @param p Player to get backpack for
* @return Backpack - never null
* @deprecated Use {@link org.royaldev.royalcommands.wrappers.player.MemoryRPlayer#getBackpack}.
*/
@Deprecated
public static Inventory getBackpack(Player p) {
return getBackpack(p.getUniqueId(), p.getWorld());
}
public static Command getCommand(String name) {
try {
final Field map = RoyalCommands.getInstance().getServer().getPluginManager().getClass().getDeclaredField("commandMap");
map.setAccessible(true);
final CommandMap cm = (CommandMap) map.get(RoyalCommands.getInstance().getServer().getPluginManager());
return cm.getCommand(name);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* @deprecated Use {@link org.royaldev.royalcommands.wrappers.player.MemoryRPlayer#getHomes}.size()
*/
@Deprecated
public static int getCurrentHomes(Player p) {
return getCurrentHomes(p.getUniqueId());
}
/**
* @deprecated Use {@link org.royaldev.royalcommands.wrappers.player.MemoryRPlayer#getHomes}.size()
*/
@Deprecated
public static int getCurrentHomes(UUID u) {
ConfigurationSection pconf = PlayerConfigurationManager.getConfiguration(u).getConfigurationSection("home");
if (pconf == null) return 0;
return pconf.getValues(false).size();
}
/**
* Returns the Double from a String
*
* @param number String to get double from
* @return Double or null if string was not a valid double
*/
public static Double getDouble(String number) {
try {
return Double.valueOf(number);
} catch (Exception e) {
return null;
}
}
/**
* Gets an empty inventory with a backpack configuration.
*
* @return Backpack
*/
public static Inventory getEmptyBackpack() {
return Bukkit.createInventory(null, 36, "Backpack");
}
/**
* Gets enchantments from form "name:level,..." (e.g. "damage_all:2,durability:1")
*
* @param enchant String of enchantment
* @return Map of Enchantments and their levels or null if invalid
*/
public static Map<Enchantment, Integer> getEnchantments(String enchant) {
final Map<Enchantment, Integer> enchants = new HashMap<>();
for (String enc : enchant.split(",")) {
enc = enc.replace(" ", "");
String[] data = enc.split(":");
if (data.length < 2) return null;
String name = data[0];
int lvl;
try {
lvl = Integer.parseInt(data[1]);
} catch (NumberFormatException e) {
continue;
}
Enchantment e = Enchantment.getByName(name.toUpperCase());
if (e == null) continue;
enchants.put(e, lvl);
}
return enchants;
}
public static String getFriendlyEnumName(Enum e) {
return e.name().toLowerCase().replace("_", " ");
}
/**
* @deprecated Use {@link org.royaldev.royalcommands.wrappers.player.MemoryRPlayer#getHomeLimit}
*/
@Deprecated
public static int getHomeLimit(Player p) {
String name = p.getName();
String group;
if (RoyalCommands.getInstance().vh.usingVault()) {
try {
group = RoyalCommands.getInstance().vh.getPermission().getPrimaryGroup(p);
} catch (Exception e) {
group = "";
}
} else group = "";
if (group == null) group = "";
int limit;
final FileConfiguration c = RoyalCommands.getInstance().getConfig();
if (c.isSet("homes.limits.players." + name)) limit = c.getInt("homes.limits.players." + name, -1);
else limit = c.getInt("homes.limits.groups." + group, -1);
return limit;
}
/**
* Gets the message shown to other players on the server when someone is disconnected (kicked).
*
* @param format Format of the message
* @param reason Reason for disconnect
* @param kicked Person disconnected
* @param kicker Person who caused disconnect
* @return Formatted string
*/
public static String getInGameMessage(final String format, final String reason, final OfflinePlayer kicked, final CommandSender kicker) {
if (reason == null || kicked == null || kicker == null) return null;
String message = format;
message = colorize(message);
if (kicked.isOnline()) message = message.replace("{kdispname}", ((Player) kicked).getDisplayName());
else message = message.replace("{kdispname}", kicked.getName());
message = message.replace("{kname}", kicked.getName());
message = message.replace("{name}", kicker.getName());
if (kicker instanceof Player) message = message.replace("{dispname}", ((Player) kicker).getDisplayName());
else message = message.replace("{dispname}", kicker.getName());
message = message.replace("{reason}", reason);
return message;
}
/**
* Returns the Integer from a String
*
* @param number String to get int from
* @return Integer or null if string was not a valid integer
*/
public static Integer getInt(String number) {
try {
return Integer.valueOf(number);
} catch (Exception e) {
return null;
}
}
/**
* Returns the ItemStack for any material name and amount.
* If amount is null, will be default stack size.
* <p/>
* name can contain a ":" to specify data
*
* @param name Name of the material
* @param amount Amount of items or null for default
* @return ItemStack or null if no such material
*/
public static ItemStack getItem(String name, Integer amount) {
if (name == null) return null;
Short data;
String datas = null;
name = name.trim().toUpperCase();
if (name.contains(":")) {
if (name.split(":").length < 2) {
datas = null;
name = name.split(":")[0];
} else {
datas = name.split(":")[1];
name = name.split(":")[0];
}
}
try {
data = Short.valueOf(datas);
} catch (Exception e) {
if (datas != null) return null;
else data = null;
}
Material mat = Material.getMaterial(name);
if (mat == null) return null;
if (amount == null) amount = Config.defaultStack;
ItemStack stack = new ItemStack(mat, amount);
if (data != null) stack.setDurability(data);
return stack;
}
/**
* Gets an ItemStack from an alias and an amount.
*
* @param alias Alias of the item name
* @param amount Amount of the item to be in the stack
* @return ItemStack
* @throws InvalidItemNameException If item alias is not valid
* @throws NullPointerException If ItemNameManager is not loaded
*/
public static ItemStack getItemFromAlias(String alias, int amount) throws InvalidItemNameException, NullPointerException {
ItemStack is;
if (RoyalCommands.inm == null) throw new NullPointerException("ItemNameManager is not loaded!");
is = RoyalCommands.inm.getItemStackFromAlias(alias);
if (is == null) throw new InvalidItemNameException(alias + " is not a valid alias!");
is.setAmount(amount);
return is;
}
/**
* Returns formatted name of an ItemStack.
*
* @param is ItemStack to get name for
* @return Name of item (formatted)
*/
public static String getItemName(ItemStack is) {
return getItemName(is.getType());
}
/**
* Returns formatted name of a Material
*
* @param m Material to get name for
* @return Name of item (formatted)
*/
public static String getItemName(Material m) {
return m.name().toLowerCase().replace("_", " ");
}
public static String getMVWorldName(World w) {
if (w == null) throw new NullPointerException("w can't be null!");
if (!Config.multiverseNames || RoyalCommands.mvc == null)
return RoyalCommands.wm.getConfig().getString("worlds." + w.getName() + ".displayname", w.getName());
return RoyalCommands.mvc.getMVWorldManager().getMVWorld(w).getColoredWorldString();
}
/**
* Gets the message shown to a player on disconnect.
*
* @param message Format of the message
* @param reason Reason for disconnect.
* @param kicker Person who caused disconnect.
* @return Formatted string
*/
public static String getMessage(final String message, final String reason, final CommandSender kicker) {
String format = message;
format = colorize(format);
if (kicker instanceof Player) format = format.replace("{dispname}", ((Player) kicker).getDisplayName());
else format = format.replace("{dispname}", kicker.getName());
format = format.replace("{name}", kicker.getName());
format = format.replace("{reason}", reason);
return format;
}
public static String getMessage(final String message, final String reason, final String kicker) {
String format = message;
format = colorize(format);
format = format.replace("{dispname}", kicker);
format = format.replace("{name}", kicker);
format = format.replace("{reason}", reason);
return format;
}
public static String getName(UUID u) throws Exception {
return new NameFetcher(Arrays.asList(u)).call().get(u);
}
/**
* Gets an OfflinePlayer with support for name completion. If no Player is on that matches the beginning of the
* name, the string provided will be used to get an OfflinePlayer to return. If there is a Player, it will be cast
* to OfflinePlayer and returned.
*
* @param name Name of player
* @return OfflinePlayer
*/
@SuppressWarnings("deprecation")
public static OfflinePlayer getOfflinePlayer(String name) {
OfflinePlayer op = RoyalCommands.getInstance().getServer().getPlayerExact(name);
if (op == null) op = RoyalCommands.getInstance().getServer().getPlayer(name);
if (op == null) op = RoyalCommands.getInstance().getServer().getOfflinePlayer(name);
return op;
}
public static List<FancyMessage> getPlayerTooltip(final Object o) {
final List<FancyMessage> tooltip = new ArrayList<>();
final VaultHandler vh = RoyalCommands.getInstance().vh;
if (o instanceof OfflinePlayer) {
final OfflinePlayer op = (OfflinePlayer) o;
if (tooltip.size() < 1)
tooltip.add(new FancyMessage("Offline Player").color(MessageColor.NEUTRAL._()).style(ChatColor.BOLD, ChatColor.UNDERLINE));
tooltip.add(new FancyMessage("Name: ").color(MessageColor.POSITIVE._()).style(ChatColor.BOLD).then(op.getName()).color(MessageColor.NEUTRAL._()));
tooltip.add(new FancyMessage("Operator: ").color(MessageColor.POSITIVE._()).style(ChatColor.BOLD).then(op.isOp() ? "Yes" : "No").color(MessageColor.NEUTRAL._()));
if (vh.usingVault() && vh.getPermission().hasGroupSupport()) {
final String group = vh.getPermission().getPrimaryGroup(null, op);
final Chat c = vh.getChat();
String prefix = c == null ? null : c.getGroupPrefix((String) null, group);
if (prefix == null || prefix.isEmpty()) prefix = c == null ? null : c.getPlayerPrefix(null, op);
if (prefix == null) prefix = "";
String suffix = c == null ? null : c.getGroupSuffix((String) null, group);
if (suffix == null || suffix.isEmpty()) suffix = c == null ? null : c.getPlayerSuffix(null, op);
if (suffix == null) suffix = "";
// TODO: Config format
if (!group.isEmpty()) {
tooltip.add(new FancyMessage("Group: ").color(MessageColor.POSITIVE._()).style(ChatColor.BOLD).then(ChatColor.translateAlternateColorCodes('&', prefix)).color(MessageColor.NEUTRAL._()).then(group).then(ChatColor.translateAlternateColorCodes('&', suffix)));
}
}
}
if (o instanceof Player) {
final Player p = (Player) o;
if (tooltip.size() > 0) { // Replace Offline Player with Player
tooltip.remove(0);
tooltip.add(0, new FancyMessage("Player").color(MessageColor.NEUTRAL._()).style(ChatColor.BOLD, ChatColor.UNDERLINE));
}
}
if (o instanceof ConsoleCommandSender) {
if (tooltip.size() < 1) {
tooltip.add(new FancyMessage("Console").color(MessageColor.NEUTRAL._()).style(ChatColor.BOLD, ChatColor.UNDERLINE));
}
}
return tooltip.isEmpty() ? null : tooltip;
}
public static Object getPrivateField(Object object, String field) throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
Class<?> clazz = object.getClass();
Field objectField = clazz.getDeclaredField(field);
final boolean wasAccessible = objectField.isAccessible();
objectField.setAccessible(true);
Object result = objectField.get(object);
objectField.setAccessible(wasAccessible);
return result;
}
public static String getRChatGroupPrefix(final String s) {
try {
Class.forName("org.royaldev.royalchat.DataManager");
} catch (ClassNotFoundException e) {
return null;
}
RoyalChat rc = (RoyalChat) Bukkit.getPluginManager().getPlugin("RoyalChat");
String prefix = rc.dm.getGroupPrefix(s);
if (prefix.isEmpty()) prefix = null;
return prefix;
}
public static String getRChatGroupSuffix(final String s) {
try {
Class.forName("org.royaldev.royalchat.DataManager");
} catch (ClassNotFoundException e) {
return null;
}
RoyalChat rc = (RoyalChat) Bukkit.getPluginManager().getPlugin("RoyalChat");
String suffix = rc.dm.getGroupSuffix(s);
if (suffix.isEmpty()) suffix = null;
return suffix;
}
public static String getRChatPrefix(final Player p) {
try {
Class.forName("org.royaldev.royalchat.DataManager");
} catch (ClassNotFoundException e) {
return null;
}
RoyalChat rc = (RoyalChat) Bukkit.getPluginManager().getPlugin("RoyalChat");
String prefix = rc.dm.getPrefix(p);
if (prefix.isEmpty()) prefix = null;
return prefix;
}
public static String getRChatSuffix(final Player p) {
try {
Class.forName("org.royaldev.royalchat.DataManager");
} catch (ClassNotFoundException e) {
return null;
}
RoyalChat rc = (RoyalChat) Bukkit.getPluginManager().getPlugin("RoyalChat");
String suffix = rc.dm.getSuffix(p);
if (suffix.isEmpty()) suffix = null;
return suffix;
}
/**
* Returns a location that is always above ground.
* If there is no ground under the location, returns
* null.
*
* @param l Location to find safe location for
* @return Safe location or null if no ground
*/
public static Location getSafeLocation(Location l) {
int unsafeY = l.getBlockY();
if (unsafeY < 0) return null;
for (int i = unsafeY; i >= 0; i--) {
if (i < 0) return null;
Block b = l.getWorld().getBlockAt(l.getBlockX(), i, l.getBlockZ());
if (b == null) return null;
if (b.getType() == Material.AIR) continue;
double safeY = l.getY() - (unsafeY - i);
return new Location(l.getWorld(), l.getX(), safeY + 1, l.getZ(), l.getYaw(), l.getPitch());
}
return null;
}
/**
* Returns a location that is always above ground.
* If there is no ground under the location, returns
* null.
*
* @param e Entity to derive location from
* @return Safe location or null if no ground
*/
public static Location getSafeLocation(Entity e) {
if (e == null) return null;
return getSafeLocation(e.getLocation());
}
/**
* Gets the block the player is looking at
*
* @param p Player to get block from
* @return Block player is looking at
*/
@SuppressWarnings("deprecation")
public static Block getTarget(Player p) {
return p.getTargetBlock((Set<Material>) null, 300); // waiting on method for Materials
}
/**
* Gets a timestamp from a player's userdata file.
*
* @param p OfflinePlayer to get timestamp from
* @param title Path of timestamp
* @return timestamp or -1 if there was no such timestamp
*/
public static long getTimeStamp(OfflinePlayer p, String title) {
PlayerConfiguration pcm = PlayerConfigurationManager.getConfiguration(p);
if (pcm.get(title) == null) return -1;
return pcm.getLong(title);
}
public static UUID getUUID(String name) throws Exception {
final Map<String, UUID> m = new UUIDFetcher(Arrays.asList(name)).call();
for (Map.Entry<String, UUID> e : m.entrySet()) if (e.getKey().equalsIgnoreCase(name)) return e.getValue();
throw new Exception("Couldn't find name in results.");
}
@Deprecated
public static Entity getVehicleToTeleport(final Entity rider) {
if (!Config.vehicleTeleportEnabled) return null;
final Entity vehicle = rider.getVehicle();
if (vehicle == null) return null;
if (Config.vehicleTeleportVehicles && vehicle instanceof Vehicle) return vehicle;
if (Config.vehicleTeleportAnimals && vehicle instanceof Animals) return vehicle;
if (Config.vehicleTeleportPlayers && vehicle instanceof Player) return vehicle;
return null;
}
/**
* Gets a world via its real name, Multiverse name, or WorldManager name.
*
* @param name Name of world to get
* @return World or null if none exists
*/
public static World getWorld(String name) {
World w;
w = Bukkit.getWorld(name);
if (w != null) return w;
if (RoyalCommands.mvc != null) {
MultiverseWorld mvw = RoyalCommands.mvc.getMVWorldManager().getMVWorld(name);
w = (mvw == null) ? null : mvw.getCBWorld();
if (w != null) return w;
}
w = RoyalCommands.wm.getWorld(name);
return w;
}
public static boolean isBanned(final Player p) {
final PlayerConfiguration pcm = PlayerConfigurationManager.getConfiguration(p);
if (pcm.isSet("bantime")) {
if (RUtils.isTimeStampValid(p, "bantime")) return true;
else {
pcm.set("bantime", null);
RUtils.unbanPlayer(p);
return false;
}
}
return p.isBanned();
}
public static boolean isIPBanned(Player p) {
return Bukkit.getIPBans().contains(p.getAddress().getAddress().toString().replace("/", ""));
}
public static boolean isIPBanned(String ip) {
return Bukkit.getIPBans().contains(ip);
}
private static boolean isInt(String s) {
Integer i;
try {
i = Integer.parseInt(s);
} catch (NumberFormatException e) {
i = null;
}
return i != null;
}
private static boolean isInt(char c) {
Integer i;
try {
i = Integer.parseInt(String.valueOf(c));
} catch (NumberFormatException e) {
i = null;
}
return i != null;
}
/**
* Checks to see if teleport is allowed for the specified OfflinePlayer
*
* @param p OfflinePlayer to check teleportation status on
* @return true or false
*/
public static boolean isTeleportAllowed(OfflinePlayer p) {
return PlayerConfigurationManager.getConfiguration(p).getBoolean("allow_tp", true);
}
/**
* Checks to see if the timestamp is greater than the current time.
*
* @param p OfflinePlayer to check for
* @param title Path of timestamp to check
* @return true if the timestamp has not been passed, false if otherwise
*/
public static boolean isTimeStampValid(OfflinePlayer p, String title) {
PlayerConfiguration pcm = PlayerConfigurationManager.getConfiguration(p);
if (!pcm.isSet(title)) return false;
long time = System.currentTimeMillis();
long overall = pcm.getLong(title);
return time < overall;
}
public static boolean isTimeStampValidAddTime(OfflinePlayer p, String timestamp, String timeset) {
PlayerConfiguration pcm = PlayerConfigurationManager.getConfiguration(p);
if (pcm.get(timestamp) == null || pcm.get(timeset) == null) return false;
long time = new Date().getTime();
long overall = (pcm.getLong(timestamp) * 1000L) + pcm.getLong(timeset);
return time < overall;
}
public static String join(Iterable<String> i, String between) {
String ret = "";
for (String s : i) ret = ("".equals(ret)) ? ret.concat(s) : ret.concat(between + s);
return ret;
}
public static String join(String[] i, String between) {
String ret = "";
for (String s : i) ret = ("".equals(ret)) ? ret.concat(s) : ret.concat(between + s);
return ret;
}
public static String join(Object[] i, String between) {
String ret = "";
for (Object o : i)
ret = ("".equals(ret)) ? ret.concat(o.toString().toLowerCase()) : ret.concat(between + o.toString().toLowerCase());
return ret;
}
/**
* Kicks a player and sets the last kick for history writing.
*
* @param kicked Player to kick
* @param reason Reason for kick
*/
public static void kickPlayer(final Player kicked, final CommandSender kicker, final String reason) {
final PlayerConfiguration pcm = PlayerConfigurationManager.getConfiguration(kicked);
pcm.set("last_kick.kicker", (kicker == null) ? "Unknown" : kicker.getName());
pcm.set("last_kick.reason", decolorize(reason));
pcm.set("last_kick.timestamp", System.currentTimeMillis());
kicked.kickPlayer(RUtils.getMessage(Config.kickFormat, reason, kicker));
}
/**
* Lists files in a directory.
*
* @param f Directory to list files in
* @param recursive Recursively list files?
* @return List of files - never null
*/
public static List<File> listFiles(File f, boolean recursive) {
List<File> fs = new ArrayList<>();
if (!f.isDirectory()) return fs;
File[] listed = f.listFiles();
if (listed == null) return fs;
for (File in : listed) {
if (in.isDirectory()) {
if (!recursive) continue;
fs.addAll(listFiles(in, true));
continue;
}
fs.add(in);
}
return fs;
}
/**
* Makes a scheduled Bukkit task for watching a player when he's warming up for teleport.
*
* @param p Player to teleport when warmup is finished
* @param t Location to teleport to when warmup is finished
* @return ID of Bukkit task
*/
private static int makeTeleportRunner(final Player p, final Location t) {
synchronized (teleRunners) {
if (teleRunners.containsKey(p.getName())) cancelTeleportRunner(p);
}
p.sendMessage(MessageColor.POSITIVE + "Please wait " + MessageColor.NEUTRAL + Config.teleportWarmup + MessageColor.POSITIVE + " seconds for your teleport.");
final PlayerConfiguration pcm = PlayerConfigurationManager.getConfiguration(p);
pcm.set("teleport_warmup", new Date().getTime());
final Runnable r = new Runnable() {
@Override
public void run() {
long l = pcm.getLong("teleport_warmup", -1);
if (l < 0) {
cancelTeleportRunner(p);
return;
}
int toAdd = Config.teleportWarmup * 1000;
l = l + toAdd;
long c = new Date().getTime();
if (l < c) {
p.sendMessage(MessageColor.POSITIVE + "Teleporting...");
teleAllowed.add(p.getName());
String error = teleport(p, t);
teleAllowed.remove(p.getName());
if (!error.isEmpty()) p.sendMessage(MessageColor.NEGATIVE + error);
cancelTeleportRunner(p);
}
}
};
int id = Bukkit.getScheduler().scheduleSyncRepeatingTask(RoyalCommands.getInstance(), r, 0, 10);
synchronized (teleRunners) {
teleRunners.put(p.getName(), id);
}
return id;
}
/**
* Makes a scheduled Bukkit task for watching a player when he's warming up for teleport.
*
* @param p Player to teleport when warmup is finished
* @param t Entity to teleport to when warmup is finished
* @return ID of Bukkit task
*/
private static int makeTeleportRunner(final Player p, final Entity t) {
return makeTeleportRunner(p, t.getLocation());
}
public static boolean nearEqual(double a, double b, double margin) {
return Math.abs(a - b) < margin;
}
public static boolean nearEqual(double a, double b) {
return nearEqual(a, b, .05D);
}
/**
* Plays the configured teleport sound at a location.
*
* @param at Location to play sound at
*/
public static void playTeleportSound(Location at) {
if (at == null) throw new IllegalArgumentException("Location cannot be null!");
if (!Config.teleportSoundEnabled) return;
Sound toPlay;
try {
toPlay = Sound.valueOf(Config.teleportSoundName);
} catch (IllegalArgumentException e) {
RoyalCommands.getInstance().getLogger().warning("A teleport sound was attempted, but teleport_sound.name was not a valid sound name!");
return;
}
at.getWorld().playSound(at, toPlay, Config.teleportSoundVolume, Config.teleportSoundPitch);
}
public static void removeAssignment(ItemStack is, GeneralConfiguration gcf) {
setAssignment(is, null, gcf);
}
/**
* Renames an ItemStack.
*
* @param is ItemStack to rename
* @param newName Name to give ItemStack
* @return ItemStack with new name
*/
public static ItemStack renameItem(ItemStack is, String newName) {
if (is == null) throw new IllegalArgumentException("ItemStack cannot be null!");
if (newName == null) return is;
ItemMeta im = is.getItemMeta();
im.setDisplayName(newName);
is.setItemMeta(im);
return is;
}
public static String replaceVars(final String orig, final Player p) {
String repld = orig;
repld = repld.replace("{name}", p.getName()).replace("{dispname}", p.getDisplayName()).replace("{world}", getMVWorldName(p.getWorld()));
if (!RoyalCommands.getInstance().vh.usingVault()) return repld;
try {
repld = repld.replace("{group}", RoyalCommands.getInstance().vh.getPermission().getPrimaryGroup(p));
} catch (Exception ignored) {
}
try {
repld = repld.replace("{prefix}", RoyalCommands.getInstance().vh.getChat().getPlayerPrefix(p));
} catch (Exception ignored) {
String prefix = getRChatPrefix(p);
if (prefix != null) repld = repld.replace("{prefix}", prefix);
}
try {
repld = repld.replace("{suffix}", RoyalCommands.getInstance().vh.getChat().getPlayerSuffix(p));
} catch (Exception ignored) {
String suffix = getRChatSuffix(p);
if (suffix != null) repld = repld.replace("{suffix}", suffix);
}
return repld;
}
/**
* Saves player backpacks in a forwards-compatible method, using native Bukkit methods.
*
* @param p Player to save backpack for
* @param i Inventory to save as backpack
*/
public static void saveBackpack(Player p, Inventory i) {
saveBackpack(p.getUniqueId(), p.getWorld(), i);
}
/**
* Saves player backpacks in a forwards-compatible method, using native Bukkit methods.
*
* @param u UUID of player to save backpack for
* @param i Inventory to save as backpack
*/
public static void saveBackpack(UUID u, World w, Inventory i) {
final PlayerConfiguration pcm = PlayerConfigurationManager.getConfiguration(u);
if (w == null) return;
String worldGroup = WorldManager.il.getWorldGroup(w);
if (worldGroup == null) worldGroup = "w-" + w.getName();
for (int slot = 0; slot < i.getSize(); slot++)
pcm.set("backpack." + worldGroup + ".item." + slot, i.getItem(slot));
pcm.set("backpack." + worldGroup + ".size", i.getSize());
}
/**
* Schedules a player kick via the Bukkit scheduler. Will run as soon as a spot frees for the event.
*
* @param p Player to kick
* @param reason Reason for kick
* @throws IllegalArgumentException If p or reason is null
* @throws NullPointerException If method could not get the RoyalCommands plugin to schedule with via Bukkit
*/
public static void scheduleKick(final Player p, final String reason) throws IllegalArgumentException, NullPointerException {
if (p == null) throw new IllegalArgumentException("Player cannot be null!");
if (reason == null) throw new IllegalArgumentException("Reason cannot be null!");
Runnable r = new Runnable() {
@Override
public void run() {
p.kickPlayer(reason);
}
};
Plugin plugin = RoyalCommands.getInstance();
if (plugin == null) throw new NullPointerException("Could not get the RoyalCommands plugin.");
RoyalCommands.getInstance().getServer().getScheduler().scheduleSyncDelayedTask(plugin, r);
}
public static void setAssignment(ItemStack is, List<String> commands, GeneralConfiguration gcf) {
if (is == null) return;
gcf.set(getAssignmentPath(is), commands);
}
public static void setFields(Object o, String[] fields, Object... values) throws ReflectiveOperationException {
try {
for (int index = 0; index < fields.length; index++) {
final String field = fields[index];
final Field f = o.getClass().getDeclaredField(field);
f.setAccessible(true);
f.set(o, values[index]);
}
} catch (ReflectiveOperationException ex) {
ex.printStackTrace();
}
}
/**
* Sets the holder of an Inventory
*
* @param i Inventory to set holder of
* @param ih InventoryHolder to be set
* @return New inventory with updated holder
*/
public static Inventory setHolder(Inventory i, InventoryHolder ih) {
Inventory ii = createInv(ih, i.getSize(), i.getName());
ii.setContents(i.getContents());
return ii;
}
public static ItemStack setItemStackSpawned(ItemStack stack, String spawner, boolean spawned) {
final SpawnInfo si = SpawnInfo.SpawnInfoManager.getSpawnInfo(stack);
si.setSpawner(spawner);
si.setSpawned(spawned);
return SpawnInfo.SpawnInfoManager.applySpawnInfo(stack, si);
}
/**
* Sets a timestamp in a player's userdata file
*
* @param p OfflinePlayer to set the timestamp on
* @param seconds Seconds relative to the current time for timestamp
* @param title Path to timestamp
*/
public static void setTimeStamp(OfflinePlayer p, long seconds, String title) {
PlayerConfiguration pcm = PlayerConfigurationManager.getConfiguration(p);
pcm.set(title, (seconds * 1000) + new Date().getTime());
}
/**
* Shows a temporary empty chest to the player
*
* @param player Player to show chest to
*/
public static void showEmptyChest(Player player) {
player.openInventory(Bukkit.createInventory(null, InventoryType.CHEST));
}
/**
* Shows a temporary empty chest to the player
*
* @param p Player to show chest to
* @param name Name of chest
*/
public static void showEmptyChest(Player p, String name) {
p.openInventory(Bukkit.createInventory(null, InventoryType.CHEST.getDefaultSize(), name));
}
/**
* Shows a chest filled of an item to player
*
* @param p Player to show chest to
* @param name Name of item to fill chest with
*/
public static void showFilledChest(Player p, String name) {
Inventory inv = Bukkit.createInventory(null, InventoryType.CHEST);
ItemStack stack = getItem(name, 64);
for (int i = 0; i < inv.getSize(); i++) inv.addItem(stack);
p.openInventory(inv);
}
public static void silentKick(final Player t, final String reason) {
t.kickPlayer(reason + "\00-silent");
}
/**
* Teleports a player without registering it in /back.
*
* @param p Player to teleport
* @param l Location to teleport to
* @return Error message if any.
*/
@Deprecated
public static String silentTeleport(Player p, Location l) {
synchronized (teleRunners) {
if (Config.teleportWarmup > 0 && !teleRunners.containsKey(p.getName()) && !RoyalCommands.getInstance().ah.isAuthorized(p, "rcmds.exempt.teleportwarmup")) {
makeTeleportRunner(p, l);
return "";
} else if (Config.teleportWarmup > 0 && teleRunners.containsKey(p.getName()) && !teleAllowed.contains(p.getName())) {
return "";
}
}
final Location toTele = (Config.safeTeleport) ? getSafeLocation(l) : l;
if (toTele == null) return "There is no ground below.";
final Chunk c = toTele.getChunk();
if (!c.isLoaded()) c.load(true);
final Entity vehicle = getVehicleToTeleport(p);
if (vehicle != null) {
return teleportWithVehicle(toTele, p, vehicle, false);
} else {
p.setVelocity(new Vector(0, 0, 0));
p.setFallDistance(0F);
p.teleport(toTele);
//playTeleportSound(toTele); Silent
return "";
}
}
/**
* Teleports a player without registering it in /back.
*
* @param p Player to teleport
* @param e Entity to teleport to
* @return Error message if any.
*/
@Deprecated
public static String silentTeleport(Player p, Entity e) {
if (e == null) return "Entity was null";
return silentTeleport(p, e.getLocation());
}
/**
* Teleports a player and registers it in /back.
*
* @param p Player to teleport
* @param l Location to teleport to
* @return Error message if any.
* @deprecated Use {@link org.royaldev.royalcommands.wrappers.player.MemoryRPlayer#getTeleporter}.
*/
@Deprecated
public static String teleport(Player p, Location l) {
synchronized (teleRunners) {
if (Config.teleportWarmup > 0 && !teleRunners.containsKey(p.getName()) && !RoyalCommands.getInstance().ah.isAuthorized(p, "rcmds.exempt.teleportwarmup")) {
makeTeleportRunner(p, l);
return "";
} else if (Config.teleportWarmup > 0 && teleRunners.containsKey(p.getName()) && !teleAllowed.contains(p.getName())) {
return "";
}
}
final Location toTele = (Config.safeTeleport) ? getSafeLocation(l) : l;
if (toTele == null) return "There is no ground below.";
final Chunk c = toTele.getChunk();
if (!c.isLoaded()) c.load(true);
final Entity vehicle = getVehicleToTeleport(p);
if (vehicle != null) {
return teleportWithVehicle(toTele, p, vehicle);
} else {
CmdBack.addBackLocation(p, p.getLocation());
p.setVelocity(new Vector(0, 0, 0));
p.setFallDistance(0F);
p.teleport(toTele);
playTeleportSound(toTele);
return "";
}
}
/**
* Teleports a player and registers it in /back.
*
* @param p Player to teleport
* @param e Entity to teleport to
* @return Error message if any.
*/
@Deprecated
public static String teleport(Player p, Entity e) {
if (e == null) return "Entity was null";
return teleport(p, e.getLocation());
}
@Deprecated
private static String teleportWithVehicle(Location l, Entity passenger, Entity vehicle) {
return teleportWithVehicle(l, passenger, vehicle, false);
}
@Deprecated
private static String teleportWithVehicle(Location l, Entity passenger, Entity vehicle, boolean silent) {
if (!Config.vehicleCrossWorldTeleport && !l.getWorld().getName().equals(vehicle.getWorld().getName()))
return "Passenger on vehicle cannot teleport to a different world!";
vehicle.eject();
if (!silent && passenger instanceof Player) {
final Player p = (Player) passenger;
CmdBack.addBackLocation(p, p.getLocation());
}
passenger.setVelocity(new Vector(0, 0, 0));
passenger.setFallDistance(0F);
passenger.teleport(l);
vehicle.setVelocity(new Vector(0, 0, 0));
vehicle.setFallDistance(0F);
vehicle.teleport(l);
vehicle.setPassenger(passenger);
return "";
}
/**
* Returns the amount of seconds from a string like "6y5d4h3m2s"
*
* @param format String like "5y4d3h2m1s"
* @return -1 if no numbers or incorrect format, the number provided if no letters, and the seconds if correct format
*/
public static int timeFormatToSeconds(String format) {
format = format.toLowerCase();
if (!format.contains("y") && !format.contains("d") && !format.contains("h") && !format.contains("m") && !format.contains("s")) {
if (isInt(format)) return Integer.valueOf(format);
return -1;
}
String nums = "";
int num;
int seconds = 0;
for (int i = 0; i < format.length(); i++) {
char c = format.charAt(i);
if (isInt(c)) {
nums += c;
continue;
}
if (nums.isEmpty()) return -1; // this will happen if someone enters 5dd3h, etc. (invalid format)
switch (c) {
case 'y':
num = Integer.valueOf(nums);
seconds += num * 31556926;
nums = "";
break;
case 'd':
num = Integer.valueOf(nums);
seconds += num * 86400;
nums = "";
break;
case 'h':
num = Integer.valueOf(nums);
seconds += num * 3600;
nums = "";
break;
case 'm':
num = Integer.valueOf(nums);
seconds += num * 60;
nums = "";
break;
case 's':
num = Integer.valueOf(nums);
seconds += num;
nums = "";
break;
default:
return -1;
}
}
return seconds;
}
public static void unbanPlayer(OfflinePlayer t) {
final BanList bl = Bukkit.getBanList(BanList.Type.NAME);
bl.pardon(t.getName());
}
/**
* Wraps text to fit evenly in the chat box
*
* @param text Text to wrap
* @param len Length to wrap at
* @return Array of strings
*/
@SuppressWarnings("unchecked")
public static String[] wrapText(String text, int len) {
// return empty array for null text
if (text == null) return new String[]{};
// return text if len is zero or less
if (len <= 0) return new String[]{text};
// return text if less than length
if (text.length() <= len) return new String[]{text};
char[] chars = text.toCharArray();
java.util.Vector lines = new java.util.Vector();
StringBuilder line = new StringBuilder();
StringBuilder word = new StringBuilder();
for (char aChar : chars) {
word.append(aChar);
if (aChar == ' ') {
if ((line.length() + word.length()) > len) {
lines.add(line.toString());
line.delete(0, line.length());
}
line.append(word);
word.delete(0, word.length());
}
}
// handle any extra chars in current word
if (word.length() > 0) {
if ((line.length() + word.length()) > len) {
lines.add(line.toString());
line.delete(0, line.length());
}
line.append(word);
}
// handle extra line
if (line.length() > 0) lines.add(line.toString());
String[] ret = new String[lines.size()];
int c = 0; // counter
for (Enumeration e = lines.elements(); e.hasMoreElements(); c++) ret[c] = (String) e.nextElement();
return ret;
}
/**
* Writes a string containing all the vital ban information about a player to a list of previous bans in the
* player's userdata.
*
* @param t Player to write ban history of
*/
public static void writeBanHistory(OfflinePlayer t) {
if (!t.isBanned()) return;
PlayerConfiguration pcm = PlayerConfigurationManager.getConfiguration(t);
if (!pcm.exists()) pcm.createFile();
List<String> prevBans = pcm.getStringList("prevbans");
if (prevBans == null) prevBans = new ArrayList<>();
// banner,banreason,bannedat,istempban
prevBans.add(pcm.getString("banner") + "\u00b5" + pcm.getString("banreason") + "\u00b5" + pcm.getString("bannedat") + "\u00b5" + (pcm.get("bantime") != null));
pcm.set("prevbans", prevBans);
}
}