Documentation improvements

This commit is contained in:
Dan Mulloy 2016-04-02 14:47:54 -04:00
parent 74adaba8ac
commit 10ded26d60
14 changed files with 262 additions and 169 deletions

View File

@ -1,27 +1,43 @@
/**
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
* Copyright (C) 2016 dmulloy2
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program;
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA
*/
package com.comphenix.protocol; package com.comphenix.protocol;
import java.text.MessageFormat;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.logging.Level;
import org.apache.commons.lang.Validate;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import com.comphenix.protocol.error.BasicErrorReporter; import com.comphenix.protocol.error.BasicErrorReporter;
import com.comphenix.protocol.error.ErrorReporter; import com.comphenix.protocol.error.ErrorReporter;
import com.google.common.util.concurrent.ListeningScheduledExecutorService; import com.google.common.util.concurrent.ListeningScheduledExecutorService;
/**
* The main entry point for ProtocolLib.
* @author dmulloy2
*/
public class ProtocolLibrary { public class ProtocolLibrary {
public static final long MILLI_PER_SECOND = 1000;
public static final List<String> INCOMPATIBLE = Arrays.asList("TagAPI");
/** /**
* The minimum version ProtocolLib has been tested with. * The minimum version ProtocolLib has been tested with.
*/ */
public static final String MINIMUM_MINECRAFT_VERSION = "1.9"; public static final String MINIMUM_MINECRAFT_VERSION = "1.9";
/** /**
* The maximum version ProtocolLib has been tested with, * The maximum version ProtocolLib has been tested with.
*/ */
public static final String MAXIMUM_MINECRAFT_VERSION = "1.9"; public static final String MAXIMUM_MINECRAFT_VERSION = "1.9";
@ -30,6 +46,11 @@ public class ProtocolLibrary {
*/ */
public static final String MINECRAFT_LAST_RELEASE_DATE = "2016-02-29"; public static final String MINECRAFT_LAST_RELEASE_DATE = "2016-02-29";
/**
* Plugins that are currently incompatible with ProtocolLib.
*/
public static final List<String> INCOMPATIBLE = Arrays.asList("TagAPI");
private static Plugin plugin; private static Plugin plugin;
private static ProtocolConfig config; private static ProtocolConfig config;
private static ProtocolManager manager; private static ProtocolManager manager;
@ -39,58 +60,85 @@ public class ProtocolLibrary {
private static ListeningScheduledExecutorService executorSync; private static ListeningScheduledExecutorService executorSync;
private static boolean updatesDisabled; private static boolean updatesDisabled;
private static boolean initialized;
protected static void init(Plugin plugin, ProtocolConfig config, ProtocolManager manager, ErrorReporter reporter, protected static void init(Plugin plugin, ProtocolConfig config, ProtocolManager manager, ErrorReporter reporter,
ListeningScheduledExecutorService executorAsync, ListeningScheduledExecutorService executorSync) { ListeningScheduledExecutorService executorAsync, ListeningScheduledExecutorService executorSync) {
Validate.isTrue(!initialized, "ProtocolLib has already been initialized.");
ProtocolLibrary.plugin = plugin; ProtocolLibrary.plugin = plugin;
ProtocolLibrary.config = config; ProtocolLibrary.config = config;
ProtocolLibrary.manager = manager; ProtocolLibrary.manager = manager;
ProtocolLibrary.reporter = reporter; ProtocolLibrary.reporter = reporter;
ProtocolLibrary.executorAsync = executorAsync; ProtocolLibrary.executorAsync = executorAsync;
ProtocolLibrary.executorSync = executorSync; ProtocolLibrary.executorSync = executorSync;
ProtocolLogger.init(plugin);
initialized = true;
} }
/**
* Gets the ProtocolLib plugin instance.
* @return The plugin instance
*/
public static Plugin getPlugin() { public static Plugin getPlugin() {
return plugin; return plugin;
} }
/**
* Gets ProtocolLib's configuration
* @return The config
*/
public static ProtocolConfig getConfig() { public static ProtocolConfig getConfig() {
return config; return config;
} }
/**
* Retrieves the packet protocol manager.
* @return Packet protocol manager
*/
public static ProtocolManager getProtocolManager() { public static ProtocolManager getProtocolManager() {
return manager; return manager;
} }
/**
* Retrieve the current error reporter.
* @return Current error reporter.
*/
public static ErrorReporter getErrorReporter() { public static ErrorReporter getErrorReporter() {
return reporter; return reporter;
} }
public static void disableUpdates() { /**
updatesDisabled = true; * Retrieve an executor service for performing asynchronous tasks on the behalf of ProtocolLib.
} * <p>
* Note that this service is NULL if ProtocolLib has not been initialized yet.
public static boolean updatesDisabled() { * @return The executor service, or NULL.
return updatesDisabled; */
}
public static ListeningScheduledExecutorService getExecutorAsync() { public static ListeningScheduledExecutorService getExecutorAsync() {
return executorAsync; return executorAsync;
} }
/**
* Retrieve an executor service for performing synchronous tasks (main thread) on the behalf of ProtocolLib.
* <p>
* Note that this service is NULL if ProtocolLib has not been initialized yet.
* @return The executor service, or NULL.
*/
public static ListeningScheduledExecutorService getExecutorSync() { public static ListeningScheduledExecutorService getExecutorSync() {
return executorSync; return executorSync;
} }
public static void log(Level level, String message, Object... args) { /**
plugin.getLogger().log(level, MessageFormat.format(message, args)); * Disables the ProtocolLib update checker.
*/
public static void disableUpdates() {
updatesDisabled = true;
} }
public static void log(String message, Object... args) { /**
log(Level.INFO, message, args); * Whether or not updates are currently disabled.
} * @return True if it is, false if not
*/
public static void log(Level level, String message, Throwable ex) { public static boolean updatesDisabled() {
plugin.getLogger().log(level, message, ex); return updatesDisabled;
} }
} }

View File

@ -0,0 +1,63 @@
/**
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
* Copyright (C) 2016 dmulloy2
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program;
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA
*/
package com.comphenix.protocol;
import java.text.MessageFormat;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.bukkit.plugin.Plugin;
/**
* @author dmulloy2
*/
public class ProtocolLogger {
private static Logger logger;
protected static void init(Plugin plugin) {
ProtocolLogger.logger = plugin.getLogger();
}
/**
* Logs a message to console with a given level.
* @param level Logging level
* @param message Message to log
* @param args Arguments to format in
*/
public static void log(Level level, String message, Object... args) {
logger.log(level, MessageFormat.format(message, args));
}
/**
* Logs a method to console with the INFO level.
* @param message Message to log
* @param args Arguments to format in
*/
public static void log(String message, Object... args) {
log(Level.INFO, message, args);
}
/**
* Logs a message to console with a given level and exception.
* @param level Logging level
* @param message Message to log
* @param ex Exception to log
*/
public static void log(Level level, String message, Throwable ex) {
logger.log(level, message, ex);
}
}

View File

@ -28,7 +28,7 @@ import java.util.logging.Level;
import com.comphenix.protocol.PacketStream; import com.comphenix.protocol.PacketStream;
import com.comphenix.protocol.PacketType; import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.ProtocolLogger;
import com.comphenix.protocol.events.NetworkMarker; import com.comphenix.protocol.events.NetworkMarker;
import com.comphenix.protocol.events.PacketEvent; import com.comphenix.protocol.events.PacketEvent;
import com.comphenix.protocol.injector.PrioritizedListener; import com.comphenix.protocol.injector.PrioritizedListener;
@ -429,15 +429,17 @@ public class AsyncMarker implements Serializable, Comparable<AsyncMarker> {
// Incoming chat packets are async only if they aren't commands // Incoming chat packets are async only if they aren't commands
return ! content.startsWith("/"); return ! content.startsWith("/");
} else { } else {
ProtocolLibrary.log(Level.WARNING, "Failed to determine contents of incoming chat packet!"); ProtocolLogger.log(Level.WARNING, "Failed to determine contents of incoming chat packet!");
alwaysSync = true; alwaysSync = true;
} }
} else if (event.getPacketType() == PacketType.Status.Server.SERVER_INFO) {
return true;
} else { } else {
// TODO: Find more cases of async packets // TODO: Find more cases of async packets
return false; return false;
} }
} else { } else {
ProtocolLibrary.log(Level.INFO, "Could not determine asynchronous state of packets (this can probably be ignored)"); ProtocolLogger.log(Level.INFO, "Could not determine asynchronous state of packets (this can probably be ignored)");
alwaysSync = true; alwaysSync = true;
} }
} }

