* Added support for the Minecraft 1.10 protocol(#210) * Fixed the Clang compilation errors * Fixed wrong sound pitch value and fixed SendPlayerSpawn Metadata value. * Prefixed each enum item with the appropriate class name.
This commit is contained in:
parent
dd8daaf63e
commit
61078e8402
@ -3,6 +3,7 @@ Many people have contributed to Cuberite, and this list attempts to broadcast at
|
||||
BasedDoge (Donated AlchemistVillage prefabs)
|
||||
bearbin (Alexander Harkness)
|
||||
beeduck
|
||||
bibo38
|
||||
birkett (Anthony Birkett)
|
||||
derouinw
|
||||
Diusrex
|
||||
|
@ -9,6 +9,7 @@ SET (SRCS
|
||||
Packetizer.cpp
|
||||
Protocol18x.cpp
|
||||
Protocol19x.cpp
|
||||
Protocol110x.cpp
|
||||
ProtocolRecognizer.cpp
|
||||
)
|
||||
|
||||
@ -20,12 +21,14 @@ SET (HDRS
|
||||
Protocol.h
|
||||
Protocol18x.h
|
||||
Protocol19x.h
|
||||
Protocol110x.h
|
||||
ProtocolRecognizer.h
|
||||
)
|
||||
|
||||
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||
set_source_files_properties(Protocol19x.cpp PROPERTIES COMPILE_FLAGS "-Wno-error=switch-enum -Wno-error=switch")
|
||||
set_source_files_properties(Protocol18x.cpp PROPERTIES COMPILE_FLAGS "-Wno-error=switch-enum -Wno-error=switch")
|
||||
set_source_files_properties(Protocol19x.cpp PROPERTIES COMPILE_FLAGS "-Wno-error=switch-enum -Wno-error=switch")
|
||||
set_source_files_properties(Protocol18x.cpp PROPERTIES COMPILE_FLAGS "-Wno-error=switch-enum -Wno-error=switch")
|
||||
set_source_files_properties(Protocol110x.cpp PROPERTIES COMPILE_FLAGS "-Wno-error=switch")
|
||||
endif()
|
||||
|
||||
if (NOT MSVC)
|
||||
|
879
src/Protocol/Protocol110x.cpp
Normal file
879
src/Protocol/Protocol110x.cpp
Normal file
@ -0,0 +1,879 @@
|
||||
|
||||
// Protocol110x.cpp
|
||||
|
||||
/*
|
||||
Implements the 1.10.x protocol classes:
|
||||
- cProtocol1100
|
||||
- release 1.10.0 protocol (#210)
|
||||
(others may be added later in the future for the 1.10 release series)
|
||||
*/
|
||||
|
||||
#include "Globals.h"
|
||||
#include "Protocol110x.h"
|
||||
#include "Packetizer.h"
|
||||
|
||||
#include "../Root.h"
|
||||
#include "../Server.h"
|
||||
|
||||
#include "../Entities/Boat.h"
|
||||
#include "../Entities/ExpOrb.h"
|
||||
#include "../Entities/Minecart.h"
|
||||
#include "../Entities/FallingBlock.h"
|
||||
#include "../Entities/Painting.h"
|
||||
#include "../Entities/Pickup.h"
|
||||
#include "../Entities/Player.h"
|
||||
#include "../Entities/ItemFrame.h"
|
||||
#include "../Entities/ArrowEntity.h"
|
||||
#include "../Entities/FireworkEntity.h"
|
||||
#include "../Entities/SplashPotionEntity.h"
|
||||
|
||||
#include "../Mobs/IncludeAllMonsters.h"
|
||||
|
||||
#include "Bindings/PluginManager.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// The disabled error is intended, since the Metadata have overlapping indexes
|
||||
// based on the type of the Entity.
|
||||
//
|
||||
// IMPORTANT: The enum is used to automate the sequential counting of the
|
||||
// Metadata indexes. Adding a new enum value causes the following values to
|
||||
// increase their index. Therefore the ordering of the enum values is VERY important!
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wduplicate-enum"
|
||||
|
||||
namespace Metadata
|
||||
{
|
||||
enum Metadata_Index
|
||||
{
|
||||
// Entity
|
||||
ENTITY_FLAGS,
|
||||
ENTITY_AIR,
|
||||
ENTITY_CUSTOM_NAME,
|
||||
ENTITY_CUSTOM_NAME_VISIBLE,
|
||||
ENTITY_SILENT,
|
||||
ENTITY_NO_GRAVITY,
|
||||
_ENTITY_NEXT, // Used by descendants
|
||||
|
||||
// Potion
|
||||
POTION_THROWN = _ENTITY_NEXT,
|
||||
|
||||
// FallingBlock
|
||||
FALLING_BLOCK_POSITION = _ENTITY_NEXT,
|
||||
|
||||
// AreaEffectCloud
|
||||
AREA_EFFECT_CLOUD_RADIUS = _ENTITY_NEXT,
|
||||
AREA_EFFECT_CLOUD_COLOR,
|
||||
AREA_EFFECT_CLOUD_SINGLE_POINT_EFFECT,
|
||||
AREA_EFFECT_CLOUD_PARTICLE_ID,
|
||||
AREA_EFFECT_CLOUD_PARTICLE_PARAMETER1,
|
||||
AREA_EFFECT_CLOUD_PARTICLE_PARAMETER2,
|
||||
|
||||
// Arrow
|
||||
ARROW_CRITICAL = _ENTITY_NEXT,
|
||||
_ARROW_NEXT,
|
||||
|
||||
// TippedArrow
|
||||
TIPPED_ARROW_COLOR = _ARROW_NEXT,
|
||||
|
||||
// Boat
|
||||
BOAT_LAST_HIT_TIME = _ENTITY_NEXT,
|
||||
BOAT_FORWARD_DIRECTION,
|
||||
BOAT_DAMAGE_TAKEN,
|
||||
BOAT_TYPE,
|
||||
BOAT_RIGHT_PADDLE_TURNING,
|
||||
BOAT_LEFT_PADDLE_TURNING,
|
||||
|
||||
// EnderCrystal
|
||||
ENDER_CRYSTAL_BEAM_TARGET = _ENTITY_NEXT,
|
||||
ENDER_CRYSTAL_SHOW_BOTTOM,
|
||||
|
||||
// Fireball
|
||||
_FIREBALL_NEXT = _ENTITY_NEXT,
|
||||
|
||||
// WitherSkull
|
||||
WITHER_SKULL_INVULNERABLE = _FIREBALL_NEXT,
|
||||
|
||||
// Fireworks
|
||||
FIREWORK_INFO = _ENTITY_NEXT,
|
||||
|
||||
// Hanging
|
||||
_HANGING_NEXT = _ENTITY_NEXT,
|
||||
|
||||
// ItemFrame
|
||||
ITEM_FRAME_ITEM = _HANGING_NEXT,
|
||||
ITEM_FRAME_ROTATION,
|
||||
|
||||
// Item
|
||||
ITEM_ITEM = _ENTITY_NEXT,
|
||||
|
||||
// Living
|
||||
LIVING_ACTIVE_HAND = _ENTITY_NEXT,
|
||||
LIVING_HEALTH,
|
||||
LIVING_POTION_EFFECT_COLOR,
|
||||
LIVING_POTION_EFFECT_AMBIENT,
|
||||
LIVING_NUMBER_OF_ARROWS,
|
||||
_LIVING_NEXT,
|
||||
|
||||
// Player
|
||||
PLAYER_ADDITIONAL_HEARTHS = _LIVING_NEXT,
|
||||
PLAYER_SCORE,
|
||||
PLAYER_DISPLAYED_SKIN_PARTS,
|
||||
PLAYER_MAIN_HAND,
|
||||
|
||||
// ArmorStand
|
||||
ARMOR_STAND_STATUS = _LIVING_NEXT,
|
||||
ARMOR_STAND_HEAD_ROTATION,
|
||||
ARMOR_STAND_BODY_ROTATION,
|
||||
ARMOR_STAND_LEFT_ARM_ROTATION,
|
||||
ARMOR_STAND_RIGHT_ARM_ROTATION,
|
||||
ARMOR_STAND_LEFT_LEG_ROTATION,
|
||||
ARMOR_STAND_RIGHT_LEG_ROTATION,
|
||||
|
||||
// Insentient
|
||||
INSENTIENT_STATUS = _LIVING_NEXT,
|
||||
_INSENTIENT_NEXT,
|
||||
|
||||
// Ambient
|
||||
_AMBIENT_NEXT = _INSENTIENT_NEXT,
|
||||
|
||||
// Bat
|
||||
BAT_HANGING = _AMBIENT_NEXT,
|
||||
|
||||
// Creature
|
||||
_CREATURE_NEXT = _INSENTIENT_NEXT,
|
||||
|
||||
// Ageable
|
||||
AGEABLE_BABY = _CREATURE_NEXT,
|
||||
_AGEABLE_NEXT,
|
||||
|
||||
// PolarBear
|
||||
POLAR_BEAR_STANDING = _AGEABLE_NEXT,
|
||||
|
||||
// Animal
|
||||
_ANIMAL_NEXT = _AGEABLE_NEXT,
|
||||
|
||||
// Horse
|
||||
HORSE_STATUS = _ANIMAL_NEXT,
|
||||
HORSE_TYPE,
|
||||
HORSE_VARIANT,
|
||||
HORSE_OWNER,
|
||||
HORSE_ARMOR,
|
||||
|
||||
// Pig
|
||||
PIG_HAS_SADDLE = _ANIMAL_NEXT,
|
||||
|
||||
// Rabbit
|
||||
RABBIT_TYPE = _ANIMAL_NEXT,
|
||||
|
||||
// Sheep
|
||||
SHEEP_STATUS = _ANIMAL_NEXT,
|
||||
|
||||
// TameableAnimal
|
||||
TAMEABLE_ANIMAL_STATUS = _ANIMAL_NEXT,
|
||||
TAMEABLE_ANIMAL_OWNER,
|
||||
_TAMEABLE_NEXT,
|
||||
|
||||
// Ocelot
|
||||
OCELOT_TYPE = _TAMEABLE_NEXT,
|
||||
|
||||
// Wolf
|
||||
WOLF_DAMAGE_TAKEN = _TAMEABLE_NEXT,
|
||||
WOLF_BEGGING,
|
||||
WOLF_COLLAR_COLOR,
|
||||
|
||||
// Villager
|
||||
VILLAGER_PROFESSION = _AGEABLE_NEXT,
|
||||
|
||||
// Golem
|
||||
_GOLEM_NEXT = _CREATURE_NEXT,
|
||||
|
||||
// IronGolem
|
||||
IRON_GOLEM_PLAYER_CREATED = _GOLEM_NEXT,
|
||||
|
||||
// Shulker
|
||||
SHULKER_FACING_DIRECTION = _GOLEM_NEXT,
|
||||
SHULKER_ATTACHMENT_FALLING_BLOCK_POSITION,
|
||||
SHULKER_SHIELD_HEIGHT,
|
||||
|
||||
// Monster
|
||||
_MONSTER_NEXT = _CREATURE_NEXT,
|
||||
|
||||
// Blaze
|
||||
BLAZE_ON_FIRE = _MONSTER_NEXT,
|
||||
|
||||
// Creeper
|
||||
CREEPER_STATE = _MONSTER_NEXT,
|
||||
CREEPER_POWERED,
|
||||
CREEPER_IGNITED,
|
||||
|
||||
// Guardian
|
||||
GUARDIAN_STATUS = _MONSTER_NEXT,
|
||||
GUARDIAN_TARGET,
|
||||
|
||||
// Skeleton
|
||||
SKELETON_TYPE = _MONSTER_NEXT,
|
||||
SKELETON_ARMS_SWINGING,
|
||||
|
||||
// Spider
|
||||
SPIDER_CLIMBING = _MONSTER_NEXT,
|
||||
|
||||
// Witch
|
||||
WITCH_AGGRESIVE = _MONSTER_NEXT,
|
||||
|
||||
// Wither
|
||||
WITHER_FIRST_HEAD_TARGET = _MONSTER_NEXT,
|
||||
WITHER_SECOND_HEAD_TARGET,
|
||||
WITHER_THIRD_HEAD_TARGET,
|
||||
WITHER_INVULNERABLE_TIMER,
|
||||
|
||||
// Zombie
|
||||
ZOMBIE_IS_BABY = _MONSTER_NEXT,
|
||||
ZOMBIE_TYPE,
|
||||
ZOMBIE_CONVERTING,
|
||||
ZOMBIE_HANDS_RISED_UP,
|
||||
|
||||
// Enderman
|
||||
ENDERMAN_CARRIED_BLOCK = _MONSTER_NEXT,
|
||||
ENDERMAN_SCREAMING,
|
||||
|
||||
// EnderDragon
|
||||
ENDER_DRAGON_DRAGON_PHASE = _INSENTIENT_NEXT,
|
||||
|
||||
// Flying
|
||||
_FLYING_NEXT = _INSENTIENT_NEXT,
|
||||
|
||||
// Ghast
|
||||
GHAST_ATTACKING = _FLYING_NEXT,
|
||||
|
||||
// Slime
|
||||
SLIME_SIZE = _INSENTIENT_NEXT,
|
||||
|
||||
// Minecart
|
||||
MINECART_SHAKING_POWER = _ENTITY_NEXT,
|
||||
MINECART_SHAKING_DIRECTION,
|
||||
MINECART_SHAKING_MULTIPLIER,
|
||||
MINECART_BLOCK_ID_META,
|
||||
MINECART_BLOCK_Y,
|
||||
MINECART_SHOW_BLOCK,
|
||||
_MINECART_NEXT,
|
||||
|
||||
// MinecartCommandBlock
|
||||
MINECART_COMMAND_BLOCK_COMMAND = _MINECART_NEXT,
|
||||
MINECART_COMMAND_BLOCK_LAST_OUTPUT,
|
||||
|
||||
// MinecartFurnace
|
||||
MINECART_FURNACE_POWERED = _MINECART_NEXT,
|
||||
|
||||
// TNTPrimed
|
||||
TNT_PRIMED_FUSE_TIME = _ENTITY_NEXT,
|
||||
};
|
||||
}
|
||||
|
||||
#pragma clang diagnostic pop // Restore ignored clang errors
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cProtocol1100::cProtocol1100(cClientHandle * a_Client, const AString &a_ServerAddress, UInt16 a_ServerPort, UInt32 a_State) :
|
||||
super(a_Client, a_ServerAddress, a_ServerPort, a_State)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cProtocol1100::SendSoundEffect(const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch)
|
||||
{
|
||||
ASSERT(m_State == 3); // In game mode?
|
||||
|
||||
cPacketizer Pkt(*this, 0x19); // Named sound effect packet
|
||||
Pkt.WriteString(a_SoundName);
|
||||
Pkt.WriteVarInt32(0); // Master sound category (may want to be changed to a parameter later)
|
||||
Pkt.WriteBEInt32(FloorC(a_X * 8.0));
|
||||
Pkt.WriteBEInt32(FloorC(a_Y * 8.0));
|
||||
Pkt.WriteBEInt32(FloorC(a_Z * 8.0));
|
||||
Pkt.WriteBEFloat(a_Volume);
|
||||
Pkt.WriteBEFloat(a_Pitch);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cProtocol1100::HandlePacketStatusRequest(cByteBuffer & a_ByteBuffer)
|
||||
{
|
||||
cServer * Server = cRoot::Get()->GetServer();
|
||||
AString ServerDescription = Server->GetDescription();
|
||||
int NumPlayers = Server->GetNumPlayers();
|
||||
int MaxPlayers = Server->GetMaxPlayers();
|
||||
AString Favicon = Server->GetFaviconData();
|
||||
cRoot::Get()->GetPluginManager()->CallHookServerPing(*m_Client, ServerDescription, NumPlayers, MaxPlayers, Favicon);
|
||||
|
||||
// Version:
|
||||
Json::Value Version;
|
||||
Version["name"] = "Cuberite 1.10";
|
||||
Version["protocol"] = 210;
|
||||
|
||||
// Players:
|
||||
Json::Value Players;
|
||||
Players["online"] = NumPlayers;
|
||||
Players["max"] = MaxPlayers;
|
||||
// TODO: Add "sample"
|
||||
|
||||
// Description:
|
||||
Json::Value Description;
|
||||
Description["text"] = ServerDescription.c_str();
|
||||
|
||||
// Create the response:
|
||||
Json::Value ResponseValue;
|
||||
ResponseValue["version"] = Version;
|
||||
ResponseValue["players"] = Players;
|
||||
ResponseValue["description"] = Description;
|
||||
if (!Favicon.empty())
|
||||
{
|
||||
ResponseValue["favicon"] = Printf("data:image/png;base64,%s", Favicon.c_str());
|
||||
}
|
||||
|
||||
Json::StyledWriter Writer;
|
||||
AString Response = Writer.write(ResponseValue);
|
||||
|
||||
cPacketizer Pkt(*this, 0x00); // Response packet
|
||||
Pkt.WriteString(Response);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cProtocol1100::WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a_Entity)
|
||||
{
|
||||
using namespace Metadata;
|
||||
|
||||
// Common metadata:
|
||||
Int8 Flags = 0;
|
||||
if (a_Entity.IsOnFire())
|
||||
{
|
||||
Flags |= 0x01;
|
||||
}
|
||||
if (a_Entity.IsCrouched())
|
||||
{
|
||||
Flags |= 0x02;
|
||||
}
|
||||
if (a_Entity.IsSprinting())
|
||||
{
|
||||
Flags |= 0x08;
|
||||
}
|
||||
if (a_Entity.IsRclking())
|
||||
{
|
||||
Flags |= 0x10;
|
||||
}
|
||||
if (a_Entity.IsInvisible())
|
||||
{
|
||||
Flags |= 0x20;
|
||||
}
|
||||
a_Pkt.WriteBEUInt8(ENTITY_FLAGS); // Index
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_BYTE); // Type
|
||||
a_Pkt.WriteBEInt8(Flags);
|
||||
|
||||
switch (a_Entity.GetEntityType())
|
||||
{
|
||||
case cEntity::etPlayer:
|
||||
{
|
||||
auto & Player = reinterpret_cast<const cPlayer &>(a_Entity);
|
||||
|
||||
// TODO Set player custom name to their name.
|
||||
// Then it's possible to move the custom name of mobs to the entities
|
||||
// and to remove the "special" player custom name.
|
||||
a_Pkt.WriteBEUInt8(ENTITY_CUSTOM_NAME);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_STRING);
|
||||
a_Pkt.WriteString(Player.GetName());
|
||||
|
||||
a_Pkt.WriteBEUInt8(LIVING_HEALTH);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_FLOAT);
|
||||
a_Pkt.WriteBEFloat(static_cast<float>(Player.GetHealth()));
|
||||
break;
|
||||
}
|
||||
case cEntity::etPickup:
|
||||
{
|
||||
a_Pkt.WriteBEUInt8(ITEM_ITEM);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_ITEM);
|
||||
WriteItem(a_Pkt, reinterpret_cast<const cPickup &>(a_Entity).GetItem());
|
||||
break;
|
||||
}
|
||||
case cEntity::etMinecart:
|
||||
{
|
||||
a_Pkt.WriteBEUInt8(MINECART_SHAKING_POWER);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_VARINT);
|
||||
|
||||
// The following expression makes Minecarts shake more with less health or higher damage taken
|
||||
auto & Minecart = reinterpret_cast<const cMinecart &>(a_Entity);
|
||||
auto maxHealth = a_Entity.GetMaxHealth();
|
||||
auto curHealth = a_Entity.GetHealth();
|
||||
a_Pkt.WriteVarInt32(static_cast<UInt32>((maxHealth - curHealth) * Minecart.LastDamage() * 4));
|
||||
|
||||
a_Pkt.WriteBEUInt8(MINECART_SHAKING_DIRECTION); // (doesn't seem to effect anything)
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_VARINT);
|
||||
a_Pkt.WriteVarInt32(1);
|
||||
|
||||
a_Pkt.WriteBEUInt8(MINECART_SHAKING_MULTIPLIER); // or damage taken
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_FLOAT);
|
||||
a_Pkt.WriteBEFloat(static_cast<float>(Minecart.LastDamage() + 10));
|
||||
|
||||
if (Minecart.GetPayload() == cMinecart::mpNone)
|
||||
{
|
||||
auto & RideableMinecart = reinterpret_cast<const cRideableMinecart &>(Minecart);
|
||||
const cItem & MinecartContent = RideableMinecart.GetContent();
|
||||
if (!MinecartContent.IsEmpty())
|
||||
{
|
||||
a_Pkt.WriteBEUInt8(MINECART_BLOCK_ID_META);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_VARINT);
|
||||
int Content = MinecartContent.m_ItemType;
|
||||
Content |= MinecartContent.m_ItemDamage << 8;
|
||||
a_Pkt.WriteVarInt32(static_cast<UInt32>(Content));
|
||||
|
||||
a_Pkt.WriteBEUInt8(MINECART_BLOCK_Y);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_VARINT);
|
||||
a_Pkt.WriteVarInt32(static_cast<UInt32>(RideableMinecart.GetBlockHeight()));
|
||||
|
||||
a_Pkt.WriteBEUInt8(MINECART_SHOW_BLOCK);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
|
||||
a_Pkt.WriteBool(true);
|
||||
}
|
||||
}
|
||||
else if (Minecart.GetPayload() == cMinecart::mpFurnace)
|
||||
{
|
||||
a_Pkt.WriteBEUInt8(MINECART_FURNACE_POWERED);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
|
||||
a_Pkt.WriteBool(reinterpret_cast<const cMinecartWithFurnace &>(Minecart).IsFueled());
|
||||
}
|
||||
break;
|
||||
} // case etMinecart
|
||||
|
||||
case cEntity::etProjectile:
|
||||
{
|
||||
auto & Projectile = reinterpret_cast<const cProjectileEntity &>(a_Entity);
|
||||
switch (Projectile.GetProjectileKind())
|
||||
{
|
||||
case cProjectileEntity::pkArrow:
|
||||
{
|
||||
a_Pkt.WriteBEUInt8(ARROW_CRITICAL);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_BYTE);
|
||||
a_Pkt.WriteBEInt8(reinterpret_cast<const cArrowEntity &>(Projectile).IsCritical() ? 1 : 0);
|
||||
break;
|
||||
}
|
||||
case cProjectileEntity::pkFirework:
|
||||
{
|
||||
a_Pkt.WriteBEUInt8(FIREWORK_INFO); // Firework item used for this firework
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_ITEM);
|
||||
WriteItem(a_Pkt, reinterpret_cast<const cFireworkEntity &>(Projectile).GetItem());
|
||||
break;
|
||||
}
|
||||
case cProjectileEntity::pkSplashPotion:
|
||||
{
|
||||
a_Pkt.WriteBEUInt8(POTION_THROWN); // Potion item which was thrown
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_ITEM);
|
||||
WriteItem(a_Pkt, reinterpret_cast<const cSplashPotionEntity &>(Projectile).GetItem());
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
} // case etProjectile
|
||||
|
||||
case cEntity::etMonster:
|
||||
{
|
||||
WriteMobMetadata(a_Pkt, reinterpret_cast<const cMonster &>(a_Entity));
|
||||
break;
|
||||
}
|
||||
|
||||
case cEntity::etBoat:
|
||||
{
|
||||
auto & Boat = reinterpret_cast<const cBoat &>(a_Entity);
|
||||
|
||||
a_Pkt.WriteBEInt8(BOAT_LAST_HIT_TIME);
|
||||
a_Pkt.WriteBEInt8(METADATA_TYPE_VARINT);
|
||||
a_Pkt.WriteBEInt32(Boat.GetLastDamage());
|
||||
|
||||
a_Pkt.WriteBEInt8(BOAT_FORWARD_DIRECTION);
|
||||
a_Pkt.WriteBEInt8(METADATA_TYPE_VARINT);
|
||||
a_Pkt.WriteBEInt32(Boat.GetForwardDirection());
|
||||
|
||||
a_Pkt.WriteBEInt8(BOAT_DAMAGE_TAKEN);
|
||||
a_Pkt.WriteBEInt8(METADATA_TYPE_FLOAT);
|
||||
a_Pkt.WriteBEFloat(Boat.GetDamageTaken());
|
||||
|
||||
a_Pkt.WriteBEInt8(BOAT_TYPE);
|
||||
a_Pkt.WriteBEInt8(METADATA_TYPE_VARINT);
|
||||
a_Pkt.WriteBEInt32(Boat.GetType());
|
||||
|
||||
a_Pkt.WriteBEInt8(BOAT_RIGHT_PADDLE_TURNING);
|
||||
a_Pkt.WriteBEInt8(METADATA_TYPE_BOOL);
|
||||
a_Pkt.WriteBool(Boat.IsRightPaddleUsed());
|
||||
|
||||
a_Pkt.WriteBEInt8(BOAT_LEFT_PADDLE_TURNING);
|
||||
a_Pkt.WriteBEInt8(METADATA_TYPE_BOOL);
|
||||
a_Pkt.WriteBool(Boat.IsLeftPaddleUsed());
|
||||
|
||||
break;
|
||||
} // case etBoat
|
||||
|
||||
case cEntity::etItemFrame:
|
||||
{
|
||||
auto & Frame = reinterpret_cast<const cItemFrame &>(a_Entity);
|
||||
a_Pkt.WriteBEUInt8(ITEM_FRAME_ITEM);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_ITEM);
|
||||
WriteItem(a_Pkt, Frame.GetItem());
|
||||
a_Pkt.WriteBEUInt8(ITEM_FRAME_ROTATION);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_VARINT);
|
||||
a_Pkt.WriteVarInt32(Frame.GetItemRotation());
|
||||
break;
|
||||
} // case etItemFrame
|
||||
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cProtocol1100::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob)
|
||||
{
|
||||
using namespace Metadata;
|
||||
|
||||
// Living Enitiy Metadata
|
||||
if (a_Mob.HasCustomName())
|
||||
{
|
||||
// TODO: As of 1.9 _all_ entities can have custom names; should this be moved up?
|
||||
a_Pkt.WriteBEUInt8(ENTITY_CUSTOM_NAME);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_STRING);
|
||||
a_Pkt.WriteString(a_Mob.GetCustomName());
|
||||
|
||||
a_Pkt.WriteBEUInt8(ENTITY_CUSTOM_NAME_VISIBLE); // Custom name always visible
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
|
||||
a_Pkt.WriteBool(a_Mob.IsCustomNameAlwaysVisible());
|
||||
}
|
||||
|
||||
a_Pkt.WriteBEUInt8(LIVING_HEALTH);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_FLOAT);
|
||||
a_Pkt.WriteBEFloat(static_cast<float>(a_Mob.GetHealth()));
|
||||
|
||||
switch (a_Mob.GetMobType())
|
||||
{
|
||||
case mtBat:
|
||||
{
|
||||
auto & Bat = reinterpret_cast<const cBat &>(a_Mob);
|
||||
a_Pkt.WriteBEUInt8(BAT_HANGING);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_BYTE);
|
||||
a_Pkt.WriteBEInt8(Bat.IsHanging() ? 1 : 0);
|
||||
break;
|
||||
} // case mtBat
|
||||
|
||||
case mtCreeper:
|
||||
{
|
||||
auto & Creeper = reinterpret_cast<const cCreeper &>(a_Mob);
|
||||
a_Pkt.WriteBEUInt8(CREEPER_STATE); // (idle or "blowing")
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_VARINT);
|
||||
a_Pkt.WriteVarInt32(Creeper.IsBlowing() ? 1 : static_cast<UInt32>(-1));
|
||||
|
||||
a_Pkt.WriteBEUInt8(CREEPER_POWERED);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
|
||||
a_Pkt.WriteBool(Creeper.IsCharged());
|
||||
|
||||
a_Pkt.WriteBEUInt8(CREEPER_IGNITED);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
|
||||
a_Pkt.WriteBool(Creeper.IsBurnedWithFlintAndSteel());
|
||||
break;
|
||||
} // case mtCreeper
|
||||
|
||||
case mtEnderman:
|
||||
{
|
||||
auto & Enderman = reinterpret_cast<const cEnderman &>(a_Mob);
|
||||
a_Pkt.WriteBEUInt8(ENDERMAN_CARRIED_BLOCK);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_BLOCKID);
|
||||
UInt32 Carried = 0;
|
||||
Carried |= static_cast<UInt32>(Enderman.GetCarriedBlock() << 4);
|
||||
Carried |= Enderman.GetCarriedMeta();
|
||||
a_Pkt.WriteVarInt32(Carried);
|
||||
|
||||
a_Pkt.WriteBEUInt8(ENDERMAN_SCREAMING);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
|
||||
a_Pkt.WriteBool(Enderman.IsScreaming());
|
||||
break;
|
||||
} // case mtEnderman
|
||||
|
||||
case mtGhast:
|
||||
{
|
||||
auto & Ghast = reinterpret_cast<const cGhast &>(a_Mob);
|
||||
a_Pkt.WriteBEUInt8(GHAST_ATTACKING);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
|
||||
a_Pkt.WriteBool(Ghast.IsCharging());
|
||||
break;
|
||||
} // case mtGhast
|
||||
|
||||
case mtHorse:
|
||||
{
|
||||
auto & Horse = reinterpret_cast<const cHorse &>(a_Mob);
|
||||
Int8 Flags = 0;
|
||||
if (Horse.IsTame())
|
||||
{
|
||||
Flags |= 0x02;
|
||||
}
|
||||
if (Horse.IsSaddled())
|
||||
{
|
||||
Flags |= 0x04;
|
||||
}
|
||||
if (Horse.IsChested())
|
||||
{
|
||||
Flags |= 0x08;
|
||||
}
|
||||
if (Horse.IsEating())
|
||||
{
|
||||
Flags |= 0x20;
|
||||
}
|
||||
if (Horse.IsRearing())
|
||||
{
|
||||
Flags |= 0x40;
|
||||
}
|
||||
if (Horse.IsMthOpen())
|
||||
{
|
||||
Flags |= 0x80;
|
||||
}
|
||||
a_Pkt.WriteBEUInt8(HORSE_STATUS);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_BYTE);
|
||||
a_Pkt.WriteBEInt8(Flags);
|
||||
|
||||
a_Pkt.WriteBEUInt8(HORSE_TYPE);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_VARINT);
|
||||
a_Pkt.WriteVarInt32(static_cast<UInt32>(Horse.GetHorseType()));
|
||||
|
||||
a_Pkt.WriteBEUInt8(HORSE_VARIANT); // Color / style
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_VARINT);
|
||||
int Appearance = 0;
|
||||
Appearance = Horse.GetHorseColor();
|
||||
Appearance |= Horse.GetHorseStyle() << 8;
|
||||
a_Pkt.WriteVarInt32(static_cast<UInt32>(Appearance));
|
||||
|
||||
a_Pkt.WriteBEUInt8(HORSE_ARMOR);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_VARINT);
|
||||
a_Pkt.WriteVarInt32(static_cast<UInt32>(Horse.GetHorseArmour()));
|
||||
|
||||
a_Pkt.WriteBEUInt8(AGEABLE_BABY);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
|
||||
a_Pkt.WriteBool(Horse.IsBaby());
|
||||
break;
|
||||
} // case mtHorse
|
||||
|
||||
case mtMagmaCube:
|
||||
{
|
||||
auto & MagmaCube = reinterpret_cast<const cMagmaCube &>(a_Mob);
|
||||
a_Pkt.WriteBEUInt8(SLIME_SIZE);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_VARINT);
|
||||
a_Pkt.WriteVarInt32(static_cast<UInt32>(MagmaCube.GetSize()));
|
||||
break;
|
||||
} // case mtMagmaCube
|
||||
|
||||
case mtOcelot:
|
||||
{
|
||||
auto & Ocelot = reinterpret_cast<const cOcelot &>(a_Mob);
|
||||
|
||||
a_Pkt.WriteBEUInt8(AGEABLE_BABY);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
|
||||
a_Pkt.WriteBool(Ocelot.IsBaby());
|
||||
break;
|
||||
} // case mtOcelot
|
||||
|
||||
case mtCow:
|
||||
{
|
||||
auto & Cow = reinterpret_cast<const cCow &>(a_Mob);
|
||||
|
||||
a_Pkt.WriteBEUInt8(AGEABLE_BABY);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
|
||||
a_Pkt.WriteBool(Cow.IsBaby());
|
||||
break;
|
||||
} // case mtCow
|
||||
|
||||
case mtChicken:
|
||||
{
|
||||
auto & Chicken = reinterpret_cast<const cChicken &>(a_Mob);
|
||||
|
||||
a_Pkt.WriteBEUInt8(AGEABLE_BABY);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
|
||||
a_Pkt.WriteBool(Chicken.IsBaby());
|
||||
break;
|
||||
} // case mtChicken
|
||||
|
||||
case mtPig:
|
||||
{
|
||||
auto & Pig = reinterpret_cast<const cPig &>(a_Mob);
|
||||
|
||||
a_Pkt.WriteBEUInt8(AGEABLE_BABY);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
|
||||
a_Pkt.WriteBool(Pig.IsBaby());
|
||||
|
||||
a_Pkt.WriteBEUInt8(PIG_HAS_SADDLE);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
|
||||
a_Pkt.WriteBool(Pig.IsSaddled());
|
||||
|
||||
break;
|
||||
} // case mtPig
|
||||
|
||||
case mtSheep:
|
||||
{
|
||||
auto & Sheep = reinterpret_cast<const cSheep &>(a_Mob);
|
||||
|
||||
a_Pkt.WriteBEUInt8(AGEABLE_BABY);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
|
||||
a_Pkt.WriteBool(Sheep.IsBaby());
|
||||
|
||||
a_Pkt.WriteBEUInt8(SHEEP_STATUS);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_BYTE);
|
||||
Int8 SheepMetadata = 0;
|
||||
SheepMetadata = static_cast<Int8>(Sheep.GetFurColor());
|
||||
if (Sheep.IsSheared())
|
||||
{
|
||||
SheepMetadata |= 0x10;
|
||||
}
|
||||
a_Pkt.WriteBEInt8(SheepMetadata);
|
||||
break;
|
||||
} // case mtSheep
|
||||
|
||||
case mtRabbit:
|
||||
{
|
||||
auto & Rabbit = reinterpret_cast<const cRabbit &>(a_Mob);
|
||||
a_Pkt.WriteBEUInt8(AGEABLE_BABY);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
|
||||
a_Pkt.WriteBool(Rabbit.IsBaby());
|
||||
|
||||
a_Pkt.WriteBEUInt8(RABBIT_TYPE);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_VARINT);
|
||||
a_Pkt.WriteVarInt32(static_cast<UInt32>(Rabbit.GetRabbitType()));
|
||||
break;
|
||||
} // case mtRabbit
|
||||
|
||||
case mtSkeleton:
|
||||
{
|
||||
auto & Skeleton = reinterpret_cast<const cSkeleton &>(a_Mob);
|
||||
a_Pkt.WriteBEUInt8(SKELETON_TYPE);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_VARINT);
|
||||
a_Pkt.WriteVarInt32(Skeleton.IsWither() ? 1 : 0);
|
||||
break;
|
||||
} // case mtSkeleton
|
||||
|
||||
case mtSlime:
|
||||
{
|
||||
auto & Slime = reinterpret_cast<const cSlime &>(a_Mob);
|
||||
a_Pkt.WriteBEUInt8(SLIME_SIZE);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_VARINT);
|
||||
a_Pkt.WriteVarInt32(static_cast<UInt32>(Slime.GetSize()));
|
||||
break;
|
||||
} // case mtSlime
|
||||
|
||||
case mtVillager:
|
||||
{
|
||||
auto & Villager = reinterpret_cast<const cVillager &>(a_Mob);
|
||||
a_Pkt.WriteBEUInt8(AGEABLE_BABY);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
|
||||
a_Pkt.WriteBool(Villager.IsBaby());
|
||||
|
||||
a_Pkt.WriteBEUInt8(VILLAGER_PROFESSION);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_VARINT);
|
||||
a_Pkt.WriteVarInt32(static_cast<UInt32>(Villager.GetVilType()));
|
||||
break;
|
||||
} // case mtVillager
|
||||
|
||||
case mtWitch:
|
||||
{
|
||||
auto & Witch = reinterpret_cast<const cWitch &>(a_Mob);
|
||||
a_Pkt.WriteBEUInt8(WITCH_AGGRESIVE);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
|
||||
a_Pkt.WriteBool(Witch.IsAngry());
|
||||
break;
|
||||
} // case mtWitch
|
||||
|
||||
case mtWither:
|
||||
{
|
||||
auto & Wither = reinterpret_cast<const cWither &>(a_Mob);
|
||||
a_Pkt.WriteBEUInt8(WITHER_INVULNERABLE_TIMER);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_VARINT);
|
||||
a_Pkt.WriteVarInt32(Wither.GetWitherInvulnerableTicks());
|
||||
|
||||
// TODO: Use boss bar packet for health
|
||||
break;
|
||||
} // case mtWither
|
||||
|
||||
case mtWolf:
|
||||
{
|
||||
auto & Wolf = reinterpret_cast<const cWolf &>(a_Mob);
|
||||
a_Pkt.WriteBEUInt8(AGEABLE_BABY);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
|
||||
a_Pkt.WriteBool(Wolf.IsBaby());
|
||||
|
||||
Int8 WolfStatus = 0;
|
||||
if (Wolf.IsSitting())
|
||||
{
|
||||
WolfStatus |= 0x1;
|
||||
}
|
||||
if (Wolf.IsAngry())
|
||||
{
|
||||
WolfStatus |= 0x2;
|
||||
}
|
||||
if (Wolf.IsTame())
|
||||
{
|
||||
WolfStatus |= 0x4;
|
||||
}
|
||||
a_Pkt.WriteBEUInt8(TAMEABLE_ANIMAL_STATUS);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_BYTE);
|
||||
a_Pkt.WriteBEInt8(WolfStatus);
|
||||
|
||||
a_Pkt.WriteBEUInt8(WOLF_DAMAGE_TAKEN);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_FLOAT);
|
||||
a_Pkt.WriteBEFloat(static_cast<float>(a_Mob.GetHealth())); // TODO Not use the current health
|
||||
|
||||
a_Pkt.WriteBEUInt8(WOLF_BEGGING);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
|
||||
a_Pkt.WriteBool(Wolf.IsBegging());
|
||||
|
||||
a_Pkt.WriteBEUInt8(WOLF_COLLAR_COLOR);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_VARINT);
|
||||
a_Pkt.WriteVarInt32(static_cast<UInt32>(Wolf.GetCollarColor()));
|
||||
break;
|
||||
} // case mtWolf
|
||||
|
||||
case mtZombie:
|
||||
{
|
||||
auto & Zombie = reinterpret_cast<const cZombie &>(a_Mob);
|
||||
a_Pkt.WriteBEUInt8(AGEABLE_BABY);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
|
||||
a_Pkt.WriteBool(Zombie.IsBaby());
|
||||
|
||||
a_Pkt.WriteBEUInt8(ZOMBIE_TYPE);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_VARINT);
|
||||
a_Pkt.WriteVarInt32(Zombie.IsVillagerZombie() ? 1 : 0); // TODO: This actually encodes the zombie villager profession, but that isn't implemented yet.
|
||||
|
||||
a_Pkt.WriteBEUInt8(ZOMBIE_CONVERTING);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
|
||||
a_Pkt.WriteBool(Zombie.IsConverting());
|
||||
break;
|
||||
} // case mtZombie
|
||||
|
||||
case mtZombiePigman:
|
||||
{
|
||||
auto & ZombiePigman = reinterpret_cast<const cZombiePigman &>(a_Mob);
|
||||
a_Pkt.WriteBEUInt8(AGEABLE_BABY);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
|
||||
a_Pkt.WriteBool(ZombiePigman.IsBaby());
|
||||
break;
|
||||
} // case mtZombiePigman
|
||||
} // switch (a_Mob.GetType())
|
||||
}
|
34
src/Protocol/Protocol110x.h
Normal file
34
src/Protocol/Protocol110x.h
Normal file
@ -0,0 +1,34 @@
|
||||
|
||||
// Protocol110x.h
|
||||
|
||||
/*
|
||||
Declares the 1.10.x protocol classes:
|
||||
- cProtocol1100
|
||||
- release 1.10.0 protocol (#210)
|
||||
(others may be added later in the future for the 1.10 release series)
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Protocol19x.h"
|
||||
|
||||
class cProtocol1100 :
|
||||
public cProtocol194
|
||||
{
|
||||
typedef cProtocol194 super;
|
||||
|
||||
public:
|
||||
cProtocol1100(cClientHandle * a_Client, const AString &a_ServerAddress, UInt16 a_ServerPort, UInt32 a_State);
|
||||
|
||||
virtual void SendSoundEffect(const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch) override;
|
||||
|
||||
virtual void HandlePacketStatusRequest(cByteBuffer & a_ByteBuffer) override;
|
||||
|
||||
protected:
|
||||
virtual void WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a_Entity) override;
|
||||
virtual void WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob) override;
|
||||
};
|
@ -739,7 +739,7 @@ void cProtocol190::SendPickupSpawn(const cPickup & a_Pickup)
|
||||
{
|
||||
ASSERT(m_State == 3); // In game mode?
|
||||
|
||||
{
|
||||
{ // TODO Use SendSpawnObject
|
||||
cPacketizer Pkt(*this, 0x00); // Spawn Object packet
|
||||
Pkt.WriteVarInt32(a_Pickup.GetUniqueID());
|
||||
// TODO: Bad way to write a UUID, and it's not a true UUID, but this is functional for now.
|
||||
@ -757,14 +757,7 @@ void cProtocol190::SendPickupSpawn(const cPickup & a_Pickup)
|
||||
Pkt.WriteBEInt16(0);
|
||||
}
|
||||
|
||||
{
|
||||
cPacketizer Pkt(*this, 0x39); // Entity Metadata packet
|
||||
Pkt.WriteVarInt32(a_Pickup.GetUniqueID());
|
||||
Pkt.WriteBEUInt8(5); // Index 5: Item
|
||||
Pkt.WriteBEUInt8(METADATA_TYPE_ITEM);
|
||||
WriteItem(Pkt, a_Pickup.GetItem());
|
||||
Pkt.WriteBEUInt8(0xff); // End of metadata
|
||||
}
|
||||
SendEntityMetadata(a_Pickup);
|
||||
}
|
||||
|
||||
|
||||
@ -1057,12 +1050,7 @@ void cProtocol190::SendPlayerSpawn(const cPlayer & a_Player)
|
||||
Pkt.WriteBEDouble(a_Player.GetPosZ());
|
||||
Pkt.WriteByteAngle(a_Player.GetYaw());
|
||||
Pkt.WriteByteAngle(a_Player.GetPitch());
|
||||
Pkt.WriteBEUInt8(6); // Start metadata - Index 6: Health
|
||||
Pkt.WriteBEUInt8(METADATA_TYPE_FLOAT);
|
||||
Pkt.WriteBEFloat(static_cast<float>(a_Player.GetHealth()));
|
||||
Pkt.WriteBEUInt8(2); // Index 2: Custom name
|
||||
Pkt.WriteBEUInt8(METADATA_TYPE_STRING);
|
||||
Pkt.WriteString(a_Player.GetName());
|
||||
WriteEntityMetadata(Pkt, a_Player);
|
||||
Pkt.WriteBEUInt8(0xff); // Metadata: end
|
||||
}
|
||||
|
||||
@ -3520,7 +3508,22 @@ void cProtocol190::WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a_En
|
||||
|
||||
switch (a_Entity.GetEntityType())
|
||||
{
|
||||
case cEntity::etPlayer: break; // TODO?
|
||||
case cEntity::etPlayer:
|
||||
{
|
||||
auto & Player = reinterpret_cast<const cPlayer &>(a_Entity);
|
||||
|
||||
// TODO Set player custom name to their name.
|
||||
// Then it's possible to move the custom name of mobs to the entities
|
||||
// and to remove the "special" player custom name.
|
||||
a_Pkt.WriteBEUInt8(2); // Index 2: Custom name
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_STRING);
|
||||
a_Pkt.WriteString(Player.GetName());
|
||||
|
||||
a_Pkt.WriteBEUInt8(6); // Start metadata - Index 6: Health
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_FLOAT);
|
||||
a_Pkt.WriteBEFloat(static_cast<float>(Player.GetHealth()));
|
||||
break;
|
||||
}
|
||||
case cEntity::etPickup:
|
||||
{
|
||||
a_Pkt.WriteBEUInt8(5); // Index 5: Item
|
||||
@ -4367,8 +4370,3 @@ void cProtocol194::SendUpdateSign(int a_BlockX, int a_BlockY, int a_BlockZ, cons
|
||||
Writer.Finish();
|
||||
Pkt.WriteBuf(Writer.GetResult().data(), Writer.GetResult().size());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -259,10 +259,10 @@ protected:
|
||||
void WriteItem(cPacketizer & a_Pkt, const cItem & a_Item);
|
||||
|
||||
/** Writes the metadata for the specified entity, not including the terminating 0xff. */
|
||||
void WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a_Entity);
|
||||
virtual void WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a_Entity);
|
||||
|
||||
/** Writes the mob-specific metadata for the specified mob */
|
||||
void WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob);
|
||||
virtual void WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob);
|
||||
|
||||
/** Writes the entity properties for the specified entity, including the Count field. */
|
||||
void WriteEntityProperties(cPacketizer & a_Pkt, const cEntity & a_Entity);
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "ProtocolRecognizer.h"
|
||||
#include "Protocol18x.h"
|
||||
#include "Protocol19x.h"
|
||||
#include "Protocol110x.h"
|
||||
#include "Packetizer.h"
|
||||
#include "../ClientHandle.h"
|
||||
#include "../Root.h"
|
||||
@ -47,11 +48,12 @@ AString cProtocolRecognizer::GetVersionTextFromInt(int a_ProtocolVersion)
|
||||
{
|
||||
switch (a_ProtocolVersion)
|
||||
{
|
||||
case PROTO_VERSION_1_8_0: return "1.8";
|
||||
case PROTO_VERSION_1_9_0: return "1.9";
|
||||
case PROTO_VERSION_1_9_1: return "1.9.1";
|
||||
case PROTO_VERSION_1_9_2: return "1.9.2";
|
||||
case PROTO_VERSION_1_9_4: return "1.9.4";
|
||||
case PROTO_VERSION_1_8_0: return "1.8";
|
||||
case PROTO_VERSION_1_9_0: return "1.9";
|
||||
case PROTO_VERSION_1_9_1: return "1.9.1";
|
||||
case PROTO_VERSION_1_9_2: return "1.9.2";
|
||||
case PROTO_VERSION_1_9_4: return "1.9.4";
|
||||
case PROTO_VERSION_1_10_0: return "1.10";
|
||||
}
|
||||
ASSERT(!"Unknown protocol version");
|
||||
return Printf("Unknown protocol (%d)", a_ProtocolVersion);
|
||||
@ -1047,6 +1049,11 @@ bool cProtocolRecognizer::TryRecognizeLengthedProtocol(UInt32 a_PacketLengthRema
|
||||
m_Protocol = new cProtocol194(m_Client, ServerAddress, ServerPort, NextState);
|
||||
return true;
|
||||
}
|
||||
case PROTO_VERSION_1_10_0:
|
||||
{
|
||||
m_Protocol = new cProtocol1100(m_Client, ServerAddress, ServerPort, NextState);
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
{
|
||||
LOGINFO("Client \"%s\" uses an unsupported protocol (lengthed, version %u (0x%x))",
|
||||
|
@ -18,8 +18,8 @@
|
||||
|
||||
|
||||
// Adjust these if a new protocol is added or an old one is removed:
|
||||
#define MCS_CLIENT_VERSIONS "1.8.x, 1.9.x"
|
||||
#define MCS_PROTOCOL_VERSIONS "47, 107, 108, 109, 110"
|
||||
#define MCS_CLIENT_VERSIONS "1.8.x, 1.9.x, 1.10.x"
|
||||
#define MCS_PROTOCOL_VERSIONS "47, 107, 108, 109, 110, 210"
|
||||
|
||||
|
||||
|
||||
@ -33,11 +33,12 @@ class cProtocolRecognizer :
|
||||
public:
|
||||
enum
|
||||
{
|
||||
PROTO_VERSION_1_8_0 = 47,
|
||||
PROTO_VERSION_1_9_0 = 107,
|
||||
PROTO_VERSION_1_9_1 = 108,
|
||||
PROTO_VERSION_1_9_2 = 109,
|
||||
PROTO_VERSION_1_9_4 = 110,
|
||||
PROTO_VERSION_1_8_0 = 47,
|
||||
PROTO_VERSION_1_9_0 = 107,
|
||||
PROTO_VERSION_1_9_1 = 108,
|
||||
PROTO_VERSION_1_9_2 = 109,
|
||||
PROTO_VERSION_1_9_4 = 110,
|
||||
PROTO_VERSION_1_10_0 = 210,
|
||||
} ;
|
||||
|
||||
cProtocolRecognizer(cClientHandle * a_Client);
|
||||
|
Loading…
Reference in New Issue
Block a user