Make Spigot its own submodule

Merge pull request #118 from Techcable/spigot-in-submodule
This commit is contained in:
Techcable 2016-03-21 12:22:47 -05:00 committed by Zach Brown
parent ca7c627ded
commit 667953bb9f
183 changed files with 26 additions and 18207 deletions

3
.gitmodules vendored
View File

@ -10,3 +10,6 @@
[submodule "Paperclip"]
path = Paperclip
url = https://github.com/PaperSpigot/Paperclip.git
[submodule "Spigot"]
path = Spigot
url = https://Techcable@hub.spigotmc.org/stash/scm/spigot/spigot.git

View File

@ -1,33 +0,0 @@
From 194ff8ab46d416cfbd1e1c09ae4ea53f84949ab9 Mon Sep 17 00:00:00 2001
From: md_5 <md_5@live.com.au>
Date: Sun, 2 Jun 2013 10:36:24 +1000
Subject: [PATCH] POM Changes
diff --git a/pom.xml b/pom.xml
index 204d681..6377570 100644
--- a/pom.xml
+++ b/pom.xml
@@ -9,14 +9,14 @@
<version>9</version>
</parent>
- <groupId>org.bukkit</groupId>
- <artifactId>bukkit</artifactId>
+ <groupId>org.spigotmc</groupId>
+ <artifactId>spigot-api</artifactId>
<version>1.9-R0.1-SNAPSHOT</version>
<packaging>jar</packaging>
- <name>Bukkit</name>
- <url>http://www.bukkit.org/</url>
- <description>A plugin API for Minecraft servers.</description>
+ <name>Spigot-API</name>
+ <url>http://www.spigotmc.org/</url>
+ <description>An enhanced plugin API for Minecraft servers.</description>
<properties>
<maven.compiler.source>1.6</maven.compiler.source>
--
2.5.0

View File

@ -1,500 +0,0 @@
From 8d138fbb2a8a9b588e673ee5855e662db585a34d Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Sun, 2 Jun 2013 10:42:57 +1000
Subject: [PATCH] Spigot Timings
Adds performance tracking timings all around the Minecraft Server, and improves the usability of the /timings command
Plugins can track their own timings with CustomTimingsHandler
diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java
index 2ace8c1..e61e50b 100644
--- a/src/main/java/org/bukkit/Bukkit.java
+++ b/src/main/java/org/bukkit/Bukkit.java
@@ -546,6 +546,7 @@ public final class Bukkit {
*/
public static void reload() {
server.reload();
+ org.spigotmc.CustomTimingsHandler.reload(); // Spigot
}
/**
@@ -1156,4 +1157,9 @@ public final class Bukkit {
public static UnsafeValues getUnsafe() {
return server.getUnsafe();
}
+
+ public static Server.Spigot spigot()
+ {
+ return server.spigot();
+ }
}
diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java
index 60bcec8..5ca4321 100644
--- a/src/main/java/org/bukkit/Server.java
+++ b/src/main/java/org/bukkit/Server.java
@@ -948,4 +948,15 @@ public interface Server extends PluginMessageRecipient {
*/
@Deprecated
UnsafeValues getUnsafe();
+
+ public class Spigot
+ {
+
+ public org.bukkit.configuration.file.YamlConfiguration getConfig()
+ {
+ throw new UnsupportedOperationException( "Not supported yet." );
+ }
+ }
+
+ Spigot spigot();
}
diff --git a/src/main/java/org/bukkit/command/Command.java b/src/main/java/org/bukkit/command/Command.java
index a02c28d..0ba9b1c 100644
--- a/src/main/java/org/bukkit/command/Command.java
+++ b/src/main/java/org/bukkit/command/Command.java
@@ -31,6 +31,7 @@ public abstract class Command {
protected String usageMessage;
private String permission;
private String permissionMessage;
+ public org.spigotmc.CustomTimingsHandler timings; // Spigot
protected Command(String name) {
this(name, "", "/" + name, new ArrayList<String>());
@@ -44,6 +45,7 @@ public abstract class Command {
this.usageMessage = usageMessage;
this.aliases = aliases;
this.activeAliases = new ArrayList<String>(aliases);
+ this.timings = new org.spigotmc.CustomTimingsHandler("** Command: " + name); // Spigot
}
/**
@@ -227,6 +229,7 @@ public abstract class Command {
public boolean setLabel(String name) {
this.nextLabel = name;
if (!isRegistered()) {
+ this.timings = new org.spigotmc.CustomTimingsHandler("** Command: " + name); // Spigot
this.label = name;
return true;
}
diff --git a/src/main/java/org/bukkit/command/SimpleCommandMap.java b/src/main/java/org/bukkit/command/SimpleCommandMap.java
index a229d08..a08a49d 100644
--- a/src/main/java/org/bukkit/command/SimpleCommandMap.java
+++ b/src/main/java/org/bukkit/command/SimpleCommandMap.java
@@ -136,11 +136,15 @@ public class SimpleCommandMap implements CommandMap {
}
try {
+ target.timings.startTiming(); // Spigot
// Note: we don't return the result of target.execute as thats success / failure, we return handled (true) or not handled (false)
target.execute(sender, sentCommandLabel, Arrays_copyOfRange(args, 1, args.length));
+ target.timings.stopTiming(); // Spigot
} catch (CommandException ex) {
+ target.timings.stopTiming(); // Spigot
throw ex;
} catch (Throwable ex) {
+ target.timings.stopTiming(); // Spigot
throw new CommandException("Unhandled exception executing '" + commandLine + "' in " + target, ex);
}
diff --git a/src/main/java/org/bukkit/command/defaults/TimingsCommand.java b/src/main/java/org/bukkit/command/defaults/TimingsCommand.java
index a39ea5d..fc59aa3 100644
--- a/src/main/java/org/bukkit/command/defaults/TimingsCommand.java
+++ b/src/main/java/org/bukkit/command/defaults/TimingsCommand.java
@@ -19,23 +19,101 @@ import org.bukkit.util.StringUtil;
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;
+
+import org.bukkit.command.RemoteConsoleCommandSender;
+import org.bukkit.plugin.SimplePluginManager;
+import org.spigotmc.CustomTimingsHandler;
+// Spigot end
+
public class TimingsCommand extends BukkitCommand {
- private static final List<String> TIMINGS_SUBCOMMANDS = ImmutableList.of("merged", "reset", "separate");
+ private static final List<String> TIMINGS_SUBCOMMANDS = ImmutableList.of("report", "reset", "on", "off", "paste"); // Spigot
+ public static long timingStart = 0; // Spigot
public TimingsCommand(String name) {
super(name);
- this.description = "Records timings for all plugin events";
- this.usageMessage = "/timings <reset|merged|separate>";
+ this.description = "Manages Spigot Timings data to see performance of the server."; // Spigot
+ this.usageMessage = "/timings <reset|report|on|off|paste>"; // Spigot
this.setPermission("bukkit.command.timings");
}
+ // Spigot start - redesigned Timings Command
+ public void executeSpigotTimings(CommandSender sender, String[] args) {
+ if ( "on".equals( args[0] ) )
+ {
+ ( (SimplePluginManager) Bukkit.getPluginManager() ).useTimings( true );
+ CustomTimingsHandler.reload();
+ sender.sendMessage( "Enabled Timings & Reset" );
+ return;
+ } else if ( "off".equals( args[0] ) )
+ {
+ ( (SimplePluginManager) Bukkit.getPluginManager() ).useTimings( false );
+ sender.sendMessage( "Disabled Timings" );
+ return;
+ }
+
+ if ( !Bukkit.getPluginManager().useTimings() )
+ {
+ sender.sendMessage( "Please enable timings by typing /timings on" );
+ return;
+ }
+
+ boolean paste = "paste".equals( args[0] );
+ if ("reset".equals(args[0])) {
+ CustomTimingsHandler.reload();
+ sender.sendMessage("Timings reset");
+ } else if ("merged".equals(args[0]) || "report".equals(args[0]) || paste) {
+ long sampleTime = System.nanoTime() - timingStart;
+ int index = 0;
+ File timingFolder = new File("timings");
+ timingFolder.mkdirs();
+ File timings = new File(timingFolder, "timings.txt");
+ ByteArrayOutputStream bout = ( paste ) ? new ByteArrayOutputStream() : null;
+ while (timings.exists()) timings = new File(timingFolder, "timings" + (++index) + ".txt");
+ PrintStream fileTimings = null;
+ try {
+ fileTimings = ( paste ) ? new PrintStream( bout ) : new PrintStream( timings );
+
+ CustomTimingsHandler.printTimings(fileTimings);
+ fileTimings.println( "Sample time " + sampleTime + " (" + sampleTime / 1E9 + "s)" );
+
+ fileTimings.println( "<spigotConfig>" );
+ fileTimings.println( Bukkit.spigot().getConfig().saveToString() );
+ fileTimings.println( "</spigotConfig>" );
+
+ if ( paste )
+ {
+ new PasteThread( sender, bout ).start();
+ return;
+ }
+
+ sender.sendMessage("Timings written to " + timings.getPath());
+ sender.sendMessage( "Paste contents of file into form at http://www.spigotmc.org/go/timings to read results." );
+
+ } catch (IOException e) {
+ } finally {
+ if (fileTimings != null) {
+ fileTimings.close();
+ }
+ }
+ }
+ }
+ // Spigot end
+
@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;
}
+ if (true) { executeSpigotTimings(sender, args); return true; } // Spigot
if (!sender.getServer().getPluginManager().useTimings()) {
sender.sendMessage("Please enable timings by setting \"settings.plugin-profiling\" to true in bukkit.yml");
return true;
@@ -121,4 +199,55 @@ public class TimingsCommand extends BukkitCommand {
}
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 synchronized void start() {
+ if (sender instanceof RemoteConsoleCommandSender) {
+ run();
+ } else {
+ super.start();
+ }
+ }
+
+ @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 + "Timings results can be viewed at http://www.spigotmc.org/go/timings?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
}
diff --git a/src/main/java/org/bukkit/plugin/SimplePluginManager.java b/src/main/java/org/bukkit/plugin/SimplePluginManager.java
index 5a9e50d..c9d23d6 100644
--- a/src/main/java/org/bukkit/plugin/SimplePluginManager.java
+++ b/src/main/java/org/bukkit/plugin/SimplePluginManager.java
@@ -295,6 +295,7 @@ public final class SimplePluginManager implements PluginManager {
}
}
+ org.bukkit.command.defaults.TimingsCommand.timingStart = System.nanoTime(); // Spigot
return result.toArray(new Plugin[result.size()]);
}
diff --git a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
index 2118771..cd843f4 100644
--- a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
+++ b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
@@ -39,6 +39,7 @@ import org.bukkit.plugin.PluginLoader;
import org.bukkit.plugin.RegisteredListener;
import org.bukkit.plugin.TimedRegisteredListener;
import org.bukkit.plugin.UnknownDependencyException;
+import org.spigotmc.CustomTimingsHandler; // Spigot
import org.yaml.snakeyaml.error.YAMLException;
/**
@@ -49,6 +50,7 @@ public final class JavaPluginLoader implements PluginLoader {
private final Pattern[] fileFilters = new Pattern[] { Pattern.compile("\\.jar$"), };
private final Map<String, Class<?>> classes = new HashMap<String, Class<?>>();
private final Map<String, PluginClassLoader> loaders = new LinkedHashMap<String, PluginClassLoader>();
+ public static final CustomTimingsHandler pluginParentTimer = new CustomTimingsHandler("** Plugins"); // Spigot
/**
* This class was not meant to be constructed explicitly
@@ -291,13 +293,19 @@ public final class JavaPluginLoader implements PluginLoader {
}
}
+ final CustomTimingsHandler timings = new CustomTimingsHandler("Plugin: " + plugin.getDescription().getFullName() + " Event: " + listener.getClass().getName() + "::" + method.getName()+"("+eventClass.getSimpleName()+")", pluginParentTimer); // Spigot
EventExecutor executor = new EventExecutor() {
public void execute(Listener listener, Event event) throws EventException {
try {
if (!eventClass.isAssignableFrom(event.getClass())) {
return;
}
+ // Spigot start
+ boolean isAsync = event.isAsynchronous();
+ if (!isAsync) timings.startTiming();
method.invoke(listener, event);
+ if (!isAsync) timings.stopTiming();
+ // Spigot end
} catch (InvocationTargetException ex) {
throw new EventException(ex.getCause());
} catch (Throwable t) {
@@ -305,7 +313,7 @@ public final class JavaPluginLoader implements PluginLoader {
}
}
};
- if (useTimings) {
+ if (false) { // Spigot - RL 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 0000000..8d98297
--- /dev/null
+++ b/src/main/java/org/spigotmc/CustomTimingsHandler.java
@@ -0,0 +1,165 @@
+package org.spigotmc;
+
+import org.bukkit.command.defaults.TimingsCommand;
+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 java.util.List;
+import java.util.Queue;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+import org.bukkit.Bukkit;
+import org.bukkit.World;
+
+/**
+ * Provides custom timing sections for /timings merged.
+ */
+public class CustomTimingsHandler
+{
+
+ private static Queue<CustomTimingsHandler> HANDLERS = new ConcurrentLinkedQueue<CustomTimingsHandler>();
+ /*========================================================================*/
+ 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;
+ HANDLERS.add( this );
+ }
+
+ /**
+ * Prints the timings and extra data to the given stream.
+ *
+ * @param printStream
+ */
+ public static void printTimings(PrintStream printStream)
+ {
+ printStream.println( "Minecraft" );
+ for ( CustomTimingsHandler timings : 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 : HANDLERS )
+ {
+ timings.reset();
+ }
+ }
+ TimingsCommand.timingStart = System.nanoTime();
+ }
+
+ /**
+ * 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 : HANDLERS )
+ {
+ if ( timings.curTickTotal > 50000000 )
+ {
+ timings.violations += Math.ceil( timings.curTickTotal / 50000000 );
+ }
+ timings.curTickTotal = 0;
+ timings.timingDepth = 0; // incase reset messes this up
+ }
+ }
+ }
+
+ /**
+ * 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;
+ start = 0;
+ timingDepth = 0;
+ }
+}
--
2.5.0

View File

@ -1,69 +0,0 @@
From 4523472589759a21480748098592974ad2792e03 Mon Sep 17 00:00:00 2001
From: md_5 <md_5@live.com.au>
Date: Mon, 4 Mar 2013 18:31:20 +1100
Subject: [PATCH] Add PlayerItemDamageEvent
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 0000000..38a72ab
--- /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;
+ }
+}
--
2.5.0

View File

@ -1,102 +0,0 @@
From 0b286d348e11792e7da9b19a7fd02e623ed52aca Mon Sep 17 00:00:00 2001
From: md_5 <md_5@live.com.au>
Date: Sun, 2 Jun 2013 15:20:49 +1000
Subject: [PATCH] BungeeCord Support
diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java
index 723464b..6444fdf 100644
--- a/src/main/java/org/bukkit/entity/Player.java
+++ b/src/main/java/org/bukkit/entity/Player.java
@@ -1272,4 +1272,22 @@ public interface Player extends HumanEntity, Conversable, CommandSender, Offline
*/
public <T> void spawnParticle(Particle particle, double x, double y, double z, int count, double offsetX, double offsetY, double offsetZ, double extra, T data);
+ // 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 68834dd..4bc024f 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
@@ -43,10 +44,17 @@ public class PlayerLoginEvent extends PlayerEvent {
* @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 = realAddress;
+ }
+
+ public PlayerLoginEvent(final Player player, final String hostname, final InetAddress address) {
+ this(player, hostname, address, address);
+ // Spigot end
}
/**
@@ -58,7 +66,7 @@ public class PlayerLoginEvent extends PlayerEvent {
*/
@Deprecated
public PlayerLoginEvent(final Player player, final Result result, final String message) {
- this(player, "", null, result, message);
+ this(player, "", null, result, message, null); // Spigot
}
/**
@@ -71,12 +79,23 @@ public class PlayerLoginEvent extends PlayerEvent {
* @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
*
--
2.5.0

View File

@ -1,34 +0,0 @@
From 161c7845321df654c9e26e47f251fa6c3997f82c Mon Sep 17 00:00:00 2001
From: md_5 <md_5@live.com.au>
Date: Sun, 2 Jun 2013 15:08:24 +1000
Subject: [PATCH] Add Arrow API
diff --git a/src/main/java/org/bukkit/entity/Arrow.java b/src/main/java/org/bukkit/entity/Arrow.java
index e49eef0..e7a32f7 100644
--- a/src/main/java/org/bukkit/entity/Arrow.java
+++ b/src/main/java/org/bukkit/entity/Arrow.java
@@ -39,4 +39,20 @@ public interface Arrow extends Projectile {
* @param critical whether or not it should be critical
*/
public void setCritical(boolean critical);
+
+ 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();
}
--
2.5.0

View File

@ -1,369 +0,0 @@
From 6a7d6bd4e8e3175db58638c137135ed21d50fefa Mon Sep 17 00:00:00 2001
From: md_5 <md_5@live.com.au>
Date: Sun, 2 Jun 2013 15:57:09 +1000
Subject: [PATCH] Add Particle API
diff --git a/src/main/java/org/bukkit/Effect.java b/src/main/java/org/bukkit/Effect.java
index fe29e1c..f28fecd 100644
--- a/src/main/java/org/bukkit/Effect.java
+++ b/src/main/java/org/bukkit/Effect.java
@@ -5,6 +5,7 @@ import java.util.Map;
import com.google.common.collect.Maps;
import org.bukkit.block.BlockFace;
+import org.bukkit.material.MaterialData;
import org.bukkit.potion.Potion;
/**
@@ -79,27 +80,188 @@ 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 smoke particles that appears on blazes, minecarts
+ * with furnaces and fire
+ */
+ LARGE_SMOKE("largesmoke", 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("blockcrack", Type.PARTICLE, MaterialData.class),
+ /**
+ * The particles generated while sprinting a block
+ * This particle requires a Material and data value so that the client can select the correct texture.
+ */
+ TILE_DUST("blockdust", Type.PARTICLE, MaterialData.class);
private final int id;
private final Type type;
private final Class<?> data;
private static final Map<Integer, Effect> BY_ID = Maps.newHashMap();
+ private static final Map<String, Effect> 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
@@ -108,6 +270,15 @@ public enum Effect {
}
/**
+ * 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.
*/
public Type getType() {
@@ -115,8 +286,7 @@ public enum Effect {
}
/**
- * @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;
@@ -136,12 +306,32 @@ public enum Effect {
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 9d71de4..f59bdd3 100644
--- a/src/main/java/org/bukkit/World.java
+++ b/src/main/java/org/bukkit/World.java
@@ -1189,6 +1189,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
+
/**
* Gets the world border for this world.
*
diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java
index 6444fdf..77ddf68 100644
--- a/src/main/java/org/bukkit/entity/Player.java
+++ b/src/main/java/org/bukkit/entity/Player.java
@@ -1286,6 +1286,11 @@ public interface Player extends HumanEntity, Conversable, CommandSender, Offline
{
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 08aa71d..5217aec 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));
+ }
}
}
}
--
2.5.0

View File

@ -1,220 +0,0 @@
From 9d7dd9d5f9276fce1fd98a79a90d7a4b3523001e Mon Sep 17 00:00:00 2001
From: Andy Shulman <andy.shulman@hotmail.com>
Date: Mon, 15 Apr 2013 20:06:01 -0500
Subject: [PATCH] Define EntitySpawnEvent and SpawnerSpawnEvent
Defines EntitySpawnEvent and SpawnerSpawnEvent. Adds BUKKIT-267 and BUKKIT-1559
diff --git a/src/main/java/org/bukkit/event/entity/CreatureSpawnEvent.java b/src/main/java/org/bukkit/event/entity/CreatureSpawnEvent.java
index c035b37..9dd8ef1 100644
--- a/src/main/java/org/bukkit/event/entity/CreatureSpawnEvent.java
+++ b/src/main/java/org/bukkit/event/entity/CreatureSpawnEvent.java
@@ -3,17 +3,13 @@ package org.bukkit.event.entity;
import org.bukkit.Location;
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.
* <p>
* 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) {
@@ -21,29 +17,12 @@ public class CreatureSpawnEvent extends EntityEvent implements Cancellable {
this.spawnReason = spawnReason;
}
- 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 reason for why the creature is being spawned.
*
* @return A SpawnReason value detailing the reason for the creature being
@@ -53,15 +32,6 @@ public class CreatureSpawnEvent extends EntityEvent implements Cancellable {
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 0000000..5dcf98f
--- /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.
+ * <p>
+ * 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 bafd934..776f8e7 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 0000000..1acb3c4
--- /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.
+ * <p>
+ * 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;
+ }
+}
--
2.5.0

View File

@ -1,112 +0,0 @@
From f4a34eb093b24d141daa07889a425b6c5d5b7c76 Mon Sep 17 00:00:00 2001
From: md_5 <md_5@live.com.au>
Date: Tue, 2 Jul 2013 20:32:53 +1000
Subject: [PATCH] Entity Mount and Dismount Events
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 0000000..24d4942
--- /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 0000000..16aa2a7
--- /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;
+ }
+}
--
2.5.0

View File

@ -1,54 +0,0 @@
From 36c03b52a29710a08ab8c8a4aecdf00877847315 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Sun, 7 Jul 2013 10:32:05 -0400
Subject: [PATCH] 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.
diff --git a/src/main/java/org/bukkit/event/inventory/InventoryClickEvent.java b/src/main/java/org/bukkit/event/inventory/InventoryClickEvent.java
index 28198b8..3313d91 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 class InventoryClickEvent extends InventoryInteractEvent {
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;
@@ -73,6 +81,14 @@ public class InventoryClickEvent extends InventoryInteractEvent {
}
/**
+ * 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.
*
* @return the slot type
--
2.5.0

View File

@ -1,28 +0,0 @@
From d42215ef49162229b53cdae06df8143f7d3b8692 Mon Sep 17 00:00:00 2001
From: Alex Bennett <alex.eugene.bennett@gmail.com>
Date: Thu, 11 Jul 2013 15:31:32 -0500
Subject: [PATCH] Added getAllSessionData() to the Conversation API.
diff --git a/src/main/java/org/bukkit/conversations/ConversationContext.java b/src/main/java/org/bukkit/conversations/ConversationContext.java
index 4f33ff4..7390a77 100644
--- a/src/main/java/org/bukkit/conversations/ConversationContext.java
+++ b/src/main/java/org/bukkit/conversations/ConversationContext.java
@@ -46,6 +46,14 @@ public class ConversationContext {
}
/**
+ * Gets the entire sessionData map.
+ * @return The full sessionData map.
+ */
+ public Map<Object, Object> 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.
--
2.5.0

View File

@ -1,34 +0,0 @@
From 6b81cd9d8cfc6fbc6046bd89aab7ca0b7ff83426 Mon Sep 17 00:00:00 2001
From: md_5 <md_5@live.com.au>
Date: Mon, 22 Jul 2013 19:09:43 +1000
Subject: [PATCH] Catch Conversation API Errors
diff --git a/src/main/java/org/bukkit/conversations/Conversation.java b/src/main/java/org/bukkit/conversations/Conversation.java
index d4c1f6d..46912c8 100644
--- a/src/main/java/org/bukkit/conversations/Conversation.java
+++ b/src/main/java/org/bukkit/conversations/Conversation.java
@@ -209,6 +209,7 @@ public class Conversation {
* @param input The user's chat text.
*/
public void acceptInput(String input) {
+ try { // Spigot
if (currentPrompt != null) {
// Echo the user's input
@@ -228,6 +229,12 @@ public class Conversation {
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
}
/**
--
2.5.0

View File

@ -1,41 +0,0 @@
From 8747c4a54e1c16d7e96a02212f2583f40d9d5523 Mon Sep 17 00:00:00 2001
From: md_5 <md_5@live.com.au>
Date: Sat, 3 Aug 2013 19:20:50 +1000
Subject: [PATCH] Player Collision API
diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java
index 77ddf68..146fbd4 100644
--- a/src/main/java/org/bukkit/entity/Player.java
+++ b/src/main/java/org/bukkit/entity/Player.java
@@ -1291,6 +1291,27 @@ public interface Player extends HumanEntity, Conversable, CommandSender, Offline
{
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();
--
2.5.0

View File

@ -1,28 +0,0 @@
From 7aef7e6c46ff1f2c9b6b348b817b7af04f4eb327 Mon Sep 17 00:00:00 2001
From: md_5 <md_5@live.com.au>
Date: Sat, 3 Aug 2013 19:42:16 +1000
Subject: [PATCH] Expand Boolean Prompt Values
diff --git a/src/main/java/org/bukkit/conversations/BooleanPrompt.java b/src/main/java/org/bukkit/conversations/BooleanPrompt.java
index 3f2c97f..81ef78c 100644
--- a/src/main/java/org/bukkit/conversations/BooleanPrompt.java
+++ b/src/main/java/org/bukkit/conversations/BooleanPrompt.java
@@ -15,12 +15,13 @@ public abstract class BooleanPrompt extends ValidatingPrompt{
@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));
}
--
2.5.0

View File

@ -1,36 +0,0 @@
From d60f114d2e756c1757df92f70c3bf32a631f5a6d Mon Sep 17 00:00:00 2001
From: md_5 <md_5@live.com.au>
Date: Sat, 3 Aug 2013 19:49:36 +1000
Subject: [PATCH] Add Getter for Entity Invulnerability
diff --git a/src/main/java/org/bukkit/entity/Entity.java b/src/main/java/org/bukkit/entity/Entity.java
index 6dc7076..9f4d48b 100644
--- a/src/main/java/org/bukkit/entity/Entity.java
+++ b/src/main/java/org/bukkit/entity/Entity.java
@@ -356,4 +356,22 @@ public interface Entity extends Metadatable, CommandSender {
* @return whether the entity is glowing
*/
boolean isGlowing();
+
+ // 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
}
--
2.5.0

View File

@ -1,28 +0,0 @@
From e5707119e3a0e1279df92b73c9d618eb7956c7c8 Mon Sep 17 00:00:00 2001
From: ninja- <xninja@openmailbox.org>
Date: Tue, 8 Oct 2013 14:35:58 +0200
Subject: [PATCH] Add respawn API.
diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java
index 146fbd4..a9bdfde 100644
--- a/src/main/java/org/bukkit/entity/Player.java
+++ b/src/main/java/org/bukkit/entity/Player.java
@@ -1312,6 +1312,14 @@ public interface Player extends HumanEntity, Conversable, CommandSender, Offline
{
throw new UnsupportedOperationException( "Not supported yet." );
}
+
+ /**
+ * Respawns the player if dead.
+ */
+ public void respawn()
+ {
+ throw new UnsupportedOperationException( "Not supported yet." );
+ }
}
Spigot spigot();
--
2.5.0

View File

@ -1,30 +0,0 @@
From ae75234b451d6cf85e70ed248e758aa8d0510e72 Mon Sep 17 00:00:00 2001
From: md_5 <md_5@live.com.au>
Date: Sat, 19 Oct 2013 12:59:42 +1100
Subject: [PATCH] Fix Plugin Message API Disconnects
diff --git a/src/main/java/org/bukkit/plugin/messaging/StandardMessenger.java b/src/main/java/org/bukkit/plugin/messaging/StandardMessenger.java
index a906f8d..4c171e8 100644
--- a/src/main/java/org/bukkit/plugin/messaging/StandardMessenger.java
+++ b/src/main/java/org/bukkit/plugin/messaging/StandardMessenger.java
@@ -421,7 +421,15 @@ public class StandardMessenger implements Messenger {
Set<PluginMessageListenerRegistration> registrations = getIncomingChannelRegistrations(channel);
for (PluginMessageListenerRegistration registration : registrations) {
- registration.getListener().onPluginMessageReceived(channel, source, message);
+ // Spigot Start
+ try
+ {
+ registration.getListener().onPluginMessageReceived( channel, source, message );
+ } catch ( Throwable t )
+ {
+ org.bukkit.Bukkit.getLogger().log( java.util.logging.Level.WARNING, "Could not pass incoming plugin message to " + registration.getPlugin(), t );
+ }
+ // Spigot End
}
}
--
2.5.0

View File

@ -1,85 +0,0 @@
From 4e7e25927d68916ab42503766e264c3db44155be Mon Sep 17 00:00:00 2001
From: md_5 <git@md-5.net>
Date: Tue, 24 Dec 2013 10:14:25 +1100
Subject: [PATCH] Fix Tab Completion for Some Commands
diff --git a/src/main/java/org/bukkit/command/defaults/PluginsCommand.java b/src/main/java/org/bukkit/command/defaults/PluginsCommand.java
index b888da1..e21d167 100644
--- a/src/main/java/org/bukkit/command/defaults/PluginsCommand.java
+++ b/src/main/java/org/bukkit/command/defaults/PluginsCommand.java
@@ -40,4 +40,12 @@ public class PluginsCommand extends BukkitCommand {
return "(" + plugins.length + "): " + pluginList.toString();
}
+
+ // Spigot Start
+ @Override
+ public java.util.List<String> tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException
+ {
+ return java.util.Collections.emptyList();
+ }
+ // Spigot End
}
diff --git a/src/main/java/org/bukkit/command/defaults/ReloadCommand.java b/src/main/java/org/bukkit/command/defaults/ReloadCommand.java
index eb018f1..c70d512 100644
--- a/src/main/java/org/bukkit/command/defaults/ReloadCommand.java
+++ b/src/main/java/org/bukkit/command/defaults/ReloadCommand.java
@@ -27,4 +27,12 @@ public class ReloadCommand extends BukkitCommand {
return true;
}
+
+ // Spigot Start
+ @Override
+ public java.util.List<String> tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException
+ {
+ return java.util.Collections.emptyList();
+ }
+ // Spigot End
}
diff --git a/src/main/java/org/bukkit/command/defaults/TellCommand.java b/src/main/java/org/bukkit/command/defaults/TellCommand.java
index 7b0a41c..2e5d811 100644
--- a/src/main/java/org/bukkit/command/defaults/TellCommand.java
+++ b/src/main/java/org/bukkit/command/defaults/TellCommand.java
@@ -46,4 +46,16 @@ public class TellCommand extends VanillaCommand {
return true;
}
+
+ // Spigot Start
+ @Override
+ public java.util.List<String> tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException
+ {
+ if ( args.length == 0 )
+ {
+ return super.tabComplete( sender, alias, args );
+ }
+ return java.util.Collections.emptyList();
+ }
+ // Spigot End
}
diff --git a/src/main/java/org/bukkit/command/defaults/TestForCommand.java b/src/main/java/org/bukkit/command/defaults/TestForCommand.java
index 7e5494d..e168b49 100644
--- a/src/main/java/org/bukkit/command/defaults/TestForCommand.java
+++ b/src/main/java/org/bukkit/command/defaults/TestForCommand.java
@@ -24,4 +24,16 @@ public class TestForCommand extends VanillaCommand {
sender.sendMessage(ChatColor.RED + "/testfor is only usable by commandblocks with analog output.");
return true;
}
+
+ // Spigot Start
+ @Override
+ public java.util.List<String> tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException
+ {
+ if ( args.length == 0 )
+ {
+ return super.tabComplete( sender, alias, args );
+ }
+ return java.util.Collections.emptyList();
+ }
+ // Spigot End
}
--
2.5.0

View File

@ -1,30 +0,0 @@
From e3615f3fa41f42a38dbc675946b23311055a8938 Mon Sep 17 00:00:00 2001
From: Smove <jan@lavasurvival.net>
Date: Sat, 1 Feb 2014 18:10:49 +1100
Subject: [PATCH] Implement Locale Getter for Players
diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java
index a9bdfde..43ef5b1 100644
--- a/src/main/java/org/bukkit/entity/Player.java
+++ b/src/main/java/org/bukkit/entity/Player.java
@@ -1320,6 +1320,16 @@ public interface Player extends HumanEntity, Conversable, CommandSender, Offline
{
throw new UnsupportedOperationException( "Not supported yet." );
}
+
+ /**
+ * Gets player locale language.
+ *
+ * @return the player's client language settings
+ */
+ public String getLocale()
+ {
+ throw new UnsupportedOperationException( "Not supported yet." );
+ }
}
Spigot spigot();
--
2.5.0

View File

@ -1,30 +0,0 @@
From 200eacd0d6f315d1b0c918ba29c49111f7b5a8a5 Mon Sep 17 00:00:00 2001
From: Tux <write@imaginarycode.com>
Date: Sun, 9 Feb 2014 14:02:11 -0500
Subject: [PATCH] Add support for fetching hidden players
diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java
index 43ef5b1..97995db 100644
--- a/src/main/java/org/bukkit/entity/Player.java
+++ b/src/main/java/org/bukkit/entity/Player.java
@@ -1330,6 +1330,16 @@ public interface Player extends HumanEntity, Conversable, CommandSender, Offline
{
throw new UnsupportedOperationException( "Not supported yet." );
}
+
+ /**
+ * Gets all players hidden with {@link #hidePlayer(org.bukkit.entity.Player)}.
+ *
+ * @return a Set with all hidden players
+ */
+ public java.util.Set<Player> getHiddenPlayers()
+ {
+ throw new UnsupportedOperationException( "Not supported yet." );
+ }
}
Spigot spigot();
--
2.5.0

View File

@ -1,70 +0,0 @@
From 839fc96a5f387bb4d5e17f916df25b60e42f20a5 Mon Sep 17 00:00:00 2001
From: drXor <mcyoungsota@gmail.com>
Date: Sun, 23 Feb 2014 16:16:29 -0400
Subject: [PATCH] Silenceable Lightning API
diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java
index f59bdd3..d088c3c 100644
--- a/src/main/java/org/bukkit/World.java
+++ b/src/main/java/org/bukkit/World.java
@@ -1234,6 +1234,30 @@ public interface World extends PluginMessageRecipient, Metadatable {
{
throw new UnsupportedOperationException( "Not supported yet." );
}
+
+ /**
+ * Strikes lightning at the given {@link Location} and possibly without sound
+ *
+ * @param loc The location to strike lightning
+ * @param isSilent Whether this strike makes no sound
+ * @return The lightning entity.
+ */
+ public LightningStrike strikeLightning(Location loc, boolean isSilent)
+ {
+ throw new UnsupportedOperationException( "Not supported yet." );
+ }
+
+ /**
+ * Strikes lightning at the given {@link Location} without doing damage and possibly without sound
+ *
+ * @param loc The location to strike lightning
+ * @param isSilent Whether this strike makes no sound
+ * @return The lightning entity.
+ */
+ public LightningStrike strikeLightningEffect(Location loc, boolean isSilent)
+ {
+ throw new UnsupportedOperationException( "Not supported yet." );
+ }
}
Spigot spigot();
diff --git a/src/main/java/org/bukkit/entity/LightningStrike.java b/src/main/java/org/bukkit/entity/LightningStrike.java
index c8b5154..1ed4ac9 100644
--- a/src/main/java/org/bukkit/entity/LightningStrike.java
+++ b/src/main/java/org/bukkit/entity/LightningStrike.java
@@ -12,4 +12,21 @@ public interface LightningStrike extends Weather {
*/
public boolean isEffect();
+
+ public class Spigot extends Entity.Spigot
+ {
+
+ /*
+ * Returns whether the strike is silent.
+ *
+ * @return whether the strike is silent.
+ */
+ public boolean isSilent()
+ {
+ throw new UnsupportedOperationException( "Not supported yet." );
+ }
+
+ }
+
+ Spigot spigot();
}
--
2.5.0

View File

@ -1,94 +0,0 @@
From 695554e3a650ccdb4d3d1d1ae56fb6bfacda48ea Mon Sep 17 00:00:00 2001
From: md_5 <git@md-5.net>
Date: Sun, 30 Mar 2014 15:58:22 +1100
Subject: [PATCH] Remove deprecation on some player lookup methods
Most of these methods still have plenty of use given that only one player with each name can exist at a time. Deprecating these methods renders even basic functionality such as /msg <name> impossible without causing compiler warnings. We will maintain this API and it should be considered safe and appropriate for most use cases.
diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java
index e61e50b..dc2c9d1 100644
--- a/src/main/java/org/bukkit/Bukkit.java
+++ b/src/main/java/org/bukkit/Bukkit.java
@@ -377,12 +377,9 @@ public final class Bukkit {
* <p>
* This method may not return objects for offline players.
*
- * @deprecated Use {@link #getPlayer(UUID)} as player names are no longer
- * guaranteed to be unique
* @param name the name to look up
* @return a player if one was found, null otherwise
*/
- @Deprecated
public static Player getPlayer(String name) {
return server.getPlayer(name);
}
@@ -390,12 +387,9 @@ public final class Bukkit {
/**
* Gets the player with the exact given name, case insensitive.
*
- * @deprecated Use {@link #getPlayer(UUID)} as player names are no longer
- * guaranteed to be unique
* @param name Exact name of the player to retrieve
* @return a player object if one was found, null otherwise
*/
- @Deprecated
public static Player getPlayerExact(String name) {
return server.getPlayerExact(name);
}
@@ -407,12 +401,9 @@ public final class Bukkit {
* This list is not sorted in any particular order. If an exact match is
* found, the returned list will only contain a single result.
*
- * @deprecated Use {@link #getPlayer(UUID)} as player names are no longer
- * guaranteed to be unique
* @param name the (partial) name to match
* @return list of all possible players
*/
- @Deprecated
public static List<Player> matchPlayer(String name) {
return server.matchPlayer(name);
}
diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java
index 5ca4321..cdccaf3 100644
--- a/src/main/java/org/bukkit/Server.java
+++ b/src/main/java/org/bukkit/Server.java
@@ -313,23 +313,17 @@ public interface Server extends PluginMessageRecipient {
* <p>
* This method may not return objects for offline players.
*
- * @deprecated Use {@link #getPlayer(UUID)} as player names are no longer
- * guaranteed to be unique
* @param name the name to look up
* @return a player if one was found, null otherwise
*/
- @Deprecated
public Player getPlayer(String name);
/**
* Gets the player with the exact given name, case insensitive.
*
- * @deprecated Use {@link #getPlayer(UUID)} as player names are no longer
- * guaranteed to be unique
* @param name Exact name of the player to retrieve
* @return a player object if one was found, null otherwise
*/
- @Deprecated
public Player getPlayerExact(String name);
/**
@@ -339,12 +333,9 @@ public interface Server extends PluginMessageRecipient {
* This list is not sorted in any particular order. If an exact match is
* found, the returned list will only contain a single result.
*
- * @deprecated Use {@link #getPlayer(UUID)} as player names are no longer
- * guaranteed to be unique
* @param name the (partial) name to match
* @return list of all possible players
*/
- @Deprecated
public List<Player> matchPlayer(String name);
/**
--
2.5.0

View File

@ -1,31 +0,0 @@
From c273b600a1dc967bfb9584ffb910e5ac05a3feb5 Mon Sep 17 00:00:00 2001
From: md_5 <git@md-5.net>
Date: Thu, 17 Apr 2014 19:35:13 +1000
Subject: [PATCH] Add Score.isScoreSet()Z API.
diff --git a/src/main/java/org/bukkit/scoreboard/Score.java b/src/main/java/org/bukkit/scoreboard/Score.java
index 4c10346..2410cbd 100644
--- a/src/main/java/org/bukkit/scoreboard/Score.java
+++ b/src/main/java/org/bukkit/scoreboard/Score.java
@@ -51,6 +51,17 @@ public interface Score {
*/
void setScore(int score) throws IllegalStateException;
+ // Spigot start
+ /**
+ * Shows if this score has been set at any point in time.
+ *
+ * @return if this score has been set before
+ * @throws IllegalStateException if the associated objective has been
+ * unregistered
+ */
+ boolean isScoreSet() throws IllegalStateException;
+ // Spigot end
+
/**
* Gets the scoreboard for the associated objective.
*
--
2.5.0

View File

@ -1,65 +0,0 @@
From b4f68c78aa8154ab3f3fee79fa35967382eb3aff Mon Sep 17 00:00:00 2001
From: ninja <xninja@openmailbox.org>
Date: Tue, 8 Apr 2014 14:01:32 +0200
Subject: [PATCH] Add PlayerSpawnLocationEvent.
diff --git a/src/main/java/org/spigotmc/event/player/PlayerSpawnLocationEvent.java b/src/main/java/org/spigotmc/event/player/PlayerSpawnLocationEvent.java
new file mode 100644
index 0000000..dd3f58c
--- /dev/null
+++ b/src/main/java/org/spigotmc/event/player/PlayerSpawnLocationEvent.java
@@ -0,0 +1,50 @@
+package org.spigotmc.event.player;
+
+import org.bukkit.Location;
+import org.bukkit.entity.Entity;
+import org.bukkit.entity.Player;
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.player.PlayerEvent;
+
+/**
+ * Called when player is about to spawn in a world after joining the server.
+ */
+public class PlayerSpawnLocationEvent extends PlayerEvent {
+ private static final HandlerList handlers = new HandlerList();
+ private Location spawnLocation;
+
+ public PlayerSpawnLocationEvent(final Player who, Location spawnLocation) {
+ super(who);
+ this.spawnLocation = spawnLocation;
+ }
+
+
+ /**
+ * Gets player's spawn location.
+ * If the player {@link Player#hasPlayedBefore()}, it's going to default to the location inside player.dat file.
+ * For new players, the default spawn location is spawn of the main Bukkit world.
+ *
+ * @return the spawn location
+ */
+ public Location getSpawnLocation() {
+ return spawnLocation;
+ }
+
+ /**
+ * Sets player's spawn location.
+ *
+ * @param location the spawn location
+ */
+ public void setSpawnLocation(Location location) {
+ this.spawnLocation = location;
+ }
+
+ @Override
+ public HandlerList getHandlers() {
+ return handlers;
+ }
+
+ public static HandlerList getHandlerList() {
+ return handlers;
+ }
+}
--
2.5.0

View File

@ -1,67 +0,0 @@
From 3023d912fbd278e9cce35e715477f5a1969e1441 Mon Sep 17 00:00:00 2001
From: md_5 <git@md-5.net>
Date: Wed, 16 Jul 2014 17:24:21 +1000
Subject: [PATCH] Ease ClassLoader Deadlocks Where Possible
When on Java 7 we can register the classloader as parallel capable to prevent deadlocks caused by certain scenarios. Due to the nature of PluginClassLoader this isn't completely safe, but we can make it safer by switching to concurrency focused collections. Either way this is far better than crashing the server.
diff --git a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
index cd843f4..7bf2fa6 100644
--- a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
+++ b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
@@ -48,7 +48,7 @@ import org.yaml.snakeyaml.error.YAMLException;
public final class JavaPluginLoader implements PluginLoader {
final Server server;
private final Pattern[] fileFilters = new Pattern[] { Pattern.compile("\\.jar$"), };
- private final Map<String, Class<?>> classes = new HashMap<String, Class<?>>();
+ private final Map<String, Class<?>> classes = new java.util.concurrent.ConcurrentHashMap<String, Class<?>>(); // Spigot
private final Map<String, PluginClassLoader> loaders = new LinkedHashMap<String, PluginClassLoader>();
public static final CustomTimingsHandler pluginParentTimer = new CustomTimingsHandler("** Plugins"); // Spigot
diff --git a/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java b/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java
index 13f8633..4cffa13 100644
--- a/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java
+++ b/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java
@@ -17,7 +17,7 @@ import org.bukkit.plugin.PluginDescriptionFile;
*/
final class PluginClassLoader extends URLClassLoader {
private final JavaPluginLoader loader;
- private final Map<String, Class<?>> classes = new HashMap<String, Class<?>>();
+ private final Map<String, Class<?>> classes = new java.util.concurrent.ConcurrentHashMap<String, Class<?>>(); // Spigot
private final PluginDescriptionFile description;
private final File dataFolder;
private final File file;
@@ -25,6 +25,30 @@ final class PluginClassLoader extends URLClassLoader {
private JavaPlugin pluginInit;
private IllegalStateException pluginState;
+ // Spigot Start
+ static
+ {
+ try
+ {
+ java.lang.reflect.Method method = ClassLoader.class.getDeclaredMethod( "registerAsParallelCapable" );
+ if ( method != null )
+ {
+ boolean oldAccessible = method.isAccessible();
+ method.setAccessible( true );
+ method.invoke( null );
+ method.setAccessible( oldAccessible );
+ org.bukkit.Bukkit.getLogger().log( java.util.logging.Level.INFO, "Set PluginClassLoader as parallel capable" );
+ }
+ } catch ( NoSuchMethodException ex )
+ {
+ // Ignore
+ } catch ( Exception ex )
+ {
+ org.bukkit.Bukkit.getLogger().log( java.util.logging.Level.WARNING, "Error setting PluginClassLoader as parallel capable", ex );
+ }
+ }
+ // Spigot End
+
PluginClassLoader(final JavaPluginLoader loader, final ClassLoader parent, final PluginDescriptionFile description, final File dataFolder, final File file) throws InvalidPluginException, MalformedURLException {
super(new URL[] {file.toURI().toURL()}, parent);
Validate.notNull(loader, "Loader cannot be null");
--
2.5.0

View File

@ -1,23 +0,0 @@
From a7b3e4ecddc7a8203270b844a902a2d0a892cf25 Mon Sep 17 00:00:00 2001
From: md_5 <git@md-5.net>
Date: Tue, 22 Jul 2014 21:01:32 +1000
Subject: [PATCH] Fix slow tab complete for some commands.
Use online players instead of offline players, which is very slow.
diff --git a/src/main/java/org/bukkit/command/defaults/WhitelistCommand.java b/src/main/java/org/bukkit/command/defaults/WhitelistCommand.java
index 92de43c..855f560 100644
--- a/src/main/java/org/bukkit/command/defaults/WhitelistCommand.java
+++ b/src/main/java/org/bukkit/command/defaults/WhitelistCommand.java
@@ -105,7 +105,7 @@ public class WhitelistCommand extends VanillaCommand {
} else if (args.length == 2) {
if (args[0].equalsIgnoreCase("add")) {
List<String> completions = new ArrayList<String>();
- for (OfflinePlayer player : Bukkit.getOfflinePlayers()) {
+ for (OfflinePlayer player : Bukkit.getOnlinePlayers()) { // Spigot - well maybe sometimes you haven't turned the whitelist on just yet.
String name = player.getName();
if (StringUtil.startsWithIgnoreCase(name, args[1]) && !player.isWhitelisted()) {
completions.add(name);
--
2.5.0

View File

@ -1,25 +0,0 @@
From cd9f774fd319b7bc548a18585c2ac16cbc61076a Mon Sep 17 00:00:00 2001
From: drXor <mcyoung@mit.edu>
Date: Wed, 23 Jul 2014 15:50:36 -0400
Subject: [PATCH] Undeprecate Player#updateInventory()V
diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java
index eb5084b..a89df18 100644
--- a/src/main/java/org/bukkit/entity/Player.java
+++ b/src/main/java/org/bukkit/entity/Player.java
@@ -334,10 +334,8 @@ public interface Player extends HumanEntity, Conversable, CommandSender, Offline
/**
* Forces an update of the player's entire inventory.
*
- * @deprecated This method should not be relied upon as it is a temporary
- * work-around for a larger, more complicated issue.
*/
- @Deprecated
+ //@Deprecated // Spigot - undeprecate
public void updateInventory();
/**
--
2.5.0

View File

@ -1,46 +0,0 @@
From cead8b988efa720dedbe6a3b314552416780234d Mon Sep 17 00:00:00 2001
From: libraryaddict <redwarfare@live.com>
Date: Fri, 22 Aug 2014 05:31:04 -0400
Subject: [PATCH] Added isUnbreakable and setUnbreakable to ItemMeta
diff --git a/src/main/java/org/bukkit/inventory/meta/ItemMeta.java b/src/main/java/org/bukkit/inventory/meta/ItemMeta.java
index 459e09c..d8cc821 100644
--- a/src/main/java/org/bukkit/inventory/meta/ItemMeta.java
+++ b/src/main/java/org/bukkit/inventory/meta/ItemMeta.java
@@ -157,4 +157,32 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable {
@SuppressWarnings("javadoc")
ItemMeta clone();
+
+ // Spigot start
+ public class Spigot
+ {
+
+ /**
+ * Sets the unbreakable tag
+ *
+ * @param unbreakable true if set unbreakable
+ */
+ public void setUnbreakable(boolean unbreakable)
+ {
+ throw new UnsupportedOperationException( "Not supported yet." );
+ }
+
+ /**
+ * Return if the unbreakable tag is true
+ *
+ * @return true if the unbreakable tag is true
+ */
+ public boolean isUnbreakable()
+ {
+ throw new UnsupportedOperationException( "Not supported yet." );
+ }
+ }
+
+ Spigot spigot();
+ // Spigot end
}
--
2.5.0

View File

@ -1,330 +0,0 @@
From 23a21243fa55f95f91c067bccfd843f32cba170b Mon Sep 17 00:00:00 2001
From: md_5 <git@md-5.net>
Date: Sat, 13 Dec 2014 12:59:14 +1100
Subject: [PATCH] BungeeCord Chat API
diff --git a/pom.xml b/pom.xml
index 6377570..8fb67ea 100644
--- a/pom.xml
+++ b/pom.xml
@@ -83,6 +83,14 @@
<version>1.15</version>
<scope>compile</scope>
</dependency>
+ <dependency>
+ <groupId>net.md-5</groupId>
+ <artifactId>bungeecord-chat</artifactId>
+ <version>1.9-SNAPSHOT</version>
+ <type>jar</type>
+ <scope>compile</scope>
+ </dependency>
+
<!-- testing -->
<dependency>
<groupId>junit</groupId>
diff --git a/src/main/java/org/bukkit/ChatColor.java b/src/main/java/org/bukkit/ChatColor.java
index b8872b4..adbae51 100644
--- a/src/main/java/org/bukkit/ChatColor.java
+++ b/src/main/java/org/bukkit/ChatColor.java
@@ -10,95 +10,205 @@ import com.google.common.collect.Maps;
/**
* All supported color values for chat
*/
-public enum ChatColor {
+public enum ChatColor{
/**
* Represents black
*/
- BLACK('0', 0x00),
+ BLACK('0', 0x00) {
+ @Override
+ public net.md_5.bungee.api.ChatColor asBungee() {
+ return net.md_5.bungee.api.ChatColor.BLACK;
+ }
+ },
/**
* Represents dark blue
*/
- DARK_BLUE('1', 0x1),
+ DARK_BLUE('1', 0x1){
+ @Override
+ public net.md_5.bungee.api.ChatColor asBungee() {
+ return net.md_5.bungee.api.ChatColor.DARK_BLUE;
+ }
+ },
/**
* Represents dark green
*/
- DARK_GREEN('2', 0x2),
+ DARK_GREEN('2', 0x2){
+ @Override
+ public net.md_5.bungee.api.ChatColor asBungee() {
+ return net.md_5.bungee.api.ChatColor.DARK_GREEN;
+ }
+ },
/**
* Represents dark blue (aqua)
*/
- DARK_AQUA('3', 0x3),
+ DARK_AQUA('3', 0x3){
+ @Override
+ public net.md_5.bungee.api.ChatColor asBungee() {
+ return net.md_5.bungee.api.ChatColor.DARK_AQUA;
+ }
+ },
/**
* Represents dark red
*/
- DARK_RED('4', 0x4),
+ DARK_RED('4', 0x4){
+ @Override
+ public net.md_5.bungee.api.ChatColor asBungee() {
+ return net.md_5.bungee.api.ChatColor.DARK_RED;
+ }
+ },
/**
* Represents dark purple
*/
- DARK_PURPLE('5', 0x5),
+ DARK_PURPLE('5', 0x5){
+ @Override
+ public net.md_5.bungee.api.ChatColor asBungee() {
+ return net.md_5.bungee.api.ChatColor.DARK_PURPLE;
+ }
+ },
/**
* Represents gold
*/
- GOLD('6', 0x6),
+ GOLD('6', 0x6){
+ @Override
+ public net.md_5.bungee.api.ChatColor asBungee() {
+ return net.md_5.bungee.api.ChatColor.GOLD;
+ }
+ },
/**
* Represents gray
*/
- GRAY('7', 0x7),
+ GRAY('7', 0x7){
+ @Override
+ public net.md_5.bungee.api.ChatColor asBungee() {
+ return net.md_5.bungee.api.ChatColor.GRAY;
+ }
+ },
/**
* Represents dark gray
*/
- DARK_GRAY('8', 0x8),
+ DARK_GRAY('8', 0x8){
+ @Override
+ public net.md_5.bungee.api.ChatColor asBungee() {
+ return net.md_5.bungee.api.ChatColor.DARK_GRAY;
+ }
+ },
/**
* Represents blue
*/
- BLUE('9', 0x9),
+ BLUE('9', 0x9){
+ @Override
+ public net.md_5.bungee.api.ChatColor asBungee() {
+ return net.md_5.bungee.api.ChatColor.BLUE;
+ }
+ },
/**
* Represents green
*/
- GREEN('a', 0xA),
+ GREEN('a', 0xA){
+ @Override
+ public net.md_5.bungee.api.ChatColor asBungee() {
+ return net.md_5.bungee.api.ChatColor.GREEN;
+ }
+ },
/**
* Represents aqua
*/
- AQUA('b', 0xB),
+ AQUA('b', 0xB){
+ @Override
+ public net.md_5.bungee.api.ChatColor asBungee() {
+ return net.md_5.bungee.api.ChatColor.AQUA;
+ }
+ },
/**
* Represents red
*/
- RED('c', 0xC),
+ RED('c', 0xC){
+ @Override
+ public net.md_5.bungee.api.ChatColor asBungee() {
+ return net.md_5.bungee.api.ChatColor.RED;
+ }
+ },
/**
* Represents light purple
*/
- LIGHT_PURPLE('d', 0xD),
+ LIGHT_PURPLE('d', 0xD){
+ @Override
+ public net.md_5.bungee.api.ChatColor asBungee() {
+ return net.md_5.bungee.api.ChatColor.LIGHT_PURPLE;
+ }
+ },
/**
* Represents yellow
*/
- YELLOW('e', 0xE),
+ YELLOW('e', 0xE){
+ @Override
+ public net.md_5.bungee.api.ChatColor asBungee() {
+ return net.md_5.bungee.api.ChatColor.YELLOW;
+ }
+ },
/**
* Represents white
*/
- WHITE('f', 0xF),
+ WHITE('f', 0xF){
+ @Override
+ public net.md_5.bungee.api.ChatColor asBungee() {
+ return net.md_5.bungee.api.ChatColor.WHITE;
+ }
+ },
/**
* Represents magical characters that change around randomly
*/
- MAGIC('k', 0x10, true),
+ MAGIC('k', 0x10, true){
+ @Override
+ public net.md_5.bungee.api.ChatColor asBungee() {
+ return net.md_5.bungee.api.ChatColor.MAGIC;
+ }
+ },
/**
* Makes the text bold.
*/
- BOLD('l', 0x11, true),
+ BOLD('l', 0x11, true){
+ @Override
+ public net.md_5.bungee.api.ChatColor asBungee() {
+ return net.md_5.bungee.api.ChatColor.BOLD;
+ }
+ },
/**
* Makes a line appear through the text.
*/
- STRIKETHROUGH('m', 0x12, true),
+ STRIKETHROUGH('m', 0x12, true){
+ @Override
+ public net.md_5.bungee.api.ChatColor asBungee() {
+ return net.md_5.bungee.api.ChatColor.STRIKETHROUGH;
+ }
+ },
/**
* Makes the text appear underlined.
*/
- UNDERLINE('n', 0x13, true),
+ UNDERLINE('n', 0x13, true){
+ @Override
+ public net.md_5.bungee.api.ChatColor asBungee() {
+ return net.md_5.bungee.api.ChatColor.UNDERLINE;
+ }
+ },
/**
* Makes the text italic.
*/
- ITALIC('o', 0x14, true),
+ ITALIC('o', 0x14, true){
+ @Override
+ public net.md_5.bungee.api.ChatColor asBungee() {
+ return net.md_5.bungee.api.ChatColor.ITALIC;
+ }
+ },
/**
* Resets all previous chat colors or formats.
*/
- RESET('r', 0x15);
+ RESET('r', 0x15){
+ @Override
+ public net.md_5.bungee.api.ChatColor asBungee() {
+ return net.md_5.bungee.api.ChatColor.RESET;
+ }
+ };
/**
* The special character which prefixes all chat colour codes. Use this if
@@ -125,6 +235,10 @@ public enum ChatColor {
this.toString = new String(new char[] {COLOR_CHAR, code});
}
+ public net.md_5.bungee.api.ChatColor asBungee() {
+ return net.md_5.bungee.api.ChatColor.RESET;
+ };
+
/**
* Gets the char value associated with this color
*
diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java
index cdccaf3..1ae5e96 100644
--- a/src/main/java/org/bukkit/Server.java
+++ b/src/main/java/org/bukkit/Server.java
@@ -947,6 +947,24 @@ public interface Server extends PluginMessageRecipient {
{
throw new UnsupportedOperationException( "Not supported yet." );
}
+
+ /**
+ * Sends the component to the player
+ *
+ * @param component the components to send
+ */
+ public void broadcast(net.md_5.bungee.api.chat.BaseComponent component) {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ /**
+ * Sends an array of components as a single message to the player
+ *
+ * @param components the components to send
+ */
+ public void broadcast(net.md_5.bungee.api.chat.BaseComponent... components) {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
}
Spigot spigot();
diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java
index a89df18..dc58bea 100644
--- a/src/main/java/org/bukkit/entity/Player.java
+++ b/src/main/java/org/bukkit/entity/Player.java
@@ -1338,6 +1338,24 @@ public interface Player extends HumanEntity, Conversable, CommandSender, Offline
{
throw new UnsupportedOperationException( "Not supported yet." );
}
+
+ /**
+ * Sends the component to the player
+ *
+ * @param component the components to send
+ */
+ public void sendMessage(net.md_5.bungee.api.chat.BaseComponent component) {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ /**
+ * Sends an array of components as a single message to the player
+ *
+ * @param components the components to send
+ */
+ public void sendMessage(net.md_5.bungee.api.chat.BaseComponent... components) {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
}
Spigot spigot();
--
2.7.0.windows.1

View File

@ -1,27 +0,0 @@
From 785014588a688d3453f23d230ef33662d51e3556 Mon Sep 17 00:00:00 2001
From: md_5 <git@md-5.net>
Date: Mon, 13 Jul 2015 19:10:15 +1000
Subject: [PATCH] Add restart API.
diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java
index 1ae5e96..69720e9 100644
--- a/src/main/java/org/bukkit/Server.java
+++ b/src/main/java/org/bukkit/Server.java
@@ -965,6 +965,13 @@ public interface Server extends PluginMessageRecipient {
public void broadcast(net.md_5.bungee.api.chat.BaseComponent... components) {
throw new UnsupportedOperationException("Not supported yet.");
}
+
+ /**
+ * Restart the server. If the server administrator has not configured restarting, the server will stop.
+ */
+ public void restart() {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
}
Spigot spigot();
--
2.5.0

View File

@ -1,115 +0,0 @@
From 87d690ad5537531bc6eb1ac0d96dd4c21d6f64c9 Mon Sep 17 00:00:00 2001
From: md_5 <md_5@live.com.au>
Date: Tue, 2 Jul 2013 13:07:39 +1000
Subject: [PATCH] POM Changes
Basic changes to the build system which mark the artifact as Spigot, and the necessary code changes to ensure proper functionality. Also disables the auto updater provided by CraftBukkit as it is useless to us.
diff --git a/pom.xml b/pom.xml
index 452ed6c..4f7cea7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,12 +1,12 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
- <groupId>org.bukkit</groupId>
- <artifactId>craftbukkit</artifactId>
+ <groupId>org.spigotmc</groupId>
+ <artifactId>spigot</artifactId>
<packaging>jar</packaging>
<version>1.9-R0.1-SNAPSHOT</version>
- <name>CraftBukkit</name>
- <url>http://www.bukkit.org</url>
+ <name>Spigot</name>
+ <url>http://www.spigotmc.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@@ -19,10 +19,17 @@
<maven.compiler.target>1.6</maven.compiler.target>
</properties>
+ <parent>
+ <groupId>org.spigotmc</groupId>
+ <artifactId>spigot-parent</artifactId>
+ <version>dev-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
<dependencies>
<dependency>
- <groupId>org.bukkit</groupId>
- <artifactId>bukkit</artifactId>
+ <groupId>org.spigotmc</groupId>
+ <artifactId>spigot-api</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
@@ -56,6 +63,11 @@
<version>5.1.37</version>
<scope>compile</scope>
</dependency>
+ <dependency>
+ <groupId>net.sf.trove4j</groupId>
+ <artifactId>trove4j</artifactId>
+ <version>3.0.3</version>
+ </dependency>
<!-- testing -->
<dependency>
<groupId>junit</groupId>
@@ -86,11 +98,26 @@
<groupId>net.md-5</groupId>
<artifactId>scriptus</artifactId>
<version>0.2</version>
- <configuration>
- <format>git-Bukkit-%s</format>
- </configuration>
<executions>
<execution>
+ <id>ex-spigot</id>
+ <configuration>
+ <format>git-Spigot-%s</format>
+ <scmDirectory>../</scmDirectory>
+ <descriptionProperty>spigot.desc</descriptionProperty>
+ </configuration>
+ <phase>initialize</phase>
+ <goals>
+ <goal>describe</goal>
+ </goals>
+ </execution>
+ <execution>
+ <id>ex-craftbukkit</id>
+ <configuration>
+ <format>-%s</format>
+ <scmDirectory>../../CraftBukkit</scmDirectory>
+ <descriptionProperty>craftbukkit.desc</descriptionProperty>
+ </configuration>
<phase>initialize</phase>
<goals>
<goal>describe</goal>
@@ -107,7 +134,7 @@
<manifestEntries>
<Main-Class>org.bukkit.craftbukkit.Main</Main-Class>
<Implementation-Title>CraftBukkit</Implementation-Title>
- <Implementation-Version>${describe}</Implementation-Version>
+ <Implementation-Version>${spigot.desc}${craftbukkit.desc}</Implementation-Version>
<Implementation-Vendor>Bukkit Team</Implementation-Vendor>
<Specification-Title>Bukkit</Specification-Title>
<Specification-Version>${api.version}</Specification-Version>
diff --git a/src/main/java/org/bukkit/craftbukkit/util/Versioning.java b/src/main/java/org/bukkit/craftbukkit/util/Versioning.java
index f905d17..9304637 100644
--- a/src/main/java/org/bukkit/craftbukkit/util/Versioning.java
+++ b/src/main/java/org/bukkit/craftbukkit/util/Versioning.java
@@ -11,7 +11,7 @@ public final class Versioning {
public static String getBukkitVersion() {
String result = "Unknown-Version";
- InputStream stream = Bukkit.class.getClassLoader().getResourceAsStream("META-INF/maven/org.bukkit/bukkit/pom.properties");
+ InputStream stream = Bukkit.class.getClassLoader().getResourceAsStream("META-INF/maven/org.spigotmc/spigot-api/pom.properties");
Properties properties = new Properties();
if (stream != null) {
--
2.5.0

View File

@ -1,165 +0,0 @@
From 166aa5db2d713b8877a070bf885da3f94f66cfb6 Mon Sep 17 00:00:00 2001
From: md_5 <md_5@live.com.au>
Date: Sun, 2 Jun 2013 15:10:56 +1000
Subject: [PATCH] Skeleton API Implementations
This contains the basic, empty implementations for some Spigot-API extensions. They are included early in the patching progress so that compilation will still succeed midway despite the APIs only being provided by subsequent patches.
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index d330226..6b37266 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -1653,4 +1653,14 @@ public final class CraftServer implements Server {
public UnsafeValues getUnsafe() {
return CraftMagicNumbers.INSTANCE;
}
+
+ private final Spigot spigot = new Spigot()
+ {
+
+ };
+
+ public Spigot spigot()
+ {
+ return spigot;
+ }
}
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index 2c82ecb..fb84060 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -1508,4 +1508,14 @@ public class CraftWorld implements World {
cps.queueUnload(chunk.locX, chunk.locZ);
}
}
+ // Spigot start
+ private final Spigot spigot = new Spigot()
+ {
+ };
+
+ public Spigot spigot()
+ {
+ return spigot;
+ }
+ // Spigot end
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftArrow.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftArrow.java
index dca8520..bf48e6e 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftArrow.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftArrow.java
@@ -71,4 +71,15 @@ public class CraftArrow extends AbstractProjectile implements Arrow {
public void _INVALID_setShooter(LivingEntity shooter) {
getHandle().shooter = ((CraftLivingEntity) shooter).getHandle();
}
+
+ // Spigot start
+ private final Arrow.Spigot spigot = new Arrow.Spigot()
+ {
+ };
+
+ public Arrow.Spigot spigot()
+ {
+ return spigot;
+ }
+ // Spigot end
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
index 27c1851..cc88297 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
@@ -563,4 +563,15 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
public boolean isGlowing() {
return getHandle().glowing;
}
+
+ // Spigot start
+ private final Spigot spigot = new Spigot()
+ {
+ };
+
+ public Spigot spigot()
+ {
+ return spigot;
+ }
+ // Spigot end
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLightningStrike.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLightningStrike.java
index 64e346d..243e8e5 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLightningStrike.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLightningStrike.java
@@ -27,4 +27,15 @@ public class CraftLightningStrike extends CraftEntity implements LightningStrike
public EntityType getType() {
return EntityType.LIGHTNING;
}
+
+ // Spigot start
+ private final LightningStrike.Spigot spigot = new LightningStrike.Spigot() {
+
+ };
+
+ @Override
+ public LightningStrike.Spigot spigot() {
+ return spigot;
+ }
+ // Spigot end
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
index 303da2d..01ba89f 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -1402,4 +1402,15 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
getHandle().playerConnection.sendPacket(packetplayoutworldparticles);
}
+
+ // Spigot start
+ private final Player.Spigot spigot = new Player.Spigot()
+ {
+ };
+
+ public Player.Spigot spigot()
+ {
+ return spigot;
+ }
+ // Spigot end
}
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
index 294f6c9..0a5edb5 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
@@ -820,4 +820,16 @@ class CraftMetaItem implements ItemMeta, Repairable {
return HANDLED_TAGS;
}
}
+
+ // Spigot start
+ private final Spigot spigot = new Spigot()
+ {
+ };
+
+ @Override
+ public Spigot spigot()
+ {
+ return spigot;
+ }
+ // Spigot end
}
diff --git a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScore.java b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScore.java
index d3ae91b..0b71b53 100644
--- a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScore.java
+++ b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScore.java
@@ -59,4 +59,11 @@ final class CraftScore implements Score {
public CraftScoreboard getScoreboard() {
return objective.getScoreboard();
}
+
+ // Spigot start
+ @Override
+ public boolean isScoreSet() throws IllegalStateException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+ // Spigot end
}
--
2.5.0

File diff suppressed because it is too large Load Diff

View File

@ -1,27 +0,0 @@
From 2c942605d485c7bfc6ab5830baabd792f4d76be6 Mon Sep 17 00:00:00 2001
From: md_5 <git@md-5.net>
Date: Mon, 14 Apr 2014 10:38:04 +1000
Subject: [PATCH] Obfuscation Helpers
Provides several friendly named methods which map to a obfuscated method. Obfuscated methods which are used frequently should be added to this file to ease with updates to new Minecraft versions.
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 318d68a..c226e01 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -1268,6 +1268,12 @@ public abstract class MinecraftServer implements Runnable, ICommandListener, IAs
}
+ // Spigot Start
+ public ServerConnection getServerConnection()
+ {
+ return this.p;
+ }
+ // Spigot End
public ServerConnection am() {
return this.p;
}
--
2.5.0

View File

@ -1,340 +0,0 @@
From 990c91d3496dc24aca7e201b7bb46c7fce3f0279 Mon Sep 17 00:00:00 2001
From: md_5 <md_5@live.com.au>
Date: Sun, 7 Jul 2013 09:32:53 +1000
Subject: [PATCH] Spigot Configuration
Provides the basic infrastructure to load and save the Spigot configuration file, spigot.yml
diff --git a/src/main/java/net/minecraft/server/DedicatedServer.java b/src/main/java/net/minecraft/server/DedicatedServer.java
index 6d80991..9a38cca 100644
--- a/src/main/java/net/minecraft/server/DedicatedServer.java
+++ b/src/main/java/net/minecraft/server/DedicatedServer.java
@@ -165,6 +165,11 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer
if (this.P() < 0) {
this.setPort(this.propertyManager.getInt("server-port", 25565));
}
+ // Spigot start
+ this.a((PlayerList) (new DedicatedPlayerList(this)));
+ org.spigotmc.SpigotConfig.init((File) options.valueOf("spigot-settings"));
+ org.spigotmc.SpigotConfig.registerCommands();
+ // Spigot end
DedicatedServer.LOGGER.info("Generating keypair");
this.a(MinecraftEncryption.b());
@@ -179,7 +184,11 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer
return false;
}
- this.a((PlayerList) (new DedicatedPlayerList(this))); // CraftBukkit
+ // Spigot Start - Move DedicatedPlayerList up and bring plugin loading from CraftServer to here
+ // this.a((PlayerList) (new DedicatedPlayerList(this))); // CraftBukkit
+ server.loadPlugins();
+ server.enablePlugins(org.bukkit.plugin.PluginLoadOrder.STARTUP);
+ // Spigot End
if (!this.getOnlineMode()) {
DedicatedServer.LOGGER.warn("**** SERVER IS RUNNING IN OFFLINE/INSECURE MODE!");
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
index f5b497c..fa104d1 100644
--- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java
@@ -97,6 +97,7 @@ public abstract class World implements IBlockAccess {
public long ticksPerMonsterSpawns;
public boolean populating;
private int tickPosition;
+ public final org.spigotmc.SpigotWorldConfig spigotConfig; // Spigot
public CraftWorld getWorld() {
return this.world;
@@ -111,6 +112,7 @@ public abstract class World implements IBlockAccess {
}
protected World(IDataManager idatamanager, WorldData worlddata, WorldProvider worldprovider, MethodProfiler methodprofiler, boolean flag, ChunkGenerator gen, org.bukkit.World.Environment env) {
+ this.spigotConfig = new org.spigotmc.SpigotWorldConfig( worlddata.getName() ); // Spigot
this.generator = gen;
this.world = new CraftWorld((WorldServer) this, gen, env);
this.ticksPerAnimalSpawns = this.getServer().getTicksPerAnimalSpawns(); // CraftBukkit
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index 6b37266..91965c0 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -252,8 +252,10 @@ public final class CraftServer implements Server {
chunkGCLoadThresh = configuration.getInt("chunk-gc.load-threshold");
loadIcon();
- loadPlugins();
- enablePlugins(PluginLoadOrder.STARTUP);
+ // Spigot Start - Moved to old location of new DedicatedPlayerList in DedicatedServer
+ // loadPlugins();
+ // enablePlugins(PluginLoadOrder.STARTUP);
+ // Spigot End
}
public boolean getCommandBlockOverride(String command) {
@@ -674,6 +676,7 @@ public final class CraftServer implements Server {
logger.log(Level.WARNING, "Failed to load banned-players.json, " + ex.getMessage());
}
+ org.spigotmc.SpigotConfig.init((File) console.options.valueOf("spigot-settings")); // Spigot
for (WorldServer world : console.worlds) {
world.worldData.setDifficulty(difficulty);
world.setSpawnFlags(monsters, animals);
@@ -688,11 +691,14 @@ public final class CraftServer implements Server {
} else {
world.ticksPerMonsterSpawns = this.getTicksPerMonsterSpawns();
}
+ world.spigotConfig.init(); // Spigot
}
pluginManager.clearPlugins();
commandMap.clearCommands();
resetRecipes();
+ org.spigotmc.SpigotConfig.registerCommands(); // Spigot
+
overrideAllCommandBlockCommands = commandsConfiguration.getStringList("command-block-overrides").contains("*");
int pollCount = 0;
diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java
index 4e642b7..aca0d97 100644
--- a/src/main/java/org/bukkit/craftbukkit/Main.java
+++ b/src/main/java/org/bukkit/craftbukkit/Main.java
@@ -114,6 +114,14 @@ public class Main {
acceptsAll(asList("v", "version"), "Show the CraftBukkit Version");
acceptsAll(asList("demo"), "Demo mode");
+
+ // Spigot Start
+ acceptsAll(asList("S", "spigot-settings"), "File for spigot settings")
+ .withRequiredArg()
+ .ofType(File.class)
+ .defaultsTo(new File("spigot.yml"))
+ .describedAs("Yml file");
+ // Spigot End
}
};
diff --git a/src/main/java/org/spigotmc/SpigotConfig.java b/src/main/java/org/spigotmc/SpigotConfig.java
new file mode 100644
index 0000000..cb88089
--- /dev/null
+++ b/src/main/java/org/spigotmc/SpigotConfig.java
@@ -0,0 +1,139 @@
+package org.spigotmc;
+
+import com.google.common.base.Throwables;
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Level;
+import net.minecraft.server.MinecraftServer;
+import org.bukkit.Bukkit;
+import org.bukkit.command.Command;
+import org.bukkit.configuration.InvalidConfigurationException;
+import org.bukkit.configuration.file.YamlConfiguration;
+
+public class SpigotConfig
+{
+
+ private static File CONFIG_FILE;
+ private static final String HEADER = "This is the main configuration file for Spigot.\n"
+ + "As you can see, there's tons to configure. Some options may impact gameplay, so use\n"
+ + "with caution, and make sure you know what each option does before configuring.\n"
+ + "For a reference for any variable inside this file, check out the Spigot wiki at\n"
+ + "http://www.spigotmc.org/wiki/spigot-configuration/\n"
+ + "\n"
+ + "If you need help with the configuration or have any questions related to Spigot,\n"
+ + "join us at the IRC or drop by our forums and leave a post.\n"
+ + "\n"
+ + "IRC: #spigot @ irc.spi.gt ( http://www.spigotmc.org/pages/irc/ )\n"
+ + "Forums: http://www.spigotmc.org/\n";
+ /*========================================================================*/
+ public static YamlConfiguration config;
+ static int version;
+ static Map<String, Command> commands;
+ /*========================================================================*/
+
+ public static void init(File configFile)
+ {
+ CONFIG_FILE = configFile;
+ config = new YamlConfiguration();
+ try
+ {
+ config.load( CONFIG_FILE );
+ } catch ( IOException ex )
+ {
+ } catch ( InvalidConfigurationException ex )
+ {
+ Bukkit.getLogger().log( Level.SEVERE, "Could not load spigot.yml, please correct your syntax errors", ex );
+ throw Throwables.propagate( ex );
+ }
+
+ config.options().header( HEADER );
+ config.options().copyDefaults( true );
+
+ commands = new HashMap<String, Command>();
+
+ version = getInt( "config-version", 8 );
+ set( "config-version", 8 );
+ readConfig( SpigotConfig.class, null );
+ }
+
+ public static void registerCommands()
+ {
+ for ( Map.Entry<String, Command> entry : commands.entrySet() )
+ {
+ MinecraftServer.getServer().server.getCommandMap().register( entry.getKey(), "Spigot", entry.getValue() );
+ }
+ }
+
+ static void readConfig(Class<?> clazz, Object instance)
+ {
+ for ( Method method : clazz.getDeclaredMethods() )
+ {
+ if ( Modifier.isPrivate( method.getModifiers() ) )
+ {
+ if ( method.getParameterTypes().length == 0 && method.getReturnType() == Void.TYPE )
+ {
+ try
+ {
+ method.setAccessible( true );
+ method.invoke( instance );
+ } catch ( InvocationTargetException ex )
+ {
+ throw Throwables.propagate( ex.getCause() );
+ } catch ( Exception ex )
+ {
+ Bukkit.getLogger().log( Level.SEVERE, "Error invoking " + method, ex );
+ }
+ }
+ }
+ }
+
+ try
+ {
+ config.save( CONFIG_FILE );
+ } catch ( IOException ex )
+ {
+ Bukkit.getLogger().log( Level.SEVERE, "Could not save " + CONFIG_FILE, ex );
+ }
+ }
+
+ private static void set(String path, Object val)
+ {
+ config.set( path, val );
+ }
+
+ private static boolean getBoolean(String path, boolean def)
+ {
+ config.addDefault( path, def );
+ return config.getBoolean( path, config.getBoolean( path ) );
+ }
+
+ private static int getInt(String path, int def)
+ {
+ config.addDefault( path, def );
+ return config.getInt( path, config.getInt( path ) );
+ }
+
+ private static <T> List getList(String path, T def)
+ {
+ config.addDefault( path, def );
+ return (List<T>) config.getList( path, config.getList( path ) );
+ }
+
+ private static String getString(String path, String def)
+ {
+ config.addDefault( path, def );
+ return config.getString( path, config.getString( path ) );
+ }
+
+ private static double getDouble(String path, double def)
+ {
+ config.addDefault( path, def );
+ return config.getDouble( path, config.getDouble( path ) );
+ }
+}
diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java
new file mode 100644
index 0000000..961ddb4
--- /dev/null
+++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java
@@ -0,0 +1,71 @@
+package org.spigotmc;
+
+import java.util.List;
+import org.bukkit.Bukkit;
+import org.bukkit.configuration.file.YamlConfiguration;
+
+public class SpigotWorldConfig
+{
+
+ private final String worldName;
+ private final YamlConfiguration config;
+ private boolean verbose;
+
+ public SpigotWorldConfig(String worldName)
+ {
+ this.worldName = worldName;
+ this.config = SpigotConfig.config;
+ init();
+ }
+
+ public void init()
+ {
+ this.verbose = getBoolean( "verbose", true );
+
+ log( "-------- World Settings For [" + worldName + "] --------" );
+ SpigotConfig.readConfig( SpigotWorldConfig.class, this );
+ }
+
+ private void log(String s)
+ {
+ if ( verbose )
+ {
+ Bukkit.getLogger().info( s );
+ }
+ }
+
+ private void set(String path, Object val)
+ {
+ config.set( "world-settings.default." + path, val );
+ }
+
+ private boolean getBoolean(String path, boolean def)
+ {
+ config.addDefault( "world-settings.default." + path, def );
+ return config.getBoolean( "world-settings." + worldName + "." + path, config.getBoolean( "world-settings.default." + path ) );
+ }
+
+ private double getDouble(String path, double def)
+ {
+ config.addDefault( "world-settings.default." + path, def );
+ return config.getDouble( "world-settings." + worldName + "." + path, config.getDouble( "world-settings.default." + path ) );
+ }
+
+ private int getInt(String path, int def)
+ {
+ config.addDefault( "world-settings.default." + path, def );
+ return config.getInt( "world-settings." + worldName + "." + path, config.getInt( "world-settings.default." + path ) );
+ }
+
+ private <T> List getList(String path, T def)
+ {
+ config.addDefault( "world-settings.default." + path, def );
+ return (List<T>) config.getList( "world-settings." + worldName + "." + path, config.getList( "world-settings.default." + path ) );
+ }
+
+ private String getString(String path, String def)
+ {
+ config.addDefault( "world-settings.default." + path, def );
+ return config.getString( "world-settings." + worldName + "." + path, config.getString( "world-settings.default." + path ) );
+ }
+}
--
2.5.0

View File

@ -1,164 +0,0 @@
From bf9a9c1ba24bbc4cc668647b5e123717ba9defa9 Mon Sep 17 00:00:00 2001
From: md_5 <git@md-5.net>
Date: Mon, 7 Mar 2016 22:14:13 +1100
Subject: [PATCH] Crop Growth Rates
Allows configuring the growth rates of crops as a percentage of their normal growth rate.
diff --git a/src/main/java/net/minecraft/server/Block.java b/src/main/java/net/minecraft/server/Block.java
index 57f3981..12589d6 100644
--- a/src/main/java/net/minecraft/server/Block.java
+++ b/src/main/java/net/minecraft/server/Block.java
@@ -857,4 +857,16 @@ public class Block {
private static void a(int i, String s, Block block) {
a(i, new MinecraftKey(s), block);
}
+
+ // Spigot start
+ public static float range(float min, float value, float max) {
+ if (value < min) {
+ return min;
+ }
+ if (value > max) {
+ return max;
+ }
+ return value;
+ }
+ // Spigot end
}
diff --git a/src/main/java/net/minecraft/server/BlockCactus.java b/src/main/java/net/minecraft/server/BlockCactus.java
index f4b90e1..c00d874 100644
--- a/src/main/java/net/minecraft/server/BlockCactus.java
+++ b/src/main/java/net/minecraft/server/BlockCactus.java
@@ -31,7 +31,7 @@ public class BlockCactus extends Block {
if (i < 3) {
int j = ((Integer) iblockdata.get(BlockCactus.AGE)).intValue();
- if (j == 15) {
+ if (j >= (byte) range(3, ((100 / world.spigotConfig.cactusModifier) * 15) + 0.5F, 15)) { // Spigot
// world.setTypeUpdate(blockposition1, this.getBlockData()); // CraftBukkit
IBlockData iblockdata1 = iblockdata.set(BlockCactus.AGE, Integer.valueOf(0));
diff --git a/src/main/java/net/minecraft/server/BlockCrops.java b/src/main/java/net/minecraft/server/BlockCrops.java
index 062f769..7c909d8 100644
--- a/src/main/java/net/minecraft/server/BlockCrops.java
+++ b/src/main/java/net/minecraft/server/BlockCrops.java
@@ -54,7 +54,7 @@ public class BlockCrops extends BlockPlant implements IBlockFragilePlantElement
if (i < this.g()) {
float f = a((Block) this, world, blockposition);
- if (random.nextInt((int) (25.0F / f) + 1) == 0) {
+ if (random.nextInt((int) ((100 / world.spigotConfig.wheatModifier) * (25.0F / f)) + 1) == 0) { // Spigot
// CraftBukkit start
IBlockData data = this.setAge(i + 1);
CraftEventFactory.handleBlockGrowEvent(world, blockposition.getX(), blockposition.getY(), blockposition.getZ(), this, toLegacyData(data));
diff --git a/src/main/java/net/minecraft/server/BlockMushroom.java b/src/main/java/net/minecraft/server/BlockMushroom.java
index fa7919e..6148691 100644
--- a/src/main/java/net/minecraft/server/BlockMushroom.java
+++ b/src/main/java/net/minecraft/server/BlockMushroom.java
@@ -23,7 +23,7 @@ public class BlockMushroom extends BlockPlant implements IBlockFragilePlantEleme
public void b(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) {
final int sourceX = blockposition.getX(), sourceY = blockposition.getY(), sourceZ = blockposition.getZ(); // CraftBukkit
- if (random.nextInt(25) == 0) {
+ if (random.nextInt(Math.max(1, (int) (100 / world.spigotConfig.mushroomModifier) * 25)) == 0) { // Spigot
int i = 5;
boolean flag = true;
Iterator iterator = BlockPosition.b(blockposition.a(-4, -1, -4), blockposition.a(4, 1, 4)).iterator();
diff --git a/src/main/java/net/minecraft/server/BlockNetherWart.java b/src/main/java/net/minecraft/server/BlockNetherWart.java
index b2ca55f..ff485b0 100644
--- a/src/main/java/net/minecraft/server/BlockNetherWart.java
+++ b/src/main/java/net/minecraft/server/BlockNetherWart.java
@@ -29,7 +29,7 @@ public class BlockNetherWart extends BlockPlant {
public void b(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) {
int i = ((Integer) iblockdata.get(BlockNetherWart.AGE)).intValue();
- if (i < 3 && random.nextInt(10) == 0) {
+ if (i < 3 && random.nextInt(Math.max(1, (int) (100 / world.spigotConfig.wartModifier) * 10)) == 0) { // Spigot
iblockdata = iblockdata.set(BlockNetherWart.AGE, Integer.valueOf(i + 1));
// world.setTypeAndData(blockposition, iblockdata, 2); // CraftBukkit
org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(world, blockposition.getX(), blockposition.getY(), blockposition.getZ(), this, toLegacyData(iblockdata)); // CraftBukkit
diff --git a/src/main/java/net/minecraft/server/BlockReed.java b/src/main/java/net/minecraft/server/BlockReed.java
index f507b83..fb19f19 100644
--- a/src/main/java/net/minecraft/server/BlockReed.java
+++ b/src/main/java/net/minecraft/server/BlockReed.java
@@ -30,7 +30,7 @@ public class BlockReed extends Block {
if (i < 3) {
int j = ((Integer) iblockdata.get(BlockReed.AGE)).intValue();
- if (j == 15) {
+ if (j >= (byte) range(3, ((100 / world.spigotConfig.caneModifier) * 15) + 0.5F, 15)) { // Spigot
// CraftBukkit start
// world.setTypeUpdate(blockposition.up(), this.getBlockData()); // CraftBukkit
BlockPosition upPos = blockposition.up();
diff --git a/src/main/java/net/minecraft/server/BlockSapling.java b/src/main/java/net/minecraft/server/BlockSapling.java
index a2691a5..8b34250 100644
--- a/src/main/java/net/minecraft/server/BlockSapling.java
+++ b/src/main/java/net/minecraft/server/BlockSapling.java
@@ -34,7 +34,7 @@ public class BlockSapling extends BlockPlant implements IBlockFragilePlantElemen
public void b(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) {
if (!world.isClientSide) {
super.b(world, blockposition, iblockdata, random);
- if (world.getLightLevel(blockposition.up()) >= 9 && random.nextInt(7) == 0) {
+ if (world.getLightLevel(blockposition.up()) >= 9 && random.nextInt(Math.max(2, (int) (((100 / world.spigotConfig.saplingModifier) * 7) + 0.5F))) == 0) { // Spigot
// CraftBukkit start
world.captureTreeGeneration = true;
// CraftBukkit end
diff --git a/src/main/java/net/minecraft/server/BlockStem.java b/src/main/java/net/minecraft/server/BlockStem.java
index 41200fa..097d11e 100644
--- a/src/main/java/net/minecraft/server/BlockStem.java
+++ b/src/main/java/net/minecraft/server/BlockStem.java
@@ -50,7 +50,7 @@ public class BlockStem extends BlockPlant implements IBlockFragilePlantElement {
if (world.getLightLevel(blockposition.up()) >= 9) {
float f = BlockCrops.a((Block) this, world, blockposition);
- if (random.nextInt((int) (25.0F / f) + 1) == 0) {
+ if (random.nextInt((int) ((100 / (this == Blocks.PUMPKIN_STEM ? world.spigotConfig.pumpkinModifier : world.spigotConfig.melonModifier)) * (25.0F / f)) + 1) == 0) { // Spigot
int i = ((Integer) iblockdata.get(BlockStem.AGE)).intValue();
if (i < 7) {
diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java
index 961ddb4..8860a96 100644
--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java
+++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java
@@ -68,4 +68,37 @@ public class SpigotWorldConfig
config.addDefault( "world-settings.default." + path, def );
return config.getString( "world-settings." + worldName + "." + path, config.getString( "world-settings.default." + path ) );
}
+
+ // Crop growth rates
+ public int cactusModifier;
+ public int caneModifier;
+ public int melonModifier;
+ public int mushroomModifier;
+ public int pumpkinModifier;
+ public int saplingModifier;
+ public int wheatModifier;
+ public int wartModifier;
+ private int getAndValidateGrowth(String crop)
+ {
+ int modifier = getInt( "growth." + crop.toLowerCase() + "-modifier", 100 );
+ if ( modifier == 0 )
+ {
+ log( "Cannot set " + crop + " growth to zero, defaulting to 100" );
+ modifier = 100;
+ }
+ log( crop + " Growth Modifier: " + modifier + "%" );
+
+ return modifier;
+ }
+ private void growthModifiers()
+ {
+ cactusModifier = getAndValidateGrowth( "Cactus" );
+ caneModifier = getAndValidateGrowth( "Cane" );
+ melonModifier = getAndValidateGrowth( "Melon" );
+ mushroomModifier = getAndValidateGrowth( "Mushroom" );
+ pumpkinModifier = getAndValidateGrowth( "Pumpkin" );
+ saplingModifier = getAndValidateGrowth( "Sapling" );
+ wheatModifier = getAndValidateGrowth( "Wheat" );
+ wartModifier = getAndValidateGrowth( "NetherWart" );
+ }
}
--
2.5.0

View File

@ -1,98 +0,0 @@
From e96dfe4a2034662ef8c10920a9e2bfec4466bf8c Mon Sep 17 00:00:00 2001
From: md_5 <md_5@live.com.au>
Date: Sat, 23 Mar 2013 09:46:33 +1100
Subject: [PATCH] Merge tweaks and configuration
This allows the merging of Experience orbs, as well as the configuration of the merge radius of items. Additionally it refactors the merge algorithm to be a better experience for players.
diff --git a/src/main/java/net/minecraft/server/EntityItem.java b/src/main/java/net/minecraft/server/EntityItem.java
index 6009cac..7ea1150 100644
--- a/src/main/java/net/minecraft/server/EntityItem.java
+++ b/src/main/java/net/minecraft/server/EntityItem.java
@@ -123,7 +123,10 @@ public class EntityItem extends Entity {
}
private void x() {
- Iterator iterator = this.world.a(EntityItem.class, this.getBoundingBox().grow(0.5D, 0.0D, 0.5D)).iterator();
+ // Spigot start
+ double radius = world.spigotConfig.itemMerge;
+ Iterator iterator = this.world.a(EntityItem.class, this.getBoundingBox().grow(radius, radius, radius)).iterator();
+ // Spigot end
while (iterator.hasNext()) {
EntityItem entityitem = (EntityItem) iterator.next();
@@ -157,12 +160,14 @@ public class EntityItem extends Entity {
} else if (itemstack1.count + itemstack.count > itemstack1.getMaxStackSize()) {
return false;
} else {
- if (org.bukkit.craftbukkit.event.CraftEventFactory.callItemMergeEvent(this, entityitem).isCancelled()) return false; // CraftBukkit
- itemstack1.count += itemstack.count;
- entityitem.pickupDelay = Math.max(entityitem.pickupDelay, this.pickupDelay);
- entityitem.age = Math.min(entityitem.age, this.age);
- entityitem.setItemStack(itemstack1);
- this.die();
+ // Spigot start
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callItemMergeEvent(entityitem, this).isCancelled()) return false; // CraftBukkit
+ itemstack.count += itemstack1.count;
+ this.pickupDelay = Math.max(entityitem.pickupDelay, this.pickupDelay);
+ this.age = Math.min(entityitem.age, this.age);
+ this.setItemStack(itemstack);
+ entityitem.die();
+ // Spigot end
return true;
}
} else {
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
index c94fbb6..1ee65dd 100644
--- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java
@@ -927,6 +927,23 @@ public abstract class World implements IBlockAccess {
// Not all projectiles extend EntityProjectile, so check for Bukkit interface instead
event = CraftEventFactory.callProjectileLaunchEvent(entity);
}
+ // Spigot start
+ else if (entity instanceof EntityExperienceOrb) {
+ EntityExperienceOrb xp = (EntityExperienceOrb) entity;
+ double radius = spigotConfig.expMerge;
+ if (radius > 0) {
+ List<Entity> entities = this.getEntities(entity, entity.getBoundingBox().grow(radius, radius, radius));
+ for (Entity e : entities) {
+ if (e instanceof EntityExperienceOrb) {
+ EntityExperienceOrb loopItem = (EntityExperienceOrb) e;
+ if (!loopItem.dead) {
+ xp.value += loopItem.value;
+ loopItem.die();
+ }
+ }
+ }
+ }
+ } // Spigot end
if (event != null && (event.isCancelled() || entity.dead)) {
entity.dead = true;
diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java
index 8860a96..d4fb83c 100644
--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java
+++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java
@@ -101,4 +101,18 @@ public class SpigotWorldConfig
wheatModifier = getAndValidateGrowth( "Wheat" );
wartModifier = getAndValidateGrowth( "NetherWart" );
}
+
+ public double itemMerge;
+ private void itemMerge()
+ {
+ itemMerge = getDouble("merge-radius.item", 2.5 );
+ log( "Item Merge Radius: " + itemMerge );
+ }
+
+ public double expMerge;
+ private void expMerge()
+ {
+ expMerge = getDouble("merge-radius.exp", 3.0 );
+ log( "Experience Merge Radius: " + expMerge );
+ }
}
--
2.5.0

View File

@ -1,185 +0,0 @@
From 5de73dd3d1df8ba2273c6b4192833ce7ffe5f0de Mon Sep 17 00:00:00 2001
From: md_5 <git@md-5.net>
Date: Tue, 25 Mar 2014 16:10:01 +1100
Subject: [PATCH] Async Operation Catching
Catch and throw an exception when a potentially unsafe operation occurs on a thread other than the main server thread.
diff --git a/src/main/java/net/minecraft/server/Block.java b/src/main/java/net/minecraft/server/Block.java
index 12589d6..1d2f580 100644
--- a/src/main/java/net/minecraft/server/Block.java
+++ b/src/main/java/net/minecraft/server/Block.java
@@ -274,9 +274,13 @@ public class Block {
return 10;
}
- public void onPlace(World world, BlockPosition blockposition, IBlockData iblockdata) {}
+ public void onPlace(World world, BlockPosition blockposition, IBlockData iblockdata) {
+ org.spigotmc.AsyncCatcher.catchOp( "block onPlace"); // Spigot
+ }
- public void remove(World world, BlockPosition blockposition, IBlockData iblockdata) {}
+ public void remove(World world, BlockPosition blockposition, IBlockData iblockdata) {
+ org.spigotmc.AsyncCatcher.catchOp( "block remove"); // Spigot
+ }
public int a(Random random) {
return 1;
diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java
index 7004b58..6e3bcd7 100644
--- a/src/main/java/net/minecraft/server/EntityLiving.java
+++ b/src/main/java/net/minecraft/server/EntityLiving.java
@@ -620,6 +620,7 @@ public abstract class EntityLiving extends Entity {
}
public void addEffect(MobEffect mobeffect) {
+ org.spigotmc.AsyncCatcher.catchOp( "effect add"); // Spigot
// CraftBukkit start
if (isTickingEffects) {
effectsToProcess.add(mobeffect);
diff --git a/src/main/java/net/minecraft/server/EntityTracker.java b/src/main/java/net/minecraft/server/EntityTracker.java
index ed9b0e5..0c19e5a 100644
--- a/src/main/java/net/minecraft/server/EntityTracker.java
+++ b/src/main/java/net/minecraft/server/EntityTracker.java
@@ -102,6 +102,7 @@ public class EntityTracker {
}
public void addEntity(Entity entity, int i, final int j, boolean flag) {
+ org.spigotmc.AsyncCatcher.catchOp( "entity track"); // Spigot
try {
if (this.trackedEntities.b(entity.getId())) {
throw new IllegalStateException("Entity is already tracked!");
@@ -146,6 +147,7 @@ public class EntityTracker {
}
public void untrackEntity(Entity entity) {
+ org.spigotmc.AsyncCatcher.catchOp( "entity untrack"); // Spigot
if (entity instanceof EntityPlayer) {
EntityPlayer entityplayer = (EntityPlayer) entity;
Iterator iterator = this.c.iterator();
diff --git a/src/main/java/net/minecraft/server/EntityTrackerEntry.java b/src/main/java/net/minecraft/server/EntityTrackerEntry.java
index 8b38bd2..f8570a8 100644
--- a/src/main/java/net/minecraft/server/EntityTrackerEntry.java
+++ b/src/main/java/net/minecraft/server/EntityTrackerEntry.java
@@ -324,6 +324,7 @@ public class EntityTrackerEntry {
}
public void updatePlayer(EntityPlayer entityplayer) {
+ org.spigotmc.AsyncCatcher.catchOp( "player tracker update"); // Spigot
if (entityplayer != this.tracker) {
if (this.c(entityplayer)) {
if (!this.trackedPlayers.contains(entityplayer) && (this.e(entityplayer) || this.tracker.attachedToPlayer)) {
@@ -558,6 +559,7 @@ public class EntityTrackerEntry {
}
public void clear(EntityPlayer entityplayer) {
+ org.spigotmc.AsyncCatcher.catchOp( "player tracker clear"); // Spigot
if (this.trackedPlayers.contains(entityplayer)) {
this.trackedPlayers.remove(entityplayer);
this.tracker.c(entityplayer);
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
index e548d00..c73f0ef 100644
--- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java
@@ -897,6 +897,7 @@ public abstract class World implements IBlockAccess {
}
public boolean addEntity(Entity entity, SpawnReason spawnReason) { // Changed signature, added SpawnReason
+ org.spigotmc.AsyncCatcher.catchOp( "entity add"); // Spigot
if (entity == null) return false;
// CraftBukkit end
int i = MathHelper.floor(entity.locX / 16.0D);
@@ -1003,6 +1004,7 @@ public abstract class World implements IBlockAccess {
}
public void removeEntity(Entity entity) {
+ org.spigotmc.AsyncCatcher.catchOp( "entity remove"); // Spigot
entity.b(false);
entity.die();
if (entity instanceof EntityHuman) {
@@ -2446,6 +2448,7 @@ public abstract class World implements IBlockAccess {
}
public void a(Collection<Entity> collection) {
+ org.spigotmc.AsyncCatcher.catchOp( "entity world add"); // Spigot
// CraftBukkit start
// this.entityList.addAll(collection);
Iterator iterator = collection.iterator();
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index 0dcdeab..dfe58c6 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -169,6 +169,7 @@ public class CraftWorld implements World {
}
public boolean unloadChunkRequest(int x, int z, boolean safe) {
+ org.spigotmc.AsyncCatcher.catchOp( "chunk unload"); // Spigot
if (safe && isChunkInUse(x, z)) {
return false;
}
@@ -179,6 +180,7 @@ public class CraftWorld implements World {
}
public boolean unloadChunk(int x, int z, boolean save, boolean safe) {
+ org.spigotmc.AsyncCatcher.catchOp( "chunk unload"); // Spigot
if (isChunkInUse(x, z)) {
return false;
}
@@ -261,6 +263,7 @@ public class CraftWorld implements World {
}
public boolean loadChunk(int x, int z, boolean generate) {
+ org.spigotmc.AsyncCatcher.catchOp( "chunk load"); // Spigot
chunkLoadCount++;
if (generate) {
// Use the default variant of loadChunk when generate == true.
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
index 01ba89f..e93cedb 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -211,6 +211,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
@Override
public void kickPlayer(String message) {
+ org.spigotmc.AsyncCatcher.catchOp( "player kick"); // Spigot
if (getHandle().playerConnection == null) return;
getHandle().playerConnection.disconnect(message == null ? "" : message);
diff --git a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardManager.java b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardManager.java
index 69fcb10..3992c71 100644
--- a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardManager.java
+++ b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardManager.java
@@ -42,6 +42,7 @@ public final class CraftScoreboardManager implements ScoreboardManager {
}
public CraftScoreboard getNewScoreboard() {
+ org.spigotmc.AsyncCatcher.catchOp( "scoreboard creation"); // Spigot
CraftScoreboard scoreboard = new CraftScoreboard(new ScoreboardServer(server));
scoreboards.add(scoreboard);
return scoreboard;
diff --git a/src/main/java/org/spigotmc/AsyncCatcher.java b/src/main/java/org/spigotmc/AsyncCatcher.java
new file mode 100644
index 0000000..4b3aa85
--- /dev/null
+++ b/src/main/java/org/spigotmc/AsyncCatcher.java
@@ -0,0 +1,17 @@
+package org.spigotmc;
+
+import net.minecraft.server.MinecraftServer;
+
+public class AsyncCatcher
+{
+
+ public static boolean enabled = true;
+
+ public static void catchOp(String reason)
+ {
+ if ( enabled && Thread.currentThread() != MinecraftServer.getServer().primaryThread )
+ {
+ throw new IllegalStateException( "Asynchronous " + reason + "!" );
+ }
+ }
+}
--
2.5.0

View File

@ -1,55 +0,0 @@
From 76af8264cfaab9954e9733d2822a35a9ab28817b Mon Sep 17 00:00:00 2001
From: md_5 <md_5@live.com.au>
Date: Sat, 23 Mar 2013 09:52:41 +1100
Subject: [PATCH] View Distance
This commit allows the user to select per world view distances, and view distances below 3. Be wary of the issues selecting a view distance of 1 or 2 may cause!
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index 13d47d7..8ef7eb2 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -49,9 +49,9 @@ public class PlayerChunkMap {
private boolean m = true;
private boolean wasNotEmpty; // CraftBukkit - add field
- public PlayerChunkMap(WorldServer worldserver) {
+ public PlayerChunkMap(WorldServer worldserver, int viewDistance /* Spigot */) {
this.world = worldserver;
- this.a(worldserver.getMinecraftServer().getPlayerList().s());
+ this.a(viewDistance); // Spigot
}
public WorldServer getWorld() {
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
index c65e557..59b78bb 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java
@@ -57,7 +57,7 @@ public class WorldServer extends World implements IAsyncTaskHandler {
// CraftBukkit end
this.server = minecraftserver;
this.tracker = new EntityTracker(this);
- this.manager = new PlayerChunkMap(this);
+ this.manager = new PlayerChunkMap(this, spigotConfig.viewDistance); // Spigot
this.worldProvider.a((World) this);
this.chunkProvider = this.n();
this.portalTravelAgent = new org.bukkit.craftbukkit.CraftTravelAgent(this); // CraftBukkit
diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java
index d4fb83c..86300d6 100644
--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java
+++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java
@@ -115,4 +115,11 @@ public class SpigotWorldConfig
expMerge = getDouble("merge-radius.exp", 3.0 );
log( "Experience Merge Radius: " + expMerge );
}
+
+ public int viewDistance;
+ private void viewDistance()
+ {
+ viewDistance = getInt( "view-distance", Bukkit.getViewDistance() );
+ log( "View Distance: " + viewDistance );
+ }
}
--
2.5.0

View File

@ -1,877 +0,0 @@
From bb377d35a2ce39ec624b3e9c3761c28c46fc9367 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Thu, 10 Jan 2013 00:18:11 -0500
Subject: [PATCH] Spigot Timings
Overhauls the Timings System adding performance tracking all around the Minecraft Server
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
index 582e684..7980e80 100644
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -834,6 +834,7 @@ public class Chunk {
}
public void loadNearby(IChunkProvider ichunkprovider, ChunkGenerator chunkgenerator) {
+ world.timings.syncChunkLoadPostTimer.startTiming(); // Spigot
Chunk chunk = ichunkprovider.getLoadedChunkAt(this.locX, this.locZ - 1);
Chunk chunk1 = ichunkprovider.getLoadedChunkAt(this.locX + 1, this.locZ);
Chunk chunk2 = ichunkprovider.getLoadedChunkAt(this.locX, this.locZ + 1);
@@ -858,6 +859,7 @@ public class Chunk {
chunk4.a(chunkgenerator);
}
}
+ world.timings.syncChunkLoadPostTimer.stopTiming(); // Spigot
}
diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java
index 22c17db..162613b 100644
--- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
+++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java
@@ -154,6 +154,7 @@ public class ChunkProviderServer implements IChunkProvider {
// CraftBukkit end
if (chunk == null) {
+ world.timings.syncChunkLoadTimer.startTiming(); // Spigot
long k = ChunkCoordIntPair.a(i, j);
chunk = this.loadChunk(i, j);
@@ -202,6 +203,7 @@ public class ChunkProviderServer implements IChunkProvider {
}
// CraftBukkit end
chunk.loadNearby(this, this.chunkGenerator);
+ world.timings.syncChunkLoadTimer.stopTiming(); // Spigot
}
return chunk;
diff --git a/src/main/java/net/minecraft/server/ChunkRegionLoader.java b/src/main/java/net/minecraft/server/ChunkRegionLoader.java
index 003aee0..53b5296 100644
--- a/src/main/java/net/minecraft/server/ChunkRegionLoader.java
+++ b/src/main/java/net/minecraft/server/ChunkRegionLoader.java
@@ -44,7 +44,9 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver {
// CraftBukkit start - Add async variant, provide compatibility
public Chunk a(World world, int i, int j) throws IOException {
+ world.timings.syncChunkLoadDataTimer.startTiming(); // Spigot
Object[] data = loadChunk(world, i, j);
+ world.timings.syncChunkLoadDataTimer.stopTiming(); // Spigot
if (data != null) {
Chunk chunk = (Chunk) data[0];
NBTTagCompound nbttagcompound = (NBTTagCompound) data[1];
@@ -347,7 +349,7 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver {
public void loadEntities(Chunk chunk, NBTTagCompound nbttagcompound, World world) {
// CraftBukkit end
-
+ world.timings.syncChunkLoadEntitiesTimer.startTiming(); // Spigot
NBTTagList nbttaglist1 = nbttagcompound.getList("Entities", 10);
if (nbttaglist1 != null) {
@@ -358,7 +360,8 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver {
chunk.g(true);
}
}
-
+ world.timings.syncChunkLoadEntitiesTimer.stopTiming(); // Spigot
+ world.timings.syncChunkLoadTileEntitiesTimer.startTiming(); // Spigot
NBTTagList nbttaglist2 = nbttagcompound.getList("TileEntities", 10);
if (nbttaglist2 != null) {
@@ -371,6 +374,8 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver {
}
}
}
+ world.timings.syncChunkLoadTileEntitiesTimer.stopTiming(); // Spigot
+ world.timings.syncChunkLoadTileTicksTimer.startTiming(); // Spigot
if (nbttagcompound.hasKeyOfType("TileTicks", 9)) {
NBTTagList nbttaglist3 = nbttagcompound.getList("TileTicks", 10);
@@ -390,6 +395,7 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver {
}
}
}
+ world.timings.syncChunkLoadTileTicksTimer.stopTiming(); // Spigot
// return chunk; // CraftBukkit
}
diff --git a/src/main/java/net/minecraft/server/DedicatedServer.java b/src/main/java/net/minecraft/server/DedicatedServer.java
index 9c17951..db78855 100644
--- a/src/main/java/net/minecraft/server/DedicatedServer.java
+++ b/src/main/java/net/minecraft/server/DedicatedServer.java
@@ -22,6 +22,7 @@ import java.io.PrintStream;
import org.apache.logging.log4j.Level;
import org.bukkit.craftbukkit.LoggerOutputStream;
+import org.bukkit.craftbukkit.SpigotTimings; // Spigot
import org.bukkit.event.server.ServerCommandEvent;
import org.bukkit.craftbukkit.util.Waitable;
import org.bukkit.event.server.RemoteServerCommandEvent;
@@ -394,6 +395,7 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer
}
public void aL() {
+ SpigotTimings.serverCommandTimer.startTiming(); // Spigot
while (!this.serverCommandQueue.isEmpty()) {
ServerCommand servercommand = (ServerCommand) this.serverCommandQueue.remove(0);
@@ -408,6 +410,7 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer
// CraftBukkit end
}
+ SpigotTimings.serverCommandTimer.stopTiming(); // Spigot
}
public boolean aa() {
diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
index 6c81511..c1d4fb4 100644
--- a/src/main/java/net/minecraft/server/Entity.java
+++ b/src/main/java/net/minecraft/server/Entity.java
@@ -24,6 +24,7 @@ import org.bukkit.block.BlockFace;
import org.bukkit.entity.Hanging;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Vehicle;
+import org.spigotmc.CustomTimingsHandler; // Spigot
import org.bukkit.event.entity.EntityCombustByEntityEvent;
import org.bukkit.event.hanging.HangingBreakByEntityEvent;
import org.bukkit.event.vehicle.VehicleBlockCollisionEvent;
@@ -139,6 +140,7 @@ public abstract class Entity implements ICommandListener {
public boolean valid; // CraftBukkit
public org.bukkit.projectiles.ProjectileSource projectileSource; // CraftBukkit - For projectiles only
public boolean forceExplosionKnockback; // CraftBukkit - SPIGOT-949
+ public CustomTimingsHandler tickTimer = org.bukkit.craftbukkit.SpigotTimings.getEntityTimings(this); // Spigot
public Entity(World world) {
this.id = Entity.entityCount++;
@@ -447,6 +449,7 @@ public abstract class Entity implements ICommandListener {
}
public void move(double d0, double d1, double d2) {
+ org.bukkit.craftbukkit.SpigotTimings.entityMoveTimer.startTiming(); // Spigot
if (this.noclip) {
this.a(this.getBoundingBox().c(d0, d1, d2));
this.recalcPosition();
@@ -787,6 +790,7 @@ public abstract class Entity implements ICommandListener {
this.world.methodProfiler.b();
}
+ org.bukkit.craftbukkit.SpigotTimings.entityMoveTimer.stopTiming(); // Spigot
}
public void recalcPosition() {
diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java
index 6e3bcd7..ff20c9b 100644
--- a/src/main/java/net/minecraft/server/EntityLiving.java
+++ b/src/main/java/net/minecraft/server/EntityLiving.java
@@ -24,6 +24,8 @@ import org.bukkit.event.entity.EntityRegainHealthEvent;
import org.bukkit.event.player.PlayerItemConsumeEvent;
// CraftBukkit end
+import org.bukkit.craftbukkit.SpigotTimings; // Spigot
+
public abstract class EntityLiving extends Entity {
private static final UUID a = UUID.fromString("662A6B8D-DA3E-4C1C-8813-96EA6097278D");
@@ -1680,6 +1682,7 @@ public abstract class EntityLiving extends Entity {
}
public void m() {
+ SpigotTimings.timerEntityBaseTick.startTiming(); // Spigot
super.m();
this.cu();
if (!this.world.isClientSide) {
@@ -1752,7 +1755,9 @@ public abstract class EntityLiving extends Entity {
}
}
+ SpigotTimings.timerEntityBaseTick.stopTiming(); // Spigot
this.n();
+ SpigotTimings.timerEntityTickRest.startTiming(); // Spigot
double d0 = this.locX - this.lastX;
double d1 = this.locZ - this.lastZ;
float f = (float) (d0 * d0 + d1 * d1);
@@ -1822,6 +1827,7 @@ public abstract class EntityLiving extends Entity {
this.bo = 0;
}
+ SpigotTimings.timerEntityTickRest.stopTiming(); // Spigot
}
protected float h(float f, float f1) {
@@ -1886,6 +1892,7 @@ public abstract class EntityLiving extends Entity {
}
this.world.methodProfiler.a("ai");
+ SpigotTimings.timerEntityAI.startTiming(); // Spigot
if (this.cf()) {
this.bc = false;
this.bd = 0.0F;
@@ -1896,6 +1903,7 @@ public abstract class EntityLiving extends Entity {
this.doTick();
this.world.methodProfiler.b();
}
+ SpigotTimings.timerEntityAI.stopTiming(); // Spigot
this.world.methodProfiler.b();
this.world.methodProfiler.a("jump");
@@ -1918,10 +1926,14 @@ public abstract class EntityLiving extends Entity {
this.be *= 0.98F;
this.bf *= 0.9F;
this.r();
+ SpigotTimings.timerEntityAIMove.startTiming(); // Spigot
this.g(this.bd, this.be);
+ SpigotTimings.timerEntityAIMove.stopTiming(); // Spigot
this.world.methodProfiler.b();
this.world.methodProfiler.a("push");
+ SpigotTimings.timerEntityAICollision.startTiming(); // Spigot
this.cn();
+ SpigotTimings.timerEntityAICollision.stopTiming(); // Spigot
this.world.methodProfiler.b();
}
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index c226e01..d754d0d 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -45,6 +45,7 @@ import org.bukkit.craftbukkit.CraftServer;
// CraftBukkit start
// CraftBukkit end
+import org.bukkit.craftbukkit.SpigotTimings; // Spigot
public abstract class MinecraftServer implements Runnable, ICommandListener, IAsyncTaskHandler, IMojangStatistics {
@@ -622,6 +623,7 @@ public abstract class MinecraftServer implements Runnable, ICommandListener, IAs
protected void B() {}
protected void C() throws ExceptionWorldConflict { // CraftBukkit - added throws
+ SpigotTimings.serverTickTimer.startTiming(); // Spigot
long i = System.nanoTime();
++this.ticks;
@@ -648,10 +650,12 @@ public abstract class MinecraftServer implements Runnable, ICommandListener, IAs
}
if (autosavePeriod > 0 && this.ticks % autosavePeriod == 0) { // CraftBukkit
+ SpigotTimings.worldSaveTimer.startTiming(); // Spigot
this.methodProfiler.a("save");
this.v.savePlayers();
this.saveChunks(true);
this.methodProfiler.b();
+ SpigotTimings.worldSaveTimer.stopTiming(); // Spigot
}
this.methodProfiler.a("tallying");
@@ -668,6 +672,8 @@ public abstract class MinecraftServer implements Runnable, ICommandListener, IAs
this.methodProfiler.b();
this.methodProfiler.b();
+ SpigotTimings.serverTickTimer.stopTiming(); // Spigot
+ org.spigotmc.CustomTimingsHandler.tick(); // Spigot
}
public void D() {
@@ -682,16 +688,23 @@ public abstract class MinecraftServer implements Runnable, ICommandListener, IAs
this.methodProfiler.c("levels");
+ SpigotTimings.schedulerTimer.startTiming(); // Spigot
// CraftBukkit start
this.server.getScheduler().mainThreadHeartbeat(this.ticks);
+ SpigotTimings.schedulerTimer.stopTiming(); // Spigot
// Run tasks that are waiting on processing
+ SpigotTimings.processQueueTimer.startTiming(); // Spigot
while (!processQueue.isEmpty()) {
processQueue.remove().run();
}
+ SpigotTimings.processQueueTimer.stopTiming(); // Spigot
+ SpigotTimings.chunkIOTickTimer.startTiming(); // Spigot
org.bukkit.craftbukkit.chunkio.ChunkIOExecutor.tick();
+ SpigotTimings.chunkIOTickTimer.stopTiming(); // Spigot
+ SpigotTimings.timeUpdateTimer.startTiming(); // Spigot
// Send time updates to everyone, it will get the right time from the world the player is in.
if (this.ticks % 20 == 0) {
for (int i = 0; i < this.getPlayerList().players.size(); ++i) {
@@ -699,6 +712,7 @@ public abstract class MinecraftServer implements Runnable, ICommandListener, IAs
entityplayer.playerConnection.sendPacket(new PacketPlayOutUpdateTime(entityplayer.world.getTime(), entityplayer.getPlayerTime(), entityplayer.world.getGameRules().getBoolean("doDaylightCycle"))); // Add support for per player time
}
}
+ SpigotTimings.timeUpdateTimer.stopTiming(); // Spigot
int i;
@@ -722,7 +736,9 @@ public abstract class MinecraftServer implements Runnable, ICommandListener, IAs
CrashReport crashreport;
try {
+ worldserver.timings.doTick.startTiming(); // Spigot
worldserver.doTick();
+ worldserver.timings.doTick.stopTiming(); // Spigot
} catch (Throwable throwable) {
crashreport = CrashReport.a(throwable, "Exception ticking world");
worldserver.a(crashreport);
@@ -730,7 +746,9 @@ public abstract class MinecraftServer implements Runnable, ICommandListener, IAs
}
try {
+ worldserver.timings.tickEntities.startTiming(); // Spigot
worldserver.tickEntities();
+ worldserver.timings.tickEntities.stopTiming(); // Spigot
} catch (Throwable throwable1) {
crashreport = CrashReport.a(throwable1, "Exception ticking world entities");
worldserver.a(crashreport);
@@ -739,7 +757,9 @@ public abstract class MinecraftServer implements Runnable, ICommandListener, IAs
this.methodProfiler.b();
this.methodProfiler.a("tracker");
+ worldserver.timings.tracker.startTiming(); // Spigot
worldserver.getTracker().updatePlayers();
+ worldserver.timings.tracker.stopTiming(); // Spigot
this.methodProfiler.b();
this.methodProfiler.b();
// } // CraftBukkit
@@ -748,14 +768,20 @@ public abstract class MinecraftServer implements Runnable, ICommandListener, IAs
}
this.methodProfiler.c("connection");
+ SpigotTimings.connectionTimer.startTiming(); // Spigot
this.am().c();
+ SpigotTimings.connectionTimer.stopTiming(); // Spigot
this.methodProfiler.c("players");
+ SpigotTimings.playerListTimer.startTiming(); // Spigot
this.v.tick();
+ SpigotTimings.playerListTimer.stopTiming(); // Spigot
this.methodProfiler.c("tickables");
+ SpigotTimings.tickablesTimer.startTiming(); // Spigot
for (i = 0; i < this.o.size(); ++i) {
((ITickable) this.o.get(i)).c();
}
+ SpigotTimings.tickablesTimer.stopTiming(); // Spigot
this.methodProfiler.b();
}
diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java
index 969840c..76cbb21 100644
--- a/src/main/java/net/minecraft/server/PlayerConnection.java
+++ b/src/main/java/net/minecraft/server/PlayerConnection.java
@@ -1282,6 +1282,7 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable {
// CraftBukkit end
private void handleCommand(String s) {
+ org.bukkit.craftbukkit.SpigotTimings.playerCommandTimer.startTiming(); // Spigot
// CraftBukkit start - whole method
this.LOGGER.info(this.player.getName() + " issued server command: " + s);
@@ -1291,18 +1292,22 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable {
this.server.getPluginManager().callEvent(event);
if (event.isCancelled()) {
+ org.bukkit.craftbukkit.SpigotTimings.playerCommandTimer.stopTiming(); // Spigot
return;
}
try {
if (this.server.dispatchCommand(event.getPlayer(), event.getMessage().substring(1))) {
+ org.bukkit.craftbukkit.SpigotTimings.playerCommandTimer.stopTiming(); // Spigot
return;
}
} catch (org.bukkit.command.CommandException ex) {
player.sendMessage(org.bukkit.ChatColor.RED + "An internal error occurred while attempting to perform this command");
java.util.logging.Logger.getLogger(PlayerConnection.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
+ org.bukkit.craftbukkit.SpigotTimings.playerCommandTimer.stopTiming(); // Spigot
return;
}
+ org.bukkit.craftbukkit.SpigotTimings.playerCommandTimer.stopTiming(); // Spigot
// this.minecraftServer.getCommandHandler().a(this.player, s);
// CraftBukkit end
}
diff --git a/src/main/java/net/minecraft/server/TileEntity.java b/src/main/java/net/minecraft/server/TileEntity.java
index baf1d73..8bbdc11 100644
--- a/src/main/java/net/minecraft/server/TileEntity.java
+++ b/src/main/java/net/minecraft/server/TileEntity.java
@@ -6,10 +6,12 @@ import java.util.concurrent.Callable;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
+import org.spigotmc.CustomTimingsHandler; // Spigot
import org.bukkit.inventory.InventoryHolder; // CraftBukkit
public abstract class TileEntity {
+ public CustomTimingsHandler tickTimer = org.bukkit.craftbukkit.SpigotTimings.getTileEntityTimings(this); // Spigot
private static final Logger a = LogManager.getLogger();
private static Map<String, Class<? extends TileEntity>> f = Maps.newHashMap();
private static Map<Class<? extends TileEntity>, String> g = Maps.newHashMap();
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
index c73f0ef..d6d4c5b 100644
--- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java
@@ -18,6 +18,7 @@ import com.google.common.collect.Maps;
import java.util.Map;
import org.bukkit.Bukkit;
import org.bukkit.block.BlockState;
+import org.bukkit.craftbukkit.SpigotTimings; // Spigot
import org.bukkit.craftbukkit.CraftServer;
import org.bukkit.craftbukkit.CraftWorld;
import org.bukkit.craftbukkit.event.CraftEventFactory;
@@ -99,6 +100,8 @@ public abstract class World implements IBlockAccess {
private int tickPosition;
public final org.spigotmc.SpigotWorldConfig spigotConfig; // Spigot
+ public final SpigotTimings.WorldTimingsHandler timings; // Spigot
+
public CraftWorld getWorld() {
return this.world;
}
@@ -160,6 +163,7 @@ public abstract class World implements IBlockAccess {
});
this.getServer().addWorld(this.world);
// CraftBukkit end
+ timings = new SpigotTimings.WorldTimingsHandler(this); // Spigot - code below can generate new world and access timings
}
public World b() {
@@ -1332,6 +1336,7 @@ public abstract class World implements IBlockAccess {
CrashReportSystemDetails crashreportsystemdetails1;
CrashReport crashreport1;
+ timings.entityTick.startTiming(); // Spigot
// CraftBukkit start - Use field for loop variable
for (this.tickPosition = 0; this.tickPosition < this.entityList.size(); ++this.tickPosition) {
entity = (Entity) this.entityList.get(this.tickPosition);
@@ -1349,7 +1354,9 @@ public abstract class World implements IBlockAccess {
this.methodProfiler.a("tick");
if (!entity.dead && !(entity instanceof EntityPlayer)) {
try {
+ SpigotTimings.tickEntityTimer.startTiming(); // Spigot
this.g(entity);
+ SpigotTimings.tickEntityTimer.stopTiming(); // Spigot
} catch (Throwable throwable1) {
crashreport1 = CrashReport.a(throwable1, "Ticking entity");
crashreportsystemdetails1 = crashreport1.a("Entity being ticked");
@@ -1375,6 +1382,7 @@ public abstract class World implements IBlockAccess {
this.methodProfiler.b();
}
+ timings.entityTick.stopTiming(); // Spigot
this.methodProfiler.c("blockEntities");
this.M = true;
// CraftBukkit start - From below, clean up tile entities before ticking them
@@ -1395,6 +1403,7 @@ public abstract class World implements IBlockAccess {
if (this.isLoaded(blockposition) && this.N.a(blockposition)) {
try {
this.methodProfiler.a(""/*tileentity.getClass().getSimpleName()*/); // CraftBukkit: SPIGOT-1900
+ tileentity.tickTimer.startTiming(); // Spigot
((ITickable) tileentity).c();
this.methodProfiler.b();
} catch (Throwable throwable2) {
@@ -1403,6 +1412,11 @@ public abstract class World implements IBlockAccess {
tileentity.a(crashreportsystemdetails1);
throw new ReportedException(crashreport1);
}
+ // Spigot start
+ finally {
+ tileentity.tickTimer.stopTiming();
+ }
+ // Spigot end
}
}
@@ -1415,6 +1429,8 @@ public abstract class World implements IBlockAccess {
}
}
+ timings.tileEntityTick.stopTiming(); // Spigot
+ timings.tileEntityPending.startTiming(); // Spigot
this.M = false;
/* CraftBukkit start - Moved up
if (!this.tileEntityListUnload.isEmpty()) {
@@ -1449,6 +1465,7 @@ public abstract class World implements IBlockAccess {
this.b.clear();
}
+ timings.tileEntityPending.stopTiming(); // Spigot
this.methodProfiler.b();
this.methodProfiler.b();
}
@@ -1492,6 +1509,7 @@ public abstract class World implements IBlockAccess {
// CraftBukkit start - Use neighbor cache instead of looking up
Chunk startingChunk = this.getChunkIfLoaded(i >> 4, j >> 4);
if (!flag || (startingChunk != null && startingChunk.areNeighborsLoaded(2)) /* this.isAreaLoaded(i - b0, 0, j - b0, i + b0, 0, j + b0) */) {
+ entity.tickTimer.startTiming(); // Spigot
// CraftBukkit end
entity.M = entity.locX;
entity.N = entity.locY;
@@ -1559,6 +1577,7 @@ public abstract class World implements IBlockAccess {
}
}
+ entity.tickTimer.stopTiming(); // Spigot
}
}
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
index 2c95e76..9abcc8d 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java
@@ -219,10 +219,13 @@ public class WorldServer extends World implements IAsyncTaskHandler {
// CraftBukkit start - Only call spawner if we have players online and the world allows for mobs or animals
long time = this.worldData.getTime();
if (this.getGameRules().getBoolean("doMobSpawning") && this.worldData.getType() != WorldType.DEBUG_ALL_BLOCK_STATES && (this.allowMonsters || this.allowAnimals) && (this instanceof WorldServer && this.players.size() > 0)) {
+ timings.mobSpawn.startTiming(); // Spigot
this.spawnerCreature.a(this, this.allowMonsters && (this.ticksPerMonsterSpawns != 0 && time % this.ticksPerMonsterSpawns == 0L), this.allowAnimals && (this.ticksPerAnimalSpawns != 0 && time % this.ticksPerAnimalSpawns == 0L), this.worldData.getTime() % 400L == 0L);
+ timings.mobSpawn.stopTiming(); // Spigot
// CraftBukkit end
}
+ timings.doChunkUnload.startTiming(); // Spigot
this.methodProfiler.c("chunkSource");
this.chunkProvider.unloadChunks();
int j = this.a(1.0F);
@@ -236,21 +239,36 @@ public class WorldServer extends World implements IAsyncTaskHandler {
this.worldData.setDayTime(this.worldData.getDayTime() + 1L);
}
+ timings.doChunkUnload.stopTiming(); // Spigot
this.methodProfiler.c("tickPending");
+ timings.doTickPending.startTiming(); // Spigot
this.a(false);
+ timings.doTickPending.stopTiming(); // Spigot
this.methodProfiler.c("tickBlocks");
+ timings.doTickTiles.startTiming(); // Spigot
this.j();
+ timings.doTickTiles.stopTiming(); // Spigot
this.methodProfiler.c("chunkMap");
+ timings.doChunkMap.startTiming(); // Spigot
this.manager.flush();
+ timings.doChunkMap.stopTiming(); // Spigot
this.methodProfiler.c("village");
+ timings.doVillages.startTiming(); // Spigot
this.villages.tick();
this.siegeManager.a();
+ timings.doVillages.stopTiming(); // Spigot
this.methodProfiler.c("portalForcer");
+ timings.doPortalForcer.startTiming(); // Spigot
this.portalTravelAgent.a(this.getTime());
+ timings.doPortalForcer.stopTiming(); // Spigot
this.methodProfiler.b();
+ timings.doSounds.startTiming(); // Spigot
this.ao();
+ timings.doSounds.stopTiming(); // Spigot
+ timings.doChunkGC.startTiming();// Spigot
this.getWorld().processChunkGC(); // CraftBukkit
+ timings.doChunkGC.stopTiming(); // Spigot
}
public BiomeBase.BiomeMeta a(EnumCreatureType enumcreaturetype, BlockPosition blockposition) {
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index 91965c0..261b423 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -1663,6 +1663,11 @@ public final class CraftServer implements Server {
private final Spigot spigot = new Spigot()
{
+ @Override
+ public YamlConfiguration getConfig()
+ {
+ return org.spigotmc.SpigotConfig.config;
+ }
};
public Spigot spigot()
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index dfe58c6..e0e469d 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -274,7 +274,9 @@ public class CraftWorld implements World {
net.minecraft.server.Chunk chunk = world.getChunkProviderServer().chunks.get(LongHash.toLong(x, z));
if (chunk == null) {
+ world.timings.syncChunkLoadTimer.startTiming(); // Spigot
chunk = world.getChunkProviderServer().getOrLoadChunkAt(x, z);
+ world.timings.syncChunkLoadTimer.stopTiming(); // Spigot
}
return chunk != null;
}
diff --git a/src/main/java/org/bukkit/craftbukkit/SpigotTimings.java b/src/main/java/org/bukkit/craftbukkit/SpigotTimings.java
new file mode 100644
index 0000000..558574f
--- /dev/null
+++ b/src/main/java/org/bukkit/craftbukkit/SpigotTimings.java
@@ -0,0 +1,170 @@
+package org.bukkit.craftbukkit;
+
+import com.google.common.collect.Maps;
+import net.minecraft.server.*;
+import org.bukkit.plugin.java.JavaPluginLoader;
+import org.spigotmc.CustomTimingsHandler;
+import org.bukkit.scheduler.BukkitTask;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.bukkit.craftbukkit.scheduler.CraftTask;
+
+public class SpigotTimings {
+
+ public static final CustomTimingsHandler serverTickTimer = new CustomTimingsHandler("** Full Server Tick");
+ public static final CustomTimingsHandler playerListTimer = new CustomTimingsHandler("Player List");
+ public static final CustomTimingsHandler connectionTimer = new CustomTimingsHandler("Connection Handler");
+ public static final CustomTimingsHandler tickablesTimer = new CustomTimingsHandler("Tickables");
+ public static final CustomTimingsHandler schedulerTimer = new CustomTimingsHandler("Scheduler");
+ public static final CustomTimingsHandler chunkIOTickTimer = new CustomTimingsHandler("ChunkIOTick");
+ public static final CustomTimingsHandler timeUpdateTimer = new CustomTimingsHandler("Time Update");
+ public static final CustomTimingsHandler serverCommandTimer = new CustomTimingsHandler("Server Command");
+ public static final CustomTimingsHandler worldSaveTimer = new CustomTimingsHandler("World Save");
+
+ public static final CustomTimingsHandler entityMoveTimer = new CustomTimingsHandler("** entityMove");
+ public static final CustomTimingsHandler tickEntityTimer = new CustomTimingsHandler("** tickEntity");
+ public static final CustomTimingsHandler activatedEntityTimer = new CustomTimingsHandler("** activatedTickEntity");
+ public static final CustomTimingsHandler tickTileEntityTimer = new CustomTimingsHandler("** tickTileEntity");
+
+ public static final CustomTimingsHandler timerEntityBaseTick = new CustomTimingsHandler("** livingEntityBaseTick");
+ public static final CustomTimingsHandler timerEntityAI = new CustomTimingsHandler("** livingEntityAI");
+ public static final CustomTimingsHandler timerEntityAICollision = new CustomTimingsHandler("** livingEntityAICollision");
+ public static final CustomTimingsHandler timerEntityAIMove = new CustomTimingsHandler("** livingEntityAIMove");
+ public static final CustomTimingsHandler timerEntityTickRest = new CustomTimingsHandler("** livingEntityTickRest");
+
+ public static final CustomTimingsHandler processQueueTimer = new CustomTimingsHandler("processQueue");
+ public static final CustomTimingsHandler schedulerSyncTimer = new CustomTimingsHandler("** Scheduler - Sync Tasks", JavaPluginLoader.pluginParentTimer);
+
+ public static final CustomTimingsHandler playerCommandTimer = new CustomTimingsHandler("** playerCommand");
+
+ public static final HashMap<String, CustomTimingsHandler> entityTypeTimingMap = new HashMap<String, CustomTimingsHandler>();
+ public static final HashMap<String, CustomTimingsHandler> tileEntityTypeTimingMap = new HashMap<String, CustomTimingsHandler>();
+ public static final HashMap<String, CustomTimingsHandler> pluginTaskTimingMap = new HashMap<String, CustomTimingsHandler>();
+
+ /**
+ * Gets a timer associated with a plugins tasks.
+ * @param task
+ * @param period
+ * @return
+ */
+ public static CustomTimingsHandler getPluginTaskTimings(BukkitTask task, long period) {
+ if (!task.isSync()) {
+ return null;
+ }
+ String plugin;
+ final CraftTask ctask = (CraftTask) task;
+
+ if (task.getOwner() != null) {
+ plugin = task.getOwner().getDescription().getFullName();
+ } else if (ctask.timingName != null) {
+ plugin = "CraftScheduler";
+ } else {
+ plugin = "Unknown";
+ }
+ String taskname = ctask.getTaskName();
+
+ String name = "Task: " + plugin + " Runnable: " + taskname;
+ if (period > 0) {
+ name += "(interval:" + period +")";
+ } else {
+ name += "(Single)";
+ }
+ CustomTimingsHandler result = pluginTaskTimingMap.get(name);
+ if (result == null) {
+ result = new CustomTimingsHandler(name, SpigotTimings.schedulerSyncTimer);
+ pluginTaskTimingMap.put(name, result);
+ }
+ return result;
+ }
+
+ /**
+ * Get a named timer for the specified entity type to track type specific timings.
+ * @param entity
+ * @return
+ */
+ public static CustomTimingsHandler getEntityTimings(Entity entity) {
+ String entityType = entity.getClass().getSimpleName();
+ CustomTimingsHandler result = entityTypeTimingMap.get(entityType);
+ if (result == null) {
+ result = new CustomTimingsHandler("** tickEntity - " + entityType, activatedEntityTimer);
+ entityTypeTimingMap.put(entityType, result);
+ }
+ return result;
+ }
+
+ /**
+ * Get a named timer for the specified tile entity type to track type specific timings.
+ * @param entity
+ * @return
+ */
+ public static CustomTimingsHandler getTileEntityTimings(TileEntity entity) {
+ String entityType = entity.getClass().getSimpleName();
+ CustomTimingsHandler result = tileEntityTypeTimingMap.get(entityType);
+ if (result == null) {
+ result = new CustomTimingsHandler("** tickTileEntity - " + entityType, tickTileEntityTimer);
+ tileEntityTypeTimingMap.put(entityType, result);
+ }
+ return result;
+ }
+
+ /**
+ * Set of timers per world, to track world specific timings.
+ */
+ public static class WorldTimingsHandler {
+ public final CustomTimingsHandler mobSpawn;
+ public final CustomTimingsHandler doChunkUnload;
+ public final CustomTimingsHandler doPortalForcer;
+ public final CustomTimingsHandler doTickPending;
+ public final CustomTimingsHandler doTickTiles;
+ public final CustomTimingsHandler doVillages;
+ public final CustomTimingsHandler doChunkMap;
+ public final CustomTimingsHandler doChunkGC;
+ public final CustomTimingsHandler doSounds;
+ public final CustomTimingsHandler entityTick;
+ public final CustomTimingsHandler tileEntityTick;
+ public final CustomTimingsHandler tileEntityPending;
+ public final CustomTimingsHandler tracker;
+ public final CustomTimingsHandler doTick;
+ public final CustomTimingsHandler tickEntities;
+
+ public final CustomTimingsHandler syncChunkLoadTimer;
+ public final CustomTimingsHandler syncChunkLoadDataTimer;
+ public final CustomTimingsHandler syncChunkLoadStructuresTimer;
+ public final CustomTimingsHandler syncChunkLoadEntitiesTimer;
+ public final CustomTimingsHandler syncChunkLoadTileEntitiesTimer;
+ public final CustomTimingsHandler syncChunkLoadTileTicksTimer;
+ public final CustomTimingsHandler syncChunkLoadPostTimer;
+
+ public WorldTimingsHandler(World server) {
+ String name = server.worldData.getName() +" - ";
+
+ mobSpawn = new CustomTimingsHandler("** " + name + "mobSpawn");
+ doChunkUnload = new CustomTimingsHandler("** " + name + "doChunkUnload");
+ doTickPending = new CustomTimingsHandler("** " + name + "doTickPending");
+ doTickTiles = new CustomTimingsHandler("** " + name + "doTickTiles");
+ doVillages = new CustomTimingsHandler("** " + name + "doVillages");
+ doChunkMap = new CustomTimingsHandler("** " + name + "doChunkMap");
+ doSounds = new CustomTimingsHandler("** " + name + "doSounds");
+ doChunkGC = new CustomTimingsHandler("** " + name + "doChunkGC");
+ doPortalForcer = new CustomTimingsHandler("** " + name + "doPortalForcer");
+ entityTick = new CustomTimingsHandler("** " + name + "entityTick");
+ tileEntityTick = new CustomTimingsHandler("** " + name + "tileEntityTick");
+ tileEntityPending = new CustomTimingsHandler("** " + name + "tileEntityPending");
+
+ syncChunkLoadTimer = new CustomTimingsHandler("** " + name + "syncChunkLoad");
+ syncChunkLoadDataTimer = new CustomTimingsHandler("** " + name + "syncChunkLoad - Data");
+ syncChunkLoadStructuresTimer = new CustomTimingsHandler("** " + name + "chunkLoad - Structures");
+ syncChunkLoadEntitiesTimer = new CustomTimingsHandler("** " + name + "chunkLoad - Entities");
+ syncChunkLoadTileEntitiesTimer = new CustomTimingsHandler("** " + name + "chunkLoad - TileEntities");
+ syncChunkLoadTileTicksTimer = new CustomTimingsHandler("** " + name + "chunkLoad - TileTicks");
+ syncChunkLoadPostTimer = new CustomTimingsHandler("** " + name + "chunkLoad - Post");
+
+
+ tracker = new CustomTimingsHandler(name + "tracker");
+ doTick = new CustomTimingsHandler(name + "doTick");
+ tickEntities = new CustomTimingsHandler(name + "tickEntities");
+ }
+ }
+}
diff --git a/src/main/java/org/bukkit/craftbukkit/chunkio/ChunkIOProvider.java b/src/main/java/org/bukkit/craftbukkit/chunkio/ChunkIOProvider.java
index 6dfef44..482af17 100644
--- a/src/main/java/org/bukkit/craftbukkit/chunkio/ChunkIOProvider.java
+++ b/src/main/java/org/bukkit/craftbukkit/chunkio/ChunkIOProvider.java
@@ -45,7 +45,9 @@ class ChunkIOProvider implements AsynchronousExecutor.CallBackProvider<QueuedChu
chunk.addEntities();
if (queuedChunk.provider.chunkGenerator != null) {
+ queuedChunk.provider.world.timings.syncChunkLoadStructuresTimer.startTiming(); // Spigot
queuedChunk.provider.chunkGenerator.recreateStructures(chunk, queuedChunk.x, queuedChunk.z);
+ queuedChunk.provider.world.timings.syncChunkLoadStructuresTimer.stopTiming(); // Spigot
}
Server server = queuedChunk.provider.world.getServer();
diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
index 9fea4fb..8442ecb 100644
--- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
+++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
@@ -346,7 +346,9 @@ public class CraftScheduler implements BukkitScheduler {
}
if (task.isSync()) {
try {
+ task.timings.startTiming(); // Spigot
task.run();
+ task.timings.stopTiming(); // Spigot
} catch (final Throwable throwable) {
task.getOwner().getLogger().log(
Level.WARNING,
diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftTask.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftTask.java
index 55db3ff..220e39a 100644
--- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftTask.java
+++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftTask.java
@@ -1,11 +1,13 @@
package org.bukkit.craftbukkit.scheduler;
import org.bukkit.Bukkit;
+import org.bukkit.craftbukkit.SpigotTimings; // Spigot
+import org.spigotmc.CustomTimingsHandler; // Spigot
import org.bukkit.plugin.Plugin;
import org.bukkit.scheduler.BukkitTask;
-class CraftTask implements BukkitTask, Runnable {
+public class CraftTask implements BukkitTask, Runnable { // Spigot
private volatile CraftTask next = null;
/**
@@ -22,6 +24,7 @@ class CraftTask implements BukkitTask, Runnable {
private final Plugin plugin;
private final int id;
+ final CustomTimingsHandler timings; // Spigot
CraftTask() {
this(null, null, -1, -1);
}
@@ -30,11 +33,26 @@ class CraftTask implements BukkitTask, Runnable {
this(null, task, -1, -1);
}
- CraftTask(final Plugin plugin, final Runnable task, final int id, final long period) {
+ // Spigot start
+ public String timingName = null;
+ CraftTask(String timingName) {
+ this(timingName, null, null, -1, -1);
+ }
+ CraftTask(String timingName, final Runnable task) {
+ this(timingName, null, task, -1, -1);
+ }
+ CraftTask(String timingName, final Plugin plugin, final Runnable task, final int id, final long period) {
this.plugin = plugin;
this.task = task;
this.id = id;
this.period = period;
+ this.timingName = timingName == null && task == null ? "Unknown" : timingName;
+ timings = this.isSync() ? SpigotTimings.getPluginTaskTimings(this, period) : null;
+ }
+
+ CraftTask(final Plugin plugin, final Runnable task, final int id, final long period) {
+ this(null, plugin, task, id, period);
+ // Spigot end
}
public final int getTaskId() {
@@ -94,4 +112,13 @@ class CraftTask implements BukkitTask, Runnable {
setPeriod(-2l);
return true;
}
+
+ // Spigot start
+ public String getTaskName() {
+ if (timingName != null) {
+ return timingName;
+ }
+ return task.getClass().getName();
+ }
+ // Spigot end
}
--
2.5.0

View File

@ -1,163 +0,0 @@
From dce78d1261c864f14894a4ec275a67524266a299 Mon Sep 17 00:00:00 2001
From: md_5 <md_5@live.com.au>
Date: Fri, 21 Jun 2013 17:29:54 +1000
Subject: [PATCH] Fix Mob Spawning Relative to View Distance
Changes the mob spawning algorithm to properly account for view distance and the range around players.
Needs better documentation.
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
index 8345e87..e4725b0 100644
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -43,6 +43,7 @@ public class Chunk {
private long v;
private int w;
private ConcurrentLinkedQueue<BlockPosition> x;
+ protected gnu.trove.map.hash.TObjectIntHashMap<Class> entityCount = new gnu.trove.map.hash.TObjectIntHashMap<Class>(); // Spigot
// CraftBukkit start - Neighbor loaded cache for chunk lighting and entity ticking
private int neighbors = 0x1 << 12;
@@ -606,6 +607,22 @@ public class Chunk {
entity.ac = k;
entity.ad = this.locZ;
this.entitySlices[k].add(entity);
+ // Spigot start - increment creature type count
+ // Keep this synced up with World.a(Class)
+ if (entity instanceof EntityInsentient) {
+ EntityInsentient entityinsentient = (EntityInsentient) entity;
+ if (entityinsentient.isTypeNotPersistent() && entityinsentient.isPersistent()) {
+ return;
+ }
+ }
+ for ( EnumCreatureType creatureType : EnumCreatureType.values() )
+ {
+ if ( creatureType.a().isAssignableFrom( entity.getClass() ) )
+ {
+ this.entityCount.adjustOrPutValue( creatureType.a(), 1, 1 );
+ }
+ }
+ // Spigot end
}
public void b(Entity entity) {
@@ -622,6 +639,22 @@ public class Chunk {
}
this.entitySlices[i].remove(entity);
+ // Spigot start - decrement creature type count
+ // Keep this synced up with World.a(Class)
+ if (entity instanceof EntityInsentient) {
+ EntityInsentient entityinsentient = (EntityInsentient) entity;
+ if (entityinsentient.isTypeNotPersistent() && entityinsentient.isPersistent()) {
+ return;
+ }
+ }
+ for ( EnumCreatureType creatureType : EnumCreatureType.values() )
+ {
+ if ( creatureType.a().isAssignableFrom( entity.getClass() ) )
+ {
+ this.entityCount.adjustValue( creatureType.a(), -1 );
+ }
+ }
+ // Spigot end
}
public boolean c(BlockPosition blockposition) {
diff --git a/src/main/java/net/minecraft/server/SpawnerCreature.java b/src/main/java/net/minecraft/server/SpawnerCreature.java
index b3cb8bb..9e19dfd 100644
--- a/src/main/java/net/minecraft/server/SpawnerCreature.java
+++ b/src/main/java/net/minecraft/server/SpawnerCreature.java
@@ -17,6 +17,25 @@ public final class SpawnerCreature {
public SpawnerCreature() {}
+ // Spigot start - get entity count only from chunks being processed in b
+ private int getEntityCount(WorldServer server, Class oClass)
+ {
+ int i = 0;
+ Iterator<Long> it = this.b.iterator();
+ while ( it.hasNext() )
+ {
+ Long coord = it.next();
+ int x = LongHash.msw( coord );
+ int z = LongHash.lsw( coord );
+ if ( !((ChunkProviderServer)server.chunkProvider).unloadQueue.contains( coord ) && server.isChunkLoaded( x, z, true ) )
+ {
+ i += server.getChunkAt( x, z ).entityCount.get( oClass );
+ }
+ }
+ return i;
+ }
+ // Spigot end
+
public int a(WorldServer worldserver, boolean flag, boolean flag1, boolean flag2) {
if (!flag && !flag1) {
return 0;
@@ -36,6 +55,11 @@ public final class SpawnerCreature {
j = MathHelper.floor(entityhuman.locZ / 16.0D);
byte b0 = 8;
+ // Spigot Start
+ b0 = worldserver.spigotConfig.mobSpawnRange;
+ b0 = ( b0 > worldserver.spigotConfig.viewDistance ) ? (byte) worldserver.spigotConfig.viewDistance : b0;
+ b0 = ( b0 > 8 ) ? 8 : b0;
+ // Spigot End
for (int i1 = -b0; i1 <= b0; ++i1) {
for (k = -b0; k <= b0; ++k) {
@@ -89,18 +113,20 @@ public final class SpawnerCreature {
if (limit == 0) {
continue;
}
+ int mobcnt = 0; // Spigot
// CraftBukkit end
if ((!enumcreaturetype.d() || flag1) && (enumcreaturetype.d() || flag) && (!enumcreaturetype.e() || flag2)) {
k = worldserver.a(enumcreaturetype.a());
int l1 = limit * i / a; // CraftBukkit - use per-world limits
- if (k <= l1) {
+ if ((mobcnt = getEntityCount(worldserver, enumcreaturetype.a())) <= limit * i / 256) {
BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition();
Iterator iterator1 = this.b.iterator();
+ int moblimit = (limit * i / 256) - mobcnt + 1; // Spigot - up to 1 more than limit
label120:
- while (iterator1.hasNext()) {
+ while (iterator1.hasNext() && (moblimit > 0)) { // Spigot - while more allowed
// CraftBukkit start = use LongHash and LongObjectHashMap
long key = ((Long) iterator1.next()).longValue();
BlockPosition blockposition1 = getRandomPosition(worldserver, LongHash.msw(key), LongHash.lsw(key));
@@ -162,7 +188,10 @@ public final class SpawnerCreature {
entityinsentient.die();
}
- if (l2 >= entityinsentient.cJ()) {
+ // Spigot start
+ if ( --moblimit <= 0 ) {
+ // If we're past limit, stop spawn
+ // Spigot end
continue label120;
}
}
diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java
index 86300d6..cacb8fc 100644
--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java
+++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java
@@ -122,4 +122,11 @@ public class SpigotWorldConfig
viewDistance = getInt( "view-distance", Bukkit.getViewDistance() );
log( "View Distance: " + viewDistance );
}
+
+ public byte mobSpawnRange;
+ private void mobSpawnRange()
+ {
+ mobSpawnRange = (byte) getInt( "mob-spawn-range", 4 );
+ log( "Mob Spawn Range: " + mobSpawnRange );
+ }
}
--
2.5.0

View File

@ -1,27 +0,0 @@
From 2a1554b7745d3505ac5bc808320d8a9471ad0b45 Mon Sep 17 00:00:00 2001
From: md_5 <md_5@live.com.au>
Date: Sun, 3 Feb 2013 09:20:19 +1100
Subject: [PATCH] Handle Null Tile Entities
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
index 7e8092f..59a7163 100644
--- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java
@@ -1396,6 +1396,13 @@ public abstract class World implements IBlockAccess {
while (iterator.hasNext()) {
TileEntity tileentity = (TileEntity) iterator.next();
+ // Spigot start
+ if (tileentity == null) {
+ getServer().getLogger().severe("Spigot has detected a null entity and has removed it, preventing a crash");
+ iterator.remove();
+ continue;
+ }
+ // Spigot end
if (!tileentity.x() && tileentity.t()) {
BlockPosition blockposition = tileentity.getPosition();
--
2.5.0

View File

@ -1,38 +0,0 @@
From b991c9bc542ce11cc8d07f7b2c6f9ab2152cc12e Mon Sep 17 00:00:00 2001
From: md_5 <md_5@live.com.au>
Date: Sun, 22 Sep 2013 19:10:53 +1000
Subject: [PATCH] Item Despawn Rate
diff --git a/src/main/java/net/minecraft/server/EntityItem.java b/src/main/java/net/minecraft/server/EntityItem.java
index 7ea1150..eb0f8eb 100644
--- a/src/main/java/net/minecraft/server/EntityItem.java
+++ b/src/main/java/net/minecraft/server/EntityItem.java
@@ -109,7 +109,7 @@ public class EntityItem extends Entity {
// Craftbukkit end */
this.aj();
- if (!this.world.isClientSide && this.age >= 6000) {
+ if (!this.world.isClientSide && this.age >= world.spigotConfig.itemDespawnRate) { // Spigot
// CraftBukkit start - fire ItemDespawnEvent
if (org.bukkit.craftbukkit.event.CraftEventFactory.callItemDespawnEvent(this).isCancelled()) {
this.age = 0;
diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java
index cacb8fc..ca888fc 100644
--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java
+++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java
@@ -129,4 +129,11 @@ public class SpigotWorldConfig
mobSpawnRange = (byte) getInt( "mob-spawn-range", 4 );
log( "Mob Spawn Range: " + mobSpawnRange );
}
+
+ public int itemDespawnRate;
+ private void itemDespawnRate()
+ {
+ itemDespawnRate = getInt( "item-despawn-rate", 6000 );
+ log( "Item Despawn Rate: " + itemDespawnRate );
+ }
}
--
2.5.0

View File

@ -1,543 +0,0 @@
From a6fd76ee6c1cba5ed83ed03042318c5f58fc25a6 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Sun, 3 Feb 2013 05:10:21 -0500
Subject: [PATCH] Entity Activation Range
This feature gives 3 new configurable ranges that if an entity of the matching type is outside of this radius of any player, will tick at 5% of its normal rate.
This will drastically cut down on tick timings for entities that are not in range of a user to actually be "used".
This change can have dramatic impact on gameplay if configured too low. Balance according to your servers desired gameplay.
diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
index 6e125e7..87a069a 100644
--- a/src/main/java/net/minecraft/server/Entity.java
+++ b/src/main/java/net/minecraft/server/Entity.java
@@ -107,7 +107,7 @@ public abstract class Entity implements ICommandListener {
public int ticksLived;
public int maxFireTicks;
public int fireTicks;
- public boolean inWater;
+ public boolean inWater; // Spigot - protected -> public // PAIL
public int noDamageTicks;
protected boolean justCreated;
protected boolean fireProof;
@@ -141,6 +141,12 @@ public abstract class Entity implements ICommandListener {
public org.bukkit.projectiles.ProjectileSource projectileSource; // CraftBukkit - For projectiles only
public boolean forceExplosionKnockback; // CraftBukkit - SPIGOT-949
public CustomTimingsHandler tickTimer = org.bukkit.craftbukkit.SpigotTimings.getEntityTimings(this); // Spigot
+ // Spigot start
+ public final byte activationType = org.spigotmc.ActivationRange.initializeEntityActivationType(this);
+ public final boolean defaultActivationState;
+ public long activatedTick = Integer.MIN_VALUE;
+ public void inactiveTick() { }
+ // Spigot end
public Entity(World world) {
this.id = Entity.entityCount++;
@@ -160,7 +166,12 @@ public abstract class Entity implements ICommandListener {
this.setPosition(0.0D, 0.0D, 0.0D);
if (world != null) {
this.dimension = world.worldProvider.getDimensionManager().getDimensionID();
+ // Spigot start
+ this.defaultActivationState = org.spigotmc.ActivationRange.initializeEntityActivationState(this, world.spigotConfig);
+ } else {
+ this.defaultActivationState = false;
}
+ // Spigot end
this.datawatcher = new DataWatcher(this);
this.datawatcher.register(Entity.ax, Byte.valueOf((byte) 0));
diff --git a/src/main/java/net/minecraft/server/EntityAgeable.java b/src/main/java/net/minecraft/server/EntityAgeable.java
index e4a02bc..dbede68 100644
--- a/src/main/java/net/minecraft/server/EntityAgeable.java
+++ b/src/main/java/net/minecraft/server/EntityAgeable.java
@@ -10,6 +10,31 @@ public abstract class EntityAgeable extends EntityCreature {
private float bx;
public boolean ageLocked; // CraftBukkit
+ // Spigot start
+ @Override
+ public void inactiveTick()
+ {
+ super.inactiveTick();
+ if ( this.world.isClientSide || this.ageLocked )
+ { // CraftBukkit
+ this.a( this.isBaby() );
+ } else
+ {
+ int i = this.getAge();
+
+ if ( i < 0 )
+ {
+ ++i;
+ this.setAgeRaw( i );
+ } else if ( i > 0 )
+ {
+ --i;
+ this.setAgeRaw( i );
+ }
+ }
+ }
+ // Spigot end
+
public EntityAgeable(World world) {
super(world);
}
diff --git a/src/main/java/net/minecraft/server/EntityArrow.java b/src/main/java/net/minecraft/server/EntityArrow.java
index 1cda4e6..a40f3ec 100644
--- a/src/main/java/net/minecraft/server/EntityArrow.java
+++ b/src/main/java/net/minecraft/server/EntityArrow.java
@@ -27,7 +27,7 @@ public abstract class EntityArrow extends Entity implements IProjectile {
private int at;
private Block au;
private int av;
- protected boolean inGround;
+ public boolean inGround; // Spigot - protected -> public
protected int b;
public EntityArrow.PickupStatus fromPlayer;
public int shake;
@@ -37,6 +37,18 @@ public abstract class EntityArrow extends Entity implements IProjectile {
private double damage;
public int knockbackStrength;
+ // Spigot Start
+ @Override
+ public void inactiveTick()
+ {
+ if ( this.inGround )
+ {
+ this.aw += 1; // Despawn counter. First int after shooter
+ }
+ super.inactiveTick();
+ }
+ // Spigot End
+
public EntityArrow(World world) {
super(world);
this.h = -1;
diff --git a/src/main/java/net/minecraft/server/EntityFireworks.java b/src/main/java/net/minecraft/server/EntityFireworks.java
index 7454fde..ff44aa4 100644
--- a/src/main/java/net/minecraft/server/EntityFireworks.java
+++ b/src/main/java/net/minecraft/server/EntityFireworks.java
@@ -13,6 +13,14 @@ public class EntityFireworks extends Entity {
this.setSize(0.25F, 0.25F);
}
+ // Spigot Start
+ @Override
+ public void inactiveTick() {
+ this.ticksFlown += 1;
+ super.inactiveTick();
+ }
+ // Spigot End
+
protected void i() {
this.datawatcher.register(EntityFireworks.FIREWORK_ITEM, Optional.absent());
}
diff --git a/src/main/java/net/minecraft/server/EntityItem.java b/src/main/java/net/minecraft/server/EntityItem.java
index eb0f8eb..39af5d5 100644
--- a/src/main/java/net/minecraft/server/EntityItem.java
+++ b/src/main/java/net/minecraft/server/EntityItem.java
@@ -122,6 +122,28 @@ public class EntityItem extends Entity {
}
}
+ // Spigot start - copied from above
+ @Override
+ public void inactiveTick() {
+ // CraftBukkit start - Use wall time for pickup and despawn timers
+ int elapsedTicks = MinecraftServer.currentTick - this.lastTick;
+ if (this.pickupDelay != 32767) this.pickupDelay -= elapsedTicks;
+ if (this.age != -32768) this.age += elapsedTicks;
+ this.lastTick = MinecraftServer.currentTick;
+ // CraftBukkit end
+
+ if (!this.world.isClientSide && this.age >= world.spigotConfig.itemDespawnRate) { // Spigot
+ // CraftBukkit start - fire ItemDespawnEvent
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callItemDespawnEvent(this).isCancelled()) {
+ this.age = 0;
+ return;
+ }
+ // CraftBukkit end
+ this.die();
+ }
+ }
+ // Spigot end
+
private void x() {
// Spigot start
double radius = world.spigotConfig.itemMerge;
diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java
index aca2c60..96a0571 100644
--- a/src/main/java/net/minecraft/server/EntityLiving.java
+++ b/src/main/java/net/minecraft/server/EntityLiving.java
@@ -104,6 +104,13 @@ public abstract class EntityLiving extends Entity {
ArrayList<org.bukkit.inventory.ItemStack> drops = new ArrayList<org.bukkit.inventory.ItemStack>();
public org.bukkit.craftbukkit.attribute.CraftAttributeMap craftAttributes;
// CraftBukkit end
+ // Spigot start
+ public void inactiveTick()
+ {
+ super.inactiveTick();
+ ++this.ticksFarFromPlayer; // Above all the floats
+ }
+ // Spigot end
public void Q() {
this.damageEntity(DamageSource.OUT_OF_WORLD, Float.MAX_VALUE);
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
index 73c31a3..559dd75 100644
--- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java
@@ -1336,6 +1336,7 @@ public abstract class World implements IBlockAccess {
CrashReportSystemDetails crashreportsystemdetails1;
CrashReport crashreport1;
+ org.spigotmc.ActivationRange.activateEntities(this); // Spigot
timings.entityTick.startTiming(); // Spigot
// CraftBukkit start - Use field for loop variable
for (this.tickPosition = 0; this.tickPosition < this.entityList.size(); ++this.tickPosition) {
@@ -1513,9 +1514,11 @@ public abstract class World implements IBlockAccess {
int j = MathHelper.floor(entity.locZ);
byte b0 = 32;
- // CraftBukkit start - Use neighbor cache instead of looking up
- Chunk startingChunk = this.getChunkIfLoaded(i >> 4, j >> 4);
- if (!flag || (startingChunk != null && startingChunk.areNeighborsLoaded(2)) /* this.isAreaLoaded(i - b0, 0, j - b0, i + b0, 0, j + b0) */) {
+ // Spigot start
+ if (!org.spigotmc.ActivationRange.checkIfActive(entity)) {
+ entity.ticksLived++;
+ entity.inactiveTick();
+ } else {
entity.tickTimer.startTiming(); // Spigot
// CraftBukkit end
entity.M = entity.locX;
diff --git a/src/main/java/org/bukkit/craftbukkit/SpigotTimings.java b/src/main/java/org/bukkit/craftbukkit/SpigotTimings.java
index 558574f..41d2d87 100644
--- a/src/main/java/org/bukkit/craftbukkit/SpigotTimings.java
+++ b/src/main/java/org/bukkit/craftbukkit/SpigotTimings.java
@@ -39,6 +39,9 @@ public class SpigotTimings {
public static final CustomTimingsHandler playerCommandTimer = new CustomTimingsHandler("** playerCommand");
+ public static final CustomTimingsHandler entityActivationCheckTimer = new CustomTimingsHandler("entityActivationCheck");
+ public static final CustomTimingsHandler checkIfActiveTimer = new CustomTimingsHandler("** checkIfActive");
+
public static final HashMap<String, CustomTimingsHandler> entityTypeTimingMap = new HashMap<String, CustomTimingsHandler>();
public static final HashMap<String, CustomTimingsHandler> tileEntityTypeTimingMap = new HashMap<String, CustomTimingsHandler>();
public static final HashMap<String, CustomTimingsHandler> pluginTaskTimingMap = new HashMap<String, CustomTimingsHandler>();
diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org/spigotmc/ActivationRange.java
new file mode 100644
index 0000000..c4364cd
--- /dev/null
+++ b/src/main/java/org/spigotmc/ActivationRange.java
@@ -0,0 +1,286 @@
+package org.spigotmc;
+
+import java.util.Set;
+import net.minecraft.server.AxisAlignedBB;
+import net.minecraft.server.Chunk;
+import net.minecraft.server.Entity;
+import net.minecraft.server.EntityAmbient;
+import net.minecraft.server.EntityAnimal;
+import net.minecraft.server.EntityArrow;
+import net.minecraft.server.EntityComplexPart;
+import net.minecraft.server.EntityCreature;
+import net.minecraft.server.EntityCreeper;
+import net.minecraft.server.EntityEnderCrystal;
+import net.minecraft.server.EntityEnderDragon;
+import net.minecraft.server.EntityFireball;
+import net.minecraft.server.EntityFireworks;
+import net.minecraft.server.EntityHuman;
+import net.minecraft.server.EntityLiving;
+import net.minecraft.server.EntityMonster;
+import net.minecraft.server.EntityProjectile;
+import net.minecraft.server.EntitySheep;
+import net.minecraft.server.EntitySlice;
+import net.minecraft.server.EntitySlime;
+import net.minecraft.server.EntityTNTPrimed;
+import net.minecraft.server.EntityVillager;
+import net.minecraft.server.EntityWeather;
+import net.minecraft.server.EntityWither;
+import net.minecraft.server.MathHelper;
+import net.minecraft.server.MinecraftServer;
+import net.minecraft.server.World;
+import org.bukkit.craftbukkit.SpigotTimings;
+
+public class ActivationRange
+{
+
+ static AxisAlignedBB maxBB = new AxisAlignedBB( 0, 0, 0, 0, 0, 0 );
+ static AxisAlignedBB miscBB = new AxisAlignedBB( 0, 0, 0, 0, 0, 0 );
+ static AxisAlignedBB animalBB = new AxisAlignedBB( 0, 0, 0, 0, 0, 0 );
+ static AxisAlignedBB monsterBB = new AxisAlignedBB( 0, 0, 0, 0, 0, 0 );
+
+ /**
+ * Initializes an entities type on construction to specify what group this
+ * entity is in for activation ranges.
+ *
+ * @param entity
+ * @return group id
+ */
+ public static byte initializeEntityActivationType(Entity entity)
+ {
+ if ( entity instanceof EntityMonster || entity instanceof EntitySlime )
+ {
+ return 1; // Monster
+ } else if ( entity instanceof EntityCreature || entity instanceof EntityAmbient )
+ {
+ return 2; // Animal
+ } else
+ {
+ return 3; // Misc
+ }
+ }
+
+ /**
+ * These entities are excluded from Activation range checks.
+ *
+ * @param entity
+ * @param world
+ * @return boolean If it should always tick.
+ */
+ public static boolean initializeEntityActivationState(Entity entity, SpigotWorldConfig config)
+ {
+ if ( ( entity.activationType == 3 && config.miscActivationRange == 0 )
+ || ( entity.activationType == 2 && config.animalActivationRange == 0 )
+ || ( entity.activationType == 1 && config.monsterActivationRange == 0 )
+ || entity instanceof EntityHuman
+ || entity instanceof EntityProjectile
+ || entity instanceof EntityEnderDragon
+ || entity instanceof EntityComplexPart
+ || entity instanceof EntityWither
+ || entity instanceof EntityFireball
+ || entity instanceof EntityWeather
+ || entity instanceof EntityTNTPrimed
+ || entity instanceof EntityEnderCrystal
+ || entity instanceof EntityFireworks )
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Find what entities are in range of the players in the world and set
+ * active if in range.
+ *
+ * @param world
+ */
+ public static void activateEntities(World world)
+ {
+ SpigotTimings.entityActivationCheckTimer.startTiming();
+ final int miscActivationRange = world.spigotConfig.miscActivationRange;
+ final int animalActivationRange = world.spigotConfig.animalActivationRange;
+ final int monsterActivationRange = world.spigotConfig.monsterActivationRange;
+
+ int maxRange = Math.max( monsterActivationRange, animalActivationRange );
+ maxRange = Math.max( maxRange, miscActivationRange );
+ maxRange = Math.min( ( world.spigotConfig.viewDistance << 4 ) - 8, maxRange );
+
+ for ( EntityHuman player : world.players )
+ {
+
+ player.activatedTick = MinecraftServer.currentTick;
+ maxBB = player.getBoundingBox().grow( maxRange, 256, maxRange );
+ miscBB = player.getBoundingBox().grow( miscActivationRange, 256, miscActivationRange );
+ animalBB = player.getBoundingBox().grow( animalActivationRange, 256, animalActivationRange );
+ monsterBB = player.getBoundingBox().grow( monsterActivationRange, 256, monsterActivationRange );
+
+ int i = MathHelper.floor( maxBB.a / 16.0D );
+ int j = MathHelper.floor( maxBB.d / 16.0D );
+ int k = MathHelper.floor( maxBB.c / 16.0D );
+ int l = MathHelper.floor( maxBB.f / 16.0D );
+
+ for ( int i1 = i; i1 <= j; ++i1 )
+ {
+ for ( int j1 = k; j1 <= l; ++j1 )
+ {
+ if ( world.getWorld().isChunkLoaded( i1, j1 ) )
+ {
+ activateChunkEntities( world.getChunkAt( i1, j1 ) );
+ }
+ }
+ }
+ }
+ SpigotTimings.entityActivationCheckTimer.stopTiming();
+ }
+
+ /**
+ * Checks for the activation state of all entities in this chunk.
+ *
+ * @param chunk
+ */
+ private static void activateChunkEntities(Chunk chunk)
+ {
+ for ( EntitySlice slice : chunk.entitySlices )
+ {
+ for ( Entity entity : (Set<Entity>) slice )
+ {
+ if ( MinecraftServer.currentTick > entity.activatedTick )
+ {
+ if ( entity.defaultActivationState )
+ {
+ entity.activatedTick = MinecraftServer.currentTick;
+ continue;
+ }
+ switch ( entity.activationType )
+ {
+ case 1:
+ if ( monsterBB.b( entity.getBoundingBox() ) )
+ {
+ entity.activatedTick = MinecraftServer.currentTick;
+ }
+ break;
+ case 2:
+ if ( animalBB.b( entity.getBoundingBox() ) )
+ {
+ entity.activatedTick = MinecraftServer.currentTick;
+ }
+ break;
+ case 3:
+ default:
+ if ( miscBB.b( entity.getBoundingBox() ) )
+ {
+ entity.activatedTick = MinecraftServer.currentTick;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * If an entity is not in range, do some more checks to see if we should
+ * give it a shot.
+ *
+ * @param entity
+ * @return
+ */
+ public static boolean checkEntityImmunities(Entity entity)
+ {
+ // quick checks.
+ if ( entity.inWater || entity.fireTicks > 0 )
+ {
+ return true;
+ }
+ if ( !( entity instanceof EntityArrow ) )
+ {
+ if ( !entity.onGround || !entity.passengers.isEmpty() || entity.isPassenger() )
+ {
+ return true;
+ }
+ } else if ( !( (EntityArrow) entity ).inGround )
+ {
+ return true;
+ }
+ // special cases.
+ if ( entity instanceof EntityLiving )
+ {
+ EntityLiving living = (EntityLiving) entity;
+ if ( /*TODO: Missed mapping? living.attackTicks > 0 || */ living.hurtTicks > 0 || living.effects.size() > 0 )
+ {
+ return true;
+ }
+ if ( entity instanceof EntityCreature && ( (EntityCreature) entity ).getGoalTarget() != null )
+ {
+ return true;
+ }
+ if ( entity instanceof EntityVillager && ( (EntityVillager) entity ).da() /* Getter for first boolean */ )
+ {
+ return true;
+ }
+ if ( entity instanceof EntityAnimal )
+ {
+ EntityAnimal animal = (EntityAnimal) entity;
+ if ( animal.isBaby() || animal.isInLove() )
+ {
+ return true;
+ }
+ if ( entity instanceof EntitySheep && ( (EntitySheep) entity ).isSheared() )
+ {
+ return true;
+ }
+ }
+ if (entity instanceof EntityCreeper && ((EntityCreeper) entity).isIgnited()) { // isExplosive
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Checks if the entity is active for this tick.
+ *
+ * @param entity
+ * @return
+ */
+ public static boolean checkIfActive(Entity entity)
+ {
+ SpigotTimings.checkIfActiveTimer.startTiming();
+ // Never safe to skip fireworks or entities not yet added to chunk
+ // PAIL: inChunk
+ if ( !entity.aa || entity instanceof EntityFireworks ) {
+ SpigotTimings.checkIfActiveTimer.stopTiming();
+ return true;
+ }
+
+ boolean isActive = entity.activatedTick >= MinecraftServer.currentTick || entity.defaultActivationState;
+
+ // Should this entity tick?
+ if ( !isActive )
+ {
+ if ( ( MinecraftServer.currentTick - entity.activatedTick - 1 ) % 20 == 0 )
+ {
+ // Check immunities every 20 ticks.
+ if ( checkEntityImmunities( entity ) )
+ {
+ // Triggered some sort of immunity, give 20 full ticks before we check again.
+ entity.activatedTick = MinecraftServer.currentTick + 20;
+ }
+ isActive = true;
+ }
+ // Add a little performance juice to active entities. Skip 1/4 if not immune.
+ } else if ( !entity.defaultActivationState && entity.ticksLived % 4 == 0 && !checkEntityImmunities( entity ) )
+ {
+ isActive = false;
+ }
+ int x = MathHelper.floor( entity.locX );
+ int z = MathHelper.floor( entity.locZ );
+ // Make sure not on edge of unloaded chunk
+ Chunk chunk = entity.world.getChunkIfLoaded( x >> 4, z >> 4 );
+ if ( isActive && !( chunk != null && chunk.areNeighborsLoaded( 1 ) ) )
+ {
+ isActive = false;
+ }
+ SpigotTimings.checkIfActiveTimer.stopTiming();
+ return isActive;
+ }
+}
diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java
index ca888fc..92dbe54 100644
--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java
+++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java
@@ -136,4 +136,15 @@ public class SpigotWorldConfig
itemDespawnRate = getInt( "item-despawn-rate", 6000 );
log( "Item Despawn Rate: " + itemDespawnRate );
}
+
+ public int animalActivationRange = 32;
+ public int monsterActivationRange = 32;
+ public int miscActivationRange = 16;
+ private void activationRange()
+ {
+ animalActivationRange = getInt( "entity-activation-range.animals", animalActivationRange );
+ monsterActivationRange = getInt( "entity-activation-range.monsters", monsterActivationRange );
+ miscActivationRange = getInt( "entity-activation-range.misc", miscActivationRange );
+ log( "Entity Activation Range: An " + animalActivationRange + " / Mo " + monsterActivationRange + " / Mi " + miscActivationRange );
+ }
}
--
2.5.0

View File

@ -1,691 +0,0 @@
From 00a824f87f74ff3b2f2e1689d79dc143c481d0b5 Mon Sep 17 00:00:00 2001
From: md_5 <md_5@live.com.au>
Date: Sat, 23 Feb 2013 08:58:35 +1100
Subject: [PATCH] Metrics
diff --git a/src/main/java/org/spigotmc/Metrics.java b/src/main/java/org/spigotmc/Metrics.java
new file mode 100644
index 0000000..a5fd59d
--- /dev/null
+++ b/src/main/java/org/spigotmc/Metrics.java
@@ -0,0 +1,645 @@
+/*
+ * Copyright 2011-2013 Tyler Blair. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and contributors and should not be interpreted as representing official policies,
+ * either expressed or implied, of anybody else.
+ */
+package org.spigotmc;
+
+import org.bukkit.Bukkit;
+import org.bukkit.configuration.file.YamlConfiguration;
+import org.bukkit.configuration.InvalidConfigurationException;
+import org.bukkit.plugin.Plugin;
+import org.bukkit.plugin.PluginDescriptionFile;
+import org.bukkit.scheduler.BukkitTask;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.UnsupportedEncodingException;
+import java.net.Proxy;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLEncoder;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.Set;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.UUID;
+import java.util.concurrent.TimeUnit;
+import java.util.logging.Level;
+import net.minecraft.server.MinecraftServer;
+
+/**
+ * <p> The metrics class obtains data about a plugin and submits statistics about it to the metrics backend. </p> <p>
+ * Public methods provided by this class: </p>
+ * <code>
+ * Graph createGraph(String name); <br/>
+ * void addCustomData(BukkitMetrics.Plotter plotter); <br/>
+ * void start(); <br/>
+ * </code>
+ */
+public class Metrics {
+
+ /**
+ * The current revision number
+ */
+ private final static int REVISION = 6;
+ /**
+ * The base url of the metrics domain
+ */
+ private static final String BASE_URL = "http://mcstats.org";
+ /**
+ * The url used to report a server's status
+ */
+ private static final String REPORT_URL = "/report/%s";
+ /**
+ * The separator to use for custom data. This MUST NOT change unless you are hosting your own version of metrics and
+ * want to change it.
+ */
+ private static final String CUSTOM_DATA_SEPARATOR = "~~";
+ /**
+ * Interval of time to ping (in minutes)
+ */
+ private static final int PING_INTERVAL = 10;
+ /**
+ * All of the custom graphs to submit to metrics
+ */
+ private final Set<Graph> graphs = Collections.synchronizedSet(new HashSet<Graph>());
+ /**
+ * The default graph, used for addCustomData when you don't want a specific graph
+ */
+ private final Graph defaultGraph = new Graph("Default");
+ /**
+ * The plugin configuration file
+ */
+ private final YamlConfiguration configuration;
+ /**
+ * The plugin configuration file
+ */
+ private final File configurationFile;
+ /**
+ * Unique server id
+ */
+ private final String guid;
+ /**
+ * Debug mode
+ */
+ private final boolean debug;
+ /**
+ * Lock for synchronization
+ */
+ private final Object optOutLock = new Object();
+ /**
+ * The scheduled task
+ */
+ private volatile Timer task = null;
+
+ public Metrics() throws IOException {
+ // load the config
+ configurationFile = getConfigFile();
+ configuration = YamlConfiguration.loadConfiguration(configurationFile);
+
+ // add some defaults
+ configuration.addDefault("opt-out", false);
+ configuration.addDefault("guid", UUID.randomUUID().toString());
+ configuration.addDefault("debug", false);
+
+ // Do we need to create the file?
+ if (configuration.get("guid", null) == null) {
+ configuration.options().header("http://mcstats.org").copyDefaults(true);
+ configuration.save(configurationFile);
+ }
+
+ // Load the guid then
+ guid = configuration.getString("guid");
+ debug = configuration.getBoolean("debug", false);
+ }
+
+ /**
+ * Construct and create a Graph that can be used to separate specific plotters to their own graphs on the metrics
+ * website. Plotters can be added to the graph object returned.
+ *
+ * @param name The name of the graph
+ * @return Graph object created. Will never return NULL under normal circumstances unless bad parameters are given
+ */
+ public Graph createGraph(final String name) {
+ if (name == null) {
+ throw new IllegalArgumentException("Graph name cannot be null");
+ }
+
+ // Construct the graph object
+ final Graph graph = new Graph(name);
+
+ // Now we can add our graph
+ graphs.add(graph);
+
+ // and return back
+ return graph;
+ }
+
+ /**
+ * Add a Graph object to BukkitMetrics that represents data for the plugin that should be sent to the backend
+ *
+ * @param graph The name of the graph
+ */
+ public void addGraph(final Graph graph) {
+ if (graph == null) {
+ throw new IllegalArgumentException("Graph cannot be null");
+ }
+
+ graphs.add(graph);
+ }
+
+ /**
+ * Adds a custom data plotter to the default graph
+ *
+ * @param plotter The plotter to use to plot custom data
+ */
+ public void addCustomData(final Plotter plotter) {
+ if (plotter == null) {
+ throw new IllegalArgumentException("Plotter cannot be null");
+ }
+
+ // Add the plotter to the graph o/
+ defaultGraph.addPlotter(plotter);
+
+ // Ensure the default graph is included in the submitted graphs
+ graphs.add(defaultGraph);
+ }
+
+ /**
+ * Start measuring statistics. This will immediately create an async repeating task as the plugin and send the
+ * initial data to the metrics backend, and then after that it will post in increments of PING_INTERVAL * 1200
+ * ticks.
+ *
+ * @return True if statistics measuring is running, otherwise false.
+ */
+ public boolean start() {
+ synchronized (optOutLock) {
+ // Did we opt out?
+ if (isOptOut()) {
+ return false;
+ }
+
+ // Is metrics already running?
+ if (task != null) {
+ return true;
+ }
+
+ // Begin hitting the server with glorious data
+ task = new Timer("Spigot Metrics Thread", true);
+
+ task.scheduleAtFixedRate(new TimerTask() {
+ private boolean firstPost = true;
+
+ public void run() {
+ try {
+ // This has to be synchronized or it can collide with the disable method.
+ synchronized (optOutLock) {
+ // Disable Task, if it is running and the server owner decided to opt-out
+ if (isOptOut() && task != null) {
+ task.cancel();
+ task = null;
+ // Tell all plotters to stop gathering information.
+ for (Graph graph : graphs) {
+ graph.onOptOut();
+ }
+ }
+ }
+
+ // We use the inverse of firstPost because if it is the first time we are posting,
+ // it is not a interval ping, so it evaluates to FALSE
+ // Each time thereafter it will evaluate to TRUE, i.e PING!
+ postPlugin(!firstPost);
+
+ // After the first post we set firstPost to false
+ // Each post thereafter will be a ping
+ firstPost = false;
+ } catch (IOException e) {
+ if (debug) {
+ Bukkit.getLogger().log(Level.INFO, "[Metrics] " + e.getMessage());
+ }
+ }
+ }
+ }, 0, TimeUnit.MINUTES.toMillis(PING_INTERVAL));
+
+ return true;
+ }
+ }
+
+ /**
+ * Has the server owner denied plugin metrics?
+ *
+ * @return true if metrics should be opted out of it
+ */
+ public boolean isOptOut() {
+ synchronized (optOutLock) {
+ try {
+ // Reload the metrics file
+ configuration.load(getConfigFile());
+ } catch (IOException ex) {
+ if (debug) {
+ Bukkit.getLogger().log(Level.INFO, "[Metrics] " + ex.getMessage());
+ }
+ return true;
+ } catch (InvalidConfigurationException ex) {
+ if (debug) {
+ Bukkit.getLogger().log(Level.INFO, "[Metrics] " + ex.getMessage());
+ }
+ return true;
+ }
+ return configuration.getBoolean("opt-out", false);
+ }
+ }
+
+ /**
+ * Enables metrics for the server by setting "opt-out" to false in the config file and starting the metrics task.
+ *
+ * @throws java.io.IOException
+ */
+ public void enable() throws IOException {
+ // This has to be synchronized or it can collide with the check in the task.
+ synchronized (optOutLock) {
+ // Check if the server owner has already set opt-out, if not, set it.
+ if (isOptOut()) {
+ configuration.set("opt-out", false);
+ configuration.save(configurationFile);
+ }
+
+ // Enable Task, if it is not running
+ if (task == null) {
+ start();
+ }
+ }
+ }
+
+ /**
+ * Disables metrics for the server by setting "opt-out" to true in the config file and canceling the metrics task.
+ *
+ * @throws java.io.IOException
+ */
+ public void disable() throws IOException {
+ // This has to be synchronized or it can collide with the check in the task.
+ synchronized (optOutLock) {
+ // Check if the server owner has already set opt-out, if not, set it.
+ if (!isOptOut()) {
+ configuration.set("opt-out", true);
+ configuration.save(configurationFile);
+ }
+
+ // Disable Task, if it is running
+ if (task != null) {
+ task.cancel();
+ task = null;
+ }
+ }
+ }
+
+ /**
+ * Gets the File object of the config file that should be used to store data such as the GUID and opt-out status
+ *
+ * @return the File object for the config file
+ */
+ public File getConfigFile() {
+ // I believe the easiest way to get the base folder (e.g craftbukkit set via -P) for plugins to use
+ // is to abuse the plugin object we already have
+ // plugin.getDataFolder() => base/plugins/PluginA/
+ // pluginsFolder => base/plugins/
+ // The base is not necessarily relative to the startup directory.
+ // File pluginsFolder = plugin.getDataFolder().getParentFile();
+
+ // return => base/plugins/PluginMetrics/config.yml
+ return new File(new File((File) MinecraftServer.getServer().options.valueOf("plugins"), "PluginMetrics"), "config.yml");
+ }
+
+ /**
+ * Generic method that posts a plugin to the metrics website
+ */
+ private void postPlugin(final boolean isPing) throws IOException {
+ // Server software specific section
+ String pluginName = "Spigot";
+ boolean onlineMode = Bukkit.getServer().getOnlineMode(); // TRUE if online mode is enabled
+ String pluginVersion = (Metrics.class.getPackage().getImplementationVersion() != null) ? Metrics.class.getPackage().getImplementationVersion() : "unknown";
+ String serverVersion = Bukkit.getVersion();
+ int playersOnline = Bukkit.getServer().getOnlinePlayers().size();
+
+ // END server software specific section -- all code below does not use any code outside of this class / Java
+
+ // Construct the post data
+ final StringBuilder data = new StringBuilder();
+
+ // The plugin's description file containg all of the plugin data such as name, version, author, etc
+ data.append(encode("guid")).append('=').append(encode(guid));
+ encodeDataPair(data, "version", pluginVersion);
+ encodeDataPair(data, "server", serverVersion);
+ encodeDataPair(data, "players", Integer.toString(playersOnline));
+ encodeDataPair(data, "revision", String.valueOf(REVISION));
+
+ // New data as of R6
+ String osname = System.getProperty("os.name");
+ String osarch = System.getProperty("os.arch");
+ String osversion = System.getProperty("os.version");
+ String java_version = System.getProperty("java.version");
+ int coreCount = Runtime.getRuntime().availableProcessors();
+
+ // normalize os arch .. amd64 -> x86_64
+ if (osarch.equals("amd64")) {
+ osarch = "x86_64";
+ }
+
+ encodeDataPair(data, "osname", osname);
+ encodeDataPair(data, "osarch", osarch);
+ encodeDataPair(data, "osversion", osversion);
+ encodeDataPair(data, "cores", Integer.toString(coreCount));
+ encodeDataPair(data, "online-mode", Boolean.toString(onlineMode));
+ encodeDataPair(data, "java_version", java_version);
+
+ // If we're pinging, append it
+ if (isPing) {
+ encodeDataPair(data, "ping", "true");
+ }
+
+ // Acquire a lock on the graphs, which lets us make the assumption we also lock everything
+ // inside of the graph (e.g plotters)
+ synchronized (graphs) {
+ final Iterator<Graph> iter = graphs.iterator();
+
+ while (iter.hasNext()) {
+ final Graph graph = iter.next();
+
+ for (Plotter plotter : graph.getPlotters()) {
+ // The key name to send to the metrics server
+ // The format is C-GRAPHNAME-PLOTTERNAME where separator - is defined at the top
+ // Legacy (R4) submitters use the format Custom%s, or CustomPLOTTERNAME
+ final String key = String.format("C%s%s%s%s", CUSTOM_DATA_SEPARATOR, graph.getName(), CUSTOM_DATA_SEPARATOR, plotter.getColumnName());
+
+ // The value to send, which for the foreseeable future is just the string
+ // value of plotter.getValue()
+ final String value = Integer.toString(plotter.getValue());
+
+ // Add it to the http post data :)
+ encodeDataPair(data, key, value);
+ }
+ }
+ }
+
+ // Create the url
+ URL url = new URL(BASE_URL + String.format(REPORT_URL, encode(pluginName)));
+
+ // Connect to the website
+ URLConnection connection;
+
+ // Mineshafter creates a socks proxy, so we can safely bypass it
+ // It does not reroute POST requests so we need to go around it
+ if (isMineshafterPresent()) {
+ connection = url.openConnection(Proxy.NO_PROXY);
+ } else {
+ connection = url.openConnection();
+ }
+
+ connection.setDoOutput(true);
+
+ // Write the data
+ final OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream());
+ writer.write(data.toString());
+ writer.flush();
+
+ // Now read the response
+ final BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
+ final String response = reader.readLine();
+
+ // close resources
+ writer.close();
+ reader.close();
+
+ if (response == null || response.startsWith("ERR")) {
+ throw new IOException(response); //Throw the exception
+ } else {
+ // Is this the first update this hour?
+ if (response.contains("OK This is your first update this hour")) {
+ synchronized (graphs) {
+ final Iterator<Graph> iter = graphs.iterator();
+
+ while (iter.hasNext()) {
+ final Graph graph = iter.next();
+
+ for (Plotter plotter : graph.getPlotters()) {
+ plotter.reset();
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Check if mineshafter is present. If it is, we need to bypass it to send POST requests
+ *
+ * @return true if mineshafter is installed on the server
+ */
+ private boolean isMineshafterPresent() {
+ try {
+ Class.forName("mineshafter.MineServer");
+ return true;
+ } catch (Exception e) {
+ return false;
+ }
+ }
+
+ /**
+ * <p>Encode a key/value data pair to be used in a HTTP post request. This INCLUDES a & so the first key/value pair
+ * MUST be included manually, e.g:</p>
+ * <code>
+ * StringBuffer data = new StringBuffer();
+ * data.append(encode("guid")).append('=').append(encode(guid));
+ * encodeDataPair(data, "version", description.getVersion());
+ * </code>
+ *
+ * @param buffer the stringbuilder to append the data pair onto
+ * @param key the key value
+ * @param value the value
+ */
+ private static void encodeDataPair(final StringBuilder buffer, final String key, final String value) throws UnsupportedEncodingException {
+ buffer.append('&').append(encode(key)).append('=').append(encode(value));
+ }
+
+ /**
+ * Encode text as UTF-8
+ *
+ * @param text the text to encode
+ * @return the encoded text, as UTF-8
+ */
+ private static String encode(final String text) throws UnsupportedEncodingException {
+ return URLEncoder.encode(text, "UTF-8");
+ }
+
+ /**
+ * Represents a custom graph on the website
+ */
+ public static class Graph {
+
+ /**
+ * The graph's name, alphanumeric and spaces only :) If it does not comply to the above when submitted, it is
+ * rejected
+ */
+ private final String name;
+ /**
+ * The set of plotters that are contained within this graph
+ */
+ private final Set<Plotter> plotters = new LinkedHashSet<Plotter>();
+
+ private Graph(final String name) {
+ this.name = name;
+ }
+
+ /**
+ * Gets the graph's name
+ *
+ * @return the Graph's name
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Add a plotter to the graph, which will be used to plot entries
+ *
+ * @param plotter the plotter to add to the graph
+ */
+ public void addPlotter(final Plotter plotter) {
+ plotters.add(plotter);
+ }
+
+ /**
+ * Remove a plotter from the graph
+ *
+ * @param plotter the plotter to remove from the graph
+ */
+ public void removePlotter(final Plotter plotter) {
+ plotters.remove(plotter);
+ }
+
+ /**
+ * Gets an <b>unmodifiable</b> set of the plotter objects in the graph
+ *
+ * @return an unmodifiable {@link java.util.Set} of the plotter objects
+ */
+ public Set<Plotter> getPlotters() {
+ return Collections.unmodifiableSet(plotters);
+ }
+
+ @Override
+ public int hashCode() {
+ return name.hashCode();
+ }
+
+ @Override
+ public boolean equals(final Object object) {
+ if (!(object instanceof Graph)) {
+ return false;
+ }
+
+ final Graph graph = (Graph) object;
+ return graph.name.equals(name);
+ }
+
+ /**
+ * Called when the server owner decides to opt-out of BukkitMetrics while the server is running.
+ */
+ protected void onOptOut() {
+ }
+ }
+
+ /**
+ * Interface used to collect custom data for a plugin
+ */
+ public static abstract class Plotter {
+
+ /**
+ * The plot's name
+ */
+ private final String name;
+
+ /**
+ * Construct a plotter with the default plot name
+ */
+ public Plotter() {
+ this("Default");
+ }
+
+ /**
+ * Construct a plotter with a specific plot name
+ *
+ * @param name the name of the plotter to use, which will show up on the website
+ */
+ public Plotter(final String name) {
+ this.name = name;
+ }
+
+ /**
+ * Get the current value for the plotted point. Since this function defers to an external function it may or may
+ * not return immediately thus cannot be guaranteed to be thread friendly or safe. This function can be called
+ * from any thread so care should be taken when accessing resources that need to be synchronized.
+ *
+ * @return the current value for the point to be plotted.
+ */
+ public abstract int getValue();
+
+ /**
+ * Get the column name for the plotted point
+ *
+ * @return the plotted point's column name
+ */
+ public String getColumnName() {
+ return name;
+ }
+
+ /**
+ * Called after the website graphs have been updated
+ */
+ public void reset() {
+ }
+
+ @Override
+ public int hashCode() {
+ return getColumnName().hashCode();
+ }
+
+ @Override
+ public boolean equals(final Object object) {
+ if (!(object instanceof Plotter)) {
+ return false;
+ }
+
+ final Plotter plotter = (Plotter) object;
+ return plotter.name.equals(name) && plotter.getValue() == getValue();
+ }
+ }
+}
diff --git a/src/main/java/org/spigotmc/SpigotConfig.java b/src/main/java/org/spigotmc/SpigotConfig.java
index cb88089..dcca493 100644
--- a/src/main/java/org/spigotmc/SpigotConfig.java
+++ b/src/main/java/org/spigotmc/SpigotConfig.java
@@ -36,6 +36,7 @@ public class SpigotConfig
static int version;
static Map<String, Command> commands;
/*========================================================================*/
+ private static Metrics metrics;
public static void init(File configFile)
{
@@ -68,6 +69,18 @@ public class SpigotConfig
{
MinecraftServer.getServer().server.getCommandMap().register( entry.getKey(), "Spigot", entry.getValue() );
}
+
+ if ( metrics == null )
+ {
+ try
+ {
+ metrics = new Metrics();
+ metrics.start();
+ } catch ( IOException ex )
+ {
+ Bukkit.getServer().getLogger().log( Level.SEVERE, "Could not start metrics service", ex );
+ }
+ }
}
static void readConfig(Class<?> clazz, Object instance)
--
2.5.0

View File

@ -1,52 +0,0 @@
From 9f79aedb7c74ac76bbc9360b8a63b4fa0122313f Mon Sep 17 00:00:00 2001
From: md_5 <md_5@live.com.au>
Date: Mon, 4 Mar 2013 18:45:52 +1100
Subject: [PATCH] PlayerItemDamageEvent
diff --git a/src/main/java/net/minecraft/server/ItemStack.java b/src/main/java/net/minecraft/server/ItemStack.java
index e659ac5..782ca57 100644
--- a/src/main/java/net/minecraft/server/ItemStack.java
+++ b/src/main/java/net/minecraft/server/ItemStack.java
@@ -338,6 +338,11 @@ public final class ItemStack {
}
public boolean isDamaged(int i, Random random) {
+ return isDamaged(i, random, null);
+ }
+
+ public boolean isDamaged(int i, Random random, EntityLiving entityliving) {
+ // Spigot end
if (!this.e()) {
return false;
} else {
@@ -352,7 +357,16 @@ public final class ItemStack {
}
i -= k;
- if (i <= 0) {
+ // Spigot start
+ if (entityliving instanceof EntityPlayer) {
+ org.bukkit.craftbukkit.inventory.CraftItemStack item = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(this);
+ org.bukkit.event.player.PlayerItemDamageEvent event = new org.bukkit.event.player.PlayerItemDamageEvent((org.bukkit.entity.Player) entityliving.getBukkitEntity(), item, i);
+ org.bukkit.Bukkit.getServer().getPluginManager().callEvent(event);
+ if (event.isCancelled()) return false;
+ i = event.getDamage();
+ }
+ // Spigot end
+ if (i <= 0 ) {
return false;
}
}
@@ -365,7 +379,7 @@ public final class ItemStack {
public void damage(int i, EntityLiving entityliving) {
if (!(entityliving instanceof EntityHuman) || !((EntityHuman) entityliving).abilities.canInstantlyBuild) {
if (this.e()) {
- if (this.isDamaged(i, entityliving.getRandom())) {
+ if (this.isDamaged(i, entityliving.getRandom(), entityliving)) { // Spigot
entityliving.b(this);
--this.count;
if (entityliving instanceof EntityHuman) {
--
2.5.0

View File

@ -1,27 +0,0 @@
From 8ab16d84c2c2527ca6d12c3f2ecee24d46e9facb Mon Sep 17 00:00:00 2001
From: md_5 <md_5@live.com.au>
Date: Mon, 18 Mar 2013 20:01:44 +1100
Subject: [PATCH] Prevent NPE in CraftSign
This commit prevents the constructor of CraftSign throwing an NPE when it cannot get the sign tile entity. Instead it will fallback to a 4 empty lined sign, and not try to do anything to those lines on .update().
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftSign.java b/src/main/java/org/bukkit/craftbukkit/block/CraftSign.java
index 42a6f9a..43adfcc 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftSign.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftSign.java
@@ -18,6 +18,12 @@ public class CraftSign extends CraftBlockState implements Sign {
CraftWorld world = (CraftWorld) block.getWorld();
sign = (TileEntitySign) world.getTileEntityAt(getX(), getY(), getZ());
+ // Spigot start
+ if (sign == null) {
+ lines = new String[]{"", "", "", ""};
+ return;
+ }
+ // Spigot end
lines = new String[sign.lines.length];
System.arraycopy(revertComponents(sign.lines), 0, lines, 0, lines.length);
}
--
2.5.0

View File

@ -1,109 +0,0 @@
From f7020dc8e3f83b179a9ae3e8df654c1498dafc06 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Wed, 20 Feb 2013 11:58:47 -0500
Subject: [PATCH] Entity Tracking Ranges
This will let you configure how far to track entities in range from players, so that the entity does not render on the client if out of this range.
This has multiple benefits:
1) Less bandwidth. Not sending update packets for entities that are not even close to a player, or even close enough to clearly see.
2) Less lag by maps in item frames - Default range is 160 blocks... Many players can track that item frame and cause lag and not even see it.
3) Less lag in general - Less work for the server to do
4) Less client lag - Not trying to render distant item frames and paintings and entities will reduce entity count on the client, which is major for shop/town worlds which may use tons of item frames.
diff --git a/src/main/java/net/minecraft/server/EntityTracker.java b/src/main/java/net/minecraft/server/EntityTracker.java
index 0c19e5a..3773bb1 100644
--- a/src/main/java/net/minecraft/server/EntityTracker.java
+++ b/src/main/java/net/minecraft/server/EntityTracker.java
@@ -103,6 +103,7 @@ public class EntityTracker {
public void addEntity(Entity entity, int i, final int j, boolean flag) {
org.spigotmc.AsyncCatcher.catchOp( "entity track"); // Spigot
+ i = org.spigotmc.TrackingRange.getEntityTrackingRange(entity, i); // Spigot
try {
if (this.trackedEntities.b(entity.getId())) {
throw new IllegalStateException("Entity is already tracked!");
diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java
index 92dbe54..1369657 100644
--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java
+++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java
@@ -147,4 +147,19 @@ public class SpigotWorldConfig
miscActivationRange = getInt( "entity-activation-range.misc", miscActivationRange );
log( "Entity Activation Range: An " + animalActivationRange + " / Mo " + monsterActivationRange + " / Mi " + miscActivationRange );
}
+
+ public int playerTrackingRange = 48;
+ public int animalTrackingRange = 48;
+ public int monsterTrackingRange = 48;
+ public int miscTrackingRange = 32;
+ public int otherTrackingRange = 64;
+ private void trackingRange()
+ {
+ playerTrackingRange = getInt( "entity-tracking-range.players", playerTrackingRange );
+ animalTrackingRange = getInt( "entity-tracking-range.animals", animalTrackingRange );
+ monsterTrackingRange = getInt( "entity-tracking-range.monsters", monsterTrackingRange );
+ miscTrackingRange = getInt( "entity-tracking-range.misc", miscTrackingRange );
+ otherTrackingRange = getInt( "entity-tracking-range.other", otherTrackingRange );
+ log( "Entity Tracking Range: Pl " + playerTrackingRange + " / An " + animalTrackingRange + " / Mo " + monsterTrackingRange + " / Mi " + miscTrackingRange + " / Other " + otherTrackingRange );
+ }
}
diff --git a/src/main/java/org/spigotmc/TrackingRange.java b/src/main/java/org/spigotmc/TrackingRange.java
new file mode 100644
index 0000000..4bf4d2a
--- /dev/null
+++ b/src/main/java/org/spigotmc/TrackingRange.java
@@ -0,0 +1,51 @@
+package org.spigotmc;
+
+import net.minecraft.server.Entity;
+import net.minecraft.server.EntityExperienceOrb;
+import net.minecraft.server.EntityGhast;
+import net.minecraft.server.EntityItem;
+import net.minecraft.server.EntityItemFrame;
+import net.minecraft.server.EntityPainting;
+import net.minecraft.server.EntityPlayer;
+
+public class TrackingRange
+{
+
+ /**
+ * Gets the range an entity should be 'tracked' by players and visible in
+ * the client.
+ *
+ * @param entity
+ * @param defaultRange Default range defined by Mojang
+ * @return
+ */
+ public static int getEntityTrackingRange(Entity entity, int defaultRange)
+ {
+ SpigotWorldConfig config = entity.world.spigotConfig;
+ if ( entity instanceof EntityPlayer )
+ {
+ return config.playerTrackingRange;
+ } else if ( entity.activationType == 1 )
+ {
+ return config.monsterTrackingRange;
+ } else if ( entity instanceof EntityGhast )
+ {
+ if ( config.monsterTrackingRange > config.monsterActivationRange )
+ {
+ return config.monsterTrackingRange;
+ } else
+ {
+ return config.monsterActivationRange;
+ }
+ } else if ( entity.activationType == 2 )
+ {
+ return config.animalTrackingRange;
+ } else if ( entity instanceof EntityItemFrame || entity instanceof EntityPainting || entity instanceof EntityItem || entity instanceof EntityExperienceOrb )
+ {
+ return config.miscTrackingRange;
+ } else
+ {
+ return config.otherTrackingRange;
+ }
+ }
+}
--
2.5.0

View File

@ -1,23 +0,0 @@
From c80bcc2152798c930886951e4a7dadec80af2623 Mon Sep 17 00:00:00 2001
From: md_5 <md_5@live.com.au>
Date: Tue, 23 Apr 2013 11:50:27 +1000
Subject: [PATCH] Thread Naming and Tweaks
Removes the sleep forever thread and adds useful names for debugging to all staged thread files.
diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
index 8442ecb..93d8d42 100644
--- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
+++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
@@ -72,7 +72,7 @@ public class CraftScheduler implements BukkitScheduler {
*/
private final ConcurrentHashMap<Integer, CraftTask> runners = new ConcurrentHashMap<Integer, CraftTask>();
private volatile int currentTick = -1;
- private final Executor executor = Executors.newCachedThreadPool();
+ private final Executor executor = Executors.newCachedThreadPool(new com.google.common.util.concurrent.ThreadFactoryBuilder().setNameFormat("Craft Scheduler Thread - %1$d").build()); // Spigot
private CraftAsyncDebugger debugHead = new CraftAsyncDebugger(-1, null, null) {@Override StringBuilder debugTo(StringBuilder string) {return string;}};
private CraftAsyncDebugger debugTail = debugHead;
private static final int RECENT_TICKS;
--
2.5.0

View File

@ -1,58 +0,0 @@
From 1fdbeff9746f4351c28d219906ba0827c4e042c3 Mon Sep 17 00:00:00 2001
From: Antony Riley <antony@cyberiantiger.org>
Date: Wed, 27 Mar 2013 01:41:54 +0200
Subject: [PATCH] Close Unloaded Save Files
diff --git a/src/main/java/net/minecraft/server/RegionFileCache.java b/src/main/java/net/minecraft/server/RegionFileCache.java
index b07e7d5..5528019 100644
--- a/src/main/java/net/minecraft/server/RegionFileCache.java
+++ b/src/main/java/net/minecraft/server/RegionFileCache.java
@@ -10,7 +10,7 @@ import java.util.Map;
public class RegionFileCache {
- private static final Map<File, RegionFile> a = Maps.newHashMap();
+ public static final Map<File, RegionFile> a = Maps.newHashMap(); // Spigot - private -> public
public static synchronized RegionFile a(File file, int i, int j) {
File file1 = new File(file, "region");
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index 261b423..f906f60 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -966,6 +966,31 @@ public final class CraftServer implements Server {
worlds.remove(world.getName().toLowerCase());
console.worlds.remove(console.worlds.indexOf(handle));
+
+ File parentFolder = world.getWorldFolder().getAbsoluteFile();
+
+ // Synchronized because access to RegionFileCache.a is guarded by this lock.
+ synchronized (RegionFileCache.class) {
+ // RegionFileCache.a should be RegionFileCache.cache
+ Iterator<Map.Entry<File, RegionFile>> i = RegionFileCache.a.entrySet().iterator();
+ while(i.hasNext()) {
+ Map.Entry<File, RegionFile> entry = i.next();
+ File child = entry.getKey().getAbsoluteFile();
+ while (child != null) {
+ if (child.equals(parentFolder)) {
+ i.remove();
+ try {
+ entry.getValue().c(); // Should be RegionFile.close();
+ } catch (IOException ex) {
+ getLogger().log(Level.SEVERE, null, ex);
+ }
+ break;
+ }
+ child = child.getParentFile();
+ }
+ }
+ }
+
return true;
}
--
2.5.0

View File

@ -1,23 +0,0 @@
From 4f8eb5a098a2303e0aa999424b5a425d6e20640a Mon Sep 17 00:00:00 2001
From: md_5 <md_5@live.com.au>
Date: Sun, 19 May 2013 18:29:48 +1000
Subject: [PATCH] Remove -o Option
Serves no purpose other than to confuse users.
diff --git a/src/main/java/net/minecraft/server/PropertyManager.java b/src/main/java/net/minecraft/server/PropertyManager.java
index 8ee534b..80ec702 100644
--- a/src/main/java/net/minecraft/server/PropertyManager.java
+++ b/src/main/java/net/minecraft/server/PropertyManager.java
@@ -54,7 +54,7 @@ public class PropertyManager {
}
private <T> T getOverride(String name, T value) {
- if ((this.options != null) && (this.options.has(name))) {
+ if ((this.options != null) && (this.options.has(name)) && !name.equals( "online-mode")) { // Spigot
return (T) this.options.valueOf(name);
}
--
2.5.0

View File

@ -1,71 +0,0 @@
From 2eb971b8ea7c38519d0acaa6dbae6e74bf2cb457 Mon Sep 17 00:00:00 2001
From: md_5 <md_5@live.com.au>
Date: Sat, 1 Jun 2013 16:34:38 +1000
Subject: [PATCH] Recipe Deconstruction
Some non API methods contributed by Asphodan to allow recipe deconstruction.
diff --git a/src/main/java/net/minecraft/server/IRecipe.java b/src/main/java/net/minecraft/server/IRecipe.java
index f963104..ffc65a2 100644
--- a/src/main/java/net/minecraft/server/IRecipe.java
+++ b/src/main/java/net/minecraft/server/IRecipe.java
@@ -13,4 +13,6 @@ public interface IRecipe {
ItemStack[] b(InventoryCrafting inventorycrafting);
org.bukkit.inventory.Recipe toBukkitRecipe(); // CraftBukkit
+
+ java.util.List<ItemStack> getIngredients(); // Spigot
}
diff --git a/src/main/java/net/minecraft/server/ShapedRecipes.java b/src/main/java/net/minecraft/server/ShapedRecipes.java
index 28adcdb..cac2e78 100644
--- a/src/main/java/net/minecraft/server/ShapedRecipes.java
+++ b/src/main/java/net/minecraft/server/ShapedRecipes.java
@@ -10,7 +10,7 @@ public class ShapedRecipes implements IRecipe {
private final int width;
private final int height;
private final ItemStack[] items;
- private final ItemStack result;
+ public ItemStack result; // Spigot
private boolean e;
public ShapedRecipes(int i, int j, ItemStack[] aitemstack, ItemStack itemstack) {
@@ -165,4 +165,11 @@ public class ShapedRecipes implements IRecipe {
public int a() {
return this.width * this.height;
}
+
+ // Spigot start
+ public java.util.List<ItemStack> getIngredients()
+ {
+ return java.util.Arrays.asList( items );
+ }
+ // Spigot end
}
diff --git a/src/main/java/net/minecraft/server/ShapelessRecipes.java b/src/main/java/net/minecraft/server/ShapelessRecipes.java
index 8570889..e9934f9 100644
--- a/src/main/java/net/minecraft/server/ShapelessRecipes.java
+++ b/src/main/java/net/minecraft/server/ShapelessRecipes.java
@@ -12,7 +12,7 @@ import org.bukkit.craftbukkit.inventory.CraftShapelessRecipe;
public class ShapelessRecipes implements IRecipe {
- private final ItemStack result;
+ public final ItemStack result; // Spigot
private final List<ItemStack> ingredients;
public ShapelessRecipes(ItemStack itemstack, List<ItemStack> list) {
@@ -90,4 +90,11 @@ public class ShapelessRecipes implements IRecipe {
public int a() {
return this.ingredients.size();
}
+
+ // Spigot start
+ public java.util.List<ItemStack> getIngredients()
+ {
+ return java.util.Collections.unmodifiableList( ingredients );
+ }
+ // Spigot end
}
--
2.5.0

View File

@ -1,31 +0,0 @@
From d468b6a997fe3765682774a037d9fe7208e77647 Mon Sep 17 00:00:00 2001
From: md_5 <md_5@live.com.au>
Date: Sun, 2 Jun 2013 15:16:05 +1000
Subject: [PATCH] Implement Arrow API
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftArrow.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftArrow.java
index bf48e6e..2a3482c 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftArrow.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftArrow.java
@@ -75,6 +75,17 @@ public class CraftArrow extends AbstractProjectile implements Arrow {
// Spigot start
private final Arrow.Spigot spigot = new Arrow.Spigot()
{
+ @Override
+ public double getDamage()
+ {
+ return getHandle().k();
+ }
+
+ @Override
+ public void setDamage(double damage)
+ {
+ getHandle().c( damage );
+ }
};
public Arrow.Spigot spigot()
--
2.5.0

View File

@ -1,125 +0,0 @@
From 6b0ebbee8cf70d21d0eb858d3fb1728ac1ae46f4 Mon Sep 17 00:00:00 2001
From: erocs <github@erocs.org>
Date: Sun, 8 Sep 2013 12:06:15 -0700
Subject: [PATCH] Hopper Customisations
Allows editing hopper cooldowns and amount transferred per tick.
diff --git a/src/main/java/net/minecraft/server/TileEntityHopper.java b/src/main/java/net/minecraft/server/TileEntityHopper.java
index 7b00f6a..c01acb9 100644
--- a/src/main/java/net/minecraft/server/TileEntityHopper.java
+++ b/src/main/java/net/minecraft/server/TileEntityHopper.java
@@ -174,12 +174,11 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi
}
if (flag) {
- this.setCooldown(8);
+ this.setCooldown(world.spigotConfig.hopperTransfer); // Spigot
this.update();
return true;
}
}
-
return false;
} else {
return false;
@@ -233,7 +232,7 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi
// ItemStack itemstack1 = addItem(iinventory, this.splitStack(i, 1), enumdirection);
// CraftBukkit start - Call event when pushing items into other inventories
- CraftItemStack oitemstack = CraftItemStack.asCraftMirror(this.splitStack(i, 1));
+ CraftItemStack oitemstack = CraftItemStack.asCraftMirror(this.splitStack(i, world.spigotConfig.hopperAmount)); // Spigot
Inventory destinationInventory;
// Have to special case large chests as they work oddly
@@ -247,9 +246,10 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi
this.getWorld().getServer().getPluginManager().callEvent(event);
if (event.isCancelled()) {
this.setItem(i, itemstack);
- this.setCooldown(8); // Delay hopper checks
+ this.setCooldown(world.spigotConfig.hopperTransfer); // Spigot
return false;
}
+ int origCount = event.getItem().getAmount(); // Spigot
ItemStack itemstack1 = addItem(iinventory, CraftItemStack.asNMSCopy(event.getItem()), enumdirection);
if (itemstack1 == null || itemstack1.count == 0) {
@@ -261,7 +261,7 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi
// CraftBukkit end
return true;
}
-
+ itemstack.count -= origCount - itemstack1.count; // Spigot
this.setItem(i, itemstack);
}
}
@@ -371,7 +371,7 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi
ItemStack itemstack1 = itemstack.cloneItemStack();
// ItemStack itemstack2 = addItem(ihopper, iinventory.splitStack(i, 1), (EnumDirection) null);
// CraftBukkit start - Call event on collection of items from inventories into the hopper
- CraftItemStack oitemstack = CraftItemStack.asCraftMirror(iinventory.splitStack(i, 1));
+ CraftItemStack oitemstack = CraftItemStack.asCraftMirror(iinventory.splitStack(i, ihopper.getWorld().spigotConfig.hopperAmount)); // Spigot
Inventory sourceInventory;
// Have to special case large chests as they work oddly
@@ -388,13 +388,13 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi
iinventory.setItem(i, itemstack1);
if (ihopper instanceof TileEntityHopper) {
- ((TileEntityHopper) ihopper).setCooldown(8); // Delay hopper checks
+ ((TileEntityHopper) ihopper).setCooldown(ihopper.getWorld().spigotConfig.hopperTransfer); // Spigot
} else if (ihopper instanceof EntityMinecartHopper) {
- ((EntityMinecartHopper) ihopper).setCooldown(4); // Delay hopper minecart checks
+ ((EntityMinecartHopper) ihopper).setCooldown(ihopper.getWorld().spigotConfig.hopperTransfer / 2); // Spigot
}
-
return false;
}
+ int origCount = event.getItem().getAmount(); // Spigot
ItemStack itemstack2 = addItem(ihopper, CraftItemStack.asNMSCopy(event.getItem()), null);
if (itemstack2 == null || itemstack2.count == 0) {
@@ -406,6 +406,7 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi
// CraftBukkit end
return true;
}
+ itemstack1.count -= origCount - itemstack2.count; // Spigot
iinventory.setItem(i, itemstack1);
}
@@ -495,7 +496,7 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi
TileEntityHopper tileentityhopper = (TileEntityHopper) iinventory;
if (tileentityhopper.p()) {
- tileentityhopper.setCooldown(8);
+ tileentityhopper.setCooldown(tileentityhopper.world.spigotConfig.hopperTransfer); // Spigot
}
iinventory.update();
diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java
index 1369657..4de0a98 100644
--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java
+++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java
@@ -162,4 +162,19 @@ public class SpigotWorldConfig
otherTrackingRange = getInt( "entity-tracking-range.other", otherTrackingRange );
log( "Entity Tracking Range: Pl " + playerTrackingRange + " / An " + animalTrackingRange + " / Mo " + monsterTrackingRange + " / Mi " + miscTrackingRange + " / Other " + otherTrackingRange );
}
+
+ public int hopperTransfer;
+ public int hopperCheck;
+ public int hopperAmount;
+ private void hoppers()
+ {
+ // Set the tick delay between hopper item movements
+ hopperTransfer = getInt( "ticks-per.hopper-transfer", 8 );
+ // Set the tick delay between checking for items after the associated
+ // container is empty. Default to the hopperTransfer value to prevent
+ // hopper sorting machines from becoming out of sync.
+ hopperCheck = getInt( "ticks-per.hopper-check", hopperTransfer );
+ hopperAmount = getInt( "hopper-amount", 1 );
+ log( "Hopper Transfer: " + hopperTransfer + " Hopper Check: " + hopperCheck + " Hopper Amount: " + hopperAmount );
+ }
}
--
2.5.0

View File

@ -1,31 +0,0 @@
From 12c21abb5f5c7728ff6312b73ca738cf2910085a Mon Sep 17 00:00:00 2001
From: md_5 <md_5@live.com.au>
Date: Sat, 15 Jun 2013 21:34:48 +1000
Subject: [PATCH] Firework Meta Crash Fix
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaFirework.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaFirework.java
index 0f7da6b..5a409ae 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaFirework.java
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaFirework.java
@@ -145,7 +145,7 @@ class CraftMetaFirework extends CraftMetaItem implements FireworkMeta {
case BURST:
return 4;
default:
- throw new AssertionError(type);
+ throw new IllegalStateException(type.toString()); // Spigot
}
}
@@ -162,7 +162,7 @@ class CraftMetaFirework extends CraftMetaItem implements FireworkMeta {
case 4:
return Type.BURST;
default:
- throw new AssertionError(nbt);
+ throw new IllegalStateException(Integer.toString(nbt)); // Spigot
}
}
--
2.5.0

View File

@ -1,36 +0,0 @@
From 2467f472fd780075961558c3f14cd3cde2f51dcb Mon Sep 17 00:00:00 2001
From: md_5 <md_5@live.com.au>
Date: Fri, 21 Jun 2013 18:01:29 +1000
Subject: [PATCH] Allow Disabling of Command Logging
diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java
index 76cbb21..7d98d67 100644
--- a/src/main/java/net/minecraft/server/PlayerConnection.java
+++ b/src/main/java/net/minecraft/server/PlayerConnection.java
@@ -1284,6 +1284,7 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable {
private void handleCommand(String s) {
org.bukkit.craftbukkit.SpigotTimings.playerCommandTimer.startTiming(); // Spigot
// CraftBukkit start - whole method
+ if ( org.spigotmc.SpigotConfig.logCommands ) // Spigot
this.LOGGER.info(this.player.getName() + " issued server command: " + s);
CraftPlayer player = this.getPlayer();
diff --git a/src/main/java/org/spigotmc/SpigotConfig.java b/src/main/java/org/spigotmc/SpigotConfig.java
index dcca493..3999f5b 100644
--- a/src/main/java/org/spigotmc/SpigotConfig.java
+++ b/src/main/java/org/spigotmc/SpigotConfig.java
@@ -149,4 +149,10 @@ public class SpigotConfig
config.addDefault( path, def );
return config.getDouble( path, config.getDouble( path ) );
}
+
+ public static boolean logCommands;
+ private static void logCommands()
+ {
+ logCommands = getBoolean( "commands.log", true );
+ }
}
--
2.5.0

View File

@ -1,53 +0,0 @@
From b4675b950f4c405e96367011a77fb16fda3cd5aa Mon Sep 17 00:00:00 2001
From: md_5 <md_5@live.com.au>
Date: Fri, 21 Jun 2013 18:05:54 +1000
Subject: [PATCH] Allow Disabling of Command TabComplete
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index f906f60..fa21527 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -1572,6 +1572,13 @@ public final class CraftServer implements Server {
}
public List<String> tabCompleteCommand(Player player, String message) {
+ // Spigot Start
+ if ( (org.spigotmc.SpigotConfig.tabComplete < 0 || message.length() <= org.spigotmc.SpigotConfig.tabComplete) && !message.contains( " " ) )
+ {
+ return ImmutableList.of();
+ }
+ // Spigot End
+
List<String> completions = null;
try {
completions = getCommandMap().tabComplete(player, message.substring(1));
diff --git a/src/main/java/org/spigotmc/SpigotConfig.java b/src/main/java/org/spigotmc/SpigotConfig.java
index 3999f5b..ca001e9 100644
--- a/src/main/java/org/spigotmc/SpigotConfig.java
+++ b/src/main/java/org/spigotmc/SpigotConfig.java
@@ -155,4 +155,21 @@ public class SpigotConfig
{
logCommands = getBoolean( "commands.log", true );
}
+
+ public static int tabComplete;
+ private static void tabComplete()
+ {
+ if ( version < 6 )
+ {
+ boolean oldValue = getBoolean( "commands.tab-complete", true );
+ if ( oldValue )
+ {
+ set( "commands.tab-complete", 0 );
+ } else
+ {
+ set( "commands.tab-complete", -1 );
+ }
+ }
+ tabComplete = getInt( "commands.tab-complete", 0 );
+ }
}
--
2.5.0

View File

@ -1,107 +0,0 @@
From 0988b9fd0a9e454f00ff512887f0030433d98cc9 Mon Sep 17 00:00:00 2001
From: md_5 <md_5@live.com.au>
Date: Fri, 21 Jun 2013 19:21:58 +1000
Subject: [PATCH] Configurable Messages
diff --git a/src/main/java/net/minecraft/server/HandshakeListener.java b/src/main/java/net/minecraft/server/HandshakeListener.java
index 37c13c5..ee987b9 100644
--- a/src/main/java/net/minecraft/server/HandshakeListener.java
+++ b/src/main/java/net/minecraft/server/HandshakeListener.java
@@ -62,11 +62,11 @@ public class HandshakeListener implements PacketHandshakingInListener {
// CraftBukkit end
if (packethandshakinginsetprotocol.b() > 107) {
- chatcomponenttext = new ChatComponentText("Outdated server! I\'m still on 1.9");
+ chatcomponenttext = new ChatComponentText( java.text.MessageFormat.format( org.spigotmc.SpigotConfig.outdatedServerMessage.replaceAll("'", "''"), "1.9" ) ); // Spigot
this.b.sendPacket(new PacketLoginOutDisconnect(chatcomponenttext));
this.b.close(chatcomponenttext);
} else if (packethandshakinginsetprotocol.b() < 107) {
- chatcomponenttext = new ChatComponentText("Outdated client! Please use 1.9");
+ chatcomponenttext = new ChatComponentText( java.text.MessageFormat.format( org.spigotmc.SpigotConfig.outdatedClientMessage.replaceAll("'", "''"), "1.9" ) ); // Spigot
this.b.sendPacket(new PacketLoginOutDisconnect(chatcomponenttext));
this.b.close(chatcomponenttext);
} else {
diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/java/net/minecraft/server/PlayerList.java
index 2095242..b21a5b7 100644
--- a/src/main/java/net/minecraft/server/PlayerList.java
+++ b/src/main/java/net/minecraft/server/PlayerList.java
@@ -466,7 +466,7 @@ public abstract class PlayerList {
event.disallow(PlayerLoginEvent.Result.KICK_BANNED, s);
} else if (!this.isWhitelisted(gameprofile)) {
// return "You are not white-listed on this server!";
- event.disallow(PlayerLoginEvent.Result.KICK_WHITELIST, "You are not white-listed on this server!");
+ event.disallow(PlayerLoginEvent.Result.KICK_WHITELIST, org.spigotmc.SpigotConfig.whitelistMessage); // Spigot
} else if (getIPBans().isBanned(socketaddress) && !getIPBans().get(socketaddress).hasExpired()) {
IpBanEntry ipbanentry = this.l.get(socketaddress);
@@ -480,7 +480,7 @@ public abstract class PlayerList {
} else {
// return this.players.size() >= this.maxPlayers && !this.f(gameprofile) ? "The server is full!" : null;
if (this.players.size() >= this.maxPlayers && !this.f(gameprofile)) {
- event.disallow(PlayerLoginEvent.Result.KICK_FULL, "The server is full");
+ event.disallow(PlayerLoginEvent.Result.KICK_FULL, org.spigotmc.SpigotConfig.serverFullMessage); // Spigot
}
}
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index fa21527..7cdba38 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -627,11 +627,7 @@ public final class CraftServer implements Server {
return true;
}
- if (sender instanceof Player) {
- sender.sendMessage("Unknown command. Type \"/help\" for help.");
- } else {
- sender.sendMessage("Unknown command. Type \"help\" for help.");
- }
+ sender.sendMessage(org.spigotmc.SpigotConfig.unknownCommandMessage);
return false;
}
diff --git a/src/main/java/org/spigotmc/SpigotConfig.java b/src/main/java/org/spigotmc/SpigotConfig.java
index ca001e9..3726ea5 100644
--- a/src/main/java/org/spigotmc/SpigotConfig.java
+++ b/src/main/java/org/spigotmc/SpigotConfig.java
@@ -12,6 +12,7 @@ import java.util.Map;
import java.util.logging.Level;
import net.minecraft.server.MinecraftServer;
import org.bukkit.Bukkit;
+import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.YamlConfiguration;
@@ -172,4 +173,28 @@ public class SpigotConfig
}
tabComplete = getInt( "commands.tab-complete", 0 );
}
+
+ public static String whitelistMessage;
+ public static String unknownCommandMessage;
+ public static String serverFullMessage;
+ public static String outdatedClientMessage = "Outdated client! Please use {0}";
+ public static String outdatedServerMessage = "Outdated server! I\'m still on {0}";
+ private static String transform(String s)
+ {
+ return ChatColor.translateAlternateColorCodes( '&', s ).replaceAll( "\\n", "\n" );
+ }
+ private static void messages()
+ {
+ if (version < 8)
+ {
+ set( "messages.outdated-client", outdatedClientMessage );
+ set( "messages.outdated-server", outdatedServerMessage );
+ }
+
+ whitelistMessage = transform( getString( "messages.whitelist", "You are not whitelisted on this server!" ) );
+ unknownCommandMessage = transform( getString( "messages.unknown-command", "Unknown command. Type \"/help\" for help." ) );
+ serverFullMessage = transform( getString( "messages.server-full", "The server is full!" ) );
+ outdatedClientMessage = transform( getString( "messages.outdated-client", outdatedClientMessage ) );
+ outdatedServerMessage = transform( getString( "messages.outdated-server", outdatedServerMessage ) );
+ }
}
--
2.5.0

View File

@ -1,51 +0,0 @@
From 71cd35a1527593f3c82c7461ce9552af19e3018a Mon Sep 17 00:00:00 2001
From: md_5 <md_5@live.com.au>
Date: Sat, 22 Jun 2013 16:12:02 +1000
Subject: [PATCH] Allow Disabling of Random Lighting Updates
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
index e4725b0..20b945c 100644
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -967,7 +967,7 @@ public class Chunk {
}
this.q = true;
- if (!this.lit && this.done) {
+ if (!this.lit && this.done && this.world.spigotConfig.randomLightUpdates) { // Spigot - also use random light updates setting to determine if we should relight
this.o();
}
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
index ca04f24..ffbb05d 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java
@@ -374,7 +374,7 @@ public class WorldServer extends World implements IAsyncTaskHandler {
protected void i() {
this.methodProfiler.a("playerCheckLight");
- if (!this.players.isEmpty()) {
+ if (spigotConfig.randomLightUpdates && !this.players.isEmpty()) { // Spigot
int i = this.random.nextInt(this.players.size());
EntityHuman entityhuman = (EntityHuman) this.players.get(i);
int j = MathHelper.floor(entityhuman.locX) + this.random.nextInt(11) - 5;
diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java
index 4de0a98..c2452d6 100644
--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java
+++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java
@@ -177,4 +177,11 @@ public class SpigotWorldConfig
hopperAmount = getInt( "hopper-amount", 1 );
log( "Hopper Transfer: " + hopperTransfer + " Hopper Check: " + hopperCheck + " Hopper Amount: " + hopperAmount );
}
+
+ public boolean randomLightUpdates;
+ private void lightUpdates()
+ {
+ randomLightUpdates = getBoolean( "random-light-updates", false );
+ log( "Random Lighting Updates: " + randomLightUpdates );
+ }
}
--
2.5.0

View File

@ -1,52 +0,0 @@
From 2dd0071691dbc596290019977fa9665463e7870b Mon Sep 17 00:00:00 2001
From: md_5 <md_5@live.com.au>
Date: Thu, 27 Jun 2013 17:26:09 +1000
Subject: [PATCH] Properly Close Inventories
Properly close inventories when unloading and switching worlds.
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
index 20b945c..f68abb4 100644
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -761,6 +761,18 @@ public class Chunk {
while (iterator.hasNext()) {
TileEntity tileentity = (TileEntity) iterator.next();
+ // Spigot Start
+ if ( tileentity instanceof IInventory )
+ {
+ for ( org.bukkit.entity.HumanEntity h : Lists.<org.bukkit.entity.HumanEntity>newArrayList((List<org.bukkit.entity.HumanEntity>) ( (IInventory) tileentity ).getViewers() ) )
+ {
+ if ( h instanceof org.bukkit.craftbukkit.entity.CraftHumanEntity )
+ {
+ ( (org.bukkit.craftbukkit.entity.CraftHumanEntity) h).getHandle().closeInventory();
+ }
+ }
+ }
+ // Spigot End
this.world.b(tileentity);
}
@@ -771,6 +783,18 @@ public class Chunk {
java.util.Iterator<Entity> iter = newList.iterator();
while (iter.hasNext()) {
Entity entity = iter.next();
+ // Spigot Start
+ if ( entity instanceof IInventory )
+ {
+ for ( org.bukkit.entity.HumanEntity h : Lists.<org.bukkit.entity.HumanEntity>newArrayList( (List<org.bukkit.entity.HumanEntity>) ( (IInventory) entity ).getViewers() ) )
+ {
+ if ( h instanceof org.bukkit.craftbukkit.entity.CraftHumanEntity )
+ {
+ ( (org.bukkit.craftbukkit.entity.CraftHumanEntity) h).getHandle().closeInventory();
+ }
+ }
+ }
+ // Spigot End
// Do not pass along players, as doing so can get them stuck outside of time.
// (which for example disables inventory icon updates and prevents block breaking)
--
2.5.0

View File

@ -1,27 +0,0 @@
From 4a1495e9ec2458f8e2d62580d5fdc501fa00226f Mon Sep 17 00:00:00 2001
From: md_5 <md_5@live.com.au>
Date: Fri, 28 Jun 2013 19:52:54 +1000
Subject: [PATCH] Disallow Interaction With Self
diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java
index 7d98d67..61bde4e 100644
--- a/src/main/java/net/minecraft/server/PlayerConnection.java
+++ b/src/main/java/net/minecraft/server/PlayerConnection.java
@@ -1445,6 +1445,13 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable {
if (this.player.dead) return; // CraftBukkit
WorldServer worldserver = this.minecraftServer.getWorldServer(this.player.dimension);
Entity entity = packetplayinuseentity.a((World) worldserver);
+ // Spigot Start
+ if ( entity == player && !player.isSpectator() )
+ {
+ disconnect( "Cannot interact with self!" );
+ return;
+ }
+ // Spigot End
this.player.resetIdleTimer();
if (entity != null) {
--
2.5.0

View File

@ -1,35 +0,0 @@
From 10154dcc951a95851fbbcf02976a9fc6eca2643b Mon Sep 17 00:00:00 2001
From: md_5 <git@md-5.net>
Date: Sat, 27 Feb 2016 10:07:58 +1100
Subject: [PATCH] Entity Mount and Dismount Events
diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
index 280ceb8..1104a04 100644
--- a/src/main/java/net/minecraft/server/Entity.java
+++ b/src/main/java/net/minecraft/server/Entity.java
@@ -1681,6 +1681,13 @@ public abstract class Entity implements ICommandListener {
}
}
// CraftBukkit end
+ // Spigot start
+ org.spigotmc.event.entity.EntityMountEvent event = new org.spigotmc.event.entity.EntityMountEvent(entity.getBukkitEntity(), this.getBukkitEntity());
+ Bukkit.getPluginManager().callEvent(event);
+ if (event.isCancelled()) {
+ return;
+ }
+ // Spigot end
if (!this.world.isClientSide && entity instanceof EntityHuman && !(this.bt() instanceof EntityHuman)) {
this.passengers.add(0, entity);
} else {
@@ -1710,6 +1717,7 @@ public abstract class Entity implements ICommandListener {
}
}
// CraftBukkit end
+ Bukkit.getPluginManager().callEvent( new org.spigotmc.event.entity.EntityDismountEvent(entity.getBukkitEntity(), this.getBukkitEntity())); // Spigot
this.passengers.remove(entity);
entity.j = 60;
}
--
2.5.0

View File

@ -1,26 +0,0 @@
From 01836118052d7480962601f48cb275e7e512f223 Mon Sep 17 00:00:00 2001
From: Alex Ciuba <alexciuba@gmail.com>
Date: Tue, 11 Jun 2013 15:23:03 -0400
Subject: [PATCH] Prevent Ghost Players Caused by Plugins
Check if the player is still connected after firing event. Fixes BUKKIT-4327
diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/java/net/minecraft/server/PlayerList.java
index e10e80d..0f56aee 100644
--- a/src/main/java/net/minecraft/server/PlayerList.java
+++ b/src/main/java/net/minecraft/server/PlayerList.java
@@ -606,6 +606,11 @@ public abstract class PlayerList {
Player respawnPlayer = cserver.getPlayer(entityplayer1);
PlayerRespawnEvent respawnEvent = new PlayerRespawnEvent(respawnPlayer, location, isBedSpawn);
cserver.getPluginManager().callEvent(respawnEvent);
+ // Spigot Start
+ if (entityplayer.playerConnection.isDisconnected()) {
+ return entityplayer;
+ }
+ // Spigot End
location = respawnEvent.getRespawnLocation();
entityplayer.reset();
--
2.5.0

View File

@ -1,22 +0,0 @@
From 63ae188a51ad00dc2f9530ae65fa062e1332271e Mon Sep 17 00:00:00 2001
From: md_5 <md_5@live.com.au>
Date: Sat, 3 Aug 2013 19:02:59 +1000
Subject: [PATCH] Plug World Unload Memory Leak
diff --git a/src/main/java/net/minecraft/server/BlockRedstoneTorch.java b/src/main/java/net/minecraft/server/BlockRedstoneTorch.java
index c6c0ab2..b4d1741 100644
--- a/src/main/java/net/minecraft/server/BlockRedstoneTorch.java
+++ b/src/main/java/net/minecraft/server/BlockRedstoneTorch.java
@@ -10,7 +10,7 @@ import org.bukkit.event.block.BlockRedstoneEvent; // CraftBukkit
public class BlockRedstoneTorch extends BlockTorch {
- private static Map<World, List<BlockRedstoneTorch.RedstoneUpdateInfo>> g = Maps.newHashMap();
+ private static Map<World, List<BlockRedstoneTorch.RedstoneUpdateInfo>> g = new java.util.WeakHashMap(); // Spigot
private final boolean isOn;
private boolean a(World world, BlockPosition blockposition, boolean flag) {
--
2.5.0

View File

@ -1,92 +0,0 @@
From 5cb4c77361fa3df82d795a16680348b0b7a0b10d Mon Sep 17 00:00:00 2001
From: md_5 <md_5@live.com.au>
Date: Sat, 3 Aug 2013 19:27:07 +1000
Subject: [PATCH] Player Collision API
diff --git a/src/main/java/net/minecraft/server/EntityHuman.java b/src/main/java/net/minecraft/server/EntityHuman.java
index 74bf367..45c4ef3 100644
--- a/src/main/java/net/minecraft/server/EntityHuman.java
+++ b/src/main/java/net/minecraft/server/EntityHuman.java
@@ -377,6 +377,7 @@ public abstract class EntityHuman extends EntityLiving {
List list = this.world.getEntities(this, axisalignedbb);
+ if (this.isCollidable()) { // Spigot: Add isCollidable() condition (second !this.isDead near bottom of EntityLiving)
for (int i = 0; i < list.size(); ++i) {
Entity entity = (Entity) list.get(i);
@@ -384,6 +385,7 @@ public abstract class EntityHuman extends EntityLiving {
this.c(entity);
}
}
+ } // Spigot
}
}
diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java
index 6fabefa..0cf1b90 100644
--- a/src/main/java/net/minecraft/server/EntityLiving.java
+++ b/src/main/java/net/minecraft/server/EntityLiving.java
@@ -1974,7 +1974,7 @@ public abstract class EntityLiving extends Entity {
protected void cn() {
List list = this.world.a((Entity) this, this.getBoundingBox(), IEntitySelector.a(this));
- if (!list.isEmpty()) {
+ if (this.isInteractable() && !list.isEmpty()) { // Spigot: Add isInteractable() condition
for (int i = 0; i < list.size(); ++i) {
Entity entity = (Entity) list.get(i);
// TODO better check now?
diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java
index 4e34d45..688b359 100644
--- a/src/main/java/net/minecraft/server/EntityPlayer.java
+++ b/src/main/java/net/minecraft/server/EntityPlayer.java
@@ -65,6 +65,21 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
public double maxHealthCache;
public boolean joining = true;
// CraftBukkit end
+ // Spigot start
+ public boolean collidesWithEntities = true;
+
+ @Override
+ public boolean isInteractable()
+ {
+ return this.collidesWithEntities && super.isInteractable(); // (first !this.isDead near bottom of EntityLiving)
+ }
+
+ @Override
+ public boolean isCollidable()
+ {
+ return this.collidesWithEntities && super.isCollidable(); // (second !this.isDead near bottom of EntityLiving)
+ }
+ // Spigot end
public EntityPlayer(MinecraftServer minecraftserver, WorldServer worldserver, GameProfile gameprofile, PlayerInteractManager playerinteractmanager) {
super(worldserver, gameprofile);
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
index e93cedb..cdabd78 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -1407,6 +1407,19 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
// Spigot start
private final Player.Spigot spigot = new Player.Spigot()
{
+
+ @Override
+ public boolean getCollidesWithEntities()
+ {
+ return getHandle().collidesWithEntities;
+ }
+
+ @Override
+ public void setCollidesWithEntities(boolean collides)
+ {
+ getHandle().collidesWithEntities = collides;
+ getHandle().i = collides; // First boolean of Entity
+ }
};
public Player.Spigot spigot()
--
2.5.0

View File

@ -1,27 +0,0 @@
From fb58dd6254e350724b17e19abd41c951c684fb41 Mon Sep 17 00:00:00 2001
From: agentk20 <agentkid20@gmail.com>
Date: Sat, 3 Aug 2013 19:28:48 +1000
Subject: [PATCH] Fully Disable Snooper When Not Required
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index d754d0d..28c3a72 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -662,11 +662,11 @@ public abstract class MinecraftServer implements Runnable, ICommandListener, IAs
this.h[this.ticks % 100] = System.nanoTime() - i;
this.methodProfiler.b();
this.methodProfiler.a("snooper");
- if (!this.m.d() && this.ticks > 100) {
+ if (getSnooperEnabled() && !this.m.d() && this.ticks > 100) { // Spigot
this.m.a();
}
- if (this.ticks % 6000 == 0) {
+ if (getSnooperEnabled() && this.ticks % 6000 == 0) { // Spigot
this.m.b();
}
--
2.5.0

View File

@ -1,25 +0,0 @@
From acfe9bfa8054fcc76549ec2c963fdf7ccdfbea77 Mon Sep 17 00:00:00 2001
From: DerFlash <bte@freenet.de>
Date: Sat, 3 Aug 2013 19:53:48 +1000
Subject: [PATCH] Add Getter for Entity Invulnerability
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
index cc88297..0fc57de 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
@@ -567,6 +567,11 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
// Spigot start
private final Spigot spigot = new Spigot()
{
+ @Override
+ public boolean isInvulnerable()
+ {
+ return getHandle().isInvulnerable(net.minecraft.server.DamageSource.GENERIC);
+ }
};
public Spigot spigot()
--
2.5.0

View File

@ -1,31 +0,0 @@
From b07dbc551cf636d98d6d7d99a0fa371f57b614ef Mon Sep 17 00:00:00 2001
From: md_5 <md_5@live.com.au>
Date: Mon, 5 Aug 2013 20:17:20 +1000
Subject: [PATCH] Cap Minimum Player Speed
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
index eea3951..f7e6c07 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -1175,7 +1175,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
public void setFlySpeed(float value) {
validateSpeed(value);
EntityPlayer player = getHandle();
- player.abilities.flySpeed = value / 2f;
+ player.abilities.flySpeed = Math.max( value, 0.0001f ) / 2f; // Spigot
player.updateAbilities();
}
@@ -1184,7 +1184,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
public void setWalkSpeed(float value) {
validateSpeed(value);
EntityPlayer player = getHandle();
- player.abilities.walkSpeed = value / 2f;
+ player.abilities.walkSpeed = Math.max( value, 0.0001f ) / 2f; // Spigot
player.updateAbilities();
}
--
2.5.0

View File

@ -1,26 +0,0 @@
From c345c700f58a271f1638e3a683c8c28c287be1f4 Mon Sep 17 00:00:00 2001
From: BlackHole <black-hole@live.com>
Date: Tue, 16 Jul 2013 22:34:50 +0200
Subject: [PATCH] Call EntityChangeBlockEvent for Fire Arrows hitting TNT
Adds BUKKIT-4355
diff --git a/src/main/java/net/minecraft/server/BlockTNT.java b/src/main/java/net/minecraft/server/BlockTNT.java
index 54140f7..f794167 100644
--- a/src/main/java/net/minecraft/server/BlockTNT.java
+++ b/src/main/java/net/minecraft/server/BlockTNT.java
@@ -73,6 +73,11 @@ public class BlockTNT extends Block {
EntityArrow entityarrow = (EntityArrow) entity;
if (entityarrow.isBurning()) {
+ // CraftBukkit start
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(entityarrow, blockposition.getX(), blockposition.getY(), blockposition.getZ(), Blocks.AIR, 0).isCancelled()) {
+ return;
+ }
+ // CraftBukkit end
this.a(world, blockposition, world.getType(blockposition).set(BlockTNT.EXPLODE, Boolean.valueOf(true)), entityarrow.shooter instanceof EntityLiving ? (EntityLiving) entityarrow.shooter : null);
world.setAir(blockposition);
}
--
2.5.0

View File

@ -1,49 +0,0 @@
From 338d1a0473ae949f6236f6eee08a016391f8d976 Mon Sep 17 00:00:00 2001
From: md_5 <md_5@live.com.au>
Date: Sat, 21 Sep 2013 12:33:09 +1000
Subject: [PATCH] Allow Disabling of 1.6.3 Structure Saving
diff --git a/src/main/java/net/minecraft/server/StructureGenerator.java b/src/main/java/net/minecraft/server/StructureGenerator.java
index dacba33..4a4d2af 100644
--- a/src/main/java/net/minecraft/server/StructureGenerator.java
+++ b/src/main/java/net/minecraft/server/StructureGenerator.java
@@ -197,7 +197,13 @@ public abstract class StructureGenerator extends WorldGenBase {
protected void a(World world) {
if (this.a == null) {
- this.a = (PersistentStructure) world.a(PersistentStructure.class, this.a());
+ // Spigot Start
+ if (world.spigotConfig.saveStructureInfo) {
+ this.a = (PersistentStructure) world.a(PersistentStructure.class, this.a());
+ } else {
+ this.a = new PersistentStructure(this.a());
+ }
+ // Spigot End
if (this.a == null) {
this.a = new PersistentStructure(this.a());
world.a(this.a(), (PersistentBase) this.a);
diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java
index c2452d6..89f9bc3 100644
--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java
+++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java
@@ -184,4 +184,16 @@ public class SpigotWorldConfig
randomLightUpdates = getBoolean( "random-light-updates", false );
log( "Random Lighting Updates: " + randomLightUpdates );
}
+
+ public boolean saveStructureInfo;
+ private void structureInfo()
+ {
+ saveStructureInfo = getBoolean( "save-structure-info", true );
+ log( "Structure Info Saving: " + saveStructureInfo );
+ if ( !saveStructureInfo )
+ {
+ log( "*** WARNING *** You have selected to NOT save structure info. This may cause structures such as fortresses to not spawn mobs!" );
+ log( "*** WARNING *** Please use this option with caution, SpigotMC is not responsible for any issues this option may cause in the future!" );
+ }
+ }
}
--
2.5.0

View File

@ -1,49 +0,0 @@
From 5a0bea3e4562f09095e7b46f6787aa903f52d3a6 Mon Sep 17 00:00:00 2001
From: md_5 <md_5@live.com.au>
Date: Sun, 6 Oct 2013 17:36:28 +1100
Subject: [PATCH] Don't Special Case X Move Value
diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java
index 61bde4e..24c2a88 100644
--- a/src/main/java/net/minecraft/server/PlayerConnection.java
+++ b/src/main/java/net/minecraft/server/PlayerConnection.java
@@ -126,6 +126,7 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable {
private float lastPitch = Float.MAX_VALUE;
private float lastYaw = Float.MAX_VALUE;
private boolean justTeleported = false;
+ private boolean hasMoved; // Spigot
public CraftPlayer getPlayer() {
return (this.player == null) ? null : (CraftPlayer) this.player.getBukkitEntity();
@@ -353,6 +354,18 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable {
// CraftBukkit start - fire PlayerMoveEvent
Player player = this.getPlayer();
+ // Spigot Start
+ if ( !hasMoved )
+ {
+ Location curPos = player.getLocation();
+ lastPosX = curPos.getX();
+ lastPosY = curPos.getY();
+ lastPosZ = curPos.getZ();
+ lastYaw = curPos.getYaw();
+ lastPitch = curPos.getPitch();
+ hasMoved = true;
+ }
+ // Spigot End
Location from = new Location(player.getWorld(), lastPosX, lastPosY, lastPosZ, lastYaw, lastPitch); // Get the Players previous Event location.
Location to = player.getLocation().clone(); // Start off the To location as the Players current location.
@@ -378,7 +391,7 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable {
this.lastPitch = to.getPitch();
// Skip the first time we do this
- if (from.getX() != Double.MAX_VALUE) {
+ if (true) { // Spigot - don't skip any move events
Location oldTo = to.clone();
PlayerMoveEvent event = new PlayerMoveEvent(player, from, to);
this.server.getPluginManager().callEvent(event);
--
2.5.0

View File

@ -1,29 +0,0 @@
From ece598b449d1a8fe3073de1e90068246dd1cbf75 Mon Sep 17 00:00:00 2001
From: ninja- <xninja@openmailbox.org>
Date: Tue, 8 Oct 2013 14:34:49 +0200
Subject: [PATCH] Implement respawn API.
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
index f7e6c07..d245755 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -1420,6 +1420,15 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
getHandle().collidesWithEntities = collides;
getHandle().i = collides; // First boolean of Entity
}
+
+ @Override
+ public void respawn()
+ {
+ if ( getHealth() <= 0 && isOnline() )
+ {
+ server.getServer().getPlayerList().moveToWorld( getHandle(), 0, false );
+ }
+ }
};
public Player.Spigot spigot()
--
2.5.0

View File

@ -1,38 +0,0 @@
From a812d6abf9d591b6f9681f6e31af6bd8e176bafb Mon Sep 17 00:00:00 2001
From: md_5 <md_5@live.com.au>
Date: Mon, 14 Oct 2013 19:20:10 +1100
Subject: [PATCH] Arrow Despawn Rate
diff --git a/src/main/java/net/minecraft/server/EntityArrow.java b/src/main/java/net/minecraft/server/EntityArrow.java
index a40f3ec..e40642f 100644
--- a/src/main/java/net/minecraft/server/EntityArrow.java
+++ b/src/main/java/net/minecraft/server/EntityArrow.java
@@ -144,7 +144,7 @@ public abstract class EntityArrow extends Entity implements IProjectile {
if (block == this.au && i == this.av) {
++this.aw;
- if (this.aw >= 1200) {
+ if (this.aw >= world.spigotConfig.arrowDespawnRate) { // Spigot - First int after shooter
this.die();
}
} else {
diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java
index 89f9bc3..28643c5 100644
--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java
+++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java
@@ -196,4 +196,11 @@ public class SpigotWorldConfig
log( "*** WARNING *** Please use this option with caution, SpigotMC is not responsible for any issues this option may cause in the future!" );
}
}
+
+ public int arrowDespawnRate;
+ private void arrowDespawnRate()
+ {
+ arrowDespawnRate = getInt( "arrow-despawn-rate", 1200 );
+ log( "Arrow Despawn Rate: " + arrowDespawnRate );
+ }
}
--
2.5.0

View File

@ -1,334 +0,0 @@
From 4301af27dac931f8831bf87c1c285c0b7237a5d3 Mon Sep 17 00:00:00 2001
From: md_5 <md_5@live.com.au>
Date: Tue, 5 Aug 2014 17:20:19 +0100
Subject: [PATCH] Watchdog Thread.
diff --git a/src/main/java/net/minecraft/server/DedicatedServer.java b/src/main/java/net/minecraft/server/DedicatedServer.java
index 1361b06..e5c0ed9 100644
--- a/src/main/java/net/minecraft/server/DedicatedServer.java
+++ b/src/main/java/net/minecraft/server/DedicatedServer.java
@@ -276,7 +276,7 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer
}
// CraftBukkit end
- if (this.aP() > 0L) {
+ if (false && this.aP() > 0L) { // Spigot - disable
Thread thread1 = new Thread(new ThreadWatchdog(this));
thread1.setName("Server Watchdog");
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 28c3a72..bc9ac2b 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -568,6 +568,7 @@ public abstract class MinecraftServer implements Runnable, ICommandListener, IAs
this.a(crashreport);
} finally {
try {
+ org.spigotmc.WatchdogThread.doStop();
this.isStopped = true;
this.stop();
} catch (Throwable throwable1) {
@@ -672,6 +673,7 @@ public abstract class MinecraftServer implements Runnable, ICommandListener, IAs
this.methodProfiler.b();
this.methodProfiler.b();
+ org.spigotmc.WatchdogThread.tick(); // Spigot
SpigotTimings.serverTickTimer.stopTiming(); // Spigot
org.spigotmc.CustomTimingsHandler.tick(); // Spigot
}
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index 7cdba38..72e1e2f 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -1696,6 +1696,11 @@ public final class CraftServer implements Server {
{
return org.spigotmc.SpigotConfig.config;
}
+
+ @Override
+ public void restart() {
+ org.spigotmc.RestartCommand.restart();
+ }
};
public Spigot spigot()
diff --git a/src/main/java/org/spigotmc/RestartCommand.java b/src/main/java/org/spigotmc/RestartCommand.java
new file mode 100644
index 0000000..429c258
--- /dev/null
+++ b/src/main/java/org/spigotmc/RestartCommand.java
@@ -0,0 +1,124 @@
+package org.spigotmc;
+
+import java.io.File;
+import java.util.List;
+import net.minecraft.server.EntityPlayer;
+import net.minecraft.server.MinecraftServer;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandSender;
+
+public class RestartCommand extends Command
+{
+
+ public RestartCommand(String name)
+ {
+ super( name );
+ this.description = "Restarts the server";
+ this.usageMessage = "/restart";
+ this.setPermission( "bukkit.command.restart" );
+ }
+
+ @Override
+ public boolean execute(CommandSender sender, String currentAlias, String[] args)
+ {
+ if ( testPermission( sender ) )
+ {
+ MinecraftServer.getServer().processQueue.add( new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ restart();
+ }
+ } );
+ }
+ return true;
+ }
+
+ public static void restart()
+ {
+ restart( new File( SpigotConfig.restartScript ) );
+ }
+
+ public static void restart(final File script)
+ {
+ AsyncCatcher.enabled = false; // Disable async catcher incase it interferes with us
+ try
+ {
+ if ( script.isFile() )
+ {
+ System.out.println( "Attempting to restart with " + SpigotConfig.restartScript );
+
+ // Disable Watchdog
+ WatchdogThread.doStop();
+
+ // Kick all players
+ for ( EntityPlayer p : (List< EntityPlayer>) MinecraftServer.getServer().getPlayerList().players )
+ {
+ p.playerConnection.disconnect(SpigotConfig.restartMessage);
+ }
+ // Give the socket a chance to send the packets
+ try
+ {
+ Thread.sleep( 100 );
+ } catch ( InterruptedException ex )
+ {
+ }
+ // Close the socket so we can rebind with the new process
+ MinecraftServer.getServer().getServerConnection().b();
+
+ // Give time for it to kick in
+ try
+ {
+ Thread.sleep( 100 );
+ } catch ( InterruptedException ex )
+ {
+ }
+
+ // Actually shutdown
+ try
+ {
+ MinecraftServer.getServer().stop();
+ } catch ( Throwable t )
+ {
+ }
+
+ // This will be done AFTER the server has completely halted
+ Thread shutdownHook = new Thread()
+ {
+ @Override
+ public void run()
+ {
+ try
+ {
+ String os = System.getProperty( "os.name" ).toLowerCase();
+ if ( os.contains( "win" ) )
+ {
+ Runtime.getRuntime().exec( "cmd /c start " + script.getPath() );
+ } else
+ {
+ Runtime.getRuntime().exec( new String[]
+ {
+ "sh", script.getPath()
+ } );
+ }
+ } catch ( Exception e )
+ {
+ e.printStackTrace();
+ }
+ }
+ };
+
+ shutdownHook.setDaemon( true );
+ Runtime.getRuntime().addShutdownHook( shutdownHook );
+ } else
+ {
+ System.out.println( "Startup script '" + SpigotConfig.restartScript + "' does not exist! Stopping server." );
+ }
+ System.exit( 0 );
+ } catch ( Exception ex )
+ {
+ ex.printStackTrace();
+ }
+ }
+}
diff --git a/src/main/java/org/spigotmc/SpigotConfig.java b/src/main/java/org/spigotmc/SpigotConfig.java
index 3726ea5..34def7b 100644
--- a/src/main/java/org/spigotmc/SpigotConfig.java
+++ b/src/main/java/org/spigotmc/SpigotConfig.java
@@ -197,4 +197,18 @@ public class SpigotConfig
outdatedClientMessage = transform( getString( "messages.outdated-client", outdatedClientMessage ) );
outdatedServerMessage = transform( getString( "messages.outdated-server", outdatedServerMessage ) );
}
+
+ public static int timeoutTime = 60;
+ public static boolean restartOnCrash = true;
+ public static String restartScript = "./start.sh";
+ public static String restartMessage;
+ private static void watchdog()
+ {
+ timeoutTime = getInt( "settings.timeout-time", timeoutTime );
+ restartOnCrash = getBoolean( "settings.restart-on-crash", restartOnCrash );
+ restartScript = getString( "settings.restart-script", restartScript );
+ restartMessage = transform( getString( "messages.restart", "Server is restarting" ) );
+ commands.put( "restart", new RestartCommand( "restart" ) );
+ WatchdogThread.doStart( timeoutTime, restartOnCrash );
+ }
}
diff --git a/src/main/java/org/spigotmc/WatchdogThread.java b/src/main/java/org/spigotmc/WatchdogThread.java
new file mode 100644
index 0000000..de08ad6
--- /dev/null
+++ b/src/main/java/org/spigotmc/WatchdogThread.java
@@ -0,0 +1,117 @@
+package org.spigotmc;
+
+import java.lang.management.ManagementFactory;
+import java.lang.management.MonitorInfo;
+import java.lang.management.ThreadInfo;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import net.minecraft.server.MinecraftServer;
+import org.bukkit.Bukkit;
+
+public class WatchdogThread extends Thread
+{
+
+ private static WatchdogThread instance;
+ private final long timeoutTime;
+ private final boolean restart;
+ private volatile long lastTick;
+ private volatile boolean stopping;
+
+ private WatchdogThread(long timeoutTime, boolean restart)
+ {
+ super( "Spigot Watchdog Thread" );
+ this.timeoutTime = timeoutTime;
+ this.restart = restart;
+ }
+
+ public static void doStart(int timeoutTime, boolean restart)
+ {
+ if ( instance == null )
+ {
+ instance = new WatchdogThread( timeoutTime * 1000L, restart );
+ instance.start();
+ }
+ }
+
+ public static void tick()
+ {
+ instance.lastTick = System.currentTimeMillis();
+ }
+
+ public static void doStop()
+ {
+ if ( instance != null )
+ {
+ instance.stopping = true;
+ }
+ }
+
+ @Override
+ public void run()
+ {
+ while ( !stopping )
+ {
+ //
+ if ( lastTick != 0 && System.currentTimeMillis() > lastTick + timeoutTime )
+ {
+ Logger log = Bukkit.getServer().getLogger();
+ log.log( Level.SEVERE, "The server has stopped responding!" );
+ log.log( Level.SEVERE, "Please report this to http://www.spigotmc.org/" );
+ log.log( Level.SEVERE, "Be sure to include ALL relevant console errors and Minecraft crash reports" );
+ log.log( Level.SEVERE, "Spigot version: " + Bukkit.getServer().getVersion() );
+ //
+ log.log( Level.SEVERE, "------------------------------" );
+ log.log( Level.SEVERE, "Server thread dump (Look for plugins here before reporting to Spigot!):" );
+ dumpThread( ManagementFactory.getThreadMXBean().getThreadInfo( MinecraftServer.getServer().primaryThread.getId(), Integer.MAX_VALUE ), log );
+ log.log( Level.SEVERE, "------------------------------" );
+ //
+ log.log( Level.SEVERE, "Entire Thread Dump:" );
+ ThreadInfo[] threads = ManagementFactory.getThreadMXBean().dumpAllThreads( true, true );
+ for ( ThreadInfo thread : threads )
+ {
+ dumpThread( thread, log );
+ }
+ log.log( Level.SEVERE, "------------------------------" );
+
+ if ( restart )
+ {
+ RestartCommand.restart();
+ }
+ break;
+ }
+
+ try
+ {
+ sleep( 10000 );
+ } catch ( InterruptedException ex )
+ {
+ interrupt();
+ }
+ }
+ }
+
+ private static void dumpThread(ThreadInfo thread, Logger log)
+ {
+ log.log( Level.SEVERE, "------------------------------" );
+ //
+ log.log( Level.SEVERE, "Current Thread: " + thread.getThreadName() );
+ log.log( Level.SEVERE, "\tPID: " + thread.getThreadId()
+ + " | Suspended: " + thread.isSuspended()
+ + " | Native: " + thread.isInNative()
+ + " | State: " + thread.getThreadState() );
+ if ( thread.getLockedMonitors().length != 0 )
+ {
+ log.log( Level.SEVERE, "\tThread is waiting on monitor(s):" );
+ for ( MonitorInfo monitor : thread.getLockedMonitors() )
+ {
+ log.log( Level.SEVERE, "\t\tLocked on:" + monitor.getLockedStackFrame() );
+ }
+ }
+ log.log( Level.SEVERE, "\tStack:" );
+ //
+ for ( StackTraceElement stack : thread.getStackTrace() )
+ {
+ log.log( Level.SEVERE, "\t\t" + stack );
+ }
+ }
+}
--
2.5.0

View File

@ -1,30 +0,0 @@
From a192d0fe60f91c9924690fc9a9566390b91c591c Mon Sep 17 00:00:00 2001
From: Thinkofdeath <thethinkofdeath@gmail.com>
Date: Mon, 2 Dec 2013 23:42:09 +0000
Subject: [PATCH] Fix some chunks not being sent to the client
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
index f68abb4..47ef0db 100644
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -1009,7 +1009,15 @@ public class Chunk {
}
public boolean isReady() {
- return this.q && this.done && this.lit;
+ // Spigot Start
+ /*
+ * As of 1.7, Mojang added a check to make sure that only chunks which have been lit are sent to the client.
+ * Unfortunately this interferes with our modified chunk ticking algorithm, which will only tick chunks distant from the player on a very infrequent basis.
+ * We cannot unfortunately do this lighting stage during chunk gen as it appears to put a lot more noticeable load on the server, than when it is done at play time.
+ * For now at least we will simply send all chunks, in accordance with pre 1.7 behaviour.
+ */
+ return true;
+ // Spigot End
}
public boolean j() {
--
2.5.0

View File

@ -1,39 +0,0 @@
From ae1236a4a4a148d9eb2e7be52b04eeef85ee54fc Mon Sep 17 00:00:00 2001
From: md_5 <md_5@live.com.au>
Date: Thu, 5 Dec 2013 13:55:53 +1100
Subject: [PATCH] Fix Broken Async Chat
diff --git a/src/main/java/net/minecraft/server/PacketPlayInChat.java b/src/main/java/net/minecraft/server/PacketPlayInChat.java
index 0ab90f3..18358b4 100644
--- a/src/main/java/net/minecraft/server/PacketPlayInChat.java
+++ b/src/main/java/net/minecraft/server/PacketPlayInChat.java
@@ -24,7 +24,24 @@ public class PacketPlayInChat implements Packet<PacketListenerPlayIn> {
packetdataserializer.a(this.a);
}
- public void a(PacketListenerPlayIn packetlistenerplayin) {
+ // Spigot Start
+ private static final java.util.concurrent.ExecutorService executors = java.util.concurrent.Executors.newCachedThreadPool(
+ new com.google.common.util.concurrent.ThreadFactoryBuilder().setDaemon( true ).setNameFormat( "Async Chat Thread - #%d" ).build() );
+ public void a(final PacketListenerPlayIn packetlistenerplayin) {
+ if ( !a.startsWith("/") )
+ {
+ executors.submit( new Runnable()
+ {
+
+ @Override
+ public void run()
+ {
+ packetlistenerplayin.a( PacketPlayInChat.this );
+ }
+ } );
+ return;
+ }
+ // Spigot End
packetlistenerplayin.a(this);
}
--
2.5.0

View File

@ -1,145 +0,0 @@
From 375f19d5b86d8c2498918195a67c992259ffa5f6 Mon Sep 17 00:00:00 2001
From: md_5 <git@md-5.net>
Date: Wed, 18 Dec 2013 13:32:10 +1100
Subject: [PATCH] Fire PreLogin Events in Offline Mode
diff --git a/src/main/java/net/minecraft/server/LoginListener.java b/src/main/java/net/minecraft/server/LoginListener.java
index 3cca9ff..71d24b2 100644
--- a/src/main/java/net/minecraft/server/LoginListener.java
+++ b/src/main/java/net/minecraft/server/LoginListener.java
@@ -13,6 +13,7 @@ import java.util.Arrays;
import java.util.Random;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger;
+import java.util.logging.Level;
import javax.crypto.SecretKey;
import org.apache.commons.lang3.Validate;
import org.apache.logging.log4j.LogManager;
@@ -80,10 +81,23 @@ public class LoginListener implements PacketLoginInListener, ITickable {
}
+ // Spigot start
+ public void initUUID()
+ {
+ UUID uuid = UUID.nameUUIDFromBytes( ( "OfflinePlayer:" + this.i.getName() ).getBytes( Charsets.UTF_8 ) );
+
+ this.i = new GameProfile( uuid, this.i.getName() );
+ }
+ // Spigot end
+
public void b() {
+ // Spigot start - Moved to initUUID
+ /*
if (!this.i.isComplete()) {
this.i = this.a(this.i);
}
+ */
+ // Spigot end
// CraftBukkit start - fire PlayerLoginEvent
EntityPlayer s = this.server.getPlayerList().attemptLogin(this, this.i, hostname);
@@ -133,7 +147,22 @@ public class LoginListener implements PacketLoginInListener, ITickable {
this.g = LoginListener.EnumProtocolState.KEY;
this.networkManager.sendPacket(new PacketLoginOutEncryptionBegin(this.j, this.server.O().getPublic(), this.e));
} else {
- this.g = LoginListener.EnumProtocolState.READY_TO_ACCEPT;
+ // Spigot start
+ new Thread("User Authenticator #" + LoginListener.b.incrementAndGet()) {
+
+ @Override
+ public void run() {
+ try {
+ initUUID();
+ new LoginHandler().fireEvents();
+ LoginListener.this.g = LoginListener.EnumProtocolState.READY_TO_ACCEPT;
+ } catch (Exception ex) {
+ disconnect("Failed to verify username!");
+ server.server.getLogger().log(java.util.logging.Level.WARNING, "Exception verifying " + i.getName(), ex);
+ }
+ }
+ }.start();
+ // Spigot end
}
}
@@ -162,6 +191,39 @@ public class LoginListener implements PacketLoginInListener, ITickable {
return;
}
+ new LoginHandler().fireEvents();
+ } else if (LoginListener.this.server.R()) {
+ LoginListener.c.warn("Failed to verify username but will let them in anyway!");
+ LoginListener.this.i = LoginListener.this.a(gameprofile);
+ LoginListener.this.g = LoginListener.EnumProtocolState.READY_TO_ACCEPT;
+ } else {
+ LoginListener.this.disconnect("Failed to verify username!");
+ LoginListener.c.error("Username \'" + gameprofile.getName() + "\' tried to join with an invalid session"); // CraftBukkit - fix null pointer
+ }
+ } catch (AuthenticationUnavailableException authenticationunavailableexception) {
+ if (LoginListener.this.server.R()) {
+ LoginListener.c.warn("Authentication servers are down but will let them in anyway!");
+ LoginListener.this.i = LoginListener.this.a(gameprofile);
+ LoginListener.this.g = LoginListener.EnumProtocolState.READY_TO_ACCEPT;
+ } else {
+ LoginListener.this.disconnect("Authentication servers are down. Please try again later, sorry!");
+ LoginListener.c.error("Couldn\'t verify username because servers are unavailable");
+ }
+ // CraftBukkit start - catch all exceptions
+ } catch (Exception exception) {
+ disconnect("Failed to verify username!");
+ server.server.getLogger().log(java.util.logging.Level.WARNING, "Exception verifying " + gameprofile.getName(), exception);
+ // CraftBukkit end
+ }
+ }
+ }).start();
+ }
+ }
+
+ // Spigot start
+ public class LoginHandler {
+
+ public void fireEvents() throws Exception {
String playerName = i.getName();
java.net.InetAddress address = ((java.net.InetSocketAddress) networkManager.getSocketAddress()).getAddress();
java.util.UUID uniqueId = i.getId();
@@ -196,34 +258,9 @@ public class LoginListener implements PacketLoginInListener, ITickable {
// CraftBukkit end
LoginListener.c.info("UUID of player " + LoginListener.this.i.getName() + " is " + LoginListener.this.i.getId());
LoginListener.this.g = LoginListener.EnumProtocolState.READY_TO_ACCEPT;
- } else if (LoginListener.this.server.R()) {
- LoginListener.c.warn("Failed to verify username but will let them in anyway!");
- LoginListener.this.i = LoginListener.this.a(gameprofile);
- LoginListener.this.g = LoginListener.EnumProtocolState.READY_TO_ACCEPT;
- } else {
- LoginListener.this.disconnect("Failed to verify username!");
- LoginListener.c.error("Username \'" + gameprofile.getName() + "\' tried to join with an invalid session"); // CraftBukkit - fix null pointer
- }
- } catch (AuthenticationUnavailableException authenticationunavailableexception) {
- if (LoginListener.this.server.R()) {
- LoginListener.c.warn("Authentication servers are down but will let them in anyway!");
- LoginListener.this.i = LoginListener.this.a(gameprofile);
- LoginListener.this.g = LoginListener.EnumProtocolState.READY_TO_ACCEPT;
- } else {
- LoginListener.this.disconnect("Authentication servers are down. Please try again later, sorry!");
- LoginListener.c.error("Couldn\'t verify username because servers are unavailable");
- }
- // CraftBukkit start - catch all exceptions
- } catch (Exception exception) {
- disconnect("Failed to verify username!");
- server.server.getLogger().log(java.util.logging.Level.WARNING, "Exception verifying " + gameprofile.getName(), exception);
- // CraftBukkit end
- }
-
}
- }).start();
}
- }
+ // Spigot end
protected GameProfile a(GameProfile gameprofile) {
UUID uuid = UUID.nameUUIDFromBytes(("OfflinePlayer:" + gameprofile.getName()).getBytes(Charsets.UTF_8));
--
2.5.0

View File

@ -1,189 +0,0 @@
From abc10e573e1f4f0c7d755ef8d96a1e4aa1381c17 Mon Sep 17 00:00:00 2001
From: md_5 <md_5@live.com.au>
Date: Sun, 1 Dec 2013 18:18:41 +1100
Subject: [PATCH] BungeeCord Support
Provides support for IP forwarding via BungeeCord.
diff --git a/src/main/java/net/minecraft/server/HandshakeListener.java b/src/main/java/net/minecraft/server/HandshakeListener.java
index ee987b9..ed20034 100644
--- a/src/main/java/net/minecraft/server/HandshakeListener.java
+++ b/src/main/java/net/minecraft/server/HandshakeListener.java
@@ -7,6 +7,7 @@ import java.util.HashMap;
public class HandshakeListener implements PacketHandshakingInListener {
+ private static final com.google.gson.Gson gson = new com.google.gson.Gson(); // Spigot
// CraftBukkit start - add fields
private static final HashMap<InetAddress, Long> throttleTracker = new HashMap<InetAddress, Long>();
private static int throttleCounter = 0;
@@ -71,6 +72,26 @@ public class HandshakeListener implements PacketHandshakingInListener {
this.b.close(chatcomponenttext);
} else {
this.b.setPacketListener(new LoginListener(this.a, this.b));
+ // Spigot Start
+ if (org.spigotmc.SpigotConfig.bungee) {
+ String[] split = packethandshakinginsetprotocol.hostname.split("\00");
+ if ( split.length == 3 || split.length == 4 ) {
+ packethandshakinginsetprotocol.hostname = split[0];
+ b.l = new java.net.InetSocketAddress(split[1], ((java.net.InetSocketAddress) b.getSocketAddress()).getPort());
+ b.spoofedUUID = com.mojang.util.UUIDTypeAdapter.fromString( split[2] );
+ } else
+ {
+ chatcomponenttext = new ChatComponentText("If you wish to use IP forwarding, please enable it in your BungeeCord config as well!");
+ this.b.sendPacket(new PacketLoginOutDisconnect(chatcomponenttext));
+ this.b.close(chatcomponenttext);
+ return;
+ }
+ if ( split.length == 4 )
+ {
+ b.spoofedProfile = gson.fromJson(split[3], com.mojang.authlib.properties.Property[].class);
+ }
+ }
+ // Spigot End
((LoginListener) this.b.i()).hostname = packethandshakinginsetprotocol.hostname + ":" + packethandshakinginsetprotocol.port; // CraftBukkit - set hostname
}
break;
diff --git a/src/main/java/net/minecraft/server/LoginListener.java b/src/main/java/net/minecraft/server/LoginListener.java
index 71d24b2..efa785f 100644
--- a/src/main/java/net/minecraft/server/LoginListener.java
+++ b/src/main/java/net/minecraft/server/LoginListener.java
@@ -84,9 +84,24 @@ public class LoginListener implements PacketLoginInListener, ITickable {
// Spigot start
public void initUUID()
{
- UUID uuid = UUID.nameUUIDFromBytes( ( "OfflinePlayer:" + this.i.getName() ).getBytes( Charsets.UTF_8 ) );
+ UUID uuid;
+ if ( networkManager.spoofedUUID != null )
+ {
+ uuid = networkManager.spoofedUUID;
+ } else
+ {
+ uuid = UUID.nameUUIDFromBytes( ( "OfflinePlayer:" + this.i.getName() ).getBytes( Charsets.UTF_8 ) );
+ }
this.i = new GameProfile( uuid, this.i.getName() );
+
+ if (networkManager.spoofedProfile != null)
+ {
+ for ( com.mojang.authlib.properties.Property property : networkManager.spoofedProfile )
+ {
+ this.i.getProperties().put( property.getName(), property );
+ }
+ }
}
// Spigot end
diff --git a/src/main/java/net/minecraft/server/NetworkManager.java b/src/main/java/net/minecraft/server/NetworkManager.java
index 5ed2c96..c3ff6c2 100644
--- a/src/main/java/net/minecraft/server/NetworkManager.java
+++ b/src/main/java/net/minecraft/server/NetworkManager.java
@@ -64,7 +64,11 @@ public class NetworkManager extends SimpleChannelInboundHandler<Packet<?>> {
private final Queue<NetworkManager.QueuedPacket> i = Queues.newConcurrentLinkedQueue();
private final ReentrantReadWriteLock j = new ReentrantReadWriteLock();
public Channel channel;
- private SocketAddress l;
+ // Spigot Start // PAIL
+ public SocketAddress l;
+ public java.util.UUID spoofedUUID;
+ public com.mojang.authlib.properties.Property[] spoofedProfile;
+ // Spigot End
private PacketListener m;
private IChatBaseComponent n;
private boolean o;
@@ -323,4 +327,11 @@ public class NetworkManager extends SimpleChannelInboundHandler<Packet<?>> {
this.b = agenericfuturelistener;
}
}
+
+ // Spigot Start
+ public SocketAddress getRawAddress()
+ {
+ return this.channel.remoteAddress();
+ }
+ // Spigot End
}
diff --git a/src/main/java/net/minecraft/server/PacketHandshakingInSetProtocol.java b/src/main/java/net/minecraft/server/PacketHandshakingInSetProtocol.java
index 86f1be7..e6ab607 100644
--- a/src/main/java/net/minecraft/server/PacketHandshakingInSetProtocol.java
+++ b/src/main/java/net/minecraft/server/PacketHandshakingInSetProtocol.java
@@ -13,7 +13,7 @@ public class PacketHandshakingInSetProtocol implements Packet<PacketHandshakingI
public void a(PacketDataSerializer packetdataserializer) throws IOException {
this.a = packetdataserializer.g();
- this.hostname = packetdataserializer.c(255);
+ this.hostname = packetdataserializer.c(Short.MAX_VALUE); // Spigot
this.port = packetdataserializer.readUnsignedShort();
this.d = EnumProtocol.a(packetdataserializer.g());
}
diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/java/net/minecraft/server/PlayerList.java
index f878dfc..eb9375d 100644
--- a/src/main/java/net/minecraft/server/PlayerList.java
+++ b/src/main/java/net/minecraft/server/PlayerList.java
@@ -451,7 +451,7 @@ public abstract class PlayerList {
EntityPlayer entity = new EntityPlayer(server, server.getWorldServer(0), gameprofile, new PlayerInteractManager(server.getWorldServer(0)));
Player player = entity.getBukkitEntity();
- PlayerLoginEvent event = new PlayerLoginEvent(player, hostname, ((java.net.InetSocketAddress) socketaddress).getAddress());
+ PlayerLoginEvent event = new PlayerLoginEvent(player, hostname, ((java.net.InetSocketAddress) socketaddress).getAddress(), ((java.net.InetSocketAddress) loginlistener.networkManager.getRawAddress()).getAddress());
String s;
if (getProfileBans().isBanned(gameprofile) && !getProfileBans().get(gameprofile).hasExpired()) {
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index 72e1e2f..1a5f14d 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -560,7 +560,13 @@ public final class CraftServer implements Server {
@Override
public long getConnectionThrottle() {
- return this.configuration.getInt("settings.connection-throttle");
+ // Spigot Start - Automatically set connection throttle for bungee configurations
+ if (org.spigotmc.SpigotConfig.bungee) {
+ return -1;
+ } else {
+ return this.configuration.getInt("settings.connection-throttle");
+ }
+ // Spigot End
}
@Override
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
index d245755..71d4ddc 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -1409,6 +1409,12 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
{
@Override
+ public InetSocketAddress getRawAddress()
+ {
+ return (InetSocketAddress) getHandle().playerConnection.networkManager.getRawAddress();
+ }
+
+ @Override
public boolean getCollidesWithEntities()
{
return getHandle().collidesWithEntities;
diff --git a/src/main/java/org/spigotmc/SpigotConfig.java b/src/main/java/org/spigotmc/SpigotConfig.java
index 34def7b..824ba7a 100644
--- a/src/main/java/org/spigotmc/SpigotConfig.java
+++ b/src/main/java/org/spigotmc/SpigotConfig.java
@@ -211,4 +211,14 @@ public class SpigotConfig
commands.put( "restart", new RestartCommand( "restart" ) );
WatchdogThread.doStart( timeoutTime, restartOnCrash );
}
+
+ public static boolean bungee;
+ private static void bungee() {
+ if ( version < 4 )
+ {
+ set( "settings.bungeecord", false );
+ System.out.println( "Oudated config, disabling BungeeCord support!" );
+ }
+ bungee = getBoolean( "settings.bungeecord", false );
+ }
}
--
2.5.0

View File

@ -1,39 +0,0 @@
From 06d44f0f810440e2070437a393ac31f36df863d9 Mon Sep 17 00:00:00 2001
From: Dylan Xaldin <Puremin0rez515@gmail.com>
Date: Thu, 12 Dec 2013 18:05:03 -0600
Subject: [PATCH] Allow Disabling Zombie Villager Aggression
Ability to configure if Zombies will be aggressive towards Villagers.
diff --git a/src/main/java/net/minecraft/server/EntityZombie.java b/src/main/java/net/minecraft/server/EntityZombie.java
index d5f508b..ba2f12f 100644
--- a/src/main/java/net/minecraft/server/EntityZombie.java
+++ b/src/main/java/net/minecraft/server/EntityZombie.java
@@ -46,7 +46,7 @@ public class EntityZombie extends EntityMonster {
this.goalSelector.a(6, new PathfinderGoalMoveThroughVillage(this, 1.0D, false));
this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this, true, new Class[] { EntityPigZombie.class}));
this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget(this, EntityHuman.class, true));
- this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget(this, EntityVillager.class, false));
+ if ( world.spigotConfig.zombieAggressiveTowardsVillager ) this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget(this, EntityVillager.class, false)); // Spigot
this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget(this, EntityIronGolem.class, true));
}
diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java
index 28643c5..6df2186 100644
--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java
+++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java
@@ -203,4 +203,11 @@ public class SpigotWorldConfig
arrowDespawnRate = getInt( "arrow-despawn-rate", 1200 );
log( "Arrow Despawn Rate: " + arrowDespawnRate );
}
+
+ public boolean zombieAggressiveTowardsVillager;
+ private void zombieAggressiveTowardsVillager()
+ {
+ zombieAggressiveTowardsVillager = getBoolean( "zombie-aggressive-towards-villager", true );
+ log( "Zombie Aggressive Towards Villager: " + zombieAggressiveTowardsVillager );
+ }
}
--
2.5.0

View File

@ -1,57 +0,0 @@
From edc862d79d59ff2cc77a068e722a11c3bfcd9abe Mon Sep 17 00:00:00 2001
From: md_5 <git@md-5.net>
Date: Fri, 13 Dec 2013 11:58:58 +1100
Subject: [PATCH] Configurable Amount of Netty Threads
This brings back the option that the Spigot version of netty saw. By default Netty will try and use cores*2 threads, however if running multiple servers on the same machine, this can be too many threads. Additionally some people have 16 core servers. If 32 Netty threads are allowed in this setup, then the lock contention, and thus blocking between threads becomes much greater, leading to decreased performance.
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index bc9ac2b..d616c4f 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -57,7 +57,7 @@ public abstract class MinecraftServer implements Runnable, ICommandListener, IAs
private final List<ITickable> o = Lists.newArrayList();
protected final ICommandHandler b;
public final MethodProfiler methodProfiler = new MethodProfiler();
- private final ServerConnection p;
+ private ServerConnection p; // Spigot
private final ServerPing q = new ServerPing();
private final Random r = new Random();
private final DataConverterManager dataConverterManager;
@@ -122,7 +122,7 @@ public abstract class MinecraftServer implements Runnable, ICommandListener, IAs
this.W = gameprofilerepository;
this.X = usercache;
// this.universe = file; // CraftBukkit
- this.p = new ServerConnection(this);
+ // this.p = new ServerConnection(this); // Spigot
this.b = this.i();
// this.convertable = new WorldLoaderServer(file); // CraftBukkit - moved to DedicatedServer.init
this.dataConverterManager = dataconvertermanager;
@@ -1303,7 +1303,7 @@ public abstract class MinecraftServer implements Runnable, ICommandListener, IAs
}
// Spigot End
public ServerConnection am() {
- return this.p;
+ return this.p == null ? this.p = new ServerConnection(this) : this.p; // Spigot
}
public boolean ao() {
diff --git a/src/main/java/org/spigotmc/SpigotConfig.java b/src/main/java/org/spigotmc/SpigotConfig.java
index 824ba7a..a306266 100644
--- a/src/main/java/org/spigotmc/SpigotConfig.java
+++ b/src/main/java/org/spigotmc/SpigotConfig.java
@@ -221,4 +221,11 @@ public class SpigotConfig
}
bungee = getBoolean( "settings.bungeecord", false );
}
+
+ private static void nettyThreads()
+ {
+ int count = getInt( "settings.netty-threads", 4 );
+ System.setProperty( "io.netty.eventLoopThreads", Integer.toString( count ) );
+ Bukkit.getLogger().log( Level.INFO, "Using {0} threads for Netty based IO", count );
+ }
}
--
2.5.0

View File

@ -1,22 +0,0 @@
From 27435da7261f44e7b09a250d0f30068eb7d7ea37 Mon Sep 17 00:00:00 2001
From: md_5 <git@md-5.net>
Date: Fri, 13 Dec 2013 15:21:02 +1100
Subject: [PATCH] Prevent Mineshaft Saving
diff --git a/src/main/java/net/minecraft/server/StructureGenerator.java b/src/main/java/net/minecraft/server/StructureGenerator.java
index 4a4d2af..22d96e9 100644
--- a/src/main/java/net/minecraft/server/StructureGenerator.java
+++ b/src/main/java/net/minecraft/server/StructureGenerator.java
@@ -198,7 +198,7 @@ public abstract class StructureGenerator extends WorldGenBase {
protected void a(World world) {
if (this.a == null) {
// Spigot Start
- if (world.spigotConfig.saveStructureInfo) {
+ if (world.spigotConfig.saveStructureInfo && !this.a().equals( "Mineshaft" )) {
this.a = (PersistentStructure) world.a(PersistentStructure.class, this.a());
} else {
this.a = new PersistentStructure(this.a());
--
2.5.0

View File

@ -1,26 +0,0 @@
From 9aa16093b9bdf922f4ac04d87c5eaeb9e5fa377a Mon Sep 17 00:00:00 2001
From: md_5 <git@md-5.net>
Date: Wed, 18 Dec 2013 13:39:14 +1100
Subject: [PATCH] Log Cause of Unexpected Exceptions
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index d616c4f..05a63cb 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -549,6 +549,12 @@ public abstract class MinecraftServer implements Runnable, ICommandListener, IAs
}
} catch (Throwable throwable) {
MinecraftServer.LOGGER.error("Encountered an unexpected exception", throwable);
+ // Spigot Start
+ if ( throwable.getCause() != null )
+ {
+ MinecraftServer.LOGGER.error( "\tCause of unexpected exception was", throwable.getCause() );
+ }
+ // Spigot End
CrashReport crashreport = null;
if (throwable instanceof ReportedException) {
--
2.5.0

View File

@ -1,215 +0,0 @@
From f7d1c59ee398f6740c96349acd5b41723c29c6a0 Mon Sep 17 00:00:00 2001
From: Thinkofdeath <thethinkofdeath@gmail.com>
Date: Fri, 20 Dec 2013 21:36:06 +0000
Subject: [PATCH] Particle API
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftEffect.java b/src/main/java/org/bukkit/craftbukkit/CraftEffect.java
index 7de0de5..13f9e9d 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftEffect.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftEffect.java
@@ -55,6 +55,9 @@ public class CraftEffect {
Validate.isTrue(((Material) data).isBlock(), "Material is not a block!");
datavalue = ((Material) data).getId();
break;
+ case ITEM_BREAK:
+ datavalue = ((Material) data).getId();
+ break;
default:
datavalue = 0;
}
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index d132f1a..8f2ec20 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -864,28 +864,18 @@ public class CraftWorld implements World {
Validate.isTrue(effect.getData() == null, "Wrong kind of data for this effect!");
}
- int datavalue = data == null ? 0 : CraftEffect.getDataValue(effect, data);
- playEffect(loc, effect, datavalue, radius);
+ if (data != null && data.getClass().equals( org.bukkit.material.MaterialData.class )) {
+ org.bukkit.material.MaterialData materialData = (org.bukkit.material.MaterialData) data;
+ Validate.isTrue( materialData.getItemType().isBlock(), "Material must be block" );
+ spigot().playEffect( loc, effect, materialData.getItemType().getId(), materialData.getData(), 0, 0, 0, 1, 1, radius );
+ } else {
+ int dataValue = data == null ? 0 : CraftEffect.getDataValue( effect, data );
+ playEffect( loc, effect, dataValue, radius );
+ }
}
public void playEffect(Location location, Effect effect, int data, int radius) {
- Validate.notNull(location, "Location cannot be null");
- Validate.notNull(effect, "Effect cannot be null");
- Validate.notNull(location.getWorld(), "World cannot be null");
- int packetData = effect.getId();
- PacketPlayOutWorldEvent packet = new PacketPlayOutWorldEvent(packetData, new BlockPosition(location.getBlockX(), location.getBlockY(), location.getBlockZ()), data, false);
- int distance;
- radius *= radius;
-
- for (Player player : getPlayers()) {
- if (((CraftPlayer) player).getHandle().playerConnection == null) continue;
- if (!location.getWorld().equals(player.getWorld())) continue;
-
- distance = (int) player.getLocation().distanceSquared(location);
- if (distance <= radius) {
- ((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet);
- }
- }
+ spigot().playEffect( location, effect, data, 0, 0, 0, 0, 1, 1, radius );
}
public <T extends Entity> T spawn(Location location, Class<T> clazz) throws IllegalArgumentException {
@@ -1516,6 +1506,70 @@ public class CraftWorld implements World {
// Spigot start
private final Spigot spigot = new Spigot()
{
+ @Override
+ public void playEffect( Location location, Effect effect, int id, int data, float offsetX, float offsetY, float offsetZ, float speed, int particleCount, int radius )
+ {
+ Validate.notNull( location, "Location cannot be null" );
+ Validate.notNull( effect, "Effect cannot be null" );
+ Validate.notNull( location.getWorld(), "World cannot be null" );
+ Packet packet;
+ if ( effect.getType() != Effect.Type.PARTICLE )
+ {
+ int packetData = effect.getId();
+ packet = new PacketPlayOutWorldEvent( packetData, new BlockPosition(location.getBlockX(), location.getBlockY(), location.getBlockZ() ), id, false );
+ } else
+ {
+ net.minecraft.server.EnumParticle particle = null;
+ int[] extra = null;
+ for ( net.minecraft.server.EnumParticle p : net.minecraft.server.EnumParticle.values() )
+ {
+ if ( effect.getName().startsWith( p.b().replace("_", "") ) )
+ {
+ particle = p;
+ if ( effect.getData() != null )
+ {
+ if ( effect.getData().equals( org.bukkit.Material.class ) )
+ {
+ extra = new int[]{ id };
+ } else
+ {
+ extra = new int[]{ (data << 12) | (id & 0xFFF) };
+ }
+ }
+ break;
+ }
+ }
+ if ( extra == null )
+ {
+ extra = new int[0];
+ }
+ packet = new PacketPlayOutWorldParticles( particle, true, (float) location.getX(), (float) location.getY(), (float) location.getZ(), offsetX, offsetY, offsetZ, speed, particleCount, extra );
+ }
+ int distance;
+ radius *= radius;
+ for ( Player player : getPlayers() )
+ {
+ if ( ( (CraftPlayer) player ).getHandle().playerConnection == null )
+ {
+ continue;
+ }
+ if ( !location.getWorld().equals( player.getWorld() ) )
+ {
+ continue;
+ }
+ distance = (int) player.getLocation().distanceSquared( location );
+ if ( distance <= radius )
+ {
+ ( (CraftPlayer) player ).getHandle().playerConnection.sendPacket( packet );
+ }
+ }
+ }
+
+ @Override
+ public void playEffect( Location location, Effect effect )
+ {
+ CraftWorld.this.playEffect( location, effect, 0 );
+ }
};
public Spigot spigot()
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
index a90de6a..9ef1fc4 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -315,9 +315,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
public void playEffect(Location loc, Effect effect, int data) {
if (getHandle().playerConnection == null) return;
- int packetData = effect.getId();
- PacketPlayOutWorldEvent packet = new PacketPlayOutWorldEvent(packetData, new BlockPosition(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()), data, false);
- getHandle().playerConnection.sendPacket(packet);
+ spigot().playEffect(loc, effect, data, 0, 0, 0, 0, 1, 1, 64); // Spigot
}
@Override
@@ -1435,6 +1433,63 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
server.getServer().getPlayerList().moveToWorld( getHandle(), 0, false );
}
}
+
+ @Override
+ public void playEffect( Location location, Effect effect, int id, int data, float offsetX, float offsetY, float offsetZ, float speed, int particleCount, int radius )
+ {
+ Validate.notNull( location, "Location cannot be null" );
+ Validate.notNull( effect, "Effect cannot be null" );
+ Validate.notNull( location.getWorld(), "World cannot be null" );
+ Packet packet;
+ if ( effect.getType() != Effect.Type.PARTICLE )
+ {
+ int packetData = effect.getId();
+ packet = new PacketPlayOutWorldEvent( packetData, new BlockPosition(location.getBlockX(), location.getBlockY(), location.getBlockZ() ), id, false );
+ } else
+ {
+ net.minecraft.server.EnumParticle particle = null;
+ int[] extra = null;
+ for ( net.minecraft.server.EnumParticle p : net.minecraft.server.EnumParticle.values() )
+ {
+ if ( effect.getName().startsWith( p.b().replace("_", "") ) )
+ {
+ particle = p;
+ if ( effect.getData() != null )
+ {
+ if ( effect.getData().equals( org.bukkit.Material.class ) )
+ {
+ extra = new int[]{ id };
+ } else
+ {
+ extra = new int[]{ (data << 12) | (id & 0xFFF) };
+ }
+ }
+ break;
+ }
+ }
+ if ( extra == null )
+ {
+ extra = new int[0];
+ }
+ packet = new PacketPlayOutWorldParticles( particle, true, (float) location.getX(), (float) location.getY(), (float) location.getZ(), offsetX, offsetY, offsetZ, speed, particleCount, extra );
+ }
+ int distance;
+ radius *= radius;
+ if ( getHandle().playerConnection == null )
+ {
+ return;
+ }
+ if ( !location.getWorld().equals( getWorld() ) )
+ {
+ return;
+ }
+
+ distance = (int) getLocation().distanceSquared( location );
+ if ( distance <= radius )
+ {
+ getHandle().playerConnection.sendPacket( packet );
+ }
+ }
};
public Player.Spigot spigot()
--
2.5.0

View File

@ -1,30 +0,0 @@
From 3226bf418d193d5aaa5075792cba7291f0d00350 Mon Sep 17 00:00:00 2001
From: DerFlash <bte@freenet.de>
Date: Tue, 9 Jul 2013 00:11:12 +0200
Subject: [PATCH] Save ticks lived to nbttag
diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
index 1eec160..5955732 100644
--- a/src/main/java/net/minecraft/server/Entity.java
+++ b/src/main/java/net/minecraft/server/Entity.java
@@ -1292,6 +1292,7 @@ public abstract class Entity implements ICommandListener {
nbttagcompound.setLong("WorldUUIDLeast", this.world.getDataManager().getUUID().getLeastSignificantBits());
nbttagcompound.setLong("WorldUUIDMost", this.world.getDataManager().getUUID().getMostSignificantBits());
nbttagcompound.setInt("Bukkit.updateLevel", CURRENT_LEVEL);
+ nbttagcompound.setInt("Spigot.ticksLived", this.ticksLived);
// CraftBukkit end
if (this.getCustomName() != null && !this.getCustomName().isEmpty()) {
nbttagcompound.setString("CustomName", this.getCustomName());
@@ -1428,6 +1429,8 @@ public abstract class Entity implements ICommandListener {
if (this instanceof EntityLiving) {
EntityLiving entity = (EntityLiving) this;
+ this.ticksLived = nbttagcompound.getInt("Spigot.ticksLived");
+
// Reset the persistence for tamed animals
if (entity instanceof EntityTameableAnimal && !isLevelAtLeast(nbttagcompound, 2) && !nbttagcompound.getBoolean("PersistenceRequired")) {
EntityInsentient entityinsentient = (EntityInsentient) entity;
--
2.5.0

View File

@ -1,72 +0,0 @@
From 2a39802f8d846864a587def7c0d3cf2e3da8449a Mon Sep 17 00:00:00 2001
From: md_5 <git@md-5.net>
Date: Sun, 2 Feb 2014 16:55:46 +0000
Subject: [PATCH] Add Option to Nerf Mobs from Spawner's
diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
index 1045aa2..f1d7dc5 100644
--- a/src/main/java/net/minecraft/server/Entity.java
+++ b/src/main/java/net/minecraft/server/Entity.java
@@ -145,6 +145,7 @@ public abstract class Entity implements ICommandListener {
public final byte activationType = org.spigotmc.ActivationRange.initializeEntityActivationType(this);
public final boolean defaultActivationState;
public long activatedTick = Integer.MIN_VALUE;
+ public boolean fromMobSpawner;
public void inactiveTick() { }
// Spigot end
diff --git a/src/main/java/net/minecraft/server/EntityInsentient.java b/src/main/java/net/minecraft/server/EntityInsentient.java
index 8351aa5..16444b6 100644
--- a/src/main/java/net/minecraft/server/EntityInsentient.java
+++ b/src/main/java/net/minecraft/server/EntityInsentient.java
@@ -619,6 +619,12 @@ public abstract class EntityInsentient extends EntityLiving {
this.world.methodProfiler.a("checkDespawn");
this.L();
this.world.methodProfiler.b();
+ // Spigot Start
+ if ( this.fromMobSpawner )
+ {
+ return;
+ }
+ // Spigot End
this.world.methodProfiler.a("sensing");
this.bu.a();
this.world.methodProfiler.b();
diff --git a/src/main/java/net/minecraft/server/MobSpawnerAbstract.java b/src/main/java/net/minecraft/server/MobSpawnerAbstract.java
index 01cbd71..efe792b 100644
--- a/src/main/java/net/minecraft/server/MobSpawnerAbstract.java
+++ b/src/main/java/net/minecraft/server/MobSpawnerAbstract.java
@@ -94,7 +94,12 @@ public abstract class MobSpawnerAbstract {
if (this.spawnData.b().d() == 1 && this.spawnData.b().hasKeyOfType("id", 8) && entity instanceof EntityInsentient) {
((EntityInsentient) entity).prepare(world.D(new BlockPosition(entity)), (GroupDataEntity) null);
}
-
+ // Spigot Start
+ if ( entity.world.spigotConfig.nerfSpawnerMobs )
+ {
+ entity.fromMobSpawner = true;
+ }
+ // Spigot End
ChunkRegionLoader.a(entity, world, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER); // CraftBukkit
world.triggerEffect(2004, blockposition, 0);
if (entityinsentient != null) {
diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java
index 6df2186..3854195 100644
--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java
+++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java
@@ -210,4 +210,11 @@ public class SpigotWorldConfig
zombieAggressiveTowardsVillager = getBoolean( "zombie-aggressive-towards-villager", true );
log( "Zombie Aggressive Towards Villager: " + zombieAggressiveTowardsVillager );
}
+
+ public boolean nerfSpawnerMobs;
+ private void nerfSpawnerMobs()
+ {
+ nerfSpawnerMobs = getBoolean( "nerf-spawner-mobs", false );
+ log( "Nerfing mobs spawned from spawners: " + nerfSpawnerMobs );
+ }
}
--
2.5.0

View File

@ -1,36 +0,0 @@
From d4f504fab98a9308994aabf88621723d5fdc6651 Mon Sep 17 00:00:00 2001
From: md_5 <git@md-5.net>
Date: Mon, 23 Dec 2013 14:07:41 +1100
Subject: [PATCH] Warn if PermGen may be insufficient
diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java
index aca0d97..337aa29 100644
--- a/src/main/java/org/bukkit/craftbukkit/Main.java
+++ b/src/main/java/org/bukkit/craftbukkit/Main.java
@@ -173,6 +173,22 @@ public class Main {
useConsole = false;
}
+ // Spigot Start
+ int maxPermGen = 0; // In kb
+ for ( String s : java.lang.management.ManagementFactory.getRuntimeMXBean().getInputArguments() )
+ {
+ if ( s.startsWith( "-XX:MaxPermSize" ) )
+ {
+ maxPermGen = Integer.parseInt( s.replaceAll( "[^\\d]", "" ) );
+ maxPermGen <<= 10 * ("kmg".indexOf( Character.toLowerCase( s.charAt( s.length() - 1 ) ) ) );
+ }
+ }
+ if ( Float.parseFloat( System.getProperty( "java.class.version" ) ) < 52 && maxPermGen < ( 128 << 10 ) ) // 128mb
+ {
+ System.out.println( "Warning, your max perm gen size is not set or less than 128mb. It is recommended you restart Java with the following argument: -XX:MaxPermSize=128M" );
+ System.out.println( "Please see http://www.spigotmc.org/wiki/changing-permgen-size/ for more details and more in-depth instructions." );
+ }
+ // Spigot End
System.out.println("Loading libraries, please wait...");
MinecraftServer.main(options);
} catch (Throwable t) {
--
2.5.0

View File

@ -1,22 +0,0 @@
From 20018eca9a63874370634de3f0550b33be542448 Mon Sep 17 00:00:00 2001
From: md_5 <git@md-5.net>
Date: Mon, 23 Dec 2013 15:57:57 +1100
Subject: [PATCH] Disable Connected Check on setScoreboard
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
index e3ecd4d..28fc6e6 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -1234,7 +1234,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
throw new IllegalStateException("Cannot set scoreboard yet");
}
if (playerConnection.isDisconnected()) {
- throw new IllegalStateException("Cannot set scoreboard for invalid CraftPlayer");
+ // throw new IllegalStateException("Cannot set scoreboard for invalid CraftPlayer"); // Spigot - remove this as Mojang's semi asynchronous Netty implementation can lead to races
}
this.server.getScoreboardManager().setPlayerBoard(this, scoreboard);
--
2.5.0

View File

@ -1,62 +0,0 @@
From 7aeea7d6a4332b15cc56691df077db4d28303407 Mon Sep 17 00:00:00 2001
From: slide23 <me@slide.ws>
Date: Fri, 20 Dec 2013 20:15:33 -0600
Subject: [PATCH] Add Late Bind Option
Add late-bind config option to delay binding until loading is done.
diff --git a/src/main/java/net/minecraft/server/DedicatedServer.java b/src/main/java/net/minecraft/server/DedicatedServer.java
index e5c0ed9..d6a01a9 100644
--- a/src/main/java/net/minecraft/server/DedicatedServer.java
+++ b/src/main/java/net/minecraft/server/DedicatedServer.java
@@ -176,6 +176,7 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer
this.a(MinecraftEncryption.b());
DedicatedServer.LOGGER.info("Starting Minecraft server on " + (this.getServerIp().isEmpty() ? "*" : this.getServerIp()) + ":" + this.P());
+ if (!org.spigotmc.SpigotConfig.lateBind) {
try {
this.am().a(inetaddress, this.P());
} catch (IOException ioexception) {
@@ -184,6 +185,7 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer
DedicatedServer.LOGGER.warn("Perhaps a server is already running on that port?");
return false;
}
+ }
// Spigot Start - Move DedicatedPlayerList up and bring plugin loading from CraftServer to here
// this.a((PlayerList) (new DedicatedPlayerList(this))); // CraftBukkit
@@ -276,6 +278,17 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer
}
// CraftBukkit end
+ if (org.spigotmc.SpigotConfig.lateBind) {
+ try {
+ this.am().a(inetaddress, this.P());
+ } catch (IOException ioexception) {
+ DedicatedServer.LOGGER.warn("**** FAILED TO BIND TO PORT!");
+ DedicatedServer.LOGGER.warn("The exception was: {}", new Object[] { ioexception.toString()});
+ DedicatedServer.LOGGER.warn("Perhaps a server is already running on that port?");
+ return false;
+ }
+ }
+
if (false && this.aP() > 0L) { // Spigot - disable
Thread thread1 = new Thread(new ThreadWatchdog(this));
diff --git a/src/main/java/org/spigotmc/SpigotConfig.java b/src/main/java/org/spigotmc/SpigotConfig.java
index a306266..4edc6af 100644
--- a/src/main/java/org/spigotmc/SpigotConfig.java
+++ b/src/main/java/org/spigotmc/SpigotConfig.java
@@ -228,4 +228,9 @@ public class SpigotConfig
System.setProperty( "io.netty.eventLoopThreads", Integer.toString( count ) );
Bukkit.getLogger().log( Level.INFO, "Using {0} threads for Netty based IO", count );
}
+
+ public static boolean lateBind;
+ private static void lateBind() {
+ lateBind = getBoolean( "settings.late-bind", false );
+ }
}
--
2.5.0

View File

@ -1,93 +0,0 @@
From 20ba002dde049a8fad1402b4e976e38304e4018e Mon Sep 17 00:00:00 2001
From: Thinkofdeath <thethinkofdeath@gmail.com>
Date: Tue, 7 Jan 2014 15:56:26 +0000
Subject: [PATCH] Allow statistics to be disabled/forced
diff --git a/src/main/java/net/minecraft/server/ServerStatisticManager.java b/src/main/java/net/minecraft/server/ServerStatisticManager.java
index 76bd9c1..a08eb77 100644
--- a/src/main/java/net/minecraft/server/ServerStatisticManager.java
+++ b/src/main/java/net/minecraft/server/ServerStatisticManager.java
@@ -31,6 +31,14 @@ public class ServerStatisticManager extends StatisticManager {
public ServerStatisticManager(MinecraftServer minecraftserver, File file) {
this.c = minecraftserver;
this.d = file;
+ // Spigot start
+ for ( String name : org.spigotmc.SpigotConfig.forcedStats.keySet() )
+ {
+ StatisticWrapper wrapper = new StatisticWrapper();
+ wrapper.a( org.spigotmc.SpigotConfig.forcedStats.get( name ) );
+ a.put( StatisticList.getStatistic( name ), wrapper );
+ }
+ // Spigot end
}
public void a() {
@@ -48,6 +56,7 @@ public class ServerStatisticManager extends StatisticManager {
}
public void b() {
+ if ( org.spigotmc.SpigotConfig.disableStatSaving ) return; // Spigot
try {
FileUtils.writeStringToFile(this.d, a(this.a));
} catch (IOException ioexception) {
@@ -57,6 +66,7 @@ public class ServerStatisticManager extends StatisticManager {
}
public void setStatistic(EntityHuman entityhuman, Statistic statistic, int i) {
+ if ( org.spigotmc.SpigotConfig.disableStatSaving ) return; // Spigot
int j = statistic.d() ? this.getStatisticValue(statistic) : 0;
super.setStatistic(entityhuman, statistic, i);
diff --git a/src/main/java/org/spigotmc/SpigotConfig.java b/src/main/java/org/spigotmc/SpigotConfig.java
index 4edc6af..a2be9df 100644
--- a/src/main/java/org/spigotmc/SpigotConfig.java
+++ b/src/main/java/org/spigotmc/SpigotConfig.java
@@ -10,10 +10,12 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
+import gnu.trove.map.hash.TObjectIntHashMap;
import net.minecraft.server.MinecraftServer;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
+import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.YamlConfiguration;
@@ -233,4 +235,31 @@ public class SpigotConfig
private static void lateBind() {
lateBind = getBoolean( "settings.late-bind", false );
}
+
+ public static boolean disableStatSaving;
+ public static TObjectIntHashMap<String> forcedStats = new TObjectIntHashMap<String>();
+ private static void stats()
+ {
+ disableStatSaving = getBoolean( "stats.disable-saving", false );
+
+ if ( !config.contains( "stats.forced-stats" ) ) {
+ config.createSection( "stats.forced-stats" );
+ }
+
+ ConfigurationSection section = config.getConfigurationSection( "stats.forced-stats" );
+ for ( String name : section.getKeys( true ) )
+ {
+ if ( section.isInt( name ) )
+ {
+ forcedStats.put( name, section.getInt( name ) );
+ }
+ }
+
+ if ( disableStatSaving && section.getInt( "achievement.openInventory", 0 ) < 1 )
+ {
+ Bukkit.getLogger().warning( "*** WARNING *** stats.disable-saving is true but stats.forced-stats.achievement.openInventory" +
+ " isn't set to 1. Disabling stat saving without forcing the achievement may cause it to get stuck on the player's " +
+ "screen." );
+ }
+ }
}
--
2.5.0

View File

@ -1,28 +0,0 @@
From 61c54a8a1c06464bdb8bd07b5a0936157ab39813 Mon Sep 17 00:00:00 2001
From: md_5 <git@md-5.net>
Date: Fri, 10 Jan 2014 15:15:50 +1100
Subject: [PATCH] Fix ItemStack Unbreakable Code
diff --git a/src/main/java/net/minecraft/server/ItemStack.java b/src/main/java/net/minecraft/server/ItemStack.java
index 782ca57..4a43208 100644
--- a/src/main/java/net/minecraft/server/ItemStack.java
+++ b/src/main/java/net/minecraft/server/ItemStack.java
@@ -286,7 +286,13 @@ public final class ItemStack {
}
public boolean e() {
- return this.item == null ? false : (this.item.getMaxDurability() <= 0 ? false : !this.hasTag() || !this.getTag().getBoolean("Unbreakable"));
+ // Spigot Start
+ if ( this.item.getMaxDurability() <= 0 )
+ {
+ return false;
+ }
+ return ( !hasTag() ) || ( !getTag().getBoolean( "Unbreakable" ) );
+ // Spigot End
}
public boolean usesData() {
--
2.5.0

View File

@ -1,41 +0,0 @@
From 91ccf3dfcb0fe90e0fdd2392b0f6951f8bee8f1a Mon Sep 17 00:00:00 2001
From: md_5 <git@md-5.net>
Date: Sun, 12 Jan 2014 20:56:41 +1100
Subject: [PATCH] Try and Debug Crash Reports Crashing
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 05a63cb..dfe3305 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -748,7 +748,13 @@ public abstract class MinecraftServer implements Runnable, ICommandListener, IAs
worldserver.doTick();
worldserver.timings.doTick.stopTiming(); // Spigot
} catch (Throwable throwable) {
+ // Spigot Start
+ try {
crashreport = CrashReport.a(throwable, "Exception ticking world");
+ } catch (Throwable t){
+ throw new RuntimeException("Error generating crash report", t);
+ }
+ // Spigot End
worldserver.a(crashreport);
throw new ReportedException(crashreport);
}
@@ -758,7 +764,13 @@ public abstract class MinecraftServer implements Runnable, ICommandListener, IAs
worldserver.tickEntities();
worldserver.timings.tickEntities.stopTiming(); // Spigot
} catch (Throwable throwable1) {
+ // Spigot Start
+ try {
crashreport = CrashReport.a(throwable1, "Exception ticking world entities");
+ } catch (Throwable t){
+ throw new RuntimeException("Error generating crash report", t);
+ }
+ // Spigot End
worldserver.a(crashreport);
throw new ReportedException(crashreport);
}
--
2.5.0

View File

@ -1,87 +0,0 @@
From 5cf8af27e4ce431e97368d6443355adb429c059f Mon Sep 17 00:00:00 2001
From: md_5 <git@md-5.net>
Date: Sun, 12 Jan 2014 21:07:18 +1100
Subject: [PATCH] Improve AutoSave Mechanism
The problem here is that MinecraftServer.save(..), will attempt to sleep whilst all pending chunks are written to disk.
however due to various and complicated bugs, it will wait for an incorrect amount of chunks, which may cause it to sleep for an overly long amount of time.
Instead we will mimic the save-all command in its behaviour, which is both safe and performant.
Also, only save modified chunks, or chunks with entities after 4 auto save passes
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
index a7006b8..a4bf29a 100644
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -875,7 +875,7 @@ public class Chunk {
if (this.s && this.world.getTime() != this.lastSaved || this.r) {
return true;
}
- } else if (this.s && this.world.getTime() >= this.lastSaved + 600L) {
+ } else if (this.s && this.world.getTime() >= this.lastSaved + MinecraftServer.getServer().autosavePeriod * 4) { // Spigot - Only save if we've passed 2 auto save intervals without modification
return true;
}
diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java
index 162613b..83857a6 100644
--- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
+++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java
@@ -263,7 +263,7 @@ public class ChunkProviderServer implements IChunkProvider {
this.saveChunk(chunk);
chunk.f(false);
++i;
- if (i == 24 && !flag) {
+ if (i == 24 && !flag && false) { // Spigot
return false;
}
}
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index dfe3305..bd2837c 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -660,7 +660,17 @@ public abstract class MinecraftServer implements Runnable, ICommandListener, IAs
SpigotTimings.worldSaveTimer.startTiming(); // Spigot
this.methodProfiler.a("save");
this.v.savePlayers();
- this.saveChunks(true);
+ // Spigot Start
+ // We replace this with saving each individual world as this.saveChunks(...) is broken,
+ // and causes the main thread to sleep for random amounts of time depending on chunk activity
+ // Also pass flag to only save modified chunks
+ server.playerCommandState = true;
+ for (World world : worlds) {
+ world.getWorld().save(false);
+ }
+ server.playerCommandState = false;
+ // this.saveChunks(true);
+ // Spigot End
this.methodProfiler.b();
SpigotTimings.worldSaveTimer.stopTiming(); // Spigot
}
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index 8f2ec20..bb0268e 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -768,12 +768,17 @@ public class CraftWorld implements World {
}
public void save() {
+ // Spigot start
+ save(true);
+ }
+ public void save(boolean forceSave) {
+ // Spigot end
this.server.checkSaveState();
try {
boolean oldSave = world.savingDisabled;
world.savingDisabled = false;
- world.save(true, null);
+ world.save(forceSave, null); // Spigot
world.savingDisabled = oldSave;
} catch (ExceptionWorldConflict ex) {
--
2.5.0

View File

@ -1,33 +0,0 @@
From 9ac4a3b1609dd19bb6f8b14f37172207bf9ec6c0 Mon Sep 17 00:00:00 2001
From: md_5 <git@md-5.net>
Date: Mon, 20 Jan 2014 13:44:07 +1100
Subject: [PATCH] Catch stalling on corrupted map data / NBT arrays.
diff --git a/src/main/java/net/minecraft/server/NBTTagByteArray.java b/src/main/java/net/minecraft/server/NBTTagByteArray.java
index c6b5f70..13e9d0b 100644
--- a/src/main/java/net/minecraft/server/NBTTagByteArray.java
+++ b/src/main/java/net/minecraft/server/NBTTagByteArray.java
@@ -23,6 +23,7 @@ public class NBTTagByteArray extends NBTBase {
void load(DataInput datainput, int i, NBTReadLimiter nbtreadlimiter) throws IOException {
nbtreadlimiter.a(192L);
int j = datainput.readInt();
+ com.google.common.base.Preconditions.checkArgument( j < 1 << 24);
nbtreadlimiter.a((long) (8 * j));
this.data = new byte[j];
diff --git a/src/main/java/net/minecraft/server/NBTTagIntArray.java b/src/main/java/net/minecraft/server/NBTTagIntArray.java
index 5f17034..e206e50 100644
--- a/src/main/java/net/minecraft/server/NBTTagIntArray.java
+++ b/src/main/java/net/minecraft/server/NBTTagIntArray.java
@@ -27,6 +27,7 @@ public class NBTTagIntArray extends NBTBase {
void load(DataInput datainput, int i, NBTReadLimiter nbtreadlimiter) throws IOException {
nbtreadlimiter.a(192L);
int j = datainput.readInt();
+ com.google.common.base.Preconditions.checkArgument( j < 1 << 24);
nbtreadlimiter.a((long) (32 * j));
this.data = new int[j];
--
2.5.0

View File

@ -1,38 +0,0 @@
From 293c8c84dca0a789d28c3dcdefa8c9b46f77467a Mon Sep 17 00:00:00 2001
From: Dmck2b <dmck2b+github@gmail.com>
Date: Mon, 20 Jan 2014 20:18:23 +0000
Subject: [PATCH] Allow toggling of ZombiePigmen spawning in portal blocks
diff --git a/src/main/java/net/minecraft/server/BlockPortal.java b/src/main/java/net/minecraft/server/BlockPortal.java
index 05f0719..d85335b 100644
--- a/src/main/java/net/minecraft/server/BlockPortal.java
+++ b/src/main/java/net/minecraft/server/BlockPortal.java
@@ -35,7 +35,7 @@ public class BlockPortal extends BlockHalfTransparent {
public void b(World world, BlockPosition blockposition, IBlockData iblockdata, Random random) {
super.b(world, blockposition, iblockdata, random);
- if (world.worldProvider.d() && world.getGameRules().getBoolean("doMobSpawning") && random.nextInt(2000) < world.getDifficulty().a()) {
+ if (world.spigotConfig.enableZombiePigmenPortalSpawns && world.worldProvider.d() && world.getGameRules().getBoolean("doMobSpawning") && random.nextInt(2000) < world.getDifficulty().a()) { // Spigot
int i = blockposition.getY();
BlockPosition blockposition1;
diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java
index 3854195..4cca76a 100644
--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java
+++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java
@@ -217,4 +217,11 @@ public class SpigotWorldConfig
nerfSpawnerMobs = getBoolean( "nerf-spawner-mobs", false );
log( "Nerfing mobs spawned from spawners: " + nerfSpawnerMobs );
}
+
+ public boolean enableZombiePigmenPortalSpawns;
+ private void enableZombiePigmenPortalSpawns()
+ {
+ enableZombiePigmenPortalSpawns = getBoolean( "enable-zombie-pigmen-portal-spawns", true );
+ log( "Allow Zombie Pigmen to spawn from portal blocks: " + enableZombiePigmenPortalSpawns );
+ }
}
--
2.5.0

View File

@ -1,165 +0,0 @@
From 8ae40e4b57d9b0750319f013dbe1d818b9bc43be Mon Sep 17 00:00:00 2001
From: md_5 <git@md-5.net>
Date: Sat, 25 Jan 2014 14:08:35 +1100
Subject: [PATCH] Highly Optimized Tick Loop
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index bd2837c..49e5aac 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -114,6 +114,12 @@ public abstract class MinecraftServer implements Runnable, ICommandListener, IAs
public java.util.Queue<Runnable> processQueue = new java.util.concurrent.ConcurrentLinkedQueue<Runnable>();
public int autosavePeriod;
// CraftBukkit end
+ // Spigot start
+ private static final int TPS = 20;
+ private static final int TICK_TIME = 1000000000 / TPS;
+ private static final int SAMPLE_INTERVAL = 100;
+ public final double[] recentTps = new double[ 3 ];
+ // Spigot end
public MinecraftServer(OptionSet options, Proxy proxy, DataConverterManager dataconvertermanager, YggdrasilAuthenticationService yggdrasilauthenticationservice, MinecraftSessionService minecraftsessionservice, GameProfileRepository gameprofilerepository, UserCache usercache) {
this.e = proxy;
@@ -502,6 +508,13 @@ public abstract class MinecraftServer implements Runnable, ICommandListener, IAs
this.isRunning = false;
}
+ // Spigot Start
+ private static double calcTps(double avg, double exp, double tps)
+ {
+ return ( avg * exp ) + ( tps * ( 1 - exp ) );
+ }
+ // Spigot End
+
public void run() {
try {
if (this.init()) {
@@ -512,38 +525,34 @@ public abstract class MinecraftServer implements Runnable, ICommandListener, IAs
this.q.setServerInfo(new ServerPing.ServerData("1.9", 107));
this.a(this.q);
+ // Spigot start
+ Arrays.fill( recentTps, 20 );
+ long lastTick = System.nanoTime(), catchupTime = 0, curTime, wait, tickSection = lastTick;
while (this.isRunning) {
- long j = av();
- long k = j - this.aa;
-
- if (k > 2000L && this.aa - this.Q >= 15000L) {
- if (server.getWarnOnOverload()) // CraftBukkit
- MinecraftServer.LOGGER.warn("Can\'t keep up! Did the system time change, or is the server overloaded? Running {}ms behind, skipping {} tick(s)", new Object[] { Long.valueOf(k), Long.valueOf(k / 50L)});
- k = 2000L;
- this.Q = this.aa;
- }
-
- if (k < 0L) {
- MinecraftServer.LOGGER.warn("Time ran backwards! Did the system time change?");
- k = 0L;
+ curTime = System.nanoTime();
+ wait = TICK_TIME - (curTime - lastTick) - catchupTime;
+ if (wait > 0) {
+ Thread.sleep(wait / 1000000);
+ catchupTime = 0;
+ continue;
+ } else {
+ catchupTime = Math.min(1000000000, Math.abs(wait));
}
- i += k;
- this.aa = j;
- if (this.worlds.get(0).everyoneDeeplySleeping()) { // CraftBukkit
- this.C();
- i = 0L;
- } else {
- while (i > 50L) {
- MinecraftServer.currentTick = (int) (System.currentTimeMillis() / 50); // CraftBukkit
- i -= 50L;
- this.C();
- }
+ if ( MinecraftServer.currentTick++ % SAMPLE_INTERVAL == 0 )
+ {
+ double currentTps = 1E9 / ( curTime - tickSection ) * SAMPLE_INTERVAL;
+ recentTps[0] = calcTps( recentTps[0], 0.92, currentTps ); // 1/exp(5sec/1min)
+ recentTps[1] = calcTps( recentTps[1], 0.9835, currentTps ); // 1/exp(5sec/5min)
+ recentTps[2] = calcTps( recentTps[2], 0.9945, currentTps ); // 1/exp(5sec/15min)
+ tickSection = curTime;
}
+ lastTick = curTime;
- Thread.sleep(Math.max(1L, 50L - i));
+ this.C();
this.P = true;
}
+ // Spigot end
} else {
this.a((CrashReport) null);
}
diff --git a/src/main/java/org/spigotmc/SpigotConfig.java b/src/main/java/org/spigotmc/SpigotConfig.java
index a2be9df..e1cc2e0 100644
--- a/src/main/java/org/spigotmc/SpigotConfig.java
+++ b/src/main/java/org/spigotmc/SpigotConfig.java
@@ -262,4 +262,9 @@ public class SpigotConfig
"screen." );
}
}
+
+ private static void tpsCommand()
+ {
+ commands.put( "tps", new TicksPerSecondCommand( "tps" ) );
+ }
}
diff --git a/src/main/java/org/spigotmc/TicksPerSecondCommand.java b/src/main/java/org/spigotmc/TicksPerSecondCommand.java
new file mode 100644
index 0000000..be2e31d
--- /dev/null
+++ b/src/main/java/org/spigotmc/TicksPerSecondCommand.java
@@ -0,0 +1,45 @@
+package org.spigotmc;
+
+import com.google.common.base.Joiner;
+import net.minecraft.server.MinecraftServer;
+import com.google.common.collect.Iterables;
+import org.bukkit.ChatColor;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandSender;
+
+public class TicksPerSecondCommand extends Command
+{
+
+ public TicksPerSecondCommand(String name)
+ {
+ super( name );
+ this.description = "Gets the current ticks per second for the server";
+ this.usageMessage = "/tps";
+ this.setPermission( "bukkit.command.tps" );
+ }
+
+ @Override
+ public boolean execute(CommandSender sender, String currentAlias, String[] args)
+ {
+ if ( !testPermission( sender ) )
+ {
+ return true;
+ }
+
+ StringBuilder sb = new StringBuilder( ChatColor.GOLD + "TPS from last 1m, 5m, 15m: " );
+ for ( double tps : MinecraftServer.getServer().recentTps )
+ {
+ sb.append( format( tps ) );
+ sb.append( ", " );
+ }
+ sender.sendMessage( sb.substring( 0, sb.length() - 2 ) );
+
+ return true;
+ }
+
+ private String format(double tps)
+ {
+ return ( ( tps > 18.0 ) ? ChatColor.GREEN : ( tps > 16.0 ) ? ChatColor.YELLOW : ChatColor.RED ).toString()
+ + ( ( tps > 20.0 ) ? "*" : "" ) + Math.min( Math.round( tps * 100.0 ) / 100.0, 20.0 );
+ }
+}
--
2.5.0

View File

@ -1,43 +0,0 @@
From dbfad51762956d4bc6c5c5d72cbf0f3a2badde7d Mon Sep 17 00:00:00 2001
From: md_5 <git@md-5.net>
Date: Sun, 26 Jan 2014 21:48:34 +1100
Subject: [PATCH] Configurable Ping Sample Size
diff --git a/src/main/java/net/minecraft/server/PacketStatusListener.java b/src/main/java/net/minecraft/server/PacketStatusListener.java
index 519a380..08b14ec 100644
--- a/src/main/java/net/minecraft/server/PacketStatusListener.java
+++ b/src/main/java/net/minecraft/server/PacketStatusListener.java
@@ -108,6 +108,13 @@ public class PacketStatusListener implements PacketStatusInListener {
}
ServerPing.ServerPingPlayerSample playerSample = new ServerPing.ServerPingPlayerSample(event.getMaxPlayers(), profiles.size());
+ // Spigot Start
+ if ( !profiles.isEmpty() )
+ {
+ java.util.Collections.shuffle( profiles ); // This sucks, its inefficient but we have no simple way of doing it differently
+ profiles = profiles.subList( 0, Math.min( profiles.size(), org.spigotmc.SpigotConfig.playerSample ) ); // Cap the sample to n (or less) displayed players, ie: Vanilla behaviour
+ }
+ // Spigot End
playerSample.a(profiles.toArray(new GameProfile[profiles.size()]));
ServerPing ping = new ServerPing();
diff --git a/src/main/java/org/spigotmc/SpigotConfig.java b/src/main/java/org/spigotmc/SpigotConfig.java
index e1cc2e0..936c860 100644
--- a/src/main/java/org/spigotmc/SpigotConfig.java
+++ b/src/main/java/org/spigotmc/SpigotConfig.java
@@ -267,4 +267,11 @@ public class SpigotConfig
{
commands.put( "tps", new TicksPerSecondCommand( "tps" ) );
}
+
+ public static int playerSample;
+ private static void playerSample()
+ {
+ playerSample = getInt( "settings.sample-count", 12 );
+ System.out.println( "Server Ping Player Sample Count: " + playerSample );
+ }
}
--
2.5.0

View File

@ -1,43 +0,0 @@
From 61113aa5f7710ecae31ddc374322342efc928f17 Mon Sep 17 00:00:00 2001
From: md_5 <git@md-5.net>
Date: Mon, 27 Jan 2014 08:39:26 +1100
Subject: [PATCH] Add Optional Tick Shuffling
This prevents players from 'gaming' the server, and strategically relogging to increase their position in the tick order.
diff --git a/src/main/java/net/minecraft/server/ServerConnection.java b/src/main/java/net/minecraft/server/ServerConnection.java
index 968a1b7..827bfaf 100644
--- a/src/main/java/net/minecraft/server/ServerConnection.java
+++ b/src/main/java/net/minecraft/server/ServerConnection.java
@@ -123,6 +123,13 @@ public class ServerConnection {
List list = this.h;
synchronized (this.h) {
+ // Spigot Start
+ // This prevents players from 'gaming' the server, and strategically relogging to increase their position in the tick order
+ if ( org.spigotmc.SpigotConfig.playerShuffle > 0 && MinecraftServer.currentTick % org.spigotmc.SpigotConfig.playerShuffle == 0 )
+ {
+ Collections.shuffle( this.h );
+ }
+ // Spigot End
Iterator iterator = this.h.iterator();
while (iterator.hasNext()) {
diff --git a/src/main/java/org/spigotmc/SpigotConfig.java b/src/main/java/org/spigotmc/SpigotConfig.java
index 936c860..83e575f 100644
--- a/src/main/java/org/spigotmc/SpigotConfig.java
+++ b/src/main/java/org/spigotmc/SpigotConfig.java
@@ -274,4 +274,10 @@ public class SpigotConfig
playerSample = getInt( "settings.sample-count", 12 );
System.out.println( "Server Ping Player Sample Count: " + playerSample );
}
+
+ public static int playerShuffle;
+ private static void playerShuffle()
+ {
+ playerShuffle = getInt( "settings.player-shuffle", 0 );
+ }
}
--
2.5.0

View File

@ -1,39 +0,0 @@
From 91de49dc685e28082f2060813a712900d00ef634 Mon Sep 17 00:00:00 2001
From: Smove <jan@lavasurvival.net>
Date: Sat, 1 Feb 2014 18:12:16 +1100
Subject: [PATCH] Implement Locale Getter for Players
diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java
index 91b5e2e..7df4d87 100644
--- a/src/main/java/net/minecraft/server/EntityPlayer.java
+++ b/src/main/java/net/minecraft/server/EntityPlayer.java
@@ -25,7 +25,7 @@ import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
public class EntityPlayer extends EntityHuman implements ICrafting {
private static final Logger bQ = LogManager.getLogger();
- private String locale = "en_US";
+ public String locale = "en_US"; // Spigot private -> public
public PlayerConnection playerConnection;
public final MinecraftServer server;
public final PlayerInteractManager playerInteractManager;
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
index 28fc6e6..8307458 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -1490,6 +1490,12 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
getHandle().playerConnection.sendPacket( packet );
}
}
+
+ @Override
+ public String getLocale()
+ {
+ return getHandle().locale;
+ }
};
public Player.Spigot spigot()
--
2.5.0

View File

@ -1,63 +0,0 @@
From 65b40359420e0895ba245c0a7645e1fccdef63e0 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Fri, 31 Jan 2014 11:18:34 -0500
Subject: [PATCH] Cap Entity Collisions
Limit a single entity to colliding a max of configurable times per tick.
This will alleviate issues where living entities are hoarded in 1x1 pens.
diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
index b723b9b..0b0ff64 100644
--- a/src/main/java/net/minecraft/server/Entity.java
+++ b/src/main/java/net/minecraft/server/Entity.java
@@ -147,6 +147,7 @@ public abstract class Entity implements ICommandListener {
public long activatedTick = Integer.MIN_VALUE;
public boolean fromMobSpawner;
public void inactiveTick() { }
+ protected int numCollisions = 0;
// Spigot end
public Entity(World world) {
diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java
index 0cf1b90..8122cae 100644
--- a/src/main/java/net/minecraft/server/EntityLiving.java
+++ b/src/main/java/net/minecraft/server/EntityLiving.java
@@ -1975,7 +1975,8 @@ public abstract class EntityLiving extends Entity {
List list = this.world.a((Entity) this, this.getBoundingBox(), IEntitySelector.a(this));
if (this.isInteractable() && !list.isEmpty()) { // Spigot: Add isInteractable() condition
- for (int i = 0; i < list.size(); ++i) {
+ numCollisions = Math.max(0, numCollisions - world.spigotConfig.maxCollisionsPerEntity); // Spigot
+ for (int i = 0; i < list.size() && numCollisions < world.spigotConfig.maxCollisionsPerEntity; ++i) {
Entity entity = (Entity) list.get(i);
// TODO better check now?
// CraftBukkit start - Only handle mob (non-player) collisions every other tick
@@ -1984,7 +1985,8 @@ public abstract class EntityLiving extends Entity {
}
// CraftBukkit end
-
+ entity.numCollisions++; // Spigot
+ numCollisions++; // Spigot
this.C(entity);
}
}
diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java
index 4cca76a..19525eb 100644
--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java
+++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java
@@ -224,4 +224,11 @@ public class SpigotWorldConfig
enableZombiePigmenPortalSpawns = getBoolean( "enable-zombie-pigmen-portal-spawns", true );
log( "Allow Zombie Pigmen to spawn from portal blocks: " + enableZombiePigmenPortalSpawns );
}
+
+ public int maxCollisionsPerEntity;
+ private void maxEntityCollision()
+ {
+ maxCollisionsPerEntity = getInt( "max-entity-collisions", 8 );
+ log( "Max Entity Collisions: " + maxCollisionsPerEntity );
+ }
}
--
2.5.0

View File

@ -1,22 +0,0 @@
From 3fec87491b69ba4cc3faaad819eb9c2fb9546836 Mon Sep 17 00:00:00 2001
From: Thinkofdeath <thethinkofdeath@gmail.com>
Date: Thu, 6 Feb 2014 21:59:20 +0000
Subject: [PATCH] Fix dispensing bone meal not having the correct data value
diff --git a/src/main/java/net/minecraft/server/DispenserRegistry.java b/src/main/java/net/minecraft/server/DispenserRegistry.java
index f2dc326..d7bea3d 100644
--- a/src/main/java/net/minecraft/server/DispenserRegistry.java
+++ b/src/main/java/net/minecraft/server/DispenserRegistry.java
@@ -442,7 +442,7 @@ public class DispenserRegistry {
// CraftBukkit start
org.bukkit.block.Block block = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ());
- CraftItemStack craftItem = CraftItemStack.asNewCraftStack(itemstack.getItem());
+ CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack); // Spigot
BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(0, 0, 0));
if (!BlockDispenser.eventFired) {
--
2.5.0

Some files were not shown because too many files have changed in this diff Show More