Archiviert
13
0

Make it possible to get every player that is tracking a given entity.

Dieser Commit ist enthalten in:
Kristian S. Stangeland 2012-12-02 02:49:11 +01:00
Ursprung 2bd06922e0
Commit f4accbfe2d
3 geänderte Dateien mit 50 neuen und 2 gelöschten Zeilen

Datei anzeigen

@ -130,7 +130,7 @@ public interface ProtocolManager extends PacketStream {
public PacketConstructor createPacketConstructor(int id, Object... arguments); public PacketConstructor createPacketConstructor(int id, Object... arguments);
/** /**
* Completely refresh all clients about an entity. * Completely resend an entity to a list of clients.
* <p> * <p>
* Note that this method is NOT thread safe. If you call this method from anything * Note that this method is NOT thread safe. If you call this method from anything
* but the main thread, it will throw an exception. * but the main thread, it will throw an exception.
@ -148,6 +148,14 @@ public interface ProtocolManager extends PacketStream {
*/ */
public Entity getEntityFromID(World container, int id) throws FieldAccessException; public Entity getEntityFromID(World container, int id) throws FieldAccessException;
/**
* Retrieve every client that is receiving information about a given entity.
* @param entity - the entity that is being tracked.
* @return Every client/player that is tracking the given entity.
* @throws FieldAccessException If reflection failed.
*/
public List<Player> getEntityTrackers(Entity entity) throws FieldAccessException;
/** /**
* Retrieves a immutable set containing the ID of the sent server packets that will be observed by listeners. * Retrieves a immutable set containing the ID of the sent server packets that will be observed by listeners.
* @return Every filtered server packet. * @return Every filtered server packet.

Datei anzeigen

@ -21,12 +21,14 @@ import java.lang.reflect.Constructor;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import net.minecraft.server.EntityPlayer;
import net.minecraft.server.EntityTrackerEntry; import net.minecraft.server.EntityTrackerEntry;
import org.bukkit.World; import org.bukkit.World;
@ -118,7 +120,39 @@ class EntityUtilities {
} catch (SecurityException e) { } catch (SecurityException e) {
throw new FieldAccessException("Security limitation prevents access to 'scanPlayers' method in trackerEntry.", e); throw new FieldAccessException("Security limitation prevents access to 'scanPlayers' method in trackerEntry.", e);
} catch (NoSuchMethodException e) { } catch (NoSuchMethodException e) {
throw new FieldAccessException("Canot find 'scanPlayers' method. Is ProtocolLib up to date?", e); throw new FieldAccessException("Cannot find 'scanPlayers' method. Is ProtocolLib up to date?", e);
}
}
/**
* Retrieve every client that is receiving information about a given entity.
* @param entity - the entity that is being tracked.
* @return Every client/player that is tracking the given entity.
* @throws FieldAccessException If reflection failed.
*/
public static List<Player> getEntityTrackers(Entity entity) {
try {
List<Player> result = new ArrayList<Player>();
Object trackerEntry = getEntityTrackerEntry(entity.getWorld(), entity.getEntityId());
if (trackedPlayersField == null)
trackedPlayersField = FuzzyReflection.fromObject(trackerEntry).getFieldByType("java\\.util\\..*");
Collection<?> trackedPlayers = (Collection<?>) FieldUtils.readField(trackedPlayersField, trackerEntry, false);
// Wrap every player - we also ensure that the underlying tracker list is immutable
for (Object tracker : trackedPlayers) {
if (tracker instanceof EntityPlayer) {
EntityPlayer nmsPlayer = (EntityPlayer) tracker;
result.add(nmsPlayer.getBukkitEntity());
}
}
return result;
} catch (IllegalAccessException e) {
throw new FieldAccessException("Security limitation prevented access to the list of tracked players.", e);
} catch (InvocationTargetException e) {
throw new FieldAccessException("Exception occurred in Minecraft.", e);
} }
} }

Datei anzeigen

@ -55,6 +55,7 @@ import com.comphenix.protocol.events.*;
import com.comphenix.protocol.injector.player.PlayerInjectionHandler; import com.comphenix.protocol.injector.player.PlayerInjectionHandler;
import com.comphenix.protocol.reflect.FieldAccessException; import com.comphenix.protocol.reflect.FieldAccessException;
import com.comphenix.protocol.reflect.FuzzyReflection; import com.comphenix.protocol.reflect.FuzzyReflection;
import com.comphenix.protocol.wrappers.BukkitConverters;
import com.google.common.base.Objects; import com.google.common.base.Objects;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
@ -571,6 +572,11 @@ public final class PacketFilterManager implements ProtocolManager, ListenerInvok
return EntityUtilities.getEntityFromID(container, id); return EntityUtilities.getEntityFromID(container, id);
} }
@Override
public List<Player> getEntityTrackers(Entity entity) throws FieldAccessException {
return EntityUtilities.getEntityTrackers(entity);
}
/** /**
* Initialize the packet injection for every player. * Initialize the packet injection for every player.
* @param players - list of players to inject. * @param players - list of players to inject.