|
dvander@370
|
1 |
/** |
|
ds@653
|
2 |
* vim: set ts=4 : |
|
ds@1330
|
3 |
* ============================================================================= |
|
dvander@1231
|
4 |
* SourceMod |
|
dvander@1231
|
5 |
* Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved. |
|
ds@1330
|
6 |
* ============================================================================= |
|
dvander@370
|
7 |
* |
|
ds@1330
|
8 |
* This program is free software; you can redistribute it and/or modify it under |
|
ds@1330
|
9 |
* the terms of the GNU General Public License, version 3.0, as published by the |
|
ds@1330
|
10 |
* Free Software Foundation. |
|
dvander@1231
|
11 |
* |
|
ds@1330
|
12 |
* This program is distributed in the hope that it will be useful, but WITHOUT |
|
ds@1330
|
13 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
|
ds@1330
|
14 |
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more |
|
ds@1330
|
15 |
* details. |
|
dvander@1231
|
16 |
* |
|
ds@1330
|
17 |
* You should have received a copy of the GNU General Public License along with |
|
ds@1330
|
18 |
* this program. If not, see <http://www.gnu.org/licenses/>. |
|
dvander@1231
|
19 |
* |
|
ds@1330
|
20 |
* As a special exception, AlliedModders LLC gives you permission to link the |
|
ds@1330
|
21 |
* code of this program (as well as its derivative works) to "Half-Life 2," the |
|
ds@1330
|
22 |
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software |
|
ds@1330
|
23 |
* by the Valve Corporation. You must obey the GNU General Public License in |
|
ds@1330
|
24 |
* all respects for all other code used. Additionally, AlliedModders LLC grants |
|
ds@1330
|
25 |
* this exception to all derivative works. AlliedModders LLC defines further |
|
ds@1330
|
26 |
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), |
|
ds@1330
|
27 |
* or <http://www.sourcemod.net/license.php>. |
|
dvander@370
|
28 |
* |
|
dvander@370
|
29 |
* Version: $Id$ |
|
dvander@370
|
30 |
*/ |
|
dvander@370
|
31 |
|
|
dvander@173
|
32 |
#ifndef _INCLUDE_SOURCEMOD_PLUGINSYSTEM_H_ |
|
dvander@173
|
33 |
#define _INCLUDE_SOURCEMOD_PLUGINSYSTEM_H_ |
|
dvander@173
|
34 |
|
|
dvander@211
|
35 |
#include <time.h> |
|
faluco@333
|
36 |
#include <errno.h> |
|
faluco@333
|
37 |
#include <sys/stat.h> |
|
dvander@173
|
38 |
#include <IPluginSys.h> |
|
dvander@220
|
39 |
#include <IHandleSys.h> |
|
ds@611
|
40 |
#include <IForwardSys.h> |
|
dvander@174
|
41 |
#include <sh_list.h> |
|
dvander@174
|
42 |
#include <sh_stack.h> |
|
faluco@389
|
43 |
#include <sh_vector.h> |
|
dvander@601
|
44 |
#include <sh_string.h> |
|
dvander@173
|
45 |
#include "sm_globals.h" |
|
dvander@262
|
46 |
#include "vm/sp_vm_basecontext.h" |
|
dvander@203
|
47 |
#include "PluginInfoDatabase.h" |
|
dvander@211
|
48 |
#include "sm_trie.h" |
|
dvander@220
|
49 |
#include "sourcemod.h" |
|
dvander@309
|
50 |
#include <IRootConsoleMenu.h> |
|
faluco@1541
|
51 |
#if defined ORANGEBOX_BUILD |
|
faluco@1541
|
52 |
#include "convar_sm_ob.h" |
|
faluco@1541
|
53 |
#else |
|
ds@457
|
54 |
#include "convar_sm.h" |
|
faluco@1541
|
55 |
#endif |
|
dvander@173
|
56 |
|
|
dvander@174
|
57 |
using namespace SourceHook; |
|
dvander@174
|
58 |
|
|
dvander@209
|
59 |
/** |
|
dvander@209
|
60 |
* NOTES: |
|
dvander@209
|
61 |
* |
|
dvander@209
|
62 |
* Currently this system needs a lot of work but it's good skeletally. Plugin creation |
|
dvander@209
|
63 |
* is done without actually compiling anything. This is done by Load functions in the |
|
dvander@209
|
64 |
* manager. This will need a rewrite when we add context switching. |
|
dvander@209
|
65 |
* |
|
dvander@209
|
66 |
* The plugin object itself has a few things to note. The most important is that it stores |
|
dvander@209
|
67 |
* a table of function objects. The manager marshals allocation and freeing of these objects. |
|
dvander@209
|
68 |
* The plugin object can be in erroneous states, they are: |
|
dvander@209
|
69 |
* Plugin_Error --> Some error occurred any time during or after compilation. |
|
dvander@209
|
70 |
* This error can be cleared since the plugin itself is valid. |
|
dvander@209
|
71 |
* However, the state itself being set prevents any runtime action. |
|
dvander@209
|
72 |
* Plugin_BadLoad --> The plugin failed to load entirely and nothing can be done to save it. |
|
dvander@209
|
73 |
* |
|
dvander@209
|
74 |
* If a plugin fails to load externally, it is never added to the internal tracker. However, |
|
dvander@209
|
75 |
* plugins that failed to load from the internal loading mechanism are always tracked. This |
|
dvander@209
|
76 |
* allows users to see which automatically loaded plugins failed, and makes the interface a bit |
|
dvander@209
|
77 |
* more flexible. |
|
dvander@211
|
78 |
* |
|
dvander@211
|
79 |
* Once a plugin is compiled, it sets its own state to Plugin_Created. This state is still invalid |
|
dvander@211
|
80 |
* for execution. SourceMod is a two pass system, and even though the second pass is not implemented |
|
dvander@211
|
81 |
* yet, it is structured so Plugin_Created must be switched to Plugin_Running in the second pass. When |
|
dvander@211
|
82 |
* implemented, a Created plugin will be switched to Error in the second pass if it not loadable. |
|
dvander@211
|
83 |
* |
|
dvander@211
|
84 |
* The two pass loading mechanism is described below. Modules/natives are not implemented yet. |
|
dvander@211
|
85 |
* PASS ONE: All loadable plugins are found and have the following steps performed: |
|
dvander@211
|
86 |
* 1. Loading and compilation is attempted. |
|
dvander@211
|
87 |
* 2. If successful, all natives from Core are added. |
|
dvander@211
|
88 |
* 3. OnPluginLoad() is called. |
|
dvander@211
|
89 |
* 4. If failed, any user natives are scrapped and the process halts here. |
|
dvander@211
|
90 |
* 5. If successful, the plugin is ready for Pass 2. |
|
dvander@211
|
91 |
* INTERMEDIATE: |
|
dvander@211
|
92 |
* 1. All forced modules are loaded. |
|
dvander@211
|
93 |
* PASS TWO: All loaded plugins are found and have these steps performed: |
|
dvander@211
|
94 |
* 1. Any modules referenced in the plugin that are not already loaded, are loaded. |
|
dvander@211
|
95 |
* 2. If any module fails to load and the plugin requires it, load fails and jump to step 6. |
|
dvander@211
|
96 |
* 3. If any natives are unresolved, check if they are found in the user-natives pool. |
|
dvander@211
|
97 |
* 4. If yes, load succeeds. If not, natives are passed through a native acceptance filter. |
|
dvander@211
|
98 |
* 5. If the filter fails, the plugin is marked as failed. |
|
dvander@211
|
99 |
* 6. If the plugin has failed to load at this point, any dynamic natives it has added are scrapped. |
|
dvander@211
|
100 |
* Furthermore, any plugin that referenced these natives must now have pass 2 re-ran. |
|
dvander@211
|
101 |
* PASS THREE (not a real pass): |
|
ds@426
|
102 |
* 7. Once all plugins are deemed to be loaded, OnPluginStart() is called |
|
dvander@209
|
103 |
*/ |
|
dvander@209
|
104 |
|
|
dvander@174
|
105 |
#define SM_CONTEXTVAR_MYSELF 0 |
|
dvander@174
|
106 |
|
|
dvander@173
|
107 |
struct ContextPair |
|
dvander@173
|
108 |
{ |
|
dvander@209
|
109 |
ContextPair() : base(NULL), ctx(NULL), co(NULL) |
|
dvander@173
|
110 |
{ |
|
dvander@173
|
111 |
}; |
|
dvander@262
|
112 |
BaseContext *base; |
|
dvander@173
|
113 |
sp_context_t *ctx; |
|
dvander@209
|
114 |
ICompilation *co; |
|
dvander@209
|
115 |
IVirtualMachine *vm; |
|
dvander@173
|
116 |
}; |
|
dvander@173
|
117 |
|
|
dvander@605
|
118 |
struct FakeNative |
|
dvander@605
|
119 |
{ |
|
dvander@605
|
120 |
IPluginContext *ctx; |
|
dvander@605
|
121 |
IPluginFunction *call; |
|
dvander@605
|
122 |
String name; |
|
dvander@605
|
123 |
SPVM_NATIVE_FUNC func; |
|
dvander@605
|
124 |
}; |
|
dvander@605
|
125 |
|
|
faluco@383
|
126 |
enum LoadRes |
|
faluco@383
|
127 |
{ |
|
faluco@383
|
128 |
LoadRes_Successful, |
|
faluco@383
|
129 |
LoadRes_AlreadyLoaded, |
|
dvander@1436
|
130 |
LoadRes_Failure, |
|
dvander@1436
|
131 |
LoadRes_NeverLoad |
|
faluco@383
|
132 |
}; |
|
faluco@383
|
133 |
|
|
dvander@978
|
134 |
struct AutoConfig |
|
dvander@978
|
135 |
{ |
|
dvander@978
|
136 |
String autocfg; |
|
dvander@978
|
137 |
String folder; |
|
dvander@978
|
138 |
bool create; |
|
dvander@978
|
139 |
}; |
|
dvander@978
|
140 |
|
|
faluco@1112
|
141 |
class CPlugin; |
|
faluco@1112
|
142 |
struct WeakNative |
|
faluco@1112
|
143 |
{ |
|
faluco@1112
|
144 |
WeakNative(CPlugin *plugin, uint32_t index) |
|
faluco@1112
|
145 |
{ |
|
faluco@1112
|
146 |
pl = plugin; |
|
faluco@1112
|
147 |
idx = index; |
|
faluco@1112
|
148 |
} |
|
faluco@1112
|
149 |
CPlugin *pl; |
|
faluco@1112
|
150 |
uint32_t idx; |
|
faluco@1112
|
151 |
}; |
|
faluco@1112
|
152 |
|
|
dvander@173
|
153 |
class CPlugin : public IPlugin |
|
dvander@173
|
154 |
{ |
|
dvander@174
|
155 |
friend class CPluginManager; |
|
dvander@176
|
156 |
friend class CFunction; |
|
dvander@173
|
157 |
public: |
|
dvander@209
|
158 |
CPlugin(const char *file); |
|
dvander@209
|
159 |
~CPlugin(); |
|
dvander@209
|
160 |
public: |
|
faluco@641
|
161 |
PluginType GetType(); |
|
faluco@641
|
162 |
SourcePawn::IPluginContext *GetBaseContext(); |
|
faluco@641
|
163 |
sp_context_t *GetContext(); |
|
faluco@641
|
164 |
const sm_plugininfo_t *GetPublicInfo(); |
|
faluco@641
|
165 |
const char *GetFilename(); |
|
faluco@641
|
166 |
bool IsDebugging(); |
|
faluco@641
|
167 |
PluginStatus GetStatus(); |
|
faluco@641
|
168 |
bool SetPauseState(bool paused); |
|
faluco@641
|
169 |
unsigned int GetSerial(); |
|
faluco@641
|
170 |
const sp_plugin_t *GetPluginStructure(); |
|
faluco@641
|
171 |
IdentityToken_t *GetIdentity(); |
|
faluco@641
|
172 |
bool SetProperty(const char *prop, void *ptr); |
|
faluco@641
|
173 |
bool GetProperty(const char *prop, void **ptr, bool remove=false); |
|
dvander@173
|
174 |
public: |
|
dvander@209
|
175 |
/** |
|
dvander@209
|
176 |
* Creates a plugin object with default values. |
|
dvander@209
|
177 |
* If an error buffer is specified, and an error occurs, the error will be copied to the buffer |
|
dvander@209
|
178 |
* and NULL will be returned. |
|
dvander@209
|
179 |
* If an error buffer is not specified, the error will be copied to an internal buffer and |
|
dvander@209
|
180 |
* a valid (but error-stated) CPlugin will be returned. |
|
dvander@209
|
181 |
*/ |
|
dvander@209
|
182 |
static CPlugin *CreatePlugin(const char *file, char *error, size_t maxlength); |
|
dvander@209
|
183 |
public: |
|
dvander@209
|
184 |
/** |
|
dvander@209
|
185 |
* Starts the initial compilation of a plugin. |
|
dvander@209
|
186 |
* Returns false if another compilation exists or there is a current context set. |
|
dvander@209
|
187 |
*/ |
|
dvander@209
|
188 |
ICompilation *StartMyCompile(IVirtualMachine *vm); |
|
dvander@209
|
189 |
/** |
|
dvander@209
|
190 |
* Finalizes a compilation. If error buffer is NULL, the error is saved locally. |
|
dvander@209
|
191 |
*/ |
|
dvander@209
|
192 |
bool FinishMyCompile(char *error, size_t maxlength); |
|
dvander@209
|
193 |
void CancelMyCompile(); |
|
dvander@229
|
194 |
|
|
dvander@209
|
195 |
/** |
|
dvander@209
|
196 |
* Sets an error state on the plugin |
|
dvander@209
|
197 |
*/ |
|
dvander@209
|
198 |
void SetErrorState(PluginStatus status, const char *error_fmt, ...); |
|
dvander@211
|
199 |
|
|
dvander@211
|
200 |
/** |
|
dvander@229
|
201 |
* Initializes the plugin's identity information |
|
dvander@229
|
202 |
*/ |
|
dvander@229
|
203 |
void InitIdentity(); |
|
dvander@229
|
204 |
|
|
dvander@229
|
205 |
/** |
|
dvander@211
|
206 |
* Calls the OnPluginLoad function, and sets any failed states if necessary. |
|
dvander@211
|
207 |
* NOTE: Valid pre-states are: Plugin_Created |
|
dvander@282
|
208 |
* NOTE: If validated, plugin state is changed to Plugin_Loaded |
|
dvander@211
|
209 |
* |
|
dvander@211
|
210 |
* If the error buffer is NULL, the error message is cached locally. |
|
dvander@211
|
211 |
*/ |
|
dvander@211
|
212 |
bool Call_AskPluginLoad(char *error, size_t maxlength); |
|
dvander@211
|
213 |
|
|
dvander@211
|
214 |
/** |
|
ds@426
|
215 |
* Calls the OnPluginStart function. |
|
dvander@211
|
216 |
* NOTE: Valid pre-states are: Plugin_Created |
|
dvander@282
|
217 |
* NOTE: Post-state will be Plugin_Running |
|
dvander@211
|
218 |
*/ |
|
ds@426
|
219 |
void Call_OnPluginStart(); |
|
dvander@282
|
220 |
|
|
dvander@282
|
221 |
/** |
|
ds@426
|
222 |
* Calls the OnPluginEnd function. |
|
dvander@282
|
223 |
*/ |
|
ds@426
|
224 |
void Call_OnPluginEnd(); |
|
faluco@290
|
225 |
|
|
faluco@290
|
226 |
/** |
|
faluco@1221
|
227 |
* Calls the OnAllPluginsLoaded function. |
|
faluco@1221
|
228 |
*/ |
|
faluco@1221
|
229 |
void Call_OnAllPluginsLoaded(); |
|
faluco@1221
|
230 |
|
|
faluco@1221
|
231 |
/** |
|
dvander@315
|
232 |
* Toggles debug mode in the plugin |
|
dvander@315
|
233 |
*/ |
|
dvander@309
|
234 |
bool ToggleDebugMode(bool debug, char *error, size_t maxlength); |
|
faluco@290
|
235 |
|
|
faluco@290
|
236 |
/** |
|
dvander@315
|
237 |
* Returns true if a plugin is usable. |
|
dvander@315
|
238 |
*/ |
|
dvander@615
|
239 |
bool IsRunnable(); |
|
faluco@389
|
240 |
|
|
faluco@389
|
241 |
/** |
|
dvander@536
|
242 |
* Adds a language file index to the plugin's list. |
|
dvander@536
|
243 |
*/ |
|
faluco@389
|
244 |
void AddLangFile(unsigned int index); |
|
faluco@389
|
245 |
|
|
faluco@389
|
246 |
/** |
|
dvander@536
|
247 |
* Get language file count for this plugin. |
|
dvander@536
|
248 |
*/ |
|
dvander@615
|
249 |
size_t GetLangFileCount(); |
|
faluco@389
|
250 |
|
|
faluco@389
|
251 |
/** |
|
dvander@536
|
252 |
* Get language file index based on the vector index. |
|
dvander@536
|
253 |
*/ |
|
dvander@615
|
254 |
unsigned int GetLangFileByIndex(unsigned int index); |
|
dvander@211
|
255 |
public: |
|
faluco@333
|
256 |
/** |
|
dvander@536
|
257 |
* Returns the modification time during last plugin load. |
|
dvander@536
|
258 |
*/ |
|
dvander@615
|
259 |
time_t GetTimeStamp(); |
|
faluco@333
|
260 |
|
|
faluco@333
|
261 |
/** |
|
dvander@536
|
262 |
* Returns the current modification time of the plugin file. |
|
dvander@536
|
263 |
*/ |
|
faluco@333
|
264 |
time_t GetFileTimeStamp(); |
|
dvander@282
|
265 |
|
|
dvander@282
|
266 |
/** |
|
dvander@282
|
267 |
* Returns true if the plugin was running, but is now invalid. |
|
dvander@282
|
268 |
*/ |
|
dvander@282
|
269 |
bool WasRunning(); |
|
dvander@536
|
270 |
|
|
dvander@536
|
271 |
Handle_t GetMyHandle(); |
|
dvander@978
|
272 |
|
|
dvander@978
|
273 |
void AddConfig(bool autoCreate, const char *cfg, const char *folder); |
|
dvander@978
|
274 |
unsigned int GetConfigCount(); |
|
dvander@978
|
275 |
AutoConfig *GetConfig(unsigned int i); |
|
faluco@1112
|
276 |
inline void AddLibrary(const char *name) |
|
faluco@1089
|
277 |
{ |
|
faluco@1112
|
278 |
m_Libraries.push_back(name); |
|
faluco@1089
|
279 |
} |
|
dvander@1124
|
280 |
void LibraryActions(bool dropping); |
|
dvander@173
|
281 |
protected: |
|
dvander@173
|
282 |
void UpdateInfo(); |
|
faluco@333
|
283 |
void SetTimeStamp(time_t t); |
|
dvander@605
|
284 |
void DependencyDropped(CPlugin *pOwner); |
|
dvander@173
|
285 |
private: |
|
dvander@209
|
286 |
ContextPair m_ctx; |
|
dvander@174
|
287 |
PluginType m_type; |
|
ds@652
|
288 |
char m_filename[PLATFORM_MAX_PATH]; |
|
dvander@173
|
289 |
PluginStatus m_status; |
|
dvander@173
|
290 |
unsigned int m_serial; |
|
dvander@173
|
291 |
sm_plugininfo_t m_info; |
|
dvander@173
|
292 |
sp_plugin_t *m_plugin; |
|
dvander@209
|
293 |
char m_errormsg[256]; |
|
dvander@211
|
294 |
time_t m_LastAccess; |
|
dvander@229
|
295 |
IdentityToken_t *m_ident; |
|
dvander@220
|
296 |
Handle_t m_handle; |
|
dvander@282
|
297 |
bool m_WasRunning; |
|
faluco@389
|
298 |
CVector<unsigned int> m_PhraseFiles; |
|
dvander@605
|
299 |
List<CPlugin *> m_dependents; |
|
dvander@605
|
300 |
List<CPlugin *> m_dependsOn; |
|
dvander@605
|
301 |
List<FakeNative *> m_fakeNatives; |
|
dvander@1122
|
302 |
List<WeakNative> m_WeakNatives; |
|
faluco@1112
|
303 |
List<String> m_RequiredLibs; |
|
faluco@1112
|
304 |
List<String> m_Libraries; |
|
dvander@486
|
305 |
Trie *m_pProps; |
|
dvander@605
|
306 |
bool m_FakeNativesMissing; |
|
faluco@1112
|
307 |
bool m_LibraryMissing; |
|
dvander@978
|
308 |
CVector<AutoConfig *> m_configs; |
|
dvander@1630
|
309 |
bool m_bGotAllLoaded; |
|
dvander@601
|
310 |
}; |
|
dvander@601
|
311 |
|
|
dvander@220
|
312 |
class CPluginManager : |
|
dvander@220
|
313 |
public IPluginManager, |
|
dvander@220
|
314 |
public SMGlobalClass, |
|
dvander@309
|
315 |
public IHandleTypeDispatch, |
|
dvander@309
|
316 |
public IRootConsoleCommand |
|
dvander@174
|
317 |
{ |
|
dvander@176
|
318 |
friend class CPlugin; |
|
dvander@174
|
319 |
public: |
|
dvander@174
|
320 |
CPluginManager(); |
|
dvander@176
|
321 |
~CPluginManager(); |
|
dvander@174
|
322 |
public: |
|
dvander@203
|
323 |
/* Implements iterator class */ |
|
dvander@174
|
324 |
class CPluginIterator : public IPluginIterator |
|
dvander@174
|
325 |
{ |
|
dvander@174
|
326 |
public: |
|
dvander@213
|
327 |
CPluginIterator(List<CPlugin *> *mylist); |
|
dvander@174
|
328 |
virtual ~CPluginIterator(); |
|
dvander@174
|
329 |
virtual bool MorePlugins(); |
|
dvander@174
|
330 |
virtual IPlugin *GetPlugin(); |
|
dvander@174
|
331 |
virtual void NextPlugin(); |
|
dvander@282
|
332 |
void Release(); |
|
dvander@174
|
333 |
public: |
|
dvander@174
|
334 |
void Reset(); |
|
dvander@174
|
335 |
private: |
|
dvander@213
|
336 |
List<CPlugin *> *mylist; |
|
dvander@213
|
337 |
List<CPlugin *>::iterator current; |
|
dvander@174
|
338 |
}; |
|
dvander@174
|
339 |
friend class CPluginManager::CPluginIterator; |
|
dvander@203
|
340 |
public: //IPluginManager |
|
dvander@282
|
341 |
IPlugin *LoadPlugin(const char *path, |
|
dvander@174
|
342 |
bool debug, |
|
dvander@174
|
343 |
PluginType type, |
|
dvander@174
|
344 |
char error[], |
|
ds@755
|
345 |
size_t maxlength, |
|
faluco@383
|
346 |
bool *wasloaded); |
|
dvander@282
|
347 |
bool UnloadPlugin(IPlugin *plugin); |
|
dvander@282
|
348 |
IPlugin *FindPluginByContext(const sp_context_t *ctx); |
|
dvander@282
|
349 |
unsigned int GetPluginCount(); |
|
dvander@282
|
350 |
IPluginIterator *GetPluginIterator(); |
|
dvander@282
|
351 |
void AddPluginsListener(IPluginsListener *listener); |
|
dvander@282
|
352 |
void RemovePluginsListener(IPluginsListener *listener); |
|
dvander@220
|
353 |
public: //SMGlobalClass |
|
dvander@282
|
354 |
void OnSourceModAllInitialized(); |
|
dvander@282
|
355 |
void OnSourceModShutdown(); |
|
dvander@220
|
356 |
public: //IHandleTypeDispatch |
|
dvander@282
|
357 |
void OnHandleDestroy(HandleType_t type, void *object); |
|
dvander@309
|
358 |
public: //IRootConsoleCommand |
|
faluco@1541
|
359 |
void OnRootConsoleCommand(const char *cmdname, const CCommand &command); |
|
dvander@190
|
360 |
public: |
|
dvander@203
|
361 |
/** |
|
dvander@211
|
362 |
* Loads all plugins not yet loaded |
|
dvander@203
|
363 |
*/ |
|
dvander@211
|
364 |
void LoadAll_FirstPass(const char *config, const char *basedir); |
|
dvander@211
|
365 |
|
|
dvander@211
|
366 |
/** |
|
dvander@211
|
367 |
* Runs the second loading pass for all plugins |
|
dvander@211
|
368 |
*/ |
|
dvander@211
|
369 |
void LoadAll_SecondPass(); |
|
dvander@203
|
370 |
|
|
dvander@203
|
371 |
/** |
|
dvander@203
|
372 |
* Tests a plugin file mask against a local folder. |
|
dvander@203
|
373 |
* The alias is searched backwards from localdir - i.e., given this input: |
|
dvander@203
|
374 |
* csdm/ban csdm/ban |
|
dvander@203
|
375 |
* ban csdm/ban |
|
dvander@203
|
376 |
* csdm/ban optional/csdm/ban |
|
dvander@203
|
377 |
* All of these will return true for an alias match. |
|
dvander@203
|
378 |
* Wildcards are allowed in the filename. |
|
dvander@203
|
379 |
*/ |
|
dvander@209
|
380 |
bool TestAliasMatch(const char *alias, const char *localdir); |
|
dvander@211
|
381 |
|
|
dvander@211
|
382 |
/** |
|
dvander@211
|
383 |
* Returns whether anything loaded will be a late load. |
|
dvander@211
|
384 |
*/ |
|
faluco@290
|
385 |
bool IsLateLoadTime() const; |
|
dvander@233
|
386 |
|
|
dvander@233
|
387 |
/** |
|
dvander@233
|
388 |
* Adds natives from core into the native pool. |
|
dvander@233
|
389 |
*/ |
|
dvander@233
|
390 |
void RegisterNativesFromCore(sp_nativeinfo_t *natives); |
|
dvander@247
|
391 |
|
|
dvander@247
|
392 |
/** |
|
dvander@247
|
393 |
* Converts a Handle to an IPlugin if possible. |
|
dvander@247
|
394 |
*/ |
|
dvander@247
|
395 |
IPlugin *PluginFromHandle(Handle_t handle, HandleError *err); |
|
faluco@290
|
396 |
|
|
faluco@290
|
397 |
/** |
|
dvander@309
|
398 |
* Finds a plugin based on its index. (starts on index 1) |
|
dvander@309
|
399 |
*/ |
|
faluco@290
|
400 |
CPlugin *GetPluginByOrder(int num); |
|
dvander@309
|
401 |
|
|
dvander@1638
|
402 |
int GetOrderOfPlugin(IPlugin *pl); |
|
dvander@1638
|
403 |
|
|
ds@457
|
404 |
/** |
|
ds@457
|
405 |
* Internal version of FindPluginByContext() |
|
ds@457
|
406 |
*/ |
|
ds@457
|
407 |
inline CPlugin *GetPluginByCtx(const sp_context_t *ctx) |
|
ds@457
|
408 |
{ |
|
ds@457
|
409 |
return reinterpret_cast<CPlugin *>(ctx->user[SM_CONTEXTVAR_MYSELF]); |
|
ds@457
|
410 |
} |
|
ds@457
|
411 |
|
|
dvander@309
|
412 |
/** |
|
dvander@309
|
413 |
* Gets status text for a status code |
|
dvander@309
|
414 |
*/ |
|
dvander@309
|
415 |
const char *GetStatusText(PluginStatus status); |
|
dvander@315
|
416 |
|
|
faluco@333
|
417 |
/** |
|
faluco@333
|
418 |
* Reload or update plugins on level shutdown. |
|
faluco@333
|
419 |
*/ |
|
faluco@333
|
420 |
void ReloadOrUnloadPlugins(); |
|
faluco@333
|
421 |
|
|
ds@611
|
422 |
/** |
|
ds@611
|
423 |
* Add public functions from all running or paused |
|
ds@611
|
424 |
* plugins to the specified forward if the names match. |
|
ds@611
|
425 |
*/ |
|
ds@611
|
426 |
void AddFunctionsToForward(const char *name, IChangeableForward *pForward); |
|
ds@611
|
427 |
|
|
faluco@1221
|
428 |
/** |
|
faluco@1221
|
429 |
* Iterates through plugins to call OnAllPluginsLoaded. |
|
faluco@1221
|
430 |
*/ |
|
faluco@1221
|
431 |
void AllPluginsLoaded(); |
|
faluco@1221
|
432 |
|
|
dvander@900
|
433 |
CPlugin *GetPluginFromIdentity(IdentityToken_t *pToken); |
|
dvander@900
|
434 |
|
|
dvander@1018
|
435 |
void Shutdown(); |
|
dvander@1018
|
436 |
|
|
dvander@1572
|
437 |
void OnLibraryAction(const char *lib, bool is_a_plugin, bool drop); |
|
dvander@1124
|
438 |
|
|
dvander@1124
|
439 |
bool LibraryExists(const char *lib); |
|
faluco@1348
|
440 |
|
|
faluco@1348
|
441 |
bool ReloadPlugin(CPlugin *pl); |
|
dvander@1630
|
442 |
|
|
dvander@1630
|
443 |
void UnloadAll(); |
|
dvander@209
|
444 |
private: |
|
ds@755
|
445 |
LoadRes _LoadPlugin(CPlugin **pPlugin, const char *path, bool debug, PluginType type, char error[], size_t maxlength); |
|
dvander@298
|
446 |
|
|
dvander@298
|
447 |
void LoadAutoPlugin(const char *plugin); |
|
dvander@298
|
448 |
|
|
dvander@209
|
449 |
/** |
|
dvander@209
|
450 |
* Recursively loads all plugins in the given directory. |
|
dvander@209
|
451 |
*/ |
|
dvander@209
|
452 |
void LoadPluginsFromDir(const char *basedir, const char *localdir); |
|
dvander@209
|
453 |
|
|
dvander@209
|
454 |
/** |
|
dvander@211
|
455 |
* Adds a plugin object. This is wrapped by LoadPlugin functions. |
|
dvander@211
|
456 |
*/ |
|
dvander@211
|
457 |
void AddPlugin(CPlugin *pPlugin); |
|
dvander@211
|
458 |
|
|
dvander@211
|
459 |
/** |
|
dvander@211
|
460 |
* Runs the second loading pass on a plugin. |
|
dvander@209
|
461 |
*/ |
|
dvander@298
|
462 |
bool RunSecondPass(CPlugin *pPlugin, char *error, size_t maxlength); |
|
dvander@211
|
463 |
|
|
dvander@211
|
464 |
/** |
|
dvander@211
|
465 |
* Adds any globally registered natives to a plugin |
|
dvander@211
|
466 |
*/ |
|
dvander@211
|
467 |
void AddCoreNativesToPlugin(CPlugin *pPlugin); |
|
dvander@315
|
468 |
|
|
dvander@315
|
469 |
/** |
|
dvander@315
|
470 |
* Runs an extension pass on a plugin. |
|
dvander@315
|
471 |
*/ |
|
dvander@315
|
472 |
bool LoadOrRequireExtensions(CPlugin *pPlugin, unsigned int pass, char *error, size_t maxlength); |
|
faluco@430
|
473 |
|
|
faluco@1112
|
474 |
/** |
|
faluco@1112
|
475 |
* Manages required natives. |
|
faluco@1112
|
476 |
*/ |
|
faluco@1112
|
477 |
bool FindOrRequirePluginDeps(CPlugin *pPlugin, char *error, size_t maxlength); |
|
faluco@1112
|
478 |
|
|
faluco@430
|
479 |
void _SetPauseState(CPlugin *pPlugin, bool pause); |
|
dvander@174
|
480 |
protected: |
|
dvander@209
|
481 |
/** |
|
dvander@209
|
482 |
* Caching internal objects |
|
dvander@209
|
483 |
*/ |
|
dvander@174
|
484 |
void ReleaseIterator(CPluginIterator *iter); |
|
dvander@900
|
485 |
public: |
|
dvander@229
|
486 |
inline IdentityToken_t *GetIdentity() |
|
dvander@229
|
487 |
{ |
|
dvander@229
|
488 |
return m_MyIdent; |
|
dvander@229
|
489 |
} |
|
dvander@601
|
490 |
public: |
|
dvander@601
|
491 |
bool AddFakeNative(IPluginFunction *pFunction, const char *name, SPVM_FAKENATIVE_FUNC func); |
|
dvander@601
|
492 |
private: |
|
dvander@601
|
493 |
void AddFakeNativesToPlugin(CPlugin *pPlugin); |
|
faluco@1112
|
494 |
void TryRefreshDependencies(CPlugin *pOther); |
|
dvander@174
|
495 |
private: |
|
dvander@174
|
496 |
List<IPluginsListener *> m_listeners; |
|
dvander@213
|
497 |
List<CPlugin *> m_plugins; |
|
dvander@174
|
498 |
CStack<CPluginManager::CPluginIterator *> m_iters; |
|
dvander@203
|
499 |
CPluginInfoDatabase m_PluginInfo; |
|
dvander@211
|
500 |
Trie *m_LoadLookup; |
|
dvander@211
|
501 |
bool m_AllPluginsLoaded; |
|
dvander@229
|
502 |
IdentityToken_t *m_MyIdent; |
|
dvander@1382
|
503 |
Trie *m_pCoreNatives; |
|
dvander@601
|
504 |
|
|
dvander@601
|
505 |
/* Dynamic native stuff */ |
|
dvander@601
|
506 |
List<FakeNative *> m_Natives; |
|
dvander@601
|
507 |
Trie *m_pNativeLookup; |
|
dvander@601
|
508 |
|
|
dvander@1630
|
509 |
bool m_LoadingLocked; |
|
dvander@174
|
510 |
}; |
|
dvander@174
|
511 |
|
|
dvander@211
|
512 |
extern CPluginManager g_PluginSys; |
|
dvander@174
|
513 |
|
|
dvander@173
|
514 |
#endif //_INCLUDE_SOURCEMOD_PLUGINSYSTEM_H_ |