diff options
Diffstat (limited to 'src/net/ea/network.cpp')
-rw-r--r-- | src/net/ea/network.cpp | 372 |
1 files changed, 0 insertions, 372 deletions
diff --git a/src/net/ea/network.cpp b/src/net/ea/network.cpp deleted file mode 100644 index 1ae4d2323..000000000 --- a/src/net/ea/network.cpp +++ /dev/null @@ -1,372 +0,0 @@ -/* - * The ManaPlus Client - * Copyright (C) 2004-2009 The Mana World Development Team - * Copyright (C) 2009-2010 The Mana Developers - * Copyright (C) 2011-2017 The ManaPlus Developers - * - * This file is part of The ManaPlus Client. - * - * 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 - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include "net/ea/network.h" - -#include "configuration.h" -#include "logger.h" - -#include "net/packetinfo.h" - -#include "utils/cast.h" -#include "utils/delete2.h" -#include "utils/gettext.h" -#include "utils/sdlhelper.h" - -#include <sstream> - -#include "debug.h" - -#ifndef SDL_BIG_ENDIAN -#error missing SDL_endian.h -#endif // SDL_BYTEORDER - -extern unsigned int mLastHost; - -namespace Ea -{ - -const unsigned int BUFFER_SIZE = 1000000; -const unsigned int BUFFER_LIMIT = 930000; - -int networkThread(void *data) -{ - Network *const network = static_cast<Network *>(data); - - if ((network == nullptr) || !network->realConnect()) - return -1; - - network->receive(); - - return 0; -} - -Network::Network() : - mSocket(nullptr), - mServer(), - mPackets(nullptr), - mInBuffer(new char[BUFFER_SIZE]), - mOutBuffer(new char[BUFFER_SIZE]), - mInSize(0), - mOutSize(0), - mToSkip(0), - mState(IDLE), - mError(), - mWorkerThread(nullptr), - mMutexIn(SDL_CreateMutex()), - mMutexOut(SDL_CreateMutex()), - mSleep(config.getIntValue("networksleep")), - mPauseDispatch(false) -{ - TcpNet::init(); -} - -Network::~Network() -{ - if (mState != IDLE && mState != NET_ERROR) - disconnect(); - - SDL_DestroyMutex(mMutexIn); - mMutexIn = nullptr; - SDL_DestroyMutex(mMutexOut); - mMutexOut = nullptr; - - delete2Arr(mInBuffer); - delete2Arr(mOutBuffer); - delete2Arr(mPackets); - - TcpNet::quit(); -} - -bool Network::connect(const ServerInfo &server) -{ - if (mState != IDLE && mState != NET_ERROR) - { - logger->log1("Tried to connect an already connected socket!"); - return false; - } - - if (server.hostname.empty()) - { - // TRANSLATORS: error message - setError(_("Empty address given to Network::connect()!")); - return false; - } - - logger->log("Network::Connecting to %s:%i", - server.hostname.c_str(), server.port); - - mServer.hostname = server.hostname; - mServer.althostname = server.althostname; - mServer.port = server.port; - - // Reset to sane values - mOutSize = 0; - mInSize = 0; - mToSkip = 0; - - mState = CONNECTING; - mWorkerThread = SDL::createThread(&networkThread, "network", this); - if (mWorkerThread == nullptr) - { - setError("Unable to create network worker thread"); - return false; - } - - return true; -} - -void Network::disconnect() -{ - BLOCK_START("Network::disconnect") - mState = IDLE; - - SDL::WaitThread(mWorkerThread); - mWorkerThread = nullptr; - - if (mSocket != nullptr) - { - TcpNet::closeSocket(mSocket); - mSocket = nullptr; - if (mSleep > 0) - SDL_Delay(mSleep); - } - BLOCK_END("Network::disconnect") -} - -void Network::flush() -{ - if ((mOutSize == 0u) || mState != CONNECTED) - return; - - SDL_mutexP(mMutexOut); - const int ret = TcpNet::send(mSocket, mOutBuffer, mOutSize); -/* - if (logger) - { - logger->dlog(std::string("Send ").append( - toString(mOutSize)).append(" bytes")); - } -*/ - if (ret < CAST_S32(mOutSize)) - { - SDL_mutexV(mMutexOut); - setError("Error in TcpNet::send(): " + - std::string(TcpNet::getError())); - } - mOutSize = 0; - SDL_mutexV(mMutexOut); -} - -void Network::skip(const int len) -{ - SDL_mutexP(mMutexIn); - mToSkip += len; - if (mInSize == 0u) - { - SDL_mutexV(mMutexIn); - return; - } - - if (mInSize >= mToSkip) - { - mInSize -= mToSkip; - memmove(mInBuffer, mInBuffer + CAST_SIZE(mToSkip), mInSize); - mToSkip = 0; - } - else - { - mToSkip -= mInSize; - mInSize = 0; - } - SDL_mutexV(mMutexIn); -} - -bool Network::realConnect() -{ - IPaddress ipAddress; - - if (TcpNet::resolveHost(&ipAddress, mServer.hostname.c_str(), - mServer.port) == -1) - { - if (mServer.althostname.empty() || TcpNet::resolveHost(&ipAddress, - mServer.althostname.c_str(), mServer.port) == -1) - { - const std::string errorMessage = std::string( - // TRANSLATORS: error message - _("Unable to resolve host \"")).append( - mServer.hostname).append("\"."); - setError(errorMessage); - logger->log_r("TcpNet::ResolveHost: %s", errorMessage.c_str()); - return false; - } - logger->log_r("using alt host name: %s", mServer.althostname.c_str()); - } - - mState = CONNECTING; - - mSocket = TcpNet::open(&ipAddress); - if (mSocket == nullptr) - { - logger->log_r("Error in TcpNet::open(): %s", TcpNet::getError()); - setError(TcpNet::getError()); - return false; - } - - mLastHost = ipAddress.host; - logger->log_r("Network::Started session with %s:%i", - ipToString(ipAddress.host), ipAddress.port); - - mState = CONNECTED; - return true; -} - -void Network::receive() -{ - TcpNet::SocketSet set; - - if ((set = TcpNet::allocSocketSet(1)) == nullptr) - { - setError("Error in TcpNet::allocSocketSet(): " + - std::string(TcpNet::getError())); - return; - } - - if (TcpNet::addSocket(set, mSocket) == -1) - { - setError("Error in TcpNet::addSocket(): " + - std::string(TcpNet::getError())); - } - - while (mState == CONNECTED) - { - const int numReady = TcpNet::checkSockets( - set, (CAST_U32(500))); - switch (numReady) - { - case -1: - logger->log_r("Error: TcpNet::checkSockets"); - break; - // FALLTHROUGH - case 0: - break; - - case 1: - { - // Receive data from the socket - SDL_mutexP(mMutexIn); - if (mInSize > BUFFER_LIMIT) - { - SDL_mutexV(mMutexIn); - SDL_Delay(100); - continue; - } - - const int ret = TcpNet::recv(mSocket, - mInBuffer + CAST_SIZE(mInSize), - BUFFER_SIZE - mInSize); - - if (ret == 0) - { - // We got disconnected - mState = IDLE; - logger->log_r("Disconnected."); - } - else if (ret < 0) - { - // TRANSLATORS: error message - setError(_("Connection to server terminated. ") + - std::string(TcpNet::getError())); - } - else - { -// DEBUGLOG("Receive " + toString(ret) + " bytes"); - mInSize += ret; - if (mToSkip != 0u) - { - if (mInSize >= mToSkip) - { - mInSize -= mToSkip; - memmove(mInBuffer, - mInBuffer + CAST_SIZE(mToSkip), - mInSize); - mToSkip = 0; - } - else - { - mToSkip -= mInSize; - mInSize = 0; - } - } - } - SDL_mutexV(mMutexIn); - break; - } - - default: - // more than one socket is ready.. - // this should not happen since we only listen once socket. - std::stringstream errorStream; - errorStream << "Error in TcpNet::recv(), " << numReady - << " sockets are ready: " << TcpNet::getError(); - setError(errorStream.str()); - break; - } - } - - if (TcpNet::delSocket(set, mSocket) == -1) - logger->log_r("Error in TcpNet::delSocket(): %s", TcpNet::getError()); - - TcpNet::freeSocketSet(set); -} - -void Network::setError(const std::string &error) -{ - logger->log_r("Network error: %s", error.c_str()); - mError = error; - mState = NET_ERROR; -} - -uint16_t Network::readWord(const int pos) const -{ -#if SDL_BYTEORDER == SDL_BIG_ENDIAN - return SDL_Swap16(*reinterpret_cast<uint16_t*>( - mInBuffer + CAST_SIZE(pos))); -#else // SDL_BYTEORDER == SDL_BIG_ENDIAN - - return (*reinterpret_cast<uint16_t*>( - mInBuffer + CAST_SIZE(pos))); -#endif // SDL_BYTEORDER == SDL_BIG_ENDIAN -} - -void Network::fixSendBuffer() -{ - if (mOutSize > BUFFER_LIMIT) - { - if (mState != CONNECTED) - mOutSize = 0; - else - flush(); - } -} - -} // namespace Ea |