diff --git a/extensions/clientprefs/cookie.cpp b/extensions/clientprefs/cookie.cpp index 38897734..3415ad48 100644 --- a/extensions/clientprefs/cookie.cpp +++ b/extensions/clientprefs/cookie.cpp @@ -145,10 +145,7 @@ Cookie *CookieManager::CreateCookie(const char *name, const char *description, C bool CookieManager::GetCookieValue(Cookie *pCookie, int client, char **value) { - if (pCookie == NULL) - { - return false; - } + assert(pCookie); CookieData *data = pCookie->data[client]; @@ -160,6 +157,7 @@ bool CookieManager::GetCookieValue(Cookie *pCookie, int client, char **value) clientData[client].push_back(data); pCookie->data[client] = data; data->changed = true; + data->timestamp = time(NULL); } *value = &data->value[0]; @@ -169,10 +167,7 @@ bool CookieManager::GetCookieValue(Cookie *pCookie, int client, char **value) bool CookieManager::SetCookieValue(Cookie *pCookie, int client, char *value) { - if (pCookie == NULL) - { - return false; - } + assert(pCookie); CookieData *data = pCookie->data[client]; @@ -190,6 +185,7 @@ bool CookieManager::SetCookieValue(Cookie *pCookie, int client, char *value) } data->changed = true; + data->timestamp = time(NULL); return true; } @@ -302,6 +298,10 @@ void CookieManager::ClientConnectCallback(int serial, IQuery *data) CookieData *pData = new CookieData(value); pData->changed = false; + unsigned int timestamp = 0; + row->GetInt(4, (int *)×tamp); + pData->timestamp = timestamp; + Cookie *parent = FindCookie(name); if (parent == NULL) @@ -417,3 +417,19 @@ void CookieManager::OnPluginDestroyed(IPlugin *plugin) } } +bool CookieManager::GetCookieTime(Cookie *pCookie, int client, time_t *value) +{ + assert(pCookie); + + CookieData *data = pCookie->data[client]; + + /* Check if a value has been set before */ + if (data == NULL) + { + return false; + } + + *value = data->timestamp; + + return true; +} diff --git a/extensions/clientprefs/cookie.h b/extensions/clientprefs/cookie.h index 8fe2376e..4358e291 100644 --- a/extensions/clientprefs/cookie.h +++ b/extensions/clientprefs/cookie.h @@ -60,6 +60,7 @@ struct CookieData char value[MAX_VALUE_LENGTH]; bool changed; + time_t timestamp; Cookie *parent; }; @@ -118,6 +119,7 @@ public: bool GetCookieValue(Cookie *pCookie, int client, char **value); bool SetCookieValue(Cookie *pCookie, int client, char *value); + bool GetCookieTime(Cookie *pCookie, int client, time_t *value); void Unload(); diff --git a/extensions/clientprefs/natives.cpp b/extensions/clientprefs/natives.cpp index 2060c034..11b68b19 100644 --- a/extensions/clientprefs/natives.cpp +++ b/extensions/clientprefs/natives.cpp @@ -399,6 +399,38 @@ cell_t AddSettingsPrefabMenuItem(IPluginContext *pContext, const cell_t *params) return 0; } +cell_t GetClientCookieTime(IPluginContext *pContext, const cell_t *params) +{ + if (g_ClientPrefs.Database == NULL && !g_ClientPrefs.databaseLoading) + { + return pContext->ThrowNativeError("Clientprefs is disabled due to a failed database connection"); + } + + Handle_t hndl = static_cast(params[2]); + HandleError err; + HandleSecurity sec; + + sec.pOwner = NULL; + sec.pIdentity = myself->GetIdentity(); + + Cookie *pCookie; + + if ((err = handlesys->ReadHandle(hndl, g_CookieType, &sec, (void **)&pCookie)) + != HandleError_None) + { + return pContext->ThrowNativeError("Invalid Cookie handle %x (error %d)", hndl, err); + } + + time_t value; + + if (!g_CookieManager.GetCookieTime(pCookie, params[1], &value)) + { + return 0; + } + + return value; +} + sp_nativeinfo_t g_ClientPrefNatives[] = { {"RegClientCookie", RegClientPrefCookie}, diff --git a/extensions/clientprefs/query.cpp b/extensions/clientprefs/query.cpp index 964b5133..0775ed17 100644 --- a/extensions/clientprefs/query.cpp +++ b/extensions/clientprefs/query.cpp @@ -200,7 +200,7 @@ bool TQueryOp::BindParamsAndRun() UTIL_Format(query, sizeof(query), "SELECT sm_cookies.name, sm_cookie_cache.value, sm_cookies.description, \ - sm_cookies.access \ + sm_cookies.access, sm_cookie_cache.timestamp \ FROM sm_cookies \ JOIN sm_cookie_cache \ ON sm_cookies.id = sm_cookie_cache.cookie_id \ @@ -214,7 +214,6 @@ bool TQueryOp::BindParamsAndRun() case Query_InsertData: { - time_t t = time(NULL); char safe_id[128]; char safe_val[MAX_VALUE_LENGTH*2 + 1]; @@ -238,9 +237,9 @@ bool TQueryOp::BindParamsAndRun() safe_id, m_params.cookieId, safe_val, - (unsigned int)t, + (unsigned int)m_params.data->timestamp, safe_val, - (unsigned int)t); + (unsigned int)m_params.data->timestamp); } else if (g_DriverType == Driver_SQLite) { @@ -252,7 +251,7 @@ bool TQueryOp::BindParamsAndRun() safe_id, m_params.cookieId, safe_val, - (unsigned int)t); + (unsigned int)m_params.data->timestamp); } if (!m_database->DoSimpleQuery(query)) diff --git a/plugins/include/clientprefs.inc b/plugins/include/clientprefs.inc index f28776af..50371764 100644 --- a/plugins/include/clientprefs.inc +++ b/plugins/include/clientprefs.inc @@ -222,6 +222,15 @@ native bool:ReadCookieIterator(Handle:iter, */ native CookieAccess:GetCookieAccess(Handle:cookie); +/** + * Returns the last updated timestamp for a client cookie + * + * @param client Client index. + * @param cookie Cookie handle. + * @return Last updated timestamp. + */ +native GetClientCookieTime(client, Handle:cookie); + /** * Do not edit below this line! */