core/smn_core.cpp
author David Anderson <dvander@alliedmods.net>
Wed May 23 01:44:00 2007 +0000 (2007-05-23)
changeset 837 de0223664adc
parent 653 ef60870067ff
child 886 649c859c2272
permissions -rw-r--r--
added request amb293 - SetFailState
     1 /**
     2  * vim: set ts=4 :
     3  * ===============================================================
     4  * SourceMod (C)2004-2007 AlliedModders LLC.  All rights reserved.
     5  * ===============================================================
     6  *
     7  * This file is not open source and may not be copied without explicit
     8  * written permission of AlliedModders LLC.  This file may not be redistributed 
     9  * in whole or significant part.
    10  * For information, see LICENSE.txt or http://www.sourcemod.net/license.php
    11  *
    12  * Version: $Id$
    13  */
    14 
    15 #include <time.h>
    16 #include "sm_globals.h"
    17 #include "sourcemod.h"
    18 #include "PluginSys.h"
    19 #include "HandleSys.h"
    20 
    21 HandleType_t g_PlIter;
    22 
    23 
    24 class CoreNativeHelpers : 
    25 	public SMGlobalClass,
    26 	public IHandleTypeDispatch
    27 {
    28 public:
    29 	void OnSourceModAllInitialized()
    30 	{
    31 		HandleAccess hacc;
    32 		g_HandleSys.InitAccessDefaults(NULL,  &hacc);
    33 		hacc.access[HandleAccess_Clone] = HANDLE_RESTRICT_IDENTITY|HANDLE_RESTRICT_OWNER;
    34 
    35 		g_PlIter = g_HandleSys.CreateType("PluginIterator", this, 0, NULL, NULL, g_pCoreIdent, NULL);
    36 	}
    37 	void OnHandleDestroy(HandleType_t type, void *object)
    38 	{
    39 		IPluginIterator *iter = (IPluginIterator *)object;
    40 		iter->Release();
    41 	}
    42 	void OnSourceModShutdown()
    43 	{
    44 		g_HandleSys.RemoveType(g_PlIter, g_pCoreIdent);
    45 	}
    46 } g_CoreNativeHelpers;
    47 
    48 
    49 static cell_t ThrowError(IPluginContext *pContext, const cell_t *params)
    50 {
    51 	char buffer[512];
    52 
    53 	g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 1);
    54 
    55 	if (pContext->GetContext()->n_err == SP_ERROR_NONE)
    56 	{
    57 		pContext->ThrowNativeErrorEx(SP_ERROR_ABORTED, "%s", buffer);
    58 	}
    59 
    60 	return 0;
    61 }
    62 
    63 static cell_t GetTime(IPluginContext *pContext, const cell_t *params)
    64 {
    65 	time_t t = time(NULL);
    66 	cell_t *addr;
    67 	pContext->LocalToPhysAddr(params[1], &addr);
    68 
    69 	*(time_t *)addr = t;
    70 
    71 	return static_cast<cell_t>(t);
    72 }
    73 
    74 static cell_t GetPluginIterator(IPluginContext *pContext, const cell_t *params)
    75 {
    76 	IPluginIterator *iter = g_PluginSys.GetPluginIterator();
    77 
    78 	Handle_t hndl = g_HandleSys.CreateHandle(g_PlIter, iter, pContext->GetIdentity(), g_pCoreIdent, NULL);
    79 
    80 	if (hndl == BAD_HANDLE)
    81 	{
    82 		iter->Release();
    83 	}
    84 
    85 	return hndl;
    86 }
    87 
    88 static cell_t MorePlugins(IPluginContext *pContext, const cell_t *params)
    89 {
    90 	Handle_t hndl = (Handle_t)params[1];
    91 	HandleError err;
    92 	IPluginIterator *pIter;
    93 
    94 	HandleSecurity sec;
    95 	sec.pIdentity = g_pCoreIdent;
    96 	sec.pOwner = pContext->GetIdentity();
    97 
    98 	if ((err=g_HandleSys.ReadHandle(hndl, g_PlIter, &sec, (void **)&pIter)) != HandleError_None)
    99 	{
   100 		return pContext->ThrowNativeError("Could not read Handle %x (error %d)", hndl, err);
   101 	}
   102 
   103 	return pIter->MorePlugins() ? 1 : 0;
   104 }
   105 
   106 static cell_t ReadPlugin(IPluginContext *pContext, const cell_t *params)
   107 {
   108 	Handle_t hndl = (Handle_t)params[1];
   109 	HandleError err;
   110 	IPluginIterator *pIter;
   111 
   112 	HandleSecurity sec;
   113 	sec.pIdentity = g_pCoreIdent;
   114 	sec.pOwner = pContext->GetIdentity();
   115 
   116 	if ((err=g_HandleSys.ReadHandle(hndl, g_PlIter, &sec, (void **)&pIter)) != HandleError_None)
   117 	{
   118 		return pContext->ThrowNativeError("Could not read Handle %x (error %d)", hndl, err);
   119 	}
   120 
   121 	CPlugin *pPlugin = (CPlugin *)pIter->GetPlugin();
   122 	if (!pPlugin)
   123 	{
   124 		return BAD_HANDLE;
   125 	}
   126 
   127 	pIter->NextPlugin();
   128 
   129 	return pPlugin->GetMyHandle();
   130 }
   131 
   132 CPlugin *GetPluginFromHandle(IPluginContext *pContext, Handle_t hndl)
   133 {
   134 	if (hndl == BAD_HANDLE)
   135 	{
   136 		return g_PluginSys.GetPluginByCtx(pContext->GetContext());
   137 	} else {
   138 		HandleError err;
   139 		CPlugin *pPlugin = (CPlugin *)g_PluginSys.PluginFromHandle(hndl, &err);
   140 		if (!pPlugin)
   141 		{
   142 			pContext->ThrowNativeError("Could not read Handle %x (error %d)", hndl, err);
   143 		}
   144 		return pPlugin;
   145 	}
   146 }
   147 
   148 static cell_t GetPluginStatus(IPluginContext *pContext, const cell_t *params)
   149 {
   150 	CPlugin *pPlugin = GetPluginFromHandle(pContext, params[1]);
   151 	if (!pPlugin)
   152 	{
   153 		return 0;
   154 	}
   155 
   156 	return pPlugin->GetStatus();
   157 }
   158 
   159 static cell_t GetPluginFilename(IPluginContext *pContext, const cell_t *params)
   160 {
   161 	CPlugin *pPlugin = GetPluginFromHandle(pContext, params[1]);
   162 	if (!pPlugin)
   163 	{
   164 		return 0;
   165 	}
   166 
   167 	pContext->StringToLocalUTF8(params[2], params[3], pPlugin->GetFilename(), NULL);
   168 
   169 	return 1;
   170 }
   171 
   172 static cell_t IsPluginDebugging(IPluginContext *pContext, const cell_t *params)
   173 {
   174 	CPlugin *pPlugin = GetPluginFromHandle(pContext, params[1]);
   175 	if (!pPlugin)
   176 	{
   177 		return 0;
   178 	}
   179 
   180 	return pPlugin->IsDebugging() ? 1 : 0;
   181 }
   182 
   183 /* Local to plugins only */
   184 enum PluginInfo
   185 {
   186 	PlInfo_Name,			/**< Plugin name */
   187 	PlInfo_Author,			/**< Plugin author */
   188 	PlInfo_Description,		/**< Plugin description */
   189 	PlInfo_Version,			/**< Plugin verison */
   190 	PlInfo_URL,				/**< Plugin URL */
   191 };
   192 
   193 static cell_t GetPluginInfo(IPluginContext *pContext, const cell_t *params)
   194 {
   195 	CPlugin *pPlugin = GetPluginFromHandle(pContext, params[1]);
   196 	if (!pPlugin)
   197 	{
   198 		return 0;
   199 	}
   200 
   201 	const sm_plugininfo_t *info = pPlugin->GetPublicInfo();
   202 
   203 	if (!info)
   204 	{
   205 		return 0;
   206 	}
   207 
   208 	const char *str = NULL;
   209 
   210 	switch ((PluginInfo)params[2])
   211 	{
   212 	case PlInfo_Name:
   213 		{
   214 			str = info->name;
   215 			break;
   216 		}
   217 	case PlInfo_Author:
   218 		{
   219 			str = info->author;
   220 			break;
   221 		}
   222 	case PlInfo_Description:
   223 		{
   224 			str = info->description;
   225 			break;
   226 		}
   227 	case PlInfo_Version:
   228 		{
   229 			str = info->version;
   230 			break;
   231 		}
   232 	case PlInfo_URL:
   233 		{
   234 			str = info->url;
   235 			break;
   236 		}
   237 	}
   238 
   239 	if (!str || str[0] == '\0')
   240 	{
   241 		return 0;
   242 	}
   243 
   244 	pContext->StringToLocalUTF8(params[3], params[4], str, NULL);
   245 
   246 	return 1;
   247 }
   248 
   249 static cell_t SetFailState(IPluginContext *pContext, const cell_t *params)
   250 {
   251 	char *str;
   252 	pContext->LocalToString(params[1], &str);
   253 
   254 	CPlugin *pPlugin = g_PluginSys.GetPluginByCtx(pContext->GetContext());
   255 	pPlugin->SetErrorState(Plugin_Error, "%s", str);
   256 
   257 	return pContext->ThrowNativeErrorEx(SP_ERROR_ABORTED, "%s", str);
   258 }
   259 
   260 REGISTER_NATIVES(coreNatives)
   261 {
   262 	{"GetPluginFilename",	GetPluginFilename},
   263 	{"GetPluginInfo",		GetPluginInfo},
   264 	{"GetPluginIterator",	GetPluginIterator},
   265 	{"GetPluginStatus",		GetPluginStatus},
   266 	{"GetTime",				GetTime},
   267 	{"IsPluginDebugging",	IsPluginDebugging},
   268 	{"MorePlugins",			MorePlugins},
   269 	{"ReadPlugin",			ReadPlugin},
   270 	{"ThrowError",			ThrowError},
   271 	{"SetFailState",		SetFailState},
   272 	{NULL,					NULL},
   273 };