Update CS:GO team score gamedata.
2 * vim: set ts=4 sw=4 tw=99 noet :
3 * =============================================================================
5 * Copyright (C) 2004-2010 AlliedModders LLC. All rights reserved.
6 * =============================================================================
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.
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
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/>.
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>.
32 #ifndef _INCLUDE_SOURCEMOD_PLUGINSYSTEM_H_
33 #define _INCLUDE_SOURCEMOD_PLUGINSYSTEM_H_
38 #include <IPluginSys.h>
39 #include <IHandleSys.h>
40 #include <IForwardSys.h>
43 #include <sh_vector.h>
44 #include <sh_string.h>
45 #include "common_logic.h"
46 #include <IRootConsoleMenu.h>
47 #include <sm_stringhashmap.h>
48 #include <sm_namehashset.h>
49 #include "ITranslator.h"
50 #include "IGameConfigs.h"
51 #include "NativeOwner.h"
56 using namespace SourceHook;
61 * UPDATE 2008-03-11: These comments are horribly out of date. They paint a good overall
62 * picture of how PluginSys works, but things like dependencies and fake natives have
63 * complicated things quite a bit.
65 * Currently this system needs a lot of work but it's good skeletally. Plugin creation
66 * is done without actually compiling anything. This is done by Load functions in the
67 * manager. This will need a rewrite when we add context switching.
69 * The plugin object itself has a few things to note. The most important is that it stores
70 * a table of function objects. The manager marshals allocation and freeing of these objects.
71 * The plugin object can be in erroneous states, they are:
72 * Plugin_Error --> Some error occurred any time during or after compilation.
73 * This error can be cleared since the plugin itself is valid.
74 * However, the state itself being set prevents any runtime action.
75 * Plugin_BadLoad --> The plugin failed to load entirely and nothing can be done to save it.
77 * If a plugin fails to load externally, it is never added to the internal tracker. However,
78 * plugins that failed to load from the internal loading mechanism are always tracked. This
79 * allows users to see which automatically loaded plugins failed, and makes the interface a bit
82 * Once a plugin is compiled, it sets its own state to Plugin_Created. This state is still invalid
83 * for execution. SourceMod is a two pass system, and even though the second pass is not implemented
84 * yet, it is structured so Plugin_Created must be switched to Plugin_Running in the second pass. When
85 * implemented, a Created plugin will be switched to Error in the second pass if it not loadable.
87 * The two pass loading mechanism is described below. Modules/natives are not implemented yet.
88 * PASS ONE: All loadable plugins are found and have the following steps performed:
89 * 1. Loading and compilation is attempted.
90 * 2. If successful, all natives from Core are added.
91 * 3. OnPluginLoad() is called.
92 * 4. If failed, any user natives are scrapped and the process halts here.
93 * 5. If successful, the plugin is ready for Pass 2.
95 * 1. All forced modules are loaded.
96 * PASS TWO: All loaded plugins are found and have these steps performed:
97 * 1. Any modules referenced in the plugin that are not already loaded, are loaded.
98 * 2. If any module fails to load and the plugin requires it, load fails and jump to step 6.
99 * 3. If any natives are unresolved, check if they are found in the user-natives pool.
100 * 4. If yes, load succeeds. If not, natives are passed through a native acceptance filter.
101 * 5. If the filter fails, the plugin is marked as failed.
102 * 6. If the plugin has failed to load at this point, any dynamic natives it has added are scrapped.
103 * Furthermore, any plugin that referenced these natives must now have pass 2 re-ran.
104 * PASS THREE (not a real pass):
105 * 7. Once all plugins are deemed to be loaded, OnPluginStart() is called
111 LoadRes_AlreadyLoaded,
113 LoadRes_SilentFailure,
128 friend class CPluginManager;
129 friend class CFunction;
131 CPlugin(const char *file);
134 PluginType GetType();
135 SourcePawn::IPluginContext *GetBaseContext();
136 sp_context_t *GetContext();
137 void *GetPluginStructure();
138 const char *GetFilename();
140 PluginStatus GetStatus();
141 bool IsSilentlyFailed();
142 void SetSilentlyFailed(bool sf);
143 const sm_plugininfo_t *GetPublicInfo();
144 bool SetPauseState(bool paused);
145 unsigned int GetSerial();
146 IdentityToken_t *GetIdentity();
147 unsigned int CalcMemUsage();
148 bool SetProperty(const char *prop, void *ptr);
149 bool GetProperty(const char *prop, void **ptr, bool remove=false);
150 void DropEverything();
151 SourcePawn::IPluginRuntime *GetRuntime();
152 CNativeOwner *ToNativeOwner() {
157 * Creates a plugin object with default values.
158 * If an error buffer is specified, and an error occurs, the error will be copied to the buffer
159 * and NULL will be returned.
160 * If an error buffer is not specified, the error will be copied to an internal buffer and
161 * a valid (but error-stated) CPlugin will be returned.
163 static CPlugin *CreatePlugin(const char *file, char *error, size_t maxlength);
165 static inline bool matches(const char *file, const CPlugin *plugin)
167 return strcmp(plugin->m_filename, file) == 0;
172 * Sets an error state on the plugin
174 void SetErrorState(PluginStatus status, const char *error_fmt, ...);
177 * Initializes the plugin's identity information
182 * Calls the OnPluginLoad function, and sets any failed states if necessary.
183 * NOTE: Valid pre-states are: Plugin_Created
184 * NOTE: If validated, plugin state is changed to Plugin_Loaded
186 * If the error buffer is NULL, the error message is cached locally.
188 APLRes Call_AskPluginLoad(char *error, size_t maxlength);
191 * Calls the OnPluginStart function.
192 * NOTE: Valid pre-states are: Plugin_Created
193 * NOTE: Post-state will be Plugin_Running
195 void Call_OnPluginStart();
198 * Calls the OnPluginEnd function.
200 void Call_OnPluginEnd();
203 * Calls the OnAllPluginsLoaded function.
205 void Call_OnAllPluginsLoaded();
208 * Returns true if a plugin is usable.
213 * Get languages info.
215 IPhraseCollection *GetPhrases();
218 * Returns the modification time during last plugin load.
220 time_t GetTimeStamp();
223 * Returns the current modification time of the plugin file.
225 time_t GetFileTimeStamp();
228 * Returns true if the plugin was running, but is now invalid.
232 Handle_t GetMyHandle();
234 bool AddFakeNative(IPluginFunction *pFunc, const char *name, SPVM_FAKENATIVE_FUNC func);
235 void AddConfig(bool autoCreate, const char *cfg, const char *folder);
236 size_t GetConfigCount();
237 AutoConfig *GetConfig(size_t i);
238 inline void AddLibrary(const char *name)
240 m_Libraries.push_back(name);
242 void LibraryActions(LibraryAction action);
243 void SyncMaxClients(int max_clients);
246 void SetTimeStamp(time_t t);
247 void DependencyDropped(CPlugin *pOwner);
250 char m_filename[PLATFORM_MAX_PATH];
251 PluginStatus m_status;
252 bool m_bSilentlyFailed;
253 unsigned int m_serial;
254 sm_plugininfo_t m_info;
255 char m_errormsg[256];
257 IdentityToken_t *m_ident;
260 IPhraseCollection *m_pPhrases;
261 List<String> m_RequiredLibs;
262 List<String> m_Libraries;
263 StringHashMap<void *> m_Props;
264 bool m_FakeNativesMissing;
265 bool m_LibraryMissing;
266 CVector<AutoConfig *> m_configs;
267 bool m_bGotAllLoaded;
269 char m_DateTime[256];
270 IPluginRuntime *m_pRuntime;
271 IPluginContext *m_pContext;
272 sp_pubvar_t *m_MaxClientsVar;
275 class CPluginManager :
276 public IScriptManager,
277 public SMGlobalClass,
278 public IHandleTypeDispatch,
279 public IRootConsoleCommand
281 friend class CPlugin;
286 /* Implements iterator class */
287 class CPluginIterator : public IPluginIterator
290 CPluginIterator(List<CPlugin *> *mylist);
291 virtual ~CPluginIterator();
292 virtual bool MorePlugins();
293 virtual IPlugin *GetPlugin();
294 virtual void NextPlugin();
299 List<CPlugin *> *mylist;
300 List<CPlugin *>::iterator current;
302 friend class CPluginManager::CPluginIterator;
303 public: //IScriptManager
304 IPlugin *LoadPlugin(const char *path,
310 bool UnloadPlugin(IPlugin *plugin);
311 IPlugin *FindPluginByContext(const sp_context_t *ctx);
312 unsigned int GetPluginCount();
313 IPluginIterator *GetPluginIterator();
314 void AddPluginsListener(IPluginsListener *listener);
315 void RemovePluginsListener(IPluginsListener *listener);
316 void LoadAll(const char *config_path, const char *plugins_path);
318 SMPlugin *FindPluginByOrder(unsigned num) {
319 return GetPluginByOrder(num);
321 SMPlugin *FindPluginByIdentity(IdentityToken_t *ident) {
322 return GetPluginFromIdentity(ident);
324 SMPlugin *FindPluginByContext(IPluginContext *ctx) {
325 return GetPluginByCtx(ctx->GetContext());
327 SMPlugin *FindPluginByContext(sp_context_t *ctx) {
328 return GetPluginByCtx(ctx);
330 SMPlugin *FindPluginByConsoleArg(const char *text);
331 SMPlugin *FindPluginByHandle(Handle_t hndl, HandleError *errp) {
332 return static_cast<SMPlugin *>(PluginFromHandle(hndl, errp));
334 const CVector<SMPlugin *> *ListPlugins();
335 void FreePluginList(const CVector<SMPlugin *> *plugins);
336 public: //SMGlobalClass
337 void OnSourceModAllInitialized();
338 void OnSourceModShutdown();
339 ConfigResult OnSourceModConfigChanged(const char *key, const char *value, ConfigSource source, char *error, size_t maxlength);
340 void OnSourceModMaxPlayersChanged(int newvalue);
341 public: //IHandleTypeDispatch
342 void OnHandleDestroy(HandleType_t type, void *object);
343 bool GetHandleApproxSize(HandleType_t type, void *object, unsigned int *pSize);
344 public: //IRootConsoleCommand
345 void OnRootConsoleCommand(const char *cmdname, const CCommand &command);
348 * Loads all plugins not yet loaded
350 void LoadAll_FirstPass(const char *config, const char *basedir);
353 * Runs the second loading pass for all plugins
355 void LoadAll_SecondPass();
358 * Tests a plugin file mask against a local folder.
359 * The alias is searched backwards from localdir - i.e., given this input:
362 * csdm/ban optional/csdm/ban
363 * All of these will return true for an alias match.
364 * Wildcards are allowed in the filename.
366 bool TestAliasMatch(const char *alias, const char *localdir);
369 * Returns whether anything loaded will be a late load.
371 bool IsLateLoadTime() const;
374 * Converts a Handle to an IPlugin if possible.
376 IPlugin *PluginFromHandle(Handle_t handle, HandleError *err);
379 * Finds a plugin based on its index. (starts on index 1)
381 CPlugin *GetPluginByOrder(int num);
383 int GetOrderOfPlugin(IPlugin *pl);
386 * Internal version of FindPluginByContext()
388 CPlugin *GetPluginByCtx(const sp_context_t *ctx);
391 * Gets status text for a status code
393 const char *GetStatusText(PluginStatus status);
396 * Add public functions from all running or paused
397 * plugins to the specified forward if the names match.
399 void AddFunctionsToForward(const char *name, IChangeableForward *pForward);
402 * Iterates through plugins to call OnAllPluginsLoaded.
404 void AllPluginsLoaded();
406 CPlugin *GetPluginFromIdentity(IdentityToken_t *pToken);
410 void OnLibraryAction(const char *lib, LibraryAction action);
412 bool LibraryExists(const char *lib);
414 bool ReloadPlugin(CPlugin *pl);
418 void SyncMaxClients(int max_clients);
420 void ListPluginsToClient(CPlayer *player, const CCommand &args);
422 LoadRes _LoadPlugin(CPlugin **pPlugin, const char *path, bool debug, PluginType type, char error[], size_t maxlength);
424 void LoadAutoPlugin(const char *plugin);
427 * Recursively loads all plugins in the given directory.
429 void LoadPluginsFromDir(const char *basedir, const char *localdir);
432 * Adds a plugin object. This is wrapped by LoadPlugin functions.
434 void AddPlugin(CPlugin *pPlugin);
437 * Runs the second loading pass on a plugin.
439 bool RunSecondPass(CPlugin *pPlugin, char *error, size_t maxlength);
442 * Runs an extension pass on a plugin.
444 bool LoadOrRequireExtensions(CPlugin *pPlugin, unsigned int pass, char *error, size_t maxlength);
447 * Manages required natives.
449 bool FindOrRequirePluginDeps(CPlugin *pPlugin, char *error, size_t maxlength);
451 void _SetPauseState(CPlugin *pPlugin, bool pause);
454 * Caching internal objects
456 void ReleaseIterator(CPluginIterator *iter);
458 inline IdentityToken_t *GetIdentity()
462 IPluginManager *GetOldAPI();
464 void TryRefreshDependencies(CPlugin *pOther);
466 List<IPluginsListener *> m_listeners;
467 List<CPlugin *> m_plugins;
468 CStack<CPluginManager::CPluginIterator *> m_iters;
469 NameHashSet<CPlugin *> m_LoadLookup;
470 bool m_AllPluginsLoaded;
471 IdentityToken_t *m_MyIdent;
473 /* Dynamic native stuff */
474 List<FakeNative *> m_Natives;
476 bool m_LoadingLocked;
479 bool m_bBlockBadPlugins;
482 IForward *m_pOnLibraryAdded;
483 IForward *m_pOnLibraryRemoved;
486 extern CPluginManager g_PluginSys;
488 #endif //_INCLUDE_SOURCEMOD_PLUGINSYSTEM_H_