Pyrogenesis  13997
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
NetSession.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 #include "NetSession.h"
20 #include "NetClient.h"
21 #include "NetServer.h"
22 #include "NetMessage.h"
23 #include "NetStats.h"
25 #include "ps/CLogger.h"
27 
28 static const int CHANNEL_COUNT = 1;
29 
31  m_Client(client), m_FileTransferer(this), m_Host(NULL), m_Server(NULL), m_Stats(NULL)
32 {
33 }
34 
36 {
37  delete m_Stats;
38 
39  if (m_Host && m_Server)
40  {
41  // Disconnect immediately (we can't wait for acks)
42  enet_peer_disconnect_now(m_Server, NDR_UNEXPECTED_SHUTDOWN);
43  enet_host_destroy(m_Host);
44 
45  m_Host = NULL;
46  m_Server = NULL;
47  }
48 }
49 
50 bool CNetClientSession::Connect(u16 port, const CStr& server)
51 {
52  ENSURE(!m_Host);
53  ENSURE(!m_Server);
54 
55  // Create ENet host
56  ENetHost* host = enet_host_create(NULL, 1, CHANNEL_COUNT, 0, 0);
57  if (!host)
58  return false;
59 
60  // Bind to specified host
61  ENetAddress addr;
62  addr.port = port;
63  if (enet_address_set_host(&addr, server.c_str()) < 0)
64  return false;
65 
66  // Initiate connection to server
67  ENetPeer* peer = enet_host_connect(host, &addr, CHANNEL_COUNT, 0);
68  if (!peer)
69  return false;
70 
71  m_Host = host;
72  m_Server = peer;
73 
76  g_ProfileViewer.AddRootTable(m_Stats);
77 
78  return true;
79 }
80 
82 {
84 
85  // TODO: ought to do reliable async disconnects, probably
86  enet_peer_disconnect_now(m_Server, reason);
87  enet_host_destroy(m_Host);
88 
89  m_Host = NULL;
90  m_Server = NULL;
91 
93 }
94 
96 {
97  PROFILE3("net client poll");
98 
100 
102 
103  ENetEvent event;
104  while (enet_host_service(m_Host, &event, 0) > 0)
105  {
106  switch (event.type)
107  {
108  case ENET_EVENT_TYPE_CONNECT:
109  {
110  ENSURE(event.peer == m_Server);
111 
112  // Report the server address
113  char hostname[256] = "(error)";
114  enet_address_get_host_ip(&event.peer->address, hostname, ARRAY_SIZE(hostname));
115  LOGMESSAGE(L"Net client: Connected to %hs:%u", hostname, (unsigned int)event.peer->address.port);
116 
118 
119  break;
120  }
121 
122  case ENET_EVENT_TYPE_DISCONNECT:
123  {
124  ENSURE(event.peer == m_Server);
125 
126  LOGMESSAGE(L"Net client: Disconnected");
127  m_Client.HandleDisconnect(event.data);
128  return;
129  }
130 
131  case ENET_EVENT_TYPE_RECEIVE:
132  {
133  CNetMessage* msg = CNetMessageFactory::CreateMessage(event.packet->data, event.packet->dataLength, m_Client.GetScriptInterface());
134  if (msg)
135  {
136  LOGMESSAGE(L"Net client: Received message %hs of size %lu from server", msg->ToString().c_str(), (unsigned long)msg->GetSerializedLength());
137 
138  m_Client.HandleMessage(msg);
139 
140  delete msg;
141  }
142 
143  enet_packet_destroy(event.packet);
144 
145  break;
146  }
147 
148  case ENET_EVENT_TYPE_NONE:
149  break;
150  }
151  }
152 
153 }
154 
156 {
157  PROFILE3("net client flush");
158 
159  ENSURE(m_Host && m_Server);
160 
161  enet_host_flush(m_Host);
162 }
163 
165 {
166  ENSURE(m_Host && m_Server);
167 
168  return CNetHost::SendMessage(message, m_Server, "server");
169 }
170 
171 
172 
174  m_Server(server), m_FileTransferer(this), m_Peer(peer)
175 {
176 }
177 
179 {
180  Update((uint)NMT_CONNECTION_LOST, NULL);
181 
182  enet_peer_disconnect(m_Peer, reason);
183 }
184 
186 {
187  enet_peer_disconnect_now(m_Peer, reason);
188 }
189 
191 {
192  return m_Server.SendMessage(m_Peer, message);
193 }
ScriptInterface & GetScriptInterface()
Get the script interface associated with this network client, which is equivalent to the one used by ...
Definition: NetClient.cpp:191
CNetFileTransferer m_FileTransferer
Definition: NetSession.h:91
void DisconnectNow(u32 reason)
Sends an unreliable disconnection notification to the client.
Definition: NetSession.cpp:185
void Poll()
Process queued incoming messages.
Definition: NetSession.cpp:95
virtual bool SendMessage(const CNetMessage *message)
Send a message to the client.
Definition: NetSession.cpp:190
#define LOGMESSAGE
Definition: CLogger.h:32
static const int CHANNEL_COUNT
Definition: NetSession.cpp:28
void Disconnect(u32 reason)
Sends a disconnection notification to the client, and sends a NMT_CONNECTION_LOST message to the sess...
Definition: NetSession.cpp:178
struct _ENetPeer ENetPeer
Definition: NetHost.h:30
static bool SendMessage(const CNetMessage *message, ENetPeer *peer, const char *peerName)
Transmit a message to the given peer.
Definition: NetHost.cpp:26
#define ARRAY_SIZE(name)
void HandleConnect()
Call when the network connection has been successfully initiated.
Definition: NetClient.cpp:224
CNetClientSession(CNetClient &client)
Definition: NetSession.cpp:30
CNetServerSession(CNetServerWorker &server, ENetPeer *peer)
Definition: NetSession.cpp:173
void HandleDisconnect(u32 reason)
Call when the network connection has been lost.
Definition: NetClient.cpp:229
CNetServerWorker & m_Server
Definition: NetSession.h:148
ENetHost * m_Host
Definition: NetSession.h:93
#define ENSURE(expr)
ensure the expression &lt;expr&gt; evaluates to non-zero.
Definition: debug.h:282
ENetPeer * m_Peer
Definition: NetSession.h:152
virtual bool SendMessage(const CNetMessage *message)
Send a message to the server.
Definition: NetSession.cpp:164
void Flush()
Flush queued outgoing network messages.
Definition: NetSession.cpp:155
#define SAFE_DELETE(p)
delete memory ensuing from new and set the pointer to zero (thus making double-frees safe / a no-op) ...
ENet connection statistics profiler table.
Definition: NetStats.h:36
static bool IsInitialised()
Definition: Singleton.h:63
bool Update(unsigned int eventType, void *pEventData)
Definition: fsm.cpp:393
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:250
#define u16
Definition: types.h:40
void Poll()
Call frequently (e.g.
#define PROFILE3(name)
Definition: Profile.h:201
#define u32
Definition: types.h:41
Network client.
Definition: NetClient.h:57
virtual size_t GetSerializedLength() const
Retrieves the size in bytes of the serialized message.
Definition: NetMessage.cpp:78
struct _ENetHost ENetHost
Definition: NetHost.h:32
#define g_ProfileViewer
Network client/server sessions.
CNetStatsTable * m_Stats
Definition: NetSession.h:95
ENetPeer * m_Server
Definition: NetSession.h:94
bool SendMessage(ENetPeer *peer, const CNetMessage *message)
Send a message to the given network peer.
Definition: NetServer.cpp:188
void Disconnect(u32 reason)
Disconnect from the server.
Definition: NetSession.cpp:81
CNetClient & m_Client
Definition: NetSession.h:89
Network server worker thread.
Definition: NetServer.h:160
bool Connect(u16 port, const CStr &server)
Definition: NetSession.cpp:50
static CNetMessage * CreateMessage(const void *pData, size_t dataSize, ScriptInterface &scriptInterface)
Factory method which creates a message object based on the given data.
Definition: NetMessage.cpp:94
virtual CStr ToString() const
Returns a string representation for the message.
Definition: NetMessage.cpp:84