View File

@ -35,7 +35,7 @@ import org.apache.commons.lang.builder.ToStringStyle;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.ProtocolLogger;
import com.comphenix.protocol.collections.ExpireHashMap; import com.comphenix.protocol.collections.ExpireHashMap;
import com.comphenix.protocol.error.Report.ReportBuilder; import com.comphenix.protocol.error.Report.ReportBuilder;
import com.comphenix.protocol.events.PacketAdapter; import com.comphenix.protocol.events.PacketAdapter;
@ -464,13 +464,15 @@ public class DetailedErrorReporter implements ErrorReporter {
} else { } else {
try { try {
if (!apacheCommonsMissing) if (!apacheCommonsMissing)
return (ToStringBuilder.reflectionToString(value, ToStringStyle.MULTI_LINE_STYLE, false, null)); return ToStringBuilder.reflectionToString(value, ToStringStyle.MULTI_LINE_STYLE, false, null);
} catch (LinkageError ex) { } catch (LinkageError ex) {
// Apache is probably missing // Apache is probably missing
apacheCommonsMissing = true; apacheCommonsMissing = true;
} catch (Exception e) { } catch (ThreadDeath | OutOfMemoryError e) {
throw e;
} catch (Throwable ex) {
// Don't use the error logger to log errors in error logging (that could lead to infinite loops) // Don't use the error logger to log errors in error logging (that could lead to infinite loops)
ProtocolLibrary.log(Level.WARNING, "Cannot convert to a String with Apache: " + e.getMessage()); ProtocolLogger.log(Level.WARNING, "Cannot convert to a String with Apache: " + ex.getMessage());
} }
// Use our custom object printer instead // Use our custom object printer instead

View File

@ -27,6 +27,7 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level; import java.util.logging.Level;
import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.ProtocolLogger;
import com.comphenix.protocol.error.PluginContext; import com.comphenix.protocol.error.PluginContext;
import com.comphenix.protocol.reflect.compiler.BackgroundCompiler; import com.comphenix.protocol.reflect.compiler.BackgroundCompiler;
import com.comphenix.protocol.reflect.instances.BannedGenerator; import com.comphenix.protocol.reflect.instances.BannedGenerator;
@ -198,8 +199,8 @@ public class StructureModifier<TField> {
} catch (FieldAccessException ex) { } catch (FieldAccessException ex) {
String plugin = PluginContext.getPluginCaller(ex); String plugin = PluginContext.getPluginCaller(ex);
if (ProtocolLibrary.INCOMPATIBLE.contains(plugin)) { if (ProtocolLibrary.INCOMPATIBLE.contains(plugin)) {
ProtocolLibrary.log(Level.WARNING, "Encountered an exception caused by incompatible plugin {0}.", plugin); ProtocolLogger.log(Level.WARNING, "Encountered an exception caused by incompatible plugin {0}.", plugin);
ProtocolLibrary.log(Level.WARNING, "It is advised that you remove it."); ProtocolLogger.log(Level.WARNING, "It is advised that you remove it.");
} }
throw ex; throw ex;
@ -328,8 +329,8 @@ public class StructureModifier<TField> {
} catch (FieldAccessException ex) { } catch (FieldAccessException ex) {
String plugin = PluginContext.getPluginCaller(ex); String plugin = PluginContext.getPluginCaller(ex);
if (ProtocolLibrary.INCOMPATIBLE.contains(plugin)) { if (ProtocolLibrary.INCOMPATIBLE.contains(plugin)) {
ProtocolLibrary.log(Level.WARNING, "Encountered an exception caused by incompatible plugin {0}.", plugin); ProtocolLogger.log(Level.WARNING, "Encountered an exception caused by incompatible plugin {0}.", plugin);
ProtocolLibrary.log(Level.WARNING, "It is advised that you remove it."); ProtocolLogger.log(Level.WARNING, "It is advised that you remove it.");
} }
throw ex; throw ex;

View File

@ -19,7 +19,7 @@ package com.comphenix.protocol.reflect;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.ProtocolLogger;
import com.comphenix.protocol.reflect.accessors.Accessors; import com.comphenix.protocol.reflect.accessors.Accessors;
import com.comphenix.protocol.reflect.accessors.FieldAccessor; import com.comphenix.protocol.reflect.accessors.FieldAccessor;
import com.google.common.base.Objects; import com.google.common.base.Objects;
@ -184,8 +184,7 @@ public class VolatileField {
currentSet = false; currentSet = false;
} else { } else {
// This can be a bad sign // This can be a bad sign
ProtocolLibrary.log("Unable to switch {0} to {1}. Expected {2}, but got {3}.", ProtocolLogger.log("Unable to switch {0} to {1}. Expected {2}, but got {3}.", getField().toGenericString(), previous, current, getValue());
getField().toGenericString(), previous, current, getValue());
} }
} }
} }

