Pyrogenesis  13997
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
NetClient.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2011 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 #include "precompiled.h"
19 
20 #include "NetClient.h"
21 
22 #include "NetMessage.h"
23 #include "NetSession.h"
24 #include "NetTurnManager.h"
25 
26 #include "lib/byte_order.h"
27 #include "lib/sysdep/sysdep.h"
28 #include "ps/CConsole.h"
29 #include "ps/CLogger.h"
30 #include "ps/Compress.h"
31 #include "ps/CStr.h"
32 #include "ps/Game.h"
33 #include "ps/Loader.h"
36 
38 
39 /**
40  * Async task for receiving the initial game state when rejoining an
41  * in-progress network game.
42  */
44 {
46 public:
48  : m_Client(client)
49  {
50  }
51 
52  virtual void OnComplete()
53  {
54  // We've received the game state from the server
55 
56  // Save it so we can use it after the map has finished loading
58 
59  // Pretend the server told us to start the game
60  CGameStartMessage start;
61  m_Client.HandleMessage(&start);
62  }
63 
64 private:
66 };
67 
69  m_Session(NULL),
70  m_UserName(L"anonymous"),
71  m_GUID(GenerateGUID()), m_HostID((u32)-1), m_ClientTurnManager(NULL), m_Game(game)
72 {
73  m_Game->SetTurnManager(NULL); // delete the old local turn manager so we don't accidentally use it
74 
75  void* context = this;
76 
77  // Set up transitions for session
79 
81 
83 
85 
87 
88  AddTransition(NCS_PREGAME, (uint)NMT_CHAT, NCS_PREGAME, (void*)&OnChat, context);
89  AddTransition(NCS_PREGAME, (uint)NMT_GAME_SETUP, NCS_PREGAME, (void*)&OnGameSetup, context);
93 
94  AddTransition(NCS_JOIN_SYNCING, (uint)NMT_CHAT, NCS_JOIN_SYNCING, (void*)&OnChat, context);
95  AddTransition(NCS_JOIN_SYNCING, (uint)NMT_GAME_SETUP, NCS_JOIN_SYNCING, (void*)&OnGameSetup, context);
96  AddTransition(NCS_JOIN_SYNCING, (uint)NMT_PLAYER_ASSIGNMENT, NCS_JOIN_SYNCING, (void*)&OnPlayerAssignment, context);
97  AddTransition(NCS_JOIN_SYNCING, (uint)NMT_GAME_START, NCS_JOIN_SYNCING, (void*)&OnGameStart, context);
101 
102  AddTransition(NCS_LOADING, (uint)NMT_CHAT, NCS_LOADING, (void*)&OnChat, context);
103  AddTransition(NCS_LOADING, (uint)NMT_GAME_SETUP, NCS_LOADING, (void*)&OnGameSetup, context);
104  AddTransition(NCS_LOADING, (uint)NMT_PLAYER_ASSIGNMENT, NCS_LOADING, (void*)&OnPlayerAssignment, context);
105  AddTransition(NCS_LOADING, (uint)NMT_LOADED_GAME, NCS_INGAME, (void*)&OnLoadedGame, context);
106 
107  AddTransition(NCS_INGAME, (uint)NMT_CHAT, NCS_INGAME, (void*)&OnChat, context);
108  AddTransition(NCS_INGAME, (uint)NMT_GAME_SETUP, NCS_INGAME, (void*)&OnGameSetup, context);
109  AddTransition(NCS_INGAME, (uint)NMT_PLAYER_ASSIGNMENT, NCS_INGAME, (void*)&OnPlayerAssignment, context);
110  AddTransition(NCS_INGAME, (uint)NMT_SIMULATION_COMMAND, NCS_INGAME, (void*)&OnInGame, context);
111  AddTransition(NCS_INGAME, (uint)NMT_SYNC_ERROR, NCS_INGAME, (void*)&OnInGame, context);
112  AddTransition(NCS_INGAME, (uint)NMT_END_COMMAND_BATCH, NCS_INGAME, (void*)&OnInGame, context);
113 
114  // Set first state
116 }
117 
119 {
121 }
122 
123 void CNetClient::SetUserName(const CStrW& username)
124 {
125  ENSURE(!m_Session); // must be called before we start the connection
126 
127  m_UserName = username;
128 }
129 
130 bool CNetClient::SetupConnection(const CStr& server)
131 {
132  CNetClientSession* session = new CNetClientSession(*this);
133  bool ok = session->Connect(PS_DEFAULT_PORT, server);
134  SetAndOwnSession(session);
135  return ok;
136 }
137 
139 {
140  delete m_Session;
141  m_Session = session;
142 }
143 
145 {
147 }
148 
150 {
151  if (m_Session)
152  m_Session->Poll();
153 }
154 
156 {
157  if (m_Session)
158  m_Session->Flush();
159 }
160 
162 {
163  if (m_GuiMessageQueue.empty())
164  return CScriptValRooted();
165 
167  m_GuiMessageQueue.pop_front();
168  return r;
169 }
170 
172 {
173  ENSURE(!message.undefined());
174 
175  m_GuiMessageQueue.push_back(message);
176 }
177 
179 {
180  std::wstring r;
181  while (true)
182  {
183  CScriptValRooted msg = GuiPoll();
184  if (msg.undefined())
185  break;
186  r += GetScriptInterface().ToString(msg.get()) + L"\n";
187  }
188  return r;
189 }
190 
192 {
194 }
195 
197 {
198  CScriptValRooted msg;
199  GetScriptInterface().Eval("({'type':'players', 'hosts':{}})", msg);
200 
201  CScriptValRooted hosts;
202  GetScriptInterface().GetProperty(msg.get(), "hosts", hosts);
203 
204  for (PlayerAssignmentMap::iterator it = m_PlayerAssignments.begin(); it != m_PlayerAssignments.end(); ++it)
205  {
206  CScriptValRooted host;
207  GetScriptInterface().Eval("({})", host);
208  GetScriptInterface().SetProperty(host.get(), "name", std::wstring(it->second.m_Name), false);
209  GetScriptInterface().SetProperty(host.get(), "player", it->second.m_PlayerID, false);
210  GetScriptInterface().SetProperty(hosts.get(), it->first.c_str(), host, false);
211  }
212 
213  PushGuiMessage(msg);
214 }
215 
217 {
218  if (!m_Session)
219  return false;
220 
221  return m_Session->SendMessage(message);
222 }
223 
225 {
226  Update((uint)NMT_CONNECT_COMPLETE, NULL);
227 }
228 
230 {
231  CScriptValRooted msg;
232  GetScriptInterface().Eval("({'type':'netstatus','status':'disconnected'})", msg);
233  GetScriptInterface().SetProperty(msg.get(), "reason", (int)reason, false);
234  PushGuiMessage(msg);
235 
237 
238  // Update the state immediately to UNCONNECTED (don't bother with FSM transitions since
239  // we'd need one for every single state, and we don't need to use per-state actions)
241 }
242 
243 void CNetClient::SendChatMessage(const std::wstring& text)
244 {
245  CChatMessage chat;
246  chat.m_Message = text;
247  SendMessage(&chat);
248 }
249 
251 {
252  // Handle non-FSM messages first
253 
255  if (status == INFO::OK)
256  return true;
257  if (status != INFO::SKIPPED)
258  return false;
259 
260  if (message->GetType() == NMT_FILE_TRANSFER_REQUEST)
261  {
262  CFileTransferRequestMessage* reqMessage = (CFileTransferRequestMessage*)message;
263 
264  // TODO: we should support different transfer request types, instead of assuming
265  // it's always requesting the simulation state
266 
267  std::stringstream stream;
268 
269  LOGMESSAGERENDER(L"Serializing game at turn %u for rejoining player", m_ClientTurnManager->GetCurrentTurn());
271  stream.write((char*)&turn, sizeof(turn));
272 
273  bool ok = m_Game->GetSimulation2()->SerializeState(stream);
274  ENSURE(ok);
275 
276  // Compress the content with zlib to save bandwidth
277  // (TODO: if this is still too large, compressing with e.g. LZMA works much better)
278  std::string compressed;
279  CompressZLib(stream.str(), compressed, true);
280 
281  m_Session->GetFileTransferer().StartResponse(reqMessage->m_RequestID, compressed);
282 
283  return true;
284  }
285 
286  // Update FSM
287  bool ok = Update(message->GetType(), message);
288  if (!ok)
289  LOGERROR(L"Net client: Error running FSM update (type=%d state=%d)", (int)message->GetType(), (int)GetCurrState());
290  return ok;
291 }
292 
294 {
295  if (!m_JoinSyncBuffer.empty())
296  {
297  // We're rejoining a game, and just finished loading the initial map,
298  // so deserialize the saved game state now
299 
300  std::string state;
301  DecompressZLib(m_JoinSyncBuffer, state, true);
302 
303  std::stringstream stream(state);
304 
305  u32 turn;
306  stream.read((char*)&turn, sizeof(turn));
307  turn = to_le32(turn);
308 
309  LOGMESSAGE(L"Rejoining client deserializing state at turn %u\n", turn);
310 
311  bool ok = m_Game->GetSimulation2()->DeserializeState(stream);
312  ENSURE(ok);
313 
314  m_ClientTurnManager->ResetState(turn, turn);
315 
316  CScriptValRooted msg;
317  GetScriptInterface().Eval("({'type':'netstatus','status':'join_syncing'})", msg);
318  PushGuiMessage(msg);
319  }
320  else
321  {
322  // Connecting at the start of a game, so we'll wait for other players to finish loading
323  CScriptValRooted msg;
324  GetScriptInterface().Eval("({'type':'netstatus','status':'waiting_for_players'})", msg);
325  PushGuiMessage(msg);
326  }
327 
328  CLoadedGameMessage loaded;
329  loaded.m_CurrentTurn = m_ClientTurnManager->GetCurrentTurn();
330  SendMessage(&loaded);
331 }
332 
333 bool CNetClient::OnConnect(void* context, CFsmEvent* event)
334 {
335  ENSURE(event->GetType() == (uint)NMT_CONNECT_COMPLETE);
336 
337  CNetClient* client = (CNetClient*)context;
338 
339  CScriptValRooted msg;
340  client->GetScriptInterface().Eval("({'type':'netstatus','status':'connected'})", msg);
341  client->PushGuiMessage(msg);
342 
343  return true;
344 }
345 
346 bool CNetClient::OnHandshake(void* context, CFsmEvent* event)
347 {
348  ENSURE(event->GetType() == (uint)NMT_SERVER_HANDSHAKE);
349 
350  CNetClient* client = (CNetClient*)context;
351 
352  CCliHandshakeMessage handshake;
353  handshake.m_MagicResponse = PS_PROTOCOL_MAGIC_RESPONSE;
354  handshake.m_ProtocolVersion = PS_PROTOCOL_VERSION;
355  handshake.m_SoftwareVersion = PS_PROTOCOL_VERSION;
356  client->SendMessage(&handshake);
357 
358  return true;
359 }
360 
361 bool CNetClient::OnHandshakeResponse(void* context, CFsmEvent* event)
362 {
363  ENSURE(event->GetType() == (uint)NMT_SERVER_HANDSHAKE_RESPONSE);
364 
365  CNetClient* client = (CNetClient*)context;
366 
367  CAuthenticateMessage authenticate;
368  authenticate.m_GUID = client->m_GUID;
369  authenticate.m_Name = client->m_UserName;
370  authenticate.m_Password = L""; // TODO
371  client->SendMessage(&authenticate);
372 
373  return true;
374 }
375 
376 bool CNetClient::OnAuthenticate(void* context, CFsmEvent* event)
377 {
378  ENSURE(event->GetType() == (uint)NMT_AUTHENTICATE_RESULT);
379 
380  CNetClient* client = (CNetClient*)context;
381 
382  CAuthenticateResultMessage* message = (CAuthenticateResultMessage*)event->GetParamRef();
383 
384  LOGMESSAGE(L"Net: Authentication result: host=%u, %ls", message->m_HostID, message->m_Message.c_str());
385 
386  bool isRejoining = (message->m_Code == ARC_OK_REJOINING);
387 
388  client->m_HostID = message->m_HostID;
389 
390  CScriptValRooted msg;
391  client->GetScriptInterface().Eval("({'type':'netstatus','status':'authenticated'})", msg);
392  client->GetScriptInterface().SetProperty(msg.get(), "rejoining", isRejoining);
393  client->PushGuiMessage(msg);
394 
395  return true;
396 }
397 
398 bool CNetClient::OnChat(void* context, CFsmEvent* event)
399 {
400  ENSURE(event->GetType() == (uint)NMT_CHAT);
401 
402  CNetClient* client = (CNetClient*)context;
403 
404  CChatMessage* message = (CChatMessage*)event->GetParamRef();
405 
406  CScriptValRooted msg;
407  client->GetScriptInterface().Eval("({'type':'chat'})", msg);
408  client->GetScriptInterface().SetProperty(msg.get(), "guid", std::string(message->m_GUID), false);
409  client->GetScriptInterface().SetProperty(msg.get(), "text", std::wstring(message->m_Message), false);
410  client->PushGuiMessage(msg);
411 
412  return true;
413 }
414 
415 bool CNetClient::OnGameSetup(void* context, CFsmEvent* event)
416 {
417  ENSURE(event->GetType() == (uint)NMT_GAME_SETUP);
418 
419  CNetClient* client = (CNetClient*)context;
420 
421  CGameSetupMessage* message = (CGameSetupMessage*)event->GetParamRef();
422 
423  client->m_GameAttributes = message->m_Data;
424 
425  CScriptValRooted msg;
426  client->GetScriptInterface().Eval("({'type':'gamesetup'})", msg);
427  client->GetScriptInterface().SetProperty(msg.get(), "data", message->m_Data, false);
428  client->PushGuiMessage(msg);
429 
430  return true;
431 }
432 
433 bool CNetClient::OnPlayerAssignment(void* context, CFsmEvent* event)
434 {
435  ENSURE(event->GetType() == (uint)NMT_PLAYER_ASSIGNMENT);
436 
437  CNetClient* client = (CNetClient*)context;
438 
439  CPlayerAssignmentMessage* message = (CPlayerAssignmentMessage*)event->GetParamRef();
440 
441  // Unpack the message
442  PlayerAssignmentMap newPlayerAssignments;
443  for (size_t i = 0; i < message->m_Hosts.size(); ++i)
444  {
445  PlayerAssignment assignment;
446  assignment.m_Enabled = true;
447  assignment.m_Name = message->m_Hosts[i].m_Name;
448  assignment.m_PlayerID = message->m_Hosts[i].m_PlayerID;
449  newPlayerAssignments[message->m_Hosts[i].m_GUID] = assignment;
450  }
451 
452  client->m_PlayerAssignments.swap(newPlayerAssignments);
453 
455 
456  return true;
457 }
458 
459 bool CNetClient::OnGameStart(void* context, CFsmEvent* event)
460 {
461  ENSURE(event->GetType() == (uint)NMT_GAME_START);
462 
463  CNetClient* client = (CNetClient*)context;
464 
465  // Find the player assigned to our GUID
466  int player = -1;
467  if (client->m_PlayerAssignments.find(client->m_GUID) != client->m_PlayerAssignments.end())
468  player = client->m_PlayerAssignments[client->m_GUID].m_PlayerID;
469 
471  *client->m_Game->GetSimulation2(), *client, client->m_HostID, client->m_Game->GetReplayLogger());
472 
473  client->m_Game->SetPlayerID(player);
474  client->m_Game->StartGame(client->m_GameAttributes, "");
475 
476  CScriptValRooted msg;
477  client->GetScriptInterface().Eval("({'type':'start'})", msg);
478  client->PushGuiMessage(msg);
479 
480  return true;
481 }
482 
483 bool CNetClient::OnJoinSyncStart(void* context, CFsmEvent* event)
484 {
485  ENSURE(event->GetType() == (uint)NMT_JOIN_SYNC_START);
486 
487  CNetClient* client = (CNetClient*)context;
488 
489  // The server wants us to start downloading the game state from it, so do so
491  shared_ptr<CNetFileReceiveTask>(new CNetFileReceiveTask_ClientRejoin(*client))
492  );
493 
494  return true;
495 }
496 
498 {
499  ENSURE(event->GetType() == (uint)NMT_END_COMMAND_BATCH);
500 
501  CNetClient* client = (CNetClient*)context;
502 
503  CEndCommandBatchMessage* endMessage = (CEndCommandBatchMessage*)event->GetParamRef();
504 
505  client->m_ClientTurnManager->FinishedAllCommands(endMessage->m_Turn, endMessage->m_TurnLength);
506 
507  // Execute all the received commands for the latest turn
509 
510  return true;
511 }
512 
513 bool CNetClient::OnLoadedGame(void* context, CFsmEvent* event)
514 {
515  ENSURE(event->GetType() == (uint)NMT_LOADED_GAME);
516 
517  CNetClient* client = (CNetClient*)context;
518 
519  // All players have loaded the game - start running the turn manager
520  // so that the game begins
521  client->m_Game->SetTurnManager(client->m_ClientTurnManager);
522 
523  CScriptValRooted msg;
524  client->GetScriptInterface().Eval("({'type':'netstatus','status':'active'})", msg);
525  client->PushGuiMessage(msg);
526 
527  return true;
528 }
529 
530 bool CNetClient::OnInGame(void *context, CFsmEvent* event)
531 {
532  // TODO: should split each of these cases into a separate method
533 
534  CNetClient* client = (CNetClient*)context;
535 
536  CNetMessage* message = (CNetMessage*)event->GetParamRef();
537  if (message)
538  {
539  if (message->GetType() == NMT_SIMULATION_COMMAND)
540  {
541  CSimulationMessage* simMessage = static_cast<CSimulationMessage*> (message);
542  client->m_ClientTurnManager->OnSimulationMessage(simMessage);
543  }
544  else if (message->GetType() == NMT_SYNC_ERROR)
545  {
546  CSyncErrorMessage* syncMessage = static_cast<CSyncErrorMessage*> (message);
547  client->m_ClientTurnManager->OnSyncError(syncMessage->m_Turn, syncMessage->m_HashExpected);
548  }
549  else if (message->GetType() == NMT_END_COMMAND_BATCH)
550  {
551  CEndCommandBatchMessage* endMessage = static_cast<CEndCommandBatchMessage*> (message);
552  client->m_ClientTurnManager->FinishedAllCommands(endMessage->m_Turn, endMessage->m_TurnLength);
553  }
554  }
555 
556  return true;
557 }
558 
560 {
561  // TODO: Ideally this will be guaranteed unique (and verified
562  // cryptographically) since we'll rely on it to identify hosts
563  // and associate them with player controls (e.g. to support
564  // leaving/rejoining in-progress games), and we don't want
565  // a host to masquerade as someone else.
566  // For now, just try to pick a very random number.
567 
568  CStr guid;
569  for (size_t i = 0; i < 2; ++i)
570  {
571  u32 r = 0;
572  sys_generate_random_bytes((u8*)&r, sizeof(r));
573  char buf[32];
574  sprintf_s(buf, ARRAY_SIZE(buf), "%08X", r);
575  guid += buf;
576  }
577 
578  return guid;
579 }
#define PS_PROTOCOL_VERSION
Definition: NetMessages.h:31
The container that holds the rules, resources and attributes of the game.
Definition: Game.h:39
ScriptInterface & GetScriptInterface()
Get the script interface associated with this network client, which is equivalent to the one used by ...
Definition: NetClient.cpp:191
#define u8
Definition: types.h:39
void DestroyConnection()
Destroy the connection to the server.
Definition: NetClient.cpp:144
std::map< CStr, PlayerAssignment > PlayerAssignmentMap
Definition: NetHost.h:51
CStrW m_Name
Player name.
Definition: NetHost.h:45
Simple (non-streaming) compression functions.
virtual void OnComplete()
Called when m_Buffer contains the full received data.
Definition: NetClient.cpp:52
CNetClient * g_NetClient
Global network client for the standard game.
Definition: NetClient.cpp:37
CStr GenerateGUID()
Initialise m_GUID with a random value.
Definition: NetClient.cpp:559
const Status OK
Definition: status.h:386
#define LOGERROR
Definition: CLogger.h:35
CNetClientTurnManager * m_ClientTurnManager
Turn manager associated with the current game (or NULL if we haven&#39;t started the game yet) ...
Definition: NetClient.h:200
Represents a signal in the state machine that a change has occurred.
Definition: fsm.h:53
virtual ~CNetClient()
Definition: NetClient.cpp:118
CNetClientSession * m_Session
Current network session (or NULL if not connected)
Definition: NetClient.h:197
bool DeserializeState(std::istream &stream)
void Poll()
Process queued incoming messages.
Definition: NetSession.cpp:95
#define LOGMESSAGE
Definition: CLogger.h:32
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:293
static bool OnChat(void *context, CFsmEvent *event)
Definition: NetClient.cpp:398
i32 m_PlayerID
The player that the given host controls, or -1 if none (observer)
Definition: NetHost.h:48
CScriptValRooted GuiPoll()
Retrieves the next queued GUI message, and removes it from the queue.
Definition: NetClient.cpp:161
CNetFileReceiveTask_ClientRejoin(CNetClient &client)
Definition: NetClient.cpp:47
void PushGuiMessage(const CScriptValRooted &message)
Add a message to the queue, to be read by GuiPoll.
Definition: NetClient.cpp:171
static bool OnHandshake(void *context, CFsmEvent *event)
Definition: NetClient.cpp:346
static bool OnLoadedGame(void *context, CFsmEvent *event)
Definition: NetClient.cpp:513
static bool OnInGame(void *context, CFsmEvent *event)
Definition: NetClient.cpp:530
NONCOPYABLE(CNetFileReceiveTask_ClientRejoin)
int sprintf_s(char *buf, size_t max_chars, const char *fmt,...) PRINTF_ARGS(3)
#define ARRAY_SIZE(name)
void HandleConnect()
Call when the network connection has been successfully initiated.
Definition: NetClient.cpp:224
void StartTask(const shared_ptr< CNetFileReceiveTask > &task)
Registers a file-receiving task.
static bool OnAuthenticate(void *context, CFsmEvent *event)
Definition: NetClient.cpp:376
void HandleDisconnect(u32 reason)
Call when the network connection has been lost.
Definition: NetClient.cpp:229
void Flush()
Flush any queued outgoing network messages.
Definition: NetClient.cpp:155
void PostPlayerAssignmentsToScript()
Push a message onto the GUI queue listing the current player assignments.
Definition: NetClient.cpp:196
bool SendMessage(const CNetMessage *message)
Send a message to the server.
Definition: NetClient.cpp:216
void StartResponse(u32 requestID, const std::string &data)
Registers data to be sent in response to a request.
std::deque< CScriptValRooted > m_GuiMessageQueue
Queue of messages for GuiPoll.
Definition: NetClient.h:217
#define ENSURE(expr)
ensure the expression &lt;expr&gt; evaluates to non-zero.
Definition: debug.h:282
Status HandleMessageReceive(const CNetMessage *message)
Should be called when a message is received from the network.
void SetPlayerID(int playerID)
Definition: Game.cpp:254
CNetClient(CGame *game)
Construct a client associated with the given game object.
Definition: NetClient.cpp:68
#define PS_DEFAULT_PORT
Definition: NetMessages.h:32
static bool OnConnect(void *context, CFsmEvent *event)
Definition: NetClient.cpp:333
void SetTurnManager(CNetTurnManager *turnManager)
Replace the current turn manager.
Definition: Game.cpp:102
PlayerAssignmentMap m_PlayerAssignments
Latest copy of player assignments heard from the server.
Definition: NetClient.h:209
void SetAndOwnSession(CNetClientSession *session)
Take ownership of a session object, and use it for all network communication.
Definition: NetClient.cpp:138
#define to_le32(x)
Definition: byte_order.h:78
Asynchronous file-receiving task.
CGame * m_Game
Definition: NetClient.h:193
static bool OnPlayerAssignment(void *context, CFsmEvent *event)
Definition: NetClient.cpp:433
virtual bool SendMessage(const CNetMessage *message)
Send a message to the server.
Definition: NetSession.cpp:164
u32 m_HostID
Unique-per-game identifier of this client, used to identify the sender of simulation commands...
Definition: NetClient.h:203
virtual void OnSyncError(u32 turn, const std::string &expectedHash)
Called when there has been an out-of-sync error.
void ResetState(u32 newCurrentTurn, u32 newReadyTurn)
void Flush()
Flush queued outgoing network messages.
Definition: NetSession.cpp:155
Special message type for updated to game startup settings.
Definition: NetMessage.h:134
void StartGame(const CScriptValRooted &attribs, const std::string &savedState)
Definition: Game.cpp:261
void SetUserName(const CStrW &username)
Set the user&#39;s name that will be displayed to all players.
Definition: NetClient.cpp:123
CStrW m_UserName
Definition: NetClient.h:194
ScriptInterface & GetScriptInterface() const
#define SAFE_DELETE(p)
delete memory ensuing from new and set the pointer to zero (thus making double-frees safe / a no-op) ...
bool undefined() const
Returns whether the value is uninitialised or is JSVAL_VOID.
Definition: ScriptVal.cpp:58
bool Eval(const char *code)
static bool OnJoinSyncEndCommandBatch(void *context, CFsmEvent *event)
Definition: NetClient.cpp:497
static bool OnGameSetup(void *context, CFsmEvent *event)
Definition: NetClient.cpp:415
i64 Status
Error handling system.
Definition: status.h:171
CStr m_GUID
Globally unique identifier to distinguish users beyond the lifetime of a single network session...
Definition: NetClient.h:212
bool Update(unsigned int eventType, void *pEventData)
Definition: fsm.cpp:393
void Poll()
Poll the connection for messages from the server and process them, and send any queued messages...
Definition: NetClient.cpp:149
std::string m_JoinSyncBuffer
Serialized game state received when joining an in-progress game.
Definition: NetClient.h:220
void SetCurrState(unsigned int state)
Definition: fsm.cpp:375
Status sys_generate_random_bytes(u8 *buf, size_t count)
generate high-quality random bytes.
Definition: unix.cpp:318
NetMessageType GetType() const
Retrieves the message type.
Definition: NetMessage.h:46
bool SerializeState(std::ostream &stream)
CScriptValRooted m_GameAttributes
Latest copy of game setup attributes heard from the server.
Definition: NetClient.h:206
The base class for all network messages exchanged within the game.
Definition: NetMessage.h:32
CNetFileTransferer & GetFileTransferer()
Definition: NetSession.h:86
void FinishedAllCommands(u32 turn, u32 turnLength)
Called when all commands for a given turn have been received.
CSimulation2 * GetSimulation2()
Get the pointer to the simulation2 object.
Definition: Game.h:136
bool GetProperty(jsval obj, const char *name, T &out)
Get the named property on the given object.
void CompressZLib(const std::string &data, std::string &out, bool includeLengthHeader)
Definition: Compress.cpp:25
bool HandleMessage(CNetMessage *message)
Call when a message has been received from the network.
Definition: NetClient.cpp:250
static bool OnJoinSyncStart(void *context, CFsmEvent *event)
Definition: NetClient.cpp:483
bool SetupConnection(const CStr &server)
Set up a connection to the remote networked server.
Definition: NetClient.cpp:130
bool m_Enabled
Whether the player is currently connected and active.
Definition: NetHost.h:42
unsigned int GetCurrState(void) const
Definition: fsm.h:154
#define PS_PROTOCOL_MAGIC_RESPONSE
Definition: NetMessages.h:30
const Status SKIPPED
Definition: status.h:392
Async task for receiving the initial game state when rejoining an in-progress network game...
Definition: NetClient.cpp:43
#define u32
Definition: types.h:41
Network client.
Definition: NetClient.h:57
CFsmTransition * AddTransition(unsigned int state, unsigned int eventType, unsigned int nextState)
Definition: fsm.cpp:272
void SendChatMessage(const std::wstring &text)
Definition: NetClient.cpp:243
bool UpdateFastForward()
Advance the simulation by as much as possible.
Implementation of CNetTurnManager for network clients.
static bool OnGameStart(void *context, CFsmEvent *event)
Definition: NetClient.cpp:459
void DecompressZLib(const std::string &data, std::string &out, bool includeLengthHeader)
Definition: Compress.cpp:50
Network client/server sessions.
#define LOGMESSAGERENDER
Definition: CLogger.h:33
jsval get() const
Returns the current value (or JSVAL_VOID if uninitialised).
Definition: ScriptVal.cpp:45
virtual void OnSimulationMessage(CSimulationMessage *msg)
Called by networking code when a simulation message is received.
Abstraction around a SpiderMonkey JSContext.
std::wstring ToString(jsval obj, bool pretty=false)
CScriptValRooted m_Data
Definition: NetMessage.h:145
bool SetProperty(jsval obj, const char *name, const T &value, bool constant=false, bool enumerate=true)
Set the named property on the given object.
unsigned int GetType(void) const
Definition: fsm.h:61
void SetFirstState(unsigned int firstState)
Definition: fsm.cpp:366
The client end of a network session.
Definition: NetSession.h:55
friend class CNetFileReceiveTask_ClientRejoin
Definition: NetClient.h:61
void * GetParamRef(void)
Definition: fsm.h:62
bool Connect(u16 port, const CStr &server)
Definition: NetSession.cpp:50
IReplayLogger & GetReplayLogger() const
Definition: Game.h:162
static enum @41 state
std::wstring TestReadGuiMessages()
Return a concatenation of all messages in the GUI queue, for test cases to easily verify the queue co...
Definition: NetClient.cpp:178
Special message type for simulation commands.
Definition: NetMessage.h:113
static bool OnHandshakeResponse(void *context, CFsmEvent *event)
Definition: NetClient.cpp:361