forked from Mirrors/openclonk
418 lines
25 KiB
C++
418 lines
25 KiB
C++
/*
|
|
* OpenClonk, http://www.openclonk.org
|
|
*
|
|
* Copyright (c) 2004-2009, RedWolf Design GmbH, http://www.clonk.de/
|
|
* Copyright (c) 2009-2016, The OpenClonk Team and contributors
|
|
*
|
|
* Distributed under the terms of the ISC license; see accompanying file
|
|
* "COPYING" for details.
|
|
*
|
|
* "Clonk" is a registered trademark of Matthes Bender, used with permission.
|
|
* See accompanying file "TRADEMARK" for details.
|
|
*
|
|
* To redistribute this file separately, substitute the full license texts
|
|
* for the above references.
|
|
*/
|
|
// permanent player information management
|
|
//
|
|
// A separate list of all local and remote player infos is held here,
|
|
// independantely of the global C4PlayerList.
|
|
// This list is used for:
|
|
// -player information to be known before actual join
|
|
// (player count for landscape width, team, color, etc.)
|
|
// -player file resource association (network mode)
|
|
// -league information to be stored for each player; even after elimination
|
|
// *-startup loader screen information; e.g. for replays
|
|
//
|
|
// * = 2do
|
|
//
|
|
// Please note that any fields added to C4PlayerInfo will be transferred to the masterserver and back.
|
|
// C4RoundResults is responsible for collecting information after player elimination.
|
|
|
|
#ifndef INC_C4PlayerInfo
|
|
#define INC_C4PlayerInfo
|
|
|
|
#include "network/C4PacketBase.h"
|
|
#include "network/C4Network2Res.h"
|
|
#include "config/C4Constants.h"
|
|
#include "lib/C4InputValidation.h"
|
|
#include "object/C4Id.h"
|
|
|
|
// information about one player at a client
|
|
class C4PlayerInfo
|
|
{
|
|
public:
|
|
// player flags
|
|
enum Flags
|
|
{
|
|
PIF_Joined = 1<<0, // player has joined the game
|
|
PIF_Removed = 1<<2, // player has been removed
|
|
PIF_HasRes = 1<<3, // pRes is set
|
|
PIF_JoinIssued = 1<<4, // flag for host to mark a player for which the join is issued
|
|
PIF_TempFile = 1<<5, // player file is temporary and to be deleted after join recreation
|
|
PIF_InScenarioFile = 1<<6, // player file is present within the scenario; res is not to be used
|
|
PIF_JoinedForSavegameOnly = 1<<7, // player file has been specified to take over a savegame player; do not join as normal player if association fails
|
|
PIF_Disconnected = 1<<8, // the player was removed because his client disconnected
|
|
PIF_Won = 1<<9, // player survived until game end (for game evaluation only)
|
|
PIF_VotedOut = 1<<10, // player was removed from the round after a successful voting
|
|
PIF_AttributesFixed= 1<<11, // player color and name aren't changed on collision
|
|
PIF_NoScenarioInit = 1<<12, // do not call ScenariInit for this player
|
|
PIF_NoEliminationCheck = 1<<13, // do not eliminate player if crew is empty
|
|
PIF_Invisible = 1<<14, // do not show in lobby and menus
|
|
|
|
// flags to be synchronized via network and saved into player info
|
|
PIF_SyncFlags = PIF_Joined | PIF_Removed | PIF_HasRes | PIF_InScenarioFile | PIF_JoinedForSavegameOnly | PIF_Disconnected | PIF_Won | PIF_VotedOut | PIF_AttributesFixed | PIF_NoScenarioInit | PIF_NoEliminationCheck | PIF_Invisible,
|
|
|
|
// flags to be copied from savegame-player for takeover
|
|
PIF_SavegameTakeoverFlags = PIF_Joined | PIF_Removed | PIF_JoinIssued | PIF_AttributesFixed | PIF_NoScenarioInit | PIF_NoEliminationCheck | PIF_Invisible
|
|
};
|
|
|
|
// player attributes used in attribute conflict resolver
|
|
enum Attribute { PLRATT_Color=0, PLRATT_Name=1, PLRATT_Last=2 };
|
|
enum AttributeLevel { PLRAL_Current, PLRAL_Original, PLRAL_Alternate };
|
|
private:
|
|
uint32_t dwFlags; // DWORD-mask of C4PlayerInfoFlags-constants
|
|
C4PlayerType eType; // user or script player
|
|
|
|
ValidatedStdCopyStrBuf<C4InVal::VAL_NameNoEmpty> sName; // player name
|
|
ValidatedStdCopyStrBuf<C4InVal::VAL_NameAllowEmpty> sForcedName; // player name if a new name is forced e.g. because the current name appeared twice
|
|
int32_t iID; // unique ID set by host
|
|
C4Network2Res::Ref pRes; // player resource to load from
|
|
C4Network2ResCore ResCore; // core of resource to load from
|
|
StdCopyStrBuf szFilename; // source filename for local players
|
|
uint32_t dwColor; // player color
|
|
uint32_t dwOriginalColor, dwAlternateColor; // original player color wish
|
|
int32_t idSavegamePlayer; // ID of associated savegame player
|
|
int32_t idTeam; // team ID
|
|
StdCopyStrBuf szAuthID; // authentication ID (for league server, will be cleared on successful join)
|
|
int32_t iInGameNumber, iInGameJoinFrame, iInGamePartFrame; // information about player in game
|
|
C4ID idExtraData; // extra data for script players
|
|
|
|
ValidatedStdCopyStrBuf<C4InVal::VAL_NameAllowEmpty> sLeagueAccount; // account name on league server
|
|
int32_t iLeagueScore; // score on league server at join time
|
|
int32_t iLeagueRank; // rank on league server at join time
|
|
int32_t iLeagueRankSymbol; // symbolization of the player's rank
|
|
int32_t iLeagueScoreProjected;// score on league server in case of win
|
|
int32_t iLeagueProjectedGain; // projected league score increase if game is won - -1 for unknown; valid values always positive
|
|
ValidatedStdCopyStrBuf<C4InVal::VAL_NameAllowEmpty> sClanTag; // clan ("team") tag
|
|
int32_t iLeaguePerformance; // script-set league performance value, only set temporarily for masterserver end reference
|
|
StdCopyStrBuf sLeagueProgressData; // level progress data as reported by league
|
|
|
|
public:
|
|
C4PlayerInfo() // construct empty
|
|
: dwFlags(0), eType(C4PT_User), iID(0), pRes(0), szFilename(), dwColor(0xffffffff),
|
|
dwOriginalColor(0xffffffff), dwAlternateColor(0), idSavegamePlayer(0), idTeam(0), iInGameNumber(-1),
|
|
iInGameJoinFrame(-1), iInGamePartFrame(-1), idExtraData(C4ID::None), sLeagueAccount(""),
|
|
iLeagueScore(0), iLeagueRank(0), iLeagueRankSymbol(0), iLeagueProjectedGain(-1), iLeaguePerformance(0) { }
|
|
|
|
void Clear(); // clear fields
|
|
|
|
bool LoadFromLocalFile(const char *szFilename); // load data from local file
|
|
bool SetAsScriptPlayer(const char *szName, uint32_t dwColor, uint32_t dwFlags, C4ID idExtra); // set as a script (AI) player
|
|
|
|
void SetJoined(int32_t iNumber); // mark as joined in current game frame
|
|
void SetJoinIssued() { dwFlags |= PIF_JoinIssued; } // mark as joined
|
|
void SetRemoved(); // mark as removed in current game frame - always marks as previously joined, too
|
|
void SetID(int32_t iToID) { iID = iToID; } // set player info ID
|
|
void SetColor(DWORD dwUseClr) { dwColor = dwUseClr; } // set color to be used
|
|
void SetOriginalColor(DWORD dwUseClr) { dwOriginalColor = dwUseClr; } // set color the player wishes to have
|
|
void SetFilename(const char *szToFilename); // set new player filename
|
|
void SetToScenarioFilename(const char *szScenFilename); // set to file within scenario; discard resource
|
|
void SetTempFile() { assert(!!szFilename); dwFlags |= PIF_TempFile; } // mark filename as temp, so it is deleted in dtor or after join
|
|
void SetTeam(int32_t idToTeam) { idTeam = idToTeam; }
|
|
void DeleteTempFile(); // delete filename if temp
|
|
void LoadResource(); // network: Load resource if present and not being loaded yet
|
|
void DiscardResource(); // delete any source resource for network player infos
|
|
void SetAssociatedSavegamePlayer(int32_t aidSavegamePlayer) // link with savegame player from restore list
|
|
{ idSavegamePlayer=aidSavegamePlayer; }
|
|
int32_t GetAssociatedSavegamePlayerID() const
|
|
{ return idSavegamePlayer; }
|
|
void SetJoinForSavegameOnly() // flag to be deleted if savegame association fails
|
|
{ dwFlags |= PIF_JoinedForSavegameOnly; }
|
|
bool IsJoinForSavegameOnly() // flag to be deleted if savegame association fails
|
|
{ return !!(dwFlags & PIF_JoinedForSavegameOnly); }
|
|
bool SetSavegameResume(C4PlayerInfo *pSavegameInfo); // take over savegame player data to do resume
|
|
void SetAuthID(const char *sznAuthID)
|
|
{ szAuthID = sznAuthID; }
|
|
void SetLeagueData(const char *szAccount, const char *szNewClanTag, int32_t iScore, int32_t iRank, int32_t iRankSymbol, const char *szProgressData)
|
|
{ sLeagueAccount.CopyValidated(szAccount); sClanTag.CopyValidated(szNewClanTag); iLeagueScore = iScore; iLeagueRank = iRank; iLeagueRankSymbol = iRankSymbol; sLeagueProgressData.Copy(szProgressData); }
|
|
void SetLeaguePerformance(int32_t iNewPerf)
|
|
{ iLeaguePerformance = iNewPerf; }
|
|
void SetLeagueProgressData(const char *szNewProgressData)
|
|
{ if (szNewProgressData) sLeagueProgressData.Copy(szNewProgressData); else sLeagueProgressData.Clear(); }
|
|
void SetVotedOut()
|
|
{ dwFlags |= PIF_VotedOut; }
|
|
void SetLeagueProjectedGain(int32_t iProjectedGain)
|
|
{ assert(iProjectedGain>=0); iLeagueProjectedGain = iProjectedGain; }
|
|
void ResetLeagueProjectedGain()
|
|
{ iLeagueProjectedGain = -1; }
|
|
void SetForcedName(const char *szNewName)
|
|
{ if (szNewName) sForcedName.CopyValidated(szNewName); else sForcedName.Clear(); }
|
|
|
|
void CompileFunc(StdCompiler *pComp);
|
|
|
|
C4PlayerType GetType() const { return eType; }
|
|
uint32_t GetColor() const { return dwColor; } // get player color
|
|
uint32_t GetLobbyColor() const;
|
|
uint32_t GetOriginalColor() const { return dwOriginalColor; } // get original player color
|
|
uint32_t GetAlternateColor() const { return dwAlternateColor; } // get secondary original player color
|
|
const char *GetName() const { return sLeagueAccount.getLength() ? sLeagueAccount.getData() : sForcedName.getLength() ? sForcedName.getData() : sName.getData(); } // get player name
|
|
const char *GetOriginalName() const { return sName.getData(); }
|
|
const char *GetForcedName() const { return sForcedName.getData(); }
|
|
StdStrBuf GetLobbyName() const; // return player name including clan/team tag if known; fallback to regular player name
|
|
const char *GetFilename() const { return szFilename.getData(); } // get filename for local games
|
|
const char *GetLocalJoinFilename() const; // get name of file to join the player from
|
|
C4Network2Res *GetRes() const { return pRes; } // get player resource for network games
|
|
bool IsRemoved() const { return !!(dwFlags & PIF_Removed); }
|
|
bool HasJoined() const { return !!(dwFlags & PIF_Joined); } // return whether player has joined
|
|
bool IsJoined() const { return HasJoined() && !(dwFlags & PIF_Removed); } // return whether player is currently in the game
|
|
bool HasJoinIssued() const { return !!(dwFlags & (PIF_Joined | PIF_JoinIssued)); } // return whether player join is in the queue already (or performed long ago, even)
|
|
bool IsUsingColor() const { return !IsRemoved() && !idSavegamePlayer; } //return whether the player is actually using the player color
|
|
bool IsUsingName() const { return !IsRemoved() && !sLeagueAccount.getLength(); } //return whether the player is actually using the player name (e.g. not if league name is used)
|
|
bool IsUsingAttribute(Attribute eAttr) const { if (eAttr == PLRATT_Color) return IsUsingColor(); else return IsUsingName(); }
|
|
bool IsUsingPlayerFile() const { return !IsRemoved(); } //return whether the player is using the file (i.e., isn't dead yet)
|
|
bool IsUsingTeam() const { return !IsRemoved(); } // whether player should be in the team list
|
|
bool IsAttributesFixed() const { return !!(dwFlags & PIF_AttributesFixed); }
|
|
bool IsInvisible() const { return !!(dwFlags & PIF_Invisible); }
|
|
bool IsScenarioInitDesired() const { return !(dwFlags & PIF_NoScenarioInit); }
|
|
C4ID GetScriptPlayerExtraID() const { return idExtraData; }
|
|
bool IsNoEliminationCheck() const { return !!(dwFlags & PIF_NoEliminationCheck); }
|
|
bool HasAutoGeneratedColor() { return dwColor != dwOriginalColor; } // whether the player got a new color assigned due to color conflict
|
|
bool HasWon() const { return !!(dwFlags & PIF_Won); }
|
|
bool HasTeamWon() const;
|
|
const char *getAuthID() const { return szAuthID.getData(); } // returns authentication ID for this player [league]
|
|
const char *getLeagueAccount() const { return sLeagueAccount.getData(); } // returns account name on league server
|
|
int32_t getLeagueScore() const { return iLeagueScore; } // returns score number on league server (0 for not assigned)
|
|
int32_t getLeagueRank() const { return iLeagueRank; } // returns rank on league server (0 for not assigned)
|
|
int32_t getLeagueRankSymbol() const { return iLeagueRankSymbol; } // returns rank symbol on league server (0 for not assigned)
|
|
int32_t getLeagueScoreProjected() const { return iLeagueScoreProjected; } // returns score on league server in case of win (0 for not assigned)
|
|
int32_t GetInGameNumber() const { return iInGameNumber; } // returns player number the player had in the game
|
|
bool IsLeagueProjectedGainValid() const { return iLeagueProjectedGain>=0; }
|
|
int32_t GetLeagueProjectedGain() const { return iLeagueProjectedGain; } // get score gain in primary league if this player's team wins
|
|
const char *GetLeagueProgressData() const { return sLeagueProgressData.getData(); }
|
|
|
|
int32_t GetID() const { return iID; } // get unique ID, if assigned
|
|
int32_t GetTeam() const { return idTeam; }
|
|
bool IsTempFile() const { return !!(dwFlags & PIF_TempFile); } // return whether filename points to temp folder
|
|
|
|
DWORD GetFlags() { return dwFlags; } // for dbg print only
|
|
|
|
void SetDisconnected() { dwFlags |= PIF_Disconnected; }
|
|
void SetWinner() { dwFlags |= PIF_Won; }
|
|
|
|
bool LoadBigIcon(C4FacetSurface &fctTarget); // load BigIcon.png of player into target facet; return false if no bigicon present or player file not yet loaded
|
|
};
|
|
|
|
// player infos for one client
|
|
// merely a list of player infos
|
|
class C4ClientPlayerInfos
|
|
{
|
|
private:
|
|
// std::vector...
|
|
int32_t iPlayerCount; // number of clients registered into the list
|
|
int32_t iPlayerCapacity; // size of pClients-array
|
|
C4PlayerInfo **ppPlayers; // array of registered client information
|
|
void GrowList(size_t iByVal); // increase list capacity
|
|
|
|
int32_t iClientID; // ID of client described by this packet
|
|
|
|
// flags for this packet
|
|
enum Flags
|
|
{
|
|
CIF_AddPlayers = 1<<0, // if set, the players are to be added to the current list (otherwise overwrite)
|
|
CIF_Updated = 1<<1, // set temporarily if changed and not transmissioned to clients (valid for host only)
|
|
CIF_Initial = 1<<2, // set for first-time player info packets
|
|
CIF_Developer = 1<<3, // set for developer hosts (by regkey); client side check only!
|
|
CIF_Removed = 1<<4 // client was removed
|
|
};
|
|
uint32_t dwFlags; // bit mask of the above flags
|
|
|
|
public:
|
|
C4ClientPlayerInfos(const char *szJoinFilenames=NULL, bool fAdd=false, C4PlayerInfo *pAddInfo=NULL); // ctor; sets local data (or makes an add-player-packet if filename is given) if par is true
|
|
C4ClientPlayerInfos(const C4ClientPlayerInfos &rCopy); // copy ctor
|
|
~C4ClientPlayerInfos() { Clear(); } // dtor
|
|
|
|
C4ClientPlayerInfos &operator = (const C4ClientPlayerInfos &rCopy);
|
|
|
|
void Clear(); // del all players
|
|
void GrabMergeFrom(C4ClientPlayerInfos &rFrom); // merge existing player info packed into this one - empties pFrom!
|
|
void AddInfo(C4PlayerInfo *pAddInfo); // add info to list
|
|
void RemoveIndexedInfo(int32_t iAtIndex); // remove info from list (delete it)
|
|
void RemoveInfo(int32_t idPlr); // remove info from list (delete it)
|
|
|
|
// update-flag
|
|
void SetUpdated() { dwFlags |= CIF_Updated; }
|
|
bool IsUpdated() { return !!(dwFlags & CIF_Updated); }
|
|
void ResetUpdated() { dwFlags &= ~CIF_Updated; }
|
|
void SetAdd() { dwFlags |= CIF_AddPlayers; }
|
|
void ResetAdd() { dwFlags &= ~CIF_AddPlayers; }
|
|
|
|
// query functions
|
|
int32_t GetPlayerCount() const { return iPlayerCount; } // get number of player infos available
|
|
int32_t GetFlaggedPlayerCount(DWORD dwFlag) const; // get number of player infos with any of the given flags set
|
|
C4PlayerInfo *GetPlayerInfo(int32_t iIndex) const; // get indexed player info
|
|
C4PlayerInfo *GetPlayerInfo(int32_t iIndex, C4PlayerType eType) const; // get indexed player info of given type
|
|
C4PlayerInfo *GetPlayerInfoByID(int32_t id) const; // get player info by unique player ID
|
|
C4PlayerInfo *GetPlayerInfoByRes(int32_t idResID) const; // get player info by resource ID
|
|
int32_t GetClientID() const { return iClientID; } // get target client ID
|
|
bool HasUnjoinedPlayers() const; // check all players and return whether one of them didn't join
|
|
int32_t GetJoinedPlayerCount() const; // return number of players that are IsJoined()
|
|
bool IsAddPacket() const { return !!(dwFlags & CIF_AddPlayers); } // return whether players are to be added to the current list (otherwise overwrite)
|
|
bool IsInitialPacket() const { return !!(dwFlags & CIF_Initial); } // returns whether this packet was sent as the first local-join packet
|
|
bool IsDeveloperPacket() const { return !!(dwFlags & CIF_Developer); } // returns whether packet was created by a developer host - client side check only!
|
|
|
|
// network: Load all resources connected with the players that are not being loaded yet
|
|
void LoadResources();
|
|
|
|
// pack/unpack functions
|
|
void CompileFunc(StdCompiler *pComp);
|
|
};
|
|
|
|
// * PID_PlayerInfoUpdRequest
|
|
// packet containing information about one or more joined players at a client
|
|
// or about lobby player-info updates
|
|
class C4PacketPlayerInfoUpdRequest : public C4PacketBase
|
|
{
|
|
public:
|
|
C4ClientPlayerInfos Info; // info for clients to be joined
|
|
|
|
C4PacketPlayerInfoUpdRequest() : Info() { } // std ctor
|
|
C4PacketPlayerInfoUpdRequest(const char *szFilenames, bool fAdd) // ctor
|
|
: Info(szFilenames, fAdd) { };
|
|
|
|
C4PacketPlayerInfoUpdRequest(const C4ClientPlayerInfos &rInfo) : Info(rInfo) {} // ctor
|
|
|
|
virtual void CompileFunc(StdCompiler *pComp);
|
|
};
|
|
|
|
// * PID_PlayerInfoUpd
|
|
// packet containing information about one or more (updated) players at a client
|
|
class C4PacketPlayerInfo : public C4PacketBase
|
|
{
|
|
public:
|
|
C4ClientPlayerInfos Info; // info for clients to be updated
|
|
bool fIsRecreationInfo; // if set, this info packet describes savegame recreation players
|
|
|
|
C4PacketPlayerInfo() : Info(), fIsRecreationInfo(false) { } // std ctor
|
|
C4PacketPlayerInfo(const C4ClientPlayerInfos &rCopyInfos, bool fRecreationPlayers) // ctor
|
|
: Info(rCopyInfos), fIsRecreationInfo(fRecreationPlayers) { };
|
|
|
|
virtual void CompileFunc(StdCompiler *pComp);
|
|
};
|
|
|
|
// player info list
|
|
// contains player info packets for all known clients and self
|
|
class C4PlayerInfoList
|
|
{
|
|
private:
|
|
// std::vector...
|
|
int32_t iClientCount; // number of clients registered into the list
|
|
int32_t iClientCapacity; // size of pClients-array
|
|
C4ClientPlayerInfos **ppClients; // array of registered client information
|
|
void GrowList(size_t iByVal); // increase list capacity
|
|
|
|
int32_t iLastPlayerID; // last ID given to a player
|
|
|
|
enum MatchingLevel { PML_PlrFileName=0, PML_PlrName, PML_PrefColor, PML_Any };
|
|
|
|
public:
|
|
C4PlayerInfoList(); // ctor
|
|
C4PlayerInfoList(const C4PlayerInfoList &rCpy);
|
|
~C4PlayerInfoList() { Clear(); } // dtor
|
|
C4PlayerInfoList &operator = (const C4PlayerInfoList &rCpy);
|
|
void Clear(); // clear list
|
|
|
|
// forwards player info update request to the appropriate handler
|
|
bool DoPlayerInfoUpdate(C4ClientPlayerInfos *pUpdate);
|
|
|
|
// performs a local player join for the given player file(s)
|
|
bool DoLocalNonNetworkPlayerJoin(const char *szPlayerFile);
|
|
bool DoLocalNonNetworkPlayerInfoUpdate(C4ClientPlayerInfos *pUpdate);
|
|
|
|
// sets any unset IDs (host/standalone only); also removes players that would exceed the maximum player limit
|
|
// returns whether any players remain
|
|
bool AssignPlayerIDs(C4ClientPlayerInfos *pNewClientInfo);
|
|
|
|
// assign any unset teams (host/standalone only) - fByHost determines whether packet was sent by host
|
|
void AssignTeams(C4ClientPlayerInfos *pNewClientInfo, bool fByHost);
|
|
|
|
// generate teams used by the player info list if they do not exist and auto generated teams are enabled
|
|
// used for replays
|
|
void RecheckAutoGeneratedTeams();
|
|
|
|
// add info for client; overwriting or appending to existing info if necessary
|
|
// this takes over the pNewClientInfo ptr, and may invalidate (delete) it!
|
|
// the pointer to the info structure as it is valid in the list is returned
|
|
// when infos are added, unset IDs will automatically be assigned (should happen for host only!)
|
|
C4ClientPlayerInfos *AddInfo(C4ClientPlayerInfos *pNewClientInfo);
|
|
|
|
// resolve any color conflicts in self AND given (optional) packet. Sets Updated-flags.
|
|
void ResolvePlayerAttributeConflicts(C4ClientPlayerInfos *pSecPacket);
|
|
|
|
// do color updates: Savegame color assignment; team colors; duplicate attribute check
|
|
void UpdatePlayerAttributes(C4ClientPlayerInfos *pForInfo, bool fResolveConflicts);
|
|
void UpdatePlayerAttributes();
|
|
|
|
// query functions
|
|
int32_t GetInfoCount() const { return iClientCount; } // get number of registered client infos
|
|
C4ClientPlayerInfos *GetIndexedInfo(int32_t iIndex) const // get client player infos by indexed
|
|
{ return (ppClients && Inside<int32_t>(iIndex, 0, iClientCount-1)) ? ppClients[iIndex] : NULL; }
|
|
C4ClientPlayerInfos **GetInfoPtrByClientID(int32_t iClientID) const; // get info for a specific client ID
|
|
C4ClientPlayerInfos *GetInfoByClientID(int32_t iClientID) const
|
|
{ C4ClientPlayerInfos **ppNfo = GetInfoPtrByClientID(iClientID); return ppNfo ? *ppNfo : NULL; }
|
|
C4PlayerInfo *GetPlayerInfoByIndex(int32_t index) const; // get player info by index (for running through all players regardless of clients or ids)
|
|
C4PlayerInfo *GetPlayerInfoByID(int32_t id) const; // get player info by unique player ID
|
|
C4PlayerInfo *GetPlayerInfoByID(int32_t id, int32_t *pidClient) const; // get player info by unique player ID, and assign associated client
|
|
C4ClientPlayerInfos *GetClientInfoByPlayerID(int32_t id) const; // get client info that contains a specific player
|
|
C4PlayerInfo *GetPlayerInfoBySavegameID(int32_t id) const;// get player info by savegame association ID
|
|
C4PlayerInfo *GetNextPlayerInfoByID(int32_t id) const; // get player info with smallest ID > given id
|
|
C4PlayerInfo *GetActivePlayerInfoByName(const char *szName); // find info by name (case insensitive)
|
|
int32_t GetPlayerCount() const; // get number of players on all clients
|
|
int32_t GetJoinIssuedPlayerCount() const; // get number of players with PIF_JoinIssued-flag set
|
|
int32_t GetActivePlayerCount(bool fCountInvisible) const; // get number of players that have not been removed
|
|
StdStrBuf GetActivePlayerNames(bool fCountInvisible, int32_t iAtClientID=-1) const; // get a comma-separated list of players that have not been removed yet
|
|
int32_t GetActiveScriptPlayerCount(bool fCountSavegameResumes, bool fCountInvisible) const; // get number of script players that have not been removed
|
|
C4PlayerInfo *GetPrimaryInfoByClientID(int32_t iClientID) const
|
|
{
|
|
C4ClientPlayerInfos *pInfoPkt = GetInfoByClientID(iClientID);
|
|
if (!pInfoPkt) return NULL;
|
|
return pInfoPkt->GetPlayerInfo(0);
|
|
}
|
|
C4PlayerInfo *FindSavegameResumePlayerInfo(const C4PlayerInfo *pMatchInfo, MatchingLevel mlMatchStart, MatchingLevel mlMatchEnd) const; // automatic savegame player association: Associate by name (or prefcolor, if none matches)
|
|
bool HasSameTeamPlayers(int32_t iClient1, int32_t iClient2) const; // check all active players; return true if two of them on different clients are in the same team
|
|
C4PlayerInfo *FindUnassociatedRestoreInfo(const C4PlayerInfoList &rRestoreInfoList); // find a player in the given list that has not been associated by a player in this list
|
|
|
|
void RemoveInfo(C4ClientPlayerInfos **ppRemoveInfo) // remove client info given by direct ptr into list
|
|
{ *ppRemoveInfo = ppClients[--iClientCount]; /* maybe redundant self-assignment; no vector shrink */ }
|
|
|
|
public:
|
|
bool Load(C4Group &hGroup, const char *szFromFile, class C4LangStringTable *pLang=NULL); // clear self and load from group file
|
|
bool Save(C4Group &hGroup, const char *szToFile); // save to group file
|
|
|
|
// external ID counter manipulation used by C4Game
|
|
void SetIDCounter(int32_t idNewCounter) { iLastPlayerID = idNewCounter; }
|
|
int32_t GetIDCounter() { return iLastPlayerID; }
|
|
void FixIDCounter(); // make sure ID counter is same as largest info
|
|
|
|
// game interaction
|
|
bool InitLocal(); // put locally joining players into list (non-network)
|
|
bool LocalJoinUnjoinedPlayersInQueue(); // join all unjoined players to local input queue
|
|
int32_t GetStartupCount(); // get number of players already joined and to be joined
|
|
void CreateRestoreInfosForJoinedScriptPlayers(C4PlayerInfoList &rSavegamePlayers); // create matching script player joins for all script playeers in restore info
|
|
bool RecreatePlayers(C4ValueNumbers *); // directly join all players whose join-flag is set
|
|
bool RecreatePlayerFiles(); // update player source files
|
|
bool RestoreSavegameInfos(C4PlayerInfoList &rSavegamePlayers); // recreate this list from rSavegamePlayers for host/single games; just merge associated infos
|
|
bool SetAsRestoreInfos(C4PlayerInfoList &rFromPlayers, bool fSaveUserPlrs, bool fSaveScriptPlrs, bool fSetUserPlrRefToLocalGroup, bool fSetScriptPlrRefToLocalGroup); // copy all joined players from player list
|
|
void RemoveUnassociatedPlayers(C4PlayerInfoList &rSavegamePlayers); // remove all savegame players that are not associated to this list from the game
|
|
int32_t GetFreePlayerSlotCount(); // get number of players that may still join
|
|
void ResetLeagueProjectedGain(bool fSetUpdated); // reset known projected gains for all players (to be updated by league again)
|
|
|
|
// network: Load all resources connected with the players that are not being loaded yet
|
|
void LoadResources();
|
|
|
|
// compiler
|
|
void CompileFunc(StdCompiler *pComp);
|
|
};
|
|
|
|
#endif // INC_C4PlayerInfo
|