Removed loader's reliance on tier0 by manually parsing command line for -game (bug 5674, r=DS).

This commit is contained in:
Nicholas Hastings 2013-03-22 20:47:35 -04:00
parent 6f10f32a3a
commit 42a139baf5
5 changed files with 65 additions and 108 deletions

View File

@ -41,7 +41,7 @@ class IServerGameDLL;
IGameDllBridge* gamedll_bridge = NULL; IGameDllBridge* gamedll_bridge = NULL;
static int game_info_detected = 0; static int game_info_detected = 0;
static const char *game_name = NULL; static char game_name[128];
static char gamedll_paths[MAX_GAMEDLL_PATHS][PLATFORM_MAX_PATH]; static char gamedll_paths[MAX_GAMEDLL_PATHS][PLATFORM_MAX_PATH];
static void *gamedll_libs[MAX_GAMEDLL_PATHS]; static void *gamedll_libs[MAX_GAMEDLL_PATHS];
static unsigned int gamedll_path_count = 0; static unsigned int gamedll_path_count = 0;
@ -70,7 +70,7 @@ mm_DetectGameInformation()
game_info_detected = -1; game_info_detected = -1;
if ((game_name = mm_GetGameName()) == NULL) if (!mm_GetGameName(game_name, sizeof(game_name)))
{ {
return false; return false;
} }

View File

@ -33,11 +33,9 @@
#include "serverplugin.h" #include "serverplugin.h"
#include "gamedll.h" #include "gamedll.h"
#include "utility.h" #include "utility.h"
#include "valve_commandline.h" #if defined __APPLE__
#include <crt_externs.h>
#undef GetCommandLine #endif
typedef ICommandLine *(*GetCommandLine)();
static HMODULE mm_library = NULL; static HMODULE mm_library = NULL;
static char mm_fatal_logfile[PLATFORM_MAX_PATH] = "metamod-fatal.log"; static char mm_fatal_logfile[PLATFORM_MAX_PATH] = "metamod-fatal.log";
@ -186,94 +184,81 @@ mm_GetProcAddress(const char *name)
return mm_GetLibAddress(mm_library, name); return mm_GetLibAddress(mm_library, name);
} }
#if defined _WIN32 bool
#define TIER0_NAME "bin\\tier0.dll" mm_GetGameName(char *buffer, size_t size)
#define VSTDLIB_NAME "bin\\vstdlib.dll"
#elif defined __APPLE__
#define TIER0_NAME "bin/libtier0.dylib"
#define VSTDLIB_NAME "bin/libvstdlib.dylib"
#elif defined __linux__
#define TIER0_NAME "bin/" LIB_PREFIX "tier0" LIB_SUFFIX
#define VSTDLIB_NAME "bin/" LIB_PREFIX "vstdlib" LIB_SUFFIX
#endif
const char *
mm_GetGameName()
{ {
void *lib; buffer[0] = '\0';
char error[255];
GetCommandLine valve_cmdline;
char lib_path[PLATFORM_MAX_PATH];
const char *game_name;
#ifdef __linux__ #if defined _WIN32
if (!mm_ResolvePath("bin/libtier0_srv.so", lib_path, sizeof(lib_path)) static char game[128];
&& !mm_ResolvePath("bin/libtier0.so", lib_path, sizeof(lib_path))
&& !mm_ResolvePath("bin/tier0_i486.so", lib_path, sizeof(lib_path))) LPWSTR pCmdLine = GetCommandLineW();
#else int argc;
if (!mm_ResolvePath(TIER0_NAME, lib_path, sizeof(lib_path))) LPWSTR *wargv = CommandLineToArgvW(pCmdLine, &argc);
#endif for (int i = 0; i < argc; ++i)
{ {
mm_LogFatal("Could not find path for tier0"); if (wcscmp(wargv[i], L"-game") != 0)
return NULL; continue;
if (++i >= argc)
break;
wcstombs(buffer, wargv[i], size);
buffer[size-1] = '\0';
break;
} }
if ((lib = mm_LoadLibrary(lib_path, error, sizeof(error))) == NULL) LocalFree(wargv);
return buffer[0] != 0;
#elif defined __APPLE__
int argc = *_NSGetArgc();
char **argv = *_NSGetArgv();
for (int i = 0; i < argc; ++i)
{ {
mm_LogFatal("Could not load %s: %s", lib_path, error); if (strcmp(argv[i], "-game") != 0)
return NULL; continue;
if (++i >= argc)
break;
strncpy(buffer, argv[i], size);
buffer[size-1] = '\0';
break;
} }
valve_cmdline = (GetCommandLine)mm_GetLibAddress(lib, "CommandLine_Tier0"); return buffer[0] != 0;
#elif defined __linux__
FILE *pFile = fopen("/proc/self/cmdline", "rb");
if (!pFile)
return false;
/* '_Tier0' dropped on Alien Swarm version */ char *arg = NULL;
if (valve_cmdline == NULL) size_t argsize = 0;
{ bool bNextIsGame = false;
valve_cmdline = (GetCommandLine)mm_GetLibAddress(lib, "CommandLine");
}
if (valve_cmdline == NULL) while (getdelim(&arg, &argsize, NULL, pFile) != -1)
{ {
/* We probably have a Ship engine. */ if (bNextIsGame)
mm_UnloadLibrary(lib);
#ifdef __linux__
if (!mm_ResolvePath("bin/libvstdlib_srv.so", lib_path, sizeof(lib_path))
&& !mm_ResolvePath("bin/libvstdlib.so", lib_path, sizeof(lib_path))
&& !mm_ResolvePath("bin/vstdlib_i486.so", lib_path, sizeof(lib_path)))
#else
if (!mm_ResolvePath(VSTDLIB_NAME, lib_path, sizeof(lib_path)))
#endif
{ {
mm_LogFatal("Could not find path for vstdlib"); strncpy(buffer, arg, size);
return NULL; buffer[size-1] = '\0';
break;
} }
if ((lib = mm_LoadLibrary(lib_path, error, sizeof(error))) == NULL) if (strcmp(arg, "-game") == 0)
{ {
mm_LogFatal("Could not load %s: %s", lib_path, error); bNextIsGame = true;
return NULL;
} }
valve_cmdline = (GetCommandLine)mm_GetLibAddress(lib, "CommandLine");
} }
if (valve_cmdline == NULL) free(arg);
{ fclose(pFile);
mm_LogFatal("Could not locate any command line functionality");
return NULL;
}
game_name = valve_cmdline()->ParmValue("-game"); return buffer[0] != 0;
#else
mm_UnloadLibrary(lib); #error unsupported platform
#endif
/* This probably means that the game directory is actually the current directory */
if (!game_name)
{
game_name = ".";
}
return game_name;
} }
MetamodBackend MetamodBackend

