1
0
Fork 0

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
This commit is contained in:
madmaxoft@gmail.com 2012-08-19 19:42:32 +00:00
parent 5b36aa1567
commit 427e582d5f
40 changed files with 1089 additions and 507 deletions

View File

@ -1,6 +1,6 @@
/* /*
** Lua binding: AllToLua ** 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 #ifndef __cplusplus
@ -5931,14 +5931,14 @@ static int tolua_AllToLua_cPlayer_GetStance00(lua_State* tolua_S)
#ifndef TOLUA_RELEASE #ifndef TOLUA_RELEASE
tolua_Error tolua_err; tolua_Error tolua_err;
if ( 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) !tolua_isnoobj(tolua_S,2,&tolua_err)
) )
goto tolua_lerror; goto tolua_lerror;
else else
#endif #endif
{ {
cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); const cPlayer* self = (const cPlayer*) tolua_tousertype(tolua_S,1,0);
#ifndef TOLUA_RELEASE #ifndef TOLUA_RELEASE
if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetStance'", NULL); if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetStance'", NULL);
#endif #endif
@ -6293,14 +6293,14 @@ static int tolua_AllToLua_cPlayer_GetClientHandle00(lua_State* tolua_S)
#ifndef TOLUA_RELEASE #ifndef TOLUA_RELEASE
tolua_Error tolua_err; tolua_Error tolua_err;
if ( 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) !tolua_isnoobj(tolua_S,2,&tolua_err)
) )
goto tolua_lerror; goto tolua_lerror;
else else
#endif #endif
{ {
cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); const cPlayer* self = (const cPlayer*) tolua_tousertype(tolua_S,1,0);
#ifndef TOLUA_RELEASE #ifndef TOLUA_RELEASE
if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetClientHandle'", NULL); if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetClientHandle'", NULL);
#endif #endif
@ -6326,7 +6326,7 @@ static int tolua_AllToLua_cPlayer_SendMessage00(lua_State* tolua_S)
tolua_Error tolua_err; tolua_Error tolua_err;
if ( if (
!tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) || !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) !tolua_isnoobj(tolua_S,3,&tolua_err)
) )
goto tolua_lerror; goto tolua_lerror;
@ -6334,15 +6334,16 @@ static int tolua_AllToLua_cPlayer_SendMessage00(lua_State* tolua_S)
#endif #endif
{ {
cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0); 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 #ifndef TOLUA_RELEASE
if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SendMessage'", NULL); if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SendMessage'", NULL);
#endif #endif
{ {
self->SendMessage(a_Message); self->SendMessage(a_Message);
tolua_pushcppstring(tolua_S,(const char*)a_Message);
} }
} }
return 0; return 1;
#ifndef TOLUA_RELEASE #ifndef TOLUA_RELEASE
tolua_lerror: tolua_lerror:
tolua_error(tolua_S,"#ferror in function 'SendMessage'.",&tolua_err); 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; tolua_Error tolua_err;
if ( if (
!tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) || !tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) ||
!tolua_iscppstring(tolua_S,2,0,&tolua_err) || !tolua_isusertype(tolua_S,2,"cPlayer",0,&tolua_err) ||
!tolua_isusertype(tolua_S,3,"cPlayer",0,&tolua_err) || !tolua_iscppstring(tolua_S,3,0,&tolua_err) ||
!tolua_isnoobj(tolua_S,4,&tolua_err) !tolua_isnoobj(tolua_S,4,&tolua_err)
) )
goto tolua_lerror; goto tolua_lerror;
@ -7912,13 +7913,13 @@ static int tolua_AllToLua_cPlugin_OnDisconnect00(lua_State* tolua_S)
#endif #endif
{ {
cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0); 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,2,0));
cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,3,0)); const AString a_Reason = ((const AString) tolua_tocppstring(tolua_S,3,0));
#ifndef TOLUA_RELEASE #ifndef TOLUA_RELEASE
if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnDisconnect'", NULL); if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnDisconnect'", NULL);
#endif #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_pushboolean(tolua_S,(bool)tolua_ret);
tolua_pushcppstring(tolua_S,(const char*)a_Reason); tolua_pushcppstring(tolua_S,(const char*)a_Reason);
} }
@ -8759,16 +8760,16 @@ public:
return ( bool ) cPlugin:: OnCraftingNoRecipe(a_Player,a_Grid,a_Recipe); 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)) { 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_pushusertype(lua_state, (void*)a_Player, "cPlayer");
tolua_pushcppstring(lua_state, (const char*)a_Reason);
ToluaBase::dbcall(lua_state, 3, 1); ToluaBase::dbcall(lua_state, 3, 1);
bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0);
lua_pop(lua_state, 1); lua_pop(lua_state, 1);
return tolua_ret; return tolua_ret;
} else { } 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) { 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) { bool cPlugin__OnCraftingNoRecipe( const cPlayer* a_Player, const cCraftingGrid* a_Grid, cCraftingRecipe* a_Recipe) {
return ( bool )cPlugin::OnCraftingNoRecipe(a_Player,a_Grid,a_Recipe); return ( bool )cPlugin::OnCraftingNoRecipe(a_Player,a_Grid,a_Recipe);
}; };
bool cPlugin__OnDisconnect( const AString& a_Reason, cPlayer* a_Player) { bool cPlugin__OnDisconnect( cPlayer* a_Player, const AString& a_Reason) {
return ( bool )cPlugin::OnDisconnect(a_Reason,a_Player); return ( bool )cPlugin::OnDisconnect(a_Player,a_Reason);
}; };
bool cPlugin__OnKilled( cPawn* a_Killed, cEntity* a_Killer) { bool cPlugin__OnKilled( cPawn* a_Killed, cEntity* a_Killer) {
return ( bool )cPlugin::OnKilled(a_Killed,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; tolua_Error tolua_err;
if ( if (
!tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) || !tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) ||
!tolua_iscppstring(tolua_S,2,0,&tolua_err) || !tolua_isusertype(tolua_S,2,"cPlayer",0,&tolua_err) ||
!tolua_isusertype(tolua_S,3,"cPlayer",0,&tolua_err) || !tolua_iscppstring(tolua_S,3,0,&tolua_err) ||
!tolua_isnoobj(tolua_S,4,&tolua_err) !tolua_isnoobj(tolua_S,4,&tolua_err)
) )
goto tolua_lerror; goto tolua_lerror;
@ -9411,13 +9412,13 @@ static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnDisconnect00(lua_State* tolua_
#endif #endif
{ {
Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0); 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,2,0));
cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,3,0)); const AString a_Reason = ((const AString) tolua_tocppstring(tolua_S,3,0));
#ifndef TOLUA_RELEASE #ifndef TOLUA_RELEASE
if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnDisconnect'", NULL); if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnDisconnect'", NULL);
#endif #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_pushboolean(tolua_S,(bool)tolua_ret);
tolua_pushcppstring(tolua_S,(const char*)a_Reason); tolua_pushcppstring(tolua_S,(const char*)a_Reason);
} }
@ -10219,16 +10220,16 @@ public:
return ( bool ) cPlugin_NewLua:: OnCraftingNoRecipe(a_Player,a_Grid,a_Recipe); 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)) { 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_pushusertype(lua_state, (void*)a_Player, "cPlayer");
tolua_pushcppstring(lua_state, (const char*)a_Reason);
ToluaBase::dbcall(lua_state, 3, 1); ToluaBase::dbcall(lua_state, 3, 1);
bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0); bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0);
lua_pop(lua_state, 1); lua_pop(lua_state, 1);
return tolua_ret; return tolua_ret;
} else { } 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) { 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) { 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); return ( bool )cPlugin_NewLua::OnCraftingNoRecipe(a_Player,a_Grid,a_Recipe);
}; };
bool cPlugin_NewLua__OnDisconnect( const AString& a_Reason, cPlayer* a_Player) { bool cPlugin_NewLua__OnDisconnect( cPlayer* a_Player, const AString& a_Reason) {
return ( bool )cPlugin_NewLua::OnDisconnect(a_Reason,a_Player); return ( bool )cPlugin_NewLua::OnDisconnect(a_Player,a_Reason);
}; };
bool cPlugin_NewLua__OnKilled( cPawn* a_Killed, cEntity* a_Killer) { bool cPlugin_NewLua__OnKilled( cPawn* a_Killed, cEntity* a_Killer) {
return ( bool )cPlugin_NewLua::OnKilled(a_Killed,a_Killer); return ( bool )cPlugin_NewLua::OnKilled(a_Killed,a_Killer);

View File

@ -1,6 +1,6 @@
/* /*
** Lua binding: AllToLua ** 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 */ /* Exported function */

