Пример #1
0
        public static async Task <WinCheckResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequestMessage entityRequest, HttpRequest httpRequest,
            ILogger log)
        {
            // Extract the context from the incoming request
            var context = await FunctionContext <PlayFabIdRequest> .Create(entityRequest);

            string playFabId = context.FunctionArgument.PlayFabId;

            Settings.TrySetSecretKey(context.ApiSettings);
            Settings.TrySetCloudName(context.ApiSettings);

            // Grab the current player's game state
            var state = await GameStateUtil.GetCurrentGameState(playFabId, context.ApiSettings, context.AuthenticationContext);

            var winCheckResult = WinCheckUtil.Check(state);

            if (winCheckResult.Winner != GameWinnerType.NONE)
            {
                // Update the leaderboard accordingly
                await LeaderboardUtils.UpdateLeaderboard(playFabId, winCheckResult.Winner);

                // Store the game history
                await GameStateUtil.AddGameStateHistory(state, playFabId, context.ApiSettings, context.AuthenticationContext);

                // Clear the current game state
                await GameStateUtil.UpdateCurrentGameState(new TicTacToeState(), playFabId, context.ApiSettings, context.AuthenticationContext);
            }



            return(winCheckResult);
        }
Пример #2
0
        public static async Task <TicTacToeSharedGroupData> Run(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequestMessage req)
        {
            var context = await FunctionContext <GetSharedGroupRequest> .Create(req);

            return(await SharedGroupDataUtil.GetAsync(context.AuthenticationContext, context.FunctionArgument.SharedGroupId));
        }
Пример #3
0
        public static async Task <dynamic> MakeHTTPRequest(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequestMessage req, ILogger log)
        {
            /* Create the function execution's context through the request */
            var context = await FunctionContext <dynamic> .Create(req);

            var args = context.FunctionArgument;

            /* Prepare the body, headers, and url of the external HTTP request */
            dynamic body = new
            {
                input  = args,
                userId = context.CurrentPlayerId,
                mode   = "foobar"
            };
            var requestContent = new StringContent(PlayFabSimpleJson.SerializeObject(body));

            requestContent.Headers.Add("X-MyCustomHeader", "Some Value");
            requestContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
            var url = "http://httpbin.org/status/200";

            /* Execute the HTTP request using a simple HttpClient */
            using (var client = new HttpClient())
            {
                using (var httpResponseMessage =
                           await client.PostAsync(url, requestContent))
                {
                    using (var responseContent = httpResponseMessage.Content)
                    {
                        return(await responseContent.ReadAsAsync <dynamic>());
                    }
                }
            }
        }
Пример #4
0
        public static async Task <GameState> Run(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequestMessage req)
        {
            var context = await FunctionContext <StartMatchRequest> .Create(req);

            return(await GameStateUtil.InitializeAsync(context.AuthenticationContext, context.FunctionArgument.SharedGroupId));
        }
Пример #5
0
        public static async Task <ResponseWrapper <SetMatchLobbyLockStateResponse> > Run(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequestMessage req,
            [CosmosDB(ConnectionStringSetting = "PlayFabTicTacToeCosmosDB")] DocumentClient cosmosDBClient)
        {
            var context = await FunctionContext <SetMatchLobbyLockStateRequest> .Create(req);

            var matchLobbyId = context.FunctionArgument.MatchLobbyId;
            var locked       = context.FunctionArgument.Locked;
            var creatorId    = context.CallerEntityProfile.Entity.Id;

            try
            {
                var matchLobby = await MatchLobbyUtil.SetMatchLobbyLockState(matchLobbyId, locked, creatorId, cosmosDBClient);

                return(new ResponseWrapper <SetMatchLobbyLockStateResponse> {
                    StatusCode = StatusCode.OK, Response = new SetMatchLobbyLockStateResponse {
                        MatchLobby = matchLobby
                    }
                });
            }
            catch (TicTacToeException exception)
            {
                return(TicTacToeExceptionUtil.GetEmptyResponseWrapperFromException <SetMatchLobbyLockStateResponse>(exception));
            }
        }
