Leviathan  0.8.0.0
Leviathan game engine
Leviathan::NetworkClientInterface Class Referenceabstract

Class that encapsulates common networking functionality required by client programs. More...

#include <NetworkClientInterface.h>

+ Inheritance diagram for Leviathan::NetworkClientInterface:

Public Types

enum  CLIENT_CONNECTION_STATE {
  CLIENT_CONNECTION_STATE::None, CLIENT_CONNECTION_STATE::WaitingForOpening, CLIENT_CONNECTION_STATE::SentJoinRequest, CLIENT_CONNECTION_STATE::Connected,
  CLIENT_CONNECTION_STATE::Closed
}
 

Public Member Functions

DLLEXPORT NetworkClientInterface ()
 
virtual DLLEXPORT ~NetworkClientInterface ()
 
virtual DLLEXPORT void HandleRequestPacket (const std::shared_ptr< NetworkRequest > &request, Connection &connection) override
 Called by ConnectionInfo to handle incoming packets. More...
 
virtual DLLEXPORT void HandleResponseOnlyPacket (const std::shared_ptr< NetworkResponse > &message, Connection &connection) override
 Called by ConnectionInfo when it receives a response without a matching request object. More...
 
DLLEXPORT bool JoinServer (std::shared_ptr< Connection > connectiontouse)
 Connects the client to a server. More...
 
DLLEXPORT void DisconnectFromServer (const std::string &reason, bool connectiontimedout=false)
 Disconnects the client from the server or does nothing. More...
 
virtual DLLEXPORT std::vector< std::shared_ptr< Connection > > & GetClientConnections () override
 If this is a server returns all the clients. More...
 
DLLEXPORT void OnUpdateFullSynchronizationState (size_t variablesgot, size_t expectedvariables)
 Called directly by SyncedVariables to update the status string. More...
 
DLLEXPORT void SendCommandStringToServer (const std::string &messagestr)
 Sends a command string to the server. More...
 
virtual DLLEXPORT void CloseDown () override
 Closes all client related things. More...
 
DLLEXPORT bool IsConnected () const
 Returns true if the client is connected to a server. More...
 
virtual DLLEXPORT int GetOurID () const
 Returns the ID that the server has assigned to us. More...
 
virtual DLLEXPORT std::shared_ptr< ConnectionGetServerConnection ()
 Returns the active server connection or NULL. More...
 
DLLEXPORT void MarkForNotifyReceivedStates ()
 Marks a keep alive to be sent on next tick. More...
 
DLLEXPORT void TickIt () override
 Updates status of the client to server connections. More...
 
auto GetServerConnectionState () const
 
- Public Member Functions inherited from Leviathan::NetworkInterface
DLLEXPORT NetworkInterface (NETWORKED_TYPE type)
 
virtual DLLEXPORT ~NetworkInterface ()
 
virtual DLLEXPORT bool PreHandleResponse (const std::shared_ptr< NetworkResponse > &response, SentNetworkThing *originalrequest, Connection &connection)
 Called by ConnectionInfo to verify that a response is good. More...
 
virtual DLLEXPORT bool CanConnectionTerminate (Connection &connection)
 Called by Connection just before terminating an inactive connection. More...
 
DLLEXPORT void VerifyType (NETWORKED_TYPE type) const
 Asserts if types don't match. More...
 
NetworkHandlerGetOwner ()
 

Protected Member Functions

virtual DLLEXPORT void _OnDisconnectFromServer (const std::string &reasonstring, bool donebyus)
 
virtual DLLEXPORT void _OnStartConnectToServer ()
 
virtual DLLEXPORT void _OnFailedToConnectToServer (const std::string &reason)
 
virtual DLLEXPORT void _OnSuccessfullyConnectedToServer ()
 
virtual DLLEXPORT void _OnCloseDown ()
 
virtual DLLEXPORT void _OnNewConnectionStatusMessage (const std::string &message)
 Called when this class generates a new update message. More...
 
virtual DLLEXPORT WindowGetWindowForWorldJoin (const std::string &extraoptions)
 This is used to get the target window for a world that we have been notified that we have joined and will receive updates. More...
 
virtual DLLEXPORT std::shared_ptr< PhysicsMaterialManagerGetPhysicsMaterialsForReceivedWorld (int32_t worldtype, const std::string &extraoptions)
 This is called to get physics materials for a world. More...
 
virtual DLLEXPORT void _OnProperlyConnected ()=0
 Called when the server has confirmed the join and we are a player on the server. More...
 
DLLEXPORT std::shared_ptr< SentRequestDoJoinDefaultWorld ()
 This is a helper for _OnProperlyConnected to. More...
 