View File

@ -184,13 +184,7 @@ void cChestEntity::UsedBy(cPlayer * a_Player)
GetWindow()->SendWholeWindow( a_Player->GetClientHandle() ); GetWindow()->SendWholeWindow( a_Player->GetClientHandle() );
} }
} }
cPacket_BlockAction ChestOpen; m_World->BroadcastBlockAction(m_PosX, m_PosY, m_PosZ, 1, 1);
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);
// This is rather a hack // This is rather a hack
// Instead of marking the chunk as dirty upon chest contents change, we mark it dirty now // 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) if (m_JoinedChest && !a_OnlyThis)
{ {
cItem *Combined = new cItem[GetChestHeight()*c_ChestWidth]; // TODO: "Combined" memory leaks here
int i; cItem * Combined = new cItem[GetChestHeight() * c_ChestWidth];
cItem *first = (m_TopChest) ? GetContents(true) : m_JoinedChest->GetContents(true); cItem * first = (m_TopChest) ? GetContents(true) : m_JoinedChest->GetContents(true);
cItem *second = (!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++) for (int i = 0; i < GetChestHeight() * c_ChestWidth; i++)
{ {
int index = i % c_ChestHeight*c_ChestWidth; int index = i % (c_ChestHeight * c_ChestWidth);
if (i < c_ChestHeight*c_ChestWidth) if (i < c_ChestHeight * c_ChestWidth)
Combined[index] = first[index]; Combined[index] = first[index];
else else
Combined[index] = second[index]; Combined[index] = second[index];
@ -224,7 +218,9 @@ cItem *cChestEntity::GetContents(bool a_OnlyThis)
return Combined; return Combined;
} }
else else
{
return m_Content; return m_Content;
}
} }

View File

@ -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) 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; a_Y = a_ChunkY;

View File

@ -177,6 +177,12 @@ public:
void BroadcastPlayerAnimation(const cPlayer & a_Player, char a_Animation, 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 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); 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 ); } Vector3i PositionToWorldPosition( const Vector3i & a_InChunkPos ) { return PositionToWorldPosition( a_InChunkPos.x, a_InChunkPos.y, a_InChunkPos.z ); }

View File

@ -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) 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 // a_Player rclked block entity at the coords specified, handle it

View File

@ -53,6 +53,23 @@ public:
/// Broadcasts an entity equipment change to all clients in the chunk where a_Entity is /// 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); 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 /// 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); void UseBlockEntity(cPlayer * a_Player, int a_X, int a_Y, int a_Z);

View File

@ -39,40 +39,45 @@
#include "cAuthenticator.h" #include "cAuthenticator.h"
#include "MersenneTwister.h" #include "MersenneTwister.h"
#include "packets/cPacket_KeepAlive.h" #include "packets/cPacket_13.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_ArmAnim.h" #include "packets/cPacket_ArmAnim.h"
#include "packets/cPacket_BlockChange.h"
#include "packets/cPacket_BlockDig.h"
#include "packets/cPacket_BlockPlace.h" #include "packets/cPacket_BlockPlace.h"
#include "packets/cPacket_Flying.h" #include "packets/cPacket_Chat.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_CreativeInventoryAction.h"
#include "packets/cPacket_DestroyEntity.h"
#include "packets/cPacket_Disconnect.h"
#include "packets/cPacket_EntityEquipment.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_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_UseEntity.h"
#include "packets/cPacket_WholeInventory.h"
#include "packets/cPacket_WindowClick.h" #include "packets/cPacket_WindowClick.h"
#include "packets/cPacket_WindowClose.h" #include "packets/cPacket_WindowClose.h"
#include "packets/cPacket_WindowOpen.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 // Therefore I keep this function huge and untidy for the time being
// ( http://forum.mc-server.org/showthread.php?tid=524 ) // ( http://forum.mc-server.org/showthread.php?tid=524 )
// LOGD("Recv packet %02x", a_Packet->m_PacketID);
m_TimeLastPacket = cWorld::GetTime(); 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()); // 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); HandleWindowClick(wc->m_WindowID, wc->m_SlotNum, wc->m_IsRightClick, wc->m_IsShiftPressed, wc->m_HeldItem);
break; break;
} }
case E_UPDATE_SIGN: HandleUpdateSign (reinterpret_cast<cPacket_UpdateSign *> (a_Packet)); break; case E_UPDATE_SIGN:
case E_USE_ENTITY: HandleUseEntity (reinterpret_cast<cPacket_UseEntity *> (a_Packet)); break; {
case E_RESPAWN: HandleRespawn(); break; cPacket_UpdateSign * us = reinterpret_cast<cPacket_UpdateSign *>(a_Packet);
case E_DISCONNECT: HandleDisconnect (reinterpret_cast<cPacket_Disconnect *> (a_Packet)); break; HandleUpdateSign(us->m_BlockX, us->m_BlockY, us->m_BlockZ, us->m_Line1, us->m_Line2, us->m_Line3, us->m_Line4);
case E_KEEP_ALIVE: HandleKeepAlive (reinterpret_cast<cPacket_KeepAlive *> (a_Packet)); break; break;
}
case E_USE_ENTITY:
{
cPacket_UseEntity * ue = reinterpret_cast<cPacket_UseEntity *>(a_Packet);
HandleUseEntity(ue->m_TargetEntityID, ue->m_IsLeftClick);
break;
}
case E_RESPAWN:
{
HandleRespawn();
break;
}
case E_DISCONNECT:
{
cPacket_Disconnect * dc = reinterpret_cast<cPacket_Disconnect *>(a_Packet);
HandleDisconnect(dc->m_Reason);
break;
}
case E_KEEP_ALIVE:
{
cPacket_KeepAlive * ka = reinterpret_cast<cPacket_KeepAlive *>(a_Packet);
HandleKeepAlive(ka->m_KeepAliveID);
break;
}
} // switch (Packet type) } // switch (Packet type)
break; break;
} // case csPlaying } // case csPlaying
@ -797,7 +828,8 @@ void cClientHandle::HandleUnexpectedPacket(int a_PacketType)
void cClientHandle::HandleMoveLookConfirm(double a_PosX, double a_PosY, double a_PosZ) void cClientHandle::HandleMoveLookConfirm(double a_PosX, double a_PosY, double a_PosZ)
{ {
Vector3d ReceivedPosition = Vector3d(a_PosX, a_PosY, 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 // 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(); double Dist = (ReceivedPosition - m_ConfirmPosition).SqrLength();
if (Dist < 1.0) 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); LOGWARNING("Player \"%s\" sent a weird position confirmation %.2f blocks away, retrying", m_Username.c_str(), Dist);
m_ConfirmPosition = m_Player->GetPosition(); 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) 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->SetStance(a_Stance);
m_Player->SetTouchGround(a_IsOnGround); 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) 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->MoveTo(Vector3d(a_PosX, a_PosY, a_PosZ));
m_Player->SetStance (a_Stance); m_Player->SetStance (a_Stance);
m_Player->SetTouchGround(a_IsOnGround); 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(); 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; return;
} }
@ -1169,9 +1233,9 @@ void cClientHandle::HandleUseEntity(cPacket_UseEntity * a_Packet)
{ {
virtual bool Item(cEntity * a_Entity) override 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<cPawn *>(a_Entity)->TakeDamage(Damage, Instigator);
} }
return true; return true;
} }
@ -1184,7 +1248,7 @@ void cClientHandle::HandleUseEntity(cPacket_UseEntity * a_Packet)
Callback.Instigator = m_Player; Callback.Instigator = m_Player;
cWorld * World = m_Player->GetWorld(); 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()); LOGD("Received d/c packet from \"%s\" with reason \"%s\"", m_Username.c_str(), a_Reason.c_str());
if (!cRoot::Get()->GetPluginManager()->CallHook(cPluginManager::HOOK_DISCONNECT, 2, a_Packet->m_Reason.c_str(), m_Player)) if (!cRoot::Get()->GetPluginManager()->CallHookDisconnect(m_Player, a_Reason))
{ {
cPacket_Chat DisconnectMessage(m_Username + " disconnected: " + a_Packet->m_Reason); AString DisconnectMessage;
cRoot::Get()->GetServer()->Broadcast(DisconnectMessage); Printf(DisconnectMessage, "%s disconnected: %s", m_Username.c_str(), a_Reason.c_str());
m_Player->GetWorld()->BroadcastChat(DisconnectMessage, this);
} }
Destroy(); 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; cTimer t1;
m_Ping = (short)((t1.GetNowTime() - m_PingStartTime) / 2); m_Ping = (short)((t1.GetNowTime() - m_PingStartTime) / 2);
@ -1225,6 +1290,9 @@ void cClientHandle::HandleKeepAlive(cPacket_KeepAlive * a_Packet)
} }
bool cClientHandle::CheckBlockInteractionsRate(void) bool cClientHandle::CheckBlockInteractionsRate(void)
{ {
ASSERT(m_Player != NULL); 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) void cClientHandle::CheckIfWorldDownloaded(void)
{ {
if (m_State != csDownloadingWorld) if (m_State != csDownloadingWorld)
@ -1576,7 +1812,7 @@ void cClientHandle::SendConfirmPosition(void)
} }
m_ConfirmPosition = m_Player->GetPosition(); 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)) while (!m_PendingNrmSendPackets.empty() && (Data.size() < 1000))
{ {
m_PendingNrmSendPackets.front()->Serialize(Data); m_PendingNrmSendPackets.front()->Serialize(Data);
// LOGD("Sending packet 0x%02x", m_PendingNrmSendPackets.front()->m_PacketID);
delete m_PendingNrmSendPackets.front(); delete m_PendingNrmSendPackets.front();
m_PendingNrmSendPackets.erase(m_PendingNrmSendPackets.begin()); m_PendingNrmSendPackets.erase(m_PendingNrmSendPackets.begin());
} }

