From 7e0a84fc2b7493670dc8167aafb83c3811272eb3 Mon Sep 17 00:00:00 2001
From: Andrei Karas <akaras@inbox.ru>
Date: Fri, 28 Aug 2015 00:47:23 +0300
Subject: Move receive code from partyhandler into separate file.

---
 src/CMakeLists.txt               |   6 +
 src/Makefile.am                  |   6 +
 src/net/ea/partyhandler.cpp      | 186 ++--------------------
 src/net/ea/partyhandler.h        |  22 +--
 src/net/ea/partyrecv.cpp         | 229 +++++++++++++++++++++++++++
 src/net/ea/partyrecv.h           |  53 +++++++
 src/net/eathena/partyhandler.cpp | 313 +++----------------------------------
 src/net/eathena/partyhandler.h   |  19 ---
 src/net/eathena/partyrecv.cpp    | 327 +++++++++++++++++++++++++++++++++++++++
 src/net/eathena/partyrecv.h      |  45 ++++++
 src/net/tmwa/partyhandler.cpp    | 278 ++-------------------------------
 src/net/tmwa/partyhandler.h      |  15 --
 src/net/tmwa/partyrecv.cpp       | 296 +++++++++++++++++++++++++++++++++++
 src/net/tmwa/partyrecv.h         |  43 +++++
 14 files changed, 1053 insertions(+), 785 deletions(-)
 create mode 100644 src/net/ea/partyrecv.cpp
 create mode 100644 src/net/ea/partyrecv.h
 create mode 100644 src/net/eathena/partyrecv.cpp
 create mode 100644 src/net/eathena/partyrecv.h
 create mode 100644 src/net/tmwa/partyrecv.cpp
 create mode 100644 src/net/tmwa/partyrecv.h

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 3faaed6d1..9a1527cd6 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1389,6 +1389,8 @@ SET(SRCS_EVOL
     net/ea/npcrecv.h
     net/ea/partyhandler.cpp
     net/ea/partyhandler.h
+    net/ea/partyrecv.cpp
+    net/ea/partyrecv.h
     net/ea/playerhandler.cpp
     net/ea/playerhandler.h
     net/ea/skillhandler.cpp
@@ -1460,6 +1462,8 @@ SET(SRCS_TMWA
     net/tmwa/packets.h
     net/tmwa/partyhandler.cpp
     net/tmwa/partyhandler.h
+    net/tmwa/partyrecv.cpp
+    net/tmwa/partyrecv.h
     net/tmwa/pethandler.cpp
     net/tmwa/pethandler.h
     net/tmwa/playerhandler.cpp
@@ -1671,6 +1675,8 @@ SET(SRCS_EATHENA
     net/eathena/packets.h
     net/eathena/partyhandler.cpp
     net/eathena/partyhandler.h
+    net/eathena/partyrecv.cpp
+    net/eathena/partyrecv.h
     net/eathena/pethandler.cpp
     net/eathena/pethandler.h
     net/eathena/playerhandler.cpp
diff --git a/src/Makefile.am b/src/Makefile.am
index 3ac6c0503..7e13324f1 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1231,6 +1231,8 @@ manaplus_SOURCES += main.cpp \
 	      net/ea/npcrecv.h \
 	      net/ea/partyhandler.cpp \
 	      net/ea/partyhandler.h \
+	      net/ea/partyrecv.cpp \
+	      net/ea/partyrecv.h \
 	      net/ea/playerhandler.cpp \
 	      net/ea/playerhandler.h \
 	      net/ea/skillhandler.cpp \
@@ -1303,6 +1305,8 @@ manaplus_SOURCES += \
 	      net/tmwa/packets.h \
 	      net/tmwa/partyhandler.cpp \
 	      net/tmwa/partyhandler.h \
+	      net/tmwa/partyrecv.cpp \
+	      net/tmwa/partyrecv.h \
 	      net/tmwa/pethandler.cpp \
 	      net/tmwa/pethandler.h \
 	      net/tmwa/playerhandler.cpp \
@@ -1517,6 +1521,8 @@ manaplus_SOURCES += gui/windows/bankwindow.cpp \
 	      net/eathena/packets.h \
 	      net/eathena/partyhandler.cpp \
 	      net/eathena/partyhandler.h \
+	      net/eathena/partyrecv.cpp \
+	      net/eathena/partyrecv.h \
 	      net/eathena/pethandler.cpp \
 	      net/eathena/pethandler.h \
 	      net/eathena/playerhandler.cpp \
diff --git a/src/net/ea/partyhandler.cpp b/src/net/ea/partyhandler.cpp
index 83d5f04b4..0797e6e55 100644
--- a/src/net/ea/partyhandler.cpp
+++ b/src/net/ea/partyhandler.cpp
@@ -35,6 +35,8 @@
 
 #include "net/messagein.h"
 
+#include "net/ea/partyrecv.h"
+
 #include "gui/widgets/tabs/chat/partytab.h"
 
 #include "utils/delete2.h"
@@ -44,15 +46,11 @@
 namespace Ea
 {
 
-Party *taParty = nullptr;
-PartyShareT PartyHandler::mShareExp = PartyShare::UNKNOWN;
-PartyShareT PartyHandler::mShareItems = PartyShare::UNKNOWN;
-
 PartyHandler::PartyHandler() :
     Net::PartyHandler()
 {
-    mShareExp = PartyShare::UNKNOWN;
-    mShareItems = PartyShare::UNKNOWN;
+    PartyRecv::mShareExp = PartyShare::UNKNOWN;
+    PartyRecv::mShareItems = PartyShare::UNKNOWN;
     taParty = Party::getParty(1);
 }
 
@@ -75,183 +73,19 @@ void PartyHandler::clear() const
     taParty = nullptr;
 }
 
-void PartyHandler::processPartyCreate(Net::MessageIn &msg)
-{
-    if (msg.readUInt8("flag"))
-        NotifyManager::notify(NotifyTypes::PARTY_CREATE_FAILED);
-    else
-        NotifyManager::notify(NotifyTypes::PARTY_CREATED);
-}
-
-void PartyHandler::processPartySettingsContinue(Net::MessageIn &msg,
-                                                const PartyShareT exp,
-                                                const PartyShareT item)
-{
-    switch (exp)
-    {
-        case PartyShare::YES:
-            if (mShareExp == PartyShare::YES)
-                break;
-            mShareExp = PartyShare::YES;
-            NotifyManager::notify(NotifyTypes::PARTY_EXP_SHARE_ON);
-            break;
-        case PartyShare::NO:
-            if (mShareExp == PartyShare::NO)
-                break;
-            mShareExp = PartyShare::NO;
-            NotifyManager::notify(NotifyTypes::PARTY_EXP_SHARE_OFF);
-            break;
-        case PartyShare::NOT_POSSIBLE:
-            if (mShareExp == PartyShare::NOT_POSSIBLE)
-                break;
-            mShareExp = PartyShare::NOT_POSSIBLE;
-            NotifyManager::notify(NotifyTypes::PARTY_EXP_SHARE_ERROR);
-            break;
-        default:
-        case PartyShare::UNKNOWN:
-            UNIMPLIMENTEDPACKET;
-            break;
-    }
-
-    switch (item)
-    {
-        case PartyShare::YES:
-            if (mShareItems == PartyShare::YES)
-                break;
-            mShareItems = PartyShare::YES;
-            NotifyManager::notify(NotifyTypes::PARTY_ITEM_SHARE_ON);
-            break;
-        case PartyShare::NO:
-            if (mShareItems == PartyShare::NO)
-                break;
-            mShareItems = PartyShare::NO;
-            NotifyManager::notify(NotifyTypes::PARTY_ITEM_SHARE_OFF);
-            break;
-        case PartyShare::NOT_POSSIBLE:
-            if (mShareItems == PartyShare::NOT_POSSIBLE)
-                break;
-            mShareItems = PartyShare::NOT_POSSIBLE;
-            NotifyManager::notify(NotifyTypes::PARTY_ITEM_SHARE_ERROR);
-            break;
-        default:
-        case PartyShare::UNKNOWN:
-            UNIMPLIMENTEDPACKET;
-            break;
-    }
-}
-
-void PartyHandler::processPartyLeave(Net::MessageIn &msg)
-{
-    const BeingId id = msg.readBeingId("account id");
-    const std::string nick = msg.readString(24, "nick");
-    const int reason = msg.readUInt8("flag");
-    if (!localPlayer)
-        return;
-
-    if (id == localPlayer->getId())
-    {
-        switch (reason)
-        {
-            case 0:
-            default:
-                NotifyManager::notify(NotifyTypes::PARTY_LEFT);
-                break;
-
-            case 1:
-                NotifyManager::notify(NotifyTypes::PARTY_KICKED);
-                break;
-
-            case 2:
-                NotifyManager::notify(NotifyTypes::PARTY_LEFT_DENY);
-                break;
-
-            case 3:
-                NotifyManager::notify(NotifyTypes::PARTY_KICK_DENY);
-                break;
-        }
-
-        if (reason >= 2)
-            return;
-
-        if (Ea::taParty)
-        {
-            Ea::taParty->removeFromMembers();
-            Ea::taParty->clearMembers();
-        }
-
-        delete2(partyTab)
-
-        if (socialWindow && Ea::taParty)
-            socialWindow->removeTab(Ea::taParty);
-        localPlayer->setPartyName("");
-    }
-    else
-    {
-        switch (reason)
-        {
-            case 0:
-            default:
-                NotifyManager::notify(NotifyTypes::PARTY_USER_LEFT, nick);
-                break;
-
-            case 1:
-                NotifyManager::notify(NotifyTypes::PARTY_USER_KICKED, nick);
-                break;
-
-            case 2:
-                NotifyManager::notify(NotifyTypes::PARTY_USER_LEFT_DENY, nick);
-                break;
-
-            case 3:
-                NotifyManager::notify(NotifyTypes::PARTY_USER_KICK_DENY, nick);
-                break;
-        }
-
-        if (reason >= 2)
-            return;
-
-        if (actorManager)
-        {
-            Being *const b = actorManager->findBeing(id);
-            if (b && b->getType() == ActorType::Player)
-            {
-                b->setParty(nullptr);
-                b->setPartyName("");
-            }
-        }
-        if (Ea::taParty)
-            Ea::taParty->removeMember(id);
-    }
-}
-
-void PartyHandler::processPartyUpdateCoords(Net::MessageIn &msg)
+ChatTab *PartyHandler::getTab() const
 {
-    const BeingId id = msg.readBeingId("account id");
-    PartyMember *m = nullptr;
-    if (Ea::taParty)
-        m = Ea::taParty->getMember(id);
-    if (m)
-    {
-        m->setX(msg.readInt16("x"));
-        m->setY(msg.readInt16("y"));
-    }
-    else
-    {
-        msg.readInt16("x");
-        msg.readInt16("y");
-    }
+    return partyTab;
 }
 
-ChatTab *PartyHandler::getTab() const
+PartyShareT PartyHandler::getShareExperience() const
 {
-    return partyTab;
+    return PartyRecv::mShareExp;
 }
 
-void PartyHandler::createTab()
+PartyShareT PartyHandler::getShareItems() const
 {
-    partyTab = new PartyTab(chatWindow);
-    if (config.getBoolValue("showChatHistory"))
-        partyTab->loadFromLogFile("#Party");
+    return PartyRecv::mShareItems;
 }
 
 }  // namespace Ea
diff --git a/src/net/ea/partyhandler.h b/src/net/ea/partyhandler.h
index 453aced1d..1848d5316 100644
--- a/src/net/ea/partyhandler.h
+++ b/src/net/ea/partyhandler.h
@@ -44,33 +44,15 @@ class PartyHandler notfinal : public Net::PartyHandler
 
         void join(const int partyId) const override final;
 
-        PartyShareT getShareExperience() const override final A_WARN_UNUSED
-        { return mShareExp; }
+        PartyShareT getShareExperience() const override final A_WARN_UNUSED;
 
-        PartyShareT getShareItems() const override final A_WARN_UNUSED
-        { return mShareItems; }
+        PartyShareT getShareItems() const override final A_WARN_UNUSED;
 
         static void reload();
 
         void clear() const override final;
 
         ChatTab *getTab() const override final;
-
-    protected:
-        static void createTab();
-
-        static void processPartyCreate(Net::MessageIn &msg);
-
-        static void processPartyLeave(Net::MessageIn &msg);
-
-        static void processPartyUpdateCoords(Net::MessageIn &msg);
-
-        static void processPartySettingsContinue(Net::MessageIn &msg,
-                                                 const PartyShareT exp,
-                                                 const PartyShareT item);
-
-        static PartyShareT mShareExp;
-        static PartyShareT mShareItems;
 };
 
 extern Party *taParty;
diff --git a/src/net/ea/partyrecv.cpp b/src/net/ea/partyrecv.cpp
new file mode 100644
index 000000000..415129f41
--- /dev/null
+++ b/src/net/ea/partyrecv.cpp
@@ -0,0 +1,229 @@
+/*
+ *  The ManaPlus Client
+ *  Copyright (C) 2008  Lloyd Bryant <lloyd_bryant@netzero.net>
+ *  Copyright (C) 2011-2015  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 "net/ea/partyrecv.h"
+
+#include "actormanager.h"
+#include "configuration.h"
+#include "notifymanager.h"
+#include "party.h"
+
+#include "being/localplayer.h"
+
+#include "enums/resources/notifytypes.h"
+
+#include "gui/windows/chatwindow.h"
+#include "gui/windows/socialwindow.h"
+
+#include "net/messagein.h"
+
+#include "gui/widgets/tabs/chat/partytab.h"
+
+#include "utils/delete2.h"
+
+#include "debug.h"
+
+namespace Ea
+{
+
+Party *taParty = nullptr;
+
+namespace PartyRecv
+{
+    PartyShareT mShareExp = PartyShare::UNKNOWN;
+    PartyShareT mShareItems = PartyShare::UNKNOWN;
+}  // namespace PartyRecv
+
+void PartyRecv::processPartyCreate(Net::MessageIn &msg)
+{
+    if (msg.readUInt8("flag"))
+        NotifyManager::notify(NotifyTypes::PARTY_CREATE_FAILED);
+    else
+        NotifyManager::notify(NotifyTypes::PARTY_CREATED);
+}
+
+void PartyRecv::processPartySettingsContinue(Net::MessageIn &msg,
+                                                const PartyShareT exp,
+                                                const PartyShareT item)
+{
+    switch (exp)
+    {
+        case PartyShare::YES:
+            if (mShareExp == PartyShare::YES)
+                break;
+            mShareExp = PartyShare::YES;
+            NotifyManager::notify(NotifyTypes::PARTY_EXP_SHARE_ON);
+            break;
+        case PartyShare::NO:
+            if (mShareExp == PartyShare::NO)
+                break;
+            mShareExp = PartyShare::NO;
+            NotifyManager::notify(NotifyTypes::PARTY_EXP_SHARE_OFF);
+            break;
+        case PartyShare::NOT_POSSIBLE:
+            if (mShareExp == PartyShare::NOT_POSSIBLE)
+                break;
+            mShareExp = PartyShare::NOT_POSSIBLE;
+            NotifyManager::notify(NotifyTypes::PARTY_EXP_SHARE_ERROR);
+            break;
+        default:
+        case PartyShare::UNKNOWN:
+            UNIMPLIMENTEDPACKET;
+            break;
+    }
+
+    switch (item)
+    {
+        case PartyShare::YES:
+            if (mShareItems == PartyShare::YES)
+                break;
+            mShareItems = PartyShare::YES;
+            NotifyManager::notify(NotifyTypes::PARTY_ITEM_SHARE_ON);
+            break;
+        case PartyShare::NO:
+            if (mShareItems == PartyShare::NO)
+                break;
+            mShareItems = PartyShare::NO;
+            NotifyManager::notify(NotifyTypes::PARTY_ITEM_SHARE_OFF);
+            break;
+        case PartyShare::NOT_POSSIBLE:
+            if (mShareItems == PartyShare::NOT_POSSIBLE)
+                break;
+            mShareItems = PartyShare::NOT_POSSIBLE;
+            NotifyManager::notify(NotifyTypes::PARTY_ITEM_SHARE_ERROR);
+            break;
+        default:
+        case PartyShare::UNKNOWN:
+            UNIMPLIMENTEDPACKET;
+            break;
+    }
+}
+
+void PartyRecv::processPartyLeave(Net::MessageIn &msg)
+{
+    const BeingId id = msg.readBeingId("account id");
+    const std::string nick = msg.readString(24, "nick");
+    const int reason = msg.readUInt8("flag");
+    if (!localPlayer)
+        return;
+
+    if (id == localPlayer->getId())
+    {
+        switch (reason)
+        {
+            case 0:
+            default:
+                NotifyManager::notify(NotifyTypes::PARTY_LEFT);
+                break;
+
+            case 1:
+                NotifyManager::notify(NotifyTypes::PARTY_KICKED);
+                break;
+
+            case 2:
+                NotifyManager::notify(NotifyTypes::PARTY_LEFT_DENY);
+                break;
+
+            case 3:
+                NotifyManager::notify(NotifyTypes::PARTY_KICK_DENY);
+                break;
+        }
+
+        if (reason >= 2)
+            return;
+
+        if (Ea::taParty)
+        {
+            Ea::taParty->removeFromMembers();
+            Ea::taParty->clearMembers();
+        }
+
+        delete2(partyTab)
+
+        if (socialWindow && Ea::taParty)
+            socialWindow->removeTab(Ea::taParty);
+        localPlayer->setPartyName("");
+    }
+    else
+    {
+        switch (reason)
+        {
+            case 0:
+            default:
+                NotifyManager::notify(NotifyTypes::PARTY_USER_LEFT, nick);
+                break;
+
+            case 1:
+                NotifyManager::notify(NotifyTypes::PARTY_USER_KICKED, nick);
+                break;
+
+            case 2:
+                NotifyManager::notify(NotifyTypes::PARTY_USER_LEFT_DENY, nick);
+                break;
+
+            case 3:
+                NotifyManager::notify(NotifyTypes::PARTY_USER_KICK_DENY, nick);
+                break;
+        }
+
+        if (reason >= 2)
+            return;
+
+        if (actorManager)
+        {
+            Being *const b = actorManager->findBeing(id);
+            if (b && b->getType() == ActorType::Player)
+            {
+                b->setParty(nullptr);
+                b->setPartyName("");
+            }
+        }
+        if (Ea::taParty)
+            Ea::taParty->removeMember(id);
+    }
+}
+
+void PartyRecv::processPartyUpdateCoords(Net::MessageIn &msg)
+{
+    const BeingId id = msg.readBeingId("account id");
+    PartyMember *m = nullptr;
+    if (Ea::taParty)
+        m = Ea::taParty->getMember(id);
+    if (m)
+    {
+        m->setX(msg.readInt16("x"));
+        m->setY(msg.readInt16("y"));
+    }
+    else
+    {
+        msg.readInt16("x");
+        msg.readInt16("y");
+    }
+}
+
+void PartyRecv::createTab()
+{
+    partyTab = new PartyTab(chatWindow);
+    if (config.getBoolValue("showChatHistory"))
+        partyTab->loadFromLogFile("#Party");
+}
+
+}  // namespace Ea
diff --git a/src/net/ea/partyrecv.h b/src/net/ea/partyrecv.h
new file mode 100644
index 000000000..87452318f
--- /dev/null
+++ b/src/net/ea/partyrecv.h
@@ -0,0 +1,53 @@
+/*
+ *  The ManaPlus Client
+ *  Copyright (C) 2008  Lloyd Bryant <lloyd_bryant@netzero.net>
+ *  Copyright (C) 2011-2015  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 NET_EA_PARTYRECV_H
+#define NET_EA_PARTYRECV_H
+
+#include "net/partyhandler.h"
+
+class Party;
+
+namespace Net
+{
+    class MessageIn;
+}
+
+namespace Ea
+{
+    namespace PartyRecv
+    {
+        extern PartyShareT mShareExp;
+        extern PartyShareT mShareItems;
+
+        void processPartyCreate(Net::MessageIn &msg);
+        void processPartyLeave(Net::MessageIn &msg);
+        void processPartyUpdateCoords(Net::MessageIn &msg);
+        void processPartySettingsContinue(Net::MessageIn &msg,
+                                          const PartyShareT exp,
+                                          const PartyShareT item);
+
+        void createTab();
+    }  // namespace PartyRecv
+    extern Party *taParty;
+}  // namespace Ea
+
+#endif  // NET_EA_PARTYRECV_H
diff --git a/src/net/eathena/partyhandler.cpp b/src/net/eathena/partyhandler.cpp
index 15c1c4940..0e0625b4c 100644
--- a/src/net/eathena/partyhandler.cpp
+++ b/src/net/eathena/partyhandler.cpp
@@ -34,7 +34,10 @@
 
 #include "gui/widgets/tabs/chat/partytab.h"
 
+#include "net/ea/partyrecv.h"
+
 #include "net/eathena/messageout.h"
+#include "net/eathena/partyrecv.h"
 #include "net/eathena/protocol.h"
 
 #include "debug.h"
@@ -77,40 +80,40 @@ void PartyHandler::handleMessage(Net::MessageIn &msg)
     switch (msg.getId())
     {
         case SMSG_PARTY_CREATE:
-            processPartyCreate(msg);
+            Ea::PartyRecv::processPartyCreate(msg);
             break;
         case SMSG_PARTY_INFO:
-            processPartyInfo(msg);
+            PartyRecv::processPartyInfo(msg);
             break;
         case SMSG_PARTY_INVITE_RESPONSE:
-            processPartyInviteResponse(msg);
+            PartyRecv::processPartyInviteResponse(msg);
             break;
         case SMSG_PARTY_INVITED:
-            processPartyInvited(msg);
+            PartyRecv::processPartyInvited(msg);
             break;
         case SMSG_PARTY_SETTINGS:
-            processPartySettings(msg);
+            PartyRecv::processPartySettings(msg);
             break;
         case SMSG_PARTY_LEAVE:
-            processPartyLeave(msg);
+            Ea::PartyRecv::processPartyLeave(msg);
             break;
         case SMSG_PARTY_UPDATE_COORDS:
-            processPartyUpdateCoords(msg);
+            Ea::PartyRecv::processPartyUpdateCoords(msg);
             break;
         case SMSG_PARTY_MESSAGE:
-            processPartyMessage(msg);
+            PartyRecv::processPartyMessage(msg);
             break;
         case SMSG_PARTY_INVITATION_STATS:
-            processPartyInvitationStats(msg);
+            PartyRecv::processPartyInvitationStats(msg);
             break;
         case SMSG_PARTY_MEMBER_INFO:
-            processPartyMemberInfo(msg);
+            PartyRecv::processPartyMemberInfo(msg);
             break;
         case SMSG_PARTY_ITEM_PICKUP:
-            processPartyItemPickup(msg);
+            PartyRecv::processPartyItemPickup(msg);
             break;
         case SMSG_PARTY_LEADER:
-            processPartyLeader(msg);
+            PartyRecv::processPartyLeader(msg);
             break;
 
         default:
@@ -205,7 +208,8 @@ void PartyHandler::setShareExperience(const PartyShareT share) const
 
     createOutPacket(CMSG_PARTY_SETTINGS);
     outMsg.writeInt16(static_cast<int16_t>(share), "share exp");
-    outMsg.writeInt16(static_cast<int16_t>(mShareItems), "share items");
+    outMsg.writeInt16(static_cast<int16_t>(Ea::PartyRecv::mShareItems),
+        "share items");
 }
 
 // +++ must be 3 types item, exp, pickup
@@ -215,240 +219,11 @@ void PartyHandler::setShareItems(const PartyShareT share) const
         return;
 
     createOutPacket(CMSG_PARTY_SETTINGS);
-    outMsg.writeInt16(static_cast<int16_t>(mShareExp), "share exp");
+    outMsg.writeInt16(static_cast<int16_t>(Ea::PartyRecv::mShareExp),
+        "share exp");
     outMsg.writeInt16(static_cast<int16_t>(share), "share items");
 }
 
-void PartyHandler::processPartyInvitationStats(Net::MessageIn &msg)
-{
-    // +++ for now server allow only switch this option but not using it.
-    msg.readUInt8("allow party");
-}
-
-void PartyHandler::processPartyMemberInfo(Net::MessageIn &msg)
-{
-    const BeingId id = msg.readBeingId("account id");
-    const bool leader = msg.readInt32("leader") == 0U;
-    const int x = msg.readInt16("x");
-    const int y = msg.readInt16("y");
-    const bool online = msg.readInt8("online") == 0U;
-    msg.readString(24, "party name");
-    const std::string nick = msg.readString(24, "player name");
-    const std::string map = msg.readString(16, "map name");
-    msg.readInt8("party.item&1");
-    msg.readInt8("party.item&2");
-
-    if (!Ea::taParty)
-        return;
-
-    PartyMember *const member = Ea::taParty->addMember(id, nick);
-    if (member)
-    {
-        if (partyTab && member->getOnline() != online)
-            partyTab->showOnline(nick, fromBool(online, Online));
-        member->setLeader(leader);
-        member->setOnline(online);
-        member->setMap(map);
-        member->setX(x);
-        member->setY(y);
-    }
-}
-
-void PartyHandler::processPartySettings(Net::MessageIn &msg)
-{
-    if (!partyTab)
-    {
-        if (!chatWindow)
-            return;
-
-        createTab();
-    }
-
-    msg.readInt32("party exp");
-    const PartyShareT exp = static_cast<PartyShareT>(
-        msg.readInt8("share exp"));
-    const PartyShareT item = static_cast<PartyShareT>(
-        msg.readInt8("share item"));
-    processPartySettingsContinue(msg, exp, item);
-}
-
-void PartyHandler::processPartyInfo(Net::MessageIn &msg)
-{
-    bool isOldParty = false;
-    std::set<std::string> names;
-    std::set<std::string> onlineNames;
-    if (!Ea::taParty)
-    {
-        logger->log1("error: party empty in SMSG_PARTY_INFO");
-        Ea::taParty = Party::getParty(1);
-    }
-    if (!partyTab)
-        createTab();
-
-    if (Ea::taParty)
-    {
-        if (Ea::taParty->getNumberOfElements() > 1)
-        {
-            isOldParty = true;
-            Ea::taParty->getNamesSet(names);
-            const Party::MemberList *const members = Ea::taParty->getMembers();
-            FOR_EACHP (Party::MemberList::const_iterator, it, members)
-            {
-                if ((*it)->getOnline())
-                    onlineNames.insert((*it)->getName());
-            }
-            if (localPlayer)
-                onlineNames.insert(localPlayer->getName());
-        }
-    }
-
-    if (!localPlayer)
-        logger->log1("error: localPlayer==0 in SMSG_PARTY_INFO");
-
-    if (Ea::taParty)
-        Ea::taParty->clearMembers();
-
-    const int length = msg.readInt16("len");
-    if (Ea::taParty)
-        Ea::taParty->setName(msg.readString(24, "party name"));
-
-    const int count = (length - 28) / 46;
-    if (localPlayer && Ea::taParty)
-    {
-        localPlayer->setParty(Ea::taParty);
-        localPlayer->setPartyName(Ea::taParty->getName());
-    }
-
-    for (int i = 0; i < count; i++)
-    {
-        const BeingId id = msg.readBeingId("account id");
-        std::string nick = msg.readString(24, "nick");
-        std::string map = msg.readString(16, "map name");
-        const bool leader = msg.readUInt8("leader") == 0U;
-        const bool online = msg.readUInt8("online") == 0U;
-
-        if (Ea::taParty)
-        {
-            bool joined(false);
-
-            if (isOldParty)
-            {
-                if (names.find(nick) == names.end())
-                {
-                    NotifyManager::notify(NotifyTypes::PARTY_USER_JOINED,
-                        nick);
-                    joined = true;
-                }
-            }
-            PartyMember *const member = Ea::taParty->addMember(id, nick);
-            if (member)
-            {
-                if (!joined && partyTab)
-                {
-                    if (!names.empty() && ((onlineNames.find(nick)
-                        == onlineNames.end() && online)
-                        || (onlineNames.find(nick) != onlineNames.end()
-                        && !online)))
-                    {
-                        partyTab->showOnline(nick, fromBool(online, Online));
-                    }
-
-                    member->setLeader(leader);
-                    member->setOnline(online);
-                    member->setMap(map);
-                }
-                else
-                {
-                    member->setLeader(leader);
-                    member->setOnline(online);
-                    member->setMap(map);
-                }
-            }
-        }
-    }
-
-    if (Ea::taParty)
-        Ea::taParty->sort();
-
-    if (localPlayer && Ea::taParty)
-    {
-        localPlayer->setParty(Ea::taParty);
-        localPlayer->setPartyName(Ea::taParty->getName());
-        if (socialWindow)
-            socialWindow->updateParty();
-    }
-}
-
-void PartyHandler::processPartyMessage(Net::MessageIn &msg)
-{
-    const int msgLength = msg.readInt16("len") - 8;
-    if (msgLength <= 0)
-        return;
-
-    const BeingId id = msg.readBeingId("id");
-    std::string chatMsg = msg.readString(msgLength, "message");
-
-    const size_t pos = chatMsg.find(" : ", 0);
-    if (pos != std::string::npos)
-        chatMsg.erase(0, pos + 3);
-
-    if (Ea::taParty && partyTab)
-    {
-        const PartyMember *const member = Ea::taParty->getMember(id);
-        if (member)
-        {
-            partyTab->chatLog(member->getName(), chatMsg);
-        }
-        else
-        {
-            NotifyManager::notify(NotifyTypes::PARTY_UNKNOWN_USER_MSG,
-                chatMsg);
-        }
-    }
-}
-
-void PartyHandler::processPartyInviteResponse(Net::MessageIn &msg)
-{
-    if (!partyTab)
-        return;
-
-    const std::string nick = msg.readString(24, "nick");
-
-    switch (msg.readInt32("result"))
-    {
-        case 0:
-            NotifyManager::notify(NotifyTypes::PARTY_INVITE_ALREADY_MEMBER,
-                nick);
-            break;
-        case 1:
-            NotifyManager::notify(NotifyTypes::PARTY_INVITE_REFUSED, nick);
-            break;
-        case 2:
-            NotifyManager::notify(NotifyTypes::PARTY_INVITE_DONE, nick);
-            break;
-        case 3:
-            NotifyManager::notify(NotifyTypes::PARTY_INVITE_PARTY_FULL,
-                nick);
-            break;
-        case 4:
-            NotifyManager::notify(NotifyTypes::PARTY_INVITE_PARTY_SAME_ACCOUNT,
-                nick);
-            break;
-        case 5:
-            NotifyManager::notify(
-                NotifyTypes::PARTY_INVITE_PARTY_BLOCKED_INVITE,
-                nick);
-            break;
-        case 7:
-            NotifyManager::notify(NotifyTypes::PARTY_INVITE_PARTY_NOT_ONLINE,
-                nick);
-            break;
-        default:
-            NotifyManager::notify(NotifyTypes::PARTY_INVITE_ERROR, nick);
-            break;
-    }
-}
-
 void PartyHandler::changeLeader(const std::string &name) const
 {
     const Being *const being = actorManager->findBeingByName(
@@ -465,54 +240,4 @@ void PartyHandler::allowInvite(const bool allow) const
     outMsg.writeInt8(static_cast<int8_t>(allow ? 1 : 0), "allow");
 }
 
-void PartyHandler::processPartyItemPickup(Net::MessageIn &msg)
-{
-    UNIMPLIMENTEDPACKET;
-    // +++ probably need add option to show pickup notifications
-    // in party tab
-    msg.readBeingId("account id");
-    msg.readInt16("item id");
-    msg.readUInt8("identify");
-    msg.readUInt8("attribute");
-    msg.readUInt8("refine");
-    for (int f = 0; f < 4; f++)
-        msg.readInt16("card");
-    msg.readInt16("equip location");
-    msg.readUInt8("item type");
-    // for color can be used ItemColorManager
-}
-
-void PartyHandler::processPartyLeader(Net::MessageIn &msg)
-{
-    PartyMember *const oldMember = Ea::taParty->getMember(
-        msg.readBeingId("old leder id"));
-    PartyMember *const newMember = Ea::taParty->getMember(
-        msg.readBeingId("new leder id"));
-    if (oldMember)
-        oldMember->setLeader(false);
-    if (newMember)
-        newMember->setLeader(true);
-}
-
-void PartyHandler::processPartyInvited(Net::MessageIn &msg)
-{
-    const BeingId id = msg.readBeingId("account id");
-    const std::string partyName = msg.readString(24, "party name");
-
-    std::string nick;
-
-    if (actorManager)
-    {
-        const Being *const being = actorManager->findBeing(id);
-        if (being)
-        {
-            if (being->getType() == ActorType::Player)
-                nick = being->getName();
-        }
-    }
-
-    if (socialWindow)
-        socialWindow->showPartyInvite(partyName, nick, 0);
-}
-
 }  // namespace EAthena
diff --git a/src/net/eathena/partyhandler.h b/src/net/eathena/partyhandler.h
index 80d85e6fb..c44b1eee9 100644
--- a/src/net/eathena/partyhandler.h
+++ b/src/net/eathena/partyhandler.h
@@ -62,25 +62,6 @@ class PartyHandler final : public MessageHandler, public Ea::PartyHandler
         void changeLeader(const std::string &name) const override final;
 
         void allowInvite(const bool allow) const override final;
-
-    protected:
-        static void processPartySettings(Net::MessageIn &msg);
-
-        static void processPartyInvitationStats(Net::MessageIn &msg);
-
-        static void processPartyMemberInfo(Net::MessageIn &msg);
-
-        static void processPartyInfo(Net::MessageIn &msg);
-
-        static void processPartyMessage(Net::MessageIn &msg);
-
-        static void processPartyInviteResponse(Net::MessageIn &msg);
-
-        static void processPartyItemPickup(Net::MessageIn &msg);
-
-        static void processPartyLeader(Net::MessageIn &msg);
-
-        static void processPartyInvited(Net::MessageIn &msg);
 };
 
 }  // namespace EAthena
diff --git a/src/net/eathena/partyrecv.cpp b/src/net/eathena/partyrecv.cpp
new file mode 100644
index 000000000..479433690
--- /dev/null
+++ b/src/net/eathena/partyrecv.cpp
@@ -0,0 +1,327 @@
+/*
+ *  The ManaPlus Client
+ *  Copyright (C) 2008  Lloyd Bryant <lloyd_bryant@netzero.net>
+ *  Copyright (C) 2011-2015  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 "net/eathena/partyrecv.h"
+
+#include "actormanager.h"
+#include "notifymanager.h"
+#include "party.h"
+
+#include "being/localplayer.h"
+
+#include "enums/resources/notifytypes.h"
+
+#include "gui/windows/chatwindow.h"
+#include "gui/windows/socialwindow.h"
+
+#include "gui/widgets/tabs/chat/partytab.h"
+
+#include "net/ea/partyrecv.h"
+
+#include "net/eathena/messageout.h"
+#include "net/eathena/protocol.h"
+
+#include "debug.h"
+
+namespace EAthena
+{
+
+void PartyRecv::processPartyInvitationStats(Net::MessageIn &msg)
+{
+    // +++ for now server allow only switch this option but not using it.
+    msg.readUInt8("allow party");
+}
+
+void PartyRecv::processPartyMemberInfo(Net::MessageIn &msg)
+{
+    const BeingId id = msg.readBeingId("account id");
+    const bool leader = msg.readInt32("leader") == 0U;
+    const int x = msg.readInt16("x");
+    const int y = msg.readInt16("y");
+    const bool online = msg.readInt8("online") == 0U;
+    msg.readString(24, "party name");
+    const std::string nick = msg.readString(24, "player name");
+    const std::string map = msg.readString(16, "map name");
+    msg.readInt8("party.item&1");
+    msg.readInt8("party.item&2");
+
+    if (!Ea::taParty)
+        return;
+
+    PartyMember *const member = Ea::taParty->addMember(id, nick);
+    if (member)
+    {
+        if (partyTab && member->getOnline() != online)
+            partyTab->showOnline(nick, fromBool(online, Online));
+        member->setLeader(leader);
+        member->setOnline(online);
+        member->setMap(map);
+        member->setX(x);
+        member->setY(y);
+    }
+}
+
+void PartyRecv::processPartySettings(Net::MessageIn &msg)
+{
+    if (!partyTab)
+    {
+        if (!chatWindow)
+            return;
+
+        Ea::PartyRecv::createTab();
+    }
+
+    msg.readInt32("party exp");
+    const PartyShareT exp = static_cast<PartyShareT>(
+        msg.readInt8("share exp"));
+    const PartyShareT item = static_cast<PartyShareT>(
+        msg.readInt8("share item"));
+    Ea::PartyRecv::processPartySettingsContinue(msg, exp, item);
+}
+
+void PartyRecv::processPartyInfo(Net::MessageIn &msg)
+{
+    bool isOldParty = false;
+    std::set<std::string> names;
+    std::set<std::string> onlineNames;
+    if (!Ea::taParty)
+    {
+        logger->log1("error: party empty in SMSG_PARTY_INFO");
+        Ea::taParty = Party::getParty(1);
+    }
+    if (!partyTab)
+        Ea::PartyRecv::createTab();
+
+    if (Ea::taParty)
+    {
+        if (Ea::taParty->getNumberOfElements() > 1)
+        {
+            isOldParty = true;
+            Ea::taParty->getNamesSet(names);
+            const Party::MemberList *const members = Ea::taParty->getMembers();
+            FOR_EACHP (Party::MemberList::const_iterator, it, members)
+            {
+                if ((*it)->getOnline())
+                    onlineNames.insert((*it)->getName());
+            }
+            if (localPlayer)
+                onlineNames.insert(localPlayer->getName());
+        }
+    }
+
+    if (!localPlayer)
+        logger->log1("error: localPlayer==0 in SMSG_PARTY_INFO");
+
+    if (Ea::taParty)
+        Ea::taParty->clearMembers();
+
+    const int length = msg.readInt16("len");
+    if (Ea::taParty)
+        Ea::taParty->setName(msg.readString(24, "party name"));
+
+    const int count = (length - 28) / 46;
+    if (localPlayer && Ea::taParty)
+    {
+        localPlayer->setParty(Ea::taParty);
+        localPlayer->setPartyName(Ea::taParty->getName());
+    }
+
+    for (int i = 0; i < count; i++)
+    {
+        const BeingId id = msg.readBeingId("account id");
+        std::string nick = msg.readString(24, "nick");
+        std::string map = msg.readString(16, "map name");
+        const bool leader = msg.readUInt8("leader") == 0U;
+        const bool online = msg.readUInt8("online") == 0U;
+
+        if (Ea::taParty)
+        {
+            bool joined(false);
+
+            if (isOldParty)
+            {
+                if (names.find(nick) == names.end())
+                {
+                    NotifyManager::notify(NotifyTypes::PARTY_USER_JOINED,
+                        nick);
+                    joined = true;
+                }
+            }
+            PartyMember *const member = Ea::taParty->addMember(id, nick);
+            if (member)
+            {
+                if (!joined && partyTab)
+                {
+                    if (!names.empty() && ((onlineNames.find(nick)
+                        == onlineNames.end() && online)
+                        || (onlineNames.find(nick) != onlineNames.end()
+                        && !online)))
+                    {
+                        partyTab->showOnline(nick, fromBool(online, Online));
+                    }
+
+                    member->setLeader(leader);
+                    member->setOnline(online);
+                    member->setMap(map);
+                }
+                else
+                {
+                    member->setLeader(leader);
+                    member->setOnline(online);
+                    member->setMap(map);
+                }
+            }
+        }
+    }
+
+    if (Ea::taParty)
+        Ea::taParty->sort();
+
+    if (localPlayer && Ea::taParty)
+    {
+        localPlayer->setParty(Ea::taParty);
+        localPlayer->setPartyName(Ea::taParty->getName());
+        if (socialWindow)
+            socialWindow->updateParty();
+    }
+}
+
+void PartyRecv::processPartyMessage(Net::MessageIn &msg)
+{
+    const int msgLength = msg.readInt16("len") - 8;
+    if (msgLength <= 0)
+        return;
+
+    const BeingId id = msg.readBeingId("id");
+    std::string chatMsg = msg.readString(msgLength, "message");
+
+    const size_t pos = chatMsg.find(" : ", 0);
+    if (pos != std::string::npos)
+        chatMsg.erase(0, pos + 3);
+
+    if (Ea::taParty && partyTab)
+    {
+        const PartyMember *const member = Ea::taParty->getMember(id);
+        if (member)
+        {
+            partyTab->chatLog(member->getName(), chatMsg);
+        }
+        else
+        {
+            NotifyManager::notify(NotifyTypes::PARTY_UNKNOWN_USER_MSG,
+                chatMsg);
+        }
+    }
+}
+
+void PartyRecv::processPartyInviteResponse(Net::MessageIn &msg)
+{
+    if (!partyTab)
+        return;
+
+    const std::string nick = msg.readString(24, "nick");
+
+    switch (msg.readInt32("result"))
+    {
+        case 0:
+            NotifyManager::notify(NotifyTypes::PARTY_INVITE_ALREADY_MEMBER,
+                nick);
+            break;
+        case 1:
+            NotifyManager::notify(NotifyTypes::PARTY_INVITE_REFUSED, nick);
+            break;
+        case 2:
+            NotifyManager::notify(NotifyTypes::PARTY_INVITE_DONE, nick);
+            break;
+        case 3:
+            NotifyManager::notify(NotifyTypes::PARTY_INVITE_PARTY_FULL,
+                nick);
+            break;
+        case 4:
+            NotifyManager::notify(NotifyTypes::PARTY_INVITE_PARTY_SAME_ACCOUNT,
+                nick);
+            break;
+        case 5:
+            NotifyManager::notify(
+                NotifyTypes::PARTY_INVITE_PARTY_BLOCKED_INVITE,
+                nick);
+            break;
+        case 7:
+            NotifyManager::notify(NotifyTypes::PARTY_INVITE_PARTY_NOT_ONLINE,
+                nick);
+            break;
+        default:
+            NotifyManager::notify(NotifyTypes::PARTY_INVITE_ERROR, nick);
+            break;
+    }
+}
+
+void PartyRecv::processPartyItemPickup(Net::MessageIn &msg)
+{
+    UNIMPLIMENTEDPACKET;
+    // +++ probably need add option to show pickup notifications
+    // in party tab
+    msg.readBeingId("account id");
+    msg.readInt16("item id");
+    msg.readUInt8("identify");
+    msg.readUInt8("attribute");
+    msg.readUInt8("refine");
+    for (int f = 0; f < 4; f++)
+        msg.readInt16("card");
+    msg.readInt16("equip location");
+    msg.readUInt8("item type");
+    // for color can be used ItemColorManager
+}
+
+void PartyRecv::processPartyLeader(Net::MessageIn &msg)
+{
+    PartyMember *const oldMember = Ea::taParty->getMember(
+        msg.readBeingId("old leder id"));
+    PartyMember *const newMember = Ea::taParty->getMember(
+        msg.readBeingId("new leder id"));
+    if (oldMember)
+        oldMember->setLeader(false);
+    if (newMember)
+        newMember->setLeader(true);
+}
+
+void PartyRecv::processPartyInvited(Net::MessageIn &msg)
+{
+    const BeingId id = msg.readBeingId("account id");
+    const std::string partyName = msg.readString(24, "party name");
+
+    std::string nick;
+
+    if (actorManager)
+    {
+        const Being *const being = actorManager->findBeing(id);
+        if (being)
+        {
+            if (being->getType() == ActorType::Player)
+                nick = being->getName();
+        }
+    }
+
+    if (socialWindow)
+        socialWindow->showPartyInvite(partyName, nick, 0);
+}
+
+}  // namespace EAthena
diff --git a/src/net/eathena/partyrecv.h b/src/net/eathena/partyrecv.h
new file mode 100644
index 000000000..623051a4f
--- /dev/null
+++ b/src/net/eathena/partyrecv.h
@@ -0,0 +1,45 @@
+/*
+ *  The ManaPlus Client
+ *  Copyright (C) 2008  Lloyd Bryant <lloyd_bryant@netzero.net>
+ *  Copyright (C) 2011-2015  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 NET_EATHENA_PARTYRECV_H
+#define NET_EATHENA_PARTYRECV_H
+
+#include "net/eathena/messagehandler.h"
+
+#include "net/ea/partyhandler.h"
+
+namespace EAthena
+{
+    namespace PartyRecv
+    {
+        void processPartySettings(Net::MessageIn &msg);
+        void processPartyInvitationStats(Net::MessageIn &msg);
+        void processPartyMemberInfo(Net::MessageIn &msg);
+        void processPartyInfo(Net::MessageIn &msg);
+        void processPartyMessage(Net::MessageIn &msg);
+        void processPartyInviteResponse(Net::MessageIn &msg);
+        void processPartyItemPickup(Net::MessageIn &msg);
+        void processPartyLeader(Net::MessageIn &msg);
+        void processPartyInvited(Net::MessageIn &msg);
+    }  // namespace PartyRecv
+}  // namespace EAthena
+
+#endif  // NET_EATHENA_PARTYRECV_H
diff --git a/src/net/tmwa/partyhandler.cpp b/src/net/tmwa/partyhandler.cpp
index 92e26ec81..90fbee9d3 100644
--- a/src/net/tmwa/partyhandler.cpp
+++ b/src/net/tmwa/partyhandler.cpp
@@ -34,7 +34,10 @@
 
 #include "gui/widgets/tabs/chat/partytab.h"
 
+#include "net/ea/partyrecv.h"
+
 #include "net/tmwa/messageout.h"
+#include "net/tmwa/partyrecv.h"
 #include "net/tmwa/protocol.h"
 
 #include "debug.h"
@@ -76,34 +79,34 @@ void PartyHandler::handleMessage(Net::MessageIn &msg)
     switch (msg.getId())
     {
         case SMSG_PARTY_CREATE:
-            processPartyCreate(msg);
+            Ea::PartyRecv::processPartyCreate(msg);
             break;
         case SMSG_PARTY_INFO:
-            processPartyInfo(msg);
+            PartyRecv::processPartyInfo(msg);
             break;
         case SMSG_PARTY_INVITE_RESPONSE:
-            processPartyInviteResponse(msg);
+            PartyRecv::processPartyInviteResponse(msg);
             break;
         case SMSG_PARTY_INVITED:
-            processPartyInvited(msg);
+            PartyRecv::processPartyInvited(msg);
             break;
         case SMSG_PARTY_SETTINGS:
-            processPartySettings(msg);
+            PartyRecv::processPartySettings(msg);
             break;
         case SMSG_PARTY_MOVE:
-            processPartyMove(msg);
+            PartyRecv::processPartyMove(msg);
             break;
         case SMSG_PARTY_LEAVE:
-            processPartyLeave(msg);
+            Ea::PartyRecv::processPartyLeave(msg);
             break;
         case SMSG_PARTY_UPDATE_HP:
-            processPartyUpdateHp(msg);
+            PartyRecv::processPartyUpdateHp(msg);
             break;
         case SMSG_PARTY_UPDATE_COORDS:
-            processPartyUpdateCoords(msg);
+            Ea::PartyRecv::processPartyUpdateCoords(msg);
             break;
         case SMSG_PARTY_MESSAGE:
-            processPartyMessage(msg);
+            PartyRecv::processPartyMessage(msg);
             break;
 
         default:
@@ -189,7 +192,8 @@ void PartyHandler::setShareExperience(const PartyShareT share) const
 
     createOutPacket(CMSG_PARTY_SETTINGS);
     outMsg.writeInt16(static_cast<int16_t>(share), "share exp");
-    outMsg.writeInt16(static_cast<int16_t>(mShareItems), "share items");
+    outMsg.writeInt16(static_cast<int16_t>(Ea::PartyRecv::mShareItems),
+        "share items");
 }
 
 void PartyHandler::setShareItems(const PartyShareT share) const
@@ -198,185 +202,11 @@ void PartyHandler::setShareItems(const PartyShareT share) const
         return;
 
     createOutPacket(CMSG_PARTY_SETTINGS);
-    outMsg.writeInt16(static_cast<int16_t>(mShareExp), "share exp");
+    outMsg.writeInt16(static_cast<int16_t>(Ea::PartyRecv::mShareExp),
+        "share exp");
     outMsg.writeInt16(static_cast<int16_t>(share), "share items");
 }
 
-void PartyHandler::processPartySettings(Net::MessageIn &msg)
-{
-    if (!partyTab)
-    {
-        if (!chatWindow)
-            return;
-
-        createTab();
-    }
-
-    // These seem to indicate the sharing mode for exp and items
-    const PartyShareT exp = static_cast<PartyShareT>(
-        msg.readInt16("share exp"));
-    const PartyShareT item = static_cast<PartyShareT>(
-        msg.readInt16("share items"));
-    processPartySettingsContinue(msg, exp, item);
-}
-
-void PartyHandler::processPartyInfo(Net::MessageIn &msg)
-{
-    bool isOldParty = false;
-    std::set<std::string> names;
-    std::set<std::string> onlineNames;
-    if (!Ea::taParty)
-    {
-        logger->log1("error: party empty in SMSG_PARTY_INFO");
-        Ea::taParty = Party::getParty(1);
-    }
-    if (Ea::taParty)
-    {
-        if (Ea::taParty->getNumberOfElements() > 1)
-        {
-            isOldParty = true;
-            Ea::taParty->getNamesSet(names);
-            const Party::MemberList *const members = Ea::taParty->getMembers();
-            FOR_EACHP (Party::MemberList::const_iterator, it, members)
-            {
-                if ((*it)->getOnline())
-                    onlineNames.insert((*it)->getName());
-            }
-            if (localPlayer)
-                onlineNames.insert(localPlayer->getName());
-        }
-    }
-
-    if (!localPlayer)
-        logger->log1("error: localPlayer==0 in SMSG_PARTY_INFO");
-
-    if (Ea::taParty)
-        Ea::taParty->clearMembers();
-
-    const int length = msg.readInt16("len");
-    if (Ea::taParty)
-        Ea::taParty->setName(msg.readString(24, "party name"));
-
-    const int count = (length - 28) / 46;
-    if (localPlayer && Ea::taParty)
-    {
-        localPlayer->setParty(Ea::taParty);
-        localPlayer->setPartyName(Ea::taParty->getName());
-    }
-
-    for (int i = 0; i < count; i++)
-    {
-        const BeingId id = msg.readBeingId("id");
-        std::string nick = msg.readString(24, "nick");
-        std::string map = msg.readString(16, "map");
-        const bool leader = msg.readUInt8("leader") == 0U;
-        const bool online = msg.readUInt8("online") == 0U;
-
-        if (Ea::taParty)
-        {
-            bool joined(false);
-
-            if (isOldParty)
-            {
-                if (names.find(nick) == names.end())
-                {
-                    NotifyManager::notify(NotifyTypes::PARTY_USER_JOINED,
-                        nick);
-                    joined = true;
-                }
-            }
-            PartyMember *const member = Ea::taParty->addMember(id, nick);
-            if (member)
-            {
-                if (!joined && partyTab)
-                {
-                    if (!names.empty() && ((onlineNames.find(nick)
-                        == onlineNames.end() && online)
-                        || (onlineNames.find(nick) != onlineNames.end()
-                        && !online)))
-                    {
-                        partyTab->showOnline(nick, fromBool(online, Online));
-                    }
-
-                    member->setLeader(leader);
-                    member->setOnline(online);
-                    member->setMap(map);
-                }
-                else
-                {
-                    member->setLeader(leader);
-                    member->setOnline(online);
-                    member->setMap(map);
-                }
-            }
-        }
-    }
-
-    if (Ea::taParty)
-        Ea::taParty->sort();
-
-    if (localPlayer && Ea::taParty)
-    {
-        localPlayer->setParty(Ea::taParty);
-        localPlayer->setPartyName(Ea::taParty->getName());
-        if (socialWindow)
-            socialWindow->updateParty();
-    }
-}
-
-void PartyHandler::processPartyMessage(Net::MessageIn &msg)
-{
-    const int msgLength = msg.readInt16("len") - 8;
-    if (msgLength <= 0)
-        return;
-
-    const BeingId id = msg.readBeingId("id");
-    const std::string chatMsg = msg.readString(msgLength, "message");
-
-    if (Ea::taParty && partyTab)
-    {
-        const PartyMember *const member = Ea::taParty->getMember(id);
-        if (member)
-        {
-            partyTab->chatLog(member->getName(), chatMsg);
-        }
-        else
-        {
-            NotifyManager::notify(NotifyTypes::PARTY_UNKNOWN_USER_MSG,
-                chatMsg);
-        }
-    }
-}
-
-void PartyHandler::processPartyInviteResponse(Net::MessageIn &msg)
-{
-    if (!partyTab)
-        return;
-
-    const std::string nick = msg.readString(24, "nick");
-
-    switch (msg.readUInt8("status"))
-    {
-        case 0:
-            NotifyManager::notify(NotifyTypes::PARTY_INVITE_ALREADY_MEMBER,
-                nick);
-            break;
-        case 1:
-            NotifyManager::notify(NotifyTypes::PARTY_INVITE_REFUSED, nick);
-            break;
-        case 2:
-            NotifyManager::notify(NotifyTypes::PARTY_INVITE_DONE, nick);
-            break;
-        case 3:
-            NotifyManager::notify(NotifyTypes::PARTY_INVITE_PARTY_FULL,
-                nick);
-            break;
-        default:
-            NotifyManager::notify(NotifyTypes::PARTY_INVITE_ERROR, nick);
-            break;
-    }
-}
-
 void PartyHandler::changeLeader(const std::string &name A_UNUSED) const
 {
 }
@@ -385,78 +215,4 @@ void PartyHandler::allowInvite(const bool allow A_UNUSED) const
 {
 }
 
-void PartyHandler::processPartyInvited(Net::MessageIn &msg)
-{
-    const BeingId id = msg.readBeingId("account id");
-    const std::string partyName = msg.readString(24, "party name");
-    std::string nick;
-
-    if (actorManager)
-    {
-        const Being *const being = actorManager->findBeing(id);
-        if (being)
-        {
-            if (being->getType() == ActorType::Player)
-                nick = being->getName();
-        }
-    }
-
-    if (socialWindow)
-        socialWindow->showPartyInvite(partyName, nick, 0);
-}
-
-void PartyHandler::processPartyMove(Net::MessageIn &msg)
-{
-    const BeingId id = msg.readBeingId("id");
-    PartyMember *m = nullptr;
-    if (Ea::taParty)
-        m = Ea::taParty->getMember(id);
-    if (m)
-    {
-        msg.readInt32("unused");
-        m->setX(msg.readInt16("x"));
-        m->setY(msg.readInt16("y"));
-        const bool online = msg.readUInt8("online") != 0;
-        if (m->getOnline() != online)
-            partyTab->showOnline(m->getName(), fromBool(online, Online));
-        m->setOnline(online);
-        msg.readString(24, "party");
-        msg.readString(24, "nick");
-        m->setMap(msg.readString(16, "map"));
-    }
-    else
-    {
-        msg.readInt32("unused");
-        msg.readInt16("x");
-        msg.readInt16("y");
-        msg.readUInt8("online");
-        msg.readString(24, "party");
-        msg.readString(24, "nick");
-        msg.readString(16, "map");
-    }
-}
-
-void PartyHandler::processPartyUpdateHp(Net::MessageIn &msg)
-{
-    const BeingId id = msg.readBeingId("id");
-    const int hp = msg.readInt16("hp");
-    const int maxhp = msg.readInt16("max hp");
-    PartyMember *m = nullptr;
-    if (Ea::taParty)
-        m = Ea::taParty->getMember(id);
-    if (m)
-    {
-        m->setHp(hp);
-        m->setMaxHp(maxhp);
-    }
-
-    // The server only sends this when the member is in range, so
-    // lets make sure they get the party hilight.
-    if (actorManager && Ea::taParty)
-    {
-        if (Being *const b = actorManager->findBeing(id))
-            b->setParty(Ea::taParty);
-    }
-}
-
 }  // namespace TmwAthena
diff --git a/src/net/tmwa/partyhandler.h b/src/net/tmwa/partyhandler.h
index 30c837c37..47fe9c232 100644
--- a/src/net/tmwa/partyhandler.h
+++ b/src/net/tmwa/partyhandler.h
@@ -62,21 +62,6 @@ class PartyHandler final : public MessageHandler, public Ea::PartyHandler
         void changeLeader(const std::string &name) const override final;
 
         void allowInvite(const bool allow) const override final;
-
-    protected:
-        static void processPartySettings(Net::MessageIn &msg);
-
-        static void processPartyInfo(Net::MessageIn &msg);
-
-        static void processPartyMessage(Net::MessageIn &msg);
-
-        static void processPartyInviteResponse(Net::MessageIn &msg);
-
-        static void processPartyInvited(Net::MessageIn &msg);
-
-        static void processPartyMove(Net::MessageIn &msg);
-
-        static void processPartyUpdateHp(Net::MessageIn &msg);
 };
 
 }  // namespace TmwAthena
diff --git a/src/net/tmwa/partyrecv.cpp b/src/net/tmwa/partyrecv.cpp
new file mode 100644
index 000000000..eaee64943
--- /dev/null
+++ b/src/net/tmwa/partyrecv.cpp
@@ -0,0 +1,296 @@
+/*
+ *  The ManaPlus Client
+ *  Copyright (C) 2008  Lloyd Bryant <lloyd_bryant@netzero.net>
+ *  Copyright (C) 2011-2015  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 "net/tmwa/partyrecv.h"
+
+#include "actormanager.h"
+#include "notifymanager.h"
+#include "party.h"
+
+#include "being/localplayer.h"
+
+#include "enums/resources/notifytypes.h"
+
+#include "gui/windows/chatwindow.h"
+#include "gui/windows/socialwindow.h"
+
+#include "gui/widgets/tabs/chat/partytab.h"
+
+#include "net/ea/partyrecv.h"
+
+#include "net/tmwa/messageout.h"
+#include "net/tmwa/protocol.h"
+
+#include "debug.h"
+
+namespace TmwAthena
+{
+
+void PartyRecv::processPartySettings(Net::MessageIn &msg)
+{
+    if (!partyTab)
+    {
+        if (!chatWindow)
+            return;
+
+        Ea::PartyRecv::createTab();
+    }
+
+    // These seem to indicate the sharing mode for exp and items
+    const PartyShareT exp = static_cast<PartyShareT>(
+        msg.readInt16("share exp"));
+    const PartyShareT item = static_cast<PartyShareT>(
+        msg.readInt16("share items"));
+    Ea::PartyRecv::processPartySettingsContinue(msg, exp, item);
+}
+
+void PartyRecv::processPartyInfo(Net::MessageIn &msg)
+{
+    bool isOldParty = false;
+    std::set<std::string> names;
+    std::set<std::string> onlineNames;
+    if (!Ea::taParty)
+    {
+        logger->log1("error: party empty in SMSG_PARTY_INFO");
+        Ea::taParty = Party::getParty(1);
+    }
+    if (Ea::taParty)
+    {
+        if (Ea::taParty->getNumberOfElements() > 1)
+        {
+            isOldParty = true;
+            Ea::taParty->getNamesSet(names);
+            const Party::MemberList *const members = Ea::taParty->getMembers();
+            FOR_EACHP (Party::MemberList::const_iterator, it, members)
+            {
+                if ((*it)->getOnline())
+                    onlineNames.insert((*it)->getName());
+            }
+            if (localPlayer)
+                onlineNames.insert(localPlayer->getName());
+        }
+    }
+
+    if (!localPlayer)
+        logger->log1("error: localPlayer==0 in SMSG_PARTY_INFO");
+
+    if (Ea::taParty)
+        Ea::taParty->clearMembers();
+
+    const int length = msg.readInt16("len");
+    if (Ea::taParty)
+        Ea::taParty->setName(msg.readString(24, "party name"));
+
+    const int count = (length - 28) / 46;
+    if (localPlayer && Ea::taParty)
+    {
+        localPlayer->setParty(Ea::taParty);
+        localPlayer->setPartyName(Ea::taParty->getName());
+    }
+
+    for (int i = 0; i < count; i++)
+    {
+        const BeingId id = msg.readBeingId("id");
+        std::string nick = msg.readString(24, "nick");
+        std::string map = msg.readString(16, "map");
+        const bool leader = msg.readUInt8("leader") == 0U;
+        const bool online = msg.readUInt8("online") == 0U;
+
+        if (Ea::taParty)
+        {
+            bool joined(false);
+
+            if (isOldParty)
+            {
+                if (names.find(nick) == names.end())
+                {
+                    NotifyManager::notify(NotifyTypes::PARTY_USER_JOINED,
+                        nick);
+                    joined = true;
+                }
+            }
+            PartyMember *const member = Ea::taParty->addMember(id, nick);
+            if (member)
+            {
+                if (!joined && partyTab)
+                {
+                    if (!names.empty() && ((onlineNames.find(nick)
+                        == onlineNames.end() && online)
+                        || (onlineNames.find(nick) != onlineNames.end()
+                        && !online)))
+                    {
+                        partyTab->showOnline(nick, fromBool(online, Online));
+                    }
+
+                    member->setLeader(leader);
+                    member->setOnline(online);
+                    member->setMap(map);
+                }
+                else
+                {
+                    member->setLeader(leader);
+                    member->setOnline(online);
+                    member->setMap(map);
+                }
+            }
+        }
+    }
+
+    if (Ea::taParty)
+        Ea::taParty->sort();
+
+    if (localPlayer && Ea::taParty)
+    {
+        localPlayer->setParty(Ea::taParty);
+        localPlayer->setPartyName(Ea::taParty->getName());
+        if (socialWindow)
+            socialWindow->updateParty();
+    }
+}
+
+void PartyRecv::processPartyMessage(Net::MessageIn &msg)
+{
+    const int msgLength = msg.readInt16("len") - 8;
+    if (msgLength <= 0)
+        return;
+
+    const BeingId id = msg.readBeingId("id");
+    const std::string chatMsg = msg.readString(msgLength, "message");
+
+    if (Ea::taParty && partyTab)
+    {
+        const PartyMember *const member = Ea::taParty->getMember(id);
+        if (member)
+        {
+            partyTab->chatLog(member->getName(), chatMsg);
+        }
+        else
+        {
+            NotifyManager::notify(NotifyTypes::PARTY_UNKNOWN_USER_MSG,
+                chatMsg);
+        }
+    }
+}
+
+void PartyRecv::processPartyInviteResponse(Net::MessageIn &msg)
+{
+    if (!partyTab)
+        return;
+
+    const std::string nick = msg.readString(24, "nick");
+
+    switch (msg.readUInt8("status"))
+    {
+        case 0:
+            NotifyManager::notify(NotifyTypes::PARTY_INVITE_ALREADY_MEMBER,
+                nick);
+            break;
+        case 1:
+            NotifyManager::notify(NotifyTypes::PARTY_INVITE_REFUSED, nick);
+            break;
+        case 2:
+            NotifyManager::notify(NotifyTypes::PARTY_INVITE_DONE, nick);
+            break;
+        case 3:
+            NotifyManager::notify(NotifyTypes::PARTY_INVITE_PARTY_FULL,
+                nick);
+            break;
+        default:
+            NotifyManager::notify(NotifyTypes::PARTY_INVITE_ERROR, nick);
+            break;
+    }
+}
+
+void PartyRecv::processPartyInvited(Net::MessageIn &msg)
+{
+    const BeingId id = msg.readBeingId("account id");
+    const std::string partyName = msg.readString(24, "party name");
+    std::string nick;
+
+    if (actorManager)
+    {
+        const Being *const being = actorManager->findBeing(id);
+        if (being)
+        {
+            if (being->getType() == ActorType::Player)
+                nick = being->getName();
+        }
+    }
+
+    if (socialWindow)
+        socialWindow->showPartyInvite(partyName, nick, 0);
+}
+
+void PartyRecv::processPartyMove(Net::MessageIn &msg)
+{
+    const BeingId id = msg.readBeingId("id");
+    PartyMember *m = nullptr;
+    if (Ea::taParty)
+        m = Ea::taParty->getMember(id);
+    if (m)
+    {
+        msg.readInt32("unused");
+        m->setX(msg.readInt16("x"));
+        m->setY(msg.readInt16("y"));
+        const bool online = msg.readUInt8("online") != 0;
+        if (m->getOnline() != online)
+            partyTab->showOnline(m->getName(), fromBool(online, Online));
+        m->setOnline(online);
+        msg.readString(24, "party");
+        msg.readString(24, "nick");
+        m->setMap(msg.readString(16, "map"));
+    }
+    else
+    {
+        msg.readInt32("unused");
+        msg.readInt16("x");
+        msg.readInt16("y");
+        msg.readUInt8("online");
+        msg.readString(24, "party");
+        msg.readString(24, "nick");
+        msg.readString(16, "map");
+    }
+}
+
+void PartyRecv::processPartyUpdateHp(Net::MessageIn &msg)
+{
+    const BeingId id = msg.readBeingId("id");
+    const int hp = msg.readInt16("hp");
+    const int maxhp = msg.readInt16("max hp");
+    PartyMember *m = nullptr;
+    if (Ea::taParty)
+        m = Ea::taParty->getMember(id);
+    if (m)
+    {
+        m->setHp(hp);
+        m->setMaxHp(maxhp);
+    }
+
+    // The server only sends this when the member is in range, so
+    // lets make sure they get the party hilight.
+    if (actorManager && Ea::taParty)
+    {
+        if (Being *const b = actorManager->findBeing(id))
+            b->setParty(Ea::taParty);
+    }
+}
+
+}  // namespace TmwAthena
diff --git a/src/net/tmwa/partyrecv.h b/src/net/tmwa/partyrecv.h
new file mode 100644
index 000000000..0d94cd738
--- /dev/null
+++ b/src/net/tmwa/partyrecv.h
@@ -0,0 +1,43 @@
+/*
+ *  The ManaPlus Client
+ *  Copyright (C) 2008  Lloyd Bryant <lloyd_bryant@netzero.net>
+ *  Copyright (C) 2011-2015  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 NET_TMWA_PARTYRECV_H
+#define NET_TMWA_PARTYRECV_H
+
+#include "net/tmwa/messagehandler.h"
+
+#include "net/ea/partyhandler.h"
+
+namespace TmwAthena
+{
+    namespace PartyRecv
+    {
+        void processPartySettings(Net::MessageIn &msg);
+        void processPartyInfo(Net::MessageIn &msg);
+        void processPartyMessage(Net::MessageIn &msg);
+        void processPartyInviteResponse(Net::MessageIn &msg);
+        void processPartyInvited(Net::MessageIn &msg);
+        void processPartyMove(Net::MessageIn &msg);
+        void processPartyUpdateHp(Net::MessageIn &msg);
+    }  // namespace PartyRecv
+}  // namespace TmwAthena
+
+#endif  // NET_TMWA_PARTYRECV_H
-- 
cgit v1.2.3-70-g09d2