package net.md_5.bungee.entitymap;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import io.netty.buffer.ByteBuf;
import net.md_5.bungee.BungeeCord;
import net.md_5.bungee.UserConnection;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.protocol.DefinedPacket;
import net.md_5.bungee.protocol.ProtocolConstants;
import java.util.UUID;
class EntityMap_1_8 extends EntityMap
{
static final EntityMap_1_8 INSTANCE = new EntityMap_1_8();
EntityMap_1_8()
{
addRewrite( 0x04, ProtocolConstants.Direction.TO_CLIENT, true ); // Entity Equipment
addRewrite( 0x0A, ProtocolConstants.Direction.TO_CLIENT, true ); // Use bed
addRewrite( 0x0B, ProtocolConstants.Direction.TO_CLIENT, true ); // Animation
addRewrite( 0x0C, ProtocolConstants.Direction.TO_CLIENT, true ); // Spawn Player
addRewrite( 0x0D, ProtocolConstants.Direction.TO_CLIENT, true ); // Collect Item
addRewrite( 0x0E, ProtocolConstants.Direction.TO_CLIENT, true ); // Spawn Object
addRewrite( 0x0F, ProtocolConstants.Direction.TO_CLIENT, true ); // Spawn Mob
addRewrite( 0x10, ProtocolConstants.Direction.TO_CLIENT, true ); // Spawn Painting
addRewrite( 0x11, ProtocolConstants.Direction.TO_CLIENT, true ); // Spawn Experience Orb
addRewrite( 0x12, ProtocolConstants.Direction.TO_CLIENT, true ); // Entity Velocity
addRewrite( 0x14, ProtocolConstants.Direction.TO_CLIENT, true ); // Entity
addRewrite( 0x15, ProtocolConstants.Direction.TO_CLIENT, true ); // Entity Relative Move
addRewrite( 0x16, ProtocolConstants.Direction.TO_CLIENT, true ); // Entity Look
addRewrite( 0x17, ProtocolConstants.Direction.TO_CLIENT, true ); // Entity Look and Relative Move
addRewrite( 0x18, ProtocolConstants.Direction.TO_CLIENT, true ); // Entity Teleport
addRewrite( 0x19, ProtocolConstants.Direction.TO_CLIENT, true ); // Entity Head Look
addRewrite( 0x1A, ProtocolConstants.Direction.TO_CLIENT, false ); // Entity Status
addRewrite( 0x1B, ProtocolConstants.Direction.TO_CLIENT, false ); // Attach Entity
addRewrite( 0x1C, ProtocolConstants.Direction.TO_CLIENT, true ); // Entity Metadata
addRewrite( 0x1D, ProtocolConstants.Direction.TO_CLIENT, true ); // Entity Effect
addRewrite( 0x1E, ProtocolConstants.Direction.TO_CLIENT, true ); // Remove Entity Effect
addRewrite( 0x20, ProtocolConstants.Direction.TO_CLIENT, true ); // Entity Properties
addRewrite( 0x25, ProtocolConstants.Direction.TO_CLIENT, true ); // Block Break Animation
addRewrite( 0x2C, ProtocolConstants.Direction.TO_CLIENT, true ); // Spawn Global Entity
addRewrite( 0x43, ProtocolConstants.Direction.TO_CLIENT, true ); // Camera
addRewrite( 0x49, ProtocolConstants.Direction.TO_CLIENT, true ); // Update Entity NBT
addRewrite( 0x02, ProtocolConstants.Direction.TO_SERVER, true ); // Use Entity
addRewrite( 0x0B, ProtocolConstants.Direction.TO_SERVER, true ); // Entity Action
}
@Override
@SuppressFBWarnings("DLS_DEAD_LOCAL_STORE")
public void rewriteClientbound(ByteBuf packet, int oldId, int newId)
{
super.rewriteClientbound( packet, oldId, newId );
//Special cases
int readerIndex = packet.readerIndex();
int packetId = DefinedPacket.readVarInt( packet );
int packetIdLength = packet.readerIndex() - readerIndex;
if ( packetId == 0x0D /* Collect Item */ )
{
DefinedPacket.readVarInt( packet );
rewriteVarInt( packet, oldId, newId, packet.readerIndex() );
} else if ( packetId == 0x1B /* Attach Entity */ )
{
rewriteInt( packet, oldId, newId, readerIndex + packetIdLength + 4 );
} else if ( packetId == 0x13 /* Destroy Entities */ )
{
int count = DefinedPacket.readVarInt( packet );
int[] ids = new int[ count ];
for ( int i = 0; i < count; i++ )
{
ids[i] = DefinedPacket.readVarInt( packet );
}
packet.readerIndex( readerIndex + packetIdLength );
packet.writerIndex( readerIndex + packetIdLength );
DefinedPacket.writeVarInt( count, packet );
for ( int id : ids )
{
if ( id == oldId )
{
id = newId;
} else if ( id == newId )
{
id = oldId;
}
DefinedPacket.writeVarInt( id, packet );
}
} else if ( packetId == 0x0E /* Spawn Object */ )
{
DefinedPacket.readVarInt( packet );
int type = packet.readUnsignedByte();
if ( type == 60 || type == 90 )
{
packet.skipBytes( 14 );
int position = packet.readerIndex();
int readId = packet.readInt();
int changedId = readId;
if ( readId == oldId )
{
packet.setInt( position, changedId = newId );
} else if ( readId == newId )
{
packet.setInt( position, changedId = oldId );
}
if ( readId > 0 && changedId <= 0 )
{
packet.writerIndex( packet.writerIndex() - 6 );
} else if ( changedId > 0 && readId <= 0 )
{
packet.ensureWritable( 6 );
packet.writerIndex( packet.writerIndex() + 6 );
}
}
} else if ( packetId == 0x0C /* Spawn Player */ )
{
DefinedPacket.readVarInt( packet ); // Entity ID
int idLength = packet.readerIndex() - readerIndex - packetIdLength;
UUID uuid = DefinedPacket.readUUID( packet );
ProxiedPlayer player;
if ( ( player = BungeeCord.getInstance().getPlayerByOfflineUUID( uuid ) ) != null )
{
int previous = packet.writerIndex();
packet.readerIndex( readerIndex );
packet.writerIndex( readerIndex + packetIdLength + idLength );
DefinedPacket.writeUUID( player.getUniqueId(), packet );
packet.writerIndex( previous );
}
} else if ( packetId == 0x42 /* Combat Event */ )
{
int event = packet.readUnsignedByte();
if ( event == 1 /* End Combat*/ )
{
DefinedPacket.readVarInt( packet );
rewriteInt( packet, oldId, newId, packet.readerIndex() );
} else if ( event == 2 /* Entity Dead */ )
{
int position = packet.readerIndex();
rewriteVarInt( packet, oldId, newId, packet.readerIndex() );
packet.readerIndex( position );
DefinedPacket.readVarInt( packet );
rewriteInt( packet, oldId, newId, packet.readerIndex() );
}
}
packet.readerIndex( readerIndex );
}
@Override
public void rewriteServerbound(ByteBuf packet, int oldId, int newId)
{
super.rewriteServerbound( packet, oldId, newId );
//Special cases
int readerIndex = packet.readerIndex();
int packetId = DefinedPacket.readVarInt( packet );
int packetIdLength = packet.readerIndex() - readerIndex;
if ( packetId == 0x18 /* Spectate */ && !BungeeCord.getInstance().getConfig().isIpForward() )
{
UUID uuid = DefinedPacket.readUUID( packet );
ProxiedPlayer player;
if ( ( player = BungeeCord.getInstance().getPlayer( uuid ) ) != null )
{
int previous = packet.writerIndex();
packet.readerIndex( readerIndex );
packet.writerIndex( readerIndex + packetIdLength );
DefinedPacket.writeUUID( ( (UserConnection) player ).getPendingConnection().getOfflineId(), packet );
packet.writerIndex( previous );
}
}
packet.readerIndex( readerIndex );
}
}