diff options
| -rw-r--r-- | src/con_.c | 26 | ||||
| -rw-r--r-- | src/con_.h | 3 | ||||
| -rw-r--r-- | src/engineapi.c | 18 | ||||
| -rw-r--r-- | src/engineapi.h | 11 | ||||
| -rw-r--r-- | src/sst.c | 9 | 
5 files changed, 37 insertions, 30 deletions
| @@ -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;  } @@ -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 <stdbool.h> // used in generated code  #include <string.h> // " +#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 <entpropsinit.gen.h> -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 @@ -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 | 
