From 203774b4e7d1c5c0a74cb6f9e3e104fb2f5a2c81 Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Sun, 31 Jul 2011 17:43:25 +0300 Subject: Extract shared logic from tradehandler netcode to ea namespace. --- src/CMakeLists.txt | 2 + src/Makefile.am | 4 +- src/net/ea/tradehandler.cpp | 284 ++++++++++++++++++++++++++++++++++++++++++ src/net/ea/tradehandler.h | 63 ++++++++++ src/net/tmwa/tradehandler.cpp | 230 ++-------------------------------- src/net/tmwa/tradehandler.h | 6 +- 6 files changed, 362 insertions(+), 227 deletions(-) create mode 100644 src/net/ea/tradehandler.cpp create mode 100644 src/net/ea/tradehandler.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 36127c5f3..4d230c18f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -710,6 +710,8 @@ SET(SRCS_EVOL net/ea/specialhandler.cpp net/ea/specialhandler.h net/ea/token.h + net/ea/tradehandler.cpp + net/ea/tradehandler.h ) SET(SRCS_TMWA diff --git a/src/Makefile.am b/src/Makefile.am index b4c42472b..18ae560b8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -692,8 +692,10 @@ manaplus_SOURCES += \ net/ea/playerhandler.cpp \ net/ea/playerhandler.h \ net/ea/specialhandler.cpp \ - net/ewa/specialhandler.h \ + net/ea/specialhandler.h \ net/ea/token.h \ + net/ea/tradehandler.cpp \ + net/ea/tradehandler.h \ net/tmwa/gui/guildtab.cpp \ net/tmwa/gui/guildtab.h \ net/tmwa/gui/partytab.cpp \ diff --git a/src/net/ea/tradehandler.cpp b/src/net/ea/tradehandler.cpp new file mode 100644 index 000000000..36a5f8811 --- /dev/null +++ b/src/net/ea/tradehandler.cpp @@ -0,0 +1,284 @@ +/* + * The ManaPlus Client + * Copyright (C) 2004-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 . + */ + +#include "net/ea/tradehandler.h" + +#include "event.h" +#include "inventory.h" +#include "item.h" +#include "log.h" +#include "playerinfo.h" +#include "playerrelations.h" + +#include "gui/confirmdialog.h" +#include "gui/tradewindow.h" + +#include "net/inventoryhandler.h" +#include "net/messagein.h" + +#include "net/ea/eaprotocol.h" + +#include "utils/gettext.h" + +#include "debug.h" + +extern std::string tradePartnerName; +ConfirmDialog *confirmDlg; + +/** + * Listener for request trade dialogs + */ +namespace +{ + struct RequestTradeListener : public gcn::ActionListener + { + void action(const gcn::ActionEvent &event) + { + confirmDlg = 0; + if (event.getId() == "ignore") + player_relations.ignoreTrade(tradePartnerName); + Net::getTradeHandler()->respond(event.getId() == "yes"); + } + } listener; +} + +namespace Ea +{ + +TradeHandler::TradeHandler() +{ + confirmDlg = 0; +} + +void TradeHandler::removeItem(int slotNum A_UNUSED, int amount A_UNUSED) +{ + // TODO +} + +void TradeHandler::processTradeRequest(Net::MessageIn &msg) +{ + // If a trade window or request window is already open, send a + // trade cancel to any other trade request. + // + // Note that it would be nice if the server would prevent this + // situation, and that the requesting player would get a + // special message about the player being occupied. + std::string tradePartnerNameTemp = msg.readString(24); + + if (player_relations.hasPermission(tradePartnerName, + PlayerRelation::TRADE)) + { + if (PlayerInfo::isTrading() || confirmDlg) + { + Net::getTradeHandler()->respond(false); + return; + } + + tradePartnerName = tradePartnerNameTemp; + PlayerInfo::setTrading(true); + if (tradeWindow) + { + if (tradePartnerName.empty() + || tradeWindow->getAutoTradeNick() + != tradePartnerName) + { + tradeWindow->clear(); + confirmDlg = new ConfirmDialog( + _("Request for Trade"), + strprintf(_("%s wants to trade with you, do" + " you accept?"), tradePartnerName.c_str()), + true); + confirmDlg->addActionListener(&listener); + } + else + { + Net::getTradeHandler()->respond(true); + } + } + } + else + { + Net::getTradeHandler()->respond(false); + return; + } +} + +void TradeHandler::processTradeResponse(Net::MessageIn &msg) +{ + switch (msg.readInt8()) + { + case 0: // Too far away + SERVER_NOTICE(_("Trading isn't possible. Trade " + "partner is too far away.")) + break; + case 1: // Character doesn't exist + SERVER_NOTICE(_("Trading isn't possible. Character " + "doesn't exist.")) + break; + case 2: // Invite request check failed... + SERVER_NOTICE(_("Trade cancelled due to an unknown " + "reason.")) + break; + case 3: // Trade accepted + if (tradeWindow) + { + tradeWindow->reset(); + tradeWindow->setCaption(strprintf( + _("Trade: You and %s"), + tradePartnerName.c_str())); + tradeWindow->initTrade(tradePartnerName); + tradeWindow->setVisible(true); + } + break; + case 4: // Trade cancelled + if (player_relations.hasPermission(tradePartnerName, + PlayerRelation::SPEECH_LOG)) + { + SERVER_NOTICE(strprintf(_("Trade with %s cancelled."), + tradePartnerName.c_str())) + } + // otherwise ignore silently + + if (tradeWindow) + { + tradeWindow->setVisible(false); +// tradeWindow->clear(); + } + PlayerInfo::setTrading(false); + break; + default: // Shouldn't happen as well, but to be sure + SERVER_NOTICE(_("Unhandled trade cancel packet.")) + if (tradeWindow) + tradeWindow->clear(); + break; + } +} + +void TradeHandler::processTradeItemAdd(Net::MessageIn &msg) +{ + int amount = msg.readInt32(); + int type = msg.readInt16(); + int identify = msg.readInt8(); // identified flag + msg.readInt8(); // attribute + int refine = msg.readInt8(); // refine + msg.skip(8); // card (4 shorts) + + // TODO: handle also identified, etc + if (tradeWindow) + { + if (type == 0) + { + tradeWindow->setMoney(amount); + } + else + { + tradeWindow->addItem2(type, false, amount, refine, + static_cast(identify), false); + } + } +} + +void TradeHandler::processTradeItemAddResponse(Net::MessageIn &msg) +{ + // Trade: New Item add response (was 0x00ea, now 01b1) + const int index = msg.readInt16() - INVENTORY_OFFSET; + Item *item = PlayerInfo::getInventory()->getItem(index); + if (!item) + { + if (tradeWindow) + tradeWindow->receivedOk(true); + return; + } + int quantity = msg.readInt16(); + + int res = msg.readInt8(); + switch (res) + { + case 0: + // Successfully added item + if (item->isEquipment() && item->isEquipped()) + Net::getInventoryHandler()->unequipItem(item); + + if (tradeWindow) + { + tradeWindow->addItem2(item->getId(), true, + quantity, item->getRefine(), item->getColor(), + item->isEquipment()); + } + item->increaseQuantity(-quantity); + break; + case 1: + // Add item failed - player overweighted + SERVER_NOTICE(_("Failed adding item. Trade " + "partner is over weighted.")) + break; + case 2: + // Add item failed - player has no free slot + SERVER_NOTICE(_("Failed adding item. Trade " + "partner has no free slot.")) + break; + case 3: + // Add item failed - non tradable item + SERVER_NOTICE(_("Failed adding item. You " + "can't trade this item.")) + break; + default: + SERVER_NOTICE(_("Failed adding item for " + "unknown reason.")) + logger->log("QQQ SMSG_TRADE_ITEM_ADD_RESPONSE: " + + toString(res)); + break; + } +} + +void TradeHandler::processTradeOk(Net::MessageIn &msg) +{ + // 0 means ok from myself, 1 means ok from other; + if (tradeWindow) + tradeWindow->receivedOk(msg.readInt8() == 0); + else + msg.readInt8(); +} + +void TradeHandler::processTradeCancel(Net::MessageIn &msg A_UNUSED) +{ + SERVER_NOTICE(_("Trade canceled.")) + if (tradeWindow) + { + tradeWindow->setVisible(false); + tradeWindow->reset(); + } + PlayerInfo::setTrading(false); +} + +void TradeHandler::processTradeComplete(Net::MessageIn &msg A_UNUSED) +{ + SERVER_NOTICE(_("Trade completed.")) + if (tradeWindow) + { + tradeWindow->setVisible(false); + tradeWindow->reset(); + } + PlayerInfo::setTrading(false); +} + +} // namespace Ea diff --git a/src/net/ea/tradehandler.h b/src/net/ea/tradehandler.h new file mode 100644 index 000000000..2a27f8c31 --- /dev/null +++ b/src/net/ea/tradehandler.h @@ -0,0 +1,63 @@ +/* + * The ManaPlus Client + * Copyright (C) 2004-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 . + */ + +#ifndef NET_EA_TRADEHANDLER_H +#define NET_EA_TRADEHANDLER_H + +#include "net/messagein.h" +#include "net/net.h" +#include "net/tradehandler.h" + +#ifdef __GNUC__ +#define A_UNUSED __attribute__ ((unused)) +#else +#define A_UNUSED +#endif + +namespace Ea +{ + +class TradeHandler : public Net::TradeHandler +{ + public: + TradeHandler(); + + void removeItem(int slotNum, int amount); + + void processTradeRequest(Net::MessageIn &msg); + + void processTradeResponse(Net::MessageIn &msg); + + void processTradeItemAdd(Net::MessageIn &msg); + + void processTradeItemAddResponse(Net::MessageIn &msg); + + void processTradeOk(Net::MessageIn &msg); + + void processTradeCancel(Net::MessageIn &msg); + + void processTradeComplete(Net::MessageIn &msg); +}; + +} // namespace Ea + +#endif // NET_EA_TRADEHANDLER_H diff --git a/src/net/tmwa/tradehandler.cpp b/src/net/tmwa/tradehandler.cpp index 083ff5154..108b544a0 100644 --- a/src/net/tmwa/tradehandler.cpp +++ b/src/net/tmwa/tradehandler.cpp @@ -22,50 +22,18 @@ #include "net/tmwa/tradehandler.h" -#include "event.h" -#include "inventory.h" #include "item.h" -#include "localplayer.h" #include "log.h" #include "playerinfo.h" -#include "playerrelations.h" -#include "gui/confirmdialog.h" -#include "gui/tradewindow.h" - -#include "net/inventoryhandler.h" #include "net/messagein.h" -#include "net/messageout.h" #include "net/tmwa/protocol.h" #include "net/ea/eaprotocol.h" -#include "utils/gettext.h" -#include "utils/stringutils.h" - #include "debug.h" -extern std::string tradePartnerName; -ConfirmDialog *confirmDlg; - -/** - * Listener for request trade dialogs - */ -namespace -{ - struct RequestTradeListener : public gcn::ActionListener - { - void action(const gcn::ActionEvent &event) - { - confirmDlg = 0; - if (event.getId() == "ignore") - player_relations.ignoreTrade(tradePartnerName); - Net::getTradeHandler()->respond(event.getId() == "yes"); - } - } listener; -} - extern Net::TradeHandler *tradeHandler; namespace TmwAthena @@ -86,7 +54,6 @@ TradeHandler::TradeHandler() }; handledMessages = _messages; tradeHandler = this; - confirmDlg = 0; } @@ -95,209 +62,31 @@ void TradeHandler::handleMessage(Net::MessageIn &msg) switch (msg.getId()) { case SMSG_TRADE_REQUEST: - { - // If a trade window or request window is already open, send a - // trade cancel to any other trade request. - // - // Note that it would be nice if the server would prevent this - // situation, and that the requesting player would get a - // special message about the player being occupied. - std::string tradePartnerNameTemp = msg.readString(24); - - if (player_relations.hasPermission(tradePartnerName, - PlayerRelation::TRADE)) - { - if (PlayerInfo::isTrading() || confirmDlg) - { - Net::getTradeHandler()->respond(false); - break; - } - - tradePartnerName = tradePartnerNameTemp; - PlayerInfo::setTrading(true); - if (tradeWindow) - { - if (tradePartnerName.empty() - || tradeWindow->getAutoTradeNick() - != tradePartnerName) - { - tradeWindow->clear(); - confirmDlg = new ConfirmDialog( - _("Request for Trade"), - strprintf(_("%s wants to trade with you, do" - " you accept?"), tradePartnerName.c_str()), - true); - confirmDlg->addActionListener(&listener); - } - else - { - Net::getTradeHandler()->respond(true); - } - } - } - else - { - Net::getTradeHandler()->respond(false); - break; - } - } + processTradeRequest(msg); break; case SMSG_TRADE_RESPONSE: - switch (msg.readInt8()) - { - case 0: // Too far away - SERVER_NOTICE(_("Trading isn't possible. Trade " - "partner is too far away.")) - break; - case 1: // Character doesn't exist - SERVER_NOTICE(_("Trading isn't possible. Character " - "doesn't exist.")) - break; - case 2: // Invite request check failed... - SERVER_NOTICE(_("Trade cancelled due to an unknown " - "reason.")) - break; - case 3: // Trade accepted - if (tradeWindow) - { - tradeWindow->reset(); - tradeWindow->setCaption(strprintf( - _("Trade: You and %s"), - tradePartnerName.c_str())); - tradeWindow->initTrade(tradePartnerName); - tradeWindow->setVisible(true); - } - break; - case 4: // Trade cancelled - if (player_relations.hasPermission(tradePartnerName, - PlayerRelation::SPEECH_LOG)) - { - SERVER_NOTICE(strprintf(_("Trade with %s cancelled."), - tradePartnerName.c_str())) - } - // otherwise ignore silently - - if (tradeWindow) - { - tradeWindow->setVisible(false); -// tradeWindow->clear(); - } - PlayerInfo::setTrading(false); - break; - default: // Shouldn't happen as well, but to be sure - SERVER_NOTICE(_("Unhandled trade cancel packet.")) - if (tradeWindow) - tradeWindow->clear(); - break; - } + processTradeResponse(msg); break; case SMSG_TRADE_ITEM_ADD: - { - int amount = msg.readInt32(); - int type = msg.readInt16(); - int identify = msg.readInt8(); // identified flag - msg.readInt8(); // attribute - int refine = msg.readInt8(); // refine - msg.skip(8); // card (4 shorts) - - // TODO: handle also identified, etc - if (tradeWindow) - { - if (type == 0) - { - tradeWindow->setMoney(amount); - } - else - { - tradeWindow->addItem2(type, false, amount, refine, - static_cast(identify), false); - } - } - } + processTradeItemAdd(msg); break; case SMSG_TRADE_ITEM_ADD_RESPONSE: - // Trade: New Item add response (was 0x00ea, now 01b1) - { - const int index = msg.readInt16() - INVENTORY_OFFSET; - Item *item = PlayerInfo::getInventory()->getItem(index); - if (!item) - { - if (tradeWindow) - tradeWindow->receivedOk(true); - return; - } - int quantity = msg.readInt16(); - - int res = msg.readInt8(); - switch (res) - { - case 0: - // Successfully added item - if (item->isEquipment() && item->isEquipped()) - Net::getInventoryHandler()->unequipItem(item); - - if (tradeWindow) - { - tradeWindow->addItem2(item->getId(), true, - quantity, item->getRefine(), item->getColor(), - item->isEquipment()); - } - item->increaseQuantity(-quantity); - break; - case 1: - // Add item failed - player overweighted - SERVER_NOTICE(_("Failed adding item. Trade " - "partner is over weighted.")) - break; - case 2: - // Add item failed - player has no free slot - SERVER_NOTICE(_("Failed adding item. Trade " - "partner has no free slot.")) - break; - case 3: - // Add item failed - non tradable item - SERVER_NOTICE(_("Failed adding item. You " - "can't trade this item.")) - break; - default: - SERVER_NOTICE(_("Failed adding item for " - "unknown reason.")) - logger->log("QQQ SMSG_TRADE_ITEM_ADD_RESPONSE: " - + toString(res)); - break; - } - } + processTradeItemAddResponse(msg); break; case SMSG_TRADE_OK: - // 0 means ok from myself, 1 means ok from other; - if (tradeWindow) - tradeWindow->receivedOk(msg.readInt8() == 0); - else - msg.readInt8(); + processTradeOk(msg); break; case SMSG_TRADE_CANCEL: - SERVER_NOTICE(_("Trade canceled.")) - if (tradeWindow) - { - tradeWindow->setVisible(false); - tradeWindow->reset(); - } - PlayerInfo::setTrading(false); + processTradeCancel(msg); break; case SMSG_TRADE_COMPLETE: - SERVER_NOTICE(_("Trade completed.")) - if (tradeWindow) - { - tradeWindow->setVisible(false); - tradeWindow->reset(); - } - PlayerInfo::setTrading(false); + processTradeComplete(msg); break; default: @@ -334,11 +123,6 @@ void TradeHandler::addItem(Item *item, int amount) outMsg.writeInt32(amount); } -void TradeHandler::removeItem(int slotNum A_UNUSED, int amount A_UNUSED) -{ - // TODO -} - void TradeHandler::setMoney(int amount) { MessageOut outMsg(CMSG_TRADE_ITEM_ADD_REQUEST); diff --git a/src/net/tmwa/tradehandler.h b/src/net/tmwa/tradehandler.h index 89f8d8a3a..85c153743 100644 --- a/src/net/tmwa/tradehandler.h +++ b/src/net/tmwa/tradehandler.h @@ -26,6 +26,8 @@ #include "net/net.h" #include "net/tradehandler.h" +#include "net/ea/tradehandler.h" + #include "net/tmwa/messagehandler.h" #ifdef __GNUC__ @@ -37,7 +39,7 @@ namespace TmwAthena { -class TradeHandler : public MessageHandler, public Net::TradeHandler +class TradeHandler : public MessageHandler, public Ea::TradeHandler { public: TradeHandler(); @@ -50,8 +52,6 @@ class TradeHandler : public MessageHandler, public Net::TradeHandler void addItem(Item *item, int amount); - void removeItem(int slotNum, int amount); - void setMoney(int amount); void confirm(); -- cgit v1.2.3-70-g09d2