3 * =============================================================================
4 * SourceMod Client Preferences Extension
5 * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
6 * =============================================================================
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.
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
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/>.
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>.
32 #include "extension.h"
36 cell_t RegClientPrefCookie(IPluginContext *pContext, const cell_t *params)
38 if (g_ClientPrefs.Database == NULL && !g_ClientPrefs.databaseLoading)
40 return pContext->ThrowNativeError("Clientprefs is disabled due to a failed database connection");
44 pContext->LocalToString(params[1], &name);
48 return pContext->ThrowNativeError("Cannot create preference cookie with no name");
52 pContext->LocalToString(params[2], &desc);
54 Cookie *pCookie = g_CookieManager.CreateCookie(name, desc, (CookieAccess)params[3]);
61 return handlesys->CreateHandle(g_CookieType,
63 pContext->GetIdentity(),
64 myself->GetIdentity(),
68 cell_t FindClientPrefCookie(IPluginContext *pContext, const cell_t *params)
70 if (g_ClientPrefs.Database == NULL && !g_ClientPrefs.databaseLoading)
72 return pContext->ThrowNativeError("Clientprefs is disabled due to a failed database connection");
76 pContext->LocalToString(params[1], &name);
78 Cookie *pCookie = g_CookieManager.FindCookie(name);
85 return handlesys->CreateHandle(g_CookieType,
87 pContext->GetIdentity(),
88 myself->GetIdentity(),
92 cell_t SetClientPrefCookie(IPluginContext *pContext, const cell_t *params)
94 if (g_ClientPrefs.Database == NULL && !g_ClientPrefs.databaseLoading)
96 return pContext->ThrowNativeError("Clientprefs is disabled due to a failed database connection");
99 int client = params[1];
101 if ((client < 1) || (client > playerhelpers->GetMaxClients()))
103 return pContext->ThrowNativeError("Client index %d is invalid", client);
106 Handle_t hndl = static_cast<Handle_t>(params[2]);
111 sec.pIdentity = myself->GetIdentity();
115 if ((err = handlesys->ReadHandle(hndl, g_CookieType, &sec, (void **)&pCookie))
118 return pContext->ThrowNativeError("Invalid Cookie handle %x (error %d)", hndl, err);
122 pContext->LocalToString(params[3], &value);
124 return g_CookieManager.SetCookieValue(pCookie, client, value);
127 cell_t GetClientPrefCookie(IPluginContext *pContext, const cell_t *params)
129 if (g_ClientPrefs.Database == NULL && !g_ClientPrefs.databaseLoading)
131 return pContext->ThrowNativeError("Clientprefs is disabled due to a failed database connection");
134 int client = params[1];
136 if ((client < 1) || (client > playerhelpers->GetMaxClients()))
138 return pContext->ThrowNativeError("Client index %d is invalid", client);
141 Handle_t hndl = static_cast<Handle_t>(params[2]);
146 sec.pIdentity = myself->GetIdentity();
150 if ((err = handlesys->ReadHandle(hndl, g_CookieType, &sec, (void **)&pCookie))
153 return pContext->ThrowNativeError("Invalid Cookie handle %x (error %d)", hndl, err);
158 g_CookieManager.GetCookieValue(pCookie, client, &value);
160 pContext->StringToLocal(params[3], params[4], value);
165 cell_t AreClientCookiesCached(IPluginContext *pContext, const cell_t *params)
167 if (g_ClientPrefs.Database == NULL && !g_ClientPrefs.databaseLoading)
169 return pContext->ThrowNativeError("Clientprefs is disabled due to a failed database connection");
172 int client = params[1];
174 if ((client < 1) || (client > playerhelpers->GetMaxClients()))
176 return pContext->ThrowNativeError("Client index %d is invalid", client);
179 return g_CookieManager.AreClientCookiesCached(client);
182 cell_t GetCookieAccess(IPluginContext *pContext, const cell_t *params)
184 if (g_ClientPrefs.Database == NULL && !g_ClientPrefs.databaseLoading)
186 return pContext->ThrowNativeError("Clientprefs is disabled due to a failed database connection");
189 Handle_t hndl = static_cast<Handle_t>(params[1]);
194 sec.pIdentity = myself->GetIdentity();
198 if ((err = handlesys->ReadHandle(hndl, g_CookieType, &sec, (void **)&pCookie))
201 return pContext->ThrowNativeError("Invalid Cookie handle %x (error %d)", hndl, err);
204 return pCookie->access;
207 static cell_t GetCookieIterator(IPluginContext *pContext, const cell_t *params)
209 if (g_ClientPrefs.Database == NULL && !g_ClientPrefs.databaseLoading)
211 return pContext->ThrowNativeError("Clientprefs is disabled due to a failed database connection");
214 SourceHook::List<Cookie *>::iterator *iter = new SourceHook::List<Cookie *>::iterator;
215 *iter = g_CookieManager.cookieList.begin();
217 Handle_t hndl = handlesys->CreateHandle(g_CookieIterator, iter, pContext->GetIdentity(), myself->GetIdentity(), NULL);
218 if (hndl == BAD_HANDLE)
226 static cell_t ReadCookieIterator(IPluginContext *pContext, const cell_t *params)
228 if (g_ClientPrefs.Database == NULL && !g_ClientPrefs.databaseLoading)
230 return pContext->ThrowNativeError("Clientprefs is disabled due to a failed database connection");
233 SourceHook::List<Cookie *>::iterator *iter;
235 Handle_t hndl = static_cast<Handle_t>(params[1]);
240 sec.pIdentity = myself->GetIdentity();
242 if ((err = handlesys->ReadHandle(hndl, g_CookieIterator, &sec, (void **)&iter))
245 return pContext->ThrowNativeError("Invalid Cookie iterator handle %x (error %d)", hndl, err);
248 if (*iter == g_CookieManager.cookieList.end())
253 Cookie *pCookie = (Cookie *)**iter;
257 pContext->StringToLocalUTF8(params[2], params[3], pCookie->name, NULL);
258 pContext->StringToLocalUTF8(params[5], params[6], pCookie->description, NULL);
261 pContext->LocalToPhysAddr(params[4], &addr);
262 *addr = pCookie->access;
267 cell_t ShowSettingsMenu(IPluginContext *pContext, const cell_t *params)
269 if (g_ClientPrefs.Database == NULL && !g_ClientPrefs.databaseLoading)
271 return pContext->ThrowNativeError("Clientprefs is disabled due to a failed database connection");
275 Translate(message, sizeof(message), "%T:", 2, NULL, "Client Settings", ¶ms[1]);
277 g_CookieManager.clientMenu->SetDefaultTitle(message);
278 g_CookieManager.clientMenu->Display(params[1], 0, NULL);
283 cell_t AddSettingsMenuItem(IPluginContext *pContext, const cell_t *params)
285 if (g_ClientPrefs.Database == NULL && !g_ClientPrefs.databaseLoading)
287 return pContext->ThrowNativeError("Clientprefs is disabled due to a failed database connection");
291 pContext->LocalToString(params[3], &display);
293 /* Register a callback */
294 ItemHandler *pItem = new ItemHandler;
295 pItem->isAutoMenu = false;
296 pItem->forward = forwards->CreateForwardEx(NULL, ET_Ignore, 5, NULL, Param_Cell, Param_Cell, Param_Cell, Param_String, Param_Cell);
298 pItem->forward->AddFunction(pContext, static_cast<funcid_t>(params[1]));
301 AutoMenuData *data = new AutoMenuData;
302 data->datavalue = params[2];
303 data->handler = pItem;
304 UTIL_Format(info, sizeof(info), "%x", data);
306 ItemDrawInfo draw(display, 0);
308 g_CookieManager.clientMenu->AppendItem(info, draw);
310 /* Track this in case the plugin unloads */
312 IPlugin *pPlugin = plsys->FindPluginByContext(pContext->GetContext());
313 SourceHook::List<char *> *pList = NULL;
315 if (!pPlugin->GetProperty("SettingsMenuItems", (void **)&pList, false) || !pList)
317 pList = new SourceHook::List<char *>;
318 pPlugin->SetProperty("SettingsMenuItems", pList);
321 char *copyarray = new char[strlen(display)+1];
322 UTIL_Format(copyarray, strlen(display)+1, "%s", display);
324 pList->push_back(copyarray);
329 cell_t AddSettingsPrefabMenuItem(IPluginContext *pContext, const cell_t *params)
331 if (g_ClientPrefs.Database == NULL && !g_ClientPrefs.databaseLoading)
333 return pContext->ThrowNativeError("Clientprefs is disabled due to a failed database connection");
336 Handle_t hndl = static_cast<Handle_t>(params[1]);
341 sec.pIdentity = myself->GetIdentity();
345 if ((err = handlesys->ReadHandle(hndl, g_CookieType, &sec, (void **)&pCookie))
348 return pContext->ThrowNativeError("Invalid Cookie handle %x (error %d)", hndl, err);
351 /* Register a callback */
352 ItemHandler *pItem = new ItemHandler;
353 pItem->isAutoMenu = true;
354 pItem->autoMenuType = (CookieMenu)params[2];
357 /* User passed a function id for a callback */
360 pItem->forward = forwards->CreateForwardEx(NULL, ET_Ignore, 5, NULL, Param_Cell, Param_Cell, Param_Cell, Param_String, Param_Cell);
361 pItem->forward->AddFunction(pContext, static_cast<funcid_t>(params[4]));
365 pItem->forward = NULL;
369 pContext->LocalToString(params[3], &display);
371 ItemDrawInfo draw(display, 0);
374 AutoMenuData *data = new AutoMenuData;
375 data->datavalue = params[5];
376 data->pCookie = pCookie;
377 data->type = (CookieMenu)params[2];
378 data->handler = pItem;
379 UTIL_Format(info, sizeof(info), "%x", data);
381 g_CookieManager.clientMenu->AppendItem(info, draw);
383 /* Track this in case the plugin unloads */
385 IPlugin *pPlugin = plsys->FindPluginByContext(pContext->GetContext());
386 SourceHook::List<char *> *pList = NULL;
388 if (!pPlugin->GetProperty("SettingsMenuItems", (void **)&pList, false) || !pList)
390 pList = new SourceHook::List<char *>;
391 pPlugin->SetProperty("SettingsMenuItems", pList);
394 char *copyarray = new char[strlen(display)+1];
395 UTIL_Format(copyarray, strlen(display)+1, "%s", display);
397 pList->push_back(copyarray);
402 sp_nativeinfo_t g_ClientPrefNatives[] =
404 {"RegClientCookie", RegClientPrefCookie},
405 {"FindClientCookie", FindClientPrefCookie},
406 {"SetClientCookie", SetClientPrefCookie},
407 {"GetClientCookie", GetClientPrefCookie},
408 {"AreClientCookiesCached", AreClientCookiesCached},
409 {"GetCookieAccess", GetCookieAccess},
410 {"ReadCookieIterator", ReadCookieIterator},
411 {"GetCookieIterator", GetCookieIterator},
412 {"ShowCookieMenu", ShowSettingsMenu},
413 {"SetCookieMenuItem", AddSettingsMenuItem},
414 {"SetCookiePrefabMenu", AddSettingsPrefabMenuItem},