From 336ec8a82855858701647c809d7214dece69dd87 Mon Sep 17 00:00:00 2001
From: Andrei Karas <akaras@inbox.ru>
Date: Wed, 15 Apr 2015 00:22:39 +0300
Subject: eathena: add support for change password.

---
 src/client.cpp                   |  4 ++--
 src/net/eathena/loginhandler.cpp | 52 +++++++++++++++++++++++++++++++++++-----
 src/net/eathena/loginhandler.h   |  5 ++--
 src/net/eathena/protocol.h       |  3 ++-
 src/net/loginhandler.h           |  3 +--
 src/net/tmwa/loginhandler.cpp    |  4 +---
 src/net/tmwa/loginhandler.h      |  3 +--
 7 files changed, 56 insertions(+), 18 deletions(-)

diff --git a/src/client.cpp b/src/client.cpp
index fd0672805..ec05a7460 100644
--- a/src/client.cpp
+++ b/src/client.cpp
@@ -1437,8 +1437,8 @@ int Client::gameExec()
                     BLOCK_START("Client::gameExec "
                         "STATE_CHANGEPASSWORD_ATTEMPT")
                     logger->log1("State: CHANGE PASSWORD ATTEMPT");
-                    loginHandler->changePassword(loginData.username,
-                        loginData.password, loginData.newPassword);
+                    loginHandler->changePassword(loginData.password,
+                        loginData.newPassword);
                     BLOCK_END("Client::gameExec STATE_CHANGEPASSWORD_ATTEMPT")
                     break;
 
diff --git a/src/net/eathena/loginhandler.cpp b/src/net/eathena/loginhandler.cpp
index 26c93212b..81ee45a60 100644
--- a/src/net/eathena/loginhandler.cpp
+++ b/src/net/eathena/loginhandler.cpp
@@ -56,6 +56,7 @@ LoginHandler::LoginHandler() :
         SMSG_SERVER_VERSION_RESPONSE,
         SMSG_UPDATE_HOST,
         SMSG_LOGIN_CODING_KEY,
+        SMSG_CHAR_PASSWORD_RESPONSE,
         0
     };
     handledMessages = _messages;
@@ -94,6 +95,10 @@ void LoginHandler::handleMessage(Net::MessageIn &msg)
             processCondingKey(msg);
             break;
 
+        case SMSG_CHAR_PASSWORD_RESPONSE:
+            processCharPasswordResponse(msg);
+            break;
+
         default:
             break;
     }
@@ -130,13 +135,12 @@ void LoginHandler::disconnect()
         mNetwork->disconnect();
 }
 
-void LoginHandler::changePassword(const std::string &restrict username
-                                  A_UNUSED,
-                                  const std::string &restrict
-                                  oldPassword A_UNUSED,
-                                  const std::string &restrict
-                                  newPassword A_UNUSED) const
+void LoginHandler::changePassword(const std::string &restrict oldPassword,
+                                  const std::string &restrict newPassword) const
 {
+    createOutPacket(CMSG_CHAR_PASSWORD_CHANGE);
+    outMsg.writeStringNoLog(oldPassword, 24, "old password");
+    outMsg.writeStringNoLog(newPassword, 24, "new password");
 }
 
 void LoginHandler::sendLoginRegister(const std::string &restrict username,
@@ -296,4 +300,40 @@ void LoginHandler::ping() const
     outMsg.writeInt32(0, "unused");
 }
 
+void LoginHandler::processCharPasswordResponse(Net::MessageIn &msg)
+{
+    // 0: acc not found, 1: success, 2: password mismatch, 3: pass too short
+    const uint8_t errMsg = msg.readUInt8("result code");
+    // Successful pass change
+    if (errMsg == 1)
+    {
+        client->setState(STATE_CHANGEPASSWORD_SUCCESS);
+    }
+    // pass change failed
+    else
+    {
+        switch (errMsg)
+        {
+            case 0:
+                errorMessage =
+                    // TRANSLATORS: error message
+                    _("Account was not found. Please re-login.");
+                break;
+            case 2:
+                // TRANSLATORS: error message
+                errorMessage = _("Old password incorrect.");
+                break;
+            case 3:
+                // TRANSLATORS: error message
+                errorMessage = _("New password too short.");
+                break;
+            default:
+                // TRANSLATORS: error message
+                errorMessage = _("Unknown error.");
+                break;
+        }
+        client->setState(STATE_ACCOUNTCHANGE_ERROR);
+    }
+}
+
 }  // namespace EAthena
