diff options
author | Guillaume Melquiond <guillaume.melquiond@gmail.com> | 2006-05-19 06:00:30 +0000 |
---|---|---|
committer | Guillaume Melquiond <guillaume.melquiond@gmail.com> | 2006-05-19 06:00:30 +0000 |
commit | 149efe91e50bf0e298761bb941e20ce4d8362314 (patch) | |
tree | 33b35c8374c919332622d98a8bac66096c8b5fe3 /src/connectionhandler.cpp | |
parent | ede341d0d121a842ad6ec8060931863cdc8021c1 (diff) | |
download | manaserv-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.cpp | 203 |
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 < <d->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) |