View File

@ -15,30 +15,6 @@
#include "Vector3d.h" #include "Vector3d.h"
#include "cSocketThreads.h" #include "cSocketThreads.h"
#include "ChunkDef.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" #include "ByteBuffer.h"
@ -114,6 +90,19 @@ public:
void SendWindowClose(char a_WindowID); void SendWindowClose(char a_WindowID);
void SendWholeInventory(const cInventory & a_Inventory); void SendWholeInventory(const cInventory & a_Inventory);
void SendWholeInventory(const cWindow & a_Window); 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 const AString & GetUsername(void) const; //tolua_export
@ -212,14 +201,20 @@ private:
void HandleSlotSelected (short a_SlotNum); void HandleSlotSelected (short a_SlotNum);
void HandleWindowClose (char a_WindowID); void HandleWindowClose (char a_WindowID);
void HandleWindowClick (char a_WindowID, short a_SlotNum, bool a_IsRightClick, bool a_IsShiftPressed, const cItem & a_HeldItem); 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 HandleUpdateSign (
void HandleUseEntity (cPacket_UseEntity * a_Packet); 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 HandleRespawn (void);
void HandleDisconnect (cPacket_Disconnect * a_Packet); void HandleDisconnect (const AString & a_Reason);
void HandleKeepAlive (cPacket_KeepAlive * a_Packet); void HandleKeepAlive (int a_KeepAliveID);
/*
/// Handles rclk with a dye; returns true if the dye is to be be consumed /// Handles rclk with a dye; returns true if the dye is to be be consumed
bool HandleDyes(cPacket_BlockPlace * a_Packet); bool HandleDyes(cPacket_BlockPlace * a_Packet);
*/
/// Returns true if the rate block interactions is within a reasonable limit (bot protection) /// Returns true if the rate block interactions is within a reasonable limit (bot protection)
bool CheckBlockInteractionsRate(void); bool CheckBlockInteractionsRate(void);

View File

@ -12,11 +12,6 @@
#include "MersenneTwister.h" #include "MersenneTwister.h"
#include "packets/cPacket_SpawnMob.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 "Vector3f.h"
#include "Vector3i.h" #include "Vector3i.h"
@ -60,11 +55,19 @@ cMonster::cMonster()
m_MetaData = NORMAL; m_MetaData = NORMAL;
} }
cMonster::~cMonster() cMonster::~cMonster()
{ {
LOG("cMonster::~cMonster()"); LOG("cMonster::~cMonster()");
} }
bool cMonster::IsA( const char* a_EntityType ) bool cMonster::IsA( const char* a_EntityType )
{ {
if( strcmp( a_EntityType, "cMonster" ) == 0 ) return true; if( strcmp( a_EntityType, "cMonster" ) == 0 ) return true;
@ -100,6 +103,10 @@ void cMonster::MoveToPosition( const Vector3f & a_Position )
m_Destination = a_Position; m_Destination = a_Position;
} }
bool cMonster::ReachedDestination() bool cMonster::ReachedDestination()
{ {
Vector3f Distance = (m_Destination) - Vector3f( m_Pos ); Vector3f Distance = (m_Destination) - Vector3f( m_Pos );
@ -173,7 +180,7 @@ void cMonster::Tick(float a_Dt)
ReplicateMovement(); ReplicateMovement();
Vector3f Distance = m_Destination - Vector3f( m_Pos ); Vector3f Distance = m_Destination - Vector3f( m_Pos );
if( Distance.SqrLength() > 0.1f ) if (Distance.SqrLength() > 0.1f)
{ {
float Rotation, Pitch; float Rotation, Pitch;
Distance.Normalize(); Distance.Normalize();
@ -182,18 +189,22 @@ void cMonster::Tick(float a_Dt)
SetPitch( Pitch ); 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); 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); InStateChasing(a_Dt);
} }
if(m_EMState == ESCAPING) { if (m_EMState == ESCAPING)
{
InStateEscaping(a_Dt); InStateEscaping(a_Dt);
} }
} }
@ -202,50 +213,38 @@ void cMonster::Tick(float a_Dt)
void cMonster::ReplicateMovement() void cMonster::ReplicateMovement()
{ {
if(m_bDirtyOrientation && !m_bDirtyPosition) if (m_bDirtyOrientation && !m_bDirtyPosition)
{ {
cPacket_EntityLook EntityLook(*this); m_World->BroadcastEntLook(*this);
m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, EntityLook );
m_bDirtyOrientation = false; m_bDirtyOrientation = false;
} }
if( m_bDirtyPosition ) if (m_bDirtyPosition)
{ {
float DiffX = (float)(GetPosX() - m_LastPosX ); float DiffX = (float)(GetPosX() - m_LastPosX);
float DiffY = (float)(GetPosY() - m_LastPosY ); float DiffY = (float)(GetPosY() - m_LastPosY);
float DiffZ = (float)(GetPosZ() - m_LastPosZ ); float DiffZ = (float)(GetPosZ() - m_LastPosZ);
float SqrDist = DiffX*DiffX + DiffY*DiffY + DiffZ*DiffZ; float SqrDist = DiffX * DiffX + DiffY * DiffY + DiffZ * DiffZ;
if ( if (
(SqrDist > 4 * 4) // 4 blocks is max Relative Move (SqrDist > 4 * 4) // 4 blocks is max Relative Move
|| (cWorld::GetTime() - m_TimeLastTeleportPacket > 2 ) // Send an absolute position every 2 seconds || (cWorld::GetTime() - m_TimeLastTeleportPacket > 2) // Send an absolute position every 2 seconds
) )
{ {
//LOG("Teleported %f", sqrtf(SqrDist) ); // LOGD("Teleported %f", sqrtf(SqrDist) );
cPacket_TeleportEntity TeleportEntity( this ); m_World->BroadcastTeleportEntity(*this);
m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, TeleportEntity);
m_TimeLastTeleportPacket = cWorld::GetTime(); m_TimeLastTeleportPacket = cWorld::GetTime();
} }
else 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; m_World->BroadcastRelEntMoveLook(*this, (char)(DiffX * 32), (char)(DiffY * 32), (char)(DiffZ * 32));
RelativeEntityMoveLook.m_UniqueID = GetUniqueID(); m_bDirtyOrientation = false;
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 );
} }
else else
{ {
cPacket_RelativeEntityMove RelativeEntityMove; m_World->BroadcastRelEntMove(*this, (char)(DiffX * 32), (char)(DiffY * 32), (char)(DiffZ * 32));
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_LastPosX = GetPosX(); m_LastPosX = GetPosX();
@ -325,6 +324,10 @@ void cMonster::HandlePhysics(float a_Dt)
} }
} }
void cMonster::TakeDamage(int a_Damage, cEntity* a_Instigator) void cMonster::TakeDamage(int a_Damage, cEntity* a_Instigator)
{ {
cPawn::TakeDamage( a_Damage, a_Instigator ); cPawn::TakeDamage( a_Damage, a_Instigator );
@ -332,96 +335,135 @@ void cMonster::TakeDamage(int a_Damage, cEntity* a_Instigator)
AddReference( m_Target ); AddReference( m_Target );
} }
void cMonster::KilledBy( cEntity* a_Killer ) void cMonster::KilledBy( cEntity* a_Killer )
{ {
cPawn::KilledBy( a_Killer ); cPawn::KilledBy( a_Killer );
m_DestroyTimer = 0; m_DestroyTimer = 0;
} }
//----State Logic //----State Logic
const char *cMonster::GetState() { const char *cMonster::GetState()
switch(m_EMState) { {
case IDLE: switch(m_EMState)
return "Idle"; {
break; case IDLE: return "Idle";
case ATTACKING: case ATTACKING: return "Attacking";
return "Attacking"; case CHASING: return "Chasing";
break; default: return "Unknown";
case CHASING:
return "Chasing";
break;
default:
return "Unknown";
break;
} }
} }
//for debugging
void cMonster::SetState(const char* a_str)
// for debugging
void cMonster::SetState(const AString & a_State)
{ {
std::string str = a_str; if (a_State.compare("Idle") == 0)
if(str.compare("Idle") == 0 ) { {
m_EMState = IDLE; m_EMState = IDLE;
} else if(str.compare("Attacking") == 0 ) { }
else if (a_State.compare("Attacking") == 0)
{
m_EMState = ATTACKING; m_EMState = ATTACKING;
} else if(str.compare("Chasing") == 0 ) { }
else if (a_State.compare("Chasing") == 0)
{
m_EMState = CHASING; m_EMState = CHASING;
} else { }
else
{
printf("Invalid State"); printf("Invalid State");
} }
} }
//Checks to see if EventSeePlayer should be fired //Checks to see if EventSeePlayer should be fired
//monster sez: Do I see the player //monster sez: Do I see the player
void cMonster::CheckEventSeePlayer() void cMonster::CheckEventSeePlayer()
{ {
cPlayer *Closest = FindClosestPlayer(); cPlayer *Closest = FindClosestPlayer();
if(Closest) if (Closest)
{ {
EventSeePlayer(Closest); EventSeePlayer(Closest);
} }
} }
void cMonster::CheckEventLostPlayer() void cMonster::CheckEventLostPlayer()
{ {
Vector3f pos; Vector3f pos;
cTracer LineOfSight(GetWorld() ); cTracer LineOfSight(GetWorld());
if(m_Target != 0) { if (m_Target != NULL)
{
pos = m_Target->GetPosition(); 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(); EventLosePlayer();
} }
} else { }
else
{
EventLosePlayer(); 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) void cMonster::EventSeePlayer(cEntity *a_SeenPlayer)
{ {
m_Target = a_SeenPlayer; m_Target = a_SeenPlayer;
AddReference( m_Target ); AddReference( m_Target );
} }
void cMonster::EventLosePlayer(){
void cMonster::EventLosePlayer()
{
Dereference(m_Target); Dereference(m_Target);
m_Target = 0; m_Target = 0;
m_EMState = IDLE; m_EMState = IDLE;
} }
//What to do if in Idle State //What to do if in Idle State
void cMonster::InStateIdle(float a_Dt) { void cMonster::InStateIdle(float a_Dt)
{
idle_interval += 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; MTRand r1;
int rem = r1.randInt()%6 + 1; int rem = r1.randInt()%6 + 1;
//LOG("Moving: int: %3.3f rem: %i",idle_interval,rem); // 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 idle_interval -= 1; // So nothing gets dropped when the server hangs for a few seconds
Vector3f Dist; Vector3f Dist;
Dist.x = (float)((r1.randInt()%11)-5); Dist.x = (float)((r1.randInt()%11)-5);
Dist.z = (float)((r1.randInt()%11)-5); Dist.z = (float)((r1.randInt()%11)-5);
@ -435,62 +477,60 @@ 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; (void)a_Dt;
if(m_Target) { if(m_Target)
{
Vector3d newloc = m_Pos; Vector3d newloc = m_Pos;
newloc.x = (m_Target->GetPosition().x < newloc.x)? (newloc.x + m_SightDistance): (newloc.x - m_SightDistance); 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); newloc.z = (m_Target->GetPosition().z < newloc.z)? (newloc.z + m_SightDistance): (newloc.z - m_SightDistance);
MoveToPosition(newloc); MoveToPosition(newloc);
} else { }
else
{
m_EMState = IDLE; //this shouldnt be required but just to be safe 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);
}
}
// Do attack here
// a_Dt is passed so we can set attack rate
#if 0 void cMonster::Attack(float a_Dt)
// TODO: Implement this debug function inside cWorld instead - the world owns the entities
void cMonster::ListMonsters()
{ {
m_AttackInterval += a_Dt * m_AttackRate;
cWorld::EntityList Entities = cRoot::Get()->GetWorld()->GetEntities(); if ((m_Target != NULL) && (m_AttackInterval > 3.0))
cRoot::Get()->GetWorld()->LockEntities(); {
for( cWorld::EntityList::iterator itr = Entities.begin(); itr != Entities.end(); ++itr) { // Setting this higher gives us more wiggle room for attackrate
if((*itr)->GetEntityType() == cEntity::E_ENTITY){ m_AttackInterval = 0.0;
LOG("In state: %s type: %i attack rate: %i",((cMonster *)(*itr))->GetState(), ((cMonster *)(*itr))->GetMobType(),((cMonster *)(*itr))->GetAttackRate()); ((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) cPlayer * cMonster::FindClosestPlayer(void)
{ {
return m_World->FindClosestPlayer(m_Pos, m_SightDistance); 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; MTRand r1;
int Count = r1.randInt() % (a_Max + 1 - a_Min) + a_Min; int Count = r1.randInt() % (a_Max + 1 - a_Min) + a_Min;

View File

@ -41,7 +41,7 @@ public:
virtual bool ReachedDestination(); virtual bool ReachedDestination();
const char *GetState(); const char *GetState();
void SetState(const char* str); void SetState(const AString & str);
static void ListMonsters(); static void ListMonsters();
virtual void CheckEventSeePlayer(); virtual void CheckEventSeePlayer();
@ -93,7 +93,7 @@ protected:
float m_AttackRange; float m_AttackRange;
float m_AttackInterval; 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 }; //tolua_export

View File

@ -122,9 +122,7 @@ void cPawn::TeleportTo( const double & a_PosX, const double & a_PosY, const doub
{ {
SetPosition( a_PosX, a_PosY, a_PosZ ); SetPosition( a_PosX, a_PosY, a_PosZ );
cPacket_TeleportEntity TeleportEntity( this ); GetWorld()->BroadcastTeleportEntity(*this);
cRoot::Get()->GetServer()->Broadcast( TeleportEntity );
} }
@ -133,7 +131,7 @@ void cPawn::TeleportTo( const double & a_PosX, const double & a_PosY, const doub
void cPawn::Tick(float a_Dt) 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) if (GetMetaData() == BURNING)
{ {

View File

@ -148,18 +148,17 @@ void cPickup::Tick(float a_Dt)
return; return;
} }
if(!m_bCollected) if (!m_bCollected)
{ {
HandlePhysics( a_Dt ); HandlePhysics(a_Dt);
} }
if( !m_bReplicated || m_bDirtyPosition ) if (!m_bReplicated || m_bDirtyPosition)
{ {
MoveToCorrectChunk(); MoveToCorrectChunk();
m_bReplicated = true; m_bReplicated = true;
m_bDirtyPosition = false; m_bDirtyPosition = false;
cPacket_TeleportEntity TeleportEntity( this ); GetWorld()->BroadcastTeleportEntity(*this);
GetWorld()->BroadcastToChunk( m_ChunkX, m_ChunkY, m_ChunkZ, TeleportEntity );
} }
} }

View File

@ -77,38 +77,32 @@ void cPiston::ExtendPiston( int pistx, int pisty, int pistz )
} }
int oldx = pistx, oldy = pisty, oldz = pistz; int oldx = pistx, oldy = pisty, oldz = pistz;
char currBlockMeta; 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 ) AddDir(pistx, pisty, pistz, pistonMeta & 7, -1)
currBlock = m_World->GetBlock( pistx, pisty, pistz ); currBlock = m_World->GetBlock(pistx, pisty, pistz);
currBlockMeta = m_World->GetBlockMeta( pistx, pisty, pistz ); currBlockMeta = m_World->GetBlockMeta(pistx, pisty, pistz);
m_World->SetBlock( oldx, oldy, oldz, currBlock, currBlockMeta ); m_World->SetBlock( oldx, oldy, oldz, currBlock, currBlockMeta);
oldx = pistx; oldx = pistx;
oldy = pisty; oldy = pisty;
oldz = pistz; oldz = pistz;
} }
cPacket_BlockAction Action; m_World->BroadcastBlockAction(pistx, pisty, pistz, 0, pistonMeta);
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->FastSetBlock( pistx, pisty, pistz, pistonBlock, pistonMeta | 0x8 ); m_World->FastSetBlock( pistx, pisty, pistz, pistonBlock, pistonMeta | 0x8 );
int extx = pistx; int extx = pistx;
int exty = pisty; int exty = pisty;
int extz = pistz; 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); cRedstone Redstone(m_World);
Redstone.ChangeRedstone( extx, exty, extz, 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. 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; return;
} }
m_World->BroadcastBlockAction(pistx, pisty, pistz, 1, pistonMeta & ~(8));
m_World->FastSetBlock(pistx, pisty, pistz, pistonBlock, pistonMeta & ~(8));
//send blockaction packet AddDir(pistx, pisty, pistz, pistonMeta & 7, 1)
cPacket_BlockAction Action; if (m_World->GetBlock(pistx, pisty, pistz) == E_BLOCK_PISTON_EXTENSION)
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 )
{ {
if ( pistonBlock == E_BLOCK_STICKY_PISTON ) if (pistonBlock == E_BLOCK_STICKY_PISTON)
{ {
int tempx = pistx, tempy = pisty, tempz = pistz; int tempx = pistx, tempy = pisty, tempz = pistz;
AddDir( tempx, tempy, tempz, pistonMeta & 7, 1 ) AddDir( tempx, tempy, tempz, pistonMeta & 7, 1 )

View File

@ -22,17 +22,6 @@
#include "MersenneTwister.h" #include "MersenneTwister.h"
#include "packets/cPacket_NamedEntitySpawn.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 "Vector3d.h"
#include "Vector3f.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 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) if (m_bDirtyOrientation && !m_bDirtyPosition)
{ {
cPacket_EntityLook EntityLook(*this); m_World->BroadcastEntLook(*this, m_ClientHandle);
m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, EntityLook, m_ClientHandle ); m_World->BroadcastEntHeadLook(*this, m_ClientHandle);
cPacket_EntityHeadLook EntityHeadLook(*this);
m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, EntityHeadLook, m_ClientHandle);
m_bDirtyOrientation = false; m_bDirtyOrientation = false;
} }
else if (m_bDirtyPosition ) else if (m_bDirtyPosition)
{ {
cRoot::Get()->GetPluginManager()->CallHook( cPluginManager::E_PLUGIN_PLAYER_MOVE, 1, this ); 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 (cWorld::GetTime() - m_TimeLastTeleportPacket > 2 ) // Send an absolute position every 2 seconds
) )
{ {
//LOG("Teleported %f", sqrtf(SqrDist) ); // LOG("Teleported %f", sqrtf(SqrDist) );
cPacket_TeleportEntity TeleportEntity( this ); m_World->BroadcastTeleportEntity(*this, m_ClientHandle);
m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, TeleportEntity, m_ClientHandle);
m_TimeLastTeleportPacket = cWorld::GetTime(); m_TimeLastTeleportPacket = cWorld::GetTime();
} }
else 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; m_World->BroadcastRelEntMoveLook(*this, (char)(DiffX * 32), (char)(DiffY * 32), (char)(DiffZ * 32), m_ClientHandle);
RelativeEntityMoveLook.m_UniqueID = GetUniqueID(); m_bDirtyOrientation = false;
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 );
} }
else else
{ {
cPacket_RelativeEntityMove RelativeEntityMove; m_World->BroadcastRelEntMove(*this, (char)(DiffX * 32), (char)(DiffY * 32), (char)(DiffZ * 32), m_ClientHandle);
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_LastPosX = GetPosX(); 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 // TODO: Increase Exhaustion level http://www.minecraftwiki.net/wiki/Hunger#Exhaustion_level_increase
if(m_FoodExhaustionLevel >= 4.f) if (m_FoodExhaustionLevel >= 4.f)
{ {
m_FoodExhaustionLevel -= 4.f; m_FoodExhaustionLevel -= 4.f;
if(m_FoodSaturationLevel >= 1.f) if (m_FoodSaturationLevel >= 1.f)
{
m_FoodSaturationLevel--; m_FoodSaturationLevel--;
}
else else
{
m_FoodLevel = MAX(m_FoodLevel -1, 0); m_FoodLevel = MAX(m_FoodLevel -1, 0);
}
SendHealth(); 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; m_bTouchGround = a_bTouchGround;
if( !m_bTouchGround ) if (!m_bTouchGround)
{ {
cWorld* World = GetWorld(); cWorld* World = GetWorld();
char BlockID = World->GetBlock( float2int(m_Pos.x), float2int(m_Pos.y), float2int(m_Pos.z) ); char BlockID = World->GetBlock( float2int(m_Pos.x), float2int(m_Pos.y), float2int(m_Pos.z) );
if( BlockID != E_BLOCK_AIR ) if( BlockID != E_BLOCK_AIR )
{ {
// LOGD("TouchGround set to true by server");
m_bTouchGround = true; m_bTouchGround = true;
} }
if( BlockID == E_BLOCK_WATER || BlockID == E_BLOCK_STATIONARY_WATER || BlockID == E_BLOCK_LADDER || BlockID == E_BLOCK_TORCH ) 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; m_LastGroundHeight = (float)m_Pos.y;
} }
} }
if( m_bTouchGround ) if (m_bTouchGround)
{ {
float Dist = (float)(m_LastGroundHeight - m_Pos.y); 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); TakeDamage(Damage, 0);
if( Damage > 0 )
{
TakeDamage( Damage, 0 );
}
} }
m_LastGroundHeight = (float)m_Pos.y; m_LastGroundHeight = (float)m_Pos.y;
} }
} }
void cPlayer::Heal( int a_Health ) void cPlayer::Heal( int a_Health )
{ {
if( m_Health < GetMaxHealth() ) if( m_Health < GetMaxHealth() )
@ -338,6 +323,10 @@ void cPlayer::Heal( int a_Health )
} }
} }
bool cPlayer::Feed(short a_Food, float a_Saturation) bool cPlayer::Feed(short a_Food, float a_Saturation)
{ {
if (m_FoodLevel >= GetMaxFoodLevel()) if (m_FoodLevel >= GetMaxFoodLevel())
@ -352,19 +341,25 @@ bool cPlayer::Feed(short a_Food, float a_Saturation)
return true; return true;
} }
void cPlayer::SendHealth() void cPlayer::SendHealth()
{ {
cPacket_UpdateHealth Health; if (m_ClientHandle != NULL)
Health.m_Health = GetHealth(); {
Health.m_Food = GetFoodLevel(); m_ClientHandle->SendHealth();
Health.m_Saturation = GetFoodSaturationLevel(); }
if(m_ClientHandle != 0)
m_ClientHandle->Send( Health );
} }
void cPlayer::TakeDamage( int a_Damage, cEntity* a_Instigator ) 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 ); cPawn::TakeDamage( a_Damage, a_Instigator );
@ -412,23 +407,20 @@ void cPlayer::Respawn()
{ {
m_Health = GetMaxHealth(); m_Health = GetMaxHealth();
// Create Respawn player packet m_ClientHandle->SendRespawn();
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 );
//Set non Burning // Set non Burning
SetMetaData(NORMAL); SetMetaData(NORMAL);
TeleportTo( GetWorld()->GetSpawnX(), GetWorld()->GetSpawnY(), GetWorld()->GetSpawnZ() ); TeleportTo(GetWorld()->GetSpawnX(), GetWorld()->GetSpawnY(), GetWorld()->GetSpawnZ());
SetVisible( true ); SetVisible(true);
} }
double cPlayer::GetEyeHeight() double cPlayer::GetEyeHeight()
{ {
return m_Stance; 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 // 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)) if ((a_WindowType == 1) && (m_CurrentWindow->GetWindowType() == cWindow::Chest))
{ {
// Chest int x, y, z;
cPacket_BlockAction ChestClose; m_CurrentWindow->GetOwner()->GetBlockPos(x, y, z);
int y = 0; m_World->BroadcastBlockAction(x, y, z, 1, 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);
} }
m_CurrentWindow->Close( *this ); 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) LOGWARNING("%s: Setting invalid gamemode: %d", GetName().c_str(), a_GameMode);
{ return;
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());
}
} }
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; 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 ); SetPosition( a_PosX, a_PosY, a_PosZ );
cPacket_TeleportEntity TeleportEntity( this ); m_World->BroadcastTeleportEntity(*this, GetClientHandle());
cRoot::Get()->GetServer()->Broadcast( TeleportEntity, GetClientHandle() ); m_ClientHandle->SendPlayerMoveLook();
cPacket_PlayerPosition PlayerPosition( this );
m_ClientHandle->Send( PlayerPosition );
} }
@ -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 // TODO: Official server refuses position packets too far away from each other, kicking "hacked" clients; we should, too
SetPosition( a_NewPos ); 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 if (a_bVisible && !m_bVisible) // Make visible
{ {
m_bVisible = true; m_bVisible = true;
SpawnOn( NULL ); // Spawn on everybody SpawnOn(NULL); // Spawn on all clients
} }
if (!a_bVisible && m_bVisible) if (!a_bVisible && m_bVisible)
{ {
m_bVisible = false; m_bVisible = false;
cPacket_DestroyEntity DestroyEntity( this ); m_World->BroadcastDestroyEntity(*this, m_ClientHandle); // Destroy on all clients
m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, DestroyEntity ); // Destroy on all clients
} }
} }