Пример #6
0
        public static async Task<TicTacToeMove> MakeMinimaxAIMove(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequestMessage req,
            ILogger log)
        {
            var context = await FunctionContext<PlayFabIdRequest>.Create(req);

            Settings.TrySetSecretKey(context.ApiSettings);
            Settings.TrySetCloudName(context.ApiSettings);

            var playFabId = context.FunctionArgument.PlayFabId;

            // Attempt to load the Player's game state
            var state = await GameStateUtil.GetCurrentGameState(playFabId, context.ApiSettings, context.AuthenticationContext);

            // Look for a minimax AI move to make
            var aiMove = TicTacToeAI.GetNextMinimaxMove(state);

            // Store the AI move on the current game state
            var oneDimMoveIndex = aiMove.row * 3 + aiMove.col;
            state.Data[oneDimMoveIndex] = (int) OccupantType.AI;
            await GameStateUtil.UpdateCurrentGameState(state, playFabId, context.ApiSettings, context.AuthenticationContext);

            // Respond with the AI move
            return aiMove;
        }
Пример #7
0
        public static async Task <dynamic> MakeApiCall(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequestMessage req, ILogger log)
        {
            /* Create the function execution's context through the request */
            var context = await FunctionContext <dynamic> .Create(req);

            var args = context.FunctionArgument;

            /* Create the request object through the SDK models */
            var request = new UpdatePlayerStatisticsRequest
            {
                PlayFabId  = context.CurrentPlayerId,
                Statistics = new List <StatisticUpdate>
                {
                    new StatisticUpdate
                    {
                        StatisticName = "Level",
                        Value         = 2
                    }
                }
            };
            /* Use the ApiSettings and AuthenticationContext provided to the function as context for making API calls. */
            var serverApi = new PlayFabServerInstanceAPI(context.ApiSettings, context.AuthenticationContext);

            /* The PlayFabServerAPI SDK methods provide means of making HTTP request to the PlayFab Main Server without any
             * extra code needed to issue the HTTP requests. */
            return(await serverApi.UpdatePlayerStatisticsAsync(request));
        }
        public static async Task <TicTacToeSharedGroupData> Run(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequestMessage req,
            ILogger log)
        {
            var context = await FunctionContext <CreateSharedGroupRequest> .Create(req);

            // We have to use the MasterPlayerAccountId instead of the TitlePlayerAccountId to avoid errors during its addition as member of SGD
            var playerOne = context.CallerEntityProfile.Lineage.MasterPlayerAccountId;

            var sgdResponse = await SharedGroupDataUtil.CreateAsync(context.AuthenticationContext, context.FunctionArgument.SharedGroupId);

            await SharedGroupDataUtil.AddMembersAsync(context.AuthenticationContext, context.FunctionArgument.SharedGroupId, new List <string> {
                playerOne
            });

            var sharedGroupData = new TicTacToeSharedGroupData
            {
                SharedGroupId = sgdResponse.SharedGroupId,
                Match         = new Match {
                    PlayerOneId = playerOne
                }
            };

            return(await SharedGroupDataUtil.UpdateAsync(context.AuthenticationContext, sharedGroupData));
        }
Пример #9
0
        public static async Task <ResponseWrapper <JoinMatchLobbyResponse> > Run(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequestMessage req,
            [CosmosDB(ConnectionStringSetting = "PlayFabTicTacToeCosmosDB")] DocumentClient cosmosDBClient)
        {
            var context = await FunctionContext <JoinMatchLobbyRequest> .Create(req);

            var matchLobbyId   = context.FunctionArgument.MatchLobbyId;
            var invitationCode = context.FunctionArgument.InvitationCode;
            var playerTwo      = context.CallerEntityProfile.Entity.Id;

            try
            {
                var matchLobby = await MatchLobbyUtil.JoinMatchLobby(matchLobbyId, playerTwo, cosmosDBClient, invitationCode);

                return(new ResponseWrapper <JoinMatchLobbyResponse> {
                    StatusCode = StatusCode.OK, Response = new JoinMatchLobbyResponse {
                        NetworkId = matchLobby.NetworkId
                    }
                });
            }
            catch (TicTacToeException exception)
            {
                return(TicTacToeExceptionUtil.GetEmptyResponseWrapperFromException <JoinMatchLobbyResponse>(exception));
            }
        }
