From a0138ff3772e71f338d04668076ec1eb9d44f8f4 Mon Sep 17 00:00:00 2001 From: Michael Smith Date: Thu, 12 May 2022 16:17:42 +0100 Subject: Further clean up engine API initialisation --- src/con_.c | 26 ++++++++++++++------------ src/con_.h | 3 ++- src/engineapi.c | 18 ++++++++++++++---- src/engineapi.h | 11 ++++++----- src/sst.c | 9 +-------- 5 files changed, 37 insertions(+), 30 deletions(-) diff --git a/src/con_.c b/src/con_.c index fd5db62..715872b 100644 --- a/src/con_.c +++ b/src/con_.c @@ -22,6 +22,7 @@ #include "abi.h" #include "con_.h" +#include "engineapi.h" // only for factories - XXX: do we care this is circular? #include "extmalloc.h" #include "gametype.h" #include "mem.h" @@ -52,6 +53,8 @@ void (*_con_colourmsgf)(void *this, const struct con_colour *c, const char *fmt, // XXX: the const and non-const entries might actually be flipped on windows, // not 100% sure, but dunno if it's worth essentially duping most of these when // the actual executed machine code is probably identical anyway. +// XXX: make these use gamedata at some point and avoid all the conditionals, +// now that gamedata is populated before the rest of console init DECL_VFUNC(int, AllocateDLLIdentifier, 5) DECL_VFUNC(int, AllocateDLLIdentifier_p2, 8) DECL_VFUNC(void, RegisterConCommand, 6, /*ConCommandBase*/ void *) @@ -240,6 +243,7 @@ static void VCALLCONV InternalSetIntValue(struct con_var *this, int v) { // Hack: IConVar things get this-adjusted pointers, we just reverse the offset // to get the top pointer. +// XXX: rewrite these at some point to use the normal VCALL stuff static void VCALLCONV SetValue_str_thunk(void *thisoff, const char *v) { struct con_var *this = mem_offset(thisoff, -offsetof(struct con_var, vtable_iconvar)); @@ -335,7 +339,7 @@ void *_con_vtab_iconvar[7] = { #endif }; -static void fillvts(void) { +void con_init(void) { void **pc = _con_vtab_cmd + 3 + NVDTOR, **pv = _con_vtab_var + 3 + NVDTOR, **pi = _con_vtab_iconvar #ifndef _WIN32 @@ -394,6 +398,8 @@ static void fillvts(void) { *pi++ = (void *)&IsFlagSet_thunk; // last one: not in 004, but doesn't matter. one less branch! *pi++ = (void *)&GetSplitScreenPlayerSlot; + + regcmds(); } void con_reg(void *cmd_or_var) { @@ -405,9 +411,9 @@ void con_reg(void *cmd_or_var) { } } -bool con_init(void *(*f)(const char *, int *), int plugin_ver) { +bool con_detect(int pluginver) { int ifacever; // for error messages - if (_con_iface = f("VEngineCvar007", 0)) { + if (_con_iface = factory_engine("VEngineCvar007", 0)) { // GENIUS HACK (BUT STILL BAD): Portal 2 has everything in ICvar shifted // down 3 places due to the extra stuff in IAppSystem. This means that // if we look up the Portal 2-specific cvar using FindCommandBase, it @@ -442,28 +448,24 @@ bool con_init(void *(*f)(const char *, int *), int plugin_ver) { ifacever = 7; goto e; } - fillvts(); - regcmds(); return true; } - if (_con_iface = f("VEngineCvar004", 0)) { + if (_con_iface = factory_engine("VEngineCvar004", 0)) { // TODO(compat): are there any cases where 004 is incompatible? could // this crash? find out! _con_colourmsgf = VFUNC(_con_iface, ConsoleColorPrintf_004); dllid = VCALL(_con_iface, AllocateDLLIdentifier); // even more spaghetti! we need the plugin interface version to // accurately distinguish 2007/2013 branches - if (plugin_ver == 3) _gametype_tag |= _gametype_tag_2013; + if (pluginver == 3) _gametype_tag |= _gametype_tag_2013; else _gametype_tag |= _gametype_tag_OrangeBox; - fillvts(); - regcmds(); return true; } - if (f("VEngineCvar003", 0)) { + if (factory_engine("VEngineCvar003", 0)) { ifacever = 3; goto warnoe; } - if (f("VEngineCvar002", 0)) { + if (factory_engine("VEngineCvar002", 0)) { // I don't suppose there's anything below 002 worth caring about? Shrug. ifacever = 2; warnoe: con_warn("sst: error: old engine console support is not implemented\n"); @@ -474,7 +476,7 @@ warnoe: con_warn("sst: error: old engine console support is not implemented\n"); e: con_msg("\n\n"); con_msg("-- Please include ALL of the following if asking for help:\n"); con_msg("-- plugin: " LONGNAME " v" VERSION "\n"); - con_msg("-- interfaces: %d/%d\n", plugin_ver, ifacever); + con_msg("-- interfaces: %d/%d\n", pluginver, ifacever); con_msg("\n\n"); return false; } diff --git a/src/con_.h b/src/con_.h index 93306ad..900e8fa 100644 --- a/src/con_.h +++ b/src/con_.h @@ -94,7 +94,8 @@ typedef int (*con_complcb)(const char *part, * These are called by the plugin load/unload functions; they have no use * elsewhere. */ -bool con_init(void *(*f)(const char *, int *), int plugin_ver); +bool con_detect(int pluginver); +void con_init(void); void con_disconnect(void); /* diff --git a/src/engineapi.c b/src/engineapi.c index 5113883..369bebd 100644 --- a/src/engineapi.c +++ b/src/engineapi.c @@ -17,8 +17,10 @@ #include // used in generated code #include // " +#include "con_.h" #include "engineapi.h" #include "gamedata.h" +#include "gameinfo.h" #include "gametype.h" #include "intdefs.h" #include "mem.h" // " @@ -26,8 +28,6 @@ #include "vcall.h" #include "x86.h" -#include "con_.h" - u64 _gametype_tag = 0; // declared in gametype.h but seems sensible enough here ifacefactory factory_client = 0, factory_server = 0, factory_engine = 0, @@ -45,7 +45,9 @@ DECL_VFUNC_DYN(int, GetEngineBuildNumber) #include -void engineapi_init(void) { +bool engineapi_init(int pluginver) { + if (!con_detect(pluginver)) return false; + if (engclient = factory_engine("VEngineClient015", 0)) { _gametype_tag |= _gametype_tag_Client015; } @@ -77,6 +79,11 @@ void engineapi_init(void) { _gametype_tag |= _gametype_tag_SrvDLL005; } + // detect p1 for the benefit of specific features + if (!GAMETYPE_MATCHES(Portal2) && con_findcmd("upgrade_portalgun")) { + _gametype_tag |= _gametype_tag_Portal1; + } + // TERRIBLE HACK: TODO(compat): come up with a better method later if (GAMETYPE_MATCHES(L4D2) && os_access(OS_LIT( "update/maps/c14m1_junkyard.bsp"), R_OK) != -1) { @@ -86,12 +93,15 @@ void engineapi_init(void) { // need to do this now; ServerClass network table iteration requires // SendProp offsets gamedata_init(); + con_init(); + if (!gameinfo_init()) { con_disconnect(); return false; } - // TODO(compat): we need this terrible hack for now because TLS somehow if (has_vtidx_GetAllServerClasses && has_sz_SendProp && has_off_SP_varname && has_off_SP_offset) { initentprops(VCALL(srvdll, GetAllServerClasses)); } + + return true; } // vi: sw=4 ts=4 noet tw=80 cc=80 diff --git a/src/engineapi.h b/src/engineapi.h index 6def65b..fc191ca 100644 --- a/src/engineapi.h +++ b/src/engineapi.h @@ -127,13 +127,14 @@ extern void *globalvars; /* * Called on plugin init to attempt to initialise various core interfaces. - * Doesn't return an error result, because the plugin can still load even if - * this stuff is missing. + * This includes console/cvar initialisation and populating gametype and + * gamedata values. * - * Also performs additional gametype detection after con_init(), and calls - * gamedata_init() to setup offsets and such. + * Returns true if there is enough stuff in place for the plugin to function - + * there may still be stuff missing. Returns false if there's no way the plugin + * can possibly work, e.g. if there's no cvar interface. */ -void engineapi_init(void); +bool engineapi_init(int pluginver); #endif diff --git a/src/sst.c b/src/sst.c index 13e8b19..5a7ca31 100644 --- a/src/sst.c +++ b/src/sst.c @@ -28,7 +28,6 @@ #include "ent.h" #include "fov.h" #include "fixes.h" -#include "gamedata.h" #include "gameinfo.h" #include "gametype.h" #include "hook.h" @@ -201,13 +200,7 @@ static bool already_loaded = false, skip_unload = false; static bool do_load(ifacefactory enginef, ifacefactory serverf) { factory_engine = enginef; factory_server = serverf; - if (!con_init(enginef, ifacever)) return false; - engineapi_init(); // load some other interfaces. also calls gamedata_init() - // detect p1 for the benefit of specific features - if (!GAMETYPE_MATCHES(Portal2) && con_findcmd("upgrade_portalgun")) { - _gametype_tag |= _gametype_tag_Portal1; - } - if (!gameinfo_init()) { con_disconnect(); return false; } + if (!engineapi_init(ifacever)) return false; const void **p = vtable_firstdiff; if (GAMETYPE_MATCHES(Portal2)) *p++ = (void *)&nop_p_v; // ClientFullyConnect -- cgit v1.2.3