Skip to content

Commit dea3ef7

Browse files
authored
Add string_t SetEntPropString support for ep1 (fixes #1287) (#1299)
2 parents 3164af7 + 1cc7d37 commit dea3ef7

4 files changed

Lines changed: 71 additions & 13 deletions

File tree

core/HalfLife2.cpp

Lines changed: 65 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1367,8 +1367,36 @@ bool CHalfLife2::IsMapValid(const char *map)
13671367
return FindMap(map) != SMFindMapResult::NotFound;
13681368
}
13691369

1370-
// TODO: Add ep1 support for this. (No IServerTools available there)
1371-
#if SOURCE_ENGINE >= SE_ORANGEBOX
1370+
#if SOURCE_ENGINE < SE_ORANGEBOX
1371+
class VKeyValuesSS_Helper {};
1372+
static bool VKeyValuesSS(CBaseEntity* pThisPtr, const char *pszKey, const char *pszValue, int offset)
1373+
{
1374+
void** this_ptr = *reinterpret_cast<void***>(&pThisPtr);
1375+
void** vtable = *reinterpret_cast<void***>(pThisPtr);
1376+
void* vfunc = vtable[offset];
1377+
1378+
union
1379+
{
1380+
bool (VKeyValuesSS_Helper::* mfpnew)(const char *, const char *);
1381+
#ifndef PLATFORM_POSIX
1382+
void* addr;
1383+
} u;
1384+
u.addr = vfunc;
1385+
#else
1386+
struct
1387+
{
1388+
void* addr;
1389+
intptr_t adjustor;
1390+
} s;
1391+
} u;
1392+
u.s.addr = vfunc;
1393+
u.s.adjustor = 0;
1394+
#endif
1395+
1396+
return (bool)(reinterpret_cast<VKeyValuesSS_Helper*>(this_ptr)->*u.mfpnew)(pszKey, pszValue);
1397+
}
1398+
#endif
1399+
13721400
string_t CHalfLife2::AllocPooledString(const char *pszValue)
13731401
{
13741402
// 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)
13781406
// current targetname string_t, set it to our string to insert via SetKeyValue,
13791407
// read back the new targetname value, restore the old value, and return the new one.
13801408

1409+
#if SOURCE_ENGINE < SE_ORANGEBOX
1410+
CBaseEntity* pEntity = nullptr;
1411+
for (int i = 0; i < gpGlobals->maxEntities; ++i)
1412+
{
1413+
pEntity = ReferenceToEntity(i);
1414+
if (pEntity)
1415+
{
1416+
break;
1417+
}
1418+
}
1419+
1420+
if (!pEntity)
1421+
{
1422+
logger->LogError("Failed to locate a valid entity for AllocPooledString.");
1423+
return NULL_STRING;
1424+
}
1425+
1426+
#else
13811427
CBaseEntity *pEntity = ((IServerUnknown *) servertools->FirstEntity())->GetBaseEntity();
1428+
#endif
13821429
auto *pDataMap = GetDataMap(pEntity);
13831430
assert(pDataMap);
13841431

1385-
static int offset = -1;
1386-
if (offset == -1)
1432+
static int iNameOffset = -1;
1433+
if (iNameOffset == -1)
13871434
{
13881435
sm_datatable_info_t info;
13891436
bool found = FindDataMapInfo(pDataMap, "m_iName", &info);
13901437
assert(found);
1391-
offset = info.actual_offset;
1438+
iNameOffset = info.actual_offset;
13921439
}
13931440

1394-
string_t *pProp = (string_t *) ((intp) pEntity + offset);
1441+
string_t* pProp = (string_t*)((intp)pEntity + iNameOffset);
13951442
string_t backup = *pProp;
1443+
1444+
#if SOURCE_ENGINE < SE_ORANGEBOX
1445+
static int iFuncOffset;
1446+
if (!g_pGameConf->GetOffset("DispatchKeyValue", &iFuncOffset) || !iFuncOffset)
1447+
{
1448+
logger->LogError("Failed to locate DispatchKeyValue in core gamedata. AllocPooledString unsupported.");
1449+
return NULL_STRING;
1450+
}
1451+
VKeyValuesSS(pEntity, "targetname", pszValue, iFuncOffset);
1452+
#else
13961453
servertools->SetKeyValue(pEntity, "targetname", pszValue);
1454+
#endif
1455+
13971456
string_t newString = *pProp;
13981457
*pProp = backup;
13991458

14001459
return newString;
14011460
}
1402-
#endif
14031461

14041462
bool CHalfLife2::GetServerSteam3Id(char *pszOut, size_t len) const
14051463
{

core/HalfLife2.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -239,9 +239,7 @@ class CHalfLife2 :
239239
void FreeUtlVectorUtlString(CUtlVector<CUtlString, CUtlMemoryGlobalMalloc<CUtlString>> &vec);
240240
#endif
241241
bool GetMapDisplayName(const char *pMapName, char *pDisplayname, size_t nMapNameMax);
242-
#if SOURCE_ENGINE >= SE_ORANGEBOX
243242
string_t AllocPooledString(const char *pszValue);
244-
#endif
245243
bool GetServerSteam3Id(char *pszOut, size_t len) const override;
246244
uint64_t GetServerSteamId64() const override;
247245
public:

core/smn_entities.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2380,12 +2380,8 @@ static cell_t SetEntPropString(IPluginContext *pContext, const cell_t *params)
23802380

23812381
if (bIsStringIndex)
23822382
{
2383-
#if SOURCE_ENGINE < SE_ORANGEBOX
2384-
return pContext->ThrowNativeError("Cannot set %s. Setting string_t values not supported on this game.", prop);
2385-
#else
23862383
*(string_t *) ((intptr_t) pEntity + offset) = g_HL2.AllocPooledString(src);
23872384
len = strlen(src);
2388-
#endif
23892385
}
23902386
else
23912387
{

gamedata/core.games/engine.ep1.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,12 @@
4141
"windows" "4"
4242
"linux" "4"
4343
}
44+
45+
/* For AllocPooledString. KeyValue(const char *, const char *) */
46+
"DispatchKeyValue"
47+
{
48+
"windows" "35"
49+
}
4450
}
4551

4652
"Keys"

0 commit comments

Comments
 (0)