diff options
Diffstat (limited to 'src')
117 files changed, 963 insertions, 783 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e0a42478..45b58ac0 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -350,10 +350,6 @@ SET(SRCS net/logindata.h net/loginhandler.h net/messagehandler.h - net/messagein.cpp - net/messagein.h - net/messageout.cpp - net/messageout.h net/npchandler.h net/net.cpp net/net.h diff --git a/src/actorspritemanager.cpp b/src/actorspritemanager.cpp index 2ee80d03..31b6d8f0 100644 --- a/src/actorspritemanager.cpp +++ b/src/actorspritemanager.cpp @@ -180,7 +180,7 @@ Being *ActorSpriteManager::findBeingByPixel(int x, int y) const const int halfTileHeight = map->getTileHeight() / 2; Being *closest = 0; - int closestDist; + int closestDist = 0; for_actors { diff --git a/src/client.cpp b/src/client.cpp index 5a9cc726..28affce6 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -380,6 +380,7 @@ Client::Client(const Options &options): sound.init(); sound.setSfxVolume(config.getIntValue("sfxVolume")); + sound.setNotificationsVolume(config.getIntValue("notificationsVolume")); sound.setMusicVolume(config.getIntValue("musicVolume")); } catch (const char *err) @@ -541,7 +542,7 @@ int Client::exec() lastTickTime = tick_time; // Update the screen when application is active, delay otherwise. - if (SDL_GetAppState() & SDL_APPACTIVE) + if (isActive()) { frame_count++; gui->draw(); diff --git a/src/client.h b/src/client.h index 2ee6764c..4ad5562d 100644 --- a/src/client.h +++ b/src/client.h @@ -214,6 +214,15 @@ public: */ void videoResized(int width, int height); + static bool isActive() + { return SDL_GetAppState() & SDL_APPACTIVE; } + + static bool hasInputFocus() + { return SDL_GetAppState() & SDL_APPINPUTFOCUS; } + + static bool hasMouseFocus() + { return SDL_GetAppState() & SDL_APPMOUSEFOCUS; } + private: void initRootDir(); void initHomeDir(); diff --git a/src/defaults.cpp b/src/defaults.cpp index 104f3971..0dc8e3ed 100644 --- a/src/defaults.cpp +++ b/src/defaults.cpp @@ -85,6 +85,7 @@ DefaultsData* getConfigDefaults() AddDEF(configData, "hwaccel", false); AddDEF(configData, "sound", false); AddDEF(configData, "sfxVolume", 100); + AddDEF(configData, "notificationsVolume", 100); AddDEF(configData, "musicVolume", 60); AddDEF(configData, "remember", false); AddDEF(configData, "username", ""); diff --git a/src/gui/charcreatedialog.cpp b/src/gui/charcreatedialog.cpp index 84bce434..8fee148b 100644 --- a/src/gui/charcreatedialog.cpp +++ b/src/gui/charcreatedialog.cpp @@ -39,7 +39,6 @@ #include "gui/widgets/textfield.h" #include "net/charhandler.h" -#include "net/messageout.h" #include "net/net.h" #include "resources/hairdb.h" diff --git a/src/gui/charselectdialog.cpp b/src/gui/charselectdialog.cpp index a806fa96..1850eb9d 100644 --- a/src/gui/charselectdialog.cpp +++ b/src/gui/charselectdialog.cpp @@ -46,7 +46,6 @@ #include "net/charhandler.h" #include "net/logindata.h" #include "net/loginhandler.h" -#include "net/messageout.h" #include "net/net.h" #include "resources/hairdb.h" diff --git a/src/gui/customserverdialog.cpp b/src/gui/customserverdialog.cpp index 9d56a3ce..e0d25928 100644 --- a/src/gui/customserverdialog.cpp +++ b/src/gui/customserverdialog.cpp @@ -161,12 +161,10 @@ void CustomServerDialog::action(const gcn::ActionEvent &event) if (event.getId() == "addServer") { // Check the given information - if (mServerAddressField->getText().empty() - || mPortField->getText().empty()) + if (mServerAddressField->getText().empty()) { OkDialog *dlg = new OkDialog(_("Error"), - _("Please at least type both the address and the port " - "of the server.")); + _("Please type in at least the address of the server.")); dlg->addActionListener(this); } else @@ -178,7 +176,6 @@ void CustomServerDialog::action(const gcn::ActionEvent &event) serverInfo.name = mNameField->getText(); serverInfo.description = mDescriptionField->getText(); serverInfo.hostname = mServerAddressField->getText(); - serverInfo.port = (short) atoi(mPortField->getText().c_str()); #ifdef MANASERV_SUPPORT switch (mTypeField->getSelected()) { @@ -194,6 +191,10 @@ void CustomServerDialog::action(const gcn::ActionEvent &event) #else serverInfo.type = ServerInfo::TMWATHENA; #endif + if (mPortField->getText().empty()) + serverInfo.port = ServerInfo::defaultPortForServerType(serverInfo.type); + else + serverInfo.port = (short) atoi(mPortField->getText().c_str()); // Tell the server has to be saved serverInfo.save = true; diff --git a/src/gui/equipmentwindow.cpp b/src/gui/equipmentwindow.cpp index 4aa76c2f..85a4c766 100644 --- a/src/gui/equipmentwindow.cpp +++ b/src/gui/equipmentwindow.cpp @@ -197,7 +197,7 @@ Item *EquipmentWindow::getItem(int x, int y) const return 0; } -const std::string EquipmentWindow::getSlotName(int x, int y) const +std::string EquipmentWindow::getSlotName(int x, int y) const { for (int i = 0; i < mBoxesNumber; ++i) { diff --git a/src/gui/equipmentwindow.h b/src/gui/equipmentwindow.h index 0f1d19fa..29814dc5 100644 --- a/src/gui/equipmentwindow.h +++ b/src/gui/equipmentwindow.h @@ -93,7 +93,7 @@ class EquipmentWindow : public Window, public gcn::ActionListener void mouseMoved(gcn::MouseEvent &event); Item *getItem(int x, int y) const; - const std::string getSlotName(int x, int y) const; + std::string getSlotName(int x, int y) const; void setSelected(int index); diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index 2f24d009..78fc42fb 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -29,6 +29,7 @@ #include "gui/widgets/window.h" #include "gui/widgets/windowcontainer.h" +#include "client.h" #include "configuration.h" #include "eventlistener.h" #include "graphics.h" @@ -204,7 +205,7 @@ void Gui::draw() int mouseX, mouseY; Uint8 button = SDL_GetMouseState(&mouseX, &mouseY); - if ((SDL_GetAppState() & SDL_APPMOUSEFOCUS || button & SDL_BUTTON(1)) + if ((Client::hasMouseFocus() || button & SDL_BUTTON(1)) && mCustomCursor && mMouseCursorAlpha > 0.0f) { diff --git a/src/gui/serverdialog.cpp b/src/gui/serverdialog.cpp index 49de7f38..9802224b 100644 --- a/src/gui/serverdialog.cpp +++ b/src/gui/serverdialog.cpp @@ -69,18 +69,6 @@ static std::string serverTypeToString(ServerInfo::Type type) } } -static unsigned short defaultPortForServerType(ServerInfo::Type type) -{ - switch (type) - { - default: - case ServerInfo::TMWATHENA: - return 6901; - case ServerInfo::MANASERV: - return 9601; - } -} - ServersListModel::ServersListModel(ServerInfos *servers, ServerDialog *parent): mServers(servers), mVersionStrings(servers->size(), VersionString(0, "")), @@ -510,7 +498,7 @@ void ServerDialog::loadServers() if (server.port == 0) { // If no port is given, use the default for the given type - server.port = defaultPortForServerType(server.type); + server.port = ServerInfo::defaultPortForServerType(server.type); } } else if (xmlStrEqual(subNode->name, BAD_CAST "description")) @@ -563,7 +551,7 @@ void ServerDialog::loadCustomServers() server.hostname = config.getValue(hostNameKey, ""); server.type = ServerInfo::parseType(config.getValue(typeKey, "")); - const int defaultPort = defaultPortForServerType(server.type); + const int defaultPort = ServerInfo::defaultPortForServerType(server.type); server.port = (unsigned short) config.getValue(portKey, defaultPort); server.description = config.getValue(descriptionKey, ""); diff --git a/src/gui/setup_audio.cpp b/src/gui/setup_audio.cpp index c43210d0..69ee3dc3 100644 --- a/src/gui/setup_audio.cpp +++ b/src/gui/setup_audio.cpp @@ -37,31 +37,38 @@ Setup_Audio::Setup_Audio(): mMusicVolume(config.getIntValue("musicVolume")), mSfxVolume(config.getIntValue("sfxVolume")), + mNotificationsVolume(config.getIntValue("notificationsVolume")), mSoundEnabled(config.getBoolValue("sound")), mDownloadEnabled(config.getBoolValue("download-music")), mSoundCheckBox(new CheckBox(_("Sound"), mSoundEnabled)), mDownloadMusicCheckBox(new CheckBox(_("Download music"), mDownloadEnabled)), mSfxSlider(new Slider(0, sound.getMaxVolume())), + mNotificationsSlider(new Slider(0, sound.getMaxVolume())), mMusicSlider(new Slider(0, sound.getMaxVolume())) { setName(_("Audio")); setDimension(gcn::Rectangle(0, 0, 250, 200)); gcn::Label *sfxLabel = new Label(_("Sfx volume")); + gcn::Label *notificationsLabel = new Label(_("Notifications volume")); gcn::Label *musicLabel = new Label(_("Music volume")); mSfxSlider->setActionEventId("sfx"); + mNotificationsSlider->setActionEventId("notifications"); mMusicSlider->setActionEventId("music"); mSfxSlider->addActionListener(this); + mNotificationsSlider->addActionListener(this); mMusicSlider->addActionListener(this); mSoundCheckBox->setPosition(10, 10); mSfxSlider->setValue(mSfxVolume); + mNotificationsSlider->setValue(mNotificationsVolume); mMusicSlider->setValue(mMusicVolume); mSfxSlider->setWidth(90); + mNotificationsSlider->setWidth(90); mMusicSlider->setWidth(90); // Do the layout @@ -71,9 +78,11 @@ Setup_Audio::Setup_Audio(): place(0, 0, mSoundCheckBox); place(0, 1, mSfxSlider); place(1, 1, sfxLabel); - place(0, 2, mMusicSlider); - place(1, 2, musicLabel); - place(0, 3, mDownloadMusicCheckBox); + place(0, 2, mNotificationsSlider); + place(1, 2, notificationsLabel); + place(0, 3, mMusicSlider); + place(1, 3, musicLabel); + place(0, 4, mDownloadMusicCheckBox); setDimension(gcn::Rectangle(0, 0, 370, 280)); } @@ -83,6 +92,7 @@ void Setup_Audio::apply() mSoundEnabled = mSoundCheckBox->isSelected(); mDownloadEnabled = mDownloadMusicCheckBox->isSelected(); mSfxVolume = config.getIntValue("sfxVolume"); + mNotificationsVolume = config.getIntValue("sfxVolume"); mMusicVolume = config.getIntValue("musicVolume"); config.setValue("sound", mSoundEnabled); @@ -134,12 +144,20 @@ void Setup_Audio::action(const gcn::ActionEvent &event) { if (event.getId() == "sfx") { - config.setValue("sfxVolume", (int) mSfxSlider->getValue()); - sound.setSfxVolume((int) mSfxSlider->getValue()); + int volume = (int) mSfxSlider->getValue(); + config.setValue("sfxVolume", volume); + sound.setSfxVolume(volume); + } + else if (event.getId() == "notifications") + { + int volume = (int) mNotificationsSlider->getValue(); + config.setValue("notificationsVolume", volume); + sound.setNotificationsVolume(volume); } else if (event.getId() == "music") { - config.setValue("musicVolume", (int) mMusicSlider->getValue()); - sound.setMusicVolume((int) mMusicSlider->getValue()); + int volume = (int) mMusicSlider->getValue(); + config.setValue("musicVolume", volume); + sound.setMusicVolume(volume); } } diff --git a/src/gui/setup_audio.h b/src/gui/setup_audio.h index 5477eaad..ac81bdb7 100644 --- a/src/gui/setup_audio.h +++ b/src/gui/setup_audio.h @@ -39,11 +39,17 @@ class Setup_Audio : public SetupTab, public gcn::ActionListener void action(const gcn::ActionEvent &event); private: - int mMusicVolume, mSfxVolume; - bool mSoundEnabled, mDownloadEnabled; - - gcn::CheckBox *mSoundCheckBox, *mDownloadMusicCheckBox; - gcn::Slider *mSfxSlider, *mMusicSlider; + int mMusicVolume; + int mSfxVolume; + int mNotificationsVolume; + bool mSoundEnabled; + bool mDownloadEnabled; + + gcn::CheckBox *mSoundCheckBox; + gcn::CheckBox *mDownloadMusicCheckBox; + gcn::Slider *mSfxSlider; + gcn::Slider *mNotificationsSlider; + gcn::Slider *mMusicSlider; }; -#endif +#endif // GUI_SETUP_AUDIO_H diff --git a/src/gui/socialwindow.cpp b/src/gui/socialwindow.cpp index 421d639d..4203a137 100644 --- a/src/gui/socialwindow.cpp +++ b/src/gui/socialwindow.cpp @@ -123,9 +123,10 @@ public: if (!name.empty()) { + Net::getGuildHandler()->invite(mGuild->getId(), name); SERVER_NOTICE(strprintf(_("Invited user %s to guild %s."), - name.c_str(), - mGuild->getName().c_str())) + name.c_str(), + mGuild->getName().c_str())) } mInviteDialog = NULL; } diff --git a/src/gui/specialswindow.cpp b/src/gui/specialswindow.cpp index 8097eb05..7db5952a 100644 --- a/src/gui/specialswindow.cpp +++ b/src/gui/specialswindow.cpp @@ -48,6 +48,8 @@ #include "utils/stringutils.h" #include "utils/xml.h" +#include "localplayer.h" + #include <string> #define SPECIALS_WIDTH 200 @@ -106,12 +108,20 @@ void SpecialsWindow::action(const gcn::ActionEvent &event) if (disp) { - /*Being *target = local_player->getTarget(); - - if (target) - Net::getSpecialHandler()->use(disp->mInfo->id, 1, target->getId()); - else*/ - Net::getSpecialHandler()->use(disp->mInfo->id); + if (disp->mInfo->targetMode == SpecialInfo::TARGET_BEING) + { + Being *target = local_player->getTarget(); + + if (target) + Net::getSpecialHandler()->use(disp->mInfo->id, 1, target->getId()); + else + Net::getSpecialHandler()->use(disp->mInfo->id); + } + else + { + // TODO: Allow the player to aim at a position on the map and + // Use special on the map position. + } } } else if (event.getId() == "close") @@ -202,22 +212,11 @@ SpecialEntry::SpecialEntry(SpecialInfo *info) : mNameLabel->setPosition(35, 0); add(mNameLabel); - if (info->hasLevel) - { - mLevelLabel = new Label(toString(info->level)); - mLevelLabel->setPosition(getWidth() - mLevelLabel->getWidth(), 0); - add(mLevelLabel); - } - - - if (info->isActive) - { - mUse = new Button("Use", "use", specialsWindow); - mUse->setPosition(getWidth() - mUse->getWidth(), 13); - add(mUse); - } + mUse = new Button("Use", "use", specialsWindow); + mUse->setPosition(getWidth() - mUse->getWidth(), 13); + add(mUse); - if (info->hasRechargeBar) + if (info->rechargeable) { float progress = (float)info->rechargeCurrent / (float)info->rechargeNeeded; mRechargeBar = new ProgressBar(progress, 100, 10, Theme::PROG_MP); diff --git a/src/gui/truetypefont.cpp b/src/gui/truetypefont.cpp index 5f85ea68..620ba191 100644 --- a/src/gui/truetypefont.cpp +++ b/src/gui/truetypefont.cpp @@ -57,7 +57,7 @@ class TextChunk sdlCol.r = color.r; sdlCol.g = color.g; - const char* str = getSafeUtf8String(text); + const char *str = getSafeUtf8String(text); SDL_Surface *surface = TTF_RenderUTF8_Blended( font, str, sdlCol); delete[] str; @@ -179,7 +179,7 @@ int TrueTypeFont::getWidth(const std::string &text) const } int w, h; - const char* str = getSafeUtf8String(text); + const char *str = getSafeUtf8String(text); TTF_SizeUTF8(mFont, str, &w, &h); delete[] str; return w; diff --git a/src/gui/widgets/chattab.cpp b/src/gui/widgets/chattab.cpp index 8642be69..1979ecbd 100644 --- a/src/gui/widgets/chattab.cpp +++ b/src/gui/widgets/chattab.cpp @@ -23,9 +23,11 @@ #include "actorspritemanager.h" #include "chatlogger.h" +#include "client.h" #include "commandhandler.h" #include "configuration.h" #include "localplayer.h" +#include "sound.h" #include "gui/gui.h" #include "gui/recorder.h" @@ -237,10 +239,20 @@ void ChatTab::chatLog(std::string line, Own own, bool ignoreRecord) } mScrollArea->logic(); + chatWindow->mRecorder->record(line.substr(3)); - if (this != getTabbedArea()->getSelectedTab() && - own != BY_PLAYER) - setFlash(true); + + if (own != BY_PLAYER) + { + bool currentTab = getTabbedArea()->getSelectedTab() == this; + + if (!currentTab) + setFlash(true); + + if (!(currentTab && Client::hasInputFocus()) && own != BY_SERVER) + if (checkNotify(own)) + sound.playNotification("system/newmessage.ogg"); + } } void ChatTab::chatLog(const std::string &nick, const std::string &msg) @@ -318,6 +330,11 @@ void ChatTab::handleCommand(const std::string &msg) commandHandler->handleCommand(msg, this); } +bool ChatTab::checkNotify(Own own) const +{ + return own == ACT_WHISPER; +} + void ChatTab::getAutoCompleteList(std::vector<std::string> &names) const { actorSpriteManager->getPlayerNPCNameLister()->getAutoCompleteList(names); diff --git a/src/gui/widgets/chattab.h b/src/gui/widgets/chattab.h index 3796c37b..200ad55a 100644 --- a/src/gui/widgets/chattab.h +++ b/src/gui/widgets/chattab.h @@ -115,6 +115,15 @@ class ChatTab : public Tab, public AutoCompleteLister, public EventListener virtual void handleCommand(const std::string &msg); /** + * Returns whether a notify sound may be played for the given type of + * message. By default, only returns true for inline whispers. + * + * Is never called for server-messages or when the window has focus + * and this is the current tab. + */ + virtual bool checkNotify(Own own) const; + + /** * Adapts the text format to the current gui opacity, * for better readability. */ diff --git a/src/gui/widgets/whispertab.h b/src/gui/widgets/whispertab.h index e88d084b..a0dcfc14 100644 --- a/src/gui/widgets/whispertab.h +++ b/src/gui/widgets/whispertab.h @@ -57,6 +57,9 @@ class WhisperTab : public ChatTab void handleCommand(const std::string &msg); + bool checkNotify(Own) const + { return true; } + private: std::string mNick; }; diff --git a/src/map.cpp b/src/map.cpp index 8c748bbc..fa3d9a4c 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -644,12 +644,12 @@ void Map::removeActor(Actors::iterator iterator) mActors.erase(iterator); } -const std::string Map::getMusicFile() const +std::string Map::getMusicFile() const { return getProperty("music"); } -const std::string Map::getName() const +std::string Map::getName() const { if (hasProperty("name")) return getProperty("name"); @@ -657,7 +657,7 @@ const std::string Map::getName() const return getProperty("mapname"); } -const std::string Map::getFilename() const +std::string Map::getFilename() const { std::string fileName = getProperty("_filename"); int lastSlash = fileName.rfind("/") + 1; @@ -275,13 +275,13 @@ class Map : public Properties */ Vector getTileCenter(int x, int y); - const std::string getMusicFile() const; - const std::string getName() const; + std::string getMusicFile() const; + std::string getName() const; /** * Gives the map id based on filepath (ex: 009-1) */ - const std::string getFilename() const; + std::string getFilename() const; /** * Check the current position against surrounding blocking tiles, and diff --git a/src/net/manaserv/adminhandler.cpp b/src/net/manaserv/adminhandler.cpp index ab49037d..8928a33d 100644 --- a/src/net/manaserv/adminhandler.cpp +++ b/src/net/manaserv/adminhandler.cpp @@ -41,7 +41,7 @@ AdminHandler::AdminHandler() adminHandler = this; } -void AdminHandler::handleMessage(Net::MessageIn &msg) +void AdminHandler::handleMessage(MessageIn &msg) { } diff --git a/src/net/manaserv/adminhandler.h b/src/net/manaserv/adminhandler.h index 9c68c620..83fbb854 100644 --- a/src/net/manaserv/adminhandler.h +++ b/src/net/manaserv/adminhandler.h @@ -33,7 +33,7 @@ class AdminHandler : public Net::AdminHandler, public MessageHandler public: AdminHandler(); - void handleMessage(Net::MessageIn &msg); + void handleMessage(MessageIn &msg); void announce(const std::string &text); diff --git a/src/net/manaserv/beinghandler.cpp b/src/net/manaserv/beinghandler.cpp index b319fa37..b744e53c 100644 --- a/src/net/manaserv/beinghandler.cpp +++ b/src/net/manaserv/beinghandler.cpp @@ -32,9 +32,9 @@ #include "gui/okdialog.h" #include "net/net.h" -#include "net/messagein.h" #include "net/manaserv/inventoryhandler.h" +#include "net/manaserv/messagein.h" #include "net/manaserv/playerhandler.h" #include "net/manaserv/manaserv_protocol.h" @@ -62,7 +62,7 @@ BeingHandler::BeingHandler() handledMessages = _messages; } -void BeingHandler::handleMessage(Net::MessageIn &msg) +void BeingHandler::handleMessage(MessageIn &msg) { switch (msg.getId()) { @@ -93,7 +93,7 @@ void BeingHandler::handleMessage(Net::MessageIn &msg) } } -static void handleLooks(Being *being, Net::MessageIn &msg) +static void handleLooks(Being *being, MessageIn &msg) { int lookChanges = msg.readInt8(); @@ -109,7 +109,7 @@ static void handleLooks(Being *being, Net::MessageIn &msg) } } -void BeingHandler::handleBeingEnterMessage(Net::MessageIn &msg) +void BeingHandler::handleBeingEnterMessage(MessageIn &msg) { int type = msg.readInt8(); int id = msg.readInt16(); @@ -165,7 +165,7 @@ void BeingHandler::handleBeingEnterMessage(Net::MessageIn &msg) being->setAction(action); } -void BeingHandler::handleBeingLeaveMessage(Net::MessageIn &msg) +void BeingHandler::handleBeingLeaveMessage(MessageIn &msg) { Being *being = actorSpriteManager->findBeing(msg.readInt16()); if (!being) @@ -174,7 +174,7 @@ void BeingHandler::handleBeingLeaveMessage(Net::MessageIn &msg) actorSpriteManager->destroy(being); } -void BeingHandler::handleBeingsMoveMessage(Net::MessageIn &msg) +void BeingHandler::handleBeingsMoveMessage(MessageIn &msg) { while (msg.getUnreadLength()) { @@ -233,7 +233,7 @@ void BeingHandler::handleBeingsMoveMessage(Net::MessageIn &msg) } } -void BeingHandler::handleBeingAttackMessage(Net::MessageIn &msg) +void BeingHandler::handleBeingAttackMessage(MessageIn &msg) { Being *being = actorSpriteManager->findBeing(msg.readInt16()); const BeingDirection direction = (BeingDirection) msg.readInt8(); @@ -247,7 +247,7 @@ void BeingHandler::handleBeingAttackMessage(Net::MessageIn &msg) being->setAction(Being::ATTACK, attackId); } -void BeingHandler::handleBeingsDamageMessage(Net::MessageIn &msg) +void BeingHandler::handleBeingsDamageMessage(MessageIn &msg) { while (msg.getUnreadLength()) { @@ -260,7 +260,7 @@ void BeingHandler::handleBeingsDamageMessage(Net::MessageIn &msg) } } -void BeingHandler::handleBeingActionChangeMessage(Net::MessageIn &msg) +void BeingHandler::handleBeingActionChangeMessage(MessageIn &msg) { Being *being = actorSpriteManager->findBeing(msg.readInt16()); Being::Action action = (Being::Action) msg.readInt8(); @@ -299,7 +299,7 @@ void BeingHandler::handleBeingActionChangeMessage(Net::MessageIn &msg) } } -void BeingHandler::handleBeingLooksChangeMessage(Net::MessageIn &msg) +void BeingHandler::handleBeingLooksChangeMessage(MessageIn &msg) { Being *being = actorSpriteManager->findBeing(msg.readInt16()); if (!being || being->getType() != ActorSprite::PLAYER) @@ -314,7 +314,7 @@ void BeingHandler::handleBeingLooksChangeMessage(Net::MessageIn &msg) } } -void BeingHandler::handleBeingDirChangeMessage(Net::MessageIn &msg) +void BeingHandler::handleBeingDirChangeMessage(MessageIn &msg) { Being *being = actorSpriteManager->findBeing(msg.readInt16()); if (!being) diff --git a/src/net/manaserv/beinghandler.h b/src/net/manaserv/beinghandler.h index f33afbc1..94cf20c4 100644 --- a/src/net/manaserv/beinghandler.h +++ b/src/net/manaserv/beinghandler.h @@ -43,17 +43,17 @@ class BeingHandler : public MessageHandler public: BeingHandler(); - void handleMessage(Net::MessageIn &msg); + void handleMessage(MessageIn &msg); private: - void handleBeingAttackMessage(Net::MessageIn &msg); - void handleBeingEnterMessage(Net::MessageIn &msg); - void handleBeingLeaveMessage(Net::MessageIn &msg); - void handleBeingsMoveMessage(Net::MessageIn &msg); - void handleBeingsDamageMessage(Net::MessageIn &msg); - void handleBeingActionChangeMessage(Net::MessageIn &msg); - void handleBeingLooksChangeMessage(Net::MessageIn &msg); - void handleBeingDirChangeMessage(Net::MessageIn &msg); + void handleBeingAttackMessage(MessageIn &msg); + void handleBeingEnterMessage(MessageIn &msg); + void handleBeingLeaveMessage(MessageIn &msg); + void handleBeingsMoveMessage(MessageIn &msg); + void handleBeingsDamageMessage(MessageIn &msg); + void handleBeingActionChangeMessage(MessageIn &msg); + void handleBeingLooksChangeMessage(MessageIn &msg); + void handleBeingDirChangeMessage(MessageIn &msg); }; } // namespace ManaServ diff --git a/src/net/manaserv/buysellhandler.cpp b/src/net/manaserv/buysellhandler.cpp index f9ebb147..2e7cf26d 100644 --- a/src/net/manaserv/buysellhandler.cpp +++ b/src/net/manaserv/buysellhandler.cpp @@ -28,10 +28,8 @@ #include "gui/buydialog.h" #include "gui/selldialog.h" -#include "net/messagein.h" - #include "net/manaserv/manaserv_protocol.h" - +#include "net/manaserv/messagein.h" namespace ManaServ { @@ -45,7 +43,7 @@ BuySellHandler::BuySellHandler() handledMessages = _messages; } -void BuySellHandler::handleMessage(Net::MessageIn &msg) +void BuySellHandler::handleMessage(MessageIn &msg) { Being *being = actorSpriteManager->findBeing(msg.readInt16()); if (!being || being->getType() != ActorSprite::NPC) diff --git a/src/net/manaserv/buysellhandler.h b/src/net/manaserv/buysellhandler.h index f7c7e1f7..88432842 100644 --- a/src/net/manaserv/buysellhandler.h +++ b/src/net/manaserv/buysellhandler.h @@ -31,7 +31,7 @@ class BuySellHandler : public MessageHandler public: BuySellHandler(); - void handleMessage(Net::MessageIn &msg); + void handleMessage(MessageIn &msg); }; } // namespace ManaServ diff --git a/src/net/manaserv/charhandler.cpp b/src/net/manaserv/charhandler.cpp index c05e9320..e809bfac 100644 --- a/src/net/manaserv/charhandler.cpp +++ b/src/net/manaserv/charhandler.cpp @@ -76,7 +76,7 @@ CharHandler::~CharHandler() clear(); } -void CharHandler::handleMessage(Net::MessageIn &msg) +void CharHandler::handleMessage(MessageIn &msg) { switch (msg.getId()) { @@ -98,7 +98,7 @@ void CharHandler::handleMessage(Net::MessageIn &msg) } } -void CharHandler::handleCharacterInfo(Net::MessageIn &msg) +void CharHandler::handleCharacterInfo(MessageIn &msg) { CachedCharacterInfo info; info.slot = msg.readInt8(); @@ -126,7 +126,7 @@ void CharHandler::handleCharacterInfo(Net::MessageIn &msg) updateCharacters(); } -void CharHandler::handleCharacterCreateResponse(Net::MessageIn &msg) +void CharHandler::handleCharacterCreateResponse(MessageIn &msg) { const int errMsg = msg.readInt8(); @@ -192,7 +192,7 @@ void CharHandler::handleCharacterCreateResponse(Net::MessageIn &msg) } } -void CharHandler::handleCharacterDeleteResponse(Net::MessageIn &msg) +void CharHandler::handleCharacterDeleteResponse(MessageIn &msg) { int errMsg = msg.readInt8(); if (errMsg == ERRMSG_OK) @@ -232,7 +232,7 @@ void CharHandler::handleCharacterDeleteResponse(Net::MessageIn &msg) unlockCharSelectDialog(); } -void CharHandler::handleCharacterSelectResponse(Net::MessageIn &msg) +void CharHandler::handleCharacterSelectResponse(MessageIn &msg) { int errMsg = msg.readInt8(); diff --git a/src/net/manaserv/charhandler.h b/src/net/manaserv/charhandler.h index e3098c09..d2159204 100644 --- a/src/net/manaserv/charhandler.h +++ b/src/net/manaserv/charhandler.h @@ -44,7 +44,7 @@ class CharHandler : public MessageHandler, public Net::CharHandler ~CharHandler(); - void handleMessage(Net::MessageIn &msg); + void handleMessage(MessageIn &msg); void setCharSelectDialog(CharSelectDialog *window); @@ -108,10 +108,10 @@ class CharHandler : public MessageHandler, public Net::CharHandler CachedAttributes attribute; }; - void handleCharacterInfo(Net::MessageIn &msg); - void handleCharacterCreateResponse(Net::MessageIn &msg); - void handleCharacterDeleteResponse(Net::MessageIn &msg); - void handleCharacterSelectResponse(Net::MessageIn &msg); + void handleCharacterInfo(MessageIn &msg); + void handleCharacterCreateResponse(MessageIn &msg); + void handleCharacterDeleteResponse(MessageIn &msg); + void handleCharacterSelectResponse(MessageIn &msg); void updateCharacters(); diff --git a/src/net/manaserv/chathandler.cpp b/src/net/manaserv/chathandler.cpp index 8241baa7..d777fa35 100644 --- a/src/net/manaserv/chathandler.cpp +++ b/src/net/manaserv/chathandler.cpp @@ -74,7 +74,7 @@ ChatHandler::ChatHandler() chatHandler = this; } -void ChatHandler::handleMessage(Net::MessageIn &msg) +void ChatHandler::handleMessage(MessageIn &msg) { switch (msg.getId()) { @@ -143,7 +143,7 @@ void ChatHandler::handleMessage(Net::MessageIn &msg) } } -void ChatHandler::handleGameChatMessage(Net::MessageIn &msg) +void ChatHandler::handleGameChatMessage(MessageIn &msg) { short id = msg.readInt16(); std::string chatMsg = msg.readString(); @@ -177,7 +177,7 @@ void ChatHandler::handleGameChatMessage(Net::MessageIn &msg) event.trigger(Event::ChatChannel); } -void ChatHandler::handleEnterChannelResponse(Net::MessageIn &msg) +void ChatHandler::handleEnterChannelResponse(MessageIn &msg) { if (msg.readInt8() == ERRMSG_OK) { @@ -212,7 +212,7 @@ void ChatHandler::handleEnterChannelResponse(Net::MessageIn &msg) } } -void ChatHandler::handleListChannelsResponse(Net::MessageIn &msg) +void ChatHandler::handleListChannelsResponse(MessageIn &msg) { SERVER_NOTICE(_("Listing channels.")) while (msg.getUnreadLength()) @@ -229,7 +229,7 @@ void ChatHandler::handleListChannelsResponse(Net::MessageIn &msg) SERVER_NOTICE(_("End of channel list.")) } -void ChatHandler::handlePrivateMessage(Net::MessageIn &msg) +void ChatHandler::handlePrivateMessage(MessageIn &msg) { std::string userNick = msg.readString(); std::string chatMsg = msg.readString(); @@ -240,7 +240,7 @@ void ChatHandler::handlePrivateMessage(Net::MessageIn &msg) event.trigger(Event::ChatChannel); } -void ChatHandler::handleAnnouncement(Net::MessageIn &msg) +void ChatHandler::handleAnnouncement(MessageIn &msg) { std::string chatMsg = msg.readString(); std::string sender = msg.readString(); @@ -249,7 +249,7 @@ void ChatHandler::handleAnnouncement(Net::MessageIn &msg) event.trigger(Event::ChatChannel); } -void ChatHandler::handleChatMessage(Net::MessageIn &msg) +void ChatHandler::handleChatMessage(MessageIn &msg) { short channelId = msg.readInt16(); std::string userNick = msg.readString(); @@ -266,7 +266,7 @@ void ChatHandler::handleChatMessage(Net::MessageIn &msg) } } -void ChatHandler::handleQuitChannelResponse(Net::MessageIn &msg) +void ChatHandler::handleQuitChannelResponse(MessageIn &msg) { if (msg.readInt8() == ERRMSG_OK) { @@ -276,7 +276,7 @@ void ChatHandler::handleQuitChannelResponse(Net::MessageIn &msg) } } -void ChatHandler::handleListChannelUsersResponse(Net::MessageIn &msg) +void ChatHandler::handleListChannelUsersResponse(MessageIn &msg) { std::string channelName = msg.readString(); std::string userNick; @@ -299,7 +299,7 @@ void ChatHandler::handleListChannelUsersResponse(Net::MessageIn &msg) } } -void ChatHandler::handleChannelEvent(Net::MessageIn &msg) +void ChatHandler::handleChannelEvent(MessageIn &msg) { short channelId = msg.readInt16(); char eventId = msg.readInt8(); @@ -353,7 +353,7 @@ void ChatHandler::handleChannelEvent(Net::MessageIn &msg) } } -void ChatHandler::handleWhoResponse(Net::MessageIn &msg) +void ChatHandler::handleWhoResponse(MessageIn &msg) { std::string userNick; diff --git a/src/net/manaserv/chathandler.h b/src/net/manaserv/chathandler.h index e0288412..7ae4227b 100644 --- a/src/net/manaserv/chathandler.h +++ b/src/net/manaserv/chathandler.h @@ -37,7 +37,7 @@ class ChatHandler : public MessageHandler, public Net::ChatHandler /** * Handle the given message appropriately. */ - void handleMessage(Net::MessageIn &msg); + void handleMessage(MessageIn &msg); void connect(); @@ -75,52 +75,52 @@ class ChatHandler : public MessageHandler, public Net::ChatHandler /** * Handle chat messages sent from the game server. */ - void handleGameChatMessage(Net::MessageIn &msg); + void handleGameChatMessage(MessageIn &msg); /** * Handle channel entry responses. */ - void handleEnterChannelResponse(Net::MessageIn &msg); + void handleEnterChannelResponse(MessageIn &msg); /** * Handle list channels responses. */ - void handleListChannelsResponse(Net::MessageIn &msg); + void handleListChannelsResponse(MessageIn &msg); /** * Handle private messages. */ - void handlePrivateMessage(Net::MessageIn &msg); + void handlePrivateMessage(MessageIn &msg); /** * Handle announcements. */ - void handleAnnouncement(Net::MessageIn &msg); + void handleAnnouncement(MessageIn &msg); /** * Handle chat messages. */ - void handleChatMessage(Net::MessageIn &msg); + void handleChatMessage(MessageIn &msg); /** * Handle quit channel responses. */ - void handleQuitChannelResponse(Net::MessageIn &msg); + void handleQuitChannelResponse(MessageIn &msg); /** * Handle list channel users responses. */ - void handleListChannelUsersResponse(Net::MessageIn &msg); + void handleListChannelUsersResponse(MessageIn &msg); /** * Handle channel events. */ - void handleChannelEvent(Net::MessageIn &msg); + void handleChannelEvent(MessageIn &msg); /** * Handle who responses. */ - void handleWhoResponse(Net::MessageIn &msg); + void handleWhoResponse(MessageIn &msg); }; } // namespace ManaServ diff --git a/src/net/manaserv/effecthandler.cpp b/src/net/manaserv/effecthandler.cpp index 06533be6..d0aaf081 100644 --- a/src/net/manaserv/effecthandler.cpp +++ b/src/net/manaserv/effecthandler.cpp @@ -27,9 +27,8 @@ #include "gui/viewport.h" -#include "net/messagein.h" - #include "net/manaserv/manaserv_protocol.h" +#include "net/manaserv/messagein.h" namespace ManaServ { @@ -44,7 +43,7 @@ EffectHandler::EffectHandler() handledMessages = _messages; } -void EffectHandler::handleMessage(Net::MessageIn &msg) +void EffectHandler::handleMessage(MessageIn &msg) { switch (msg.getId()) { @@ -62,7 +61,7 @@ void EffectHandler::handleMessage(Net::MessageIn &msg) } } -void EffectHandler::handleCreateEffectPos(Net::MessageIn &msg) +void EffectHandler::handleCreateEffectPos(MessageIn &msg) { int id = msg.readInt16(); uint16_t x = msg.readInt16(); @@ -70,7 +69,7 @@ void EffectHandler::handleCreateEffectPos(Net::MessageIn &msg) effectManager->trigger(id, x, y); } -void EffectHandler::handleCreateEffectBeing(Net::MessageIn &msg) +void EffectHandler::handleCreateEffectBeing(MessageIn &msg) { int eid = msg.readInt16(); int bid = msg.readInt16(); @@ -81,7 +80,7 @@ void EffectHandler::handleCreateEffectBeing(Net::MessageIn &msg) logger->log("Warning: CreateEffect called for unknown being #%d", bid); } -void EffectHandler::handleShake(Net::MessageIn &msg) +void EffectHandler::handleShake(MessageIn &msg) { int16_t intensityX = 0; int16_t intensityY = 0; diff --git a/src/net/manaserv/effecthandler.h b/src/net/manaserv/effecthandler.h index 712bded3..de81fea9 100644 --- a/src/net/manaserv/effecthandler.h +++ b/src/net/manaserv/effecthandler.h @@ -31,12 +31,12 @@ class EffectHandler : public MessageHandler public: EffectHandler(); - void handleMessage(Net::MessageIn &msg); + void handleMessage(MessageIn &msg); private: - void handleCreateEffectPos(Net::MessageIn &msg); - void handleCreateEffectBeing(Net::MessageIn &msg); - void handleShake(Net::MessageIn &msg); + void handleCreateEffectPos(MessageIn &msg); + void handleCreateEffectBeing(MessageIn &msg); + void handleShake(MessageIn &msg); }; } // namespace ManaServ diff --git a/src/net/manaserv/gamehandler.cpp b/src/net/manaserv/gamehandler.cpp index 89b80e68..265c0d8a 100644 --- a/src/net/manaserv/gamehandler.cpp +++ b/src/net/manaserv/gamehandler.cpp @@ -26,6 +26,7 @@ #include "net/manaserv/chathandler.h" #include "net/manaserv/connection.h" +#include "net/manaserv/messagein.h" #include "net/manaserv/messageout.h" extern Net::GameHandler *gameHandler; @@ -50,7 +51,7 @@ GameHandler::GameHandler() gameHandler = this; } -void GameHandler::handleMessage(Net::MessageIn &msg) +void GameHandler::handleMessage(MessageIn &msg) { switch (msg.getId()) { diff --git a/src/net/manaserv/gamehandler.h b/src/net/manaserv/gamehandler.h index 2d33710e..454cae43 100644 --- a/src/net/manaserv/gamehandler.h +++ b/src/net/manaserv/gamehandler.h @@ -36,7 +36,7 @@ class GameHandler : public MessageHandler, public Net::GameHandler public: GameHandler(); - void handleMessage(Net::MessageIn &msg); + void handleMessage(MessageIn &msg); void connect(); diff --git a/src/net/manaserv/guildhandler.cpp b/src/net/manaserv/guildhandler.cpp index a8e662ec..cd22fcec 100644 --- a/src/net/manaserv/guildhandler.cpp +++ b/src/net/manaserv/guildhandler.cpp @@ -32,7 +32,6 @@ #include "gui/widgets/channeltab.h" -#include "net/messagein.h" #include "net/net.h" #include "net/manaserv/connection.h" @@ -62,6 +61,7 @@ GuildHandler::GuildHandler() CPMSG_GUILD_INVITED, CPMSG_GUILD_REJOIN, CPMSG_GUILD_QUIT_RESPONSE, + CPMSG_GUILD_KICK_NOTIFICATION, 0 }; handledMessages = _messages; @@ -69,7 +69,7 @@ GuildHandler::GuildHandler() guildHandler = this; } -void GuildHandler::handleMessage(Net::MessageIn &msg) +void GuildHandler::handleMessage(MessageIn &msg) { switch (msg.getId()) { @@ -91,11 +91,20 @@ void GuildHandler::handleMessage(Net::MessageIn &msg) case CPMSG_GUILD_INVITE_RESPONSE: { logger->log("Received CPMSG_GUILD_INVITE_RESPONSE"); - if (msg.readInt8() == ERRMSG_OK) + const unsigned char response = msg.readInt8(); + if (response == ERRMSG_OK) { // TODO - Acknowledge invite was sent SERVER_NOTICE(_("Invite sent.")) } + else if (response == ERRMSG_ALREADY_MEMBER) + { + SERVER_NOTICE(_("Invited player is already in that guild.")); + } + else if (response == ERRMSG_LIMIT_REACHED) + { + SERVER_NOTICE(_("Invited player can't join another guild.")); + } } break; case CPMSG_GUILD_ACCEPT_RESPONSE: @@ -235,10 +244,27 @@ void GuildHandler::handleMessage(Net::MessageIn &msg) } } } break; + case CPMSG_GUILD_KICK_NOTIFICATION: + { + logger->log("Received CPMSG_GUILD_KICK_NOTIFICATION"); + + const int guildId = msg.readInt16(); + std::string player = msg.readString(); + Guild *guild = local_player->getGuild(guildId); + if (guild) + { + Channel *channel = channelManager->findByName(guild->getName()); + channelManager->removeChannel(channel); + local_player->removeGuild(guildId); + SERVER_NOTICE(strprintf( + _("Player %s kicked you out of guild %s"), + player.c_str(), guild->getName().c_str())); + } + } break; } } -void GuildHandler::joinedGuild(Net::MessageIn &msg) +void GuildHandler::joinedGuild(MessageIn &msg) { std::string guildName = msg.readString(); short guildId = msg.readInt16(); @@ -283,9 +309,10 @@ void GuildHandler::invite(int guildId, Being *being) void GuildHandler::inviteResponse(int guildId, bool response) { - /*MessageOut msg(PCMSG_GUILD_ACCEPT); - msg.writeString(name); - chatServerConnection->send(msg);*/ + MessageOut msg(PCMSG_GUILD_ACCEPT); + msg.writeInt16(guildId); + msg.writeInt8(response ? 1 : 0); + chatServerConnection->send(msg); } void GuildHandler::leave(int guildId) diff --git a/src/net/manaserv/guildhandler.h b/src/net/manaserv/guildhandler.h index 0d3da7bf..d1232a6f 100644 --- a/src/net/manaserv/guildhandler.h +++ b/src/net/manaserv/guildhandler.h @@ -35,7 +35,7 @@ public: bool isSupported() { return true; } - void handleMessage(Net::MessageIn &msg); + void handleMessage(MessageIn &msg); void create(const std::string &name); @@ -63,7 +63,7 @@ public: void endAlliance(int guildId, int otherGuildId); protected: - void joinedGuild(Net::MessageIn &msg); + void joinedGuild(MessageIn &msg); }; } // namespace ManaServ diff --git a/src/net/manaserv/inventoryhandler.cpp b/src/net/manaserv/inventoryhandler.cpp index 0ece6e11..b306869e 100644 --- a/src/net/manaserv/inventoryhandler.cpp +++ b/src/net/manaserv/inventoryhandler.cpp @@ -328,7 +328,7 @@ InventoryHandler::InventoryHandler() listen(Event::ItemChannel); } -void InventoryHandler::handleMessage(Net::MessageIn &msg) +void InventoryHandler::handleMessage(MessageIn &msg) { switch (msg.getId()) { diff --git a/src/net/manaserv/inventoryhandler.h b/src/net/manaserv/inventoryhandler.h index 0a07c38d..808acb96 100644 --- a/src/net/manaserv/inventoryhandler.h +++ b/src/net/manaserv/inventoryhandler.h @@ -125,7 +125,7 @@ class InventoryHandler : public MessageHandler, Net::InventoryHandler, public: InventoryHandler(); - void handleMessage(Net::MessageIn &msg); + void handleMessage(MessageIn &msg); void event(Event::Channel channel, const Event &event); diff --git a/src/net/manaserv/itemhandler.cpp b/src/net/manaserv/itemhandler.cpp index 5e46b9eb..4e29bb4f 100644 --- a/src/net/manaserv/itemhandler.cpp +++ b/src/net/manaserv/itemhandler.cpp @@ -40,7 +40,7 @@ ItemHandler::ItemHandler() handledMessages = _messages; } -void ItemHandler::handleMessage(Net::MessageIn &msg) +void ItemHandler::handleMessage(MessageIn &msg) { switch (msg.getId()) { diff --git a/src/net/manaserv/itemhandler.h b/src/net/manaserv/itemhandler.h index fef2fa53..e45db269 100644 --- a/src/net/manaserv/itemhandler.h +++ b/src/net/manaserv/itemhandler.h @@ -31,7 +31,7 @@ class ItemHandler : public MessageHandler public: ItemHandler(); - void handleMessage(Net::MessageIn &msg); + void handleMessage(MessageIn &msg); }; } // namespace ManaServ diff --git a/src/net/manaserv/loginhandler.cpp b/src/net/manaserv/loginhandler.cpp index 18fea9de..416e9422 100644 --- a/src/net/manaserv/loginhandler.cpp +++ b/src/net/manaserv/loginhandler.cpp @@ -59,7 +59,7 @@ LoginHandler::LoginHandler() loginHandler = this; } -void LoginHandler::handleMessage(Net::MessageIn &msg) +void LoginHandler::handleMessage(MessageIn &msg) { switch (msg.getId()) { @@ -250,13 +250,13 @@ void LoginHandler::handleMessage(Net::MessageIn &msg) } } -void LoginHandler::handleLoginRandomResponse(Net::MessageIn &msg) +void LoginHandler::handleLoginRandomResponse(MessageIn &msg) { mLoginData->randomSeed = msg.readString(); loginAccountContinue(); } -void LoginHandler::handleLoginResponse(Net::MessageIn &msg) +void LoginHandler::handleLoginResponse(MessageIn &msg) { const int errMsg = msg.readInt8(); @@ -294,7 +294,7 @@ void LoginHandler::handleLoginResponse(Net::MessageIn &msg) } } -void LoginHandler::handleRegisterResponse(Net::MessageIn &msg) +void LoginHandler::handleRegisterResponse(MessageIn &msg) { const int errMsg = msg.readInt8(); @@ -331,7 +331,7 @@ void LoginHandler::handleRegisterResponse(Net::MessageIn &msg) } } -void LoginHandler::readServerInfo(Net::MessageIn &msg) +void LoginHandler::readServerInfo(MessageIn &msg) { // Safety check for outdated manaserv versions (remove me later) if (msg.getUnreadLength() == 0) diff --git a/src/net/manaserv/loginhandler.h b/src/net/manaserv/loginhandler.h index 3145beab..33cc83ad 100644 --- a/src/net/manaserv/loginhandler.h +++ b/src/net/manaserv/loginhandler.h @@ -36,7 +36,7 @@ class LoginHandler : public MessageHandler, public Net::LoginHandler public: LoginHandler(); - void handleMessage(Net::MessageIn &msg); + void handleMessage(MessageIn &msg); void connect(); @@ -77,11 +77,11 @@ class LoginHandler : public MessageHandler, public Net::LoginHandler void reconnect(); private: - void handleLoginRandomResponse(Net::MessageIn &msg); - void handleLoginResponse(Net::MessageIn &msg); - void handleRegisterResponse(Net::MessageIn &msg); + void handleLoginRandomResponse(MessageIn &msg); + void handleLoginResponse(MessageIn &msg); + void handleRegisterResponse(MessageIn &msg); - void readServerInfo(Net::MessageIn &msg); + void readServerInfo(MessageIn &msg); void loginAccountContinue(); diff --git a/src/net/manaserv/manaserv_protocol.h b/src/net/manaserv/manaserv_protocol.h index aa1976f1..5f94b726 100644 --- a/src/net/manaserv/manaserv_protocol.h +++ b/src/net/manaserv/manaserv_protocol.h @@ -26,7 +26,19 @@ namespace ManaServ { enum { PROTOCOL_VERSION = 1, - SUPPORTED_DB_VERSION = 19 + SUPPORTED_DB_VERSION = 21 +}; + +/** + * The type of a value in a message. Prepended before each value when the + * protocol is running in debug mode. + */ +enum ValueType { + Int8, + Int16, + Int32, + String, + Double }; /** @@ -43,7 +55,7 @@ enum { * Components: B byte, W word, D double word, S variable-size string * C tile-based coordinates (B*3) * - * Hosts: P (player's client), A (account server), C (char server), + * Hosts: P (player's client), A (account server), C (chat server), * G (game server) * * TODO - Document specific error codes for each packet @@ -127,8 +139,9 @@ enum { GPMSG_ITEMS = 0x0281, // { W item id, W*2 position }* PGMSG_ATTACK = 0x0290, // W being id GPMSG_BEING_ATTACK = 0x0291, // W being id, B direction, B attack Id - PGMSG_USE_SPECIAL = 0x0292, // B specialID + PGMSG_USE_SPECIAL_ON_BEING = 0x0292, // B specialID, W being id GPMSG_SPECIAL_STATUS = 0x0293, // { B specialID, D current, D max, D recharge } + PGMSG_USE_SPECIAL_ON_POINT = 0x0294, // B specialID, W*2 position PGMSG_SAY = 0x02A0, // S text GPMSG_SAY = 0x02A1, // W being id, S text GPMSG_NPC_CHOICE = 0x02B0, // W being id, { S text }* @@ -175,7 +188,7 @@ enum { CPMSG_GUILD_CREATE_RESPONSE = 0x0351, // B error, W guild, B rights, W channel PCMSG_GUILD_INVITE = 0x0352, // W id, S name CPMSG_GUILD_INVITE_RESPONSE = 0x0353, // B error - PCMSG_GUILD_ACCEPT = 0x0354, // W id + PCMSG_GUILD_ACCEPT = 0x0354, // W id, B accepted (0 if false, 1 if true) CPMSG_GUILD_ACCEPT_RESPONSE = 0x0355, // B error, W guild, B rights, W channel PCMSG_GUILD_GET_MEMBERS = 0x0356, // W id CPMSG_GUILD_GET_MEMBERS_RESPONSE = 0x0357, // S names, B online @@ -186,6 +199,7 @@ enum { CPMSG_GUILD_PROMOTE_MEMBER_RESPONSE = 0x0366, // B error PCMSG_GUILD_KICK_MEMBER = 0x0370, // W guild, S name CPMSG_GUILD_KICK_MEMBER_RESPONSE = 0x0371, // B error + CPMSG_GUILD_KICK_NOTIFICATION = 0x0372, // W guild, S player that kicked CPMSG_GUILD_INVITED = 0x0388, // S char name, S guild name, W id CPMSG_GUILD_REJOIN = 0x0389, // S name, W guild, W rights, W channel, S announce @@ -230,7 +244,7 @@ enum { // Inter-server GAMSG_REGISTER = 0x0500, // S address, W port, S password, D items db revision, { W map id }* - AGMSG_REGISTER_RESPONSE = 0x0501, // C item version, C password response, { S globalvar_key, S globalvar_value } + AGMSG_REGISTER_RESPONSE = 0x0501, // W item version, W password response, { S globalvar_key, S globalvar_value } AGMSG_ACTIVE_MAP = 0x0502, // W map id, W Number of mapvar_key mapvar_value sent, { S mapvar_key, S mapvar_value }, W Number of map items, { D item Id, W amount, W posX, W posY } AGMSG_PLAYER_ENTER = 0x0510, // B*32 token, D id, S name, serialised character data GAMSG_PLAYER_DATA = 0x0520, // D id, serialised character data @@ -250,7 +264,7 @@ enum { GAMSG_BAN_PLAYER = 0x0550, // D id, W duration GAMSG_CHANGE_PLAYER_LEVEL = 0x0555, // D id, W level GAMSG_CHANGE_ACCOUNT_LEVEL = 0x0556, // D id, W level - GAMSG_STATISTICS = 0x0560, // { W map id, W thing nb, W monster nb, W player nb, { D character id }* }* + GAMSG_STATISTICS = 0x0560, // { W map id, W entity nb, W monster nb, W player nb, { D character id }* }* CGMSG_CHANGED_PARTY = 0x0590, // D character id, D party id GCMSG_REQUEST_POST = 0x05A0, // D character id CGMSG_POST_RESPONSE = 0x05A1, // D receiver id, { S sender name, S letter, W num attachments { W attachment item id, W quantity } } @@ -261,7 +275,8 @@ enum { GAMSG_REMOVE_ITEM_ON_MAP = 0x0602, // D map id, D item id, W amount, W pos x, W pos y GAMSG_ANNOUNCE = 0x0603, // S text, W senderid, S sendername - XXMSG_INVALID = 0x7FFF + XXMSG_DEBUG_FLAG = 0x8000, // Message in debug mode + XXMSG_INVALID = 0x7FFF }; // Generic return values @@ -278,7 +293,8 @@ enum { ERRMSG_SERVER_FULL, // the server is overloaded ERRMSG_TIME_OUT, // data failed to arrive in due time ERRMSG_LIMIT_REACHED, // limit reached - ERRMSG_ADMINISTRATIVE_LOGOFF // kicked by server administrator + ERRMSG_ADMINISTRATIVE_LOGOFF, // kicked by server administrator + ERRMSG_ALREADY_MEMBER // is already member of guild/party }; // used in AGMSG_REGISTER_RESPONSE to show state of item db @@ -337,8 +353,8 @@ enum AttribmodResponseCode { ATTRIBMOD_DENIED }; -// Object type enumeration -enum ThingType +// Entity type enumeration +enum EntityType { // A simple item. OBJECT_ITEM = 0, diff --git a/src/net/manaserv/messagehandler.cpp b/src/net/manaserv/messagehandler.cpp index 79d6667c..6ebd8c3c 100644 --- a/src/net/manaserv/messagehandler.cpp +++ b/src/net/manaserv/messagehandler.cpp @@ -32,4 +32,4 @@ MessageHandler::~MessageHandler() unregisterHandler(this); } -} +} // namespace ManaServ diff --git a/src/net/manaserv/messagehandler.h b/src/net/manaserv/messagehandler.h index 97708415..6e0221cb 100644 --- a/src/net/manaserv/messagehandler.h +++ b/src/net/manaserv/messagehandler.h @@ -24,8 +24,12 @@ #include "net/messagehandler.h" +#include <memory> + namespace ManaServ { +class MessageIn; + /** * \ingroup Network */ @@ -34,10 +38,11 @@ class MessageHandler : public Net::MessageHandler public: ~MessageHandler(); + virtual void handleMessage(MessageIn &msg) = 0; }; typedef const std::auto_ptr<MessageHandler> MessageHandlerPtr; -} +} // namespace ManaServ #endif // NET_MANASERV_MESSAGEHANDLER_H diff --git a/src/net/manaserv/messagein.cpp b/src/net/manaserv/messagein.cpp index 4994de4c..8065d313 100644 --- a/src/net/manaserv/messagein.cpp +++ b/src/net/manaserv/messagein.cpp @@ -27,15 +27,41 @@ namespace ManaServ { MessageIn::MessageIn(const char *data, unsigned int length): - Net::MessageIn(data, length) + mData(data), + mLength(length), + mDebugMode(false), + mPos(0) { // Read the message ID mId = readInt16(); + + // Read and clear the debug flag + mDebugMode = mId & ManaServ::XXMSG_DEBUG_FLAG; + mId &= ~ManaServ::XXMSG_DEBUG_FLAG; +} + +uint8_t MessageIn::readInt8() +{ + uint8_t value = 0; + + if (!readValueType(ManaServ::Int8)) + return value; + + if (mPos < mLength) + { + value = mData[mPos]; + } + mPos++; + return value; } uint16_t MessageIn::readInt16() { uint16_t value = 0; + + if (!readValueType(ManaServ::Int16)) + return value; + if (mPos + 2 <= mLength) { uint16_t t; @@ -49,6 +75,10 @@ uint16_t MessageIn::readInt16() uint32_t MessageIn::readInt32() { uint32_t value = 0; + + if (!readValueType(ManaServ::Int32)) + return value; + if (mPos + 4 <= mLength) { uint32_t t; @@ -59,4 +89,57 @@ uint32_t MessageIn::readInt32() return value; } +std::string MessageIn::readString(int length) +{ + if (!readValueType(ManaServ::String)) + return std::string(); + + if (mDebugMode) + { + int fixedLength = (int16_t) readInt16(); + if (fixedLength != length) + { + // String does not have the expected length + mPos = mLength + 1; + return std::string(); + } + } + + // Get string length + if (length < 0) + { + length = readInt16(); + } + + // Make sure the string isn't erroneous + if (length < 0 || mPos + length > mLength) + { + mPos = mLength + 1; + return std::string(); + } + + // Read the string + const char *stringBeg = mData + mPos; + const char *stringEnd = (const char *)memchr(stringBeg, '\0', length); + std::string readString(stringBeg, + stringEnd ? stringEnd - stringBeg : length); + mPos += length; + + return readString; +} + +bool MessageIn::readValueType(ManaServ::ValueType type) +{ + if (!mDebugMode) // Verification not possible + return true; + + if (mPos >= mLength) + return false; + + uint8_t t = mData[mPos]; + ++mPos; + + return t == type; } + +} // ManaServ diff --git a/src/net/manaserv/messagein.h b/src/net/manaserv/messagein.h index 97e68812..89ae5ed8 100644 --- a/src/net/manaserv/messagein.h +++ b/src/net/manaserv/messagein.h @@ -22,24 +22,75 @@ #ifndef NET_MANASERV_MESSAGEIN_H #define NET_MANASERV_MESSAGEIN_H -#include "net/messagein.h" +#include "net/manaserv/manaserv_protocol.h" + +#include <cstdint> +#include <string> namespace ManaServ { /** - * Used for parsing an incoming message. + * Used for parsing an incoming message from manaserv. * * \ingroup Network */ -class MessageIn : public Net::MessageIn +class MessageIn { public: MessageIn(const char *data, unsigned int length); + /** + * Returns the message ID. + */ + uint16_t getId() const { return mId; } + + /** + * Returns the message length. + */ + unsigned int getLength() const { return mLength; } + + /** + * Returns the length of unread data. + */ + unsigned int getUnreadLength() const { return mLength - mPos; } + + /** + * Reads an unsigned 8-bit integer from the message. + */ + uint8_t readInt8(); + + /** + * Reads an unsigned 16-bit integer from the message. + */ uint16_t readInt16(); + + /** + * Reads an unsigned 32-bit integer from the message. + */ uint32_t readInt32(); + + /** + * Reads a string. If a length is not given (-1), it is assumed + * that the length of the string is stored in a short at the + * start of the string. + */ + std::string readString(int length = -1); + + private: + bool readValueType(ManaServ::ValueType type); + + const char *mData; /**< The message data. */ + unsigned int mLength; /**< The length of the data. */ + unsigned short mId; /**< The message ID. */ + bool mDebugMode; /**< Includes debugging information. */ + + /** + * Actual position in the packet. From 0 to packet->length. A value + * bigger than packet->length means EOP was reached when reading it. + */ + unsigned int mPos; }; -} +} // namespace ManaServ #endif // NET_MANASERV_MESSAGEIN_H diff --git a/src/net/manaserv/messageout.cpp b/src/net/manaserv/messageout.cpp index 6a8482e8..1197176f 100644 --- a/src/net/manaserv/messageout.cpp +++ b/src/net/manaserv/messageout.cpp @@ -28,9 +28,17 @@ namespace ManaServ { MessageOut::MessageOut(uint16_t id): - Net::MessageOut(id) + mData(0), + mPos(0), + mDataSize(0), + mDebugMode(false) { + bool debug = true; + if (debug) + id |= ManaServ::XXMSG_DEBUG_FLAG; + writeInt16(id); + mDebugMode = debug; } MessageOut::~MessageOut() @@ -44,8 +52,21 @@ void MessageOut::expand(size_t bytes) mDataSize = mPos + bytes; } +void MessageOut::writeInt8(uint8_t value) +{ + if (mDebugMode) + writeValueType(ManaServ::Int8); + + expand(1); + mData[mPos] = value; + mPos += 1; +} + void MessageOut::writeInt16(uint16_t value) { + if (mDebugMode) + writeValueType(ManaServ::Int16); + expand(2); uint16_t t = ENET_HOST_TO_NET_16(value); memcpy(mData + mPos, &t, 2); @@ -54,10 +75,53 @@ void MessageOut::writeInt16(uint16_t value) void MessageOut::writeInt32(uint32_t value) { + if (mDebugMode) + writeValueType(ManaServ::Int32); + expand(4); uint32_t t = ENET_HOST_TO_NET_32(value); memcpy(mData + mPos, &t, 4); mPos += 4; } +void MessageOut::writeString(const std::string &string, int length) +{ + if (mDebugMode) + { + writeValueType(ManaServ::String); + writeInt16(length); + } + + int stringLength = string.length(); + if (length < 0) + { + // Write the length at the start if not fixed + writeInt16(stringLength); + length = stringLength; + } + else if (length < stringLength) + { + // Make sure the length of the string is no longer than specified + stringLength = length; + } + expand(length); + + // Write the actual string + memcpy(mData + mPos, string.data(), stringLength); + + if (length > stringLength) + { + // Pad remaining space with zeros + memset(mData + mPos + stringLength, '\0', length - stringLength); + } + mPos += length; +} + +void MessageOut::writeValueType(ManaServ::ValueType type) +{ + expand(1); + mData[mPos] = type; + mPos += 1; +} + } // namespace ManaServ diff --git a/src/net/manaserv/messageout.h b/src/net/manaserv/messageout.h index 59fc148f..d452f784 100644 --- a/src/net/manaserv/messageout.h +++ b/src/net/manaserv/messageout.h @@ -22,21 +22,57 @@ #ifndef NET_MANASERV_MESSAGEOUT_H #define NET_MANASERV_MESSAGEOUT_H -#include "net/messageout.h" +#include "net/manaserv/manaserv_protocol.h" + +#include <cstdint> +#include <string> namespace ManaServ { -class MessageOut : public Net::MessageOut +/** + * Used for building an outgoing message to manaserv. + * + * \ingroup Network + */ +class MessageOut { public: MessageOut(uint16_t id); ~MessageOut(); + /** + * Writes an unsigned 8-bit integer to the message. + */ + void writeInt8(uint8_t value); + + /** + * Writes an unsigned 16-bit integer to the message. + */ void writeInt16(uint16_t value); + + /** + * Writes an unsigned 32-bit integer to the message. + */ void writeInt32(uint32_t value); - protected: + /** + * Writes a string. If a fixed length is not given (-1), it is stored + * as a short at the start of the string. + */ + void writeString(const std::string &string, int length = -1); + + /** + * Returns the content of the message. + */ + char *getData() const { return mData; } + + /** + * Returns the length of the data. + */ + unsigned int getDataSize() const { return mDataSize; } + + private: /** * Expand the packet data to be able to hold more data. * @@ -45,8 +81,15 @@ class MessageOut : public Net::MessageOut * added. */ void expand(size_t size); + + void writeValueType(ManaServ::ValueType type); + + char *mData; /**< Data building up. */ + unsigned int mPos; /**< Position in the data. */ + unsigned int mDataSize; /**< Size of data. */ + bool mDebugMode; /**< Include debugging information. */ }; -} +} // namespace ManaServ #endif // NET_MANASERV_MESSAGEOUT_H diff --git a/src/net/manaserv/npchandler.cpp b/src/net/manaserv/npchandler.cpp index 71b761ab..502df13d 100644 --- a/src/net/manaserv/npchandler.cpp +++ b/src/net/manaserv/npchandler.cpp @@ -53,7 +53,7 @@ NpcHandler::NpcHandler() npcHandler = this; } -void NpcHandler::handleMessage(Net::MessageIn &msg) +void NpcHandler::handleMessage(MessageIn &msg) { Being *being = actorSpriteManager->findBeing(msg.readInt16()); if (!being || being->getType() != ActorSprite::NPC) @@ -108,7 +108,7 @@ void NpcHandler::handleMessage(Net::MessageIn &msg) case GPMSG_NPC_MESSAGE: event = new Event(Event::Message); event->setInt("id", npcId); - event->setString("text", msg.readString(msg.getUnreadLength())); + event->setString("text", msg.readString()); event->trigger(Event::NpcChannel); delete event; diff --git a/src/net/manaserv/npchandler.h b/src/net/manaserv/npchandler.h index 29821da5..0f42385d 100644 --- a/src/net/manaserv/npchandler.h +++ b/src/net/manaserv/npchandler.h @@ -37,7 +37,7 @@ class NpcHandler : public MessageHandler, public Net::NpcHandler public: NpcHandler(); - void handleMessage(Net::MessageIn &msg); + void handleMessage(MessageIn &msg); void startShopping(int beingId); diff --git a/src/net/manaserv/partyhandler.cpp b/src/net/manaserv/partyhandler.cpp index 2bb688e0..a0d4b6d9 100644 --- a/src/net/manaserv/partyhandler.cpp +++ b/src/net/manaserv/partyhandler.cpp @@ -65,7 +65,7 @@ PartyHandler::PartyHandler(): mParty->setName("Party"); } -void PartyHandler::handleMessage(Net::MessageIn &msg) +void PartyHandler::handleMessage(MessageIn &msg) { switch (msg.getId()) { diff --git a/src/net/manaserv/partyhandler.h b/src/net/manaserv/partyhandler.h index 4b316bd2..6c526f73 100644 --- a/src/net/manaserv/partyhandler.h +++ b/src/net/manaserv/partyhandler.h @@ -37,7 +37,7 @@ class PartyHandler : public MessageHandler, public Net::PartyHandler public: PartyHandler(); - void handleMessage(Net::MessageIn &msg); + void handleMessage(MessageIn &msg); void create(const std::string &name = ""); diff --git a/src/net/manaserv/playerhandler.cpp b/src/net/manaserv/playerhandler.cpp index adb60fb3..841ead56 100644 --- a/src/net/manaserv/playerhandler.cpp +++ b/src/net/manaserv/playerhandler.cpp @@ -85,7 +85,7 @@ PlayerHandler::PlayerHandler() playerHandler = this; } -void PlayerHandler::handleMessage(Net::MessageIn &msg) +void PlayerHandler::handleMessage(MessageIn &msg) { switch (msg.getId()) { @@ -277,7 +277,7 @@ void PlayerHandler::handleMessage(Net::MessageIn &msg) } } -void PlayerHandler::handleMapChangeMessage(Net::MessageIn &msg) +void PlayerHandler::handleMapChangeMessage(MessageIn &msg) { const std::string mapName = msg.readString(); const unsigned short x = msg.readInt16(); diff --git a/src/net/manaserv/playerhandler.h b/src/net/manaserv/playerhandler.h index 28342f2d..abb29e9b 100644 --- a/src/net/manaserv/playerhandler.h +++ b/src/net/manaserv/playerhandler.h @@ -41,7 +41,7 @@ class PlayerHandler : public MessageHandler, public Net::PlayerHandler public: PlayerHandler(); - void handleMessage(Net::MessageIn &msg); + void handleMessage(MessageIn &msg); void attack(int id); void emote(int emoteId); @@ -73,7 +73,7 @@ class PlayerHandler : public MessageHandler, public Net::PlayerHandler { return true; } private: - void handleMapChangeMessage(Net::MessageIn &msg); + void handleMapChangeMessage(MessageIn &msg); }; } // namespace ManaServ diff --git a/src/net/manaserv/specialhandler.cpp b/src/net/manaserv/specialhandler.cpp index fa98cd48..0a477ff8 100644 --- a/src/net/manaserv/specialhandler.cpp +++ b/src/net/manaserv/specialhandler.cpp @@ -37,26 +37,34 @@ SpecialHandler::SpecialHandler() specialHandler = this; } -void SpecialHandler::handleMessage(Net::MessageIn &msg) +void SpecialHandler::handleMessage(MessageIn &msg) { // TODO } void SpecialHandler::use(int id) { - MessageOut msg(PGMSG_USE_SPECIAL); + MessageOut msg(PGMSG_USE_SPECIAL_ON_BEING); msg.writeInt8(id); + msg.writeInt16(0); gameServerConnection->send(msg); } void SpecialHandler::use(int id, int level, int beingId) { - // TODO + MessageOut msg(PGMSG_USE_SPECIAL_ON_BEING); + msg.writeInt8(id); + msg.writeInt16(beingId); + gameServerConnection->send(msg); } void SpecialHandler::use(int id, int level, int x, int y) { - // TODO + MessageOut msg(PGMSG_USE_SPECIAL_ON_POINT); + msg.writeInt8(id); + msg.writeInt16(x); + msg.writeInt16(y); + gameServerConnection->send(msg); } void SpecialHandler::use(int id, const std::string &map) diff --git a/src/net/manaserv/specialhandler.h b/src/net/manaserv/specialhandler.h index 29de76bb..ee26b3b7 100644 --- a/src/net/manaserv/specialhandler.h +++ b/src/net/manaserv/specialhandler.h @@ -33,7 +33,7 @@ class SpecialHandler : public MessageHandler, public Net::SpecialHandler public: SpecialHandler(); - void handleMessage(Net::MessageIn &msg); + void handleMessage(MessageIn &msg); void use(int id); diff --git a/src/net/manaserv/tradehandler.cpp b/src/net/manaserv/tradehandler.cpp index b5d526ae..ff7849ff 100644 --- a/src/net/manaserv/tradehandler.cpp +++ b/src/net/manaserv/tradehandler.cpp @@ -97,7 +97,7 @@ void TradeHandler::setAcceptTradeRequests(bool acceptTradeRequests) SERVER_NOTICE(_("Ignoring incoming trade requests.")) } -void TradeHandler::handleMessage(Net::MessageIn &msg) +void TradeHandler::handleMessage(MessageIn &msg) { switch (msg.getId()) { diff --git a/src/net/manaserv/tradehandler.h b/src/net/manaserv/tradehandler.h index 321b942f..5d20c14e 100644 --- a/src/net/manaserv/tradehandler.h +++ b/src/net/manaserv/tradehandler.h @@ -33,7 +33,7 @@ class TradeHandler : public MessageHandler, public Net::TradeHandler public: TradeHandler(); - void handleMessage(Net::MessageIn &msg); + void handleMessage(MessageIn &msg); /** * Returns whether trade requests are accepted. diff --git a/src/net/messagehandler.h b/src/net/messagehandler.h index 5a0cc091..3bf6c419 100644 --- a/src/net/messagehandler.h +++ b/src/net/messagehandler.h @@ -22,9 +22,7 @@ #ifndef NET_MESSAGEHANDLER_H #define NET_MESSAGEHANDLER_H -#include "net/messagein.h" - -#include <memory> +#include <cstdint> namespace Net { @@ -36,11 +34,9 @@ class MessageHandler public: const uint16_t *handledMessages; - virtual void handleMessage(MessageIn &msg) = 0; - virtual ~MessageHandler() {} }; -} +} // namespace Net #endif // NET_MESSAGEHANDLER_H diff --git a/src/net/messagein.cpp b/src/net/messagein.cpp deleted file mode 100644 index 46d12884..00000000 --- a/src/net/messagein.cpp +++ /dev/null @@ -1,162 +0,0 @@ -/* - * The Mana Client - * Copyright (C) 2004-2009 The Mana World Development Team - * Copyright (C) 2009-2012 The Mana Developers - * - * This file is part of The Mana Client. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include "net/messagein.h" - -#define MAKEWORD(low,high) \ - ((unsigned short)(((unsigned char)(low)) | \ - ((unsigned short)((unsigned char)(high))) << 8)) - -#include <cstring> - -namespace Net { - -MessageIn::MessageIn(const char *data, unsigned int length): - mData(data), - mLength(length), - mPos(0) -{ -} - -uint8_t MessageIn::readInt8() -{ - uint8_t value = 0; - if (mPos < mLength) - { - value = mData[mPos]; - } - mPos++; - return value; -} - -void MessageIn::readCoordinates(uint16_t &x, uint16_t &y) -{ - if (mPos + 3 <= mLength) - { - unsigned char const *p = reinterpret_cast< unsigned char const * >(mData + mPos); - x = p[0] | ((p[1] & 0x07) << 8); - y = (p[1] >> 3) | ((p[2] & 0x3F) << 5); - } - mPos += 3; -} - -void MessageIn::readCoordinates(uint16_t &x, uint16_t &y, uint8_t &direction) -{ - if (mPos + 3 <= mLength) - { - const char *data = mData + mPos; - uint16_t temp; - - temp = MAKEWORD(data[1] & 0x00c0, data[0] & 0x00ff); - x = temp >> 6; - temp = MAKEWORD(data[2] & 0x00f0, data[1] & 0x003f); - y = temp >> 4; - - direction = data[2] & 0x000f; - - // Translate from tmwAthena format - switch (direction) - { - case 0: - direction = 1; - break; - case 1: - direction = 3; - break; - case 2: - direction = 2; - break; - case 3: - direction = 6; - break; - case 4: - direction = 4; - break; - case 5: - direction = 12; - break; - case 6: - direction = 8; - break; - case 7: - direction = 9; - break; - case 8: - direction = 8; - break; - default: - // OOPSIE! Impossible or unknown - direction = 0; - } - } - mPos += 3; -} - -void MessageIn::readCoordinatePair(uint16_t &srcX, uint16_t &srcY, - uint16_t &dstX, uint16_t &dstY) -{ - if (mPos + 5 <= mLength) - { - const char *data = mData + mPos; - uint16_t temp; - - temp = MAKEWORD(data[3], data[2] & 0x000f); - dstX = temp >> 2; - - dstY = MAKEWORD(data[4], data[3] & 0x0003); - - temp = MAKEWORD(data[1], data[0]); - srcX = temp >> 6; - - temp = MAKEWORD(data[2], data[1] & 0x003f); - srcY = temp >> 4; - } - mPos += 5; -} - -void MessageIn::skip(unsigned int length) -{ - mPos += length; -} - -std::string MessageIn::readString(int length) -{ - // Get string length - if (length < 0) - length = readInt16(); - - // Make sure the string isn't erroneous - if (length < 0 || mPos + length > mLength) - { - mPos = mLength + 1; - return ""; - } - - // Read the string - char const *stringBeg = mData + mPos; - char const *stringEnd = (char const *)memchr(stringBeg, '\0', length); - std::string readString(stringBeg, - stringEnd ? stringEnd - stringBeg : length); - mPos += length; - return readString; -} - -} diff --git a/src/net/messagein.h b/src/net/messagein.h deleted file mode 100644 index 44986f39..00000000 --- a/src/net/messagein.h +++ /dev/null @@ -1,118 +0,0 @@ -/* - * The Mana Client - * Copyright (C) 2004-2009 The Mana World Development Team - * Copyright (C) 2009-2012 The Mana Developers - * - * This file is part of The Mana Client. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef NET_MESSAGEIN_H -#define NET_MESSAGEIN_H - -#include <cstdint> -#include <string> - -namespace Net { - -/** - * Used for parsing an incoming message. - * - * \ingroup Network - */ -class MessageIn -{ - public: - /** - * Returns the message ID. - */ - uint16_t getId() const { return mId; } - - /** - * Returns the message length. - */ - unsigned int getLength() const { return mLength; } - - /** - * Returns the length of unread data. - */ - unsigned int getUnreadLength() const { return mLength - mPos; } - - /** - * Reads an unsigned 8-bit integer from the message. - */ - virtual uint8_t readInt8(); - - /** - * Reads an unsigned 16-bit integer from the message. - */ - virtual uint16_t readInt16() = 0; - - /** - * Reads an unsigned 32-bit integer from the message. - */ - virtual uint32_t readInt32() = 0; - - /** - * Reads a 3-byte block containing tile-based coordinates. Used by - * manaserv. - */ - virtual void readCoordinates(uint16_t &x, uint16_t &y); - - /** - * Reads a special 3 byte block used by eAthena, containing x and y - * coordinates and direction. - */ - virtual void readCoordinates(uint16_t &x, uint16_t &y, uint8_t &direction); - - /** - * Reads a special 5 byte block used by eAthena, containing a source - * and destination coordinate pair. - */ - virtual void readCoordinatePair(uint16_t &srcX, uint16_t &srcY, - uint16_t &dstX, uint16_t &dstY); - - /** - * Skips a given number of bytes. - */ - virtual void skip(unsigned int length); - - /** - * Reads a string. If a length is not given (-1), it is assumed - * that the length of the string is stored in a short at the - * start of the string. - */ - virtual std::string readString(int length = -1); - - virtual ~MessageIn() {} - - protected: - MessageIn(const char *data, unsigned int length); - - const char *mData; /**< The message data. */ - unsigned int mLength; /**< The length of the data. */ - unsigned short mId; /**< The message ID. */ - - /** - * Actual position in the packet. From 0 to packet->length. - * A value bigger than packet->length means EOP was reached when - * reading it. - */ - unsigned int mPos; -}; - -} // namespace Net - -#endif // NET_MESSAGEIN_H diff --git a/src/net/messageout.cpp b/src/net/messageout.cpp deleted file mode 100644 index 56d1d8b7..00000000 --- a/src/net/messageout.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/* - * The Mana Client - * Copyright (C) 2004-2009 The Mana World Development Team - * Copyright (C) 2009-2012 The Mana Developers - * - * This file is part of The Mana Client. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include "net/messageout.h" - -#include <cstring> - -namespace Net { - -MessageOut::MessageOut(uint16_t id): - mData(0), - mDataSize(0), - mPos(0) -{ -} - -void MessageOut::writeInt8(uint8_t value) -{ - expand(1); - mData[mPos] = value; - mPos += 1; -} - -void MessageOut::writeString(const std::string &string, int length) -{ - int stringLength = string.length(); - if (length < 0) - { - // Write the length at the start if not fixed - writeInt16(stringLength); - length = stringLength; - } - else if (length < stringLength) - { - // Make sure the length of the string is no longer than specified - stringLength = length; - } - expand(length); - - // Write the actual string - memcpy(mData + mPos, string.data(), stringLength); - - // Pad remaining space with zeros - if (length > stringLength) - { - memset(mData + mPos + stringLength, '\0', length - stringLength); - } - mPos += length; -} - -char *MessageOut::getData() const -{ - return mData; -} - -unsigned int MessageOut::getDataSize() const -{ - return mDataSize; -} - -} diff --git a/src/net/messageout.h b/src/net/messageout.h deleted file mode 100644 index b8576db2..00000000 --- a/src/net/messageout.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * The Mana Client - * Copyright (C) 2004-2009 The Mana World Development Team - * Copyright (C) 2009-2012 The Mana Developers - * - * This file is part of The Mana Client. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef NET_MESSAGEOUT_H -#define NET_MESSAGEOUT_H - -#include <cstdint> -#include <string> - -namespace Net { - -/** - * Used for building an outgoing message. - * - * \ingroup Network - */ -class MessageOut -{ - public: - /** - * Writes an unsigned 8-bit integer to the message. - */ - virtual void writeInt8(uint8_t value); - - /** - * Writes an unsigned 16-bit integer to the message. - */ - virtual void writeInt16(uint16_t value) = 0; - - /** - * Writes an unsigned 32-bit integer to the message. - */ - virtual void writeInt32(uint32_t value) = 0; - - /** - * Writes a string. If a fixed length is not given (-1), it is stored - * as a short at the start of the string. - */ - virtual void writeString(const std::string &string, int length = -1); - - /** - * Returns the content of the message. - */ - virtual char *getData() const; - - /** - * Returns the length of the data. - */ - virtual unsigned int getDataSize() const; - - virtual ~MessageOut() {} - - protected: - MessageOut(uint16_t id); - - /** - * Expand the packet data to be able to hold more data. - * - * NOTE: For performance enhancements this method could allocate extra - * memory in advance instead of expanding size every time more data is - * added. - */ - virtual void expand(size_t size) = 0; - - char *mData; /**< Data building up. */ - unsigned int mDataSize; /**< Size of data. */ - unsigned int mPos; /**< Position in the data. */ -}; - -} - -#endif // NET_MESSAGEOUT_H diff --git a/src/net/serverinfo.h b/src/net/serverinfo.h index e709bed0..8e2ee5b0 100644 --- a/src/net/serverinfo.h +++ b/src/net/serverinfo.h @@ -108,6 +108,18 @@ public: return MANASERV; return UNKNOWN; } + + static unsigned short defaultPortForServerType(Type type) + { + switch (type) + { + default: + case ServerInfo::TMWATHENA: + return 6901; + case ServerInfo::MANASERV: + return 9601; + } + } }; typedef std::deque<ServerInfo> ServerInfos; diff --git a/src/net/tmwa/adminhandler.cpp b/src/net/tmwa/adminhandler.cpp index 9184c761..29202eb7 100644 --- a/src/net/tmwa/adminhandler.cpp +++ b/src/net/tmwa/adminhandler.cpp @@ -30,6 +30,8 @@ #include "net/chathandler.h" #include "net/net.h" +#include "net/tmwa/messagein.h" +#include "net/tmwa/messageout.h" #include "net/tmwa/protocol.h" #include "utils/gettext.h" @@ -53,7 +55,7 @@ AdminHandler::AdminHandler() adminHandler = this; } -void AdminHandler::handleMessage(Net::MessageIn &msg) +void AdminHandler::handleMessage(MessageIn &msg) { int id; switch (msg.getId()) diff --git a/src/net/tmwa/adminhandler.h b/src/net/tmwa/adminhandler.h index 9b38fa67..71c37a09 100644 --- a/src/net/tmwa/adminhandler.h +++ b/src/net/tmwa/adminhandler.h @@ -34,7 +34,7 @@ class AdminHandler : public MessageHandler, public Net::AdminHandler public: AdminHandler(); - void handleMessage(Net::MessageIn &msg); + void handleMessage(MessageIn &msg); void announce(const std::string &text); diff --git a/src/net/tmwa/beinghandler.cpp b/src/net/tmwa/beinghandler.cpp index b7d84685..fb01990a 100644 --- a/src/net/tmwa/beinghandler.cpp +++ b/src/net/tmwa/beinghandler.cpp @@ -33,6 +33,8 @@ #include "party.h" #include "playerrelations.h" +#include "net/tmwa/messagein.h" +#include "net/tmwa/messageout.h" #include "net/tmwa/protocol.h" #include "resources/hairdb.h" @@ -146,7 +148,7 @@ static void handlePosMessage(Map *map, Being *dstBeing, Uint16 x, Uint16 y, } } -void BeingHandler::handleMessage(Net::MessageIn &msg) +void BeingHandler::handleMessage(MessageIn &msg) { if (!actorSpriteManager) return; diff --git a/src/net/tmwa/beinghandler.h b/src/net/tmwa/beinghandler.h index c1bdbe43..81bbad74 100644 --- a/src/net/tmwa/beinghandler.h +++ b/src/net/tmwa/beinghandler.h @@ -31,7 +31,7 @@ class BeingHandler : public MessageHandler public: BeingHandler(bool enableSync); - virtual void handleMessage(Net::MessageIn &msg); + virtual void handleMessage(MessageIn &msg); private: // Should we honor server "Stop Walking" packets diff --git a/src/net/tmwa/buysellhandler.cpp b/src/net/tmwa/buysellhandler.cpp index e6ccae56..908e1d6d 100644 --- a/src/net/tmwa/buysellhandler.cpp +++ b/src/net/tmwa/buysellhandler.cpp @@ -32,8 +32,7 @@ #include "gui/buyselldialog.h" #include "gui/selldialog.h" -#include "net/messagein.h" - +#include "net/tmwa/messagein.h" #include "net/tmwa/protocol.h" #include "utils/gettext.h" @@ -54,7 +53,7 @@ BuySellHandler::BuySellHandler() handledMessages = _messages; } -void BuySellHandler::handleMessage(Net::MessageIn &msg) +void BuySellHandler::handleMessage(MessageIn &msg) { int n_items; diff --git a/src/net/tmwa/buysellhandler.h b/src/net/tmwa/buysellhandler.h index 18d0294c..b5229e0f 100644 --- a/src/net/tmwa/buysellhandler.h +++ b/src/net/tmwa/buysellhandler.h @@ -33,7 +33,7 @@ class BuySellHandler : public MessageHandler public: BuySellHandler(); - virtual void handleMessage(Net::MessageIn &msg); + virtual void handleMessage(MessageIn &msg); private: int mNpcId; diff --git a/src/net/tmwa/charserverhandler.cpp b/src/net/tmwa/charserverhandler.cpp index 8834798f..ce193821 100644 --- a/src/net/tmwa/charserverhandler.cpp +++ b/src/net/tmwa/charserverhandler.cpp @@ -29,12 +29,12 @@ #include "gui/okdialog.h" #include "net/logindata.h" -#include "net/messagein.h" -#include "net/messageout.h" #include "net/net.h" #include "net/tmwa/gamehandler.h" #include "net/tmwa/loginhandler.h" +#include "net/tmwa/messagein.h" +#include "net/tmwa/messageout.h" #include "net/tmwa/network.h" #include "net/tmwa/protocol.h" @@ -68,7 +68,7 @@ CharServerHandler::CharServerHandler() charHandler = this; } -void CharServerHandler::handleMessage(Net::MessageIn &msg) +void CharServerHandler::handleMessage(MessageIn &msg) { switch (msg.getId()) { @@ -196,7 +196,7 @@ void CharServerHandler::handleMessage(Net::MessageIn &msg) } } -void CharServerHandler::readPlayerData(Net::MessageIn &msg, Net::Character *character) +void CharServerHandler::readPlayerData(MessageIn &msg, Net::Character *character) { const Token &token = static_cast<LoginHandler*>(Net::getLoginHandler())->getToken(); diff --git a/src/net/tmwa/charserverhandler.h b/src/net/tmwa/charserverhandler.h index 31b2ba8e..c9f44e0f 100644 --- a/src/net/tmwa/charserverhandler.h +++ b/src/net/tmwa/charserverhandler.h @@ -40,7 +40,7 @@ class CharServerHandler : public MessageHandler, public Net::CharHandler public: CharServerHandler(); - virtual void handleMessage(Net::MessageIn &msg); + virtual void handleMessage(MessageIn &msg); void setCharSelectDialog(CharSelectDialog *window); @@ -82,7 +82,7 @@ class CharServerHandler : public MessageHandler, public Net::CharHandler void connect(); private: - void readPlayerData(Net::MessageIn &msg, Net::Character *character); + void readPlayerData(MessageIn &msg, Net::Character *character); }; } // namespace TmwAthena diff --git a/src/net/tmwa/chathandler.cpp b/src/net/tmwa/chathandler.cpp index 134db59f..9e5e7b19 100644 --- a/src/net/tmwa/chathandler.cpp +++ b/src/net/tmwa/chathandler.cpp @@ -28,9 +28,8 @@ #include "localplayer.h" #include "playerrelations.h" -#include "net/messagein.h" -#include "net/messageout.h" - +#include "net/tmwa/messagein.h" +#include "net/tmwa/messageout.h" #include "net/tmwa/protocol.h" #include "utils/gettext.h" @@ -57,7 +56,7 @@ ChatHandler::ChatHandler() chatHandler = this; } -void ChatHandler::handleMessage(Net::MessageIn &msg) +void ChatHandler::handleMessage(MessageIn &msg) { Being *being; std::string chatMsg; diff --git a/src/net/tmwa/chathandler.h b/src/net/tmwa/chathandler.h index 65db4bec..fa3a8ec3 100644 --- a/src/net/tmwa/chathandler.h +++ b/src/net/tmwa/chathandler.h @@ -36,7 +36,7 @@ class ChatHandler : public MessageHandler, public Net::ChatHandler public: ChatHandler(); - void handleMessage(Net::MessageIn &msg); + void handleMessage(MessageIn &msg); void talk(const std::string &text); diff --git a/src/net/tmwa/gamehandler.cpp b/src/net/tmwa/gamehandler.cpp index 93f0b86f..68ed62b0 100644 --- a/src/net/tmwa/gamehandler.cpp +++ b/src/net/tmwa/gamehandler.cpp @@ -29,10 +29,9 @@ #include "gui/okdialog.h" -#include "net/messagein.h" -#include "net/messageout.h" - #include "net/tmwa/loginhandler.h" +#include "net/tmwa/messagein.h" +#include "net/tmwa/messageout.h" #include "net/tmwa/network.h" #include "net/tmwa/protocol.h" @@ -60,7 +59,7 @@ GameHandler::GameHandler() listen(Event::GameChannel); } -void GameHandler::handleMessage(Net::MessageIn &msg) +void GameHandler::handleMessage(MessageIn &msg) { switch (msg.getId()) { diff --git a/src/net/tmwa/gamehandler.h b/src/net/tmwa/gamehandler.h index 4f0525b9..a6bcde0a 100644 --- a/src/net/tmwa/gamehandler.h +++ b/src/net/tmwa/gamehandler.h @@ -39,7 +39,7 @@ class GameHandler : public MessageHandler, public Net::GameHandler, public: GameHandler(); - void handleMessage(Net::MessageIn &msg); + void handleMessage(MessageIn &msg); void event(Event::Channel channel, const Event &event); diff --git a/src/net/tmwa/generalhandler.cpp b/src/net/tmwa/generalhandler.cpp index 3bbadccd..6c2bcddb 100644 --- a/src/net/tmwa/generalhandler.cpp +++ b/src/net/tmwa/generalhandler.cpp @@ -32,8 +32,6 @@ #include "gui/socialwindow.h" #include "gui/statuswindow.h" -#include "net/messagein.h" -#include "net/messageout.h" #include "net/serverinfo.h" #include "net/tmwa/adminhandler.h" @@ -46,6 +44,8 @@ #include "net/tmwa/inventoryhandler.h" #include "net/tmwa/itemhandler.h" #include "net/tmwa/loginhandler.h" +#include "net/tmwa/messagein.h" +#include "net/tmwa/messageout.h" #include "net/tmwa/network.h" #include "net/tmwa/npchandler.h" #include "net/tmwa/partyhandler.h" @@ -116,7 +116,7 @@ GeneralHandler::~GeneralHandler() delete mNetwork; } -void GeneralHandler::handleMessage(Net::MessageIn &msg) +void GeneralHandler::handleMessage(MessageIn &msg) { int code; diff --git a/src/net/tmwa/generalhandler.h b/src/net/tmwa/generalhandler.h index 7c8c6037..a34852fd 100644 --- a/src/net/tmwa/generalhandler.h +++ b/src/net/tmwa/generalhandler.h @@ -39,7 +39,7 @@ class GeneralHandler : public MessageHandler, public Net::GeneralHandler, ~GeneralHandler(); - void handleMessage(Net::MessageIn &msg); + void handleMessage(MessageIn &msg); void load(); diff --git a/src/net/tmwa/guildhandler.cpp b/src/net/tmwa/guildhandler.cpp index f34b914e..a3194991 100644 --- a/src/net/tmwa/guildhandler.cpp +++ b/src/net/tmwa/guildhandler.cpp @@ -28,6 +28,7 @@ #include "gui/socialwindow.h" #include "net/tmwa/messagein.h" +#include "net/tmwa/messageout.h" #include "net/tmwa/protocol.h" #include "net/tmwa/gui/guildtab.h" @@ -85,7 +86,7 @@ GuildHandler::~GuildHandler() guildTab = 0; } -void GuildHandler::handleMessage(Net::MessageIn &msg) +void GuildHandler::handleMessage(MessageIn &msg) { switch (msg.getId()) { diff --git a/src/net/tmwa/guildhandler.h b/src/net/tmwa/guildhandler.h index cc2dd524..4a74a26b 100644 --- a/src/net/tmwa/guildhandler.h +++ b/src/net/tmwa/guildhandler.h @@ -34,7 +34,7 @@ class GuildHandler : public Net::GuildHandler, public MessageHandler ~GuildHandler(); - void handleMessage(Net::MessageIn &msg); + void handleMessage(MessageIn &msg); void create(const std::string &name); diff --git a/src/net/tmwa/inventoryhandler.cpp b/src/net/tmwa/inventoryhandler.cpp index f260110d..256e7159 100644 --- a/src/net/tmwa/inventoryhandler.cpp +++ b/src/net/tmwa/inventoryhandler.cpp @@ -34,9 +34,8 @@ #include "gui/equipmentwindow.h" #include "gui/widgets/chattab.h" -#include "net/messagein.h" -#include "net/messageout.h" - +#include "net/tmwa/messagein.h" +#include "net/tmwa/messageout.h" #include "net/tmwa/protocol.h" #include "resources/iteminfo.h" @@ -125,7 +124,7 @@ InventoryHandler::~InventoryHandler() delete mStorage; } -void InventoryHandler::handleMessage(Net::MessageIn &msg) +void InventoryHandler::handleMessage(MessageIn &msg) { int number, flag; int index, amount, itemId, equipType; diff --git a/src/net/tmwa/inventoryhandler.h b/src/net/tmwa/inventoryhandler.h index 88ab953d..3eefdd9b 100644 --- a/src/net/tmwa/inventoryhandler.h +++ b/src/net/tmwa/inventoryhandler.h @@ -187,7 +187,7 @@ class InventoryHandler : public MessageHandler, public Net::InventoryHandler, ~InventoryHandler(); - void handleMessage(Net::MessageIn &msg); + void handleMessage(MessageIn &msg); void event(Event::Channel channel, const Event &event); diff --git a/src/net/tmwa/itemhandler.cpp b/src/net/tmwa/itemhandler.cpp index d1a560f3..f05bb899 100644 --- a/src/net/tmwa/itemhandler.cpp +++ b/src/net/tmwa/itemhandler.cpp @@ -21,8 +21,7 @@ #include "net/tmwa/itemhandler.h" -#include "net/messagein.h" - +#include "net/tmwa/messagein.h" #include "net/tmwa/protocol.h" #include "actorspritemanager.h" @@ -42,7 +41,7 @@ ItemHandler::ItemHandler() handledMessages = _messages; } -void ItemHandler::handleMessage(Net::MessageIn &msg) +void ItemHandler::handleMessage(MessageIn &msg) { switch (msg.getId()) { diff --git a/src/net/tmwa/itemhandler.h b/src/net/tmwa/itemhandler.h index 96557d8b..3f58a172 100644 --- a/src/net/tmwa/itemhandler.h +++ b/src/net/tmwa/itemhandler.h @@ -31,7 +31,7 @@ class ItemHandler : public MessageHandler public: ItemHandler(); - virtual void handleMessage(Net::MessageIn &msg); + virtual void handleMessage(MessageIn &msg); }; } // namespace TmwAthena diff --git a/src/net/tmwa/loginhandler.cpp b/src/net/tmwa/loginhandler.cpp index 393e712a..51c757cc 100644 --- a/src/net/tmwa/loginhandler.cpp +++ b/src/net/tmwa/loginhandler.cpp @@ -25,9 +25,9 @@ #include "log.h" #include "net/logindata.h" -#include "net/messagein.h" -#include "net/messageout.h" +#include "net/tmwa/messagein.h" +#include "net/tmwa/messageout.h" #include "net/tmwa/network.h" #include "net/tmwa/protocol.h" @@ -62,7 +62,7 @@ LoginHandler::~LoginHandler() delete_all(mWorlds); } -void LoginHandler::handleMessage(Net::MessageIn &msg) +void LoginHandler::handleMessage(MessageIn &msg) { int code, worldCount; diff --git a/src/net/tmwa/loginhandler.h b/src/net/tmwa/loginhandler.h index fcd51e46..fcc7c5cc 100644 --- a/src/net/tmwa/loginhandler.h +++ b/src/net/tmwa/loginhandler.h @@ -40,7 +40,7 @@ class LoginHandler : public MessageHandler, public Net::LoginHandler ~LoginHandler(); - void handleMessage(Net::MessageIn &msg); + void handleMessage(MessageIn &msg); void connect(); diff --git a/src/net/tmwa/messagehandler.h b/src/net/tmwa/messagehandler.h index 82bbabbc..2b1f5b7e 100644 --- a/src/net/tmwa/messagehandler.h +++ b/src/net/tmwa/messagehandler.h @@ -23,14 +23,12 @@ #define NET_TA_MESSAGEHANDLER_H #include "net/messagehandler.h" -#include "net/messagein.h" - -#include "net/tmwa/messageout.h" #include <memory> namespace TmwAthena { +class MessageIn; class Network; /** @@ -43,6 +41,8 @@ class MessageHandler : public Net::MessageHandler ~MessageHandler(); + virtual void handleMessage(MessageIn &msg) = 0; + void setNetwork(Network *network); protected: diff --git a/src/net/tmwa/messagein.cpp b/src/net/tmwa/messagein.cpp index c4d083b3..899b135d 100644 --- a/src/net/tmwa/messagein.cpp +++ b/src/net/tmwa/messagein.cpp @@ -24,15 +24,32 @@ #include <SDL.h> #include <SDL_endian.h> +#define MAKEWORD(low,high) \ + ((unsigned short)(((unsigned char)(low)) | \ + ((unsigned short)((unsigned char)(high))) << 8)) + namespace TmwAthena { MessageIn::MessageIn(const char *data, unsigned int length): - Net::MessageIn(data, length) + mData(data), + mLength(length), + mPos(0) { // Read the message ID mId = readInt16(); } +uint8_t MessageIn::readInt8() +{ + uint8_t value = 0; + if (mPos < mLength) + { + value = mData[mPos]; + } + mPos++; + return value; +} + uint16_t MessageIn::readInt16() { uint16_t value = 0; @@ -67,4 +84,105 @@ uint32_t MessageIn::readInt32() return value; } +void MessageIn::readCoordinates(uint16_t &x, uint16_t &y, uint8_t &direction) +{ + if (mPos + 3 <= mLength) + { + const char *data = mData + mPos; + uint16_t temp; + + temp = MAKEWORD(data[1] & 0x00c0, data[0] & 0x00ff); + x = temp >> 6; + temp = MAKEWORD(data[2] & 0x00f0, data[1] & 0x003f); + y = temp >> 4; + + direction = data[2] & 0x000f; + + // Translate from tmwAthena format + switch (direction) + { + case 0: + direction = 1; + break; + case 1: + direction = 3; + break; + case 2: + direction = 2; + break; + case 3: + direction = 6; + break; + case 4: + direction = 4; + break; + case 5: + direction = 12; + break; + case 6: + direction = 8; + break; + case 7: + direction = 9; + break; + case 8: + direction = 8; + break; + default: + // OOPSIE! Impossible or unknown + direction = 0; + } + } + mPos += 3; +} + +void MessageIn::readCoordinatePair(uint16_t &srcX, uint16_t &srcY, + uint16_t &dstX, uint16_t &dstY) +{ + if (mPos + 5 <= mLength) + { + const char *data = mData + mPos; + uint16_t temp; + + temp = MAKEWORD(data[3], data[2] & 0x000f); + dstX = temp >> 2; + + dstY = MAKEWORD(data[4], data[3] & 0x0003); + + temp = MAKEWORD(data[1], data[0]); + srcX = temp >> 6; + + temp = MAKEWORD(data[2], data[1] & 0x003f); + srcY = temp >> 4; + } + mPos += 5; +} + +void MessageIn::skip(unsigned int length) +{ + mPos += length; +} + +std::string MessageIn::readString(int length) +{ + // Get string length + if (length < 0) + length = readInt16(); + + // Make sure the string isn't erroneous + if (length < 0 || mPos + length > mLength) + { + mPos = mLength + 1; + return ""; + } + + // Read the string + char const *stringBeg = mData + mPos; + char const *stringEnd = (char const *)memchr(stringBeg, '\0', length); + std::string readString(stringBeg, + stringEnd ? stringEnd - stringBeg : length); + mPos += length; + return readString; +} + } // namespace TmwAthena diff --git a/src/net/tmwa/messagein.h b/src/net/tmwa/messagein.h index 714f71bb..48121187 100644 --- a/src/net/tmwa/messagein.h +++ b/src/net/tmwa/messagein.h @@ -22,26 +22,89 @@ #ifndef NET_TA_MESSAGEIN_H #define NET_TA_MESSAGEIN_H -#include "net/messagein.h" - +#include <cstdint> #include <string> namespace TmwAthena { /** - * Used for parsing an incoming message. + * Used for parsing an incoming message from eAthena. * * \ingroup Network */ - class MessageIn : public Net::MessageIn +class MessageIn { public: MessageIn(const char *data, unsigned int length); + /** + * Returns the message ID. + */ + uint16_t getId() const { return mId; } + + /** + * Returns the message length. + */ + unsigned int getLength() const { return mLength; } + + /** + * Returns the length of unread data. + */ + unsigned int getUnreadLength() const { return mLength - mPos; } + + /** + * Reads an unsigned 8-bit integer from the message. + */ + uint8_t readInt8(); + + /** + * Reads an unsigned 16-bit integer from the message. + */ uint16_t readInt16(); + + /** + * Reads an unsigned 32-bit integer from the message. + */ uint32_t readInt32(); + + /** + * Reads a special 3 byte block used by eAthena, containing x and y + * coordinates and direction. + */ + void readCoordinates(uint16_t &x, uint16_t &y, uint8_t &direction); + + /** + * Reads a special 5 byte block used by eAthena, containing a source + * and destination coordinate pair. + */ + void readCoordinatePair(uint16_t &srcX, uint16_t &srcY, + uint16_t &dstX, uint16_t &dstY); + + /** + * Skips a given number of bytes. + */ + void skip(unsigned int length); + + /** + * Reads a string. If a length is not given (-1), it is assumed + * that the length of the string is stored in a short at the + * start of the string. + */ + std::string readString(int length = -1); + + private: + const char *mData; /**< The message data. */ + unsigned int mLength; /**< The length of the data. */ + unsigned short mId; /**< The message ID. */ + + /** + * Actual position in the packet. From 0 to packet->length. + * A value bigger than packet->length means EOP was reached when + * reading it. + */ + unsigned int mPos; }; -} +} // TmwAthena #endif // NET_TA_MESSAGEIN_H diff --git a/src/net/tmwa/messageout.cpp b/src/net/tmwa/messageout.cpp index 7f09ecce..ae5f6dba 100644 --- a/src/net/tmwa/messageout.cpp +++ b/src/net/tmwa/messageout.cpp @@ -27,15 +27,16 @@ #include <SDL_endian.h> #include <cstring> -#include <string> namespace TmwAthena { MessageOut::MessageOut(uint16_t id): - Net::MessageOut(id) + mDataSize(0), + mPos(0) { mNetwork = TmwAthena::Network::instance(); mData = mNetwork->mOutBuffer + mNetwork->mOutSize; + writeInt16(id); } @@ -44,11 +45,18 @@ void MessageOut::expand(size_t bytes) mNetwork->mOutSize += bytes; } +void MessageOut::writeInt8(uint8_t value) +{ + expand(1); + mData[mPos] = value; + mPos += 1; +} + void MessageOut::writeInt16(uint16_t value) { expand(2); #if SDL_BYTEORDER == SDL_BIG_ENDIAN - uint16_t swap=SDL_Swap16(value); + uint16_t swap = SDL_Swap16(value); memcpy(mData + mPos, &swap, sizeof(uint16_t)); #else memcpy(mData + mPos, &value, sizeof(uint16_t)); @@ -60,7 +68,7 @@ void MessageOut::writeInt32(uint32_t value) { expand(4); #if SDL_BYTEORDER == SDL_BIG_ENDIAN - uint32_t swap=SDL_Swap32(value); + uint32_t swap = SDL_Swap32(value); memcpy(mData + mPos, &swap, sizeof(uint32_t)); #else memcpy(mData + mPos, &value, sizeof(uint32_t)); @@ -68,10 +76,37 @@ void MessageOut::writeInt32(uint32_t value) mPos += 4; } +void MessageOut::writeString(const std::string &string, int length) +{ + int stringLength = string.length(); + if (length < 0) + { + // Write the length at the start if not fixed + writeInt16(stringLength); + length = stringLength; + } + else if (length < stringLength) + { + // Make sure the length of the string is no longer than specified + stringLength = length; + } + expand(length); + + // Write the actual string + memcpy(mData + mPos, string.data(), stringLength); + + // Pad remaining space with zeros + if (length > stringLength) + { + memset(mData + mPos + stringLength, '\0', length - stringLength); + } + mPos += length; +} + void MessageOut::writeCoordinates(uint16_t x, uint16_t y, uint8_t direction) { char *data = mData + mPos; - mNetwork->mOutSize += 3; + expand(3); mPos += 3; uint16_t temp = x; diff --git a/src/net/tmwa/messageout.h b/src/net/tmwa/messageout.h index d30fd1ec..dd2b84cc 100644 --- a/src/net/tmwa/messageout.h +++ b/src/net/tmwa/messageout.h @@ -22,37 +22,77 @@ #ifndef NET_TA_MESSAGEOUT_H #define NET_TA_MESSAGEOUT_H -#include "net/messageout.h" +#include <cstdint> +#include <string> namespace TmwAthena { class Network; /** - * Used for building an outgoing message. + * Used for building an outgoing message to eAthena. * * \ingroup Network */ -class MessageOut : public Net::MessageOut +class MessageOut { public: MessageOut(uint16_t id); + /** + * Writes an unsigned 8-bit integer to the message. + */ + void writeInt8(uint8_t value); + + /** + * Writes an unsigned 16-bit integer to the message. + */ void writeInt16(uint16_t value); + + /** + * Writes an unsigned 32-bit integer to the message. + */ void writeInt32(uint32_t value); /** + * Writes a string. If a fixed length is not given (-1), it is stored + * as a short at the start of the string. + */ + void writeString(const std::string &string, int length = -1); + + /** * Encodes coordinates and direction in 3 bytes. */ void writeCoordinates(uint16_t x, uint16_t y, uint8_t direction); + /** + * Returns the content of the message. + */ + char *getData() const { return mData; } + + /** + * Returns the length of the data. + */ + unsigned int getDataSize() const { return mDataSize; } + private: + /** + * Expand the packet data to be able to hold more data. + * + * NOTE: For performance enhancements this method could allocate extra + * memory in advance instead of expanding size every time more data is + * added. + */ void expand(size_t size); Network *mNetwork; + + char *mData; /**< Data building up. */ + unsigned int mDataSize; /**< Size of data. */ + unsigned int mPos; /**< Position in the data. */ }; -} +} // namespace TmwAthena #endif // NET_TA_MESSAGEOUT_H diff --git a/src/net/tmwa/network.cpp b/src/net/tmwa/network.cpp index 5f5d4631..3a02deba 100644 --- a/src/net/tmwa/network.cpp +++ b/src/net/tmwa/network.cpp @@ -24,8 +24,8 @@ #include "log.h" #include "net/messagehandler.h" -#include "net/messagein.h" +#include "net/tmwa/messagein.h" #include "net/tmwa/protocol.h" #include "utils/gettext.h" diff --git a/src/net/tmwa/npchandler.cpp b/src/net/tmwa/npchandler.cpp index 71f9ba2a..2b0a5b0a 100644 --- a/src/net/tmwa/npchandler.cpp +++ b/src/net/tmwa/npchandler.cpp @@ -25,11 +25,11 @@ #include "event.h" #include "localplayer.h" -#include "net/messagein.h" -#include "net/messageout.h" #include "net/net.h" #include "net/npchandler.h" +#include "net/tmwa/messagein.h" +#include "net/tmwa/messageout.h" #include "net/tmwa/protocol.h" #include "utils/stringutils.h" @@ -68,7 +68,7 @@ NpcHandler::NpcHandler() npcHandler = this; } -void NpcHandler::handleMessage(Net::MessageIn &msg) +void NpcHandler::handleMessage(MessageIn &msg) { if (msg.getId() == SMSG_NPC_CHOICE || msg.getId() == SMSG_NPC_MESSAGE) { diff --git a/src/net/tmwa/npchandler.h b/src/net/tmwa/npchandler.h index 1c3d99c3..71486a40 100644 --- a/src/net/tmwa/npchandler.h +++ b/src/net/tmwa/npchandler.h @@ -37,7 +37,7 @@ class NpcHandler : public MessageHandler, public Net::NpcHandler public: NpcHandler(); - void handleMessage(Net::MessageIn &msg); + void handleMessage(MessageIn &msg); void startShopping(int beingId); diff --git a/src/net/tmwa/partyhandler.cpp b/src/net/tmwa/partyhandler.cpp index 314136e6..4753dac1 100644 --- a/src/net/tmwa/partyhandler.cpp +++ b/src/net/tmwa/partyhandler.cpp @@ -28,9 +28,8 @@ #include "gui/socialwindow.h" -#include "net/messagein.h" -#include "net/messageout.h" - +#include "net/tmwa/messagein.h" +#include "net/tmwa/messageout.h" #include "net/tmwa/protocol.h" #include "net/tmwa/gui/partytab.h" @@ -74,7 +73,7 @@ PartyHandler::~PartyHandler() partyTab = 0; } -void PartyHandler::handleMessage(Net::MessageIn &msg) +void PartyHandler::handleMessage(MessageIn &msg) { switch (msg.getId()) { diff --git a/src/net/tmwa/partyhandler.h b/src/net/tmwa/partyhandler.h index bf567bb6..9a3570a8 100644 --- a/src/net/tmwa/partyhandler.h +++ b/src/net/tmwa/partyhandler.h @@ -38,7 +38,7 @@ class PartyHandler : public MessageHandler, public Net::PartyHandler ~PartyHandler(); - void handleMessage(Net::MessageIn &msg); + void handleMessage(MessageIn &msg); void create(const std::string &name = ""); diff --git a/src/net/tmwa/playerhandler.cpp b/src/net/tmwa/playerhandler.cpp index a3651a2f..c598c5f9 100644 --- a/src/net/tmwa/playerhandler.cpp +++ b/src/net/tmwa/playerhandler.cpp @@ -38,9 +38,8 @@ #include "gui/statuswindow.h" #include "gui/viewport.h" -#include "net/messagein.h" -#include "net/messageout.h" - +#include "net/tmwa/messagein.h" +#include "net/tmwa/messageout.h" #include "net/tmwa/protocol.h" #include "utils/stringutils.h" @@ -159,7 +158,7 @@ PlayerHandler::PlayerHandler() playerHandler = this; } -void PlayerHandler::handleMessage(Net::MessageIn &msg) +void PlayerHandler::handleMessage(MessageIn &msg) { if (!local_player) return; diff --git a/src/net/tmwa/playerhandler.h b/src/net/tmwa/playerhandler.h index 7e31366b..2c4b6194 100644 --- a/src/net/tmwa/playerhandler.h +++ b/src/net/tmwa/playerhandler.h @@ -34,7 +34,7 @@ class PlayerHandler : public MessageHandler, public Net::PlayerHandler public: PlayerHandler(); - void handleMessage(Net::MessageIn &msg); + void handleMessage(MessageIn &msg); void attack(int id); void emote(int emoteId); diff --git a/src/net/tmwa/specialhandler.cpp b/src/net/tmwa/specialhandler.cpp index b814cd41..7de0aaea 100644 --- a/src/net/tmwa/specialhandler.cpp +++ b/src/net/tmwa/specialhandler.cpp @@ -27,9 +27,8 @@ #include "gui/skilldialog.h" -#include "net/messagein.h" -#include "net/messageout.h" - +#include "net/tmwa/messagein.h" +#include "net/tmwa/messageout.h" #include "net/tmwa/protocol.h" #include "utils/gettext.h" @@ -82,7 +81,7 @@ SpecialHandler::SpecialHandler() specialHandler = this; } -void SpecialHandler::handleMessage(Net::MessageIn &msg) +void SpecialHandler::handleMessage(MessageIn &msg) { int skillCount; int skillId; diff --git a/src/net/tmwa/specialhandler.h b/src/net/tmwa/specialhandler.h index 40223056..bb772ff1 100644 --- a/src/net/tmwa/specialhandler.h +++ b/src/net/tmwa/specialhandler.h @@ -34,7 +34,7 @@ class SpecialHandler : public MessageHandler, public Net::SpecialHandler public: SpecialHandler(); - void handleMessage(Net::MessageIn &msg); + void handleMessage(MessageIn &msg); void use(int id); diff --git a/src/net/tmwa/tradehandler.cpp b/src/net/tmwa/tradehandler.cpp index 66772468..40e37594 100644 --- a/src/net/tmwa/tradehandler.cpp +++ b/src/net/tmwa/tradehandler.cpp @@ -32,9 +32,9 @@ #include "gui/tradewindow.h" #include "net/inventoryhandler.h" -#include "net/messagein.h" -#include "net/messageout.h" +#include "net/tmwa/messagein.h" +#include "net/tmwa/messageout.h" #include "net/tmwa/protocol.h" #include "resources/iteminfo.h" @@ -81,7 +81,7 @@ TradeHandler::TradeHandler() } -void TradeHandler::handleMessage(Net::MessageIn &msg) +void TradeHandler::handleMessage(MessageIn &msg) { switch (msg.getId()) { diff --git a/src/net/tmwa/tradehandler.h b/src/net/tmwa/tradehandler.h index 443d763a..60ee4444 100644 --- a/src/net/tmwa/tradehandler.h +++ b/src/net/tmwa/tradehandler.h @@ -34,7 +34,7 @@ class TradeHandler : public MessageHandler, public Net::TradeHandler public: TradeHandler(); - void handleMessage(Net::MessageIn &msg); + void handleMessage(MessageIn &msg); void request(Being *being); diff --git a/src/properties.h b/src/properties.h index b6ef5d80..59318b80 100644 --- a/src/properties.h +++ b/src/properties.h @@ -42,8 +42,8 @@ class Properties * @return the value of the given property or the given default when it * doesn't exist. */ - const std::string getProperty(const std::string &name, - const std::string &def = "") const + std::string getProperty(const std::string &name, + const std::string &def = "") const { PropertyMap::const_iterator i = mProperties.find(name); return (i != mProperties.end()) ? i->second : def; diff --git a/src/resources/beinginfo.cpp b/src/resources/beinginfo.cpp index 8683e7bc..5a277770 100644 --- a/src/resources/beinginfo.cpp +++ b/src/resources/beinginfo.cpp @@ -84,7 +84,7 @@ void BeingInfo::addSound(SoundEvent event, const std::string &filename) const std::string &BeingInfo::getSound(SoundEvent event) const { - static std::string empty(""); + static const std::string empty; SoundEvents::const_iterator i = mSounds.find(event); return (i == mSounds.end()) ? empty : diff --git a/src/resources/iteminfo.cpp b/src/resources/iteminfo.cpp index 22be274a..3583bb27 100644 --- a/src/resources/iteminfo.cpp +++ b/src/resources/iteminfo.cpp @@ -33,7 +33,7 @@ const std::string &ItemInfo::getSprite(Gender gender) const } else { - static const std::string empty = ""; + static const std::string empty; std::map<int, std::string>::const_iterator i = mAnimationFiles.find(gender); diff --git a/src/resources/soundeffect.cpp b/src/resources/soundeffect.cpp index 91ee1fde..d1b0227b 100644 --- a/src/resources/soundeffect.cpp +++ b/src/resources/soundeffect.cpp @@ -44,9 +44,9 @@ Resource *SoundEffect::load(SDL_RWops *rw) } } -bool SoundEffect::play(int loops, int volume) +bool SoundEffect::play(int loops, int volume, int channel) { Mix_VolumeChunk(mChunk, volume); - return Mix_PlayChannel(-1, mChunk, loops) != -1; + return Mix_PlayChannel(channel, mChunk, loops) != -1; } diff --git a/src/resources/soundeffect.h b/src/resources/soundeffect.h index dee8f551..decc60a0 100644 --- a/src/resources/soundeffect.h +++ b/src/resources/soundeffect.h @@ -53,11 +53,12 @@ class SoundEffect : public Resource * * @param loops Number of times to repeat the playback. * @param volume Sample playback volume. + * @param channel Sample playback channel. * * @return <code>true</code> if the playback started properly * <code>false</code> otherwise. */ - virtual bool play(int loops, int volume); + bool play(int loops, int volume, int channel = -1); protected: SoundEffect(Mix_Chunk *soundEffect): mChunk(soundEffect) {} diff --git a/src/resources/specialdb.cpp b/src/resources/specialdb.cpp index 5dac2e6c..426a1143 100644 --- a/src/resources/specialdb.cpp +++ b/src/resources/specialdb.cpp @@ -34,14 +34,11 @@ namespace SpecialInfo::TargetMode SpecialDB::targetModeFromString(const std::string& str) { - if (str=="self") return SpecialInfo::TARGET_SELF; - else if (str=="friend") return SpecialInfo::TARGET_FRIEND; - else if (str=="enemy") return SpecialInfo::TARGET_ENEMY; - else if (str=="being") return SpecialInfo::TARGET_BEING; + if (str=="being") return SpecialInfo::TARGET_BEING; else if (str=="point") return SpecialInfo::TARGET_POINT; logger->log("SpecialDB: Warning, unknown target mode \"%s\"", str.c_str() ); - return SpecialInfo::TARGET_SELF; + return SpecialInfo::TARGET_BEING; } void SpecialDB::load() @@ -80,13 +77,9 @@ void SpecialDB::load() info->name = XML::getProperty(special, "name", ""); info->icon = XML::getProperty(special, "icon", ""); - info->isActive = XML::getBoolProperty(special, "active", false); - info->targetMode = targetModeFromString(XML::getProperty(special, "target", "self")); + info->targetMode = targetModeFromString(XML::getProperty(special, "target", "being")); - info->level = XML::getProperty(special, "level", -1); - info->hasLevel = info->level > -1; - - info->hasRechargeBar = XML::getBoolProperty(special, "recharge", false); + info->rechargeable = XML::getBoolProperty(special, "rechargeable", true); info->rechargeNeeded = 0; info->rechargeCurrent = 0; diff --git a/src/resources/specialdb.h b/src/resources/specialdb.h index 5c105ed5..dc1c26b6 100644 --- a/src/resources/specialdb.h +++ b/src/resources/specialdb.h @@ -28,9 +28,6 @@ struct SpecialInfo { enum TargetMode { - TARGET_SELF, // no target selection - TARGET_FRIEND, // target friendly being - TARGET_ENEMY, // target hostile being TARGET_BEING, // target any being TARGET_POINT // target map location }; @@ -39,13 +36,9 @@ struct SpecialInfo std::string name; // displayed name of special std::string icon; // filename of graphical icon - bool isActive; // true when the special can be used TargetMode targetMode; // target mode - bool hasLevel; // true when the special has levels - int level; // level of special when applicable - - bool hasRechargeBar; // true when the special has a recharge bar + bool rechargeable; // true when the special has a recharge bar int rechargeNeeded; // maximum recharge when applicable int rechargeCurrent; // current recharge when applicable }; diff --git a/src/resources/userpalette.cpp b/src/resources/userpalette.cpp index 12ea3f8d..073f5b03 100644 --- a/src/resources/userpalette.cpp +++ b/src/resources/userpalette.cpp @@ -32,7 +32,7 @@ #include <math.h> -const std::string ColorTypeNames[] = { +static const std::string ColorTypeNames[] = { "ColorBeing", "ColorPlayer", "ColorSelf", diff --git a/src/sound.cpp b/src/sound.cpp index e8348a40..1af1f136 100644 --- a/src/sound.cpp +++ b/src/sound.cpp @@ -31,6 +31,10 @@ #include "resources/resourcemanager.h" #include "resources/soundeffect.h" +enum { + CHANNEL_NOTIFICATIONS = 0 +}; + /** * This will be set to true, when a music can be freed after a fade out * Currently used by fadeOutCallBack() @@ -49,6 +53,7 @@ static void fadeOutCallBack() Sound::Sound(): mInstalled(false), mSfxVolume(100), + mNotificationsVolume(100), mMusicVolume(60), mMusic(NULL) { @@ -90,8 +95,10 @@ void Sound::init() } Mix_AllocateChannels(16); + Mix_ReserveChannels(1); // reserve one channel for notification sounds Mix_VolumeMusic(mMusicVolume); Mix_Volume(-1, mSfxVolume); + Mix_Volume(CHANNEL_NOTIFICATIONS, mNotificationsVolume); info(); @@ -154,7 +161,18 @@ void Sound::setSfxVolume(int volume) mSfxVolume = volume; if (mInstalled) + { Mix_Volume(-1, mSfxVolume); + Mix_Volume(CHANNEL_NOTIFICATIONS, mNotificationsVolume); + } +} + +void Sound::setNotificationsVolume(int volume) +{ + mNotificationsVolume = volume; + + if (mInstalled) + Mix_Volume(CHANNEL_NOTIFICATIONS, mNotificationsVolume); } static Music *loadMusic(const std::string &fileName) @@ -281,6 +299,17 @@ void Sound::playSfx(const std::string &path, int x, int y) } } +void Sound::playNotification(const std::string &path) +{ + const std::string fullPath = paths.getValue("sfx", "sfx/") + path; + + ResourceManager *resman = ResourceManager::getInstance(); + if (SoundEffect *sample = resman->getSoundEffect(fullPath)) + { + sample->play(0, 128, CHANNEL_NOTIFICATIONS); + } +} + void Sound::close() { if (!mInstalled) diff --git a/src/sound.h b/src/sound.h index dd368f84..180bca62 100644 --- a/src/sound.h +++ b/src/sound.h @@ -92,6 +92,7 @@ class Sound void setMusicVolume(int volume); void setSfxVolume(int volume); + void setNotificationsVolume(int volume); /** * Plays a sound at the specified location. @@ -103,6 +104,13 @@ class Sound void playSfx(const std::string &path, int x = 0, int y = 0); /** + * Plays a sound on the notification channel. + * + * @param path The resource path to the sound file. + */ + void playNotification(const std::string &path); + + /** * The sound logic. * Currently used to check whether the music file can be freed after * a fade out, and whether new music has to be played. @@ -125,6 +133,7 @@ class Sound bool mInstalled; int mSfxVolume; + int mNotificationsVolume; int mMusicVolume; std::string mCurrentMusicFile; diff --git a/src/utils/stringutils.cpp b/src/utils/stringutils.cpp index 5a51ef66..4f27d41b 100644 --- a/src/utils/stringutils.cpp +++ b/src/utils/stringutils.cpp @@ -157,8 +157,8 @@ bool isWordSeparator(char chr) return (chr == ' ' || chr == ',' || chr == '.' || chr == '"'); } -const std::string findSameSubstring(const std::string &str1, - const std::string &str2) +std::string findSameSubstring(const std::string &str1, + const std::string &str2) { int minLength = str1.length() > str2.length() ? str2.length() : str1.length(); for (int f = 0; f < minLength; f ++) @@ -171,9 +171,9 @@ const std::string findSameSubstring(const std::string &str1, return str1.substr(0, minLength); } -const char* getSafeUtf8String(std::string text) +const char *getSafeUtf8String(const std::string &text) { - char* buf = new char[text.size() + UTF8_MAX_SIZE]; + char *buf = new char[text.size() + UTF8_MAX_SIZE]; memcpy(buf, text.c_str(), text.size()); memset(buf + text.size(), 0, UTF8_MAX_SIZE); return buf; diff --git a/src/utils/stringutils.h b/src/utils/stringutils.h index 74365491..b83bc580 100644 --- a/src/utils/stringutils.h +++ b/src/utils/stringutils.h @@ -125,10 +125,10 @@ int compareStrI(const std::string &a, const std::string &b); */ bool isWordSeparator(char chr); -const std::string findSameSubstring(const std::string &str1, - const std::string &str2); +std::string findSameSubstring(const std::string &str1, + const std::string &str2); -const char* getSafeUtf8String(std::string text); +const char *getSafeUtf8String(const std::string &text); /** * Returns a bool value depending on the given string value. |