virtual DLLEXPORT void _OnWorldJoined (std::shared_ptr< GameWorld > world)
 Called when joining a world has succeeded and the client has created the clientside world object. This should attach the world to be drawn and do any special setup required on it. More...
 
virtual DLLEXPORT void _HandleWorldJoinResponse (int32_t worldid, int32_t worldtype, const std::string &extraoptions)
 This is called when we receive a packet from the server indicating that we should create a new world and expect to receive updates for it. More...
 
virtual DLLEXPORT GameWorld_GetWorldForEntityMessage (int32_t worldid)
 This needs to lookup a GameWorld for an entity update message by id. More...
 
virtual DLLEXPORT void _OnLocalControlChanged (GameWorld *world)
 Called when local control has been changed. More...
 
virtual DLLEXPORT void _OnEntityReceived (GameWorld *world, ObjectID created)
 Called when an entity creation packet has been passed to the GameWorld. More...
 
- Protected Member Functions inherited from Leviathan::NetworkInterface
virtual bool _CustomHandleRequestPacket (const std::shared_ptr< NetworkRequest > &request, Connection &connection)
 
virtual bool _CustomHandleResponseOnlyPacket (const std::shared_ptr< NetworkResponse > &message, Connection &connection)
 
DLLEXPORT bool _HandleDefaultRequest (const std::shared_ptr< NetworkRequest > &request, Connection &connectiontosendresult)
 Utility function for subclasses to call for default handling. More...
 
DLLEXPORT bool _HandleDefaultResponseOnly (const std::shared_ptr< NetworkResponse > &message, Connection &connection)
 Utility function for subclasses to call for default handling of non-request responses. More...
 
DLLEXPORT void SetOwner (NetworkHandler *owner)
 

Protected Attributes

std::vector< std::shared_ptr< SentRequest > > OurSentRequests
 This vector holds the made requests to allow using the response to do stuff. More...
 
CLIENT_CONNECTION_STATE ConnectState = CLIENT_CONNECTION_STATE::None
 
std::shared_ptr< ConnectionServerConnection
 
bool UsingHeartbeats = false
 Marks whether heartbeats are in use. More...
 
WantedClockType::time_point LastReceivedHeartbeat
 The last time a heartbeat packet was received. More...
 
WantedClockType::time_point LastSentHeartbeat
 The last time a heartbeat was sent. More...
 
bool KeepAliveQueued = false
 True when a keep alive should be sent on next tick. More...
 
float SecondsWithoutConnection = 0.f
 Holds the time for how long we have been without a heartbeat. More...
 
int OurPlayerID = -1
 Our player id, this is required for some requests. More...
 
std::shared_ptr< GameWorldOurReceivedWorld
 
- Protected Attributes inherited from Leviathan::NetworkInterface
NETWORKED_TYPE OurNetworkType
 
NetworkHandlerOwner = nullptr
 

Detailed Description

Class that encapsulates common networking functionality required by client programs.

More specific version of NetworkInterface and should be included additionally in client network interface classes.

See also
NetworkInterface

Definition at line 22 of file NetworkClientInterface.h.

Member Enumeration Documentation

◆ CLIENT_CONNECTION_STATE

Enumerator
None 

Not connected to a server.

WaitingForOpening 

JoinServer has been called and the client is now waiting for the connection object to become open

SentJoinRequest 

Sent join request, waiting for it to succeed.

Connected 

Properly connected.

Closed 

Client is leaving a server.

Definition at line 24 of file NetworkClientInterface.h.

24  {
25 
27  None,
28 
31  WaitingForOpening,
32 
34  SentJoinRequest,
35 
37  Connected,
38 
40  Closed
41  };
In this mode the View doesn&#39;t take any input under any circumstances.
Moves to this state once handshake is complete.

Constructor & Destructor Documentation

◆ NetworkClientInterface()

DLLEXPORT NetworkClientInterface::NetworkClientInterface ( )

Definition at line 22 of file NetworkClientInterface.cpp.

◆ ~NetworkClientInterface()

DLLEXPORT NetworkClientInterface::~NetworkClientInterface ( )
virtual

Definition at line 26 of file NetworkClientInterface.cpp.

26 {}

Member Function Documentation

◆ _GetWorldForEntityMessage()

DLLEXPORT GameWorld * NetworkClientInterface::_GetWorldForEntityMessage ( int32_t  worldid)
protectedvirtual

This needs to lookup a GameWorld for an entity update message by id.

The default implementation only looks at OurReceivedWorld

Definition at line 502 of file NetworkClientInterface.cpp.

