Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions gameinfo.conf.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
NAME GameName
Copy link
Copy Markdown
Member

@illwieckz illwieckz Dec 28, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think anything prevents to use a real-life example like Unvanquished default strings in the template.

Copy link
Copy Markdown
Member

@illwieckz illwieckz Dec 28, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same for the default values in the code if undefined.

Note that in the future we would be able to make the engine being able to load some built-in asset and display an error (like Darkplaces does) so the template and the hardcoded version would reference that dummy game that does nothing at all instead.

VERSION 0.0
DEFAULT_BASEPAK mybasepak
Copy link
Copy Markdown
Member

@illwieckz illwieckz Dec 27, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not just BASEPAK? We already know this is the default since it's stored in that file.

Copy link
Copy Markdown
Member

@illwieckz illwieckz Dec 28, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After deep thoughts, this may be called BASENAME, there may be more than one usage for a basename.

We can also use it to compute ~/.local/share/${BASENAME} while other OS may do something with NAME instead if it's more common on such OS to do that (My Games/${GAME}).

I don't think it's a bad idea to enforce the basename is also the basepak name.

It may also make easier to reimplement per-directory full-conversion downloadable mod like quake3 did, by using this BASENAME (unvanquished or quake6) string instead of a shortcut (unv or baseq6).

MASTERSERVER1 master.example.net
MASTERSERVER2 master.template.net
WWW_BASEURL dl.example.net/pkg
GAMENAME_STRING abc
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

URI_PROTO seems to be better or something like that.

2 changes: 2 additions & 0 deletions src.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,8 @@ set(ENGINELIST
${ENGINE_DIR}/sys/con_common.h
${ENGINE_DIR}/sys/con_common.cpp
${ENGINE_DIR}/sys/sys_events.h
${ENGINE_DIR}/qcommon/gameinfo.h
${ENGINE_DIR}/qcommon/gameinfo.cpp
)

if (WIN32)
Expand Down
24 changes: 0 additions & 24 deletions src/common/Defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,30 +31,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef COMMON_DEFS_H_
#define COMMON_DEFS_H_

#define PRODUCT_NAME "Unvanquished"
/** Case, No spaces */
#define PRODUCT_NAME_UPPER "UNVANQUISHED"
/** No case, No spaces */
#define PRODUCT_NAME_LOWER "unvanquished"

#define PRODUCT_VERSION "0.51"

/** Default base package */
#define DEFAULT_BASE_PAK PRODUCT_NAME_LOWER

/** URI scheme and server browser filter */
#define GAMENAME_STRING "unv"
#define GAMENAME_FOR_MASTER PRODUCT_NAME_UPPER

#define MAX_MASTER_SERVERS 5
#define MASTER1_SERVER_NAME "master.unvanquished.net"
#define MASTER2_SERVER_NAME "master2.unvanquished.net"
#define MASTER3_SERVER_NAME ""
#define MASTER4_SERVER_NAME ""
#define MASTER5_SERVER_NAME ""

#define WWW_BASEURL "dl.unvanquished.net/pkg"

#define AUTOEXEC_NAME "autoexec.cfg"

#define CONFIG_NAME "autogen.cfg"
Expand All @@ -63,7 +40,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define SERVERCONFIG_NAME "autogen_server.cfg"

#define UNNAMED_PLAYER "UnnamedPlayer"
#define UNNAMED_SERVER PRODUCT_NAME " " PRODUCT_VERSION " Server"

/** file containing our RSA public and private keys */
#define RSAKEY_FILE "pubkey"
Expand Down
6 changes: 3 additions & 3 deletions src/common/FileSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2171,19 +2171,19 @@ std::string DefaultHomePath()
wchar_t buffer[MAX_PATH];
if (!SUCCEEDED(SHGetFolderPathW(nullptr, CSIDL_PERSONAL, nullptr, SHGFP_TYPE_CURRENT, buffer)))
return "";
return Str::UTF16To8(buffer) + "\\My Games\\" PRODUCT_NAME;
return Str::UTF16To8(buffer) + "\\My Games\\" + Gameinfo::getInstance().name();
#else
const char* home = getenv("HOME");
if (!home)
return "";
#ifdef __APPLE__
return std::string(home) + "/Library/Application Support/" PRODUCT_NAME;
return std::string(home) + "/Library/Application Support/" + Gameinfo::getInstance().name();
#else
const char* _xdgDataHome = getenv("XDG_DATA_HOME");
std::string xdgDataHome = _xdgDataHome == nullptr ? Path::Build(Path::Build(std::string(home), ".local") ,"share") : std::string(_xdgDataHome);
std::string xdgHomePath;