View File

@ -108,8 +108,8 @@ mm_UnloadMetamodLibrary();
extern void extern void
mm_LogFatal(const char *message, ...); mm_LogFatal(const char *message, ...);
extern const char * extern bool
mm_GetGameName(); mm_GetGameName(char *buffer, size_t size);
extern MetamodBackend extern MetamodBackend
mm_DetermineBackend(QueryValveInterface qvi, const char *game_name); mm_DetermineBackend(QueryValveInterface qvi, const char *game_name);

View File

@ -70,7 +70,7 @@ IVspBridge *vsp_bridge = NULL;
*/ */
class ServerPlugin class ServerPlugin
{ {
const char *game_name; char game_name[128];
unsigned int vsp_version; unsigned int vsp_version;
bool load_allowed; bool load_allowed;
public: public:
@ -88,7 +88,7 @@ public:
/* Backend should already filled in if loaded as gamedll */ /* Backend should already filled in if loaded as gamedll */
if (gamedll_bridge == NULL) if (gamedll_bridge == NULL)
{ {
if ((game_name = mm_GetGameName()) == NULL) if (!mm_GetGameName(game_name, sizeof(game_name)))
{ {
return false; return false;
} }

View File

@ -1,28 +0,0 @@
#ifndef _INCLUDE_VALVE_COMMAND_LINE_H_
#define _INCLUDE_VALVE_COMMAND_LINE_H_
class ICommandLine
{
public:
virtual void CreateCmdLine( const char *commandline ) = 0;
virtual void CreateCmdLine( int argc, char **argv ) = 0;
virtual const char *GetCmdLine( void ) const = 0;
// Check whether a particular parameter exists
virtual const char *CheckParm( const char *psz, const char **ppszValue = 0 ) const = 0;
virtual void RemoveParm( const char *parm ) = 0;
virtual void AppendParm( const char *pszParm, const char *pszValues ) = 0;
// Returns the argument after the one specified, or the default if not found
virtual const char *ParmValue( const char *psz, const char *pDefaultVal = 0 ) const = 0;
virtual int ParmValue( const char *psz, int nDefaultVal ) const = 0;
virtual float ParmValue( const char *psz, float flDefaultVal ) const = 0;
// Gets at particular parameters
virtual int ParmCount() const = 0;
virtual int FindParm( const char *psz ) const = 0; // Returns 0 if not found.
virtual const char* GetParm( int nIndex ) const = 0;
};
#endif /* _INCLUDE_VALVE_COMMAND_LINE_H_ */