From 0e9ef0640cab30431bef8a4683a5da549d5c8f88 Mon Sep 17 00:00:00 2001
From: Andrei Karas <akaras@inbox.ru>
Date: Sat, 30 Jul 2011 01:02:50 +0300
Subject: Extract shared logic from guildhandler and partyhandler netcode to ea
 namespace.

---
 src/CMakeLists.txt              |   8 +
 src/Makefile.am                 |   8 +
 src/net/ea/gamehandler.cpp      |   2 +-
 src/net/ea/gamehandler.h        |   1 -
 src/net/ea/gui/guildtab.cpp     | 154 +++++++++++
 src/net/ea/gui/guildtab.h       |  57 ++++
 src/net/ea/gui/partytab.cpp     | 245 +++++++++++++++++
 src/net/ea/gui/partytab.h       |  58 ++++
 src/net/ea/guildhandler.cpp     | 590 ++++++++++++++++++++++++++++++++++++++++
 src/net/ea/guildhandler.h       | 115 ++++++++
 src/net/ea/partyhandler.cpp     | 451 ++++++++++++++++++++++++++++++
 src/net/ea/partyhandler.h       |  91 +++++++
 src/net/tmwa/generalhandler.cpp |  20 +-
 src/net/tmwa/gui/guildtab.cpp   |  99 +------
 src/net/tmwa/gui/guildtab.h     |  20 +-
 src/net/tmwa/gui/partytab.cpp   | 188 +------------
 src/net/tmwa/gui/partytab.h     |  20 +-
 src/net/tmwa/guildhandler.cpp   | 513 +++-------------------------------
 src/net/tmwa/guildhandler.h     |   8 +-
 src/net/tmwa/partyhandler.cpp   | 414 ++--------------------------
 src/net/tmwa/partyhandler.h     |  21 +-
 21 files changed, 1865 insertions(+), 1218 deletions(-)
 create mode 100644 src/net/ea/gui/guildtab.cpp
 create mode 100644 src/net/ea/gui/guildtab.h
 create mode 100644 src/net/ea/gui/partytab.cpp
 create mode 100644 src/net/ea/gui/partytab.h
 create mode 100644 src/net/ea/guildhandler.cpp
 create mode 100644 src/net/ea/guildhandler.h
 create mode 100644 src/net/ea/partyhandler.cpp
 create mode 100644 src/net/ea/partyhandler.h

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 5d2cea383..27067bc92 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -676,6 +676,10 @@ SET(SRCS_GUICHAN
     )
 
 SET(SRCS_EVOL
+    net/ea/gui/guildtab.cpp
+    net/ea/gui/guildtab.h
+    net/ea/gui/partytab.cpp
+    net/ea/gui/partytab.h
     net/ea/adminhandler.cpp
     net/ea/adminhandler.h
     net/ea/beinghandler.cpp
@@ -689,8 +693,12 @@ SET(SRCS_EVOL
     net/ea/eaprotocol.h
     net/ea/gamehandler.cpp
     net/ea/gamehandler.h
+    net/ea/guildhandler.cpp
+    net/ea/guildhandler.h
     net/ea/loginhandler.cpp
     net/ea/loginhandler.h
+    net/ea/partyhandler.cpp
+    net/ea/partyhandler.h
     net/ea/token.h
     )
 
diff --git a/src/Makefile.am b/src/Makefile.am
index 44212fab8..ab935904d 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -660,6 +660,10 @@ manaplus_SOURCES += enet/callbacks.c \
 endif
 
 manaplus_SOURCES += \
+	      net/ea/gui/guildtab.cpp \
+	      net/ea/gui/guildtab.h \
+	      net/ea/gui/partytab.cpp \
+	      net/ea/gui/partytab.h \
 	      net/ea/adminhandler.cpp \
 	      net/ea/adminhandler.h \
 	      net/ea/beinghandler.cpp \
@@ -672,9 +676,13 @@ manaplus_SOURCES += \
 	      net/ea/chathandler.h \
 	      net/ea/gamehandler.cpp \
 	      net/ea/gamehandler.h \
+	      net/ea/guildhandler.cpp \
+	      net/ea/guildhandler.h \
 	      net/ea/eaprotocol.h \
 	      net/ea/loginhandler.cpp \
 	      net/ea/loginhandler.h \
+	      net/ea/partyhandler.cpp \
+	      net/ea/partyhandler.h \
 	      net/ea/token.h \
 	      net/tmwa/gui/guildtab.cpp \
 	      net/tmwa/gui/guildtab.h \
diff --git a/src/net/ea/gamehandler.cpp b/src/net/ea/gamehandler.cpp
index 694600322..0b6b8a040 100644
--- a/src/net/ea/gamehandler.cpp
+++ b/src/net/ea/gamehandler.cpp
@@ -98,4 +98,4 @@ void GameHandler::processMapQuitResponse(Net::MessageIn &msg)
         new OkDialog(_("Game"), _("Request to quit denied!"), NULL);
 }
 
-} // namespace TmwAthena
+} // namespace Ea
diff --git a/src/net/ea/gamehandler.h b/src/net/ea/gamehandler.h
index 16168636b..abfaaa6b4 100644
--- a/src/net/ea/gamehandler.h
+++ b/src/net/ea/gamehandler.h
@@ -52,7 +52,6 @@ class GameHandler : public Net::GameHandler, public Mana::Listener
 
         virtual void setMap(const std::string map);
 
-        /** The tmwAthena protocol is making use of the MP status bar. */
         virtual bool canUseMagicBar() const
         { return true; }
 
