core/smn_core.cpp
author Scott Ehlert <ds@alliedmods.net>
Sun Jul 15 08:00:26 2007 +0000 (2007-07-15)
changeset 1116 40cc5e9f0f1b
parent 1113 c09265bc03ce
child 1124 a397d51fb986
permissions -rw-r--r--
Removed strange debugging code
     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 <string.h>
    17 #include "sm_stringutil.h"
    18 #include "sm_globals.h"
    19 #include "sourcemod.h"
    20 #include "PluginSys.h"
    21 #include "HandleSys.h"
    22 #include "LibrarySys.h"
    23 
    24 #if defined PLATFORM_WINDOWS
    25 #include <windows.h>
    26 #elif defined PLATFORM_LINUX
    27 #include <limits.h>
    28 #include <unistd.h>
    29 #include <sys/times.h>
    30 #endif
    31 
    32 HandleType_t g_PlIter;
    33 
    34 class CoreNativeHelpers : 
    35 	public SMGlobalClass,
    36 	public IHandleTypeDispatch
    37 {
    38 public:
    39 	void OnSourceModAllInitialized()
    40 	{
    41 		HandleAccess hacc;
    42 		g_HandleSys.InitAccessDefaults(NULL,  &hacc);
    43 		hacc.access[HandleAccess_Clone] = HANDLE_RESTRICT_IDENTITY|HANDLE_RESTRICT_OWNER;
    44 
    45 		g_PlIter = g_HandleSys.CreateType("PluginIterator", this, 0, NULL, NULL, g_pCoreIdent, NULL);
    46 	}
    47 	void OnHandleDestroy(HandleType_t type, void *object)
    48 	{
    49 		IPluginIterator *iter = (IPluginIterator *)object;
    50 		iter->Release();
    51 	}
    52 	void OnSourceModShutdown()
    53 	{
    54 		g_HandleSys.RemoveType(g_PlIter, g_pCoreIdent);
    55 	}
    56 } g_CoreNativeHelpers;
    57 
    58 
    59 static cell_t ThrowError(IPluginContext *pContext, const cell_t *params)
    60 {
    61 	char buffer[512];
    62 
    63 	g_SourceMod.SetGlobalTarget(LANG_SERVER);
    64 
    65 	g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 1);
    66 
    67 	if (pContext->GetContext()->n_err == SP_ERROR_NONE)
    68 	{
    69 		pContext->ThrowNativeErrorEx(SP_ERROR_ABORTED, "%s", buffer);
    70 	}
    71 
    72 	return 0;
    73 }
    74 
    75 static cell_t GetTime(IPluginContext *pContext, const cell_t *params)
    76 {
    77 	time_t t = time(NULL);
    78 	cell_t *addr;
    79 	pContext->LocalToPhysAddr(params[1], &addr);
    80 
    81 	*(time_t *)addr = t;
    82 
    83 	return static_cast<cell_t>(t);
    84 }
    85 
    86 static cell_t FormatTime(IPluginContext *pContext, const cell_t *params)
    87 {
    88 	char *format, *buffer;
    89 	pContext->LocalToString(params[1], &buffer);
    90 	pContext->LocalToString(params[3], &format);
    91 
    92 	time_t t = (params[4] == -1) ? time(NULL) : (time_t)params[4];
    93 	strftime(buffer, params[2], format, localtime(&t));
    94 
    95 	return 1;
    96 }
    97 
    98 static cell_t GetPluginIterator(IPluginContext *pContext, const cell_t *params)
    99 {
   100 	IPluginIterator *iter = g_PluginSys.GetPluginIterator();
   101 
   102 	Handle_t hndl = g_HandleSys.CreateHandle(g_PlIter, iter, pContext->GetIdentity(), g_pCoreIdent, NULL);
   103 
   104 	if (hndl == BAD_HANDLE)
   105 	{
   106 		iter->Release();
   107 	}
   108 
   109 	return hndl;
   110 }
   111 
   112 static cell_t MorePlugins(IPluginContext *pContext, const cell_t *params)
   113 {
   114 	Handle_t hndl = (Handle_t)params[1];
   115 	HandleError err;
   116 	IPluginIterator *pIter;
   117 
   118 	HandleSecurity sec;
   119 	sec.pIdentity = g_pCoreIdent;
   120 	sec.pOwner = pContext->GetIdentity();
   121 
   122 	if ((err=g_HandleSys.ReadHandle(hndl, g_PlIter, &sec, (void **)&pIter)) != HandleError_None)
   123 	{
   124 		return pContext->ThrowNativeError("Could not read Handle %x (error %d)", hndl, err);
   125 	}
   126 
   127 	return pIter->MorePlugins() ? 1 : 0;
   128 }
   129 
   130 static cell_t ReadPlugin(IPluginContext *pContext, const cell_t *params)
   131 {
   132 	Handle_t hndl = (Handle_t)params[1];
   133 	HandleError err;
   134 	IPluginIterator *pIter;
   135 
   136 	HandleSecurity sec;
   137 	sec.pIdentity = g_pCoreIdent;
   138 	sec.pOwner = pContext->GetIdentity();
   139 
   140 	if ((err=g_HandleSys.ReadHandle(hndl, g_PlIter, &sec, (void **)&pIter)) != HandleError_None)
   141 	{
   142 		return pContext->ThrowNativeError("Could not read Handle %x (error %d)", hndl, err);
   143 	}
   144 
   145 	CPlugin *pPlugin = (CPlugin *)pIter->GetPlugin();
   146 	if (!pPlugin)
   147 	{
   148 		return BAD_HANDLE;
   149 	}
   150 
   151 	pIter->NextPlugin();
   152 
   153 	return pPlugin->GetMyHandle();
   154 }
   155 
   156 CPlugin *GetPluginFromHandle(IPluginContext *pContext, Handle_t hndl)
   157 {
   158 	if (hndl == BAD_HANDLE)
   159 	{
   160 		return g_PluginSys.GetPluginByCtx(pContext->GetContext());
   161 	} else {
   162 		HandleError err;
   163 		CPlugin *pPlugin = (CPlugin *)g_PluginSys.PluginFromHandle(hndl, &err);
   164 		if (!pPlugin)
   165 		{
   166 			pContext->ThrowNativeError("Could not read Handle %x (error %d)", hndl, err);
   167 		}
   168 		return pPlugin;
   169 	}
   170 }
   171 
   172 static cell_t GetPluginStatus(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->GetStatus();
   181 }
   182 
   183 static cell_t GetPluginFilename(IPluginContext *pContext, const cell_t *params)
   184 {
   185 	CPlugin *pPlugin = GetPluginFromHandle(pContext, params[1]);
   186 	if (!pPlugin)
   187 	{
   188 		return 0;
   189 	}
   190 
   191 	pContext->StringToLocalUTF8(params[2], params[3], pPlugin->GetFilename(), NULL);
   192 
   193 	return 1;
   194 }
   195 
   196 static cell_t IsPluginDebugging(IPluginContext *pContext, const cell_t *params)
   197 {
   198 	CPlugin *pPlugin = GetPluginFromHandle(pContext, params[1]);
   199 	if (!pPlugin)
   200 	{
   201 		return 0;
   202 	}
   203 
   204 	return pPlugin->IsDebugging() ? 1 : 0;
   205 }
   206 
   207 /* Local to plugins only */
   208 enum PluginInfo
   209 {
   210 	PlInfo_Name,			/**< Plugin name */
   211 	PlInfo_Author,			/**< Plugin author */
   212 	PlInfo_Description,		/**< Plugin description */
   213 	PlInfo_Version,			/**< Plugin verison */
   214 	PlInfo_URL,				/**< Plugin URL */
   215 };
   216 
   217 static cell_t GetPluginInfo(IPluginContext *pContext, const cell_t *params)
   218 {
   219 	CPlugin *pPlugin = GetPluginFromHandle(pContext, params[1]);
   220 	if (!pPlugin)
   221 	{
   222 		return 0;
   223 	}
   224 
   225 	const sm_plugininfo_t *info = pPlugin->GetPublicInfo();
   226 
   227 	if (!info)
   228 	{
   229 		return 0;
   230 	}
   231 
   232 	const char *str = NULL;
   233 
   234 	switch ((PluginInfo)params[2])
   235 	{
   236 	case PlInfo_Name:
   237 		{
   238 			str = info->name;
   239 			break;
   240 		}
   241 	case PlInfo_Author:
   242 		{
   243 			str = info->author;
   244 			break;
   245 		}
   246 	case PlInfo_Description:
   247 		{
   248 			str = info->description;
   249 			break;
   250 		}
   251 	case PlInfo_Version:
   252 		{
   253 			str = info->version;
   254 			break;
   255 		}
   256 	case PlInfo_URL:
   257 		{
   258 			str = info->url;
   259 			break;
   260 		}
   261 	}
   262 
   263 	if (!str || str[0] == '\0')
   264 	{
   265 		return 0;
   266 	}
   267 
   268 	pContext->StringToLocalUTF8(params[3], params[4], str, NULL);
   269 
   270 	return 1;
   271 }
   272 
   273 static cell_t SetFailState(IPluginContext *pContext, const cell_t *params)
   274 {
   275 	char *str;
   276 	pContext->LocalToString(params[1], &str);
   277 
   278 	CPlugin *pPlugin = g_PluginSys.GetPluginByCtx(pContext->GetContext());
   279 	pPlugin->SetErrorState(Plugin_Error, "%s", str);
   280 
   281 	return pContext->ThrowNativeErrorEx(SP_ERROR_ABORTED, "%s", str);
   282 }
   283 
   284 static cell_t GetSysTickCount(IPluginContext *pContext, const cell_t *params)
   285 {
   286 #if defined PLATFORM_WINDOWS
   287 	return (cell_t)GetTickCount();
   288 #elif defined PLATFORM_LINUX
   289 	tms tm;
   290 	clock_t ticks = times(&tm);
   291 	long ticks_per_sec = sysconf(_SC_CLK_TCK);
   292 	double fticks = (double)ticks / (double)ticks_per_sec;
   293 	fticks *= 1000.0f;
   294 	if (fticks > INT_MAX)
   295 	{
   296 		double r = (int)(fticks / INT_MAX) * (double)INT_MAX;
   297 		fticks -= r;
   298 	}
   299 	return (cell_t)fticks;
   300 #endif
   301 }
   302 
   303 static cell_t AutoExecConfig(IPluginContext *pContext, const cell_t *params)
   304 {
   305 	CPlugin *plugin = g_PluginSys.GetPluginByCtx(pContext->GetContext());
   306 
   307 	char *cfg, *folder;
   308 	pContext->LocalToString(params[2], &cfg);
   309 	pContext->LocalToString(params[3], &folder);
   310 
   311 	if (cfg[0] == '\0')
   312 	{
   313 		static char temp_str[255];
   314 		static char temp_file[PLATFORM_MAX_PATH];
   315 		char *ptr;
   316 
   317 		g_LibSys.GetFileFromPath(temp_str, sizeof(temp_str), plugin->GetFilename());
   318 		if ((ptr = strstr(temp_str, ".smx")) != NULL)
   319 		{
   320 			*ptr = '\0';
   321 		}
   322 
   323 		/* We have the raw filename! */
   324 		UTIL_Format(temp_file, sizeof(temp_file), "plugin.%s", temp_str);
   325 		cfg = temp_file;
   326 	}
   327 
   328 	plugin->AddConfig(params[1] ? true : false, cfg, folder);
   329 
   330 	return 1;
   331 }
   332 
   333 static cell_t MarkNativeAsOptional(IPluginContext *pContext, const cell_t *params)
   334 {
   335 	char *name;
   336 	uint32_t idx;
   337 	sp_context_t *ctx = pContext->GetContext();
   338 
   339 	pContext->LocalToString(params[1], &name);
   340 	if (pContext->FindNativeByName(name, &idx) != SP_ERROR_NONE)
   341 	{
   342 		return pContext->ThrowNativeError("Unable to find native \"%s\"", name);
   343 	}
   344 
   345 	ctx->natives[idx].flags |= SP_NTVFLAG_OPTIONAL;
   346 
   347 	return 1;
   348 }
   349 
   350 static cell_t RegPluginLibrary(IPluginContext *pContext, const cell_t *params)
   351 {
   352 	char *name;
   353 	CPlugin *pl = g_PluginSys.GetPluginByCtx(pContext->GetContext());
   354 
   355 	pContext->LocalToString(params[1], &name);
   356 
   357 	pl->AddLibrary(name);
   358 
   359 	return 1;
   360 }
   361 
   362 REGISTER_NATIVES(coreNatives)
   363 {
   364 	{"AutoExecConfig",			AutoExecConfig},
   365 	{"GetPluginFilename",		GetPluginFilename},
   366 	{"GetPluginInfo",			GetPluginInfo},
   367 	{"GetPluginIterator",		GetPluginIterator},
   368 	{"GetPluginStatus",			GetPluginStatus},
   369 	{"GetSysTickCount",			GetSysTickCount},
   370 	{"GetTime",					GetTime},
   371 	{"IsPluginDebugging",		IsPluginDebugging},
   372 	{"MorePlugins",				MorePlugins},
   373 	{"ReadPlugin",				ReadPlugin},
   374 	{"ThrowError",				ThrowError},
   375 	{"SetFailState",			SetFailState},
   376 	{"FormatTime",				FormatTime},
   377 	{"MarkNativeAsOptional",	MarkNativeAsOptional},
   378 	{"RegPluginLibrary",		RegPluginLibrary},
   379 	{NULL,						NULL},
   380 };