コード例 #1
0
        private object OnNpcConversationRespond(VehicleVendor vendor, BasePlayer player, ConversationData conversationData, ResponseNode responseNode)
        {
            CostLabelUI.Destroy(player);

            foreach (var intercepter in _responseIntercepters)
            {
                var forceNextSpeechNode = intercepter.Intercept(vendor, player, conversationData, responseNode);
                if (forceNextSpeechNode != string.Empty)
                {
                    ConversationUtils.ForceSpeechNode(vendor, player, forceNextSpeechNode);
                    return(false);
                }
            }

            return(null);
        }
コード例 #2
0
        private async Task <ResultConversations> GetConversationsUntilEnd(string username, string endCt, int limit)
        {
            //Define Query
            TableQuery <UserConversationsTimeRowEntity> rangeQuery =
                new TableQuery <UserConversationsTimeRowEntity>().Where(
                    TableQuery.CombineFilters(
                        TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, username),
                        TableOperators.And, TableQuery.CombineFilters(
                            TableQuery.GenerateFilterCondition("RowKey", QueryComparisons.GreaterThan, endCt),
                            TableOperators.And,
                            TableQuery.GenerateFilterCondition("RowKey", QueryComparisons.LessThanOrEqual,
                                                               ConversationUtils.DateTimeToRowKey(new DateTime(2000, 1, 1))))));

            rangeQuery.TakeCount = limit;
            return(await ExecuteConversationQueryAndConvert(rangeQuery));
        }
コード例 #3
0
        private async Task <ResultMessages> GetMostRecentMessages(string conversationId, int limit)
        {
            //Define Query
            TableQuery <MessagesTableEntity> messageQuery = new TableQuery <MessagesTableEntity>().Where(
                TableQuery.CombineFilters(
                    TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, conversationId),
                    TableOperators.And,
                    TableQuery.CombineFilters(
                        TableQuery.GenerateFilterCondition("RowKey", QueryComparisons.LessThan,
                                                           ConversationUtils.DateTimeToRowKey(new DateTime(2000, 1, 1))), TableOperators.And,
                        TableQuery.GenerateFilterCondition("RowKey", QueryComparisons.GreaterThanOrEqual,
                                                           ConversationUtils.DateTimeToRowKey(DateTime.UtcNow)))));

            messageQuery.TakeCount = limit;
            return(await ExecuteMessageQueryAndConvert(messageQuery));
        }
コード例 #4
0
            public override string Intercept(NPCTalking npcTalking, BasePlayer player, ConversationData conversationData, ResponseNode responseNode)
            {
                if (responseNode.actionString != _matchResponseAction)
                {
                    return(string.Empty);
                }

                int vanillaPrice;

                if (!ConversationUtils.ResponseHasScrapPrice(responseNode, out vanillaPrice))
                {
                    return(string.Empty);
                }

                var priceConfig = _getVehicleConfig().GetPriceForPlayer(player.IPlayer, _freePermission);

                if (priceConfig == null || priceConfig.MatchesVanillaPrice(vanillaPrice))
                {
                    return(string.Empty);
                }

                var neededScrap           = PlayerInventoryUtils.GetPlayerNeededScrap(player, vanillaPrice);
                var canAffordVanillaPrice = neededScrap <= 0;
                var canAffordCustomPrice  = priceConfig.CanPlayerAfford(player);

                if (!canAffordCustomPrice)
                {
                    return(ConversationUtils.SpeechNodes.Goodbye);
                }

                // Add scrap so the vanilla checks will pass. Add full amount for simplicity.
                player.inventory.containerMain.AddItem(ItemManager.itemDictionary[ScrapItemId], vanillaPrice);

                // Check conditions just in case, to make sure we don't give free scrap.
                if (!responseNode.PassesConditions(player, npcTalking))
                {
                    _pluginInstance.LogError($"Price adjustment unexpectedly failed for price config (response: '{_matchResponseAction}', player: {player.userID}).");
                    player.inventory.containerMain.AddItem(ItemManager.itemDictionary[ScrapItemId], -vanillaPrice);
                    return(string.Empty);
                }

                priceConfig.TryChargePlayer(player, vanillaPrice);

                return(string.Empty);
            }
