diff options
Diffstat (limited to 'src/net')
-rw-r--r-- | src/net/messagein.cpp | 151 | ||||
-rw-r--r-- | src/net/messagein.h | 94 | ||||
-rw-r--r-- | src/net/messageout.cpp | 130 | ||||
-rw-r--r-- | src/net/messageout.h | 80 | ||||
-rw-r--r-- | src/net/network.cpp | 361 | ||||
-rw-r--r-- | src/net/network.h | 79 | ||||
-rw-r--r-- | src/net/packet.cpp | 40 | ||||
-rw-r--r-- | src/net/packet.h | 47 | ||||
-rw-r--r-- | src/net/protocol.cpp | 188 | ||||
-rw-r--r-- | src/net/protocol.h | 96 | ||||
-rw-r--r-- | src/net/win2linux.h | 51 | ||||
-rw-r--r-- | src/net/win2mac.cpp | 14 | ||||
-rw-r--r-- | src/net/win2mac.h | 7 |
13 files changed, 937 insertions, 401 deletions
diff --git a/src/net/messagein.cpp b/src/net/messagein.cpp new file mode 100644 index 00000000..2710d132 --- /dev/null +++ b/src/net/messagein.cpp @@ -0,0 +1,151 @@ +/* + * The Mana World + * Copyright 2004 The Mana World Development Team + * + * This file is part of The Mana World. + * + * The Mana World 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. + * + * The Mana World 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 The Mana World; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +#include "messagein.h" +#include <SDL_net.h> +#ifdef MACOSX +#include "win2mac.h" +#endif + +#define MAKEWORD(low,high) \ + ((unsigned short)(((unsigned char)(low)) | \ + ((unsigned short)((unsigned char)(high))) << 8)) + + +MessageIn::MessageIn(const char *data, unsigned int length): + mData(data), + mLength(length), + mPos(0) +{ + // Read the message ID + mId = readShort(); +} + +char +MessageIn::readByte() +{ + assert(mPos < mLength); + return mData[mPos++]; +} + +short +MessageIn::readShort() +{ + assert(mPos + 2 <= mLength); + mPos += 2; +#ifdef MACOSX + return DR_SwapTwoBytes(*(short*)(mData + (mPos - 2))); +#else + return (*(short*)(mData + (mPos - 2))); +#endif +} + +long +MessageIn::readLong() +{ + assert(mPos + 4 <= mLength); + mPos += 4; +#ifdef MACOSX + return DR_SwapFourBytes(*(long*)(mData + (mPos - 4))); +#else + return (*(long*)(mData + (mPos - 4))); +#endif +} + +void +MessageIn::readCoordinates(unsigned short &x, + unsigned short &y, + unsigned char &direction) +{ + assert(mPos + 3 <= mLength); + + const char *data = mData + mPos; + short temp; + + temp = MAKEWORD(data[1] & 0x00c0, data[0] & 0x00ff); + x = temp >> 6; + temp = MAKEWORD(data[2] & 0x00f0, data[1] & 0x003f); + y = temp >> 4; + + direction = data[2] & 0x000f; + + mPos += 3; +} + +void +MessageIn::readCoordinatePair(unsigned short &srcX, unsigned short &srcY, + unsigned short &dstX, unsigned short &dstY) +{ + assert(mPos + 5 <= mLength); + + const char *data = mData + mPos; + short temp; + + temp = MAKEWORD(data[3], data[2] & 0x000f); + dstX = temp >> 2; + + dstY = MAKEWORD(data[4], data[3] & 0x0003); + + temp = MAKEWORD(data[1], data[0]); + srcX = temp >> 6; + + temp = MAKEWORD(data[2], data[1] & 0x003f); + srcY = temp >> 4; + + mPos += 5; +} + +void +MessageIn::skip(unsigned int length) +{ + assert(mPos + length <= mLength); + mPos += length; +} + +std::string +MessageIn::readString(int length) +{ + int stringLength = 0; + std::string readString = ""; + + // Get string length + if (length < 0) { + stringLength = readShort(); + } else { + stringLength = length; + } + + // Make sure there is enough data available + assert(mPos + length <= mLength); + + // Read the string + char *tmpString = new char[stringLength + 1]; + memcpy(tmpString, (void*)&mData[mPos], stringLength); + tmpString[stringLength] = 0; + mPos += stringLength; + + readString = tmpString; + delete tmpString; + + return readString; +} diff --git a/src/net/messagein.h b/src/net/messagein.h new file mode 100644 index 00000000..9a61ce7d --- /dev/null +++ b/src/net/messagein.h @@ -0,0 +1,94 @@ +/* + * The Mana World + * Copyright 2004 The Mana World Development Team + * + * This file is part of The Mana World. + * + * The Mana World 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. + * + * The Mana World 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 The Mana World; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +#ifndef _TMW_MESSAGEIN_ +#define _TMW_MESSAGEIN_ + +#include <string> + +/** + * Used for parsing an incoming message. + */ +class MessageIn +{ + public: + /** + * Constructor. + */ + MessageIn(const char *data, unsigned int length); + + /** + * Returns the message ID. + */ + short + getId() { return mId; } + + /** + * Returns the message length. + */ + unsigned int + getLength() { return mLength; } + + char readByte(); /**< Reads a byte. */ + short readShort(); /**< Reads a short. */ + long readLong(); /**< Reads a long. */ + + /** + * Reads a special 3 byte block used by eAthena, containing x and y + * coordinates and direction. + */ + void + readCoordinates(unsigned short &x, + unsigned short &y, + unsigned char &direction); + + /** + * Reads a special 5 byte block used by eAthena, containing a source + * and destination coordinate pair. + */ + void + readCoordinatePair(unsigned short &srcX, unsigned short &srcY, + unsigned short &dstX, unsigned short &dstY); + + /** + * Skips a given number of bytes. + */ + void + skip(unsigned int length); + + /** + * Reads a string. If a length is not given (-1), it is assumed + * that the length of the string is stored in a short at the + * start of the string. + */ + std::string + readString(int length = -1); + + private: + const char* mData; /**< The message data. */ + unsigned int mLength; /**< The length of the data. */ + unsigned int mPos; /**< The position in the data. */ + short mId; /**< The message ID. */ +}; + +#endif diff --git a/src/net/messageout.cpp b/src/net/messageout.cpp new file mode 100644 index 00000000..871ba43a --- /dev/null +++ b/src/net/messageout.cpp @@ -0,0 +1,130 @@ +/* + * The Mana World + * Copyright 2004 The Mana World Development Team + * + * This file is part of The Mana World. + * + * The Mana World 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. + * + * The Mana World 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 The Mana World; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +#include "messageout.h" + +#include <iostream> +#include <SDL_net.h> + +#include "network.h" + +MessageOut::MessageOut(): + mPacket(0), + mData(0), + mDataSize(0), + mPos(0) +{ + // TODO: data not to be already allocated, keep it this way unitl full + // conversion + mData = out; +} + +MessageOut::~MessageOut() +{ + if (mPacket) { + delete mPacket; + } + + // Don't free this data for now, see above. + //if (mData) { + // free(mData); + //} +} + +void MessageOut::expand(size_t bytes) +{ + mData = (char*)realloc(mData, bytes); + mDataSize = bytes; +} + +void MessageOut::writeByte(char value) +{ + expand(mPos + sizeof(char)); + mData[mPos] = value; + mPos += sizeof(char); +} + +void MessageOut::writeShort(short value) +{ + expand(mPos + sizeof(short)); +#ifdef MACOSX + (*(short *)(mData + mPos)) = DR_SwapTwoBytes(value); +#else + (*(short *)(mData + mPos)) = value; +#endif + //SDLNet_Write16(value, &mData[mPos]); + mPos += sizeof(short); +} + +void MessageOut::writeLong(long value) +{ + expand(mPos + sizeof(long)); +#ifdef MACOSX + (*(long *)(mData + mPos)) = DR_SwapFourBytes(value); +#else + (*(long *)(mData + mPos)) = value; +#endif + //SDLNet_Write32(value, &mData[mPos]); + mPos += sizeof(long); +} + +void MessageOut::writeString(const std::string &string, int length) +{ + std::string toWrite = string; + + if (length < 0) + { + // Write the length at the start if not fixed + writeShort(string.length()); + toWrite = string; + + expand(mPos + string.length()); + } + else + { + // Make sure the length of the string is no longer than specified + toWrite = string.substr(0, length); + expand(mPos + length); + } + + // Write the actual string + memcpy(&mData[mPos], (void*)toWrite.c_str(), toWrite.length()); + mPos += toWrite.length(); + + // Pad remaining space with zeros + if (length > (int)toWrite.length()) + { + memset(&mData[mPos], '\0', length - toWrite.length()); + mPos += length - toWrite.length(); + } +} + +const Packet *MessageOut::getPacket() +{ + if (!mPacket) + { + mPacket = new Packet(mData, mDataSize); + } + + return mPacket; +} diff --git a/src/net/messageout.h b/src/net/messageout.h new file mode 100644 index 00000000..d836b43f --- /dev/null +++ b/src/net/messageout.h @@ -0,0 +1,80 @@ +/* + * The Mana World + * Copyright 2004 The Mana World Development Team + * + * This file is part of The Mana World. + * + * The Mana World 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. + * + * The Mana World 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 The Mana World; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +#ifndef _TMW_MESSAGEOUT_ +#define _TMW_MESSAGEOUT_ + +#include <string> + +#include "packet.h" + +/** + * Used for building an outgoing message. + */ +class MessageOut +{ + public: + /** + * Constructor. + */ + MessageOut(); + + /** + * Destructor. + */ + ~MessageOut(); + + void writeByte(char value); /**< Writes a byte. */ + void writeShort(short value); /**< Writes a short. */ + void writeLong(long value); /**< Writes a long. */ + + /** + * Writes a string. If a fixed length is not given (-1), it is stored + * as a short at the start of the string. + */ + void writeString(const std::string &string, int length = -1); + + /** + * Returns an instance of Packet derived from the written data. Use for + * sending the packet. No more writing to the packet may be done after + * a call to this method. + */ + const Packet *getPacket(); + + private: + /** + * Expand the packet data to be able to hold more data. + * + * NOTE: For performance enhancements this method could allocate extra + * memory in advance instead of expanding size every time more data is + * added. + */ + void expand(unsigned int size); + + Packet *mPacket; /**< Created packet. */ + char *mData; /**< Data building up. */ + unsigned int mDataSize; /**< Size of data. */ + unsigned int mPos; /**< Position in the data. */ +}; + +#endif diff --git a/src/net/network.cpp b/src/net/network.cpp index b0d27be9..6624ee1e 100644 --- a/src/net/network.cpp +++ b/src/net/network.cpp @@ -23,162 +23,309 @@ #include "../log.h" #include "network.h" +#include "protocol.h" +#ifdef MACOSX +#include "win2mac.h" +#endif #ifndef WIN32 #include <unistd.h> #include <fcntl.h> #include <errno.h> #endif +#include <sstream> /** Warning: buffers and other variables are shared, so there can be only one connection active at a time */ -int buffer_size = 65536; -char *in, *out; -int in_size, out_size; +short packet_lengths[] = { + 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// #0x0040 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 55, 17, 3, 37, 46, -1, 23, -1, 3,108, 3, 2, + 3, 28, 19, 11, 3, -1, 9, 5, 54, 53, 58, 60, 41, 2, 6, 6, +// #0x0080 + 7, 3, 2, 2, 2, 5, 16, 12, 10, 7, 29, 23, -1, -1, -1, 0, + 7, 22, 28, 2, 6, 30, -1, -1, 3, -1, -1, 5, 9, 17, 17, 6, + 23, 6, 6, -1, -1, -1, -1, 8, 7, 6, 7, 4, 7, 0, -1, 6, + 8, 8, 3, 3, -1, 6, 6, -1, 7, 6, 2, 5, 6, 44, 5, 3, +// #0x00C0 + 7, 2, 6, 8, 6, 7, -1, -1, -1, -1, 3, 3, 6, 6, 2, 27, + 3, 4, 4, 2, -1, -1, 3, -1, 6, 14, 3, -1, 28, 29, -1, -1, + 30, 30, 26, 2, 6, 26, 3, 3, 8, 19, 5, 2, 3, 2, 2, 2, + 3, 2, 6, 8, 21, 8, 8, 2, 2, 26, 3, -1, 6, 27, 30, 10, +// #0x0100 + 2, 6, 6, 30, 79, 31, 10, 10, -1, -1, 4, 6, 6, 2, 11, -1, + 10, 39, 4, 10, 31, 35, 10, 18, 2, 13, 15, 20, 68, 2, 3, 16, + 6, 14, -1, -1, 21, 8, 8, 8, 8, 8, 2, 2, 3, 4, 2, -1, + 6, 86, 6, -1, -1, 7, -1, 6, 3, 16, 4, 4, 4, 6, 24, 26, +// #0x0140 + 22, 14, 6, 10, 23, 19, 6, 39, 8, 9, 6, 27, -1, 2, 6, 6, + 110, 6, -1, -1, -1, -1, -1, 6, -1, 54, 66, 54, 90, 42, 6, 42, + -1, -1, -1, -1, -1, 30, -1, 3, 14, 3, 30, 10, 43, 14,186,182, + 14, 30, 10, 3, -1, 6,106, -1, 4, 5, 4, -1, 6, 7, -1, -1, +// #0x0180 + 6, 3,106, 10, 10, 34, 0, 6, 8, 4, 4, 4, 29, -1, 10, 6, + 90, 86, 24, 6, 30,102, 9, 4, 8, 4, 14, 10, 4, 6, 2, 6, + 3, 3, 35, 5, 11, 26, -1, 4, 4, 6, 10, 12, 6, -1, 4, 4, + 11, 7, -1, 67, 12, 18,114, 6, 3, 6, 26, 26, 26, 26, 2, 3, +// #0x01C0 + 2, 14, 10, -1, 22, 22, 4, 2, 13, 97, 0, 9, 9, 29, 6, 28, + 8, 14, 10, 35, 6, 8, 4, 11, 54, 53, 60, 2, -1, 47, 33, 6, + 30, 8, 34, 14, 2, 6, 26, 2, 28, 81, 6, 10, 26, 2, -1, -1, + -1, -1, 20, 10, 32, 9, 34, 14, 2, 6, 48, 56, -1, 4, 5, 10, +// #0x200 + 26, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; -SOCKET sock; -SOCKADDR_IN addr; -// File descriptors attached to socket -fd_set read_socket; -fd_set write_socket; +unsigned int buffer_size = 65536; +char *in = NULL; +char *out = NULL; +unsigned int in_size = 0; +unsigned int out_size = 0; +bool connectionOpen = false; -void WFIFOSET(int len) -{ - if (out_size + len >= buffer_size) { - logger->log("Warning: Output buffer full"); - } - else { - out_size += len; - } -} +TCPsocket sock; +SDLNet_SocketSet set; char *iptostring(int address) { - short temp1, temp2; static char asciiIP[16]; - temp1 = LOWORD(address); - temp2 = HIWORD(address); - sprintf(asciiIP, "%i.%i.%i.%i", LOBYTE(temp1), HIBYTE(temp1), LOBYTE(temp2), HIBYTE(temp2)); + sprintf(asciiIP, "%i.%i.%i.%i", + (unsigned char)(address), + (unsigned char)(address >> 8), + (unsigned char)(address >> 16), + (unsigned char)(address >> 24)); + return asciiIP; } -SOCKET open_session(const char* address, short port) +int open_session(const char* address, short port) { - #ifdef WIN32 - WSADATA wsda; - #endif - struct hostent *server; - int ret; - - // Init WinSock and connect the socket - #ifdef WIN32 - WSAStartup(MAKEWORD(2,0), &wsda); - #endif - - sock = socket(PF_INET, SOCK_STREAM, 0); // Create socket for current session - if(sock==SOCKET_ERROR)return SOCKET_ERROR; - - addr.sin_family = AF_INET; - addr.sin_port = htons(port); - addr.sin_addr.s_addr = inet_addr(address); - if(addr.sin_addr.s_addr == INADDR_NONE){ - server = NULL; - server = gethostbyname(address); - if(server == NULL)return SOCKET_ERROR; - memcpy(&addr.sin_addr, server->h_addr_list[0], server->h_length); + assert(!connectionOpen); + + // Initialize SDL_net + if (SDLNet_Init() == -1) + { + logger->log("Error in SDLNet_Init(): %s", SDLNet_GetError()); + return -1; } - ret = connect(sock, (struct sockaddr *) &addr, sizeof(addr)); - if(ret == SOCKET_ERROR)return SOCKET_ERROR; + 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); + if (!sock) + { + logger->log("Error in SDLNet_TCP_Open(): %s", SDLNet_GetError()); + return -1; + } + + // Create a socket set to listen to socket + set = SDLNet_AllocSocketSet(1); + if (!set) + { + logger->log("Error in SDLNet_AllocSocketSet(): %s", SDLNet_GetError()); + return -1; + } + + // Add the socket to the set + int ret = SDLNet_TCP_AddSocket(set, sock); + if (ret == -1) + { + logger->log("Error in SDLNet_AddSocket(): %s", SDLNet_GetError()); + return -1; + } // Init buffers - in = (char *)malloc(buffer_size); - out = (char *)malloc(buffer_size); + in = (char*)malloc(buffer_size); + out = (char*)malloc(buffer_size); memset(in, '\0', buffer_size); memset(out, '\0', buffer_size); in_size = 0; out_size = 0; - FD_CLR(sock, &read_socket); - FD_CLR(sock, &write_socket); - return sock; + logger->log("Network::Started session with %s:%i", address, port); + connectionOpen = true; + + return 0; } void close_session() { - FD_CLR(sock,&read_socket); - FD_CLR(sock,&write_socket); - closesocket(sock); - if(in!=NULL) { + assert(connectionOpen); + + // Remove the socket from the socket set + int ret = SDLNet_TCP_DelSocket(set, sock); + if (ret == -1) + { + logger->log("Error in SDLNet_DelSocket(): %s", SDLNet_GetError()); + } + + // Close the TCP connection + SDLNet_TCP_Close(sock); + + // Free the socket set + SDLNet_FreeSocketSet(set); + set = NULL; + + // Clear buffers + if (in != NULL) + { free(in); + in = NULL; } - if(out!=NULL) { + + if (out != NULL) + { free(out); + out = NULL; } - in = NULL; - out = NULL; + in_size = 0; out_size = 0; - WSACleanup(); + + // Shutdown the network API + SDLNet_Quit(); + + logger->log("Network::Closed session"); + connectionOpen = false; } void flush() { - int ret = 0; - void *buf = out; - timeval time_out; - - // Init the time_out struct to 0s so it won't block - time_out.tv_sec=0; - time_out.tv_usec=0; - - // Clear file descriptors and set them to socket - FD_ZERO(&read_socket); - FD_ZERO(&write_socket); - FD_SET(sock, &read_socket); - FD_SET(sock, &write_socket); - - // Check if socket has available data by evaluating attached file descriptors - select(FD_SETSIZE, &read_socket, &write_socket, NULL, &time_out); - - // Send data if available - if(FD_ISSET(sock, &write_socket)) { - // While there wasn't a error or sent the whole data: handles partial packet send - while((ret!=SOCKET_ERROR)&&(out_size>0)) { - ret = send(sock, (char *)buf, out_size, 0); - - if(ret!=SOCKET_ERROR && ret>0) { - buf = (char*)buf+ret; - out_size -= ret; - } + int numReady = SDLNet_CheckSockets(set, 0); + if (numReady == -1) + { + logger->log("Error: SDLNet_CheckSockets"); + return; + } + else if (numReady) + { + // Receive data from the socket + int ret = SDLNet_TCP_Recv(sock, in + in_size, buffer_size - in_size); + if (ret <= 0) + { + logger->log("Warning: unknown error when receiving data"); + logger->log("SDLNet_GetError(): %s", SDLNet_GetError()); + // The client disconnected, notify it somewhere + logger->error("Disconnected from server"); + return; + } + else { + in_size += ret; + } + } + + // Send all available data, waits if not all data can be sent immediately + if (out_size > 0) + { + int ret = SDLNet_TCP_Send(sock, (char*)out, out_size); + if (ret < (int)out_size) + { + // It is likely that the server disconnected + std::stringstream ss; + ss << "Error in SDLNet_TCP_Send(): " << SDLNet_GetError(); + logger->error(ss.str()); + return; } - if (ret == SOCKET_ERROR) { - logger->error("Socket Error"); -#ifdef WIN32 - logger->log("Error: Socket error: %i ", WSAGetLastError()); - if (WSAGetLastError() == 10053) - logger->log("Error: Packet size error"); - /** Probably the last packet you sent, was defined with - * wrong size: WFIFOSET(size); - */ + out_size -= ret; + } +} + +unsigned short readWord(int pos) +{ +#ifdef MACOSX + return DR_SwapTwoBytes((*(unsigned short*)(in+(pos)))); #else - logger->log("Error: Undefined socket error"); + return (*(unsigned short *)(in+(pos))); #endif - } +} + +MessageIn +get_next_message() +{ + // At least 2 bytes should be received for the message ID + while (in_size < 2) flush(); + + int length = packet_lengths[readWord(0)]; + + if (length == -1) + { + // Another 2 bytes should be received for the length + while (in_size < 4) flush(); + length = readWord(2); } - // Read data, if available - if (FD_ISSET(sock, &read_socket)) { - /* There's no check for partial received packets because at this level - the app doesn't know packet length, but it will done when parsing received data */ - ret = recv(sock, in+in_size, RFIFOSPACE, 0); - if (ret == SOCKET_ERROR) { -#ifdef WIN32 - logger->log("Error: Socket error: %i ", WSAGetLastError()); +#ifdef DEBUG + printf("Received packet 0x%x of length %d\n", readWord(0), length); +#endif + + // Make sure the whole packet is received + while (in_size < (unsigned int)length) flush(); + + return MessageIn(in, length); +} + +void writeByte(int pos, unsigned char value)//writeByte(unsigned char value) +{ + (*(unsigned char *)(out + pos + out_size)) = value; + //out_size++; +} + +void writeWord(int pos, unsigned short value)//writeWord(unsigned short value) +{ +#ifdef MACOSX + (*(unsigned short *)(out + pos + out_size)) = DR_SwapTwoBytes(value); +#else + (*(unsigned short *)(out + pos + out_size)) = value; +#endif + //SDLNet_Write16(value, (out + (pos + out_size))); + //out_size += 2; +} + +void writeLong(int pos, unsigned int value)//writeLong(int value) +{ +#ifdef MACOSX + (*(unsigned int *)(out + pos + out_size)) = DR_SwapFourBytes(value); #else - logger->log("Error: Undefined socket error"); + (*(unsigned int *)(out + pos + out_size)) = value; #endif - } else RFIFOSET(ret); // Set size of available data to read + //SDLNet_Write32((Uint32)value, (out + (pos + out_size))); + //out_size += 4; +} + +char *writePointer(int pos)//writeString(const std::string &string, int length) +{ + return (out+(pos+out_size)); + //memcpy((out + out_size), string.c_str(), length); + //out_size += length; +} + +void writeSet(unsigned int value) +{ + if (out_size + value >= buffer_size) { + logger->log("Warning: Output buffer full"); + } + else { + out_size += value; } } + +void skip(int len) +{ + memcpy(in, in + len, in_size - len); + in_size -= len; +} diff --git a/src/net/network.h b/src/net/network.h index cc5e542f..a037c6fa 100644 --- a/src/net/network.h +++ b/src/net/network.h @@ -21,67 +21,20 @@ * $Id$ */ -#ifndef _TMW_NETWORK_H -#define _TMW_NETWORK_H - -#ifndef WIN32 -#include "win2linux.h" -#else -#include <winsock.h> -#endif - -#include <stdio.h> - -#ifdef MACOSX -#include "win2mac.h" -#endif - -/** Macros to write in output buffer, pos is the location where to write data - After you wrote len bytes, you have to use WFIFOSET */ -#define WFIFOSPACE (buffer_size-out_size) // Number of bytes currently written in uotput buffer -#define WFIFOP(pos) (out+(pos+out_size)) // Return a pointer to a specific location in output buffer -#define WFIFOB(pos) (*(unsigned char *)(out+pos+out_size)) // Write a byte (1 byte) -#define WFIFOW(pos) (*(unsigned short *)(out+pos+out_size)) // Write a word (2 byte) -#define WFIFOL(pos) (*(unsigned int *)(out+pos+out_size)) // Write a long (4 byte) -//#define WFIFOSET(len) out_size+=len // Increase size of written data - -#ifdef MACOSX - #define net_b_value(id) (id) - #define net_w_value(id) DR_SwapTwoBytes(id) - #define net_l_value(id) DR_SwapFourBytes(id) -#else - #define net_b_value(id) (id) - #define net_w_value(id) (id) - #define net_l_value(id) (id) -#endif +#ifndef _TMW_NETWORK_ +#define _TMW_NETWORK_ +#include <string> -/** Macros to read from input buffer, pos is the location of data to be read - After you read len bytes, you should use RFIFOSKIP */ -#define RFIFOP(pos) (in+(pos)) // Get a pointer from a specific location in input buffer - -#ifdef MACOSX - #define RFIFOB(pos) ((*(unsigned char*)(in+(pos)))) // Read a byte - #define RFIFOW(pos) DR_SwapTwoBytes((*(unsigned short*)(in+(pos)))) // Read a word - #define RFIFOL(pos) DR_SwapFourBytes((*(unsigned int*)(in+(pos)))) // Read a long -#else - #define RFIFOB(pos) (*(unsigned char*)(in+(pos))) // Read a byte - #define RFIFOW(pos) (*(unsigned short*)(in+(pos))) // Read a word - #define RFIFOL(pos) (*(unsigned int*)(in+(pos))) // Read a long -#endif - -#define RFIFOSKIP(len) (memcpy(in,in+len,in_size-len));in_size-=len; // Empty len bytes from input buffer -#define RFIFOSPACE (buffer_size-in_size) // Return input buffer size -#define RFIFOSET(len) in_size+=len; - -/** Increase size of written data */ -void WFIFOSET(int len); +#include "SDL_net.h" +#include "messagein.h" +#include "messageout.h" /** Convert an address from int format to string */ char *iptostring(int address); /** Open a session with a server */ -SOCKET open_session(const char* address, short port); +int open_session(const char* address, short port); /** Close a session */ void close_session(); @@ -89,7 +42,21 @@ void close_session(); /** Send and receive data waiting in the buffers */ void flush(); -extern char *in, *out; // Input, output buffer -extern int in_size, out_size; // Input, output buffer size +/** + * Returns the next arriving message, waiting for it if necessary. + */ +MessageIn get_next_message(); +extern char *out; + + +void writeByte(int pos, unsigned char value);//writeByte(char value); +void writeWord(int pos, unsigned short value);//writeWord(short value); +void writeLong(int pos, unsigned int value);//writeLong(int value); +char *writePointer(int pos); //writeString(const std::string &string, int length); +void writeSet(unsigned int value); +void skip(int len); + +extern unsigned int in_size; /**< Amount of data in input buffer. */ +extern unsigned int out_size; /**< Amount of data in output buffer. */ #endif diff --git a/src/net/packet.cpp b/src/net/packet.cpp new file mode 100644 index 00000000..b8ee1e7f --- /dev/null +++ b/src/net/packet.cpp @@ -0,0 +1,40 @@ +/* + * The Mana World + * Copyright 2004 The Mana World Development Team + * + * This file is part of The Mana World. + * + * The Mana World 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. + * + * The Mana World 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 The Mana World; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +#include "packet.h" +#include <string.h> +#include <cstdlib> + +Packet::Packet(const char *data, int length): + length(length) +{ + // Create a copy of the data + this->data = new char[length]; + memcpy(this->data, data, length); +} + +Packet::~Packet() +{ + // Clean up the data + delete[] data; +} diff --git a/src/net/packet.h b/src/net/packet.h new file mode 100644 index 00000000..6b9fd18d --- /dev/null +++ b/src/net/packet.h @@ -0,0 +1,47 @@ +/* + * The Mana World + * Copyright 2004 The Mana World Development Team + * + * This file is part of The Mana World. + * + * The Mana World 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. + * + * The Mana World 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 The Mana World; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +#ifndef _TMW_PACKET_ +#define _TMW_PACKET_ + +/** + * A packet wraps a certain amount of bytes for sending and receiving. + */ +class Packet +{ + public: + /** + * Constructor. + */ + Packet(const char *data, int length); + + /** + * Destructor. + */ + ~Packet(); + + char *data; /**< Packet data */ + unsigned int length; /**< Length of data in bytes */ +}; + +#endif diff --git a/src/net/protocol.cpp b/src/net/protocol.cpp index ce27b7ea..17076b90 100644 --- a/src/net/protocol.cpp +++ b/src/net/protocol.cpp @@ -23,10 +23,6 @@ #include "protocol.h" -#ifndef WIN32 -#include "win2linux.h" -#endif - #include "network.h" #include "../being.h" @@ -36,111 +32,24 @@ #include "../playerinfo.h" #include "../sound.h" +#define LOBYTE(w) ((unsigned char)(w)) +#define HIBYTE(w) ((unsigned char)(((unsigned short)(w)) >> 8)) -short packet_lengths[] = { - 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// #0x0040 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 55, 17, 3, 37, 46, -1, 23, -1, 3,108, 3, 2, - 3, 28, 19, 11, 3, -1, 9, 5, 54, 53, 58, 60, 41, 2, 6, 6, -// #0x0080 - 7, 3, 2, 2, 2, 5, 16, 12, 10, 7, 29, 23, -1, -1, -1, 0, - 7, 22, 28, 2, 6, 30, -1, -1, 3, -1, -1, 5, 9, 17, 17, 6, - 23, 6, 6, -1, -1, -1, -1, 8, 7, 6, 7, 4, 7, 0, -1, 6, - 8, 8, 3, 3, -1, 6, 6, -1, 7, 6, 2, 5, 6, 44, 5, 3, -// #0x00C0 - 7, 2, 6, 8, 6, 7, -1, -1, -1, -1, 3, 3, 6, 6, 2, 27, - 3, 4, 4, 2, -1, -1, 3, -1, 6, 14, 3, -1, 28, 29, -1, -1, - 30, 30, 26, 2, 6, 26, 3, 3, 8, 19, 5, 2, 3, 2, 2, 2, - 3, 2, 6, 8, 21, 8, 8, 2, 2, 26, 3, -1, 6, 27, 30, 10, -// #0x0100 - 2, 6, 6, 30, 79, 31, 10, 10, -1, -1, 4, 6, 6, 2, 11, -1, - 10, 39, 4, 10, 31, 35, 10, 18, 2, 13, 15, 20, 68, 2, 3, 16, - 6, 14, -1, -1, 21, 8, 8, 8, 8, 8, 2, 2, 3, 4, 2, -1, - 6, 86, 6, -1, -1, 7, -1, 6, 3, 16, 4, 4, 4, 6, 24, 26, -// #0x0140 - 22, 14, 6, 10, 23, 19, 6, 39, 8, 9, 6, 27, -1, 2, 6, 6, - 110, 6, -1, -1, -1, -1, -1, 6, -1, 54, 66, 54, 90, 42, 6, 42, - -1, -1, -1, -1, -1, 30, -1, 3, 14, 3, 30, 10, 43, 14,186,182, - 14, 30, 10, 3, -1, 6,106, -1, 4, 5, 4, -1, 6, 7, -1, -1, -// #0x0180 - 6, 3,106, 10, 10, 34, 0, 6, 8, 4, 4, 4, 29, -1, 10, 6, - 90, 86, 24, 6, 30,102, 9, 4, 8, 4, 14, 10, 4, 6, 2, 6, - 3, 3, 35, 5, 11, 26, -1, 4, 4, 6, 10, 12, 6, -1, 4, 4, - 11, 7, -1, 67, 12, 18,114, 6, 3, 6, 26, 26, 26, 26, 2, 3, -// #0x01C0 - 2, 14, 10, -1, 22, 22, 4, 2, 13, 97, 0, 9, 9, 29, 6, 28, - 8, 14, 10, 35, 6, 8, 4, 11, 54, 53, 60, 2, -1, 47, 33, 6, - 30, 8, 34, 14, 2, 6, 26, 2, 28, 81, 6, 10, 26, 2, -1, -1, - -1, -1, 20, 10, 32, 9, 34, 14, 2, 6, 48, 56, -1, 4, 5, 10, -// #0x200 - 26, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -short get_length(short id) { - return packet_lengths[id]; -} - -unsigned short get_dest_x(const char *data) { - short temp; - temp = MAKEWORD(data[3], data[2] & 0x000f); - temp >>= 2; - return temp; -} - -unsigned short get_dest_y(const char *data) { - return MAKEWORD(data[4], data[3] & 0x0003); -} - -unsigned short get_src_x(const char *data) { - short temp; - temp = MAKEWORD(data[1], data[0]); - temp >>= 6; - return temp; -} - -unsigned short get_src_y(const char *data) { - short temp; - temp = MAKEWORD(data[2], data[1] & 0x003f); - temp >>= 4; - return temp; -} - -unsigned char get_src_direction(char data) { +unsigned char get_src_direction(char data) +{ data >>= 4; return data; } -unsigned char get_dest_direction(char data) { +unsigned char get_dest_direction(char data) +{ return data & 0x000f; } -unsigned short get_x(const char *data) { - short temp; - temp = MAKEWORD(data[1] & 0x00c0, data[0] & 0x00ff); - temp >>= 6; - return temp; -} - -unsigned short get_y(const char *data) { - short temp; - if (!data) throw "Corrupted data"; - temp = MAKEWORD(data[2] & 0x00f0, data[1] & 0x003f); - temp >>= 4; - return temp; -} - -unsigned char get_direction(const char *data) { - return data[2] & 0x000f; -} - -void set_coordinates(char *data, unsigned short x, unsigned short y, - unsigned char direction) +void set_coordinates(char *data, + unsigned short x, + unsigned short y, + unsigned char direction) { short temp; temp = x; @@ -149,7 +58,7 @@ void set_coordinates(char *data, unsigned short x, unsigned short y, data[1] = 1; data[2] = 2; data[0] = HIBYTE(temp); - data[1] = LOBYTE(temp); + data[1] = (unsigned char)(temp); temp = y; temp <<= 4; data[1] |= HIBYTE(temp); @@ -160,7 +69,7 @@ void set_coordinates(char *data, unsigned short x, unsigned short y, void map_start() { // Connect to map server - if (open_session(iptostring(map_address), map_port) == SOCKET_ERROR) + 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"; @@ -168,63 +77,70 @@ void map_start() } // Send login infos - WFIFOW(0) = net_w_value(0x0072); - WFIFOL(2) = net_l_value(account_ID); - WFIFOL(6) = net_l_value(char_ID); - WFIFOL(10) = net_l_value(session_ID1); - WFIFOL(14) = net_l_value(session_ID2); - WFIFOB(18) = net_b_value(sex); - WFIFOSET(19); - + writeWord(0, 0x0072); + writeLong(2, account_ID); + writeLong(6, char_ID); + writeLong(10, session_ID1); + writeLong(14, session_ID2); + writeByte(18, sex); + writeSet(19); + + // Skip a mysterious 4 bytes while ((in_size < 4)|| (out_size > 0)) flush(); - RFIFOSKIP(4); + skip(4); - while (in_size < 2) flush(); + MessageIn msg = get_next_message(); - if (RFIFOW(0) == SMSG_LOGIN_SUCCESS) { - while (in_size < 11) flush(); - startX = get_x(RFIFOP(6)); - startY = get_y(RFIFOP(6)); - int direction = get_direction(RFIFOP(6)); + 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); - RFIFOSKIP(11); - } else if (0x0081) { + } + else if (msg.getId() == 0x0081) + { logger->log("Warning: Map server D/C"); - } else { + } + else + { logger->error("Unknown packet: map_start"); } + skip(msg.getLength()); + // Send "map loaded" - WFIFOW(0) = net_w_value(0x007d); - WFIFOSET(2); - while (out_size > 0) flush(); + writeWord(0, 0x007d); + writeSet(2); + flush(); } void walk(unsigned short x, unsigned short y, unsigned char direction) { char temp[3]; set_coordinates(temp, x, y, direction); - WFIFOW(0) = net_w_value(0x0085); - memcpy(WFIFOP(2), temp, 3); - WFIFOSET(5); + writeWord(0, 0x0085); + memcpy(writePointer(2), temp, 3); + writeSet(5); } void speak(char *speech) { int len = (int)strlen(speech); - WFIFOW(0) = net_w_value(0x008c); - WFIFOW(2) = net_w_value(len + 4); - memcpy(WFIFOP(4), speech, len); - WFIFOSET(len + 4); + writeWord(0, 0x008c); + writeWord(2, len + 4); + memcpy(writePointer(4), speech, len); + writeSet(len + 4); } void action(char type, int id) { - WFIFOW(0) = net_w_value(0x0089); - WFIFOL(2) = net_l_value(id); - WFIFOB(6) = net_b_value(type); - WFIFOSET(7); + writeWord(0, 0x0089); + writeLong(2, id); + writeByte(6, type); + writeSet(7); } Being* attack(unsigned short x, unsigned short y, unsigned char direction) @@ -278,7 +194,7 @@ void attack(Being *target) } // Implement charging attacks here - char_info->lastAttackTime = 0; + player_info->lastAttackTime = 0; player_node->action = Being::ATTACK; action(0, target->getId()); diff --git a/src/net/protocol.h b/src/net/protocol.h index 3fa039ba..69b36783 100644 --- a/src/net/protocol.h +++ b/src/net/protocol.h @@ -21,52 +21,74 @@ * $Id$ */ -#ifndef _TMW_PROTOCOL_H -#define _TMW_PROTOCOL_H +#ifndef _TMW_PROTOCOL_ +#define _TMW_PROTOCOL_ class Being; // Packets from server to client -#define SMSG_LOGIN_SUCCESS 0x0073 /**< Logged in, starting location */ -#define SMSG_REMOVE_BEING 0x0080 /**< Died, logged out, teleport ... */ -#define SMSG_MOVE_BEING 0x007b /**< A nearby monster moves */ -#define SMSG_PLAYER_UPDATE_1 0x01d8 -#define SMSG_PLAYER_UPDATE_2 0x01d9 -#define SMSG_MOVE_PLAYER_BEING 0x01da /**< A nearby player moves */ -#define SMSG_CHANGE_BEING_LOOKS 0x00c3 -#define SMSG_BEING_CHAT 0x008d /**< A being talks */ -#define SMSG_MY_BEING_CHAT 0x008e /**< My being talks */ -#define SMSG_GM_CHAT 0x009a /**< GM announce */ -#define SMSG_WALK_RESPONSE 0x0087 +#define SMSG_LOGIN_SUCCESS 0x0073 /**< Contains starting location */ +#define SMSG_PLAYER_UPDATE_1 0x01d8 +#define SMSG_PLAYER_UPDATE_2 0x01d9 +#define SMSG_PLAYER_MOVE 0x01da /**< A nearby player moves */ +#define SMSG_PLAYER_STAT_UPDATE_1 0x00b0 +#define SMSG_PLAYER_STAT_UPDATE_2 0x00b1 +#define SMSG_PLAYER_STAT_UPDATE_3 0x0141 +#define SMSG_PLAYER_STAT_UPDATE_4 0x00bc +#define SMSG_PLAYER_STAT_UPDATE_5 0x00bd +#define SMSG_PLAYER_STAT_UPDATE_6 0x00be +#define SMSG_PLAYER_WARP 0x0091 /**< Warp player to map/location */ +#define SMSG_PLAYER_INVENTORY 0x01ee +#define SMSG_PLAYER_INVENTORY_ADD 0x00a0 +#define SMSG_PLAYER_INVENTORY_REMOVE 0x00af +#define SMSG_PLAYER_INVENTORY_USE 0x01c8 +#define SMSG_PLAYER_EQUIPMENT 0x00a4 +#define SMSG_PLAYER_EQUIP 0x00aa +#define SMSG_PLAYER_UNEQUIP 0x00ac +#define SMSG_PLAYER_ARROW_EQUIP 0x013c +#define SMSG_PLAYER_ARROW_MESSAGE 0x013b +#define SMSG_PLAYER_SKILLS 0x010f +#define SMSG_SKILL_FAILED 0x0110 +#define SMSG_ITEM_USE_RESPONSE 0x00a8 +#define SMSG_ITEM_VISIBLE 0x009d /**< An item is on the floor */ +#define SMSG_ITEM_DROPPED 0x009e /**< An item is dropped */ +#define SMSG_ITEM_REMOVE 0x00a1 /**< An item disappers */ +#define SMSG_BEING_VISIBLE 0x0078 +#define SMSG_BEING_MOVE 0x007b /**< A nearby monster moves */ +#define SMSG_BEING_REMOVE 0x0080 +#define SMSG_BEING_CHANGE_LOOKS 0x00c3 +#define SMSG_BEING_LEVELUP 0x019b +#define SMSG_BEING_EMOTION 0x00c0 +#define SMSG_BEING_ACTION 0x008a /**< Attack, sit, stand up, ... */ +#define SMSG_BEING_CHAT 0x008d /**< A being talks */ +#define SMSG_BEING_NAME_RESPONSE 0x0095 /**< Has to be requested */ +#define SMSG_NPC_MESSAGE 0x00b4 +#define SMSG_NPC_NEXT 0x00b5 +#define SMSG_NPC_CLOSE 0x00b6 +#define SMSG_NPC_CHOICE 0x00b7 /**< Display a choice */ +#define SMSG_NPC_BUY_SELL_CHOICE 0x00c4 +#define SMSG_NPC_BUY 0x00c6 +#define SMSG_NPC_SELL 0x00c7 +#define SMSG_NPC_BUY_RESPONSE 0x00ca +#define SMSG_NPC_SELL_RESPONSE 0x00cb +#define SMSG_PLAYER_CHAT 0x008e /**< Player talks */ +#define SMSG_GM_CHAT 0x009a /**< GM announce */ +#define SMSG_WALK_RESPONSE 0x0087 +#define SMSG_TRADE_REQUEST 0x00e5 /**< Receiving a request to trade */ +#define SMSG_TRADE_RESPONSE 0x00e7 +#define SMSG_TRADE_ITEM_ADD 0x00e9 +#define SMSG_TRADE_ITEM_ADD_RESPONSE 0x01b1 /**< Not standard eAthena! */ +#define SMSG_TRADE_OK 0x00ec +#define SMSG_TRADE_CANCEL 0x00ee +#define SMSG_TRADE_COMPLETE 0x00f0 + +// Packets from client to server +#define CMSG_TRADE_RESPONSE 0x00e6 -/** Packet length by id */ -short get_length(short id); - -/** Decodes x coord */ -unsigned short get_x(const char *data); - -/** Decodes y coord */ -unsigned short get_y(const char *data); - -/** Decodes direction */ -unsigned char get_direction(const char *data); - -/** Decodes src x coord */ -unsigned short get_src_x(const char *data); - -/** Decodes src y coord */ -unsigned short get_src_y(const char *data); - /** Decodes src direction */ unsigned char get_src_direction(char data); -/** Decodes dest x coord */ -unsigned short get_dest_x(const char *data); - -/** Decodes dest y coord */ -unsigned short get_dest_y(const char *data); - /** Decodes dest direction */ unsigned char get_dest_direction(char data); diff --git a/src/net/win2linux.h b/src/net/win2linux.h deleted file mode 100644 index 1371f4d9..00000000 --- a/src/net/win2linux.h +++ /dev/null @@ -1,51 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <stdio.h> -#include <unistd.h> -#include <arpa/inet.h> -#include <netdb.h> - -typedef unsigned char BYTE; -typedef unsigned short WORD; -#define MAKEWORD(low,high) \ - ((WORD)(((BYTE)(low)) | ((WORD)((BYTE)(high))) << 8)) -#define closesocket(a) close(a) -#define SOCKET int -#define SOCKET_ERROR -1 -#define SOCKADDR_IN struct sockaddr_in -typedef struct sockaddr SOCKADDR; -typedef SOCKADDR * LPSOCKADDR; -#define WSACleanup() ; - - - -typedef unsigned short WORD; -typedef unsigned long int LWORD; -typedef unsigned char BYTE; -#define LOBYTE(w) ((BYTE) (w) ) -#define HIBYTE(w) ((BYTE) (((WORD)(w)) >> 8) ) -#define LOWORD(l) ((WORD) (l) ) -#define HIWORD(l) ((WORD) (((LWORD)(l)) >> 16) ) -#define HANDLE int -#define HANDLE int -#define PHANDLE int -#define SMALL_RECT int -//#define WORD int -#define DWORD int -#define PDWORD int -#define BOOL int -#define LPBOOL int -#define LPSTR int -#define LPTSTR int -#define LPCTSTR int -#define LPDWORD int -#define LPVOID int -#define WINAPI - -#define LOBYTE(w) ((BYTE) (w) ) -#define HIBYTE(w) ((BYTE) (((WORD)(w)) >> 8) ) -#define LPTHREAD_START_ROUTINE void *(*)(void *) -#define CloseHandle close diff --git a/src/net/win2mac.cpp b/src/net/win2mac.cpp index 6ddc59cc..d6da2cf2 100644 --- a/src/net/win2mac.cpp +++ b/src/net/win2mac.cpp @@ -1,5 +1,7 @@ #include "win2mac.h" +#define SWAP( a, b ) { char c; c=a; a=b; b=c; } + UInt32 DR_SwapFourBytes(UInt32 dw) { UInt32 tmp; @@ -21,15 +23,9 @@ UInt16 DR_SwapTwoBytes(UInt16 w) char* SwapChar(char charlist[]) { for (int i = 0; i < 24 / 2; i++) - SWAP(charlist[i],charlist[24 - i]); - return charlist; -} + { + SWAP(charlist[i], charlist[24 - i]); + } -/* -char* SwapChar(char charlist[]) -{ - for (int i = 0; i < sizeof(charlist) * 4 / 2; i++) - SWAP(charlist[i],charlist[sizeof(charlist) * 4 - i]); return charlist; } -*/ diff --git a/src/net/win2mac.h b/src/net/win2mac.h index 8159f4a3..29102fae 100644 --- a/src/net/win2mac.h +++ b/src/net/win2mac.h @@ -1,13 +1,10 @@ -#ifndef _TMW_MAC_H -#define _TMW_MAC_H +#ifndef _TMW_WIN2MAC_ +#define _TMW_WIN2MAC_ #include <stdio.h> #define UInt16 unsigned short int -#define INT16 short int #define UInt32 unsigned long int -#define INT32 long int -#define SWAP( a, b ) { char c; c=a; a=b; b=c; } UInt32 DR_SwapFourBytes(UInt32 dw); UInt16 DR_SwapTwoBytes(UInt16 w); |