/*************************************************************************** kbattleshipserver.cpp ------------------- Developers: (c) 2000-2001 Nikolas Zimmermann (c) 2000-2001 Daniel Molkentin ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include #include #ifdef HAVE_STROPTS_H #include #endif #ifdef HAVE_SYS_FILIO_H #include #endif #include #include #include #include #include "kbattleshipserver.moc" KBattleshipServer::KBattleshipServer(int port, const TQString& name) : KExtendedSocket(TQString(), port, inetSocket | passiveSocket), m_name(name) { m_port = port; m_serverSocket = 0; } void KBattleshipServer::init() { if(listen()) { KMessageBox::error(0L, i18n("Failed to bind to local port \"%1\"\n\nPlease check if another KBattleship server instance\nis running or another application uses this port.").arg(m_port)); emit sigServerFailure(); return; } m_service.setServiceName(m_name); m_service.setType(BATTLESHIP_SERVICE); m_service.setPort(m_port); m_service.publishAsync(); m_connectNotifier = new TQSocketNotifier(fd(), TQSocketNotifier::Read, TQT_TQOBJECT(this)); TQT_BASE_OBJECT_NAME::connect(m_connectNotifier, TQT_SIGNAL(activated(int)), TQT_SLOT(slotNewConnection())); } void KBattleshipServer::slotNewConnection() { KExtendedSocket *sock; accept(sock); if(sock && m_serverSocket == 0) { m_service.stop(); m_serverSocket = sock; m_readNotifier = new TQSocketNotifier(sock->fd(), TQSocketNotifier::Read, TQT_TQOBJECT(this)); TQObject::connect(m_readNotifier, TQT_SIGNAL(activated(int)), this, TQT_SLOT(slotReadClient())); emit sigNewConnect(); } else delete sock; } void KBattleshipServer::slotReadClient() { int len; ioctl(m_serverSocket->fd(), FIONREAD, &len); if(!len) { slotDiscardClient(i18n("The connection broke down!"), false, true); return; } char *buf = new char[len + 1]; m_serverSocket->readBlock(buf, len); buf[len] = 0; m_readBuffer += TQString::fromUtf8(buf); delete []buf; int pos; while ((pos = m_readBuffer.find("")) >= 0) { pos += 11; // Length of "" KMessage *msg = new KMessage(); msg->setDataStream(m_readBuffer.left(pos)); m_readBuffer.remove(0, pos); emit sigNewMessage(msg); } } void KBattleshipServer::sendMessage(KMessage *msg) { TQCString post = msg->sendStream().utf8(); m_serverSocket->writeBlock(post.data(), post.length()); emit sigMessageSent(msg); } void KBattleshipServer::slotDiscardClient(const TQString &reason, bool kmversion, bool bemit) { KMessage *msg = new KMessage(KMessage::DISCARD); msg->addField("reason", reason); if(kmversion) msg->addField("kmversion", "true"); else msg->addField("kmversion", "false"); TQCString post = msg->sendStream().utf8(); m_serverSocket->writeBlock(post.data(), post.length()); delete msg; delete m_readNotifier; m_readNotifier = 0; delete m_serverSocket; m_serverSocket = 0; if(bemit) emit sigEndConnect(); }