コード例 #5
0
        public override async Task HandleIncomingUserResponseAsync(ITurnContext turnContext, CancellationToken cancellationToken)
        {
            var userInput = ConversationUtils.GetUserReply(turnContext);

            if (DialogUtils.IsUserInputInOptions(userInput, Constants.RequestedMaintenanceServiceSelection.CarpentryPossibleValues))
            {
                ConversationData.ServiceBookingForm.RequestedService = SupportedMaintenanceServices.Carpentry;
            }
            else if (DialogUtils.IsUserInputInOptions(userInput, Constants.RequestedMaintenanceServiceSelection.ElectricalMaintenancePossibleValues))
            {
                ConversationData.ServiceBookingForm.RequestedService = SupportedMaintenanceServices.ElectricalMaintenance;
            }
            else if (DialogUtils.IsUserInputInOptions(userInput, Constants.RequestedMaintenanceServiceSelection.PlumbingPossibleValues))
            {
                ConversationData.ServiceBookingForm.RequestedService = SupportedMaintenanceServices.PlumbingServices;
            }
            else if (DialogUtils.IsUserInputInOptions(userInput, Constants.RequestedMaintenanceServiceSelection.AirConditioningPossibleValues))
            {
                ConversationData.ServiceBookingForm.RequestedService = SupportedMaintenanceServices.AirConditioningMaintenance;
            }
            else if (DialogUtils.IsUserInputInOptions(userInput, Constants.RequestedMaintenanceServiceSelection.PaintingPossibleValues))
            {
                ConversationData.ServiceBookingForm.RequestedService = SupportedMaintenanceServices.PaintingServices;
            }
            else if (DialogUtils.IsUserInputInOptions(userInput, Constants.RequestedMaintenanceServiceSelection.CleaningPossibleValues))
            {
                ConversationData.ServiceBookingForm.RequestedService = SupportedMaintenanceServices.Cleaning;
            }
            else
            {
                await ConversationUtils.SendMessageBasedOnUserPreferredLanguage(
                    Constants.General.InvalidValueProvided,
                    UserProfile,
                    turnContext,
                    cancellationToken
                    );
            }

            if (ConversationData.ServiceBookingForm.RequestedService.HasValue)
            {
                ConversationData.SetWaitingForUserInputFlag(false);
            }
        }
コード例 #6
0
        //Helping Functions
        /// <summary>
        /// Deletes 4 entities corresponding to a conversation
        /// </summary>
        /// <param name="conversation"></param>
        public async Task <bool> TryDeleteConversation(Conversation conversation)
        {
            try
            {
                var timeRow = ConversationUtils.DateTimeToRowKey(conversation.LastModifiedDateUtc);
                var task1   = RetrieveAndDelete(conversation.Participants[0], conversation.Id, timeRow);
                var task2   = RetrieveAndDelete(conversation.Participants[1], conversation.Id, timeRow);
                await Task.WhenAll(task1, task2);
            }
            catch (StorageException)
            {
                return(false);
            }
            catch (ArgumentNullException)
            {
                return(false);
            }

            return(true);
        }
コード例 #7
0
            public override string Intercept(NPCTalking npcTalking, BasePlayer player, ConversationData conversationData, ResponseNode responseNode)
            {
                int vanillaPrice;

                if (!ConversationUtils.PrecedesPaymentOption(conversationData, responseNode, _matchResponseAction, out vanillaPrice))
                {
                    return(string.Empty);
                }

                var priceConfig = _getVehicleConfig().GetPriceForPlayer(player.IPlayer, _freePermission);

                if (priceConfig == null || priceConfig.MatchesVanillaPrice(vanillaPrice))
                {
                    return(string.Empty);
                }

                var neededScrap           = PlayerInventoryUtils.GetPlayerNeededScrap(player, vanillaPrice);
                var canAffordVanillaPrice = neededScrap <= 0;
                var canAffordCustomPrice  = priceConfig.CanPlayerAfford(player);

                CostLabelUI.Create(player, priceConfig);

                if (canAffordCustomPrice == canAffordVanillaPrice)
                {
                    return(string.Empty);
                }

                if (!canAffordCustomPrice)
                {
                    // Reduce scrap that will be removed to just below the amount they need for vanilla.
                    neededScrap--;
                }

                // Add or remove scrap so the vanilla logic for showing the payment option will match the custom payment logic.
                PlayerInventoryUtils.UpdateWithFakeScrap(player, neededScrap);

                // This delay needs to be long enough for the text to print out, which could vary by language.
                player.Invoke(() => PlayerInventoryUtils.Refresh(player), 3f);

                return(string.Empty);
            }
