From 86f9be571452f487483d53fd8c715bc08772befe Mon Sep 17 00:00:00 2001
From: Borja Ferrer <faluco@alliedmods.net>
Date: Mon, 1 Jan 2007 03:33:14 +0000
Subject: [PATCH] Added CPlayer class Added new player natives Fixed floatround
 returning a float instead of an int Added new float.inc file Added
 OnClientSettingsChanged forward

--HG--
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40247
---
 core/CPlayer.cpp               |  44 +++++
 core/CPlayer.h                 |  80 +++++++++
 core/CPlayerManager.cpp        |  55 +++++-
 core/CPlayerManager.h          |  37 +++-
 core/msvc8/sourcemod_mm.vcproj |  18 +-
 core/smn_float.cpp             |   2 +-
 core/smn_player.cpp            | 107 ++++++++++++
 plugins/include/float.inc      | 300 +++++++++++++++++++++++++++++++++
 plugins/include/sourcemod.inc  | 131 +++++++++++++-
 9 files changed, 763 insertions(+), 11 deletions(-)
 create mode 100644 core/CPlayer.cpp
 create mode 100644 core/CPlayer.h
 create mode 100644 core/smn_player.cpp
 create mode 100644 plugins/include/float.inc

diff --git a/core/CPlayer.cpp b/core/CPlayer.cpp
new file mode 100644
index 00000000..fd4f9aef
--- /dev/null
+++ b/core/CPlayer.cpp
@@ -0,0 +1,44 @@
+#include "CPlayer.h"
+
+CPlayer::CPlayer()
+{
+	m_IsConnected = false;
+	m_IsInGame = false;
+	m_IsAuthorized = false;
+	m_PlayerEdict = NULL;
+}
+
+void CPlayer::Initialize(const char *name, const char *ip, edict_t *pEntity)
+{
+	m_IsConnected = true;
+	m_Name.assign(name);
+	m_Ip.assign(ip);
+	m_PlayerEdict = pEntity;
+}
+
+void CPlayer::Connect()
+{
+	m_IsInGame = true;
+}
+
+void CPlayer::Authorize(const char *steamid)
+{
+	m_IsAuthorized = true;
+	m_AuthID.assign(steamid);
+}
+
+void CPlayer::Disconnect()
+{
+	m_IsConnected = false;
+	m_IsInGame = false;
+	m_IsAuthorized = false;
+	m_Name.clear();
+	m_Ip.clear();
+	m_AuthID.clear();
+	m_PlayerEdict = NULL;
+}
+
+void CPlayer::SetName(const char *name)
+{
+	m_Name.assign(name);
+}
diff --git a/core/CPlayer.h b/core/CPlayer.h
new file mode 100644
index 00000000..1fb23a2e
--- /dev/null
+++ b/core/CPlayer.h
@@ -0,0 +1,80 @@
+#ifndef _INCLUDE_SOURCEMOD_CPLAYER_H_
+#define _INCLUDE_SOURCEMOD_CPLAYER_H_
+
+#include <sh_string.h>
+#include <eiface.h>
+
+using namespace SourceHook;
+
+class CPlayer
+{
+	friend class CPlayerManager;
+public:
+	CPlayer();
+public:
+	const char *PlayerName() const;
+	const char *PlayerIP() const;
+	const char *PlayerAuthString() const;
+	edict_t *GetPlayerEdict() const;
+	bool IsPlayerInGame() const;
+	bool IsPlayerConnected() const;
+	bool IsPlayerAuthorized() const;
+	bool IsPlayerFakeClient() const;
+	//:TODO: is user alive function
+private:
+	void Initialize(const char *name, const char *ip, edict_t *pEntity);
+	void Connect();
+	void Authorize(const char *steamid);
+	void Disconnect();
+	void SetName(const char *name);
+private:
+	bool m_IsConnected;
+	bool m_IsInGame;
+	bool m_IsAuthorized;
+	String m_Name;
+	String m_Ip;
+	String m_AuthID;
+	edict_t *m_PlayerEdict;
+};
+
+inline const char *CPlayer::PlayerName() const
+{
+	return m_Name.c_str();
+}
+
+inline const char *CPlayer::PlayerIP() const
+{
+	return m_Ip.c_str();
+}
+
+inline const char *CPlayer::PlayerAuthString() const
+{
+	return m_AuthID.c_str();
+}
+
+inline edict_t *CPlayer::GetPlayerEdict() const
+{
+	return m_PlayerEdict;
+}
+
+inline bool CPlayer::IsPlayerInGame() const
+{
+	return m_IsInGame;
+}
+
+inline bool CPlayer::IsPlayerConnected() const
+{
+	return m_IsConnected;
+}
+
+inline bool CPlayer::IsPlayerAuthorized() const
+{
+	return m_IsAuthorized;
+}
+
+inline bool CPlayer::IsPlayerFakeClient() const
+{
+	return (strcmp(m_AuthID.c_str(), "BOT") == 0);
+}
+
+#endif // _INCLUDE_SOURCEMOD_CPLAYER_H_
diff --git a/core/CPlayerManager.cpp b/core/CPlayerManager.cpp
index 968e18af..2158648f 100644
--- a/core/CPlayerManager.cpp
+++ b/core/CPlayerManager.cpp
@@ -1,10 +1,13 @@
 #include "CPlayerManager.h"
 #include "ForwardSys.h"
 
