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(""); }