2012-10-16 07:28:54 +02:00
|
|
|
/*
|
|
|
|
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
|
|
|
* Copyright (C) 2012 Kristian S. Stangeland
|
|
|
|
*
|
2015-06-19 19:14:20 +02:00
|
|
|
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
|
|
|
* GNU General Public License as published by the Free Software Foundation; either version 2 of
|
2012-10-16 07:28:54 +02:00
|
|
|
* the License, or (at your option) any later version.
|
|
|
|
*
|
2015-06-19 19:14:20 +02:00
|
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
|
|
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
2012-10-16 07:28:54 +02:00
|
|
|
* See the GNU General Public License for more details.
|
|
|
|
*
|
2015-06-19 19:14:20 +02:00
|
|
|
* You should have received a copy of the GNU General Public License along with this program;
|
|
|
|
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
2012-10-16 07:28:54 +02:00
|
|
|
* 02111-1307 USA
|
|
|
|
*/
|
|
|
|
|
|
|
|
package com.comphenix.protocol.events;
|
|
|
|
|
2022-07-24 17:02:56 +02:00
|
|
|
import java.io.IOException;
|
|
|
|
import java.io.ObjectInputStream;
|
|
|
|
import java.io.ObjectOutputStream;
|
|
|
|
import java.lang.ref.WeakReference;
|
|
|
|
import java.util.EventObject;
|
|
|
|
|
2013-12-04 04:17:02 +01:00
|
|
|
import com.comphenix.protocol.PacketType;
|
2014-03-30 00:50:45 +01:00
|
|
|
import com.comphenix.protocol.ProtocolLibrary;
|
2012-10-16 07:28:54 +02:00
|
|
|
import com.comphenix.protocol.async.AsyncMarker;
|
2016-05-03 04:04:10 +02:00
|
|
|
import com.comphenix.protocol.error.PluginContext;
|
2014-03-30 00:50:45 +01:00
|
|
|
import com.comphenix.protocol.error.Report;
|
|
|
|
import com.comphenix.protocol.error.ReportType;
|
2022-03-08 04:09:04 +01:00
|
|
|
import com.comphenix.protocol.injector.temporary.TemporaryPlayer;
|
2014-03-22 23:21:57 +01:00
|
|
|
import com.google.common.base.Objects;
|
2013-07-17 03:52:27 +02:00
|
|
|
import com.google.common.base.Preconditions;
|
2014-03-30 00:50:45 +01:00
|
|
|
import com.google.common.collect.HashMultimap;
|
|
|
|
import com.google.common.collect.Multimaps;
|
|
|
|
import com.google.common.collect.SetMultimap;
|
2022-07-24 17:02:56 +02:00
|
|
|
|
2022-03-08 04:09:04 +01:00
|
|
|
import org.bukkit.Bukkit;
|
|
|
|
import org.bukkit.entity.Player;
|
|
|
|
import org.bukkit.event.Cancellable;
|
2012-10-16 07:28:54 +02:00
|
|
|
|
2014-03-30 00:50:45 +01:00
|
|
|
/**
|
2022-03-08 04:09:04 +01:00
|
|
|
* Represents a packet sending or receiving event. Changes to the packet will be reflected in the final version to be
|
|
|
|
* sent or received. It is also possible to cancel an event.
|
|
|
|
*
|
2014-03-30 00:50:45 +01:00
|
|
|
* @author Kristian
|
|
|
|
*/
|
2012-10-16 07:28:54 +02:00
|
|
|
public class PacketEvent extends EventObject implements Cancellable {
|
2022-03-08 04:09:04 +01:00
|
|
|
|
2014-03-30 00:50:45 +01:00
|
|
|
public static final ReportType REPORT_CHANGING_PACKET_TYPE_IS_CONFUSING = new ReportType(
|
|
|
|
"Plugin %s changed packet type from %s to %s in packet listener. This is confusing for other plugins! (Not an error, though!)");
|
2022-03-08 04:09:04 +01:00
|
|
|
|
2015-06-19 19:14:20 +02:00
|
|
|
private static final SetMultimap<PacketType, PacketType> CHANGE_WARNINGS =
|
2019-08-07 17:34:59 +02:00
|
|
|
Multimaps.synchronizedSetMultimap(HashMultimap.create());
|
2022-03-08 04:09:04 +01:00
|
|
|
|
2012-10-16 07:28:54 +02:00
|
|
|
/**
|
|
|
|
* Automatically generated by Eclipse.
|
|
|
|
*/
|
|
|
|
private static final long serialVersionUID = -5360289379097430620L;
|
2022-03-08 04:09:04 +01:00
|
|
|
// Network input and output handlers
|
|
|
|
NetworkMarker networkMarker;
|
2012-11-20 03:23:43 +01:00
|
|
|
private transient WeakReference<Player> playerReference;
|
2012-10-16 07:28:54 +02:00
|
|
|
private PacketContainer packet;
|
|
|
|
private boolean serverPacket;
|
|
|
|
private boolean cancel;
|
|
|
|
private AsyncMarker asyncMarker;
|
|
|
|
private boolean asynchronous;
|
2013-03-12 02:02:36 +01:00
|
|
|
// Whether or not a packet event is read only
|
|
|
|
private boolean readOnly;
|
2014-04-25 02:55:17 +02:00
|
|
|
private boolean filtered;
|
2022-03-08 04:09:04 +01:00
|
|
|
|
2012-10-16 07:28:54 +02:00
|
|
|
/**
|
|
|
|
* Use the static constructors to create instances of this event.
|
2022-03-08 04:09:04 +01:00
|
|
|
*
|
2012-10-16 07:28:54 +02:00
|
|
|
* @param source - the event source.
|
|
|
|
*/
|
|
|
|
public PacketEvent(Object source) {
|
|
|
|
super(source);
|
2014-04-25 02:55:17 +02:00
|
|
|
this.filtered = true;
|
2012-10-16 07:28:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
private PacketEvent(Object source, PacketContainer packet, Player player, boolean serverPacket) {
|
2014-04-25 02:55:17 +02:00
|
|
|
this(source, packet, null, player, serverPacket, true);
|
2013-07-17 03:52:27 +02:00
|
|
|
}
|
2022-03-08 04:09:04 +01:00
|
|
|
|
|
|
|
private PacketEvent(Object source, PacketContainer packet, NetworkMarker marker, Player player, boolean serverPacket,
|
|
|
|
boolean filtered) {
|
2012-10-16 07:28:54 +02:00
|
|
|
super(source);
|
|
|
|
this.packet = packet;
|
2019-08-07 17:34:59 +02:00
|
|
|
this.playerReference = new WeakReference<>(player);
|
2013-07-17 03:52:27 +02:00
|
|
|
this.networkMarker = marker;
|
2012-10-16 07:28:54 +02:00
|
|
|
this.serverPacket = serverPacket;
|
2014-04-25 02:55:17 +02:00
|
|
|
this.filtered = filtered;
|
2012-10-16 07:28:54 +02:00
|
|
|
}
|
2022-03-08 04:09:04 +01:00
|
|
|
|
2012-10-16 07:28:54 +02:00
|
|
|
private PacketEvent(PacketEvent origial, AsyncMarker asyncMarker) {
|
|
|
|
super(origial.source);
|
|
|
|
this.packet = origial.packet;
|
2019-08-07 17:34:59 +02:00
|
|
|
this.playerReference = origial.getPlayerReference();
|
2012-10-16 07:28:54 +02:00
|
|
|
this.cancel = origial.cancel;
|
|
|
|
this.serverPacket = origial.serverPacket;
|
2014-04-25 02:55:17 +02:00
|
|
|
this.filtered = origial.filtered;
|
2014-04-26 00:20:50 +02:00
|
|
|
this.networkMarker = origial.networkMarker;
|
2012-10-16 07:28:54 +02:00
|
|
|
this.asyncMarker = asyncMarker;
|
|
|
|
this.asynchronous = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Creates an event representing a client packet transmission.
|
2022-03-08 04:09:04 +01:00
|
|
|
*
|
2012-10-16 07:28:54 +02:00
|
|
|
* @param source - the event source.
|
|
|
|
* @param packet - the packet.
|
|
|
|
* @param client - the client that sent the packet.
|
|
|
|
* @return The event.
|
|
|
|
*/
|
|
|
|
public static PacketEvent fromClient(Object source, PacketContainer packet, Player client) {
|
|
|
|
return new PacketEvent(source, packet, client, false);
|
|
|
|
}
|
2022-03-08 04:09:04 +01:00
|
|
|
|
2013-07-17 03:52:27 +02:00
|
|
|
/**
|
|
|
|
* Creates an event representing a client packet transmission.
|
2022-03-08 04:09:04 +01:00
|
|
|
*
|
2013-07-17 03:52:27 +02:00
|
|
|
* @param source - the event source.
|
|
|
|
* @param packet - the packet.
|
|
|
|
* @param marker - the network marker.
|
|
|
|
* @param client - the client that sent the packet.
|
|
|
|
* @return The event.
|
|
|
|
*/
|
|
|
|
public static PacketEvent fromClient(Object source, PacketContainer packet, NetworkMarker marker, Player client) {
|
2014-04-25 02:55:17 +02:00
|
|
|
return new PacketEvent(source, packet, marker, client, false, true);
|
|
|
|
}
|
2022-03-08 04:09:04 +01:00
|
|
|
|
2014-04-25 02:55:17 +02:00
|
|
|
/**
|
|
|
|
* Creates an event representing a client packet transmission.
|
|
|
|
* <p>
|
|
|
|
* If <i>filtered</i> is FALSE, then this event is only processed by packet monitors.
|
2022-03-08 04:09:04 +01:00
|
|
|
*
|
|
|
|
* @param source - the event source.
|
|
|
|
* @param packet - the packet.
|
|
|
|
* @param marker - the network marker.
|
|
|
|
* @param client - the client that sent the packet.
|
2014-04-25 02:55:17 +02:00
|
|
|
* @param filtered - whether or not this packet event is processed by every packet listener.
|
|
|
|
* @return The event.
|
|
|
|
*/
|
2022-03-08 04:09:04 +01:00
|
|
|
public static PacketEvent fromClient(Object source, PacketContainer packet, NetworkMarker marker, Player client,
|
|
|
|
boolean filtered) {
|
2014-04-25 02:55:17 +02:00
|
|
|
return new PacketEvent(source, packet, marker, client, false, filtered);
|
2013-07-17 03:52:27 +02:00
|
|
|
}
|
2022-03-08 04:09:04 +01:00
|
|
|
|
2012-10-16 07:28:54 +02:00
|
|
|
/**
|
|
|
|
* Creates an event representing a server packet transmission.
|
2022-03-08 04:09:04 +01:00
|
|
|
*
|
|
|
|
* @param source - the event source.
|
|
|
|
* @param packet - the packet.
|
2012-10-16 07:28:54 +02:00
|
|
|
* @param recipient - the client that will receieve the packet.
|
|
|
|
* @return The event.
|
|
|
|
*/
|
2022-03-08 04:09:04 +01:00
|
|
|
public static PacketEvent fromServer(Object source, PacketContainer packet, Player recipient) {
|
2012-10-16 07:28:54 +02:00
|
|
|
return new PacketEvent(source, packet, recipient, true);
|
|
|
|
}
|
2022-03-08 04:09:04 +01:00
|
|
|
|
2013-07-17 03:52:27 +02:00
|
|
|
/**
|
|
|
|
* Creates an event representing a server packet transmission.
|
2022-03-08 04:09:04 +01:00
|
|
|
*
|
|
|
|
* @param source - the event source.
|
|
|
|
* @param packet - the packet.
|
|
|
|
* @param marker - the network marker.
|
2013-07-17 03:52:27 +02:00
|
|
|
* @param recipient - the client that will receieve the packet.
|
|
|
|
* @return The event.
|
|
|
|
*/
|
|
|
|
public static PacketEvent fromServer(Object source, PacketContainer packet, NetworkMarker marker, Player recipient) {
|
2014-04-25 02:55:17 +02:00
|
|
|
return new PacketEvent(source, packet, marker, recipient, true, true);
|
|
|
|
}
|
2022-03-08 04:09:04 +01:00
|
|
|
|
2014-04-25 02:55:17 +02:00
|
|
|
/**
|
|
|
|
* Creates an event representing a server packet transmission.
|
|
|
|
* <p>
|
|
|
|
* If <i>filtered</i> is FALSE, then this event is only processed by packet monitors.
|
2022-03-08 04:09:04 +01:00
|
|
|
*
|
|
|
|
* @param source - the event source.
|
|
|
|
* @param packet - the packet.
|
|
|
|
* @param marker - the network marker.
|
2014-04-25 02:55:17 +02:00
|
|
|
* @param recipient - the client that will receieve the packet.
|
2022-03-08 04:09:04 +01:00
|
|
|
* @param filtered - whether or not this packet event is processed by every packet listener.
|
2014-04-25 02:55:17 +02:00
|
|
|
* @return The event.
|
|
|
|
*/
|
2022-03-08 04:09:04 +01:00
|
|
|
public static PacketEvent fromServer(Object source, PacketContainer packet, NetworkMarker marker, Player recipient,
|
|
|
|
boolean filtered) {
|
2014-04-25 02:55:17 +02:00
|
|
|
return new PacketEvent(source, packet, marker, recipient, true, filtered);
|
2013-07-17 03:52:27 +02:00
|
|
|
}
|
2022-03-08 04:09:04 +01:00
|
|
|
|
2012-10-16 07:28:54 +02:00
|
|
|
/**
|
|
|
|
* Create an asynchronous packet event from a synchronous event and a async marker.
|
2022-03-08 04:09:04 +01:00
|
|
|
*
|
|
|
|
* @param event - the original synchronous event.
|
2012-10-16 07:28:54 +02:00
|
|
|
* @param marker - the asynchronous marker.
|
|
|
|
* @return The new packet event.
|
|
|
|
*/
|
|
|
|
public static PacketEvent fromSynchronous(PacketEvent event, AsyncMarker marker) {
|
|
|
|
return new PacketEvent(event, marker);
|
|
|
|
}
|
2022-03-08 04:09:04 +01:00
|
|
|
|
2013-12-06 01:21:35 +01:00
|
|
|
/**
|
|
|
|
* Determine if we are executing the packet event in an asynchronous thread.
|
|
|
|
* <p>
|
|
|
|
* If so, you must synchronize all calls to the Bukkit API.
|
|
|
|
* <p>
|
2022-03-08 04:09:04 +01:00
|
|
|
* Generally, most server packets are executed on the main thread, whereas client packets are all executed
|
|
|
|
* asynchronously.
|
|
|
|
*
|
2013-12-06 01:21:35 +01:00
|
|
|
* @return TRUE if we are, FALSE otherwise.
|
|
|
|
*/
|
|
|
|
public boolean isAsync() {
|
2016-03-19 21:01:38 +01:00
|
|
|
return !Bukkit.isPrimaryThread();
|
2013-12-06 01:21:35 +01:00
|
|
|
}
|
2022-03-08 04:09:04 +01:00
|
|
|
|
2012-10-16 07:28:54 +02:00
|
|
|
/**
|
|
|
|
* Retrieves the packet that will be sent to the player.
|
2022-03-08 04:09:04 +01:00
|
|
|
*
|
2012-10-16 07:28:54 +02:00
|
|
|
* @return Packet to send to the player.
|
|
|
|
*/
|
|
|
|
public PacketContainer getPacket() {
|
|
|
|
return packet;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Replace the packet that will be sent to the player.
|
2022-03-08 04:09:04 +01:00
|
|
|
*
|
2012-10-16 07:28:54 +02:00
|
|
|
* @param packet - the packet that will be sent instead.
|
|
|
|
*/
|
|
|
|
public void setPacket(PacketContainer packet) {
|
2022-03-08 04:09:04 +01:00
|
|
|
if (readOnly) {
|
2013-03-12 02:02:36 +01:00
|
|
|
throw new IllegalStateException("The packet event is read-only.");
|
2022-03-08 04:09:04 +01:00
|
|
|
}
|
|
|
|
if (packet == null) {
|
2014-03-22 23:20:16 +01:00
|
|
|
throw new IllegalArgumentException("Cannot set packet to NULL. Use setCancelled() instead.");
|
2022-03-08 04:09:04 +01:00
|
|
|
}
|
|
|
|
|
2014-03-30 00:50:45 +01:00
|
|
|
// Change warnings
|
|
|
|
final PacketType oldType = this.packet.getType();
|
|
|
|
final PacketType newType = packet.getType();
|
|
|
|
if (this.packet != null && !Objects.equal(oldType, newType)) {
|
|
|
|
// Only report this once
|
|
|
|
if (CHANGE_WARNINGS.put(oldType, newType)) {
|
2015-06-19 19:14:20 +02:00
|
|
|
ProtocolLibrary.getErrorReporter().reportWarning(this,
|
2014-03-30 00:50:45 +01:00
|
|
|
Report.newBuilder(REPORT_CHANGING_PACKET_TYPE_IS_CONFUSING).
|
2022-03-08 04:09:04 +01:00
|
|
|
messageParam(PluginContext.getPluginCaller(new Exception()), oldType, newType).
|
|
|
|
build());
|
2014-03-30 00:50:45 +01:00
|
|
|
}
|
|
|
|
}
|
2012-10-16 07:28:54 +02:00
|
|
|
this.packet = packet;
|
|
|
|
}
|
2022-03-08 04:09:04 +01:00
|
|
|
|
2012-10-16 07:28:54 +02:00
|
|
|
/**
|
|
|
|
* Retrieves the packet ID.
|
2013-12-04 04:17:02 +01:00
|
|
|
* <p>
|
|
|
|
* Deprecated: Use {@link #getPacketType()} instead.
|
2022-03-08 04:09:04 +01:00
|
|
|
*
|
2012-10-16 07:28:54 +02:00
|
|
|
* @return The current packet ID.
|
|
|
|
*/
|
2013-12-04 04:17:02 +01:00
|
|
|
@Deprecated
|
2012-10-16 07:28:54 +02:00
|
|
|
public int getPacketID() {
|
2020-06-06 21:13:29 +02:00
|
|
|
return packet.getId();
|
2012-10-16 07:28:54 +02:00
|
|
|
}
|
2022-03-08 04:09:04 +01:00
|
|
|
|
2013-12-04 04:17:02 +01:00
|
|
|
/**
|
|
|
|
* Retrieve the packet type.
|
2022-03-08 04:09:04 +01:00
|
|
|
*
|
2013-12-04 04:17:02 +01:00
|
|
|
* @return The type.
|
|
|
|
*/
|
|
|
|
public PacketType getPacketType() {
|
|
|
|
return packet.getType();
|
|
|
|
}
|
2022-03-08 04:09:04 +01:00
|
|
|
|
2012-10-16 07:28:54 +02:00
|
|
|
/**
|
|
|
|
* Retrieves whether or not the packet should be cancelled.
|
2022-03-08 04:09:04 +01:00
|
|
|
*
|
2012-10-16 07:28:54 +02:00
|
|
|
* @return TRUE if it should be cancelled, FALSE otherwise.
|
|
|
|
*/
|
2015-06-19 19:14:20 +02:00
|
|
|
@Override
|
2012-10-16 07:28:54 +02:00
|
|
|
public boolean isCancelled() {
|
|
|
|
return cancel;
|
|
|
|
}
|
2022-03-08 04:09:04 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets whether or not the packet should be cancelled. Uncancelling is possible.
|
|
|
|
* <p>
|
|
|
|
* <b>Warning</b>: A cancelled packet should never be re-transmitted. Use the asynchronous
|
|
|
|
* packet manager if you need to perform extensive processing. It should also be used if you need to synchronize with
|
|
|
|
* the main thread.
|
|
|
|
* <p>
|
|
|
|
* This ensures that other plugins can work with the same packet.
|
|
|
|
* <p>
|
|
|
|
* An asynchronous listener can also delay a packet indefinitely without having to block its thread.
|
|
|
|
*
|
|
|
|
* @param cancel - TRUE if it should be cancelled, FALSE otherwise.
|
|
|
|
*/
|
|
|
|
@Override
|
|
|
|
public void setCancelled(boolean cancel) {
|
|
|
|
if (readOnly) {
|
|
|
|
throw new IllegalStateException("The packet event is read-only.");
|
|
|
|
}
|
|
|
|
this.cancel = cancel;
|
|
|
|
}
|
|
|
|
|
2013-07-17 03:52:27 +02:00
|
|
|
/**
|
|
|
|
* Retrieve the object responsible for managing the serialized input and output of a packet.
|
|
|
|
* <p>
|
2022-03-08 04:09:04 +01:00
|
|
|
* Note that the serialized input data is only available for client-side packets, and the output handlers can only be
|
|
|
|
* applied to server-side packets.
|
|
|
|
*
|
2013-07-17 03:52:27 +02:00
|
|
|
* @return The network manager.
|
|
|
|
*/
|
|
|
|
public NetworkMarker getNetworkMarker() {
|
|
|
|
if (networkMarker == null) {
|
|
|
|
if (isServerPacket()) {
|
2022-03-08 04:09:04 +01:00
|
|
|
networkMarker = new NetworkMarker(serverPacket ? ConnectionSide.SERVER_SIDE : ConnectionSide.CLIENT_SIDE, this.getPacketType());
|
2013-07-17 03:52:27 +02:00
|
|
|
} else {
|
|
|
|
throw new IllegalStateException("Add the option ListenerOptions.INTERCEPT_INPUT_BUFFER to your listener.");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return networkMarker;
|
|
|
|
}
|
2012-10-16 07:28:54 +02:00
|
|
|
|
2013-07-17 03:52:27 +02:00
|
|
|
/**
|
|
|
|
* Update the network manager.
|
|
|
|
* <p>
|
|
|
|
* This method is internal - do not call.
|
2022-03-08 04:09:04 +01:00
|
|
|
*
|
2013-07-17 03:52:27 +02:00
|
|
|
* @param networkMarker - the new network manager.
|
|
|
|
*/
|
|
|
|
public void setNetworkMarker(NetworkMarker networkMarker) {
|
|
|
|
this.networkMarker = Preconditions.checkNotNull(networkMarker, "marker cannot be NULL");
|
|
|
|
}
|
2012-10-16 07:28:54 +02:00
|
|
|
|
2019-08-07 17:34:59 +02:00
|
|
|
private WeakReference<Player> getPlayerReference() {
|
2017-07-06 19:56:30 +02:00
|
|
|
Player player = playerReference.get();
|
|
|
|
|
|
|
|
if (player instanceof TemporaryPlayer) {
|
|
|
|
Player updated = player.getPlayer();
|
|
|
|
if (updated != null && !(updated instanceof TemporaryPlayer)) {
|
|
|
|
playerReference.clear();
|
|
|
|
playerReference = new WeakReference<>(updated);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-07 17:34:59 +02:00
|
|
|
return playerReference;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Retrieves the player that has sent the packet or is receiving it.
|
2022-03-08 04:09:04 +01:00
|
|
|
*
|
2019-08-07 17:34:59 +02:00
|
|
|
* @return The player associated with this event.
|
|
|
|
*/
|
|
|
|
public Player getPlayer() {
|
|
|
|
return getPlayerReference().get();
|
2017-07-06 19:56:30 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Whether or not the player in this PacketEvent is temporary (i.e. they don't have a true player instance yet).
|
|
|
|
* Temporary players have a limited subset of methods that may be used:
|
|
|
|
* <ul>
|
|
|
|
* <li>getPlayer</li>
|
|
|
|
* <li>getAddress</li>
|
|
|
|
* <li>getServer</li>
|
|
|
|
* <li>chat</li>
|
|
|
|
* <li>sendMessage</li>
|
|
|
|
* <li>kickPlayer</li>
|
|
|
|
* <li>isOnline</li>
|
|
|
|
* </ul>
|
2022-03-08 04:09:04 +01:00
|
|
|
* <p>
|
2017-07-06 19:56:30 +02:00
|
|
|
* Anything else will throw an UnsupportedOperationException. Use this check before calling other methods when
|
|
|
|
* dealing with packets early in the login sequence or if you get the aforementioned exception.
|
|
|
|
*
|
|
|
|
* @return True if the player is temporary, false if not.
|
|
|
|
*/
|
|
|
|
public boolean isPlayerTemporary() {
|
|
|
|
return getPlayer() instanceof TemporaryPlayer;
|
2012-10-16 07:28:54 +02:00
|
|
|
}
|
2022-03-08 04:09:04 +01:00
|
|
|
|
2014-04-25 02:55:17 +02:00
|
|
|
/**
|
|
|
|
* Determine if this packet is filtered by every packet listener.
|
|
|
|
* <p>
|
|
|
|
* If not, it will only be intercepted by monitor packets.
|
2022-03-08 04:09:04 +01:00
|
|
|
*
|
2014-04-25 02:55:17 +02:00
|
|
|
* @return TRUE if it is, FALSE otherwise.
|
|
|
|
*/
|
|
|
|
public boolean isFiltered() {
|
|
|
|
return filtered;
|
|
|
|
}
|
2022-03-08 04:09:04 +01:00
|
|
|
|
2012-10-16 07:28:54 +02:00
|
|
|
/**
|
|
|
|
* Whether or not this packet was created by the server.
|
|
|
|
* <p>
|
|
|
|
* Most listeners can deduce this by noting which listener method was invoked.
|
2022-03-08 04:09:04 +01:00
|
|
|
*
|
2012-10-16 07:28:54 +02:00
|
|
|
* @return TRUE if the packet was created by the server, FALSE if it was created by a client.
|
|
|
|
*/
|
|
|
|
public boolean isServerPacket() {
|
|
|
|
return serverPacket;
|
|
|
|
}
|
2022-03-08 04:09:04 +01:00
|
|
|
|
2012-10-16 07:28:54 +02:00
|
|
|
/**
|
|
|
|
* Retrieve the asynchronous marker.
|
|
|
|
* <p>
|
|
|
|
* If the packet is synchronous, this marker will be used to schedule an asynchronous event. In the following
|
|
|
|
* asynchronous event, the marker is used to correctly pass the packet around to the different threads.
|
|
|
|
* <p>
|
|
|
|
* Note that if there are no asynchronous events that can receive this packet, the marker is NULL.
|
2022-03-08 04:09:04 +01:00
|
|
|
*
|
2012-10-16 07:28:54 +02:00
|
|
|
* @return The current asynchronous marker, or NULL.
|
|
|
|
*/
|
|
|
|
public AsyncMarker getAsyncMarker() {
|
|
|
|
return asyncMarker;
|
|
|
|
}
|
2022-03-08 04:09:04 +01:00
|
|
|
|
2012-10-16 07:28:54 +02:00
|
|
|
/**
|
2015-06-19 19:14:20 +02:00
|
|
|
* Set the asynchronous marker.
|
2012-10-16 07:28:54 +02:00
|
|
|
* <p>
|
2022-03-08 04:09:04 +01:00
|
|
|
* If the marker is non-null at the end of an synchronous event processing, the packet will be scheduled to be
|
|
|
|
* processed asynchronously with the given settings.
|
2012-10-16 07:28:54 +02:00
|
|
|
* <p>
|
2015-06-19 19:14:20 +02:00
|
|
|
* Note that if there are no asynchronous events that can receive this packet, the marker should be NULL.
|
2022-03-08 04:09:04 +01:00
|
|
|
*
|
2012-10-16 07:28:54 +02:00
|
|
|
* @param asyncMarker - the new asynchronous marker, or NULL.
|
|
|
|
* @throws IllegalStateException If the current event is asynchronous.
|
|
|
|
*/
|
|
|
|
public void setAsyncMarker(AsyncMarker asyncMarker) {
|
2022-03-08 04:09:04 +01:00
|
|
|
if (isAsynchronous()) {
|
2012-10-16 07:28:54 +02:00
|
|
|
throw new IllegalStateException("The marker is immutable for asynchronous events");
|
2022-03-08 04:09:04 +01:00
|
|
|
}
|
|
|
|
if (readOnly) {
|
2013-03-12 02:02:36 +01:00
|
|
|
throw new IllegalStateException("The packet event is read-only.");
|
2022-03-08 04:09:04 +01:00
|
|
|
}
|
2012-10-16 07:28:54 +02:00
|
|
|
this.asyncMarker = asyncMarker;
|
|
|
|
}
|
|
|
|
|
2013-03-12 02:02:36 +01:00
|
|
|
/**
|
|
|
|
* Determine if the current packet event is read only.
|
|
|
|
* <p>
|
2022-03-08 04:09:04 +01:00
|
|
|
* 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.
|
2013-03-12 02:02:36 +01:00
|
|
|
* <p>
|
|
|
|
* Thus, the packet is considered immutable if the packet event is read only.
|
2022-03-08 04:09:04 +01:00
|
|
|
*
|
2013-03-12 02:02:36 +01:00
|
|
|
* @return TRUE if it is, FALSE otherwise.
|
|
|
|
*/
|
|
|
|
public boolean isReadOnly() {
|
|
|
|
return readOnly;
|
|
|
|
}
|
2022-03-08 04:09:04 +01:00
|
|
|
|
2013-03-12 02:02:36 +01:00
|
|
|
/**
|
|
|
|
* Set the read-only state of this packet event.
|
|
|
|
* <p>
|
|
|
|
* This will be reset for every packet listener.
|
2022-03-08 04:09:04 +01:00
|
|
|
*
|
2013-03-12 02:02:36 +01:00
|
|
|
* @param readOnly - TRUE if it is read-only, FALSE otherwise.
|
|
|
|
*/
|
|
|
|
public void setReadOnly(boolean readOnly) {
|
|
|
|
this.readOnly = readOnly;
|
|
|
|
}
|
2022-03-08 04:09:04 +01:00
|
|
|
|
2012-10-16 07:28:54 +02:00
|
|
|
/**
|
|
|
|
* Determine if the packet event has been executed asynchronously or not.
|
2022-03-08 04:09:04 +01:00
|
|
|
*
|
2012-10-16 07:28:54 +02:00
|
|
|
* @return TRUE if this packet event is asynchronous, FALSE otherwise.
|
|
|
|
*/
|
|
|
|
public boolean isAsynchronous() {
|
|
|
|
return asynchronous;
|
|
|
|
}
|
2013-03-12 02:02:36 +01:00
|
|
|
|
2014-04-26 00:20:50 +02:00
|
|
|
/**
|
|
|
|
* Schedule a packet for sending or receiving after the current packet event is successful.
|
|
|
|
* <p>
|
|
|
|
* The packet will be added to {@link NetworkMarker#getScheduledPackets()}.
|
2022-03-08 04:09:04 +01:00
|
|
|
*
|
2014-04-26 00:20:50 +02:00
|
|
|
* @param scheduled - the packet to transmit or receive.
|
|
|
|
*/
|
|
|
|
public void schedule(ScheduledPacket scheduled) {
|
|
|
|
getNetworkMarker().getScheduledPackets().add(scheduled);
|
|
|
|
}
|
2022-03-08 04:09:04 +01:00
|
|
|
|
2014-04-26 00:20:50 +02:00
|
|
|
/**
|
|
|
|
* Unschedule a specific packet.
|
2022-03-08 04:09:04 +01:00
|
|
|
*
|
2014-04-26 00:20:50 +02:00
|
|
|
* @param scheduled - the scheduled packet.
|
|
|
|
* @return TRUE if it was unscheduled, FALSE otherwise.
|
|
|
|
*/
|
|
|
|
public boolean unschedule(ScheduledPacket scheduled) {
|
|
|
|
if (networkMarker != null) {
|
|
|
|
return networkMarker.getScheduledPackets().remove(scheduled);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2022-03-08 04:09:04 +01:00
|
|
|
|
2012-10-16 07:28:54 +02:00
|
|
|
private void writeObject(ObjectOutputStream output) throws IOException {
|
2022-03-08 04:09:04 +01:00
|
|
|
// Default serialization
|
2012-10-16 07:28:54 +02:00
|
|
|
output.defaultWriteObject();
|
|
|
|
|
|
|
|
// Write the name of the player (or NULL if it's not set)
|
2019-08-07 17:34:59 +02:00
|
|
|
Player player = getPlayer();
|
|
|
|
output.writeObject(player != null ? new SerializedOfflinePlayer(player) : null);
|
2012-10-16 07:28:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
private void readObject(ObjectInputStream input) throws ClassNotFoundException, IOException {
|
2022-03-08 04:09:04 +01:00
|
|
|
// Default deserialization
|
2012-10-16 07:28:54 +02:00
|
|
|
input.defaultReadObject();
|
|
|
|
|
2012-11-20 03:23:43 +01:00
|
|
|
final SerializedOfflinePlayer serialized = (SerializedOfflinePlayer) input.readObject();
|
2022-03-08 04:09:04 +01:00
|
|
|
|
2012-11-20 03:23:43 +01:00
|
|
|
// Better than nothing
|
2022-03-08 04:09:04 +01:00
|
|
|
if (serialized != null) {
|
|
|
|
// Store it, to prevent weak reference from cleaning up the reference
|
|
|
|
Player offlinePlayer = serialized.getPlayer();
|
|
|
|
playerReference = new WeakReference<>(offlinePlayer);
|
|
|
|
}
|
2012-10-16 07:28:54 +02:00
|
|
|
}
|
2015-06-19 19:14:20 +02:00
|
|
|
|
|
|
|
@Override
|
|
|
|
public String toString() {
|
|
|
|
return "PacketEvent[player=" + getPlayer() + ", packet=" + packet + "]";
|
|
|
|
}
|
2016-05-21 23:37:13 +02:00
|
|
|
}
|