diff options
31 files changed, 500 insertions, 304 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 116bceed0..6b59b54db 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -327,30 +327,23 @@ gcc-8_unittestsbin: tags: - docker -mplint: - stage: lint - script: - - ./tools/ci/jobs/mplint.sh src po data - <<: *job-push - variables: - PACKAGES: gcc g++ git - make autoconf automake autopoint gettext - tags: - - docker linters: stage: lint image: debian:buster script: + - ./tools/ci/jobs/mplint.sh src po data - ./tools/ci/jobs/pngcheck.sh - ./tools/ci/jobs/imagemagiccheck.sh - ./tools/ci/jobs/cpplint.sh - ./tools/ci/jobs/nsiqcppstyle.sh <<: *job-push variables: - PACKAGES: python wget pngcheck imagemagick git grep + MPLINT_PACKAGE_URL: "$CI_API_V4_URL/projects/mana%2Fmplint/jobs/artifacts/master/download?job=package_debian10_buster" + PACKAGES: git grep imagemagick pngcheck python unzip wget tags: - - lightweight + - docker + gcc-5_h_all: stage: prebuild diff --git a/src/being/being.cpp b/src/being/being.cpp index e918877a1..6dd797eac 100644 --- a/src/being/being.cpp +++ b/src/being/being.cpp @@ -4309,8 +4309,8 @@ void Being::drawHpBar(Graphics *restrict const graphics, const int maxHP, const int hp, const int damage, - const UserColorIdT color1, - const UserColorIdT color2, + const UserColorIdT colorFG, + const UserColorIdT colorBG, const int x, const int y, const int width, @@ -4346,13 +4346,13 @@ void Being::drawHpBar(Graphics *restrict const graphics, if ((damage == 0 && (this != localPlayer || hp == maxHP)) || (hp == 0 && maxHP == damage)) { - graphics->setColor(userPalette->getColorWithAlpha(color1)); + graphics->setColor(userPalette->getColorWithAlpha(colorFG)); graphics->fillRectangle(Rect(x, y, dx, height)); return; } else if (width - dx <= 0) { - graphics->setColor(userPalette->getColorWithAlpha(color2)); + graphics->setColor(userPalette->getColorWithAlpha(colorBG)); graphics->fillRectangle(Rect(x, y, width, height)); return; } @@ -4362,22 +4362,23 @@ void Being::drawHpBar(Graphics *restrict const graphics, { if (hp == maxHP) { - graphics->setColor(userPalette->getColorWithAlpha(color1)); + graphics->setColor(userPalette->getColorWithAlpha(colorFG)); graphics->fillRectangle(Rect(x, y, dx, height)); return; } else if (width - dx <= 0) { - graphics->setColor(userPalette->getColorWithAlpha(color2)); + graphics->setColor(userPalette->getColorWithAlpha(colorBG)); graphics->fillRectangle(Rect(x, y, width, height)); return; } } - graphics->setColor(userPalette->getColorWithAlpha(color1)); + // foreground + graphics->setColor(userPalette->getColorWithAlpha(colorFG)); graphics->fillRectangle(Rect(x, y, dx, height)); - - graphics->setColor(userPalette->getColorWithAlpha(color2)); + // background + graphics->setColor(userPalette->getColorWithAlpha(colorBG)); graphics->fillRectangle(Rect(x + dx, y, width - dx, height)); } diff --git a/src/defaults.cpp b/src/defaults.cpp index 4869de8ef..eae83e1ab 100644 --- a/src/defaults.cpp +++ b/src/defaults.cpp @@ -189,15 +189,9 @@ void setConfigDefaults(Configuration &cfg) AddDEF("screenshotDirectory3", ""); AddDEF("useScreenshotDirectorySuffix", true); AddDEF("screenshotDirectorySuffix", ""); -#ifdef __SWITCH__ AddDEF("joystickEnabled", true); -#else - AddDEF("joystickEnabled", false); -#endif - AddDEF("upTolerance", 100); - AddDEF("downTolerance", 100); - AddDEF("leftTolerance", 100); - AddDEF("rightTolerance", 100); + AddDEF("joystickTolerance", 0.3F); + AddDEF("useHatForMovement", true); AddDEF("logNpcInGui", true); AddDEF("download-music", true); AddDEF("guialpha", 0.8F); @@ -238,8 +232,8 @@ void setConfigDefaults(Configuration &cfg) AddDEF("allowCommandsInChatTabs", true); AddDEF("serverMsgInDebug", true); AddDEF("hideShopMessages", true); - AddDEF("showChatHistory", true); - AddDEF("chatMaxLinesLimit", 40); + AddDEF("loadChatHistoryLines", 100); + AddDEF("chatMaxLinesLimit", 100); AddDEF("chatColor", 0); AddDEF("showJob", true); AddDEF("updateOnlineList", true); diff --git a/src/game.cpp b/src/game.cpp index 4e3c399cd..69daa254d 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -293,8 +293,6 @@ static void createGuiWindows() localChatTab = new ChatTab(chatWindow, _("General"), GENERAL_CHANNEL, "#General", ChatTabType::INPUT); localChatTab->setAllowHighlight(false); - if (config.getBoolValue("showChatHistory")) - localChatTab->loadFromLogFile("#General"); // TRANSLATORS: chat tab header debugChatTab = new ChatTab(chatWindow, _("Debug"), "", diff --git a/src/gui/sdlinput.cpp b/src/gui/sdlinput.cpp index 9b8b1ec6a..8f3ca8bff 100644 --- a/src/gui/sdlinput.cpp +++ b/src/gui/sdlinput.cpp @@ -171,6 +171,22 @@ void SDLInput::pushInput(const SDL_Event &event) break; } + case SDL_JOYBUTTONDOWN: + case SDL_JOYHATMOTION: + case SDL_JOYAXISMOTION: + { + const InputActionT actionId = inputManager.getActionByKey(event); + if (actionId > InputAction::NO_VALUE) + { + keyInput.setActionId(actionId); + keyInput.setType(KeyEventType::PRESSED); + mKeyInputQueue.push(keyInput); + keyInput.setType(KeyEventType::RELEASED); + mKeyInputQueue.push(keyInput); + } + break; + } + #ifdef USE_SDL2 case SDL_TEXTINPUT: keyInput.setType(KeyEventType::PRESSED); diff --git a/src/gui/widgets/tabs/chat/battletab.cpp b/src/gui/widgets/tabs/chat/battletab.cpp index 5dd5ff987..9fa18e945 100644 --- a/src/gui/widgets/tabs/chat/battletab.cpp +++ b/src/gui/widgets/tabs/chat/battletab.cpp @@ -36,8 +36,6 @@ BattleTab::BattleTab(const Widget2 *const widget) : ChatTab(widget, _("Battle"), "", "#Battle", ChatTabType::BATTLE) { setTabColors(ThemeColorId::BATTLE_CHAT_TAB); - if (config.getBoolValue("showChatHistory")) - loadFromLogFile("#Battle"); } BattleTab::~BattleTab() diff --git a/src/gui/widgets/tabs/chat/chattab.cpp b/src/gui/widgets/tabs/chat/chattab.cpp index ec9042694..3773df55f 100644 --- a/src/gui/widgets/tabs/chat/chattab.cpp +++ b/src/gui/widgets/tabs/chat/chattab.cpp @@ -97,6 +97,10 @@ ChatTab::ChatTab(const Widget2 *const widget, if (chatWindow != nullptr) chatWindow->addTab(this); mTextOutput->updateSize(true); + + const int maxLines = config.getIntValue("loadChatHistoryLines"); + if (maxLines > 0) + loadFromLogFile(logName, maxLines); } ChatTab::~ChatTab() @@ -510,12 +514,13 @@ void ChatTab::addRow(std::string &line) false); } -void ChatTab::loadFromLogFile(const std::string &name) +void ChatTab::loadFromLogFile(const std::string &name, + const unsigned maxLines) { if (chatLogger != nullptr) { std::list<std::string> list; - chatLogger->loadLast(name, list, 5); + chatLogger->loadLast(name, list, maxLines); std::list<std::string>::const_iterator i = list.begin(); while (i != list.end()) { diff --git a/src/gui/widgets/tabs/chat/chattab.h b/src/gui/widgets/tabs/chat/chattab.h index 7a3774fc2..7aeeeebdb 100644 --- a/src/gui/widgets/tabs/chat/chattab.h +++ b/src/gui/widgets/tabs/chat/chattab.h @@ -153,7 +153,8 @@ class ChatTab notfinal : public Tab bool hasRows() const A_WARN_UNUSED { return mTextOutput->hasRows(); } - void loadFromLogFile(const std::string &name); + void loadFromLogFile(const std::string &name, + const unsigned maxLines); bool getAllowHighlight() const noexcept2 A_WARN_UNUSED { return mAllowHightlight; } diff --git a/src/gui/widgets/tabs/setup_chat.cpp b/src/gui/widgets/tabs/setup_chat.cpp index f42f34c5a..ae9043962 100644 --- a/src/gui/widgets/tabs/setup_chat.cpp +++ b/src/gui/widgets/tabs/setup_chat.cpp @@ -148,11 +148,12 @@ Setup_Chat::Setup_Chat(const Widget2 *const widget) : MainConfig_true); // TRANSLATORS: settings option - new SetupItemCheckBox(_("Show chat history"), + new SetupItemIntTextField(_("Show chat history lines"), // TRANSLATORS: settings description - _("If this setting enabled, client will load old chat tabs content " - "from logs on startup instead of starting with empty chat tabs."), - "showChatHistory", this, "showChatHistoryEvent", + _("If this number is set to above 0, the client will load old chat" + " tabs content from logs on startup instead of starting with empty" + " chat tabs."), + "loadChatHistoryLines", this, "loadChatHistoryLinesEvent", 0, 10000, MainConfig_true); // TRANSLATORS: settings option diff --git a/src/gui/widgets/tabs/setup_joystick.cpp b/src/gui/widgets/tabs/setup_joystick.cpp index ab623b901..297f5bafc 100644 --- a/src/gui/widgets/tabs/setup_joystick.cpp +++ b/src/gui/widgets/tabs/setup_joystick.cpp @@ -35,6 +35,7 @@ #include "gui/widgets/dropdown.h" #include "gui/widgets/label.h" #include "gui/widgets/layouthelper.h" +#include "gui/widgets/slider.h" #include "utils/delete2.h" #include "utils/gettext.h" @@ -43,12 +44,6 @@ Setup_Joystick::Setup_Joystick(const Widget2 *const widget) : SetupTab(widget), - mCalibrateLabel(new Label(this, - // TRANSLATORS: joystick settings tab label - _("Press the button to start calibration"))), - // TRANSLATORS: joystick settings tab button - mCalibrateButton(new Button(this, _("Calibrate"), "calibrate", - BUTTON_SKIN, this)), // TRANSLATORS: joystick settings tab button mDetectButton(new Button(this, _("Detect joysticks"), "detect", BUTTON_SKIN, this)), @@ -58,6 +53,13 @@ Setup_Joystick::Setup_Joystick(const Widget2 *const widget) : mNamesModel(new NamesModel), mNamesDropDown(new DropDown(this, mNamesModel, false, Modal_false, nullptr, std::string())), + mToleranceLabel(new Label(this)), + mToleranceSlider(new Slider(this, 0.01, 1, 0.01)), + mUseHatForMovementCheckBox(new CheckBox(this, + // TRANSLATORS: joystick settings tab checkbox + _("Use joystick hat (d-pad) for movement"), + config.getBoolValue("useHatForMovement"), + nullptr, std::string())), mUseInactiveCheckBox(new CheckBox(this, // TRANSLATORS: joystick settings tab checkbox _("Use joystick if client window inactive"), @@ -73,10 +75,19 @@ Setup_Joystick::Setup_Joystick(const Widget2 *const widget) : mJoystickEnabled->setSelected(mOriginalJoystickEnabled); mJoystickEnabled->setActionEventId("joystick"); mJoystickEnabled->addActionListener(this); - mCalibrateButton->setEnabled(mOriginalJoystickEnabled); + + const float tolerance = config.getFloatValue("joystickTolerance"); + mToleranceSlider->setValue(tolerance); + // TRANSLATORS: joystick settings tab label + mToleranceLabel->setCaption(_("joystick dead zone: ") + + strprintf("%.2f", tolerance)); + mToleranceLabel->setWidth(150); + mToleranceLabel->setHeight(20); mNamesDropDown->setActionEventId("name"); mNamesDropDown->addActionListener(this); + mToleranceSlider->setActionEventId("toleranceslider"); + mToleranceSlider->addActionListener(this); if (joystick != nullptr) { @@ -96,10 +107,13 @@ Setup_Joystick::Setup_Joystick(const Widget2 *const widget) : place(0, 0, mJoystickEnabled, 1, 1); place(0, 1, mNamesDropDown, 1, 1); - place(0, 2, mUseInactiveCheckBox, 1, 1); - place(0, 3, mDetectButton, 1, 1); - place(0, 4, mCalibrateLabel, 1, 1); - place(0, 5, mCalibrateButton, 1, 1); + + place(0, 2, mToleranceSlider, 1, 1); + place(1, 2, mToleranceLabel, 1, 1).setPadding(3); + + place(0, 3, mUseHatForMovementCheckBox, 1, 1); + place(0, 4, mUseInactiveCheckBox, 1, 1); + place(0, 5, mDetectButton, 1, 1); setDimension(Rect(0, 0, 365, 75)); } @@ -121,6 +135,13 @@ void Setup_Joystick::action(const ActionEvent &event) if (joystick != nullptr) joystick->setNumber(mNamesDropDown->getSelected()); } + else if (source == mToleranceSlider) + { + const float tolerance = mToleranceSlider->getValue(); + // TRANSLATORS: joystick settings tab label + mToleranceLabel->setCaption(_("joystick dead zone: ") + + strprintf("%.2f", tolerance)); + } else if (source == mDetectButton) { Joystick::detect(); @@ -130,36 +151,11 @@ void Setup_Joystick::action(const ActionEvent &event) else mNamesDropDown->setSelected(0); } - else - { - if (joystick == nullptr) - return; - - if (joystick->isCalibrating()) - { - // TRANSLATORS: joystick settings tab button - mCalibrateButton->setCaption(_("Calibrate")); - mCalibrateLabel->setCaption - // TRANSLATORS: joystick settings tab label - (_("Press the button to start calibration")); - joystick->finishCalibration(); - } - else - { - // TRANSLATORS: joystick settings tab button - mCalibrateButton->setCaption(_("Stop")); - mCalibrateLabel->setCaption( - // TRANSLATORS: joystick settings tab label - _("Rotate the stick and don't press buttons")); - joystick->startCalibration(); - } - } } void Setup_Joystick::setTempEnabled(const bool sel) { Joystick::setEnabled(sel); - mCalibrateButton->setEnabled(sel); if (joystick != nullptr) { if (sel) @@ -186,6 +182,16 @@ void Setup_Joystick::apply() config.setValue("joystickEnabled", Joystick::isEnabled()); - config.setValue("useInactiveJoystick", mUseInactiveCheckBox->isSelected()); - joystick->setUseInactive(mUseInactiveCheckBox->isSelected()); + config.setValue("useHatForMovement", + mUseHatForMovementCheckBox->isSelected()); + joystick->setUseHatForMovement( + mUseHatForMovementCheckBox->isSelected()); + config.setValue("useInactiveJoystick", + mUseInactiveCheckBox->isSelected()); + joystick->setUseInactive( + mUseInactiveCheckBox->isSelected()); + + float tolerance = mToleranceSlider->getValue(); + config.setValue("joystickTolerance", tolerance); + joystick->setTolerance(tolerance); } diff --git a/src/gui/widgets/tabs/setup_joystick.h b/src/gui/widgets/tabs/setup_joystick.h index 174cd82b2..2c138daf5 100644 --- a/src/gui/widgets/tabs/setup_joystick.h +++ b/src/gui/widgets/tabs/setup_joystick.h @@ -31,6 +31,7 @@ class CheckBox; class DropDown; class Label; class NamesModel; +class Slider; class Setup_Joystick final : public SetupTab { @@ -50,12 +51,13 @@ class Setup_Joystick final : public SetupTab void setTempEnabled(const bool sel); private: - Label *mCalibrateLabel A_NONNULLPOINTER; - Button *mCalibrateButton A_NONNULLPOINTER; Button *mDetectButton A_NONNULLPOINTER; CheckBox *mJoystickEnabled A_NONNULLPOINTER; NamesModel *mNamesModel A_NONNULLPOINTER; DropDown *mNamesDropDown A_NONNULLPOINTER; + Label *mToleranceLabel A_NONNULLPOINTER; + Slider *mToleranceSlider A_NONNULLPOINTER; + CheckBox *mUseHatForMovementCheckBox A_NONNULLPOINTER; CheckBox *mUseInactiveCheckBox A_NONNULLPOINTER; bool mOriginalJoystickEnabled A_NONNULLPOINTER; }; diff --git a/src/gui/windows/chatwindow.cpp b/src/gui/windows/chatwindow.cpp index a3b777655..15363883f 100644 --- a/src/gui/windows/chatwindow.cpp +++ b/src/gui/windows/chatwindow.cpp @@ -1246,8 +1246,6 @@ WhisperTab *ChatWindow::addWhisperTab(const std::string &caption, if ((gui != nullptr) && !playerRelations.isGoodName(nick)) ret->setLabelFont(gui->getSecureFont()); mWhispers[tempNick] = ret; - if (config.getBoolValue("showChatHistory")) - ret->loadFromLogFile(nick); } if (switchTo) @@ -1330,8 +1328,6 @@ ChatTab *ChatWindow::addChannelTab(const std::string &name, ret = new ChannelTab(this, name); mChannels[tempName] = ret; ret->setAllowHighlight(false); - if (config.getBoolValue("showChatHistory")) - ret->loadFromLogFile(name); } if (switchTo) diff --git a/src/gui/windows/ministatuswindow.cpp b/src/gui/windows/ministatuswindow.cpp index 4c2b2d376..e52a1a8d7 100644 --- a/src/gui/windows/ministatuswindow.cpp +++ b/src/gui/windows/ministatuswindow.cpp @@ -275,8 +275,6 @@ void MiniStatusWindow::statChanged(const AttributesT id A_UNUSED, statusWindow->updateMPBar(mMpBar, false); } - StatusWindow::updateJobBar(mJobBar, - true); } void MiniStatusWindow::attributeChanged(const AttributesT id, @@ -302,6 +300,11 @@ void MiniStatusWindow::attributeChanged(const AttributesT id, StatusWindow::updateXPBar(mXpBar, true); break; + case Attributes::PLAYER_JOB_LEVEL: + case Attributes::PLAYER_JOB_EXP: + case Attributes::PLAYER_JOB_EXP_NEEDED: + StatusWindow::updateJobBar(mJobBar, true); + break; case Attributes::TOTAL_WEIGHT: case Attributes::MAX_WEIGHT: StatusWindow::updateWeightBar(mWeightBar); diff --git a/src/gui/windows/quitdialog.cpp b/src/gui/windows/quitdialog.cpp index d1ceb1ad9..7ef2bc6e8 100644 --- a/src/gui/windows/quitdialog.cpp +++ b/src/gui/windows/quitdialog.cpp @@ -210,6 +210,7 @@ void QuitDialog::keyPressed(KeyEvent &event) { const InputActionT actionId = event.getActionId(); int dir = 0; + bool consume = true; PRAGMA45(GCC diagnostic push) PRAGMA45(GCC diagnostic ignored "-Wswitch-enum") @@ -229,10 +230,14 @@ void QuitDialog::keyPressed(KeyEvent &event) dir = 1; break; default: + consume = false; break; } PRAGMA45(GCC diagnostic pop) + if (consume) + event.consume(); + if (dir != 0) { STD_VECTOR<RadioButton*>::const_iterator it = mOptions.begin(); diff --git a/src/gui/windows/registerdialog.cpp b/src/gui/windows/registerdialog.cpp index 40a0e472c..588ca0074 100644 --- a/src/gui/windows/registerdialog.cpp +++ b/src/gui/windows/registerdialog.cpp @@ -157,6 +157,12 @@ RegisterDialog::~RegisterDialog() delete2(mWrongDataNoticeListener) } +void RegisterDialog::logic() +{ + mRegisterButton->setEnabled(canSubmit()); + Window::logic(); +} + void RegisterDialog::action(const ActionEvent &event) { const std::string &eventId = event.getId(); @@ -289,11 +295,6 @@ void RegisterDialog::action(const ActionEvent &event) void RegisterDialog::keyPressed(KeyEvent &event) { - if (event.isConsumed()) - { - mRegisterButton->setEnabled(canSubmit()); - return; - } const InputActionT actionId = event.getActionId(); if (actionId == InputAction::GUI_CANCEL) { @@ -304,10 +305,6 @@ void RegisterDialog::keyPressed(KeyEvent &event) { action(ActionEvent(nullptr, mRegisterButton->getActionEventId())); } - else - { - mRegisterButton->setEnabled(canSubmit()); - } } bool RegisterDialog::canSubmit() const diff --git a/src/gui/windows/registerdialog.h b/src/gui/windows/registerdialog.h index 6249253f8..139739780 100644 --- a/src/gui/windows/registerdialog.h +++ b/src/gui/windows/registerdialog.h @@ -62,6 +62,8 @@ class RegisterDialog final : public Window, void postInit() override; + void logic() override final; + /** * Called when receiving actions from the widgets. */ diff --git a/src/gui/windows/updaterwindow.cpp b/src/gui/windows/updaterwindow.cpp index 948ce5a17..2ed01f4f3 100644 --- a/src/gui/windows/updaterwindow.cpp +++ b/src/gui/windows/updaterwindow.cpp @@ -619,8 +619,7 @@ void UpdaterWindow::download() const STD_VECTOR<std::string> &mirrors = settings.updateMirrors; FOR_EACH (STD_VECTOR<std::string>::const_iterator, it, mirrors) { - mDownload->addMirror(pathJoin(*it, - mCurrentFile)); + mDownload->addMirror(urlJoin(*it, mCurrentFile)); } } } diff --git a/src/input/inputmanager.cpp b/src/input/inputmanager.cpp index a379e0e86..8cb10041e 100644 --- a/src/input/inputmanager.cpp +++ b/src/input/inputmanager.cpp @@ -416,8 +416,45 @@ std::string InputManager::getKeyStringLong(const InputActionT index) const } else if (key.type == InputType::JOYSTICK) { - // TRANSLATORS: long joystick button name. must be short. - str = strprintf(_("JButton%d"), key.value + 1); + if (key.value < Joystick::MAX_BUTTONS) + { + // TRANSLATORS: joystick button name. must be short. + str = strprintf(_("JButton%d"), key.value + 1); + } + else if (key.value == Joystick::KEY_UP) + { + // TRANSLATORS: joystick up button. must be short. + str = _("JUp"); + } + else if (key.value == Joystick::KEY_DOWN) + { + // TRANSLATORS: joystick down button. must be short. + str = _("JDown"); + } + else if (key.value == Joystick::KEY_LEFT) + { + // TRANSLATORS: joystick left button. must be short. + str = _("JLeft"); + } + else if (key.value == Joystick::KEY_RIGHT) + { + // TRANSLATORS: joystick right button. must be short. + str = _("JRight"); + } + else if (key.value >= Joystick::KEY_NEGATIVE_AXIS_FIRST + && key.value < Joystick::KEY_POSITIVE_AXIS_FIRST) + { + // TRANSLATORS: joystick negative axis. must be short. + str = strprintf(_("JAxis%dMinus"), + key.value - Joystick::KEY_NEGATIVE_AXIS_FIRST); + } + else if (key.value >= Joystick::KEY_POSITIVE_AXIS_FIRST + && key.value < Joystick::KEY_END) + { + // TRANSLATORS: joystick positive axis. must be short. + str = strprintf(_("JAxis%dPlus"), + key.value - Joystick::KEY_POSITIVE_AXIS_FIRST); + } } if (!str.empty()) { @@ -459,8 +496,45 @@ void InputManager::updateKeyString(const InputFunction &ki, } else if (key.type == InputType::JOYSTICK) { - // TRANSLATORS: short joystick button name. muse be very short - str = strprintf(_("JB%d"), key.value + 1); + if (key.value < Joystick::MAX_BUTTONS) + { + // TRANSLATORS: joystick button name. must be very short + str = strprintf(_("JB%d"), key.value + 1); + } + else if (key.value == Joystick::KEY_UP) + { + // TRANSLATORS: joystick up button. must be very short + str = _("JUp"); + } + else if (key.value == Joystick::KEY_DOWN) + { + // TRANSLATORS: joystick down button. must be very short + str = _("JDn"); + } + else if (key.value == Joystick::KEY_LEFT) + { + // TRANSLATORS: joystick left button. must be very short + str = _("JLt"); + } + else if (key.value == Joystick::KEY_RIGHT) + { + // TRANSLATORS: joystick right button. must be very short + str = _("JRt"); + } + else if (key.value >= Joystick::KEY_NEGATIVE_AXIS_FIRST + && key.value < Joystick::KEY_POSITIVE_AXIS_FIRST) + { + // TRANSLATORS: joystick negative axis. must be very short. + str = strprintf(_("JA%d-"), + key.value - Joystick::KEY_NEGATIVE_AXIS_FIRST); + } + else if (key.value >= Joystick::KEY_POSITIVE_AXIS_FIRST + && key.value < Joystick::KEY_END) + { + // TRANSLATORS: joystick positive axis. must be very short. + str = strprintf(_("JA%d+"), + key.value - Joystick::KEY_POSITIVE_AXIS_FIRST); + } } if (!str.empty()) { @@ -617,21 +691,7 @@ bool InputManager::handleEvent(const SDL_Event &restrict event) restrict2 BLOCK_END("InputManager::handleEvent") return true; } - keyboard.handleActivateKey(event); - // send straight to gui for certain windows -#ifndef DYECMD - if ((quitDialog != nullptr) || TextDialog::isActive()) - { - if (guiInput != nullptr) - guiInput->pushInput(event); - if (gui != nullptr) - gui->handleInput(); - BLOCK_END("InputManager::handleEvent") - return true; - } -#endif // DYECMD - break; } case SDL_KEYUP: @@ -650,10 +710,13 @@ bool InputManager::handleEvent(const SDL_Event &restrict event) restrict2 break; } case SDL_JOYBUTTONDOWN: + case SDL_JOYHATMOTION: + case SDL_JOYAXISMOTION: { updateConditionMask(true); // joystick.handleActicateButton(event); - if (handleAssignKey(event, InputType::JOYSTICK)) + if (joystick != nullptr && joystick->isActionEvent(event) + && handleAssignKey(event, InputType::JOYSTICK)) { BLOCK_END("InputManager::handleEvent") return true; @@ -690,8 +753,16 @@ bool InputManager::handleEvent(const SDL_Event &restrict event) restrict2 guiInput->pushInput(event); if (gui != nullptr) { - const bool res = gui->handleInput(); - if (res && event.type == SDL_KEYDOWN) + bool res = gui->handleInput(); +#ifndef DYECMD + // always treat keyboard input as handled if a text dialog is active + if (event.type == SDL_KEYDOWN && TextDialog::isActive()) + res = true; +#endif // DYECMD + const bool joystickActionEvent = + joystick != nullptr && joystick->isActionEvent(event); + // stop processing input if event is consumed by the gui + if (res && (event.type == SDL_KEYDOWN || joystickActionEvent)) { BLOCK_END("InputManager::handleEvent") return true; @@ -724,6 +795,8 @@ bool InputManager::handleEvent(const SDL_Event &restrict event) restrict2 // break; case SDL_JOYBUTTONDOWN: + case SDL_JOYHATMOTION: + case SDL_JOYAXISMOTION: if ((joystick != nullptr) && joystick->validate()) { if (triggerAction(joystick->getActionVector(event))) @@ -1055,7 +1128,6 @@ InputActionT InputManager::getKeyIndex(const int value, InputActionT InputManager::getActionByKey(const SDL_Event &restrict event) const restrict2 { - // for now support only keyboard events if (event.type == SDL_KEYDOWN || event.type == SDL_KEYUP) { const InputActionT idx = keyboard.getActionId(event); @@ -1065,6 +1137,15 @@ InputActionT InputManager::getActionByKey(const SDL_Event &restrict event) return idx; } } + if (joystick != nullptr && joystick->isActionEvent(event)) + { + const InputActionT idx = joystick->getActionId(event); + if (CAST_S32(idx) >= 0 && + checkKey(&inputActionData[CAST_SIZE(idx)])) + { + return idx; + } + } return InputAction::NO_VALUE; } diff --git a/src/input/joystick.cpp b/src/input/joystick.cpp index 52d9a7525..ea1883ad0 100644 --- a/src/input/joystick.cpp +++ b/src/input/joystick.cpp @@ -47,21 +47,24 @@ bool Joystick::mInitialized = false; Joystick::Joystick(const int no) : mDirection(0), + mHatPosition(0), mJoystick(nullptr), - mUpTolerance(0), - mDownTolerance(0), - mLeftTolerance(0), - mRightTolerance(0), - mCalibrating(false), + mTolerance(0), mNumber(no >= joystickCount ? joystickCount : no), - mCalibrated(false), + mAxesNumber(MAX_AXES), mButtonsNumber(MAX_BUTTONS), + mUseHatForMovement(true), mUseInactive(false), mHaveHats(false), mKeyToAction(), mKeyToId(), mKeyTimeMap() { + for (int i = 0; i < MAX_AXES; i++) + { + mIsTrigger[i] = false; + mAxesPositions[i] = 0; + } for (int i = 0; i < MAX_BUTTONS; i++) mActiveButtons[i] = false; } @@ -130,7 +133,9 @@ bool Joystick::open() return false; } + mAxesNumber = SDL_JoystickNumAxes(mJoystick); mButtonsNumber = SDL_JoystickNumButtons(mJoystick); + logger->log("Joystick: %i ", mNumber); #ifdef USE_SDL2 logger->log("Name: %s", SDL_JoystickName(mJoystick)); @@ -189,32 +194,31 @@ bool Joystick::open() logger->log("Name: %s", SDL_JoystickName(mNumber)); #endif // USE_SDL2 - logger->log("Axes: %i ", SDL_JoystickNumAxes(mJoystick)); + logger->log("Axes: %i ", mAxesNumber); logger->log("Balls: %i", SDL_JoystickNumBalls(mJoystick)); logger->log("Hats: %i", SDL_JoystickNumHats(mJoystick)); logger->log("Buttons: %i", mButtonsNumber); mHaveHats = (SDL_JoystickNumHats(mJoystick) > 0); + if (mAxesNumber > MAX_AXES) + mAxesNumber = mAxesNumber; + if (mButtonsNumber > MAX_BUTTONS) mButtonsNumber = MAX_BUTTONS; -#ifdef __SWITCH__ - config.setValue("joystick" + toString(mNumber) + "calibrated", true); - config.setValue("leftTolerance" + toString(mNumber), -10000); - config.setValue("rightTolerance" + toString(mNumber), 10000); - config.setValue("upTolerance" + toString(mNumber), -10000); - config.setValue("downTolerance" + toString(mNumber), 10000); -#endif - mCalibrated = config.getValueBool("joystick" - + toString(mNumber) + "calibrated", false); - - mUpTolerance = config.getIntValue("upTolerance" + toString(mNumber)); - mDownTolerance = config.getIntValue("downTolerance" + toString(mNumber)); - mLeftTolerance = config.getIntValue("leftTolerance" + toString(mNumber)); - mRightTolerance = config.getIntValue("rightTolerance" + toString(mNumber)); + mTolerance = config.getFloatValue("joystickTolerance"); + mUseHatForMovement = config.getBoolValue("useHatForMovement"); mUseInactive = config.getBoolValue("useInactiveJoystick"); + for (int i = 0; i < mAxesNumber; i++) + { + // heuristic to detect controller triggers. + // their resting position is at SDL_JOYSTICK_AXIS_MIN = -32768 + if (SDL_JoystickGetAxis(mJoystick, i) == SDL_JOYSTICK_AXIS_MIN) + mIsTrigger[i] = true; + } + return true; } @@ -245,15 +249,7 @@ void Joystick::setNumber(const int n) void Joystick::logic() { BLOCK_START("Joystick::logic") - // When calibrating, don't bother the outside with our state - if (mCalibrating) - { - doCalibration(); - BLOCK_END("Joystick::logic") - return; - } - - if (!mEnabled || !mCalibrated) + if (!mEnabled) { BLOCK_END("Joystick::logic") return; @@ -264,18 +260,28 @@ void Joystick::logic() if (mUseInactive || settings.inputFocused != KeyboardFocus::Unfocused) { + for (int i = 0; i < mAxesNumber; i++) + { + int position = SDL_JoystickGetAxis(mJoystick, i); + // transform range [SDL_JOYSTICK_AXIS_MIN, SDL_JOYSTICK_AXIS_MAX] + // to [0, SDL_JOYSTICK_AXIS_MAX] + if (mIsTrigger[i]) + position = (position - SDL_JOYSTICK_AXIS_MIN) / 2; + mAxesPositions[i] = position; + } + // X-Axis - int position = SDL_JoystickGetAxis(mJoystick, 0); - if (position >= mRightTolerance) + int position = mAxesPositions[0]; + if (position >= mTolerance * SDL_JOYSTICK_AXIS_MAX) mDirection |= RIGHT; - else if (position <= mLeftTolerance) + else if (position <= mTolerance * SDL_JOYSTICK_AXIS_MIN) mDirection |= LEFT; // Y-Axis - position = SDL_JoystickGetAxis(mJoystick, 1); - if (position <= mUpTolerance) + position = mAxesPositions[1]; + if (position <= mTolerance * SDL_JOYSTICK_AXIS_MIN) mDirection |= UP; - else if (position >= mDownTolerance) + else if (position >= mTolerance * SDL_JOYSTICK_AXIS_MAX) mDirection |= DOWN; #ifdef DEBUG_JOYSTICK @@ -287,18 +293,21 @@ void Joystick::logic() logger->log("axis 4 pos: %d", SDL_JoystickGetAxis(mJoystick, 4)); #endif // DEBUG_JOYSTICK - if ((mDirection == 0U) && mHaveHats) + if (mHaveHats) { // reading only hat 0 const uint8_t hat = SDL_JoystickGetHat(mJoystick, 0); + mHatPosition = 0; if ((hat & SDL_HAT_RIGHT) != 0) - mDirection |= RIGHT; + mHatPosition |= RIGHT; else if ((hat & SDL_HAT_LEFT) != 0) - mDirection |= LEFT; + mHatPosition |= LEFT; if ((hat & SDL_HAT_UP) != 0) - mDirection |= UP; + mHatPosition |= UP; else if ((hat & SDL_HAT_DOWN) != 0) - mDirection |= DOWN; + mHatPosition |= DOWN; + if ((mDirection == 0U) && mUseHatForMovement) + mDirection = mHatPosition; } // Buttons @@ -316,52 +325,42 @@ void Joystick::logic() } else { + mHatPosition = 0; + for (int i = 0; i < mAxesNumber; i++) + mAxesPositions[i] = 0; for (int i = 0; i < mButtonsNumber; i++) mActiveButtons[i] = false; } BLOCK_END("Joystick::logic") } -void Joystick::startCalibration() -{ - mUpTolerance = 0; - mDownTolerance = 0; - mLeftTolerance = 0; - mRightTolerance = 0; - mCalibrating = true; -} - -void Joystick::doCalibration() +bool Joystick::buttonPressed(const int no) const { - // X-Axis - int position = SDL_JoystickGetAxis(mJoystick, 0); - if (position > mRightTolerance) - mRightTolerance = position; - else if (position < mLeftTolerance) - mLeftTolerance = position; - - // Y-Axis - position = SDL_JoystickGetAxis(mJoystick, 1); - if (position > mDownTolerance) - mDownTolerance = position; - else if (position < mUpTolerance) - mUpTolerance = position; -} + if (!mEnabled) + return false; + const int button = getButton(no); + if (button >= 0) + { + if (button < mButtonsNumber) + return mActiveButtons[button]; + if (button == KEY_UP) + return (mHatPosition & UP) != 0; + if (button == KEY_DOWN) + return (mHatPosition & DOWN) != 0; + if (button == KEY_LEFT) + return (mHatPosition & LEFT) != 0; + if (button == KEY_RIGHT) + return (mHatPosition & RIGHT) != 0; + } + const int naxis = getNegativeAxis(no); + if (naxis >= 0) + return mAxesPositions[naxis] < mTolerance * SDL_JOYSTICK_AXIS_MIN; -void Joystick::finishCalibration() -{ - mCalibrated = true; - mCalibrating = false; - config.setValue("joystick" + toString(mNumber) + "calibrated", true); - config.setValue("leftTolerance" + toString(mNumber), mLeftTolerance); - config.setValue("rightTolerance" + toString(mNumber), mRightTolerance); - config.setValue("upTolerance" + toString(mNumber), mUpTolerance); - config.setValue("downTolerance" + toString(mNumber), mDownTolerance); -} + const int paxis = getPositiveAxis(no); + if (paxis >= 0) + return mAxesPositions[paxis] > mTolerance * SDL_JOYSTICK_AXIS_MAX; -bool Joystick::buttonPressed(const unsigned char no) const -{ - return (mEnabled && no < MAX_BUTTONS) ? mActiveButtons[no] : false; + return false; } void Joystick::getNames(STD_VECTOR <std::string> &names) @@ -377,33 +376,128 @@ void Joystick::update() mKeyTimeMap, InputType::JOYSTICK); } +bool Joystick::isActionEvent(const SDL_Event &event) +{ + return getButtonFromEvent(event) >= 0; +} + KeysVector *Joystick::getActionVector(const SDL_Event &event) { const int i = getButtonFromEvent(event); - - if (i < 0 || i >= mButtonsNumber) - return nullptr; -// logger->log("button triggerAction: %d", i); - if (mKeyToAction.find(i) != mKeyToAction.end()) - return &mKeyToAction[i]; - return nullptr; + return getActionVectorByKey(i); } KeysVector *Joystick::getActionVectorByKey(const int i) { - if (i < 0 || i >= mButtonsNumber) + if (getButton(i) < 0 + && getNegativeAxis(i) < 0 + && getPositiveAxis(i) < 0) + { return nullptr; + } // logger->log("button triggerAction: %d", i); - if (mKeyToAction.find(i) != mKeyToAction.end()) - return &mKeyToAction[i]; + + KeyToActionMapIter it = mKeyToAction.find(i); + if (it != mKeyToAction.end()) + return &it->second; + return nullptr; } +InputActionT Joystick::getActionId(const SDL_Event &event) +{ + const int i = getButtonFromEvent(event); + if (i < 0) + return InputAction::NO_VALUE; + + KeyToIdMapIter it = mKeyToId.find(i); + if (it != mKeyToId.end()) + return it->second; + + return InputAction::NO_VALUE; +} + int Joystick::getButtonFromEvent(const SDL_Event &event) const { - if (event.jbutton.which != mNumber) + if (event.type == SDL_JOYBUTTONDOWN) + { + if (event.jbutton.which != mNumber) + return -1; + return event.jbutton.button; + } + if (!mUseHatForMovement && event.type == SDL_JOYHATMOTION) + { + // reading only hat 0 + if (event.jhat.which != mNumber || event.jhat.hat != 0) + return -1; + const int value = event.jhat.value; + // SDL reports new hat position, not when d-pad button is pressed. + // because of that we have to compare it to previously known state. + if ((mHatPosition & UP) == 0 && (value & SDL_HAT_UP) != 0) + return KEY_UP; + if ((mHatPosition & DOWN) == 0 && (value & SDL_HAT_DOWN) != 0) + return KEY_DOWN; + if ((mHatPosition & LEFT) == 0 && (value & SDL_HAT_LEFT) != 0) + return KEY_LEFT; + if ((mHatPosition & RIGHT) == 0 && (value & SDL_HAT_RIGHT) != 0) + return KEY_RIGHT; + } + if (event.type == SDL_JOYAXISMOTION) + { + if (event.jaxis.which != mNumber) + return -1; + const int axis = event.jaxis.axis; + if (axis < RESERVED_AXES) + return -1; + int position = event.jaxis.value; + // transform range [SDL_JOYSTICK_AXIS_MIN, SDL_JOYSTICK_AXIS_MAX] + // to [0, SDL_JOYSTICK_AXIS_MAX] + if (mIsTrigger[axis]) + position = (position - SDL_JOYSTICK_AXIS_MIN) / 2; + if (position < mTolerance * SDL_JOYSTICK_AXIS_MIN + && mAxesPositions[axis] > mTolerance * SDL_JOYSTICK_AXIS_MIN) + return KEY_NEGATIVE_AXIS_FIRST + axis; + if (position > mTolerance * SDL_JOYSTICK_AXIS_MAX + && mAxesPositions[axis] < mTolerance * SDL_JOYSTICK_AXIS_MAX) + return KEY_POSITIVE_AXIS_FIRST + axis; + } + return -1; +} + +int Joystick::getButton(const int key) const +{ + if (key < 0 + || (mButtonsNumber <= key && key < MAX_BUTTONS) + || (mUseHatForMovement && key >= MAX_BUTTONS) + || key >= KEY_NEGATIVE_AXIS_FIRST) + { + return -1; + } + return key; +} + +int Joystick::getNegativeAxis(const int key) const +{ + if (key < KEY_NEGATIVE_AXIS_FIRST || key >= KEY_POSITIVE_AXIS_FIRST) + return -1; + + const int axis = key - KEY_NEGATIVE_AXIS_FIRST; + if (axis < RESERVED_AXES || axis >= mAxesNumber) + return -1; + + return axis; +} + +int Joystick::getPositiveAxis(const int key) const +{ + if (key < KEY_POSITIVE_AXIS_FIRST || key >= KEY_END) return -1; - return event.jbutton.button; + + const int axis = key - KEY_POSITIVE_AXIS_FIRST; + if (axis < RESERVED_AXES || axis >= mAxesNumber) + return -1; + + return axis; } bool Joystick::isActionActive(const InputActionT index) const @@ -417,19 +511,14 @@ bool Joystick::isActionActive(const InputActionT index) const const InputItem &val = key.values[i]; if (val.type != InputType::JOYSTICK) continue; - const int value = val.value; - if (value >= 0 && value < mButtonsNumber) - { - if (mActiveButtons[value]) - return true; - } + return buttonPressed(val.value); } return false; } bool Joystick::validate() const { - if (mCalibrating || !mEnabled || !mCalibrated) + if (!mEnabled) return false; return mUseInactive || @@ -441,14 +530,8 @@ void Joystick::handleRepeat(const int time) BLOCK_START("Joystick::handleRepeat") FOR_EACH (KeyTimeMapIter, it, mKeyTimeMap) { - bool repeat(false); const int key = (*it).first; - if (key >= 0 && key < mButtonsNumber) - { - if (mActiveButtons[key]) - repeat = true; - } - if (repeat) + if (buttonPressed(key)) { int &keyTime = (*it).second; if (time > keyTime && abs(time - keyTime) diff --git a/src/input/joystick.h b/src/input/joystick.h index a3c129950..49c4e553a 100644 --- a/src/input/joystick.h +++ b/src/input/joystick.h @@ -31,6 +31,15 @@ PRAGMA48(GCC diagnostic ignored "-Wshadow") #include <SDL_events.h> PRAGMA48(GCC diagnostic pop) +// defined first in SDL 2.0.6 +// not available on older distros +#ifndef SDL_JOYSTICK_AXIS_MIN +#define SDL_JOYSTICK_AXIS_MIN -32768 +#endif +#ifndef SDL_JOYSTICK_AXIS_MAX +#define SDL_JOYSTICK_AXIS_MAX 32767 +#endif + class Joystick final { public: @@ -42,6 +51,27 @@ class Joystick final MAX_BUTTONS = 64 }; + enum + { + RESERVED_AXES = 2, // reserved for movement + MAX_AXES = 8 // number of axes we can handle + }; + + /** + * Additional "buttons" for hat 0 (d-pad), + * sticks and triggers. + */ + enum + { + KEY_UP = MAX_BUTTONS, + KEY_DOWN, + KEY_LEFT, + KEY_RIGHT, + KEY_NEGATIVE_AXIS_FIRST, + KEY_POSITIVE_AXIS_FIRST = KEY_NEGATIVE_AXIS_FIRST + MAX_AXES, + KEY_END = KEY_POSITIVE_AXIS_FIRST + MAX_AXES + }; + /** * Directions, to be used as bitmask values. */ @@ -98,14 +128,7 @@ class Joystick final */ void logic(); - void startCalibration(); - - void finishCalibration(); - - bool isCalibrating() const noexcept2 A_WARN_UNUSED - { return mCalibrating; } - - bool buttonPressed(const unsigned char no) const A_WARN_UNUSED; + bool buttonPressed(const int no) const A_WARN_UNUSED; bool isUp() const noexcept2 A_WARN_UNUSED { return mEnabled && ((mDirection & UP) != 0); } @@ -122,15 +145,25 @@ class Joystick final int getNumber() const noexcept2 A_WARN_UNUSED { return mNumber; } + void setTolerance(const float tolerance) + { mTolerance = tolerance; } + + void setUseHatForMovement(const bool b) + { mUseHatForMovement = b; } + void setUseInactive(const bool b) { mUseInactive = b; } void update(); + bool isActionEvent(const SDL_Event &event) A_WARN_UNUSED; + KeysVector *getActionVector(const SDL_Event &event) A_WARN_UNUSED; KeysVector *getActionVectorByKey(const int i) A_WARN_UNUSED; + InputActionT getActionId(const SDL_Event &event) A_WARN_UNUSED; + int getButtonFromEvent(const SDL_Event &event) const A_WARN_UNUSED; bool isActionActive(const InputActionT index) const A_WARN_UNUSED; @@ -144,18 +177,18 @@ class Joystick final protected: unsigned char mDirection; + unsigned char mHatPosition; + int mAxesPositions[MAX_AXES]; + bool mIsTrigger[MAX_AXES]; bool mActiveButtons[MAX_BUTTONS]; SDL_Joystick *mJoystick; - int mUpTolerance; - int mDownTolerance; - int mLeftTolerance; - int mRightTolerance; - bool mCalibrating; + float mTolerance; int mNumber; - bool mCalibrated; + int mAxesNumber; int mButtonsNumber; + bool mUseHatForMovement; bool mUseInactive; bool mHaveHats; @@ -172,7 +205,11 @@ class Joystick final static bool mInitialized; static int joystickCount; - void doCalibration(); + int getButton(const int key) const A_WARN_UNUSED; + + int getNegativeAxis(const int key) const A_WARN_UNUSED; + + int getPositiveAxis(const int key) const A_WARN_UNUSED; }; extern Joystick *joystick; diff --git a/src/net/ea/partyrecv.cpp b/src/net/ea/partyrecv.cpp index 370cfed9c..53cb0227e 100644 --- a/src/net/ea/partyrecv.cpp +++ b/src/net/ea/partyrecv.cpp @@ -226,8 +226,6 @@ void PartyRecv::processPartyUpdateCoords(Net::MessageIn &msg) void PartyRecv::createTab() { partyTab = new PartyTab(chatWindow); - if (config.getBoolValue("showChatHistory")) - partyTab->loadFromLogFile("#Party"); } } // namespace Ea diff --git a/src/net/eathena/clanrecv.cpp b/src/net/eathena/clanrecv.cpp index 9ecb860a9..c686796dd 100644 --- a/src/net/eathena/clanrecv.cpp +++ b/src/net/eathena/clanrecv.cpp @@ -125,8 +125,6 @@ void ClanRecv::createTab() if (clanTab != nullptr) return; clanTab = new ClanTab(chatWindow); - if (config.getBoolValue("showChatHistory")) - clanTab->loadFromLogFile("#Clan"); } } // namespace EAthena diff --git a/src/net/eathena/guildrecv.cpp b/src/net/eathena/guildrecv.cpp index 74b8d9b8d..3d402c5b9 100644 --- a/src/net/eathena/guildrecv.cpp +++ b/src/net/eathena/guildrecv.cpp @@ -698,8 +698,6 @@ void GuildRecv::processGuildPositionInfo(Net::MessageIn &msg) if ((guildTab == nullptr) && (chatWindow != nullptr)) { guildTab = new GuildTab(chatWindow); - if (config.getBoolValue("showChatHistory")) - guildTab->loadFromLogFile("#Guild"); if (localPlayer != nullptr) localPlayer->addGuild(taGuild); guildHandler->memberList(); diff --git a/src/net/eathena/inventoryhandler.cpp b/src/net/eathena/inventoryhandler.cpp index 3911c63fa..19197c851 100644 --- a/src/net/eathena/inventoryhandler.cpp +++ b/src/net/eathena/inventoryhandler.cpp @@ -572,7 +572,7 @@ void InventoryHandler::selectEgg(const Item *const item) const int InventoryHandler::convertFromServerSlot(const int serverSlot) const { - if (serverSlot < 0 || serverSlot >= 17) + if (serverSlot < 0 || serverSlot > 17) return 0; return CAST_S32(EQUIP_CONVERT[serverSlot]); diff --git a/src/net/eathena/packetsin.inc b/src/net/eathena/packetsin.inc index 443c583c0..2a8e26264 100644 --- a/src/net/eathena/packetsin.inc +++ b/src/net/eathena/packetsin.inc @@ -84,6 +84,7 @@ packet(SMSG_CHAR_DELETE_SUCCEEDED, 0x006f, 2, &Ea::CharServerRecv::pro packet(SMSG_CHAR_LOGIN, 0x006b, -1, &CharServerRecv::processCharLogin, 0); packet(SMSG_CHAR_LOGIN2, 0x082d, -1, &CharServerRecv::processCharLogin2, 0); packet(SMSG_CHAR_LOGIN_ERROR, 0x006c, 3, &Ea::CharServerRecv::processCharLoginError, 0); +packet(SMSG_CHAR_PASSWORD_RESPONSE, 0x0062, 3, &LoginRecv::processCharPasswordResponse, 0); packet(SMSG_CHAR_MAP_INFO, 0x0071, 28, &CharServerRecv::processCharMapInfo, 0); packet(SMSG_CHAR_PINCODE_STATUS, 0x08b9, 12, &CharServerRecv::processPincodeStatus, 0); packet(SMSG_CHAR_PINCODE_MAKE_STATUS, 0x08bb, 8, &CharServerRecv::processPincodeMakeStatus, 0); @@ -1006,9 +1007,6 @@ if (serverVersion > 0) packet2(SMSG_QUEST_LIST2, 0x0b23, -1, &QuestRecv::processAddQuests2, 0); packet2(SMSG_QUEST_ADD2, 0x0b24, 23, &QuestRecv::processAddQuest2, 0); packet2(SMSG_PLAYER_ATTRS, 0x0b25, -1, &PlayerRecv::processPlayerAttrs, 0); - - // char server - packet2(SMSG_CHAR_PASSWORD_RESPONSE, 0x0062, 3, &LoginRecv::processCharPasswordResponse, 0); } // 20150225 main diff --git a/src/net/tmwa/guildmanager.cpp b/src/net/tmwa/guildmanager.cpp index f00e444db..52c056de6 100644 --- a/src/net/tmwa/guildmanager.cpp +++ b/src/net/tmwa/guildmanager.cpp @@ -234,8 +234,6 @@ void GuildManager::createTab(Guild *const guild) if (mTab == nullptr) { mTab = new EmulateGuildTab(chatWindow); - if (config.getBoolValue("showChatHistory")) - mTab->loadFromLogFile("#Guild"); if (localPlayer != nullptr) localPlayer->addGuild(guild); } diff --git a/src/net/tmwa/inventoryhandler.cpp b/src/net/tmwa/inventoryhandler.cpp index a438c2602..076d365f1 100644 --- a/src/net/tmwa/inventoryhandler.cpp +++ b/src/net/tmwa/inventoryhandler.cpp @@ -34,14 +34,13 @@ #include "debug.h" -// missing EQUIP_RING1_SLOT const EquipSlot::Type EQUIP_CONVERT[] = { EquipSlot::PROJECTILE_SLOT, // 0 0 EquipSlot::FEET_SLOT, // 1 SPRITE_HAIR EquipSlot::LEGS_SLOT, // 2 SPRITE_WEAPON EquipSlot::TORSO_SLOT, // 3 SPRITE_HEAD_BOTTOM - EquipSlot::PROJECTILE_SLOT, // 4 0 + EquipSlot::RING1_SLOT, // 4 SPRITE_HEAD_TOP EquipSlot::NECK_SLOT, // 5 SPRITE_RING EquipSlot::PROJECTILE_SLOT, // 6 0 EquipSlot::HEAD_SLOT, // 7 SPRITE_CLOTHES_COLOR diff --git a/src/net/tmwa/loginrecv.cpp b/src/net/tmwa/loginrecv.cpp index a11888b9d..aa9b89fb9 100644 --- a/src/net/tmwa/loginrecv.cpp +++ b/src/net/tmwa/loginrecv.cpp @@ -62,34 +62,31 @@ void LoginRecv::processServerVersion(Net::MessageIn &msg) const uint8_t b2 = msg.readUInt8("b2"); const uint8_t b3 = msg.readUInt8("b3"); msg.readUInt8("b4"); + const unsigned int options = msg.readInt32("options"); + + Ea::LoginRecv::mRegistrationEnabled = + ((options & FLAG_REGISTRATION) != 0U); + + serverVersion = 0; + if (b1 == 255) { // old TMWA - const unsigned int options = msg.readInt32("options"); - Ea::LoginRecv::mRegistrationEnabled = - ((options & FLAG_REGISTRATION) != 0U); - serverVersion = 0; tmwServerVersion = 0; } else if (b1 >= 0x0d) { // new TMWA - const unsigned int options = msg.readInt32("options"); - Ea::LoginRecv::mRegistrationEnabled = - ((options & FLAG_REGISTRATION) != 0U); - serverVersion = 0; tmwServerVersion = (b1 << 16) | (b2 << 8) | b3; } else { // eAthena - const unsigned int options = msg.readInt32("options"); - Ea::LoginRecv::mRegistrationEnabled = - ((options & FLAG_REGISTRATION) != 0U); - serverVersion = 0; tmwServerVersion = 0; } + if (tmwServerVersion > 0) - logger->log("Tmw server version: x%06x", tmwServerVersion); + logger->log("TMW server version: 0x%06x", tmwServerVersion); else logger->log("Server without version"); + updateProtocol(); if (client->getState() != State::LOGIN) diff --git a/tools/ci/jobs/mplint.sh b/tools/ci/jobs/mplint.sh index 573cd1c85..60422e5f6 100755 --- a/tools/ci/jobs/mplint.sh +++ b/tools/ci/jobs/mplint.sh @@ -1,29 +1,18 @@ #!/usr/bin/env bash -export CC=gcc -export CXX=g++ - -if [ "$NEWCC" != "" ]; then - export CC="$NEWCC" -fi -if [ "$NEWCXX" != "" ]; then - export CXX="$NEWCXX" -fi +set -e # Fail if any command fails +set -u # Fail if any variable is unset when used export LOGFILE=mplint_po.log - source ./tools/ci/scripts/init.sh -export CXXFLAGS="-std=gnu++11" +rm -rf mplint || true +tools/ci/scripts/retry.sh wget -O mplint-release.zip "$MPLINT_PACKAGE_URL" +unzip mplint-release.zip -do_init +read mplint_commit < mplint-version.txt +printf "Using mplint: %s\n" "$mplint_commit" -rm -rf mplint || true -gitclone https://git.themanaworld.org/mana mplint.git -cd mplint -run_configure_simple -run_make -cd .. echo " " >config.h for task in "$@"; do run_mplint $task diff --git a/tools/ci/scripts/exit.sh b/tools/ci/scripts/exit.sh index 1f13618c1..5c63a1d1b 100755 --- a/tools/ci/scripts/exit.sh +++ b/tools/ci/scripts/exit.sh @@ -1,3 +1,3 @@ #!/usr/bin/env bash -rm $ERRFILE +rm -f "$ERRFILE" diff --git a/tools/ci/scripts/init.sh b/tools/ci/scripts/init.sh index 9512e9b66..ed25a59e8 100755 --- a/tools/ci/scripts/init.sh +++ b/tools/ci/scripts/init.sh @@ -3,7 +3,7 @@ export dir=$(pwd) export ERRFILE=${dir}/logs/${LOGFILE} -rm ${ERRFILE} +rm -f "$ERRFILE" function do_init { $CC --version @@ -104,11 +104,11 @@ function check_error { } function run_configure_simple { - rm $ERRFILE + rm -f "$ERRFILE" echo "autoreconf -i" autoreconf -i 2>$ERRFILE check_error $? - rm $ERRFILE + rm -f "$ERRFILE" echo "./configure $*" ./configure $* 2>$ERRFILE check_error $? @@ -117,14 +117,14 @@ function run_configure_simple { function run_configure { run_configure_simple $* - rm $ERRFILE + rm -f "$ERRFILE" cd po echo "make update-gmo" make update-gmo 2>$ERRFILE check_error $? cd .. - rm $ERRFILE + rm -f "$ERRFILE" cd po echo "make update-po" make update-po 2>$ERRFILE @@ -133,14 +133,14 @@ function run_configure { } function run_cmake { - rm $ERRFILE + rm -f "$ERRFILE" echo "cmake ." cmake . 2>$ERRFILE check_error $? } function run_make { - rm $ERRFILE + rm -f "$ERRFILE" if [ "$JOBS" == "" ]; then export JOBS=2 echo "No JOBS defined" @@ -153,7 +153,7 @@ function run_make { } function run_make_check { - rm $ERRFILE + rm -f "$ERRFILE" if [ "$JOBS" == "" ]; then export JOBS=2 echo "No JOBS defined" @@ -211,7 +211,7 @@ function run_check_warnings { } function run_h { - rm $ERRFILE + rm -f "$ERRFILE" echo "$CC -c -x c++ $* $includes */*/*/*/*.h */*/*/*.h */*/*.h */*.h *.h" $CC -c -x c++ $* $includes */*/*/*/*.h */*/*/*.h */*/*.h */*.h *.h 2>$ERRFILE if [[ -s "$ERRFILE" ]]; then @@ -221,7 +221,7 @@ function run_h { } function run_tarball { - rm $ERRFILE + rm -f "$ERRFILE" echo "make dist-xz" make dist-xz 2>$ERRFILE check_error $? @@ -234,14 +234,17 @@ function run_tarball { } function run_mplint { - rm $ERRFILE - echo "mplint/src/mplint $*" - mplint/src/mplint "$@" \ - | grep -v \ - -e "src/unittests/doctest.h" \ - -e "src/unittests/catch.hpp" \ - -e "src/debug/" \ - > "$ERRFILE" + rm -f "$ERRFILE" + echo "\$ ./mplint $*" + + ./mplint "$@" > "$ERRFILE.unfiltered" + + # if grep does not find any messages, it exits non-zero + grep -v \ + -e "src/unittests/doctest.h" \ + -e "src/unittests/catch.hpp" \ + -e "src/debug/" \ + < "$ERRFILE.unfiltered" > "$ERRFILE" || true run_check_warnings } |