xdgHomePath = Path::Build(xdgDataHome, PRODUCT_NAME_LOWER);
xdgHomePath = Path::Build(xdgDataHome, Gameinfo::getInstance().name_lower());

return xdgHomePath;
#endif
Expand Down
2 changes: 1 addition & 1 deletion src/engine/client/ClientApplication.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ class ClientApplication : public Application {
void Shutdown(bool error, Str::StringRef message) override {
#if defined(_WIN32) || defined(BUILD_GRAPHICAL_CLIENT)
if (error) {
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, PRODUCT_NAME, message.c_str(), nullptr);
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, ENGINE_NAME, message.c_str(), nullptr);
}
#endif

Expand Down
4 changes: 2 additions & 2 deletions src/engine/client/cl_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2918,7 +2918,7 @@ void CL_Init()

p_team = Cvar_Get("p_team", "0", CVAR_ROM );

cl_gamename = Cvar_Get( "cl_gamename", GAMENAME_FOR_MASTER, CVAR_TEMP );
cl_gamename = Cvar_Get( "cl_gamename", Gameinfo::getInstance().name_upper().c_str(), CVAR_TEMP );
cl_altTab = Cvar_Get( "cl_altTab", "1", 0 );

//bani
Expand Down Expand Up @@ -3130,7 +3130,7 @@ void CL_ServerInfoPacket( netadr_t from, msg_t *msg )
// Arnout: if this isn't the correct game, ignore it
gameName = Info_ValueForKey( infoString, "gamename" );

if ( !gameName[ 0 ] || Q_stricmp( gameName, GAMENAME_STRING ) )
if ( !gameName[ 0 ] || Q_stricmp( gameName, Gameinfo::getInstance().gamename_string().c_str() ) )
{
Log::Debug( "Different game info packet: %s", infoString );
return;
Expand Down
2 changes: 1 addition & 1 deletion src/engine/client/dl_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ if (curl_easy_setopt(request_, option, value) != CURLE_OK) { \
return false; \
}

SETOPT( CURLOPT_USERAGENT, Str::Format( "%s %s", PRODUCT_NAME "/" PRODUCT_VERSION, curl_version() ).c_str() )
SETOPT( CURLOPT_USERAGENT, Str::Format( "%s %s", ENGINE_NAME "/" ENGINE_VERSION, curl_version() ).c_str() )
SETOPT( CURLOPT_REFERER, Str::Format("%s%s", URI_SCHEME, Cvar::GetValue("cl_currentServerIP")).c_str() )
SETOPT( CURLOPT_URL, url.c_str() )
SETOPT( CURLOPT_PROTOCOLS, long(CURLPROTO_HTTP) )
Expand Down
18 changes: 11 additions & 7 deletions src/engine/framework/System.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,12 @@ std::string GetSingletonSocketPath()
char homePathHash[33] = "";
Com_MD5Buffer(homePath.data(), homePath.size(), homePathHash, sizeof(homePathHash));
#ifdef _WIN32
return std::string("\\\\.\\pipe\\" PRODUCT_NAME) + suffix + "-" + homePathHash;
return std::string("\\\\.\\pipe\\") + Gameinfo::getInstance().name() + suffix + "-" + homePathHash;
#else
// We use a temporary directory rather that using the homepath because
// socket paths are limited to about 100 characters. This also avoids issues
// when the homepath is on a network filesystem.
return std::string("/tmp/." PRODUCT_NAME_LOWER) + suffix + "-" + homePathHash + "/socket";
return std::string("/tmp/.") + Gameinfo::getInstance().name_lower() + suffix + "-" + homePathHash + "/socket";
#endif
}

