question

dgupta avatar image
dgupta asked

AcceptTrade always giving timeout error

Im trying to make it so that players can gift items to other players. It seems very simple, but it does not work no matter what I do. I keep getting a trade timeout error. Is it because my item has a lot of custom data in it?

I log the trade ids, and I know that the correct trade is being accepted and everything. But the trade is givining a timeout error anyway.

Anyway, here is my code:

//Gives the item to a friend and the trade id is stored in the shared group data for the friend
 public void GiveItemToFriend(string friendID, ItemInstance item, System.Action<string> onError, System.Action onResolution) {
        if(_friendStartedTradeIds.ContainsKey(friendID))
        {
            onError("The player hasn't accepted the previous sword you gave him yet!");
            return;
        }


        if(item.CustomData.ContainsKey("Player Gifted"))
        {
            onError("You can't regift a sword!");
            return;
        }
        
        PlayFabClientAPI.ExecuteCloudScript(new ExecuteCloudScriptRequest() {FunctionName = "TooManyItems", FunctionParameter = new {ID = friendID}}, 
            (res) => {
                 PlayFabUtiltyMethods.PrintExecuteScriptError(res);
                if(res.FunctionResult.ToString() == "True") {
                    onError("Your friend already has too many items!");
                }
                else {
                    OpenTradeRequest open = new OpenTradeRequest() {
                        OfferedInventoryInstanceIds = new List<string>() {item.ItemInstanceId},
                        AllowedPlayerIds = new List<string>{friendID}
                    };
                    
                    PlayFabClientAPI.OpenTrade(open, (oRes) => {
                        Debug.Log("Trade id is: " + oRes.Trade.TradeId);
                        UpdateGroupWithTradeID(oRes.Trade.TradeId, friendID, onResolution);
                    }, (err) => { Debug.LogError(err.ErrorMessage); onError("Error: " + err.ErrorMessage); });
             }          
        }, (err) => { Debug.LogError(err.ErrorMessage); onError("Error: " + err.ErrorMessage); });
    }

//Copde to update the group trade id data
 void UpdateGroupWithTradeID(string tradeID, string friendID, System.Action OnDone) {
        UpdateSharedGroupDataRequest uSG = new UpdateSharedGroupDataRequest() {
            SharedGroupId = friendID,
            Data = new Dictionary<string, string>() {
                {LogInManager.PlayFabID + " Trade", tradeID}},
            Permission = UserDataPermission.Public
        };
        PlayFabClientAPI.UpdateSharedGroupData(uSG, (res) => {OnDone(); }, (error) => {Debug.LogError(error.ErrorMessage);});
    }


//Accept item from player (gives a timeout error)
 public void AcceptItemFromFriend(string friendID, System.Action onAccepted, System.Action<string> onError) {
            Debug.Log("Trade id: " + _friendStartedTradeIds[friendID]);
            AcceptTradeRequest accept = new AcceptTradeRequest()
            {
                OfferingPlayerId = friendID,
                TradeId = _friendStartedTradeIds[friendID]
            };
            PlayFabClientAPI.AcceptTrade(accept, (res) => {
                ExecuteCloudScriptRequest tradeA = new ExecuteCloudScriptRequest()
                {
                    FunctionName = "AcceptedSwordFromPlayer",
                    FunctionParameter = new { FriendID = friendID, SwordID = res.Trade.AcceptedInventoryInstanceIds[0] }
                };
                PlayFabClientAPI.ExecuteCloudScript(tradeA, (sRes) => {
                    PlayFabUtiltyMethods.PrintExecuteScriptError(sRes);
                    RemoveTradeIds(friendID, _friendStartedTradeIds[friendID]);
                    onAccepted();
                }, (error) => { Debug.LogError(error.ErrorMessage); onError(error.ErrorMessage); });
            }, (err) => { Debug.LogError("Error: " + err.ErrorMessage); onError(err.ErrorMessage); });
        }, () => { onError("You have too many swords right now! Sell some to accept this sword!");     
    }






Trading
1 comment
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

dgupta avatar image dgupta commented ·

Also, when I try to cancel the trade with the same trade id, it returns the error "TradeDoesNotExist" which makes no sense since AcceptTrade doesn't return this error.

0 Likes 0 ·
brendan avatar image
brendan answered

For your test, can you please specify:

Title ID

Trade ID

PlayFab IDs for both the offering and accepting players

Item ID(s) in the trade

Which call is timing out, and any specific error details returned.

8 comments
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

dgupta avatar image dgupta commented ·