Пример #10
0
        public static async Task Run(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequestMessage req
            )
        {
            var context = await FunctionContext <DeleteSharedGroupRequest> .Create(req);

            var request = context.FunctionArgument;

            await SharedGroupDataUtil.DeleteAsync(context.AuthenticationContext, request.SharedGroupId);
        }
Пример #11
0
        public static async Task <GameState> Run(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequestMessage req,
            ILogger log)
        {
            var context = await FunctionContext <SetGameWinnerRequest> .Create(req);

            var gameWinnerRequest = context.FunctionArgument;

            return(await GameStateUtil.UpdateWinnerAsync(context.AuthenticationContext, gameWinnerRequest.PlayerId, gameWinnerRequest.SharedGroupId));
        }
Пример #12
0
        public static async Task <TicTacToeSharedGroupData> Run(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequestMessage req)
        {
            var context = await FunctionContext <JoinMatchRequest> .Create(req);

            var playerId = context.CallerEntityProfile.Lineage.MasterPlayerAccountId;

            await SharedGroupDataUtil.AddMembersAsync(context.AuthenticationContext, context.FunctionArgument.SharedGroupId, new List <string> {
                playerId
            });

            return(await MatchUtil.AddMember(context.AuthenticationContext, context.FunctionArgument.SharedGroupId, playerId));
        }
Пример #13
0
        public static async Task <dynamic> LevelCompleted(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequestMessage req, ILogger log)
        {
            /* Create the function execution's context through the request */
            var context = await FunctionContext <dynamic> .Create(req);

            var args = context.FunctionArgument;

            var level          = args["levelName"];
            var monstersKilled = (int)args["monstersKilled"];

            var updateUserInternalDataRequest = new UpdateUserInternalDataRequest
            {
                PlayFabId = context.CurrentPlayerId,
                Data      = new Dictionary <string, string>
                {
                    { "lastLevelCompleted", level }
                }
            };

            /* Use the ApiSettings and AuthenticationContext provided to the function as context for making API calls. */
            var serverApi = new PlayFabServerInstanceAPI(context.ApiSettings, context.AuthenticationContext);
            /* Execute the Server API request */
            var updateUserDataResult = await serverApi.UpdateUserInternalDataAsync(updateUserInternalDataRequest);

            log.LogDebug($"Set lastLevelCompleted for player {context.CurrentPlayerId} to {level}");

            var updateStatRequest = new UpdatePlayerStatisticsRequest
            {
                PlayFabId  = context.CurrentPlayerId,
                Statistics = new List <StatisticUpdate>
                {
                    new StatisticUpdate
                    {
                        StatisticName = "level_monster_kills",
                        Value         = monstersKilled
                    }
                }
            };

            /* Execute the server API request */
            var updateStatResult = await serverApi.UpdatePlayerStatisticsAsync(updateStatRequest);

            log.LogDebug($"Updated level_monster_kills stat for player {context.CurrentPlayerId} to {monstersKilled}");

            return(new
            {
                updateStatResult.Result
            });
        }
Пример #14
0
        public static async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequestMessage req,
            [CosmosDB(ConnectionStringSetting = "PlayFabTicTacToeCosmosDB")] DocumentClient cosmosDBClient)
        {
            var context = await FunctionContext <DeleteMatchLobbyInfoRequest> .Create(req);

            var matchLobbyRequest = context.FunctionArgument;

            Settings.TrySetSecretKey(context.ApiSettings);
            Settings.TrySetCloudName(context.ApiSettings);

            await MatchLobbyUtil.DeleteMatchLobbyFromDDBBAsync(cosmosDBClient, matchLobbyRequest.Id, matchLobbyRequest.MatchLobbyId);

            return(new OkObjectResult(matchLobbyRequest));
        }
