1
0

Added a crude limiter for explosions sent to client.

Now the client can survive even 3000k TNT blocks exploding without jerking much.

git-svn-id: http://mc-server.googlecode.com/svn/trunk@1606 0a769ca7-a7f5-676a-18bf-c427514a06d6
This commit is contained in:
madmaxoft@gmail.com 2013-06-18 19:32:31 +00:00
parent 961c7bc51e
commit 32f28bf1fb
2 changed files with 42 additions and 2 deletions

View File

@ -47,6 +47,12 @@
/// If the number of queued outgoing packets reaches this, the client will be kicked /// If the number of queued outgoing packets reaches this, the client will be kicked
#define MAX_OUTGOING_PACKETS 2000 #define MAX_OUTGOING_PACKETS 2000
/// How many explosions per single game tick are allowed
static const int MAX_EXPLOSIONS_PER_TICK = 100;
/// How many explosions in the recent history are allowed
static const int MAX_RUNNING_SUM_EXPLOSIONS = cClientHandle::NUM_CHECK_EXPLOSIONS_TICKS * MAX_EXPLOSIONS_PER_TICK / 8;
@ -87,6 +93,8 @@ cClientHandle::cClientHandle(const cSocket * a_Socket, int a_ViewDistance)
, m_UniqueID(0) , m_UniqueID(0)
, m_BlockDigAnimStage(-1) , m_BlockDigAnimStage(-1)
, m_HasStartedDigging(false) , m_HasStartedDigging(false)
, m_CurrentExplosionTick(0)
, m_RunningSumExplosions(0)
{ {
m_Protocol = new cProtocolRecognizer(this); m_Protocol = new cProtocolRecognizer(this);
@ -1310,6 +1318,11 @@ void cClientHandle::Tick(float a_Dt)
m_Player->GetWorld()->BroadcastBlockBreakAnimation(m_UniqueID, m_BlockDigAnimX, m_BlockDigAnimY, m_BlockDigAnimZ, (char)(m_BlockDigAnimStage / 1000), this); m_Player->GetWorld()->BroadcastBlockBreakAnimation(m_UniqueID, m_BlockDigAnimX, m_BlockDigAnimY, m_BlockDigAnimZ, (char)(m_BlockDigAnimStage / 1000), this);
} }
} }
// Update the explosion statistics:
m_CurrentExplosionTick = (m_CurrentExplosionTick + 1) % ARRAYCOUNT(m_NumExplosionsPerTick);
m_RunningSumExplosions -= m_NumExplosionsPerTick[m_CurrentExplosionTick];
m_NumExplosionsPerTick[m_CurrentExplosionTick] = 0;
} }
@ -1563,7 +1576,20 @@ void cClientHandle::SendEntityStatus(const cEntity & a_Entity, char a_Status)
void cClientHandle::SendExplosion(double a_BlockX, double a_BlockY, double a_BlockZ, float a_Radius, const cVector3iArray & a_BlocksAffected, const Vector3d & a_PlayerMotion) void cClientHandle::SendExplosion(double a_BlockX, double a_BlockY, double a_BlockZ, float a_Radius, const cVector3iArray & a_BlocksAffected, const Vector3d & a_PlayerMotion)
{ {
m_Protocol->SendExplosion(a_BlockX,a_BlockY,a_BlockZ,a_Radius, a_BlocksAffected, a_PlayerMotion); if (
(m_NumExplosionsPerTick[m_CurrentExplosionTick] > MAX_EXPLOSIONS_PER_TICK) || // Too many explosions in this tick
(m_RunningSumExplosions > MAX_RUNNING_SUM_EXPLOSIONS) // Too many explosions in the recent history
)
{
LOGD("Dropped %u explosions", a_BlocksAffected.size());
return;
}
// Update the statistics:
m_NumExplosionsPerTick[m_CurrentExplosionTick] += a_BlocksAffected.size();
m_RunningSumExplosions += a_BlocksAffected.size();
m_Protocol->SendExplosion(a_BlockX, a_BlockY, a_BlockZ, a_Radius, a_BlocksAffected, a_PlayerMotion);
} }

View File

@ -56,7 +56,10 @@ public:
#endif #endif
static const int MAX_VIEW_DISTANCE = 10; static const int MAX_VIEW_DISTANCE = 10;
static const int MIN_VIEW_DISTANCE = 4; static const int MIN_VIEW_DISTANCE = 4;
/// How many ticks should be checked for a running average of explosions, for limiting purposes
static const int NUM_CHECK_EXPLOSIONS_TICKS = 20;
cClientHandle(const cSocket * a_Socket, int a_ViewDistance); cClientHandle(const cSocket * a_Socket, int a_ViewDistance);
virtual ~cClientHandle(); virtual ~cClientHandle();
@ -258,6 +261,17 @@ private:
/// If set to true during csDownloadingWorld, the tick thread calls CheckIfWorldDownloaded() /// If set to true during csDownloadingWorld, the tick thread calls CheckIfWorldDownloaded()
bool m_ShouldCheckDownloaded; bool m_ShouldCheckDownloaded;
/// Stores the recent history of the number of explosions per tick
int m_NumExplosionsPerTick[NUM_CHECK_EXPLOSIONS_TICKS];
/// Points to the current tick in the m_NumExplosionsPerTick[] array
int m_CurrentExplosionTick;
/// Running sum of m_NumExplosionsPerTick[]
int m_RunningSumExplosions;
/// Returns true if the rate block interactions is within a reasonable limit (bot protection) /// Returns true if the rate block interactions is within a reasonable limit (bot protection)
bool CheckBlockInteractionsRate(void); bool CheckBlockInteractionsRate(void);