diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/net/ea/beinghandler.cpp | 8 | ||||
-rw-r--r-- | src/net/ea/charserverhandler.cpp | 28 | ||||
-rw-r--r-- | src/net/ea/chathandler.cpp | 4 | ||||
-rw-r--r-- | src/net/ea/generalhandler.cpp | 21 | ||||
-rw-r--r-- | src/net/ea/loginhandler.cpp | 8 | ||||
-rw-r--r-- | src/net/ea/maphandler.cpp | 6 | ||||
-rw-r--r-- | src/net/ea/playerhandler.cpp | 20 | ||||
-rw-r--r-- | src/net/ea/protocol.h | 47 | ||||
-rw-r--r-- | src/net/tmwserv/generalhandler.cpp | 21 | ||||
-rw-r--r-- | src/resources/itemdb.cpp | 24 | ||||
-rw-r--r-- | src/resources/itemdb.h | 8 | ||||
-rw-r--r-- | src/resources/resourcemanager.cpp | 30 | ||||
-rw-r--r-- | src/resources/resourcemanager.h | 11 | ||||
-rw-r--r-- | src/sound.cpp | 18 |
14 files changed, 205 insertions, 49 deletions
diff --git a/src/net/ea/beinghandler.cpp b/src/net/ea/beinghandler.cpp index 6ab73b4c..4b61ec61 100644 --- a/src/net/ea/beinghandler.cpp +++ b/src/net/ea/beinghandler.cpp @@ -65,8 +65,8 @@ BeingHandler::BeingHandler(bool enableSync): SMSG_PLAYER_MOVE, SMSG_PLAYER_STOP, SMSG_PLAYER_MOVE_TO_ATTACK, - 0x0119, - 0x0196, + SMSG_PLAYER_STATUS_CHANGE, + SMSG_BEING_STATUS_CHANGE, 0 }; handledMessages = _messages; @@ -574,7 +574,7 @@ void BeingHandler::handleMessage(MessageIn &msg) */ break; - case 0x0119: + case SMSG_PLAYER_STATUS_CHANGE: // Change in players' flags id = msg.readInt32(); dstBeing = beingManager->findBeing(id); @@ -590,7 +590,7 @@ void BeingHandler::handleMessage(MessageIn &msg) } break; - case 0x0196: + case SMSG_BEING_STATUS_CHANGE: // Status change status = msg.readInt16(); id = msg.readInt32(); diff --git a/src/net/ea/charserverhandler.cpp b/src/net/ea/charserverhandler.cpp index 3402b5fc..fab1ffe3 100644 --- a/src/net/ea/charserverhandler.cpp +++ b/src/net/ea/charserverhandler.cpp @@ -46,13 +46,13 @@ CharServerHandler::CharServerHandler(): mCharCreateDialog(0) { static const Uint16 _messages[] = { - 0x006b, - 0x006c, - 0x006d, - 0x006e, - 0x006f, - 0x0070, - 0x0071, + SMSG_CHAR_LOGIN, + SMSG_CHAR_LOGIN_ERROR, + SMSG_CHAR_CREATE_SUCCEEDED, + SMSG_CHAR_CREATE_FAILED, + SMSG_CHAR_DELETE_SUCCEEDED, + SMSG_CHAR_DELETE_FAILED, + SMSG_CHAR_MAP_INFO, 0 }; handledMessages = _messages; @@ -89,7 +89,7 @@ void CharServerHandler::handleMessage(MessageIn &msg) state = STATE_CHAR_SELECT; break; - case 0x006c: + case SMSG_CHAR_LOGIN_ERROR: switch (msg.readInt8()) { case 0: errorMessage = _("Access denied"); @@ -104,7 +104,7 @@ void CharServerHandler::handleMessage(MessageIn &msg) mCharInfo->unlock(); break; - case 0x006d: + case SMSG_CHAR_CREATE_SUCCEEDED: tempPlayer = readPlayerData(msg, slot); mCharInfo->unlock(); mCharInfo->select(slot); @@ -119,7 +119,7 @@ void CharServerHandler::handleMessage(MessageIn &msg) } break; - case 0x006e: + case SMSG_CHAR_CREATE_FAILED: new OkDialog(_("Error"), _("Failed to create character. Most likely" " the name is already taken.")); @@ -127,7 +127,7 @@ void CharServerHandler::handleMessage(MessageIn &msg) mCharCreateDialog->unlock(); break; - case 0x006f: + case SMSG_CHAR_DELETE_SUCCEEDED: delete mCharInfo->getEntry(); mCharInfo->setEntry(0); mCharInfo->unlock(); @@ -135,12 +135,12 @@ void CharServerHandler::handleMessage(MessageIn &msg) new OkDialog(_("Info"), _("Player deleted")); break; - case 0x0070: + case SMSG_CHAR_DELETE_FAILED: mCharInfo->unlock(); new OkDialog(_("Error"), _("Failed to delete character.")); break; - case 0x0071: + case SMSG_CHAR_MAP_INFO: player_node = mCharInfo->getEntry(); slot = mCharInfo->getPos(); msg.skip(4); // CharID, must be the same as player_node->charID @@ -236,7 +236,7 @@ void CharServerHandler::connect(LoginData *loginData) { mLoginData = loginData; - MessageOut outMsg(0x0065); + MessageOut outMsg(CMSG_CHAR_SERVER_CONNECT); outMsg.writeInt32(loginData->account_ID); outMsg.writeInt32(loginData->session_ID1); outMsg.writeInt32(loginData->session_ID2); diff --git a/src/net/ea/chathandler.cpp b/src/net/ea/chathandler.cpp index 626f1048..2e8df374 100644 --- a/src/net/ea/chathandler.cpp +++ b/src/net/ea/chathandler.cpp @@ -54,7 +54,7 @@ ChatHandler::ChatHandler() SMSG_WHISPER, SMSG_WHISPER_RESPONSE, SMSG_GM_CHAT, - 0x10c, // MVP + SMSG_MVP, // MVP 0 }; handledMessages = _messages; @@ -164,7 +164,7 @@ void ChatHandler::handleMessage(MessageIn &msg) break; } - case 0x010c: + case SMSG_MVP: // Display MVP player msg.readInt32(); // id localChatTab->chatLog("MVP player", BY_SERVER); diff --git a/src/net/ea/generalhandler.cpp b/src/net/ea/generalhandler.cpp index 7d5a7d40..1084c138 100644 --- a/src/net/ea/generalhandler.cpp +++ b/src/net/ea/generalhandler.cpp @@ -46,12 +46,16 @@ #include "net/messagein.h" #include "net/messageout.h" +#include "resources/itemdb.h" + #include "configuration.h" #include "log.h" #include "main.h" #include "utils/gettext.h" +#include <list> + Net::GeneralHandler *generalHandler; namespace EAthena { @@ -80,6 +84,23 @@ GeneralHandler::GeneralHandler(): }; handledMessages = _messages; generalHandler = this; + + std::list<ItemDB::Stat*> stats; + ItemDB::Stat stat; + stat.tag = "str"; stat.format = N_("Strength: %d"); + stats.push_back(&stat); + stat.tag = "agi"; stat.format = N_("Agility: %d"); + stats.push_back(&stat); + stat.tag = "vit"; stat.format = N_("Vitality: %d"); + stats.push_back(&stat); + stat.tag = "int"; stat.format = N_("Intelligence: %d"); + stats.push_back(&stat); + stat.tag = "dex"; stat.format = N_("Dexterity: %d"); + stats.push_back(&stat); + stat.tag = "luck"; stat.format = N_("Luck: %d"); + stats.push_back(&stat); + + ItemDB::setStatsList(stats); } GeneralHandler::~GeneralHandler() diff --git a/src/net/ea/loginhandler.cpp b/src/net/ea/loginhandler.cpp index 9c34c4cd..d9093e16 100644 --- a/src/net/ea/loginhandler.cpp +++ b/src/net/ea/loginhandler.cpp @@ -45,8 +45,8 @@ LoginHandler::LoginHandler() { static const Uint16 _messages[] = { SMSG_UPDATE_HOST, - 0x0069, - 0x006a, + SMSG_LOGIN_DATA, + SMSG_LOGIN_ERROR, 0 }; handledMessages = _messages; @@ -69,7 +69,7 @@ void LoginHandler::handleMessage(MessageIn &msg) mUpdateHost.c_str()); break; - case 0x0069: + case SMSG_LOGIN_DATA: // Skip the length word msg.skip(2); @@ -102,7 +102,7 @@ void LoginHandler::handleMessage(MessageIn &msg) state = STATE_CHAR_SERVER; break; - case 0x006a: + case SMSG_LOGIN_ERROR: code = msg.readInt8(); logger->log("Login::error code: %i", code); diff --git a/src/net/ea/maphandler.cpp b/src/net/ea/maphandler.cpp index 6b061798..79e41914 100644 --- a/src/net/ea/maphandler.cpp +++ b/src/net/ea/maphandler.cpp @@ -43,7 +43,7 @@ namespace EAthena { MapHandler::MapHandler() { static const Uint16 _messages[] = { - SMSG_LOGIN_SUCCESS, + SMSG_MAP_LOGIN_SUCCESS, SMSG_SERVER_PING, SMSG_WHO_ANSWER, 0 @@ -58,7 +58,7 @@ void MapHandler::handleMessage(MessageIn &msg) switch (msg.getId()) { - case SMSG_LOGIN_SUCCESS: + case SMSG_MAP_LOGIN_SUCCESS: msg.readInt32(); // server tick msg.readCoordinates(player_node->mX, player_node->mY, direction); msg.skip(2); // unknown @@ -100,7 +100,7 @@ void MapHandler::mapLoaded(const std::string &mapName) void MapHandler::who() { - MessageOut outMsg(0x00c1); + MessageOut outMsg(CMSG_WHO_REQUEST); } void MapHandler::quit() diff --git a/src/net/ea/playerhandler.cpp b/src/net/ea/playerhandler.cpp index 5d2a4829..c0c0fe20 100644 --- a/src/net/ea/playerhandler.cpp +++ b/src/net/ea/playerhandler.cpp @@ -435,14 +435,14 @@ void PlayerHandler::handleMessage(MessageIn &msg) void PlayerHandler::attack(Being *being) { - MessageOut outMsg(0x0089); + MessageOut outMsg(CMSG_PLAYER_ATTACK); outMsg.writeInt32(being->getId()); outMsg.writeInt8(0); } void PlayerHandler::emote(int emoteId) { - MessageOut outMsg(0x00bf); + MessageOut outMsg(CMSG_PLAYER_EMOTE); outMsg.writeInt8(emoteId); } @@ -501,20 +501,28 @@ void PlayerHandler::setDestination(int x, int y, int direction) { char temp[4] = ""; set_coordinates(temp, x, y, direction); - MessageOut outMsg(0x0085); + MessageOut outMsg(CMSG_PLAYER_CHANGE_DEST); outMsg.writeString(temp, 3); } void PlayerHandler::changeAction(Being::Action action) { - MessageOut outMsg(0x0089); + char type; + switch (action) + { + case Being::SIT: type = 2; break; + case Being::STAND: type = 3; break; + default: return; + } + + MessageOut outMsg(CMSG_PLAYER_CHANGE_ACT); outMsg.writeInt32(0); - outMsg.writeInt8((action == Being::SIT) ? 2 : 3); + outMsg.writeInt8(type); } void PlayerHandler::respawn() { - MessageOut outMsg(0x00b2); + MessageOut outMsg(CMSG_PLAYER_RESPAWN); outMsg.writeInt8(0); } diff --git a/src/net/ea/protocol.h b/src/net/ea/protocol.h index a9028f7e..d34a635f 100644 --- a/src/net/ea/protocol.h +++ b/src/net/ea/protocol.h @@ -28,10 +28,22 @@ static const int STORAGE_OFFSET = 1; /********************************* * Packets from server to client * *********************************/ -#define SMSG_LOGIN_SUCCESS 0x0073 /**< Contains starting location */ #define SMSG_SERVER_PING 0x007f /**< Contains server tick */ #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 0x007e +#define SMSG_CHAR_DELETE_SUCCEEDED 0x006f +#define SMSG_CHAR_DELETE_FAILED 0x0070 +#define SMSG_CHAR_MAP_INFO 0x0071 + +#define SMSG_MAP_LOGIN_SUCCESS 0x0073 /**< Contains starting location */ #define SMSG_PLAYER_UPDATE_1 0x01d8 #define SMSG_PLAYER_UPDATE_2 0x01d9 #define SMSG_PLAYER_MOVE 0x01da /**< A nearby player moves */ @@ -75,6 +87,9 @@ static const int STORAGE_OFFSET = 1; #define SMSG_BEING_NAME_RESPONSE 0x0095 /**< Has to be requested */ #define SMSG_BEING_CHANGE_DIRECTION 0x009c +#define SMSG_PLAYER_STATUS_CHANGE 0x0119 +#define SMSG_BEING_STATUS_CHANGE 0x0196 + #define SMSG_NPC_MESSAGE 0x00b4 #define SMSG_NPC_NEXT 0x00b5 #define SMSG_NPC_CLOSE 0x00b6 @@ -120,35 +135,42 @@ static const int STORAGE_OFFSET = 1; #define SMSG_ADMIN_KICK_ACK 0x00cd +#define SMSG_MVP 0x010c + /********************************** * Packets from client to server * **********************************/ +#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_CLIENT_PING 0x007e /**< Send to server with tick */ -#define CMSG_CLIENT_QUIT 0x018A -#define CMSG_TRADE_RESPONSE 0x00e6 -#define CMSG_ITEM_PICKUP 0x009f #define CMSG_MAP_LOADED 0x007d +#define CMSG_CLIENT_QUIT 0x018A + #define CMSG_CHAT_MESSAGE 0x008c #define CMSG_CHAT_WHISPER 0x0096 #define CMSG_CHAT_ANNOUNCE 0x0099 #define CMSG_CHAT_WHO 0x00c1 + #define CMSG_SKILL_LEVELUP_REQUEST 0x0112 #define CMSG_STAT_UPDATE_REQUEST 0x00bb -#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_TRADE_REQUEST 0x00e4 + #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 +#define CMSG_PLAYER_RESPAWN 0x00b2 +#define CMSG_PLAYER_EMOTE 0x00bf +#define CMSG_PLAYER_ATTACK 0x0089 +#define CMSG_WHO_REQUEST 0x00c1 #define CMSG_NPC_TALK 0x0090 #define CMSG_NPC_NEXT_REQUEST 0x00b9 @@ -160,6 +182,13 @@ static const int STORAGE_OFFSET = 1; #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 diff --git a/src/net/tmwserv/generalhandler.cpp b/src/net/tmwserv/generalhandler.cpp index 98c764c5..cd9b2f15 100644 --- a/src/net/tmwserv/generalhandler.cpp +++ b/src/net/tmwserv/generalhandler.cpp @@ -40,6 +40,10 @@ #include "net/tmwserv/playerhandler.h" #include "net/tmwserv/tradehandler.h" +#include "utils/gettext.h" + +#include <list> + Net::GeneralHandler *generalHandler; Net::Connection *gameServerConnection = 0; @@ -70,6 +74,23 @@ GeneralHandler::GeneralHandler(): chatServerConnection = Net::getConnection(); generalHandler = this; + + std::list<ItemDB::Stat*> stats; + ItemDB::Stat stat; + stat.tag = "str"; stat.format = N_("Strength: %d"); + stats.push_back(&stat); + stat.tag = "agi"; stat.format = N_("Agility: %d"); + stats.push_back(&stat); + stat.tag = "dex"; stat.format = N_("Dexterity: %d"); + stats.push_back(&stat); + stat.tag = "vit"; stat.format = N_("Vitality: %d"); + stats.push_back(&stat); + stat.tag = "int"; stat.format = N_("Intelligence: %d"); + stats.push_back(&stat); + stat.tag = "will"; stat.format = N_("Willpower: %d"); + stats.push_back(&stat); + + ItemDB::setStatsList(stats); } void GeneralHandler::load() diff --git a/src/resources/itemdb.cpp b/src/resources/itemdb.cpp index 50eba33d..807fa0a4 100644 --- a/src/resources/itemdb.cpp +++ b/src/resources/itemdb.cpp @@ -56,6 +56,13 @@ static char const *const fields[][2] = { "mp", N_("MP %+d") } }; +static std::list<ItemDB::Stat*> extraStats; + +void ItemDB::setStatsList(std::list<ItemDB::Stat*> stats) +{ + extraStats = stats; +} + static ItemType itemTypeFromString(const std::string &name, int id = 0) { if (name=="generic") return ITEM_UNUSABLE; @@ -149,7 +156,6 @@ void ItemDB::load() itemInfo->setWeaponType(weaponType); itemInfo->setAttackRange(attackRange); -#ifdef TMWSERV_SUPPORT std::string effect; for (int i = 0; i < int(sizeof(fields) / sizeof(fields[0])); ++i) { @@ -158,12 +164,20 @@ void ItemDB::load() if (!effect.empty()) effect += " / "; effect += strprintf(gettext(fields[i][1]), value); } -#else - std::string effect = XML::getProperty(node, "effect", ""); -#endif + for (std::list<Stat*>::iterator it = extraStats.begin(); + it != extraStats.end(); it++) + { + int value = XML::getProperty(node, (*it)->tag.c_str(), 0); + if (!value) continue; + if (!effect.empty()) effect += " / "; + effect += strprintf((*it)->format.c_str(), value); + } + std::string temp = XML::getProperty(node, "effect", ""); + if (!effect.empty() && !temp.empty()) + effect += " / "; + effect += temp; itemInfo->setEffect(effect); - for_each_xml_child_node(itemChild, node) { if (xmlStrEqual(itemChild->name, BAD_CAST "sprite")) diff --git a/src/resources/itemdb.h b/src/resources/itemdb.h index 770f32dd..2bb8fd5e 100644 --- a/src/resources/itemdb.h +++ b/src/resources/itemdb.h @@ -22,6 +22,7 @@ #ifndef ITEM_MANAGER_H #define ITEM_MANAGER_H +#include <list> #include <map> #include <string> @@ -45,6 +46,13 @@ namespace ItemDB const ItemInfo &get(int id); const ItemInfo &get(const std::string &name); + struct Stat { + std::string tag; + std::string format; + }; + + void setStatsList(std::list<Stat*> stats); + // Items database typedef std::map<int, ItemInfo*> ItemInfos; typedef std::map<std::string, ItemInfo*> NamedItemInfos; diff --git a/src/resources/resourcemanager.cpp b/src/resources/resourcemanager.cpp index 33d5e3e5..0b8d6c35 100644 --- a/src/resources/resourcemanager.cpp +++ b/src/resources/resourcemanager.cpp @@ -419,7 +419,35 @@ void *ResourceManager::loadFile(const std::string &fileName, int &fileSize) return buffer; } -std::vector<std::string> ResourceManager::loadTextFile(const std::string &fileName) +bool ResourceManager::copyFile(const std::string &src, const std::string &dst) +{ + PHYSFS_file *srcFile = PHYSFS_openRead(src.c_str()); + if (!srcFile) + { + logger->log("Read error: %s", PHYSFS_getLastError()); + return false; + } + PHYSFS_file *dstFile = PHYSFS_openWrite(dst.c_str()); + if (!dstFile) + { + logger->log("Write error: %s", PHYSFS_getLastError()); + PHYSFS_close(srcFile); + return false; + } + + int fileSize = PHYSFS_fileLength(srcFile); + void *buf = malloc(fileSize); + PHYSFS_read(srcFile, buf, 1, fileSize); + PHYSFS_write(dstFile, buf, 1, fileSize); + + PHYSFS_close(srcFile); + PHYSFS_close(dstFile); + free(buf); + return true; +} + +std::vector<std::string> ResourceManager::loadTextFile( + const std::string &fileName) { int contentsLength; char *fileContents = (char*)loadFile(fileName, contentsLength); diff --git a/src/resources/resourcemanager.h b/src/resources/resourcemanager.h index ec60fa9a..b2ad3069 100644 --- a/src/resources/resourcemanager.h +++ b/src/resources/resourcemanager.h @@ -125,6 +125,17 @@ class ResourceManager Resource *load(const std::string &path, loader fun); /** + * Copies a file from one place to another (useful for extracting + * raw files from a zip archive, for example) + * + * @param src Source file name + * @param dst Destination file name + * @return true on success, false on failure. An error message should be + * in the log file. + */ + bool copyFile(const std::string &src, const std::string &dst); + + /** * Convenience wrapper around ResourceManager::get for loading * images. */ diff --git a/src/sound.cpp b/src/sound.cpp index a366f28d..4a9a6f39 100644 --- a/src/sound.cpp +++ b/src/sound.cpp @@ -141,7 +141,23 @@ static Mix_Music *loadMusic(const std::string &filename) ResourceManager *resman = ResourceManager::getInstance(); std::string path = resman->getPath("music/" + filename); - logger->log("Loading music \"%s\"", path.c_str()); + if (path.find(".zip/") != std::string::npos || + path.find(".zip\\") != std::string::npos) + { + // Music file is a virtual file inside a zip archive - we have to copy + // it to a temporary physical file so that SDL_mixer can stream it. + logger->log("Loading music \"%s\" from temporary file tempMusic.ogg", + path.c_str()); + bool success = resman->copyFile("music/" + filename, "tempMusic.ogg"); + if (success) + { + path = resman->getPath("tempMusic.ogg"); + } else { + return NULL; + } + } else { + logger->log("Loading music \"%s\"", path.c_str()); + } Mix_Music *music = Mix_LoadMUS(path.c_str()); |