From 32f28bf1fb61195f4f3709fccce09abc3b20a166 Mon Sep 17 00:00:00 2001 From: "madmaxoft@gmail.com" Date: Tue, 18 Jun 2013 19:32:31 +0000 Subject: 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 --- source/ClientHandle.cpp | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) (limited to 'source/ClientHandle.cpp') diff --git a/source/ClientHandle.cpp b/source/ClientHandle.cpp index 13b7e64c9..4831c5512 100644 --- a/source/ClientHandle.cpp +++ b/source/ClientHandle.cpp @@ -47,6 +47,12 @@ /// If the number of queued outgoing packets reaches this, the client will be kicked #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_BlockDigAnimStage(-1) , m_HasStartedDigging(false) + , m_CurrentExplosionTick(0) + , m_RunningSumExplosions(0) { 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); } } + + // 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) { - 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); } -- cgit v1.2.3