Add conversion methods to WirePacket
Dieser Commit ist enthalten in:
Ursprung
242b25eb1e
Commit
26c29d9c85
@ -16,30 +16,71 @@
|
|||||||
*/
|
*/
|
||||||
package com.comphenix.protocol.injector.netty;
|
package com.comphenix.protocol.injector.netty;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
import com.comphenix.protocol.PacketType;
|
||||||
|
import com.comphenix.protocol.events.PacketContainer;
|
||||||
|
import com.comphenix.protocol.utility.MinecraftMethods;
|
||||||
|
import com.comphenix.protocol.utility.MinecraftReflection;
|
||||||
|
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.buffer.Unpooled;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* A packet represented only by its id and bytes.
|
||||||
* @author dmulloy2
|
* @author dmulloy2
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class WirePacket {
|
public class WirePacket {
|
||||||
private final int id;
|
private final int id;
|
||||||
private final byte[] bytes;
|
private final byte[] bytes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new WirePacket with a given type and contents
|
||||||
|
* @param type Type of the packet
|
||||||
|
* @param bytes Contents of the packet
|
||||||
|
*/
|
||||||
|
public WirePacket(PacketType type, byte[] bytes) {
|
||||||
|
this.id = checkNotNull(type, "type cannot be null").getCurrentId();
|
||||||
|
this.bytes = bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new WirePacket with a given id and contents
|
||||||
|
* @param id ID of the packet
|
||||||
|
* @param bytes Contents of the packet
|
||||||
|
*/
|
||||||
public WirePacket(int id, byte[] bytes) {
|
public WirePacket(int id, byte[] bytes) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.bytes = bytes;
|
this.bytes = bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets this packet's ID
|
||||||
|
* @return The ID
|
||||||
|
*/
|
||||||
public int getId() {
|
public int getId() {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets this packet's contents as a byte array
|
||||||
|
* @return The contents
|
||||||
|
*/
|
||||||
public byte[] getBytes() {
|
public byte[] getBytes() {
|
||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes the id of this packet to a given output
|
||||||
|
* @param output Output to write to
|
||||||
|
*/
|
||||||
public void writeId(ByteBuf output) {
|
public void writeId(ByteBuf output) {
|
||||||
|
checkNotNull(output, "output cannot be null!");
|
||||||
|
// From PacketDataSerializer#d(int)
|
||||||
|
|
||||||
int i = id;
|
int i = id;
|
||||||
while ((i & -128) != 0) {
|
while ((i & -128) != 0) {
|
||||||
output.writeByte(i & 127 | 128);
|
output.writeByte(i & 127 | 128);
|
||||||
@ -49,7 +90,78 @@ public class WirePacket {
|
|||||||
output.writeByte(i);
|
output.writeByte(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes the contents of this packet to a given output
|
||||||
|
* @param output Output to write to
|
||||||
|
*/
|
||||||
public void writeBytes(ByteBuf output) {
|
public void writeBytes(ByteBuf output) {
|
||||||
|
checkNotNull(output, "output cannot be null!");
|
||||||
output.writeBytes(bytes);
|
output.writeBytes(bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fully writes the ID and contents of this packet to a given output
|
||||||
|
* @param output Output to write to
|
||||||
|
*/
|
||||||
|
public void writeFully(ByteBuf output) {
|
||||||
|
writeId(output);
|
||||||
|
writeBytes(output);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serializes this packet into a byte buffer
|
||||||
|
* @return The buffer
|
||||||
|
*/
|
||||||
|
public ByteBuf serialize() {
|
||||||
|
ByteBuf buffer = Unpooled.buffer();
|
||||||
|
writeFully(buffer);
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a WirePacket from an existing PacketContainer
|
||||||
|
* @param packet Existing packet
|
||||||
|
* @return The resulting WirePacket
|
||||||
|
*/
|
||||||
|
public static WirePacket fromPacket(PacketContainer packet) {
|
||||||
|
checkNotNull(packet, "packet cannot be null!");
|
||||||
|
|
||||||
|
int id = packet.getType().getCurrentId();
|
||||||
|
|
||||||
|
ByteBuf buffer = PacketContainer.createPacketBuffer();
|
||||||
|
Method write = MinecraftMethods.getPacketWriteByteBufMethod();
|
||||||
|
|
||||||
|
try {
|
||||||
|
write.invoke(packet.getHandle(), buffer);
|
||||||
|
} catch (ReflectiveOperationException ex) {
|
||||||
|
throw new RuntimeException("Failed to serialize packet contents.", ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new WirePacket(id, buffer.array());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a WirePacket from an existing Minecraft packet
|
||||||
|
* @param packet Existing Minecraft packet
|
||||||
|
* @return The resulting WirePacket
|
||||||
|
* @throws IllegalArgumentException If the packet is null or not a Minecraft packet
|
||||||
|
*/
|
||||||
|
public static WirePacket fromPacket(Object packet) {
|
||||||
|
checkNotNull(packet, "packet cannot be null!");
|
||||||
|
checkArgument(MinecraftReflection.isPacketClass(packet), "packet must be a Minecraft packet");
|
||||||
|
|
||||||
|
PacketType type = PacketType.fromClass(packet.getClass());
|
||||||
|
int id = type.getCurrentId();
|
||||||
|
|
||||||
|
ByteBuf buffer = PacketContainer.createPacketBuffer();
|
||||||
|
Method write = MinecraftMethods.getPacketWriteByteBufMethod();
|
||||||
|
|
||||||
|
try {
|
||||||
|
write.invoke(packet, buffer);
|
||||||
|
} catch (ReflectiveOperationException ex) {
|
||||||
|
throw new RuntimeException("Failed to serialize packet contents.", ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new WirePacket(id, buffer.array());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
In neuem Issue referenzieren
Einen Benutzer sperren