503 {
504  if(OurReceivedWorld && OurReceivedWorld->GetID() == worldid)
505  return OurReceivedWorld.get();
506 
507  LOG_WARNING("NetworkClientInterface: failed to find world with id for entity update "
508  "message, id: " +
509  std::to_string(worldid));
510  return nullptr;
511 }
std::shared_ptr< GameWorld > OurReceivedWorld
#define LOG_WARNING(x)
Definition: Define.h:82

◆ _HandleWorldJoinResponse()

DLLEXPORT void NetworkClientInterface::_HandleWorldJoinResponse ( int32_t  worldid,
int32_t  worldtype,
const std::string &  extraoptions 
)
protectedvirtual

This is called when we receive a packet from the server indicating that we should create a new world and expect to receive updates for it.

Definition at line 467 of file NetworkClientInterface.cpp.

469 {
470  auto world = Engine::Get()->CreateWorld(GetWindowForWorldJoin(extraoptions), worldtype,
471  GetPhysicsMaterialsForReceivedWorld(worldtype, extraoptions),
473 
474  if(!world) {
475 
476  LOG_ERROR("NetworkClientInterface: _HandleWorldJoinResponse: failed to create world");
477  DisconnectFromServer("Cannot create requested world type");
478  return;
479  }
480 
481  world->SetServerForLocalControl(ServerConnection);
482 
483  OurReceivedWorld = world;
485 }
std::shared_ptr< GameWorld > OurReceivedWorld
#define LOG_ERROR(x)
Definition: Define.h:83
virtual DLLEXPORT Window * GetWindowForWorldJoin(const std::string &extraoptions)
This is used to get the target window for a world that we have been notified that we have joined and ...
virtual DLLEXPORT void _OnWorldJoined(std::shared_ptr< GameWorld > world)
Called when joining a world has succeeded and the client has created the clientside world object...
static WorldNetworkSettings GetSettingsForClient()
Creates settings for a client.
virtual DLLEXPORT std::shared_ptr< PhysicsMaterialManager > GetPhysicsMaterialsForReceivedWorld(int32_t worldtype, const std::string &extraoptions)
This is called to get physics materials for a world.
DLLEXPORT void DisconnectFromServer(const std::string &reason, bool connectiontimedout=false)
Disconnects the client from the server or does nothing.
static DLLEXPORT Engine * Get()
Definition: Engine.cpp:84
std::shared_ptr< Connection > ServerConnection
DLLEXPORT std::shared_ptr< GameWorld > CreateWorld(Window *owningwindow, int worldtype, const std::shared_ptr< PhysicsMaterialManager > &physicsMaterials, const WorldNetworkSettings &networking, int overrideid=-1)
Creates a GameWorld for placing entities into.
Definition: Engine.cpp:1173

◆ _OnCloseDown()

virtual DLLEXPORT void Leviathan::NetworkClientInterface::_OnCloseDown ( )
inlineprotectedvirtual

Definition at line 123 of file NetworkClientInterface.h.

123 {}

◆ _OnDisconnectFromServer()

virtual DLLEXPORT void Leviathan::NetworkClientInterface::_OnDisconnectFromServer ( const std::string &  reasonstring,
bool  donebyus 
)
inlineprotectedvirtual

Reimplemented in Pong::PongNetHandler.

Definition at line 116 of file NetworkClientInterface.h.

118  {}

◆ _OnEntityReceived()

DLLEXPORT void NetworkClientInterface::_OnEntityReceived ( GameWorld world,
ObjectID  created 
)
protectedvirtual

Called when an entity creation packet has been passed to the GameWorld.

Definition at line 519 of file NetworkClientInterface.cpp.

519 {}

◆ _OnFailedToConnectToServer()

virtual DLLEXPORT void Leviathan::NetworkClientInterface::_OnFailedToConnectToServer ( const std::string &  reason)
inlineprotectedvirtual

Definition at line 120 of file NetworkClientInterface.h.

120 {}

◆ _OnLocalControlChanged()

DLLEXPORT void NetworkClientInterface::_OnLocalControlChanged ( GameWorld world)
protectedvirtual

Called when local control has been changed.

Definition at line 513 of file NetworkClientInterface.cpp.

514 {
515  LOG_WARNING(
516  "NetworkClientInterface: base implementation of _OnLocalControlChanged called");
517 }
#define LOG_WARNING(x)
Definition: Define.h:82

◆ _OnNewConnectionStatusMessage()

virtual DLLEXPORT void Leviathan::NetworkClientInterface::_OnNewConnectionStatusMessage ( const std::string &  message)
inlineprotectedvirtual

Called when this class generates a new update message.

Reimplemented in Pong::PongNetHandler.

Definition at line 126 of file NetworkClientInterface.h.

126 {}

◆ _OnProperlyConnected()

virtual DLLEXPORT void Leviathan::NetworkClientInterface::_OnProperlyConnected ( )
protectedpure virtual

Called when the server has confirmed the join and we are a player on the server.

This is where the game needs to request joining a GameWorld or do some other game specific logic

Implemented in Pong::PongNetHandler.

◆ _OnStartConnectToServer()

virtual DLLEXPORT void Leviathan::NetworkClientInterface::_OnStartConnectToServer ( )
inlineprotectedvirtual

Definition at line 119 of file NetworkClientInterface.h.

119 {}

◆ _OnSuccessfullyConnectedToServer()

virtual DLLEXPORT void Leviathan::NetworkClientInterface::_OnSuccessfullyConnectedToServer ( )
inlineprotectedvirtual

Definition at line 121 of file NetworkClientInterface.h.

121 {}

◆ _OnWorldJoined()

DLLEXPORT void NetworkClientInterface::_OnWorldJoined ( std::shared_ptr< GameWorld world)
protectedvirtual

Called when joining a world has succeeded and the client has created the clientside world object. This should attach the world to be drawn and do any special setup required on it.

Definition at line 461 of file NetworkClientInterface.cpp.

462 {
463  LOG_WARNING(
464  "Joined world but OnWorldJoined is not overridden, the world won't be displayed");
465 }
#define LOG_WARNING(x)
Definition: Define.h:82

◆ CloseDown()

DLLEXPORT void NetworkClientInterface::CloseDown ( )
overridevirtual

Closes all client related things.

Implements Leviathan::NetworkInterface.

Definition at line 528 of file NetworkClientInterface.cpp.

529 {
530  _OnCloseDown();
531 
532  if(ServerConnection) {
533 
534  DisconnectFromServer("Game closing");
535  }
536 }
DLLEXPORT void DisconnectFromServer(const std::string &reason, bool connectiontimedout=false)
Disconnects the client from the server or does nothing.
std::shared_ptr< Connection > ServerConnection

◆ DisconnectFromServer()

DLLEXPORT void NetworkClientInterface::DisconnectFromServer ( const std::string &  reason,
bool  connectiontimedout = false 
)

Disconnects the client from the server or does nothing.

Todo:
Add a check to not close the connection if it is used by RemoteConsole

Definition at line 184 of file NetworkClientInterface.cpp.

186 {
187  // Return if no connection //
188  if(!ServerConnection) {
189 
190  LOG_WARNING("NetworkClientInterface: DisconnectFromServer: not connected "
191  "to any servers");
192  return;
193  }
194 
195  LOG_INFO("Client: disconnected from server, reason: " + reason);
196 
197  // Discard waiting requests //
198  OurSentRequests.clear();
199 
200  // Send disconnect message to server //
201  _OnNewConnectionStatusMessage("Disconnected from " +
202  ServerConnection->GenerateFormatedAddressString() +
203  ", reason: " + reason);
204 
205  // TODO: clear synced variables
206  // Owner->GetSyncedVariables()->Clear();
207 
208  // Close connection //
209  LOG_WRITE("TODO: send disconnect reason to server");
211 
212  if(ServerConnection) {
213  ServerConnection->SendCloseConnectionPacket();
214  }
215 
216  ServerConnection.reset();
217 
219  OurPlayerID = -1;
220 
221  _OnDisconnectFromServer(reason, connectiontimedout ? false : true);
222 }
#define LOG_INFO(x)
Definition: Define.h:81
std::vector< std::shared_ptr< SentRequest > > OurSentRequests
This vector holds the made requests to allow using the response to do stuff.
virtual DLLEXPORT void _OnNewConnectionStatusMessage(const std::string &message)
Called when this class generates a new update message.
int OurPlayerID
Our player id, this is required for some requests.
#define LOG_WARNING(x)
Definition: Define.h:82
#define LOG_WRITE(x)
Definition: Define.h:84
virtual DLLEXPORT void _OnDisconnectFromServer(const std::string &reasonstring, bool donebyus)
std::shared_ptr< Connection > ServerConnection
virtual DLLEXPORT void CloseConnection(Connection &connection)
Marks a connection as closing.

◆ DoJoinDefaultWorld()

DLLEXPORT std::shared_ptr< SentRequest > NetworkClientInterface::DoJoinDefaultWorld ( )
protected

This is a helper for _OnProperlyConnected to.

Definition at line 449 of file NetworkClientInterface.cpp.

450 {
452  LOG_ERROR("NetworkClientInterface: DoJoinDefaultWorld: not connected to a server");
453  return nullptr;
454  }
455 
456  LOG_INFO("NetworkClientInterface: requesting to join default world on server");
457  return ServerConnection->SendPacketToConnection(
458  std::make_shared<RequestJoinGame>(), RECEIVE_GUARANTEE::Critical);
459 }
#define LOG_INFO(x)
Definition: Define.h:81
#define LOG_ERROR(x)
Definition: Define.h:83
std::shared_ptr< Connection > ServerConnection

