about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/game/server/entities/character.cpp34
-rw-r--r--src/game/server/entities/character.h12
-rw-r--r--src/game/server/gamecontext.cpp26
-rw-r--r--src/game/server/player.h6
4 files changed, 34 insertions, 44 deletions
diff --git a/src/game/server/entities/character.cpp b/src/game/server/entities/character.cpp
index 697260a2..76c074cd 100644
--- a/src/game/server/entities/character.cpp
+++ b/src/game/server/entities/character.cpp
@@ -49,7 +49,7 @@ CCharacter::CCharacter(CGameWorld *pWorld)
 	
 	// last positions
 	m_LastPositionsSize = Server()->TickSpeed() / 4;
-	m_LastPositions = new LastPosition[m_LastPositionsSize]();
+	m_LastPositions = new vec2[m_LastPositionsSize]();
 }
 
 CCharacter::~CCharacter()
@@ -119,31 +119,29 @@ void CCharacter::Destroy()
 }
 
 // checks whether the player has been at those coords recently (like a few ticks ago)
-bool CCharacter::HasBeenThereRecently(float x, float y, const LastPosition *&pos, int firstTick, int lastTick) const
+bool CCharacter::HasBeenThereRecently(vec2 v, const vec2 *&pos, int firstTick, int lastTick) const
 {
 	// start with the most recent position
-	float dx, dy, dxp = 0, dyp = 0;
+	vec2 d, dp(0,0);
 	for(; lastTick > firstTick; --lastTick)
 	{
 		int i = lastTick % m_LastPositionsSize;
-		dx = abs(m_LastPositions[i].x - x);
-		dy = abs(m_LastPositions[i].y - y);
-		if(dx <= 1.0 && dy <= 1.0)
+		d = m_LastPositions[i] - v;
+		d = vec2(absolute(d.x), absolute(d.y));
+		if(d.x <= 1.0 && d.y <= 1.0)
 		{
 			pos = &m_LastPositions[i];
 			return true;
 		}
 		// abort if too far away or if distance getting bigger
-		if(dx > 100.0 || dy > 100.0 || (dxp > 0 && dx > dxp && dy > dyp)) return false;
-		// write previous vals
-		dxp = dx;
-		dyp = dy;
+		if(d.x > 100.0 || d.y > 100.0 || (dp.x > 0 && d.x > dp.x && d.y > dp.x)) return false;
+		dp = d;
 	}
 	return false;
 }
 
 // checks whether the player has been aiming at another character recently (like a few ticks ago)
