Player trading

This describes how trading between players is implemented.
Please note, that all other (item dropping, equipping, adding to inventory) is taken as working and explained, and is NOT being explained here again!
This solution uses principles explained in previous parts of documentation


Top

1 Objective

We want two players to be able to exchange items (trade). The requirements are following:

2 Definitions

Word(s) Explanation
Revert the trade Give items back to both players
Close the trade Revert trade for both players

3 Network messages

As another step of analysis, let's have a look at messages, that will have to be sent between server and client to accomplish this task:

The message in the following tables is just verbal description, it has nothing to do with class names or code names ×

Server to client messages:

Message Explanation
TradeRequest Informs server that player A want to initiate trade with player B
TradeAccept Informs server that player X accepted trade
TradeDecline Informs server that player X declined trade
TradeAddItem / TradeRemoveItem Informs server that player X wants to add / remove item to the offer window

Client to server messages:

Message Explanation
TradeRequest Informs player A that player B wants to trade him
TradeOpen Opens trade window on client side
TradeClose (sucessfull or unsuccessfull) Closes trade window on client side and displays console message
TradeAccept Informs player A that player B has accepted trade
TradeAddItem / TradeRemoveItem Client side removes / adds item to the html offer window

Using the messages above (mostly like 3 or more messages can fit into one packet class), it is possible to implement entire trading system between players.
Understanding, that once trade is successfully finished, items are removed / added to player inventories accordingly, if at all possible.

4 Trade orchestrator

In order to manage all trades, there must be a class that takes a care about it.
However, one can say, that trade instance can be inside relevant player instance, which would be possible solution, however, not so versatile as it is needed, because if we would like to cancel all ongoing trades (for example when the server shuts down), the task and iteration would be quite ugly.

The trade orchestrator (trade manager) can do following things:

5 Client side representation


5.1 Parsing the events

This is actually very simple.
There is HTML window, representing the trade, and it is hidden, or shown, or it's elements are changed according to the packet received.
Also, appropriate console messages are shown about trade progress


5.2 Item displayment

On client side, an instance of InventoryHTML is created, allowing to parse pormal inventory event packet. This allows sending such a packet, but inside trading packet, with additional info.
Like that, quite simply, items can be displayed inside the trade windows.

6 Adding item to trade window

This is done on the server side, and once it it done, updater takes all created packets and send them to clients.
When item is added to trade window, it is physically removed from the inventory, and added to the trade instance.

7 Adding item to trade window

This is processs of cancelling existing trade, where the items must be returned back to their owners
In this case, we can run to problems:

Problem Solution
The player is no longer in game We MUST make sure it never happens *
The player has no inventory space Item is dropped under him
The player is in different map We MUST make sure it never happens

Now if player is no longer in game, well, we can not forbid client to disconnect...
However, whenever client disconnects, we can revert his on going trade transaction (revert for both sides), before he is saved to database.
That solves the problem. (since the trade will be closed for both sodes anyway...)

8 Making sure special cases will not break the solution

As stated above, we must make sure that player will never be able to switch maps, while trading.
Reverting such a trade, would still be possible, however, we set it as rule, because then it would all be so chaotic in game...
While player is trading, we forbid him to do following (and if he does it, it reverts ongoing trade):

9 Special case - death

We can not forbid this from happening, as we would break the game rules.
When player dies, and he is still trading, then the trade is closed automatically