◆ GetClientConnections()

DLLEXPORT std::vector< std::shared_ptr< Leviathan::Connection > > & NetworkClientInterface::GetClientConnections ( )
overridevirtual

If this is a server returns all the clients.

Implements Leviathan::NetworkInterface.

Definition at line 225 of file NetworkClientInterface.cpp.

226 {
227  LOG_FATAL("Calling GetClientConnections on a client interface");
228  throw Exception("Calling GetClientConnections on a client interface");
229 }
#define LOG_FATAL(x)
Definition: Define.h:85
Base class for all exceptions thrown by Leviathan.
Definition: Exceptions.h:10

◆ GetOurID()

DLLEXPORT int NetworkClientInterface::GetOurID ( ) const
virtual

Returns the ID that the server has assigned to us.

Definition at line 622 of file NetworkClientInterface.cpp.

623 {
624  return OurPlayerID;
625 }
int OurPlayerID
Our player id, this is required for some requests.

◆ GetPhysicsMaterialsForReceivedWorld()

DLLEXPORT std::shared_ptr< PhysicsMaterialManager > NetworkClientInterface::GetPhysicsMaterialsForReceivedWorld ( int32_t  worldtype,
const std::string &  extraoptions 
)
protectedvirtual

This is called to get physics materials for a world.

