Added some missing features to 2.7.0.

Note that this supercedes the previous increment commit.
This commit is contained in:
Kristian S. Stangeland 2013-09-02 02:42:18 +02:00
parent 1b5463651f
commit 37766d3ecf
3 changed files with 106 additions and 29 deletions

View File

@ -21,6 +21,7 @@ import java.lang.reflect.InvocationTargetException;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import org.bukkit.Location;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -83,12 +84,21 @@ public interface ProtocolManager extends PacketStream {
* Broadcast a packet to every player that is recieving information about a given entity. * Broadcast a packet to every player that is recieving information about a given entity.
* <p> * <p>
* This is usually every player in the same world within an observable distance. If the entity is a * This is usually every player in the same world within an observable distance. If the entity is a
* player, its naturally excluded. * player, it will only be included if <i>includeTracker</i> is TRUE.
* @param packet - the packet to broadcast. * @param packet - the packet to broadcast.
* @param tracker - the entity tracker. * @param entity - the entity whose trackers we will inform.
* @param includeTracker - whether or not to also transmit the packet to the entity, if it is a tracker.
* @throws FieldAccessException If we were unable to send the packet due to reflection problems. * @throws FieldAccessException If we were unable to send the packet due to reflection problems.
*/ */
public void broadcastServerPacket(PacketContainer packet, Entity tracker); public void broadcastServerPacket(PacketContainer packet, Entity entity, boolean includeTracker);
/**
* Broadcast a packet to every player within the given maximum observer distance.
* @param packet - the packet to broadcast.
* @param origin - the origin to consider when calculating the distance to each observer.
* @param maxObserverDistance - the maximum distance to the origin.
*/
public void broadcastServerPacket(PacketContainer packet, Location origin, int maxObserverDistance);
/** /**
* Retrieves a list of every registered packet listener. * Retrieves a list of every registered packet listener.

View File

@ -7,6 +7,7 @@ import java.util.List;
import java.util.Set; import java.util.Set;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import org.bukkit.Location;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -162,20 +163,6 @@ public class DelayedPacketManager implements ProtocolManager, InternalManager {
}; };
} }
private Runnable queuedBroadcastServerPacket(final PacketContainer packet, final Entity tracker) {
return new Runnable() {
@Override
public void run() {
// Invoke the correct version
if (tracker != null) {
delegate.broadcastServerPacket(packet, tracker);
} else {
delegate.broadcastServerPacket(packet);
}
}
};
}
@Override @Override
public void setPlayerHook(PlayerInjectHooks playerHook) { public void setPlayerHook(PlayerInjectHooks playerHook) {
this.hook = playerHook; this.hook = playerHook;
@ -225,19 +212,45 @@ public class DelayedPacketManager implements ProtocolManager, InternalManager {
} }
@Override @Override
public void broadcastServerPacket(PacketContainer packet, Entity tracker) { public void broadcastServerPacket(final PacketContainer packet, final Entity entity, final boolean includeTracker) {
if (delegate != null) if (delegate != null) {
delegate.broadcastServerPacket(packet, tracker); delegate.broadcastServerPacket(packet, entity, includeTracker);
else } else {
queuedActions.add(queuedBroadcastServerPacket(packet, tracker)); queuedActions.add(new Runnable() {
@Override
public void run() {
delegate.broadcastServerPacket(packet, entity, includeTracker);
}
});
}
} }
@Override @Override
public void broadcastServerPacket(PacketContainer packet) { public void broadcastServerPacket(final PacketContainer packet, final Location origin, final int maxObserverDistance) {
if (delegate != null) if (delegate != null) {
delegate.broadcastServerPacket(packet, origin, maxObserverDistance);
} else {
queuedActions.add(new Runnable() {
@Override
public void run() {
delegate.broadcastServerPacket(packet, origin, maxObserverDistance);
}
});
}
}
@Override
public void broadcastServerPacket(final PacketContainer packet) {
if (delegate != null) {
delegate.broadcastServerPacket(packet); delegate.broadcastServerPacket(packet);
else } else {
queuedActions.add(queuedBroadcastServerPacket(packet, null)); queuedActions.add(new Runnable() {
@Override
public void run() {
delegate.broadcastServerPacket(packet);
}
});
}
} }
@Override @Override

View File

@ -33,6 +33,7 @@ import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy; import net.sf.cglib.proxy.MethodProxy;
import org.bukkit.Location;
import org.bukkit.Server; import org.bukkit.Server;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
@ -182,6 +183,9 @@ public final class PacketFilterManager implements ProtocolManager, ListenerInvok
// Plugin verifier // Plugin verifier
private PluginVerifier pluginVerifier; private PluginVerifier pluginVerifier;
// Whether or not Location.distance(Location) exists - we assume this is the case
private boolean hasRecycleDistance = true;
// The current Minecraft version // The current Minecraft version
private MinecraftVersion minecraftVersion; private MinecraftVersion minecraftVersion;
@ -626,10 +630,60 @@ public final class PacketFilterManager implements ProtocolManager, ListenerInvok
} }
@Override @Override
public void broadcastServerPacket(PacketContainer packet, Entity tracker) { public void broadcastServerPacket(PacketContainer packet, Entity entity, boolean includeTracker) {
Preconditions.checkNotNull(packet, "packet cannot be NULL."); Preconditions.checkNotNull(packet, "packet cannot be NULL.");
Preconditions.checkNotNull(tracker, "tracker cannot be NULL."); Preconditions.checkNotNull(entity, "entity cannot be NULL.");
broadcastServerPacket(packet, getEntityTrackers(tracker)); List<Player> trackers = getEntityTrackers(entity);
// Only add it if it's a player
if (includeTracker && entity instanceof Player) {
trackers.add((Player) entity);
}
broadcastServerPacket(packet, trackers);
}
@Override
public void broadcastServerPacket(PacketContainer packet, Location origin, int maxObserverDistance) {
try {
// Square the maximum too
int maxDistance = maxObserverDistance * maxObserverDistance;
World world = origin.getWorld();
Location recycle = origin.clone();
// Only broadcast the packet to nearby players
for (Player player : server.getOnlinePlayers()) {
if (world.equals(player.getWorld()) &&
getDistanceSquared(origin, recycle, player) <= maxDistance) {
sendServerPacket(player, packet);
}
}
} catch (InvocationTargetException e) {
throw new FieldAccessException("Unable to send server packet.", e);
}
}
/**
* Retrieve the squared distance between a location and a player.
* @param origin - the origin location.
* @param recycle - a location object to be recycled, if supported.
* @param player - the player.
* @return The squared distance between the player and the origin,
*/
private double getDistanceSquared(Location origin, Location recycle, Player player) {
if (hasRecycleDistance) {
try {
return player.getLocation(recycle).distanceSquared(origin);
} catch (Error e) {
// Damn it
hasRecycleDistance = false;
}
}
// The fallback method
return player.getLocation().distanceSquared(origin);
} }
/** /**