diff options
author | Stijn Buys <ingar@osirion.org> | 2008-02-16 12:22:33 +0000 |
---|---|---|
committer | Stijn Buys <ingar@osirion.org> | 2008-02-16 12:22:33 +0000 |
commit | d6ee7ec642cc6b3097c8d321a1a00630e24027d1 (patch) | |
tree | 35f56e5168cc3e12724898b9efb81b4b2938f575 /src/core/netconnection.cc | |
parent | 715d0c3952a3a1d59b64074e472d0a9a3b414351 (diff) |
initial client-to-server connection
Diffstat (limited to 'src/core/netconnection.cc')
-rw-r--r-- | src/core/netconnection.cc | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/src/core/netconnection.cc b/src/core/netconnection.cc new file mode 100644 index 0000000..85c0534 --- /dev/null +++ b/src/core/netconnection.cc @@ -0,0 +1,148 @@ +/* + net/netconnection.cc + This file is part of the Osirion project and is distributed under + the terms of the GNU General Public License version 2 +*/ + +#include <sstream> + +#include "sys/sys.h" +#include "net/net.h" +#include "core/netconnection.h" +#include "core/player.h" + +namespace core +{ + +NetConnection::NetConnection() +{ +} + +NetConnection::~NetConnection() +{ +} + +void NetConnection::connect(std::string const &to_host, int to_port) +{ + TCPConnection::connect(to_host, to_port); + if(connected()) { + FD_ZERO(&clientset); + FD_SET(fd(), &clientset); + } + + std::ostringstream osstream; + osstream << "name " << localplayer.name << std::endl; + send(osstream.str()); +} + +void NetConnection::disconnect() +{ + TCPConnection::disconnect(); + FD_ZERO(&clientset); +} + +bool NetConnection::has_messages() const +{ + return (recvq.size() > 0); +} + +void NetConnection::retreive(std::string & message) +{ + if (recvq.size() > 0) { + message.assign(recvq.front()); + recvq.pop_front(); + } else { + message.clear(); + } +} + +// receive data and decode it into lines +void NetConnection::receive() +{ + // TODO: binary mode data transfer + std::string datablock; + TCPConnection::receive(datablock); + + if (error()) + return; + while (datablock.size() > 0) { + // scan the datablock for enters + if (datablock[0] == '\n' || datablock[0] == '\r') { + if (messageblock.size() > 0) { + recvq.push_back(messageblock); + messageblock.clear(); + } + } else { + if (messageblock.size() < net::FRAMESIZE) { + messageblock.append(datablock.substr(0,1)); + } else { + con_warn << "Network message exceeds " << net::FRAMESIZE << " bytes!" << std::endl; + messageblock.clear(); + } + } + datablock.erase(0,1); + } + datablock.clear(); +} + +void NetConnection::frame(float seconds) +{ + timeval timeout; + timeout.tv_sec = 0; + timeout.tv_usec = 0; + fd_set readset = clientset; + + int nb = select(fd()+1, &readset, NULL, NULL, &timeout); + if (nb == 0) + return; + + if (nb == -1) { + con_error << "Network error on select()" << std::endl; + //perror("select"); + abort(); + } + + if (FD_ISSET(this->fd(), &readset) && !error()) { + receive(); + while (has_messages()) { + std::string message; + retreive(message); + parse_incoming_message(message); + } + } +} + +// parse incoming client messages +/** + * The following incoming messages are parsed; + * + * msg info <text> + * msg public <name> <text> + */ +void NetConnection::parse_incoming_message(const std::string & message) +{ + std::istringstream msgstream(message); + + std::string command; + msgstream >> command; + + if (command == "msg") { + std::string level; + if (msgstream >> level) { + if (level =="info") { + if (message.size() > 9) { + con_print << message.substr(9) << std::endl; + } + } else if (level == "public") { + // FIXME - separate sender nickname + if (message.size() > 11) { + con_print << message.substr(11) << std::endl; + } + + } + } + } + +} + +} |