1
0

Put in some sanity checks to ensure players don't interact with blocks too quickly. Changed gamemode to be player based. (MCServer crashes when picking up an item. Need to find and fix bug.)

git-svn-id: http://mc-server.googlecode.com/svn/trunk@38 0a769ca7-a7f5-676a-18bf-c427514a06d6
This commit is contained in:
admin@omencraft.com 2011-11-01 20:09:13 +00:00
parent 01246b27b0
commit f849b664e0
3 changed files with 56 additions and 14 deletions

View File

@ -471,6 +471,14 @@ void cClientHandle::HandlePacket( cPacket* a_Packet )
break; break;
case E_BLOCK_DIG: case E_BLOCK_DIG:
{ {
LOG("TimeP: %f", m_Player->GetLastBlockActionTime() );
LOG("TimeN: %f", cRoot::Get()->GetWorld()->GetTime() );
if ( cRoot::Get()->GetWorld()->GetTime() - m_Player->GetLastBlockActionTime() < 0.1 ) { //only allow block interactions every 0.1 seconds
LOGWARN("Player %s tried to interact with a block too quickly! (could indicate bot)", GetUsername() );
m_Player->SetLastBlockActionTime(); //Player tried to interact with a block. Reset last block interation time.
break;
}
m_Player->SetLastBlockActionTime(); //Player tried to interact with a block. Reset last block interation time.
cPacket_BlockDig* PacketData = reinterpret_cast<cPacket_BlockDig*>(a_Packet); cPacket_BlockDig* PacketData = reinterpret_cast<cPacket_BlockDig*>(a_Packet);
LOG("OnBlockDig: %i %i %i Dir: %i Stat: %i", PacketData->m_PosX, PacketData->m_PosY, PacketData->m_PosZ, PacketData->m_Direction, PacketData->m_Status ); LOG("OnBlockDig: %i %i %i Dir: %i Stat: %i", PacketData->m_PosX, PacketData->m_PosY, PacketData->m_PosZ, PacketData->m_Direction, PacketData->m_Status );
if( PacketData->m_Status == 0x04 ) // Drop block if( PacketData->m_Status == 0x04 ) // Drop block
@ -482,10 +490,10 @@ void cClientHandle::HandlePacket( cPacket* a_Packet )
cWorld* World = m_Player->GetWorld(); cWorld* World = m_Player->GetWorld();
char OldBlock = World->GetBlock(PacketData->m_PosX, PacketData->m_PosY, PacketData->m_PosZ); char OldBlock = World->GetBlock(PacketData->m_PosX, PacketData->m_PosY, PacketData->m_PosZ);
char MetaData = World->GetBlockMeta(PacketData->m_PosX, PacketData->m_PosY, PacketData->m_PosZ); char MetaData = World->GetBlockMeta(PacketData->m_PosX, PacketData->m_PosY, PacketData->m_PosZ);
bool bBroken = (PacketData->m_Status == 0x02) || g_BlockOneHitDig[(int)OldBlock] || ( (PacketData->m_Status == 0x00) && (World->GetGameMode() == 1) ); //need to change to check for client's gamemode. bool bBroken = (PacketData->m_Status == 0x02) || g_BlockOneHitDig[(int)OldBlock] || ( (PacketData->m_Status == 0x00) && (m_Player->GetGameMode() == 1) );
cItem PickupItem; cItem PickupItem;
if( bBroken && !(World->GetGameMode() == 1) ) // broken if( bBroken && !(m_Player->GetGameMode() == 1) ) // broken
{ {
ENUM_ITEM_ID PickupID = cBlockToPickup::ToPickup( (ENUM_BLOCK_ID)OldBlock, m_Player->GetInventory().GetEquippedItem().m_ItemID ); ENUM_ITEM_ID PickupID = cBlockToPickup::ToPickup( (ENUM_BLOCK_ID)OldBlock, m_Player->GetInventory().GetEquippedItem().m_ItemID );
PickupItem.m_ItemID = PickupID; PickupItem.m_ItemID = PickupID;
@ -579,10 +587,18 @@ void cClientHandle::HandlePacket( cPacket* a_Packet )
break; break;
case E_BLOCK_PLACE: case E_BLOCK_PLACE:
{ {
LOG("TimeP: %f", m_Player->GetLastBlockActionTime() );
LOG("TimeN: %f", cRoot::Get()->GetWorld()->GetTime() );
if ( cRoot::Get()->GetWorld()->GetTime() - m_Player->GetLastBlockActionTime() < 0.1 ) { //only allow block interactions every 0.1 seconds
LOGWARN("Player %s tried to interact with a block too quickly! (could indicate bot)", GetUsername() );
m_Player->SetLastBlockActionTime(); //Player tried to interact with a block. Reset last block interation time.
break;
}
m_Player->SetLastBlockActionTime(); //Player tried to interact with a block. Reset last block interation time.
cPacket_BlockPlace* PacketData = reinterpret_cast<cPacket_BlockPlace*>(a_Packet); cPacket_BlockPlace* PacketData = reinterpret_cast<cPacket_BlockPlace*>(a_Packet);
cItem & Equipped = m_Player->GetInventory().GetEquippedItem(); cItem & Equipped = m_Player->GetInventory().GetEquippedItem();
//if( (Equipped.m_ItemID != PacketData->m_ItemType) ) // Not valid //if( (Equipped.m_ItemID != PacketData->m_ItemType) ) // Not valid
if( (Equipped.m_ItemID != PacketData->m_ItemType) && (cRoot::Get()->GetWorld()->GetGameMode() != 1) ) // Not valid if( (Equipped.m_ItemID != PacketData->m_ItemType) && (m_Player->GetGameMode() != 1) ) // Not valid
{ {
LOGWARN("Player %s tried to place a block that was not selected! (could indicate bot)", GetUsername() ); LOGWARN("Player %s tried to place a block that was not selected! (could indicate bot)", GetUsername() );
break; break;
@ -721,7 +737,7 @@ void cClientHandle::HandlePacket( cPacket* a_Packet )
if( IsValidBlock( PacketData->m_ItemType) ) if( IsValidBlock( PacketData->m_ItemType) )
{ {
if( (m_Player->GetInventory().RemoveItem( Item )) || (cRoot::Get()->GetWorld()->GetGameMode() == 1) ) if( (m_Player->GetInventory().RemoveItem( Item )) || (m_Player->GetGameMode() == 1) )
{ {
int X = PacketData->m_PosX; int X = PacketData->m_PosX;
char Y = PacketData->m_PosY; char Y = PacketData->m_PosY;
@ -914,7 +930,9 @@ void cClientHandle::SendLoginResponse()
cPacket_Login LoginResponse; cPacket_Login LoginResponse;
LoginResponse.m_ProtocolVersion = m_Player->GetUniqueID(); LoginResponse.m_ProtocolVersion = m_Player->GetUniqueID();
//LoginResponse.m_Username = ""; //LoginResponse.m_Username = "";
LoginResponse.m_ServerMode = cRoot::Get()->GetWorld()->GetGameMode(); //set gamemode from world. //m_Player->SetGameMode ( 0 );
m_Player->SetGameMode ( cRoot::Get()->GetWorld()->GetGameMode() ); //set player's gamemode to server's gamemode at login.
LoginResponse.m_ServerMode = m_Player->GetGameMode(); //set gamemode from player.
LoginResponse.m_MapSeed = 0; LoginResponse.m_MapSeed = 0;
LoginResponse.m_Dimension = 0; LoginResponse.m_Dimension = 0;
Send( LoginResponse ); Send( LoginResponse );

View File

@ -58,6 +58,8 @@ struct cPlayer::sPlayerState
cPlayer::cPlayer(cClientHandle* a_Client, const char* a_PlayerName) cPlayer::cPlayer(cClientHandle* a_Client, const char* a_PlayerName)
: m_bBurnable(true) : m_bBurnable(true)
, m_GameMode( 0 )
, m_LastBlockActionTime( 0 )
, e_EPMetaState(NORMAL) , e_EPMetaState(NORMAL)
, m_bVisible( true ) , m_bVisible( true )
, m_LastGroundHeight( 0 ) , m_LastGroundHeight( 0 )
@ -107,6 +109,8 @@ cPlayer::~cPlayer(void)
cRoot::Get()->GetWorld()->RemovePlayer( this ); // TODO - Remove from correct world? Or get rid of this? cRoot::Get()->GetWorld()->RemovePlayer( this ); // TODO - Remove from correct world? Or get rid of this?
} }
void cPlayer::SpawnOn( cClientHandle* a_Target ) void cPlayer::SpawnOn( cClientHandle* a_Target )
{ {
if( a_Target == m_ClientHandle || !m_bVisible ) return; if( a_Target == m_ClientHandle || !m_bVisible ) return;
@ -223,7 +227,7 @@ void cPlayer::InStateBurning(float a_Dt) {
char block = GetWorld()->GetBlock( (int)m_Pos->x, (int)m_Pos->y, (int)m_Pos->z ); char block = GetWorld()->GetBlock( (int)m_Pos->x, (int)m_Pos->y, (int)m_Pos->z );
char bblock = GetWorld()->GetBlock( (int)m_Pos->x, (int)m_Pos->y -1, (int)m_Pos->z ); char bblock = GetWorld()->GetBlock( (int)m_Pos->x, (int)m_Pos->y -1, (int)m_Pos->z );
if(m_FireDamageInterval > 1000) { if(m_FireDamageInterval > 1000) {
m_FireDamageInterval = 0; m_FireDamageInterval = 0;
int rem = rand()%3 + 1; //Burn most of the time int rem = rand()%3 + 1; //Burn most of the time
if(rem >= 2) { if(rem >= 2) {
@ -234,20 +238,20 @@ void cPlayer::InStateBurning(float a_Dt) {
if(block == E_BLOCK_LAVA || block == E_BLOCK_STATIONARY_LAVA || block == E_BLOCK_FIRE if(block == E_BLOCK_LAVA || block == E_BLOCK_STATIONARY_LAVA || block == E_BLOCK_FIRE
|| bblock == E_BLOCK_LAVA || bblock == E_BLOCK_STATIONARY_LAVA || bblock == E_BLOCK_FIRE) || bblock == E_BLOCK_LAVA || bblock == E_BLOCK_STATIONARY_LAVA || bblock == E_BLOCK_FIRE)
m_BurnPeriod = 0; m_BurnPeriod = 0;
if(m_BurnPeriod > 5) { if(m_BurnPeriod > 5) {
cChunk* InChunk = GetWorld()->GetChunkUnreliable( m_ChunkX, m_ChunkY, m_ChunkZ ); cChunk* InChunk = GetWorld()->GetChunkUnreliable( m_ChunkX, m_ChunkY, m_ChunkZ );
e_EPMetaState = NORMAL; e_EPMetaState = NORMAL;
cPacket_Metadata md(NORMAL, GetUniqueID()); cPacket_Metadata md(NORMAL, GetUniqueID());
//md.m_UniqueID = GetUniqueID(); //md.m_UniqueID = GetUniqueID();
InChunk->Broadcast(md); InChunk->Broadcast(md);
m_BurnPeriod = 0; m_BurnPeriod = 0;
} }
} }
} }
//----Change Entity MetaData //----Change Entity MetaData
@ -359,7 +363,8 @@ void cPlayer::Respawn()
// Create Respawn player packet // Create Respawn player packet
cPacket_Respawn Packet; cPacket_Respawn Packet;
//Set Gamemode for packet by looking at world's gamemode (Need to check players gamemode.) //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)GetWorld()->GetGameMode();
Packet.m_CreativeMode = (char)m_GameMode; //Set GameMode packet based on Player's GameMode;
//Send Packet //Send Packet
m_ClientHandle->Send( Packet ); m_ClientHandle->Send( Packet );
TeleportTo( GetWorld()->GetSpawnX(), GetWorld()->GetSpawnY(), GetWorld()->GetSpawnZ() ); TeleportTo( GetWorld()->GetSpawnX(), GetWorld()->GetSpawnY(), GetWorld()->GetSpawnZ() );
@ -389,6 +394,17 @@ void cPlayer::CloseWindow()
m_CurrentWindow = 0; m_CurrentWindow = 0;
} }
void cPlayer::SetLastBlockActionTime()
{
m_LastBlockActionTime = cRoot::Get()->GetWorld()->GetTime();
}
void cPlayer::SetGameMode( int a_GameMode )
{
m_GameMode = a_GameMode;
}
#ifdef SendMessage // Cause stupid windows.h defines SendMessage as SendMessageA #ifdef SendMessage // Cause stupid windows.h defines SendMessage as SendMessageA
#undef SendMessage #undef SendMessage
#endif #endif

View File

@ -29,6 +29,11 @@ public:
virtual void TeleportTo( cEntity* a_Entity ); //tolua_export virtual void TeleportTo( cEntity* a_Entity ); //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
int GetGameMode() { return m_GameMode; } //return GameMode for player.
float GetLastBlockActionTime() { return m_LastBlockActionTime; } //return LastBlockActionTime for player.
void SetLastBlockActionTime();
void SetGameMode( int a_GameMode );
// 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
@ -65,13 +70,13 @@ public:
bool SaveToDisk(); bool SaveToDisk();
bool LoadFromDisk(); bool LoadFromDisk();
//Burning logic //Burning logic
bool m_bBurnable; bool m_bBurnable;
enum PMetaState{NORMAL,BURNING,CROUCHED,RIDING} e_EPMetaState; enum PMetaState{NORMAL,BURNING,CROUCHED,RIDING} e_EPMetaState;
virtual void CheckMetaDataBurn(); virtual void CheckMetaDataBurn();
virtual void InStateBurning(float a_Dt); virtual void InStateBurning(float a_Dt);
protected: protected:
struct sPlayerState; struct sPlayerState;
sPlayerState* m_pState; sPlayerState* m_pState;
@ -93,5 +98,8 @@ protected:
float m_FireDamageInterval; float m_FireDamageInterval;
float m_BurnPeriod; float m_BurnPeriod;
float m_LastBlockActionTime;
int m_GameMode;
cClientHandle* m_ClientHandle; cClientHandle* m_ClientHandle;
}; //tolua_export }; //tolua_export