Store SourcePawn context metadata
This commit is contained in:
parent
8e42daada7
commit
714ffae578
@ -78,7 +78,6 @@ class SM:
|
||||
self.compiler.AddToListVar('CXXFLAGS', '-fvisibility-inlines-hidden')
|
||||
self.compiler.AddToListVar('CFLAGS', '-Wall')
|
||||
self.compiler.AddToListVar('CFLAGS', '-Werror')
|
||||
self.compiler.AddToListVar('CFLAGS', '-Wno-uninitialized')
|
||||
self.compiler.AddToListVar('CFLAGS', '-Wno-unused')
|
||||
self.compiler.AddToListVar('CFLAGS', '-Wno-switch')
|
||||
self.compiler.AddToListVar('CFLAGS', '-Wno-implicit-exception-spec-mismatch')
|
||||
|
@ -229,44 +229,6 @@ static bool dumpCallback(const google_breakpad::MinidumpDescriptor& descriptor,
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
char pis[64];
|
||||
char pds[32];
|
||||
for (unsigned i = 0; i < plugin_count; ++i) {
|
||||
PluginInfo *p = &plugins[i];
|
||||
if (p->serial == 0) continue;
|
||||
my_uitos(pds, i, my_uint_len(i));
|
||||
pds[my_uint_len(i)] = '\0';
|
||||
my_strlcpy(pis, "plugin[", sizeof(pis));
|
||||
my_strlcat(pis, pds, sizeof(pis));
|
||||
my_strlcat(pis, "].", sizeof(pis));
|
||||
sys_write(extra, pis, my_strlen(pis));
|
||||
sys_write(extra, "filename=", 9);
|
||||
sys_write(extra, p->filename, my_strlen(p->filename));
|
||||
sys_write(extra, "\n", 1);
|
||||
sys_write(extra, pis, my_strlen(pis));
|
||||
sys_write(extra, "name=", 5);
|
||||
sys_write(extra, p->name, my_strlen(p->name));
|
||||
sys_write(extra, "\n", 1);
|
||||
sys_write(extra, pis, my_strlen(pis));
|
||||
sys_write(extra, "author=", 7);
|
||||
sys_write(extra, p->author, my_strlen(p->author));
|
||||
sys_write(extra, "\n", 1);
|
||||
sys_write(extra, pis, my_strlen(pis));
|
||||
sys_write(extra, "description=", 12);
|
||||
sys_write(extra, p->description, my_strlen(p->description));
|
||||
sys_write(extra, "\n", 1);
|
||||
sys_write(extra, pis, my_strlen(pis));
|
||||
sys_write(extra, "version=", 8);
|
||||
sys_write(extra, p->version, my_strlen(p->version));
|
||||
sys_write(extra, "\n", 1);
|
||||
sys_write(extra, pis, my_strlen(pis));
|
||||
sys_write(extra, "url=", 4);
|
||||
sys_write(extra, p->url, my_strlen(p->url));
|
||||
sys_write(extra, "\n", 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
sys_close(extra);
|
||||
|
||||
return succeeded;
|
||||
@ -1226,28 +1188,17 @@ bool Accelerator::SDK_OnLoad(char *error, size_t maxlength, bool late)
|
||||
#error Bad platform.
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
IPluginIterator *i = plsys->GetPluginIterator();
|
||||
while (i->MorePlugins()) {
|
||||
IPlugin *p = i->GetPlugin();
|
||||
const sm_plugininfo_t *pmi = p->GetPublicInfo();
|
||||
PluginInfo *pi = &plugins[plugin_count++];
|
||||
plsys->AddPluginsListener(this);
|
||||
|
||||
pi->serial = p->GetSerial();
|
||||
pi->status = p->GetStatus();
|
||||
|
||||
strncpy(pi->filename, p->GetFilename(), sizeof(pi->filename) - 1);
|
||||
|
||||
strncpy(pi->name, pmi->name, sizeof(pi->name) - 1);
|
||||
strncpy(pi->author, pmi->author, sizeof(pi->author) - 1);
|
||||
strncpy(pi->description, pmi->description, sizeof(pi->description) - 1);
|
||||
strncpy(pi->version, pmi->version, sizeof(pi->version) - 1);
|
||||
strncpy(pi->url, pmi->url, sizeof(pi->url) - 1);
|
||||
|
||||
i->NextPlugin();
|
||||
IPluginIterator *iterator = plsys->GetPluginIterator();
|
||||
while (iterator->MorePlugins()) {
|
||||
IPlugin *plugin = iterator->GetPlugin();
|
||||
if (plugin->GetStatus() == Plugin_Running) {
|
||||
this->OnPluginLoaded(plugin);
|
||||
}
|
||||
iterator->NextPlugin();
|
||||
}
|
||||
delete i;
|
||||
#endif
|
||||
delete iterator;
|
||||
|
||||
strncpy(crashCommandLine, GetCmdLine(), sizeof(crashCommandLine) - 1);
|
||||
|
||||
@ -1316,6 +1267,8 @@ bool Accelerator::SDK_OnLoad(char *error, size_t maxlength, bool late)
|
||||
|
||||
void Accelerator::SDK_OnUnload()
|
||||
{
|
||||
plsys->RemovePluginsListener(this);
|
||||
|
||||
#if defined _LINUX
|
||||
g_pSM->RemoveGameFrameHook(OnGameFrame);
|
||||
#elif defined _WINDOWS
|
||||
@ -1333,3 +1286,162 @@ void Accelerator::OnCoreMapStart(edict_t *pEdictList, int edictCount, int client
|
||||
{
|
||||
strncpy(crashMap, gamehelpers->GetCurrentMap(), sizeof(crashMap) - 1);
|
||||
}
|
||||
|
||||
/* 010 Editor Template
|
||||
uint64 headerMagic;
|
||||
uint32 version;
|
||||
uint32 size;
|
||||
uint32 count;
|
||||
struct {
|
||||
uint32 size;
|
||||
uint32 context <format=hex>;
|
||||
char file[];
|
||||
uint32 count;
|
||||
struct {
|
||||
uint32 pcode <format=hex>;
|
||||
char name[];
|
||||
} functions[count] <optimize=false>;
|
||||
} plugins[count] <optimize=false>;
|
||||
uint64 tailMagic;
|
||||
*/
|
||||
|
||||
unsigned char *serializedPluginContexts = nullptr;
|
||||
std::map<const IPluginContext *, unsigned char *> pluginContextMap;
|
||||
|
||||
void SerializePluginContexts()
|
||||
{
|
||||
if (serializedPluginContexts) {
|
||||
handler->UnregisterAppMemory(serializedPluginContexts);
|
||||
free(serializedPluginContexts);
|
||||
serializedPluginContexts = nullptr;
|
||||
}
|
||||
|
||||
uint32_t count = pluginContextMap.size();
|
||||
if (count == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t size = 0;
|
||||
size += sizeof(uint64_t); // header magic
|
||||
size += sizeof(uint32_t); // version
|
||||
size += sizeof(uint32_t); // size
|
||||
size += sizeof(uint32_t); // count
|
||||
|
||||
for (auto &it : pluginContextMap) {
|
||||
unsigned char *buffer = it.second;
|
||||
|
||||
uint32_t bufferSize;
|
||||
memcpy(&bufferSize, buffer, sizeof(uint32_t));
|
||||
|
||||
size += bufferSize;
|
||||
}
|
||||
|
||||
size += sizeof(uint64_t); // tail magic
|
||||
|
||||
serializedPluginContexts = (unsigned char *)malloc(size);
|
||||
handler->RegisterAppMemory(serializedPluginContexts, size);
|
||||
unsigned char *cursor = serializedPluginContexts;
|
||||
|
||||
uint64_t headerMagic = 103582791429521979ULL;
|
||||
memcpy(cursor, &headerMagic, sizeof(uint64_t));
|
||||
cursor += sizeof(uint64_t);
|
||||
|
||||
uint32_t version = 1;
|
||||
memcpy(cursor, &version, sizeof(uint32_t));
|
||||
cursor += sizeof(uint32_t);
|
||||
|
||||
memcpy(cursor, &size, sizeof(uint32_t));
|
||||
cursor += sizeof(uint32_t);
|
||||
|
||||
memcpy(cursor, &count, sizeof(uint32_t));
|
||||
cursor += sizeof(uint32_t);
|
||||
|
||||
for (auto &it : pluginContextMap) {
|
||||
unsigned char *buffer = it.second;
|
||||
|
||||
uint32_t bufferSize;
|
||||
memcpy(&bufferSize, buffer, sizeof(uint32_t));
|
||||
|
||||
memcpy(cursor, buffer, bufferSize);
|
||||
cursor += bufferSize;
|
||||
}
|
||||
|
||||
uint64_t tailMagic = 76561197987819599ULL;
|
||||
memcpy(cursor, &tailMagic, sizeof(uint64_t));
|
||||
cursor += sizeof(uint64_t);
|
||||
}
|
||||
|
||||
void Accelerator::OnPluginLoaded(IPlugin *plugin)
|
||||
{
|
||||
IPluginRuntime *runtime = plugin->GetRuntime();
|
||||
IPluginContext *context = plugin->GetBaseContext();
|
||||
if (!runtime || !context) {
|
||||
return;
|
||||
}
|
||||
|
||||
const char *filename = plugin->GetFilename();
|
||||
size_t filenameSize = strlen(filename) + 1;
|
||||
|
||||
uint32_t size = 0;
|
||||
size += sizeof(uint32_t); // size
|
||||
size += sizeof(void *); // GetBaseContext
|
||||
size += filenameSize;
|
||||
|
||||
uint32_t count = runtime->GetPublicsNum();
|
||||
size += sizeof(uint32_t); // count
|
||||
size += count * sizeof(uint32_t); // pubinfo->code_offs
|
||||
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
sp_public_t *pubinfo;
|
||||
runtime->GetPublicByIndex(i, &pubinfo);
|
||||
|
||||
size += strlen(pubinfo->name) + 1;
|
||||
}
|
||||
|
||||
unsigned char *buffer = (unsigned char *)malloc(size);
|
||||
unsigned char *cursor = buffer;
|
||||
|
||||
memcpy(cursor, &size, sizeof(uint32_t));
|
||||
cursor += sizeof(uint32_t);
|
||||
|
||||
memcpy(cursor, &context, sizeof(void *));
|
||||
cursor += sizeof(void *);
|
||||
|
||||
memcpy(cursor, filename, filenameSize);
|
||||
cursor += filenameSize;
|
||||
|
||||
memcpy(cursor, &count, sizeof(uint32_t));
|
||||
cursor += sizeof(uint32_t);
|
||||
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
sp_public_t *pubinfo;
|
||||
runtime->GetPublicByIndex(i, &pubinfo);
|
||||
|
||||
memcpy(cursor, &pubinfo->code_offs, sizeof(uint32_t));
|
||||
cursor += sizeof(uint32_t);
|
||||
|
||||
size_t nameSize = strlen(pubinfo->name) + 1;
|
||||
memcpy(cursor, pubinfo->name, nameSize);
|
||||
cursor += nameSize;
|
||||
}
|
||||
|
||||
pluginContextMap[context] = buffer;
|
||||
|
||||
SerializePluginContexts();
|
||||
}
|
||||
|
||||
void Accelerator::OnPluginUnloaded(IPlugin *plugin)
|
||||
{
|
||||
IPluginContext *context = plugin->GetBaseContext();
|
||||
if (!context) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto it = pluginContextMap.find(context);
|
||||
if (it != pluginContextMap.end()) {
|
||||
free(it->second);
|
||||
pluginContextMap.erase(it);
|
||||
}
|
||||
|
||||
SerializePluginContexts();
|
||||
}
|
||||
|
@ -30,11 +30,10 @@
|
||||
|
||||
/**
|
||||
* @brief Sample implementation of the SDK Extension.
|
||||
* Note: Uncomment one of the pre-defined virtual functions in order to use it.
|
||||
*/
|
||||
class Accelerator : public SDKExtension
|
||||
class Accelerator : public SDKExtension, IPluginsListener
|
||||
{
|
||||
public:
|
||||
public: // SDKExtension
|
||||
/**
|
||||
* @brief This is called after the initial loading sequence has been processed.
|
||||
*
|
||||
@ -50,52 +49,6 @@ public:
|
||||
*/
|
||||
virtual void SDK_OnUnload();
|
||||
|
||||
/**
|
||||
* @brief Called when the pause state is changed.
|
||||
*/
|
||||
//virtual void SDK_OnPauseChange(bool paused);
|
||||
|
||||
/**
|
||||
* @brief this is called when Core wants to know if your extension is working.
|
||||
*
|
||||
* @param error Error message buffer.
|
||||
* @param maxlength Size of error message buffer.
|
||||
* @return True if working, false otherwise.
|
||||
*/
|
||||
//virtual bool QueryRunning(char *error, size_t maxlen);
|
||||
public:
|
||||
#if defined SMEXT_CONF_METAMOD
|
||||
/**
|
||||
* @brief Called when Metamod is attached, before the extension version is called.
|
||||
*
|
||||
* @param error Error buffer.
|
||||
* @param maxlength Maximum size of error buffer.
|
||||
* @param late Whether or not Metamod considers this a late load.
|
||||
* @return True to succeed, false to fail.
|
||||
*/
|
||||
//virtual bool SDK_OnMetamodLoad(ISmmAPI *ismm, char *error, size_t maxlen, bool late);
|
||||
|
||||
/**
|
||||
* @brief Called when Metamod is detaching, after the extension version is called.
|
||||
* NOTE: By default this is blocked unless sent from SourceMod.
|
||||
*
|
||||
* @param error Error buffer.
|
||||
* @param maxlength Maximum size of error buffer.
|
||||
* @return True to succeed, false to fail.
|
||||
*/
|
||||
//virtual bool SDK_OnMetamodUnload(char *error, size_t maxlen);
|
||||
|
||||
/**
|
||||
* @brief Called when Metamod's pause state is changing.
|
||||
* NOTE: By default this is blocked unless sent from SourceMod.
|
||||
*
|
||||
* @param paused Pause state being set.
|
||||
* @param error Error buffer.
|
||||
* @param maxlength Maximum size of error buffer.
|
||||
* @return True to succeed, false to fail.
|
||||
*/
|
||||
//virtual bool SDK_OnMetamodPauseChange(bool paused, char *error, size_t maxlen);
|
||||
#endif
|
||||
/**
|
||||
* @brief Called on server activation before plugins receive the OnServerLoad forward.
|
||||
*
|
||||
@ -104,6 +57,17 @@ public:
|
||||
* @param clientMax Maximum number of clients allowed in the server.
|
||||
*/
|
||||
virtual void OnCoreMapStart(edict_t *pEdictList, int edictCount, int clientMax);
|
||||
|
||||
public: // IPluginsListener
|
||||
/**
|
||||
* @brief Called when a plugin is fully loaded successfully.
|
||||
*/
|
||||
virtual void OnPluginLoaded(IPlugin *plugin);
|
||||
|
||||
/**
|
||||
* @brief Called when a plugin is unloaded (only if fully loaded).
|
||||
*/
|
||||
virtual void OnPluginUnloaded(IPlugin *plugin);
|
||||
};
|
||||
|
||||
#endif // _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_
|
||||
|
Loading…
Reference in New Issue
Block a user