Merge branch 'master' into gh-pages

This commit is contained in:
Kristian S. Stangeland 2013-01-22 13:26:58 +01:00
commit 290b791eb3
24 changed files with 243 additions and 77 deletions

View File

@ -11,12 +11,12 @@
</arguments> </arguments>
</buildCommand> </buildCommand>
<buildCommand> <buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name> <name>net.sourceforge.metrics.builder</name>
<arguments> <arguments>
</arguments> </arguments>
</buildCommand> </buildCommand>
<buildCommand> <buildCommand>
<name>net.sourceforge.metrics.builder</name> <name>org.eclipse.m2e.core.maven2Builder</name>
<arguments> <arguments>
</arguments> </arguments>
</buildCommand> </buildCommand>

View File

@ -2,7 +2,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>com.comphenix.protocol</groupId> <groupId>com.comphenix.protocol</groupId>
<artifactId>ProtocolLib</artifactId> <artifactId>ProtocolLib</artifactId>
<version>2.0.0</version> <version>2.1.0</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<description>Provides read/write access to the Minecraft protocol.</description> <description>Provides read/write access to the Minecraft protocol.</description>
@ -203,7 +203,7 @@
<dependency> <dependency>
<groupId>org.bukkit</groupId> <groupId>org.bukkit</groupId>
<artifactId>craftbukkit</artifactId> <artifactId>craftbukkit</artifactId>
<version>1.4.6-R0.1</version> <version>1.4.7-R0.1</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency> <dependency>

View File

@ -17,6 +17,8 @@
package com.comphenix.protocol; package com.comphenix.protocol;
import java.io.IOException;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
@ -25,6 +27,7 @@ import com.comphenix.protocol.error.ErrorReporter;
import com.comphenix.protocol.metrics.Updater; import com.comphenix.protocol.metrics.Updater;
import com.comphenix.protocol.metrics.Updater.UpdateResult; import com.comphenix.protocol.metrics.Updater.UpdateResult;
import com.comphenix.protocol.metrics.Updater.UpdateType; import com.comphenix.protocol.metrics.Updater.UpdateType;
import com.comphenix.protocol.utility.WrappedScheduler;
/** /**
* Handles the "protocol" administration command. * Handles the "protocol" administration command.
@ -64,42 +67,59 @@ class CommandProtocol extends CommandBase {
return true; return true;
} }
@SuppressWarnings("deprecation")
public void checkVersion(final CommandSender sender) { public void checkVersion(final CommandSender sender) {
// Perform on an async thread // Perform on an async thread
plugin.getServer().getScheduler().scheduleAsyncDelayedTask(plugin, new Runnable() { WrappedScheduler.runAsynchronouslyOnce(plugin, new Runnable() {
@Override @Override
public void run() { public void run() {
try { try {
UpdateResult result = updater.update(UpdateType.NO_DOWNLOAD, true); UpdateResult result = updater.update(UpdateType.NO_DOWNLOAD, true);
sender.sendMessage(ChatColor.BLUE + "[ProtocolLib] " + result.toString()); sender.sendMessage(ChatColor.BLUE + "[ProtocolLib] " + result.toString());
} catch (Exception e) { } catch (Exception e) {
if (isHttpError(e)) {
getReporter().reportWarning(this, "Http error: " + e.getCause().getMessage());
} else {
getReporter().reportDetailed(this, "Cannot check updates for ProtocolLib.", e, sender); getReporter().reportDetailed(this, "Cannot check updates for ProtocolLib.", e, sender);
} }
} }
}); }
}, 0L);
updateFinished(); updateFinished();
} }
@SuppressWarnings("deprecation")
public void updateVersion(final CommandSender sender) { public void updateVersion(final CommandSender sender) {
// Perform on an async thread // Perform on an async thread
plugin.getServer().getScheduler().scheduleAsyncDelayedTask(plugin, new Runnable() { WrappedScheduler.runAsynchronouslyOnce(plugin, new Runnable() {
@Override @Override
public void run() { public void run() {
try { try {
UpdateResult result = updater.update(UpdateType.DEFAULT, true); UpdateResult result = updater.update(UpdateType.DEFAULT, true);
sender.sendMessage(ChatColor.BLUE + "[ProtocolLib] " + result.toString()); sender.sendMessage(ChatColor.BLUE + "[ProtocolLib] " + result.toString());
} catch (Exception e) { } catch (Exception e) {
if (isHttpError(e)) {
getReporter().reportWarning(this, "Http error: " + e.getCause().getMessage());
} else {
getReporter().reportDetailed(this, "Cannot update ProtocolLib.", e, sender); getReporter().reportDetailed(this, "Cannot update ProtocolLib.", e, sender);
} }
} }
}); }
}, 0L);
updateFinished(); updateFinished();
} }
private boolean isHttpError(Exception e) {
Throwable cause = e.getCause();
if (cause instanceof IOException) {
// Thanks for making the message a part of the API ...
return cause.getMessage().contains("HTTP response");
} else {
return false;
}
}
/** /**
* Prevent further automatic updates until the next delay. * Prevent further automatic updates until the next delay.
*/ */

