Apply our patches over Spigot-Server and Spigot-API directly

This commit is contained in:
Zach Brown
2014-06-24 07:21:58 -05:00
parent 8ee4e6118b
commit 8ae366785c
196 changed files with 36 additions and 17676 deletions

View File

@@ -1,160 +0,0 @@
From 4c0a6720e1aa3018860c091f0eab1744a7009ec6 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
diff --git a/pom.xml b/pom.xml
index b2e2002..df02bd3 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.7.9-R0.3-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>
@@ -18,24 +18,12 @@
<buildtag.suffix></buildtag.suffix>
</properties>
- <scm>
- <connection>scm:git:git://github.com/Bukkit/CraftBukkit.git</connection>
- <developerConnection>scm:git:ssh://git@github.com/Bukkit/CraftBukkit.git</developerConnection>
- <url>https://github.com/Bukkit/CraftBukkit</url>
- </scm>
-
- <distributionManagement>
- <repository>
- <id>repobo-rel</id>
- <name>repo.bukkit.org Releases</name>
- <url>http://repo.bukkit.org/content/repositories/releases/</url>
- </repository>
- <snapshotRepository>
- <id>repobo-snap</id>
- <name>repo.bukkit.org Snapshots</name>
- <url>http://repo.bukkit.org/content/repositories/snapshots/</url>
- </snapshotRepository>
- </distributionManagement>
+ <parent>
+ <groupId>org.spigotmc</groupId>
+ <artifactId>spigot-parent</artifactId>
+ <version>dev-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
<repositories>
<repository>
@@ -53,8 +41,8 @@
<dependencies>
<dependency>
- <groupId>org.bukkit</groupId>
- <artifactId>bukkit</artifactId>
+ <groupId>org.spigotmc</groupId>
+ <artifactId>spigot-api</artifactId>
<version>${project.version}</version>
<type>jar</type>
<scope>compile</scope>
@@ -107,33 +95,6 @@
<artifactId>gson</artifactId>
<version>2.1</version>
</dependency>
- <dependency>
- <groupId>org.avaje</groupId>
- <artifactId>ebean</artifactId>
- <version>2.7.3</version>
- <type>jar</type>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.yaml</groupId>
- <artifactId>snakeyaml</artifactId>
- <version>1.9</version>
- <type>jar</type>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>com.google.guava</groupId>
- <artifactId>guava</artifactId>
- <version>10.0</version>
- <type>jar</type>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>commons-lang</groupId>
- <artifactId>commons-lang</artifactId>
- <version>2.3</version>
- <scope>provided</scope>
- </dependency>
<!-- testing -->
<dependency>
<groupId>junit</groupId>
@@ -151,15 +112,15 @@
<!-- This builds a completely 'ready to start' jar with all dependencies inside -->
<build>
- <defaultGoal>clean install</defaultGoal>
+ <defaultGoal>install</defaultGoal>
<plugins>
<plugin>
<groupId>com.lukegb.mojo</groupId>
<artifactId>gitdescribe-maven-plugin</artifactId>
<version>1.3</version>
<configuration>
- <outputPrefix>${buildtag.prefix}</outputPrefix>
- <outputPostfix>${buildtag.suffix}</outputPostfix>
+ <outputPrefix>git-Spigot-</outputPrefix>
+ <outputPostfix></outputPostfix>
</configuration>
<executions>
<execution>
@@ -212,7 +173,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
- <version>1.4</version>
+ <version>2.1</version>
<executions>
<execution>
<phase>package</phase>
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index 3be5174..853e5d2 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -308,7 +308,7 @@ public final class CraftServer implements Server {
loadIcon();
updater = new AutoUpdater(new BukkitDLUpdaterService(configuration.getString("auto-updater.host")), getLogger(), configuration.getString("auto-updater.preferred-channel"));
- updater.setEnabled(configuration.getBoolean("auto-updater.enabled"));
+ updater.setEnabled(false); // Spigot
updater.setSuggestChannels(configuration.getBoolean("auto-updater.suggest-channels"));
updater.getOnBroken().addAll(configuration.getStringList("auto-updater.on-broken"));
updater.getOnUpdate().addAll(configuration.getStringList("auto-updater.on-update"));
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) {
--
1.9.1

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Zach Brown <1254957+zachbr@users.noreply.github.com>
Date: Sat, 17 May 2014 00:18:54 -0500
Date: Tue, 24 Jun 2014 07:32:04 -0500
Subject: [PATCH] Allow undead horse types to be leashed
@@ -8,13 +8,11 @@ diff --git a/src/main/java/net/minecraft/server/EntityHorse.java b/src/main/java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/EntityHorse.java
+++ b/src/main/java/net/minecraft/server/EntityHorse.java
@@ -0,0 +0,0 @@ import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason;
// CraftBukkit end
@@ -0,0 +0,0 @@ import java.util.List;
+// PaperSpigot start
+import org.spigotmc.SpigotWorldConfig;
+// PaperSpigot end
import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason; // CraftBukkit
+import org.spigotmc.SpigotWorldConfig; // PaperSpigot
+
public class EntityHorse extends EntityAnimal implements IInventoryListener {
@@ -24,7 +22,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public boolean bM() {
- return !this.cE() && super.bM();
+ // PaperSpigot start - Configurable undead horse leashing
+ // PaperSpigot start - configurable undead horse leashing
+ if (SpigotWorldConfig.allowUndeadHorseLeashing) {
+ return super.bM();
+ } else {
@@ -39,17 +37,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java
+++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java
@@ -0,0 +0,0 @@ public class SpigotWorldConfig
log( "Allow Zombie Pigmen to spawn from portal blocks: " + enableZombiePigmenPortalSpawns );
{
witherSpawnSoundRadius = getInt( "wither-spawn-sound-radius", 0 );
}
+
+ public static boolean allowUndeadHorseLeashing;
+ private void allowUndeadHorseLeashing()
+ {
+ allowUndeadHorseLeashing = getBoolean( "allow-undead-horse-leashing", true);
+ log( "Allow undead horse types to be leashed: " + allowUndeadHorseLeashing );
+ }
+
public int maxBulkChunk;
private void bulkChunkCount()
{
}
--

View File

@@ -1,88 +0,0 @@
From 59b4d5f7a05bcd2a37573713843d2598e069e38e 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
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index 9bc72aa..fc3aece 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -1313,4 +1313,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 4f8d47d..09e7223 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 fe0f200..e026c1f 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
@@ -399,4 +399,15 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
return getHandle().vehicle.getBukkitEntity();
}
+
+ // 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/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
index 55ea121..dea26e0 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -1285,4 +1285,15 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
}
collection.add(new AttributeModifiable(getHandle().bb(), (new AttributeRanged("generic.maxHealth", scaledHealth ? healthScale : getMaxHealth(), 0.0D, Float.MAX_VALUE)).a("Max Health").a(true)));
}
+
+ // Spigot start
+ private final Player.Spigot spigot = new Player.Spigot()
+ {
+ };
+
+ public Player.Spigot spigot()
+ {
+ return spigot;
+ }
+ // Spigot end
}
--
1.9.1

View File

@@ -1,26 +0,0 @@
From 58337f50edfe719fbf71c940574371d23afc97d0 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
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 00bb455..dda2602 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -1225,6 +1225,12 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo
}
}
+ // Spigot Start
+ public ServerConnection getServerConnection()
+ {
+ return this.p;
+ }
+ // Spigot End
public ServerConnection ai() {
return this.p;
}
--
1.8.3.2

View File