diff --git a/src/net/eathena/loginhandler.h b/src/net/eathena/loginhandler.h
index c1543e627..abca1d359 100644
--- a/src/net/eathena/loginhandler.h
+++ b/src/net/eathena/loginhandler.h
@@ -50,8 +50,7 @@ class LoginHandler final : public MessageHandler, public Ea::LoginHandler
         unsigned int getMaxPasswordLength() const override final A_WARN_UNUSED
         { return 24; }
 
-        void changePassword(const std::string &restrict username,
-                            const std::string &restrict oldPassword,
+        void changePassword(const std::string &restrict oldPassword,
                             const std::string &restrict newPassword)
                             const override final;
 
@@ -72,6 +71,8 @@ class LoginHandler final : public MessageHandler, public Ea::LoginHandler
 
         static void processCondingKey(Net::MessageIn &msg);
 
+        static void processCharPasswordResponse(Net::MessageIn &msg);
+
     private:
         void sendLoginRegister(const std::string &restrict username,
                                const std::string &restrict password,
diff --git a/src/net/eathena/protocol.h b/src/net/eathena/protocol.h
index 62f4d1716..156597505 100644
--- a/src/net/eathena/protocol.h
+++ b/src/net/eathena/protocol.h
@@ -47,6 +47,7 @@
 #define SMSG_CHAR_RENAME             0x0290
 #define SMSG_CHAR_CHANGE_SLOT        0x08d5
 #define SMSG_CHAR_CAPTCHA_NOT_SUPPORTED 0x07e9
+#define SMSG_CHAR_PASSWORD_RESPONSE  0x0062
 
 #define SMSG_CHAR_CREATE_FAILED      0x006e
 #define SMSG_CHAR_DELETE_SUCCEEDED   0x006f
@@ -484,7 +485,7 @@
 #define CMSG_LOGIN_REGISTER2         0x027c
 #define CMSG_NAME_REQUEST            0x088a
 
-// Custom change password packet
+#define CMSG_CHAR_PASSWORD_CHANGE    0x0061
 #define CMSG_CHAR_SERVER_CONNECT     0x0065
 #define CMSG_CHAR_SELECT             0x0066
 #define CMSG_CHAR_CREATE             0x0970
diff --git a/src/net/loginhandler.h b/src/net/loginhandler.h
index 410eb858b..47979ca65 100644
--- a/src/net/loginhandler.h
+++ b/src/net/loginhandler.h
@@ -73,8 +73,7 @@ class LoginHandler notfinal
 
         virtual void changeEmail(const std::string &email) const = 0;
 
-        virtual void changePassword(const std::string &restrict username,
-                                    const std::string &restrict oldPassword,
+        virtual void changePassword(const std::string &restrict oldPassword,
                                     const std::string &restrict newPassword)
                                     const = 0;
 
diff --git a/src/net/tmwa/loginhandler.cpp b/src/net/tmwa/loginhandler.cpp
index 0007f0ffb..96a33d55a 100644
--- a/src/net/tmwa/loginhandler.cpp
+++ b/src/net/tmwa/loginhandler.cpp
@@ -128,9 +128,7 @@ void LoginHandler::disconnect()
         mNetwork->disconnect();
 }
 
-void LoginHandler::changePassword(const std::string &restrict username
-                                  A_UNUSED,
-                                  const std::string &restrict oldPassword,
+void LoginHandler::changePassword(const std::string &restrict oldPassword,
                                   const std::string &restrict newPassword)
                                   const
 {
diff --git a/src/net/tmwa/loginhandler.h b/src/net/tmwa/loginhandler.h
index fba17a8ae..9db07dee5 100644
--- a/src/net/tmwa/loginhandler.h
+++ b/src/net/tmwa/loginhandler.h
@@ -52,8 +52,7 @@ class LoginHandler final : public MessageHandler, public Ea::LoginHandler
         unsigned int getMaxPasswordLength() const override final A_WARN_UNUSED
         { return 24; }
 
-        void changePassword(const std::string &restrict username,
-                            const std::string &restrict oldPassword,
+        void changePassword(const std::string &restrict oldPassword,
                             const std::string &restrict newPassword)
                             const override final;
 
-- 
cgit v1.2.3-70-g09d2