/*
* This file is part of Vanilla.
*
* Copyright (c) 2011 Spout LLC <http://www.spout.org/>
* Vanilla is licensed under the Spout License Version 1.
*
* Vanilla is free software: you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option)
* any later version.
*
* In addition, 180 days after any changes are published, you can use the
* software, incorporating those changes, under the terms of the MIT license,
* as described in the Spout License Version 1.
*
* Vanilla 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. See the GNU Lesser General Public License for
* more details.
*
* You should have received a copy of the GNU Lesser General Public License,
* the MIT license and the Spout License Version 1 along with this program.
* If not, see <http://www.gnu.org/licenses/> for the GNU Lesser General Public
* License and see <http://spout.in/licensev1> for the full license, including
* the MIT license.
*/
package org.spout.vanilla.protocol;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.apache.commons.lang3.tuple.Pair;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import org.spout.api.Platform;
import org.spout.api.Spout;
import org.spout.api.command.Command;
import org.spout.api.command.CommandArguments;
import org.spout.api.component.entity.PlayerNetworkComponent;
import org.spout.api.exception.ArgumentParseException;
import org.spout.api.exception.UnknownPacketException;
import org.spout.api.map.DefaultedKey;
import org.spout.api.map.DefaultedKeyImpl;
import org.spout.api.protocol.ClientSession;
import org.spout.api.protocol.Message;
import org.spout.api.protocol.MessageCodec;
import org.spout.api.protocol.Protocol;
import org.spout.api.protocol.ServerSession;
import org.spout.api.util.Named;
import org.spout.vanilla.ChatStyle;
import org.spout.vanilla.VanillaPlugin;
import org.spout.vanilla.component.entity.player.VanillaPlayerNetworkComponent;
import org.spout.vanilla.protocol.codec.auth.EncryptionKeyRequestCodec;
import org.spout.vanilla.protocol.codec.auth.EncryptionKeyResponseCodec;
import org.spout.vanilla.protocol.codec.entity.EntityActionCodec;
import org.spout.vanilla.protocol.codec.entity.EntityAnimationCodec;
import org.spout.vanilla.protocol.codec.entity.EntityAttachEntityCodec;
import org.spout.vanilla.protocol.codec.entity.EntityDestroyCodec;
import org.spout.vanilla.protocol.codec.entity.EntityEquipmentCodec;
import org.spout.vanilla.protocol.codec.entity.EntityInitializeCodec;
import org.spout.vanilla.protocol.codec.entity.EntityItemDataCodec;
import org.spout.vanilla.protocol.codec.entity.EntityMetadataCodec;
import org.spout.vanilla.protocol.codec.entity.EntityPropertiesCodec;
import org.spout.vanilla.protocol.codec.entity.EntityRelativePositionCodec;
import org.spout.vanilla.protocol.codec.entity.EntityStatusCodec;
import org.spout.vanilla.protocol.codec.entity.EntityTileDataCodec;
import org.spout.vanilla.protocol.codec.entity.SteerVehicleCodec;
import org.spout.vanilla.protocol.codec.entity.effect.EntityEffectCodec;
import org.spout.vanilla.protocol.codec.entity.effect.EntityRemoveEffectCodec;
import org.spout.vanilla.protocol.codec.entity.pos.EntityHeadYawCodec;
import org.spout.vanilla.protocol.codec.entity.pos.EntityRelativePositionYawCodec;
import org.spout.vanilla.protocol.codec.entity.pos.EntityTeleportCodec;
import org.spout.vanilla.protocol.codec.entity.pos.EntityVelocityCodec;
import org.spout.vanilla.protocol.codec.entity.pos.EntityYawCodec;
import org.spout.vanilla.protocol.codec.entity.spawn.EntityExperienceOrbCodec;
import org.spout.vanilla.protocol.codec.entity.spawn.EntityMobCodec;
import org.spout.vanilla.protocol.codec.entity.spawn.EntityPaintingCodec;
import org.spout.vanilla.protocol.codec.entity.spawn.EntitySpawnObjectCodec;
import org.spout.vanilla.protocol.codec.entity.spawn.EntityThunderboltCodec;
import org.spout.vanilla.protocol.codec.player.PlayerAbilityCodec;
import org.spout.vanilla.protocol.codec.player.PlayerBedCodec;
import org.spout.vanilla.protocol.codec.player.PlayerBlockPlacementCodec;
import org.spout.vanilla.protocol.codec.player.PlayerChatCodec;
import org.spout.vanilla.protocol.codec.player.PlayerCollectItemCodec;
import org.spout.vanilla.protocol.codec.player.PlayerDiggingCodec;
import org.spout.vanilla.protocol.codec.player.PlayerExperienceCodec;
import org.spout.vanilla.protocol.codec.player.PlayerGameStateCodec;
import org.spout.vanilla.protocol.codec.player.PlayerGroundCodec;
import org.spout.vanilla.protocol.codec.player.PlayerHealthCodec;
import org.spout.vanilla.protocol.codec.player.PlayerHeldItemChangeCodec;
import org.spout.vanilla.protocol.codec.player.PlayerLocaleViewDistanceCodec;
import org.spout.vanilla.protocol.codec.player.PlayerStatisticCodec;
import org.spout.vanilla.protocol.codec.player.PlayerStatusCodec;
import org.spout.vanilla.protocol.codec.player.PlayerTabCompleteCodec;
import org.spout.vanilla.protocol.codec.player.PlayerTimeCodec;
import org.spout.vanilla.protocol.codec.player.PlayerUseEntityCodec;
import org.spout.vanilla.protocol.codec.player.conn.PlayerHandshakeCodec;
import org.spout.vanilla.protocol.codec.player.conn.PlayerKickCodec;
import org.spout.vanilla.protocol.codec.player.conn.PlayerListCodec;
import org.spout.vanilla.protocol.codec.player.conn.PlayerLoginRequestCodec;
import org.spout.vanilla.protocol.codec.player.conn.PlayerPingCodec;
import org.spout.vanilla.protocol.codec.player.pos.PlayerLookCodec;
import org.spout.vanilla.protocol.codec.player.pos.PlayerPositionCodec;
import org.spout.vanilla.protocol.codec.player.pos.PlayerPositionLookCodec;
import org.spout.vanilla.protocol.codec.player.pos.PlayerRespawnCodec;
import org.spout.vanilla.protocol.codec.player.pos.PlayerSpawnCodec;
import org.spout.vanilla.protocol.codec.player.pos.PlayerSpawnPositionCodec;
import org.spout.vanilla.protocol.codec.scoreboard.ScoreboardDisplayCodec;
import org.spout.vanilla.protocol.codec.scoreboard.ScoreboardObjectiveCodec;
import org.spout.vanilla.protocol.codec.scoreboard.ScoreboardScoreCodec;
import org.spout.vanilla.protocol.codec.scoreboard.ScoreboardTeamCodec;
import org.spout.vanilla.protocol.codec.server.ServerListPingCodec;
import org.spout.vanilla.protocol.codec.server.ServerPluginCodec;
import org.spout.vanilla.protocol.codec.window.WindowClickCodec;
import org.spout.vanilla.protocol.codec.window.WindowCloseCodec;
import org.spout.vanilla.protocol.codec.window.WindowCreativeActionCodec;
import org.spout.vanilla.protocol.codec.window.WindowEnchantItemCodec;
import org.spout.vanilla.protocol.codec.window.WindowItemsCodec;
import org.spout.vanilla.protocol.codec.window.WindowOpenCodec;
import org.spout.vanilla.protocol.codec.window.WindowPropertyCodec;
import org.spout.vanilla.protocol.codec.window.WindowSlotCodec;
import org.spout.vanilla.protocol.codec.window.WindowTransactionCodec;
import org.spout.vanilla.protocol.codec.world.EffectCodec;
import org.spout.vanilla.protocol.codec.world.ExplosionCodec;
import org.spout.vanilla.protocol.codec.world.ParticleEffectCodec;
import org.spout.vanilla.protocol.codec.world.SoundEffectCodec;
import org.spout.vanilla.protocol.codec.world.block.BlockActionCodec;
import org.spout.vanilla.protocol.codec.world.block.BlockBreakAnimationCodec;
import org.spout.vanilla.protocol.codec.world.block.BlockBulkCodec;
import org.spout.vanilla.protocol.codec.world.block.BlockChangeCodec;
import org.spout.vanilla.protocol.codec.world.block.SignCodec;
import org.spout.vanilla.protocol.codec.world.chunk.ChunkBulkCodec;
import org.spout.vanilla.protocol.codec.world.chunk.ChunkDataCodec;
import org.spout.vanilla.protocol.handler.ServerListPingHandler;
import org.spout.vanilla.protocol.handler.ServerPluginHandler;
import org.spout.vanilla.protocol.handler.auth.EncryptionKeyRequestHandler;
import org.spout.vanilla.protocol.handler.auth.EncryptionKeyResponseHandler;
import org.spout.vanilla.protocol.handler.entity.EntityActionHandler;
import org.spout.vanilla.protocol.handler.entity.EntityAnimationHandler;
import org.spout.vanilla.protocol.handler.entity.EntityAttachEntityHandler;
import org.spout.vanilla.protocol.handler.entity.EntityDestroyHandler;
import org.spout.vanilla.protocol.handler.entity.EntityEffectHandler;
import org.spout.vanilla.protocol.handler.entity.EntityEquipmentHandler;
import org.spout.vanilla.protocol.handler.entity.EntityExperienceOrbHandler;
import org.spout.vanilla.protocol.handler.entity.EntityInitializeHandler;
import org.spout.vanilla.protocol.handler.entity.EntityItemDataHandler;
import org.spout.vanilla.protocol.handler.entity.EntityMetadataHandler;
import org.spout.vanilla.protocol.handler.entity.EntityMobHandler;
import org.spout.vanilla.protocol.handler.entity.EntityObjectHandler;
import org.spout.vanilla.protocol.handler.entity.EntityPaintingHandler;
import org.spout.vanilla.protocol.handler.entity.EntityPropertiesHandler;
import org.spout.vanilla.protocol.handler.entity.EntityStatusHandler;
import org.spout.vanilla.protocol.handler.entity.EntityThunderboltHandler;
import org.spout.vanilla.protocol.handler.entity.EntityTileDataHandler;
import org.spout.vanilla.protocol.handler.entity.SteerVehicleHandler;
import org.spout.vanilla.protocol.handler.entity.effect.EntityRemoveEffectHandler;
import org.spout.vanilla.protocol.handler.entity.pos.EntityHeadYawHandler;
import org.spout.vanilla.protocol.handler.entity.pos.EntityRelativePositionHandler;
import org.spout.vanilla.protocol.handler.entity.pos.EntityRelativePositionYawHandler;
import org.spout.vanilla.protocol.handler.entity.pos.EntityTeleportHandler;
import org.spout.vanilla.protocol.handler.entity.pos.EntityVelocityHandler;
import org.spout.vanilla.protocol.handler.entity.pos.EntityYawHandler;
import org.spout.vanilla.protocol.handler.player.PlayerAbilityHandler;
import org.spout.vanilla.protocol.handler.player.PlayerBedHandler;
import org.spout.vanilla.protocol.handler.player.PlayerBlockPlacementHandler;
import org.spout.vanilla.protocol.handler.player.PlayerChatHandler;
import org.spout.vanilla.protocol.handler.player.PlayerCollectItemHandler;
import org.spout.vanilla.protocol.handler.player.PlayerDiggingHandler;
import org.spout.vanilla.protocol.handler.player.PlayerExperienceHandler;
import org.spout.vanilla.protocol.handler.player.PlayerGameStateHandler;
import org.spout.vanilla.protocol.handler.player.PlayerGroundHandler;
import org.spout.vanilla.protocol.handler.player.PlayerHealthHandler;
import org.spout.vanilla.protocol.handler.player.PlayerHeldItemChangeHandler;
import org.spout.vanilla.protocol.handler.player.PlayerLocaleViewDistanceHandler;
import org.spout.vanilla.protocol.handler.player.PlayerRespawnHandler;
import org.spout.vanilla.protocol.handler.player.PlayerStatisticHandler;
import org.spout.vanilla.protocol.handler.player.PlayerStatusHandler;
import org.spout.vanilla.protocol.handler.player.PlayerTabCompleteHandler;
import org.spout.vanilla.protocol.handler.player.PlayerTimeHandler;
import org.spout.vanilla.protocol.handler.player.PlayerUseEntityHandler;
import org.spout.vanilla.protocol.handler.player.conn.PlayerHandshakeHandler;
import org.spout.vanilla.protocol.handler.player.conn.PlayerKickHandler;
import org.spout.vanilla.protocol.handler.player.conn.PlayerListHandler;
import org.spout.vanilla.protocol.handler.player.conn.PlayerLoginRequestHandler;
import org.spout.vanilla.protocol.handler.player.conn.PlayerPingHandler;
import org.spout.vanilla.protocol.handler.player.pos.PlayerLookHandler;
import org.spout.vanilla.protocol.handler.player.pos.PlayerPositionHandler;
import org.spout.vanilla.protocol.handler.player.pos.PlayerPositionLookHandler;
import org.spout.vanilla.protocol.handler.player.pos.PlayerSpawnHandler;
import org.spout.vanilla.protocol.handler.player.pos.PlayerSpawnPositionHandler;
import org.spout.vanilla.protocol.handler.scoreboard.ScoreboardDisplayHandler;
import org.spout.vanilla.protocol.handler.scoreboard.ScoreboardObjectiveHandler;
import org.spout.vanilla.protocol.handler.scoreboard.ScoreboardScoreHandler;
import org.spout.vanilla.protocol.handler.scoreboard.ScoreboardTeamHandler;
import org.spout.vanilla.protocol.handler.window.WindowClickHandler;
import org.spout.vanilla.protocol.handler.window.WindowCloseHandler;
import org.spout.vanilla.protocol.handler.window.WindowCreativeActionHandler;
import org.spout.vanilla.protocol.handler.window.WindowEnchantItemHandler;
import org.spout.vanilla.protocol.handler.window.WindowItemsHandler;
import org.spout.vanilla.protocol.handler.window.WindowOpenHandler;
import org.spout.vanilla.protocol.handler.window.WindowPropertyHandler;
import org.spout.vanilla.protocol.handler.window.WindowSlotHandler;
import org.spout.vanilla.protocol.handler.window.WindowTransactionHandler;
import org.spout.vanilla.protocol.handler.world.EffectHandler;
import org.spout.vanilla.protocol.handler.world.ExplosionHandler;
import org.spout.vanilla.protocol.handler.world.ParticleEffectHandler;
import org.spout.vanilla.protocol.handler.world.SoundEffectHandler;
import org.spout.vanilla.protocol.handler.world.block.BlockActionHandler;
import org.spout.vanilla.protocol.handler.world.block.BlockBreakAnimationHandler;
import org.spout.vanilla.protocol.handler.world.block.BlockBulkHandler;
import org.spout.vanilla.protocol.handler.world.block.BlockChangeHandler;
import org.spout.vanilla.protocol.handler.world.block.SignHandler;
import org.spout.vanilla.protocol.handler.world.chunk.ChunkBulkHandler;
import org.spout.vanilla.protocol.handler.world.chunk.ChunkDataHandler;
import org.spout.vanilla.protocol.msg.ServerPluginMessage;
import org.spout.vanilla.protocol.msg.player.PlayerChatMessage;
import org.spout.vanilla.protocol.msg.player.conn.PlayerHandshakeMessage;
import org.spout.vanilla.protocol.msg.player.conn.PlayerKickMessage;
import org.spout.vanilla.protocol.netcache.ChunkNetCache;
import org.spout.vanilla.protocol.netcache.protocol.ChunkCacheCodec;
import org.spout.vanilla.protocol.netcache.protocol.ChunkCacheHandler;
import org.spout.vanilla.protocol.plugin.BeaconCodec;
import org.spout.vanilla.protocol.plugin.BeaconHandler;
import org.spout.vanilla.protocol.plugin.CommandBlockCodec;
import org.spout.vanilla.protocol.plugin.CommandBlockHandler;
import org.spout.vanilla.protocol.plugin.RegisterPluginChannelCodec;
import org.spout.vanilla.protocol.plugin.RegisterPluginChannelMessage;
import org.spout.vanilla.protocol.plugin.RegisterPluginChannelMessageHandler;
import org.spout.vanilla.protocol.plugin.UnregisterPluginChannelCodec;
import org.spout.vanilla.protocol.plugin.UnregisterPluginChannelMessageHandler;
public class VanillaProtocol extends Protocol {
public static final DefaultedKey<String> SESSION_ID = new DefaultedKeyImpl<String>("sessionid", "0000000000000000");
public static final DefaultedKey<String> HANDSHAKE_USERNAME = new DefaultedKeyImpl<String>("handshake_username", "");
public static final DefaultedKey<Long> LOGIN_TIME = new DefaultedKeyImpl<Long>("handshake_time", -1L);
public static final DefaultedKey<ChunkNetCache> CHUNK_NET_CACHE = new DefaultedKeyImpl<ChunkNetCache>("chunk_net_cache", (ChunkNetCache) null);
public static final DefaultedKey<ArrayList<String>> REGISTERED_CUSTOM_PACKETS = new DefaultedKey<ArrayList<String>>() {
private final List<String> defaultRestricted = Arrays.asList("REGISTER", "UNREGISTER");
public ArrayList<String> getDefaultValue() {
return new ArrayList<String>(defaultRestricted);
}
public String getKeyString() {
return "registeredPluginChannels";
}
};
public static final int DEFAULT_PORT = 25565;
public VanillaProtocol() {
super("Vanilla", DEFAULT_PORT, 512);
// THIS FORMATTING IS CORRECT NO MATTER WHAT ANY AUTOFORMATTER SAYS. DON'T CHANGE IT
/* 0x00 */
registerPacket(PlayerPingCodec.class, new PlayerPingHandler());
/* 0x01 */
registerPacket(PlayerLoginRequestCodec.class, new PlayerLoginRequestHandler());
/* 0x02 */
registerPacket(PlayerHandshakeCodec.class, new PlayerHandshakeHandler());
/* 0x03 */
registerPacket(PlayerChatCodec.class, new PlayerChatHandler());
/* 0x04 */
registerPacket(PlayerTimeCodec.class, new PlayerTimeHandler());
/* 0x05 */
registerPacket(EntityEquipmentCodec.class, new EntityEquipmentHandler());
/* 0x06 */
registerPacket(PlayerSpawnPositionCodec.class, new PlayerSpawnPositionHandler());
/* 0x07 */
registerPacket(PlayerUseEntityCodec.class, new PlayerUseEntityHandler());
/* 0x08 */
registerPacket(PlayerHealthCodec.class, new PlayerHealthHandler());
/* 0x09 */
registerPacket(PlayerRespawnCodec.class, new PlayerRespawnHandler());
/* 0x0A */
registerPacket(PlayerGroundCodec.class, new PlayerGroundHandler());
/* 0x0B */
registerPacket(PlayerPositionCodec.class, new PlayerPositionHandler());
/* 0x0C */
registerPacket(PlayerLookCodec.class, new PlayerLookHandler());
/* 0x0D */
registerPacket(PlayerPositionLookCodec.class, new PlayerPositionLookHandler());
/* 0x0E */
registerPacket(PlayerDiggingCodec.class, new PlayerDiggingHandler());
/* 0x0F */
registerPacket(PlayerBlockPlacementCodec.class, new PlayerBlockPlacementHandler());
/* 0x10 */
registerPacket(PlayerHeldItemChangeCodec.class, new PlayerHeldItemChangeHandler());
/* 0x11 */
registerPacket(PlayerBedCodec.class, new PlayerBedHandler());
/* 0x12 */
registerPacket(EntityAnimationCodec.class, new EntityAnimationHandler());
/* 0x13 */
registerPacket(EntityActionCodec.class, new EntityActionHandler());
/* 0x14 */
registerPacket(PlayerSpawnCodec.class, new PlayerSpawnHandler());
/* 0x15 */ //registerPacket(EntityItemCodec.class, new EntityItemHandler()); // Removed as of 1.4.6
/* 0x16 */
registerPacket(PlayerCollectItemCodec.class, new PlayerCollectItemHandler());
/* 0x17 */
registerPacket(EntitySpawnObjectCodec.class, new EntityObjectHandler());
/* 0x18 */
registerPacket(EntityMobCodec.class, new EntityMobHandler());
/* 0x19 */
registerPacket(EntityPaintingCodec.class, new EntityPaintingHandler());
/* 0x1A */
registerPacket(EntityExperienceOrbCodec.class, new EntityExperienceOrbHandler());
/* 0x1B */
registerPacket(SteerVehicleCodec.class, new SteerVehicleHandler());
/* 0x1C */
registerPacket(EntityVelocityCodec.class, new EntityVelocityHandler());
/* 0x1D */
registerPacket(EntityDestroyCodec.class, new EntityDestroyHandler());
/* 0x1E */
registerPacket(EntityInitializeCodec.class, new EntityInitializeHandler()); //TODO the meaning of this packet is basically that the entity did not move/look since the last such packet. We need to implement this!
/* 0x1F */
registerPacket(EntityRelativePositionCodec.class, new EntityRelativePositionHandler());
/* 0x20 */
registerPacket(EntityYawCodec.class, new EntityYawHandler()); //TODO rename Entity Look on the minecraft protocol page
/* 0x21 */
registerPacket(EntityRelativePositionYawCodec.class, new EntityRelativePositionYawHandler()); //TODO same as above
/* 0x22 */
registerPacket(EntityTeleportCodec.class, new EntityTeleportHandler());
/* 0x23 */
registerPacket(EntityHeadYawCodec.class, new EntityHeadYawHandler()); //TODO same as above
/* 0x26 */
registerPacket(EntityStatusCodec.class, new EntityStatusHandler());
/* 0x27 */
registerPacket(EntityAttachEntityCodec.class, new EntityAttachEntityHandler());
/* 0x28 */
registerPacket(EntityMetadataCodec.class, new EntityMetadataHandler());
/* 0x29 */
registerPacket(EntityEffectCodec.class, new EntityEffectHandler());
/* 0x2A */
registerPacket(EntityRemoveEffectCodec.class, new EntityRemoveEffectHandler());
/* 0x2B */
registerPacket(PlayerExperienceCodec.class, new PlayerExperienceHandler());
/* 0x2C */
registerPacket(EntityPropertiesCodec.class, new EntityPropertiesHandler());
/* 0x33 */
registerPacket(ChunkDataCodec.class, new ChunkDataHandler()); //TODO rename on the minecraft protocol page
/* 0x34 */
registerPacket(BlockBulkCodec.class, new BlockBulkHandler());
/* 0x35 */
registerPacket(BlockChangeCodec.class, new BlockChangeHandler());
/* 0x36 */
registerPacket(BlockActionCodec.class, new BlockActionHandler());
/* 0x37 */
registerPacket(BlockBreakAnimationCodec.class, new BlockBreakAnimationHandler());
/* 0x38 */
registerPacket(ChunkBulkCodec.class, new ChunkBulkHandler());
/* 0x3C */
registerPacket(ExplosionCodec.class, new ExplosionHandler());
/* 0x3D */
registerPacket(EffectCodec.class, new EffectHandler());
/* 0x3E */
registerPacket(SoundEffectCodec.class, new SoundEffectHandler());
/* 0x3F */
registerPacket(ParticleEffectCodec.class, new ParticleEffectHandler());
/* 0x46 */
registerPacket(PlayerGameStateCodec.class, new PlayerGameStateHandler());
/* 0x47 */
registerPacket(EntityThunderboltCodec.class, new EntityThunderboltHandler()); //Minecraft protocol page -> Thunderbolt :/
/* 0x64 */
registerPacket(WindowOpenCodec.class, new WindowOpenHandler());
/* 0x65 */
registerPacket(WindowCloseCodec.class, new WindowCloseHandler());
/* 0x66 */
registerPacket(WindowClickCodec.class, new WindowClickHandler());
/* 0x67 */
registerPacket(WindowSlotCodec.class, new WindowSlotHandler());
/* 0x68 */
registerPacket(WindowItemsCodec.class, new WindowItemsHandler());
/* 0x69 */
registerPacket(WindowPropertyCodec.class, new WindowPropertyHandler()); //Update Window Property on the protocol page!
/* 0x6A */
registerPacket(WindowTransactionCodec.class, new WindowTransactionHandler());
/* 0x6B */
registerPacket(WindowCreativeActionCodec.class, new WindowCreativeActionHandler());
/* 0x6C */
registerPacket(WindowEnchantItemCodec.class, new WindowEnchantItemHandler());
/* 0x82 */
registerPacket(SignCodec.class, new SignHandler());
/* 0x83 */
registerPacket(EntityItemDataCodec.class, new EntityItemDataHandler());
/* 0x84 */
registerPacket(EntityTileDataCodec.class, new EntityTileDataHandler()); //Update Tile Entity...
/* 0xC8 */
registerPacket(PlayerStatisticCodec.class, new PlayerStatisticHandler());
/* 0xC9 */
registerPacket(PlayerListCodec.class, new PlayerListHandler());
/* 0xCA */
registerPacket(PlayerAbilityCodec.class, new PlayerAbilityHandler());
/* 0xCB */
registerPacket(PlayerTabCompleteCodec.class, new PlayerTabCompleteHandler());
/* 0xCC */
registerPacket(PlayerLocaleViewDistanceCodec.class, new PlayerLocaleViewDistanceHandler());
/* 0xCD */
registerPacket(PlayerStatusCodec.class, new PlayerStatusHandler());
/* 0xCE */
registerPacket(ScoreboardObjectiveCodec.class, new ScoreboardObjectiveHandler());
/* 0xCF */
registerPacket(ScoreboardScoreCodec.class, new ScoreboardScoreHandler());
/* 0xD0 */
registerPacket(ScoreboardDisplayCodec.class, new ScoreboardDisplayHandler());
/* 0xD1 */
registerPacket(ScoreboardTeamCodec.class, new ScoreboardTeamHandler());
/* 0xFA */
registerPacket(ServerPluginCodec.class, new ServerPluginHandler());
/* 0xFC */
registerPacket(EncryptionKeyResponseCodec.class, new EncryptionKeyResponseHandler());
/* 0xFD */
registerPacket(EncryptionKeyRequestCodec.class, new EncryptionKeyRequestHandler());
/* 0xFE */
registerPacket(ServerListPingCodec.class, new ServerListPingHandler());
/* 0xFF */
registerPacket(PlayerKickCodec.class, new PlayerKickHandler());
/* PacketFA wrapped packets */
registerPacket(RegisterPluginChannelCodec.class, new RegisterPluginChannelMessageHandler());
registerPacket(UnregisterPluginChannelCodec.class, new UnregisterPluginChannelMessageHandler());
registerPacket(ChunkCacheCodec.class, new ChunkCacheHandler());
registerPacket(CommandBlockCodec.class, new CommandBlockHandler());
registerPacket(BeaconCodec.class, new BeaconHandler());
}
@Override
public Message getCommandMessage(String command, CommandArguments args) {
try {
if (command.equals("kick")) {
return getKickMessage(args.popRemainingStrings("message"));
} else if (command.equals("say")) {
return new PlayerChatMessage(args.popRemainingStrings("message") + "\u00a7r"); // The reset text is a workaround for a change in 1.3 -- Remove if fixed
} else {
return new PlayerChatMessage('/' + command + ' ' + args.popRemainingStrings("message"));
}
} catch (ArgumentParseException ex) {
return new PlayerChatMessage(ChatStyle.RED + ex.getMessage());
}
}
@Override
@SuppressWarnings ("unchecked")
public <T extends Message> Message getWrappedMessage(T dynamicMessage) throws IOException {
MessageCodec<T> codec = (MessageCodec<T>) getCodecLookupService().find(dynamicMessage.getClass());
ByteBuf buffer = codec.encode(Spout.getPlatform() == Platform.CLIENT, dynamicMessage);
return new ServerPluginMessage(getName(codec), buffer.array());
}
@Override
public MessageCodec<?> readHeader(ByteBuf buf) throws UnknownPacketException {
int opcode = buf.readUnsignedByte();
MessageCodec<?> codec = getCodecLookupService().find(opcode);
if (codec == null) {
throw new UnknownPacketException(opcode);
}
return codec;
}
@Override
public ByteBuf writeHeader(MessageCodec<?> codec, ByteBuf data) {
ByteBuf buffer = Unpooled.buffer(1);
buffer.writeByte(codec.getOpcode());
return buffer;
}
@Override
public Message getKickMessage(String message) {
return new PlayerKickMessage(message);
}
@Override
public Message getIntroductionMessage(String playerName, InetSocketAddress addr) {
return new PlayerHandshakeMessage((byte) VanillaPlugin.MINECRAFT_PROTOCOL_ID, VanillaPlugin.getInstance().getUsername(), addr.getHostName(), addr.getPort());
}
public static MessageCodec<?> getCodec(String name, Protocol activeProtocol) {
for (Pair<Integer, String> item : activeProtocol.getDynamicallyRegisteredPackets()) {
MessageCodec<?> codec = activeProtocol.getCodecLookupService().find(item.getLeft());
if (getName(codec).equalsIgnoreCase(name)) {
return codec;
}
}
return null;
}
public static String getName(MessageCodec<?> codec) {
if (codec instanceof Named) {
return ((Named) codec).getName();
} else {
return "SPOUT:" + codec.getOpcode();
}
}
@Override
public Class<? extends PlayerNetworkComponent> getServerNetworkComponent(ServerSession session) {
return VanillaPlayerNetworkComponent.class;
}
@Override
public Class<? extends PlayerNetworkComponent> getClientNetworkComponent(ClientSession session) {
return VanillaPlayerNetworkComponent.class;
}
@Override
public void initializeServerSession(ServerSession session) {
List<MessageCodec<?>> dynamicCodecList = new ArrayList<MessageCodec<?>>();
for (Pair<Integer, String> item : getDynamicallyRegisteredPackets()) {
MessageCodec<?> codec = getCodecLookupService().find(item.getLeft());
if (codec != null) {
dynamicCodecList.add(codec);
} else {
throw new IllegalStateException("Dynamic packet class" + item.getRight() + " claims to be registered but is not in our CodecLookupService!");
}
}
session.send(new RegisterPluginChannelMessage(dynamicCodecList));
}
@Override
public void initializeClientSession(ClientSession session) {
List<MessageCodec<?>> dynamicCodecList = new ArrayList<MessageCodec<?>>();
for (Pair<Integer, String> item : getDynamicallyRegisteredPackets()) {
MessageCodec<?> codec = getCodecLookupService().find(item.getLeft());
if (codec != null) {
dynamicCodecList.add(codec);
} else {
throw new IllegalStateException("Dynamic packet class" + item.getRight() + " claims to be registered but is not in our CodecLookupService!");
}
}
session.send(new RegisterPluginChannelMessage(dynamicCodecList));
}
}