Merge.
Merge.
1.1 --- a/AMBuildScript Thu May 13 04:18:58 2010 -0500
1.2 +++ b/AMBuildScript Thu May 13 04:19:39 2010 -0500
1.3 @@ -82,6 +82,7 @@
1.4 self.compiler.AddToListVar('CFLAGS', '-mfpmath=sse')
1.5 self.compiler.AddToListVar('CFLAGS', '-msse')
1.6 self.compiler.AddToListVar('CFLAGS', '-m32')
1.7 + self.compiler.AddToListVar('POSTLINKFLAGS', '-m32')
1.8 self.compiler.AddToListVar('CFLAGS', '-static-libgcc')
1.9 self.compiler.AddToListVar('CXXFLAGS', '-fno-exceptions')
1.10 self.compiler.AddToListVar('CXXFLAGS', '-fno-rtti')
2.1 --- a/core/AMBuilder Thu May 13 04:18:58 2010 -0500
2.2 +++ b/core/AMBuilder Thu May 13 04:19:39 2010 -0500
2.3 @@ -64,7 +64,6 @@
2.4 'PluginSys.cpp',
2.5 'smn_console.cpp',
2.6 'smn_handles.cpp',
2.7 - 'smn_timers.cpp',
2.8 'UserMessages.cpp',
2.9 'Database.cpp',
2.10 'MenuManager.cpp',
3.1 --- a/core/DebugReporter.cpp Thu May 13 04:18:58 2010 -0500
3.2 +++ b/core/DebugReporter.cpp Thu May 13 04:19:39 2010 -0500
3.3 @@ -56,11 +56,16 @@
3.4 void DebugReport::GenerateError(IPluginContext *ctx, cell_t func_idx, int err, const char *message, ...)
3.5 {
3.6 va_list ap;
3.7 - char buffer[512];
3.8
3.9 va_start(ap, message);
3.10 + GenerateErrorVA(ctx, func_idx, err, message, ap);
3.11 + va_end(ap);
3.12 +}
3.13 +
3.14 +void DebugReport::GenerateErrorVA(IPluginContext *ctx, cell_t func_idx, int err, const char *message, va_list ap)
3.15 +{
3.16 + char buffer[512];
3.17 UTIL_FormatArgs(buffer, sizeof(buffer), message, ap);
3.18 - va_end(ap);
3.19
3.20 const char *plname = g_PluginSys.FindPluginByContext(ctx->GetContext())->GetFilename();
3.21 const char *error = g_pSourcePawn2->GetErrorString(err);
4.1 --- a/core/DebugReporter.h Thu May 13 04:18:58 2010 -0500
4.2 +++ b/core/DebugReporter.h Thu May 13 04:19:39 2010 -0500
4.3 @@ -46,6 +46,7 @@
4.4 void OnDebugSpew(const char *msg, ...);
4.5 public:
4.6 void GenerateError(IPluginContext *ctx, cell_t func_idx, int err, const char *message, ...);
4.7 + void GenerateErrorVA(IPluginContext *ctx, cell_t func_idx, int err, const char *message, va_list ap);
4.8 void GenerateCodeError(IPluginContext *ctx, uint32_t code_addr, int err, const char *message, ...);
4.9 private:
4.10 int _GetPluginIndex(IPluginContext *ctx);
5.1 --- a/core/Makefile Thu May 13 04:18:58 2010 -0500
5.2 +++ b/core/Makefile Thu May 13 04:19:39 2010 -0500
5.3 @@ -26,7 +26,7 @@
5.4 smn_datapacks.cpp smn_entities.cpp smn_events.cpp smn_fakenatives.cpp \
5.5 smn_filesystem.cpp smn_gameconfigs.cpp smn_halflife.cpp \
5.6 smn_handles.cpp smn_keyvalues.cpp smn_banning.cpp \
5.7 - smn_lang.cpp smn_player.cpp smn_string.cpp smn_timers.cpp \
5.8 + smn_lang.cpp smn_player.cpp smn_string.cpp \
5.9 smn_usermsgs.cpp smn_menus.cpp smn_database.cpp smn_vector.cpp \
5.10 smn_hudtext.cpp smn_nextmap.cpp
5.11 OBJECTS += ExtensionSys.cpp \
6.1 --- a/core/TimerSys.h Thu May 13 04:18:58 2010 -0500
6.2 +++ b/core/TimerSys.h Thu May 13 04:19:39 2010 -0500
6.3 @@ -78,11 +78,11 @@
6.4 float GetTickedTime();
6.5 void NotifyOfGameStart(float offset /* = 0.0f */);
6.6 bool GetMapTimeLeft(float *pTime);
6.7 + IMapTimer *GetMapTimer();
6.8 public:
6.9 void RunFrame();
6.10 void RemoveMapChangeTimers();
6.11 void GameFrame(bool simulating);
6.12 - IMapTimer *GetMapTimer();
6.13 private:
6.14 List<ITimer *> m_SingleTimers;
6.15 List<ITimer *> m_LoopTimers;
7.1 --- a/core/logic/AMBuilder Thu May 13 04:18:58 2010 -0500
7.2 +++ b/core/logic/AMBuilder Thu May 13 04:19:39 2010 -0500
7.3 @@ -30,6 +30,7 @@
7.4 'smn_adt_trie.cpp',
7.5 'Profiler.cpp',
7.6 'smn_functions.cpp',
7.7 + 'smn_timers.cpp',
7.8 'sm_crc32.cpp'
7.9 ]
7.10 if AMBuild.target['platform'] == 'windows':
8.1 --- a/core/logic/Makefile Thu May 13 04:18:58 2010 -0500
8.2 +++ b/core/logic/Makefile Thu May 13 04:19:39 2010 -0500
8.3 @@ -26,7 +26,8 @@
8.4 smn_adt_trie.cpp \
8.5 Profiler.cpp \
8.6 smn_functions.cpp \
8.7 - sm_crc32.cpp
8.8 + sm_crc32.cpp \
8.9 + smn_timers.cpp
8.10
8.11 ##############################################
8.12 ### CONFIGURE ANY OTHER FLAGS/OPTIONS HERE ###
9.1 --- a/core/logic/common_logic.cpp Thu May 13 04:18:58 2010 -0500
9.2 +++ b/core/logic/common_logic.cpp Thu May 13 04:19:39 2010 -0500
9.3 @@ -50,6 +50,8 @@
9.4 IRootConsole *rootmenu;
9.5 IPluginManager *pluginsys;
9.6 IForwardManager *forwardsys;
9.7 +ITimerSystem *timersys;
9.8 +ServerGlobals serverGlobals;
9.9
9.10 static sm_logic_t logic =
9.11 {
9.12 @@ -65,6 +67,7 @@
9.13
9.14 memcpy(&smcore, core, sizeof(sm_core_t));
9.15 memcpy(_logic, &logic, sizeof(sm_logic_t));
9.16 + memcpy(&serverGlobals, core->serverGlobals, sizeof(ServerGlobals));
9.17
9.18 handlesys = core->handlesys;
9.19 libsys = core->libsys;
9.20 @@ -75,6 +78,7 @@
9.21 rootmenu = core->rootmenu;
9.22 pluginsys = core->pluginsys;
9.23 forwardsys = core->forwardsys;
9.24 + timersys = core->timersys;
9.25 }
9.26
9.27 PLATFORM_EXTERN_C ITextParsers *get_textparsers()
10.1 --- a/core/logic/common_logic.h Thu May 13 04:18:58 2010 -0500
10.2 +++ b/core/logic/common_logic.h Thu May 13 04:19:39 2010 -0500
10.3 @@ -47,6 +47,8 @@
10.4 extern IRootConsole *rootmenu;
10.5 extern IPluginManager *pluginsys;
10.6 extern IForwardManager *forwardsys;
10.7 +extern ITimerSystem *timersys;
10.8 +extern ServerGlobals serverGlobals;
10.9
10.10 #endif /* _INCLUDE_SOURCEMOD_COMMON_LOGIC_H_ */
10.11
11.1 --- a/core/logic/intercom.h Thu May 13 04:18:58 2010 -0500
11.2 +++ b/core/logic/intercom.h Thu May 13 04:19:39 2010 -0500
11.3 @@ -42,7 +42,7 @@
11.4 * Add 1 to the RHS of this expression to bump the intercom file
11.5 * This is to prevent mismatching core/logic binaries
11.6 */
11.7 -#define SM_LOGIC_MAGIC (0x0F47C0DE - 3)
11.8 +#define SM_LOGIC_MAGIC (0x0F47C0DE - 4)
11.9
11.10 #if defined SM_LOGIC
11.11 class IVEngineServer
11.12 @@ -63,11 +63,19 @@
11.13 class IRootConsole;
11.14 class IPluginManager;
11.15 class IForwardManager;
11.16 + class ITimerSystem;
11.17 }
11.18
11.19 class IVEngineServer;
11.20 class ConVar;
11.21
11.22 +struct ServerGlobals
11.23 +{
11.24 + const double *universalTime;
11.25 + float *interval_per_tick;
11.26 + float *frametime;
11.27 +};
11.28 +
11.29 struct sm_core_t
11.30 {
11.31 /* Objects */
11.32 @@ -80,6 +88,7 @@
11.33 IRootConsole *rootmenu;
11.34 IPluginManager *pluginsys;
11.35 IForwardManager *forwardsys;
11.36 + ITimerSystem *timersys;
11.37 /* Functions */
11.38 void (*AddNatives)(sp_nativeinfo_t* nlist);
11.39 ConVar * (*FindConVar)(const char*);
11.40 @@ -89,6 +98,9 @@
11.41 const char * (*GetCvarString)(ConVar*);
11.42 size_t (*Format)(char*, size_t, const char*, ...);
11.43 unsigned int (*ReplaceAll)(char*, size_t, const char *, const char *, bool);
11.44 + void (*GenerateError)(IPluginContext *, cell_t, int, const char *, ...);
11.45 + /* Data */
11.46 + ServerGlobals *serverGlobals;
11.47 };
11.48
11.49 struct sm_logic_t
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
12.2 +++ b/core/logic/smn_timers.cpp Thu May 13 04:19:39 2010 -0500
12.3 @@ -0,0 +1,367 @@
12.4 +/**
12.5 + * vim: set ts=4 :
12.6 + * =============================================================================
12.7 + * SourceMod
12.8 + * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
12.9 + * =============================================================================
12.10 + *
12.11 + * This program is free software; you can redistribute it and/or modify it under
12.12 + * the terms of the GNU General Public License, version 3.0, as published by the
12.13 + * Free Software Foundation.
12.14 + *
12.15 + * This program is distributed in the hope that it will be useful, but WITHOUT
12.16 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12.17 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
12.18 + * details.
12.19 + *
12.20 + * You should have received a copy of the GNU General Public License along with
12.21 + * this program. If not, see <http://www.gnu.org/licenses/>.
12.22 + *
12.23 + * As a special exception, AlliedModders LLC gives you permission to link the
12.24 + * code of this program (as well as its derivative works) to "Half-Life 2," the
12.25 + * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
12.26 + * by the Valve Corporation. You must obey the GNU General Public License in
12.27 + * all respects for all other code used. Additionally, AlliedModders LLC grants
12.28 + * this exception to all derivative works. AlliedModders LLC defines further
12.29 + * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
12.30 + * or <http://www.sourcemod.net/license.php>.
12.31 + *
12.32 + * Version: $Id$
12.33 + */
12.34 +
12.35 +#include "common_logic.h"
12.36 +#include <string.h>
12.37 +#include <IHandleSys.h>
12.38 +#include <ITimerSystem.h>
12.39 +#include <IPluginSys.h>
12.40 +#include <sh_stack.h>
12.41 +
12.42 +using namespace SourceHook;
12.43 +
12.44 +#define TIMER_DATA_HNDL_CLOSE (1<<9)
12.45 +#define TIMER_HNDL_CLOSE (1<<9)
12.46 +
12.47 +HandleType_t g_TimerType;
12.48 +
12.49 +struct TimerInfo
12.50 +{
12.51 + ITimer *Timer;
12.52 + IPluginFunction *Hook;
12.53 + IPluginContext *pContext;
12.54 + Handle_t TimerHandle;
12.55 + int UserData;
12.56 + int Flags;
12.57 +};
12.58 +
12.59 +class TimerNatives :
12.60 + public SMGlobalClass,
12.61 + public IHandleTypeDispatch,
12.62 + public ITimedEvent
12.63 +{
12.64 +public:
12.65 + ~TimerNatives();
12.66 +public: //ITimedEvent
12.67 + ResultType OnTimer(ITimer *pTimer, void *pData);
12.68 + void OnTimerEnd(ITimer *pTimer, void *pData);
12.69 +public: //IHandleTypeDispatch
12.70 + void OnHandleDestroy(HandleType_t type, void *object);
12.71 +public: //SMGlobalClass
12.72 + void OnSourceModAllInitialized();
12.73 + void OnSourceModShutdown();
12.74 +public:
12.75 + TimerInfo *CreateTimerInfo();
12.76 + void DeleteTimerInfo(TimerInfo *pInfo);
12.77 +private:
12.78 + CStack<TimerInfo *> m_FreeTimers;
12.79 +};
12.80 +
12.81 +TimerNatives::~TimerNatives()
12.82 +{
12.83 + CStack<TimerInfo *>::iterator iter;
12.84 + for (iter=m_FreeTimers.begin(); iter!=m_FreeTimers.end(); iter++)
12.85 + {
12.86 + delete (*iter);
12.87 + }
12.88 + m_FreeTimers.popall();
12.89 +}
12.90 +
12.91 +void TimerNatives::OnSourceModAllInitialized()
12.92 +{
12.93 + HandleAccess sec;
12.94 +
12.95 + handlesys->InitAccessDefaults(NULL, &sec);
12.96 + sec.access[HandleAccess_Clone] = HANDLE_RESTRICT_IDENTITY;
12.97 +
12.98 + g_TimerType = handlesys->CreateType("Timer", this, 0, NULL, &sec, g_pCoreIdent, NULL);
12.99 +}
12.100 +
12.101 +void TimerNatives::OnSourceModShutdown()
12.102 +{
12.103 + handlesys->RemoveType(g_TimerType, g_pCoreIdent);
12.104 + g_TimerType = 0;
12.105 +}
12.106 +
12.107 +void TimerNatives::OnHandleDestroy(HandleType_t type, void *object)
12.108 +{
12.109 + TimerInfo *pTimer = reinterpret_cast<TimerInfo *>(object);
12.110 +
12.111 + timersys->KillTimer(pTimer->Timer);
12.112 +}
12.113 +
12.114 +TimerInfo *TimerNatives::CreateTimerInfo()
12.115 +{
12.116 + TimerInfo *pInfo;
12.117 +
12.118 + if (m_FreeTimers.empty())
12.119 + {
12.120 + pInfo = new TimerInfo;
12.121 + } else {
12.122 + pInfo = m_FreeTimers.front();
12.123 + m_FreeTimers.pop();
12.124 + }
12.125 +
12.126 + return pInfo;
12.127 +}
12.128 +
12.129 +void TimerNatives::DeleteTimerInfo(TimerInfo *pInfo)
12.130 +{
12.131 + m_FreeTimers.push(pInfo);
12.132 +}
12.133 +
12.134 +ResultType TimerNatives::OnTimer(ITimer *pTimer, void *pData)
12.135 +{
12.136 + TimerInfo *pInfo = reinterpret_cast<TimerInfo *>(pData);
12.137 + IPluginFunction *pFunc = pInfo->Hook;
12.138 + cell_t res = static_cast<ResultType>(Pl_Continue);
12.139 +
12.140 + pFunc->PushCell(pInfo->TimerHandle);
12.141 + pFunc->PushCell(pInfo->UserData);
12.142 + pFunc->Execute(&res);
12.143 +
12.144 + return static_cast<ResultType>(res);
12.145 +}
12.146 +
12.147 +void TimerNatives::OnTimerEnd(ITimer *pTimer, void *pData)
12.148 +{
12.149 + HandleSecurity sec;
12.150 + HandleError herr;
12.151 + TimerInfo *pInfo = reinterpret_cast<TimerInfo *>(pData);
12.152 + Handle_t usrhndl = static_cast<Handle_t>(pInfo->UserData);
12.153 +
12.154 + sec.pOwner = pInfo->pContext->GetIdentity();
12.155 + sec.pIdentity = g_pCoreIdent;
12.156 +
12.157 + if (pInfo->Flags & TIMER_DATA_HNDL_CLOSE)
12.158 + {
12.159 + if ((herr=handlesys->FreeHandle(usrhndl, &sec)) != HandleError_None)
12.160 + {
12.161 + smcore.GenerateError(pInfo->pContext, pInfo->Hook->GetFunctionID(),
12.162 + SP_ERROR_NATIVE,
12.163 + "Invalid data handle %x (error %d) passed during timer end with TIMER_DATA_HNDL_CLOSE",
12.164 + usrhndl, herr);
12.165 + }
12.166 + }
12.167 +
12.168 + if (pInfo->TimerHandle != BAD_HANDLE)
12.169 + {
12.170 + if ((herr=handlesys->FreeHandle(pInfo->TimerHandle, &sec)) != HandleError_None)
12.171 + {
12.172 + smcore.GenerateError(pInfo->pContext, pInfo->Hook->GetFunctionID(),
12.173 + SP_ERROR_NATIVE,
12.174 + "Invalid timer handle %x (error %d) during timer end, displayed function is timer callback, not the stack trace",
12.175 + pInfo->TimerHandle, herr);
12.176 + }
12.177 + }
12.178 +
12.179 + DeleteTimerInfo(pInfo);
12.180 +}
12.181 +
12.182 +/*******************************
12.183 +* *
12.184 +* TIMER NATIVE IMPLEMENTATIONS *
12.185 +* *
12.186 +********************************/
12.187 +
12.188 +static TimerNatives s_TimerNatives;
12.189 +
12.190 +static cell_t smn_CreateTimer(IPluginContext *pCtx, const cell_t *params)
12.191 +{
12.192 + IPluginFunction *pFunc;
12.193 + TimerInfo *pInfo;
12.194 + ITimer *pTimer;
12.195 + Handle_t hndl;
12.196 + int flags = params[4];
12.197 +
12.198 + pFunc = pCtx->GetFunctionById(params[2]);
12.199 + if (!pFunc)
12.200 + {
12.201 + return pCtx->ThrowNativeError("Invalid function id (%X)", params[2]);
12.202 + }
12.203 +
12.204 + pInfo = s_TimerNatives.CreateTimerInfo();
12.205 + pTimer = timersys->CreateTimer(&s_TimerNatives, sp_ctof(params[1]), pInfo, flags);
12.206 +
12.207 + if (!pTimer)
12.208 + {
12.209 + s_TimerNatives.DeleteTimerInfo(pInfo);
12.210 + return 0;
12.211 + }
12.212 +
12.213 + hndl = handlesys->CreateHandle(g_TimerType, pInfo, pCtx->GetIdentity(), g_pCoreIdent, NULL);
12.214 +
12.215 + /* If we can't get a handle, the timer isn't refcounted against the plugin and
12.216 + * we need to bail out to prevent a crash.
12.217 + */
12.218 + if (hndl == BAD_HANDLE)
12.219 + {
12.220 + /* Free this for completeness. */
12.221 + if (flags & TIMER_DATA_HNDL_CLOSE)
12.222 + {
12.223 + HandleSecurity sec(pCtx->GetIdentity(), g_pCoreIdent);
12.224 + handlesys->FreeHandle(params[3], &sec);
12.225 + }
12.226 + /* Zero everything so there's no conflicts */
12.227 + memset(pInfo, 0, sizeof(TimerInfo));
12.228 + timersys->KillTimer(pTimer);
12.229 +
12.230 + return pCtx->ThrowNativeError("Could not create timer, no more handles");
12.231 + }
12.232 +
12.233 + pInfo->UserData = params[3];
12.234 + pInfo->Flags = flags;
12.235 + pInfo->TimerHandle = hndl;
12.236 + pInfo->Hook = pFunc;
12.237 + pInfo->Timer = pTimer;
12.238 + pInfo->pContext = pCtx;
12.239 +
12.240 + return hndl;
12.241 +}
12.242 +
12.243 +static cell_t smn_KillTimer(IPluginContext *pCtx, const cell_t *params)
12.244 +{
12.245 + Handle_t hndl = static_cast<Handle_t>(params[1]);
12.246 + HandleError herr;
12.247 + HandleSecurity sec;
12.248 + TimerInfo *pInfo;
12.249 +
12.250 + sec.pOwner = pCtx->GetIdentity();
12.251 + sec.pIdentity = g_pCoreIdent;
12.252 +
12.253 + if ((herr=handlesys->ReadHandle(hndl, g_TimerType, &sec, (void **)&pInfo))
12.254 + != HandleError_None)
12.255 + {
12.256 + return pCtx->ThrowNativeError("Invalid timer handle %x (error %d)", hndl, herr);
12.257 + }
12.258 +
12.259 + timersys->KillTimer(pInfo->Timer);
12.260 +
12.261 + if (params[2] && !(pInfo->Flags & TIMER_DATA_HNDL_CLOSE))
12.262 + {
12.263 + sec.pOwner = pInfo->pContext->GetIdentity();
12.264 + sec.pIdentity = g_pCoreIdent;
12.265 +
12.266 + if ((herr=handlesys->FreeHandle(static_cast<Handle_t>(pInfo->UserData), &sec)) != HandleError_None)
12.267 + {
12.268 + return pCtx->ThrowNativeError("Invalid data handle %x (error %d) on timer kill with TIMER_DATA_HNDL_CLOSE", hndl, herr);
12.269 + }
12.270 + }
12.271 +
12.272 + return 1;
12.273 +}
12.274 +
12.275 +static cell_t smn_TriggerTimer(IPluginContext *pCtx, const cell_t *params)
12.276 +{
12.277 + Handle_t hndl = static_cast<Handle_t>(params[1]);
12.278 + HandleError herr;
12.279 + HandleSecurity sec;
12.280 + TimerInfo *pInfo;
12.281 +
12.282 + sec.pOwner = pCtx->GetIdentity();
12.283 + sec.pIdentity = g_pCoreIdent;
12.284 +
12.285 + if ((herr=handlesys->ReadHandle(hndl, g_TimerType, &sec, (void **)&pInfo))
12.286 + != HandleError_None)
12.287 + {
12.288 + return pCtx->ThrowNativeError("Invalid timer handle %x (error %d)", hndl, herr);
12.289 + }
12.290 +
12.291 + timersys->FireTimerOnce(pInfo->Timer, params[2] ? true : false);
12.292 +
12.293 + return 1;
12.294 +}
12.295 +
12.296 +static cell_t smn_GetTickedTime(IPluginContext *pContext, const cell_t *params)
12.297 +{
12.298 + return sp_ftoc(*serverGlobals.universalTime);
12.299 +}
12.300 +
12.301 +static cell_t smn_GetMapTimeLeft(IPluginContext *pContext, const cell_t *params)
12.302 +{
12.303 + float time_left;
12.304 + if (!timersys->GetMapTimeLeft(&time_left))
12.305 + {
12.306 + return 0;
12.307 + }
12.308 +
12.309 + cell_t *addr;
12.310 + pContext->LocalToPhysAddr(params[1], &addr);
12.311 + *addr = (int)time_left;
12.312 +
12.313 + return 1;
12.314 +}
12.315 +
12.316 +static cell_t smn_GetMapTimeLimit(IPluginContext *pContext, const cell_t *params)
12.317 +{
12.318 + IMapTimer *pMapTimer = timersys->GetMapTimer();
12.319 +
12.320 + if (!pMapTimer)
12.321 + {
12.322 + return 0;
12.323 + }
12.324 +
12.325 + cell_t *addr;
12.326 + pContext->LocalToPhysAddr(params[1], &addr);
12.327 +
12.328 + *addr = pMapTimer->GetMapTimeLimit();
12.329 +
12.330 + return 1;
12.331 +}
12.332 +
12.333 +static cell_t smn_ExtendMapTimeLimit(IPluginContext *pContext, const cell_t *params)
12.334 +{
12.335 + IMapTimer *pMapTimer = timersys->GetMapTimer();
12.336 +
12.337 + if (!pMapTimer)
12.338 + {
12.339 + return 0;
12.340 + }
12.341 +
12.342 + pMapTimer->ExtendMapTimeLimit(params[1]);
12.343 +
12.344 + return 1;
12.345 +}
12.346 +
12.347 +static cell_t smn_IsServerProcessing(IPluginContext *pContext, const cell_t *params)
12.348 +{
12.349 + return (*serverGlobals.frametime > 0.0f) ? 1 : 0;
12.350 +}
12.351 +
12.352 +static cell_t smn_GetTickInterval(IPluginContext *pContext, const cell_t *params)
12.353 +{
12.354 + return sp_ftoc(*serverGlobals.interval_per_tick);
12.355 +}
12.356 +
12.357 +REGISTER_NATIVES(timernatives)
12.358 +{
12.359 + {"CreateTimer", smn_CreateTimer},
12.360 + {"KillTimer", smn_KillTimer},
12.361 + {"TriggerTimer", smn_TriggerTimer},
12.362 + {"GetTickedTime", smn_GetTickedTime},
12.363 + {"GetMapTimeLeft", smn_GetMapTimeLeft},
12.364 + {"GetMapTimeLimit", smn_GetMapTimeLimit},
12.365 + {"ExtendMapTimeLimit", smn_ExtendMapTimeLimit},
12.366 + {"IsServerProcessing", smn_IsServerProcessing},
12.367 + {"GetTickInterval", smn_GetTickInterval},
12.368 + {NULL, NULL}
12.369 +};
12.370 +
13.1 --- a/core/logic_bridge.cpp Thu May 13 04:18:58 2010 -0500
13.2 +++ b/core/logic_bridge.cpp Thu May 13 04:19:39 2010 -0500
13.3 @@ -43,7 +43,9 @@
13.4 #include "ShareSys.h"
13.5 #include "sm_srvcmds.h"
13.6 #include "ForwardSys.h"
13.7 +#include "TimerSys.h"
13.8 #include "logic_bridge.h"
13.9 +#include "DebugReporter.h"
13.10
13.11 static ILibrary *g_pLogic = NULL;
13.12 static LogicInitFunction logic_init_fn;
13.13 @@ -82,11 +84,22 @@
13.14 va_end(ap);
13.15 }
13.16
13.17 +static void generate_error(IPluginContext *ctx, cell_t func_idx, int err, const char *fmt, ...)
13.18 +{
13.19 + va_list ap;
13.20 +
13.21 + va_start(ap, fmt);
13.22 + g_DbgReporter.GenerateErrorVA(ctx, func_idx, err, fmt, ap);
13.23 + va_end(ap);
13.24 +}
13.25 +
13.26 static const char *get_cvar_string(ConVar* cvar)
13.27 {
13.28 return cvar->GetString();
13.29 }
13.30
13.31 +static ServerGlobals serverGlobals;
13.32 +
13.33 static sm_core_t core_bridge =
13.34 {
13.35 /* Objects */
13.36 @@ -99,6 +112,7 @@
13.37 &g_RootMenu,
13.38 &g_PluginSys,
13.39 &g_Forwards,
13.40 + &g_Timers,
13.41 /* Functions */
13.42 add_natives,
13.43 find_convar,
13.44 @@ -107,13 +121,19 @@
13.45 log_error,
13.46 get_cvar_string,
13.47 UTIL_Format,
13.48 - UTIL_ReplaceAll
13.49 + UTIL_ReplaceAll,
13.50 + generate_error,
13.51 + &serverGlobals
13.52 };
13.53
13.54 void InitLogicBridge()
13.55 {
13.56 sm_logic_t logic;
13.57
13.58 + serverGlobals.universalTime = g_pUniversalTime;
13.59 + serverGlobals.frametime = &gpGlobals->frametime;
13.60 + serverGlobals.interval_per_tick = &gpGlobals->interval_per_tick;
13.61 +
13.62 core_bridge.core_ident = g_pCoreIdent;
13.63 logic_init_fn(&core_bridge, &logic);
13.64
14.1 --- a/core/smn_timers.cpp Thu May 13 04:18:58 2010 -0500
14.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
14.3 @@ -1,368 +0,0 @@
14.4 -/**
14.5 - * vim: set ts=4 :
14.6 - * =============================================================================
14.7 - * SourceMod
14.8 - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
14.9 - * =============================================================================
14.10 - *
14.11 - * This program is free software; you can redistribute it and/or modify it under
14.12 - * the terms of the GNU General Public License, version 3.0, as published by the
14.13 - * Free Software Foundation.
14.14 - *
14.15 - * This program is distributed in the hope that it will be useful, but WITHOUT
14.16 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14.18 - * details.
14.19 - *
14.20 - * You should have received a copy of the GNU General Public License along with
14.21 - * this program. If not, see <http://www.gnu.org/licenses/>.
14.22 - *
14.23 - * As a special exception, AlliedModders LLC gives you permission to link the
14.24 - * code of this program (as well as its derivative works) to "Half-Life 2," the
14.25 - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
14.26 - * by the Valve Corporation. You must obey the GNU General Public License in
14.27 - * all respects for all other code used. Additionally, AlliedModders LLC grants
14.28 - * this exception to all derivative works. AlliedModders LLC defines further
14.29 - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
14.30 - * or <http://www.sourcemod.net/license.php>.
14.31 - *
14.32 - * Version: $Id$
14.33 - */
14.34 -
14.35 -#include "HandleSys.h"
14.36 -#include "TimerSys.h"
14.37 -#include "PluginSys.h"
14.38 -#include "Logger.h"
14.39 -#include "DebugReporter.h"
14.40 -
14.41 -#define TIMER_DATA_HNDL_CLOSE (1<<9)
14.42 -#define TIMER_HNDL_CLOSE (1<<9)
14.43 -
14.44 -HandleType_t g_TimerType;
14.45 -
14.46 -struct TimerInfo
14.47 -{
14.48 - ITimer *Timer;
14.49 - IPluginFunction *Hook;
14.50 - IPluginContext *pContext;
14.51 - Handle_t TimerHandle;
14.52 - int UserData;
14.53 - int Flags;
14.54 -};
14.55 -
14.56 -class TimerNatives :
14.57 - public SMGlobalClass,
14.58 - public IHandleTypeDispatch,
14.59 - public ITimedEvent
14.60 -{
14.61 -public:
14.62 - ~TimerNatives();
14.63 -public: //ITimedEvent
14.64 - ResultType OnTimer(ITimer *pTimer, void *pData);
14.65 - void OnTimerEnd(ITimer *pTimer, void *pData);
14.66 -public: //IHandleTypeDispatch
14.67 - void OnHandleDestroy(HandleType_t type, void *object);
14.68 -public: //SMGlobalClass
14.69 - void OnSourceModAllInitialized();
14.70 - void OnSourceModShutdown();
14.71 -public:
14.72 - TimerInfo *CreateTimerInfo();
14.73 - void DeleteTimerInfo(TimerInfo *pInfo);
14.74 -private:
14.75 - CStack<TimerInfo *> m_FreeTimers;
14.76 -};
14.77 -
14.78 -TimerNatives::~TimerNatives()
14.79 -{
14.80 - CStack<TimerInfo *>::iterator iter;
14.81 - for (iter=m_FreeTimers.begin(); iter!=m_FreeTimers.end(); iter++)
14.82 - {
14.83 - delete (*iter);
14.84 - }
14.85 - m_FreeTimers.popall();
14.86 -}
14.87 -
14.88 -void TimerNatives::OnSourceModAllInitialized()
14.89 -{
14.90 - HandleAccess sec;
14.91 -
14.92 - g_HandleSys.InitAccessDefaults(NULL, &sec);
14.93 - sec.access[HandleAccess_Clone] = HANDLE_RESTRICT_IDENTITY;
14.94 -
14.95 - g_TimerType = g_HandleSys.CreateType("Timer", this, 0, NULL, &sec, g_pCoreIdent, NULL);
14.96 -}
14.97 -
14.98 -void TimerNatives::OnSourceModShutdown()
14.99 -{
14.100 - g_HandleSys.RemoveType(g_TimerType, g_pCoreIdent);
14.101 - g_TimerType = 0;
14.102 -}
14.103 -
14.104 -void TimerNatives::OnHandleDestroy(HandleType_t type, void *object)
14.105 -{
14.106 - TimerInfo *pTimer = reinterpret_cast<TimerInfo *>(object);
14.107 -
14.108 - g_Timers.KillTimer(pTimer->Timer);
14.109 -}
14.110 -
14.111 -TimerInfo *TimerNatives::CreateTimerInfo()
14.112 -{
14.113 - TimerInfo *pInfo;
14.114 -
14.115 - if (m_FreeTimers.empty())
14.116 - {
14.117 - pInfo = new TimerInfo;
14.118 - } else {
14.119 - pInfo = m_FreeTimers.front();
14.120 - m_FreeTimers.pop();
14.121 - }
14.122 -
14.123 - return pInfo;
14.124 -}
14.125 -
14.126 -void TimerNatives::DeleteTimerInfo(TimerInfo *pInfo)
14.127 -{
14.128 - m_FreeTimers.push(pInfo);
14.129 -}
14.130 -
14.131 -ResultType TimerNatives::OnTimer(ITimer *pTimer, void *pData)
14.132 -{
14.133 - TimerInfo *pInfo = reinterpret_cast<TimerInfo *>(pData);
14.134 - IPluginFunction *pFunc = pInfo->Hook;
14.135 - cell_t res = static_cast<ResultType>(Pl_Continue);
14.136 -
14.137 - pFunc->PushCell(pInfo->TimerHandle);
14.138 - pFunc->PushCell(pInfo->UserData);
14.139 - pFunc->Execute(&res);
14.140 -
14.141 - return static_cast<ResultType>(res);
14.142 -}
14.143 -
14.144 -void TimerNatives::OnTimerEnd(ITimer *pTimer, void *pData)
14.145 -{
14.146 - HandleSecurity sec;
14.147 - HandleError herr;
14.148 - TimerInfo *pInfo = reinterpret_cast<TimerInfo *>(pData);
14.149 - Handle_t usrhndl = static_cast<Handle_t>(pInfo->UserData);
14.150 -
14.151 - sec.pOwner = pInfo->pContext->GetIdentity();
14.152 - sec.pIdentity = g_pCoreIdent;
14.153 -
14.154 - if (pInfo->Flags & TIMER_DATA_HNDL_CLOSE)
14.155 - {
14.156 - if ((herr=g_HandleSys.FreeHandle(usrhndl, &sec)) != HandleError_None)
14.157 - {
14.158 - g_DbgReporter.GenerateError(pInfo->pContext,
14.159 - pInfo->Hook->GetFunctionID(),
14.160 - SP_ERROR_NATIVE,
14.161 - "Invalid data handle %x (error %d) passed during timer end with TIMER_DATA_HNDL_CLOSE",
14.162 - usrhndl,
14.163 - herr);
14.164 - }
14.165 - }
14.166 -
14.167 - if (pInfo->TimerHandle != BAD_HANDLE)
14.168 - {
14.169 - if ((herr=g_HandleSys.FreeHandle(pInfo->TimerHandle, &sec)) != HandleError_None)
14.170 - {
14.171 - g_DbgReporter.GenerateError(pInfo->pContext,
14.172 - pInfo->Hook->GetFunctionID(),
14.173 - SP_ERROR_NATIVE,
14.174 - "Invalid timer handle %x (error %d) during timer end, displayed function is timer callback, not the stack trace",
14.175 - pInfo->TimerHandle,
14.176 - herr);
14.177 - }
14.178 - }
14.179 -
14.180 - DeleteTimerInfo(pInfo);
14.181 -}
14.182 -
14.183 -/*******************************
14.184 -* *
14.185 -* TIMER NATIVE IMPLEMENTATIONS *
14.186 -* *
14.187 -********************************/
14.188 -
14.189 -static TimerNatives s_TimerNatives;
14.190 -
14.191 -static cell_t smn_CreateTimer(IPluginContext *pCtx, const cell_t *params)
14.192 -{
14.193 - IPluginFunction *pFunc;
14.194 - TimerInfo *pInfo;
14.195 - ITimer *pTimer;
14.196 - Handle_t hndl;
14.197 - int flags = params[4];
14.198 -
14.199 - pFunc = pCtx->GetFunctionById(params[2]);
14.200 - if (!pFunc)
14.201 - {
14.202 - return pCtx->ThrowNativeError("Invalid function id (%X)", params[2]);
14.203 - }
14.204 -
14.205 - pInfo = s_TimerNatives.CreateTimerInfo();
14.206 - pTimer = g_Timers.CreateTimer(&s_TimerNatives, sp_ctof(params[1]), pInfo, flags);
14.207 -
14.208 - if (!pTimer)
14.209 - {
14.210 - s_TimerNatives.DeleteTimerInfo(pInfo);
14.211 - return 0;
14.212 - }
14.213 -
14.214 - hndl = g_HandleSys.CreateHandle(g_TimerType, pInfo, pCtx->GetIdentity(), g_pCoreIdent, NULL);
14.215 -
14.216 - /* If we can't get a handle, the timer isn't refcounted against the plugin and
14.217 - * we need to bail out to prevent a crash.
14.218 - */
14.219 - if (hndl == BAD_HANDLE)
14.220 - {
14.221 - /* Free this for completeness. */
14.222 - if (flags & TIMER_DATA_HNDL_CLOSE)
14.223 - {
14.224 - HandleSecurity sec(pCtx->GetIdentity(), g_pCoreIdent);
14.225 - g_HandleSys.FreeHandle(params[3], &sec);
14.226 - }
14.227 - /* Zero everything so there's no conflicts */
14.228 - memset(pInfo, 0, sizeof(TimerInfo));
14.229 - g_Timers.KillTimer(pTimer);
14.230 -
14.231 - return pCtx->ThrowNativeError("Could not create timer, no more handles");
14.232 - }
14.233 -
14.234 - pInfo->UserData = params[3];
14.235 - pInfo->Flags = flags;
14.236 - pInfo->TimerHandle = hndl;
14.237 - pInfo->Hook = pFunc;
14.238 - pInfo->Timer = pTimer;
14.239 - pInfo->pContext = pCtx;
14.240 -
14.241 - return hndl;
14.242 -}
14.243 -
14.244 -static cell_t smn_KillTimer(IPluginContext *pCtx, const cell_t *params)
14.245 -{
14.246 - Handle_t hndl = static_cast<Handle_t>(params[1]);
14.247 - HandleError herr;
14.248 - HandleSecurity sec;
14.249 - TimerInfo *pInfo;
14.250 -
14.251 - sec.pOwner = pCtx->GetIdentity();
14.252 - sec.pIdentity = g_pCoreIdent;
14.253 -
14.254 - if ((herr=g_HandleSys.ReadHandle(hndl, g_TimerType, &sec, (void **)&pInfo))
14.255 - != HandleError_None)
14.256 - {
14.257 - return pCtx->ThrowNativeError("Invalid timer handle %x (error %d)", hndl, herr);
14.258 - }
14.259 -
14.260 - g_Timers.KillTimer(pInfo->Timer);
14.261 -
14.262 - if (params[2] && !(pInfo->Flags & TIMER_DATA_HNDL_CLOSE))
14.263 - {
14.264 - sec.pOwner = pInfo->pContext->GetIdentity();
14.265 - sec.pIdentity = g_pCoreIdent;
14.266 -
14.267 - if ((herr=g_HandleSys.FreeHandle(static_cast<Handle_t>(pInfo->UserData), &sec)) != HandleError_None)
14.268 - {
14.269 - return pCtx->ThrowNativeError("Invalid data handle %x (error %d) on timer kill with TIMER_DATA_HNDL_CLOSE", hndl, herr);
14.270 - }
14.271 - }
14.272 -
14.273 - return 1;
14.274 -}
14.275 -
14.276 -static cell_t smn_TriggerTimer(IPluginContext *pCtx, const cell_t *params)
14.277 -{
14.278 - Handle_t hndl = static_cast<Handle_t>(params[1]);
14.279 - HandleError herr;
14.280 - HandleSecurity sec;
14.281 - TimerInfo *pInfo;
14.282 -
14.283 - sec.pOwner = pCtx->GetIdentity();
14.284 - sec.pIdentity = g_pCoreIdent;
14.285 -
14.286 - if ((herr=g_HandleSys.ReadHandle(hndl, g_TimerType, &sec, (void **)&pInfo))
14.287 - != HandleError_None)
14.288 - {
14.289 - return pCtx->ThrowNativeError("Invalid timer handle %x (error %d)", hndl, herr);
14.290 - }
14.291 -
14.292 - g_Timers.FireTimerOnce(pInfo->Timer, params[2] ? true : false);
14.293 -
14.294 - return 1;
14.295 -}
14.296 -
14.297 -static cell_t smn_GetTickedTime(IPluginContext *pContext, const cell_t *params)
14.298 -{
14.299 - return sp_ftoc(*g_pUniversalTime);
14.300 -}
14.301 -
14.302 -static cell_t smn_GetMapTimeLeft(IPluginContext *pContext, const cell_t *params)
14.303 -{
14.304 - float time_left;
14.305 - if (!g_Timers.GetMapTimeLeft(&time_left))
14.306 - {
14.307 - return 0;
14.308 - }
14.309 -
14.310 - cell_t *addr;
14.311 - pContext->LocalToPhysAddr(params[1], &addr);
14.312 - *addr = (int)time_left;
14.313 -
14.314 - return 1;
14.315 -}
14.316 -
14.317 -static cell_t smn_GetMapTimeLimit(IPluginContext *pContext, const cell_t *params)
14.318 -{
14.319 - IMapTimer *pMapTimer = g_Timers.GetMapTimer();
14.320 -
14.321 - if (!pMapTimer)
14.322 - {
14.323 - return 0;
14.324 - }
14.325 -
14.326 - cell_t *addr;
14.327 - pContext->LocalToPhysAddr(params[1], &addr);
14.328 -
14.329 - *addr = pMapTimer->GetMapTimeLimit();
14.330 -
14.331 - return 1;
14.332 -}
14.333 -
14.334 -static cell_t smn_ExtendMapTimeLimit(IPluginContext *pContext, const cell_t *params)
14.335 -{
14.336 - IMapTimer *pMapTimer = g_Timers.GetMapTimer();
14.337 -
14.338 - if (!pMapTimer)
14.339 - {
14.340 - return 0;
14.341 - }
14.342 -
14.343 - pMapTimer->ExtendMapTimeLimit(params[1]);
14.344 -
14.345 - return 1;
14.346 -}
14.347 -
14.348 -static cell_t smn_IsServerProcessing(IPluginContext *pContext, const cell_t *params)
14.349 -{
14.350 - return (gpGlobals->frametime > 0.0f) ? 1 : 0;
14.351 -}
14.352 -
14.353 -static cell_t smn_GetTickInterval(IPluginContext *pContext, const cell_t *params)
14.354 -{
14.355 - return sp_ftoc(gpGlobals->interval_per_tick);
14.356 -}
14.357 -
14.358 -REGISTER_NATIVES(timernatives)
14.359 -{
14.360 - {"CreateTimer", smn_CreateTimer},
14.361 - {"KillTimer", smn_KillTimer},
14.362 - {"TriggerTimer", smn_TriggerTimer},
14.363 - {"GetTickedTime", smn_GetTickedTime},
14.364 - {"GetMapTimeLeft", smn_GetMapTimeLeft},
14.365 - {"GetMapTimeLimit", smn_GetMapTimeLimit},
14.366 - {"ExtendMapTimeLimit", smn_ExtendMapTimeLimit},
14.367 - {"IsServerProcessing", smn_IsServerProcessing},
14.368 - {"GetTickInterval", smn_GetTickInterval},
14.369 - {NULL, NULL}
14.370 -};
14.371 -
15.1 --- a/extensions/curl/AMBuilder Thu May 13 04:18:58 2010 -0500
15.2 +++ b/extensions/curl/AMBuilder Thu May 13 04:19:39 2010 -0500
15.3 @@ -5,7 +5,7 @@
15.4
15.5 def BuildCURL():
15.6 curl = AMBuild.AddJob('curl')
15.7 - if AMBuild.target['platform'] == 'linux' or AMBuild.target['platform'] == 'darwin':
15.8 + if AMBuild.target['platform'] in ['linux', 'darwin']:
15.9 if not osutil.FileExists(os.path.join(AMBuild.outputFolder, 'curl', 'Makefile')):
15.10 args = ['/bin/bash',
15.11 os.path.join(AMBuild.sourceFolder, 'extensions', 'curl', 'curl-src', 'configure'),
15.12 @@ -16,11 +16,10 @@
15.13 '--without-libidn',
15.14 '--without-libssh2',
15.15 '--without-zlib']
15.16 - if AMBuild.target['platform'] == 'linux':
15.17 - env = None
15.18 - elif AMBuild.target['platform'] == 'darwin':
15.19 - env = os.environ.copy()
15.20 - env['CFLAGS'] = '-m32 -isysroot /Developer/SDKs/MacOSX10.5.sdk'
15.21 + env = os.environ.copy()
15.22 + env['CFLAGS'] = '-m32'
15.23 + if AMBuild.target['platform'] == 'darwin':
15.24 + env['CFLAGS'] += ' -isysroot /Developer/SDKs/MacOSX10.5.sdk'
15.25 env['LDFLAGS'] = '-mmacosx-version-min=10.5'
15.26 curl.AddCommand(command.DirectCommand(argv = args, env = env))
15.27 curl.AddCommand(command.ShellCommand('cd lib && make'))
16.1 --- a/public/ITimerSystem.h Thu May 13 04:18:58 2010 -0500
16.2 +++ b/public/ITimerSystem.h Thu May 13 04:19:39 2010 -0500
16.3 @@ -42,7 +42,7 @@
16.4 #include <IForwardSys.h>
16.5
16.6 #define SMINTERFACE_TIMERSYS_NAME "ITimerSys"
16.7 -#define SMINTERFACE_TIMERSYS_VERSION 3
16.8 +#define SMINTERFACE_TIMERSYS_VERSION 4
16.9
16.10 namespace SourceMod
16.11 {
16.12 @@ -203,6 +203,13 @@
16.13 * @return True on success, false if no support.
16.14 */
16.15 virtual bool GetMapTimeLeft(float *pTime) =0;
16.16 +
16.17 + /**
16.18 + * @brief Returns the interface for dealing with map time limits.
16.19 + *
16.20 + * @return Map timer interface.
16.21 + */
16.22 + virtual IMapTimer *GetMapTimer() = 0;
16.23 };
16.24 }
16.25