diff --git a/src/net/ea/gui/guildtab.cpp b/src/net/ea/gui/guildtab.cpp
new file mode 100644
index 000000000..037885fd1
--- /dev/null
+++ b/src/net/ea/gui/guildtab.cpp
@@ -0,0 +1,154 @@
+/*
+ *  The ManaPlus Client
+ *  Copyright (C) 2008-2009  The Mana World Development Team
+ *  Copyright (C) 2009-2010  The Mana Developers
+ *  Copyright (C) 2011  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/gui/guildtab.h"
+
+#include "chatlog.h"
+#include "commandhandler.h"
+#include "guild.h"
+#include "localplayer.h"
+
+#include "gui/theme.h"
+
+#include "net/net.h"
+
+#include "net/ea/guildhandler.h"
+
+#include "net/guildhandler.h"
+
+#include "resources/iteminfo.h"
+#include "resources/itemdb.h"
+
+#include "utils/dtor.h"
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+#include "debug.h"
+
+namespace Ea
+{
+extern Guild *taGuild;
+
+GuildTab::GuildTab() :
+    ChatTab(_("Guild"))
+{
+    setTabColor(&Theme::getThemeColor(Theme::GUILD_CHAT_TAB));
+}
+
+GuildTab::~GuildTab()
+{
+}
+
+bool GuildTab::handleCommand(const std::string &type, const std::string &args)
+{
+    if (type == "help")
+    {
+        if (args == "invite")
+        {
+            chatLog(_("Command: /invite <nick>"));
+            chatLog(_("This command invites <nick> to the guild you're in."));
+            chatLog(_("If the <nick> has spaces in it, enclose it in "
+                            "double quotes (\")."));
+        }
+        else if (args == "leave")
+        {
+            chatLog(_("Command: /leave"));
+            chatLog(_("This command causes the player to leave the guild."));
+        }
+        else
+            return false;
+    }
+/*
+    else if (type == "create" || type == "new")
+    {
+        if (args.empty())
+            chatLog(_("Guild name is missing."), BY_SERVER);
+        else
+            Net::getGuildHandler()->create(args);
+    }
+*/
+    else if (type == "invite" && taGuild)
+    {
+        Net::getGuildHandler()->invite(taGuild->getId(), args);
+    }
+    else if (type == "leave" && taGuild)
+    {
+        Net::getGuildHandler()->leave(taGuild->getId());
+    }
+    else if (type == "kick" && taGuild)
+    {
+        Net::getGuildHandler()->kick(taGuild->getMember(args));
+    }
+    else if (type == "notice" && taGuild)
+    {
+        std::string str1 = args.substr(0, 60);
+        std::string str2 = "";
+        if (args.size() > 60)
+            str2 = args.substr(60);
+        Net::getGuildHandler()->changeNotice(taGuild->getId(), str1, str2);
+    }
+    else
+    {
+        return false;
+    }
+
+    return true;
+}
+
+void GuildTab::handleInput(const std::string &msg)
+{
+    if (!taGuild)
+        return;
+
+    if (chatWindow)
+    {
+        Net::getGuildHandler()->chat(taGuild->getId(),
+            chatWindow->doReplace(msg));
+    }
+    else
+    {
+        Net::getGuildHandler()->chat(taGuild->getId(), msg);
+    }
+}
+
+void GuildTab::showHelp()
+{
+    chatLog(_("/help > Display this help."));
+    chatLog(_("/invite > Invite a player to your guild"));
+    chatLog(_("/leave > Leave the guild you are in"));
+    chatLog(_("/kick > Kick some one from the guild you are in"));
+}
+
+void GuildTab::getAutoCompleteList(std::vector<std::string> &names) const
+{
+    if (taGuild)
+        taGuild->getNames(names);
+    names.push_back("/notice ");
+}
+
+void GuildTab::saveToLogFile(std::string &msg)
+{
+    if (chatLogger)
+        chatLogger->log("#Guild", msg);
+}
+
+} // namespace Ea
diff --git a/src/net/ea/gui/guildtab.h b/src/net/ea/gui/guildtab.h
new file mode 100644
index 000000000..f4b87f8a2
--- /dev/null
+++ b/src/net/ea/gui/guildtab.h
@@ -0,0 +1,57 @@
+/*
+ *  The ManaPlus Client
+ *  Copyright (C) 2009  The Mana World Development Team
+ *  Copyright (C) 2009-2010  The Mana Developers
+ *  Copyright (C) 2011  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 EA_GUILDTAB_H
+#define EA_GUILDTAB_H
+
+#include "gui/widgets/chattab.h"
+
+namespace Ea
+{
+
+/**
+ * A tab for a guild chat channel.
+ */
+class GuildTab : public ChatTab
+{
+    public:
+        GuildTab();
+
+        ~GuildTab();
+
+        bool handleCommand(const std::string &type, const std::string &args);
+
+        void showHelp();
+
+        void saveToLogFile(std::string &msg);
+
+        int getType() const { return ChatTab::TAB_GUILD; }
+
+    protected:
+        void handleInput(const std::string &msg);
+
+        void getAutoCompleteList(std::vector<std::string> &names) const;
+};
+
+} // namespace Ea
+
+#endif // EA_GUILDTAB_H
diff --git a/src/net/ea/gui/partytab.cpp b/src/net/ea/gui/partytab.cpp
new file mode 100644
index 000000000..02e0910a7
--- /dev/null
+++ b/src/net/ea/gui/partytab.cpp
@@ -0,0 +1,245 @@
+/*
+ *  The ManaPlus Client
+ *  Copyright (C) 2008-2009  The Mana World Development Team
+ *  Copyright (C) 2009-2010  The Mana Developers
+ *  Copyright (C) 2011  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/gui/partytab.h"
+
+#include "chatlog.h"
+#include "commandhandler.h"
+#include "localplayer.h"
+#include "party.h"
+
+#include "gui/theme.h"
+
+#include "net/net.h"
+#include "net/partyhandler.h"
+
+#include "resources/iteminfo.h"
+#include "resources/itemdb.h"
+
+#include "utils/dtor.h"
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+#include "net/chathandler.h"
+
+#include "debug.h"
+
+namespace Ea
+{
+
+PartyTab::PartyTab() :
+    ChatTab(_("Party"))
+{
+    setTabColor(&Theme::getThemeColor(Theme::PARTY_CHAT_TAB));
+}
+
+PartyTab::~PartyTab()
+{
+}
+
+void PartyTab::handleInput(const std::string &msg)
+{
+    if (chatWindow)
+        Net::getPartyHandler()->chat(chatWindow->doReplace(msg));
+    else
+        Net::getPartyHandler()->chat(msg);
+}
+
+void PartyTab::showHelp()
+{
+    chatLog(_("/help > Display this help."));
+    chatLog(_("/invite > Invite a player to your party"));
+    chatLog(_("/leave > Leave the party you are in"));
+    chatLog(_("/kick > Kick some one from the party you are in"));
+    chatLog(_("/item > Show/change party item sharing options"));
+    chatLog(_("/exp > Show/change party experience sharing options"));
+}
+
+bool PartyTab::handleCommand(const std::string &type, const std::string &args)
+{
+    if (type == "help")
+    {
+        if (args == "invite")
+        {
+            chatLog(_("Command: /invite <nick>"));
+            chatLog(_("This command invites <nick> to party with you."));
+            chatLog(_("If the <nick> has spaces in it, enclose it in "
+                            "double quotes (\")."));
+        }
+        else if (args == "leave")
+        {
+            chatLog(_("Command: /leave"));
+            chatLog(_("This command causes the player to leave the party."));
+        }
+        else if (args == "item")
+        {
+            chatLog(_("Command: /item <policy>"));
+            chatLog(
+                _("This command changes the party's item sharing policy."));
+            chatLog(_("<policy> can be one of \"1\", \"yes\", \"true\" to "
+                      "enable item sharing, or \"0\", \"no\", \"false\" to "
+                      "disable item sharing."));
+            chatLog(_("Command: /item"));
+            chatLog(_("This command displays the party's"
+                    " current item sharing policy."));
+        }
+        else if (args == "exp")
+        {
+            chatLog(_("Command: /exp <policy>"));
+            chatLog(_("This command changes the party's "
+                    "experience sharing policy."));
+            chatLog(_("<policy> can be one of \"1\", \"yes\", \"true\" to "
+                      "enable experience sharing, or \"0\","
+                      " \"no\", \"false\" to disable experience sharing."));
+            chatLog(_("Command: /exp"));
+            chatLog(_("This command displays the party's current "
+                    "experience sharing policy."));
+        }
+        else
+        {
+            return false;
+        }
+    }
+    else if (type == "create" || type == "new")
+    {
+        if (args.empty())
+            chatLog(_("Party name is missing."), BY_SERVER);
+        else
+            Net::getPartyHandler()->create(args);
+    }
+    else if (type == "invite")
+    {
+        Net::getPartyHandler()->invite(args);
+    }
+    else if (type == "leave")
+    {
+        Net::getPartyHandler()->leave();
+    }
+    else if (type == "kick")
+    {
+        Net::getPartyHandler()->kick(args);
+    }
+    else if (type == "item")
+    {
+        if (args.empty())
+        {
+            switch (Net::getPartyHandler()->getShareItems())
+            {
+                case PARTY_SHARE:
+                    chatLog(_("Item sharing enabled."), BY_SERVER);
+                    return true;
+                case PARTY_SHARE_NO:
+                    chatLog(_("Item sharing disabled."), BY_SERVER);
+                    return true;
+                case PARTY_SHARE_NOT_POSSIBLE:
+                    chatLog(_("Item sharing not possible."), BY_SERVER);
+                    return true;
+                case PARTY_SHARE_UNKNOWN:
+                    chatLog(_("Item sharing unknown."), BY_SERVER);
+                    return true;
+                default:
+                    break;
+            }
+        }
+
+        char opt = CommandHandler::parseBoolean(args);
+
+        switch (opt)
+        {
+            case 1:
+                Net::getPartyHandler()->setShareItems(PARTY_SHARE);
+                break;
+            case 0:
+                Net::getPartyHandler()->setShareItems(PARTY_SHARE_NO);
+                break;
+            case -1:
+                chatLog(strprintf(BOOLEAN_OPTIONS, "item"));
+            default:
+                break;
+        }
+    }
+    else if (type == "exp")
+    {
+        if (args.empty())
+        {
+            switch (Net::getPartyHandler()->getShareExperience())
+            {
+                case PARTY_SHARE:
+                    chatLog(_("Experience sharing enabled."), BY_SERVER);
+                    return true;
+                case PARTY_SHARE_NO:
+                    chatLog(_("Experience sharing disabled."), BY_SERVER);
+                    return true;
+                case PARTY_SHARE_NOT_POSSIBLE:
+                    chatLog(_("Experience sharing not possible."), BY_SERVER);
+                    return true;
+                case PARTY_SHARE_UNKNOWN:
+                    chatLog(_("Experience sharing unknown."), BY_SERVER);
+                    return true;
+                default:
+                    break;
+            }
+        }
+
+        char opt = CommandHandler::parseBoolean(args);
+
+        switch (opt)
+        {
+            case 1:
+                Net::getPartyHandler()->setShareExperience(PARTY_SHARE);
+                break;
+            case 0:
+                Net::getPartyHandler()->setShareExperience(PARTY_SHARE_NO);
+                break;
+            case -1:
+                chatLog(strprintf(BOOLEAN_OPTIONS, "exp"));
+            default:
+                break;
+        }
+    }
+    else
+    {
+        return false;
+    }
+
+    return true;
+}
+
+void PartyTab::getAutoCompleteList(std::vector<std::string> &names) const
+{
+    if (!player_node)
+        return;
+
+    Party *p = player_node->getParty();
+
+    if (p)
+        p->getNames(names);
+}
+
+void PartyTab::saveToLogFile(std::string &msg)
+{
+    if (chatLogger)
+        chatLogger->log("#Party", msg);
+}
+
+} // namespace Ea
+
diff --git a/src/net/ea/gui/partytab.h b/src/net/ea/gui/partytab.h
new file mode 100644
index 000000000..f34d51370
--- /dev/null
+++ b/src/net/ea/gui/partytab.h
@@ -0,0 +1,58 @@
+/*
+ *  The ManaPlus Client
+ *  Copyright (C) 2009  The Mana World Development Team
+ *  Copyright (C) 2009-2010  The Mana Developers
+ *  Copyright (C) 2011  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 EA_PARTYTAB_H
+#define EA_PARTYTAB_H
+
+#include "gui/widgets/chattab.h"
+
+namespace Ea
+{
+
+/**
+ * A tab for a party chat channel.
+ */
+class PartyTab : public ChatTab
+{
+    public:
+        PartyTab();
+        ~PartyTab();
+
+        void showHelp();
+
+        bool handleCommand(const std::string &type, const std::string &args);
+
+        int getType() const { return ChatTab::TAB_PARTY; }
+
+        void saveToLogFile(std::string &msg);
+
+    protected:
+        void handleInput(const std::string &msg);
+
+        virtual void getAutoCompleteList(std::vector<std::string>&) const;
+};
+
+extern PartyTab *partyTab;
+
+} // namespace Ea
+
+#endif // EA_PARTYTAB_H
diff --git a/src/net/ea/guildhandler.cpp b/src/net/ea/guildhandler.cpp
new file mode 100644
index 000000000..cf0e19b36
--- /dev/null
+++ b/src/net/ea/guildhandler.cpp
@@ -0,0 +1,590 @@
+/*
+ *  The ManaPlus Client
+ *  Copyright (C) 2009-2010  The Mana Developers
+ *  Copyright (C) 2011  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/guildhandler.h"
+
+#include "actorspritemanager.h"
+#include "guild.h"
+#include "event.h"
+#include "localplayer.h"
+#include "log.h"
+
+#include "gui/socialwindow.h"
+
+#include "utils/gettext.h"
+
+#include "debug.h"
+
+namespace Ea
+{
+GuildTab *guildTab = 0;
+Guild *taGuild = 0;
+
+GuildHandler::GuildHandler() :
+    showBasicInfo(false)
+{
+}
+
+GuildHandler::~GuildHandler()
+{
+    delete guildTab;
+    guildTab = 0;
+}
+
+void GuildHandler::requestAlliance(int guildId A_UNUSED,
+                                   int otherGuildId A_UNUSED)
+{
+    // TODO
+}
+
+void GuildHandler::requestAllianceResponse(int guildId A_UNUSED,
+                                           int otherGuildId A_UNUSED,
+                                           bool response A_UNUSED)
+{
+    // TODO
+}
+
+void GuildHandler::endAlliance(int guildId A_UNUSED, int otherGuildId A_UNUSED)
+{
+    // TODO
+}
+
+bool GuildHandler::isSupported()
+{
+    return true;
+}
+
+void GuildHandler::processGuildCreateResponse(Net::MessageIn &msg)
+{
+    int flag = msg.readInt8();
+
+    switch (flag)
+    {
+        case 0:
+            // Success
+            SERVER_NOTICE(_("Guild created."))
+            break;
+
+        case 1:
+            // Already in a guild
+            SERVER_NOTICE(_("You are already in guild."))
+            break;
+
+        case 2:
+            // Unable to make (likely name already in use)
+            SERVER_NOTICE(_("You are already in guild."))
+            break;
+
+        case 3:
+            // Emperium check failed
+            SERVER_NOTICE(_("Emperium check failed."))
+            break;
+
+        default:
+            // Unknown response
+            SERVER_NOTICE(_("Unknown server response."))
+            break;
+    }
+}
+
+void GuildHandler::processGuildPositionInfo(Net::MessageIn &msg)
+{
+    int guildId =  msg.readInt32();
+    int emblem =  msg.readInt32();
+    int posMode =  msg.readInt32();
+    msg.readInt32(); // Unused
+    msg.readInt8(); // Unused
+    std::string guildName = msg.readString(24);
+
+    Guild *g = Guild::getGuild(static_cast<short int>(guildId));
+    if (!g)
+        return;
+
+    g->setName(guildName);
+    g->setEmblemId(emblem);
+    if (!taGuild)
+        taGuild = g;
+    if (!guildTab && chatWindow)
+    {
+        guildTab = new GuildTab();
+        if (player_node)
+            player_node->addGuild(taGuild);
+        memberList(guildId);
+    }
+
+    if (player_node)
+    {
+        player_node->setGuild(g);
+        player_node->setGuildName(g->getName());
+    }
+
+    logger->log("Guild position info: %d %d %d %s\n", guildId,
+                emblem, posMode, guildName.c_str());
+}
+
+void GuildHandler::processGuildMemberLogin(Net::MessageIn &msg)
+{
+    int accountId = msg.readInt32(); // Account ID
+    int charId = msg.readInt32(); // Char ID
+    int online = msg.readInt32(); // Flag
+    if (taGuild)
+    {
+        GuildMember *m = taGuild->getMember(accountId, charId);
+        if (m)
+            m->setOnline(online);
+    }
+}
+
+void GuildHandler::processGuildMasterOrMember(Net::MessageIn &msg)
+{
+    msg.readInt32(); // Type (0x57 for member, 0xd7 for master)
+}
+
+void GuildHandler::processGuildBasicInfo(Net::MessageIn &msg)
+{
+    int guildId = msg.readInt32(); // Guild ID
+    int level = msg.readInt32(); // Guild level
+    int members = msg.readInt32(); // 'Connect member'
+    int maxMembers = msg.readInt32(); // 'Max member'
+    int avgLevel = msg.readInt32(); // Average level
+    int exp = msg.readInt32(); // Exp
+    int nextExp = msg.readInt32(); // Next exp
+    msg.skip(16); // unused
+    std::string name = msg.readString(24); // Name
+    std::string master = msg.readString(24); // Master's name
+    std::string castle = msg.readString(20); // Castles
+                            // (ie: "Six Castles" or "None Taken")
+
+    if (guildTab && showBasicInfo)
+    {
+        showBasicInfo = false;
+        guildTab->chatLog(strprintf(
+            _("Guild name: %s"), name.c_str()), BY_SERVER);
+        guildTab->chatLog(strprintf(
+            _("Guild master: %s"), master.c_str()), BY_SERVER);
+        guildTab->chatLog(strprintf(
+            _("Guild level: %d"), level), BY_SERVER);
+        guildTab->chatLog(strprintf(
+            _("Online members: %d"), members), BY_SERVER);
+        guildTab->chatLog(strprintf(
+            _("Max members: %d"), maxMembers), BY_SERVER);
+        guildTab->chatLog(strprintf(
+            _("Average level: %d"), avgLevel), BY_SERVER);
+        guildTab->chatLog(strprintf(
+            _("Guild exp: %d"), exp), BY_SERVER);
+        guildTab->chatLog(strprintf(
+            _("Guild next exp: %d"), nextExp), BY_SERVER);
+        guildTab->chatLog(strprintf(
+            _("Guild castle: %s"), castle.c_str()), BY_SERVER);
+    }
+
+    Guild *g = Guild::getGuild(static_cast<short int>(guildId));
+    if (!g)
+        return;
+    g->setName(name);
+}
+
+void GuildHandler::processGuildAlianceInfo(Net::MessageIn &msg)
+{
+    int length = msg.readInt16();
+    int count = (length - 4) / 32;
+
+    for (int i = 0; i < count; i++)
+    {
+        msg.readInt32(); // 'Opposition'
+        msg.readInt32(); // Other guild ID
+        msg.readString(24); // Other guild name
+    }
+}
+
+void GuildHandler::processGuildMemberList(Net::MessageIn &msg)
+{
+    int length = msg.readInt16();
+    int count = (length - 4) / 104;
+    if (!taGuild)
+    {
+        logger->log1("!taGuild");
+        return;
+    }
+
+    taGuild->clearMembers();
+
+    for (int i = 0; i < count; i++)
+    {
+        int id = msg.readInt32(); // Account ID
+        int charId = msg.readInt32(); // Char ID
+        msg.readInt16(); // Hair
+        msg.readInt16(); // Hair color
+        int gender = msg.readInt16(); // Gender
+        int race = msg.readInt16(); // Class
+        int level = msg.readInt16(); // Level
+        int exp = msg.readInt32(); // Exp
+        int online = msg.readInt32(); // Online
+        int pos = msg.readInt32(); // Position
+        msg.skip(50); // unused
+        std::string name = msg.readString(24); // Name
+
+        GuildMember *m = taGuild->addMember(id, charId, name);
+        if (m)
+        {
+            m->setOnline(online);
+            m->setID(id);
+            m->setCharId(charId);
+            if (!gender)
+                m->setGender(GENDER_FEMALE);
+            else if (gender == 1)
+                m->setGender(GENDER_MALE);
+            else
+                m->setGender(GENDER_UNSPECIFIED);
+
+            m->setLevel(level);
+            m->setExp(exp);
+            m->setPos(pos);
+            m->setRace(race);
+//                    m->setDisplayBold(!pos);
+            if (actorSpriteManager)
+            {
+                Being *being = actorSpriteManager->findBeingByName(
+                    name, Being::PLAYER);
+                if (being)
+                {
+                    being->setGuildName(taGuild->getName());
+                    if (being->getLevel() != level)
+                    {
+                        being->setLevel(level);
+                        being->updateName();
+                    }
+                }
+            }
+        }
+    }
+    taGuild->sort();
+    if (actorSpriteManager)
+    {
+        actorSpriteManager->updatePlayerGuild();
+        actorSpriteManager->updatePlayerColors();
+    }
+}
+
+void GuildHandler::processGuildPosNameList(Net::MessageIn &msg)
+{
+    if (!taGuild)
+    {
+        logger->log1("!taGuild");
+        return;
+    }
+
+    int length = msg.readInt16();
+    int count = (length - 4) / 28;
+
+    for (int i = 0; i < count; i++)
+    {
+        int id = msg.readInt32(); // ID
+        std::string name = msg.readString(24); // Position name
+        taGuild->addPos(id, name);
+    }
+}
+
+void GuildHandler::processGuildPosInfoList(Net::MessageIn &msg)
+{
+    int length = msg.readInt16();
+    int count = (length - 4) / 16;
+
+    for (int i = 0; i < count; i++)
+    {
+        msg.readInt32(); // ID
+        msg.readInt32(); // Mode
+        msg.readInt32(); // Same ID
+        msg.readInt32(); // Exp mode
+    }
+}
+
+void GuildHandler::processGuildPositionChanged(Net::MessageIn &msg)
+{
+    msg.readInt16(); // Always 44
+    msg.readInt32(); // ID
+    msg.readInt32(); // Mode
+    msg.readInt32(); // Same ID
+    msg.readInt32(); // Exp mode
+    msg.readString(24); // Name
+}
+
+void GuildHandler::processGuildMemberPosChange(Net::MessageIn &msg)
+{
+    msg.readInt16(); // Always 16
+    int accountId = msg.readInt32(); // Account ID
+    int charId = msg.readInt32(); // Char ID
+    int pos = msg.readInt32(); // Position
+    if (taGuild)
+    {
+        GuildMember *m = taGuild->getMember(accountId, charId);
+        if (m)
+            m->setPos(pos);
+    }
+}
+
+void GuildHandler::processGuildEmblem(Net::MessageIn &msg)
+{
+    int length = msg.readInt16();
+
+    msg.readInt32(); // Guild ID
+    msg.readInt32(); // Emblem ID
+    msg.skip(length - 12); // Emblem data (unknown format)
+}
+
+void GuildHandler::processGuildSkillInfo(Net::MessageIn &msg)
+{
+    int length = msg.readInt16();
+    int count = (length - 6) / 37;
+
+    msg.readInt16(); // 'Skill point'
+
+    for (int i = 0; i < count; i++)
+    {
+        msg.readInt16(); // ID
+        msg.readInt16(); // 'Info' (unknown atm)
+        msg.readInt16(); // unused
+        msg.readInt16(); // Level
+        msg.readInt16(); // SP
+        msg.readInt16(); // 'Range'
+        msg.skip(24); // unused
+        msg.readInt8(); // Can be increased
+    }
+}
+
+void GuildHandler::processGuildNotice(Net::MessageIn &msg)
+{
+    std::string msg1 = msg.readString(60); // Mes1
+    std::string msg2 = msg.readString(120); // Mes2
+    if (guildTab)
+    {
+        guildTab->chatLog(msg1, BY_SERVER);
+        guildTab->chatLog(msg2, BY_SERVER);
+    }
+}
+
+void GuildHandler::processGuildInvite(Net::MessageIn &msg)
+{
+    int guildId = msg.readInt32();
+    std::string guildName = msg.readString(24);
+
+    if (socialWindow)
+        socialWindow->showGuildInvite(guildName, guildId, "");
+}
+
+void GuildHandler::processGuildInviteAck(Net::MessageIn &msg)
+{
+    int flag = msg.readInt8();
+    if (!guildTab)
+        return;
+
+    switch (flag)
+    {
+        case 0:
+            guildTab->chatLog(_("Could not inivte user to guild."), BY_SERVER);
+            break;
+
+        case 1:
+            guildTab->chatLog(_("User rejected guild invite."), BY_SERVER);
+            break;
+
+        case 2:
+            guildTab->chatLog(_("User is now part of your guild."), BY_SERVER);
+            break;
+
+        case 3:
+            guildTab->chatLog(_("Your guild is full."), BY_SERVER);
+            break;
+
+        default:
+            guildTab->chatLog(_("Unknown guild invite response."), BY_SERVER);
+            break;
+    }
+}
+
+void GuildHandler::processGuildLeave(Net::MessageIn &msg)
+{
+    std::string nick = msg.readString(24); // Name
+    std::string message = msg.readString(40); // Message
+
+    if (taGuild)
+        taGuild->removeMember(nick);
+
+    if (player_node && nick == player_node->getName())
+    {
+        if (taGuild)
+        {
+            taGuild->removeFromMembers();
+            taGuild->clearMembers();
+        }
+        SERVER_NOTICE(_("You have left the guild."))
+        delete guildTab;
+        guildTab = 0;
+
+        if (socialWindow && taGuild)
+            socialWindow->removeTab(taGuild);
+        if (actorSpriteManager)
+            actorSpriteManager->updatePlayerColors();
+    }
+    else
+    {
+        if (guildTab)
+        {
+            guildTab->chatLog(strprintf(
+                _("%s has left your guild."),
+                nick.c_str()), BY_SERVER);
+        }
+        if (actorSpriteManager)
+        {
+            Being *b = actorSpriteManager->findBeingByName(
+                nick, Being::PLAYER);
+
+            if (b)
+                b->clearGuilds();
+            if (taGuild)
+                taGuild->removeMember(nick);
+        }
+    }
+}
+
+void GuildHandler::processGuildExpulsion(Net::MessageIn &msg)
+{
+    std::string nick = msg.readString(24); // Name (of expulsed?)
+    std::string message = msg.readString(40); // Message
+    msg.skip(24); // unused ("dummy")
+    if (taGuild)
+        taGuild->removeMember(nick);
+
+    if (player_node && nick == player_node->getName())
+    {
+        if (taGuild)
+        {
+            taGuild->removeFromMembers();
+            taGuild->clearMembers();
+        }
+        SERVER_NOTICE(_("You was kicked from guild."));
+        delete guildTab;
+        guildTab = 0;
+
+        if (socialWindow && taGuild)
+            socialWindow->removeTab(taGuild);
+        if (actorSpriteManager)
+            actorSpriteManager->updatePlayerColors();
+    }
+    else
+    {
+        if (guildTab)
+        {
+            guildTab->chatLog(strprintf(_("%s has kicked from your guild."),
+                nick.c_str()), BY_SERVER);
+        }
+
+        if (actorSpriteManager)
+        {
+            Being *b = actorSpriteManager->findBeingByName(
+                nick, Being::PLAYER);
+
+            if (b)
+                b->clearGuilds();
+            if (taGuild)
+                taGuild->removeMember(nick);
+        }
+    }
+}
+
+void GuildHandler::processGuildExpulsionList(Net::MessageIn &msg)
+{
+    int length = msg.readInt16();
+    int count = (length - 4) / 88;
+
+    for (int i = 0; i < count; i++)
+    {
+        msg.readString(24); // Name (of expulsed?)
+        msg.readString(24); // 'Acc' (name of expulser?)
+        msg.readString(24); // Message
+    }
+}
+
+void GuildHandler::processGuildMessage(Net::MessageIn &msg)
+{
+    int msgLength = msg.readInt16() - 4;
+
+    if (msgLength <= 0)
+        return;
+    if (guildTab)
+    {
+        std::string chatMsg = msg.readString(msgLength);
+
+        std::string::size_type pos = chatMsg.find(" : ", 0);
+        if (pos != std::string::npos)
+        {
+            std::string sender_name = ((pos == std::string::npos)
+                ? "" : chatMsg.substr(0, pos));
+
+                chatMsg.erase(0, pos + 3);
+
+            trim(chatMsg);
+            guildTab->chatLog(sender_name, chatMsg);
+        }
+        else
+        {
+            guildTab->chatLog(chatMsg);
+        }
+    }
+}
+
+void GuildHandler::processGuildSkillUp(Net::MessageIn &msg)
+{
+    msg.readInt16(); // Skill ID
+    msg.readInt16(); // Level
+    msg.readInt16(); // SP
+    msg.readInt16(); // 'Range'
+    msg.readInt8(); // unused? (always 1)
+}
+
+void GuildHandler::processGuildReqAlliance(Net::MessageIn &msg)
+{
+    msg.readInt32(); // Account ID
+    msg.readString(24); // Name
+}
+
+void GuildHandler::processGuildReqAllianceAck(Net::MessageIn &msg)
+{
+    msg.readInt32(); // Flag
+}
+
+void GuildHandler::processGuildDelAlliance(Net::MessageIn &msg)
+{
+    msg.readInt32(); // Guild ID
+    msg.readInt32(); // Flag
+}
+
+void GuildHandler::processGuildOppositionAck(Net::MessageIn &msg)
+{
+    msg.readInt8(); // Flag
+}
+
+void GuildHandler::processGuildBroken(Net::MessageIn &msg)
+{
+    msg.readInt32(); // Flag
+}
+
+} // namespace Ea
diff --git a/src/net/ea/guildhandler.h b/src/net/ea/guildhandler.h
new file mode 100644
index 000000000..7c516c61b
--- /dev/null
+++ b/src/net/ea/guildhandler.h
@@ -0,0 +1,115 @@
+/*
+ *  The ManaPlus Client
+ *  Copyright (C) 2009-2010  The Mana Developers
+ *  Copyright (C) 2011  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_GUILDHANDLER_H
+#define NET_EA_GUILDHANDLER_H
+
+#include "net/guildhandler.h"
+#include "net/messagein.h"
+
+#include "net/ea/gui/guildtab.h"
+
+#ifdef __GNUC__
+#define A_UNUSED  __attribute__ ((unused))
+#else
+#define A_UNUSED
+#endif
+
+namespace Ea
+{
+
+class GuildHandler : public Net::GuildHandler
+{
+    public:
+        GuildHandler();
+
+        ~GuildHandler();
+
+        void requestAlliance(int guildId, int otherGuildId);
+
+        void requestAllianceResponse(int guildId, int otherGuildId,
+                                     bool response);
+
+        void endAlliance(int guildId, int otherGuildId);
+
+        bool isSupported();
+
+        virtual void processGuildCreateResponse(Net::MessageIn &msg);
+
+        virtual void processGuildPositionInfo(Net::MessageIn &msg);
+
+        virtual void processGuildMemberLogin(Net::MessageIn &msg);
+
+        virtual void processGuildMasterOrMember(Net::MessageIn &msg);
+
+        virtual void processGuildBasicInfo(Net::MessageIn &msg);
+
+        virtual void processGuildAlianceInfo(Net::MessageIn &msg);
+
+        virtual void processGuildMemberList(Net::MessageIn &msg);
+
+        virtual void processGuildPosNameList(Net::MessageIn &msg);
+
+        virtual void processGuildPosInfoList(Net::MessageIn &msg);
+
+        virtual void processGuildPositionChanged(Net::MessageIn &msg);
+
+        virtual void processGuildMemberPosChange(Net::MessageIn &msg);
+
+        virtual void processGuildEmblem(Net::MessageIn &msg);
+
+        virtual void processGuildSkillInfo(Net::MessageIn &msg);
+
+        virtual void processGuildNotice(Net::MessageIn &msg);
+
+        virtual void processGuildInvite(Net::MessageIn &msg);
+
+        virtual void processGuildInviteAck(Net::MessageIn &msg);
+
+        virtual void processGuildLeave(Net::MessageIn &msg);
+
+        virtual void processGuildExpulsion(Net::MessageIn &msg);
+
+        virtual void processGuildExpulsionList(Net::MessageIn &msg);
+
+        virtual void processGuildMessage(Net::MessageIn &msg);
+
+        virtual void processGuildSkillUp(Net::MessageIn &msg);
+
+        virtual void processGuildReqAlliance(Net::MessageIn &msg);
+
+        virtual void processGuildReqAllianceAck(Net::MessageIn &msg);
+
+        virtual void processGuildDelAlliance(Net::MessageIn &msg);
+
+        virtual void processGuildOppositionAck(Net::MessageIn &msg);
+
+        virtual void processGuildBroken(Net::MessageIn &msg);
+
+    protected:
+        bool showBasicInfo;
+};
+
+extern Guild *taGuild;
+extern GuildTab *guildTab;
+}
+
+#endif // NET_EA_GUILDHANDLER_H
diff --git a/src/net/ea/partyhandler.cpp b/src/net/ea/partyhandler.cpp
new file mode 100644
index 000000000..1878bb567
--- /dev/null
+++ b/src/net/ea/partyhandler.cpp
@@ -0,0 +1,451 @@
+/*
+ *  The ManaPlus Client
+ *  Copyright (C) 2008  Lloyd Bryant <lloyd_bryant@netzero.net>
+ *
+ *  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/partyhandler.h"
+
+#include "actorspritemanager.h"
+#include "localplayer.h"
+#include "log.h"
+
+#include "gui/socialwindow.h"
+
+#include "net/messagein.h"
+
+#include "net/ea/gui/partytab.h"
+
+#include "utils/gettext.h"
+
+#include "debug.h"
+
+#define PARTY_ID 1
+
+namespace Ea
+{
+
+PartyTab *partyTab = 0;
+Party *taParty = 0;
+
+PartyHandler::PartyHandler():
+    mShareExp(PARTY_SHARE_UNKNOWN),
+    mShareItems(PARTY_SHARE_UNKNOWN)
+{
+    taParty = Party::getParty(1);
+}
+
+PartyHandler::~PartyHandler()
+{
+    delete partyTab;
+    partyTab = 0;
+}
+
+void PartyHandler::join(int partyId A_UNUSED)
+{
+    // TODO?
+}
+
+void PartyHandler::requestPartyMembers() const
+{
+    // Our eAthena doesn't have this message
+    // Not needed anyways
+}
+
+void PartyHandler::reload()
+{
+    taParty = Party::getParty(1);
+}
+
+void PartyHandler::clear()
+{
+    taParty = 0;
+}
+
+void PartyHandler::processPartyCreate(Net::MessageIn &msg)
+{
+    if (msg.readInt8())
+        SERVER_NOTICE(_("Could not create party."))
+    else
+        SERVER_NOTICE(_("Party successfully created."))
+}
+
+void PartyHandler::processPartyInfo(Net::MessageIn &msg)
+{
+    bool oldParty = false;
+    std::set<std::string> names;
+    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)
+        {
+            oldParty = true;
+
+            Ea::taParty->getNamesSet(names);
+        }
+    }
+
+    if (!player_node)
+        logger->log1("error: player_node==0 in SMSG_PARTY_INFO");
+
+    if (Ea::taParty)
+        Ea::taParty->clearMembers();
+
+    int length = msg.readInt16();
+    if (Ea::taParty)
+        Ea::taParty->setName(msg.readString(24));
+
+    int count = (length - 28) / 46;
+    if (player_node && Ea::taParty)
+    {
+        player_node->setParty(Ea::taParty);
+        player_node->setPartyName(Ea::taParty->getName());
+    }
+
+    for (int i = 0; i < count; i++)
+    {
+        int id = msg.readInt32();
+        std::string nick = msg.readString(24);
+        std::string map = msg.readString(16);
+        bool leader = msg.readInt8() == 0;
+        bool online = msg.readInt8() == 0;
+
+        if (Ea::taParty)
+        {
+            PartyMember *member = 0;
+            if (oldParty)
+            {
+                //member = Ea::taParty->getMember(id);
+                if (Ea::partyTab && names.find(nick) == names.end())
+                {
+                    Ea::partyTab->chatLog(strprintf(
+                        _("%s has joined your party."),
+                        nick.c_str()), BY_SERVER);
+                }
+            }
+            member = Ea::taParty->addMember(id, nick);
+
+            if (member)
+            {
+                member->setLeader(leader);
+                member->setOnline(online);
+                member->setMap(map);
+            }
+        }
+    }
+
+    if (Ea::taParty)
+        Ea::taParty->sort();
+
+    if (player_node && Ea::taParty)
+    {
+        player_node->setParty(Ea::taParty);
+        player_node->setPartyName(Ea::taParty->getName());
+    }
+}
+
+void PartyHandler::processPartyInviteResponse(Net::MessageIn &msg)
+{
+    if (!Ea::partyTab)
+        return;
+
+    std::string nick = msg.readString(24);
+
+    switch (msg.readInt8())
+    {
+        case 0:
+            Ea::partyTab->chatLog(strprintf(
+                _("%s is already a member of a party."),
+                nick.c_str()), BY_SERVER);
+            break;
+        case 1:
+            Ea::partyTab->chatLog(strprintf(
+                _("%s refused your invitation."),
+                nick.c_str()), BY_SERVER);
+            break;
+        case 2:
+            Ea::partyTab->chatLog(strprintf(
+                _("%s is now a member of your party."),
+                nick.c_str()), BY_SERVER);
+            break;
+        case 3:
+            Ea::partyTab->chatLog(strprintf(
+                _("%s can't join your party because party is "
+                "full."), nick.c_str()), BY_SERVER);
+            break;
+        default:
+            Ea::partyTab->chatLog(strprintf(
+                _("QQQ Unknown invite response for %s."),
+                nick.c_str()), BY_SERVER);
+            break;
+    }
+}
+
+void PartyHandler::processPartyInvited(Net::MessageIn &msg)
+{
+    int id = msg.readInt32();
+    std::string partyName = msg.readString(24);
+    std::string nick = "";
+    Being *being;
+
+    if (actorSpriteManager)
+    {
+        if ((being = actorSpriteManager->findBeing(id)))
+        {
+            if (being && being->getType() == Being::PLAYER)
+                nick = being->getName();
+        }
+    }
+
+    if (socialWindow)
+        socialWindow->showPartyInvite(partyName, nick);
+}
+
+void PartyHandler::processPartySettings(Net::MessageIn &msg)
+{
+    if (!Ea::partyTab)
+    {
+        if (!chatWindow)
+            return;
+
+        Ea::partyTab = new PartyTab();
+    }
+
+    // These seem to indicate the sharing mode for exp and items
+    short exp = msg.readInt16();
+    short item = msg.readInt16();
+
+    if (!Ea::partyTab)
+        return;
+
+    switch (exp)
+    {
+        case PARTY_SHARE:
+            if (mShareExp == PARTY_SHARE)
+                break;
+            mShareExp = PARTY_SHARE;
+            if (Ea::partyTab)
+            {
+                Ea::partyTab->chatLog(
+                    _("Experience sharing enabled."), BY_SERVER);
+            }
+            break;
+        case PARTY_SHARE_NO:
+            if (mShareExp == PARTY_SHARE_NO)
+                break;
+            mShareExp = PARTY_SHARE_NO;
+            if (Ea::partyTab)
+            {
+                Ea::partyTab->chatLog(
+                    _("Experience sharing disabled."), BY_SERVER);
+            }
+            break;
+        case PARTY_SHARE_NOT_POSSIBLE:
+            if (mShareExp == PARTY_SHARE_NOT_POSSIBLE)
+                break;
+            mShareExp = PARTY_SHARE_NOT_POSSIBLE;
+            if (Ea::partyTab)
+            {
+                Ea::partyTab->chatLog(
+                    _("Experience sharing not possible."),
+                    BY_SERVER);
+            }
+            break;
+        default:
+            logger->log("QQQ Unknown party exp option: %d\n", exp);
+            break;
+    }
+
+    switch (item)
+    {
+        case PARTY_SHARE:
+            if (mShareItems == PARTY_SHARE)
+                break;
+            mShareItems = PARTY_SHARE;
+            if (Ea::partyTab)
+            {
+                Ea::partyTab->chatLog(
+                    _("Item sharing enabled."), BY_SERVER);
+            }
+            break;
+        case PARTY_SHARE_NO:
+            if (mShareItems == PARTY_SHARE_NO)
+                break;
+            mShareItems = PARTY_SHARE_NO;
+            if (Ea::partyTab)
+            {
+                Ea::partyTab->chatLog(
+                    _("Item sharing disabled."), BY_SERVER);
+            }
+            break;
+        case PARTY_SHARE_NOT_POSSIBLE:
+            if (mShareItems == PARTY_SHARE_NOT_POSSIBLE)
+                break;
+            mShareItems = PARTY_SHARE_NOT_POSSIBLE;
+            if (Ea::partyTab)
+            {
+                Ea::partyTab->chatLog(
+                    _("Item sharing not possible."), BY_SERVER);
+            }
+            break;
+        default:
+            logger->log("QQQ Unknown party item option: %d\n",
+                        exp);
+            break;
+    }
+}
+
+void PartyHandler::processPartyMove(Net::MessageIn &msg)
+{
+    int id = msg.readInt32();    // id
+    PartyMember *m = 0;
+    if (Ea::taParty)
+        m = Ea::taParty->getMember(id);
+    if (m)
+    {
+        msg.skip(4);
+        m->setX(msg.readInt16());    // x
+        m->setY(msg.readInt16());    // y
+        m->setOnline(msg.readInt8());     // online (if 0)
+        msg.readString(24); // party
+        msg.readString(24); // nick
+        m->setMap(msg.readString(16)); // map
+    }
+    else
+    {
+        msg.skip(4);
+        msg.readInt16();    // x
+        msg.readInt16();    // y
+        msg.readInt8();     // online (if 0)
+        msg.readString(24); // party
+        msg.readString(24); // nick
+        msg.readString(16); // map
+    }
+}
+
+void PartyHandler::processPartyLeave(Net::MessageIn &msg)
+{
+    int id = msg.readInt32();
+    std::string nick = msg.readString(24);
+    msg.readInt8();     // fail
+    if (player_node && id == player_node->getId())
+    {
+        if (Ea::taParty)
+        {
+            Ea::taParty->removeFromMembers();
+            Ea::taParty->clearMembers();
+        }
+        SERVER_NOTICE(_("You have left the party."))
+        delete Ea::partyTab;
+        Ea::partyTab = 0;
+
+        if (socialWindow && Ea::taParty)
+            socialWindow->removeTab(Ea::taParty);
+    }
+    else
+    {
+        if (Ea::partyTab)
+        {
+            Ea::partyTab->chatLog(strprintf(
+                _("%s has left your party."),
+                nick.c_str()), BY_SERVER);
+        }
+        if (actorSpriteManager)
+        {
+            Being *b = actorSpriteManager->findBeing(id);
+            if (b && b->getType() == Being::PLAYER)
+                b->setParty(0);
+        }
+        if (Ea::taParty)
+            Ea::taParty->removeMember(id);
+    }
+}
+
+void PartyHandler::processPartyUpdateHp(Net::MessageIn &msg)
+{
+    int id = msg.readInt32();
+    int hp = msg.readInt16();
+    int maxhp = msg.readInt16();
+    PartyMember *m = 0;
+    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 (actorSpriteManager && Ea::taParty)
+    {
+        if (Being *b = actorSpriteManager->findBeing(id))
+            b->setParty(Ea::taParty);
+    }
+}  
+
+void PartyHandler::processPartyUpdateCoords(Net::MessageIn &msg)
+{
+    int id = msg.readInt32(); // id
+    PartyMember *m = 0;
+    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 PartyHandler::processPartyMessage(Net::MessageIn &msg)
+{
+    int msgLength = msg.readInt16() - 8;
+    if (msgLength <= 0)
+        return;
+
+    int id = msg.readInt32();
+    std::string chatMsg = msg.readString(msgLength);
+
+    if (Ea::taParty)
+    {
+        PartyMember *member = Ea::taParty->getMember(id);
+        if (Ea::partyTab)
+        {
+            if (member)
+            {
+                Ea::partyTab->chatLog(member->getName(), chatMsg);
+            }
+            else
+            {
+                Ea::partyTab->chatLog(strprintf(
+                    _("An unknown member tried to say: %s"),
+                    chatMsg.c_str()), BY_SERVER);
+            }
+        }
+    }
+}
+
+} // namespace TmwAthena
diff --git a/src/net/ea/partyhandler.h b/src/net/ea/partyhandler.h
new file mode 100644
index 000000000..6ba0d0b82
--- /dev/null
+++ b/src/net/ea/partyhandler.h
@@ -0,0 +1,91 @@
+/*
+ *  The ManaPlus Client
+ *  Copyright (C) 2008  Lloyd Bryant <lloyd_bryant@netzero.net>
+ *
+ *  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_PARTYHANDLER_H
+#define NET_EA_PARTYHANDLER_H
+
+#include "net/messagein.h"
+#include "net/net.h"
+#include "net/partyhandler.h"
+
+#include "net/ea/gui/partytab.h"
+
+#include "party.h"
+
+#ifdef __GNUC__
+#define A_UNUSED  __attribute__ ((unused))
+#else
+#define A_UNUSED
+#endif
+
+namespace Ea
+{
+
+class PartyHandler : public Net::PartyHandler
+{
+    public:
+        PartyHandler();
+
+        ~PartyHandler();
+
+        void join(int partyId);
+
+        void requestPartyMembers() const;
+
+        PartyShare getShareExperience() const
+        { return mShareExp; }
+
+        PartyShare getShareItems() const
+        { return mShareItems; }
+
+        void reload();
+
+        void clear();
+
+        virtual void processPartyCreate(Net::MessageIn &msg);
+
+        virtual void processPartyInfo(Net::MessageIn &msg);
+
+        virtual void processPartyInviteResponse(Net::MessageIn &msg);
+
+        virtual void processPartyInvited(Net::MessageIn &msg);
+
+        virtual void processPartySettings(Net::MessageIn &msg);
+
+        virtual void processPartyMove(Net::MessageIn &msg);
+
+        virtual void processPartyLeave(Net::MessageIn &msg);
+
+        virtual void processPartyUpdateHp(Net::MessageIn &msg);
+
+        virtual void processPartyUpdateCoords(Net::MessageIn &msg);
+
+        virtual void processPartyMessage(Net::MessageIn &msg);
+
+    protected:
+        PartyShare mShareExp, mShareItems;
+};
+
+extern PartyTab *partyTab;
+extern Party *taParty;
+
+} // namespace Ea
+
+#endif // NET_EA_PARTYHANDLER_H
diff --git a/src/net/tmwa/generalhandler.cpp b/src/net/tmwa/generalhandler.cpp
index 7993c24dc..3e46fa66b 100644
--- a/src/net/tmwa/generalhandler.cpp
+++ b/src/net/tmwa/generalhandler.cpp
@@ -37,6 +37,11 @@
 #include "net/messageout.h"
 #include "net/serverinfo.h"
 
+#include "net/ea/guildhandler.h"
+
+#include "net/ea/gui/guildtab.h"
+#include "net/ea/gui/partytab.h"
+
 #include "net/tmwa/adminhandler.h"
 #include "net/tmwa/beinghandler.h"
 #include "net/tmwa/buysellhandler.h"
@@ -75,9 +80,6 @@ namespace TmwAthena
 ServerInfo charServer;
 ServerInfo mapServer;
 
-extern Guild *taGuild;
-extern Party *taParty;
-
 GeneralHandler::GeneralHandler():
     mAdminHandler(new AdminHandler),
     mBeingHandler(new BeingHandler(config.getBoolValue("EnableSync"))),
@@ -282,15 +284,15 @@ void GeneralHandler::event(Mana::Channels channel,
         {
             if (socialWindow)
             {
-                socialWindow->removeTab(taGuild);
-                socialWindow->removeTab(taParty);
+                socialWindow->removeTab(Ea::taGuild);
+                socialWindow->removeTab(Ea::taParty);
             }
 
-            delete guildTab;
-            guildTab = 0;
+            delete Ea::guildTab;
+            Ea::guildTab = 0;
 
-            delete partyTab;
-            partyTab = 0;
+            delete Ea::partyTab;
+            Ea::partyTab = 0;
         }
     }
 }
diff --git a/src/net/tmwa/gui/guildtab.cpp b/src/net/tmwa/gui/guildtab.cpp
index ce828b338..99b775089 100644
--- a/src/net/tmwa/gui/guildtab.cpp
+++ b/src/net/tmwa/gui/guildtab.cpp
@@ -43,111 +43,14 @@
 
 namespace TmwAthena
 {
-
-extern Guild *taGuild;
-
 GuildTab::GuildTab() :
-    ChatTab(_("Guild"))
+    Ea::GuildTab()
 {
-    setTabColor(&Theme::getThemeColor(Theme::GUILD_CHAT_TAB));
 }
 
 GuildTab::~GuildTab()
 {
 }
 
-void GuildTab::handleInput(const std::string &msg)
-{
-    if (!taGuild)
-        return;
-
-    if (chatWindow)
-    {
-        Net::getGuildHandler()->chat(taGuild->getId(),
-            chatWindow->doReplace(msg));
-    }
-    else
-    {
-        Net::getGuildHandler()->chat(taGuild->getId(), msg);
-    }
-}
-
-void GuildTab::showHelp()
-{
-    chatLog(_("/help > Display this help."));
-    chatLog(_("/invite > Invite a player to your guild"));
-    chatLog(_("/leave > Leave the guild you are in"));
-    chatLog(_("/kick > Kick some one from the guild you are in"));
-}
-
-bool GuildTab::handleCommand(const std::string &type, const std::string &args)
-{
-    if (type == "help")
-    {
-        if (args == "invite")
-        {
-            chatLog(_("Command: /invite <nick>"));
-            chatLog(_("This command invites <nick> to the guild you're in."));
-            chatLog(_("If the <nick> has spaces in it, enclose it in "
-                            "double quotes (\")."));
-        }
-        else if (args == "leave")
-        {
-            chatLog(_("Command: /leave"));
-            chatLog(_("This command causes the player to leave the guild."));
-        }
-        else
-            return false;
-    }
-/*
-    else if (type == "create" || type == "new")
-    {
-        if (args.empty())
-            chatLog(_("Guild name is missing."), BY_SERVER);
-        else
-            Net::getGuildHandler()->create(args);
-    }
-*/
-    else if (type == "invite" && taGuild)
-    {
-        Net::getGuildHandler()->invite(taGuild->getId(), args);
-    }
-    else if (type == "leave" && taGuild)
-    {
-        Net::getGuildHandler()->leave(taGuild->getId());
-    }
-    else if (type == "kick" && taGuild)
-    {
-        Net::getGuildHandler()->kick(taGuild->getMember(args));
-    }
-    else if (type == "notice" && taGuild)
-    {
-        std::string str1 = args.substr(0, 60);
-        std::string str2 = "";
-        if (args.size() > 60)
-            str2 = args.substr(60);
-        Net::getGuildHandler()->changeNotice(taGuild->getId(), str1, str2);
-    }
-    else
-    {
-        return false;
-    }
-
-    return true;
-}
-
-void GuildTab::getAutoCompleteList(std::vector<std::string> &names) const
-{
-    if (taGuild)
-        taGuild->getNames(names);
-    names.push_back("/notice ");
-}
-
-void GuildTab::saveToLogFile(std::string &msg)
-{
-    if (chatLogger)
-        chatLogger->log("#Guild", msg);
-}
-
 } // namespace TmwAthena
 