View File

@ -35,12 +35,13 @@ public:
virtual void Tick(float a_Dt) override; virtual void Tick(float a_Dt) override;
void SetTouchGround( bool a_bTouchGround ); 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 double GetEyeHeight(); //tolua_export
Vector3d GetEyePosition(); //tolua_export Vector3d GetEyePosition(); //tolua_export
OBSOLETE
inline bool GetFlying() { return m_bTouchGround; } //tolua_export inline bool GetFlying() { return m_bTouchGround; } //tolua_export
inline bool IsOnGround(void) const {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 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 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 SetLastBlockActionTime(); //tolua_export
void SetGameMode( eGameMode a_GameMode ); //tolua_export void SetGameMode( eGameMode a_GameMode ); //tolua_export
void LoginSetGameMode( eGameMode a_GameMode ); 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 // Tries to move to a new position, with collision checks and stuff
virtual void MoveTo( const Vector3d & a_NewPos ); //tolua_export virtual void MoveTo( const Vector3d & a_NewPos ); //tolua_export
@ -62,9 +63,9 @@ public:
void OpenWindow( cWindow* a_Window ); void OpenWindow( cWindow* a_Window );
void CloseWindow(char a_WindowType); 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 const AString & GetName(void) const { return m_PlayerName; } //tolua_export
void SetName(const AString & a_Name) { m_PlayerName = a_Name; } //tolua_export void SetName(const AString & a_Name) { m_PlayerName = a_Name; } //tolua_export

View File

@ -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_Reason);
UNUSED(a_Player); UNUSED(a_Player);

