package com.bergerkiller.bukkit.common.reflection.classes;
import java.util.Set;
import org.bukkit.Chunk;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import com.bergerkiller.bukkit.common.conversion.Conversion;
import com.bergerkiller.bukkit.common.conversion.ConversionPairs;
import com.bergerkiller.bukkit.common.protocol.PacketType;
import com.bergerkiller.bukkit.common.reflection.ClassTemplate;
import com.bergerkiller.bukkit.common.reflection.FieldAccessor;
import com.bergerkiller.bukkit.common.reflection.MethodAccessor;
import com.bergerkiller.bukkit.common.reflection.NMSClassTemplate;
import com.bergerkiller.bukkit.common.wrappers.IntHashMap;
public class EntityTrackerRef {
public static final ClassTemplate<?> TEMPLATE = NMSClassTemplate.create("EntityTracker");
public static final FieldAccessor<Set<Object>> trackerSet = TEMPLATE.getField("c");
public static final FieldAccessor<IntHashMap<Object>> trackedEntities = TEMPLATE.getField("trackedEntities").translate(ConversionPairs.intHashMap);
private static final MethodAccessor<Void> spawnEntities = TEMPLATE.getMethod("a", EntityPlayerRef.TEMPLATE.getType(), ChunkRef.TEMPLATE.getType());
private static final MethodAccessor<Void> track = TEMPLATE.getMethod("track", EntityRef.TEMPLATE.getType());
private static final MethodAccessor<Void> untrack = TEMPLATE.getMethod("untrackEntity", EntityRef.TEMPLATE.getType());
private static final MethodAccessor<Void> sendPacket = TEMPLATE.getMethod("sendPacketToEntity", EntityRef.TEMPLATE.getType(), PacketType.DEFAULT.getType());
private static final MethodAccessor<Void> untrackPlayer = TEMPLATE.getMethod("untrackPlayer", EntityPlayerRef.TEMPLATE.getType());
public static void sendPacket(Object entityTrackerInstance, Entity entity, Object packet) {
sendPacket.invoke(entityTrackerInstance, Conversion.toEntityHandle.convert(entity), packet);
}
public static void spawnEntities(Object entityTrackerInstance, Player player, Chunk chunk) {
spawnEntities.invoke(entityTrackerInstance, Conversion.toEntityHandle.convert(player), Conversion.toChunkHandle.convert(chunk));
}
public static void removeViewer(Object entityTrackerInstance, Player player) {
untrackPlayer.invoke(entityTrackerInstance, Conversion.toEntityHandle.convert(player));
}
public static void startTracking(Object entityTrackerInstance, Entity entity) {
track.invoke(entityTrackerInstance, Conversion.toEntityHandle.convert(entity));
}
public static void stopTracking(Object entityTrackerInstance, Entity entity) {
untrack.invoke(entityTrackerInstance, Conversion.toEntityHandle.convert(entity));
}
public static Object getEntry(Object entityTrackerInstance, Entity entity) {
return trackedEntities.get(entityTrackerInstance).get(entity.getEntityId());
}
public static void updatePlayer(Object entityTrackerInstance, Player player) {
for (Object entry : trackerSet.get(entityTrackerInstance)) {
if (EntityTrackerEntryRef.tracker.get(entry) != player) {
EntityTrackerEntryRef.updatePlayer(entry, player);
}
}
}
public static Object setEntry(Object entityTrackerInstance, Entity entity, Object entityTrackerEntry) {
Object previous;
final int id = entity.getEntityId();
// Set in tracked entities map
IntHashMap<Object> trackedMap = trackedEntities.get(entityTrackerInstance);
previous = trackedMap.remove(id);
trackedMap.put(id, entityTrackerEntry);
// Replace in set
Set<Object> trackers = trackerSet.get(entityTrackerInstance);
trackers.remove(previous);
trackers.add(entityTrackerEntry);
return previous;
}
}