summaryrefslogtreecommitdiff
path: root/src/net
diff options
context:
space:
mode:
Diffstat (limited to 'src/net')
-rw-r--r--src/net/messagein.cpp151
-rw-r--r--src/net/messagein.h94
-rw-r--r--src/net/messageout.cpp130
-rw-r--r--src/net/messageout.h80
-rw-r--r--src/net/network.cpp361
-rw-r--r--src/net/network.h79
-rw-r--r--src/net/packet.cpp40
-rw-r--r--src/net/packet.h47
-rw-r--r--src/net/protocol.cpp188
-rw-r--r--src/net/protocol.h96
-rw-r--r--src/net/win2linux.h51
-rw-r--r--src/net/win2mac.cpp14
-rw-r--r--src/net/win2mac.h7
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);