View File

@ -56,8 +56,8 @@ public:
virtual bool OnChunkGenerating (cWorld * a_World, int a_ChunkX, int a_ChunkZ, cLuaChunk * a_pLuaChunk); 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 OnCollectItem (cPickup* a_Pickup, cPlayer* a_Player );
virtual bool OnCraftingNoRecipe(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe); 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 OnDisconnect (cPlayer * a_Player, const AString & a_Reason);
virtual bool OnKilled (cPawn* a_Killed, cEntity* a_Killer ); virtual bool OnKilled (cPawn * a_Killed, cEntity* a_Killer );
virtual bool OnLogin (cClientHandle * a_Client, int a_ProtocolVersion, const AString & a_Username); virtual bool OnLogin (cClientHandle * a_Client, int a_ProtocolVersion, const AString & a_Username);
virtual bool OnPlayerJoin (cPlayer* a_Player ); virtual bool OnPlayerJoin (cPlayer* a_Player );
virtual void OnPlayerMove (cPlayer* a_Player ); virtual void OnPlayerMove (cPlayer* a_Player );

View File

@ -214,22 +214,6 @@ bool cPluginManager::CallHook(PluginHook a_Hook, unsigned int a_NumArgs, ...)
break; 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: case HOOK_PLAYER_JOIN:
{ {
if( a_NumArgs != 1 ) break; 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) bool cPluginManager::CallHookPostCrafting(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe)
{ {
HookMap::iterator Plugins = m_Hooks.find(HOOK_POST_CRAFTING); HookMap::iterator Plugins = m_Hooks.find(HOOK_POST_CRAFTING);

View File

@ -103,6 +103,7 @@ public: //tolua_export
bool CallHookChat (cPlayer * a_Player, const AString & a_Message); bool CallHookChat (cPlayer * a_Player, const AString & a_Message);
bool CallHookChunkGenerating (cWorld * a_World, int a_ChunkX, int a_ChunkZ, cLuaChunk * a_Chunk); 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 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 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 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); bool CallHookPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe);

View File

@ -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 ); cCSLock Lock(m_CriticalSection);
if( !PushFunction("OnDisconnect") ) if (!PushFunction("OnDisconnect"))
{
return false; return false;
}
tolua_pushstring( m_LuaState, a_Reason.c_str() );
tolua_pushusertype(m_LuaState, a_Player, "cPlayer"); 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; return false;
}
bool bRetVal = (tolua_toboolean( m_LuaState, -1, 0) > 0); return (tolua_toboolean( m_LuaState, -1, 0) > 0);
return bRetVal;
} }

