main class
+ */
+public abstract class AutoCommand
extends Command {
+
+ private static String VERSION;
+
+ static {
+ String path = Bukkit.getServer().getClass().getPackage().getName();
+ AutoCommand.VERSION = path.substring(path.lastIndexOf(".") + 1, path.length());
+ Core.log(Level.INFO, "AutoCommand hook for Bukkit " + AutoCommand.VERSION);
+ }
+
+ protected final P plugin;
+ protected final String command;
+
+ public AutoCommand(P plugin, String command, String description, String... aliases) {
+ super(command);
+ this.plugin = plugin;
+ this.command = command;
+
+ super.setDescription(description);
+ List aliasList = new ArrayList<>();
+ for (String alias : aliases) {
+ aliasList.add(alias);
+ }
+ super.setAliases(aliasList);
+ this.register();
+ }
+
+ private void register() {
+ try {
+ Field f = Class.forName("org.bukkit.craftbukkit." + AutoCommand.VERSION + ".CraftServer").getDeclaredField("commandMap");
+ f.setAccessible(true);
+
+ CommandMap map = (CommandMap) f.get(Bukkit.getServer());
+ map.register(this.plugin.getName(), this);
+ } catch (Exception exc) {
+ exc.printStackTrace();
+ }
+ }
+
+ public abstract boolean execute(CommandSender sender, String label, String[] args);
+
+ public abstract List tabComplete(CommandSender sender, String label, String[] args);
+
+ public String buildString(String[] args, int start) {
+ String str = "";
+ if (args.length > start) {
+ str += args[start];
+ for (int i = start + 1; i < args.length; i++) {
+ str += " " + args[i];
+ }
+ }
+ return str;
+ }
+
+ public P getPlugin() {
+ return this.plugin;
+ }
+}
diff --git a/src/main/java/eu/univento/core/api/Blackscreen.java b/src/main/java/eu/univento/core/api/Blackscreen.java
new file mode 100644
index 0000000..7091575
--- /dev/null
+++ b/src/main/java/eu/univento/core/api/Blackscreen.java
@@ -0,0 +1,80 @@
+package eu.univento.core.api;
+
+import org.bukkit.Bukkit;
+import org.bukkit.entity.Player;
+import org.bukkit.plugin.Plugin;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+/**
+ *
+ * @author janhektor
+ *
+ */
+public class Blackscreen {
+ private static Object packetObject;
+ private static Class> packetClass;
+ private static String VERSION;
+ private static Map ticksLeft = new HashMap();
+
+ static { String path = Bukkit.getServer().getClass().getPackage().getName();
+ VERSION = path.substring(path.lastIndexOf(".") + 1, path.length());
+ try {
+ packetClass = Class.forName("net.minecraft.server." + VERSION + ".Packet");
+ Class> packetGameStateClass = Class.forName("net.minecraft.server." + VERSION + ".PacketPlayOutGameStateChange");
+ packetObject = packetGameStateClass.getConstructor(new Class[] { Integer.TYPE, Float.TYPE }).newInstance(new Object[] { Integer.valueOf(4), Integer.valueOf(0) });
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ }
+
+ public static void setupUtil(Plugin instance)
+ {
+ setupUtil(instance, 2);
+ }
+
+ public static void setupUtil(Plugin instance, int repeatingTicks)
+ {
+ Bukkit.getScheduler().runTaskTimer(instance, () -> {
+ for (UUID uuid : Blackscreen.ticksLeft.keySet()) {
+ Player p = Bukkit.getPlayer(uuid);
+ if (p == null) {
+ Blackscreen.ticksLeft.remove(uuid);
+ }
+ else if (((Integer)Blackscreen.ticksLeft.get(uuid)).intValue() > 0) {
+ Blackscreen.ticksLeft.put(uuid, Integer.valueOf((Blackscreen.ticksLeft.get(uuid)).intValue() - 2));
+ Blackscreen.access(p);
+ } else {
+ Blackscreen.ticksLeft.remove(uuid);
+ }
+ }
+ }
+ , 0L, repeatingTicks);
+ }
+
+ protected static void access(Player p) {
+
+}
+
+private static void sendPacket(Player p) {
+ try {
+ Object nmsPlayer = p.getClass().getMethod("getHandle", new Class[0]).invoke(p, new Object[0]);
+ Field playerConnectionField = nmsPlayer.getClass().getField("playerConnection");
+ Object pConnection = playerConnectionField.get(nmsPlayer);
+ Method sendPacket = pConnection.getClass().getMethod("sendPacket", new Class[] { packetClass });
+ sendPacket.invoke(pConnection, new Object[] { packetObject });
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ }
+
+ public static void setBlack(Player p, int seconds)
+ {
+ ticksLeft.put(p.getUniqueId(), Integer.valueOf(seconds * 20));
+ sendPacket(p);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/eu/univento/core/api/Config.java b/src/main/java/eu/univento/core/api/Config.java
new file mode 100644
index 0000000..ae6574b
--- /dev/null
+++ b/src/main/java/eu/univento/core/api/Config.java
@@ -0,0 +1,171 @@
+package eu.univento.core.api;
+
+import org.bukkit.Bukkit;
+import org.bukkit.Location;
+import org.bukkit.configuration.file.FileConfiguration;
+import org.bukkit.configuration.file.YamlConfiguration;
+
+import java.io.File;
+import java.io.IOException;
+import java.sql.SQLException;
+
+/**
+ * gets data from config file
+ * @author joethei
+ * @version 1.1
+ */
+public class Config {
+
+ /**config file*/
+ private static File file = new File("plugins/Core", "config.yml");
+ /**load configuration */
+ private static FileConfiguration cfg = YamlConfiguration.loadConfiguration(file);
+
+ /**
+ * write default data to config
+ * @throws ClassNotFoundException Class couldn't be found
+ * @throws SQLException SQL server not available or throwing error
+ * @throws IOException I/O failed
+ */
+ public static void writeDefault() throws ClassNotFoundException, SQLException, IOException {
+ //editable messages will be set here, but do not edit this messages.
+
+ //seting the default MySQL config.
+ cfg.addDefault("MySQL.Host", "192.168.0.101");
+ cfg.addDefault("MySQL.Port", "3306");
+ cfg.addDefault("MySQL.DB", "core");
+ cfg.addDefault("MySQL.User", "root");//best user name
+ cfg.addDefault("MySQL.Pass", "");//best password
+ cfg.addDefault("TS.IP", "ts.univento.eu");
+ cfg.addDefault("TS.QueryPort", 0);
+ cfg.addDefault("TS.QueryUser", "ServerQuery");
+ cfg.addDefault("TS.QueryPass", "password");
+
+ cfg.options().copyDefaults(true);
+ cfg.save(file);
+
+ }
+
+ /**
+ * write data as string to config
+ * @param path path to data
+ * @param obj data
+ */
+ public static void write(String path, String obj) {
+ cfg.set(path, obj);
+ try {
+ cfg.save(file);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * write data as integer to config
+ * @param path path to data
+ * @param obj data
+ */
+ public static void write(String path, int obj) {
+ cfg.set(path, obj);
+ try {
+ cfg.save(file);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * write data as double to config
+ * @param path path to data
+ * @param obj data
+ */
+ public static void write(String path, double obj) {
+ cfg.set(path, obj);
+ try {
+ cfg.save(file);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+
+ /**
+ * write location to config
+ * @param path path to data
+ * @param loc location
+ */
+ public static void write(String path, Location loc) {
+ String world = loc.getWorld().getName();
+ double x = loc.getX();
+ double y = loc.getY();
+ double z = loc.getZ();
+ double yaw = (double) loc.getYaw();
+ double pitch = (double) loc.getPitch();
+
+ cfg.set(path + ".World", world);
+ cfg.set(path + ".X", x);
+ cfg.set(path + ".Y", y);
+ cfg.set(path + ".Z", z);
+ cfg.set(path + ".Yaw", yaw);
+ cfg.set(path + ".Pitch", pitch);
+
+ try {
+ cfg.save(file);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * read integer from config
+ * @param path path to data
+ * @return Integer
+ */
+ public static int readInt(String path) {
+ return cfg.getInt(path);
+ }
+
+ /**
+ * read double from config
+ * @param path path to data
+ * @return Double
+ */
+ public static double readDouble(String path) {
+ return cfg.getDouble(path);
+ }
+
+ /**
+ * read string from config
+ * @param path path to data
+ * @return String
+ */
+ public static String readString(String path) {
+ return cfg.getString(path);
+ }
+
+ /**
+ * read location from config
+ * @param path path to data
+ * @return Location
+ */
+ public static Location readLocation(String path) {
+ String world = cfg.getString(path + ".World");
+ double x = cfg.getDouble(path + ".X");
+ double y = cfg.getDouble(path + ".Y");
+ double z = cfg.getDouble(path + ".Z");
+ float yaw = (float) cfg.getDouble(path + ".Yaw");
+ float pitch = (float) cfg.getDouble(path + ".Pitch");
+
+ return new Location(Bukkit.getWorld(world), x, y, z, yaw, pitch);
+ }
+
+ /**
+ * checks if data is existing
+ * @param path path do data
+ * @return true / false
+ */
+ public static boolean isExsisting(String path) {
+ return cfg.contains(path);
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/eu/univento/core/api/Hologram.java b/src/main/java/eu/univento/core/api/Hologram.java
new file mode 100644
index 0000000..5fcf3bc
--- /dev/null
+++ b/src/main/java/eu/univento/core/api/Hologram.java
@@ -0,0 +1,93 @@
+package eu.univento.core.api;
+
+import eu.univento.core.Core;
+import net.minecraft.server.v1_9_R1.EntityArmorStand;
+import net.minecraft.server.v1_9_R1.PacketPlayOutEntityDestroy;
+import net.minecraft.server.v1_9_R1.PacketPlayOutSpawnEntityLiving;
+import org.bukkit.Bukkit;
+import org.bukkit.Location;
+import org.bukkit.craftbukkit.v1_9_R1.CraftWorld;
+import org.bukkit.craftbukkit.v1_9_R1.entity.CraftPlayer;
+import org.bukkit.entity.Player;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Hologram {
+
+ private List entitylist = new ArrayList<>();
+ private String[] Text;
+ private Location location;
+ double DISTANCE = 0.25D;
+ int count;
+
+ public Hologram(String[] Text, Location location) {
+ this.Text = Text;
+ this.location = location;
+ create();
+ }
+
+
+ public void showPlayerTemp(final Player p,int Time){
+ showPlayer(p);
+ Bukkit.getScheduler().runTaskLater(Core.getInstance(), () -> hidePlayer(p), Time);
+ }
+
+
+ public void showAllTemp(final Player p,int Time){
+ showAll();
+ Bukkit.getScheduler().runTaskLater(Core.getInstance(), () -> hideAll(), Time);
+ }
+
+ public void showPlayer(Player p) {
+ for (EntityArmorStand armor : entitylist) {
+ PacketPlayOutSpawnEntityLiving packet = new PacketPlayOutSpawnEntityLiving(armor);
+ ((CraftPlayer) p).getHandle().playerConnection.sendPacket(packet);
+ }
+ }
+
+ public void hidePlayer(Player p) {
+ for (EntityArmorStand armor : entitylist) {
+ PacketPlayOutEntityDestroy packet = new PacketPlayOutEntityDestroy(armor.getId());
+ ((CraftPlayer) p).getHandle().playerConnection.sendPacket(packet);
+
+ }
+ }
+
+ public void showAll() {
+ for (Player player : Bukkit.getOnlinePlayers()) {
+ for (EntityArmorStand armor : entitylist) {
+ PacketPlayOutSpawnEntityLiving packet = new PacketPlayOutSpawnEntityLiving(armor);
+ ((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet);
+ }
+ }
+ }
+
+ public void hideAll() {
+ for (Player player : Bukkit.getOnlinePlayers()) {
+ for (EntityArmorStand armor : entitylist) {
+ PacketPlayOutEntityDestroy packet = new PacketPlayOutEntityDestroy(armor.getId());
+ ((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet);
+ }
+ }
+ }
+
+ private void create() {
+ for (String Text : this.Text) {
+ EntityArmorStand entity = new EntityArmorStand(((CraftWorld) this.location.getWorld()).getHandle(),this.location.getX(), this.location.getY(),this.location.getZ());
+ entity.setCustomName(Text);
+ entity.setCustomNameVisible(true);
+ entity.setInvisible(true);
+ entity.setGravity(false);
+ entitylist.add(entity);
+ this.location.subtract(0, this.DISTANCE, 0);
+ count++;
+ }
+
+ for (int i = 0; i < count; i++) {
+ this.location.add(0, this.DISTANCE, 0);
+ }
+ this.count = 0;
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/eu/univento/core/api/Title.java b/src/main/java/eu/univento/core/api/Title.java
new file mode 100644
index 0000000..81f9db1
--- /dev/null
+++ b/src/main/java/eu/univento/core/api/Title.java
@@ -0,0 +1,85 @@
+package eu.univento.core.api;
+
+import net.minecraft.server.v1_9_R1.IChatBaseComponent;
+import net.minecraft.server.v1_9_R1.PacketPlayOutPlayerListHeaderFooter;
+import net.minecraft.server.v1_9_R1.PacketPlayOutTitle;
+import net.minecraft.server.v1_9_R1.PlayerConnection;
+import org.bukkit.ChatColor;
+import org.bukkit.craftbukkit.v1_9_R1.entity.CraftPlayer;
+import org.bukkit.entity.Player;
+
+import java.lang.reflect.Field;
+
+//TODO: find real author, its not me
+/**
+ * sends title to player
+ * @author joethei
+ * @version 1.0
+ */
+public class Title {
+
+ /**
+ * send title to player
+ * @param player Player
+ * @param fadeIn Integer
+ * @param stay Integer
+ * @param fadeOut Integer
+ * @param title String
+ * @param subtitle String
+ */
+ public static void sendTitle(Player player, Integer fadeIn, Integer stay, Integer fadeOut, String title, String subtitle) {
+ PlayerConnection connection = ((CraftPlayer) player).getHandle().playerConnection;
+
+ PacketPlayOutTitle packetPlayOutTimes = new PacketPlayOutTitle(PacketPlayOutTitle.EnumTitleAction.TIMES, null, fadeIn, stay, fadeOut);
+ connection.sendPacket(packetPlayOutTimes);
+
+ if (subtitle != null) {
+ subtitle = subtitle.replaceAll("%player%", player.getDisplayName());
+ subtitle = ChatColor.translateAlternateColorCodes('&', subtitle);
+ IChatBaseComponent titleSub = IChatBaseComponent.ChatSerializer.a("{\"text\": \"" + subtitle + "\"}");
+ PacketPlayOutTitle packetPlayOutSubTitle = new PacketPlayOutTitle(PacketPlayOutTitle.EnumTitleAction.SUBTITLE, titleSub);
+ connection.sendPacket(packetPlayOutSubTitle);
+ }
+
+ if (title != null) {
+ title = title.replaceAll("%player%", player.getDisplayName());
+ title = ChatColor.translateAlternateColorCodes('&', title);
+ IChatBaseComponent titleMain = IChatBaseComponent.ChatSerializer.a("{\"text\": \"" + title + "\"}");
+ PacketPlayOutTitle packetPlayOutTitle = new PacketPlayOutTitle(PacketPlayOutTitle.EnumTitleAction.TITLE, titleMain);
+ connection.sendPacket(packetPlayOutTitle);
+ }
+ }
+
+ /**
+ * sends tab title to player
+ * @param player Player
+ * @param header String
+ * @param footer String
+ */
+ public static void sendTabTitle(Player player, String header, String footer) {
+ if (header == null)
+ header = "";
+ header = ChatColor.translateAlternateColorCodes('&', header);
+
+ if (footer == null)
+ footer = "";
+ footer = ChatColor.translateAlternateColorCodes('&', footer);
+
+ header = header.replaceAll("%player%", player.getDisplayName());
+ footer = footer.replaceAll("%player%", player.getDisplayName());
+
+ PlayerConnection connection = ((CraftPlayer) player).getHandle().playerConnection;
+ IChatBaseComponent tabTitle = IChatBaseComponent.ChatSerializer.a("{\"text\": \"" + header + "\"}");
+ IChatBaseComponent tabFoot = IChatBaseComponent.ChatSerializer.a("{\"text\": \"" + footer + "\"}");
+ PacketPlayOutPlayerListHeaderFooter headerPacket = new PacketPlayOutPlayerListHeaderFooter(tabTitle);
+ try {
+ Field field = headerPacket.getClass().getDeclaredField("b");
+ field.setAccessible(true);
+ field.set(headerPacket, tabFoot);
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ connection.sendPacket(headerPacket);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/eu/univento/core/api/Utils.java b/src/main/java/eu/univento/core/api/Utils.java
new file mode 100644
index 0000000..a6885fe
--- /dev/null
+++ b/src/main/java/eu/univento/core/api/Utils.java
@@ -0,0 +1,176 @@
+package eu.univento.core.api;
+
+import eu.univento.core.Core;
+import org.bukkit.*;
+import org.bukkit.entity.Entity;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.potion.PotionEffect;
+import org.bukkit.util.Vector;
+
+import java.io.File;
+import java.util.List;
+
+/**
+ * some utils you may need
+ * @author joethei
+ * @version 1.0
+ */
+public class Utils {
+
+ /**
+ * plays sound for all players
+ * @param s Sound
+ */
+ public static void playSoundToAll(Sound s) {
+ for (Player all : Bukkit.getOnlinePlayers())
+ all.playSound(all.getLocation(), s, 3.0F, 3.0F);
+ }
+
+ /**
+ * plays effect for all players
+ * @param e Effect
+ */
+ @SuppressWarnings("deprecation")
+ public static void playEffectToAll(Effect e) {
+ for (Player all : Bukkit.getOnlinePlayers())
+ all.playEffect(all.getLocation(), e, 3);
+ }
+
+ /**
+ * checks if server version is from spigot
+ * @return true/false
+ */
+ public static boolean isSpigot() {
+ return Bukkit.getVersion().contains("Spigot");
+ }
+
+ /**
+ * deletes all folders and files in directory
+ * @param file File
+ */
+ public static void deleteDir(File file) {
+ if (file.isDirectory()) {
+ if (file.list().length == 0) {
+ file.delete();
+ } else {
+ String[] files = file.list();
+ for (String tmp : files) {
+ File fileDelete = new File(file, tmp);
+ deleteDir(fileDelete);
+ }
+ if (file.list().length == 0)
+ file.delete();
+ }
+ } else
+ file.delete();
+ }
+
+ /**
+ * creates a random number
+ * @param low lowest possible value
+ * @param high highest possible value
+ * @return double
+ */
+ public static double random(int low, int high) {
+ return Math.random() * (high - low) + low;
+ }
+
+ /**
+ * checks if player has empty inventory
+ * @param p Player
+ * @return true/false
+ */
+ public static boolean hasEmptyInventory(Player p) {
+ for (ItemStack item : p.getInventory().getContents()) {
+ if ((item != null) && (item.getType() != Material.AIR))
+ return false;
+ }
+ for (ItemStack item : p.getInventory().getArmorContents()) {
+ if ((item != null) && (item.getType() != Material.AIR))
+ return false;
+ }
+ return true;
+ }
+
+
+ /**
+ * removes list of entity and counts them
+ * @param e List
+ * @return Integer
+ */
+ public static int removeEntitys(List e) {
+ int i = 0;
+ for (Entity en : e) {
+ en.remove();
+ i++;
+ }
+ return i;
+ }
+
+ /**
+ * clears all potion effects from player
+ * @param player Player
+ */
+ public static void clearPotionEffects(Player player) {
+ for (PotionEffect effect : player.getActivePotionEffects())
+ player.removePotionEffect(effect.getType());
+ }
+
+ /**
+ * calculates vector from one location to another
+ * @param from Location
+ * @param to Location
+ * @return Vector
+ */
+ public static Vector calculateVector(Location from, Location to) {
+ Location b = to;
+
+ // calculate the distance between the locations (a => from || b => to)
+ double dX = from.getX() - b.getX();
+ double dY = from.getY() - b.getY();
+ double dZ = from.getZ() - b.getZ();
+ // -------------------------
+
+ // calculate the yaw
+ double yaw = Math.atan2(dZ, dX);
+ // -------------------------
+
+ // calculate the pitch
+ double pitch = Math.atan2(Math.sqrt(dZ * dZ + dX * dX), dY) + Math.PI;
+ // -------------------------
+
+ // calculate and create the new vector
+ double x = Math.sin(pitch) * Math.cos(yaw);
+ double y = Math.sin(pitch) * Math.sin(yaw);
+ double z = Math.cos(pitch);
+
+ // -------------------------
+
+ return new Vector(x, z, y);
+ }
+
+ /**
+ * restarts server
+ */
+ public static void restart() {
+ Bukkit.getScheduler().scheduleSyncDelayedTask(Core.getInstance(), new Runnable() {
+
+ @Override
+ public void run() {
+ Bukkit.getServer().spigot().restart();
+ }
+
+ }, 10 * 20L);
+ }
+
+ /**
+ * shots random firework at specified location
+ * @param loc Location
+ */
+ public static void randomFirework(Location loc) {
+ FireworkEffect.Builder builder = FireworkEffect.builder();
+ FireworkEffect effect = builder.flicker(false).trail(false).with(FireworkEffect.Type.BALL_LARGE).withColor(Color.RED).withFade(Color.BLUE).build();
+ //TODO: make a random fireworks effect
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/eu/univento/core/api/database/Database.java b/src/main/java/eu/univento/core/api/database/Database.java
new file mode 100644
index 0000000..76fa156
--- /dev/null
+++ b/src/main/java/eu/univento/core/api/database/Database.java
@@ -0,0 +1,72 @@
+package eu.univento.core.api.database;
+
+import org.bukkit.plugin.Plugin;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+public abstract class Database
+{
+ protected Connection connection;
+ protected Plugin plugin;
+
+ protected Database(Plugin plugin)
+ {
+ this.plugin = plugin;
+ this.connection = null;
+ }
+
+ public abstract Connection openConnection()
+ throws SQLException, ClassNotFoundException;
+
+ public boolean checkConnection()
+ throws SQLException
+ {
+ return (this.connection != null) && (!this.connection.isClosed());
+ }
+
+ public Connection getConnection()
+ {
+ return this.connection;
+ }
+
+ public boolean closeConnection()
+ throws SQLException
+ {
+ if (this.connection == null) {
+ return false;
+ }
+ this.connection.close();
+ return true;
+ }
+
+ public ResultSet querySQL(String query)
+ throws SQLException, ClassNotFoundException
+ {
+ if (!checkConnection()) {
+ openConnection();
+ }
+
+ Statement statement = this.connection.createStatement();
+
+ ResultSet result = statement.executeQuery(query);
+
+ return result;
+ }
+
+ public int updateSQL(String query)
+ throws SQLException, ClassNotFoundException
+ {
+ if (!checkConnection()) {
+ openConnection();
+ }
+
+ Statement statement = this.connection.createStatement();
+
+ int result = statement.executeUpdate(query);
+
+ return result;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/eu/univento/core/api/database/MySQL.java b/src/main/java/eu/univento/core/api/database/MySQL.java
new file mode 100644
index 0000000..7f8353d
--- /dev/null
+++ b/src/main/java/eu/univento/core/api/database/MySQL.java
@@ -0,0 +1,36 @@
+package eu.univento.core.api.database;
+
+import org.bukkit.plugin.Plugin;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+
+public class MySQL extends Database
+{
+ private final String user;
+ private final String database;
+ private final String password;
+ private final String port;
+ private final String hostname;
+
+ public MySQL(Plugin plugin, String hostname, String port, String database, String username, String password) {
+ super(plugin);
+ this.hostname = hostname;
+ this.port = port;
+ this.database = database;
+ this.user = username;
+ this.password = password;
+ }
+
+ public Connection openConnection() throws SQLException, ClassNotFoundException {
+ if (checkConnection()) {
+ return this.connection;
+ }
+ Class.forName("com.mysql.jdbc.Driver");
+ this.connection = DriverManager.getConnection("jdbc:mysql://" +
+ this.hostname + ":" + this.port + "/" + this.database,
+ this.user, this.password);
+ return this.connection;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/eu/univento/core/api/database/SQLite.java b/src/main/java/eu/univento/core/api/database/SQLite.java
new file mode 100644
index 0000000..51961a1
--- /dev/null
+++ b/src/main/java/eu/univento/core/api/database/SQLite.java
@@ -0,0 +1,47 @@
+package eu.univento.core.api.database;
+
+import org.bukkit.plugin.Plugin;
+
+import java.io.File;
+import java.io.IOException;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.util.logging.Level;
+
+public class SQLite extends Database
+{
+ private final String dbLocation;
+
+ public SQLite(Plugin plugin, String dbLocation)
+ {
+ super(plugin);
+ this.dbLocation = dbLocation;
+ }
+
+ public Connection openConnection()
+ throws SQLException, ClassNotFoundException
+ {
+ if (checkConnection()) {
+ return this.connection;
+ }
+ if (!this.plugin.getDataFolder().exists()) {
+ this.plugin.getDataFolder().mkdirs();
+ }
+ File file = new File(this.plugin.getDataFolder(), this.dbLocation);
+ if (!file.exists()) {
+ try {
+ file.createNewFile();
+ } catch (IOException e) {
+ this.plugin.getLogger().log(Level.SEVERE,
+ "Unable to create database!");
+ }
+ }
+ Class.forName("org.sqlite.JDBC");
+ this.connection =
+ DriverManager.getConnection("jdbc:sqlite:" +
+ this.plugin.getDataFolder().toPath().toString() + "/" +
+ this.dbLocation);
+ return this.connection;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/eu/univento/core/api/effects/Effects.java b/src/main/java/eu/univento/core/api/effects/Effects.java
new file mode 100644
index 0000000..d5fb373
--- /dev/null
+++ b/src/main/java/eu/univento/core/api/effects/Effects.java
@@ -0,0 +1,36 @@
+package eu.univento.core.api.effects;
+
+import eu.univento.core.api.player.PlayerSettings;
+import net.minecraft.server.v1_9_R1.EnumParticle;
+import net.minecraft.server.v1_9_R1.PacketPlayOutWorldParticles;
+import org.bukkit.Location;
+import org.bukkit.craftbukkit.v1_9_R1.entity.CraftPlayer;
+import org.bukkit.entity.Player;
+
+/**
+ * some better effects
+ * @author joethei
+ * @version 1.0
+ */
+public class Effects {
+
+ /**
+ * plays effects from location
+ * @param loc Location
+ * @param ep EnumParticle
+ * @param f float of particles
+ * @param count count of particles
+ */
+ public static void playEffect(Location loc, EnumParticle ep, float f, int count) {
+ PacketPlayOutWorldParticles packet = new PacketPlayOutWorldParticles(ep, true, (float) loc.getX(), (float) loc.getY(), (float) loc.getZ(), f, f, f, 0.0F, count, 0, 0);
+ for(Player p : PlayerSettings.getAllPlayersWithEffectsEnabled()) {
+ ((CraftPlayer)p).getHandle().playerConnection.sendPacket(packet);
+ }
+ }
+
+ public static void playEffectToPlayer(Player p, Location loc, EnumParticle ep, float f, int count) {
+ PacketPlayOutWorldParticles packet = new PacketPlayOutWorldParticles(ep, true, (float) loc.getX(), (float) loc.getY(), (float) loc.getZ(), f, f, f, 0.0F, count, 0, 0);
+ ((CraftPlayer)p).getHandle().playerConnection.sendPacket(packet);
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/eu/univento/core/api/effects/ParticleEffect.java b/src/main/java/eu/univento/core/api/effects/ParticleEffect.java
new file mode 100644
index 0000000..14c4e9e
--- /dev/null
+++ b/src/main/java/eu/univento/core/api/effects/ParticleEffect.java
@@ -0,0 +1,1606 @@
+package eu.univento.core.api.effects;
+
+import eu.univento.core.api.utils.reflection.ReflectionUtils;
+import eu.univento.core.api.utils.reflection.ReflectionUtils.PackageType;
+import org.bukkit.Bukkit;
+import org.bukkit.Color;
+import org.bukkit.Location;
+import org.bukkit.Material;
+import org.bukkit.entity.Player;
+import org.bukkit.util.Vector;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+/**
+ * ParticleEffect Library
+ *
+ * This library was created by @DarkBlade12 and allows you to display all Minecraft particle effects on a Bukkit server
+ *
+ * You are welcome to use it, modify it and redistribute it under the following conditions:
+ *
+ *
Don't claim this class as your own
+ *
Don't remove this disclaimer
+ *
+ *
+ * Special thanks:
+ *
+ *
@microgeek (original idea, names and packet parameters)
+ *
@ShadyPotato (1.8 names, ids and packet parameters)
+ *
@RingOfStorms (particle behavior)
+ *
@Cybermaxke (particle behavior)
+ *
@JamieSinn (hosting a jenkins server and documentation for particleeffect)
+ *
+ *
+ * It would be nice if you provide credit to me if you use this class in a published project
+ *
+ * @author DarkBlade12
+ * @version 1.7
+ */
+public enum ParticleEffect {
+ /**
+ * A particle effect which is displayed by exploding tnt and creepers:
+ *
+ *
It looks like a white cloud
+ *
The speed value influences the velocity at which the particle flies off
+ *
+ */
+ EXPLOSION_NORMAL("explode", 0, -1, ParticleProperty.DIRECTIONAL),
+ /**
+ * A particle effect which is displayed by exploding ghast fireballs and wither skulls:
+ *
+ *
It looks like a gray ball which is fading away
+ *
The speed value slightly influences the size of this particle effect
+ *
+ */
+ EXPLOSION_LARGE("largeexplode", 1, -1),
+ /**
+ * A particle effect which is displayed by exploding tnt and creepers:
+ *
+ *
It looks like a crowd of gray balls which are fading away
+ *
The speed value has no influence on this particle effect
+ *
+ */
+ EXPLOSION_HUGE("hugeexplosion", 2, -1),
+ /**
+ * A particle effect which is displayed by launching fireworks:
+ *
+ *
It looks like a white star which is sparkling
+ *
The speed value influences the velocity at which the particle flies off
+ *
+ */
+ FIREWORKS_SPARK("fireworksSpark", 3, -1, ParticleProperty.DIRECTIONAL),
+ /**
+ * A particle effect which is displayed by swimming entities and arrows in water:
+ *
+ *
It looks like a bubble
+ *
The speed value influences the velocity at which the particle flies off
+ *
+ */
+ WATER_BUBBLE("bubble", 4, -1, ParticleProperty.DIRECTIONAL, ParticleProperty.REQUIRES_WATER),
+ /**
+ * A particle effect which is displayed by swimming entities and shaking wolves:
+ *
+ *
It looks like a blue drop
+ *
The speed value has no influence on this particle effect
+ *
+ */
+ WATER_SPLASH("splash", 5, -1, ParticleProperty.DIRECTIONAL),
+ /**
+ * A particle effect which is displayed on water when fishing:
+ *
+ *
It looks like a blue droplet
+ *
The speed value influences the velocity at which the particle flies off
+ *
+ */
+ WATER_WAKE("wake", 6, 7, ParticleProperty.DIRECTIONAL),
+ /**
+ * A particle effect which is displayed by water:
+ *
+ *
It looks like a tiny blue square
+ *
The speed value has no influence on this particle effect
+ *
+ */
+ SUSPENDED("suspended", 7, -1, ParticleProperty.REQUIRES_WATER),
+ /**
+ * A particle effect which is displayed by air when close to bedrock and the in the void:
+ *
+ *
It looks like a tiny gray square
+ *
The speed value has no influence on this particle effect
+ *
+ */
+ SUSPENDED_DEPTH("depthSuspend", 8, -1, ParticleProperty.DIRECTIONAL),
+ /**
+ * A particle effect which is displayed when landing a critical hit and by arrows:
+ *
+ *
It looks like a light brown cross
+ *
The speed value influences the velocity at which the particle flies off
+ *
+ */
+ CRIT("crit", 9, -1, ParticleProperty.DIRECTIONAL),
+ /**
+ * A particle effect which is displayed when landing a hit with an enchanted weapon:
+ *
+ *
It looks like a cyan star
+ *
The speed value influences the velocity at which the particle flies off
+ *
+ */
+ CRIT_MAGIC("magicCrit", 10, -1, ParticleProperty.DIRECTIONAL),
+ /**
+ * A particle effect which is displayed by primed tnt, torches, droppers, dispensers, end portals, brewing stands and monster spawners:
+ *
+ *
It looks like a little gray cloud
+ *
The speed value influences the velocity at which the particle flies off
+ *
+ */
+ SMOKE_NORMAL("smoke", 11, -1, ParticleProperty.DIRECTIONAL),
+ /**
+ * A particle effect which is displayed by fire, minecarts with furnace and blazes:
+ *
+ *
It looks like a large gray cloud
+ *
The speed value influences the velocity at which the particle flies off
+ *
+ */
+ SMOKE_LARGE("largesmoke", 12, -1, ParticleProperty.DIRECTIONAL),
+ /**
+ * A particle effect which is displayed when splash potions or bottles o' enchanting hit something:
+ *
+ *
It looks like a white swirl
+ *
The speed value causes the particle to only move upwards when set to 0
+ *
Only the motion on the y-axis can be controlled, the motion on the x- and z-axis are multiplied by 0.1 when setting the values to 0
+ *
+ */
+ SPELL("spell", 13, -1),
+ /**
+ * A particle effect which is displayed when instant splash potions hit something:
+ *
+ *
It looks like a white cross
+ *
The speed value causes the particle to only move upwards when set to 0
+ *
Only the motion on the y-axis can be controlled, the motion on the x- and z-axis are multiplied by 0.1 when setting the values to 0
+ *
+ */
+ SPELL_INSTANT("instantSpell", 14, -1),
+ /**
+ * A particle effect which is displayed by entities with active potion effects:
+ *
+ *
It looks like a colored swirl
+ *
The speed value causes the particle to be colored black when set to 0
+ *
The particle color gets lighter when increasing the speed and darker when decreasing the speed
+ *
+ */
+ SPELL_MOB("mobSpell", 15, -1, ParticleProperty.COLORABLE),
+ /**
+ * A particle effect which is displayed by entities with active potion effects applied through a beacon:
+ *
+ *
It looks like a transparent colored swirl
+ *
The speed value causes the particle to be always colored black when set to 0
+ *
The particle color gets lighter when increasing the speed and darker when decreasing the speed
+ *
+ */
+ SPELL_MOB_AMBIENT("mobSpellAmbient", 16, -1, ParticleProperty.COLORABLE),
+ /**
+ * A particle effect which is displayed by witches:
+ *
+ *
It looks like a purple cross
+ *
The speed value causes the particle to only move upwards when set to 0
+ *
Only the motion on the y-axis can be controlled, the motion on the x- and z-axis are multiplied by 0.1 when setting the values to 0
+ *
+ */
+ SPELL_WITCH("witchMagic", 17, -1),
+ /**
+ * A particle effect which is displayed by blocks beneath a water source:
+ *
+ *
It looks like a blue drip
+ *
The speed value has no influence on this particle effect
+ *
+ */
+ DRIP_WATER("dripWater", 18, -1),
+ /**
+ * A particle effect which is displayed by blocks beneath a lava source:
+ *
+ *
It looks like an orange drip
+ *
The speed value has no influence on this particle effect
+ *
+ */
+ DRIP_LAVA("dripLava", 19, -1),
+ /**
+ * A particle effect which is displayed when attacking a villager in a village:
+ *
+ *
It looks like a cracked gray heart
+ *
The speed value has no influence on this particle effect
+ *
+ */
+ VILLAGER_ANGRY("angryVillager", 20, -1),
+ /**
+ * A particle effect which is displayed when using bone meal and trading with a villager in a village:
+ *
+ *
It looks like a green star
+ *
The speed value has no influence on this particle effect
+ *
+ */
+ VILLAGER_HAPPY("happyVillager", 21, -1, ParticleProperty.DIRECTIONAL),
+ /**
+ * A particle effect which is displayed by mycelium:
+ *
+ *
It looks like a tiny gray square
+ *
The speed value has no influence on this particle effect
+ *
+ */
+ TOWN_AURA("townaura", 22, -1, ParticleProperty.DIRECTIONAL),
+ /**
+ * A particle effect which is displayed by note blocks:
+ *
+ *
It looks like a colored note
+ *
The speed value causes the particle to be colored green when set to 0
+ *
+ */
+ NOTE("note", 23, -1, ParticleProperty.COLORABLE),
+ /**
+ * A particle effect which is displayed by nether portals, endermen, ender pearls, eyes of ender, ender chests and dragon eggs:
+ *
+ *
It looks like a purple cloud
+ *
The speed value influences the spread of this particle effect
+ *
+ */
+ PORTAL("portal", 24, -1, ParticleProperty.DIRECTIONAL),
+ /**
+ * A particle effect which is displayed by enchantment tables which are nearby bookshelves:
+ *
+ *
It looks like a cryptic white letter
+ *
The speed value influences the spread of this particle effect
+ *
+ */
+ ENCHANTMENT_TABLE("enchantmenttable", 25, -1, ParticleProperty.DIRECTIONAL),
+ /**
+ * A particle effect which is displayed by torches, active furnaces, magma cubes and monster spawners:
+ *
+ *
It looks like a tiny flame
+ *
The speed value influences the velocity at which the particle flies off
+ *
+ */
+ FLAME("flame", 26, -1, ParticleProperty.DIRECTIONAL),
+ /**
+ * A particle effect which is displayed by lava:
+ *
+ *
It looks like a spark
+ *
The speed value has no influence on this particle effect
+ *
+ */
+ LAVA("lava", 27, -1),
+ /**
+ * A particle effect which is currently unused:
+ *
+ *
It looks like a transparent gray square
+ *
The speed value has no influence on this particle effect
+ *
+ */
+ FOOTSTEP("footstep", 28, -1),
+ /**
+ * A particle effect which is displayed when a mob dies:
+ *
+ *
It looks like a large white cloud
+ *
The speed value influences the velocity at which the particle flies off
+ *
+ */
+ CLOUD("cloud", 29, -1, ParticleProperty.DIRECTIONAL),
+ /**
+ * A particle effect which is displayed by redstone ore, powered redstone, redstone torches and redstone repeaters:
+ *
+ *
It looks like a tiny colored cloud
+ *
The speed value causes the particle to be colored red when set to 0
+ *
+ */
+ REDSTONE("reddust", 30, -1, ParticleProperty.COLORABLE),
+ /**
+ * A particle effect which is displayed when snowballs hit a block:
+ *
+ *
It looks like a little piece with the snowball texture
+ *
The speed value has no influence on this particle effect
+ *
+ */
+ SNOWBALL("snowballpoof", 31, -1),
+ /**
+ * A particle effect which is currently unused:
+ *
+ *
It looks like a tiny white cloud
+ *
The speed value influences the velocity at which the particle flies off
+ *
+ */
+ SNOW_SHOVEL("snowshovel", 32, -1, ParticleProperty.DIRECTIONAL),
+ /**
+ * A particle effect which is displayed by slimes:
+ *
+ *
It looks like a tiny part of the slimeball icon
+ *
The speed value has no influence on this particle effect
+ *
+ */
+ SLIME("slime", 33, -1),
+ /**
+ * A particle effect which is displayed when breeding and taming animals:
+ *
+ *
It looks like a red heart
+ *
The speed value has no influence on this particle effect
+ *
+ */
+ HEART("heart", 34, -1),
+ /**
+ * A particle effect which is displayed by barriers:
+ *
+ *
It looks like a red box with a slash through it
+ *
The speed value has no influence on this particle effect
+ *
+ */
+ BARRIER("barrier", 35, 8),
+ /**
+ * A particle effect which is displayed when breaking a tool or eggs hit a block:
+ *
+ *
It looks like a little piece with an item texture
+ *
+ */
+ ITEM_CRACK("iconcrack", 36, -1, ParticleProperty.DIRECTIONAL, ParticleProperty.REQUIRES_DATA),
+ /**
+ * A particle effect which is displayed when breaking blocks or sprinting:
+ *
+ *
It looks like a little piece with a block texture
+ *
The speed value has no influence on this particle effect
+ *
+ */
+ BLOCK_CRACK("blockcrack", 37, -1, ParticleProperty.REQUIRES_DATA),
+ /**
+ * A particle effect which is displayed when falling:
+ *
+ *
It looks like a little piece with a block texture
+ *
+ */
+ BLOCK_DUST("blockdust", 38, 7, ParticleProperty.DIRECTIONAL, ParticleProperty.REQUIRES_DATA),
+ /**
+ * A particle effect which is displayed when rain hits the ground:
+ *
+ *
It looks like a blue droplet
+ *
The speed value has no influence on this particle effect
+ *
+ */
+ WATER_DROP("droplet", 39, 8),
+ /**
+ * A particle effect which is currently unused:
+ *
+ *
It has no visual effect
+ *
+ */
+ ITEM_TAKE("take", 40, 8),
+ /**
+ * A particle effect which is displayed by elder guardians:
+ *
+ *
It looks like the shape of the elder guardian
+ *
The speed value has no influence on this particle effect
+ *
The offset values have no influence on this particle effect
+ *
+ */
+ MOB_APPEARANCE("mobappearance", 41, 8);
+
+ private static final Map NAME_MAP = new HashMap();
+ private static final Map ID_MAP = new HashMap();
+ private final String name;
+ private final int id;
+ private final int requiredVersion;
+ private final List properties;
+
+ // Initialize map for quick name and id lookup
+ static {
+ for (ParticleEffect effect : values()) {
+ NAME_MAP.put(effect.name, effect);
+ ID_MAP.put(effect.id, effect);
+ }
+ }
+
+ /**
+ * Construct a new particle effect
+ *
+ * @param name Name of this particle effect
+ * @param id Id of this particle effect
+ * @param requiredVersion Version which is required (1.x)
+ * @param properties Properties of this particle effect
+ */
+ private ParticleEffect(String name, int id, int requiredVersion, ParticleProperty... properties) {
+ this.name = name;
+ this.id = id;
+ this.requiredVersion = requiredVersion;
+ this.properties = Arrays.asList(properties);
+ }
+
+ /**
+ * Returns the name of this particle effect
+ *
+ * @return The name
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Returns the id of this particle effect
+ *
+ * @return The id
+ */
+ public int getId() {
+ return id;
+ }
+
+ /**
+ * Returns the required version for this particle effect (1.x)
+ *
+ * @return The required version
+ */
+ public int getRequiredVersion() {
+ return requiredVersion;
+ }
+
+ /**
+ * Determine if this particle effect has a specific property
+ *
+ * @return Whether it has the property or not
+ */
+ public boolean hasProperty(ParticleProperty property) {
+ return properties.contains(property);
+ }
+
+ /**
+ * Determine if this particle effect is supported by your current server version
+ *
+ * @return Whether the particle effect is supported or not
+ */
+ public boolean isSupported() {
+ if (requiredVersion == -1) {
+ return true;
+ }
+ return ParticlePacket.getVersion() >= requiredVersion;
+ }
+
+ /**
+ * Returns the particle effect with the given name
+ *
+ * @param name Name of the particle effect
+ * @return The particle effect
+ */
+ public static ParticleEffect fromName(String name) {
+ for (Entry entry : NAME_MAP.entrySet()) {
+ if (!entry.getKey().equalsIgnoreCase(name)) {
+ continue;
+ }
+ return entry.getValue();
+ }
+ return null;
+ }
+
+ /**
+ * Returns the particle effect with the given id
+ *
+ * @param id Id of the particle effect
+ * @return The particle effect
+ */
+ public static ParticleEffect fromId(int id) {
+ for (Entry entry : ID_MAP.entrySet()) {
+ if (entry.getKey() != id) {
+ continue;
+ }
+ return entry.getValue();
+ }
+ return null;
+ }
+
+ /**
+ * Determine if water is at a certain location
+ *
+ * @param location Location to check
+ * @return Whether water is at this location or not
+ */
+ private static boolean isWater(Location location) {
+ Material material = location.getBlock().getType();
+ return material == Material.WATER || material == Material.STATIONARY_WATER;
+ }
+
+ /**
+ * Determine if the distance between @param location and one of the players exceeds 256
+ *
+ * @param location Location to check
+ * @return Whether the distance exceeds 256 or not
+ */
+ private static boolean isLongDistance(Location location, List players) {
+ String world = location.getWorld().getName();
+ for (Player player : players) {
+ Location playerLocation = player.getLocation();
+ if (!world.equals(playerLocation.getWorld().getName()) || playerLocation.distanceSquared(location) < 65536) {
+ continue;
+ }
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Determine if the data type for a particle effect is correct
+ *
+ * @param effect Particle effect
+ * @param data Particle data
+ * @return Whether the data type is correct or not
+ */
+ private static boolean isDataCorrect(ParticleEffect effect, ParticleData data) {
+ return ((effect == BLOCK_CRACK || effect == BLOCK_DUST) && data instanceof BlockData) || (effect == ITEM_CRACK && data instanceof ItemData);
+ }
+
+ /**
+ * Determine if the color type for a particle effect is correct
+ *
+ * @param effect Particle effect
+ * @param color Particle color
+ * @return Whether the color type is correct or not
+ */
+ private static boolean isColorCorrect(ParticleEffect effect, ParticleColor color) {
+ return ((effect == SPELL_MOB || effect == SPELL_MOB_AMBIENT || effect == REDSTONE) && color instanceof OrdinaryColor) || (effect == NOTE && color instanceof NoteColor);
+ }
+
+ /**
+ * Displays a particle effect which is only visible for all players within a certain range in the world of @param center
+ *
+ * @param offsetX Maximum distance particles can fly away from the center on the x-axis
+ * @param offsetY Maximum distance particles can fly away from the center on the y-axis
+ * @param offsetZ Maximum distance particles can fly away from the center on the z-axis
+ * @param speed Display speed of the particles
+ * @param amount Amount of particles
+ * @param center Center location of the effect
+ * @param range Range of the visibility
+ * @throws ParticleVersionException If the particle effect is not supported by the server version
+ * @throws ParticleDataException If the particle effect requires additional data
+ * @throws IllegalArgumentException If the particle effect requires water and none is at the center location
+ * @see ParticlePacket
+ * @see ParticlePacket#sendTo(Location, double)
+ */
+ public void display(float offsetX, float offsetY, float offsetZ, float speed, int amount, Location center, double range) throws ParticleVersionException, ParticleDataException, IllegalArgumentException {
+ if (!isSupported()) {
+ throw new ParticleVersionException("This particle effect is not supported by your server version");
+ }
+ if (hasProperty(ParticleProperty.REQUIRES_DATA)) {
+ throw new ParticleDataException("This particle effect requires additional data");
+ }
+ if (hasProperty(ParticleProperty.REQUIRES_WATER) && !isWater(center)) {
+ throw new IllegalArgumentException("There is no water at the center location");
+ }
+ new ParticlePacket(this, offsetX, offsetY, offsetZ, speed, amount, range > 256, null).sendTo(center, range);
+ }
+
+ /**
+ * Displays a particle effect which is only visible for the specified players
+ *
+ * @param offsetX Maximum distance particles can fly away from the center on the x-axis
+ * @param offsetY Maximum distance particles can fly away from the center on the y-axis
+ * @param offsetZ Maximum distance particles can fly away from the center on the z-axis
+ * @param speed Display speed of the particles
+ * @param amount Amount of particles
+ * @param center Center location of the effect
+ * @param players Receivers of the effect
+ * @throws ParticleVersionException If the particle effect is not supported by the server version
+ * @throws ParticleDataException If the particle effect requires additional data
+ * @throws IllegalArgumentException If the particle effect requires water and none is at the center location
+ * @see ParticlePacket
+ * @see ParticlePacket#sendTo(Location, List)
+ */
+ public void display(float offsetX, float offsetY, float offsetZ, float speed, int amount, Location center, List players) throws ParticleVersionException, ParticleDataException, IllegalArgumentException {
+ if (!isSupported()) {
+ throw new ParticleVersionException("This particle effect is not supported by your server version");
+ }
+ if (hasProperty(ParticleProperty.REQUIRES_DATA)) {
+ throw new ParticleDataException("This particle effect requires additional data");
+ }
+ if (hasProperty(ParticleProperty.REQUIRES_WATER) && !isWater(center)) {
+ throw new IllegalArgumentException("There is no water at the center location");
+ }
+ new ParticlePacket(this, offsetX, offsetY, offsetZ, speed, amount, isLongDistance(center, players), null).sendTo(center, players);
+ }
+
+ /**
+ * Displays a particle effect which is only visible for the specified players
+ *
+ * @param offsetX Maximum distance particles can fly away from the center on the x-axis
+ * @param offsetY Maximum distance particles can fly away from the center on the y-axis
+ * @param offsetZ Maximum distance particles can fly away from the center on the z-axis
+ * @param speed Display speed of the particles
+ * @param amount Amount of particles
+ * @param center Center location of the effect
+ * @param players Receivers of the effect
+ * @throws ParticleVersionException If the particle effect is not supported by the server version
+ * @throws ParticleDataException If the particle effect requires additional data
+ * @throws IllegalArgumentException If the particle effect requires water and none is at the center location
+ * @see #display(float, float, float, float, int, Location, List)
+ */
+ public void display(float offsetX, float offsetY, float offsetZ, float speed, int amount, Location center, Player... players) throws ParticleVersionException, ParticleDataException, IllegalArgumentException {
+ display(offsetX, offsetY, offsetZ, speed, amount, center, Arrays.asList(players));
+ }
+
+ /**
+ * Displays a single particle which flies into a determined direction and is only visible for all players within a certain range in the world of @param center
+ *
+ * @param direction Direction of the particle
+ * @param speed Display speed of the particle
+ * @param center Center location of the effect
+ * @param range Range of the visibility
+ * @throws ParticleVersionException If the particle effect is not supported by the server version
+ * @throws ParticleDataException If the particle effect requires additional data
+ * @throws IllegalArgumentException If the particle effect is not directional or if it requires water and none is at the center location
+ * @see ParticlePacket#ParticlePacket(ParticleEffect, Vector, float, boolean, ParticleData)
+ * @see ParticlePacket#sendTo(Location, double)
+ */
+ public void display(Vector direction, float speed, Location center, double range) throws ParticleVersionException, ParticleDataException, IllegalArgumentException {
+ if (!isSupported()) {
+ throw new ParticleVersionException("This particle effect is not supported by your server version");
+ }
+ if (hasProperty(ParticleProperty.REQUIRES_DATA)) {
+ throw new ParticleDataException("This particle effect requires additional data");
+ }
+ if (!hasProperty(ParticleProperty.DIRECTIONAL)) {
+ throw new IllegalArgumentException("This particle effect is not directional");
+ }
+ if (hasProperty(ParticleProperty.REQUIRES_WATER) && !isWater(center)) {
+ throw new IllegalArgumentException("There is no water at the center location");
+ }
+ new ParticlePacket(this, direction, speed, range > 256, null).sendTo(center, range);
+ }
+
+ /**
+ * Displays a single particle which flies into a determined direction and is only visible for the specified players
+ *
+ * @param direction Direction of the particle
+ * @param speed Display speed of the particle
+ * @param center Center location of the effect
+ * @param players Receivers of the effect
+ * @throws ParticleVersionException If the particle effect is not supported by the server version
+ * @throws ParticleDataException If the particle effect requires additional data
+ * @throws IllegalArgumentException If the particle effect is not directional or if it requires water and none is at the center location
+ * @see ParticlePacket#ParticlePacket(ParticleEffect, Vector, float, boolean, ParticleData)
+ * @see ParticlePacket#sendTo(Location, List)
+ */
+ public void display(Vector direction, float speed, Location center, List players) throws ParticleVersionException, ParticleDataException, IllegalArgumentException {
+ if (!isSupported()) {
+ throw new ParticleVersionException("This particle effect is not supported by your server version");
+ }
+ if (hasProperty(ParticleProperty.REQUIRES_DATA)) {
+ throw new ParticleDataException("This particle effect requires additional data");
+ }
+ if (!hasProperty(ParticleProperty.DIRECTIONAL)) {
+ throw new IllegalArgumentException("This particle effect is not directional");
+ }
+ if (hasProperty(ParticleProperty.REQUIRES_WATER) && !isWater(center)) {
+ throw new IllegalArgumentException("There is no water at the center location");
+ }
+ new ParticlePacket(this, direction, speed, isLongDistance(center, players), null).sendTo(center, players);
+ }
+
+ /**
+ * Displays a single particle which flies into a determined direction and is only visible for the specified players
+ *
+ * @param direction Direction of the particle
+ * @param speed Display speed of the particle
+ * @param center Center location of the effect
+ * @param players Receivers of the effect
+ * @throws ParticleVersionException If the particle effect is not supported by the server version
+ * @throws ParticleDataException If the particle effect requires additional data
+ * @throws IllegalArgumentException If the particle effect is not directional or if it requires water and none is at the center location
+ * @see #display(Vector, float, Location, List)
+ */
+ public void display(Vector direction, float speed, Location center, Player... players) throws ParticleVersionException, ParticleDataException, IllegalArgumentException {
+ display(direction, speed, center, Arrays.asList(players));
+ }
+
+ /**
+ * Displays a single particle which is colored and only visible for all players within a certain range in the world of @param center
+ *
+ * @param color Color of the particle
+ * @param center Center location of the effect
+ * @param range Range of the visibility
+ * @throws ParticleVersionException If the particle effect is not supported by the server version
+ * @throws ParticleColorException If the particle effect is not colorable or the color type is incorrect
+ * @see ParticlePacket#ParticlePacket(ParticleEffect, ParticleColor, boolean)
+ * @see ParticlePacket#sendTo(Location, double)
+ */
+ public void display(ParticleColor color, Location center, double range) throws ParticleVersionException, ParticleColorException {
+ if (!isSupported()) {
+ throw new ParticleVersionException("This particle effect is not supported by your server version");
+ }
+ if (!hasProperty(ParticleProperty.COLORABLE)) {
+ throw new ParticleColorException("This particle effect is not colorable");
+ }
+ if (!isColorCorrect(this, color)) {
+ throw new ParticleColorException("The particle color type is incorrect");
+ }
+ new ParticlePacket(this, color, range > 256).sendTo(center, range);
+ }
+
+ /**
+ * Displays a single particle which is colored and only visible for the specified players
+ *
+ * @param color Color of the particle
+ * @param center Center location of the effect
+ * @param players Receivers of the effect
+ * @throws ParticleVersionException If the particle effect is not supported by the server version
+ * @throws ParticleColorException If the particle effect is not colorable or the color type is incorrect
+ * @see ParticlePacket#ParticlePacket(ParticleEffect, ParticleColor, boolean)
+ * @see ParticlePacket#sendTo(Location, List)
+ */
+ public void display(ParticleColor color, Location center, List players) throws ParticleVersionException, ParticleColorException {
+ if (!isSupported()) {
+ throw new ParticleVersionException("This particle effect is not supported by your server version");
+ }
+ if (!hasProperty(ParticleProperty.COLORABLE)) {
+ throw new ParticleColorException("This particle effect is not colorable");
+ }
+ if (!isColorCorrect(this, color)) {
+ throw new ParticleColorException("The particle color type is incorrect");
+ }
+ new ParticlePacket(this, color, isLongDistance(center, players)).sendTo(center, players);
+ }
+
+ /**
+ * Displays a single particle which is colored and only visible for the specified players
+ *
+ * @param color Color of the particle
+ * @param center Center location of the effect
+ * @param players Receivers of the effect
+ * @throws ParticleVersionException If the particle effect is not supported by the server version
+ * @throws ParticleColorException If the particle effect is not colorable or the color type is incorrect
+ * @see #display(ParticleColor, Location, List)
+ */
+ public void display(ParticleColor color, Location center, Player... players) throws ParticleVersionException, ParticleColorException {
+ display(color, center, Arrays.asList(players));
+ }
+
+ /**
+ * Displays a particle effect which requires additional data and is only visible for all players within a certain range in the world of @param center
+ *
+ * @param data Data of the effect
+ * @param offsetX Maximum distance particles can fly away from the center on the x-axis
+ * @param offsetY Maximum distance particles can fly away from the center on the y-axis
+ * @param offsetZ Maximum distance particles can fly away from the center on the z-axis
+ * @param speed Display speed of the particles
+ * @param amount Amount of particles
+ * @param center Center location of the effect
+ * @param range Range of the visibility
+ * @throws ParticleVersionException If the particle effect is not supported by the server version
+ * @throws ParticleDataException If the particle effect does not require additional data or if the data type is incorrect
+ * @see ParticlePacket
+ * @see ParticlePacket#sendTo(Location, double)
+ */
+ public void display(ParticleData data, float offsetX, float offsetY, float offsetZ, float speed, int amount, Location center, double range) throws ParticleVersionException, ParticleDataException {
+ if (!isSupported()) {
+ throw new ParticleVersionException("This particle effect is not supported by your server version");
+ }
+ if (!hasProperty(ParticleProperty.REQUIRES_DATA)) {
+ throw new ParticleDataException("This particle effect does not require additional data");
+ }
+ if (!isDataCorrect(this, data)) {
+ throw new ParticleDataException("The particle data type is incorrect");
+ }
+ new ParticlePacket(this, offsetX, offsetY, offsetZ, speed, amount, range > 256, data).sendTo(center, range);
+ }
+
+ /**
+ * Displays a particle effect which requires additional data and is only visible for the specified players
+ *
+ * @param data Data of the effect
+ * @param offsetX Maximum distance particles can fly away from the center on the x-axis
+ * @param offsetY Maximum distance particles can fly away from the center on the y-axis
+ * @param offsetZ Maximum distance particles can fly away from the center on the z-axis
+ * @param speed Display speed of the particles
+ * @param amount Amount of particles
+ * @param center Center location of the effect
+ * @param players Receivers of the effect
+ * @throws ParticleVersionException If the particle effect is not supported by the server version
+ * @throws ParticleDataException If the particle effect does not require additional data or if the data type is incorrect
+ * @see ParticlePacket
+ * @see ParticlePacket#sendTo(Location, List)
+ */
+ public void display(ParticleData data, float offsetX, float offsetY, float offsetZ, float speed, int amount, Location center, List players) throws ParticleVersionException, ParticleDataException {
+ if (!isSupported()) {
+ throw new ParticleVersionException("This particle effect is not supported by your server version");
+ }
+ if (!hasProperty(ParticleProperty.REQUIRES_DATA)) {
+ throw new ParticleDataException("This particle effect does not require additional data");
+ }
+ if (!isDataCorrect(this, data)) {
+ throw new ParticleDataException("The particle data type is incorrect");
+ }
+ new ParticlePacket(this, offsetX, offsetY, offsetZ, speed, amount, isLongDistance(center, players), data).sendTo(center, players);
+ }
+
+ /**
+ * Displays a particle effect which requires additional data and is only visible for the specified players
+ *
+ * @param data Data of the effect
+ * @param offsetX Maximum distance particles can fly away from the center on the x-axis
+ * @param offsetY Maximum distance particles can fly away from the center on the y-axis
+ * @param offsetZ Maximum distance particles can fly away from the center on the z-axis
+ * @param speed Display speed of the particles
+ * @param amount Amount of particles
+ * @param center Center location of the effect
+ * @param players Receivers of the effect
+ * @throws ParticleVersionException If the particle effect is not supported by the server version
+ * @throws ParticleDataException If the particle effect does not require additional data or if the data type is incorrect
+ * @see #display(ParticleData, float, float, float, float, int, Location, List)
+ */
+ public void display(ParticleData data, float offsetX, float offsetY, float offsetZ, float speed, int amount, Location center, Player... players) throws ParticleVersionException, ParticleDataException {
+ display(data, offsetX, offsetY, offsetZ, speed, amount, center, Arrays.asList(players));
+ }
+
+ /**
+ * Displays a single particle which requires additional data that flies into a determined direction and is only visible for all players within a certain range in the world of @param center
+ *
+ * @param data Data of the effect
+ * @param direction Direction of the particle
+ * @param speed Display speed of the particles
+ * @param center Center location of the effect
+ * @param range Range of the visibility
+ * @throws ParticleVersionException If the particle effect is not supported by the server version
+ * @throws ParticleDataException If the particle effect does not require additional data or if the data type is incorrect
+ * @see ParticlePacket
+ * @see ParticlePacket#sendTo(Location, double)
+ */
+ public void display(ParticleData data, Vector direction, float speed, Location center, double range) throws ParticleVersionException, ParticleDataException {
+ if (!isSupported()) {
+ throw new ParticleVersionException("This particle effect is not supported by your server version");
+ }
+ if (!hasProperty(ParticleProperty.REQUIRES_DATA)) {
+ throw new ParticleDataException("This particle effect does not require additional data");
+ }
+ if (!isDataCorrect(this, data)) {
+ throw new ParticleDataException("The particle data type is incorrect");
+ }
+ new ParticlePacket(this, direction, speed, range > 256, data).sendTo(center, range);
+ }
+
+ /**
+ * Displays a single particle which requires additional data that flies into a determined direction and is only visible for the specified players
+ *
+ * @param data Data of the effect
+ * @param direction Direction of the particle
+ * @param speed Display speed of the particles
+ * @param center Center location of the effect
+ * @param players Receivers of the effect
+ * @throws ParticleVersionException If the particle effect is not supported by the server version
+ * @throws ParticleDataException If the particle effect does not require additional data or if the data type is incorrect
+ * @see ParticlePacket
+ * @see ParticlePacket#sendTo(Location, List)
+ */
+ public void display(ParticleData data, Vector direction, float speed, Location center, List players) throws ParticleVersionException, ParticleDataException {
+ if (!isSupported()) {
+ throw new ParticleVersionException("This particle effect is not supported by your server version");
+ }
+ if (!hasProperty(ParticleProperty.REQUIRES_DATA)) {
+ throw new ParticleDataException("This particle effect does not require additional data");
+ }
+ if (!isDataCorrect(this, data)) {
+ throw new ParticleDataException("The particle data type is incorrect");
+ }
+ new ParticlePacket(this, direction, speed, isLongDistance(center, players), data).sendTo(center, players);
+ }
+
+ /**
+ * Displays a single particle which requires additional data that flies into a determined direction and is only visible for the specified players
+ *
+ * @param data Data of the effect
+ * @param direction Direction of the particle
+ * @param speed Display speed of the particles
+ * @param center Center location of the effect
+ * @param players Receivers of the effect
+ * @throws ParticleVersionException If the particle effect is not supported by the server version
+ * @throws ParticleDataException If the particle effect does not require additional data or if the data type is incorrect
+ * @see #display(ParticleData, Vector, float, Location, List)
+ */
+ public void display(ParticleData data, Vector direction, float speed, Location center, Player... players) throws ParticleVersionException, ParticleDataException {
+ display(data, direction, speed, center, Arrays.asList(players));
+ }
+
+ /**
+ * Represents the property of a particle effect
+ *
+ * This class is part of the ParticleEffect Library and follows the same usage conditions
+ *
+ * @author DarkBlade12
+ * @since 1.7
+ */
+ public static enum ParticleProperty {
+ /**
+ * The particle effect requires water to be displayed
+ */
+ REQUIRES_WATER,
+ /**
+ * The particle effect requires block or item data to be displayed
+ */
+ REQUIRES_DATA,
+ /**
+ * The particle effect uses the offsets as direction values
+ */
+ DIRECTIONAL,
+ /**
+ * The particle effect uses the offsets as color values
+ */
+ COLORABLE
+ }
+
+ /**
+ * Represents the particle data for effects like {@link ParticleEffect#ITEM_CRACK}, {@link ParticleEffect#BLOCK_CRACK} and {@link ParticleEffect#BLOCK_DUST}
+ *
+ * This class is part of the ParticleEffect Library and follows the same usage conditions
+ *
+ * @author DarkBlade12
+ * @since 1.6
+ */
+ public static abstract class ParticleData {
+ private final Material material;
+ private final byte data;
+ private final int[] packetData;
+
+ /**
+ * Construct a new particle data
+ *
+ * @param material Material of the item/block
+ * @param data Data value of the item/block
+ */
+ @SuppressWarnings("deprecation")
+ public ParticleData(Material material, byte data) {
+ this.material = material;
+ this.data = data;
+ this.packetData = new int[] { material.getId(), data };
+ }
+
+ /**
+ * Returns the material of this data
+ *
+ * @return The material
+ */
+ public Material getMaterial() {
+ return material;
+ }
+
+ /**
+ * Returns the data value of this data
+ *
+ * @return The data value
+ */
+ public byte getData() {
+ return data;
+ }
+
+ /**
+ * Returns the data as an int array for packet construction
+ *
+ * @return The data for the packet
+ */
+ public int[] getPacketData() {
+ return packetData;
+ }
+
+ /**
+ * Returns the data as a string for pre 1.8 versions
+ *
+ * @return The data string for the packet
+ */
+ public String getPacketDataString() {
+ return "_" + packetData[0] + "_" + packetData[1];
+ }
+ }
+
+ /**
+ * Represents the item data for the {@link ParticleEffect#ITEM_CRACK} effect
+ *
+ * This class is part of the ParticleEffect Library and follows the same usage conditions
+ *
+ * @author DarkBlade12
+ * @since 1.6
+ */
+ public static final class ItemData extends ParticleData {
+ /**
+ * Construct a new item data
+ *
+ * @param material Material of the item
+ * @param data Data value of the item
+ * @see ParticleData#ParticleData(Material, byte)
+ */
+ public ItemData(Material material, byte data) {
+ super(material, data);
+ }
+ }
+
+ /**
+ * Represents the block data for the {@link ParticleEffect#BLOCK_CRACK} and {@link ParticleEffect#BLOCK_DUST} effects
+ *
+ * This class is part of the ParticleEffect Library and follows the same usage conditions
+ *
+ * @author DarkBlade12
+ * @since 1.6
+ */
+ public static final class BlockData extends ParticleData {
+ /**
+ * Construct a new block data
+ *
+ * @param material Material of the block
+ * @param data Data value of the block
+ * @throws IllegalArgumentException If the material is not a block
+ * @see ParticleData#ParticleData(Material, byte)
+ */
+ public BlockData(Material material, byte data) throws IllegalArgumentException {
+ super(material, data);
+ if (!material.isBlock()) {
+ throw new IllegalArgumentException("The material is not a block");
+ }
+ }
+ }
+
+ /**
+ * Represents the color for effects like {@link ParticleEffect#SPELL_MOB}, {@link ParticleEffect#SPELL_MOB_AMBIENT}, {@link ParticleEffect#REDSTONE} and {@link ParticleEffect#NOTE}
+ *
+ * This class is part of the ParticleEffect Library and follows the same usage conditions
+ *
+ * @author DarkBlade12
+ * @since 1.7
+ */
+ public static abstract class ParticleColor {
+ /**
+ * Returns the value for the offsetX field
+ *
+ * @return The offsetX value
+ */
+ public abstract float getValueX();
+
+ /**
+ * Returns the value for the offsetY field
+ *
+ * @return The offsetY value
+ */
+ public abstract float getValueY();
+
+ /**
+ * Returns the value for the offsetZ field
+ *
+ * @return The offsetZ value
+ */
+ public abstract float getValueZ();
+ }
+
+ /**
+ * Represents the color for effects like {@link ParticleEffect#SPELL_MOB}, {@link ParticleEffect#SPELL_MOB_AMBIENT} and {@link ParticleEffect#NOTE}
+ *
+ * This class is part of the ParticleEffect Library and follows the same usage conditions
+ *
+ * @author DarkBlade12
+ * @since 1.7
+ */
+ public static final class OrdinaryColor extends ParticleColor {
+ private final int red;
+ private final int green;
+ private final int blue;
+
+ /**
+ * Construct a new ordinary color
+ *
+ * @param red Red value of the RGB format
+ * @param green Green value of the RGB format
+ * @param blue Blue value of the RGB format
+ * @throws IllegalArgumentException If one of the values is lower than 0 or higher than 255
+ */
+ public OrdinaryColor(int red, int green, int blue) throws IllegalArgumentException {
+ if (red < 0) {
+ throw new IllegalArgumentException("The red value is lower than 0");
+ }
+ if (red > 255) {
+ throw new IllegalArgumentException("The red value is higher than 255");
+ }
+ this.red = red;
+ if (green < 0) {
+ throw new IllegalArgumentException("The green value is lower than 0");
+ }
+ if (green > 255) {
+ throw new IllegalArgumentException("The green value is higher than 255");
+ }
+ this.green = green;
+ if (blue < 0) {
+ throw new IllegalArgumentException("The blue value is lower than 0");
+ }
+ if (blue > 255) {
+ throw new IllegalArgumentException("The blue value is higher than 255");
+ }
+ this.blue = blue;
+ }
+
+ /**
+ * Construct a new ordinary color
+ *
+ * @param color Bukkit color
+ */
+ public OrdinaryColor(Color color) {
+ this(color.getRed(), color.getGreen(), color.getBlue());
+ }
+
+ /**
+ * Returns the red value of the RGB format
+ *
+ * @return The red value
+ */
+ public int getRed() {
+ return red;
+ }
+
+ /**
+ * Returns the green value of the RGB format
+ *
+ * @return The green value
+ */
+ public int getGreen() {
+ return green;
+ }
+
+ /**
+ * Returns the blue value of the RGB format
+ *
+ * @return The blue value
+ */
+ public int getBlue() {
+ return blue;
+ }
+
+ /**
+ * Returns the red value divided by 255
+ *
+ * @return The offsetX value
+ */
+ @Override
+ public float getValueX() {
+ return (float) red / 255F;
+ }
+
+ /**
+ * Returns the green value divided by 255
+ *
+ * @return The offsetY value
+ */
+ @Override
+ public float getValueY() {
+ return (float) green / 255F;
+ }
+
+ /**
+ * Returns the blue value divided by 255
+ *
+ * @return The offsetZ value
+ */
+ @Override
+ public float getValueZ() {
+ return (float) blue / 255F;
+ }
+ }
+
+ /**
+ * Represents the color for the {@link ParticleEffect#NOTE} effect
+ *
+ * This class is part of the ParticleEffect Library and follows the same usage conditions
+ *
+ * @author DarkBlade12
+ * @since 1.7
+ */
+ public static final class NoteColor extends ParticleColor {
+ private final int note;
+
+ /**
+ * Construct a new note color
+ *
+ * @param note Note id which determines color
+ * @throws IllegalArgumentException If the note value is lower than 0 or higher than 24
+ */
+ public NoteColor(int note) throws IllegalArgumentException {
+ if (note < 0) {
+ throw new IllegalArgumentException("The note value is lower than 0");
+ }
+ if (note > 24) {
+ throw new IllegalArgumentException("The note value is higher than 24");
+ }
+ this.note = note;
+ }
+
+ /**
+ * Returns the note value divided by 24
+ *
+ * @return The offsetX value
+ */
+ @Override
+ public float getValueX() {
+ return (float) note / 24F;
+ }
+
+ /**
+ * Returns zero because the offsetY value is unused
+ *
+ * @return zero
+ */
+ @Override
+ public float getValueY() {
+ return 0;
+ }
+
+ /**
+ * Returns zero because the offsetZ value is unused
+ *
+ * @return zero
+ */
+ @Override
+ public float getValueZ() {
+ return 0;
+ }
+
+ }
+
+ /**
+ * Represents a runtime exception that is thrown either if the displayed particle effect requires data and has none or vice-versa or if the data type is incorrect
+ *
+ * This class is part of the ParticleEffect Library and follows the same usage conditions
+ *
+ * @author DarkBlade12
+ * @since 1.6
+ */
+ private static final class ParticleDataException extends RuntimeException {
+ private static final long serialVersionUID = 3203085387160737484L;
+
+ /**
+ * Construct a new particle data exception
+ *
+ * @param message Message that will be logged
+ */
+ public ParticleDataException(String message) {
+ super(message);
+ }
+ }
+
+ /**
+ * Represents a runtime exception that is thrown either if the displayed particle effect is not colorable or if the particle color type is incorrect
+ *
+ * This class is part of the ParticleEffect Library and follows the same usage conditions
+ *
+ * @author DarkBlade12
+ * @since 1.7
+ */
+ private static final class ParticleColorException extends RuntimeException {
+ private static final long serialVersionUID = 3203085387160737484L;
+
+ /**
+ * Construct a new particle color exception
+ *
+ * @param message Message that will be logged
+ */
+ public ParticleColorException(String message) {
+ super(message);
+ }
+ }
+
+ /**
+ * Represents a runtime exception that is thrown if the displayed particle effect requires a newer version
+ *
+ * This class is part of the ParticleEffect Library and follows the same usage conditions
+ *
+ * @author DarkBlade12
+ * @since 1.6
+ */
+ private static final class ParticleVersionException extends RuntimeException {
+ private static final long serialVersionUID = 3203085387160737484L;
+
+ /**
+ * Construct a new particle version exception
+ *
+ * @param message Message that will be logged
+ */
+ public ParticleVersionException(String message) {
+ super(message);
+ }
+ }
+
+ /**
+ * Represents a particle effect packet with all attributes which is used for sending packets to the players
+ *
+ * This class is part of the ParticleEffect Library and follows the same usage conditions
+ *
+ * @author DarkBlade12
+ * @since 1.5
+ */
+ public static final class ParticlePacket {
+ private static int version;
+ private static Class> enumParticle;
+ private static Constructor> packetConstructor;
+ private static Method getHandle;
+ private static Field playerConnection;
+ private static Method sendPacket;
+ private static boolean initialized;
+ private final ParticleEffect effect;
+ private float offsetX;
+ private final float offsetY;
+ private final float offsetZ;
+ private final float speed;
+ private final int amount;
+ private final boolean longDistance;
+ private final ParticleData data;
+ private Object packet;
+
+ /**
+ * Construct a new particle packet
+ *
+ * @param effect Particle effect
+ * @param offsetX Maximum distance particles can fly away from the center on the x-axis
+ * @param offsetY Maximum distance particles can fly away from the center on the y-axis
+ * @param offsetZ Maximum distance particles can fly away from the center on the z-axis
+ * @param speed Display speed of the particles
+ * @param amount Amount of particles
+ * @param longDistance Indicates whether the maximum distance is increased from 256 to 65536
+ * @param data Data of the effect
+ * @throws IllegalArgumentException If the speed or amount is lower than 0
+ * @see #initialize()
+ */
+ public ParticlePacket(ParticleEffect effect, float offsetX, float offsetY, float offsetZ, float speed, int amount, boolean longDistance, ParticleData data) throws IllegalArgumentException {
+ initialize();
+ if (speed < 0) {
+ throw new IllegalArgumentException("The speed is lower than 0");
+ }
+ if (amount < 0) {
+ throw new IllegalArgumentException("The amount is lower than 0");
+ }
+ this.effect = effect;
+ this.offsetX = offsetX;
+ this.offsetY = offsetY;
+ this.offsetZ = offsetZ;
+ this.speed = speed;
+ this.amount = amount;
+ this.longDistance = longDistance;
+ this.data = data;
+ }
+
+ /**
+ * Construct a new particle packet of a single particle flying into a determined direction
+ *
+ * @param effect Particle effect
+ * @param direction Direction of the particle
+ * @param speed Display speed of the particle
+ * @param longDistance Indicates whether the maximum distance is increased from 256 to 65536
+ * @param data Data of the effect
+ * @throws IllegalArgumentException If the speed is lower than 0
+ * @see #ParticleEffect(ParticleEffect, float, float, float, float, int, boolean, ParticleData)
+ */
+ public ParticlePacket(ParticleEffect effect, Vector direction, float speed, boolean longDistance, ParticleData data) throws IllegalArgumentException {
+ this(effect, (float) direction.getX(), (float) direction.getY(), (float) direction.getZ(), speed, 0, longDistance, data);
+ }
+
+ /**
+ * Construct a new particle packet of a single colored particle
+ *
+ * @param effect Particle effect
+ * @param color Color of the particle
+ * @param longDistance Indicates whether the maximum distance is increased from 256 to 65536
+ * @see #ParticleEffect(ParticleEffect, float, float, float, float, int, boolean, ParticleData)
+ */
+ public ParticlePacket(ParticleEffect effect, ParticleColor color, boolean longDistance) {
+ this(effect, color.getValueX(), color.getValueY(), color.getValueZ(), 1, 0, longDistance, null);
+ if (effect == ParticleEffect.REDSTONE && color instanceof OrdinaryColor && ((OrdinaryColor) color).getRed() == 0) {
+ offsetX = Float.MIN_NORMAL;
+ }
+ }
+
+ /**
+ * Initializes {@link #packetConstructor}, {@link #getHandle}, {@link #playerConnection} and {@link #sendPacket} and sets {@link #initialized} to true if it succeeds
+ *
+ * Note: These fields only have to be initialized once, so it will return if {@link #initialized} is already set to true
+ *
+ * @throws VersionIncompatibleException if your bukkit version is not supported by this library
+ */
+ public static void initialize() throws VersionIncompatibleException {
+ if (initialized) {
+ return;
+ }
+ try {
+ version = Integer.parseInt(Character.toString(PackageType.getServerVersion().charAt(3)));
+ if (version > 7) {
+ enumParticle = PackageType.MINECRAFT_SERVER.getClass("EnumParticle");
+ }
+ Class> packetClass = PackageType.MINECRAFT_SERVER.getClass(version < 7 ? "Packet63WorldParticles" : "PacketPlayOutWorldParticles");
+ packetConstructor = ReflectionUtils.getConstructor(packetClass);
+ getHandle = ReflectionUtils.getMethod("CraftPlayer", PackageType.CRAFTBUKKIT_ENTITY, "getHandle");
+ playerConnection = ReflectionUtils.getField("EntityPlayer", PackageType.MINECRAFT_SERVER, false, "playerConnection");
+ sendPacket = ReflectionUtils.getMethod(playerConnection.getType(), "sendPacket", PackageType.MINECRAFT_SERVER.getClass("Packet"));
+ } catch (Exception exception) {
+ throw new VersionIncompatibleException("Your current bukkit version seems to be incompatible with this library", exception);
+ }
+ initialized = true;
+ }
+
+ /**
+ * Returns the version of your server (1.x)
+ *
+ * @return The version number
+ */
+ public static int getVersion() {
+ if (!initialized) {
+ initialize();
+ }
+ return version;
+ }
+
+ /**
+ * Determine if {@link #packetConstructor}, {@link #getHandle}, {@link #playerConnection} and {@link #sendPacket} are initialized
+ *
+ * @return Whether these fields are initialized or not
+ * @see #initialize()
+ */
+ public static boolean isInitialized() {
+ return initialized;
+ }
+
+ /**
+ * Initializes {@link #packet} with all set values
+ *
+ * @param center Center location of the effect
+ * @throws PacketInstantiationException If instantion fails due to an unknown error
+ */
+ private void initializePacket(Location center) throws PacketInstantiationException {
+ if (packet != null) {
+ return;
+ }
+ try {
+ packet = packetConstructor.newInstance();
+ if (version < 8) {
+ String name = effect.getName();
+ if (data != null) {
+ name += data.getPacketDataString();
+ }
+ ReflectionUtils.setValue(packet, true, "a", name);
+ } else {
+ ReflectionUtils.setValue(packet, true, "a", enumParticle.getEnumConstants()[effect.getId()]);
+ ReflectionUtils.setValue(packet, true, "j", longDistance);
+ if (data != null) {
+ int[] packetData = data.getPacketData();
+ ReflectionUtils.setValue(packet, true, "k", effect == ParticleEffect.ITEM_CRACK ? packetData : new int[] { packetData[0] | (packetData[1] << 12) });
+ }
+ }
+ ReflectionUtils.setValue(packet, true, "b", (float) center.getX());
+ ReflectionUtils.setValue(packet, true, "c", (float) center.getY());
+ ReflectionUtils.setValue(packet, true, "d", (float) center.getZ());
+ ReflectionUtils.setValue(packet, true, "e", offsetX);
+ ReflectionUtils.setValue(packet, true, "f", offsetY);
+ ReflectionUtils.setValue(packet, true, "g", offsetZ);
+ ReflectionUtils.setValue(packet, true, "h", speed);
+ ReflectionUtils.setValue(packet, true, "i", amount);
+ } catch (Exception exception) {
+ throw new PacketInstantiationException("Packet instantiation failed", exception);
+ }
+ }
+
+ /**
+ * Sends the packet to a single player and caches it
+ *
+ * @param center Center location of the effect
+ * @param player Receiver of the packet
+ * @throws PacketInstantiationException If instantion fails due to an unknown error
+ * @throws PacketSendingException If sending fails due to an unknown error
+ * @see #initializePacket(Location)
+ */
+ public void sendTo(Location center, Player player) throws PacketInstantiationException, PacketSendingException {
+ initializePacket(center);
+ try {
+ sendPacket.invoke(playerConnection.get(getHandle.invoke(player)), packet);
+ } catch (Exception exception) {
+ throw new PacketSendingException("Failed to send the packet to player '" + player.getName() + "'", exception);
+ }
+ }
+
+ /**
+ * Sends the packet to all players in the list
+ *
+ * @param center Center location of the effect
+ * @param players Receivers of the packet
+ * @throws IllegalArgumentException If the player list is empty
+ * @see #sendTo(Location center, Player player)
+ */
+ public void sendTo(Location center, List players) throws IllegalArgumentException {
+ if (players.isEmpty()) {
+ throw new IllegalArgumentException("The player list is empty");
+ }
+ for (Player player : players) {
+ sendTo(center, player);
+ }
+ }
+
+ /**
+ * Sends the packet to all players in a certain range
+ *
+ * @param center Center location of the effect
+ * @param range Range in which players will receive the packet (Maximum range for particles is usually 16, but it can differ for some types)
+ * @throws IllegalArgumentException If the range is lower than 1
+ * @see #sendTo(Location center, Player player)
+ */
+ public void sendTo(Location center, double range) throws IllegalArgumentException {
+ if (range < 1) {
+ throw new IllegalArgumentException("The range is lower than 1");
+ }
+ String worldName = center.getWorld().getName();
+ double squared = range * range;
+ for (Player player : Bukkit.getOnlinePlayers()) {
+ if (!player.getWorld().getName().equals(worldName) || player.getLocation().distanceSquared(center) > squared) {
+ continue;
+ }
+ sendTo(center, player);
+ }
+ }
+
+ /**
+ * Represents a runtime exception that is thrown if a bukkit version is not compatible with this library
+ *
+ * This class is part of the ParticleEffect Library and follows the same usage conditions
+ *
+ * @author DarkBlade12
+ * @since 1.5
+ */
+ private static final class VersionIncompatibleException extends RuntimeException {
+ private static final long serialVersionUID = 3203085387160737484L;
+
+ /**
+ * Construct a new version incompatible exception
+ *
+ * @param message Message that will be logged
+ * @param cause Cause of the exception
+ */
+ public VersionIncompatibleException(String message, Throwable cause) {
+ super(message, cause);
+ }
+ }
+
+ /**
+ * Represents a runtime exception that is thrown if packet instantiation fails
+ *
+ * This class is part of the ParticleEffect Library and follows the same usage conditions
+ *
+ * @author DarkBlade12
+ * @since 1.4
+ */
+ private static final class PacketInstantiationException extends RuntimeException {
+ private static final long serialVersionUID = 3203085387160737484L;
+
+ /**
+ * Construct a new packet instantiation exception
+ *
+ * @param message Message that will be logged
+ * @param cause Cause of the exception
+ */
+ public PacketInstantiationException(String message, Throwable cause) {
+ super(message, cause);
+ }
+ }
+
+ /**
+ * Represents a runtime exception that is thrown if packet sending fails
+ *
+ * This class is part of the ParticleEffect Library and follows the same usage conditions
+ *
+ * @author DarkBlade12
+ * @since 1.4
+ */
+ private static final class PacketSendingException extends RuntimeException {
+ private static final long serialVersionUID = 3203085387160737484L;
+
+ /**
+ * Construct a new packet sending exception
+ *
+ * @param message Message that will be logged
+ * @param cause Cause of the exception
+ */
+ public PacketSendingException(String message, Throwable cause) {
+ super(message, cause);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/eu/univento/core/api/effects/WorldBoarder.java b/src/main/java/eu/univento/core/api/effects/WorldBoarder.java
new file mode 100644
index 0000000..d37eb20
--- /dev/null
+++ b/src/main/java/eu/univento/core/api/effects/WorldBoarder.java
@@ -0,0 +1,129 @@
+package eu.univento.core.api.effects;
+
+import eu.univento.core.Core;
+import org.bukkit.Bukkit;
+import org.bukkit.entity.Player;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * @author MrSheepSheep
+ * @version 0.1
+ */
+public class WorldBoarder {
+
+ private static Method handle, sendPacket;
+ private static Method center, distance, time, movement;
+ private static Field player_connection;
+ private static Constructor> constructor, border_constructor;
+ private static Object constant;
+
+ static {
+ try {
+ handle = getClass("org.bukkit.craftbukkit", "entity.CraftPlayer").getMethod("getHandle");
+ player_connection = getClass("net.minecraft.server", "EntityPlayer").getField("playerConnection");
+ for (Method m : getClass("net.minecraft.server", "PlayerConnection").getMethods()) {
+ if (m.getName().equals("sendPacket")) {
+ sendPacket = m;
+ break;
+ }
+ }
+ Class> enumclass;
+ try {
+ enumclass = getClass("net.minecraft.server", "EnumWorldBorderAction");
+ } catch(ClassNotFoundException x) {
+ enumclass = getClass("net.minecraft.server", "PacketPlayOutWorldBorder$EnumWorldBorderAction");
+ }
+ constructor = getClass("net.minecraft.server", "PacketPlayOutWorldBorder").getConstructor(getClass("net.minecraft.server", "WorldBorder"), enumclass);
+ border_constructor = getClass("net.minecraft.server", "WorldBorder").getConstructor();
+
+ Method[] methods = getClass("net.minecraft.server", "WorldBorder").getMethods();
+
+ String setCenter = "setCenter";
+ String setWarningDistance = "setWarningDistance";
+ String setWarningTime = "setWarningTime";
+ String transitionSizeBetween = "transitionSizeBetween";
+
+ if (!inClass(methods, setCenter))
+ setCenter = "c";
+ if (!inClass(methods, setWarningDistance))
+ setWarningDistance = "c";
+ if (!inClass(methods, setWarningTime))
+ setWarningTime = "b";
+ if (!inClass(methods, transitionSizeBetween))
+ transitionSizeBetween = "a";
+
+ center = getClass("net.minecraft.server", "WorldBorder").getMethod(setCenter, double.class, double.class);
+ distance = getClass("net.minecraft.server", "WorldBorder").getMethod(setWarningDistance, int.class);
+ time = getClass("net.minecraft.server", "WorldBorder").getMethod(setWarningTime, int.class);
+ movement = getClass("net.minecraft.server", "WorldBorder").getMethod(transitionSizeBetween, double.class, double.class, long.class);
+
+ for (Object o: enumclass.getEnumConstants()) {
+ if (o.toString().equals("INITIALIZE")) {
+ constant = o;
+ break;
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ private static boolean inClass(Method[] methods, String methodName){
+ for (Method m : methods)
+ if (Objects.equals(m.getName(), methodName))
+ return true;
+ return false;
+ }
+
+ private static Class> getClass(String prefix, String name) throws Exception {
+ return Class.forName((prefix + ".") + Bukkit.getServer().getClass().getPackage().getName().substring(Bukkit.getServer().getClass().getPackage().getName().lastIndexOf(".") + 1) + "." + name);
+ }
+
+ Core plugin;
+ protected List togglelist = new ArrayList<>();
+
+ protected WorldBoarder(Core plugin) {
+ this.plugin = plugin;
+ }
+
+ protected void sendBorder(Player p, int percentage, int intensity){
+ percentage = Math.round(percentage / intensity);
+ setBorder(p, percentage);
+ fadeBorder(p, percentage, 5);
+ }
+
+ protected void fadeBorder(Player p, int percentage, long time){
+ int dist = -10000 * percentage + 1300000;
+ sendWorldBorderPacket(p, 0, 200000D, (double) dist, (long) 1000 * time + 4000); //Add 4000 to make sure the "security" zone does not count in the fade time
+ }
+
+ protected void removeBorder(Player p) {
+ sendWorldBorderPacket(p, 0, 200000D, 200000D, 0);
+ }
+
+ protected void setBorder(Player p, int percentage){
+ int dist = -10000 * percentage + 1300000;
+ sendWorldBorderPacket(p, dist, 200000D, 200000D, 0);
+ }
+
+ protected void sendWorldBorderPacket(Player p, int dist, double oldradius, double newradius, long delay) {
+ try {
+ Object worldborder = border_constructor.newInstance();
+ center.invoke(worldborder, p.getLocation().getX(), p.getLocation().getY());
+ distance.invoke(worldborder, dist);
+ time.invoke(worldborder, 15);
+ movement.invoke(worldborder, oldradius, newradius, delay);
+
+ Object packet = constructor.newInstance(worldborder, constant);
+ sendPacket.invoke(player_connection.get(handle.invoke(p)), packet);
+ } catch(Exception x) {
+ x.printStackTrace();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/eu/univento/core/api/entity/EntityModifier.java b/src/main/java/eu/univento/core/api/entity/EntityModifier.java
new file mode 100644
index 0000000..3804106
--- /dev/null
+++ b/src/main/java/eu/univento/core/api/entity/EntityModifier.java
@@ -0,0 +1,239 @@
+package eu.univento.core.api.entity;
+
+import net.minecraft.server.v1_9_R1.EntityLiving;
+import net.minecraft.server.v1_9_R1.NBTTagCompound;
+import org.bukkit.Bukkit;
+import org.bukkit.EntityEffect;
+import org.bukkit.Location;
+import org.bukkit.craftbukkit.v1_9_R1.entity.CraftCreature;
+import org.bukkit.craftbukkit.v1_9_R1.entity.CraftEntity;
+import org.bukkit.entity.Player;
+import org.bukkit.plugin.Plugin;
+
+import java.lang.reflect.Field;
+
+/**
+ *
+ * @author GerVorbis
+ * @version 1.0
+ */
+public class EntityModifier
+{
+ static org.bukkit.entity.Entity entity;
+ static CraftEntity craftentity;
+ static net.minecraft.server.v1_9_R1.Entity entityS;
+ static int scheduler;
+ static Plugin plugin;
+ static Player player = null;
+ static float Speed;
+
+ public EntityModifier(org.bukkit.entity.Entity entity, Plugin plugin)
+ {
+ EntityModifier.entity = entity;
+ craftentity = (CraftEntity)entity;
+ entityS = craftentity.getHandle();
+ EntityModifier.plugin = plugin;
+ }
+
+ public static Builder modify()
+ {
+ return new Builder();
+ }
+
+ public static final class Builder
+ {
+ public Builder setDisplayName(String display)
+ {
+ EntityModifier.entity.setCustomName(display);
+ EntityModifier.entity.setCustomNameVisible(true);
+ return this;
+ }
+
+ public Builder setDisplayNameVisible(Boolean visible)
+ {
+ EntityModifier.entity.setCustomNameVisible(visible.booleanValue());
+ return this;
+ }
+
+ public Builder playEffekt(EntityEffect entityeffect)
+ {
+ EntityModifier.entity.playEffect(entityeffect);
+ return this;
+ }
+
+ public Builder remove()
+ {
+ EntityModifier.entity.remove();
+ return this;
+ }
+
+ public Builder setPassenger(org.bukkit.entity.Entity passenger)
+ {
+ EntityModifier.entity.setPassenger(passenger);
+ return this;
+ }
+
+ public Builder setFireTicks(int ticks)
+ {
+ EntityModifier.entity.setFireTicks(ticks);
+ return this;
+ }
+
+ public Builder setLocation(Location location)
+ {
+ teleport(location);
+ return this;
+ }
+
+ public Builder setYawPitch(float yaw, float pitch)
+ {
+ Location loc = EntityModifier.entity.getLocation().clone();
+ teleport(
+ new Location(loc.getWorld(), loc.getX(), loc.getY(),
+ loc.getZ(), yaw, pitch));
+ return this;
+ }
+
+ public Builder teleport(Location location)
+ {
+ EntityModifier.entity.teleport(location);
+ return this;
+ }
+
+ public Builder die()
+ {
+ EntityModifier.entityS.die();
+ return this;
+ }
+
+ public Builder setInvisible(boolean invisible)
+ {
+ EntityModifier.entityS.setInvisible(invisible);
+ return this;
+ }
+
+ public Builder noClip(boolean noClip)
+ {
+ EntityModifier.entityS.noclip = noClip;
+ return this;
+ }
+
+ public Builder setInvulnerable(boolean invulnerable)
+ {
+ try
+ {
+ Field invulnerableField = net.minecraft.server.v1_9_R1.Entity.class
+ .getDeclaredField("invulnerable");
+ invulnerableField.setAccessible(true);
+ invulnerableField.setBoolean(EntityModifier.entityS, invulnerable);
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ return this;
+ }
+
+ public Builder setNoAI(boolean noAI)
+ {
+ NBTTagCompound tag = new NBTTagCompound();
+ EntityModifier.entityS.c(tag);
+ tag.setBoolean("NoAI", noAI);
+ EntityLiving el = (EntityLiving)EntityModifier.entityS;
+ el.a(tag);
+ return this;
+ }
+
+ public Builder setSilent(boolean silent)
+ {
+ NBTTagCompound tag = new NBTTagCompound();
+ EntityModifier.entityS.c(tag);
+ tag.setBoolean("Silent", silent);
+ EntityLiving el = (EntityLiving)EntityModifier.entityS;
+ el.a(tag);
+ return this;
+ }
+
+ public Builder setCanPickUpLoot(boolean canpickuploot)
+ {
+ NBTTagCompound tag = new NBTTagCompound();
+ EntityModifier.entityS.c(tag);
+ tag.setBoolean("CanPickUpLoot", canpickuploot);
+ EntityLiving el = (EntityLiving)EntityModifier.entityS;
+ el.a(tag);
+ return this;
+ }
+
+ public Builder setHealth(float health)
+ {
+ NBTTagCompound tag = new NBTTagCompound();
+ EntityModifier.entityS.c(tag);
+ tag.setFloat("HealF", health);
+ EntityLiving el = (EntityLiving)EntityModifier.entityS;
+ el.a(tag);
+ return this;
+ }
+
+ public Builder setCanDespawn(boolean candespawn)
+ {
+ candespawn = !candespawn;
+ NBTTagCompound tag = new NBTTagCompound();
+ EntityModifier.entityS.c(tag);
+ tag.setBoolean("PersistenceRequired", candespawn);
+ EntityLiving el = (EntityLiving)EntityModifier.entityS;
+ el.a(tag);
+ return this;
+ }
+
+ public Builder walkToLocation(Location location, float speed)
+ {
+ ((CraftCreature)EntityModifier.entity)
+ .getHandle()
+ .getNavigation()
+ .a(location.getX(), location.getY(), location.getZ(), speed);
+ return this;
+ }
+
+ public Builder followPlayer(Player target, float speed)
+ {
+ EntityModifier.player = target;
+ EntityModifier.Speed = speed;
+ EntityModifier.scheduler = Bukkit.getScheduler().scheduleSyncRepeatingTask(EntityModifier.plugin,
+ new Runnable()
+ {
+ @SuppressWarnings("deprecation")
+ public void run() {
+ double distance = EntityModifier.entity.getLocation().distance(
+ EntityModifier.player.getLocation());
+ if (distance < 11.0D) {
+ float speed = EntityModifier.Speed;
+ if (distance < 3.0D) {
+ speed = 0.0F;
+ }
+ ((CraftCreature)EntityModifier.entity)
+ .getHandle()
+ .getNavigation()
+ .a(EntityModifier.player.getLocation().getX(),
+ EntityModifier.player.getLocation().getY(),
+ EntityModifier.player.getLocation().getZ(),
+ speed);
+ }
+ else if (EntityModifier.player.isOnGround()) {
+ EntityModifier.entity.teleport(EntityModifier.player);
+ }
+ }
+ }
+ , 0L, 1L);
+ return this;
+ }
+
+ public Builder stopFollowingPlayer()
+ {
+ Bukkit.getScheduler().cancelTask(EntityModifier.scheduler);
+ return this;
+ }
+
+ public org.bukkit.entity.Entity build()
+ {
+ return EntityModifier.entity;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/eu/univento/core/api/events/MoveEventFilter.java b/src/main/java/eu/univento/core/api/events/MoveEventFilter.java
new file mode 100644
index 0000000..de71feb
--- /dev/null
+++ b/src/main/java/eu/univento/core/api/events/MoveEventFilter.java
@@ -0,0 +1,89 @@
+package eu.univento.core.api.events;
+
+import org.bukkit.Location;
+import org.bukkit.Server;
+import org.bukkit.World;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.player.PlayerMoveEvent;
+
+import java.util.WeakHashMap;
+
+/**
+ * @author Crislibaer
+ */
+public class MoveEventFilter implements Listener
+{
+ public static class PlayerBlockMoveEvent extends PlayerMoveEvent
+ {
+ public PlayerBlockMoveEvent(PlayerMoveEvent pEvent)
+ {
+ super(pEvent.getPlayer(), pEvent.getFrom(), pEvent.getTo());
+ }
+ }
+
+ private static class BlockPosition
+ {
+ public int x;
+ public int y;
+ public int z;
+ public World world;
+ }
+
+ private Server mServer;
+ private WeakHashMap mLastPosition = new WeakHashMap<>();
+
+ public MoveEventFilter(Server pServer)
+ {
+ mServer = pServer;
+ }
+
+ @EventHandler
+ public void onPlayerMove(PlayerMoveEvent pEvent)
+ {
+ if(pEvent.isCancelled() || pEvent instanceof PlayerBlockMoveEvent)
+ {
+ return;
+ }
+
+ BlockPosition lastPos = mLastPosition.get(pEvent.getPlayer());
+ Location currentPos = pEvent.getTo();
+ boolean fireEvent = false;
+
+ if(lastPos == null)
+ {
+ lastPos = new BlockPosition();
+ mLastPosition.put(pEvent.getPlayer(), lastPos);
+ fireEvent = true;
+ }
+ else if(lastPos.x != currentPos.getBlockX() || lastPos.z != currentPos.getBlockZ() || lastPos.y != currentPos.getBlockY())
+ {
+ fireEvent = true;
+ }
+ else if(lastPos.world != currentPos.getWorld())
+ {
+ fireEvent = true;
+ }
+
+ if(fireEvent)
+ {
+ // make sure that our event is synchronous
+ assert !pEvent.isAsynchronous();
+
+ // fire event
+ PlayerBlockMoveEvent event = new PlayerBlockMoveEvent(pEvent);
+ mServer.getPluginManager().callEvent(event);
+
+ // check event state and only update new position if event does not gets canceled
+ if(!event.isCancelled())
+ {
+ // update new position
+ lastPos.world = currentPos.getWorld();
+ lastPos.x = currentPos.getBlockX();
+ lastPos.y = currentPos.getBlockY();
+ lastPos.z = currentPos.getBlockZ();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/eu/univento/core/api/fakeplayer/FakePlayer.java b/src/main/java/eu/univento/core/api/fakeplayer/FakePlayer.java
new file mode 100644
index 0000000..8ed0956
--- /dev/null
+++ b/src/main/java/eu/univento/core/api/fakeplayer/FakePlayer.java
@@ -0,0 +1,234 @@
+package eu.univento.core.api.fakeplayer;
+
+import com.mojang.authlib.GameProfile;
+import eu.univento.core.Core;
+import net.minecraft.server.v1_9_R1.*;
+import org.bukkit.Location;
+import org.bukkit.craftbukkit.v1_9_R1.entity.CraftPlayer;
+import org.bukkit.entity.ArmorStand;
+import org.bukkit.entity.EntityType;
+import org.bukkit.entity.LivingEntity;
+import org.bukkit.entity.Player;
+import org.bukkit.scheduler.BukkitRunnable;
+import org.bukkit.scheduler.BukkitTask;
+
+import java.lang.reflect.Field;
+import java.util.Arrays;
+
+/**
+ * @author joethei
+ * @version 0.3
+ */
+public class FakePlayer {
+
+ //TODO: fix parts and add some stuff
+
+ private static final double MOVE_SPEED = 4.3D / 20;
+
+ private Player player;
+ private int entityId;
+ private GameProfile gameProfile;
+ private DataWatcher dataWatcher;
+
+ private Location location;
+ private ArmorStand armorStand;
+ private LivingEntity target;
+ private BukkitTask task;
+
+ private boolean moveable;
+
+ public FakePlayer(GameProfile gameProfile, boolean moveable, Player player) {
+
+ this.player = player;
+
+ this.moveable = moveable;
+
+ this.entityId = (int) get(Entity.class, null, "entityCount");
+ set(Entity.class, null, "entityCount", this.entityId + 1);
+ this.gameProfile = gameProfile;
+
+ this.dataWatcher = new DataWatcher(null);
+ byte status = 0;
+ //this.dataWatcher.a(0, status);
+ //this.dataWatcher.a(10, (byte) 127);
+ //this.dataWatcher.a(6, 20F);
+ }
+
+ private final BukkitRunnable tickTask = new BukkitRunnable() {
+
+ private int ticksLiving = 0;
+
+ @Override
+ public void run() {
+ if(target != null) {
+ followEntity(target);
+
+ ticksLiving++;
+ }
+ }
+ };
+
+ private byte changeMask(byte bitMask, int bit, boolean state) {
+ if(state)
+ return bitMask |= 1 << bit;
+ else
+ return bitMask &= ~(1 << bit);
+
+ }
+
+ public void setTarget(LivingEntity target) {
+ this.target = target;
+ }
+
+ public void clearTarget() {
+ this.target = null;
+ }
+
+ public void setFire(boolean fire) {
+ setStatus(0, fire);
+ }
+
+ public void setSneaking(boolean sneaking) {
+ setStatus(1, sneaking);
+ }
+
+ public void setSprinting(boolean sprinting) {
+ setStatus(3, sprinting);
+ }
+
+ public void setUseItem(boolean useItem) {
+ setStatus(4, useItem);
+ }
+
+ public void setInvisible(boolean invisible) {
+ setStatus(5, invisible);
+ }
+
+ private void setStatus(int data, boolean bool) {
+ DataWatcher dataWatcher = this.dataWatcher;
+ byte status = 0;
+ status = changeMask(status, data, bool);
+ //dataWatcher.a(0, status);
+ //dataWatcher.a(10, (byte) 127);
+ //dataWatcher.a(6, 20F);
+ }
+
+ public void followEntity(LivingEntity entity) {
+ double diffX = entity.getLocation().getX() - location.getX();
+ double diffY = (entity.getLocation().getY() + entity.getEyeHeight() * 0.9D) - location.getY() + 1.6F;
+ double diffZ = entity.getLocation().getZ() - location.getZ();
+ double hypoXZ = Math.sqrt(diffX * diffX + diffZ * diffZ);
+ float yaw = (float) (Math.atan2(diffZ, diffX) * 180D / Math.PI) - 90F;
+ float pitch = (float) -(Math.atan2(diffY, hypoXZ) * 18D / Math.PI);
+ look(yaw, pitch);
+
+ if(moveable) {
+ if(Math.abs(diffX) > 3D || Math.abs(diffZ) > 3D) {
+ yaw = (float) Math.toRadians(yaw);
+ double x = Math.sin(yaw);
+ double z = Math.cos(yaw);
+ move(x * MOVE_SPEED, 0, z * MOVE_SPEED);
+ }
+ }
+ }
+
+ private void move(double x, int y, double z) {
+ sendPackets(new PacketPlayOutEntity.PacketPlayOutRelEntityMoveLook(this.entityId, (byte) toFixedPointNumber(x), (byte) toFixedPointNumber(y), (byte) toFixedPointNumber(z), toAngle(location.getYaw()), toAngle(location.getPitch()), true));
+ this.location.add(toFixedPointNumber(x) / 32D, toFixedPointNumber(y) / 32D, toFixedPointNumber(z) / 32D);
+ this.armorStand.teleport(this.location);
+ }
+
+ public void spawn(Location location) {
+
+ PacketPlayOutNamedEntitySpawn playerSpawn = new PacketPlayOutNamedEntitySpawn();
+ set(playerSpawn, "a", this.entityId);
+ set(playerSpawn, "b", this.gameProfile.getId());
+ set(playerSpawn, "c", toFixedPointNumber(location.getX()));
+ set(playerSpawn, "d", toFixedPointNumber(location.getY()));
+ set(playerSpawn, "e", toFixedPointNumber(location.getZ()));
+ set(playerSpawn, "f", toAngle(location.getYaw()));
+ set(playerSpawn, "g", toAngle(location.getPitch()));
+ set(playerSpawn, "h", 0);
+ set(playerSpawn, "i", this.dataWatcher);
+
+ PacketPlayOutPlayerInfo playerInfo = new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER);
+ set(playerInfo, "b", Arrays.asList(playerInfo.new PlayerInfoData(this.gameProfile, 0, WorldSettings.EnumGamemode.NOT_SET, new ChatComponentText(this.gameProfile.getName()))));
+ sendPackets(playerInfo, playerSpawn);
+
+ this.location = location;
+ this.armorStand = (ArmorStand) location.getWorld().spawnEntity(location, EntityType.ARMOR_STAND);
+ this.armorStand.setGravity(true);
+ this.armorStand.setVisible(false);
+
+ this.task = tickTask.runTaskTimer(Core.getInstance(), 0L, 1L);
+ }
+
+ public void despawn() {
+ PacketPlayOutPlayerInfo playerInfo = new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.REMOVE_PLAYER);
+ set(playerInfo, "b", Arrays.asList(playerInfo.new PlayerInfoData(this.gameProfile, 0, null, null)));
+ sendPackets(new PacketPlayOutEntityDestroy(this.entityId), playerInfo);
+
+ this.armorStand.remove();
+ this.armorStand = null;
+ this.task.cancel();
+ }
+
+ public void removeTablist() {
+ PacketPlayOutPlayerInfo playerInfo = new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.REMOVE_PLAYER);
+ set(playerInfo, "b", Arrays.asList(playerInfo.new PlayerInfoData(this.gameProfile, 0, null, null)));
+ sendPackets(new PacketPlayOutEntityDestroy(this.entityId), playerInfo);
+ }
+
+
+ private void look(float yaw, float pitch) {
+ PacketPlayOutEntityHeadRotation headRotation = new PacketPlayOutEntityHeadRotation();
+ set(headRotation, "a", this.entityId);
+ set(headRotation, "b", toAngle(yaw));
+ sendPackets(headRotation, new PacketPlayOutEntity.PacketPlayOutEntityLook(this.entityId, toAngle(yaw), toAngle(pitch), false));
+ this.location.setYaw(yaw);
+ this.location.setPitch(pitch);
+ }
+
+ private int toFixedPointNumber(double value) {
+ return (int) Math.floor(value * 32D);
+ }
+
+ private byte toAngle(float value) {
+ return (byte) ((int) (value * 256.0F / 360.F));
+ }
+
+ public void sendPackets(Packet>... packets) {
+ for(Packet> packet : packets)
+ ((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet);
+ }
+
+ private void set(Object instance, String name, Object value) {
+ set(instance.getClass(), instance, name, value);
+ }
+
+ private void set(Class> clazz, Object instance, String name, Object value) {
+ try{
+ Field field = clazz.getDeclaredField(name);
+ field.setAccessible(true);
+ field.set(instance, value);
+ }catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ private Object get(Object instance, String name) {
+ return get(instance.getClass(), instance, name);
+ }
+
+ private Object get(Class> clazz, Object instance, String name) {
+ try{
+ Field field = clazz.getDeclaredField(name);
+ field.setAccessible(true);
+ return field.get(instance);
+ }catch (Exception e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/eu/univento/core/api/fakeplayer/PlayerKi.java b/src/main/java/eu/univento/core/api/fakeplayer/PlayerKi.java
new file mode 100644
index 0000000..4661219
--- /dev/null
+++ b/src/main/java/eu/univento/core/api/fakeplayer/PlayerKi.java
@@ -0,0 +1,51 @@
+package eu.univento.core.api.fakeplayer;
+
+import com.mojang.authlib.GameProfile;
+import eu.univento.core.api.utils.GameProfileBuilder;
+import org.bukkit.Material;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.block.Action;
+import org.bukkit.event.player.PlayerInteractEvent;
+
+import java.util.UUID;
+
+/**
+ * @author joethei
+ * @version 0.1
+ */
+public class PlayerKi implements Listener{
+
+ FakePlayer player;
+
+ public FakePlayer createPlayer(Player p, String uuid, String name, String skinUrl, String capeUrl) {
+ GameProfile gameProfile = GameProfileBuilder.getProfile(UUID.fromString(uuid), name, skinUrl, capeUrl);
+ return new FakePlayer(gameProfile, true, p);
+ }
+
+ @EventHandler
+ public void onInteract(PlayerInteractEvent e) {
+ if(e.getAction() == Action.RIGHT_CLICK_AIR) {
+ if(e.getItem().getType() == Material.DIAMOND) {
+ if(this.player != null) {
+ this.player.despawn();
+ }
+ FakePlayer player = createPlayer(e.getPlayer(), e.getPlayer().getUniqueId().toString(),
+ "TestUser", "http://textures.minecraft.net/texture/a116e69a845e227f7ca1fdde8c357c8c821ebd4ba619382ea4a1f87d4ae94",
+ "http://textures.minecraft.net/texture/3f688e0e699b3d9fe448b5bb50a3a288f9c589762b3dae8308842122dcb81");
+ this.player = player;
+ player.spawn(e.getPlayer().getLocation());
+ player.setTarget(e.getPlayer());
+ player.setSneaking(true);
+ player.removeTablist();
+ }
+ if(e.getItem().getType() == Material.DIAMOND_SWORD) {
+ player.despawn();
+ }
+ if(e.getItem().getType() == Material.NETHER_STAR) {
+ player.followEntity(e.getPlayer());
+ }
+ }
+ }
+}
diff --git a/src/main/java/eu/univento/core/api/gui/AnvilGUI.java b/src/main/java/eu/univento/core/api/gui/AnvilGUI.java
new file mode 100644
index 0000000..ad824a0
--- /dev/null
+++ b/src/main/java/eu/univento/core/api/gui/AnvilGUI.java
@@ -0,0 +1,224 @@
+package eu.univento.core.api.gui;
+
+import eu.univento.core.Core;
+import net.minecraft.server.v1_9_R1.*;
+import org.bukkit.Bukkit;
+import org.bukkit.craftbukkit.v1_9_R1.entity.CraftPlayer;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.Listener;
+import org.bukkit.event.inventory.InventoryClickEvent;
+import org.bukkit.event.inventory.InventoryCloseEvent;
+import org.bukkit.event.player.PlayerQuitEvent;
+import org.bukkit.inventory.Inventory;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.ItemMeta;
+
+import java.util.HashMap;
+
+/**
+ * Created by chasechocolate.
+ */
+public class AnvilGUI {
+ private class AnvilContainer extends ContainerAnvil {
+ public AnvilContainer(EntityHuman entity){
+ super(entity.inventory, entity.world,new BlockPosition(0, 0, 0), entity);
+ }
+
+ @Override
+ public boolean a(EntityHuman entityhuman){
+ return true;
+ }
+ }
+
+ public enum AnvilSlot {
+ INPUT_LEFT(0),
+ INPUT_RIGHT(1),
+ OUTPUT(2);
+
+ private int slot;
+
+ private AnvilSlot(int slot){
+ this.slot = slot;
+ }
+
+ public int getSlot(){
+ return slot;
+ }
+
+ public static AnvilSlot bySlot(int slot){
+ for(AnvilSlot anvilSlot : values()){
+ if(anvilSlot.getSlot() == slot){
+ return anvilSlot;
+ }
+ }
+
+ return null;
+ }
+ }
+
+ public class AnvilClickEvent {
+ private AnvilSlot slot;
+
+ private String name;
+
+ private boolean close = true;
+ private boolean destroy = true;
+
+ public AnvilClickEvent(AnvilSlot slot, String name){
+ this.slot = slot;
+ this.name = name;
+ }
+
+ public AnvilSlot getSlot(){
+ return slot;
+ }
+
+ public String getName(){
+ return name;
+ }
+
+ public boolean getWillClose(){
+ return close;
+ }
+
+ public void setWillClose(boolean close){
+ this.close = close;
+ }
+
+ public boolean getWillDestroy(){
+ return destroy;
+ }
+
+ public void setWillDestroy(boolean destroy){
+ this.destroy = destroy;
+ }
+ }
+
+ public interface AnvilClickEventHandler {
+ public void onAnvilClick(AnvilClickEvent event);
+ }
+
+ private Player player;
+
+ private AnvilClickEventHandler handler;
+
+ private HashMap items = new HashMap();
+
+ private Inventory inv;
+
+ private Listener listener;
+
+ public AnvilGUI(Player player, final AnvilClickEventHandler handler){
+ this.player = player;
+ this.handler = handler;
+
+ this.listener = new Listener(){
+ @EventHandler
+ public void onInventoryClick(InventoryClickEvent event){
+ if(event.getWhoClicked() instanceof Player){
+ Player clicker = (Player) event.getWhoClicked();
+
+ if(event.getInventory().equals(inv)){
+ event.setCancelled(true);
+
+ ItemStack item = event.getCurrentItem();
+ int slot = event.getRawSlot();
+ String name = "";
+
+ if(item != null){
+ if(item.hasItemMeta()){
+ ItemMeta meta = item.getItemMeta();
+
+ if(meta.hasDisplayName()){
+ name = meta.getDisplayName();
+ }
+ }
+ }
+
+ AnvilClickEvent clickEvent = new AnvilClickEvent(AnvilSlot.bySlot(slot), name);
+
+ handler.onAnvilClick(clickEvent);
+
+ if(clickEvent.getWillClose()){
+ event.getWhoClicked().closeInventory();
+ }
+
+ if(clickEvent.getWillDestroy()){
+ destroy();
+ }
+ }
+ }
+ }
+
+ @EventHandler
+ public void onInventoryClose(InventoryCloseEvent event){
+ if(event.getPlayer() instanceof Player){
+ Player player = (Player) event.getPlayer();
+ Inventory inv = event.getInventory();
+
+ if(inv.equals(AnvilGUI.this.inv)){
+ inv.clear();
+ destroy();
+ }
+ }
+ }
+
+ @EventHandler
+ public void onPlayerQuit(PlayerQuitEvent event){
+ if(event.getPlayer().equals(getPlayer())){
+ destroy();
+ }
+ }
+ };
+
+ Bukkit.getPluginManager().registerEvents(listener, Core.getInstance()); //Replace with instance of main class
+ }
+
+ public Player getPlayer(){
+ return player;
+ }
+
+ public void setSlot(AnvilSlot slot, ItemStack item){
+ items.put(slot, item);
+ }
+
+ public void open(){
+ EntityPlayer p = ((CraftPlayer) player).getHandle();
+
+ AnvilContainer container = new AnvilContainer(p);
+
+ //Set the items to the items from the inventory given
+ inv = container.getBukkitView().getTopInventory();
+
+ for(AnvilSlot slot : items.keySet()){
+ inv.setItem(slot.getSlot(), items.get(slot));
+ }
+
+ //Counter stuff that the game uses to keep track of inventories
+ int c = p.nextContainerCounter();
+
+ //Send the packet
+ p.playerConnection.sendPacket(new PacketPlayOutOpenWindow(c, "minecraft:anvil", new ChatMessage("Repairing", new Object[]{}), 0));
+
+ //Set their active container to the container
+ p.activeContainer = container;
+
+ //Set their active container window id to that counter stuff
+ p.activeContainer.windowId = c;
+
+ //Add the slot listener
+ p.activeContainer.addSlotListener(p);
+ }
+
+ public void destroy(){
+ player = null;
+ handler = null;
+ items = null;
+
+ HandlerList.unregisterAll(listener);
+
+ listener = null;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/eu/univento/core/api/items/ItemSkulls.java b/src/main/java/eu/univento/core/api/items/ItemSkulls.java
new file mode 100644
index 0000000..665a4ec
--- /dev/null
+++ b/src/main/java/eu/univento/core/api/items/ItemSkulls.java
@@ -0,0 +1,124 @@
+package eu.univento.core.api.items;
+
+import com.mojang.authlib.GameProfile;
+import com.mojang.authlib.properties.Property;
+import org.bukkit.Location;
+import org.bukkit.Material;
+import org.bukkit.block.Block;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.SkullMeta;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.Base64;
+import java.util.UUID;
+
+public class ItemSkulls
+{
+ private static Class> skullMetaClass;
+ private static Class> tileEntityClass;
+ private static Class> blockPositionClass;
+ private static int mcVersion;
+
+ static
+ {
+ String version = org.bukkit.Bukkit.getServer().getClass().getPackage().getName()
+ .split("\\.")[3];
+ mcVersion = Integer.parseInt(version.replaceAll("[^0-9]", ""));
+ try {
+ skullMetaClass = Class.forName("org.bukkit.craftbukkit." + version +
+ ".inventory.CraftMetaSkull");
+ tileEntityClass = Class.forName("net.minecraft.server." + version +
+ ".TileEntitySkull");
+ if (mcVersion > 174)
+ blockPositionClass = Class.forName("net.minecraft.server." +
+ version + ".BlockPosition");
+ else
+ blockPositionClass = null;
+ }
+ catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public static ItemStack getSkull(String skinURL)
+ {
+ return getSkull(skinURL, 1);
+ }
+
+ public static ItemStack getSkull(String skinURL, int amount)
+ {
+ ItemStack skull = new ItemStack(Material.SKULL_ITEM, amount, (short) 3);
+ SkullMeta meta = (SkullMeta)skull.getItemMeta();
+ try {
+ Field profileField = skullMetaClass.getDeclaredField("profile");
+ profileField.setAccessible(true);
+ profileField.set(meta, getProfile(skinURL));
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ skull.setItemMeta(meta);
+ return skull;
+ }
+
+ public static boolean setBlock(Location loc, String skinURL)
+ {
+ return setBlock(loc.getBlock(), skinURL);
+ }
+
+ public static boolean setBlock(Block block, String skinURL)
+ {
+ boolean flag = block.getType() == Material.SKULL;
+ if (!flag)
+ block.setType(Material.SKULL);
+ try
+ {
+ Object nmsWorld = block.getWorld().getClass()
+ .getMethod("getHandle", new Class[0]).invoke(block.getWorld(), new Object[0]);
+ Object tileEntity = null;
+
+ if (mcVersion <= 174) {
+ Method getTileEntity = nmsWorld.getClass().getMethod(
+ "getTileEntity", new Class[] { Integer.TYPE, Integer.TYPE, Integer.TYPE });
+ tileEntity = tileEntityClass.cast(getTileEntity.invoke(
+ nmsWorld, new Object[] { Integer.valueOf(block.getX()), Integer.valueOf(block.getY()), Integer.valueOf(block.getZ()) }));
+ } else {
+ Method getTileEntity = nmsWorld.getClass().getMethod(
+ "getTileEntity", new Class[] { blockPositionClass });
+ tileEntity = tileEntityClass.cast(getTileEntity.invoke(
+ nmsWorld, new Object[] {
+ getBlockPositionFor(block.getX(), block.getY(),
+ block.getZ()) }));
+ }
+
+ tileEntityClass.getMethod("setGameProfile", new Class[] { GameProfile.class })
+ .invoke(tileEntity, new Object[] { getProfile(skinURL) });
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ return !flag;
+ }
+
+ private static GameProfile getProfile(String skinURL) {
+ GameProfile profile = new GameProfile(UUID.randomUUID(), null);
+ String base64encoded = Base64.getEncoder().encodeToString(
+ new String("{textures:{SKIN:{url:\"" + skinURL + "\"}}}")
+ .getBytes());
+ Property property = new Property("textures", base64encoded);
+ profile.getProperties().put("textures", property);
+ return profile;
+ }
+
+ private static Object getBlockPositionFor(int x, int y, int z) {
+ Object blockPosition = null;
+ try {
+ Constructor> cons = blockPositionClass.getConstructor(new Class[] { Integer.TYPE,
+ Integer.TYPE, Integer.TYPE });
+ blockPosition = cons.newInstance(new Object[] { Integer.valueOf(x), Integer.valueOf(y), Integer.valueOf(z) });
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ return blockPosition;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/eu/univento/core/api/items/Pagifier.java b/src/main/java/eu/univento/core/api/items/Pagifier.java
new file mode 100644
index 0000000..8899d3a
--- /dev/null
+++ b/src/main/java/eu/univento/core/api/items/Pagifier.java
@@ -0,0 +1,67 @@
+package eu.univento.core.api.items;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
+/***************************
+* Pagifier by leNic *
+***************************/
+
+/**
+ * @author leNic
+ * @version 1.0
+ */
+ public class Pagifier {
+ // Properties
+ private int pageSize;
+ // List of pages
+ private List> pages;
+ // Constructor
+ public Pagifier(int pageSize){
+ this.pageSize = pageSize;
+ this.pages = new ArrayList<>();
+ // Create first page
+ this.pages.add(new ArrayList<>());
+ }
+ /**
+ * Add item to pages
+ * (Creates a new page if the previous page is not existing or full)
+ * @param item The item you want to add
+ */
+ public void addItem(T item){
+ int pageNum = pages.size() - 1;
+ List currentPage = this.pages.get(pageNum);
+ // Add page if full
+ if(currentPage.size() >= this.pageSize) {
+ currentPage = new ArrayList<>();
+ this.pages.add(currentPage);
+ pageNum++;
+ }
+ currentPage.add(item);
+ }
+ /**
+ * Get the items of a page
+ * @param pageNum Number of the page (beginning at 0)
+ * @return Optional with a list of the page's items
+ */
+ public Optional> getPage(int pageNum){
+ if(this.pages.size() == 0)
+ return Optional.empty();
+ return Optional.of(this.pages.get(pageNum));
+ }
+ /**
+ * Get all pages
+ * @return List containing all pages
+ */
+ public List> getPages(){
+ return this.pages;
+ }
+ /**
+ * Get the current set page size
+ * @return The current page size
+ */
+ public int getPageSize(){
+ return this.pageSize;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/eu/univento/core/api/languages/Language_DE.java b/src/main/java/eu/univento/core/api/languages/Language_DE.java
new file mode 100644
index 0000000..46eb57d
--- /dev/null
+++ b/src/main/java/eu/univento/core/api/languages/Language_DE.java
@@ -0,0 +1,557 @@
+package eu.univento.core.api.languages;
+
+import eu.univento.core.api.player.CustomPlayer;
+import eu.univento.core.api.player.Perms;
+
+/**
+ * @author joethei
+ * @version 1.0
+ */
+
+public class Language_DE implements Languages{
+
+ @Override
+ public String UNKNOWN_ERROR() {
+ return "§cEs ist ein unbekannter Fehler aufgetreten";
+ }
+
+ @Override
+ public String NO_PERMS() {
+ return "§cDu hast keine Berechtigung diesen Befehl auszuführen";
+ }
+
+ @Override
+ public String ERROR() {
+ return "§cFehler: ";
+ }
+
+ @Override
+ public String NOT_ONLINE(String name) {
+ return "§7" + name + " ist §cnicht §7online";
+ }
+
+ @Override
+ public String KICK_RESTART() {
+ return "§cDer Server wurde neu gestartet";
+ }
+
+ @Override
+ public String KICK_FULL() {
+ return "§cDieser Server ist bereits voll";
+ }
+
+ @Override
+ public String COMMAND_NOT_FOUND() {
+ return "§cDieser Befehl konnte nicht gefunden werden";
+ }
+
+ @Override
+ public String Core_FIX_OWN() {
+ return "§7Du wurdest §egefixt";
+ }
+
+ @Override
+ public String Core_FIX_OTHER(CustomPlayer p) {
+ return "§7Du hast " + p.getDisplayName() + " §egefixt";
+ }
+
+ @Override
+ public String Core_FIX_BY_OTHER(CustomPlayer p) {
+ return "§7Du wurdest von " + p.getDisplayName() + " §egefixt";
+ }
+
+ @Override
+ public String Core_NICK_ON() {
+ return "§7Du hast einen §eNicknamen §7zugewiesen bekommen";
+ }
+
+ @Override
+ public String Core_NICK_OFF() {
+ return "§7Du hast nun §ckeinen §eNicknamen §7mehr";
+ }
+
+ @Override
+ public String Core_BUILD_ON() {
+ return "§7Du hast den Baumodus §abetreten";
+ }
+
+ @Override
+ public String Core_BUILD_OFF() {
+ return "§7Du hast den Baumodus §cverlassen";
+ }
+
+ @Override
+ public String Core_BAN_NO_REASON() {
+ return "§cDieser Grund exsistiert nicht";
+ }
+
+ @Override
+ public String Core_BAN_USAGE() {
+ return "§cNutze ";
+ }
+
+ @Override
+ public String Core_BAN_BANNED(CustomPlayer p) {
+ return "§7Du hast " + p.getColor() + p.getDisplayName() + " §cgebannt";
+ }
+
+ @Override
+ public String Core_GM_USAGE() {
+ return "§7Nutze §e/gm <0 | 1 | 2 | 3>";
+ }
+
+ @Override
+ public String Core_GM_CHANGED() {
+ return "§7Dein Spielmodus wurde §ageändert";
+ }
+
+ @Override
+ public String Core_GLOBALMUTE_ON() {
+ return "§7Der Server wurde §cstumm gestellt";
+ }
+
+ @Override
+ public String Core_GLOBALMUTE_OFF() {
+ return "§7Der Server wurde §asozial §7gestellt";
+ }
+
+ @Override
+ public String Core_RUNAS_USAGE() {
+ return "§cFühre /runas ";
+ }
+
+ @Override
+ public String Core_RUNAS_RUN(CustomPlayer p) {
+ return "§7Der Spieler " + p.getColor() + p.getDisplayName() + " §7hat deinen Befehl §eerfolgreich §7ausgeführt";
+ }
+
+ @Override
+ public String Core_SETRANK_USAGE() {
+ return "§cNutze /setrank ";
+ }
+
+ @Override
+ public String Core_SETRANK_KICK() {
+ return "\n§aDu hast nun einen neuen Rang.§e\nBitte joine neu§7.";
+ }
+
+ @Override
+ public String Core_SETRANK_NO_RANK() {
+ return "§cDieser Rang exsistiert nicht";
+ }
+
+ @Override
+ public String Core_SETRANK_SET(CustomPlayer p, Perms.Ranks rank) {
+ return "§7Du hast dem Spieler " + p.getDisplayName() + " auf §e" + rank.toString() + " §7gesetzt";
+ }
+ @Override
+ public String Core_TS_ALLREADY_VERIFIED() {
+ return "§cDu hast bereits einen verifizierten Account";
+ }
+
+ @Override
+ public String Core_TS_VERIFIED() {
+ return "§7Du hast deinen Account §eerfolgreich §7verifiziert";
+ }
+
+ @Override
+ public String Core_VANISH_ON() {
+ return "§7Du bist nun §aunsichtbar";
+ }
+
+ @Override
+ public String Core_VANISH_OFF() {
+ return "§7Du bist nun wieder §csichtbar";
+ }
+
+ @Override
+ public String Core_SERVER_MUTED() {
+ return "§7Der Chat ist bis auf weiteres §cgesperrt";
+ }
+
+ @Override
+ public String Core_CHAT_CLEARED(CustomPlayer p) {
+ return "§7Der Chat wurde von " + p.getColor() + p.getDisplayName() + " §cgereinigt";
+ }
+
+ @Override
+ public String Core_TAB_TITLE() {
+ return "§7Du spielst auf §e";
+ }
+
+ @Override
+ public String Lobby_PLAYERS_HIDE() {
+ return "§7Du kannst nun §ckeine §7Spieler mehr sehen";
+ }
+
+ @Override
+ public String Lobby_PLAYERS_SHOW() {
+ return "§7Du kannst nun §aalle §7Spieler sehen";
+ }
+
+ @Override
+ public String Lobby_AUTONICK_ON() {
+ return "§7Du §aerhälst §7nun einen automatischen §eNicknamen";
+ }
+
+ @Override
+ public String Lobby_AUTONICK_OFF() {
+ return "§7Du hast nun §ckeinen §7automatischen §eNicknamen §7mehr";
+ }
+
+ @Override
+ public String Lobby_FORCEFIELD_ON() {
+ return "§7Du hast das §eSchutzschild §aaktiviert";
+ }
+
+ @Override
+ public String Lobby_FORCEFIELD_OFF() {
+ return "§7Du hast das §eSchutzschild §cdeaktiviert";
+ }
+
+ @Override
+ public String Lobby_SILENT_LOBBY_ON() {
+ return "§7Du hast die §eSilent-Lobby §abetreten";
+ }
+
+ @Override
+ public String Lobby_SILENT_LOBBY_OFF() {
+ return "§7Du hast die §eSilent-Lobby §cverlassen";
+ }
+
+ @Override
+ public String Lobby_PLAYING_MUSIC_PREFIX() {
+ return "§6Jetzt spielt: ";
+ }
+
+ @Override
+ public String Lobby_FOUND_ITEM_PREFIX() {
+ return "§7Du hast etwas §egefunden";
+ }
+
+ @Override
+ public String Lobby_SET_LOCATION() {
+ return "§aPosition wurde gesetzt";
+ }
+
+ @Override
+ public String Lobby_SET_LOCATION_USAGE() {
+ return "§cNutze /setloc ";
+ }
+
+ @Override
+ public String Lobby_DROP_ITEM_USAGE() {
+ return "§cNutze /dropitem ";
+ }
+
+ @Override
+ public String Lobby_DROP_ITEM() {
+ return "§aDu hast ein Item gelegt";
+ }
+
+ @Override
+ public String Lobby_SET_SIGN() {
+ return "§aNeues Status Schild erstellt";
+ }
+
+ @Override
+ public String Lobby_JOIN_TITLE_1() {
+ return "§6univento§7.§eeu";
+ }
+
+ @Override
+ public String Lobby_JOIN_TITLE_2() {
+ return "§cIch putze hier nur";
+ }
+
+ @Override
+ public String Lobby_PET_ADD() {
+ return "§7Du hast nun ein §eHaustier";
+ }
+
+ @Override
+ public String Lobby_PET_REMOVE() {
+ return "§7Du hast nun §ckein §eHaustier §7mehr";
+ }
+
+ @Override
+ public String Lobby_PARKOUR_ON() {
+ return "§7Du hast den §eParkourmodus §abetreten";
+ }
+
+ @Override
+ public String Lobby_PARKOUR_OFF() {
+ return "§7Du hast den §eParkourmodus §cverlassen";
+ }
+
+ @Override
+ public String LobbyItems_NAVIGATOR() {
+ return "§eNavigator";
+ }
+
+ @Override
+ public String LobbyItems_PLAYER_HIDER_ON() {
+ return "§cSpieler verstecken";
+ }
+
+ @Override
+ public String LobbyItems_PLAYER_HIDER_OFF() {
+ return "§aSpieler anzeigen";
+ }
+
+ @Override
+ public String LobbyItems_AUTO_NICK() {
+ return "§5AutoNick";
+ }
+
+ @Override
+ public String LobbyItems_SILENT_LOBBY() {
+ return "§cSilent-Lobby";
+ }
+
+ @Override
+ public String LobbyItems_FORCEFIELD() {
+ return "§aSchutzschild";
+ }
+
+ @Override
+ public String LobbyItems_FUN_CHEST() {
+ return "§cF§aU§eN§3Chest";
+ }
+
+ @Override
+ public String LobbyItems_PROFILE() {
+ return "§eDein Profil";
+ }
+
+ @Override
+ public String LobbyItems_YOUTUBER() {
+ return "§5Youtuber Funktionen";
+ }
+
+ @Override
+ public String LobbyItems_SUGGESTION() {
+ return "§6Vorschläge";
+ }
+
+ @Override
+ public String LobbyItems_SPAWN() {
+ return "§6Spawn";
+ }
+
+ @Override
+ public String LobbyItems_PREMIUMHUB() {
+ return "§6Premium Lobby";
+ }
+
+ @Override
+ public String LobbyItems_MAYA() {
+ return "§6Maya";
+ }
+
+ @Override
+ public String LobbyItems_WOOLGET() {
+ return "§6WoolGet";
+ }
+
+ @Override
+ public String LobbyItems_BUILDSERVER() {
+ return "§aBau-Server";
+ }
+
+ @Override
+ public String LobbyItems_PLAYERS_ONLINE() {
+ return " §6Spieler online";
+ }
+
+ @Override
+ public String LobbyItems_GADGETS() {
+ return "§6Gadgets";
+ }
+
+ @Override
+ public String LobbyItems_MUSIC() {
+ return "§6Musik";
+ }
+
+ @Override
+ public String LobbyItems_PARTICLE() {
+ return "§6Partikel";
+ }
+
+ @Override
+ public String LobbyItems_PETS() {
+ return "§6Haustiere";
+ }
+
+ @Override
+ public String LobbyItems_YOUR_PET() {
+ return "§6Dein Haustier";
+ }
+
+ @Override
+ public String LobbyItems_PETS_NAME() {
+ return "§6Namen ändern";
+ }
+
+ @Override
+ public String LobbyItems_PETS_AGE() {
+ return "§6Alter ändern";
+ }
+
+ @Override
+ public String LobbyItems_PETS_RIDE() {
+ return "§6Reiten";
+ }
+
+ @Override
+ public String LobbyItems_PETS_REMOVE() {
+ return "§6Haustier entfernen";
+ }
+
+ @Override
+ public String LobbyItems_PETS_PIG() {
+ return "§6Schwein";
+ }
+
+ @Override
+ public String LobbyItems_PETS_COW() {
+ return "§6Kuh";
+ }
+
+ @Override
+ public String LobbyItems_PETS_CHICKEN() {
+ return "§6Hühnchen";
+ }
+
+ @Override
+ public String LobbyItems_PETS_RABBIT() {
+ return "§6Hase";
+ }
+
+ @Override
+ public String LobbyItems_PETS_MUSHROM_COW() {
+ return "§6Pilzkuh";
+ }
+
+ @Override
+ public String LobbyItems_PLAYER_MENU() {
+ return " Menü";
+ }
+
+ @Override
+ public String LobbyItems_PLAYER_FRIEND() {
+ return "§6Freundschaftsanfrage senden";
+ }
+
+ @Override
+ public String LobbyItems_PLAYER_PARTY() {
+ return "§6Party Anfrage senden";
+ }
+
+ @Override
+ public String LobbyItems_PLAYER_PROFILE() {
+ return "§6Profil";
+ }
+
+ @Override
+ public String LobbyItems_PLAYER_STATS() {
+ return "§6Statistiken";
+ }
+
+ @Override
+ public String LobbyItems_STATS() {
+ return "§6Deine Statistiken";
+ }
+
+ @Override
+ public String LobbyItems_FRIENDS() {
+ return "§6Freunde";
+ }
+
+ @Override
+ public String LobbyItems_SETTINGS() {
+ return "§eEinstellungen";
+ }
+
+ @Override
+ public String LobbyItems_SETTINGS_FASTMENU() {
+ return "§6Inventar Animation";
+ }
+
+ @Override
+ public String LobbyItems_SETTINGS_SERVER_TELEPORT() {
+ return "§6Server-Teleport";
+ }
+
+ @Override
+ public String LobbyItems_SETTINGS_PARTY_REQUESTS() {
+ return "§6Party Anfragen";
+ }
+
+ @Override
+ public String LobbyItems_SETTINGS_FRIEND_REQUESTS() {
+ return "§6Freundschafts Anfragen";
+ }
+
+ @Override
+ public String LobbyItems_SETTINGS_CHATSOUNDS() {
+ return "§6Chat Geräusche";
+ }
+
+ @Override
+ public String LobbyItems_SETTINGS_EFFECTS() {
+ return "§6Effekte";
+ }
+
+ @Override
+ public String LobbyItems_SETTINGS_LANGUAGES() {
+ return "§6Sprachen";
+ }
+
+ @Override
+ public String LobbyItems_SETTINGS_ON() {
+ return "§aaktiviert";
+ }
+
+ @Override
+ public String LobbyItems_SETTINGS_OFF() {
+ return "§cdeaktiviert";
+ }
+
+ @Override
+ public String LobbyItems_BACK() {
+ return "§cZurück";
+ }
+
+ @Override
+ public String LobbyBoard_FOUND_SECRETS() {
+ return "§eVerstecke§7:";
+ }
+
+ @Override
+ public String LobbyBoard_COINS() {
+ return "§eDeine Coins§7:";
+ }
+
+ @Override
+ public String LobbyBoard_TS() {
+ return "§eTeamSpeak§7:";
+ }
+
+ @Override
+ public String LobbyBoard_FORUM() {
+ return "§eForum§7:";
+ }
+
+ @Override
+ public String LobbyBoard_NEW() {
+ return "§e§lJetzt neu:";
+ }
+
+ @Override
+ public String LobbyBoard_NEWS() {
+ return "Scheibenwischer";
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/eu/univento/core/api/languages/Language_EN.java b/src/main/java/eu/univento/core/api/languages/Language_EN.java
new file mode 100644
index 0000000..d8a0af6
--- /dev/null
+++ b/src/main/java/eu/univento/core/api/languages/Language_EN.java
@@ -0,0 +1,556 @@
+package eu.univento.core.api.languages;
+
+import eu.univento.core.api.player.CustomPlayer;
+import eu.univento.core.api.player.Perms;
+
+/**
+ * @author joethei
+ * @version 0.1
+ */
+public class Language_EN implements Languages{
+
+ @Override
+ public String UNKNOWN_ERROR() {
+ return "§cEs ist ein unbekannter Fehler aufgetreten";
+ }
+
+ @Override
+ public String NO_PERMS() {
+ return "§cYou're not allowed do use this command";
+ }
+
+ @Override
+ public String ERROR() {
+ return "§cERROR: ";
+ }
+
+ @Override
+ public String NOT_ONLINE(String name) {
+ return "§7" + name + " is §cnot §7online";
+ }
+
+ @Override
+ public String KICK_RESTART() {
+ return "§cThe server has been restarted";
+ }
+
+ @Override
+ public String KICK_FULL() {
+ return "§cThe server is full";
+ }
+
+ @Override
+ public String COMMAND_NOT_FOUND() {
+ return "§cThis command hasn't been found.";
+ }
+
+ @Override
+ public String Core_FIX_OWN() {
+ return "§7You were §efixed";
+ }
+
+ @Override
+ public String Core_FIX_OTHER(CustomPlayer p) {
+ return "§7You §efixed " + p.getDisplayName();
+ }
+
+ @Override
+ public String Core_FIX_BY_OTHER(CustomPlayer p) {
+ return "§7You've been §efixed §7by " + p.getDisplayName();
+ }
+
+ @Override
+ public String Core_NICK_ON() {
+ return "§7You got a §enickname";
+ }
+
+ @Override
+ public String Core_NICK_OFF() {
+ return "§7Now you have §cno more keinen §enickname";
+ }
+
+ @Override
+ public String Core_BUILD_ON() {
+ return "§7You've §ajoined §7the building-mode";
+ }
+
+ @Override
+ public String Core_BUILD_OFF() {
+ return "§7You've §cleft §7the building-mode";
+ }
+
+ @Override
+ public String Core_BAN_NO_REASON() {
+ return "§cThis reason doesn't exist";
+ }
+
+ @Override
+ public String Core_BAN_USAGE() {
+ return "§cUse ";
+ }
+
+ @Override
+ public String Core_BAN_BANNED(CustomPlayer p) {
+ return "§7You've §cbanned " + p.getColor() + p.getDisplayName();
+ }
+
+ @Override
+ public String Core_GM_USAGE() {
+ return "§7Use §e/gm <0 | 1 | 2 | 3>";
+ }
+
+ @Override
+ public String Core_GM_CHANGED() {
+ return "§7You're gamemode has been §achanged";
+ }
+
+ @Override
+ public String Core_GLOBALMUTE_ON() {
+ return "§7The server has been §cmuted";
+ }
+
+ @Override
+ public String Core_GLOBALMUTE_OFF() {
+ return "§7The server has been §aunmuted";
+ }
+
+ @Override
+ public String Core_RUNAS_USAGE() {
+ return "§cUse /runas ";
+ }
+
+ @Override
+ public String Core_RUNAS_RUN(CustomPlayer p) {
+ return "§7The player " + p.getColor() + p.getDisplayName() + " §7has executed your command §esuccesfully";
+ }
+
+ @Override
+ public String Core_SETRANK_USAGE() {
+ return "§cUse /setrank ";
+ }
+
+ @Override
+ public String Core_SETRANK_KICK() {
+ return "\n§aYou've got a new rank,§e\nplease rejoin§7.";
+ }
+
+ @Override
+ public String Core_SETRANK_NO_RANK() {
+ return "§cThis rank doesn't exist";
+ }
+
+ @Override
+ public String Core_SETRANK_SET(CustomPlayer p, Perms.Ranks rank) {
+ return "§7You gave " + p.getDisplayName() + " the rank §e" + rank.toString();
+ }
+
+ @Override
+ public String Core_TS_ALLREADY_VERIFIED() {
+ return "§cYou've already had a verificated account";
+ }
+
+ @Override
+ public String Core_TS_VERIFIED() {
+ return "§7You verificated your account §esuccesfully";
+ }
+
+ @Override
+ public String Core_VANISH_ON() {
+ return "§7You are now §aunvisible";
+ }
+
+ @Override
+ public String Core_VANISH_OFF() {
+ return "§7You are now §cvisible §7again";
+ }
+
+ @Override
+ public String Core_SERVER_MUTED() {
+ return "§7The chat has been §cblocked";
+ }
+
+ @Override
+ public String Core_CHAT_CLEARED(CustomPlayer p) {
+ return "§7The chat has been §ccleaned §7by " + p.getColor() + p.getDisplayName();
+ }
+
+ @Override
+ public String Core_TAB_TITLE() {
+ return "§7You're playing on §e";
+ }
+
+ @Override
+ public String Lobby_PLAYERS_HIDE() {
+ return "§7You've §chidden §7all other players";
+ }
+
+ @Override
+ public String Lobby_PLAYERS_SHOW() {
+ return "§7Now you can §asee §7all other players ";
+ }
+
+ @Override
+ public String Lobby_AUTONICK_ON() {
+ return "§7You'll §aget an automatical §enickname";
+ }
+
+ @Override
+ public String Lobby_AUTONICK_OFF() {
+ return "§7You're §cnot getting an automatical §enickname §eanymore";
+ }
+
+ @Override
+ public String Lobby_FORCEFIELD_ON() {
+ return "§7You §aactivated §7your §eforcefield";
+ }
+
+ @Override
+ public String Lobby_FORCEFIELD_OFF() {
+ return "§7You §cdeactivated §7your §eforcefield";
+ }
+
+ @Override
+ public String Lobby_SILENT_LOBBY_ON() {
+ return "§7You §ajoined §7the §esilent-lobby";
+ }
+
+ @Override
+ public String Lobby_SILENT_LOBBY_OFF() {
+ return "§7You §eleft §7the §esilent-lobby";
+ }
+
+ @Override
+ public String Lobby_PLAYING_MUSIC_PREFIX() {
+ return "§6Now playing: ";
+ }
+
+ @Override
+ public String Lobby_FOUND_ITEM_PREFIX() {
+ return "§7You've §efound §7something";
+ }
+
+ @Override
+ public String Lobby_SET_LOCATION() {
+ return "§aPoisition has been set";
+ }
+
+ @Override
+ public String Lobby_SET_LOCATION_USAGE() {
+ return "§cUse /setloc ";
+ }
+
+ @Override
+ public String Lobby_DROP_ITEM_USAGE() {
+ return "§cUse /dropitem ";
+ }
+
+ @Override
+ public String Lobby_DROP_ITEM() {
+ return "§aYou set an item";
+ }
+
+ @Override
+ public String Lobby_SET_SIGN() {
+ return "§aNeues Status Schild erstellt";
+ }
+
+ @Override
+ public String Lobby_JOIN_TITLE_1() {
+ return "§6univento§7.§eeu";
+ }
+
+ @Override
+ public String Lobby_JOIN_TITLE_2() {
+ return "§cI'm just cleaning hear";
+ }
+
+ @Override
+ public String Lobby_PET_ADD() {
+ return "§7Now you have a §epet";
+ }
+
+ @Override
+ public String Lobby_PET_REMOVE() {
+ return "§7Du hast nun §ckein §eHaustier §7mehr";
+ }
+
+ @Override
+ public String Lobby_PARKOUR_ON() {
+ return "§7You §ajoined §7the §eparkour mode";
+ }
+
+ @Override
+ public String Lobby_PARKOUR_OFF() {
+ return "§7You §cleft §7the §eparkour mode";
+ }
+
+ @Override
+ public String LobbyItems_NAVIGATOR() {
+ return "§eNavigator";
+ }
+
+ @Override
+ public String LobbyItems_PLAYER_HIDER_ON() {
+ return "§cHide players";
+ }
+
+ @Override
+ public String LobbyItems_PLAYER_HIDER_OFF() {
+ return "§aShow players";
+ }
+
+ @Override
+ public String LobbyItems_AUTO_NICK() {
+ return "§5AutoNick";
+ }
+
+ @Override
+ public String LobbyItems_SILENT_LOBBY() {
+ return "§cSilent-Lobby";
+ }
+
+ @Override
+ public String LobbyItems_FORCEFIELD() {
+ return "§aForcefield";
+ }
+
+ @Override
+ public String LobbyItems_FUN_CHEST() {
+ return "§cF§aU§eN§3Chest";
+ }
+
+ @Override
+ public String LobbyItems_PROFILE() {
+ return "§eYour profile";
+ }
+
+ @Override
+ public String LobbyItems_YOUTUBER() {
+ return "§5Youtuber Funktionen";
+ }
+
+ @Override
+ public String LobbyItems_SUGGESTION() {
+ return "§6Suggestions";
+ }
+
+ @Override
+ public String LobbyItems_SPAWN() {
+ return "§6Spawn";
+ }
+
+ @Override
+ public String LobbyItems_PREMIUMHUB() {
+ return "§6Premium Lobby";
+ }
+
+ @Override
+ public String LobbyItems_MAYA() {
+ return "§6Maya";
+ }
+
+ @Override
+ public String LobbyItems_WOOLGET() {
+ return "§6WoolGet";
+ }
+
+ @Override
+ public String LobbyItems_BUILDSERVER() {
+ return "§aBuilding-Server";
+ }
+
+ @Override
+ public String LobbyItems_PLAYERS_ONLINE() {
+ return " §6players online";
+ }
+
+ @Override
+ public String LobbyItems_GADGETS() {
+ return "§6Gadgets";
+ }
+
+ @Override
+ public String LobbyItems_MUSIC() {
+ return "§6Music";
+ }
+
+ @Override
+ public String LobbyItems_PARTICLE() {
+ return "§6Particles";
+ }
+
+ @Override
+ public String LobbyItems_PETS() {
+ return "§6Pets";
+ }
+
+ @Override
+ public String LobbyItems_YOUR_PET() {
+ return "§6your pet";
+ }
+
+ @Override
+ public String LobbyItems_PETS_NAME() {
+ return "§6change name";
+ }
+
+ @Override
+ public String LobbyItems_PETS_AGE() {
+ return "§6change age";
+ }
+
+ @Override
+ public String LobbyItems_PETS_RIDE() {
+ return "§6ride";
+ }
+
+ @Override
+ public String LobbyItems_PETS_REMOVE() {
+ return "§6ride pet";
+ }
+
+ @Override
+ public String LobbyItems_PETS_PIG() {
+ return "§6pig";
+ }
+
+ @Override
+ public String LobbyItems_PETS_COW() {
+ return "§6cow";
+ }
+
+ @Override
+ public String LobbyItems_PETS_CHICKEN() {
+ return "§6chicken";
+ }
+
+ @Override
+ public String LobbyItems_PETS_RABBIT() {
+ return "§6rabbit";
+ }
+
+ @Override
+ public String LobbyItems_PETS_MUSHROM_COW() {
+ return "§6mushroom-cow";
+ }
+
+ @Override
+ public String LobbyItems_PLAYER_MENU() {
+ return " menu";
+ }
+
+ @Override
+ public String LobbyItems_PLAYER_FRIEND() {
+ return "§6send freind request";
+ }
+
+ @Override
+ public String LobbyItems_PLAYER_PARTY() {
+ return "§6send party request";
+ }
+
+ @Override
+ public String LobbyItems_PLAYER_PROFILE() {
+ return "§6Profil";
+ }
+
+ @Override
+ public String LobbyItems_PLAYER_STATS() {
+ return "§6stats";
+ }
+
+ @Override
+ public String LobbyItems_STATS() {
+ return "§6Deine Statistiken";
+ }
+
+ @Override
+ public String LobbyItems_FRIENDS() {
+ return "§6friends";
+ }
+
+ @Override
+ public String LobbyItems_SETTINGS() {
+ return "§eSettings";
+ }
+
+ @Override
+ public String LobbyItems_SETTINGS_FASTMENU() {
+ return "§6inventory animations";
+ }
+
+ @Override
+ public String LobbyItems_SETTINGS_SERVER_TELEPORT() {
+ return "§6Server-Teleport";
+ }
+
+ @Override
+ public String LobbyItems_SETTINGS_PARTY_REQUESTS() {
+ return "§6party requests";
+ }
+
+ @Override
+ public String LobbyItems_SETTINGS_FRIEND_REQUESTS() {
+ return "§6friend requests";
+ }
+
+ @Override
+ public String LobbyItems_SETTINGS_CHATSOUNDS() {
+ return "§6chat sounds";
+ }
+
+ @Override
+ public String LobbyItems_SETTINGS_EFFECTS() {
+ return "§6effects";
+ }
+
+ @Override
+ public String LobbyItems_SETTINGS_LANGUAGES() {
+ return "§6languages";
+ }
+
+ @Override
+ public String LobbyItems_SETTINGS_ON() {
+ return "§aactivated";
+ }
+
+ @Override
+ public String LobbyItems_SETTINGS_OFF() {
+ return "§cdeactivated";
+ }
+
+ @Override
+ public String LobbyItems_BACK() {
+ return "§cback";
+ }
+
+ @Override
+ public String LobbyBoard_FOUND_SECRETS() {
+ return "§eSecrets§7:";
+ }
+
+ @Override
+ public String LobbyBoard_COINS() {
+ return "§eYour coins§7:";
+ }
+
+ @Override
+ public String LobbyBoard_TS() {
+ return "§eTeamSpeak§7:";
+ }
+
+ @Override
+ public String LobbyBoard_FORUM() {
+ return "§eForum§7:";
+ }
+
+ @Override
+ public String LobbyBoard_NEW() {
+ return "§e§lNew:";
+ }
+
+ @Override
+ public String LobbyBoard_NEWS() {
+ return "Scheibenwischer";
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/eu/univento/core/api/languages/Language_IT.java b/src/main/java/eu/univento/core/api/languages/Language_IT.java
new file mode 100644
index 0000000..4be78ad
--- /dev/null
+++ b/src/main/java/eu/univento/core/api/languages/Language_IT.java
@@ -0,0 +1,556 @@
+package eu.univento.core.api.languages;
+
+import eu.univento.core.api.player.CustomPlayer;
+import eu.univento.core.api.player.Perms;
+
+/**
+ * @author joethei
+ * @version 0.1
+ */
+public class Language_IT implements Languages{
+
+ @Override
+ public String UNKNOWN_ERROR() {
+ return "§cSi è presentato un errore sconosciuto";
+ }
+
+ @Override
+ public String NO_PERMS() {
+ return "§cNon hai accesso a quel commando";
+ }
+
+ @Override
+ public String ERROR() {
+ return "§cErrore: ";
+ }
+
+ @Override
+ public String NOT_ONLINE(String name) {
+ return "§7" + name + " §cnon §7è online";
+ }
+
+ @Override
+ public String KICK_RESTART() {
+ return "§cIl server è stato riavviato";
+ }
+
+ @Override
+ public String KICK_FULL() {
+ return "§cQuesto server è pieno";
+ }
+
+ @Override
+ public String COMMAND_NOT_FOUND() {
+ return "§cNon è stato trovato questo commando";
+ }
+
+ @Override
+ public String Core_FIX_OWN() {
+ return "§7Tu sei stato §efissato";
+ }
+
+ @Override
+ public String Core_FIX_OTHER(CustomPlayer p) {
+ return "§7Tu hai §efissato " + p.getDisplayName();
+ }
+
+ @Override
+ public String Core_FIX_BY_OTHER(CustomPlayer p) {
+ return "§7Tu sei stato §efissato §7da" + p.getDisplayName();
+ }
+
+ @Override
+ public String Core_NICK_ON() {
+ return "§7Hai ricevuto un §eNickname";
+ }
+
+ @Override
+ public String Core_NICK_OFF() {
+ return "§7Adesso §cnon §7hai più un §eNickname";
+ }
+
+ @Override
+ public String Core_BUILD_ON() {
+ return "§7Tu sei §aentrato §7nel §emodo di costruzione";
+ }
+
+ @Override
+ public String Core_BUILD_OFF() {
+ return "§7Tu sei §auscito §7dal §emodo di costruzione";
+ }
+
+ @Override
+ public String Core_BAN_NO_REASON() {
+ return "§cQuesto motivo non esiste";
+ }
+
+ @Override
+ public String Core_BAN_USAGE() {
+ return "§cDevi usare /ban ";
+ }
+
+ @Override
+ public String Core_BAN_BANNED(CustomPlayer p) {
+ return "§7Tu hai §ebannato " + p.getColor() + p.getDisplayName();
+ }
+
+ @Override
+ public String Core_GM_USAGE() {
+ return "§7Usi §e/gm <0 | 1 | 2 | 3>";
+ }
+
+ @Override
+ public String Core_GM_CHANGED() {
+ return "§7La tua modalitá del gioco è stata §aaggiornata";
+ }
+
+ @Override
+ public String Core_GLOBALMUTE_ON() {
+ return "§7Il server è stato messo §csilenzioso";
+ }
+
+ @Override
+ public String Core_GLOBALMUTE_OFF() {
+ return "§7Il server è stato rimesso §cnormale";
+ }
+
+ @Override
+ public String Core_RUNAS_USAGE() {
+ return "§cUsi /runas ";
+ }
+
+ @Override
+ public String Core_RUNAS_RUN(CustomPlayer p) {
+ return p.getColor() + p.getDisplayName() + " §7ha eseguito il tuo commando";
+ }
+
+ @Override
+ public String Core_SETRANK_USAGE() {
+ return "§cUsi /setrank ";
+ }
+
+ @Override
+ public String Core_SETRANK_KICK() {
+ return "\n§aHai un nuovo gruppo§e\nti prego di rientrare il server§7.";
+ }
+
+ @Override
+ public String Core_SETRANK_NO_RANK() {
+ return "§cQuesto gruppo non esiste";
+ }
+
+ @Override
+ public String Core_SETRANK_SET(CustomPlayer p, Perms.Ranks rank) {
+ return "§7Hai dato " + p.getDisplayName() + " il gruppo §e" + rank.toString();
+ }
+ @Override
+ public String Core_TS_ALLREADY_VERIFIED() {
+ return "§cTu hai già un account verificato";
+ }
+
+ @Override
+ public String Core_TS_VERIFIED() {
+ return "§7Hai verificato il tuo account con §esuccesso";
+ }
+
+ @Override
+ public String Core_VANISH_ON() {
+ return "§7Adesso sei §ainvisibile §7per gli altri";
+ }
+
+ @Override
+ public String Core_VANISH_OFF() {
+ return "§7Adesso sei §crivisibile §7per gli altri";
+ }
+
+ @Override
+ public String Core_SERVER_MUTED() {
+ return "§7Il chat è stato §cmutato";
+ }
+
+ @Override
+ public String Core_CHAT_CLEARED(CustomPlayer p) {
+ return "§7La chat è stata §cpulita §7da " + p.getColor() + p.getDisplayName();
+ }
+
+ @Override
+ public String Core_TAB_TITLE() {
+ return "§7Stai giocando su §e";
+ }
+
+ @Override
+ public String Lobby_PLAYERS_HIDE() {
+ return "§7Adesso gli altri sono §cinvisibili §7per te";
+ }
+
+ @Override
+ public String Lobby_PLAYERS_SHOW() {
+ return "§7Adesso gli altri sono §avisibili §7per te";
+ }
+
+ @Override
+ public String Lobby_AUTONICK_ON() {
+ return "§7Adesso ti viene dato un §esoprannome §7automatico";
+ }
+
+ @Override
+ public String Lobby_AUTONICK_OFF() {
+ return "§7Adesso §cnon §7ti viene dato un più §esoprannome §7automatico";
+ }
+
+ @Override
+ public String Lobby_FORCEFIELD_ON() {
+ return "§7Hai §aattivato §7il §eForcefield";
+ }
+
+ @Override
+ public String Lobby_FORCEFIELD_OFF() {
+ return "§7Hai §cdisattivato §7il §eForcefield";
+ }
+
+ @Override
+ public String Lobby_SILENT_LOBBY_ON() {
+ return "§7Sei §aentrato §7nella §eSilent-Lobby";
+ }
+
+ @Override
+ public String Lobby_SILENT_LOBBY_OFF() {
+ return "§7Sei §cuscita §7della §eSilent-Lobby";
+ }
+
+ @Override
+ public String Lobby_PLAYING_MUSIC_PREFIX() {
+ return "§6In riproduzione: ";
+ }
+
+ @Override
+ public String Lobby_FOUND_ITEM_PREFIX() {
+ return "§7Hai §etrovato §7qualcosa";
+ }
+
+ @Override
+ public String Lobby_SET_LOCATION() {
+ return "§aPosizione è stata fissata";
+ }
+
+ @Override
+ public String Lobby_SET_LOCATION_USAGE() {
+ return "§cUsi /setloc ";
+ }
+
+ @Override
+ public String Lobby_DROP_ITEM_USAGE() {
+ return "§cUsi /dropitem ";
+ }
+
+ @Override
+ public String Lobby_DROP_ITEM() {
+ return "§aHai messo un nuovo item qui.";
+ }
+
+ @Override
+ public String Lobby_SET_SIGN() {
+ return "§aNeues Status Schild erstellt";
+ }
+
+ @Override
+ public String Lobby_JOIN_TITLE_1() {
+ return "§6univento§7.§eeu";
+ }
+
+ @Override
+ public String Lobby_JOIN_TITLE_2() {
+ return "§cIo solo pulisco qui";
+ }
+
+ @Override
+ public String Lobby_PET_ADD() {
+ return "§7Adesso hai un §eanimale domestico";
+ }
+
+ @Override
+ public String Lobby_PET_REMOVE() {
+ return "§cNon §7hai più un §eanimale domestico";
+ }
+
+ @Override
+ public String Lobby_PARKOUR_ON() {
+ return "§7Sei §aentrato §7nel §emodo del parkour";
+ }
+
+ @Override
+ public String Lobby_PARKOUR_OFF() {
+ return "§7Sei §cuscito §7del §emodo del parkour";
+ }
+
+ @Override
+ public String LobbyItems_NAVIGATOR() {
+ return "§eNavigatore";
+ }
+
+ @Override
+ public String LobbyItems_PLAYER_HIDER_ON() {
+ return "§cNascondere i giocatori";
+ }
+
+ @Override
+ public String LobbyItems_PLAYER_HIDER_OFF() {
+ return "§aMostrare i giocatori";
+ }
+
+ @Override
+ public String LobbyItems_AUTO_NICK() {
+ return "§5AutoNick";
+ }
+
+ @Override
+ public String LobbyItems_SILENT_LOBBY() {
+ return "§cSilent-Lobby";
+ }
+
+ @Override
+ public String LobbyItems_FORCEFIELD() {
+ return "§aForcefield";
+ }
+
+ @Override
+ public String LobbyItems_FUN_CHEST() {
+ return "§cF§aU§eN§3Chest";
+ }
+
+ @Override
+ public String LobbyItems_PROFILE() {
+ return "§eIl tuo profilo";
+ }
+
+ @Override
+ public String LobbyItems_YOUTUBER() {
+ return "§5Altri funzioni";
+ }
+
+ @Override
+ public String LobbyItems_SUGGESTION() {
+ return "§6Suggestioni";
+ }
+
+ @Override
+ public String LobbyItems_SPAWN() {
+ return "§6Spawn";
+ }
+
+ @Override
+ public String LobbyItems_PREMIUMHUB() {
+ return "§6Lobby dei VIP";
+ }
+
+ @Override
+ public String LobbyItems_MAYA() {
+ return "§6Maya";
+ }
+
+ @Override
+ public String LobbyItems_WOOLGET() {
+ return "§6WoolGet";
+ }
+
+ @Override
+ public String LobbyItems_BUILDSERVER() {
+ return "§aServer per costruire";
+ }
+
+ @Override
+ public String LobbyItems_PLAYERS_ONLINE() {
+ return " §6giocatori sono online";
+ }
+
+ @Override
+ public String LobbyItems_GADGETS() {
+ return "§6Gadgets";
+ }
+
+ @Override
+ public String LobbyItems_MUSIC() {
+ return "§6Musica";
+ }
+
+ @Override
+ public String LobbyItems_PARTICLE() {
+ return "§6Particelle";
+ }
+
+ @Override
+ public String LobbyItems_PETS() {
+ return "§6Animali domestici";
+ }
+
+ @Override
+ public String LobbyItems_YOUR_PET() {
+ return "§6Il tuo animale domestico";
+ }
+
+ @Override
+ public String LobbyItems_PETS_NAME() {
+ return "§6Cambiare il nome";
+ }
+
+ @Override
+ public String LobbyItems_PETS_AGE() {
+ return "§6Cambiare l'età";
+ }
+
+ @Override
+ public String LobbyItems_PETS_RIDE() {
+ return "§6Cavalcarlo";
+ }
+
+ @Override
+ public String LobbyItems_PETS_REMOVE() {
+ return "§6Cancellarlo";
+ }
+
+ @Override
+ public String LobbyItems_PETS_PIG() {
+ return "§6Maiale";
+ }
+
+ @Override
+ public String LobbyItems_PETS_COW() {
+ return "§6Mucca";
+ }
+
+ @Override
+ public String LobbyItems_PETS_CHICKEN() {
+ return "§6Gallina";
+ }
+
+ @Override
+ public String LobbyItems_PETS_RABBIT() {
+ return "§6Coniglio";
+ }
+
+ @Override
+ public String LobbyItems_PETS_MUSHROM_COW() {
+ return "§6Muucelio";
+ }
+
+ @Override
+ public String LobbyItems_PLAYER_MENU() {
+ return ": menu";
+ }
+
+ @Override
+ public String LobbyItems_PLAYER_FRIEND() {
+ return "§6Inviare una richiesta di amicizia";
+ }
+
+ @Override
+ public String LobbyItems_PLAYER_PARTY() {
+ return "§6Inviare una richiesta per una party";
+ }
+
+ @Override
+ public String LobbyItems_PLAYER_PROFILE() {
+ return "§6Il suo profilo";
+ }
+
+ @Override
+ public String LobbyItems_PLAYER_STATS() {
+ return "§6Statistiche";
+ }
+
+ @Override
+ public String LobbyItems_STATS() {
+ return "§6Le tue statistiche";
+ }
+
+ @Override
+ public String LobbyItems_FRIENDS() {
+ return "§6Amici";
+ }
+
+ @Override
+ public String LobbyItems_SETTINGS() {
+ return "§eOpzioni";
+ }
+
+ @Override
+ public String LobbyItems_SETTINGS_FASTMENU() {
+ return "§6Animazioni dell'inventario";
+ }
+
+ @Override
+ public String LobbyItems_SETTINGS_SERVER_TELEPORT() {
+ return "§6Server-Teleport";
+ }
+
+ @Override
+ public String LobbyItems_SETTINGS_PARTY_REQUESTS() {
+ return "§6Richieste per una party";
+ }
+
+ @Override
+ public String LobbyItems_SETTINGS_FRIEND_REQUESTS() {
+ return "§6Richieste di amicizia";
+ }
+
+ @Override
+ public String LobbyItems_SETTINGS_CHATSOUNDS() {
+ return "§6Suoni del chat";
+ }
+
+ @Override
+ public String LobbyItems_SETTINGS_EFFECTS() {
+ return "§6Effetti";
+ }
+
+ @Override
+ public String LobbyItems_SETTINGS_LANGUAGES() {
+ return "§6Lingue";
+ }
+
+ @Override
+ public String LobbyItems_SETTINGS_ON() {
+ return "§aattivo";
+ }
+
+ @Override
+ public String LobbyItems_SETTINGS_OFF() {
+ return "§cdisattivo";
+ }
+
+ @Override
+ public String LobbyItems_BACK() {
+ return "§cIndietro";
+ }
+
+ @Override
+ public String LobbyBoard_FOUND_SECRETS() {
+ return "§eSegreti§7:";
+ }
+
+ @Override
+ public String LobbyBoard_COINS() {
+ return "§eVenties§7:";
+ }
+
+ @Override
+ public String LobbyBoard_TS() {
+ return "§eTeamSpeak§7:";
+ }
+
+ @Override
+ public String LobbyBoard_FORUM() {
+ return "§eForum§7:";
+ }
+
+ @Override
+ public String LobbyBoard_NEW() {
+ return "§e§lNovità:";
+ }
+
+ @Override
+ public String LobbyBoard_NEWS() {
+ return "Scheibenwischer";
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/eu/univento/core/api/languages/Languages.java b/src/main/java/eu/univento/core/api/languages/Languages.java
new file mode 100644
index 0000000..a74dd53
--- /dev/null
+++ b/src/main/java/eu/univento/core/api/languages/Languages.java
@@ -0,0 +1,125 @@
+package eu.univento.core.api.languages;
+
+import eu.univento.core.api.player.CustomPlayer;
+import eu.univento.core.api.player.Perms;
+
+/**
+ * @author joethei
+ * @version 0.3
+ */
+public interface Languages{
+
+ String UNKNOWN_ERROR();
+ String NO_PERMS();
+ String ERROR();
+ String NOT_ONLINE(String name);
+ String KICK_RESTART();
+ String KICK_FULL();
+ String COMMAND_NOT_FOUND();
+
+ String Core_FIX_OWN();
+ String Core_FIX_OTHER(CustomPlayer p);
+ String Core_FIX_BY_OTHER(CustomPlayer p);
+ String Core_NICK_ON();
+ String Core_NICK_OFF();
+ String Core_BUILD_ON();
+ String Core_BUILD_OFF();
+ String Core_BAN_NO_REASON();
+ String Core_BAN_USAGE();
+ String Core_BAN_BANNED(CustomPlayer p);
+ String Core_GM_USAGE();
+ String Core_GM_CHANGED();
+ String Core_GLOBALMUTE_ON();
+ String Core_GLOBALMUTE_OFF();
+ String Core_RUNAS_USAGE();
+ String Core_RUNAS_RUN(CustomPlayer p);
+ String Core_SETRANK_USAGE();
+ String Core_SETRANK_KICK();
+ String Core_SETRANK_NO_RANK();
+ String Core_SETRANK_SET(CustomPlayer p, Perms.Ranks rank);
+ String Core_TS_ALLREADY_VERIFIED();
+ String Core_TS_VERIFIED();
+ String Core_VANISH_ON();
+ String Core_VANISH_OFF();
+ String Core_SERVER_MUTED();
+ String Core_CHAT_CLEARED(CustomPlayer p);
+ String Core_TAB_TITLE();
+
+ String Lobby_PLAYERS_HIDE();
+ String Lobby_PLAYERS_SHOW();
+ String Lobby_AUTONICK_ON();
+ String Lobby_AUTONICK_OFF();
+ String Lobby_FORCEFIELD_ON();
+ String Lobby_FORCEFIELD_OFF();
+ String Lobby_SILENT_LOBBY_ON();
+ String Lobby_SILENT_LOBBY_OFF();
+ String Lobby_PLAYING_MUSIC_PREFIX();
+ String Lobby_FOUND_ITEM_PREFIX();
+ String Lobby_SET_LOCATION();
+ String Lobby_SET_LOCATION_USAGE();
+ String Lobby_DROP_ITEM_USAGE();
+ String Lobby_DROP_ITEM();
+ String Lobby_SET_SIGN();
+ String Lobby_JOIN_TITLE_1();
+ String Lobby_JOIN_TITLE_2();
+ String Lobby_PET_ADD();
+ String Lobby_PET_REMOVE();
+ String Lobby_PARKOUR_ON();
+ String Lobby_PARKOUR_OFF();
+
+ String LobbyItems_NAVIGATOR();
+ String LobbyItems_PLAYER_HIDER_ON();
+ String LobbyItems_PLAYER_HIDER_OFF();
+ String LobbyItems_AUTO_NICK();
+ String LobbyItems_SILENT_LOBBY();
+ String LobbyItems_FORCEFIELD();
+ String LobbyItems_FUN_CHEST();
+ String LobbyItems_PROFILE();
+ String LobbyItems_YOUTUBER();
+ String LobbyItems_SUGGESTION();
+ String LobbyItems_SPAWN();
+ String LobbyItems_PREMIUMHUB();
+ String LobbyItems_MAYA();
+ String LobbyItems_WOOLGET();
+ String LobbyItems_BUILDSERVER();
+ String LobbyItems_PLAYERS_ONLINE();
+ String LobbyItems_GADGETS();
+ String LobbyItems_MUSIC();
+ String LobbyItems_PARTICLE();
+ String LobbyItems_PETS();
+ String LobbyItems_YOUR_PET();
+ String LobbyItems_PETS_NAME();
+ String LobbyItems_PETS_AGE();
+ String LobbyItems_PETS_RIDE();
+ String LobbyItems_PETS_REMOVE();
+ String LobbyItems_PETS_PIG();
+ String LobbyItems_PETS_COW();
+ String LobbyItems_PETS_CHICKEN();
+ String LobbyItems_PETS_RABBIT();
+ String LobbyItems_PETS_MUSHROM_COW();
+ String LobbyItems_PLAYER_MENU();
+ String LobbyItems_PLAYER_FRIEND();
+ String LobbyItems_PLAYER_PARTY();
+ String LobbyItems_PLAYER_PROFILE();
+ String LobbyItems_PLAYER_STATS();
+ String LobbyItems_STATS();
+ String LobbyItems_FRIENDS();
+ String LobbyItems_SETTINGS();
+ String LobbyItems_SETTINGS_FASTMENU();
+ String LobbyItems_SETTINGS_SERVER_TELEPORT();
+ String LobbyItems_SETTINGS_PARTY_REQUESTS();
+ String LobbyItems_SETTINGS_FRIEND_REQUESTS();
+ String LobbyItems_SETTINGS_CHATSOUNDS();
+ String LobbyItems_SETTINGS_EFFECTS();
+ String LobbyItems_SETTINGS_LANGUAGES();
+ String LobbyItems_SETTINGS_ON();
+ String LobbyItems_SETTINGS_OFF();
+ String LobbyItems_BACK();
+
+ String LobbyBoard_FOUND_SECRETS();
+ String LobbyBoard_COINS();
+ String LobbyBoard_NEW();
+ String LobbyBoard_NEWS();
+ String LobbyBoard_TS();
+ String LobbyBoard_FORUM();
+}
\ No newline at end of file
diff --git a/src/main/java/eu/univento/core/api/languages/Messages.java b/src/main/java/eu/univento/core/api/languages/Messages.java
new file mode 100644
index 0000000..f7bea72
--- /dev/null
+++ b/src/main/java/eu/univento/core/api/languages/Messages.java
@@ -0,0 +1,314 @@
+package eu.univento.core.api.languages;
+
+import eu.univento.core.api.player.CustomPlayer;
+import eu.univento.core.api.player.Perms;
+
+
+/**
+ * @author joethei
+ * @version 2.0
+ */
+public class Messages {
+
+ CustomPlayer player;
+
+ Language_DE de = new Language_DE();
+ Language_EN en = new Language_EN();
+ Language_IT it = new Language_IT();
+
+ Languages lang;
+
+ public Messages(CustomPlayer player) {
+ this.player = player;
+ if(player.getLanguage().equals("DE")) this.lang = de;
+ if(player.getLanguage().equals("IT")) this.lang = it;
+ if(player.getLanguage().equals("EN")) this.lang = en;
+ }
+
+ public String PREFIX() {
+ return " §6univento §8» ";
+ }
+ public String TAB_PREFIX() { return "§8• §6U N I V E N T O §8• ";}
+
+ public String UNKNOWN_ERROR() {
+ return lang.UNKNOWN_ERROR();
+ }
+ public String NO_PERMS() {
+ return lang.NO_PERMS();
+ }
+ public String ERROR() {
+ return lang.ERROR();
+ }
+ public String NOT_ONLINE(String name) {
+ return lang.NOT_ONLINE(name);
+ }
+ public String KICK_RESTART() {
+ return lang.KICK_RESTART();
+ }
+ public String KICK_FULL() {
+ return lang.KICK_FULL();
+ }
+ public String COMMAND_NOT_FOUND() {
+ return lang.COMMAND_NOT_FOUND();
+ }
+
+ public String Core_FIX_OWN() {
+ return lang.Core_FIX_OWN();
+ }
+ public String Core_FIX_OTHER(CustomPlayer p) {
+ return lang.Core_FIX_OTHER(p);
+ }
+ public String Core_FIX_BY_OTHER(CustomPlayer p) {
+ return lang.Core_FIX_BY_OTHER(p);
+ }
+ public String Core_NICK_ON() {
+ return lang.Core_NICK_ON();
+ }
+ public String Core_NICK_OFF() {
+ return lang.Core_NICK_OFF();
+ }
+ public String Core_BUILD_ON() {
+ return lang.Core_BUILD_ON();
+ }
+ public String Core_BUILD_OFF() {
+ return lang.Core_BUILD_OFF();
+ }
+ public String Core_BAN_NO_REASON() {
+ return lang.Core_BAN_NO_REASON();
+ }
+ public String Core_BAN_USAGE() {
+ return lang.Core_BAN_USAGE();
+ }
+ public String Core_BAN_BANNED(CustomPlayer p) {
+ return lang.Core_BAN_BANNED(p);
+ }
+ public String Core_GM_USAGE() {
+ return lang.Core_GM_USAGE();
+ }
+ public String Core_GM_CHANGED() {
+ return lang.Core_GM_CHANGED();
+ }
+ public String Core_GLOBALMUTE_ON() {
+ return lang.Core_GLOBALMUTE_ON();
+ }
+ public String Core_GLOBALMUTE_OFF() {
+ return lang.Core_GLOBALMUTE_OFF();
+ }
+ public String Core_RUNAS_USAGE() {
+ return lang.Core_RUNAS_USAGE();
+ }
+ public String Core_RUNAS_RUN(CustomPlayer p) {
+ return lang.Core_RUNAS_RUN(p);
+ }
+ public String Core_SETRANK_USAGE() {
+ return lang.Core_SETRANK_USAGE();
+ }
+ public String Core_SETRANK_KICK() {
+ return lang.Core_SETRANK_KICK();
+ }
+ public String Core_SETRANK_NO_RANK() {
+ return lang.Core_SETRANK_NO_RANK();
+ }
+ public String Core_SETRANK_SET(CustomPlayer p, Perms.Ranks rank) {
+ return lang.Core_SETRANK_SET(p, rank);
+ }
+ public String Core_TS_ALLREADY_VERIFIED() {
+ return lang.Core_TS_ALLREADY_VERIFIED();
+ }
+ public String Core_TS_VERIFIED() {
+ return lang.Core_TS_VERIFIED();
+ }
+ public String Core_VANISH_ON() {
+ return lang.Core_VANISH_ON();
+ }
+ public String Core_VANISH_OFF() {
+ return lang.Core_VANISH_OFF();
+ }
+ public String Core_SERVER_MUTED() {
+ return lang.Core_SERVER_MUTED();
+ }
+ public String Core_CHAT_CLEARED(CustomPlayer p) { return lang.Core_CHAT_CLEARED(p);}
+ public String Core_TAB_TITLE() { return lang.Core_TAB_TITLE(); }
+
+ public String Lobby_PLAYERS_HIDE() {
+ return lang.Lobby_PLAYERS_HIDE();
+ }
+ public String Lobby_PLAYERS_SHOW() {
+ return lang.Lobby_PLAYERS_SHOW();
+ }
+ public String Lobby_AUTONICK_ON() {
+ return lang.Lobby_AUTONICK_ON();
+ }
+ public String Lobby_AUTONICK_OFF() {
+ return lang.Lobby_AUTONICK_OFF();
+ }
+ public String Lobby_FORCEFIELD_ON() {
+ return lang.Lobby_FORCEFIELD_ON();
+ }
+ public String Lobby_FORCEFIELD_OFF() {
+ return lang.Lobby_FORCEFIELD_OFF();
+ }
+ public String Lobby_SILENT_LOBBY_ON() {
+ return lang.Lobby_SILENT_LOBBY_ON();
+ }
+ public String Lobby_SILENT_LOBBY_OFF() {
+ return lang.Lobby_SILENT_LOBBY_OFF();
+ }
+ public String Lobby_PLAYING_MUSIC_PREFIX() {
+ return lang.Lobby_PLAYING_MUSIC_PREFIX();
+ }
+ public String Lobby_FOUND_ITEM_PREFIX() {
+ return lang.Lobby_FOUND_ITEM_PREFIX();
+ }
+ public String Lobby_SET_LOCATION() {
+ return lang.Lobby_SET_LOCATION();
+ }
+ public String Lobby_SET_LOCATION_USAGE() {
+ return lang.Lobby_SET_LOCATION_USAGE();
+ }
+ public String Lobby_DROP_ITEM_USAGE() {
+ return lang.Lobby_DROP_ITEM_USAGE();
+ }
+ public String Lobby_DROP_ITEM() {
+ return lang.Lobby_DROP_ITEM();
+ }
+ public String Lobby_SET_SIGN() {
+ return lang.Lobby_SET_SIGN();
+ }
+ public String Lobby_JOIN_TITLE_1() {
+ return lang.Lobby_JOIN_TITLE_1();
+ }
+ public String Lobby_JOIN_TITLE_2() {
+ return lang.Lobby_JOIN_TITLE_2();
+ }
+ public String Lobby_PET_ADD() {
+ return lang.Lobby_PET_ADD();
+ }
+ public String Lobby_PET_REMOVE() {
+ return lang.Lobby_PET_REMOVE();
+ }
+ public String Lobby_PARKOUR_ON() {
+ return lang.Lobby_PARKOUR_ON();
+ }
+ public String Lobby_PARKOUR_OFF() {
+ return lang.Lobby_PARKOUR_OFF();
+ }
+
+ public String LobbyItems_NAVIGATOR() {
+ return lang.LobbyItems_NAVIGATOR();
+ }
+ public String LobbyItems_PLAYER_HIDER_ON() {
+ return lang.LobbyItems_PLAYER_HIDER_ON();
+ }
+ public String LobbyItems_PLAYER_HIDER_OFF() {
+ return lang.LobbyItems_PLAYER_HIDER_OFF();
+ }
+ public String LobbyItems_AUTO_NICK() {
+ return lang.LobbyItems_AUTO_NICK();
+ }
+ public String LobbyItems_SILENT_LOBBY() {
+ return lang.LobbyItems_SILENT_LOBBY();
+ }
+ public String LobbyItems_FORCEFIELD() {
+ return lang.LobbyItems_FORCEFIELD();
+ }
+ public String LobbyItems_FUN_CHEST() {
+ return lang.LobbyItems_FUN_CHEST();
+ }
+ public String LobbyItems_PROFILE() {
+ return lang.LobbyItems_PROFILE();
+ }
+ public String LobbyItems_YOUTUBER() { return lang.LobbyItems_YOUTUBER(); }
+ public String LobbyItems_SUGGESTION() { return lang.LobbyItems_SUGGESTION(); }
+ public String LobbyItems_SPAWN() {
+ return lang.LobbyItems_SPAWN();
+ }
+ public String LobbyItems_PREMIUMHUB() {
+ return lang.LobbyItems_PREMIUMHUB();
+ }
+ public String LobbyItems_MAYA() {
+ return lang.LobbyItems_MAYA();
+ }
+ public String LobbyItems_WOOLGET() { return lang.LobbyItems_WOOLGET(); }
+ public String LobbyItems_BUILDSERVER() {
+ return lang.LobbyItems_BUILDSERVER();
+ }
+ public String LobbyItems_PLAYERS_ONLINE() {
+ return lang.LobbyItems_PLAYERS_ONLINE();
+ }
+ public String LobbyItems_GADGETS() {
+ return lang.LobbyItems_GADGETS();
+ }
+ public String LobbyItems_MUSIC() {
+ return lang.LobbyItems_MUSIC();
+ }
+ public String LobbyItems_PARTICLE() {
+ return lang.LobbyItems_PARTICLE();
+ }
+ public String LobbyItems_PETS() {
+ return lang.LobbyItems_PETS();
+ }
+ public String LobbyItems_YOUR_PET() { return lang.LobbyItems_YOUR_PET(); }
+ public String LobbyItems_PETS_NAME() { return lang.LobbyItems_PETS_NAME(); }
+ public String LobbyItems_PETS_AGE() { return lang.LobbyItems_PETS_AGE(); }
+ public String LobbyItems_PETS_RIDE() { return lang.LobbyItems_PETS_RIDE(); }
+ public String LobbyItems_PETS_REMOVE() { return lang.LobbyItems_PETS_REMOVE(); }
+ public String LobbyItems_PETS_PIG() { return lang.LobbyItems_PETS_PIG(); }
+ public String LobbyItems_PETS_COW() { return lang.LobbyItems_PETS_COW(); }
+ public String LobbyItems_PETS_CHICKEN() { return lang.LobbyItems_PETS_CHICKEN(); }
+ public String LobbyItems_PETS_RABBIT() { return lang.LobbyItems_PETS_RABBIT(); }
+ public String LobbyItems_PETS_MUSHROM_COW () { return lang.LobbyItems_PETS_MUSHROM_COW(); }
+ public String LobbyItems_PLAYER_MENU() { return lang.LobbyItems_PLAYER_MENU(); }
+ public String LobbyItems_PLAYER_FRIEND() { return lang.LobbyItems_PLAYER_FRIEND(); }
+ public String LobbyItems_PLAYER_PARTY() { return lang.LobbyItems_PLAYER_PARTY(); }
+ public String LobbyItems_PLAYER_PROFILE() { return lang.LobbyItems_PLAYER_PROFILE(); }
+ public String LobbyItems_PLAYER_STATS() { return lang.LobbyItems_PLAYER_STATS();}
+ public String LobbyItems_STATS() {
+ return lang.LobbyItems_STATS();
+ }
+ public String LobbyItems_FRIENDS() {
+ return lang.LobbyItems_FRIENDS();
+ }
+ public String LobbyItems_SETTINGS() {
+ return lang.LobbyItems_SETTINGS();
+ }
+ public String LobbyItems_SETTINGS_FASTMENU() { return lang.LobbyItems_SETTINGS_FASTMENU();}
+ public String LobbyItems_SETTINGS_SERVER_TELEPORT() { return lang.LobbyItems_SETTINGS_SERVER_TELEPORT(); }
+ public String LobbyItems_SETTINGS_PARTY_REQUESTS() {
+ return lang.LobbyItems_SETTINGS_PARTY_REQUESTS();
+ }
+ public String LobbyItems_SETTINGS_FRIEND_REQUESTS() {
+ return lang.LobbyItems_SETTINGS_FRIEND_REQUESTS();
+ }
+ public String LobbyItems_SETTINGS_CHATSOUNDS() {
+ return lang.LobbyItems_SETTINGS_CHATSOUNDS();
+ }
+ public String LobbyItems_SETTINGS_EFFECTS() {
+ return lang.LobbyItems_SETTINGS_EFFECTS();
+ }
+ public String LobbyItems_SETTINGS_LANGUAGES() {
+ return lang.LobbyItems_SETTINGS_LANGUAGES();
+ }
+ public String LobbyItems_SETTINGS_ON() {
+ return lang.LobbyItems_SETTINGS_ON();
+ }
+ public String LobbyItems_SETTINGS_OFF() {
+ return lang.LobbyItems_SETTINGS_OFF();
+ }
+ public String LobbyItems_BACK() { return lang.LobbyItems_BACK(); }
+
+ public String LobbyBoard_COINS() { return lang.LobbyBoard_COINS(); }
+ public String LobbyBoard_NEW() { return lang.LobbyBoard_NEW(); }
+ public String LobbyBoard_NEWS() { return lang.LobbyBoard_NEWS(); }
+ public String LobbyBoard_TS() { return lang.LobbyBoard_TS(); }
+ public String LobbyBoard_FORUM() { return lang.LobbyBoard_FORUM(); }
+ public String LobbyBoard_FOUND_SECRETS() { return lang.LobbyBoard_FOUND_SECRETS(); }
+
+ public class Build {
+ public String PREFIX = "• §bTeam§3Vento • ";
+ }
+
+ public static class Console{
+ public static String NOT_A_PLAYER = "You are not a valid player";
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/eu/univento/core/api/player/BanSystem.java b/src/main/java/eu/univento/core/api/player/BanSystem.java
new file mode 100644
index 0000000..cc191db
--- /dev/null
+++ b/src/main/java/eu/univento/core/api/player/BanSystem.java
@@ -0,0 +1,148 @@
+package eu.univento.core.api.player;
+
+import eu.univento.core.Core;
+import eu.univento.core.api.database.MySQL;
+import eu.univento.core.api.utils.NameFetcher;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.UUID;
+
+/**
+ * bans and unbans players
+ * @author joethei
+ * @version 1.2
+ */
+public class BanSystem{
+
+ /**
+ * sets player banned
+ * @param p player
+ * @param reason reason
+ * @param who who banned
+ * @param time duration
+ * @throws SQLException SQL server not available or throwing error
+ * @throws ClassNotFoundException class couldn't be found
+ */
+static void setBanned(CustomPlayer p, String reason, CustomPlayer who, int time)throws SQLException, ClassNotFoundException {
+ int id = p.getID();
+ MySQL sql = Core.returnSQL();
+ sql.openConnection();
+
+ Date date = new Date();
+ date.setTime(date.getTime() + (time * 24));
+ Timestamp timestamp = new Timestamp(date.getTime());
+
+ PreparedStatement st = sql.getConnection().prepareStatement("INSERT INTO bans (BID, Reason, until, BannerID) VALUES ('" + id + "', '" + reason + "', '" + who.getID() + "', '" + timestamp + "');");
+ st.execute();
+ p.kickPlayer("§cYou have been banned. §6Reason: " + reason + "\nUntil: " + timestamp);
+ who.sendMessage("§cDu hast den Spieler " + p.getColor() + p.getName() + "§c für " + time + " Tage gebannt wegen " + reason);
+ sql.closeConnection();
+ }
+
+/**
+ * unbans a player
+ * @param p player
+ * @throws SQLException SQL server not available or throwing error
+ * @throws ClassNotFoundException class couldn't be found
+ */
+static void removeAllBans(CustomPlayer p) throws SQLException, ClassNotFoundException{
+ int id = p.getID();
+ MySQL sql = Core.returnSQL();
+ sql.openConnection();
+ PreparedStatement st = sql.getConnection().prepareStatement("DELETE FROM bans WHERE ID ='" + id + "';");
+ st.execute();
+ sql.closeConnection();
+ }
+
+/**
+ * checks if player is banned
+ * @param p player
+ * @return true /false
+ * @throws SQLException SQL server not available or throwing error
+ * @throws ClassNotFoundException class couldn't be found
+ */
+static boolean isBanned(CustomPlayer p) throws SQLException, ClassNotFoundException {
+ int id = p.getID();
+ MySQL sql = Core.returnSQL();
+ PreparedStatement st = sql.getConnection().prepareStatement("SELECT * FROM bans WHERE BID='" + id + "';");
+ ResultSet rs = st.executeQuery();
+ if(rs.next()) {
+ Date date = new Date();
+ Timestamp time = new Timestamp(date.getTime());
+ sql.closeConnection();
+ return time.before(getBanTime(p));
+ }else {
+ sql.closeConnection();
+ return false;
+ }
+
+ }
+
+ static Timestamp getBanTime(CustomPlayer p) throws SQLException {
+ int id = p.getID();
+ MySQL sql = Core.returnSQL();
+ PreparedStatement st = sql.getConnection().prepareStatement("SELECT * FROM bans WHERE ID='" + id + "';");
+ ResultSet rs = st.executeQuery();
+ if(rs.next()) {
+ Timestamp time = rs.getTimestamp("until");
+ sql.closeConnection();
+ return time;
+ }
+ sql.closeConnection();
+ return null;
+ }
+
+/**
+ * return reason for ban
+ * @param p player
+ * @return String
+ * @throws SQLException SQL server not available or throwing error
+ * @throws ClassNotFoundException class couldn't be found
+ */
+static String getBanReason(CustomPlayer p)throws SQLException, ClassNotFoundException {
+ int id = p.getID();
+ MySQL sql = Core.returnSQL();
+ sql.openConnection();
+ PreparedStatement st = sql.getConnection().prepareStatement("SELECT * FROM bans WHERE ID='" + id + "';");
+ ResultSet rs = st.executeQuery();
+ if(rs.next()) {
+ String reason = rs.getString("Reason");
+ sql.closeConnection();
+ return reason;
+ }else {
+ sql.closeConnection();
+ return null;
+ }
+ }
+
+/**
+ * gets the name of the player who banned the player
+ * @param p player
+ * @return String
+ * @throws SQLException SQL server not available or throwing error
+ * @throws ClassNotFoundException class couldn't be found
+ */
+static String getWhoBanned(CustomPlayer p)throws SQLException, ClassNotFoundException {
+ int id = p.getID();
+ MySQL sql = Core.returnSQL();
+ sql.openConnection();
+ ResultSet rs = Core.returnSQL().getConnection().createStatement().executeQuery("SELECT * FROM bans WHERE ID='" + id + "';");
+ if (!rs.next()) {
+ sql.closeConnection();
+ return null;
+ }
+ String whouuid = rs.getString("who");
+ UUID who = UUID.fromString(whouuid);
+ List list = new ArrayList<>();
+ list.add(who);
+ NameFetcher name = new NameFetcher(list);
+ sql.closeConnection();
+ return name.toString();
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/eu/univento/core/api/player/Coins.java b/src/main/java/eu/univento/core/api/player/Coins.java
new file mode 100644
index 0000000..6d3c763
--- /dev/null
+++ b/src/main/java/eu/univento/core/api/player/Coins.java
@@ -0,0 +1,60 @@
+package eu.univento.core.api.player;
+
+import eu.univento.core.Core;
+import eu.univento.core.api.database.MySQL;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+/**
+ * coins management
+ * @author joethei
+ * @version 1.0
+ */
+public class Coins{
+
+ /**
+ * gets coins from player
+ * @param p CustomPlayer
+ * @return coins as integer
+ */
+ static int getCoins(CustomPlayer p) {
+ int id = p.getID();
+ MySQL sql = Core.returnSQL();
+ try {
+ sql.openConnection();
+ PreparedStatement st = sql.getConnection().prepareStatement("SELECT Coins FROM users WHERE ID='" + id + "';");
+ ResultSet rs = st.executeQuery();
+ if(rs.next()) {
+ int coins = rs.getInt("Coins");
+ sql.closeConnection();
+ return coins;
+ }
+ return 0;
+ } catch (ClassNotFoundException | SQLException e) {
+ e.printStackTrace();
+ return 0;
+ }
+ }
+
+ /**
+ * sets coins of player
+ * @param p CustomPlayer
+ * @param coins coins to set
+ */
+ static void setCoins(CustomPlayer p, int coins) {
+ int id = p.getID();
+ MySQL sql = Core.returnSQL();
+ try {
+ sql.openConnection();
+ PreparedStatement st = sql.getConnection().prepareStatement("UPDATE users SET Coins='" + coins + "' WHERE ID='" + id + "';");
+ st.execute();
+ sql.closeConnection();
+ } catch (ClassNotFoundException | SQLException e) {
+ e.printStackTrace();
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/eu/univento/core/api/player/CustomPlayer.java b/src/main/java/eu/univento/core/api/player/CustomPlayer.java
new file mode 100644
index 0000000..9748199
--- /dev/null
+++ b/src/main/java/eu/univento/core/api/player/CustomPlayer.java
@@ -0,0 +1,832 @@
+package eu.univento.core.api.player;
+
+import eu.univento.core.Core;
+import eu.univento.core.api.Actionbar;
+import eu.univento.core.api.Utils;
+import eu.univento.core.api.database.MySQL;
+import eu.univento.core.api.effects.Effects;
+import eu.univento.core.api.languages.Messages;
+import eu.univento.core.api.server.Game;
+import eu.univento.core.api.server.ServerSettings;
+import eu.univento.core.api.server.Servers;
+import eu.univento.core.api.utils.NameFetcher;
+import net.minecraft.server.v1_9_R1.EnumParticle;
+import org.bukkit.Bukkit;
+import org.bukkit.Color;
+import org.bukkit.Location;
+import org.bukkit.Sound;
+import org.bukkit.attribute.Attribute;
+import org.bukkit.attribute.AttributeModifier;
+import org.bukkit.craftbukkit.v1_9_R1.CraftServer;
+import org.bukkit.craftbukkit.v1_9_R1.entity.CraftPlayer;
+import org.bukkit.entity.Player;
+import org.bukkit.scoreboard.Team;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Timestamp;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+/**
+ * custom player implementation
+ * @author joethei
+ * @version 1.0
+ */
+public class CustomPlayer extends CraftPlayer {
+
+ /**
+ * all normal players
+ */
+ private static final HashMap PLAYERS = new HashMap<>();
+
+ /**
+ * normal player
+ */
+ private final Player PLAYER;
+
+ /**
+ * custom prefix for chat
+ */
+ private String customPrefix;
+ /**
+ * custom suffix for chat
+ */
+ private String customSuffix;
+ /**
+ * custom color for chat
+ */
+ private String customColor;
+
+ /**
+ * player id from database
+ */
+ private int id = 0;
+
+ /**
+ * if player has open inventory
+ */
+ private boolean openInventory;
+
+ //private MongoDB mongoDB = Core.getMongoDB();
+ //private MongoCollection userCollection = mongoDB.getDatabase().getCollection("users");
+
+ /**
+ * inits player
+ *
+ * @param player Player
+ */
+ private CustomPlayer(Player player) {
+ super((CraftServer) Bukkit.getServer(), ((CraftPlayer) player).getHandle());
+ PLAYERS.put(player.getName().toLowerCase(), this);
+ PLAYER = player;
+ id = getID();
+ }
+
+ /**
+ * called on player leaving
+ */
+ public void onLeave() {
+ /**
+ Date date = new Date();
+ Document doc = new Document("uuid", getUniqueId());
+ userCollection.updateOne(doc, new Document("$set", new Document("lastOnline", date)));
+
+ HashMap location = new HashMap<>();
+ location.put("X", getLocation().getX());
+ location.put("Y", getLocation().getY());
+ location.put("Z", getLocation().getZ());
+ location.put("Yaw", getLocation().getYaw());
+ location.put("Pitch", getLocation().getPitch());
+
+ userCollection.updateOne(doc, new Document("$set", new Document("Pos", new Document("Loc", location))));
+
+ */
+ if (PLAYERS.containsKey(getName().toLowerCase())) PLAYERS.remove(getName().toLowerCase());
+ }
+
+ /**
+ * init player
+ *
+ * @param player Player
+ * @return CustomPlayer
+ */
+ public static CustomPlayer getPlayer(String player) {
+ if (PLAYERS.containsKey(player.toLowerCase())) {
+ return PLAYERS.get(player.toLowerCase());
+ } else {
+ Player p = Bukkit.getPlayer(player);
+ return p == null ? null : new CustomPlayer(p);
+ }
+ }
+
+ /**
+ * gets custom player from player
+ *
+ * @param player Player
+ * @return CustomPlayer
+ */
+ public static CustomPlayer getPlayer(Player player) {
+ return getPlayer(player.getName());
+ }
+
+ /**
+ * gets custom player from database id
+ *
+ * @param id database id of player
+ * @return CustomPlayer
+ */
+ public static CustomPlayer getPlayer(int id) {
+ MySQL sql = Core.returnSQL();
+ try {
+ sql.openConnection();
+ PreparedStatement st = sql.getConnection().prepareStatement("SELECT ID, UUID FROM users WHERE ID='" + id + "');");
+ ResultSet rs = st.executeQuery();
+ String uuidString = rs.getString("UUID");
+ sql.closeConnection();
+ UUID uuid = UUID.fromString(uuidString);
+ NameFetcher names = new NameFetcher(Arrays.asList(uuid));
+ Map map = null;
+ try {
+ map = names.call();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ String name = map.toString();
+ String Name = name.substring(name.indexOf('=') + 1, name.indexOf('}'));
+
+ return CustomPlayer.getPlayer(Name);
+
+ } catch (ClassNotFoundException | SQLException e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ /**
+ * gets database id of player
+ *
+ * @return Integer
+ */
+ public int getID() {
+ if (id == 0) {
+ MySQL sql = Core.returnSQL();
+ try {
+ sql.openConnection();
+ String uuid = this.getUniqueId().toString();
+ PreparedStatement st = sql.getConnection().prepareStatement("SELECT * FROM users WHERE UUID ='" + uuid + "';");
+ ResultSet rs = st.executeQuery();
+ if (rs.next()) {
+ int id = rs.getInt("ID");
+ this.id = id;
+ sql.closeConnection();
+ return id;
+ } else {
+ sql.closeConnection();
+
+ return 0;
+ }
+ } catch (ClassNotFoundException | SQLException e) {
+ e.printStackTrace();
+ return 0;
+ }
+ } else {
+ return id;
+ }
+ }
+
+ /**
+ * get normal player
+ *
+ * @return Player
+ */
+ public Player getPLAYER() {
+ return PLAYER;
+ }
+
+ /**
+ public void insertToDatabase() {
+ DBObject obj = new BasicDBObject("uuid", getUniqueId());
+ Date date = new Date();
+
+ obj.put("rank", "Player");
+ obj.put("firstLogin", date);
+ obj.put("lastLogin", date);
+ obj.put("lastOnline", date);
+ obj.put("lastIP", spigot().getRawAddress().getHostName());
+ obj.put("tsid", 0);
+ obj.put("timesJoined", 1);
+ obj.put("timePlayed", 0);
+ obj.put("coins", 0);
+ obj.put("experience", 0);
+ obj.put("secrets", 0);
+ obj.put("foundSecrets", new ArrayList());
+ obj.put("foundEggs", new ArrayList());
+
+ HashMap settings = new HashMap<>();
+ settings.put("playerVisibility", "all");
+ settings.put("inventoryAnimation", true);
+ settings.put("teleportAnimation", true);
+ settings.put("partyRequests", true);
+ settings.put("friendRequests", true);
+ settings.put("friendJump", true);
+ settings.put("chatSounds", true);
+ settings.put("effects", true);
+ settings.put("storyMode", true);
+ settings.put("language", "EN");
+
+ obj.put("Settings", settings);
+
+ HashMap location = new HashMap<>();
+ location.put("X", getLocation().getX());
+ location.put("Y", getLocation().getY());
+ location.put("Z", getLocation().getZ());
+ location.put("Yaw", getLocation().getYaw());
+ location.put("Pitch", getLocation().getPitch());
+
+ obj.put("Pos", location);
+ userCollection.insertOne(obj);
+ }
+
+ public void updateDatabaseEntry() {
+ Date date = new Date();
+ Document doc = new Document("uuid", getUniqueId());
+ userCollection.updateOne(doc, new Document("$set", new Document("lastLogin", date)));
+ userCollection.updateOne(doc, new Document("$set", new Document("lastIP", spigot().getRawAddress().getHostName().toString())));
+ userCollection.updateOne(doc, new Document("$set", new Document("timesPlayed", getTimesJoined() + 1)));
+ }
+
+
+ public void setRank(Perms.Ranks rank) {
+ userCollection.updateOne(new Document("uuid", getUniqueId()), new Document("$set", new Document("rank", rank.toString())));
+ }
+
+ public void setTSID(int id) {
+ userCollection.updateOne(new Document("uuid", getUniqueId()), new Document("$set", new Document("tsid", id)));
+ }
+
+ public void setCoins(int coins) {
+ userCollection.updateOne(new Document("uuid", getUniqueId()), new Document("$set", new Document("coins", coins)));
+ }
+
+ public void setExperience(int experience) {
+ userCollection.updateOne(new Document("uuid", getUniqueId()), new Document("$set", new Document("experience", experience)));
+ }
+
+ public void setSecrets(int secrets) {
+ userCollection.updateOne(new Document("uuid", getUniqueId()), new Document("$set", new Document("secrets", secrets)));
+ }
+
+
+ private Object getObjectFromDatbase(String name) {
+ FindIterable cursor = userCollection.find(new Document("uuid", getUniqueId()));
+ cursor.cursorType(CursorType.NonTailable);
+
+ Document doc = cursor.first();
+ if (doc == null) {
+ return null;
+ }
+ return doc.get(name);
+ }
+
+ private int getIntegerFromDatabase(String name) {
+ FindIterable cursor = userCollection.find(new Document("uuid", getUniqueId()));
+ cursor.cursorType(CursorType.NonTailable);
+
+ Document doc = cursor.first();
+ if (doc == null) {
+ return 0;
+ }
+ return doc.getInteger(name);
+ }
+
+ private String getStringFromDatabase(String name) {
+ FindIterable cursor = userCollection.find(new Document("uuid", getUniqueId()));
+ cursor.cursorType(CursorType.NonTailable);
+
+ Document doc = cursor.first();
+ if (doc == null) {
+ return null;
+ }
+ return doc.getString(name);
+ }
+
+ private Date getDateFromDatabase(String name) {
+ FindIterable cursor = userCollection.find(new Document("uuid", getUniqueId()));
+ cursor.cursorType(CursorType.NonTailable);
+
+ Document doc = cursor.first();
+ if (doc == null) {
+ return null;
+ }
+ return doc.getDate(name);
+ }
+
+ public Perms.Ranks getRank() {
+ return Perms.Ranks.valueOf(getStringFromDatabase("rank"));
+ }
+
+ public Date getFirstLogin() {
+ return getDateFromDatabase("firstLogin");
+ }
+
+ public Date getLastLogin() {
+ return getDateFromDatabase("lastLogin");
+ }
+
+ public Date getLastOnline() {
+ return getDateFromDatabase("lastOnline");
+ }
+
+ public String getLastIP() {
+ return getStringFromDatabase("lastIP");
+ }
+
+ public int getTSID() {
+ return getIntegerFromDatabase("tsid");
+ }
+
+ public int getTimesJoined() {
+ return getIntegerFromDatabase("timesJoined");
+ }
+
+ public int getCoins() {
+ return getIntegerFromDatabase("coins");
+ }
+
+ public int getExperience() {
+ return getIntegerFromDatabase("experience");
+ }
+
+ public int getSecrets() {
+ return getIntegerFromDatabase("secrets");
+ }
+
+ public ArrayList getFoundSecrets() {
+ return (ArrayList) getObjectFromDatbase("foundSecrets");
+ }
+
+ public ArrayList getFoundEggs() {
+ return (ArrayList) getObjectFromDatbase("foundEggs");
+ }
+
+ public HashMap getSettings() {
+ return (HashMap) getObjectFromDatbase("settings");
+ }
+ */
+ /**
+ * connects player to server in bungeecord
+ * @param server ServerPinger to connect to
+ */
+ public void connectToServer(String server) {
+ Servers.connectServer(PLAYER, server);
+ }
+
+ /**
+ * if player is allowed to do stuff
+ * @param rank Ranks
+ * @return true/false
+ */
+ public boolean isAllowed(Perms.Ranks rank) {
+ try {
+ return Perms.isAllowed(this, rank);
+ } catch (ClassNotFoundException | SQLException e) {
+ e.printStackTrace();
+ return false;
+ }
+ }
+
+ /**
+ * rank of player
+ * @return Ranks
+ */
+ public Perms.Ranks getRank() {
+ try {
+ return Perms.getRank(this);
+ } catch (ClassNotFoundException | SQLException e) {
+ e.printStackTrace();
+ return Perms.Ranks.Player;
+ }
+ }
+
+ public Perms.Ranks getFreshRank() {
+ try{
+ return Perms.getRankFresh(this);
+ }catch (ClassNotFoundException | SQLException e) {
+ e.printStackTrace();
+ return Perms.Ranks.Player;
+ }
+ }
+
+ /**
+ * sets rank of this custom player
+ * @param r Ranks
+ */
+ public void setRank(Perms.Ranks r) {
+ try {
+ Perms.setRank(this, r);
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * prefix of player
+ * @return String
+ */
+ public String getPrefix() {
+ if(customPrefix != null) return customPrefix;
+ if(isNicked()) return Perms.getPrefix(Perms.Ranks.Premium);
+ return Perms.getPrefix(getRank());
+ }
+
+ /**
+ * suffix of player
+ * @return String
+ */
+ public String getSuffix() {
+ if(customSuffix != null) return customSuffix;
+ if(isNicked()) return Perms.getSuffix(Perms.Ranks.Premium);
+ return Perms.getSuffix(getRank());
+ }
+
+ /**
+ * color of player (Ranks)
+ * @return String
+ */
+ public String getColor() {
+ if(customColor != null) return customColor;
+ if(isNicked()) return Perms.getColor(Perms.Ranks.Premium);
+ return Perms.getColor(getRank());
+ }
+
+ public Color getArmorColor() {
+ return Perms.getArmorColor(getRank());
+ }
+
+ /**
+ * sets a custom prefix
+ * @param prefix String
+ */
+ public void setCustomPrefix(String prefix) {
+ customPrefix = prefix;
+ }
+
+ /**
+ * sets a custom suffix
+ * @param suffix String
+ */
+ public void setCustomSuffix(String suffix) {
+ customSuffix = suffix;
+ }
+
+ /**
+ * sets a custom color
+ * @param color String
+ */
+ public void setCustomColor(String color) {
+ customColor = color;
+ }
+
+ /**
+ * gets scoreboard team for player
+ * @return Team
+ */
+ public Team getTeam() {
+ Perms.Teams teams = new Perms.Teams(this);
+ if(isNicked()) {
+ return teams.Premium;
+ }else {
+ return Perms.Teams.getTeam(this);
+ }
+ }
+
+ /**
+ * bans player
+ * @param reason why ban him ?
+ * @param who who banned him ?
+ * @param time ban duration
+ */
+ public void ban(String reason, CustomPlayer who, Integer time) {
+ try {
+ BanSystem.setBanned(this, reason, who, time);
+ } catch (SQLException | ClassNotFoundException e) {
+ e.printStackTrace();
+ }
+ }
+ /**
+ * if player is banned
+ * @return true/false
+ */
+ public boolean isBanned() {
+ try {
+ return BanSystem.isBanned(this);
+ } catch (SQLException | ClassNotFoundException e) {
+ e.printStackTrace();
+ return false;
+ }
+ }
+
+ /**
+ * get ban reason
+ * @return String
+ */
+ public String getBanReason() {
+ try {
+ return BanSystem.getBanReason(this);
+ } catch (SQLException | ClassNotFoundException e) {
+ e.printStackTrace();
+ return null;
+ }
+
+ }
+
+ /**
+ * get uuid of player who banned
+ * @return String
+ */
+ public String getWhoBanned() {
+ try {
+ return BanSystem.getWhoBanned(this);
+ } catch (SQLException | ClassNotFoundException e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ public Timestamp getBanTime() {
+ try {
+ return BanSystem.getBanTime(this);
+ } catch (SQLException e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ /**
+ * unbans the player
+ */
+ public void removeAllBans() {
+ try {
+ BanSystem.removeAllBans(this);
+ } catch (SQLException | ClassNotFoundException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * get nickname of player
+ * @return String
+ */
+ public String getNick() {
+ return NickName.getNick(this);
+ }
+
+ /**
+ * if player is nicked
+ * @return true/false
+ */
+ public boolean isNicked() {
+ if(ServerSettings.isGame()) {
+ try {
+ return NickName.isNicked(this);
+ } catch (SQLException | ClassNotFoundException e) {
+ e.printStackTrace();
+ return false;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * checks if player is nicked
+ * @return true/false
+ */
+ public boolean isNickedReal() {
+ try {
+ return NickName.isNicked(this);
+ } catch (SQLException | ClassNotFoundException e) {
+ e.printStackTrace();
+ }
+ return false;
+ }
+
+ /**
+ * sets nickname
+ * @param is boolean
+ */
+ public void setNicked(boolean is) {
+ try {
+ NickName.setNick(this, is);
+ } catch (SQLException | ClassNotFoundException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void nick(String nick) {
+ NickName.setName(this, nick);
+ NickName.changeSkin(this, nick);
+ }
+
+ public void unnick() {
+ NickName.changeSkin(this, getName());
+ NickName.setName(this, getName());
+ }
+
+ /**
+ * checks if player has played on the network before
+ * @return true/false
+ */
+ @Override
+ public boolean hasPlayedBefore() {
+ MySQL sql = Core.returnSQL();
+ try {
+ sql.openConnection();
+ String uuid = this.getUniqueId().toString();
+ ResultSet rs = sql.getConnection().createStatement().executeQuery("SELECT * FROM users WHERE UUID= '" + uuid + "';");
+ if (rs.next()) {
+ sql.closeConnection();
+ return true;
+ }else {
+ sql.closeConnection();
+ return false;
+ }
+
+ } catch (ClassNotFoundException | SQLException e) {
+ e.printStackTrace();
+ return false;
+ }
+ }
+
+ /**
+ * checks if inventory is empty
+ * @return true/false
+ */
+ public boolean hasEmptyInventory() {
+ return Utils.hasEmptyInventory(PLAYER);
+ }
+
+ /**
+ * clears all potion effects from player
+ */
+ public void clearPotionEffects() {
+ Utils.clearPotionEffects(PLAYER);
+ }
+
+ /**
+ * checks if players has a open inventory
+ * @return true/false
+ */
+ public boolean hasOpenInventory() {
+ return openInventory;
+ }
+
+ /**
+ * sets opened inventory
+ * @param openInventory true/false
+ */
+ public void setOpenInventory(boolean openInventory) {
+ this.openInventory = openInventory;
+ }
+
+ /**
+ * gets coins from player
+ * @return coins as integer
+ */
+ public int getCoins() {
+ return Coins.getCoins(this);
+ }
+
+ /**
+ * sets coins if player
+ * @param coins coins as integer
+ */
+ public void setCoins(int coins) {
+ Coins.setCoins(this, coins);
+ }
+
+ /**
+ * adds coins to player coins
+ * @param coins coins as integer
+ */
+ public void addCoins(int coins) {
+ int temp = Coins.getCoins(this);
+ Coins.setCoins(this, temp + coins);
+ }
+
+ /**
+ * substracts coins from player coins
+ * @param coins coins as integer
+ */
+ public void substractCoins(int coins) {
+ int temp = Coins.getCoins(this);
+ Coins.setCoins(this, temp - coins);
+ }
+
+ /**
+ * sends message with actionbar to player
+ * @param text String
+ */
+ public void sendActionBar(String text) {
+ Actionbar.send(PLAYER, text);
+ }
+
+ /**
+ * gets experience from player
+ * @return experience experience as integer
+ */
+ public int getExperience() {
+ return Experience.getExperience(this);
+ }
+
+ /**
+ * sets experience of player
+ * @param experience experience to set
+ */
+ public void setExperience(int experience) {
+ Experience.setExperience(this, experience);
+ }
+
+ /**
+ * adds experience to player
+ * @param experience experience to add
+ */
+ public void addExperience(int experience) {
+ int temp = Experience.getExperience(this);
+ Experience.setExperience(this, temp + experience);
+ setExp(0F);
+ giveExp(getExperience());
+ playSound(getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1.0F, 1.0F);
+ }
+
+ /**
+ * removes experience from player
+ * @param experience experience to remove
+ */
+ public void substractExperience(int experience) {
+ int temp = Experience.getExperience(this);
+ Experience.setExperience(this, temp - experience);
+ setExp(0F);
+ giveExp(getExperience());
+ }
+
+ public void refreshExperience() {
+ setLevel(0);
+ setExp(0F);
+ giveExp(getExperience());
+ }
+
+ public int getFoundSecrets() {
+ return 0;
+ }
+
+ public String getLanguage() {
+ return "DE";
+ }
+
+ public void setLanguage(String lang) {
+ PlayerSettings.set(lang, "lang", this);
+ }
+
+ public boolean isSetting(String setting) {
+ return PlayerSettings.isSet(setting, this);
+ }
+
+ public String getSetting(String setting) { return PlayerSettings.get(setting, this); }
+
+ public void changeSetting(String setting) {
+ PlayerSettings.change(setting, this);
+ }
+
+ public void playParticle(Location loc, EnumParticle ep, float f, int count) {
+ if(isSetting("effects"))
+ Effects.playEffectToPlayer(PLAYER, loc, ep, f, count);
+ }
+
+ public void setAttackSpeed(double speed) {
+ AttributeModifier modifier = new AttributeModifier("Core", speed, AttributeModifier.Operation.ADD_NUMBER);
+ getAttribute(Attribute.GENERIC_ATTACK_SPEED).addModifier(modifier);
+ }
+
+ public double getAttackSpeed() {
+ return getAttribute(Attribute.GENERIC_ATTACK_SPEED).getValue();
+ }
+
+ public void resetAttackSpeed() {
+ AttributeModifier modifier = new AttributeModifier("Core", getAttackSpeed(), AttributeModifier.Operation.ADD_NUMBER);
+ getAttribute(Attribute.GENERIC_ATTACK_SPEED).removeModifier(modifier);
+ }
+
+ public Messages getMessages() {
+ return new Messages(this);
+ }
+
+ public Statistics getStatistics(Game game) {
+ return new Statistics(this, game);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/eu/univento/core/api/player/Experience.java b/src/main/java/eu/univento/core/api/player/Experience.java
new file mode 100644
index 0000000..012a28d
--- /dev/null
+++ b/src/main/java/eu/univento/core/api/player/Experience.java
@@ -0,0 +1,60 @@
+package eu.univento.core.api.player;
+
+import eu.univento.core.Core;
+import eu.univento.core.api.database.MySQL;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+/**
+ * experience management
+ * @author joethei
+ * @version 1.0
+ */
+public class Experience{
+
+ /**
+ * gets experience from player
+ * @param p CustomPlayer
+ * @return experience as integer
+ */
+ static int getExperience(CustomPlayer p) {
+ int id = p.getID();
+ MySQL sql = Core.returnSQL();
+ try {
+ sql.openConnection();
+ PreparedStatement st = sql.getConnection().prepareStatement("SELECT Experience FROM users WHERE ID='" + id + "';");
+ ResultSet rs = st.executeQuery();
+ if(rs.next()) {
+ int coins = rs.getInt("Experience");
+ sql.closeConnection();
+ return coins;
+ }
+ return 0;
+ } catch (ClassNotFoundException | SQLException e) {
+ e.printStackTrace();
+ return 0;
+ }
+ }
+
+ /**
+ * sets experience of player
+ * @param p CustomPlayer
+ * @param experience experience to set
+ */
+ static void setExperience(CustomPlayer p, int experience) {
+ int id = p.getID();
+ MySQL sql = Core.returnSQL();
+ try {
+ sql.openConnection();
+ PreparedStatement st = sql.getConnection().prepareStatement("UPDATE users SET Experience='" + experience + "' WHERE ID='" + id + "';");
+ st.execute();
+ sql.closeConnection();
+ } catch (ClassNotFoundException | SQLException e) {
+ e.printStackTrace();
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/eu/univento/core/api/player/Friends.java b/src/main/java/eu/univento/core/api/player/Friends.java
new file mode 100644
index 0000000..3301acc
--- /dev/null
+++ b/src/main/java/eu/univento/core/api/player/Friends.java
@@ -0,0 +1,109 @@
+package eu.univento.core.api.player;
+
+import eu.univento.core.Core;
+import eu.univento.core.api.database.MySQL;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+
+/**
+ * api for friends
+ * @author joethei
+ * @version 1.1
+ */
+public class Friends {
+
+ /**
+ * player object
+ */
+ CustomPlayer player;
+
+ /**
+ * creates the friends object
+ * @param player CustomPlayer
+ */
+ public Friends(CustomPlayer player) {
+ this.player = player;
+ }
+
+ /**
+ * gets database IDs of friends
+ * @return ArrayList
+ */
+ public ArrayList getFriends() {
+ MySQL sql = Core.returnSQL();
+ try {
+ sql.openConnection();
+ ArrayList list = new ArrayList();
+ ResultSet rs = sql.getConnection().createStatement().executeQuery("SELECT * FROM Friends WHERE Player_ID = '" + player.getID());
+ while(rs.next()) {
+ list.add(rs.getInt("Friend_ID"));
+ }
+ sql.closeConnection();
+ return list;
+ } catch (ClassNotFoundException | SQLException e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ /**
+ * add player to friends
+ * @param p CustomPlayer
+ */
+ public void addFriend(CustomPlayer p) {
+ MySQL sql = Core.returnSQL();
+ try {
+ sql.openConnection();
+ PreparedStatement ps = sql.getConnection().prepareStatement("INSERT INTO Friends ('Player_ID', 'Friend_ID') VALUES ('" + player.getID() + "', '" + p.getID() + "');");
+ ps.execute();
+ sql.closeConnection();
+ } catch (ClassNotFoundException | SQLException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * removes player from friends
+ * @param p CustomPlayer
+ */
+ public void removeFriend(CustomPlayer p) {
+ MySQL sql = Core.returnSQL();
+ try {
+ sql.openConnection();
+ PreparedStatement ps = sql.getConnection().prepareStatement("DELETE FROM Friends WHERE Player_ID='" + player.getID() + "' AND Friend_ID='" + p.getID() + "');");
+ ps.execute();
+ sql.closeConnection();
+ } catch (ClassNotFoundException | SQLException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * checks if player is friend
+ * @param p CustomPlayer
+ * @return true/false
+ */
+ public boolean isFriend(CustomPlayer p) {
+ return getFriends().contains(p.getID());
+ }
+
+ /**
+ * counts friends
+ * @return int
+ */
+ public int countFriends() {
+ return getFriends().size();
+ }
+
+ /**
+ * checks if player has friends
+ * @return true/false
+ */
+ public boolean hasFriends() {
+ return getFriends().size() >= 0;
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/eu/univento/core/api/player/NickName.java b/src/main/java/eu/univento/core/api/player/NickName.java
new file mode 100644
index 0000000..af45b27
--- /dev/null
+++ b/src/main/java/eu/univento/core/api/player/NickName.java
@@ -0,0 +1,219 @@
+package eu.univento.core.api.player;
+
+import com.mojang.authlib.GameProfile;
+import com.mojang.authlib.properties.Property;
+import eu.univento.core.Core;
+import eu.univento.core.api.database.MySQL;
+import net.minecraft.server.v1_9_R1.Packet;
+import net.minecraft.server.v1_9_R1.PacketPlayOutEntityDestroy;
+import net.minecraft.server.v1_9_R1.PacketPlayOutNamedEntitySpawn;
+import net.minecraft.server.v1_9_R1.PacketPlayOutPlayerInfo;
+import org.bukkit.Bukkit;
+import org.bukkit.craftbukkit.v1_9_R1.entity.CraftPlayer;
+import org.bukkit.entity.Player;
+import org.bukkit.scheduler.BukkitRunnable;
+
+import java.lang.reflect.Field;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Random;
+
+/**
+ * gets nick settings for players
+ * @author joethei
+ * @version 1.1
+ */
+public class NickName {
+
+ private static HashMap nicks = new HashMap<>();
+
+ private static Field nameField = getField(GameProfile.class, "name");
+ /**
+ *
+ * @param p remove nickname from player
+ */
+ public static void remove(CustomPlayer p) {
+ if (nicks.containsKey(p))
+ nicks.remove(p);
+ }
+
+ /**
+ * sets nick boolean
+ * @param p player
+ * @param nick boolean
+ * @throws ClassNotFoundException Class couldn't be found
+ * @throws SQLException SQL server not available or throwing error
+ */
+ static void setNick(CustomPlayer p, boolean nick) throws SQLException, ClassNotFoundException {
+ MySQL sql = Core.returnSQL();
+ sql.openConnection();
+ if (nick)
+ sql.getConnection().createStatement().executeUpdate("UPDATE PlayerSettings SET nick = '1' WHERE ID = '" + p.getID() + "';");
+ else
+ sql.getConnection().createStatement().executeUpdate("UPDATE PlayerSettings SET nick = '0' WHERE ID = '" + p.getID() + "';");
+ sql.closeConnection();
+ }
+
+ /**
+ * gets if player is nicked
+ * @param p player
+ * @return true / false
+ * @throws ClassNotFoundException Class couldn't be found
+ * @throws SQLException SQL server not available or throwing error
+ */
+ static boolean isNicked(CustomPlayer p) throws SQLException, ClassNotFoundException {
+ MySQL sql = Core.returnSQL();
+ sql.openConnection();
+ ResultSet rs = sql.getConnection().createStatement().executeQuery("SELECT nick FROM PlayerSettings WHERE ID = '" + p.getID() + "';");
+ if (rs.next()) {
+ boolean is = rs.getInt("nick") == 1;
+ sql.closeConnection();
+ return is;
+ }
+ sql.closeConnection();
+ return false;
+ }
+
+ /**
+ * gets nickname of player
+ * @param p player
+ * @return String
+ */
+ static String getNick(CustomPlayer p) {
+ if (nicks.containsKey(p)) {
+ return nicks.get(p);
+ }else if(p.isNicked()){
+ nicks.put(p, getRandomNick());
+ return nicks.get(p);
+ }
+ return null;
+ }
+
+ /**
+ * gets random Nickname
+ * @return String
+ */
+ private static String getRandomNick() {
+ ArrayList names = new ArrayList<>();
+ names.add("GommeHD");
+ names.add("Notch");
+ names.add("12ms");
+ names.add("Coriux");
+ names.add("Kekse");
+ names.add("AFK");
+ names.add("13ms");
+ names.add("Inhaltsangabe");
+ names.add("LassMichEinfach");
+ names.add("Inventar");
+ names.add("DDoS");
+ names.add("Upps");
+ names.add("Hater");
+ names.add("ServerOwner");
+ names.add("HastDuMinecraft");
+ names.add("Telekom");
+ names.add("TeamBlauNurGute");
+ names.add("Stats");
+ names.add("Herbst");
+ names.add("IchHabTwitter");
+ names.add("Versager");
+ names.add("ImmerAmSterben");
+ names.add("Lagmolia");
+ names.add("Bowspammer");
+ names.add("Behindert");
+ names.add("DasProgramm");
+ names.add("DasPlugin");
+ names.add("Staubsauger");
+ names.add("Buchstabe");
+ names.add("gekickt");
+ names.add("Einfachpermaban");
+ names.add("KeinNameWarFrei");
+ names.add("KlopapierIstLeer");
+ names.add("Packungsbeilage");
+ names.add("HabKeinRewiPremium");
+ names.add("PermaBanAufGomme");
+ names.add("Vorteil");
+ names.add("Nachteil");
+ names.add("Oberteil");
+ names.add("Einstellung");
+ names.add("Verbindung");
+ names.add("WarAFKWasWar");
+
+ Random r = new Random();
+ int i = r.nextInt(names.size());
+
+ return names.get(i);
+ }
+
+ static void changeSkin(CustomPlayer p, String name) {
+ Skin skin = new Skin(Bukkit.getOfflinePlayer(name).getUniqueId().toString().replace("_", ""));
+ if(skin.getName() != null) {
+ GameProfile profile = p.getProfile();
+ profile.getProperties().clear();
+ profile.getProperties().put(skin.getName(), new Property(skin.getName(), skin.getValue(), skin.getSignature()));
+ Bukkit.getScheduler().runTaskLater(Core.getInstance(), () -> {
+ for(Player players : Bukkit.getOnlinePlayers()) {
+ players.hidePlayer(p);
+ }
+ }, 1L);
+ Bukkit.getScheduler().runTaskLater(Core.getInstance(), () -> {
+ for(Player players : Bukkit.getOnlinePlayers()) {
+ players.showPlayer(p);
+ }
+ }, 1L);
+ }
+ }
+
+ static void setName(CustomPlayer p, String name) {
+ p.setDisplayName(name);
+ try {
+ nameField.set(p.getProfile(), name);
+ PacketPlayOutEntityDestroy destroy = new PacketPlayOutEntityDestroy(p.getEntityId());
+ sendPacket(destroy);
+ removeFromTablist(p);
+
+ new BukkitRunnable() {
+
+ @Override
+ public void run() {
+ addToTablist(p);
+ PacketPlayOutNamedEntitySpawn spawn = new PacketPlayOutNamedEntitySpawn(p.getHandle());
+ Bukkit.getOnlinePlayers().stream().filter(players -> !players.equals(p)).forEach(players -> {
+ ((CraftPlayer) players).getHandle().playerConnection.sendPacket(spawn);
+ });
+ }
+
+ }.runTaskLater(Core.getInstance(), 4);
+ } catch (IllegalAccessException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private static void addToTablist(CraftPlayer p) {
+ PacketPlayOutPlayerInfo packet = new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER, p.getHandle());
+ sendPacket(packet);
+ }
+
+ private static void removeFromTablist(CraftPlayer cp) {
+ PacketPlayOutPlayerInfo packet = new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.REMOVE_PLAYER, cp.getHandle());
+ sendPacket(packet);
+ }
+
+ private static void sendPacket(Packet> packet) {
+ for(Player players : Bukkit.getOnlinePlayers()) {
+ ((CraftPlayer)players).getHandle().playerConnection.sendPacket(packet);
+ }
+ }
+
+ private static Field getField(Class> clazz, String name) {
+ try{
+ Field field = clazz.getDeclaredField(name);
+ field.setAccessible(true);
+ return field;
+ }catch (NoSuchFieldException | SecurityException e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/eu/univento/core/api/player/Perms.java b/src/main/java/eu/univento/core/api/player/Perms.java
new file mode 100644
index 0000000..6a9819d
--- /dev/null
+++ b/src/main/java/eu/univento/core/api/player/Perms.java
@@ -0,0 +1,307 @@
+package eu.univento.core.api.player;
+
+import eu.univento.core.Core;
+import eu.univento.core.api.database.MySQL;
+import org.bukkit.Color;
+import org.bukkit.scoreboard.Scoreboard;
+import org.bukkit.scoreboard.Team;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.HashMap;
+
+/**
+ * some permission management
+ * @author joethei
+ * @version 1.0
+ */
+public class Perms{
+
+ private static HashMap ranks = new HashMap<>();
+ public static HashMap getRanks() {
+ return ranks;
+ }
+
+/**
+ * gets the prefix of a player
+ * @param r Ranks
+ * @return String
+ */
+static String getPrefix(Ranks r) {
+ switch(r) {
+ case Admin: return "§8[§4Admin§8]§4 ";
+ case SrDeveloper: return "§8[§3Dev+§8]§3 ";
+ case Developer: return "§8[§3Dev§8]§3 ";
+ case SrModerator: return "§8[§cSrMod§8]§c ";
+ case HeadBuilder: return "§8[§aHead-Builder§8]§a ";
+ case Moderator: return "§8[§cMod§8]§c ";
+ case Builder: return "§8[§2Builder§8]§2 ";
+ case Supporter: return "§8[§9Supporter§8]§9 ";
+ case Youtuber: return "§5";
+ case Premium: return "§6";
+ case Player: return "§e";
+ default: return "§cFehler ";
+ }
+ }
+
+/**
+ * gets the suffix of a player
+ * @param r Ranks
+ * @return String
+ */
+static String getSuffix(Ranks r) {
+ switch(r) {
+ case Admin: return "§8 »§7 ";
+ case SrDeveloper: return "§8 »§7";
+ case Developer: return "§8 »§7 ";
+ case SrModerator: return "§8 »§7 ";
+ case HeadBuilder: return "§8 »§7 ";
+ case Moderator: return "§8 »§7 ";
+ case Builder: return "§8 »§7 ";
+ case Supporter: return "§8 »§7 ";
+ case Youtuber: return "§8 »§7 ";
+ case Premium: return "§8 »§7 ";
+ case Player: return "§8 »§7 ";
+ default: return "§cFehler";
+ }
+ }
+
+/**
+ * gets color of a player
+ * @param r Ranks
+ * @return String
+ */
+static String getColor(Ranks r) {
+ switch(r) {
+ case Admin: return "§4";
+ case SrDeveloper: return "§3";
+ case Developer: return "§3";
+ case SrModerator: return "§c";
+ case HeadBuilder: return "§a";
+ case Moderator: return "§c";
+ case Builder: return "§2";
+ case Supporter: return "§9";
+ case Youtuber: return "§5";
+ case Premium: return "§6";
+ case Player: return "§e";
+ default: return "§cFehler";
+ }
+ }
+
+static Color getArmorColor(Ranks r) {
+ switch (r) {
+ case Admin: return Color.MAROON;
+ case SrDeveloper: return Color.TEAL;
+ case Developer: return Color.TEAL;
+ case SrModerator: return Color.RED;
+ case HeadBuilder: return Color.LIME;
+ case Moderator: return Color.RED;
+ case Builder: return Color.GREEN;
+ case Supporter: return Color.PURPLE;
+ default: return null;
+ }
+}
+
+/**
+ * contains all scoreboard ranks
+ * @author joethei
+ * @version 1.0
+ */
+static class Teams {
+
+ CustomPlayer player;
+ Scoreboard board;
+
+ Team Admin;
+ Team SrDeveloper;
+ Team Developer;
+ Team SrModerator;
+ Team Moderator;
+ Team HeadBuilder;
+ Team Builder;
+ Team Supporter;
+ Team Youtuber;
+ Team Premium;
+ Team Player;
+
+ Teams(CustomPlayer player) {
+ this.player = player;
+ board = player.getScoreboard();
+ Admin = board.getTeam("a");
+ SrDeveloper = board.getTeam("b");
+ Developer = board.getTeam("c");
+ SrModerator = board.getTeam("d");
+ HeadBuilder = board.getTeam("e");
+ Moderator = board.getTeam("f");
+ Builder = board.getTeam("g");
+ Supporter = board.getTeam("h");
+ Youtuber = board.getTeam("i");
+ Premium = board.getTeam("j");
+ Player = board.getTeam("k");
+ }
+
+ /**
+ * returns scoreboard team for rank
+ * @param p CustomPlayer
+ * @return Team
+ */
+ static Team getTeam(CustomPlayer p) {
+ Teams teams = new Teams(p);
+ switch(p.getRank()) {
+ case Admin: return teams.Admin;
+ case SrDeveloper: return teams.SrDeveloper;
+ case Developer: return teams.Developer;
+ case SrModerator: return teams.SrModerator;
+ case HeadBuilder: return teams.HeadBuilder;
+ case Moderator: return teams.Moderator;
+ case Builder: return teams.Builder;
+ case Supporter: return teams.Supporter;
+ case Youtuber: return teams.Youtuber;
+ case Premium: return teams.Premium;
+ case Player: return teams.Player;
+ default: return null;
+ }
+ }
+}
+
+/**
+ * setup scoreboards
+ */
+public static void initScoreboard(CustomPlayer p) {
+ Scoreboard board = p.getScoreboard();
+ board.getTeams().forEach(Team::unregister);
+
+ Team Admin = board.registerNewTeam("a");
+ Team SrDeveloper = board.registerNewTeam("b");
+ Team Developer = board.registerNewTeam("c");
+ Team SrModerator = board.registerNewTeam("d");
+ Team HeadBuilder = board.registerNewTeam("e");
+ Team Moderator = board.registerNewTeam("f");
+ Team Builder = board.registerNewTeam("g");
+ Team Supporter = board.registerNewTeam("h");
+ Team Youtuber = board.registerNewTeam("i");
+ Team Premium = board.registerNewTeam("j");
+ Team Player = board.registerNewTeam("k");
+
+ Admin.setPrefix(getColor(Ranks.Admin));
+ SrDeveloper.setPrefix(getColor(Ranks.SrDeveloper));
+ Developer.setPrefix(getColor(Ranks.Developer));
+ SrModerator.setPrefix(getColor(Ranks.SrModerator));
+ HeadBuilder.setPrefix(getColor(Ranks.HeadBuilder));
+ Moderator.setPrefix(getColor(Ranks.Moderator));
+ Builder.setPrefix(getColor(Ranks.Builder));
+ Supporter.setPrefix(getColor(Ranks.Supporter));
+ Youtuber.setPrefix(getColor(Ranks.Youtuber));
+ Premium.setPrefix(getColor(Ranks.Premium));
+ Player.setPrefix(getColor(Ranks.Player));
+
+ Admin.setOption(Team.Option.NAME_TAG_VISIBILITY, Team.OptionStatus.ALWAYS);
+ SrDeveloper.setOption(Team.Option.NAME_TAG_VISIBILITY, Team.OptionStatus.ALWAYS);
+ Developer.setOption(Team.Option.NAME_TAG_VISIBILITY, Team.OptionStatus.ALWAYS);
+ SrModerator.setOption(Team.Option.NAME_TAG_VISIBILITY, Team.OptionStatus.ALWAYS);
+ HeadBuilder.setOption(Team.Option.NAME_TAG_VISIBILITY, Team.OptionStatus.ALWAYS);
+ Moderator.setOption(Team.Option.NAME_TAG_VISIBILITY, Team.OptionStatus.ALWAYS);
+ Builder.setOption(Team.Option.NAME_TAG_VISIBILITY, Team.OptionStatus.ALWAYS);
+ Supporter.setOption(Team.Option.NAME_TAG_VISIBILITY, Team.OptionStatus.ALWAYS);
+ Youtuber.setOption(Team.Option.NAME_TAG_VISIBILITY, Team.OptionStatus.ALWAYS);
+ Premium.setOption(Team.Option.NAME_TAG_VISIBILITY, Team.OptionStatus.ALWAYS);
+ Player.setOption(Team.Option.NAME_TAG_VISIBILITY, Team.OptionStatus.ALWAYS);
+}
+/**
+ * gets Rank of player
+ * @param p Player
+ * @return Ranks
+ * @throws ClassNotFoundException Class couldn't be found
+ * @throws SQLException SQL server not available or throwing error
+ */
+static Ranks getRank(CustomPlayer p) throws ClassNotFoundException, SQLException {
+ if(getRanks().get(p) != null) {
+ return getRanks().get(p);
+ }else {
+ return getRankFresh(p);
+ }
+
+ }
+
+/**
+ * gets Rank of player fresh from database
+ * @param p Player
+ * @return Ranks
+ * @throws ClassNotFoundException Class couldn't be found
+ * @throws SQLException SQL server not available or throwing error
+ */
+static Ranks getRankFresh(CustomPlayer p) throws SQLException, ClassNotFoundException {
+ MySQL sql = Core.returnSQL();
+ sql.openConnection();
+ String uuid = p.getUniqueId().toString();
+ PreparedStatement st = sql.getConnection().prepareStatement("SELECT * FROM users WHERE UUID= '" + uuid + "';");
+ ResultSet rs = st.executeQuery();
+ if(rs.next()) {
+ String rank = rs.getString("Rank");
+ sql.closeConnection();
+ return Ranks.valueOf(rank);
+ }else {
+ sql.closeConnection();
+ return null;
+ }
+ }
+
+ /**
+ * sets rank for player
+ * @param p Player
+ * @param r Ranks
+ * @throws ClassNotFoundException Class couldn't be found
+ * @throws SQLException SQL server not available or throwing error
+ */
+static void setRank(CustomPlayer p, Ranks r) throws ClassNotFoundException, SQLException {
+ MySQL sql = Core.returnSQL();
+ sql.openConnection();
+ PreparedStatement st = sql.getConnection().prepareStatement("UPDATE users SET Rank='" + r.toString() + "' WHERE ID='" + p.getID() + "';");
+ st.execute();
+ sql.closeConnection();
+ }
+
+/**
+ * if player is allowed to do
+ * @param p Player
+ * @param r Ranks
+ * @return true / false
+ * @throws ClassNotFoundException Class couldn't be found
+ * @throws SQLException SQL server not available or throwing error
+ */
+static boolean isAllowed(CustomPlayer p, Ranks r) throws ClassNotFoundException, SQLException{
+ Ranks rank;
+ if(getRank(p) == null) {
+ rank = getRankFresh(p);
+ }else {
+ rank = getRank(p);
+ }
+ return rank.value >= r.value;
+ }
+
+/**
+ * contains all ranks
+ * @author joethei
+ * @version 1.0
+ */
+ public enum Ranks{
+ Admin(11),
+ SrDeveloper(10),
+ Developer(9),
+ SrModerator(8),
+ HeadBuilder(7),
+ Moderator(6),
+ Builder(5),
+ Supporter(4),
+ Youtuber(3),
+ Premium(2),
+ Player(1);
+
+ final int value;
+
+ Ranks(int n) {
+ this.value = n;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/eu/univento/core/api/player/PlayerSettings.java b/src/main/java/eu/univento/core/api/player/PlayerSettings.java
new file mode 100644
index 0000000..07cf824
--- /dev/null
+++ b/src/main/java/eu/univento/core/api/player/PlayerSettings.java
@@ -0,0 +1,144 @@
+package eu.univento.core.api.player;
+
+import eu.univento.core.Core;
+import eu.univento.core.api.database.MySQL;
+import org.bukkit.Bukkit;
+import org.bukkit.entity.Player;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+
+/**
+ * server-wide settings
+ * @author joethei
+ * @version 0.1
+ */
+
+public class PlayerSettings {
+
+ /**
+ * returns if setting is set
+ * @param what what setting is set
+ * @param p CustomPlayer
+ * @return boolean
+ */
+ static boolean isSet(String what, CustomPlayer p) {
+ int id = p.getID();
+ MySQL sql = Core.returnSQL();
+ try {
+ sql.openConnection();
+ PreparedStatement st = sql.getConnection().prepareStatement("SELECT * FROM PlayerSettings WHERE ID = '" + id + "';");
+ ResultSet rs = st.executeQuery();
+ if (rs.next()) {
+ boolean is = rs.getInt(what) == 1;
+ sql.closeConnection();
+ return is;
+ }
+ sql.closeConnection();
+ return false;
+ } catch (ClassNotFoundException | SQLException e) {
+ e.printStackTrace();
+ return false;
+ }
+ }
+
+ /**
+ * sets setting
+ * @param p CustomPlayer
+ * @param bool boolean to set to
+ * @param what what to set
+ * @throws ClassNotFoundException class could not be found
+ * @throws SQLException SQL ServerPinger not available or throwing error
+ */
+ static void set(boolean bool, String what, CustomPlayer p) throws SQLException, ClassNotFoundException {
+ int id = p.getID();
+ MySQL sql = Core.returnSQL();
+ sql.openConnection();
+ if (bool) {
+ PreparedStatement st = sql.getConnection().prepareStatement("UPDATE PlayerSettings SET " + what + " = '1' WHERE ID = '" + id + "';");
+ st.execute();
+ }else {
+ PreparedStatement st = sql.getConnection().prepareStatement("UPDATE PlayerSettings SET " + what + " = '0' WHERE ID = '" + id + "';");
+ st.execute();
+ }
+ sql.closeConnection();
+ }
+
+ /**
+ * gets setting from player
+ * @param what what to get
+ * @param p CustomPlayer
+ * @return String
+ */
+ static String get(String what, CustomPlayer p) {
+ int id = p.getID();
+ MySQL sql = Core.returnSQL();
+ try {
+ sql.openConnection();
+ PreparedStatement st = sql.getConnection().prepareStatement("SELECT " + what + " FROM PlayerSettings WHERE ID='" + id + "';");
+ ResultSet rs = st.executeQuery();
+ if(rs.next()) {
+ String rt = rs.getString(what);
+ sql.closeConnection();
+ return rt;
+ }
+ return null;
+ } catch (SQLException | ClassNotFoundException e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ /**
+ * sets settings for player
+ * @param set value to set
+ * @param what what to set
+ * @param p CustomPlayer
+ */
+ static void set(String set, String what, CustomPlayer p) {
+ int id = p.getID();
+ MySQL sql = Core.returnSQL();
+ try {
+ sql.openConnection();
+ PreparedStatement st = sql.getConnection().prepareStatement("UPDATE PlayerSettings SET " + what + " = '" + set + "' WHERE ID = '" + id + "';");
+ st.execute();
+ } catch (SQLException | ClassNotFoundException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * changes settings
+ * @param what what to set
+ * @param p CustomPlayer
+ */
+ static void change(String what, CustomPlayer p) {
+ if(isSet(what, p)) {
+ try {
+ set(false, what, p);
+ } catch (ClassNotFoundException | SQLException e) {
+ e.printStackTrace();
+ }
+ }else {
+ try {
+ set(true, what, p);
+ } catch (ClassNotFoundException | SQLException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public static ArrayList getAllPlayersWithEffectsEnabled() {
+ ArrayList list = new ArrayList<>();
+ for(Player players : Bukkit.getOnlinePlayers()) {
+ CustomPlayer p = CustomPlayer.getPlayer(players);
+ if(isSet("effects", p)) {
+ list.add(p);
+ }
+ }
+ return list;
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/eu/univento/core/api/player/Spectator.java b/src/main/java/eu/univento/core/api/player/Spectator.java
new file mode 100644
index 0000000..7c28315
--- /dev/null
+++ b/src/main/java/eu/univento/core/api/player/Spectator.java
@@ -0,0 +1,67 @@
+package eu.univento.core.api.player;
+
+import eu.univento.core.api.server.ServerSettings;
+import org.bukkit.Bukkit;
+import org.bukkit.GameMode;
+import org.bukkit.entity.Player;
+
+import java.util.ArrayList;
+
+/**
+ *
+ * @author joethei
+ * @version 1.0
+ */
+public class Spectator {
+
+ /**
+ * contains all spectators
+ */
+ private static ArrayList spectators = new ArrayList<>();
+
+ /**
+ * adds player to spectators
+ * @param p CustomPlayer
+ */
+ public static void add(CustomPlayer p) {
+ for (Player on : Bukkit.getOnlinePlayers()) {
+ on.hidePlayer(p);
+ }
+ spectators.add(p);
+ p.setGameMode(GameMode.ADVENTURE);
+ p.setAllowFlight(true);
+ p.setFlying(true);
+ }
+
+ /**
+ * removes player from spectator
+ * @param p CustomPlayer
+ */
+ public static void remove(CustomPlayer p) {
+ for (Player on : Bukkit.getOnlinePlayers()) {
+ on.showPlayer(p);
+ }
+ spectators.remove(p);
+ p.setGameMode(ServerSettings.getGameMode());
+ p.setAllowFlight(false);
+ p.setFlying(false);
+ }
+
+ /**
+ * gets all spectators
+ * @return ArrayList
+ */
+ public static ArrayList getSpectators() {
+ return spectators;
+ }
+
+ /**
+ * checks if players is spectator
+ * @param p CustomPlayer
+ * @return true/false
+ */
+ public static boolean is(CustomPlayer p) {
+ return spectators.contains(p);
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/eu/univento/core/api/player/Statistics.java b/src/main/java/eu/univento/core/api/player/Statistics.java
new file mode 100644
index 0000000..4541342
--- /dev/null
+++ b/src/main/java/eu/univento/core/api/player/Statistics.java
@@ -0,0 +1,217 @@
+package eu.univento.core.api.player;
+
+import eu.univento.core.Core;
+import eu.univento.core.api.database.MySQL;
+import eu.univento.core.api.server.Game;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+/**
+ * statistics management
+ * @author joethei
+ * @version 1.0
+ */
+public class Statistics {
+
+ CustomPlayer player;
+ Game game;
+
+ /**
+ * @param player CustomPlayer
+ * @param game Game
+ */
+ public Statistics(CustomPlayer player, Game game) {
+ this.player = player;
+ this.game = game;
+ }
+
+
+ /**
+ * gets deaths of player for game
+ * @return Integer
+ */
+ public int getDeaths() {
+ MySQL sql = Core.returnSQL();
+ try {
+ sql.openConnection();
+ PreparedStatement st = sql.getConnection().prepareStatement("SELECT Deaths FROM " + game.toString() + "Stats WHERE ID='" + player.getID() + "');");
+ ResultSet rs = st.executeQuery();
+ int deaths = rs.getInt("Deaths");
+ sql.closeConnection();
+ return deaths;
+ } catch (ClassNotFoundException | SQLException e) {
+ e.printStackTrace();
+ return 0;
+ }
+ }
+
+ /**
+ * sets deaths of player for game
+ * @param deaths Integer
+ */
+ public void setDeaths(int deaths) {
+ MySQL sql = Core.returnSQL();
+ try {
+ sql.openConnection();
+ PreparedStatement st = sql.getConnection().prepareStatement("UPDATE " + game.toString() + "Stats WHERE ID='" + player.getID() + "' SET Deaths='" + deaths +"');");
+ st.execute();
+ } catch (ClassNotFoundException | SQLException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void addDeath() {
+ setDeaths(getDeaths() + 1);
+ }
+
+ /**
+ * gets kills of player for game
+ * @return Integer
+ */
+ public int getKills() {
+ MySQL sql = Core.returnSQL();
+ try {
+ sql.openConnection();
+ PreparedStatement st = sql.getConnection().prepareStatement("SELECT Kills FROM " + game.toString() + "Stats WHERE ID='" + player.getID() + "');");
+ ResultSet rs = st.executeQuery();
+ int kills = rs.getInt("Kills");
+ sql.closeConnection();
+ return kills;
+ } catch (ClassNotFoundException | SQLException e) {
+ e.printStackTrace();
+ return 0;
+ }
+ }
+
+ /**
+ * sets kills of player for game
+ * @param kills Integer
+ */
+ public void setKills(int kills) {
+ MySQL sql = Core.returnSQL();
+ try {
+ sql.openConnection();
+ PreparedStatement st = sql.getConnection().prepareStatement("UPDATE " + game.toString() + "Stats WHERE ID='" + player.getID() + "' SET Kills='" + kills +"');");
+ st.execute();
+ } catch (ClassNotFoundException | SQLException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void addKill() {
+ setKills(getKills() + 1);
+ }
+
+ /**
+ * gets played rounds of player for game
+ * @return Integer
+ */
+ public int getPlayedRounds() {
+ MySQL sql = Core.returnSQL();
+ try {
+ sql.openConnection();
+ PreparedStatement st = sql.getConnection().prepareStatement("SELECT PlayedRounds FROM " + game.toString() + "Stats WHERE ID='" + player.getID() + "');");
+ ResultSet rs = st.executeQuery();
+ int rounds = rs.getInt("PlayedRounds");
+ sql.closeConnection();
+ return rounds;
+ } catch (ClassNotFoundException | SQLException e) {
+ e.printStackTrace();
+ return 0;
+ }
+ }
+
+ /**
+ * sets played rounds of player for game
+ * @param rounds Integer
+ */
+ public void setPlayedRounds(int rounds) {
+ MySQL sql = Core.returnSQL();
+ try {
+ sql.openConnection();
+ PreparedStatement st = sql.getConnection().prepareStatement("UPDATE " + game.toString() + "Stats WHERE ID='" + player.getID() + "' SET PlayedRounds='" + rounds +"');");
+ st.execute();
+ } catch (ClassNotFoundException | SQLException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void addPlayedRound() {
+ setPlayedRounds(getPlayedRounds() + 1);
+ }
+
+ /**
+ * gets playtime of player for game
+ * @return Integer
+ */
+ public int getPlaytime() {
+ MySQL sql = Core.returnSQL();
+ try {
+ sql.openConnection();
+ PreparedStatement st = sql.getConnection().prepareStatement("SELECT Playtime FROM " + game.toString() + "Stats WHERE ID='" + player.getID() + "');");
+ ResultSet rs = st.executeQuery();
+ int time = rs.getInt("Playtime");
+ sql.closeConnection();
+ return time;
+ } catch (ClassNotFoundException | SQLException e) {
+ e.printStackTrace();
+ return 0;
+ }
+ }
+
+ /**
+ * sets playtime of player for game
+ * @param time Integer
+ */
+ public void setPlaytime(int time) {
+ MySQL sql = Core.returnSQL();
+ try {
+ sql.openConnection();
+ PreparedStatement st = sql.getConnection().prepareStatement("UPDATE " + game.toString() + "Stats WHERE ID='" + player.getID() + "' SET Playtime='" + time +"');");
+ st.execute();
+ } catch (ClassNotFoundException | SQLException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * gets wins of player for game
+ * @return Integer
+ */
+ public int getWins() {
+ MySQL sql = Core.returnSQL();
+ try {
+ sql.openConnection();
+ PreparedStatement st = sql.getConnection().prepareStatement("SELECT Wins FROM " + game.toString() + "Stats WHERE ID='" + player.getID() + "');");
+ ResultSet rs = st.executeQuery();
+ int wins = rs.getInt("Wins");
+ sql.closeConnection();
+ return wins;
+ } catch (ClassNotFoundException | SQLException e) {
+ e.printStackTrace();
+ return 0;
+ }
+ }
+
+ /**
+ * sets wins of player for game
+ * @param wins Integer
+ */
+ public void setWins(int wins) {
+ MySQL sql = Core.returnSQL();
+ try {
+ sql.openConnection();
+ PreparedStatement st = sql.getConnection().prepareStatement("UPDATE " + game.toString() + "Stats WHERE ID='" + player.getID() + "' SET Wins='" + wins +"');");
+ st.execute();
+ } catch (ClassNotFoundException | SQLException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void addWin() {
+ setWins(getWins() + 1);
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/eu/univento/core/api/server/Game.java b/src/main/java/eu/univento/core/api/server/Game.java
new file mode 100644
index 0000000..bd4ca7d
--- /dev/null
+++ b/src/main/java/eu/univento/core/api/server/Game.java
@@ -0,0 +1,19 @@
+package eu.univento.core.api.server;
+
+/**
+ * all minigames with description
+ * @author joethei
+ * @version 1.0
+ */
+public enum Game {
+
+ //TODO: lookout for some TODOs in this file
+ WoolGet,
+ FlagAttack,
+ Free4All,
+ TrashGames,
+ HulkFight,
+ Maya,
+ FallingAttack,
+ Worms
+}
\ No newline at end of file
diff --git a/src/main/java/eu/univento/core/api/server/GameInfo.java b/src/main/java/eu/univento/core/api/server/GameInfo.java
new file mode 100644
index 0000000..bb55932
--- /dev/null
+++ b/src/main/java/eu/univento/core/api/server/GameInfo.java
@@ -0,0 +1,27 @@
+package eu.univento.core.api.server;
+
+/**
+ * @author joethei
+ * @version 0.1
+ */
+public class GameInfo {
+
+ Game game;
+
+ public GameInfo(Game game) {
+ this.game = game;
+ }
+
+ public int getPlayerCount() {
+ return 0;
+ }
+
+ public int getServerCount() {
+ return 0;
+ }
+
+ public ServerInfo[] getServers() {
+ return null;
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/eu/univento/core/api/server/MojangService.java b/src/main/java/eu/univento/core/api/server/MojangService.java
new file mode 100644
index 0000000..2207006
--- /dev/null
+++ b/src/main/java/eu/univento/core/api/server/MojangService.java
@@ -0,0 +1,122 @@
+package eu.univento.core.api.server;
+
+import org.bukkit.ChatColor;
+import org.json.simple.JSONObject;
+import org.json.simple.parser.JSONParser;
+import org.json.simple.parser.ParseException;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.URL;
+
+public enum MojangService {
+
+ ACCOUNTS("Accounts Service", "account.mojang.com"),
+ AUTHENTICATION("Authentication Service", "auth.mojang.com"),
+ AUTHENTICATION_SERVER("Authentication ServerPinger", "authserver.mojang.com"),
+ LOGIN("Login Service", "login.minecraft.net"),
+ SESSION_MINECRAFT("Minecraft Session ServerPinger", "session.minecraft.net"),
+ SESSION_MOJANG("Mojang Session ServerPinger", "sessionserver.mojang.com"),
+ SKINS("Skin ServerPinger", "skins.minecraft.net"),
+ MAIN_WEBSITE("Main Site", "minecraft.net");
+
+ /*
+ * @Author TheTinySpider
+ * Idea from: sebasju1234
+ *
+ * Status names and other information can be found at:
+ * [url]http://minecraft.gamepedia.com/User_talk:Oxguy3/Minecraft.net_API[/url]
+ */
+
+ private String name, serviceURL;
+ private JSONParser jsonParser = new JSONParser();
+
+ MojangService(String name, String serviceURL) {
+ this.name = name;
+ this.serviceURL = serviceURL;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Check the current Mojang service for it's status, errors are ignored.
+ *
+ * @return Status of the service.
+ */
+ public Status getStatus() {
+ return getStatus(true);
+ }
+
+ /**
+ * Check the current Mojang service for it's status.
+ *
+ * @param suppressErrors - Don't print errors in console.
+ * @return Status of the service.
+ */
+ public Status getStatus(boolean suppressErrors) {
+ try {
+ URL url = new URL("[url]http://status.mojang.com/check?service=[/url]" + serviceURL);
+ BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(url.openStream()));
+
+ Object object = jsonParser.parse(bufferedReader);
+ JSONObject jsonObject = (JSONObject) object;
+
+ String status = (String) jsonObject.get(serviceURL);
+
+ return Status.get(status);
+
+ } catch (IOException | ParseException exception) {
+
+ if (!suppressErrors) {
+ exception.printStackTrace();
+ }
+
+ return Status.UNKNOWN;
+ }
+ }
+
+ public enum Status {
+ ONLINE("Online", ChatColor.GREEN.toString(), "No problems detected!"),
+ UNSTABLE("Unstable", ChatColor.YELLOW.toString(), "May be experiencing issues..."),
+ OFFLINE("Offline", ChatColor.DARK_RED.toString(), "Experiencing problems!"),
+ UNKNOWN("Unknown", ChatColor.WHITE.toString(), "Couldn't connect to Mojang!");
+
+ private String status, color, description;
+
+ Status(String status, String color, String description) {
+ this.status = status;
+ this.color = color;
+ this.description = description;
+ }
+
+ public String getStatus() {
+ return status;
+ }
+
+ public String getColor() {
+ return color;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public static Status get(String status) {
+ status = status.toLowerCase();
+
+ switch (status) {
+ case "green":
+ return Status.ONLINE;
+ case "yellow":
+ return Status.UNSTABLE;
+ case "red":
+ return Status.OFFLINE;
+ default:
+ return Status.UNKNOWN;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/eu/univento/core/api/server/ServerDatabase.java b/src/main/java/eu/univento/core/api/server/ServerDatabase.java
new file mode 100644
index 0000000..e4a2278
--- /dev/null
+++ b/src/main/java/eu/univento/core/api/server/ServerDatabase.java
@@ -0,0 +1,69 @@
+package eu.univento.core.api.server;
+
+import eu.univento.core.Core;
+import eu.univento.core.api.database.MySQL;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+/**
+ * @author joethei
+ * @version 0.1
+ */
+public class ServerDatabase {
+
+ static String getIP(String name) {
+ MySQL sql = Core.returnSQL();
+ try {
+ sql.openConnection();
+ PreparedStatement st = sql.getConnection().prepareStatement("SELECT ip FROM Servers WHERE name='" + name + "'");
+ ResultSet rs = st.executeQuery();
+ if(rs.next()) {
+ String ip = rs.getString("ip");
+ sql.closeConnection();
+ return ip;
+ }
+ return null;
+ } catch (SQLException | ClassNotFoundException e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ static int getPort(String name) {
+ MySQL sql = Core.returnSQL();
+ try {
+ sql.openConnection();
+ PreparedStatement st = sql.getConnection().prepareStatement("SELECT port FROM Servers WHERE name='" + name + "'");
+ ResultSet rs = st.executeQuery();
+ if(rs.next()) {
+ int port = rs.getInt("port");
+ sql.closeConnection();
+ return port;
+ }
+ return 0;
+ } catch (SQLException | ClassNotFoundException e) {
+ e.printStackTrace();
+ return 0;
+ }
+ }
+
+ static String getMotd(String name) {
+ MySQL sql = Core.returnSQL();
+ try {
+ sql.openConnection();
+ PreparedStatement st = sql.getConnection().prepareStatement("SELECT motd FROM Servers WHERE name='" + name + "'");
+ ResultSet rs = st.executeQuery();
+ if(rs.next()) {
+ String motd = rs.getString("motd");
+ sql.closeConnection();
+ return motd;
+ }
+ return null;
+ } catch (SQLException | ClassNotFoundException e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/eu/univento/core/api/server/ServerInfo.java b/src/main/java/eu/univento/core/api/server/ServerInfo.java
new file mode 100644
index 0000000..fc08428
--- /dev/null
+++ b/src/main/java/eu/univento/core/api/server/ServerInfo.java
@@ -0,0 +1,50 @@
+package eu.univento.core.api.server;
+
+import java.util.regex.Pattern;
+
+/**
+ * @author joethei
+ * @version 0.1
+ */
+public class ServerInfo {
+
+ String name;
+ ServerPinger pinger;
+
+ public ServerInfo(String name) {
+ this.name = name;
+ pinger = new ServerPinger(name, 200);
+ pinger.ping();
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public Game getGame() {
+ String[] parts = getMotd().split(Pattern.quote(";"));
+ return Game.valueOf(parts[0]);
+ }
+
+ public String getGameState() {
+ String[] parts = getMotd().split(Pattern.quote(";"));
+ return parts[1];
+ }
+
+ public boolean isOnline() {
+ return pinger.isOnline();
+ }
+
+ public int getOnlinePlayers() {
+ return pinger.getPlayerCount();
+ }
+
+ public int getMaxPlayers() {
+ return pinger.getMaxPlayers();
+ }
+
+ public String getMotd() {
+ return ServerDatabase.getMotd(name);
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/eu/univento/core/api/server/ServerPinger.java b/src/main/java/eu/univento/core/api/server/ServerPinger.java
new file mode 100644
index 0000000..982b4a2
--- /dev/null
+++ b/src/main/java/eu/univento/core/api/server/ServerPinger.java
@@ -0,0 +1,166 @@
+package eu.univento.core.api.server;
+
+import java.io.*;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.net.SocketException;
+import java.nio.charset.Charset;
+
+public class ServerPinger {
+
+ private String address;
+ private int port;
+ private int timeout;
+
+ private boolean online;
+ private int playercount;
+ private int maxplayers;
+ private String motd;
+
+ public ServerPinger(String name, int timeout){
+ this.address = ServerDatabase.getIP(name);
+ this.port = ServerDatabase.getPort(name);
+ this.timeout = timeout;
+ }
+
+ public String getAddress(){
+ return this.address;
+ }
+
+ public void setAddress(String address){
+ this.address = address;
+ }
+
+ public int getPort(){
+ return this.port;
+ }
+
+ public void setPort(int port){
+ this.port = port;
+ }
+
+ public int getTimeout(){
+ return this.timeout;
+ }
+
+ public void setTimeout(int timeout){
+ this.timeout = timeout;
+ }
+
+ public boolean isOnline(){
+ return this.online;
+ }
+
+ private void setOnline(boolean online){
+ this.online = online;
+ }
+
+ public int getPlayerCount(){
+ return this.playercount;
+ }
+
+ private void setPlayerCount(int playercount){
+ this.playercount = playercount;
+ }
+
+ public int getMaxPlayers(){
+ return this.maxplayers;
+ }
+
+ private void setMaxPlayers(int maxplayers){
+ this.maxplayers = maxplayers;
+ }
+
+ public String getMotd(){
+ return this.motd;
+ }
+
+ private void setMotd(String motd){
+ this.motd = motd;
+ }
+
+ public void ping(){
+ try{
+ Socket socket = new Socket();
+ OutputStream outputStream;
+ DataOutputStream dataOutputStream;
+ InputStream inputStream;
+ InputStreamReader inputStreamReader;
+ socket.setSoTimeout(this.timeout);
+ socket.connect(new InetSocketAddress(this.getAddress(), this.getPort()), this.getTimeout());
+ outputStream = socket.getOutputStream();
+ dataOutputStream = new DataOutputStream(outputStream);
+ inputStream = socket.getInputStream();
+ inputStreamReader = new InputStreamReader(inputStream, Charset.forName("UTF-16BE"));
+ dataOutputStream.write(new byte[]{(byte) 0xFE,(byte) 0x01});
+ int packetId = inputStream.read();
+ if(packetId == -1){
+ dataOutputStream.close();
+ outputStream.close();
+ inputStreamReader.close();
+ inputStream.close();
+ socket.close();
+ throw new IOException("Premature end of stream.");
+ }
+ if(packetId != 0xFF){
+ dataOutputStream.close();
+ outputStream.close();
+ inputStreamReader.close();
+ inputStream.close();
+ socket.close();
+ throw new IOException("Invalid packet ID (" + packetId + ").");
+ }
+ int length = inputStreamReader.read();
+ if(length == -1){
+ dataOutputStream.close();
+ outputStream.close();
+ inputStreamReader.close();
+ inputStream.close();
+ socket.close();
+ throw new IOException("Premature end of stream.");
+ }
+ if(length == 0){
+ dataOutputStream.close();
+ outputStream.close();
+ inputStreamReader.close();
+ inputStream.close();
+ socket.close();
+ throw new IOException("Invalid string length.");
+ }
+ char[] chars = new char[length];
+ if(inputStreamReader.read(chars,0,length) != length){
+ dataOutputStream.close();
+ outputStream.close();
+ inputStreamReader.close();
+ inputStream.close();
+ socket.close();
+ throw new IOException("Premature end of stream.");
+ }
+ String string = new String(chars);
+ if(string.startsWith("§")){
+ String[] data = string.split("\0");
+ this.setMotd(data[3]);
+ this.setOnline(true);
+ this.setPlayerCount(Integer.parseInt(data[4]));
+ this.setMaxPlayers(Integer.parseInt(data[5]));
+ }
+ else{
+ String[] data = string.split("§");
+ this.setMotd(data[0]);
+ this.setOnline(true);
+ this.setPlayerCount(Integer.parseInt(data[1]));
+ this.setMaxPlayers(Integer.parseInt(data[2]));
+ }
+ dataOutputStream.close();
+ outputStream.close();
+ inputStreamReader.close();
+ inputStream.close();
+ socket.close();
+ } catch (SocketException exception) {
+ this.setOnline(false);
+ } catch (IOException exception) {
+ this.setOnline(false);
+ }
+ }
+
+}
diff --git a/src/main/java/eu/univento/core/api/server/ServerSettings.java b/src/main/java/eu/univento/core/api/server/ServerSettings.java
new file mode 100644
index 0000000..faf0450
--- /dev/null
+++ b/src/main/java/eu/univento/core/api/server/ServerSettings.java
@@ -0,0 +1,83 @@
+package eu.univento.core.api.server;
+
+import org.bukkit.GameMode;
+
+/**
+ * @author joethei
+ * @version 0.1
+ */
+public class ServerSettings {
+
+ private static boolean build;
+ private static boolean lobby;
+ private static boolean debug;
+ private static boolean mute;
+ private static boolean game;
+ private static Game playedGame;
+ private static GameMode gameMode;
+ private static String gameState;
+
+ public static Game getPlayedGame() {
+ return playedGame;
+ }
+
+ public static void setPlayedGame(Game game) {
+ ServerSettings.playedGame = game;
+ }
+
+ public static GameMode getGameMode() {
+ return gameMode;
+ }
+
+ public static void setGameMode(GameMode gameMode) {
+ ServerSettings.gameMode = gameMode;
+ }
+
+ public static boolean isGame() {
+ return game;
+ }
+
+ public static void setGame(boolean game) {
+ ServerSettings.game = game;
+ }
+
+ public static boolean isBuild() {
+ return build;
+ }
+
+ public static void setBuild(boolean build) {
+ ServerSettings.build = build;
+ }
+
+ public static boolean isLobby() {
+ return lobby;
+ }
+
+ public static void setLobby(boolean lobby) {
+ ServerSettings.lobby = lobby;
+ }
+
+ public static boolean isDebug() {
+ return debug;
+ }
+
+ public static void setDebug(boolean debug) {
+ ServerSettings.debug = debug;
+ }
+
+ public static boolean isMute() {
+ return mute;
+ }
+
+ public static void setMute(boolean mute) {
+ ServerSettings.mute = mute;
+ }
+
+ public static String getGameState() {
+ return gameState;
+ }
+
+ public static void setGameState(String gameState) {
+ ServerSettings.gameState = gameState;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/eu/univento/core/api/server/Servers.java b/src/main/java/eu/univento/core/api/server/Servers.java
new file mode 100644
index 0000000..6a830af
--- /dev/null
+++ b/src/main/java/eu/univento/core/api/server/Servers.java
@@ -0,0 +1,44 @@
+package eu.univento.core.api.server;
+
+import eu.univento.core.Core;
+import org.bukkit.Bukkit;
+import org.bukkit.entity.Player;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+/**
+ * sends player to other bungeecord servers
+ * @author joethei
+ * @version 1.0
+ */
+public class Servers {
+
+
+ /**
+ * sends player to server
+ * @param p player
+ * @param server name of server
+ */
+ public static void connectServer(Player p, String server) {
+ ByteArrayOutputStream b = new ByteArrayOutputStream();
+ DataOutputStream out = new DataOutputStream(b);
+ try {
+ out.writeUTF("Connect");
+ out.writeUTF(server);
+ } catch (IOException el) {
+ el.printStackTrace();
+ }
+ p.sendPluginMessage(Core.getInstance(), "BungeeCord", b.toByteArray());
+ }
+
+ /**
+ * connects all player to server
+ * @param server name of server
+ */
+ public static void connectAllToServer(String server) {
+ for (Player all : Bukkit.getOnlinePlayers())
+ connectServer(all, server);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/eu/univento/core/api/twitch/API.java b/src/main/java/eu/univento/core/api/twitch/API.java
new file mode 100644
index 0000000..de7c26e
--- /dev/null
+++ b/src/main/java/eu/univento/core/api/twitch/API.java
@@ -0,0 +1,25 @@
+package eu.univento.core.api.twitch;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.net.URL;
+
+public class API {
+ public static String readJsonFromUrl(String urlString) throws Exception {
+ BufferedReader reader = null;
+ try {
+ URL url = new URL(urlString);
+ reader = new BufferedReader(new InputStreamReader(url.openStream()));
+ StringBuffer buffer = new StringBuffer();
+ int read;
+ char[] chars = new char[1024];
+ while ((read = reader.read(chars)) != -1)
+ buffer.append(chars, 0, read);
+
+ return buffer.toString();
+ } finally {
+ if (reader != null)
+ reader.close();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/eu/univento/core/api/twitch/Twitch_API.java b/src/main/java/eu/univento/core/api/twitch/Twitch_API.java
new file mode 100644
index 0000000..8691770
--- /dev/null
+++ b/src/main/java/eu/univento/core/api/twitch/Twitch_API.java
@@ -0,0 +1,43 @@
+package eu.univento.core.api.twitch;
+
+
+import com.google.gson.Gson;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonObject;
+
+
+public class Twitch_API {
+public static Gson gson = new Gson();
+
+
+
+
+public static Twitch_Stream getStream(String channelname){
+try{
+String json = API.readJsonFromUrl("http://api.justin.tv/api/stream/list.json?channel="+channelname);
+
+
+Twitch_Stream stream = new Twitch_Stream();
+if(json.equalsIgnoreCase("[]")){
+stream.setOnline(false);
+return stream;
+}
+JsonArray jb = gson.fromJson(json, JsonArray.class);
+JsonObject jo = (JsonObject) jb.get(0);
+stream.setOnline(true);
+stream.load(jo);
+return stream;
+} catch (Exception error){
+error.printStackTrace();
+}
+
+
+
+
+return null;
+
+
+
+
+}
+}
\ No newline at end of file
diff --git a/src/main/java/eu/univento/core/api/twitch/Twitch_Stream.java b/src/main/java/eu/univento/core/api/twitch/Twitch_Stream.java
new file mode 100644
index 0000000..8ce5f5f
--- /dev/null
+++ b/src/main/java/eu/univento/core/api/twitch/Twitch_Stream.java
@@ -0,0 +1,380 @@
+package eu.univento.core.api.twitch;
+
+import com.google.gson.JsonObject;
+
+public class Twitch_Stream {
+ boolean online;
+ int broadcast_part;
+ boolean featured;
+ boolean channel_subscription;
+ String id;
+ String category;
+ String title;
+ int channel_count;
+ int video_height;
+ int site_count;
+ boolean embed_enabled;
+ String up_time;
+ String meta_game;
+ String format;
+ int embed_count;
+ String stream_type;
+ boolean abuse_reported;
+ int video_width;
+ String geo;
+ String name;
+ String language;
+ int stream_count;
+ double video_bitrate;
+ String broadcaster;
+ int channel_view_count;
+ String username;
+ String status;
+ String channel_url;
+ boolean producer;
+ String subcategory_title;
+ String screen_cap_url_large;
+ String screen_cap_url_small;
+ String screen_cap_url_medium;
+ String screen_cap_url_huge;
+ String timezone;
+ String category_title;
+ int views_count;
+
+ public void load(JsonObject job) {
+ setBroadcast_part(job.get("broadcast_part").getAsInt());
+ setFeatured(job.get("featured").getAsBoolean());
+ setChannel_subscription(job.get("channel_subscription").getAsBoolean());
+ setId(job.get("id").getAsString());
+ setCategory(job.get("category").getAsString());
+ setTitle(job.get("title").getAsString());
+ setChannel_count(job.get("channel_count").getAsInt());
+ setVideo_height(job.get("video_height").getAsInt());
+ setSite_count(job.get("site_count").getAsInt());
+ setEmbed_enabled(job.get("embed_enabled").getAsBoolean());
+ setUp_time(job.get("up_time").getAsString());
+ setMeta_game(job.get("meta_game").getAsString());
+ setFormat(job.get("format").getAsString());
+ setEmbed_count(job.get("embed_count").getAsInt());
+ setStream_type(job.get("stream_type").getAsString());
+ setAbuse_reported(job.get("abuse_reported").getAsBoolean());
+ setVideo_width(job.get("video_width").getAsInt());
+ setGeo(job.get("geo").getAsString());
+ setName(job.get("name").getAsString());
+ setLanguage(job.get("language").getAsString());
+ setStream_count(job.get("stream_count").getAsInt());
+ setVideo_bitrate(job.get("video_bitrate").getAsDouble());
+ setBroadcaster(job.get("broadcaster").getAsString());
+ setChannel_view_count(job.get("channel_view_count").getAsInt());
+
+ setUsername(job.get("channel").getAsJsonObject().get("login").getAsString());
+ setTitle(job.get("channel").getAsJsonObject().get("status").getAsString());
+ setChannel_url(job.get("channel").getAsJsonObject().get("channel_url").getAsString());
+ setProducer(job.get("channel").getAsJsonObject().get("producer").getAsBoolean());
+
+ setSubcategory_title(job.get("channel").getAsJsonObject().get("subcategory_title").getAsString());
+ setScreen_cap_url_large(job.get("channel").getAsJsonObject().get("screen_cap_url_large").getAsString());
+ setScreen_cap_url_small(job.get("channel").getAsJsonObject().get("screen_cap_url_small").getAsString());
+ setScreen_cap_url_medium(job.get("channel").getAsJsonObject().get("screen_cap_url_medium").getAsString());
+ setScreen_cap_url_huge(job.get("channel").getAsJsonObject().get("screen_cap_url_huge").getAsString());
+ setTimezone(job.get("channel").getAsJsonObject().get("timezone").getAsString());
+ setCategory_title(job.get("channel").getAsJsonObject().get("category_title").getAsString());
+ setViews_count(job.get("channel").getAsJsonObject().get("views_count").getAsInt());
+ }
+
+ public boolean isOnline() {
+ return this.online;
+ }
+
+ public void setOnline(boolean online) {
+ this.online = online;
+ }
+
+ public int getBroadcast_part() {
+ return this.broadcast_part;
+ }
+
+ public void setBroadcast_part(int broadcast_part) {
+ this.broadcast_part = broadcast_part;
+ }
+
+ public boolean isFeatured() {
+ return this.featured;
+ }
+
+ public void setFeatured(boolean featured) {
+ this.featured = featured;
+ }
+
+ public boolean isChannel_subscription() {
+ return this.channel_subscription;
+ }
+
+ public void setChannel_subscription(boolean channel_subscription) {
+ this.channel_subscription = channel_subscription;
+ }
+
+ public String getId() {
+ return this.id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getCategory() {
+ return this.category;
+ }
+
+ public void setCategory(String category) {
+ this.category = category;
+ }
+
+ public String getTitle() {
+ return this.title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public int getChannel_count() {
+ return this.channel_count;
+ }
+
+ public void setChannel_count(int channel_count) {
+ this.channel_count = channel_count;
+ }
+
+ public int getVideo_height() {
+ return this.video_height;
+ }
+
+ public void setVideo_height(int video_height) {
+ this.video_height = video_height;
+ }
+
+ public int getSite_count() {
+ return this.site_count;
+ }
+
+ public void setSite_count(int site_count) {
+ this.site_count = site_count;
+ }
+
+ public boolean isEmbed_enabled() {
+ return this.embed_enabled;
+ }
+
+ public void setEmbed_enabled(boolean embed_enabled) {
+ this.embed_enabled = embed_enabled;
+ }
+
+ public String getUp_time() {
+ return this.up_time;
+ }
+
+ public void setUp_time(String up_time) {
+ this.up_time = up_time;
+ }
+
+ public String getMeta_game() {
+ return this.meta_game;
+ }
+
+ public void setMeta_game(String meta_game) {
+ this.meta_game = meta_game;
+ }
+
+ public String getFormat() {
+ return this.format;
+ }
+
+ public void setFormat(String format) {
+ this.format = format;
+ }
+
+ public int getEmbed_count() {
+ return this.embed_count;
+ }
+
+ public void setEmbed_count(int embed_count) {
+ this.embed_count = embed_count;
+ }
+
+ public String getStream_type() {
+ return this.stream_type;
+ }
+
+ public void setStream_type(String stream_type) {
+ this.stream_type = stream_type;
+ }
+
+ public boolean isAbuse_reported() {
+ return this.abuse_reported;
+ }
+
+ public void setAbuse_reported(boolean abuse_reported) {
+ this.abuse_reported = abuse_reported;
+ }
+
+ public int getVideo_width() {
+ return this.video_width;
+ }
+
+ public void setVideo_width(int video_width) {
+ this.video_width = video_width;
+ }
+
+ public String getGeo() {
+ return this.geo;
+ }
+
+ public void setGeo(String geo) {
+ this.geo = geo;
+ }
+
+ public String getName() {
+ return this.name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getLanguage() {
+ return this.language;
+ }
+
+ public void setLanguage(String language) {
+ this.language = language;
+ }
+
+ public int getStream_count() {
+ return this.stream_count;
+ }
+
+ public void setStream_count(int stream_count) {
+ this.stream_count = stream_count;
+ }
+
+ public double getVideo_bitrate() {
+ return this.video_bitrate;
+ }
+
+ public void setVideo_bitrate(double video_bitrate) {
+ this.video_bitrate = video_bitrate;
+ }
+
+ public String getBroadcaster() {
+ return this.broadcaster;
+ }
+
+ public void setBroadcaster(String broadcaster) {
+ this.broadcaster = broadcaster;
+ }
+
+ public int getChannel_view_count() {
+ return this.channel_view_count;
+ }
+
+ public void setChannel_view_count(int channel_view_count) {
+ this.channel_view_count = channel_view_count;
+ }
+
+ public String getUsername() {
+ return this.username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getStatus() {
+ return this.status;
+ }
+
+ public void setStatus(String status) {
+ this.status = status;
+ }
+
+ public String getChannel_url() {
+ return this.channel_url;
+ }
+
+ public void setChannel_url(String channel_url) {
+ this.channel_url = channel_url;
+ }
+
+ public boolean isProducer() {
+ return this.producer;
+ }
+
+ public void setProducer(boolean producer) {
+ this.producer = producer;
+ }
+
+ public String getSubcategory_title() {
+ return this.subcategory_title;
+ }
+
+ public void setSubcategory_title(String subcategory_title) {
+ this.subcategory_title = subcategory_title;
+ }
+
+ public String getScreen_cap_url_large() {
+ return this.screen_cap_url_large;
+ }
+
+ public void setScreen_cap_url_large(String screen_cap_url_large) {
+ this.screen_cap_url_large = screen_cap_url_large;
+ }
+
+ public String getScreen_cap_url_small() {
+ return this.screen_cap_url_small;
+ }
+
+ public void setScreen_cap_url_small(String screen_cap_url_small) {
+ this.screen_cap_url_small = screen_cap_url_small;
+ }
+
+ public String getScreen_cap_url_medium() {
+ return this.screen_cap_url_medium;
+ }
+
+ public void setScreen_cap_url_medium(String screen_cap_url_medium) {
+ this.screen_cap_url_medium = screen_cap_url_medium;
+ }
+
+ public String getScreen_cap_url_huge() {
+ return this.screen_cap_url_huge;
+ }
+
+ public void setScreen_cap_url_huge(String screen_cap_url_huge) {
+ this.screen_cap_url_huge = screen_cap_url_huge;
+ }
+
+ public String getTimezone() {
+ return this.timezone;
+ }
+
+ public void setTimezone(String timezone) {
+ this.timezone = timezone;
+ }
+
+ public String getCategory_title() {
+ return this.category_title;
+ }
+
+ public void setCategory_title(String category_title) {
+ this.category_title = category_title;
+ }
+
+ public int getViews_count() {
+ return this.views_count;
+ }
+
+ public void setViews_count(int views_count) {
+ this.views_count = views_count;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/eu/univento/core/api/utils/Direction.java b/src/main/java/eu/univento/core/api/utils/Direction.java
new file mode 100644
index 0000000..3184740
--- /dev/null
+++ b/src/main/java/eu/univento/core/api/utils/Direction.java
@@ -0,0 +1,37 @@
+package eu.univento.core.api.utils;
+
+public enum Direction
+{
+ NORTH(1, 0),
+ SOUTH(-1, 0),
+ EAST(0, 1),
+ WEST(0, -1),
+ NORTHEAST(1, 1),
+ SOUTHEAST(-1, 1),
+ NORTHWEST(1, -1),
+ SOUTHWEST(-1, -1);
+
+ private int x;
+ private int z;
+
+ private Direction(int x, int z) { this.x = x;
+ this.z = z; }
+
+ public int getX()
+ {
+ return this.x;
+ }
+
+ public int getZ() {
+ return this.z;
+ }
+
+ public static Direction getDirection(String direction) {
+ for (Direction dir : values())
+ {
+ if (dir.name().equalsIgnoreCase(direction))
+ return dir;
+ }
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/eu/univento/core/api/utils/GameProfileBuilder.java b/src/main/java/eu/univento/core/api/utils/GameProfileBuilder.java
new file mode 100644
index 0000000..006ddbd
--- /dev/null
+++ b/src/main/java/eu/univento/core/api/utils/GameProfileBuilder.java
@@ -0,0 +1,171 @@
+package eu.univento.core.api.utils;
+
+import com.google.gson.*;
+import com.mojang.authlib.GameProfile;
+import com.mojang.authlib.properties.Property;
+import com.mojang.authlib.properties.PropertyMap;
+import com.mojang.util.UUIDTypeAdapter;
+import org.yaml.snakeyaml.external.biz.base64Coder.Base64Coder;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.lang.reflect.Type;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.UUID;
+
+/**
+ * @author Jofkos
+ */
+public class GameProfileBuilder {
+
+ private static final String SERVICE_URL = "https://sessionserver.mojang.com/session/minecraft/profile/%s?unsigned=false";
+ private static final String JSON_SKIN = "{\"timestamp\":%d,\"profileId\":\"%s\",\"profileName\":\"%s\",\"isPublic\":true,\"textures\":{\"SKIN\":{\"url\":\"%s\"}}}";
+ private static final String JSON_CAPE = "{\"timestamp\":%d,\"profileId\":\"%s\",\"profileName\":\"%s\",\"isPublic\":true,\"textures\":{\"SKIN\":{\"url\":\"%s\"},\"CAPE\":{\"url\":\"%s\"}}}";
+
+ private static Gson gson = new GsonBuilder().disableHtmlEscaping().registerTypeAdapter(UUID.class, new UUIDTypeAdapter()).registerTypeAdapter(GameProfile.class, new GameProfileSerializer()).registerTypeAdapter(PropertyMap.class, new PropertyMap.Serializer()).create();
+
+ private static HashMap cache = new HashMap<>();
+
+ private static long cacheTime = -1;
+
+ /**
+ * Don't run in main thread!
+ *
+ * Fetches the GameProfile from the Mojang servers
+ *
+ * @param uuid The player uuid
+ * @return The GameProfile
+ * @throws IOException If something wents wrong while fetching
+ * @see GameProfile
+ */
+ public static GameProfile fetch(UUID uuid) throws IOException {
+ return fetch(uuid, false);
+ }
+
+ /**
+ * Don't run in main thread!
+ *
+ * Fetches the GameProfile from the Mojang servers
+ * @param uuid The player uuid
+ * @param forceNew If true the cache is ignored
+ * @return The GameProfile
+ * @throws IOException If something wents wrong while fetching
+ * @see GameProfile
+ */
+ public static GameProfile fetch(UUID uuid, boolean forceNew) throws IOException {
+ if (!forceNew && cache.containsKey(uuid) && cache.get(uuid).isValid()) {
+ return cache.get(uuid).profile;
+ } else {
+ HttpURLConnection connection = (HttpURLConnection) new URL(String.format(SERVICE_URL, UUIDTypeAdapter.fromUUID(uuid))).openConnection();
+ connection.setReadTimeout(5000);
+
+ if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
+ String json = new BufferedReader(new InputStreamReader(connection.getInputStream())).readLine();
+
+ GameProfile result = gson.fromJson(json, GameProfile.class);
+ cache.put(uuid, new CachedProfile(result));
+ return result;
+ } else {
+ if (!forceNew && cache.containsKey(uuid)) {
+ return cache.get(uuid).profile;
+ }
+ JsonObject error = (JsonObject) new JsonParser().parse(new BufferedReader(new InputStreamReader(connection.getErrorStream())).readLine());
+ throw new IOException(error.get("error").getAsString() + ": " + error.get("errorMessage").getAsString());
+ }
+ }
+ }
+
+ /**
+ * Builds a GameProfile for the specified args
+ *
+ * @param uuid The uuid
+ * @param name The name
+ * @param skin The url from the skin image
+ * @return A GameProfile built from the arguments
+ * @see GameProfile
+ */
+ public static GameProfile getProfile(UUID uuid, String name, String skin) {
+ return getProfile(uuid, name, skin, null);
+ }
+
+ /**
+ * Builds a GameProfile for the specified args
+ *
+ * @param uuid The uuid
+ * @param name The name
+ * @param skinUrl Url from the skin image
+ * @param capeUrl Url from the cape image
+ * @return A GameProfile built from the arguments
+ * @see GameProfile
+ */
+ public static GameProfile getProfile(UUID uuid, String name, String skinUrl, String capeUrl) {
+ GameProfile profile = new GameProfile(uuid, name);
+ boolean cape = capeUrl != null && !capeUrl.isEmpty();
+
+ List