示例#1
0
        public async Task <IActionResult> CreateCharacter([FromRoute] string name,
                                                          [FromServices][NotNull] IPlayfabCharacterClient playfabCharacterClient,
                                                          [FromServices][NotNull] ICharacterAppearanceRepository characterAppearanceRepository,
                                                          [FromServices][NotNull] ICharacterDataRepository characterDataRepository)
        {
            if (playfabCharacterClient == null)
            {
                throw new ArgumentNullException(nameof(playfabCharacterClient));
            }
            if (characterAppearanceRepository == null)
            {
                throw new ArgumentNullException(nameof(characterAppearanceRepository));
            }
            if (characterDataRepository == null)
            {
                throw new ArgumentNullException(nameof(characterDataRepository));
            }
            if (string.IsNullOrWhiteSpace(name))
            {
                throw new ArgumentException("Value cannot be null or whitespace.", nameof(name));
            }

            int accountId = ClaimsReader.GetAccountIdInt(User);

            bool nameIsAvailable = await ValidateNameAvailability(name);

            if (!nameIsAvailable)
            {
                return(BadRequest(new CharacterCreationResponse(CharacterCreationResponseCode.NameUnavailableError)));
            }

            string playfabId = ClaimsReader.GetPlayfabId(User);

            //Now, we actually need to create the character on PlayFab first. It's better to have an orphaned character on PlayFab
            //than to have a character without a PlayFab equivalent.
            PlayFabResultModel <GladMMOPlayFabGrantCharacterToUserResult> playFabResultModel = await playfabCharacterClient.GrantCharacterToUser(new GladMMOPlayFabGrantCharacterToUserRequest(name, "test", playfabId));

            //TODO: Better error handling
            if (playFabResultModel.ResultCode != HttpStatusCode.OK)
            {
                if (Logger.IsEnabled(LogLevel.Error))
                {
                    Logger.LogError($"PlayFab CharacterCreation Erorr: {playFabResultModel.ResultCode}:{playFabResultModel.ResultStatus}");
                }

                return(BadRequest(new CharacterCreationResponse(CharacterCreationResponseCode.GeneralServerError)));
            }

            CharacterEntryModel characterEntryModel = new CharacterEntryModel(accountId, name, playfabId, playFabResultModel.Data.CharacterId);

            //TODO: We need a transition around the creation of the below entries.
            ProjectVersionStage.AssertBeta();
            //TODO: Don't expose the database table model
            //Otherwise we should try to create. There is a race condition here that can cause it to still fail
            //since others could create a character with this name before we finish after checking
            bool result = await CharacterRepository.TryCreateAsync(characterEntryModel);

            //TODO: Also needs to be apart of the transaction
            if (result)
            {
                await characterDataRepository.TryCreateAsync(new CharacterDataModel(characterEntryModel.CharacterId, 0));

                await characterAppearanceRepository.TryCreateAsync(new CharacterAppearanceModel(characterEntryModel.CharacterId, 9));                 //Default is 9 right now.
            }

            return(Json(new CharacterCreationResponse(CharacterCreationResponseCode.Success)));
        }