Пример #1
0
        [NoResponseCache]         //we don't want to cache this, if they are removed from a guild then we want this reflected immediately or they may be taking in a guild chat they aren't apart of due to a race condition
        public async Task <IActionResult> GetCharacterMembershipGuildStatus([FromRoute(Name = "id")] int characterId,
                                                                            [NotNull][FromServices] IGuildCharacterMembershipRepository guildCharacterMembershipRepository)
        {
            if (guildCharacterMembershipRepository == null)
            {
                throw new ArgumentNullException(nameof(guildCharacterMembershipRepository));
            }

            //If guild membership repo doesn't have the character id as an entry then it means there is no guild associated with them.
            if (!(await guildCharacterMembershipRepository.ContainsAsync(characterId).ConfigureAwaitFalse()))
            {
                return(BuildFailedResponseModel(CharacterGuildMembershipStatusResponseCode.NoGuild));
            }

            //TODO: There is technically a race condition here. They could have just been kicked from a guild but the cached model may say they are in a guild
            //this could result in incredibly rare cases of a kicked member joining at the perfect moment who can talk in guild chat but no longer be in the guild
            ProjectVersionStage.AssertBeta();

            //Otherwise, they are in a guild
            try
            {
                return(BuildSuccessfulResponseModel(new CharacterGuildMembershipStatusResponse((await guildCharacterMembershipRepository.RetrieveAsync(characterId).ConfigureAwaitFalse()).GuildId)));
            }
            catch (Exception e)
            {
                if (Logger.IsEnabled(LogLevel.Error))
                {
                    Logger.LogError($"Encountered error in expected guild membership status request. CharacterId: {characterId} Reason: {e.Message}\n\nStack: {e.StackTrace}");
                }

                return(BuildFailedResponseModel(CharacterGuildMembershipStatusResponseCode.GeneralServerError));
            }
        }
Пример #2
0
        public async Task <IActionResult> GetCharacterGuildList([NotNull][FromServices] IGuildCharacterMembershipRepository guildCharacterMembershipRepository,
                                                                [FromServices] ISocialServiceToGameServiceClient socialToGameClient)
        {
            if (guildCharacterMembershipRepository == null)
            {
                throw new ArgumentNullException(nameof(guildCharacterMembershipRepository));
            }

            CharacterSessionDataResponse session = await socialToGameClient.GetCharacterSessionDataByAccount(ClaimsReader.GetAccountIdInt(User));

            if (!session.isSuccessful)
            {
                return(BuildFailedResponseModel(CharacterGuildMembershipStatusResponseCode.GeneralServerError));
            }

            //No guild check
            if (!await guildCharacterMembershipRepository.ContainsAsync(session.CharacterId))
            {
                return(BuildFailedResponseModel(CharacterGuildMembershipStatusResponseCode.NoGuild));
            }

            var playerGuildMembership = await guildCharacterMembershipRepository.RetrieveAsync(session.CharacterId);

            int[] roster = await guildCharacterMembershipRepository.GetEntireGuildRosterAsync(playerGuildMembership.GuildId);

            return(BuildSuccessfulResponseModel(new CharacterGuildListResponseModel(roster)));
        }
Пример #3
0
        public async Task <IActionResult> JoinGuildChat([FromServices] ICharacterSessionRepository characterSessionRepository,
                                                        [FromServices] IFactoryCreatable <VivoxTokenClaims, VivoxTokenClaimsCreationContext> claimsFactory,
                                                        [FromServices] IGuildCharacterMembershipRepository guildMembershipRepository,
                                                        [FromServices] IVivoxTokenSignService signService)
        {
            int accountId = this.ClaimsReader.GetAccountIdInt(User);

            //If the user doesn't actually have a claimed session in the game
            //then we shouldn't log them into Vivox.
            if (!await characterSessionRepository.AccountHasActiveSession(accountId))
            {
                return(BuildFailedResponseModel(VivoxLoginResponseCode.NoActiveCharacterSession));
            }

            int characterId = await RetrieveSessionCharacterIdAsync(characterSessionRepository, accountId);

            if (!await guildMembershipRepository.ContainsAsync(characterId))
            {
                return(BuildFailedResponseModel(VivoxLoginResponseCode.ChannelUnavailable));
            }

            int guildId = (await guildMembershipRepository.RetrieveAsync(characterId)).GuildId;

            //TODO: Use a factory for channel name generation maybe?
            VivoxTokenClaims claims = claimsFactory.Create(new VivoxTokenClaimsCreationContext(characterId, VivoxAction.JoinChannel, new VivoxChannelData(false, $"Guild-{guildId}")));

            //We don't send it back in a JSON form even though it's technically a JSON object
            //because the client just needs it as a raw string anyway to put through the Vivox client API.
            return(BuildSuccessfulResponseModel(new VivoxChannelJoinResponse(signService.CreateSignature(claims), claims.DestinationSIPURI)));
        }