コード例 #8
0
        /// <summary>
        /// Deletes entity corresponding to a message
        /// </summary>
        /// <param name="conversationId"></param>
        /// <param name="message"></param>
        public async Task <bool> TryDeleteMessage(string conversationId, Message message)
        {
            try
            {
                var entity = await messageTable.ExecuteAsync(TableOperation.Retrieve <MessagesTableEntity>(
                                                                 conversationId,
                                                                 ConversationUtils.DateTimeToRowKey(message.UtcTime)));

                await messageTable.ExecuteAsync(TableOperation.Delete((MessagesTableEntity)entity.Result));

                return(true);
            }
            catch (StorageException)
            {
                return(false);
            }
            catch (ArgumentNullException)
            {
                return(false);
            }
        }
        public override async Task ProActiveMessageToUseAsync(ITurnContext turnContext, CancellationToken cancellationToken)
        {
            var messageFormattingValues = new string[]
            {
                this.ConversationData.NewUserMaintenanceServiceId,
                this.ConversationData.ServiceBookingForm.RequiredServiceDescription
            };

            await ConversationUtils.SendMessageBasedOnUserPreferredLanguage(
                Constants.RequestStatusUpdate.ServiceRequestDeliveredMessage,
                UserProfile,
                turnContext,
                cancellationToken,
                formattingValues : new MessageOption()
            {
                Arabic  = messageFormattingValues,
                English = messageFormattingValues
            });

            ConversationData.SetWaitingForUserInputFlag();
        }
        private async Task HandleIncommingMessage(ITurnContext turnContext, CancellationToken cancellationToken = default(CancellationToken))
        {
            var userProfile = await conversationStateDataAccessor.GetUserData(turnContext);

            var conversationData = await conversationStateDataAccessor.GetConversationData(turnContext);

            do
            {
                var suitableDialog = GetSuitableDialog(userProfile, conversationData);

                if (!conversationData.WaitingForUserInput)
                {
                    await suitableDialog.StartAsync(turnContext, cancellationToken);
                }
                else
                {
                    if (DialogUtils.ValidateUserInputIsNotEmpty(ConversationUtils.GetUserReply(turnContext)))
                    {
                        await suitableDialog.HandleIncomingUserResponseAsync(turnContext, cancellationToken);
                    }
                    else
                    {
                        await ConversationUtils.SendMessageBasedOnUserPreferredLanguage(
                            Dialogs.Constants.General.EmptyValueProvided,
                            userProfile,
                            turnContext,
                            cancellationToken
                            );
                    }
                }

                conversationData = suitableDialog.ConversationData;
                userProfile      = suitableDialog.UserProfile;
            } while (!conversationData.WaitingForUserInput);

            await conversationStateDataAccessor.UpdateUserData(turnContext, userProfile);

            await conversationStateDataAccessor.UpdateConversationData(turnContext, conversationData);
        }
        public override async Task StartAsync(ITurnContext turnContext, CancellationToken cancellationToken)
        {
            var formRepresentation = new string[]
            {
                this.ConversationData.ServiceBookingForm.ToLocalizedStrings(this.UserProfile.PreferredLanguage.Value)
            };

            var formValuesStringRepresentation = new MessageOption()
            {
                English = formRepresentation,
                Arabic  = formRepresentation
            };

            await ConversationUtils.SendMessageBasedOnUserPreferredLanguage(
                Constants.Confirmation.ConfirmationMessage,
                this.UserProfile,
                turnContext,
                cancellationToken,
                formattingValues : formValuesStringRepresentation);

            ConversationData.SetWaitingForUserInputFlag(true);
        }