+CPlayerManager g_PlayerManager;
+
 SH_DECL_HOOK5(IServerGameClients, ClientConnect, SH_NOATTRIB, 0, bool, edict_t *, const char *, const char *, char *, int);
 SH_DECL_HOOK2_void(IServerGameClients, ClientPutInServer, SH_NOATTRIB, 0, edict_t *, const char *);
 SH_DECL_HOOK1_void(IServerGameClients, ClientDisconnect, SH_NOATTRIB, 0, edict_t *);
 SH_DECL_HOOK1_void(IServerGameClients, ClientCommand, SH_NOATTRIB, 0, edict_t *);
+SH_DECL_HOOK1_void(IServerGameClients, ClientSettingsChanged, SH_NOATTRIB, 0, edict_t *);
 
 void CPlayerManager::OnSourceModAllInitialized()
 {
@@ -13,6 +16,7 @@ void CPlayerManager::OnSourceModAllInitialized()
 	SH_ADD_HOOK_MEMFUNC(IServerGameClients, ClientDisconnect, serverClients, this, &CPlayerManager::OnClientDisconnect, false);
 	SH_ADD_HOOK_MEMFUNC(IServerGameClients, ClientDisconnect, serverClients, this, &CPlayerManager::OnClientDisconnect_Post, true);
 	SH_ADD_HOOK_MEMFUNC(IServerGameClients, ClientCommand, serverClients, this, &CPlayerManager::OnClientCommand, false);
+	SH_ADD_HOOK_MEMFUNC(IServerGameClients, ClientSettingsChanged, serverClients, this, &CPlayerManager::OnClientSettingsChanged, true);
 
 	/* Register OnClientConnect */
 	ParamType p1[] = {Param_Cell, Param_String, Param_Cell};
@@ -31,8 +35,16 @@ void CPlayerManager::OnSourceModAllInitialized()
 	/* Register OnClientCommand */
 	m_clcommand = g_Forwards.CreateForward("OnClientCommand", ET_Hook, 1, p2);
 
+	/* Register OnClientSettingsChanged */
+	m_clinfochanged = g_Forwards.CreateForward("OnClientSettingsChanged", ET_Ignore, 1, p2);
+
 	/* Register OnClientAuthorized */
 	//:TODO:
+
+	/* Initialize all players */
+	m_maxClients = g_SMAPI->pGlobals()->maxClients;
+	m_PlayerCount = 0;
+	m_Players = new CPlayer[m_maxClients];
 }
 
 void CPlayerManager::OnSourceModShutdown()
@@ -42,6 +54,7 @@ void CPlayerManager::OnSourceModShutdown()
 	SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, ClientDisconnect, serverClients, this, &CPlayerManager::OnClientDisconnect, false);
 	SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, ClientDisconnect, serverClients, this, &CPlayerManager::OnClientDisconnect_Post, true);
 	SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, ClientCommand, serverClients, this, &CPlayerManager::OnClientCommand, false);
+	SH_REMOVE_HOOK_MEMFUNC(IServerGameClients, ClientSettingsChanged, serverClients, this, &CPlayerManager::OnClientSettingsChanged, true);
 
 	/* Release forwards */
 	g_Forwards.ReleaseForward(m_clconnect);
