Correct line endings
Also ensure every file ends with a new line for consistency
Dieser Commit ist enthalten in:
Ursprung
9ecbea68ca
Commit
1ca7973b77
@ -152,4 +152,4 @@ public interface AsynchronousManager {
|
||||
* @return Set of every asynchronous packet listener.
|
||||
*/
|
||||
public abstract Set<PacketListener> getAsyncHandlers();
|
||||
}
|
||||
}
|
||||
|
@ -1082,4 +1082,4 @@ public class PacketType implements Serializable, Comparable<PacketType> {
|
||||
else
|
||||
return clazz.getSimpleName() + "[" + currentId + ", legacy: " + legacyId + "]";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Datei-Diff unterdrückt, da er zu groß ist
Diff laden
@ -1,144 +1,144 @@
|
||||
/**
|
||||
* 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.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import com.comphenix.protocol.error.BasicErrorReporter;
|
||||
import com.comphenix.protocol.error.ErrorReporter;
|
||||
import com.google.common.util.concurrent.ListeningScheduledExecutorService;
|
||||
|
||||
/**
|
||||
* The main entry point for ProtocolLib.
|
||||
* @author dmulloy2
|
||||
*/
|
||||
public class ProtocolLibrary {
|
||||
/**
|
||||
* The minimum version ProtocolLib has been tested with.
|
||||
*/
|
||||
public static final String MINIMUM_MINECRAFT_VERSION = "1.9";
|
||||
|
||||
/**
|
||||
* The maximum version ProtocolLib has been tested with.
|
||||
*/
|
||||
public static final String MAXIMUM_MINECRAFT_VERSION = "1.9.4";
|
||||
|
||||
/**
|
||||
* The date (with ISO 8601 or YYYY-MM-DD) when the most recent version (1.9.4) was released.
|
||||
*/
|
||||
public static final String MINECRAFT_LAST_RELEASE_DATE = "2016-05-10";
|
||||
|
||||
/**
|
||||
* Plugins that are currently incompatible with ProtocolLib.
|
||||
*/
|
||||
public static final List<String> INCOMPATIBLE = Arrays.asList("TagAPI");
|
||||
|
||||
private static Plugin plugin;
|
||||
private static ProtocolConfig config;
|
||||
private static ProtocolManager manager;
|
||||
private static ErrorReporter reporter = new BasicErrorReporter();
|
||||
|
||||
private static ListeningScheduledExecutorService executorAsync;
|
||||
private static ListeningScheduledExecutorService executorSync;
|
||||
|
||||
private static boolean updatesDisabled;
|
||||
private static boolean initialized;
|
||||
|
||||
protected static void init(Plugin plugin, ProtocolConfig config, ProtocolManager manager, ErrorReporter reporter,
|
||||
ListeningScheduledExecutorService executorAsync, ListeningScheduledExecutorService executorSync) {
|
||||
Validate.isTrue(!initialized, "ProtocolLib has already been initialized.");
|
||||
ProtocolLibrary.plugin = plugin;
|
||||
ProtocolLibrary.config = config;
|
||||
ProtocolLibrary.manager = manager;
|
||||
ProtocolLibrary.reporter = reporter;
|
||||
ProtocolLibrary.executorAsync = executorAsync;
|
||||
ProtocolLibrary.executorSync = executorSync;
|
||||
ProtocolLogger.init(plugin);
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the ProtocolLib plugin instance.
|
||||
* @return The plugin instance
|
||||
*/
|
||||
public static Plugin getPlugin() {
|
||||
return plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets ProtocolLib's configuration
|
||||
* @return The config
|
||||
*/
|
||||
public static ProtocolConfig getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the packet protocol manager.
|
||||
* @return Packet protocol manager
|
||||
*/
|
||||
public static ProtocolManager getProtocolManager() {
|
||||
return manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the current error reporter.
|
||||
* @return Current error reporter.
|
||||
*/
|
||||
public static ErrorReporter getErrorReporter() {
|
||||
return reporter;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables the ProtocolLib update checker.
|
||||
*/
|
||||
public static void disableUpdates() {
|
||||
updatesDisabled = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not updates are currently disabled.
|
||||
* @return True if it is, false if not
|
||||
*/
|
||||
public static boolean updatesDisabled() {
|
||||
return updatesDisabled;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 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.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import com.comphenix.protocol.error.BasicErrorReporter;
|
||||
import com.comphenix.protocol.error.ErrorReporter;
|
||||
import com.google.common.util.concurrent.ListeningScheduledExecutorService;
|
||||
|
||||
/**
|
||||
* The main entry point for ProtocolLib.
|
||||
* @author dmulloy2
|
||||
*/
|
||||
public class ProtocolLibrary {
|
||||
/**
|
||||
* The minimum version ProtocolLib has been tested with.
|
||||
*/
|
||||
public static final String MINIMUM_MINECRAFT_VERSION = "1.9";
|
||||
|
||||
/**
|
||||
* The maximum version ProtocolLib has been tested with.
|
||||
*/
|
||||
public static final String MAXIMUM_MINECRAFT_VERSION = "1.9.4";
|
||||
|
||||
/**
|
||||
* The date (with ISO 8601 or YYYY-MM-DD) when the most recent version (1.9.4) was released.
|
||||
*/
|
||||
public static final String MINECRAFT_LAST_RELEASE_DATE = "2016-05-10";
|
||||
|
||||
/**
|
||||
* Plugins that are currently incompatible with ProtocolLib.
|
||||
*/
|
||||
public static final List<String> INCOMPATIBLE = Arrays.asList("TagAPI");
|
||||
|
||||
private static Plugin plugin;
|
||||
private static ProtocolConfig config;
|
||||
private static ProtocolManager manager;
|
||||
private static ErrorReporter reporter = new BasicErrorReporter();
|
||||
|
||||
private static ListeningScheduledExecutorService executorAsync;
|
||||
private static ListeningScheduledExecutorService executorSync;
|
||||
|
||||
private static boolean updatesDisabled;
|
||||
private static boolean initialized;
|
||||
|
||||
protected static void init(Plugin plugin, ProtocolConfig config, ProtocolManager manager, ErrorReporter reporter,
|
||||
ListeningScheduledExecutorService executorAsync, ListeningScheduledExecutorService executorSync) {
|
||||
Validate.isTrue(!initialized, "ProtocolLib has already been initialized.");
|
||||
ProtocolLibrary.plugin = plugin;
|
||||
ProtocolLibrary.config = config;
|
||||
ProtocolLibrary.manager = manager;
|
||||
ProtocolLibrary.reporter = reporter;
|
||||
ProtocolLibrary.executorAsync = executorAsync;
|
||||
ProtocolLibrary.executorSync = executorSync;
|
||||
ProtocolLogger.init(plugin);
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the ProtocolLib plugin instance.
|
||||
* @return The plugin instance
|
||||
*/
|
||||
public static Plugin getPlugin() {
|
||||
return plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets ProtocolLib's configuration
|
||||
* @return The config
|
||||
*/
|
||||
public static ProtocolConfig getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the packet protocol manager.
|
||||
* @return Packet protocol manager
|
||||
*/
|
||||
public static ProtocolManager getProtocolManager() {
|
||||
return manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the current error reporter.
|
||||
* @return Current error reporter.
|
||||
*/
|
||||
public static ErrorReporter getErrorReporter() {
|
||||
return reporter;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables the ProtocolLib update checker.
|
||||
*/
|
||||
public static void disableUpdates() {
|
||||
updatesDisabled = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not updates are currently disabled.
|
||||
* @return True if it is, false if not
|
||||
*/
|
||||
public static boolean updatesDisabled() {
|
||||
return updatesDisabled;
|
||||
}
|
||||
}
|
||||
|
@ -1,81 +1,81 @@
|
||||
/**
|
||||
* 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();
|
||||
}
|
||||
|
||||
private static boolean isDebugEnabled() {
|
||||
try {
|
||||
return ProtocolLibrary.getConfig().isDebug();
|
||||
} catch (Throwable ex) {
|
||||
return true; // For testing
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
public static void debug(String message, Object... args) {
|
||||
if (isDebugEnabled()) {
|
||||
if (logger != null) {
|
||||
log("[Debug] " + message, args);
|
||||
} else {
|
||||
System.out.println("[Debug] " + MessageFormat.format(message, args));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 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();
|
||||
}
|
||||
|
||||
private static boolean isDebugEnabled() {
|
||||
try {
|
||||
return ProtocolLibrary.getConfig().isDebug();
|
||||
} catch (Throwable ex) {
|
||||
return true; // For testing
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
public static void debug(String message, Object... args) {
|
||||
if (isDebugEnabled()) {
|
||||
if (logger != null) {
|
||||
log("[Debug] " + message, args);
|
||||
} else {
|
||||
System.out.println("[Debug] " + MessageFormat.format(message, args));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -282,4 +282,4 @@ public interface ProtocolManager extends PacketStream {
|
||||
public AsynchronousManager getAsynchronousManager();
|
||||
|
||||
public void verifyWhitelist(PacketListener listener, ListeningWhitelist whitelist);
|
||||
}
|
||||
}
|
||||
|
@ -243,4 +243,4 @@ public class ExpireHashMap<K, V> {
|
||||
return valueView.toString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -87,4 +87,4 @@ public interface ErrorReporter {
|
||||
* @param reportBuilder - an error report builder that will be used to get the report.
|
||||
*/
|
||||
public abstract void reportDetailed(Object sender, ReportBuilder reportBuilder);
|
||||
}
|
||||
}
|
||||
|
@ -1261,4 +1261,4 @@ public class PacketContainer implements Serializable {
|
||||
public String toString() {
|
||||
return "PacketContainer[type=" + type + ", structureModifier=" + structureModifier + "]";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -453,4 +453,4 @@ public class PacketEvent extends EventObject implements Cancellable {
|
||||
public String toString() {
|
||||
return "PacketEvent[player=" + getPlayer() + ", packet=" + packet + "]";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,31 +1,31 @@
|
||||
package com.comphenix.protocol.injector;
|
||||
|
||||
/**
|
||||
* Sets the inject hook type. Different types allow for maximum compatibility.
|
||||
* @author Kristian
|
||||
*/
|
||||
public enum PlayerInjectHooks {
|
||||
/**
|
||||
* The injection hook that does nothing. Set when every other inject hook fails.
|
||||
*/
|
||||
NONE,
|
||||
|
||||
/**
|
||||
* Override the network handler object itself. Only works in 1.3.
|
||||
* <p>
|
||||
* Cannot intercept MapChunk packets.
|
||||
*/
|
||||
NETWORK_MANAGER_OBJECT,
|
||||
|
||||
/**
|
||||
* Override the packet queue lists in NetworkHandler.
|
||||
* <p>
|
||||
* Cannot intercept MapChunk packets.
|
||||
*/
|
||||
NETWORK_HANDLER_FIELDS,
|
||||
|
||||
/**
|
||||
* Override the server handler object. Versatile, but a tad slower.
|
||||
*/
|
||||
NETWORK_SERVER_OBJECT;
|
||||
}
|
||||
package com.comphenix.protocol.injector;
|
||||
|
||||
/**
|
||||
* Sets the inject hook type. Different types allow for maximum compatibility.
|
||||
* @author Kristian
|
||||
*/
|
||||
public enum PlayerInjectHooks {
|
||||
/**
|
||||
* The injection hook that does nothing. Set when every other inject hook fails.
|
||||
*/
|
||||
NONE,
|
||||
|
||||
/**
|
||||
* Override the network handler object itself. Only works in 1.3.
|
||||
* <p>
|
||||
* Cannot intercept MapChunk packets.
|
||||
*/
|
||||
NETWORK_MANAGER_OBJECT,
|
||||
|
||||
/**
|
||||
* Override the packet queue lists in NetworkHandler.
|
||||
* <p>
|
||||
* Cannot intercept MapChunk packets.
|
||||
*/
|
||||
NETWORK_HANDLER_FIELDS,
|
||||
|
||||
/**
|
||||
* Override the server handler object. Versatile, but a tad slower.
|
||||
*/
|
||||
NETWORK_SERVER_OBJECT;
|
||||
}
|
||||
|
@ -172,4 +172,4 @@ public class StructureCache {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -389,4 +389,4 @@ public class NettyByteBufAdapter extends AbstractByteBuf {
|
||||
public ByteBuf retain() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,111 +1,111 @@
|
||||
/**
|
||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||
* Copyright (C) 2015 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.injector.netty;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.ProtocolLogger;
|
||||
import com.comphenix.protocol.PacketType.Protocol;
|
||||
import com.comphenix.protocol.PacketType.Sender;
|
||||
import com.comphenix.protocol.injector.netty.ProtocolRegistry;
|
||||
import com.comphenix.protocol.injector.packet.MapContainer;
|
||||
import com.comphenix.protocol.reflect.StructureModifier;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
/**
|
||||
* @author dmulloy2
|
||||
*/
|
||||
|
||||
public class NettyProtocolRegistry extends ProtocolRegistry {
|
||||
|
||||
public NettyProtocolRegistry() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected synchronized void initialize() {
|
||||
ProtocolLogger.debug("NettyProtocolRegistry#initialize()"); // Debug for issue #202
|
||||
|
||||
Object[] protocols = enumProtocol.getEnumConstants();
|
||||
|
||||
// ID to Packet class maps
|
||||
Map<Object, Map<Integer, Class<?>>> serverMaps = Maps.newLinkedHashMap();
|
||||
Map<Object, Map<Integer, Class<?>>> clientMaps = Maps.newLinkedHashMap();
|
||||
|
||||
Register result = new Register();
|
||||
StructureModifier<Object> modifier = null;
|
||||
|
||||
// Iterate through the protocols
|
||||
for (Object protocol : protocols) {
|
||||
if (modifier == null)
|
||||
modifier = new StructureModifier<Object>(protocol.getClass().getSuperclass(), false);
|
||||
StructureModifier<Map<Object, Map<Integer, Class<?>>>> maps = modifier.withTarget(protocol).withType(Map.class);
|
||||
for (Entry<Object, Map<Integer, Class<?>>> entry : maps.read(0).entrySet()) {
|
||||
String direction = entry.getKey().toString();
|
||||
if (direction.contains("CLIENTBOUND")) { // Sent by Server
|
||||
serverMaps.put(protocol, entry.getValue());
|
||||
} else if (direction.contains("SERVERBOUND")) { // Sent by Client
|
||||
clientMaps.put(protocol, entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Maps we have to occasionally check have changed
|
||||
for (Map<Integer, Class<?>> map : serverMaps.values()) {
|
||||
result.containers.add(new MapContainer(map));
|
||||
}
|
||||
|
||||
for (Map<Integer, Class<?>> map : clientMaps.values()) {
|
||||
result.containers.add(new MapContainer(map));
|
||||
}
|
||||
|
||||
for (int i = 0; i < protocols.length; i++) {
|
||||
Object protocol = protocols[i];
|
||||
Enum<?> enumProtocol = (Enum<?>) protocol;
|
||||
Protocol equivalent = Protocol.fromVanilla(enumProtocol);
|
||||
|
||||
// Associate known types
|
||||
if (serverMaps.containsKey(protocol))
|
||||
associatePackets(result, serverMaps.get(protocol), equivalent, Sender.SERVER);
|
||||
if (clientMaps.containsKey(protocol))
|
||||
associatePackets(result, clientMaps.get(protocol), equivalent, Sender.CLIENT);
|
||||
}
|
||||
|
||||
// Exchange (thread safe, as we have only one writer)
|
||||
this.register = result;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void associatePackets(Register register, Map<Integer, Class<?>> lookup, Protocol protocol, Sender sender) {
|
||||
for (Entry<Integer, Class<?>> entry : lookup.entrySet()) {
|
||||
PacketType type = PacketType.fromCurrent(protocol, sender, entry.getKey(), entry.getValue());
|
||||
|
||||
try {
|
||||
register.typeToClass.put(type, entry.getValue());
|
||||
|
||||
if (sender == Sender.SERVER)
|
||||
register.serverPackets.add(type);
|
||||
if (sender == Sender.CLIENT)
|
||||
register.clientPackets.add(type);
|
||||
} catch (IllegalArgumentException ex) {
|
||||
// Sometimes this happens with fake packets, just ignore it
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||
* Copyright (C) 2015 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.injector.netty;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.ProtocolLogger;
|
||||
import com.comphenix.protocol.PacketType.Protocol;
|
||||
import com.comphenix.protocol.PacketType.Sender;
|
||||
import com.comphenix.protocol.injector.netty.ProtocolRegistry;
|
||||
import com.comphenix.protocol.injector.packet.MapContainer;
|
||||
import com.comphenix.protocol.reflect.StructureModifier;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
/**
|
||||
* @author dmulloy2
|
||||
*/
|
||||
|
||||
public class NettyProtocolRegistry extends ProtocolRegistry {
|
||||
|
||||
public NettyProtocolRegistry() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected synchronized void initialize() {
|
||||
ProtocolLogger.debug("NettyProtocolRegistry#initialize()"); // Debug for issue #202
|
||||
|
||||
Object[] protocols = enumProtocol.getEnumConstants();
|
||||
|
||||
// ID to Packet class maps
|
||||
Map<Object, Map<Integer, Class<?>>> serverMaps = Maps.newLinkedHashMap();
|
||||
Map<Object, Map<Integer, Class<?>>> clientMaps = Maps.newLinkedHashMap();
|
||||
|
||||
Register result = new Register();
|
||||
StructureModifier<Object> modifier = null;
|
||||
|
||||
// Iterate through the protocols
|
||||
for (Object protocol : protocols) {
|
||||
if (modifier == null)
|
||||
modifier = new StructureModifier<Object>(protocol.getClass().getSuperclass(), false);
|
||||
StructureModifier<Map<Object, Map<Integer, Class<?>>>> maps = modifier.withTarget(protocol).withType(Map.class);
|
||||
for (Entry<Object, Map<Integer, Class<?>>> entry : maps.read(0).entrySet()) {
|
||||
String direction = entry.getKey().toString();
|
||||
if (direction.contains("CLIENTBOUND")) { // Sent by Server
|
||||
serverMaps.put(protocol, entry.getValue());
|
||||
} else if (direction.contains("SERVERBOUND")) { // Sent by Client
|
||||
clientMaps.put(protocol, entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Maps we have to occasionally check have changed
|
||||
for (Map<Integer, Class<?>> map : serverMaps.values()) {
|
||||
result.containers.add(new MapContainer(map));
|
||||
}
|
||||
|
||||
for (Map<Integer, Class<?>> map : clientMaps.values()) {
|
||||
result.containers.add(new MapContainer(map));
|
||||
}
|
||||
|
||||
for (int i = 0; i < protocols.length; i++) {
|
||||
Object protocol = protocols[i];
|
||||
Enum<?> enumProtocol = (Enum<?>) protocol;
|
||||
Protocol equivalent = Protocol.fromVanilla(enumProtocol);
|
||||
|
||||
// Associate known types
|
||||
if (serverMaps.containsKey(protocol))
|
||||
associatePackets(result, serverMaps.get(protocol), equivalent, Sender.SERVER);
|
||||
if (clientMaps.containsKey(protocol))
|
||||
associatePackets(result, clientMaps.get(protocol), equivalent, Sender.CLIENT);
|
||||
}
|
||||
|
||||
// Exchange (thread safe, as we have only one writer)
|
||||
this.register = result;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void associatePackets(Register register, Map<Integer, Class<?>> lookup, Protocol protocol, Sender sender) {
|
||||
for (Entry<Integer, Class<?>> entry : lookup.entrySet()) {
|
||||
PacketType type = PacketType.fromCurrent(protocol, sender, entry.getKey(), entry.getValue());
|
||||
|
||||
try {
|
||||
register.typeToClass.put(type, entry.getValue());
|
||||
|
||||
if (sender == Sender.SERVER)
|
||||
register.serverPackets.add(type);
|
||||
if (sender == Sender.CLIENT)
|
||||
register.clientPackets.add(type);
|
||||
} catch (IllegalArgumentException ex) {
|
||||
// Sometimes this happens with fake packets, just ignore it
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -122,4 +122,4 @@ public abstract class ProtocolRegistry {
|
||||
count += map.size();
|
||||
return count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,55 +1,55 @@
|
||||
/**
|
||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||
* Copyright (C) 2015 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.injector.netty;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
/**
|
||||
* @author dmulloy2
|
||||
*/
|
||||
|
||||
public class WirePacket {
|
||||
private final int id;
|
||||
private final byte[] bytes;
|
||||
|
||||
public WirePacket(int id, byte[] bytes) {
|
||||
this.id = id;
|
||||
this.bytes = bytes;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public byte[] getBytes() {
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public void writeId(ByteBuf output) {
|
||||
int i = id;
|
||||
while ((i & -128) != 0) {
|
||||
output.writeByte(i & 127 | 128);
|
||||
i >>>= 7;
|
||||
}
|
||||
|
||||
output.writeByte(i);
|
||||
}
|
||||
|
||||
public void writeBytes(ByteBuf output) {
|
||||
output.writeBytes(bytes);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||
* Copyright (C) 2015 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.injector.netty;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
/**
|
||||
* @author dmulloy2
|
||||
*/
|
||||
|
||||
public class WirePacket {
|
||||
private final int id;
|
||||
private final byte[] bytes;
|
||||
|
||||
public WirePacket(int id, byte[] bytes) {
|
||||
this.id = id;
|
||||
this.bytes = bytes;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public byte[] getBytes() {
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public void writeId(ByteBuf output) {
|
||||
int i = id;
|
||||
while ((i & -128) != 0) {
|
||||
output.writeByte(i & 127 | 128);
|
||||
i >>>= 7;
|
||||
}
|
||||
|
||||
output.writeByte(i);
|
||||
}
|
||||
|
||||
public void writeBytes(ByteBuf output) {
|
||||
output.writeBytes(bytes);
|
||||
}
|
||||
}
|
||||
|
@ -64,4 +64,4 @@ public class MapContainer {
|
||||
throw new RuntimeException("Unable to retrieve modCount.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,322 +1,322 @@
|
||||
/*
|
||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||
* Copyright (C) 2012 Kristian S. Stangeland
|
||||
*
|
||||
* 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.injector.packet;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.PacketType.Sender;
|
||||
import com.comphenix.protocol.error.ReportType;
|
||||
import com.comphenix.protocol.injector.netty.NettyProtocolRegistry;
|
||||
import com.comphenix.protocol.injector.netty.ProtocolRegistry;
|
||||
import com.comphenix.protocol.reflect.FieldAccessException;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
/**
|
||||
* Static packet registry in Minecraft.
|
||||
* @author Kristian
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
public class PacketRegistry {
|
||||
public static final ReportType REPORT_CANNOT_CORRECT_TROVE_MAP = new ReportType("Unable to correct no entry value.");
|
||||
|
||||
public static final ReportType REPORT_INSUFFICIENT_SERVER_PACKETS = new ReportType("Too few server packets detected: %s");
|
||||
public static final ReportType REPORT_INSUFFICIENT_CLIENT_PACKETS = new ReportType("Too few client packets detected: %s");
|
||||
|
||||
// The Netty packet registry
|
||||
private static volatile ProtocolRegistry NETTY;
|
||||
|
||||
// Cached for Netty
|
||||
private static volatile Set<Integer> LEGACY_SERVER_PACKETS;
|
||||
private static volatile Set<Integer> LEGACY_CLIENT_PACKETS;
|
||||
private static volatile Map<Integer, Class> LEGACY_PREVIOUS_PACKETS;
|
||||
|
||||
// Whether or not the registry has been initialized
|
||||
private static volatile boolean INITIALIZED = false;
|
||||
|
||||
/**
|
||||
* Initializes the packet registry.
|
||||
*/
|
||||
private static void initialize() {
|
||||
if (INITIALIZED) {
|
||||
if (NETTY == null) {
|
||||
throw new IllegalStateException("Failed to initialize packet registry.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
NETTY = new NettyProtocolRegistry();
|
||||
INITIALIZED = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given packet type is supported on the current server.
|
||||
* @param type - the type to check.
|
||||
* @return TRUE if it is, FALSE otherwise.
|
||||
*/
|
||||
public static boolean isSupported(PacketType type) {
|
||||
initialize();
|
||||
return NETTY.getPacketTypeLookup().containsKey(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a map of every packet class to every ID.
|
||||
* <p>
|
||||
* Deprecated: Use {@link #getPacketToType()} instead.
|
||||
* @return A map of packet classes and their corresponding ID.
|
||||
*/
|
||||
@Deprecated
|
||||
public static Map<Class, Integer> getPacketToID() {
|
||||
initialize();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<Class, Integer> result = (Map) Maps.transformValues(
|
||||
NETTY.getPacketClassLookup(),
|
||||
new Function<PacketType, Integer>() {
|
||||
@Override
|
||||
public Integer apply(PacketType type) {
|
||||
return type.getLegacyId();
|
||||
};
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a map of every packet class to the respective packet type.
|
||||
* @return A map of packet classes and their corresponding packet type.
|
||||
*/
|
||||
public static Map<Class, PacketType> getPacketToType() {
|
||||
initialize();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<Class, PacketType> result = (Map) NETTY.getPacketClassLookup();
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the injected proxy classes handlig each packet ID.
|
||||
* <p>
|
||||
* This is not supported in 1.7.2 and later.
|
||||
* @return Injected classes.
|
||||
*/
|
||||
@Deprecated
|
||||
public static Map<Integer, Class> getOverwrittenPackets() {
|
||||
initialize();
|
||||
throw new IllegalStateException("Not supported on Netty.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the vanilla classes handling each packet ID.
|
||||
* @return Vanilla classes.
|
||||
*/
|
||||
@Deprecated
|
||||
public static Map<Integer, Class> getPreviousPackets() {
|
||||
initialize();
|
||||
|
||||
// Construct it first
|
||||
if (LEGACY_PREVIOUS_PACKETS == null) {
|
||||
Map<Integer, Class> map = Maps.newHashMap();
|
||||
|
||||
for (Entry<PacketType, Class<?>> entry : NETTY.getPacketTypeLookup().entrySet()) {
|
||||
map.put(entry.getKey().getLegacyId(), entry.getValue());
|
||||
}
|
||||
LEGACY_PREVIOUS_PACKETS = Collections.unmodifiableMap(map);
|
||||
}
|
||||
return LEGACY_PREVIOUS_PACKETS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve every known and supported server packet.
|
||||
* <p>
|
||||
* Deprecated: Use {@link #getServerPacketTypes()} instead.
|
||||
* @return An immutable set of every known server packet.
|
||||
* @throws FieldAccessException If we're unable to retrieve the server packet data from Minecraft.
|
||||
*/
|
||||
@Deprecated
|
||||
public static Set<Integer> getServerPackets() throws FieldAccessException {
|
||||
initialize();
|
||||
|
||||
if (LEGACY_SERVER_PACKETS == null) {
|
||||
LEGACY_SERVER_PACKETS = toLegacy(NETTY.getServerPackets());
|
||||
}
|
||||
return LEGACY_SERVER_PACKETS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve every known and supported server packet type.
|
||||
* @return Every server packet type.
|
||||
*/
|
||||
public static Set<PacketType> getServerPacketTypes() {
|
||||
initialize();
|
||||
|
||||
NETTY.synchronize();
|
||||
return NETTY.getServerPackets();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve every known and supported client packet.
|
||||
* <p>
|
||||
* Deprecated: Use {@link #getClientPacketTypes()} instead.
|
||||
* @return An immutable set of every known client packet.
|
||||
* @throws FieldAccessException If we're unable to retrieve the client packet data from Minecraft.
|
||||
*/
|
||||
@Deprecated
|
||||
public static Set<Integer> getClientPackets() throws FieldAccessException {
|
||||
initialize();
|
||||
|
||||
if (LEGACY_CLIENT_PACKETS == null) {
|
||||
LEGACY_CLIENT_PACKETS = toLegacy(NETTY.getClientPackets());
|
||||
}
|
||||
return LEGACY_CLIENT_PACKETS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve every known and supported server packet type.
|
||||
* @return Every server packet type.
|
||||
*/
|
||||
public static Set<PacketType> getClientPacketTypes() {
|
||||
initialize();
|
||||
|
||||
NETTY.synchronize();
|
||||
return NETTY.getClientPackets();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a set of packet types to a set of integers based on the legacy packet ID.
|
||||
* @param types - packet type.
|
||||
* @return Set of integers.
|
||||
*/
|
||||
public static Set<Integer> toLegacy(Set<PacketType> types) {
|
||||
Set<Integer> result = Sets.newHashSet();
|
||||
|
||||
for (PacketType type : types)
|
||||
result.add(type.getLegacyId());
|
||||
return Collections.unmodifiableSet(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a set of legacy packet IDs to packet types.
|
||||
* @param ids - legacy packet IDs.
|
||||
* @return Set of packet types.
|
||||
*/
|
||||
public static Set<PacketType> toPacketTypes(Set<Integer> ids) {
|
||||
return toPacketTypes(ids, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a set of legacy packet IDs to packet types.
|
||||
* @param ids - legacy packet IDs.
|
||||
* @param preference - the sender preference, if any.
|
||||
* @return Set of packet types.
|
||||
*/
|
||||
public static Set<PacketType> toPacketTypes(Set<Integer> ids, Sender preference) {
|
||||
Set<PacketType> result = Sets.newHashSet();
|
||||
|
||||
for (int id : ids)
|
||||
result.add(PacketType.fromLegacy(id, preference));
|
||||
return Collections.unmodifiableSet(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the correct packet class from a given packet ID.
|
||||
* <p>
|
||||
* Deprecated: Use {@link #getPacketClassFromType(PacketType)} instead.
|
||||
* @param packetID - the packet ID.
|
||||
* @return The associated class.
|
||||
*/
|
||||
@Deprecated
|
||||
public static Class getPacketClassFromID(int packetID) {
|
||||
initialize();
|
||||
return NETTY.getPacketTypeLookup().get(PacketType.findLegacy(packetID));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the correct packet class from a given type.
|
||||
* @param type - the packet type.
|
||||
* @return The associated class.
|
||||
*/
|
||||
public static Class getPacketClassFromType(PacketType type) {
|
||||
return getPacketClassFromType(type, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the correct packet class from a given type.
|
||||
* <p>
|
||||
* Note that forceVanillla will be ignored on MC 1.7.2 and later.
|
||||
* @param type - the packet type.
|
||||
* @param forceVanilla - whether or not to look for vanilla classes, not injected classes.
|
||||
* @return The associated class.
|
||||
*/
|
||||
public static Class getPacketClassFromType(PacketType type, boolean forceVanilla) {
|
||||
initialize();
|
||||
return NETTY.getPacketTypeLookup().get(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the correct packet class from a given packet ID.
|
||||
* <p>
|
||||
* This method has been deprecated.
|
||||
* @param packetID - the packet ID.
|
||||
* @param forceVanilla - whether or not to look for vanilla classes, not injected classes.
|
||||
* @return The associated class.
|
||||
*/
|
||||
@Deprecated
|
||||
public static Class getPacketClassFromID(int packetID, boolean forceVanilla) {
|
||||
initialize();
|
||||
return getPacketClassFromID(packetID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the packet ID of a given packet.
|
||||
* <p>
|
||||
* Deprecated: Use {@link #getPacketType(Class)}.
|
||||
* @param packet - the type of packet to check.
|
||||
* @return The legacy ID of the given packet.
|
||||
* @throws IllegalArgumentException If this is not a valid packet.
|
||||
*/
|
||||
@Deprecated
|
||||
public static int getPacketID(Class<?> packet) {
|
||||
initialize();
|
||||
return NETTY.getPacketClassLookup().get(packet).getLegacyId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the packet type of a given packet.
|
||||
* @param packet - the class of the packet.
|
||||
* @return The packet type, or NULL if not found.
|
||||
*/
|
||||
public static PacketType getPacketType(Class<?> packet) {
|
||||
return getPacketType(packet, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the packet type of a given packet.
|
||||
* @param packet - the class of the packet.
|
||||
* @param sender - the sender of the packet, or NULL.
|
||||
* @return The packet type, or NULL if not found.
|
||||
*/
|
||||
public static PacketType getPacketType(Class<?> packet, Sender sender) {
|
||||
initialize();
|
||||
return NETTY.getPacketClassLookup().get(packet);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||
* Copyright (C) 2012 Kristian S. Stangeland
|
||||
*
|
||||
* 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.injector.packet;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.PacketType.Sender;
|
||||
import com.comphenix.protocol.error.ReportType;
|
||||
import com.comphenix.protocol.injector.netty.NettyProtocolRegistry;
|
||||
import com.comphenix.protocol.injector.netty.ProtocolRegistry;
|
||||
import com.comphenix.protocol.reflect.FieldAccessException;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
/**
|
||||
* Static packet registry in Minecraft.
|
||||
* @author Kristian
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
public class PacketRegistry {
|
||||
public static final ReportType REPORT_CANNOT_CORRECT_TROVE_MAP = new ReportType("Unable to correct no entry value.");
|
||||
|
||||
public static final ReportType REPORT_INSUFFICIENT_SERVER_PACKETS = new ReportType("Too few server packets detected: %s");
|
||||
public static final ReportType REPORT_INSUFFICIENT_CLIENT_PACKETS = new ReportType("Too few client packets detected: %s");
|
||||
|
||||
// The Netty packet registry
|
||||
private static volatile ProtocolRegistry NETTY;
|
||||
|
||||
// Cached for Netty
|
||||
private static volatile Set<Integer> LEGACY_SERVER_PACKETS;
|
||||
private static volatile Set<Integer> LEGACY_CLIENT_PACKETS;
|
||||
private static volatile Map<Integer, Class> LEGACY_PREVIOUS_PACKETS;
|
||||
|
||||
// Whether or not the registry has been initialized
|
||||
private static volatile boolean INITIALIZED = false;
|
||||
|
||||
/**
|
||||
* Initializes the packet registry.
|
||||
*/
|
||||
private static void initialize() {
|
||||
if (INITIALIZED) {
|
||||
if (NETTY == null) {
|
||||
throw new IllegalStateException("Failed to initialize packet registry.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
NETTY = new NettyProtocolRegistry();
|
||||
INITIALIZED = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given packet type is supported on the current server.
|
||||
* @param type - the type to check.
|
||||
* @return TRUE if it is, FALSE otherwise.
|
||||
*/
|
||||
public static boolean isSupported(PacketType type) {
|
||||
initialize();
|
||||
return NETTY.getPacketTypeLookup().containsKey(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a map of every packet class to every ID.
|
||||
* <p>
|
||||
* Deprecated: Use {@link #getPacketToType()} instead.
|
||||
* @return A map of packet classes and their corresponding ID.
|
||||
*/
|
||||
@Deprecated
|
||||
public static Map<Class, Integer> getPacketToID() {
|
||||
initialize();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<Class, Integer> result = (Map) Maps.transformValues(
|
||||
NETTY.getPacketClassLookup(),
|
||||
new Function<PacketType, Integer>() {
|
||||
@Override
|
||||
public Integer apply(PacketType type) {
|
||||
return type.getLegacyId();
|
||||
};
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a map of every packet class to the respective packet type.
|
||||
* @return A map of packet classes and their corresponding packet type.
|
||||
*/
|
||||
public static Map<Class, PacketType> getPacketToType() {
|
||||
initialize();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<Class, PacketType> result = (Map) NETTY.getPacketClassLookup();
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the injected proxy classes handlig each packet ID.
|
||||
* <p>
|
||||
* This is not supported in 1.7.2 and later.
|
||||
* @return Injected classes.
|
||||
*/
|
||||
@Deprecated
|
||||
public static Map<Integer, Class> getOverwrittenPackets() {
|
||||
initialize();
|
||||
throw new IllegalStateException("Not supported on Netty.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the vanilla classes handling each packet ID.
|
||||
* @return Vanilla classes.
|
||||
*/
|
||||
@Deprecated
|
||||
public static Map<Integer, Class> getPreviousPackets() {
|
||||
initialize();
|
||||
|
||||
// Construct it first
|
||||
if (LEGACY_PREVIOUS_PACKETS == null) {
|
||||
Map<Integer, Class> map = Maps.newHashMap();
|
||||
|
||||
for (Entry<PacketType, Class<?>> entry : NETTY.getPacketTypeLookup().entrySet()) {
|
||||
map.put(entry.getKey().getLegacyId(), entry.getValue());
|
||||
}
|
||||
LEGACY_PREVIOUS_PACKETS = Collections.unmodifiableMap(map);
|
||||
}
|
||||
return LEGACY_PREVIOUS_PACKETS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve every known and supported server packet.
|
||||
* <p>
|
||||
* Deprecated: Use {@link #getServerPacketTypes()} instead.
|
||||
* @return An immutable set of every known server packet.
|
||||
* @throws FieldAccessException If we're unable to retrieve the server packet data from Minecraft.
|
||||
*/
|
||||
@Deprecated
|
||||
public static Set<Integer> getServerPackets() throws FieldAccessException {
|
||||
initialize();
|
||||
|
||||
if (LEGACY_SERVER_PACKETS == null) {
|
||||
LEGACY_SERVER_PACKETS = toLegacy(NETTY.getServerPackets());
|
||||
}
|
||||
return LEGACY_SERVER_PACKETS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve every known and supported server packet type.
|
||||
* @return Every server packet type.
|
||||
*/
|
||||
public static Set<PacketType> getServerPacketTypes() {
|
||||
initialize();
|
||||
|
||||
NETTY.synchronize();
|
||||
return NETTY.getServerPackets();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve every known and supported client packet.
|
||||
* <p>
|
||||
* Deprecated: Use {@link #getClientPacketTypes()} instead.
|
||||
* @return An immutable set of every known client packet.
|
||||
* @throws FieldAccessException If we're unable to retrieve the client packet data from Minecraft.
|
||||
*/
|
||||
@Deprecated
|
||||
public static Set<Integer> getClientPackets() throws FieldAccessException {
|
||||
initialize();
|
||||
|
||||
if (LEGACY_CLIENT_PACKETS == null) {
|
||||
LEGACY_CLIENT_PACKETS = toLegacy(NETTY.getClientPackets());
|
||||
}
|
||||
return LEGACY_CLIENT_PACKETS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve every known and supported server packet type.
|
||||
* @return Every server packet type.
|
||||
*/
|
||||
public static Set<PacketType> getClientPacketTypes() {
|
||||
initialize();
|
||||
|
||||
NETTY.synchronize();
|
||||
return NETTY.getClientPackets();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a set of packet types to a set of integers based on the legacy packet ID.
|
||||
* @param types - packet type.
|
||||
* @return Set of integers.
|
||||
*/
|
||||
public static Set<Integer> toLegacy(Set<PacketType> types) {
|
||||
Set<Integer> result = Sets.newHashSet();
|
||||
|
||||
for (PacketType type : types)
|
||||
result.add(type.getLegacyId());
|
||||
return Collections.unmodifiableSet(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a set of legacy packet IDs to packet types.
|
||||
* @param ids - legacy packet IDs.
|
||||
* @return Set of packet types.
|
||||
*/
|
||||
public static Set<PacketType> toPacketTypes(Set<Integer> ids) {
|
||||
return toPacketTypes(ids, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a set of legacy packet IDs to packet types.
|
||||
* @param ids - legacy packet IDs.
|
||||
* @param preference - the sender preference, if any.
|
||||
* @return Set of packet types.
|
||||
*/
|
||||
public static Set<PacketType> toPacketTypes(Set<Integer> ids, Sender preference) {
|
||||
Set<PacketType> result = Sets.newHashSet();
|
||||
|
||||
for (int id : ids)
|
||||
result.add(PacketType.fromLegacy(id, preference));
|
||||
return Collections.unmodifiableSet(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the correct packet class from a given packet ID.
|
||||
* <p>
|
||||
* Deprecated: Use {@link #getPacketClassFromType(PacketType)} instead.
|
||||
* @param packetID - the packet ID.
|
||||
* @return The associated class.
|
||||
*/
|
||||
@Deprecated
|
||||
public static Class getPacketClassFromID(int packetID) {
|
||||
initialize();
|
||||
return NETTY.getPacketTypeLookup().get(PacketType.findLegacy(packetID));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the correct packet class from a given type.
|
||||
* @param type - the packet type.
|
||||
* @return The associated class.
|
||||
*/
|
||||
public static Class getPacketClassFromType(PacketType type) {
|
||||
return getPacketClassFromType(type, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the correct packet class from a given type.
|
||||
* <p>
|
||||
* Note that forceVanillla will be ignored on MC 1.7.2 and later.
|
||||
* @param type - the packet type.
|
||||
* @param forceVanilla - whether or not to look for vanilla classes, not injected classes.
|
||||
* @return The associated class.
|
||||
*/
|
||||
public static Class getPacketClassFromType(PacketType type, boolean forceVanilla) {
|
||||
initialize();
|
||||
return NETTY.getPacketTypeLookup().get(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the correct packet class from a given packet ID.
|
||||
* <p>
|
||||
* This method has been deprecated.
|
||||
* @param packetID - the packet ID.
|
||||
* @param forceVanilla - whether or not to look for vanilla classes, not injected classes.
|
||||
* @return The associated class.
|
||||
*/
|
||||
@Deprecated
|
||||
public static Class getPacketClassFromID(int packetID, boolean forceVanilla) {
|
||||
initialize();
|
||||
return getPacketClassFromID(packetID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the packet ID of a given packet.
|
||||
* <p>
|
||||
* Deprecated: Use {@link #getPacketType(Class)}.
|
||||
* @param packet - the type of packet to check.
|
||||
* @return The legacy ID of the given packet.
|
||||
* @throws IllegalArgumentException If this is not a valid packet.
|
||||
*/
|
||||
@Deprecated
|
||||
public static int getPacketID(Class<?> packet) {
|
||||
initialize();
|
||||
return NETTY.getPacketClassLookup().get(packet).getLegacyId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the packet type of a given packet.
|
||||
* @param packet - the class of the packet.
|
||||
* @return The packet type, or NULL if not found.
|
||||
*/
|
||||
public static PacketType getPacketType(Class<?> packet) {
|
||||
return getPacketType(packet, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the packet type of a given packet.
|
||||
* @param packet - the class of the packet.
|
||||
* @param sender - the sender of the packet, or NULL.
|
||||
* @return The packet type, or NULL if not found.
|
||||
*/
|
||||
public static PacketType getPacketType(Class<?> packet, Sender sender) {
|
||||
initialize();
|
||||
return NETTY.getPacketClassLookup().get(packet);
|
||||
}
|
||||
}
|
||||
|
@ -11,4 +11,4 @@
|
||||
* }
|
||||
* </pre>
|
||||
*/
|
||||
package com.comphenix.protocol;
|
||||
package com.comphenix.protocol;
|
||||
|
@ -682,4 +682,4 @@ public class StructureModifier<TField> {
|
||||
public String toString() {
|
||||
return "StructureModifier[fieldType=" + fieldType + ", data=" + data + "]";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -51,4 +51,4 @@ final class DefaultConstrutorAccessor implements ConstructorAccessor {
|
||||
public String toString() {
|
||||
return "DefaultConstrutorAccessor [constructor=" + constructor + "]";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -57,4 +57,4 @@ final class DefaultFieldAccessor implements FieldAccessor {
|
||||
public String toString() {
|
||||
return "DefaultFieldAccessor [field=" + field + "]";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -49,4 +49,4 @@ final class DefaultMethodAccessor implements MethodAccessor {
|
||||
public String toString() {
|
||||
return "DefaultMethodAccessor [method=" + method + "]";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,4 +27,4 @@ public interface FieldAccessor {
|
||||
* @return The field.
|
||||
*/
|
||||
public Field getField();
|
||||
}
|
||||
}
|
||||
|
@ -20,4 +20,4 @@ public interface MethodAccessor {
|
||||
* @return The method.
|
||||
*/
|
||||
public Method getMethod();
|
||||
}
|
||||
}
|
||||
|
@ -117,4 +117,4 @@ public class BukkitCloner implements Cloner {
|
||||
throw new IllegalArgumentException("Cannot clone objects of type " + source.getClass());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,39 +1,39 @@
|
||||
/**
|
||||
* (c) 2016 dmulloy2
|
||||
*/
|
||||
package com.comphenix.protocol.reflect.cloning;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
|
||||
/**
|
||||
* A cloner that can clone Optional objects
|
||||
* @author dmulloy2
|
||||
*/
|
||||
|
||||
public class OptionalCloner implements Cloner {
|
||||
protected Cloner wrapped;
|
||||
|
||||
public OptionalCloner(Cloner wrapped) {
|
||||
this.wrapped = wrapped;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canClone(Object source) {
|
||||
return source instanceof Optional;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object clone(Object source) {
|
||||
Optional<?> optional = (Optional<?>) source;
|
||||
if (!optional.isPresent()) {
|
||||
return Optional.absent();
|
||||
}
|
||||
|
||||
// Clone the inner value
|
||||
return Optional.of(wrapped.clone(optional.get()));
|
||||
}
|
||||
|
||||
public Cloner getWrapped() {
|
||||
return wrapped;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* (c) 2016 dmulloy2
|
||||
*/
|
||||
package com.comphenix.protocol.reflect.cloning;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
|
||||
/**
|
||||
* A cloner that can clone Optional objects
|
||||
* @author dmulloy2
|
||||
*/
|
||||
|
||||
public class OptionalCloner implements Cloner {
|
||||
protected Cloner wrapped;
|
||||
|
||||
public OptionalCloner(Cloner wrapped) {
|
||||
this.wrapped = wrapped;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canClone(Object source) {
|
||||
return source instanceof Optional;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object clone(Object source) {
|
||||
Optional<?> optional = (Optional<?>) source;
|
||||
if (!optional.isPresent()) {
|
||||
return Optional.absent();
|
||||
}
|
||||
|
||||
// Clone the inner value
|
||||
return Optional.of(wrapped.clone(optional.get()));
|
||||
}
|
||||
|
||||
public Cloner getWrapped() {
|
||||
return wrapped;
|
||||
}
|
||||
}
|
||||
|
@ -55,4 +55,4 @@ class ClassRegexMatcher extends AbstractFuzzyMatcher<Class<?>> {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -54,4 +54,4 @@ class ClassSetMatcher extends AbstractFuzzyMatcher<Class<?>> {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -65,4 +65,4 @@ public class CollectionGenerator implements InstanceProvider {
|
||||
// Cannot provide an instance
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -32,4 +32,4 @@ public interface InstanceProvider {
|
||||
* @throws NotConstructableException Thrown to indicate that this type cannot or should never be constructed.
|
||||
*/
|
||||
public abstract Object create(@Nullable Class<?> type);
|
||||
}
|
||||
}
|
||||
|
@ -77,4 +77,4 @@ public class PrimitiveGenerator implements InstanceProvider {
|
||||
// Cannot handle this type
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -122,4 +122,4 @@ public class HistogramStream extends OnlineComputation {
|
||||
public int getCount() {
|
||||
return count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -46,4 +46,4 @@ public abstract class OnlineComputation {
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -152,4 +152,4 @@ public class StatisticsStream extends OnlineComputation {
|
||||
getMean(), getStandardDeviation(),
|
||||
getMinimum(), getMaximum(), getCount());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,57 +1,57 @@
|
||||
/**
|
||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||
* Copyright (C) 2015 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.utility;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author dmulloy2
|
||||
*/
|
||||
|
||||
// TODO Switch to AutoCloseable w/ Java 7
|
||||
public class Closer implements Closeable {
|
||||
private final List<Closeable> list;
|
||||
|
||||
private Closer() {
|
||||
this.list = new ArrayList<Closeable>();
|
||||
}
|
||||
|
||||
public static Closer create() {
|
||||
return new Closer();
|
||||
}
|
||||
|
||||
public <C extends Closeable> C register(C close) {
|
||||
list.add(close);
|
||||
return close;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
for (Closeable close : list) {
|
||||
closeQuietly(close);
|
||||
}
|
||||
}
|
||||
|
||||
public static void closeQuietly(Closeable close) {
|
||||
try {
|
||||
close.close();
|
||||
} catch (Throwable ex) { }
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||
* Copyright (C) 2015 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.utility;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author dmulloy2
|
||||
*/
|
||||
|
||||
// TODO Switch to AutoCloseable w/ Java 7
|
||||
public class Closer implements Closeable {
|
||||
private final List<Closeable> list;
|
||||
|
||||
private Closer() {
|
||||
this.list = new ArrayList<Closeable>();
|
||||
}
|
||||
|
||||
public static Closer create() {
|
||||
return new Closer();
|
||||
}
|
||||
|
||||
public <C extends Closeable> C register(C close) {
|
||||
list.add(close);
|
||||
return close;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
for (Closeable close : list) {
|
||||
closeQuietly(close);
|
||||
}
|
||||
}
|
||||
|
||||
public static void closeQuietly(Closeable close) {
|
||||
try {
|
||||
close.close();
|
||||
} catch (Throwable ex) { }
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,27 +1,27 @@
|
||||
/**
|
||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||
* Copyright (C) 2015 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.utility;
|
||||
|
||||
/**
|
||||
* @author dmulloy2
|
||||
*/
|
||||
|
||||
public final class Constants {
|
||||
public static final String PACKAGE_VERSION = "v1_9_R2";
|
||||
public static final String NMS = "net.minecraft.server." + PACKAGE_VERSION;
|
||||
public static final String OBC = "org.bukkit.craftbukkit." + PACKAGE_VERSION;
|
||||
}
|
||||
/**
|
||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||
* Copyright (C) 2015 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.utility;
|
||||
|
||||
/**
|
||||
* @author dmulloy2
|
||||
*/
|
||||
|
||||
public final class Constants {
|
||||
public static final String PACKAGE_VERSION = "v1_9_R2";
|
||||
public static final String NMS = "net.minecraft.server." + PACKAGE_VERSION;
|
||||
public static final String OBC = "org.bukkit.craftbukkit." + PACKAGE_VERSION;
|
||||
}
|
||||
|
@ -2103,4 +2103,4 @@ public class MinecraftReflection {
|
||||
throw new RuntimeException("Cannot construct packet serializer.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -468,4 +468,4 @@ public class StreamSerializer {
|
||||
else
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,63 +1,63 @@
|
||||
/**
|
||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||
* Copyright (C) 2015 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.utility;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
/**
|
||||
* General utility class
|
||||
* @author dmulloy2
|
||||
*/
|
||||
public class Util {
|
||||
|
||||
/**
|
||||
* Gets a list of currently online Players.
|
||||
* @return The list
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static List<Player> getOnlinePlayers() {
|
||||
return (List<Player>) Bukkit.getOnlinePlayers();
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a variable argument array into a List.
|
||||
* @param elements Array to convert
|
||||
* @return The list
|
||||
*/
|
||||
@SafeVarargs
|
||||
public static <E> List<E> asList(E... elements) {
|
||||
List<E> list = new ArrayList<E>(elements.length);
|
||||
for (E element : elements) {
|
||||
list.add(element);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not this server is running Spigot. This works by checking
|
||||
* the server version for the String "Spigot"
|
||||
* @return True if it is, false if not.
|
||||
*/
|
||||
public static boolean isUsingSpigot() {
|
||||
return Bukkit.getServer().getVersion().contains("Spigot");
|
||||
}
|
||||
}
|
||||
/**
|
||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||
* Copyright (C) 2015 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.utility;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
/**
|
||||
* General utility class
|
||||
* @author dmulloy2
|
||||
*/
|
||||
public class Util {
|
||||
|
||||
/**
|
||||
* Gets a list of currently online Players.
|
||||
* @return The list
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static List<Player> getOnlinePlayers() {
|
||||
return (List<Player>) Bukkit.getOnlinePlayers();
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a variable argument array into a List.
|
||||
* @param elements Array to convert
|
||||
* @return The list
|
||||
*/
|
||||
@SafeVarargs
|
||||
public static <E> List<E> asList(E... elements) {
|
||||
List<E> list = new ArrayList<E>(elements.length);
|
||||
for (E element : elements) {
|
||||
list.add(element);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not this server is running Spigot. This works by checking
|
||||
* the server version for the String "Spigot"
|
||||
* @return True if it is, false if not.
|
||||
*/
|
||||
public static boolean isUsingSpigot() {
|
||||
return Bukkit.getServer().getVersion().contains("Spigot");
|
||||
}
|
||||
}
|
||||
|
@ -1,244 +1,244 @@
|
||||
/**
|
||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||
* Copyright (C) 2015 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.wrappers;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import com.comphenix.protocol.reflect.EquivalentConverter;
|
||||
import com.comphenix.protocol.reflect.FieldAccessException;
|
||||
import com.comphenix.protocol.reflect.StructureModifier;
|
||||
import com.comphenix.protocol.utility.MinecraftReflection;
|
||||
import com.google.common.base.Objects;
|
||||
|
||||
/**
|
||||
* Copies a immutable net.minecraft.server.BlockPosition, which represents a integer 3D vector.
|
||||
*
|
||||
* @author dmulloy2
|
||||
*/
|
||||
public class BlockPosition {
|
||||
|
||||
/**
|
||||
* Represents the null (0, 0, 0) origin.
|
||||
*/
|
||||
public static BlockPosition ORIGIN = new BlockPosition(0, 0, 0);
|
||||
|
||||
private static Constructor<?> blockPositionConstructor;
|
||||
|
||||
// Use protected members, like Bukkit
|
||||
protected final int x;
|
||||
protected final int y;
|
||||
protected final int z;
|
||||
|
||||
// Used to access a BlockPosition, in case it's names are changed
|
||||
private static StructureModifier<Integer> intModifier;
|
||||
|
||||
/**
|
||||
* Construct an immutable 3D vector.
|
||||
* @param x - x coordinate
|
||||
* @param y - y coordinate
|
||||
* @param z - z coordinate
|
||||
*/
|
||||
public BlockPosition(int x, int y, int z) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct an immutable integer 3D vector from a mutable Bukkit vector.
|
||||
* @param vector - the mutable real Bukkit vector to copy.
|
||||
*/
|
||||
public BlockPosition(Vector vector) {
|
||||
if (vector == null)
|
||||
throw new IllegalArgumentException("Vector cannot be NULL.");
|
||||
this.x = vector.getBlockX();
|
||||
this.y = vector.getBlockY();
|
||||
this.z = vector.getBlockZ();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert this instance to an equivalent real 3D vector.
|
||||
* @return Real 3D vector.
|
||||
*/
|
||||
public Vector toVector() {
|
||||
return new Vector(x, y, z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert this instance to an equivalent Location.
|
||||
* @param world World for the location
|
||||
* @return Location
|
||||
*/
|
||||
public Location toLocation(World world) {
|
||||
return new Location(world, x, y, z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the x-coordinate.
|
||||
* @return X coordinate.
|
||||
*/
|
||||
public int getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the y-coordinate.
|
||||
* @return Y coordinate.
|
||||
*/
|
||||
public int getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the z-coordinate.
|
||||
* @return Z coordinate.
|
||||
*/
|
||||
public int getZ() {
|
||||
return z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the current position and a given position together, producing a result position.
|
||||
* @param other - the other position.
|
||||
* @return The new result position.
|
||||
*/
|
||||
public BlockPosition add(BlockPosition other) {
|
||||
if (other == null)
|
||||
throw new IllegalArgumentException("other cannot be NULL");
|
||||
return new BlockPosition(x + other.x, y + other.y, z + other.z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the current position and a given position together, producing a result position.
|
||||
* @param other - the other position.
|
||||
* @return The new result position.
|
||||
*/
|
||||
public BlockPosition subtract(BlockPosition other) {
|
||||
if (other == null)
|
||||
throw new IllegalArgumentException("other cannot be NULL");
|
||||
return new BlockPosition(x - other.x, y - other.y, z - other.z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiply each dimension in the current position by the given factor.
|
||||
* @param factor - multiplier.
|
||||
* @return The new result.
|
||||
*/
|
||||
public BlockPosition multiply(int factor) {
|
||||
return new BlockPosition(x * factor, y * factor, z * factor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Divide each dimension in the current position by the given divisor.
|
||||
* @param divisor - the divisor.
|
||||
* @return The new result.
|
||||
*/
|
||||
public BlockPosition divide(int divisor) {
|
||||
if (divisor == 0)
|
||||
throw new IllegalArgumentException("Cannot divide by null.");
|
||||
return new BlockPosition(x / divisor, y / divisor, z / divisor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to convert between NMS ChunkPosition and the wrapper instance.
|
||||
* @return A new converter.
|
||||
*/
|
||||
public static EquivalentConverter<BlockPosition> getConverter() {
|
||||
return new EquivalentConverter<BlockPosition>() {
|
||||
@Override
|
||||
public Object getGeneric(Class<?> genericType, BlockPosition specific) {
|
||||
if (blockPositionConstructor == null) {
|
||||
try {
|
||||
blockPositionConstructor = MinecraftReflection.getBlockPositionClass().
|
||||
getConstructor(int.class, int.class, int.class);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Cannot find block position constructor.", e);
|
||||
}
|
||||
}
|
||||
|
||||
// Construct the underlying BlockPosition
|
||||
try {
|
||||
Object result = blockPositionConstructor.newInstance(specific.x, specific.y, specific.z);
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Cannot construct BlockPosition.", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPosition getSpecific(Object generic) {
|
||||
if (MinecraftReflection.isBlockPosition(generic)) {
|
||||
// Use a structure modifier
|
||||
intModifier = new StructureModifier<Object>(generic.getClass(), null, false).withType(int.class);
|
||||
|
||||
// Damn it all
|
||||
if (intModifier.size() < 3) {
|
||||
throw new IllegalStateException("Cannot read class " + generic.getClass() + " for its integer fields.");
|
||||
}
|
||||
|
||||
if (intModifier.size() >= 3) {
|
||||
try {
|
||||
StructureModifier<Integer> instance = intModifier.withTarget(generic);
|
||||
BlockPosition result = new BlockPosition(instance.read(0), instance.read(1), instance.read(2));
|
||||
return result;
|
||||
} catch (FieldAccessException e) {
|
||||
// This is an exeptional work-around, so we don't want to burden the caller with the messy details
|
||||
throw new RuntimeException("Field access error.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise, return NULL
|
||||
return null;
|
||||
}
|
||||
|
||||
// Thanks Java Generics!
|
||||
@Override
|
||||
public Class<BlockPosition> getSpecificType() {
|
||||
return BlockPosition.class;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
// Fast checks
|
||||
if (this == obj) return true;
|
||||
if (obj == null) return false;
|
||||
|
||||
// Only compare objects of similar type
|
||||
if (obj instanceof BlockPosition) {
|
||||
BlockPosition other = (BlockPosition) obj;
|
||||
return x == other.x && y == other.y && z == other.z;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "BlockPosition [x=" + x + ", y=" + y + ", z=" + z + "]";
|
||||
}
|
||||
}
|
||||
/**
|
||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||
* Copyright (C) 2015 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.wrappers;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import com.comphenix.protocol.reflect.EquivalentConverter;
|
||||
import com.comphenix.protocol.reflect.FieldAccessException;
|
||||
import com.comphenix.protocol.reflect.StructureModifier;
|
||||
import com.comphenix.protocol.utility.MinecraftReflection;
|
||||
import com.google.common.base.Objects;
|
||||
|
||||
/**
|
||||
* Copies a immutable net.minecraft.server.BlockPosition, which represents a integer 3D vector.
|
||||
*
|
||||
* @author dmulloy2
|
||||
*/
|
||||
public class BlockPosition {
|
||||
|
||||
/**
|
||||
* Represents the null (0, 0, 0) origin.
|
||||
*/
|
||||
public static BlockPosition ORIGIN = new BlockPosition(0, 0, 0);
|
||||
|
||||
private static Constructor<?> blockPositionConstructor;
|
||||
|
||||
// Use protected members, like Bukkit
|
||||
protected final int x;
|
||||
protected final int y;
|
||||
protected final int z;
|
||||
|
||||
// Used to access a BlockPosition, in case it's names are changed
|
||||
private static StructureModifier<Integer> intModifier;
|
||||
|
||||
/**
|
||||
* Construct an immutable 3D vector.
|
||||
* @param x - x coordinate
|
||||
* @param y - y coordinate
|
||||
* @param z - z coordinate
|
||||
*/
|
||||
public BlockPosition(int x, int y, int z) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct an immutable integer 3D vector from a mutable Bukkit vector.
|
||||
* @param vector - the mutable real Bukkit vector to copy.
|
||||
*/
|
||||
public BlockPosition(Vector vector) {
|
||||
if (vector == null)
|
||||
throw new IllegalArgumentException("Vector cannot be NULL.");
|
||||
this.x = vector.getBlockX();
|
||||
this.y = vector.getBlockY();
|
||||
this.z = vector.getBlockZ();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert this instance to an equivalent real 3D vector.
|
||||
* @return Real 3D vector.
|
||||
*/
|
||||
public Vector toVector() {
|
||||
return new Vector(x, y, z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert this instance to an equivalent Location.
|
||||
* @param world World for the location
|
||||
* @return Location
|
||||
*/
|
||||
public Location toLocation(World world) {
|
||||
return new Location(world, x, y, z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the x-coordinate.
|
||||
* @return X coordinate.
|
||||
*/
|
||||
public int getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the y-coordinate.
|
||||
* @return Y coordinate.
|
||||
*/
|
||||
public int getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the z-coordinate.
|
||||
* @return Z coordinate.
|
||||
*/
|
||||
public int getZ() {
|
||||
return z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the current position and a given position together, producing a result position.
|
||||
* @param other - the other position.
|
||||
* @return The new result position.
|
||||
*/
|
||||
public BlockPosition add(BlockPosition other) {
|
||||
if (other == null)
|
||||
throw new IllegalArgumentException("other cannot be NULL");
|
||||
return new BlockPosition(x + other.x, y + other.y, z + other.z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the current position and a given position together, producing a result position.
|
||||
* @param other - the other position.
|
||||
* @return The new result position.
|
||||
*/
|
||||
public BlockPosition subtract(BlockPosition other) {
|
||||
if (other == null)
|
||||
throw new IllegalArgumentException("other cannot be NULL");
|
||||
return new BlockPosition(x - other.x, y - other.y, z - other.z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiply each dimension in the current position by the given factor.
|
||||
* @param factor - multiplier.
|
||||
* @return The new result.
|
||||
*/
|
||||
public BlockPosition multiply(int factor) {
|
||||
return new BlockPosition(x * factor, y * factor, z * factor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Divide each dimension in the current position by the given divisor.
|
||||
* @param divisor - the divisor.
|
||||
* @return The new result.
|
||||
*/
|
||||
public BlockPosition divide(int divisor) {
|
||||
if (divisor == 0)
|
||||
throw new IllegalArgumentException("Cannot divide by null.");
|
||||
return new BlockPosition(x / divisor, y / divisor, z / divisor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to convert between NMS ChunkPosition and the wrapper instance.
|
||||
* @return A new converter.
|
||||
*/
|
||||
public static EquivalentConverter<BlockPosition> getConverter() {
|
||||
return new EquivalentConverter<BlockPosition>() {
|
||||
@Override
|
||||
public Object getGeneric(Class<?> genericType, BlockPosition specific) {
|
||||
if (blockPositionConstructor == null) {
|
||||
try {
|
||||
blockPositionConstructor = MinecraftReflection.getBlockPositionClass().
|
||||
getConstructor(int.class, int.class, int.class);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Cannot find block position constructor.", e);
|
||||
}
|
||||
}
|
||||
|
||||
// Construct the underlying BlockPosition
|
||||
try {
|
||||
Object result = blockPositionConstructor.newInstance(specific.x, specific.y, specific.z);
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Cannot construct BlockPosition.", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPosition getSpecific(Object generic) {
|
||||
if (MinecraftReflection.isBlockPosition(generic)) {
|
||||
// Use a structure modifier
|
||||
intModifier = new StructureModifier<Object>(generic.getClass(), null, false).withType(int.class);
|
||||
|
||||
// Damn it all
|
||||
if (intModifier.size() < 3) {
|
||||
throw new IllegalStateException("Cannot read class " + generic.getClass() + " for its integer fields.");
|
||||
}
|
||||
|
||||
if (intModifier.size() >= 3) {
|
||||
try {
|
||||
StructureModifier<Integer> instance = intModifier.withTarget(generic);
|
||||
BlockPosition result = new BlockPosition(instance.read(0), instance.read(1), instance.read(2));
|
||||
return result;
|
||||
} catch (FieldAccessException e) {
|
||||
// This is an exeptional work-around, so we don't want to burden the caller with the messy details
|
||||
throw new RuntimeException("Field access error.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise, return NULL
|
||||
return null;
|
||||
}
|
||||
|
||||
// Thanks Java Generics!
|
||||
@Override
|
||||
public Class<BlockPosition> getSpecificType() {
|
||||
return BlockPosition.class;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
// Fast checks
|
||||
if (this == obj) return true;
|
||||
if (obj == null) return false;
|
||||
|
||||
// Only compare objects of similar type
|
||||
if (obj instanceof BlockPosition) {
|
||||
BlockPosition other = (BlockPosition) obj;
|
||||
return x == other.x && y == other.y && z == other.z;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "BlockPosition [x=" + x + ", y=" + y + ", z=" + z + "]";
|
||||
}
|
||||
}
|
||||
|
@ -1,51 +1,51 @@
|
||||
/**
|
||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||
* Copyright (C) 2015 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.wrappers;
|
||||
|
||||
import net.md_5.bungee.api.chat.BaseComponent;
|
||||
import net.md_5.bungee.chat.ComponentSerializer;
|
||||
|
||||
/**
|
||||
* Utility class for converting between the BungeeCord Chat API and ProtocolLib's wrapper
|
||||
* <p>
|
||||
* Note: The BungeeCord Chat API is not included in CraftBukkit.
|
||||
* @author dmulloy2
|
||||
*/
|
||||
|
||||
public final class ComponentConverter {
|
||||
|
||||
private ComponentConverter() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a {@link WrappedChatComponent} into an array of {@link BaseComponent}s
|
||||
* @param wrapper ProtocolLib wrapper
|
||||
* @return BaseComponent array
|
||||
*/
|
||||
public static BaseComponent[] fromWrapper(WrappedChatComponent wrapper) {
|
||||
return ComponentSerializer.parse(wrapper.getJson());
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an array of {@link BaseComponent}s into a ProtocolLib wrapper
|
||||
* @param components BaseComponent array
|
||||
* @return ProtocolLib wrapper
|
||||
*/
|
||||
public static WrappedChatComponent fromBaseComponent(BaseComponent... components) {
|
||||
return WrappedChatComponent.fromJson(ComponentSerializer.toString(components));
|
||||
}
|
||||
}
|
||||
/**
|
||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||
* Copyright (C) 2015 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.wrappers;
|
||||
|
||||
import net.md_5.bungee.api.chat.BaseComponent;
|
||||
import net.md_5.bungee.chat.ComponentSerializer;
|
||||
|
||||
/**
|
||||
* Utility class for converting between the BungeeCord Chat API and ProtocolLib's wrapper
|
||||
* <p>
|
||||
* Note: The BungeeCord Chat API is not included in CraftBukkit.
|
||||
* @author dmulloy2
|
||||
*/
|
||||
|
||||
public final class ComponentConverter {
|
||||
|
||||
private ComponentConverter() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a {@link WrappedChatComponent} into an array of {@link BaseComponent}s
|
||||
* @param wrapper ProtocolLib wrapper
|
||||
* @return BaseComponent array
|
||||
*/
|
||||
public static BaseComponent[] fromWrapper(WrappedChatComponent wrapper) {
|
||||
return ComponentSerializer.parse(wrapper.getJson());
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an array of {@link BaseComponent}s into a ProtocolLib wrapper
|
||||
* @param components BaseComponent array
|
||||
* @return ProtocolLib wrapper
|
||||
*/
|
||||
public static WrappedChatComponent fromBaseComponent(BaseComponent... components) {
|
||||
return WrappedChatComponent.fromJson(ComponentSerializer.toString(components));
|
||||
}
|
||||
}
|
||||
|
@ -1,142 +1,142 @@
|
||||
/**
|
||||
* 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.wrappers;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
|
||||
import com.comphenix.protocol.reflect.EquivalentConverter;
|
||||
import com.comphenix.protocol.reflect.StructureModifier;
|
||||
import com.comphenix.protocol.utility.MinecraftReflection;
|
||||
|
||||
/**
|
||||
* Represents a MinecraftKey in 1.9.
|
||||
* <p>
|
||||
* Keys are in the format {@code prefix:key}
|
||||
*
|
||||
* @author dmulloy2
|
||||
*/
|
||||
|
||||
public class MinecraftKey {
|
||||
private final String prefix;
|
||||
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) {
|
||||
this.prefix = prefix;
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new key with minecraft prefix and a key.
|
||||
* @param key The key
|
||||
*/
|
||||
public MinecraftKey(String 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) {
|
||||
StructureModifier<String> modifier = new StructureModifier<String>(handle.getClass()).withTarget(handle).withType(String.class);
|
||||
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) {
|
||||
return new MinecraftKey(value.name().toLowerCase().replace("_", "."));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the prefix of this MinecraftKey. It is minecraft by default.
|
||||
* @return The prefix
|
||||
*/
|
||||
public String getPrefix() {
|
||||
return prefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the key of this MinecraftKey. It is generally the important part.
|
||||
* @return The key
|
||||
*/
|
||||
public String getKey() {
|
||||
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() {
|
||||
return prefix + ":" + key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this key back into Enum format, upper case with periods replaced
|
||||
* by underscores.
|
||||
* @return The enum format
|
||||
*/
|
||||
public String getEnumFormat() {
|
||||
return key.toUpperCase().replace(".", "_");
|
||||
}
|
||||
|
||||
private static Constructor<?> constructor = null;
|
||||
|
||||
public static EquivalentConverter<MinecraftKey> getConverter() {
|
||||
return new EquivalentConverter<MinecraftKey>() {
|
||||
@Override
|
||||
public MinecraftKey getSpecific(Object generic) {
|
||||
return MinecraftKey.fromHandle(generic);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getGeneric(Class<?> genericType, MinecraftKey specific) {
|
||||
if (constructor == null) {
|
||||
try {
|
||||
constructor = MinecraftReflection.getMinecraftKeyClass().getConstructor(String.class, String.class);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new RuntimeException("Failed to obtain MinecraftKey constructor", e);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
return constructor.newInstance(specific.getPrefix(), specific.getKey());
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new RuntimeException("Failed to create new MinecraftKey", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<MinecraftKey> getSpecificType() {
|
||||
return MinecraftKey.class;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 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.wrappers;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
|
||||
import com.comphenix.protocol.reflect.EquivalentConverter;
|
||||
import com.comphenix.protocol.reflect.StructureModifier;
|
||||
import com.comphenix.protocol.utility.MinecraftReflection;
|
||||
|
||||
/**
|
||||
* Represents a MinecraftKey in 1.9.
|
||||
* <p>
|
||||
* Keys are in the format {@code prefix:key}
|
||||
*
|
||||
* @author dmulloy2
|
||||
*/
|
||||
|
||||
public class MinecraftKey {
|
||||
private final String prefix;
|
||||
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) {
|
||||
this.prefix = prefix;
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new key with minecraft prefix and a key.
|
||||
* @param key The key
|
||||
*/
|
||||
public MinecraftKey(String 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) {
|
||||
StructureModifier<String> modifier = new StructureModifier<String>(handle.getClass()).withTarget(handle).withType(String.class);
|
||||
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) {
|
||||
return new MinecraftKey(value.name().toLowerCase().replace("_", "."));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the prefix of this MinecraftKey. It is minecraft by default.
|
||||
* @return The prefix
|
||||
*/
|
||||
public String getPrefix() {
|
||||
return prefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the key of this MinecraftKey. It is generally the important part.
|
||||
* @return The key
|
||||
*/
|
||||
public String getKey() {
|
||||
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() {
|
||||
return prefix + ":" + key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this key back into Enum format, upper case with periods replaced
|
||||
* by underscores.
|
||||
* @return The enum format
|
||||
*/
|
||||
public String getEnumFormat() {
|
||||
return key.toUpperCase().replace(".", "_");
|
||||
}
|
||||
|
||||
private static Constructor<?> constructor = null;
|
||||
|
||||
public static EquivalentConverter<MinecraftKey> getConverter() {
|
||||
return new EquivalentConverter<MinecraftKey>() {
|
||||
@Override
|
||||
public MinecraftKey getSpecific(Object generic) {
|
||||
return MinecraftKey.fromHandle(generic);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getGeneric(Class<?> genericType, MinecraftKey specific) {
|
||||
if (constructor == null) {
|
||||
try {
|
||||
constructor = MinecraftReflection.getMinecraftKeyClass().getConstructor(String.class, String.class);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new RuntimeException("Failed to obtain MinecraftKey constructor", e);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
return constructor.newInstance(specific.getPrefix(), specific.getKey());
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new RuntimeException("Failed to create new MinecraftKey", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<MinecraftKey> getSpecificType() {
|
||||
return MinecraftKey.class;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -1,268 +1,268 @@
|
||||
/**
|
||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||
* Copyright (C) 2015 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.wrappers;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Constructor;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.reflect.EquivalentConverter;
|
||||
import com.comphenix.protocol.reflect.StructureModifier;
|
||||
import com.comphenix.protocol.utility.MinecraftReflection;
|
||||
|
||||
/**
|
||||
* Represents a single block change.
|
||||
*
|
||||
* @author dmulloy2
|
||||
*/
|
||||
|
||||
public class MultiBlockChangeInfo {
|
||||
private static Constructor<?> constructor;
|
||||
private static Class<?> nmsClass = MinecraftReflection.getMultiBlockChangeInfoClass();
|
||||
|
||||
private short location;
|
||||
private WrappedBlockData data;
|
||||
private ChunkCoordIntPair chunk;
|
||||
|
||||
public MultiBlockChangeInfo(short location, WrappedBlockData data, ChunkCoordIntPair chunk) {
|
||||
this.location = location;
|
||||
this.data = data;
|
||||
this.chunk = chunk;
|
||||
}
|
||||
|
||||
public MultiBlockChangeInfo(Location location, WrappedBlockData data) {
|
||||
this.data = data;
|
||||
this.chunk = new ChunkCoordIntPair(location.getBlockX() >> 4, location.getBlockZ() >> 4);
|
||||
this.setLocation(location);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this block change's absolute Location in a given World.
|
||||
*
|
||||
* @param world World for the location
|
||||
* @return This block change's absolute Location
|
||||
*/
|
||||
public Location getLocation(World world) {
|
||||
return new Location(world, getAbsoluteX(), getY(), getAbsoluteZ());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this block change's absolute Location.
|
||||
*
|
||||
* @param location This block change's new location
|
||||
*/
|
||||
public void setLocation(Location location) {
|
||||
setLocation(location.getBlockX(), location.getBlockY(), location.getBlockZ());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this block change's absolute coordinates.
|
||||
*
|
||||
* @param x X coordinate
|
||||
* @param y Y coordinate
|
||||
* @param z Z coordinate
|
||||
*/
|
||||
public void setLocation(int x, int y, int z) {
|
||||
x = x & 15;
|
||||
z = z & 15;
|
||||
|
||||
this.location = (short) (x << 12 | z << 8 | y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this block change's relative x coordinate.
|
||||
*
|
||||
* @return Relative X coordinate
|
||||
*/
|
||||
public int getX() {
|
||||
return location >> 12 & 15;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this block change's absolute x coordinate.
|
||||
*
|
||||
* @return Absolute X coordinate
|
||||
*/
|
||||
public int getAbsoluteX() {
|
||||
return (chunk.getChunkX() << 4) + getX();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this block change's absolute x coordinate.
|
||||
*
|
||||
* @param x New x coordinate
|
||||
*/
|
||||
public void setX(int x) {
|
||||
setLocation(x, getY(), getZ());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this block change's y coordinate.
|
||||
*
|
||||
* @return Y coordinate
|
||||
*/
|
||||
public int getY() {
|
||||
return location & 255;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this block change's y coordinate
|
||||
*
|
||||
* @param y New y coordinate
|
||||
*/
|
||||
public void setY(int y) {
|
||||
setLocation(getX(), y, getZ());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this block change's relative z coordinate.
|
||||
*
|
||||
* @return Relative Z coordinate
|
||||
*/
|
||||
public int getZ() {
|
||||
return location >> 8 & 15;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this block change's absolute z coordinate.
|
||||
*
|
||||
* @return Absolute Z coordinate
|
||||
*/
|
||||
public int getAbsoluteZ() {
|
||||
return (chunk.getChunkZ() << 4) + getZ();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this block change's relative z coordinate.
|
||||
*
|
||||
* @param z New z coordinate
|
||||
*/
|
||||
public void setZ(int z) {
|
||||
setLocation(getX(), getY(), z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this block change's block data.
|
||||
*
|
||||
* @return The block data
|
||||
*/
|
||||
public WrappedBlockData getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this block change's block data.
|
||||
*
|
||||
* @param data New block data
|
||||
*/
|
||||
public void setData(WrappedBlockData data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the chunk this block change occured in.
|
||||
*
|
||||
* @return The chunk
|
||||
*/
|
||||
public ChunkCoordIntPair getChunk() {
|
||||
return chunk;
|
||||
}
|
||||
|
||||
public static EquivalentConverter<MultiBlockChangeInfo> getConverter(final ChunkCoordIntPair chunk) {
|
||||
return new EquivalentConverter<MultiBlockChangeInfo>() {
|
||||
|
||||
@Override
|
||||
public MultiBlockChangeInfo getSpecific(Object generic) {
|
||||
StructureModifier<Object> modifier = new StructureModifier<Object>(generic.getClass(), null, false).withTarget(generic);
|
||||
|
||||
StructureModifier<Short> shorts = modifier.withType(short.class);
|
||||
short location = shorts.read(0);
|
||||
|
||||
StructureModifier<WrappedBlockData> dataModifier = modifier.withType(MinecraftReflection.getIBlockDataClass(),
|
||||
BukkitConverters.getWrappedBlockDataConverter());
|
||||
WrappedBlockData data = dataModifier.read(0);
|
||||
|
||||
return new MultiBlockChangeInfo(location, data, chunk);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getGeneric(Class<?> genericType, MultiBlockChangeInfo specific) {
|
||||
try {
|
||||
if (constructor == null) {
|
||||
constructor = nmsClass.getConstructor(
|
||||
PacketType.Play.Server.MULTI_BLOCK_CHANGE.getPacketClass(),
|
||||
short.class,
|
||||
MinecraftReflection.getIBlockDataClass()
|
||||
);
|
||||
}
|
||||
|
||||
return constructor.newInstance(
|
||||
null,
|
||||
specific.location,
|
||||
BukkitConverters.getWrappedBlockDataConverter().getGeneric(MinecraftReflection.getIBlockDataClass(), specific.data)
|
||||
);
|
||||
} catch (Throwable ex) {
|
||||
throw new RuntimeException("Failed to construct MultiBlockChangeInfo instance.", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<MultiBlockChangeInfo> getSpecificType() {
|
||||
return MultiBlockChangeInfo.class;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static EquivalentConverter<MultiBlockChangeInfo[]> getArrayConverter(final ChunkCoordIntPair chunk) {
|
||||
return new EquivalentConverter<MultiBlockChangeInfo[]>() {
|
||||
private final EquivalentConverter<MultiBlockChangeInfo> converter = MultiBlockChangeInfo.getConverter(chunk);
|
||||
|
||||
@Override
|
||||
public MultiBlockChangeInfo[] getSpecific(Object generic) {
|
||||
Object[] array = (Object[]) generic;
|
||||
MultiBlockChangeInfo[] result = new MultiBlockChangeInfo[array.length];
|
||||
|
||||
// Unwrap every item
|
||||
for (int i = 0; i < result.length; i++) {
|
||||
result[i] = converter.getSpecific(array[i]);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getGeneric(Class<?> genericType, MultiBlockChangeInfo[] specific) {
|
||||
Object[] result = (Object[]) Array.newInstance(nmsClass, specific.length);
|
||||
|
||||
// Wrap every item
|
||||
for (int i = 0; i < result.length; i++) {
|
||||
result[i] = converter.getGeneric(nmsClass, specific[i]);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<MultiBlockChangeInfo[]> getSpecificType() {
|
||||
return MultiBlockChangeInfo[].class;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
/**
|
||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||
* Copyright (C) 2015 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.wrappers;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Constructor;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.reflect.EquivalentConverter;
|
||||
import com.comphenix.protocol.reflect.StructureModifier;
|
||||
import com.comphenix.protocol.utility.MinecraftReflection;
|
||||
|
||||
/**
|
||||
* Represents a single block change.
|
||||
*
|
||||
* @author dmulloy2
|
||||
*/
|
||||
|
||||
public class MultiBlockChangeInfo {
|
||||
private static Constructor<?> constructor;
|
||||
private static Class<?> nmsClass = MinecraftReflection.getMultiBlockChangeInfoClass();
|
||||
|
||||
private short location;
|
||||
private WrappedBlockData data;
|
||||
private ChunkCoordIntPair chunk;
|
||||
|
||||
public MultiBlockChangeInfo(short location, WrappedBlockData data, ChunkCoordIntPair chunk) {
|
||||
this.location = location;
|
||||
this.data = data;
|
||||
this.chunk = chunk;
|
||||
}
|
||||
|
||||
public MultiBlockChangeInfo(Location location, WrappedBlockData data) {
|
||||
this.data = data;
|
||||
this.chunk = new ChunkCoordIntPair(location.getBlockX() >> 4, location.getBlockZ() >> 4);
|
||||
this.setLocation(location);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this block change's absolute Location in a given World.
|
||||
*
|
||||
* @param world World for the location
|
||||
* @return This block change's absolute Location
|
||||
*/
|
||||
public Location getLocation(World world) {
|
||||
return new Location(world, getAbsoluteX(), getY(), getAbsoluteZ());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this block change's absolute Location.
|
||||
*
|
||||
* @param location This block change's new location
|
||||
*/
|
||||
public void setLocation(Location location) {
|
||||
setLocation(location.getBlockX(), location.getBlockY(), location.getBlockZ());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this block change's absolute coordinates.
|
||||
*
|
||||
* @param x X coordinate
|
||||
* @param y Y coordinate
|
||||
* @param z Z coordinate
|
||||
*/
|
||||
public void setLocation(int x, int y, int z) {
|
||||
x = x & 15;
|
||||
z = z & 15;
|
||||
|
||||
this.location = (short) (x << 12 | z << 8 | y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this block change's relative x coordinate.
|
||||
*
|
||||
* @return Relative X coordinate
|
||||
*/
|
||||
public int getX() {
|
||||
return location >> 12 & 15;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this block change's absolute x coordinate.
|
||||
*
|
||||
* @return Absolute X coordinate
|
||||
*/
|
||||
public int getAbsoluteX() {
|
||||
return (chunk.getChunkX() << 4) + getX();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this block change's absolute x coordinate.
|
||||
*
|
||||
* @param x New x coordinate
|
||||
*/
|
||||
public void setX(int x) {
|
||||
setLocation(x, getY(), getZ());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this block change's y coordinate.
|
||||
*
|
||||
* @return Y coordinate
|
||||
*/
|
||||
public int getY() {
|
||||
return location & 255;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this block change's y coordinate
|
||||
*
|
||||
* @param y New y coordinate
|
||||
*/
|
||||
public void setY(int y) {
|
||||
setLocation(getX(), y, getZ());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this block change's relative z coordinate.
|
||||
*
|
||||
* @return Relative Z coordinate
|
||||
*/
|
||||
public int getZ() {
|
||||
return location >> 8 & 15;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this block change's absolute z coordinate.
|
||||
*
|
||||
* @return Absolute Z coordinate
|
||||
*/
|
||||
public int getAbsoluteZ() {
|
||||
return (chunk.getChunkZ() << 4) + getZ();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this block change's relative z coordinate.
|
||||
*
|
||||
* @param z New z coordinate
|
||||
*/
|
||||
public void setZ(int z) {
|
||||
setLocation(getX(), getY(), z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this block change's block data.
|
||||
*
|
||||
* @return The block data
|
||||
*/
|
||||
public WrappedBlockData getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this block change's block data.
|
||||
*
|
||||
* @param data New block data
|
||||
*/
|
||||
public void setData(WrappedBlockData data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the chunk this block change occured in.
|
||||
*
|
||||
* @return The chunk
|
||||
*/
|
||||
public ChunkCoordIntPair getChunk() {
|
||||
return chunk;
|
||||
}
|
||||
|
||||
public static EquivalentConverter<MultiBlockChangeInfo> getConverter(final ChunkCoordIntPair chunk) {
|
||||
return new EquivalentConverter<MultiBlockChangeInfo>() {
|
||||
|
||||
@Override
|
||||
public MultiBlockChangeInfo getSpecific(Object generic) {
|
||||
StructureModifier<Object> modifier = new StructureModifier<Object>(generic.getClass(), null, false).withTarget(generic);
|
||||
|
||||
StructureModifier<Short> shorts = modifier.withType(short.class);
|
||||
short location = shorts.read(0);
|
||||
|
||||
StructureModifier<WrappedBlockData> dataModifier = modifier.withType(MinecraftReflection.getIBlockDataClass(),
|
||||
BukkitConverters.getWrappedBlockDataConverter());
|
||||
WrappedBlockData data = dataModifier.read(0);
|
||||
|
||||
return new MultiBlockChangeInfo(location, data, chunk);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getGeneric(Class<?> genericType, MultiBlockChangeInfo specific) {
|
||||
try {
|
||||
if (constructor == null) {
|
||||
constructor = nmsClass.getConstructor(
|
||||
PacketType.Play.Server.MULTI_BLOCK_CHANGE.getPacketClass(),
|
||||
short.class,
|
||||
MinecraftReflection.getIBlockDataClass()
|
||||
);
|
||||
}
|
||||
|
||||
return constructor.newInstance(
|
||||
null,
|
||||
specific.location,
|
||||
BukkitConverters.getWrappedBlockDataConverter().getGeneric(MinecraftReflection.getIBlockDataClass(), specific.data)
|
||||
);
|
||||
} catch (Throwable ex) {
|
||||
throw new RuntimeException("Failed to construct MultiBlockChangeInfo instance.", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<MultiBlockChangeInfo> getSpecificType() {
|
||||
return MultiBlockChangeInfo.class;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static EquivalentConverter<MultiBlockChangeInfo[]> getArrayConverter(final ChunkCoordIntPair chunk) {
|
||||
return new EquivalentConverter<MultiBlockChangeInfo[]>() {
|
||||
private final EquivalentConverter<MultiBlockChangeInfo> converter = MultiBlockChangeInfo.getConverter(chunk);
|
||||
|
||||
@Override
|
||||
public MultiBlockChangeInfo[] getSpecific(Object generic) {
|
||||
Object[] array = (Object[]) generic;
|
||||
MultiBlockChangeInfo[] result = new MultiBlockChangeInfo[array.length];
|
||||
|
||||
// Unwrap every item
|
||||
for (int i = 0; i < result.length; i++) {
|
||||
result[i] = converter.getSpecific(array[i]);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getGeneric(Class<?> genericType, MultiBlockChangeInfo[] specific) {
|
||||
Object[] result = (Object[]) Array.newInstance(nmsClass, specific.length);
|
||||
|
||||
// Wrap every item
|
||||
for (int i = 0; i < result.length; i++) {
|
||||
result[i] = converter.getGeneric(nmsClass, specific[i]);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<MultiBlockChangeInfo[]> getSpecificType() {
|
||||
return MultiBlockChangeInfo[].class;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -1,189 +1,189 @@
|
||||
/**
|
||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||
* Copyright (C) 2015 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.wrappers;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
|
||||
import com.comphenix.protocol.reflect.EquivalentConverter;
|
||||
import com.comphenix.protocol.reflect.StructureModifier;
|
||||
import com.comphenix.protocol.utility.MinecraftReflection;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers.NativeGameMode;
|
||||
import com.google.common.base.Objects;
|
||||
|
||||
/**
|
||||
* Represents an immutable PlayerInfoData in the PLAYER_INFO packet.
|
||||
* @author dmulloy2
|
||||
*/
|
||||
public class PlayerInfoData {
|
||||
private static Constructor<?> constructor;
|
||||
|
||||
private final int latency;
|
||||
private final NativeGameMode gameMode;
|
||||
private final WrappedGameProfile profile;
|
||||
private final WrappedChatComponent displayName;
|
||||
|
||||
// This is the same order as the NMS class, minus the packet (which isn't a field)
|
||||
public PlayerInfoData(WrappedGameProfile profile, int latency, NativeGameMode gameMode, WrappedChatComponent displayName) {
|
||||
this.profile = profile;
|
||||
this.latency = latency;
|
||||
this.gameMode = gameMode;
|
||||
this.displayName = displayName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the GameProfile of the player represented by this data.
|
||||
* @return The GameProfile
|
||||
*/
|
||||
public WrappedGameProfile getProfile() {
|
||||
return profile;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Replaced by {@link #getLatency()}
|
||||
*/
|
||||
@Deprecated
|
||||
public int getPing() {
|
||||
return latency;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the latency between the client and the server.
|
||||
* @return The latency
|
||||
*/
|
||||
public int getLatency() {
|
||||
return latency;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the GameMode of the player represented by this data.
|
||||
* @return The GameMode
|
||||
*/
|
||||
public NativeGameMode getGameMode() {
|
||||
return gameMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the display name of the player represented by this data.
|
||||
* @return The display name
|
||||
*/
|
||||
public WrappedChatComponent getDisplayName() {
|
||||
return displayName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to convert between NMS PlayerInfoData and the wrapper instance.
|
||||
* @return A new converter.
|
||||
*/
|
||||
public static EquivalentConverter<PlayerInfoData> getConverter() {
|
||||
return new EquivalentConverter<PlayerInfoData>() {
|
||||
@Override
|
||||
public Object getGeneric(Class<?> genericType, PlayerInfoData specific) {
|
||||
if (constructor == null) {
|
||||
try {
|
||||
// public PlayerInfoData(Packet, GameProfile, int, GameMode, ChatComponent)
|
||||
constructor = MinecraftReflection.getPlayerInfoDataClass().getConstructor(
|
||||
MinecraftReflection.getMinecraftClass("PacketPlayOutPlayerInfo"),
|
||||
MinecraftReflection.getGameProfileClass(),
|
||||
int.class,
|
||||
EnumWrappers.getGameModeClass(),
|
||||
MinecraftReflection.getIChatBaseComponentClass()
|
||||
);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Cannot find PlayerInfoData constructor.", e);
|
||||
}
|
||||
}
|
||||
|
||||
// Attempt to construct the underlying PlayerInfoData
|
||||
|
||||
try {
|
||||
// public PlayerInfoData(null, GameProfile, ping, GameMode, ChatComponent)
|
||||
// The packet isn't a field, so it can be null
|
||||
Object result = constructor.newInstance(
|
||||
null,
|
||||
specific.profile.handle,
|
||||
specific.latency,
|
||||
EnumWrappers.getGameModeConverter().getGeneric(EnumWrappers.getGameModeClass(), specific.gameMode),
|
||||
specific.displayName != null ? specific.displayName.handle : null
|
||||
);
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to construct PlayerInfoData.", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlayerInfoData getSpecific(Object generic) {
|
||||
if (MinecraftReflection.isPlayerInfoData(generic)) {
|
||||
StructureModifier<Object> modifier = new StructureModifier<Object>(generic.getClass(), null, false)
|
||||
.withTarget(generic);
|
||||
|
||||
StructureModifier<WrappedGameProfile> gameProfiles = modifier.withType(
|
||||
MinecraftReflection.getGameProfileClass(), BukkitConverters.getWrappedGameProfileConverter());
|
||||
WrappedGameProfile gameProfile = gameProfiles.read(0);
|
||||
|
||||
StructureModifier<Integer> ints = modifier.withType(int.class);
|
||||
int latency = ints.read(0);
|
||||
|
||||
StructureModifier<NativeGameMode> gameModes = modifier.withType(
|
||||
EnumWrappers.getGameModeClass(), EnumWrappers.getGameModeConverter());
|
||||
NativeGameMode gameMode = gameModes.read(0);
|
||||
|
||||
StructureModifier<WrappedChatComponent> displayNames = modifier.withType(
|
||||
MinecraftReflection.getIChatBaseComponentClass(), BukkitConverters.getWrappedChatComponentConverter());
|
||||
WrappedChatComponent displayName = displayNames.read(0);
|
||||
|
||||
return new PlayerInfoData(gameProfile, latency, gameMode, displayName);
|
||||
}
|
||||
|
||||
// Otherwise, return null
|
||||
return null;
|
||||
}
|
||||
|
||||
// Thanks Java Generics!
|
||||
@Override
|
||||
public Class<PlayerInfoData> getSpecificType() {
|
||||
return PlayerInfoData.class;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
// Fast checks
|
||||
if (this == obj) return true;
|
||||
if (obj == null) return false;
|
||||
|
||||
// Only compare objects of similar type
|
||||
if (obj instanceof PlayerInfoData) {
|
||||
PlayerInfoData other = (PlayerInfoData) obj;
|
||||
return profile.equals(other.profile) && latency == other.latency && gameMode == other.gameMode
|
||||
&& displayName.equals(other.displayName);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(latency, gameMode, profile, displayName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("PlayerInfoData[latency=%s, gameMode=%s, profile=%s, displayName=%s",
|
||||
latency, gameMode, profile, displayName);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||
* Copyright (C) 2015 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.wrappers;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
|
||||
import com.comphenix.protocol.reflect.EquivalentConverter;
|
||||
import com.comphenix.protocol.reflect.StructureModifier;
|
||||
import com.comphenix.protocol.utility.MinecraftReflection;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers.NativeGameMode;
|
||||
import com.google.common.base.Objects;
|
||||
|
||||
/**
|
||||
* Represents an immutable PlayerInfoData in the PLAYER_INFO packet.
|
||||
* @author dmulloy2
|
||||
*/
|
||||
public class PlayerInfoData {
|
||||
private static Constructor<?> constructor;
|
||||
|
||||
private final int latency;
|
||||
private final NativeGameMode gameMode;
|
||||
private final WrappedGameProfile profile;
|
||||
private final WrappedChatComponent displayName;
|
||||
|
||||
// This is the same order as the NMS class, minus the packet (which isn't a field)
|
||||
public PlayerInfoData(WrappedGameProfile profile, int latency, NativeGameMode gameMode, WrappedChatComponent displayName) {
|
||||
this.profile = profile;
|
||||
this.latency = latency;
|
||||
this.gameMode = gameMode;
|
||||
this.displayName = displayName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the GameProfile of the player represented by this data.
|
||||
* @return The GameProfile
|
||||
*/
|
||||
public WrappedGameProfile getProfile() {
|
||||
return profile;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Replaced by {@link #getLatency()}
|
||||
*/
|
||||
@Deprecated
|
||||
public int getPing() {
|
||||
return latency;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the latency between the client and the server.
|
||||
* @return The latency
|
||||
*/
|
||||
public int getLatency() {
|
||||
return latency;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the GameMode of the player represented by this data.
|
||||
* @return The GameMode
|
||||
*/
|
||||
public NativeGameMode getGameMode() {
|
||||
return gameMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the display name of the player represented by this data.
|
||||
* @return The display name
|
||||
*/
|
||||
public WrappedChatComponent getDisplayName() {
|
||||
return displayName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to convert between NMS PlayerInfoData and the wrapper instance.
|
||||
* @return A new converter.
|
||||
*/
|
||||
public static EquivalentConverter<PlayerInfoData> getConverter() {
|
||||
return new EquivalentConverter<PlayerInfoData>() {
|
||||
@Override
|
||||
public Object getGeneric(Class<?> genericType, PlayerInfoData specific) {
|
||||
if (constructor == null) {
|
||||
try {
|
||||
// public PlayerInfoData(Packet, GameProfile, int, GameMode, ChatComponent)
|
||||
constructor = MinecraftReflection.getPlayerInfoDataClass().getConstructor(
|
||||
MinecraftReflection.getMinecraftClass("PacketPlayOutPlayerInfo"),
|
||||
MinecraftReflection.getGameProfileClass(),
|
||||
int.class,
|
||||
EnumWrappers.getGameModeClass(),
|
||||
MinecraftReflection.getIChatBaseComponentClass()
|
||||
);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Cannot find PlayerInfoData constructor.", e);
|
||||
}
|
||||
}
|
||||
|
||||
// Attempt to construct the underlying PlayerInfoData
|
||||
|
||||
try {
|
||||
// public PlayerInfoData(null, GameProfile, ping, GameMode, ChatComponent)
|
||||
// The packet isn't a field, so it can be null
|
||||
Object result = constructor.newInstance(
|
||||
null,
|
||||
specific.profile.handle,
|
||||
specific.latency,
|
||||
EnumWrappers.getGameModeConverter().getGeneric(EnumWrappers.getGameModeClass(), specific.gameMode),
|
||||
specific.displayName != null ? specific.displayName.handle : null
|
||||
);
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to construct PlayerInfoData.", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlayerInfoData getSpecific(Object generic) {
|
||||
if (MinecraftReflection.isPlayerInfoData(generic)) {
|
||||
StructureModifier<Object> modifier = new StructureModifier<Object>(generic.getClass(), null, false)
|
||||
.withTarget(generic);
|
||||
|
||||
StructureModifier<WrappedGameProfile> gameProfiles = modifier.withType(
|
||||
MinecraftReflection.getGameProfileClass(), BukkitConverters.getWrappedGameProfileConverter());
|
||||
WrappedGameProfile gameProfile = gameProfiles.read(0);
|
||||
|
||||
StructureModifier<Integer> ints = modifier.withType(int.class);
|
||||
int latency = ints.read(0);
|
||||
|
||||
StructureModifier<NativeGameMode> gameModes = modifier.withType(
|
||||
EnumWrappers.getGameModeClass(), EnumWrappers.getGameModeConverter());
|
||||
NativeGameMode gameMode = gameModes.read(0);
|
||||
|
||||
StructureModifier<WrappedChatComponent> displayNames = modifier.withType(
|
||||
MinecraftReflection.getIChatBaseComponentClass(), BukkitConverters.getWrappedChatComponentConverter());
|
||||
WrappedChatComponent displayName = displayNames.read(0);
|
||||
|
||||
return new PlayerInfoData(gameProfile, latency, gameMode, displayName);
|
||||
}
|
||||
|
||||
// Otherwise, return null
|
||||
return null;
|
||||
}
|
||||
|
||||
// Thanks Java Generics!
|
||||
@Override
|
||||
public Class<PlayerInfoData> getSpecificType() {
|
||||
return PlayerInfoData.class;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
// Fast checks
|
||||
if (this == obj) return true;
|
||||
if (obj == null) return false;
|
||||
|
||||
// Only compare objects of similar type
|
||||
if (obj instanceof PlayerInfoData) {
|
||||
PlayerInfoData other = (PlayerInfoData) obj;
|
||||
return profile.equals(other.profile) && latency == other.latency && gameMode == other.gameMode
|
||||
&& displayName.equals(other.displayName);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(latency, gameMode, profile, displayName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("PlayerInfoData[latency=%s, gameMode=%s, profile=%s, displayName=%s",
|
||||
latency, gameMode, profile, displayName);
|
||||
}
|
||||
}
|
||||
|
@ -1,166 +1,166 @@
|
||||
/**
|
||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||
* Copyright (C) 2015 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.wrappers;
|
||||
|
||||
import java.lang.reflect.Modifier;
|
||||
|
||||
import org.bukkit.Material;
|
||||
|
||||
import com.comphenix.protocol.reflect.FuzzyReflection;
|
||||
import com.comphenix.protocol.reflect.accessors.Accessors;
|
||||
import com.comphenix.protocol.reflect.accessors.MethodAccessor;
|
||||
import com.comphenix.protocol.reflect.fuzzy.FuzzyMethodContract;
|
||||
import com.comphenix.protocol.utility.MinecraftReflection;
|
||||
|
||||
/**
|
||||
* Represents a wrapper around IBlockData.
|
||||
*
|
||||
* @author dmulloy2
|
||||
*/
|
||||
|
||||
public class WrappedBlockData extends AbstractWrapper {
|
||||
private static final Class<?> MAGIC_NUMBERS = MinecraftReflection.getCraftBukkitClass("util.CraftMagicNumbers");
|
||||
private static final Class<?> IBLOCK_DATA = MinecraftReflection.getIBlockDataClass();
|
||||
private static final Class<?> BLOCK = MinecraftReflection.getBlockClass();
|
||||
|
||||
private static MethodAccessor FROM_LEGACY_DATA = null;
|
||||
private static MethodAccessor TO_LEGACY_DATA = null;
|
||||
private static MethodAccessor GET_NMS_BLOCK = null;
|
||||
private static MethodAccessor GET_BLOCK = null;
|
||||
|
||||
static {
|
||||
FuzzyReflection fuzzy = FuzzyReflection.fromClass(BLOCK);
|
||||
FuzzyMethodContract contract = FuzzyMethodContract.newBuilder()
|
||||
.banModifier(Modifier.STATIC)
|
||||
.parameterExactArray(int.class)
|
||||
.returnTypeExact(IBLOCK_DATA)
|
||||
.build();
|
||||
FROM_LEGACY_DATA = Accessors.getMethodAccessor(fuzzy.getMethod(contract));
|
||||
|
||||
contract = FuzzyMethodContract.newBuilder()
|
||||
.banModifier(Modifier.STATIC)
|
||||
.parameterExactArray(IBLOCK_DATA)
|
||||
.returnTypeExact(int.class)
|
||||
.build();
|
||||
TO_LEGACY_DATA = Accessors.getMethodAccessor(fuzzy.getMethod(contract, "toLegacyData"));
|
||||
|
||||
fuzzy = FuzzyReflection.fromClass(MAGIC_NUMBERS);
|
||||
GET_NMS_BLOCK = Accessors.getMethodAccessor(fuzzy.getMethodByParameters("getBlock", BLOCK,
|
||||
new Class<?>[] { Material.class }));
|
||||
|
||||
fuzzy = FuzzyReflection.fromClass(IBLOCK_DATA);
|
||||
GET_BLOCK = Accessors.getMethodAccessor(fuzzy.getMethodByParameters("getBlock", BLOCK,
|
||||
new Class<?>[0]));
|
||||
}
|
||||
|
||||
public WrappedBlockData(Object handle) {
|
||||
super(IBLOCK_DATA);
|
||||
setHandle(handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the type of this BlockData.
|
||||
* @return The type of this BlockData.
|
||||
*/
|
||||
public Material getType() {
|
||||
Object block = GET_BLOCK.invoke(handle);
|
||||
return BukkitConverters.getBlockConverter().getSpecific(block);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the type id of this BlockData.
|
||||
* @return The type id of this BlockData.
|
||||
* @deprecated ID's are deprecated
|
||||
*/
|
||||
@Deprecated
|
||||
public int getTypeId() {
|
||||
Object block = GET_BLOCK.invoke(handle);
|
||||
return BukkitConverters.getBlockIDConverter().getSpecific(block);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the data of this BlockData.
|
||||
* @return The data of this BlockData.
|
||||
*/
|
||||
public int getData() {
|
||||
Object block = GET_BLOCK.invoke(handle);
|
||||
return (Integer) TO_LEGACY_DATA.invoke(block, handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the type of this BlockData.
|
||||
* @param type New type
|
||||
*/
|
||||
public void setType(Material type) {
|
||||
setTypeAndData(type, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the data of this BlockData.
|
||||
* @param data New data
|
||||
*/
|
||||
public void setData(int data) {
|
||||
setTypeAndData(getType(), data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the type and data of this BlockData.
|
||||
* @param type New type
|
||||
* @param data New data
|
||||
*/
|
||||
public void setTypeAndData(Material type, int data) {
|
||||
Object nmsBlock = GET_NMS_BLOCK.invoke(null, type);
|
||||
Object blockData = FROM_LEGACY_DATA.invoke(nmsBlock, data);
|
||||
setHandle(blockData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new BlockData instance with the given type and no data.
|
||||
* @param type Block type
|
||||
* @return New BlockData
|
||||
*/
|
||||
public static WrappedBlockData createData(Material type) {
|
||||
return createData(type, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new BlockData instance with the given type and data.
|
||||
* @param type Block type
|
||||
* @param data Block data
|
||||
* @return New BlockData
|
||||
*/
|
||||
public static WrappedBlockData createData(Material type, int data) {
|
||||
Object nmsBlock = GET_NMS_BLOCK.invoke(null, type);
|
||||
Object blockData = FROM_LEGACY_DATA.invoke(nmsBlock, data);
|
||||
return new WrappedBlockData(blockData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "WrappedBlockData[handle=" + handle + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof WrappedBlockData) {
|
||||
WrappedBlockData that = (WrappedBlockData) o;
|
||||
return this.getType() == that.getType();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||
* Copyright (C) 2015 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.wrappers;
|
||||
|
||||
import java.lang.reflect.Modifier;
|
||||
|
||||
import org.bukkit.Material;
|
||||
|
||||
import com.comphenix.protocol.reflect.FuzzyReflection;
|
||||
import com.comphenix.protocol.reflect.accessors.Accessors;
|
||||
import com.comphenix.protocol.reflect.accessors.MethodAccessor;
|
||||
import com.comphenix.protocol.reflect.fuzzy.FuzzyMethodContract;
|
||||
import com.comphenix.protocol.utility.MinecraftReflection;
|
||||
|
||||
/**
|
||||
* Represents a wrapper around IBlockData.
|
||||
*
|
||||
* @author dmulloy2
|
||||
*/
|
||||
|
||||
public class WrappedBlockData extends AbstractWrapper {
|
||||
private static final Class<?> MAGIC_NUMBERS = MinecraftReflection.getCraftBukkitClass("util.CraftMagicNumbers");
|
||||
private static final Class<?> IBLOCK_DATA = MinecraftReflection.getIBlockDataClass();
|
||||
private static final Class<?> BLOCK = MinecraftReflection.getBlockClass();
|
||||
|
||||
private static MethodAccessor FROM_LEGACY_DATA = null;
|
||||
private static MethodAccessor TO_LEGACY_DATA = null;
|
||||
private static MethodAccessor GET_NMS_BLOCK = null;
|
||||
private static MethodAccessor GET_BLOCK = null;
|
||||
|
||||
static {
|
||||
FuzzyReflection fuzzy = FuzzyReflection.fromClass(BLOCK);
|
||||
FuzzyMethodContract contract = FuzzyMethodContract.newBuilder()
|
||||
.banModifier(Modifier.STATIC)
|
||||
.parameterExactArray(int.class)
|
||||
.returnTypeExact(IBLOCK_DATA)
|
||||
.build();
|
||||
FROM_LEGACY_DATA = Accessors.getMethodAccessor(fuzzy.getMethod(contract));
|
||||
|
||||
contract = FuzzyMethodContract.newBuilder()
|
||||
.banModifier(Modifier.STATIC)
|
||||
.parameterExactArray(IBLOCK_DATA)
|
||||
.returnTypeExact(int.class)
|
||||
.build();
|
||||
TO_LEGACY_DATA = Accessors.getMethodAccessor(fuzzy.getMethod(contract, "toLegacyData"));
|
||||
|
||||
fuzzy = FuzzyReflection.fromClass(MAGIC_NUMBERS);
|
||||
GET_NMS_BLOCK = Accessors.getMethodAccessor(fuzzy.getMethodByParameters("getBlock", BLOCK,
|
||||
new Class<?>[] { Material.class }));
|
||||
|
||||
fuzzy = FuzzyReflection.fromClass(IBLOCK_DATA);
|
||||
GET_BLOCK = Accessors.getMethodAccessor(fuzzy.getMethodByParameters("getBlock", BLOCK,
|
||||
new Class<?>[0]));
|
||||
}
|
||||
|
||||
public WrappedBlockData(Object handle) {
|
||||
super(IBLOCK_DATA);
|
||||
setHandle(handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the type of this BlockData.
|
||||
* @return The type of this BlockData.
|
||||
*/
|
||||
public Material getType() {
|
||||
Object block = GET_BLOCK.invoke(handle);
|
||||
return BukkitConverters.getBlockConverter().getSpecific(block);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the type id of this BlockData.
|
||||
* @return The type id of this BlockData.
|
||||
* @deprecated ID's are deprecated
|
||||
*/
|
||||
@Deprecated
|
||||
public int getTypeId() {
|
||||
Object block = GET_BLOCK.invoke(handle);
|
||||
return BukkitConverters.getBlockIDConverter().getSpecific(block);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the data of this BlockData.
|
||||
* @return The data of this BlockData.
|
||||
*/
|
||||
public int getData() {
|
||||
Object block = GET_BLOCK.invoke(handle);
|
||||
return (Integer) TO_LEGACY_DATA.invoke(block, handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the type of this BlockData.
|
||||
* @param type New type
|
||||
*/
|
||||
public void setType(Material type) {
|
||||
setTypeAndData(type, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the data of this BlockData.
|
||||
* @param data New data
|
||||
*/
|
||||
public void setData(int data) {
|
||||
setTypeAndData(getType(), data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the type and data of this BlockData.
|
||||
* @param type New type
|
||||
* @param data New data
|
||||
*/
|
||||
public void setTypeAndData(Material type, int data) {
|
||||
Object nmsBlock = GET_NMS_BLOCK.invoke(null, type);
|
||||
Object blockData = FROM_LEGACY_DATA.invoke(nmsBlock, data);
|
||||
setHandle(blockData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new BlockData instance with the given type and no data.
|
||||
* @param type Block type
|
||||
* @return New BlockData
|
||||
*/
|
||||
public static WrappedBlockData createData(Material type) {
|
||||
return createData(type, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new BlockData instance with the given type and data.
|
||||
* @param type Block type
|
||||
* @param data Block data
|
||||
* @return New BlockData
|
||||
*/
|
||||
public static WrappedBlockData createData(Material type, int data) {
|
||||
Object nmsBlock = GET_NMS_BLOCK.invoke(null, type);
|
||||
Object blockData = FROM_LEGACY_DATA.invoke(nmsBlock, data);
|
||||
return new WrappedBlockData(blockData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "WrappedBlockData[handle=" + handle + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o instanceof WrappedBlockData) {
|
||||
WrappedBlockData that = (WrappedBlockData) o;
|
||||
return this.getType() == that.getType();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -158,4 +158,4 @@ public class WrappedChatComponent extends AbstractWrapper {
|
||||
public String toString() {
|
||||
return "WrappedChatComponent[json=" + getJson() + "]";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -333,4 +333,4 @@ public class WrappedGameProfile extends AbstractWrapper {
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,232 +1,232 @@
|
||||
/**
|
||||
* 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.wrappers;
|
||||
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import com.comphenix.protocol.reflect.StructureModifier;
|
||||
import com.comphenix.protocol.reflect.accessors.Accessors;
|
||||
import com.comphenix.protocol.reflect.accessors.ConstructorAccessor;
|
||||
import com.comphenix.protocol.utility.MinecraftReflection;
|
||||
import com.comphenix.protocol.wrappers.WrappedDataWatcher.WrappedDataWatcherObject;
|
||||
|
||||
/**
|
||||
* Represents a DataWatcher Item in 1.9.
|
||||
* @author dmulloy2
|
||||
*/
|
||||
|
||||
public class WrappedWatchableObject extends AbstractWrapper {
|
||||
private static final Class<?> HANDLE_TYPE = MinecraftReflection.getDataWatcherItemClass();
|
||||
private static ConstructorAccessor constructor;
|
||||
|
||||
private final StructureModifier<Object> modifier;
|
||||
|
||||
/**
|
||||
* Constructs a wrapped watchable object around an existing NMS data watcher item.
|
||||
* @param handle Data watcher item
|
||||
*/
|
||||
public WrappedWatchableObject(Object handle) {
|
||||
super(HANDLE_TYPE);
|
||||
setHandle(handle);
|
||||
this.modifier = new StructureModifier<Object>(handleType).withTarget(handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a wrapped watchable object with a given watcher object and initial value.
|
||||
* @param watcherObject Watcher object
|
||||
* @param value Initial value
|
||||
*/
|
||||
public WrappedWatchableObject(WrappedDataWatcherObject watcherObject, Object value) {
|
||||
this(newHandle(watcherObject, value));
|
||||
}
|
||||
|
||||
private static Object newHandle(WrappedDataWatcherObject watcherObject, Object value) {
|
||||
if (constructor == null) {
|
||||
constructor = Accessors.getConstructorAccessor(HANDLE_TYPE.getConstructors()[0]);
|
||||
}
|
||||
|
||||
return constructor.invoke(watcherObject.getHandle(), value);
|
||||
}
|
||||
|
||||
// ---- Getter methods
|
||||
|
||||
/**
|
||||
* Gets this Item's watcher object, which contains the index and serializer.
|
||||
* @return The watcher object
|
||||
*/
|
||||
public WrappedDataWatcherObject getWatcherObject() {
|
||||
return new WrappedDataWatcherObject(modifier.read(0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this Item's index from the watcher object
|
||||
* @return The index
|
||||
*/
|
||||
public int getIndex() {
|
||||
return getWatcherObject().getIndex();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the wrapped value of this data watcher item.
|
||||
* @return The wrapped value
|
||||
*/
|
||||
public Object getValue() {
|
||||
return getWrapped(getRawValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the raw value of this data watcher item.
|
||||
* @return Raw value
|
||||
*/
|
||||
public Object getRawValue() {
|
||||
return modifier.readSafely(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the wrapped object value, if needed.
|
||||
*
|
||||
* @param value - the raw NMS object to wrap.
|
||||
* @return The wrapped object.
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
static Object getWrapped(Object value) {
|
||||
// Handle the special cases
|
||||
if (MinecraftReflection.isItemStack(value)) {
|
||||
return BukkitConverters.getItemStackConverter().getSpecific(value);
|
||||
} else if (MinecraftReflection.isChunkCoordinates(value)) {
|
||||
return new WrappedChunkCoordinate((Comparable) value);
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the wrapped type, if needed.
|
||||
*
|
||||
* @param wrapped - the wrapped class type.
|
||||
* @return The wrapped class type.
|
||||
*/
|
||||
static Class<?> getWrappedType(Class<?> unwrapped) {
|
||||
if (unwrapped.equals(MinecraftReflection.getChunkPositionClass()))
|
||||
return ChunkPosition.class;
|
||||
else if (unwrapped.equals(MinecraftReflection.getBlockPositionClass()))
|
||||
return BlockPosition.class;
|
||||
else if (unwrapped.equals(MinecraftReflection.getChunkCoordinatesClass()))
|
||||
return WrappedChunkCoordinate.class;
|
||||
else if (unwrapped.equals(MinecraftReflection.getItemStackClass()))
|
||||
return ItemStack.class;
|
||||
else
|
||||
return unwrapped;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of this item.
|
||||
* @param value New value
|
||||
* @param updateClient Whether or not to update the client
|
||||
*/
|
||||
public void setValue(Object value, boolean updateClient) {
|
||||
modifier.write(1, getUnwrapped(value));
|
||||
|
||||
if (updateClient) {
|
||||
setDirtyState(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of this item.
|
||||
* @param value New value
|
||||
*/
|
||||
public void setValue(Object value) {
|
||||
setValue(value, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the raw NMS value.
|
||||
*
|
||||
* @param wrapped - the wrapped position.
|
||||
* @return The raw NMS object.
|
||||
*/
|
||||
static Object getUnwrapped(Object wrapped) {
|
||||
// Convert special cases
|
||||
if (wrapped instanceof ChunkPosition)
|
||||
return ChunkPosition.getConverter().getGeneric(MinecraftReflection.getChunkPositionClass(), (ChunkPosition) wrapped);
|
||||
else if (wrapped instanceof BlockPosition)
|
||||
return BlockPosition.getConverter().getGeneric(MinecraftReflection.getBlockPositionClass(), (BlockPosition) wrapped);
|
||||
else if (wrapped instanceof WrappedChunkCoordinate)
|
||||
return ((WrappedChunkCoordinate) wrapped).getHandle();
|
||||
else if (wrapped instanceof ItemStack)
|
||||
return BukkitConverters.getItemStackConverter().getGeneric(MinecraftReflection.getItemStackClass(), (ItemStack) wrapped);
|
||||
else
|
||||
return wrapped;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the unwrapped type, if needed.
|
||||
*
|
||||
* @param wrapped - the unwrapped class type.
|
||||
* @return The unwrapped class type.
|
||||
*/
|
||||
static Class<?> getUnwrappedType(Class<?> wrapped) {
|
||||
if (wrapped.equals(ChunkPosition.class))
|
||||
return MinecraftReflection.getChunkPositionClass();
|
||||
else if (wrapped.equals(BlockPosition.class))
|
||||
return MinecraftReflection.getBlockPositionClass();
|
||||
else if (wrapped.equals(WrappedChunkCoordinate.class))
|
||||
return MinecraftReflection.getChunkCoordinatesClass();
|
||||
else if (ItemStack.class.isAssignableFrom(wrapped))
|
||||
return MinecraftReflection.getItemStackClass();
|
||||
else
|
||||
return wrapped;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not the value must be synchronized with the client.
|
||||
* @return True if it must, false if not
|
||||
*/
|
||||
public boolean getDirtyState() {
|
||||
return (boolean) modifier.read(2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this item's dirty state
|
||||
* @param dirty New state
|
||||
*/
|
||||
public void setDirtyState(boolean dirty) {
|
||||
modifier.write(2, dirty);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == this) return true;
|
||||
if (obj == null) return false;
|
||||
|
||||
if (obj instanceof WrappedWatchableObject) {
|
||||
// watcher object, value, dirty state
|
||||
WrappedWatchableObject other = (WrappedWatchableObject) obj;
|
||||
return getWatcherObject().equals(other.getWatcherObject())
|
||||
&& getRawValue().equals(other.getRawValue())
|
||||
&& getDirtyState() == other.getDirtyState();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "DataWatcherItem[object=" + getWatcherObject() + ", value=" + getValue() + ", dirty=" + getDirtyState() + "]";
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 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.wrappers;
|
||||
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import com.comphenix.protocol.reflect.StructureModifier;
|
||||
import com.comphenix.protocol.reflect.accessors.Accessors;
|
||||
import com.comphenix.protocol.reflect.accessors.ConstructorAccessor;
|
||||
import com.comphenix.protocol.utility.MinecraftReflection;
|
||||
import com.comphenix.protocol.wrappers.WrappedDataWatcher.WrappedDataWatcherObject;
|
||||
|
||||
/**
|
||||
* Represents a DataWatcher Item in 1.9.
|
||||
* @author dmulloy2
|
||||
*/
|
||||
|
||||
public class WrappedWatchableObject extends AbstractWrapper {
|
||||
private static final Class<?> HANDLE_TYPE = MinecraftReflection.getDataWatcherItemClass();
|
||||
private static ConstructorAccessor constructor;
|
||||
|
||||
private final StructureModifier<Object> modifier;
|
||||
|
||||
/**
|
||||
* Constructs a wrapped watchable object around an existing NMS data watcher item.
|
||||
* @param handle Data watcher item
|
||||
*/
|
||||
public WrappedWatchableObject(Object handle) {
|
||||
super(HANDLE_TYPE);
|
||||
setHandle(handle);
|
||||
this.modifier = new StructureModifier<Object>(handleType).withTarget(handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a wrapped watchable object with a given watcher object and initial value.
|
||||
* @param watcherObject Watcher object
|
||||
* @param value Initial value
|
||||
*/
|
||||
public WrappedWatchableObject(WrappedDataWatcherObject watcherObject, Object value) {
|
||||
this(newHandle(watcherObject, value));
|
||||
}
|
||||
|
||||
private static Object newHandle(WrappedDataWatcherObject watcherObject, Object value) {
|
||||
if (constructor == null) {
|
||||
constructor = Accessors.getConstructorAccessor(HANDLE_TYPE.getConstructors()[0]);
|
||||
}
|
||||
|
||||
return constructor.invoke(watcherObject.getHandle(), value);
|
||||
}
|
||||
|
||||
// ---- Getter methods
|
||||
|
||||
/**
|
||||
* Gets this Item's watcher object, which contains the index and serializer.
|
||||
* @return The watcher object
|
||||
*/
|
||||
public WrappedDataWatcherObject getWatcherObject() {
|
||||
return new WrappedDataWatcherObject(modifier.read(0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this Item's index from the watcher object
|
||||
* @return The index
|
||||
*/
|
||||
public int getIndex() {
|
||||
return getWatcherObject().getIndex();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the wrapped value of this data watcher item.
|
||||
* @return The wrapped value
|
||||
*/
|
||||
public Object getValue() {
|
||||
return getWrapped(getRawValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the raw value of this data watcher item.
|
||||
* @return Raw value
|
||||
*/
|
||||
public Object getRawValue() {
|
||||
return modifier.readSafely(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the wrapped object value, if needed.
|
||||
*
|
||||
* @param value - the raw NMS object to wrap.
|
||||
* @return The wrapped object.
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
static Object getWrapped(Object value) {
|
||||
// Handle the special cases
|
||||
if (MinecraftReflection.isItemStack(value)) {
|
||||
return BukkitConverters.getItemStackConverter().getSpecific(value);
|
||||
} else if (MinecraftReflection.isChunkCoordinates(value)) {
|
||||
return new WrappedChunkCoordinate((Comparable) value);
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the wrapped type, if needed.
|
||||
*
|
||||
* @param wrapped - the wrapped class type.
|
||||
* @return The wrapped class type.
|
||||
*/
|
||||
static Class<?> getWrappedType(Class<?> unwrapped) {
|
||||
if (unwrapped.equals(MinecraftReflection.getChunkPositionClass()))
|
||||
return ChunkPosition.class;
|
||||
else if (unwrapped.equals(MinecraftReflection.getBlockPositionClass()))
|
||||
return BlockPosition.class;
|
||||
else if (unwrapped.equals(MinecraftReflection.getChunkCoordinatesClass()))
|
||||
return WrappedChunkCoordinate.class;
|
||||
else if (unwrapped.equals(MinecraftReflection.getItemStackClass()))
|
||||
return ItemStack.class;
|
||||
else
|
||||
return unwrapped;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of this item.
|
||||
* @param value New value
|
||||
* @param updateClient Whether or not to update the client
|
||||
*/
|
||||
public void setValue(Object value, boolean updateClient) {
|
||||
modifier.write(1, getUnwrapped(value));
|
||||
|
||||
if (updateClient) {
|
||||
setDirtyState(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of this item.
|
||||
* @param value New value
|
||||
*/
|
||||
public void setValue(Object value) {
|
||||
setValue(value, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the raw NMS value.
|
||||
*
|
||||
* @param wrapped - the wrapped position.
|
||||
* @return The raw NMS object.
|
||||
*/
|
||||
static Object getUnwrapped(Object wrapped) {
|
||||
// Convert special cases
|
||||
if (wrapped instanceof ChunkPosition)
|
||||
return ChunkPosition.getConverter().getGeneric(MinecraftReflection.getChunkPositionClass(), (ChunkPosition) wrapped);
|
||||
else if (wrapped instanceof BlockPosition)
|
||||
return BlockPosition.getConverter().getGeneric(MinecraftReflection.getBlockPositionClass(), (BlockPosition) wrapped);
|
||||
else if (wrapped instanceof WrappedChunkCoordinate)
|
||||
return ((WrappedChunkCoordinate) wrapped).getHandle();
|
||||
else if (wrapped instanceof ItemStack)
|
||||
return BukkitConverters.getItemStackConverter().getGeneric(MinecraftReflection.getItemStackClass(), (ItemStack) wrapped);
|
||||
else
|
||||
return wrapped;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the unwrapped type, if needed.
|
||||
*
|
||||
* @param wrapped - the unwrapped class type.
|
||||
* @return The unwrapped class type.
|
||||
*/
|
||||
static Class<?> getUnwrappedType(Class<?> wrapped) {
|
||||
if (wrapped.equals(ChunkPosition.class))
|
||||
return MinecraftReflection.getChunkPositionClass();
|
||||
else if (wrapped.equals(BlockPosition.class))
|
||||
return MinecraftReflection.getBlockPositionClass();
|
||||
else if (wrapped.equals(WrappedChunkCoordinate.class))
|
||||
return MinecraftReflection.getChunkCoordinatesClass();
|
||||
else if (ItemStack.class.isAssignableFrom(wrapped))
|
||||
return MinecraftReflection.getItemStackClass();
|
||||
else
|
||||
return wrapped;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not the value must be synchronized with the client.
|
||||
* @return True if it must, false if not
|
||||
*/
|
||||
public boolean getDirtyState() {
|
||||
return (boolean) modifier.read(2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this item's dirty state
|
||||
* @param dirty New state
|
||||
*/
|
||||
public void setDirtyState(boolean dirty) {
|
||||
modifier.write(2, dirty);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == this) return true;
|
||||
if (obj == null) return false;
|
||||
|
||||
if (obj instanceof WrappedWatchableObject) {
|
||||
// watcher object, value, dirty state
|
||||
WrappedWatchableObject other = (WrappedWatchableObject) obj;
|
||||
return getWatcherObject().equals(other.getWatcherObject())
|
||||
&& getRawValue().equals(other.getRawValue())
|
||||
&& getDirtyState() == other.getDirtyState();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "DataWatcherItem[object=" + getWatcherObject() + ", value=" + getValue() + ", dirty=" + getDirtyState() + "]";
|
||||
}
|
||||
}
|
||||
|
@ -9,4 +9,4 @@ package com.comphenix.protocol.wrappers.collection;
|
||||
*/
|
||||
public interface BiFunction<T1, T2, TResult> {
|
||||
public TResult apply(T1 arg1, T2 arg2);
|
||||
}
|
||||
}
|
||||
|
@ -84,4 +84,4 @@ public interface NbtBase<TType> {
|
||||
* @return The cloned tag.
|
||||
*/
|
||||
public abstract NbtBase<TType> deepClone();
|
||||
}
|
||||
}
|
||||
|
@ -350,4 +350,4 @@ public interface NbtCompound extends NbtBase<Map<String, NbtBase<?>>>, Iterable<
|
||||
*/
|
||||
@Override
|
||||
public abstract Iterator<NbtBase<?>> iterator();
|
||||
}
|
||||
}
|
||||
|
@ -137,4 +137,4 @@ public interface NbtList<TType> extends NbtBase<List<NbtBase<TType>>>, Iterable<
|
||||
*/
|
||||
@Override
|
||||
public abstract Iterator<TType> iterator();
|
||||
}
|
||||
}
|
||||
|
@ -678,4 +678,4 @@ public class ProtocolLib extends JavaPlugin {
|
||||
public Statistics getStatistics() {
|
||||
return statistics;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -91,4 +91,4 @@ public interface ListenerInvoker {
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract Class<?> getPacketClassFromID(int packetID, boolean forceVanilla);
|
||||
}
|
||||
}
|
||||
|
Datei-Diff unterdrückt, da er zu groß ist
Diff laden
@ -63,4 +63,4 @@ public interface ChannelListener {
|
||||
* @return TRUE if it is, FALSE otherwise.
|
||||
*/
|
||||
boolean isDebug();
|
||||
}
|
||||
}
|
||||
|
@ -94,4 +94,4 @@ public interface Injector {
|
||||
* @param player - the more up-to-date player.
|
||||
*/
|
||||
public abstract void setUpdatedPlayer(Player player);
|
||||
}
|
||||
}
|
||||
|
@ -1,371 +1,371 @@
|
||||
/**
|
||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||
* Copyright (C) 2015 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.injector.netty;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelPipeline;
|
||||
import io.netty.channel.ChannelPromise;
|
||||
import io.netty.util.concurrent.EventExecutorGroup;
|
||||
|
||||
import java.net.SocketAddress;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
/**
|
||||
* A pipeline proxy.
|
||||
* @author Kristian
|
||||
*/
|
||||
public class PipelineProxy implements ChannelPipeline {
|
||||
protected final ChannelPipeline pipeline;
|
||||
protected final Channel channel;
|
||||
|
||||
public PipelineProxy(ChannelPipeline pipeline, Channel channel) {
|
||||
this.pipeline = pipeline;
|
||||
this.channel = channel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelPipeline addAfter(EventExecutorGroup arg0, String arg1, String arg2, ChannelHandler arg3) {
|
||||
pipeline.addAfter(arg0, arg1, arg2, arg3);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelPipeline addAfter(String arg0, String arg1, ChannelHandler arg2) {
|
||||
pipeline.addAfter(arg0, arg1, arg2);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelPipeline addBefore(EventExecutorGroup arg0, String arg1, String arg2, ChannelHandler arg3) {
|
||||
pipeline.addBefore(arg0, arg1, arg2, arg3);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelPipeline addBefore(String arg0, String arg1, ChannelHandler arg2) {
|
||||
pipeline.addBefore(arg0, arg1, arg2);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelPipeline addFirst(ChannelHandler... arg0) {
|
||||
pipeline.addFirst(arg0);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelPipeline addFirst(EventExecutorGroup arg0, ChannelHandler... arg1) {
|
||||
pipeline.addFirst(arg0, arg1);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelPipeline addFirst(EventExecutorGroup arg0, String arg1, ChannelHandler arg2) {
|
||||
pipeline.addFirst(arg0, arg1, arg2);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelPipeline addFirst(String arg0, ChannelHandler arg1) {
|
||||
pipeline.addFirst(arg0, arg1);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelPipeline addLast(ChannelHandler... arg0) {
|
||||
pipeline.addLast(arg0);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelPipeline addLast(EventExecutorGroup arg0, ChannelHandler... arg1) {
|
||||
pipeline.addLast(arg0, arg1);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelPipeline addLast(EventExecutorGroup arg0, String arg1, ChannelHandler arg2) {
|
||||
pipeline.addLast(arg0, arg1, arg2);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelPipeline addLast(String arg0, ChannelHandler arg1) {
|
||||
pipeline.addLast(arg0, arg1);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelFuture bind(SocketAddress arg0, ChannelPromise arg1) {
|
||||
return pipeline.bind(arg0, arg1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelFuture bind(SocketAddress arg0) {
|
||||
return pipeline.bind(arg0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Channel channel() {
|
||||
return channel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelFuture close() {
|
||||
return pipeline.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelFuture close(ChannelPromise arg0) {
|
||||
return pipeline.close(arg0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelFuture connect(SocketAddress arg0, ChannelPromise arg1) {
|
||||
return pipeline.connect(arg0, arg1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelFuture connect(SocketAddress arg0, SocketAddress arg1, ChannelPromise arg2) {
|
||||
return pipeline.connect(arg0, arg1, arg2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelFuture connect(SocketAddress arg0, SocketAddress arg1) {
|
||||
return pipeline.connect(arg0, arg1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelFuture connect(SocketAddress arg0) {
|
||||
return pipeline.connect(arg0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelHandlerContext context(ChannelHandler arg0) {
|
||||
return pipeline.context(arg0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelHandlerContext context(Class<? extends ChannelHandler> arg0) {
|
||||
return pipeline.context(arg0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelHandlerContext context(String arg0) {
|
||||
return pipeline.context(arg0);
|
||||
}
|
||||
|
||||
// We have to call the depreciated methods to properly implement the proxy
|
||||
@Override
|
||||
public ChannelFuture deregister() {
|
||||
return pipeline.deregister();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelFuture deregister(ChannelPromise arg0) {
|
||||
return pipeline.deregister(arg0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelPipeline fireChannelUnregistered() {
|
||||
pipeline.fireChannelUnregistered();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelFuture disconnect() {
|
||||
return pipeline.disconnect();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelFuture disconnect(ChannelPromise arg0) {
|
||||
return pipeline.disconnect(arg0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelPipeline fireChannelActive() {
|
||||
pipeline.fireChannelActive();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelPipeline fireChannelInactive() {
|
||||
pipeline.fireChannelInactive();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelPipeline fireChannelRead(Object arg0) {
|
||||
pipeline.fireChannelRead(arg0);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelPipeline fireChannelReadComplete() {
|
||||
pipeline.fireChannelReadComplete();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelPipeline fireChannelRegistered() {
|
||||
pipeline.fireChannelRegistered();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelPipeline fireChannelWritabilityChanged() {
|
||||
pipeline.fireChannelWritabilityChanged();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelPipeline fireExceptionCaught(Throwable arg0) {
|
||||
pipeline.fireExceptionCaught(arg0);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelPipeline fireUserEventTriggered(Object arg0) {
|
||||
pipeline.fireUserEventTriggered(arg0);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelHandler first() {
|
||||
return pipeline.first();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelHandlerContext firstContext() {
|
||||
return pipeline.firstContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelPipeline flush() {
|
||||
pipeline.flush();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends ChannelHandler> T get(Class<T> arg0) {
|
||||
return pipeline.get(arg0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelHandler get(String arg0) {
|
||||
return pipeline.get(arg0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Entry<String, ChannelHandler>> iterator() {
|
||||
return pipeline.iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelHandler last() {
|
||||
return pipeline.last();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelHandlerContext lastContext() {
|
||||
return pipeline.lastContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> names() {
|
||||
return pipeline.names();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelPipeline read() {
|
||||
pipeline.read();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelPipeline remove(ChannelHandler arg0) {
|
||||
pipeline.remove(arg0);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends ChannelHandler> T remove(Class<T> arg0) {
|
||||
return pipeline.remove(arg0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelHandler remove(String arg0) {
|
||||
return pipeline.remove(arg0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelHandler removeFirst() {
|
||||
return pipeline.removeFirst();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelHandler removeLast() {
|
||||
return pipeline.removeLast();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelPipeline replace(ChannelHandler arg0, String arg1, ChannelHandler arg2) {
|
||||
pipeline.replace(arg0, arg1, arg2);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends ChannelHandler> T replace(Class<T> arg0, String arg1, ChannelHandler arg2) {
|
||||
return pipeline.replace(arg0, arg1, arg2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelHandler replace(String arg0, String arg1, ChannelHandler arg2) {
|
||||
return pipeline.replace(arg0, arg1, arg2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, ChannelHandler> toMap() {
|
||||
return pipeline.toMap();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelFuture write(Object arg0, ChannelPromise arg1) {
|
||||
return pipeline.write(arg0, arg1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelFuture write(Object arg0) {
|
||||
return pipeline.write(arg0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelFuture writeAndFlush(Object arg0, ChannelPromise arg1) {
|
||||
return pipeline.writeAndFlush(arg0, arg1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelFuture writeAndFlush(Object arg0) {
|
||||
return pipeline.writeAndFlush(arg0);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||
* Copyright (C) 2015 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.injector.netty;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelPipeline;
|
||||
import io.netty.channel.ChannelPromise;
|
||||
import io.netty.util.concurrent.EventExecutorGroup;
|
||||
|
||||
import java.net.SocketAddress;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
/**
|
||||
* A pipeline proxy.
|
||||
* @author Kristian
|
||||
*/
|
||||
public class PipelineProxy implements ChannelPipeline {
|
||||
protected final ChannelPipeline pipeline;
|
||||
protected final Channel channel;
|
||||
|
||||
public PipelineProxy(ChannelPipeline pipeline, Channel channel) {
|
||||
this.pipeline = pipeline;
|
||||
this.channel = channel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelPipeline addAfter(EventExecutorGroup arg0, String arg1, String arg2, ChannelHandler arg3) {
|
||||
pipeline.addAfter(arg0, arg1, arg2, arg3);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelPipeline addAfter(String arg0, String arg1, ChannelHandler arg2) {
|
||||
pipeline.addAfter(arg0, arg1, arg2);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelPipeline addBefore(EventExecutorGroup arg0, String arg1, String arg2, ChannelHandler arg3) {
|
||||
pipeline.addBefore(arg0, arg1, arg2, arg3);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelPipeline addBefore(String arg0, String arg1, ChannelHandler arg2) {
|
||||
pipeline.addBefore(arg0, arg1, arg2);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelPipeline addFirst(ChannelHandler... arg0) {
|
||||
pipeline.addFirst(arg0);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelPipeline addFirst(EventExecutorGroup arg0, ChannelHandler... arg1) {
|
||||
pipeline.addFirst(arg0, arg1);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelPipeline addFirst(EventExecutorGroup arg0, String arg1, ChannelHandler arg2) {
|
||||
pipeline.addFirst(arg0, arg1, arg2);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelPipeline addFirst(String arg0, ChannelHandler arg1) {
|
||||
pipeline.addFirst(arg0, arg1);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelPipeline addLast(ChannelHandler... arg0) {
|
||||
pipeline.addLast(arg0);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelPipeline addLast(EventExecutorGroup arg0, ChannelHandler... arg1) {
|
||||
pipeline.addLast(arg0, arg1);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelPipeline addLast(EventExecutorGroup arg0, String arg1, ChannelHandler arg2) {
|
||||
pipeline.addLast(arg0, arg1, arg2);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelPipeline addLast(String arg0, ChannelHandler arg1) {
|
||||
pipeline.addLast(arg0, arg1);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelFuture bind(SocketAddress arg0, ChannelPromise arg1) {
|
||||
return pipeline.bind(arg0, arg1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelFuture bind(SocketAddress arg0) {
|
||||
return pipeline.bind(arg0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Channel channel() {
|
||||
return channel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelFuture close() {
|
||||
return pipeline.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelFuture close(ChannelPromise arg0) {
|
||||
return pipeline.close(arg0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelFuture connect(SocketAddress arg0, ChannelPromise arg1) {
|
||||
return pipeline.connect(arg0, arg1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelFuture connect(SocketAddress arg0, SocketAddress arg1, ChannelPromise arg2) {
|
||||
return pipeline.connect(arg0, arg1, arg2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelFuture connect(SocketAddress arg0, SocketAddress arg1) {
|
||||
return pipeline.connect(arg0, arg1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelFuture connect(SocketAddress arg0) {
|
||||
return pipeline.connect(arg0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelHandlerContext context(ChannelHandler arg0) {
|
||||
return pipeline.context(arg0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelHandlerContext context(Class<? extends ChannelHandler> arg0) {
|
||||
return pipeline.context(arg0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelHandlerContext context(String arg0) {
|
||||
return pipeline.context(arg0);
|
||||
}
|
||||
|
||||
// We have to call the depreciated methods to properly implement the proxy
|
||||
@Override
|
||||
public ChannelFuture deregister() {
|
||||
return pipeline.deregister();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelFuture deregister(ChannelPromise arg0) {
|
||||
return pipeline.deregister(arg0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelPipeline fireChannelUnregistered() {
|
||||
pipeline.fireChannelUnregistered();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelFuture disconnect() {
|
||||
return pipeline.disconnect();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelFuture disconnect(ChannelPromise arg0) {
|
||||
return pipeline.disconnect(arg0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelPipeline fireChannelActive() {
|
||||
pipeline.fireChannelActive();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelPipeline fireChannelInactive() {
|
||||
pipeline.fireChannelInactive();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelPipeline fireChannelRead(Object arg0) {
|
||||
pipeline.fireChannelRead(arg0);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelPipeline fireChannelReadComplete() {
|
||||
pipeline.fireChannelReadComplete();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelPipeline fireChannelRegistered() {
|
||||
pipeline.fireChannelRegistered();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelPipeline fireChannelWritabilityChanged() {
|
||||
pipeline.fireChannelWritabilityChanged();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelPipeline fireExceptionCaught(Throwable arg0) {
|
||||
pipeline.fireExceptionCaught(arg0);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelPipeline fireUserEventTriggered(Object arg0) {
|
||||
pipeline.fireUserEventTriggered(arg0);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelHandler first() {
|
||||
return pipeline.first();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelHandlerContext firstContext() {
|
||||
return pipeline.firstContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelPipeline flush() {
|
||||
pipeline.flush();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends ChannelHandler> T get(Class<T> arg0) {
|
||||
return pipeline.get(arg0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelHandler get(String arg0) {
|
||||
return pipeline.get(arg0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Entry<String, ChannelHandler>> iterator() {
|
||||
return pipeline.iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelHandler last() {
|
||||
return pipeline.last();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelHandlerContext lastContext() {
|
||||
return pipeline.lastContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> names() {
|
||||
return pipeline.names();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelPipeline read() {
|
||||
pipeline.read();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelPipeline remove(ChannelHandler arg0) {
|
||||
pipeline.remove(arg0);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends ChannelHandler> T remove(Class<T> arg0) {
|
||||
return pipeline.remove(arg0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelHandler remove(String arg0) {
|
||||
return pipeline.remove(arg0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelHandler removeFirst() {
|
||||
return pipeline.removeFirst();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelHandler removeLast() {
|
||||
return pipeline.removeLast();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelPipeline replace(ChannelHandler arg0, String arg1, ChannelHandler arg2) {
|
||||
pipeline.replace(arg0, arg1, arg2);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends ChannelHandler> T replace(Class<T> arg0, String arg1, ChannelHandler arg2) {
|
||||
return pipeline.replace(arg0, arg1, arg2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelHandler replace(String arg0, String arg1, ChannelHandler arg2) {
|
||||
return pipeline.replace(arg0, arg1, arg2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, ChannelHandler> toMap() {
|
||||
return pipeline.toMap();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelFuture write(Object arg0, ChannelPromise arg1) {
|
||||
return pipeline.write(arg0, arg1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelFuture write(Object arg0) {
|
||||
return pipeline.write(arg0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelFuture writeAndFlush(Object arg0, ChannelPromise arg1) {
|
||||
return pipeline.writeAndFlush(arg0, arg1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChannelFuture writeAndFlush(Object arg0) {
|
||||
return pipeline.writeAndFlush(arg0);
|
||||
}
|
||||
}
|
||||
|
@ -62,4 +62,4 @@ public class LegacyNetworkMarker extends NetworkMarker {
|
||||
throw new RuntimeException("Cannot add header.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -76,4 +76,4 @@ public interface PacketInjector {
|
||||
* Perform any necessary cleanup before unloading ProtocolLib.
|
||||
*/
|
||||
public abstract void cleanupAll();
|
||||
}
|
||||
}
|
||||
|
@ -202,4 +202,4 @@ public interface PlayerInjectionHandler {
|
||||
public abstract boolean hasMainThreadListener(PacketType type);
|
||||
|
||||
public abstract Channel getChannel(Player player);
|
||||
}
|
||||
}
|
||||
|
@ -367,4 +367,4 @@ class ReplacedArrayList<TKey> extends ArrayList<TKey> {
|
||||
revertAll();
|
||||
super.finalize();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -80,4 +80,4 @@ public abstract class AbstractInputStreamLookup {
|
||||
* Invoked when the injection should be undone.
|
||||
*/
|
||||
public abstract void cleanupAll();
|
||||
}
|
||||
}
|
||||
|
@ -18,4 +18,4 @@ class InjectorContainer {
|
||||
throw new IllegalArgumentException("Injector cannot be NULL.");
|
||||
this.injector = injector;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -40,4 +40,4 @@ class QueuedSendPacket {
|
||||
public boolean isFiltered() {
|
||||
return filtered;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -68,4 +68,4 @@ public interface SocketInjector {
|
||||
* @param updatedPlayer - the real Bukkit player.
|
||||
*/
|
||||
public abstract void setUpdatedPlayer(Player updatedPlayer);
|
||||
}
|
||||
}
|
||||
|
@ -51,4 +51,4 @@ public abstract class AbstractPacketInjector implements PacketInjector {
|
||||
public void cleanupAll() {
|
||||
reveivedFilters.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -80,4 +80,4 @@ public abstract class AbstractPlayerHandler implements PlayerInjectionHandler {
|
||||
public void checkListener(Set<PacketListener> listeners) {
|
||||
// Yes, really
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -750,4 +750,4 @@ public class Metrics {
|
||||
return plotter.name.equals(name) && plotter.getValue() == getValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,417 +1,417 @@
|
||||
/*
|
||||
* Updater for Bukkit.
|
||||
*
|
||||
* This class provides the means to safely and easily update a plugin, or check to see if it is updated using dev.bukkit.org
|
||||
*/
|
||||
|
||||
// Somewhat modified by aadnk.
|
||||
package com.comphenix.protocol.updater;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.util.Enumeration;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.json.simple.JSONValue;
|
||||
|
||||
import com.comphenix.protocol.ProtocolLibrary;
|
||||
import com.comphenix.protocol.error.Report;
|
||||
|
||||
/**
|
||||
* Check dev.bukkit.org to find updates for a given plugin, and download the updates if needed.
|
||||
* <p/>
|
||||
* <b>VERY, VERY IMPORTANT</b>: Because there are no standards for adding auto-update toggles in your plugin's config, this system provides NO CHECK WITH YOUR CONFIG to make sure the user has allowed auto-updating.
|
||||
* <br>
|
||||
* It is a <b>BUKKIT POLICY</b> that you include a boolean value in your config that prevents the auto-updater from running <b>AT ALL</b>.
|
||||
* <br>
|
||||
* If you fail to include this option in your config, your plugin will be <b>REJECTED</b> when you attempt to submit it to dev.bukkit.org.
|
||||
* <p/>
|
||||
* An example of a good configuration option would be something similar to 'auto-update: true' - if this value is set to false you may NOT run the auto-updater.
|
||||
* <br>
|
||||
* If you are unsure about these rules, please read the plugin submission guidelines: http://goo.gl/8iU5l
|
||||
*
|
||||
* @author Gravity
|
||||
* @version 2.0
|
||||
*/
|
||||
|
||||
public class BukkitUpdater extends Updater {
|
||||
private URL url; // Connecting to RSS
|
||||
private File file; // The plugin's file
|
||||
private Thread thread; // Updater thread
|
||||
|
||||
private int id = -1; // Project's Curse ID
|
||||
private String apiKey = null; // BukkitDev ServerMods API key
|
||||
private static final String TITLE_VALUE = "name"; // Gets remote file's title
|
||||
private static final String LINK_VALUE = "downloadUrl"; // Gets remote file's download link
|
||||
private static final String TYPE_VALUE = "releaseType"; // Gets remote file's release type
|
||||
private static final String VERSION_VALUE = "gameVersion"; // Gets remote file's build version
|
||||
private static final Object FILE_NAME = "fileName"; // Gets remote file's name
|
||||
private static final String QUERY = "/servermods/files?projectIds="; // Path to GET
|
||||
private static final String HOST = "https://api.curseforge.com"; // Slugs will be appended to this to get to the project's RSS feed
|
||||
|
||||
// private static final String[] NO_UPDATE_TAG = { "-DEV", "-PRE", "-SNAPSHOT" }; // If the version number contains one of these, don't update.
|
||||
private static final int BYTE_SIZE = 1024; // Used for downloading files
|
||||
|
||||
private YamlConfiguration config; // Config file
|
||||
private String updateFolder;// The folder that downloads will be placed in
|
||||
|
||||
/**
|
||||
* Initialize the updater.
|
||||
* <p>
|
||||
* Call {@link #start()} to actually start looking (and downloading) updates.
|
||||
*
|
||||
* @param plugin The plugin that is checking for an update.
|
||||
* @param id The dev.bukkit.org id of the project
|
||||
* @param file The file that the plugin is running from, get this by doing this.getFile() from within your main class.
|
||||
* @param type Specify the type of update this will be. See {@link UpdateType}
|
||||
* @param announce True if the program should announce the progress of new updates in console
|
||||
*/
|
||||
public BukkitUpdater(Plugin plugin, int id, File file, UpdateType type, boolean announce) {
|
||||
super(plugin, type, announce);
|
||||
|
||||
this.file = file;
|
||||
this.id = id;
|
||||
this.updateFolder = plugin.getServer().getUpdateFolder();
|
||||
|
||||
File dataFolder = plugin.getDataFolder();
|
||||
if (dataFolder != null) {
|
||||
final File pluginFile = plugin.getDataFolder().getParentFile();
|
||||
final File updaterFile = new File(pluginFile, "Updater");
|
||||
final File updaterConfigFile = new File(updaterFile, "config.yml");
|
||||
|
||||
if (!updaterFile.exists()) {
|
||||
updaterFile.mkdir();
|
||||
}
|
||||
if (!updaterConfigFile.exists()) {
|
||||
try {
|
||||
updaterConfigFile.createNewFile();
|
||||
} catch (final IOException e) {
|
||||
plugin.getLogger().severe("The updater could not create a configuration in " + updaterFile.getAbsolutePath());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
this.config = YamlConfiguration.loadConfiguration(updaterConfigFile);
|
||||
|
||||
this.config.options().header("This configuration file affects all plugins using the Updater system (version 2+ - http://forums.bukkit.org/threads/96681/ )" + '\n'
|
||||
+ "If you wish to use your API key, read http://wiki.bukkit.org/ServerMods_API and place it below." + '\n'
|
||||
+ "Some updating systems will not adhere to the disabled value, but these may be turned off in their plugin's configuration.");
|
||||
this.config.addDefault("api-key", "PUT_API_KEY_HERE");
|
||||
this.config.addDefault("disable", false);
|
||||
|
||||
if (this.config.get("api-key", null) == null) {
|
||||
this.config.options().copyDefaults(true);
|
||||
try {
|
||||
this.config.save(updaterConfigFile);
|
||||
} catch (final IOException e) {
|
||||
plugin.getLogger().severe("The updater could not save the configuration in " + updaterFile.getAbsolutePath());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
if (this.config.getBoolean("disable")) {
|
||||
this.result = UpdateResult.DISABLED;
|
||||
return;
|
||||
}
|
||||
|
||||
String key = this.config.getString("api-key");
|
||||
if (key.equalsIgnoreCase("PUT_API_KEY_HERE") || key.equals("")) {
|
||||
key = null;
|
||||
}
|
||||
|
||||
this.apiKey = key;
|
||||
}
|
||||
|
||||
try {
|
||||
this.url = new URL(BukkitUpdater.HOST + BukkitUpdater.QUERY + id);
|
||||
} catch (final MalformedURLException e) {
|
||||
plugin.getLogger().severe("The project ID provided for updating, " + id + " is invalid.");
|
||||
this.result = UpdateResult.FAIL_BADID;
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// aadnk - decouple the thread start and the constructor.
|
||||
/**
|
||||
* Begin looking for updates.
|
||||
* @param type - the update type.
|
||||
*/
|
||||
public void start(UpdateType type) {
|
||||
waitForThread();
|
||||
|
||||
this.type = type;
|
||||
this.thread = new Thread(new UpdateRunnable());
|
||||
this.thread.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Save an update from dev.bukkit.org into the server's update folder.
|
||||
*/
|
||||
private void saveFile(File folder, String file, String u) {
|
||||
if (!folder.exists()) {
|
||||
folder.mkdir();
|
||||
}
|
||||
BufferedInputStream in = null;
|
||||
FileOutputStream fout = null;
|
||||
try {
|
||||
// Download the file
|
||||
final URL url = new URL(u);
|
||||
final int fileLength = url.openConnection().getContentLength();
|
||||
in = new BufferedInputStream(url.openStream());
|
||||
fout = new FileOutputStream(folder.getAbsolutePath() + "/" + file);
|
||||
|
||||
final byte[] data = new byte[BukkitUpdater.BYTE_SIZE];
|
||||
int count;
|
||||
if (this.announce) {
|
||||
this.plugin.getLogger().info("About to download a new update: " + this.versionName);
|
||||
}
|
||||
long downloaded = 0;
|
||||
while ((count = in.read(data, 0, BukkitUpdater.BYTE_SIZE)) != -1) {
|
||||
downloaded += count;
|
||||
fout.write(data, 0, count);
|
||||
final int percent = (int) ((downloaded * 100) / fileLength);
|
||||
if (this.announce && ((percent % 10) == 0)) {
|
||||
this.plugin.getLogger().info("Downloading update: " + percent + "% of " + fileLength + " bytes.");
|
||||
}
|
||||
}
|
||||
//Just a quick check to make sure we didn't leave any files from last time...
|
||||
for (final File xFile : new File(this.plugin.getDataFolder().getParent(), this.updateFolder).listFiles()) {
|
||||
if (xFile.getName().endsWith(".zip")) {
|
||||
xFile.delete();
|
||||
}
|
||||
}
|
||||
// Check to see if it's a zip file, if it is, unzip it.
|
||||
final File dFile = new File(folder.getAbsolutePath() + "/" + file);
|
||||
if (dFile.getName().endsWith(".zip")) {
|
||||
// Unzip
|
||||
this.unzip(dFile.getCanonicalPath());
|
||||
}
|
||||
if (this.announce) {
|
||||
this.plugin.getLogger().info("Finished updating.");
|
||||
}
|
||||
} catch (final Exception ex) {
|
||||
this.plugin.getLogger().warning("The auto-updater tried to download a new update, but was unsuccessful.");
|
||||
this.result = BukkitUpdater.UpdateResult.FAIL_DOWNLOAD;
|
||||
} finally {
|
||||
try {
|
||||
if (in != null) {
|
||||
in.close();
|
||||
}
|
||||
if (fout != null) {
|
||||
fout.close();
|
||||
}
|
||||
} catch (final Exception ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Part of Zip-File-Extractor, modified by Gravity for use with Bukkit
|
||||
*/
|
||||
private void unzip(String file) {
|
||||
try {
|
||||
final File fSourceZip = new File(file);
|
||||
final String zipPath = file.substring(0, file.length() - 4);
|
||||
ZipFile zipFile = new ZipFile(fSourceZip);
|
||||
Enumeration<? extends ZipEntry> e = zipFile.entries();
|
||||
while (e.hasMoreElements()) {
|
||||
ZipEntry entry = e.nextElement();
|
||||
File destinationFilePath = new File(zipPath, entry.getName());
|
||||
destinationFilePath.getParentFile().mkdirs();
|
||||
if (entry.isDirectory()) {
|
||||
continue;
|
||||
} else {
|
||||
final BufferedInputStream bis = new BufferedInputStream(zipFile.getInputStream(entry));
|
||||
int b;
|
||||
final byte buffer[] = new byte[BukkitUpdater.BYTE_SIZE];
|
||||
final FileOutputStream fos = new FileOutputStream(destinationFilePath);
|
||||
final BufferedOutputStream bos = new BufferedOutputStream(fos, BukkitUpdater.BYTE_SIZE);
|
||||
while ((b = bis.read(buffer, 0, BukkitUpdater.BYTE_SIZE)) != -1) {
|
||||
bos.write(buffer, 0, b);
|
||||
}
|
||||
bos.flush();
|
||||
bos.close();
|
||||
bis.close();
|
||||
final String name = destinationFilePath.getName();
|
||||
if (name.endsWith(".jar") && this.pluginFile(name)) {
|
||||
destinationFilePath.renameTo(new File(this.plugin.getDataFolder().getParent(), this.updateFolder + "/" + name));
|
||||
}
|
||||
}
|
||||
entry = null;
|
||||
destinationFilePath = null;
|
||||
}
|
||||
e = null;
|
||||
zipFile.close();
|
||||
zipFile = null;
|
||||
|
||||
// Move any plugin data folders that were included to the right place, Bukkit won't do this for us.
|
||||
for (final File dFile : new File(zipPath).listFiles()) {
|
||||
if (dFile.isDirectory()) {
|
||||
if (this.pluginFile(dFile.getName())) {
|
||||
final File oFile = new File(this.plugin.getDataFolder().getParent(), dFile.getName()); // Get current dir
|
||||
final File[] contents = oFile.listFiles(); // List of existing files in the current dir
|
||||
for (final File cFile : dFile.listFiles()) // Loop through all the files in the new dir
|
||||
{
|
||||
boolean found = false;
|
||||
for (final File xFile : contents) // Loop through contents to see if it exists
|
||||
{
|
||||
if (xFile.getName().equals(cFile.getName())) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
// Move the new file into the current dir
|
||||
cFile.renameTo(new File(oFile.getCanonicalFile() + "/" + cFile.getName()));
|
||||
} else {
|
||||
// This file already exists, so we don't need it anymore.
|
||||
cFile.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
dFile.delete();
|
||||
}
|
||||
new File(zipPath).delete();
|
||||
fSourceZip.delete();
|
||||
} catch (final IOException ex) {
|
||||
this.plugin.getLogger().warning("The auto-updater tried to unzip a new update file, but was unsuccessful.");
|
||||
this.result = BukkitUpdater.UpdateResult.FAIL_DOWNLOAD;
|
||||
ex.printStackTrace();
|
||||
}
|
||||
new File(file).delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the name of a jar is one of the plugins currently installed, used for extracting the correct files out of a zip.
|
||||
*/
|
||||
private boolean pluginFile(String name) {
|
||||
for (final File file : new File("plugins").listFiles()) {
|
||||
if (file.getName().equals(name)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate whether the version number is marked showing that it should not be updated by this program
|
||||
*/
|
||||
/* private boolean hasTag(String version) {
|
||||
for (final String string : BukkitUpdater.NO_UPDATE_TAG) {
|
||||
if (version.contains(string)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} */
|
||||
|
||||
public boolean read() {
|
||||
try {
|
||||
final URLConnection conn = this.url.openConnection();
|
||||
conn.setConnectTimeout(5000);
|
||||
|
||||
if (this.apiKey != null) {
|
||||
conn.addRequestProperty("X-API-Key", this.apiKey);
|
||||
}
|
||||
conn.addRequestProperty("User-Agent", "Updater (by Gravity)");
|
||||
conn.setDoOutput(true);
|
||||
|
||||
final BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
|
||||
final String response = reader.readLine();
|
||||
|
||||
final JSONArray array = (JSONArray) JSONValue.parse(response);
|
||||
|
||||
if (array.size() == 0) {
|
||||
this.plugin.getLogger().warning("The updater could not find any files for the project id " + this.id);
|
||||
this.result = UpdateResult.FAIL_BADID;
|
||||
return false;
|
||||
}
|
||||
|
||||
final JSONObject jsonObject = (JSONObject) array.get(array.size() - 1);
|
||||
this.versionFileName = (String) jsonObject.get(BukkitUpdater.FILE_NAME);
|
||||
this.versionName = (String) jsonObject.get(BukkitUpdater.TITLE_VALUE);
|
||||
this.versionLink = (String) jsonObject.get(BukkitUpdater.LINK_VALUE);
|
||||
this.versionType = (String) jsonObject.get(BukkitUpdater.TYPE_VALUE);
|
||||
this.versionGameVersion = (String) jsonObject.get(BukkitUpdater.VERSION_VALUE);
|
||||
|
||||
return true;
|
||||
} catch (final IOException e) {
|
||||
if (e.getMessage().contains("HTTP response code: 403")) {
|
||||
this.plugin.getLogger().warning("dev.bukkit.org rejected the API key provided in plugins/Updater/config.yml");
|
||||
this.plugin.getLogger().warning("Please double-check your configuration to ensure it is correct.");
|
||||
this.result = UpdateResult.FAIL_APIKEY;
|
||||
} else {
|
||||
this.plugin.getLogger().warning("The updater could not contact dev.bukkit.org for updating.");
|
||||
this.plugin.getLogger().warning("If you have not recently modified your configuration and this is the first time you are seeing this message, the site may be experiencing temporary downtime.");
|
||||
this.result = UpdateResult.FAIL_DBO;
|
||||
}
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// aadnk - added listeners
|
||||
private class UpdateRunnable implements Runnable {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
if (BukkitUpdater.this.url != null) {
|
||||
// Obtain the results of the project's file feed
|
||||
if (BukkitUpdater.this.read()) {
|
||||
if (BukkitUpdater.this.versionCheck(BukkitUpdater.this.versionName)) {
|
||||
performUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// Any generic error will be handled here
|
||||
ProtocolLibrary.getErrorReporter().reportDetailed(
|
||||
BukkitUpdater.this, Report.newBuilder(REPORT_CANNOT_UPDATE_PLUGIN).error(e).callerParam(this));
|
||||
|
||||
} finally {
|
||||
// Invoke the listeners on the main thread
|
||||
for (Runnable listener : listeners) {
|
||||
plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, listener);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void performUpdate() {
|
||||
if ((BukkitUpdater.this.versionLink != null) && (BukkitUpdater.this.type != UpdateType.NO_DOWNLOAD)) {
|
||||
final File pluginFolder = plugin.getDataFolder().getParentFile();
|
||||
File destinationFolder = new File(pluginFolder, updateFolder);
|
||||
String name = BukkitUpdater.this.file.getName();
|
||||
|
||||
// If it's a zip file, it shouldn't be downloaded as the plugin's name
|
||||
if (BukkitUpdater.this.versionLink.endsWith(".zip")) {
|
||||
name = versionFileName;
|
||||
}
|
||||
BukkitUpdater.this.saveFile(
|
||||
destinationFolder,
|
||||
name,
|
||||
BukkitUpdater.this.versionLink
|
||||
);
|
||||
} else {
|
||||
BukkitUpdater.this.result = UpdateResult.UPDATE_AVAILABLE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRemoteVersion() {
|
||||
return getLatestName();
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Updater for Bukkit.
|
||||
*
|
||||
* This class provides the means to safely and easily update a plugin, or check to see if it is updated using dev.bukkit.org
|
||||
*/
|
||||
|
||||
// Somewhat modified by aadnk.
|
||||
package com.comphenix.protocol.updater;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.util.Enumeration;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.json.simple.JSONValue;
|
||||
|
||||
import com.comphenix.protocol.ProtocolLibrary;
|
||||
import com.comphenix.protocol.error.Report;
|
||||
|
||||
/**
|
||||
* Check dev.bukkit.org to find updates for a given plugin, and download the updates if needed.
|
||||
* <p/>
|
||||
* <b>VERY, VERY IMPORTANT</b>: Because there are no standards for adding auto-update toggles in your plugin's config, this system provides NO CHECK WITH YOUR CONFIG to make sure the user has allowed auto-updating.
|
||||
* <br>
|
||||
* It is a <b>BUKKIT POLICY</b> that you include a boolean value in your config that prevents the auto-updater from running <b>AT ALL</b>.
|
||||
* <br>
|
||||
* If you fail to include this option in your config, your plugin will be <b>REJECTED</b> when you attempt to submit it to dev.bukkit.org.
|
||||
* <p/>
|
||||
* An example of a good configuration option would be something similar to 'auto-update: true' - if this value is set to false you may NOT run the auto-updater.
|
||||
* <br>
|
||||
* If you are unsure about these rules, please read the plugin submission guidelines: http://goo.gl/8iU5l
|
||||
*
|
||||
* @author Gravity
|
||||
* @version 2.0
|
||||
*/
|
||||
|
||||
public class BukkitUpdater extends Updater {
|
||||
private URL url; // Connecting to RSS
|
||||
private File file; // The plugin's file
|
||||
private Thread thread; // Updater thread
|
||||
|
||||
private int id = -1; // Project's Curse ID
|
||||
private String apiKey = null; // BukkitDev ServerMods API key
|
||||
private static final String TITLE_VALUE = "name"; // Gets remote file's title
|
||||
private static final String LINK_VALUE = "downloadUrl"; // Gets remote file's download link
|
||||
private static final String TYPE_VALUE = "releaseType"; // Gets remote file's release type
|
||||
private static final String VERSION_VALUE = "gameVersion"; // Gets remote file's build version
|
||||
private static final Object FILE_NAME = "fileName"; // Gets remote file's name
|
||||
private static final String QUERY = "/servermods/files?projectIds="; // Path to GET
|
||||
private static final String HOST = "https://api.curseforge.com"; // Slugs will be appended to this to get to the project's RSS feed
|
||||
|
||||
// private static final String[] NO_UPDATE_TAG = { "-DEV", "-PRE", "-SNAPSHOT" }; // If the version number contains one of these, don't update.
|
||||
private static final int BYTE_SIZE = 1024; // Used for downloading files
|
||||
|
||||
private YamlConfiguration config; // Config file
|
||||
private String updateFolder;// The folder that downloads will be placed in
|
||||
|
||||
/**
|
||||
* Initialize the updater.
|
||||
* <p>
|
||||
* Call {@link #start()} to actually start looking (and downloading) updates.
|
||||
*
|
||||
* @param plugin The plugin that is checking for an update.
|
||||
* @param id The dev.bukkit.org id of the project
|
||||
* @param file The file that the plugin is running from, get this by doing this.getFile() from within your main class.
|
||||
* @param type Specify the type of update this will be. See {@link UpdateType}
|
||||
* @param announce True if the program should announce the progress of new updates in console
|
||||
*/
|
||||
public BukkitUpdater(Plugin plugin, int id, File file, UpdateType type, boolean announce) {
|
||||
super(plugin, type, announce);
|
||||
|
||||
this.file = file;
|
||||
this.id = id;
|
||||
this.updateFolder = plugin.getServer().getUpdateFolder();
|
||||
|
||||
File dataFolder = plugin.getDataFolder();
|
||||
if (dataFolder != null) {
|
||||
final File pluginFile = plugin.getDataFolder().getParentFile();
|
||||
final File updaterFile = new File(pluginFile, "Updater");
|
||||
final File updaterConfigFile = new File(updaterFile, "config.yml");
|
||||
|
||||
if (!updaterFile.exists()) {
|
||||
updaterFile.mkdir();
|
||||
}
|
||||
if (!updaterConfigFile.exists()) {
|
||||
try {
|
||||
updaterConfigFile.createNewFile();
|
||||
} catch (final IOException e) {
|
||||
plugin.getLogger().severe("The updater could not create a configuration in " + updaterFile.getAbsolutePath());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
this.config = YamlConfiguration.loadConfiguration(updaterConfigFile);
|
||||
|
||||
this.config.options().header("This configuration file affects all plugins using the Updater system (version 2+ - http://forums.bukkit.org/threads/96681/ )" + '\n'
|
||||
+ "If you wish to use your API key, read http://wiki.bukkit.org/ServerMods_API and place it below." + '\n'
|
||||
+ "Some updating systems will not adhere to the disabled value, but these may be turned off in their plugin's configuration.");
|
||||
this.config.addDefault("api-key", "PUT_API_KEY_HERE");
|
||||
this.config.addDefault("disable", false);
|
||||
|
||||
if (this.config.get("api-key", null) == null) {
|
||||
this.config.options().copyDefaults(true);
|
||||
try {
|
||||
this.config.save(updaterConfigFile);
|
||||
} catch (final IOException e) {
|
||||
plugin.getLogger().severe("The updater could not save the configuration in " + updaterFile.getAbsolutePath());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
if (this.config.getBoolean("disable")) {
|
||||
this.result = UpdateResult.DISABLED;
|
||||
return;
|
||||
}
|
||||
|
||||
String key = this.config.getString("api-key");
|
||||
if (key.equalsIgnoreCase("PUT_API_KEY_HERE") || key.equals("")) {
|
||||
key = null;
|
||||
}
|
||||
|
||||
this.apiKey = key;
|
||||
}
|
||||
|
||||
try {
|
||||
this.url = new URL(BukkitUpdater.HOST + BukkitUpdater.QUERY + id);
|
||||
} catch (final MalformedURLException e) {
|
||||
plugin.getLogger().severe("The project ID provided for updating, " + id + " is invalid.");
|
||||
this.result = UpdateResult.FAIL_BADID;
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// aadnk - decouple the thread start and the constructor.
|
||||
/**
|
||||
* Begin looking for updates.
|
||||
* @param type - the update type.
|
||||
*/
|
||||
public void start(UpdateType type) {
|
||||
waitForThread();
|
||||
|
||||
this.type = type;
|
||||
this.thread = new Thread(new UpdateRunnable());
|
||||
this.thread.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Save an update from dev.bukkit.org into the server's update folder.
|
||||
*/
|
||||
private void saveFile(File folder, String file, String u) {
|
||||
if (!folder.exists()) {
|
||||
folder.mkdir();
|
||||
}
|
||||
BufferedInputStream in = null;
|
||||
FileOutputStream fout = null;
|
||||
try {
|
||||
// Download the file
|
||||
final URL url = new URL(u);
|
||||
final int fileLength = url.openConnection().getContentLength();
|
||||
in = new BufferedInputStream(url.openStream());
|
||||
fout = new FileOutputStream(folder.getAbsolutePath() + "/" + file);
|
||||
|
||||
final byte[] data = new byte[BukkitUpdater.BYTE_SIZE];
|
||||
int count;
|
||||
if (this.announce) {
|
||||
this.plugin.getLogger().info("About to download a new update: " + this.versionName);
|
||||
}
|
||||
long downloaded = 0;
|
||||
while ((count = in.read(data, 0, BukkitUpdater.BYTE_SIZE)) != -1) {
|
||||
downloaded += count;
|
||||
fout.write(data, 0, count);
|
||||
final int percent = (int) ((downloaded * 100) / fileLength);
|
||||
if (this.announce && ((percent % 10) == 0)) {
|
||||
this.plugin.getLogger().info("Downloading update: " + percent + "% of " + fileLength + " bytes.");
|
||||
}
|
||||
}
|
||||
//Just a quick check to make sure we didn't leave any files from last time...
|
||||
for (final File xFile : new File(this.plugin.getDataFolder().getParent(), this.updateFolder).listFiles()) {
|
||||
if (xFile.getName().endsWith(".zip")) {
|
||||
xFile.delete();
|
||||
}
|
||||
}
|
||||
// Check to see if it's a zip file, if it is, unzip it.
|
||||
final File dFile = new File(folder.getAbsolutePath() + "/" + file);
|
||||
if (dFile.getName().endsWith(".zip")) {
|
||||
// Unzip
|
||||
this.unzip(dFile.getCanonicalPath());
|
||||
}
|
||||
if (this.announce) {
|
||||
this.plugin.getLogger().info("Finished updating.");
|
||||
}
|
||||
} catch (final Exception ex) {
|
||||
this.plugin.getLogger().warning("The auto-updater tried to download a new update, but was unsuccessful.");
|
||||
this.result = BukkitUpdater.UpdateResult.FAIL_DOWNLOAD;
|
||||
} finally {
|
||||
try {
|
||||
if (in != null) {
|
||||
in.close();
|
||||
}
|
||||
if (fout != null) {
|
||||
fout.close();
|
||||
}
|
||||
} catch (final Exception ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Part of Zip-File-Extractor, modified by Gravity for use with Bukkit
|
||||
*/
|
||||
private void unzip(String file) {
|
||||
try {
|
||||
final File fSourceZip = new File(file);
|
||||
final String zipPath = file.substring(0, file.length() - 4);
|
||||
ZipFile zipFile = new ZipFile(fSourceZip);
|
||||
Enumeration<? extends ZipEntry> e = zipFile.entries();
|
||||
while (e.hasMoreElements()) {
|
||||
ZipEntry entry = e.nextElement();
|
||||
File destinationFilePath = new File(zipPath, entry.getName());
|
||||
destinationFilePath.getParentFile().mkdirs();
|
||||
if (entry.isDirectory()) {
|
||||
continue;
|
||||
} else {
|
||||
final BufferedInputStream bis = new BufferedInputStream(zipFile.getInputStream(entry));
|
||||
int b;
|
||||
final byte buffer[] = new byte[BukkitUpdater.BYTE_SIZE];
|
||||
final FileOutputStream fos = new FileOutputStream(destinationFilePath);
|
||||
final BufferedOutputStream bos = new BufferedOutputStream(fos, BukkitUpdater.BYTE_SIZE);
|
||||
while ((b = bis.read(buffer, 0, BukkitUpdater.BYTE_SIZE)) != -1) {
|
||||
bos.write(buffer, 0, b);
|
||||
}
|
||||
bos.flush();
|
||||
bos.close();
|
||||
bis.close();
|
||||
final String name = destinationFilePath.getName();
|
||||
if (name.endsWith(".jar") && this.pluginFile(name)) {
|
||||
destinationFilePath.renameTo(new File(this.plugin.getDataFolder().getParent(), this.updateFolder + "/" + name));
|
||||
}
|
||||
}
|
||||
entry = null;
|
||||
destinationFilePath = null;
|
||||
}
|
||||
e = null;
|
||||
zipFile.close();
|
||||
zipFile = null;
|
||||
|
||||
// Move any plugin data folders that were included to the right place, Bukkit won't do this for us.
|
||||
for (final File dFile : new File(zipPath).listFiles()) {
|
||||
if (dFile.isDirectory()) {
|
||||
if (this.pluginFile(dFile.getName())) {
|
||||
final File oFile = new File(this.plugin.getDataFolder().getParent(), dFile.getName()); // Get current dir
|
||||
final File[] contents = oFile.listFiles(); // List of existing files in the current dir
|
||||
for (final File cFile : dFile.listFiles()) // Loop through all the files in the new dir
|
||||
{
|
||||
boolean found = false;
|
||||
for (final File xFile : contents) // Loop through contents to see if it exists
|
||||
{
|
||||
if (xFile.getName().equals(cFile.getName())) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
// Move the new file into the current dir
|
||||
cFile.renameTo(new File(oFile.getCanonicalFile() + "/" + cFile.getName()));
|
||||
} else {
|
||||
// This file already exists, so we don't need it anymore.
|
||||
cFile.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
dFile.delete();
|
||||
}
|
||||
new File(zipPath).delete();
|
||||
fSourceZip.delete();
|
||||
} catch (final IOException ex) {
|
||||
this.plugin.getLogger().warning("The auto-updater tried to unzip a new update file, but was unsuccessful.");
|
||||
this.result = BukkitUpdater.UpdateResult.FAIL_DOWNLOAD;
|
||||
ex.printStackTrace();
|
||||
}
|
||||
new File(file).delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the name of a jar is one of the plugins currently installed, used for extracting the correct files out of a zip.
|
||||
*/
|
||||
private boolean pluginFile(String name) {
|
||||
for (final File file : new File("plugins").listFiles()) {
|
||||
if (file.getName().equals(name)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate whether the version number is marked showing that it should not be updated by this program
|
||||
*/
|
||||
/* private boolean hasTag(String version) {
|
||||
for (final String string : BukkitUpdater.NO_UPDATE_TAG) {
|
||||
if (version.contains(string)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} */
|
||||
|
||||
public boolean read() {
|
||||
try {
|
||||
final URLConnection conn = this.url.openConnection();
|
||||
conn.setConnectTimeout(5000);
|
||||
|
||||
if (this.apiKey != null) {
|
||||
conn.addRequestProperty("X-API-Key", this.apiKey);
|
||||
}
|
||||
conn.addRequestProperty("User-Agent", "Updater (by Gravity)");
|
||||
conn.setDoOutput(true);
|
||||
|
||||
final BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
|
||||
final String response = reader.readLine();
|
||||
|
||||
final JSONArray array = (JSONArray) JSONValue.parse(response);
|
||||
|
||||
if (array.size() == 0) {
|
||||
this.plugin.getLogger().warning("The updater could not find any files for the project id " + this.id);
|
||||
this.result = UpdateResult.FAIL_BADID;
|
||||
return false;
|
||||
}
|
||||
|
||||
final JSONObject jsonObject = (JSONObject) array.get(array.size() - 1);
|
||||
this.versionFileName = (String) jsonObject.get(BukkitUpdater.FILE_NAME);
|
||||
this.versionName = (String) jsonObject.get(BukkitUpdater.TITLE_VALUE);
|
||||
this.versionLink = (String) jsonObject.get(BukkitUpdater.LINK_VALUE);
|
||||
this.versionType = (String) jsonObject.get(BukkitUpdater.TYPE_VALUE);
|
||||
this.versionGameVersion = (String) jsonObject.get(BukkitUpdater.VERSION_VALUE);
|
||||
|
||||
return true;
|
||||
} catch (final IOException e) {
|
||||
if (e.getMessage().contains("HTTP response code: 403")) {
|
||||
this.plugin.getLogger().warning("dev.bukkit.org rejected the API key provided in plugins/Updater/config.yml");
|
||||
this.plugin.getLogger().warning("Please double-check your configuration to ensure it is correct.");
|
||||
this.result = UpdateResult.FAIL_APIKEY;
|
||||
} else {
|
||||
this.plugin.getLogger().warning("The updater could not contact dev.bukkit.org for updating.");
|
||||
this.plugin.getLogger().warning("If you have not recently modified your configuration and this is the first time you are seeing this message, the site may be experiencing temporary downtime.");
|
||||
this.result = UpdateResult.FAIL_DBO;
|
||||
}
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// aadnk - added listeners
|
||||
private class UpdateRunnable implements Runnable {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
if (BukkitUpdater.this.url != null) {
|
||||
// Obtain the results of the project's file feed
|
||||
if (BukkitUpdater.this.read()) {
|
||||
if (BukkitUpdater.this.versionCheck(BukkitUpdater.this.versionName)) {
|
||||
performUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// Any generic error will be handled here
|
||||
ProtocolLibrary.getErrorReporter().reportDetailed(
|
||||
BukkitUpdater.this, Report.newBuilder(REPORT_CANNOT_UPDATE_PLUGIN).error(e).callerParam(this));
|
||||
|
||||
} finally {
|
||||
// Invoke the listeners on the main thread
|
||||
for (Runnable listener : listeners) {
|
||||
plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, listener);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void performUpdate() {
|
||||
if ((BukkitUpdater.this.versionLink != null) && (BukkitUpdater.this.type != UpdateType.NO_DOWNLOAD)) {
|
||||
final File pluginFolder = plugin.getDataFolder().getParentFile();
|
||||
File destinationFolder = new File(pluginFolder, updateFolder);
|
||||
String name = BukkitUpdater.this.file.getName();
|
||||
|
||||
// If it's a zip file, it shouldn't be downloaded as the plugin's name
|
||||
if (BukkitUpdater.this.versionLink.endsWith(".zip")) {
|
||||
name = versionFileName;
|
||||
}
|
||||
BukkitUpdater.this.saveFile(
|
||||
destinationFolder,
|
||||
name,
|
||||
BukkitUpdater.this.versionLink
|
||||
);
|
||||
} else {
|
||||
BukkitUpdater.this.result = UpdateResult.UPDATE_AVAILABLE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRemoteVersion() {
|
||||
return getLatestName();
|
||||
}
|
||||
}
|
||||
|
@ -1,120 +1,120 @@
|
||||
/**
|
||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||
* Copyright (C) 2015 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.updater;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import com.comphenix.protocol.ProtocolLibrary;
|
||||
import com.comphenix.protocol.error.Report;
|
||||
import com.comphenix.protocol.utility.Closer;
|
||||
import com.google.common.base.Charsets;
|
||||
|
||||
/**
|
||||
* Adapted version of the Bukkit updater for use with Spigot resources
|
||||
* @author dmulloy2
|
||||
*/
|
||||
|
||||
public final class SpigotUpdater extends Updater {
|
||||
private String remoteVersion;
|
||||
|
||||
public SpigotUpdater(Plugin plugin, UpdateType type, boolean announce) {
|
||||
super(plugin, type, announce);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(UpdateType type) {
|
||||
waitForThread();
|
||||
|
||||
this.type = type;
|
||||
this.thread = new Thread(new SpigotUpdateRunnable());
|
||||
this.thread.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getResult() {
|
||||
waitForThread();
|
||||
return String.format(result.toString(), remoteVersion, plugin.getDescription().getVersion(), RESOURCE_URL);
|
||||
}
|
||||
|
||||
private class SpigotUpdateRunnable implements Runnable {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
String version = getSpigotVersion();
|
||||
remoteVersion = version;
|
||||
|
||||
if (versionCheck(version)) {
|
||||
result = UpdateResult.SPIGOT_UPDATE_AVAILABLE;
|
||||
} else {
|
||||
result = UpdateResult.NO_UPDATE;
|
||||
}
|
||||
} catch (Throwable ex) {
|
||||
if (ProtocolLibrary.getConfig().isDebug()) {
|
||||
ProtocolLibrary.getErrorReporter().reportDetailed(
|
||||
SpigotUpdater.this, Report.newBuilder(REPORT_CANNOT_UPDATE_PLUGIN).error(ex).callerParam(this));
|
||||
} else {
|
||||
plugin.getLogger().log(Level.WARNING, "Failed to check for updates: " + ex);
|
||||
}
|
||||
|
||||
ProtocolLibrary.disableUpdates();
|
||||
} finally {
|
||||
// Invoke the listeners on the main thread
|
||||
for (Runnable listener : listeners) {
|
||||
plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, listener);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final String PROTOCOL = "https://";
|
||||
private static final String RESOURCE_URL = PROTOCOL + "www.spigotmc.org/resources/protocollib.1997/";
|
||||
private static final String API_URL = PROTOCOL + "www.spigotmc.org/api/general.php";
|
||||
private static final String ACTION = "POST";
|
||||
|
||||
private static final int ID = 1997;
|
||||
private static final byte[] API_KEY = ("key=98BE0FE67F88AB82B4C197FAF1DC3B69206EFDCC4D3B80FC83A00037510B99B4&resource=" + ID).getBytes(Charsets.UTF_8);
|
||||
|
||||
public String getSpigotVersion() throws IOException {
|
||||
Closer closer = Closer.create();
|
||||
|
||||
try {
|
||||
HttpURLConnection con = (HttpURLConnection) new URL(API_URL).openConnection();
|
||||
con.setDoOutput(true);
|
||||
con.setRequestMethod(ACTION);
|
||||
con.getOutputStream().write(API_KEY);
|
||||
|
||||
InputStreamReader isr = closer.register(new InputStreamReader(con.getInputStream()));
|
||||
BufferedReader br = closer.register(new BufferedReader(isr));
|
||||
return br.readLine();
|
||||
} finally {
|
||||
closer.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRemoteVersion() {
|
||||
return remoteVersion;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||
* Copyright (C) 2015 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.updater;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import com.comphenix.protocol.ProtocolLibrary;
|
||||
import com.comphenix.protocol.error.Report;
|
||||
import com.comphenix.protocol.utility.Closer;
|
||||
import com.google.common.base.Charsets;
|
||||
|
||||
/**
|
||||
* Adapted version of the Bukkit updater for use with Spigot resources
|
||||
* @author dmulloy2
|
||||
*/
|
||||
|
||||
public final class SpigotUpdater extends Updater {
|
||||
private String remoteVersion;
|
||||
|
||||
public SpigotUpdater(Plugin plugin, UpdateType type, boolean announce) {
|
||||
super(plugin, type, announce);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(UpdateType type) {
|
||||
waitForThread();
|
||||
|
||||
this.type = type;
|
||||
this.thread = new Thread(new SpigotUpdateRunnable());
|
||||
this.thread.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getResult() {
|
||||
waitForThread();
|
||||
return String.format(result.toString(), remoteVersion, plugin.getDescription().getVersion(), RESOURCE_URL);
|
||||
}
|
||||
|
||||
private class SpigotUpdateRunnable implements Runnable {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
String version = getSpigotVersion();
|
||||
remoteVersion = version;
|
||||
|
||||
if (versionCheck(version)) {
|
||||
result = UpdateResult.SPIGOT_UPDATE_AVAILABLE;
|
||||
} else {
|
||||
result = UpdateResult.NO_UPDATE;
|
||||
}
|
||||
} catch (Throwable ex) {
|
||||
if (ProtocolLibrary.getConfig().isDebug()) {
|
||||
ProtocolLibrary.getErrorReporter().reportDetailed(
|
||||
SpigotUpdater.this, Report.newBuilder(REPORT_CANNOT_UPDATE_PLUGIN).error(ex).callerParam(this));
|
||||
} else {
|
||||
plugin.getLogger().log(Level.WARNING, "Failed to check for updates: " + ex);
|
||||
}
|
||||
|
||||
ProtocolLibrary.disableUpdates();
|
||||
} finally {
|
||||
// Invoke the listeners on the main thread
|
||||
for (Runnable listener : listeners) {
|
||||
plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, listener);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final String PROTOCOL = "https://";
|
||||
private static final String RESOURCE_URL = PROTOCOL + "www.spigotmc.org/resources/protocollib.1997/";
|
||||
private static final String API_URL = PROTOCOL + "www.spigotmc.org/api/general.php";
|
||||
private static final String ACTION = "POST";
|
||||
|
||||
private static final int ID = 1997;
|
||||
private static final byte[] API_KEY = ("key=98BE0FE67F88AB82B4C197FAF1DC3B69206EFDCC4D3B80FC83A00037510B99B4&resource=" + ID).getBytes(Charsets.UTF_8);
|
||||
|
||||
public String getSpigotVersion() throws IOException {
|
||||
Closer closer = Closer.create();
|
||||
|
||||
try {
|
||||
HttpURLConnection con = (HttpURLConnection) new URL(API_URL).openConnection();
|
||||
con.setDoOutput(true);
|
||||
con.setRequestMethod(ACTION);
|
||||
con.getOutputStream().write(API_KEY);
|
||||
|
||||
InputStreamReader isr = closer.register(new InputStreamReader(con.getInputStream()));
|
||||
BufferedReader br = closer.register(new BufferedReader(isr));
|
||||
return br.readLine();
|
||||
} finally {
|
||||
closer.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRemoteVersion() {
|
||||
return remoteVersion;
|
||||
}
|
||||
}
|
||||
|
@ -217,4 +217,4 @@ public class SimpleMinecraftClient {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -53,4 +53,4 @@ public class PacketTypeTest {
|
||||
|
||||
assertFalse("There are packets that aren\'t accounted for!", missing);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -65,4 +65,4 @@ public class UpdaterTest {
|
||||
System.out.println("Determined remote Bukkit Dev version: " + remote);
|
||||
System.out.println("Update available: " + updater.versionCheck(remote));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -143,4 +143,4 @@ public class MinecraftReflectionTest {
|
||||
public void testGameProfile() {
|
||||
assertEquals(GameProfile.class, MinecraftReflection.getGameProfileClass());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -97,4 +97,4 @@ public class StreamSerializerTest {
|
||||
|
||||
assertEquals(initial, deserialized);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,70 +1,70 @@
|
||||
/**
|
||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||
* Copyright (C) 2015 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.wrappers;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.powermock.core.classloader.annotations.PowerMockIgnore;
|
||||
|
||||
import com.comphenix.protocol.BukkitInitialization;
|
||||
import com.comphenix.protocol.reflect.EquivalentConverter;
|
||||
import com.comphenix.protocol.utility.MinecraftReflection;
|
||||
|
||||
/**
|
||||
* @author dmulloy2
|
||||
*/
|
||||
@RunWith(org.powermock.modules.junit4.PowerMockRunner.class)
|
||||
@PowerMockIgnore({ "org.apache.log4j.*", "org.apache.logging.*", "org.bukkit.craftbukkit.libs.jline.*" })
|
||||
public class MultiBlockChangeTest {
|
||||
|
||||
@BeforeClass
|
||||
public static void initializeBukkit() throws IllegalAccessException {
|
||||
BukkitInitialization.initializeItemMeta();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
int x = 42;
|
||||
int y = 64;
|
||||
int z = 70;
|
||||
|
||||
Location loc = new Location(null, x, y, z);
|
||||
ChunkCoordIntPair chunk = new ChunkCoordIntPair(x >> 4, z >> 4);
|
||||
WrappedBlockData blockData = WrappedBlockData.createData(Material.STONE);
|
||||
MultiBlockChangeInfo info = new MultiBlockChangeInfo(loc, blockData);
|
||||
|
||||
// Make sure the location is correct
|
||||
assertEquals(loc, info.getLocation(null));
|
||||
|
||||
MultiBlockChangeInfo[] array = { info, info };
|
||||
|
||||
EquivalentConverter<MultiBlockChangeInfo[]> converter = MultiBlockChangeInfo.getArrayConverter(chunk);
|
||||
Object generic = converter.getGeneric(MinecraftReflection.getMultiBlockChangeInfoArrayClass(), array);
|
||||
MultiBlockChangeInfo[] back = converter.getSpecific(generic);
|
||||
|
||||
// Make sure our conversions are correct
|
||||
assertEquals(info.getX(), back[0].getX());
|
||||
assertEquals(info.getY(), back[0].getY());
|
||||
assertEquals(info.getZ(), back[0].getZ());
|
||||
assertEquals(info.getData(), back[0].getData());
|
||||
}
|
||||
}
|
||||
/**
|
||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||
* Copyright (C) 2015 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.wrappers;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.powermock.core.classloader.annotations.PowerMockIgnore;
|
||||
|
||||
import com.comphenix.protocol.BukkitInitialization;
|
||||
import com.comphenix.protocol.reflect.EquivalentConverter;
|
||||
import com.comphenix.protocol.utility.MinecraftReflection;
|
||||
|
||||
/**
|
||||
* @author dmulloy2
|
||||
*/
|
||||
@RunWith(org.powermock.modules.junit4.PowerMockRunner.class)
|
||||
@PowerMockIgnore({ "org.apache.log4j.*", "org.apache.logging.*", "org.bukkit.craftbukkit.libs.jline.*" })
|
||||
public class MultiBlockChangeTest {
|
||||
|
||||
@BeforeClass
|
||||
public static void initializeBukkit() throws IllegalAccessException {
|
||||
BukkitInitialization.initializeItemMeta();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
int x = 42;
|
||||
int y = 64;
|
||||
int z = 70;
|
||||
|
||||
Location loc = new Location(null, x, y, z);
|
||||
ChunkCoordIntPair chunk = new ChunkCoordIntPair(x >> 4, z >> 4);
|
||||
WrappedBlockData blockData = WrappedBlockData.createData(Material.STONE);
|
||||
MultiBlockChangeInfo info = new MultiBlockChangeInfo(loc, blockData);
|
||||
|
||||
// Make sure the location is correct
|
||||
assertEquals(loc, info.getLocation(null));
|
||||
|
||||
MultiBlockChangeInfo[] array = { info, info };
|
||||
|
||||
EquivalentConverter<MultiBlockChangeInfo[]> converter = MultiBlockChangeInfo.getArrayConverter(chunk);
|
||||
Object generic = converter.getGeneric(MinecraftReflection.getMultiBlockChangeInfoArrayClass(), array);
|
||||
MultiBlockChangeInfo[] back = converter.getSpecific(generic);
|
||||
|
||||
// Make sure our conversions are correct
|
||||
assertEquals(info.getX(), back[0].getX());
|
||||
assertEquals(info.getY(), back[0].getY());
|
||||
assertEquals(info.getZ(), back[0].getZ());
|
||||
assertEquals(info.getData(), back[0].getData());
|
||||
}
|
||||
}
|
||||
|
@ -1,51 +1,51 @@
|
||||
/**
|
||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||
* Copyright (C) 2015 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.wrappers;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.comphenix.protocol.BukkitInitialization;
|
||||
import com.comphenix.protocol.utility.MinecraftReflection;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers.NativeGameMode;
|
||||
|
||||
/**
|
||||
* @author dmulloy2
|
||||
*/
|
||||
public class PlayerInfoDataTest {
|
||||
|
||||
@BeforeClass
|
||||
public static void initializeBukkit() {
|
||||
BukkitInitialization.initializePackage();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
WrappedGameProfile profile = new WrappedGameProfile(UUID.randomUUID(), "Name");
|
||||
WrappedChatComponent displayName = WrappedChatComponent.fromText("Name's Name");
|
||||
|
||||
PlayerInfoData data = new PlayerInfoData(profile, 42, NativeGameMode.CREATIVE, displayName);
|
||||
Object generic = PlayerInfoData.getConverter().getGeneric(MinecraftReflection.getPlayerInfoDataClass(), data);
|
||||
PlayerInfoData back = PlayerInfoData.getConverter().getSpecific(generic);
|
||||
|
||||
assertEquals(data, back);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||
* Copyright (C) 2015 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.wrappers;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.comphenix.protocol.BukkitInitialization;
|
||||
import com.comphenix.protocol.utility.MinecraftReflection;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers.NativeGameMode;
|
||||
|
||||
/**
|
||||
* @author dmulloy2
|
||||
*/
|
||||
public class PlayerInfoDataTest {
|
||||
|
||||
@BeforeClass
|
||||
public static void initializeBukkit() {
|
||||
BukkitInitialization.initializePackage();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
WrappedGameProfile profile = new WrappedGameProfile(UUID.randomUUID(), "Name");
|
||||
WrappedChatComponent displayName = WrappedChatComponent.fromText("Name's Name");
|
||||
|
||||
PlayerInfoData data = new PlayerInfoData(profile, 42, NativeGameMode.CREATIVE, displayName);
|
||||
Object generic = PlayerInfoData.getConverter().getGeneric(MinecraftReflection.getPlayerInfoDataClass(), data);
|
||||
PlayerInfoData back = PlayerInfoData.getConverter().getSpecific(generic);
|
||||
|
||||
assertEquals(data, back);
|
||||
}
|
||||
}
|
||||
|
@ -1,56 +1,56 @@
|
||||
/**
|
||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||
* Copyright (C) 2015 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.wrappers;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.bukkit.DyeColor;
|
||||
import org.bukkit.Material;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.comphenix.protocol.BukkitInitialization;
|
||||
import com.comphenix.protocol.utility.MinecraftReflection;
|
||||
|
||||
/**
|
||||
* @author dmulloy2
|
||||
*/
|
||||
|
||||
public class WrappedBlockDataTest {
|
||||
|
||||
@BeforeClass
|
||||
public static void initializeBukkit() throws IllegalAccessException {
|
||||
BukkitInitialization.initializeItemMeta();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
Material type = Material.WOOL;
|
||||
int data = DyeColor.BLUE.getWoolData();
|
||||
|
||||
WrappedBlockData wrapper = WrappedBlockData.createData(type, data);
|
||||
|
||||
assertEquals(wrapper.getType(), type);
|
||||
assertEquals(wrapper.getData(), data);
|
||||
|
||||
Object generic = BukkitConverters.getWrappedBlockDataConverter().getGeneric(MinecraftReflection.getIBlockDataClass(), wrapper);
|
||||
WrappedBlockData back = BukkitConverters.getWrappedBlockDataConverter().getSpecific(generic);
|
||||
|
||||
assertEquals(wrapper.getType(), back.getType());
|
||||
assertEquals(wrapper.getData(), back.getData());
|
||||
}
|
||||
}
|
||||
/**
|
||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||
* Copyright (C) 2015 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.wrappers;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.bukkit.DyeColor;
|
||||
import org.bukkit.Material;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.comphenix.protocol.BukkitInitialization;
|
||||
import com.comphenix.protocol.utility.MinecraftReflection;
|
||||
|
||||
/**
|
||||
* @author dmulloy2
|
||||
*/
|
||||
|
||||
public class WrappedBlockDataTest {
|
||||
|
||||
@BeforeClass
|
||||
public static void initializeBukkit() throws IllegalAccessException {
|
||||
BukkitInitialization.initializeItemMeta();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
Material type = Material.WOOL;
|
||||
int data = DyeColor.BLUE.getWoolData();
|
||||
|
||||
WrappedBlockData wrapper = WrappedBlockData.createData(type, data);
|
||||
|
||||
assertEquals(wrapper.getType(), type);
|
||||
assertEquals(wrapper.getData(), data);
|
||||
|
||||
Object generic = BukkitConverters.getWrappedBlockDataConverter().getGeneric(MinecraftReflection.getIBlockDataClass(), wrapper);
|
||||
WrappedBlockData back = BukkitConverters.getWrappedBlockDataConverter().getSpecific(generic);
|
||||
|
||||
assertEquals(wrapper.getType(), back.getType());
|
||||
assertEquals(wrapper.getData(), back.getData());
|
||||
}
|
||||
}
|
||||
|
@ -1,102 +1,102 @@
|
||||
/**
|
||||
* 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.wrappers;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNotSame;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import net.minecraft.server.v1_9_R2.EntityLightning;
|
||||
import net.minecraft.server.v1_9_R2.ItemStack;
|
||||
|
||||
import org.bukkit.craftbukkit.v1_9_R2.entity.CraftLightningStrike;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.comphenix.protocol.BukkitInitialization;
|
||||
import com.comphenix.protocol.wrappers.WrappedDataWatcher.Registry;
|
||||
import com.comphenix.protocol.wrappers.WrappedDataWatcher.Serializer;
|
||||
import com.comphenix.protocol.wrappers.WrappedDataWatcher.WrappedDataWatcherObject;
|
||||
|
||||
/**
|
||||
* @author dmulloy2
|
||||
*/
|
||||
|
||||
public class WrappedDataWatcherTest {
|
||||
|
||||
@BeforeClass
|
||||
public static void prepare() {
|
||||
BukkitInitialization.initializePackage();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBytes() {
|
||||
// Create a fake lightning strike and get its watcher
|
||||
EntityLightning lightning = new EntityLightning(null, 0, 0, 0, true);
|
||||
Entity entity = new CraftLightningStrike(null, lightning);
|
||||
WrappedDataWatcher wrapper = WrappedDataWatcher.getEntityWatcher(entity);
|
||||
|
||||
WrappedWatchableObject watchable = wrapper.getWatchableObject(0);
|
||||
WrappedDataWatcherObject object = watchable.getWatcherObject();
|
||||
|
||||
// Make sure the serializers work
|
||||
assertEquals(object.getSerializer(), Registry.get(Byte.class));
|
||||
|
||||
// Make sure we can set existing objects
|
||||
wrapper.setObject(0, (byte) 21);
|
||||
assertTrue(wrapper.getByte(0) == 21);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStrings() {
|
||||
WrappedDataWatcher wrapper = new WrappedDataWatcher();
|
||||
|
||||
// Make sure we can create watcher objects
|
||||
Serializer serializer = Registry.get(String.class);
|
||||
WrappedDataWatcherObject object = new WrappedDataWatcherObject(3, serializer);
|
||||
wrapper.setObject(object, "Test");
|
||||
|
||||
assertEquals(wrapper.getString(3), "Test");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFloats() {
|
||||
WrappedDataWatcher wrapper = new WrappedDataWatcher();
|
||||
|
||||
// Make sure we can add new entries
|
||||
Serializer serializer = Registry.get(Float.class);
|
||||
WrappedDataWatcherObject object = new WrappedDataWatcherObject(10, serializer);
|
||||
wrapper.setObject(object, 21.0F);
|
||||
|
||||
assertTrue(wrapper.hasIndex(10));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSerializers() {
|
||||
Serializer blockPos = Registry.get(net.minecraft.server.v1_9_R2.BlockPosition.class, false);
|
||||
Serializer optionalBlockPos = Registry.get(net.minecraft.server.v1_9_R2.BlockPosition.class, true);
|
||||
assertNotSame(blockPos, optionalBlockPos);
|
||||
|
||||
assertNull(Registry.get(ItemStack.class, false));
|
||||
assertNotNull(Registry.get(UUID.class, true));
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 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.wrappers;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNotSame;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import net.minecraft.server.v1_9_R2.EntityLightning;
|
||||
import net.minecraft.server.v1_9_R2.ItemStack;
|
||||
|
||||
import org.bukkit.craftbukkit.v1_9_R2.entity.CraftLightningStrike;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.comphenix.protocol.BukkitInitialization;
|
||||
import com.comphenix.protocol.wrappers.WrappedDataWatcher.Registry;
|
||||
import com.comphenix.protocol.wrappers.WrappedDataWatcher.Serializer;
|
||||
import com.comphenix.protocol.wrappers.WrappedDataWatcher.WrappedDataWatcherObject;
|
||||
|
||||
/**
|
||||
* @author dmulloy2
|
||||
*/
|
||||
|
||||
public class WrappedDataWatcherTest {
|
||||
|
||||
@BeforeClass
|
||||
public static void prepare() {
|
||||
BukkitInitialization.initializePackage();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBytes() {
|
||||
// Create a fake lightning strike and get its watcher
|
||||
EntityLightning lightning = new EntityLightning(null, 0, 0, 0, true);
|
||||
Entity entity = new CraftLightningStrike(null, lightning);
|
||||
WrappedDataWatcher wrapper = WrappedDataWatcher.getEntityWatcher(entity);
|
||||
|
||||
WrappedWatchableObject watchable = wrapper.getWatchableObject(0);
|
||||
WrappedDataWatcherObject object = watchable.getWatcherObject();
|
||||
|
||||
// Make sure the serializers work
|
||||
assertEquals(object.getSerializer(), Registry.get(Byte.class));
|
||||
|
||||
// Make sure we can set existing objects
|
||||
wrapper.setObject(0, (byte) 21);
|
||||
assertTrue(wrapper.getByte(0) == 21);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStrings() {
|
||||
WrappedDataWatcher wrapper = new WrappedDataWatcher();
|
||||
|
||||
// Make sure we can create watcher objects
|
||||
Serializer serializer = Registry.get(String.class);
|
||||
WrappedDataWatcherObject object = new WrappedDataWatcherObject(3, serializer);
|
||||
wrapper.setObject(object, "Test");
|
||||
|
||||
assertEquals(wrapper.getString(3), "Test");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFloats() {
|
||||
WrappedDataWatcher wrapper = new WrappedDataWatcher();
|
||||
|
||||
// Make sure we can add new entries
|
||||
Serializer serializer = Registry.get(Float.class);
|
||||
WrappedDataWatcherObject object = new WrappedDataWatcherObject(10, serializer);
|
||||
wrapper.setObject(object, 21.0F);
|
||||
|
||||
assertTrue(wrapper.hasIndex(10));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSerializers() {
|
||||
Serializer blockPos = Registry.get(net.minecraft.server.v1_9_R2.BlockPosition.class, false);
|
||||
Serializer optionalBlockPos = Registry.get(net.minecraft.server.v1_9_R2.BlockPosition.class, true);
|
||||
assertNotSame(blockPos, optionalBlockPos);
|
||||
|
||||
assertNull(Registry.get(ItemStack.class, false));
|
||||
assertNotNull(Registry.get(UUID.class, true));
|
||||
}
|
||||
}
|
||||
|
@ -81,4 +81,4 @@ public class WrappedGameProfileTest {
|
||||
assertEquals(property.getValue(), value);
|
||||
assertEquals(property.getSignature(), signature);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -52,4 +52,4 @@ public class WrappedServerPingTest {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -114,4 +114,4 @@ public class ExamplePlugin extends JavaPlugin {
|
||||
throw new RuntimeException("Cannot send packet.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -400,4 +400,4 @@ public final class Reflection {
|
||||
matcher.appendTail(output);
|
||||
return output.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -521,4 +521,4 @@ public abstract class TinyProtocol {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
In neuem Issue referenzieren
Einen Benutzer sperren