コード例 #12
0
            public override string Intercept(NPCTalking npcTalking, BasePlayer player, ConversationData conversationData, ResponseNode responseNode)
            {
                int vanillaPrice;

                if (!ConversationUtils.PrecedesPaymentOption(conversationData, responseNode, _matchResponseAction, out vanillaPrice))
                {
                    return(string.Empty);
                }

                if (!_getVehicleConfig().RequiresPermission)
                {
                    return(string.Empty);
                }

                if (_pluginInstance.HasPermissionAny(player.UserIDString, Permission_Allow_All, _allowPermission))
                {
                    return(string.Empty);
                }

                _pluginInstance.ChatMessage(player, "Error.Vehicle.NoPermission");
                return(ConversationUtils.SpeechNodes.Goodbye);
            }
コード例 #13
0
            public static bool PrecedesPaymentOption(ConversationData conversationData, ResponseNode responseNode, string matchResponseAction, out int scrapPrice)
            {
                var resultingSpeechNode = ConversationUtils.FindSpeechNodeByName(conversationData, responseNode.resultingSpeechNode);

                if (resultingSpeechNode == null)
                {
                    scrapPrice = 0;
                    return(false);
                }

                foreach (var futureResponseOption in resultingSpeechNode.responses)
                {
                    if (!string.IsNullOrEmpty(matchResponseAction) &&
                        matchResponseAction == futureResponseOption.actionString &&
                        ConversationUtils.ResponseHasScrapPrice(futureResponseOption, out scrapPrice))
                    {
                        return(true);
                    }
                }

                scrapPrice = 0;
                return(false);
            }
コード例 #14
0
        public override async Task HandleIncomingUserResponseAsync(ITurnContext turnContext, CancellationToken cancellationToken)
        {
            var userInput = ConversationUtils.GetUserReply(turnContext);

            if (DialogUtils.IsUserInputInOptions(userInput, Constants.LanguageSelection.EnglishLanguagePossibleSelectionValues))
            {
                UserProfile.PreferredLanguage = SupportedLanguage.English;
            }
            else if (DialogUtils.IsUserInputInOptions(userInput, Constants.LanguageSelection.ArabicLanguagePossibleSelectionValues))
            {
                UserProfile.PreferredLanguage = SupportedLanguage.Arabic;
            }
            else
            {
                await ConversationUtils.SendMessage(Constants.General.InvalidValueProvided.CombineLanguageValues(),
                                                    turnContext,
                                                    cancellationToken);
            }

            if (UserProfile.PreferredLanguage.HasValue)
            {
                this.ConversationData.SetWaitingForUserInputFlag(false);
            }
        }
コード例 #15
0
        private async Task <ResultMessages> ExecuteMessageQueryAndConvert(TableQuery <MessagesTableEntity> rangeQuery)
        {
            try
            {
                var resultEntities = await messageTable.ExecuteQuerySegmentedAsync(rangeQuery, null);

                var entities  = resultEntities.Results;
                var converter = new Converter <MessagesTableEntity, Message>(entity =>
                                                                             new Message(entity.Text, entity.SenderUsername,
                                                                                         ConversationUtils.ParseDateTime(entity.RowKey)));
                var messages = new List <Message>(entities.ConvertAll(converter));
                if (messages.Count == 0)
                {
                    return(new ResultMessages(messages, null, null));
                }

                return(new ResultMessages(messages, ConversationUtils.DateTimeToRowKey(messages.First().UtcTime),
                                          ConversationUtils.DateTimeToRowKey(messages.Last().UtcTime)));
            }
            catch (StorageException)
            {
                throw new StorageUnavailableException("Failed to get messages");
            }
        }
        private async Task HandleDeleteUserDataRequest(ITurnContext turnContext, CancellationToken cancellationToken)
        {
            await conversationStateDataAccessor.DeleteUserCachedData(turnContext);

            await ConversationUtils.SendMessage("User Data Deleted (Y)!", turnContext, cancellationToken);
        }