If this returns null physics won't be initialized for the received world.

Definition at line 494 of file NetworkClientInterface.cpp.

496 {
497  LOG_INFO("NetworkClientInterface: default GetPhysicsMaterialsForReceivedWorld called, "
498  "world won't have physics");
499  return nullptr;
500 }
#define LOG_INFO(x)
Definition: Define.h:81

◆ GetServerConnection()

DLLEXPORT std::shared_ptr< Connection > NetworkClientInterface::GetServerConnection ( )
virtual

Returns the active server connection or NULL.

Definition at line 627 of file NetworkClientInterface.cpp.

628 {
629  return ServerConnection;
630 }
std::shared_ptr< Connection > ServerConnection

◆ GetServerConnectionState()

auto Leviathan::NetworkClientInterface::GetServerConnectionState ( ) const
inline

Definition at line 109 of file NetworkClientInterface.h.

110  {
111  return ConnectState;
112  }

◆ GetWindowForWorldJoin()

DLLEXPORT Window * NetworkClientInterface::GetWindowForWorldJoin ( const std::string &  extraoptions)
protectedvirtual

This is used to get the target window for a world that we have been notified that we have joined and will receive updates.

Definition at line 487 of file NetworkClientInterface.cpp.

489 {
490  return Engine::Get()->GetWindowEntity();
491 }
DLLEXPORT Window * GetWindowEntity()
Returns the main window.
Definition: Engine.h:155
static DLLEXPORT Engine * Get()
Definition: Engine.cpp:84

◆ HandleRequestPacket()

DLLEXPORT void NetworkClientInterface::HandleRequestPacket ( const std::shared_ptr< NetworkRequest > &  request,
Connection connection 
)
overridevirtual

Called by ConnectionInfo to handle incoming packets.

This function is responsible for interpreting the packet data and generating a response. If the response could take a long time to generate it is recommended to queue a task to the ThreadingManager.

Note
The connection parameter shouldn't be stored directly since it can become invalid after this function returns. Get a shared pointer from NetworkHandler instead

Implements Leviathan::NetworkInterface.

Definition at line 28 of file NetworkClientInterface.cpp.

30 {
31  if(_HandleDefaultRequest(request, connection))
32  return;
33 
34  // switch (request->GetType()) {
35  // }
36 
37  if(_CustomHandleRequestPacket(request, connection))
38  return;
39 
40  LOG_ERROR(
41  "NetworkClientInterface: failed to handle request of type: " + request->GetTypeStr());
42 }
#define LOG_ERROR(x)
Definition: Define.h:83
virtual bool _CustomHandleRequestPacket(const std::shared_ptr< NetworkRequest > &request, Connection &connection)
DLLEXPORT bool _HandleDefaultRequest(const std::shared_ptr< NetworkRequest > &request, Connection &connectiontosendresult)
Utility function for subclasses to call for default handling.

◆ HandleResponseOnlyPacket()

DLLEXPORT void NetworkClientInterface::HandleResponseOnlyPacket ( const std::shared_ptr< NetworkResponse > &  message,
Connection connection 
)
overridevirtual

Called by ConnectionInfo when it receives a response without a matching request object.