Expand Down Expand Up @@ -394,7 +394,7 @@ static void StartSignalThread()
// Command line arguments
struct cmdlineArgs_t {
cmdlineArgs_t()
: homePath(FS::DefaultHomePath()), libPath(FS::DefaultBasePath()), reset_config(false), use_curses(Application::GetTraits().useCurses) {}
: homePath(""), libPath(FS::DefaultBasePath()), reset_config(false), use_curses(Application::GetTraits().useCurses) {}

std::string homePath;
std::string libPath;
Expand Down Expand Up @@ -453,7 +453,7 @@ static void ParseCmdline(int argc, char** argv, cmdlineArgs_t& cmdlineArgs)
}

if (!strcmp(argv[i], "--help") || !strcmp(argv[i], "-help")) {
std::string helpUrl = Application::GetTraits().supportsUri ? " | -connect " URI_SCHEME "ADDRESS[:PORT]" : "";
std::string helpUrl = Application::GetTraits().supportsUri ? " [" URI_SCHEME "ADDRESS[:PORT]]" : "";
printf("Usage: %s [-OPTION]... [+COMMAND...%s]\n", argv[0], helpUrl.c_str());
printf("Possible options are:\n"
" -homepath <path> set the path used for user-specific configuration files and downloaded dpk files\n"
Expand All @@ -468,7 +468,7 @@ static void ParseCmdline(int argc, char** argv, cmdlineArgs_t& cmdlineArgs)
);
OSExit(0);
} else if (!strcmp(argv[i], "--version") || !strcmp(argv[i], "-version")) {
printf(PRODUCT_NAME " " PRODUCT_VERSION "\n");
printf(ENGINE_NAME " " ENGINE_VERSION "\n");
OSExit(0);
} else if (!strcmp(argv[i], "-set")) {
if (i >= argc - 2) {
Expand Down Expand Up @@ -535,16 +535,20 @@ static void Init(int argc, char** argv)
#endif

// Print a banner and a copy of the command-line arguments
Log::Notice(Q3_VERSION " " PLATFORM_STRING " " ARCH_STRING " " __DATE__);
std::string argsString = "cmdline:";
for (int i = 1; i < argc; i++) {
argsString.push_back(' ');
argsString.append(argv[i]);
}
Log::Notice(argsString);

Sys::SetupCrashHandler(); // If Breakpad is enabled, this handler will soon be replaced.
Sys::ParseCmdline(argc, argv, cmdlineArgs);
Gameinfo::getInstance().parse(FS::Path::Build(cmdlineArgs.libPath, "gameinfo.conf"));
Log::Notice("%s %s", Q3_VERSION, PLATFORM_STRING " " ARCH_STRING " " __DATE__);
Log::Notice(argsString);
if (cmdlineArgs.homePath.empty()) {
cmdlineArgs.homePath = FS::DefaultHomePath();
}

// Platform-specific initialization
#ifdef _WIN32
Expand Down
2 changes: 1 addition & 1 deletion src/engine/qcommon/common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -715,7 +715,7 @@ void Com_WriteConfigToFile( const char *filename, void (*writeConfig)( fileHandl
return;
}

FS_Printf( f, "// generated by " PRODUCT_NAME ", do not modify\n" );
FS_Printf( f, "// generated by %s, do not modify\n", Gameinfo::getInstance().name().c_str() );
writeConfig( f );
FS_FCloseFile( f );
}
Expand Down
7 changes: 4 additions & 3 deletions src/engine/qcommon/files.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ constexpr FS::offset_t MAX_FILE_LENGTH = 1000 * 1000 * 1000;
const char TEMP_SUFFIX[] = ".tmp";

// Cvars to select the base and extra packages to use
static Cvar::Cvar<std::string> fs_basepak("fs_basepak", "base pak to load", 0, DEFAULT_BASE_PAK);
static Cvar::Cvar<std::string> fs_basepak( "fs_basepak", "base pak to load", 0, "" );
static Cvar::Cvar<std::string> fs_extrapaks("fs_extrapaks", "space-seperated list of paks to load in addition to the base pak", 0, "");

struct handleData_t {
Expand Down Expand Up @@ -626,8 +626,9 @@ void FS_LoadBasePak()

if (!FS_LoadPak(fs_basepak.Get().c_str())) {
Log::Notice("Could not load base pak '%s', falling back to default\n", fs_basepak.Get().c_str());
if (!FS_LoadPak(DEFAULT_BASE_PAK))
Sys::Error("Could not load default base pak '%s'", DEFAULT_BASE_PAK);
if (!FS_LoadPak(Gameinfo::getInstance().default_basepak().c_str()))
Com_Error(errorParm_t::ERR_FATAL, "Could not load default base pak '%s'",
Gameinfo::getInstance().default_basepak().c_str());
}
}

Expand Down
169 changes: 169 additions & 0 deletions src/engine/qcommon/gameinfo.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
/*
===========================================================================

Daemon GPL Source Code
Copyright (C) 2017, Daemon Developers

This file is part of the Daemon GPL Source Code (Daemon Source Code).

Daemon Source Code 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 3 of the License, or
(at your option) any later version.

Daemon Source Code 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 Daemon Source Code. If not, see <http://www.gnu.org/licenses/>.

===========================================================================
*/

#include <algorithm>
#include <string>

#include "gameinfo.h"
#include "common/FileSystem.h"


Gameinfo& Gameinfo::getInstance()
{
static Gameinfo instance;
return instance;
}

void Gameinfo::parse(std::string fname)
{
if (!FS::RawPath::FileExists(fname))
{
Sys::Error("GAMEINFO: No gameinfo.conf found in libpath");
}
FS::File f = FS::RawPath::OpenRead(fname);
std::string content = f.ReadAll();
f.Close();
Cmd::Args a(content);
if (a.Argc() & 1)
{
Sys::Error("GAMEINFO: Invalid gaminfo.conf");
}
std::vector<std::string> argvec = a.ArgVector();
for (int i = 0; i < argvec.size(); i += 2)
{
if(argvec[i] == "NAME")
{
_name = argvec[i+1];
}
else if(argvec[i] == "VERSION")
{
_version = argvec[i+1];
}
else if(argvec[i] == "DEFAULT_BASEPAK")
{
_default_basepak = argvec[i+1];
}
else if(argvec[i] == "MASTERSERVER1")
{
_masterserver1 = argvec[i+1];
}
else if(argvec[i] == "MASTERSERVER2")
{
_masterserver2 = argvec[i+1];
}
else if(argvec[i] == "MASTERSERVER3")
{
_masterserver3 = argvec[i+1];
}
else if(argvec[i] == "MASTERSERVER4")
{
_masterserver4 = argvec[i+1];
}
else if(argvec[i] == "MASTERSERVER5")
{
_masterserver5 = argvec[i+1];
}
else if(argvec[i] == "WWW_BASEURL")
{
_www_baseurl = argvec[i+1];
}
else if(argvec[i] == "GAMENAME_STRING")
{
_gamename_string = argvec[i+1];
}
else
{
Log::Warn("GAMEINFO: Unrecognized field '%s' in gameinfo.conf", argvec[i]);
}
}
}

std::string Gameinfo::name() const
{
return _name;
}

std::string Gameinfo::name_lower() const
{
std::string temp = _name;
std::transform(temp.begin(), temp.end(), temp.begin(), ::tolower);
return temp;
}

std::string Gameinfo::name_upper() const
{
std::string temp = _name;
std::transform(temp.begin(), temp.end(), temp.begin(), ::toupper);
return temp;
}

std::string Gameinfo::version() const
{
return _version;
}

std::string Gameinfo::default_basepak() const
{
return _default_basepak;
}

std::string Gameinfo::masterserver1() const
{
return _masterserver1;
}

std::string Gameinfo::masterserver2() const
{
return _masterserver2;
}

std::string Gameinfo::masterserver3() const
{
return _masterserver3;
}

std::string Gameinfo::masterserver4() const
{
return _masterserver4;
}

std::string Gameinfo::masterserver5() const
{
return _masterserver5;
}

std::string Gameinfo::www_baseurl() const
{
return _www_baseurl;
}

std::string Gameinfo::unnamed_server() const
{
return _name + " " + _version + " Server";
}

std::string Gameinfo::gamename_string() const
{
return _gamename_string;
}
Loading