@@ -49,13 +62,18 @@ void CPlayerManager::OnSourceModShutdown()
 	g_Forwards.ReleaseForward(m_cldisconnect);
 	g_Forwards.ReleaseForward(m_cldisconnect_post);
 	g_Forwards.ReleaseForward(m_clcommand);
+	g_Forwards.ReleaseForward(m_clinfochanged);
+
+	delete [] m_Players;
 }
 
 bool CPlayerManager::OnClientConnect(edict_t *pEntity, const char *pszName, const char *pszAddress, char *reject, int maxrejectlen)
 {
 	cell_t res = 1;
+	int client = engine->IndexOfEdict(pEntity);
 
-	m_clconnect->PushCell(engine->IndexOfEdict(pEntity));
+	m_Players[client].Initialize(pszName, pszAddress, pEntity);
+	m_clconnect->PushCell(client);
 	m_clconnect->PushStringEx(reject, maxrejectlen, SM_PARAM_STRING_UTF8, SM_PARAM_COPYBACK);
 	m_clconnect->PushCell(maxrejectlen);
 	m_clconnect->Execute(&res, NULL);
@@ -66,8 +84,11 @@ bool CPlayerManager::OnClientConnect(edict_t *pEntity, const char *pszName, cons
 void CPlayerManager::OnClientPutInServer(edict_t *pEntity, const char *playername)
 {
 	cell_t res;
+	int client = engine->IndexOfEdict(pEntity);
 
-	m_clputinserver->PushCell(engine->IndexOfEdict(pEntity));
+	m_Players[client].Connect();
+	m_PlayerCount++;
+	m_clputinserver->PushCell(client);
 	m_clputinserver->Execute(&res, NULL);
 }
 
@@ -79,9 +100,18 @@ void CPlayerManager::OnClientAuthorized()
 void CPlayerManager::OnClientDisconnect(edict_t *pEntity)
 {
 	cell_t res;
+	int client = engine->IndexOfEdict(pEntity);
 
-	m_cldisconnect->PushCell(engine->IndexOfEdict(pEntity));
-	m_cldisconnect->Execute(&res, NULL);
+	if (m_Players[client].IsPlayerConnected())
+	{
+		m_cldisconnect->PushCell(client);
+		m_cldisconnect->Execute(&res, NULL);
+	}
+	if (m_Players[client].IsPlayerInGame())
+	{
+		m_PlayerCount--;
+	}
+	m_Players[client].Disconnect();
 }
 
 void CPlayerManager::OnClientDisconnect_Post(edict_t *pEntity)
@@ -98,4 +128,19 @@ void CPlayerManager::OnClientCommand(edict_t *pEntity)
 
 	m_clcommand->PushCell(engine->IndexOfEdict(pEntity));
 	m_clcommand->Execute(&res, NULL);
-}
\ No newline at end of file
+
+	//:TODO: res should be evaluated here for something, DOCUMENT this in the INC FILE!
+}
+
+void CPlayerManager::OnClientSettingsChanged(edict_t *pEntity)
+{
+	cell_t res;
+	int client = engine->IndexOfEdict(pEntity);
+
+	m_clinfochanged->PushCell(engine->IndexOfEdict(pEntity));
+	m_clinfochanged->Execute(&res, NULL);
+	if (m_Players[client].IsPlayerInGame())
+	{
+		m_Players[client].SetName(engine->GetClientConVarValue(client, "name"));
+	}
+}
diff --git a/core/CPlayerManager.h b/core/CPlayerManager.h
index b11b233c..ed482517 100644
--- a/core/CPlayerManager.h
+++ b/core/CPlayerManager.h
@@ -1,16 +1,23 @@
 #ifndef _INCLUDE_SOURCEMOD_CPLAYERMANAGER_H_
 #define _INCLUDE_SOURCEMOD_CPLAYERMANAGER_H_
 
-#include "sourcemod.h"
+#include "sm_globals.h"
 #include <eiface.h>
 #include "sourcemm_api.h"
 #include <IForwardSys.h>
