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
** Generated automatically by tolua++-1.0.92 on 08/19/12 13:48:32.
** Generated automatically by tolua++-1.0.92 on 08/19/12 21:46:45.
*/
#ifndef __cplusplus
@ -5931,14 +5931,14 @@ static int tolua_AllToLua_cPlayer_GetStance00(lua_State* tolua_S)
#ifndef TOLUA_RELEASE
tolua_Error tolua_err;
if (
!tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) ||
!tolua_isusertype(tolua_S,1,"const cPlayer",0,&tolua_err) ||
!tolua_isnoobj(tolua_S,2,&tolua_err)
)
goto tolua_lerror;
else
#endif
{
cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0);
const cPlayer* self = (const cPlayer*) tolua_tousertype(tolua_S,1,0);
#ifndef TOLUA_RELEASE
if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetStance'", NULL);
#endif
@ -6293,14 +6293,14 @@ static int tolua_AllToLua_cPlayer_GetClientHandle00(lua_State* tolua_S)
#ifndef TOLUA_RELEASE
tolua_Error tolua_err;
if (
!tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) ||
!tolua_isusertype(tolua_S,1,"const cPlayer",0,&tolua_err) ||
!tolua_isnoobj(tolua_S,2,&tolua_err)
)
goto tolua_lerror;
else
#endif
{
cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0);
const cPlayer* self = (const cPlayer*) tolua_tousertype(tolua_S,1,0);
#ifndef TOLUA_RELEASE
if (!self) tolua_error(tolua_S,"invalid 'self' in function 'GetClientHandle'", NULL);
#endif
@ -6326,7 +6326,7 @@ static int tolua_AllToLua_cPlayer_SendMessage00(lua_State* tolua_S)
tolua_Error tolua_err;
if (
!tolua_isusertype(tolua_S,1,"cPlayer",0,&tolua_err) ||
!tolua_isstring(tolua_S,2,0,&tolua_err) ||
!tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
!tolua_isnoobj(tolua_S,3,&tolua_err)
)
goto tolua_lerror;
@ -6334,15 +6334,16 @@ static int tolua_AllToLua_cPlayer_SendMessage00(lua_State* tolua_S)
#endif
{
cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0);
const char* a_Message = ((const char*) tolua_tostring(tolua_S,2,0));
const AString a_Message = ((const AString) tolua_tocppstring(tolua_S,2,0));
#ifndef TOLUA_RELEASE
if (!self) tolua_error(tolua_S,"invalid 'self' in function 'SendMessage'", NULL);
#endif
{
self->SendMessage(a_Message);
tolua_pushcppstring(tolua_S,(const char*)a_Message);
}
}
return 0;
return 1;
#ifndef TOLUA_RELEASE
tolua_lerror:
tolua_error(tolua_S,"#ferror in function 'SendMessage'.",&tolua_err);
@ -7903,8 +7904,8 @@ static int tolua_AllToLua_cPlugin_OnDisconnect00(lua_State* tolua_S)
tolua_Error tolua_err;
if (
!tolua_isusertype(tolua_S,1,"cPlugin",0,&tolua_err) ||
!tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
!tolua_isusertype(tolua_S,3,"cPlayer",0,&tolua_err) ||
!tolua_isusertype(tolua_S,2,"cPlayer",0,&tolua_err) ||
!tolua_iscppstring(tolua_S,3,0,&tolua_err) ||
!tolua_isnoobj(tolua_S,4,&tolua_err)
)
goto tolua_lerror;
@ -7912,13 +7913,13 @@ static int tolua_AllToLua_cPlugin_OnDisconnect00(lua_State* tolua_S)
#endif
{
cPlugin* self = (cPlugin*) tolua_tousertype(tolua_S,1,0);
const AString a_Reason = ((const AString) tolua_tocppstring(tolua_S,2,0));
cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,3,0));
cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,2,0));
const AString a_Reason = ((const AString) tolua_tocppstring(tolua_S,3,0));
#ifndef TOLUA_RELEASE
if (!self) tolua_error(tolua_S,"invalid 'self' in function 'OnDisconnect'", NULL);
#endif
{
bool tolua_ret = (bool) self->OnDisconnect(a_Reason,a_Player);
bool tolua_ret = (bool) self->OnDisconnect(a_Player,a_Reason);
tolua_pushboolean(tolua_S,(bool)tolua_ret);
tolua_pushcppstring(tolua_S,(const char*)a_Reason);
}
@ -8759,16 +8760,16 @@ public:
return ( bool ) cPlugin:: OnCraftingNoRecipe(a_Player,a_Grid,a_Recipe);
};
};
bool OnDisconnect( const AString& a_Reason, cPlayer* a_Player) {
bool OnDisconnect( cPlayer* a_Player, const AString& a_Reason) {
if (push_method("OnDisconnect", tolua_AllToLua_cPlugin_OnDisconnect00)) {
tolua_pushcppstring(lua_state, (const char*)a_Reason);
tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer");
tolua_pushcppstring(lua_state, (const char*)a_Reason);
ToluaBase::dbcall(lua_state, 3, 1);
bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0);
lua_pop(lua_state, 1);
return tolua_ret;
} else {
return ( bool ) cPlugin:: OnDisconnect(a_Reason,a_Player);
return ( bool ) cPlugin:: OnDisconnect(a_Player,a_Reason);
};
};
bool OnKilled( cPawn* a_Killed, cEntity* a_Killer) {
@ -8936,8 +8937,8 @@ public:
bool cPlugin__OnCraftingNoRecipe( const cPlayer* a_Player, const cCraftingGrid* a_Grid, cCraftingRecipe* a_Recipe) {
return ( bool )cPlugin::OnCraftingNoRecipe(a_Player,a_Grid,a_Recipe);
};
bool cPlugin__OnDisconnect( const AString& a_Reason, cPlayer* a_Player) {
return ( bool )cPlugin::OnDisconnect(a_Reason,a_Player);
bool cPlugin__OnDisconnect( cPlayer* a_Player, const AString& a_Reason) {
return ( bool )cPlugin::OnDisconnect(a_Player,a_Reason);
};
bool cPlugin__OnKilled( cPawn* a_Killed, cEntity* a_Killer) {
return ( bool )cPlugin::OnKilled(a_Killed,a_Killer);
@ -9402,8 +9403,8 @@ static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnDisconnect00(lua_State* tolua_
tolua_Error tolua_err;
if (
!tolua_isusertype(tolua_S,1,"Lua__cPlugin",0,&tolua_err) ||
!tolua_iscppstring(tolua_S,2,0,&tolua_err) ||
!tolua_isusertype(tolua_S,3,"cPlayer",0,&tolua_err) ||
!tolua_isusertype(tolua_S,2,"cPlayer",0,&tolua_err) ||
!tolua_iscppstring(tolua_S,3,0,&tolua_err) ||
!tolua_isnoobj(tolua_S,4,&tolua_err)
)
goto tolua_lerror;
@ -9411,13 +9412,13 @@ static int tolua_AllToLua_Lua__cPlugin_cPlugin__OnDisconnect00(lua_State* tolua_
#endif
{
Lua__cPlugin* self = (Lua__cPlugin*) tolua_tousertype(tolua_S,1,0);
const AString a_Reason = ((const AString) tolua_tocppstring(tolua_S,2,0));
cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,3,0));
cPlayer* a_Player = ((cPlayer*) tolua_tousertype(tolua_S,2,0));
const AString a_Reason = ((const AString) tolua_tocppstring(tolua_S,3,0));
#ifndef TOLUA_RELEASE
if (!self) tolua_error(tolua_S,"invalid 'self' in function 'cPlugin__OnDisconnect'", NULL);
#endif
{
bool tolua_ret = (bool) self->cPlugin__OnDisconnect(a_Reason,a_Player);
bool tolua_ret = (bool) self->cPlugin__OnDisconnect(a_Player,a_Reason);
tolua_pushboolean(tolua_S,(bool)tolua_ret);
tolua_pushcppstring(tolua_S,(const char*)a_Reason);
}
@ -10219,16 +10220,16 @@ public:
return ( bool ) cPlugin_NewLua:: OnCraftingNoRecipe(a_Player,a_Grid,a_Recipe);
};
};
bool OnDisconnect( const AString& a_Reason, cPlayer* a_Player) {
bool OnDisconnect( cPlayer* a_Player, const AString& a_Reason) {
if (push_method("OnDisconnect", tolua_AllToLua_cPlugin_OnDisconnect00)) {
tolua_pushcppstring(lua_state, (const char*)a_Reason);
tolua_pushusertype(lua_state, (void*)a_Player, "cPlayer");
tolua_pushcppstring(lua_state, (const char*)a_Reason);
ToluaBase::dbcall(lua_state, 3, 1);
bool tolua_ret = ( bool )tolua_toboolean(lua_state, -1, 0);
lua_pop(lua_state, 1);
return tolua_ret;
} else {
return ( bool ) cPlugin_NewLua:: OnDisconnect(a_Reason,a_Player);
return ( bool ) cPlugin_NewLua:: OnDisconnect(a_Player,a_Reason);
};
};
bool OnKilled( cPawn* a_Killed, cEntity* a_Killer) {
@ -10399,8 +10400,8 @@ public:
bool cPlugin_NewLua__OnCraftingNoRecipe( const cPlayer* a_Player, const cCraftingGrid* a_Grid, cCraftingRecipe* a_Recipe) {
return ( bool )cPlugin_NewLua::OnCraftingNoRecipe(a_Player,a_Grid,a_Recipe);
};
bool cPlugin_NewLua__OnDisconnect( const AString& a_Reason, cPlayer* a_Player) {
return ( bool )cPlugin_NewLua::OnDisconnect(a_Reason,a_Player);
bool cPlugin_NewLua__OnDisconnect( cPlayer* a_Player, const AString& a_Reason) {
return ( bool )cPlugin_NewLua::OnDisconnect(a_Player,a_Reason);
};
bool cPlugin_NewLua__OnKilled( cPawn* a_Killed, cEntity* a_Killer) {
return ( bool )cPlugin_NewLua::OnKilled(a_Killed,a_Killer);

View File

@ -1,6 +1,6 @@
/*
** Lua binding: AllToLua
** Generated automatically by tolua++-1.0.92 on 08/19/12 13:48:33.
** Generated automatically by tolua++-1.0.92 on 08/19/12 21:46:45.
*/
/* Exported function */

View File

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

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)
{
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 BroadcastEntityEquipment(const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item, const cClientHandle * a_Exclude = NULL);
void BroadcastRelEntMoveLook (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude = NULL);
void BroadcastRelEntMove (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude = NULL);
void BroadcastEntLook (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL);
void BroadcastEntHeadLook (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL);
void BroadcastBlockAction (int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, const cClientHandle * a_Exclude = NULL);
void BroadcastDestroyEntity(const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL);
void PositionToWorldPosition(int a_ChunkX, int a_ChunkY, int a_ChunkZ, int & a_X, int & a_Y, int & a_Z);
Vector3i PositionToWorldPosition( const Vector3i & a_InChunkPos ) { return PositionToWorldPosition( a_InChunkPos.x, a_InChunkPos.y, a_InChunkPos.z ); }

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)
{
// 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
void BroadcastEntityEquipment(const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item, const cClientHandle * a_Exclude = NULL);
/// Broadcasts a RelEntMoveLook packet to all clients in the chunk where a_Entity is
void BroadcastRelEntMoveLook(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude = NULL);
/// Broadcasts a RelEntMove packet to all clients in the chunk where a_Entity is
void BroadcastRelEntMove(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude = NULL);
/// Broadcasts a EntLook packet to all clients in the chunk where a_Entity is
void BroadcastEntLook(const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL);
/// Broadcasts a EntHeadLook packet to all clients in the chunk where a_Entity is
void BroadcastEntHeadLook(const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL);
/// Broadcasts a BlockAction packet to all clients who are in the specified chunk
void BroadcastBlockAction(int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, const cClientHandle * a_Exclude = NULL);
void BroadcastDestroyEntity(const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL);
/// a_Player rclked block entity at the coords specified, handle it
void UseBlockEntity(cPlayer * a_Player, int a_X, int a_Y, int a_Z);

View File

@ -39,40 +39,45 @@
#include "cAuthenticator.h"
#include "MersenneTwister.h"
#include "packets/cPacket_KeepAlive.h"
#include "packets/cPacket_Respawn.h"
#include "packets/cPacket_UpdateHealth.h"
#include "packets/cPacket_RelativeEntityMoveLook.h"
#include "packets/cPacket_Chat.h"
#include "packets/cPacket_Login.h"
#include "packets/cPacket_TimeUpdate.h"
#include "packets/cPacket_BlockDig.h"
#include "packets/cPacket_Handshake.h"
#include "packets/cPacket_13.h"
#include "packets/cPacket_ArmAnim.h"
#include "packets/cPacket_BlockChange.h"
#include "packets/cPacket_BlockDig.h"
#include "packets/cPacket_BlockPlace.h"
#include "packets/cPacket_Flying.h"
#include "packets/cPacket_Disconnect.h"
#include "packets/cPacket_PickupSpawn.h"
#include "packets/cPacket_ItemSwitch.h"
#include "packets/cPacket_EntityEquipment.h"
#include "packets/cPacket_Chat.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_PickupSpawn.h"
#include "packets/cPacket_Ping.h"
#include "packets/cPacket_Player.h"
#include "packets/cPacket_PreChunk.h"
#include "packets/cPacket_RelativeEntityMove.h"
#include "packets/cPacket_RelativeEntityMoveLook.h"
#include "packets/cPacket_Respawn.h"
#include "packets/cPacket_SpawnMob.h"
#include "packets/cPacket_TeleportEntity.h"
#include "packets/cPacket_TimeUpdate.h"
#include "packets/cPacket_UpdateHealth.h"
#include "packets/cPacket_UpdateSign.h"
#include "packets/cPacket_UseEntity.h"
#include "packets/cPacket_WholeInventory.h"
#include "packets/cPacket_WindowClick.h"
#include "packets/cPacket_WindowClose.h"
#include "packets/cPacket_WindowOpen.h"
#include "packets/cPacket_WholeInventory.h"
#include "packets/cPacket_13.h"
#include "packets/cPacket_UpdateSign.h"
#include "packets/cPacket_Ping.h"
#include "packets/cPacket_NamedEntitySpawn.h"
#include "packets/cPacket_MapChunk.h"
#include "packets/cPacket_PreChunk.h"
#include "packets/cPacket_InventorySlot.h"
// DEBUG:
#include "packets/cPacket_BlockChange.h"
#include "packets/cPacket_MultiBlock.h"
@ -500,6 +505,8 @@ void cClientHandle::HandlePacket(cPacket * a_Packet)
// Therefore I keep this function huge and untidy for the time being
// ( http://forum.mc-server.org/showthread.php?tid=524 )
// LOGD("Recv packet %02x", a_Packet->m_PacketID);
m_TimeLastPacket = cWorld::GetTime();
// LOG("Recv packet 0x%02x from client \"%s\" (\"%s\")", a_Packet->m_PacketID, m_Socket.GetIPString().c_str(), m_Username.c_str());
@ -678,11 +685,35 @@ void cClientHandle::HandlePacket(cPacket * a_Packet)
HandleWindowClick(wc->m_WindowID, wc->m_SlotNum, wc->m_IsRightClick, wc->m_IsShiftPressed, wc->m_HeldItem);
break;
}
case E_UPDATE_SIGN: HandleUpdateSign (reinterpret_cast<cPacket_UpdateSign *> (a_Packet)); break;
case E_USE_ENTITY: HandleUseEntity (reinterpret_cast<cPacket_UseEntity *> (a_Packet)); break;
case E_RESPAWN: HandleRespawn(); break;
case E_DISCONNECT: HandleDisconnect (reinterpret_cast<cPacket_Disconnect *> (a_Packet)); break;
case E_KEEP_ALIVE: HandleKeepAlive (reinterpret_cast<cPacket_KeepAlive *> (a_Packet)); break;
case E_UPDATE_SIGN:
{
cPacket_UpdateSign * us = reinterpret_cast<cPacket_UpdateSign *>(a_Packet);
HandleUpdateSign(us->m_BlockX, us->m_BlockY, us->m_BlockZ, us->m_Line1, us->m_Line2, us->m_Line3, us->m_Line4);
break;
}
case E_USE_ENTITY:
{
cPacket_UseEntity * ue = reinterpret_cast<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)
break;
} // case csPlaying
@ -797,7 +828,8 @@ void cClientHandle::HandleUnexpectedPacket(int a_PacketType)
void cClientHandle::HandleMoveLookConfirm(double a_PosX, double a_PosY, double a_PosZ)
{
Vector3d ReceivedPosition = Vector3d(a_PosX, a_PosY, a_PosZ);
// LOGD("Received MoveLook confirmation: {%0.2f %0.2f %0.2f}", a_PosX, a_PosY, a_PosZ);
// Test the distance between points with a small/large enough value instead of comparing directly. Floating point inaccuracies might screw stuff up
double Dist = (ReceivedPosition - m_ConfirmPosition).SqrLength();
if (Dist < 1.0)
@ -813,7 +845,7 @@ void cClientHandle::HandleMoveLookConfirm(double a_PosX, double a_PosY, double a
{
LOGWARNING("Player \"%s\" sent a weird position confirmation %.2f blocks away, retrying", m_Username.c_str(), Dist);
m_ConfirmPosition = m_Player->GetPosition();
Send(cPacket_PlayerMoveLook(m_Player));
SendPlayerMoveLook();
}
}
@ -840,8 +872,25 @@ void cClientHandle::HandleCreativeInventory(short a_SlotNum, const cItem & a_Hel
void cClientHandle::HandlePlayerPos(double a_PosX, double a_PosY, double a_PosZ, double a_Stance, bool a_IsOnGround)
{
// LOG("recv player pos: %0.2f %0.2f %0.2f", PacketData->m_PosX, PacketData->m_PosY, PacketData->m_PosZ);
m_Player->MoveTo(Vector3d(a_PosX, a_PosY, a_PosZ));
/*
// TODO: Invalid stance check
if ((a_PosY >= a_Stance) || (a_Stance > a_PosY + 1.65))
{
LOGD("Invalid stance");
SendPlayerMoveLook();
return;
}
*/
// LOGD("recv player pos: {%0.2f %0.2f %0.2f}, ground: %d", a_PosX, a_PosY, a_PosZ, a_IsOnGround ? 1 : 0);
Vector3d Pos(a_PosX, a_PosY, a_PosZ);
if ((m_Player->GetPosition() - Pos).SqrLength() > 100 * 100)
{
LOGD("Too far away (%0.2f), \"repairing\" the client", (m_Player->GetPosition() - Pos).Length());
SendPlayerMoveLook();
return;
}
m_Player->MoveTo(Pos);
m_Player->SetStance(a_Stance);
m_Player->SetTouchGround(a_IsOnGround);
}
@ -1086,6 +1135,16 @@ void cClientHandle::HandlePlayerLook(float a_Rotation, float a_Pitch, bool a_IsO
void cClientHandle::HandlePlayerMoveLook(double a_PosX, double a_PosY, double a_PosZ, double a_Stance, float a_Rotation, float a_Pitch, bool a_IsOnGround)
{
/*
// TODO: Invalid stance check
if ((a_PosY >= a_Stance) || (a_Stance > a_PosY + 1.65))
{
LOGD("Invalid stance");
SendPlayerMoveLook();
return;
}
*/
m_Player->MoveTo(Vector3d(a_PosX, a_PosY, a_PosZ));
m_Player->SetStance (a_Stance);
m_Player->SetTouchGround(a_IsOnGround);
@ -1148,20 +1207,25 @@ void cClientHandle::HandleWindowClick(char a_WindowID, short a_SlotNum, bool a_I
void cClientHandle::HandleUpdateSign(cPacket_UpdateSign * a_Packet)
void cClientHandle::HandleUpdateSign(
int a_BlockX, int a_BlockY, int a_BlockZ,
const AString & a_Line1, const AString & a_Line2,
const AString & a_Line3, const AString & a_Line4
)
{
cWorld * World = m_Player->GetWorld();
World->UpdateSign(a_Packet->m_PosX, a_Packet->m_PosY, a_Packet->m_PosZ, a_Packet->m_Line1, a_Packet->m_Line2, a_Packet->m_Line3, a_Packet->m_Line4);
World->UpdateSign(a_BlockX, a_BlockY, a_BlockZ, a_Line1, a_Line2, a_Line3, a_Line4);
}
void cClientHandle::HandleUseEntity(cPacket_UseEntity * a_Packet)
void cClientHandle::HandleUseEntity(int a_TargetEntityID, bool a_IsLeftClick)
{
if (!a_Packet->m_bLeftClick)
if (!a_IsLeftClick)
{
// TODO: we don't handle right-clicking yet
return;
}
@ -1169,9 +1233,9 @@ void cClientHandle::HandleUseEntity(cPacket_UseEntity * a_Packet)
{
virtual bool Item(cEntity * a_Entity) override
{
if( a_Entity->IsA("cPawn") )
if (a_Entity->IsA("cPawn"))
{
reinterpret_cast< cPawn* >( a_Entity )->TakeDamage(Damage, Instigator );
reinterpret_cast<cPawn *>(a_Entity)->TakeDamage(Damage, Instigator);
}
return true;
}
@ -1184,7 +1248,7 @@ void cClientHandle::HandleUseEntity(cPacket_UseEntity * a_Packet)
Callback.Instigator = m_Player;
cWorld * World = m_Player->GetWorld();
World->DoWithEntityByID(a_Packet->m_TargetID, Callback);
World->DoWithEntityByID(a_TargetEntityID, Callback);
}
@ -1200,13 +1264,14 @@ void cClientHandle::HandleRespawn(void)
void cClientHandle::HandleDisconnect(cPacket_Disconnect * a_Packet)
void cClientHandle::HandleDisconnect(const AString & a_Reason)
{
LOG("Received d/c packet from \"%s\"", m_Username.c_str());
if (!cRoot::Get()->GetPluginManager()->CallHook(cPluginManager::HOOK_DISCONNECT, 2, a_Packet->m_Reason.c_str(), m_Player))
LOGD("Received d/c packet from \"%s\" with reason \"%s\"", m_Username.c_str(), a_Reason.c_str());
if (!cRoot::Get()->GetPluginManager()->CallHookDisconnect(m_Player, a_Reason))
{
cPacket_Chat DisconnectMessage(m_Username + " disconnected: " + a_Packet->m_Reason);
cRoot::Get()->GetServer()->Broadcast(DisconnectMessage);
AString DisconnectMessage;
Printf(DisconnectMessage, "%s disconnected: %s", m_Username.c_str(), a_Reason.c_str());
m_Player->GetWorld()->BroadcastChat(DisconnectMessage, this);
}
Destroy();
}
@ -1215,9 +1280,9 @@ void cClientHandle::HandleDisconnect(cPacket_Disconnect * a_Packet)
void cClientHandle::HandleKeepAlive(cPacket_KeepAlive * a_Packet)
void cClientHandle::HandleKeepAlive(int a_KeepAliveID)
{
if (a_Packet->m_KeepAliveID == m_PingID)
if (a_KeepAliveID == m_PingID)
{
cTimer t1;
m_Ping = (short)((t1.GetNowTime() - m_PingStartTime) / 2);
@ -1225,6 +1290,9 @@ void cClientHandle::HandleKeepAlive(cPacket_KeepAlive * a_Packet)
}
bool cClientHandle::CheckBlockInteractionsRate(void)
{
ASSERT(m_Player != NULL);
@ -1543,6 +1611,174 @@ void cClientHandle::SendWholeInventory(const cWindow & a_Window)
void cClientHandle::SendTeleportEntity(const cEntity & a_Entity)
{
cPacket_TeleportEntity te(a_Entity);
Send(te);
}
void cClientHandle::SendPlayerListItem(const cPlayer & a_Player)
{
cPacket_PlayerListItem pli(a_Player.GetColor() + a_Player.GetName(), true, a_Player.GetClientHandle()->GetPing());
Send(pli);
}
void cClientHandle::SendPlayerPosition(void)
{
cPacket_PlayerPosition pp(m_Player);
Send(pp);
}
void cClientHandle::SendRelEntMoveLook(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ)
{
ASSERT(a_Entity.GetUniqueID() != m_Player->GetUniqueID()); // Must not send for self
cPacket_RelativeEntityMoveLook reml;
reml.m_UniqueID = a_Entity.GetUniqueID();
reml.m_MoveX = a_RelX;
reml.m_MoveY = a_RelY;
reml.m_MoveZ = a_RelZ;
reml.m_Yaw = (char)((a_Entity.GetRotation() / 360.f) * 256);
reml.m_Pitch = (char)((a_Entity.GetPitch() / 360.f) * 256);
Send(reml);
}
void cClientHandle::SendRelEntMove(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ)
{
ASSERT(a_Entity.GetUniqueID() != m_Player->GetUniqueID()); // Must not send for self
cPacket_RelativeEntityMove rem;
rem.m_UniqueID = a_Entity.GetUniqueID();
rem.m_MoveX = a_RelX;
rem.m_MoveY = a_RelY;
rem.m_MoveZ = a_RelZ;
Send(rem);
}
void cClientHandle::SendEntLook(const cEntity & a_Entity)
{
ASSERT(a_Entity.GetUniqueID() != m_Player->GetUniqueID()); // Must not send for self
cPacket_EntityLook el;
el.m_UniqueID = a_Entity.GetUniqueID();
el.m_Rotation = (char)((a_Entity.GetRotation() / 360.f) * 256);
el.m_Pitch = (char)((a_Entity.GetPitch() / 360.f) * 256);
Send(el);
}
void cClientHandle::SendEntHeadLook(const cEntity & a_Entity)
{
ASSERT(a_Entity.GetUniqueID() != m_Player->GetUniqueID()); // Must not send for self
cPacket_EntityHeadLook ehl(a_Entity);
Send(ehl);
}
void cClientHandle::SendBlockAction(int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2)
{
cPacket_BlockAction ba;
ba.m_BlockX = a_BlockX;
ba.m_BlockY = (short)a_BlockY;
ba.m_BlockZ = a_BlockZ;
ba.m_Byte1 = a_Byte1;
ba.m_Byte2 = a_Byte2;
Send(ba);
}
void cClientHandle::SendHealth(void)
{
cPacket_UpdateHealth Health;
Health.m_Health = m_Player->GetHealth();
Health.m_Food = m_Player->GetFoodLevel();
Health.m_Saturation = m_Player->GetFoodSaturationLevel();
Send(Health);
}
void cClientHandle::SendRespawn(void)
{
cPacket_Respawn Packet;
Packet.m_CreativeMode = (char)m_Player->GetGameMode(); // Set GameMode packet based on Player's GameMode;
Send(Packet);
}
void cClientHandle::SendGameMode(char a_GameMode)
{
cPacket_NewInvalidState nis;
nis.m_Reason = 3;
nis.m_GameMode = a_GameMode;
Send(nis);
}
void cClientHandle::SendDestroyEntity(const cEntity & a_Entity)
{
cPacket_DestroyEntity de;
de.m_UniqueID = a_Entity.GetUniqueID();
Send(de);
}
void cClientHandle::SendPlayerMoveLook(void)
{
cPacket_PlayerMoveLook pml(*m_Player);
/*
LOGD("Sending PlayerMoveLook: {%0.2f, %0.2f, %0.2f}, stance %0.2f, OnGround: %d",
m_Player->GetPosX(), m_Player->GetPosY(), m_Player->GetPosZ(), m_Player->GetStance(), m_Player->IsOnGround() ? 1 : 0
);
*/
Send(pml);
}
void cClientHandle::CheckIfWorldDownloaded(void)
{
if (m_State != csDownloadingWorld)
@ -1576,7 +1812,7 @@ void cClientHandle::SendConfirmPosition(void)
}
m_ConfirmPosition = m_Player->GetPosition();
Send(cPacket_PlayerMoveLook(m_Player));
SendPlayerMoveLook();
}
@ -1808,6 +2044,7 @@ void cClientHandle::GetOutgoingData(AString & a_Data)
while (!m_PendingNrmSendPackets.empty() && (Data.size() < 1000))
{
m_PendingNrmSendPackets.front()->Serialize(Data);
// LOGD("Sending packet 0x%02x", m_PendingNrmSendPackets.front()->m_PacketID);
delete m_PendingNrmSendPackets.front();
m_PendingNrmSendPackets.erase(m_PendingNrmSendPackets.begin());
}

View File

@ -15,30 +15,6 @@
#include "Vector3d.h"
#include "cSocketThreads.h"
#include "ChunkDef.h"
#include "packets/cPacket_KeepAlive.h"
#include "packets/cPacket_Player.h"
#include "packets/cPacket_Respawn.h"
#include "packets/cPacket_RelativeEntityMoveLook.h"
#include "packets/cPacket_Chat.h"
#include "packets/cPacket_Login.h"
#include "packets/cPacket_WindowClick.h"
#include "packets/cPacket_TimeUpdate.h"
#include "packets/cPacket_BlockDig.h"
#include "packets/cPacket_Handshake.h"
#include "packets/cPacket_ArmAnim.h"
#include "packets/cPacket_BlockPlace.h"
#include "packets/cPacket_Flying.h"
#include "packets/cPacket_Disconnect.h"
#include "packets/cPacket_PickupSpawn.h"
#include "packets/cPacket_ItemSwitch.h"
#include "packets/cPacket_EntityEquipment.h"
#include "packets/cPacket_CreativeInventoryAction.h"
#include "packets/cPacket_NewInvalidState.h"
#include "packets/cPacket_UseEntity.h"
#include "packets/cPacket_WindowClose.h"
#include "packets/cPacket_UpdateSign.h"
#include "packets/cPacket_Ping.h"
#include "ByteBuffer.h"
@ -114,6 +90,19 @@ public:
void SendWindowClose(char a_WindowID);
void SendWholeInventory(const cInventory & a_Inventory);
void SendWholeInventory(const cWindow & a_Window);
void SendTeleportEntity(const cEntity & a_Entity);
void SendPlayerListItem(const cPlayer & a_Player);
void SendPlayerPosition(void);
void SendRelEntMoveLook(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ);
void SendRelEntMove (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ);
void SendEntLook (const cEntity & a_Entity);
void SendEntHeadLook (const cEntity & a_Entity);
void SendBlockAction (int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2);
void SendHealth (void);
void SendRespawn(void);
void SendGameMode(char a_GameMode);
void SendDestroyEntity(const cEntity & a_Entity);
void SendPlayerMoveLook(void);
const AString & GetUsername(void) const; //tolua_export
@ -212,14 +201,20 @@ private:
void HandleSlotSelected (short a_SlotNum);
void HandleWindowClose (char a_WindowID);
void HandleWindowClick (char a_WindowID, short a_SlotNum, bool a_IsRightClick, bool a_IsShiftPressed, const cItem & a_HeldItem);
void HandleUpdateSign (cPacket_UpdateSign * a_Packet);
void HandleUseEntity (cPacket_UseEntity * a_Packet);
void HandleUpdateSign (
int a_BlockX, int a_BlockY, int a_BlockZ,
const AString & a_Line1, const AString & a_Line2,
const AString & a_Line3, const AString & a_Line4
);
void HandleUseEntity (int a_TargetEntityID, bool a_IsLeftClick);
void HandleRespawn (void);
void HandleDisconnect (cPacket_Disconnect * a_Packet);
void HandleKeepAlive (cPacket_KeepAlive * a_Packet);
void HandleDisconnect (const AString & a_Reason);
void HandleKeepAlive (int a_KeepAliveID);
/*
/// Handles rclk with a dye; returns true if the dye is to be be consumed
bool HandleDyes(cPacket_BlockPlace * a_Packet);
*/
/// Returns true if the rate block interactions is within a reasonable limit (bot protection)
bool CheckBlockInteractionsRate(void);

View File

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

View File

@ -41,7 +41,7 @@ public:
virtual bool ReachedDestination();
const char *GetState();
void SetState(const char* str);
void SetState(const AString & str);
static void ListMonsters();
virtual void CheckEventSeePlayer();
@ -93,7 +93,7 @@ protected:
float m_AttackRange;
float m_AttackInterval;
void AddRandomDropItem(cItems & a_Drops, unsigned int a_Min, unsigned int a_Max, ENUM_ITEM_ID a_Item, short a_ItemHealth = 0);
void AddRandomDropItem(cItems & a_Drops, unsigned int a_Min, unsigned int a_Max, short a_Item, short a_ItemHealth = 0);
}; //tolua_export

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 );
cPacket_TeleportEntity TeleportEntity( this );
cRoot::Get()->GetServer()->Broadcast( TeleportEntity );
GetWorld()->BroadcastTeleportEntity(*this);
}
@ -133,7 +131,7 @@ void cPawn::TeleportTo( const double & a_PosX, const double & a_PosY, const doub
void cPawn::Tick(float a_Dt)
{
CheckMetaDataBurn(); //Check to see if pawn should burn based on block they are on
CheckMetaDataBurn(); // Check to see if pawn should burn based on block they are on
if (GetMetaData() == BURNING)
{

View File

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

View File

@ -77,38 +77,32 @@ void cPiston::ExtendPiston( int pistx, int pisty, int pistz )
}
int oldx = pistx, oldy = pisty, oldz = pistz;
char currBlockMeta;
for (int i = dist+1; i>0; i--)
for (int i = dist + 1; i>0; i--)
{
AddDir( pistx, pisty, pistz, pistonMeta & 7, -1 )
currBlock = m_World->GetBlock( pistx, pisty, pistz );
currBlockMeta = m_World->GetBlockMeta( pistx, pisty, pistz );
m_World->SetBlock( oldx, oldy, oldz, currBlock, currBlockMeta );
AddDir(pistx, pisty, pistz, pistonMeta & 7, -1)
currBlock = m_World->GetBlock(pistx, pisty, pistz);
currBlockMeta = m_World->GetBlockMeta(pistx, pisty, pistz);
m_World->SetBlock( oldx, oldy, oldz, currBlock, currBlockMeta);
oldx = pistx;
oldy = pisty;
oldz = pistz;
}
cPacket_BlockAction Action;
Action.m_PosX = (int)pistx;
Action.m_PosY = (short)pisty;
Action.m_PosZ = (int)pistz;
Action.m_Byte1 = 0;
Action.m_Byte2 = pistonMeta;
m_World->BroadcastToChunkOfBlock(pistx, pisty, pistz, &Action);
m_World->BroadcastBlockAction(pistx, pisty, pistz, 0, pistonMeta);
m_World->FastSetBlock( pistx, pisty, pistz, pistonBlock, pistonMeta | 0x8 );
int extx = pistx;
int exty = pisty;
int extz = pistz;
AddDir( extx, exty, extz, pistonMeta&7, 1 )
AddDir(extx, exty, extz, pistonMeta & 7, 1)
m_World->SetBlock( extx, exty, extz, E_BLOCK_PISTON_EXTENSION, isSticky+pistonMeta&7 );
m_World->SetBlock(extx, exty, extz, E_BLOCK_PISTON_EXTENSION, isSticky + pistonMeta & 7);
if (recalc) {
if (recalc)
{
cRedstone Redstone(m_World);
Redstone.ChangeRedstone( extx, exty, extz, false ); //recalculate redstone around current device.
Redstone.ChangeRedstone( pistx, pisty, pistz, false ); //recalculate redstone around current device.
Redstone.ChangeRedstone(extx, exty, extz, false); // recalculate redstone around current device
Redstone.ChangeRedstone(pistx, pisty, pistz, false); // recalculate redstone around current device
}
}
}
@ -125,21 +119,13 @@ void cPiston::RetractPiston( int pistx, int pisty, int pistz )
{
return;
}
m_World->BroadcastBlockAction(pistx, pisty, pistz, 1, pistonMeta & ~(8));
m_World->FastSetBlock(pistx, pisty, pistz, pistonBlock, pistonMeta & ~(8));
//send blockaction packet
cPacket_BlockAction Action;
Action.m_PosX = (int)pistx;
Action.m_PosY = (short)pisty;
Action.m_PosZ = (int)pistz;
Action.m_Byte1 = 1;
Action.m_Byte2 = pistonMeta & ~(8);
m_World->BroadcastToChunkOfBlock(pistx, pisty, pistz, &Action );
m_World->FastSetBlock( pistx, pisty, pistz, pistonBlock, pistonMeta & ~(8) );
AddDir( pistx, pisty, pistz, pistonMeta & 7, 1 )
if ( m_World->GetBlock( pistx, pisty, pistz ) == E_BLOCK_PISTON_EXTENSION )
AddDir(pistx, pisty, pistz, pistonMeta & 7, 1)
if (m_World->GetBlock(pistx, pisty, pistz) == E_BLOCK_PISTON_EXTENSION)
{
if ( pistonBlock == E_BLOCK_STICKY_PISTON )
if (pistonBlock == E_BLOCK_STICKY_PISTON)
{
int tempx = pistx, tempy = pisty, tempz = pistz;
AddDir( tempx, tempy, tempz, pistonMeta & 7, 1 )

View File

@ -22,17 +22,6 @@
#include "MersenneTwister.h"
#include "packets/cPacket_NamedEntitySpawn.h"
#include "packets/cPacket_EntityLook.h"
#include "packets/cPacket_TeleportEntity.h"
#include "packets/cPacket_RelativeEntityMove.h"
#include "packets/cPacket_RelativeEntityMoveLook.h"
#include "packets/cPacket_UpdateHealth.h"
#include "packets/cPacket_Respawn.h"
#include "packets/cPacket_DestroyEntity.h"
#include "packets/cPacket_Metadata.h"
#include "packets/cPacket_Chat.h"
#include "packets/cPacket_NewInvalidState.h"
#include "packets/cPacket_BlockAction.h"
#include "Vector3d.h"
#include "Vector3f.h"
@ -105,6 +94,8 @@ cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName)
a_PlayerName.c_str(), m_Pos.x, m_Pos.y, m_Pos.z
);
}
m_LastGroundHeight = (float)(m_Pos.y);
m_Stance = m_Pos.y + 1.62;
}
@ -193,13 +184,11 @@ void cPlayer::Tick(float a_Dt)
if (m_bDirtyOrientation && !m_bDirtyPosition)
{
cPacket_EntityLook EntityLook(*this);
m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, EntityLook, m_ClientHandle );
cPacket_EntityHeadLook EntityHeadLook(*this);
m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, EntityHeadLook, m_ClientHandle);
m_World->BroadcastEntLook(*this, m_ClientHandle);
m_World->BroadcastEntHeadLook(*this, m_ClientHandle);
m_bDirtyOrientation = false;
}
else if (m_bDirtyPosition )
else if (m_bDirtyPosition)
{
cRoot::Get()->GetPluginManager()->CallHook( cPluginManager::E_PLUGIN_PLAYER_MOVE, 1, this );
@ -212,32 +201,21 @@ void cPlayer::Tick(float a_Dt)
(cWorld::GetTime() - m_TimeLastTeleportPacket > 2 ) // Send an absolute position every 2 seconds
)
{
//LOG("Teleported %f", sqrtf(SqrDist) );
cPacket_TeleportEntity TeleportEntity( this );
m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, TeleportEntity, m_ClientHandle);
// LOG("Teleported %f", sqrtf(SqrDist) );
m_World->BroadcastTeleportEntity(*this, m_ClientHandle);
m_TimeLastTeleportPacket = cWorld::GetTime();
}
else
{ // Relative move sucks balls! It's always wrong wtf!
if( m_bDirtyOrientation )
{
// Relative move sucks balls! It's always wrong wtf!
if (m_bDirtyOrientation)
{
cPacket_RelativeEntityMoveLook RelativeEntityMoveLook;
RelativeEntityMoveLook.m_UniqueID = GetUniqueID();
RelativeEntityMoveLook.m_MoveX = (char)(DiffX*32);
RelativeEntityMoveLook.m_MoveY = (char)(DiffY*32);
RelativeEntityMoveLook.m_MoveZ = (char)(DiffZ*32);
RelativeEntityMoveLook.m_Yaw = (char)((GetRotation()/360.f)*256);
RelativeEntityMoveLook.m_Pitch = (char)((GetPitch()/360.f)*256);
m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, RelativeEntityMoveLook, m_ClientHandle );
m_World->BroadcastRelEntMoveLook(*this, (char)(DiffX * 32), (char)(DiffY * 32), (char)(DiffZ * 32), m_ClientHandle);
m_bDirtyOrientation = false;
}
else
{
cPacket_RelativeEntityMove RelativeEntityMove;
RelativeEntityMove.m_UniqueID = GetUniqueID();
RelativeEntityMove.m_MoveX = (char)(DiffX*32);
RelativeEntityMove.m_MoveY = (char)(DiffY*32);
RelativeEntityMove.m_MoveZ = (char)(DiffZ*32);
m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, RelativeEntityMove, m_ClientHandle );
m_World->BroadcastRelEntMove(*this, (char)(DiffX * 32), (char)(DiffY * 32), (char)(DiffZ * 32), m_ClientHandle);
}
}
m_LastPosX = GetPosX();
@ -266,15 +244,19 @@ void cPlayer::Tick(float a_Dt)
}
}
//TODO: Increase Exhaustion level http://www.minecraftwiki.net/wiki/Hunger#Exhaustion_level_increase
if(m_FoodExhaustionLevel >= 4.f)
// TODO: Increase Exhaustion level http://www.minecraftwiki.net/wiki/Hunger#Exhaustion_level_increase
if (m_FoodExhaustionLevel >= 4.f)
{
m_FoodExhaustionLevel -= 4.f;
if(m_FoodSaturationLevel >= 1.f)
if (m_FoodSaturationLevel >= 1.f)
{
m_FoodSaturationLevel--;
}
else
{
m_FoodLevel = MAX(m_FoodLevel -1, 0);
}
SendHealth();
}
@ -293,40 +275,43 @@ void cPlayer::Tick(float a_Dt)
void cPlayer::SetTouchGround( bool a_bTouchGround )
void cPlayer::SetTouchGround(bool a_bTouchGround)
{
m_bTouchGround = a_bTouchGround;
if( !m_bTouchGround )
if (!m_bTouchGround)
{
cWorld* World = GetWorld();
char BlockID = World->GetBlock( float2int(m_Pos.x), float2int(m_Pos.y), float2int(m_Pos.z) );
if( BlockID != E_BLOCK_AIR )
{
// LOGD("TouchGround set to true by server");
m_bTouchGround = true;
}
if( BlockID == E_BLOCK_WATER || BlockID == E_BLOCK_STATIONARY_WATER || BlockID == E_BLOCK_LADDER || BlockID == E_BLOCK_TORCH )
{
// LOGD("Water / Ladder / Torch");
m_LastGroundHeight = (float)m_Pos.y;
}
}
if( m_bTouchGround )
if (m_bTouchGround)
{
float Dist = (float)(m_LastGroundHeight - m_Pos.y);
if( Dist > 4.f ) // Player dropped
int Damage = (int)(Dist - 4.f);
if (Damage > 0)
{
int Damage = (int)(Dist - 4.f);
if( Damage > 0 )
{
TakeDamage( Damage, 0 );
}
TakeDamage(Damage, 0);
}
m_LastGroundHeight = (float)m_Pos.y;
}
}
void cPlayer::Heal( int a_Health )
{
if( m_Health < GetMaxHealth() )
@ -338,6 +323,10 @@ void cPlayer::Heal( int a_Health )
}
}
bool cPlayer::Feed(short a_Food, float a_Saturation)
{
if (m_FoodLevel >= GetMaxFoodLevel())
@ -352,19 +341,25 @@ bool cPlayer::Feed(short a_Food, float a_Saturation)
return true;
}
void cPlayer::SendHealth()
{
cPacket_UpdateHealth Health;
Health.m_Health = GetHealth();
Health.m_Food = GetFoodLevel();
Health.m_Saturation = GetFoodSaturationLevel();
if(m_ClientHandle != 0)
m_ClientHandle->Send( Health );
if (m_ClientHandle != NULL)
{
m_ClientHandle->SendHealth();
}
}
void cPlayer::TakeDamage( int a_Damage, cEntity* a_Instigator )
{
if(m_GameMode != eGameMode_Creative)
if (m_GameMode != eGameMode_Creative)
{
cPawn::TakeDamage( a_Damage, a_Instigator );
@ -412,23 +407,20 @@ void cPlayer::Respawn()
{
m_Health = GetMaxHealth();
// Create Respawn player packet
cPacket_Respawn Packet;
//Set Gamemode for packet by looking at world's gamemode (Need to check players gamemode.)
//Packet.m_CreativeMode = (char)GetWorld()->GetGameMode();
Packet.m_CreativeMode = (char)m_GameMode; //Set GameMode packet based on Player's GameMode;
//Send Packet
m_ClientHandle->Send( Packet );
m_ClientHandle->SendRespawn();
//Set non Burning
// Set non Burning
SetMetaData(NORMAL);
TeleportTo( GetWorld()->GetSpawnX(), GetWorld()->GetSpawnY(), GetWorld()->GetSpawnZ() );
TeleportTo(GetWorld()->GetSpawnX(), GetWorld()->GetSpawnY(), GetWorld()->GetSpawnZ());
SetVisible( true );
SetVisible(true);
}
double cPlayer::GetEyeHeight()
{
return m_Stance;
@ -486,14 +478,9 @@ void cPlayer::CloseWindow(char a_WindowType)
// FIXME: If the player entity is destroyed while having a chest window open, the chest will not close
if ((a_WindowType == 1) && (m_CurrentWindow->GetWindowType() == cWindow::Chest))
{
// Chest
cPacket_BlockAction ChestClose;
int y = 0;
m_CurrentWindow->GetOwner()->GetBlockPos(ChestClose.m_PosX, y, ChestClose.m_PosZ);
ChestClose.m_PosY = (short)y;
ChestClose.m_Byte1 = 1; // Unused, always 1
ChestClose.m_Byte2 = 0; // 0 = closed
m_World->Broadcast(ChestClose);
int x, y, z;
m_CurrentWindow->GetOwner()->GetBlockPos(x, y, z);
m_World->BroadcastBlockAction(x, y, z, 1, 0);
}
m_CurrentWindow->Close( *this );
@ -526,28 +513,33 @@ void cPlayer::SetLastBlockActionCnt( int a_LastBlockActionCnt )
void cPlayer::SetGameMode( eGameMode a_GameMode )
void cPlayer::SetGameMode(eGameMode a_GameMode)
{
if ( (a_GameMode < 2) && (a_GameMode >= 0) )
if ((a_GameMode >= 2) || (a_GameMode < 0))
{
if (m_GameMode != a_GameMode)
{
cInventory *OldInventory = 0;
if(m_GameMode == eGameMode_Survival)
OldInventory = m_Inventory;
else
OldInventory = m_CreativeInventory;
m_GameMode = a_GameMode;
cPacket_NewInvalidState GameModePacket;
GameModePacket.m_Reason = 3; //GameModeChange
GameModePacket.m_GameMode = (char)a_GameMode; //GameModeChange
m_ClientHandle->Send ( GameModePacket );
GetInventory().SendWholeInventory(m_ClientHandle);
GetInventory().SetEquippedSlot(OldInventory->GetEquippedSlot());
}
LOGWARNING("%s: Setting invalid gamemode: %d", GetName().c_str(), a_GameMode);
return;
}
if (m_GameMode == a_GameMode)
{
// Gamemode already set
return;
}
short OldSlotNum = 0;
if (m_GameMode == eGameMode_Survival)
{
OldSlotNum = m_Inventory->GetEquippedSlot();
}
else
{
OldSlotNum = m_CreativeInventory->GetEquippedSlot();
}
m_GameMode = a_GameMode;
m_ClientHandle->SendGameMode(a_GameMode);
GetInventory().SendWholeInventory(m_ClientHandle);
GetInventory().SetEquippedSlot(OldSlotNum);
}
@ -563,7 +555,7 @@ void cPlayer::LoginSetGameMode( eGameMode a_GameMode )
void cPlayer::SetIP( std::string a_IP )
void cPlayer::SetIP(const AString & a_IP)
{
m_IP = a_IP;
}
@ -572,26 +564,21 @@ void cPlayer::SetIP( std::string a_IP )
void cPlayer::SendMessage( const char* a_Message )
void cPlayer::SendMessage(const AString & a_Message)
{
m_ClientHandle->Send( cPacket_Chat( a_Message ) );
m_ClientHandle->SendChat(a_Message);
}
void cPlayer::TeleportTo( const double & a_PosX, const double & a_PosY, const double & a_PosZ )
void cPlayer::TeleportTo(const double & a_PosX, const double & a_PosY, const double & a_PosZ)
{
SetPosition( a_PosX, a_PosY, a_PosZ );
cPacket_TeleportEntity TeleportEntity( this );
cRoot::Get()->GetServer()->Broadcast( TeleportEntity, GetClientHandle() );
cPacket_PlayerPosition PlayerPosition( this );
m_ClientHandle->Send( PlayerPosition );
m_World->BroadcastTeleportEntity(*this, GetClientHandle());
m_ClientHandle->SendPlayerMoveLook();
}
@ -604,24 +591,24 @@ void cPlayer::MoveTo( const Vector3d & a_NewPos )
// TODO: Official server refuses position packets too far away from each other, kicking "hacked" clients; we should, too
SetPosition( a_NewPos );
SetStance(a_NewPos.y + 1.62);
}
void cPlayer::SetVisible( bool a_bVisible )
void cPlayer::SetVisible(bool a_bVisible)
{
if (a_bVisible && !m_bVisible) // Make visible
{
m_bVisible = true;
SpawnOn( NULL ); // Spawn on everybody
SpawnOn(NULL); // Spawn on all clients
}
if (!a_bVisible && m_bVisible)
{
m_bVisible = false;
cPacket_DestroyEntity DestroyEntity( this );
m_World->BroadcastToChunk(m_ChunkX, m_ChunkY, m_ChunkZ, DestroyEntity ); // Destroy on all clients
m_World->BroadcastDestroyEntity(*this, m_ClientHandle); // Destroy on all clients
}
}

View File

@ -35,12 +35,13 @@ public:
virtual void Tick(float a_Dt) override;
void SetTouchGround( bool a_bTouchGround );
inline void SetStance( const double & a_Stance ) { m_Stance = a_Stance; }
inline void SetStance( const double a_Stance ) { m_Stance = a_Stance; }
double GetEyeHeight(); //tolua_export
Vector3d GetEyePosition(); //tolua_export
OBSOLETE
inline bool GetFlying() { return m_bTouchGround; } //tolua_export
inline bool IsOnGround(void) const {return m_bTouchGround; } // tolua_export
inline const double & GetStance() { return m_Stance; } //tolua_export
inline const double GetStance(void) const { return m_Pos.y + 1.62; } //tolua_export // TODO: Proper stance when crouching etc.
inline cInventory & GetInventory() { if(GetGameMode() == eGameMode_Survival) return *m_Inventory; else return *m_CreativeInventory; } //tolua_export
virtual void TeleportTo( const double & a_PosX, const double & a_PosY, const double & a_PosZ ); //tolua_export
@ -53,7 +54,7 @@ public:
void SetLastBlockActionTime(); //tolua_export
void SetGameMode( eGameMode a_GameMode ); //tolua_export
void LoginSetGameMode( eGameMode a_GameMode );
void SetIP( std::string a_IP );
void SetIP(const AString & a_IP);
// Tries to move to a new position, with collision checks and stuff
virtual void MoveTo( const Vector3d & a_NewPos ); //tolua_export
@ -62,9 +63,9 @@ public:
void OpenWindow( cWindow* a_Window );
void CloseWindow(char a_WindowType);
cClientHandle * GetClientHandle() { return m_ClientHandle; } //tolua_export
cClientHandle * GetClientHandle(void) const { return m_ClientHandle; } //tolua_export
void SendMessage( const char* a_Message ); //tolua_export
void SendMessage(const AString & a_Message); //tolua_export
const AString & GetName(void) const { return m_PlayerName; } //tolua_export
void SetName(const AString & a_Name) { m_PlayerName = a_Name; } //tolua_export

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_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 OnCollectItem (cPickup* a_Pickup, cPlayer* a_Player );
virtual bool OnCraftingNoRecipe(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe);
virtual bool OnDisconnect (const AString & a_Reason, cPlayer * a_Player );
virtual bool OnKilled (cPawn* a_Killed, cEntity* a_Killer );
virtual bool OnDisconnect (cPlayer * a_Player, const AString & a_Reason);
virtual bool OnKilled (cPawn * a_Killed, cEntity* a_Killer );
virtual bool OnLogin (cClientHandle * a_Client, int a_ProtocolVersion, const AString & a_Username);
virtual bool OnPlayerJoin (cPlayer* a_Player );
virtual void OnPlayerMove (cPlayer* a_Player );

View File

@ -214,22 +214,6 @@ bool cPluginManager::CallHook(PluginHook a_Hook, unsigned int a_NumArgs, ...)
break;
}
case HOOK_DISCONNECT:
{
if( a_NumArgs != 2 ) break;
va_list argptr;
va_start( argptr, a_NumArgs);
const char* Reason = va_arg(argptr, const char* );
cPlayer* Player = va_arg(argptr, cPlayer* );
va_end (argptr);
for( PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr )
{
if( (*itr)->OnDisconnect( Reason, Player ) )
return true;
}
break;
}
case HOOK_PLAYER_JOIN:
{
if( a_NumArgs != 1 ) break;
@ -509,6 +493,27 @@ bool cPluginManager::CallHookCraftingNoRecipe(const cPlayer * a_Player, const cC
bool cPluginManager::CallHookDisconnect(cPlayer * a_Player, const AString & a_Reason)
{
HookMap::iterator Plugins = m_Hooks.find(HOOK_DISCONNECT);
if (Plugins == m_Hooks.end())
{
return false;
}
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnDisconnect(a_Player, a_Reason))
{
return true;
}
}
return false;
}
bool cPluginManager::CallHookPostCrafting(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe)
{
HookMap::iterator Plugins = m_Hooks.find(HOOK_POST_CRAFTING);

View File

@ -103,6 +103,7 @@ public: //tolua_export
bool CallHookChat (cPlayer * a_Player, const AString & a_Message);
bool CallHookChunkGenerating (cWorld * a_World, int a_ChunkX, int a_ChunkZ, cLuaChunk * a_Chunk);
bool CallHookCraftingNoRecipe(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe);
bool CallHookDisconnect (cPlayer * a_Player, const AString & a_Reason);
bool CallHookLogin (cClientHandle * a_Client, int a_ProtocolVersion, const AString & a_Username);
bool CallHookPostCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe);
bool CallHookPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe);

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

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 OnCollectItem (cPickup* a_Pickup, cPlayer* a_Player ) override;
virtual bool OnCraftingNoRecipe(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) override;
virtual bool OnDisconnect (const AString & a_Reason, cPlayer * a_Player ) override;
virtual bool OnDisconnect (cPlayer * a_Player, const AString & a_Reason) override;
virtual bool OnKilled (cPawn* a_Killed, cEntity* a_Killer ) override;
virtual bool OnLogin (cClientHandle * a_Client, int a_ProtocolVersion, const AString & a_Username) override;
virtual bool OnPlayerJoin (cPlayer* a_Player ) override;

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 );
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 OnCollectItem (cPickup* a_Pickup, cPlayer* a_Player ) override;
virtual bool OnCraftingNoRecipe(const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) override;
virtual bool OnDisconnect (const AString & a_Reason, cPlayer * a_Player ) override;
virtual bool OnDisconnect (cPlayer * a_Player, const AString & a_Reason) override;
virtual bool OnKilled (cPawn* a_Killed, cEntity* a_Killer ) override;
virtual bool OnLogin (cClientHandle * a_Client, int a_ProtocolVersion, const AString & a_Username) override;
virtual bool OnPlayerJoin (cPlayer* a_Player ) override;

