Archiviert
13
0

Add the ability to broadcast a packet to every player or nearby players

This is just a convenience method.
Dieser Commit ist enthalten in:
Kristian S. Stangeland 2013-09-01 18:47:24 +02:00
Ursprung 8295b951d9
Commit fba2b7a6b3
3 geänderte Dateien mit 127 neuen und 97 gelöschten Zeilen

Datei anzeigen

@ -72,6 +72,24 @@ public interface ProtocolManager extends PacketStream {
public void recieveClientPacket(Player sender, PacketContainer packet, boolean filters) public void recieveClientPacket(Player sender, PacketContainer packet, boolean filters)
throws IllegalAccessException, InvocationTargetException; throws IllegalAccessException, InvocationTargetException;
/**
* Broadcast a given packet to every connected player on the server.
* @param packet - the packet to broadcast.
* @throws FieldAccessException If we were unable to send the packet due to reflection problems.
*/
public void broadcastServerPacket(PacketContainer packet);
/**
* Broadcast a packet to every player that is recieving information about a given entity.
* <p>
* This is usually every player in the same world within an observable distance. If the entity is a
* player, its naturally excluded.
* @param packet - the packet to broadcast.
* @param tracker - the entity tracker.
* @throws FieldAccessException If we were unable to send the packet due to reflection problems.
*/
public void broadcastServerPacket(PacketContainer packet, Entity tracker);
/** /**
* Retrieves a list of every registered packet listener. * Retrieves a list of every registered packet listener.
* @return Every registered packet listener. * @return Every registered packet listener.

Datei anzeigen

@ -29,7 +29,6 @@ import com.google.common.base.Objects;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
/** /**
@ -43,73 +42,11 @@ public class DelayedPacketManager implements ProtocolManager, InternalManager {
public static final ReportType REPORT_CANNOT_SEND_QUEUED_PACKET = new ReportType("Cannot send queued packet %s."); public static final ReportType REPORT_CANNOT_SEND_QUEUED_PACKET = new ReportType("Cannot send queued packet %s.");
public static final ReportType REPORT_CANNOT_REGISTER_QUEUED_LISTENER = new ReportType("Cannot register queued listener %s."); public static final ReportType REPORT_CANNOT_REGISTER_QUEUED_LISTENER = new ReportType("Cannot register queued listener %s.");
/**
* Represents a packet that will be transmitted later.
* @author Kristian
*
*/
private static class QueuedPacket {
private final Player player;
private final PacketContainer packet;
private final NetworkMarker marker;
private final boolean filtered;
private final ConnectionSide side;
public QueuedPacket(Player player, PacketContainer packet, NetworkMarker marker, boolean filtered, ConnectionSide side) {
this.player = player;
this.packet = packet;
this.marker = marker;
this.filtered = filtered;
this.side = side;
}
/**
* Retrieve the packet that will be transmitted or receieved.
* @return The packet.
*/
public PacketContainer getPacket() {
return packet;
}
/**
* Retrieve the player that will send or recieve the packet.
* @return The source.
*/
public Player getPlayer() {
return player;
}
/**
* Retrieve whether or not the packet will the sent or received.
* @return The connection side.
*/
public ConnectionSide getSide() {
return side;
}
/**
* Retrieve the associated network marker used to serialize packets on the network stream.
* @return The associated marker.
*/
public NetworkMarker getMarker() {
return marker;
}
/**
* Determine if the packet should be intercepted by packet listeners.
* @return TRUE if it should, FALSE otherwise.
*/
public boolean isFiltered() {
return filtered;
}
}
private volatile InternalManager delegate; private volatile InternalManager delegate;
// Packet listeners that will be registered // Queued actions
private final Set<PacketListener> queuedListeners = Sets.newSetFromMap(Maps.<PacketListener, Boolean>newConcurrentMap()); private final List<Runnable> queuedActions = Collections.synchronizedList(Lists.<Runnable>newArrayList());
private final List<QueuedPacket> queuedPackets = Collections.synchronizedList(Lists.<QueuedPacket>newArrayList()); private final List<PacketListener> queuedListeners = Collections.synchronizedList(Lists.<PacketListener>newArrayList());
private AsynchronousManager asyncManager; private AsynchronousManager asyncManager;
private ErrorReporter reporter; private ErrorReporter reporter;
@ -170,6 +107,8 @@ public class DelayedPacketManager implements ProtocolManager, InternalManager {
delegate.registerEvents(queuedManager, queuedPlugin); delegate.registerEvents(queuedManager, queuedPlugin);
} }
// Add any pending listeners
synchronized (queuedListeners) {
for (PacketListener listener : queuedListeners) { for (PacketListener listener : queuedListeners) {
try { try {
delegate.addPacketListener(listener); delegate.addPacketListener(listener);
@ -180,20 +119,38 @@ public class DelayedPacketManager implements ProtocolManager, InternalManager {
callerParam(delegate).messageParam(listener).error(e)); callerParam(delegate).messageParam(listener).error(e));
} }
} }
}
synchronized (queuedPackets) { // Execute any delayed actions
for (QueuedPacket packet : queuedPackets) { synchronized (queuedActions) {
for (Runnable action : queuedActions) {
action.run();
}
}
// Don't keep this around anymore
queuedListeners.clear();
queuedActions.clear();
}
}
private Runnable queuedAddPacket(final ConnectionSide side, final Player player, final PacketContainer packet,
final NetworkMarker marker, final boolean filtered) {
return new Runnable() {
@Override
public void run() {
try { try {
// Attempt to send it now // Attempt to send it now
switch (packet.getSide()) { switch (side) {
case CLIENT_SIDE: case CLIENT_SIDE:
delegate.recieveClientPacket(packet.getPlayer(), packet.getPacket(), packet.getMarker(), packet.isFiltered()); delegate.recieveClientPacket(player, packet, marker, filtered);
break; break;
case SERVER_SIDE: case SERVER_SIDE:
delegate.sendServerPacket(packet.getPlayer(), packet.getPacket(), packet.getMarker(), packet.isFiltered()); delegate.sendServerPacket(player, packet, marker, filtered);
break; break;
default: default:
throw new IllegalArgumentException("side cannot be " + side);
} }
} catch (Exception e) { } catch (Exception e) {
// Inform about this plugin error // Inform about this plugin error
@ -202,13 +159,22 @@ public class DelayedPacketManager implements ProtocolManager, InternalManager {
callerParam(delegate).messageParam(packet).error(e)); callerParam(delegate).messageParam(packet).error(e));
} }
} }
};
} }
// Don't keep this around anymore private Runnable queuedBroadcastServerPacket(final PacketContainer packet, final Entity tracker) {
queuedListeners.clear(); return new Runnable() {
queuedPackets.clear(); @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) {
@ -235,7 +201,7 @@ public class DelayedPacketManager implements ProtocolManager, InternalManager {
if (delegate != null) { if (delegate != null) {
delegate.sendServerPacket(reciever, packet, marker, filters); delegate.sendServerPacket(reciever, packet, marker, filters);
} else { } else {
queuedPackets.add(new QueuedPacket(reciever, packet, marker, filters, ConnectionSide.SERVER_SIDE)); queuedActions.add(queuedAddPacket(ConnectionSide.SERVER_SIDE, reciever, packet, marker, filters));
} }
} }
@ -254,10 +220,26 @@ public class DelayedPacketManager implements ProtocolManager, InternalManager {
if (delegate != null) { if (delegate != null) {
delegate.recieveClientPacket(sender, packet, marker, filters); delegate.recieveClientPacket(sender, packet, marker, filters);
} else { } else {
queuedPackets.add(new QueuedPacket(sender, packet, marker, filters, ConnectionSide.CLIENT_SIDE)); queuedActions.add(queuedAddPacket(ConnectionSide.CLIENT_SIDE, sender, packet, marker, filters));
} }
} }
@Override
public void broadcastServerPacket(PacketContainer packet, Entity tracker) {
if (delegate != null)
delegate.broadcastServerPacket(packet, tracker);
else
queuedActions.add(queuedBroadcastServerPacket(packet, tracker));
}
@Override
public void broadcastServerPacket(PacketContainer packet) {
if (delegate != null)
delegate.broadcastServerPacket(packet);
else
queuedActions.add(queuedBroadcastServerPacket(packet, null));
}
@Override @Override
public ImmutableSet<PacketListener> getPacketListeners() { public ImmutableSet<PacketListener> getPacketListeners() {
if (delegate != null) if (delegate != null)

Datei anzeigen

@ -19,6 +19,7 @@ package com.comphenix.protocol.injector;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
@ -68,6 +69,7 @@ import com.comphenix.protocol.reflect.FuzzyReflection;
import com.comphenix.protocol.utility.MinecraftReflection; import com.comphenix.protocol.utility.MinecraftReflection;
import com.comphenix.protocol.utility.MinecraftVersion; import com.comphenix.protocol.utility.MinecraftVersion;
import com.google.common.base.Objects; import com.google.common.base.Objects;
import com.google.common.base.Preconditions;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
@ -617,6 +619,34 @@ public final class PacketFilterManager implements ProtocolManager, ListenerInvok
} }
} }
@Override
public void broadcastServerPacket(PacketContainer packet) {
Preconditions.checkNotNull(packet, "packet cannot be NULL.");
broadcastServerPacket(packet, Arrays.asList(server.getOnlinePlayers()));
}
@Override
public void broadcastServerPacket(PacketContainer packet, Entity tracker) {
Preconditions.checkNotNull(packet, "packet cannot be NULL.");
Preconditions.checkNotNull(tracker, "tracker cannot be NULL.");
broadcastServerPacket(packet, getEntityTrackers(tracker));
}
/**
* Broadcast a packet to a given iterable of players.
* @param packet - the packet to broadcast.
* @param players - the iterable of players.
*/
private void broadcastServerPacket(PacketContainer packet, Iterable<Player> players) {
try {
for (Player player : players) {
sendServerPacket(player, packet);
}
} catch (InvocationTargetException e) {
throw new FieldAccessException("Unable to send server packet.", e);
}
}
@Override @Override
public void sendServerPacket(Player reciever, PacketContainer packet) throws InvocationTargetException { public void sendServerPacket(Player reciever, PacketContainer packet) throws InvocationTargetException {
sendServerPacket(reciever, packet, null, true); sendServerPacket(reciever, packet, null, true);