+#include "CPlayer.h"
+
+class CPlayer;
 
 class CPlayerManager : public SMGlobalClass
 {
 public: //SMGlobalClass
 	virtual void OnSourceModAllInitialized();
 	virtual void OnSourceModShutdown();
+public:
+	int GetMaxClients() const;
+	CPlayer *GetPlayerByIndex(int client) const;
+	int GetPlayerCount() const;
 public:
 	bool OnClientConnect(edict_t *pEntity, const char *pszName, const char *pszAddress, char *reject, int maxrejectlen);
 	void OnClientPutInServer(edict_t *pEntity, char const *playername);
@@ -18,12 +25,38 @@ public:
 	void OnClientDisconnect_Post(edict_t *pEntity);
 	void OnClientAuthorized(); //:TODO: any args needed?
 	void OnClientCommand(edict_t *pEntity);
+	void OnClientSettingsChanged(edict_t *pEntity);
 private:
 	IForward *m_clconnect;
 	IForward *m_cldisconnect;
 	IForward *m_cldisconnect_post;
 	IForward *m_clputinserver;
 	IForward *m_clcommand;
+	IForward *m_clinfochanged;
+	CPlayer *m_Players;
+	int m_maxClients;
+	int m_PlayerCount;
 };
 
-#endif //_INCLUDE_SOURCEMOD_CPLAYERMANAGER_H_
\ No newline at end of file
+extern CPlayerManager g_PlayerManager;
+
+inline int CPlayerManager::GetMaxClients() const
+{
+	return m_maxClients;
+}
+
+inline CPlayer *CPlayerManager::GetPlayerByIndex(int client) const
+{
+	if (client > m_maxClients || client < 0)
+	{
+		return NULL;
+	}
+	return &m_Players[client];
+}
+
+inline int CPlayerManager::GetPlayerCount() const
+{
+	return m_PlayerCount;
+}
+
+#endif //_INCLUDE_SOURCEMOD_CPLAYERMANAGER_H_
diff --git a/core/msvc8/sourcemod_mm.vcproj b/core/msvc8/sourcemod_mm.vcproj
index 5300a0ac..7f9ac9f3 100644
--- a/core/msvc8/sourcemod_mm.vcproj
+++ b/core/msvc8/sourcemod_mm.vcproj
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="Windows-1252"?>
 <VisualStudioProject
 	ProjectType="Visual C++"
-	Version="8.00"
+	Version="8,00"
 	Name="sourcemod_mm"
 	ProjectGUID="{E39527CD-7CAB-4420-97CC-DA1B93B260BC}"
 	RootNamespace="sourcemod_mm"
@@ -178,6 +178,10 @@
 			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
 			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
 			>
+			<File
+				RelativePath="..\CPlayer.cpp"
+				>
+			</File>
 			<File
 				RelativePath="..\CPlayerManager.cpp"
 				>
@@ -210,6 +214,10 @@
 				RelativePath="..\smn_float.cpp"
 				>
 			</File>
+			<File
+				RelativePath="..\smn_player.cpp"
+				>
+			</File>
 			<File
 				RelativePath="..\smn_string.cpp"
 				>
@@ -228,6 +236,10 @@
 			Filter="h;hpp;hxx;hm;inl;inc;xsd"
 			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
 			>
+			<File
+				RelativePath="..\CPlayer.h"
+				>
+			</File>
 			<File
 				RelativePath="..\CPlayerManager.h"
 				>
@@ -315,6 +327,10 @@
 					RelativePath="..\systems\PluginSys.h"
 					>
 				</File>
+				<File
+					RelativePath="..\systems\ShareSys.h"
+					>
+				</File>
 			</Filter>
 			<Filter
 				Name="Source Files"
diff --git a/core/smn_float.cpp b/core/smn_float.cpp
index 851a5fed..cab961a2 100644
--- a/core/smn_float.cpp
+++ b/core/smn_float.cpp
@@ -150,7 +150,7 @@ static cell_t sm_floatround(IPluginContext *pCtx, const cell_t *params)
 		}
 	}
 
-	return sp_ftoc(val);
+	return static_cast<int>(val);
 }
 
 static cell_t sm_floatstr(IPluginContext *pCtx, const cell_t *params)