diff --git a/src/net/tmwa/gui/guildtab.h b/src/net/tmwa/gui/guildtab.h
index e1af7ed70..21c56c4ed 100644
--- a/src/net/tmwa/gui/guildtab.h
+++ b/src/net/tmwa/gui/guildtab.h
@@ -23,7 +23,7 @@
 #ifndef TA_GUILDTAB_H
 #define TA_GUILDTAB_H
 
-#include "gui/widgets/chattab.h"
+#include "net/ea/gui/guildtab.h"
 
 namespace TmwAthena
 {
@@ -31,28 +31,14 @@ namespace TmwAthena
 /**
  * A tab for a guild chat channel.
  */
-class GuildTab : public ChatTab
+class GuildTab : public Ea::GuildTab
 {
     public:
         GuildTab();
-        ~GuildTab();
-
-        void showHelp();
-
-        bool handleCommand(const std::string &type, const std::string &args);
-
-        void saveToLogFile(std::string &msg);
 
-        int getType() const { return ChatTab::TAB_GUILD; }
-
-    protected:
-        void handleInput(const std::string &msg);
-
-        void getAutoCompleteList(std::vector<std::string> &names) const;
+        ~GuildTab();
 };
 
-extern GuildTab *guildTab;
-
 } // namespace TmwAthena
 
 #endif // TA_GUILDTAB_H