View File

@ -26,7 +26,7 @@ import javax.annotation.Nullable;
import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.Enhancer;
import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.ProtocolLogger;
import com.google.common.base.Objects; import com.google.common.base.Objects;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
@ -284,7 +284,7 @@ public class DefaultInstances implements InstanceProvider {
// Did we break the non-null contract? // Did we break the non-null contract?
if (params[i] == null && nonNull) { if (params[i] == null && nonNull) {
ProtocolLibrary.log(Level.WARNING, "Nonnull contract broken."); ProtocolLogger.log(Level.WARNING, "Nonnull contract broken.");
return null; return null;
} }
} }

View File

@ -46,6 +46,7 @@ import org.bukkit.inventory.ItemStack;
import com.comphenix.protocol.PacketType; import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.ProtocolLogger;
import com.comphenix.protocol.error.ErrorReporter; import com.comphenix.protocol.error.ErrorReporter;
import com.comphenix.protocol.error.Report; import com.comphenix.protocol.error.Report;
import com.comphenix.protocol.error.ReportType; import com.comphenix.protocol.error.ReportType;
@ -208,7 +209,7 @@ public class MinecraftReflection {
if (MinecraftVersion.SCARY_UPDATE.compareTo(version) <= 0) { if (MinecraftVersion.SCARY_UPDATE.compareTo(version) <= 0) {
// Just assume R1 - it's probably fine // Just assume R1 - it's probably fine
packageVersion = "v" + version.getMajor() + "_" + version.getMinor() + "_R1"; packageVersion = "v" + version.getMajor() + "_" + version.getMinor() + "_R1";
ProtocolLibrary.log(Level.WARNING, "Assuming package version: " + packageVersion); ProtocolLogger.log(Level.WARNING, "Assuming package version: " + packageVersion);
} }
} }