View File

@ -52,9 +52,18 @@ public final class Packets {
public static final int PLAYER_POSITION = 11; public static final int PLAYER_POSITION = 11;
public static final int PLAYER_LOOK = 12; public static final int PLAYER_LOOK = 12;
public static final int PLAYER_LOOK_MOVE = 13; public static final int PLAYER_LOOK_MOVE = 13;
/**
* Made bi-directional in 1.4.6.
*/
public static final int BLOCK_ITEM_SWITCH = 16;
public static final int ENTITY_LOCATION_ACTION = 17; public static final int ENTITY_LOCATION_ACTION = 17;
public static final int ARM_ANIMATION = 18; public static final int ARM_ANIMATION = 18;
public static final int NAMED_ENTITY_SPAWN = 20; public static final int NAMED_ENTITY_SPAWN = 20;
/**
* Removed in 1.4.6 and replaced with {@link VEHICLE_SPAWN}.
* @see <a href="http://www.wiki.vg/Protocol_History#2012-12-20">Protocol History - MinecraftCoalition</a>
*/
@Deprecated()
public static final int PICKUP_SPAWN = 21; public static final int PICKUP_SPAWN = 21;
public static final int COLLECT = 22; public static final int COLLECT = 22;
public static final int VEHICLE_SPAWN = 23; public static final int VEHICLE_SPAWN = 23;
@ -153,7 +162,13 @@ public final class Packets {
public static final int HANDSHAKE = 2; public static final int HANDSHAKE = 2;
public static final int CHAT = 3; public static final int CHAT = 3;
public static final int USE_ENTITY = 7; public static final int USE_ENTITY = 7;
/**
* Since 1.3.1, the client no longer sends a respawn packet. Moved to CLIENT_COMMAND.
*/
@Deprecated
public static final int RESPAWN = 9; public static final int RESPAWN = 9;
public static final int FLYING = 10; public static final int FLYING = 10;
public static final int PLAYER_POSITION = 11; public static final int PLAYER_POSITION = 11;
public static final int PLAYER_LOOK = 12; public static final int PLAYER_LOOK = 12;

View File

@ -23,6 +23,8 @@ import org.bukkit.configuration.Configuration;
import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import com.comphenix.protocol.injector.PacketFilterManager.PlayerInjectHooks;
/** /**
* Represents the configuration of ProtocolLib. * Represents the configuration of ProtocolLib.
* *
@ -36,9 +38,10 @@ class ProtocolConfig {
private static final String METRICS_ENABLED = "metrics"; private static final String METRICS_ENABLED = "metrics";
private static final String IGNORE_VERSION_CHECK = "ignore version check"; private static final String IGNORE_VERSION_CHECK = "ignore version check";
private static final String BACKGROUND_COMPILER_ENABLED = "background compiler"; private static final String BACKGROUND_COMPILER_ENABLED = "background compiler";
private static final String INJECTION_METHOD = "injection method";
private static final String UPDATER_NOTIFY = "notify"; private static final String UPDATER_NOTIFY = "notify";
private static final String UPDATER_DOWNLAD = "download"; private static final String UPDATER_DOWNLAD = "download";
private static final String UPDATER_DELAY = "delay"; private static final String UPDATER_DELAY = "delay";
@ -234,6 +237,38 @@ class ProtocolConfig {
updater.set(UPDATER_LAST_TIME, lastTimeSeconds); updater.set(UPDATER_LAST_TIME, lastTimeSeconds);
} }
/**
* Retrieve the default injection method.
* @return Default method.
*/
public PlayerInjectHooks getDefaultMethod() {
return PlayerInjectHooks.NETWORK_SERVER_OBJECT;
}
/**
* Retrieve the injection method that has been set in the configuration, or use a default value.
* @return Injection method to use.
* @throws IllegalArgumentException If the configuration option is malformed.
*/
public PlayerInjectHooks getInjectionMethod() throws IllegalArgumentException {
String text = global.getString(INJECTION_METHOD);
// Default hook if nothing has been set
PlayerInjectHooks hook = getDefaultMethod();
if (text != null)
hook = PlayerInjectHooks.valueOf(text.toUpperCase().replace(" ", "_"));
return hook;
}
/**
* Set the starting injection method to use.
* @return Injection method.
*/
public void setInjectionMethod(PlayerInjectHooks hook) {
global.set(INJECTION_METHOD, hook.name());
}
/** /**
* Save the current configuration file. * Save the current configuration file.
*/ */

View File

@ -37,6 +37,7 @@ import com.comphenix.protocol.error.DetailedErrorReporter;
import com.comphenix.protocol.error.ErrorReporter; import com.comphenix.protocol.error.ErrorReporter;
import com.comphenix.protocol.injector.DelayedSingleTask; import com.comphenix.protocol.injector.DelayedSingleTask;
import com.comphenix.protocol.injector.PacketFilterManager; import com.comphenix.protocol.injector.PacketFilterManager;
import com.comphenix.protocol.injector.PacketFilterManager.PlayerInjectHooks;
import com.comphenix.protocol.metrics.Statistics; import com.comphenix.protocol.metrics.Statistics;
import com.comphenix.protocol.metrics.Updater; import com.comphenix.protocol.metrics.Updater;
import com.comphenix.protocol.reflect.compiler.BackgroundCompiler; import com.comphenix.protocol.reflect.compiler.BackgroundCompiler;
@ -55,7 +56,7 @@ public class ProtocolLibrary extends JavaPlugin {
/** /**
* The maximum version ProtocolLib has been tested with, * The maximum version ProtocolLib has been tested with,
*/ */
private static final String MAXIMUM_MINECRAFT_VERSION = "1.4.6"; private static final String MAXIMUM_MINECRAFT_VERSION = "1.4.7";
/** /**
* The number of milliseconds per second. * The number of milliseconds per second.
@ -136,6 +137,19 @@ public class ProtocolLibrary extends JavaPlugin {
protocolManager = new PacketFilterManager(getClassLoader(), getServer(), unhookTask, detailedReporter); protocolManager = new PacketFilterManager(getClassLoader(), getServer(), unhookTask, detailedReporter);
detailedReporter.addGlobalParameter("manager", protocolManager); detailedReporter.addGlobalParameter("manager", protocolManager);
// Update injection hook
try {
PlayerInjectHooks hook = config.getInjectionMethod();
// Only update the hook if it's different
if (!protocolManager.getPlayerHook().equals(hook)) {
logger.info("Changing player hook from " + protocolManager.getPlayerHook() + " to " + hook);
protocolManager.setPlayerHook(hook);
}
} catch (IllegalArgumentException e) {
detailedReporter.reportWarning(config, "Cannot parse injection method. Using default.", e);
}
// Initialize command handlers // Initialize command handlers
commandProtocol = new CommandProtocol(detailedReporter, this, updater, config); commandProtocol = new CommandProtocol(detailedReporter, this, updater, config);
commandPacket = new CommandPacket(detailedReporter, this, logger, protocolManager); commandPacket = new CommandPacket(detailedReporter, this, logger, protocolManager);
@ -269,12 +283,15 @@ public class ProtocolLibrary extends JavaPlugin {
MinecraftVersion currentVersion = new MinecraftVersion(this.getDescription().getVersion()); MinecraftVersion currentVersion = new MinecraftVersion(this.getDescription().getVersion());
MinecraftVersion newestVersion = null; MinecraftVersion newestVersion = null;
// Skip the file that contains this current instance however
File loadedFile = getFile();
try { try {
// Scan the plugin folder for newer versions of ProtocolLib // Scan the plugin folder for newer versions of ProtocolLib
File pluginFolder = new File("plugins/"); File pluginFolder = new File("plugins/");
for (File candidate : pluginFolder.listFiles()) { for (File candidate : pluginFolder.listFiles()) {
if (candidate.isFile()) { if (candidate.isFile() && !candidate.equals(loadedFile)) {
Matcher match = ourPlugin.matcher(candidate.getName()); Matcher match = ourPlugin.matcher(candidate.getName());
if (match.matches()) { if (match.matches()) {

View File

@ -30,6 +30,7 @@ import com.comphenix.protocol.events.ListeningWhitelist;
import com.comphenix.protocol.events.PacketAdapter; import com.comphenix.protocol.events.PacketAdapter;
import com.comphenix.protocol.events.PacketEvent; import com.comphenix.protocol.events.PacketEvent;
import com.comphenix.protocol.events.PacketListener; import com.comphenix.protocol.events.PacketListener;
import com.comphenix.protocol.utility.WrappedScheduler;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.base.Joiner; import com.google.common.base.Joiner;
@ -298,9 +299,9 @@ public class AsyncListenerHandler {
}); });
} }
@SuppressWarnings("deprecation")
private void scheduleAsync(Runnable runnable) { private void scheduleAsync(Runnable runnable) {
filterManager.getScheduler().scheduleAsyncDelayedTask(listener.getPlugin(), runnable); // Handle deprecation
WrappedScheduler.runAsynchronouslyRepeat(listener.getPlugin(), filterManager.getScheduler(), runnable, 0L, -1L);
} }
/** /**

View File

@ -114,6 +114,9 @@ public class BlockingHashMap<TKey, TValue> {
if (remainingTime > 0) { if (remainingTime > 0) {
TimeUnit.NANOSECONDS.timedWait(lock, remainingTime); TimeUnit.NANOSECONDS.timedWait(lock, remainingTime);
value = backingMap.get(key); value = backingMap.get(key);
} else {
// Timeout elapsed
break;
} }
} }
} }

View File

@ -175,6 +175,14 @@ public class PacketContainer implements Serializable {
return structureModifier.withType(byte.class); return structureModifier.withType(byte.class);
} }
/**
* Retrieves a read/write structure for every boolean field.
* @return A modifier for every boolean field.
*/
public StructureModifier<Boolean> getBooleans() {
return structureModifier.withType(boolean.class);
}
/** /**
* Retrieves a read/write structure for every short field. * Retrieves a read/write structure for every short field.
* @return A modifier for every short field. * @return A modifier for every short field.

View File

@ -50,7 +50,7 @@ public class PlayerInjectionHandler {
/** /**
* The maximum number of milliseconds to wait until a player can be looked up by connection. * The maximum number of milliseconds to wait until a player can be looked up by connection.
*/ */
private static final long TIMEOUT_PLAYER_LOOKUP = 1000; // ms private static final long TIMEOUT_PLAYER_LOOKUP = 2000; // ms
/** /**
* The highest possible packet ID. It's unlikely that this value will ever change. * The highest possible packet ID. It's unlikely that this value will ever change.
@ -486,7 +486,7 @@ public class PlayerInjectionHandler {
if (injector != null) if (injector != null)
injector.sendServerPacket(packet.getHandle(), filters); injector.sendServerPacket(packet.getHandle(), filters);
else else
reporter.reportWarning(this, String.format( throw new PlayerLoggedOutException(String.format(
"Unable to send packet %s (%s): Player %s has logged out.", "Unable to send packet %s (%s): Player %s has logged out.",
packet.getID(), packet, reciever.getName() packet.getID(), packet, reciever.getName()
)); ));
@ -507,7 +507,7 @@ public class PlayerInjectionHandler {
if (injector != null) if (injector != null)
injector.processPacket(mcPacket); injector.processPacket(mcPacket);
else else
reporter.reportWarning(this, String.format( throw new PlayerLoggedOutException(String.format(
"Unable to receieve packet %s. Player %s has logged out.", "Unable to receieve packet %s. Player %s has logged out.",
mcPacket, player.getName() mcPacket, player.getName()
)); ));

View File

@ -51,6 +51,8 @@ import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginDescriptionFile; import org.bukkit.plugin.PluginDescriptionFile;
import com.comphenix.protocol.utility.WrappedScheduler;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
@ -136,7 +138,7 @@ public class Metrics {
/** /**
* The scheduled task * The scheduled task
*/ */
private volatile Scheduling.TaskWrapper task = null; private volatile WrappedScheduler.TaskWrapper task = null;
public Metrics(final Plugin plugin) throws IOException { public Metrics(final Plugin plugin) throws IOException {
if (plugin == null) { if (plugin == null) {
@ -237,7 +239,7 @@ public class Metrics {
} }
// Begin hitting the server with glorious data // Begin hitting the server with glorious data
task = Scheduling.runAsynchronously(plugin, new Runnable() { task = WrappedScheduler.runAsynchronouslyRepeat(plugin, new Runnable() {
private boolean firstPost = true; private boolean firstPost = true;

View File

@ -119,7 +119,12 @@ public class Updater
/** /**
* The updater found an update, but because of the UpdateType being set to NO_DOWNLOAD, it wasn't downloaded. * The updater found an update, but because of the UpdateType being set to NO_DOWNLOAD, it wasn't downloaded.
*/ */
UPDATE_AVAILABLE(7, "The updater found an update, but because of the UpdateType being set to NO_DOWNLOAD, it wasn't downloaded."); UPDATE_AVAILABLE(7, "The updater found an update, but because of the UpdateType being set to NO_DOWNLOAD, it wasn't downloaded."),
/**
* Updating SNAPSHOT versions are not supported. Please perform a manual upgrade.
*/
NOT_SUPPORTED(8, "Updating SNAPSHOT versions are not supported. Please perform a manual upgrade.");
private static final Map<Integer, Updater.UpdateResult> valueList = new HashMap<Integer, Updater.UpdateResult>(); private static final Map<Integer, Updater.UpdateResult> valueList = new HashMap<Integer, Updater.UpdateResult>();
private final int value; private final int value;
@ -479,7 +484,12 @@ public class Updater
remVer=-1; remVer=-1;
} }
if(hasTag(version)||version.equalsIgnoreCase(remoteVersion)||curVer>=remVer) if (hasTag(version))
{
result = Updater.UpdateResult.NOT_SUPPORTED;
return false;
}
else if (version.equalsIgnoreCase(remoteVersion) || curVer>=remVer)
{ {
// We already have the latest version, or this build is tagged for no-update // We already have the latest version, or this build is tagged for no-update
result = Updater.UpdateResult.NO_UPDATE; result = Updater.UpdateResult.NO_UPDATE;

View File

@ -1,4 +1,4 @@
package com.comphenix.protocol.metrics; package com.comphenix.protocol.utility;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import org.bukkit.scheduler.BukkitScheduler; import org.bukkit.scheduler.BukkitScheduler;
@ -9,7 +9,7 @@ import org.bukkit.scheduler.BukkitTask;
* *
* @author Kristian * @author Kristian
*/ */
class Scheduling { public class WrappedScheduler {
/** /**
* Represents a backwards compatible Bukkit task. * Represents a backwards compatible Bukkit task.
*/ */
@ -21,15 +21,26 @@ class Scheduling {
} }
/** /**
* Schedule a given task for asynchronous execution. * Schedule a given task for a single asynchronous execution.
* @param plugin - the owner plugin.
* @param runnable - the task to run.
* @param firstDelay - the amount of time to wait until executing the task.
* @return A cancel token.
*/
public static TaskWrapper runAsynchronouslyOnce(final Plugin plugin, Runnable runnable, long firstDelay) {
return runAsynchronouslyRepeat(plugin, plugin.getServer().getScheduler(), runnable, firstDelay, -1L);
}
/**
* Schedule a given task for multiple asynchronous executions.
* @param plugin - the owner plugin. * @param plugin - the owner plugin.
* @param runnable - the task to run. * @param runnable - the task to run.
* @param firstDelay - the amount of time to wait until executing the task for the first time. * @param firstDelay - the amount of time to wait until executing the task for the first time.
* @param repeatDelay - the amount of time inbetween each execution. If less than zero, the task is only executed once. * @param repeatDelay - the amount of time inbetween each execution. If less than zero, the task is only executed once.
* @return A cancel token. * @return A cancel token.
*/ */
public static TaskWrapper runAsynchronously(final Plugin plugin, Runnable runnable, long firstDelay, long repeatDelay) { public static TaskWrapper runAsynchronouslyRepeat(final Plugin plugin, Runnable runnable, long firstDelay, long repeatDelay) {
return runAsynchronously(plugin, plugin.getServer().getScheduler(), runnable, firstDelay, repeatDelay); return runAsynchronouslyRepeat(plugin, plugin.getServer().getScheduler(), runnable, firstDelay, repeatDelay);
} }
/** /**
@ -41,7 +52,7 @@ class Scheduling {
* @param repeatDelay - the amount of time inbetween each execution. If less than zero, the task is only executed once. * @param repeatDelay - the amount of time inbetween each execution. If less than zero, the task is only executed once.
* @return A cancel token. * @return A cancel token.
*/ */
public static TaskWrapper runAsynchronously(final Plugin plugin, final BukkitScheduler scheduler, Runnable runnable, long firstDelay, long repeatDelay) { public static TaskWrapper runAsynchronouslyRepeat(final Plugin plugin, final BukkitScheduler scheduler, Runnable runnable, long firstDelay, long repeatDelay) {
try { try {
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
final int taskID = scheduler.scheduleAsyncRepeatingTask(plugin, runnable, firstDelay, repeatDelay); final int taskID = scheduler.scheduleAsyncRepeatingTask(plugin, runnable, firstDelay, repeatDelay);

View File

@ -218,6 +218,14 @@ public class WrappedWatchableObject {
modifier.withType(Object.class).write(0, getUnwrapped(newValue)); modifier.withType(Object.class).write(0, getUnwrapped(newValue));
} }
/**
* Read the underlying value field.
* @return The underlying value.
*/
private Object getNMSValue() {
return modifier.withType(Object.class).read(0);
}
/** /**
* Read the value field. * Read the value field.
* @return The watched value. * @return The watched value.
@ -324,7 +332,7 @@ public class WrappedWatchableObject {
// Helper // Helper
Object getClonedValue() throws FieldAccessException { Object getClonedValue() throws FieldAccessException {
Object value = getValue(); Object value = getNMSValue();
// Only a limited set of references types are supported // Only a limited set of references types are supported
if (MinecraftReflection.isChunkPosition(value)) { if (MinecraftReflection.isChunkPosition(value)) {

View File

@ -272,7 +272,7 @@ public interface NbtCompound extends NbtBase<Map<String, NbtBase<?>>>, Iterable<
* @param compound - the compound value. * @param compound - the compound value.
* @return This current compound, for chaining. * @return This current compound, for chaining.
*/ */
public abstract NbtCompound put(WrappedCompound compound); public abstract NbtCompound put(NbtCompound compound);
/** /**
* Retrieve the NBT list value of an entry identified by a given key. * Retrieve the NBT list value of an entry identified by a given key.

View File

@ -524,7 +524,7 @@ class WrappedCompound implements NbtWrapper<Map<String, NbtBase<?>>>, Iterable<N
* @return This current compound, for chaining. * @return This current compound, for chaining.
*/ */
@Override @Override
public NbtCompound put(WrappedCompound compound) { public NbtCompound put(NbtCompound compound) {
getValue().put(compound.getName(), compound); getValue().put(compound.getName(), compound);
return this; return this;
} }

View File

@ -16,3 +16,7 @@ global:
# Disable version checking for the given Minecraft version. Backup your world first! # Disable version checking for the given Minecraft version. Backup your world first!
ignore version check: ignore version check:
# Override the starting injecting method
injection method:

View File

@ -1,5 +1,5 @@
name: ProtocolLib name: ProtocolLib
version: 2.0.0 version: 2.1.0
description: Provides read/write access to the Minecraft protocol. description: Provides read/write access to the Minecraft protocol.
author: Comphenix author: Comphenix
website: http://www.comphenix.net/ProtocolLib website: http://www.comphenix.net/ProtocolLib

View File

@ -0,0 +1,60 @@
package com.comphenix.protocol;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
// Will have to be updated for every version though
import org.bukkit.craftbukkit.v1_4_R1.inventory.CraftItemFactory;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.Server;
import org.bukkit.inventory.ItemFactory;
import org.bukkit.inventory.meta.ItemMeta;
import com.comphenix.protocol.reflect.FieldUtils;
import com.comphenix.protocol.utility.MinecraftReflection;
/**
* Used to ensure that ProtocolLib and Bukkit is prepared to be tested.
*
* @author Kristian
*/
public class BukkitInitialization {
private static boolean initialized;
/**
* Initialize Bukkit and ProtocolLib such that we can perfrom unit testing.
* @throws IllegalAccessException If we are unable to initialize Bukkit.
*/
public static void initializeItemMeta() throws IllegalAccessException {
if (!initialized) {
// Denote that we're done
initialized = true;
initializePackage();
// Mock the server object
Server mockedServer = mock(Server.class);
ItemFactory mockedFactory = mock(CraftItemFactory.class);
ItemMeta mockedMeta = mock(ItemMeta.class);
when(mockedServer.getItemFactory()).thenReturn(mockedFactory);
when(mockedFactory.getItemMeta(any(Material.class))).thenReturn(mockedMeta);
// Inject this fake server
FieldUtils.writeStaticField(Bukkit.class, "server", mockedServer, true);
// And the fake item factory
FieldUtils.writeStaticField(CraftItemFactory.class, "instance", mockedFactory, true);
}
}
/**
* Ensure that package names are correctly set up.
*/
public static void initializePackage() {
// Initialize reflection
MinecraftReflection.setMinecraftPackage("net.minecraft.server.v1_4_R1", "org.bukkit.craftbukkit.v1_4_R1");
}
}

View File

@ -18,31 +18,23 @@
package com.comphenix.protocol.events; package com.comphenix.protocol.events;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.lang.reflect.Array; import java.lang.reflect.Array;
import java.util.List; import java.util.List;
// Will have to be updated for every version though // Will have to be updated for every version though
import org.bukkit.craftbukkit.v1_4_6.inventory.CraftItemFactory; import org.bukkit.craftbukkit.v1_4_R1.inventory.CraftItemFactory;
import org.bukkit.Bukkit;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.Server;
import org.bukkit.WorldType; import org.bukkit.WorldType;
import org.bukkit.inventory.ItemFactory;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.core.classloader.annotations.PrepareForTest;
import com.comphenix.protocol.BukkitInitialization;
import com.comphenix.protocol.Packets; import com.comphenix.protocol.Packets;
import com.comphenix.protocol.reflect.EquivalentConverter; import com.comphenix.protocol.reflect.EquivalentConverter;
import com.comphenix.protocol.reflect.FieldUtils;
import com.comphenix.protocol.reflect.StructureModifier; import com.comphenix.protocol.reflect.StructureModifier;
import com.comphenix.protocol.utility.MinecraftReflection; import com.comphenix.protocol.utility.MinecraftReflection;
import com.comphenix.protocol.wrappers.BukkitConverters; import com.comphenix.protocol.wrappers.BukkitConverters;
@ -65,22 +57,7 @@ public class PacketContainerTest {
@BeforeClass @BeforeClass
public static void initializeBukkit() throws IllegalAccessException { public static void initializeBukkit() throws IllegalAccessException {
// Initialize reflection BukkitInitialization.initializeItemMeta();
MinecraftReflection.setMinecraftPackage("net.minecraft.server.v1_4_6", "org.bukkit.craftbukkit.v1_4_6");
// Mock the server object
Server mockedServer = mock(Server.class);
ItemFactory mockedFactory = mock(CraftItemFactory.class);
ItemMeta mockedMeta = mock(ItemMeta.class);
when(mockedServer.getItemFactory()).thenReturn(mockedFactory);
when(mockedFactory.getItemMeta(any(Material.class))).thenReturn(mockedMeta);
// Inject this fake server
FieldUtils.writeStaticField(Bukkit.class, "server", mockedServer, true);
// And the fake item factory
FieldUtils.writeStaticField(CraftItemFactory.class, "instance", mockedFactory, true);
} }
private <T> void testPrimitive(StructureModifier<T> modifier, int index, T initialValue, T testValue) { private <T> void testPrimitive(StructureModifier<T> modifier, int index, T initialValue, T testValue) {

View File

@ -30,7 +30,6 @@ import com.comphenix.protocol.events.ListenerPriority;
import com.google.common.primitives.Ints; import com.google.common.primitives.Ints;
public class SortedCopyOnWriteArrayTest { public class SortedCopyOnWriteArrayTest {
@Test @Test
public void testInsertion() { public void testInsertion() {

View File

@ -21,13 +21,12 @@ import static org.junit.Assert.*;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
import com.comphenix.protocol.BukkitInitialization;
import com.comphenix.protocol.utility.MinecraftReflection;
public class NbtCompoundTest { public class NbtCompoundTest {
@BeforeClass @BeforeClass
public static void setupBukkit() { public static void initializeBukkit() throws IllegalAccessException {
MinecraftReflection.setMinecraftPackage("net.minecraft.server.v1_4_6", "org.bukkit.craftbukkit.v1_4_6"); BukkitInitialization.initializePackage();
} }
@Test @Test

View File

@ -28,15 +28,13 @@ import java.io.DataOutputStream;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
import com.comphenix.protocol.BukkitInitialization;
import com.comphenix.protocol.utility.MinecraftReflection;
import com.comphenix.protocol.wrappers.nbt.io.NbtBinarySerializer; import com.comphenix.protocol.wrappers.nbt.io.NbtBinarySerializer;
public class NbtFactoryTest { public class NbtFactoryTest {
@BeforeClass @BeforeClass
public static void initializeBukkit() { public static void initializeBukkit() throws IllegalAccessException {
// Initialize reflection BukkitInitialization.initializePackage();
MinecraftReflection.setMinecraftPackage("net.minecraft.server.v1_4_6", "org.bukkit.craftbukkit.v1_4_6");
} }
@Test @Test

View File

@ -6,15 +6,14 @@ import org.bukkit.configuration.file.YamlConfiguration;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
import com.comphenix.protocol.utility.MinecraftReflection; import com.comphenix.protocol.BukkitInitialization;
import com.comphenix.protocol.wrappers.nbt.NbtCompound; import com.comphenix.protocol.wrappers.nbt.NbtCompound;
import com.comphenix.protocol.wrappers.nbt.NbtFactory; import com.comphenix.protocol.wrappers.nbt.NbtFactory;
public class NbtConfigurationSerializerTest { public class NbtConfigurationSerializerTest {
@BeforeClass @BeforeClass
public static void initializeBukkit() { public static void initializeBukkit() throws IllegalAccessException {
// Initialize reflection BukkitInitialization.initializePackage();
MinecraftReflection.setMinecraftPackage("net.minecraft.server.v1_4_6", "org.bukkit.craftbukkit.v1_4_6");
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")