From 427e582d5fcbd5025a81a4e89ccada47877ccc64 Mon Sep 17 00:00:00 2001 From: "madmaxoft@gmail.com" Date: Sun, 19 Aug 2012 19:42:32 +0000 Subject: Almost all packets' handling is now rewritten not to use cPacket descendants elsewhere than in cClientHandle. git-svn-id: http://mc-server.googlecode.com/svn/trunk@761 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- source/Bindings.cpp | 57 ++--- source/Bindings.h | 2 +- source/cChestEntity.cpp | 26 +-- source/cChunk.cpp | 96 +++++++++ source/cChunk.h | 6 + source/cChunkMap.cpp | 108 ++++++++++ source/cChunkMap.h | 17 ++ source/cClientHandle.cpp | 335 +++++++++++++++++++++++++----- source/cClientHandle.h | 51 ++--- source/cMonster.cpp | 252 ++++++++++++---------- source/cMonster.h | 4 +- source/cPawn.cpp | 6 +- source/cPickup.cpp | 9 +- source/cPiston.cpp | 48 ++--- source/cPlayer.cpp | 201 +++++++++--------- source/cPlayer.h | 11 +- source/cPlugin.cpp | 2 +- source/cPlugin.h | 4 +- source/cPluginManager.cpp | 37 ++-- source/cPluginManager.h | 1 + source/cPlugin_NewLua.cpp | 17 +- source/cPlugin_NewLua.h | 2 +- source/cPlugin_Squirrel.cpp | 6 +- source/cPlugin_Squirrel.h | 2 +- source/cSignEntity.cpp | 6 +- source/cWorld.cpp | 77 ++++++- source/cWorld.h | 7 + source/packets/cPacket_BlockAction.cpp | 12 +- source/packets/cPacket_BlockAction.h | 27 ++- source/packets/cPacket_EntityLook.h | 7 +- source/packets/cPacket_KeepAlive.h | 6 +- source/packets/cPacket_Player.cpp | 33 ++- source/packets/cPacket_Player.h | 4 +- source/packets/cPacket_Respawn.h | 27 +-- source/packets/cPacket_TeleportEntity.cpp | 14 +- source/packets/cPacket_TeleportEntity.h | 9 +- source/packets/cPacket_UpdateSign.cpp | 12 +- source/packets/cPacket_UpdateSign.h | 25 +-- source/packets/cPacket_UseEntity.cpp | 6 +- source/packets/cPacket_UseEntity.h | 24 ++- 40 files changed, 1089 insertions(+), 507 deletions(-) diff --git a/source/Bindings.cpp b/source/Bindings.cpp index b1a7867b3..9c3a22232 100644 --- a/source/Bindings.cpp +++ b/source/Bindings.cpp @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 08/19/12 13:48:32. +** Generated automatically by tolua++-1.0.92 on 08/19/12 21:46:45. */ #ifndef __cplusplus @@ -5931,14 +5931,14 @@ static int tolua_AllToLua_cPlayer_GetStance00(lua_State* tolua_S) #ifndef TOLUA_RELEASE tolua_Error tolua_err; if ( - !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isusertype(tolua_S,1,"const cPlayer",0,&tolua_err) || !tolua_isnoobj(tolua_S,2,&tolua_err) ) goto tolua_lerror; else #endif { - cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); + const cPlayer* self = (const cPlayer*) tolua_tousertype(tolua_S,1,0); #ifndef TOLUA_RELEASE if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetStance'", NULL); #endif @@ -6293,14 +6293,14 @@ static int tolua_AllToLua_cPlayer_GetClientHandle00(lua_State* tolua_S) #ifndef TOLUA_RELEASE tolua_Error tolua_err; if ( - !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || + !tolua_isusertype(tolua_S,1,"const cPlayer",0,&tolua_err) || !tolua_isnoobj(tolua_S,2,&tolua_err) ) goto tolua_lerror; else #endif { - cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); + const cPlayer* self = (const cPlayer*) tolua_tousertype(tolua_S,1,0); #ifndef TOLUA_RELEASE if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetClientHandle'", NULL); #endif @@ -6326,7 +6326,7 @@ static int tolua_AllToLua_cPlayer_SendMessage00(lua_State* tolua_S) tolua_Error tolua_err; if ( !tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || - !tolua_isstring(tolua_S,2,0,&tolua_err) || + !tolua_iscppstring(tolua_S,2,0,&tolua_err) || !tolua_isnoobj(tolua_S,3,&tolua_err) ) goto tolua_lerror; @@ -6334,15 +6334,16 @@ static int tolua_AllToLua_cPlayer_SendMessage00(lua_State* tolua_S) #endif { cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); - const char* a_Message = ((const char*) tolua_tostring(tolua_S,2,0)); + const AString a_Message = ((const AString) tolua_tocppstring(tolua_S,2,0)); #ifndef TOLUA_RELEASE if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SendMessage'", NULL); #endif { self->SendMessage(a_Message); + tolua_pushcppstring(tolua_S,(const char*)a_Message); } } - return 0; + return 1; #ifndef TOLUA_RELEASE tolua_lerror: tolua_error(tolua_S,"#ferror in function 'SendMessage'.",&tolua_err); @@ -7903,8 +7904,8 @@ static int tolua_AllToLua_cPlugin_OnDisconnect00(lua_State* tolua_S) tolua_Error tolua_err; if ( !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || - !tolua_iscppstring(tolua_S,2,0,&tolua_err) || - !tolua_isusertype(tolua_S,3,"cPlayer",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cPlayer",0,&tolua_err) || + !tolua_iscppstring(tolua_S,3,0,&tolua_err) || !tolua_isnoobj(tolua_S,4,&tolua_err) ) goto tolua_lerror; @@ -7912,13 +7913,13 @@ static int tolua_AllToLua_cPlugin_OnDisconnect00(lua_State* tolua_S) #endif { cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); - const AString a_Reason = ((const AString) tolua_tocppstring(tolua_S,2,0)); - cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,3,0)); + cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,2,0)); + const AString a_Reason = ((const AString) tolua_tocppstring(tolua_S,3,0)); #ifndef TOLUA_RELEASE if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnDisconnect'", NULL); #endif { - bool tolua_ret = (bool) self->OnDisconnect(a_Reason,a_Player); + bool tolua_ret = (bool) self->OnDisconnect(a_Player,a_Reason); tolua_pushboolean(tolua_S,(bool)tolua_ret); tolua_pushcppstring(tolua_S,(const char*)a_Reason); } @@ -8759,16 +8760,16 @@ public: return ( bool ) cPlugin:: OnCraftingNoRecipe(a_Player,a_Grid,a_Recipe); }; }; - bool OnDisconnect( const AString& a_Reason, cPlayer* a_Player) { + bool OnDisconnect( cPlayer* a_Player, const AString& a_Reason) { if (push_method("OnDisconnect", tolua_AllToLua_cPlugin_OnDisconnect00)) { - tolua_pushcppstring(lua_state, (const char*)a_Reason); tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer"); + tolua_pushcppstring(lua_state, (const char*)a_Reason); ToluaBase::dbcall(lua_state, 3, 1); bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); lua_pop(lua_state, 1); return tolua_ret; } else { - return ( bool ) cPlugin:: OnDisconnect(a_Reason,a_Player); + return ( bool ) cPlugin:: OnDisconnect(a_Player,a_Reason); }; }; bool OnKilled( cPawn* a_Killed, cEntity* a_Killer) { @@ -8936,8 +8937,8 @@ public: bool cPlugin__OnCraftingNoRecipe( const cPlayer* a_Player, const cCraftingGrid* a_Grid, cCraftingRecipe* a_Recipe) { return ( bool )cPlugin::OnCraftingNoRecipe(a_Player,a_Grid,a_Recipe); }; - bool cPlugin__OnDisconnect( const AString& a_Reason, cPlayer* a_Player) { - return ( bool )cPlugin::OnDisconnect(a_Reason,a_Player); + bool cPlugin__OnDisconnect( cPlayer* a_Player, const AString& a_Reason) { + return ( bool )cPlugin::OnDisconnect(a_Player,a_Reason); }; bool cPlugin__OnKilled( cPawn* a_Killed, cEntity* a_Killer) { return ( bool )cPlugin::OnKilled(a_Killed,a_Killer); @@ -9402,8 +9403,8 @@ static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnDisconnect00(lua_State* tolua_ tolua_Error tolua_err; if ( !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || - !tolua_iscppstring(tolua_S,2,0,&tolua_err) || - !tolua_isusertype(tolua_S,3,"cPlayer",0,&tolua_err) || + !tolua_isusertype(tolua_S,2,"cPlayer",0,&tolua_err) || + !tolua_iscppstring(tolua_S,3,0,&tolua_err) || !tolua_isnoobj(tolua_S,4,&tolua_err) ) goto tolua_lerror; @@ -9411,13 +9412,13 @@ static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnDisconnect00(lua_State* tolua_ #endif { Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); - const AString a_Reason = ((const AString) tolua_tocppstring(tolua_S,2,0)); - cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,3,0)); + cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,2,0)); + const AString a_Reason = ((const AString) tolua_tocppstring(tolua_S,3,0)); #ifndef TOLUA_RELEASE if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnDisconnect'", NULL); #endif { - bool tolua_ret = (bool) self->cPlugin__OnDisconnect(a_Reason,a_Player); + bool tolua_ret = (bool) self->cPlugin__OnDisconnect(a_Player,a_Reason); tolua_pushboolean(tolua_S,(bool)tolua_ret); tolua_pushcppstring(tolua_S,(const char*)a_Reason); } @@ -10219,16 +10220,16 @@ public: return ( bool ) cPlugin_NewLua:: OnCraftingNoRecipe(a_Player,a_Grid,a_Recipe); }; }; - bool OnDisconnect( const AString& a_Reason, cPlayer* a_Player) { + bool OnDisconnect( cPlayer* a_Player, const AString& a_Reason) { if (push_method("OnDisconnect", tolua_AllToLua_cPlugin_OnDisconnect00)) { - tolua_pushcppstring(lua_state, (const char*)a_Reason); tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer"); + tolua_pushcppstring(lua_state, (const char*)a_Reason); ToluaBase::dbcall(lua_state, 3, 1); bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); lua_pop(lua_state, 1); return tolua_ret; } else { - return ( bool ) cPlugin_NewLua:: OnDisconnect(a_Reason,a_Player); + return ( bool ) cPlugin_NewLua:: OnDisconnect(a_Player,a_Reason); }; }; bool OnKilled( cPawn* a_Killed, cEntity* a_Killer) { @@ -10399,8 +10400,8 @@ public: bool cPlugin_NewLua__OnCraftingNoRecipe( const cPlayer* a_Player, const cCraftingGrid* a_Grid, cCraftingRecipe* a_Recipe) { return ( bool )cPlugin_NewLua::OnCraftingNoRecipe(a_Player,a_Grid,a_Recipe); }; - bool cPlugin_NewLua__OnDisconnect( const AString& a_Reason, cPlayer* a_Player) { - return ( bool )cPlugin_NewLua::OnDisconnect(a_Reason,a_Player); + bool cPlugin_NewLua__OnDisconnect( cPlayer* a_Player, const AString& a_Reason) { + return ( bool )cPlugin_NewLua::OnDisconnect(a_Player,a_Reason); }; bool cPlugin_NewLua__OnKilled( cPawn* a_Killed, cEntity* a_Killer) { return ( bool )cPlugin_NewLua::OnKilled(a_Killed,a_Killer); diff --git a/source/Bindings.h b/source/Bindings.h index 769910f51..9487a8b7f 100644 --- a/source/Bindings.h +++ b/source/Bindings.h @@ -1,6 +1,6 @@ /* ** Lua binding: AllToLua -** Generated automatically by tolua++-1.0.92 on 08/19/12 13:48:33. +** Generated automatically by tolua++-1.0.92 on 08/19/12 21:46:45. */ /* Exported function */ diff --git a/source/cChestEntity.cpp b/source/cChestEntity.cpp index 5d015f42e..92a039dd7 100644 --- a/source/cChestEntity.cpp +++ b/source/cChestEntity.cpp @@ -184,13 +184,7 @@ void cChestEntity::UsedBy(cPlayer * a_Player) GetWindow()->SendWholeWindow( a_Player->GetClientHandle() ); } } - cPacket_BlockAction ChestOpen; - ChestOpen.m_PosX = GetPosX(); - ChestOpen.m_PosY = (short)GetPosY(); - ChestOpen.m_PosZ = GetPosZ(); - ChestOpen.m_Byte1 = (char)1; - ChestOpen.m_Byte2 = (char)1; - m_World->BroadcastToChunkOfBlock(m_PosX, m_PosY, m_PosZ, &ChestOpen); + m_World->BroadcastBlockAction(m_PosX, m_PosY, m_PosZ, 1, 1); // This is rather a hack // Instead of marking the chunk as dirty upon chest contents change, we mark it dirty now @@ -205,18 +199,18 @@ void cChestEntity::UsedBy(cPlayer * a_Player) -cItem *cChestEntity::GetContents(bool a_OnlyThis) +cItem * cChestEntity::GetContents(bool a_OnlyThis) { if (m_JoinedChest && !a_OnlyThis) { - cItem *Combined = new cItem[GetChestHeight()*c_ChestWidth]; - int i; - cItem *first = (m_TopChest) ? GetContents(true) : m_JoinedChest->GetContents(true); - cItem *second = (!m_TopChest) ? GetContents(true) : m_JoinedChest->GetContents(true); - for (i=0; i < GetChestHeight()*c_ChestWidth; i++) + // TODO: "Combined" memory leaks here + cItem * Combined = new cItem[GetChestHeight() * c_ChestWidth]; + cItem * first = (m_TopChest) ? GetContents(true) : m_JoinedChest->GetContents(true); + cItem * second = (!m_TopChest) ? GetContents(true) : m_JoinedChest->GetContents(true); + for (int i = 0; i < GetChestHeight() * c_ChestWidth; i++) { - int index = i % c_ChestHeight*c_ChestWidth; - if (i < c_ChestHeight*c_ChestWidth) + int index = i % (c_ChestHeight * c_ChestWidth); + if (i < c_ChestHeight * c_ChestWidth) Combined[index] = first[index]; else Combined[index] = second[index]; @@ -224,7 +218,9 @@ cItem *cChestEntity::GetContents(bool a_OnlyThis) return Combined; } else + { return m_Content; + } } diff --git a/source/cChunk.cpp b/source/cChunk.cpp index 11995b176..4d3c928a6 100644 --- a/source/cChunk.cpp +++ b/source/cChunk.cpp @@ -1787,6 +1787,102 @@ void cChunk::BroadcastEntityEquipment(const cEntity & a_Entity, short a_SlotNum, +void cChunk::BroadcastRelEntMoveLook(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude) +{ + for (cClientHandleList::const_iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr ) + { + if (*itr == a_Exclude) + { + continue; + } + (*itr)->SendRelEntMoveLook(a_Entity, a_RelX, a_RelY, a_RelZ); + } // for itr - LoadedByClient[] +} + + + + + +void cChunk::BroadcastRelEntMove(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude) +{ + for (cClientHandleList::const_iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr ) + { + if (*itr == a_Exclude) + { + continue; + } + (*itr)->SendRelEntMove(a_Entity, a_RelX, a_RelY, a_RelZ); + } // for itr - LoadedByClient[] +} + + + + + +void cChunk::BroadcastEntLook(const cEntity & a_Entity, const cClientHandle * a_Exclude) +{ + for (cClientHandleList::const_iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr ) + { + if (*itr == a_Exclude) + { + continue; + } + (*itr)->SendEntLook(a_Entity); + } // for itr - LoadedByClient[] +} + + + + + +void cChunk::BroadcastEntHeadLook(const cEntity & a_Entity, const cClientHandle * a_Exclude) +{ + for (cClientHandleList::const_iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr ) + { + if (*itr == a_Exclude) + { + continue; + } + (*itr)->SendEntHeadLook(a_Entity); + } // for itr - LoadedByClient[] +} + + + + + +void cChunk::BroadcastBlockAction(int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, const cClientHandle * a_Exclude) +{ + for (cClientHandleList::const_iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr ) + { + if (*itr == a_Exclude) + { + continue; + } + (*itr)->SendBlockAction(a_BlockX, a_BlockY, a_BlockZ, a_Byte1, a_Byte2); + } // for itr - LoadedByClient[] +} + + + + + +void cChunk::BroadcastDestroyEntity(const cEntity & a_Entity, const cClientHandle * a_Exclude) +{ + for (cClientHandleList::const_iterator itr = m_LoadedByClient.begin(); itr != m_LoadedByClient.end(); ++itr ) + { + if (*itr == a_Exclude) + { + continue; + } + (*itr)->SendDestroyEntity(a_Entity); + } // for itr - LoadedByClient[] +} + + + + + void cChunk::PositionToWorldPosition(int a_ChunkX, int a_ChunkY, int a_ChunkZ, int & a_X, int & a_Y, int & a_Z) { a_Y = a_ChunkY; diff --git a/source/cChunk.h b/source/cChunk.h index 375f9a17b..71811c7d5 100644 --- a/source/cChunk.h +++ b/source/cChunk.h @@ -177,6 +177,12 @@ public: void BroadcastPlayerAnimation(const cPlayer & a_Player, char a_Animation, const cClientHandle * a_Exclude = NULL); void BroadcastEntityEquipment(const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item, const cClientHandle * a_Exclude = NULL); + void BroadcastRelEntMoveLook (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude = NULL); + void BroadcastRelEntMove (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude = NULL); + void BroadcastEntLook (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); + void BroadcastEntHeadLook (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); + void BroadcastBlockAction (int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, const cClientHandle * a_Exclude = NULL); + void BroadcastDestroyEntity(const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); void PositionToWorldPosition(int a_ChunkX, int a_ChunkY, int a_ChunkZ, int & a_X, int & a_Y, int & a_Z); Vector3i PositionToWorldPosition( const Vector3i & a_InChunkPos ) { return PositionToWorldPosition( a_InChunkPos.x, a_InChunkPos.y, a_InChunkPos.z ); } diff --git a/source/cChunkMap.cpp b/source/cChunkMap.cpp index 5adc8f2c1..cbfbe1cf9 100644 --- a/source/cChunkMap.cpp +++ b/source/cChunkMap.cpp @@ -294,6 +294,114 @@ void cChunkMap::BroadcastEntityEquipment(const cEntity & a_Entity, short a_SlotN + +void cChunkMap::BroadcastRelEntMoveLook(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude) +{ + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkY(), a_Entity.GetChunkZ()); + if (Chunk == NULL) + { + return; + } + // It's perfectly legal to broadcast packets even to invalid chunks! + Chunk->BroadcastRelEntMoveLook(a_Entity, a_RelX, a_RelY, a_RelZ, a_Exclude); +} + + + + + + +void cChunkMap::BroadcastRelEntMove(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude) +{ + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkY(), a_Entity.GetChunkZ()); + if (Chunk == NULL) + { + return; + } + // It's perfectly legal to broadcast packets even to invalid chunks! + Chunk->BroadcastRelEntMove(a_Entity, a_RelX, a_RelY, a_RelZ, a_Exclude); +} + + + + + + +void cChunkMap::BroadcastEntLook(const cEntity & a_Entity, const cClientHandle * a_Exclude) +{ + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkY(), a_Entity.GetChunkZ()); + if (Chunk == NULL) + { + return; + } + // It's perfectly legal to broadcast packets even to invalid chunks! + Chunk->BroadcastEntLook(a_Entity, a_Exclude); +} + + + + + + +void cChunkMap::BroadcastEntHeadLook(const cEntity & a_Entity, const cClientHandle * a_Exclude) +{ + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkY(), a_Entity.GetChunkZ()); + if (Chunk == NULL) + { + return; + } + // It's perfectly legal to broadcast packets even to invalid chunks! + Chunk->BroadcastEntHeadLook(a_Entity, a_Exclude); +} + + + + + + +void cChunkMap::BroadcastBlockAction(int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, const cClientHandle * a_Exclude) +{ + cCSLock Lock(m_CSLayers); + int x, y, z, ChunkX, ChunkZ; + x = a_BlockX; + y = a_BlockY; + z = a_BlockZ; + cChunkDef::BlockToChunk(x, y, z, ChunkX, ChunkZ); + cChunkPtr Chunk = GetChunkNoGen(ChunkX, ZERO_CHUNK_Y, ChunkZ); + if (Chunk == NULL) + { + return; + } + // It's perfectly legal to broadcast packets even to invalid chunks! + Chunk->BroadcastBlockAction(a_BlockX, a_BlockY, a_BlockZ, a_Byte1, a_Byte2, a_Exclude); +} + + + + + + +void cChunkMap::BroadcastDestroyEntity(const cEntity & a_Entity, const cClientHandle * a_Exclude) +{ + cCSLock Lock(m_CSLayers); + cChunkPtr Chunk = GetChunkNoGen(a_Entity.GetChunkX(), a_Entity.GetChunkY(), a_Entity.GetChunkZ()); + if (Chunk == NULL) + { + return; + } + // It's perfectly legal to broadcast packets even to invalid chunks! + Chunk->BroadcastDestroyEntity(a_Entity, a_Exclude); +} + + + + + + void cChunkMap::UseBlockEntity(cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) { // a_Player rclked block entity at the coords specified, handle it diff --git a/source/cChunkMap.h b/source/cChunkMap.h index 3cf0720d1..fc595c906 100644 --- a/source/cChunkMap.h +++ b/source/cChunkMap.h @@ -53,6 +53,23 @@ public: /// Broadcasts an entity equipment change to all clients in the chunk where a_Entity is void BroadcastEntityEquipment(const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item, const cClientHandle * a_Exclude = NULL); + /// Broadcasts a RelEntMoveLook packet to all clients in the chunk where a_Entity is + void BroadcastRelEntMoveLook(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude = NULL); + + /// Broadcasts a RelEntMove packet to all clients in the chunk where a_Entity is + void BroadcastRelEntMove(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude = NULL); + + /// Broadcasts a EntLook packet to all clients in the chunk where a_Entity is + void BroadcastEntLook(const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); + + /// Broadcasts a EntHeadLook packet to all clients in the chunk where a_Entity is + void BroadcastEntHeadLook(const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); + + /// Broadcasts a BlockAction packet to all clients who are in the specified chunk + void BroadcastBlockAction(int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, const cClientHandle * a_Exclude = NULL); + + void BroadcastDestroyEntity(const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); + /// a_Player rclked block entity at the coords specified, handle it void UseBlockEntity(cPlayer * a_Player, int a_X, int a_Y, int a_Z); diff --git a/source/cClientHandle.cpp b/source/cClientHandle.cpp index 62c1a6ea5..a73e1f447 100644 --- a/source/cClientHandle.cpp +++ b/source/cClientHandle.cpp @@ -39,40 +39,45 @@ #include "cAuthenticator.h" #include "MersenneTwister.h" -#include "packets/cPacket_KeepAlive.h" -#include "packets/cPacket_Respawn.h" -#include "packets/cPacket_UpdateHealth.h" -#include "packets/cPacket_RelativeEntityMoveLook.h" -#include "packets/cPacket_Chat.h" -#include "packets/cPacket_Login.h" -#include "packets/cPacket_TimeUpdate.h" -#include "packets/cPacket_BlockDig.h" -#include "packets/cPacket_Handshake.h" +#include "packets/cPacket_13.h" #include "packets/cPacket_ArmAnim.h" +#include "packets/cPacket_BlockChange.h" +#include "packets/cPacket_BlockDig.h" #include "packets/cPacket_BlockPlace.h" -#include "packets/cPacket_Flying.h" +#include "packets/cPacket_Chat.h" +#include "packets/cPacket_CreativeInventoryAction.h" +#include "packets/cPacket_DestroyEntity.h" #include "packets/cPacket_Disconnect.h" -#include "packets/cPacket_PickupSpawn.h" -#include "packets/cPacket_ItemSwitch.h" #include "packets/cPacket_EntityEquipment.h" -#include "packets/cPacket_CreativeInventoryAction.h" +#include "packets/cPacket_EntityLook.h" +#include "packets/cPacket_Flying.h" +#include "packets/cPacket_Handshake.h" +#include "packets/cPacket_InventorySlot.h" +#include "packets/cPacket_ItemSwitch.h" +#include "packets/cPacket_KeepAlive.h" +#include "packets/cPacket_Login.h" +#include "packets/cPacket_MapChunk.h" +#include "packets/cPacket_Metadata.h" +#include "packets/cPacket_MultiBlock.h" +#include "packets/cPacket_NamedEntitySpawn.h" #include "packets/cPacket_NewInvalidState.h" +#include "packets/cPacket_PickupSpawn.h" +#include "packets/cPacket_Ping.h" +#include "packets/cPacket_Player.h" +#include "packets/cPacket_PreChunk.h" +#include "packets/cPacket_RelativeEntityMove.h" +#include "packets/cPacket_RelativeEntityMoveLook.h" +#include "packets/cPacket_Respawn.h" +#include "packets/cPacket_SpawnMob.h" +#include "packets/cPacket_TeleportEntity.h" +#include "packets/cPacket_TimeUpdate.h" +#include "packets/cPacket_UpdateHealth.h" +#include "packets/cPacket_UpdateSign.h" #include "packets/cPacket_UseEntity.h" +#include "packets/cPacket_WholeInventory.h" #include "packets/cPacket_WindowClick.h" #include "packets/cPacket_WindowClose.h" #include "packets/cPacket_WindowOpen.h" -#include "packets/cPacket_WholeInventory.h" -#include "packets/cPacket_13.h" -#include "packets/cPacket_UpdateSign.h" -#include "packets/cPacket_Ping.h" -#include "packets/cPacket_NamedEntitySpawn.h" -#include "packets/cPacket_MapChunk.h" -#include "packets/cPacket_PreChunk.h" -#include "packets/cPacket_InventorySlot.h" - -// DEBUG: -#include "packets/cPacket_BlockChange.h" -#include "packets/cPacket_MultiBlock.h" @@ -500,6 +505,8 @@ void cClientHandle::HandlePacket(cPacket * a_Packet) // Therefore I keep this function huge and untidy for the time being // ( http://forum.mc-server.org/showthread.php?tid=524 ) + // LOGD("Recv packet %02x", a_Packet->m_PacketID); + m_TimeLastPacket = cWorld::GetTime(); // LOG("Recv packet 0x%02x from client \"%s\" (\"%s\")", a_Packet->m_PacketID, m_Socket.GetIPString().c_str(), m_Username.c_str()); @@ -678,11 +685,35 @@ void cClientHandle::HandlePacket(cPacket * a_Packet) HandleWindowClick(wc->m_WindowID, wc->m_SlotNum, wc->m_IsRightClick, wc->m_IsShiftPressed, wc->m_HeldItem); break; } - case E_UPDATE_SIGN: HandleUpdateSign (reinterpret_cast (a_Packet)); break; - case E_USE_ENTITY: HandleUseEntity (reinterpret_cast (a_Packet)); break; - case E_RESPAWN: HandleRespawn(); break; - case E_DISCONNECT: HandleDisconnect (reinterpret_cast (a_Packet)); break; - case E_KEEP_ALIVE: HandleKeepAlive (reinterpret_cast (a_Packet)); break; + case E_UPDATE_SIGN: + { + cPacket_UpdateSign * us = reinterpret_cast(a_Packet); + HandleUpdateSign(us->m_BlockX, us->m_BlockY, us->m_BlockZ, us->m_Line1, us->m_Line2, us->m_Line3, us->m_Line4); + break; + } + case E_USE_ENTITY: + { + cPacket_UseEntity * ue = reinterpret_cast(a_Packet); + HandleUseEntity(ue->m_TargetEntityID, ue->m_IsLeftClick); + break; + } + case E_RESPAWN: + { + HandleRespawn(); + break; + } + case E_DISCONNECT: + { + cPacket_Disconnect * dc = reinterpret_cast(a_Packet); + HandleDisconnect(dc->m_Reason); + break; + } + case E_KEEP_ALIVE: + { + cPacket_KeepAlive * ka = reinterpret_cast(a_Packet); + HandleKeepAlive(ka->m_KeepAliveID); + break; + } } // switch (Packet type) break; } // case csPlaying @@ -797,7 +828,8 @@ void cClientHandle::HandleUnexpectedPacket(int a_PacketType) void cClientHandle::HandleMoveLookConfirm(double a_PosX, double a_PosY, double a_PosZ) { Vector3d ReceivedPosition = Vector3d(a_PosX, a_PosY, a_PosZ); - + // LOGD("Received MoveLook confirmation: {%0.2f %0.2f %0.2f}", a_PosX, a_PosY, a_PosZ); + // Test the distance between points with a small/large enough value instead of comparing directly. Floating point inaccuracies might screw stuff up double Dist = (ReceivedPosition - m_ConfirmPosition).SqrLength(); if (Dist < 1.0) @@ -813,7 +845,7 @@ void cClientHandle::HandleMoveLookConfirm(double a_PosX, double a_PosY, double a { LOGWARNING("Player \"%s\" sent a weird position confirmation %.2f blocks away, retrying", m_Username.c_str(), Dist); m_ConfirmPosition = m_Player->GetPosition(); - Send(cPacket_PlayerMoveLook(m_Player)); + SendPlayerMoveLook(); } } @@ -840,8 +872,25 @@ void cClientHandle::HandleCreativeInventory(short a_SlotNum, const cItem & a_Hel void cClientHandle::HandlePlayerPos(double a_PosX, double a_PosY, double a_PosZ, double a_Stance, bool a_IsOnGround) { - // LOG("recv player pos: %0.2f %0.2f %0.2f", PacketData->m_PosX, PacketData->m_PosY, PacketData->m_PosZ); - m_Player->MoveTo(Vector3d(a_PosX, a_PosY, a_PosZ)); + /* + // TODO: Invalid stance check + if ((a_PosY >= a_Stance) || (a_Stance > a_PosY + 1.65)) + { + LOGD("Invalid stance"); + SendPlayerMoveLook(); + return; + } + */ + + // LOGD("recv player pos: {%0.2f %0.2f %0.2f}, ground: %d", a_PosX, a_PosY, a_PosZ, a_IsOnGround ? 1 : 0); + Vector3d Pos(a_PosX, a_PosY, a_PosZ); + if ((m_Player->GetPosition() - Pos).SqrLength() > 100 * 100) + { + LOGD("Too far away (%0.2f), \"repairing\" the client", (m_Player->GetPosition() - Pos).Length()); + SendPlayerMoveLook(); + return; + } + m_Player->MoveTo(Pos); m_Player->SetStance(a_Stance); m_Player->SetTouchGround(a_IsOnGround); } @@ -1086,6 +1135,16 @@ void cClientHandle::HandlePlayerLook(float a_Rotation, float a_Pitch, bool a_IsO void cClientHandle::HandlePlayerMoveLook(double a_PosX, double a_PosY, double a_PosZ, double a_Stance, float a_Rotation, float a_Pitch, bool a_IsOnGround) { + /* + // TODO: Invalid stance check + if ((a_PosY >= a_Stance) || (a_Stance > a_PosY + 1.65)) + { + LOGD("Invalid stance"); + SendPlayerMoveLook(); + return; + } + */ + m_Player->MoveTo(Vector3d(a_PosX, a_PosY, a_PosZ)); m_Player->SetStance (a_Stance); m_Player->SetTouchGround(a_IsOnGround); @@ -1148,20 +1207,25 @@ void cClientHandle::HandleWindowClick(char a_WindowID, short a_SlotNum, bool a_I -void cClientHandle::HandleUpdateSign(cPacket_UpdateSign * a_Packet) +void cClientHandle::HandleUpdateSign( + int a_BlockX, int a_BlockY, int a_BlockZ, + const AString & a_Line1, const AString & a_Line2, + const AString & a_Line3, const AString & a_Line4 +) { cWorld * World = m_Player->GetWorld(); - World->UpdateSign(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, a_Packet->m_Line1, a_Packet->m_Line2, a_Packet->m_Line3, a_Packet->m_Line4); + World->UpdateSign(a_BlockX, a_BlockY, a_BlockZ, a_Line1, a_Line2, a_Line3, a_Line4); } -void cClientHandle::HandleUseEntity(cPacket_UseEntity * a_Packet) +void cClientHandle::HandleUseEntity(int a_TargetEntityID, bool a_IsLeftClick) { - if (!a_Packet->m_bLeftClick) + if (!a_IsLeftClick) { + // TODO: we don't handle right-clicking yet return; } @@ -1169,9 +1233,9 @@ void cClientHandle::HandleUseEntity(cPacket_UseEntity * a_Packet) { virtual bool Item(cEntity * a_Entity) override { - if( a_Entity->IsA("cPawn") ) + if (a_Entity->IsA("cPawn")) { - reinterpret_cast< cPawn* >( a_Entity )->TakeDamage(Damage, Instigator ); + reinterpret_cast(a_Entity)->TakeDamage(Damage, Instigator); } return true; } @@ -1184,7 +1248,7 @@ void cClientHandle::HandleUseEntity(cPacket_UseEntity * a_Packet) Callback.Instigator = m_Player; cWorld * World = m_Player->GetWorld(); - World->DoWithEntityByID(a_Packet->m_TargetID, Callback); + World->DoWithEntityByID(a_TargetEntityID, Callback); } @@ -1200,13 +1264,14 @@ void cClientHandle::HandleRespawn(void) -void cClientHandle::HandleDisconnect(cPacket_Disconnect * a_Packet) +void cClientHandle::HandleDisconnect(const AString & a_Reason) { - LOG("Received d/c packet from \"%s\"", m_Username.c_str()); - if (!cRoot::Get()->GetPluginManager()->CallHook(cPluginManager::HOOK_DISCONNECT, 2, a_Packet->m_Reason.c_str(), m_Player)) + LOGD("Received d/c packet from \"%s\" with reason \"%s\"", m_Username.c_str(), a_Reason.c_str()); + if (!cRoot::Get()->GetPluginManager()->CallHookDisconnect(m_Player, a_Reason)) { - cPacket_Chat DisconnectMessage(m_Username + " disconnected: " + a_Packet->m_Reason); - cRoot::Get()->GetServer()->Broadcast(DisconnectMessage); + AString DisconnectMessage; + Printf(DisconnectMessage, "%s disconnected: %s", m_Username.c_str(), a_Reason.c_str()); + m_Player->GetWorld()->BroadcastChat(DisconnectMessage, this); } Destroy(); } @@ -1215,9 +1280,9 @@ void cClientHandle::HandleDisconnect(cPacket_Disconnect * a_Packet) -void cClientHandle::HandleKeepAlive(cPacket_KeepAlive * a_Packet) +void cClientHandle::HandleKeepAlive(int a_KeepAliveID) { - if (a_Packet->m_KeepAliveID == m_PingID) + if (a_KeepAliveID == m_PingID) { cTimer t1; m_Ping = (short)((t1.GetNowTime() - m_PingStartTime) / 2); @@ -1225,6 +1290,9 @@ void cClientHandle::HandleKeepAlive(cPacket_KeepAlive * a_Packet) } + + + bool cClientHandle::CheckBlockInteractionsRate(void) { ASSERT(m_Player != NULL); @@ -1543,6 +1611,174 @@ void cClientHandle::SendWholeInventory(const cWindow & a_Window) +void cClientHandle::SendTeleportEntity(const cEntity & a_Entity) +{ + cPacket_TeleportEntity te(a_Entity); + Send(te); +} + + + + + +void cClientHandle::SendPlayerListItem(const cPlayer & a_Player) +{ + cPacket_PlayerListItem pli(a_Player.GetColor() + a_Player.GetName(), true, a_Player.GetClientHandle()->GetPing()); + Send(pli); +} + + + + + +void cClientHandle::SendPlayerPosition(void) +{ + cPacket_PlayerPosition pp(m_Player); + Send(pp); +} + + + + + +void cClientHandle::SendRelEntMoveLook(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) +{ + ASSERT(a_Entity.GetUniqueID() != m_Player->GetUniqueID()); // Must not send for self + + cPacket_RelativeEntityMoveLook reml; + reml.m_UniqueID = a_Entity.GetUniqueID(); + reml.m_MoveX = a_RelX; + reml.m_MoveY = a_RelY; + reml.m_MoveZ = a_RelZ; + reml.m_Yaw = (char)((a_Entity.GetRotation() / 360.f) * 256); + reml.m_Pitch = (char)((a_Entity.GetPitch() / 360.f) * 256); + Send(reml); +} + + + + + +void cClientHandle::SendRelEntMove(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) +{ + ASSERT(a_Entity.GetUniqueID() != m_Player->GetUniqueID()); // Must not send for self + + cPacket_RelativeEntityMove rem; + rem.m_UniqueID = a_Entity.GetUniqueID(); + rem.m_MoveX = a_RelX; + rem.m_MoveY = a_RelY; + rem.m_MoveZ = a_RelZ; + Send(rem); +} + + + + + +void cClientHandle::SendEntLook(const cEntity & a_Entity) +{ + ASSERT(a_Entity.GetUniqueID() != m_Player->GetUniqueID()); // Must not send for self + + cPacket_EntityLook el; + el.m_UniqueID = a_Entity.GetUniqueID(); + el.m_Rotation = (char)((a_Entity.GetRotation() / 360.f) * 256); + el.m_Pitch = (char)((a_Entity.GetPitch() / 360.f) * 256); + Send(el); +} + + + + + +void cClientHandle::SendEntHeadLook(const cEntity & a_Entity) +{ + ASSERT(a_Entity.GetUniqueID() != m_Player->GetUniqueID()); // Must not send for self + + cPacket_EntityHeadLook ehl(a_Entity); + Send(ehl); +} + + + + + +void cClientHandle::SendBlockAction(int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2) +{ + cPacket_BlockAction ba; + ba.m_BlockX = a_BlockX; + ba.m_BlockY = (short)a_BlockY; + ba.m_BlockZ = a_BlockZ; + ba.m_Byte1 = a_Byte1; + ba.m_Byte2 = a_Byte2; + Send(ba); +} + + + + + +void cClientHandle::SendHealth(void) +{ + cPacket_UpdateHealth Health; + Health.m_Health = m_Player->GetHealth(); + Health.m_Food = m_Player->GetFoodLevel(); + Health.m_Saturation = m_Player->GetFoodSaturationLevel(); + Send(Health); +} + + + + + +void cClientHandle::SendRespawn(void) +{ + cPacket_Respawn Packet; + Packet.m_CreativeMode = (char)m_Player->GetGameMode(); // Set GameMode packet based on Player's GameMode; + Send(Packet); +} + + + + + +void cClientHandle::SendGameMode(char a_GameMode) +{ + cPacket_NewInvalidState nis; + nis.m_Reason = 3; + nis.m_GameMode = a_GameMode; + Send(nis); +} + + + + + +void cClientHandle::SendDestroyEntity(const cEntity & a_Entity) +{ + cPacket_DestroyEntity de; + de.m_UniqueID = a_Entity.GetUniqueID(); + Send(de); +} + + + + + +void cClientHandle::SendPlayerMoveLook(void) +{ + cPacket_PlayerMoveLook pml(*m_Player); + /* + LOGD("Sending PlayerMoveLook: {%0.2f, %0.2f, %0.2f}, stance %0.2f, OnGround: %d", + m_Player->GetPosX(), m_Player->GetPosY(), m_Player->GetPosZ(), m_Player->GetStance(), m_Player->IsOnGround() ? 1 : 0 + ); + */ + Send(pml); +} + + + + + void cClientHandle::CheckIfWorldDownloaded(void) { if (m_State != csDownloadingWorld) @@ -1576,7 +1812,7 @@ void cClientHandle::SendConfirmPosition(void) } m_ConfirmPosition = m_Player->GetPosition(); - Send(cPacket_PlayerMoveLook(m_Player)); + SendPlayerMoveLook(); } @@ -1808,6 +2044,7 @@ void cClientHandle::GetOutgoingData(AString & a_Data) while (!m_PendingNrmSendPackets.empty() && (Data.size() < 1000)) { m_PendingNrmSendPackets.front()->Serialize(Data); + // LOGD("Sending packet 0x%02x", m_PendingNrmSendPackets.front()->m_PacketID); delete m_PendingNrmSendPackets.front(); m_PendingNrmSendPackets.erase(m_PendingNrmSendPackets.begin()); } diff --git a/source/cClientHandle.h b/source/cClientHandle.h index f2f7e7595..ff0599675 100644 --- a/source/cClientHandle.h +++ b/source/cClientHandle.h @@ -15,30 +15,6 @@ #include "Vector3d.h" #include "cSocketThreads.h" #include "ChunkDef.h" - -#include "packets/cPacket_KeepAlive.h" -#include "packets/cPacket_Player.h" -#include "packets/cPacket_Respawn.h" -#include "packets/cPacket_RelativeEntityMoveLook.h" -#include "packets/cPacket_Chat.h" -#include "packets/cPacket_Login.h" -#include "packets/cPacket_WindowClick.h" -#include "packets/cPacket_TimeUpdate.h" -#include "packets/cPacket_BlockDig.h" -#include "packets/cPacket_Handshake.h" -#include "packets/cPacket_ArmAnim.h" -#include "packets/cPacket_BlockPlace.h" -#include "packets/cPacket_Flying.h" -#include "packets/cPacket_Disconnect.h" -#include "packets/cPacket_PickupSpawn.h" -#include "packets/cPacket_ItemSwitch.h" -#include "packets/cPacket_EntityEquipment.h" -#include "packets/cPacket_CreativeInventoryAction.h" -#include "packets/cPacket_NewInvalidState.h" -#include "packets/cPacket_UseEntity.h" -#include "packets/cPacket_WindowClose.h" -#include "packets/cPacket_UpdateSign.h" -#include "packets/cPacket_Ping.h" #include "ByteBuffer.h" @@ -114,6 +90,19 @@ public: void SendWindowClose(char a_WindowID); void SendWholeInventory(const cInventory & a_Inventory); void SendWholeInventory(const cWindow & a_Window); + void SendTeleportEntity(const cEntity & a_Entity); + void SendPlayerListItem(const cPlayer & a_Player); + void SendPlayerPosition(void); + void SendRelEntMoveLook(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ); + void SendRelEntMove (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ); + void SendEntLook (const cEntity & a_Entity); + void SendEntHeadLook (const cEntity & a_Entity); + void SendBlockAction (int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2); + void SendHealth (void); + void SendRespawn(void); + void SendGameMode(char a_GameMode); + void SendDestroyEntity(const cEntity & a_Entity); + void SendPlayerMoveLook(void); const AString & GetUsername(void) const; //tolua_export @@ -212,14 +201,20 @@ private: void HandleSlotSelected (short a_SlotNum); void HandleWindowClose (char a_WindowID); void HandleWindowClick (char a_WindowID, short a_SlotNum, bool a_IsRightClick, bool a_IsShiftPressed, const cItem & a_HeldItem); - void HandleUpdateSign (cPacket_UpdateSign * a_Packet); - void HandleUseEntity (cPacket_UseEntity * a_Packet); + void HandleUpdateSign ( + int a_BlockX, int a_BlockY, int a_BlockZ, + const AString & a_Line1, const AString & a_Line2, + const AString & a_Line3, const AString & a_Line4 + ); + void HandleUseEntity (int a_TargetEntityID, bool a_IsLeftClick); void HandleRespawn (void); - void HandleDisconnect (cPacket_Disconnect * a_Packet); - void HandleKeepAlive (cPacket_KeepAlive * a_Packet); + void HandleDisconnect (const AString & a_Reason); + void HandleKeepAlive (int a_KeepAliveID); + /* /// Handles rclk with a dye; returns true if the dye is to be be consumed bool HandleDyes(cPacket_BlockPlace * a_Packet); + */ /// Returns true if the rate block interactions is within a reasonable limit (bot protection) bool CheckBlockInteractionsRate(void); diff --git a/source/cMonster.cpp b/source/cMonster.cpp index 3c73cae8a..a7c05977e 100644 --- a/source/cMonster.cpp +++ b/source/cMonster.cpp @@ -12,11 +12,6 @@ #include "MersenneTwister.h" #include "packets/cPacket_SpawnMob.h" -#include "packets/cPacket_EntityLook.h" -#include "packets/cPacket_TeleportEntity.h" -#include "packets/cPacket_RelativeEntityMoveLook.h" -#include "packets/cPacket_RelativeEntityMove.h" -#include "packets/cPacket_Metadata.h" #include "Vector3f.h" #include "Vector3i.h" @@ -60,11 +55,19 @@ cMonster::cMonster() m_MetaData = NORMAL; } + + + + cMonster::~cMonster() { LOG("cMonster::~cMonster()"); } + + + + bool cMonster::IsA( const char* a_EntityType ) { if( strcmp( a_EntityType, "cMonster" ) == 0 ) return true; @@ -100,6 +103,10 @@ void cMonster::MoveToPosition( const Vector3f & a_Position ) m_Destination = a_Position; } + + + + bool cMonster::ReachedDestination() { Vector3f Distance = (m_Destination) - Vector3f( m_Pos ); @@ -173,7 +180,7 @@ void cMonster::Tick(float a_Dt) ReplicateMovement(); Vector3f Distance = m_Destination - Vector3f( m_Pos ); - if( Distance.SqrLength() > 0.1f ) + if (Distance.SqrLength() > 0.1f) { float Rotation, Pitch; Distance.Normalize(); @@ -182,18 +189,22 @@ void cMonster::Tick(float a_Dt) SetPitch( Pitch ); } - if(m_EMState == IDLE) { //If enemy passive we ignore checks for player visibility + if (m_EMState == IDLE) + { + // If enemy passive we ignore checks for player visibility InStateIdle(a_Dt); } - if(m_EMState == CHASING) { //If we do not see a player anymore skip chasing action + if (m_EMState == CHASING) + { + // If we do not see a player anymore skip chasing action InStateChasing(a_Dt); } - if(m_EMState == ESCAPING) { + if (m_EMState == ESCAPING) + { InStateEscaping(a_Dt); } - } @@ -202,50 +213,38 @@ void cMonster::Tick(float a_Dt) void cMonster::ReplicateMovement() { - if(m_bDirtyOrientation && !m_bDirtyPosition) + if (m_bDirtyOrientation && !m_bDirtyPosition) { - cPacket_EntityLook EntityLook(*this); - m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, EntityLook ); + m_World->BroadcastEntLook(*this); m_bDirtyOrientation = false; } - if( m_bDirtyPosition ) + if (m_bDirtyPosition) { - float DiffX = (float)(GetPosX() - m_LastPosX ); - float DiffY = (float)(GetPosY() - m_LastPosY ); - float DiffZ = (float)(GetPosZ() - m_LastPosZ ); - float SqrDist = DiffX*DiffX + DiffY*DiffY + DiffZ*DiffZ; + float DiffX = (float)(GetPosX() - m_LastPosX); + float DiffY = (float)(GetPosY() - m_LastPosY); + float DiffZ = (float)(GetPosZ() - m_LastPosZ); + float SqrDist = DiffX * DiffX + DiffY * DiffY + DiffZ * DiffZ; if ( - (SqrDist > 4 * 4) // 4 blocks is max Relative Move - || (cWorld::GetTime() - m_TimeLastTeleportPacket > 2 ) // Send an absolute position every 2 seconds + (SqrDist > 4 * 4) // 4 blocks is max Relative Move + || (cWorld::GetTime() - m_TimeLastTeleportPacket > 2) // Send an absolute position every 2 seconds ) { - //LOG("Teleported %f", sqrtf(SqrDist) ); - cPacket_TeleportEntity TeleportEntity( this ); - m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, TeleportEntity); + // LOGD("Teleported %f", sqrtf(SqrDist) ); + m_World->BroadcastTeleportEntity(*this); m_TimeLastTeleportPacket = cWorld::GetTime(); } else - { // Relative move sucks balls! It's always wrong wtf! - if( m_bDirtyOrientation ) + { + // Relative move sucks balls! It's always wrong wtf! + if (m_bDirtyOrientation) { - cPacket_RelativeEntityMoveLook RelativeEntityMoveLook; - RelativeEntityMoveLook.m_UniqueID = GetUniqueID(); - RelativeEntityMoveLook.m_MoveX = (char)(DiffX*32); - RelativeEntityMoveLook.m_MoveY = (char)(DiffY*32); - RelativeEntityMoveLook.m_MoveZ = (char)(DiffZ*32); - RelativeEntityMoveLook.m_Yaw = (char)((GetRotation()/360.f)*256); - RelativeEntityMoveLook.m_Pitch = (char)((GetPitch()/360.f)*256); - m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, RelativeEntityMoveLook ); + m_World->BroadcastRelEntMoveLook(*this, (char)(DiffX * 32), (char)(DiffY * 32), (char)(DiffZ * 32)); + m_bDirtyOrientation = false; } else { - cPacket_RelativeEntityMove RelativeEntityMove; - RelativeEntityMove.m_UniqueID = GetUniqueID(); - RelativeEntityMove.m_MoveX = (char)(DiffX*32); - RelativeEntityMove.m_MoveY = (char)(DiffY*32); - RelativeEntityMove.m_MoveZ = (char)(DiffZ*32); - m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, RelativeEntityMove ); + m_World->BroadcastRelEntMove(*this, (char)(DiffX * 32), (char)(DiffY * 32), (char)(DiffZ * 32)); } } m_LastPosX = GetPosX(); @@ -325,6 +324,10 @@ void cMonster::HandlePhysics(float a_Dt) } } + + + + void cMonster::TakeDamage(int a_Damage, cEntity* a_Instigator) { cPawn::TakeDamage( a_Damage, a_Instigator ); @@ -332,96 +335,135 @@ void cMonster::TakeDamage(int a_Damage, cEntity* a_Instigator) AddReference( m_Target ); } + + + + void cMonster::KilledBy( cEntity* a_Killer ) { cPawn::KilledBy( a_Killer ); m_DestroyTimer = 0; } + + + + //----State Logic -const char *cMonster::GetState() { - switch(m_EMState) { - case IDLE: - return "Idle"; - break; - case ATTACKING: - return "Attacking"; - break; - case CHASING: - return "Chasing"; - break; - default: - return "Unknown"; - break; +const char *cMonster::GetState() +{ + switch(m_EMState) + { + case IDLE: return "Idle"; + case ATTACKING: return "Attacking"; + case CHASING: return "Chasing"; + default: return "Unknown"; } } -//for debugging -void cMonster::SetState(const char* a_str) + + + + +// for debugging +void cMonster::SetState(const AString & a_State) { - std::string str = a_str; - if(str.compare("Idle") == 0 ) { + if (a_State.compare("Idle") == 0) + { m_EMState = IDLE; - } else if(str.compare("Attacking") == 0 ) { + } + else if (a_State.compare("Attacking") == 0) + { m_EMState = ATTACKING; - } else if(str.compare("Chasing") == 0 ) { + } + else if (a_State.compare("Chasing") == 0) + { m_EMState = CHASING; - } else { + } + else + { printf("Invalid State"); } } + + + + //Checks to see if EventSeePlayer should be fired //monster sez: Do I see the player void cMonster::CheckEventSeePlayer() { cPlayer *Closest = FindClosestPlayer(); - if(Closest) + if (Closest) { EventSeePlayer(Closest); } } + + + + void cMonster::CheckEventLostPlayer() { Vector3f pos; - cTracer LineOfSight(GetWorld() ); + cTracer LineOfSight(GetWorld()); - if(m_Target != 0) { + if (m_Target != NULL) + { pos = m_Target->GetPosition(); - if((pos - m_Pos).Length() > m_SightDistance || LineOfSight.Trace(m_Pos,(pos - m_Pos), (int)(pos - m_Pos).Length())) + if ((pos - m_Pos).Length() > m_SightDistance || LineOfSight.Trace(m_Pos,(pos - m_Pos), (int)(pos - m_Pos).Length())) { EventLosePlayer(); } - } else { + } + else + { EventLosePlayer(); } } -//What to do if player is seen -//default to change state to chasing + + + + +// What to do if player is seen +// default to change state to chasing void cMonster::EventSeePlayer(cEntity *a_SeenPlayer) { m_Target = a_SeenPlayer; AddReference( m_Target ); } -void cMonster::EventLosePlayer(){ + + + + +void cMonster::EventLosePlayer() +{ Dereference(m_Target); m_Target = 0; m_EMState = IDLE; } + + + + //What to do if in Idle State -void cMonster::InStateIdle(float a_Dt) { +void cMonster::InStateIdle(float a_Dt) +{ idle_interval += a_Dt; - if(idle_interval > 1) { //at this interval the results are predictable + if (idle_interval > 1) + { + // at this interval the results are predictable MTRand r1; int rem = r1.randInt()%6 + 1; - //LOG("Moving: int: %3.3f rem: %i",idle_interval,rem); - idle_interval -= 1; //So nothing gets dropped when the server hangs for a few seconds + // LOGD("Moving: int: %3.3f rem: %i",idle_interval,rem); + idle_interval -= 1; // So nothing gets dropped when the server hangs for a few seconds Vector3f Dist; Dist.x = (float)((r1.randInt()%11)-5); Dist.z = (float)((r1.randInt()%11)-5); @@ -435,33 +477,35 @@ void cMonster::InStateIdle(float a_Dt) { } } -//What to do if in Chasing State -//This state should always be defined in each child class -void cMonster::InStateChasing(float a_Dt) { - (void)a_Dt; + + + + +// What to do if in Chasing State +// This state should always be defined in each child class +void cMonster::InStateChasing(float a_Dt) +{ + UNUSED(a_Dt); } -//What to do if in Escaping State -void cMonster::InStateEscaping(float a_Dt) { + + + + +// What to do if in Escaping State +void cMonster::InStateEscaping(float a_Dt) +{ (void)a_Dt; - if(m_Target) { + if(m_Target) + { Vector3d newloc = m_Pos; newloc.x = (m_Target->GetPosition().x < newloc.x)? (newloc.x + m_SightDistance): (newloc.x - m_SightDistance); newloc.z = (m_Target->GetPosition().z < newloc.z)? (newloc.z + m_SightDistance): (newloc.z - m_SightDistance); MoveToPosition(newloc); - } else { - m_EMState = IDLE; //this shouldnt be required but just to be safe } -} - - -//Do attack here -//a_Dt is passed so we can set attack rate -void cMonster::Attack(float a_Dt) { - m_AttackInterval += a_Dt * m_AttackRate; - if(m_Target != 0 && m_AttackInterval > 3.0) { //Setting this higher gives us more wiggle room for attackrate - m_AttackInterval = 0.0; - ((cPawn *)m_Target)->TakeDamage((int)m_AttackDamage,this); + else + { + m_EMState = IDLE; //this shouldnt be required but just to be safe } } @@ -469,28 +513,24 @@ void cMonster::Attack(float a_Dt) { -#if 0 -// TODO: Implement this debug function inside cWorld instead - the world owns the entities -void cMonster::ListMonsters() +// Do attack here +// a_Dt is passed so we can set attack rate +void cMonster::Attack(float a_Dt) { - - cWorld::EntityList Entities = cRoot::Get()->GetWorld()->GetEntities(); - cRoot::Get()->GetWorld()->LockEntities(); - for( cWorld::EntityList::iterator itr = Entities.begin(); itr != Entities.end(); ++itr) { - if((*itr)->GetEntityType() == cEntity::E_ENTITY){ - LOG("In state: %s type: %i attack rate: %i",((cMonster *)(*itr))->GetState(), ((cMonster *)(*itr))->GetMobType(),((cMonster *)(*itr))->GetAttackRate()); - - } + m_AttackInterval += a_Dt * m_AttackRate; + if ((m_Target != NULL) && (m_AttackInterval > 3.0)) + { + // Setting this higher gives us more wiggle room for attackrate + m_AttackInterval = 0.0; + ((cPawn *)m_Target)->TakeDamage((int)m_AttackDamage, this); } - cRoot::Get()->GetWorld()->UnlockEntities(); } -#endif -//Checks for Players close by and if they are visible return the closest +// Checks for Players close by and if they are visible return the closest cPlayer * cMonster::FindClosestPlayer(void) { return m_World->FindClosestPlayer(m_Pos, m_SightDistance); @@ -545,7 +585,7 @@ void cMonster::SetSightDistance(float sd) -void cMonster::AddRandomDropItem(cItems & a_Drops, unsigned int a_Min, unsigned int a_Max, ENUM_ITEM_ID a_Item, short a_ItemHealth) +void cMonster::AddRandomDropItem(cItems & a_Drops, unsigned int a_Min, unsigned int a_Max, short a_Item, short a_ItemHealth) { MTRand r1; int Count = r1.randInt() % (a_Max + 1 - a_Min) + a_Min; diff --git a/source/cMonster.h b/source/cMonster.h index ab247fcfa..d46cd9205 100644 --- a/source/cMonster.h +++ b/source/cMonster.h @@ -41,7 +41,7 @@ public: virtual bool ReachedDestination(); const char *GetState(); - void SetState(const char* str); + void SetState(const AString & str); static void ListMonsters(); virtual void CheckEventSeePlayer(); @@ -93,7 +93,7 @@ protected: float m_AttackRange; float m_AttackInterval; - void AddRandomDropItem(cItems & a_Drops, unsigned int a_Min, unsigned int a_Max, ENUM_ITEM_ID a_Item, short a_ItemHealth = 0); + void AddRandomDropItem(cItems & a_Drops, unsigned int a_Min, unsigned int a_Max, short a_Item, short a_ItemHealth = 0); }; //tolua_export diff --git a/source/cPawn.cpp b/source/cPawn.cpp index 9fe34059b..5b2b475c0 100644 --- a/source/cPawn.cpp +++ b/source/cPawn.cpp @@ -122,9 +122,7 @@ void cPawn::TeleportTo( const double & a_PosX, const double & a_PosY, const doub { SetPosition( a_PosX, a_PosY, a_PosZ ); - cPacket_TeleportEntity TeleportEntity( this ); - - cRoot::Get()->GetServer()->Broadcast( TeleportEntity ); + GetWorld()->BroadcastTeleportEntity(*this); } @@ -133,7 +131,7 @@ void cPawn::TeleportTo( const double & a_PosX, const double & a_PosY, const doub void cPawn::Tick(float a_Dt) { - CheckMetaDataBurn(); //Check to see if pawn should burn based on block they are on + CheckMetaDataBurn(); // Check to see if pawn should burn based on block they are on if (GetMetaData() == BURNING) { diff --git a/source/cPickup.cpp b/source/cPickup.cpp index 2302c56a3..d643c9d88 100644 --- a/source/cPickup.cpp +++ b/source/cPickup.cpp @@ -148,18 +148,17 @@ void cPickup::Tick(float a_Dt) return; } - if(!m_bCollected) + if (!m_bCollected) { - HandlePhysics( a_Dt ); + HandlePhysics(a_Dt); } - if( !m_bReplicated || m_bDirtyPosition ) + if (!m_bReplicated || m_bDirtyPosition) { MoveToCorrectChunk(); m_bReplicated = true; m_bDirtyPosition = false; - cPacket_TeleportEntity TeleportEntity( this ); - GetWorld()->BroadcastToChunk( m_ChunkX, m_ChunkY, m_ChunkZ, TeleportEntity ); + GetWorld()->BroadcastTeleportEntity(*this); } } diff --git a/source/cPiston.cpp b/source/cPiston.cpp index be8b0dff3..b314cffe1 100644 --- a/source/cPiston.cpp +++ b/source/cPiston.cpp @@ -77,38 +77,32 @@ void cPiston::ExtendPiston( int pistx, int pisty, int pistz ) } int oldx = pistx, oldy = pisty, oldz = pistz; char currBlockMeta; - for (int i = dist+1; i>0; i--) + for (int i = dist + 1; i>0; i--) { - AddDir( pistx, pisty, pistz, pistonMeta & 7, -1 ) - currBlock = m_World->GetBlock( pistx, pisty, pistz ); - currBlockMeta = m_World->GetBlockMeta( pistx, pisty, pistz ); - m_World->SetBlock( oldx, oldy, oldz, currBlock, currBlockMeta ); + AddDir(pistx, pisty, pistz, pistonMeta & 7, -1) + currBlock = m_World->GetBlock(pistx, pisty, pistz); + currBlockMeta = m_World->GetBlockMeta(pistx, pisty, pistz); + m_World->SetBlock( oldx, oldy, oldz, currBlock, currBlockMeta); oldx = pistx; oldy = pisty; oldz = pistz; } - cPacket_BlockAction Action; - Action.m_PosX = (int)pistx; - Action.m_PosY = (short)pisty; - Action.m_PosZ = (int)pistz; - Action.m_Byte1 = 0; - Action.m_Byte2 = pistonMeta; - - m_World->BroadcastToChunkOfBlock(pistx, pisty, pistz, &Action); + m_World->BroadcastBlockAction(pistx, pisty, pistz, 0, pistonMeta); m_World->FastSetBlock( pistx, pisty, pistz, pistonBlock, pistonMeta | 0x8 ); int extx = pistx; int exty = pisty; int extz = pistz; - AddDir( extx, exty, extz, pistonMeta&7, 1 ) + AddDir(extx, exty, extz, pistonMeta & 7, 1) - m_World->SetBlock( extx, exty, extz, E_BLOCK_PISTON_EXTENSION, isSticky+pistonMeta&7 ); + m_World->SetBlock(extx, exty, extz, E_BLOCK_PISTON_EXTENSION, isSticky + pistonMeta & 7); - if (recalc) { + if (recalc) + { cRedstone Redstone(m_World); - Redstone.ChangeRedstone( extx, exty, extz, false ); //recalculate redstone around current device. - Redstone.ChangeRedstone( pistx, pisty, pistz, false ); //recalculate redstone around current device. + Redstone.ChangeRedstone(extx, exty, extz, false); // recalculate redstone around current device + Redstone.ChangeRedstone(pistx, pisty, pistz, false); // recalculate redstone around current device } } } @@ -125,21 +119,13 @@ void cPiston::RetractPiston( int pistx, int pisty, int pistz ) { return; } + m_World->BroadcastBlockAction(pistx, pisty, pistz, 1, pistonMeta & ~(8)); + m_World->FastSetBlock(pistx, pisty, pistz, pistonBlock, pistonMeta & ~(8)); - //send blockaction packet - cPacket_BlockAction Action; - Action.m_PosX = (int)pistx; - Action.m_PosY = (short)pisty; - Action.m_PosZ = (int)pistz; - Action.m_Byte1 = 1; - Action.m_Byte2 = pistonMeta & ~(8); - m_World->BroadcastToChunkOfBlock(pistx, pisty, pistz, &Action ); - m_World->FastSetBlock( pistx, pisty, pistz, pistonBlock, pistonMeta & ~(8) ); - - AddDir( pistx, pisty, pistz, pistonMeta & 7, 1 ) - if ( m_World->GetBlock( pistx, pisty, pistz ) == E_BLOCK_PISTON_EXTENSION ) + AddDir(pistx, pisty, pistz, pistonMeta & 7, 1) + if (m_World->GetBlock(pistx, pisty, pistz) == E_BLOCK_PISTON_EXTENSION) { - if ( pistonBlock == E_BLOCK_STICKY_PISTON ) + if (pistonBlock == E_BLOCK_STICKY_PISTON) { int tempx = pistx, tempy = pisty, tempz = pistz; AddDir( tempx, tempy, tempz, pistonMeta & 7, 1 ) diff --git a/source/cPlayer.cpp b/source/cPlayer.cpp index 7c0f0c703..14163a798 100644 --- a/source/cPlayer.cpp +++ b/source/cPlayer.cpp @@ -22,17 +22,6 @@ #include "MersenneTwister.h" #include "packets/cPacket_NamedEntitySpawn.h" -#include "packets/cPacket_EntityLook.h" -#include "packets/cPacket_TeleportEntity.h" -#include "packets/cPacket_RelativeEntityMove.h" -#include "packets/cPacket_RelativeEntityMoveLook.h" -#include "packets/cPacket_UpdateHealth.h" -#include "packets/cPacket_Respawn.h" -#include "packets/cPacket_DestroyEntity.h" -#include "packets/cPacket_Metadata.h" -#include "packets/cPacket_Chat.h" -#include "packets/cPacket_NewInvalidState.h" -#include "packets/cPacket_BlockAction.h" #include "Vector3d.h" #include "Vector3f.h" @@ -105,6 +94,8 @@ cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName) a_PlayerName.c_str(), m_Pos.x, m_Pos.y, m_Pos.z ); } + m_LastGroundHeight = (float)(m_Pos.y); + m_Stance = m_Pos.y + 1.62; } @@ -193,13 +184,11 @@ void cPlayer::Tick(float a_Dt) if (m_bDirtyOrientation && !m_bDirtyPosition) { - cPacket_EntityLook EntityLook(*this); - m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, EntityLook, m_ClientHandle ); - cPacket_EntityHeadLook EntityHeadLook(*this); - m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, EntityHeadLook, m_ClientHandle); + m_World->BroadcastEntLook(*this, m_ClientHandle); + m_World->BroadcastEntHeadLook(*this, m_ClientHandle); m_bDirtyOrientation = false; } - else if (m_bDirtyPosition ) + else if (m_bDirtyPosition) { cRoot::Get()->GetPluginManager()->CallHook( cPluginManager::E_PLUGIN_PLAYER_MOVE, 1, this ); @@ -212,32 +201,21 @@ void cPlayer::Tick(float a_Dt) (cWorld::GetTime() - m_TimeLastTeleportPacket > 2 ) // Send an absolute position every 2 seconds ) { - //LOG("Teleported %f", sqrtf(SqrDist) ); - cPacket_TeleportEntity TeleportEntity( this ); - m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, TeleportEntity, m_ClientHandle); + // LOG("Teleported %f", sqrtf(SqrDist) ); + m_World->BroadcastTeleportEntity(*this, m_ClientHandle); m_TimeLastTeleportPacket = cWorld::GetTime(); } else - { // Relative move sucks balls! It's always wrong wtf! - if( m_bDirtyOrientation ) + { + // Relative move sucks balls! It's always wrong wtf! + if (m_bDirtyOrientation) { - cPacket_RelativeEntityMoveLook RelativeEntityMoveLook; - RelativeEntityMoveLook.m_UniqueID = GetUniqueID(); - RelativeEntityMoveLook.m_MoveX = (char)(DiffX*32); - RelativeEntityMoveLook.m_MoveY = (char)(DiffY*32); - RelativeEntityMoveLook.m_MoveZ = (char)(DiffZ*32); - RelativeEntityMoveLook.m_Yaw = (char)((GetRotation()/360.f)*256); - RelativeEntityMoveLook.m_Pitch = (char)((GetPitch()/360.f)*256); - m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, RelativeEntityMoveLook, m_ClientHandle ); + m_World->BroadcastRelEntMoveLook(*this, (char)(DiffX * 32), (char)(DiffY * 32), (char)(DiffZ * 32), m_ClientHandle); + m_bDirtyOrientation = false; } else { - cPacket_RelativeEntityMove RelativeEntityMove; - RelativeEntityMove.m_UniqueID = GetUniqueID(); - RelativeEntityMove.m_MoveX = (char)(DiffX*32); - RelativeEntityMove.m_MoveY = (char)(DiffY*32); - RelativeEntityMove.m_MoveZ = (char)(DiffZ*32); - m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, RelativeEntityMove, m_ClientHandle ); + m_World->BroadcastRelEntMove(*this, (char)(DiffX * 32), (char)(DiffY * 32), (char)(DiffZ * 32), m_ClientHandle); } } m_LastPosX = GetPosX(); @@ -266,15 +244,19 @@ void cPlayer::Tick(float a_Dt) } } - //TODO: Increase Exhaustion level http://www.minecraftwiki.net/wiki/Hunger#Exhaustion_level_increase - if(m_FoodExhaustionLevel >= 4.f) + // TODO: Increase Exhaustion level http://www.minecraftwiki.net/wiki/Hunger#Exhaustion_level_increase + if (m_FoodExhaustionLevel >= 4.f) { m_FoodExhaustionLevel -= 4.f; - if(m_FoodSaturationLevel >= 1.f) + if (m_FoodSaturationLevel >= 1.f) + { m_FoodSaturationLevel--; + } else + { m_FoodLevel = MAX(m_FoodLevel -1, 0); + } SendHealth(); } @@ -293,40 +275,43 @@ void cPlayer::Tick(float a_Dt) -void cPlayer::SetTouchGround( bool a_bTouchGround ) +void cPlayer::SetTouchGround(bool a_bTouchGround) { m_bTouchGround = a_bTouchGround; - if( !m_bTouchGround ) + if (!m_bTouchGround) { cWorld* World = GetWorld(); char BlockID = World->GetBlock( float2int(m_Pos.x), float2int(m_Pos.y), float2int(m_Pos.z) ); if( BlockID != E_BLOCK_AIR ) { + // LOGD("TouchGround set to true by server"); m_bTouchGround = true; } if( BlockID == E_BLOCK_WATER || BlockID == E_BLOCK_STATIONARY_WATER || BlockID == E_BLOCK_LADDER || BlockID == E_BLOCK_TORCH ) { + // LOGD("Water / Ladder / Torch"); m_LastGroundHeight = (float)m_Pos.y; } } - if( m_bTouchGround ) + if (m_bTouchGround) { float Dist = (float)(m_LastGroundHeight - m_Pos.y); - if( Dist > 4.f ) // Player dropped + int Damage = (int)(Dist - 4.f); + if (Damage > 0) { - int Damage = (int)(Dist - 4.f); - if( Damage > 0 ) - { - TakeDamage( Damage, 0 ); - } + TakeDamage(Damage, 0); } m_LastGroundHeight = (float)m_Pos.y; } } + + + + void cPlayer::Heal( int a_Health ) { if( m_Health < GetMaxHealth() ) @@ -338,6 +323,10 @@ void cPlayer::Heal( int a_Health ) } } + + + + bool cPlayer::Feed(short a_Food, float a_Saturation) { if (m_FoodLevel >= GetMaxFoodLevel()) @@ -352,19 +341,25 @@ bool cPlayer::Feed(short a_Food, float a_Saturation) return true; } + + + + void cPlayer::SendHealth() { - cPacket_UpdateHealth Health; - Health.m_Health = GetHealth(); - Health.m_Food = GetFoodLevel(); - Health.m_Saturation = GetFoodSaturationLevel(); - if(m_ClientHandle != 0) - m_ClientHandle->Send( Health ); + if (m_ClientHandle != NULL) + { + m_ClientHandle->SendHealth(); + } } + + + + void cPlayer::TakeDamage( int a_Damage, cEntity* a_Instigator ) { - if(m_GameMode != eGameMode_Creative) + if (m_GameMode != eGameMode_Creative) { cPawn::TakeDamage( a_Damage, a_Instigator ); @@ -412,23 +407,20 @@ void cPlayer::Respawn() { m_Health = GetMaxHealth(); - // Create Respawn player packet - cPacket_Respawn Packet; - //Set Gamemode for packet by looking at world's gamemode (Need to check players gamemode.) - //Packet.m_CreativeMode = (char)GetWorld()->GetGameMode(); - Packet.m_CreativeMode = (char)m_GameMode; //Set GameMode packet based on Player's GameMode; - - //Send Packet - m_ClientHandle->Send( Packet ); + m_ClientHandle->SendRespawn(); - //Set non Burning + // Set non Burning SetMetaData(NORMAL); - TeleportTo( GetWorld()->GetSpawnX(), GetWorld()->GetSpawnY(), GetWorld()->GetSpawnZ() ); + TeleportTo(GetWorld()->GetSpawnX(), GetWorld()->GetSpawnY(), GetWorld()->GetSpawnZ()); - SetVisible( true ); + SetVisible(true); } + + + + double cPlayer::GetEyeHeight() { return m_Stance; @@ -486,14 +478,9 @@ void cPlayer::CloseWindow(char a_WindowType) // FIXME: If the player entity is destroyed while having a chest window open, the chest will not close if ((a_WindowType == 1) && (m_CurrentWindow->GetWindowType() == cWindow::Chest)) { - // Chest - cPacket_BlockAction ChestClose; - int y = 0; - m_CurrentWindow->GetOwner()->GetBlockPos(ChestClose.m_PosX, y, ChestClose.m_PosZ); - ChestClose.m_PosY = (short)y; - ChestClose.m_Byte1 = 1; // Unused, always 1 - ChestClose.m_Byte2 = 0; // 0 = closed - m_World->Broadcast(ChestClose); + int x, y, z; + m_CurrentWindow->GetOwner()->GetBlockPos(x, y, z); + m_World->BroadcastBlockAction(x, y, z, 1, 0); } m_CurrentWindow->Close( *this ); @@ -526,28 +513,33 @@ void cPlayer::SetLastBlockActionCnt( int a_LastBlockActionCnt ) -void cPlayer::SetGameMode( eGameMode a_GameMode ) +void cPlayer::SetGameMode(eGameMode a_GameMode) { - if ( (a_GameMode < 2) && (a_GameMode >= 0) ) + if ((a_GameMode >= 2) || (a_GameMode < 0)) { - if (m_GameMode != a_GameMode) - { - cInventory *OldInventory = 0; - if(m_GameMode == eGameMode_Survival) - OldInventory = m_Inventory; - else - OldInventory = m_CreativeInventory; - - m_GameMode = a_GameMode; - cPacket_NewInvalidState GameModePacket; - GameModePacket.m_Reason = 3; //GameModeChange - GameModePacket.m_GameMode = (char)a_GameMode; //GameModeChange - m_ClientHandle->Send ( GameModePacket ); - GetInventory().SendWholeInventory(m_ClientHandle); - - GetInventory().SetEquippedSlot(OldInventory->GetEquippedSlot()); - } + LOGWARNING("%s: Setting invalid gamemode: %d", GetName().c_str(), a_GameMode); + return; + } + + if (m_GameMode == a_GameMode) + { + // Gamemode already set + return; + } + + short OldSlotNum = 0; + if (m_GameMode == eGameMode_Survival) + { + OldSlotNum = m_Inventory->GetEquippedSlot(); + } + else + { + OldSlotNum = m_CreativeInventory->GetEquippedSlot(); } + m_GameMode = a_GameMode; + m_ClientHandle->SendGameMode(a_GameMode); + GetInventory().SendWholeInventory(m_ClientHandle); + GetInventory().SetEquippedSlot(OldSlotNum); } @@ -563,7 +555,7 @@ void cPlayer::LoginSetGameMode( eGameMode a_GameMode ) -void cPlayer::SetIP( std::string a_IP ) +void cPlayer::SetIP(const AString & a_IP) { m_IP = a_IP; } @@ -572,26 +564,21 @@ void cPlayer::SetIP( std::string a_IP ) -void cPlayer::SendMessage( const char* a_Message ) +void cPlayer::SendMessage(const AString & a_Message) { - m_ClientHandle->Send( cPacket_Chat( a_Message ) ); + m_ClientHandle->SendChat(a_Message); } -void cPlayer::TeleportTo( const double & a_PosX, const double & a_PosY, const double & a_PosZ ) +void cPlayer::TeleportTo(const double & a_PosX, const double & a_PosY, const double & a_PosZ) { SetPosition( a_PosX, a_PosY, a_PosZ ); - cPacket_TeleportEntity TeleportEntity( this ); - cRoot::Get()->GetServer()->Broadcast( TeleportEntity, GetClientHandle() ); - - - cPacket_PlayerPosition PlayerPosition( this ); - - m_ClientHandle->Send( PlayerPosition ); + m_World->BroadcastTeleportEntity(*this, GetClientHandle()); + m_ClientHandle->SendPlayerMoveLook(); } @@ -604,24 +591,24 @@ void cPlayer::MoveTo( const Vector3d & a_NewPos ) // TODO: Official server refuses position packets too far away from each other, kicking "hacked" clients; we should, too SetPosition( a_NewPos ); + SetStance(a_NewPos.y + 1.62); } -void cPlayer::SetVisible( bool a_bVisible ) +void cPlayer::SetVisible(bool a_bVisible) { if (a_bVisible && !m_bVisible) // Make visible { m_bVisible = true; - SpawnOn( NULL ); // Spawn on everybody + SpawnOn(NULL); // Spawn on all clients } if (!a_bVisible && m_bVisible) { m_bVisible = false; - cPacket_DestroyEntity DestroyEntity( this ); - m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, DestroyEntity ); // Destroy on all clients + m_World->BroadcastDestroyEntity(*this, m_ClientHandle); // Destroy on all clients } } diff --git a/source/cPlayer.h b/source/cPlayer.h index a27070048..ba8e15880 100644 --- a/source/cPlayer.h +++ b/source/cPlayer.h @@ -35,12 +35,13 @@ public: virtual void Tick(float a_Dt) override; void SetTouchGround( bool a_bTouchGround ); - inline void SetStance( const double & a_Stance ) { m_Stance = a_Stance; } + inline void SetStance( const double a_Stance ) { m_Stance = a_Stance; } double GetEyeHeight(); //tolua_export Vector3d GetEyePosition(); //tolua_export + OBSOLETE inline bool GetFlying() { return m_bTouchGround; } //tolua_export inline bool IsOnGround(void) const {return m_bTouchGround; } // tolua_export - inline const double & GetStance() { return m_Stance; } //tolua_export + inline const double GetStance(void) const { return m_Pos.y + 1.62; } //tolua_export // TODO: Proper stance when crouching etc. inline cInventory & GetInventory() { if(GetGameMode() == eGameMode_Survival) return *m_Inventory; else return *m_CreativeInventory; } //tolua_export virtual void TeleportTo( const double & a_PosX, const double & a_PosY, const double & a_PosZ ); //tolua_export @@ -53,7 +54,7 @@ public: void SetLastBlockActionTime(); //tolua_export void SetGameMode( eGameMode a_GameMode ); //tolua_export void LoginSetGameMode( eGameMode a_GameMode ); - void SetIP( std::string a_IP ); + void SetIP(const AString & a_IP); // Tries to move to a new position, with collision checks and stuff virtual void MoveTo( const Vector3d & a_NewPos ); //tolua_export @@ -62,9 +63,9 @@ public: void OpenWindow( cWindow* a_Window ); void CloseWindow(char a_WindowType); - cClientHandle * GetClientHandle() { return m_ClientHandle; } //tolua_export + cClientHandle * GetClientHandle(void) const { return m_ClientHandle; } //tolua_export - void SendMessage( const char* a_Message ); //tolua_export + void SendMessage(const AString & a_Message); //tolua_export const AString & GetName(void) const { return m_PlayerName; } //tolua_export void SetName(const AString & a_Name) { m_PlayerName = a_Name; } //tolua_export diff --git a/source/cPlugin.cpp b/source/cPlugin.cpp index 86f9e8fd5..2b3825d2a 100644 --- a/source/cPlugin.cpp +++ b/source/cPlugin.cpp @@ -141,7 +141,7 @@ bool cPlugin::OnCraftingNoRecipe(const cPlayer * a_Player, const cCraftingGrid * -bool cPlugin::OnDisconnect(const AString & a_Reason, cPlayer * a_Player) +bool cPlugin::OnDisconnect(cPlayer * a_Player, const AString & a_Reason) { UNUSED(a_Reason); UNUSED(a_Player); diff --git a/source/cPlugin.h b/source/cPlugin.h index 1c013c9e2..c3f7c41b6 100644 --- a/source/cPlugin.h +++ b/source/cPlugin.h @@ -56,8 +56,8 @@ public: virtual bool OnChunkGenerating (cWorld * a_World, int a_ChunkX, int a_ChunkZ, cLuaChunk * a_pLuaChunk); virtual bool OnCollectItem (cPickup* a_Pickup, cPlayer* a_Player ); virtual bool OnCraftingNoRecipe(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe); - virtual bool OnDisconnect (const AString & a_Reason, cPlayer * a_Player ); - virtual bool OnKilled (cPawn* a_Killed, cEntity* a_Killer ); + virtual bool OnDisconnect (cPlayer * a_Player, const AString & a_Reason); + virtual bool OnKilled (cPawn * a_Killed, cEntity* a_Killer ); virtual bool OnLogin (cClientHandle * a_Client, int a_ProtocolVersion, const AString & a_Username); virtual bool OnPlayerJoin (cPlayer* a_Player ); virtual void OnPlayerMove (cPlayer* a_Player ); diff --git a/source/cPluginManager.cpp b/source/cPluginManager.cpp index dd1051762..ec75a2e11 100644 --- a/source/cPluginManager.cpp +++ b/source/cPluginManager.cpp @@ -214,22 +214,6 @@ bool cPluginManager::CallHook(PluginHook a_Hook, unsigned int a_NumArgs, ...) break; } - case HOOK_DISCONNECT: - { - if( a_NumArgs != 2 ) break; - va_list argptr; - va_start( argptr, a_NumArgs); - const char* Reason = va_arg(argptr, const char* ); - cPlayer* Player = va_arg(argptr, cPlayer* ); - va_end (argptr); - for( PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr ) - { - if( (*itr)->OnDisconnect( Reason, Player ) ) - return true; - } - break; - } - case HOOK_PLAYER_JOIN: { if( a_NumArgs != 1 ) break; @@ -509,6 +493,27 @@ bool cPluginManager::CallHookCraftingNoRecipe(const cPlayer * a_Player, const cC +bool cPluginManager::CallHookDisconnect(cPlayer * a_Player, const AString & a_Reason) +{ + HookMap::iterator Plugins = m_Hooks.find(HOOK_DISCONNECT); + if (Plugins == m_Hooks.end()) + { + return false; + } + for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) + { + if ((*itr)->OnDisconnect(a_Player, a_Reason)) + { + return true; + } + } + return false; +} + + + + + bool cPluginManager::CallHookPostCrafting(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) { HookMap::iterator Plugins = m_Hooks.find(HOOK_POST_CRAFTING); diff --git a/source/cPluginManager.h b/source/cPluginManager.h index cac2ea977..fbde66935 100644 --- a/source/cPluginManager.h +++ b/source/cPluginManager.h @@ -103,6 +103,7 @@ public: //tolua_export bool CallHookChat (cPlayer * a_Player, const AString & a_Message); bool CallHookChunkGenerating (cWorld * a_World, int a_ChunkX, int a_ChunkZ, cLuaChunk * a_Chunk); bool CallHookCraftingNoRecipe(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe); + bool CallHookDisconnect (cPlayer * a_Player, const AString & a_Reason); bool CallHookLogin (cClientHandle * a_Client, int a_ProtocolVersion, const AString & a_Username); bool CallHookPostCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe); bool CallHookPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe); diff --git a/source/cPlugin_NewLua.cpp b/source/cPlugin_NewLua.cpp index 55010c3b2..fcea9e475 100644 --- a/source/cPlugin_NewLua.cpp +++ b/source/cPlugin_NewLua.cpp @@ -184,20 +184,23 @@ bool cPlugin_NewLua::OnCollectItem( cPickup* a_Pickup, cPlayer* a_Player ) -bool cPlugin_NewLua::OnDisconnect(const AString & a_Reason, cPlayer* a_Player ) +bool cPlugin_NewLua::OnDisconnect(cPlayer * a_Player, const AString & a_Reason) { - cCSLock Lock( m_CriticalSection ); - if( !PushFunction("OnDisconnect") ) + cCSLock Lock(m_CriticalSection); + if (!PushFunction("OnDisconnect")) + { return false; + } - tolua_pushstring( m_LuaState, a_Reason.c_str() ); tolua_pushusertype(m_LuaState, a_Player, "cPlayer"); + tolua_pushstring (m_LuaState, a_Reason.c_str()); - if( !CallFunction(2, 1, "OnDisconnect") ) + if (!CallFunction(2, 1, "OnDisconnect")) + { return false; + } - bool bRetVal = (tolua_toboolean( m_LuaState, -1, 0) > 0); - return bRetVal; + return (tolua_toboolean( m_LuaState, -1, 0) > 0); } diff --git a/source/cPlugin_NewLua.h b/source/cPlugin_NewLua.h index 6ead29293..1d931530b 100644 --- a/source/cPlugin_NewLua.h +++ b/source/cPlugin_NewLua.h @@ -33,7 +33,7 @@ public: //tolua_export virtual bool OnChunkGenerating (cWorld * a_World, int a_ChunkX, int a_ChunkZ, cLuaChunk * a_pLuaChunk ) override; virtual bool OnCollectItem (cPickup* a_Pickup, cPlayer* a_Player ) override; virtual bool OnCraftingNoRecipe(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) override; - virtual bool OnDisconnect (const AString & a_Reason, cPlayer * a_Player ) override; + virtual bool OnDisconnect (cPlayer * a_Player, const AString & a_Reason) override; virtual bool OnKilled (cPawn* a_Killed, cEntity* a_Killer ) override; virtual bool OnLogin (cClientHandle * a_Client, int a_ProtocolVersion, const AString & a_Username) override; virtual bool OnPlayerJoin (cPlayer* a_Player ) override; diff --git a/source/cPlugin_Squirrel.cpp b/source/cPlugin_Squirrel.cpp index 903f28e0f..f0152f240 100644 --- a/source/cPlugin_Squirrel.cpp +++ b/source/cPlugin_Squirrel.cpp @@ -112,13 +112,13 @@ bool cPlugin_Squirrel::OnCollectItem( cPickup* a_Pickup, cPlayer* a_Player ) -bool cPlugin_Squirrel::OnDisconnect(const AString & a_Reason, cPlayer* a_Player ) +bool cPlugin_Squirrel::OnDisconnect(cPlayer* a_Player, const AString & a_Reason) { cCSLock Lock( m_CriticalSection ); - if(!m_Plugin->HasFunction("OnDisconnect")) return false; + if (!m_Plugin->HasFunction("OnDisconnect")) return false; - return m_Plugin->GetFunction("OnDisconnect").Evaluate(a_Reason, a_Player); + return m_Plugin->GetFunction("OnDisconnect").Evaluate(a_Player, a_Reason); } diff --git a/source/cPlugin_Squirrel.h b/source/cPlugin_Squirrel.h index 15cdc6d59..631304a32 100644 --- a/source/cPlugin_Squirrel.h +++ b/source/cPlugin_Squirrel.h @@ -22,7 +22,7 @@ public: virtual bool OnChunkGenerating (cWorld * a_World, int a_ChunkX, int a_ChunkZ, cLuaChunk * a_pLuaChunk ) override; virtual bool OnCollectItem (cPickup* a_Pickup, cPlayer* a_Player ) override; virtual bool OnCraftingNoRecipe(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) override; - virtual bool OnDisconnect (const AString & a_Reason, cPlayer * a_Player ) override; + virtual bool OnDisconnect (cPlayer * a_Player, const AString & a_Reason) override; virtual bool OnKilled (cPawn* a_Killed, cEntity* a_Killer ) override; virtual bool OnLogin (cClientHandle * a_Client, int a_ProtocolVersion, const AString & a_Username) override; virtual bool OnPlayerJoin (cPlayer* a_Player ) override; diff --git a/source/cSignEntity.cpp b/source/cSignEntity.cpp index 80e10621e..eefcf4ccd 100644 --- a/source/cSignEntity.cpp +++ b/source/cSignEntity.cpp @@ -83,9 +83,9 @@ AString cSignEntity::GetLine( int a_Index ) const cPacket * cSignEntity::GetPacket(void) { cPacket_UpdateSign * Sign = new cPacket_UpdateSign; - Sign->m_PosX = m_PosX; - Sign->m_PosY = (short)m_PosY; - Sign->m_PosZ = m_PosZ; + Sign->m_BlockX = m_PosX; + Sign->m_BlockY = (short)m_PosY; + Sign->m_BlockZ = m_PosZ; Sign->m_Line1 = m_Line[0]; Sign->m_Line2 = m_Line[1]; Sign->m_Line3 = m_Line[2]; diff --git a/source/cWorld.cpp b/source/cWorld.cpp index 6b2bb971d..27db76491 100644 --- a/source/cWorld.cpp +++ b/source/cWorld.cpp @@ -1300,6 +1300,78 @@ void cWorld::BroadcastEntityEquipment(const cEntity & a_Entity, short a_SlotNum, +void cWorld::BroadcastTeleportEntity(const cEntity & a_Entity, const cClientHandle * a_Exclude) +{ + cCSLock Lock(m_CSPlayers); + for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) + { + cClientHandle * ch = (*itr)->GetClientHandle(); + if ((ch == a_Exclude) || (ch == NULL) || !ch->IsLoggedIn() || ch->IsDestroyed()) + { + continue; + } + ch->SendTeleportEntity(a_Entity); + } +} + + + + + +void cWorld::BroadcastRelEntMoveLook(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude) +{ + m_ChunkMap->BroadcastRelEntMoveLook(a_Entity, a_RelX, a_RelY, a_RelZ, a_Exclude); +} + + + + + +void cWorld::BroadcastRelEntMove(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude) +{ + m_ChunkMap->BroadcastRelEntMove(a_Entity, a_RelX, a_RelY, a_RelZ, a_Exclude); +} + + + + + +void cWorld::BroadcastEntLook(const cEntity & a_Entity, const cClientHandle * a_Exclude) +{ + m_ChunkMap->BroadcastEntLook(a_Entity, a_Exclude); +} + + + + + +void cWorld::BroadcastEntHeadLook(const cEntity & a_Entity, const cClientHandle * a_Exclude) +{ + m_ChunkMap->BroadcastEntHeadLook(a_Entity, a_Exclude); +} + + + + + +void cWorld::BroadcastBlockAction(int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, const cClientHandle * a_Exclude) +{ + m_ChunkMap->BroadcastBlockAction(a_BlockX, a_BlockY, a_BlockZ, a_Byte1, a_Byte2, a_Exclude); +} + + + + + +void cWorld::BroadcastDestroyEntity(const cEntity & a_Entity, const cClientHandle * a_Exclude) +{ + m_ChunkMap->BroadcastDestroyEntity(a_Entity, a_Exclude); +} + + + + + void cWorld::MarkChunkDirty (int a_ChunkX, int a_ChunkY, int a_ChunkZ) { m_ChunkMap->MarkChunkDirty (a_ChunkX, a_ChunkY, a_ChunkZ); @@ -1561,13 +1633,12 @@ void cWorld::SendPlayerList(cPlayer * a_DestPlayer) { // Sends the playerlist to a_DestPlayer cCSLock Lock(m_CSPlayers); - for ( cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) + for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr) { cClientHandle * ch = (*itr)->GetClientHandle(); if ((ch != NULL) && !ch->IsDestroyed()) { - cPacket_PlayerListItem PlayerListItem((*itr)->GetColor() + (*itr)->GetName(), true, (*itr)->GetClientHandle()->GetPing()); - a_DestPlayer->GetClientHandle()->Send( PlayerListItem ); + a_DestPlayer->GetClientHandle()->SendPlayerListItem(*(*itr)); } } } diff --git a/source/cWorld.h b/source/cWorld.h index 5bf3a1390..103dd1b65 100644 --- a/source/cWorld.h +++ b/source/cWorld.h @@ -81,6 +81,13 @@ public: void BroadcastChat(const AString & a_Message, const cClientHandle * a_Exclude = NULL); void BroadcastPlayerAnimation(const cPlayer & a_Player, char a_Animation, const cClientHandle * a_Exclude = NULL); void BroadcastEntityEquipment(const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item, const cClientHandle * a_Exclude = NULL); + void BroadcastTeleportEntity (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); + void BroadcastRelEntMoveLook (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude = NULL); + void BroadcastRelEntMove (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude = NULL); + void BroadcastEntLook (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); + void BroadcastEntHeadLook (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); + void BroadcastBlockAction (int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, const cClientHandle * a_Exclude = NULL); + void BroadcastDestroyEntity (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); void MarkChunkDirty (int a_ChunkX, int a_ChunkY, int a_ChunkZ); void MarkChunkSaving(int a_ChunkX, int a_ChunkY, int a_ChunkZ); diff --git a/source/packets/cPacket_BlockAction.cpp b/source/packets/cPacket_BlockAction.cpp index 43a279f37..a4eb01ad8 100644 --- a/source/packets/cPacket_BlockAction.cpp +++ b/source/packets/cPacket_BlockAction.cpp @@ -10,9 +10,9 @@ cPacket_BlockAction::cPacket_BlockAction( const cPacket_BlockAction & a_Copy ) { m_PacketID = E_BLOCK_ACTION; - m_PosX = a_Copy.m_PosX; - m_PosY = a_Copy.m_PosY; - m_PosZ = a_Copy.m_PosZ; + m_BlockX = a_Copy.m_BlockX; + m_BlockY = a_Copy.m_BlockY; + m_BlockZ = a_Copy.m_BlockZ; m_Byte1 = a_Copy.m_Byte1; m_Byte2 = a_Copy.m_Byte2; } @@ -24,9 +24,9 @@ cPacket_BlockAction::cPacket_BlockAction( const cPacket_BlockAction & a_Copy ) void cPacket_BlockAction::Serialize(AString & a_Data) const { AppendByte (a_Data, m_PacketID); - AppendInteger(a_Data, m_PosX); - AppendShort (a_Data, m_PosY); - AppendInteger(a_Data, m_PosZ); + AppendInteger(a_Data, m_BlockX); + AppendShort (a_Data, m_BlockY); + AppendInteger(a_Data, m_BlockZ); AppendByte (a_Data, m_Byte1); AppendByte (a_Data, m_Byte2); } diff --git a/source/packets/cPacket_BlockAction.h b/source/packets/cPacket_BlockAction.h index c74068401..df473801f 100644 --- a/source/packets/cPacket_BlockAction.h +++ b/source/packets/cPacket_BlockAction.h @@ -4,28 +4,33 @@ #include "cPacket.h" -class cPacket_BlockAction : public cPacket + + + +class cPacket_BlockAction : + public cPacket { public: cPacket_BlockAction() - : m_PosX( 0 ) - , m_PosY( 0 ) - , m_PosZ( 0 ) + : m_BlockX( 0 ) + , m_BlockY( 0 ) + , m_BlockZ( 0 ) , m_Byte1( 0 ) , m_Byte2( 0 ) - { m_PacketID = E_BLOCK_ACTION; } + { + m_PacketID = E_BLOCK_ACTION; + } + cPacket_BlockAction( const cPacket_BlockAction & a_Copy ); - virtual cPacket* Clone() const { return new cPacket_BlockAction(*this); } + virtual cPacket * Clone() const { return new cPacket_BlockAction(*this); } virtual void Serialize(AString & a_Data) const override; - int m_PosX; // Block X Coordinate - short m_PosY; // Block Y Coordinate - int m_PosZ; // Block Z Coordinate + int m_BlockX; + short m_BlockY; + int m_BlockZ; char m_Byte1; // Varies char m_Byte2; // Varies - - static const unsigned int c_Size = 1 + 4 + 2 + 4 + 1 + 1; }; diff --git a/source/packets/cPacket_EntityLook.h b/source/packets/cPacket_EntityLook.h index 7f2864d46..463faccda 100644 --- a/source/packets/cPacket_EntityLook.h +++ b/source/packets/cPacket_EntityLook.h @@ -43,14 +43,17 @@ public: cPacket_EntityHeadLook(void) : m_UniqueID( 0 ) , m_HeadYaw( 0 ) - { m_PacketID = E_ENT_LOOK; } + { + m_PacketID = E_ENT_LOOK; + } + cPacket_EntityHeadLook(const cEntity & a_Entity); virtual cPacket * Clone(void) const { return new cPacket_EntityHeadLook(*this); } virtual void Serialize(AString & a_Data) const override; - int m_UniqueID; + int m_UniqueID; char m_HeadYaw; }; diff --git a/source/packets/cPacket_KeepAlive.h b/source/packets/cPacket_KeepAlive.h index 0eeb5e095..c3b9d0587 100644 --- a/source/packets/cPacket_KeepAlive.h +++ b/source/packets/cPacket_KeepAlive.h @@ -12,14 +12,12 @@ class cPacket_KeepAlive : public cPacket public: cPacket_KeepAlive() { m_PacketID = E_KEEP_ALIVE; } cPacket_KeepAlive(int a_PingID) { m_KeepAliveID = a_PingID; } - virtual cPacket* Clone() const { return new cPacket_KeepAlive(*this); } + virtual cPacket * Clone() const { return new cPacket_KeepAlive(*this); } - virtual int Parse(cByteBuffer & a_Buffer) override; + virtual int Parse(cByteBuffer & a_Buffer) override; virtual void Serialize(AString & a_Data) const override; int m_KeepAliveID; - - static const unsigned int c_Size = 1 + 4; }; diff --git a/source/packets/cPacket_Player.cpp b/source/packets/cPacket_Player.cpp index c24905e15..2136d63e6 100644 --- a/source/packets/cPacket_Player.cpp +++ b/source/packets/cPacket_Player.cpp @@ -143,16 +143,16 @@ void cPacket_PlayerLook::Serialize(AString & a_Data) const /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // cPacket_PlayerMoveLook: -cPacket_PlayerMoveLook::cPacket_PlayerMoveLook( cPlayer* a_Player ) +cPacket_PlayerMoveLook::cPacket_PlayerMoveLook(const cPlayer & a_Player) { m_PacketID = E_PLAYERMOVELOOK; - m_PosX = a_Player->GetPosX(); - m_PosY = a_Player->GetPosY() + 1.65; - m_PosZ = a_Player->GetPosZ(); - m_Stance = a_Player->GetStance(); - m_Rotation = a_Player->GetRotation(); - m_Pitch = a_Player->GetPitch(); - m_IsOnGround = a_Player->IsOnGround(); + m_PosX = a_Player.GetPosX(); + m_PosY = a_Player.GetPosY() + 0.03; // Add a small amount so that the player doesn't start inside a block + m_PosZ = a_Player.GetPosZ(); + m_Stance = a_Player.GetStance() + 0.03; // Add a small amount so that the player doesn't start inside a block + m_Rotation = a_Player.GetRotation(); + m_Pitch = a_Player.GetPitch(); + m_IsOnGround = a_Player.IsOnGround(); } @@ -161,6 +161,8 @@ cPacket_PlayerMoveLook::cPacket_PlayerMoveLook( cPlayer* a_Player ) int cPacket_PlayerMoveLook::Parse(cByteBuffer & a_Buffer) { + // NOTE that Stance and Y are swapped when sent C->S vs S->C + // This is the C->S case: int TotalBytes = 0; HANDLE_PACKET_READ(ReadBEDouble, m_PosX, TotalBytes); HANDLE_PACKET_READ(ReadBEDouble, m_PosY, TotalBytes); @@ -169,6 +171,7 @@ int cPacket_PlayerMoveLook::Parse(cByteBuffer & a_Buffer) HANDLE_PACKET_READ(ReadBEFloat, m_Rotation, TotalBytes); HANDLE_PACKET_READ(ReadBEFloat, m_Pitch, TotalBytes); HANDLE_PACKET_READ(ReadBool, m_IsOnGround, TotalBytes); + // LOGD("Recv PML: {%0.2f, %0.2f, %0.2f}, Stance %0.2f, Gnd: %d", m_PosX, m_PosY, m_PosZ, m_Stance, m_IsOnGround ? 1 : 0); return TotalBytes; } @@ -178,10 +181,14 @@ int cPacket_PlayerMoveLook::Parse(cByteBuffer & a_Buffer) void cPacket_PlayerMoveLook::Serialize(AString & a_Data) const { + // NOTE that Stance and Y are swapped when sent C->S vs S->C + // This is the S->C case: + // LOGD("Send PML: {%0.2f, %0.2f, %0.2f}, Stance: %0.2f, Gnd: %d", m_PosX, m_PosY, m_PosZ, m_Stance, m_IsOnGround ? 1 : 0); + AppendByte (a_Data, m_PacketID); AppendDouble(a_Data, m_PosX); - AppendDouble(a_Data, m_PosY); AppendDouble(a_Data, m_Stance); + AppendDouble(a_Data, m_PosY); AppendDouble(a_Data, m_PosZ); AppendFloat (a_Data, m_Rotation); AppendFloat (a_Data, m_Pitch); @@ -200,7 +207,7 @@ cPacket_PlayerPosition::cPacket_PlayerPosition(cPlayer * a_Player) m_PacketID = E_PLAYERPOS; m_PosX = a_Player->GetPosX(); - m_PosY = a_Player->GetPosY() + 1.65; + m_PosY = a_Player->GetPosY(); m_PosZ = a_Player->GetPosZ(); m_Stance = a_Player->GetStance(); m_IsOnGround = a_Player->IsOnGround(); @@ -218,6 +225,7 @@ int cPacket_PlayerPosition::Parse(cByteBuffer & a_Buffer) HANDLE_PACKET_READ(ReadBEDouble, m_Stance, TotalBytes); HANDLE_PACKET_READ(ReadBEDouble, m_PosZ, TotalBytes); HANDLE_PACKET_READ(ReadBool, m_IsOnGround, TotalBytes); + // LOGD("Recv PlayerPos: {%0.2f %0.2f %0.2f}, Stance %0.2f, Gnd: %d", m_PosX, m_PosY, m_PosZ, m_Stance, m_IsOnGround ? 1 : 0); return TotalBytes; } @@ -227,12 +235,17 @@ int cPacket_PlayerPosition::Parse(cByteBuffer & a_Buffer) void cPacket_PlayerPosition::Serialize(AString & a_Data) const { + LOGD("Ignore send PlayerPos"); + /* + LOGD("Send PlayerPos: {%0.2f %0.2f %0.2f}, Stance %0.2f, Gnd: %d", m_PosX, m_PosY, m_PosZ, m_Stance, m_IsOnGround ? 1 : 0); + // _X: This should not get sent to the client at all - http://wiki.vg/wiki/index.php?title=Protocol&oldid=2513#Player_Position_.280x0B.29 AppendByte (a_Data, m_PacketID); AppendDouble (a_Data, m_PosX); AppendDouble (a_Data, m_PosY); AppendDouble (a_Data, m_Stance); AppendDouble (a_Data, m_PosZ); AppendBool (a_Data, m_IsOnGround); + */ } diff --git a/source/packets/cPacket_Player.h b/source/packets/cPacket_Player.h index d9f7c0057..af2dbcc34 100644 --- a/source/packets/cPacket_Player.h +++ b/source/packets/cPacket_Player.h @@ -109,8 +109,8 @@ public: m_PacketID = E_PLAYERMOVELOOK; } - cPacket_PlayerMoveLook( cPlayer* a_Player ); - virtual cPacket* Clone() const { return new cPacket_PlayerMoveLook(*this); } + cPacket_PlayerMoveLook(const cPlayer & a_Player); + virtual cPacket * Clone() const { return new cPacket_PlayerMoveLook(*this); } virtual int Parse(cByteBuffer & a_Buffer) override; virtual void Serialize(AString & a_Data) const override; diff --git a/source/packets/cPacket_Respawn.h b/source/packets/cPacket_Respawn.h index d51869cda..b05f84614 100644 --- a/source/packets/cPacket_Respawn.h +++ b/source/packets/cPacket_Respawn.h @@ -9,26 +9,29 @@ -class cPacket_Respawn : public cPacket +class cPacket_Respawn : + public cPacket { public: cPacket_Respawn() - : m_Dimension( 0 ) - , m_Difficulty( 0 ) - , m_CreativeMode( 0 ) - , m_WorldHeight( 0 ) + : m_Dimension(0) + , m_Difficulty(0) + , m_CreativeMode(0) + , m_WorldHeight(256) , m_LevelType( cPacket_Login::LEVEL_TYPE_DEFAULT ) - { m_PacketID = E_RESPAWN; } + { + m_PacketID = E_RESPAWN; + } - virtual cPacket* Clone() const { return new cPacket_Respawn( *this ); } + virtual cPacket * Clone() const { return new cPacket_Respawn( *this ); } - virtual int Parse(cByteBuffer & a_Buffer) override; + virtual int Parse(cByteBuffer & a_Buffer) override; virtual void Serialize(AString & a_Data) const override; - int m_Dimension; - char m_Difficulty; - char m_CreativeMode; - short m_WorldHeight; + int m_Dimension; + char m_Difficulty; + char m_CreativeMode; + short m_WorldHeight; AString m_LevelType; }; diff --git a/source/packets/cPacket_TeleportEntity.cpp b/source/packets/cPacket_TeleportEntity.cpp index 396095037..14905701a 100644 --- a/source/packets/cPacket_TeleportEntity.cpp +++ b/source/packets/cPacket_TeleportEntity.cpp @@ -9,16 +9,16 @@ -cPacket_TeleportEntity::cPacket_TeleportEntity(cEntity* a_Client) +cPacket_TeleportEntity::cPacket_TeleportEntity(const cEntity & a_Entity) { m_PacketID = E_ENT_TELEPORT; - m_UniqueID = a_Client->GetUniqueID(); - m_PosX = (int)(a_Client->GetPosX() * 32); - m_PosY = (int)(a_Client->GetPosY() * 32); - m_PosZ = (int)(a_Client->GetPosZ() * 32); - m_Rotation = (char)((a_Client->GetRotation() / 360.f) * 256); - m_Pitch = (char)((a_Client->GetPitch() / 360.f) * 256); + m_UniqueID = a_Entity.GetUniqueID(); + m_PosX = (int)(a_Entity.GetPosX() * 32); + m_PosY = (int)(a_Entity.GetPosY() * 32); + m_PosZ = (int)(a_Entity.GetPosZ() * 32); + m_Rotation = (char)((a_Entity.GetRotation() / 360.f) * 256); + m_Pitch = (char)((a_Entity.GetPitch() / 360.f) * 256); } diff --git a/source/packets/cPacket_TeleportEntity.h b/source/packets/cPacket_TeleportEntity.h index d0504f901..5203badb6 100644 --- a/source/packets/cPacket_TeleportEntity.h +++ b/source/packets/cPacket_TeleportEntity.h @@ -18,9 +18,12 @@ public: , m_PosZ( 0 ) , m_Rotation( 0 ) , m_Pitch( 0 ) - { m_PacketID = E_ENT_TELEPORT; } - virtual cPacket* Clone() const { return new cPacket_TeleportEntity(*this); } - cPacket_TeleportEntity(cEntity* a_Client); + { + m_PacketID = E_ENT_TELEPORT; + } + + virtual cPacket * Clone() const { return new cPacket_TeleportEntity(*this); } + cPacket_TeleportEntity(const cEntity & a_Entity); virtual void Serialize(AString & a_Data) const override; diff --git a/source/packets/cPacket_UpdateSign.cpp b/source/packets/cPacket_UpdateSign.cpp index 3ef587f13..564debf01 100644 --- a/source/packets/cPacket_UpdateSign.cpp +++ b/source/packets/cPacket_UpdateSign.cpp @@ -10,9 +10,9 @@ int cPacket_UpdateSign::Parse(cByteBuffer & a_Buffer) { int TotalBytes = 0; - HANDLE_PACKET_READ(ReadBEInt, m_PosX, TotalBytes); - HANDLE_PACKET_READ(ReadBEShort, m_PosY, TotalBytes); - HANDLE_PACKET_READ(ReadBEInt, m_PosZ, TotalBytes); + HANDLE_PACKET_READ(ReadBEInt, m_BlockX, TotalBytes); + HANDLE_PACKET_READ(ReadBEShort, m_BlockY, TotalBytes); + HANDLE_PACKET_READ(ReadBEInt, m_BlockZ, TotalBytes); HANDLE_PACKET_READ(ReadBEUTF16String16, m_Line1, TotalBytes); HANDLE_PACKET_READ(ReadBEUTF16String16, m_Line2, TotalBytes); HANDLE_PACKET_READ(ReadBEUTF16String16, m_Line3, TotalBytes); @@ -27,9 +27,9 @@ int cPacket_UpdateSign::Parse(cByteBuffer & a_Buffer) void cPacket_UpdateSign::Serialize(AString & a_Data) const { AppendByte (a_Data, m_PacketID); - AppendInteger (a_Data, m_PosX); - AppendShort (a_Data, m_PosY); - AppendInteger (a_Data, m_PosZ); + AppendInteger (a_Data, m_BlockX); + AppendShort (a_Data, m_BlockY); + AppendInteger (a_Data, m_BlockZ); AppendString16(a_Data, m_Line1); AppendString16(a_Data, m_Line2); AppendString16(a_Data, m_Line3); diff --git a/source/packets/cPacket_UpdateSign.h b/source/packets/cPacket_UpdateSign.h index 9c3790c77..110ae8253 100644 --- a/source/packets/cPacket_UpdateSign.h +++ b/source/packets/cPacket_UpdateSign.h @@ -11,24 +11,25 @@ class cPacket_UpdateSign : public cPacket { public: cPacket_UpdateSign() - : m_PosX( 0 ) - , m_PosY( 0 ) - , m_PosZ( 0 ) - { m_PacketID = E_UPDATE_SIGN; } - virtual cPacket* Clone() const { return new cPacket_UpdateSign( *this ); } - - virtual int Parse(cByteBuffer & a_Buffer) override; + : m_BlockX( 0 ) + , m_BlockY( 0 ) + , m_BlockZ( 0 ) + { + m_PacketID = E_UPDATE_SIGN; + } + + virtual cPacket * Clone() const { return new cPacket_UpdateSign( *this ); } + + virtual int Parse(cByteBuffer & a_Buffer) override; virtual void Serialize(AString & a_Data) const override; - int m_PosX; - short m_PosY; - int m_PosZ; + int m_BlockX; + short m_BlockY; + int m_BlockZ; AString m_Line1; AString m_Line2; AString m_Line3; AString m_Line4; - - static const unsigned int c_Size = 1 + 4 + 2 + 4 + 2 + 2 + 2 + 2; // minimum size }; diff --git a/source/packets/cPacket_UseEntity.cpp b/source/packets/cPacket_UseEntity.cpp index 73b4f7f82..9ecb3bffc 100644 --- a/source/packets/cPacket_UseEntity.cpp +++ b/source/packets/cPacket_UseEntity.cpp @@ -10,9 +10,9 @@ int cPacket_UseEntity::Parse(cByteBuffer & a_Buffer) { int TotalBytes = 0; - HANDLE_PACKET_READ(ReadBEInt, m_UniqueID, TotalBytes); - HANDLE_PACKET_READ(ReadBEInt, m_TargetID, TotalBytes); - HANDLE_PACKET_READ(ReadBool, m_bLeftClick, TotalBytes); + HANDLE_PACKET_READ(ReadBEInt, m_SourceEntityID, TotalBytes); + HANDLE_PACKET_READ(ReadBEInt, m_TargetEntityID, TotalBytes); + HANDLE_PACKET_READ(ReadBool, m_IsLeftClick, TotalBytes); return TotalBytes; } diff --git a/source/packets/cPacket_UseEntity.h b/source/packets/cPacket_UseEntity.h index 799122bf9..ff33ccd93 100644 --- a/source/packets/cPacket_UseEntity.h +++ b/source/packets/cPacket_UseEntity.h @@ -7,23 +7,25 @@ -class cPacket_UseEntity : public cPacket +class cPacket_UseEntity : + public cPacket { public: cPacket_UseEntity() - : m_UniqueID( 0 ) - , m_TargetID( 0 ) - , m_bLeftClick( false ) - { m_PacketID = E_USE_ENTITY; } - virtual cPacket* Clone() const { return new cPacket_UseEntity(*this); } + : m_SourceEntityID(0) + , m_TargetEntityID(0) + , m_IsLeftClick(false) + { + m_PacketID = E_USE_ENTITY; + } + + virtual cPacket * Clone() const { return new cPacket_UseEntity(*this); } virtual int Parse(cByteBuffer & a_Buffer) override; - int m_UniqueID; - int m_TargetID; - bool m_bLeftClick; - - static const unsigned int c_Size = 1 + 4 + 4 + 1; + int m_SourceEntityID; + int m_TargetEntityID; + bool m_IsLeftClick; }; -- cgit v1.2.3