From 4e5366272bc19bf38f0f52a5b9ab16af75ac8e7f Mon Sep 17 00:00:00 2001 From: md_5 Date: Sun, 2 Jun 2013 10:36:24 +1000 Subject: [PATCH 01/19] POM Changes --- pom.xml | 44 ++++++++++++-------------------------------- 1 file changed, 12 insertions(+), 32 deletions(-) diff --git a/pom.xml b/pom.xml index dfdcbdf3..2d1df202 100644 --- a/pom.xml +++ b/pom.xml @@ -1,43 +1,23 @@ 4.0.0 - org.bukkit - bukkit + + + org.spigotmc + spigot-parent + dev-SNAPSHOT + ../pom.xml + + + org.spigotmc + spigot-api 1.6.4-R0.1-SNAPSHOT - Bukkit - http://www.bukkit.org + Spigot-API + http://www.spigotmc.org UTF-8 - - scm:git:git@github.com:Bukkit/Bukkit.git - scm:git:git://github.com/Bukkit/Bukkit.git - https://github.com/Bukkit/Bukkit/tree/master/ - - - - jenkins - http://ci.bukkit.org - - - - - jd.bukkit.org - file:///home/javadocs/public_html/ - - - repobo-rel - repo.bukkit.org Releases - http://repo.bukkit.org/content/repositories/releases/ - - - repobo-snap - repo.bukkit.org Snapshots - http://repo.bukkit.org/content/repositories/snapshots/ - - - From 7c39ad668156860fc8d65ef67d5d2f91f6ab9853 Mon Sep 17 00:00:00 2001 From: Aikar Date: Sun, 2 Jun 2013 10:42:57 +1000 Subject: [PATCH 02/19] Measure Timings Duration --- src/main/java/org/bukkit/command/defaults/TimingsCommand.java | 4 ++++ src/main/java/org/bukkit/plugin/SimplePluginManager.java | 1 + 2 files changed, 5 insertions(+) diff --git a/src/main/java/org/bukkit/command/defaults/TimingsCommand.java b/src/main/java/org/bukkit/command/defaults/TimingsCommand.java index 05cfcb01..c2874f1f 100644 --- a/src/main/java/org/bukkit/command/defaults/TimingsCommand.java +++ b/src/main/java/org/bukkit/command/defaults/TimingsCommand.java @@ -21,6 +21,7 @@ public class TimingsCommand extends BukkitCommand { private static final List TIMINGS_SUBCOMMANDS = ImmutableList.of("merged", "reset", "separate"); + public static long timingStart = 0; // Spigot public TimingsCommand(String name) { super(name); @@ -50,9 +51,11 @@ public boolean execute(CommandSender sender, String currentAlias, String[] args) } } } + timingStart = System.nanoTime(); // Spigot sender.sendMessage("Timings reset"); } else if ("merged".equals(args[0]) || separate) { + long sampleTime = System.nanoTime() - timingStart; // Spigot int index = 0; int pluginIdx = 0; File timingFolder = new File("timings"); @@ -92,6 +95,7 @@ public boolean execute(CommandSender sender, String currentAlias, String[] args) } fileTimings.println(" Total time " + totalTime + " (" + totalTime / 1000000000 + "s)"); } + fileTimings.println( "Sample time " + sampleTime + " (" + sampleTime / 1E9 + "s)" ); // Spigot sender.sendMessage("Timings written to " + timings.getPath()); if (separate) sender.sendMessage("Names written to " + names.getPath()); } catch (IOException e) { diff --git a/src/main/java/org/bukkit/plugin/SimplePluginManager.java b/src/main/java/org/bukkit/plugin/SimplePluginManager.java index 93fb4f5a..a96a33b4 100644 --- a/src/main/java/org/bukkit/plugin/SimplePluginManager.java +++ b/src/main/java/org/bukkit/plugin/SimplePluginManager.java @@ -274,6 +274,7 @@ public Plugin[] loadPlugins(File directory) { } } + org.bukkit.command.defaults.TimingsCommand.timingStart = System.nanoTime(); // Spigot return result.toArray(new Plugin[result.size()]); } From 16349138fcd26973eea2b0265aa75e01d432ea45 Mon Sep 17 00:00:00 2001 From: md_5 Date: Sun, 2 Jun 2013 10:55:20 +1000 Subject: [PATCH 03/19] Timings Paste Command --- .../command/defaults/TimingsCommand.java | 70 +++++++++++++++++-- 1 file changed, 65 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/bukkit/command/defaults/TimingsCommand.java b/src/main/java/org/bukkit/command/defaults/TimingsCommand.java index c2874f1f..7c28b751 100644 --- a/src/main/java/org/bukkit/command/defaults/TimingsCommand.java +++ b/src/main/java/org/bukkit/command/defaults/TimingsCommand.java @@ -19,6 +19,15 @@ import com.google.common.collect.ImmutableList; +// Spigot start +import java.io.ByteArrayOutputStream; +import java.io.OutputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLEncoder; +import java.util.logging.Level; +// Spigot end + public class TimingsCommand extends BukkitCommand { private static final List TIMINGS_SUBCOMMANDS = ImmutableList.of("merged", "reset", "separate"); public static long timingStart = 0; // Spigot @@ -26,14 +35,14 @@ public class TimingsCommand extends BukkitCommand { public TimingsCommand(String name) { super(name); this.description = "Records timings for all plugin events"; - this.usageMessage = "/timings "; + this.usageMessage = "/timings [paste]"; // Spigot this.setPermission("bukkit.command.timings"); } @Override public boolean execute(CommandSender sender, String currentAlias, String[] args) { if (!testPermission(sender)) return true; - if (args.length != 1) { + if (args.length < 1) { // Spigot sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage); return false; } @@ -43,6 +52,7 @@ public boolean execute(CommandSender sender, String currentAlias, String[] args) } boolean separate = "separate".equals(args[0]); + boolean paste = "paste".equals( args[0] ); // Spigot if ("reset".equals(args[0])) { for (HandlerList handlerList : HandlerList.getHandlerLists()) { for (RegisteredListener listener : handlerList.getRegisteredListeners()) { @@ -53,8 +63,7 @@ public boolean execute(CommandSender sender, String currentAlias, String[] args) } timingStart = System.nanoTime(); // Spigot sender.sendMessage("Timings reset"); - } else if ("merged".equals(args[0]) || separate) { - + } else if ("merged".equals(args[0]) || separate || paste) { // Spigot long sampleTime = System.nanoTime() - timingStart; // Spigot int index = 0; int pluginIdx = 0; @@ -62,11 +71,12 @@ public boolean execute(CommandSender sender, String currentAlias, String[] args) timingFolder.mkdirs(); File timings = new File(timingFolder, "timings.txt"); File names = null; + ByteArrayOutputStream bout = ( paste ) ? new ByteArrayOutputStream() : null; // Spigot while (timings.exists()) timings = new File(timingFolder, "timings" + (++index) + ".txt"); PrintStream fileTimings = null; PrintStream fileNames = null; try { - fileTimings = new PrintStream(timings); + fileTimings = ( paste ) ? new PrintStream( bout ) : new PrintStream( timings ); if (separate) { names = new File(timingFolder, "names" + index + ".txt"); fileNames = new PrintStream(names); @@ -96,6 +106,13 @@ public boolean execute(CommandSender sender, String currentAlias, String[] args) fileTimings.println(" Total time " + totalTime + " (" + totalTime / 1000000000 + "s)"); } fileTimings.println( "Sample time " + sampleTime + " (" + sampleTime / 1E9 + "s)" ); // Spigot + // Spigot start + if ( paste ) + { + new PasteThread( sender, bout ).start(); + return true; + } + // Spigot end sender.sendMessage("Timings written to " + timings.getPath()); if (separate) sender.sendMessage("Names written to " + names.getPath()); } catch (IOException e) { @@ -122,4 +139,47 @@ public List tabComplete(CommandSender sender, String alias, String[] arg } return ImmutableList.of(); } + + // Spigot start + private static class PasteThread extends Thread + { + + private final CommandSender sender; + private final ByteArrayOutputStream bout; + + public PasteThread(CommandSender sender, ByteArrayOutputStream bout) + { + super( "Timings paste thread" ); + this.sender = sender; + this.bout = bout; + } + + @Override + public void run() + { + try + { + HttpURLConnection con = (HttpURLConnection) new URL( "http://paste.ubuntu.com/" ).openConnection(); + con.setDoOutput( true ); + con.setRequestMethod( "POST" ); + con.setInstanceFollowRedirects( false ); + + OutputStream out = con.getOutputStream(); + out.write( "poster=Spigot&syntax=text&content=".getBytes( "UTF-8" ) ); + out.write( URLEncoder.encode( bout.toString( "UTF-8" ), "UTF-8" ).getBytes( "UTF-8" ) ); + out.close(); + con.getInputStream().close(); + + String location = con.getHeaderField( "Location" ); + String pasteID = location.substring( "http://paste.ubuntu.com/".length(), location.length() - 1 ); + sender.sendMessage( ChatColor.GREEN + "Your timings have been pasted to " + location ); + sender.sendMessage( ChatColor.GREEN + "You can view the results at http://aikar.co/timings.php?url=" + pasteID ); + } catch ( IOException ex ) + { + sender.sendMessage( ChatColor.RED + "Error pasting timings, check your console for more information" ); + Bukkit.getServer().getLogger().log( Level.WARNING, "Could not paste timings", ex ); + } + } + } + // Spigot end } From ad178fb48cc5ab621220bddd3f694ccf216664ab Mon Sep 17 00:00:00 2001 From: md_5 Date: Sun, 2 Jun 2013 11:17:05 +1000 Subject: [PATCH 04/19] Enchanced Timings --- .../command/defaults/ReloadCommand.java | 1 + .../command/defaults/TimingsCommand.java | 45 ++++- .../plugin/TimedRegisteredListener.java | 21 ++- .../bukkit/plugin/java/JavaPluginLoader.java | 2 +- .../org/spigotmc/CustomTimingsHandler.java | 175 ++++++++++++++++++ .../plugin/TimedRegisteredListenerTest.java | 1 - 6 files changed, 235 insertions(+), 10 deletions(-) create mode 100644 src/main/java/org/spigotmc/CustomTimingsHandler.java diff --git a/src/main/java/org/bukkit/command/defaults/ReloadCommand.java b/src/main/java/org/bukkit/command/defaults/ReloadCommand.java index fb3c90fb..ffbcac1f 100644 --- a/src/main/java/org/bukkit/command/defaults/ReloadCommand.java +++ b/src/main/java/org/bukkit/command/defaults/ReloadCommand.java @@ -20,6 +20,7 @@ public ReloadCommand(String name) { public boolean execute(CommandSender sender, String currentAlias, String[] args) { if (!testPermission(sender)) return true; + org.spigotmc.CustomTimingsHandler.reload(); // Spigot: TODO: Why is this here? Bukkit.reload(); Command.broadcastCommandMessage(sender, ChatColor.GREEN + "Reload complete."); diff --git a/src/main/java/org/bukkit/command/defaults/TimingsCommand.java b/src/main/java/org/bukkit/command/defaults/TimingsCommand.java index 7c28b751..ec1320ff 100644 --- a/src/main/java/org/bukkit/command/defaults/TimingsCommand.java +++ b/src/main/java/org/bukkit/command/defaults/TimingsCommand.java @@ -35,7 +35,7 @@ public class TimingsCommand extends BukkitCommand { public TimingsCommand(String name) { super(name); this.description = "Records timings for all plugin events"; - this.usageMessage = "/timings [paste]"; // Spigot + this.usageMessage = "/timings [paste]"; // Spigot this.setPermission("bukkit.command.timings"); } @@ -46,14 +46,33 @@ public boolean execute(CommandSender sender, String currentAlias, String[] args) sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage); return false; } - if (!sender.getServer().getPluginManager().useTimings()) { + /*if (!sender.getServer().getPluginManager().useTimings()) { sender.sendMessage("Please enable timings by setting \"settings.plugin-profiling\" to true in bukkit.yml"); return true; + }*/ + + // Spigot start - dynamic enable + if ( "on".equals( args[0] ) ) + { + ( (org.bukkit.plugin.SimplePluginManager) Bukkit.getPluginManager() ).useTimings( true ); + sender.sendMessage( "Enabled Timings" ); + } else if ( "off".equals( args[0] ) ) + { + ( (org.bukkit.plugin.SimplePluginManager) Bukkit.getPluginManager() ).useTimings( false ); + sender.sendMessage( "Disabled Timings" ); } + // Spigot end boolean separate = "separate".equals(args[0]); boolean paste = "paste".equals( args[0] ); // Spigot - if ("reset".equals(args[0])) { + if ("on".equals(args[0]) || "reset".equals(args[0])) { // Spigot + // Spigot start + if ( !"on".equals( args[0] ) && !Bukkit.getPluginManager().useTimings() ) + { + sender.sendMessage( "Please enable timings by typing /timings on" ); + return true; + } + // Spigot end for (HandlerList handlerList : HandlerList.getHandlerLists()) { for (RegisteredListener listener : handlerList.getRegisteredListeners()) { if (listener instanceof TimedRegisteredListener) { @@ -61,10 +80,18 @@ public boolean execute(CommandSender sender, String currentAlias, String[] args) } } } - timingStart = System.nanoTime(); // Spigot + // Spigot start + org.spigotmc.CustomTimingsHandler.reload(); + timingStart = System.nanoTime(); sender.sendMessage("Timings reset"); - } else if ("merged".equals(args[0]) || separate || paste) { // Spigot - long sampleTime = System.nanoTime() - timingStart; // Spigot + } else if ("merged".equals(args[0]) || separate || paste) { + if ( !Bukkit.getPluginManager().useTimings() ) + { + sender.sendMessage( "Please enable timings by typing /timings on" ); + return true; + } + long sampleTime = System.nanoTime() - timingStart; + // Spigot end int index = 0; int pluginIdx = 0; File timingFolder = new File("timings"); @@ -99,12 +126,15 @@ public boolean execute(CommandSender sender, String currentAlias, String[] args) totalTime += time; Class eventClass = trl.getEventClass(); if (count > 0 && eventClass != null) { - fileTimings.println(" " + eventClass.getSimpleName() + (trl.hasMultiple() ? " (and sub-classes)" : "") + " Time: " + time + " Count: " + count + " Avg: " + avg); + fileTimings.println(" " + eventClass.getSimpleName() + (trl.hasMultiple() ? " (and sub-classes)" : "") + " Time: " + time + " Count: " + count + " Avg: " + avg + " Violations: " + trl.violations); // Spigot } } } fileTimings.println(" Total time " + totalTime + " (" + totalTime / 1000000000 + "s)"); } + + // Spigot start + org.spigotmc.CustomTimingsHandler.printTimings(fileTimings); fileTimings.println( "Sample time " + sampleTime + " (" + sampleTime / 1E9 + "s)" ); // Spigot // Spigot start if ( paste ) @@ -114,6 +144,7 @@ public boolean execute(CommandSender sender, String currentAlias, String[] args) } // Spigot end sender.sendMessage("Timings written to " + timings.getPath()); + sender.sendMessage( "Paste contents of file into form at http://aikar.co/timings.php to read results." ); if (separate) sender.sendMessage("Names written to " + names.getPath()); } catch (IOException e) { } finally { diff --git a/src/main/java/org/bukkit/plugin/TimedRegisteredListener.java b/src/main/java/org/bukkit/plugin/TimedRegisteredListener.java index d86805b9..4b744eaa 100644 --- a/src/main/java/org/bukkit/plugin/TimedRegisteredListener.java +++ b/src/main/java/org/bukkit/plugin/TimedRegisteredListener.java @@ -11,6 +11,10 @@ public class TimedRegisteredListener extends RegisteredListener { private int count; private long totalTime; + // Spigot start + public long curTickTotal = 0; + public long violations = 0; + // Spigot end private Class eventClass; private boolean multiple = false; @@ -20,6 +24,13 @@ public TimedRegisteredListener(final Listener pluginListener, final EventExecuto @Override public void callEvent(Event event) throws EventException { + // Spigot start + if ( org.bukkit.Bukkit.getServer() != null && !org.bukkit.Bukkit.getServer().getPluginManager().useTimings() ) + { + super.callEvent( event ); + return; + } + // Spigot end if (event.isAsynchronous()) { super.callEvent(event); return; @@ -34,7 +45,11 @@ public void callEvent(Event event) throws EventException { } long start = System.nanoTime(); super.callEvent(event); - totalTime += System.nanoTime() - start; + // Spigot start + long diff = System.nanoTime() - start; + curTickTotal += diff; + totalTime += diff; + // Spigot end } private static Class getCommonSuperclass(Class class1, Class class2) { @@ -50,6 +65,10 @@ private static Class getCommonSuperclass(Class class1, Class class2) { public void reset() { count = 0; totalTime = 0; + // Spigot start + curTickTotal = 0; + violations = 0; + // Spigot end } /** diff --git a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java index ea30d83d..d905435a 100644 --- a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java +++ b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java @@ -430,7 +430,7 @@ public void execute(Listener listener, Event event) throws EventException { } } }; - if (useTimings) { + if (true) { // Spigot - TRL handles useTimings check now eventSet.add(new TimedRegisteredListener(listener, executor, eh.priority(), plugin, eh.ignoreCancelled())); } else { eventSet.add(new RegisteredListener(listener, executor, eh.priority(), plugin, eh.ignoreCancelled())); diff --git a/src/main/java/org/spigotmc/CustomTimingsHandler.java b/src/main/java/org/spigotmc/CustomTimingsHandler.java new file mode 100644 index 00000000..9fca481d --- /dev/null +++ b/src/main/java/org/spigotmc/CustomTimingsHandler.java @@ -0,0 +1,175 @@ +package org.spigotmc; + +import org.bukkit.event.HandlerList; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.RegisteredListener; +import org.bukkit.plugin.TimedRegisteredListener; +import java.io.PrintStream; +import java.util.Collection; +import java.util.HashSet; +import org.bukkit.Bukkit; +import org.bukkit.World; + +/** + * Provides custom timing sections for /timings merged. + */ +public class CustomTimingsHandler +{ + + private static final Collection ALL_HANDLERS = new HashSet(); + private static CustomTimingsHandler[] BAKED_HANDLERS; + /*========================================================================*/ + private final String name; + private final CustomTimingsHandler parent; + private long count = 0; + private long start = 0; + private long timingDepth = 0; + private long totalTime = 0; + private long curTickTotal = 0; + private long violations = 0; + + public CustomTimingsHandler(String name) + { + this( name, null ); + } + + public CustomTimingsHandler(String name, CustomTimingsHandler parent) + { + this.name = name; + this.parent = parent; + ALL_HANDLERS.add( this ); + BAKED_HANDLERS = ALL_HANDLERS.toArray( new CustomTimingsHandler[ ALL_HANDLERS.size() ] ); + } + + /** + * Prints the timings and extra data to the given stream. + * + * @param printStream + */ + public static void printTimings(PrintStream printStream) + { + printStream.println( "Minecraft" ); + for ( CustomTimingsHandler timings : BAKED_HANDLERS ) + { + long time = timings.totalTime; + long count = timings.count; + if ( count == 0 ) + { + continue; + } + long avg = time / count; + + printStream.println( " " + timings.name + " Time: " + time + " Count: " + count + " Avg: " + avg + " Violations: " + timings.violations ); + } + printStream.println( "# Version " + Bukkit.getVersion() ); + int entities = 0; + int livingEntities = 0; + for ( World world : Bukkit.getWorlds() ) + { + entities += world.getEntities().size(); + livingEntities += world.getLivingEntities().size(); + } + printStream.println( "# Entities " + entities ); + printStream.println( "# LivingEntities " + livingEntities ); + } + + /** + * Resets all timings. + */ + public static void reload() + { + if ( Bukkit.getPluginManager().useTimings() ) + { + for ( CustomTimingsHandler timings : BAKED_HANDLERS ) + { + timings.reset(); + } + } + } + + /** + * Ticked every tick by CraftBukkit to count the number of times a timer + * caused TPS loss. + */ + public static void tick() + { + if ( Bukkit.getPluginManager().useTimings() ) + { + for ( CustomTimingsHandler timings : BAKED_HANDLERS ) + { + if ( timings.curTickTotal > 50000000 ) + { + timings.violations += Math.ceil( timings.curTickTotal / 50000000 ); + } + timings.curTickTotal = 0; + timings.timingDepth = 0; // incase reset messes this up + } + + for ( Plugin plugin : Bukkit.getPluginManager().getPlugins() ) + { + for ( RegisteredListener listener : HandlerList.getRegisteredListeners( plugin ) ) + { + if ( listener instanceof TimedRegisteredListener ) + { + TimedRegisteredListener timings = (TimedRegisteredListener) listener; + if ( timings.curTickTotal > 50000000 ) + { + timings.violations += Math.ceil( timings.curTickTotal / 50000000 ); + } + timings.curTickTotal = 0; + } + } + } + } + } + + /** + * Starts timing to track a section of code. + */ + public void startTiming() + { + // If second condtion fails we are already timing + if ( Bukkit.getPluginManager().useTimings() && ++timingDepth == 1 ) + { + start = System.nanoTime(); + if ( parent != null && ++parent.timingDepth == 1 ) + { + parent.start = start; + } + } + } + + /** + * Stops timing a section of code. + */ + public void stopTiming() + { + if ( Bukkit.getPluginManager().useTimings() ) + { + if ( --timingDepth != 0 || start == 0 ) + { + return; + } + long diff = System.nanoTime() - start; + totalTime += diff; + curTickTotal += diff; + count++; + start = 0; + if ( parent != null ) + { + parent.stopTiming(); + } + } + } + + /** + * Reset this timer, setting all values to zero. + */ + public void reset() + { + count = 0; + violations = 0; + curTickTotal = 0; + totalTime = 0; + } +} diff --git a/src/test/java/org/bukkit/plugin/TimedRegisteredListenerTest.java b/src/test/java/org/bukkit/plugin/TimedRegisteredListenerTest.java index b206b1f3..01b62fb5 100644 --- a/src/test/java/org/bukkit/plugin/TimedRegisteredListenerTest.java +++ b/src/test/java/org/bukkit/plugin/TimedRegisteredListenerTest.java @@ -15,7 +15,6 @@ public class TimedRegisteredListenerTest { - @Test public void testEventClass() throws EventException { Listener listener = new Listener() {}; EventExecutor executor = new EventExecutor() { From 5bfbb73a891f15b691895a41e57e186ecbde1b8f Mon Sep 17 00:00:00 2001 From: md_5 Date: Mon, 4 Mar 2013 18:31:20 +1100 Subject: [PATCH 05/19] Add PlayerItemDamageEvent --- .../event/player/PlayerItemDamageEvent.java | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 src/main/java/org/bukkit/event/player/PlayerItemDamageEvent.java diff --git a/src/main/java/org/bukkit/event/player/PlayerItemDamageEvent.java b/src/main/java/org/bukkit/event/player/PlayerItemDamageEvent.java new file mode 100644 index 00000000..38a72ab8 --- /dev/null +++ b/src/main/java/org/bukkit/event/player/PlayerItemDamageEvent.java @@ -0,0 +1,54 @@ +package org.bukkit.event.player; + +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.inventory.ItemStack; + +public class PlayerItemDamageEvent extends PlayerEvent implements Cancellable { + + private static final HandlerList handlers = new HandlerList(); + private final ItemStack item; + private int damage; + private boolean cancelled = false; + + public PlayerItemDamageEvent(Player player, ItemStack what, int damage) { + super(player); + this.item = what; + this.damage = damage; + } + + public ItemStack getItem() { + return item; + } + + /** + * Gets the amount of durability damage this item will be taking. + * + * @return durability change + */ + public int getDamage() { + return damage; + } + + public void setDamage(int damage) { + this.damage = damage; + } + + public boolean isCancelled() { + return cancelled; + } + + public void setCancelled(boolean cancel) { + this.cancelled = cancel; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} From 5a9d48d12531234b4c5f77db11782548495533bd Mon Sep 17 00:00:00 2001 From: md_5 Date: Sun, 2 Jun 2013 15:20:49 +1000 Subject: [PATCH 06/19] BungeeCord Support --- src/main/java/org/bukkit/entity/Player.java | 19 +++++++++++++ .../bukkit/event/player/PlayerLoginEvent.java | 27 ++++++++++++++++--- 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java index 3ec374b4..cc9c3b22 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java @@ -721,4 +721,23 @@ public interface Player extends HumanEntity, Conversable, CommandSender, Offline * @see Player#setHealthScaled(boolean) */ public double getHealthScale(); + + // Spigot start + public class Spigot extends Entity.Spigot + { + + /** + * Gets the connection address of this player, regardless of whether it + * has been spoofed or not. + * + * @return the player's connection address + */ + public InetSocketAddress getRawAddress() + { + throw new UnsupportedOperationException( "Not supported yet." ); + } + } + + Spigot spigot(); + // Spigot end } diff --git a/src/main/java/org/bukkit/event/player/PlayerLoginEvent.java b/src/main/java/org/bukkit/event/player/PlayerLoginEvent.java index 60c08756..dab3c5c0 100644 --- a/src/main/java/org/bukkit/event/player/PlayerLoginEvent.java +++ b/src/main/java/org/bukkit/event/player/PlayerLoginEvent.java @@ -14,6 +14,7 @@ public class PlayerLoginEvent extends PlayerEvent { private final String hostname; private Result result = Result.ALLOWED; private String message = ""; + private final InetAddress realAddress; // Spigot /** * @deprecated Address should be provided in other constructor @@ -38,10 +39,17 @@ public PlayerLoginEvent(final Player player, final String hostname) { * @param hostname The hostname that was used to connect to the server * @param address The address the player used to connect, provided for timing issues */ - public PlayerLoginEvent(final Player player, final String hostname, final InetAddress address) { + public PlayerLoginEvent(final Player player, final String hostname, final InetAddress address, final InetAddress realAddress) { // Spigot super(player); this.hostname = hostname; this.address = address; + // Spigot start + this.realAddress = address; + } + + public PlayerLoginEvent(final Player player, final String hostname, final InetAddress address) { + this(player, hostname, address, address); + // Spigot end } /** @@ -49,7 +57,7 @@ public PlayerLoginEvent(final Player player, final String hostname, final InetAd */ @Deprecated public PlayerLoginEvent(final Player player, final Result result, final String message) { - this(player, "", null, result, message); + this(player, "", null, result, message, null); // Spigot } /** @@ -61,12 +69,23 @@ public PlayerLoginEvent(final Player player, final Result result, final String m * @param result The result status for this event * @param message The message to be displayed if result denies login */ - public PlayerLoginEvent(final Player player, String hostname, final InetAddress address, final Result result, final String message) { - this(player, hostname, address); + public PlayerLoginEvent(final Player player, String hostname, final InetAddress address, final Result result, final String message, final InetAddress realAddress) { // Spigot + this(player, hostname, address, realAddress); // Spigot this.result = result; this.message = message; } + // Spigot start + /** + * Gets the connection address of this player, regardless of whether it has been spoofed or not. + * + * @return the player's connection address + */ + public InetAddress getRealAddress() { + return realAddress; + } + // Spigot end + /** * Gets the current result of the login, as an enum * From 2aa215242a5a0b115a6e94e4b0246422dadd3a0c Mon Sep 17 00:00:00 2001 From: md_5 Date: Sun, 2 Jun 2013 15:08:24 +1000 Subject: [PATCH 07/19] Add Arrow API --- src/main/java/org/bukkit/entity/Arrow.java | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/bukkit/entity/Arrow.java b/src/main/java/org/bukkit/entity/Arrow.java index 26d34739..676fe2bf 100644 --- a/src/main/java/org/bukkit/entity/Arrow.java +++ b/src/main/java/org/bukkit/entity/Arrow.java @@ -3,4 +3,22 @@ /** * Represents an arrow. */ -public interface Arrow extends Projectile {} +public interface Arrow extends Projectile +{ + + public class Spigot extends Entity.Spigot + { + + public double getDamage() + { + throw new UnsupportedOperationException( "Not supported yet." ); + } + + public void setDamage(double damage) + { + throw new UnsupportedOperationException( "Not supported yet." ); + } + } + + Spigot spigot(); +} From 7f39697735685b815d19724d7fa964b3d976d01f Mon Sep 17 00:00:00 2001 From: md_5 Date: Sun, 2 Jun 2013 15:57:09 +1000 Subject: [PATCH 08/19] Add Particle API --- src/main/java/org/bukkit/Effect.java | 195 +++++++++++++++++++- src/main/java/org/bukkit/World.java | 50 +++++ src/main/java/org/bukkit/entity/Player.java | 5 + src/test/java/org/bukkit/EffectTest.java | 6 +- 4 files changed, 248 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/bukkit/Effect.java b/src/main/java/org/bukkit/Effect.java index 708bee92..62c7c114 100644 --- a/src/main/java/org/bukkit/Effect.java +++ b/src/main/java/org/bukkit/Effect.java @@ -5,6 +5,7 @@ import com.google.common.collect.Maps; import org.bukkit.block.BlockFace; +import org.bukkit.material.MaterialData; import org.bukkit.potion.Potion; /** @@ -78,27 +79,178 @@ public enum Effect { /** * The flames seen on a mobspawner; a visual effect. */ - MOBSPAWNER_FLAMES(2004, Type.VISUAL); + MOBSPAWNER_FLAMES(2004, Type.VISUAL), + /** + * The spark that comes off a fireworks + */ + FIREWORKS_SPARK("fireworksSpark", Type.PARTICLE), + /** + * Critical hit particles + */ + CRIT("crit", Type.PARTICLE), + /** + * Blue critical hit particles + */ + MAGIC_CRIT("magicCrit", Type.PARTICLE), + /** + * Multicolored potion effect particles + */ + POTION_SWIRL("mobSpell", Type.PARTICLE), + /** + * Multicolored potion effect particles that are slightly transparent + */ + POTION_SWIRL_TRANSPARENT("mobSpellAmbient", Type.PARTICLE), + /** + * A puff of white potion swirls + */ + SPELL("spell", Type.PARTICLE), + /** + * A puff of white stars + */ + INSTANT_SPELL("instantSpell", Type.PARTICLE), + /** + * A puff of purple particles + */ + WITCH_MAGIC("witchMagic", Type.PARTICLE), + /** + * The note that appears above note blocks + */ + NOTE("note", Type.PARTICLE), + /** + * The particles shown at nether portals + */ + PORTAL("portal", Type.PARTICLE), + /** + * The symbols that fly towards the enchantment table + */ + FLYING_GLYPH("enchantmenttable", Type.PARTICLE), + /** + * Fire particles + */ + FLAME("flame", Type.PARTICLE), + /** + * The particles that pop out of lava + */ + LAVA_POP("lava", Type.PARTICLE), + /** + * A small gray square + */ + FOOTSTEP("footstep", Type.PARTICLE), + /** + * Water particles + */ + SPLASH("splash", Type.PARTICLE), + /** + * Smoke particles + */ + PARTICLE_SMOKE("smoke", Type.PARTICLE), + /** + * The biggest explosion particle effect + */ + EXPLOSION_HUGE("hugeexplosion", Type.PARTICLE), + /** + * A larger version of the explode particle + */ + EXPLOSION_LARGE("largeexplode", Type.PARTICLE), + /** + * Explosion particles + */ + EXPLOSION("explode", Type.PARTICLE), + /** + * Small gray particles + */ + VOID_FOG("depthsuspend", Type.PARTICLE), + /** + * Small gray particles + */ + SMALL_SMOKE("townaura", Type.PARTICLE), + /** + * A puff of white smoke + */ + CLOUD("cloud", Type.PARTICLE), + /** + * Multicolored dust particles + */ + COLOURED_DUST("reddust", Type.PARTICLE), + /** + * Snowball breaking + */ + SNOWBALL_BREAK("snowballpoof", Type.PARTICLE), + /** + * The water drip particle that appears on blocks under water + */ + WATERDRIP("dripWater", Type.PARTICLE), + /** + * The lava drip particle that appears on blocks under lava + */ + LAVADRIP("dripLava", Type.PARTICLE), + /** + * White particles + */ + SNOW_SHOVEL("snowshovel", Type.PARTICLE), + /** + * The particle shown when a slime jumps + */ + SLIME("slime", Type.PARTICLE), + /** + * The particle that appears when breading animals + */ + HEART("heart", Type.PARTICLE), + /** + * The particle that appears when hitting a villager + */ + VILLAGER_THUNDERCLOUD("angryVillager", Type.PARTICLE), + /** + * The particle that appears when trading with a villager + */ + HAPPY_VILLAGER("happyVillager", Type.PARTICLE), + /** + * The particles generated when a tool breaks. + * This particle requires a Material so that the client can select the correct texture. + */ + ITEM_BREAK("iconcrack", Type.PARTICLE, Material.class), + /** + * The particles generated while breaking a block. + * This particle requires a Material and data value so that the client can select the correct texture. + */ + TILE_BREAK("tilecrack", Type.PARTICLE, MaterialData.class); private final int id; private final Type type; private final Class data; private static final Map BY_ID = Maps.newHashMap(); + private static final Map BY_NAME = Maps.newHashMap(); + private final String particleName; - Effect(int id, Type type) { + private Effect(int id, Type type) { this(id,type,null); } - Effect(int id, Type type, Class data) { + private Effect(int id, Type type, Class data) { this.id = id; this.type = type; this.data = data; + particleName = null; + } + + private Effect(String particleName, Type type, Class data) { + this.particleName = particleName; + this.type = type; + id = 0; + this.data = data; + } + + private Effect(String particleName, Type type) { + this.particleName = particleName; + this.type = type; + id = 0; + this.data = null; } /** * Gets the ID for this effect. * - * @return ID of this effect + * @return if this Effect isn't of type PARTICLE it returns ID of this effect * @deprecated Magic value */ @Deprecated @@ -106,6 +258,15 @@ public int getId() { return this.id; } + /** + * Returns the effect's name. This returns null if the effect is not a particle + * + * @return The effect's name + */ + public String getName() { + return particleName; + } + /** * @return The type of the effect. */ @@ -114,7 +275,7 @@ public Type getType() { } /** - * @return The class which represents data for this effect, or null if none + * @return if this Effect isn't of type PARTICLE it returns the class which represents data for this effect, or null if none */ public Class getData() { return this.data; @@ -134,12 +295,32 @@ public static Effect getById(int id) { static { for (Effect effect : values()) { - BY_ID.put(effect.id, effect); + if (effect.type != Type.PARTICLE) { + BY_ID.put(effect.id, effect); + } + } + } + + /** + * Gets the Effect associated with the given name. + * + * @param name name of the Effect to return + * @return Effect with the given name + */ + public static Effect getByName(String name) { + return BY_NAME.get(name); + } + + static { + for (Effect effect : values()) { + if (effect.type == Type.PARTICLE) { + BY_NAME.put(effect.particleName, effect); + } } } /** * Represents the type of an effect. */ - public enum Type {SOUND, VISUAL} + public enum Type {SOUND, VISUAL, PARTICLE} } diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java index 62fadda7..39c72c5c 100644 --- a/src/main/java/org/bukkit/World.java +++ b/src/main/java/org/bukkit/World.java @@ -1070,6 +1070,56 @@ public interface World extends PluginMessageRecipient, Metadatable { */ public boolean isGameRule(String rule); + // Spigot start + public class Spigot + { + + /** + * Plays an effect to all players within a default radius around a given + * location. + * + * @param location the {@link Location} around which players must be to + * see the effect + * @param effect the {@link Effect} + * @throws IllegalArgumentException if the location or effect is null. + * It also throws when the effect requires a material or a material data + */ + public void playEffect(Location location, Effect effect) + { + throw new UnsupportedOperationException( "Not supported yet." ); + } + + /** + * Plays an effect to all players within a default radius around a given + * location. The effect will use the provided material (and material + * data if required). The particle's position on the client will be the + * given location, adjusted on each axis by a normal distribution with + * mean 0 and standard deviation given in the offset parameters, each + * particle has independently calculated offsets. The effect will have + * the given speed and particle count if the effect is a particle. Some + * effect will create multiple particles. + * + * @param location the {@link Location} around which players must be to + * see the effect + * @param effect effect the {@link Effect} + * @param id the item/block/data id for the effect + * @param data the data value of the block/item for the effect + * @param offsetX the amount to be randomly offset by in the X axis + * @param offsetY the amount to be randomly offset by in the Y axis + * @param offsetZ the amount to be randomly offset by in the Z axis + * @param speed the speed of the particles + * @param particleCount the number of particles + * @param radius the radius around the location + */ + public void playEffect(Location location, Effect effect, int id, int data, float offsetX, float offsetY, float offsetZ, float speed, int particleCount, int radius) + { + throw new UnsupportedOperationException( "Not supported yet." ); + } + } + + Spigot spigot(); + // Spigot end + /** * Represents various map environment types that a world may be */ diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java index cc9c3b22..8eab616f 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java @@ -736,6 +736,11 @@ public InetSocketAddress getRawAddress() { throw new UnsupportedOperationException( "Not supported yet." ); } + + public void playEffect(Location location, Effect effect, int id, int data, float offsetX, float offsetY, float offsetZ, float speed, int particleCount, int radius) + { + throw new UnsupportedOperationException( "Not supported yet." ); + } } Spigot spigot(); diff --git a/src/test/java/org/bukkit/EffectTest.java b/src/test/java/org/bukkit/EffectTest.java index 08aa71d3..5217aecb 100644 --- a/src/test/java/org/bukkit/EffectTest.java +++ b/src/test/java/org/bukkit/EffectTest.java @@ -9,7 +9,11 @@ public class EffectTest { @Test public void getById() { for (Effect effect : Effect.values()) { - assertThat(Effect.getById(effect.getId()), is(effect)); + if (effect.getType() != Effect.Type.PARTICLE) { + assertThat(Effect.getById(effect.getId()), is(effect)); + } else { + assertThat(Effect.getByName(effect.getName()), is(effect)); + } } } } From 5fa9eea67a3645ca31c3d358b81f294b6c5a66cb Mon Sep 17 00:00:00 2001 From: Andy Shulman Date: Mon, 15 Apr 2013 20:06:01 -0500 Subject: [PATCH 09/19] Define EntitySpawnEvent and SpawnerSpawnEvent Defines EntitySpawnEvent and SpawnerSpawnEvent. Adds BUKKIT-267 and BUKKIT-1559 --- .../event/entity/CreatureSpawnEvent.java | 32 +------------ .../bukkit/event/entity/EntitySpawnEvent.java | 45 +++++++++++++++++++ .../bukkit/event/entity/ItemSpawnEvent.java | 40 +++-------------- .../event/entity/SpawnerSpawnEvent.java | 22 +++++++++ 4 files changed, 74 insertions(+), 65 deletions(-) create mode 100644 src/main/java/org/bukkit/event/entity/EntitySpawnEvent.java create mode 100644 src/main/java/org/bukkit/event/entity/SpawnerSpawnEvent.java diff --git a/src/main/java/org/bukkit/event/entity/CreatureSpawnEvent.java b/src/main/java/org/bukkit/event/entity/CreatureSpawnEvent.java index f60c86ff..303479dd 100644 --- a/src/main/java/org/bukkit/event/entity/CreatureSpawnEvent.java +++ b/src/main/java/org/bukkit/event/entity/CreatureSpawnEvent.java @@ -4,17 +4,13 @@ import org.bukkit.entity.CreatureType; import org.bukkit.entity.Entity; import org.bukkit.entity.LivingEntity; -import org.bukkit.event.Cancellable; -import org.bukkit.event.HandlerList; /** * Called when a creature is spawned into a world. *

