summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorblue112 <bluesansdouze@gmail.com>2009-04-21 15:36:50 +0200
committerJared Adams <jaxad0127@gmail.com>2009-04-21 08:31:07 -0600
commit0d100ca5fc6854de9906d9e972ef26be6bbed802 (patch)
tree012c4016af6243e3f33a5a39d74c9c6cd12e0f5f /src
parente26e524ad739dafd99954add3c2f35842e9fb6ec (diff)
downloadmanaserv-0d100ca5fc6854de9906d9e972ef26be6bbed802.tar.gz
manaserv-0d100ca5fc6854de9906d9e972ef26be6bbed802.tar.bz2
manaserv-0d100ca5fc6854de9906d9e972ef26be6bbed802.tar.xz
manaserv-0d100ca5fc6854de9906d9e972ef26be6bbed802.zip
Trade System Patch (server side)
Server side modification for making the three steps trade working. For tmwserv Some trade related protocol modification too.
Diffstat (limited to 'src')
-rw-r--r--src/defines.h15
-rw-r--r--src/game-server/character.cpp2
-rw-r--r--src/game-server/gamehandler.cpp12
-rw-r--r--src/game-server/trade.cpp101
-rw-r--r--src/game-server/trade.hpp22
5 files changed, 113 insertions, 39 deletions
diff --git a/src/defines.h b/src/defines.h
index e4421e0c..a6655447 100644
--- a/src/defines.h
+++ b/src/defines.h
@@ -172,12 +172,15 @@ enum {
GPMSG_TRADE_COMPLETE = 0x02C3, // -
PGMSG_TRADE_CANCEL = 0x02C4, // -
GPMSG_TRADE_CANCEL = 0x02C5, // -
- PGMSG_TRADE_ACCEPT = 0x02C6, // -
- GPMSG_TRADE_ACCEPT = 0x02C7, // -
- PGMSG_TRADE_ADD_ITEM = 0x02C8, // B slot, B amount
- GPMSG_TRADE_ADD_ITEM = 0x02C9, // W item id, B amount
- PGMSG_TRADE_SET_MONEY = 0x02CA, // L amount
- GPMSG_TRADE_SET_MONEY = 0x02CB, // L amount
+ PGMSG_TRADE_AGREED = 0x02C6, // -
+ GPMSG_TRADE_AGREED = 0x02C7, // -
+ PGMSG_TRADE_CONFIRM = 0x02C8, // -
+ GPMSG_TRADE_CONFIRM = 0x02C9, // -
+ PGMSG_TRADE_ADD_ITEM = 0x02CA, // B slot, B amount
+ GPMSG_TRADE_ADD_ITEM = 0x02CB, // W item id, B amount
+ PGMSG_TRADE_SET_MONEY = 0x02CC, // L amount
+ GPMSG_TRADE_SET_MONEY = 0x02CD, // L amount
+ GPMSG_TRADE_BOTH_CONFIRM = 0x02CE, // -
PGMSG_USE_ITEM = 0x0300, // B slot
GPMSG_USE_RESPONSE = 0x0301, // B error
GPMSG_BEINGS_DAMAGE = 0x0310, // { W being id, W amount }*
diff --git a/src/game-server/character.cpp b/src/game-server/character.cpp
index d35124e5..b60cf4e1 100644
--- a/src/game-server/character.cpp
+++ b/src/game-server/character.cpp
@@ -221,7 +221,7 @@ void Character::cancelTransaction()
switch (t)
{
case TRANS_TRADE:
- static_cast< Trade * >(mTransactionHandler)->cancel(this);
+ static_cast< Trade * >(mTransactionHandler)->cancel();
break;
case TRANS_BUYSELL:
static_cast< BuySell * >(mTransactionHandler)->cancel();
diff --git a/src/game-server/gamehandler.cpp b/src/game-server/gamehandler.cpp
index 7caa7191..e1301712 100644
--- a/src/game-server/gamehandler.cpp
+++ b/src/game-server/gamehandler.cpp
@@ -443,7 +443,8 @@ void GameHandler::processMessage(NetComputer *comp, MessageIn &message)
} break;
case PGMSG_TRADE_CANCEL:
- case PGMSG_TRADE_ACCEPT:
+ case PGMSG_TRADE_AGREED:
+ case PGMSG_TRADE_CONFIRM:
case PGMSG_TRADE_ADD_ITEM:
case PGMSG_TRADE_SET_MONEY:
{
@@ -454,10 +455,13 @@ void GameHandler::processMessage(NetComputer *comp, MessageIn &message)
switch (message.getId())
{
case PGMSG_TRADE_CANCEL:
- t->cancel(computer.character);
+ t->cancel();
break;
- case PGMSG_TRADE_ACCEPT :
- t->accept(computer.character);
+ case PGMSG_TRADE_CONFIRM:
+ t->confirm(computer.character);
+ break;
+ case PGMSG_TRADE_AGREED:
+ t->agree(computer.character);
// log transaction
accountHandler->sendTransaction(computer.character->getDatabaseID(),
TRANS_TRADE_END, "User finished trading");
diff --git a/src/game-server/trade.cpp b/src/game-server/trade.cpp
index e5ceea3d..92c31a82 100644
--- a/src/game-server/trade.cpp
+++ b/src/game-server/trade.cpp
@@ -30,6 +30,15 @@
#include "game-server/inventory.hpp"
#include "net/messageout.hpp"
+/*
+ * States :
+ * TRADE_INIT : A player has ask to make a trade, waiting for accept
+ * TRADE_RUN : Both player are now trading and can add objects and GP (1)
+ * TRADE_CONFIRM_WAIT : One player has confirm, waiting for the other one
+ * TRADE_CONFIRMED : Both player has confirmed and agree button is unlock (2)
+ * TRADE_AGREE_WAIT : One player has agreed, waiting for the other one
+ */
+
Trade::Trade(Character *c1, Character *c2):
mChar1(c1), mChar2(c2), mMoney1(0), mMoney2(0), mState(TRADE_INIT)
{
@@ -46,26 +55,31 @@ Trade::~Trade()
mChar2->setTrading(NULL);
}
-void Trade::cancel(Character *c)
+void Trade::cancel()
{
MessageOut msg(GPMSG_TRADE_CANCEL);
- if (c != mChar1) mChar1->getClient()->send(msg);
- if (c != mChar2) mChar2->getClient()->send(msg);
+ mChar1->getClient()->send(msg);
+ mChar2->getClient()->send(msg);
delete this;
}
bool Trade::request(Character *c, int id)
{
+ //The trade isn't confirmed, the player which is request is the same.
if (mState != TRADE_INIT || c != mChar2 || mChar1->getPublicID() != id)
{
/* This is not an ack for the current transaction. So assume
a new one is about to start and cancel the current one. */
- cancel(c);
+ cancel();
return false;
}
-
- // Starts trading.
+
+ //Second player confirmed.
+
+ //Starts trading.
mState = TRADE_RUN;
+
+ //Telling both player that the trade has started
MessageOut msg(GPMSG_TRADE_START);
mChar1->getClient()->send(msg);
mChar2->getClient()->send(msg);
@@ -87,30 +101,37 @@ bool Trade::perform(TradedItems items, Inventory &inv1, Inventory &inv2)
return true;
}
-void Trade::accept(Character *c)
+void Trade::agree(Character *c)
{
- if (mState == TRADE_RUN)
+ //No player agreed
+ if(mState == TRADE_CONFIRMED)
{
+ //One player agreed, if it's the player 2, make it player 1
if (c == mChar2)
{
std::swap(mChar1, mChar2);
std::swap(mItems1, mItems2);
std::swap(mMoney1, mMoney2);
}
- assert(c == mChar1);
// First player agrees.
- mState = TRADE_EXIT;
- MessageOut msg(GPMSG_TRADE_ACCEPT);
+ mState = TRADE_CONFIRM_WAIT;
+
+ //Send the other player that the first player has confirmed
+ MessageOut msg(GPMSG_TRADE_AGREED);
mChar2->getClient()->send(msg);
return;
}
-
- if (mState != TRADE_EXIT || c != mChar2)
+
+ if(mState == TRADE_AGREE_WAIT && c == mChar1)
{
- // First player has already agreed. We only care about the second one.
+ //We don't care about the first player, he already agreed
return;
}
-
+
+ //The second player has agreed
+
+ //Check if both player has the objects in their inventories
+ // and enouth money, then swap them.
Inventory v1(mChar1, true), v2(mChar2, true);
if (!perform(mItems1, v1, v2) ||
!perform(mItems2, v2, v1) ||
@@ -119,19 +140,56 @@ void Trade::accept(Character *c)
{
v1.cancel();
v2.cancel();
- cancel(NULL);
+ cancel();
return;
}
-
+
MessageOut msg(GPMSG_TRADE_COMPLETE);
mChar1->getClient()->send(msg);
mChar2->getClient()->send(msg);
delete this;
}
+void Trade::confirm(Character *c)
+{
+ if(mState == TRADE_CONFIRMED || mState == TRADE_AGREE_WAIT) return;
+
+ if (mState == TRADE_RUN) //No player has confirmed
+ {
+ //One player confirms, if it's the player 2, make it player 1
+ if (c == mChar2)
+ {
+ std::swap(mChar1, mChar2);
+ std::swap(mItems1, mItems2);
+ std::swap(mMoney1, mMoney2);
+ }
+ assert(c == mChar1);
+ // First player agrees.
+ mState = TRADE_CONFIRM_WAIT;
+
+ //Send the other player that the first player has confirmed
+ MessageOut msg(GPMSG_TRADE_CONFIRM);
+ mChar2->getClient()->send(msg);
+ return;
+ }
+
+ if (mState != TRADE_CONFIRM_WAIT || c != mChar2)
+ {
+ // First player has already agreed. We only care about the second one.
+ return;
+ }
+
+ mState = TRADE_CONFIRMED;
+ MessageOut msg(GPMSG_TRADE_BOTH_CONFIRM);
+ mChar1->getClient()->send(msg);
+ mChar2->getClient()->send(msg);
+}
+
void Trade::setMoney(Character *c, int amount)
{
- if (mState == TRADE_INIT || amount < 0) return;
+ //If the player has already confirmed, exit.
+ if ((mState != TRADE_RUN && (mState != TRADE_CONFIRM_WAIT || c != mChar1))
+ || amount < 0) return;
/* Checking now if there is enough money is useless as it can change
later on. At worst, the transaction will be canceled at the end if
@@ -158,7 +216,9 @@ void Trade::setMoney(Character *c, int amount)
void Trade::addItem(Character *c, int slot, int amount)
{
- if (mState == TRADE_INIT) return;
+ //If the player has already confirmed, exit.
+ if ((mState != TRADE_RUN && (mState != TRADE_CONFIRM_WAIT || c != mChar1))
+ || amount < 0) return;
Character *other;
TradedItems *items;
@@ -192,7 +252,4 @@ void Trade::addItem(Character *c, int slot, int amount)
msg.writeShort(id);
msg.writeByte(amount);
other->getClient()->send(msg);
-
- // Go back to normal run.
- mState = TRADE_RUN;
}
diff --git a/src/game-server/trade.hpp b/src/game-server/trade.hpp
index 14e99e82..f1a9613a 100644
--- a/src/game-server/trade.hpp
+++ b/src/game-server/trade.hpp
@@ -42,7 +42,7 @@ class Trade
* Warns the other character the trade is cancelled.
* Takes care of cleaning afterwards.
*/
- void cancel(Character *);
+ void cancel(void);
/**
* Requests a trade to start with given public ID.
@@ -53,10 +53,15 @@ class Trade
bool request(Character *, int);
/**
- * Agrees to complete the trade.
+ * Confirm the trade.
*/
- void accept(Character *);
+ void confirm(Character *);
+ /*
+ * Agree to complete the trade
+ */
+ void agree(Character *c);
+
/**
* Adds some items to the trade.
*/
@@ -79,11 +84,16 @@ class Trade
typedef std::vector< TradedItem > TradedItems;
+ /*
+ * See trade.cpp for doc on TradeStates
+ */
enum TradeState
{
- TRADE_INIT = 0, /**< Waiting for an ack from player 2. */
- TRADE_RUN, /**< Currently trading. */
- TRADE_EXIT /**< Waiting for an ack from player 2. */
+ TRADE_INIT = 0,
+ TRADE_RUN,
+ TRADE_CONFIRM_WAIT,
+ TRADE_CONFIRMED,
+ TRADE_AGREE_WAIT
};
static bool perform(TradedItems items, Inventory &inv1, Inventory &inv2);