Ensure that monitor listeners cannot modify a packet event.

This commit is contained in:
Kristian S. Stangeland 2013-03-12 02:02:36 +01:00
parent 1bd0db20ce
commit e3cfa45607
2 changed files with 43 additions and 11 deletions

View File

@ -44,6 +44,9 @@ public class PacketEvent extends EventObject implements Cancellable {
private AsyncMarker asyncMarker; private AsyncMarker asyncMarker;
private boolean asynchronous; private boolean asynchronous;
// Whether or not a packet event is read only
private boolean readOnly;
/** /**
* Use the static constructors to create instances of this event. * Use the static constructors to create instances of this event.
* @param source - the event source. * @param source - the event source.
@ -114,6 +117,8 @@ public class PacketEvent extends EventObject implements Cancellable {
* @param packet - the packet that will be sent instead. * @param packet - the packet that will be sent instead.
*/ */
public void setPacket(PacketContainer packet) { public void setPacket(PacketContainer packet) {
if (readOnly)
throw new IllegalStateException("The packet event is read-only.");
this.packet = packet; this.packet = packet;
} }
@ -147,6 +152,8 @@ public class PacketEvent extends EventObject implements Cancellable {
* @param cancel - TRUE if it should be cancelled, FALSE otherwise. * @param cancel - TRUE if it should be cancelled, FALSE otherwise.
*/ */
public void setCancelled(boolean cancel) { public void setCancelled(boolean cancel) {
if (readOnly)
throw new IllegalStateException("The packet event is read-only.");
this.cancel = cancel; this.cancel = cancel;
} }
@ -193,9 +200,34 @@ public class PacketEvent extends EventObject implements Cancellable {
public void setAsyncMarker(AsyncMarker asyncMarker) { public void setAsyncMarker(AsyncMarker asyncMarker) {
if (isAsynchronous()) if (isAsynchronous())
throw new IllegalStateException("The marker is immutable for asynchronous events"); throw new IllegalStateException("The marker is immutable for asynchronous events");
if (readOnly)
throw new IllegalStateException("The packet event is read-only.");
this.asyncMarker = asyncMarker; this.asyncMarker = asyncMarker;
} }
/**
* Determine if the current packet event is read only.
* <p>
* This is used to ensure that a monitor listener doesn't accidentally alter the state of the event. However,
* it is still possible to modify the packet itself, as it would require too many resources to verify its integrity.
* <p>
* Thus, the packet is considered immutable if the packet event is read only.
* @return TRUE if it is, FALSE otherwise.
*/
public boolean isReadOnly() {
return readOnly;
}
/**
* Set the read-only state of this packet event.
* <p>
* This will be reset for every packet listener.
* @param readOnly - TRUE if it is read-only, FALSE otherwise.
*/
public void setReadOnly(boolean readOnly) {
this.readOnly = readOnly;
}
/** /**
* Determine if the packet event has been executed asynchronously or not. * Determine if the packet event has been executed asynchronously or not.
* @return TRUE if this packet event is asynchronous, FALSE otherwise. * @return TRUE if this packet event is asynchronous, FALSE otherwise.

View File

@ -45,6 +45,7 @@ public final class SortedPacketListenerList extends AbstractConcurrentListenerMu
// The returned list is thread-safe // The returned list is thread-safe
for (PrioritizedListener<PacketListener> element : list) { for (PrioritizedListener<PacketListener> element : list) {
try { try {
event.setReadOnly(element.getPriority() == ListenerPriority.MONITOR);
element.getListener().onPacketReceiving(event); element.getListener().onPacketReceiving(event);
} catch (Throwable e) { } catch (Throwable e) {
// Minecraft doesn't want your Exception. // Minecraft doesn't want your Exception.
@ -67,15 +68,14 @@ public final class SortedPacketListenerList extends AbstractConcurrentListenerMu
return; return;
for (PrioritizedListener<PacketListener> element : list) { for (PrioritizedListener<PacketListener> element : list) {
final PacketListener listener = element.getListener();
try { try {
if (listener.getReceivingWhitelist().getPriority() == priorityFilter) { if (element.getPriority() == priorityFilter) {
listener.onPacketReceiving(event); event.setReadOnly(element.getPriority() == ListenerPriority.MONITOR);
element.getListener().onPacketReceiving(event);
} }
} catch (Throwable e) { } catch (Throwable e) {
// Minecraft doesn't want your Exception. // Minecraft doesn't want your Exception.
reporter.reportMinimal(listener.getPlugin(), "onPacketReceiving(PacketEvent)", e, reporter.reportMinimal(element.getListener().getPlugin(), "onPacketReceiving(PacketEvent)", e,
event.getPacket().getHandle()); event.getPacket().getHandle());
} }
} }
@ -94,6 +94,7 @@ public final class SortedPacketListenerList extends AbstractConcurrentListenerMu
for (PrioritizedListener<PacketListener> element : list) { for (PrioritizedListener<PacketListener> element : list) {
try { try {
event.setReadOnly(element.getPriority() == ListenerPriority.MONITOR);
element.getListener().onPacketSending(event); element.getListener().onPacketSending(event);
} catch (Throwable e) { } catch (Throwable e) {
// Minecraft doesn't want your Exception. // Minecraft doesn't want your Exception.
@ -116,15 +117,14 @@ public final class SortedPacketListenerList extends AbstractConcurrentListenerMu
return; return;
for (PrioritizedListener<PacketListener> element : list) { for (PrioritizedListener<PacketListener> element : list) {
final PacketListener listener = element.getListener();
try { try {
if (listener.getSendingWhitelist().getPriority() == priorityFilter) { if (element.getPriority() == priorityFilter) {
listener.onPacketSending(event); event.setReadOnly(element.getPriority() == ListenerPriority.MONITOR);
element.getListener().onPacketSending(event);
} }
} catch (Throwable e) { } catch (Throwable e) {
// Minecraft doesn't want your Exception. // Minecraft doesn't want your Exception.
reporter.reportMinimal(listener.getPlugin(), "onPacketSending(PacketEvent)", e, reporter.reportMinimal(element.getListener().getPlugin(), "onPacketSending(PacketEvent)", e,
event.getPacket().getHandle()); event.getPacket().getHandle());
} }
} }