Overhaul of ClientPrefs extension (bug 5538, r=asherkin).
1.1 --- a/extensions/clientprefs/cookie.cpp Mon Feb 25 20:44:16 2013 -0600
1.2 +++ b/extensions/clientprefs/cookie.cpp Thu Feb 28 21:51:49 2013 +0000
1.3 @@ -41,6 +41,7 @@
1.4 {
1.5 connected[i] = false;
1.6 statsLoaded[i] = false;
1.7 + statsPending[i] = false;
1.8 }
1.9
1.10 cookieDataLoadedForward = NULL;
1.11 @@ -51,10 +52,7 @@
1.12 void CookieManager::Unload()
1.13 {
1.14 /* If clients are connected we should try save their data */
1.15 -
1.16 - int maxclients = playerhelpers->GetMaxClients();
1.17 -
1.18 - for (int i=1; i<=maxclients; i++)
1.19 + for (int i = playerhelpers->GetMaxClients()+1; --i > 0;)
1.20 {
1.21 if (connected[i])
1.22 {
1.23 @@ -63,20 +61,14 @@
1.24 }
1.25
1.26 /* Find all cookies and delete them */
1.27 -
1.28 - SourceHook::List<Cookie *>::iterator _iter;
1.29 -
1.30 Cookie *current;
1.31
1.32 - _iter = cookieList.begin();
1.33 -
1.34 - while (_iter != cookieList.end())
1.35 + for (SourceHook::List<Cookie *>::iterator _iter = cookieList.begin(); _iter != cookieList.end(); _iter++)
1.36 {
1.37 current = (Cookie *)*_iter;
1.38
1.39 if (current == NULL)
1.40 {
1.41 - _iter++;
1.42 continue;
1.43 }
1.44
1.45 @@ -91,9 +83,9 @@
1.46 g_ClientPrefs.cookieMutex->Unlock();
1.47 delete current;
1.48 }
1.49 -
1.50 - _iter = cookieList.erase(_iter);
1.51 }
1.52 +
1.53 + cookieList.clear();
1.54 }
1.55
1.56 Cookie *CookieManager::FindCookie(const char *name)
1.57 @@ -116,9 +108,7 @@
1.58 if (pCookie != NULL)
1.59 {
1.60 /* Update data fields to the provided values */
1.61 - strncpy(pCookie->description, description, MAX_DESC_LENGTH);
1.62 - pCookie->description[MAX_DESC_LENGTH-1] = '\0';
1.63 -
1.64 + UTIL_strncpy(pCookie->description, description, MAX_DESC_LENGTH);
1.65 pCookie->access = access;
1.66
1.67 return pCookie;
1.68 @@ -126,18 +116,15 @@
1.69
1.70 /* First time cookie - Create from scratch */
1.71 pCookie = new Cookie(name, description, access);
1.72 + pCookie->usedInQuery++;
1.73 +
1.74 + /* Attempt to insert cookie into the db and get its ID num */
1.75 + TQueryOp *op = new TQueryOp(Query_InsertCookie, pCookie);
1.76 + op->m_params.cookie = pCookie;
1.77 +
1.78 cookieTrie.insert(name, pCookie);
1.79 cookieList.push_back(pCookie);
1.80
1.81 - /* Attempt to insert cookie into the db and get its ID num */
1.82 -
1.83 - TQueryOp *op = new TQueryOp(Query_InsertCookie, pCookie);
1.84 -
1.85 - g_ClientPrefs.cookieMutex->Lock();
1.86 - op->m_params.cookie = pCookie;
1.87 - pCookie->usedInQuery++;
1.88 - g_ClientPrefs.cookieMutex->Unlock();
1.89 -
1.90 g_ClientPrefs.AddQueryToQueue(op);
1.91
1.92 return pCookie;
1.93 @@ -145,8 +132,6 @@
1.94
1.95 bool CookieManager::GetCookieValue(Cookie *pCookie, int client, char **value)
1.96 {
1.97 - assert(pCookie);
1.98 -
1.99 CookieData *data = pCookie->data[client];
1.100
1.101 /* Check if a value has been set before */
1.102 @@ -156,8 +141,8 @@
1.103 data->parent = pCookie;
1.104 clientData[client].push_back(data);
1.105 pCookie->data[client] = data;
1.106 - data->changed = true;
1.107 - data->timestamp = time(NULL);
1.108 + data->changed = false;
1.109 + data->timestamp = 0;
1.110 }
1.111
1.112 *value = &data->value[0];
1.113 @@ -167,8 +152,6 @@
1.114
1.115 bool CookieManager::SetCookieValue(Cookie *pCookie, int client, const char *value)
1.116 {
1.117 - assert(pCookie);
1.118 -
1.119 CookieData *data = pCookie->data[client];
1.120
1.121 if (data == NULL)
1.122 @@ -180,8 +163,7 @@
1.123 }
1.124 else
1.125 {
1.126 - strncpy(data->value, value, MAX_VALUE_LENGTH);
1.127 - data->value[MAX_VALUE_LENGTH-1] = '\0';
1.128 + UTIL_strncpy(data->value, value, MAX_VALUE_LENGTH);
1.129 }
1.130
1.131 data->changed = true;
1.132 @@ -200,9 +182,12 @@
1.133 }
1.134
1.135 connected[client] = true;
1.136 + statsPending[client] = true;
1.137
1.138 + g_ClientPrefs.AttemptReconnection();
1.139 +
1.140 TQueryOp *op = new TQueryOp(Query_SelectData, player->GetSerial());
1.141 - strcpy(op->m_params.steamId, authstring);
1.142 + UTIL_strncpy(op->m_params.steamId, authstring, MAX_NAME_LENGTH);
1.143
1.144 g_ClientPrefs.AddQueryToQueue(op);
1.145 }
1.146 @@ -211,105 +196,103 @@
1.147 {
1.148 connected[client] = false;
1.149 statsLoaded[client] = false;
1.150 -
1.151 - SourceHook::List<CookieData *>::iterator _iter;
1.152 + statsPending[client] = false;
1.153
1.154 CookieData *current;
1.155
1.156 - _iter = clientData[client].begin();
1.157 -
1.158 - while (_iter != clientData[client].end())
1.159 + g_ClientPrefs.AttemptReconnection();
1.160 +
1.161 + /* Save this cookie to the database */
1.162 + IGamePlayer *player = playerhelpers->GetGamePlayer(client);
1.163 + const char *pAuth = NULL;
1.164 + int dbId;
1.165 +
1.166 + if (player)
1.167 {
1.168 + pAuth = player->GetAuthString();
1.169 + }
1.170 +
1.171 + g_ClientPrefs.ClearQueryCache(player->GetSerial());
1.172 +
1.173 + for (SourceHook::List<CookieData *>::iterator _iter = clientData[client].begin();\
1.174 + _iter != clientData[client].end(); _iter++)
1.175 + {
1.176 + if (player == NULL || pAuth == NULL)
1.177 + {
1.178 + /* panic! */
1.179 + current->parent->data[client] = NULL;
1.180 + delete current;
1.181 + continue;
1.182 + }
1.183 +
1.184 current = (CookieData *)*_iter;
1.185 -
1.186 - if (!current->changed)
1.187 + dbId = current->parent->dbid;
1.188 +
1.189 + if (!current->changed || dbId == -1)
1.190 {
1.191 current->parent->data[client] = NULL;
1.192 delete current;
1.193 - _iter = clientData[client].erase(_iter);
1.194 continue;
1.195 }
1.196
1.197 - /* Save this cookie to the database */
1.198 - IGamePlayer *player = playerhelpers->GetGamePlayer(client);
1.199 -
1.200 - if (player == NULL)
1.201 - {
1.202 - /* panic! */
1.203 - return;
1.204 - }
1.205 -
1.206 - int dbId = current->parent->dbid;
1.207 -
1.208 - if (dbId == -1)
1.209 - {
1.210 - /* Insert/Find Query must be still running or failed. */
1.211 - return;
1.212 - }
1.213 -
1.214 TQueryOp *op = new TQueryOp(Query_InsertData, client);
1.215
1.216 - strcpy(op->m_params.steamId, player->GetAuthString());
1.217 + UTIL_strncpy(op->m_params.steamId, pAuth, MAX_NAME_LENGTH);
1.218 op->m_params.cookieId = dbId;
1.219 op->m_params.data = current;
1.220
1.221 g_ClientPrefs.AddQueryToQueue(op);
1.222
1.223 current->parent->data[client] = NULL;
1.224 -
1.225 -
1.226 - /* We don't delete here, it will be removed when the query is completed */
1.227 -
1.228 - _iter = clientData[client].erase(_iter);
1.229 }
1.230 +
1.231 + clientData[client].clear();
1.232 }
1.233
1.234 void CookieManager::ClientConnectCallback(int serial, IQuery *data)
1.235 {
1.236 int client;
1.237 - IResultSet *results;
1.238
1.239 /* Check validity of client */
1.240 if ((client = playerhelpers->GetClientFromSerial(serial)) == 0)
1.241 {
1.242 return;
1.243 }
1.244 -
1.245 + statsPending[client] = false;
1.246 +
1.247 + IResultSet *results;
1.248 /* Check validity of results */
1.249 if (data == NULL || (results = data->GetResultSet()) == NULL)
1.250 {
1.251 return;
1.252 }
1.253
1.254 + CookieData *pData;
1.255 IResultRow *row;
1.256 - do
1.257 + unsigned int timestamp;
1.258 + CookieAccess access;
1.259 +
1.260 + while (results->MoreRows() && ((row = results->FetchRow()) != NULL))
1.261 {
1.262 - if ((row = results->FetchRow()) == NULL)
1.263 - {
1.264 - break;
1.265 - }
1.266 -
1.267 - const char *name;
1.268 + const char *name = "";
1.269 row->GetString(0, &name, NULL);
1.270 -
1.271 - const char *value;
1.272 +
1.273 + const char *value = "";
1.274 row->GetString(1, &value, NULL);
1.275
1.276 - CookieData *pData = new CookieData(value);
1.277 + pData = new CookieData(value);
1.278 pData->changed = false;
1.279
1.280 - unsigned int timestamp = 0;
1.281 - row->GetInt(4, (int *)×tamp);
1.282 - pData->timestamp = timestamp;
1.283 + pData->timestamp = (row->GetInt(4, (int *)×tamp) == DBVal_Data) ? timestamp : 0;
1.284
1.285 Cookie *parent = FindCookie(name);
1.286
1.287 if (parent == NULL)
1.288 {
1.289 - const char *desc;
1.290 + const char *desc = "";
1.291 row->GetString(2, &desc, NULL);
1.292
1.293 - CookieAccess access = CookieAccess_Public;
1.294 + access = CookieAccess_Public;
1.295 row->GetInt(3, (int *)&access);
1.296
1.297 parent = CreateCookie(name, desc, access);
1.298 @@ -317,10 +300,8 @@
1.299
1.300 pData->parent = parent;
1.301 parent->data[client] = pData;
1.302 -
1.303 clientData[client].push_back(pData);
1.304 -
1.305 - } while (results->MoreRows());
1.306 + }
1.307
1.308 statsLoaded[client] = true;
1.309
1.310 @@ -338,7 +319,7 @@
1.311
1.312 TQueryOp *op = new TQueryOp(Query_SelectId, pCookie);
1.313 /* Put the cookie name into the steamId field to save space - Make sure we remember that it's there */
1.314 - strcpy(op->m_params.steamId, pCookie->name);
1.315 + UTIL_strncpy(op->m_params.steamId, pCookie->name, MAX_NAME_LENGTH);
1.316 g_ClientPrefs.AddQueryToQueue(op);
1.317 }
1.318
1.319 @@ -366,26 +347,31 @@
1.320 return statsLoaded[client];
1.321 }
1.322
1.323 +bool CookieManager::AreClientCookiesPening(int client)
1.324 +{
1.325 + return statsPending[client];
1.326 +}
1.327 +
1.328 void CookieManager::OnPluginDestroyed(IPlugin *plugin)
1.329 {
1.330 SourceHook::List<char *> *pList;
1.331
1.332 if (plugin->GetProperty("SettingsMenuItems", (void **)&pList, true))
1.333 {
1.334 - SourceHook::List<char *>::iterator p_iter = pList->begin();
1.335 char *name;
1.336 -
1.337 - while (p_iter != pList->end())
1.338 + ItemDrawInfo draw;
1.339 + const char *info;
1.340 + AutoMenuData * data;
1.341 + unsigned itemcount;
1.342 +
1.343 + for (SourceHook::List<char *>::iterator p_iter = pList->begin(); p_iter != pList->end(); p_iter++)
1.344 {
1.345 name = (char *)*p_iter;
1.346 -
1.347 - p_iter = pList->erase(p_iter); //remove from this plugins list
1.348 -
1.349 - ItemDrawInfo draw;
1.350 -
1.351 - for (unsigned int i=0; i<clientMenu->GetItemCount(); i++)
1.352 + itemcount = clientMenu->GetItemCount();
1.353 + //remove from this plugins list
1.354 + for (unsigned int i=0; i < itemcount; i++)
1.355 {
1.356 - const char *info = clientMenu->GetItemInfo(i, &draw);
1.357 + info = clientMenu->GetItemInfo(i, &draw);
1.358
1.359 if (info == NULL)
1.360 {
1.361 @@ -394,9 +380,7 @@
1.362
1.363 if (strcmp(draw.display, name) == 0)
1.364 {
1.365 - ItemDrawInfo draw;
1.366 - const char *info = clientMenu->GetItemInfo(i, &draw);
1.367 - AutoMenuData *data = (AutoMenuData *)strtoul(info, NULL, 16);
1.368 + data = (AutoMenuData *)strtoul(info, NULL, 16);
1.369
1.370 if (data->handler->forward != NULL)
1.371 {
1.372 @@ -410,15 +394,15 @@
1.373 }
1.374 }
1.375
1.376 - delete name;
1.377 - }
1.378 + delete [] name;
1.379 + }
1.380 +
1.381 + pList->clear();
1.382 }
1.383 }
1.384
1.385 bool CookieManager::GetCookieTime(Cookie *pCookie, int client, time_t *value)
1.386 {
1.387 - assert(pCookie);
1.388 -
1.389 CookieData *data = pCookie->data[client];
1.390
1.391 /* Check if a value has been set before */
2.1 --- a/extensions/clientprefs/cookie.h Mon Feb 25 20:44:16 2013 -0600
2.2 +++ b/extensions/clientprefs/cookie.h Thu Feb 28 21:51:49 2013 +0000
2.3 @@ -54,11 +54,10 @@
2.4 {
2.5 CookieData(const char *value)
2.6 {
2.7 - strncpy(this->value, value, MAX_VALUE_LENGTH);
2.8 - this->value[MAX_VALUE_LENGTH-1] = '\0';
2.9 + UTIL_strncpy(this->value, value, MAX_VALUE_LENGTH);
2.10 }
2.11
2.12 - char value[MAX_VALUE_LENGTH];
2.13 + char value[MAX_VALUE_LENGTH+1];
2.14 bool changed;
2.15 time_t timestamp;
2.16 Cookie *parent;
2.17 @@ -68,10 +67,8 @@
2.18 {
2.19 Cookie(const char *name, const char *description, CookieAccess access)
2.20 {
2.21 - strncpy(this->name, name, MAX_NAME_LENGTH);
2.22 - this->name[MAX_NAME_LENGTH-1] = '\0';
2.23 - strncpy(this->description, description, MAX_DESC_LENGTH);
2.24 - this->description[MAX_DESC_LENGTH-1] = '\0';
2.25 + UTIL_strncpy(this->name, name, MAX_NAME_LENGTH);
2.26 + UTIL_strncpy(this->description, description, MAX_DESC_LENGTH);
2.27
2.28 this->access = access;
2.29
2.30 @@ -97,8 +94,8 @@
2.31 }
2.32 }
2.33
2.34 - char name[MAX_NAME_LENGTH];
2.35 - char description[MAX_DESC_LENGTH];
2.36 + char name[MAX_NAME_LENGTH+1];
2.37 + char description[MAX_DESC_LENGTH+1];
2.38 int dbid;
2.39 CookieData *data[MAXCLIENTS+1];
2.40 CookieAccess access;
2.41 @@ -133,6 +130,8 @@
2.42 bool AreClientCookiesCached(int client);
2.43
2.44 void OnPluginDestroyed(IPlugin *plugin);
2.45 +
2.46 + bool AreClientCookiesPening(int client);
2.47
2.48 public:
2.49 IForward *cookieDataLoadedForward;
2.50 @@ -145,6 +144,7 @@
2.51
2.52 bool connected[MAXCLIENTS+1];
2.53 bool statsLoaded[MAXCLIENTS+1];
2.54 + bool statsPending[MAXCLIENTS+1];
2.55 };
2.56
2.57 extern CookieManager g_CookieManager;
3.1 --- a/extensions/clientprefs/extension.cpp Mon Feb 25 20:44:16 2013 -0600
3.2 +++ b/extensions/clientprefs/extension.cpp Thu Feb 28 21:51:49 2013 +0000
3.3 @@ -47,7 +47,6 @@
3.4 HandleType_t g_CookieIterator = 0;
3.5 CookieIteratorHandler g_CookieIteratorHandler;
3.6 DbDriver g_DriverType;
3.7 -static const DatabaseInfo *storage_local = NULL;
3.8
3.9 bool ClientPrefs::SDK_OnLoad(char *error, size_t maxlength, bool late)
3.10 {
3.11 @@ -60,28 +59,19 @@
3.12 {
3.13 DBInfo = dbi->FindDatabaseConf("default");
3.14
3.15 - if (DBInfo == NULL ||
3.16 - (strcmp(DBInfo->host, "localhost") == 0 &&
3.17 - strcmp(DBInfo->database, "sourcemod") == 0 &&
3.18 - strcmp(DBInfo->user, "root") == 0 &&
3.19 - strcmp(DBInfo->pass, "") == 0 &&
3.20 - strcmp(DBInfo->driver, "") == 0))
3.21 - {
3.22 - storage_local = dbi->FindDatabaseConf("storage-local");
3.23 - if (DBInfo == NULL)
3.24 - {
3.25 - DBInfo = storage_local;
3.26 - }
3.27 - }
3.28 -
3.29 if (DBInfo == NULL)
3.30 {
3.31 - snprintf(error, maxlength, "Could not find \"clientprefs\" or \"default\" database configs");
3.32 - return false;
3.33 + DBInfo = dbi->FindDatabaseConf("storage-local");
3.34 }
3.35 }
3.36 +
3.37 + if (DBInfo == NULL)
3.38 + {
3.39 + snprintf(error, maxlength, "Could not find any suitable database configs");
3.40 + return false;
3.41 + }
3.42
3.43 - if (DBInfo->driver[0] != '\0')
3.44 + if (DBInfo->driver && DBInfo->driver[0] != '\0')
3.45 {
3.46 Driver = dbi->FindOrLoadDriver(DBInfo->driver);
3.47 }
3.48 @@ -96,7 +86,6 @@
3.49 return false;
3.50 }
3.51
3.52 - Database = NULL;
3.53 databaseLoading = true;
3.54 TQueryOp *op = new TQueryOp(Query_Connect, 0);
3.55 dbi->AddToThreadQueue(op, PrioQueue_High);
3.56 @@ -136,19 +125,7 @@
3.57
3.58 if (late)
3.59 {
3.60 - int maxclients = playerhelpers->GetMaxClients();
3.61 -
3.62 - for (int i = 1; i <= maxclients; i++)
3.63 - {
3.64 - IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(i);
3.65 -
3.66 - if (!pPlayer || !pPlayer->IsAuthorized())
3.67 - {
3.68 - continue;
3.69 - }
3.70 -
3.71 - g_CookieManager.OnClientAuthorized(i, pPlayer->GetAuthString());
3.72 - }
3.73 + this->CatchLateLoadClients();
3.74 }
3.75
3.76 return true;
3.77 @@ -188,20 +165,37 @@
3.78 if (Database != NULL)
3.79 {
3.80 Database->Close();
3.81 + Database = NULL;
3.82 + }
3.83 +
3.84 + if (g_CookieManager.cookieDataLoadedForward != NULL)
3.85 + {
3.86 + forwards->ReleaseForward(g_CookieManager.cookieDataLoadedForward);
3.87 + g_CookieManager.cookieDataLoadedForward = NULL;
3.88 }
3.89
3.90 - forwards->ReleaseForward(g_CookieManager.cookieDataLoadedForward);
3.91 -
3.92 - HandleSecurity sec = HandleSecurity(identity, identity);
3.93 - HandleError err = handlesys->FreeHandle(g_CookieManager.clientMenu->GetHandle(), &sec);
3.94 - if (HandleError_None != err)
3.95 + if (g_CookieManager.clientMenu != NULL)
3.96 {
3.97 - g_pSM->LogError(myself, "Error %d when attempting to free client menu handle", err);
3.98 + Handle_t menuHandle = g_CookieManager.clientMenu->GetHandle();
3.99 +
3.100 + if (menuHandle != BAD_HANDLE)
3.101 + {
3.102 + HandleSecurity sec = HandleSecurity(identity, identity);
3.103 + HandleError err = handlesys->FreeHandle(menuHandle, &sec);
3.104 + if (HandleError_None != err)
3.105 + {
3.106 + g_pSM->LogError(myself, "Error %d when attempting to free client menu handle", err);
3.107 + }
3.108 + }
3.109 +
3.110 + g_CookieManager.clientMenu = NULL;
3.111 }
3.112
3.113 - phrases->Destroy();
3.114 -
3.115 - sharesys->DestroyIdentity( identity );
3.116 + if (phrases != NULL)
3.117 + {
3.118 + phrases->Destroy();
3.119 + phrases = NULL;
3.120 + }
3.121
3.122 plsys->RemovePluginsListener(&g_CookieManager);
3.123 playerhelpers->RemoveClientListener(&g_CookieManager);
3.124 @@ -212,15 +206,23 @@
3.125
3.126 void ClientPrefs::OnCoreMapStart(edict_t *pEdictList, int edictCount, int clientMax)
3.127 {
3.128 - if (Database == NULL && !databaseLoading)
3.129 + this->AttemptReconnection();
3.130 +}
3.131 +
3.132 +void ClientPrefs::AttemptReconnection()
3.133 +{
3.134 + if (Database || databaseLoading)
3.135 {
3.136 - g_pSM->LogMessage(myself, "Attempting to reconnect to database...");
3.137 -
3.138 - databaseLoading = true;
3.139 -
3.140 - TQueryOp *op = new TQueryOp(Query_Connect, 0);
3.141 - dbi->AddToThreadQueue(op, PrioQueue_High);
3.142 + return; /* We're already loading, or have loaded. */
3.143 }
3.144 +
3.145 + g_pSM->LogMessage(myself, "Attempting to reconnect to database...");
3.146 + databaseLoading = true;
3.147 +
3.148 + TQueryOp *op = new TQueryOp(Query_Connect, 0);
3.149 + dbi->AddToThreadQueue(op, PrioQueue_High);
3.150 +
3.151 + this->CatchLateLoadClients(); /* DB reconnection, we should check if we missed anyone... */
3.152 }
3.153
3.154 void ClientPrefs::DatabaseConnect()
3.155 @@ -230,19 +232,10 @@
3.156
3.157 Database = Driver->Connect(DBInfo, true, error, sizeof(error));
3.158
3.159 - if (Database == NULL &&
3.160 - DBInfo != storage_local &&
3.161 - storage_local != NULL)
3.162 - {
3.163 - DBInfo = storage_local;
3.164 - Database = Driver->Connect(DBInfo, true, error, sizeof(error));
3.165 - }
3.166 -
3.167 if (Database == NULL)
3.168 {
3.169 g_pSM->LogError(myself, error);
3.170 databaseLoading = false;
3.171 - ProcessQueryCache();
3.172 return;
3.173 }
3.174
3.175 @@ -319,87 +312,76 @@
3.176
3.177 databaseLoading = false;
3.178
3.179 - ProcessQueryCache();
3.180 -
3.181 + this->ProcessQueryCache();
3.182 return;
3.183
3.184 fatal_fail:
3.185 Database->Close();
3.186 Database = NULL;
3.187 databaseLoading = false;
3.188 - ProcessQueryCache();
3.189 }
3.190
3.191 bool ClientPrefs::AddQueryToQueue( TQueryOp *query )
3.192 {
3.193 queryMutex->Lock();
3.194 -
3.195 - if (Database == NULL && databaseLoading)
3.196 + if (Database == NULL)
3.197 {
3.198 cachedQueries.push_back(query);
3.199 queryMutex->Unlock();
3.200 - return true;
3.201 + return false;
3.202 + }
3.203 +
3.204 + if (!cachedQueries.empty())
3.205 + {
3.206 + queryMutex->Unlock();
3.207 + this->ProcessQueryCache();
3.208 + }
3.209 + else
3.210 + {
3.211 + queryMutex->Unlock();
3.212 }
3.213
3.214 - queryMutex->Unlock();
3.215 -
3.216 - if (Database)
3.217 - {
3.218 - query->SetDatabase(Database);
3.219 - dbi->AddToThreadQueue(query, PrioQueue_Normal);
3.220 - return true;
3.221 - }
3.222 -
3.223 - query->Destroy();
3.224 -
3.225 - /* If Database is NULL and we're not in the loading phase it must have failed - Can't do much */
3.226 - return false;
3.227 + query->SetDatabase(Database);
3.228 + dbi->AddToThreadQueue(query, PrioQueue_Normal);
3.229 + return true;
3.230 }
3.231
3.232 void ClientPrefs::ProcessQueryCache()
3.233 {
3.234 - SourceHook::List<TQueryOp *>::iterator iter;
3.235 + if (Database == NULL)
3.236 + {
3.237 + return;
3.238 + }
3.239
3.240 queryMutex->Lock();
3.241 -
3.242 - iter = cachedQueries.begin();
3.243 -
3.244 - while (iter != cachedQueries.end())
3.245 + TQueryOp *op;
3.246 + for (SourceHook::List<TQueryOp *>::iterator iter = cachedQueries.begin(); iter != cachedQueries.end(); iter++)
3.247 {
3.248 - TQueryOp *op = *iter;
3.249 -
3.250 - if (Database != NULL)
3.251 - {
3.252 - op->SetDatabase(Database);
3.253 - dbi->AddToThreadQueue(op, PrioQueue_Normal);
3.254 - }
3.255 - else
3.256 - {
3.257 - op->Destroy();
3.258 - }
3.259 -
3.260 - iter++;
3.261 + op = *iter;
3.262 + op->SetDatabase(Database);
3.263 + dbi->AddToThreadQueue(op, PrioQueue_Normal);
3.264 }
3.265
3.266 cachedQueries.clear();
3.267 -
3.268 queryMutex->Unlock();
3.269 }
3.270
3.271 size_t IsAuthIdConnected(char *authID)
3.272 {
3.273 IGamePlayer *player;
3.274 - int maxPlayers = playerhelpers->GetMaxClients();
3.275 -
3.276 - for (int playerIndex = 1; playerIndex <= maxPlayers; playerIndex++)
3.277 + const char *authString;
3.278 +
3.279 + for (int playerIndex = playerhelpers->GetMaxClients()+1; --playerIndex > 0;)
3.280 {
3.281 player = playerhelpers->GetGamePlayer(playerIndex);
3.282 - if (!player || !player->IsConnected())
3.283 + if (player == NULL || !player->IsConnected())
3.284 {
3.285 continue;
3.286 }
3.287 - const char *authString = player->GetAuthString();
3.288 - if (!authString || authString[0] == '\0')
3.289 +
3.290 + authString = player->GetAuthString();
3.291 +
3.292 + if (authString == NULL || authString[0] == '\0')
3.293 {
3.294 continue;
3.295 }
3.296 @@ -412,22 +394,45 @@
3.297 return 0;
3.298 }
3.299
3.300 -size_t UTIL_Format(char *buffer, size_t maxlength, const char *fmt, ...)
3.301 +void ClientPrefs::CatchLateLoadClients()
3.302 {
3.303 - va_list ap;
3.304 - va_start(ap, fmt);
3.305 - size_t len = vsnprintf(buffer, maxlength, fmt, ap);
3.306 - va_end(ap);
3.307 + IGamePlayer *pPlayer;
3.308 + for (int i = playerhelpers->GetMaxClients()+1; --i > 0;)
3.309 + {
3.310 + if (g_CookieManager.AreClientCookiesPening(i) || g_CookieManager.AreClientCookiesCached(i))
3.311 + {
3.312 + continue;
3.313 + }
3.314 +
3.315 + pPlayer = playerhelpers->GetGamePlayer(i);
3.316 +
3.317 + if (!pPlayer || !pPlayer->IsAuthorized())
3.318 + {
3.319 + continue;
3.320 + }
3.321
3.322 - if (len >= maxlength)
3.323 - {
3.324 - buffer[maxlength - 1] = '\0';
3.325 - return (maxlength - 1);
3.326 + g_CookieManager.OnClientAuthorized(i, pPlayer->GetAuthString());
3.327 }
3.328 - else
3.329 +}
3.330 +
3.331 +void ClientPrefs::ClearQueryCache(int serial)
3.332 +{
3.333 + queryMutex->Lock();
3.334 +
3.335 + for (SourceHook::List<TQueryOp *>::iterator iter = cachedQueries.begin(); iter != cachedQueries.end();)
3.336 {
3.337 - return len;
3.338 - }
3.339 + TQueryOp *op = *iter;
3.340 + if (op && op->PullQueryType() == Query_SelectData && op->PullQuerySerial() == serial)
3.341 + {
3.342 + op->Destroy();
3.343 + iter = cachedQueries.erase(iter);
3.344 + }
3.345 + else
3.346 + {
3.347 + iter++;
3.348 + }
3.349 + }
3.350 + queryMutex->Unlock();
3.351 }
3.352
3.353 bool Translate(char *buffer,
3.354 @@ -478,6 +483,30 @@
3.355 return true;
3.356 }
3.357
3.358 +char * UTIL_strncpy(char * destination, const char * source, size_t num)
3.359 +{
3.360 + if (source == NULL)
3.361 + {
3.362 + destination[0] = '\0';
3.363 + return destination;
3.364 + }
3.365 +
3.366 + size_t req = strlen(source);
3.367 + if (!req)
3.368 + {
3.369 + destination[0] = '\0';
3.370 + return destination;
3.371 + }
3.372 + else if (req >= num)
3.373 + {
3.374 + req = num-1;
3.375 + }
3.376 +
3.377 + strncpy(destination, source, req);
3.378 + destination[req] = '\0';
3.379 + return destination;
3.380 +}
3.381 +
3.382 IdentityToken_t *ClientPrefs::GetIdentity() const
3.383 {
3.384 return identity;
3.385 @@ -493,3 +522,15 @@
3.386 return SM_BUILD_TIMESTAMP;
3.387 }
3.388
3.389 +ClientPrefs::ClientPrefs()
3.390 +{
3.391 + Driver = NULL;
3.392 + Database = NULL;
3.393 + databaseLoading = false;
3.394 + phrases = NULL;
3.395 + DBInfo = NULL;
3.396 +
3.397 + cookieMutex = NULL;
3.398 + queryMutex = NULL;
3.399 + identity = NULL;
3.400 +}
4.1 --- a/extensions/clientprefs/extension.h Mon Feb 25 20:44:16 2013 -0600
4.2 +++ b/extensions/clientprefs/extension.h Thu Feb 28 21:51:49 2013 +0000
4.3 @@ -38,6 +38,9 @@
4.4 #include <stdarg.h>
4.5 #include "smsdk_ext.h"
4.6 #include "sh_list.h"
4.7 +
4.8 +char * UTIL_strncpy(char * destination, const char * source, size_t num);
4.9 +
4.10 #include "cookie.h"
4.11 #include "menus.h"
4.12 #include "query.h"
4.13 @@ -59,6 +62,8 @@
4.14 class ClientPrefs : public SDKExtension
4.15 {
4.16 public:
4.17 + ClientPrefs();
4.18 +public:
4.19 /**
4.20 * @brief This is called after the initial loading sequence has been processed.
4.21 *
4.22 @@ -93,6 +98,10 @@
4.23
4.24 bool AddQueryToQueue(TQueryOp *query);
4.25 void ProcessQueryCache();
4.26 +
4.27 + void AttemptReconnection();
4.28 + void CatchLateLoadClients();
4.29 + void ClearQueryCache(int serial);
4.30
4.31 /**
4.32 * @brief Called when the pause state is changed.
4.33 @@ -145,11 +154,11 @@
4.34 public:
4.35 IDBDriver *Driver;
4.36 IDatabase *Database;
4.37 - bool databaseLoading;
4.38 IPhraseCollection *phrases;
4.39 const DatabaseInfo *DBInfo;
4.40
4.41 IMutex *cookieMutex;
4.42 + bool databaseLoading;
4.43
4.44 private:
4.45 SourceHook::List<TQueryOp *> cachedQueries;
4.46 @@ -177,8 +186,6 @@
4.47
4.48 size_t IsAuthIdConnected(char *authID);
4.49
4.50 -size_t UTIL_Format(char *buffer, size_t maxlength, const char *fmt, ...);
4.51 -
4.52 extern sp_nativeinfo_t g_ClientPrefNatives[];
4.53
4.54 extern ClientPrefs g_ClientPrefs;
5.1 --- a/extensions/clientprefs/menus.cpp Mon Feb 25 20:44:16 2013 -0600
5.2 +++ b/extensions/clientprefs/menus.cpp Thu Feb 28 21:51:49 2013 +0000
5.3 @@ -99,7 +99,7 @@
5.4 if (data->handler->forward != NULL)
5.5 {
5.6 char buffer[100];
5.7 - UTIL_Format(buffer, sizeof(buffer), "%s", dr.display);
5.8 + g_pSM->Format(buffer, sizeof(buffer), "%s", dr.display);
5.9
5.10 data->handler->forward->PushCell(client);
5.11 data->handler->forward->PushCell(CookieMenuAction_DisplayOption);
5.12 @@ -118,53 +118,15 @@
5.13
5.14 void AutoMenuHandler::OnMenuSelect(SourceMod::IBaseMenu *menu, int client, unsigned int item)
5.15 {
5.16 + static const char settings[CookieMenu_Elements][2][4] = { {"yes", "no"}, {"1", "0"}, {"on", "off"}, {"1", "0"} };
5.17 ItemDrawInfo draw;
5.18
5.19 const char *info = menu->GetItemInfo(item, &draw);
5.20
5.21 AutoMenuData *data = (AutoMenuData *)strtoul(info, NULL, 16);
5.22
5.23 - switch (data->type)
5.24 - {
5.25 - case CookieMenu_YesNo:
5.26 - {
5.27 - if (item == 0)
5.28 - {
5.29 - g_CookieManager.SetCookieValue(data->pCookie, client, "yes");
5.30 - }
5.31 - else
5.32 - {
5.33 - g_CookieManager.SetCookieValue(data->pCookie, client, "no");
5.34 - }
5.35 - break;
5.36 - }
5.37 - case CookieMenu_YesNo_Int:
5.38 - case CookieMenu_OnOff_Int:
5.39 - {
5.40 - if (item == 0)
5.41 - {
5.42 - g_CookieManager.SetCookieValue(data->pCookie, client, "1");
5.43 - }
5.44 - else
5.45 - {
5.46 - g_CookieManager.SetCookieValue(data->pCookie, client, "0");
5.47 - }
5.48 - break;
5.49 - }
5.50 - case CookieMenu_OnOff:
5.51 - {
5.52 - if (item == 0)
5.53 - {
5.54 - g_CookieManager.SetCookieValue(data->pCookie, client, "on");
5.55 - }
5.56 - else
5.57 - {
5.58 - g_CookieManager.SetCookieValue(data->pCookie, client, "off");
5.59 - }
5.60 - break;
5.61 - }
5.62 - }
5.63 -
5.64 + g_CookieManager.SetCookieValue(data->pCookie, client, settings[data->type][item]);
5.65 +
5.66 char message[255];
5.67 char *value;
5.68 g_CookieManager.GetCookieValue(data->pCookie, client, &value);
6.1 --- a/extensions/clientprefs/menus.h Mon Feb 25 20:44:16 2013 -0600
6.2 +++ b/extensions/clientprefs/menus.h Thu Feb 28 21:51:49 2013 +0000
6.3 @@ -59,13 +59,14 @@
6.4 CookieMenu_YesNo_Int, /**< Yes/No menu with 1/0 saved into the cookie */
6.5 CookieMenu_OnOff, /**< On/Off menu with "on"/"off" results saved into the cookie */
6.6 CookieMenu_OnOff_Int, /**< On/Off menu with 1/0 saved into the cookie */
6.7 + CookieMenu_Elements
6.8 };
6.9
6.10 struct ItemHandler
6.11 {
6.12 - bool isAutoMenu;
6.13 IChangeableForward *forward;
6.14 CookieMenu autoMenuType;
6.15 + bool isAutoMenu;
6.16 };
6.17
6.18 class ClientMenuHandler : public IMenuHandler
6.19 @@ -96,8 +97,8 @@
6.20 {
6.21 ItemHandler *handler;
6.22 Cookie *pCookie;
6.23 + cell_t datavalue;
6.24 CookieMenu type;
6.25 - cell_t datavalue;
6.26 };
6.27
6.28 #endif // _INCLUDE_SOURCEMOD_CLIENTPREFS_MENUS_H_
7.1 --- a/extensions/clientprefs/natives.cpp Mon Feb 25 20:44:16 2013 -0600
7.2 +++ b/extensions/clientprefs/natives.cpp Thu Feb 28 21:51:49 2013 +0000
7.3 @@ -35,10 +35,7 @@
7.4
7.5 cell_t RegClientPrefCookie(IPluginContext *pContext, const cell_t *params)
7.6 {
7.7 - if (g_ClientPrefs.Database == NULL && !g_ClientPrefs.databaseLoading)
7.8 - {
7.9 - return pContext->ThrowNativeError("Clientprefs is disabled due to a failed database connection");
7.10 - }
7.11 + g_ClientPrefs.AttemptReconnection();
7.12
7.13 char *name;
7.14 pContext->LocalToString(params[1], &name);
7.15 @@ -67,10 +64,7 @@
7.16
7.17 cell_t FindClientPrefCookie(IPluginContext *pContext, const cell_t *params)
7.18 {
7.19 - if (g_ClientPrefs.Database == NULL && !g_ClientPrefs.databaseLoading)
7.20 - {
7.21 - return pContext->ThrowNativeError("Clientprefs is disabled due to a failed database connection");
7.22 - }
7.23 + g_ClientPrefs.AttemptReconnection();
7.24
7.25 char *name;
7.26 pContext->LocalToString(params[1], &name);
7.27 @@ -91,10 +85,7 @@
7.28
7.29 cell_t SetAuthIdCookie(IPluginContext *pContext, const cell_t *params)
7.30 {
7.31 - if (g_ClientPrefs.Database == NULL && !g_ClientPrefs.databaseLoading)
7.32 - {
7.33 - return pContext->ThrowNativeError("Clientprefs is disabled due to a failed database connection");
7.34 - }
7.35 + g_ClientPrefs.AttemptReconnection();
7.36
7.37 char *steamID;
7.38 pContext->LocalToString(params[1], &steamID);
7.39 @@ -136,8 +127,7 @@
7.40 // edit database table
7.41 TQueryOp *op = new TQueryOp(Query_InsertData, pCookie);
7.42 // limit player auth length which doubles for cookie name length
7.43 - strncpy(op->m_params.steamId, steamID, MAX_NAME_LENGTH);
7.44 - op->m_params.steamId[MAX_NAME_LENGTH-1] = '\0';
7.45 + UTIL_strncpy(op->m_params.steamId, steamID, MAX_NAME_LENGTH);
7.46 op->m_params.cookieId = i_dbId;
7.47 op->m_params.data = payload;
7.48
7.49 @@ -148,10 +138,7 @@
7.50
7.51 cell_t SetClientPrefCookie(IPluginContext *pContext, const cell_t *params)
7.52 {
7.53 - if (g_ClientPrefs.Database == NULL && !g_ClientPrefs.databaseLoading)
7.54 - {
7.55 - return pContext->ThrowNativeError("Clientprefs is disabled due to a failed database connection");
7.56 - }
7.57 + g_ClientPrefs.AttemptReconnection();
7.58
7.59 int client = params[1];
7.60
7.61 @@ -183,10 +170,7 @@
7.62
7.63 cell_t GetClientPrefCookie(IPluginContext *pContext, const cell_t *params)
7.64 {
7.65 - if (g_ClientPrefs.Database == NULL && !g_ClientPrefs.databaseLoading)
7.66 - {
7.67 - return pContext->ThrowNativeError("Clientprefs is disabled due to a failed database connection");
7.68 - }
7.69 + g_ClientPrefs.AttemptReconnection();
7.70
7.71 int client = params[1];
7.72
7.73 @@ -221,10 +205,7 @@
7.74
7.75 cell_t AreClientCookiesCached(IPluginContext *pContext, const cell_t *params)
7.76 {
7.77 - if (g_ClientPrefs.Database == NULL && !g_ClientPrefs.databaseLoading)
7.78 - {
7.79 - return pContext->ThrowNativeError("Clientprefs is disabled due to a failed database connection");
7.80 - }
7.81 + g_ClientPrefs.AttemptReconnection();
7.82
7.83 int client = params[1];
7.84
7.85 @@ -238,10 +219,7 @@
7.86
7.87 cell_t GetCookieAccess(IPluginContext *pContext, const cell_t *params)
7.88 {
7.89 - if (g_ClientPrefs.Database == NULL && !g_ClientPrefs.databaseLoading)
7.90 - {
7.91 - return pContext->ThrowNativeError("Clientprefs is disabled due to a failed database connection");
7.92 - }
7.93 + g_ClientPrefs.AttemptReconnection();
7.94
7.95 Handle_t hndl = static_cast<Handle_t>(params[1]);
7.96 HandleError err;
7.97 @@ -263,10 +241,7 @@
7.98
7.99 static cell_t GetCookieIterator(IPluginContext *pContext, const cell_t *params)
7.100 {
7.101 - if (g_ClientPrefs.Database == NULL && !g_ClientPrefs.databaseLoading)
7.102 - {
7.103 - return pContext->ThrowNativeError("Clientprefs is disabled due to a failed database connection");
7.104 - }
7.105 + g_ClientPrefs.AttemptReconnection();
7.106
7.107 SourceHook::List<Cookie *>::iterator *iter = new SourceHook::List<Cookie *>::iterator;
7.108 *iter = g_CookieManager.cookieList.begin();
7.109 @@ -282,10 +257,7 @@
7.110
7.111 static cell_t ReadCookieIterator(IPluginContext *pContext, const cell_t *params)
7.112 {
7.113 - if (g_ClientPrefs.Database == NULL && !g_ClientPrefs.databaseLoading)
7.114 - {
7.115 - return pContext->ThrowNativeError("Clientprefs is disabled due to a failed database connection");
7.116 - }
7.117 + g_ClientPrefs.AttemptReconnection();
7.118
7.119 SourceHook::List<Cookie *>::iterator *iter;
7.120
7.121 @@ -323,10 +295,7 @@
7.122
7.123 cell_t ShowSettingsMenu(IPluginContext *pContext, const cell_t *params)
7.124 {
7.125 - if (g_ClientPrefs.Database == NULL && !g_ClientPrefs.databaseLoading)
7.126 - {
7.127 - return pContext->ThrowNativeError("Clientprefs is disabled due to a failed database connection");
7.128 - }
7.129 + g_ClientPrefs.AttemptReconnection();
7.130
7.131 char message[256];
7.132 Translate(message, sizeof(message), "%T:", 2, NULL, "Client Settings", ¶ms[1]);
7.133 @@ -339,10 +308,7 @@
7.134
7.135 cell_t AddSettingsMenuItem(IPluginContext *pContext, const cell_t *params)
7.136 {
7.137 - if (g_ClientPrefs.Database == NULL && !g_ClientPrefs.databaseLoading)
7.138 - {
7.139 - return pContext->ThrowNativeError("Clientprefs is disabled due to a failed database connection");
7.140 - }
7.141 + g_ClientPrefs.AttemptReconnection();
7.142
7.143 char *display;
7.144 pContext->LocalToString(params[3], &display);
7.145 @@ -358,7 +324,7 @@
7.146 AutoMenuData *data = new AutoMenuData;
7.147 data->datavalue = params[2];
7.148 data->handler = pItem;
7.149 - UTIL_Format(info, sizeof(info), "%x", data);
7.150 + g_pSM->Format(info, sizeof(info), "%x", data);
7.151
7.152 ItemDrawInfo draw(display, 0);
7.153
7.154 @@ -376,7 +342,7 @@
7.155 }
7.156
7.157 char *copyarray = new char[strlen(display)+1];
7.158 - UTIL_Format(copyarray, strlen(display)+1, "%s", display);
7.159 + g_pSM->Format(copyarray, strlen(display)+1, "%s", display);
7.160
7.161 pList->push_back(copyarray);
7.162
7.163 @@ -385,10 +351,7 @@
7.164
7.165 cell_t AddSettingsPrefabMenuItem(IPluginContext *pContext, const cell_t *params)
7.166 {
7.167 - if (g_ClientPrefs.Database == NULL && !g_ClientPrefs.databaseLoading)
7.168 - {
7.169 - return pContext->ThrowNativeError("Clientprefs is disabled due to a failed database connection");
7.170 - }
7.171 + g_ClientPrefs.AttemptReconnection();
7.172
7.173 Handle_t hndl = static_cast<Handle_t>(params[1]);
7.174 HandleError err;
7.175 @@ -433,7 +396,7 @@
7.176 data->pCookie = pCookie;
7.177 data->type = (CookieMenu)params[2];
7.178 data->handler = pItem;
7.179 - UTIL_Format(info, sizeof(info), "%x", data);
7.180 + g_pSM->Format(info, sizeof(info), "%x", data);
7.181
7.182 g_CookieManager.clientMenu->AppendItem(info, draw);
7.183
7.184 @@ -449,7 +412,7 @@
7.185 }
7.186
7.187 char *copyarray = new char[strlen(display)+1];
7.188 - UTIL_Format(copyarray, strlen(display)+1, "%s", display);
7.189 + g_pSM->Format(copyarray, strlen(display)+1, "%s", display);
7.190
7.191 pList->push_back(copyarray);
7.192
7.193 @@ -458,10 +421,7 @@
7.194
7.195 cell_t GetClientCookieTime(IPluginContext *pContext, const cell_t *params)
7.196 {
7.197 - if (g_ClientPrefs.Database == NULL && !g_ClientPrefs.databaseLoading)
7.198 - {
7.199 - return pContext->ThrowNativeError("Clientprefs is disabled due to a failed database connection");
7.200 - }
7.201 + g_ClientPrefs.AttemptReconnection();
7.202
7.203 Handle_t hndl = static_cast<Handle_t>(params[2]);
7.204 HandleError err;
8.1 --- a/extensions/clientprefs/query.cpp Mon Feb 25 20:44:16 2013 -0600
8.2 +++ b/extensions/clientprefs/query.cpp Thu Feb 28 21:51:49 2013 +0000
8.3 @@ -35,12 +35,6 @@
8.4 void TQueryOp::RunThinkPart()
8.5 {
8.6 //handler for threaded sql queries
8.7 -
8.8 - if (m_type == Query_Connect)
8.9 - {
8.10 - return;
8.11 - }
8.12 -
8.13 switch (m_type)
8.14 {
8.15 case Query_InsertCookie:
8.16 @@ -61,6 +55,11 @@
8.17 break;
8.18 }
8.19
8.20 + case Query_Connect:
8.21 + {
8.22 + return;
8.23 + }
8.24 +
8.25 default:
8.26 {
8.27 break;
8.28 @@ -73,31 +72,26 @@
8.29 if (m_type == Query_Connect)
8.30 {
8.31 g_ClientPrefs.DatabaseConnect();
8.32 + return;
8.33 }
8.34 - else
8.35 - {
8.36 - assert(m_database != NULL);
8.37 -
8.38 - /* I don't think this is needed anymore... keeping for now. */
8.39 - m_database->LockForFullAtomicOperation();
8.40 -
8.41 +
8.42 + assert(m_database != NULL);
8.43 + /* I don't think this is needed anymore... keeping for now. */
8.44 + m_database->LockForFullAtomicOperation();
8.45 if (!BindParamsAndRun())
8.46 - {
8.47 - g_pSM->LogError(myself,
8.48 - "Failed SQL Query, Error: \"%s\" (Query id %i - serial %i)",
8.49 - m_database->GetError(),
8.50 - m_type,
8.51 - m_serial);
8.52 - }
8.53 + {
8.54 + g_pSM->LogError(myself,
8.55 + "Failed SQL Query, Error: \"%s\" (Query id %i - serial %i)",
8.56 + m_database->GetError(),
8.57 + m_type,
8.58 + m_serial);
8.59 + }
8.60
8.61 - m_database->UnlockFromFullAtomicOperation();
8.62 - }
8.63 + m_database->UnlockFromFullAtomicOperation();
8.64 }
8.65
8.66 IDBDriver *TQueryOp::GetDriver()
8.67 {
8.68 - assert(m_database != NULL);
8.69 -
8.70 return m_database->GetDriver();
8.71 }
8.72
8.73 @@ -131,6 +125,7 @@
8.74 m_database = NULL;
8.75 m_insertId = -1;
8.76 m_pResult = NULL;
8.77 + m_serial = 0;
8.78 }
8.79
8.80 void TQueryOp::SetDatabase(IDatabase *db)
8.81 @@ -162,7 +157,7 @@
8.82
8.83 if (g_DriverType == Driver_MySQL)
8.84 {
8.85 - UTIL_Format(query,
8.86 + g_pSM->Format(query,
8.87 sizeof(query),
8.88 "INSERT IGNORE INTO sm_cookies (name, description, access) \
8.89 VALUES (\"%s\", \"%s\", %d)",
8.90 @@ -172,7 +167,7 @@
8.91 }
8.92 else if (g_DriverType == Driver_SQLite)
8.93 {
8.94 - UTIL_Format(query,
8.95 + g_pSM->Format(query,
8.96 sizeof(query),
8.97 "INSERT OR IGNORE INTO sm_cookies (name, description, access) \
8.98 VALUES ('%s', '%s', %d)",
8.99 @@ -197,7 +192,7 @@
8.100
8.101 m_database->QuoteString(m_params.steamId, safe_str, sizeof(safe_str), &ignore);
8.102
8.103 - UTIL_Format(query,
8.104 + g_pSM->Format(query,
8.105 sizeof(query),
8.106 "SELECT sm_cookies.name, sm_cookie_cache.value, sm_cookies.description, \
8.107 sm_cookies.access, sm_cookie_cache.timestamp \
8.108 @@ -228,7 +223,7 @@
8.109
8.110 if (g_DriverType == Driver_MySQL)
8.111 {
8.112 - UTIL_Format(query,
8.113 + g_pSM->Format(query,
8.114 sizeof(query),
8.115 "INSERT INTO sm_cookie_cache (player, cookie_id, value, timestamp) \
8.116 VALUES (\"%s\", %d, \"%s\", %d) \
8.117 @@ -243,7 +238,7 @@
8.118 }
8.119 else if (g_DriverType == Driver_SQLite)
8.120 {
8.121 - UTIL_Format(query,
8.122 + g_pSM->Format(query,
8.123 sizeof(query),
8.124 "INSERT OR REPLACE INTO sm_cookie_cache \
8.125 (player, cookie_id, value, timestamp) \
8.126 @@ -274,7 +269,7 @@
8.127 sizeof(safe_name),
8.128 &ignore);
8.129
8.130 - UTIL_Format(query,
8.131 + g_pSM->Format(query,
8.132 sizeof(query),
8.133 "SELECT id FROM sm_cookies WHERE name = '%s'",
8.134 safe_name);
8.135 @@ -296,6 +291,16 @@
8.136 return false;
8.137 }
8.138
8.139 +querytype TQueryOp::PullQueryType()
8.140 +{
8.141 + return m_type;
8.142 +}
8.143 +
8.144 +int TQueryOp::PullQuerySerial()
8.145 +{
8.146 + return m_serial;
8.147 +}
8.148 +
8.149 ParamData::~ParamData()
8.150 {
8.151 if (cookie)
8.152 @@ -309,8 +314,10 @@
8.153 delete cookie;
8.154 cookie = NULL;
8.155 }
8.156 -
8.157 - g_ClientPrefs.cookieMutex->Unlock();
8.158 + else
8.159 + {
8.160 + g_ClientPrefs.cookieMutex->Unlock();
8.161 + }
8.162 }
8.163
8.164 if (data)
9.1 --- a/extensions/clientprefs/query.h Mon Feb 25 20:44:16 2013 -0600
9.2 +++ b/extensions/clientprefs/query.h Thu Feb 28 21:51:49 2013 +0000
9.3 @@ -93,6 +93,10 @@
9.4 {
9.5 return m_database;
9.6 }
9.7 +
9.8 +public:
9.9 + querytype PullQueryType();
9.10 + int PullQuerySerial();
9.11
9.12 private:
9.13 IDatabase *m_database;