diff --git a/extension/extension.cpp b/extension/extension.cpp index d4a8f75..daa263b 100644 --- a/extension/extension.cpp +++ b/extension/extension.cpp @@ -27,7 +27,6 @@ #include #include "MemoryDownloader.h" -#include "forwards.h" #include "natives.h" #if defined _LINUX @@ -1085,25 +1084,6 @@ class UploadThread: public IThread } } uploadThread; -class SourcePawnNotifyThread : public IThread -{ -public: - - void RunThread(IThreadHandle* pHandle) { - for (;;) { - // Wait until OnMapStart is called once, this should be enough delay to make sure plugins are loaded. - if (g_accelerator.IsMapStarted() && g_accelerator.IsDoneUploading()) { - extforwards::CallOnDoneUploadingForward(); - break; - } - } - } - - void OnTerminate(IThreadHandle* pHandle, bool cancel) { - } - -} spNotifyThread; - class VFuncEmptyClass {}; const char *GetCmdLine() @@ -1142,7 +1122,7 @@ const char *GetCmdLine() } Accelerator::Accelerator() : - m_doneuploading(false), m_maphasstarted(false) + m_doneuploading(false), m_maphasstarted(false), m_spNotifyThread(this) { } @@ -1171,8 +1151,8 @@ bool Accelerator::SDK_OnLoad(char *error, size_t maxlength, bool late) strncpy(crashGameDirectory, g_pSM->GetGameFolderName(), sizeof(crashGameDirectory) - 1); threader->MakeThread(&uploadThread); - threader->MakeThread(&spNotifyThread); // This thread waits for accelator to be done uploading and for the first OnMapStart call, then fires a SourceMod forward - + threader->MakeThread(&m_spNotifyThread); // This thread waits for accelator to be done uploading and for the first OnMapStart call, then fires a SourceMod forward + do { char gameconfigError[256]; if (!gameconfs->LoadGameConfigFile("accelerator.games", &gameconfig, gameconfigError, sizeof(gameconfigError))) { @@ -1235,6 +1215,7 @@ bool Accelerator::SDK_OnLoad(char *error, size_t maxlength, bool late) #endif do { +#if SMINTERFACE_EXTENSIONAPI_VERSION < 9 char spJitPath[512]; g_pSM->BuildPath(Path_SM, spJitPath, sizeof(spJitPath), "bin/" PLATFORM_ARCH_FOLDER "sourcepawn.jit.x86." PLATFORM_LIB_EXT); @@ -1270,6 +1251,11 @@ bool Accelerator::SDK_OnLoad(char *error, size_t maxlength, bool late) } strncpy(crashSourceModVersion, spEngine2->GetVersionString(), sizeof(crashSourceModVersion)); +#else + auto engine = g_pSM->GetScriptingEngine(); + + strncpy(crashSourceModVersion, engine->GetVersionString(), sizeof(crashSourceModVersion)); +#endif } while(false); plsys->AddPluginsListener(this); @@ -1353,6 +1339,7 @@ void Accelerator::SDK_OnUnload() { extforwards::Shutdown(); plsys->RemovePluginsListener(this); + m_spNotifyThread.Shutdown(); #if defined _LINUX g_pSM->RemoveGameFrameHook(OnGameFrame); @@ -1484,6 +1471,7 @@ void Accelerator::OnPluginLoaded(IPlugin *plugin) size += sizeof(void *); // GetBaseContext size += filenameSize; +#if SMINTERFACE_EXTENSIONAPI_VERSION < 9 uint32_t count = runtime->GetPublicsNum(); size += sizeof(uint32_t); // count size += count * sizeof(uint32_t); // pubinfo->code_offs @@ -1494,6 +1482,23 @@ void Accelerator::OnPluginLoaded(IPlugin *plugin) size += strlen(pubinfo->name) + 1; } +#else +static_assert(false, "Check the code below is still true."); +static_assert(sizeof(funcid_t) == 4, "funcid_t is no longer 4 bytes long."); + + // The count has to be discovered + uint32_t count = 0; + for (; count < ~(1 << 31); ++count) { + auto func_id = (count << 1) | 0x1; + auto func = runtime->GetFunctionById(func_id); + if (!func) { + break; + } + size += strlen(func->DebugName()) + 1; + } + size += sizeof(uint32_t); + size += count * sizeof(uint32_t); +#endif unsigned char *buffer = (unsigned char *)malloc(size); unsigned char *cursor = buffer; @@ -1511,6 +1516,7 @@ void Accelerator::OnPluginLoaded(IPlugin *plugin) cursor += sizeof(uint32_t); for (uint32_t i = 0; i < count; ++i) { +#if SMINTERFACE_EXTENSIONAPI_VERSION < 9 sp_public_t *pubinfo; runtime->GetPublicByIndex(i, &pubinfo); @@ -1520,6 +1526,18 @@ void Accelerator::OnPluginLoaded(IPlugin *plugin) size_t nameSize = strlen(pubinfo->name) + 1; memcpy(cursor, pubinfo->name, nameSize); cursor += nameSize; +#else + auto func_id = (i << 1) | 0x1; + auto func = runtime->GetFunctionById(func_id); + + // This information is no longer public + *(uint32_t*)cursor = 0x0; + cursor += sizeof(uint32_t); + + size_t nameSize = strlen(func->DebugName()) + 1; + memcpy(cursor, func->DebugName(), nameSize); + cursor += nameSize; +#endif } pluginContextMap[context] = buffer; diff --git a/extension/extension.h b/extension/extension.h index 0412a7c..337ae46 100644 --- a/extension/extension.h +++ b/extension/extension.h @@ -30,6 +30,7 @@ #include #include #include "smsdk_ext.h" +#include "forwards.h" /** * @brief Represents a crash that has been successfully uploaded to Accelerator's backend @@ -133,6 +134,35 @@ class Accelerator : public SDKExtension, IPluginsListener mutable std::mutex m_uploadedcrashes_mutex; // mutex for accessing the m_uploadedcrashes vector std::atomic_bool m_doneuploading; // Signals that Accelerator is done uploading crashes. std::atomic_bool m_maphasstarted; // Signals that OnMapStart has been called at least once. + + class SourcePawnNotifyThread : public IThread + { + public: + SourcePawnNotifyThread(Accelerator* outter) : m_outter(outter), m_terminated(false), m_shutdown(false) {} + ~SourcePawnNotifyThread() { while (!m_terminated) {} } + + void RunThread(IThreadHandle* pHandle) { + while (!m_shutdown) { + // Wait until OnMapStart is called once, this should be enough delay to make sure plugins are loaded. + if (m_outter->IsMapStarted() && m_outter->IsDoneUploading()) { + extforwards::CallOnDoneUploadingForward(); + break; + } + } + } + + void OnTerminate(IThreadHandle* pHandle, bool cancel) { + m_terminated = true; + } + + void Shutdown() { + m_shutdown = true; + } + + Accelerator* m_outter; + bool m_terminated; + bool m_shutdown; + } m_spNotifyThread; }; // Expose the extension singleton.