Пример #15
0
        public static async Task <TicTacToeSharedGroupData> Run(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequestMessage req,
            [CosmosDB(
                 databaseName: Constants.DATABASE_NAME,
                 collectionName: Constants.MATCH_LOBBY_TABLE_NAME,
                 ConnectionStringSetting = "PlayFabTicTacToeCosmosDB")]
            IAsyncCollector <MatchLobby> matchlobbyCollection
            )
        {
            var context = await FunctionContext <CreateMatchLobbyRequest> .Create(req);

            var playerOne = context.CallerEntityProfile.Lineage.MasterPlayerAccountId;

            return(await MatchLobbyUtil.CreateMatchLobby(context.AuthenticationContext, context.FunctionArgument.SharedGroupId, playerOne, matchlobbyCollection));;
        }
Пример #16
0
        public static async Task <MatchLobby> Run(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequestMessage req,
            [CosmosDB(ConnectionStringSetting = "PlayFabTicTacToeCosmosDB")] DocumentClient cosmosDBClient,
            [CosmosDB(
                 databaseName: Constants.DatabaseName,
                 collectionName: Constants.MatchLobbyTableName,
                 ConnectionStringSetting = "PlayFabTicTacToeCosmosDB")]
            IAsyncCollector <MatchLobby> matchlobbyCollection)
        {
            var context = await FunctionContext <CreateMatchLobbyRequest> .Create(req);

            var args      = context.FunctionArgument;
            var creatorId = context.CallerEntityProfile.Entity.Id;

            return(await MatchLobbyUtil.CreateMatchLobby(args.MatchLobbyId, args.Locked, creatorId, args.NetworkId, matchlobbyCollection, cosmosDBClient));
        }
Пример #17
0
        public static async Task <Wrapper <MatchLobbyDTO> > Run(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequestMessage req,
            [CosmosDB(ConnectionStringSetting = "PlayFabTicTacToeCosmosDB")] DocumentClient cosmosDBClient)
        {
            var context = await FunctionContext <SearchMatchLobbiesRequest> .Create(req);

            var lobbyListRequest = context.FunctionArgument;

            var result = await MatchLobbyUtil.GetMatchLobbiesDTOAsync(
                cosmosDBClient,
                ExpressionUtils.GetSearchMatchLobbiesExpression(lobbyListRequest.SearchTerm));

            return(new Wrapper <MatchLobbyDTO>
            {
                Items = result
            });
        }
Пример #18
0
        public static async Task <MakeMultiplayerMoveResponse> Run(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequestMessage req,
            ILogger log)
        {
            var context = await FunctionContext <MakeMultiplayerMoveRequest> .Create(req);

            var playerMoveRequest = context.FunctionArgument;

            var updatedData = await GameStateUtil.MoveUpdateAsync(context.AuthenticationContext, playerMoveRequest.PlayerId, playerMoveRequest.PlayerMove, playerMoveRequest.SharedGroupId);

            return(new MakeMultiplayerMoveResponse
            {
                GameState = updatedData,
                PlayerMoveResult = new MakePlayerMoveResponse {
                    Valid = updatedData != null
                }
            });
        }
Пример #19
0
        public static async Task <dynamic> UpdatePlayerMove(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequestMessage req, ILogger log)
        {
            /* Create the function execution's context through the request */
            var context = await FunctionContext <dynamic> .Create(req);

            var args = context.FunctionArgument;

            /* Use the ApiSettings and AuthenticationContext provided to the function as context for making API calls. */
            var serverApi = new PlayFabServerInstanceAPI(context.ApiSettings, context.AuthenticationContext);

            bool validMove = await ProcessPlayerMove(serverApi, args["playerMove"], context.CurrentPlayerId, log);

            return(new
            {
                ValidMove = validMove
            });
        }
Пример #20
0
        public static async Task <MatchLobby> Run(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequestMessage req,
            [CosmosDB(ConnectionStringSetting = "PlayFabTicTacToeCosmosDB")] DocumentClient cosmosDBClient)
        {
            var context = await FunctionContext <LeaveMatchLobbyRequest> .Create(req);

            var matchLobbyId = context.FunctionArgument.MatchLobbyId;

            var matchLobby = await MatchLobbyUtil.GetMatchLobbyAsync(
                cosmosDBClient,
                (document) => document.MatchLobbyId == matchLobbyId);

            if (matchLobby == null)
            {
                throw new Exception("Match Lobby not found");
            }

            return(await MatchLobbyUtil.LeaveMatchLobby(matchLobby, cosmosDBClient));
        }
