package com.bergerkiller.bukkit.common.protocol; import com.bergerkiller.bukkit.common.Common; import com.bergerkiller.bukkit.common.conversion.Conversion; import com.bergerkiller.bukkit.common.reflection.ClassTemplate; import com.bergerkiller.bukkit.common.reflection.FieldAccessor; import com.bergerkiller.bukkit.common.reflection.SafeField; import com.bergerkiller.bukkit.common.wrappers.DataWatcher; public class CommonPacket { private Object packet; private PacketType type; public CommonPacket(int id, boolean outGoing) { this(PacketType.getType(id, outGoing)); } public CommonPacket(PacketType packetType) { this.type = packetType; this.packet = this.type.createPacketHandle(); } public CommonPacket(Object packetHandle) { this(packetHandle, PacketType.getType(packetHandle)); } public CommonPacket(Object packetHandle, PacketType packetType) { this.type = packetType; this.packet = packetHandle; } /** * Get the packet type * * @return Packet type */ public PacketType getType() { return this.type; } /** * Get the vanilla object of the packet * * @return Vanilla object */ public Object getHandle() { return this.packet; } /** * Write data on a cusotm field in the packet * * @param fieldAccessor Custom field * @param value Value */ public <T> void write(FieldAccessor<T> fieldAccessor, T value) { fieldAccessor.set(getHandle(), value); } /** * Write data to a field by name * * @param field Field name * @param value Value */ public void write(String field, Object value) { try { SafeField.set(packet, field, value); } catch(Exception e) { e.printStackTrace(); throw new IllegalArgumentException("Invalid field name: "+field); } } /** * Write data to a field by index * * @param index Index * @param value Value * @throws IllegalArgumentException Invalid field index */ @SuppressWarnings("unchecked") public void write(int index, Object value) throws IllegalArgumentException { this.write((FieldAccessor<Object>) this.type.getFieldAt(index), value); } /** * Read data from a custom field * * @param fieldAccessor Cusotm field * @return Data */ public <T> T read(FieldAccessor<T> fieldAccessor) { return fieldAccessor.get(this.getHandle()); } /** * Read data from a field by name * * @param field Field name * @return Data */ public Object read(String field) { try { return SafeField.get(packet, field); } catch(Exception e) { e.printStackTrace(); throw new IllegalArgumentException("Invalid field name: "+field); } } /** * Read data from a field by index * * @param index Index * @return Data * @throws IllegalArgumentException Ivalid field index */ public Object read(int index) throws IllegalArgumentException { return this.read(this.type.getFieldAt(index)); } /** * Set the datawatcher from a packet * * @param datawatcher DataWatcher * @throws IllegalArgumentException no datawatcher field found */ public void setDatawatcher(DataWatcher datawatcher) throws IllegalArgumentException { write(type.getMetaDataField(), datawatcher); } /** * Get the data watcher from a packet * * @throws IllegalArgumentException no datawatcher field found * @return DataWatcher */ public Object getDatawatcher() throws IllegalArgumentException { return this.read(type.getMetaDataField()); } /** * Read an integer from a packet * * @param index Field index * @return Integer * @throws IllegalArgumentException Field index not found */ public int readInt(int index) throws IllegalArgumentException { return (Integer) read(index); } /** * Read a boolean from a packet * * @param index Field index * @return Boolean * @throws IllegalArgumentException Field index not found */ public boolean readBoolean(int index) throws IllegalArgumentException { return (Boolean) read(index); } /** * Read a byte from a packet * * @param index Field index * @return Byte * @throws IllegalArgumentException Field index not found */ public byte readByte(int index) throws IllegalArgumentException { return (Byte) read(index); } /** * Read a string from a packet * * @param index Field index * @return String * @throws IllegalArgumentException Field index not found */ public String readString(int index) throws IllegalArgumentException { return (String) read(index); } /** * Read a double from a packet * * @param index Field index * @return Double * @throws IllegalArgumentException Field index not found */ public double readDouble(int index) throws IllegalArgumentException { return (Double) read(index); } @Override public String toString() { final Object handle = getHandle(); if (handle == null) { return "null"; } PacketType type = this.getType(); try { StringBuilder builder = new StringBuilder(); builder.append(type).append(" {\n"); // Get all field accessor constants defined in the Packet Type for (SafeField<?> field : ClassTemplate.create(type).getFields()) { if (field.isStatic()) { continue; } Object fieldValue = field.get(type); if (fieldValue instanceof FieldAccessor) { // Obtain the name and value for each field final String name = field.getName(); final Object value = ((FieldAccessor<?>) fieldValue).get(handle); builder.append(" ").append(name).append(" = ").append(Conversion.toString.convert(value)).append('\n'); } } builder.append("}"); return builder.toString(); } catch (Throwable t) { } // Print the fields (error/unknown packet...) StringBuilder builder = new StringBuilder(); if (handle.getClass().getName().startsWith(Common.NMS_ROOT)) { builder.append(handle.getClass().getSimpleName()); } else { builder.append(handle.getClass().getName()); } builder.append(" {\n"); for (SafeField<?> field : ClassTemplate.create(handle).getFields()) { if (field.isStatic()) { continue; } builder.append(" ").append(field.getName()).append(" = ").append(Conversion.toString.convert(field.get(handle))).append('\n'); } builder.append("}"); return builder.toString(); } }