-bool CCharacter::AimedAtCharRecently(float aimX, float aimY, const CCharacter *c, const LastPosition *&pos, const LastPosition *&posVictim, int firstTick)
+bool CCharacter::AimedAtCharRecently(vec2 v, const CCharacter *c, const vec2 *&pos, const vec2 *&posVictim, int firstTick)
 {
 	// The last few positions of both characters are saved. Since you cannot tell (due to the network) _when_ the player aimed at the other player, or even where he was when he aimed, we need to check each position of the one player against each position of the other player in the time before.
 	// start with the most recent position
@@ -152,7 +150,7 @@ bool CCharacter::AimedAtCharRecently(float aimX, float aimY, const CCharacter *c
 	{
 		int b = lastTick % m_LastPositionsSize;
 		// check if the other player has been where the player aimed
-		if(c->HasBeenThereRecently(m_LastPositions[b].x + aimX, m_LastPositions[b].y + aimY, posVictim, firstTick, lastTick))
+		if(c->HasBeenThereRecently(v + m_LastPositions[b], posVictim, firstTick, lastTick))
 		{
 			pos = &m_LastPositions[b];
 			return true;
@@ -161,20 +159,21 @@ bool CCharacter::AimedAtCharRecently(float aimX, float aimY, const CCharacter *c
 	return false;
 }
 
-float CCharacter::HowCloseToXRecently(vec2 x, const LastPosition *&pos, int firstTick)
+float CCharacter::HowCloseToXRecently(vec2 x, const vec2 *&pos, int firstTick)
 {
-	float lowest = 1000.0;
+	float lowest = -1.0;
 	// start with the most recent position
 	firstTick = max(firstTick, Server()->Tick() - m_LastPositionsSize);
 	for(int lastTick = Server()->Tick(); lastTick > firstTick; --lastTick)
 	{
 		int i = lastTick % m_LastPositionsSize;
-		float d = distance(x, vec2(m_LastPositions[i].x, m_LastPositions[i].y));
-		if(d < lowest)
+		float d = distance(x, m_LastPositions[i]);
+		if(d < lowest || lowest < .0)
 		{
 			pos = &m_LastPositions[i];
 			lowest = d;
 		}
+		if(lowest == .0) break;
 	}
 	return lowest;
 }
@@ -714,8 +713,7 @@ void CCharacter::Tick()
 	m_PrevInput = m_Input;
 	
 	// save position
-	m_LastPositions[Server()->Tick() % m_LastPositionsSize].x = m_Pos.x;
-	m_LastPositions[Server()->Tick() % m_LastPositionsSize].y = m_Pos.y;
+	m_LastPositions[Server()->Tick() % m_LastPositionsSize] = m_Pos;
 	
 	return;
 }
diff --git a/src/game/server/entities/character.h b/src/game/server/entities/character.h
index 77997903..0d68707a 100644
--- a/src/game/server/entities/character.h
+++ b/src/game/server/entities/character.h
@@ -70,13 +70,9 @@ public:
 	int m_FreezeTicks;
 	
 	// bot detection
-	struct LastPosition {
-		float x;
-		float y;
-	};
-	bool HasBeenThereRecently(float x, float y, const LastPosition *&pos, int firstTick, int lastTick) const;
-	bool AimedAtCharRecently(float aimX, float aimY, const CCharacter *c, const LastPosition *&pos, const LastPosition *&posVictim, int firstTick);
-	float HowCloseToXRecently(vec2 x, const LastPosition *&pos, int firstTick);
+	bool HasBeenThereRecently(vec2 v, const vec2 *&pos, int firstTick, int lastTick) const;
+	bool AimedAtCharRecently(vec2 v, const CCharacter *c, const vec2 *&pos, const vec2 *&posVictim, int firstTick);
+	float HowCloseToXRecently(vec2 x, const vec2 *&pos, int firstTick);
 
 private:
 	// player controlling this character
@@ -146,7 +142,7 @@ private:
 	CCharacterCore m_ReckoningCore; // the dead reckoning core
 	
 	// bot detection
-	LastPosition *m_LastPositions;
+	vec2 *m_LastPositions;
 	int m_LastPositionsSize;
 
 };
diff --git a/src/game/server/gamecontext.cpp b/src/game/server/gamecontext.cpp
index ee906059..307d446a 100644
--- a/src/game/server/gamecontext.cpp
+++ b/src/game/server/gamecontext.cpp
@@ -533,7 +533,7 @@ void CGameContext::OnTick()
 	if(g_Config.m_SvBotDetection && Server()->GetNumLoggedInAdmins())
 	{
 		char aBuf[128];
-		const CCharacter::LastPosition *pos, *posVictim;
+		const vec2 *pos, *posVictim;
 		float d, precision;
 		CCharacter *ci, *cj;
 		CPlayer *p;
@@ -552,43 +552,39 @@ void CGameContext::OnTick()
 				if(j != i && (cj = GetPlayerChar(j)))
 				{
 					int indexAdd = 0;
+					vec2 target(p->m_LatestActivity.m_TargetX, p->m_LatestActivity.m_TargetY);
 					
 					// fast aiming bot detection
 					if(g_Config.m_SvBotDetection&BOT_DETECTION_FAST_AIM
 						&& p->m_AimBotTargetSpeed > 300.0 // only fast movements
-						&& (d = cj->HowCloseToXRecently(vec2(ci->m_Pos.x + p->m_LatestActivity.m_TargetX, ci->m_Pos.y + p->m_LatestActivity.m_TargetY), posVictim, p->m_AimBotLastDetection)) < 16.0
+						&& (d = cj->HowCloseToXRecently(ci->m_Pos + target, posVictim, p->m_AimBotLastDetection)) < 16.0
 						&& (precision = p->m_AimBotTargetSpeed * (256.0 - d * d)) >= 50000.0
 						&& !( // don't detect same constellation twice
-							ci->m_Pos.x == p->m_AimBotLastDetectionPos.x
-							&& ci->m_Pos.y == p->m_AimBotLastDetectionPos.y
-							&& posVictim->x == p->m_AimBotLastDetectionPosVictim.x
-							&& posVictim->y == p->m_AimBotLastDetectionPosVictim.y
+							ci->m_Pos == p->m_AimBotLastDetectionPos
+							&& *posVictim == p->m_AimBotLastDetectionPosVictim
 						)
 					)//if
 					{
 						indexAdd = min(3, (int)(precision / 50000));
-						p->m_AimBotLastDetectionPos.x = ci->m_Pos.x;
-						p->m_AimBotLastDetectionPos.y = ci->m_Pos.y;
+						p->m_AimBotLastDetectionPos = ci->m_Pos;
 						// prepare console output
-						str_format(aBuf, sizeof(aBuf), "player=%d victim=%d a_index=%d precision=%d speed=%d distance=%d", i, j, p->m_AimBotIndex + indexAdd, (int)precision, (int)p->m_AimBotTargetSpeed, (int)d);
+						str_format(aBuf, sizeof(aBuf), "player=%d victim=%d index=%d precision=%d speed=%d distance=%d", i, j, p->m_AimBotIndex + indexAdd, (int)precision, (int)p->m_AimBotTargetSpeed, (int)d);
 					}
 					
 					// follow bot detection
 					else if(g_Config.m_SvBotDetection&BOT_DETECTION_FOLLOW
 						&& cj->NetworkClipped(i) == 0 // needs to be in sight
-						&& ci->AimedAtCharRecently(p->m_LatestActivity.m_TargetX, p->m_LatestActivity.m_TargetY, cj, pos, posVictim, p->m_AimBotLastDetection)
+						&& ci->AimedAtCharRecently(target, cj, pos, posVictim, p->m_AimBotLastDetection)
 						&& !( // don't detect same constellation twice
-							pos->x == p->m_AimBotLastDetectionPos.x
-							&& pos->y == p->m_AimBotLastDetectionPos.y
-							&& posVictim->x == p->m_AimBotLastDetectionPosVictim.x
-							&& posVictim->y == p->m_AimBotLastDetectionPosVictim.y
+							*pos == p->m_AimBotLastDetectionPos
+							&& *posVictim == p->m_AimBotLastDetectionPosVictim
 						)
 					)//if
 					{
 						indexAdd = 1;
 						p->m_AimBotLastDetectionPos = *pos;
 						// prepare console output
-						str_format(aBuf, sizeof(aBuf), "player=%d victim=%d a_index=%d", i, j, p->m_AimBotIndex + indexAdd);
+						str_format(aBuf, sizeof(aBuf), "player=%d victim=%d index=%d", i, j, p->m_AimBotIndex + indexAdd);
 					}
 					
 					// detected
diff --git a/src/game/server/player.h b/src/game/server/player.h
index 53466d0c..b16e2589 100644
--- a/src/game/server/player.h
+++ b/src/game/server/player.h
@@ -135,12 +135,12 @@ public:
 	// bot detection
 	int m_IsAimBot;
 	int m_AimBotIndex;
-	int m_AimBotLastDetection;
 	float m_AimBotTargetSpeed;
 	vec2 m_CurrentTarget;
 	vec2 m_LastTarget;
-	CCharacter::LastPosition m_AimBotLastDetectionPos;
-	CCharacter::LastPosition m_AimBotLastDetectionPosVictim;
+	int m_AimBotLastDetection;
+	vec2 m_AimBotLastDetectionPos;
+	vec2 m_AimBotLastDetectionPosVictim;
 	
 private:
 	CCharacter *m_pCharacter;