Line data Source code
1 : /* Copyright (C) 2021 Wildfire Games.
2 : * This file is part of 0 A.D.
3 : *
4 : * 0 A.D. is free software: you can redistribute it and/or modify
5 : * it under the terms of the GNU General Public License as published by
6 : * the Free Software Foundation, either version 2 of the License, or
7 : * (at your option) any later version.
8 : *
9 : * 0 A.D. is distributed in the hope that it will be useful,
10 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 : * GNU General Public License for more details.
13 : *
14 : * You should have received a copy of the GNU General Public License
15 : * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
16 : */
17 :
18 : #ifndef INCLUDED_NETSERVERTURNMANAGER
19 : #define INCLUDED_NETSERVERTURNMANAGER
20 :
21 : #include "ps/CStr.h"
22 :
23 : #include <map>
24 : #include <unordered_map>
25 :
26 : class CNetServerWorker;
27 : class CNetServerSession;
28 :
29 : /**
30 : * The server-side counterpart to CNetClientTurnManager.
31 : * Records the turn state of each client, and sends turn advancement messages
32 : * when clients are ready.
33 : *
34 : * Thread-safety:
35 : * - This is constructed and used by CNetServerWorker in the network server thread.
36 : */
37 0 : class CNetServerTurnManager
38 : {
39 : NONCOPYABLE(CNetServerTurnManager);
40 : public:
41 : CNetServerTurnManager(CNetServerWorker& server);
42 :
43 : void NotifyFinishedClientCommands(CNetServerSession& session, u32 turn);
44 :
45 : void NotifyFinishedClientUpdate(CNetServerSession& session, u32 turn, const CStr& hash);
46 :
47 : /**
48 : * Inform the turn manager of a new client
49 : * @param observer - whether this client is an observer.
50 : */
51 : void InitialiseClient(int client, u32 turn, bool observer);
52 :
53 : /**
54 : * Inform the turn manager that a previously-initialised client has left the game.
55 : */
56 : void UninitialiseClient(int client);
57 :
58 : void SetTurnLength(u32 msecs);
59 :
60 : /**
61 : * Returns the latest turn for which all clients are ready;
62 : * they will have already been told to execute this turn.
63 : */
64 0 : u32 GetReadyTurn() { return m_ReadyTurn; }
65 :
66 : /**
67 : * Returns the turn length that was used for the given turn.
68 : * Requires turn <= GetReadyTurn().
69 : */
70 : u32 GetSavedTurnLength(u32 turn);
71 :
72 : private:
73 : void CheckClientsReady();
74 :
75 0 : struct Client
76 : {
77 : CStrW playerName;
78 : // Latest turn for which all commands have been received.
79 : u32 readyTurn;
80 : // Last known simulated turn.
81 : u32 simulatedTurn;
82 : bool isObserver;
83 : bool isOOS = false;
84 : };
85 :
86 : std::unordered_map<int, Client> m_ClientsData;
87 :
88 : // Cached value - is any client OOS? This is reset when the OOS client leaves.
89 : bool m_HasSyncError = false;
90 :
91 : // Map of turn -> {Client ID -> state hash}; old indexes <= min(m_ClientsSimulated) are deleted
92 : std::map<u32, std::map<int, std::string>> m_ClientStateHashes;
93 :
94 : /// The latest turn for which we have received all commands from all clients
95 : u32 m_ReadyTurn;
96 :
97 : // Current turn length
98 : u32 m_TurnLength;
99 :
100 : // Turn lengths for all previously executed turns
101 : std::vector<u32> m_SavedTurnLengths;
102 :
103 : CNetServerWorker& m_NetServer;
104 : };
105 :
106 : #endif // INCLUDED_NETSERVERTURNMANAGER
|