summaryrefslogtreecommitdiff
path: root/src/net/tmwa/network.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/net/tmwa/network.cpp')
-rw-r--r--src/net/tmwa/network.cpp302
1 files changed, 9 insertions, 293 deletions
diff --git a/src/net/tmwa/network.cpp b/src/net/tmwa/network.cpp
index 4f2f85a51..98f6485a7 100644
--- a/src/net/tmwa/network.cpp
+++ b/src/net/tmwa/network.cpp
@@ -90,112 +90,17 @@ short packet_lengths[] =
-1, 122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
-const unsigned int BUFFER_SIZE = 1000000;
-const unsigned int BUFFER_LIMIT = 930000;
-
-int networkThread(void *data)
-{
- Network *network = static_cast<Network*>(data);
-
- if (!network || !network->realConnect())
- return -1;
-
- network->receive();
-
- return 0;
-}
-
Network *Network::mInstance = nullptr;
-Network::Network() :
- mSocket(nullptr),
- mInBuffer(new char[BUFFER_SIZE]),
- mOutBuffer(new char[BUFFER_SIZE]),
- mInSize(0),
- mOutSize(0),
- mToSkip(0),
- mState(IDLE),
- mWorkerThread(nullptr)
+Network::Network()
{
- SDLNet_Init();
-
- mMutex = SDL_CreateMutex();
mInstance = this;
}
Network::~Network()
{
clearHandlers();
-
- if (mState != IDLE && mState != NET_ERROR)
- disconnect();
-
- SDL_DestroyMutex(mMutex);
- mMutex = nullptr;
mInstance = nullptr;
-
- delete []mInBuffer;
- delete []mOutBuffer;
-
- SDLNet_Quit();
-}
-
-bool Network::connect(ServerInfo server)
-{
- if (mState != IDLE && mState != NET_ERROR)
- {
- logger->log1("Tried to connect an already connected socket!");
- assert(false);
- return false;
- }
-
- if (server.hostname.empty())
- {
- 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.port = server.port;
-
- // Reset to sane values
- mOutSize = 0;
- mInSize = 0;
- mToSkip = 0;
-
- mState = CONNECTING;
- mWorkerThread = SDL_CreateThread(networkThread, this);
- if (!mWorkerThread)
- {
- setError("Unable to create network worker thread");
- return false;
- }
-
- return true;
-}
-
-void Network::disconnect()
-{
- mState = IDLE;
-
- if (mWorkerThread && SDL_GetThreadID(mWorkerThread))
- {
- SDL_WaitThread(mWorkerThread, nullptr);
- mWorkerThread = nullptr;
- }
-
- if (mSocket)
- {
- // need call SDLNet_TCP_DelSocket?
- SDLNet_TCP_Close(mSocket);
- mSocket = nullptr;
- int sleep = config.getIntValue("networksleep");
- if (sleep > 0)
- SDL_Delay(sleep);
- }
}
void Network::registerHandler(MessageHandler *handler)
@@ -256,49 +161,6 @@ void Network::dispatchMessages()
}
}
-void Network::flush()
-{
- if (!mOutSize || mState != CONNECTED)
- return;
-
- int ret;
-
- SDL_mutexP(mMutex);
- ret = SDLNet_TCP_Send(mSocket, mOutBuffer, mOutSize);
- DEBUGLOG("Send " + toString(mOutSize) + " bytes");
- if (ret < static_cast<int>(mOutSize))
- {
- setError("Error in SDLNet_TCP_Send(): " +
- std::string(SDLNet_GetError()));
- }
- mOutSize = 0;
- SDL_mutexV(mMutex);
-}
-
-void Network::skip(int len)
-{
- SDL_mutexP(mMutex);
- mToSkip += len;
- if (!mInSize)
- {
- SDL_mutexV(mMutex);
- return;
- }
-
- if (mInSize >= mToSkip)
- {
- mInSize -= mToSkip;
- memmove(mInBuffer, mInBuffer + mToSkip, mInSize);
- mToSkip = 0;
- }
- else
- {
- mToSkip -= mInSize;
- mInSize = 0;
- }
- SDL_mutexV(mMutex);
-}
-
bool Network::messageReady()
{
int len = -1;
@@ -308,11 +170,18 @@ bool Network::messageReady()
{
int msgId = readWord(0);
if (msgId == SMSG_SERVER_VERSION_RESPONSE)
+ {
len = 10;
+ }
else if (msgId == SMSG_UPDATE_HOST2)
+ {
len = -1;
+ }
else
- len = packet_lengths[msgId];
+ {
+ if (msgId >= 0 && msgId < sizeof(packet_lengths) / sizeof (short))
+ len = packet_lengths[msgId];
+ }
if (len == -1 && mInSize > 4)
len = readWord(2);
@@ -356,162 +225,9 @@ MessageIn Network::getNextMessage()
return msg;
}
-bool Network::realConnect()
-{
- IPaddress ipAddress;
-
- if (SDLNet_ResolveHost(&ipAddress, mServer.hostname.c_str(),
- mServer.port) == -1)
- {
- std::string errorMessage = _("Unable to resolve host \"") +
- mServer.hostname + "\"";
- setError(errorMessage);
- logger->log("SDLNet_ResolveHost: %s", errorMessage.c_str());
- return false;
- }
-
- mState = CONNECTING;
-
- mSocket = SDLNet_TCP_Open(&ipAddress);
- if (!mSocket)
- {
- logger->log("Error in SDLNet_TCP_Open(): %s", SDLNet_GetError());
- setError(SDLNet_GetError());
- return false;
- }
-
- logger->log("Network::Started session with %s:%i",
- ipToString(ipAddress.host), ipAddress.port);
-
- mState = CONNECTED;
-
- return true;
-}
-
-void Network::receive()
-{
- SDLNet_SocketSet set;
-
- if (!(set = SDLNet_AllocSocketSet(1)))
- {
- setError("Error in SDLNet_AllocSocketSet(): " +
- std::string(SDLNet_GetError()));
- return;
- }
-
- if (SDLNet_TCP_AddSocket(set, mSocket) == -1)
- {
- setError("Error in SDLNet_AddSocket(): " +
- std::string(SDLNet_GetError()));
- }
-
- while (mState == CONNECTED)
- {
- // TODO Try to get this to block all the time while still being able
- // to escape the loop
- int numReady = SDLNet_CheckSockets(set, (static_cast<uint32_t>(500)));
- int ret;
- switch (numReady)
- {
- case -1:
- logger->log1("Error: SDLNet_CheckSockets");
- // FALLTHROUGH
- case 0:
- break;
-
- case 1:
- // Receive data from the socket
- SDL_mutexP(mMutex);
- if (mInSize > BUFFER_LIMIT)
- {
- SDL_mutexV(mMutex);
- SDL_Delay(100);
- continue;
- }
-
- ret = SDLNet_TCP_Recv(mSocket, mInBuffer + mInSize,
- BUFFER_SIZE - mInSize);
-
- if (!ret)
- {
- // We got disconnected
- mState = IDLE;
- logger->log1("Disconnected.");
- }
- else if (ret < 0)
- {
- setError(_("Connection to server terminated. ") +
- std::string(SDLNet_GetError()));
- }
- else
- {
-// DEBUGLOG("Receive " + toString(ret) + " bytes");
- mInSize += ret;
- if (mToSkip)
- {
- if (mInSize >= mToSkip)
- {
- mInSize -= mToSkip;
- memmove(mInBuffer, mInBuffer + mToSkip, mInSize);
- mToSkip = 0;
- }
- else
- {
- mToSkip -= mInSize;
- mInSize = 0;
- }
- }
- }
- SDL_mutexV(mMutex);
- break;
-
- default:
- // more than one socket is ready..
- // this should not happen since we only listen once socket.
- std::stringstream errorStream;
- errorStream << "Error in SDLNet_TCP_Recv(), " << numReady
- << " sockets are ready: " << SDLNet_GetError();
- setError(errorStream.str());
- break;
- }
- }
-
- if (SDLNet_TCP_DelSocket(set, mSocket) == -1)
- logger->log("Error in SDLNet_DelSocket(): %s", SDLNet_GetError());
-
- SDLNet_FreeSocketSet(set);
-}
-
Network *Network::instance()
{
return mInstance;
}
-void Network::setError(const std::string &error)
-{
- logger->log("Network error: %s", error.c_str());
- mError = error;
- mState = NET_ERROR;
-}
-
-uint16_t Network::readWord(int pos)
-{
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- return SDL_Swap16((*(uint16_t*)(mInBuffer + (pos))));
-#else
- return (*reinterpret_cast<uint16_t*>(mInBuffer + (pos)));
-#endif
-}
-
-void Network::fixSendBuffer()
-{
- if (mOutSize > BUFFER_LIMIT)
- {
- if (mState != CONNECTED)
- mOutSize = 0;
- else
- flush();
- }
-}
-
} // namespace TmwAthena