@@ -1,301 +0,0 @@
From 45a5a5488e6357d94cc9f197e876d8d1a86f81bb 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
diff --git a/src/main/java/net/minecraft/server/DedicatedServer.java b/src/main/java/net/minecraft/server/DedicatedServer.java
index f1caa38..00f9b89 100644
--- a/src/main/java/net/minecraft/server/DedicatedServer.java
+++ b/src/main/java/net/minecraft/server/DedicatedServer.java
@@ -109,6 +109,11 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer
if (this.L() < 0) {
this.setPort(this.propertyManager.getInt("server-port", 25565));
}
+ // Spigot start
+ this.a((PlayerList) (new DedicatedPlayerList(this)));
+ org.spigotmc.SpigotConfig.init();
+ org.spigotmc.SpigotConfig.registerCommands();
+ // Spigot end
i.info("Generating keypair");
this.a(MinecraftEncryption.b());
@@ -123,7 +128,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)));
+ server.loadPlugins();
+ server.enablePlugins(org.bukkit.plugin.PluginLoadOrder.STARTUP);
+ // Spigot End
if (!this.getOnlineMode()) {
i.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 eb5da2a..c6ba026 100644
--- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java
@@ -106,6 +106,7 @@ public abstract class World implements IBlockAccess {
public boolean pvpMode;
public boolean keepSpawnInMemory = true;
public ChunkGenerator generator;
+ public final org.spigotmc.SpigotWorldConfig spigotConfig; // Spigot
public CraftWorld getWorld() {
return this.world;
@@ -121,6 +122,7 @@ public abstract class World implements IBlockAccess {
// Changed signature - added gen and env
public World(IDataManager idatamanager, String s, WorldSettings worldsettings, WorldProvider worldprovider, MethodProfiler methodprofiler, ChunkGenerator gen, org.bukkit.World.Environment env) {
+ this.spigotConfig = new org.spigotmc.SpigotWorldConfig( s ); // 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 853e5d2..95742fa 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -314,8 +314,10 @@ public final class CraftServer implements Server {
updater.getOnUpdate().addAll(configuration.getStringList("auto-updater.on-update"));
updater.check(serverVersion);
- 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) {
@@ -749,6 +751,7 @@ public final class CraftServer implements Server {
logger.log(Level.WARNING, "Failed to load banned-players.json, " + ex.getMessage());
}
+ org.spigotmc.SpigotConfig.init(); // Spigot
for (WorldServer world : console.worlds) {
world.difficulty = difficulty;
world.setSpawnFlags(monsters, animals);
@@ -763,11 +766,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/spigotmc/SpigotConfig.java b/src/main/java/org/spigotmc/SpigotConfig.java
new file mode 100644
index 0000000..fd5997d
--- /dev/null
+++ b/src/main/java/org/spigotmc/SpigotConfig.java
@@ -0,0 +1,120 @@
+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.file.YamlConfiguration;
+
+public class SpigotConfig
+{
+
+ private static final File CONFIG_FILE = new File( "spigot.yml" );
+ 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.esper.net ( http://webchat.esper.net/?channel=spigot )\n"
+ + "Forums: http://www.spigotmc.org/forum/\n";
+ /*========================================================================*/
+ static YamlConfiguration config;
+ static int version;
+ static Map<String, Command> commands;
+ /*========================================================================*/
+
+ public static void init()
+ {
+ config = YamlConfiguration.loadConfiguration( CONFIG_FILE );
+ config.options().header( HEADER );
+ config.options().copyDefaults( true );
+
+ commands = new HashMap<String, Command>();
+
+ version = getInt( "config-version", 6 );
+ set( "config-version", 6 );
+ 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 )
+ {
+ 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 ) );
+ }
+}
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 ) );
+ }
+}
--
1.9.1

View File

@@ -1,182 +0,0 @@
From 622e47b08274e5a09f6a7e0bcf98300fb438062f Mon Sep 17 00:00:00 2001
From: md_5 <md_5@live.com.au>
Date: Tue, 11 Jun 2013 12:56:02 +1000
Subject: [PATCH] Better Chunk Tick Selection
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
index c6ba026..02600a7 100644
--- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java
@@ -62,7 +62,7 @@ public abstract class World implements IBlockAccess {
public Scoreboard scoreboard = new Scoreboard(); // CraftBukkit - protected -> public
public boolean isStatic;
// CraftBukkit start - public, longhashset
- protected LongHashSet chunkTickList = new LongHashSet();
+ // protected LongHashSet chunkTickList = new LongHashSet(); // Spigot
private int K;
public boolean allowMonsters;
public boolean allowAnimals;
@@ -79,6 +79,30 @@ public abstract class World implements IBlockAccess {
private boolean M;
int[] I;
+ // Spigot start
+ protected final net.minecraft.util.gnu.trove.map.hash.TLongShortHashMap chunkTickList;
+ protected float growthOdds = 100;
+ protected float modifiedOdds = 100;
+ private final byte chunkTickRadius;
+
+ public static long chunkToKey(int x, int z)
+ {
+ long k = ( ( ( (long) x ) & 0xFFFF0000L ) << 16 ) | ( ( ( (long) x ) & 0x0000FFFFL ) << 0 );
+ k |= ( ( ( (long) z ) & 0xFFFF0000L ) << 32 ) | ( ( ( (long) z ) & 0x0000FFFFL ) << 16 );
+ return k;
+ }
+
+ public static int keyToX(long k)
+ {
+ return (int) ( ( ( k >> 16 ) & 0xFFFF0000 ) | ( k & 0x0000FFFF ) );
+ }
+
+ public static int keyToZ(long k)
+ {
+ return (int) ( ( ( k >> 32 ) & 0xFFFF0000L ) | ( ( k >> 16 ) & 0x0000FFFF ) );
+ }
+ // Spigot end
+
public BiomeBase getBiome(int i, int j) {
if (this.isLoaded(i, 0, j)) {
Chunk chunk = this.getChunkAtWorldCoords(i, j);
@@ -128,6 +152,11 @@ public abstract class World implements IBlockAccess {
this.ticksPerAnimalSpawns = this.getServer().getTicksPerAnimalSpawns(); // CraftBukkit
this.ticksPerMonsterSpawns = this.getServer().getTicksPerMonsterSpawns(); // CraftBukkit
// CraftBukkit end
+ // Spigot start
+ this.chunkTickRadius = (byte) ( ( this.getServer().getViewDistance() < 7 ) ? this.getServer().getViewDistance() : 7 );
+ this.chunkTickList = new net.minecraft.util.gnu.trove.map.hash.TLongShortHashMap( spigotConfig.chunksPerTick * 5, 0.7f, Long.MIN_VALUE, Short.MIN_VALUE );
+ this.chunkTickList.setAutoCompactionFactor( 0 );
+ // Spigot end
this.K = this.random.nextInt(12000);
this.allowMonsters = true;
@@ -1986,17 +2015,44 @@ public abstract class World implements IBlockAccess {
int k;
int l;
+ // Spigot start
+ int optimalChunks = spigotConfig.chunksPerTick;
+ // Quick conditions to allow us to exist early
+ if ( optimalChunks <= 0 || players.isEmpty() )
+ {
+ return;
+ }
+ // Keep chunks with growth inside of the optimal chunk range
+ int chunksPerPlayer = Math.min( 200, Math.max( 1, (int) ( ( ( optimalChunks - players.size() ) / (double) players.size() ) + 0.5 ) ) );
+ int randRange = 3 + chunksPerPlayer / 30;
+ // Limit to normal tick radius - including view distance
+ randRange = ( randRange > chunkTickRadius ) ? chunkTickRadius : randRange;
+ // odds of growth happening vs growth happening in vanilla
+ this.growthOdds = this.modifiedOdds = Math.max( 35, Math.min( 100, ( ( chunksPerPlayer + 1 ) * 100F ) / 15F ) );
+ // Spigot end
for (i = 0; i < this.players.size(); ++i) {
entityhuman = (EntityHuman) this.players.get(i);
j = MathHelper.floor(entityhuman.locX / 16.0D);
k = MathHelper.floor(entityhuman.locZ / 16.0D);
l = this.p();
- for (int i1 = -l; i1 <= l; ++i1) {
- for (int j1 = -l; j1 <= l; ++j1) {
- this.chunkTickList.add(org.bukkit.craftbukkit.util.LongHash.toLong(i1 + j, j1 + k)); // CraftBukkit
+ // Spigot start - Always update the chunk the player is on
+ long key = chunkToKey( j, k );
+ int existingPlayers = Math.max( 0, chunkTickList.get( key ) ); // filter out -1
+ chunkTickList.put(key, (short) (existingPlayers + 1));
+
+ // Check and see if we update the chunks surrounding the player this tick
+ for ( int chunk = 0; chunk < chunksPerPlayer; chunk++ )
+ {
+ int dx = ( random.nextBoolean() ? 1 : -1 ) * random.nextInt( randRange );
+ int dz = ( random.nextBoolean() ? 1 : -1 ) * random.nextInt( randRange );
+ long hash = chunkToKey( dx + j, dz + k );
+ if ( !chunkTickList.contains( hash ) && this.isChunkLoaded( dx + j, dz + k ) )
+ {
+ chunkTickList.put( hash, (short) -1 ); // no players
}
}
+ // Spigot End
}
this.methodProfiler.b();
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
index 3fa3a81..a30b79e 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java
@@ -307,10 +307,20 @@ public class WorldServer extends World {
// CraftBukkit start
// Iterator iterator = this.chunkTickList.iterator();
- for (long chunkCoord : this.chunkTickList.popAll()) {
+ // Spigot start
+ for (net.minecraft.util.gnu.trove.iterator.TLongShortIterator iter = chunkTickList.iterator(); iter.hasNext();) {
+ iter.advance();
+ long chunkCoord = iter.key();
+ int chunkX = World.keyToX(chunkCoord);
+ int chunkZ = World.keyToZ(chunkCoord);
+ // If unloaded, or in procedd of being unloaded, drop it
+ if ( ( !this.isChunkLoaded( chunkX, chunkZ ) ) || ( this.chunkProviderServer.unloadQueue.contains( chunkX, chunkZ ) ) )
+ {
+ iter.remove();
+ continue;
+ }
+ // Spigot end
// ChunkCoordIntPair chunkcoordintpair = (ChunkCoordIntPair) iterator.next();
- int chunkX = LongHash.msw(chunkCoord);
- int chunkZ = LongHash.lsw(chunkCoord);
int k = chunkX * 16;
int l = chunkZ * 16;
@@ -401,6 +411,7 @@ public class WorldServer extends World {
if (block.isTicking()) {
++i;
+ this.growthOdds = (iter.value() < 1) ? this.modifiedOdds : 100; // Spigot - grow fast if no players are in this chunk (value = player count)
block.a(this, k2 + k, i3 + chunksection.getYPosition(), l2 + l, this.random);
}
}
@@ -409,6 +420,12 @@ public class WorldServer extends World {
this.methodProfiler.b();
}
+ // Spigot Start
+ if ( spigotConfig.clearChunksOnTick )
+ {
+ chunkTickList.clear();
+ }
+ // Spigot End
}
public boolean a(int i, int j, int k, Block block) {
diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java
index 961ddb4..90a227f 100644
--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java
+++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java
@@ -68,4 +68,15 @@ public class SpigotWorldConfig
config.addDefault( "world-settings.default." + path, def );
return config.getString( "world-settings." + worldName + "." + path, config.getString( "world-settings.default." + path ) );
}
+
+ public int chunksPerTick;
+ public boolean clearChunksOnTick;
+ private void chunksPerTick()
+ {
+ chunksPerTick = getInt( "chunks-per-tick", 650 );
+ log( "Chunks to Grow per Tick: " + chunksPerTick );
+
+ clearChunksOnTick = getBoolean( "clear-tick-list", false );
+ log( "Clear tick list: " + clearChunksOnTick );
+ }
}
--
1.9.1

View File

@@ -1,176 +0,0 @@
From 1e1bd1813fe7ea78783f98d772faa52ba59005f6 Mon Sep 17 00:00:00 2001
From: md_5 <md_5@live.com.au>
Date: Fri, 21 Jun 2013 17:17:20 +1000
Subject: [PATCH] Crop Growth Rates
diff --git a/src/main/java/net/minecraft/server/Block.java b/src/main/java/net/minecraft/server/Block.java
index 14c00c5..51f8279 100644
--- a/src/main/java/net/minecraft/server/Block.java
+++ b/src/main/java/net/minecraft/server/Block.java
@@ -804,4 +804,16 @@ public class Block {
return 0;
}
// CraftBukkit end
+
+ // 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 57eb59d..6778cae 100644
--- a/src/main/java/net/minecraft/server/BlockCactus.java
+++ b/src/main/java/net/minecraft/server/BlockCactus.java
@@ -23,7 +23,7 @@ public class BlockCactus extends Block {
if (l < 3) {
int i1 = world.getData(i, j, k);
- if (i1 == 15) {
+ if (i1 >= (byte) range(3, (world.growthOdds / world.spigotConfig.cactusModifier * 15) + 0.5F, 15)) { // Spigot
org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(world, i, j + 1, k, this, 0); // CraftBukkit
world.setData(i, j, k, 0, 4);
this.doPhysics(world, i, j + 1, k, this);
diff --git a/src/main/java/net/minecraft/server/BlockCrops.java b/src/main/java/net/minecraft/server/BlockCrops.java
index 875181f..fd28d85 100644
--- a/src/main/java/net/minecraft/server/BlockCrops.java
+++ b/src/main/java/net/minecraft/server/BlockCrops.java
@@ -29,7 +29,7 @@ public class BlockCrops extends BlockPlant implements IBlockFragilePlantElement
if (l < 7) {
float f = this.n(world, i, j, k);
- if (random.nextInt((int) (25.0F / f) + 1) == 0) {
+ if (random.nextInt((int) (world.growthOdds / world.spigotConfig.wheatModifier * (25.0F / f)) + 1) == 0) { // Spigot
++l;
CraftEventFactory.handleBlockGrowEvent(world, i, j, k, this, l); // CraftBukkit
}
diff --git a/src/main/java/net/minecraft/server/BlockGrass.java b/src/main/java/net/minecraft/server/BlockGrass.java
index abd991b..7c00158 100644
--- a/src/main/java/net/minecraft/server/BlockGrass.java
+++ b/src/main/java/net/minecraft/server/BlockGrass.java
@@ -39,7 +39,8 @@ public class BlockGrass extends Block implements IBlockFragilePlantElement {
}
// CraftBukkit end
} else if (world.getLightLevel(i, j + 1, k) >= 9) {
- for (int l = 0; l < 4; ++l) {
+ int numGrowth = Math.min(4, Math.max(20, (int) (4 * 100F / world.growthOdds))); // Spigot
+ for (int l = 0; l < numGrowth; ++l) { // Spigot
int i1 = i + random.nextInt(3) - 1;
int j1 = j + random.nextInt(5) - 3;
int k1 = k + random.nextInt(3) - 1;
diff --git a/src/main/java/net/minecraft/server/BlockMushroom.java b/src/main/java/net/minecraft/server/BlockMushroom.java
index 5b90eb9..c720a7f 100644
--- a/src/main/java/net/minecraft/server/BlockMushroom.java
+++ b/src/main/java/net/minecraft/server/BlockMushroom.java
@@ -19,7 +19,7 @@ public class BlockMushroom extends BlockPlant implements IBlockFragilePlantEleme
public void a(World world, int i, int j, int k, Random random) {
final int sourceX = i, sourceY = j, sourceZ = k; // CraftBukkit
- if (random.nextInt(25) == 0) {
+ if (random.nextInt(Math.max(1, (int) world.growthOdds / world.spigotConfig.mushroomModifier * 25)) == 0) { // Spigot
byte b0 = 4;
int l = 5;
diff --git a/src/main/java/net/minecraft/server/BlockMycel.java b/src/main/java/net/minecraft/server/BlockMycel.java
index a01a6e6..2854bbc 100644
--- a/src/main/java/net/minecraft/server/BlockMycel.java
+++ b/src/main/java/net/minecraft/server/BlockMycel.java
@@ -33,7 +33,8 @@ public class BlockMycel extends Block {
}
// CraftBukkit end
} else if (world.getLightLevel(i, j + 1, k) >= 9) {
- for (int l = 0; l < 4; ++l) {
+ int numGrowth = Math.min(4, Math.max(20, (int) (4 * 100F / world.growthOdds))); // Spigot
+ for (int l = 0; l < numGrowth; ++l) { // Spigot
int i1 = i + random.nextInt(3) - 1;
int j1 = j + random.nextInt(5) - 3;
int k1 = k + random.nextInt(3) - 1;
diff --git a/src/main/java/net/minecraft/server/BlockReed.java b/src/main/java/net/minecraft/server/BlockReed.java
index a1350f6..6c04ad2 100644
--- a/src/main/java/net/minecraft/server/BlockReed.java
+++ b/src/main/java/net/minecraft/server/BlockReed.java
@@ -24,7 +24,7 @@ public class BlockReed extends Block {
if (l < 3) {
int i1 = world.getData(i, j, k);
- if (i1 == 15) {
+ if (i1 >= (byte) range(3, (world.growthOdds / world.spigotConfig.caneModifier * 15) + 0.5F, 15)) { // Spigot
org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(world, i, j + 1, k, this, 0); // CraftBukkit
world.setData(i, j, k, 0, 4);
} else {
diff --git a/src/main/java/net/minecraft/server/BlockSapling.java b/src/main/java/net/minecraft/server/BlockSapling.java
index ab8b07c..348a00e 100644
--- a/src/main/java/net/minecraft/server/BlockSapling.java
+++ b/src/main/java/net/minecraft/server/BlockSapling.java
@@ -27,7 +27,7 @@ public class BlockSapling extends BlockPlant implements IBlockFragilePlantElemen
public void a(World world, int i, int j, int k, Random random) {
if (!world.isStatic) {
super.a(world, i, j, k, random);
- if (world.getLightLevel(i, j + 1, k) >= 9 && random.nextInt(7) == 0) {
+ if (world.getLightLevel(i, j + 1, k) >= 9 && (random.nextInt(Math.max(2, (int) ((world.growthOdds / 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 40ad1c6..b37b187 100644
--- a/src/main/java/net/minecraft/server/BlockStem.java
+++ b/src/main/java/net/minecraft/server/BlockStem.java
@@ -26,7 +26,7 @@ public class BlockStem extends BlockPlant implements IBlockFragilePlantElement {
if (world.getLightLevel(i, j + 1, k) >= 9) {
float f = this.n(world, i, j, k);
- if (random.nextInt((int) (25.0F / f) + 1) == 0) {
+ if (random.nextInt((int) (world.growthOdds / (this == Blocks.PUMPKIN_STEM? world.spigotConfig.pumpkinModifier : world.spigotConfig.melonModifier) * (25.0F / f)) + 1) == 0) { // Spigot
int l = world.getData(i, j, k);
if (l < 7) {
diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java
index 90a227f..7e79ba5 100644
--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java
+++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java
@@ -79,4 +79,35 @@ public class SpigotWorldConfig
clearChunksOnTick = getBoolean( "clear-tick-list", false );
log( "Clear tick list: " + clearChunksOnTick );
}
+
+ // Crop growth rates
+ public int cactusModifier;
+ public int caneModifier;
+ public int melonModifier;
+ public int mushroomModifier;
+ public int pumpkinModifier;
+ public int saplingModifier;
+ public int wheatModifier;
+ 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" );
+ }
}
--
1.9.1

View File

@@ -1,6 +1,6 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Zach Brown <1254957+zachbr@users.noreply.github.com>
Date: Mon, 19 May 2014 21:13:31 -0500
Date: Tue, 24 Jun 2014 07:39:37 -0500
Subject: [PATCH] Configurable damage multiplier for PvP blocking
@@ -18,11 +18,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public PlayerInventory inventory = new PlayerInventory(this);
@@ -0,0 +0,0 @@ public abstract class EntityHuman extends EntityLiving implements ICommandListen
protected void d(DamageSource damagesource, float f) {
// CraftBukkit end
if (!this.isInvulnerable()) {
if (!damagesource.ignoresArmor() && this.isBlocking() && f > 0.0F) {
- f = (1.0F + f) * 0.5F;
+ f = (1.0F + f) * SpigotWorldConfig.playerBlockingDamageMultiplier; // PaperSpigot - Configurable damage multiplier for players blocking
+ f = (1.0F + f) * SpigotWorldConfig.playerBlockingDamageMultiplier; // PaperSpigot - Configurable PvP blocking damage multiplier
}
f = this.b(damagesource, f);
@@ -31,12 +31,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java
+++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java
@@ -0,0 +0,0 @@ public class SpigotWorldConfig
{
witherSpawnSoundRadius = getInt( "wither-spawn-sound-radius", 0 );
allowUndeadHorseLeashing = getBoolean( "allow-undead-horse-leashing", true);
log( "Allow undead horse types to be leashed: " + allowUndeadHorseLeashing );
}
+
+ public static float playerBlockingDamageMultiplier;
+ private void setPlayerBlockingDamageMultiplier()
+ private void playerBlockingDamageMultiplier()
+ {
+ playerBlockingDamageMultiplier = getFloat( "player-blocking-damage-multiplier", 0.5F );
+ }

View File

@@ -1,100 +0,0 @@
From 0094c2822caafc637fff7309e009c67424aabc2a Mon Sep 17 00:00:00 2001
From: md_5 <md_5@live.com.au>
Date: Tue, 11 Jun 2013 12:09:45 +1000
Subject: [PATCH] More Efficient Chunk Save Queue
diff --git a/src/main/java/net/minecraft/server/ChunkRegionLoader.java b/src/main/java/net/minecraft/server/ChunkRegionLoader.java
index 26bafe0..49acc9a 100644
--- a/src/main/java/net/minecraft/server/ChunkRegionLoader.java
+++ b/src/main/java/net/minecraft/server/ChunkRegionLoader.java
@@ -15,6 +15,7 @@ import org.apache.logging.log4j.Logger;
public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver {
+ private java.util.LinkedHashMap<ChunkCoordIntPair, PendingChunkToSave> pendingSaves = new java.util.LinkedHashMap<ChunkCoordIntPair, PendingChunkToSave>(); // Spigot
private static final Logger a = LogManager.getLogger();
private List b = new ArrayList();
private Set c = new HashSet();
@@ -30,13 +31,11 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver {
ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(i, j);
synchronized (this.d) {
- if (this.c.contains(chunkcoordintpair)) {
- for (int k = 0; k < this.b.size(); ++k) {
- if (((PendingChunkToSave) this.b.get(k)).a.equals(chunkcoordintpair)) {
- return true;
- }
- }
- }
+ // Spigot start
+ if (pendingSaves.containsKey(chunkcoordintpair)) {
+ return true;
+ }
+ // Spigot end
}
return RegionFileCache.a(this.e, i, j).chunkExists(i & 31, j & 31);
@@ -63,14 +62,12 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver {
Object object = this.d;
synchronized (this.d) {
- if (this.c.contains(chunkcoordintpair)) {
- for (int k = 0; k < this.b.size(); ++k) {
- if (((PendingChunkToSave) this.b.get(k)).a.equals(chunkcoordintpair)) {
- nbttagcompound = ((PendingChunkToSave) this.b.get(k)).b;
- break;
- }
- }
+ // Spigot start
+ PendingChunkToSave pendingchunktosave = pendingSaves.get(chunkcoordintpair);
+ if (pendingchunktosave != null) {
+ nbttagcompound = pendingchunktosave.b;
}
+ // Spigot end
}
if (nbttagcompound == null) {
@@ -150,17 +147,11 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver {
Object object = this.d;
synchronized (this.d) {
- if (this.c.contains(chunkcoordintpair)) {
- for (int i = 0; i < this.b.size(); ++i) {
- if (((PendingChunkToSave) this.b.get(i)).a.equals(chunkcoordintpair)) {
- this.b.set(i, new PendingChunkToSave(chunkcoordintpair, nbttagcompound));
- return;
- }
- }
+ // Spigot start
+ if (this.pendingSaves.put(chunkcoordintpair, new PendingChunkToSave(chunkcoordintpair, nbttagcompound)) != null) {
+ return;
}
-
- this.b.add(new PendingChunkToSave(chunkcoordintpair, nbttagcompound));
- this.c.add(chunkcoordintpair);
+ // Spigot end
FileIOThread.a.a(this);
}
}
@@ -170,12 +161,14 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver {
Object object = this.d;
synchronized (this.d) {
- if (this.b.isEmpty()) {
+ // Spigot start
+ if (this.pendingSaves.isEmpty()) {
return false;
}
- pendingchunktosave = (PendingChunkToSave) this.b.remove(0);
- this.c.remove(pendingchunktosave.a);
+ pendingchunktosave = this.pendingSaves.values().iterator().next();
+ this.pendingSaves.remove(pendingchunktosave.a);
+ // Spigot end
}
if (pendingchunktosave != null) {
--
1.8.3.2

View File

@@ -1,6 +1,6 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Zach Brown <1254957+zachbr@users.noreply.github.com>
Date: Tue, 20 May 2014 20:17:36 -0500
Date: Tue, 24 Jun 2014 07:44:59 -0500
Subject: [PATCH] Configurable cactus and reed natural growth heights
@@ -10,7 +10,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+++ b/src/main/java/net/minecraft/server/BlockCactus.java
@@ -0,0 +0,0 @@ import java.util.Random;
import org.bukkit.event.entity.EntityDamageByBlockEvent; // CraftBukkit
import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit
+import org.spigotmc.SpigotWorldConfig; // PaperSpigot
+

View File

@@ -1,96 +0,0 @@
From 2f9ed9fae66cee9278ba2ce8fc6a93a578e99243 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 8343ac9..95beb11 100644
--- a/src/main/java/net/minecraft/server/EntityItem.java
+++ b/src/main/java/net/minecraft/server/EntityItem.java
@@ -117,7 +117,10 @@ public class EntityItem extends Entity {
}
private void k() {
- Iterator iterator = this.world.a(EntityItem.class, this.boundingBox.grow(0.5D, 0.0D, 0.5D)).iterator();
+ // Spigot start
+ double radius = world.spigotConfig.itemMerge;
+ Iterator iterator = this.world.a(EntityItem.class, this.boundingBox.grow(radius, radius, radius)).iterator();
+ // Spigot end
while (iterator.hasNext()) {
EntityItem entityitem = (EntityItem) iterator.next();
@@ -148,11 +151,13 @@ public class EntityItem extends Entity {
} else if (itemstack1.count + itemstack.count > itemstack1.getMaxStackSize()) {
return false;
} else {
- 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
+ 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 02600a7..7c18d86 100644
--- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java
@@ -1010,6 +1010,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.boundingBox.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 7e79ba5..1545a61 100644
--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java
+++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java
@@ -110,4 +110,18 @@ public class SpigotWorldConfig
saplingModifier = getAndValidateGrowth( "Sapling" );
wheatModifier = getAndValidateGrowth( "Wheat" );
}
+
+ 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 );
+ }
}
--
1.9.1

View File

@@ -1,224 +0,0 @@
From 0ed4d284bbdfffc523e2c2c731443a31df66de15 Mon Sep 17 00:00:00 2001
From: md_5 <md_5@live.com.au>
Date: Fri, 21 Jun 2013 17:13:47 +1000
Subject: [PATCH] LongHash Tweaks
diff --git a/src/main/java/org/bukkit/craftbukkit/util/LongHash.java b/src/main/java/org/bukkit/craftbukkit/util/LongHash.java
index 691cafd..9d54472 100644
--- a/src/main/java/org/bukkit/craftbukkit/util/LongHash.java
+++ b/src/main/java/org/bukkit/craftbukkit/util/LongHash.java
@@ -10,6 +10,6 @@ public class LongHash {
}
public static int lsw(long l) {
- return (int) (l & 0xFFFFFFFF) + Integer.MIN_VALUE;
+ return (int) (l) + Integer.MIN_VALUE; // Spigot - remove redundant &
}
}
diff --git a/src/main/java/org/bukkit/craftbukkit/util/LongHashSet.java b/src/main/java/org/bukkit/craftbukkit/util/LongHashSet.java
index 22c96c5..7f659b7 100644
--- a/src/main/java/org/bukkit/craftbukkit/util/LongHashSet.java
+++ b/src/main/java/org/bukkit/craftbukkit/util/LongHashSet.java
@@ -31,6 +31,7 @@ public class LongHashSet {
private int elements;
private long[] values;
private int modCount;
+ private org.spigotmc.FlatMap<Boolean> flat = new org.spigotmc.FlatMap<Boolean>(); // Spigot
public LongHashSet() {
this(INITIAL_SIZE);
@@ -56,10 +57,30 @@ public class LongHashSet {
}
public boolean contains(int msw, int lsw) {
+ // Spigot start
+ if ( elements == 0 )
+ {
+ return false;
+ }
+ if ( flat.contains( msw, lsw ) )
+ {
+ return true;
+ }
+ // Spigot end
return contains(LongHash.toLong(msw, lsw));
}
public boolean contains(long value) {
+ // Spigot start
+ if ( elements == 0 )
+ {
+ return false;
+ }
+ if ( flat.contains( value ) )
+ {
+ return true;
+ }
+ // Spigot end
int hash = hash(value);
int index = (hash & 0x7FFFFFFF) % values.length;
int offset = 1;
@@ -82,6 +103,7 @@ public class LongHashSet {
}
public boolean add(long value) {
+ flat.put( value, Boolean.TRUE ); // Spigot
int hash = hash(value);
int index = (hash & 0x7FFFFFFF) % values.length;
int offset = 1;
@@ -125,10 +147,18 @@ public class LongHashSet {
}
public void remove(int msw, int lsw) {
- remove(LongHash.toLong(msw, lsw));
+ // Spigot start
+ flat.remove(msw, lsw);
+ remove0(LongHash.toLong(msw, lsw));
}
public boolean remove(long value) {
+ flat.remove(value);
+ return remove0(value);
+ }
+
+ private boolean remove0(long value) {
+ // Spigot end
int hash = hash(value);
int index = (hash & 0x7FFFFFFF) % values.length;
int offset = 1;
@@ -161,6 +191,7 @@ public class LongHashSet {
freeEntries = values.length;
modCount++;
+ flat = new org.spigotmc.FlatMap<Boolean>();
}
public long[] toArray() {
diff --git a/src/main/java/org/bukkit/craftbukkit/util/LongObjectHashMap.java b/src/main/java/org/bukkit/craftbukkit/util/LongObjectHashMap.java
index 01861cc..2e5b436 100644
--- a/src/main/java/org/bukkit/craftbukkit/util/LongObjectHashMap.java
+++ b/src/main/java/org/bukkit/craftbukkit/util/LongObjectHashMap.java
@@ -28,6 +28,7 @@ public class LongObjectHashMap<V> implements Cloneable, Serializable {
private transient V[][] values;
private transient int modCount;
private transient int size;
+ private transient org.spigotmc.FlatMap<V> flat = new org.spigotmc.FlatMap<V>(); // Spigot
public LongObjectHashMap() {
initialize();
@@ -61,6 +62,17 @@ public class LongObjectHashMap<V> implements Cloneable, Serializable {
}
public V get(long key) {
+ // Spigot start
+ if ( size == 0 )
+ {
+ return null;
+ }
+ V val = flat.get( key );
+ if ( val != null )
+ {
+ return val;
+ }
+ // Spigot end
int index = (int) (keyIndex(key) & (BUCKET_SIZE - 1));
long[] inner = keys[index];
if (inner == null) return null;
@@ -78,6 +90,7 @@ public class LongObjectHashMap<V> implements Cloneable, Serializable {
}
public V put(long key, V value) {
+ flat.put(key, value); // Spigot
int index = (int) (keyIndex(key) & (BUCKET_SIZE - 1));
long[] innerKeys = keys[index];
V[] innerValues = values[index];
@@ -124,6 +137,7 @@ public class LongObjectHashMap<V> implements Cloneable, Serializable {
}
public V remove(long key) {
+ flat.remove(key); // Spigot
int index = (int) (keyIndex(key) & (BUCKET_SIZE - 1));
long[] inner = keys[index];
if (inner == null) {
@@ -174,6 +188,7 @@ public class LongObjectHashMap<V> implements Cloneable, Serializable {
size = 0;
Arrays.fill(keys, null);
Arrays.fill(values, null);
+ flat = new org.spigotmc.FlatMap<V>();
}
public Set<Long> keySet() {
diff --git a/src/main/java/org/spigotmc/FlatMap.java b/src/main/java/org/spigotmc/FlatMap.java
new file mode 100644
index 0000000..9416f6e
--- /dev/null
+++ b/src/main/java/org/spigotmc/FlatMap.java
@@ -0,0 +1,64 @@
+package org.spigotmc;
+
+import org.bukkit.craftbukkit.util.LongHash;
+
+public class FlatMap<V>
+{
+
+ private static final int FLAT_LOOKUP_SIZE = 512;
+ private final Object[][] flatLookup = new Object[ FLAT_LOOKUP_SIZE * 2 ][ FLAT_LOOKUP_SIZE * 2 ];
+
+ public void put(long msw, long lsw, V value)
+ {
+ long acx = Math.abs( msw );
+ long acz = Math.abs( lsw );
+ if ( acx < FLAT_LOOKUP_SIZE && acz < FLAT_LOOKUP_SIZE )
+ {
+ flatLookup[(int) ( msw + FLAT_LOOKUP_SIZE )][(int) ( lsw + FLAT_LOOKUP_SIZE )] = value;
+ }
+ }
+
+ public void put(long key, V value)
+ {
+ put( LongHash.msw( key ), LongHash.lsw( key ), value );
+
+ }
+
+ public void remove(long key)
+ {
+ put( key, null );
+ }
+
+ public void remove(long msw, long lsw)
+ {
+ put( msw, lsw, null );
+ }
+
+ public boolean contains(long msw, long lsw)
+ {
+ return get( msw, lsw ) != null;
+ }
+
+ public boolean contains(long key)
+ {
+ return get( key ) != null;
+ }
+
+ public V get(long msw, long lsw)
+ {
+ long acx = Math.abs( msw );
+ long acz = Math.abs( lsw );
+ if ( acx < FLAT_LOOKUP_SIZE && acz < FLAT_LOOKUP_SIZE )
+ {
+ return (V) flatLookup[(int) ( msw + FLAT_LOOKUP_SIZE )][(int) ( lsw + FLAT_LOOKUP_SIZE )];
+ } else
+ {
+ return null;
+ }
+ }
+
+ public V get(long key)
+ {
+ return get( LongHash.msw( key ), LongHash.lsw( key ) );
+ }
+}
--
1.8.3.2

View File

@@ -1,173 +0,0 @@
From 8fec23d1020ed297e0c44f477a6466bdd89222b3 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 51f8279..aaead32 100644
--- a/src/main/java/net/minecraft/server/Block.java
+++ b/src/main/java/net/minecraft/server/Block.java
@@ -433,9 +433,13 @@ public class Block {
return 10;
}
- public void onPlace(World world, int i, int j, int k) {}
+ public void onPlace(World world, int i, int j, int k) {
+ org.spigotmc.AsyncCatcher.catchOp( "block onPlace"); // Spigot
+ }
- public void remove(World world, int i, int j, int k, Block block, int l) {}
+ public void remove(World world, int i, int j, int k, Block block, int l) {
+ org.spigotmc.AsyncCatcher.catchOp( "block remove"); // Spigot
+ }
public int a(Random random) {
return 1;
diff --git a/src/main/java/net/minecraft/server/EntityTracker.java b/src/main/java/net/minecraft/server/EntityTracker.java
index 1af0e67..70b0181 100644
--- a/src/main/java/net/minecraft/server/EntityTracker.java
+++ b/src/main/java/net/minecraft/server/EntityTracker.java
@@ -91,6 +91,7 @@ public class EntityTracker {
}
public void addEntity(Entity entity, int i, int j, boolean flag) {
+ org.spigotmc.AsyncCatcher.catchOp( "entity track"); // Spigot
if (i > this.e) {
i = this.e;
}
@@ -125,6 +126,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 c148c4d..a2b54a4 100644
--- a/src/main/java/net/minecraft/server/EntityTrackerEntry.java
+++ b/src/main/java/net/minecraft/server/EntityTrackerEntry.java
@@ -299,6 +299,7 @@ public class EntityTrackerEntry {
}
public void updatePlayer(EntityPlayer entityplayer) {
+ org.spigotmc.AsyncCatcher.catchOp( "player tracker update"); // Spigot
if (entityplayer != this.tracker) {
double d0 = entityplayer.locX - (double) (this.xLoc / 32);
double d1 = entityplayer.locZ - (double) (this.zLoc / 32);
@@ -515,6 +516,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);
entityplayer.d(this.tracker);
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
index 7c18d86..1fea307 100644
--- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java
@@ -979,6 +979,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
@@ -1085,6 +1086,7 @@ public abstract class World implements IBlockAccess {
}
public void removeEntity(Entity entity) {
+ org.spigotmc.AsyncCatcher.catchOp( "entity remove"); // Spigot
entity.die();
if (entity instanceof EntityHuman) {
this.players.remove(entity);
@@ -2465,6 +2467,7 @@ public abstract class World implements IBlockAccess {
}
public void a(List list) {
+ org.spigotmc.AsyncCatcher.catchOp( "entity world add"); // Spigot
// CraftBukkit start
// this.entityList.addAll(list);
Entity entity = null;
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index fc3aece..81913ac 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -162,6 +162,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;
}
@@ -172,6 +173,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 (safe && isChunkInUse(x, z)) {
return false;
}
@@ -239,6 +241,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 f700f0b..4d2374d 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -238,6 +238,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 84091a4..a8f28d7 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 + "!" );
+ }
+ }
+}
--
1.9.1

View File

@@ -1,55 +0,0 @@
From e58171001d40f747655e603fd0fdc2701be5e465 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 ae53635..cc1b095 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -26,9 +26,9 @@ public class PlayerChunkMap {
private final int[][] i = new int[][] { { 1, 0}, { 0, 1}, { -1, 0}, { 0, -1}};
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 a() {
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
index 9b5b370..3d938d8 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java
@@ -55,7 +55,7 @@ public class WorldServer extends World {
// CraftBukkit end
this.server = minecraftserver;
this.tracker = new EntityTracker(this);
- this.manager = new PlayerChunkMap(this);
+ this.manager = new PlayerChunkMap(this, spigotConfig.viewDistance); // Spigot
if (this.entitiesById == null) {
this.entitiesById = new IntHashMap();
}
diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java
index 1545a61..6cc3a91 100644
--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java
+++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java
@@ -124,4 +124,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 );
+ }
}
--
1.9.1

View File

@@ -1,394 +0,0 @@
From 5458bbfb3dfe9c40834dd68fe0e9bec527971fad Mon Sep 17 00:00:00 2001
From: Mike Primm <mike@primmhome.com>
Date: Sun, 13 Jan 2013 03:49:07 -0800
Subject: [PATCH] Compressed Nibble Arrays
Implement 'lightening' of NibbleArrays - only allocate
buffers when non-trivial value Saving from 40-45% of memory use by chunk
section data.
Finish up NibbleArray lightening work - use for Snapshots, reduce copies
Fix nibble handling with NBT - arrays aren't copied by NBTByteArray
diff --git a/src/main/java/net/minecraft/server/ChunkRegionLoader.java b/src/main/java/net/minecraft/server/ChunkRegionLoader.java
index 49acc9a..ce7a8bf 100644
--- a/src/main/java/net/minecraft/server/ChunkRegionLoader.java
+++ b/src/main/java/net/minecraft/server/ChunkRegionLoader.java
@@ -224,15 +224,15 @@ public class ChunkRegionLoader implements IChunkLoader, IAsyncChunkSaver {
nbttagcompound1.setByte("Y", (byte) (chunksection.getYPosition() >> 4 & 255));
nbttagcompound1.setByteArray("Blocks", chunksection.getIdArray());
if (chunksection.getExtendedIdArray() != null) {
- nbttagcompound1.setByteArray("Add", chunksection.getExtendedIdArray().a);
+ nbttagcompound1.setByteArray("Add", chunksection.getExtendedIdArray().getValueArray()); // Spigot
}
- nbttagcompound1.setByteArray("Data", chunksection.getDataArray().a);
- nbttagcompound1.setByteArray("BlockLight", chunksection.getEmittedLightArray().a);
+ nbttagcompound1.setByteArray("Data", chunksection.getDataArray().getValueArray()); // Spigot
+ nbttagcompound1.setByteArray("BlockLight", chunksection.getEmittedLightArray().getValueArray()); // Spigot
if (flag) {
- nbttagcompound1.setByteArray("SkyLight", chunksection.getSkyLightArray().a);
+ nbttagcompound1.setByteArray("SkyLight", chunksection.getSkyLightArray().getValueArray()); // Spigot
} else {
- nbttagcompound1.setByteArray("SkyLight", new byte[chunksection.getEmittedLightArray().a.length]);
+ nbttagcompound1.setByteArray("SkyLight", new byte[chunksection.getEmittedLightArray().getValueArray().length]); // Spigot
}
nbttaglist.add(nbttagcompound1);
diff --git a/src/main/java/net/minecraft/server/ChunkSection.java b/src/main/java/net/minecraft/server/ChunkSection.java
index a05efa0..360de1a 100644
--- a/src/main/java/net/minecraft/server/ChunkSection.java
+++ b/src/main/java/net/minecraft/server/ChunkSection.java
@@ -140,7 +140,8 @@ public class ChunkSection {
}
}
} else {
- byte[] ext = this.extBlockIds.a;
+ this.extBlockIds.forceToNonTrivialArray(); // Spigot
+ byte[] ext = this.extBlockIds.getValueArray();
for (int off = 0, off2 = 0; off < blkIds.length;) {
byte extid = ext[off2];
int l = (blkIds[off] & 0xFF) | ((extid & 0xF) << 8); // Even data
@@ -171,6 +172,12 @@ public class ChunkSection {
off++;
off2++;
}
+ // Spigot start
+ this.extBlockIds.detectAndProcessTrivialArray();
+ if (this.extBlockIds.isTrivialArray() && (this.extBlockIds.getTrivialArrayValue() == 0)) {
+ this.extBlockIds = null;
+ }
+ // Spigot end
}
this.nonEmptyBlockCount = cntNonEmpty;
this.tickingBlockCount = cntTicking;
@@ -224,12 +231,11 @@ public class ChunkSection {
public void setExtendedIdArray(NibbleArray nibblearray) {
// CraftBukkit start - Don't hang on to an empty nibble array
boolean empty = true;
- for (int i = 0; i < nibblearray.a.length; i++) {
- if (nibblearray.a[i] != 0) {
- empty = false;
- break;
- }
+ // Spigot start
+ if ((!nibblearray.isTrivialArray()) || (nibblearray.getTrivialArrayValue() != 0)) {
+ empty = false;
}
+ // Spigot end
if (empty) {
return;
@@ -253,11 +259,11 @@ public class ChunkSection {
// CraftBukkit start - Validate array lengths
private NibbleArray validateNibbleArray(NibbleArray nibbleArray) {
- if (nibbleArray != null && nibbleArray.a.length < 2048) {
- byte[] newArray = new byte[2048];
- System.arraycopy(nibbleArray.a, 0, newArray, 0, ((nibbleArray.a.length > 2048) ? 2048 : nibbleArray.a.length));
- nibbleArray = new NibbleArray(newArray, 4);
+ // Spigot start - fix for more awesome nibble arrays
+ if (nibbleArray != null && nibbleArray.getByteLength() < 2048) {
+ nibbleArray.resizeArray(2048);
}
+ // Spigot end
return nibbleArray;
}
diff --git a/src/main/java/net/minecraft/server/NibbleArray.java b/src/main/java/net/minecraft/server/NibbleArray.java
index 5d75a54..c9bc20c 100644
--- a/src/main/java/net/minecraft/server/NibbleArray.java
+++ b/src/main/java/net/minecraft/server/NibbleArray.java
@@ -1,13 +1,117 @@
package net.minecraft.server;
+import java.util.Arrays; // Spigot
+
public class NibbleArray {
- public final byte[] a;
+ private byte[] a; // Spigot - remove final, make private (anyone directly accessing this is broken already)
private final int b;
private final int c;
+ // Spigot start
+ private byte trivialValue;
+ private byte trivialByte;
+ private int length;
+ private static final int LEN2K = 2048; // Universal length used right now - optimize around this
+ private static final byte[][] TrivLen2k;
+
+ static {
+ TrivLen2k = new byte[16][];
+ for (int i = 0; i < 16; i++) {
+ TrivLen2k[i] = new byte[LEN2K];
+ Arrays.fill(TrivLen2k[i], (byte) (i | (i << 4)));
+ }
+ }
+
+ // Try to convert array to trivial array
+ public void detectAndProcessTrivialArray() {
+ trivialValue = (byte) (a[0] & 0xF);
+ trivialByte = (byte) (trivialValue | (trivialValue << 4));
+ for (int i = 0; i < a.length; i++) {
+ if (a[i] != trivialByte) return;
+ }
+ // All values matches, so array is trivial
+ this.length = a.length;
+ this.a = null;
+ }
+
+ // Force array to non-trivial state
+ public void forceToNonTrivialArray() {
+ if (this.a == null) {
+ this.a = new byte[this.length];
+ if (this.trivialByte != 0) {
+ Arrays.fill(this.a, this.trivialByte);
+ }
+ }
+ }
+
+ // Test if array is in trivial state
+ public boolean isTrivialArray() {
+ return (this.a == null);
+ }
+
+ // Get value of all elements (only valid if array is in trivial state)
+ public int getTrivialArrayValue() {
+ return this.trivialValue;
+ }
+
+ // Get logical length of byte array for nibble data (whether trivial or non-trivial)
+ public int getByteLength() {
+ if (this.a == null) {
+ return this.length;
+ } else {
+ return this.a.length;
+ }
+ }
+
+ // Return byte encoding of array (whether trivial or non-trivial) - returns read-only array if trivial (do not modify!)
+ public byte[] getValueArray() {
+ if (this.a != null) {
+ return this.a;
+ } else {
+ byte[] rslt;
+
+ if (this.length == LEN2K) { // All current uses are 2k long, but be safe
+ rslt = TrivLen2k[this.trivialValue];
+ } else {
+ rslt = new byte[this.length];
+ if (this.trivialByte != 0) {
+ Arrays.fill(rslt, this.trivialByte);
+ }
+ }
+ return rslt;
+ }
+ }
+
+ // Copy byte representation of array to given offset in given byte array
+ public int copyToByteArray(byte[] dest, int off) {
+ if (this.a == null) {
+ Arrays.fill(dest, off, off + this.length, this.trivialByte);
+ return off + this.length;
+ } else {
+ System.arraycopy(this.a, 0, dest, off, this.a.length);
+ return off + this.a.length;
+ }
+ }
+
+ // Resize array to given byte length
+ public void resizeArray(int len) {
+ if (this.a == null) {
+ this.length = len;
+ } else if (this.a.length != len) {
+ byte[] newa = new byte[len];
+ System.arraycopy(this.a, 0, newa, 0, ((this.a.length > len) ? len : this.a.length));
+ this.a = newa;
+ }
+ }
+ // Spigot end
public NibbleArray(int i, int j) {
- this.a = new byte[i >> 1];
+ // Spigot start
+ //this.a = new byte[i >> 1];
+ this.a = null; // Start off as trivial value (all same zero value)
+ this.length = i >> 1;
+ this.trivialByte = this.trivialValue = 0;
+ // Spigot end
this.b = j;
this.c = j + 4;
}
@@ -16,9 +120,11 @@ public class NibbleArray {
this.a = abyte;
this.b = i;
this.c = i + 4;
+ detectAndProcessTrivialArray(); // Spigot
}
public int a(int i, int j, int k) {
+ if (this.a == null) return this.trivialValue; // Spigot
int l = j << this.c | k << this.b | i;
int i1 = l >> 1;
int j1 = l & 1;
@@ -27,6 +133,18 @@ public class NibbleArray {
}
public void a(int i, int j, int k, int l) {
+ // Spigot start
+ if (this.a == null) {
+ if (l != this.trivialValue) { // Not same as trivial value, array no longer trivial
+ this.a = new byte[this.length];
+ if (this.trivialByte != 0) {
+ Arrays.fill(this.a, this.trivialByte);
+ }
+ } else {
+ return;
+ }
+ }
+ // Spigot end
int i1 = j << this.c | k << this.b | i;
int j1 = i1 >> 1;
int k1 = i1 & 1;
diff --git a/src/main/java/net/minecraft/server/OldChunkLoader.java b/src/main/java/net/minecraft/server/OldChunkLoader.java
index fcb9912..6ee28cc 100644
--- a/src/main/java/net/minecraft/server/OldChunkLoader.java
+++ b/src/main/java/net/minecraft/server/OldChunkLoader.java
@@ -94,9 +94,11 @@ public class OldChunkLoader {
nbttagcompound1.setByte("Y", (byte) (k & 255));
nbttagcompound1.setByteArray("Blocks", abyte);
- nbttagcompound1.setByteArray("Data", nibblearray.a);
- nbttagcompound1.setByteArray("SkyLight", nibblearray1.a);
- nbttagcompound1.setByteArray("BlockLight", nibblearray2.a);
+ // Spigot start - a -> getValueArray() accessor
+ nbttagcompound1.setByteArray("Data", nibblearray.getValueArray());
+ nbttagcompound1.setByteArray("SkyLight", nibblearray1.getValueArray());
+ nbttagcompound1.setByteArray("BlockLight", nibblearray2.getValueArray());
+ // Spigot end
nbttaglist.add(nbttagcompound1);
}
}
diff --git a/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java b/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java
index c7b799a..856e825 100644
--- a/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java
+++ b/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java
@@ -138,16 +138,16 @@ public class PacketPlayOutMapChunk extends Packet {
for (l = 0; l < achunksection.length; ++l) {
if (achunksection[l] != null && (!flag || !achunksection[l].isEmpty()) && (i & 1 << l) != 0) {
nibblearray = achunksection[l].getDataArray();
- System.arraycopy(nibblearray.a, 0, abyte, j, nibblearray.a.length);
- j += nibblearray.a.length;
+ nibblearray.copyToByteArray(abyte, j);
+ j += nibblearray.getByteLength();
}
}
for (l = 0; l < achunksection.length; ++l) {
if (achunksection[l] != null && (!flag || !achunksection[l].isEmpty()) && (i & 1 << l) != 0) {
nibblearray = achunksection[l].getEmittedLightArray();
- System.arraycopy(nibblearray.a, 0, abyte, j, nibblearray.a.length);
- j += nibblearray.a.length;
+ nibblearray.copyToByteArray(abyte, j);
+ j += nibblearray.getByteLength();
}
}
@@ -155,8 +155,8 @@ public class PacketPlayOutMapChunk extends Packet {
for (l = 0; l < achunksection.length; ++l) {
if (achunksection[l] != null && (!flag || !achunksection[l].isEmpty()) && (i & 1 << l) != 0) {
nibblearray = achunksection[l].getSkyLightArray();
- System.arraycopy(nibblearray.a, 0, abyte, j, nibblearray.a.length);
- j += nibblearray.a.length;
+ nibblearray.copyToByteArray(abyte, j);
+ j += nibblearray.getByteLength();
}
}
}
@@ -165,8 +165,8 @@ public class PacketPlayOutMapChunk extends Packet {
for (l = 0; l < achunksection.length; ++l) {
if (achunksection[l] != null && (!flag || !achunksection[l].isEmpty()) && achunksection[l].getExtendedIdArray() != null && (i & 1 << l) != 0) {
nibblearray = achunksection[l].getExtendedIdArray();
- System.arraycopy(nibblearray.a, 0, abyte, j, nibblearray.a.length);
- j += nibblearray.a.length;
+ nibblearray.copyToByteArray(abyte, j);
+ j += nibblearray.getByteLength();
}
}
}
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
index b2c6ef4..55f5225 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
@@ -174,7 +174,18 @@ public class CraftChunk implements Chunk {
}
if (cs[i].getExtendedIdArray() != null) { /* If we've got extended IDs */
- byte[] extids = cs[i].getExtendedIdArray().a;
+ // Spigot start
+ if (cs[i].getExtendedIdArray().isTrivialArray()) {
+ int tval = cs[i].getExtendedIdArray().getTrivialArrayValue();
+ if (tval != 0) {
+ tval = tval << 8;
+ for (int j = 0; j < 4096; j++) {
+ blockids[j] |= tval;
+ }
+ }
+ } else {
+ byte[] extids = cs[i].getExtendedIdArray().getValueArray();
+ // Spigot end
for (int j = 0; j < 2048; j++) {
short b = (short) (extids[j] & 0xFF);
@@ -186,21 +197,42 @@ public class CraftChunk implements Chunk {
blockids[j<<1] |= (b & 0x0F) << 8;
blockids[(j<<1)+1] |= (b & 0xF0) << 4;
}
+ } // Spigot
}
sectionBlockIDs[i] = blockids;
/* Get block data nibbles */
- sectionBlockData[i] = new byte[2048];
- System.arraycopy(cs[i].getDataArray().a, 0, sectionBlockData[i], 0, 2048);
+ // Spigot start
+ if (cs[i].getDataArray().isTrivialArray() && (cs[i].getDataArray().getTrivialArrayValue() == 0)) {
+ sectionBlockData[i] = emptyData;
+ } else {
+ sectionBlockData[i] = new byte[2048];
+ cs[i].getDataArray().copyToByteArray(sectionBlockData[i], 0);
+ }
if (cs[i].getSkyLightArray() == null) {
sectionSkyLights[i] = emptyData;
+ }
+ else if (cs[i].getSkyLightArray().isTrivialArray()) {
+ if (cs[i].getSkyLightArray().getTrivialArrayValue() == 0) {
+ sectionSkyLights[i] = emptyData;
+ } else if (cs[i].getSkyLightArray().getTrivialArrayValue() == 15) {
+ sectionSkyLights[i] = emptySkyLight;
+ } else {
+ sectionSkyLights[i] = new byte[2048];
+ cs[i].getSkyLightArray().copyToByteArray(sectionSkyLights[i], 0);
+ }
} else {
sectionSkyLights[i] = new byte[2048];
- System.arraycopy(cs[i].getSkyLightArray().a, 0, sectionSkyLights[i], 0, 2048);
+ cs[i].getSkyLightArray().copyToByteArray(sectionSkyLights[i], 0);
+ }
+ if (cs[i].getEmittedLightArray().isTrivialArray() && (cs[i].getEmittedLightArray().getTrivialArrayValue() == 0)) {
+ sectionEmitLights[i] = emptyData;
+ } else {
+ sectionEmitLights[i] = new byte[2048];
+ cs[i].getEmittedLightArray().copyToByteArray(sectionEmitLights[i], 0);
}
- sectionEmitLights[i] = new byte[2048];
- System.arraycopy(cs[i].getEmittedLightArray().a, 0, sectionEmitLights[i], 0, 2048);
+ // Spigot end
}
}
--
1.8.3.2

View File

@@ -1,6 +1,6 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: gsand <gsandowns@gmail.com>
Date: Tue, 15 Apr 2014 22:57:01 -0700
Date: Tue, 24 Jun 2014 08:01:42 -0500
Subject: [PATCH] Inverted Daylight Detector Toggle
@@ -8,17 +8,14 @@ diff --git a/src/main/java/net/minecraft/server/BlockDaylightDetector.java b/src
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/BlockDaylightDetector.java
+++ b/src/main/java/net/minecraft/server/BlockDaylightDetector.java
@@ -0,0 +0,0 @@ package net.minecraft.server;
@@ -0,0 +0,0 @@
package net.minecraft.server;
+import org.spigotmc.SpigotWorldConfig; // PaperSpigot
+
import java.util.Random;
+// PaperSpigot start
+import org.spigotmc.SpigotWorldConfig;
+// PaperSpigot end
+
public class BlockDaylightDetector extends BlockContainer {
private IIcon[] a = new IIcon[2];
@@ -0,0 +0,0 @@ public class BlockDaylightDetector extends BlockContainer {
f += (6.2831855F - f) * 0.2F;
}
@@ -26,21 +23,20 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- i1 = Math.round((float) i1 * MathHelper.cos(f));
- if (i1 < 0) {
- i1 = 0;
- }
+ // PaperSpigot start - Inverted Daylight Detectors
+ if (SpigotWorldConfig.InvertedDaylightDetectors) {
+ i1 = Math.round((float) i1 * MathHelper.cos(f) * -1 + 15);
+ if (i1 < 10) {
+ i1 = 0;
+ }
+
+ if (i1 > 9) {
+ i1 = 15;
+ }
}
- if (i1 > 15) {
- i1 = 15;
+ else {
+ if (i1 > 9) {
+ i1 = 15;
+ }
+ } else {
+ i1 = Math.round((float) i1 * MathHelper.cos(f));
+ if (i1 < 0) {
+ i1 = 0;
@@ -59,17 +55,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java
+++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java
@@ -0,0 +0,0 @@ public class SpigotWorldConfig
log( "Allow undead horse types to be leashed: " + allowUndeadHorseLeashing );
{
babyZombieMovementSpeed = getDouble( "baby-zombie-movement-speed", 0.5D );
}
+
+ public static boolean InvertedDaylightDetectors;
+ private void InvertedDaylightDetectors()
+ {
+ InvertedDaylightDetectors = getBoolean( "inverted-daylight-detectors", false);
+ log( "Inverted Redstone Lamps: " + InvertedDaylightDetectors );
+ }
+
public int maxBulkChunk;
private void bulkChunkCount()
{
}
--

View File

@@ -1,542 +0,0 @@
From 240e3a0afa47aa7e53f6f647c000dc5c627d5d95 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Thu, 10 Jan 2013 00:18:11 -0500
Subject: [PATCH] Improved Timings System
Tracks nearly every point of minecraft internals and plugin events to give a good quick overview on what is causing TPS loss.
diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java
index 8cc2efd..64ae190 100644
--- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
+++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java
@@ -137,6 +137,7 @@ public class ChunkProviderServer implements IChunkProvider {
boolean newChunk = false;
if (chunk == null) {
+ org.bukkit.craftbukkit.SpigotTimings.syncChunkLoadTimer.startTiming(); // Spigot
chunk = this.loadChunk(i, j);
if (chunk == null) {
if (this.chunkProvider == null) {
@@ -187,6 +188,7 @@ public class ChunkProviderServer implements IChunkProvider {
}
// CraftBukkit end
chunk.a(this, this, i, j);
+ org.bukkit.craftbukkit.SpigotTimings.syncChunkLoadTimer.stopTiming(); // Spigot
}
return chunk;
diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
index 04f5bc6..0999562 100644
--- a/src/main/java/net/minecraft/server/Entity.java
+++ b/src/main/java/net/minecraft/server/Entity.java
@@ -15,6 +15,7 @@ import org.bukkit.entity.Hanging;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Painting;
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.painting.PaintingBreakByEntityEvent;
@@ -114,6 +115,8 @@ public abstract class Entity {
public boolean valid; // CraftBukkit
public org.bukkit.projectiles.ProjectileSource projectileSource; // CraftBukkit - For projectiles only
+ public CustomTimingsHandler tickTimer = org.bukkit.craftbukkit.SpigotTimings.getEntityTimings(this); // Spigot
+
public int getId() {
return this.id;
}
@@ -426,7 +429,8 @@ public abstract class Entity {
if (d0 == 0 && d1 == 0 && d2 == 0 && this.vehicle == null && this.passenger == null) {
return;
}
- // CraftBukkit end
+ // CraftBukkit end
+ org.bukkit.craftbukkit.SpigotTimings.entityMoveTimer.startTiming(); // Spigot
if (this.X) {
this.boundingBox.d(d0, d1, d2);
this.locX = (this.boundingBox.a + this.boundingBox.d) / 2.0D;
@@ -735,6 +739,7 @@ public abstract class Entity {
this.world.methodProfiler.b();
}
+ org.bukkit.craftbukkit.SpigotTimings.entityMoveTimer.stopTiming(); // Spigot
}
protected String G() {
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 17b15f6..21cf068 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -37,6 +37,7 @@ import jline.console.ConsoleReader;
import joptsimple.OptionSet;
import org.bukkit.World.Environment;
+import org.bukkit.craftbukkit.SpigotTimings; // Spigot
import org.bukkit.craftbukkit.util.Waitable;
import org.bukkit.event.server.RemoteServerCommandEvent;
import org.bukkit.event.world.WorldSaveEvent;
@@ -545,6 +546,7 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo
protected void t() {}
protected void u() throws ExceptionWorldConflict { // CraftBukkit - added throws
+ SpigotTimings.serverTickTimer.startTiming(); // Spigot
long i = System.nanoTime();
++this.ticks;
@@ -596,6 +598,7 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo
public void v() {
this.methodProfiler.a("levels");
+ SpigotTimings.schedulerTimer.startTiming(); // Spigot
// CraftBukkit start
this.server.getScheduler().mainThreadHeartbeat(this.ticks);
@@ -604,7 +607,10 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo
processQueue.remove().run();
}
+ SpigotTimings.schedulerTimer.stopTiming(); // Spigot
+ SpigotTimings.chunkIOTickTimer.startTiming(); // Spigot
org.bukkit.craftbukkit.chunkio.ChunkIOExecutor.tick();
+ SpigotTimings.chunkIOTickTimer.stopTiming(); // Spigot
// Send time updates to everyone, it will get the right time from the world the player is in.
if (this.ticks % 20 == 0) {
@@ -655,7 +661,9 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo
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
@@ -664,16 +672,24 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo
}
this.methodProfiler.c("connection");
+ SpigotTimings.connectionTimer.startTiming(); // Spigot
this.ai().c();
+ SpigotTimings.connectionTimer.stopTiming(); // Spigot
this.methodProfiler.c("players");
+ SpigotTimings.playerListTimer.startTiming(); // Spigot
this.u.tick();
+ SpigotTimings.playerListTimer.stopTiming(); // Spigot
this.methodProfiler.c("tickables");
+ SpigotTimings.tickablesTimer.startTiming(); // Spigot
for (i = 0; i < this.n.size(); ++i) {
((IUpdatePlayerListBox) this.n.get(i)).a();
}
+ SpigotTimings.tickablesTimer.stopTiming(); // Spigot
this.methodProfiler.b();
+ SpigotTimings.serverTickTimer.stopTiming(); // Spigot
+ org.spigotmc.CustomTimingsHandler.tick(); // Spigot
}
public boolean getAllowNether() {
diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java
index ec45c30..92284eb 100644
--- a/src/main/java/net/minecraft/server/PlayerConnection.java
+++ b/src/main/java/net/minecraft/server/PlayerConnection.java
@@ -940,6 +940,7 @@ public class PlayerConnection implements PacketPlayInListener {
// CraftBukkit end
private void handleCommand(String s) {
+ org.bukkit.craftbukkit.SpigotTimings.playerCommandTimer.startTiming(); // Spigot
// CraftBukkit start - whole method
this.c.info(this.player.getName() + " issued server command: " + s);
@@ -949,18 +950,22 @@ public class PlayerConnection implements PacketPlayInListener {
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 2a3d647..78e17d7 100644
--- a/src/main/java/net/minecraft/server/TileEntity.java
+++ b/src/main/java/net/minecraft/server/TileEntity.java
@@ -7,10 +7,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 class TileEntity {
+ public CustomTimingsHandler tickTimer = org.bukkit.craftbukkit.SpigotTimings.getTileEntityTimings(this); // Spigot
private static final Logger a = LogManager.getLogger();
private static Map i = new HashMap();
private static Map j = new HashMap();
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
index 1fea307..40a3fcf 100644
--- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java
@@ -16,6 +16,7 @@ import org.bukkit.Bukkit;
import org.bukkit.block.BlockState;
import org.bukkit.craftbukkit.util.CraftMagicNumbers;
import org.bukkit.craftbukkit.util.LongHashSet;
+import org.bukkit.craftbukkit.SpigotTimings; // Spigot
import org.bukkit.generator.ChunkGenerator;
import org.bukkit.craftbukkit.CraftServer;
import org.bukkit.craftbukkit.CraftWorld;
@@ -132,6 +133,8 @@ public abstract class World implements IBlockAccess {
public ChunkGenerator generator;
public final org.spigotmc.SpigotWorldConfig spigotConfig; // Spigot
+ public final SpigotTimings.WorldTimingsHandler timings; // Spigot
+
public CraftWorld getWorld() {
return this.world;
}
@@ -215,6 +218,7 @@ public abstract class World implements IBlockAccess {
this.a();
this.getServer().addWorld(this.world); // CraftBukkit
+ timings = new SpigotTimings.WorldTimingsHandler(this); // Spigot
}
protected abstract IChunkProvider j();
@@ -1312,6 +1316,7 @@ public abstract class World implements IBlockAccess {
this.f.clear();
this.methodProfiler.c("regular");
+ 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);
@@ -1327,7 +1332,9 @@ public abstract class World implements IBlockAccess {
this.methodProfiler.a("tick");
if (!entity.dead) {
try {
+ SpigotTimings.tickEntityTimer.startTiming(); // Spigot
this.playerJoinedWorld(entity);
+ SpigotTimings.tickEntityTimer.stopTiming(); // Spigot
} catch (Throwable throwable1) {
crashreport = CrashReport.a(throwable1, "Ticking entity");
crashreportsystemdetails = crashreport.a("Entity being ticked");
@@ -1352,7 +1359,9 @@ public abstract class World implements IBlockAccess {
this.methodProfiler.b();
}
+ timings.entityTick.stopTiming(); // Spigot
this.methodProfiler.c("blockEntities");
+ timings.tileEntityTick.startTiming(); // Spigot
this.M = true;
// CraftBukkit start - From below, clean up tile entities before ticking them
if (!this.b.isEmpty()) {
@@ -1368,8 +1377,11 @@ public abstract class World implements IBlockAccess {
if (!tileentity.r() && tileentity.o() && this.isLoaded(tileentity.x, tileentity.y, tileentity.z)) {
try {
+ tileentity.tickTimer.startTiming(); // Spigot
tileentity.h();
+ tileentity.tickTimer.stopTiming(); // Spigot
} catch (Throwable throwable2) {
+ tileentity.tickTimer.stopTiming(); // Spigot
crashreport = CrashReport.a(throwable2, "Ticking block entity");
crashreportsystemdetails = crashreport.a("Block entity being ticked");
tileentity.a(crashreportsystemdetails);
@@ -1389,6 +1401,8 @@ public abstract class World implements IBlockAccess {
}
}
+ timings.tileEntityTick.stopTiming(); // Spigot
+ timings.tileEntityPending.startTiming(); // Spigot
this.M = false;
/* CraftBukkit start - Moved up
if (!this.b.isEmpty()) {
@@ -1429,6 +1443,7 @@ public abstract class World implements IBlockAccess {
this.a.clear();
}
+ timings.tileEntityPending.stopTiming(); // Spigot
this.methodProfiler.b();
this.methodProfiler.b();
}
@@ -1453,6 +1468,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.b(i - b0, 0, j - b0, i + b0, 0, j + b0) */) {
+ entity.tickTimer.startTiming(); // Spigot
// CraftBukkit end
entity.S = entity.locX;
entity.T = entity.locY;
@@ -1515,6 +1531,7 @@ public abstract class World implements IBlockAccess {
entity.passenger = null;
}
}
+ 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 e74f777..8cbfa30 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java
@@ -185,10 +185,13 @@ public class WorldServer extends World {
// 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.allowMonsters || this.allowAnimals) && (this instanceof WorldServer && this.players.size() > 0)) {
+ timings.mobSpawn.startTiming(); // Spigot
this.R.spawnEntities(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);
@@ -202,21 +205,36 @@ public class WorldServer extends World {
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.g();
+ 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.Q.a(this.getTime());
+ timings.doPortalForcer.stopTiming(); // Spigot
this.methodProfiler.b();
+ timings.doSounds.startTiming(); // Spigot
this.Z();
+ timings.doSounds.stopTiming(); // Spigot
+ timings.doChunkGC.startTiming(); // Spigot
this.getWorld().processChunkGC(); // CraftBukkit
+ timings.doChunkGC.stopTiming(); // Spigot
}
public BiomeMeta a(EnumCreatureType enumcreaturetype, int i, int j, int k) {
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..8340c13
--- /dev/null
+++ b/src/main/java/org/bukkit/craftbukkit/SpigotTimings.java
@@ -0,0 +1,125 @@
+package org.bukkit.craftbukkit;
+
+import net.minecraft.server.*;
+import org.spigotmc.CustomTimingsHandler;
+import org.bukkit.scheduler.BukkitTask;
+
+import java.util.HashMap;
+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("Player Tick");
+ 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 syncChunkLoadTimer = new CustomTimingsHandler("syncChunkLoad");
+
+ 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 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) {
+ String plugin = task.getOwner().getDescription().getFullName();
+ String name = "Task: " + plugin + " Runnable: " + ( (CraftTask) task ).getTaskClass().getSimpleName();
+ if (period > 0) {
+ name += "(interval:" + period +")";
+ } else {
+ name += "(Single)";
+ }
+ CustomTimingsHandler result = pluginTaskTimingMap.get(name);
+ if (result == null) {
+ result = new CustomTimingsHandler(name);
+ 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 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");
+ tracker = new CustomTimingsHandler(name + "tracker");
+ }
+ }
+}
diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftTask.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftTask.java
index 55db3ff..7d294c0 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;
+ CustomTimingsHandler timings = null; // Spigot
CraftTask() {
this(null, null, -1, -1);
}
@@ -50,7 +53,22 @@ class CraftTask implements BukkitTask, Runnable {
}
public void run() {
+ // Spigot start - Wrap custom timings on Tasks
+ if (!Bukkit.getServer().getPluginManager().useTimings()) {
+ task.run();
+ return;
+ }
+ if (timings == null && this.getOwner() != null && this.isSync()) {
+ timings = SpigotTimings.getPluginTaskTimings(this, period);
+ }
+ if (timings != null) {
+ timings.startTiming();
+ }
task.run();
+ if (timings != null) {
+ timings.stopTiming();
+ }
+ // Spigot end
}
long getPeriod() {
@@ -77,7 +95,7 @@ class CraftTask implements BukkitTask, Runnable {
this.next = next;
}
- Class<? extends Runnable> getTaskClass() {
+ public Class<? extends Runnable> getTaskClass() { // Spigot
return task.getClass();
}
--
1.9.1

View File

@@ -1,155 +0,0 @@
From ad6096243ee953cfd0208b1d9aaef93122d95a12 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
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
index d770e4e..39767d0 100644
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -40,6 +40,7 @@ public class Chunk {
public int r;
public long s;
private int x;
+ protected net.minecraft.util.gnu.trove.map.hash.TObjectIntHashMap<Class> entityCount = new net.minecraft.util.gnu.trove.map.hash.TObjectIntHashMap<Class>(); // Spigot
// CraftBukkit start - Neighbor loaded cache for chunk lighting and entity ticking
private int neighbors = 0x1 << 12;
@@ -635,6 +636,22 @@ public class Chunk {
entity.ai = k;
entity.aj = 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) {
@@ -651,6 +668,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 d(int i, int j, int k) {
diff --git a/src/main/java/net/minecraft/server/SpawnerCreature.java b/src/main/java/net/minecraft/server/SpawnerCreature.java
index 2ef15d2..23d6611 100644
--- a/src/main/java/net/minecraft/server/SpawnerCreature.java
+++ b/src/main/java/net/minecraft/server/SpawnerCreature.java
@@ -27,6 +27,23 @@ public final class SpawnerCreature {
return new ChunkPosition(k, i1, l);
}
+ // Spigot start - get entity count only from chunks being processed in b
+ private int getEntityCount(WorldServer server, Class oClass)
+ {
+ int i = 0;
+ for ( Long coord : this.a.keySet() )
+ {
+ int x = LongHash.msw( coord );
+ int z = LongHash.lsw( coord );
+ if ( !server.chunkProviderServer.unloadQueue.contains( coord ) && server.isChunkLoaded( x, z ) )
+ {
+ i += server.getChunkAt( x, z ).entityCount.get( oClass );
+ }
+ }
+ return i;
+ }
+ // Spigot end
+
public int spawnEntities(WorldServer worldserver, boolean flag, boolean flag1, boolean flag2) {
if (!flag && !flag1) {
return 0;
@@ -42,6 +59,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 l = -b0; l <= b0; ++l) {
for (int i1 = -b0; i1 <= b0; ++i1) {
@@ -89,13 +111,15 @@ public final class SpawnerCreature {
if (limit == 0) {
continue;
}
+ int mobcnt = 0;
// CraftBukkit end
- if ((!enumcreaturetype.d() || flag1) && (enumcreaturetype.d() || flag) && (!enumcreaturetype.e() || flag2) && worldserver.a(enumcreaturetype.a()) <= limit * this.a.size() / 256) { // CraftBukkit - use per-world limits
+ if ((!enumcreaturetype.d() || flag1) && (enumcreaturetype.d() || flag) && (!enumcreaturetype.e() || flag2) && (mobcnt = getEntityCount(worldserver, enumcreaturetype.a())) <= limit * this.a.size() / 256) { // Spigot - use per-world limits and use all loaded chunks
Iterator iterator = this.a.keySet().iterator();
+ int moblimit = (limit * this.a.size() / 256) - mobcnt + 1; // Spigot - up to 1 more than limit
label110:
- while (iterator.hasNext()) {
+ while (iterator.hasNext() && (moblimit > 0)) { // Spigot - while more allowed
// CraftBukkit start = use LongHash and LongObjectHashMap
long key = ((Long) iterator.next()).longValue();
@@ -160,6 +184,13 @@ public final class SpawnerCreature {
groupdataentity = entityinsentient.a(groupdataentity);
worldserver.addEntity(entityinsentient, SpawnReason.NATURAL);
// CraftBukkit end
+ // Spigot start
+ if ( --moblimit <= 0 )
+ {
+ // If we're past limit, stop spawn
+ continue label110;
+ }
+ // Spigot end
if (j2 >= entityinsentient.bB()) {
continue label110;
}
diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java
index 6cc3a91..46249d7 100644
--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java
+++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java
@@ -131,4 +131,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 );
+ }
}
--
1.9.1

View File

@@ -1,27 +0,0 @@
From 12c06cd7b3eb049c7e2a170566a9f72c96f29d17 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 40a3fcf..3e93cfd 100644
--- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java
@@ -1374,6 +1374,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.r() && tileentity.o() && this.isLoaded(tileentity.x, tileentity.y, tileentity.z)) {
try {
--
1.9.1

View File

@@ -1,522 +0,0 @@
From a972387b658808e5a9bdfaf911454fd39dda1300 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 0999562..e966314 100644
--- a/src/main/java/net/minecraft/server/Entity.java
+++ b/src/main/java/net/minecraft/server/Entity.java
@@ -91,7 +91,7 @@ public abstract class Entity {
public int ticksLived;
public int maxFireTicks;
public int fireTicks; // CraftBukkit - private -> public
- protected boolean inWater;
+ public boolean inWater; // Spigot - protected -> public
public int noDamageTicks;
private boolean justCreated;
protected boolean fireProof;
@@ -115,7 +115,13 @@ public abstract class Entity {
public boolean valid; // CraftBukkit
public org.bukkit.projectiles.ProjectileSource projectileSource; // CraftBukkit - For projectiles only
+ // Spigot start
public CustomTimingsHandler tickTimer = org.bukkit.craftbukkit.SpigotTimings.getEntityTimings(this); // Spigot
+ public final byte activationType = org.spigotmc.ActivationRange.initializeEntityActivationType(this);
+ public final boolean defaultActivationState;
+ public long activatedTick = 0;
+ public void inactiveTick() { }
+ // Spigot end
public int getId() {
return this.id;
@@ -142,7 +148,12 @@ public abstract class Entity {
this.setPosition(0.0D, 0.0D, 0.0D);
if (world != null) {
this.dimension = world.worldProvider.dimension;
+ // Spigot start
+ this.defaultActivationState = org.spigotmc.ActivationRange.initializeEntityActivationState(this, world.spigotConfig);
+ } else {
+ this.defaultActivationState = false;
}
+ // Spigot end
this.datawatcher = new DataWatcher(this);
this.datawatcher.a(0, 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 36ed831..7ddca48 100644
--- a/src/main/java/net/minecraft/server/EntityAgeable.java
+++ b/src/main/java/net/minecraft/server/EntityAgeable.java
@@ -6,6 +6,31 @@ public abstract class EntityAgeable extends EntityCreature {
private float bq;
public boolean ageLocked = false; // CraftBukkit
+ // Spigot start
+ @Override
+ public void inactiveTick()
+ {
+ super.inactiveTick();
+ if ( this.world.isStatic || this.ageLocked )
+ { // CraftBukkit
+ this.a( this.isBaby() );
+ } else
+ {
+ int i = this.getAge();
+
+ if ( i < 0 )
+ {
+ ++i;
+ this.setAge( i );
+ } else if ( i > 0 )
+ {
+ --i;
+ this.setAge( 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 3628774..3137bcf 100644
--- a/src/main/java/net/minecraft/server/EntityArrow.java
+++ b/src/main/java/net/minecraft/server/EntityArrow.java
@@ -15,7 +15,7 @@ public class EntityArrow extends Entity implements IProjectile {
private int f = -1;
private Block g;
private int h;
- private boolean inGround;
+ public boolean inGround = false; // Spigot - private -> public
public int fromPlayer;
public int shake;
public Entity shooter;
@@ -24,6 +24,18 @@ public class EntityArrow extends Entity implements IProjectile {
private double damage = 2.0D;
public int knockbackStrength; // CraftBukkit - private -> public
+ // Spigot Start
+ @Override
+ public void inactiveTick()
+ {
+ if ( this.inGround )
+ {
+ this.at += 19; // Despawn counter. First int after shooter
+ }
+ super.inactiveTick();
+ }
+ // Spigot End
+
public EntityArrow(World world) {
super(world);
this.j = 10.0D;
diff --git a/src/main/java/net/minecraft/server/EntityFireworks.java b/src/main/java/net/minecraft/server/EntityFireworks.java
index a228a2c..0a81006 100644
--- a/src/main/java/net/minecraft/server/EntityFireworks.java
+++ b/src/main/java/net/minecraft/server/EntityFireworks.java
@@ -5,6 +5,15 @@ public class EntityFireworks extends Entity {
private int ticksFlown;
public int expectedLifespan; // CraftBukkit - private -> public
+ // Spigot Start
+ @Override
+ public void inactiveTick()
+ {
+ this.ticksFlown += 19;
+ super.inactiveTick();
+ }
+ // Spigot End
+
public EntityFireworks(World world) {
super(world);
this.a(0.25F, 0.25F);
diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java
index b3bf43a..a180c89 100644
--- a/src/main/java/net/minecraft/server/EntityLiving.java
+++ b/src/main/java/net/minecraft/server/EntityLiving.java
@@ -80,6 +80,13 @@ public abstract class EntityLiving extends Entity {
public int maxAirTicks = 300;
ArrayList<org.bukkit.inventory.ItemStack> drops = null;
// CraftBukkit end
+ // Spigot start
+ public void inactiveTick()
+ {
+ super.inactiveTick();
+ ++this.aU; // Above all the floats
+ }
+ // Spigot end
public EntityLiving(World world) {
super(world);
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
index 3e93cfd..0cb803e 100644
--- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java
@@ -1316,6 +1316,7 @@ public abstract class World implements IBlockAccess {
this.f.clear();
this.methodProfiler.c("regular");
+ 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) {
@@ -1472,9 +1473,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.b(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.S = entity.locX;
diff --git a/src/main/java/org/bukkit/craftbukkit/SpigotTimings.java b/src/main/java/org/bukkit/craftbukkit/SpigotTimings.java
index 8340c13..541dfe4 100644
--- a/src/main/java/org/bukkit/craftbukkit/SpigotTimings.java
+++ b/src/main/java/org/bukkit/craftbukkit/SpigotTimings.java
@@ -30,6 +30,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..06284ad
--- /dev/null
+++ b/src/main/java/org/spigotmc/ActivationRange.java
@@ -0,0 +1,296 @@
+package org.spigotmc;
+
+import java.util.ArrayList;
+import java.util.List;
+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.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.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.CraftWorld;
+import org.bukkit.craftbukkit.SpigotTimings;
+
+public class ActivationRange
+{
+
+ static AxisAlignedBB maxBB = AxisAlignedBB.a( 0, 0, 0, 0, 0, 0 );
+ static AxisAlignedBB miscBB = AxisAlignedBB.a( 0, 0, 0, 0, 0, 0 );
+ static AxisAlignedBB animalBB = AxisAlignedBB.a( 0, 0, 0, 0, 0, 0 );
+ static AxisAlignedBB monsterBB = AxisAlignedBB.a( 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;
+ }
+
+ /**
+ * Utility method to grow an AABB without creating a new AABB or touching
+ * the pool, so we can re-use ones we have.
+ *
+ * @param target
+ * @param source
+ * @param x
+ * @param y
+ * @param z
+ */
+ public static void growBB(AxisAlignedBB target, AxisAlignedBB source, int x, int y, int z)
+ {
+ target.a = source.a - x;
+ target.b = source.b - y;
+ target.c = source.c - z;
+ target.d = source.d + x;
+ target.e = source.e + y;
+ target.f = source.f + z;
+ }
+
+ /**
+ * 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 ( Entity player : new ArrayList<Entity>( world.players ) )
+ {
+
+ player.activatedTick = MinecraftServer.currentTick;
+ growBB( maxBB, player.boundingBox, maxRange, 256, maxRange );
+ growBB( miscBB, player.boundingBox, miscActivationRange, 256, miscActivationRange );
+ growBB( animalBB, player.boundingBox, animalActivationRange, 256, animalActivationRange );
+ growBB( monsterBB, player.boundingBox, 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 ( List<Entity> slice : chunk.entitySlices )
+ {
+ for ( Entity entity : slice )
+ {
+ if ( MinecraftServer.currentTick > entity.activatedTick )
+ {
+ if ( entity.defaultActivationState )
+ {
+ entity.activatedTick = MinecraftServer.currentTick;
+ continue;
+ }
+ switch ( entity.activationType )
+ {
+ case 1:
+ if ( monsterBB.b( entity.boundingBox ) )
+ {
+ entity.activatedTick = MinecraftServer.currentTick;
+ }
+ break;
+ case 2:
+ if ( animalBB.b( entity.boundingBox ) )
+ {
+ entity.activatedTick = MinecraftServer.currentTick;
+ }
+ break;
+ case 3:
+ default:
+ if ( miscBB.b( entity.boundingBox ) )
+ {
+ 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 /* isInWater */ || entity.fireTicks > 0 )
+ {
+ return true;
+ }
+ if ( !( entity instanceof EntityArrow ) )
+ {
+ if ( !entity.onGround || entity.passenger != null
+ || entity.vehicle != null )
+ {
+ return true;
+ }
+ } else if ( !( (EntityArrow) entity ).inGround )
+ {
+ return true;
+ }
+ // special cases.
+ if ( entity instanceof EntityLiving )
+ {
+ EntityLiving living = (EntityLiving) entity;
+ if ( living.attackTicks > 0 || living.hurtTicks > 0 || living.effects.size() > 0 )
+ {
+ return true;
+ }
+ if ( entity instanceof EntityCreature && ( (EntityCreature) entity ).target != null )
+ {
+ return true;
+ }
+ if ( entity instanceof EntityVillager && ( (EntityVillager) entity ).bY() /* Getter for first boolean */ )
+ {
+ return true;
+ }
+ if ( entity instanceof EntityAnimal )
+ {
+ EntityAnimal animal = (EntityAnimal) entity;
+ if ( animal.isBaby() || animal.ce() /*love*/ )
+ {
+ return true;
+ }
+ if ( entity instanceof EntitySheep && ( (EntitySheep) entity ).isSheared() )
+ {
+ 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();
+ 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
+ if ( isActive && !entity.world.areChunksLoaded( x, 0, z, 16 ) )
+ {
+ 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 46249d7..ed2836a 100644
--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java
+++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java
@@ -138,4 +138,15 @@ public class SpigotWorldConfig
mobSpawnRange = (byte) getInt( "mob-spawn-range", 4 );
log( "Mob Spawn Range: " + mobSpawnRange );
}
+
+ 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 );
+ }
}
--
1.9.1

View File

@@ -1,692 +0,0 @@
From 64fa9cb277665dcf02463a4ad93472e5a5f10cb8 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..f1690a2
--- /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().length;
+
+ // 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();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/spigotmc/SpigotConfig.java b/src/main/java/org/spigotmc/SpigotConfig.java
index fd5997d..98fcb47 100644
--- a/src/main/java/org/spigotmc/SpigotConfig.java
+++ b/src/main/java/org/spigotmc/SpigotConfig.java
@@ -35,6 +35,7 @@ public class SpigotConfig
static int version;
static Map<String, Command> commands;
/*========================================================================*/
+ private static Metrics metrics;
public static void init()
{
@@ -55,6 +56,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)
--
1.9.1

View File

@@ -1,54 +0,0 @@
From 6d1e63d8c59ecc36efdbd54880bb0ca1af9bda2c 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 f9aaf4a..f32f40d 100644
--- a/src/main/java/net/minecraft/server/ItemStack.java
+++ b/src/main/java/net/minecraft/server/ItemStack.java
@@ -279,7 +279,13 @@ public final class ItemStack {
return this.item.getMaxDurability();
}
+ // Spigot start
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.g()) {
return false;
} else {
@@ -294,7 +300,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;
}
}
@@ -307,7 +322,7 @@ public final class ItemStack {
public void damage(int i, EntityLiving entityliving) {
if (!(entityliving instanceof EntityHuman) || !((EntityHuman) entityliving).abilities.canInstantlyBuild) {
if (this.g()) {
- if (this.isDamaged(i, entityliving.aH())) {
+ if (this.isDamaged(i, entityliving.aH(), entityliving)) {
entityliving.a(this);
--this.count;
if (entityliving instanceof EntityHuman) {
--
1.9.1

View File

@@ -1,23 +0,0 @@
From 057734283eef7808469dd78e94ea86d4177b8c82 Mon Sep 17 00:00:00 2001
From: md_5 <md_5@live.com.au>
Date: Sun, 17 Mar 2013 19:02:50 +1100
Subject: [PATCH] Faster UUID for entities
It is overkill to create a new SecureRandom on each entity create and then use it to make a new Entity ID for every entity instance created. Instead we will just use a pseudo random UUID based off the random instance we already have.
diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
index 0b6e9cf..9179baa 100644
--- a/src/main/java/net/minecraft/server/Entity.java
+++ b/src/main/java/net/minecraft/server/Entity.java
@@ -142,7 +142,7 @@ public abstract class Entity {
this.random = new Random();
this.maxFireTicks = 1;
this.justCreated = true;
- this.uniqueID = UUID.randomUUID();
+ this.uniqueID = new UUID(random.nextLong(), random.nextLong()); // Spigot
this.as = EnumEntitySize.SIZE_2;
this.world = world;
this.setPosition(0.0D, 0.0D, 0.0D);
--
1.9.1

View File

@@ -1,36 +0,0 @@
From f2da21e80183a5a42d4043949909cb82663ba5cd 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 77717d5..1533dd4 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftSign.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftSign.java
@@ -14,6 +14,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(sign.lines, 0, lines, 0, lines.length);
}
@@ -34,7 +40,7 @@ public class CraftSign extends CraftBlockState implements Sign {
public boolean update(boolean force, boolean applyPhysics) {
boolean result = super.update(force, applyPhysics);
- if (result) {
+ if (result && sign != null) { // Spigot, add null check
sign.lines = sanitizeLines(lines);
sign.update();
}
--
1.9.1

View File

@@ -1,109 +0,0 @@
From 2d698107a735cb7fdfce121d5518a1c8d3761447 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 70b0181..c0766d6 100644
--- a/src/main/java/net/minecraft/server/EntityTracker.java
+++ b/src/main/java/net/minecraft/server/EntityTracker.java
@@ -92,6 +92,7 @@ public class EntityTracker {
public void addEntity(Entity entity, int i, int j, boolean flag) {
org.spigotmc.AsyncCatcher.catchOp( "entity track"); // Spigot
+ i = org.spigotmc.TrackingRange.getEntityTrackingRange(entity, i); // Spigot
if (i > this.e) {
i = this.e;
}
diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java
index ed2836a..6421bf2 100644
--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java
+++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java
@@ -149,4 +149,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;
+ }
+ }
+}
--
1.9.1

View File

@@ -1,74 +0,0 @@
From 55030705cb3ebfa20d6d1f6891eee6b1758a1ca3 Mon Sep 17 00:00:00 2001
From: md_5 <md_5@live.com.au>
Date: Sat, 23 Mar 2013 19:08:41 +1100
Subject: [PATCH] Limit Custom Map Rendering
The default CraftBukkit render sequence for maps is ridiculously slow. By only using it when a custom renderer has been added (rarely in most cases), we can fallback to the Vanilla renderer for general usage. This leads to a much higher effiency overall, especially if no plugins are rendering such maps.
diff --git a/src/main/java/net/minecraft/server/WorldMapHumanTracker.java b/src/main/java/net/minecraft/server/WorldMapHumanTracker.java
index ec708d1..ef56386 100644
--- a/src/main/java/net/minecraft/server/WorldMapHumanTracker.java
+++ b/src/main/java/net/minecraft/server/WorldMapHumanTracker.java
@@ -37,23 +37,29 @@ public class WorldMapHumanTracker {
int i;
int j;
- org.bukkit.craftbukkit.map.RenderData render = this.worldMap.mapView.render((org.bukkit.craftbukkit.entity.CraftPlayer) trackee.getBukkitEntity()); // CraftBukkit
+ // Spigot start
+ boolean custom = this.worldMap.mapView.renderers.size() > 1 || !(this.worldMap.mapView.renderers.get(0) instanceof org.bukkit.craftbukkit.map.CraftMapRenderer);
+ org.bukkit.craftbukkit.map.RenderData render = (custom) ? this.worldMap.mapView.render((org.bukkit.craftbukkit.entity.CraftPlayer) trackee.getBukkitEntity()) : null; // CraftBukkit
if (--this.g < 0) {
this.g = 4;
- abyte = new byte[render.cursors.size() * 3 + 1]; // CraftBukkit
+ abyte = new byte[((custom) ? render.cursors.size() : this.worldMap.g.size()) * 3 + 1]; // CraftBukkit
abyte[0] = 1;
i = 0;
// CraftBukkit start
- for (i = 0; i < render.cursors.size(); ++i) {
- org.bukkit.map.MapCursor cursor = render.cursors.get(i);
- if (!cursor.isVisible()) continue;
- abyte[i * 3 + 1] = (byte) (cursor.getRawType() << 4 | cursor.getDirection() & 15);
- abyte[i * 3 + 2] = (byte) cursor.getX();
- abyte[i * 3 + 3] = (byte) cursor.getY();
+ // Spigot start
+ for (Iterator iterator = ((custom) ? render.cursors.iterator() : this.worldMap.g.values().iterator()); iterator.hasNext(); ++i) {
+ org.bukkit.map.MapCursor cursor = (custom) ? (org.bukkit.map.MapCursor) iterator.next() : null;
+ if (cursor != null && !cursor.isVisible()) continue;
+ WorldMapDecoration deco = (custom) ? null : (WorldMapDecoration) iterator.next();
+
+ abyte[i * 3 + 1] = (byte) (((custom) ? cursor.getRawType() : deco.type) << 4 | ((custom) ? cursor.getDirection() : deco.rotation) & 15);
+ abyte[i * 3 + 2] = (byte) ((custom) ? cursor.getX() : deco.locX);
+ abyte[i * 3 + 3] = (byte) ((custom) ? cursor.getY() : deco.locY);
}
+ // Spigot end
// CraftBukkit end
boolean flag = !itemstack.A();
@@ -88,7 +94,7 @@ public class WorldMapHumanTracker {
abyte1[2] = (byte) j;
for (int i1 = 0; i1 < abyte1.length - 3; ++i1) {
- abyte1[i1 + 3] = render.buffer[(i1 + j) * 128 + i]; // CraftBukkit
+ abyte1[i1 + 3] = ((custom) ? render.buffer : this.worldMap.colors)[(i1 + j) * 128 + i];
}
this.c[i] = -1;
diff --git a/src/main/java/org/bukkit/craftbukkit/map/CraftMapView.java b/src/main/java/org/bukkit/craftbukkit/map/CraftMapView.java
index 1a150d9..c9f0027 100644
--- a/src/main/java/org/bukkit/craftbukkit/map/CraftMapView.java
+++ b/src/main/java/org/bukkit/craftbukkit/map/CraftMapView.java
@@ -18,7 +18,7 @@ import org.bukkit.map.MapView;
public final class CraftMapView implements MapView {
private final Map<CraftPlayer, RenderData> renderCache = new HashMap<CraftPlayer, RenderData>();
- private final List<MapRenderer> renderers = new ArrayList<MapRenderer>();
+ public final List<MapRenderer> renderers = new ArrayList<MapRenderer>(); // Spigot
private final Map<MapRenderer, Map<CraftPlayer, CraftMapCanvas>> canvases = new HashMap<MapRenderer, Map<CraftPlayer, CraftMapCanvas>>();
protected final WorldMap worldMap;
--
1.9.1

View File

@@ -1,23 +0,0 @@
From 7b20e3085dc0b346f9ffb9f625465e53562ffb70 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 84dcfcc..a30f217 100644
--- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
+++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
@@ -71,7 +71,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;
--
1.9.1

View File

@@ -1,66 +0,0 @@
From cabbfafe4301f951c0eb3d810af5350f45fc4cff 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 900ed68..829f4a3 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 a = new HashMap();
+ public static final Map a = new HashMap(); // CraftBukkit - private -> public
public static synchronized RegionFile a(File file1, int i, int j) {
File file2 = new File(file1, "region");
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index 95742fa..24d4e76 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -85,6 +85,8 @@ import net.minecraft.server.MinecraftServer;
import net.minecraft.server.MobEffectList;
import net.minecraft.server.PropertyManager;
import net.minecraft.server.ServerCommand;
+import net.minecraft.server.RegionFile;
+import net.minecraft.server.RegionFileCache;
import net.minecraft.server.ServerNBTManager;
import net.minecraft.server.WorldLoaderServer;
import net.minecraft.server.WorldManager;
@@ -1019,6 +1021,30 @@ 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;
}
--
1.9.1

View File

@@ -1,23 +0,0 @@
From 85469a82bd3aa027e89d9b03d6731193eeb238f7 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 bb535c2..93968bd 100644
--- a/src/main/java/net/minecraft/server/PropertyManager.java
+++ b/src/main/java/net/minecraft/server/PropertyManager.java
@@ -52,7 +52,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);
}
--
1.9.1

View File

@@ -1,71 +0,0 @@
From 064f79546c3d9ed48f2535918baddf905fe22540 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 bb28c12..c0836e4 100644
--- a/src/main/java/net/minecraft/server/IRecipe.java
+++ b/src/main/java/net/minecraft/server/IRecipe.java
@@ -11,4 +11,6 @@ public interface IRecipe {
ItemStack b();
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 cc444db..867dd07 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 int width;
private int height;
private ItemStack[] items;
- private ItemStack result;
+ public ItemStack result; // Spigot
private boolean e;
public ShapedRecipes(int i, int j, ItemStack[] aitemstack, ItemStack itemstack) {
@@ -156,4 +156,11 @@ public class ShapedRecipes implements IRecipe {
this.e = true;
return this;
}
+
+ // 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 0fab83c..21181fb 100644
--- a/src/main/java/net/minecraft/server/ShapelessRecipes.java
+++ b/src/main/java/net/minecraft/server/ShapelessRecipes.java
@@ -11,7 +11,7 @@ import org.bukkit.craftbukkit.inventory.CraftShapelessRecipe;
public class ShapelessRecipes implements IRecipe {
- private final ItemStack result;
+ public final ItemStack result; // Spigot
private final List ingredients;
public ShapelessRecipes(ItemStack itemstack, List list) {
@@ -75,4 +75,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
}
--
1.9.1

View File

@@ -1,31 +0,0 @@
From 37cf2bb33b714e62f1221b6494352bff100c1627 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 09e7223..8c8a173 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().e();
+ }
+
+ @Override
+ public void setDamage(double damage)
+ {
+ getHandle().b( damage );
+ }
};
public Arrow.Spigot spigot()
--
1.9.1

View File

@@ -1,133 +0,0 @@
From 331a947c4c7512a3f2ee370832717fe9229ed725 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 48a882a..51cbdad 100644
--- a/src/main/java/net/minecraft/server/TileEntityHopper.java
+++ b/src/main/java/net/minecraft/server/TileEntityHopper.java
@@ -189,12 +189,18 @@ public class TileEntityHopper extends TileEntity implements IHopper {
}
if (flag) {
- this.c(8);
+ this.c(world.spigotConfig.hopperTransfer); // Spigot
this.update();
return true;
}
}
+ // Spigot start
+ if ( !this.j() )
+ {
+ this.c( world.spigotConfig.hopperCheck );
+ }
+ // Spigot end
return false;
} else {
return false;
@@ -246,7 +252,7 @@ public class TileEntityHopper extends TileEntity implements IHopper {
if (this.getItem(j) != null) {
ItemStack itemstack = this.getItem(j).cloneItemStack();
// CraftBukkit start - Call event when pushing items into other inventories
- CraftItemStack oitemstack = CraftItemStack.asCraftMirror(this.splitStack(j, 1));
+ CraftItemStack oitemstack = CraftItemStack.asCraftMirror(this.splitStack(j, world.spigotConfig.hopperAmount)); // Spigot
Inventory destinationInventory;
// Have to special case large chests as they work oddly
@@ -260,11 +266,11 @@ public class TileEntityHopper extends TileEntity implements IHopper {
this.getWorld().getServer().getPluginManager().callEvent(event);
if (event.isCancelled()) {
this.setItem(j, itemstack);
- this.c(8); // Delay hopper checks
+ this.c(world.spigotConfig.hopperTransfer); // Spigot
return false;
}
+ int origCount = event.getItem().getAmount(); // Spigot
ItemStack itemstack1 = addItem(iinventory, CraftItemStack.asNMSCopy(event.getItem()), i);
-
if (itemstack1 == null || itemstack1.count == 0) {
if (event.getItem().equals(oitemstack)) {
iinventory.update();
@@ -274,7 +280,7 @@ public class TileEntityHopper extends TileEntity implements IHopper {
// CraftBukkit end
return true;
}
-
+ itemstack.count -= origCount - itemstack1.count; // Spigot
this.setItem(j, itemstack);
}
}
@@ -379,7 +385,7 @@ public class TileEntityHopper extends TileEntity implements IHopper {
if (itemstack != null && canTakeItemFromInventory(iinventory, itemstack, i, j)) {
ItemStack itemstack1 = itemstack.cloneItemStack();
// 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
@@ -396,13 +402,14 @@ public class TileEntityHopper extends TileEntity implements IHopper {
iinventory.setItem(i, itemstack1);
if (ihopper instanceof TileEntityHopper) {
- ((TileEntityHopper) ihopper).c(8); // Delay hopper checks
+ ((TileEntityHopper) ihopper).c(ihopper.getWorld().spigotConfig.hopperTransfer); // Spigot
} else if (ihopper instanceof EntityMinecartHopper) {
- ((EntityMinecartHopper) ihopper).l(4); // Delay hopper minecart checks
+ ((EntityMinecartHopper) ihopper).l(ihopper.getWorld().spigotConfig.hopperTransfer / 2); // Spigot
}
return false;
}
+ int origCount = event.getItem().getAmount(); // Spigot
ItemStack itemstack2 = addItem(ihopper, CraftItemStack.asNMSCopy(event.getItem()), -1);
if (itemstack2 == null || itemstack2.count == 0) {
@@ -415,6 +422,7 @@ public class TileEntityHopper extends TileEntity implements IHopper {
return true;
}
+ itemstack1.count -= origCount - itemstack2.count; // Spigot
iinventory.setItem(i, itemstack1);
}
@@ -502,7 +510,7 @@ public class TileEntityHopper extends TileEntity implements IHopper {
if (flag) {
if (iinventory instanceof TileEntityHopper) {
- ((TileEntityHopper) iinventory).c(8);
+ ((TileEntityHopper) iinventory).c(((TileEntityHopper) iinventory).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 6421bf2..956c628 100644
--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java
+++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java
@@ -164,4 +164,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 );
+ }
}
--
1.9.1

View File

@@ -1,32 +0,0 @@
From 296a8b176d18def1f52aec81873d7c68083d39fe Mon Sep 17 00:00:00 2001
From: md_5 <md_5@live.com.au>
Date: Tue, 11 Jun 2013 11:54:32 +1000
Subject: [PATCH] Prevent Shutdown Hang
Prevents server hanging if players disconnect during the shutdown sequence.
diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/java/net/minecraft/server/PlayerList.java
index 1dbce5c..2a15271 100644
--- a/src/main/java/net/minecraft/server/PlayerList.java
+++ b/src/main/java/net/minecraft/server/PlayerList.java
@@ -1152,8 +1152,15 @@ public abstract class PlayerList {
}
public void u() {
- for (int i = 0; i < this.players.size(); ++i) {
- ((EntityPlayer) this.players.get(i)).playerConnection.disconnect(this.server.server.getShutdownMessage()); // CraftBukkit - add custom shutdown message
+ while (!this.players.isEmpty()) {
+ // Spigot start
+ EntityPlayer p = (EntityPlayer) this.players.get( 0 );
+ p.playerConnection.disconnect( this.server.server.getShutdownMessage() );
+ if ( ( !this.players.isEmpty() ) && ( this.players.get( 0 ) == p ) )
+ {
+ this.players.remove( 0 ); // Prevent shutdown hang if already disconnected
+ }
+ // Spigot end
}
}
--
1.9.1

View File

@@ -1,102 +0,0 @@
From 722ea3f2c86af3f7e5819e4766f6211b3898cd17 Mon Sep 17 00:00:00 2001
From: Andy Shulman <andy.shulman@hotmail.com>
Date: Mon, 15 Apr 2013 20:06:37 -0500
Subject: [PATCH] Implement SpawnerSpawnEvent.
Adds BUKKIT-267
diff --git a/src/main/java/net/minecraft/server/MobSpawnerAbstract.java b/src/main/java/net/minecraft/server/MobSpawnerAbstract.java
index 06f9b1f..b97ac4b 100644
--- a/src/main/java/net/minecraft/server/MobSpawnerAbstract.java
+++ b/src/main/java/net/minecraft/server/MobSpawnerAbstract.java
@@ -5,7 +5,11 @@ import java.util.Collection;
import java.util.Iterator;
import java.util.List;
-import org.bukkit.event.entity.CreatureSpawnEvent; // CraftBukkit
+// CraftBukkit start
+import org.bukkit.craftbukkit.event.CraftEventFactory;
+import org.bukkit.event.entity.CreatureSpawnEvent;
+import org.bukkit.event.entity.SpawnerSpawnEvent;
+// CraftBukkit end
public abstract class MobSpawnerAbstract {
@@ -128,7 +132,12 @@ public abstract class MobSpawnerAbstract {
entity.f(nbttagcompound);
if (entity.world != null) {
- entity.world.addEntity(entity, CreatureSpawnEvent.SpawnReason.SPAWNER); // CraftBukkit
+ // CraftBukkit start - call SpawnerSpawnEvent, abort if cancelled
+ SpawnerSpawnEvent event = CraftEventFactory.callSpawnerSpawnEvent(entity, this.b(), this.c(), this.d());
+ if (!event.isCancelled()) {
+ entity.world.addEntity(entity, CreatureSpawnEvent.SpawnReason.SPAWNER); // CraftBukkit
+ }
+ // CraftBukkit end
}
NBTTagCompound nbttagcompound1;
@@ -152,6 +161,11 @@ public abstract class MobSpawnerAbstract {
entity2.f(nbttagcompound2);
entity2.setPositionRotation(entity1.locX, entity1.locY, entity1.locZ, entity1.yaw, entity1.pitch);
+ // CraftBukkit start - call SpawnerSpawnEvent, skip if cancelled
+ SpawnerSpawnEvent event = CraftEventFactory.callSpawnerSpawnEvent(entity2, this.b(), this.c(), this.d());
+ if (event.isCancelled()) {
+ continue;
+ }
if (entity.world != null) {
entity.world.addEntity(entity2, CreatureSpawnEvent.SpawnReason.SPAWNER); // CraftBukkit
}
@@ -163,7 +177,12 @@ public abstract class MobSpawnerAbstract {
}
} else if (entity instanceof EntityLiving && entity.world != null) {
((EntityInsentient) entity).a((GroupDataEntity) null);
- this.a().addEntity(entity, CreatureSpawnEvent.SpawnReason.SPAWNER); // CraftBukkit
+ // CraftBukkit start - call SpawnerSpawnEvent, abort if cancelled
+ SpawnerSpawnEvent event = CraftEventFactory.callSpawnerSpawnEvent(entity, this.b(), this.c(), this.d());
+ if (!event.isCancelled()) {
+ this.a().addEntity(entity, CreatureSpawnEvent.SpawnReason.SPAWNER); // CraftBukkit
+ }
+ // CraftBukkit end
}
return entity;
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
index 522d6b0..9a3c728 100644
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
@@ -36,6 +36,7 @@ import org.bukkit.Statistic.Type;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.BlockState;
+import org.bukkit.block.CreatureSpawner;
import org.bukkit.craftbukkit.CraftServer;
import org.bukkit.craftbukkit.CraftStatistic;
import org.bukkit.craftbukkit.CraftWorld;
@@ -141,6 +142,22 @@ public class CraftEventFactory {
}
/**
+ * Mob spawner event
+ */
+ public static SpawnerSpawnEvent callSpawnerSpawnEvent(Entity spawnee, int spawnerX, int spawnerY, int spawnerZ) {
+ org.bukkit.craftbukkit.entity.CraftEntity entity = spawnee.getBukkitEntity();
+ BlockState state = entity.getWorld().getBlockAt(spawnerX, spawnerY, spawnerZ).getState();
+
+ if (!(state instanceof CreatureSpawner)) {
+ state = null;
+ }
+
+ SpawnerSpawnEvent event = new SpawnerSpawnEvent(entity, (CreatureSpawner) state);
+ entity.getServer().getPluginManager().callEvent(event);
+ return event;
+ }
+
+ /**
* Bucket methods
*/
public static PlayerBucketEmptyEvent callPlayerBucketEmptyEvent(EntityHuman who, int clickedX, int clickedY, int clickedZ, int clickedFace, ItemStack itemInHand) {
--
1.9.1

View File

@@ -1,31 +0,0 @@
From c13065ba778749814980d29d17c6804df9d6d368 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
}
}
--
1.9.1

View File

@@ -1,37 +0,0 @@
From 8123ddb10e530f8f513253a31a957a0c0cc2b545 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 253a448..c581334 100644
--- a/src/main/java/net/minecraft/server/PlayerConnection.java
+++ b/src/main/java/net/minecraft/server/PlayerConnection.java
@@ -942,7 +942,7 @@ public class PlayerConnection implements PacketPlayInListener {
private void handleCommand(String s) {
org.bukkit.craftbukkit.SpigotTimings.playerCommandTimer.startTiming(); // Spigot
// CraftBukkit start - whole method
- this.c.info(this.player.getName() + " issued server command: " + s);
+ if ( org.spigotmc.SpigotConfig.logCommands ) this.c.info(this.player.getName() + " issued server command: " + s); // Spigot
CraftPlayer player = this.getPlayer();
diff --git a/src/main/java/org/spigotmc/SpigotConfig.java b/src/main/java/org/spigotmc/SpigotConfig.java
index 98fcb47..afd6b56 100644
--- a/src/main/java/org/spigotmc/SpigotConfig.java
+++ b/src/main/java/org/spigotmc/SpigotConfig.java
@@ -130,4 +130,10 @@ public class SpigotConfig
config.addDefault( path, def );
return config.getString( path, config.getString( path ) );
}
+
+ public static boolean logCommands;
+ private static void logCommands()
+ {
+ logCommands = getBoolean( "commands.log", true );
+ }
}
--
1.9.1

View File

@@ -1,53 +0,0 @@
From 8757372e0d0333692126e407de47cdba81e824b4 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 24d4e76..7b68460 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -1600,6 +1600,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 afd6b56..20634f1 100644
--- a/src/main/java/org/spigotmc/SpigotConfig.java
+++ b/src/main/java/org/spigotmc/SpigotConfig.java
@@ -136,4 +136,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 );
+ }
}
--
1.9.1

View File

@@ -1,107 +0,0 @@
From e35855cf232e8ca71cad50484959b98e247ae142 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 9cc9581..b98079c 100644
--- a/src/main/java/net/minecraft/server/HandshakeListener.java
+++ b/src/main/java/net/minecraft/server/HandshakeListener.java
@@ -64,11 +64,11 @@ public class HandshakeListener implements PacketHandshakingInListener {
// CraftBukkit end
if (packethandshakinginsetprotocol.d() > 5) {
- chatcomponenttext = new ChatComponentText("Outdated server! I\'m still on 1.7.9");
+ chatcomponenttext = new ChatComponentText( org.spigotmc.SpigotConfig.outdatedServerMessage ); // Spigot
this.b.handle(new PacketLoginOutDisconnect(chatcomponenttext), new GenericFutureListener[0]);
this.b.close(chatcomponenttext);
} else if (packethandshakinginsetprotocol.d() < 5) {
- chatcomponenttext = new ChatComponentText("Outdated client! Please use 1.7.9");
+ chatcomponenttext = new ChatComponentText( org.spigotmc.SpigotConfig.outdatedClientMessage ); // Spigot
this.b.handle(new PacketLoginOutDisconnect(chatcomponenttext), new GenericFutureListener[0]);
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 2a15271..e156a5a 100644
--- a/src/main/java/net/minecraft/server/PlayerList.java
+++ b/src/main/java/net/minecraft/server/PlayerList.java
@@ -365,7 +365,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 (this.k.isBanned(socketaddress) && !this.j.get(gameprofile).e()) { // Should be hasExpired
IpBanEntry ipbanentry = this.k.get(socketaddress);
@@ -379,7 +379,7 @@ public abstract class PlayerList {
} else {
// return this.players.size() >= this.maxPlayers ? "The server is full!" : null;
if (this.players.size() >= this.maxPlayers) {
- 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 7b68460..73d92fd 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -706,11 +706,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 20634f1..efcd193 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.file.YamlConfiguration;
@@ -153,4 +154,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 {}";
+ 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 < 4)
+ {
+ 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 ) );
+ }
}
--
1.9.1

View File

@@ -1,51 +0,0 @@
From 7d365125cbb0941da8dbc0894c426f4bad3cae07 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 39767d0..5ef6865 100644
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -929,7 +929,7 @@ public class Chunk {
}
this.m = 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.p();
}
}
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
index 0cb803e..dcbf520 100644
--- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java
@@ -2107,7 +2107,7 @@ public abstract class World implements IBlockAccess {
}
this.methodProfiler.a("playerCheckLight");
- if (!this.players.isEmpty()) {
+ if (spigotConfig.randomLightUpdates && !this.players.isEmpty()) { // Spigot
i = this.random.nextInt(this.players.size());
entityhuman = (EntityHuman) this.players.get(i);
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 956c628..8868ea3 100644
--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java
+++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java
@@ -179,4 +179,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 );
+ }
}
--
1.9.1

View File

@@ -1,63 +0,0 @@
From d35c0a27272e11eb32a8202860148c501ee2956f 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 5ef6865..d74586e 100644
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -783,6 +783,15 @@ public class Chunk {
while (iterator.hasNext()) {
TileEntity tileentity = (TileEntity) iterator.next();
+ // Spigot Start
+ if ( tileentity instanceof IInventory )
+ {
+ for ( org.bukkit.craftbukkit.entity.CraftHumanEntity h : new ArrayList<org.bukkit.craftbukkit.entity.CraftHumanEntity>( (List) ( (IInventory) tileentity ).getViewers() ) )
+ {
+ h.getHandle().closeInventory();
+ }
+ }
+ // Spigot End
this.world.a(tileentity);
}
@@ -792,6 +801,15 @@ public class Chunk {
java.util.Iterator<Object> iter = this.entitySlices[i].iterator();
while (iter.hasNext()) {
Entity entity = (Entity) iter.next();
+ // Spigot Start
+ if ( entity instanceof IInventory )
+ {
+ for ( org.bukkit.craftbukkit.entity.CraftHumanEntity h : new ArrayList<org.bukkit.craftbukkit.entity.CraftHumanEntity>( (List) ( (IInventory) entity ).getViewers() ) )
+ {
+ 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)
diff --git a/src/main/java/net/minecraft/server/EntityMinecartContainer.java b/src/main/java/net/minecraft/server/EntityMinecartContainer.java
index b599eeb..2065e5a 100644
--- a/src/main/java/net/minecraft/server/EntityMinecartContainer.java
+++ b/src/main/java/net/minecraft/server/EntityMinecartContainer.java
@@ -149,6 +149,12 @@ public abstract class EntityMinecartContainer extends EntityMinecartAbstract imp
}
public void b(int i) {
+ // Spigot Start
+ for ( HumanEntity human : new java.util.ArrayList<HumanEntity>( transaction ) )
+ {
+ human.closeInventory();
+ }
+ // Spigot End
this.b = false;
super.b(i);
}
--
1.9.1

View File

@@ -1,27 +0,0 @@
From d4363413bc30737605f456aedc7a6f1b85e6de7b 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 c581334..662eb5a 100644
--- a/src/main/java/net/minecraft/server/PlayerConnection.java
+++ b/src/main/java/net/minecraft/server/PlayerConnection.java
@@ -1056,6 +1056,13 @@ public class PlayerConnection implements PacketPlayInListener {
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 )
+ {
+ disconnect( "Cannot interact with self!" );
+ return;
+ }
+ // Spigot End
this.player.v();
if (entity != null) {
--
1.9.1

View File

@@ -1,36 +0,0 @@
From d6302f62b973c46d0f259f951e2dd9c9785de896 Mon Sep 17 00:00:00 2001
From: md_5 <md_5@live.com.au>
Date: Tue, 2 Jul 2013 09:07:54 +1000
Subject: [PATCH] Lower Chunk Compression
Use a chunk compression level of 4 - this provides an optimal balance between speed and compression.
diff --git a/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java b/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java
index 856e825..09b34e9 100644
--- a/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java
+++ b/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java
@@ -24,7 +24,7 @@ public class PacketPlayOutMapChunk extends Packet {
this.b = chunk.locZ;
this.inflatedBuffer = flag;
ChunkMap chunkmap = a(chunk, flag, i);
- Deflater deflater = new Deflater(-1);
+ Deflater deflater = new Deflater(4); // Spigot
this.d = chunkmap.c;
this.c = chunkmap.b;
diff --git a/src/main/java/net/minecraft/server/PacketPlayOutMapChunkBulk.java b/src/main/java/net/minecraft/server/PacketPlayOutMapChunkBulk.java
index 3eac231..bf3a139 100644
--- a/src/main/java/net/minecraft/server/PacketPlayOutMapChunkBulk.java
+++ b/src/main/java/net/minecraft/server/PacketPlayOutMapChunkBulk.java
@@ -22,7 +22,7 @@ public class PacketPlayOutMapChunkBulk extends Packet {
@Override
protected Deflater initialValue() {
// Don't use higher compression level, slows things down too much
- return new Deflater(6);
+ return new Deflater(4); // Spigot 6 -> 4
}
};
// CraftBukkit end
--
1.9.1

View File

@@ -1,51 +0,0 @@
From c0e0deda0bfc821c7e234f387f9b28d079c692a8 Mon Sep 17 00:00:00 2001
From: md_5 <md_5@live.com.au>
Date: Tue, 2 Jul 2013 20:32:49 +1000
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 e74e6d6..2a192e1 100644
--- a/src/main/java/net/minecraft/server/Entity.java
+++ b/src/main/java/net/minecraft/server/Entity.java
@@ -1461,6 +1461,7 @@ public abstract class Entity {
}
}
// CraftBukkit end
+ pluginManager.callEvent( new org.spigotmc.event.entity.EntityDismountEvent( this.getBukkitEntity(), this.vehicle.getBukkitEntity() ) ); // Spigot
this.setPositionRotation(this.vehicle.locX, this.vehicle.boundingBox.b + (double) this.vehicle.length, this.vehicle.locZ, this.yaw, this.pitch);
this.vehicle.passenger = null;
@@ -1496,6 +1497,17 @@ public abstract class Entity {
}
}
// CraftBukkit end
+ // Spigot Start
+ if ( entity.world.isChunkLoaded( (int) entity.locX >> 4, (int) entity.locZ >> 4 ) )
+ {
+ org.spigotmc.event.entity.EntityMountEvent event = new org.spigotmc.event.entity.EntityMountEvent( this.getBukkitEntity(), entity.getBukkitEntity() );
+ pluginManager.callEvent( event );
+ if ( event.isCancelled() )
+ {
+ return;
+ }
+ }
+ // Spigot End
if (this.vehicle != null) {
this.vehicle.passenger = null;
diff --git a/src/main/java/net/minecraft/server/EntityHuman.java b/src/main/java/net/minecraft/server/EntityHuman.java
index 381ba31..1fc7a22 100644
--- a/src/main/java/net/minecraft/server/EntityHuman.java
+++ b/src/main/java/net/minecraft/server/EntityHuman.java
@@ -323,6 +323,7 @@ public abstract class EntityHuman extends EntityLiving implements ICommandListen
public void setPassengerOf(Entity entity) {
// CraftBukkit end
if (this.vehicle != null && entity == null) {
+ world.getServer().getPluginManager().callEvent( new org.spigotmc.event.entity.EntityDismountEvent( this.getBukkitEntity(), this.vehicle.getBukkitEntity() ) ); // Spigot
// CraftBukkit start - use parent method instead to correctly fire VehicleExitEvent
Entity originalVehicle = this.vehicle;
// First statement moved down, second statement handled in parent method.
--
1.9.1

View File

@@ -1,26 +0,0 @@
From b3497c286e366bd54813d98a74c2041fe298fb28 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 e156a5a..4c5d77e 100644
--- a/src/main/java/net/minecraft/server/PlayerList.java
+++ b/src/main/java/net/minecraft/server/PlayerList.java
@@ -492,6 +492,11 @@ public abstract class PlayerList {
Player respawnPlayer = this.cserver.getPlayer(entityplayer1);
PlayerRespawnEvent respawnEvent = new PlayerRespawnEvent(respawnPlayer, location, isBedSpawn);
this.cserver.getPluginManager().callEvent(respawnEvent);
+ // Spigot Start
+ if (entityplayer.playerConnection.isDisconnected()) {
+ return entityplayer;
+ }
+ // Spigot End
location = respawnEvent.getRespawnLocation();
entityplayer.reset();
--
1.9.1

View File

@@ -1,22 +0,0 @@
From 71ca2b1633955973b3a1d8fd74fda0f79fbe9826 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 8e01414..e0469bb 100644
--- a/src/main/java/net/minecraft/server/BlockRedstoneTorch.java
+++ b/src/main/java/net/minecraft/server/BlockRedstoneTorch.java
@@ -11,7 +11,7 @@ import org.bukkit.event.block.BlockRedstoneEvent; // CraftBukkit
public class BlockRedstoneTorch extends BlockTorch {
private boolean isOn;
- private static Map b = new HashMap();
+ private static Map b = new java.util.WeakHashMap(); // Spigot
private boolean a(World world, int i, int j, int k, boolean flag) {
if (!b.containsKey(world)) {
--
1.9.1

View File

@@ -1,85 +0,0 @@
From 87d34d87e622b96a4369337e20b7fc5135a5c4db 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 1fc7a22..d091bcf 100644
--- a/src/main/java/net/minecraft/server/EntityHuman.java
+++ b/src/main/java/net/minecraft/server/EntityHuman.java
@@ -430,7 +430,7 @@ public abstract class EntityHuman extends EntityLiving implements ICommandListen
List list = this.world.getEntities(this, axisalignedbb);
- if (list != null) {
+ if (list != null && this.R()) { // Spigot: Add this.R() condition
for (int i = 0; i < list.size(); ++i) {
Entity entity = (Entity) list.get(i);
diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java
index a180c89..dbe58b1 100644
--- a/src/main/java/net/minecraft/server/EntityLiving.java
+++ b/src/main/java/net/minecraft/server/EntityLiving.java
@@ -1495,7 +1495,7 @@ public abstract class EntityLiving extends Entity {
protected void bn() {
List list = this.world.getEntities(this, this.boundingBox.grow(0.20000000298023224D, 0.0D, 0.20000000298023224D));
- if (list != null && !list.isEmpty()) {
+ if (this.R() && list != null && !list.isEmpty()) { // Spigot: Add this.R() condition
for (int i = 0; i < list.size(); ++i) {
Entity entity = (Entity) list.get(i);
diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java
index 3a0d679..367472d 100644
--- a/src/main/java/net/minecraft/server/EntityPlayer.java
+++ b/src/main/java/net/minecraft/server/EntityPlayer.java
@@ -63,6 +63,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 Q()
+ {
+ return this.collidesWithEntities && super.Q();
+ }
+
+ @Override
+ public boolean R()
+ {
+ return this.collidesWithEntities && super.R();
+ }
+ // 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 4d2374d..a5002d8 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -1290,6 +1290,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().k = collides; // First boolean of Entity
+ }
};
public Player.Spigot spigot()
--
1.9.1

View File

@@ -1,27 +0,0 @@
From c26ed0885fe7d9a9a567a91574c8d77aa8ab9068 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 21cf068..007fb86 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -583,11 +583,11 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo
this.g[this.ticks % 100] = System.nanoTime() - i;
this.methodProfiler.b();
this.methodProfiler.a("snooper");
- if (!this.l.d() && this.ticks > 100) {
+ if (getSnooperEnabled() && !this.l.d() && this.ticks > 100) { // Spigot
this.l.a();
}
- if (this.ticks % 6000 == 0) {
+ if (getSnooperEnabled() && this.ticks % 6000 == 0) { // Spigot
this.l.b();
}
--
1.9.1

View File

@@ -1,25 +0,0 @@
From 324a21ec3861a69a7dd3837fb0f4c1b813f00b34 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 e026c1f..96d763b 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
@@ -403,6 +403,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();
+ }
};
public Spigot spigot()
--
1.9.1

View File

@@ -1,31 +0,0 @@
From dcee57c4729f137fa10d740b99cfe99c2d46ddbf 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 a5002d8..fd64fcd 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -1162,7 +1162,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();
}
@@ -1170,7 +1170,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();
}
--
1.9.1

View File

@@ -1,24 +0,0 @@
From 2732a7fe07b2bad4ca22938a4e99b26bc2f74665 Mon Sep 17 00:00:00 2001
From: md_5 <md_5@live.com.au>
Date: Sat, 14 Sep 2013 10:16:38 +1000
Subject: [PATCH] Update Inventory and Health for PlayerConsumeItemEvent
diff --git a/src/main/java/net/minecraft/server/EntityHuman.java b/src/main/java/net/minecraft/server/EntityHuman.java
index d091bcf..c3a0dc3 100644
--- a/src/main/java/net/minecraft/server/EntityHuman.java
+++ b/src/main/java/net/minecraft/server/EntityHuman.java
@@ -277,6 +277,10 @@ public abstract class EntityHuman extends EntityLiving implements ICommandListen
// Update client
if (this instanceof EntityPlayer) {
((EntityPlayer) this).playerConnection.sendPacket(new PacketPlayOutSetSlot((byte) 0, activeContainer.a((IInventory) this.inventory, this.inventory.itemInHandIndex).index, this.f));
+ // Spigot Start
+ ((EntityPlayer) this).getBukkitEntity().updateInventory();
+ ((EntityPlayer) this).getBukkitEntity().updateScaledHealth();
+ // Spigot End
}
return;
}
--
1.9.1

View File

@@ -1,35 +0,0 @@
From eadf3b254418dadd61660c01c83a9970b6637ff7 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 e943676..7320a88 100644
--- a/src/main/java/net/minecraft/server/BlockTNT.java
+++ b/src/main/java/net/minecraft/server/BlockTNT.java
@@ -54,7 +54,7 @@ public class BlockTNT extends Block {
public boolean interact(World world, int i, int j, int k, EntityHuman entityhuman, int l, float f, float f1, float f2) {
if (entityhuman.bE() != null && entityhuman.bE().getItem() == Items.FLINT_AND_STEEL) {
- this.a(world, i, j, k, 1, entityhuman);
+ this.a(world, i, j, k, 1, (EntityLiving) entityhuman); // Spigot - Fix decompile error!
world.setAir(i, j, k);
entityhuman.bE().damage(1, entityhuman);
return true;
@@ -68,6 +68,11 @@ public class BlockTNT extends Block {
EntityArrow entityarrow = (EntityArrow) entity;
if (entityarrow.isBurning()) {
+ // CraftBukkit start
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(entityarrow, i, j, k, Blocks.AIR, 0).isCancelled()) {
+ return;
+ }
+ // CraftBukkit end
this.a(world, i, j, k, 1, entityarrow.shooter instanceof EntityLiving ? (EntityLiving) entityarrow.shooter : null);
world.setAir(i, j, k);
}
--
1.9.1

View File

@@ -1,50 +0,0 @@
From 9dcf96ddd617afe5aa500b21e38280ee90a58e22 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 97308d0..4d336d8 100644
--- a/src/main/java/net/minecraft/server/StructureGenerator.java
+++ b/src/main/java/net/minecraft/server/StructureGenerator.java
@@ -178,7 +178,15 @@ public abstract class StructureGenerator extends WorldGenBase {
private void a(World world) {
if (this.e == null) {
+ // Spigot Start
+ if ( world.spigotConfig.saveStructureInfo )
+ {
this.e = (PersistentStructure) world.a(PersistentStructure.class, this.a());
+ } else
+ {
+ this.e = new PersistentStructure( this.a() );
+ }
+ // Spigot End
if (this.e == null) {
this.e = new PersistentStructure(this.a());
world.a(this.a(), (PersistentBase) this.e);
diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java
index 8868ea3..48ae475 100644
--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java
+++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java
@@ -186,4 +186,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 when updating to 1.7!" );
+ log( "*** WARNING *** Please use this option with caution, SpigotMC is not responsible for any issues this option may cause in the future!" );
+ }
+ }
}
--
1.9.1

View File

@@ -1,38 +0,0 @@
From 5d9bc356a50009e0cb33eaaad4473133e5747660 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 95beb11..0f1bcc7 100644
--- a/src/main/java/net/minecraft/server/EntityItem.java
+++ b/src/main/java/net/minecraft/server/EntityItem.java
@@ -104,7 +104,7 @@ public class EntityItem extends Entity {
}
// ++this.age; // CraftBukkit - Moved up
- if (!this.world.isStatic && this.age >= 6000) {
+ if (!this.world.isStatic && 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 48ae475..6d31363 100644
--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java
+++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java
@@ -198,4 +198,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 itemDespawnRate;
+ private void itemDespawnRate()
+ {
+ itemDespawnRate = getInt( "item-despawn-rate", 6000 );
+ log( "Item Despawn Rate: " + itemDespawnRate );
+ }
}
--
1.9.1

View File

@@ -1,49 +0,0 @@
From 955229fac012049a2960f52747893a238fa9e11e 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 8bf1afd..99ce73e 100644
--- a/src/main/java/net/minecraft/server/PlayerConnection.java
+++ b/src/main/java/net/minecraft/server/PlayerConnection.java
@@ -106,6 +106,7 @@ public class PlayerConnection implements PacketPlayInListener {
private float lastPitch = Float.MAX_VALUE;
private float lastYaw = Float.MAX_VALUE;
private boolean justTeleported = false;
+ private boolean hasMoved; // Spigot
// For the PacketPlayOutBlockPlace hack :(
Long lastPacket;
@@ -202,6 +203,18 @@ public class PlayerConnection implements PacketPlayInListener {
// 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.
@@ -230,7 +243,7 @@ public class PlayerConnection implements PacketPlayInListener {
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
PlayerMoveEvent event = new PlayerMoveEvent(player, from, to);
this.server.getPluginManager().callEvent(event);
--
1.9.1

View File

@@ -1,29 +0,0 @@
From 7ed63c7e4413fb7651ff02e9c6dd98e41df54b44 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 fd64fcd..5142f71 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -1303,6 +1303,15 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
getHandle().collidesWithEntities = collides;
getHandle().k = collides; // First boolean of Entity
}
+
+ @Override
+ public void respawn()
+ {
+ if ( getHealth() <= 0 && isOnline() )
+ {
+ server.getServer().getPlayerList().moveToWorld( getHandle(), 0, false );
+ }
+ }
};
public Player.Spigot spigot()
--
1.9.1

View File

@@ -1,28 +0,0 @@
From ba03f5b43e813c037b5c9ef26affb404c2c5bd6d Mon Sep 17 00:00:00 2001
From: md_5 <md_5@live.com.au>
Date: Wed, 9 Oct 2013 18:20:05 +1100
Subject: [PATCH] Fix BrewingStands Removing NBT / Potions
diff --git a/src/main/java/net/minecraft/server/BlockBrewingStand.java b/src/main/java/net/minecraft/server/BlockBrewingStand.java
index 3287d77..eabea5a 100644
--- a/src/main/java/net/minecraft/server/BlockBrewingStand.java
+++ b/src/main/java/net/minecraft/server/BlockBrewingStand.java
@@ -86,7 +86,13 @@ public class BlockBrewingStand extends BlockContainer {
entityitem.motX = (double) ((float) this.a.nextGaussian() * f3);
entityitem.motY = (double) ((float) this.a.nextGaussian() * f3 + 0.2F);
entityitem.motZ = (double) ((float) this.a.nextGaussian() * f3);
- world.addEntity(entityitem);
+ // Spigot Start
+ if ( itemstack.hasTag() )
+ {
+ entityitem.getItemStack().setTag( (NBTTagCompound) itemstack.getTag().clone() );
+ }
+ // Spigot End
+ world.addEntity( entityitem );
}
}
}
--
1.9.1

View File

@@ -1,38 +0,0 @@
From 86e5aaa7611adc75078d9a7e7c939d1d08cf5207 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 3137bcf..13903e9 100644
--- a/src/main/java/net/minecraft/server/EntityArrow.java
+++ b/src/main/java/net/minecraft/server/EntityArrow.java
@@ -156,7 +156,7 @@ public class EntityArrow extends Entity implements IProjectile {
if (block == this.g && i == this.h) {
++this.at;
- if (this.at == 1200) {
+ if (this.at >= world.spigotConfig.arrowDespawnRate) { // 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 6d31363..1814b4f 100644
--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java
+++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java
@@ -205,4 +205,11 @@ public class SpigotWorldConfig
itemDespawnRate = getInt( "item-despawn-rate", 6000 );
log( "Item Despawn Rate: " + itemDespawnRate );
}
+
+ public int arrowDespawnRate;
+ private void arrowDespawnRate()
+ {
+ arrowDespawnRate = getInt( "arrow-despawn-rate", 1200 );
+ log( "Arrow Despawn Rate: " + arrowDespawnRate );
+ }
}
--
1.9.1

View File

@@ -1,38 +0,0 @@
From 848300ae6ec63841bb95388db51ad6aaac03a095 Mon Sep 17 00:00:00 2001
From: md_5 <md_5@live.com.au>
Date: Sun, 1 Dec 2013 17:52:14 +1100
Subject: [PATCH] Fix packed ice generation
diff --git a/src/main/java/net/minecraft/server/WorldGenPackedIce2.java b/src/main/java/net/minecraft/server/WorldGenPackedIce2.java
index c0db754..a830758 100644
--- a/src/main/java/net/minecraft/server/WorldGenPackedIce2.java
+++ b/src/main/java/net/minecraft/server/WorldGenPackedIce2.java
@@ -41,13 +41,13 @@ public class WorldGenPackedIce2 extends WorldGenerator {
Block block = world.getType(i + l1, j + j1, k + i2);
if (block.getMaterial() == Material.AIR || block == Blocks.DIRT || block == Blocks.SNOW_BLOCK || block == Blocks.ICE) {
- this.setType(world, i + l1, j + j1, k + i2, Blocks.PACKED_ICE);
+ world.setTypeUpdate(i + l1, j + j1, k + i2, Blocks.PACKED_ICE); // Spigot
}
if (j1 != 0 && k1 > 1) {
block = world.getType(i + l1, j - j1, k + i2);
if (block.getMaterial() == Material.AIR || block == Blocks.DIRT || block == Blocks.SNOW_BLOCK || block == Blocks.ICE) {
- this.setType(world, i + l1, j - j1, k + i2, Blocks.PACKED_ICE);
+ world.setTypeUpdate(i + l1, j - j1, k + i2, Blocks.PACKED_ICE); // Spigot
}
}
}
@@ -78,7 +78,7 @@ public class WorldGenPackedIce2 extends WorldGenerator {
Block block1 = world.getType(i + j2, l1, k + k1);
if (block1.getMaterial() == Material.AIR || block1 == Blocks.DIRT || block1 == Blocks.SNOW_BLOCK || block1 == Blocks.ICE || block1 == Blocks.PACKED_ICE) {
- this.setType(world, i + j2, l1, k + k1, Blocks.PACKED_ICE);
+ world.setTypeUpdate(i + j2, l1, k + k1, Blocks.PACKED_ICE); // Spigot
--l1;
--k2;
if (k2 <= 0) {
--
1.9.1

View File

@@ -1,305 +0,0 @@
From 59d64d815676dfe80e9002afb00792dae5e6c677 Mon Sep 17 00:00:00 2001
From: md_5 <md_5@live.com.au>
Date: Sat, 23 Feb 2013 12:33:20 +1100
Subject: [PATCH] Watchdog Thread.
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 007fb86..51f1761 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -498,6 +498,7 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo
this.a(crashreport);
} finally {
try {
+ org.spigotmc.WatchdogThread.doStop();
this.stop();
this.isStopped = true;
} catch (Throwable throwable1) {
@@ -688,6 +689,7 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo
SpigotTimings.tickablesTimer.stopTiming(); // Spigot
this.methodProfiler.b();
+ org.spigotmc.WatchdogThread.tick(); // Spigot
SpigotTimings.serverTickTimer.stopTiming(); // Spigot
org.spigotmc.CustomTimingsHandler.tick(); // 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 efcd193..2b499fe 100644
--- a/src/main/java/org/spigotmc/SpigotConfig.java
+++ b/src/main/java/org/spigotmc/SpigotConfig.java
@@ -178,4 +178,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 );
+ }
+ }
+}
--
1.9.1

View File

@@ -1,21 +0,0 @@
From 228dfc549a66b9b3e971cf3a88527e93567e078a Mon Sep 17 00:00:00 2001
From: md_5 <md_5@live.com.au>
Date: Tue, 3 Dec 2013 11:07:48 +1100
Subject: [PATCH] Clear Flower Pot on Drop
diff --git a/src/main/java/net/minecraft/server/BlockFlowerPot.java b/src/main/java/net/minecraft/server/BlockFlowerPot.java
index ca6f4f0..0fa90b4 100644
--- a/src/main/java/net/minecraft/server/BlockFlowerPot.java
+++ b/src/main/java/net/minecraft/server/BlockFlowerPot.java
@@ -90,6 +90,7 @@ public class BlockFlowerPot extends BlockContainer {
if (tileentityflowerpot != null && tileentityflowerpot.a() != null) {
this.a(world, i, j, k, new ItemStack(tileentityflowerpot.a(), 1, tileentityflowerpot.b()));
+ tileentityflowerpot.a( null, 0 ); // Spigot
}
super.remove(world, i, j, k, block, l);
--
1.9.1

View File

@@ -1,30 +0,0 @@
From 6e808e5174020875a3c1a70123844c0fd0358b44 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 d74586e..a48785b 100644
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -953,7 +953,15 @@ public class Chunk {
}
public boolean k() {
- return this.m && 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 ChunkCoordIntPair l() {
--
1.9.1

View File

@@ -1,40 +0,0 @@
From 59e7429c3cc3e420533c554666dc7d490e6b6439 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 604a7af..d419f0f 100644
--- a/src/main/java/net/minecraft/server/PacketPlayInChat.java
+++ b/src/main/java/net/minecraft/server/PacketPlayInChat.java
@@ -43,7 +43,25 @@ public class PacketPlayInChat extends Packet {
}
// CraftBukkit end
- public void handle(PacketListener packetlistener) {
+ // 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 handle(final PacketListener packetlistener)
+ {
+ if ( a() )
+ {
+ executors.submit( new Runnable()
+ {
+
+ @Override
+ public void run()
+ {
+ PacketPlayInChat.this.a( (PacketPlayInListener) packetlistener );
+ }
+ } );
+ return;
+ }
+ // Spigot End
this.a((PacketPlayInListener) packetlistener);
}
}
--
1.9.1

View File

@@ -1,40 +0,0 @@
From 2f2e091205757111702bd087de1e26032403a6d2 Mon Sep 17 00:00:00 2001
From: ItsHarry <info@itsjerryandharry.com>
Date: Thu, 5 Dec 2013 21:58:11 +0100
Subject: [PATCH] Allow Teleportation of Vehicles and Passengers
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
index 5142f71..7d16bab 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -459,9 +459,11 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
return false;
}
- if (entity.vehicle != null || entity.passenger != null) {
- return false;
- }
+ // Spigot Start
+ // if (entity.vehicle != null || entity.passenger != null) {
+ // return false;
+ // }
+ // Spigot End
// From = Players current Location
Location from = this.getLocation();
@@ -475,6 +477,11 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
if (event.isCancelled()) {
return false;
}
+
+ // Spigot Start
+ eject();
+ leaveVehicle();
+ // Spigot End
// Update the From Location
from = event.getFrom();
--
1.9.1

View File

@@ -1,21 +0,0 @@
From 5a3944c0a289434760d2e5448640423518e6810b Mon Sep 17 00:00:00 2001
From: md_5 <md_5@live.com.au>
Date: Sun, 8 Dec 2013 16:52:42 +1100
Subject: [PATCH] Remove OS X Special Chars from Signs
diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java
index 99ce73e..c7e40fe 100644
--- a/src/main/java/net/minecraft/server/PlayerConnection.java
+++ b/src/main/java/net/minecraft/server/PlayerConnection.java
@@ -1582,6 +1582,7 @@ public class PlayerConnection implements PacketPlayInListener {
for (j = 0; j < 4; ++j) {
boolean flag = true;
+ packetplayinupdatesign.f()[j] = packetplayinupdatesign.f()[j].replaceAll( "\uF700", "" ).replaceAll( "\uF701", "" ); // Spigot - Mac OSX sends weird chars
if (packetplayinupdatesign.f()[j].length() > 15) {
flag = false;
--
1.9.1

View File

@@ -1,431 +0,0 @@
From 625906f2c19b34c027c32c7bba15a8355f9bc6b5 Mon Sep 17 00:00:00 2001
From: md_5 <md_5@live.com.au>
Date: Thu, 16 May 2013 18:51:05 +1000
Subject: [PATCH] Orebfuscator
diff --git a/src/main/java/net/minecraft/server/EntityFallingBlock.java b/src/main/java/net/minecraft/server/EntityFallingBlock.java
index bc51217..8335e89 100644
--- a/src/main/java/net/minecraft/server/EntityFallingBlock.java
+++ b/src/main/java/net/minecraft/server/EntityFallingBlock.java
@@ -86,6 +86,7 @@ public class EntityFallingBlock extends Entity {
}
this.world.setAir(i, j, k);
+ world.spigotConfig.antiXrayInstance.updateNearbyBlocks(world, i, j, k); // Spigot
}
if (this.onGround) {
@@ -101,6 +102,7 @@ public class EntityFallingBlock extends Entity {
}
this.world.setTypeAndData(i, j, k, this.id, this.data, 3);
// CraftBukkit end
+ world.spigotConfig.antiXrayInstance.updateNearbyBlocks(world, i, j, k); // Spigot
if (this.id instanceof BlockFalling) {
((BlockFalling) this.id).a(this.world, i, j, k, this.data);
diff --git a/src/main/java/net/minecraft/server/Explosion.java b/src/main/java/net/minecraft/server/Explosion.java
index d6ac728..229b296 100644
--- a/src/main/java/net/minecraft/server/Explosion.java
+++ b/src/main/java/net/minecraft/server/Explosion.java
@@ -239,6 +239,7 @@ public class Explosion {
j = chunkposition.y;
k = chunkposition.z;
block = this.world.getType(i, j, k);
+ world.spigotConfig.antiXrayInstance.updateNearbyBlocks(world, i, j, k); // Spigot
if (flag) {
double d0 = (double) ((float) i + this.world.random.nextFloat());
double d1 = (double) ((float) j + this.world.random.nextFloat());
diff --git a/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java b/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java
index 09b34e9..3006712 100644
--- a/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java
+++ b/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java
@@ -28,6 +28,7 @@ public class PacketPlayOutMapChunk extends Packet {
this.d = chunkmap.c;
this.c = chunkmap.b;
+ chunk.world.spigotConfig.antiXrayInstance.obfuscateSync(chunk.locX, chunk.locZ, i, chunkmap.a, chunk.world); // Spigot
try {
this.buffer = chunkmap.a;
diff --git a/src/main/java/net/minecraft/server/PacketPlayOutMapChunkBulk.java b/src/main/java/net/minecraft/server/PacketPlayOutMapChunkBulk.java
index bf3a139..30bf8a7 100644
--- a/src/main/java/net/minecraft/server/PacketPlayOutMapChunkBulk.java
+++ b/src/main/java/net/minecraft/server/PacketPlayOutMapChunkBulk.java
@@ -26,6 +26,7 @@ public class PacketPlayOutMapChunkBulk extends Packet {
}
};
// CraftBukkit end
+ private World world; // Spigot
public PacketPlayOutMapChunkBulk() {}
@@ -44,6 +45,9 @@ public class PacketPlayOutMapChunkBulk extends Packet {
Chunk chunk = (Chunk) list.get(k);
ChunkMap chunkmap = PacketPlayOutMapChunk.a(chunk, true, '\uffff');
+ // Spigot start
+ world = chunk.world;
+ /*
if (buildBuffer.length < j + chunkmap.a.length) {
byte[] abyte = new byte[j + chunkmap.a.length];
@@ -52,6 +56,8 @@ public class PacketPlayOutMapChunkBulk extends Packet {
}
System.arraycopy(chunkmap.a, 0, buildBuffer, j, chunkmap.a.length);
+ */
+ // Spigot end
j += chunkmap.a.length;
this.a[k] = chunk.locX;
this.b[k] = chunk.locZ;
@@ -79,6 +85,22 @@ public class PacketPlayOutMapChunkBulk extends Packet {
if (this.buffer != null) {
return;
}
+ // Spigot start
+ int finalBufferSize = 0;
+ // Obfuscate all sections
+ for (int i = 0; i < a.length; i++) {
+ world.spigotConfig.antiXrayInstance.obfuscate(a[i], b[i], c[i], inflatedBuffers[i], world);
+ finalBufferSize += inflatedBuffers[i].length;
+ }
+
+ // Now it's time to efficiently copy the chunk to the build buffer
+ buildBuffer = new byte[finalBufferSize];
+ int bufferLocation = 0;
+ for (int i = 0; i < a.length; i++) {
+ System.arraycopy(inflatedBuffers[i], 0, buildBuffer, bufferLocation, inflatedBuffers[i].length);
+ bufferLocation += inflatedBuffers[i].length;
+ }
+ // Spigot end
Deflater deflater = localDeflater.get();
deflater.reset();
diff --git a/src/main/java/net/minecraft/server/PlayerInteractManager.java b/src/main/java/net/minecraft/server/PlayerInteractManager.java
index 2db45ad..97fe53c 100644
--- a/src/main/java/net/minecraft/server/PlayerInteractManager.java
+++ b/src/main/java/net/minecraft/server/PlayerInteractManager.java
@@ -173,6 +173,7 @@ public class PlayerInteractManager {
this.o = i1;
}
}
+ world.spigotConfig.antiXrayInstance.updateNearbyBlocks(world, i, j, k); // Spigot
}
}
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
index dcbf520..8e633de 100644
--- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java
@@ -237,9 +237,16 @@ public abstract class World implements IBlockAccess {
return this.getType(i, k, j);
}
- public Block getType(int i, int j, int k) {
+ // Spigot start
+ public Block getType(int i, int j, int k)
+ {
+ return getType( i, j, k, true );
+ }
+
+ public Block getType(int i, int j, int k, boolean useCaptured) {
// CraftBukkit start - tree generation
- if (captureTreeGeneration) {
+ if (captureTreeGeneration && useCaptured) {
+ // Spigot end
Iterator<BlockState> it = capturedBlockStates.iterator();
while (it.hasNext()) {
BlockState previous = it.next();
@@ -551,6 +558,7 @@ public abstract class World implements IBlockAccess {
this.e(i, j + 1, k, block);
this.e(i, j, k - 1, block);
this.e(i, j, k + 1, block);
+ spigotConfig.antiXrayInstance.updateNearbyBlocks(this, i, j, k); // Spigot
}
public void b(int i, int j, int k, Block block, int l) {
diff --git a/src/main/java/org/spigotmc/AntiXray.java b/src/main/java/org/spigotmc/AntiXray.java
new file mode 100644
index 0000000..d0fc0a9
--- /dev/null
+++ b/src/main/java/org/spigotmc/AntiXray.java
@@ -0,0 +1,227 @@
+package org.spigotmc;
+
+import net.minecraft.util.gnu.trove.set.TByteSet;
+import net.minecraft.util.gnu.trove.set.hash.TByteHashSet;
+import net.minecraft.server.Block;
+import net.minecraft.server.Blocks;
+import net.minecraft.server.World;
+import org.bukkit.craftbukkit.util.CraftMagicNumbers;
+
+public class AntiXray
+{
+
+ private static final CustomTimingsHandler update = new CustomTimingsHandler( "xray - update" );
+ private static final CustomTimingsHandler obfuscate = new CustomTimingsHandler( "xray - obfuscate" );
+ /*========================================================================*/
+ // Used to keep track of which blocks to obfuscate
+ private final boolean[] obfuscateBlocks = new boolean[ Short.MAX_VALUE ];
+ // Used to select a random replacement ore
+ private final byte[] replacementOres;
+
+ public AntiXray(SpigotWorldConfig config)
+ {
+ // Set all listed blocks as true to be obfuscated
+ for ( int id : ( config.engineMode == 1 ) ? config.hiddenBlocks : config.replaceBlocks )
+ {
+ obfuscateBlocks[id] = true;
+ }
+
+ // For every block
+ TByteSet blocks = new TByteHashSet();
+ for ( Integer i : config.hiddenBlocks )
+ {
+ Block block = Block.e( i );
+ // Check it exists and is not a tile entity
+ if ( block != null && !block.isTileEntity() )
+ {
+ // Add it to the set of replacement blocks
+ blocks.add( (byte) (int) i );
+ }
+ }
+ // Bake it to a flat array of replacements
+ replacementOres = blocks.toArray();
+ }
+
+ /**
+ * Starts the timings handler, then updates all blocks within the set radius
+ * of the given coordinate, revealing them if they are hidden ores.
+ */
+ public void updateNearbyBlocks(World world, int x, int y, int z)
+ {
+ if ( world.spigotConfig.antiXray )
+ {
+ update.startTiming();
+ updateNearbyBlocks( world, x, y, z, 2, false ); // 2 is the radius, we shouldn't change it as that would make it exponentially slower
+ update.stopTiming();
+ }
+ }
+
+ /**
+ * Starts the timings handler, and then removes all non exposed ores from
+ * the chunk buffer.
+ */
+ public void obfuscateSync(int chunkX, int chunkY, int bitmask, byte[] buffer, World world)
+ {
+ if ( world.spigotConfig.antiXray )
+ {
+ obfuscate.startTiming();
+ obfuscate( chunkX, chunkY, bitmask, buffer, world );
+ obfuscate.stopTiming();
+ }
+ }
+
+ /**
+ * Removes all non exposed ores from the chunk buffer.
+ */
+ public void obfuscate(int chunkX, int chunkY, int bitmask, byte[] buffer, World world)
+ {
+ // If the world is marked as obfuscated
+ if ( world.spigotConfig.antiXray )
+ {
+ // Initial radius to search around for air
+ int initialRadius = 1;
+ // Which block in the buffer we are looking at, anywhere from 0 to 16^4
+ int index = 0;
+ // The iterator marking which random ore we should use next
+ int randomOre = 0;
+
+ // Chunk corner X and Z blocks
+ int startX = chunkX << 4;
+ int startZ = chunkY << 4;
+
+ byte replaceWithTypeId;
+ switch ( world.getWorld().getEnvironment() )
+ {
+ case NETHER:
+ replaceWithTypeId = (byte) CraftMagicNumbers.getId(Blocks.NETHERRACK);
+ break;
+ case THE_END:
+ replaceWithTypeId = (byte) CraftMagicNumbers.getId(Blocks.WHITESTONE);
+ break;
+ default:
+ replaceWithTypeId = (byte) CraftMagicNumbers.getId(Blocks.STONE);
+ break;
+ }
+
+ // Chunks can have up to 16 sections
+ for ( int i = 0; i < 16; i++ )
+ {
+ // If the bitmask indicates this chunk is sent...
+ if ( ( bitmask & 1 << i ) != 0 )
+ {
+ // Work through all blocks in the chunk, y,z,x
+ for ( int y = 0; y < 16; y++ )
+ {
+ for ( int z = 0; z < 16; z++ )
+ {
+ for ( int x = 0; x < 16; x++ )
+ {
+ // For some reason we can get too far ahead of ourselves (concurrent modification on bulk chunks?) so if we do, just abort and move on
+ if ( index >= buffer.length )
+ {
+ index++;
+ continue;
+ }
+ // Grab the block ID in the buffer.
+ // TODO: extended IDs are not yet supported
+ int blockId = buffer[index] & 0xFF;
+ // Check if the block should be obfuscated
+ if ( obfuscateBlocks[blockId] )
+ {
+ // The world isn't loaded, bail out
+ if ( !isLoaded( world, startX + x, ( i << 4 ) + y, startZ + z, initialRadius ) )
+ {
+ index++;
+ continue;
+ }
+ // On the otherhand, if radius is 0, or the nearby blocks are all non air, we can obfuscate
+ if ( !hasTransparentBlockAdjacent( world, startX + x, ( i << 4 ) + y, startZ + z, initialRadius ) )
+ {
+ switch ( world.spigotConfig.engineMode )
+ {
+ case 1:
+ // Replace with replacement material
+ buffer[index] = replaceWithTypeId;
+ break;
+ case 2:
+ // Replace with random ore.
+ if ( randomOre >= replacementOres.length )
+ {
+ randomOre = 0;
+ }
+ buffer[index] = replacementOres[randomOre++];
+ break;
+ }
+ }
+ }
+
+ index++;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private void updateNearbyBlocks(World world, int x, int y, int z, int radius, boolean updateSelf)
+ {
+ // If the block in question is loaded
+ if ( world.isLoaded( x, y, z ) )
+ {
+ // Get block id
+ Block block = world.getType(x, y, z);
+
+ // See if it needs update
+ if ( updateSelf && obfuscateBlocks[Block.b(block)] )
+ {
+ // Send the update
+ world.notify( x, y, z );
+ }
+
+ // Check other blocks for updates
+ if ( radius > 0 )
+ {
+ updateNearbyBlocks( world, x + 1, y, z, radius - 1, true );
+ updateNearbyBlocks( world, x - 1, y, z, radius - 1, true );
+ updateNearbyBlocks( world, x, y + 1, z, radius - 1, true );
+ updateNearbyBlocks( world, x, y - 1, z, radius - 1, true );
+ updateNearbyBlocks( world, x, y, z + 1, radius - 1, true );
+ updateNearbyBlocks( world, x, y, z - 1, radius - 1, true );
+ }
+ }
+ }
+
+ private static boolean isLoaded(World world, int x, int y, int z, int radius)
+ {
+ return world.isLoaded( x, y, z )
+ && ( radius == 0 ||
+ ( isLoaded( world, x + 1, y, z, radius - 1 )
+ && isLoaded( world, x - 1, y, z, radius - 1 )
+ && isLoaded( world, x, y + 1, z, radius - 1 )
+ && isLoaded( world, x, y - 1, z, radius - 1 )
+ && isLoaded( world, x, y, z + 1, radius - 1 )
+ && isLoaded( world, x, y, z - 1, radius - 1 ) ) );
+ }
+
+ private static boolean hasTransparentBlockAdjacent(World world, int x, int y, int z, int radius)
+ {
+ return !isSolidBlock(world.getType(x, y, z, false)) /* isSolidBlock */
+ || ( radius > 0
+ && ( hasTransparentBlockAdjacent( world, x + 1, y, z, radius - 1 )
+ || hasTransparentBlockAdjacent( world, x - 1, y, z, radius - 1 )
+ || hasTransparentBlockAdjacent( world, x, y + 1, z, radius - 1 )
+ || hasTransparentBlockAdjacent( world, x, y - 1, z, radius - 1 )
+ || hasTransparentBlockAdjacent( world, x, y, z + 1, radius - 1 )
+ || hasTransparentBlockAdjacent( world, x, y, z - 1, radius - 1 ) ) );
+ }
+
+ private static boolean isSolidBlock(Block block) {
+ // Mob spawners are treated as solid blocks as far as the
+ // game is concerned for lighting and other tasks but for
+ // rendering they can be seen through therefor we special
+ // case them so that the antixray doesn't show the fake
+ // blocks around them.
+ return block.r() && block != Blocks.MOB_SPAWNER;
+ }
+}
diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java
index 1814b4f..45b2aae 100644
--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java
+++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java
@@ -1,5 +1,6 @@
package org.spigotmc;
+import java.util.Arrays;
import java.util.List;
import org.bukkit.Bukkit;
import org.bukkit.configuration.file.YamlConfiguration;
@@ -212,4 +213,36 @@ public class SpigotWorldConfig
arrowDespawnRate = getInt( "arrow-despawn-rate", 1200 );
log( "Arrow Despawn Rate: " + arrowDespawnRate );
}
+
+ public boolean antiXray;
+ public int engineMode;
+ public List<Integer> hiddenBlocks;
+ public List<Integer> replaceBlocks;
+ public AntiXray antiXrayInstance;
+ private void antiXray()
+ {
+ antiXray = getBoolean( "anti-xray.enabled", true );
+ log( "Anti X-Ray: " + antiXray );
+
+ engineMode = getInt( "anti-xray.engine-mode", 1 );
+ log( "\tEngine Mode: " + engineMode );
+
+ if ( SpigotConfig.version < 5 )
+ {
+ set( "anti-xray.blocks", null );
+ }
+ hiddenBlocks = getList( "anti-xray.hide-blocks", Arrays.asList( new Integer[]
+ {
+ 14, 15, 16, 21, 48, 49, 54, 56, 73, 74, 82, 129, 130
+ } ) );
+ log( "\tHidden Blocks: " + hiddenBlocks );
+
+ replaceBlocks = getList( "anti-xray.replace-blocks", Arrays.asList( new Integer[]
+ {
+ 1, 5
+ } ) );
+ log( "\tReplace Blocks: " + replaceBlocks );
+
+ antiXrayInstance = new AntiXray( this );
+ }
}
--
1.9.1

View File

@@ -1,134 +0,0 @@
From d09d15c7443b4e3d7922fcb9435f390f0a2e191e Mon Sep 17 00:00:00 2001
From: md_5 <git@md-5.net>
Date: Fri, 13 Dec 2013 11:45:47 +1100
Subject: [PATCH] Optimize DataWatcher
Use primitive orientated collections, as well as more effective copies across collections.
diff --git a/src/main/java/net/minecraft/server/DataWatcher.java b/src/main/java/net/minecraft/server/DataWatcher.java
index 90a2a80..f30e9f8 100644
--- a/src/main/java/net/minecraft/server/DataWatcher.java
+++ b/src/main/java/net/minecraft/server/DataWatcher.java
@@ -14,8 +14,13 @@ public class DataWatcher {
private final Entity a;
private boolean b = true;
- private static final HashMap c = new HashMap();
- private final Map d = new HashMap();
+ // Spigot Start
+ private static final net.minecraft.util.gnu.trove.map.TObjectIntMap classToId = new net.minecraft.util.gnu.trove.map.hash.TObjectIntHashMap( 10, 0.5f, -1 );
+ private final net.minecraft.util.gnu.trove.map.TIntObjectMap dataValues = new net.minecraft.util.gnu.trove.map.hash.TIntObjectHashMap( 10, 0.5f, -1 );
+ // These exist as an attempt at backwards compatability for (broken) NMS plugins
+ private static final Map c = net.minecraft.util.gnu.trove.TDecorators.wrap( classToId );
+ private final Map d = net.minecraft.util.gnu.trove.TDecorators.wrap( dataValues );
+ // Spigot End
private boolean e;
private ReadWriteLock f = new ReentrantReadWriteLock();
@@ -24,19 +29,19 @@ public class DataWatcher {
}
public void a(int i, Object object) {
- Integer integer = (Integer) c.get(object.getClass());
+ int integer = classToId.get(object.getClass()); // Spigot
- if (integer == null) {
+ if (integer == -1) { // Spigot
throw new IllegalArgumentException("Unknown data type: " + object.getClass());
} else if (i > 31) {
throw new IllegalArgumentException("Data value id is too big with " + i + "! (Max is " + 31 + ")");
- } else if (this.d.containsKey(Integer.valueOf(i))) {
+ } else if (this.dataValues.containsKey(i)) { // Spigot
throw new IllegalArgumentException("Duplicate id value for " + i + "!");
} else {
- WatchableObject watchableobject = new WatchableObject(integer.intValue(), i, object);
+ WatchableObject watchableobject = new WatchableObject(integer, i, object); // Spigot
this.f.writeLock().lock();
- this.d.put(Integer.valueOf(i), watchableobject);
+ this.dataValues.put(i, watchableobject); // Spigot
this.f.writeLock().unlock();
this.b = false;
}
@@ -46,7 +51,7 @@ public class DataWatcher {
WatchableObject watchableobject = new WatchableObject(j, i, null);
this.f.writeLock().lock();
- this.d.put(Integer.valueOf(i), watchableobject);
+ this.dataValues.put(i, watchableobject); // Spigot
this.f.writeLock().unlock();
this.b = false;
}
@@ -81,7 +86,7 @@ public class DataWatcher {
WatchableObject watchableobject;
try {
- watchableobject = (WatchableObject) this.d.get(Integer.valueOf(i));
+ watchableobject = (WatchableObject) this.dataValues.get(i); // Spigot
} catch (Throwable throwable) {
CrashReport crashreport = CrashReport.a(throwable, "Getting synched entity data");
CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Synched entity data");
@@ -133,7 +138,7 @@ public class DataWatcher {
if (this.e) {
this.f.readLock().lock();
- Iterator iterator = this.d.values().iterator();
+ Iterator iterator = this.dataValues.valueCollection().iterator(); // Spigot
while (iterator.hasNext()) {
WatchableObject watchableobject = (WatchableObject) iterator.next();
@@ -157,7 +162,7 @@ public class DataWatcher {
public void a(PacketDataSerializer packetdataserializer) {
this.f.readLock().lock();
- Iterator iterator = this.d.values().iterator();
+ Iterator iterator = this.dataValues.valueCollection().iterator(); // Spigot
while (iterator.hasNext()) {
WatchableObject watchableobject = (WatchableObject) iterator.next();
@@ -170,18 +175,11 @@ public class DataWatcher {
}
public List c() {
- ArrayList arraylist = null;
+ ArrayList arraylist = new ArrayList(); // Spigot
this.f.readLock().lock();
- WatchableObject watchableobject;
-
- for (Iterator iterator = this.d.values().iterator(); iterator.hasNext(); arraylist.add(watchableobject)) {
- watchableobject = (WatchableObject) iterator.next();
- if (arraylist == null) {
- arraylist = new ArrayList();
- }
- }
+ arraylist.addAll(this.dataValues.valueCollection()); // Spigot
this.f.readLock().unlock();
return arraylist;
@@ -295,12 +293,14 @@ public class DataWatcher {
}
static {
- c.put(Byte.class, Integer.valueOf(0));
- c.put(Short.class, Integer.valueOf(1));
- c.put(Integer.class, Integer.valueOf(2));
- c.put(Float.class, Integer.valueOf(3));
- c.put(String.class, Integer.valueOf(4));
- c.put(ItemStack.class, Integer.valueOf(5));
- c.put(ChunkCoordinates.class, Integer.valueOf(6));
+ // Spigot Start - remove valueOf
+ classToId.put(Byte.class, 0);
+ classToId.put(Short.class, 1);
+ classToId.put(Integer.class, 2);
+ classToId.put(Float.class, 3);
+ classToId.put(String.class, 4);
+ classToId.put(ItemStack.class, 5);
+ classToId.put(ChunkCoordinates.class, 6);
+ // Spigot End
}
}
--
1.9.1

View File

@@ -1,159 +0,0 @@
From 7936c99592bc205e2288842c5dfe09d19efd6e5a 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 8f982f1..0755d36 100644
--- a/src/main/java/net/minecraft/server/LoginListener.java
+++ b/src/main/java/net/minecraft/server/LoginListener.java
@@ -59,10 +59,23 @@ public class LoginListener implements PacketLoginInListener {
}
}
+ // 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 c() {
+ // 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, this.hostname);
@@ -97,7 +110,7 @@ public class LoginListener implements PacketLoginInListener {
this.g = EnumProtocolState.KEY;
this.networkManager.handle(new PacketLoginOutEncryptionBegin(this.j, this.server.K().getPublic(), this.e), new GenericFutureListener[0]);
} else {
- this.g = EnumProtocolState.READY_TO_ACCEPT;
+ (new ThreadPlayerLookupUUID(this, "User Authenticator #" + b.incrementAndGet())).start(); // Spigot
}
}
diff --git a/src/main/java/net/minecraft/server/ThreadPlayerLookupUUID.java b/src/main/java/net/minecraft/server/ThreadPlayerLookupUUID.java
index 6b91be7..1b2620c 100644
--- a/src/main/java/net/minecraft/server/ThreadPlayerLookupUUID.java
+++ b/src/main/java/net/minecraft/server/ThreadPlayerLookupUUID.java
@@ -25,50 +25,19 @@ class ThreadPlayerLookupUUID extends Thread {
GameProfile gameprofile = LoginListener.a(this.a);
try {
+ // Spigot Start
+ if ( !LoginListener.c( this.a ).getOnlineMode() )
+ {
+ a.initUUID();
+ fireLoginEvents();
+ return;
+ }
+ // Spigot End
String s = (new BigInteger(MinecraftEncryption.a(LoginListener.b(this.a), LoginListener.c(this.a).K().getPublic(), LoginListener.d(this.a)))).toString(16);
LoginListener.a(this.a, LoginListener.c(this.a).av().hasJoinedServer(new GameProfile((UUID) null, gameprofile.getName()), s));
if (LoginListener.a(this.a) != null) {
- // CraftBukkit start - fire PlayerPreLoginEvent
- if (!this.a.networkManager.isConnected()) {
- return;
- }
-
- String playerName = LoginListener.a(this.a).getName();
- java.net.InetAddress address = ((java.net.InetSocketAddress) a.networkManager.getSocketAddress()).getAddress();
- java.util.UUID uniqueId = LoginListener.a(this.a).getId();
- final org.bukkit.craftbukkit.CraftServer server = LoginListener.c(this.a).server;
-
- AsyncPlayerPreLoginEvent asyncEvent = new AsyncPlayerPreLoginEvent(playerName, address, uniqueId);
- server.getPluginManager().callEvent(asyncEvent);
-
- if (PlayerPreLoginEvent.getHandlerList().getRegisteredListeners().length != 0) {
- final PlayerPreLoginEvent event = new PlayerPreLoginEvent(playerName, address, uniqueId);
- if (asyncEvent.getResult() != PlayerPreLoginEvent.Result.ALLOWED) {
- event.disallow(asyncEvent.getResult(), asyncEvent.getKickMessage());
- }
- Waitable<PlayerPreLoginEvent.Result> waitable = new Waitable<PlayerPreLoginEvent.Result>() {
- @Override
- protected PlayerPreLoginEvent.Result evaluate() {
- server.getPluginManager().callEvent(event);
- return event.getResult();
- }};
-
- LoginListener.c(this.a).processQueue.add(waitable);
- if (waitable.get() != PlayerPreLoginEvent.Result.ALLOWED) {
- this.a.disconnect(event.getKickMessage());
- return;
- }
- } else {
- if (asyncEvent.getLoginResult() != AsyncPlayerPreLoginEvent.Result.ALLOWED) {
- this.a.disconnect(asyncEvent.getKickMessage());
- return;
- }
- }
- // CraftBukkit end
-
- LoginListener.e().info("UUID of player " + LoginListener.a(this.a).getName() + " is " + LoginListener.a(this.a).getId());
- LoginListener.a(this.a, EnumProtocolState.READY_TO_ACCEPT);
+ fireLoginEvents(); // Spigot
} else if (LoginListener.c(this.a).N()) {
LoginListener.e().warn("Failed to verify username but will let them in anyway!");
LoginListener.a(this.a, this.a.a(gameprofile));
@@ -93,4 +62,48 @@ class ThreadPlayerLookupUUID extends Thread {
// CraftBukkit end
}
}
+
+ private void fireLoginEvents() throws Exception
+ {
+ // CraftBukkit start - fire PlayerPreLoginEvent
+ if (!this.a.networkManager.isConnected()) {
+ return;
+ }
+
+ String playerName = LoginListener.a(this.a).getName();
+ java.net.InetAddress address = ((java.net.InetSocketAddress) a.networkManager.getSocketAddress()).getAddress();
+ java.util.UUID uniqueId = LoginListener.a(this.a).getId();
+ final org.bukkit.craftbukkit.CraftServer server = LoginListener.c(this.a).server;
+
+ AsyncPlayerPreLoginEvent asyncEvent = new AsyncPlayerPreLoginEvent(playerName, address, uniqueId);
+ server.getPluginManager().callEvent(asyncEvent);
+
+ if (PlayerPreLoginEvent.getHandlerList().getRegisteredListeners().length != 0) {
+ final PlayerPreLoginEvent event = new PlayerPreLoginEvent(playerName, address, uniqueId);
+ if (asyncEvent.getResult() != PlayerPreLoginEvent.Result.ALLOWED) {
+ event.disallow(asyncEvent.getResult(), asyncEvent.getKickMessage());
+ }
+ Waitable<PlayerPreLoginEvent.Result> waitable = new Waitable<PlayerPreLoginEvent.Result>() {
+ @Override
+ protected PlayerPreLoginEvent.Result evaluate() {
+ server.getPluginManager().callEvent(event);
+ return event.getResult();
+ }};
+
+ LoginListener.c(this.a).processQueue.add(waitable);
+ if (waitable.get() != PlayerPreLoginEvent.Result.ALLOWED) {
+ this.a.disconnect(event.getKickMessage());
+ return;
+ }
+ } else {
+ if (asyncEvent.getLoginResult() != AsyncPlayerPreLoginEvent.Result.ALLOWED) {
+ this.a.disconnect(asyncEvent.getKickMessage());
+ return;
+ }
+ }
+ // CraftBukkit end
+
+ LoginListener.e().info("UUID of player " + LoginListener.a(this.a).getName() + " is " + LoginListener.a(this.a).getId());
+ LoginListener.a(this.a, EnumProtocolState.READY_TO_ACCEPT);
+ }
}
--
1.9.1

View File

@@ -1,215 +0,0 @@
From 56e3bbd8f04384743c0661bfd79b8e45e2a5b515 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 b98079c..ee24038 100644
--- a/src/main/java/net/minecraft/server/HandshakeListener.java
+++ b/src/main/java/net/minecraft/server/HandshakeListener.java
@@ -1,14 +1,17 @@
package net.minecraft.server;
+import net.minecraft.util.com.mojang.authlib.properties.Property; // Spigot
import net.minecraft.util.io.netty.util.concurrent.GenericFutureListener;
// CraftBukkit start
import java.net.InetAddress;
import java.util.HashMap;
+import net.minecraft.util.com.mojang.util.UUIDTypeAdapter;
// CraftBukkit end
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;
@@ -73,6 +76,26 @@ public class HandshakeListener implements PacketHandshakingInListener {
this.b.close(chatcomponenttext);
} else {
this.b.a((PacketListener) (new LoginListener(this.a, this.b)));
+ // Spigot Start
+ if (org.spigotmc.SpigotConfig.bungee) {
+ String[] split = packethandshakinginsetprotocol.b.split("\00");
+ if ( split.length == 3 || split.length == 4 ) {
+ packethandshakinginsetprotocol.b = split[0];
+ b.n = new java.net.InetSocketAddress(split[1], ((java.net.InetSocketAddress) b.getSocketAddress()).getPort());
+ b.spoofedUUID = 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.handle(new PacketLoginOutDisconnect(chatcomponenttext), new GenericFutureListener[0]);
+ this.b.close(chatcomponenttext);
+ return;
+ }
+ if ( split.length == 4 )
+ {
+ b.spoofedProfile = gson.fromJson(split[3], Property[].class);
+ }
+ }
+ // Spigot End
((LoginListener) this.b.getPacketListener()).hostname = packethandshakinginsetprotocol.b + ":" + packethandshakinginsetprotocol.c; // 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 0755d36..e380a70 100644
--- a/src/main/java/net/minecraft/server/LoginListener.java
+++ b/src/main/java/net/minecraft/server/LoginListener.java
@@ -9,6 +9,7 @@ import javax.crypto.SecretKey;
import net.minecraft.util.com.google.common.base.Charsets;
import net.minecraft.util.com.mojang.authlib.GameProfile;
+import net.minecraft.util.com.mojang.authlib.properties.Property;
import net.minecraft.util.io.netty.util.concurrent.GenericFutureListener;
import net.minecraft.util.org.apache.commons.lang3.Validate;
import org.apache.logging.log4j.LogManager;
@@ -62,9 +63,24 @@ public class LoginListener implements PacketLoginInListener {
// 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 ( 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 1b080c7..31d6008 100644
--- a/src/main/java/net/minecraft/server/NetworkManager.java
+++ b/src/main/java/net/minecraft/server/NetworkManager.java
@@ -6,6 +6,7 @@ import javax.crypto.SecretKey;
import net.minecraft.util.com.google.common.collect.Queues;
import net.minecraft.util.com.google.common.util.concurrent.ThreadFactoryBuilder;
+import net.minecraft.util.com.mojang.authlib.properties.Property;
import net.minecraft.util.io.netty.channel.Channel;
import net.minecraft.util.io.netty.channel.ChannelFutureListener;
import net.minecraft.util.io.netty.channel.ChannelHandlerContext;
@@ -37,7 +38,11 @@ public class NetworkManager extends SimpleChannelInboundHandler {
private final Queue k = Queues.newConcurrentLinkedQueue();
private final Queue l = Queues.newConcurrentLinkedQueue();
private Channel m;
- private SocketAddress n;
+ // Spigot Start
+ public SocketAddress n;
+ public java.util.UUID spoofedUUID;
+ public Property[] spoofedProfile;
+ // Spigot End
private PacketListener o;
private EnumProtocol p;
private IChatBaseComponent q;
@@ -207,4 +212,11 @@ public class NetworkManager extends SimpleChannelInboundHandler {
static Channel a(NetworkManager networkmanager) {
return networkmanager.m;
}
+
+ // Spigot Start
+ public SocketAddress getRawAddress()
+ {
+ return this.m.remoteAddress();
+ }
+ // Spigot End
}
diff --git a/src/main/java/net/minecraft/server/PacketHandshakingInSetProtocol.java b/src/main/java/net/minecraft/server/PacketHandshakingInSetProtocol.java
index 16d4765..39692ee 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 extends Packet {
public void a(PacketDataSerializer packetdataserializer) throws IOException { // CraftBukkit - added throws
this.a = packetdataserializer.a();
- this.b = packetdataserializer.c(255);
+ this.b = packetdataserializer.c(Short.MAX_VALUE); // Spigot
this.c = packetdataserializer.readUnsignedShort();
this.d = EnumProtocol.a(packetdataserializer.a());
}
diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/java/net/minecraft/server/PlayerList.java
index 4c5d77e..cd9a8f5 100644
--- a/src/main/java/net/minecraft/server/PlayerList.java
+++ b/src/main/java/net/minecraft/server/PlayerList.java
@@ -350,7 +350,7 @@ public abstract class PlayerList {
EntityPlayer entity = new EntityPlayer(this.server, this.server.getWorldServer(0), gameprofile, new PlayerInteractManager(this.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 (this.j.isBanned(gameprofile) && !this.j.get(gameprofile).e()) { // Should be hasExpired
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index 73d92fd..4c13657 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -646,7 +646,13 @@ public final class CraftServer implements Server {
}
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
}
public int getTicksPerAnimalSpawns() {
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
index 7d16bab..c0a0b43 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -1299,6 +1299,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 2b499fe..8bfffa5 100644
--- a/src/main/java/org/spigotmc/SpigotConfig.java
+++ b/src/main/java/org/spigotmc/SpigotConfig.java
@@ -192,4 +192,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 );
+ }
}
--
1.9.1

View File

@@ -1,48 +0,0 @@
From ea516adcd661272180621a8542318ea7c50bfed4 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 89fc4c5..6cb5b14 100644
--- a/src/main/java/net/minecraft/server/EntityZombie.java
+++ b/src/main/java/net/minecraft/server/EntityZombie.java
@@ -30,7 +30,7 @@ public class EntityZombie extends EntityMonster {
this.getNavigation().b(true);
this.goalSelector.a(0, new PathfinderGoalFloat(this));
this.goalSelector.a(2, new PathfinderGoalMeleeAttack(this, EntityHuman.class, 1.0D, false));
- this.goalSelector.a(4, new PathfinderGoalMeleeAttack(this, EntityVillager.class, 1.0D, true));
+ if ( world.spigotConfig.zombieAggressiveTowardsVillager ) { this.goalSelector.a(4, new PathfinderGoalMeleeAttack(this, EntityVillager.class, 1.0D, true)); } // Spigot
this.goalSelector.a(5, new PathfinderGoalMoveTowardsRestriction(this, 1.0D));
this.goalSelector.a(6, new PathfinderGoalMoveThroughVillage(this, 1.0D, false));
this.goalSelector.a(7, new PathfinderGoalRandomStroll(this, 1.0D));
@@ -38,7 +38,7 @@ public class EntityZombie extends EntityMonster {
this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this));
this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this, true));
this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget(this, EntityHuman.class, 0, true));
- this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget(this, EntityVillager.class, 0, false));
+ if ( world.spigotConfig.zombieAggressiveTowardsVillager ) { this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget(this, EntityVillager.class, 0, false)); } // Spigot
this.a(0.6F, 1.8F);
}
diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java
index 45b2aae..b8e144d 100644
--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java
+++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java
@@ -245,4 +245,11 @@ public class SpigotWorldConfig
antiXrayInstance = new AntiXray( this );
}
+
+ public boolean zombieAggressiveTowardsVillager;
+ private void zombieAggressiveTowardsVillager()
+ {
+ zombieAggressiveTowardsVillager = getBoolean( "zombie-aggressive-towards-villager", true );
+ log( "Zombie Aggressive Towards Villager: " + zombieAggressiveTowardsVillager );
+ }
}
--
1.9.1

View File

@@ -1,57 +0,0 @@
From f4baec301dc61e04e4b99f97c73ae17d63e4746e 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 51f1761..64fa9ab 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -54,7 +54,7 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo
private final List n = new ArrayList();
private final ICommandHandler o;
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 String serverIp;
@@ -113,7 +113,7 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo
j = this;
this.d = proxy;
// this.universe = file1; // CraftBukkit
- this.p = new ServerConnection(this);
+ // this.p = new ServerConnection(this); // Spigot
this.o = new CommandDispatcher();
// this.convertable = new WorldLoaderServer(file1); // CraftBukkit - moved to DedicatedServer.init
this.T = new YggdrasilAuthenticationService(proxy, UUID.randomUUID().toString());
@@ -1250,7 +1250,7 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo
}
// Spigot End
public ServerConnection ai() {
- return this.p;
+ return ( this.p ) == null ? this.p = new ServerConnection( this ) : this.p; // Spigot
}
public boolean ak() {
diff --git a/src/main/java/org/spigotmc/SpigotConfig.java b/src/main/java/org/spigotmc/SpigotConfig.java
index 8bfffa5..b3278fd 100644
--- a/src/main/java/org/spigotmc/SpigotConfig.java
+++ b/src/main/java/org/spigotmc/SpigotConfig.java
@@ -202,4 +202,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 );
+ }
}
--
1.9.1

View File

@@ -1,22 +0,0 @@
From ac4b3f0f638006d240d371699446e54376373115 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 4d336d8..f835b01 100644
--- a/src/main/java/net/minecraft/server/StructureGenerator.java
+++ b/src/main/java/net/minecraft/server/StructureGenerator.java
@@ -179,7 +179,7 @@ public abstract class StructureGenerator extends WorldGenBase {
private void a(World world) {
if (this.e == null) {
// Spigot Start
- if ( world.spigotConfig.saveStructureInfo )
+ if ( world.spigotConfig.saveStructureInfo && !this.a().equals( "Mineshaft" ) )
{
this.e = (PersistentStructure) world.a(PersistentStructure.class, this.a());
} else
--
1.9.1

View File

@@ -1,26 +0,0 @@
From 6e97f8d49789ce149c7d59f96237cd430f0a077d 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 64fa9ab..ab29ad7 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -479,6 +479,12 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo
}
} catch (Throwable throwable) {
i.error("Encountered an unexpected exception", throwable);
+ // Spigot Start
+ if ( throwable.getCause() != null )
+ {
+ i.error( "\tCause of unexpected exception was", throwable.getCause() );
+ }
+ // Spigot End
CrashReport crashreport = null;
if (throwable instanceof ReportedException) {
--
1.9.1

View File

@@ -1,175 +0,0 @@
From 8e9e71c2621166d9fe8a9620bc8054e4e084522b 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..7eca388 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftEffect.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftEffect.java
@@ -55,6 +55,8 @@ 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();
default:
datavalue = 0;
}
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index 81913ac..1317254 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -808,28 +808,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, 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 {
@@ -1319,6 +1309,56 @@ 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, location.getBlockX(), location.getBlockY(), location.getBlockZ(), id, false );
+ } else
+ {
+ StringBuilder particleFullName = new StringBuilder();
+ particleFullName.append( effect.getName() );
+ if ( effect.getData() != null && ( effect.getData().equals( Material.class ) || effect.getData().equals( org.bukkit.material.MaterialData.class ) ) )
+ {
+ particleFullName.append( '_' ).append( id );
+ }
+ if ( effect.getData() != null && effect.getData().equals( org.bukkit.material.MaterialData.class ) )
+ {
+ particleFullName.append( '_' ).append( data );
+ }
+ packet = new PacketPlayOutWorldParticles( particleFullName.toString(), (float) location.getX(), (float) location.getY(), (float) location.getZ(), offsetX, offsetY, offsetZ, speed, particleCount );
+ }
+ 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 c0a0b43..82bd22f 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -1325,6 +1325,49 @@ 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, location.getBlockX(), location.getBlockY(), location.getBlockZ(), id, false );
+ } else
+ {
+ StringBuilder particleFullName = new StringBuilder();
+ particleFullName.append( effect.getName() );
+ if ( effect.getData() != null && ( effect.getData().equals( Material.class ) || effect.getData().equals( org.bukkit.material.MaterialData.class ) ) )
+ {
+ particleFullName.append( '_' ).append( id );
+ }
+ if ( effect.getData() != null && effect.getData().equals( org.bukkit.material.MaterialData.class ) )
+ {
+ particleFullName.append( '_' ).append( data );
+ }
+ packet = new PacketPlayOutWorldParticles( particleFullName.toString(), (float) location.getX(), (float) location.getY(), (float) location.getZ(), offsetX, offsetY, offsetZ, speed, particleCount );
+ }
+ 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()
--
1.9.1

View File

@@ -1,111 +0,0 @@
From a3c067ce8221e3a2f792a951ee7a83bed151d702 Mon Sep 17 00:00:00 2001
From: md_5 <git@md-5.net>
Date: Sun, 5 Jan 2014 09:35:01 +1100
Subject: [PATCH] Fix Biome Decoration Crashes
We don't really know what affect this will have on the terrain generation, but its better than crashing and not having terrain generate at all!
diff --git a/src/main/java/net/minecraft/server/BiomeDecorator.java b/src/main/java/net/minecraft/server/BiomeDecorator.java
index b048d6c..962d719 100644
--- a/src/main/java/net/minecraft/server/BiomeDecorator.java
+++ b/src/main/java/net/minecraft/server/BiomeDecorator.java
@@ -147,7 +147,7 @@ public class BiomeDecorator {
for (j = 0; j < this.z; ++j) {
k = this.c + this.b.nextInt(16) + 8;
l = this.d + this.b.nextInt(16) + 8;
- i1 = this.b.nextInt(this.a.getHighestBlockYAt(k, l) * 2);
+ i1 = this.b.nextInt(this.getHighestBlockYAt(k, l) * 2); // Spigot
WorldGenerator worldgenerator = biomebase.b(this.b);
worldgenerator.a(this.a, this.b, k, i1, l);
@@ -156,7 +156,7 @@ public class BiomeDecorator {
for (j = 0; j < this.A; ++j) {
k = this.c + this.b.nextInt(16) + 8;
l = this.d + this.b.nextInt(16) + 8;
- i1 = this.b.nextInt(this.a.getHighestBlockYAt(k, l) * 2);
+ i1 = this.b.nextInt(this.getHighestBlockYAt(k, l) * 2); // Spigot
(new WorldGenDeadBush(Blocks.DEAD_BUSH)).a(this.a, this.b, k, i1, l);
}
@@ -164,7 +164,7 @@ public class BiomeDecorator {
k = this.c + this.b.nextInt(16) + 8;
l = this.d + this.b.nextInt(16) + 8;
- for (i1 = this.b.nextInt(this.a.getHighestBlockYAt(k, l) * 2); i1 > 0 && this.a.isEmpty(k, i1 - 1, l); --i1) {
+ for (i1 = this.b.nextInt(this.getHighestBlockYAt(k, l) * 2); i1 > 0 && this.a.isEmpty(k, i1 - 1, l); --i1) { // Spigot
;
}
@@ -182,7 +182,7 @@ public class BiomeDecorator {
if (this.b.nextInt(8) == 0) {
k = this.c + this.b.nextInt(16) + 8;
l = this.d + this.b.nextInt(16) + 8;
- i1 = this.b.nextInt(this.a.getHighestBlockYAt(k, l) * 2);
+ i1 = this.b.nextInt(this.getHighestBlockYAt(k, l) * 2); // Spigot
this.r.a(this.a, this.b, k, i1, l);
}
}
@@ -190,42 +190,42 @@ public class BiomeDecorator {
if (this.b.nextInt(4) == 0) {
j = this.c + this.b.nextInt(16) + 8;
k = this.d + this.b.nextInt(16) + 8;
- l = this.b.nextInt(this.a.getHighestBlockYAt(j, k) * 2);
+ l = this.b.nextInt(this.getHighestBlockYAt(j, k) * 2); // Spigot
this.q.a(this.a, this.b, j, l, k);
}
if (this.b.nextInt(8) == 0) {
j = this.c + this.b.nextInt(16) + 8;
k = this.d + this.b.nextInt(16) + 8;
- l = this.b.nextInt(this.a.getHighestBlockYAt(j, k) * 2);
+ l = this.b.nextInt(this.getHighestBlockYAt(j, k) * 2); // Spigot
this.r.a(this.a, this.b, j, l, k);
}
for (j = 0; j < this.C; ++j) {
k = this.c + this.b.nextInt(16) + 8;
l = this.d + this.b.nextInt(16) + 8;
- i1 = this.b.nextInt(this.a.getHighestBlockYAt(k, l) * 2);
+ i1 = this.b.nextInt(this.getHighestBlockYAt(k, l) * 2); // Spigot
this.t.a(this.a, this.b, k, i1, l);
}
for (j = 0; j < 10; ++j) {
k = this.c + this.b.nextInt(16) + 8;
l = this.d + this.b.nextInt(16) + 8;
- i1 = this.b.nextInt(this.a.getHighestBlockYAt(k, l) * 2);
+ i1 = this.b.nextInt(this.getHighestBlockYAt(k, l) * 2); // Spigot
this.t.a(this.a, this.b, k, i1, l);
}
if (this.b.nextInt(32) == 0) {
j = this.c + this.b.nextInt(16) + 8;
k = this.d + this.b.nextInt(16) + 8;
- l = this.b.nextInt(this.a.getHighestBlockYAt(j, k) * 2);
+ l = this.b.nextInt(this.getHighestBlockYAt(j, k) * 2); // Spigot
(new WorldGenPumpkin()).a(this.a, this.b, j, l, k);
}
for (j = 0; j < this.D; ++j) {
k = this.c + this.b.nextInt(16) + 8;
l = this.d + this.b.nextInt(16) + 8;
- i1 = this.b.nextInt(this.a.getHighestBlockYAt(k, l) * 2);
+ i1 = this.b.nextInt(this.getHighestBlockYAt(k, l) * 2); // Spigot
this.u.a(this.a, this.b, k, i1, l);
}
@@ -276,4 +276,11 @@ public class BiomeDecorator {
this.a(1, this.n, 0, 16);
this.b(1, this.o, 16, 16);
}
+
+ // Spigot Start
+ private int getHighestBlockYAt(int x, int z)
+ {
+ return Math.max( 1, this.a.getHighestBlockYAt( x, z ) );
+ }
+ // Spigot End
}
--
1.9.1

View File

@@ -1,30 +0,0 @@
From 19d109674e896c40fd689fb4824f1391ffecf676 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 2a192e1..409b0ad 100644
--- a/src/main/java/net/minecraft/server/Entity.java
+++ b/src/main/java/net/minecraft/server/Entity.java
@@ -1134,6 +1134,7 @@ public abstract class Entity {
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
this.b(nbttagcompound);
if (this.vehicle != null) {
@@ -1202,6 +1203,8 @@ public abstract class Entity {
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;
--
1.9.1

View File

@@ -1,68 +0,0 @@
From f2ee4450d7b2cd0111afea54aa22a8b703f47dbd Mon Sep 17 00:00:00 2001
From: md_5 <md_5@live.com.au>
Date: Tue, 11 Jun 2013 12:17:37 +1000
Subject: [PATCH] More Efficient GetCubes
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
index 8e633de..c3f9a0e 100644
--- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java
@@ -1138,23 +1138,42 @@ public abstract class World implements IBlockAccess {
int i1 = MathHelper.floor(axisalignedbb.c);
int j1 = MathHelper.floor(axisalignedbb.f + 1.0D);
- for (int k1 = i; k1 < j; ++k1) {
- for (int l1 = i1; l1 < j1; ++l1) {
- if (this.isLoaded(k1, 64, l1)) {
- for (int i2 = k - 1; i2 < l; ++i2) {
- Block block;
-
- if (k1 >= -30000000 && k1 < 30000000 && l1 >= -30000000 && l1 < 30000000) {
- block = this.getType(k1, i2, l1);
- } else {
- block = Blocks.STONE;
+ // Spigot start
+ int ystart = ( ( k - 1 ) < 0 ) ? 0 : ( k - 1 );
+ for ( int chunkx = ( i >> 4 ); chunkx <= ( ( j - 1 ) >> 4 ); chunkx++ )
+ {
+ int cx = chunkx << 4;
+ for ( int chunkz = ( i1 >> 4 ); chunkz <= ( ( j1 - 1 ) >> 4 ); chunkz++ )
+ {
+ if ( !this.isChunkLoaded( chunkx, chunkz ) )
+ {
+ continue;
+ }
+ int cz = chunkz << 4;
+ Chunk chunk = this.getChunkAt( chunkx, chunkz );
+ // Compute ranges within chunk
+ int xstart = ( i < cx ) ? cx : i;
+ int xend = ( j < ( cx + 16 ) ) ? j : ( cx + 16 );
+ int zstart = ( i1 < cz ) ? cz : i1;
+ int zend = ( j1 < ( cz + 16 ) ) ? j1 : ( cz + 16 );
+ // Loop through blocks within chunk
+ for ( int x = xstart; x < xend; x++ )
+ {
+ for ( int z = zstart; z < zend; z++ )
+ {
+ for ( int y = ystart; y < l; y++ )
+ {
+ Block block = chunk.getType(x - cx, y, z - cz );
+ if ( block != null )
+ {
+ block.a( this, x, y, z, axisalignedbb, this.L, entity );
+ }
}
-
- block.a(this, k1, i2, l1, axisalignedbb, this.L, entity);
}
}
}
}
+ // Spigot end
double d0 = 0.25D;
List list = this.getEntities(entity, axisalignedbb.grow(d0, d0, d0));
--
1.9.1

View File

@@ -1,84 +0,0 @@
From efa76735fa9be4b7e68a4d41eebfe4d161f8c0e9 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 409b0ad..73d3b89 100644
--- a/src/main/java/net/minecraft/server/Entity.java
+++ b/src/main/java/net/minecraft/server/Entity.java
@@ -120,6 +120,7 @@ public abstract class Entity {
public final byte activationType = org.spigotmc.ActivationRange.initializeEntityActivationType(this);
public final boolean defaultActivationState;
public long activatedTick = 0;
+ 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 12e1036..76fe528 100644
--- a/src/main/java/net/minecraft/server/EntityInsentient.java
+++ b/src/main/java/net/minecraft/server/EntityInsentient.java
@@ -400,6 +400,12 @@ public abstract class EntityInsentient extends EntityLiving {
this.world.methodProfiler.a("checkDespawn");
this.w();
this.world.methodProfiler.b();
+ // Spigot Start
+ if ( this.fromMobSpawner )
+ {
+ return;
+ }
+ // Spigot End
this.world.methodProfiler.a("sensing");
this.bq.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 b97ac4b..23f09f7 100644
--- a/src/main/java/net/minecraft/server/MobSpawnerAbstract.java
+++ b/src/main/java/net/minecraft/server/MobSpawnerAbstract.java
@@ -136,6 +136,12 @@ public abstract class MobSpawnerAbstract {
SpawnerSpawnEvent event = CraftEventFactory.callSpawnerSpawnEvent(entity, this.b(), this.c(), this.d());
if (!event.isCancelled()) {
entity.world.addEntity(entity, CreatureSpawnEvent.SpawnReason.SPAWNER); // CraftBukkit
+ // Spigot Start
+ if ( entity.world.spigotConfig.nerfSpawnerMobs )
+ {
+ entity.fromMobSpawner = true;
+ }
+ // Spigot End
}
// CraftBukkit end
}
@@ -181,6 +187,12 @@ public abstract class MobSpawnerAbstract {
SpawnerSpawnEvent event = CraftEventFactory.callSpawnerSpawnEvent(entity, this.b(), this.c(), this.d());
if (!event.isCancelled()) {
this.a().addEntity(entity, CreatureSpawnEvent.SpawnReason.SPAWNER); // CraftBukkit
+ // Spigot Start
+ if ( entity.world.spigotConfig.nerfSpawnerMobs )
+ {
+ entity.fromMobSpawner = true;
+ }
+ // Spigot End
}
// CraftBukkit end
}
diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java
index b8e144d..d7766bb 100644
--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java
+++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java
@@ -252,4 +252,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 );
+ }
}
--
1.9.1

View File

@@ -1,36 +0,0 @@
From 9216a5725b4a0dae4ea006a6c39fa1d7276a7b8d 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 8d127fb..008e037 100644
--- a/src/main/java/org/bukkit/craftbukkit/Main.java
+++ b/src/main/java/org/bukkit/craftbukkit/Main.java
@@ -155,6 +155,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) {
--
1.9.1

View File

@@ -1,22 +0,0 @@
From 95232a545704431d1f98365587f57c2b51f0cd2b 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 82bd22f..1c4f3ae 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -1225,7 +1225,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);
--
1.9.1

View File

@@ -1,63 +0,0 @@
From db4568e8f946f05fc66c392bad2eb73fcf3b4ac9 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 00f9b89..dc9625b 100644
--- a/src/main/java/net/minecraft/server/DedicatedServer.java
+++ b/src/main/java/net/minecraft/server/DedicatedServer.java
@@ -119,6 +119,7 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer
this.a(MinecraftEncryption.b());
i.info("Starting Minecraft server on " + (this.getServerIp().length() == 0 ? "*" : this.getServerIp()) + ":" + this.L());
+ if (!org.spigotmc.SpigotConfig.lateBind) {
try {
this.ai().a(inetaddress, this.L());
} catch (Throwable ioexception) { // CraftBukkit - IOException -> Throwable
@@ -127,6 +128,7 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer
i.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)));
@@ -193,6 +195,18 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer
String s3 = String.format("%.3fs", new Object[] { Double.valueOf((double) i1 / 1.0E9D)});
i.info("Done (" + s3 + ")! For help, type \"help\" or \"?\"");
+
+ if (org.spigotmc.SpigotConfig.lateBind) {
+ try {
+ this.ai().a(inetaddress, this.L());
+ } catch (Throwable ioexception) { // CraftBukkit - IOException -> Throwable
+ i.warn("**** FAILED TO BIND TO PORT!");
+ i.warn("The exception was: {}", new Object[] { ioexception.toString()});
+ i.warn("Perhaps a server is already running on that port?");
+ return false;
+ }
+ }
+
if (this.propertyManager.getBoolean("enable-query", false)) {
i.info("Starting GS4 status listener");
this.k = new RemoteStatusListener(this);
diff --git a/src/main/java/org/spigotmc/SpigotConfig.java b/src/main/java/org/spigotmc/SpigotConfig.java
index b3278fd..af73544 100644
--- a/src/main/java/org/spigotmc/SpigotConfig.java
+++ b/src/main/java/org/spigotmc/SpigotConfig.java
@@ -209,4 +209,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 );
+ }
}
--
1.9.1

View File

@@ -1,94 +0,0 @@
From 6b76abdc04afb2dfa202afb6d098345854daa655 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 819896f..897e88b 100644
--- a/src/main/java/net/minecraft/server/ServerStatisticManager.java
+++ b/src/main/java/net/minecraft/server/ServerStatisticManager.java
@@ -32,6 +32,14 @@ public class ServerStatisticManager extends StatisticManager {
public ServerStatisticManager(MinecraftServer minecraftserver, File file1) {
this.c = minecraftserver;
this.d = file1;
+ // 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) {
@@ -56,6 +65,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 af73544..ca87886 100644
--- a/src/main/java/org/spigotmc/SpigotConfig.java
+++ b/src/main/java/org/spigotmc/SpigotConfig.java
@@ -10,10 +10,13 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
+
+import net.minecraft.util.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.file.YamlConfiguration;
public class SpigotConfig
@@ -214,4 +217,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." );
+ }
+ }
}
--
1.9.1

View File

@@ -1,29 +0,0 @@
From 6239bc0c14d31525868b0177a39f6e477e77ce5f Mon Sep 17 00:00:00 2001
From: Thinkofdeath <thethinkofdeath@gmail.com>
Date: Thu, 9 Jan 2014 14:19:12 +0000
Subject: [PATCH] Fix anvil collisions
diff --git a/src/main/java/net/minecraft/server/BlockAnvil.java b/src/main/java/net/minecraft/server/BlockAnvil.java
index 9e1ce2f..1fa14c5 100644
--- a/src/main/java/net/minecraft/server/BlockAnvil.java
+++ b/src/main/java/net/minecraft/server/BlockAnvil.java
@@ -11,6 +11,15 @@ public class BlockAnvil extends BlockFalling {
this.a(CreativeModeTab.c);
}
+ // Spigot start
+ @Override
+ public AxisAlignedBB a( World world, int i, int j, int k )
+ {
+ updateShape( world, i, j, k );
+ return super.a( world, i, j, k );
+ }
+ // Spigot end
+
public boolean d() {
return false;
}
--
1.9.1

View File

@@ -1,28 +0,0 @@
From 40440da2ba0d082414ed54c3b997ca883321d06f 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 f32f40d..d1bbb05 100644
--- a/src/main/java/net/minecraft/server/ItemStack.java
+++ b/src/main/java/net/minecraft/server/ItemStack.java
@@ -228,7 +228,13 @@ public final class ItemStack {
}
public boolean g() {
- return 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() {
--
1.9.1

View File

@@ -1,41 +0,0 @@
From e609c52476180bf75ce68b804dfb5823f951d434 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 ab29ad7..242b126 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -653,7 +653,13 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo
try {
worldserver.doTick();
} 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);
}
@@ -661,7 +667,13 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo
try {
worldserver.tickEntities();
} 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);
}
--
1.9.1

View File

@@ -1,32 +0,0 @@
From d7df43f39d323646ec0c9239f6b2cd7bb5a74358 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] Replace 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.
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 242b126..b52c101 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -582,7 +582,16 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IMo
if ((this.autosavePeriod > 0) && ((this.ticks % this.autosavePeriod) == 0)) { // CraftBukkit
this.methodProfiler.a("save");
this.u.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
+ server.playerCommandState = true;
+ for (World world : worlds) {
+ world.getWorld().save();
+ }
+ server.playerCommandState = false;
+ // this.saveChunks(true);
+ // Spigot End
this.methodProfiler.b();
}
--
1.9.1

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