View File

@ -16,48 +16,24 @@
*/ */
package com.comphenix.protocol.utility; package com.comphenix.protocol.utility;
import java.lang.reflect.Method;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List; import java.util.List;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import com.comphenix.protocol.reflect.accessors.Accessors;
import com.comphenix.protocol.reflect.accessors.MethodAccessor;
/** /**
* General utility class * General utility class
* @author dmulloy2 * @author dmulloy2
*/ */
public class Util { public class Util {
private static MethodAccessor getOnlinePlayers;
private static boolean reflectionRequired;
static {
try {
Method method = Bukkit.class.getMethod("getOnlinePlayers");
getOnlinePlayers = Accessors.getMethodAccessor(method);
reflectionRequired = !method.getReturnType().isAssignableFrom(Collection.class);
} catch (Throwable ex) {
throw new RuntimeException("Failed to obtain getOnlinePlayers method.", ex);
}
}
/** /**
* Gets a list of online {@link Player}s. This also provides backwards * Gets a list of currently online Players.
* compatibility, since Bukkit changed getOnlinePlayers in 1.7.9. * @return The list
* @return A list of currently online Players
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public static List<Player> getOnlinePlayers() { public static List<Player> getOnlinePlayers() {
if (reflectionRequired) {
return Arrays.asList((Player[]) getOnlinePlayers.invoke(null));
}
return (List<Player>) Bukkit.getOnlinePlayers(); return (List<Player>) Bukkit.getOnlinePlayers();
} }

View File

@ -23,6 +23,10 @@ import com.comphenix.protocol.reflect.StructureModifier;
import com.comphenix.protocol.utility.MinecraftReflection; import com.comphenix.protocol.utility.MinecraftReflection;
/** /**
* Represents a MinecraftKey in 1.9.
* <p>
* Keys are in the format {@code prefix:key}
*
* @author dmulloy2 * @author dmulloy2
*/ */
@ -30,36 +34,75 @@ public class MinecraftKey {
private final String prefix; private final String prefix;
private final String key; private final String key;
/**
* Constructs a new key with a given prefix and key.
*
* @param prefix The prefix, usually minecraft.
* @param key The key, the part we care about
*/
public MinecraftKey(String prefix, String key) { public MinecraftKey(String prefix, String key) {
this.prefix = prefix; this.prefix = prefix;
this.key = key; this.key = key;
} }
/**
* Constructs a new key with minecraft prefix and a key.
* @param key The key
*/
public MinecraftKey(String key) { public MinecraftKey(String key) {
this("minecraft", key); this("minecraft", key);
} }
/**
* Creates a MinecraftKey wrapper from a Minecraft handle.
* @param handle The handle
* @return The resulting key
*/
public static MinecraftKey fromHandle(Object handle) { public static MinecraftKey fromHandle(Object handle) {
StructureModifier<String> modifier = new StructureModifier<String>(handle.getClass()).withTarget(handle).withType(String.class); StructureModifier<String> modifier = new StructureModifier<String>(handle.getClass()).withTarget(handle).withType(String.class);
return new MinecraftKey(modifier.read(0), modifier.read(1)); return new MinecraftKey(modifier.read(0), modifier.read(1));
} }
/**
* Creates a MinecraftKey wrapper from an Enum constant. The resulting key
* is lower case, with underscores replaced by periods.
* @param value The value
* @return The resulting key
*/
public static MinecraftKey fromEnum(Enum<?> value) { public static MinecraftKey fromEnum(Enum<?> value) {
return new MinecraftKey(value.name().toLowerCase().replace("_", ".")); return new MinecraftKey(value.name().toLowerCase().replace("_", "."));
} }
/**
* Gets the prefix of this MinecraftKey. It is minecraft by default.
* @return The prefix
*/
public String getPrefix() { public String getPrefix() {
return prefix; return prefix;
} }
/**
* Gets the key of this MinecraftKey. It is generally the important part.
* @return The key
*/
public String getKey() { public String getKey() {
return key; return key;
} }
/**
* Gets the full key of this MinecraftKey. It is in the format of
* {@code prefix:key}
* @return The full key
*/
public String getFullKey() { public String getFullKey() {
return prefix + ":" + key; return prefix + ":" + key;
} }
/**
* Returns this key back into Enum format, upper case with periods replaced
* by underscores.
* @return The enum format
*/
public String getEnumFormat() { public String getEnumFormat() {
return key.toUpperCase().replace(".", "_"); return key.toUpperCase().replace(".", "_");
} }

View File

@ -68,8 +68,11 @@ public class WrappedDataWatcher extends AbstractWrapper implements Iterable<Wrap
// ---- Construction // ---- Construction
/** /**
* Constructs a wrapped data watcher around an existing NMS data watcher. * Constructs a new DataWatcher wrapper around a NMS handle. The resulting
* @param handle NMS data watcher * DataWatcher will likely have existing values that can be removed with
* {@link #clear()}.
*
* @param handle DataWatcher handle
*/ */
public WrappedDataWatcher(Object handle) { public WrappedDataWatcher(Object handle) {
super(HANDLE_TYPE); super(HANDLE_TYPE);
@ -77,14 +80,19 @@ public class WrappedDataWatcher extends AbstractWrapper implements Iterable<Wrap
} }
/** /**
* Constructs a new DataWatcher using a fake entity. * Constructs a new DataWatcher using a fake lightning entity. The
* resulting DataWatcher will not have any keys or values and new ones will
* have to be added using watcher objects.
*/ */
public WrappedDataWatcher() { public WrappedDataWatcher() {
this(newHandle(fakeEntity())); this(newHandle(fakeEntity()));
} }
/** /**
* Constructs a new DataWatcher using a real entity. * Constructs a new DataWatcher using a real entity. The resulting
* DataWatcher will not have any keys or values and new ones will have to
* be added using watcher objects.
*
* @param entity The entity * @param entity The entity
*/ */
public WrappedDataWatcher(Entity entity) { public WrappedDataWatcher(Entity entity) {
@ -221,6 +229,14 @@ public class WrappedDataWatcher extends AbstractWrapper implements Iterable<Wrap
return getMap().containsKey(index); return getMap().containsKey(index);
} }
/**
* Clears the contents of this DataWatcher. The watcher will be empty after
* this operation is called.
*/
public void clear() {
getMap().clear();
}
// ---- Object Getters // ---- Object Getters
/** /**
@ -228,9 +244,8 @@ public class WrappedDataWatcher extends AbstractWrapper implements Iterable<Wrap
* *
* @param index - index of the watched byte. * @param index - index of the watched byte.
* @return The watched byte, or NULL if this value doesn't exist. * @return The watched byte, or NULL if this value doesn't exist.
* @throws FieldAccessException Cannot read underlying field.
*/ */
public Byte getByte(int index) throws FieldAccessException { public Byte getByte(int index) {
return (Byte) getObject(index); return (Byte) getObject(index);
} }
@ -239,9 +254,8 @@ public class WrappedDataWatcher extends AbstractWrapper implements Iterable<Wrap
* *
* @param index - index of the watched short. * @param index - index of the watched short.
* @return The watched short, or NULL if this value doesn't exist. * @return The watched short, or NULL if this value doesn't exist.
* @throws FieldAccessException Cannot read underlying field.
*/ */
public Short getShort(int index) throws FieldAccessException { public Short getShort(int index) {
return (Short) getObject(index); return (Short) getObject(index);
} }
@ -250,9 +264,8 @@ public class WrappedDataWatcher extends AbstractWrapper implements Iterable<Wrap
* *
* @param index - index of the watched integer. * @param index - index of the watched integer.
* @return The watched integer, or NULL if this value doesn't exist. * @return The watched integer, or NULL if this value doesn't exist.
* @throws FieldAccessException Cannot read underlying field.
*/ */
public Integer getInteger(int index) throws FieldAccessException { public Integer getInteger(int index) {
return (Integer) getObject(index); return (Integer) getObject(index);
} }
@ -261,9 +274,8 @@ public class WrappedDataWatcher extends AbstractWrapper implements Iterable<Wrap
* *
* @param index - index of the watched float. * @param index - index of the watched float.
* @return The watched float, or NULL if this value doesn't exist. * @return The watched float, or NULL if this value doesn't exist.
* @throws FieldAccessException Cannot read underlying field.
*/ */
public Float getFloat(int index) throws FieldAccessException { public Float getFloat(int index) {
return (Float) getObject(index); return (Float) getObject(index);
} }
@ -272,9 +284,8 @@ public class WrappedDataWatcher extends AbstractWrapper implements Iterable<Wrap
* *
* @param index - index of the watched string. * @param index - index of the watched string.
* @return The watched string, or NULL if this value doesn't exist. * @return The watched string, or NULL if this value doesn't exist.
* @throws FieldAccessException Cannot read underlying field.
*/ */
public String getString(int index) throws FieldAccessException { public String getString(int index) {
return (String) getObject(index); return (String) getObject(index);
} }
@ -283,9 +294,8 @@ public class WrappedDataWatcher extends AbstractWrapper implements Iterable<Wrap
* *
* @param index - index of the watched string. * @param index - index of the watched string.
* @return The watched string, or NULL if this value doesn't exist. * @return The watched string, or NULL if this value doesn't exist.
* @throws FieldAccessException Cannot read underlying field.
*/ */
public ItemStack getItemStack(int index) throws FieldAccessException { public ItemStack getItemStack(int index) {
return (ItemStack) getObject(index); return (ItemStack) getObject(index);
} }
@ -294,9 +304,8 @@ public class WrappedDataWatcher extends AbstractWrapper implements Iterable<Wrap
* *
* @param index - index of the watched string. * @param index - index of the watched string.
* @return The watched string, or NULL if this value doesn't exist. * @return The watched string, or NULL if this value doesn't exist.
* @throws FieldAccessException Cannot read underlying field.
*/ */
public WrappedChunkCoordinate getChunkCoordinate(int index) throws FieldAccessException { public WrappedChunkCoordinate getChunkCoordinate(int index) {
return (WrappedChunkCoordinate) getObject(index); return (WrappedChunkCoordinate) getObject(index);
} }
@ -306,7 +315,7 @@ public class WrappedDataWatcher extends AbstractWrapper implements Iterable<Wrap
* @param index Index of the object to retrieve. * @param index Index of the object to retrieve.
* @return The watched object. * @return The watched object.
*/ */
public Object getObject(int index) throws FieldAccessException { public Object getObject(int index) {
return getObject(new WrappedDataWatcherObject(index, null)); return getObject(new WrappedDataWatcherObject(index, null));
} }
@ -334,6 +343,8 @@ public class WrappedDataWatcher extends AbstractWrapper implements Iterable<Wrap
* *
* @param index Index of the object to set * @param index Index of the object to set
* @param value New value * @param value New value
*
* @see {@link #setObject(WrappedDataWatcherObject, Object)}
*/ */
public void setObject(int index, Object value) { public void setObject(int index, Object value) {
Validate.isTrue(hasIndex(index), "You cannot register objects without the watcher object!"); Validate.isTrue(hasIndex(index), "You cannot register objects without the watcher object!");
@ -346,6 +357,8 @@ public class WrappedDataWatcher extends AbstractWrapper implements Iterable<Wrap
* @param index Index of the object to set * @param index Index of the object to set
* @param Serializer Serializer from {@link Serializer#get(Class)} * @param Serializer Serializer from {@link Serializer#get(Class)}
* @param value New value * @param value New value
*
* @see {@link #setObject(WrappedDataWatcherObject, Object)}
*/ */
public void setObject(int index, Serializer serializer, Object value) { public void setObject(int index, Serializer serializer, Object value) {
setObject(new WrappedDataWatcherObject(index, serializer), value); setObject(new WrappedDataWatcherObject(index, serializer), value);
@ -356,16 +369,23 @@ public class WrappedDataWatcher extends AbstractWrapper implements Iterable<Wrap
* *
* @param object Associated watcher object * @param object Associated watcher object
* @param value Wrapped value * @param value Wrapped value
*
* @see {@link #setObject(WrappedDataWatcherObject, Object)}
*/ */
public void setObject(WrappedDataWatcherObject object, WrappedWatchableObject value) { public void setObject(WrappedDataWatcherObject object, WrappedWatchableObject value) {
setObject(object, value.getRawValue()); setObject(object, value.getRawValue());
} }
/** /**
* Sets the DataWatcher Item associated with a given watcher object to a new value. * Sets the DataWatcher Item associated with a given watcher object to a
* new value. If there is not already an object at this index, the
* specified watcher object must have a serializer.
* *
* @param object Associated watcher object * @param object Associated watcher object
* @param value New value * @param value New value
*
* @throws IllegalArgumentException If the watcher object is null or must
* have a serializer and does not have one.
*/ */
public void setObject(WrappedDataWatcherObject object, Object value) { public void setObject(WrappedDataWatcherObject object, Object value) {
Validate.notNull(object, "Watcher object cannot be null!"); Validate.notNull(object, "Watcher object cannot be null!");
@ -512,7 +532,8 @@ public class WrappedDataWatcher extends AbstractWrapper implements Iterable<Wrap
// ---- 1.9 classes // ---- 1.9 classes
/** /**
* Represents a DataWatcherObject in 1.9. * Represents a DataWatcherObject in 1.9. In order to register an object,
* the serializer must be specified.
* *
* @author dmulloy2 * @author dmulloy2
*/ */
@ -524,9 +545,9 @@ public class WrappedDataWatcher extends AbstractWrapper implements Iterable<Wrap
private final StructureModifier<Object> modifier; private final StructureModifier<Object> modifier;
/** /**
* Creates a new watcher object from a NMS handle * Creates a new watcher object from a NMS handle.
* *
* @param handle NMS handle * @param handle The handle
*/ */
public WrappedDataWatcherObject(Object handle) { public WrappedDataWatcherObject(Object handle) {
super(HANDLE_TYPE); super(HANDLE_TYPE);
@ -536,7 +557,7 @@ public class WrappedDataWatcher extends AbstractWrapper implements Iterable<Wrap
} }
/** /**
* Creates a new watcher object from an index and serializer * Creates a new watcher object from an index and serializer.
* *
* @param index Index * @param index Index
* @param serializer Serializer, see {@link Registry} * @param serializer Serializer, see {@link Registry}
@ -564,7 +585,8 @@ public class WrappedDataWatcher extends AbstractWrapper implements Iterable<Wrap
} }
/** /**
* Gets this watcher object's serializer. Will return null if the serializer was never specified. * Gets this watcher object's serializer. Will return null if the
* serializer was never specified.
* *
* @return The serializer, or null * @return The serializer, or null
*/ */
@ -594,7 +616,8 @@ public class WrappedDataWatcher extends AbstractWrapper implements Iterable<Wrap
} }
/** /**
* Represents a DataWatcherSerializer in 1.9. * Represents a DataWatcherSerializer in 1.9. If a Serializer is optional,
* values must be wrapped in a {@link Optional}.
* *
* @author dmulloy2 * @author dmulloy2
*/ */
@ -629,7 +652,8 @@ public class WrappedDataWatcher extends AbstractWrapper implements Iterable<Wrap
} }
/** /**
* Whether or not this serializer is optional, that is whether or not the return type is wrapped in a {@link Optional}. * Whether or not this serializer is optional, that is whether or not
* the return type is wrapped in a {@link Optional}.
* *
* @return True if it is, false if not * @return True if it is, false if not
*/ */
@ -644,7 +668,8 @@ public class WrappedDataWatcher extends AbstractWrapper implements Iterable<Wrap
} }
/** /**
* Represents a DataWatcherRegistry containing the supported {@link Serializer}s in 1.9. * Represents a DataWatcherRegistry containing the supported
* {@link Serializer}s in 1.9.
* *
* <ul> * <ul>
* <li>Byte</li> * <li>Byte</li>
@ -668,14 +693,6 @@ public class WrappedDataWatcher extends AbstractWrapper implements Iterable<Wrap
private static boolean INITIALIZED = false; private static boolean INITIALIZED = false;
private static List<Serializer> REGISTRY = new ArrayList<>(); private static List<Serializer> REGISTRY = new ArrayList<>();
/**
* Gets the serializer associated with a given class. </br>
* <b>Note</b>: If {@link Serializer#isOptional()}, the values must be wrapped in {@link Optional}
*
* @param clazz Class to find serializer for
* @return The serializer, or null if none exists
*/
/** /**
* Gets the first serializer associated with a given class. * Gets the first serializer associated with a given class.
* *
@ -704,7 +721,8 @@ public class WrappedDataWatcher extends AbstractWrapper implements Iterable<Wrap
/** /**
* Gets the first serializer associated with a given class and optional state. * Gets the first serializer associated with a given class and optional state.
* *
* <p><b>Note</b>: If the serializer is optional, values <i>must<i> be wrapped in an {@link Optional} * <p><b>Note</b>: If the serializer is optional, values <i>must<i> be
* wrapped in an {@link Optional}
* *
* @param clazz Class to find serializer for * @param clazz Class to find serializer for
* @param optional Optional state * @param optional Optional state
@ -726,7 +744,7 @@ public class WrappedDataWatcher extends AbstractWrapper implements Iterable<Wrap
/** /**
* Gets the serializer associated with a given NMS handle. * Gets the serializer associated with a given NMS handle.
* @param handle The NMS handle * @param handle The handle
* @return The serializer, or null if none exists * @return The serializer, or null if none exists
*/ */
public static Serializer fromHandle(Object handle) { public static Serializer fromHandle(Object handle) {

View File

@ -23,6 +23,7 @@ import java.io.PrintWriter;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import java.util.Set; import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level; import java.util.logging.Level;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
@ -193,7 +194,7 @@ class CommandProtocol extends CommandBase {
* Prevent further automatic updates until the next delay. * Prevent further automatic updates until the next delay.
*/ */
public void updateFinished() { public void updateFinished() {
long currentTime = System.currentTimeMillis() / ProtocolLibrary.MILLI_PER_SECOND; long currentTime = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis());
config.setAutoLastTime(currentTime); config.setAutoLastTime(currentTime);
config.saveAll(); config.saveAll();
@ -263,7 +264,7 @@ class CommandProtocol extends CommandBase {
sender.sendMessage("Data dump written to " + file.getAbsolutePath()); sender.sendMessage("Data dump written to " + file.getAbsolutePath());
} catch (IOException ex) { } catch (IOException ex) {
ProtocolLibrary.log(Level.SEVERE, "Failed to create dump:", ex); ProtocolLogger.log(Level.SEVERE, "Failed to create dump:", ex);
sender.sendMessage(ChatColor.RED + "Failed to create dump! Check console!"); sender.sendMessage(ChatColor.RED + "Failed to create dump! Check console!");
} finally { } finally {
closer.close(); closer.close();

View File

@ -18,7 +18,6 @@ package com.comphenix.protocol;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.text.MessageFormat;
import java.util.Set; import java.util.Set;
import java.util.logging.Handler; import java.util.logging.Handler;
import java.util.logging.Level; import java.util.logging.Level;
@ -597,13 +596,13 @@ public class ProtocolLib extends JavaPlugin {
long updateTime = config.getAutoLastTime() + config.getAutoDelay(); long updateTime = config.getAutoLastTime() + config.getAutoDelay();
// Should we update? // Should we update?
if (currentTime > updateTime && !updater.isChecking()) { if (currentTime > updateTime && !updater.isChecking()) {
// Initiate the update as if it came from the console // Initiate the update as if it came from the console
if (config.isAutoDownload()) if (config.isAutoDownload())
commandProtocol.updateVersion(getServer().getConsoleSender(), false); commandProtocol.updateVersion(getServer().getConsoleSender(), false);
else if (config.isAutoNotify()) else if (config.isAutoNotify())
commandProtocol.checkVersion(getServer().getConsoleSender(), false); commandProtocol.checkVersion(getServer().getConsoleSender(), false);
else else
commandProtocol.updateFinished(); commandProtocol.updateFinished();
} }
} catch (Exception e) { } catch (Exception e) {
@ -669,32 +668,6 @@ public class ProtocolLib extends JavaPlugin {
return log; return log;
} }
/**
* Retrieve the current error reporter.
* <p>
* This is guaranteed to not be NULL in 2.5.0 and later.
* @return Current error reporter.
*/
public static ErrorReporter getErrorReporter() {
return reporter;
}
/**
* Retrieve the current strongly typed configuration.
* @return The configuration, or NULL if ProtocolLib hasn't loaded yet.
*/
public static ProtocolConfig getConfiguration() {
return config;
}
/**
* Retrieves the packet protocol manager.
* @return Packet protocol manager, or NULL if it has been disabled.
*/
public static ProtocolManager getProtocolManager() {
return protocolManager;
}
/** /**
* Retrieve the metrics instance used to measure users of this library. * Retrieve the metrics instance used to measure users of this library.
* <p> * <p>
@ -705,38 +678,4 @@ public class ProtocolLib extends JavaPlugin {
public Statistics getStatistics() { public Statistics getStatistics() {
return statistics; return statistics;
} }
}
/**
* Retrieve an executor service for performing asynchronous tasks on the behalf of ProtocolLib.
* <p>
* Note that this service is NULL if ProtocolLib has not been initialized yet.
* @return The executor service, or NULL.
*/
public static ListeningScheduledExecutorService getExecutorAsync() {
return executorAsync;
}
/**
* Retrieve an executor service for performing synchronous tasks (main thread) on the behalf of ProtocolLib.
* <p>
* Note that this service is NULL if ProtocolLib has not been initialized yet.
* @return The executor service, or NULL.
*/
public static ListeningScheduledExecutorService getExecutorSync() {
return executorSync;
}
// ---- Logging Methods
public static void log(Level level, String message, Object... args) {
logger.log(level, MessageFormat.format(message, args));
}
public static void log(String message, Object... args) {
log(Level.INFO, message, args);
}
public static void log(Level level, String message, Throwable ex) {
logger.log(level, message, ex);
}
}