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('CXXFLAGS', '-fvisibility-inlines-hidden') | ||||||
| 				self.compiler.AddToListVar('CFLAGS', '-Wall') | 				self.compiler.AddToListVar('CFLAGS', '-Wall') | ||||||
| 				self.compiler.AddToListVar('CFLAGS', '-Werror') | 				self.compiler.AddToListVar('CFLAGS', '-Werror') | ||||||
| 				self.compiler.AddToListVar('CFLAGS', '-Wno-uninitialized') |  | ||||||
| 				self.compiler.AddToListVar('CFLAGS', '-Wno-unused') | 				self.compiler.AddToListVar('CFLAGS', '-Wno-unused') | ||||||
| 				self.compiler.AddToListVar('CFLAGS', '-Wno-switch') | 				self.compiler.AddToListVar('CFLAGS', '-Wno-switch') | ||||||
| 				self.compiler.AddToListVar('CFLAGS', '-Wno-implicit-exception-spec-mismatch') | 				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); | 	sys_close(extra); | ||||||
| 
 | 
 | ||||||
| 	return succeeded; | 	return succeeded; | ||||||
| @ -1226,28 +1188,17 @@ bool Accelerator::SDK_OnLoad(char *error, size_t maxlength, bool late) | |||||||
| #error Bad platform. | #error Bad platform. | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| #if 0 | 	plsys->AddPluginsListener(this); | ||||||
| 	IPluginIterator *i = plsys->GetPluginIterator(); |  | ||||||
| 	while (i->MorePlugins()) { |  | ||||||
| 		IPlugin *p = i->GetPlugin(); |  | ||||||
| 		const sm_plugininfo_t *pmi = p->GetPublicInfo(); |  | ||||||
| 		PluginInfo *pi = &plugins[plugin_count++]; |  | ||||||
| 
 | 
 | ||||||
| 		pi->serial = p->GetSerial(); | 	IPluginIterator *iterator = plsys->GetPluginIterator(); | ||||||
| 		pi->status = p->GetStatus(); | 	while (iterator->MorePlugins()) { | ||||||
| 
 | 		IPlugin *plugin = iterator->GetPlugin(); | ||||||
| 		strncpy(pi->filename, p->GetFilename(), sizeof(pi->filename) - 1); | 		if (plugin->GetStatus() == Plugin_Running) { | ||||||
| 
 | 			this->OnPluginLoaded(plugin); | ||||||
| 		strncpy(pi->name, pmi->name, sizeof(pi->name) - 1); | 		} | ||||||
| 		strncpy(pi->author, pmi->author, sizeof(pi->author) - 1); | 		iterator->NextPlugin(); | ||||||
| 		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(); |  | ||||||
| 	} | 	} | ||||||
| 	delete i; | 	delete iterator; | ||||||
| #endif |  | ||||||
| 
 | 
 | ||||||
| 	strncpy(crashCommandLine, GetCmdLine(), sizeof(crashCommandLine) - 1); | 	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() | void Accelerator::SDK_OnUnload() | ||||||
| { | { | ||||||
|  | 	plsys->RemovePluginsListener(this); | ||||||
|  | 
 | ||||||
| #if defined _LINUX | #if defined _LINUX | ||||||
| 	g_pSM->RemoveGameFrameHook(OnGameFrame); | 	g_pSM->RemoveGameFrameHook(OnGameFrame); | ||||||
| #elif defined _WINDOWS | #elif defined _WINDOWS | ||||||
| @ -1333,3 +1286,162 @@ void Accelerator::OnCoreMapStart(edict_t *pEdictList, int edictCount, int client | |||||||
| { | { | ||||||
| 	strncpy(crashMap, gamehelpers->GetCurrentMap(), sizeof(crashMap) - 1); | 	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. |  * @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. | 	 * @brief This is called after the initial loading sequence has been processed. | ||||||
| 	 * | 	 * | ||||||
| @ -50,52 +49,6 @@ public: | |||||||
| 	 */ | 	 */ | ||||||
| 	virtual void SDK_OnUnload(); | 	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. | 	 * @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. | 	 * @param clientMax			Maximum number of clients allowed in the server. | ||||||
| 	 */ | 	 */ | ||||||
| 	virtual void OnCoreMapStart(edict_t *pEdictList, int edictCount, int clientMax); | 	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_
 | #endif // _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user