Skip to content

Commit

Permalink
Backport linkent for hlds (and listenserver) without rehlds
Browse files Browse the repository at this point in the history
  • Loading branch information
s1lentq committed Nov 28, 2023
1 parent 0118e05 commit 83c9d6e
Show file tree
Hide file tree
Showing 13 changed files with 536 additions and 123 deletions.
4 changes: 2 additions & 2 deletions metamod/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,7 @@ target_sources(metamod PRIVATE
"src/engine_api.cpp"
"src/game_support.cpp"
"src/h_export.cpp"
"src/linkent.cpp"
"src/linkgame.cpp"
"src/osdep_linkent_linux.cpp"
"src/log_meta.cpp"
"src/mdebug.cpp"
"src/mem_utils.cpp"
Expand All @@ -174,6 +173,7 @@ target_sources(metamod PRIVATE

target_link_libraries(metamod PRIVATE
dl
pthread
$<$<CONFIG:COMPAT_GLIBC>:libc-2.11.1.so>
)

Expand Down
7 changes: 5 additions & 2 deletions metamod/msvc/metamod.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,6 @@
<ClCompile Include="..\src\engine_api.cpp" />
<ClCompile Include="..\src\game_support.cpp" />
<ClCompile Include="..\src\h_export.cpp" />
<ClCompile Include="..\src\linkent.cpp" />
<ClCompile Include="..\src\linkgame.cpp" />
<ClCompile Include="..\src\log_meta.cpp" />
<ClCompile Include="..\src\mdebug.cpp" />
<ClCompile Include="..\src\mem_utils.cpp" />
Expand All @@ -164,6 +162,11 @@
<ClCompile Include="..\src\mplugin.cpp" />
<ClCompile Include="..\src\mreg.cpp" />
<ClCompile Include="..\src\mutil.cpp" />
<ClCompile Include="..\src\osdep_linkent_linux.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\src\osdep_linkent_win32.cpp" />
<ClCompile Include="..\src\precompiled.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
Expand Down
12 changes: 6 additions & 6 deletions metamod/msvc/metamod.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,6 @@
<ClCompile Include="..\src\h_export.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="..\src\linkent.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="..\src\linkgame.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="..\src\log_meta.cpp">
<Filter>src</Filter>
</ClCompile>
Expand Down Expand Up @@ -98,6 +92,12 @@
<ClCompile Include="..\src\meta_rehlds_api.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="..\src\osdep_linkent_win32.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="..\src\osdep_linkent_linux.cpp">
<Filter>src</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\src\api_info.h">
Expand Down
1 change: 1 addition & 0 deletions metamod/src/h_export.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ void WINAPI GiveFnptrsToDll(enginefuncs_t* pengfuncsFromEngine, globalvars_t* pG
g_engine.funcs = &g_engfuncs;
g_engine.globals = pGlobals;
g_engfuncs = *pengfuncsFromEngine;
g_metamod_module.load(&g_engfuncs);
g_engine.sys_module.load(pengfuncsFromEngine);

g_engfuncs = *pengfuncsFromEngine;
Expand Down
26 changes: 0 additions & 26 deletions metamod/src/linkent.cpp

This file was deleted.

50 changes: 40 additions & 10 deletions metamod/src/linkent.h
Original file line number Diff line number Diff line change
@@ -1,19 +1,49 @@
// vi: set ts=4 sw=4 :
// vim: set tw=75 :

// linkent.h - export entities from mod "games" back to the HL engine

/*
* Copyright (c) 2001-2006 Will Day <[email protected]>
*
* This file is part of Metamod.
*
* Metamod is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* Metamod is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Metamod; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*
*/

#pragma once

// Initializes replacement code
bool meta_init_linkent_replacement(CSysModule *moduleMetamod, CSysModule *moduleGame);

// Comments from SDK dlls/util.h:
//! This is the glue that hooks .MAP entity class names to our CPP classes.
//! The _declspec forces them to be exported by name so we can do a lookup with GetProcAddress().
//! The function is used to intialize / allocate the object for the entity.

// Adapted from LINK_ENTITY_TO_FUNC in adminmod linkfunc.cpp.
typedef void (*ENTITY_FN)(entvars_t *);

// Function to perform common code of LINK_ENTITY_TO_GAME.
void do_link_ent(ENTITY_FN* pfnEntity, int* missing, const char* entStr, entvars_t* pev);

#define LINK_ENTITY_TO_GAME(entityName) \
C_DLLEXPORT void entityName(entvars_t *pev) { \
static ENTITY_FN pfnEntity = nullptr; \
static int missing = 0; \
do_link_ent(&pfnEntity, &missing, STRINGIZE(entityName, 0), pev); \
}
typedef void (*ENTITY_FN) (entvars_t *);
9 changes: 0 additions & 9 deletions metamod/src/linkgame.cpp

This file was deleted.

17 changes: 13 additions & 4 deletions metamod/src/metamod.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ option_t g_global_options[] =

gamedll_t g_GameDLL;

CSysModule g_metamod_module;

ALIGN16
meta_globals_t g_metaGlobals;

Expand Down Expand Up @@ -229,10 +231,17 @@ void metamod_startup()
// Exit on failure here? Dunno...
}

meta_init_rehlds_api();

if (!g_meta_extdll.init(&g_engine.sys_module)) {
Sys_Error("Failure to init extension DLL; exiting...");
if (meta_init_rehlds_api()) {
if (!g_meta_extdll.init(&g_engine.sys_module)) {
Sys_Error("Failure to init extension DLL; exiting...");
}
} else {
// activate linkent-replacement after give_engfuncs so that if game dll is
// plugin too and uses same method we get combined export table of plugin
// and game dll
if (!meta_init_linkent_replacement(&g_metamod_module, &g_GameDLL.sys_module)) {
Sys_Error("dll: Couldn't load linkent replacement for game DLL");
}
}

// Allow for commands to metamod plugins at startup. Autoexec.cfg is
Expand Down
3 changes: 3 additions & 0 deletions metamod/src/metamod.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
// cvar to contain version
extern cvar_t g_meta_version;

// metamod module handle
extern CSysModule g_metamod_module;

// Info about the game dll/mod.
struct gamedll_t
{
Expand Down
65 changes: 3 additions & 62 deletions metamod/src/mextdll.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
CExtDll g_meta_extdll;

CExtDll::CExtDll()
: m_hGameDLL(CSysModule::INVALID_HANDLE), m_dlls(nullptr), m_count(nullptr)
: m_hGameDLL(CSysModule::INVALID_HANDLE)
{
}

Expand All @@ -17,10 +17,6 @@ void CExtDll::load()

return;
}

auto extdll = &m_dlls[(*m_count)++];
Q_memset(extdll, 0, sizeof(*extdll));
extdll->lDLLHandle = m_hGameDLL;
}

void CExtDll::unload()
Expand All @@ -29,68 +25,13 @@ void CExtDll::unload()
g_RehldsFuncs->RemoveExtDll(m_hGameDLL);
return;
}

for (auto i = 0u; i < *m_count; i++)
{
if (m_dlls[i].lDLLHandle == m_hGameDLL)
{
--(*m_count);
if (*m_count != i)
{
Q_memmove(&m_dlls[i], &m_dlls[i + 1], (*m_count - i) * sizeof(m_dlls[0]));
i = *m_count;
}

Q_memset(&m_dlls[i], 0, sizeof(m_dlls[0]));
return;
}
}
}