Пример #21
0
        public static async Task <dynamic> MakeEntityApiCall(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequestMessage req, ILogger log)
        {
            /* Create the function execution's context through the request */
            var context = await FunctionContext <dynamic> .Create(req);

            var args = context.FunctionArgument;

            var entityProfile = context.CallerEntityProfile;

            var setObjectRequest = new SetObjectsRequest
            {
                Entity  = ClassConverter <ProfilesModels.EntityKey, DataModels.EntityKey> .Convert(entityProfile.Entity),
                Objects = new List <SetObject>
                {
                    new SetObject
                    {
                        ObjectName = "obj1",
                        DataObject = new
                        {
                            foo   = "some server computed value",
                            prop1 = args["prop1"]
                        }
                    }
                }
            };

            /* Use the ApiSettings and AuthenticationContext provided to the function as context for making API calls. */
            var dataApi = new PlayFabDataInstanceAPI(context.ApiSettings, context.AuthenticationContext);
            /* Execute the entity API request */
            var setObjectsResponse = await dataApi.SetObjectsAsync(setObjectRequest);

            var setObjectsResult = setObjectsResponse.Result.SetResults[0].SetResult;

            return(new
            {
                profile = entityProfile,
                setResult = setObjectsResult
            });
        }
Пример #22
0
        public static async Task Run(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequestMessage req,
            ILogger log)
        {
            var context = await FunctionContext <PlayFabIdRequest> .Create(req);

            var playFabId = context.FunctionArgument.PlayFabId;

            Settings.TrySetSecretKey(context.ApiSettings);
            Settings.TrySetCloudName(context.ApiSettings);

            var newCurrentGameState = new TicTacToeState()
            {
                Data = new int[9]
            };

            await GameStateUtil.UpdateCurrentGameState(
                newCurrentGameState,
                playFabId,
                context.ApiSettings,
                context.AuthenticationContext);
        }
Пример #23
0
        public static async Task <MakePlayerMoveResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequestMessage req,
            ILogger log)
        {
            var context = await FunctionContext <MakePlayerMoveRequest> .Create(req);

            var move = context.FunctionArgument.Move;

            Settings.TrySetSecretKey(context.ApiSettings);
            Settings.TrySetCloudName(context.ApiSettings);

            var playFabId = context.FunctionArgument.PlayFabId;

            // Attempt to load the player's game state
            var state = await GameStateUtil.GetCurrentGameState(playFabId, context.ApiSettings, context.AuthenticationContext);

            var oneDimMoveIndex = move.row * 3 + move.col;

            // Move can only be made if spot was empty
            if (state.Data[oneDimMoveIndex] == (int)OccupantType.NONE)
            {
                state.Data[oneDimMoveIndex] = (int)OccupantType.PLAYER;
                await GameStateUtil.UpdateCurrentGameState(state, playFabId, context.ApiSettings, context.AuthenticationContext);

                return(new MakePlayerMoveResult()
                {
                    Valid = true
                });
            }
            // Move attempt was invalid
            else
            {
                return(new MakePlayerMoveResult()
                {
                    Valid = false
                });
            }
        }
Пример #24
0
        public static async Task <dynamic> HelloWorld(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequestMessage req, ILogger log)
        {
            /* Create the function execution's context through the request */
            var context = await FunctionContext <dynamic> .Create(req);

            var args = context.FunctionArgument;

            var message = $"Hello {context.CurrentPlayerId}!";

            log.LogInformation(message);

            dynamic inputValue = null;

            if (args != null && args["inputValue"] != null)
            {
                inputValue = args["inputValue"];
            }

            log.LogDebug($"HelloWorld: {new { input = inputValue} }");

            return(new { messageValue = message });
        }