extensions/clientprefs/cookie.cpp
author Ruben Gonzalez <drifter01620@gmail.com>
Thu May 22 09:49:27 2014 -0400 (2014-05-22)
changeset 4378 568f4497ef4a
parent 4348 2cb93df2515e
permissions -rw-r--r--
Update CS:GO team score gamedata.
     1 /**
     2  * vim: set ts=4 sw=4 tw=99 noet:
     3  * =============================================================================
     4  * SourceMod Client Preferences Extension
     5  * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
     6  * =============================================================================
     7  *
     8  * This program is free software; you can redistribute it and/or modify it under
     9  * the terms of the GNU General Public License, version 3.0, as published by the
    10  * Free Software Foundation.
    11  * 
    12  * This program is distributed in the hope that it will be useful, but WITHOUT
    13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    14  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
    15  * details.
    16  *
    17  * You should have received a copy of the GNU General Public License along with
    18  * this program.  If not, see <http://www.gnu.org/licenses/>.
    19  *
    20  * As a special exception, AlliedModders LLC gives you permission to link the
    21  * code of this program (as well as its derivative works) to "Half-Life 2," the
    22  * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
    23  * by the Valve Corporation.  You must obey the GNU General Public License in
    24  * all respects for all other code used.  Additionally, AlliedModders LLC grants
    25  * this exception to all derivative works.  AlliedModders LLC defines further
    26  * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
    27  * or <http://www.sourcemod.net/license.php>.
    28  *
    29  * Version: $Id$
    30  */
    31 
    32 #include "cookie.h"
    33 #include "menus.h"
    34 #include "query.h"
    35 
    36 CookieManager g_CookieManager;
    37 
    38 CookieManager::CookieManager()
    39 {
    40 	for (int i=0; i<=SM_MAXPLAYERS; i++)
    41 	{
    42 		connected[i] = false;
    43 		statsLoaded[i] = false;
    44 		statsPending[i] = false;
    45 	}
    46 
    47 	cookieDataLoadedForward = NULL;
    48 	clientMenu = NULL;
    49 }
    50 CookieManager::~CookieManager(){}
    51 
    52 void CookieManager::Unload()
    53 {
    54 	/* If clients are connected we should try save their data */
    55 	for (int i = playerhelpers->GetMaxClients()+1; --i > 0;)
    56 	{
    57 		if (connected[i])
    58 			OnClientDisconnecting(i);
    59 	}
    60 
    61 	/* Find all cookies and delete them */
    62 	for (SourceHook::List<Cookie *>::iterator _iter = cookieList.begin(); _iter != cookieList.end(); _iter++)
    63 		delete (*_iter);
    64 	
    65 	cookieList.clear();
    66 }
    67 
    68 Cookie *CookieManager::FindCookie(const char *name)
    69 {
    70 	Cookie *cookie;
    71 	if (!cookieFinder.retrieve(name, &cookie))
    72 		return NULL;
    73 	return cookie;
    74 }
    75 
    76 Cookie *CookieManager::CreateCookie(const char *name, const char *description, CookieAccess access)
    77 {
    78 	Cookie *pCookie = FindCookie(name);
    79 
    80 	/* Check if cookie already exists */
    81 	if (pCookie != NULL)
    82 	{
    83 		/* Update data fields to the provided values */
    84 		UTIL_strncpy(pCookie->description, description, MAX_DESC_LENGTH);
    85 		pCookie->access = access;
    86 
    87 		return pCookie;
    88 	}
    89 
    90 	/* First time cookie - Create from scratch */
    91 	pCookie = new Cookie(name, description, access);
    92 	
    93 	/* Attempt to insert cookie into the db and get its ID num */
    94 	TQueryOp *op = new TQueryOp(Query_InsertCookie, pCookie);
    95 	op->m_params.cookie = pCookie;
    96 	
    97 	cookieFinder.insert(name, pCookie);
    98 	cookieList.push_back(pCookie);
    99 
   100 	g_ClientPrefs.AddQueryToQueue(op);
   101 
   102 	return pCookie;
   103 }
   104 
   105 bool CookieManager::GetCookieValue(Cookie *pCookie, int client, char **value)
   106 {
   107 	CookieData *data = pCookie->data[client];
   108 
   109 	/* Check if a value has been set before */
   110 	if (data == NULL)
   111 	{
   112 		data = new CookieData("");
   113 		data->parent = pCookie;
   114 		clientData[client].push_back(data);
   115 		pCookie->data[client] = data;
   116 		data->changed = false;
   117 		data->timestamp = 0;
   118 	}
   119 
   120 	*value = &data->value[0];
   121 
   122 	return true;
   123 }
   124 
   125 bool CookieManager::SetCookieValue(Cookie *pCookie, int client, const char *value)
   126 {
   127 	CookieData *data = pCookie->data[client];
   128 
   129 	if (data == NULL)
   130 	{
   131 		data = new CookieData(value);
   132 		data->parent = pCookie;
   133 		clientData[client].push_back(data);
   134 		pCookie->data[client] = data;
   135 	}
   136 	else
   137 	{
   138 		UTIL_strncpy(data->value, value, MAX_VALUE_LENGTH);
   139 	}
   140 
   141 	data->changed = true;
   142 	data->timestamp = time(NULL);
   143 
   144 	return true;
   145 }
   146 
   147 void CookieManager::OnClientAuthorized(int client, const char *authstring)
   148 {
   149 	IGamePlayer *player = playerhelpers->GetGamePlayer(client);
   150 
   151 	if (player == NULL)
   152 	{
   153 		return;
   154 	}
   155 
   156 	connected[client] = true;
   157 	statsPending[client] = true;
   158 
   159 	g_ClientPrefs.AttemptReconnection();
   160 	
   161 	TQueryOp *op = new TQueryOp(Query_SelectData, player->GetSerial());
   162 	UTIL_strncpy(op->m_params.steamId, authstring, MAX_NAME_LENGTH);
   163 
   164 	g_ClientPrefs.AddQueryToQueue(op);
   165 }
   166 
   167 void CookieManager::OnClientDisconnecting(int client)
   168 {
   169 	connected[client] = false;
   170 	statsLoaded[client] = false;
   171 	statsPending[client] = false;
   172 
   173 	CookieData *current = NULL;
   174 
   175 	g_ClientPrefs.AttemptReconnection();
   176 	
   177 	/* Save this cookie to the database */
   178 	IGamePlayer *player = playerhelpers->GetGamePlayer(client);
   179 	const char *pAuth = NULL;
   180 	int dbId;
   181 	
   182 	if (player)
   183 	{
   184 		pAuth = player->GetAuthString();
   185 		g_ClientPrefs.ClearQueryCache(player->GetSerial());
   186 	}
   187 		
   188 	for (SourceHook::List<CookieData *>::iterator _iter = clientData[client].begin();\
   189 	_iter != clientData[client].end(); _iter++)
   190 	{
   191 		current = (CookieData *)*_iter;
   192 		dbId = current->parent->dbid;
   193 		
   194 		if (player == NULL || pAuth == NULL || !current->changed || dbId == -1)
   195 		{
   196 			current->parent->data[client] = NULL;
   197 			delete current;
   198 			continue;
   199 		}
   200 
   201 		TQueryOp *op = new TQueryOp(Query_InsertData, client);
   202 
   203 		UTIL_strncpy(op->m_params.steamId, pAuth, MAX_NAME_LENGTH);
   204 		op->m_params.cookieId = dbId;
   205 		op->m_params.data = current;
   206 
   207 		g_ClientPrefs.AddQueryToQueue(op);
   208 
   209 		current->parent->data[client] = NULL;
   210 	}
   211 	
   212 	clientData[client].clear();
   213 }
   214 
   215 void CookieManager::ClientConnectCallback(int serial, IQuery *data)
   216 {
   217 	int client;
   218 
   219 	/* Check validity of client */
   220 	if ((client = playerhelpers->GetClientFromSerial(serial)) == 0)
   221 	{
   222 		return;
   223 	}
   224 	statsPending[client] = false;
   225 	
   226 	IResultSet *results;
   227 	/* Check validity of results */
   228 	if (data == NULL || (results = data->GetResultSet()) == NULL)
   229 	{
   230 		return;
   231 	}
   232 
   233 	CookieData *pData;
   234 	IResultRow *row;
   235 	unsigned int timestamp;
   236 	CookieAccess access;
   237 	
   238 	while (results->MoreRows() && ((row = results->FetchRow()) != NULL))
   239 	{
   240 		const char *name = "";
   241 		row->GetString(0, &name, NULL);
   242 		
   243 		const char *value = "";
   244 		row->GetString(1, &value, NULL);
   245 
   246 		pData = new CookieData(value);
   247 		pData->changed = false;
   248 
   249 		pData->timestamp = (row->GetInt(4, (int *)&timestamp) == DBVal_Data) ? timestamp : 0;
   250 
   251 		Cookie *parent = FindCookie(name);
   252 
   253 		if (parent == NULL)
   254 		{
   255 			const char *desc = "";
   256 			row->GetString(2, &desc, NULL);
   257 
   258 			access = CookieAccess_Public;
   259 			row->GetInt(3, (int *)&access);
   260 
   261 			parent = CreateCookie(name, desc, access);
   262 		}
   263 
   264 		pData->parent = parent;
   265 		parent->data[client] = pData;
   266 		clientData[client].push_back(pData);
   267 	}
   268 
   269 	statsLoaded[client] = true;
   270 
   271 	cookieDataLoadedForward->PushCell(client);
   272 	cookieDataLoadedForward->Execute(NULL);
   273 }
   274 
   275 void CookieManager::InsertCookieCallback(Cookie *pCookie, int dbId)
   276 {
   277 	if (dbId > 0)
   278 	{
   279 		pCookie->dbid = dbId;
   280 		return;
   281 	}
   282 
   283 	TQueryOp *op = new TQueryOp(Query_SelectId, pCookie);
   284 	/* Put the cookie name into the steamId field to save space - Make sure we remember that it's there */
   285 	UTIL_strncpy(op->m_params.steamId, pCookie->name, MAX_NAME_LENGTH);
   286 	g_ClientPrefs.AddQueryToQueue(op);
   287 }
   288 
   289 void CookieManager::SelectIdCallback(Cookie *pCookie, IQuery *data)
   290 {
   291 	IResultSet *results;
   292 	
   293 	if (data == NULL || (results = data->GetResultSet()) == NULL)
   294 	{
   295 		return;
   296 	}
   297 
   298 	IResultRow *row = results->FetchRow();
   299 
   300 	if (row == NULL)
   301 	{
   302 		return;
   303 	}
   304 
   305 	row->GetInt(0, &pCookie->dbid);
   306 }
   307 
   308 bool CookieManager::AreClientCookiesCached(int client)
   309 {
   310 	return statsLoaded[client];
   311 }
   312 
   313 bool CookieManager::AreClientCookiesPending(int client)
   314 {
   315 	return statsPending[client];
   316 }
   317 
   318 void CookieManager::OnPluginDestroyed(IPlugin *plugin)
   319 {
   320 	SourceHook::List<char *> *pList;
   321 
   322 	if (plugin->GetProperty("SettingsMenuItems", (void **)&pList, true))
   323 	{
   324 		char *name;
   325 		ItemDrawInfo draw;
   326 		const char *info;
   327 		AutoMenuData * data;
   328 		unsigned itemcount;
   329 		
   330 		for (SourceHook::List<char *>::iterator p_iter = pList->begin(); p_iter != pList->end(); p_iter++)
   331 		{
   332 			name = (char *)*p_iter;
   333 			itemcount = clientMenu->GetItemCount();
   334 			//remove from this plugins list
   335 			for (unsigned int i=0; i < itemcount; i++)
   336 			{
   337 				info = clientMenu->GetItemInfo(i, &draw);
   338 
   339 				if (info == NULL)
   340 				{
   341 					continue;
   342 				}
   343 
   344 				if (strcmp(draw.display, name) == 0)
   345 				{
   346 					data = (AutoMenuData *)strtoul(info, NULL, 16);
   347 
   348 					if (data->handler->forward != NULL)
   349 					{
   350 						forwards->ReleaseForward(data->handler->forward);
   351 					}
   352 					delete data->handler;
   353 					delete data;
   354 
   355 					clientMenu->RemoveItem(i);
   356 					break;
   357 				}
   358 			}
   359 
   360 			delete [] name;
   361 		}
   362 		
   363 		pList->clear();
   364 	}
   365 }
   366 
   367 bool CookieManager::GetCookieTime(Cookie *pCookie, int client, time_t *value)
   368 {
   369 	CookieData *data = pCookie->data[client];
   370 
   371 	/* Check if a value has been set before */
   372 	if (data == NULL)
   373 	{
   374 		return false;
   375 	}
   376 
   377 	*value = data->timestamp;
   378 
   379 	return true;
   380 }