diff --git a/src/net/tmwa/gui/partytab.cpp b/src/net/tmwa/gui/partytab.cpp
index fc8ec138d..d15f4754f 100644
--- a/src/net/tmwa/gui/partytab.cpp
+++ b/src/net/tmwa/gui/partytab.cpp
@@ -47,199 +47,13 @@ namespace TmwAthena
 {
 
 PartyTab::PartyTab() :
-    ChatTab(_("Party"))
+    Ea::PartyTab()
 {
-    setTabColor(&Theme::getThemeColor(Theme::PARTY_CHAT_TAB));
 }
 
 PartyTab::~PartyTab()
 {
 }
 
-void PartyTab::handleInput(const std::string &msg)
-{
-    if (chatWindow)
-        Net::getPartyHandler()->chat(chatWindow->doReplace(msg));
-    else
-        Net::getPartyHandler()->chat(msg);
-}
-
-void PartyTab::showHelp()
-{
-    chatLog(_("/help > Display this help."));
-    chatLog(_("/invite > Invite a player to your party"));
-    chatLog(_("/leave > Leave the party you are in"));
-    chatLog(_("/kick > Kick some one from the party you are in"));
-    chatLog(_("/item > Show/change party item sharing options"));
-    chatLog(_("/exp > Show/change party experience sharing options"));
-}
-
-bool PartyTab::handleCommand(const std::string &type, const std::string &args)
-{
-    if (type == "help")
-    {
-        if (args == "invite")
-        {
-            chatLog(_("Command: /invite <nick>"));
-            chatLog(_("This command invites <nick> to party with you."));
-            chatLog(_("If the <nick> has spaces in it, enclose it in "
-                            "double quotes (\")."));
-        }
-        else if (args == "leave")
-        {
-            chatLog(_("Command: /leave"));
-            chatLog(_("This command causes the player to leave the party."));
-        }
-        else if (args == "item")
-        {
-            chatLog(_("Command: /item <policy>"));
-            chatLog(
-                _("This command changes the party's item sharing policy."));
-            chatLog(_("<policy> can be one of \"1\", \"yes\", \"true\" to "
-                      "enable item sharing, or \"0\", \"no\", \"false\" to "
-                      "disable item sharing."));
-            chatLog(_("Command: /item"));
-            chatLog(_("This command displays the party's"
-                    " current item sharing policy."));
-        }
-        else if (args == "exp")
-        {
-            chatLog(_("Command: /exp <policy>"));
-            chatLog(_("This command changes the party's "
-                    "experience sharing policy."));
-            chatLog(_("<policy> can be one of \"1\", \"yes\", \"true\" to "
-                      "enable experience sharing, or \"0\","
-                      " \"no\", \"false\" to disable experience sharing."));
-            chatLog(_("Command: /exp"));
-            chatLog(_("This command displays the party's current "
-                    "experience sharing policy."));
-        }
-        else
-        {
-            return false;
-        }
-    }
-    else if (type == "create" || type == "new")
-    {
-        if (args.empty())
-            chatLog(_("Party name is missing."), BY_SERVER);
-        else
-            Net::getPartyHandler()->create(args);
-    }
-    else if (type == "invite")
-    {
-        Net::getPartyHandler()->invite(args);
-    }
-    else if (type == "leave")
-    {
-        Net::getPartyHandler()->leave();
-    }
-    else if (type == "kick")
-    {
-        Net::getPartyHandler()->kick(args);
-    }
-    else if (type == "item")
-    {
-        if (args.empty())
-        {
-            switch (Net::getPartyHandler()->getShareItems())
-            {
-                case PARTY_SHARE:
-                    chatLog(_("Item sharing enabled."), BY_SERVER);
-                    return true;
-                case PARTY_SHARE_NO:
-                    chatLog(_("Item sharing disabled."), BY_SERVER);
-                    return true;
-                case PARTY_SHARE_NOT_POSSIBLE:
-                    chatLog(_("Item sharing not possible."), BY_SERVER);
-                    return true;
-                case PARTY_SHARE_UNKNOWN:
-                    chatLog(_("Item sharing unknown."), BY_SERVER);
-                    return true;
-                default:
-                    break;
-            }
-        }
-
-        char opt = CommandHandler::parseBoolean(args);
-
-        switch (opt)
-        {
-            case 1:
-                Net::getPartyHandler()->setShareItems(PARTY_SHARE);
-                break;
-            case 0:
-                Net::getPartyHandler()->setShareItems(PARTY_SHARE_NO);
-                break;
-            case -1:
-                chatLog(strprintf(BOOLEAN_OPTIONS, "item"));
-            default:
-                break;
-        }
-    }
-    else if (type == "exp")
-    {
-        if (args.empty())
-        {
-            switch (Net::getPartyHandler()->getShareExperience())
-            {
-                case PARTY_SHARE:
-                    chatLog(_("Experience sharing enabled."), BY_SERVER);
-                    return true;
-                case PARTY_SHARE_NO:
-                    chatLog(_("Experience sharing disabled."), BY_SERVER);
-                    return true;
-                case PARTY_SHARE_NOT_POSSIBLE:
-                    chatLog(_("Experience sharing not possible."), BY_SERVER);
-                    return true;
-                case PARTY_SHARE_UNKNOWN:
-                    chatLog(_("Experience sharing unknown."), BY_SERVER);
-                    return true;
-                default:
-                    break;
-            }
-        }
-
-        char opt = CommandHandler::parseBoolean(args);
-
-        switch (opt)
-        {
-            case 1:
-                Net::getPartyHandler()->setShareExperience(PARTY_SHARE);
-                break;
-            case 0:
-                Net::getPartyHandler()->setShareExperience(PARTY_SHARE_NO);
-                break;
-            case -1:
-                chatLog(strprintf(BOOLEAN_OPTIONS, "exp"));
-            default:
-                break;
-        }
-    }
-    else
-    {
-        return false;
-    }
-
-    return true;
-}
-
-void PartyTab::getAutoCompleteList(std::vector<std::string> &names) const
-{
-    if (!player_node)
-        return;
-
-    Party *p = player_node->getParty();
-
-    if (p)
-        p->getNames(names);
-}
-
-void PartyTab::saveToLogFile(std::string &msg)
-{
-    if (chatLogger)
-        chatLogger->log("#Party", msg);
-}
-
 } // namespace TmwAthena
 
