about summary refs log tree commit diff
path: root/src/game/server/entities
diff options
context:
space:
mode:
authorMarius "Teelevision" Neugebauer <marius@teele.eu>2014-04-02 02:41:20 +0200
committerMarius "Teelevision" Neugebauer <marius@teele.eu>2014-04-02 02:41:20 +0200
commit461e9be9a6dc90e9ef5c1b365205906c1d6c8431 (patch)
tree61bd1e3bc91a868cb930682c8db1da164a2ab4b7 /src/game/server/entities
parentc207f70e19fa4cc9389f547b1bf5470634fa2af1 (diff)
downloadzcatch-461e9be9a6dc90e9ef5c1b365205906c1d6c8431.tar.gz
zcatch-461e9be9a6dc90e9ef5c1b365205906c1d6c8431.zip
started bot detection
Diffstat (limited to 'src/game/server/entities')
-rw-r--r--src/game/server/entities/character.cpp55
-rw-r--r--src/game/server/entities/character.h12
2 files changed, 67 insertions, 0 deletions
diff --git a/src/game/server/entities/character.cpp b/src/game/server/entities/character.cpp
index 01ed8693..547eabce 100644
--- a/src/game/server/entities/character.cpp
+++ b/src/game/server/entities/character.cpp
@@ -46,6 +46,10 @@ CCharacter::CCharacter(CGameWorld *pWorld)
 	m_Health = 0;
 	m_Armor = 0;
 	m_FreezeTicks = 0;
+	
+	// last positions
+	m_LastPositionsSize = Server()->TickSpeed() / 4;
+	m_LastPositions = new LastPosition[m_LastPositionsSize]();
 }
 
 void CCharacter::Reset()
@@ -106,6 +110,52 @@ void CCharacter::Destroy()
 {
 	GameServer()->m_World.m_Core.m_apCharacters[m_pPlayer->GetCID()] = 0;
 	m_Alive = false;
+	
+	// delete last positions
+	delete[] m_LastPositions;
+}
+
+// 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
+{
+	// start with the most recent position
+	float dx, dy, dxp = 0, dyp = 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)
+		{
+			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;
+	}
+	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)
+{
+	// 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
+	firstTick = max(firstTick, Server()->Tick() - m_LastPositionsSize);
+	for(int lastTick = Server()->Tick(); lastTick > firstTick; --lastTick)
+	{
+		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))
+		{
+			pos = &m_LastPositions[b];
+			return true;
+		}
+	}
+	return false;
 }
 
 void CCharacter::SetWeapon(int W)
@@ -641,6 +691,11 @@ void CCharacter::Tick()
 
 	// Previnput
 	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;
+	
 	return;
 }
 
diff --git a/src/game/server/entities/character.h b/src/game/server/entities/character.h
index ece33e45..4d615324 100644
--- a/src/game/server/entities/character.h
+++ b/src/game/server/entities/character.h
@@ -67,6 +67,14 @@ public:
 
 	void Freeze(int Tick);
 	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);
 
 private:
 	// player controlling this character
@@ -134,6 +142,10 @@ private:
 	int m_ReckoningTick; // tick that we are performing dead reckoning From
 	CCharacterCore m_SendCore; // core that we should send
 	CCharacterCore m_ReckoningCore; // the dead reckoning core
+	
+	// bot detection
+	LastPosition *m_LastPositions;
+	int m_LastPositionsSize;
 
 };