Example #1
0
        public override Task <CreatePartyResponse> CreateParty(CreatePartyRequest request, ServerCallContext context)
        {
            var playerId = AuthHeaders.ExtractPlayerId(context);
            var pit      = AuthHeaders.ExtractPit(context);

            // TODO(iuliaharasim/dom): Move logic specific to party creation in a separate class.
            PartyDataModel party;

            try
            {
                party = new PartyDataModel(playerId, pit, request.MinMembers, request.MaxMembers, request.Metadata);
            }
            catch (ArgumentException exception)
            {
                throw new RpcException(new Status(StatusCode.InvalidArgument, exception.Message));
            }

            var leader = party.GetLeader();

            using (var memClient = _memoryStoreClientManager.GetClient())
                using (var transaction = memClient.CreateTransaction())
                {
                    transaction.CreateAll(new List <Entry> {
                        party, leader
                    });
                }

            return(Task.FromResult(new CreatePartyResponse {
                PartyId = party.Id
            }));
        }
Example #2
0
        public override Task <CreatePartyResponse> CreateParty(CreatePartyRequest request, ServerCallContext context)
        {
            var playerId = AuthHeaders.ExtractPlayerId(context);
            var pit      = AuthHeaders.ExtractPit(context);

            // TODO(iuliaharasim/dom): Move logic specific to party creation in a separate class.
            PartyDataModel party;

            try
            {
                party = new PartyDataModel(playerId, pit, request.MinMembers, request.MaxMembers, request.Metadata);
            }
            catch (ArgumentException exception)
            {
                throw new RpcException(new Status(StatusCode.InvalidArgument, exception.Message));
            }

            var leader = party.GetLeader();

            using (var memClient = _memoryStoreClientManager.GetClient())
                using (var transaction = memClient.CreateTransaction())
                {
                    transaction.CreateAll(new List <Entry> {
                        party, leader
                    });
                }

            var eventAttributes = new Dictionary <string, string>
            {
                { "partyId", party.Id }
            };

            string[] eventTypes = { "player_created_party", "player_joined_party", "party_created" };
            foreach (string eventType in eventTypes)
            {
                if (eventType == "party_created")
                {
                    eventAttributes.Add("partyPhase", party.CurrentPhase.ToString());
                }
                _analytics.Send(eventType, eventAttributes, playerId);
            }

            return(Task.FromResult(new CreatePartyResponse {
                PartyId = party.Id
            }));
        }
Example #3
0
        public override async Task <JoinPartyResponse> JoinParty(JoinPartyRequest request, ServerCallContext context)
        {
            var playerId = AuthHeaders.ExtractPlayerId(context);

            var pit = AuthHeaders.ExtractPit(context);

            if (string.IsNullOrEmpty(request.PartyId))
            {
                throw new RpcException(new Status(StatusCode.InvalidArgument,
                                                  "JoinParty requires a non-empty party id"));
            }

            using (var memClient = _memoryStoreClientManager.GetClient())
            {
                var partyToJoin = await memClient.GetAsync <PartyDataModel>(request.PartyId) ??
                                  throw new RpcException(new Status(StatusCode.NotFound, "The party doesn't exist"));

                var member = await memClient.GetAsync <Member>(playerId);

                if (member != null && member.PartyId != request.PartyId)
                {
                    throw new RpcException(new Status(StatusCode.AlreadyExists,
                                                      "The player is a member of another party"));
                }

                var playerInvites = await memClient.GetAsync <PlayerInvites>(playerId);

                if (playerInvites == null)
                {
                    throw new RpcException(new Status(StatusCode.FailedPrecondition,
                                                      "The player is not invited to this party"));
                }

                var invites = (await Task.WhenAll(playerInvites.InboundInviteIds
                                                  .Select(invite => memClient.GetAsync <Invite>(invite))))
                              .Where(invite =>
                {
                    if (invite == null)
                    {
                        Log.Logger.Warning("Failed to fetch an invite for {player}", playerId);
                    }

                    return(invite != null);
                }).ToList();

                var invited = invites
                              .Any(invite => invite.CurrentStatus == Invite.Status.Pending && invite.ReceiverId == playerId);

                if (!invited)
                {
                    throw new RpcException(new Status(StatusCode.FailedPrecondition,
                                                      "The player is not invited to this party"));
                }


                if (partyToJoin.CurrentPhase != PartyPhaseDataModel.Forming)
                {
                    throw new RpcException(new Status(StatusCode.FailedPrecondition,
                                                      "The party is no longer in the Forming phase"));
                }

                // TODO(iuliaharasim/dom): Move logic specific to joining a party into a separate class.
                try
                {
                    var added = partyToJoin.AddPlayerToParty(playerId, pit);
                    // If false, the player already joined the party so we should terminate early.
                    if (!added)
                    {
                        return(new JoinPartyResponse {
                            Party = ConvertToProto(partyToJoin)
                        });
                    }
                }
                catch (Exception exception)
                {
                    throw new RpcException(new Status(StatusCode.FailedPrecondition, exception.Message));
                }

                using (var transaction = memClient.CreateTransaction())
                {
                    transaction.CreateAll(new List <Entry> {
                        partyToJoin.GetMember(playerId)
                    });
                    transaction.UpdateAll(new List <Entry> {
                        partyToJoin
                    });
                }

                _analytics.Send("player_joined_party", new Dictionary <string, object>
                {
                    { "partyId", partyToJoin.Id },
                    {
                        "invites", invites.Select(invite => new Dictionary <string, string>
                        {
                            { "inviteId", invite.Id },
                            { "playerIdInviter", invite.SenderId }
                        })
                    }
                }, playerId);

                return(new JoinPartyResponse {
                    Party = ConvertToProto(partyToJoin)
                });
            }
        }