From 92a6fd04d44bcd405641d7297a0167e2d5aba26f Mon Sep 17 00:00:00 2001 From: Thorbjørn Lindeijer Date: Tue, 13 Feb 2024 12:31:13 +0100 Subject: Updated tmwAthena network protocol * The code defining the message IDs and sizes are now generated by the tools/protocol.py script in the tmwAthena repository. * Reduced client version from 20 to 6, because that is currently the minimum supported version, and any adjustments needed for later likely still need to be made. * Removed use of no longer handled messages: - CMSG_SKILL_USE_BEING - CMSG_SKILL_USE_POSITION - CMSG_SKILL_USE_MAP - SMSG_PARTY_MOVE - CMSG_WHO_REQUEST - SMSG_WHO_ANSWER - SMSG_MVP - SMSG_BEING_MOVE2 - SMSG_BEING_CHANGE_LOOKS * Some messages were renamed to match the server side - CMSG_PLAYER_ATTACK -> CMSG_PLAYER_CHANGE_ACT - CMSG_PLAYER_RESTART -> CMSG_PLAYER_REBOOT - SMSG_ADMIN_IP -> SMSG_BEING_IP_RESPONSE Part of addressing issues #55 and #47, which we now know are about handling SMSG_PLAYER_HP and SMSG_NPC_COMMAND respectively. The client will now ignore them (with a warning) instead of crash. --- src/commandhandler.cpp | 13 +- src/net/chathandler.h | 7 +- src/net/gamehandler.h | 2 - src/net/guildhandler.h | 4 +- src/net/manaserv/chathandler.h | 3 +- src/net/manaserv/gamehandler.cpp | 5 - src/net/manaserv/gamehandler.h | 2 - src/net/tmwa/adminhandler.cpp | 4 +- src/net/tmwa/beinghandler.cpp | 48 +---- src/net/tmwa/charserverhandler.cpp | 2 +- src/net/tmwa/chathandler.cpp | 13 -- src/net/tmwa/chathandler.h | 4 +- src/net/tmwa/gamehandler.cpp | 10 - src/net/tmwa/gamehandler.h | 2 - src/net/tmwa/loginhandler.cpp | 4 +- src/net/tmwa/network.cpp | 362 +++++++++++++++++++++---------- src/net/tmwa/network.h | 24 +-- src/net/tmwa/partyhandler.cpp | 15 +- src/net/tmwa/playerhandler.cpp | 6 +- src/net/tmwa/protocol.h | 426 ++++++++++++++++--------------------- src/net/tmwa/specialhandler.cpp | 14 -- 21 files changed, 471 insertions(+), 499 deletions(-) diff --git a/src/commandhandler.cpp b/src/commandhandler.cpp index 3211dcc3..c35e9ee3 100644 --- a/src/commandhandler.cpp +++ b/src/commandhandler.cpp @@ -23,17 +23,13 @@ #include "actorspritemanager.h" #include "channelmanager.h" -#include "channel.h" #include "game.h" #include "localplayer.h" #include "playerrelations.h" -#include "gui/widgets/channeltab.h" #include "gui/widgets/chattab.h" -#include "net/adminhandler.h" #include "net/chathandler.h" -#include "net/gamehandler.h" #include "net/net.h" #include "net/partyhandler.h" @@ -151,13 +147,16 @@ char CommandHandler::parseBoolean(const std::string &value) void CommandHandler::handleHelp(const std::string &args, ChatTab *tab) { - if (args == "") + if (args.empty()) { tab->chatLog(_("-- Help --")); tab->chatLog(_("/help > Display this help")); tab->chatLog(_("/where > Display map name")); - tab->chatLog(_("/who > Display number of online users")); + + if (Net::getChatHandler()->whoSupported()) + tab->chatLog(_("/who > Display number of online users")); + tab->chatLog(_("/me > Tell something about yourself")); tab->chatLog(_("/clear > Clears this window")); @@ -304,7 +303,7 @@ void CommandHandler::handleHelp(const std::string &args, ChatTab *tab) tab->chatLog(_("Command: /where")); tab->chatLog(_("This command displays the name of the current map.")); } - else if (args == "who") + else if (args == "who" && Net::getChatHandler()->whoSupported()) { tab->chatLog(_("Command: /who")); tab->chatLog(_("This command displays the number of players currently " diff --git a/src/net/chathandler.h b/src/net/chathandler.h index cb1371b4..c324c2d8 100644 --- a/src/net/chathandler.h +++ b/src/net/chathandler.h @@ -22,13 +22,14 @@ #ifndef CHATHANDLER_H #define CHATHANDLER_H -#include +#include namespace Net { + class ChatHandler { public: - virtual ~ChatHandler() {} + virtual ~ChatHandler() = default; virtual void talk(const std::string &text) = 0; @@ -55,6 +56,8 @@ class ChatHandler virtual void kickUser(int channelId, const std::string &name) = 0; virtual void who() = 0; + + virtual bool whoSupported() const = 0; }; } diff --git a/src/net/gamehandler.h b/src/net/gamehandler.h index 40e4b099..3f47aba5 100644 --- a/src/net/gamehandler.h +++ b/src/net/gamehandler.h @@ -37,8 +37,6 @@ class GameHandler virtual void disconnect() = 0; - virtual void who() = 0; - virtual void quit() = 0; virtual bool removeDeadBeings() const = 0; diff --git a/src/net/guildhandler.h b/src/net/guildhandler.h index ce48cd9a..11ca93b0 100644 --- a/src/net/guildhandler.h +++ b/src/net/guildhandler.h @@ -24,7 +24,7 @@ #include "guild.h" -#include +#include class Being; @@ -33,7 +33,7 @@ namespace Net { class GuildHandler { public: - virtual ~GuildHandler() {} + virtual ~GuildHandler() = default; virtual bool isSupported() { return false; } diff --git a/src/net/manaserv/chathandler.h b/src/net/manaserv/chathandler.h index f9602407..4ad04a70 100644 --- a/src/net/manaserv/chathandler.h +++ b/src/net/manaserv/chathandler.h @@ -23,7 +23,6 @@ #define NET_MANASERV_CHATHANDLER_H #include "net/chathandler.h" -#include "net/serverinfo.h" #include "net/manaserv/messagehandler.h" @@ -71,6 +70,8 @@ class ChatHandler : public MessageHandler, public Net::ChatHandler void who() override; + bool whoSupported() const override { return true; } + private: /** * Handle chat messages sent from the game server. diff --git a/src/net/manaserv/gamehandler.cpp b/src/net/manaserv/gamehandler.cpp index 265c0d8a..1bf4d69f 100644 --- a/src/net/manaserv/gamehandler.cpp +++ b/src/net/manaserv/gamehandler.cpp @@ -115,11 +115,6 @@ void GameHandler::disconnect() chatHandler->disconnect(); } -void GameHandler::who() -{ - // TODO -} - void GameHandler::quit(bool reconnectAccount) { MessageOut msg(PGMSG_DISCONNECT); diff --git a/src/net/manaserv/gamehandler.h b/src/net/manaserv/gamehandler.h index 2bc56ef0..01d23b43 100644 --- a/src/net/manaserv/gamehandler.h +++ b/src/net/manaserv/gamehandler.h @@ -44,8 +44,6 @@ class GameHandler : public MessageHandler, public Net::GameHandler void disconnect() override; - void who() override; - void quit(bool reconnectAccount); void quit() override { quit(false); } diff --git a/src/net/tmwa/adminhandler.cpp b/src/net/tmwa/adminhandler.cpp index ce2a8264..70e732be 100644 --- a/src/net/tmwa/adminhandler.cpp +++ b/src/net/tmwa/adminhandler.cpp @@ -45,7 +45,7 @@ AdminHandler::AdminHandler() static const uint16_t _messages[] = { SMSG_ADMIN_KICK_ACK, - SMSG_ADMIN_IP, + SMSG_BEING_IP_RESPONSE, 0 }; handledMessages = _messages; @@ -64,7 +64,7 @@ void AdminHandler::handleMessage(MessageIn &msg) else SERVER_NOTICE(_("Kick succeeded!")) break; - case SMSG_ADMIN_IP: + case SMSG_BEING_IP_RESPONSE: id = msg.readInt32(); int ip = msg.readInt32(); if (Being *player = actorSpriteManager->findBeing(id)) diff --git a/src/net/tmwa/beinghandler.cpp b/src/net/tmwa/beinghandler.cpp index 3027efc8..33908fc9 100644 --- a/src/net/tmwa/beinghandler.cpp +++ b/src/net/tmwa/beinghandler.cpp @@ -20,7 +20,6 @@ */ #include "net/tmwa/beinghandler.h" -#include "net/tmwa/playerhandler.h" #include "actorspritemanager.h" #include "being.h" @@ -33,14 +32,15 @@ #include "party.h" #include "playerrelations.h" +#include "net/net.h" +#include "net/playerhandler.h" #include "net/tmwa/messagein.h" #include "net/tmwa/messageout.h" #include "net/tmwa/protocol.h" -#include "resources/hairdb.h" #include "resources/emotedb.h" +#include "resources/hairdb.h" -#include #include namespace TmwAthena { @@ -56,13 +56,11 @@ BeingHandler::BeingHandler(bool enableSync): SMSG_BEING_VISIBLE, SMSG_BEING_MOVE, SMSG_BEING_SPAWN, - SMSG_BEING_MOVE2, SMSG_BEING_REMOVE, SMSG_SKILL_DAMAGE, SMSG_BEING_ACTION, SMSG_BEING_SELFEFFECT, SMSG_BEING_EMOTION, - SMSG_BEING_CHANGE_LOOKS, SMSG_BEING_CHANGE_LOOKS2, SMSG_BEING_NAME_RESPONSE, SMSG_PLAYER_GUILD_PARTY_INFO, @@ -288,31 +286,6 @@ void BeingHandler::handleMessage(MessageIn &msg) // Do nothing. break; - case SMSG_BEING_MOVE2: - { - /* - * A simplified movement packet, used by the - * later versions of eAthena for both mobs and - * players - */ - dstBeing = actorSpriteManager->findBeing(msg.readInt32()); - - /* - * This packet doesn't have enough info to actually - * create a new being, so if the being isn't found, - * we'll just pretend the packet didn't happen - */ - - if (!dstBeing) - break; - - Uint16 srcX, srcY, dstX, dstY; - msg.readCoordinatePair(srcX, srcY, dstX, dstY); - msg.readInt32(); // Server tick - handleMoveMessage(map, dstBeing, srcX, srcY, dstX, dstY); - } - break; - case SMSG_BEING_REMOVE: // A being should be removed or has died id = msg.readInt32(); @@ -435,7 +408,6 @@ void BeingHandler::handleMessage(MessageIn &msg) break; - case SMSG_BEING_CHANGE_LOOKS: case SMSG_BEING_CHANGE_LOOKS2: { /* @@ -456,18 +428,8 @@ void BeingHandler::handleMessage(MessageIn &msg) } int type = msg.readInt8(); - int id = 0; - int id2 = 0; - - if (msg.getId() == SMSG_BEING_CHANGE_LOOKS) - { - id = msg.readInt8(); - } - else - { // SMSG_BEING_CHANGE_LOOKS2 - id = msg.readInt16(); - id2 = msg.readInt16(); - } + int id = msg.readInt16(); + int id2 = msg.readInt16(); switch (type) { diff --git a/src/net/tmwa/charserverhandler.cpp b/src/net/tmwa/charserverhandler.cpp index 45c07bec..324afd2d 100644 --- a/src/net/tmwa/charserverhandler.cpp +++ b/src/net/tmwa/charserverhandler.cpp @@ -342,7 +342,7 @@ void CharServerHandler::deleteCharacter(Net::Character *character) void CharServerHandler::switchCharacter() { // This is really a map-server packet - MessageOut outMsg(CMSG_PLAYER_RESTART); + MessageOut outMsg(CMSG_PLAYER_REBOOT); outMsg.writeInt8(1); } diff --git a/src/net/tmwa/chathandler.cpp b/src/net/tmwa/chathandler.cpp index 155263b5..beed01a1 100644 --- a/src/net/tmwa/chathandler.cpp +++ b/src/net/tmwa/chathandler.cpp @@ -24,7 +24,6 @@ #include "actorspritemanager.h" #include "being.h" #include "event.h" -#include "game.h" #include "localplayer.h" #include "playerrelations.h" @@ -49,7 +48,6 @@ ChatHandler::ChatHandler() SMSG_WHISPER, SMSG_WHISPER_RESPONSE, SMSG_GM_CHAT, - SMSG_MVP, // MVP 0 }; handledMessages = _messages; @@ -240,12 +238,6 @@ void ChatHandler::handleMessage(MessageIn &msg) } break; } - - case SMSG_MVP: - // Display MVP player - msg.readInt32(); // id - SERVER_NOTICE(_("MVP player.")) - break; } } @@ -318,9 +310,4 @@ void ChatHandler::kickUser(int channelId, const std::string &name) SERVER_NOTICE(_("Channels are not supported!")) } -void ChatHandler::who() -{ - MessageOut outMsg(CMSG_WHO_REQUEST); -} - } // namespace TmwAthena diff --git a/src/net/tmwa/chathandler.h b/src/net/tmwa/chathandler.h index 682a3743..a21692c9 100644 --- a/src/net/tmwa/chathandler.h +++ b/src/net/tmwa/chathandler.h @@ -62,7 +62,9 @@ class ChatHandler : public MessageHandler, public Net::ChatHandler void kickUser(int channelId, const std::string &name) override; - void who() override; + void who() override {} + + bool whoSupported() const override { return false; } private: using WhisperQueue = std::queue; diff --git a/src/net/tmwa/gamehandler.cpp b/src/net/tmwa/gamehandler.cpp index 44ce6bc0..0f423d8d 100644 --- a/src/net/tmwa/gamehandler.cpp +++ b/src/net/tmwa/gamehandler.cpp @@ -36,7 +36,6 @@ #include "net/tmwa/protocol.h" #include "utils/gettext.h" -#include "utils/stringutils.h" extern Net::GameHandler *gameHandler; @@ -48,7 +47,6 @@ GameHandler::GameHandler() { static const Uint16 _messages[] = { SMSG_MAP_LOGIN_SUCCESS, - SMSG_WHO_ANSWER, SMSG_CHAR_SWITCH_RESPONSE, SMSG_MAP_QUIT_RESPONSE, 0 @@ -78,10 +76,6 @@ void GameHandler::handleMessage(MessageIn &msg) mTileX = x; mTileY = y; } break; - case SMSG_WHO_ANSWER: - SERVER_NOTICE(strprintf(_("Online users: %d"), msg.readInt32())) - break; - case SMSG_CHAR_SWITCH_RESPONSE: if (msg.readInt8()) { @@ -162,10 +156,6 @@ void GameHandler::disconnect() mNetwork->disconnect(); } -void GameHandler::who() -{ -} - void GameHandler::quit() { MessageOut outMsg(CMSG_CLIENT_QUIT); diff --git a/src/net/tmwa/gamehandler.h b/src/net/tmwa/gamehandler.h index 8859c9c6..d1722669 100644 --- a/src/net/tmwa/gamehandler.h +++ b/src/net/tmwa/gamehandler.h @@ -49,8 +49,6 @@ class GameHandler : public MessageHandler, public Net::GameHandler, void disconnect() override; - void who() override; - void quit() override; bool removeDeadBeings() const override { return true; } diff --git a/src/net/tmwa/loginhandler.cpp b/src/net/tmwa/loginhandler.cpp index 3e742f88..55336a84 100644 --- a/src/net/tmwa/loginhandler.cpp +++ b/src/net/tmwa/loginhandler.cpp @@ -307,8 +307,8 @@ void LoginHandler::unregisterAccount(const std::string &username, void LoginHandler::sendLoginRegister(const std::string &username, const std::string &password) { - MessageOut outMsg(0x0064); - outMsg.writeInt32(20); // client version + MessageOut outMsg(CMSG_LOGIN_REGISTER); + outMsg.writeInt32(6); // client version outMsg.writeString(username, 24); outMsg.writeString(password, 24); diff --git a/src/net/tmwa/network.cpp b/src/net/tmwa/network.cpp index f5aeaf91..17c6b53e 100644 --- a/src/net/tmwa/network.cpp +++ b/src/net/tmwa/network.cpp @@ -35,61 +35,202 @@ /** Warning: buffers and other variables are shared, so there can be only one connection active at a time */ +namespace TmwAthena { + +struct PacketInfo +{ + uint16_t id; + uint16_t length; + const char *name; +}; + // indicator for a variable-length packet const uint16_t VAR = 1; -uint16_t 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, 50, 3,VAR, 55, 17, 3, 37, 46,VAR, 23,VAR, 3,108, 3, 2, - 3, 28, 19, 11, 3,VAR, 9, 5, 54, 53, 58, 60, 41, 2, 6, 6, -// #0x0080 - 7, 3, 2, 2, 2, 5, 16, 12, 10, 7, 29, 23,VAR,VAR,VAR, 0, - 7, 22, 28, 2, 6, 30,VAR,VAR, 3,VAR,VAR, 5, 9, 17, 17, 6, - 23, 6, 6,VAR,VAR,VAR,VAR, 8, 7, 6, 7, 4, 7, 0,VAR, 6, - 8, 8, 3, 3,VAR, 6, 6,VAR, 7, 6, 2, 5, 6, 44, 5, 3, -// #0x00C0 - 7, 2, 6, 8, 6, 7,VAR,VAR,VAR,VAR, 3, 3, 6, 6, 2, 27, - 3, 4, 4, 2,VAR,VAR, 3,VAR, 6, 14, 3,VAR, 28, 29,VAR,VAR, - 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,VAR, 6, 27, 30, 10, -// #0x0100 - 2, 6, 6, 30, 79, 31, 10, 10,VAR,VAR, 4, 6, 6, 2, 11,VAR, - 10, 39, 4, 10, 31, 35, 10, 18, 2, 13, 15, 20, 68, 2, 3, 16, - 6, 14,VAR,VAR, 21, 8, 8, 8, 8, 8, 2, 2, 3, 4, 2,VAR, - 6, 86, 6,VAR,VAR, 7,VAR, 6, 3, 16, 4, 4, 4, 6, 24, 26, -// #0x0140 - 22, 14, 6, 10, 23, 19, 6, 39, 8, 9, 6, 27,VAR, 2, 6, 6, - 110, 6,VAR,VAR,VAR,VAR,VAR, 6,VAR, 54, 66, 54, 90, 42, 6, 42, - VAR,VAR,VAR,VAR,VAR, 30,VAR, 3, 14, 3, 30, 10, 43, 14,186,182, - 14, 30, 10, 3,VAR, 6,106,VAR, 4, 5, 4,VAR, 6, 7,VAR,VAR, -// #0x0180 - 6, 3,106, 10, 10, 34, 0, 6, 8, 4, 4, 4, 29,VAR, 10, 6, - 90, 86, 24, 6, 30, 102, 9, 4, 8, 4, 14, 10, 4, 6, 2, 6, - 3, 3, 35, 5, 11, 26,VAR, 4, 4, 6, 10, 12, 6,VAR, 4, 4, - 11, 7,VAR, 67, 12, 18,114, 6, 3, 6, 26, 26, 26, 26, 2, 3, -// #0x01C0 - 2, 14, 10,VAR, 22, 22, 4, 2, 13, 97, 0, 9, 9, 29, 6, 28, - 8, 14, 10, 35, 6,VAR, 4, 11, 54, 53, 60, 2,VAR, 47, 33, 6, - 30, 8, 34, 14, 2, 6, 26, 2, 28, 81, 6, 10, 26, 2,VAR,VAR, - VAR,VAR, 20, 10, 32, 9, 34, 14, 2, 6, 48, 56,VAR, 4, 5, 10, -// #0x0200 - 26, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 19, 10, 0, 0, 0, - 2,VAR, 16, 0, 8,VAR, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - VAR,122,VAR,VAR,VAR,VAR, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, +static const PacketInfo packet_infos[] = { + // login server messages + { SMSG_UPDATE_HOST, VAR, "SMSG_UPDATE_HOST" }, + { CMSG_LOGIN_REGISTER, 55, "CMSG_LOGIN_REGISTER" }, + { SMSG_LOGIN_DATA, VAR, "SMSG_LOGIN_DATA" }, + { SMSG_LOGIN_ERROR, 23, "SMSG_LOGIN_ERROR" }, + + // char server messages + { CMSG_CHAR_PASSWORD_CHANGE, 50, "CMSG_CHAR_PASSWORD_CHANGE" }, + { SMSG_CHAR_PASSWORD_RESPONSE, 3, "SMSG_CHAR_PASSWORD_RESPONSE" }, + { CMSG_CHAR_SERVER_CONNECT, 17, "CMSG_CHAR_SERVER_CONNECT" }, + { CMSG_CHAR_SELECT, 3, "CMSG_CHAR_SELECT" }, + { CMSG_CHAR_CREATE, 37, "CMSG_CHAR_CREATE" }, + { CMSG_CHAR_DELETE, 46, "CMSG_CHAR_DELETE" }, + { SMSG_CHAR_LOGIN, VAR, "SMSG_CHAR_LOGIN" }, + { SMSG_CHAR_LOGIN_ERROR, 3, "SMSG_CHAR_LOGIN_ERROR" }, + { SMSG_CHAR_CREATE_SUCCEEDED, 108, "SMSG_CHAR_CREATE_SUCCEEDED" }, + { SMSG_CHAR_CREATE_FAILED, 3, "SMSG_CHAR_CREATE_FAILED" }, + { SMSG_CHAR_DELETE_SUCCEEDED, 2, "SMSG_CHAR_DELETE_SUCCEEDED" }, + { SMSG_CHAR_DELETE_FAILED, 3, "SMSG_CHAR_DELETE_FAILED" }, + { SMSG_CHAR_MAP_INFO, 28, "SMSG_CHAR_MAP_INFO" }, + + // map server messages + { CMSG_MAP_SERVER_CONNECT, 19, "CMSG_MAP_SERVER_CONNECT" }, + { SMSG_MAP_LOGIN_SUCCESS, 11, "SMSG_MAP_LOGIN_SUCCESS" }, + { SMSG_BEING_VISIBLE, 54, "SMSG_BEING_VISIBLE" }, + { SMSG_BEING_MOVE, 60, "SMSG_BEING_MOVE" }, + { SMSG_BEING_SPAWN, 41, "SMSG_BEING_SPAWN" }, + { CMSG_MAP_LOADED, 2, "CMSG_MAP_LOADED" }, + { CMSG_MAP_PING, 6, "CMSG_MAP_PING" }, + { SMSG_SERVER_PING, 6, "SMSG_SERVER_PING" }, + { SMSG_BEING_REMOVE, 7, "SMSG_BEING_REMOVE" }, + { CMSG_PLAYER_CHANGE_DEST, 5, "CMSG_PLAYER_CHANGE_DEST" }, + { SMSG_WALK_RESPONSE, 12, "SMSG_WALK_RESPONSE" }, + { SMSG_PLAYER_STOP, 10, "SMSG_PLAYER_STOP" }, + { CMSG_PLAYER_CHANGE_ACT, 7, "CMSG_PLAYER_CHANGE_ACT" }, + { SMSG_BEING_ACTION, 29, "SMSG_BEING_ACTION" }, + { CMSG_CHAT_MESSAGE, VAR, "CMSG_CHAT_MESSAGE" }, + { SMSG_BEING_CHAT, VAR, "SMSG_BEING_CHAT" }, + { SMSG_PLAYER_CHAT, VAR, "SMSG_PLAYER_CHAT" }, + { CMSG_NPC_TALK, 7, "CMSG_NPC_TALK" }, + { SMSG_PLAYER_WARP, 22, "SMSG_PLAYER_WARP" }, + { SMSG_CHANGE_MAP_SERVER, 28, "SMSG_CHANGE_MAP_SERVER" }, + { CMSG_NAME_REQUEST, 6, "CMSG_NAME_REQUEST" }, + { SMSG_BEING_NAME_RESPONSE, 30, "SMSG_BEING_NAME_RESPONSE" }, + { CMSG_CHAT_WHISPER, VAR, "CMSG_CHAT_WHISPER" }, + { SMSG_WHISPER, VAR, "SMSG_WHISPER" }, + { SMSG_WHISPER_RESPONSE, 3, "SMSG_WHISPER_RESPONSE" }, + { SMSG_GM_CHAT, VAR, "SMSG_GM_CHAT" }, + { CMSG_PLAYER_CHANGE_DIR, 5, "CMSG_PLAYER_CHANGE_DIR" }, + { SMSG_BEING_CHANGE_DIRECTION, 9, "SMSG_BEING_CHANGE_DIRECTION" }, + { SMSG_ITEM_VISIBLE, 17, "SMSG_ITEM_VISIBLE" }, + { SMSG_ITEM_DROPPED, 17, "SMSG_ITEM_DROPPED" }, + { CMSG_ITEM_PICKUP, 6, "CMSG_ITEM_PICKUP" }, + { SMSG_PLAYER_INVENTORY_ADD, 23, "SMSG_PLAYER_INVENTORY_ADD" }, + { SMSG_ITEM_REMOVE, 6, "SMSG_ITEM_REMOVE" }, + { CMSG_PLAYER_INVENTORY_DROP, 6, "CMSG_PLAYER_INVENTORY_DROP" }, + { SMSG_PLAYER_EQUIPMENT, VAR, "SMSG_PLAYER_EQUIPMENT" }, + { SMSG_PLAYER_STORAGE_EQUIP, VAR, "SMSG_PLAYER_STORAGE_EQUIP" }, + { CMSG_PLAYER_INVENTORY_USE, 8, "CMSG_PLAYER_INVENTORY_USE" }, + { SMSG_ITEM_USE_RESPONSE, 7, "SMSG_ITEM_USE_RESPONSE" }, + { CMSG_PLAYER_EQUIP, 6, "CMSG_PLAYER_EQUIP" }, + { SMSG_PLAYER_EQUIP, 7, "SMSG_PLAYER_EQUIP" }, + { CMSG_PLAYER_UNEQUIP, 4, "CMSG_PLAYER_UNEQUIP" }, + { SMSG_PLAYER_UNEQUIP, 7, "SMSG_PLAYER_UNEQUIP" }, + { SMSG_PLAYER_INVENTORY_REMOVE, 6, "SMSG_PLAYER_INVENTORY_REMOVE" }, + { SMSG_PLAYER_STAT_UPDATE_1, 8, "SMSG_PLAYER_STAT_UPDATE_1" }, + { SMSG_PLAYER_STAT_UPDATE_2, 8, "SMSG_PLAYER_STAT_UPDATE_2" }, + { CMSG_PLAYER_REBOOT, 3, "CMSG_PLAYER_REBOOT" }, + { SMSG_CHAR_SWITCH_RESPONSE, 3, "SMSG_CHAR_SWITCH_RESPONSE" }, + { SMSG_NPC_MESSAGE, VAR, "SMSG_NPC_MESSAGE" }, + { SMSG_NPC_NEXT, 6, "SMSG_NPC_NEXT" }, + { SMSG_NPC_CLOSE, 6, "SMSG_NPC_CLOSE" }, + { SMSG_NPC_CHOICE, VAR, "SMSG_NPC_CHOICE" }, + { CMSG_NPC_LIST_CHOICE, 7, "CMSG_NPC_LIST_CHOICE" }, + { CMSG_NPC_NEXT_REQUEST, 6, "CMSG_NPC_NEXT_REQUEST" }, + { CMSG_STAT_UPDATE_REQUEST, 5, "CMSG_STAT_UPDATE_REQUEST" }, + { SMSG_PLAYER_STAT_UPDATE_4, 6, "SMSG_PLAYER_STAT_UPDATE_4" }, + { SMSG_PLAYER_STAT_UPDATE_5, 44, "SMSG_PLAYER_STAT_UPDATE_5" }, + { SMSG_PLAYER_STAT_UPDATE_6, 5, "SMSG_PLAYER_STAT_UPDATE_6" }, + { CMSG_PLAYER_EMOTE, 3, "CMSG_PLAYER_EMOTE" }, + { SMSG_BEING_EMOTION, 7, "SMSG_BEING_EMOTION" }, + { SMSG_NPC_BUY_SELL_CHOICE, 6, "SMSG_NPC_BUY_SELL_CHOICE" }, + { CMSG_NPC_BUY_SELL_REQUEST, 7, "CMSG_NPC_BUY_SELL_REQUEST" }, + { SMSG_NPC_BUY, VAR, "SMSG_NPC_BUY" }, + { SMSG_NPC_SELL, VAR, "SMSG_NPC_SELL" }, + { CMSG_NPC_BUY_REQUEST, VAR, "CMSG_NPC_BUY_REQUEST" }, + { CMSG_NPC_SELL_REQUEST, VAR, "CMSG_NPC_SELL_REQUEST" }, + { SMSG_NPC_BUY_RESPONSE, 3, "SMSG_NPC_BUY_RESPONSE" }, + { SMSG_NPC_SELL_RESPONSE, 3, "SMSG_NPC_SELL_RESPONSE" }, + { SMSG_ADMIN_KICK_ACK, 6, "SMSG_ADMIN_KICK_ACK" }, + { CMSG_TRADE_REQUEST, 6, "CMSG_TRADE_REQUEST" }, + { SMSG_TRADE_REQUEST, 26, "SMSG_TRADE_REQUEST" }, + { CMSG_TRADE_RESPONSE, 3, "CMSG_TRADE_RESPONSE" }, + { SMSG_TRADE_RESPONSE, 3, "SMSG_TRADE_RESPONSE" }, + { CMSG_TRADE_ITEM_ADD_REQUEST, 8, "CMSG_TRADE_ITEM_ADD_REQUEST" }, + { SMSG_TRADE_ITEM_ADD, 19, "SMSG_TRADE_ITEM_ADD" }, + { CMSG_TRADE_ADD_COMPLETE, 2, "CMSG_TRADE_ADD_COMPLETE" }, + { SMSG_TRADE_OK, 3, "SMSG_TRADE_OK" }, + { CMSG_TRADE_CANCEL_REQUEST, 2, "CMSG_TRADE_CANCEL_REQUEST" }, + { SMSG_TRADE_CANCEL, 2, "SMSG_TRADE_CANCEL" }, + { CMSG_TRADE_OK, 2, "CMSG_TRADE_OK" }, + { SMSG_TRADE_COMPLETE, 3, "SMSG_TRADE_COMPLETE" }, + { SMSG_PLAYER_STORAGE_STATUS, 6, "SMSG_PLAYER_STORAGE_STATUS" }, + { CMSG_MOVE_TO_STORAGE, 8, "CMSG_MOVE_TO_STORAGE" }, + { SMSG_PLAYER_STORAGE_ADD, 21, "SMSG_PLAYER_STORAGE_ADD" }, + { CMSG_MOVE_FROM_STORAGE, 8, "CMSG_MOVE_FROM_STORAGE" }, + { SMSG_PLAYER_STORAGE_REMOVE, 8, "SMSG_PLAYER_STORAGE_REMOVE" }, + { CMSG_CLOSE_STORAGE, 2, "CMSG_CLOSE_STORAGE" }, + { SMSG_PLAYER_STORAGE_CLOSE, 2, "SMSG_PLAYER_STORAGE_CLOSE" }, + { CMSG_PARTY_CREATE, 26, "CMSG_PARTY_CREATE" }, + { SMSG_PARTY_CREATE, 3, "SMSG_PARTY_CREATE" }, + { SMSG_PARTY_INFO, VAR, "SMSG_PARTY_INFO" }, + { CMSG_PARTY_INVITE, 6, "CMSG_PARTY_INVITE" }, + { SMSG_PARTY_INVITE_RESPONSE, 27, "SMSG_PARTY_INVITE_RESPONSE" }, + { SMSG_PARTY_INVITED, 30, "SMSG_PARTY_INVITED" }, + { CMSG_PARTY_INVITED, 10, "CMSG_PARTY_INVITED" }, + { CMSG_PARTY_LEAVE, 2, "CMSG_PARTY_LEAVE" }, + { SMSG_PARTY_SETTINGS, 6, "SMSG_PARTY_SETTINGS" }, + { CMSG_PARTY_SETTINGS, 6, "CMSG_PARTY_SETTINGS" }, + { CMSG_PARTY_KICK, 30, "CMSG_PARTY_KICK" }, + { SMSG_PARTY_LEAVE, 31, "SMSG_PARTY_LEAVE" }, + { SMSG_PARTY_UPDATE_HP, 10, "SMSG_PARTY_UPDATE_HP" }, + { SMSG_PARTY_UPDATE_COORDS, 10, "SMSG_PARTY_UPDATE_COORDS" }, + { CMSG_PARTY_MESSAGE, VAR, "CMSG_PARTY_MESSAGE" }, + { SMSG_PARTY_MESSAGE, VAR, "SMSG_PARTY_MESSAGE" }, + { SMSG_PLAYER_SKILL_UP, 11, "SMSG_PLAYER_SKILL_UP" }, + { SMSG_PLAYER_SKILLS, VAR, "SMSG_PLAYER_SKILLS" }, + { SMSG_SKILL_FAILED, 10, "SMSG_SKILL_FAILED" }, + { CMSG_SKILL_LEVELUP_REQUEST, 4, "CMSG_SKILL_LEVELUP_REQUEST" }, + { CMSG_PLAYER_STOP_ATTACK, 2, "CMSG_PLAYER_STOP_ATTACK" }, + { SMSG_PLAYER_STATUS_CHANGE, 13, "SMSG_PLAYER_STATUS_CHANGE" }, + { SMSG_PLAYER_MOVE_TO_ATTACK, 16, "SMSG_PLAYER_MOVE_TO_ATTACK" }, + { SMSG_PLAYER_ATTACK_RANGE, 4, "SMSG_PLAYER_ATTACK_RANGE" }, + { SMSG_PLAYER_ARROW_MESSAGE, 4, "SMSG_PLAYER_ARROW_MESSAGE" }, + { SMSG_PLAYER_ARROW_EQUIP, 4, "SMSG_PLAYER_ARROW_EQUIP" }, + { SMSG_PLAYER_STAT_UPDATE_3, 14, "SMSG_PLAYER_STAT_UPDATE_3" }, + { SMSG_NPC_INT_INPUT, 6, "SMSG_NPC_INT_INPUT" }, + { CMSG_NPC_INT_RESPONSE, 10, "CMSG_NPC_INT_RESPONSE" }, + { CMSG_NPC_CLOSE, 6, "CMSG_NPC_CLOSE" }, + { SMSG_BEING_RESURRECT, 8, "SMSG_BEING_RESURRECT" }, + { CMSG_CLIENT_QUIT, 4, "CMSG_CLIENT_QUIT" }, + { SMSG_MAP_QUIT_RESPONSE, 4, "SMSG_MAP_QUIT_RESPONSE" }, + { SMSG_PLAYER_GUILD_PARTY_INFO, 102, "SMSG_PLAYER_GUILD_PARTY_INFO" }, + { SMSG_BEING_STATUS_CHANGE, 9, "SMSG_BEING_STATUS_CHANGE" }, + { SMSG_PVP_MAP_MODE, 4, "SMSG_PVP_MAP_MODE" }, + { SMSG_PVP_SET, 14, "SMSG_PVP_SET" }, + { SMSG_BEING_SELFEFFECT, 10, "SMSG_BEING_SELFEFFECT" }, + { SMSG_TRADE_ITEM_ADD_RESPONSE, 7, "SMSG_TRADE_ITEM_ADD_RESPONSE" }, + { SMSG_PLAYER_INVENTORY_USE, 13, "SMSG_PLAYER_INVENTORY_USE" }, + { SMSG_NPC_STR_INPUT, 6, "SMSG_NPC_STR_INPUT" }, + { CMSG_NPC_STR_RESPONSE, VAR, "CMSG_NPC_STR_RESPONSE" }, + { SMSG_BEING_CHANGE_LOOKS2, 11, "SMSG_BEING_CHANGE_LOOKS2" }, + { SMSG_PLAYER_UPDATE_1, 54, "SMSG_PLAYER_UPDATE_1" }, + { SMSG_PLAYER_UPDATE_2, 53, "SMSG_PLAYER_UPDATE_2" }, + { SMSG_PLAYER_MOVE, 60, "SMSG_PLAYER_MOVE" }, + { SMSG_SKILL_DAMAGE, 33, "SMSG_SKILL_DAMAGE" }, + { SMSG_PLAYER_INVENTORY, VAR, "SMSG_PLAYER_INVENTORY" }, + { SMSG_PLAYER_STORAGE_ITEMS, VAR, "SMSG_PLAYER_STORAGE_ITEMS" }, + { SMSG_BEING_IP_RESPONSE, 10, "SMSG_BEING_IP_RESPONSE" }, + { CMSG_ONLINE_LIST, 2, "CMSG_ONLINE_LIST" }, + { SMSG_ONLINE_LIST, VAR, "SMSG_ONLINE_LIST" }, + { SMSG_NPC_COMMAND, 16, "SMSG_NPC_COMMAND" }, + { SMSG_QUEST_SET_VAR, 8, "SMSG_QUEST_SET_VAR" }, + { SMSG_QUEST_PLAYER_VARS, VAR, "SMSG_QUEST_PLAYER_VARS" }, + { SMSG_BEING_MOVE3, VAR, "SMSG_BEING_MOVE3" }, + { SMSG_MAP_MASK, 10, "SMSG_MAP_MASK" }, + { SMSG_MAP_MUSIC, VAR, "SMSG_MAP_MUSIC" }, + { SMSG_NPC_CHANGETITLE, VAR, "SMSG_NPC_CHANGETITLE" }, + { SMSG_SCRIPT_MESSAGE, VAR, "SMSG_SCRIPT_MESSAGE" }, + { SMSG_PLAYER_CLIENT_COMMAND, VAR, "SMSG_PLAYER_CLIENT_COMMAND" }, + { SMSG_MAP_SET_TILES_TYPE, 34, "SMSG_MAP_SET_TILES_TYPE" }, + { SMSG_PLAYER_HP, 10, "SMSG_PLAYER_HP" }, + { SMSG_PLAYER_HP_FULL, 14, "SMSG_PLAYER_HP_FULL" }, + + // any server messages + { SMSG_CONNECTION_PROBLEM, 3, "SMSG_CONNECTION_PROBLEM" }, + { CMSG_SERVER_VERSION_REQUEST, 2, "CMSG_SERVER_VERSION_REQUEST" }, + { SMSG_SERVER_VERSION_RESPONSE, 10, "SMSG_SERVER_VERSION_RESPONSE" }, + { CMSG_CLIENT_DISCONNECT, 2, "CMSG_CLIENT_DISCONNECT" }, }; -static const int packet_lengths_size - = static_cast(sizeof(packet_lengths) / sizeof(uint16_t)); const unsigned int BUFFER_SIZE = 65536; -namespace TmwAthena { - int networkThread(void *data) { auto *network = static_cast(data); @@ -105,17 +246,18 @@ int networkThread(void *data) Network *Network::mInstance = nullptr; Network::Network(): - mSocket(nullptr), mInBuffer(new char[BUFFER_SIZE]), - mOutBuffer(new char[BUFFER_SIZE]), - mInSize(0), mOutSize(0), - mToSkip(0), - mState(IDLE), - mWorkerThread(nullptr) + mOutBuffer(new char[BUFFER_SIZE]) { SDLNet_Init(); mInstance = this; + + for (const auto &packetInfo : packet_infos) + { + assert(packetInfo.length != 0); + mPacketInfo[packetInfo.id] = &packetInfo; + } } Network::~Network() @@ -209,35 +351,75 @@ void Network::unregisterHandler(MessageHandler *handler) void Network::clearHandlers() { - MessageHandlerIterator i; - for (i = mMessageHandlers.begin(); i != mMessageHandlers.end(); ++i) + for (auto& [_, messageHandler] : mMessageHandlers) { - i->second->setNetwork(nullptr); + messageHandler->setNetwork(nullptr); } mMessageHandlers.clear(); } void Network::dispatchMessages() { - while (messageReady()) - { - MessageIn msg = getNextMessage(); + MutexLocker lock(&mMutex); + + while (true) { + // Not even a message ID has been received + if (mInSize < 2) + break; - auto iter = mMessageHandlers.find(msg.getId()); + const uint16_t msgId = readWord(0); - if (msg.getLength() == 0) - logger->error("Zero length packet received. Exiting."); + auto packetInfoIt = mPacketInfo.find(msgId); + if (packetInfoIt == mPacketInfo.end()) + { + auto error = strprintf("Unknown packet 0x%x received.", msgId); + logger->error(error); + break; + } + + auto packetInfo = packetInfoIt->second; + + // Determine the length of the packet + uint16_t len = packetInfo->length; + if (len == VAR) + { + // We have not received the length yet + if (mInSize < 4) + break; + + len = readWord(2); + + if (len < 4) + { + auto error = strprintf("Variable length packet 0x%x has invalid length %d.", + msgId, len); + logger->error(error); + break; + } + } + // The message has not been fully received yet + if (mInSize < len) + break; + +#ifdef DEBUG + logger->log("Received %s (0x%x) of length %d", packetInfo->name, msgId, len); +#endif + + MessageIn message(mInBuffer, len); + + // Dispatch the message to the appropriate handler + auto iter = mMessageHandlers.find(msgId); if (iter != mMessageHandlers.end()) { - iter->second->handleMessage(msg); + iter->second->handleMessage(message); } else { - logger->log("Unhandled packet: %x", msg.getId()); + logger->log("Unhandled packet %s (0x%x)", packetInfo->name, msgId); } - skip(msg.getLength()); + skip(len); } } @@ -278,54 +460,6 @@ void Network::skip(int len) } } -bool Network::messageReady() -{ - MutexLocker lock(&mMutex); - if (mInSize < 2) - return false; - uint16_t msgId = readWord(0); - uint16_t len = 0; - // TODO don't hard-code this single case - if (msgId == SMSG_SERVER_VERSION_RESPONSE) - len = 10; - else if (msgId < packet_lengths_size) - len = packet_lengths[msgId]; - - if (len == VAR) - { - if (mInSize < 4) - return false; - len = readWord(2); - } - return mInSize >= len; -} - -MessageIn Network::getNextMessage() -{ - while (!messageReady()) - { - if (mState == NET_ERROR) - break; - } - - MutexLocker lock(&mMutex); - uint16_t msgId = readWord(0); - uint16_t len = 0; - if (msgId == SMSG_SERVER_VERSION_RESPONSE) - len = 10; - else if (msgId < 0x220) - len = packet_lengths[msgId]; - - if (len == VAR) - len = readWord(2); - -#ifdef DEBUG - logger->log("Received packet 0x%x of length %d", msgId, len); -#endif - - return MessageIn(mInBuffer, len); -} - bool Network::realConnect() { IPaddress ipAddress; diff --git a/src/net/tmwa/network.h b/src/net/tmwa/network.h index 4df44b75..36d8cafd 100644 --- a/src/net/tmwa/network.h +++ b/src/net/tmwa/network.h @@ -27,7 +27,6 @@ #include "net/serverinfo.h" #include "net/tmwa/messagehandler.h" -#include "net/tmwa/messagein.h" #include "net/tmwa/messageout.h" #include @@ -35,6 +34,7 @@ #include #include +#include /** * Protocol version, reported to the eAthena char and mapserver who can adjust @@ -45,6 +45,8 @@ namespace TmwAthena { +struct PacketInfo; + class Network { public: @@ -75,10 +77,6 @@ class Network void skip(int len); - bool messageReady(); - - MessageIn getNextMessage(); - void dispatchMessages(); void flush(); @@ -106,24 +104,24 @@ class Network void receive(); - TCPsocket mSocket; + TCPsocket mSocket = nullptr; ServerInfo mServer; char *mInBuffer, *mOutBuffer; - unsigned int mInSize, mOutSize; + unsigned int mInSize = 0; + unsigned int mOutSize = 0; - unsigned int mToSkip; + unsigned int mToSkip = 0; - int mState; + int mState = IDLE; std::string mError; - SDL_Thread *mWorkerThread; + SDL_Thread *mWorkerThread = nullptr; Mutex mMutex; - using MessageHandlers = std::map; - using MessageHandlerIterator = MessageHandlers::iterator; - MessageHandlers mMessageHandlers; + std::unordered_map mPacketInfo; + std::map mMessageHandlers; static Network *mInstance; }; diff --git a/src/net/tmwa/partyhandler.cpp b/src/net/tmwa/partyhandler.cpp index b8d9c3c7..958c8c14 100644 --- a/src/net/tmwa/partyhandler.cpp +++ b/src/net/tmwa/partyhandler.cpp @@ -55,7 +55,6 @@ PartyHandler::PartyHandler(): SMSG_PARTY_INVITE_RESPONSE, SMSG_PARTY_INVITED, SMSG_PARTY_SETTINGS, - SMSG_PARTY_MOVE, SMSG_PARTY_LEAVE, SMSG_PARTY_UPDATE_HP, SMSG_PARTY_UPDATE_COORDS, @@ -138,7 +137,7 @@ void PartyHandler::handleMessage(MessageIn &msg) { int id = msg.readInt32(); std::string partyName = msg.readString(24); - std::string nick = ""; + std::string nick; Being *being; if ((being = actorSpriteManager->findBeing(id))) @@ -212,18 +211,6 @@ void PartyHandler::handleMessage(MessageIn &msg) } break; } - case SMSG_PARTY_MOVE: - { - msg.readInt32(); // id - msg.skip(4); - msg.readInt16(); // x - msg.readInt16(); // y - msg.readInt8(); // online (if 0) - msg.readString(24); // party - msg.readString(24); // nick - msg.readString(16); // map - } - break; case SMSG_PARTY_LEAVE: { int id = msg.readInt32(); diff --git a/src/net/tmwa/playerhandler.cpp b/src/net/tmwa/playerhandler.cpp index 5c57b8aa..f704576e 100644 --- a/src/net/tmwa/playerhandler.cpp +++ b/src/net/tmwa/playerhandler.cpp @@ -20,7 +20,6 @@ */ #include "net/tmwa/playerhandler.h" -#include "net/tmwa/beinghandler.h" #include "client.h" #include "configuration.h" @@ -32,7 +31,6 @@ #include "gui/buydialog.h" #include "gui/buyselldialog.h" -#include "gui/gui.h" #include "gui/okdialog.h" #include "gui/selldialog.h" #include "gui/statuswindow.h" @@ -527,7 +525,7 @@ void PlayerHandler::handleMessage(MessageIn &msg) void PlayerHandler::attack(int id) { - MessageOut outMsg(CMSG_PLAYER_ATTACK); + MessageOut outMsg(CMSG_PLAYER_CHANGE_ACT); outMsg.writeInt32(id); outMsg.writeInt8(0); } @@ -611,7 +609,7 @@ void PlayerHandler::changeAction(Being::Action action) void PlayerHandler::respawn() { - MessageOut outMsg(CMSG_PLAYER_RESTART); + MessageOut outMsg(CMSG_PLAYER_REBOOT); outMsg.writeInt8(0); } diff --git a/src/net/tmwa/protocol.h b/src/net/tmwa/protocol.h index e9ea84e8..ea3d430e 100644 --- a/src/net/tmwa/protocol.h +++ b/src/net/tmwa/protocol.h @@ -63,251 +63,187 @@ enum static const int INVENTORY_OFFSET = 2; static const int STORAGE_OFFSET = 1; -/********************************* - * Packets from server to client * - *********************************/ -#define SMSG_SERVER_VERSION_RESPONSE 0x7531 - -#define SMSG_CONNECTION_PROBLEM 0x0081 - -#define SMSG_UPDATE_HOST 0x0063 /**< Custom update host packet */ -#define SMSG_LOGIN_DATA 0x0069 -#define SMSG_LOGIN_ERROR 0x006a - -#define SMSG_CHAR_LOGIN 0x006b -#define SMSG_CHAR_LOGIN_ERROR 0x006c -#define SMSG_CHAR_CREATE_SUCCEEDED 0x006d -#define SMSG_CHAR_CREATE_FAILED 0x006e -#define SMSG_CHAR_DELETE_SUCCEEDED 0x006f -#define SMSG_CHAR_DELETE_FAILED 0x0070 -#define SMSG_CHAR_MAP_INFO 0x0071 -#define SMSG_CHAR_PASSWORD_RESPONSE 0x0062 /**< Custom packet reply to password change request */ - -#define SMSG_CHAR_SWITCH_RESPONSE 0x00b3 -#define SMSG_CHANGE_MAP_SERVER 0x0092 - -#define SMSG_MAP_LOGIN_SUCCESS 0x0073 /**< Contains starting location */ -#define SMSG_MAP_QUIT_RESPONSE 0x018b -#define SMSG_PLAYER_UPDATE_1 0x01d8 -#define SMSG_PLAYER_UPDATE_2 0x01d9 -#define SMSG_PLAYER_MOVE 0x01da /**< A nearby player moves */ -#define SMSG_PLAYER_STOP 0x0088 /**< Stop walking, set position */ -#define SMSG_PLAYER_MOVE_TO_ATTACK 0x0139 /**< Move to within attack range */ -#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_WHO_ANSWER 0x00c2 -#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_ATTACK_RANGE 0x013a -#define SMSG_PLAYER_ARROW_EQUIP 0x013c -#define SMSG_PLAYER_ARROW_MESSAGE 0x013b -#define SMSG_PLAYER_SKILLS 0x010f -#define SMSG_PLAYER_SKILL_UP 0x010e // same as SMSG_GUILD_SKILL_UP -#define SMSG_SKILL_FAILED 0x0110 -#define SMSG_SKILL_DAMAGE 0x01de -#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_SPAWN 0x007c /**< A being spawns nearby */ -#define SMSG_BEING_MOVE2 0x0086 /**< New eAthena being moves */ -#define SMSG_BEING_REMOVE 0x0080 -#define SMSG_BEING_CHANGE_LOOKS 0x00c3 -#define SMSG_BEING_CHANGE_LOOKS2 0x01d7 /**< Same as 0x00c3, but 16 bit ID */ -#define SMSG_BEING_SELFEFFECT 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_BEING_CHANGE_DIRECTION 0x009c -#define SMSG_BEING_RESURRECT 0x0148 - -#define SMSG_PLAYER_STATUS_CHANGE 0x0119 -#define SMSG_PLAYER_GUILD_PARTY_INFO 0x0195 -#define SMSG_BEING_STATUS_CHANGE 0x0196 - -#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_NPC_INT_INPUT 0x0142 /**< Integer input */ -#define SMSG_NPC_STR_INPUT 0x01d4 /**< String input */ -#define SMSG_PLAYER_CHAT 0x008e /**< Player talks */ -#define SMSG_WHISPER 0x0097 /**< Whisper Recieved */ -#define SMSG_WHISPER_RESPONSE 0x0098 -#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 - -#define SMSG_PARTY_CREATE 0x00fa -#define SMSG_PARTY_INFO 0x00fb -#define SMSG_PARTY_INVITE_RESPONSE 0x00fd -#define SMSG_PARTY_INVITED 0x00fe -#define SMSG_PARTY_SETTINGS 0x0101 -#define SMSG_PARTY_MOVE 0x0104 -#define SMSG_PARTY_LEAVE 0x0105 -#define SMSG_PARTY_UPDATE_HP 0x0106 -#define SMSG_PARTY_UPDATE_COORDS 0x0107 -#define SMSG_PARTY_MESSAGE 0x0109 - -#define SMSG_PLAYER_STORAGE_ITEMS 0x01f0 /**< Item list for storage */ -#define SMSG_PLAYER_STORAGE_EQUIP 0x00a6 /**< Equipment list for storage */ -#define SMSG_PLAYER_STORAGE_STATUS 0x00f2 /**< Slots used and total slots */ -#define SMSG_PLAYER_STORAGE_ADD 0x00f4 /**< Add item/equip to storage */ -#define SMSG_PLAYER_STORAGE_REMOVE 0x00f6 /**< Remove item/equip from storage */ -#define SMSG_PLAYER_STORAGE_CLOSE 0x00f8 /**< Storage access closed */ - -#define SMSG_ADMIN_KICK_ACK 0x00cd -#define SMSG_ADMIN_IP 0x020c - -#define SMSG_GUILD_CREATE_RESPONSE 0x0167 -#define SMSG_GUILD_POSITION_INFO 0x016c -#define SMSG_GUILD_MEMBER_LOGIN 0x016d -#define SMSG_GUILD_MASTER_OR_MEMBER 0x014e -#define SMSG_GUILD_BASIC_INFO 0x01b6 -#define SMSG_GUILD_ALIANCE_INFO 0x014c -#define SMSG_GUILD_MEMBER_LIST 0x0154 -#define SMSG_GUILD_POS_NAME_LIST 0x0166 -#define SMSG_GUILD_POS_INFO_LIST 0x0160 -#define SMSG_GUILD_POSITION_CHANGED 0x0174 -#define SMSG_GUILD_MEMBER_POS_CHANGE 0x0156 -#define SMSG_GUILD_EMBLEM 0x0152 -#define SMSG_GUILD_SKILL_INFO 0x0162 -#define SMSG_GUILD_NOTICE 0x016f -#define SMSG_GUILD_INVITE 0x016a -#define SMSG_GUILD_INVITE_ACK 0x0169 -#define SMSG_GUILD_LEAVE 0x015a -#define SMSG_GUILD_EXPULSION 0x015c -#define SMSG_GUILD_EXPULSION_LIST 0x0163 -#define SMSG_GUILD_MESSAGE 0x017f -#define SMSG_GUILD_SKILL_UP 0x010e // same as SMSG_PLAYER_SKILL_UP -#define SMSG_GUILD_REQ_ALLIANCE 0x0171 -#define SMSG_GUILD_REQ_ALLIANCE_ACK 0x0173 -#define SMSG_GUILD_DEL_ALLIANCE 0x0184 -#define SMSG_GUILD_OPPOSITION_ACK 0x0181 -#define SMSG_GUILD_BROKEN 0x015e - -#define SMSG_MVP 0x010c - -#define SMSG_MAP_MASK 0x0226 - -/********************************** - * Packets from client to server * - **********************************/ -#define CMSG_SERVER_VERSION_REQUEST 0x7530 - -#define CMSG_CHAR_PASSWORD_CHANGE 0x0061 /**< Custom change password packet */ -#define CMSG_CHAR_SERVER_CONNECT 0x0065 -#define CMSG_CHAR_SELECT 0x0066 -#define CMSG_CHAR_CREATE 0x0067 -#define CMSG_CHAR_DELETE 0x0068 - -#define CMSG_MAP_SERVER_CONNECT 0x0072 -#define CMSG_MAP_LOADED 0x007d -#define CMSG_CLIENT_QUIT 0x018A - -#define CMSG_CHAT_MESSAGE 0x008c -#define CMSG_CHAT_WHISPER 0x0096 - -#define CMSG_SKILL_LEVELUP_REQUEST 0x0112 -#define CMSG_STAT_UPDATE_REQUEST 0x00bb -#define CMSG_SKILL_USE_BEING 0x0113 -#define CMSG_SKILL_USE_POSITION 0x0116 -// Variant of 0x116 with 80 char string at end (unsure of use) -#define CMSG_SKILL_USE_POSITION_MORE 0x0190 -#define CMSG_SKILL_USE_MAP 0x011b - -#define CMSG_PLAYER_INVENTORY_USE 0x00a7 -#define CMSG_PLAYER_INVENTORY_DROP 0x00a2 -#define CMSG_PLAYER_EQUIP 0x00a9 -#define CMSG_PLAYER_UNEQUIP 0x00ab - -#define CMSG_ITEM_PICKUP 0x009f -#define CMSG_PLAYER_CHANGE_DIR 0x009b -#define CMSG_PLAYER_CHANGE_DEST 0x0085 -#define CMSG_PLAYER_CHANGE_ACT 0x0089 // same as CMSG_PLAYER_ATTACK -#define CMSG_PLAYER_RESTART 0x00b2 -#define CMSG_PLAYER_EMOTE 0x00bf -#define CMSG_PLAYER_ATTACK 0x0089 // same as CMSG_PLAYER_CHANGE_ACT -#define CMSG_WHO_REQUEST 0x00c1 - -#define CMSG_NPC_TALK 0x0090 -#define CMSG_NPC_NEXT_REQUEST 0x00b9 -#define CMSG_NPC_CLOSE 0x0146 -#define CMSG_NPC_LIST_CHOICE 0x00b8 -#define CMSG_NPC_INT_RESPONSE 0x0143 -#define CMSG_NPC_STR_RESPONSE 0x01d5 -#define CMSG_NPC_BUY_SELL_REQUEST 0x00c5 -#define CMSG_NPC_BUY_REQUEST 0x00c8 -#define CMSG_NPC_SELL_REQUEST 0x00c9 - -#define CMSG_TRADE_REQUEST 0x00e4 -#define CMSG_TRADE_RESPONSE 0x00e6 -#define CMSG_TRADE_ITEM_ADD_REQUEST 0x00e8 -#define CMSG_TRADE_CANCEL_REQUEST 0x00ed -#define CMSG_TRADE_ADD_COMPLETE 0x00eb -#define CMSG_TRADE_OK 0x00ef - -#define CMSG_PARTY_CREATE 0x00f9 -#define CMSG_PARTY_INVITE 0x00fc -#define CMSG_PARTY_INVITED 0x00ff -#define CMSG_PARTY_LEAVE 0x0100 -#define CMSG_PARTY_SETTINGS 0x0102 -#define CMSG_PARTY_KICK 0x0103 -#define CMSG_PARTY_MESSAGE 0x0108 - -#define CMSG_MOVE_TO_STORAGE 0x00f3 /** Move item to storage */ -#define CMSG_MOVE_FROM_STORAGE 0x00f5 /** Remove item from storage */ -#define CMSG_CLOSE_STORAGE 0x00f7 /** Request storage close */ - -#define CMSG_ADMIN_ANNOUNCE 0x0099 -#define CMSG_ADMIN_LOCAL_ANNOUNCE 0x019C -#define CMSG_ADMIN_HIDE 0x019D -#define CMSG_ADMIN_KICK 0x00CC -#define CMSG_ADMIN_MUTE 0x0149 - -#define CMSG_GUILD_CHECK_MASTER 0x014d -#define CMSG_GUILD_REQUEST_INFO 0x014f -#define CMSG_GUILD_REQUEST_EMBLEM 0x0151 -#define CMSG_GUILD_CHANGE_EMBLEM 0x0153 -#define CMSG_GUILD_CHANGE_MEMBER_POS 0x0155 -#define CMSG_GUILD_LEAVE 0x0159 -#define CMSG_GUILD_EXPULSION 0x015b -#define CMSG_GUILD_BREAK 0x015d -#define CMSG_GUILD_CHANGE_POS_INFO 0x0161 -#define CMSG_GUILD_CREATE 0x0165 -#define CMSG_GUILD_INVITE 0x0168 -#define CMSG_GUILD_INVITE_REPLY 0x016b -#define CMSG_GUILD_CHANGE_NOTICE 0x016e -#define CMSG_GUILD_ALLIANCE_REQUEST 0x0170 -#define CMSG_GUILD_ALLIANCE_REPLY 0x0172 -#define CMSG_GUILD_MESSAGE 0x017e -#define CMSG_GUILD_OPPOSITION 0x0180 -#define CMSG_GUILD_ALLIANCE_DELETE 0x0183 +enum { + // login server messages + SMSG_UPDATE_HOST = 0x0063, // update host notify + CMSG_LOGIN_REGISTER = 0x0064, // account login + SMSG_LOGIN_DATA = 0x0069, // account login success + SMSG_LOGIN_ERROR = 0x006a, // account login error + + // char server messages + CMSG_CHAR_PASSWORD_CHANGE = 0x0061, // change password + SMSG_CHAR_PASSWORD_RESPONSE = 0x0062, // change password result + CMSG_CHAR_SERVER_CONNECT = 0x0065, // connect char + CMSG_CHAR_SELECT = 0x0066, // select character + CMSG_CHAR_CREATE = 0x0067, // create character + CMSG_CHAR_DELETE = 0x0068, // delete character + SMSG_CHAR_LOGIN = 0x006b, // connect char success + SMSG_CHAR_LOGIN_ERROR = 0x006c, // connect char error + SMSG_CHAR_CREATE_SUCCEEDED = 0x006d, // create character success + SMSG_CHAR_CREATE_FAILED = 0x006e, // create character error + SMSG_CHAR_DELETE_SUCCEEDED = 0x006f, // delete character success + SMSG_CHAR_DELETE_FAILED = 0x0070, // delete character error + SMSG_CHAR_MAP_INFO = 0x0071, // select character success + + // map server messages + CMSG_MAP_SERVER_CONNECT = 0x0072, // connect map + SMSG_MAP_LOGIN_SUCCESS = 0x0073, // connect map success + SMSG_BEING_VISIBLE = 0x0078, // being appear notify + SMSG_BEING_MOVE = 0x007b, // being move notify + SMSG_BEING_SPAWN = 0x007c, // being spawn notify + CMSG_MAP_LOADED = 0x007d, // map loaded + CMSG_MAP_PING = 0x007e, // ping + SMSG_SERVER_PING = 0x007f, // pong + SMSG_BEING_REMOVE = 0x0080, // remove being notify + CMSG_PLAYER_CHANGE_DEST = 0x0085, // walk + SMSG_WALK_RESPONSE = 0x0087, // walk success + SMSG_PLAYER_STOP = 0x0088, // stop walking notify + CMSG_PLAYER_CHANGE_ACT = 0x0089, // player action + SMSG_BEING_ACTION = 0x008a, // being action notify + CMSG_CHAT_MESSAGE = 0x008c, // global chat + SMSG_BEING_CHAT = 0x008d, // global chat notify + SMSG_PLAYER_CHAT = 0x008e, // global chat result + CMSG_NPC_TALK = 0x0090, // npc click + SMSG_PLAYER_WARP = 0x0091, // change map notify + SMSG_CHANGE_MAP_SERVER = 0x0092, // change map server notify + CMSG_NAME_REQUEST = 0x0094, // get being name + SMSG_BEING_NAME_RESPONSE = 0x0095, // get being name result + CMSG_CHAT_WHISPER = 0x0096, // whisper + SMSG_WHISPER = 0x0097, // receive whisper + SMSG_WHISPER_RESPONSE = 0x0098, // whisper result + SMSG_GM_CHAT = 0x009a, // gm announcement notify + CMSG_PLAYER_CHANGE_DIR = 0x009b, // face direction + SMSG_BEING_CHANGE_DIRECTION = 0x009c, // face direction notify + SMSG_ITEM_VISIBLE = 0x009d, // item visible notify + SMSG_ITEM_DROPPED = 0x009e, // item dropped notify + CMSG_ITEM_PICKUP = 0x009f, // item pickup + SMSG_PLAYER_INVENTORY_ADD = 0x00a0, // inventory add notify + SMSG_ITEM_REMOVE = 0x00a1, // flooritem delete notify + CMSG_PLAYER_INVENTORY_DROP = 0x00a2, // drop item + SMSG_PLAYER_EQUIPMENT = 0x00a4, // inventory equipment notify + SMSG_PLAYER_STORAGE_EQUIP = 0x00a6, // storage equipment notify + CMSG_PLAYER_INVENTORY_USE = 0x00a7, // use item + SMSG_ITEM_USE_RESPONSE = 0x00a8, // use item result + CMSG_PLAYER_EQUIP = 0x00a9, // equip item + SMSG_PLAYER_EQUIP = 0x00aa, // equip item result + CMSG_PLAYER_UNEQUIP = 0x00ab, // unequip item + SMSG_PLAYER_UNEQUIP = 0x00ac, // unequip item result + SMSG_PLAYER_INVENTORY_REMOVE = 0x00af, // inventory delete notify + SMSG_PLAYER_STAT_UPDATE_1 = 0x00b0, // player stat update 1 notify + SMSG_PLAYER_STAT_UPDATE_2 = 0x00b1, // player stat update 2 notify + CMSG_PLAYER_REBOOT = 0x00b2, // respawn or switch character + SMSG_CHAR_SWITCH_RESPONSE = 0x00b3, // character switch success + SMSG_NPC_MESSAGE = 0x00b4, // script message notify + SMSG_NPC_NEXT = 0x00b5, // (reverse) script next + SMSG_NPC_CLOSE = 0x00b6, // (reverse) script close + SMSG_NPC_CHOICE = 0x00b7, // (reverse) script menu + CMSG_NPC_LIST_CHOICE = 0x00b8, // (reverse) script menu result + CMSG_NPC_NEXT_REQUEST = 0x00b9, // (reverse) script next result + CMSG_STAT_UPDATE_REQUEST = 0x00bb, // stat increase + SMSG_PLAYER_STAT_UPDATE_4 = 0x00bc, // stat increase result + SMSG_PLAYER_STAT_UPDATE_5 = 0x00bd, // player stat update 5 notify + SMSG_PLAYER_STAT_UPDATE_6 = 0x00be, // stat price notify + CMSG_PLAYER_EMOTE = 0x00bf, // emote + SMSG_BEING_EMOTION = 0x00c0, // emote notify + SMSG_NPC_BUY_SELL_CHOICE = 0x00c4, // npc click result shop + CMSG_NPC_BUY_SELL_REQUEST = 0x00c5, // npc shop buy/sell select + SMSG_NPC_BUY = 0x00c6, // npc shop buy select result + SMSG_NPC_SELL = 0x00c7, // npc shop sell select result + CMSG_NPC_BUY_REQUEST = 0x00c8, // npc shop buy + CMSG_NPC_SELL_REQUEST = 0x00c9, // npc shop sell + SMSG_NPC_BUY_RESPONSE = 0x00ca, // npc shop buy result + SMSG_NPC_SELL_RESPONSE = 0x00cb, // npc shop sell result + SMSG_ADMIN_KICK_ACK = 0x00cd, // kick result + CMSG_TRADE_REQUEST = 0x00e4, // trade please + SMSG_TRADE_REQUEST = 0x00e5, // incoming trade request + CMSG_TRADE_RESPONSE = 0x00e6, // incoming trade request result + SMSG_TRADE_RESPONSE = 0x00e7, // trade please result + CMSG_TRADE_ITEM_ADD_REQUEST = 0x00e8, // trade add + SMSG_TRADE_ITEM_ADD = 0x00e9, // trade item added notify + CMSG_TRADE_ADD_COMPLETE = 0x00eb, // trade lock + SMSG_TRADE_OK = 0x00ec, // trade lock notify + CMSG_TRADE_CANCEL_REQUEST = 0x00ed, // trade cancel + SMSG_TRADE_CANCEL = 0x00ee, // trade cancel notify + CMSG_TRADE_OK = 0x00ef, // trade commit + SMSG_TRADE_COMPLETE = 0x00f0, // trade complete notify + SMSG_PLAYER_STORAGE_STATUS = 0x00f2, // storage size notify + CMSG_MOVE_TO_STORAGE = 0x00f3, // storage put + SMSG_PLAYER_STORAGE_ADD = 0x00f4, // storage added notify + CMSG_MOVE_FROM_STORAGE = 0x00f5, // storage take + SMSG_PLAYER_STORAGE_REMOVE = 0x00f6, // storage removed notify + CMSG_CLOSE_STORAGE = 0x00f7, // storage close + SMSG_PLAYER_STORAGE_CLOSE = 0x00f8, // storage closed notify + CMSG_PARTY_CREATE = 0x00f9, // party create + SMSG_PARTY_CREATE = 0x00fa, // party create result + SMSG_PARTY_INFO = 0x00fb, // party info notify + CMSG_PARTY_INVITE = 0x00fc, // party invite + SMSG_PARTY_INVITE_RESPONSE = 0x00fd, // party invite result + SMSG_PARTY_INVITED = 0x00fe, // (reverse) party invitation + CMSG_PARTY_INVITED = 0x00ff, // (reverse) party invitation result + CMSG_PARTY_LEAVE = 0x0100, // party leave + SMSG_PARTY_SETTINGS = 0x0101, // party option notify + CMSG_PARTY_SETTINGS = 0x0102, // party option + CMSG_PARTY_KICK = 0x0103, // party kick + SMSG_PARTY_LEAVE = 0x0105, // party left notify + SMSG_PARTY_UPDATE_HP = 0x0106, // party hp notify + SMSG_PARTY_UPDATE_COORDS = 0x0107, // party xy notify + CMSG_PARTY_MESSAGE = 0x0108, // party message + SMSG_PARTY_MESSAGE = 0x0109, // party message notify + SMSG_PLAYER_SKILL_UP = 0x010e, // skill raise result + SMSG_PLAYER_SKILLS = 0x010f, // skill info notify + SMSG_SKILL_FAILED = 0x0110, // skill failed + CMSG_SKILL_LEVELUP_REQUEST = 0x0112, // skill raise + CMSG_PLAYER_STOP_ATTACK = 0x0118, // attack stop + SMSG_PLAYER_STATUS_CHANGE = 0x0119, // player option notify + SMSG_PLAYER_MOVE_TO_ATTACK = 0x0139, // player move attack range notify + SMSG_PLAYER_ATTACK_RANGE = 0x013a, // player attack range notify + SMSG_PLAYER_ARROW_MESSAGE = 0x013b, // player arrow fail notify + SMSG_PLAYER_ARROW_EQUIP = 0x013c, // player arrow equip notify + SMSG_PLAYER_STAT_UPDATE_3 = 0x0141, // player stat update 3 + SMSG_NPC_INT_INPUT = 0x0142, // (reverse) script input integer + CMSG_NPC_INT_RESPONSE = 0x0143, // (reverse) script input integer result + CMSG_NPC_CLOSE = 0x0146, // (reverse) script close response + SMSG_BEING_RESURRECT = 0x0148, // being resurrected notify + CMSG_CLIENT_QUIT = 0x018a, // client quit + SMSG_MAP_QUIT_RESPONSE = 0x018b, // client quit result + SMSG_PLAYER_GUILD_PARTY_INFO = 0x0195, // guild party info notify + SMSG_BEING_STATUS_CHANGE = 0x0196, // being status change notify + SMSG_PVP_MAP_MODE = 0x0199, // map pvp status + SMSG_PVP_SET = 0x019a, // being pvp status + SMSG_BEING_SELFEFFECT = 0x019b, // being effect + SMSG_TRADE_ITEM_ADD_RESPONSE = 0x01b1, // trade add result + SMSG_PLAYER_INVENTORY_USE = 0x01c8, // use item result + SMSG_NPC_STR_INPUT = 0x01d4, // (reverse) script input string + CMSG_NPC_STR_RESPONSE = 0x01d5, // (reverse) script input string result + SMSG_BEING_CHANGE_LOOKS2 = 0x01d7, // being change look + SMSG_PLAYER_UPDATE_1 = 0x01d8, // player appear notify + SMSG_PLAYER_UPDATE_2 = 0x01d9, // player appear notify + SMSG_PLAYER_MOVE = 0x01da, // player move notify + SMSG_SKILL_DAMAGE = 0x01de, // deal skill damage + SMSG_PLAYER_INVENTORY = 0x01ee, // inventory list notify + SMSG_PLAYER_STORAGE_ITEMS = 0x01f0, // storage list notify + SMSG_BEING_IP_RESPONSE = 0x020c, // player ip notify + CMSG_ONLINE_LIST = 0x0210, // online list request + SMSG_ONLINE_LIST = 0x0211, // advanced online list + SMSG_NPC_COMMAND = 0x0212, // npc command + SMSG_QUEST_SET_VAR = 0x0214, // send quest + SMSG_QUEST_PLAYER_VARS = 0x0215, // send all quest + SMSG_BEING_MOVE3 = 0x0225, // being move 3 + SMSG_MAP_MASK = 0x0226, // send map mask + SMSG_MAP_MUSIC = 0x0227, // change map music + SMSG_NPC_CHANGETITLE = 0x0228, // npc change title + SMSG_SCRIPT_MESSAGE = 0x0229, // script message + SMSG_PLAYER_CLIENT_COMMAND = 0x0230, // remote client command + SMSG_MAP_SET_TILES_TYPE = 0x0231, // send area collision + SMSG_PLAYER_HP = 0x0232, // send hp update + SMSG_PLAYER_HP_FULL = 0x0233, // send full hp + + // any server messages + SMSG_CONNECTION_PROBLEM = 0x0081, // connect foo error + CMSG_SERVER_VERSION_REQUEST = 0x7530, // version + SMSG_SERVER_VERSION_RESPONSE = 0x7531, // version result + CMSG_CLIENT_DISCONNECT = 0x7532, // disconnect +}; } diff --git a/src/net/tmwa/specialhandler.cpp b/src/net/tmwa/specialhandler.cpp index 7de0aaea..6a0bef9a 100644 --- a/src/net/tmwa/specialhandler.cpp +++ b/src/net/tmwa/specialhandler.cpp @@ -28,7 +28,6 @@ #include "gui/skilldialog.h" #include "net/tmwa/messagein.h" -#include "net/tmwa/messageout.h" #include "net/tmwa/protocol.h" #include "utils/gettext.h" @@ -222,31 +221,18 @@ void SpecialHandler::handleMessage(MessageIn &msg) void SpecialHandler::use(int id) { - // TODO } void SpecialHandler::use(int id, int level, int beingId) { - MessageOut outMsg(CMSG_SKILL_USE_BEING); - outMsg.writeInt16(level); - outMsg.writeInt16(id); - outMsg.writeInt16(beingId); } void SpecialHandler::use(int id, int level, int x, int y) { - MessageOut outMsg(CMSG_SKILL_USE_POSITION); - outMsg.writeInt16(level); - outMsg.writeInt16(id); - outMsg.writeInt16(x); - outMsg.writeInt16(y); } void SpecialHandler::use(int id, const std::string &map) { - MessageOut outMsg(CMSG_SKILL_USE_MAP); - outMsg.writeInt16(id); - outMsg.writeString(map, 16); } } // namespace TmwAthena -- cgit v1.2.3-60-g2f50