summaryrefslogtreecommitdiff
path: root/src/net/ea
diff options
context:
space:
mode:
Diffstat (limited to 'src/net/ea')
-rw-r--r--src/net/ea/gamehandler.cpp2
-rw-r--r--src/net/ea/gamehandler.h1
-rw-r--r--src/net/ea/gui/guildtab.cpp154
-rw-r--r--src/net/ea/gui/guildtab.h57
-rw-r--r--src/net/ea/gui/partytab.cpp245
-rw-r--r--src/net/ea/gui/partytab.h58
-rw-r--r--src/net/ea/guildhandler.cpp590
-rw-r--r--src/net/ea/guildhandler.h115
-rw-r--r--src/net/ea/partyhandler.cpp451
-rw-r--r--src/net/ea/partyhandler.h91
10 files changed, 1762 insertions, 2 deletions
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