View File

@ -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 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 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 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 OnKilled (cPawn* a_Killed, cEntity* a_Killer ) override;
virtual bool OnLogin (cClientHandle * a_Client, int a_ProtocolVersion, const AString & a_Username) override; virtual bool OnLogin (cClientHandle * a_Client, int a_ProtocolVersion, const AString & a_Username) override;
virtual bool OnPlayerJoin (cPlayer* a_Player ) override; virtual bool OnPlayerJoin (cPlayer* a_Player ) override;

View File

@ -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 ); cCSLock Lock( m_CriticalSection );
if(!m_Plugin->HasFunction("OnDisconnect")) return false; if (!m_Plugin->HasFunction("OnDisconnect")) return false;
return m_Plugin->GetFunction("OnDisconnect").Evaluate<bool>(a_Reason, a_Player); return m_Plugin->GetFunction("OnDisconnect").Evaluate<bool>(a_Player, a_Reason);
} }

View File

@ -22,7 +22,7 @@ public:
virtual bool OnChunkGenerating (cWorld * a_World, int a_ChunkX, int a_ChunkZ, cLuaChunk * a_pLuaChunk ) override; 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 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 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 OnKilled (cPawn* a_Killed, cEntity* a_Killer ) override;
virtual bool OnLogin (cClientHandle * a_Client, int a_ProtocolVersion, const AString & a_Username) override; virtual bool OnLogin (cClientHandle * a_Client, int a_ProtocolVersion, const AString & a_Username) override;
virtual bool OnPlayerJoin (cPlayer* a_Player ) override; virtual bool OnPlayerJoin (cPlayer* a_Player ) override;

View File

@ -83,9 +83,9 @@ AString cSignEntity::GetLine( int a_Index ) const
cPacket * cSignEntity::GetPacket(void) cPacket * cSignEntity::GetPacket(void)
{ {
cPacket_UpdateSign * Sign = new cPacket_UpdateSign; cPacket_UpdateSign * Sign = new cPacket_UpdateSign;
Sign->m_PosX = m_PosX; Sign->m_BlockX = m_PosX;
Sign->m_PosY = (short)m_PosY; Sign->m_BlockY = (short)m_PosY;
Sign->m_PosZ = m_PosZ; Sign->m_BlockZ = m_PosZ;
Sign->m_Line1 = m_Line[0]; Sign->m_Line1 = m_Line[0];
Sign->m_Line2 = m_Line[1]; Sign->m_Line2 = m_Line[1];
Sign->m_Line3 = m_Line[2]; Sign->m_Line3 = m_Line[2];

View File

@ -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) void cWorld::MarkChunkDirty (int a_ChunkX, int a_ChunkY, int a_ChunkZ)
{ {
m_ChunkMap->MarkChunkDirty (a_ChunkX, a_ChunkY, 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 // Sends the playerlist to a_DestPlayer
cCSLock Lock(m_CSPlayers); 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(); cClientHandle * ch = (*itr)->GetClientHandle();
if ((ch != NULL) && !ch->IsDestroyed()) if ((ch != NULL) && !ch->IsDestroyed())
{ {
cPacket_PlayerListItem PlayerListItem((*itr)->GetColor() + (*itr)->GetName(), true, (*itr)->GetClientHandle()->GetPing()); a_DestPlayer->GetClientHandle()->SendPlayerListItem(*(*itr));
a_DestPlayer->GetClientHandle()->Send( PlayerListItem );
} }
} }
} }

View File

@ -81,6 +81,13 @@ public:
void BroadcastChat(const AString & a_Message, const cClientHandle * a_Exclude = NULL); 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 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 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 MarkChunkDirty (int a_ChunkX, int a_ChunkY, int a_ChunkZ);
void MarkChunkSaving(int a_ChunkX, int a_ChunkY, int a_ChunkZ); void MarkChunkSaving(int a_ChunkX, int a_ChunkY, int a_ChunkZ);