This is called when the host on the connection sends a response without a matching request. Usually the other program instance wants us to do something without expecting a response, for example they could want us to add a new message to our inbox without expecting a response (other than an ack which is automatically sent) from us. The function can optionally ignore keepalive acks (to reduce spam between clients) by setting dontmarkasreceived as true. This function shouldn't throw any exceptions.

Implements Leviathan::NetworkInterface.

Definition at line 44 of file NetworkClientInterface.cpp.

46 {
47  LEVIATHAN_ASSERT(message, "_HandleClientResponseOnly message is null");
48 
49  if(_HandleDefaultResponseOnly(message, connection))
50  return;
51 
52  switch(message->GetType()) {
54 
55  auto data = static_cast<ResponseStartWorldReceive*>(message.get());
56 
57  _HandleWorldJoinResponse(data->WorldID, data->WorldType, data->ExtraOptions);
58  return;
59  }
61  // We got a heartbeat //
62  _OnHeartbeat();
63  // Avoid spamming keep alive packets //
64  // dontmarkasreceived = true;
65  return;
66  }
68  // We need to start sending heartbeats //
69  _OnStartHeartbeats();
70  return;
71  }
73  auto data = static_cast<ResponseCacheUpdated*>(message.get());
74 
75  if(!Owner->GetCache()->HandleUpdatePacket(data)) {
76 
77  LOG_WARNING("NetworkClientInterface: applying AI cache "
78  "update failed");
79  }
80 
81  return;
82  }
84  auto data = static_cast<ResponseEntityCreation*>(message.get());
85 
86  auto world = _GetWorldForEntityMessage(data->WorldID);
87 
88  // TODO: this needs to be queued if we haven't received the world yet
89  if(!world) {
90  LOG_WARNING("NetworkClientInterface: no world found for EntityCreation. TODO: "
91  "queue this message");
92  return;
93  }
94 
95  ObjectID created = world->HandleEntityPacket(*data);
96 
97  if(created != NULL_OBJECT)
98  _OnEntityReceived(world, created);
99  return;
100  }
102  auto data = static_cast<ResponseEntityDestruction*>(message.get());
103 
104  auto world = _GetWorldForEntityMessage(data->WorldID);
105 
106  // TODO: this needs to be queued if we haven't received the world yet
107  if(!world) {
108  LOG_WARNING("NetworkClientInterface: no world found for EntityDestruction. TODO: "
109  "queue this message");
110  return;
111  }
112 
113  world->HandleEntityPacket(*data);
114  return;
115  }
117  auto data = static_cast<ResponseEntityUpdate*>(message.get());
118 
119  auto world = _GetWorldForEntityMessage(data->WorldID);
120 
121  // TODO: this needs to be queued if we haven't received the world yet
122  if(!world) {
123  LOG_WARNING("NetworkClientInterface: no world found for EntityUpdate. TODO: "
124  "queue this message");
125  return;
126  }
127 
128  world->HandleEntityPacket(std::move(*data), connection);
129  return;
130  }
132  auto data = static_cast<ResponseEntityLocalControlStatus*>(message.get());
133 
134  auto world = _GetWorldForEntityMessage(data->WorldID);
135 
136  // TODO: this needs to be queued if we haven't received the world yet
137  if(!world) {
138  LOG_WARNING(
139  "NetworkClientInterface: no world found for EntityLocalControlStatus. TODO: "
140  "queue this message");
141  return;
142  }
143 
144  world->HandleEntityPacket(*data);
145  _OnLocalControlChanged(world);
146  return;
147  }
148  default: break;
149  }
150 
151  if(_CustomHandleResponseOnlyPacket(message, connection))
152  return;
153 
154  LOG_ERROR("NetworkClientInterface: failed to handle response only of type: " +
155  message->GetTypeStr());
156 }
virtual DLLEXPORT void _OnLocalControlChanged(GameWorld *world)
Called when local control has been changed.
constexpr ObjectID NULL_OBJECT
Definition: EntityCommon.h:14
int32_t ObjectID
Definition: EntityCommon.h:11
#define LOG_ERROR(x)
Definition: Define.h:83
virtual DLLEXPORT void _HandleWorldJoinResponse(int32_t worldid, int32_t worldtype, const std::string &extraoptions)
This is called when we receive a packet from the server indicating that we should create a new world ...
virtual DLLEXPORT void _OnEntityReceived(GameWorld *world, ObjectID created)
Called when an entity creation packet has been passed to the GameWorld.
Contains an updated cache variable.
#define LOG_WARNING(x)
Definition: Define.h:82
DLLEXPORT bool HandleUpdatePacket(ResponseCacheUpdated *data)
Handles an update packet.
DLLEXPORT bool _HandleDefaultResponseOnly(const std::shared_ptr< NetworkResponse > &message, Connection &connection)
Utility function for subclasses to call for default handling of non-request responses.
Contains (list) an ID for entity to be deleted.
Contains information about a world that is about to be sent to the client.
virtual DLLEXPORT GameWorld * _GetWorldForEntityMessage(int32_t worldid)
This needs to lookup a GameWorld for an entity update message by id.
Marks that the client is required to send heartbeats.
NetworkCache * GetCache()
virtual bool _CustomHandleResponseOnlyPacket(const std::shared_ptr< NetworkResponse > &message, Connection &connection)
A new entity was created on the server.