diff --git a/src/net/tmwa/gui/partytab.h b/src/net/tmwa/gui/partytab.h
index f78a4c701..d865995f7 100644
--- a/src/net/tmwa/gui/partytab.h
+++ b/src/net/tmwa/gui/partytab.h
@@ -23,7 +23,7 @@
 #ifndef TA_PARTYTAB_H
 #define TA_PARTYTAB_H
 
-#include "gui/widgets/chattab.h"
+#include "net/ea/gui/partytab.h"
 
 namespace TmwAthena
 {
@@ -31,28 +31,14 @@ namespace TmwAthena
 /**
  * A tab for a party chat channel.
  */
-class PartyTab : public ChatTab
+class PartyTab : public Ea::PartyTab
 {
     public:
         PartyTab();
-        ~PartyTab();
-
-        void showHelp();
-
-        bool handleCommand(const std::string &type, const std::string &args);
-
-        int getType() const { return ChatTab::TAB_PARTY; }
 
-        void saveToLogFile(std::string &msg);
-
-    protected:
-        void handleInput(const std::string &msg);
-
-        virtual void getAutoCompleteList(std::vector<std::string>&) const;
+        ~PartyTab();
 };
 
-extern PartyTab *partyTab;
-
 } // namespace TmwAthena
 
 #endif // TA_PARTYTAB_H
