TF-ProjectKorra/src/com/projectkorra/projectkorra/GeneralMethods.java
Christopher Martin 102112ffdd 1.8.6 (#825)
## Fixes
* Fixed Combos and possibly Passives appearing in `/pk b <Ability>` auto-tabbing.
* Fixed Combos not loading properly on certain servers.
* Fixed issue with `PreciousStones` by updating to the latest version to resolve API change issues.
* Fixed `RapidPunch` damage.
* Fixed incorrect summation of chiblocking chance.
* Fixed possible issue in PKListener#onPlayerInteraction()
* Fixed `Earth.LavaSound`.
* Fixed Chi attempting to chiblock targets with any move.
* Fixed hitting an entity with `TempArmor` not ignoring armor.
* Fixed `Immobilize` config path.

## Additions
* Added "Contributing" section to the `README` to help guide active community members.
* Added more detail to the `PULL_REQUEST_TEMPLATE` to allow for more uniform pull requests. 
* Added many new blocks to our ability block interaction.
* Added check to combo collisions to discard dead entities.
* Added functionality to allow chiblocking abilities to affect all entities.
* Added exception handling to the configurable `Sound` options to prevent `IllegalArgumentExcpetions`.
* Added sounds and `ActionBar` messages to being Bloodbent, Electrocuted, Immobilized, MetalClipped, and Paralyzed. (Abilities: `Bloodbending`, `Lightning`, `Immobilize`, `MetalClips`, and `Paralyze`)
* Added sound and `ActionBar` message for being Chiblocked.
* Added interval config option to `RapidPunch`. (time between each punch)

## API Changes
* Updated to `Spigot 1.12.1`.
    * Confirmed to be backward compatible with `Spigot 1.12` and `Spigot 1.11.2`.
* Renamed `ElementalAbility#getTransparentMaterial()` to `ElementalAbility#getTransparentMaterials()`.
* Converted most `byte`/`int` dependent `Material` logic to use `Material` instead. 
    * `ElementalAbility#getTransparentMaterialSet()` now returns a `HashSet<Material>` instead of a `HashSet<Byte>`.
    * `ElementalAbility#getTransparentMaterials()` and `GeneralMethods.NON_OPAQUE` now return `Material[]` instead of `Integer[]`.
    * `GeneralMethods#getTargetedLocation()` now takes a `varargs Material[]` instead of a `varargs Integer[]`.
* Removed `ElementalAbility.TRANSPARENT_MATERIAL`. It was outdated and became irrelevent after `GeneralMethods.NON_OPAQUE` was updated.
* Removed `Java 7` Travi-CI  JDK check.
* Updated `pom.xml` to build in `Java 8`.
* Added new `MovementHandler` utility class to control entity movement. (currently only capable of stopping movement.
2017-08-06 00:18:12 -07:00

2162 lines
81 KiB
Java

package com.projectkorra.projectkorra;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.BlockState;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.FallingBlock;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.TNTPrimed;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.util.Vector;
import org.kingdoms.constants.StructureType;
import org.kingdoms.constants.kingdom.Kingdom;
import org.kingdoms.constants.land.Land;
import org.kingdoms.constants.land.SimpleChunkLocation;
import org.kingdoms.constants.land.SimpleLocation;
import org.kingdoms.constants.player.KingdomPlayer;
import org.kingdoms.manager.game.GameManagement;
import com.bekvon.bukkit.residence.Residence;
import com.bekvon.bukkit.residence.protection.ClaimedResidence;
import com.bekvon.bukkit.residence.protection.ResidencePermissions;
import com.google.common.reflect.ClassPath;
import com.griefcraft.lwc.LWC;
import com.griefcraft.lwc.LWCPlugin;
import com.griefcraft.model.Protection;
import com.massivecraft.factions.engine.EngineMain;
import com.massivecraft.massivecore.ps.PS;
import com.palmergames.bukkit.towny.Towny;
import com.palmergames.bukkit.towny.TownyMessaging;
import com.palmergames.bukkit.towny.TownySettings;
import com.palmergames.bukkit.towny.object.Coord;
import com.palmergames.bukkit.towny.object.PlayerCache;
import com.palmergames.bukkit.towny.object.PlayerCache.TownBlockStatus;
import com.palmergames.bukkit.towny.object.TownyPermission;
import com.palmergames.bukkit.towny.object.TownyUniverse;
import com.palmergames.bukkit.towny.object.TownyWorld;
import com.palmergames.bukkit.towny.object.WorldCoord;
import com.palmergames.bukkit.towny.utils.PlayerCacheUtil;
import com.palmergames.bukkit.towny.war.flagwar.TownyWar;
import com.palmergames.bukkit.towny.war.flagwar.TownyWarConfig;
import com.projectkorra.projectkorra.Element.SubElement;
import com.projectkorra.projectkorra.ability.Ability;
import com.projectkorra.projectkorra.ability.AddonAbility;
import com.projectkorra.projectkorra.ability.CoreAbility;
import com.projectkorra.projectkorra.ability.EarthAbility;
import com.projectkorra.projectkorra.ability.ElementalAbility;
import com.projectkorra.projectkorra.ability.FireAbility;
import com.projectkorra.projectkorra.ability.WaterAbility;
import com.projectkorra.projectkorra.ability.util.Collision;
import com.projectkorra.projectkorra.ability.util.CollisionInitializer;
import com.projectkorra.projectkorra.ability.util.CollisionManager;
import com.projectkorra.projectkorra.ability.util.ComboManager;
import com.projectkorra.projectkorra.ability.util.ComboManager.AbilityInformation;
import com.projectkorra.projectkorra.ability.util.MultiAbilityManager;
import com.projectkorra.projectkorra.ability.util.PassiveManager;
import com.projectkorra.projectkorra.airbending.AirBlast;
import com.projectkorra.projectkorra.airbending.AirShield;
import com.projectkorra.projectkorra.airbending.AirSpout;
import com.projectkorra.projectkorra.airbending.AirSuction;
import com.projectkorra.projectkorra.airbending.AirSwipe;
import com.projectkorra.projectkorra.chiblocking.AcrobatStance;
import com.projectkorra.projectkorra.chiblocking.WarriorStance;
import com.projectkorra.projectkorra.configuration.ConfigManager;
import com.projectkorra.projectkorra.earthbending.EarthBlast;
import com.projectkorra.projectkorra.earthbending.passive.EarthPassive;
import com.projectkorra.projectkorra.event.BendingPlayerCreationEvent;
import com.projectkorra.projectkorra.event.BendingReloadEvent;
import com.projectkorra.projectkorra.event.BindChangeEvent;
import com.projectkorra.projectkorra.firebending.FireBlast;
import com.projectkorra.projectkorra.firebending.FireShield;
import com.projectkorra.projectkorra.firebending.combustion.Combustion;
import com.projectkorra.projectkorra.object.Preset;
import com.projectkorra.projectkorra.storage.DBConnection;
import com.projectkorra.projectkorra.util.ActionBar;
import com.projectkorra.projectkorra.util.BlockCacheElement;
import com.projectkorra.projectkorra.util.Flight;
import com.projectkorra.projectkorra.util.ParticleEffect;
import com.projectkorra.projectkorra.util.ReflectionHandler;
import com.projectkorra.projectkorra.util.ReflectionHandler.PackageType;
import com.projectkorra.projectkorra.util.TempArmor;
import com.projectkorra.projectkorra.util.TempBlock;
import com.projectkorra.projectkorra.waterbending.WaterManipulation;
import com.projectkorra.projectkorra.waterbending.WaterSpout;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.protection.flags.DefaultFlag;
import me.ryanhamshire.GriefPrevention.Claim;
import me.ryanhamshire.GriefPrevention.GriefPrevention;
import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.chat.ComponentBuilder;
import net.md_5.bungee.api.chat.HoverEvent;
import net.md_5.bungee.api.chat.TextComponent;
import net.sacredlabyrinth.Phaed.PreciousStones.PreciousStones;
import net.sacredlabyrinth.Phaed.PreciousStones.field.FieldFlag;
@SuppressWarnings("deprecation")
public class GeneralMethods {
public static final Material[] NON_OPAQUE = { Material.AIR, Material.SAPLING, Material.WATER, Material.STATIONARY_WATER, Material.LAVA, Material.STATIONARY_LAVA, Material.POWERED_RAIL, Material.DETECTOR_RAIL, Material.WEB, Material.LONG_GRASS, Material.DEAD_BUSH, Material.YELLOW_FLOWER, Material.RED_ROSE, Material.BROWN_MUSHROOM, Material.RED_MUSHROOM, Material.TORCH, Material.FIRE, Material.REDSTONE_WIRE, Material.CROPS, Material.LADDER, Material.RAILS, Material.SIGN_POST, Material.LEVER, Material.STONE_PLATE, Material.WOOD_PLATE, Material.REDSTONE_TORCH_OFF, Material.REDSTONE_TORCH_ON, Material.STONE_BUTTON, Material.SNOW, Material.SUGAR_CANE_BLOCK, Material.PORTAL, Material.DIODE_BLOCK_OFF, Material.DIODE_BLOCK_ON, Material.PUMPKIN_STEM, Material.MELON_STEM, Material.VINE, Material.WATER_LILY, Material.NETHER_WART_BLOCK, Material.ENDER_PORTAL, Material.COCOA, Material.TRIPWIRE_HOOK, Material.TRIPWIRE, Material.FLOWER_POT, Material.CARROT, Material.POTATO, Material.WOOD_BUTTON, Material.GOLD_PLATE, Material.IRON_PLATE, Material.REDSTONE_COMPARATOR_OFF, Material.REDSTONE_COMPARATOR_ON, Material.DAYLIGHT_DETECTOR, Material.CARPET, Material.DOUBLE_PLANT, Material.STANDING_BANNER, Material.WALL_BANNER, Material.DAYLIGHT_DETECTOR_INVERTED,Material.END_ROD, Material.CHORUS_PLANT, Material.CHORUS_FLOWER, Material.BEETROOT_BLOCK, Material.END_GATEWAY };
public static final Material[] INTERACTABLE_MATERIALS = { Material.ACACIA_DOOR, Material.ACACIA_FENCE_GATE, Material.ANVIL, Material.BEACON, Material.BED_BLOCK, Material.BIRCH_DOOR, Material.BIRCH_FENCE_GATE, Material.BOAT, Material.BREWING_STAND, Material.BURNING_FURNACE, Material.CAKE_BLOCK, Material.CHEST, Material.COMMAND, Material.DARK_OAK_DOOR, Material.DARK_OAK_FENCE_GATE, Material.DISPENSER, Material.DRAGON_EGG, Material.DROPPER, Material.ENCHANTMENT_TABLE, Material.ENDER_CHEST, Material.ENDER_PORTAL_FRAME, Material.FENCE_GATE, Material.FURNACE, Material.HOPPER, Material.HOPPER_MINECART, Material.COMMAND_MINECART, Material.JUKEBOX, Material.JUNGLE_DOOR, Material.JUNGLE_FENCE_GATE, Material.LEVER, Material.MINECART, Material.NOTE_BLOCK, Material.SPRUCE_DOOR, Material.SPRUCE_FENCE_GATE, Material.STONE_BUTTON, Material.TRAPPED_CHEST, Material.TRAP_DOOR, Material.WOOD_BUTTON, Material.WOOD_DOOR, Material.WORKBENCH };
// Represents PlayerName, previously checked blocks, and whether they were true or false
private static final Map<String, Map<Block, BlockCacheElement>> BLOCK_CACHE = new ConcurrentHashMap<>();
private static final ArrayList<Ability> INVINCIBLE = new ArrayList<>();
private static ProjectKorra plugin;
private static Method getAbsorption;
private static Method setAbsorption;
public GeneralMethods(ProjectKorra plugin) {
GeneralMethods.plugin = plugin;
try {
getAbsorption = ReflectionHandler.getMethod("EntityHuman", PackageType.MINECRAFT_SERVER, "getAbsorptionHearts");
setAbsorption = ReflectionHandler.getMethod("EntityHuman", PackageType.MINECRAFT_SERVER, "setAbsorptionHearts", Float.class);
}
catch (Exception e) {
e.printStackTrace();
}
}
/**
* Checks to see if an AbilityExists. Uses method
* {@link #getAbility(String)} to check if it exists.
*
* @param string Ability Name
* @return true if ability exists
*/
public static boolean abilityExists(String string) {
return CoreAbility.getAbility(string) != null;
}
/**
* Binds a Ability to the hotbar slot that the player is on.
*
* @param player The player to bind to
* @param ability The ability name to Bind
* @see #bindAbility(Player, String, int)
*/
public static void bindAbility(Player player, String ability) {
int slot = player.getInventory().getHeldItemSlot() + 1;
bindAbility(player, ability, slot);
}
/**
* Binds a Ability to a specific hotbar slot.
*
* @param player The player to bind to
* @param ability
* @param slot
* @see #bindAbility(Player, String)
*/
public static void bindAbility(Player player, String ability, int slot) {
if (MultiAbilityManager.playerAbilities.containsKey(player)) {
GeneralMethods.sendBrandingMessage(player, ChatColor.RED + "You can't edit your binds right now!");
return;
}
BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player.getName());
CoreAbility coreAbil = CoreAbility.getAbility(ability);
if (bPlayer == null) {
return;
}
bPlayer.getAbilities().put(slot, ability);
if (coreAbil != null) {
GeneralMethods.sendBrandingMessage(player, coreAbil.getElement().getColor() + ConfigManager.languageConfig.get().getString("Commands.Bind.SuccessfullyBound").replace("{ability}", ability).replace("{slot}", String.valueOf(slot)));
}
saveAbility(bPlayer, slot, ability);
}
/**
* This method was used for the old collision detection system. Please see
* {@link Collision} for the new system.
* <p>
* Cycles through a list of ability names to check if any instances of the
* abilities exist at a specific location. If an instance of the ability is
* found then it will be removed, with the exception FireShield, and
* AirShield.
*/
@Deprecated
public static boolean blockAbilities(Player player, List<String> abilitiesToBlock, Location loc, double radius) {
boolean hasBlocked = false;
for (String ability : abilitiesToBlock) {
if (ability.equalsIgnoreCase("FireBlast")) {
hasBlocked = FireBlast.annihilateBlasts(loc, radius, player) || hasBlocked;
} else if (ability.equalsIgnoreCase("EarthBlast")) {
hasBlocked = EarthBlast.annihilateBlasts(loc, radius, player) || hasBlocked;
} else if (ability.equalsIgnoreCase("WaterManipulation")) {
hasBlocked = WaterManipulation.annihilateBlasts(loc, radius, player) || hasBlocked;
} else if (ability.equalsIgnoreCase("AirSwipe")) {
hasBlocked = AirSwipe.removeSwipesAroundPoint(loc, radius) || hasBlocked;
} else if (ability.equalsIgnoreCase("AirBlast")) {
hasBlocked = AirBlast.removeAirBlastsAroundPoint(loc, radius) || hasBlocked;
} else if (ability.equalsIgnoreCase("AirSuction")) {
hasBlocked = AirSuction.removeAirSuctionsAroundPoint(loc, radius) || hasBlocked;
} else if (ability.equalsIgnoreCase("Combustion")) {
hasBlocked = Combustion.removeAroundPoint(loc, radius) || hasBlocked;
} else if (ability.equalsIgnoreCase("FireShield")) {
hasBlocked = FireShield.isWithinShield(loc) || hasBlocked;
} else if (ability.equalsIgnoreCase("AirShield")) {
hasBlocked = AirShield.isWithinShield(loc) || hasBlocked;
} else if (ability.equalsIgnoreCase("WaterSpout")) {
hasBlocked = WaterSpout.removeSpouts(loc, radius, player) || hasBlocked;
} else if (ability.equalsIgnoreCase("AirSpout")) {
hasBlocked = AirSpout.removeSpouts(loc, radius, player) || hasBlocked;
} else if (ability.equalsIgnoreCase("Twister")) {
//hasBlocked = AirCombo.removeAroundPoint(player, "Twister", loc, radius) || hasBlocked;
} else if (ability.equalsIgnoreCase("AirStream")) {
//hasBlocked = AirCombo.removeAroundPoint(player, "AirStream", loc, radius) || hasBlocked;
} else if (ability.equalsIgnoreCase("AirSweep")) {
//hasBlocked = AirCombo.removeAroundPoint(player, "AirSweep", loc, radius) || hasBlocked;
} else if (ability.equalsIgnoreCase("FireKick")) {
//hasBlocked = FireCombo.removeAroundPoint(player, "FireKick", loc, radius) || hasBlocked;
} else if (ability.equalsIgnoreCase("FireSpin")) {
//hasBlocked = FireCombo.removeAroundPoint(player, "FireSpin", loc, radius) || hasBlocked;
} else if (ability.equalsIgnoreCase("FireWheel")) {
//hasBlocked = FireCombo.removeAroundPoint(player, "FireWheel", loc, radius) || hasBlocked;
}
}
return hasBlocked;
}
/**
* Breaks a block and sets it to {@link Material#AIR AIR}.
*
* @param block The block to break
*/
public static void breakBlock(Block block) {
block.breakNaturally(new ItemStack(Material.AIR));
}
public static boolean canView(Player player, String ability) {
return player.hasPermission("bending.ability." + ability);
}
/**
* Creates a {@link BendingPlayer} with the data from the database. This
* runs when a player logs in.
*
* @param uuid The UUID of the player
* @param player The player name
* @throws SQLException
*/
public static void createBendingPlayer(final UUID uuid, final String player) {
new BukkitRunnable() {
@Override
public void run() {
createBendingPlayerAsynchronously(uuid, player); // "async"
}
}.runTask(ProjectKorra.plugin);
}
private static void createBendingPlayerAsynchronously(final UUID uuid, final String player) {
ResultSet rs2 = DBConnection.sql.readQuery("SELECT * FROM pk_players WHERE uuid = '" + uuid.toString() + "'");
try {
if (!rs2.next()) { // Data doesn't exist, we want a completely new player.
DBConnection.sql.modifyQuery("INSERT INTO pk_players (uuid, player, slot1, slot2, slot3, slot4, slot5, slot6, slot7, slot8, slot9) VALUES ('" +
uuid.toString() + "', '" + player + "', 'null', 'null', 'null', 'null', 'null', 'null', 'null', 'null', 'null')");
new BendingPlayer(uuid, player, new ArrayList<Element>(), new ArrayList<SubElement>(), new HashMap<Integer, String>(), false);
ProjectKorra.log.info("Created new BendingPlayer for " + player);
} else {
// The player has at least played before.
String player2 = rs2.getString("player");
if (!player.equalsIgnoreCase(player2)) {
DBConnection.sql.modifyQuery("UPDATE pk_players SET player = '" + player + "' WHERE uuid = '" + uuid.toString() + "'");
// They have changed names.
ProjectKorra.log.info("Updating Player Name for " + player);
}
String subelement = rs2.getString("subelement");
String element = rs2.getString("element");
String permaremoved = rs2.getString("permaremoved");
boolean p = false;
final ArrayList<Element> elements = new ArrayList<Element>();
if (element != null && !element.equals("NULL")) {
boolean hasAddon = element.contains(";");
String[] split = element.split(";");
if (split[0] != null) { // Player has an element.
if (split[0].contains("a")) {
elements.add(Element.AIR);
}
if (split[0].contains("w")) {
elements.add(Element.WATER);
}
if (split[0].contains("e")) {
elements.add(Element.EARTH);
}
if (split[0].contains("f")) {
elements.add(Element.FIRE);
}
if (split[0].contains("c")) {
elements.add(Element.CHI);
}
if (hasAddon) {
/*
* Because plugins which depend on ProjectKorra
* would be loaded after ProjectKorra, addon
* elements would = null. To work around this, we
* keep trying to load in the elements from the
* database until it successfully loads everything
* in, or it times out.
*/
final CopyOnWriteArrayList<String> addonClone = new CopyOnWriteArrayList<String>(Arrays.asList(split[split.length - 1].split(",")));
final long startTime = System.currentTimeMillis();
final long timeoutLength = 30000; // How long until it should time out attempting to load addons in
new BukkitRunnable() {
@Override
public void run() {
if (addonClone.isEmpty()) {
ProjectKorra.log.info("Successfully loaded in all addon elements!");
cancel();
} else if (System.currentTimeMillis() - startTime > timeoutLength) {
ProjectKorra.log.severe("ProjectKorra has timed out after attempting to load in the following addon elements: " + addonClone.toString());
ProjectKorra.log.severe("These elements have taken too long to load in, resulting in users having lost these element.");
cancel();
} else {
ProjectKorra.log.info("Attempting to load in the following addon elements... " + addonClone.toString());
for (String addon : addonClone) {
if (Element.getElement(addon) != null) {
elements.add(Element.getElement(addon));
addonClone.remove(addon);
}
}
}
}
}.runTaskTimer(ProjectKorra.plugin, 0, 20);
}
}
}
final ArrayList<SubElement> subelements = new ArrayList<SubElement>();
boolean shouldSave = false;
if (subelement != null && !subelement.equals("NULL")) {
boolean hasAddon = subelement.contains(";");
String[] split = subelement.split(";");
if (subelement.equals("-")) {
Player playero = Bukkit.getPlayer(uuid);
for (SubElement sub : Element.getAllSubElements()) {
if ((playero != null && playero.hasPermission("bending." + sub.getParentElement().getName().toLowerCase() + "." + sub.getName().toLowerCase() + sub.getType().getBending())) && elements.contains(sub.getParentElement())) {
subelements.add(sub);
shouldSave = true && playero != null;
}
}
} else if (split[0] != null) {
if (split[0].contains("m")) {
subelements.add(Element.METAL);
}
if (split[0].contains("v")) {
subelements.add(Element.LAVA);
}
if (split[0].contains("s")) {
subelements.add(Element.SAND);
}
if (split[0].contains("c")) {
subelements.add(Element.COMBUSTION);
}
if (split[0].contains("l")) {
subelements.add(Element.LIGHTNING);
}
if (split[0].contains("t")) {
subelements.add(Element.SPIRITUAL);
}
if (split[0].contains("f")) {
subelements.add(Element.FLIGHT);
}
if (split[0].contains("i")) {
subelements.add(Element.ICE);
}
if (split[0].contains("h")) {
subelements.add(Element.HEALING);
}
if (split[0].contains("b")) {
subelements.add(Element.BLOOD);
}
if (split[0].contains("p")) {
subelements.add(Element.PLANT);
}
if (hasAddon) {
final CopyOnWriteArrayList<String> addonClone = new CopyOnWriteArrayList<String>(Arrays.asList(split[split.length - 1].split(",")));
final long startTime = System.currentTimeMillis();
final long timeoutLength = 30000; // How long until it should time out attempting to load addons in
new BukkitRunnable() {
@Override
public void run() {
if (addonClone.isEmpty()) {
ProjectKorra.log.info("Successfully loaded in all addon subelements!");
cancel();
} else if (System.currentTimeMillis() - startTime > timeoutLength) {
ProjectKorra.log.severe("ProjectKorra has timed out after attempting to load in the following addon subelements: " + addonClone.toString());
ProjectKorra.log.severe("These subelements have taken too long to load in, resulting in users having lost these subelement.");
cancel();
} else {
ProjectKorra.log.info("Attempting to load in the following addon subelements... " + addonClone.toString());
for (String addon : addonClone) {
if (Element.getElement(addon) != null && Element.getElement(addon) instanceof SubElement) {
subelements.add((SubElement) Element.getElement(addon));
addonClone.remove(addon);
}
}
}
}
}.runTaskTimer(ProjectKorra.plugin, 0, 20);
}
}
}
final HashMap<Integer, String> abilities = new HashMap<Integer, String>();
final ConcurrentHashMap<Integer, String> abilitiesClone = new ConcurrentHashMap<Integer, String>(abilities);
for (int i = 1; i <= 9; i++) {
String ability = rs2.getString("slot" + i);
abilitiesClone.put(i, ability);
}
final long startTime = System.currentTimeMillis();
final long timeoutLength = 30000; // How long until it should time out attempting to load addons in
new BukkitRunnable() {
@Override
public void run() {
if (abilitiesClone.isEmpty()) {
//All abilities loaded.
cancel();
} else if (System.currentTimeMillis() - startTime > timeoutLength) {
ProjectKorra.log.severe("ProjectKorra has timed out after attempting to load in the following external abilities: " + abilitiesClone.values().toString());
ProjectKorra.log.severe("These abilities have taken too long to load in, resulting in users having lost them if bound.");
cancel();
} else {
for (int slot : abilitiesClone.keySet()) {
String ability = abilitiesClone.get(slot);
if (ability.equalsIgnoreCase("null")) {
abilitiesClone.remove(slot);
continue;
} else if (CoreAbility.getAbility(ability) != null && CoreAbility.getAbility(ability).isEnabled()) {
abilities.put(slot, ability);
abilitiesClone.remove(slot);
continue;
}
}
}
}
}.runTaskTimer(ProjectKorra.plugin, 0, 20);
p = (permaremoved != null && (permaremoved.equals("true")));
final boolean boolean_p = p;
final boolean shouldSave_ = shouldSave;
new BukkitRunnable() {
@Override
public void run() {
new BendingPlayer(uuid, player, elements, subelements, abilities, boolean_p);
if (shouldSave_) {
saveSubElements(BendingPlayer.getBendingPlayer(player));
}
}
}.runTask(ProjectKorra.plugin);
}
}
catch (SQLException ex) {
ex.printStackTrace();
}
}
/**
* Deserializes the configuration file "bendingPlayers.yml" of the old
* BendingPlugin and creates a converted.yml ready for conversion.
*
* @throws IOException If the "bendingPlayers.yml" file is not found
*/
public static void deserializeFile() {
File readFile = new File(".", "bendingPlayers.yml");
File writeFile = new File(".", "converted.yml");
if (readFile.exists()) {
try (DataInputStream input = new DataInputStream(new FileInputStream(readFile)); BufferedReader reader = new BufferedReader(new InputStreamReader(input));
DataOutputStream output = new DataOutputStream(new FileOutputStream(writeFile)); BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(output))) {
String line;
while ((line = reader.readLine()) != null) {
if (!line.trim().contains("==: BendingPlayer")) {
writer.write(line + "\n");
}
}
}
catch (IOException e) {
e.printStackTrace();
}
}
}
public static void displayColoredParticle(Location loc, ParticleEffect type, String hexVal, float xOffset, float yOffset, float zOffset) {
int R = 0;
int G = 0;
int B = 0;
if (hexVal.length() <= 6) {
R = Integer.valueOf(hexVal.substring(0, 2), 16);
G = Integer.valueOf(hexVal.substring(2, 4), 16);
B = Integer.valueOf(hexVal.substring(4, 6), 16);
if (R <= 0) {
R = 1;
}
} else if (hexVal.length() <= 7 && hexVal.substring(0, 1).equals("#")) {
R = Integer.valueOf(hexVal.substring(1, 3), 16);
G = Integer.valueOf(hexVal.substring(3, 5), 16);
B = Integer.valueOf(hexVal.substring(5, 7), 16);
if (R <= 0) {
R = 1;
}
}
loc.setX(loc.getX() + Math.random() * (xOffset / 2 - -(xOffset / 2)));
loc.setY(loc.getY() + Math.random() * (yOffset / 2 - -(yOffset / 2)));
loc.setZ(loc.getZ() + Math.random() * (zOffset / 2 - -(zOffset / 2)));
if (type == ParticleEffect.RED_DUST || type == ParticleEffect.REDSTONE) {
ParticleEffect.RED_DUST.display(R, G, B, 0.004F, 0, loc, 255.0);
} else if (type == ParticleEffect.SPELL_MOB || type == ParticleEffect.MOB_SPELL) {
ParticleEffect.SPELL_MOB.display((float) 255 - R, (float) 255 - G, (float) 255 - B, 1, 0, loc, 255.0);
} else if (type == ParticleEffect.SPELL_MOB_AMBIENT || type == ParticleEffect.MOB_SPELL_AMBIENT) {
ParticleEffect.SPELL_MOB_AMBIENT.display((float) 255 - R, (float) 255 - G, (float) 255 - B, 1, 0, loc, 255.0);
} else {
ParticleEffect.RED_DUST.display(0, 0, 0, 0.004F, 0, loc, 255.0D);
}
}
public static void displayColoredParticle(Location loc, String hexVal) {
int R = 0;
int G = 0;
int B = 0;
if (hexVal.length() <= 6) {
R = Integer.valueOf(hexVal.substring(0, 2), 16);
G = Integer.valueOf(hexVal.substring(2, 4), 16);
B = Integer.valueOf(hexVal.substring(4, 6), 16);
if (R <= 0) {
R = 1;
}
} else if (hexVal.length() <= 7 && hexVal.substring(0, 1).equals("#")) {
R = Integer.valueOf(hexVal.substring(1, 3), 16);
G = Integer.valueOf(hexVal.substring(3, 5), 16);
B = Integer.valueOf(hexVal.substring(5, 7), 16);
if (R <= 0) {
R = 1;
}
}
ParticleEffect.RED_DUST.display(R, G, B, 0.004F, 0, loc, 257D);
}
public static void displayColoredParticle(Location loc, String hexVal, float xOffset, float yOffset, float zOffset) {
int R = 0;
int G = 0;
int B = 0;
if (hexVal.length() <= 6) {
R = Integer.valueOf(hexVal.substring(0, 2), 16);
G = Integer.valueOf(hexVal.substring(2, 4), 16);
B = Integer.valueOf(hexVal.substring(4, 6), 16);
if (R <= 0) {
R = 1;
}
} else if (hexVal.length() <= 7 && hexVal.substring(0, 1).equals("#")) {
R = Integer.valueOf(hexVal.substring(1, 3), 16);
G = Integer.valueOf(hexVal.substring(3, 5), 16);
B = Integer.valueOf(hexVal.substring(5, 7), 16);
if (R <= 0) {
R = 1;
}
}
loc.setX(loc.getX() + Math.random() * (xOffset / 2 - -(xOffset / 2)));
loc.setY(loc.getY() + Math.random() * (yOffset / 2 - -(yOffset / 2)));
loc.setZ(loc.getZ() + Math.random() * (zOffset / 2 - -(zOffset / 2)));
ParticleEffect.RED_DUST.display(R, G, B, 0.004F, 0, loc, 257D);
}
public static void displayParticleVector(Location loc, ParticleEffect type, float xTrans, float yTrans, float zTrans) {
if (type == ParticleEffect.FIREWORKS_SPARK) {
ParticleEffect.FIREWORKS_SPARK.display(xTrans, yTrans, zTrans, 0.09F, 0, loc, 257D);
} else if (type == ParticleEffect.SMOKE || type == ParticleEffect.SMOKE_NORMAL) {
ParticleEffect.SMOKE.display(xTrans, yTrans, zTrans, 0.04F, 0, loc, 257D);
} else if (type == ParticleEffect.LARGE_SMOKE || type == ParticleEffect.SMOKE_LARGE) {
ParticleEffect.LARGE_SMOKE.display(xTrans, yTrans, zTrans, 0.04F, 0, loc, 257D);
} else if (type == ParticleEffect.ENCHANTMENT_TABLE) {
ParticleEffect.ENCHANTMENT_TABLE.display(xTrans, yTrans, zTrans, 0.5F, 0, loc, 257D);
} else if (type == ParticleEffect.PORTAL) {
ParticleEffect.PORTAL.display(xTrans, yTrans, zTrans, 0.5F, 0, loc, 257D);
} else if (type == ParticleEffect.FLAME) {
ParticleEffect.FLAME.display(xTrans, yTrans, zTrans, 0.04F, 0, loc, 257D);
} else if (type == ParticleEffect.CLOUD) {
ParticleEffect.CLOUD.display(xTrans, yTrans, zTrans, 0.04F, 0, loc, 257D);
} else if (type == ParticleEffect.SNOW_SHOVEL) {
ParticleEffect.SNOW_SHOVEL.display(xTrans, yTrans, zTrans, 0.2F, 0, loc, 257D);
} else {
ParticleEffect.RED_DUST.display(0, 0, 0, 0.004F, 0, loc, 257D);
}
}
/**
* Drops a {@code Collection<ItemStack>} of items on a specified block.
*
* @param block The block to drop items on.
* @param items The items to drop.
*/
public static void dropItems(Block block, Collection<ItemStack> items) {
for (ItemStack item : items) {
block.getWorld().dropItem(block.getLocation(), item);
}
}
public static void displayMovePreview(Player player) {
displayMovePreview(player, player.getInventory().getHeldItemSlot() + 1);
}
public static void displayMovePreview(Player player, int slot) {
BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player);
String displayedMessage = bPlayer.getAbilities().get(slot);
CoreAbility ability = CoreAbility.getAbility(displayedMessage);
if (ability != null && bPlayer != null) {
if (bPlayer.isOnCooldown(ability)) {
displayedMessage = ability.getElement().getColor() + "" + ChatColor.STRIKETHROUGH + ability.getName();
} else {
if (bPlayer.getStance() instanceof AcrobatStance && ability.getName().equals("AcrobatStance") || bPlayer.getStance() instanceof WarriorStance && ability.getName().equals("WarriorStance")) {
displayedMessage = ability.getElement().getColor() + "" + ChatColor.UNDERLINE + ability.getName();
} else {
displayedMessage = ability.getElement().getColor() + ability.getName();
}
}
} else if (displayedMessage == null || displayedMessage.isEmpty() || displayedMessage.equals("")) {
displayedMessage = "";
}
ActionBar.sendActionBar(displayedMessage, player);
}
public static float getAbsorbationHealth(Player player) {
try {
Object entityplayer = ActionBar.getHandle.invoke(player);
Object hearts = getAbsorption.invoke(entityplayer);
//player.sendMessage(hearts.toString());
return (float) hearts;
}
catch (Exception e) {
e.printStackTrace();
}
return 0;
}
public static void setAbsorbationHealth(Player player, float hearts) {
try {
Object entityplayer = ActionBar.getHandle.invoke(player);
setAbsorption.invoke(entityplayer, hearts);
//player.sendMessage(hearts.toString());
}
catch (Exception e) {
e.printStackTrace();
}
}
public static List<Block> getBlocksAlongLine(Location ploc, Location tloc, World w) {
List<Block> blocks = new ArrayList<Block>();
//Next we will name each coordinate
int x1 = ploc.getBlockX();
int y1 = ploc.getBlockY();
int z1 = ploc.getBlockZ();
int x2 = tloc.getBlockX();
int y2 = tloc.getBlockY();
int z2 = tloc.getBlockZ();
//Then we create the following integers
int xMin, yMin, zMin;
int xMax, yMax, zMax;
int x, y, z;
//Now we need to make sure xMin is always lower then xMax
if (x1 > x2) { //If x1 is a higher number then x2
xMin = x2;
xMax = x1;
} else {
xMin = x1;
xMax = x2;
}
//Same with Y
if (y1 > y2) {
yMin = y2;
yMax = y1;
} else {
yMin = y1;
yMax = y2;
}
//And Z
if (z1 > z2) {
zMin = z2;
zMax = z1;
} else {
zMin = z1;
zMax = z2;
}
//Now it's time for the loop
for (x = xMin; x <= xMax; x++) {
for (y = yMin; y <= yMax; y++) {
for (z = zMin; z <= zMax; z++) {
Block b = new Location(w, x, y, z).getBlock();
blocks.add(b);
}
}
}
//And last but not least, we return with the list
return blocks;
}
/**
* Gets a {@code List<Blocks>} within the specified radius around the
* specified location.
*
* @param location The base location
* @param radius The block radius from location to include within the list
* of blocks
* @return The list of Blocks
*/
public static List<Block> getBlocksAroundPoint(Location location, double radius) {
List<Block> blocks = new ArrayList<Block>();
int xorg = location.getBlockX();
int yorg = location.getBlockY();
int zorg = location.getBlockZ();
int r = (int) radius * 4;
for (int x = xorg - r; x <= xorg + r; x++) {
for (int y = yorg - r; y <= yorg + r; y++) {
for (int z = zorg - r; z <= zorg + r; z++) {
Block block = location.getWorld().getBlockAt(x, y, z);
if (block.getLocation().distanceSquared(location) <= radius * radius) {
blocks.add(block);
}
}
}
}
return blocks;
}
public static BlockFace getCardinalDirection(Vector vector) {
BlockFace[] faces = { BlockFace.NORTH, BlockFace.NORTH_EAST, BlockFace.EAST, BlockFace.SOUTH_EAST, BlockFace.SOUTH, BlockFace.SOUTH_WEST, BlockFace.WEST, BlockFace.NORTH_WEST };
Vector n, ne, e, se, s, sw, w, nw;
w = new Vector(-1, 0, 0);
n = new Vector(0, 0, -1);
s = n.clone().multiply(-1);
e = w.clone().multiply(-1);
ne = n.clone().add(e.clone()).normalize();
se = s.clone().add(e.clone()).normalize();
nw = n.clone().add(w.clone()).normalize();
sw = s.clone().add(w.clone()).normalize();
Vector[] vectors = { n, ne, e, se, s, sw, w, nw };
double comp = 0;
int besti = 0;
for (int i = 0; i < vectors.length; i++) {
double dot = vector.dot(vectors[i]);
if (dot > comp) {
comp = dot;
besti = i;
}
}
return faces[besti];
}
public static List<Location> getCircle(Location loc, int radius, int height, boolean hollow, boolean sphere, int plusY) {
List<Location> circleblocks = new ArrayList<Location>();
int cx = loc.getBlockX();
int cy = loc.getBlockY();
int cz = loc.getBlockZ();
for (int x = cx - radius; x <= cx + radius; x++) {
for (int z = cz - radius; z <= cz + radius; z++) {
for (int y = (sphere ? cy - radius : cy); y < (sphere ? cy + radius : cy + height); y++) {
double dist = (cx - x) * (cx - x) + (cz - z) * (cz - z) + (sphere ? (cy - y) * (cy - y) : 0);
if (dist < radius * radius && !(hollow && dist < (radius - 1) * (radius - 1))) {
Location l = new Location(loc.getWorld(), x, y + plusY, z);
circleblocks.add(l);
}
}
}
}
return circleblocks;
}
public static String getCurrentDate() {
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Date date = new Date();
return dateFormat.format(date);
}
public static Vector getDirection(Location location, Location destination) {
double x1, y1, z1;
double x0, y0, z0;
x1 = destination.getX();
y1 = destination.getY();
z1 = destination.getZ();
x0 = location.getX();
y0 = location.getY();
z0 = location.getZ();
return new Vector(x1 - x0, y1 - y0, z1 - z0);
}
public static double getDistanceFromLine(Vector line, Location pointonline, Location point) {
Vector AP = new Vector();
double Ax, Ay, Az;
Ax = pointonline.getX();
Ay = pointonline.getY();
Az = pointonline.getZ();
double Px, Py, Pz;
Px = point.getX();
Py = point.getY();
Pz = point.getZ();
AP.setX(Px - Ax);
AP.setY(Py - Ay);
AP.setZ(Pz - Az);
return (AP.crossProduct(line).length()) / (line.length());
}
/**
* Gets a {@code Collection<ItemStack>} of item drops from a single block.
*
* @param block The single block
* @param type The Material type to change the block into
* @param data The block data to change the block into
* @param breakitem Unused
* @return The item drops fromt the specified block
*/
public static Collection<ItemStack> getDrops(Block block, Material type, byte data, ItemStack breakitem) {
BlockState tempstate = block.getState();
block.setType(type);
block.setData(data);
Collection<ItemStack> item = block.getDrops();
tempstate.update(true);
return item;
}
/**
* Gets a {@code List<Entity>} of entities around a specified radius from
* the specified area
*
* @param location The base location
* @param radius The radius of blocks to look for entities from the location
* @return A list of entities around a point
*/
public static List<Entity> getEntitiesAroundPoint(Location location, double radius) {
List<Entity> entities = new ArrayList<Entity>();
World world = location.getWorld();
// To find chunks we use chunk coordinates (not block coordinates!)
int smallX = (int) (location.getX() - radius) >> 4;
int bigX = (int) (location.getX() + radius) >> 4;
int smallZ = (int) (location.getZ() - radius) >> 4;
int bigZ = (int) (location.getZ() + radius) >> 4;
for (int x = smallX; x <= bigX; x++) {
for (int z = smallZ; z <= bigZ; z++) {
if (world.isChunkLoaded(x, z)) {
entities.addAll(Arrays.asList(world.getChunkAt(x, z).getEntities()));
}
}
}
Iterator<Entity> entityIterator = entities.iterator();
while (entityIterator.hasNext()) {
Entity e = entityIterator.next();
if (e.getWorld().equals(location.getWorld()) && e.getLocation().distanceSquared(location) > radius * radius) {
entityIterator.remove();
} else if (e instanceof Player && ((Player) e).getGameMode().equals(GameMode.SPECTATOR)) {
entityIterator.remove();
}
}
return entities;
}
public static long getGlobalCooldown() {
return ConfigManager.defaultConfig.get().getLong("Properties.GlobalCooldown");
}
/**
*
* @param one One location being tested
* @param two Another location being tested
* @return The horizontal distance between two locations
*/
public static double getHorizontalDistance(Location one, Location two) {
double x = one.getX() - two.getX();
double z = one.getZ() - two.getZ();
return Math.sqrt((x * x) + (z * z));
}
@SuppressWarnings("incomplete-switch")
public static int getIntCardinalDirection(Vector vector) {
BlockFace face = getCardinalDirection(vector);
switch (face) {
case SOUTH:
return 7;
case SOUTH_WEST:
return 6;
case WEST:
return 3;
case NORTH_WEST:
return 0;
case NORTH:
return 1;
case NORTH_EAST:
return 2;
case EAST:
return 5;
case SOUTH_EAST:
return 8;
}
return 4;
}
public static Plugin getItems() {
if (hasItems()) {
return Bukkit.getServer().getPluginManager().getPlugin("ProjectKorraItems");
}
return null;
}
/**
* Returns the last ability used by a player. Also checks if a combo was
* used.
*
* @param player The player to check
* @return name of last ability used
*/
public static String getLastUsedAbility(Player player, boolean checkCombos) {
List<AbilityInformation> lastUsedAbility = ComboManager.getRecentlyUsedAbilities(player, 1);
if (!lastUsedAbility.isEmpty()) {
if (ComboManager.checkForValidCombo(player) != null && checkCombos) {
return ComboManager.checkForValidCombo(player).getName();
} else {
return lastUsedAbility.get(0).getAbilityName();
}
}
return null;
}
/**
* Gets a location with a specified distance away from the left side of a
* location.
*
* @param location The origin location
* @param distance The distance to the left
* @return the location of the distance to the left
*/
public static Location getLeftSide(Location location, double distance) {
float angle = location.getYaw() / 60;
return location.clone().add(new Vector(Math.cos(angle), 0, Math.sin(angle)).normalize().multiply(distance));
}
public static int getMaxPresets(Player player) {
if (player.isOp()) {
return 500;
}
int cap = 0;
for (int i = 0; i <= 500; i++) {
if (player.hasPermission("bending.command.presets.create." + i)) {
cap = i;
}
}
return cap;
}
public static Vector getOrthogonalVector(Vector axis, double degrees, double length) {
Vector ortho = new Vector(axis.getY(), -axis.getX(), 0);
ortho = ortho.normalize();
ortho = ortho.multiply(length);
return rotateVectorAroundVector(axis, ortho, degrees);
}
public static Collection<Player> getPlayersAroundPoint(Location location, double distance) {
Collection<Player> players = new HashSet<Player>();
for (Player player : Bukkit.getOnlinePlayers()) {
if (player.getLocation().getWorld().equals(location.getWorld())) {
if (player.getLocation().distanceSquared(location) <= distance * distance) {
players.add(player);
}
}
}
return players;
}
public static Location getPointOnLine(Location origin, Location target, double distance) {
return origin.clone().add(getDirection(origin, target).normalize().multiply(distance));
}
/**
* Returns a location with a specified distance away from the right side of
* a location.
*
* @param location The origin location
* @param distance The distance to the right
* @return the location of the distance to the right
*/
public static Location getRightSide(Location location, double distance) {
float angle = location.getYaw() / 60;
return location.clone().subtract(new Vector(Math.cos(angle), 0, Math.sin(angle)).normalize().multiply(distance));
}
public static Plugin getProbending() {
if (hasProbending()) {
return Bukkit.getServer().getPluginManager().getPlugin("Probending");
}
return null;
}
public static Plugin getRPG() {
if (hasRPG()) {
return Bukkit.getServer().getPluginManager().getPlugin("ProjectKorraRPG");
}
return null;
}
public static Plugin getSpirits() {
if (hasSpirits()) {
return Bukkit.getServer().getPluginManager().getPlugin("ProjectKorraSpirits");
}
return null;
}
@SuppressWarnings("unused")
public static Entity getTargetedEntity(Player player, double range, List<Entity> avoid) {
double longestr = range + 1;
Entity target = null;
Location origin = player.getEyeLocation();
Vector direction = player.getEyeLocation().getDirection().normalize();
for (Entity entity : origin.getWorld().getEntities()) {
if (entity instanceof Player) {
if (((Player)entity).getGameMode().equals(GameMode.SPECTATOR)) {
continue;
}
}
if (avoid.contains(entity)) {
continue;
}
if (entity.getWorld().equals(origin.getWorld())) {
if (entity.getLocation().distanceSquared(origin) < longestr * longestr && getDistanceFromLine(direction, origin, entity.getLocation()) < 2 && (entity instanceof LivingEntity) && entity.getEntityId() != player.getEntityId() && entity.getLocation().distanceSquared(origin.clone().add(direction)) < entity.getLocation().distanceSquared(origin.clone().add(direction.clone().multiply(-1)))) {
target = entity;
longestr = entity.getLocation().distance(origin);
}
}
}
if (target != null) {
List<Block> blocklist = new ArrayList<Block>();
blocklist = GeneralMethods.getBlocksAlongLine(player.getLocation(), target.getLocation(), player.getWorld());
for (Block isAir : blocklist) {
if (GeneralMethods.isObstructed(origin, target.getLocation())) {
target = null;
break;
}
}
}
return target;
}
public static Entity getTargetedEntity(Player player, double range) {
return getTargetedEntity(player, range, new ArrayList<Entity>());
}
public static Location getTargetedLocation(Player player, double originselectrange, Material... nonOpaque2) {
Location origin = player.getEyeLocation();
Vector direction = origin.getDirection();
HashSet<Material> trans = new HashSet<Material>();
trans.add(Material.AIR);
if (nonOpaque2 == null) {
trans = null;
} else {
for (Material material : nonOpaque2) {
trans.add(material);
}
}
Block block = player.getTargetBlock(trans, (int) originselectrange + 1);
double distance = originselectrange;
if (block.getWorld().equals(origin.getWorld())) {
distance = block.getLocation().distance(origin) - 1.5;
}
Location location = origin.add(direction.multiply(distance));
return location;
}
public static Location getTargetedLocation(Player player, int range) {
return getTargetedLocation(player, range, Material.AIR);
}
public static Block getTopBlock(Location loc, int range) {
return getTopBlock(loc, range, range);
}
/**
* Returns the top block based around loc. PositiveY is the maximum amount
* of distance it will check upward. Similarly, negativeY is for downward.
*/
public static Block getTopBlock(Location loc, int positiveY, int negativeY) {
Block blockHolder = loc.getBlock();
int y = 0;
//Only one of these while statements will go
while (blockHolder.getType() != Material.AIR && Math.abs(y) < Math.abs(positiveY)) {
y++;
Block tempBlock = loc.clone().add(0, y, 0).getBlock();
if (tempBlock.getType() == Material.AIR) {
return blockHolder;
}
blockHolder = tempBlock;
}
while (blockHolder.getType() == Material.AIR && Math.abs(y) < Math.abs(negativeY)) {
y--;
blockHolder = loc.clone().add(0, y, 0).getBlock();
if (blockHolder.getType() != Material.AIR) {
return blockHolder;
}
}
return blockHolder;
}
public static Block getBottomBlock(Location loc, int positiveY, int negativeY) {
Block blockHolder = loc.getBlock();
int y = 0;
//Only one of these while statements will go
while (blockHolder.getType() != Material.AIR && Math.abs(y) < Math.abs(negativeY)) {
y--;
Block tempblock = loc.clone().add(0, y, 0).getBlock();
if (tempblock.getType() == Material.AIR) {
return blockHolder;
}
blockHolder = tempblock;
}
while (blockHolder.getType() != Material.AIR && Math.abs(y) < Math.abs(positiveY)) {
y++;
blockHolder = loc.clone().add(0, y, 0).getBlock();
if (blockHolder.getType() == Material.AIR) {
return blockHolder;
}
}
return blockHolder;
}
public static ArrayList<Element> getElementsWithNoWeaponBending() {
ArrayList<Element> elements = new ArrayList<Element>();
if (!plugin.getConfig().getBoolean("Properties.Air.CanBendWithWeapons"))
elements.add(Element.AIR);
if (!plugin.getConfig().getBoolean("Properties.Water.CanBendWithWeapons"))
elements.add(Element.WATER);
if (!plugin.getConfig().getBoolean("Properties.Earth.CanBendWithWeapons"))
elements.add(Element.EARTH);
if (!plugin.getConfig().getBoolean("Properties.Fire.CanBendWithWeapons"))
elements.add(Element.FIRE);
if (!plugin.getConfig().getBoolean("Properties.Chi.CanBendWithWeapons"))
elements.add(Element.CHI);
return elements;
}
public static boolean hasItems() {
return Bukkit.getServer().getPluginManager().getPlugin("ProjectKorraItems") != null;
}
public static boolean hasProbending() {
return Bukkit.getServer().getPluginManager().getPlugin("Probending") != null;
}
public static boolean hasRPG() {
return Bukkit.getServer().getPluginManager().getPlugin("ProjectKorraRPG") != null;
}
public static boolean hasSpirits() {
return Bukkit.getServer().getPluginManager().getPlugin("ProjectKorraSpirits") != null;
}
public static boolean isAdjacentToThreeOrMoreSources(Block block) {
if (block == null || (TempBlock.isTempBlock(block) && WaterAbility.isBendableWaterTempBlock(block))) {
return false;
}
int sources = 0;
byte full = 0x0;
BlockFace[] faces = { BlockFace.EAST, BlockFace.WEST, BlockFace.NORTH, BlockFace.SOUTH };
for (BlockFace face : faces) {
Block blocki = block.getRelative(face);
if ((blocki.getType() == Material.LAVA || blocki.getType() == Material.STATIONARY_LAVA) && blocki.getData() == full && EarthPassive.canPhysicsChange(blocki)) {
sources++;
}
if ((WaterAbility.isWater(blocki) || WaterAbility.isIce(blocki)) && blocki.getData() == full && WaterManipulation.canPhysicsChange(blocki)) {
sources++;
}
}
return sources >= 2;
}
public static boolean isImportEnabled() {
return ConfigManager.defaultConfig.get().getBoolean("Properties.ImportEnabled");
}
public static boolean isInteractable(Block block) {
return Arrays.asList(INTERACTABLE_MATERIALS).contains(block.getType());
}
public static boolean isObstructed(Location location1, Location location2) {
Vector loc1 = location1.toVector();
Vector loc2 = location2.toVector();
Vector direction = loc2.subtract(loc1);
direction.normalize();
Location loc;
double max = 0;
if (location1.getWorld().equals(location2.getWorld()))
max = location1.distance(location2);
for (double i = 0; i <= max; i++) {
loc = location1.clone().add(direction.clone().multiply(i));
Material type = loc.getBlock().getType();
if (type != Material.AIR && !(ElementalAbility.getTransparentMaterialSet().contains(type) || ElementalAbility.isWater(loc.getBlock()))) {
return true;
}
}
return false;
}
/**
* isRegionProtectedFromBuild is one of the most server intensive methods in
* the plugin. It uses a blockCache that keeps track of recent blocks that
* may have already been checked. Abilities like TremorSense call this
* ability 5 times per tick even though it only needs to check a single
* block, instead of doing all 5 of those checks this method will now look
* in the map first.
*/
public static boolean isRegionProtectedFromBuild(Player player, String ability, Location loc) {
if (!BLOCK_CACHE.containsKey(player.getName())) {
BLOCK_CACHE.put(player.getName(), new ConcurrentHashMap<Block, BlockCacheElement>());
}
Map<Block, BlockCacheElement> blockMap = BLOCK_CACHE.get(player.getName());
Block block = loc.getBlock();
if (blockMap.containsKey(block)) {
BlockCacheElement elem = blockMap.get(block);
// both abilities must be equal to each other to use the cache
if ((ability == null && elem.getAbility() == null) || (ability != null && elem.getAbility() != null && elem.getAbility().equals(ability))) {
return elem.isAllowed();
}
}
boolean value = isRegionProtectedFromBuildPostCache(player, ability, loc);
blockMap.put(block, new BlockCacheElement(player, block, ability, value, System.currentTimeMillis()));
return value;
}
public static boolean isRegionProtectedFromBuild(Ability ability, Location loc) {
return isRegionProtectedFromBuild(ability.getPlayer(), ability.getName(), loc);
}
public static boolean isRegionProtectedFromBuild(Player player, Location loc) {
return isRegionProtectedFromBuild(player, null, loc);
}
public static boolean isRegionProtectedFromBuildPostCache(Player player, String ability, Location loc) {
boolean allowHarmless = ConfigManager.defaultConfig.get().getBoolean("Properties.RegionProtection.AllowHarmlessAbilities");
boolean respectWorldGuard = ConfigManager.defaultConfig.get().getBoolean("Properties.RegionProtection.RespectWorldGuard");
boolean respectPreciousStones = ConfigManager.defaultConfig.get().getBoolean("Properties.RegionProtection.RespectPreciousStones");
boolean respectFactions = ConfigManager.defaultConfig.get().getBoolean("Properties.RegionProtection.RespectFactions");
boolean respectTowny = ConfigManager.defaultConfig.get().getBoolean("Properties.RegionProtection.RespectTowny");
boolean respectGriefPrevention = ConfigManager.defaultConfig.get().getBoolean("Properties.RegionProtection.RespectGriefPrevention");
boolean respectLWC = ConfigManager.defaultConfig.get().getBoolean("Properties.RegionProtection.RespectLWC");
boolean respectResidence = ConfigManager.defaultConfig.get().getBoolean("Properties.RegionProtection.Residence.Respect");
boolean respectKingdoms = ConfigManager.defaultConfig.get().getBoolean("Properties.RegionProtection.Kingdoms");
boolean isIgnite = false;
boolean isExplosive = false;
boolean isHarmless = false;
CoreAbility coreAbil = CoreAbility.getAbility(ability);
if (coreAbil != null) {
isIgnite = coreAbil.isIgniteAbility();
isExplosive = coreAbil.isExplosiveAbility();
isHarmless = coreAbil.isHarmlessAbility();
}
if (ability == null && allowHarmless) {
return false;
}
if (isHarmless && allowHarmless) {
return false;
}
PluginManager pm = Bukkit.getPluginManager();
Plugin wgp = pm.getPlugin("WorldGuard");
Plugin psp = pm.getPlugin("PreciousStones");
Plugin fcp = pm.getPlugin("Factions");
Plugin twnp = pm.getPlugin("Towny");
Plugin gpp = pm.getPlugin("GriefPrevention");
Plugin massivecore = pm.getPlugin("MassiveCore");
Plugin lwc = pm.getPlugin("LWC");
Plugin residence = pm.getPlugin("Residence");
Plugin kingdoms = pm.getPlugin("Kingdoms");
for (Location location : new Location[] { loc, player.getLocation() }) {
World world = location.getWorld();
if (lwc != null && respectLWC) {
LWCPlugin lwcp = (LWCPlugin) lwc;
LWC lwc2 = lwcp.getLWC();
Protection protection = lwc2.getProtectionCache().getProtection(location.getBlock());
if (protection != null) {
if (!lwc2.canAccessProtection(player, protection)) {
return true;
}
}
}
if (wgp != null && respectWorldGuard && !player.hasPermission("worldguard.region.bypass." + world.getName())) {
WorldGuardPlugin wg = (WorldGuardPlugin) Bukkit.getPluginManager().getPlugin("WorldGuard");
if (!player.isOnline()) {
return true;
}
if (isIgnite) {
if (!wg.hasPermission(player, "worldguard.override.lighter")) {
if (wg.getGlobalStateManager().get(world).blockLighter) {
return true;
}
}
}
if (isExplosive) {
if (wg.getGlobalStateManager().get(location.getWorld()).blockTNTExplosions) {
return true;
}
if (!wg.getRegionContainer().createQuery().testBuild(location, player, DefaultFlag.TNT)) {
return true;
}
}
if (!wg.canBuild(player, location.getBlock())) {
return true;
}
}
if (psp != null && respectPreciousStones) {
PreciousStones ps = (PreciousStones) psp;
if (isIgnite) {
if (ps.getForceFieldManager().hasSourceField(location, FieldFlag.PREVENT_FIRE)) {
return true;
}
}
if (isExplosive) {
if (ps.getForceFieldManager().hasSourceField(location, FieldFlag.PREVENT_EXPLOSIONS)) {
return true;
}
}
if (!PreciousStones.API().canBreak(player, location)) {
return true;
}
}
if (fcp != null && massivecore != null && respectFactions) {
if (!EngineMain.canPlayerBuildAt(player, PS.valueOf(loc.getBlock()), false)) {
return true;
}
}
if (twnp != null && respectTowny) {
Towny twn = (Towny) twnp;
WorldCoord worldCoord;
try {
TownyWorld tWorld = TownyUniverse.getDataSource().getWorld(world.getName());
worldCoord = new WorldCoord(tWorld.getName(), Coord.parseCoord(location));
boolean bBuild = PlayerCacheUtil.getCachePermission(player, location, 3, (byte) 0, TownyPermission.ActionType.BUILD);
if (!bBuild) {
PlayerCache cache = twn.getCache(player);
TownBlockStatus status = cache.getStatus();
if (((status == TownBlockStatus.ENEMY) && TownyWarConfig.isAllowingAttacks())) {
try {
TownyWar.callAttackCellEvent(twn, player, location.getBlock(), worldCoord);
}
catch (Exception e) {
TownyMessaging.sendErrorMsg(player, e.getMessage());
}
return true;
} else if (status == TownBlockStatus.WARZONE) {
} else {
return true;
}
if ((cache.hasBlockErrMsg())) {
TownyMessaging.sendErrorMsg(player, cache.getBlockErrMsg());
}
}
}
catch (Exception e1) {
TownyMessaging.sendErrorMsg(player, TownySettings.getLangString("msg_err_not_configured"));
}
}
if (gpp != null && respectGriefPrevention) {
Material type = player.getWorld().getBlockAt(location).getType();
if (type == null) {
type = Material.AIR;
}
String reason = GriefPrevention.instance.allowBuild(player, location); // WORKING with WorldGuard 6.0 BETA 4
Claim claim = GriefPrevention.instance.dataStore.getClaimAt(loc, true, null);
if (reason != null && claim != null) {
return true;
}
}
if (residence != null && respectResidence) {
ClaimedResidence res = Residence.getResidenceManager().getByLoc(loc);
if (res != null) {
ResidencePermissions perms = res.getPermissions();
if (perms.playerHas(player.getName(), ConfigManager.defaultConfig.get().getString("Properities.RegionProtection.Residence.Flag"), true)) {
return true;
}
}
}
if (kingdoms != null && respectKingdoms) {
SimpleLocation location_ = new SimpleLocation(loc);
SimpleChunkLocation chunk = location_.toSimpleChunk();
Land land = GameManagement.getLandManager().getOrLoadLand(chunk);
if (land.getOwner() != null) {
KingdomPlayer kp = GameManagement.getPlayerManager().getSession(player);
if (!kp.isAdminMode()) {
if (land.getOwner().equals("SafeZone")) {
return true;
} else if (kp.getKingdom() == null) { //If the player isn't in a kingdom but it's claimed land
return true;
} else {
Kingdom kingdom = kp.getKingdom();
String kingdomName = kingdom.getKingdomName();
if (!kingdomName.equals(land.getOwner())) //If the player's kingdom doesn't match
{
return true;
}
//If it's within the nexus area, test for higher permission
if (land.getStructure() != null && land.getStructure().getType() == StructureType.NEXUS) {
if (!kp.getRank().isHigherOrEqualTo(kingdom.getPermissionsInfo().getBuildInNexus())) {
return true;
}
}
}
}
}
}
}
return false;
}
public static boolean isSolid(Block block) {
return !Arrays.asList(NON_OPAQUE).contains(block.getType());
}
/** Checks if an entity is Undead **/
public static boolean isUndead(Entity entity) {
return entity != null && (entity.getType() == EntityType.ZOMBIE || entity.getType() == EntityType.BLAZE || entity.getType() == EntityType.GIANT || entity.getType() == EntityType.IRON_GOLEM || entity.getType() == EntityType.MAGMA_CUBE || entity.getType() == EntityType.PIG_ZOMBIE || entity.getType() == EntityType.SKELETON || entity.getType() == EntityType.SLIME || entity.getType() == EntityType.SNOWMAN || entity.getType() == EntityType.ZOMBIE);
}
public static boolean isWeapon(Material mat) {
return mat != null && (mat == Material.WOOD_AXE || mat == Material.WOOD_PICKAXE || mat == Material.WOOD_SPADE || mat == Material.WOOD_SWORD || mat == Material.STONE_AXE || mat == Material.STONE_PICKAXE || mat == Material.STONE_SPADE || mat == Material.STONE_SWORD || mat == Material.IRON_AXE || mat == Material.IRON_PICKAXE || mat == Material.IRON_SWORD || mat == Material.IRON_SPADE || mat == Material.DIAMOND_AXE || mat == Material.DIAMOND_PICKAXE || mat == Material.DIAMOND_SWORD || mat == Material.DIAMOND_SPADE || mat == Material.GOLD_AXE || mat == Material.GOLD_HOE || mat == Material.GOLD_SWORD || mat == Material.GOLD_PICKAXE || mat == Material.GOLD_SPADE);
}
public static void loadBendingPlayer(BendingPlayer pl) {
Player player = Bukkit.getPlayer(pl.getUUID());
BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player);
if (bPlayer == null) {
return;
}
if (PKListener.getToggledOut().contains(player.getUniqueId())) {
bPlayer.toggleBending();
player.sendMessage(ChatColor.YELLOW + "Reminder, you toggled your bending before signing off. Enable it again with /bending toggle.");
}
Preset.loadPresets(player);
Element element = null;
String prefix = "";
boolean chatEnabled = ConfigManager.languageConfig.get().getBoolean("Chat.Enable");
if (bPlayer.getElements().size() > 1) {
prefix = Element.AVATAR.getPrefix();
} else if (bPlayer.getElements().size() == 1) {
element = bPlayer.getElements().get(0);
prefix = element.getPrefix();
} else {
prefix = ChatColor.WHITE + ChatColor.translateAlternateColorCodes('&', ConfigManager.languageConfig.get().getString("Chat.Prefixes.Nonbender")) + " ";
}
if (chatEnabled) {
player.setDisplayName(player.getName());
player.setDisplayName(prefix + ChatColor.RESET + player.getDisplayName());
}
// Handle the AirSpout/WaterSpout login glitches
if (player.getGameMode() != GameMode.CREATIVE) {
HashMap<Integer, String> bound = bPlayer.getAbilities();
for (String str : bound.values()) {
if (str.equalsIgnoreCase("AirSpout") || str.equalsIgnoreCase("WaterSpout") || str.equalsIgnoreCase("SandSpout")) {
final Player fplayer = player;
new BukkitRunnable() {
@Override
public void run() {
fplayer.setFlying(false);
fplayer.setAllowFlight(false);
}
}.runTaskLater(ProjectKorra.plugin, 2);
break;
}
}
}
Bukkit.getServer().getPluginManager().callEvent(new BendingPlayerCreationEvent(bPlayer));
}
public static void reloadPlugin(CommandSender sender) {
ProjectKorra.log.info("Reloading ProjectKorra and configuration");
BendingReloadEvent event = new BendingReloadEvent(sender);
Bukkit.getServer().getPluginManager().callEvent(event);
if (event.isCancelled()) {
sender.sendMessage(ChatColor.RED + "Reload event cancelled");
return;
}
if (DBConnection.isOpen) {
DBConnection.sql.close();
}
GeneralMethods.stopBending();
ConfigManager.defaultConfig.reload();
ConfigManager.languageConfig.reload();
ConfigManager.presetConfig.reload();
Preset.loadExternalPresets();
new MultiAbilityManager();
new ComboManager();
// Stop the previous collision detection task before creating new manager.
ProjectKorra.collisionManager.stopCollisionDetection();
ProjectKorra.collisionManager = new CollisionManager();
ProjectKorra.collisionInitializer = new CollisionInitializer(ProjectKorra.collisionManager);
CoreAbility.registerAbilities();
reloadAddonPlugins();
ProjectKorra.collisionInitializer.initializeDefaultCollisions(); // must be called after abilities have been registered
ProjectKorra.collisionManager.startCollisionDetection();
DBConnection.host = ConfigManager.defaultConfig.get().getString("Storage.MySQL.host");
DBConnection.port = ConfigManager.defaultConfig.get().getInt("Storage.MySQL.port");
DBConnection.pass = ConfigManager.defaultConfig.get().getString("Storage.MySQL.pass");
DBConnection.db = ConfigManager.defaultConfig.get().getString("Storage.MySQL.db");
DBConnection.user = ConfigManager.defaultConfig.get().getString("Storage.MySQL.user");
DBConnection.init();
if (!DBConnection.isOpen()) {
ProjectKorra.log.severe("Unable to enable ProjectKorra due to the database not being open");
stopPlugin();
}
for (Player player : Bukkit.getOnlinePlayers()) {
Preset.unloadPreset(player);
GeneralMethods.createBendingPlayer(player.getUniqueId(), player.getName());
PassiveManager.registerPassives(player);
}
plugin.updater.checkUpdate();
ProjectKorra.log.info("Reload complete");
}
public static void reloadAddonPlugins() {
for (int i = CoreAbility.getAddonPlugins().size()-1; i > -1; i--) {
String entry = CoreAbility.getAddonPlugins().get(i);
String[] split = entry.split("::");
if (Bukkit.getServer().getPluginManager().isPluginEnabled(split[0])) {
CoreAbility.registerPluginAbilities((JavaPlugin)Bukkit.getServer().getPluginManager().getPlugin(split[0]), split[1]);
} else {
CoreAbility.getAddonPlugins().remove(i);
}
}
}
public static void removeBlock(Block block) {
if (isAdjacentToThreeOrMoreSources(block)) {
block.setType(Material.WATER);
block.setData((byte) 0x0);
} else {
block.setType(Material.AIR);
}
}
public static void removeUnusableAbilities(String player) {
BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player);
if (bPlayer == null) {
return;
}
HashMap<Integer, String> slots = bPlayer.getAbilities();
HashMap<Integer, String> finalAbilities = new HashMap<Integer, String>();
for (int i : slots.keySet()) {
if (bPlayer.canBind(CoreAbility.getAbility(slots.get(i)))) {
finalAbilities.put(i, slots.get(i));
}
}
bPlayer.setAbilities(finalAbilities);
}
public static Vector rotateVectorAroundVector(Vector axis, Vector rotator, double degrees) {
double angle = Math.toRadians(degrees);
Vector rotation = axis.clone();
Vector rotate = rotator.clone();
rotation = rotation.normalize();
Vector thirdaxis = rotation.crossProduct(rotate).normalize().multiply(rotate.length());
return rotate.multiply(Math.cos(angle)).add(thirdaxis.multiply(Math.sin(angle)));
}
/**
* Rotates a vector around the Y plane.
*/
public static Vector rotateXZ(Vector vec, double theta) {
Vector vec2 = vec.clone();
double x = vec2.getX();
double z = vec2.getZ();
vec2.setX(x * Math.cos(Math.toRadians(theta)) - z * Math.sin(Math.toRadians(theta)));
vec2.setZ(x * Math.sin(Math.toRadians(theta)) + z * Math.cos(Math.toRadians(theta)));
return vec2;
}
public static void runDebug() {
File debugFile = new File(plugin.getDataFolder(), "debug.txt");
if (debugFile.exists()) {
debugFile.delete(); // We're starting brand new.
}
writeToDebug("ProjectKorra Debug: Paste this on http://pastie.org and put it in your bug report thread.");
writeToDebug("====================");
writeToDebug("");
writeToDebug("");
writeToDebug("Date Created: " + getCurrentDate());
writeToDebug("Java Version: " + Runtime.class.getPackage().getImplementationVersion());
writeToDebug("Bukkit Version: " + Bukkit.getServer().getVersion());
writeToDebug("");
writeToDebug("ProjectKorra (Core) Information");
writeToDebug("====================");
writeToDebug("Version: " + plugin.getDescription().getVersion());
writeToDebug("Author: " + plugin.getDescription().getAuthors());
List<String> officialSidePlugins = new ArrayList<String>();
if (hasRPG()) {
officialSidePlugins.add("ProjectKorra RPG v" + getRPG().getDescription().getVersion());
}
if (hasItems()) {
officialSidePlugins.add("ProjectKorra Items v" + getItems().getDescription().getVersion());
}
if (hasSpirits()) {
officialSidePlugins.add("ProjectKorra Spirits v" + getSpirits().getDescription().getVersion());
}
if (hasProbending()) {
officialSidePlugins.add("Probending v" + getProbending().getDescription().getVersion());
}
if (!officialSidePlugins.isEmpty()) {
writeToDebug("");
writeToDebug("ProjectKorra (Side Plugin) Information");
writeToDebug("====================");
for (String line : officialSidePlugins) {
writeToDebug(line);
}
}
writeToDebug("");
writeToDebug("Supported Plugins");
writeToDebug("====================");
boolean respectWorldGuard = ConfigManager.defaultConfig.get().getBoolean("Properties.RegionProtection.RespectWorldGuard");
boolean respectPreciousStones = ConfigManager.defaultConfig.get().getBoolean("Properties.RegionProtection.RespectPreciousStones");
boolean respectFactions = ConfigManager.defaultConfig.get().getBoolean("Properties.RegionProtection.RespectFactions");
boolean respectTowny = ConfigManager.defaultConfig.get().getBoolean("Properties.RegionProtection.RespectTowny");
boolean respectGriefPrevention = ConfigManager.defaultConfig.get().getBoolean("Properties.RegionProtection.RespectGriefPrevention");
boolean respectLWC = ConfigManager.defaultConfig.get().getBoolean("Properties.RegionProtection.RespectLWC");
PluginManager pm = Bukkit.getPluginManager();
Plugin wgp = pm.getPlugin("WorldGuard");
Plugin psp = pm.getPlugin("PreciousStones");
Plugin fcp = pm.getPlugin("Factions");
Plugin twnp = pm.getPlugin("Towny");
Plugin gpp = pm.getPlugin("GriefPrevention");
Plugin massivecore = pm.getPlugin("MassiveCore");
Plugin lwc = pm.getPlugin("LWC");
if (wgp != null && respectWorldGuard) {
writeToDebug("WorldGuard v" + wgp.getDescription().getVersion());
}
if (psp != null && respectPreciousStones) {
writeToDebug("PreciousStones v" + psp.getDescription().getVersion());
}
if (fcp != null && respectFactions) {
writeToDebug("Factions v" + fcp.getDescription().getVersion());
}
if (massivecore != null && respectFactions) {
writeToDebug("MassiveCore v" + massivecore.getDescription().getVersion());
}
if (twnp != null && respectTowny) {
writeToDebug("Towny v" + twnp.getDescription().getVersion());
}
if (gpp != null && respectGriefPrevention) {
writeToDebug("GriefPrevention v" + gpp.getDescription().getVersion());
}
if (lwc != null && respectLWC) {
writeToDebug("LWC v" + lwc.getDescription().getVersion());
}
writeToDebug("");
writeToDebug("Plugins Hooking Into ProjectKorra (Core)");
writeToDebug("====================");
String[] pkPlugins = new String[] { "projectkorrarpg", "projectkorraitems", "projectkorraspirits", "probending" };
for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) {
if (plugin.getDescription().getDepend() != null && plugin.getDescription().getDepend().contains("ProjectKorra") && !Arrays.asList(pkPlugins).contains(plugin.getName().toLowerCase())) {
writeToDebug(plugin.getDescription().getName() + " v" + plugin.getDescription().getVersion());
}
}
writeToDebug("");
writeToDebug("Ability Information");
writeToDebug("====================");
ArrayList<String> stockAbils = new ArrayList<String>();
ArrayList<String> unofficialAbils = new ArrayList<String>();
for (CoreAbility ability : CoreAbility.getAbilities()) {
if (ability.getClass().getPackage().getName().startsWith("com.projectkorra")) {
stockAbils.add(ability.getName());
} else {
unofficialAbils.add(ability.getName());
}
}
if (!stockAbils.isEmpty()) {
Collections.sort(stockAbils);
for (String ability : stockAbils) {
writeToDebug(ability + " - STOCK");
}
}
if (!unofficialAbils.isEmpty()) {
Collections.sort(unofficialAbils);
for (String ability : unofficialAbils) {
writeToDebug(ability + " - UNOFFICAL");
}
}
writeToDebug("");
writeToDebug("Collection Sizes");
writeToDebug("====================");
ClassLoader loader = ProjectKorra.class.getClassLoader();
try {
for (final ClassPath.ClassInfo info : ClassPath.from(loader).getTopLevelClasses()) {
if (info.getName().startsWith("com.projectkorra.")) {
final Class<?> clazz = info.load();
for (Field field : clazz.getDeclaredFields()) {
String simpleName = clazz.getSimpleName();
field.setAccessible(true);
try {
Object obj = field.get(null);
if (obj instanceof Collection) {
writeToDebug(simpleName + ": " + field.getName() + " size=" + ((Collection<?>) obj).size());
} else if (obj instanceof Map) {
writeToDebug(simpleName + ": " + field.getName() + " size=" + ((Map<?, ?>) obj).size());
}
}
catch (Exception e) {
}
}
}
}
}
catch (IOException e) {
e.printStackTrace();
}
writeToDebug("");
writeToDebug("CoreAbility Debugger");
writeToDebug("====================");
for (String line : CoreAbility.getDebugString().split("\\n")) {
writeToDebug(line);
}
}
public static void saveAbility(BendingPlayer bPlayer, int slot, String ability) {
if (bPlayer == null) {
return;
}
String uuid = bPlayer.getUUIDString();
BindChangeEvent event = new BindChangeEvent(Bukkit.getPlayer(UUID.fromString(uuid)), ability, slot, false);
Bukkit.getServer().getPluginManager().callEvent(event);
if (event.isCancelled()) {
return;
}
//Temp code to block modifications of binds, Should be replaced when bind event is added.
if (MultiAbilityManager.playerAbilities.containsKey(Bukkit.getPlayer(bPlayer.getUUID()))) {
return;
}
HashMap<Integer, String> abilities = bPlayer.getAbilities();
DBConnection.sql.modifyQuery("UPDATE pk_players SET slot" + slot + " = '" + (abilities.get(slot) == null ? null : abilities.get(slot)) + "' WHERE uuid = '" + uuid + "'");
}
public static void saveElements(BendingPlayer bPlayer) {
if (bPlayer == null) {
return;
}
String uuid = bPlayer.getUUIDString();
StringBuilder elements = new StringBuilder();
if (bPlayer.hasElement(Element.AIR)) {
elements.append("a");
}
if (bPlayer.hasElement(Element.WATER)) {
elements.append("w");
}
if (bPlayer.hasElement(Element.EARTH)) {
elements.append("e");
}
if (bPlayer.hasElement(Element.FIRE)) {
elements.append("f");
}
if (bPlayer.hasElement(Element.CHI)) {
elements.append("c");
}
boolean hasAddon = false;
for (Element element : bPlayer.getElements()) {
if (Arrays.asList(Element.getAddonElements()).contains(element)) {
if (!hasAddon) {
hasAddon = true;
elements.append(";");
}
elements.append(element.getName() + ",");
}
}
if (elements.length() == 0) {
elements.append("NULL");
}
DBConnection.sql.modifyQuery("UPDATE pk_players SET element = '" + elements.toString() + "' WHERE uuid = '" + uuid + "'");
}
public static void saveSubElements(BendingPlayer bPlayer) {
if (bPlayer == null) {
return;
}
String uuid = bPlayer.getUUIDString();
StringBuilder subs = new StringBuilder();
if (bPlayer.hasSubElement(Element.METAL)) {
subs.append("m");
}
if (bPlayer.hasSubElement(Element.LAVA)) {
subs.append("v");
}
if (bPlayer.hasSubElement(Element.SAND)) {
subs.append("s");
}
if (bPlayer.hasSubElement(Element.COMBUSTION)) {
subs.append("c");
}
if (bPlayer.hasSubElement(Element.LIGHTNING)) {
subs.append("l");
}
if (bPlayer.hasSubElement(Element.SPIRITUAL)) {
subs.append("t");
}
if (bPlayer.hasSubElement(Element.FLIGHT)) {
subs.append("f");
}
if (bPlayer.hasSubElement(Element.ICE)) {
subs.append("i");
}
if (bPlayer.hasSubElement(Element.HEALING)) {
subs.append("h");
}
if (bPlayer.hasSubElement(Element.BLOOD)) {
subs.append("b");
}
if (bPlayer.hasSubElement(Element.PLANT)) {
subs.append("p");
}
boolean hasAddon = false;
for (Element element : bPlayer.getSubElements()) {
if (Arrays.asList(Element.getAddonSubElements()).contains(element)) {
if (!hasAddon) {
hasAddon = true;
subs.append(";");
}
subs.append(element.getName() + ",");
}
}
if (subs.length() == 0) {
subs.append("NULL");
}
DBConnection.sql.modifyQuery("UPDATE pk_players SET subelement = '" + subs.toString() + "' WHERE uuid = '" + uuid + "'");
}
public static void savePermaRemoved(BendingPlayer bPlayer) {
if (bPlayer == null) {
return;
}
String uuid = bPlayer.getUUIDString();
boolean permaRemoved = bPlayer.isPermaRemoved();
DBConnection.sql.modifyQuery("UPDATE pk_players SET permaremoved = '" + (permaRemoved ? "true" : "false") + "' WHERE uuid = '" + uuid + "'");
}
public static void setVelocity(Entity entity, Vector velocity) {
if (entity instanceof TNTPrimed) {
if (ConfigManager.defaultConfig.get().getBoolean("Properties.BendingAffectFallingSand.TNT")) {
entity.setVelocity(velocity.multiply(ConfigManager.defaultConfig.get().getDouble("Properties.BendingAffectFallingSand.TNTStrengthMultiplier")));
}
return;
}
if (entity instanceof FallingBlock) {
if (ConfigManager.defaultConfig.get().getBoolean("Properties.BendingAffectFallingSand.Normal")) {
entity.setVelocity(velocity.multiply(ConfigManager.defaultConfig.get().getDouble("Properties.BendingAffectFallingSand.NormalStrengthMultiplier")));
}
return;
}
// Attempt to stop velocity from going over the packet cap.
if (velocity.getX() > 4) {
velocity.setX(4);
} else if (velocity.getX() < -4) {
velocity.setX(-4);
}
if (velocity.getY() > 4) {
velocity.setY(4);
} else if (velocity.getY() < -4) {
velocity.setY(-4);
}
if (velocity.getZ() > 4) {
velocity.setZ(4);
} else if (velocity.getZ() < -4) {
velocity.setZ(-4);
}
entity.setVelocity(velocity);
}
public static FallingBlock spawnFallingBlock(Location loc, int type) {
return spawnFallingBlock(loc, type, (byte) 0);
}
public static FallingBlock spawnFallingBlock(Location loc, int type, byte data) {
return loc.getWorld().spawnFallingBlock(loc, type, data);
}
public static FallingBlock spawnFallingBlock(Location loc, Material type) {
return spawnFallingBlock(loc, type, (byte) 0);
}
public static FallingBlock spawnFallingBlock(Location loc, Material type, byte data) {
return loc.getWorld().spawnFallingBlock(loc, type, data);
}
public static void sendBrandingMessage(CommandSender sender, String message) {
ChatColor color;
try {
color = ChatColor.valueOf(ConfigManager.languageConfig.get().getString("Chat.Branding.Color").toUpperCase());
} catch (IllegalArgumentException exception) {
color = ChatColor.GOLD;
}
String prefix = ChatColor.translateAlternateColorCodes('&', ConfigManager.languageConfig.get().getString("Chat.Branding.ChatPrefix.Prefix")) + color + "ProjectKorra" + ChatColor.translateAlternateColorCodes('&', ConfigManager.languageConfig.get().getString("Chat.Branding.ChatPrefix.Suffix"));
if (!(sender instanceof Player)) {
sender.sendMessage(prefix + message);
} else {
TextComponent prefixComponent = new TextComponent(prefix);
prefixComponent.setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, "http://projectkorra.com/"));
prefixComponent.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder(color + "Bending brought to you by ProjectKorra!\n" + color + "Click for more info.").create()));
/*
* The commented code below does not work due to an issue with
* Spigot. In the mean time, we'll have to use this incredibly
* 'hacky' method to force the colour on the new line.
*/
String lastColor = "";
String newMessage = "";
for (int i = 0; i < message.split("").length; i++) {
String c = message.split("")[i];
if (c.equalsIgnoreCase("§")) {
lastColor = "§" + message.split("")[i + 1];
newMessage = newMessage + c;
} else if (c.equalsIgnoreCase(" ")) { //Add color every word
newMessage = newMessage + " " + lastColor;
} else {
newMessage = newMessage + c;
}
}
TextComponent messageComponent = new TextComponent(newMessage);
((Player) sender).spigot().sendMessage(new TextComponent(prefixComponent, messageComponent));
/*
* boolean prefixSent = false; for (String msg :
* message.split("\n")) { if (!prefixSent) { TextComponent
* messageComponent = new TextComponent(msg); ((Player)
* sender).spigot().sendMessage(new TextComponent(prefixComponent,
* messageComponent)); prefixSent = true; } else {
* sender.sendMessage(msg); } }
*/
}
}
public static void startCacheCleaner(final double period) {
new BukkitRunnable() {
@Override
public void run() {
for (Map<Block, BlockCacheElement> map : BLOCK_CACHE.values()) {
for (Iterator<Block> i = map.keySet().iterator(); i.hasNext();) {
Block key = i.next();
BlockCacheElement value = map.get(key);
if (System.currentTimeMillis() - value.getTime() > period) {
map.remove(key);
}
}
}
}
}.runTaskTimer(ProjectKorra.plugin, 0, (long) (period / 20));
}
public static void stopBending() {
for (CoreAbility ability : CoreAbility.getAbilities()) {
if (ability instanceof AddonAbility) {
((AddonAbility) ability).stop();
}
}
CoreAbility.removeAll();
EarthAbility.stopBending();
WaterAbility.stopBending();
FireAbility.stopBending();
Flight.removeAll();
TempBlock.removeAll();
TempArmor.revertAll();
MultiAbilityManager.removeAll();
if (!INVINCIBLE.isEmpty()) {
INVINCIBLE.clear();
}
}
public static void stopPlugin() {
plugin.getServer().getPluginManager().disablePlugin(plugin);
}
public static void writeToDebug(String message) {
try {
File dataFolder = plugin.getDataFolder();
if (!dataFolder.exists()) {
dataFolder.mkdir();
}
File saveTo = new File(plugin.getDataFolder(), "debug.txt");
if (!saveTo.exists()) {
saveTo.createNewFile();
}
FileWriter fw = new FileWriter(saveTo, true);
PrintWriter pw = new PrintWriter(fw);
pw.println(message);
pw.flush();
pw.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
}