summaryrefslogtreecommitdiff
path: root/src/net/tmwa
diff options
context:
space:
mode:
Diffstat (limited to 'src/net/tmwa')
-rw-r--r--src/net/tmwa/adminhandler.cpp4
-rw-r--r--src/net/tmwa/beinghandler.cpp48
-rw-r--r--src/net/tmwa/charserverhandler.cpp2
-rw-r--r--src/net/tmwa/chathandler.cpp13
-rw-r--r--src/net/tmwa/chathandler.h4
-rw-r--r--src/net/tmwa/gamehandler.cpp10
-rw-r--r--src/net/tmwa/gamehandler.h2
-rw-r--r--src/net/tmwa/loginhandler.cpp4
-rw-r--r--src/net/tmwa/network.cpp362
-rw-r--r--src/net/tmwa/network.h24
-rw-r--r--src/net/tmwa/partyhandler.cpp15
-rw-r--r--src/net/tmwa/playerhandler.cpp6
-rw-r--r--src/net/tmwa/protocol.h426
-rw-r--r--src/net/tmwa/specialhandler.cpp14
14 files changed, 456 insertions, 478 deletions
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 <iostream>
#include <cmath>
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<std::string>;
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<int>(sizeof(packet_lengths) / sizeof(uint16_t));
const unsigned int BUFFER_SIZE = 65536;
-namespace TmwAthena {
-
int networkThread(void *data)
{
auto *network = static_cast<Network*>(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 <SDL_net.h>
@@ -35,6 +34,7 @@
#include <map>
#include <string>
+#include <unordered_map>
/**
* 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<Uint16, MessageHandler *>;
- using MessageHandlerIterator = MessageHandlers::iterator;
- MessageHandlers mMessageHandlers;
+ std::unordered_map<uint16_t, const PacketInfo*> mPacketInfo;
+ std::map<uint16_t, MessageHandler *> 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