extensions/clientprefs/natives.cpp
author Matt Woodrow <pred@alliedmods.net>
Sun Jul 06 03:30:06 2008 +0000 (2008-07-06)
changeset 2165 ca3757e676f6
parent 2048 2454ff4d6afb
child 2207 3a97a56ded62
permissions -rw-r--r--
Fixed requiring dependencies at the wrong time.
     1 /**
     2  * vim: set ts=4 :
     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 "extension.h"
    33 #include "cookie.h"
    34 #include "menus.h"
    35 
    36 cell_t RegClientPrefCookie(IPluginContext *pContext, const cell_t *params)
    37 {
    38 	char *name;
    39 	pContext->LocalToString(params[1], &name);
    40 
    41 	if (name[0] == '\0')
    42 	{
    43 		return pContext->ThrowNativeError("Cannot create preference cookie with no name");
    44 	}
    45 
    46 	char *desc;
    47 	pContext->LocalToString(params[2], &desc);
    48 
    49 	Cookie *pCookie = g_CookieManager.CreateCookie(name, desc, (CookieAccess)params[3]);
    50 
    51 	if (!pCookie)
    52 	{
    53 		return BAD_HANDLE;
    54 	}
    55 
    56 	return handlesys->CreateHandle(g_CookieType, 
    57 		pCookie, 
    58 		pContext->GetIdentity(), 
    59 		myself->GetIdentity(), 
    60 		NULL);
    61 }
    62 
    63 cell_t FindClientPrefCookie(IPluginContext *pContext, const cell_t *params)
    64 {
    65 	char *name;
    66 	pContext->LocalToString(params[1], &name);
    67 
    68 	Cookie *pCookie = g_CookieManager.FindCookie(name);
    69 
    70 	if (!pCookie)
    71 	{
    72 		return BAD_HANDLE;
    73 	}
    74 
    75 	return handlesys->CreateHandle(g_CookieType, 
    76 		pCookie, 
    77 		pContext->GetIdentity(), 
    78 		myself->GetIdentity(), 
    79 		NULL);
    80 }
    81 
    82 cell_t SetClientPrefCookie(IPluginContext *pContext, const cell_t *params)
    83 {
    84 	int client = params[1];
    85 
    86 	if ((client < 1) || (client > playerhelpers->GetMaxClients()))
    87 	{
    88 		return pContext->ThrowNativeError("Client index %d is invalid", client);
    89 	}
    90 
    91 	Handle_t hndl = static_cast<Handle_t>(params[2]);
    92 	HandleError err;
    93 	HandleSecurity sec;
    94  
    95 	sec.pOwner = NULL;
    96 	sec.pIdentity = myself->GetIdentity();
    97 
    98 	Cookie *pCookie;
    99 
   100 	if ((err = handlesys->ReadHandle(hndl, g_CookieType, &sec, (void **)&pCookie))
   101 	     != HandleError_None)
   102 	{
   103 		return pContext->ThrowNativeError("Invalid Cookie handle %x (error %d)", hndl, err);
   104 	}
   105 
   106 	char *value;
   107 	pContext->LocalToString(params[3], &value);
   108 
   109 	return g_CookieManager.SetCookieValue(pCookie, client, value);
   110 }
   111 
   112 cell_t GetClientPrefCookie(IPluginContext *pContext, const cell_t *params)
   113 {
   114 	int client = params[1];
   115 
   116 	if ((client < 1) || (client > playerhelpers->GetMaxClients()))
   117 	{
   118 		return pContext->ThrowNativeError("Client index %d is invalid", client);
   119 	}
   120 
   121 	Handle_t hndl = static_cast<Handle_t>(params[2]);
   122 	HandleError err;
   123 	HandleSecurity sec;
   124  
   125 	sec.pOwner = NULL;
   126 	sec.pIdentity = myself->GetIdentity();
   127 
   128 	Cookie *pCookie;
   129 
   130 	if ((err = handlesys->ReadHandle(hndl, g_CookieType, &sec, (void **)&pCookie))
   131 	     != HandleError_None)
   132 	{
   133 		return pContext->ThrowNativeError("Invalid Cookie handle %x (error %d)", hndl, err);
   134 	}
   135 	
   136 	char *value = NULL;
   137 
   138 	g_CookieManager.GetCookieValue(pCookie, client, &value);
   139 
   140 	pContext->StringToLocal(params[3], params[4], value);
   141 
   142 	return 1;
   143 }
   144 
   145 cell_t AreClientCookiesCached(IPluginContext *pContext, const cell_t *params)
   146 {
   147 	int client = params[1];
   148 
   149 	if ((client < 1) || (client > playerhelpers->GetMaxClients()))
   150 	{
   151 		return pContext->ThrowNativeError("Client index %d is invalid", client);
   152 	}
   153 
   154 	return g_CookieManager.AreClientCookiesCached(client);
   155 }
   156 
   157 cell_t GetCookieAccess(IPluginContext *pContext, const cell_t *params)
   158 {
   159 	Handle_t hndl = static_cast<Handle_t>(params[1]);
   160 	HandleError err;
   161 	HandleSecurity sec;
   162  
   163 	sec.pOwner = NULL;
   164 	sec.pIdentity = myself->GetIdentity();
   165 
   166 	Cookie *pCookie;
   167 
   168 	if ((err = handlesys->ReadHandle(hndl, g_CookieType, &sec, (void **)&pCookie))
   169 	     != HandleError_None)
   170 	{
   171 		return pContext->ThrowNativeError("Invalid Cookie handle %x (error %d)", hndl, err);
   172 	}
   173 
   174 	return pCookie->access;
   175 }
   176 
   177 static cell_t GetCookieIterator(IPluginContext *pContext, const cell_t *params)
   178 {
   179 	SourceHook::List<Cookie *>::iterator *iter = new SourceHook::List<Cookie *>::iterator;
   180 	*iter = g_CookieManager.cookieList.begin();
   181 
   182 	Handle_t hndl = handlesys->CreateHandle(g_CookieIterator, iter, pContext->GetIdentity(), myself->GetIdentity(), NULL);
   183 	if (hndl == BAD_HANDLE)
   184 	{
   185 		delete iter;
   186 	}
   187 
   188 	return hndl;
   189 }
   190 
   191 static cell_t ReadCookieIterator(IPluginContext *pContext, const cell_t *params)
   192 {
   193 	SourceHook::List<Cookie *>::iterator *iter;
   194 
   195 	Handle_t hndl = static_cast<Handle_t>(params[1]);
   196 	HandleError err;
   197 	HandleSecurity sec;
   198 
   199 	sec.pOwner = NULL;
   200 	sec.pIdentity = myself->GetIdentity();
   201 
   202 	if ((err = handlesys->ReadHandle(hndl, g_CookieIterator, &sec, (void **)&iter))
   203 	     != HandleError_None)
   204 	{
   205 		return pContext->ThrowNativeError("Invalid Cookie iterator handle %x (error %d)", hndl, err);
   206 	}
   207 
   208 	if (*iter == g_CookieManager.cookieList.end())
   209 	{
   210 		return 0;
   211 	}
   212 
   213 	Cookie *pCookie = (Cookie *)**iter;
   214 
   215 	(*iter)++;
   216 
   217 	pContext->StringToLocalUTF8(params[2], params[3], pCookie->name, NULL);
   218 	pContext->StringToLocalUTF8(params[5], params[6], pCookie->description, NULL);
   219 
   220 	cell_t *addr;
   221 	pContext->LocalToPhysAddr(params[4], &addr);
   222 	*addr = pCookie->access;
   223 
   224 	return 1;
   225 }
   226 
   227 cell_t ShowSettingsMenu(IPluginContext *pContext, const cell_t *params)
   228 {
   229 	char message[256];
   230 	Translate(message, sizeof(message), "%T:", 2, NULL, "Client Settings", &params[1]);
   231 
   232 	g_CookieManager.clientMenu->SetDefaultTitle(message);
   233 	g_CookieManager.clientMenu->Display(params[1], 0, NULL);
   234 
   235 	return 0;
   236 }
   237 
   238 cell_t AddSettingsMenuItem(IPluginContext *pContext, const cell_t *params)
   239 {
   240 	char *display;
   241 	pContext->LocalToString(params[3], &display);
   242 
   243 	/* Register a callback */
   244 	ItemHandler *pItem = new ItemHandler;
   245 	pItem->isAutoMenu = false;
   246 	pItem->forward = forwards->CreateForwardEx(NULL, ET_Ignore, 5, NULL, Param_Cell, Param_Cell, Param_Cell, Param_String, Param_Cell);
   247 
   248 	pItem->forward->AddFunction(pContext, static_cast<funcid_t>(params[1]));
   249 
   250 	char info[20];
   251 	AutoMenuData *data = new AutoMenuData;
   252 	data->datavalue = params[2];
   253 	data->handler = pItem;
   254 	UTIL_Format(info, sizeof(info), "%x", data);
   255 
   256 	ItemDrawInfo draw(display, 0);
   257 
   258 	g_CookieManager.clientMenu->AppendItem(info, draw);
   259 
   260 	/* Track this in case the plugin unloads */
   261 
   262 	IPlugin *pPlugin = plsys->FindPluginByContext(pContext->GetContext());
   263 	SourceHook::List<char *> *pList = NULL;
   264 
   265 	if (!pPlugin->GetProperty("SettingsMenuItems", (void **)&pList, false) || !pList)
   266 	{
   267 		pList = new SourceHook::List<char *>;
   268 		pPlugin->SetProperty("SettingsMenuItems", pList);
   269 	}
   270 
   271 	char *copyarray = new char[strlen(display)+1];
   272 	UTIL_Format(copyarray, strlen(display)+1, "%s", display);
   273 
   274 	pList->push_back(copyarray);
   275 
   276 	return 0;
   277 }
   278 
   279 cell_t AddSettingsPrefabMenuItem(IPluginContext *pContext, const cell_t *params)
   280 {
   281 	Handle_t hndl = static_cast<Handle_t>(params[1]);
   282 	HandleError err;
   283 	HandleSecurity sec;
   284  
   285 	sec.pOwner = NULL;
   286 	sec.pIdentity = myself->GetIdentity();
   287 
   288 	Cookie *pCookie;
   289 
   290 	if ((err = handlesys->ReadHandle(hndl, g_CookieType, &sec, (void **)&pCookie))
   291 	     != HandleError_None)
   292 	{
   293 		return pContext->ThrowNativeError("Invalid Cookie handle %x (error %d)", hndl, err);
   294 	}
   295 
   296 	/* Register a callback */
   297 	ItemHandler *pItem = new ItemHandler;
   298 	pItem->isAutoMenu = true;
   299 	pItem->autoMenuType = (CookieMenu)params[2];
   300 
   301 
   302 	/* User passed a function id for a callback */
   303 	if (params[4] != -1)
   304 	{
   305 		pItem->forward = forwards->CreateForwardEx(NULL, ET_Ignore, 5, NULL, Param_Cell, Param_Cell, Param_Cell, Param_String, Param_Cell); 
   306 		pItem->forward->AddFunction(pContext, static_cast<funcid_t>(params[4]));
   307 	}
   308 	else
   309 	{
   310 		pItem->forward = NULL;
   311 	}
   312 
   313 	char *display;
   314 	pContext->LocalToString(params[3], &display);
   315 
   316 	ItemDrawInfo draw(display, 0);
   317 
   318 	char info[20];
   319 	AutoMenuData *data = new AutoMenuData;
   320 	data->datavalue = params[5];
   321 	data->pCookie = pCookie;
   322 	data->type = (CookieMenu)params[2];
   323 	data->handler = pItem;
   324 	UTIL_Format(info, sizeof(info), "%x", data);
   325 
   326 	g_CookieManager.clientMenu->AppendItem(info, draw);
   327 
   328 	/* Track this in case the plugin unloads */
   329 
   330 	IPlugin *pPlugin = plsys->FindPluginByContext(pContext->GetContext());
   331 	SourceHook::List<char *> *pList = NULL;
   332 
   333 	if (!pPlugin->GetProperty("SettingsMenuItems", (void **)&pList, false) || !pList)
   334 	{
   335 		pList = new SourceHook::List<char *>;
   336 		pPlugin->SetProperty("SettingsMenuItems", pList);
   337 	}
   338 
   339 	char *copyarray = new char[strlen(display)+1];
   340 	UTIL_Format(copyarray, strlen(display)+1, "%s", display);
   341 
   342 	pList->push_back(copyarray);
   343 
   344 	return 0;
   345 }
   346 
   347 sp_nativeinfo_t g_ClientPrefNatives[] = 
   348 {
   349 	{"RegClientCookie",				RegClientPrefCookie},
   350 	{"FindClientCookie",			FindClientPrefCookie},
   351 	{"SetClientCookie",				SetClientPrefCookie},
   352 	{"GetClientCookie",				GetClientPrefCookie},
   353 	{"AreClientCookiesCached",		AreClientCookiesCached},
   354 	{"GetCookieAccess",				GetCookieAccess},
   355 	{"ReadCookieIterator",			ReadCookieIterator},
   356 	{"GetCookieIterator",			GetCookieIterator},
   357 	{"ShowCookieMenu",				ShowSettingsMenu},
   358 	{"SetCookieMenuItem",			AddSettingsMenuItem},
   359 	{"SetCookiePrefabMenu",			AddSettingsPrefabMenuItem},
   360 	{NULL,							NULL}
   361 };