bool CExtDll::init(CSysModule *module)
{
m_hGameDLL = g_GameDLL.sys_module.gethandle();

if (g_RehldsFuncs) {
return true;
}

m_dlls = (extensiondll_t *)module->getsym("g_rgextdll");
m_count = (size_t *)module->getsym("g_iextdllMac");

if (m_dlls && m_count) {
return true;
}

// HACK HACK MORE HACK
// HLDS SHIT
auto pos = module->find_string_push("SV_SaveGameComment");
if (!pos) {
if (!m_hGameDLL)
return false;
}

const char patterns[2][2][14] = {
{ "\x56\x33\xF6\x39\x2A\x2A\x2A\x2A\x2A\x7E\x2A\x53\x8B", "\x5B\xC3\x90\x90\xA1\x2A\x2A\x2A\x2A\x53\x56\x57\x33" },
{ "\x53\x8B\x2A\x2A\x2A\x2A\x2A\x57\xBF\x2A\x2A\x2A\x2A", "\x7E\x2A\x8B\x2A\x2A\x2A\x2A\x2A\xBE\x2A\x2A\x2A\x2A" },
};

for (auto i = 0u; i < ARRAYSIZE(patterns); i++)
{
auto addr = mem_find_pattern(pos - 33, 20, patterns[0][i], sizeof(patterns[0][i]) - 1);
if (!addr) {
continue;
}

m_count = *(size_t **)(addr + 5);

addr = mem_find_pattern(addr, 30, patterns[1][i], sizeof(patterns[1][i]) - 1);
if (!addr) {
return false;
}

m_dlls = *(extensiondll_t **)(addr + 9);
return true;
}

return false;
return true;
}
2 changes: 0 additions & 2 deletions metamod/src/mextdll.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ class CExtDll

private:
module_handle_t m_hGameDLL;
extensiondll_t *m_dlls;
size_t *m_count;
};

extern CExtDll g_meta_extdll;
Loading

0 comments on commit 83c9d6e

Please sign in to comment.