summaryrefslogtreecommitdiff
path: root/src/connectionhandler.cpp
diff options
context:
space:
mode:
authorGuillaume Melquiond <guillaume.melquiond@gmail.com>2006-05-19 06:00:30 +0000
committerGuillaume Melquiond <guillaume.melquiond@gmail.com>2006-05-19 06:00:30 +0000
commit149efe91e50bf0e298761bb941e20ce4d8362314 (patch)
tree33b35c8374c919332622d98a8bac66096c8b5fe3 /src/connectionhandler.cpp
parentede341d0d121a842ad6ec8060931863cdc8021c1 (diff)
downloadmanaserv-149efe91e50bf0e298761bb941e20ce4d8362314.tar.gz
manaserv-149efe91e50bf0e298761bb941e20ce4d8362314.tar.bz2
manaserv-149efe91e50bf0e298761bb941e20ce4d8362314.tar.xz
manaserv-149efe91e50bf0e298761bb941e20ce4d8362314.zip
Switched to a monothreaded server. Fixed segfaults after disconnect.
Removed netsession.
Diffstat (limited to 'src/connectionhandler.cpp')
-rw-r--r--src/connectionhandler.cpp203
1 files changed, 105 insertions, 98 deletions
diff --git a/src/connectionhandler.cpp b/src/connectionhandler.cpp
index e7ef6b9f..1da0b830 100644
--- a/src/connectionhandler.cpp
+++ b/src/connectionhandler.cpp
@@ -27,7 +27,6 @@
#include "messagein.h"
#include "messageout.h"
#include "netcomputer.h"
-#include "netsession.h"
#include "packet.h"
#include "utils/logger.h"
@@ -93,121 +92,129 @@ ClientData::ClientData():
{
}
-ConnectionHandler::ConnectionHandler()
+bool
+ConnectionHandler::startListen(enet_uint16 port)
{
+ // Bind the server to the default localhost.
+ address.host = ENET_HOST_ANY;
+ address.port = port;
+
+ LOG_INFO("Listening on port " << port << "...", 0);
+ host = enet_host_create(&address /* the address to bind the server host to */,
+ MAX_CLIENTS /* allow up to MAX_CLIENTS clients and/or outgoing connections */,
+ 0 /* assume any amount of incoming bandwidth */,
+ 0 /* assume any amount of outgoing bandwidth */);
+
+ return host;
}
void
-ConnectionHandler::startListen(ListenThreadData *ltd)
+ConnectionHandler::stopListen()
{
- while (ltd->running)
- {
- ENetEvent event;
-
- // Wait up to 1000 milliseconds for an event.
- while (enet_host_service(ltd->host, &event, 1000) > 0)
- {
- switch (event.type)
- {
- case ENET_EVENT_TYPE_CONNECT:
- {
- LOG_INFO("A new client connected from " <<
- ip4ToString(event.peer->address.host) << ":" <<
- event.peer->address.port, 0);
- NetComputer *comp = new NetComputer(this, event.peer);
- clients.push_back(comp);
- computerConnected(comp);
- /*LOG_INFO(ltd->host->peerCount <<
- " client(s) connected", 0);*/
-
- // Store any relevant client information here.
- event.peer->data = (void *)comp;
- } break;
-
- case ENET_EVENT_TYPE_RECEIVE:
- {
- LOG_INFO("A packet of length " << event.packet->dataLength
- << " was received from " << event.peer->address.host,
- 2);
-
- NetComputer *comp = (NetComputer *)event.peer->data;
-
-#ifdef SCRIPT_SUPPORT
- // This could be good if you wanted to extend the
- // server protocol using a scripting language. This
- // could be attained by using allowing scripts to
- // "hook" certain messages.
-
- //script->message(buffer);
-#endif
-
- // If the scripting subsystem didn't hook the message
- // it will be handled by the default message handler.
-
- // Convert the client IP address to string
- // representation
- std::string ipaddr = ip4ToString(event.peer->address.host);
-
- // Make sure that the packet is big enough (> short)
- if (event.packet->dataLength >= 2)
- {
- Packet *packet = new Packet((char *)event.packet->data,
- event.packet->dataLength);
- MessageIn msg(packet); // (MessageIn frees packet)
-
- short messageId = msg.getId();
-
- if (handlers.find(messageId) != handlers.end())
- {
- // send message to appropriate handler
- handlers[messageId]->receiveMessage(*comp, msg);
- }
- else {
- // bad message (no registered handler)
- LOG_ERROR("Unhandled message (" << messageId
- << ") received from " << ipaddr, 0);
- }
- }
- else {
- LOG_ERROR("Message too short from " << ipaddr, 0);
- }
-
- /* Clean up the packet now that we're done using it. */
- enet_packet_destroy(event.packet);
- } break;
-
- case ENET_EVENT_TYPE_DISCONNECT:
- {
- NetComputer *comp = (NetComputer *)event.peer->data;
- /*LOG_INFO(event.peer->address.host
- << " disconected.", 0);*/
- // Reset the peer's client information.
- computerDisconnected(comp);
- delete comp;
- event.peer->data = NULL;
- } break;
-
- default: break;
- }
- }
- }
-
// - Disconnect all clients (close sockets)
// TODO: probably there's a better way.
ENetPeer *currentPeer;
- for (currentPeer = ltd->host->peers;
- currentPeer < &ltd->host->peers[ltd->host->peerCount];
+ for (currentPeer = host->peers;
+ currentPeer < &host->peers[host->peerCount];
++currentPeer)
{
if (currentPeer->state == ENET_PEER_STATE_CONNECTED)
{
enet_peer_disconnect(currentPeer, 0);
- enet_host_flush(ltd->host);
+ enet_host_flush(host);
enet_peer_reset(currentPeer);
}
}
+ enet_host_destroy(host);
+}
+
+void
+ConnectionHandler::process()
+{
+ ENetEvent event;
+ // Process Enet events and do not block.
+ while (enet_host_service(host, &event, 0) > 0) {
+ switch (event.type) {
+ case ENET_EVENT_TYPE_CONNECT:
+ {
+ LOG_INFO("A new client connected from " <<
+ ip4ToString(event.peer->address.host) << ":" <<
+ event.peer->address.port, 0);
+ NetComputer *comp = new NetComputer(this, event.peer);
+ clients.push_back(comp);
+ computerConnected(comp);
+ /*LOG_INFO(ltd->host->peerCount <<
+ " client(s) connected", 0);*/
+
+ // Store any relevant client information here.
+ event.peer->data = (void *)comp;
+ } break;
+
+ case ENET_EVENT_TYPE_RECEIVE:
+ {
+ LOG_INFO("A packet of length " << event.packet->dataLength <<
+ " was received from " << event.peer->address.host, 2);
+
+ NetComputer *comp = (NetComputer *)event.peer->data;
+
+#ifdef SCRIPT_SUPPORT
+ // This could be good if you wanted to extend the
+ // server protocol using a scripting language. This
+ // could be attained by using allowing scripts to
+ // "hook" certain messages.
+
+ //script->message(buffer);
+#endif
+
+ // If the scripting subsystem didn't hook the message
+ // it will be handled by the default message handler.
+
+ // Convert the client IP address to string
+ // representation
+ std::string ipaddr = ip4ToString(event.peer->address.host);
+
+ // Make sure that the packet is big enough (> short)
+ if (event.packet->dataLength >= 2) {
+ Packet *packet = new Packet((char *)event.packet->data,
+ event.packet->dataLength);
+ MessageIn msg(packet); // (MessageIn frees packet)
+
+ short messageId = msg.getId();
+
+ HandlerMap::iterator it = handlers.find(messageId);
+ if (it != handlers.end()) {
+ // send message to appropriate handler
+ it->second->receiveMessage(*comp, msg);
+ } else {
+ // bad message (no registered handler)
+ LOG_ERROR("Unhandled message (" << messageId
+ << ") received from " << ipaddr, 0);
+ }
+ } else {
+ LOG_ERROR("Message too short from " << ipaddr, 0);
+ }
+
+ /* Clean up the packet now that we're done using it. */
+ enet_packet_destroy(event.packet);
+ } break;
+
+ case ENET_EVENT_TYPE_DISCONNECT:
+ {
+ NetComputer *comp = (NetComputer *)event.peer->data;
+ /*LOG_INFO(event.peer->address.host
+ << " disconected.", 0);*/
+ // Reset the peer's client information.
+ computerDisconnected(comp);
+ delete comp;
+ clients.erase(std::find(clients.begin(), clients.end(), comp));
+ event.peer->data = NULL;
+ } break;
+
+ default: break;
+ }
+ }
}
void ConnectionHandler::computerConnected(NetComputer *comp)