diff --git a/core/smn_player.cpp b/core/smn_player.cpp
new file mode 100644
index 00000000..ad7bdcb5
--- /dev/null
+++ b/core/smn_player.cpp
@@ -0,0 +1,107 @@
+#include "CPlayerManager.h"
+
+static cell_t sm_getclientcount(IPluginContext *pCtx, const cell_t *params)
+{
+	if (params[1])
+	{
+		return g_PlayerManager.GetPlayerCount();
+	}
+
+	int maxplayers = g_PlayerManager.GetMaxClients();
+	int count = 0;
+	for (int i=1; i<=maxplayers; ++i)
+	{
+		CPlayer *pPlayer = g_PlayerManager.GetPlayerByIndex(i);
+		if ((pPlayer->IsPlayerConnected()) && !(pPlayer->IsPlayerInGame()))
+		{
+			count++;
+		}
+	}
+
+	return (g_PlayerManager.GetPlayerCount() + count);
+}
+
+static cell_t sm_getmaxclients(IPluginContext *pCtx, const cell_t *params)
+{
+	return g_PlayerManager.GetMaxClients();
+}
+
+static cell_t sm_getclientname(IPluginContext *pCtx, const cell_t *params)
+{
+	int index = params[1];
+	if ((index < 1) || (index > g_PlayerManager.GetMaxClients()))
+	{
+		//:TODO: runtime error
+	}
+
+	pCtx->StringToLocalUTF8(params[2], static_cast<size_t>(params[3]), g_PlayerManager.GetPlayerByIndex(index)->PlayerName(), NULL);
+	return 1;
+}
+
+static cell_t sm_getclientip(IPluginContext *pCtx, const cell_t *params)
+{
+	int index = params[1];
+	if ((index < 1) || (index > g_PlayerManager.GetMaxClients()))
+	{
+		//:TODO: runtime error
+	}
+
+	pCtx->StringToLocal(params[2], static_cast<size_t>(params[3]), g_PlayerManager.GetPlayerByIndex(index)->PlayerIP());
+	return 1;
+}
+
+static cell_t sm_getclientauthstr(IPluginContext *pCtx, const cell_t *params)
+{
+	int index = params[1];
+	if ((index < 1) || (index > g_PlayerManager.GetMaxClients()))
+	{
+		//:TODO: runtime error
+	}
+
+	pCtx->StringToLocal(params[2], static_cast<size_t>(params[3]), g_PlayerManager.GetPlayerByIndex(index)->PlayerAuthString());
+	return 1;
+}
+
+static cell_t sm_isplayerconnected(IPluginContext *pCtx, const cell_t *params)
+{
+	int index = params[1];
+	if ((index < 1) || (index > g_PlayerManager.GetMaxClients()))
+	{
+		//:TODO: runtime error
+	}
+
+	return (g_PlayerManager.GetPlayerByIndex(index)->IsPlayerConnected()) ? 1 : 0;
+}
+
+static cell_t sm_isplayeringame(IPluginContext *pCtx, const cell_t *params)
+{
+	int index = params[1];
+	if ((index < 1) || (index > g_PlayerManager.GetMaxClients()))
+	{
+		//:TODO: runtime error
+	}
+
+	return (g_PlayerManager.GetPlayerByIndex(index)->IsPlayerInGame()) ? 1 : 0;
+}
+
+static cell_t sm_isplayerauthorized(IPluginContext *pCtx, const cell_t *params)
+{
+	int index = params[1];
+	if ((index < 1) || (index > g_PlayerManager.GetMaxClients()))
+	{
+		//:TODO: runtime error
+	}
+
+	return (g_PlayerManager.GetPlayerByIndex(index)->IsPlayerAuthorized()) ? 1 : 0;
+}
+
+static cell_t sm_isplayerfakeclient(IPluginContext *pCtx, const cell_t *params)
+{
+	int index = params[1];
+	if ((index < 1) || (index > g_PlayerManager.GetMaxClients()))
+	{
+		//:TODO: runtime error
+	}
+
+	return (g_PlayerManager.GetPlayerByIndex(index)->IsPlayerFakeClient()) ? 1 : 0;
+}
\ No newline at end of file
diff --git a/plugins/include/float.inc b/plugins/include/float.inc
new file mode 100644
index 00000000..04fb6bb5
--- /dev/null
+++ b/plugins/include/float.inc
@@ -0,0 +1,300 @@
+/**
+ * :TODO: license info
+ */
+
+#if defined _float_included
+ #endinput
+#endif
+#define _float_included
+
+/**
+ * @GLOBAL@
+ *   All the trigonometric functions take in or return its values in RADIANS.
+ *   Use DegToRad or RadToDeg stocks to convert the radix units.
+ */
+
+/* Different methods of rounding */
+enum floatround_method
+{
+	floatround_round = 0,
+	floatround_floor,
+	floatround_ceil,
+	floatround_tozero
+};
+
+/**
+ * Converts an integer into a floating point value.
+ *
+ * @param value			Integer to convert.
+ * @return				Floating point value.
+ */
+native Float:float(value);
+
+/**
+ * Converts a string into a floating point value.
+ *
+ * @param str			String to convert.
+ * @return				Converted floating point number.
+ */
+native Float:FloatStr(const String:str[]);
+
+/**
+ * Multiplies two floats together.
+ *
+ * @param oper1			First value.
+ * @param oper2			Second value.
+ * @return				oper1*oper2.
+ */
+native Float:FloatMul(Float:oper1, Float:oper2);
+
+/**
+ * Divides the dividend by the divisor.
+ *
+ * @param dividend		First value.
+ * @param divisor		Second value.
+ * @return				dividend/divisor.
+ */
+native Float:FloatDiv(Float:dividend, Float:divisor);
+
+/**
+ * Adds two floats together.
+ *
+ * @param oper1			First value.
+ * @param oper2			Second value.
+ * @return				oper1+oper2.
+ */
+native Float:FloatAdd(Float:oper1, Float:oper2);
+
+/**
+ * Subtracts oper2 from oper1.
+ *
+ * @param oper1			First value.
+ * @param oper2			Second value.
+ * @return				oper1-oper2.
+ */
+native Float:FloatSub(Float:oper1, Float:oper2);
+
+/**
+ * Returns the decimal part of a float.
+ *
+ * @param value			Input value.
+ * @return				Decimal part.
+ */
+native Float:FloatFraction(Float:value);
+
+/**
+ * Rounds a float into an integer number.
+ *
+ * @param value			Input value to be rounded.
+ * @param method		Rounding method to use.
+ * @return				Rounded value.
+ */
+native FloatRound(Float:value, floatround_method:method=floatround_round);
+
+/**
+ * Compares two floats.
+ *
+ * @param fOne			First value.
+ * @param fTwo			Second value.
+ * @return				Returns 1 if the first argument is greater than the second argument.
+ *                      Returns -1 if the first argument is smaller than the second argument.
+ *                      Returns 0 if both arguments are equal.
+ */
+native FloatCompare(Float:fOne, Float:fTwo);
+
+/**
+ * Returns the square root of the input value, equivalent to floatpower(value, 0.5).
+ *
+ * @param value			Input value.
+ * @return				Square root of the value.
+ */
+native Float:SquareRoot(Float:value);
+
+/**
+ * Returns the value raised to the power of the exponent.
+ *
+ * @param value			Value to be raised.
+ * @param exponent		Value to raise the base.
+ * @return				value^exponent.
+ */
+native Float:Pow(Float:value, Float:exponent);
+
+/**
+ * Returns the value of raising the input by e.
+ *
+ * @param value			Input value.
+ * @return				exp(value).
+ */
+native Float:Exponential(Float:value);
+
+/**
+ * Returns the logarithm of any base specified.
+ *
+ * @param value			Input value.
+ * @param base			Logarithm base to use, default is 10.
+ * @return				log(value)/log(base).
+ */
+native Float:Logarithm(Float:value, Float:base=10.0);
+
+/**
+ * Returns the sine of the argument.
+ *
+ * @param value			Input value in radians.
+ * @return				sin(value).
+ */
+native Float:Sine(Float:value);
+
+/**
+ * Returns the cosine of the argument.
+ *
+ * @param value			Input value in radians.
+ * @return				cos(value).
+ */
+native Float:Cosine(Float:value);
+
+/**
+ * Returns the tangent of the argument.
+ *
+ * @param value			Input value in radians.
+ * @return				tan(value).
+ */
+native Float:Tangent(Float:value);
+
+/**
+ * Returns the absolute value.
+ *
+ * @param value			Input value.
+ * @return				abs(value).
+ */
+native Float:FloatAbs(Float:value);
+
+/**
+ * Returns the arctangent of the input value.
+ *
+ * @param angle			Input value.
+ * @return				atan(value) in radians.
+ */
+native Float:ArcTangent(Float:angle);
+
+/**
+ * Returns the arccosine of the input value.
+ *
+ * @param angle			Input value.
+ * @return				acos(value) in radians.
+ */
+native Float:ArcCosine(Float:angle);
+
+/**
+ * Returns the arcsine of the input value.
+ *
+ * @param angle			Input value.
+ * @return				asin(value) in radians.
+ */
+native Float:ArcSine(Float:angle);
+
+/**
+ * Returns the arctangent2 of the input values.
+ *
+ * @param x				Horizontal value.
+ * @param y				Vertical value.
+ * @return				atan2(value) in radians.
+ */
+native Float:ArcAtan2(Float:x, Float:y);
+
+/**
+ * User defined operators.
+ *
+ */
+#pragma rational Float
+
+native Float:operator*(Float:oper1, Float:oper2) = FloatMul;
+native Float:operator/(Float:oper1, Float:oper2) = FloatDiv;
+native Float:operator+(Float:oper1, Float:oper2) = FloatAdd;
+native Float:operator-(Float:oper1, Float:oper2) = FloatSub;
+
+stock Float:operator++(Float:oper)
+	return oper+1.0;
+
+stock Float:operator--(Float:oper)
+	return oper-1.0;
+
+stock Float:operator-(Float:oper)
+	return oper^Float:((-1)^((-1)/2));				/* IEEE values are sign/magnitude */
+
+stock Float:operator*(Float:oper1, oper2)
+	return FloatMul(oper1, float(oper2));			/* "*" is commutative */
+
+stock Float:operator/(Float:oper1, oper2)
+	return FloatDiv(oper1, float(oper2));
+
+stock Float:operator/(oper1, Float:oper2)
+	return FloatDiv(float(oper1), oper2);
+
+stock Float:operator+(Float:oper1, oper2)
+	return FloatAdd(oper1, float(oper2));			/* "+" is commutative */
+
+stock Float:operator-(Float:oper1, oper2)
+	return FloatSub(oper1, float(oper2));
+
+stock Float:operator-(oper1, Float:oper2)
+	return FloatSub(float(oper1), oper2);
+
+stock bool:operator==(Float:oper1, Float:oper2)
+	return FloatCompare(oper1, oper2) == 0;
+
+stock bool:operator==(Float:oper1, oper2)
+	return FloatCompare(oper1, float(oper2)) == 0; 	/* "==" is commutative */
+
+stock bool:operator!=(Float:oper1, Float:oper2)
+	return FloatCompare(oper1, oper2) != 0;
+
+stock bool:operator!=(Float:oper1, oper2)
+	return FloatCompare(oper1, float(oper2)) != 0; 	/* "==" is commutative */
+
+stock bool:operator>(Float:oper1, Float:oper2)
+	return FloatCompare(oper1, oper2) > 0;
+
+stock bool:operator>(Float:oper1, oper2)
+	return FloatCompare(oper1, float(oper2)) > 0;
+
+stock bool:operator>(oper1, Float:oper2)
+	return FloatCompare(float(oper1), oper2) > 0;
+
+stock bool:operator>=(Float:oper1, Float:oper2)
+	return FloatCompare(oper1, oper2) >= 0;
+
+stock bool:operator>=(Float:oper1, oper2)
+	return FloatCompare(oper1, float(oper2)) >= 0;
+
+stock bool:operator>=(oper1, Float:oper2)
+	return FloatCompare(float(oper1), oper2) >= 0;
+
+stock bool:operator<(Float:oper1, Float:oper2)
+	return FloatCompare(oper1, oper2) < 0;
+
+stock bool:operator<(Float:oper1, oper2)
+	return FloatCompare(oper1, float(oper2)) < 0;
+
+stock bool:operator<(oper1, Float:oper2)
+	return FloatCompare(float(oper1), oper2) < 0;
+
+stock bool:operator<=(Float:oper1, Float:oper2)
+	return FloatCompare(oper1, oper2) <= 0;
+
+stock bool:operator<=(Float:oper1, oper2)
+	return FloatCompare(oper1, float(oper2)) <= 0;
+
+stock bool:operator<=(oper1, Float:oper2)
+	return FloatCompare(float(oper1), oper2) <= 0;
+
+stock bool:operator!(Float:oper)
+	return (_:oper & ((-1)/2)) == 0;		/* -1 = all bits to 1; /2 = remove most significant bit (sign)
+											works on both 32bit and 64bit systems; no constant required */
+
+/**
+ * Forbidden operators.
+ *
+ */
+forward operator%(Float:oper1, Float:oper2);
+forward operator%(Float:oper1, oper2);
+forward operator%(oper1, Float:oper2);
\ No newline at end of file
diff --git a/plugins/include/sourcemod.inc b/plugins/include/sourcemod.inc
index a799213c..3d3a17a9 100644
--- a/plugins/include/sourcemod.inc
+++ b/plugins/include/sourcemod.inc
@@ -14,7 +14,7 @@ struct Plugin
    const String:author[],		/* Plugin Author */
    const String:version[],		/* Plugin Version */
    const String:url[],			/* Plugin URL */