◆ IsConnected()

DLLEXPORT bool NetworkClientInterface::IsConnected ( ) const

Returns true if the client is connected to a server.

This will be true when the server has responded to our join request and allowed us to join, we aren't actually yet playing on the server

Definition at line 561 of file NetworkClientInterface.cpp.

◆ JoinServer()

DLLEXPORT bool NetworkClientInterface::JoinServer ( std::shared_ptr< Connection connectiontouse)

Connects the client to a server.

Returns
Returns true when successfully started the join process, false if already connected (and DisconnectFromServer should be called)
Parameters
connectiontouseThe connection object should be retrieved by calling NetworkHandler::GetOrCreatePointerToConnection

Definition at line 158 of file NetworkClientInterface.cpp.

159 {
160  // Fail if already connected //
161  if(ServerConnection) {
162 
163  LOG_ERROR("NetworkClientInterface: JoinServer: trying to join a server "
164  "while connected to another");
165  DisconnectFromServer("Trying to connect to another server");
166  return false;
167  }
168 
169  // Store the connection //
170  ServerConnection = connectiontouse;
171 
172  KeepAliveQueued = false;
173  UsingHeartbeats = false;
174 
176 
177  // Send message //
178  _OnNewConnectionStatusMessage("Trying to connect to a server on " +
179  ServerConnection->GenerateFormatedAddressString());
180 
181  return true;
182 }
bool KeepAliveQueued
True when a keep alive should be sent on next tick.
#define LOG_ERROR(x)
Definition: Define.h:83
virtual DLLEXPORT void _OnNewConnectionStatusMessage(const std::string &message)
Called when this class generates a new update message.
bool UsingHeartbeats
Marks whether heartbeats are in use.
DLLEXPORT void DisconnectFromServer(const std::string &reason, bool connectiontimedout=false)
Disconnects the client from the server or does nothing.
std::shared_ptr< Connection > ServerConnection

◆ MarkForNotifyReceivedStates()

DLLEXPORT void NetworkClientInterface::MarkForNotifyReceivedStates ( )

Marks a keep alive to be sent on next tick.

Definition at line 632 of file NetworkClientInterface.cpp.

633 {
634  KeepAliveQueued = true;
635 }
bool KeepAliveQueued
True when a keep alive should be sent on next tick.

◆ OnUpdateFullSynchronizationState()

DLLEXPORT void NetworkClientInterface::OnUpdateFullSynchronizationState ( size_t  variablesgot,
size_t  expectedvariables 
)

Called directly by SyncedVariables to update the status string.

Definition at line 521 of file NetworkClientInterface.cpp.

523 {
524  _OnNewConnectionStatusMessage("Syncing variables, " + Convert::ToString(variablesgot) +
525  "/" + Convert::ToString(expectedvariables));
526 }
virtual DLLEXPORT void _OnNewConnectionStatusMessage(const std::string &message)
Called when this class generates a new update message.
static std::string ToString(const T &val)
Definition: Convert.h:72

◆ SendCommandStringToServer()

DLLEXPORT void NetworkClientInterface::SendCommandStringToServer ( const std::string &  messagestr)

Sends a command string to the server.

It should always be assumed that this function works. If it doesn't it is guaranteed that the client kicks itself because the connection is lost.

Exceptions
ExceptionInvalidStateif not connected to a server The maximum length is MAX_SERVERCOMMAND_LENGTH should be around 550 characters.
ExceptionInvalidArgumentwhen the message string is too long

Definition at line 538 of file NetworkClientInterface.cpp.

539 {
540  // Make sure that we are connected to a server //
542 
543  throw InvalidState("cannot send command because we aren't connected to a server");
544  }
545 
546  // Check the length //
547  if(messagestr.length() >= MAX_SERVERCOMMAND_LENGTH) {
548 
549  throw InvalidArgument("server command is too long");
550  }
551 
552  // Send it //
553  auto sendthing = ServerConnection->SendPacketToConnection(
554  std::make_shared<RequestRequestCommandExecution>(messagestr),
556 
557  // The packet may not fail so we need to monitor the response //
558  OurSentRequests.push_back(sendthing);
559 }
std::vector< std::shared_ptr< SentRequest > > OurSentRequests
This vector holds the made requests to allow using the response to do stuff.
constexpr auto MAX_SERVERCOMMAND_LENGTH
Definition: Define.h:32
std::shared_ptr< Connection > ServerConnection