View File

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

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)
{
m_ChunkMap->MarkChunkDirty (a_ChunkX, a_ChunkY, a_ChunkZ);
@ -1561,13 +1633,12 @@ void cWorld::SendPlayerList(cPlayer * a_DestPlayer)
{
// Sends the playerlist to a_DestPlayer
cCSLock Lock(m_CSPlayers);
for ( cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
for (cPlayerList::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
{
cClientHandle * ch = (*itr)->GetClientHandle();
if ((ch != NULL) && !ch->IsDestroyed())
{
cPacket_PlayerListItem PlayerListItem((*itr)->GetColor() + (*itr)->GetName(), true, (*itr)->GetClientHandle()->GetPing());
a_DestPlayer->GetClientHandle()->Send( PlayerListItem );
a_DestPlayer->GetClientHandle()->SendPlayerListItem(*(*itr));
}
}
}

View File

@ -81,6 +81,13 @@ public:
void BroadcastChat(const AString & a_Message, const cClientHandle * a_Exclude = NULL);
void BroadcastPlayerAnimation(const cPlayer & a_Player, char a_Animation, const cClientHandle * a_Exclude = NULL);
void BroadcastEntityEquipment(const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item, const cClientHandle * a_Exclude = NULL);
void BroadcastTeleportEntity (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL);
void BroadcastRelEntMoveLook (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude = NULL);
void BroadcastRelEntMove (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude = NULL);
void BroadcastEntLook (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL);
void BroadcastEntHeadLook (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL);
void BroadcastBlockAction (int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, const cClientHandle * a_Exclude = NULL);
void BroadcastDestroyEntity (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL);
void MarkChunkDirty (int a_ChunkX, int a_ChunkY, int a_ChunkZ);
void MarkChunkSaving(int a_ChunkX, int a_ChunkY, int a_ChunkZ);

View File

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

View File

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

View File

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

View File

@ -12,14 +12,12 @@ class cPacket_KeepAlive : public cPacket
public:
cPacket_KeepAlive() { m_PacketID = E_KEEP_ALIVE; }
cPacket_KeepAlive(int a_PingID) { m_KeepAliveID = a_PingID; }
virtual cPacket* Clone() const { return new cPacket_KeepAlive(*this); }
virtual cPacket * Clone() const { return new cPacket_KeepAlive(*this); }
virtual int Parse(cByteBuffer & a_Buffer) override;
virtual int Parse(cByteBuffer & a_Buffer) override;
virtual void Serialize(AString & a_Data) const override;
int m_KeepAliveID;
static const unsigned int c_Size = 1 + 4;
};

View File

@ -143,16 +143,16 @@ void cPacket_PlayerLook::Serialize(AString & a_Data) const
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cPacket_PlayerMoveLook:
cPacket_PlayerMoveLook::cPacket_PlayerMoveLook( cPlayer* a_Player )
cPacket_PlayerMoveLook::cPacket_PlayerMoveLook(const cPlayer & a_Player)
{
m_PacketID = E_PLAYERMOVELOOK;
m_PosX = a_Player->GetPosX();
m_PosY = a_Player->GetPosY() + 1.65;
m_PosZ = a_Player->GetPosZ();
m_Stance = a_Player->GetStance();
m_Rotation = a_Player->GetRotation();
m_Pitch = a_Player->GetPitch();
m_IsOnGround = a_Player->IsOnGround();
m_PosX = a_Player.GetPosX();
m_PosY = a_Player.GetPosY() + 0.03; // Add a small amount so that the player doesn't start inside a block
m_PosZ = a_Player.GetPosZ();
m_Stance = a_Player.GetStance() + 0.03; // Add a small amount so that the player doesn't start inside a block
m_Rotation = a_Player.GetRotation();
m_Pitch = a_Player.GetPitch();
m_IsOnGround = a_Player.IsOnGround();
}
@ -161,6 +161,8 @@ cPacket_PlayerMoveLook::cPacket_PlayerMoveLook( cPlayer* a_Player )
int cPacket_PlayerMoveLook::Parse(cByteBuffer & a_Buffer)
{
// NOTE that Stance and Y are swapped when sent C->S vs S->C
// This is the C->S case:
int TotalBytes = 0;
HANDLE_PACKET_READ(ReadBEDouble, m_PosX, TotalBytes);
HANDLE_PACKET_READ(ReadBEDouble, m_PosY, TotalBytes);
@ -169,6 +171,7 @@ int cPacket_PlayerMoveLook::Parse(cByteBuffer & a_Buffer)
HANDLE_PACKET_READ(ReadBEFloat, m_Rotation, TotalBytes);
HANDLE_PACKET_READ(ReadBEFloat, m_Pitch, TotalBytes);
HANDLE_PACKET_READ(ReadBool, m_IsOnGround, TotalBytes);
// LOGD("Recv PML: {%0.2f, %0.2f, %0.2f}, Stance %0.2f, Gnd: %d", m_PosX, m_PosY, m_PosZ, m_Stance, m_IsOnGround ? 1 : 0);
return TotalBytes;
}
@ -178,10 +181,14 @@ int cPacket_PlayerMoveLook::Parse(cByteBuffer & a_Buffer)
void cPacket_PlayerMoveLook::Serialize(AString & a_Data) const
{
// NOTE that Stance and Y are swapped when sent C->S vs S->C
// This is the S->C case:
// LOGD("Send PML: {%0.2f, %0.2f, %0.2f}, Stance: %0.2f, Gnd: %d", m_PosX, m_PosY, m_PosZ, m_Stance, m_IsOnGround ? 1 : 0);
AppendByte (a_Data, m_PacketID);
AppendDouble(a_Data, m_PosX);
AppendDouble(a_Data, m_PosY);
AppendDouble(a_Data, m_Stance);
AppendDouble(a_Data, m_PosY);
AppendDouble(a_Data, m_PosZ);
AppendFloat (a_Data, m_Rotation);
AppendFloat (a_Data, m_Pitch);
@ -200,7 +207,7 @@ cPacket_PlayerPosition::cPacket_PlayerPosition(cPlayer * a_Player)
m_PacketID = E_PLAYERPOS;
m_PosX = a_Player->GetPosX();
m_PosY = a_Player->GetPosY() + 1.65;
m_PosY = a_Player->GetPosY();
m_PosZ = a_Player->GetPosZ();
m_Stance = a_Player->GetStance();
m_IsOnGround = a_Player->IsOnGround();
@ -218,6 +225,7 @@ int cPacket_PlayerPosition::Parse(cByteBuffer & a_Buffer)
HANDLE_PACKET_READ(ReadBEDouble, m_Stance, TotalBytes);
HANDLE_PACKET_READ(ReadBEDouble, m_PosZ, TotalBytes);
HANDLE_PACKET_READ(ReadBool, m_IsOnGround, TotalBytes);
// LOGD("Recv PlayerPos: {%0.2f %0.2f %0.2f}, Stance %0.2f, Gnd: %d", m_PosX, m_PosY, m_PosZ, m_Stance, m_IsOnGround ? 1 : 0);
return TotalBytes;
}
@ -227,12 +235,17 @@ int cPacket_PlayerPosition::Parse(cByteBuffer & a_Buffer)
void cPacket_PlayerPosition::Serialize(AString & a_Data) const
{
LOGD("Ignore send PlayerPos");
/*
LOGD("Send PlayerPos: {%0.2f %0.2f %0.2f}, Stance %0.2f, Gnd: %d", m_PosX, m_PosY, m_PosZ, m_Stance, m_IsOnGround ? 1 : 0);
// _X: This should not get sent to the client at all - http://wiki.vg/wiki/index.php?title=Protocol&oldid=2513#Player_Position_.280x0B.29
AppendByte (a_Data, m_PacketID);
AppendDouble (a_Data, m_PosX);
AppendDouble (a_Data, m_PosY);
AppendDouble (a_Data, m_Stance);
AppendDouble (a_Data, m_PosZ);
AppendBool (a_Data, m_IsOnGround);
*/
}

View File

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

View File

@ -9,26 +9,29 @@
class cPacket_Respawn : public cPacket
class cPacket_Respawn :
public cPacket
{
public:
cPacket_Respawn()
: m_Dimension( 0 )
, m_Difficulty( 0 )
, m_CreativeMode( 0 )
, m_WorldHeight( 0 )
: m_Dimension(0)
, m_Difficulty(0)
, m_CreativeMode(0)
, m_WorldHeight(256)
, m_LevelType( cPacket_Login::LEVEL_TYPE_DEFAULT )
{ m_PacketID = E_RESPAWN; }
{
m_PacketID = E_RESPAWN;
}
virtual cPacket* Clone() const { return new cPacket_Respawn( *this ); }
virtual cPacket * Clone() const { return new cPacket_Respawn( *this ); }
virtual int Parse(cByteBuffer & a_Buffer) override;
virtual int Parse(cByteBuffer & a_Buffer) override;
virtual void Serialize(AString & a_Data) const override;
int m_Dimension;
char m_Difficulty;
char m_CreativeMode;
short m_WorldHeight;
int m_Dimension;
char m_Difficulty;
char m_CreativeMode;
short m_WorldHeight;
AString m_LevelType;
};

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

View File

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

View File

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

View File

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

View File

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

View File

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