-}
+};
 
 /**
  * Declare this as a struct in your plugin to expose its information.
@@ -50,7 +50,7 @@ forward OnPluginInit(Handle:myself);
  * @param late		Whether or not the plugin was loaded "late" (after map load).
  * @param error		Error message buffer in case load failed.
  * @param err_max	Maximum number of characters for error message buffer.
- * @return		True if load success, false otherwise.
+ * @return			True if load success, false otherwise.
  */
 forward bool:AskPluginLoad(Handle:myself, bool:late, String:error[], err_max);
 
@@ -67,3 +67,130 @@ forward OnPluginUnload();
  * @noreturn
  */
 forward OnPluginPauseChange(bool:pause);
+
+/**
+ * Called on client connection.
+ *
+ * @param client		Player index.
+ * @param rejectmsg		Buffer to store the rejection message when the connection is refused.
+ * @param maxlen		Maximum number of characters for rejection buffer.
+ * @return				True to validate client's connection, false to refuse it.
+ */
+forward bool:OnClientConnect(client, String:rejectmsg[], maxlen);
+
+/**
+ * Called when a client is entering to the game.
+ *
+ * @param client		Player index.
+ * @noreturn
+ */
+forward OnClientPutInServer(client);
+
+/**
+ * Called when a client is disconnecting from the server.
+ *
+ * @param client		Player index.
+ * @noreturn
+ */
+forward OnClientDisconnect(client);
+
+/**
+ * Called when a client is disconnected from the server.
+ *
+ * @param client		Player index.
+ * @noreturn
+ */
+forward OnClientDisconnect_Post(client);
+
+/**
+ * Called when a client is sending a command.
+ *
+ * @param client		Player index.
+ * @noreturn
+ */
+forward OnClientCommand(client);
+
+/**
+ * Called whenever the client's settings are changed.
+ *
+ * @param client		Player index.
+ * @noreturn
+ */
+forward OnClientSettingsChanged(client);
+
+/**
+ * Returns the maximum number of clients allowed on the server.
+ *
+ * @return				Maximum number of clients allowed.
+ */
+native GetMaxClients();
+
+/**
+ * Returns the client count put in the server.
+ *
+ * @param inGameOnly	If false connecting players are also counted.
+ * @return				Client count in the server.
+ */
+native GetClientCount(bool:inGameOnly=true);
+
+/**
+ * Returns the client's name.
+ *
+ * @param client		Player index.
+ * @param name			Buffer to store the client's name.
+ * @param maxlen		Maximum length of string buffer (includes NULL terminator).
+ * @noreturn
+ */
+native GetClientName(client, String:name[], maxlen);
+
+/**
+ * Returns the client's Ip address.
+ *
+ * @param client		Player index.
+ * @param name			Buffer to store the client's ip address.
+ * @param maxlen		Maximum length of string buffer (includes NULL terminator).
+ * @noreturn
+ */
+native GetClientIp(client, String:ip[], maxlen);
+
+/**
+ * Returns the client's authindex.
+ *
+ * @param client		Player index.
+ * @param auth			Buffer to store the client's auth string.
+ * @param maxlen		Maximum length of string buffer (includes NULL terminator).
+ * @return				Returns 0 on failure, non-zero otherwise.
+ */
+native GetClientAuthString(client, String:auth[], maxlen);
+
+/**
+ * Returns if a certain player is connected.
+ *
+ * @param client		Player index.
+ * @return				True if player is connected to the server, false otherwise.
+ */
+native bool:IsPlayerConnected(client);
+
+/**
+ * Returns if a certain player has entered the game.
+ *
+ * @param client		Player index.
+ * @return				True if player has entered the game, false otherwise.
+ */
+native bool:IsPlayerInGame(client);
+
+/**
+ * Returns if a certain player has been authenticated.
+ *
+ * @param client		Player index.
+ * @return				True if player has been authenticated, false otherwise.
+ */
+native bool:IsPlayerAuthorized(client);
+
+/**
+ * Returns if a certain player is a fake client.
+ *
+ * @param client		Player index.
+ * @return				True if player is a fake client, false otherwise.
+ */
+native bool:IsPlayerFakeClient(client);