View File

@ -10,9 +10,9 @@
cPacket_BlockAction::cPacket_BlockAction( const cPacket_BlockAction & a_Copy ) cPacket_BlockAction::cPacket_BlockAction( const cPacket_BlockAction & a_Copy )
{ {
m_PacketID = E_BLOCK_ACTION; m_PacketID = E_BLOCK_ACTION;
m_PosX = a_Copy.m_PosX; m_BlockX = a_Copy.m_BlockX;
m_PosY = a_Copy.m_PosY; m_BlockY = a_Copy.m_BlockY;
m_PosZ = a_Copy.m_PosZ; m_BlockZ = a_Copy.m_BlockZ;
m_Byte1 = a_Copy.m_Byte1; m_Byte1 = a_Copy.m_Byte1;
m_Byte2 = a_Copy.m_Byte2; 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 void cPacket_BlockAction::Serialize(AString & a_Data) const
{ {
AppendByte (a_Data, m_PacketID); AppendByte (a_Data, m_PacketID);
AppendInteger(a_Data, m_PosX); AppendInteger(a_Data, m_BlockX);
AppendShort (a_Data, m_PosY); AppendShort (a_Data, m_BlockY);
AppendInteger(a_Data, m_PosZ); AppendInteger(a_Data, m_BlockZ);
AppendByte (a_Data, m_Byte1); AppendByte (a_Data, m_Byte1);
AppendByte (a_Data, m_Byte2); AppendByte (a_Data, m_Byte2);
} }

View File

@ -4,28 +4,33 @@
#include "cPacket.h" #include "cPacket.h"
class cPacket_BlockAction : public cPacket
class cPacket_BlockAction :
public cPacket
{ {
public: public:
cPacket_BlockAction() cPacket_BlockAction()
: m_PosX( 0 ) : m_BlockX( 0 )
, m_PosY( 0 ) , m_BlockY( 0 )
, m_PosZ( 0 ) , m_BlockZ( 0 )
, m_Byte1( 0 ) , m_Byte1( 0 )
, m_Byte2( 0 ) , m_Byte2( 0 )
{ m_PacketID = E_BLOCK_ACTION; } {
m_PacketID = E_BLOCK_ACTION;
}
cPacket_BlockAction( const cPacket_BlockAction & a_Copy ); 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; virtual void Serialize(AString & a_Data) const override;
int m_PosX; // Block X Coordinate int m_BlockX;
short m_PosY; // Block Y Coordinate short m_BlockY;
int m_PosZ; // Block Z Coordinate int m_BlockZ;
char m_Byte1; // Varies char m_Byte1; // Varies
char m_Byte2; // Varies char m_Byte2; // Varies
static const unsigned int c_Size = 1 + 4 + 2 + 4 + 1 + 1;
}; };

View File

@ -43,14 +43,17 @@ public:
cPacket_EntityHeadLook(void) cPacket_EntityHeadLook(void)
: m_UniqueID( 0 ) : m_UniqueID( 0 )
, m_HeadYaw( 0 ) , m_HeadYaw( 0 )
{ m_PacketID = E_ENT_LOOK; } {
m_PacketID = E_ENT_LOOK;
}
cPacket_EntityHeadLook(const cEntity & a_Entity); cPacket_EntityHeadLook(const cEntity & a_Entity);
virtual cPacket * Clone(void) const { return new cPacket_EntityHeadLook(*this); } virtual cPacket * Clone(void) const { return new cPacket_EntityHeadLook(*this); }
virtual void Serialize(AString & a_Data) const override; virtual void Serialize(AString & a_Data) const override;
int m_UniqueID; int m_UniqueID;
char m_HeadYaw; char m_HeadYaw;
}; };

View File

@ -12,14 +12,12 @@ class cPacket_KeepAlive : public cPacket
public: public:
cPacket_KeepAlive() { m_PacketID = E_KEEP_ALIVE; } cPacket_KeepAlive() { m_PacketID = E_KEEP_ALIVE; }
cPacket_KeepAlive(int a_PingID) { m_KeepAliveID = a_PingID; } 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; virtual void Serialize(AString & a_Data) const override;
int m_KeepAliveID; int m_KeepAliveID;
static const unsigned int c_Size = 1 + 4;
}; };

View File

@ -143,16 +143,16 @@ void cPacket_PlayerLook::Serialize(AString & a_Data) const
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cPacket_PlayerMoveLook: // cPacket_PlayerMoveLook:
cPacket_PlayerMoveLook::cPacket_PlayerMoveLook( cPlayer* a_Player ) cPacket_PlayerMoveLook::cPacket_PlayerMoveLook(const cPlayer & a_Player)
{ {
m_PacketID = E_PLAYERMOVELOOK; m_PacketID = E_PLAYERMOVELOOK;
m_PosX = a_Player->GetPosX(); m_PosX = a_Player.GetPosX();
m_PosY = a_Player->GetPosY() + 1.65; 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_PosZ = a_Player.GetPosZ();
m_Stance = a_Player->GetStance(); 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_Rotation = a_Player.GetRotation();
m_Pitch = a_Player->GetPitch(); m_Pitch = a_Player.GetPitch();
m_IsOnGround = a_Player->IsOnGround(); m_IsOnGround = a_Player.IsOnGround();
} }
@ -161,6 +161,8 @@ cPacket_PlayerMoveLook::cPacket_PlayerMoveLook( cPlayer* a_Player )
int cPacket_PlayerMoveLook::Parse(cByteBuffer & a_Buffer) 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; int TotalBytes = 0;
HANDLE_PACKET_READ(ReadBEDouble, m_PosX, TotalBytes); HANDLE_PACKET_READ(ReadBEDouble, m_PosX, TotalBytes);
HANDLE_PACKET_READ(ReadBEDouble, m_PosY, 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_Rotation, TotalBytes);
HANDLE_PACKET_READ(ReadBEFloat, m_Pitch, TotalBytes); HANDLE_PACKET_READ(ReadBEFloat, m_Pitch, TotalBytes);
HANDLE_PACKET_READ(ReadBool, m_IsOnGround, 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; return TotalBytes;
} }
@ -178,10 +181,14 @@ int cPacket_PlayerMoveLook::Parse(cByteBuffer & a_Buffer)
void cPacket_PlayerMoveLook::Serialize(AString & a_Data) const 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); AppendByte (a_Data, m_PacketID);
AppendDouble(a_Data, m_PosX); AppendDouble(a_Data, m_PosX);
AppendDouble(a_Data, m_PosY);
AppendDouble(a_Data, m_Stance); AppendDouble(a_Data, m_Stance);
AppendDouble(a_Data, m_PosY);
AppendDouble(a_Data, m_PosZ); AppendDouble(a_Data, m_PosZ);
AppendFloat (a_Data, m_Rotation); AppendFloat (a_Data, m_Rotation);
AppendFloat (a_Data, m_Pitch); AppendFloat (a_Data, m_Pitch);
@ -200,7 +207,7 @@ cPacket_PlayerPosition::cPacket_PlayerPosition(cPlayer * a_Player)
m_PacketID = E_PLAYERPOS; m_PacketID = E_PLAYERPOS;
m_PosX = a_Player->GetPosX(); m_PosX = a_Player->GetPosX();
m_PosY = a_Player->GetPosY() + 1.65; m_PosY = a_Player->GetPosY();
m_PosZ = a_Player->GetPosZ(); m_PosZ = a_Player->GetPosZ();
m_Stance = a_Player->GetStance(); m_Stance = a_Player->GetStance();
m_IsOnGround = a_Player->IsOnGround(); 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_Stance, TotalBytes);
HANDLE_PACKET_READ(ReadBEDouble, m_PosZ, TotalBytes); HANDLE_PACKET_READ(ReadBEDouble, m_PosZ, TotalBytes);
HANDLE_PACKET_READ(ReadBool, m_IsOnGround, 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; return TotalBytes;
} }
@ -227,12 +235,17 @@ int cPacket_PlayerPosition::Parse(cByteBuffer & a_Buffer)
void cPacket_PlayerPosition::Serialize(AString & a_Data) const 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); AppendByte (a_Data, m_PacketID);
AppendDouble (a_Data, m_PosX); AppendDouble (a_Data, m_PosX);
AppendDouble (a_Data, m_PosY); AppendDouble (a_Data, m_PosY);
AppendDouble (a_Data, m_Stance); AppendDouble (a_Data, m_Stance);
AppendDouble (a_Data, m_PosZ); AppendDouble (a_Data, m_PosZ);
AppendBool (a_Data, m_IsOnGround); AppendBool (a_Data, m_IsOnGround);
*/
} }

