1.1 --- a/core/PlayerManager.cpp Tue Jul 24 17:05:46 2007 +0000
1.2 +++ b/core/PlayerManager.cpp Tue Jul 24 20:11:47 2007 +0000
1.3 @@ -21,6 +21,9 @@
1.4 #include "MenuStyle_Radio.h"
1.5 #include "sm_stringutil.h"
1.6 #include "CoreConfig.h"
1.7 +#include <inetchannel.h>
1.8 +#include <iclient.h>
1.9 +#include "TimerSys.h"
1.10
1.11 PlayerManager g_Players;
1.12 bool g_OnMapStarted = false;
1.13 @@ -32,6 +35,25 @@
1.14 SH_DECL_HOOK1_void(IServerGameClients, ClientSettingsChanged, SH_NOATTRIB, 0, edict_t *);
1.15 SH_DECL_HOOK3_void(IServerGameDLL, ServerActivate, SH_NOATTRIB, 0, edict_t *, int, int);
1.16
1.17 +class KickPlayerTimer : public ITimedEvent
1.18 +{
1.19 +public:
1.20 + ResultType OnTimer(ITimer *pTimer, void *pData)
1.21 + {
1.22 + int userid = (int)pData;
1.23 + int client = g_Players.GetClientOfUserId(userid);
1.24 + if (client)
1.25 + {
1.26 + CPlayer *player = g_Players.GetPlayerByIndex(client);
1.27 + player->Kick("Your name is reserved by SourceMod; set your password to use it.");
1.28 + }
1.29 + return Pl_Stop;
1.30 + }
1.31 + void OnTimerEnd(ITimer *pTimer, void *pData)
1.32 + {
1.33 + }
1.34 +} s_KickPlayerTimer;
1.35 +
1.36 PlayerManager::PlayerManager()
1.37 {
1.38 m_AuthQueue = NULL;
1.39 @@ -159,6 +181,31 @@
1.40 return true;
1.41 }
1.42
1.43 +bool PlayerManager::CheckSetAdminName(int index, CPlayer *pPlayer, AdminId id)
1.44 +{
1.45 + const char *password = g_Admins.GetAdminPassword(id);
1.46 + if (password == NULL)
1.47 + {
1.48 + return false;
1.49 + }
1.50 +
1.51 + if (m_PassInfoVar.size() < 1)
1.52 + {
1.53 + return false;
1.54 + }
1.55 +
1.56 + /* Whoa... the user needs a password! */
1.57 + const char *given = engine->GetClientConVarValue(index, m_PassInfoVar.c_str());
1.58 + if (!given || strcmp(given, password) != 0)
1.59 + {
1.60 + return false;
1.61 + }
1.62 +
1.63 + pPlayer->SetAdminId(id, false);
1.64 +
1.65 + return true;
1.66 +}
1.67 +
1.68 void PlayerManager::RunAuthChecks()
1.69 {
1.70 CPlayer *pPlayer;
1.71 @@ -172,24 +219,13 @@
1.72 && (strcmp(authstr, "STEAM_ID_PENDING") != 0))
1.73 {
1.74 /* Set authorization */
1.75 - pPlayer->m_AuthID.assign(authstr);
1.76 - pPlayer->m_IsAuthorized = true;
1.77 + pPlayer->Authorize(authstr);
1.78
1.79 /* Mark as removed from queue */
1.80 unsigned int client = m_AuthQueue[i];
1.81 m_AuthQueue[i] = 0;
1.82 removed++;
1.83
1.84 - /* Do admin lookups */
1.85 - if (pPlayer->GetAdminId() == INVALID_ADMIN_ID)
1.86 - {
1.87 - AdminId id = g_Admins.FindAdminByIdentity("steam", authstr);
1.88 - if (id != INVALID_ADMIN_ID)
1.89 - {
1.90 - CheckSetAdmin(client, pPlayer, id);
1.91 - }
1.92 - }
1.93 -
1.94 /* Send to extensions */
1.95 List<IClientListener *>::iterator iter;
1.96 IClientListener *pListener;
1.97 @@ -211,6 +247,11 @@
1.98 m_clauth->PushString(authstr);
1.99 m_clauth->Execute(NULL);
1.100 }
1.101 +
1.102 + if (pPlayer->IsConnected())
1.103 + {
1.104 + pPlayer->Authorize_Post();
1.105 + }
1.106 }
1.107 }
1.108
1.109 @@ -303,23 +344,6 @@
1.110 }
1.111 }
1.112
1.113 - if (pPlayer->IsConnected())
1.114 - {
1.115 - /* Do an ip based lookup */
1.116 - char ip[24], *ptr;
1.117 - strncopy(ip, pszAddress, sizeof(ip));
1.118 - if ((ptr = strchr(ip, ':')) != NULL)
1.119 - {
1.120 - *ptr = '\0';
1.121 - }
1.122 -
1.123 - AdminId id = g_Admins.FindAdminByIdentity("ip", ip);
1.124 - if (id != INVALID_ADMIN_ID)
1.125 - {
1.126 - CheckSetAdmin(client, pPlayer, id);
1.127 - }
1.128 - }
1.129 -
1.130 return true;
1.131 }
1.132
1.133 @@ -370,6 +394,15 @@
1.134 m_clauth->PushCell(client);
1.135 m_clauth->PushString(authid);
1.136 m_clauth->Execute(NULL);
1.137 + if (!pPlayer->IsConnected())
1.138 + {
1.139 + return;
1.140 + }
1.141 + }
1.142 + pPlayer->Authorize_Post();
1.143 + if (!pPlayer->IsConnected())
1.144 + {
1.145 + return;
1.146 }
1.147 }
1.148
1.149 @@ -524,7 +557,46 @@
1.150
1.151 m_clinfochanged->PushCell(engine->IndexOfEdict(pEntity));
1.152 m_clinfochanged->Execute(&res, NULL);
1.153 - m_Players[client].SetName(engine->GetClientConVarValue(client, "name"));
1.154 +
1.155 + IPlayerInfo *info = m_Players[client].GetPlayerInfo();
1.156 + const char *new_name = info ? info->GetName() : engine->GetClientConVarValue(client, "name");
1.157 + const char *old_name = m_Players[client].m_Name.c_str();
1.158 +
1.159 + if (strcmp(old_name, new_name) != 0)
1.160 + {
1.161 + AdminId id = g_Admins.FindAdminByIdentity("name", new_name);
1.162 + if (id != INVALID_ADMIN_ID && m_Players[client].GetAdminId() != id)
1.163 + {
1.164 + if (!CheckSetAdminName(client, &m_Players[client], id))
1.165 + {
1.166 + m_Players[client].Kick("Your name is reserved by SourceMod; set your password to use it.");
1.167 + RETURN_META(MRES_IGNORED);
1.168 + }
1.169 + } else if ((id = g_Admins.FindAdminByIdentity("name", old_name)) != INVALID_ADMIN_ID) {
1.170 + if (id == m_Players[client].GetAdminId())
1.171 + {
1.172 + /* This player is changing their name; force them to drop admin privileges! */
1.173 + m_Players[client].SetAdminId(INVALID_ADMIN_ID, false);
1.174 + }
1.175 + }
1.176 + m_Players[client].SetName(new_name);
1.177 + }
1.178 +
1.179 + if (m_PassInfoVar.size() > 0)
1.180 + {
1.181 + /* Try for a password change */
1.182 + const char *old_pass = m_Players[client].m_LastPassword.c_str();
1.183 + const char *new_pass = engine->GetClientConVarValue(client, m_PassInfoVar.c_str());
1.184 + if (strcmp(old_pass, new_pass) != 0)
1.185 + {
1.186 + m_Players[client].m_LastPassword.assign(new_pass);
1.187 + if (m_Players[client].IsInGame() && m_Players[client].IsAuthorized())
1.188 + {
1.189 + /* If there is already an admin id assigned, this will just bail out. */
1.190 + m_Players[client].DoBasicAdminChecks();
1.191 + }
1.192 + }
1.193 + }
1.194 }
1.195
1.196 int PlayerManager::GetMaxClients()
1.197 @@ -631,6 +703,10 @@
1.198 }
1.199 }
1.200
1.201 +const char *PlayerManager::GetPassInfoVar()
1.202 +{
1.203 + return m_PassInfoVar.c_str();
1.204 +}
1.205
1.206 /*******************
1.207 *** PLAYER CODE ***
1.208 @@ -645,6 +721,7 @@
1.209 m_Admin = INVALID_ADMIN_ID;
1.210 m_TempAdmin = false;
1.211 m_Info = NULL;
1.212 + m_LastPassword.clear();
1.213 }
1.214
1.215 void CPlayer::Initialize(const char *name, const char *ip, edict_t *pEntity)
1.216 @@ -653,15 +730,48 @@
1.217 m_Name.assign(name);
1.218 m_Ip.assign(ip);
1.219 m_pEdict = pEntity;
1.220 +
1.221 + char ip2[24], *ptr;
1.222 + strncopy(ip2, ip, sizeof(ip2));
1.223 + if ((ptr = strchr(ip2, ':')) != NULL)
1.224 + {
1.225 + *ptr = '\0';
1.226 + }
1.227 + m_IpNoPort.assign(ip2);
1.228 }
1.229
1.230 void CPlayer::Connect()
1.231 {
1.232 + if (m_IsInGame)
1.233 + {
1.234 + return;
1.235 + }
1.236 +
1.237 m_IsInGame = true;
1.238 +
1.239 + const char *var = g_Players.GetPassInfoVar();
1.240 + int client = engine->IndexOfEdict(m_pEdict);
1.241 + if (var[0] != '\0')
1.242 + {
1.243 + const char *pass = engine->GetClientConVarValue(client, var);
1.244 + m_LastPassword.assign(pass ? pass : "");
1.245 + } else {
1.246 + m_LastPassword.assign("");
1.247 + }
1.248 +
1.249 + if (m_IsAuthorized)
1.250 + {
1.251 + DoBasicAdminChecks();
1.252 + }
1.253 }
1.254
1.255 void CPlayer::Authorize(const char *steamid)
1.256 {
1.257 + if (m_IsAuthorized)
1.258 + {
1.259 + return;
1.260 + }
1.261 +
1.262 m_IsAuthorized = true;
1.263 m_AuthID.assign(steamid);
1.264 }
1.265 @@ -759,3 +869,59 @@
1.266 m_TempAdmin = false;
1.267 }
1.268 }
1.269 +
1.270 +void CPlayer::Kick(const char *str)
1.271 +{
1.272 + int client = engine->IndexOfEdict(m_pEdict);
1.273 + INetChannel *pNetChan = static_cast<INetChannel *>(engine->GetPlayerNetInfo(client));
1.274 + IClient *pClient = static_cast<IClient *>(pNetChan->GetMsgHandler());
1.275 + pClient->Disconnect("%s", str);
1.276 +}
1.277 +
1.278 +void CPlayer::Authorize_Post()
1.279 +{
1.280 + if (m_IsInGame)
1.281 + {
1.282 + DoBasicAdminChecks();
1.283 + }
1.284 +}
1.285 +
1.286 +void CPlayer::DoBasicAdminChecks()
1.287 +{
1.288 + if (GetAdminId() != INVALID_ADMIN_ID)
1.289 + {
1.290 + return;
1.291 + }
1.292 +
1.293 + /* First check the name */
1.294 + AdminId id;
1.295 + int client = engine->IndexOfEdict(m_pEdict);
1.296 +
1.297 + if ((id = g_Admins.FindAdminByIdentity("name", GetName())) != INVALID_ADMIN_ID)
1.298 + {
1.299 + if (!g_Players.CheckSetAdminName(client, this, id))
1.300 + {
1.301 + int userid = engine->GetPlayerUserId(m_pEdict);
1.302 + g_Timers.CreateTimer(&s_KickPlayerTimer, 0.1f, (void *)userid, 0);
1.303 + }
1.304 + return;
1.305 + }
1.306 +
1.307 + /* Check IP */
1.308 + if ((id = g_Admins.FindAdminByIdentity("ip", m_IpNoPort.c_str())) != INVALID_ADMIN_ID)
1.309 + {
1.310 + if (g_Players.CheckSetAdmin(client, this, id))
1.311 + {
1.312 + return;
1.313 + }
1.314 + }
1.315 +
1.316 + /* Check IP address */
1.317 + if ((id = g_Admins.FindAdminByIdentity("steam", m_AuthID.c_str())) != INVALID_ADMIN_ID)
1.318 + {
1.319 + if (g_Players.CheckSetAdmin(client, this, id))
1.320 + {
1.321 + return;
1.322 + }
1.323 + }
1.324 +}