/* ** Command & Conquer Renegade(tm) ** Copyright 2025 Electronic Arts Inc. ** ** This program 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. ** ** This program 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 this program. If not, see . */ // // Filename: useroptions.cpp // Author: Tom Spencer-Smith // Date: Dec 1999 // Description: // #include "useroptions.h" #include "_globals.h" #include "wwdebug.h" #include "player.h" #include "cnetwork.h" #include "registry.h" #include "player.h" #include "playertype.h" #include "bandwidth.h" #include "bandwidthcheck.h" #include #include "trim.h" #include "singletoninstancekeeper.h" #include "slavemaster.h" #include "debug.h" #include "rawfile.h" #include "serversettings.h" #include "autostart.h" #include "consolemode.h" #include "GameSpy_QnR.h" #include "gamespyadmin.h" #include "specialbuilds.h" #include "useroptions.h" extern char DefaultRegistryModifier[1024]; // // Class statics // cRegistryBool cUserOptions::ShowNamesOnSoldier( APPLICATION_SUB_KEY_NAME_NETOPTIONS, "ShowNamesOnSoldier", true); cRegistryBool cUserOptions::SkipQuitConfirmDialog( APPLICATION_SUB_KEY_NAME_OPTIONS, "SkipQuitConfirmDialog", false); cRegistryBool cUserOptions::SkipIngameQuitConfirmDialog( APPLICATION_SUB_KEY_NAME_OPTIONS, "SkipIngameQuitConfirmDialog", false); cRegistryBool cUserOptions::CameraLockedToTurret( APPLICATION_SUB_KEY_NAME_OPTIONS, "CameraLockedToTurret", false); cRegistryBool cUserOptions::PermitDiagLogging( APPLICATION_SUB_KEY_NAME_OPTIONS, "PermitDiagLogging", true); cRegistryInt cUserOptions::Sku( APPLICATION_SUB_KEY_NAME, "SKU", RENEGADE_BASE_SKU); cRegistryInt cUserOptions::BandwidthType( APPLICATION_SUB_KEY_NAME_NETOPTIONS, "BandwidthType", BANDWIDTH_AUTO); cRegistryInt cUserOptions::BandwidthBps( APPLICATION_SUB_KEY_NAME_NETOPTIONS, "BandwidthBps", 33600); cRegistryInt cUserOptions::GameSpyBandwidthType( APPLICATION_SUB_KEY_NAME_GAMESPY, "GameSpyBandwidthType", BANDWIDTH_AUTO); cRegistryInt cUserOptions::PreferredGameSpyNic( APPLICATION_SUB_KEY_NAME_GAMESPY, "PreferredGameSpyNic", 0); cRegistryString cUserOptions::GameSpyNickname( APPLICATION_SUB_KEY_NAME_GAMESPY, "GameSpyNickname", ""); cRegistryInt cUserOptions::GameSpyQueryPort( APPLICATION_SUB_KEY_NAME_GAMESPY, "GameSpyQueryPort", 25300); cRegistryInt cUserOptions::GameSpyGamePort( APPLICATION_SUB_KEY_NAME_GAMESPY, "GameSpyGamePort", 4848); cRegistryInt cUserOptions::SplashCount( APPLICATION_SUB_KEY_NAME_GAMESPY, "SplashCount", 0); cRegistryBool cUserOptions::DoneClientBandwidthTest( APPLICATION_SUB_KEY_NAME_GAMESPY, "DoneClientBandwidthTest", false); cRegistryInt cUserOptions::PreferredLanNic( APPLICATION_SUB_KEY_NAME_NETOPTIONS, "PreferredLanNic", 0); cRegistryInt cUserOptions::NetUpdateRate( APPLICATION_SUB_KEY_NAME_NETOPTIONS, "NetUpdateRate", 10); cRegistryFloat cUserOptions::ClientHintFactor( APPLICATION_SUB_KEY_NAME_NETOPTIONS, "ClientHintFactor", 10.0f); cRegistryFloat cUserOptions::MaxFacingPenalty( APPLICATION_SUB_KEY_NAME_NETOPTIONS, "MaxFacingPenalty", 0.3f); cRegistryFloat cUserOptions::IrrelevancePenalty( APPLICATION_SUB_KEY_NAME_NETOPTIONS, "IrrelevancePenalty", 0.2f); cRegistryInt cUserOptions::ResultsLogNumber( APPLICATION_SUB_KEY_NAME_NETOPTIONS, "ResultsLogNumber", 1); //----------------------------------------------------------------------------- bool cUserOptions::Parse_Command_Line(LPCSTR command) { WWASSERT(command != NULL); bool retcode = true; // // Convert to argv & argc for convenience. // First argument is supposed to be a pointer to the .EXE that is running // but we don't need that here. // int argc = 1; //Set argument count to 1 char * argv[20]; //Pointers to command line arguments argv[0] = NULL; //Set 1st command line argument to point to full path // // Get pointers to command line arguments just like if we were in DOS // char *command_line = strdup(command); char *token = strtok(command_line, " "); while (argc < ARRAY_SIZE(argv) && token != NULL) { argv[argc++] = strtrim(token); token = strtok(NULL, " "); if (argc >= 19) { break; } } // // Loop through all the command line arguments. // char *cmd; for (int i=1 ; i 0) { port = atoi(tport); } } addr = ::inet_addr(ipaddr); cGameSpyAdmin::Set_Game_Host_Ip(addr); cGameSpyAdmin::Set_Game_Host_Port(port); cGameSpyAdmin::Set_Is_Launch_From_Gamespy_Requested(true); } char * nickname_param = ::strstr(tmpstr, "+NETPLAYERNAME"); if (nickname_param != NULL) { nickname_param = (char *)(command + (nickname_param-tmpstr)); nickname_param += ::strlen("+NetPlayerName"); char * start = nickname_param; // Strip leading spaces while (*start && *start == ' ') start++; // if we find a space before a quote then space delimit while (*start && *start != '"' && *start != ' ') { start++; } char * end = start; // Match the end quote if (*start && *start != ' ') { start++; end = start; while (*end && *end != '"') { end++; } } // Couldn't find any quotes, so delimit by spaces if (start == end) { start = nickname_param; while (*start && *start == ' ') start++; end = strchr(start, ' '); if (!end) end = start + strlen(start); } char nickname2[300] = ""; ::strncpy(nickname2, start, end - start); nickname2[end - start] = 0; cUserOptions::GameSpyNickname.Set(nickname2); cGameSpyAdmin::Set_Is_Launch_From_Gamespy_Requested(true); } char * password_param = ::strstr(tmpstr, "+PASS"); if (password_param != NULL) { char *tmp_param = ::strstr(tmpstr, "+PASSWORD"); if (tmp_param) { password_param = (char *)(command + (tmp_param-tmpstr)); password_param += ::strlen("+PASSWORD"); } else { password_param = (char *)(command + (password_param-tmpstr)); password_param += ::strlen("+PASS"); } char * start = password_param; // Strip leading spaces while (*start && *start == ' ') start++; // if we find a space before a quote then space delimit while (*start && *start != '"' && *start != ' ') { start++; } char * end = start; // Match the end quote if (*start && *start != ' ') { start++; end = start; while (*end && *end != '"') { end++; } } // Couldn't find any quotes, so delimit by spaces if (start == end) { start = password_param; while (*start && *start == ' ') start++; end = strchr(start, ' '); if (!end) end = start + strlen(start); } char password[300] = ""; ::strncpy(password, start, end - start); password[end - start] = 0; WideStringClass wide_password; wide_password.Convert_From(password); cGameSpyAdmin::Set_Password_Attempt(wide_password); } free(tmpstr); #endif // !BETACLIENT // Return true if command line options scanned OK. return(retcode); } //----------------------------------------------------------------------------- void cUserOptions::Set_Server_INI_File(char *cmd_line_entry) { char server_config_file[MAX_PATH]; strcpy(server_config_file, strstr(cmd_line_entry, "STARTSERVER=") + 12); WWDEBUG_SAY(("Set to load server settings from config file %s\n", server_config_file)); RawFileClass file(server_config_file); if (file.Is_Available()) { ServerSettingsClass::Set_Settings_File_Name(server_config_file); RegistryClass registry (APPLICATION_SUB_KEY_NAME_WOLSETTINGS); if (registry.Is_Valid ()) { registry.Set_Int(AutoRestartClass::REG_VALUE_AUTO_RESTART_FLAG, 1); registry.Set_Int(AutoRestartClass::REG_VALUE_AUTO_RESTART_TYPE, 1); } } } //----------------------------------------------------------------------------- void cUserOptions::Set_Bandwidth_Type(BANDWIDTH_TYPE_ENUM bandwidth_type) { if (cGameSpyAdmin::Is_Gamespy_Game()) { GameSpyBandwidthType.Set(bandwidth_type); } else { BandwidthType.Set(bandwidth_type); } if (bandwidth_type != BANDWIDTH_CUSTOM) { if (bandwidth_type == BANDWIDTH_AUTO && BandwidthCheckerClass::Got_Bandwidth()) { ULONG bps = BandwidthCheckerClass::Get_Upstream_Bandwidth(); WWASSERT(bps > 0); BandwidthBps.Set(bps); } else { ULONG bps = cBandwidth::Get_Bandwidth_Bps_From_Type(bandwidth_type); WWASSERT(bps > 0); BandwidthBps.Set(bps); } } } //----------------------------------------------------------------------------- BANDWIDTH_TYPE_ENUM cUserOptions::Get_Bandwidth_Type(void) { if (cGameSpyAdmin::Is_Gamespy_Game()) { return (BANDWIDTH_TYPE_ENUM) GameSpyBandwidthType.Get(); } else { return (BANDWIDTH_TYPE_ENUM) BandwidthType.Get(); } } //----------------------------------------------------------------------------- void cUserOptions::Set_Bandwidth_Bps(int bandwidth_bps) { WWASSERT(bandwidth_bps > 0); if (cGameSpyAdmin::Is_Gamespy_Game()) { GameSpyBandwidthType.Set(BANDWIDTH_CUSTOM); } else { BandwidthType.Set(BANDWIDTH_CUSTOM); } BandwidthBps.Set(bandwidth_bps); } //----------------------------------------------------------------------------- void cUserOptions::Reread(void) { Sku.Set(RegistryClass(APPLICATION_SUB_KEY_NAME).Get_Int("SKU", Sku.Get())); BandwidthType.Set(RegistryClass(APPLICATION_SUB_KEY_NAME_NETOPTIONS).Get_Int("BandwidthType", BandwidthType.Get())); BandwidthBps.Set(RegistryClass(APPLICATION_SUB_KEY_NAME_NETOPTIONS).Get_Int("BandwidthBps", BandwidthBps.Get())); GameSpyBandwidthType.Set(RegistryClass(APPLICATION_SUB_KEY_NAME_GAMESPY).Get_Int("GameSpyBandwidthType", GameSpyBandwidthType.Get())); } /* cRegistryInt cUserOptions::GameListFilterMaxPing( APPLICATION_SUB_KEY_NAME_NETOPTIONS, "GameListFilterMaxPing", 9999); cRegistryInt cUserOptions::GameListFilterMinPlayersPresent( APPLICATION_SUB_KEY_NAME_NETOPTIONS, "GameListFilterMinPlayersPresent", 0); cRegistryInt cUserOptions::GameListFilterMaxPlayersPresent( APPLICATION_SUB_KEY_NAME_NETOPTIONS, "GameListFilterMaxPlayersPresent", 99); cRegistryInt cUserOptions::GameListFilterMaxPlayersPermitted( APPLICATION_SUB_KEY_NAME_NETOPTIONS, "GameListFilterMaxPlayersPermitted", 99); cRegistryBool cUserOptions::GameListFilterShowPrivateGames( APPLICATION_SUB_KEY_NAME_NETOPTIONS, "GameListFilterShowPrivateGames", true); cRegistryBool cUserOptions::GameListFilterShowOnlyDedicatedGames( APPLICATION_SUB_KEY_NAME_NETOPTIONS, "GameListFilterShowOnlyDedicatedGames", false); cRegistryBool cUserOptions::GameListFilterShowOnlyGamesIRankFor( APPLICATION_SUB_KEY_NAME_NETOPTIONS, "GameListFilterShowOnlyGamesIRankFor", false); */ /* // // Gamespy client launch params. // All 3 must be specified. // Example: Renegade.exe GAMESPY_IPADDR=192.168.10.100 GAMESPY_PORT=3333 GAMESPY_NICKNAME="Bob 1234" // LPCSTR param = NULL; char * value = NULL; param = "GAMESPY_IPADDR="; value = ::strstr(cmd, param); if (value != NULL) { value += ::strlen(param); ULONG ip = ::inet_addr(value); cGameSpyAdmin::Set_Game_Host_Ip(ip); cGameSpyAdmin::Set_Is_Launch_From_Gamespy_Requested(true); continue; } param = "GAMESPY_PORT="; value = ::strstr(cmd, param); if (value != NULL) { value += ::strlen(param); USHORT port = (USHORT)::atol(value); cGameSpyAdmin::Set_Game_Host_Port(port); cGameSpyAdmin::Set_Is_Launch_From_Gamespy_Requested(true); continue; } param = "GAMESPY_NICKNAME="; value = ::strstr(cmd, param); if (value != NULL) { value += ::strlen(param); WideStringClass nickname; char temp[200] = ""; char seps[] = "\""; char * start_token = ::strtok(value, seps); if (start_token != NULL) { start_token++; } char * end_token = ::strtok(NULL, seps); if (end_token != NULL && end_token > start_token) { ::strncpy(temp, start_token, end_token - start_token); temp[end_token - start_token] = 0; } nickname.Convert_From(temp); cGameSpyAdmin::Set_Player_Nickname(nickname); cGameSpyAdmin::Set_Is_Launch_From_Gamespy_Requested(true); continue; } */ /* char nickname[300] = ""; ::sscanf(nickname_param, "%s", nickname); nickname[::strlen(nickname) - 1] = ' '; nickname[0] = ' '; char nickname2[300] = ""; ::sscanf(nickname, "%s", nickname2); */ /* char seps[] = "\""; char * start_token = ::strtok(nickname_param, seps); if (start_token != NULL) { start_token++; } char * end_token = ::strtok(NULL, seps); char nickname2[300] = ""; if (end_token != NULL && end_token > start_token) { char nickname2[300] = ""; ::strncpy(nickname2, start_token, end_token - start_token); nickname2[end_token - start_token] = 0; } */ /* WideStringClass wide_nickname; wide_nickname.Convert_From(nickname2); cGameSpyAdmin::Set_Player_Nickname(wide_nickname); */