summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2018-03-07 23:32:25 +0300
committerAndrei Karas <akaras@inbox.ru>2018-03-07 23:32:25 +0300
commit0d9e625499c18a4eaf79d38dfb1ef6abf0c553bd (patch)
tree1e4c29a0de3697946060410e41910f88bcc5b979
parentb6cd136e3edf9d5c0eaaef47118ff1a72d7b0c75 (diff)
downloadmv-0d9e625499c18a4eaf79d38dfb1ef6abf0c553bd.tar.gz
mv-0d9e625499c18a4eaf79d38dfb1ef6abf0c553bd.tar.bz2
mv-0d9e625499c18a4eaf79d38dfb1ef6abf0c553bd.tar.xz
mv-0d9e625499c18a4eaf79d38dfb1ef6abf0c553bd.zip
Add support for set new pincode.
Add pincode dialog and widget.
-rw-r--r--data/graphics/gui/CMakeLists.txt1
-rw-r--r--data/graphics/gui/Makefile.am1
-rw-r--r--data/graphics/gui/pin.xml6
-rw-r--r--data/themes/golden-delicious/CMakeLists.txt1
-rw-r--r--data/themes/golden-delicious/Makefile.am1
-rw-r--r--data/themes/golden-delicious/pin.xml7
-rw-r--r--data/themes/jewelry-simple/CMakeLists.txt1
-rw-r--r--data/themes/jewelry-simple/Makefile.am1
-rw-r--r--data/themes/jewelry-simple/pin.xml7
-rw-r--r--data/themes/jewelry/CMakeLists.txt1
-rw-r--r--data/themes/jewelry/Makefile.am1
-rw-r--r--data/themes/jewelry/pin.xml7
-rw-r--r--src/CMakeLists.txt11
-rw-r--r--src/Makefile.am11
-rw-r--r--src/enums/gui/pincodestate.h37
-rw-r--r--src/gui/widgets/pincode.cpp198
-rw-r--r--src/gui/widgets/pincode.h76
-rw-r--r--src/gui/widgets/textfield.cpp5
-rw-r--r--src/gui/widgets/textfield.h2
-rw-r--r--src/gui/windows/charselectdialog.cpp1
-rw-r--r--src/gui/windows/pincodedialog.cpp135
-rw-r--r--src/gui/windows/pincodedialog.h67
-rw-r--r--src/listeners/newpincodelistener.cpp48
-rw-r--r--src/listeners/newpincodelistener.h (renamed from src/listeners/pincodelistener.h)14
-rw-r--r--src/listeners/newpincoderetrylistener.cpp (renamed from src/listeners/pincodelistener.cpp)18
-rw-r--r--src/listeners/newpincoderetrylistener.h42
-rw-r--r--src/net/charserverhandler.h3
-rw-r--r--src/net/eathena/charserverhandler.cpp11
-rw-r--r--src/net/eathena/charserverhandler.h3
-rw-r--r--src/net/eathena/charserverrecv.cpp8
-rw-r--r--src/net/tmwa/charserverhandler.h3
-rw-r--r--src/pincodemanager.cpp88
-rw-r--r--src/pincodemanager.h25
-rw-r--r--src/progs/manaplus/client.cpp1
34 files changed, 793 insertions, 49 deletions
diff --git a/data/graphics/gui/CMakeLists.txt b/data/graphics/gui/CMakeLists.txt
index 61151ab03..aca2b43cd 100644
--- a/data/graphics/gui/CMakeLists.txt
+++ b/data/graphics/gui/CMakeLists.txt
@@ -49,6 +49,7 @@ SET (FILES
ok.xml
onlinebrowserbox.xml
outfits.xml
+ pin.xml
playerbox.xml
playerboxselected.xml
popup.xml
diff --git a/data/graphics/gui/Makefile.am b/data/graphics/gui/Makefile.am
index 8a07b77e6..049d80d95 100644
--- a/data/graphics/gui/Makefile.am
+++ b/data/graphics/gui/Makefile.am
@@ -52,6 +52,7 @@ gui_DATA = \
ok.xml \
onlinebrowserbox.xml \
outfits.xml \
+ pin.xml \
playerbox.xml \
playerboxselected.xml \
popup.xml \
diff --git a/data/graphics/gui/pin.xml b/data/graphics/gui/pin.xml
new file mode 100644
index 000000000..09320030a
--- /dev/null
+++ b/data/graphics/gui/pin.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<skinset name="Default" image="window.png">
+ <widget type="Window">
+ <option name="padding" value="0" />
+ </widget>
+</skinset>
diff --git a/data/themes/golden-delicious/CMakeLists.txt b/data/themes/golden-delicious/CMakeLists.txt
index 22d589ce1..2fc2b80f4 100644
--- a/data/themes/golden-delicious/CMakeLists.txt
+++ b/data/themes/golden-delicious/CMakeLists.txt
@@ -64,6 +64,7 @@ SET (FILES
ok.xml
onlinebrowserbox.xml
outfits.xml
+ pin.xml
playerboxselected.xml
playerbox.xml
popupbrowserbox_high.xml
diff --git a/data/themes/golden-delicious/Makefile.am b/data/themes/golden-delicious/Makefile.am
index d1726b522..0dcfcb358 100644
--- a/data/themes/golden-delicious/Makefile.am
+++ b/data/themes/golden-delicious/Makefile.am
@@ -67,6 +67,7 @@ gui_DATA = \
ok.xml \
onlinebrowserbox.xml \
outfits.xml \
+ pin.xml \
playerbox.xml \
playerboxselected.xml \
popup.xml \
diff --git a/data/themes/golden-delicious/pin.xml b/data/themes/golden-delicious/pin.xml
new file mode 100644
index 000000000..b6b922852
--- /dev/null
+++ b/data/themes/golden-delicious/pin.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<skinset name="Default" image="window.png">
+ <widget type="Window">
+ <option name="padding" value="8" />
+ <option name="spacing" value="8" />
+ </widget>
+</skinset>
diff --git a/data/themes/jewelry-simple/CMakeLists.txt b/data/themes/jewelry-simple/CMakeLists.txt
index 3c1f5a92c..104b95ba9 100644
--- a/data/themes/jewelry-simple/CMakeLists.txt
+++ b/data/themes/jewelry-simple/CMakeLists.txt
@@ -63,6 +63,7 @@ SET (FILES
ok.xml
onlinebrowserbox.xml
outfits.xml
+ pin.xml
playerbox.xml
playerboxselected.xml
popup.xml
diff --git a/data/themes/jewelry-simple/Makefile.am b/data/themes/jewelry-simple/Makefile.am
index a32b82158..f3c050ac6 100644
--- a/data/themes/jewelry-simple/Makefile.am
+++ b/data/themes/jewelry-simple/Makefile.am
@@ -66,6 +66,7 @@ gui_DATA = \
ok.xml \
onlinebrowserbox.xml \
outfits.xml \
+ pin.xml \
playerbox.xml \
playerboxselected.xml \
popup.xml \
diff --git a/data/themes/jewelry-simple/pin.xml b/data/themes/jewelry-simple/pin.xml
new file mode 100644
index 000000000..267b16969
--- /dev/null
+++ b/data/themes/jewelry-simple/pin.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<skinset name="Default" image="window.png">
+ <widget type="Window">
+ <option name="padding" value="4" />
+ <option name="spacing" value="8" />
+ </widget>
+</skinset>
diff --git a/data/themes/jewelry/CMakeLists.txt b/data/themes/jewelry/CMakeLists.txt
index 193a2ea3e..afd0cc128 100644
--- a/data/themes/jewelry/CMakeLists.txt
+++ b/data/themes/jewelry/CMakeLists.txt
@@ -63,6 +63,7 @@ SET (FILES
ok.xml
onlinebrowserbox.xml
outfits.xml
+ pin.xml
playerbox.xml
playerboxselected.xml
popup.xml
diff --git a/data/themes/jewelry/Makefile.am b/data/themes/jewelry/Makefile.am
index 3e4921af6..4a7f5caa2 100644
--- a/data/themes/jewelry/Makefile.am
+++ b/data/themes/jewelry/Makefile.am
@@ -66,6 +66,7 @@ gui_DATA = \
ok.xml \
onlinebrowserbox.xml \
outfits.xml \
+ pin.xml \
playerbox.xml \
playerboxselected.xml \
popup.xml \
diff --git a/data/themes/jewelry/pin.xml b/data/themes/jewelry/pin.xml
new file mode 100644
index 000000000..d417b3c52
--- /dev/null
+++ b/data/themes/jewelry/pin.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<skinset name="Default" image="window.png">
+ <widget type="Window">
+ <option name="padding" value="4" />
+ <option name="spacing" value="10" />
+ </widget>
+</skinset>
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index fdf5e7e4f..e2b00849c 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -241,6 +241,8 @@ SET(SRCS
gui/models/serverslistmodel.h
gui/widgets/passwordfield.cpp
gui/widgets/passwordfield.h
+ gui/widgets/pincode.cpp
+ gui/widgets/pincode.h
gui/widgets/playerbox.cpp
gui/widgets/playerbox.h
gui/widgets/popup.cpp
@@ -415,6 +417,8 @@ SET(SRCS
gui/windows/okdialog.h
gui/windows/outfitwindow.cpp
gui/windows/outfitwindow.h
+ gui/windows/pincodedialog.cpp
+ gui/windows/pincodedialog.h
gui/windows/textcommandeditor.cpp
gui/windows/textcommandeditor.h
gui/onlineplayer.h
@@ -1452,6 +1456,7 @@ SET(SRCS
enums/gui/gradienttype.h
enums/gui/itemamountwindowusage.h
enums/gui/orientation.h
+ enums/gui/pincodestate.h
enums/gui/progresscolorid.h
enums/gui/serverdialogdonwloadstatus.h
enums/gui/shoplistboxtype.h
@@ -1540,8 +1545,10 @@ SET(SRCS
listeners/buyingstoremodelistener.h
listeners/buyingstoreslotslistener.cpp
listeners/buyingstoreslotslistener.h
- listeners/pincodelistener.cpp
- listeners/pincodelistener.h
+ listeners/newpincodelistener.cpp
+ listeners/newpincodelistener.h
+ listeners/newpincoderetrylistener.cpp
+ listeners/newpincoderetrylistener.h
listeners/shoprenamelistener.cpp
listeners/shoprenamelistener.h
listeners/skillwarplistener.cpp
diff --git a/src/Makefile.am b/src/Makefile.am
index 23ffab297..e6dd49550 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -217,6 +217,7 @@ BASE_SRC += client.h \
enums/gui/gradienttype.h \
enums/gui/itemamountwindowusage.h \
enums/gui/orientation.h \
+ enums/gui/pincodestate.h \
enums/gui/progresscolorid.h \
enums/gui/serverdialogdonwloadstatus.h \
enums/gui/shoplistboxtype.h \
@@ -350,6 +351,8 @@ BASE_SRC += client.h \
gui/models/serverslistmodel.h \
gui/widgets/passwordfield.cpp \
gui/widgets/passwordfield.h \
+ gui/widgets/pincode.cpp \
+ gui/widgets/pincode.h \
gui/widgets/popup.cpp \
gui/widgets/popup.h \
gui/widgets/popuplist.cpp \
@@ -1339,6 +1342,8 @@ SRC = ${BASE_SRC} \
gui/windows/npcselldialog.h \
gui/windows/outfitwindow.cpp \
gui/windows/outfitwindow.h \
+ gui/windows/pincodedialog.cpp \
+ gui/windows/pincodedialog.h \
gui/windows/textcommandeditor.cpp \
gui/windows/textcommandeditor.h \
gui/setupinputpages.cpp \
@@ -1844,8 +1849,10 @@ SRC += gui/windows/bankwindow.cpp \
listeners/buyingstoremodelistener.h \
listeners/buyingstoreslotslistener.cpp \
listeners/buyingstoreslotslistener.h \
- listeners/pincodelistener.cpp \
- listeners/pincodelistener.h \
+ listeners/newpincodelistener.cpp \
+ listeners/newpincodelistener.h \
+ listeners/newpincoderetrylistener.cpp \
+ listeners/newpincoderetrylistener.h \
listeners/requestadoptchildlistener.h \
listeners/shoprenamelistener.cpp \
listeners/shoprenamelistener.h \
diff --git a/src/enums/gui/pincodestate.h b/src/enums/gui/pincodestate.h
new file mode 100644
index 000000000..fdb5b7ab7
--- /dev/null
+++ b/src/enums/gui/pincodestate.h
@@ -0,0 +1,37 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ * Copyright (C) 2011-2018 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus 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 ENUMS_GUI_PINCODESTATE_H
+#define ENUMS_GUI_PINCODESTATE_H
+
+#include "enums/simpletypes/enumdefines.h"
+
+enumStart(PincodeState)
+{
+ None = 0,
+ Ask,
+ Create,
+ Change,
+}
+enumEnd(PincodeState);
+
+#endif // ENUMS_GUI_PINCODESTATE_H
diff --git a/src/gui/widgets/pincode.cpp b/src/gui/widgets/pincode.cpp
new file mode 100644
index 000000000..d05684056
--- /dev/null
+++ b/src/gui/widgets/pincode.cpp
@@ -0,0 +1,198 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2018 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus 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 "gui/widgets/pincode.h"
+
+#include "gui/gui.h"
+#include "gui/skin.h"
+
+#include "gui/widgets/button.h"
+#include "gui/widgets/textfield.h"
+
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+#include "debug.h"
+
+Skin *Pincode::mSkin = nullptr;
+int Pincode::mInstances = 0;
+
+Pincode::Pincode(const Widget2 *const widget,
+ TextField *const textField) :
+ Container(widget),
+ ActionListener(),
+ WidgetListener(),
+ mButtons(),
+ mText(),
+ mTextField(textField),
+ mPadding(0),
+ mSpacing(2)
+{
+ mAllowLogic = false;
+ setOpaque(Opaque_false);
+
+ if (mInstances == 0)
+ {
+ if (theme != nullptr)
+ {
+ mSkin = theme->load("pin.xml",
+ "",
+ true,
+ Theme::getThemePath());
+ }
+ }
+ mInstances ++;
+
+ if (mSkin != nullptr)
+ {
+ mPadding = mSkin->getPadding();
+ mSpacing = mSkin->getOption("spacing", 2);
+ }
+ setSelectable(false);
+
+ addButtons();
+ adjustSize();
+}
+
+Pincode::~Pincode()
+{
+ if (mWindow != nullptr)
+ mWindow->removeWidgetListener(this);
+
+ if (gui != nullptr)
+ gui->removeDragged(this);
+
+ mInstances --;
+ if (mInstances == 0)
+ {
+ if (theme != nullptr)
+ theme->unload(mSkin);
+ }
+}
+
+void Pincode::addButtons()
+{
+ int buttonWidth = 0;
+ int buttonHeight = 0;
+ for (int f = 0; f < 10; f ++)
+ {
+ const std::string str = toString(f);
+ mButtons[f] = new Button(this, str, str, this);
+ mButtons[f]->adjustSize();
+ const Rect &rect = mButtons[f]->getDimension();
+ if (rect.width > buttonWidth)
+ buttonWidth = rect.width;
+ if (rect.height > buttonHeight)
+ buttonHeight = rect.height;
+ add(mButtons[f]);
+ }
+ int x = 0;
+ int y = 0;
+ const int xSize = buttonWidth + mSpacing;
+ const int ySize = buttonHeight + mSpacing;
+ for (int f = 0; f < 10; f ++)
+ {
+ mButtons[f]->setPosition(mPadding + x * xSize,
+ mPadding + y * ySize);
+ x ++;
+ if (x > 2)
+ {
+ x = 0;
+ y ++;
+ }
+ }
+ mButtons[10] = new Button(this,
+ // TRANSLATORS: clear pin code button
+ _("Clear"),
+ "clear",
+ this);
+ mButtons[10]->adjustSize();
+ add(mButtons[10]);
+ mButtons[10]->setPosition(mPadding + xSize,
+ mPadding + 3 * ySize);
+
+ mButtonWidth = buttonWidth;
+ mButtonHeight = buttonHeight;
+}
+
+void Pincode::adjustSize()
+{
+ const int pad2 = mPadding * 2;
+ setSize(pad2 + 3 * mButtonWidth + 2 * mSpacing,
+ pad2 + 4 * mButtonHeight + 3 * mSpacing);
+}
+
+void Pincode::finalCleanup()
+{
+ mSkin = nullptr;
+}
+
+void Pincode::action(const ActionEvent &event)
+{
+ if (event.getId() == "clear")
+ {
+ mText.clear();
+ mTextField->setText(mText);
+ mTextField->signalEvent();
+ return;
+ }
+ if (mText.size() >= 4)
+ return;
+ Widget *const eventSrc = event.getSource();
+ for (int f = 0; f < 10; f ++)
+ {
+ if (mButtons[f] == eventSrc)
+ {
+ const std::string str = toString(f);
+ mText.append(str);
+ mTextField->setText(mText);
+ mTextField->signalEvent();
+ return;
+ }
+ }
+}
+
+void Pincode::shuffle(uint32_t seed)
+{
+ int tab[10];
+ const uint32_t multiplier = 0x3498;
+ const uint32_t baseSeed = 0x881234;
+ int k = 2;
+
+ for (size_t f = 0; f < 10; f ++)
+ tab[f] = f;
+ for (size_t f = 1; f < 10; f ++)
+ {
+ seed = baseSeed + seed * multiplier;
+ const size_t pos = seed % k;
+ if (f != pos)
+ {
+ const int tmp = tab[f];
+ tab[f] = tab[pos];
+ tab[pos] = tmp;
+ }
+ k = k + 1;
+ }
+ for (size_t f = 0; f < 10; f ++)
+ {
+ const std::string str = toString(tab[f]);
+ mButtons[f]->setCaption(str);
+ }
+}
diff --git a/src/gui/widgets/pincode.h b/src/gui/widgets/pincode.h
new file mode 100644
index 000000000..e707b5915
--- /dev/null
+++ b/src/gui/widgets/pincode.h
@@ -0,0 +1,76 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2018 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus 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 GUI_WIDGETS_PINCODE_H
+#define GUI_WIDGETS_PINCODE_H
+
+#include "gui/fonts/textchunk.h"
+
+#include "gui/widgets/container.h"
+
+#include "listeners/actionlistener.h"
+#include "listeners/widgetlistener.h"
+
+#include "render/graphics.h"
+
+#include "localconsts.h"
+
+class Button;
+class Skin;
+class TextField;
+
+class Pincode final : public Container,
+ public ActionListener,
+ public WidgetListener
+{
+ public:
+ Pincode(const Widget2 *const widget,
+ TextField *const textField);
+
+ A_DELETE_COPY(Pincode)
+
+ ~Pincode() override final;
+
+ void adjustSize();
+
+ void action(const ActionEvent &event) override final;
+
+ void shuffle(uint32_t seed);
+
+ static Skin *mSkin;
+
+ static int mInstances;
+
+ static void finalCleanup();
+
+ protected:
+ void addButtons();
+
+ private:
+ Button *mButtons[11];
+ std::string mText;
+ TextField *mTextField;
+ int mPadding;
+ int mSpacing;
+ int mButtonWidth;
+ int mButtonHeight;
+};
+
+#endif // GUI_WIDGETS_PINCODE_H
diff --git a/src/gui/widgets/textfield.cpp b/src/gui/widgets/textfield.cpp
index 6012f6d28..b80404c73 100644
--- a/src/gui/widgets/textfield.cpp
+++ b/src/gui/widgets/textfield.cpp
@@ -838,3 +838,8 @@ void TextField::setWindow(Widget *const widget)
Widget2::setWindow(widget);
}
}
+
+void TextField::signalEvent()
+{
+ distributeActionEvent();
+}
diff --git a/src/gui/widgets/textfield.h b/src/gui/widgets/textfield.h
index e4ac1b173..720a82906 100644
--- a/src/gui/widgets/textfield.h
+++ b/src/gui/widgets/textfield.h
@@ -241,6 +241,8 @@ class TextField notfinal : public Widget,
void setWindow(Widget *const widget) override final;
+ void signalEvent();
+
protected:
void drawCaret(Graphics* graphics, int x) A_NONNULL(2);
diff --git a/src/gui/windows/charselectdialog.cpp b/src/gui/windows/charselectdialog.cpp
index f526f133c..817ecd908 100644
--- a/src/gui/windows/charselectdialog.cpp
+++ b/src/gui/windows/charselectdialog.cpp
@@ -26,7 +26,6 @@
#include "configuration.h"
#include "listeners/charrenamelistener.h"
-#include "listeners/pincodelistener.h"
#include "gui/windows/charcreatedialog.h"
#include "gui/windows/chardeleteconfirm.h"
diff --git a/src/gui/windows/pincodedialog.cpp b/src/gui/windows/pincodedialog.cpp
new file mode 100644
index 000000000..b23ab17d1
--- /dev/null
+++ b/src/gui/windows/pincodedialog.cpp
@@ -0,0 +1,135 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2018 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus 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 "gui/windows/pincodedialog.h"
+
+#include "pincodemanager.h"
+
+#include "input/keyboardconfig.h"
+
+#include "gui/widgets/button.h"
+#include "gui/widgets/label.h"
+#include "gui/widgets/passwordfield.h"
+#include "gui/widgets/pincode.h"
+
+#include "utils/gettext.h"
+
+#include "gui/fonts/font.h"
+
+#include "debug.h"
+
+int PincodeDialog::instances = 0;
+
+PincodeDialog::PincodeDialog(const std::string &restrict title,
+ const std::string &restrict msg,
+ uint32_t seed,
+ Window *const parent) :
+ Window(title, Modal_true, parent, "pincode.xml"),
+ ActionListener(),
+ mPasswordField(new PasswordField(this, std::string())),
+ mPincode(new Pincode(this, mPasswordField)),
+ // TRANSLATORS: text dialog button
+ mOkButton(new Button(this, _("OK"), "OK", this)),
+ mEnabledKeyboard(keyboard.isEnabled())
+{
+ setStickyButtonLock(true);
+
+ keyboard.setEnabled(false);
+
+ Label *const textLabel = new Label(this, msg);
+ // TRANSLATORS: text dialog button
+ Button *const cancelButton = new Button(this, _("Cancel"), "CANCEL", this);
+
+ place(0, 0, textLabel, 4, 1);
+ place(0, 1, mPincode, 4, 1);
+ place(0, 2, mPasswordField, 4, 1);
+ place(2, 3, mOkButton, 1, 1);
+ place(3, 3, cancelButton, 1, 1);
+
+ mPasswordField->setEnabled(false);
+ mPasswordField->setActionEventId("pincode");
+ mPasswordField->addActionListener(this);
+
+ mPincode->shuffle(seed);
+ int width = getFont()->getWidth(title);
+ if (width < textLabel->getWidth())
+ width = textLabel->getWidth();
+ reflowLayout(CAST_S32(width + 20), 0);
+ updateButtons();
+}
+
+void PincodeDialog::postInit()
+{
+ Window::postInit();
+ if (getParent() != nullptr)
+ {
+ setLocationRelativeTo(getParent());
+ getParent()->moveToTop(this);
+ }
+ setVisible(Visible_true);
+ requestModalFocus();
+ mPincode->requestFocus();
+
+ instances++;
+}
+
+PincodeDialog::~PincodeDialog()
+{
+ instances--;
+ pincodeManager.clearDialog(this);
+}
+
+void PincodeDialog::action(const ActionEvent &event)
+{
+ const std::string &eventId = event.getId();
+ if (eventId == "pincode")
+ {
+ updateButtons();
+ return;
+ }
+ if (eventId == "CANCEL")
+ setActionEventId("~" + getActionEventId());
+
+ distributeActionEvent();
+ close();
+}
+
+const std::string &PincodeDialog::getMsg() const
+{
+ return mPasswordField->getText();
+}
+
+void PincodeDialog::close()
+{
+ keyboard.setEnabled(mEnabledKeyboard);
+ scheduleDelete();
+}
+
+void PincodeDialog::updateButtons()
+{
+ if (mPasswordField->getText().size() == 4)
+ {
+ mOkButton->setEnabled(true);
+ }
+ else
+ {
+ mOkButton->setEnabled(false);
+ }
+}
diff --git a/src/gui/windows/pincodedialog.h b/src/gui/windows/pincodedialog.h
new file mode 100644
index 000000000..f453f67d7
--- /dev/null
+++ b/src/gui/windows/pincodedialog.h
@@ -0,0 +1,67 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2018 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus 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 GUI_WINDOWS_PINCODEDIALOG_H
+#define GUI_WINDOWS_PINCODEDIALOG_H
+
+#include "gui/widgets/window.h"
+
+#include "listeners/actionlistener.h"
+
+class Button;
+class PasswordField;
+class Pincode;
+
+class PincodeDialog final : public Window,
+ public ActionListener
+{
+ public:
+ PincodeDialog(const std::string &restrict title,
+ const std::string &restrict msg,
+ uint32_t seed,
+ Window *const parent);
+
+ A_DELETE_COPY(PincodeDialog)
+
+ ~PincodeDialog() override final;
+
+ void postInit() override final;
+
+ void action(const ActionEvent &event) override final;
+
+ const std::string &getMsg() const A_WARN_UNUSED;
+
+ static bool isActive() noexcept2 A_WARN_UNUSED
+ { return instances != 0; }
+
+ void close() override final;
+
+ void updateButtons();
+
+ private:
+ static int instances;
+
+ PasswordField *mPasswordField;
+ Pincode *mPincode;
+ Button *mOkButton;
+ bool mEnabledKeyboard;
+};
+
+#endif // GUI_WINDOWS_PINCODEDIALOG_H
diff --git a/src/listeners/newpincodelistener.cpp b/src/listeners/newpincodelistener.cpp
new file mode 100644
index 000000000..ce5a32c90
--- /dev/null
+++ b/src/listeners/newpincodelistener.cpp
@@ -0,0 +1,48 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2018 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus 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 "listeners/newpincodelistener.h"
+
+#include "client.h"
+#include "pincodemanager.h"
+
+#include "gui/windows/pincodedialog.h"
+
+#include "debug.h"
+
+NewPincodeListener newPincodeListener;
+
+void NewPincodeListener::action(const ActionEvent &event)
+{
+ if (event.getId() == "ok")
+ {
+ const PincodeDialog *const dialog = dynamic_cast<PincodeDialog*>(
+ event.getSource());
+ if (dialog != nullptr)
+ {
+ const std::string pincode = dialog->getMsg();
+ pincodeManager.setNewPincode(pincode);
+ }
+ }
+ else
+ {
+ client->setState(State::SWITCH_LOGIN);
+ }
+}
diff --git a/src/listeners/pincodelistener.h b/src/listeners/newpincodelistener.h
index f32bf4ded..f010befc8 100644
--- a/src/listeners/pincodelistener.h
+++ b/src/listeners/newpincodelistener.h
@@ -18,25 +18,25 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef LISTENERS_PINCODELISTENER_H
-#define LISTENERS_PINCODELISTENER_H
+#ifndef LISTENERS_NEWPINCODELISTENER_H
+#define LISTENERS_NEWPINCODELISTENER_H
#include "listeners/actionlistener.h"
#include "localconsts.h"
-class PincodeListener final : public ActionListener
+class NewPincodeListener final : public ActionListener
{
public:
- PincodeListener() :
+ NewPincodeListener() :
ActionListener()
{ }
- A_DELETE_COPY(PincodeListener)
+ A_DELETE_COPY(NewPincodeListener)
void action(const ActionEvent &event) override final;
};
-extern PincodeListener pincodeListener;
+extern NewPincodeListener newPincodeListener;
-#endif // LISTENERS_PINCODELISTENER_H
+#endif // LISTENERS_NEWPINCODELISTENER_H
diff --git a/src/listeners/pincodelistener.cpp b/src/listeners/newpincoderetrylistener.cpp
index 5f810513d..d98b9bd84 100644
--- a/src/listeners/pincodelistener.cpp
+++ b/src/listeners/newpincoderetrylistener.cpp
@@ -18,23 +18,15 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "listeners/pincodelistener.h"
+#include "listeners/newpincoderetrylistener.h"
-#include "net/charserverhandler.h"
-
-#include "gui/windows/editdialog.h"
+#include "pincodemanager.h"
#include "debug.h"
-PincodeListener pincodeListener;
+NewPincodeRetryListener newPincodeRetryListener;
-void PincodeListener::action(const ActionEvent &event)
+void NewPincodeRetryListener::action(const ActionEvent &event A_UNUSED)
{
- const EditDialog *const dialog = dynamic_cast<EditDialog*>(
- event.getSource());
- if (dialog != nullptr)
- {
- const std::string pincode = dialog->getMsg();
- charServerHandler->setNewPincode(pincode);
- }
+ pincodeManager.updateState();
}
diff --git a/src/listeners/newpincoderetrylistener.h b/src/listeners/newpincoderetrylistener.h
new file mode 100644
index 000000000..cbb1e611d
--- /dev/null
+++ b/src/listeners/newpincoderetrylistener.h
@@ -0,0 +1,42 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2018 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus 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 LISTENERS_NEWPINCODERETRYLISTENER_H
+#define LISTENERS_NEWPINCODERETRYLISTENER_H
+
+#include "listeners/actionlistener.h"
+
+#include "localconsts.h"
+
+class NewPincodeRetryListener final : public ActionListener
+{
+ public:
+ NewPincodeRetryListener() :
+ ActionListener()
+ { }
+
+ A_DELETE_COPY(NewPincodeRetryListener)
+
+ void action(const ActionEvent &event) override final;
+};
+
+extern NewPincodeRetryListener newPincodeRetryListener;
+
+#endif // LISTENERS_NEWPINCODERETRYLISTENER_H
diff --git a/src/net/charserverhandler.h b/src/net/charserverhandler.h
index 8c41db2ad..56728a58f 100644
--- a/src/net/charserverhandler.h
+++ b/src/net/charserverhandler.h
@@ -87,7 +87,8 @@ class CharServerHandler notfinal
virtual void clear() const = 0;
- virtual void setNewPincode(const std::string &pin) const = 0;
+ virtual void setNewPincode(const BeingId accountId,
+ const std::string &pin) const = 0;
virtual void changeSlot(const int oldSlot,
const int newSlot) const = 0;
diff --git a/src/net/eathena/charserverhandler.cpp b/src/net/eathena/charserverhandler.cpp
index e98f963e4..a62c79c3b 100644
--- a/src/net/eathena/charserverhandler.cpp
+++ b/src/net/eathena/charserverhandler.cpp
@@ -198,13 +198,12 @@ void CharServerHandler::setCharCreateDialog(CharCreateDialog *const window)
mCharCreateDialog->setDefaultGender(token.sex);
}
-void CharServerHandler::setNewPincode(const std::string &pin A_UNUSED) const
+void CharServerHandler::setNewPincode(const BeingId accountId,
+ const std::string &pin) const
{
-// here need ecript pin with mPinSeed and pin values.
-
-// createOutPacket(CMSG_CHAR_CREATE_PIN);
-// outMsg.writeBeingId(mPinAccountId, "account id");
-// outMsg.writeString(pin, 4, "encrypted pin");
+ createOutPacket(CMSG_CHAR_CREATE_PIN);
+ outMsg.writeBeingId(accountId, "account id");
+ outMsg.writeString(pin, 4, "encrypted pin");
}
void CharServerHandler::renameCharacter(const BeingId id,
diff --git a/src/net/eathena/charserverhandler.h b/src/net/eathena/charserverhandler.h
index e86e03721..9e02dce1f 100644
--- a/src/net/eathena/charserverhandler.h
+++ b/src/net/eathena/charserverhandler.h
@@ -62,7 +62,8 @@ class CharServerHandler final : public Ea::CharServerHandler
void connect() const override final;
- void setNewPincode(const std::string &pin) const override final;
+ void setNewPincode(const BeingId accountId,
+ const std::string &pin) const override final;
/**
* Sets the character create dialog. The handler will clean up this
diff --git a/src/net/eathena/charserverrecv.cpp b/src/net/eathena/charserverrecv.cpp
index 3e69005e3..6d5fd63ca 100644
--- a/src/net/eathena/charserverrecv.cpp
+++ b/src/net/eathena/charserverrecv.cpp
@@ -347,7 +347,7 @@ void CharServerRecv::processChangeMapServer(Net::MessageIn &msg)
void CharServerRecv::processPincodeStatus(Net::MessageIn &msg)
{
- pincodeManager.setSeed(msg.readInt32("pincode seed"));
+ pincodeManager.setSeed(msg.readUInt32("pincode seed"));
pincodeManager.setAccountId(msg.readBeingId("account id"));
const uint16_t state = CAST_U16(msg.readInt16("state"));
switch (state)
@@ -356,16 +356,16 @@ void CharServerRecv::processPincodeStatus(Net::MessageIn &msg)
pincodeManager.pinOk();
break;
case 1: // ask for pin
- pincodeManager.askPin();
+ pincodeManager.setState(PincodeState::Ask);
break;
case 2: // create new pin
case 4: // create new pin?
{
- pincodeManager.createNewPin();
+ pincodeManager.setState(PincodeState::Create);
break;
}
case 3: // pin must be changed
- pincodeManager.changePin();
+ pincodeManager.setState(PincodeState::Change);
break;
case 8: // pincode was incorrect
case 5: // client show error?
diff --git a/src/net/tmwa/charserverhandler.h b/src/net/tmwa/charserverhandler.h
index 6d2051a63..51bf08b84 100644
--- a/src/net/tmwa/charserverhandler.h
+++ b/src/net/tmwa/charserverhandler.h
@@ -62,7 +62,8 @@ class CharServerHandler final : public Ea::CharServerHandler
void connect() const override final;
- void setNewPincode(const std::string &pin A_UNUSED) const
+ void setNewPincode(const BeingId accountId A_UNUSED,
+ const std::string &pin A_UNUSED) const
override final
{ }
diff --git a/src/pincodemanager.cpp b/src/pincodemanager.cpp
index e13671293..4ee8abd3a 100644
--- a/src/pincodemanager.cpp
+++ b/src/pincodemanager.cpp
@@ -20,13 +20,28 @@
#include "pincodemanager.h"
+#include "gui/windows/okdialog.h"
+#include "gui/windows/pincodedialog.h"
+
+#include "gui/widgets/createwidget.h"
+
+#include "listeners/newpincodelistener.h"
+#include "listeners/newpincoderetrylistener.h"
+
+#include "net/charserverhandler.h"
+
+#include "utils/gettext.h"
+
#include "debug.h"
PincodeManager pincodeManager;
PincodeManager::PincodeManager() :
+ mNewPincode(),
mSeed(0U),
- mAccountId(BeingId_zero)
+ mAccountId(BeingId_zero),
+ mDialog(nullptr),
+ mState(PincodeState::None)
{
}
@@ -38,21 +53,84 @@ void PincodeManager::init()
{
mSeed = 0;
mAccountId = BeingId_zero;
+ mState = PincodeState::None;
}
-void PincodeManager::pinOk()
+void PincodeManager::clearDialog(const PincodeDialog *const PincodeDialog)
{
+ if (mDialog == PincodeDialog)
+ mDialog = nullptr;
}
-void PincodeManager::askPin()
+void PincodeManager::updateState()
{
+ switch (mState)
+ {
+ case PincodeState::None:
+ case PincodeState::Ask:
+ case PincodeState::Change:
+ default:
+ break;
+ case PincodeState::Create:
+ CREATEWIDGETV(mDialog, PincodeDialog,
+ // TRANSLATORS: dialog caption
+ _("New pincode"),
+ // TRANSLATORS: dialog label
+ _("Set new pincode"),
+ mSeed,
+ nullptr);
+ mDialog->requestFocus();
+ mDialog->setActionEventId("ok");
+ mDialog->addActionListener(&newPincodeListener);
+ break;
+ }
}
-void PincodeManager::createNewPin()
+void PincodeManager::setNewPincode(const std::string &pincode)
{
+ if (mNewPincode.empty())
+ { // first pincode
+ mNewPincode = pincode;
+ CREATEWIDGETV(mDialog, PincodeDialog,
+ // TRANSLATORS: dialog caption
+ _("New pincode"),
+ // TRANSLATORS: dialog label
+ _("Confirm new pincode"),
+ mSeed,
+ nullptr);
+ mDialog->requestFocus();
+ mDialog->setActionEventId("ok");
+ mDialog->addActionListener(&newPincodeListener);
+ }
+ else
+ { // pincode confirmation
+ if (mNewPincode != pincode)
+ {
+ mNewPincode.clear();
+ OkDialog *const dialog = CREATEWIDGETR(OkDialog,
+ // TRANSLATORS: error header
+ _("Pincode"),
+ // TRANSLATORS: error message
+ _("Wrong pincode confirmation!"),
+ // TRANSLATORS: ok dialog button
+ _("OK"),
+ DialogType::ERROR,
+ Modal_true,
+ ShowCenter_true,
+ nullptr,
+ 260);
+ dialog->addActionListener(&newPincodeRetryListener);
+ }
+ else
+ {
+ charServerHandler->setNewPincode(mAccountId,
+ mNewPincode);
+ mNewPincode.clear();
+ }
+ }
}
-void PincodeManager::changePin()
+void PincodeManager::pinOk()
{
}
diff --git a/src/pincodemanager.h b/src/pincodemanager.h
index 58af704ed..bf3d2e8fc 100644
--- a/src/pincodemanager.h
+++ b/src/pincodemanager.h
@@ -23,8 +23,15 @@
#include "enums/simpletypes/beingid.h"
+#include "enums/gui/pincodestate.h"
+
+#include <string>
+
#include "localconsts.h"
+class PincodeDialog;
+class Window;
+
class PincodeManager final
{
public:
@@ -36,13 +43,9 @@ class PincodeManager final
void init();
- void pinOk();
-
- void askPin();
+ void updateState();
- void createNewPin();
-
- void changePin();
+ void pinOk();
void wrongPin();
@@ -52,9 +55,19 @@ class PincodeManager final
void setAccountId(const BeingId id)
{ mAccountId = id; }
+ void setState(const PincodeState state)
+ { mState = state; }
+
+ void clearDialog(const PincodeDialog *const PincodeDialog);
+
+ void setNewPincode(const std::string &pincode);
+
protected:
+ std::string mNewPincode;
uint32_t mSeed;
BeingId mAccountId;
+ Window *mDialog;
+ PincodeState mState;
};
extern PincodeManager pincodeManager;
diff --git a/src/progs/manaplus/client.cpp b/src/progs/manaplus/client.cpp
index c035ed018..84f6cdcce 100644
--- a/src/progs/manaplus/client.cpp
+++ b/src/progs/manaplus/client.cpp
@@ -1304,6 +1304,7 @@ int Client::gameExec()
CREATEWIDGETV(mCurrentDialog, CharSelectDialog,
loginData);
+ pincodeManager.updateState();
if (!(static_cast<CharSelectDialog*>(mCurrentDialog))
->selectByName(settings.options.character,