2
0
mirror of https://github.com/rehlds/metamod-r.git synced 2025-01-19 01:58:18 +03:00
metamod-r/metamod/src/game_support.cpp

146 lines
4.0 KiB
C++
Raw Normal View History

2016-07-26 07:22:47 +07:00
#include "precompiled.h"
// Adapted from adminmod h_export.cpp:
//! this structure contains a list of supported mods and their dlls names
2016-07-26 23:31:47 +07:00
//! To add support for another mod add an entry here, and add all the
2016-07-26 07:22:47 +07:00
//! exported entities to link_func.cpp
2016-07-26 23:31:47 +07:00
const game_modinfo_t known_games[] = {
// name/gamedir linux_so win_dll desc
2016-07-26 07:22:47 +07:00
//
// Previously enumerated in this sourcefile, the list is now kept in a
2016-07-26 23:31:47 +07:00
// separate file, generated based on game information stored in a
2016-07-26 07:22:47 +07:00
// convenient db.
2016-07-26 23:31:47 +07:00
{ "cstrike", "cs.so", "mp.dll", "Counter-Strike" },
{ "czero", "cs.so", "mp.dll", "Counter-Strike:Condition Zero" },
2016-07-26 07:22:47 +07:00
// End of list terminator:
2016-07-26 23:31:47 +07:00
{ NULL, NULL, NULL, NULL }
2016-07-26 07:22:47 +07:00
};
// Find a modinfo corresponding to the given game name.
2016-07-26 23:31:47 +07:00
inline const game_modinfo_t *lookup_game(const char *name)
2016-07-26 07:22:47 +07:00
{
2016-07-26 23:31:47 +07:00
for (auto& known : known_games)
{
if (known.name && Q_stricmp(known.name, name))
return &known;
2016-07-26 07:22:47 +07:00
}
2016-07-26 23:31:47 +07:00
2016-07-26 07:22:47 +07:00
// no match found
2016-07-26 23:31:47 +07:00
return nullptr;
2016-07-26 07:22:47 +07:00
}
2016-07-26 23:31:47 +07:00
// Installs gamedll from Steam cache
mBOOL install_gamedll(char *from, const char *to)
2016-07-26 07:22:47 +07:00
{
int length_in;
int length_out;
2016-07-26 23:31:47 +07:00
if (!from)
return mFALSE;
if (!to)
to = from;
2016-07-26 07:22:47 +07:00
2016-07-26 23:31:47 +07:00
byte *cachefile = LOAD_FILE_FOR_ME(from, &length_in);
2016-07-26 07:22:47 +07:00
// If the file seems to exist in the cache.
2016-07-26 23:31:47 +07:00
if (cachefile)
{
2016-07-26 07:22:47 +07:00
int fd = open(to, O_WRONLY | O_CREAT | O_EXCL | O_BINARY, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
2016-07-26 23:31:47 +07:00
if (fd < 0)
{
META_DEBUG(3, ("Installing gamedll from cache: Failed to create file %s: %s", to, strerror(errno)) );
2016-07-26 07:22:47 +07:00
FREE_FILE(cachefile);
return mFALSE;
}
2016-07-26 23:31:47 +07:00
length_out = Q_write(fd, cachefile, length_in);
2016-07-26 07:22:47 +07:00
FREE_FILE(cachefile);
close(fd);
// Writing the file was not successfull
2016-07-26 23:31:47 +07:00
if (length_out != length_in)
{
META_DEBUG(3, ("Installing gamedll from chache: Failed to write all %d bytes to file, only %d written: %s", length_in, length_out, strerror(errno)));
2016-07-26 07:22:47 +07:00
// Let's not leave a mess but clean up nicely.
2016-07-26 23:31:47 +07:00
if (length_out >= 0)
_unlink(to);
2016-07-26 07:22:47 +07:00
return mFALSE;
}
2016-07-26 23:31:47 +07:00
META_LOG("Installed gamedll %s from cache.", to);
2016-07-26 07:22:47 +07:00
}
2016-07-26 23:31:47 +07:00
else
{
META_DEBUG(3, ("Failed to install gamedll from cache: file %s not found in cache.", from));
2016-07-26 07:22:47 +07:00
return mFALSE;
}
return mTRUE;
}
// Set all the fields in the gamedll struct, - based either on an entry in
2016-07-26 23:31:47 +07:00
// known_games matching the current gamedir, or on one specified manually
2016-07-26 07:22:47 +07:00
// by the server admin.
//
// meta_errno values:
// - ME_NOTFOUND couldn't recognize game
2016-07-26 23:31:47 +07:00
mBOOL setup_gamedll(gamedll_t *gamedll)
2016-07-26 07:22:47 +07:00
{
2016-07-26 23:31:47 +07:00
const game_modinfo_t *known;
const char *knownfn = nullptr;
2016-07-26 07:22:47 +07:00
// Check for old-style "metagame.ini" file and complain.
if (valid_gamedir_file(OLD_GAMEDLL_TXT))
2016-07-26 23:31:47 +07:00
{
META_WARNING("File '%s' is no longer supported; instead, specify override gamedll in %s or with '+localinfo mm_gamedll <dllfile>'", OLD_GAMEDLL_TXT, CONFIG_INI);
}
2016-07-26 07:22:47 +07:00
// First, look for a known game, based on gamedir.
2016-07-26 23:31:47 +07:00
if ((known = lookup_game(gamedll->name)))
{
2016-07-26 07:22:47 +07:00
#ifdef _WIN32
2016-07-26 23:31:47 +07:00
knownfn = known->win_dll;
2016-07-26 07:22:47 +07:00
#else
2016-07-26 23:31:47 +07:00
knownfn = known->linux_so;
#endif
2016-07-26 07:22:47 +07:00
2016-07-26 23:31:47 +07:00
META_DEBUG(4, ("Checking for old version game DLL name '%s'.\n", knownfn));
Q_snprintf(gamedll->pathname, sizeof(gamedll->pathname), "dlls/%s", knownfn);
2016-07-26 23:31:47 +07:00
// Check if the gamedll file exists. If not, try to install it from the cache.
if (!valid_gamedir_file(gamedll->pathname))
{
Q_snprintf(gamedll->real_pathname, sizeof(gamedll->real_pathname), "%s/dlls/%s", gamedll->gamedir, knownfn);
install_gamedll(gamedll->pathname, gamedll->real_pathname);
2016-07-26 07:22:47 +07:00
}
}
2016-07-26 23:31:47 +07:00
else
{
// Neither known-list found a gamedll.
RETURN_ERRNO(mFALSE, ME_NOTFOUND);
}
2016-07-26 23:31:47 +07:00
Q_snprintf(gamedll->pathname, sizeof(gamedll->pathname), "%s/dlls/%s", gamedll->gamedir, knownfn);
// get filename from pathname
2016-07-26 23:31:47 +07:00
char *cp = Q_strrchr(gamedll->pathname, '/');
if (cp)
cp++;
else
cp = gamedll->pathname;
2016-07-26 07:22:47 +07:00
2016-07-26 23:31:47 +07:00
gamedll->file = cp;
2016-07-26 23:31:47 +07:00
Q_strncpy(gamedll->real_pathname, gamedll->pathname, sizeof(gamedll->real_pathname) - 1);
gamedll->real_pathname[sizeof(gamedll->real_pathname) - 1] = '\0';
2016-07-26 07:22:47 +07:00
2016-07-26 23:31:47 +07:00
gamedll->desc = known->desc;
META_LOG("Recognized game '%s'; using dllfile '%s'", gamedll->name, gamedll->file);
2016-07-26 07:22:47 +07:00
2016-07-26 23:31:47 +07:00
return mTRUE;
2016-07-26 07:22:47 +07:00
}