mirror of
https://github.com/electronicarts/CnC_Renegade.git
synced 2025-12-16 07:31:40 -05:00
Initial commit of Command & Conquer Renegade source code.
This commit is contained in:
654
Code/Commando/WOLGameInfo.cpp
Normal file
654
Code/Commando/WOLGameInfo.cpp
Normal file
@@ -0,0 +1,654 @@
|
||||
/*
|
||||
** 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* FILE
|
||||
* $Archive: /Commando/Code/Commando/WOLGameInfo.cpp $
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* PROGRAMMER
|
||||
* $Author: Steve_t $
|
||||
*
|
||||
* VERSION INFO
|
||||
* $Revision: 18 $
|
||||
* $Modtime: 10/31/02 4:30p $
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "WOLGameInfo.h"
|
||||
#include "GameData.h"
|
||||
#include "CNetwork.h"
|
||||
#include <WWOnline\WOLUser.h>
|
||||
#include <WWOnline\WOLChannel.h>
|
||||
#include <WWOnline\PingProfile.h>
|
||||
#include <WWLib\RealCRC.h>
|
||||
#include "modpackagemgr.h"
|
||||
|
||||
using namespace WWOnline;
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* WOLGameInfo::WOLGameInfo
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Default constructor
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
WOLGameInfo::WOLGameInfo(void) :
|
||||
mIsDataValid(false),
|
||||
mIsMapValid(true),
|
||||
mPingTime(-1)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* WOLGameInfo::WOLGameInfo
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Import information about the game.
|
||||
*
|
||||
* INPUTS
|
||||
* Game - Game to import information from.
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
WOLGameInfo::WOLGameInfo(const cGameData& theGame)
|
||||
{
|
||||
ImportFromGame(theGame);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* WOLGameInfo::WOLGameInfo
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Import information about the game from a channel.
|
||||
*
|
||||
* INPUTS
|
||||
* Channel - Channel to import game information from.
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
WOLGameInfo::WOLGameInfo(const RefPtr<ChannelData>& channel)
|
||||
{
|
||||
ImportFromChannel(channel);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* WOLGameInfo::~WOLGameInfo
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Destructor
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
WOLGameInfo::~WOLGameInfo(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* WOLGameInfo::Reset
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void WOLGameInfo::Reset(void)
|
||||
{
|
||||
mIsDataValid = false;
|
||||
mIsMapValid = true;
|
||||
|
||||
mVersion = 0;
|
||||
mGameType = 0;
|
||||
|
||||
mMapName[0] = 0;
|
||||
mModName[0] = 0;
|
||||
mTitle[0] = 0;
|
||||
|
||||
mMinPlayers = 0;
|
||||
mMaxPlayers = 0;
|
||||
mNumPlayers = 0;
|
||||
|
||||
mClanID1 = 0;
|
||||
mClanID2 = 0;
|
||||
|
||||
mIsMod = false;
|
||||
mIsLaddered = false;
|
||||
mIsPassworded = false;
|
||||
mIsQuickmatch = false;
|
||||
mIsDedicated = false;
|
||||
mIsFriendlyFire = false;
|
||||
mIsFreeWeapons = false;
|
||||
mIsTeamRemix = false;
|
||||
mIsTeamChange = false;
|
||||
mIsClanGame = false;
|
||||
mIsRepairBuildings = false;
|
||||
mIsDriverGunner = false;
|
||||
mSpawnWeapons = false;
|
||||
|
||||
mPingTime = -1;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* WOLGameInfo::ImportFromGame
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Import information about the game.
|
||||
*
|
||||
* INPUTS
|
||||
* Game - Game to import information from.
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void WOLGameInfo::ImportFromGame(const cGameData& theGame)
|
||||
{
|
||||
Reset();
|
||||
|
||||
mIsDataValid = true;
|
||||
mIsMapValid = true;
|
||||
|
||||
mVersion = theGame.Get_Version_Number();
|
||||
mGameType = theGame.Get_Game_Type();
|
||||
|
||||
strncpy(mMapName, theGame.Get_Map_Name(), MAX_TEXT_LENGTH);
|
||||
mMapName[MAX_TEXT_LENGTH - 1] = 0;
|
||||
|
||||
strncpy(mModName, theGame.Get_Mod_Name(), MAX_TEXT_LENGTH);
|
||||
mModName[MAX_TEXT_LENGTH - 1] = 0;
|
||||
|
||||
wcstombs(mTitle, theGame.Get_Game_Title(), MAX_TEXT_LENGTH);
|
||||
mTitle[MAX_TEXT_LENGTH - 1] = 0;
|
||||
|
||||
mMinPlayers = theGame.Get_Min_Players();
|
||||
mMaxPlayers = theGame.Get_Max_Players();
|
||||
mNumPlayers = theGame.Get_Current_Players();
|
||||
|
||||
mClanID1 = theGame.Get_Clan(0);
|
||||
mClanID2 = theGame.Get_Clan(1);
|
||||
|
||||
const WCHAR* password = theGame.Get_Password();
|
||||
mIsPassworded = ((password != NULL) && (wcslen(password) > 0));
|
||||
mIsLaddered = theGame.IsLaddered.Get();
|
||||
mIsQuickmatch = theGame.Is_QuickMatch_Server();
|
||||
mIsDedicated = theGame.IsDedicated.Get();
|
||||
|
||||
mIsFriendlyFire = theGame.IsFriendlyFirePermitted.Get();
|
||||
mIsFreeWeapons = theGame.IsFreeWeapons.Get();
|
||||
mIsTeamRemix = theGame.RemixTeams.Get();
|
||||
mIsTeamChange = theGame.IsTeamChangingAllowed.Get();
|
||||
mIsClanGame = theGame.IsClanGame.Get();
|
||||
|
||||
// C&C mode flags
|
||||
mIsRepairBuildings = theGame.CanRepairBuildings.Get();
|
||||
mIsDriverGunner = theGame.DriverIsAlwaysGunner.Get();
|
||||
mSpawnWeapons = theGame.SpawnWeapons.Get();
|
||||
|
||||
mIsMod = (theGame.Get_Mod_Name().Is_Empty() == false);
|
||||
|
||||
mPingTime = -1;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* WOLGameInfo::ImportFromChannel
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Import information about the game from a channel.
|
||||
*
|
||||
* INPUTS
|
||||
* Channel - Channel to import game information from.
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void WOLGameInfo::ImportFromChannel(const RefPtr<ChannelData>& channel)
|
||||
{
|
||||
Reset();
|
||||
|
||||
if (channel.IsValid() == false)
|
||||
{
|
||||
mIsDataValid = false;
|
||||
return;
|
||||
}
|
||||
|
||||
//ST - Test code
|
||||
//if (channel->GetName() != WideStringClass(L"ladtest07")) {
|
||||
// mIsDataValid = false;
|
||||
// return;
|
||||
//}
|
||||
|
||||
|
||||
const char* exInfo = channel->GetExtraInfo();
|
||||
|
||||
if ((exInfo == NULL) || (exInfo && (strlen(exInfo) != 36)))
|
||||
{
|
||||
WWDEBUG_SAY(("WOLERROR: Channel ExInfo NULL or wrong size\n"));
|
||||
mIsDataValid = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// Assume the data will be valid
|
||||
mIsDataValid = true;
|
||||
|
||||
// Extract ExInfo settings
|
||||
unsigned long fileCRC = 0;
|
||||
unsigned long version = 0;
|
||||
unsigned long clanID1 = 0;
|
||||
unsigned long clanID2 = 0;
|
||||
unsigned char gameType = 0;
|
||||
unsigned char gameFlags1 = 0;
|
||||
unsigned char gameFlags2 = 0;
|
||||
unsigned char modMapIndex = 0;
|
||||
|
||||
int count = sscanf(exInfo, "%08lX%08lX%08lX%08lX%c%c%c%c", &version, &fileCRC,
|
||||
&clanID1, &clanID2, &gameType, &gameFlags1, &gameFlags2, &modMapIndex);
|
||||
|
||||
// There should be 8 parameters in the exinfo
|
||||
if (count != 8)
|
||||
{
|
||||
WWDEBUG_SAY(("WOLERROR: Channel ExInfo malformed\n"));
|
||||
mIsDataValid = false;
|
||||
}
|
||||
|
||||
if (version != cNetwork::Get_Exe_Key()) {
|
||||
mIsDataValid = false;
|
||||
return;
|
||||
}
|
||||
|
||||
mVersion = version;
|
||||
mGameType = (cGameData::GameTypeEnum)(gameType - '0');
|
||||
|
||||
if (mGameType != cGameData::GAME_TYPE_CNC)
|
||||
{
|
||||
WWDEBUG_SAY(("WOLERROR: GameType '%d' out of range\n", mGameType));
|
||||
mIsDataValid = false;
|
||||
}
|
||||
|
||||
// Extract game flags
|
||||
mIsLaddered = (channel->GetTournament() != 0);
|
||||
mIsPassworded = channel->IsPassworded();
|
||||
|
||||
mIsDedicated = ((gameFlags1 & 0x40) == 0x40);
|
||||
mIsFriendlyFire = ((gameFlags1 & 0x10) == 0x10);
|
||||
mIsFreeWeapons = ((gameFlags1 & 0x08) == 0x08);
|
||||
mIsTeamRemix = ((gameFlags1 & 0x04) == 0x04);
|
||||
mIsTeamChange = ((gameFlags1 & 0x02) == 0x02);
|
||||
mIsClanGame = ((gameFlags1 & 0x01) == 0x01);
|
||||
|
||||
mIsMod = ((gameFlags2 & 0x40) == 0x40);
|
||||
mSpawnWeapons = ((gameFlags2 & 0x04) == 0x04);
|
||||
mIsRepairBuildings = ((gameFlags2 & 0x02) == 0x02);
|
||||
mIsDriverGunner = ((gameFlags2 & 0x01) == 0x01);
|
||||
|
||||
// Find the mod and map names from their CRC
|
||||
StringClass mapName(0, true);
|
||||
mapName = "<Unknown>";
|
||||
|
||||
StringClass modName(0, true);
|
||||
|
||||
bool got_map_name = true;
|
||||
if (mIsMod)
|
||||
{
|
||||
// Get the true index (+32 put the index into the printable range)
|
||||
modMapIndex -= 32;
|
||||
|
||||
// Find mod based on its crc and get map filename based on the index.
|
||||
if (ModPackageMgrClass::Get_Mod_Map_Name_From_CRC_Index(fileCRC, modMapIndex, &modName, &mapName) == false)
|
||||
{
|
||||
//mIsDataValid = false;
|
||||
got_map_name = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Find mod based on its crc and get map filename based on the index.
|
||||
if (ModPackageMgrClass::Get_Mod_Map_Name_From_CRC (0, fileCRC, &modName, &mapName) == false)
|
||||
{
|
||||
//mIsDataValid = false;
|
||||
got_map_name = false;
|
||||
}
|
||||
}
|
||||
|
||||
strncpy(mModName, modName, MAX_TEXT_LENGTH);
|
||||
mModName[MAX_TEXT_LENGTH - 1] = 0;
|
||||
|
||||
strncpy(mMapName, mapName, MAX_TEXT_LENGTH);
|
||||
mMapName[MAX_TEXT_LENGTH - 1] = 0;
|
||||
|
||||
mMinPlayers = channel->GetMinUsers();
|
||||
mMaxPlayers = channel->GetMaxUsers();
|
||||
mNumPlayers = channel->GetCurrentUsers();
|
||||
|
||||
// Do not count the host as a player for dedicated servers.
|
||||
if (mIsDedicated)
|
||||
{
|
||||
WWASSERT(mNumPlayers > 0);
|
||||
--mNumPlayers;
|
||||
|
||||
WWASSERT(mMaxPlayers > 0);
|
||||
--mMaxPlayers;
|
||||
}
|
||||
|
||||
mClanID1 = clanID1;
|
||||
mClanID2 = clanID2;
|
||||
|
||||
const char* topic = channel->GetTopic();
|
||||
|
||||
if (topic == NULL)
|
||||
{
|
||||
WWDEBUG_SAY(("WOLERROR: Channel Topic is NULL\n"));
|
||||
mIsDataValid = false;
|
||||
}
|
||||
|
||||
// Quickmatch settings are marked by a pipe '|' character
|
||||
mIsQuickmatch = (strchr(topic, '|') != NULL);
|
||||
|
||||
// Extract game title from topic
|
||||
unsigned int titleLength = (topic[0] - 0x20);
|
||||
WWASSERT(titleLength <= 32);
|
||||
titleLength = min<unsigned int>(titleLength, 32);
|
||||
++topic;
|
||||
|
||||
strncpy(mTitle, topic, titleLength);
|
||||
mTitle[titleLength] = 0;
|
||||
WWASSERT(strlen(mTitle) == titleLength);
|
||||
topic += titleLength;
|
||||
|
||||
unsigned int mapLength = (topic[0] - 0x20);
|
||||
WWASSERT(mapLength <= 16);
|
||||
mapLength = min<unsigned int>(mapLength, 16);
|
||||
++topic;
|
||||
|
||||
if (!got_map_name) {
|
||||
strncpy(mMapName, topic, mapLength);
|
||||
mMapName[mapLength] = 0;
|
||||
WWASSERT(strlen(mMapName) == mapLength);
|
||||
mIsMapValid = false;
|
||||
}
|
||||
topic += mapLength;
|
||||
|
||||
// Calculate ping
|
||||
PingProfile pings;
|
||||
DecodePingProfile(topic, pings);
|
||||
|
||||
const PingProfile& localPings = GetLocalPingProfile();
|
||||
mPingTime = ComparePingProfile(localPings, pings);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* WOLGameInfo::ExportToChannel
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Export game information into a channel.
|
||||
*
|
||||
* INPUTS
|
||||
* Channel - Channel to export game information into.
|
||||
*
|
||||
* RESULT
|
||||
* NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void WOLGameInfo::ExportToChannel(const RefPtr<ChannelData>& channel)
|
||||
{
|
||||
if (channel.IsValid() && mIsDataValid)
|
||||
{
|
||||
// If this is a dedicated server then the max players must be incremented
|
||||
// by one to account for the host.
|
||||
unsigned int maxPlayers = (mIsDedicated == true) ? (mMaxPlayers + 1) : mMaxPlayers;
|
||||
|
||||
// Set the channels min and max players
|
||||
channel->SetMinMaxUsers(mMinPlayers, maxPlayers);
|
||||
|
||||
// Set the tournament type
|
||||
unsigned int tournamentType = (mIsLaddered ? 1 : 0);
|
||||
channel->SetTournament(tournamentType);
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Encode ExInfo
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// For flags bit 6 must be set to keep the overall value at least a space character
|
||||
unsigned char gameFlags1 = 0x20;
|
||||
gameFlags1 |= mIsDedicated ? 0x40 : 0x00;
|
||||
gameFlags1 |= mIsFriendlyFire ? 0x10 : 0x00;
|
||||
gameFlags1 |= mIsFreeWeapons ? 0x08 : 0x00;
|
||||
gameFlags1 |= mIsTeamRemix ? 0x04 : 0x00;
|
||||
gameFlags1 |= mIsTeamChange ? 0x02 : 0x00;
|
||||
gameFlags1 |= mIsClanGame ? 0x01 : 0x00;
|
||||
|
||||
unsigned char gameFlags2 = 0x20;
|
||||
gameFlags2 |= mIsMod ? 0x40 : 0x00;
|
||||
gameFlags2 |= mSpawnWeapons ? 0x04: 0x00;
|
||||
gameFlags2 |= mIsRepairBuildings ? 0x02: 0x00;
|
||||
gameFlags2 |= mIsDriverGunner ? 0x01: 0x00;
|
||||
|
||||
// The file CRC is either the map name or the mod name depending on if
|
||||
// the mod flag is set.
|
||||
unsigned long fileCRC = 0;
|
||||
unsigned char modMapIndex = 0;
|
||||
|
||||
if (mIsMod)
|
||||
{
|
||||
ModPackageClass& package = ModPackageMgrClass::Get_Current_Package();
|
||||
fileCRC = package.Get_CRC();
|
||||
modMapIndex = package.Get_Map_Index(mMapName);
|
||||
}
|
||||
else
|
||||
{
|
||||
fileCRC = ::CRC_Stringi(mMapName);
|
||||
}
|
||||
|
||||
// Put the map index into the printable ASCII range
|
||||
modMapIndex += 32;
|
||||
|
||||
// WARNING: The channels ExInfo field has a maximum size of 40 bytes.
|
||||
char exInfo[41];
|
||||
sprintf(exInfo, "%08lX%08lX%08lX%08lX%c%c%c%c", mVersion, fileCRC,
|
||||
mClanID1, mClanID2, (0x30 + mGameType), gameFlags1, gameFlags2, modMapIndex);
|
||||
|
||||
channel->SetExtraInfo(exInfo);
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Encode topic
|
||||
//-------------------------------------------------------------------------
|
||||
unsigned int titleLength = min<unsigned int>(strlen(mTitle), 32);
|
||||
titleLength += 0x20;
|
||||
|
||||
// WARNING: The channels topic field has a maximum size of 80 bytes.
|
||||
// Ping profile and quickmatch settings are encoded in the topic in
|
||||
// addition to the the game title. The combined maximum of ALL these
|
||||
// entries MUST NEVER exceed 80 bytes.
|
||||
char topic[81];
|
||||
sprintf(topic, "%c%.32s", titleLength, mTitle);
|
||||
|
||||
//
|
||||
// Only using 61 max right now. Room for a map name maybe? ST - 10/31/2002 2:55PM
|
||||
//
|
||||
unsigned int mapLength = min<unsigned int>(strlen(mMapName), 16);
|
||||
mapLength += 0x20;
|
||||
|
||||
// WARNING: The channels topic field has a maximum size of 80 bytes.
|
||||
// Ping profile and quickmatch settings are encoded in the topic in
|
||||
// addition to the the game title. The combined maximum of ALL these
|
||||
// entries MUST NEVER exceed 80 bytes.
|
||||
char mapinfo[81];
|
||||
sprintf(mapinfo, "%c%.16s", mapLength, mMapName);
|
||||
strcat(topic, mapinfo);
|
||||
|
||||
// Add our ping profile
|
||||
const PingProfile& localPings = GetLocalPingProfile();
|
||||
EncodePingProfile(localPings, topic);
|
||||
|
||||
channel->SetTopic(topic);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* WOLGameInfo::
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* INPUTS
|
||||
*
|
||||
* RESULT
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
bool WOLGameInfo::IsValidGameChannel(const RefPtr<ChannelData>& channel)
|
||||
{
|
||||
WOLGameInfo gameInfo(channel);
|
||||
return (gameInfo.IsDataValid() && (gameInfo.mVersion == (unsigned long)cNetwork::Get_Exe_Key()));
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* WOLGameInfo::IsClanCompeting
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Check if the specified clan is competing in the game.
|
||||
*
|
||||
* INPUTS
|
||||
* Clan - ID of clan to check.
|
||||
*
|
||||
* RESULT
|
||||
* True if clan is competing.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
bool WOLGameInfo::IsClanCompeting(unsigned long clanID) const
|
||||
{
|
||||
return (mIsClanGame && (clanID != 0) && ((clanID == mClanID1) || (clanID == mClanID2)));
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* WOLGameInfo::IsClanGameOpen
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Check if the clan game is open for new clans to join.
|
||||
*
|
||||
* INPUTS
|
||||
* NONE
|
||||
*
|
||||
* RESULT
|
||||
* True if the game is open to clans.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
bool WOLGameInfo::IsClanGameOpen(void) const
|
||||
{
|
||||
return (mIsClanGame && ((0 == mClanID1) || (0 == mClanID2)));
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* NAME
|
||||
* WOLGameInfo::CanUserJoin
|
||||
*
|
||||
* DESCRIPTION
|
||||
* Check if the user is able to join this game.
|
||||
*
|
||||
* INPUTS
|
||||
* User
|
||||
*
|
||||
* RESULT
|
||||
* True if user can join this game.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
bool WOLGameInfo::CanUserJoin(const RefPtr<UserData>& user)
|
||||
{
|
||||
if (!user.IsValid() || !mIsDataValid || !mIsMapValid)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mVersion != (unsigned long)cNetwork::Get_Exe_Key())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mIsClanGame)
|
||||
{
|
||||
unsigned long userClanID = user->GetSquadID();
|
||||
return ((0 != userClanID) && (IsClanGameOpen() || IsClanCompeting(userClanID)));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
Reference in New Issue
Block a user