/// <inheritdoc />
        protected override IRemoteSocialTextChatHubClient GetBroadcastGroup(IHubConnectionMessageContext <IRemoteSocialTextChatHubClient> context)
        {
            if (!GuildStatusMappable.ContainsKey(context.CallerGuid))
            {
                throw new InvalidOperationException($"Tried to send Guild Message for Entity: {context.CallerGuid} but no guild data was available.");
            }

            //TODO: We should have guild status model, including pending invites and such.
            if (!GuildStatusMappable[context.CallerGuid].isSuccessful)
            {
                //TODO: Log
            }

            return(context.Clients.Group($"guild:{GuildStatusMappable[context.CallerGuid].GuildId}"));
        }
        protected EntityAssociatedData <T> BuildForwardableAssociatedData <T>([JetBrains.Annotations.NotNull] IHubConnectionMessageContext context, [JetBrains.Annotations.NotNull] T envolpeContents)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }
            if (envolpeContents == null)
            {
                throw new ArgumentNullException(nameof(envolpeContents));
            }

            //TODO: We should cache somehow the identifier's int value, parsing it each time I think can be costly.
            NetworkEntityGuid guid = new NetworkEntityGuidBuilder()
                                     .WithId(int.Parse(context.HubConntext.UserIdentifier))
                                     .WithType(EntityType.Player)
                                     .Build();

            return(new EntityAssociatedData <T>(guid, envolpeContents));
        }
Beispiel #3
0
        /// <inheritdoc />
        protected override async Task OnMessageRecieved(IHubConnectionMessageContext <IRemoteSocialTextChatHubClient> context, TMessageType message)
        {
            //TODO: We may want to do validation for the message sent more than this
            if (message.TargetChannel != TargetChannel)
            {
                return;
            }

            //TODO: We need to check if zone messaging is even enabled for the connection. This could be a WEB ONLY connection.
            if (String.IsNullOrWhiteSpace(message.Message))
            {
                return;
            }

            TSendMessageType outgoingMessage = OutgoingMessageFactory.Create(new GenericChatMessageContext <TMessageType>(message, context));

            await SendOutgoingMessage(GetBroadcastGroup(context), outgoingMessage)
            .ConfigureAwait(false);
        }
Beispiel #4
0
        protected override async Task OnMessageRecieved(IHubConnectionMessageContext <IRemoteSocialHubClient> context, GuildMemberInviteRequestModel payload)
        {
            var nameQueryResponseTask = NameQueryService.RetrievePlayerGuidAsync(payload.MemberToInvite);

            //First we need to check if they're in a guild.
            //We don't really need to handle the response for this, since it should never really happen.
            var guildStatus = await SocialService.GetCharacterMembershipGuildStatus(context.CallerGuid.EntityId);

            if (!guildStatus.isSuccessful)
            {
                if (Logger.IsEnabled(LogLevel.Warning))
                {
                    Logger.LogWarning($"User: {context.CallerGuid} attempted to Invite: {payload.MemberToInvite} to a guild but was not apart of a guild.");
                }

                return;
            }

            //Now we should know what guild the caller is in due to the query.
            //Now we need to do a reverse namequery to get the guid of who they're attempting to invite.
            var nameQueryResponse = await nameQueryResponseTask;

            //If it's not successful, assume the user doesn't exist.
            if (!nameQueryResponse.isSuccessful)
            {
                await SendGuildInviteResponse(context, GuildMemberInviteResponseCode.PlayerNotFound, NetworkEntityGuid.Empty);

                return;
            }

            //Now check if the user is already guilded
            //If they are we should indicate that to the client.
            if (await CheckIfGuilded(nameQueryResponse.Result))
            {
                await SendGuildInviteResponse(context, GuildMemberInviteResponseCode.PlayerAlreadyInGuild, nameQueryResponse.Result);

                return;
            }

            //Ok, the reverse name query was successful. Check if there is a pending invite.
            //TODO: Right now we rely on local state to indicate if there is a pending invite. We need to NOT do that because it won't work when we scale out.
            ProjectVersionStage.AssertBeta();

            //TODO: There is a race condition if multiple invites are sent at the same time, should we care??
            //If they have a pending invite.
            if (PendingInviteData.ContainsKey(nameQueryResponse.Result))
            {
                //If NOT expired then we need to say they're currently pending an invite
                if (!PendingInviteData[nameQueryResponse.Result].isInviteExpired())
                {
                    await SendGuildInviteResponse(context, GuildMemberInviteResponseCode.PlayerAlreadyHasPendingInvite, nameQueryResponse.Result);

                    return;
                }
                else
                {
                    //The invite is EXPIRED so let's added a new one.
                    PendingInviteData.ReplaceObject(nameQueryResponse.Result, GeneratePendingInviteData(context.CallerGuid, guildStatus.Result.GuildId));
                }
            }
            else
            {
                PendingInviteData.AddObject(nameQueryResponse.Result, GeneratePendingInviteData(context.CallerGuid, guildStatus.Result.GuildId));
            }
            //TODO: There is currently no handling to indicate that they are online.

            //Now they have a valid pending invite, so let's address the client
            //that needs to recieve the guild invite.
            IRemoteSocialHubClient playerClient = context.Clients.RetrievePlayerClient(nameQueryResponse.Result);

            //Indicate the player has been invited.
            await SendGuildInviteResponse(context, GuildMemberInviteResponseCode.Success, nameQueryResponse.Result);

            //Now tell the remote/target player they're being invited to a guild.
            await playerClient.ReceiveGuildInviteEventAsync(new GuildMemberInviteEventModel(guildStatus.Result.GuildId, context.CallerGuid));
        }
