summaryrefslogtreecommitdiff
path: root/cheat/gmod/player_manager.hpp
blob: 6a89b36a1aa21bddfe1aad22e4e5f43ca69616f5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#pragma once
#include "sdk.hpp"

namespace features
{
	constexpr int CHEATER_SIMTIME_THRESHOLD = 10;
	constexpr int CHEATER_AA_THRESHOLD = 50;
	constexpr int CHEATER_MAX_DETECTIONS = 200;

	class c_player_record {
		float m_last_simtime;
		int m_simtime_detections;
		int m_aa_detections;
		bool m_is_cheater;
		
		c_base_player* m_ent;

		void clear( ) {
			m_last_simtime = { };
			m_simtime_detections = { };
			m_aa_detections = { };
			m_is_cheater = { };
			m_ent = { };
		}

		void update_simtime( ) {
			if( !m_ent ) return;

			if( m_ent->m_flSimulationTime( ) == m_last_simtime ) {
				m_simtime_detections += 2;
			}
			else if( m_simtime_detections > 0 ) {
				m_simtime_detections--;
			}
			m_last_simtime = m_ent->m_flSimulationTime( );
		}

		void update_antiaim( ) {
			if( !m_ent ) return;

			auto pitch = m_ent->m_angEyeAngles( ).x;
			if( pitch > 75.f && m_aa_detections < CHEATER_MAX_DETECTIONS ) {
				m_aa_detections++;
			}
			else if( m_aa_detections > 0 ) {
				m_aa_detections--;
			}
		}

		void update_cheater( ) {
			m_is_cheater = m_simtime_detections > CHEATER_SIMTIME_THRESHOLD
				|| m_aa_detections > CHEATER_AA_THRESHOLD;
		}

	public:
		c_player_record( ) { clear( ); }
		bool is_cheater( ) const { return m_is_cheater; }
		void update( int ent_index );
	};

	class c_player_manager {
		std::array< c_player_record, 65 > m_players;
	public:
		void frame_stage_notify( );
		bool is_cheater( int ent_index );
	};
}