question

dan avatar image
dan asked

Having trouble with CloudScript and server.GrantItemsToUsers

HI there,

I am seeing some weird behavior when trying to call server.GrantItemsToUsers with CloudScript.

To give you a little background, I am creating a turn-based multiplayer game, and am adding "game" to the players' inventories to keep track of the matches they have on the go. I have a Photon callback that adds these games on room creation.

The following code works beautifully....

//Create an array for the Item Grants
		var games = [];
		for(var i = 0; i < args.CreateOptions.ExpectedUsers.length; i++)
		{
			//var accepted = new Boolean(args.CreateOptions.ExpectedUsers[i]===args.UserId);
			games.push({
			    "PlayFabId": args.CreateOptions.ExpectedUsers[i],
			    "ItemId": "Game",			    
			    "Data": {
					"Sender": args.UserId,
					"GameID": args.GameId,
					"Players": args.CreateOptions.MaxPlayers.toString(),
					"PlayerIDs": args.CreateOptions.ExpectedUsers.toString(),
					"GameOver": false.toString()
				}			
			})
		}


		//For Debugging purposes
		server.SetTitleData({
			Key: "Games",
			Value: JSON.stringify(games)
		});
		
		//Send the games
		server.GrantItemsToUsers({
			"CatalogVersion": "RFI",
			"ItemGrants": games
		});	

Giving me the following JSON data for the itemGrants...

[
  {
    "PlayFabId": "59FCE1AD1A872162",
    "ItemId": "Game",
    "Data": {
      "Sender": "59FCE1AD1A872162",
      "GameID": "262334043389",
      "Players": "2",
      "PlayerIDs": "59FCE1AD1A872162,2B4680FC09C32C7",
      "GameOver": "false"
    }
  },
  {
    "PlayFabId": "2B4680FC09C32C7",
    "ItemId": "Game",
    "Data": {
      "Sender": "59FCE1AD1A872162",
      "GameID": "262334043389",
      "Players": "2",
      "PlayerIDs": "59FCE1AD1A872162,2B4680FC09C32C7",
      "GameOver": "false"
    }
  }
]

However, if I try and add any more keys, the function stops working. For example, the code below contains one extra data key, ResultSeen...

		//Create an array for the Item Grants
		var games = [];
		for(var i = 0; i < args.CreateOptions.ExpectedUsers.length; i++)
		{
			//var accepted = new Boolean(args.CreateOptions.ExpectedUsers[i]===args.UserId);
			games.push({
			    "PlayFabId": args.CreateOptions.ExpectedUsers[i],
			    "ItemId": "Game",			    
			    "Data": {
					"Sender": args.UserId,
					"GameID": args.GameId,
					"Players": args.CreateOptions.MaxPlayers.toString(),
					"PlayerIDs": args.CreateOptions.ExpectedUsers.toString(),
					"GameOver": false.toString(),
					"ResultSeen": false.toString()
				}			
			})
		}


		//For Debugging purposes
		server.SetTitleData({
			Key: "Games",
			Value: JSON.stringify(games)
		});
		
		//Send the games
		server.GrantItemsToUsers({
			"CatalogVersion": "RFI",
			"ItemGrants": games
		});

...and produces the following JSON data, all well and good...

[
  {
    "PlayFabId": "59FCE1AD1A872162",
    "ItemId": "Game",
    "Data": {
      "Sender": "59FCE1AD1A872162",
      "GameID": "262337976668",
      "Players": "2",
      "PlayerIDs": "59FCE1AD1A872162,2B4680FC09C32C7",
      "GameOver": "false",
      "ResultSeen": "false"
    }
  },
  {
    "PlayFabId": "2B4680FC09C32C7",
    "ItemId": "Game",
    "Data": {
      "Sender": "59FCE1AD1A872162",
      "GameID": "262337976668",
      "Players": "2",
      "PlayerIDs": "59FCE1AD1A872162,2B4680FC09C32C7",
      "GameOver": "false",
      "ResultSeen": "false"
    }
  }
]

...but the room fails to initialise, throwing up the following warning in Unity...

Operation 227 failed in a server-side plugin.Check the configuration in the Dashboard. Message from server-plugin: Failed to create game on https://B433.playfablogic.com/webhook/1/prod/7EXAQPX4BWIK11YN6N8TUGD6O3CN6594C4AZFFBFMFYUFRYRBO/RoomCreated? : Error response ResultCode='4' Message='PlayFabAPIError InvalidParams: Invalid input parameters at __playfab_internal_v1.server_request (Script Document:36:13) -> throw apiResult; at server.GrantItemsToUsers (Script Document:554:74) at handlers.RoomCreated (B433-main.js:135:10) at __playfab_internal_v1.invokeHandler (Script Document:20:22)'. UnityEngine.Debug:LogError(Object) NetworkingPeer:OnOperationResponse(OperationResponse) (at Assets/Photon Unity Networking/Plugins/PhotonNetwork/NetworkingPeer.cs:1559) ExitGames.Client.Photon.PeerBase:DeserializeMessageAndCallback(Byte[]) ExitGames.Client.Photon.EnetPeer:DispatchIncomingCommands() ExitGames.Client.Photon.PhotonPeer:DispatchIncomingCommands() PhotonHandler:Update() (at Assets/Photon Unity Networking/Plugins/PhotonNetwork/PhotonHandler.cs:157)

Does anyone have any idea what I am doing wrong? This is driving me nuts!

Thanks in advance for your help!

Cheers,
Dan

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.

1 Answer

·
brendan avatar image
brendan answered

The issue is that inventory item instances can only have 5 Key/Value pairs in custom data. Custom data has to be fairly limited in item instances, as a player could have thousands of items, depending on the title's tier.

4 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.

dan avatar image dan commented ·

Thanks for the info - that's super good to know! I had a sneaky suspicion that might have been the case...


You might want to add that information to...

a) The documentation for Server.Models.ItemGrant

b) The error message thrown up by adding too many keys.

c) The back end UI, where it is actually possible to add multiple keys.

d) All of the above

:)

0 Likes 0 ·
brendan avatar image brendan dan commented ·

Yes, I've filed a bug to get make that clearer, no worries. :)

1 Like 1 ·
brendan avatar image brendan brendan commented ·

Oh, though I should point out that the error message actually does give you that data. If you return the full error message via a try/catch, or just call the API directly (via Postman, etc.), you'll see that the complete error response is:

{
    "code": 400,
    "status": "BadRequest",
    "error": "InvalidParams",
    "errorCode": 1000,
    "errorMessage": "Invalid input parameters",
    "errorDetails": {
        "Data": [
            "Too many keys specified in Data dictionary update. Limit is 5 and request contained 7."
        ]
    }
}

When you get an error in a Cloud Script though the exception returned can only contain the first part of that - best to use try/catch for debugging, so that you can get all the info.

1 Like 1 ·
dan avatar image dan commented ·

Thanks! JavaScript is not my specialty... that's good to know. :)

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.