Пример #1
0
    public async Task <string> Process(string chatId,
                                       string messageText,
                                       string user,
                                       int?answerToMessageId = null)
    {
        if (string.IsNullOrEmpty(messageText))
        {
            Console.WriteLine("Message is empty.");
            return("");
        }

        var synchronizer = synchronizerDict.ContainsKey(chatId)
            ? synchronizerDict[chatId]
            : (synchronizerDict[chatId] = new SemaphoreSlim(1, 1));

        if (!await synchronizer.WaitAsync(1000))
        {
            Console.WriteLine("Error: can't take lock.");
            return("");
        }

        try {
            // initialize new state if new player, or on "reset" command
            if (stateManager.GetState(chatId) == null || messageText.StartsWith("/reset"))
            {
                stateManager.SetState(chatId, new BotState {
                    QuestState = new QuestService(NewCellQuest.Map,
                                                  NewCellQuest.GetStartingInventory(),
                                                  NewCellQuest.GetStartingJournal(),
                                                  NewCellQuest.GetDialogs())
                                 .State
                });
            }
            else if (stateManager.GetState(chatId) == null || messageText.StartsWith("/nastya"))
            {
                var questState = new QuestService(NewCellQuest.Map,
                                                  NewCellQuest.GetStartingInventory(),
                                                  NewCellQuest.GetStartingJournal(),
                                                  NewCellQuest.GetDialogs())
                                 .State;
                questState.OpenDialogName = Dialog.ZagsEnd;
                questState.Inventory      = questState.Inventory.Give(Item.Glasses);
                stateManager.SetState(chatId, new BotState {
                    QuestState = questState
                });
            }
            // reset all hashcodes to send all messages again if "play" commend is received
            else if (messageText.StartsWith("/play"))
            {
                var oldState = stateManager.GetState(chatId);
                oldState.PreviousMessageHash = -1;
                stateManager.SetState(chatId, oldState);
            }

            var botState     = stateManager.GetState(chatId);
            var questService = new QuestService(NewCellQuest.GetDialogs(), botState.QuestState);

            if (messageText != null)
            {
                Console.WriteLine($"Received a text message in chat {chatId} from {user}: \n {messageText}");
            }

            var userValidation = questService.CanPlay(user);
            if (!userValidation.CanPlay)
            {
                return(userValidation.Reason);
            }

            var currentMove = questService.ProcessAnswer((messageText?.IsSmile() == true)
                ? messageText.FromSmile().ToString()
                : messageText);
            var answerButtons = RenderButtons(currentMove);
            var message       = currentMove.Photo != null
                ? await SendMediaMessage(chatId, currentMove, botState, answerButtons, answerToMessageId)
                : await SendTextMessage(chatId, currentMove, botState, answerButtons, answerToMessageId);

            if (message != null)
            {
                botState.QuestState = questService.State;
                stateManager.SetState(chatId, botState);
            }
        }
        catch (Exception exception) {
            Console.WriteLine(exception);
        }
        finally {
            if (synchronizer.CurrentCount == 0)
            {
                synchronizer.Release();
            }
            else
            {
                Console.WriteLine("Error: Synchronizer count is unexpected. Expected: 0, actual: " + synchronizer.CurrentCount);
            }
        }
        return("");
    }