diff --git a/.gitignore b/.gitignore index ae3c172..a1050df 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ /bin/ +/target +Core.iml \ No newline at end of file diff --git a/Core.iml b/Core.iml index bf8bd26..b23cecb 100644 --- a/Core.iml +++ b/Core.iml @@ -6,6 +6,7 @@ + @@ -23,18 +24,24 @@ + + - + + + - + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index c5d432d..4deeaea 100644 --- a/pom.xml +++ b/pom.xml @@ -10,102 +10,40 @@ jar Univento.eu Core System - https://development.univento.eu/Plugins/Core - - Plugin used on all Spigot servers to add basic functions and APIs. - - - - - joethei - Johannes Theiner - info@joethei.de - Europe/Berlin - - architect - project leader - senior developer - - - https://de.gravatar.com/userimage/65052389/84435a829d76e6b6c48d67cdd463c6ab.png?size=50 - - - - - - - Daniel Planötscher - planiel@univento.eu - Europe/Berlin - - designer - - - https://pbs.twimg.com/profile_images/706847659416494080/in1AJ9rc.jpg - - - - - 2015 - - univento - http://univento.eu - - - org.apache.maven.plugins - maven-compiler-plugin - - 1.8 - 1.8 - - - - org.apache.maven.plugins - maven-assembly-plugin - 2.2.1 - - - - eu.univento.core.Core - - - - jar-with-dependencies - - - - - make-assembly - package - - single - - - - - - org.apache.maven.plugins - maven-site-plugin - 3.4 - - en - - - - org.apache.maven.plugins - maven-javadoc-plugin - 2.10.4 - - - attach-javadocs - - javadoc - - - + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-assembly-plugin + 2.2.1 + + + + eu.univento.core.Core + + + + jar-with-dependencies + + + + + make-assembly + package + + single + + + @@ -138,7 +76,7 @@ eu.univento - Commons + CloudCommons 1.0-SNAPSHOT diff --git a/src/main/java/eu/univento/core/Core.java b/src/main/java/eu/univento/core/Core.java index 3a7d5c0..76439cc 100644 --- a/src/main/java/eu/univento/core/Core.java +++ b/src/main/java/eu/univento/core/Core.java @@ -6,6 +6,7 @@ import eu.univento.core.antihack.AntiHack; import eu.univento.core.api.Config; import eu.univento.core.api.effects.Blackscreen; import eu.univento.core.api.events.MoveEventFilter; +import eu.univento.core.api.items.InventoryManager; import eu.univento.core.api.player.CustomPlayer; import eu.univento.core.api.server.NetworkData; import eu.univento.core.api.server.ServerSettings; @@ -150,10 +151,7 @@ public class Core extends JavaPlugin implements NettyInjection.PacketHandler { pm.registerEvents(new WeaponEvents(), this); pm.registerEvents(new SpectatorEvents(), this); pm.registerEvents(new MoveEventFilter(getServer()), this); - - if (ServerSettings.isBuild()) { - new Build(this, "build", "enables/disables the build mode", "b"); - } + pm.registerEvents(new InventoryManager(), this); if (ServerSettings.isGame()) { new Fix(this, "fix", "fix your self or other players"); diff --git a/src/main/java/eu/univento/core/antihack/AntiHack.java b/src/main/java/eu/univento/core/antihack/AntiHack.java index 12e00a2..646cf80 100644 --- a/src/main/java/eu/univento/core/antihack/AntiHack.java +++ b/src/main/java/eu/univento/core/antihack/AntiHack.java @@ -20,8 +20,7 @@ public class AntiHack implements Listener{ public static void registerListeners() { PluginManager pm = Bukkit.getPluginManager(); pm.registerEvents(new AntiHack(), Core.getInstance()); - pm.registerEvents(new Glide(), Core.getInstance()); - pm.registerEvents(new Fly(), Core.getInstance()); + pm.registerEvents(new Movement(), Core.getInstance()); pm.registerEvents(new AutoClicker(), Core.getInstance()); pm.registerEvents(new Criticals(), Core.getInstance()); pm.registerEvents(new Reach(), Core.getInstance()); @@ -31,13 +30,15 @@ public class AntiHack implements Listener{ pm.registerEvents(new FastPlace(), Core.getInstance()); //pm.registerEvents(new KillAura(), Core.getInstance()); - for(Map.Entry entry : AutoClicker.clicks.entrySet()) { - if(entry.getValue() > 16) { - //TODO: change to real warn reason - entry.getKey().warn(WarnReason.SPAM, null, "https://players.univento.eu/" + entry.getKey().getUniqueId().toString() + "/hacks"); + Bukkit.getScheduler().scheduleSyncRepeatingTask(Core.getInstance(), () -> { + for(Map.Entry entry : AutoClicker.clicks.entrySet()) { + if(entry.getValue() > 16) { + //TODO: change to real warn reason + entry.getKey().warn(WarnReason.SPAM, null, "https://players.univento.eu/" + entry.getKey().getUniqueId().toString() + "/hacks"); + } + AutoClicker.clicks.remove(entry.getKey()); } - AutoClicker.clicks.remove(entry.getKey()); - } + }, 20L, 20L); } @EventHandler diff --git a/src/main/java/eu/univento/core/antihack/modules/Fly.java b/src/main/java/eu/univento/core/antihack/modules/Fly.java deleted file mode 100644 index caf47f9..0000000 --- a/src/main/java/eu/univento/core/antihack/modules/Fly.java +++ /dev/null @@ -1,18 +0,0 @@ -package eu.univento.core.antihack.modules; - -import eu.univento.core.api.player.CustomPlayer; -import org.bukkit.GameMode; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.player.PlayerMoveEvent; - -public class Fly implements Listener{ - - @EventHandler - public void onFly(PlayerMoveEvent e) { - CustomPlayer p = CustomPlayer.getPlayer(e.getPlayer()); - if(p.getGameMode() != GameMode.CREATIVE && e.getTo().getY() > e.getFrom().getY() + 1.5) { - //p.warn(Hack.FLY); - } - } -} \ No newline at end of file diff --git a/src/main/java/eu/univento/core/antihack/modules/Glide.java b/src/main/java/eu/univento/core/antihack/modules/Glide.java deleted file mode 100644 index 4d53fd7..0000000 --- a/src/main/java/eu/univento/core/antihack/modules/Glide.java +++ /dev/null @@ -1,18 +0,0 @@ -package eu.univento.core.antihack.modules; - -import eu.univento.core.api.player.CustomPlayer; -import org.bukkit.Material; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.player.PlayerMoveEvent; - -public class Glide implements Listener{ - - @EventHandler - public void onGlide(PlayerMoveEvent e) { - CustomPlayer p = CustomPlayer.getPlayer(e.getPlayer()); - if(e.getTo().getY() - e.getFrom().getY() == -0.125 && e.getTo().clone().subtract(0.0, 1.0, 0.0).getBlock().getType().equals(Material.AIR)) { - //p.warn(Hack.GLIDE); - } - } -} \ No newline at end of file diff --git a/src/main/java/eu/univento/core/antihack/modules/Movement.java b/src/main/java/eu/univento/core/antihack/modules/Movement.java new file mode 100644 index 0000000..eaf51a7 --- /dev/null +++ b/src/main/java/eu/univento/core/antihack/modules/Movement.java @@ -0,0 +1,46 @@ +package eu.univento.core.antihack.modules; + +import eu.univento.core.api.player.CustomPlayer; +import org.bukkit.GameMode; +import org.bukkit.Material; +import org.bukkit.block.BlockFace; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerMoveEvent; + +public class Movement implements Listener{ + + @EventHandler + public void onMove(PlayerMoveEvent e) { + CustomPlayer p = CustomPlayer.getPlayer(e.getPlayer()); + if(p.getGameMode() == GameMode.CREATIVE) return; + if(p.getVehicle() != null) return; + if(p.getAllowFlight()) return; + double distance = e.getTo().distance(e.getFrom()); + if(p.getFallDistance() == 0.0F && p.getLocation().getBlock().getRelative(BlockFace.UP).getType() == Material.AIR) { + if(distance > 0.6D && !p.isOnGround()) { + e.setCancelled(true); + p.teleport(e.getFrom()); + p.sendMessage("Du hast Fly an"); + } + } + if(distance > 0.2D && distance < 0.29D) { + if(p.getLocation().getBlock().getRelative(BlockFace.DOWN).getType() == Material.WATER) return; + if(p.getLocation().getBlock().getRelative(BlockFace.DOWN).isLiquid()) { + e.setCancelled(true); + p.teleport(e.getFrom()); + p.sendMessage("Du hast Jesus an"); + } + } + if(p.getFallDistance() == 0.0F && distance > 0.79D && p.isOnGround()) { + e.setCancelled(true); + p.setHealth(0.0D); + p.sendMessage("Du hast NoFall an"); + } + if(e.getTo().getY() - e.getFrom().getY() == -0.125 && e.getTo().clone().subtract(0.0, 1.0, 0.0).getBlock().getType().equals(Material.AIR)) { + e.setCancelled(true); + p.teleport(e.getFrom()); + p.sendMessage("Du hast Glide an"); + } + } +} \ No newline at end of file diff --git a/src/main/java/eu/univento/core/antihack/modules/NoSlowDown.java b/src/main/java/eu/univento/core/antihack/modules/NoSlowDown.java index bf08d31..dc0c291 100644 --- a/src/main/java/eu/univento/core/antihack/modules/NoSlowDown.java +++ b/src/main/java/eu/univento/core/antihack/modules/NoSlowDown.java @@ -14,7 +14,10 @@ public class NoSlowDown implements Listener{ if(e.getEntity() instanceof Player) { CustomPlayer p = CustomPlayer.getPlayer((Player) e.getEntity()); if(p.isSprinting()) { - //p.warn(Hack.NOSLOWDOWN); + e.setCancelled(true); + p.damage(2.0D); + p.setArrowsInBody(p.getArrowsInBody() + 50); + p.sendMessage("Du hast NoSlowDown an"); } } } @@ -24,7 +27,9 @@ public class NoSlowDown implements Listener{ if(e.getEntity() instanceof Player) { CustomPlayer p = CustomPlayer.getPlayer((Player) e.getEntity()); if(e.getFoodLevel() > p.getFoodLevel() && p.isSprinting()) { - //p.warn(Hack.NOSLOWDOWN); + e.setCancelled(true); + e.setFoodLevel(0); + p.sendMessage("Du hast NoSlowDown an"); } } } diff --git a/src/main/java/eu/univento/core/api/entity/ArmorStandAnimator.java b/src/main/java/eu/univento/core/api/entity/ArmorStandAnimator.java new file mode 100644 index 0000000..90feac1 --- /dev/null +++ b/src/main/java/eu/univento/core/api/entity/ArmorStandAnimator.java @@ -0,0 +1,418 @@ +package eu.univento.core.api.entity; + +import org.bukkit.Location; +import org.bukkit.entity.ArmorStand; +import org.bukkit.util.EulerAngle; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +/** + * The original thread that this code belongs to can be found here: + * https://www.spigotmc.org/threads/armor-stand-animator-class.152863/ + * MIT License + + Copyright (c) 2016 Bram Stout + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + * @author Bram + * + */ +public class ArmorStandAnimator { + + /** + * This is a map containing the already loaded frames. This way we don't have to parse the same animation over and over. + */ + private static Map animCache = new HashMap<>(); + /** + * This is a list with all the animator instances. This makes it easy to update all the instances at one. + */ + private static Set animators = new HashSet<>(); + + /** This void updates all the animator instances at once */ + public static void updateAll() { + for (ArmorStandAnimator ani : animators) { + ani.update(); + } + } + + /** Returns all the animator instances */ + public static Set getAnimators() { + return animators; + } + + /** Clears the animation cache in case you want to update an animation */ + public static void clearCache() { + animCache.clear(); + } + + /** The armor stand to animate */ + private ArmorStand armorStand; + /** The amount of frames this animation has */ + private int length; + /** All the frames of the animation */ + private Frame[] frames; + /** Says when the animation is paused */ + private boolean paused = false; + /** The current frame we're on */ + private int currentFrame; + /** The start location of the animation */ + private Location startLocation; + /** If this is true. The animator is going to guess the frames that aren't specified */ + private boolean interpolate = false; + + /** + * Constructor of the animator. Takes in the path to the file with the animation and the armor stand to animate. + * + * @param aniFile + * @param armorStand + */ + public ArmorStandAnimator(File aniFile, ArmorStand armorStand) { + // set all the stuff + this.armorStand = armorStand; + startLocation = armorStand.getLocation(); + // checks if the file has been loaded before. If so return the cached version + if (animCache.containsKey(aniFile.getAbsolutePath())) { + frames = animCache.get(aniFile.getAbsolutePath()); + } else { + // File has not been loaded before so load it. + BufferedReader br = null; + try { + br = new BufferedReader(new FileReader(aniFile)); + String line = ""; + // create the current frame variable + Frame currentFrame = null; + while ((line = br.readLine()) != null) { + // set the length + if (line.startsWith("length")) { + length = (int) Float.parseFloat(line.split(" ")[1]); + frames = new Frame[length]; + } + // sets the current frame + else if (line.startsWith("frame")) { + if (currentFrame != null) { + frames[currentFrame.frameID] = currentFrame; + } + int frameID = Integer.parseInt(line.split(" ")[1]); + currentFrame = new Frame(); + currentFrame.frameID = frameID; + } + // check if we need to interpolate + else if (line.contains("interpolate")) { + interpolate = true; + } + // sets the position and rotation or the main armor stand + else if (line.contains("Armorstand_Position")) { + currentFrame.x = Float.parseFloat(line.split(" ")[1]); + currentFrame.y = Float.parseFloat(line.split(" ")[2]); + currentFrame.z = Float.parseFloat(line.split(" ")[3]); + currentFrame.r = Float.parseFloat(line.split(" ")[4]); + } + // sets the rotation for the middle + else if (line.contains("Armorstand_Middle")) { + float x = (float) Math.toRadians(Float.parseFloat(line.split(" ")[1])); + float y = (float) Math.toRadians(Float.parseFloat(line.split(" ")[2])); + float z = (float) Math.toRadians(Float.parseFloat(line.split(" ")[3])); + currentFrame.middle = new EulerAngle(x, y, z); + } + // sets the rotation for the right leg + else if (line.contains("Armorstand_Right_Leg")) { + float x = (float) Math.toRadians(Float.parseFloat(line.split(" ")[1])); + float y = (float) Math.toRadians(Float.parseFloat(line.split(" ")[2])); + float z = (float) Math.toRadians(Float.parseFloat(line.split(" ")[3])); + currentFrame.rightLeg = new EulerAngle(x, y, z); + } + // sets the rotation for the left leg + else if (line.contains("Armorstand_Left_Leg")) { + float x = (float) Math.toRadians(Float.parseFloat(line.split(" ")[1])); + float y = (float) Math.toRadians(Float.parseFloat(line.split(" ")[2])); + float z = (float) Math.toRadians(Float.parseFloat(line.split(" ")[3])); + currentFrame.leftLeg = new EulerAngle(x, y, z); + } + // sets the rotation for the left arm + else if (line.contains("Armorstand_Left_Arm")) { + float x = (float) Math.toRadians(Float.parseFloat(line.split(" ")[1])); + float y = (float) Math.toRadians(Float.parseFloat(line.split(" ")[2])); + float z = (float) Math.toRadians(Float.parseFloat(line.split(" ")[3])); + currentFrame.leftArm = new EulerAngle(x, y, z); + } + // sets the rotation for the right arm + else if (line.contains("Armorstand_Right_Arm")) { + float x = (float) Math.toRadians(Float.parseFloat(line.split(" ")[1])); + float y = (float) Math.toRadians(Float.parseFloat(line.split(" ")[2])); + float z = (float) Math.toRadians(Float.parseFloat(line.split(" ")[3])); + currentFrame.rightArm = new EulerAngle(x, y, z); + } + // sets the rotation for the head + else if (line.contains("Armorstand_Head")) { + float x = (float) Math.toRadians(Float.parseFloat(line.split(" ")[1])); + float y = (float) Math.toRadians(Float.parseFloat(line.split(" ")[2])); + float z = (float) Math.toRadians(Float.parseFloat(line.split(" ")[3])); + currentFrame.head = new EulerAngle(x, y, z); + } + } + if (currentFrame != null) { + frames[currentFrame.frameID] = currentFrame; + } + } catch (Exception ex) { + ex.printStackTrace(); + } finally { + // make sure to close the stream! + if (br != null) { + try { + br.close(); + } catch (Exception ex) { + ex.printStackTrace(); + } + } + } + // add the animation to the cache, else adding the whole cache thing has no point. + animCache.put(aniFile.getAbsolutePath(), frames); + } + // register this instance of the animator + animators.add(this); + } + + /** + * This method removes this instance from the animator instances list. When you don't want to use this instance any more, you can call this method. + */ + public void remove() { + animators.remove(this); + } + + /** Pauses the animation */ + public void pause() { + paused = true; + } + + /** + * Pauses the animation and sets the current frame to 0. It also updates the animation one more time to set the armor stand to the first frame. + */ + public void stop() { + // set the current frame to 0 and update the frame and set it to 0 again + currentFrame = 0; + update(); + currentFrame = 0; + paused = true; + } + + /** Plays the animation */ + public void play() { + paused = false; + } + + /** Updates the animation and goes to the next frame */ + public void update() { + // make sure that the animation isn't paused + if (!paused) { + // makes sure that the frame is in bounds + if (currentFrame >= (length - 1) || currentFrame < 0) { + currentFrame = 0; + } + // get the frame + Frame f = frames[currentFrame]; + //checks if we need to interpolate. If so interpolate. + if(interpolate) { + if(f == null) { + f = interpolate(currentFrame); + } + } + // make sure it's not null + if (f != null) { + // get the new location + Location newLoc = startLocation.clone().add(f.x, f.y, f.z); + newLoc.setYaw(f.r + newLoc.getYaw()); + // set all the values + armorStand.teleport(newLoc); + armorStand.setBodyPose(f.middle); + armorStand.setLeftLegPose(f.leftLeg); + armorStand.setRightLegPose(f.rightLeg); + armorStand.setLeftArmPose(f.leftArm); + armorStand.setRightArmPose(f.rightArm); + armorStand.setHeadPose(f.head); + } + // go one frame higher + currentFrame++; + } + } + + /** Returns the current frame */ + public int getCurrentFrame() { + return currentFrame; + } + + /** Sets the current frame */ + public void setCurrentFrame(int currentFrame) { + this.currentFrame = currentFrame; + } + + /** Returns the armor stand this instance animates */ + public ArmorStand getArmorStand() { + return armorStand; + } + + /** Returns the amount of frame this animation has */ + public int getLength() { + return length; + } + + /** Returns the list of frames */ + public Frame[] getFrames() { + return frames; + } + + /** Returns if the animation is paused */ + public boolean isPaused() { + return paused; + } + + /** Gets the start location */ + public Location getStartLocation() { + return startLocation; + } + + /** + * Sets the start location. If you want to teleport the armor stand this is the recommended function + * + * @param location + */ + public void setStartLocation(Location location) { + startLocation = location; + } + + /** Returns interpolate */ + public boolean isInterpolated() { + return interpolate; + } + + /** Sets interpolate */ + public void setInterpolated(boolean interpolate) { + this.interpolate = interpolate; + } + + /**Returns an interpolated frame*/ + private Frame interpolate(int frameID) { + //get the minimum and maximum frames that are the closest + Frame minFrame = null; + for (int i = frameID; i >= 0; i--) { + if (frames[i] != null) { + minFrame = frames[i]; + break; + } + } + Frame maxFrame = null; + for (int i = frameID; i < frames.length; i++) { + if (frames[i] != null) { + maxFrame = frames[i]; + break; + } + } + //make sure that those frame weren't the last one + Frame res = null; + + if(maxFrame == null || minFrame == null) { + if(maxFrame == null && minFrame != null) { + return minFrame; + } + if(minFrame == null && maxFrame != null) { + return maxFrame; + } + res = new Frame(); + res.frameID = frameID; + return res; + } + //create the frame and interpolate + res = new Frame(); + res.frameID = frameID; + + //this part calculates the distance the current frame is from the minimum and maximum frame and this allows for an easy linear interpolation + float Dmin = frameID - minFrame.frameID; + float D = maxFrame.frameID - minFrame.frameID; + float D0 = Dmin / D; + + res = minFrame.mult(1 - D0, frameID).add(maxFrame.mult(D0, frameID), frameID); + + return res; + } + + /** + * The frame class. This class holds all the information of one frame. + */ + public static class Frame { + /**The Frame ID*/ + int frameID; + /**the location and rotation*/ + float x, y, z, r; + /**The rotation of the body parts*/ + EulerAngle middle; + EulerAngle rightLeg; + EulerAngle leftLeg; + EulerAngle rightArm; + EulerAngle leftArm; + EulerAngle head; + /**This multiplies every value with another value. + * Used for interpolation + * @param a + * @param frameID + * @return + */ + public Frame mult(float a, int frameID) { + Frame f = new Frame(); + f.frameID = frameID; + f.x = f.x * a; + f.y = f.y * a; + f.z = f.z * a; + f.r = f.r * a; + f.middle = new EulerAngle(middle.getX() * a, middle.getY() * a, middle.getZ() * a); + f.rightLeg = new EulerAngle(rightLeg.getX() * a, rightLeg.getY() * a, rightLeg.getZ() * a); + f.leftLeg = new EulerAngle(leftLeg.getX() * a, leftLeg.getY() * a, leftLeg.getZ() * a); + f.rightArm = new EulerAngle(rightArm.getX() * a, rightArm.getY() * a, rightArm.getZ() * a); + f.leftArm = new EulerAngle(leftArm.getX() * a, leftArm.getY() * a, leftArm.getZ() * a); + f.head = new EulerAngle(head.getX() * a, head.getY() * a, head.getZ() * a); + return f; + } + /**This adds a value to every value. + * Used for interpolation + * @param a + * @param frameID + * @return + */ + public Frame add(Frame a, int frameID) { + Frame f = new Frame(); + f.frameID = frameID; + f.x = f.x + a.x; + f.y = f.y + a.y; + f.z = f.z + a.z; + f.r = f.r + a.r; + f.middle = new EulerAngle(middle.getX() + a.middle.getX(), middle.getY() + a.middle.getY(), middle.getZ() + a.middle.getZ()); + f.rightLeg = new EulerAngle(rightLeg.getX() + a.rightLeg.getX(), rightLeg.getY() + a.rightLeg.getY(), rightLeg.getZ() + a.rightLeg.getZ()); + f.leftLeg = new EulerAngle(leftLeg.getX() + a.leftLeg.getX(), leftLeg.getY() + a.leftLeg.getY(), leftLeg.getZ() + a.leftLeg.getZ()); + f.rightArm = new EulerAngle(rightArm.getX() + a.rightArm.getX(), rightArm.getY() + a.rightArm.getY(), rightArm.getZ() + a.rightArm.getZ()); + f.leftArm = new EulerAngle(leftArm.getX() + a.leftArm.getX(), leftArm.getY() + a.leftArm.getY(), leftArm.getZ() + a.leftArm.getZ()); + f.head = new EulerAngle(head.getX() + a.head.getX(), head.getY() + a.head.getY(), head.getZ() + a.head.getZ()); + return f; + } + } + +} \ No newline at end of file diff --git a/src/main/java/eu/univento/core/api/items/ClickInventory.java b/src/main/java/eu/univento/core/api/items/ClickInventory.java new file mode 100644 index 0000000..e995d65 --- /dev/null +++ b/src/main/java/eu/univento/core/api/items/ClickInventory.java @@ -0,0 +1,238 @@ +package eu.univento.core.api.items; + +import eu.univento.core.api.items.events.NamedCloseEvent; +import eu.univento.core.api.items.events.PageCloseEvent; +import eu.univento.core.api.player.CustomPlayer; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryDragEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.plugin.java.JavaPlugin; + +import java.lang.reflect.Array; +import java.util.HashMap; + +/** + * @author joethei + * @version 0.1 + */ +public abstract class ClickInventory{ + + protected static JavaPlugin plugin; + protected Inventory currentInventory; + protected boolean inventoryInUse; + private boolean modifiable; + private CustomPlayer player; + private boolean playerInventoryUsed; + private ItemStack[] previousContents; + private String inventoryName; + private HashMap savedData; + + protected void saveContents() { + this.previousContents = this.getPlayer().getInventory().getContents().clone(); + } + + public Object getData(final Object key) { + return this.savedData.get(key); + } + + public ClickInventory setData(final Object key, final Object obj) { + if (obj == null) { + this.savedData.remove(key); + } + else { + this.savedData.put(key, obj); + } + return this; + } + + public ClickInventory(String inventoryName, final CustomPlayer player) { + this.savedData = new HashMap<>(); + this.player = player; + if (inventoryName == null) { + inventoryName = this.getClass().getSimpleName(); + } + this.inventoryName = inventoryName; + } + + public String getName() { + return this.inventoryName; + } + + public ClickInventory setPlayerInventory() { + if (!this.isInUse()) { + this.playerInventoryUsed = true; + } + return this; + } + + public void closeInventory() { + this.closeInventory(true); + } + + protected void onInventoryDrag(final InventoryDragEvent event) { + if (!this.isModifiable()) { + event.getRawSlots().stream().filter(this::checkInMenu).forEachOrdered(slot -> event.setCancelled(true)); + } + } + + protected boolean checkInMenu(int rawSlot) { + if (this.isPlayerInventory()) { + if (this.getPlayer().getOpenInventory().getTopInventory().getHolder() != this.getPlayer()) { + rawSlot -= this.getPlayer().getOpenInventory().getTopInventory().getSize(); + } + return rawSlot >= 0 && rawSlot < this.currentInventory.getSize(); + } + return rawSlot < this.currentInventory.getSize(); + } + + public boolean isPlayerInventory() { + return this.playerInventoryUsed; + } + + protected abstract void onInventoryClick(final InventoryClickEvent e); + + private void closeInventory(final boolean forceClose, final boolean restoreInventory) { + InventoryManager.removeInventory(this); + this.inventoryInUse = false; + if (this.getPlayer().hasMetadata(this.getClass().getSimpleName())) { + final E[] invs = (E[])this.getPlayer().getMetadata(this.getClass().getSimpleName()).get(0).value(); + if (invs[isPlayerInventory() ? 1 : 0] == this) + invs[isPlayerInventory() ? 1 : 0] = null; + } + if (this instanceof NamedInventory) { + Bukkit.getPluginManager().callEvent(new NamedCloseEvent((NamedInventory) this)); + } + if (this instanceof PageInventory) { + Bukkit.getPluginManager().callEvent(new PageCloseEvent((PageInventory) this)); + } + if (forceClose && (!this.isPlayerInventory() || this.getPlayer().getOpenInventory().getTopInventory().equals(this.currentInventory))) { + this.getPlayer().closeInventory(); + } + if (this.isPlayerInventory() && restoreInventory) { + this.getPlayer().getInventory().clear(); + this.getPlayer().getInventory().setContents(this.previousContents); + Bukkit.getScheduler().scheduleSyncDelayedTask(ClickInventory.plugin, () -> ClickInventory.this.getPlayer().updateInventory()); + } + } + + public void closeInventory(final boolean forceClose) { + this.closeInventory(forceClose, true); + } + + public ItemStack getItem(int slot) { + if (this.isPlayerInventory()) { + slot += 9; + if (slot >= 36) { + slot -= 36; + } + } + if (this.currentInventory != null && this.currentInventory.getSize() > slot) { + return this.currentInventory.getItem(slot); + } + return null; + } + + protected void setItems(final ItemStack[] items) { + if (this.isPlayerInventory()) { + for (int i = 0; i < items.length; ++i) { + this.setItem(i, items[i]); + } + } + else { + this.currentInventory.setContents(items); + } + } + + protected void setItem(int slot, final ItemStack item) { + if (this.isPlayerInventory()) { + slot += 9; + if (slot >= 36) { + slot -= 36; + } + } + this.currentInventory.setItem(slot, item); + } + + public CustomPlayer getPlayer() { + return this.player; + } + + public boolean isInUse() { + return this.inventoryInUse; + } + + public boolean isModifiable() { + return this.modifiable; + } + + protected void openInventory() { + final boolean isSwitchingInventory = this.isInUse(); + ItemStack heldItem = null; + final ClickInventory[] invs = new ClickInventory[2]; + for (final String inv : new String[] { "PageInventory", "NamedInventory", "AnvilInventory" }) { + if (this.getPlayer().hasMetadata(inv)) { + final E[] invss = (E[])(this.getPlayer().hasMetadata(inv) ? this.getPlayer().getMetadata(inv).get(0).value() : null); + if (invss != null) { + for (int i = 0; i < 2; ++i) { + if (invss[i] != null) { + invs[i] = (ClickInventory)invss[i]; + } + } + } + } + } + if (!this.isPlayerInventory()) { + this.inventoryInUse = false; + boolean previous = false; + if (invs[1] != null) { + previous = invs[1].inventoryInUse; + invs[1].inventoryInUse = false; + } + if (isSwitchingInventory) { + heldItem = this.getPlayer().getItemOnCursor(); + this.getPlayer().setItemOnCursor(new ItemStack(Material.AIR)); + } + if (invs[1] != null) { + invs[1].inventoryInUse = previous; + } + } + else { + this.getPlayer().updateInventory(); + if (!isSwitchingInventory && this.getPlayer().getOpenInventory().getTopInventory().getHolder() == this.getPlayer()) { + this.getPlayer().openInventory(Bukkit.createInventory(null, 0, this.getTitle())); + } + } + if (!isSwitchingInventory) { + InventoryManager.addInventory(this); + final int slot = this.isPlayerInventory() ? 1 : 0; + if (invs[slot] != null) { + if (invs[slot].inventoryInUse) { + invs[slot].closeInventory(false, false); + } + if (this.isPlayerInventory()) { + this.previousContents = invs[1].previousContents; + } + } + final E[] inv2 = (E[])(this.getPlayer().hasMetadata(this.getClass().getSimpleName()) ? this.getPlayer().getMetadata(this.getClass().getSimpleName()).get(0).value() : ((Object[]) Array.newInstance(this.getClass(), 2))); + inv2[slot] = (E)this; + this.getPlayer().setMetadata(this.getClass().getSimpleName(), new FixedMetadataValue(ClickInventory.plugin, inv2)); + } + else if (heldItem != null && heldItem.getType() != Material.AIR) { + this.getPlayer().setItemOnCursor(heldItem); + this.getPlayer().updateInventory(); + } + this.inventoryInUse = true; + } + + public abstract String getTitle(); + + public void setModifiable(final boolean modifiable) { + this.modifiable = modifiable; + } + + public abstract void setTitle(final String p0); +} \ No newline at end of file diff --git a/src/main/java/eu/univento/core/api/items/InventoryManager.java b/src/main/java/eu/univento/core/api/items/InventoryManager.java new file mode 100644 index 0000000..53eb08f --- /dev/null +++ b/src/main/java/eu/univento/core/api/items/InventoryManager.java @@ -0,0 +1,91 @@ +package eu.univento.core.api.items; + +import eu.univento.core.api.player.CustomPlayer; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryDragEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.inventory.ItemStack; + +import java.util.List; + +/** + * @author joethei + * @version 0.1 + */ +public class InventoryManager implements Listener{ + + private static List inventoryList; + + public static List getInventoryList() { + return inventoryList; + } + + public static void addInventory(ClickInventory inventory) { + inventoryList.add(inventory); + } + + public static void removeInventory(ClickInventory inventory) { + inventoryList.remove(inventory); + } + + public static NamedInventory[] getNamedInventories(final CustomPlayer p) { + if(!p.hasMetadata("NamedInventory")) return new NamedInventory[2]; + return ((NamedInventory[])p.getMetadata("NamedInventory").get(0).value()).clone(); + } + + public static NamedInventory getNamedInventory(final CustomPlayer p) { + return getNamedInventories(p)[0]; + } + + public static PageInventory[] getPageInventories(final CustomPlayer p) { + if(!p.hasMetadata("PageInventory")) return new PageInventory[2]; + return ((PageInventory[])p.getMetadata("PageInventory").get(0).value()).clone(); + } + + public static PageInventory getPageInventory(CustomPlayer p) { + return getPageInventories(p)[0]; + } + + public static ItemStack[] generateEmptyPage(int size) { + size = (int) (Math.ceil(size / 9.0) * 9); + return new ItemStack[Math.min(54, size)]; + } + + @EventHandler + public void onInventoryClick(InventoryClickEvent e) { + int i = 0; + CustomPlayer p = CustomPlayer.getPlayer((Player) e.getWhoClicked()); + for(ClickInventory inventory : inventoryList) { + if(inventory.getPlayer() == p) + inventory.onInventoryClick(e); + if(i++ == 1) break; + } + } + + @EventHandler + public void onInventoryDrag(InventoryDragEvent e) { + int i = 0; + CustomPlayer p = CustomPlayer.getPlayer((Player) e.getWhoClicked()); + for(ClickInventory inventory : inventoryList) { + if(inventory.getPlayer() == p) { + inventory.onInventoryDrag(e); + if(i++ == 1) break; + } + } + } + + @EventHandler + public void onQuit(PlayerQuitEvent e) { + int i = 0; + CustomPlayer p = CustomPlayer.getPlayer(e.getPlayer()); + for(ClickInventory inventory : inventoryList) { + if(inventory.getPlayer() == p) { + if(inventory.isInUse()) inventory.closeInventory(false); + if(i ++ == 1) break; + } + } + } +} \ No newline at end of file diff --git a/src/main/java/eu/univento/core/api/items/ItemBuilder.java b/src/main/java/eu/univento/core/api/items/ItemBuilder.java index c3e43d8..4c9b5ca 100644 --- a/src/main/java/eu/univento/core/api/items/ItemBuilder.java +++ b/src/main/java/eu/univento/core/api/items/ItemBuilder.java @@ -271,6 +271,10 @@ public class ItemBuilder { return this; } + public ItemBuilder glow() { + meta().addEnchant(Enchantment.ARROW_DAMAGE, 10, false); + return this; + } /** * Clears the defined {@link String} of lore from the {@link ItemStack} * diff --git a/src/main/java/eu/univento/core/api/items/NamedInventory.java b/src/main/java/eu/univento/core/api/items/NamedInventory.java new file mode 100644 index 0000000..b4c9ba1 --- /dev/null +++ b/src/main/java/eu/univento/core/api/items/NamedInventory.java @@ -0,0 +1,205 @@ +package eu.univento.core.api.items; + +import eu.univento.core.api.items.events.NamedPageClickEvent; +import eu.univento.core.api.player.CustomPlayer; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.inventory.ItemStack; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; + +/** + * @author joethei + * @version 0.1 + */ +public class NamedInventory extends ClickInventory{ + + protected Page currentPage; + protected HashMap pageDirectors; + protected HashMap pages; + + public NamedInventory(final CustomPlayer player) { + this(null, player); + } + + public NamedInventory(final CustomPlayer player, final boolean dymanicInventory) { + this(player); + } + + public NamedInventory(final String inventoryName, final CustomPlayer player) { + super(inventoryName, player); + this.pageDirectors = new HashMap<>(); + this.pages = new HashMap<>(); + } + + public Page getCurrentPage() { + return this.currentPage; + } + + public ItemStack[] getPage(final Page page) { + return this.pages.get(page); + } + + public Page getPage(final String pageName) { + for (final Page page : this.pages.keySet()) { + if (page.getPageName().equals(pageName)) { + return page; + } + } + return null; + } + + public Page getPageLink(final ItemStack item) { + return this.pageDirectors.get(item); + } + + public HashMap getPages() { + return this.pages; + } + + @Override + public String getTitle() { + return this.currentPage.getPageDisplayTitle(); + } + + public void linkPage(final ItemStack item, final Page page) { + this.pageDirectors.put(item, page); + } + + public void linkPage(final ItemStack item, final String pageName) { + final Page page = this.getPage(pageName); + if (page != null) { + this.linkPage(item, page); + } + } + + @Override + protected void onInventoryClick(final InventoryClickEvent event) { + final ItemStack item = event.getCurrentItem(); + if (this.checkInMenu(event.getRawSlot())) { + if (item != null && this.pageDirectors.containsKey(item)) { + event.setCancelled(true); + this.setPage(this.pageDirectors.get(item)); + return; + } + int slot = event.getSlot(); + if (this.isPlayerInventory()) { + slot -= 9; + if (slot < 0) { + slot += 36; + } + } + final NamedPageClickEvent itemClickEvent = new NamedPageClickEvent(this, this.currentPage, slot, event); + if (!this.isModifiable()) { + itemClickEvent.setCancelled(true); + } + Bukkit.getPluginManager().callEvent(itemClickEvent); + if (itemClickEvent.isCancelled()) { + event.setCancelled(true); + } + } + else if (!this.isModifiable() && event.isShiftClick() && item != null && item.getType() != Material.AIR) { + for (int slot = 0; slot < this.currentInventory.getSize(); ++slot) { + final ItemStack invItem = this.currentInventory.getItem(slot); + if (invItem == null || invItem.getType() == Material.AIR || (invItem.isSimilar(item) && invItem.getAmount() < invItem.getMaxStackSize())) { + event.setCancelled(true); + break; + } + } + } + } + + public void openInventory() { + if (this.isInUse()) { + return; + } + if (this.isPlayerInventory()) { + this.saveContents(); + } + if (this.currentPage == null) { + if (this.pages.isEmpty()) { + this.pages.put(new Page("Inventory"), new ItemStack[0]); + } + this.currentPage = this.pages.keySet().iterator().next(); + } + if (this.currentInventory == null) { + final ItemStack[] pageItems = this.getPage(this.currentPage); + if (this.isPlayerInventory()) { + this.currentInventory = this.getPlayer().getInventory(); + } + else { + this.currentInventory = Bukkit.createInventory(null, pageItems.length, this.getTitle()); + } + this.setItems(pageItems); + } + this.openInventory(); + } + + public void removePage(final Page page) { + this.pages.remove(page); + } + + public void setPage(final Page newPage) { + if (this.pages.containsKey(newPage)) { + final Page oldPage = this.currentPage; + this.currentPage = newPage; + if (this.isInUse()) { + final ItemStack[] pageItems = this.pages.get(this.currentPage); + if (!this.isPlayerInventory() && (pageItems.length != this.currentInventory.getSize() || !oldPage.getPageDisplayTitle().equals(this.getTitle()))) { + (this.currentInventory = Bukkit.createInventory(null, pageItems.length, this.getTitle())).setContents(pageItems); + this.openInventory(); + } + else { + this.setItems(pageItems); + } + } + } + } + + public void setPage(final Page page, ItemStack... items) { + if (items.length % 9 != 0) { + items = Arrays.copyOf(items, (int)(Math.ceil(items.length / 9.0) * 9.0)); + } + if (items.length > (this.isPlayerInventory() ? 36 : 54)) { + throw new RuntimeException("A inventory size of " + items.length + " was passed when the max is " + (this.isPlayerInventory() ? 36 : 54)); + } + this.pages.put(page, items); + if (this.currentPage == null) { + this.currentPage = page; + } + else if (this.currentPage.equals(page)) { + this.setPage(page); + } + } + + public void setPage(final Page page, final List items) { + this.setPage(page, (ItemStack[])items.toArray(new ItemStack[items.size()])); + } + + public void setPage(final String pageName) { + final Page page = this.getPage(pageName); + if (page != null) { + this.setPage(page); + } + } + + @Override + public NamedInventory setPlayerInventory() { + super.setPlayerInventory(); + return this; + } + + @Override + public void setTitle(final String newTitle) { + if (newTitle != null && this.getCurrentPage() != null && !this.getCurrentPage().getPageDisplayTitle().equals(newTitle)) { + this.setPage(new Page(this.getCurrentPage().getPageName(), newTitle), this.getPage(this.getCurrentPage())); + } + } + + public void unlinkPage(final ItemStack item) { + this.pageDirectors.remove(item); + } +} \ No newline at end of file diff --git a/src/main/java/eu/univento/core/api/items/Page.java b/src/main/java/eu/univento/core/api/items/Page.java new file mode 100644 index 0000000..9fd56db --- /dev/null +++ b/src/main/java/eu/univento/core/api/items/Page.java @@ -0,0 +1,59 @@ +package eu.univento.core.api.items; + +/** + * @author joethei + * @version 0.1 + */ +public class Page { + private String pageName; + private String pageTitle; + + public Page(final String pageName) { + this(pageName, pageName); + } + + public Page(final String pageName, final String pageDisplayTitle) { + this.pageTitle = pageDisplayTitle; + this.pageName = pageName; + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (this.getClass() != obj.getClass()) { + return false; + } + final Page other = (Page)obj; + return this.getPageName().equals(other.getPageName()); + } + + public String getPageDisplayTitle() { + return this.pageTitle; + } + + public String getPageName() { + return this.pageName; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = 31 * result + this.getPageName().hashCode(); + return result; + } + + public void setDisplayTitle(final String newTitle) { + this.pageTitle = newTitle; + } + + @Override + public String toString() { + return "Page[Name=" + this.getPageName() + ", Title=" + this.getPageDisplayTitle() + "]"; + } +} \ No newline at end of file diff --git a/src/main/java/eu/univento/core/api/items/PageInventory.java b/src/main/java/eu/univento/core/api/items/PageInventory.java new file mode 100644 index 0000000..3618ea5 --- /dev/null +++ b/src/main/java/eu/univento/core/api/items/PageInventory.java @@ -0,0 +1,328 @@ +package eu.univento.core.api.items; + +import eu.univento.core.api.items.events.PagesClickEvent; +import eu.univento.core.api.items.events.PagesTurnEvent; +import eu.univento.core.api.player.CustomPlayer; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.inventory.ItemStack; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; + +/** + * @author joethei + * @version 0.1 + */ +public class PageInventory extends ClickInventory{ + + protected ItemStack backAPage; + protected ItemStack forwardsAPage; + protected ItemStack exitInventory; + protected int currentPage; + protected boolean dynamicInventorySize; + private int inventorySize; + protected boolean pageDisplayedInTitle; + protected HashMap pages; + protected String title; + private String titleFormat; + + public PageInventory(final CustomPlayer player) { + this(null, player); + } + + public PageInventory(final CustomPlayer player, final boolean dynamicInventory) { + this(null, player, dynamicInventory); + } + + public PageInventory(final CustomPlayer player, final int inventorySize) { + this(null, player, inventorySize); + } + + public PageInventory(final String inventoryName, final CustomPlayer player) { + super(inventoryName, player); + this.dynamicInventorySize = true; + this.inventorySize = 54; + this.pages = new HashMap<>(); + this.title = "Inventory"; + this.titleFormat = "%Title% - Page %Page%"; + } + + public PageInventory(final String inventoryName, final CustomPlayer player, final boolean dynamicInventorySize) { + super(inventoryName, player); + this.dynamicInventorySize = true; + this.inventorySize = 54; + this.pages = new HashMap<>(); + this.title = "Inventory"; + this.titleFormat = "%Title% - Page %Page%"; + this.dynamicInventorySize = dynamicInventorySize; + } + + public PageInventory(final String inventoryName, final CustomPlayer player, final int inventorySize) { + super(inventoryName, player); + this.dynamicInventorySize = true; + this.inventorySize = 54; + this.pages = new HashMap<>(); + this.title = "Inventory"; + this.titleFormat = "%Title% - Page %Page%"; + this.inventorySize = Math.min(54, (int)Math.ceil(inventorySize / 9.0) * 9); + this.dynamicInventorySize = false; + this.pages.put(0, new ItemStack[0]); + } + + public ItemStack getExitInventory() { + return this.exitInventory; + } + + public void setExitInventory(final ItemStack item) { + this.exitInventory = item; + } + + public ItemStack getBackPage() { + if (this.backAPage == null) { + this.backAPage = new ItemBuilder(Material.SIGN).name("Zurück").make(); + } + return this.backAPage; + } + + public int getCurrentPage() { + return this.currentPage; + } + + public ItemStack getForwardsPage() { + if (this.forwardsAPage == null) { + this.forwardsAPage = new ItemBuilder(Material.SIGN).name("Vorwärts").make(); + } + return this.forwardsAPage; + } + + @Override + public String getTitle() { + return this.getPageTitle(); + } + + public ItemStack[] getPage(final int pageNumber) { + if (this.pages.containsKey(pageNumber)) { + return this.pages.get(pageNumber); + } + return null; + } + + public HashMap getPages() { + return this.pages; + } + + protected String getPageTitle() { + return this.isPageDisplayedInTitle() ? this.titleFormat.replace("%Title%", this.title).replace("%Page%", this.getCurrentPage() + 1 + "") : this.title; + } + + public boolean isPageDisplayedInTitle() { + return this.pageDisplayedInTitle; + } + + @Override + protected void onInventoryClick(final InventoryClickEvent event) { + final ItemStack item = event.getCurrentItem(); + if (this.checkInMenu(event.getRawSlot())) { + if (item != null) { + int newPage = 0; + if (item.equals(this.getBackPage())) { + newPage = -1; + } + else if (item.equals(this.getForwardsPage())) { + newPage = 1; + } + if (newPage != 0) { + final PagesTurnEvent newEvent = new PagesTurnEvent(this, event.getSlot(), event, this.getCurrentPage() + newPage); + Bukkit.getPluginManager().callEvent(newEvent); + if (!newEvent.isCancelled()) { + this.setPage(this.getCurrentPage() + newPage); + } + event.setCancelled(true); + return; + } + } + int slot = event.getSlot(); + if (this.isPlayerInventory()) { + slot -= 9; + if (slot < 0) { + slot += 36; + } + } + final PagesClickEvent itemClickEvent = new PagesClickEvent(this, slot, event); + if (!this.isModifiable()) { + itemClickEvent.setCancelled(true); + } + Bukkit.getPluginManager().callEvent(itemClickEvent); + if (itemClickEvent.isCancelled()) { + event.setCancelled(true); + } + } + else if (!this.isModifiable() && event.isShiftClick() && item != null && item.getType() != Material.AIR) { + for (int slot = 0; slot < this.currentInventory.getSize(); ++slot) { + final ItemStack invItem = this.currentInventory.getItem(slot); + if (invItem == null || invItem.getType() == Material.AIR || (invItem.isSimilar(item) && item.getAmount() < item.getMaxStackSize())) { + event.setCancelled(true); + break; + } + } + } + } + + public void openInventory() { + if (this.isInUse()) { + return; + } + this.saveContents(); + final ItemStack[] pageItems = this.getItemsForPage(); + if (this.currentInventory == null) { + if (this.isPlayerInventory()) { + this.currentInventory = this.getPlayer().getInventory(); + } + else { + this.currentInventory = Bukkit.createInventory(null, pageItems.length, this.getPageTitle()); + } + } + this.setItems(pageItems); + this.openInventory(); + } + + private ItemStack[] getItemsForPage() { + ItemStack[] pageItems = this.pages.get(Math.max(this.getCurrentPage(), 0)); + int pageSize = pageItems.length; + if (this.pages.size() > 1 || this.getExitInventory() != null) { + pageSize += 9; + } + if (!this.dynamicInventorySize || this.isPlayerInventory()) { + pageSize = (this.isPlayerInventory() ? 36 : this.inventorySize); + } + else { + pageSize = (pageSize + 8) / 9 * 9; + } + pageItems = Arrays.copyOf(pageItems, pageSize); + if (this.getCurrentPage() > 0 || this.getExitInventory() != null) { + pageItems[pageItems.length - 9] = ((this.getCurrentPage() == 0) ? this.getExitInventory() : this.getBackPage()); + } + if (this.pages.size() - 1 > this.getCurrentPage()) { + pageItems[pageItems.length - 1] = this.getForwardsPage(); + } + return pageItems; + } + + public void setBackPage(final ItemStack newBack) { + this.backAPage = newBack; + } + + public void setForwardsPage(final ItemStack newForwards) { + this.forwardsAPage = newForwards; + } + + public ArrayList getItems() { + final ArrayList items = new ArrayList<>(); + for (int i = 0; i < this.pages.size(); ++i) { + final ItemStack[] itemArray = this.pages.get(i); + for (int a = 0; a < itemArray.length - ((this.pages.size() > 1) ? 9 : 0); ++a) { + items.add(itemArray[a]); + } + } + return items; + } + + public void setPage(final int newPage) { + if (this.pages.containsKey(newPage)) { + this.currentPage = newPage; + if (this.isInUse()) { + final ItemStack[] pageItems = this.getItemsForPage(); + if (!this.isPlayerInventory() && (pageItems.length != this.currentInventory.getSize() || !this.currentInventory.getTitle().equalsIgnoreCase(this.getPageTitle()))) { + (this.currentInventory = Bukkit.createInventory(null, pageItems.length, this.getPageTitle())).setContents(pageItems); + this.openInventory(); + } + else { + this.setItems(pageItems); + } + } + } + } + + public void setPageDisplayedInTitle(final boolean displayPage) { + if (this.isPageDisplayedInTitle() != displayPage) { + this.pageDisplayedInTitle = displayPage; + if (this.isInUse()) { + this.setPage(this.getCurrentPage()); + } + } + } + + public void setPageDisplayTitleFormat(final String titleFormat) { + this.titleFormat = titleFormat; + if (this.isInUse()) { + this.setPage(this.getCurrentPage()); + } + } + + public void setPages(final ArrayList allItems) { + this.setPages((ItemStack[])allItems.toArray(new ItemStack[allItems.size()])); + } + + public void setPages(final ItemStack... allItems) { + this.pages.clear(); + int invPage = 0; + final boolean usePages = this.getExitInventory() != null || allItems.length > this.inventorySize; + ItemStack[] items = null; + int currentSlot = 0; + final int baseSize = this.isPlayerInventory() ? 36 : this.inventorySize; + for (int currentItem = 0; currentItem < allItems.length; ++currentItem) { + if (items == null) { + int newSize = allItems.length - currentItem; + if (usePages && newSize + 9 > baseSize) { + newSize = baseSize - 9; + } + else if (newSize > baseSize) { + newSize = baseSize; + } + items = new ItemStack[newSize]; + } + final ItemStack item = allItems[currentItem]; + items[currentSlot++] = item; + if (currentSlot == items.length) { + this.pages.put(invPage, items); + ++invPage; + currentSlot = 0; + items = null; + } + } + if (this.pages.keySet().size() < this.getCurrentPage()) { + this.currentPage = this.pages.keySet().size() - 1; + } + if (allItems.length == 0) { + int size = this.isPlayerInventory() ? 36 : this.inventorySize; + if (!this.isPlayerInventory() && this.dynamicInventorySize) { + size = 9; + } + items = InventoryManager.generateEmptyPage(size); + if (this.getExitInventory() != null) { + items[0] = this.getExitInventory(); + } + this.pages.put(0, items); + } + this.setPage(this.getCurrentPage()); + } + + @Override + public PageInventory setPlayerInventory() { + super.setPlayerInventory(); + return this; + } + + @Override + public void setTitle(final String newTitle) { + if (!this.getTitle().equals(newTitle)) { + this.title = newTitle; + if (this.isInUse()) { + this.setPage(this.getCurrentPage()); + } + } + } +} \ No newline at end of file diff --git a/src/main/java/eu/univento/core/api/items/PageLayout.java b/src/main/java/eu/univento/core/api/items/PageLayout.java new file mode 100644 index 0000000..baf8eb1 --- /dev/null +++ b/src/main/java/eu/univento/core/api/items/PageLayout.java @@ -0,0 +1,58 @@ +package eu.univento.core.api.items; + +import org.bukkit.inventory.ItemStack; + +import java.util.ArrayList; + +/** + * @author joethei + * @version 0.1 + */ +public class PageLayout { + private static String empty = "X"; + private static String full = "O"; + private int invSize; + private ArrayList size; + + public static void setStringFormat(final String noItem, final String aItem) { + PageLayout.empty = noItem; + PageLayout.full = aItem; + } + + public PageLayout(final String... strings) { + this.invSize = 0; + this.size = new ArrayList(); + this.invSize = strings.length * 9; + for (int slot = 0; slot < strings.length * 9; ++slot) { + final String string = strings[(int)Math.floor(slot / 9.0)]; + if (string.length() != 9) { + throw new RuntimeException("String is not a length of 9. String is a length of " + string.length() + ". " + string); + } + final String letter = string.substring(slot % 9, slot % 9 + 1); + if (!letter.equalsIgnoreCase(PageLayout.empty)) { + if (!letter.equalsIgnoreCase(PageLayout.full)) { + throw new RuntimeException("Unrecognised value " + letter); + } + this.size.add(slot); + } + } + } + + public ItemStack[] generate(final ArrayList items) { + return this.generate((ItemStack[])items.toArray(new ItemStack[items.size()])); + } + + public ItemStack[] generate(final ItemStack... items) { + final ItemStack[] itemArray = new ItemStack[this.invSize]; + for (int i = 0; i < this.size.size(); ++i) { + if (i < items.length) { + final ItemStack itemToInsert = items[i]; + if (itemToInsert != null) { + itemArray[this.size.get(i)] = itemToInsert.clone(); + } + } + } + return itemArray; + } + +} \ No newline at end of file diff --git a/src/main/java/eu/univento/core/api/items/events/ItemClickEvent.java b/src/main/java/eu/univento/core/api/items/events/ItemClickEvent.java new file mode 100644 index 0000000..3a63002 --- /dev/null +++ b/src/main/java/eu/univento/core/api/items/events/ItemClickEvent.java @@ -0,0 +1,60 @@ +package eu.univento.core.api.items.events; + +import eu.univento.core.api.items.ClickInventory; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.inventory.ItemStack; + +/** + * @author joethei + * @version 0.1 + */ +public abstract class ItemClickEvent extends Event implements Cancellable{ + + private static final HandlerList handlers = new HandlerList(); + private boolean cancelled; + private InventoryClickEvent invEvent; + protected int slot; + + public static HandlerList getHandlerList() { + return ItemClickEvent.handlers; + } + + public ItemClickEvent(final int slot, final InventoryClickEvent invEvent) { + this.slot = slot; + this.invEvent = invEvent; + } + + public InventoryClickEvent getEvent() { + return this.invEvent; + } + + public HandlerList getHandlers() { + return ItemClickEvent.handlers; + } + + public abstract ClickInventory getInventory(); + + public abstract ItemStack getItemStack(); + + public String getName() { + return this.getInventory().getName(); + } + + public abstract Player getPlayer(); + + public int getSlot() { + return this.slot; + } + + public boolean isCancelled() { + return this.cancelled; + } + + public void setCancelled(final boolean cancel) { + this.cancelled = cancel; + } +} \ No newline at end of file diff --git a/src/main/java/eu/univento/core/api/items/events/NamedCloseEvent.java b/src/main/java/eu/univento/core/api/items/events/NamedCloseEvent.java new file mode 100644 index 0000000..09500ad --- /dev/null +++ b/src/main/java/eu/univento/core/api/items/events/NamedCloseEvent.java @@ -0,0 +1,40 @@ +package eu.univento.core.api.items.events; + +import eu.univento.core.api.items.NamedInventory; +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +/** + * @author joethei + * @version 0.1 + */ +public class NamedCloseEvent extends Event { + + private static final HandlerList handlers = new HandlerList(); + private NamedInventory inv; + + public static HandlerList getHandlerList() { + return NamedCloseEvent.handlers; + } + + public NamedCloseEvent(final NamedInventory inventory) { + this.inv = inventory; + } + + public HandlerList getHandlers() { + return NamedCloseEvent.handlers; + } + + public NamedInventory getInventory() { + return this.inv; + } + + public Player getPlayer() { + return this.inv.getPlayer(); + } + + public String getName() { + return this.getInventory().getName(); + } +} \ No newline at end of file diff --git a/src/main/java/eu/univento/core/api/items/events/NamedPageClickEvent.java b/src/main/java/eu/univento/core/api/items/events/NamedPageClickEvent.java new file mode 100644 index 0000000..a0724b6 --- /dev/null +++ b/src/main/java/eu/univento/core/api/items/events/NamedPageClickEvent.java @@ -0,0 +1,56 @@ +package eu.univento.core.api.items.events; + +import eu.univento.core.api.items.NamedInventory; +import eu.univento.core.api.items.Page; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.inventory.ItemStack; + +/** + * @author joethei + * @version 0.1 + */ +public class NamedPageClickEvent extends ItemClickEvent{ + + private static final HandlerList handlers = new HandlerList(); + private NamedInventory inv; + private Page page; + + public static HandlerList getHandlerList() { + return NamedPageClickEvent.handlers; + } + + public NamedPageClickEvent(final NamedInventory inventory, final Page page, final int slot, final InventoryClickEvent invEvent) { + super(slot, invEvent); + this.inv = inventory; + this.page = page; + } + + @Override + public HandlerList getHandlers() { + return NamedPageClickEvent.handlers; + } + + @Override + public NamedInventory getInventory() { + return this.inv; + } + + @Override + public ItemStack getItemStack() { + if (this.slot >= 0) { + return this.inv.getItem(this.slot); + } + return null; + } + + public Page getPage() { + return this.page; + } + + @Override + public Player getPlayer() { + return this.inv.getPlayer(); + } +} \ No newline at end of file diff --git a/src/main/java/eu/univento/core/api/items/events/PageCloseEvent.java b/src/main/java/eu/univento/core/api/items/events/PageCloseEvent.java new file mode 100644 index 0000000..3da693b --- /dev/null +++ b/src/main/java/eu/univento/core/api/items/events/PageCloseEvent.java @@ -0,0 +1,40 @@ +package eu.univento.core.api.items.events; + +import eu.univento.core.api.items.PageInventory; +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +/** + * @author joethei + * @version 0.1 + */ +public class PageCloseEvent extends Event{ + + private static final HandlerList handlers = new HandlerList(); + private PageInventory inv; + + public static HandlerList getHandlerList() { + return PageCloseEvent.handlers; + } + + public PageCloseEvent(final PageInventory inventory) { + this.inv = inventory; + } + + public HandlerList getHandlers() { + return PageCloseEvent.handlers; + } + + public PageInventory getInventory() { + return this.inv; + } + + public Player getPlayer() { + return this.inv.getPlayer(); + } + + public String getName() { + return this.getInventory().getName(); + } +} diff --git a/src/main/java/eu/univento/core/api/items/events/PagesClickEvent.java b/src/main/java/eu/univento/core/api/items/events/PagesClickEvent.java new file mode 100644 index 0000000..14e8bf9 --- /dev/null +++ b/src/main/java/eu/univento/core/api/items/events/PagesClickEvent.java @@ -0,0 +1,49 @@ +package eu.univento.core.api.items.events; + +import eu.univento.core.api.items.PageInventory; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.inventory.ItemStack; + +/** + * @author joethei + * @version 0.1 + */ +public class PagesClickEvent extends ItemClickEvent{ + + private static final HandlerList handlers = new HandlerList(); + private PageInventory inv; + + public static HandlerList getHandlerList() { + return PagesClickEvent.handlers; + } + + public PagesClickEvent(final PageInventory inventory, final int slot, final InventoryClickEvent invEvent) { + super(slot, invEvent); + this.inv = inventory; + } + + @Override + public HandlerList getHandlers() { + return PagesClickEvent.handlers; + } + + @Override + public PageInventory getInventory() { + return this.inv; + } + + @Override + public ItemStack getItemStack() { + if (this.slot >= 0) { + return this.inv.getItem(this.slot); + } + return null; + } + + @Override + public Player getPlayer() { + return this.inv.getPlayer(); + } +} diff --git a/src/main/java/eu/univento/core/api/items/events/PagesTurnEvent.java b/src/main/java/eu/univento/core/api/items/events/PagesTurnEvent.java new file mode 100644 index 0000000..45980e2 --- /dev/null +++ b/src/main/java/eu/univento/core/api/items/events/PagesTurnEvent.java @@ -0,0 +1,55 @@ +package eu.univento.core.api.items.events; + +import eu.univento.core.api.items.PageInventory; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.inventory.ItemStack; + +/** + * @author joethei + * @version 0.1 + */ +public class PagesTurnEvent extends ItemClickEvent{ + + private static final HandlerList handlers = new HandlerList(); + private PageInventory inv; + private int newPage; + + public static HandlerList getHandlerList() { + return PagesTurnEvent.handlers; + } + + public PagesTurnEvent(final PageInventory inventory, final int slot, final InventoryClickEvent invEvent, final int newPage) { + super(slot, invEvent); + this.inv = inventory; + this.newPage = newPage; + } + + public int getNewPage() { + return this.newPage; + } + + @Override + public HandlerList getHandlers() { + return PagesTurnEvent.handlers; + } + + @Override + public PageInventory getInventory() { + return this.inv; + } + + @Override + public ItemStack getItemStack() { + if (this.slot >= 0) { + return this.inv.getItem(this.slot); + } + return null; + } + + @Override + public Player getPlayer() { + return this.inv.getPlayer(); + } +} \ No newline at end of file diff --git a/src/main/java/eu/univento/core/api/map/Map.java b/src/main/java/eu/univento/core/api/map/Map.java index 1ae42b8..fec43ac 100644 --- a/src/main/java/eu/univento/core/api/map/Map.java +++ b/src/main/java/eu/univento/core/api/map/Map.java @@ -32,7 +32,7 @@ public class Map { return item; } - public String getDownloadLink() { + public String getDownload() { return download; } } \ No newline at end of file diff --git a/src/main/java/eu/univento/core/api/map/MapDatabase.java b/src/main/java/eu/univento/core/api/map/MapDatabase.java index a468e9b..992c4a9 100644 --- a/src/main/java/eu/univento/core/api/map/MapDatabase.java +++ b/src/main/java/eu/univento/core/api/map/MapDatabase.java @@ -1,24 +1,72 @@ package eu.univento.core.api.map; -import eu.univento.core.api.server.ServerType; +import eu.univento.cloud.commons.server.ServerType; +import eu.univento.core.Core; import org.bukkit.Material; +import java.sql.SQLException; import java.util.ArrayList; /** * @author joethei * @version 0.1 */ -class MapDatabase { +public class MapDatabase { + + public static Map getMap(String name) { + final Map[] map = new Map[1]; + Core.getCommons().getDatabaseManager().getAsyncMySQL().query("SELECT * FROM maps WHERE name='" + name + "' INNER JOIN builder ON map.builder = builder.id;", resultSet -> { + try { + map[0] = new Map(resultSet.getString("map.name"), resultSet.getString("builder.name"), Material.valueOf(resultSet.getString("map.material")), resultSet.getString("map.link")); + } catch (SQLException e) { + e.printStackTrace(); + } + }); + return map[0]; + } + + public static ArrayList getAllMaps(String builderName) { + ArrayList maps = new ArrayList<>(); + + Core.getCommons().getDatabaseManager().getAsyncMySQL().query("SELECT * FROM maps WHERE builder.name='" + builderName + "' INNER JOIN builder ON map.builder = builder.id;", resultSet -> { + try { + while(resultSet.next()) { + maps.add(new Map(resultSet.getString("map.name"), resultSet.getString("builder.name"), Material.valueOf(resultSet.getString("map.material")), resultSet.getString("map.link"))); + } + } catch (SQLException e) { + e.printStackTrace(); + } + }); + return maps; + } - //TODO: add real map database public static ArrayList getAllMaps(ServerType serverType) { ArrayList maps = new ArrayList<>(); - maps.add(new Map("Map1", "TeamVento", Material.GRASS, "http://creppy.univento.eu/maps/Strive/Map1")); - maps.add(new Map("Map2", "TeamVento", Material.STONE, "http://creppy.univento.eu/maps/Strive/Map2")); - maps.add(new Map("Map3", "TeamVento", Material.APPLE, "http://creppy.univento.eu/maps/Strive/Map3")); + Core.getCommons().getDatabaseManager().getAsyncMySQL().query("SELECT * FROM maps WHERE type='" + serverType.getID() + "' INNER JOIN builder ON map.builder = builder.id;", resultSet -> { + try { + while(resultSet.next()) { + maps.add(new Map(resultSet.getString("map.name"), resultSet.getString("builder.name"), Material.valueOf(resultSet.getString("map.material")), resultSet.getString("map.link"))); + } + } catch (SQLException e) { + e.printStackTrace(); + } + }); + return maps; + } + public static ArrayList getAllMaps() { + ArrayList maps = new ArrayList<>(); + + Core.getCommons().getDatabaseManager().getAsyncMySQL().query("SELECT * FROM maps INNER JOIN builder ON map.builder = builder.id;", resultSet -> { + try { + while(resultSet.next()) { + maps.add(new Map(resultSet.getString("map.name"), resultSet.getString("builder.name"), Material.valueOf(resultSet.getString("map.material")), resultSet.getString("map.link"))); + } + } catch (SQLException e) { + e.printStackTrace(); + } + }); return maps; } } \ No newline at end of file diff --git a/src/main/java/eu/univento/core/api/map/MapDownloader.java b/src/main/java/eu/univento/core/api/map/MapDownloader.java index 024f4d3..1c58e63 100644 --- a/src/main/java/eu/univento/core/api/map/MapDownloader.java +++ b/src/main/java/eu/univento/core/api/map/MapDownloader.java @@ -1,36 +1,47 @@ package eu.univento.core.api.map; -import eu.univento.core.Core; +import org.apache.commons.io.FileUtils; +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.bukkit.WorldCreator; import java.io.File; -import java.io.FileOutputStream; -import java.io.InputStream; -import java.io.OutputStream; +import java.io.IOException; +import java.net.MalformedURLException; import java.net.URL; /** * @author joethei * @version 0.1 */ -class MapDownloader { +public class MapDownloader { - public static void download(URL file, File dest) { + private static void download(URL file, File dest) { try { - InputStream is = file.openStream(); - File finaldest = new File(dest + "/" + file.getFile()); - if(!finaldest.getParentFile().mkdirs()) Core.getCommons().getLoggingHandler().getCore().warn("Map Ordner konnte nicht erstellt werden"); - finaldest.createNewFile(); - OutputStream os = new FileOutputStream(finaldest); - byte data[] = new byte[1024]; - int count; - while ((count = is.read(data, 0, 1024)) != -1) { - os.write(data, 0, count); - } - os.flush(); - is.close(); - os.close(); - } catch (Exception ec) { - ec.printStackTrace(); + FileUtils.copyURLToFile(file, dest); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public static World loadMap(String name) { + Map map = MapDatabase.getMap(name); + try { + download(new URL(map.getDownload()), new File("worlds/" + name)); + return Bukkit.createWorld(new WorldCreator(name)); + } catch (MalformedURLException e) { + e.printStackTrace(); + return null; + } + } + + public static World loadMap(Map map) { + try { + download(new URL(map.getDownload()), new File("worlds/" + map.getName())); + return Bukkit.createWorld(new WorldCreator(map.getName())); + } catch (MalformedURLException e) { + e.printStackTrace(); + return null; } } } \ No newline at end of file diff --git a/src/main/java/eu/univento/core/api/map/MapVoting.java b/src/main/java/eu/univento/core/api/map/MapVoting.java index 8c8ae79..1d40713 100644 --- a/src/main/java/eu/univento/core/api/map/MapVoting.java +++ b/src/main/java/eu/univento/core/api/map/MapVoting.java @@ -1,6 +1,7 @@ package eu.univento.core.api.map; import eu.univento.commons.player.Rank; +import eu.univento.core.api.items.ItemBuilder; import eu.univento.core.api.player.CustomPlayer; import org.bukkit.Bukkit; import org.bukkit.entity.Player; @@ -8,8 +9,6 @@ import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.plugin.Plugin; import java.util.ArrayList; @@ -20,7 +19,7 @@ import java.util.Random; * @author joethei * @version 0.1 */ -class MapVoting implements Listener{ +public class MapVoting implements Listener{ private Map map1; @@ -80,15 +79,9 @@ class MapVoting implements Listener{ } private int getMapID(int votes) { - if(votes == votes1.size()) { - return 1; - } - if(votes == votes2.size()) { - return 2; - } - if(votes == votes3.size()) { - return 3; - } + if(votes == votes1.size()) return 1; + if(votes == votes2.size()) return 2; + if(votes == votes3.size()) return 3; return 0; } @@ -112,48 +105,16 @@ class MapVoting implements Listener{ if(p.getDatabasePlayer().isAllowed(Rank.Admin)) { Inventory inv = Bukkit.createInventory(p, 45, invTitle); - for(Map map : allMaps) { - ItemStack item = new ItemStack(map.getItem()); - ItemMeta meta = item.getItemMeta(); - meta.setDisplayName(map.getName()); - ArrayList lore = new ArrayList<>(); - lore.add("§aby " + map.getBuilder()); - meta.setLore(lore); - - inv.addItem(item); - } + for(Map map : allMaps) + inv.addItem(new ItemBuilder(map.getItem()).name(map.getName()).lore("§aby " + map.getBuilder()).make()); return inv; }else{ Inventory inv = Bukkit.createInventory(p, 9, invTitle); - ItemStack map1 = new ItemStack(this.map1.getItem()); - ItemMeta map1Meta = map1.getItemMeta(); - map1Meta.setDisplayName(this.map1.getName()); - ArrayList map1Lore = new ArrayList<>(); - map1Lore.add("§aby " + this.map1.getBuilder()); - map1Meta.setLore(map1Lore); - map1.setItemMeta(map1Meta); - - ItemStack map2 = new ItemStack(this.map2.getItem()); - ItemMeta map2Meta = map2.getItemMeta(); - map2Meta.setDisplayName(this.map2.getName()); - ArrayList map2Lore = new ArrayList<>(); - map2Lore.add("§aby " + this.map2.getBuilder()); - map2Meta.setLore(map2Lore); - map2.setItemMeta(map2Meta); - - ItemStack map3 = new ItemStack(this.map3.getItem()); - ItemMeta map3Meta = map3.getItemMeta(); - map3Meta.setDisplayName(this.map3.getName()); - ArrayList map3Lore = new ArrayList<>(); - map3Lore.add("§aby " + this.map3.getBuilder()); - map3Meta.setLore(map3Lore); - map3.setItemMeta(map3Meta); - - inv.setItem(1, map1); - inv.setItem(4, map2); - inv.setItem(7, map3); + inv.setItem(1, new ItemBuilder(this.map1.getItem()).name(this.map1.getName()).lore("§aby " + this.map1.getBuilder()).make()); + inv.setItem(4, new ItemBuilder(this.map2.getItem()).name(this.map2.getName()).lore("§aby " + this.map2.getBuilder()).make()); + inv.setItem(7, new ItemBuilder(this.map3.getItem()).name(this.map3.getName()).lore("§aby " + this.map3.getBuilder()).make()); return inv; } diff --git a/src/main/java/eu/univento/core/api/player/CustomPlayer.java b/src/main/java/eu/univento/core/api/player/CustomPlayer.java index e9371ad..6ba7b6c 100644 --- a/src/main/java/eu/univento/core/api/player/CustomPlayer.java +++ b/src/main/java/eu/univento/core/api/player/CustomPlayer.java @@ -18,6 +18,8 @@ import eu.univento.core.api.utils.GameProfileBuilder; import eu.univento.core.api.utils.UUIDFetcher; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; +import net.md_5.bungee.api.ChatMessageType; +import net.md_5.bungee.api.chat.TextComponent; import net.minecraft.server.v1_10_R1.*; import net.minecraft.server.v1_10_R1.World; import org.bson.Document; @@ -178,7 +180,7 @@ public class CustomPlayer extends CraftPlayer{ */ public void sendActionBar(String text) { - //spigot().sendMessage(ChatMessageType.ACTION_BAR, new TextComponent(text)); + spigot().sendMessage(ChatMessageType.ACTION_BAR, new TextComponent(text)); } public void sendTitle(int fadeIn, int stay, int fadeOut, String title, String subtitle) { @@ -397,6 +399,9 @@ public class CustomPlayer extends CraftPlayer{ } + /** + * crash's the players client + */ public void crashClient() { sendPacket(new PacketPlayOutExplosion(9999999999D, 9999999999D, 9999999999D, 9999999999F, @@ -408,6 +413,7 @@ public class CustomPlayer extends CraftPlayer{ getHandle().playerConnection.sendPacket(packet); } + private Field getField(Class clazz, String name) { try { Field field = clazz.getDeclaredField(name); @@ -442,10 +448,15 @@ public class CustomPlayer extends CraftPlayer{ */ public void playEffect(Location location, Effect effect, int id, int data, float offsetX, float offsetY, float offsetZ, float speed, int particleCount, int radius) { if(DATABASE_PLAYER.getSettings().hasEffectsEnabled()) { - //spigot().playEffect(location, effect, id, data, offsetX, offsetY, offsetZ, speed, particleCount, radius); + PLAYER.spigot().playEffect(location, effect, id, data, offsetX, offsetY, offsetZ, speed, particleCount, radius); } } + /** + * open or close chests for player + * @param loc location, block at location must be a type of chest + * @param open open or close the chest + */ public void changeChestState(Location loc, boolean open) { if(loc.getBlock().getType() != Material.CHEST) return; byte dataByte = (open) ? (byte) 1 : 0; @@ -454,4 +465,25 @@ public class CustomPlayer extends CraftPlayer{ sendPacket(blockActionPacket); } + /** + * sets the amount of arrows that are in the body of the player + * @param count arrow count + */ + public void setArrowsInBody(int count) { + getHandle().getDataWatcher().set(new DataWatcherObject<>(10, DataWatcherRegistry.b), count); + } + + public int getArrowsInBody() { + return getHandle().getDataWatcher().get(new DataWatcherObject<>(10, DataWatcherRegistry.b)); + } + + /** + * sends packets for item cooldown, items won't be disabled + * @param item item to have a cooldown + * @param time time in seconds + */ + public void setItemCooldown(ItemStack item, int time) { + sendPacket(new PacketPlayOutSetCooldown(item.getItem(), time)); + } + } \ No newline at end of file diff --git a/src/main/java/eu/univento/core/api/map/Cuboid.java b/src/main/java/eu/univento/core/api/schematic/Cuboid.java similarity index 97% rename from src/main/java/eu/univento/core/api/map/Cuboid.java rename to src/main/java/eu/univento/core/api/schematic/Cuboid.java index 21232bc..05f2a39 100644 --- a/src/main/java/eu/univento/core/api/map/Cuboid.java +++ b/src/main/java/eu/univento/core/api/schematic/Cuboid.java @@ -1,4 +1,4 @@ -package eu.univento.core.api.map; +package eu.univento.core.api.schematic; import org.bukkit.*; import org.bukkit.block.Block; @@ -144,7 +144,7 @@ public class Cuboid implements Cloneable, ConfigurationSerializable, Iterable list) { + File file = new File(Core.getInstance().getDataFolder().getAbsolutePath() + "/schematics/", name + ".building"); + String line = System.getProperty("line.separator"); + if(file.exists()) return false; + try { + if(!file.createNewFile()) return false; + BufferedWriter writter = new BufferedWriter(new FileWriter(file)); + for(String s : list) { + writter.write(s); + writter.write(line); + } + writter.close(); + return true; + } catch (IOException e) { + e.printStackTrace(); + return false; + } + + } + + public List getBlockList(Location loc) { + return cuboid.getBlocks().stream().map(Object::toString).collect(Collectors.toCollection(ArrayList::new)); + } + +} \ No newline at end of file diff --git a/src/main/java/eu/univento/core/api/schematic/SchematicManager.java b/src/main/java/eu/univento/core/api/schematic/SchematicManager.java new file mode 100644 index 0000000..ace6d30 --- /dev/null +++ b/src/main/java/eu/univento/core/api/schematic/SchematicManager.java @@ -0,0 +1,31 @@ +package eu.univento.core.api.schematic; + +import eu.univento.core.Core; +import eu.univento.core.api.player.CustomPlayer; + +import java.io.File; +import java.util.HashMap; +import java.util.Map; + +/** + * @author joethei + * @version 0.1 + */ +public class SchematicManager { + + private Map schematics; + + public void createFiles() { + File file = new File(Core.getInstance().getDataFolder().getAbsolutePath() + "/schematics"); + if(!file.exists()) file.mkdirs(); + } + + public SchematicManager() { + this.schematics = new HashMap<>(); + } + + public boolean load(Schematic schematic, CustomPlayer player) { + return false; + } + +} \ No newline at end of file diff --git a/src/main/java/eu/univento/core/api/server/ServerSettings.java b/src/main/java/eu/univento/core/api/server/ServerSettings.java index d7bcd9d..7c42fe9 100644 --- a/src/main/java/eu/univento/core/api/server/ServerSettings.java +++ b/src/main/java/eu/univento/core/api/server/ServerSettings.java @@ -1,5 +1,6 @@ package eu.univento.core.api.server; +import eu.univento.cloud.commons.server.ServerType; import eu.univento.core.Core; import eu.univento.core.commands.Build; import eu.univento.core.listeners.Blocks; @@ -52,9 +53,10 @@ public class ServerSettings { public static void setBuild(boolean build) { ServerSettings.build = build; - if(!build) { + Core.getCommons().getLoggingHandler().getCore().info("Build ist " + build); + if(build) { PluginManager pm = Bukkit.getPluginManager(); - new Build(Core.getInstance(), "build", "b"); + new Build(Core.getInstance(), "build", "Bau Modus an/ausschalten", "b"); pm.registerEvents(new Blocks(), Core.getInstance()); Core.getCommons().getLoggingHandler().getCore().info("Build Modus aktiviert"); } diff --git a/src/main/java/eu/univento/core/api/server/ServerType.java b/src/main/java/eu/univento/core/api/server/ServerType.java deleted file mode 100644 index f13fdff..0000000 --- a/src/main/java/eu/univento/core/api/server/ServerType.java +++ /dev/null @@ -1,28 +0,0 @@ -package eu.univento.core.api.server; - -/** - * @author joethei - * @version 0.1 - */ -public enum ServerType { - - LOBBY("Lobby", "§6Lobby"), - GAME_FREE4ALL("Free4All", "§6Free4All"), - GAME_TRASHGAMES("TrashGames", "§6TrashGames"); - - private String name; - private String prefix; - - ServerType(String name, String prefix) { - this.name = name; - this.prefix = prefix; - } - - public String getName() { - return name; - } - - public String getPrefix() { - return prefix; - } -} \ No newline at end of file diff --git a/src/main/java/eu/univento/core/api/shop/ShopCategory.java b/src/main/java/eu/univento/core/api/shop/ShopCategory.java index bb2a80d..12ec21b 100644 --- a/src/main/java/eu/univento/core/api/shop/ShopCategory.java +++ b/src/main/java/eu/univento/core/api/shop/ShopCategory.java @@ -1,6 +1,6 @@ package eu.univento.core.api.shop; -import eu.univento.core.api.server.ServerType; +import eu.univento.cloud.commons.server.ServerType; /** * @author joethei diff --git a/src/main/java/eu/univento/core/listeners/Blocks.java b/src/main/java/eu/univento/core/listeners/Blocks.java index 7e1441c..b7b4af0 100644 --- a/src/main/java/eu/univento/core/listeners/Blocks.java +++ b/src/main/java/eu/univento/core/listeners/Blocks.java @@ -23,9 +23,8 @@ public class Blocks implements Listener{ @EventHandler public void onBlockPlace(BlockPlaceEvent e) { CustomPlayer p = CustomPlayer.getPlayer(e.getPlayer()); - if(!Build.getPlayers().containsKey(p)) { + if(!Build.getPlayers().containsKey(p)) e.setCancelled(true); - } } /** @@ -35,9 +34,8 @@ public class Blocks implements Listener{ @EventHandler public void onBlockBreak(BlockBreakEvent e) { CustomPlayer p = CustomPlayer.getPlayer(e.getPlayer()); - if(!Build.getPlayers().containsKey(p)) { + if(!Build.getPlayers().containsKey(p)) e.setCancelled(true); - } } diff --git a/src/main/java/eu/univento/core/listeners/Chat.java b/src/main/java/eu/univento/core/listeners/Chat.java index b9d23ec..f67fc6b 100644 --- a/src/main/java/eu/univento/core/listeners/Chat.java +++ b/src/main/java/eu/univento/core/listeners/Chat.java @@ -52,7 +52,7 @@ public class Chat implements Listener { ShopMenu menu = new ShopMenu(Core.getInstance(), "Shop Villager", ShopItem.TestItem); new ShopVillager(Core.getInstance(), "Shop Villager", p.getLocation(), Villager.Profession.LIBRARIAN, menu); } - if(e.getMessage().equalsIgnoreCase("miniblock")) { + if (e.getMessage().equalsIgnoreCase("miniblock")) { new MiniBlock(p.getLocation(), new ItemStack(Material.GRASS), 1); new MiniBlock(p.getEyeLocation(), new ItemStack(Material.DIAMOND_SWORD), 2); new MiniBlock(p.getWorld().getSpawnLocation(), new ItemStack(Material.WOOL), 3); @@ -73,13 +73,12 @@ public class Chat implements Listener { e.setCancelled(true); p.sendMessage("§cDu musst dich bewegen bevor du chatten kannst"); } - if(!spam.containsKey(p)) spam.put(p, System.currentTimeMillis()); - if(System.currentTimeMillis() - spam.get(p) < 5 * 20L) { + if (System.currentTimeMillis() - spam.get(p) < 5 * 20L) { e.setCancelled(true); p.sendMessage("Nicht spammen"); spamPlayers.put(p, spamPlayers.get(p) + 1); } - if(spamPlayers.get(p) >= 100) { + if (spamPlayers.get(p) > 100) { p.warn(WarnReason.SPAM, null, "https://players.univento.eu/" + p.getUniqueId().toString() + "/chatlog"); } @@ -90,23 +89,24 @@ public class Chat implements Listener { sum += part; } double ratio = sum / parts.length; - int percent = (int)(100.0D * ratio); + int percent = (int) (100.0D * ratio); - if(percent > 50) { + if (percent < 50) { e.setCancelled(true); p.sendMessage("§cKeine Caps verwenden"); } - String format; + String message = e.getMessage(); + if (e.getFormat().contains("%")) message = message.replace("%", "%%"); if (p.getDatabasePlayer().isAllowed(Rank.Partner)) { if (p.getDatabasePlayer().getSettings().isNicked() && !ServerSettings.isLobby()) { - format = p.getDatabasePlayer().getRank().getPrefix() + p.getDatabasePlayer().getRank().getColor() + p.getDisplayName() + p.getDatabasePlayer().getRank().getSuffix() + ChatColor.translateAlternateColorCodes('&', e.getMessage()); - } else { - format = p.getDatabasePlayer().getRank().getPrefix() + p.getDisplayName() + p.getDatabasePlayer().getRank().getSuffix() + e.getMessage(); + e.setFormat(p.getDatabasePlayer().getRank().getPrefix() + p.getDatabasePlayer().getRank().getColor() + p.getDisplayName() + p.getDatabasePlayer().getRank().getSuffix() + ChatColor.translateAlternateColorCodes('&', message)); + }else{ + e.setFormat(p.getDatabasePlayer().getRank().getPrefix() + p.getDisplayName() + p.getDatabasePlayer().getRank().getSuffix() + ChatColor.translateAlternateColorCodes('&', message)); } - if (format.contains("%")) format = format.replace("%", "%%"); - e.setFormat(format); - Core.getOnlinePlayers().stream().filter(player -> e.getMessage().toLowerCase().contains(player.getDisplayName().toLowerCase()) || e.getMessage().toLowerCase().contains(player.getName().toLowerCase())).forEach(player -> p.playSound(p.getEyeLocation(), Sound.BLOCK_NOTE_PLING, 100.0F, 1.0F)); + }else{ + e.setFormat(p.getDatabasePlayer().getRank().getPrefix() + p.getDisplayName() + p.getDatabasePlayer().getRank().getSuffix() + message); + Core.getOnlinePlayers().stream().filter(player -> e.getMessage().toLowerCase().contains(player.getDisplayName().toLowerCase()) || e.getMessage().toLowerCase().contains(player.getName().toLowerCase())).forEach(player -> player.playSound(p.getEyeLocation(), Sound.BLOCK_NOTE_PLING, 100.0F, 1.0F)); } } @@ -114,13 +114,15 @@ public class Chat implements Listener { public void onPlayerJoin(PlayerJoinEvent e) { CustomPlayer p = CustomPlayer.getPlayer(e.getPlayer()); players.add(p); + spamPlayers.put(p, 0); + spam.put(p, System.currentTimeMillis()); } @EventHandler public void onPlayerQuit(PlayerQuitEvent e) { CustomPlayer p = CustomPlayer.getPlayer(e.getPlayer()); - if(players.contains(p)) players.remove(p); - if(spam.containsKey(p)) spam.remove(p); + if (players.contains(p)) players.remove(p); + if (spam.containsKey(p)) spam.remove(p); } @EventHandler diff --git a/src/main/java/eu/univento/core/listeners/Commands.java b/src/main/java/eu/univento/core/listeners/Commands.java index 8ce34c1..6fa84f8 100644 --- a/src/main/java/eu/univento/core/listeners/Commands.java +++ b/src/main/java/eu/univento/core/listeners/Commands.java @@ -2,10 +2,8 @@ package eu.univento.core.listeners; import eu.univento.commons.player.Rank; import eu.univento.core.Core; -import eu.univento.core.api.languages.Messages; import eu.univento.core.api.player.CustomPlayer; import org.bukkit.Bukkit; -import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; @@ -27,12 +25,11 @@ public class Commands implements Listener{ @EventHandler(priority = EventPriority.NORMAL) public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent e) { CustomPlayer p = CustomPlayer.getPlayer(e.getPlayer()); - Messages msgs = new Messages(p); if (!e.isCancelled()) { String cmd = e.getMessage().split(" ")[0]; HelpTopic topic = Bukkit.getServer().getHelpMap().getHelpTopic(cmd); if (topic == null) { - p.sendMessage(msgs.COMMAND_NOT_FOUND()); + p.sendMessage(p.getDatabasePlayer().getMessage("Command.not_found")); e.setCancelled(true); } } @@ -40,15 +37,14 @@ public class Commands implements Listener{ if(cmd.equalsIgnoreCase("/rl") || cmd.equalsIgnoreCase("/reload")) { if(p.getDatabasePlayer().isAllowed(Rank.Admin)) { e.setCancelled(true); - Bukkit.broadcastMessage(msgs.PREFIX() + "§cWarning ! Server will be restarted"); Bukkit.getScheduler().scheduleSyncDelayedTask(Core.getInstance(), () -> { - for(Player players : Bukkit.getOnlinePlayers()) { - players.kickPlayer("§cServer has been restarted \n §6Please join again at: \n §bplay§5.§6univento§5.§aeu"); + for(CustomPlayer players : Core.getOnlinePlayers()) { + players.connectToServer("Lobby01"); } - Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "/restart"); + Bukkit.spigot().restart(); }, 100L); }else { - p.sendMessage(msgs.NO_PERMS()); + p.sendMessage(p.getDatabasePlayer().getMessage("Command.no_perms")); } } } diff --git a/src/main/java/eu/univento/core/listeners/Events.java b/src/main/java/eu/univento/core/listeners/Events.java index baabe5b..d1bbb26 100644 --- a/src/main/java/eu/univento/core/listeners/Events.java +++ b/src/main/java/eu/univento/core/listeners/Events.java @@ -32,7 +32,8 @@ public class Events implements Listener{ public void onMove(PlayerMoveEvent e) { CustomPlayer p = CustomPlayer.getPlayer(e.getPlayer()); if(p.getLocation().getY() <= 0) { - p.setVelocity(new Vector().setY(4.0D).multiply(1.0D)); + p.setVelocity(new Vector().setY(10.0D).multiply(1.0D)); + p.setGliding(true); } } diff --git a/src/main/java/eu/univento/core/listeners/JoinQuit.java b/src/main/java/eu/univento/core/listeners/JoinQuit.java index b4f733a..d6e6837 100644 --- a/src/main/java/eu/univento/core/listeners/JoinQuit.java +++ b/src/main/java/eu/univento/core/listeners/JoinQuit.java @@ -39,19 +39,16 @@ public class JoinQuit implements Listener { for (Player players : Bukkit.getOnlinePlayers()) { CustomPlayer player = CustomPlayer.getPlayer(players); - if (Vanish.getPlayers().contains(player)) { + if (Vanish.getPlayers().contains(player)) p.hidePlayer(player); - } - if (SpectateManager.contains(player)) { + if (SpectateManager.contains(player)) p.hidePlayer(player); - } } if (!p.hasPlayedBefore()) { firstJoin.add(p); - for (int i = 0; i <= 15; i++) { + for (int i = 0; i <= 15; i++) Utils.randomFirework(p.getEyeLocation()); - } } if (!p.isOnline()) { HashMap labyModFeatures = new HashMap<>(); diff --git a/src/main/java/eu/univento/core/listeners/PluginMessenger.java b/src/main/java/eu/univento/core/listeners/PluginMessenger.java index dd0bbf8..db1ab78 100644 --- a/src/main/java/eu/univento/core/listeners/PluginMessenger.java +++ b/src/main/java/eu/univento/core/listeners/PluginMessenger.java @@ -38,7 +38,10 @@ public class PluginMessenger implements PluginMessageListener { try { String version = new String(data, "UTF-8"); Core.getCommons().getLoggingHandler().getCore().info(p.getName() + " hat den 5zig Mod Version : " + version); - //TODO: disable only some 5zig mod settings | https://gist.github.com/5zig/35e0854504edda418f4b + //https://gist.github.com/5zig/35e0854504edda418f4b shows why + ByteArrayDataOutput dataOutput = ByteStreams.newDataOutput(); + dataOutput.writeByte(0x01 | 0x02 | 0x02 | 0x04 | 0x08 | 0x010); + p.sendPluginMessage(Core.getInstance(), "5zig_Set", dataOutput.toByteArray()); p.sendPluginMessage(Core.getInstance(), "5zig_Set", new byte[]{0x01 | 0x02 | 0x04 | 0x08 | 0x10}); } catch (UnsupportedEncodingException e) { e.printStackTrace(); @@ -46,16 +49,17 @@ public class PluginMessenger implements PluginMessageListener { } } + //TODO: private byte[] createWDLPacket(int saveRadius, boolean cacheChunks, boolean saveEntities, boolean saveTileEntities, boolean saveContainers) { ByteArrayDataOutput output = ByteStreams.newDataOutput(); output.writeInt(1); - output.writeBoolean(false); - output.writeInt(0); - output.writeBoolean(false); - output.writeBoolean(false); - output.writeBoolean(false); + output.writeBoolean(cacheChunks); + output.writeInt(saveRadius); + output.writeBoolean(saveEntities); + output.writeBoolean(saveTileEntities); + output.writeBoolean(saveContainers); output.writeBoolean(false); return output.toByteArray(); diff --git a/src/site/site.xml b/src/site/site.xml deleted file mode 100644 index 6630a4f..0000000 --- a/src/site/site.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - Maven - https://pbs.twimg.com/profile_banners/4068816154/1463424334 - http://univento.eu - - - org.apache.maven.skins - maven-fluido-skin - 1.5 - - - - - - - - - - - - - \ No newline at end of file diff --git a/wiki b/wiki new file mode 160000 index 0000000..bc862c6 --- /dev/null +++ b/wiki @@ -0,0 +1 @@ +Subproject commit bc862c6330f5f52e6be9c91f2f3a240ca15ffcb4