◆ TickIt()

DLLEXPORT void NetworkClientInterface::TickIt ( )
overridevirtual

Updates status of the client to server connections.

Note
Should be called by NetworkInterface::TickIt

Implements Leviathan::NetworkInterface.

Definition at line 291 of file NetworkClientInterface.cpp.

292 {
293  _TickServerConnectionState();
294 
295 sentrequestloopbegin:
296 
297  // Check status of requests //
298  for(auto iter = OurSentRequests.begin(); iter != OurSentRequests.end();) {
299 
300  // Check can we handle it //
301  if((*iter)->IsFinalized()) {
302 
303  // Store a copy and delete from the vector //
304  auto tmpsendthing = *iter;
305  iter = OurSentRequests.erase(iter);
306 
307  // Handle the request //
308  if(!(*iter)->GetStatus() || !(*iter)->GotResponse) {
309  // It failed //
310 
311  Logger::Get()->Warning("NetworkClientInterface: request to server failed, "
312  "possibly retrying:");
313 
314  _ProcessFailedRequest(tmpsendthing, tmpsendthing->GotResponse);
315  } else {
316 
317  Logger::Get()->Info("Received a response to client request");
318 
319  // Handle it //
320  _ProcessCompletedRequest(tmpsendthing, tmpsendthing->GotResponse);
321  }
322 
323  // We need to loop again, because our iterator is now invalid, because
324  // quite often failed things are retried
325  goto sentrequestloopbegin;
326  }
327 
328  // Can't handle, continue looping //
329  ++iter;
330  }
331 }
std::vector< std::shared_ptr< SentRequest > > OurSentRequests
This vector holds the made requests to allow using the response to do stuff.
DLLEXPORT void Info(const std::string &data) override
Definition: Logger.cpp:164
DLLEXPORT void Warning(const std::string &data) override
Definition: Logger.cpp:190
static DLLEXPORT Logger * Get()
Definition: Logger.cpp:106

Member Data Documentation

◆ ConnectState

CLIENT_CONNECTION_STATE Leviathan::NetworkClientInterface::ConnectState = CLIENT_CONNECTION_STATE::None
protected

Definition at line 203 of file NetworkClientInterface.h.

◆ KeepAliveQueued

bool Leviathan::NetworkClientInterface::KeepAliveQueued = false
protected

True when a keep alive should be sent on next tick.

Definition at line 216 of file NetworkClientInterface.h.

◆ LastReceivedHeartbeat

WantedClockType::time_point Leviathan::NetworkClientInterface::LastReceivedHeartbeat
protected

The last time a heartbeat packet was received.

Definition at line 210 of file NetworkClientInterface.h.

◆ LastSentHeartbeat

WantedClockType::time_point Leviathan::NetworkClientInterface::LastSentHeartbeat
protected

The last time a heartbeat was sent.

Definition at line 213 of file NetworkClientInterface.h.

◆ OurPlayerID

int Leviathan::NetworkClientInterface::OurPlayerID = -1
protected

Our player id, this is required for some requests.

Definition at line 224 of file NetworkClientInterface.h.

◆ OurReceivedWorld

std::shared_ptr<GameWorld> Leviathan::NetworkClientInterface::OurReceivedWorld
protected

Our current received world. This is kept here to automatically apply update messages to it.

Definition at line 228 of file NetworkClientInterface.h.

◆ OurSentRequests

std::vector<std::shared_ptr<SentRequest> > Leviathan::NetworkClientInterface::OurSentRequests
protected

This vector holds the made requests to allow using the response to do stuff.

Definition at line 201 of file NetworkClientInterface.h.

◆ SecondsWithoutConnection

float Leviathan::NetworkClientInterface::SecondsWithoutConnection = 0.f
protected

Holds the time for how long we have been without a heartbeat.

Definition at line 220 of file NetworkClientInterface.h.

◆ ServerConnection

std::shared_ptr<Connection> Leviathan::NetworkClientInterface::ServerConnection
protected

Definition at line 204 of file NetworkClientInterface.h.

◆ UsingHeartbeats

bool Leviathan::NetworkClientInterface::UsingHeartbeats = false
protected

Marks whether heartbeats are in use.

Definition at line 207 of file NetworkClientInterface.h.


The documentation for this class was generated from the following files: