3 * ===============================================================
4 * SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved.
5 * ===============================================================
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
16 #include "sm_globals.h"
17 #include "sourcemod.h"
18 #include "PluginSys.h"
19 #include "HandleSys.h"
21 #if defined PLATFORM_WINDOWS
23 #elif defined PLATFORM_LINUX
26 #include <sys/times.h>
29 HandleType_t g_PlIter;
31 class CoreNativeHelpers :
33 public IHandleTypeDispatch
36 void OnSourceModAllInitialized()
39 g_HandleSys.InitAccessDefaults(NULL, &hacc);
40 hacc.access[HandleAccess_Clone] = HANDLE_RESTRICT_IDENTITY|HANDLE_RESTRICT_OWNER;
42 g_PlIter = g_HandleSys.CreateType("PluginIterator", this, 0, NULL, NULL, g_pCoreIdent, NULL);
44 void OnHandleDestroy(HandleType_t type, void *object)
46 IPluginIterator *iter = (IPluginIterator *)object;
49 void OnSourceModShutdown()
51 g_HandleSys.RemoveType(g_PlIter, g_pCoreIdent);
53 } g_CoreNativeHelpers;
56 static cell_t ThrowError(IPluginContext *pContext, const cell_t *params)
60 g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 1);
62 if (pContext->GetContext()->n_err == SP_ERROR_NONE)
64 pContext->ThrowNativeErrorEx(SP_ERROR_ABORTED, "%s", buffer);
70 static cell_t GetTime(IPluginContext *pContext, const cell_t *params)
72 time_t t = time(NULL);
74 pContext->LocalToPhysAddr(params[1], &addr);
78 return static_cast<cell_t>(t);
81 static cell_t GetPluginIterator(IPluginContext *pContext, const cell_t *params)
83 IPluginIterator *iter = g_PluginSys.GetPluginIterator();
85 Handle_t hndl = g_HandleSys.CreateHandle(g_PlIter, iter, pContext->GetIdentity(), g_pCoreIdent, NULL);
87 if (hndl == BAD_HANDLE)
95 static cell_t MorePlugins(IPluginContext *pContext, const cell_t *params)
97 Handle_t hndl = (Handle_t)params[1];
99 IPluginIterator *pIter;
102 sec.pIdentity = g_pCoreIdent;
103 sec.pOwner = pContext->GetIdentity();
105 if ((err=g_HandleSys.ReadHandle(hndl, g_PlIter, &sec, (void **)&pIter)) != HandleError_None)
107 return pContext->ThrowNativeError("Could not read Handle %x (error %d)", hndl, err);
110 return pIter->MorePlugins() ? 1 : 0;
113 static cell_t ReadPlugin(IPluginContext *pContext, const cell_t *params)
115 Handle_t hndl = (Handle_t)params[1];
117 IPluginIterator *pIter;
120 sec.pIdentity = g_pCoreIdent;
121 sec.pOwner = pContext->GetIdentity();
123 if ((err=g_HandleSys.ReadHandle(hndl, g_PlIter, &sec, (void **)&pIter)) != HandleError_None)
125 return pContext->ThrowNativeError("Could not read Handle %x (error %d)", hndl, err);
128 CPlugin *pPlugin = (CPlugin *)pIter->GetPlugin();
136 return pPlugin->GetMyHandle();
139 CPlugin *GetPluginFromHandle(IPluginContext *pContext, Handle_t hndl)
141 if (hndl == BAD_HANDLE)
143 return g_PluginSys.GetPluginByCtx(pContext->GetContext());
146 CPlugin *pPlugin = (CPlugin *)g_PluginSys.PluginFromHandle(hndl, &err);
149 pContext->ThrowNativeError("Could not read Handle %x (error %d)", hndl, err);
155 static cell_t GetPluginStatus(IPluginContext *pContext, const cell_t *params)
157 CPlugin *pPlugin = GetPluginFromHandle(pContext, params[1]);
163 return pPlugin->GetStatus();
166 static cell_t GetPluginFilename(IPluginContext *pContext, const cell_t *params)
168 CPlugin *pPlugin = GetPluginFromHandle(pContext, params[1]);
174 pContext->StringToLocalUTF8(params[2], params[3], pPlugin->GetFilename(), NULL);
179 static cell_t IsPluginDebugging(IPluginContext *pContext, const cell_t *params)
181 CPlugin *pPlugin = GetPluginFromHandle(pContext, params[1]);
187 return pPlugin->IsDebugging() ? 1 : 0;
190 /* Local to plugins only */
193 PlInfo_Name, /**< Plugin name */
194 PlInfo_Author, /**< Plugin author */
195 PlInfo_Description, /**< Plugin description */
196 PlInfo_Version, /**< Plugin verison */
197 PlInfo_URL, /**< Plugin URL */
200 static cell_t GetPluginInfo(IPluginContext *pContext, const cell_t *params)
202 CPlugin *pPlugin = GetPluginFromHandle(pContext, params[1]);
208 const sm_plugininfo_t *info = pPlugin->GetPublicInfo();
215 const char *str = NULL;
217 switch ((PluginInfo)params[2])
229 case PlInfo_Description:
231 str = info->description;
246 if (!str || str[0] == '\0')
251 pContext->StringToLocalUTF8(params[3], params[4], str, NULL);
256 static cell_t SetFailState(IPluginContext *pContext, const cell_t *params)
259 pContext->LocalToString(params[1], &str);
261 CPlugin *pPlugin = g_PluginSys.GetPluginByCtx(pContext->GetContext());
262 pPlugin->SetErrorState(Plugin_Error, "%s", str);
264 return pContext->ThrowNativeErrorEx(SP_ERROR_ABORTED, "%s", str);
267 static cell_t GetSysTickCount(IPluginContext *pContext, const cell_t *params)
269 #if defined PLATFORM_WINDOWS
270 return (cell_t)GetTickCount();
271 #elif defined PLATFORM_LINUX
273 clock_t ticks = times(&tm);
274 long ticks_per_sec = sysconf(_SC_CLK_TCK);
275 double fticks = (double)ticks / (double)ticks_per_sec;
277 if (fticks > INT_MAX)
279 double r = (int)(fticks / INT_MAX) * (double)INT_MAX;
282 return (cell_t)fticks;
286 REGISTER_NATIVES(coreNatives)
288 {"GetPluginFilename", GetPluginFilename},
289 {"GetPluginInfo", GetPluginInfo},
290 {"GetPluginIterator", GetPluginIterator},
291 {"GetPluginStatus", GetPluginStatus},
292 {"GetSysTickCount", GetSysTickCount},
293 {"GetTime", GetTime},
294 {"IsPluginDebugging", IsPluginDebugging},
295 {"MorePlugins", MorePlugins},
296 {"ReadPlugin", ReadPlugin},
297 {"ThrowError", ThrowError},
298 {"SetFailState", SetFailState},