コード例 #17
0
        private async Task <ResultConversations> ExecuteConversationQueryAndConvert(
            TableQuery <UserConversationsTimeRowEntity> rangeQuery)
        {
            try
            {
                var tableQuerySegment = await userConversationsTable.ExecuteQuerySegmentedAsync(rangeQuery, null);

                var entities  = tableQuerySegment.Results;
                var converter = new Converter <UserConversationsTimeRowEntity, Conversation>(entity =>
                                                                                             new Conversation(entity.Id, new List <string> {
                    entity.PartitionKey, entity.Recipient
                },
                                                                                                              ConversationUtils.ParseDateTime(entity.RowKey)));
                var conversations = new List <Conversation>(entities.ConvertAll(converter));

                if (conversations.Count == 0)
                {
                    return(new ResultConversations(conversations, null, null));
                }

                return(new ResultConversations(conversations,
                                               ConversationUtils.DateTimeToRowKey(conversations.First().LastModifiedDateUtc),
                                               ConversationUtils.DateTimeToRowKey(conversations.Last().LastModifiedDateUtc)));
            }
            catch (StorageException)
            {
                throw new StorageUnavailableException("Failed to reach storage!");
            }
        }
コード例 #18
0
        public async Task <Message> AddMessage(string conversationId, Message message)
        {
            if (message == null)
            {
                throw new ArgumentNullException(nameof(message));
            }

            if (string.IsNullOrWhiteSpace(message.SenderUsername))
            {
                throw new ArgumentException(nameof(message));
            }

            if (string.IsNullOrWhiteSpace(message.Text))
            {
                throw new ArgumentException(nameof(message));
            }


            MessagesTableEntity messageEntity = new MessagesTableEntity
            {
                PartitionKey   = conversationId,
                RowKey         = ConversationUtils.DateTimeToRowKey(message.UtcTime),
                Text           = message.Text,
                SenderUsername = message.SenderUsername
            };

            //Define operations
            var insertOperation   = TableOperation.Insert(messageEntity);
            var retrieveOperation =
                TableOperation.Retrieve <UserConversationsIdRowEntity>(message.SenderUsername, conversationId);

            try
            {
                var result = await userConversationsTable.ExecuteAsync(retrieveOperation);

                if (result.HttpStatusCode == 404)
                {
                    var participantsFromId = Conversation.ParseId(conversationId);
                    if (!participantsFromId.Contains(message.SenderUsername))
                    {
                        throw new InvalidDataException("Sender not part of conversation");
                    }

                    throw new ConversationNotFoundException("Conversation not found");
                }

                await messageTable.ExecuteAsync(insertOperation);

                var entity = (UserConversationsIdRowEntity)result.Result;

                retrieveOperation =
                    TableOperation.Retrieve <UserConversationsIdRowEntity>(entity.Recipient, conversationId);
                var retrieveResult2 = await userConversationsTable.ExecuteAsync(retrieveOperation);

                var entity2 = (UserConversationsIdRowEntity)retrieveResult2.Result;

                await UpdateConversationTime(entity2.RowKey, entity2.PartitionKey, entity2.LastModifiedUtcTime, message.UtcTime);
                await UpdateConversationTime(entity.RowKey, entity.PartitionKey, entity.LastModifiedUtcTime, message.UtcTime);

                return(message);
            }
            catch (StorageException e)
            {
                throw new StorageUnavailableException($"Failed to reached storage {e.Message}");
            }
        }
 public override Task HandleIncomingUserResponseAsync(ITurnContext turnContext, CancellationToken cancellationToken)
 {
     ConversationData.ServiceBookingForm.RequiredServiceDescription = ConversationUtils.GetUserReply(turnContext);
     ConversationData.SetWaitingForUserInputFlag(false);
     return(Task.FromResult(0));
 }
        public override async Task HandleIncomingUserResponseAsync(ITurnContext turnContext, CancellationToken cancellationToken)
        {
            var userInput = ConversationUtils.GetUserReply(turnContext);

            if (DialogUtils.IsUserInputInOptions(userInput, Constants.Confirmation.ApprovalOptionValues))
            {
                var newMaintenanceServiceRequestId = await PostMaintenanceServiceRequestForTheUser();

                if (!string.IsNullOrWhiteSpace(newMaintenanceServiceRequestId))
                {
                    var requestIdAsOption = new string[] { newMaintenanceServiceRequestId };
                    await ConversationUtils.SendMessageBasedOnUserPreferredLanguage(
                        Constants.Confirmation.RequestSupmittedMessage,
                        this.UserProfile,
                        turnContext,
                        cancellationToken,
                        formattingValues : new MessageOption()
                    {
                        English = requestIdAsOption,
                        Arabic  = requestIdAsOption
                    }
                        );

                    this.ConversationData.NewUserMaintenanceServiceId = newMaintenanceServiceRequestId;
                    this.ConversationData.IsExpectingFeedBackFromUser = true;
                    await new GettingUserFeedBackDialog(this.ConversationData, this.UserProfile).StartAsync(turnContext, cancellationToken);

                    ClearServiceBookingForm();
                    ResetUserIntentFromDialog();
                    this.ConversationData.NewUserMaintenanceServiceId = newMaintenanceServiceRequestId;
                    this.ConversationData.SetWaitingForUserInputFlag(false);
                }
                else
                {
                    await ConversationUtils.SendMessageBasedOnUserPreferredLanguage(
                        Constants.Confirmation.FailedToSupmitRequestMessage,
                        this.UserProfile,
                        turnContext,
                        cancellationToken
                        );
                }
            }
            else
            {
                this.ConversationData.SetWaitingForUserInputFlag(false);
                if (DialogUtils.IsUserInputInOptions(userInput, Constants.Confirmation.RequiredServicenAdjustmentOptionValues))
                {
                    this.ConversationData.ServiceBookingForm.RequestedService = null;
                }
                else if (DialogUtils.IsUserInputInOptions(userInput, Constants.Confirmation.ServiceDescriptionAdjustmentOptionValues))
                {
                    this.ConversationData.ServiceBookingForm.RequiredServiceDescription = null;
                }
                else if (DialogUtils.IsUserInputInOptions(userInput, Constants.Confirmation.AdressAdjustmentOptionValues))
                {
                    this.ConversationData.ServiceBookingForm.DeliveryLocation = null;
                }
                else if (DialogUtils.IsUserInputInOptions(userInput, Constants.Confirmation.YearAdjustmentOptionValues))
                {
                    this.ConversationData.ServiceBookingForm.Year = null;
                }
                else if (DialogUtils.IsUserInputInOptions(userInput, Constants.Confirmation.MonthAdjustmentOptionValues))
                {
                    this.ConversationData.ServiceBookingForm.Month = null;
                }
                else if (DialogUtils.IsUserInputInOptions(userInput, Constants.Confirmation.DayAdjustmentOptionValues))
                {
                    this.ConversationData.ServiceBookingForm.Day = null;
                }
                else if (DialogUtils.IsUserInputInOptions(userInput, Constants.Confirmation.HourAdjustmentOptionValues))
                {
                    this.ConversationData.ServiceBookingForm.Hour = null;
                }
                else if (DialogUtils.IsUserInputInOptions(userInput, Constants.Confirmation.MinuteAdjustmentOptionValues))
                {
                    this.ConversationData.ServiceBookingForm.Minutes = null;
                }
                else if (DialogUtils.IsUserInputInOptions(userInput, Constants.Confirmation.PartOfDayAdjustmentOptionValues))
                {
                    this.ConversationData.ServiceBookingForm.DayOrNight = null;
                }
                else
                {
                    this.ConversationData.SetWaitingForUserInputFlag();
                    await ConversationUtils.SendMessageBasedOnUserPreferredLanguage(
                        Constants.General.InvalidValueProvided,
                        this.UserProfile,
                        turnContext,
                        cancellationToken
                        );
                }
            }
        }