diff --git a/src/net/tmwa/guildhandler.cpp b/src/net/tmwa/guildhandler.cpp
index b6c230643..cbb32c3c8 100644
--- a/src/net/tmwa/guildhandler.cpp
+++ b/src/net/tmwa/guildhandler.cpp
@@ -22,21 +22,13 @@
 #include "net/tmwa/guildhandler.h"
 
 #include "actorspritemanager.h"
-#include "guild.h"
-#include "event.h"
 #include "localplayer.h"
 #include "log.h"
 #include "playerinfo.h"
 
-#include "gui/socialwindow.h"
-
 #include "net/tmwa/messagein.h"
 #include "net/tmwa/protocol.h"
 
-#include "net/tmwa/gui/guildtab.h"
-
-#include "utils/gettext.h"
-
 #include "debug.h"
 
 extern Net::GuildHandler *guildHandler;
@@ -44,10 +36,6 @@ extern Net::GuildHandler *guildHandler;
 namespace TmwAthena
 {
 
-GuildTab *guildTab = 0;
-Guild *taGuild;
-bool showBasicInfo(false);
-
 GuildHandler::GuildHandler()
 {
     static const Uint16 _messages[] =
@@ -87,8 +75,6 @@ GuildHandler::GuildHandler()
 
 GuildHandler::~GuildHandler()
 {
-    delete guildTab;
-    guildTab = 0;
 }
 
 void GuildHandler::handleMessage(Net::MessageIn &msg)
@@ -98,532 +84,109 @@ void GuildHandler::handleMessage(Net::MessageIn &msg)
     switch (msg.getId())
     {
         case SMSG_GUILD_CREATE_RESPONSE:
-        {
-            int flag = msg.readInt8();
-
-            if (flag == 0)
-            {
-                // Success
-                SERVER_NOTICE(_("Guild created."))
-            }
-            else if (flag == 1)
-            {
-                // Already in a guild
-                SERVER_NOTICE(_("You are already in guild."))
-            }
-            else if (flag == 2)
-            {
-                // Unable to make (likely name already in use)
-                SERVER_NOTICE(_("You are already in guild."))
-            }
-            else if (flag == 3)
-            {
-                // Emperium check failed
-                SERVER_NOTICE(_("Emperium check failed."))
-            }
-            else
-            {
-                // Unknown response
-                SERVER_NOTICE(_("Unknown server response."))
-            }
-        }
-        break;
+            processGuildCreateResponse(msg);
+            break;
 
         case SMSG_GUILD_POSITION_INFO:
-        {
-            int guildId =  msg.readInt32();
-            int emblem =  msg.readInt32();
-            int posMode =  msg.readInt32();
-            msg.readInt32(); // Unused
-            msg.readInt8(); // Unused
-            std::string guildName = msg.readString(24);
-
-            Guild *g = Guild::getGuild(static_cast<short int>(guildId));
-            if (!g)
-                break;
-
-            g->setName(guildName);
-            g->setEmblemId(emblem);
-            if (!taGuild)
-                taGuild = g;
-            if (!guildTab && chatWindow)
-            {
-                guildTab = new GuildTab();
-                if (player_node)
-                    player_node->addGuild(taGuild);
-                memberList(guildId);
-            }
-
-            if (player_node)
-            {
-                player_node->setGuild(g);
-                player_node->setGuildName(g->getName());
-            }
-
-            logger->log("Guild position info: %d %d %d %s\n", guildId,
-                        emblem, posMode, guildName.c_str());
-        }
-        break;
+            processGuildPositionInfo(msg);
+            break;
 
         case SMSG_GUILD_MEMBER_LOGIN:
         {
-            int accountId = msg.readInt32(); // Account ID
-            int charId = msg.readInt32(); // Char ID
-            int online = msg.readInt32(); // Flag
-            if (taGuild)
-            {
-                GuildMember *m = taGuild->getMember(accountId, charId);
-                if (m)
-                    m->setOnline(online);
-            }
+            processGuildMemberLogin(msg);
             break;
         }
 
         case SMSG_GUILD_MASTER_OR_MEMBER:
-            msg.readInt32(); // Type (0x57 for member, 0xd7 for master)
+            processGuildMasterOrMember(msg);
             break;
 
         case SMSG_GUILD_BASIC_INFO:
-        {
-            int guildId = msg.readInt32(); // Guild ID
-            int level = msg.readInt32(); // Guild level
-            int members = msg.readInt32(); // 'Connect member'
-            int maxMembers = msg.readInt32(); // 'Max member'
-            int avgLevel = msg.readInt32(); // Average level
-            int exp = msg.readInt32(); // Exp
-            int nextExp = msg.readInt32(); // Next exp
-            msg.skip(16); // unused
-            std::string name = msg.readString(24); // Name
-            std::string master = msg.readString(24); // Master's name
-            std::string castle = msg.readString(20); // Castles
-                                    // (ie: "Six Castles" or "None Taken")
-
-            if (guildTab && showBasicInfo)
-            {
-                showBasicInfo = false;
-                guildTab->chatLog(strprintf(
-                    _("Guild name: %s"), name.c_str()), BY_SERVER);
-                guildTab->chatLog(strprintf(
-                    _("Guild master: %s"), master.c_str()), BY_SERVER);
-                guildTab->chatLog(strprintf(
-                    _("Guild level: %d"), level), BY_SERVER);
-                guildTab->chatLog(strprintf(
-                    _("Online members: %d"), members), BY_SERVER);
-                guildTab->chatLog(strprintf(
-                    _("Max members: %d"), maxMembers), BY_SERVER);
-                guildTab->chatLog(strprintf(
-                    _("Average level: %d"), avgLevel), BY_SERVER);
-                guildTab->chatLog(strprintf(
-                    _("Guild exp: %d"), exp), BY_SERVER);
-                guildTab->chatLog(strprintf(
-                    _("Guild next exp: %d"), nextExp), BY_SERVER);
-                guildTab->chatLog(strprintf(
-                    _("Guild castle: %s"), castle.c_str()), BY_SERVER);
-            }
-
-            Guild *g = Guild::getGuild(static_cast<short int>(guildId));
-            if (!g)
-                break;
-            g->setName(name);
-        }
-        break;
+            processGuildBasicInfo(msg);
+            break;
 
         case SMSG_GUILD_ALIANCE_INFO:
-        {
-            int length = msg.readInt16();
-            int count = (length - 4) / 32;
-
-            for (int i = 0; i < count; i++)
-            {
-                msg.readInt32(); // 'Opposition'
-                msg.readInt32(); // Other guild ID
-                msg.readString(24); // Other guild name
-            }
-        }
-        break;
+            processGuildAlianceInfo(msg);
+            break;
 
         case SMSG_GUILD_MEMBER_LIST:
-        {
-            int length = msg.readInt16();
-            int count = (length - 4) / 104;
-            if (!taGuild)
-            {
-                logger->log1("!taGuild");
-                break;
-            }
-
-            taGuild->clearMembers();
-
-            for (int i = 0; i < count; i++)
-            {
-                int id = msg.readInt32(); // Account ID
-                int charId = msg.readInt32(); // Char ID
-                msg.readInt16(); // Hair
-                msg.readInt16(); // Hair color
-                int gender = msg.readInt16(); // Gender
-                int race = msg.readInt16(); // Class
-                int level = msg.readInt16(); // Level
-                int exp = msg.readInt32(); // Exp
-                int online = msg.readInt32(); // Online
-                int pos = msg.readInt32(); // Position
-                msg.skip(50); // unused
-                std::string name = msg.readString(24); // Name
-
-                GuildMember *m = taGuild->addMember(id, charId, name);
-                if (m)
-                {
-                    m->setOnline(online);
-                    m->setID(id);
-                    m->setCharId(charId);
-                    if (!gender)
-                        m->setGender(GENDER_FEMALE);
-                    else if (gender == 1)
-                        m->setGender(GENDER_MALE);
-                    else
-                        m->setGender(GENDER_UNSPECIFIED);
-
-                    m->setLevel(level);
-                    m->setExp(exp);
-                    m->setPos(pos);
-                    m->setRace(race);
-//                    m->setDisplayBold(!pos);
-                    if (actorSpriteManager)
-                    {
-                        Being *being = actorSpriteManager->findBeingByName(
-                            name, Being::PLAYER);
-                        if (being)
-                        {
-                            being->setGuildName(taGuild->getName());
-                            if (being->getLevel() != level)
-                            {
-                                being->setLevel(level);
-                                being->updateName();
-                            }
-                        }
-                    }
-                }
-            }
-            taGuild->sort();
-            if (actorSpriteManager)
-            {
-                actorSpriteManager->updatePlayerGuild();
-                actorSpriteManager->updatePlayerColors();
-            }
-        }
-        break;
+            processGuildMemberList(msg);
+            break;
 
         case SMSG_GUILD_POS_NAME_LIST:
-        {
-            if (!taGuild)
-            {
-                logger->log1("!taGuild");
-                break;
-            }
-
-            int length = msg.readInt16();
-            int count = (length - 4) / 28;
-
-            for (int i = 0; i < count; i++)
-            {
-                int id = msg.readInt32(); // ID
-                std::string name = msg.readString(24); // Position name
-                taGuild->addPos(id, name);
-            }
-        }
-        break;
+            processGuildPosNameList(msg);
+            break;
 
         case SMSG_GUILD_POS_INFO_LIST:
-        {
-            int length = msg.readInt16();
-            int count = (length - 4) / 16;
-
-            for (int i = 0; i < count; i++)
-            {
-                msg.readInt32(); // ID
-                msg.readInt32(); // Mode
-                msg.readInt32(); // Same ID
-                msg.readInt32(); // Exp mode
-            }
-        }
-        break;
+            processGuildPosInfoList(msg);
+            break;
 
         case SMSG_GUILD_POSITION_CHANGED:
-            msg.readInt16(); // Always 44
-            msg.readInt32(); // ID
-            msg.readInt32(); // Mode
-            msg.readInt32(); // Same ID
-            msg.readInt32(); // Exp mode
-            msg.readString(24); // Name
+            processGuildPositionChanged(msg);
             break;
 
         case SMSG_GUILD_MEMBER_POS_CHANGE:
-        {
-            msg.readInt16(); // Always 16
-            int accountId = msg.readInt32(); // Account ID
-            int charId = msg.readInt32(); // Char ID
-            int pos = msg.readInt32(); // Position
-            if (taGuild)
-            {
-                GuildMember *m = taGuild->getMember(accountId, charId);
-                if (m)
-                    m->setPos(pos);
-            }
+            processGuildMemberPosChange(msg);
             break;
-        }
 
         case SMSG_GUILD_EMBLEM:
-        {
-            int length = msg.readInt16();
-
-            msg.readInt32(); // Guild ID
-            msg.readInt32(); // Emblem ID
-            msg.skip(length - 12); // Emblem data (unknown format)
-        }
-        break;
+            processGuildEmblem(msg);
+            break;
 
         case SMSG_GUILD_SKILL_INFO:
-        {
-            int length = msg.readInt16();
-            int count = (length - 6) / 37;
-
-            msg.readInt16(); // 'Skill point'
-
-            for (int i = 0; i < count; i++)
-            {
-                msg.readInt16(); // ID
-                msg.readInt16(); // 'Info' (unknown atm)
-                msg.readInt16(); // unused
-                msg.readInt16(); // Level
-                msg.readInt16(); // SP
-                msg.readInt16(); // 'Range'
-                msg.skip(24); // unused
-                msg.readInt8(); // Can be increased
-            }
-        }
-        break;
+            processGuildSkillInfo(msg);
+            break;
 
         case SMSG_GUILD_NOTICE:
-        {
-            std::string msg1 = msg.readString(60); // Mes1
-            std::string msg2 = msg.readString(120); // Mes2
-            if (guildTab)
-            {
-                guildTab->chatLog(msg1, BY_SERVER);
-                guildTab->chatLog(msg2, BY_SERVER);
-            }
+            processGuildNotice(msg);
             break;
-        }
 
         case SMSG_GUILD_INVITE:
-        {
-            int guildId = msg.readInt32();
-            std::string guildName = msg.readString(24);
-
-            if (socialWindow)
-                socialWindow->showGuildInvite(guildName, guildId, "");
+            processGuildInvite(msg);
             break;
-        }
 
         case SMSG_GUILD_INVITE_ACK:
-        {
-            int flag = msg.readInt8();
-            if (!guildTab)
-                break;
-
-            switch (flag)
-            {
-                case 0:
-                    guildTab->chatLog(_("Could not inivte user to guild."),
-                                      BY_SERVER);
-                    break;
-
-                case 1:
-                    guildTab->chatLog(_("User rejected guild invite."),
-                                      BY_SERVER);
-                    break;
-
-                case 2:
-                    guildTab->chatLog(_("User is now part of your guild."),
-                                      BY_SERVER);
-                    break;
-
-                case 3:
-                    guildTab->chatLog(_("Your guild is full."),
-                                      BY_SERVER);
-                    break;
-
-                default:
-                    guildTab->chatLog(_("Unknown guild invite response."),
-                                      BY_SERVER);
-                    break;
-            }
-        }
-        break;
+            processGuildInviteAck(msg);
+            break;
 
         case SMSG_GUILD_LEAVE:
-        {
-            std::string nick = msg.readString(24); // Name
-            std::string message = msg.readString(40); // Message
-
-            if (taGuild)
-                taGuild->removeMember(nick);
-
-            if (player_node && nick == player_node->getName())
-            {
-                if (taGuild)
-                {
-                    taGuild->removeFromMembers();
-                    taGuild->clearMembers();
-                }
-                SERVER_NOTICE(_("You have left the guild."))
-                delete guildTab;
-                guildTab = 0;
-
-                if (socialWindow && taGuild)
-                    socialWindow->removeTab(taGuild);
-                if (actorSpriteManager)
-                    actorSpriteManager->updatePlayerColors();
-            }
-            else
-            {
-                if (guildTab)
-                {
-                    guildTab->chatLog(strprintf(
-                        _("%s has left your guild."),
-                        nick.c_str()), BY_SERVER);
-                }
-                if (actorSpriteManager)
-                {
-                    Being *b = actorSpriteManager->findBeingByName(
-                        nick, Being::PLAYER);
-
-                    if (b)
-                        b->clearGuilds();
-                    if (taGuild)
-                        taGuild->removeMember(nick);
-                }
-            }
+            processGuildLeave(msg);
             break;
-        }
 
         case SMSG_GUILD_EXPULSION:
-        {
-            std::string nick = msg.readString(24); // Name (of expulsed?)
-            std::string message = msg.readString(40); // Message
-            msg.skip(24); // unused ("dummy")
-            if (taGuild)
-                taGuild->removeMember(nick);
-
-            if (player_node && nick == player_node->getName())
-            {
-                if (taGuild)
-                {
-                    taGuild->removeFromMembers();
-                    taGuild->clearMembers();
-                }
-                SERVER_NOTICE(_("You was kicked from guild."));
-                delete guildTab;
-                guildTab = 0;
-
-                if (socialWindow && taGuild)
-                    socialWindow->removeTab(taGuild);
-                if (actorSpriteManager)
-                    actorSpriteManager->updatePlayerColors();
-            }
-            else
-            {
-                if (guildTab)
-                {
-                    guildTab->chatLog(strprintf(
-                        _("%s has kicked from your guild."),
-                        nick.c_str()), BY_SERVER);
-                }
-
-                if (actorSpriteManager)
-                {
-                    Being *b = actorSpriteManager->findBeingByName(
-                        nick, Being::PLAYER);
-
-                    if (b)
-                        b->clearGuilds();
-                    if (taGuild)
-                        taGuild->removeMember(nick);
-                }
-            }
+            processGuildExpulsion(msg);
             break;
-        }
 
         case SMSG_GUILD_EXPULSION_LIST:
-        {
-            int length = msg.readInt16();
-            int count = (length - 4) / 88;
-
-            for (int i = 0; i < count; i++)
-            {
-                msg.readString(24); // Name (of expulsed?)
-                msg.readString(24); // 'Acc' (name of expulser?)
-                msg.readString(24); // Message
-            }
-        }
-        break;
+            processGuildExpulsionList(msg);
+            break;
 
         case SMSG_GUILD_MESSAGE:
-        {
-            int msgLength = msg.readInt16() - 4;
-
-            if (msgLength <= 0)
-                return;
-            if (guildTab)
-            {
-                std::string chatMsg = msg.readString(msgLength);
-
-                std::string::size_type pos = chatMsg.find(" : ", 0);
-                if (pos != std::string::npos)
-                {
-                    std::string sender_name = ((pos == std::string::npos)
-                        ? "" : chatMsg.substr(0, pos));
-
-                        chatMsg.erase(0, pos + 3);
-
-                    trim(chatMsg);
-                    guildTab->chatLog(sender_name, chatMsg);
-                }
-                else
-                {
-                    guildTab->chatLog(chatMsg);
-                }
-            }
-        }
-        break;
+            processGuildMessage(msg);
+            break;
 
         case SMSG_GUILD_SKILL_UP:
-            msg.readInt16(); // Skill ID
-            msg.readInt16(); // Level
-            msg.readInt16(); // SP
-            msg.readInt16(); // 'Range'
-            msg.readInt8(); // unused? (always 1)
+            processGuildSkillUp(msg);
             break;
 
         case SMSG_GUILD_REQ_ALLIANCE:
-            msg.readInt32(); // Account ID
-            msg.readString(24); // Name
+            processGuildReqAlliance(msg);
             break;
 
         case SMSG_GUILD_REQ_ALLIANCE_ACK:
-            msg.readInt32(); // Flag
+            processGuildReqAllianceAck(msg);
             break;
 
         case SMSG_GUILD_DEL_ALLIANCE:
-            msg.readInt32(); // Guild ID
-            msg.readInt32(); // Flag
+            processGuildDelAlliance(msg);
             break;
 
         case SMSG_GUILD_OPPOSITION_ACK:
-            msg.readInt8(); // Flag
+            processGuildOppositionAck(msg);
             break;
 
         case SMSG_GUILD_BROKEN:
-            msg.readInt32(); // Flag
+            processGuildBroken(msg);
             break;
 
         default:
diff --git a/src/net/tmwa/guildhandler.h b/src/net/tmwa/guildhandler.h
index f429213a0..58bfa2b0c 100644
--- a/src/net/tmwa/guildhandler.h
+++ b/src/net/tmwa/guildhandler.h
@@ -24,6 +24,10 @@
 
 #include "net/guildhandler.h"
 
+#include "net/ea/guildhandler.h"
+
+#include "net/ea/gui/guildtab.h"
+
 #include "net/tmwa/messagehandler.h"
 
 #ifdef __GNUC__
@@ -35,7 +39,7 @@
 namespace TmwAthena
 {
 
-class GuildHandler : public Net::GuildHandler, public MessageHandler
+class GuildHandler : public Ea::GuildHandler, public MessageHandler
 {
     public:
         GuildHandler();
@@ -80,6 +84,8 @@ class GuildHandler : public Net::GuildHandler, public MessageHandler
 //        Guild *mGuild;
 };
 
+    extern Ea::GuildTab *guildTab;
+    extern Guild *taGuild;
 }
 
 #endif // NET_TA_GUILDHANDLER_H
diff --git a/src/net/tmwa/partyhandler.cpp b/src/net/tmwa/partyhandler.cpp
index 1526100f6..5bbf8baf3 100644
--- a/src/net/tmwa/partyhandler.cpp
+++ b/src/net/tmwa/partyhandler.cpp
@@ -21,36 +21,26 @@
 #include "net/tmwa/partyhandler.h"
 
 #include "actorspritemanager.h"
-#include "event.h"
 #include "localplayer.h"
 #include "log.h"
 
-#include "gui/socialwindow.h"
-
 #include "net/messagein.h"
-#include "net/messageout.h"
 
 #include "net/tmwa/protocol.h"
 
 #include "net/tmwa/gui/partytab.h"
 
 #include "utils/gettext.h"
-#include "utils/stringutils.h"
 
 #include "debug.h"
 
-#define PARTY_ID 1
-
 extern Net::PartyHandler *partyHandler;
 
 namespace TmwAthena
 {
 
-PartyTab *partyTab = 0;
-Party *taParty;
-
-PartyHandler::PartyHandler():
-    mShareExp(PARTY_SHARE_UNKNOWN), mShareItems(PARTY_SHARE_UNKNOWN)
+PartyHandler::PartyHandler() :
+    Ea::PartyHandler()
 {
     static const Uint16 _messages[] =
     {
@@ -68,13 +58,10 @@ PartyHandler::PartyHandler():
     };
     handledMessages = _messages;
     partyHandler = this;
-    taParty = Party::getParty(1);
 }
 
 PartyHandler::~PartyHandler()
 {
-    delete partyTab;
-    partyTab = 0;
 }
 
 void PartyHandler::handleMessage(Net::MessageIn &msg)
@@ -82,374 +69,34 @@ void PartyHandler::handleMessage(Net::MessageIn &msg)
     switch (msg.getId())
     {
         case SMSG_PARTY_CREATE:
-            if (msg.readInt8())
-                SERVER_NOTICE(_("Could not create party."))
-            else
-                SERVER_NOTICE(_("Party successfully created."))
+            processPartyCreate(msg);
             break;
         case SMSG_PARTY_INFO:
-            {
-                bool oldParty = false;
-                std::set<std::string> names;
-                if (!taParty)
-                {
-                    logger->log1("error: party empty in SMSG_PARTY_INFO");
-                    taParty = Party::getParty(1);
-                }
-                if (taParty)
-                {
-                    if (taParty->getNumberOfElements() > 1)
-                    {
-                        oldParty = true;
-
-                        taParty->getNamesSet(names);
-                    }
-                }
-
-                if (!player_node)
-                    logger->log1("error: player_node==0 in SMSG_PARTY_INFO");
-
-                if (taParty)
-                    taParty->clearMembers();
-
-                int length = msg.readInt16();
-                if (taParty)
-                    taParty->setName(msg.readString(24));
-
-                int count = (length - 28) / 46;
-                if (player_node && taParty)
-                {
-                    player_node->setParty(taParty);
-                    player_node->setPartyName(taParty->getName());
-                }
-
-                for (int i = 0; i < count; i++)
-                {
-                    int id = msg.readInt32();
-                    std::string nick = msg.readString(24);
-                    std::string map = msg.readString(16);
-                    bool leader = msg.readInt8() == 0;
-                    bool online = msg.readInt8() == 0;
-
-                    if (taParty)
-                    {
-                        PartyMember *member = 0;
-                        if (oldParty)
-                        {
-                            //member = taParty->getMember(id);
-                            if (partyTab && names.find(nick) == names.end())
-                            {
-                                partyTab->chatLog(strprintf(
-                                    _("%s has joined your party."),
-                                    nick.c_str()), BY_SERVER);
-                            }
-                        }
-                        member = taParty->addMember(id, nick);
-
-                        if (member)
-                        {
-                            member->setLeader(leader);
-                            member->setOnline(online);
-                            member->setMap(map);
-                        }
-                    }
-                }
-
-                if (taParty)
-                    taParty->sort();
-
-                if (player_node && taParty)
-                {
-                    player_node->setParty(taParty);
-                    player_node->setPartyName(taParty->getName());
-                }
-            }
+            processPartyInfo(msg);
             break;
         case SMSG_PARTY_INVITE_RESPONSE:
-            {
-                if (!partyTab)
-                    break;
-
-                std::string nick = msg.readString(24);
-
-                switch (msg.readInt8())
-                {
-                    case 0:
-                        partyTab->chatLog(strprintf(
-                            _("%s is already a member of a party."),
-                            nick.c_str()), BY_SERVER);
-                        break;
-                    case 1:
-                        partyTab->chatLog(strprintf(
-                            _("%s refused your invitation."),
-                            nick.c_str()), BY_SERVER);
-                        break;
-                    case 2:
-                        partyTab->chatLog(strprintf(
-                            _("%s is now a member of your party."),
-                            nick.c_str()), BY_SERVER);
-                        break;
-                    case 3:
-                        partyTab->chatLog(strprintf(
-                            _("%s can't join your party because party is "
-                            "full."), nick.c_str()), BY_SERVER);
-                        break;
-                    default:
-                        partyTab->chatLog(strprintf(
-                            _("QQQ Unknown invite response for %s."),
-                            nick.c_str()), BY_SERVER);
-                        break;
-                }
-                break;
-            }
+            processPartyInviteResponse(msg);
+            break;
         case SMSG_PARTY_INVITED:
-            {
-                int id = msg.readInt32();
-                std::string partyName = msg.readString(24);
-                std::string nick = "";
-                Being *being;
-
-                if (actorSpriteManager)
-                {
-                    if ((being = actorSpriteManager->findBeing(id)))
-                    {
-                        if (being && being->getType() == Being::PLAYER)
-                            nick = being->getName();
-                    }
-                }
-
-                if (socialWindow)
-                    socialWindow->showPartyInvite(partyName, nick);
-                break;
-            }
+            processPartyInvited(msg);
+            break;
         case SMSG_PARTY_SETTINGS:
-            {
-                if (!partyTab)
-                {
-                    if (!chatWindow)
-                        break;
-
-                    partyTab = new PartyTab();
-                }
-
-                // These seem to indicate the sharing mode for exp and items
-                short exp = msg.readInt16();
-                short item = msg.readInt16();
-
-                if (!partyTab)
-                    break;
-
-                switch (exp)
-                {
-                    case PARTY_SHARE:
-                        if (mShareExp == PARTY_SHARE)
-                            break;
-                        mShareExp = PARTY_SHARE;
-                        if (partyTab)
-                        {
-                            partyTab->chatLog(
-                                _("Experience sharing enabled."), BY_SERVER);
-                        }
-                        break;
-                    case PARTY_SHARE_NO:
-                        if (mShareExp == PARTY_SHARE_NO)
-                            break;
-                        mShareExp = PARTY_SHARE_NO;
-                        if (partyTab)
-                        {
-                            partyTab->chatLog(
-                                _("Experience sharing disabled."), BY_SERVER);
-                        }
-                        break;
-                    case PARTY_SHARE_NOT_POSSIBLE:
-                        if (mShareExp == PARTY_SHARE_NOT_POSSIBLE)
-                            break;
-                        mShareExp = PARTY_SHARE_NOT_POSSIBLE;
-                        if (partyTab)
-                        {
-                            partyTab->chatLog(
-                                _("Experience sharing not possible."),
-                                BY_SERVER);
-                        }
-                        break;
-                    default:
-                        logger->log("QQQ Unknown party exp option: %d\n", exp);
-                        break;
-                }
-
-                switch (item)
-                {
-                    case PARTY_SHARE:
-                        if (mShareItems == PARTY_SHARE)
-                            break;
-                        mShareItems = PARTY_SHARE;
-                        if (partyTab)
-                        {
-                            partyTab->chatLog(
-                                _("Item sharing enabled."), BY_SERVER);
-                        }
-                        break;
-                    case PARTY_SHARE_NO:
-                        if (mShareItems == PARTY_SHARE_NO)
-                            break;
-                        mShareItems = PARTY_SHARE_NO;
-                        if (partyTab)
-                        {
-                            partyTab->chatLog(
-                                _("Item sharing disabled."), BY_SERVER);
-                        }
-                        break;
-                    case PARTY_SHARE_NOT_POSSIBLE:
-                        if (mShareItems == PARTY_SHARE_NOT_POSSIBLE)
-                            break;
-                        mShareItems = PARTY_SHARE_NOT_POSSIBLE;
-                        if (partyTab)
-                        {
-                            partyTab->chatLog(
-                                _("Item sharing not possible."), BY_SERVER);
-                        }
-                        break;
-                    default:
-                        logger->log("QQQ Unknown party item option: %d\n",
-                                    exp);
-                        break;
-                }
-                break;
-            }
+            processPartySettings(msg);
+            break;
         case SMSG_PARTY_MOVE:
-            {
-                int id = msg.readInt32();    // id
-                PartyMember *m = 0;
-                if (taParty)
-                    m = taParty->getMember(id);
-                if (m)
-                {
-                    msg.skip(4);
-                    m->setX(msg.readInt16());    // x
-                    m->setY(msg.readInt16());    // y
-                    m->setOnline(msg.readInt8());     // online (if 0)
-                    msg.readString(24); // party
-                    msg.readString(24); // nick
-                    m->setMap(msg.readString(16)); // map
-                }
-                else
-                {
-                    msg.skip(4);
-                    msg.readInt16();    // x
-                    msg.readInt16();    // y
-                    msg.readInt8();     // online (if 0)
-                    msg.readString(24); // party
-                    msg.readString(24); // nick
-                    msg.readString(16); // map
-                }
-            }
+            processPartyMove(msg);
             break;
         case SMSG_PARTY_LEAVE:
-            {
-                int id = msg.readInt32();
-                std::string nick = msg.readString(24);
-                msg.readInt8();     // fail
-                if (player_node && id == player_node->getId())
-                {
-                    if (taParty)
-                    {
-                        taParty->removeFromMembers();
-                        taParty->clearMembers();
-                    }
-                    SERVER_NOTICE(_("You have left the party."))
-                    delete partyTab;
-                    partyTab = 0;
-
-                    if (socialWindow && taParty)
-                        socialWindow->removeTab(taParty);
-                }
-                else
-                {
-                    if (partyTab)
-                    {
-                        partyTab->chatLog(strprintf(
-                            _("%s has left your party."),
-                            nick.c_str()), BY_SERVER);
-                    }
-                    if (actorSpriteManager)
-                    {
-                        Being *b = actorSpriteManager->findBeing(id);
-                        if (b && b->getType() == Being::PLAYER)
-                            b->setParty(0);
-                    }
-                    if (taParty)
-                        taParty->removeMember(id);
-                }
-                break;
-            }
+            processPartyLeave(msg);
+            break;
         case SMSG_PARTY_UPDATE_HP:
-            {
-                int id = msg.readInt32();
-                int hp = msg.readInt16();
-                int maxhp = msg.readInt16();
-                PartyMember *m = 0;
-                if (taParty)
-                    m = 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 (actorSpriteManager && taParty)
-                {
-                    if (Being *b = actorSpriteManager->findBeing(id))
-                        b->setParty(taParty);
-                }
-            }
+            processPartyUpdateHp(msg);
             break;
         case SMSG_PARTY_UPDATE_COORDS:
-            {
-                int id = msg.readInt32(); // id
-                PartyMember *m = 0;
-                if (taParty)
-                    m = taParty->getMember(id);
-                if (m)
-                {
-                    m->setX(msg.readInt16());    // x
-                    m->setY(msg.readInt16());    // y
-                }
-                else
-                {
-                    msg.readInt16();    // x
-                    msg.readInt16();    // y
-                }
-            }
+            processPartyUpdateCoords(msg);
             break;
         case SMSG_PARTY_MESSAGE:
-            {
-                int msgLength = msg.readInt16() - 8;
-                if (msgLength <= 0)
-                    return;
-
-                int id = msg.readInt32();
-                std::string chatMsg = msg.readString(msgLength);
-
-                if (taParty)
-                {
-                    PartyMember *member = taParty->getMember(id);
-                    if (partyTab)
-                    {
-                        if (member)
-                        {
-                            partyTab->chatLog(member->getName(), chatMsg);
-                        }
-                        else
-                        {
-                            partyTab->chatLog(strprintf(
-                                _("An unknown member tried to say: %s"),
-                                chatMsg.c_str()), BY_SERVER);
-                        }
-                    }
-                }
-            }
+            processPartyMessage(msg);
             break;
 
         default:
@@ -463,11 +110,6 @@ void PartyHandler::create(const std::string &name)
     outMsg.writeString(name.substr(0, 23), 24);
 }
 
-void PartyHandler::join(int partyId A_UNUSED)
-{
-    // TODO?
-}
-
 void PartyHandler::invite(Being *being)
 {
     if (being)
@@ -518,15 +160,15 @@ void PartyHandler::kick(Being *being)
 
 void PartyHandler::kick(const std::string &name)
 {
-    if (!taParty)
+    if (!Ea::taParty)
         return;
 
-    PartyMember *m = taParty->getMember(name);
+    PartyMember *m = Ea::taParty->getMember(name);
     if (!m)
     {
-        if (partyTab)
+        if (Ea::partyTab)
         {
-            partyTab->chatLog(strprintf(_("%s is not in your party!"),
+            Ea::partyTab->chatLog(strprintf(_("%s is not in your party!"),
                               name.c_str()), BY_SERVER);
         }
         return;
@@ -544,12 +186,6 @@ void PartyHandler::chat(const std::string &text)
     outMsg.writeString(text, static_cast<int>(text.length()));
 }
 
-void PartyHandler::requestPartyMembers() const
-{
-    // Our eAthena doesn't have this message
-    // Not needed anyways
-}
-
 void PartyHandler::setShareExperience(PartyShare share)
 {
     if (share == PARTY_SHARE_NOT_POSSIBLE)
@@ -570,14 +206,4 @@ void PartyHandler::setShareItems(PartyShare share)
     outMsg.writeInt16(share);
 }
 
-void PartyHandler::reload()
-{
-    taParty = Party::getParty(1);
-}
-
-void PartyHandler::clear()
-{
-    taParty = 0;
-}
-
 } // namespace TmwAthena
diff --git a/src/net/tmwa/partyhandler.h b/src/net/tmwa/partyhandler.h
index d2b204a55..209ea5047 100644
--- a/src/net/tmwa/partyhandler.h
+++ b/src/net/tmwa/partyhandler.h
@@ -26,6 +26,8 @@
 
 #include "net/tmwa/messagehandler.h"
 
+#include "net/ea/partyhandler.h"
+
 #include "party.h"
 
 #ifdef __GNUC__
@@ -37,7 +39,7 @@
 namespace TmwAthena
 {
 
-class PartyHandler : public MessageHandler, public Net::PartyHandler
+class PartyHandler : public MessageHandler, public Ea::PartyHandler
 {
     public:
         PartyHandler();
@@ -48,8 +50,6 @@ class PartyHandler : public MessageHandler, public Net::PartyHandler
 
         void create(const std::string &name = "");
 
-        void join(int partyId);
-
         void invite(Being *being);
 
         void invite(const std::string &name);
@@ -64,24 +64,9 @@ class PartyHandler : public MessageHandler, public Net::PartyHandler
 
         void chat(const std::string &text);
 
-        void requestPartyMembers() const;
-
-        PartyShare getShareExperience() const
-        { return mShareExp; }
-
         void setShareExperience(PartyShare share);
 
-        PartyShare getShareItems() const
-        { return mShareItems; }
-
         void setShareItems(PartyShare share);
-
-        void reload();
-
-        void clear();
-
-    private:
-        PartyShare mShareExp, mShareItems;
 };
 
 } // namespace TmwAthena
-- 
cgit v1.2.3-70-g09d2