* If a Creature Spawn event is cancelled, the creature will not spawn. */ -public class CreatureSpawnEvent extends EntityEvent implements Cancellable { - private static final HandlerList handlers = new HandlerList(); - private boolean canceled; +public class CreatureSpawnEvent extends EntitySpawnEvent { private final SpawnReason spawnReason; public CreatureSpawnEvent(final LivingEntity spawnee, final SpawnReason spawnReason) { @@ -28,28 +24,11 @@ public CreatureSpawnEvent(Entity spawnee, CreatureType type, Location loc, Spawn spawnReason = reason; } - public boolean isCancelled() { - return canceled; - } - - public void setCancelled(boolean cancel) { - canceled = cancel; - } - @Override public LivingEntity getEntity() { return (LivingEntity) entity; } - /** - * Gets the location at which the creature is spawning. - * - * @return The location at which the creature is spawning - */ - public Location getLocation() { - return getEntity().getLocation(); - } - /** * Gets the type of creature being spawned. * @@ -70,15 +49,6 @@ public SpawnReason getSpawnReason() { return spawnReason; } - @Override - public HandlerList getHandlers() { - return handlers; - } - - public static HandlerList getHandlerList() { - return handlers; - } - /** * An enum to specify the type of spawning */ diff --git a/src/main/java/org/bukkit/event/entity/EntitySpawnEvent.java b/src/main/java/org/bukkit/event/entity/EntitySpawnEvent.java new file mode 100644 index 00000000..5dcf98f3 --- /dev/null +++ b/src/main/java/org/bukkit/event/entity/EntitySpawnEvent.java @@ -0,0 +1,45 @@ +package org.bukkit.event.entity; + +import org.bukkit.Location; +import org.bukkit.entity.Entity; +import org.bukkit.event.HandlerList; + +/** + * Called when an entity is spawned into a world. + *

+ * If an Entity Spawn event is cancelled, the entity will not spawn. + */ +public class EntitySpawnEvent extends EntityEvent implements org.bukkit.event.Cancellable { + private static final HandlerList handlers = new HandlerList(); + private boolean canceled; + + public EntitySpawnEvent(final Entity spawnee) { + super(spawnee); + } + + public boolean isCancelled() { + return canceled; + } + + public void setCancelled(boolean cancel) { + canceled = cancel; + } + + /** + * Gets the location at which the entity is spawning. + * + * @return The location at which the entity is spawning + */ + public Location getLocation() { + return getEntity().getLocation(); + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/src/main/java/org/bukkit/event/entity/ItemSpawnEvent.java b/src/main/java/org/bukkit/event/entity/ItemSpawnEvent.java index bafd934a..776f8e72 100644 --- a/src/main/java/org/bukkit/event/entity/ItemSpawnEvent.java +++ b/src/main/java/org/bukkit/event/entity/ItemSpawnEvent.java @@ -1,51 +1,23 @@ package org.bukkit.event.entity; -import org.bukkit.entity.Item; import org.bukkit.Location; -import org.bukkit.event.Cancellable; -import org.bukkit.event.HandlerList; +import org.bukkit.entity.Item; /** * Called when an item is spawned into a world */ -public class ItemSpawnEvent extends EntityEvent implements Cancellable { - private static final HandlerList handlers = new HandlerList(); - private final Location location; - private boolean canceled; - - public ItemSpawnEvent(final Item spawnee, final Location loc) { +public class ItemSpawnEvent extends EntitySpawnEvent { + public ItemSpawnEvent(final Item spawnee) { super(spawnee); - this.location = loc; } - public boolean isCancelled() { - return canceled; - } - - public void setCancelled(boolean cancel) { - canceled = cancel; + @Deprecated + public ItemSpawnEvent(final Item spawnee, final Location loc) { + this(spawnee); } @Override public Item getEntity() { return (Item) entity; } - - /** - * Gets the location at which the item is spawning. - * - * @return The location at which the item is spawning - */ - public Location getLocation() { - return location; - } - - @Override - public HandlerList getHandlers() { - return handlers; - } - - public static HandlerList getHandlerList() { - return handlers; - } } diff --git a/src/main/java/org/bukkit/event/entity/SpawnerSpawnEvent.java b/src/main/java/org/bukkit/event/entity/SpawnerSpawnEvent.java new file mode 100644 index 00000000..1acb3c40 --- /dev/null +++ b/src/main/java/org/bukkit/event/entity/SpawnerSpawnEvent.java @@ -0,0 +1,22 @@ +package org.bukkit.event.entity; + +import org.bukkit.block.CreatureSpawner; +import org.bukkit.entity.Entity; + +/** + * Called when an entity is spawned into a world by a spawner. + *

+ * If a Spawner Spawn event is cancelled, the entity will not spawn. + */ +public class SpawnerSpawnEvent extends EntitySpawnEvent { + private final CreatureSpawner spawner; + + public SpawnerSpawnEvent(final Entity spawnee, final CreatureSpawner spawner) { + super(spawnee); + this.spawner = spawner; + } + + public CreatureSpawner getSpawner() { + return spawner; + } +} From e16cedf2c970807933fd1c08720aafdacea159ee Mon Sep 17 00:00:00 2001 From: md_5 Date: Tue, 2 Jul 2013 20:32:53 +1000 Subject: [PATCH 10/19] Entity Mount and Dismount Events --- .../event/entity/EntityDismountEvent.java | 39 ++++++++++++++ .../event/entity/EntityMountEvent.java | 52 +++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 src/main/java/org/spigotmc/event/entity/EntityDismountEvent.java create mode 100644 src/main/java/org/spigotmc/event/entity/EntityMountEvent.java diff --git a/src/main/java/org/spigotmc/event/entity/EntityDismountEvent.java b/src/main/java/org/spigotmc/event/entity/EntityDismountEvent.java new file mode 100644 index 00000000..24d4942a --- /dev/null +++ b/src/main/java/org/spigotmc/event/entity/EntityDismountEvent.java @@ -0,0 +1,39 @@ +package org.spigotmc.event.entity; + +import org.bukkit.entity.Entity; +import org.bukkit.event.HandlerList; +import org.bukkit.event.entity.EntityEvent; + +/** + * Called when an entity stops riding another entity. + * + */ +public class EntityDismountEvent extends EntityEvent +{ + + private static final HandlerList handlers = new HandlerList(); + private boolean cancelled; + private final Entity dismounted; + + public EntityDismountEvent(Entity what, Entity dismounted) + { + super( what ); + this.dismounted = dismounted; + } + + public Entity getDismounted() + { + return dismounted; + } + + @Override + public HandlerList getHandlers() + { + return handlers; + } + + public static HandlerList getHandlerList() + { + return handlers; + } +} diff --git a/src/main/java/org/spigotmc/event/entity/EntityMountEvent.java b/src/main/java/org/spigotmc/event/entity/EntityMountEvent.java new file mode 100644 index 00000000..16aa2a7e --- /dev/null +++ b/src/main/java/org/spigotmc/event/entity/EntityMountEvent.java @@ -0,0 +1,52 @@ +package org.spigotmc.event.entity; + +import org.bukkit.entity.Entity; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.event.entity.EntityEvent; + +/** + * Called when an entity attempts to ride another entity. + * + */ +public class EntityMountEvent extends EntityEvent implements Cancellable +{ + + private static final HandlerList handlers = new HandlerList(); + private boolean cancelled; + private final Entity mount; + + public EntityMountEvent(Entity what, Entity mount) + { + super( what ); + this.mount = mount; + } + + public Entity getMount() + { + return mount; + } + + @Override + public boolean isCancelled() + { + return cancelled; + } + + @Override + public void setCancelled(boolean cancel) + { + this.cancelled = cancel; + } + + @Override + public HandlerList getHandlers() + { + return handlers; + } + + public static HandlerList getHandlerList() + { + return handlers; + } +} From ebd6e92567ca38c8870d7b0279e57bd857afab0f Mon Sep 17 00:00:00 2001 From: md_5 Date: Thu, 4 Jul 2013 20:05:19 +1000 Subject: [PATCH 11/19] Update Depends - All of these changes have been reviewed to be binary compatible and in general contract compatible with previous versions of the libraries. --- pom.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 2d1df202..2e2c9631 100644 --- a/pom.xml +++ b/pom.xml @@ -78,21 +78,21 @@ org.yaml snakeyaml - 1.9 + 1.12 jar compile com.googlecode.json-simple json-simple - 1.1 + 1.1.1 jar compile org.avaje ebean - 2.7.3 + 2.8.1 jar compile @@ -106,7 +106,7 @@ commons-lang commons-lang - 2.3 + 2.6 From c1b2dbf72a79170ebe60735f82cf41a3eeba6e02 Mon Sep 17 00:00:00 2001 From: Aikar Date: Sun, 7 Jul 2013 10:32:05 -0400 Subject: [PATCH 12/19] InventoryClickEvent getClickedInventory Add InventoryClickEvent.getClickedInventory. Adds BUKKIT-4495 Plugins currently have to do the logic themselves on the raw slot ID in order to determine the inventory clicked. This provides the logic for plugins to readily identify which inventory was clicked. --- .../event/inventory/InventoryClickEvent.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/main/java/org/bukkit/event/inventory/InventoryClickEvent.java b/src/main/java/org/bukkit/event/inventory/InventoryClickEvent.java index 28198b8b..3313d915 100644 --- a/src/main/java/org/bukkit/event/inventory/InventoryClickEvent.java +++ b/src/main/java/org/bukkit/event/inventory/InventoryClickEvent.java @@ -47,6 +47,7 @@ public class InventoryClickEvent extends InventoryInteractEvent { private static final HandlerList handlers = new HandlerList(); private final ClickType click; private final InventoryAction action; + private final Inventory clickedInventory; private SlotType slot_type; private int whichSlot; private int rawSlot; @@ -62,6 +63,13 @@ public InventoryClickEvent(InventoryView view, SlotType type, int slot, ClickTyp super(view); this.slot_type = type; this.rawSlot = slot; + if (slot < 0) { + this.clickedInventory = null; + } else if (view.getTopInventory() != null && slot < view.getTopInventory().getSize()) { + this.clickedInventory = view.getTopInventory(); + } else { + this.clickedInventory = view.getBottomInventory(); + } this.whichSlot = view.convertSlot(slot); this.click = click; this.action = action; @@ -72,6 +80,14 @@ public InventoryClickEvent(InventoryView view, SlotType type, int slot, ClickTyp this.hotbarKey = key; } + /** + * Gets the inventory that was clicked, or null if outside of window + * @return The clicked inventory + */ + public Inventory getClickedInventory() { + return clickedInventory; + } + /** * Gets the type of slot that was clicked. * From 904c2e357bba17fa097b577a1017ff689bde0e9a Mon Sep 17 00:00:00 2001 From: Alex Bennett Date: Thu, 11 Jul 2013 15:31:32 -0500 Subject: [PATCH 13/19] Added getAllSessionData() to the Conversation API. --- .../org/bukkit/conversations/ConversationContext.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/java/org/bukkit/conversations/ConversationContext.java b/src/main/java/org/bukkit/conversations/ConversationContext.java index 7a5b5edc..6b4bcace 100644 --- a/src/main/java/org/bukkit/conversations/ConversationContext.java +++ b/src/main/java/org/bukkit/conversations/ConversationContext.java @@ -43,6 +43,14 @@ public Conversable getForWhom() { return forWhom; } + /** + * Gets the entire sessionData map. + * @return The full sessionData map. + */ + public Map getAllSessionData() { + return sessionData; + } + /** * Gets session data shared between all {@link Prompt} invocations. Use this as a way * to pass data through each Prompt as the conversation develops. From 2f2abd478ca9ee0de8b07e60e2bed2a11db95653 Mon Sep 17 00:00:00 2001 From: md_5 Date: Mon, 22 Jul 2013 19:09:43 +1000 Subject: [PATCH 14/19] Catch Conversation API Errors --- src/main/java/org/bukkit/conversations/Conversation.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/main/java/org/bukkit/conversations/Conversation.java b/src/main/java/org/bukkit/conversations/Conversation.java index a30745fe..55c97858 100644 --- a/src/main/java/org/bukkit/conversations/Conversation.java +++ b/src/main/java/org/bukkit/conversations/Conversation.java @@ -193,6 +193,7 @@ public ConversationState getState() { * @param input The user's chat text. */ public void acceptInput(String input) { + try { // Spigot if (currentPrompt != null) { // Echo the user's input @@ -212,6 +213,12 @@ public void acceptInput(String input) { currentPrompt = currentPrompt.acceptInput(context, input); outputNextPrompt(); } + // Spigot Start + } catch ( Throwable t ) + { + org.bukkit.Bukkit.getLogger().log( java.util.logging.Level.SEVERE, "Error handling conversation prompt", t ); + } + // Spigot End } /** From 06003e71b6d13e6bf8f7c092917d3d3729e6885a Mon Sep 17 00:00:00 2001 From: md_5 Date: Sat, 3 Aug 2013 19:20:50 +1000 Subject: [PATCH 15/19] Player Collision API --- src/main/java/org/bukkit/entity/Player.java | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java index 8eab616f..9ee8f5ff 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java @@ -741,6 +741,27 @@ public void playEffect(Location location, Effect effect, int id, int data, float { throw new UnsupportedOperationException( "Not supported yet." ); } + + /** + * Gets whether the player collides with entities + * + * @return the player's collision toggle state + */ + public boolean getCollidesWithEntities() + { + throw new UnsupportedOperationException( "Not supported yet." ); + } + + /** + * Sets whether the player collides with entities + * + * @param collides whether the player should collide with entities or + * not. + */ + public void setCollidesWithEntities(boolean collides) + { + throw new UnsupportedOperationException( "Not supported yet." ); + } } Spigot spigot(); From 28d58e8575c23202920dfc2419abd801e694db66 Mon Sep 17 00:00:00 2001 From: md_5 Date: Sat, 3 Aug 2013 19:42:16 +1000 Subject: [PATCH 16/19] Expand Boolean Prompt Values --- src/main/java/org/bukkit/conversations/BooleanPrompt.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/bukkit/conversations/BooleanPrompt.java b/src/main/java/org/bukkit/conversations/BooleanPrompt.java index 6abb3547..a51e7543 100644 --- a/src/main/java/org/bukkit/conversations/BooleanPrompt.java +++ b/src/main/java/org/bukkit/conversations/BooleanPrompt.java @@ -14,12 +14,13 @@ public BooleanPrompt() { @Override protected boolean isInputValid(ConversationContext context, String input) { - String[] accepted = {"true", "false", "on", "off", "yes", "no"}; + String[] accepted = {"true", "false", "on", "off", "yes", "no" /* Spigot: */, "y", "n", "1", "0", "right", "wrong", "correct", "incorrect", "valid", "invalid"}; // Spigot return ArrayUtils.contains(accepted, input.toLowerCase()); } @Override protected Prompt acceptValidatedInput(ConversationContext context, String input) { + if (input.equalsIgnoreCase("y") || input.equals("1") || input.equalsIgnoreCase("right") || input.equalsIgnoreCase("correct") || input.equalsIgnoreCase("valid")) input = "true"; // Spigot return acceptValidatedInput(context, BooleanUtils.toBoolean(input)); } From 040fbc7534df1314096de3943f9b34dd06d79315 Mon Sep 17 00:00:00 2001 From: md_5 Date: Sat, 3 Aug 2013 19:49:36 +1000 Subject: [PATCH 17/19] Add Getter for Entity Invulnerability --- src/main/java/org/bukkit/entity/Entity.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/main/java/org/bukkit/entity/Entity.java b/src/main/java/org/bukkit/entity/Entity.java index 72af4fa1..a5b21003 100644 --- a/src/main/java/org/bukkit/entity/Entity.java +++ b/src/main/java/org/bukkit/entity/Entity.java @@ -280,4 +280,22 @@ public interface Entity extends Metadatable { * @return The current vehicle. */ public Entity getVehicle(); + + // Spigot Start + public class Spigot + { + + /** + * Returns whether this entity is invulnerable. + * + * @return True if the entity is invulnerable. + */ + public boolean isInvulnerable() + { + throw new UnsupportedOperationException( "Not supported yet." ); + } + } + + Spigot spigot(); + // Spigot End } From 474d138d67edc5fe5e43f732291677b44ad0b8f3 Mon Sep 17 00:00:00 2001 From: ninja- Date: Tue, 8 Oct 2013 14:35:58 +0200 Subject: [PATCH 18/19] Add respawn API. --- src/main/java/org/bukkit/entity/Player.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java index 9ee8f5ff..8fd9a076 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java @@ -762,6 +762,14 @@ public void setCollidesWithEntities(boolean collides) { throw new UnsupportedOperationException( "Not supported yet." ); } + + /** + * Respawns the player if dead. + */ + public void respawn() + { + throw new UnsupportedOperationException( "Not supported yet." ); + } } Spigot spigot(); From 0ce53223e6355d900977be482933052027f6e1f2 Mon Sep 17 00:00:00 2001 From: vemacs Date: Tue, 8 Oct 2013 10:35:56 -0600 Subject: [PATCH 19/19] Add experience cooldown API --- src/main/java/org/bukkit/entity/Player.java | 22 +++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java index 8fd9a076..5ebb9e78 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java @@ -770,6 +770,28 @@ public void respawn() { throw new UnsupportedOperationException( "Not supported yet." ); } + + /** + * Gets the player's experience cooldown + * + * @return the player's experience cooldown + */ + public int getExperienceCooldown() + { + throw new UnsupportedOperationException( "Not supported yet." ); + } + + /** + * Sets the player's experience cooldown + * + * @param cooldown how much time is needed for the player + * to gain experience points. A cooldown of 0 disables + * experience point pickup. + */ + public void setExperienceCooldown(int cooldown) + { + throw new UnsupportedOperationException( "Not supported yet." ); + } } Spigot spigot();