View File

@ -109,8 +109,8 @@ public:
m_PacketID = E_PLAYERMOVELOOK; m_PacketID = E_PLAYERMOVELOOK;
} }
cPacket_PlayerMoveLook( cPlayer* a_Player ); cPacket_PlayerMoveLook(const cPlayer & a_Player);
virtual cPacket* Clone() const { return new cPacket_PlayerMoveLook(*this); } virtual cPacket * Clone() const { return new cPacket_PlayerMoveLook(*this); }
virtual int Parse(cByteBuffer & a_Buffer) override; virtual int Parse(cByteBuffer & a_Buffer) override;
virtual void Serialize(AString & a_Data) const override; virtual void Serialize(AString & a_Data) const override;

View File

@ -9,26 +9,29 @@
class cPacket_Respawn : public cPacket class cPacket_Respawn :
public cPacket
{ {
public: public:
cPacket_Respawn() cPacket_Respawn()
: m_Dimension( 0 ) : m_Dimension(0)
, m_Difficulty( 0 ) , m_Difficulty(0)
, m_CreativeMode( 0 ) , m_CreativeMode(0)
, m_WorldHeight( 0 ) , m_WorldHeight(256)
, m_LevelType( cPacket_Login::LEVEL_TYPE_DEFAULT ) , 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; virtual void Serialize(AString & a_Data) const override;
int m_Dimension; int m_Dimension;
char m_Difficulty; char m_Difficulty;
char m_CreativeMode; char m_CreativeMode;
short m_WorldHeight; short m_WorldHeight;
AString m_LevelType; AString m_LevelType;
}; };

View File

@ -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_PacketID = E_ENT_TELEPORT;
m_UniqueID = a_Client->GetUniqueID(); m_UniqueID = a_Entity.GetUniqueID();
m_PosX = (int)(a_Client->GetPosX() * 32); m_PosX = (int)(a_Entity.GetPosX() * 32);
m_PosY = (int)(a_Client->GetPosY() * 32); m_PosY = (int)(a_Entity.GetPosY() * 32);
m_PosZ = (int)(a_Client->GetPosZ() * 32); m_PosZ = (int)(a_Entity.GetPosZ() * 32);
m_Rotation = (char)((a_Client->GetRotation() / 360.f) * 256); m_Rotation = (char)((a_Entity.GetRotation() / 360.f) * 256);
m_Pitch = (char)((a_Client->GetPitch() / 360.f) * 256); m_Pitch = (char)((a_Entity.GetPitch() / 360.f) * 256);
} }

View File

@ -18,9 +18,12 @@ public:
, m_PosZ( 0 ) , m_PosZ( 0 )
, m_Rotation( 0 ) , m_Rotation( 0 )
, m_Pitch( 0 ) , m_Pitch( 0 )
{ m_PacketID = E_ENT_TELEPORT; } {
virtual cPacket* Clone() const { return new cPacket_TeleportEntity(*this); } m_PacketID = E_ENT_TELEPORT;
cPacket_TeleportEntity(cEntity* a_Client); }
virtual cPacket * Clone() const { return new cPacket_TeleportEntity(*this); }
cPacket_TeleportEntity(const cEntity & a_Entity);
virtual void Serialize(AString & a_Data) const override; virtual void Serialize(AString & a_Data) const override;

View File

@ -10,9 +10,9 @@
int cPacket_UpdateSign::Parse(cByteBuffer & a_Buffer) int cPacket_UpdateSign::Parse(cByteBuffer & a_Buffer)
{ {
int TotalBytes = 0; int TotalBytes = 0;
HANDLE_PACKET_READ(ReadBEInt, m_PosX, TotalBytes); HANDLE_PACKET_READ(ReadBEInt, m_BlockX, TotalBytes);
HANDLE_PACKET_READ(ReadBEShort, m_PosY, TotalBytes); HANDLE_PACKET_READ(ReadBEShort, m_BlockY, TotalBytes);
HANDLE_PACKET_READ(ReadBEInt, m_PosZ, TotalBytes); HANDLE_PACKET_READ(ReadBEInt, m_BlockZ, TotalBytes);
HANDLE_PACKET_READ(ReadBEUTF16String16, m_Line1, TotalBytes); HANDLE_PACKET_READ(ReadBEUTF16String16, m_Line1, TotalBytes);
HANDLE_PACKET_READ(ReadBEUTF16String16, m_Line2, TotalBytes); HANDLE_PACKET_READ(ReadBEUTF16String16, m_Line2, TotalBytes);
HANDLE_PACKET_READ(ReadBEUTF16String16, m_Line3, 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 void cPacket_UpdateSign::Serialize(AString & a_Data) const
{ {
AppendByte (a_Data, m_PacketID); AppendByte (a_Data, m_PacketID);
AppendInteger (a_Data, m_PosX); AppendInteger (a_Data, m_BlockX);
AppendShort (a_Data, m_PosY); AppendShort (a_Data, m_BlockY);
AppendInteger (a_Data, m_PosZ); AppendInteger (a_Data, m_BlockZ);
AppendString16(a_Data, m_Line1); AppendString16(a_Data, m_Line1);
AppendString16(a_Data, m_Line2); AppendString16(a_Data, m_Line2);
AppendString16(a_Data, m_Line3); AppendString16(a_Data, m_Line3);

View File

@ -11,24 +11,25 @@ class cPacket_UpdateSign : public cPacket
{ {
public: public:
cPacket_UpdateSign() cPacket_UpdateSign()
: m_PosX( 0 ) : m_BlockX( 0 )
, m_PosY( 0 ) , m_BlockY( 0 )
, m_PosZ( 0 ) , m_BlockZ( 0 )
{ m_PacketID = E_UPDATE_SIGN; } {
virtual cPacket* Clone() const { return new cPacket_UpdateSign( *this ); } m_PacketID = E_UPDATE_SIGN;
}
virtual cPacket * Clone() const { return new cPacket_UpdateSign( *this ); }
virtual int Parse(cByteBuffer & a_Buffer) override; virtual int Parse(cByteBuffer & a_Buffer) override;
virtual void Serialize(AString & a_Data) const override; virtual void Serialize(AString & a_Data) const override;
int m_PosX; int m_BlockX;
short m_PosY; short m_BlockY;
int m_PosZ; int m_BlockZ;
AString m_Line1; AString m_Line1;
AString m_Line2; AString m_Line2;
AString m_Line3; AString m_Line3;
AString m_Line4; AString m_Line4;
static const unsigned int c_Size = 1 + 4 + 2 + 4 + 2 + 2 + 2 + 2; // minimum size
}; };

View File

@ -10,9 +10,9 @@
int cPacket_UseEntity::Parse(cByteBuffer & a_Buffer) int cPacket_UseEntity::Parse(cByteBuffer & a_Buffer)
{ {
int TotalBytes = 0; int TotalBytes = 0;
HANDLE_PACKET_READ(ReadBEInt, m_UniqueID, TotalBytes); HANDLE_PACKET_READ(ReadBEInt, m_SourceEntityID, TotalBytes);
HANDLE_PACKET_READ(ReadBEInt, m_TargetID, TotalBytes); HANDLE_PACKET_READ(ReadBEInt, m_TargetEntityID, TotalBytes);
HANDLE_PACKET_READ(ReadBool, m_bLeftClick, TotalBytes); HANDLE_PACKET_READ(ReadBool, m_IsLeftClick, TotalBytes);
return TotalBytes; return TotalBytes;
} }

View File

@ -7,23 +7,25 @@
class cPacket_UseEntity : public cPacket class cPacket_UseEntity :
public cPacket
{ {
public: public:
cPacket_UseEntity() cPacket_UseEntity()
: m_UniqueID( 0 ) : m_SourceEntityID(0)
, m_TargetID( 0 ) , m_TargetEntityID(0)
, m_bLeftClick( false ) , m_IsLeftClick(false)
{ m_PacketID = E_USE_ENTITY; } {
virtual cPacket* Clone() const { return new cPacket_UseEntity(*this); } m_PacketID = E_USE_ENTITY;
}
virtual cPacket * Clone() const { return new cPacket_UseEntity(*this); }
virtual int Parse(cByteBuffer & a_Buffer) override; virtual int Parse(cByteBuffer & a_Buffer) override;
int m_UniqueID; int m_SourceEntityID;
int m_TargetID; int m_TargetEntityID;
bool m_bLeftClick; bool m_IsLeftClick;
static const unsigned int c_Size = 1 + 4 + 4 + 1;
}; };