1/*
2 * LegacyClonk
3 *
4 * Copyright (c) RedWolf Design
5 * Copyright (c) 2004, Sven2
6 * Copyright (c) 2017-2021, The LegacyClonk Team and contributors
7 *
8 * Distributed under the terms of the ISC license; see accompanying file
9 * "COPYING" for details.
10 *
11 * "Clonk" is a registered trademark of Matthes Bender, used with permission.
12 * See accompanying file "TRADEMARK" for details.
13 *
14 * To redistribute this file separately, substitute the full license texts
15 * for the above references.
16 */
17
18// permanent player information management
19//
20// A separate list of all local and remote player infos is held here,
21// independently of the global C4PlayerList.
22// This list is used for:
23// -player information to be known before actual join
24// (player count for landscape width, team, color, etc.)
25// -player file ressource association (network mode)
26// -league information to be stored for each player; even after elimination
27// *-startup loader screen information; e.g. for replays
28//
29// * = 2do
30//
31// Please note that any fields added to C4PlayerInfo will be transferred to the masterserver and back.
32// C4RoundResults is responsible for collecting information after player elimination.
33
34#pragma once
35
36#include "C4ForwardDeclarations.h"
37#include "C4Id.h"
38#include "C4PacketBase.h"
39#include "C4Network2Res.h"
40#include "C4Constants.h"
41#include "C4InputValidation.h"
42
43// class predefs
44class C4PlayerInfo;
45class C4ClientPlayerInfos;
46class C4PlayerInfoList;
47
48// information about one player at a client
49class C4PlayerInfo
50{
51public:
52 // player flags
53 enum Flags
54 {
55 PIF_Joined = 1 << 0, // player has joined the game
56 PIF_Removed = 1 << 2, // player has been removed
57 PIF_HasRes = 1 << 3, // pRes is set
58 PIF_JoinIssued = 1 << 4, // flag for host to mark a player for which the join is issued
59 PIF_TempFile = 1 << 5, // player file is temporary and to be deleted after join recreation
60 PIF_InScenarioFile = 1 << 6, // player file is present within the scenario; res is not to be used
61 PIF_JoinedForSavegameOnly = 1 << 7, // player file has been specified to take over a savegame player; do not join as normal player if association fails
62 PIF_Disconnected = 1 << 8, // the player was removed because his client disconnected
63 PIF_Won = 1 << 9, // player survived until game end (for game evaluation only)
64 PIF_VotedOut = 1 << 10, // player was removed from the round after a successful voting
65 PIF_AttributesFixed = 1 << 11, // player color and name aren't changed on collision
66 PIF_NoScenarioInit = 1 << 12, // do not call ScenariInit for this player
67 PIF_NoEliminationCheck = 1 << 13, // do not eliminate player if crew is empty
68 PIF_Invisible = 1 << 14, // do not show in lobby and menus
69
70 // flags to be synchronized via network and saved into player info
71 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,
72
73 // flags to be copied from savegame-player for takeover
74 PIF_SavegameTakeoverFlags = PIF_Joined | PIF_Removed | PIF_JoinIssued | PIF_AttributesFixed | PIF_NoScenarioInit | PIF_NoEliminationCheck | PIF_Invisible,
75 };
76
77 // player attributes used in attribute conflict resolver
78 enum Attribute { PLRATT_Color = 0, PLRATT_Name = 1, PLRATT_Last = 2 };
79 enum AttributeLevel { PLRAL_Current, PLRAL_Original, PLRAL_Alternate };
80
81private:
82 uint32_t dwFlags; // bitmask of C4PlayerInfoFlags-constants
83 C4PlayerType eType; // user or script player
84
85 ValidatedStdStrBuf<C4InVal::VAL_NameNoEmpty> sName; // player name
86 ValidatedStdStrBuf<C4InVal::VAL_NameAllowEmpty> sForcedName; // player name if a new name is forced e.g. because the current name appeared twice
87 int32_t iID; // unique ID set by host
88 C4Network2Res::Ref pRes; // player resource to load from
89 C4Network2ResCore ResCore; // core of resource to load from
90 StdStrBuf szFilename; // source filename for local players
91 uint32_t dwColor; // player color
92 uint32_t dwOriginalColor, dwAlternateColor; // original player color wish
93 int32_t idSavegamePlayer; // ID of associated savegame player
94 int32_t idTeam; // team ID
95 StdStrBuf szAuthID; // authentication ID (for league server, will be cleared on successful join)
96 int32_t iInGameNumber, iInGameJoinFrame, iInGamePartFrame; // information about player in game
97 C4ID idExtraData; // extra data for script players
98
99 ValidatedStdStrBuf<C4InVal::VAL_NameAllowEmpty> sLeagueAccount; // account name on league server
100 int32_t iLeagueScore; // score on league server at join time
101 int32_t iLeagueRank; // rank on league server at join time
102 int32_t iLeagueRankSymbol; // symbolization of the player's rank
103 int32_t iLeagueProjectedGain; // projected league score increase if game is won - -1 for unknown; valid values always positive
104 ValidatedStdStrBuf<C4InVal::VAL_NameAllowEmpty> sClanTag; // clan ("team") tag
105 int32_t iLeaguePerformance; // script-set league performance value, only set temporarily for masterserver end reference
106 StdStrBuf sLeagueProgressData; // level progress data as reported by league
107
108public:
109 C4PlayerInfo() // construct empty
110 : dwFlags(0), iID(0), pRes(nullptr), dwColor(0xffffff), sLeagueAccount(""),
111 dwOriginalColor(0xffffff), dwAlternateColor(0), idSavegamePlayer(0), idTeam(0),
112 iLeagueScore(0), iLeagueRank(0), iLeagueRankSymbol(0), iLeagueProjectedGain(-1), iLeaguePerformance(0),
113 iInGameNumber(-1), iInGameJoinFrame(-1), iInGamePartFrame(-1), eType(C4PT_User), idExtraData(C4ID_None) {}
114
115 void Clear(); // clear fields
116
117 bool LoadFromLocalFile(const char *szFilename); // load data from local file
118 bool SetAsScriptPlayer(const char *szName, uint32_t dwColor, uint32_t dwFlags, C4ID idExtra); // set as a script (AI) player
119
120 void SetJoined(int32_t iNumber); // mark as joined in current game frame
121 void SetJoinIssued() { dwFlags |= PIF_JoinIssued; } // mark as joined
122 void SetRemoved(); // mark as removed in current game frame - always marks as previously joined, too
123 void SetID(int32_t iToID) { iID = iToID; } // set player info ID
124 void SetColor(uint32_t dwUseClr) { dwColor = dwUseClr; } // set color to be used
125 void SetOriginalColor(uint32_t dwUseClr) { dwOriginalColor = dwUseClr; } // set color the player wishes to have
126 void SetFilename(const char *szToFilename); // set new player filename
127 void SetTempFile() { assert(!!szFilename); dwFlags |= PIF_TempFile; } // mark filename as temp, so it is deleted in dtor or after join
128 void SetTeam(int32_t idToTeam) { idTeam = idToTeam; }
129 void DeleteTempFile(); // delete filename if temp
130 void LoadResource(); // network: Load resource if present and not being loaded yet
131 void DiscardResource(); // delete any source ressource for network player infos
132
133 void SetAssociatedSavegamePlayer(int32_t aidSavegamePlayer) // link with savegame player from restore list
134 {
135 idSavegamePlayer = aidSavegamePlayer;
136 }
137
138 int32_t GetAssociatedSavegamePlayerID() const
139 {
140 return idSavegamePlayer;
141 }
142
143 bool IsJoinForSavegameOnly() // flag to be deleted if savegame association fails
144 {
145 return !!(dwFlags & PIF_JoinedForSavegameOnly);
146 }
147
148 bool SetSavegameResume(C4PlayerInfo *pSavegameInfo); // take over savegame player data to do resume
149
150 void SetAuthID(const char *sznAuthID)
151 {
152 szAuthID = sznAuthID;
153 }
154
155 void SetLeagueData(const char *szAccount, const char *szNewClanTag, int32_t iScore, int32_t iRank, int32_t iRankSymbol, const char *szProgressData)
156 {
157 sLeagueAccount.CopyValidated(szFromVal: szAccount); sClanTag.CopyValidated(szFromVal: szNewClanTag); iLeagueScore = iScore; iLeagueRank = iRank; iLeagueRankSymbol = iRankSymbol; sLeagueProgressData.Copy(pnData: szProgressData);
158 }
159
160 void SetLeaguePerformance(int32_t iNewPerf)
161 {
162 iLeaguePerformance = iNewPerf;
163 }
164
165 void SetLeagueProgressData(const char *szNewProgressData)
166 {
167 if (szNewProgressData) sLeagueProgressData.Copy(pnData: szNewProgressData); else sLeagueProgressData.Clear();
168 }
169
170 void SetVotedOut()
171 {
172 dwFlags |= PIF_VotedOut;
173 }
174
175 void SetLeagueProjectedGain(int32_t iProjectedGain)
176 {
177 assert(iProjectedGain >= 0); iLeagueProjectedGain = iProjectedGain;
178 }
179
180 void ResetLeagueProjectedGain()
181 {
182 iLeagueProjectedGain = -1;
183 }
184
185 void SetForcedName(const char *szNewName)
186 {
187 if (szNewName) sForcedName.CopyValidated(szFromVal: szNewName); else sForcedName.Clear();
188 }
189
190 void CompileFunc(StdCompiler *pComp);
191
192 C4PlayerType GetType() const { return eType; }
193 uint32_t GetColor() const { return dwColor; } // get player color
194 uint32_t GetLobbyColor() const;
195 uint32_t GetOriginalColor() const { return dwOriginalColor; } // get original player color
196 uint32_t GetAlternateColor() const { return dwAlternateColor; } // get secondary original player color
197 const char *GetName() const { return sLeagueAccount.getLength() ? sLeagueAccount.getData() : sForcedName.getLength() ? sForcedName.getData() : sName.getData(); } // get player name
198 const char *GetOriginalName() const { return sName.getData(); }
199 const char *GetForcedName() const { return sForcedName.getData(); }
200 StdStrBuf GetLobbyName() const; // return player name including clan/team tag if known; fallback to regular player name
201 const char *GetFilename() const { return szFilename.getData(); } // get filename for local games
202 const char *GetLocalJoinFilename() const; // get name of file to join the player from
203 C4Network2Res *GetRes() const { return pRes; } // get player ressource for network games
204 bool IsRemoved() const { return !!(dwFlags & PIF_Removed); }
205 bool HasJoined() const { return !!(dwFlags & PIF_Joined); } // return whether player has joined
206 bool IsJoined() const { return HasJoined() && !(dwFlags & PIF_Removed); } // return whether player is currently in the game
207 bool HasJoinIssued() const { return !!(dwFlags & (PIF_Joined | PIF_JoinIssued)); } // return whether player join is in the queue already (or performed long ago, even)
208 bool IsUsingColor() const { return !IsRemoved() && !idSavegamePlayer; } // return whether the player is actually using the player color
209 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)
210 bool IsUsingAttribute(Attribute eAttr) const { if (eAttr == PLRATT_Color) return IsUsingColor(); else return IsUsingName(); }
211 bool IsUsingPlayerFile() const { return !IsRemoved(); } // return whether the player is using the file (i.e., isn't dead yet)
212 bool IsUsingTeam() const { return !IsRemoved(); } // whether player should be in the team list
213 bool IsAttributesFixed() const { return !!(dwFlags & PIF_AttributesFixed); }
214 bool IsInvisible() const { return !!(dwFlags & PIF_Invisible); }
215 bool IsScenarioInitDesired() const { return !(dwFlags & PIF_NoScenarioInit); }
216 C4ID GetScriptPlayerExtraID() const { return idExtraData; }
217 bool IsNoEliminationCheck() const { return !!(dwFlags & PIF_NoEliminationCheck); }
218 bool HasAutoGeneratedColor() { return dwColor != dwOriginalColor; } // whether the player got a new color assigned due to color conflict
219 bool HasWon() const { return !!(dwFlags & PIF_Won); }
220 bool HasTeamWon() const;
221 const char *getAuthID() const { return szAuthID.getData(); } // returns authentication ID for this player [league]
222 const char *getLeagueAccount() const { return sLeagueAccount.getData(); } // returns account name on league server
223 int32_t getLeagueScore() const { return iLeagueScore; } // returns score number on league server (0 for not assigned)
224 int32_t getLeagueRankSymbol() const { return iLeagueRankSymbol; } // returns rank symbol on league server (0 for not assigned)
225 int32_t GetInGameNumber() const { return iInGameNumber; } // returns player number the player had in the game
226 bool IsLeagueProjectedGainValid() const { return iLeagueProjectedGain >= 0; }
227 int32_t GetLeagueProjectedGain() const { return iLeagueProjectedGain; } // get score gain in primary league if this player's team wins
228 const char *GetLeagueProgressData() const { return sLeagueProgressData.getData(); }
229
230 int32_t GetID() const { return iID; } // get unique ID, if assigned
231 int32_t GetTeam() const { return idTeam; }
232 bool IsTempFile() const { return !!(dwFlags & PIF_TempFile); } // return whether filename points to temp folder
233
234 uint32_t GetFlags() { return dwFlags; } // for dbg print only
235
236 void SetDisconnected() { dwFlags |= PIF_Disconnected; }
237 void SetWinner() { dwFlags |= PIF_Won; }
238
239 bool LoadBigIcon(C4FacetExSurface &fctTarget); // load BigIcon.png of player into target facet; return false if no bigicon present or player file not yet loaded
240};
241
242// player infos for one client
243// merely a list of player infos
244class C4ClientPlayerInfos
245{
246private:
247 // std::vector...
248 int32_t iPlayerCount; // number of clients registered into the list
249 int32_t iPlayerCapacity; // size of pClients-array
250 C4PlayerInfo **ppPlayers; // array of registered client information
251 void GrowList(size_t iByVal); // increase list capacity
252
253 int32_t iClientID; // ID of client described by this packet
254
255 // flags for this packet
256 enum Flags
257 {
258 CIF_AddPlayers = 1 << 0, // if set, the players are to be added to the current list (otherwise overwrite)
259 CIF_Updated = 1 << 1, // set temporarily if changed and not transmissioned to clients (valid for host only)
260 CIF_Initial = 1 << 2, // set for first-time player info packets
261 };
262 uint32_t dwFlags; // bit mask of the above flags
263
264public:
265 C4ClientPlayerInfos(const char *szJoinFilenames = nullptr, bool fAdd = false, C4PlayerInfo *pAddInfo = nullptr); // sets local data (or makes an add-player-packet if filename is given) if par is true
266 C4ClientPlayerInfos(const C4ClientPlayerInfos &rCopy);
267 ~C4ClientPlayerInfos() { Clear(); }
268
269 C4ClientPlayerInfos &operator=(const C4ClientPlayerInfos &rCopy);
270
271 void Clear(); // del all players
272 void GrabMergeFrom(C4ClientPlayerInfos &rFrom); // merge existing player info packed into this one - empties pFrom!
273 void AddInfo(C4PlayerInfo *pAddInfo); // add info to list
274 void RemoveIndexedInfo(int32_t iAtIndex); // remove info from list (delete it)
275 void RemoveInfo(int32_t idPlr); // remove info from list (delete it)
276
277 // update-flag
278 void SetUpdated() { dwFlags |= CIF_Updated; }
279 bool IsUpdated() { return !!(dwFlags & CIF_Updated); }
280 void ResetUpdated() { dwFlags &= ~CIF_Updated; }
281 void ResetAdd() { dwFlags &= ~CIF_AddPlayers; }
282
283 // query functions
284 int32_t GetPlayerCount() const { return iPlayerCount; } // get number of player infos available
285 C4PlayerInfo *GetPlayerInfo(int32_t iIndex) const; // get indexed player info
286 C4PlayerInfo *GetPlayerInfo(int32_t iIndex, C4PlayerType eType) const; // get indexed player info of given type
287 C4PlayerInfo *GetPlayerInfoByID(int32_t id) const; // get player info by unique player ID
288 C4PlayerInfo *GetPlayerInfoByRes(int32_t idResID) const; // get player info by ressource ID
289 int32_t GetClientID() const { return iClientID; } // get target client ID
290 bool HasUnjoinedPlayers() const; // check all players and return whether one of them didn't join
291 int32_t GetJoinedPlayerCount() const; // return number of players that are IsJoined()
292 bool IsAddPacket() const { return !!(dwFlags & CIF_AddPlayers); } // return whether players are to be added to the current list (otherwise overwrite)
293 bool IsInitialPacket() const { return !!(dwFlags & CIF_Initial); } // returns whether this packet was sent as the first local-join packet
294
295 // network: Load all resources connected with the players that are not being loaded yet
296 void LoadResources();
297
298 // pack/unpack functions
299 void CompileFunc(StdCompiler *pComp);
300};
301
302// * PID_PlayerInfoUpdRequest
303// packet containing information about one or more joined players at a client
304// or about lobby player-info updates
305class C4PacketPlayerInfoUpdRequest : public C4PacketBase
306{
307public:
308 C4ClientPlayerInfos Info; // info for clients to be joined
309
310 C4PacketPlayerInfoUpdRequest() : Info() {}
311 C4PacketPlayerInfoUpdRequest(const char *szFilenames, bool fAdd)
312 : Info(szFilenames, fAdd) {}
313
314 C4PacketPlayerInfoUpdRequest(const C4ClientPlayerInfos &rInfo) : Info(rInfo) {}
315
316 virtual void CompileFunc(StdCompiler *pComp) override;
317};
318
319// player info list
320// contains player info packets for all known clients and self
321class C4PlayerInfoList
322{
323private:
324 // std::vector...
325 int32_t iClientCount; // number of clients registered into the list
326 int32_t iClientCapacity; // size of pClients-array
327 C4ClientPlayerInfos **ppClients; // array of registered client information
328 void GrowList(size_t iByVal); // increase list capacity
329
330 int32_t iLastPlayerID; // last ID given to a player
331
332 enum MatchingLevel { PML_PlrFileName = 0, PML_PlrName, PML_PrefColor, PML_Any };
333
334public:
335 C4PlayerInfoList();
336 C4PlayerInfoList(const C4PlayerInfoList &) = delete;
337 ~C4PlayerInfoList() { Clear(); }
338 C4PlayerInfoList &operator=(const C4PlayerInfoList &rCpy);
339 void Clear(); // clear list
340
341 // forwards player info update request to the appropriate handler
342 bool DoPlayerInfoUpdate(C4ClientPlayerInfos *pUpdate);
343
344 // performs a local player join for the given player file(s)
345 bool DoLocalNonNetworkPlayerJoin(const char *szPlayerFile);
346 bool DoLocalNonNetworkPlayerInfoUpdate(C4ClientPlayerInfos *pUpdate);
347
348 // sets any unset IDs (host/standalone only); also removes players that would exceed the maximum player limit
349 // returns whether any players remain
350 bool AssignPlayerIDs(C4ClientPlayerInfos *pNewClientInfo);
351
352 // assign any unset teams (host/standalone only) - fByHost determines whether packet was sent by host
353 void AssignTeams(C4ClientPlayerInfos *pNewClientInfo, bool fByHost);
354
355 // generate teams used by the player info list if they do not exist and auto generated teams are enabled
356 // used for replays
357 void RecheckAutoGeneratedTeams();
358
359 // add info for client; overwriting or appending to existing info if necessary
360 // this takes over the pNewClientInfo ptr, and may invalidate (delete) it!
361 // the pointer to the info structure as it is valid in the list is returned
362 // when infos are added, unset IDs will automatically be assigned (should happen for host only!)
363 C4ClientPlayerInfos *AddInfo(C4ClientPlayerInfos *pNewClientInfo);
364
365 // resolve any color conflicts in self AND given (optional) packet. Sets Updated-flags.
366 void ResolvePlayerAttributeConflicts(C4ClientPlayerInfos *pSecPacket);
367
368 // do color updates: Savegame color assignment; team colors; duplicate attribute check
369 void UpdatePlayerAttributes(C4ClientPlayerInfos *pForInfo, bool fResolveConflicts);
370 void UpdatePlayerAttributes();
371
372 // query functions
373 int32_t GetInfoCount() const { return iClientCount; } // get number of registered client infos
374
375 C4ClientPlayerInfos *GetIndexedInfo(int32_t iIndex) const // get client player infos by indexed
376 {
377 return (ppClients && Inside<int32_t>(ival: iIndex, lbound: 0, rbound: iClientCount - 1)) ? ppClients[iIndex] : nullptr;
378 }
379
380 C4ClientPlayerInfos **GetInfoPtrByClientID(int32_t iClientID) const; // get info for a specific client ID
381
382 C4ClientPlayerInfos *GetInfoByClientID(int32_t iClientID) const
383 {
384 C4ClientPlayerInfos **ppNfo = GetInfoPtrByClientID(iClientID); return ppNfo ? *ppNfo : nullptr;
385 }
386
387 C4PlayerInfo *GetPlayerInfoByIndex(int32_t index) const; // get player info by index (for running through all players regardless of clients or ids)
388 C4PlayerInfo *GetPlayerInfoByID(int32_t id) const; // get player info by unique player ID
389 C4PlayerInfo *GetPlayerInfoByID(int32_t id, int32_t *pidClient) const; // get player info by unique player ID, and assign associated client
390 C4ClientPlayerInfos *GetClientInfoByPlayerID(int32_t id) const; // get client info that contains a specific player
391 C4PlayerInfo *GetPlayerInfoBySavegameID(int32_t id) const; // get player info by savegame association ID
392 C4PlayerInfo *GetNextPlayerInfoByID(int32_t id) const; // get player info with smallest ID > given id
393 C4PlayerInfo *GetActivePlayerInfoByName(const char *szName); // find info by name (case insensitive)
394 int32_t GetPlayerCount() const; // get number of players on all clients
395 int32_t GetJoinIssuedPlayerCount() const; // get number of players with PIF_JoinIssued-flag set
396 int32_t GetActivePlayerCount(bool fCountInvisible) const; // get number of players that have not been removed
397 StdStrBuf GetActivePlayerNames(bool fCountInvisible, int32_t iAtClientID = -1) const; // get a comma-separated list of players that have not been removed yet
398 int32_t GetActiveScriptPlayerCount(bool fCountSavegameResumes, bool fCountInvisible) const; // get number of script players that have not been removed
399
400 C4PlayerInfo *GetPrimaryInfoByClientID(int32_t iClientID) const
401 {
402 C4ClientPlayerInfos *pInfoPkt = GetInfoByClientID(iClientID);
403 if (!pInfoPkt) return nullptr;
404 return pInfoPkt->GetPlayerInfo(iIndex: 0);
405 }
406
407 C4PlayerInfo *FindSavegameResumePlayerInfo(const C4PlayerInfo *pMatchInfo, MatchingLevel mlMatchStart, MatchingLevel mlMatchEnd) const; // automatic savegame player association: Associate by name (or prefcolor, if none matches)
408 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
409 C4PlayerInfo *FindUnassociatedRestoreInfo(const C4PlayerInfoList &rRestoreInfoList); // find a player in the given list that has not been associated by a player in this list
410
411 void RemoveInfo(C4ClientPlayerInfos **ppRemoveInfo) // remove client info given by direct ptr into list
412 {
413 *ppRemoveInfo = ppClients[--iClientCount]; /* maybe redundant self-assignment; no vector shrink */
414 }
415
416public:
417 bool Load(C4Group &hGroup, const char *szFromFile, class C4LangStringTable *pLang = nullptr); // clear self and load from group file
418 bool Save(C4Group &hGroup, const char *szToFile); // save to group file
419 bool LoadFromGameText(const char *pSource); // load from Game.txt (old-style savegames)
420
421 // external ID counter manipulation used by C4Game
422 void SetIDCounter(int32_t idNewCounter) { iLastPlayerID = idNewCounter; }
423 int32_t GetIDCounter() { return iLastPlayerID; }
424 void FixIDCounter(); // make sure ID counter is same as largest info
425
426 // game interaction
427 void InitLocal(); // put locally joining players into list (non-network)
428 bool LocalJoinUnjoinedPlayersInQueue(); // join all unjoined players to local input queue
429 int32_t GetStartupCount(); // get number of players already joined and to be joined
430 void CreateRestoreInfosForJoinedScriptPlayers(C4PlayerInfoList &rSavegamePlayers); // create matching script player joins for all script playeers in restore info
431 bool RecreatePlayers(); // directly join all players whose join-flag is set
432 bool RecreatePlayerFiles(); // update player source files
433 bool RestoreSavegameInfos(C4PlayerInfoList &rSavegamePlayers); // recreate this list from rSavegamePlayers for host/single games; just merge associated infos
434 bool SetAsRestoreInfos(C4PlayerInfoList &rFromPlayers, bool fSaveUserPlrs, bool fSaveScriptPlrs, bool fSetUserPlrRefToLocalGroup, bool fSetScriptPlrRefToLocalGroup); // copy all joined players from player list
435 bool RemoveUnassociatedPlayers(C4PlayerInfoList &rSavegamePlayers); // remove all savegame players that are not associated to this list from the game
436 int32_t GetFreePlayerSlotCount(); // get number of players that may still join
437 void ResetLeagueProjectedGain(bool fSetUpdated); // reset known projected gains for all players (to be updated by league again)
438
439 // network: Load all resources connected with the players that are not being loaded yet
440 void LoadResources();
441
442 // compiler
443 void CompileFunc(StdCompiler *pComp);
444};
445