Yup!

Title ID: 277C

Trade ID: 9A13EB7B8A0B7DE1

Offering Player Playfab ID: 5DF2AB46B01B68B6

Accepting Player Playfab ID: 85E6FB9C2566C6B9

Only one item instance id: 53A073E8EE32EC3B

(The instance id shows revoked in playfab, I'm assuming this is normal.)

The call that's timing out is PlayFabClientAPI.AcceptTrade()

Specifically, this code:

   PlayFabClientAPI.AcceptTrade(accept,(res) => { //Code doesnt get here},
(error) => { Debug.LogError(error.ErrorMessage);
//Logs TradeWaitForStatusTimeout
});

The only error I get is: TradeWaitForStatusTimeout. I tried to log error details already, and they are null.

0 Likes 0 ·
dgupta avatar image dgupta commented ·

Ok well it doesn't seem to be working, so I think I'll just make something to gift the item myself with cloudscript.

0 Likes 0 ·
brendan avatar image brendan dgupta commented ·

Thanks - I have indeed reproduced the issue you're seeing. It looks like if you are not asking for any items back in the trade (so, a "gift"), the trade isn't being finalized. This is clearly a regression, so I've opened a bug to get it fixed as soon as possible. But just so you know, trades where the person offering the item wants something in return are unaffected - they still work fine.

0 Likes 0 ·
dgupta avatar image dgupta brendan commented ·

Ok, I guess I can make a dummy item like gift or something thats traded and if the traded user doesnt have it its added to the inventory automatically. Thanks!

0 Likes 0 ·
Show more comments
01markbryant01 avatar image 01markbryant01 commented ·

Hello. I´m making a Trade System to my game. I open a trade and it state is "Open", of course. Later, when I try to Accept the trade I get this error: "TradeWaitForStatusTimeout". I get the state of the trades and I see that all my trades are in "Accepting" state after I accept them, maybe for that reason is the error. How to make the trade as accepted? Or maybe my error is other. All my trades are gift. Thanks in advance.

0 Likes 0 ·
brendan avatar image brendan 01markbryant01 commented ·

Can you please provide the specifics for your test - what is the Title ID, what are the PlayFab IDs, and what are the details of the trades being set up? Also, do you mind if we make a player in your title to test the repro?

0 Likes 0 ·
01markbryant01 avatar image
01markbryant01 answered

Ok, no problem. These are the specifics of one of my trades:

Title ID: BB3C

Trade ID: 99871A836C066CBF

Offering Player PlayFab ID: 9B639F7A11D05ED4

Accepting Player PlayFab ID: DD108DBAA7DF11FA

Only one item, the instance ID is: EAC2668625E74ECD

The order of operations is this:

1. First, player offering create the trade. This is the code:

//For now all my trades are to any player (playersPlayFabIds = null)

public void OpenTrade(List<string> itemsInstanceId, List<string> playersPlayFabIds = null)

{

var request = new OpenTradeRequest

{

AllowedPlayerIds = playersPlayFabIds,

OfferedInventoryInstanceIds = itemsInstanceId

};

PlayFabClientAPI.OpenTrade(request, HandleTradeSuccess, HandleTradeError);

}

2. Later the trade is accepted. This is not inmediatly. It´s when a player wants to accept the trade. This is the code:

/*Here, in HandleAcceptTradeError, I get TradeWaitForStatusTimeout, and if I get the trade state is "Accepting". */

public void AcceptTrade(string playerOfferingPlayFabId, string tradeId)

{

var request = new AcceptTradeRequest

{

OfferingPlayerId = playerOfferingPlayFabId, TradeId = tradeId

};

PlayFabClientAPI.AcceptTrade(request, HandleAcceptTradeSuccess,HandleAcceptTradeError);

}


You can make a player in my title to test, no problem. Thanks

2 comments
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

brendan avatar image brendan commented ·

Can you try removing AllowedPlayerIds from the call (or put adding it to the request in an if statement where you check that the list is non-zero)? My concern is that because of the way that's constructed, what's actually being passed in is

AllowedPlayerIds = []

Which does cause issues with trades right now - we have a bug open on that, which we'll be fixing as soon as we can.

0 Likes 0 ·
01markbryant01 avatar image 01markbryant01 commented ·

I got the same error (TradeWaitForStatusTimeout) when I try to Accept a trade, and the status of all my trades is "Accepting". Now my code to create a trade is this:

public void OpenTrade(List<string> itemsInstanceId, List<string> playersPlayFabIds)
    {
        var request = new OpenTradeRequest();
        if (playersPlayFabIds != null)
            request.AllowedPlayerIds = playersPlayFabIds;
        request.OfferedInventoryInstanceIds = itemsInstanceId;


        PlayFabClientAPI.OpenTrade(request, HandleTradeSuccess, HandleTradeError);
    }
0 Likes 0 ·
01markbryant01 avatar image
01markbryant01 answered

I got the same error (TradeWaitForStatusTimeout) when I try to Accept a trade, and the status of all my trades is "Accepting". Now my code to create a trade is this:

public void OpenTrade(List<string> itemsInstanceId, List<string> playersPlayFabIds)
    {
        var request = new OpenTradeRequest();
        if (playersPlayFabIds != null)
            request.AllowedPlayerIds = playersPlayFabIds;
        request.OfferedInventoryInstanceIds = itemsInstanceId;


        PlayFabClientAPI.OpenTrade(request, HandleTradeSuccess, HandleTradeError);
    }
1 comment
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

brendan avatar image brendan commented ·

Can you put a breakpoint in on the OpenTrade call, and send me the specifics of the details of the request as it is being passed in?

0 Likes 0 ·
01markbryant01 avatar image
01markbryant01 answered

Hello Here I send you a more detailed information about Open and Accept trade. I hope this help you. First, I open the trade using the next function. I put "Debug.Log" to print the data that I´m using. I show you the result.

public void OpenTrade(List<string> itemsInstanceId, List<string> playersPlayFabIds)
    {
        var request = new OpenTradeRequest();
        if (playersPlayFabIds != null)
            request.AllowedPlayerIds = playersPlayFabIds;
        request.OfferedInventoryInstanceIds = itemsInstanceId;

        Debug.Log("AllowedPlayerIds: " + request.AllowedPlayerIds);
        for (int i = 0; i < request.OfferedInventoryInstanceIds.Count; i++)
            Debug.Log("OfferedInventoryInstanceIds: " + request.OfferedInventoryInstanceIds[i]);

        PlayFabClientAPI.OpenTrade(request, HandleTradeSuccess, HandleTradeError);
    }

The logs are:

"AllowedPlayerIds: "

"OfferedInventoryInstanceIds: AD0A46AFCBF3E4A8" (it´s only one item)

Now I get the response in the next function (HandleTradeSuccess). Look Debug.Log with the result. You can see that in this moment the status of the trade is "Open".

private void HandleTradeSuccess(OpenTradeResponse response)
    {
        Debug.Log("Trade ID: " + response.Trade.TradeId);
        for (int i = 0; i < response.Trade.OfferedInventoryInstanceIds.Count; i++)
            Debug.Log("OfferedInventoryInstanceIds: " + response.Trade.OfferedInventoryInstanceIds[i]);
        Debug.Log("AllowedPlayerIds: " + response.Trade.AllowedPlayerIds);
        Debug.Log("Status: " + response.Trade.Status);
    }

The logs are:

"Trade ID: D4001B3668D9C6E4"

"OfferedInventoryInstanceIds: AD0A46AFCBF3E4A8"

"AllowedPlayerIds: "

"Status: Open"

Later I accept the trade with other player, and the next function show the call with logs.

public void AcceptTrade(string playerOfferingPlayFabId, string tradeId)
    {
        var request = new AcceptTradeRequest
        {
            OfferingPlayerId = playerOfferingPlayFabId,
            TradeId = tradeId
        };
        Debug.Log("OfferingPlayerId: " + request.OfferingPlayerId);
        Debug.Log("TradeId: " + request.TradeId);
        PlayFabClientAPI.AcceptTrade(request, HandleAcceptTradeSuccess, HandleAcceptTradeError);
    }

The logs are:

"OfferingPlayerId: 9B639F7A11D05ED4"

"TradeId: D4001B3668D9C6E4"

The response of AcceptTrade function is the error TradeWaitForStatusTimeOut, in HandleAcceptTradeError. In this point, I got the status of the trade, and the status is "Accepting". Always it happen.

1 comment
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

brendan avatar image brendan commented ·

After playing around with this for a bit, I think I have the answer. It looks like if you create the trade with the RequestedCatalogItemIds set to null, that does cause this issue. If you set it to an empty list/array, the trade works fine. I'll get a bug opened on this to get that fixed as soon as possible, but that'll get you unblocked for now.

0 Likes 0 ·

Write an Answer

Hint: Notify or tag a user in this post by typing @username.

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.