Add string_t SetEntPropString support for ep1 (fixes #1287)
This commit is contained in:
parent
2ebbf2774b
commit
4c8103a4e1
@ -1367,8 +1367,36 @@ bool CHalfLife2::IsMapValid(const char *map)
|
|||||||
return FindMap(map) != SMFindMapResult::NotFound;
|
return FindMap(map) != SMFindMapResult::NotFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Add ep1 support for this. (No IServerTools available there)
|
#if SOURCE_ENGINE == SE_EPISODEONE
|
||||||
#if SOURCE_ENGINE >= SE_ORANGEBOX
|
class VKeyValuesSS_Helper {};
|
||||||
|
static bool VKeyValuesSS(CBaseEntity* pThisPtr, const char *pszKey, const char *pszValue, int offset)
|
||||||
|
{
|
||||||
|
void** this_ptr = *reinterpret_cast<void***>(&pThisPtr);
|
||||||
|
void** vtable = *reinterpret_cast<void***>(pThisPtr);
|
||||||
|
void* vfunc = vtable[offset];
|
||||||
|
|
||||||
|
union
|
||||||
|
{
|
||||||
|
bool (VKeyValuesSS_Helper::* mfpnew)(const char *, const char *);
|
||||||
|
#ifndef PLATFORM_POSIX
|
||||||
|
void* addr;
|
||||||
|
} u;
|
||||||
|
u.addr = vfunc;
|
||||||
|
#else
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
void* addr;
|
||||||
|
intptr_t adjustor;
|
||||||
|
} s;
|
||||||
|
} u;
|
||||||
|
u.s.addr = vfunc;
|
||||||
|
u.s.adjustor = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return (bool)(reinterpret_cast<VKeyValuesSS_Helper*>(this_ptr)->*u.mfpnew)(pszKey, pszValue);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
string_t CHalfLife2::AllocPooledString(const char *pszValue)
|
string_t CHalfLife2::AllocPooledString(const char *pszValue)
|
||||||
{
|
{
|
||||||
// This is admittedly a giant hack, but it's a relatively safe method for
|
// This is admittedly a giant hack, but it's a relatively safe method for
|
||||||
@ -1378,28 +1406,58 @@ string_t CHalfLife2::AllocPooledString(const char *pszValue)
|
|||||||
// current targetname string_t, set it to our string to insert via SetKeyValue,
|
// current targetname string_t, set it to our string to insert via SetKeyValue,
|
||||||
// read back the new targetname value, restore the old value, and return the new one.
|
// read back the new targetname value, restore the old value, and return the new one.
|
||||||
|
|
||||||
|
#if SOURCE_ENGINE == SE_EPISODEONE
|
||||||
|
CBaseEntity* pEntity = nullptr;
|
||||||
|
for (int i = 0; i < gpGlobals->maxEntities; ++i)
|
||||||
|
{
|
||||||
|
pEntity = ReferenceToEntity(i);
|
||||||
|
if (pEntity)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pEntity)
|
||||||
|
{
|
||||||
|
logger->LogError("Failed to locate a valid entity for AllocPooledString.");
|
||||||
|
return NULL_STRING;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
CBaseEntity *pEntity = ((IServerUnknown *) servertools->FirstEntity())->GetBaseEntity();
|
CBaseEntity *pEntity = ((IServerUnknown *) servertools->FirstEntity())->GetBaseEntity();
|
||||||
|
#endif
|
||||||
auto *pDataMap = GetDataMap(pEntity);
|
auto *pDataMap = GetDataMap(pEntity);
|
||||||
assert(pDataMap);
|
assert(pDataMap);
|
||||||
|
|
||||||
static int offset = -1;
|
static int iNameOffset = -1;
|
||||||
if (offset == -1)
|
if (iNameOffset == -1)
|
||||||
{
|
{
|
||||||
sm_datatable_info_t info;
|
sm_datatable_info_t info;
|
||||||
bool found = FindDataMapInfo(pDataMap, "m_iName", &info);
|
bool found = FindDataMapInfo(pDataMap, "m_iName", &info);
|
||||||
assert(found);
|
assert(found);
|
||||||
offset = info.actual_offset;
|
iNameOffset = info.actual_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
string_t *pProp = (string_t *) ((intp) pEntity + offset);
|
string_t* pProp = (string_t*)((intp)pEntity + iNameOffset);
|
||||||
string_t backup = *pProp;
|
string_t backup = *pProp;
|
||||||
|
|
||||||
|
#if SOURCE_ENGINE == SE_EPISODEONE
|
||||||
|
static int iFuncOffset;
|
||||||
|
if (!g_pGameConf->GetOffset("DispatchKeyValue", &iFuncOffset) || !iFuncOffset)
|
||||||
|
{
|
||||||
|
logger->LogError("Failed to locate DispatchKeyValue in core gamedata. AllocPooledString unsupported.");
|
||||||
|
return NULL_STRING;
|
||||||
|
}
|
||||||
|
VKeyValuesSS(pEntity, "targetname", pszValue, iFuncOffset);
|
||||||
|
#else
|
||||||
servertools->SetKeyValue(pEntity, "targetname", pszValue);
|
servertools->SetKeyValue(pEntity, "targetname", pszValue);
|
||||||
|
#endif
|
||||||
|
|
||||||
string_t newString = *pProp;
|
string_t newString = *pProp;
|
||||||
*pProp = backup;
|
*pProp = backup;
|
||||||
|
|
||||||
return newString;
|
return newString;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
bool CHalfLife2::GetServerSteam3Id(char *pszOut, size_t len) const
|
bool CHalfLife2::GetServerSteam3Id(char *pszOut, size_t len) const
|
||||||
{
|
{
|
||||||
|
@ -239,9 +239,7 @@ public: //IGameHelpers
|
|||||||
void FreeUtlVectorUtlString(CUtlVector<CUtlString, CUtlMemoryGlobalMalloc<CUtlString>> &vec);
|
void FreeUtlVectorUtlString(CUtlVector<CUtlString, CUtlMemoryGlobalMalloc<CUtlString>> &vec);
|
||||||
#endif
|
#endif
|
||||||
bool GetMapDisplayName(const char *pMapName, char *pDisplayname, size_t nMapNameMax);
|
bool GetMapDisplayName(const char *pMapName, char *pDisplayname, size_t nMapNameMax);
|
||||||
#if SOURCE_ENGINE >= SE_ORANGEBOX
|
|
||||||
string_t AllocPooledString(const char *pszValue);
|
string_t AllocPooledString(const char *pszValue);
|
||||||
#endif
|
|
||||||
bool GetServerSteam3Id(char *pszOut, size_t len) const override;
|
bool GetServerSteam3Id(char *pszOut, size_t len) const override;
|
||||||
uint64_t GetServerSteamId64() const override;
|
uint64_t GetServerSteamId64() const override;
|
||||||
public:
|
public:
|
||||||
|
@ -2380,12 +2380,8 @@ static cell_t SetEntPropString(IPluginContext *pContext, const cell_t *params)
|
|||||||
|
|
||||||
if (bIsStringIndex)
|
if (bIsStringIndex)
|
||||||
{
|
{
|
||||||
#if SOURCE_ENGINE < SE_ORANGEBOX
|
|
||||||
return pContext->ThrowNativeError("Cannot set %s. Setting string_t values not supported on this game.", prop);
|
|
||||||
#else
|
|
||||||
*(string_t *) ((intptr_t) pEntity + offset) = g_HL2.AllocPooledString(src);
|
*(string_t *) ((intptr_t) pEntity + offset) = g_HL2.AllocPooledString(src);
|
||||||
len = strlen(src);
|
len = strlen(src);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -41,6 +41,12 @@
|
|||||||
"windows" "4"
|
"windows" "4"
|
||||||
"linux" "4"
|
"linux" "4"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* For AllocPooledString. KeyValue(const char *, const char *) */
|
||||||
|
"DispatchKeyValue"
|
||||||
|
{
|
||||||
|
"windows" "35"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
"Keys"
|
"Keys"
|
||||||
|
Loading…
Reference in New Issue
Block a user