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