Skip to content

Commit

Permalink
Add SDK check on load
Browse files Browse the repository at this point in the history
  • Loading branch information
evanlin96069 authored and lipsanen committed Nov 10, 2023
1 parent c593813 commit 3c1d8bb
Showing 1 changed file with 105 additions and 0 deletions.
105 changes: 105 additions & 0 deletions spt/spt-serverplugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,10 +148,115 @@ EXPOSE_SINGLE_INTERFACE_GLOBALVAR(CSourcePauseTool,
g_SourcePauseTool);
#endif

class SDKVersion
{
public:
enum Value : uint8_t
{
SDK_UNKNOWN,
SDK_2007,
SDK_2013,
SDK_BMS,
SDK_OE,
};

SDKVersion() = default;

constexpr SDKVersion(Value version) : value(version) {}

constexpr operator Value() const
{
return value;
}

explicit operator bool() const = delete;

const char* GetSPTName()
{
switch (value)
{
case SDK_2007:
return "spt.dll";
case SDK_2013:
return "spt-2013.dll";
case SDK_BMS:
return "spt-bms.dll";
case SDK_OE:
return "spt-oe.dll";
default:
return "";
}
}

private:
Value value;
};

static SDKVersion sptSDKVersion =
#if defined(SSDK2007)
SDKVersion::SDK_2007
#elif defined(SSDK2013)
SDKVersion::SDK_2013
#elif defined(BMS)
SDKVersion::SDK_BMS
#elif defined(OE)
SDKVersion::SDK_OE
#else
#error "Unknown SDK version"
#endif
;

static SDKVersion CheckSDKVersion(CreateInterfaceFn interfaceFactory)
{
void* icvar = interfaceFactory("VEngineCvar003", NULL);
if (icvar)
return SDKVersion::SDK_OE;
icvar = interfaceFactory("VEngineCvar004", NULL);
if (!icvar)
return SDKVersion::SDK_UNKNOWN;

typedef void*(__thiscall * FindCommandBase_func)(void* thisptr, const char* name);

// GENIUS HACK (BUT STILL BAD) (from SST): BMS has everything in ICvar shifted
// down 3 places due to the extra stuff in IAppSystem. This means that
// if we look up the BMS-specific cvar using FindCommandBase, it
// *actually* calls the const-overloaded FindVar on other branches,
// which just happens to still work fine.

auto find_commandbase_bms = (*(FindCommandBase_func**)(icvar))[13];
if (find_commandbase_bms(icvar, "kill"))
return SDKVersion::SDK_BMS;

if (interfaceFactory("VEngineClient014", NULL))
return SDKVersion::SDK_2013;

return SDKVersion::SDK_2007;
}

bool CSourcePauseTool::Load(CreateInterfaceFn interfaceFactory, CreateInterfaceFn gameServerFactory)
{
auto startTime = std::chrono::high_resolution_clock::now();

SDKVersion detectedVersion = CheckSDKVersion(interfaceFactory);
if (detectedVersion != sptSDKVersion)
{
if (detectedVersion == SDKVersion::SDK_UNKNOWN)
{
Warning("This game is not supported by SPT.\n");
}
else
{
Warning(
"You might be using the wrong SPT build (%s)\n"
"The correct SPT build seems to be %s\n",
sptSDKVersion.GetSPTName(),
detectedVersion.GetSPTName());
}

skipUnload = true;
return false;
}

if (pluginLoaded)
{
Warning("Trying to load SPT when SPT is already loaded.\n");
Expand Down

0 comments on commit 3c1d8bb

Please sign in to comment.