question

e.timofeev@flexilestudio.com avatar image
e.timofeev@flexilestudio.com asked

script exrcution problem

Good day.

We has problem with our cloud script call.

Error 400: The script execution was terminated after the maximum execution time limit

This script exchange "Chest_Token" to "Chest_Container". Before grant container we are looking for Token in user inventory and check token parametr as "state" and "date_of_exchange". If all right we grant chest container and revoke token.

But script terminated near "Grant Chest and Revoke Token" part.

But we dont see problem point. Whether the problem is in count of inventory items? Or server.GrantItemsToUser take a lot of time if item "Is stackable"?

Script code:

handlers.grantChest = function (args) // args.ItemInstanceId - chest token item id
{
    //inventory
    var userInventory = server.GetUserInventory(
    {
        PlayFabId : currentPlayerId
    });
    var inventory = userInventory.Inventory;

    //find chest token
    var tokenItem = getInventoryItem(inventory, args.ItemInstanceId);
    if( tokenItem == null )
    {
        return { status : "ERROR", messageValue: "invalid chest item!" };
    }
    if( tokenItem.CustomData["State"] != CHEST_TOKEN_STATE_OPENING || Number( tokenItem.CustomData["OpenDate"] ) > Date.now() )
    {
        return { status : "ERROR", messageValue: "Chest timer NOT done!" };
    }
    // all right.
    //grant chest container
    return grantChestImplementation( tokenItem );
}


function grantChestImplementation( tokenItem  )
{
    //grant Chest to user
    var itemGrantResult = server.GrantItemsToUser(
    {
        CatalogVersion: "chests",
        PlayFabId: currentPlayerId,
        ItemIds:  [  tokenItem.CustomData["Chest"] ]
    });
    var chestItem = itemGrantResult.ItemGrantResults[0];

    //destroy token
    server.RevokeInventoryItem(
    {
        PlayFabId : currentPlayerId,
        ItemInstanceId : tokenItem.ItemInstanceId
    });
    return { status : "OK", messageValue: "All right!", ChestItemId : chestItem.ItemId, ChestCatalog : chestItem.CatalogVersion };
}
function getInventoryItem(arr,ItemInstanceId)
{
    for (var k = 0; k < arr.length ; k++)
    {
    if ( arr[k].ItemInstanceId == ItemInstanceId )
    {
        return arr[k];
    }
    }
    return null;
}

 

CloudScriptPlayer Inventory
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 answered

First, I would recommend putting a check that the item found is actually of type Chest_Token, so that a hacked client can't submit another item. Granted, your check for the custom data should prevent mis-use, but only if the logic for setting that custom data can't also be compromised. From my perspective, it's always better to have too many protections rather than not enough.

Now, for the timeout you're running into, can you let us know:

What Title ID are you testing? What PlayFabId are you using for the player? What is the item instance being passed into the call? How many inventory items does that player currently have?

It is the case that currently, very large inventories can cause a problem due to the amount of time spent processing through the inventory when adding items - the same is true of adding large numbers of items to an inventory (stackable or not). We are in the process of optimizing the inventory code to take care of both of those issues though, so you should see performance improve there in the coming weeks.

10 |1200

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

e.timofeev@flexilestudio.com avatar image
e.timofeev@flexilestudio.com answered

Thanks for answer.

 

Title ID: 6B9C

Engine: Unity 5.3.5f1

"What PlayFabId are you using for the player?" - this is not always. We observed it on this accounts:  B32EB7692629A7E2  AEC1DF7B045BC3F6  20090C742E753952  BFAD78A500783604  5271356ECDAB17C9  89B5ED227B0ADFBB  B4A83F03C8D7F38F

"What is the item instance being passed into the call?"  -  it's token instance. ItemID: "Chest_Token"

When I change chest container to "not stackable" this exeption was be more rarely.

 

Can you increase maximum execution time limit?

 

 

 

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 answered

Thanks, that was a big help. Looking at the player accounts, I do see the issue. This is currently a known performance issue with adding items to extremely large inventories, and expired/consumed/revoked items are still actually being counted as part of the inventory. We are in process on an update to address this issue. We'll post here when this update is live.

10 |1200

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

e.timofeev@flexilestudio.com avatar image
e.timofeev@flexilestudio.com answered

We allso have this trouble for chests what granted by timer.

It happens more often.

handlers.grantTimeChest = function (args)
{
    //first it's check can we grant chest or not
    var userData = server.GetUserReadOnlyData (
    {
        PlayFabId : currentPlayerId,
        Keys : ["NextTimeChest"]
    });
    if( Number( userData.Data["NextTimeChest"].Value ) > Date.now() )
    {
        return { status : "ERROR", messageValue: "Chest timer NOT done!", NextTimeChest : userData.Data["NextTimeChest"].Value };
    }
    // if we can
    // get chest id and cooldwon for next chest
    var titleData = server.GetTitleData(
    {
        Keys : ["TimeChestName","TimeChestCooldown"]
    });
    //grant TimeChest to user
    var itemGrantResult = server.GrantItemsToUser(
    {
        CatalogVersion: "chests",
        PlayFabId: currentPlayerId,
        ItemIds:  [ titleData.Data.TimeChestName ] 
    });
    var chestItem = itemGrantResult.ItemGrantResults[0];
    //update cooldown
    var newChestDate = setNextTimeChest(titleData);
    return { status : "OK", messageValue: "All right!", ChestItemId : chestItem.ItemId, ChestCatalog : chestItem.CatalogVersion, NextTimeChest : newChestDate  };
}

// titleData with "TimeChestCooldown"
function setNextTimeChest(titleData)
{
    var newChestDate = Date.now() + Number(titleData.Data.TimeChestCooldown)*1000;
    // set time for next chest
    var newUserData = server.UpdateUserReadOnlyData (
    {
        PlayFabId : currentPlayerId,
        Data: { "NextTimeChest" : newChestDate }
    });
    return newChestDate;
}

 

 

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 answered

I'm not seeing anything in the code which would cause this to occur more often. However, as I said, there is a known issue with adding items to players with extremely large inventories which we'll be rolling out a change for shortly. That said, if you can provide the PlayFab IDs for some players running into the issue with that script, we can have a look to confirm.

10 |1200

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

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.