mirror of
https://github.com/dmulloy2/ProtocolLib.git
synced 2025-02-19 14:02:07 +01:00
Ignore logged out players.
This commit is contained in:
parent
627c500de1
commit
169842f265
@ -1,167 +1,168 @@
|
|||||||
/*
|
/*
|
||||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||||
* Copyright (C) 2012 Kristian S. Stangeland
|
* Copyright (C) 2012 Kristian S. Stangeland
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
* 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
|
* GNU General Public License as published by the Free Software Foundation; either version 2 of
|
||||||
* the License, or (at your option) any later version.
|
* 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;
|
* 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.
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
* See the GNU General Public License for more details.
|
* 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;
|
* 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
|
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||||
* 02111-1307 USA
|
* 02111-1307 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.comphenix.protocol;
|
package com.comphenix.protocol;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.comphenix.protocol.async.AsyncListenerHandler;
|
import com.comphenix.protocol.async.AsyncListenerHandler;
|
||||||
import com.comphenix.protocol.error.ErrorReporter;
|
import com.comphenix.protocol.error.ErrorReporter;
|
||||||
import com.comphenix.protocol.error.Report;
|
import com.comphenix.protocol.error.Report;
|
||||||
import com.comphenix.protocol.error.ReportType;
|
import com.comphenix.protocol.error.ReportType;
|
||||||
import com.comphenix.protocol.events.ListeningWhitelist;
|
import com.comphenix.protocol.events.ListeningWhitelist;
|
||||||
import com.comphenix.protocol.events.PacketContainer;
|
import com.comphenix.protocol.events.PacketContainer;
|
||||||
import com.comphenix.protocol.injector.BukkitUnwrapper;
|
import com.comphenix.protocol.injector.BukkitUnwrapper;
|
||||||
import com.comphenix.protocol.injector.server.AbstractInputStreamLookup;
|
import com.comphenix.protocol.injector.server.AbstractInputStreamLookup;
|
||||||
import com.comphenix.protocol.injector.server.TemporaryPlayerFactory;
|
import com.comphenix.protocol.injector.server.TemporaryPlayerFactory;
|
||||||
import com.comphenix.protocol.injector.spigot.SpigotPacketInjector;
|
import com.comphenix.protocol.injector.spigot.SpigotPacketInjector;
|
||||||
import com.comphenix.protocol.reflect.FieldUtils;
|
import com.comphenix.protocol.reflect.FieldUtils;
|
||||||
import com.comphenix.protocol.reflect.FuzzyReflection;
|
import com.comphenix.protocol.reflect.FuzzyReflection;
|
||||||
import com.comphenix.protocol.reflect.MethodUtils;
|
import com.comphenix.protocol.reflect.MethodUtils;
|
||||||
import com.comphenix.protocol.reflect.ObjectWriter;
|
import com.comphenix.protocol.reflect.ObjectWriter;
|
||||||
import com.comphenix.protocol.reflect.compiler.BackgroundCompiler;
|
import com.comphenix.protocol.reflect.compiler.BackgroundCompiler;
|
||||||
import com.comphenix.protocol.reflect.compiler.StructureCompiler;
|
import com.comphenix.protocol.reflect.compiler.StructureCompiler;
|
||||||
import com.comphenix.protocol.reflect.instances.CollectionGenerator;
|
import com.comphenix.protocol.reflect.instances.CollectionGenerator;
|
||||||
import com.comphenix.protocol.reflect.instances.DefaultInstances;
|
import com.comphenix.protocol.reflect.instances.DefaultInstances;
|
||||||
import com.comphenix.protocol.reflect.instances.PrimitiveGenerator;
|
import com.comphenix.protocol.reflect.instances.PrimitiveGenerator;
|
||||||
import com.comphenix.protocol.utility.MinecraftReflection;
|
import com.comphenix.protocol.utility.MinecraftReflection;
|
||||||
import com.comphenix.protocol.wrappers.ChunkPosition;
|
import com.comphenix.protocol.wrappers.ChunkPosition;
|
||||||
import com.comphenix.protocol.wrappers.WrappedDataWatcher;
|
import com.comphenix.protocol.wrappers.WrappedDataWatcher;
|
||||||
import com.comphenix.protocol.wrappers.WrappedWatchableObject;
|
import com.comphenix.protocol.wrappers.WrappedWatchableObject;
|
||||||
import com.comphenix.protocol.wrappers.nbt.io.NbtBinarySerializer;
|
import com.comphenix.protocol.wrappers.nbt.io.NbtBinarySerializer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to fix ClassLoader leaks that may lead to filling up the permanent generation.
|
* Used to fix ClassLoader leaks that may lead to filling up the permanent generation.
|
||||||
*
|
*
|
||||||
* @author Kristian
|
* @author Kristian
|
||||||
*/
|
*/
|
||||||
class CleanupStaticMembers {
|
class CleanupStaticMembers {
|
||||||
// Reports
|
// Reports
|
||||||
public final static ReportType REPORT_CANNOT_RESET_FIELD = new ReportType("Unable to reset field %s: %s");
|
public final static ReportType REPORT_CANNOT_RESET_FIELD = new ReportType("Unable to reset field %s: %s");
|
||||||
public final static ReportType REPORT_CANNOT_UNLOAD_CLASS = new ReportType("Unable to unload class %s.");
|
public final static ReportType REPORT_CANNOT_UNLOAD_CLASS = new ReportType("Unable to unload class %s.");
|
||||||
|
|
||||||
private ClassLoader loader;
|
private ClassLoader loader;
|
||||||
private ErrorReporter reporter;
|
private ErrorReporter reporter;
|
||||||
|
|
||||||
public CleanupStaticMembers(ClassLoader loader, ErrorReporter reporter) {
|
public CleanupStaticMembers(ClassLoader loader, ErrorReporter reporter) {
|
||||||
this.loader = loader;
|
this.loader = loader;
|
||||||
this.reporter = reporter;
|
this.reporter = reporter;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ensure that the previous ClassLoader is not leaking.
|
* Ensure that the previous ClassLoader is not leaking.
|
||||||
*/
|
*/
|
||||||
public void resetAll() {
|
public void resetAll() {
|
||||||
// This list must always be updated
|
// This list must always be updated
|
||||||
Class<?>[] publicClasses = {
|
Class<?>[] publicClasses = {
|
||||||
AsyncListenerHandler.class, ListeningWhitelist.class, PacketContainer.class,
|
AsyncListenerHandler.class, ListeningWhitelist.class, PacketContainer.class,
|
||||||
BukkitUnwrapper.class, DefaultInstances.class, CollectionGenerator.class,
|
BukkitUnwrapper.class, DefaultInstances.class, CollectionGenerator.class,
|
||||||
PrimitiveGenerator.class, FuzzyReflection.class, MethodUtils.class,
|
PrimitiveGenerator.class, FuzzyReflection.class, MethodUtils.class,
|
||||||
BackgroundCompiler.class, StructureCompiler.class,
|
BackgroundCompiler.class, StructureCompiler.class,
|
||||||
ObjectWriter.class, Packets.Server.class, Packets.Client.class,
|
ObjectWriter.class, Packets.Server.class, Packets.Client.class,
|
||||||
ChunkPosition.class, WrappedDataWatcher.class, WrappedWatchableObject.class,
|
ChunkPosition.class, WrappedDataWatcher.class, WrappedWatchableObject.class,
|
||||||
AbstractInputStreamLookup.class, TemporaryPlayerFactory.class, SpigotPacketInjector.class,
|
AbstractInputStreamLookup.class, TemporaryPlayerFactory.class, SpigotPacketInjector.class,
|
||||||
MinecraftReflection.class, NbtBinarySerializer.class
|
MinecraftReflection.class, NbtBinarySerializer.class
|
||||||
};
|
};
|
||||||
|
|
||||||
String[] internalClasses = {
|
String[] internalClasses = {
|
||||||
"com.comphenix.protocol.events.SerializedOfflinePlayer",
|
"com.comphenix.protocol.events.SerializedOfflinePlayer",
|
||||||
"com.comphenix.protocol.injector.player.InjectedServerConnection",
|
"com.comphenix.protocol.injector.player.InjectedServerConnection",
|
||||||
"com.comphenix.protocol.injector.player.NetworkFieldInjector",
|
"com.comphenix.protocol.injector.player.NetworkFieldInjector",
|
||||||
"com.comphenix.protocol.injector.player.NetworkObjectInjector",
|
"com.comphenix.protocol.injector.player.NetworkObjectInjector",
|
||||||
"com.comphenix.protocol.injector.player.NetworkServerInjector",
|
"com.comphenix.protocol.injector.player.NetworkServerInjector",
|
||||||
"com.comphenix.protocol.injector.player.PlayerInjector",
|
"com.comphenix.protocol.injector.player.PlayerInjector",
|
||||||
"com.comphenix.protocol.injector.EntityUtilities",
|
"com.comphenix.protocol.injector.EntityUtilities",
|
||||||
"com.comphenix.protocol.injector.packet.PacketRegistry",
|
"com.comphenix.protocol.injector.packet.PacketRegistry",
|
||||||
"com.comphenix.protocol.injector.packet.PacketInjector",
|
"com.comphenix.protocol.injector.packet.PacketInjector",
|
||||||
"com.comphenix.protocol.injector.packet.ReadPacketModifier",
|
"com.comphenix.protocol.injector.packet.ReadPacketModifier",
|
||||||
"com.comphenix.protocol.injector.StructureCache",
|
"com.comphenix.protocol.injector.StructureCache",
|
||||||
"com.comphenix.protocol.reflect.compiler.BoxingHelper",
|
"com.comphenix.protocol.reflect.compiler.BoxingHelper",
|
||||||
"com.comphenix.protocol.reflect.compiler.MethodDescriptor",
|
"com.comphenix.protocol.reflect.compiler.MethodDescriptor",
|
||||||
"com.comphenix.protocol.wrappers.nbt.WrappedElement",
|
"com.comphenix.protocol.wrappers.nbt.WrappedElement",
|
||||||
};
|
};
|
||||||
|
|
||||||
resetClasses(publicClasses);
|
resetClasses(publicClasses);
|
||||||
resetClasses(getClasses(loader, internalClasses));
|
resetClasses(getClasses(loader, internalClasses));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resetClasses(Class<?>[] classes) {
|
private void resetClasses(Class<?>[] classes) {
|
||||||
// Reset each class one by one
|
// Reset each class one by one
|
||||||
for (Class<?> clazz : classes) {
|
for (Class<?> clazz : classes) {
|
||||||
resetClass(clazz);
|
resetClass(clazz);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resetClass(Class<?> clazz) {
|
private void resetClass(Class<?> clazz) {
|
||||||
for (Field field : clazz.getFields()) {
|
for (Field field : clazz.getFields()) {
|
||||||
Class<?> type = field.getType();
|
Class<?> type = field.getType();
|
||||||
|
|
||||||
// Only check static non-primitive fields. We also skip strings.
|
// Only check static non-primitive fields. We also skip strings.
|
||||||
if (Modifier.isStatic(field.getModifiers()) &&
|
if (Modifier.isStatic(field.getModifiers()) &&
|
||||||
!type.isPrimitive() && !type.equals(String.class)) {
|
!type.isPrimitive() && !type.equals(String.class)) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
setFinalStatic(field, null);
|
setFinalStatic(field, null);
|
||||||
} catch (IllegalAccessException e) {
|
} catch (IllegalAccessException e) {
|
||||||
// Just inform the player
|
// Just inform the player
|
||||||
reporter.reportWarning(this,
|
reporter.reportWarning(this,
|
||||||
Report.newBuilder(REPORT_CANNOT_RESET_FIELD).error(e).messageParam(field.getName(), e.getMessage())
|
Report.newBuilder(REPORT_CANNOT_RESET_FIELD).error(e).messageParam(field.getName(), e.getMessage())
|
||||||
);
|
);
|
||||||
}
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// HACK! HAACK!
|
|
||||||
private static void setFinalStatic(Field field, Object newValue) throws IllegalAccessException {
|
// HACK! HAACK!
|
||||||
int modifier = field.getModifiers();
|
private static void setFinalStatic(Field field, Object newValue) throws IllegalAccessException {
|
||||||
boolean isFinal = Modifier.isFinal(modifier);
|
int modifier = field.getModifiers();
|
||||||
|
boolean isFinal = Modifier.isFinal(modifier);
|
||||||
Field modifiersField = isFinal ? FieldUtils.getField(Field.class, "modifiers", true) : null;
|
|
||||||
|
Field modifiersField = isFinal ? FieldUtils.getField(Field.class, "modifiers", true) : null;
|
||||||
// We have to remove the final field first
|
|
||||||
if (isFinal) {
|
// We have to remove the final field first
|
||||||
FieldUtils.writeField(modifiersField, field, modifier & ~Modifier.FINAL, true);
|
if (isFinal) {
|
||||||
}
|
FieldUtils.writeField(modifiersField, field, modifier & ~Modifier.FINAL, true);
|
||||||
|
}
|
||||||
// Now we can safely modify the field
|
|
||||||
FieldUtils.writeStaticField(field, newValue, true);
|
// Now we can safely modify the field
|
||||||
|
FieldUtils.writeStaticField(field, newValue, true);
|
||||||
// Revert modifier
|
|
||||||
if (isFinal) {
|
// Revert modifier
|
||||||
FieldUtils.writeField(modifiersField, field, modifier, true);
|
if (isFinal) {
|
||||||
}
|
FieldUtils.writeField(modifiersField, field, modifier, true);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
private Class<?>[] getClasses(ClassLoader loader, String[] names) {
|
|
||||||
List<Class<?>> output = new ArrayList<Class<?>>();
|
private Class<?>[] getClasses(ClassLoader loader, String[] names) {
|
||||||
|
List<Class<?>> output = new ArrayList<Class<?>>();
|
||||||
for (String name : names) {
|
|
||||||
try {
|
for (String name : names) {
|
||||||
output.add(loader.loadClass(name));
|
try {
|
||||||
} catch (ClassNotFoundException e) {
|
output.add(loader.loadClass(name));
|
||||||
// Warn the user
|
} catch (ClassNotFoundException e) {
|
||||||
reporter.reportWarning(this, Report.newBuilder(REPORT_CANNOT_UNLOAD_CLASS).error(e).messageParam(name));
|
// Warn the user
|
||||||
}
|
reporter.reportWarning(this, Report.newBuilder(REPORT_CANNOT_UNLOAD_CLASS).error(e).messageParam(name));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return output.toArray(new Class<?>[0]);
|
|
||||||
}
|
return output.toArray(new Class<?>[0]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user