Pyrogenesis  trunk
NetClient.h
Go to the documentation of this file.
1 /* Copyright (C) 2017 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 NETCLIENT_H
19 #define NETCLIENT_H
20 
21 #include "network/fsm.h"
23 #include "network/NetHost.h"
25 
26 #include "ps/CStr.h"
27 
28 #include <deque>
29 
30 class CGame;
31 class CNetClientSession;
33 class CNetServer;
34 class ScriptInterface;
35 
36 // NetClient session FSM states
37 enum
38 {
48 };
49 
50 /**
51  * Network client.
52  * This code is run by every player (including the host, if they are not
53  * a dedicated server).
54  * It provides an interface between the GUI, the network (via CNetClientSession),
55  * and the game (via CGame and CNetClientTurnManager).
56  */
57 class CNetClient : public CFsm
58 {
60 
62 
63 public:
64  /**
65  * Construct a client associated with the given game object.
66  * The game must exist for the lifetime of this object.
67  */
68  CNetClient(CGame* game, bool isLocalClient);
69 
70  virtual ~CNetClient();
71 
72  /**
73  * We assume that adding a tracing function that's only called
74  * during GC is better for performance than using a
75  * PersistentRooted<T> where each value needs to be added to
76  * the root set.
77  */
78  static void Trace(JSTracer *trc, void *data)
79  {
80  reinterpret_cast<CNetClient*>(data)->TraceMember(trc);
81  }
82 
83  void TraceMember(JSTracer *trc);
84 
85  /**
86  * Set the user's name that will be displayed to all players.
87  * This must not be called after the connection setup.
88  */
89  void SetUserName(const CStrW& username);
90 
91  /**
92  * Returns the GUID of the local client.
93  * Used for distinguishing observers.
94  */
95  CStr GetGUID() const { return m_GUID; }
96 
97  /**
98  * Set up a connection to the remote networked server.
99  * @param server IP address or host name to connect to
100  * @return true on success, false on connection failure
101  */
102  bool SetupConnection(const CStr& server, const u16 port);
103 
104  /**
105  * Destroy the connection to the server.
106  * This client probably cannot be used again.
107  */
108  void DestroyConnection();
109 
110  /**
111  * Poll the connection for messages from the server and process them, and send
112  * any queued messages.
113  * This must be called frequently (i.e. once per frame).
114  */
115  void Poll();
116 
117  /**
118  * Locally triggers a GUI message if the connection to the server is being lost or has bad latency.
119  */
120  void CheckServerConnection();
121 
122  /**
123  * Flush any queued outgoing network messages.
124  * This should be called soon after sending a group of messages that may be batched together.
125  */
126  void Flush();
127 
128  /**
129  * Retrieves the next queued GUI message, and removes it from the queue.
130  * The returned value is in the GetScriptInterface() JS context.
131  *
132  * This is the only mechanism for the networking code to send messages to
133  * the GUI - it is pull-based (instead of push) so the engine code does not
134  * need to know anything about the code structure of the GUI scripts.
135  *
136  * The structure of the messages is <code>{ "type": "...", ... }</code>.
137  * The exact types and associated data are not specified anywhere - the
138  * implementation and GUI scripts must make the same assumptions.
139  *
140  * @return next message, or the value 'undefined' if the queue is empty
141  */
142  void GuiPoll(JS::MutableHandleValue);
143 
144  /**
145  * Add a message to the queue, to be read by GuiPoll.
146  * The script value must be in the GetScriptInterface() JS context.
147  */
148  void PushGuiMessage(const JS::HandleValue message);
149 
150  /**
151  * Return a concatenation of all messages in the GUI queue,
152  * for test cases to easily verify the queue contents.
153  */
154  std::string TestReadGuiMessages();
155 
156  /**
157  * Get the script interface associated with this network client,
158  * which is equivalent to the one used by the CGame in the constructor.
159  */
161 
162  /**
163  * Send a message to the server.
164  * @param message message to send
165  * @return true on success
166  */
167  bool SendMessage(const CNetMessage* message);
168 
169  /**
170  * Call when the network connection has been successfully initiated.
171  */
172  void HandleConnect();
173 
174  /**
175  * Call when the network connection has been lost.
176  */
177  void HandleDisconnect(u32 reason);
178 
179  /**
180  * Call when a message has been received from the network.
181  */
182  bool HandleMessage(CNetMessage* message);
183 
184  /**
185  * Call when the game has started and all data files have been loaded,
186  * to signal to the server that we are ready to begin the game.
187  */
188  void LoadFinished();
189 
190  void SendGameSetupMessage(JS::MutableHandleValue attrs, ScriptInterface& scriptInterface);
191 
192  void SendAssignPlayerMessage(const int playerID, const CStr& guid);
193 
194  void SendChatMessage(const std::wstring& text);
195 
196  void SendReadyMessage(const int status);
197 
199 
200  void SendStartGameMessage();
201 
202  /**
203  * Call when the client has rejoined a running match and finished
204  * the loading screen.
205  */
206  void SendRejoinedMessage();
207 
208  /**
209  * Call to kick/ban a client
210  */
211  void SendKickPlayerMessage(const CStrW& playerName, bool ban);
212 
213  /**
214  * Call when the client has paused or unpaused the game.
215  */
216  void SendPausedMessage(bool pause);
217 
218 private:
219  // Net message / FSM transition handlers
220  static bool OnConnect(void* context, CFsmEvent* event);
221  static bool OnHandshake(void* context, CFsmEvent* event);
222  static bool OnHandshakeResponse(void* context, CFsmEvent* event);
223  static bool OnAuthenticate(void* context, CFsmEvent* event);
224  static bool OnChat(void* context, CFsmEvent* event);
225  static bool OnReady(void* context, CFsmEvent* event);
226  static bool OnGameSetup(void* context, CFsmEvent* event);
227  static bool OnPlayerAssignment(void* context, CFsmEvent* event);
228  static bool OnInGame(void* context, CFsmEvent* event);
229  static bool OnGameStart(void* context, CFsmEvent* event);
230  static bool OnJoinSyncStart(void* context, CFsmEvent* event);
231  static bool OnJoinSyncEndCommandBatch(void* context, CFsmEvent* event);
232  static bool OnRejoined(void* context, CFsmEvent* event);
233  static bool OnKicked(void* context, CFsmEvent* event);
234  static bool OnClientTimeout(void* context, CFsmEvent* event);
235  static bool OnClientPerformance(void* context, CFsmEvent* event);
236  static bool OnClientsLoading(void* context, CFsmEvent* event);
237  static bool OnClientPaused(void* context, CFsmEvent* event);
238  static bool OnLoadedGame(void* context, CFsmEvent* event);
239 
240  /**
241  * Take ownership of a session object, and use it for all network communication.
242  */
243  void SetAndOwnSession(CNetClientSession* session);
244 
245  /**
246  * Push a message onto the GUI queue listing the current player assignments.
247  */
249 
251  CStrW m_UserName;
252 
253  /// Current network session (or NULL if not connected)
255 
256  /// Turn manager associated with the current game (or NULL if we haven't started the game yet)
258 
259  /// Unique-per-game identifier of this client, used to identify the sender of simulation commands
261 
262  /// True if the player is currently rejoining or has already rejoined the game.
263  bool m_Rejoin;
264 
265  /// Whether to prevent the client of the host from timing out
267 
268  /// Latest copy of game setup attributes heard from the server
269  JS::PersistentRootedValue m_GameAttributes;
270 
271  /// Latest copy of player assignments heard from the server
273 
274  /// Globally unique identifier to distinguish users beyond the lifetime of a single network session
275  CStr m_GUID;
276 
277  /// Queue of messages for GuiPoll
278  std::deque<JS::Heap<JS::Value>> m_GuiMessageQueue;
279 
280  /// Serialized game state received when joining an in-progress game
281  std::string m_JoinSyncBuffer;
282 
283  /// Time when the server was last checked for timeouts and bad latency
285 };
286 
287 /// Global network client for the standard game
288 extern CNetClient *g_NetClient;
289 
290 #endif // NETCLIENT_H
The container that holds the rules, resources and attributes of the game.
Definition: Game.h:40
ScriptInterface & GetScriptInterface()
Get the script interface associated with this network client, which is equivalent to the one used by ...
Definition: NetClient.cpp:272
void DestroyConnection()
Destroy the connection to the server.
Definition: NetClient.cpp:175
Manages states, events, actions and transitions between states.
Definition: fsm.h:117
void SendAssignPlayerMessage(const int playerID, const CStr &guid)
Definition: NetClient.cpp:338
std::map< CStr, PlayerAssignment > PlayerAssignmentMap
Definition: NetHost.h:54
static bool OnRejoined(void *context, CFsmEvent *event)
Definition: NetClient.cpp:691
std::time_t m_LastConnectionCheck
Time when the server was last checked for timeouts and bad latency.
Definition: NetClient.h:284
bool m_IsLocalClient
Whether to prevent the client of the host from timing out.
Definition: NetClient.h:266
CNetClientTurnManager * m_ClientTurnManager
Turn manager associated with the current game (or NULL if we haven&#39;t started the game yet) ...
Definition: NetClient.h:257
uint16_t u16
Definition: types.h:38
Represents a signal in the state machine that a change has occurred.
Definition: fsm.h:53
virtual ~CNetClient()
Definition: NetClient.cpp:142
CNetClientSession * m_Session
Current network session (or NULL if not connected)
Definition: NetClient.h:254
Definition: NetClient.h:44
void LoadFinished()
Call when the game has started and all data files have been loaded, to signal to the server that we a...
Definition: NetClient.cpp:436
static bool OnChat(void *context, CFsmEvent *event)
Definition: NetClient.cpp:550
Definition: NetClient.h:43
void GuiPoll(JS::MutableHandleValue)
Retrieves the next queued GUI message, and removes it from the queue.
Definition: NetClient.cpp:236
void SendKickPlayerMessage(const CStrW &playerName, bool ban)
Call to kick/ban a client.
Definition: NetClient.cpp:378
std::string TestReadGuiMessages()
Return a concatenation of all messages in the GUI queue, for test cases to easily verify the queue co...
Definition: NetClient.cpp:255
static bool OnClientTimeout(void *context, CFsmEvent *event)
Definition: NetClient.cpp:728
static bool OnHandshake(void *context, CFsmEvent *event)
Definition: NetClient.cpp:495
static bool OnLoadedGame(void *context, CFsmEvent *event)
Definition: NetClient.cpp:824
static bool OnInGame(void *context, CFsmEvent *event)
Definition: NetClient.cpp:847
void HandleConnect()
Call when the network connection has been successfully initiated.
Definition: NetClient.cpp:309
static bool OnAuthenticate(void *context, CFsmEvent *event)
Definition: NetClient.cpp:526
void HandleDisconnect(u32 reason)
Call when the network connection has been lost.
Definition: NetClient.cpp:314
void Flush()
Flush any queued outgoing network messages.
Definition: NetClient.cpp:230
void PostPlayerAssignmentsToScript()
Push a message onto the GUI queue listing the current player assignments.
Definition: NetClient.cpp:277
bool SendMessage(const CNetMessage *message)
Send a message to the server.
Definition: NetClient.cpp:301
uint32_t u32
Definition: types.h:39
bool SetupConnection(const CStr &server, const u16 port)
Set up a connection to the remote networked server.
Definition: NetClient.cpp:161
JS::PersistentRootedValue m_GameAttributes
Latest copy of game setup attributes heard from the server.
Definition: NetClient.h:269
static bool OnReady(void *context, CFsmEvent *event)
Definition: NetClient.cpp:569
Various declarations shared by networking code.
void SendPausedMessage(bool pause)
Call when the client has paused or unpaused the game.
Definition: NetClient.cpp:386
Definition: NetClient.h:42
static bool OnConnect(void *context, CFsmEvent *event)
Definition: NetClient.cpp:479
PlayerAssignmentMap m_PlayerAssignments
Latest copy of player assignments heard from the server.
Definition: NetClient.h:272
Definition: NetClient.h:45
void SetAndOwnSession(CNetClientSession *session)
Take ownership of a session object, and use it for all network communication.
Definition: NetClient.cpp:169
Definition: NetClient.h:46
CGame * m_Game
Definition: NetClient.h:250
static bool OnPlayerAssignment(void *context, CFsmEvent *event)
Definition: NetClient.cpp:608
u32 m_HostID
Unique-per-game identifier of this client, used to identify the sender of simulation commands...
Definition: NetClient.h:260
void SetUserName(const CStrW &username)
Set the user&#39;s name that will be displayed to all players.
Definition: NetClient.cpp:154
CStrW m_UserName
Definition: NetClient.h:251
static bool OnJoinSyncEndCommandBatch(void *context, CFsmEvent *event)
Definition: NetClient.cpp:675
Network server interface.
Definition: NetServer.h:98
void SendRejoinedMessage()
Call when the client has rejoined a running match and finished the loading screen.
Definition: NetClient.cpp:372
static bool OnGameSetup(void *context, CFsmEvent *event)
Definition: NetClient.cpp:588
void TraceMember(JSTracer *trc)
Definition: NetClient.cpp:148
CStr m_GUID
Globally unique identifier to distinguish users beyond the lifetime of a single network session...
Definition: NetClient.h:275
void SendReadyMessage(const int status)
Definition: NetClient.cpp:353
void Poll()
Poll the connection for messages from the server and process them, and send any queued messages...
Definition: NetClient.cpp:186
std::string m_JoinSyncBuffer
Serialized game state received when joining an in-progress game.
Definition: NetClient.h:281
The base class for all network messages exchanged within the game.
Definition: NetMessage.h:32
bool HandleMessage(CNetMessage *message)
Call when a message has been received from the network.
Definition: NetClient.cpp:393
static bool OnClientsLoading(void *context, CFsmEvent *event)
Definition: NetClient.cpp:783
static bool OnJoinSyncStart(void *context, CFsmEvent *event)
Definition: NetClient.cpp:661
std::deque< JS::Heap< JS::Value > > m_GuiMessageQueue
Queue of messages for GuiPoll.
Definition: NetClient.h:278
void SendGameSetupMessage(JS::MutableHandleValue attrs, ScriptInterface &scriptInterface)
Definition: NetClient.cpp:331
Async task for receiving the initial game state when rejoining an in-progress network game...
Definition: NetClient.cpp:44
Network client.
Definition: NetClient.h:57
void SendChatMessage(const std::wstring &text)
Definition: NetClient.cpp:346
static bool OnKicked(void *context, CFsmEvent *event)
Definition: NetClient.cpp:708
Implementation of CTurnManager for network clients.
Definition: NetClientTurnManager.h:29
static bool OnGameStart(void *context, CFsmEvent *event)
Definition: NetClient.cpp:635
static void Trace(JSTracer *trc, void *data)
We assume that adding a tracing function that&#39;s only called during GC is better for performance than ...
Definition: NetClient.h:78
static bool OnClientPaused(void *context, CFsmEvent *event)
Definition: NetClient.cpp:805
void PushGuiMessage(const JS::HandleValue message)
Add a message to the queue, to be read by GuiPoll.
Definition: NetClient.cpp:248
CStr GetGUID() const
Returns the GUID of the local client.
Definition: NetClient.h:95
Definition: NetClient.h:47
static bool OnClientPerformance(void *context, CFsmEvent *event)
Definition: NetClient.cpp:752
void SendClearAllReadyMessage()
Definition: NetClient.cpp:360
Abstraction around a SpiderMonkey JSContext.
Definition: ScriptInterface.h:71
bool m_Rejoin
True if the player is currently rejoining or has already rejoined the game.
Definition: NetClient.h:263
Definition: NetClient.h:40
Definition: NetClient.h:41
CNetClient * g_NetClient
Global network client for the standard game.
Definition: NetClient.cpp:38
Definition: NetClient.h:39
void SendStartGameMessage()
Definition: NetClient.cpp:366
The client end of a network session.
Definition: NetSession.h:65
CNetClient(CGame *game, bool isLocalClient)
Construct a client associated with the given game object.
Definition: NetClient.cpp:69
void CheckServerConnection()
Locally triggers a GUI message if the connection to the server is being lost or has bad latency...
Definition: NetClient.cpp:195
NONCOPYABLE(CNetClient)
static bool OnHandshakeResponse(void *context, CFsmEvent *event)
Definition: NetClient.cpp:510