diff options
Diffstat (limited to 'src/net')
-rw-r--r-- | src/net/network.cpp | 131 | ||||
-rw-r--r-- | src/net/network.h | 12 | ||||
-rw-r--r-- | src/net/protocol.cpp | 51 | ||||
-rw-r--r-- | src/net/protocol.h | 3 |
4 files changed, 111 insertions, 86 deletions
diff --git a/src/net/network.cpp b/src/net/network.cpp index 6e3b6c6c..e94acee7 100644 --- a/src/net/network.cpp +++ b/src/net/network.cpp @@ -26,6 +26,7 @@ #include <cassert> #include <sstream> #include <SDL_net.h> +#include <SDL_thread.h> #include "messagein.h" @@ -85,10 +86,13 @@ char *in = NULL; char *out = NULL; unsigned int in_size = 0; unsigned int out_size = 0; -bool connectionOpen = false; +int connectionOpen = NET_IDLE; TCPsocket sock; SDLNet_SocketSet set; +SDL_Thread *mThread = NULL; +SDL_mutex *mMutex = NULL; +IPaddress *ip = NULL; char *iptostring(int address) { @@ -103,32 +107,15 @@ char *iptostring(int address) return asciiIP; } -int open_session(const char* address, short port) +int connectionThread(void *ptr) { - assert(!connectionOpen); - - // Initialize SDL_net - if (SDLNet_Init() == -1) - { - logger->log("Error in SDLNet_Init(): %s", SDLNet_GetError()); - return -1; - } - - IPaddress ip; - - // Resolve host name - if (SDLNet_ResolveHost(&ip, address, port) == -1) - { - logger->log("Error in SDLNet_ResolveHost(): %s", SDLNet_GetError()); - return -1; - } - // Create the socket for the current session - sock = SDLNet_TCP_Open(&ip); + sock = SDLNet_TCP_Open((IPaddress *)ptr); if (!sock) { logger->log("Error in SDLNet_TCP_Open(): %s", SDLNet_GetError()); - return -1; + connectionOpen = NET_ERROR; + return NET_ERROR; } // Create a socket set to listen to socket @@ -136,7 +123,8 @@ int open_session(const char* address, short port) if (!set) { logger->log("Error in SDLNet_AllocSocketSet(): %s", SDLNet_GetError()); - return -1; + connectionOpen = NET_ERROR; + return NET_ERROR; } // Add the socket to the set @@ -144,7 +132,8 @@ int open_session(const char* address, short port) if (ret == -1) { logger->log("Error in SDLNet_AddSocket(): %s", SDLNet_GetError()); - return -1; + connectionOpen = NET_ERROR; + return NET_ERROR; } // Init buffers @@ -154,16 +143,98 @@ int open_session(const char* address, short port) memset(out, '\0', buffer_size); in_size = 0; out_size = 0; + + SDL_mutexP(mMutex); + logger->log("Network::Started session with %s:%i", + iptostring(((IPaddress *)ptr)->host), + ((IPaddress *)ptr)->port); + connectionOpen = NET_CONNECTED; + SDL_mutexV(mMutex); + return NET_CONNECTED; +} + +void openConnection(const char* address, short port) +{ + //assert(connectionOpen <= NET_IDLE); + + // Initialize SDL_net + if (SDLNet_Init() == -1) + { + logger->log("Error in SDLNet_Init(): %s", SDLNet_GetError()); + connectionOpen = NET_ERROR; + } - logger->log("Network::Started session with %s:%i", address, port); - connectionOpen = true; + ip = new IPaddress(); - return 0; + // Resolve host name + if (SDLNet_ResolveHost(ip, address, port) == -1) + { + logger->log("Error in SDLNet_ResolveHost(): %s", SDLNet_GetError()); + connectionOpen = NET_ERROR; + } + + connectionOpen = NET_CONNECTING; + // Create the synchronization lock + mMutex = SDL_CreateMutex(); + // Create the connection thread + mThread = SDL_CreateThread(connectionThread, ip); + if (mThread == NULL) { + logger->log("Unable to create connection thread"); + connectionOpen = NET_ERROR; + } +} + +int pollConnection() +{ + if (mMutex) + { + SDL_mutexP(mMutex); + } + + switch (connectionOpen) + { + case NET_IDLE: + case NET_CONNECTING: + break; + case NET_CONNECTED: + case NET_ERROR: + SDL_WaitThread(mThread, NULL); + mThread = NULL; + SDL_DestroyMutex(mMutex); + mMutex = NULL; + break; + } + + if (mMutex) + { + SDL_mutexV(mMutex); + } + return connectionOpen; } -void close_session() +void closeConnection() { - assert(connectionOpen); + //assert(connectionOpen > ); + + if (connectionOpen == NET_ERROR)return; + + if (mThread) + { + SDL_WaitThread(mThread, NULL); + mThread = NULL; + } + + if (mMutex) + { + SDL_DestroyMutex(mMutex); + mMutex = NULL; + } + + if (ip) + { + delete ip; + ip = NULL; + } // Remove the socket from the socket set int ret = SDLNet_TCP_DelSocket(set, sock); @@ -199,7 +270,7 @@ void close_session() SDLNet_Quit(); logger->log("Network::Closed session"); - connectionOpen = false; + connectionOpen = NET_IDLE; } void flush() diff --git a/src/net/network.h b/src/net/network.h index 47e71190..1038b954 100644 --- a/src/net/network.h +++ b/src/net/network.h @@ -24,16 +24,24 @@ #ifndef _TMW_NETWORK_ #define _TMW_NETWORK_ +#define NET_ERROR -1 +#define NET_CONNECTED 0 +#define NET_IDLE 1 +#define NET_CONNECTING 2 + class MessageIn; /** Convert an address from int format to string */ char *iptostring(int address); /** Open a session with a server */ -int open_session(const char* address, short port); +void openConnection(const char* address, short port); + +/** Returns the status of the current connection attempt. */ +int pollConnection(); /** Close a session */ -void close_session(); +void closeConnection(); /** Send and receive data waiting in the buffers */ void flush(); diff --git a/src/net/protocol.cpp b/src/net/protocol.cpp index b56745fa..516afa59 100644 --- a/src/net/protocol.cpp +++ b/src/net/protocol.cpp @@ -68,57 +68,6 @@ void set_coordinates(char *data, data[2] |= direction; } -void map_start() -{ - // Connect to map server - if (open_session(iptostring(map_address), map_port) == -1) - { - logger->log("Warning: Unable to connect to map server"); - throw "Unable to connect to map server"; - return; - } - - // Send login infos - MessageOut outMsg; - outMsg.writeShort(0x0072); - outMsg.writeLong(account_ID); - outMsg.writeLong(char_ID); - outMsg.writeLong(session_ID1); - outMsg.writeLong(session_ID2); - outMsg.writeByte(sex); - - // Skip a mysterious 4 bytes - while ((in_size < 4)|| (out_size > 0)) flush(); - skip(4); - - MessageIn msg = get_next_message(); - - if (msg.getId() == SMSG_LOGIN_SUCCESS) - { - unsigned char direction; - msg.readLong(); // server tick - msg.readCoordinates(startX, startY, direction); - msg.skip(2); // unknown - logger->log("Protocol: Player start position: (%d, %d), Direction: %d", - startX, startY, direction); - } - else if (msg.getId() == 0x0081) - { - logger->log("Warning: Map server D/C"); - } - else - { - logger->error("Unknown packet: map_start"); - } - - skip(msg.getLength()); - - // Send "map loaded" - // TODO: be able to reuse the same msg - MessageOut newMsg; - newMsg.writeShort(0x007d); -} - void walk(unsigned short x, unsigned short y, unsigned char direction) { char temp[3]; diff --git a/src/net/protocol.h b/src/net/protocol.h index 8609530a..c6e118d4 100644 --- a/src/net/protocol.h +++ b/src/net/protocol.h @@ -115,9 +115,6 @@ unsigned char get_dest_direction(char data); /** Encodes coords and direction in 3 bytes data */ void set_coordinates(char *data, unsigned short x, unsigned short y, unsigned char direction); -/** Initialize connection with map server */ -void map_start(); - /** Requests to walk */ void walk(unsigned short x, unsigned short y, unsigned char direction); |