Beispiel #5
0
 private static async Task SendGuildInviteResponse(IHubConnectionMessageContext <IRemoteSocialHubClient> context, GuildMemberInviteResponseCode code, NetworkEntityGuid inviteeGuid)
 {
     await context.Clients.Caller.ReceiveGuildInviteResponseAsync(new GuildMemberInviteResponseModel(code, inviteeGuid));
 }
 /// <inheritdoc />
 public GenericChatMessageContext([JetBrains.Annotations.NotNull] TMessageType incomingMessage, [JetBrains.Annotations.NotNull] IHubConnectionMessageContext hubContext)
 {
     IncomingMessage = incomingMessage ?? throw new ArgumentNullException(nameof(incomingMessage));
     HubContext      = hubContext ?? throw new ArgumentNullException(nameof(hubContext));
 }
 protected EntityAssociatedData <TargetlessChannelChatMessageRequestModel> BuildForwardableTargetlessChannelChatMessage(IHubConnectionMessageContext context, TargetlessChannelChatMessageRequestModel message) => BuildForwardableAssociatedData(context, message);
Beispiel #8
0
 protected abstract Task OnMessageRecieved(IHubConnectionMessageContext <TRemoteClientHubInterfaceType> context, TMessageType payload);
 /// <inheritdoc />
 protected override IRemoteSocialTextChatHubClient GetBroadcastGroup(IHubConnectionMessageContext <IRemoteSocialTextChatHubClient> context)
 {
     return(context.Clients.Group($"zone:{ZoneLookupService.Retrieve(context.HubConntext.ConnectionId)}"));
 }
Beispiel #10
0
        protected override async Task OnMessageRecieved(IHubConnectionMessageContext <IRemoteSocialHubClient> context, PendingGuildInviteHandleRequest payload)
        {
            //Really shouldn't happen, don't tell client anything.
            if (!PendingInviteData.ContainsKey(context.CallerGuid))
            {
                if (Logger.IsEnabled(LogLevel.Error))
                {
                    Logger.LogError($"User: {context.CallerGuid} tried to claim pending guild invite but none existed.");
                }

                return;
            }

            PendingGuildInviteData inviteData = PendingInviteData.RetrieveEntity(context.CallerGuid);

            //Now we can check if they wanted to join
            if (payload.isSuccessful)
            {
                bool guildJoinResult = false;

                //Important that we dispose of this, since this handler is not created every request.
                using (var characterGuildMembershipRepositoryContainer = CharacterGuildMembershipRepositoryFactory.Create())
                {
                    //When successful, we must add them to the guild database
                    //and then alert the guild channel (everyone in the guild) that they joined
                    //AND let the client itself know that it joined a guild.
                    guildJoinResult = await characterGuildMembershipRepositoryContainer.Repository.TryCreateAsync(new CharacterGuildMemberRelationshipModel(context.CallerGuid.EntityId, inviteData.GuildId));
                }

                //This should never happen
                if (!guildJoinResult)
                {
                    if (Logger.IsEnabled(LogLevel.Error))
                    {
                        Logger.LogError($"User: {context.CallerGuid} tried to join Guild: {inviteData.GuildId} but failed.");
                    }

                    return;
                }

                //TODO: Don't hardcode this
                //$"guild:{GuildStatusMappable.RetrieveEntity(guid).GuildId}
                //Their membership is within the database now.
                //Broadcast to everyone that a player joined the guild.
                await context.Clients.Group($"guild:{inviteData.GuildId}").ReceiveGuildMemberJoinedEventAsync(new GuildMemberJoinedEventModel(context.CallerGuid));

                await context.Groups.AddToGroupAsync(context.HubConntext.ConnectionId, $"guild:{inviteData.GuildId}");

                //Let the local client know that their guild status also changed.
                await context.Clients.RetrievePlayerClient(context.CallerGuid).ReceiveGuildStatusChangedEventAsync(new GuildStatusChangedEventModel(context.CallerGuid, inviteData.GuildId));
            }
            else
            {
                //On failure, we just remove the pending invite
                //and let the inviting client know that they declined an invite.
                PendingInviteData.RemoveEntityEntry(context.CallerGuid);

                IRemoteSocialHubClient inviterClient = context.Clients.RetrievePlayerClient(inviteData.InviterGuid);

                //Tell the inviter this failed.
                await inviterClient.ReceiveGuildInviteResponseAsync(new GuildMemberInviteResponseModel(GuildMemberInviteResponseCode.PlayerDeclinedGuildInvite, context.CallerGuid));
            }
        }
Beispiel #11
0
 protected override async Task OnMessageRecieved(IHubConnectionMessageContext <IRemoteSocialHubClient> context, TestSocialModel payload)
 {
     Logger.LogError($"Recieved TestMessage: {payload.TestMessage}");
 }
Beispiel #12
0
 /// <summary>
 /// TODO
 /// </summary>
 /// <returns></returns>
 protected abstract IRemoteSocialTextChatHubClient GetBroadcastGroup(IHubConnectionMessageContext <IRemoteSocialTextChatHubClient> context);