diff options
38 files changed, 305 insertions, 42 deletions
diff --git a/data/graphics/gui/CMakeLists.txt b/data/graphics/gui/CMakeLists.txt index 92a1e3ef..cc257eee 100644 --- a/data/graphics/gui/CMakeLists.txt +++ b/data/graphics/gui/CMakeLists.txt @@ -1,6 +1,17 @@ SET (FILES bubble.png button.png + button-icon-confirm.png + button-icon-cancel.png + button-icon-equipment.png + button-icon-inventory.png + button-icon-setup.png + button-icon-shortcut.png + button-icon-skills.png + button-icon-smilies.png + button-icon-social.png + button-icon-specials.png + button-icon-status.png button_disabled.png buttonhi.png buttonpress.png @@ -30,6 +41,8 @@ SET (FILES speechbubble.xml sticky_button.png tab.png + tab_arrows_left.png + tab_arrows_right.png tab_hilight.png tabselected.png unknown-item.png diff --git a/data/graphics/gui/button-icon-cancel.png b/data/graphics/gui/button-icon-cancel.png Binary files differnew file mode 100644 index 00000000..f85a2c4e --- /dev/null +++ b/data/graphics/gui/button-icon-cancel.png diff --git a/data/graphics/gui/button-icon-confirm.png b/data/graphics/gui/button-icon-confirm.png Binary files differnew file mode 100644 index 00000000..c674662b --- /dev/null +++ b/data/graphics/gui/button-icon-confirm.png diff --git a/data/graphics/gui/button-icon-equipment.png b/data/graphics/gui/button-icon-equipment.png Binary files differnew file mode 100644 index 00000000..4f40f3ad --- /dev/null +++ b/data/graphics/gui/button-icon-equipment.png diff --git a/data/graphics/gui/button-icon-inventory.png b/data/graphics/gui/button-icon-inventory.png Binary files differnew file mode 100644 index 00000000..c0fe5bf7 --- /dev/null +++ b/data/graphics/gui/button-icon-inventory.png diff --git a/data/graphics/gui/button-icon-setup.png b/data/graphics/gui/button-icon-setup.png Binary files differnew file mode 100644 index 00000000..8e028358 --- /dev/null +++ b/data/graphics/gui/button-icon-setup.png diff --git a/data/graphics/gui/button-icon-shortcut.png b/data/graphics/gui/button-icon-shortcut.png Binary files differnew file mode 100644 index 00000000..10b97577 --- /dev/null +++ b/data/graphics/gui/button-icon-shortcut.png diff --git a/data/graphics/gui/button-icon-skills.png b/data/graphics/gui/button-icon-skills.png Binary files differnew file mode 100644 index 00000000..3d68f42b --- /dev/null +++ b/data/graphics/gui/button-icon-skills.png diff --git a/data/graphics/gui/button-icon-smilies.png b/data/graphics/gui/button-icon-smilies.png Binary files differnew file mode 100644 index 00000000..dd2a00c4 --- /dev/null +++ b/data/graphics/gui/button-icon-smilies.png diff --git a/data/graphics/gui/button-icon-social.png b/data/graphics/gui/button-icon-social.png Binary files differnew file mode 100644 index 00000000..4c6b49f1 --- /dev/null +++ b/data/graphics/gui/button-icon-social.png diff --git a/data/graphics/gui/button-icon-specials.png b/data/graphics/gui/button-icon-specials.png Binary files differnew file mode 100644 index 00000000..31c66e81 --- /dev/null +++ b/data/graphics/gui/button-icon-specials.png diff --git a/data/graphics/gui/button-icon-status.png b/data/graphics/gui/button-icon-status.png Binary files differnew file mode 100644 index 00000000..96c54d15 --- /dev/null +++ b/data/graphics/gui/button-icon-status.png diff --git a/data/graphics/gui/tab_arrows_left.png b/data/graphics/gui/tab_arrows_left.png Binary files differnew file mode 100644 index 00000000..c14590d8 --- /dev/null +++ b/data/graphics/gui/tab_arrows_left.png diff --git a/data/graphics/gui/tab_arrows_right.png b/data/graphics/gui/tab_arrows_right.png Binary files differnew file mode 100644 index 00000000..8309c68e --- /dev/null +++ b/data/graphics/gui/tab_arrows_right.png diff --git a/src/being.h b/src/being.h index a2a78bfd..b702cf1a 100644 --- a/src/being.h +++ b/src/being.h @@ -316,7 +316,7 @@ class Being : public ActorSprite, public EventListener * in ticks per tile for eAthena, * in tiles per second for Manaserv (0.1 precision). */ - void setMoveSpeed(const Vector &speed); + virtual void setMoveSpeed(const Vector &speed); /** * Gets the original Move speed. diff --git a/src/game.cpp b/src/game.cpp index 5fb98e6c..813253ce 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -64,7 +64,6 @@ #include "gui/textdialog.h" #include "gui/trade.h" #include "gui/viewport.h" -#include "gui/windowmenu.h" #include "gui/widgets/chattab.h" #include "gui/widgets/emoteshortcutcontainer.h" @@ -24,8 +24,9 @@ #include <string> +#include "gui/windowmenu.h" + class Map; -class WindowMenu; /** * The main class responsible for running the game. The game starts after you @@ -73,6 +74,12 @@ class Game int getCurrentTileWidth() const; int getCurrentTileHeight() const; + /** + * Update the key shortcuts in the window menu. + */ + void updateWindowMenuCaptions() + { mWindowMenu->updatePopUpCaptions(); } + private: int mLastTarget; bool mDisconnected; diff --git a/src/gui/quitdialog.cpp b/src/gui/quitdialog.cpp index 6ecc62a6..3da07206 100644 --- a/src/gui/quitdialog.cpp +++ b/src/gui/quitdialog.cpp @@ -44,7 +44,9 @@ QuitDialog::QuitDialog(QuitDialog** pointerToMe): mSwitchAccountServer = new RadioButton(_("Switch server"), "quitdialog"); mSwitchCharacter = new RadioButton(_("Switch character"), "quitdialog"); mOkButton = new Button(_("OK"), "ok", this); + mOkButton->setButtonIcon("button-icon-confirm.png"); mCancelButton = new Button(_("Cancel"), "cancel", this); + mCancelButton->setButtonIcon("button-icon-cancel.png"); addKeyListener(this); diff --git a/src/gui/quitdialog.h b/src/gui/quitdialog.h index 65a325b8..21fe2f8a 100644 --- a/src/gui/quitdialog.h +++ b/src/gui/quitdialog.h @@ -29,6 +29,8 @@ #include <vector> +class Button; + /** * The quit dialog. * @@ -62,8 +64,8 @@ class QuitDialog : public Window, public gcn::ActionListener, gcn::RadioButton *mForceQuit; gcn::RadioButton *mSwitchAccountServer; gcn::RadioButton *mSwitchCharacter; - gcn::Button *mOkButton; - gcn::Button *mCancelButton; + Button *mOkButton; + Button *mCancelButton; QuitDialog **mMyPointer; }; diff --git a/src/gui/setup_keyboard.cpp b/src/gui/setup_keyboard.cpp index d3ee3937..b8ce3e89 100644 --- a/src/gui/setup_keyboard.cpp +++ b/src/gui/setup_keyboard.cpp @@ -22,6 +22,7 @@ #include "gui/setup_keyboard.h" +#include "game.h" #include "keyboardconfig.h" #include "gui/gui.h" @@ -190,6 +191,8 @@ void Setup_Keyboard::refreshAssignedKey(int index) } mKeyListModel->setElementAt(index, caption); + if (Game *game = Game::instance()) + game->updateWindowMenuCaptions(); } void Setup_Keyboard::newKeyCallback(int index) diff --git a/src/gui/specialswindow.h b/src/gui/specialswindow.h index dedeeffc..b440ce13 100644 --- a/src/gui/specialswindow.h +++ b/src/gui/specialswindow.h @@ -51,6 +51,9 @@ class SpecialsWindow : public Window, public gcn::ActionListener { void draw(gcn::Graphics *graphics); + bool hasSpecials() + { return !mEntries.empty(); } + private: // (re)constructs the list of specials void rebuild(const std::map<int, Special> &specialData); diff --git a/src/gui/widgets/button.cpp b/src/gui/widgets/button.cpp index f072ef61..61ec28a2 100644 --- a/src/gui/widgets/button.cpp +++ b/src/gui/widgets/button.cpp @@ -25,6 +25,7 @@ #include "graphics.h" #include "gui/palette.h" +#include "gui/textpopup.h" #include "resources/image.h" #include "resources/theme.h" @@ -36,7 +37,8 @@ int Button::mInstances = 0; float Button::mAlpha = 1.0; -ImageRect *Button::mButton; +ImageRect* Button::mButton; +TextPopup* Button::mTextPopup = 0; enum{ BUTTON_STANDARD, // 0 @@ -81,23 +83,26 @@ Button::Button(const std::string &caption, const std::string &actionEventId, adjustSize(); } -void Button::setButtonIcon(const std::string& iconFile, int frameHeight, - int frameWidth) +bool Button::setButtonIcon(const std::string& iconFile) { // We clean up possible older references. if (mButtonIcon) removeButtonIcon(); // If nothing relevant was set, we can quit now. - if (iconFile.empty() || !frameWidth || !frameHeight) - return; + if (iconFile.empty()) + return false; // Load the icon frames. Image *btnIcons = Theme::getImageFromTheme(iconFile); if (!btnIcons) - return; + return false; - if (btnIcons->getWidth() > 0 && btnIcons->getHeight() > 0) + // Compute the sub images size. + const int frameWidth = btnIcons->getWidth() / 4; + const int frameHeight = btnIcons->getHeight(); + + if (frameWidth > 0 && frameHeight > 0) { mButtonIcon = new Image*[BUTTON_COUNT]; for (int mode = 0; mode < BUTTON_COUNT; ++mode) @@ -110,6 +115,7 @@ void Button::setButtonIcon(const std::string& iconFile, int frameHeight, } btnIcons->decRef(); + return (mButtonIcon); } void Button::removeButtonIcon() @@ -159,6 +165,10 @@ void Button::init() btn[mode]->decRef(); } updateAlpha(); + + // Load the popup + if (!mTextPopup) + mTextPopup = new TextPopup(); } mInstances++; } @@ -175,6 +185,9 @@ Button::~Button() dtor<Image*>()); } delete[] mButton; + + // Remove the popup + delete mTextPopup; } removeButtonIcon(); } @@ -301,3 +314,50 @@ void Button::setCaption(const std::string& caption) mCaption = caption; adjustSize(); } + +void Button::logic() +{ + gcn::Button::logic(); + mTextPopup->logic(); +} + +void Button::mouseMoved(gcn::MouseEvent &event) +{ + gcn::Button::mouseMoved(event); + mTextPopup->mouseMoved(event); + + int x = event.getX(); + int y = event.getY(); + + if (event.getSource() == this && !mPopupText.empty()) + { + if (mParent) + { + x += mParent->getX(); + y += mParent->getY(); + } + + mTextPopup->show(x + getX(), y + getY(), mPopupText); + } + else + { + mTextPopup->setVisible(false); + } +} + +void Button::mouseExited(gcn::MouseEvent &event) +{ + gcn::Button::mouseExited(event); + mTextPopup->mouseExited(event); + + mTextPopup->setVisible(false); +} + +void Button::setButtonPopupText(const std::string& text) +{ + mPopupText = text; + if (!mPopupText.empty()) + mTextPopup->show(getX(), getY(), mPopupText); + else + mTextPopup->setVisible(false); +} diff --git a/src/gui/widgets/button.h b/src/gui/widgets/button.h index 6d8f773c..7463d2ad 100644 --- a/src/gui/widgets/button.h +++ b/src/gui/widgets/button.h @@ -26,6 +26,7 @@ class ImageRect; class Image; +class TextPopup; /** * Button widget. Same as the Guichan button but with custom look. @@ -71,8 +72,18 @@ class Button : public gcn::Button * Standard, Highlighted, Pressed, and Disabled. * If the image is too short, the missing states won't be loaded. */ - void setButtonIcon(const std::string& iconFile = std::string(), - int frameHeight = 0, int frameWidth = 0); + bool setButtonIcon(const std::string& iconFile = std::string()); + + /** + * Set the button popup text when hovering it for a few seconds. + * + * @note: An empty text will disable the popup. + */ + void setButtonPopupText(const std::string& text = std::string()); + + void logic(); + void mouseMoved(gcn::MouseEvent &event); + void mouseExited(gcn::MouseEvent &event); private: void init(); @@ -84,6 +95,9 @@ class Button : public gcn::Button static float mAlpha; Image** mButtonIcon; /**< Button Icons graphics */ + + static TextPopup* mTextPopup; /**< The buttons popup */ + std::string mPopupText; /**< the current button text */ }; #endif diff --git a/src/gui/widgets/tabbedarea.cpp b/src/gui/widgets/tabbedarea.cpp index 412d3ddc..9b51b311 100644 --- a/src/gui/widgets/tabbedarea.cpp +++ b/src/gui/widgets/tabbedarea.cpp @@ -33,8 +33,12 @@ TabbedArea::TabbedArea() : gcn::TabbedArea(), mWidgetContainer->setOpaque(false); addWidgetListener(this); - mArrowButton[0] = new Button("<", "shift_left", this); - mArrowButton[1] = new Button(">", "shift_right", this); + mArrowButton[0] = new Button("", "shift_left", this); + mArrowButton[1] = new Button("", "shift_right", this); + if (!mArrowButton[0]->setButtonIcon("tab_arrows_left.png")) + mArrowButton[0]->setCaption("<"); + if (!mArrowButton[1]->setButtonIcon("tab_arrows_right.png")) + mArrowButton[1]->setCaption(">"); add(mArrowButton[0]); add(mArrowButton[1]); diff --git a/src/gui/widgets/tabbedarea.h b/src/gui/widgets/tabbedarea.h index d364eac5..cb29a756 100644 --- a/src/gui/widgets/tabbedarea.h +++ b/src/gui/widgets/tabbedarea.h @@ -117,7 +117,7 @@ class TabbedArea : public gcn::TabbedArea, public gcn::WidgetListener typedef std::vector< std::pair<gcn::Tab*, gcn::Widget*> > TabContainer; /** The tab arrows */ - gcn::Button *mArrowButton[2]; + Button *mArrowButton[2]; /** Check whether the arrow should be clickable */ void updateArrowEnableState(); diff --git a/src/gui/windowmenu.cpp b/src/gui/windowmenu.cpp index 542ab4a0..2cac55b5 100644 --- a/src/gui/windowmenu.cpp +++ b/src/gui/windowmenu.cpp @@ -50,20 +50,27 @@ WindowMenu::WindowMenu(): { int x = 0, h = 0; - addButton(":-)", x, h); - addButton(N_("Status"), x, h); - addButton(N_("Equipment"), x, h); - addButton(N_("Inventory"), x, h); + addButton(":-)", x, h, "button-icon-smilies.png"); + addButton(N_("Status"), x, h, "button-icon-status.png", + KeyboardConfig::KEY_WINDOW_STATUS); + addButton(N_("Inventory"), x, h, "button-icon-inventory.png", + KeyboardConfig::KEY_WINDOW_INVENTORY); + addButton(N_("Equipment"), x, h, "button-icon-equipment.png", + KeyboardConfig::KEY_WINDOW_EQUIPMENT); if (skillDialog->hasSkills()) - addButton(N_("Skills"), x, h); + addButton(N_("Skills"), x, h, "button-icon-skills.png", + KeyboardConfig::KEY_WINDOW_SKILL); - // if (specialsWindow->hasSpecials()) - addButton(N_("Specials"), x, h); + if (specialsWindow->hasSpecials()) + addButton(N_("Specials"), x, h, "button-icon-specials.png"); - addButton(N_("Social"), x, h); - addButton(N_("Shortcut"), x, h); - addButton(N_("Setup"), x, h); + addButton(N_("Social"), x, h, "button-icon-social.png", + KeyboardConfig::KEY_WINDOW_SOCIAL); + addButton(N_("Shortcuts"), x, h, "button-icon-shortcut.png", + KeyboardConfig::KEY_WINDOW_SHORTCUT); + addButton(N_("Setup"), x, h, "button-icon-setup.png", + KeyboardConfig::KEY_WINDOW_SETUP); setDimension(gcn::Rectangle(graphics->getWidth() - x - 3, 3, x - 3, h)); @@ -124,7 +131,7 @@ void WindowMenu::action(const gcn::ActionEvent &event) { window = socialWindow; } - else if (event.getId() == "Shortcut") + else if (event.getId() == "Shortcuts") { window = itemShortcutWindow; } @@ -156,11 +163,84 @@ void WindowMenu::valueChanged(const gcn::SelectionEvent &event) } } -void WindowMenu::addButton(const char* text, int &x, int &h) +static std::string createShortcutCaption(const std::string& text, + KeyboardConfig::KeyAction key) { - gcn::Button *btn = new Button(gettext(text), text, this); + std::string caption = gettext(text.c_str()); + if (key != KeyboardConfig::KEY_NO_VALUE) + { + caption += " ("; + caption += SDL_GetKeyName((SDLKey) keyboard.getKeyValue(key)); + caption += ")"; + } + return caption; +} + +void WindowMenu::addButton(const std::string& text, int &x, int &h, + const std::string& iconPath, + KeyboardConfig::KeyAction key) +{ + Button *btn = new Button("", text, this); + if (!iconPath.empty() && btn->setButtonIcon(iconPath)) + { + // When in image button mode, we have room to show + // the keyboard shortcut. + btn->setButtonPopupText(createShortcutCaption(text, key)); + } + else + { + btn->setCaption(gettext(text.c_str())); + } + btn->setPosition(x, 0); add(btn); x += btn->getWidth() + 3; - h = btn->getHeight(); + h = std::max(h, btn->getHeight()); +} + +void WindowMenu::updatePopUpCaptions() +{ + for (WidgetList::iterator it = mWidgets.begin(); it != mWidgets.end(); ++it) + { + Button *button = dynamic_cast<Button*> (*it); + if (button) + { + std::string eventId = button->getActionEventId(); + if (eventId == "Status") + { + button->setButtonPopupText(createShortcutCaption("Status", + KeyboardConfig::KEY_WINDOW_STATUS)); + } + else if (eventId == "Equipment") + { + button->setButtonPopupText(createShortcutCaption("Equipment", + KeyboardConfig::KEY_WINDOW_EQUIPMENT)); + } + else if (eventId == "Inventory") + { + button->setButtonPopupText(createShortcutCaption("Inventory", + KeyboardConfig::KEY_WINDOW_INVENTORY)); + } + else if (eventId == "Skills") + { + button->setButtonPopupText(createShortcutCaption("Skills", + KeyboardConfig::KEY_WINDOW_SKILL)); + } + else if (eventId == "Social") + { + button->setButtonPopupText(createShortcutCaption("Social", + KeyboardConfig::KEY_WINDOW_SOCIAL)); + } + else if (eventId == "Shortcuts") + { + button->setButtonPopupText(createShortcutCaption("Shortcuts", + KeyboardConfig::KEY_WINDOW_SHORTCUT)); + } + else if (eventId == "Setup") + { + button->setButtonPopupText(createShortcutCaption("Setup", + KeyboardConfig::KEY_WINDOW_SETUP)); + } + } + } } diff --git a/src/gui/windowmenu.h b/src/gui/windowmenu.h index 2bb3e764..962abaf5 100644 --- a/src/gui/windowmenu.h +++ b/src/gui/windowmenu.h @@ -22,6 +22,8 @@ #ifndef WINDOWMENU_H #define WINDOWMENU_H +#include "keyboardconfig.h" + #include "gui/widgets/container.h" #include <guichan/actionlistener.hpp> @@ -47,8 +49,16 @@ class WindowMenu : public Container, void valueChanged(const gcn::SelectionEvent &event); + /** + * Update the pop-up captions with new key shortcuts. + */ + void updatePopUpCaptions(); + private: - inline void addButton(const char* text, int &x, int &h); + inline void addButton(const std::string& text, int &x, int &h, + const std::string& iconPath = std::string(), + KeyboardConfig::KeyAction key = + KeyboardConfig::KEY_NO_VALUE); EmotePopup *mEmotePopup; }; diff --git a/src/localplayer.cpp b/src/localplayer.cpp index f941dd5f..3c1cc259 100644 --- a/src/localplayer.cpp +++ b/src/localplayer.cpp @@ -58,11 +58,6 @@ #include <cassert> -// This is the minimal delay between to permitted -// setDestination() calls using the keyboard. -// TODO: This can fine tuned later on when running is added... -const short walkingKeyboardDelay = 1000; - #define AWAY_LIMIT_TIMER 60 LocalPlayer *player_node = NULL; @@ -79,6 +74,7 @@ LocalPlayer::LocalPlayer(int id, int subtype): mWalkingDir(0), mPathSetByMouse(false), mLocalWalkTime(-1), + mKeyboardMoveDelay(500), mMessageTime(0), mShowIp(false), mAwayDialog(0), @@ -741,8 +737,9 @@ void LocalPlayer::setWalkingDir(int dir) // If the delay to send another walk message to the server hasn't expired, // don't do anything or we could get disconnected for spamming the server - if (get_elapsed_time(mLocalWalkTime) < walkingKeyboardDelay) + if (get_elapsed_time(mLocalWalkTime) < mKeyboardMoveDelay) return; + mLocalWalkTime = tick_time; mWalkingDir = dir; @@ -808,6 +805,12 @@ void LocalPlayer::stopWalking(bool sendToServer) clearPath(); } +void LocalPlayer::setMoveSpeed(const Vector& speed) +{ + Being::setMoveSpeed(speed); + mKeyboardMoveDelay = Net::getPlayerHandler()->getKeyboardMoveDelay(speed); +} + void LocalPlayer::toggleSit() { if (mLastAction != -1) diff --git a/src/localplayer.h b/src/localplayer.h index ab309d8f..ae27e51e 100644 --- a/src/localplayer.h +++ b/src/localplayer.h @@ -147,6 +147,8 @@ class LocalPlayer : public Being */ void setTarget(Being *target); + void setMoveSpeed(const Vector &speed); + /** * Sets a new destination for this being to walk to. */ @@ -253,6 +255,13 @@ class LocalPlayer : public Being int mLocalWalkTime; /**< Timestamp used to control keyboard walk messages flooding */ + /** + * The delay between two permitted setDestination() call using + * the keyboard. + * It's set in milliseconds per tile. + */ + int mKeyboardMoveDelay; + typedef std::pair<std::string, int> MessagePair; /** Queued messages*/ std::list<MessagePair> mMessages; diff --git a/src/net/logindata.h b/src/net/logindata.h index 4d8fc043..b842bdfd 100644 --- a/src/net/logindata.h +++ b/src/net/logindata.h @@ -1,7 +1,7 @@ /* * The Mana Client * Copyright (C) 2004-2009 The Mana World Development Team - * Copyright (C) 2009-2010 The Mana Developers + * Copyright (C) 2009-2011 The Mana Developers * * This file is part of The Mana Client. * @@ -36,6 +36,7 @@ public: std::string username; std::string password; + std::string randomSeed; std::string newPassword; std::string updateHost; @@ -61,6 +62,7 @@ public: { username.clear(); password.clear(); + randomSeed.clear(); newPassword.clear(); updateHost.clear(); email.clear(); diff --git a/src/net/manaserv/loginhandler.cpp b/src/net/manaserv/loginhandler.cpp index 2f802e21..f06c3262 100644 --- a/src/net/manaserv/loginhandler.cpp +++ b/src/net/manaserv/loginhandler.cpp @@ -44,6 +44,7 @@ extern std::string netToken; LoginHandler::LoginHandler() { static const Uint16 _messages[] = { + APMSG_LOGIN_RNDTRGR_RESPONSE, APMSG_LOGIN_RESPONSE, APMSG_REGISTER_RESPONSE, APMSG_RECONNECT_RESPONSE, @@ -62,6 +63,10 @@ void LoginHandler::handleMessage(Net::MessageIn &msg) { switch (msg.getId()) { + case APMSG_LOGIN_RNDTRGR_RESPONSE: + handleLoginRandomResponse(msg); + break; + case APMSG_LOGIN_RESPONSE: handleLoginResponse(msg); break; @@ -245,6 +250,12 @@ void LoginHandler::handleMessage(Net::MessageIn &msg) } } +void LoginHandler::handleLoginRandomResponse(Net::MessageIn &msg) +{ + mLoginData->randomSeed = msg.readString(); + loginAccountContinue(); +} + void LoginHandler::handleLoginResponse(Net::MessageIn &msg) { const int errMsg = msg.readInt8(); @@ -385,14 +396,25 @@ unsigned int LoginHandler::getMaxUserNameLength() const void LoginHandler::loginAccount(LoginData *loginData) { mLoginData = loginData; + mTmpPassword = loginData->password; + + MessageOut msg(PAMSG_LOGIN_RNDTRGR); + msg.writeString(mLoginData->username); + accountServerConnection->send(msg); +} + +void LoginHandler::loginAccountContinue() +{ MessageOut msg(PAMSG_LOGIN); msg.writeInt32(PROTOCOL_VERSION); // client version - msg.writeString(loginData->username); - msg.writeString(sha256(loginData->username + loginData->password)); + msg.writeString(mLoginData->username); + + msg.writeString(sha256(sha256(sha256(mLoginData->username + mTmpPassword)) + mLoginData->randomSeed)); accountServerConnection->send(msg); + mTmpPassword = ""; } void LoginHandler::logout() diff --git a/src/net/manaserv/loginhandler.h b/src/net/manaserv/loginhandler.h index 2062dcb5..294b99ac 100644 --- a/src/net/manaserv/loginhandler.h +++ b/src/net/manaserv/loginhandler.h @@ -77,12 +77,16 @@ 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 readServerInfo(Net::MessageIn &msg); + void loginAccountContinue(); + LoginData *mLoginData; + std::string mTmpPassword; unsigned int mMinUserNameLength; unsigned int mMaxUserNameLength; }; diff --git a/src/net/manaserv/manaserv_protocol.h b/src/net/manaserv/manaserv_protocol.h index cd24d838..2c790d26 100644 --- a/src/net/manaserv/manaserv_protocol.h +++ b/src/net/manaserv/manaserv_protocol.h @@ -57,6 +57,8 @@ enum { APMSG_LOGIN_RESPONSE = 0x0012, // B error, S updatehost, S Client data URL, B Character slots PAMSG_LOGOUT = 0x0013, // - APMSG_LOGOUT_RESPONSE = 0x0014, // B error + PAMSG_LOGIN_RNDTRGR = 0x0015, // S username + APMSG_LOGIN_RNDTRGR_RESPONSE = 0x0016, // S random seed PAMSG_CHAR_CREATE = 0x0020, // S name, B hair style, B hair color, B gender, B slot, {W stats}* APMSG_CHAR_CREATE_RESPONSE = 0x0021, // B error PAMSG_CHAR_DELETE = 0x0022, // B slot diff --git a/src/net/manaserv/playerhandler.cpp b/src/net/manaserv/playerhandler.cpp index a114da3d..d7c3dab6 100644 --- a/src/net/manaserv/playerhandler.cpp +++ b/src/net/manaserv/playerhandler.cpp @@ -442,4 +442,12 @@ Vector PlayerHandler::getPixelsPerTickMoveSpeed(const Vector &speed, Map *map) return speedInTicks; } +int PlayerHandler::getKeyboardMoveDelay(const Vector& speed) +{ + int maxSpeed = std::max(speed.x, speed.y); + if (maxSpeed <= 0) + maxSpeed = 2; + return 1000 / maxSpeed; +} + } // namespace ManaServ diff --git a/src/net/manaserv/playerhandler.h b/src/net/manaserv/playerhandler.h index 3e3f8aad..0edb4354 100644 --- a/src/net/manaserv/playerhandler.h +++ b/src/net/manaserv/playerhandler.h @@ -69,6 +69,8 @@ class PlayerHandler : public MessageHandler, public Net::PlayerHandler Vector getPixelsPerTickMoveSpeed(const Vector &speed, Map *map = 0); + int getKeyboardMoveDelay(const Vector& speed); + bool usePixelPrecision() { return true; } diff --git a/src/net/playerhandler.h b/src/net/playerhandler.h index f9396caf..b52b6315 100644 --- a/src/net/playerhandler.h +++ b/src/net/playerhandler.h @@ -71,12 +71,18 @@ class PlayerHandler virtual Vector getDefaultMoveSpeed() const = 0; /** - * Convert the original speed in pixel per tick for internal use. + * Convert the original server-dependant speed for internal use. */ virtual Vector getPixelsPerTickMoveSpeed(const Vector &speed, Map *map = 0) = 0; /** + * Convert the original speed into the keyboard move delay. + * The delay is set in milliseconds per tiles. + */ + virtual int getKeyboardMoveDelay(const Vector& speed) = 0; + + /** * Tells whether the client has to use pixel paths. * Return false when tiles-center positions only are to be used. */ diff --git a/src/net/tmwa/playerhandler.cpp b/src/net/tmwa/playerhandler.cpp index f30baecd..dd228f11 100644 --- a/src/net/tmwa/playerhandler.cpp +++ b/src/net/tmwa/playerhandler.cpp @@ -22,6 +22,7 @@ #include "net/tmwa/playerhandler.h" #include "net/tmwa/beinghandler.h" +#include "client.h" #include "configuration.h" #include "game.h" #include "localplayer.h" @@ -661,4 +662,9 @@ Vector PlayerHandler::getPixelsPerTickMoveSpeed(const Vector &speed, Map *map) return speedInTicks; } +int PlayerHandler::getKeyboardMoveDelay(const Vector& speed) +{ + return std::min(speed.x, speed.y) * MILLISECONDS_IN_A_TICK; +} + } // namespace TmwAthena diff --git a/src/net/tmwa/playerhandler.h b/src/net/tmwa/playerhandler.h index 63812f47..3e22be22 100644 --- a/src/net/tmwa/playerhandler.h +++ b/src/net/tmwa/playerhandler.h @@ -62,6 +62,8 @@ class PlayerHandler : public MessageHandler, public Net::PlayerHandler Vector getPixelsPerTickMoveSpeed(const Vector &speed, Map *map = 0); + int getKeyboardMoveDelay(const Vector& speed); + bool usePixelPrecision() { return false; } }; |