Ejemplo n.º 1
0
        public static string Upload(int objectId, string filename, out bool success)
        {
            success = false;
            if (!MainForm.Conf.Subscribed)
                return LocRm.GetString("NotSubscribed");

            if (UploadList.SingleOrDefault(p => p.Filename == filename) != null)
                return LocRm.GetString("FileInQueue");

            if (UploadList.Count >= CloudGateway.MaxUploadQueue)
                return LocRm.GetString("UploadQueueFull");

            if (Uploaded.FirstOrDefault(p=>p==filename)!=null)
            {
                return LocRm.GetString("AlreadyUploaded");
            }
            
            var us = new UserState(objectId, filename);
            UploadList.Add(us);

            if (!_uploading)
            {
                _uploading = true;
                ThreadPool.QueueUserWorkItem(Upload, null);
            }
            success = true;
            return LocRm.GetString("AddedToQueue");
        }
        public void XmlSerializerSizeTest()
        {
            var state = new UserState();
            state.Email = "*****@*****.**";
            state.UserId = "1";
            state.IsAdmin = true;
            state.Name = "Rick Strahl | Markus Egger";
            state.Date = DateTime.Now;
            state.Role = null;

            
            string xml = null; 
            var bytes = SerializationUtils.SerializeObjectToByteArray(state, true);

            Stopwatch watch = new Stopwatch();
            watch.Start();


            for (int i = 0; i < INT_ProfileLoop; i++)
            {
                bytes = SerializationUtils.SerializeObjectToByteArray(state, true);
            }

            
            watch.Stop();

            xml = SerializationUtils.SerializeObjectToString(state, true);
            Console.WriteLine("Xml: " + xml.Length + "  elapsed: " + watch.ElapsedMilliseconds + "ms");
            Console.WriteLine(xml);
        }
Ejemplo n.º 3
0
 public User(User u)
 {
     _username = u.UserName;
     _state = u.State;
     _nickname = u.NickName;
     _authLevel = u.AuthLevel;
 }
Ejemplo n.º 4
0
        public static string Upload(int objectId, string filename)
        {
            if (string.IsNullOrEmpty(MainForm.Conf.YouTubeUsername))
            {
                return LocRm.GetString("YouTubeAddSettings");
            }
            if (UploadList.SingleOrDefault(p => p.Filename == filename) != null)
                return LocRm.GetString("FileInQueue");

            if (UploadList.Count >= CloudGateway.MaxUploadQueue)
                return LocRm.GetString("UploadQueueFull");

            int i = MainForm.Conf.UploadedVideos.IndexOf(filename, StringComparison.Ordinal);
            if (i != -1)
            {
                return LocRm.GetString("AlreadyUploaded");
            }

            var us = new UserState(objectId, filename);
            UploadList.Add(us);

            if (!_uploading)
            {
                _uploading = true;
                ThreadPool.QueueUserWorkItem(Upload, null);
            }

            return LocRm.GetString("AddedToQueue");
        }
Ejemplo n.º 5
0
 public User(string username, string nickname, UserState state, UserAuthLevel auth)
 {
     _username = username;
     _state = state;
     _nickname = nickname;
     _authLevel = auth;
 }
Ejemplo n.º 6
0
 void IServerService.ChangeState(int clientId, UserState state)
 {
     //thread safe?
       users[clientId].State = state;
       Broadcast(ServerInterpreter.OnUserStateChanged(clientId, state));
       OnUserChanged(clientId);
 }
Ejemplo n.º 7
0
		public User(string id, string name, int color, long tick) {
			Id = id;
			Name = name;
			Color = System.Drawing.Color.FromArgb(color);
			LastCommentDate = new DateTime(tick);
			State = UserState.None;
		}
Ejemplo n.º 8
0
        public User(string nickname, UserState state)
        {
            if (nickname == null)
                throw new ArgumentNullException ("nickname");

            Nickname = nickname;
            State = state;
        }
Ejemplo n.º 9
0
 public User(string username, string password)
 {
     this.username = username;
     this.password = password;
     friends = new List<string>();
     this.level = AuthorizationLevel.GUEST;
     currentState = UserState.Active;
 }
Ejemplo n.º 10
0
 public static void PutQueryToState(RQquery query, UserState.States stateType)
 {
     state = (ViewState)UserState.Get(stateType);
     if (state == null)
         state = new ViewState(stateType);
     state.query = query;
     state.Save();
 }
Ejemplo n.º 11
0
 public UserProfile()
 {
   this.m_UserName = "******";
   this.m_ID = "0";
   this.m_IsFriend = false;
   this.m_State = UserState.Offline;
   this.m_Image = new Texture2D(32, 32);
 }
Ejemplo n.º 12
0
 public UserProfile(string name, string id, bool friend, UserState state, Texture2D image)
 {
   this.m_UserName = name;
   this.m_ID = id;
   this.m_IsFriend = friend;
   this.m_State = state;
   this.m_Image = image;
 }
Ejemplo n.º 13
0
 public static IMessage ChangeInfo(UserState state, string sign)
 {
     return MessageHelper.BuildMessage(MessageHeaders.CHANGE_INFO, writer =>
     {
       writer.WriteUserState(state);
       writer.Write(sign);
     });
 }
Ejemplo n.º 14
0
        public ActionResult Admin(string userId, UserState userState)
        {
            _userWriterService.Configure(userId, userState);

            string message = string.Format("UserState of '{0}' is {1}.", userId, userState);
            _logger.Info(message);

            return RedirectToAction("admin");
        }
Ejemplo n.º 15
0
 /// <summary>
 /// 修改家族状态(以传入用户为根节点)
 /// </summary>
 /// <param name="user">The user.</param>
 /// <param name="state">The state.</param>
 public void UpdateFamilyState(User user, UserState state)
 {
     string sql = string.Format(@";WITH CTE AS(
     SELECT * FROM tb_User  WHERE {0}=@{0}
     UNION ALL
     SELECT B.* FROM tb_User AS B,CTE AS C
     WHERE B.parentId=C.UserId and B.UserId>C.UserId)
     update tb_UserInfo set {1}=@{1} where UserId in (select UserId from CTE)", User.USERID, UserInfo.STATE);
     base.ExecuteNonQuery(sql, new SqlParameter(User.USERID, user.UserId), new SqlParameter(UserInfo.STATE, (int)state));
 }
    public void UpdatePosition(UserState state)
    {
        if (itsMe)
            return;

        last_axis_v = state.a_v;
        last_axis_h = state.a_h;
        last_jump = state.jump;
        last_position = new Vector3(state.p_x, -0.02f, state.p_z);
        last_rotation = new Quaternion(0f, state.r_y, 0f, state.r_w);
    }
Ejemplo n.º 17
0
 void IServerService.ChangeInfo(int clientId, UserState state, string sign)
 {
     var user = users[clientId];
       if (user != null)
       {
     user.State = state;
     user.Sign = sign;
     Broadcast(ServerInterpreter.OnUserInfoChanged(clientId, state, sign));
     OnUserChanged(clientId);
       }
 }
Ejemplo n.º 18
0
 public SentMessage(UserState state, string message)
 {
     Badges = state.Badges;
     Channel = state.Channel;
     ColorHex = state.ColorHex;
     DisplayName = state.DisplayName;
     EmoteSet = state.EmoteSet;
     IsModerator = state.Moderator;
     IsSubscriber = state.Subscriber;
     UserType = state.UserType;
     Message = message;
 }
Ejemplo n.º 19
0
        public ActionResult Licensing(UserState userState)
        {
            var model = GetSettingsModel();
            if (!model.IsInitialized || model.UserState == userState)
                return View(model);

            _userWriterService.Configure(model.UserId, userState);

            string message = string.Format("UserState of '{0}' is {1}.", model.UserAlias, userState);
            _logger.Info(message);

            return RedirectToAction("licensing");
        }
Ejemplo n.º 20
0
        /// <summary>
        /// 增加一条数据
        /// </summary>
        public void Add(UserState model)
        {
            StringBuilder strSql=new StringBuilder();
            strSql.Append("insert into T_UserState(");
            strSql.Append("ID,Name)");
            strSql.Append(" values (");
            strSql.Append("@ID,@Name)");
            SqlParameter[] parameters = {
                    new SqlParameter("@ID", SqlDbType.VarChar,32),
                    new SqlParameter("@Name", SqlDbType.VarChar,40)};
            parameters[0].Value = model.ID;
            parameters[1].Value = model.Name;

            DbHelperSQL.ExecuteSql(strSql.ToString(),parameters);
        }
Ejemplo n.º 21
0
        public NetworkLayer(UserState userState, string appId, string appSecret, string redirectUrl)
        {
            _userState = userState;
            _appId = appId;
            _appSecret = appSecret;
            _redirectUrl = redirectUrl;

            _cookieContainer = new CookieContainer();
            var handler = new HttpClientHandler { CookieContainer = _cookieContainer };
            if (handler.SupportsAutomaticDecompression)
            {
                handler.AutomaticDecompression = DecompressionMethods.GZip |
                                                 DecompressionMethods.Deflate;
            }
            _httpClient = new HttpClient(handler);
            _httpClient.DefaultRequestHeaders.UserAgent.ParseAdd("SnooSharp/1.0");
        }
Ejemplo n.º 22
0
 public void Configure(string userId, UserState userState)
 {
     switch (userState)
     {
         case UserState.Default:
             _userStoreService.RemoveOptinUser(userId);
             _userStoreService.RemoveOptoutUser(userId);
             break;
         case UserState.Optin:
             _userStoreService.RemoveOptoutUser(userId);
             _userStoreService.AddOptintUser(userId);
             break;
         case UserState.Optout:
             _userStoreService.RemoveOptinUser(userId);
             _userStoreService.AddOptoutUser(userId);
             break;
     }
 }
Ejemplo n.º 23
0
        private void OnAccountContactRefresh(AccountContactRefreshRequest refreshRequest)
        {
            _logger.Trace("OnAccountContactRefresh({0}, {1}, {2})", refreshRequest.UserId, refreshRequest.Account.AccountId, refreshRequest.TriggeredBy);

            UserState userState;
            var userId = refreshRequest.UserId;
            lock (_gate)
            {
                if (!_userContactsMap.TryGetValue(userId, out userState))
                {
                    userState = new UserState(userId, _accountContactProviders);
                    _userContactsMap[userId] = userState;
                    _allUserContactUpdates.OnNext(userState);
                }
            }
            

            userState.RefreshAccount(refreshRequest.Account);
        }
        public void StringSerializerTest()
        {
            var state = new UserState();
            state.Email = "*****@*****.**";
            state.UserId = "1";
            state.IsAdmin = true;
            state.Name = "Rick Strahl | Markus Egger";
            state.Date = DateTime.Now;
            state.Role = new Role() { Level = 10, Name = "Rick" };            
            
            string ser = null;
            ser = StringSerializer.SerializeObject(state);

            Stopwatch watch = new Stopwatch();
            watch.Start();
            
            for (int i = 0; i < INT_ProfileLoop; i++)
            {
                ser = StringSerializer.SerializeObject(state);
            }

            watch.Stop();

            Console.WriteLine("StringSerializer: " + ser.Length + "  elapsed: " + watch.ElapsedMilliseconds + "ms");
            Console.WriteLine(ser);

            var state2 = StringSerializer.Deserialize<UserState>(ser);

            Assert.AreEqual(state.Email, state2.Email);
            Assert.AreEqual(state.UserId, state2.UserId);
            Assert.AreEqual(state.Name, state2.Name);

            // exact date is not lined up to ticks so compare minutes
            Assert.AreEqual(state.Date.Minute, state2.Date.Minute);

            // Computed property
            Assert.AreEqual(state.UserIdInt, state2.UserIdInt);
            
            // Role is an unsupported type so it should come back as null
            Assert.IsNull(state2.Role);
        }
Ejemplo n.º 25
0
        /// <summary>
        /// Builds the actual query. 
        /// </summary>
        /// <param name="queryString">
        /// queryString == null | ""        : Rebuilds actual query from stored query state parameters or returns the default query.
        /// queryString != null             : Builds a new query from queryString and stores it in query state parameters. 
        /// </param>
        /// <param name="stateType">
        /// stateType == ListViewState      : (Re)builds actual query for ListView. 
        /// stateType == BrowseViewState    : (Re)builds actual query for BrowseView.
        /// stateType == ItemViewState      : (Re)builds actual query for SingleItemView.
        /// </param>
        /// <returns>
        /// Actual query.
        /// </returns>
        public static RQquery GetQueryFromState(string queryString, UserState.States stateType)
        {
            RQquery query = null;

            state = (ViewState)UserState.Get(stateType);
            if (state == null)
            {
                if (string.IsNullOrEmpty(queryString))
                    query = new RQquery("$recent$recent additions", "recent");
                else
                    query = new RQquery(queryString);
                state = new ViewState(stateType); //, queryString);
                state.query = query;
                //state.Save();
            }
            else
            {
                string querytest;
                UserSettingsService us = new UserSettingsService();

                query = (RQquery)state.query;
                if (! string.IsNullOrEmpty(queryString) && queryString.StartsWith("$") && queryString.LastIndexOf("$") > 1)
                    querytest = queryString.Substring(0, queryString.LastIndexOf("$")+1) + query.QueryString;
                else
                    querytest = query.QueryString;
                //if (   (! string.IsNullOrEmpty(queryString) && querytest != queryString) 
                //    || (query.QueryExternal == "" && us.GetIncludeExternal() == true) 
                //    || (query.QueryExternal != "" && us.GetIncludeExternal() == false) )
                //{
                //    query = new RQquery(! string.IsNullOrEmpty(queryString) ? queryString : query.QueryString);
                //    query.QueryExternal = us.GetIncludeExternal() == true ? "003" : "";
                //    state.query = query;
                //    //state.Save();
                //}
                if (!string.IsNullOrEmpty(queryString) && querytest != queryString)
                    query = new RQquery(! string.IsNullOrEmpty(queryString) ? queryString : query.QueryString);
                query.QueryExternal = us.GetIncludeExternal() == true ? "003" : "";
                state.query = query;
            }
            return query;
        }
Ejemplo n.º 26
0
        public static string AddUpload(int objectId, string filename, bool @public, string emailOnComplete,
            string message)
        {
            if (string.IsNullOrEmpty(MainForm.Conf.YouTubeUsername))
            {
                return LocRm.GetString("YouTubeAddSettings");
            }
            if (UploadFiles.SingleOrDefault(p => p.Filename == filename) != null)
                return LocRm.GetString("YouTubeMovieInQueue");

            if (UploadFiles.Count == 40)
                return LocRm.GetString("YouTubeQueueFull");

            int i = MainForm.Conf.UploadedVideos.IndexOf(filename, StringComparison.Ordinal);
            if (i != -1)
            {
                if (emailOnComplete != "")
                {
                    string cfg = MainForm.Conf.UploadedVideos.Substring(i);
                    string vid = cfg.Substring(cfg.IndexOf("|", StringComparison.Ordinal) + 1);
                    if (vid.IndexOf(",", StringComparison.Ordinal) != -1)
                        vid = vid.Substring(0, vid.IndexOf(",", StringComparison.Ordinal));
                    SendYouTubeMails(emailOnComplete, message, vid);
                    return LocRm.GetString("YouTubUploadedAlreadyNotificationsSent");
                }
                return LocRm.GetString("YouTubUploadedAlready");
            }

            var us = new UserState(objectId, filename, emailOnComplete, message, @public);
            UploadFiles.Enqueue(us);

            if (_uploader == null || !_uploader.IsAlive)
            {
                _uploader = new Thread(Upload) { Name = "YouTube Uploader", IsBackground = false, Priority = ThreadPriority.Normal };
                _uploader.Start();
            }

            return LocRm.GetString("YouTubeMovieAdded");
        }
Ejemplo n.º 27
0
		public void setState(UserState state)
		{
			switch (userState)                  // Onceki state i terket.
			{
			case UserState.LOBBY:
				quitStateLobby(); break;
			case UserState.QUEUE:
				quitStateQueue(); break;
			case UserState.GAME:
				quitStateGame(); break;
			}
			userState = state;
			switch (state)                      // yeni state e gir.
			{
			case UserState.LOBBY:
				setStateLobby(); break;
			case UserState.QUEUE:
				setStateQueue(); break;
			case UserState.GAME:
				setStateGame(); break;
			}
			

		}
Ejemplo n.º 28
0
 public void UserStateChanged(string roomID,User user,UserState state)
 {
     TabPage page = pages [roomID];
     ChatControl cht = (ChatControl)page.Controls [0];
     cht.UserStateChanged(user,state);
 }
Ejemplo n.º 29
0
 public ClinicBot(UserState userState, ConversationState conversationState, T dialog)
 {
     _userState         = userState;
     _conversationState = conversationState;
     _dialog            = dialog;
 }
Ejemplo n.º 30
0
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddBot <WelcomeMessageWithAccessorBot>(options =>
            {
                var secretKey   = Configuration.GetSection("botFileSecret")?.Value;
                var botFilePath = Configuration.GetSection("botFilePath")?.Value;

                // Loads .bot configuration file and adds a singleton that your Bot can access through dependency injection.
                var botConfig = BotConfiguration.Load(botFilePath ?? @".\BotConfiguration.bot", secretKey);
                services.AddSingleton(sp => botConfig ?? throw new InvalidOperationException($"The .bot config file could not be loaded. ({botConfig})"));

                // Retrieve current endpoint.
                var environment = _isProduction ? "production" : "development";
                var service     = botConfig.Services.Where(s => s.Type == "endpoint" && s.Name == environment).FirstOrDefault();
                if (!(service is EndpointService endpointService))
                {
                    throw new InvalidOperationException($"The .bot file does not contain an endpoint with name '{environment}'.");
                }
                options.CredentialProvider = new SimpleCredentialProvider(endpointService.AppId, endpointService.AppPassword);



                IStorage dataStore = new MemoryStorage();

                var conversationState = new ConversationState(dataStore);
                options.State.Add(conversationState);

                // Create and add user state.
                var userState = new UserState(dataStore);
                options.State.Add(userState);

                options.Middleware.Add(new SimplifiedEchoBotMiddleware1());
                options.Middleware.Add(new SimplifiedEchoBotMiddleware2());
                options.Middleware.Add(new SimplifiedEchoBotMiddleware3());
            });

            services.AddSingleton(sp =>
            {
                // We need to grab the conversationState we added on the options in the previous step.
                var options = sp.GetRequiredService <IOptions <BotFrameworkOptions> >().Value;
                if (options == null)
                {
                    throw new InvalidOperationException("BotFrameworkOptions must be configured prior to setting up the State Accessors");
                }

                var conversationState = options.State.OfType <ConversationState>().FirstOrDefault();
                if (conversationState == null)
                {
                    throw new InvalidOperationException("ConversationState must be defined and added before adding conversation-scoped state accessors.");
                }

                var userState = options.State.OfType <UserState>().FirstOrDefault();
                if (userState == null)
                {
                    throw new InvalidOperationException("UserState must be defined and added before adding user-scoped state accessors.");
                }

                // The dialogs will need a state store accessor. Creating it here once (on-demand) allows the dependency injection
                // to hand it to our IBot class that is create per-request.
                var accessors = new DialogBotConversationStateAndUserStateAccessor(conversationState, userState)
                {
                    ConversationDialogState = conversationState.CreateProperty <DialogState>("DialogState"),
                    WelcomeUserState        = userState.CreateProperty <WelcomeUserState>(DialogBotConversationStateAndUserStateAccessor.WelcomeUserName),
                };
                return(accessors);
            });
        }
Ejemplo n.º 31
0
 public EchoBot(ConversationState conversationState, UserState userState, ILogger <EchoBot> logger) : base(conversationState, userState, logger)
 {
 }
Ejemplo n.º 32
0
        public async Task AdaptiveDialogBotTurnState()
        {
            // Arrange
            var logger = NullLogger <AdaptiveDialogBot> .Instance;

            var storage                    = new MemoryStorage();
            var conversationState          = new ConversationState(storage);
            var userState                  = new UserState(storage);
            var skillConversationIdFactory = new SkillConversationIdFactory(storage);
            var languagePolicy             = new LanguagePolicy("en-US");

            var resourceExplorer = new ResourceExplorer();
            var resourceProvider = new MockResourceProvider(resourceExplorer);

            resourceProvider.Add("main.dialog", new MockResource("{ \"$kind\": \"Microsoft.AdaptiveDialog\" }"));
            resourceExplorer.AddResourceProvider(resourceProvider);

            var botFrameworkClientMock = new Mock <BotFrameworkClient>();

            var botFrameworkAuthenticationMock = new Mock <BotFrameworkAuthentication>();

            botFrameworkAuthenticationMock.Setup(bfa => bfa.CreateBotFrameworkClient()).Returns(botFrameworkClientMock.Object);

            // The test dialog being used here happens to not send anything so we only need to mock the type.
            var adapterMock = new Mock <BotAdapter>();

            // ChannelId and Conversation.Id are required for ConversationState and
            // ChannelId and From.Id are required for UserState.
            var activity = new Activity
            {
                ChannelId    = "test-channel",
                Conversation = new ConversationAccount {
                    Id = "test-conversation-id"
                },
                From = new ChannelAccount {
                    Id = "test-id"
                }
            };

            var turnContext = new TurnContext(adapterMock.Object, activity);

            var telemetryClient = new NullBotTelemetryClient();

            // Act
            var bot = new AdaptiveDialogBot(
                "main.dialog",
                "main.lg",
                resourceExplorer,
                conversationState,
                userState,
                skillConversationIdFactory,
                languagePolicy,
                botFrameworkAuthenticationMock.Object,
                telemetryClient,
                logger: logger);

            await bot.OnTurnAsync(turnContext, CancellationToken.None);

            // Assert
            Assert.NotNull(turnContext.TurnState.Get <BotFrameworkClient>());
            Assert.NotNull(turnContext.TurnState.Get <SkillConversationIdFactoryBase>());
            Assert.NotNull(turnContext.TurnState.Get <ConversationState>());
            Assert.NotNull(turnContext.TurnState.Get <UserState>());
            Assert.NotNull(turnContext.TurnState.Get <ResourceExplorer>());
            Assert.NotNull(turnContext.TurnState.Get <LanguageGenerator>());
            Assert.NotNull(turnContext.TurnState.Get <LanguageGeneratorManager>());
            Assert.NotNull(turnContext.TurnState.Get <LanguagePolicy>());
            Assert.NotNull(turnContext.TurnState.Get <IBotTelemetryClient>());

            Assert.Null(turnContext.TurnState.Get <MemoryScope>());
            Assert.Null(turnContext.TurnState.Get <Memory.IPathResolver>());
            Assert.Null(turnContext.TurnState.Get <Dialog>());

            // Assert no TestOptions
            var testOptionsAccessor = conversationState.CreateProperty <JObject>("TestOptions");

            Assert.Null(await testOptionsAccessor.GetAsync(turnContext));
        }
Ejemplo n.º 33
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers().AddNewtonsoftJson();

            services.AddSingleton <IConfiguration>(this.Configuration);

            // Create the credential provider to be used with the Bot Framework Adapter.
            services.AddSingleton <ICredentialProvider, ConfigurationCredentialProvider>();
            services.AddSingleton <BotAdapter>(sp => (BotFrameworkHttpAdapter)sp.GetService <IBotFrameworkHttpAdapter>());

            // Register AuthConfiguration to enable custom claim validation.
            services.AddSingleton <AuthenticationConfiguration>();

            // Register the skills client and skills request handler.
            services.AddSingleton <SkillConversationIdFactoryBase, SkillConversationIdFactory>();
            services.AddHttpClient <BotFrameworkClient, SkillHttpClient>();
            services.AddSingleton <ChannelServiceHandler, SkillHandler>();

            // Load settings
            var settings = new BotSettings();

            Configuration.Bind(settings);

            IStorage storage = null;

            // Configure storage for deployment
            if (!string.IsNullOrEmpty(settings.CosmosDb.AuthKey))
            {
                storage = new CosmosDbPartitionedStorage(settings.CosmosDb);
            }
            else
            {
                Console.WriteLine("The settings of CosmosDbStorage is incomplete, please check following settings: settings.CosmosDb");
                storage = new MemoryStorage();
            }

            services.AddSingleton(storage);
            var userState         = new UserState(storage);
            var conversationState = new ConversationState(storage);

            var botFile = Configuration.GetSection("bot").Get <string>();

            // manage all bot resources
            var resourceExplorer = new ResourceExplorer().AddFolder(botFile);

            services.AddSingleton(userState);
            services.AddSingleton(conversationState);
            services.AddSingleton(resourceExplorer);

            services.AddSingleton <IBotFrameworkHttpAdapter, BotFrameworkHttpAdapter>((s) =>
            {
                HostContext.Current.Set <IConfiguration>(Configuration);

                var adapter = new BotFrameworkHttpAdapter(new ConfigurationCredentialProvider(this.Configuration));
                adapter
                .UseStorage(storage)
                .UseState(userState, conversationState);

                if (!string.IsNullOrEmpty(settings.BlobStorage.ConnectionString) && !string.IsNullOrEmpty(settings.BlobStorage.Container))
                {
                    adapter.Use(new TranscriptLoggerMiddleware(new AzureBlobTranscriptStore(settings.BlobStorage.ConnectionString, settings.BlobStorage.Container)));
                }
                else
                {
                    Console.WriteLine("The settings of TranscriptLoggerMiddleware is incomplete, please check following settings: settings.BlobStorage.ConnectionString, settings.BlobStorage.Container");
                }

                adapter.OnTurnError = async(turnContext, exception) =>
                {
                    await turnContext.SendActivityAsync(exception.Message).ConfigureAwait(false);
                    await conversationState.ClearStateAsync(turnContext).ConfigureAwait(false);
                    await conversationState.SaveChangesAsync(turnContext).ConfigureAwait(false);
                };
                return(adapter);
            });

            services.AddSingleton <IBot, ComposerBot>();
        }
Ejemplo n.º 34
0
 public void SetState(UserState state)
 {
     m_State = state;
 }
Ejemplo n.º 35
0
        /// <summary>
        /// This method gets called by the runtime. Use this method to add services to the container.
        /// </summary>
        /// <param name="services">The <see cref="IServiceCollection"/> specifies the contract for a collection of service descriptors.</param>
        /// <seealso cref="IStatePropertyAccessor{T}"/>
        /// <seealso cref="https://docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/dependency-injection"/>
        /// <seealso cref="https://docs.microsoft.com/en-us/azure/bot-service/bot-service-manage-channels?view=azure-bot-service-4.0"/>
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddBot <SyntinelBot>(options =>
            {
                var secretKey   = Configuration.GetSection("BotFileSecret")?.Value;
                var botFilePath = Configuration.GetSection("BotFilePath")?.Value;

                // Loads .bot configuration file and adds a singleton that your Bot can access through dependency injection.
                var botConfig = BotConfiguration.Load(botFilePath ?? @".\syntinel.bot", secretKey);
                services.AddSingleton(sp => botConfig ?? throw new InvalidOperationException($"The .bot config file could not be loaded. ({botConfig})"));

                // Retrieve current endpoint.
                var environment = _isProduction ? "production" : "development";

                // The default value for reference and nullable types is null.
                var service = botConfig.Services.FirstOrDefault(s => s.Type == "endpoint" && s.Name == environment);
                if (!(service is EndpointService endpointService))
                {
                    throw new InvalidOperationException($"The .bot file does not contain an endpoint with name '{environment}'.");
                }

                // Sets bot credentials
                options.CredentialProvider = new SimpleCredentialProvider(endpointService.AppId, endpointService.AppPassword);

                // Catches any errors that occur during a conversation turn and logs them.
                options.OnTurnError = async(context, exception) =>
                {
                    _logger.LogError($"Exception caught : {exception}");
                    await context.SendActivityAsync("Sorry, it looks like something went wrong.");
                };

                // The Memory Storage used here is for local bot debugging only. When the bot
                // is restarted, everything stored in memory will be gone.
                // IStorage dataStore = new MemoryStorage();

                // For production bots use the Azure Blob or
                // Azure CosmosDB storage providers. For the Azure
                // based storage providers, add the Microsoft.Bot.Builder.Azure
                // Nuget package to your solution. That package is found at:
                // https://www.nuget.org/packages/Microsoft.Bot.Builder.Azure/
                // Uncomment the following lines to use Azure Blob Storage
                // //Storage configuration name or ID from the .bot file.
                const string StorageConfigurationId = "SyntinelBot";
                var cosmoConfig = botConfig.FindServiceByNameOrId(StorageConfigurationId);
                if (!(cosmoConfig is CosmosDbService cosmoStorageConfig))
                {
                    throw new InvalidOperationException($"The .bot file does not contain a cosmo storage with name '{StorageConfigurationId}'.");
                }

                IStorage dataStore = new CosmosDbStorage(new CosmosDbStorageOptions
                {
                    CollectionId     = cosmoStorageConfig.Collection,
                    CosmosDBEndpoint = new Uri(cosmoStorageConfig.Endpoint),
                    DatabaseId       = cosmoStorageConfig.Database,
                    AuthKey          = cosmoStorageConfig.Key,
                });

                _botStore = dataStore;

                // Create Conversation State object.
                // The Conversation State object is where we persist anything at the conversation-scope.
                _conversationState = new ConversationState(dataStore);
                _userState         = new UserState(dataStore);
                _serviceState      = new ServiceState(dataStore);
            });

            // https://docs.microsoft.com/en-us/azure/bot-service/bot-builder-tutorial-persist-user-inputs?view=azure-bot-service-4.0&tabs=csharp
            // Create and register state accesssors.
            // Acessors created here are passed into the IBot-derived class on every turn.
            services.AddSingleton <BotAccessors>(sp =>
            {
                if (_conversationState == null)
                {
                    throw new InvalidOperationException("ConversationState must be defined and added before adding conversation-scoped state accessors.");
                }

                if (_userState == null)
                {
                    throw new InvalidOperationException("UserState must be defined and added before adding user-scoped state accessors.");
                }

                if (_serviceState == null)
                {
                    throw new InvalidOperationException("ServiceState must be defined and added before adding service-scoped state accessors.");
                }

                // Create the custom state accessor.
                // State accessors enable other components to read and write individual properties of state.
                var accessors = new BotAccessors(_conversationState, _userState, _serviceState)
                {
                    UserDataAccessor         = _userState.CreateProperty <UserData>(BotAccessors.UserDataName),
                    JobDataAccessor          = _serviceState.CreateProperty <Dictionary <string, Job> >(BotAccessors.JobDataName),
                    NotificationDataAccessor = _serviceState.CreateProperty <Dictionary <string, Notification> >(BotAccessors.NotificationDataName),
                    UserRegistryAccessor     = _serviceState.CreateProperty <RegisteredUsers>(BotAccessors.UserRegistryName),
                    ConversationDialogState  = _conversationState.CreateProperty <DialogState>(BotAccessors.DialogStateName),
                };

                return(accessors);
            });
        }
Ejemplo n.º 36
0
        public void ConfigureServices(IServiceCollection services)
        {
            // Load the connected services from .bot file.
            var botFilePath   = Configuration.GetSection("botFilePath")?.Value;
            var botFileSecret = Configuration.GetSection("botFileSecret")?.Value;
            var botConfig     = BotConfiguration.Load(botFilePath, botFileSecret);

            services.AddSingleton(sp => botConfig ?? throw new InvalidOperationException($"The .bot config file could not be loaded."));

            // Get default locale from appsettings.json
            var defaultLocale = Configuration.GetSection("defaultLocale").Get <string>();

            // Initializes your bot service clients and adds a singleton that your Bot can access through dependency injection.
            var connectedServices = new BotServices(botConfig);

            services.AddSingleton(sp => connectedServices);

            // Initialize Bot State
            var cosmosDbService = botConfig.Services.FirstOrDefault(s => s.Type == ServiceTypes.CosmosDB) ?? throw new Exception("Please configure your CosmosDb service in your .bot file.");
            var cosmosDb        = cosmosDbService as CosmosDbService;
            var cosmosOptions   = new CosmosDbStorageOptions()
            {
                CosmosDBEndpoint = new Uri(cosmosDb.Endpoint),
                AuthKey          = cosmosDb.Key,
                CollectionId     = cosmosDb.Collection,
                DatabaseId       = cosmosDb.Database,
            };
            var dataStore         = new CosmosDbStorage(cosmosOptions);
            var userState         = new UserState(dataStore);
            var conversationState = new ConversationState(dataStore);

            services.AddSingleton(dataStore);
            services.AddSingleton(userState);
            services.AddSingleton(conversationState);
            services.AddSingleton(new BotStateSet(userState, conversationState));

            // Add the bot with options
            services.AddBot <$safeprojectname$>(options =>
            {
                // Load the connected services from .bot file.
                var environment = _isProduction ? "production" : "development";
                var service     = botConfig.Services.FirstOrDefault(s => s.Type == ServiceTypes.Endpoint && s.Name == environment);
                if (!(service is EndpointService endpointService))
                {
                    throw new InvalidOperationException($"The .bot file does not contain an endpoint with name '{environment}'.");
                }

                options.CredentialProvider = new SimpleCredentialProvider(endpointService.AppId, endpointService.AppPassword);

                // Telemetry Middleware (logs activity messages in Application Insights)
                var appInsightsService = botConfig.Services.FirstOrDefault(s => s.Type == ServiceTypes.AppInsights) ?? throw new Exception("Please configure your AppInsights connection in your .bot file.");
                var instrumentationKey = (appInsightsService as AppInsightsService).InstrumentationKey;
                var appInsightsLogger  = new TelemetryLoggerMiddleware(instrumentationKey, logUserName: true, logOriginalMessage: true);
                options.Middleware.Add(appInsightsLogger);

                // Catches any errors that occur during a conversation turn and logs them to AppInsights.
                options.OnTurnError = async(context, exception) =>
                {
                    await context.SendActivityAsync(MainStrings.ERROR);
                    connectedServices.TelemetryClient.TrackException(exception);
                };

                // Transcript Middleware (saves conversation history in a standard format)
                var storageService       = botConfig.Services.FirstOrDefault(s => s.Type == ServiceTypes.BlobStorage) ?? throw new Exception("Please configure your Azure Storage service in your .bot file.");
                var blobStorage          = storageService as BlobStorageService;
                var transcriptStore      = new AzureBlobTranscriptStore(blobStorage.ConnectionString, blobStorage.Container);
                var transcriptMiddleware = new TranscriptLoggerMiddleware(transcriptStore);
                options.Middleware.Add(transcriptMiddleware);

                // Typing Middleware (automatically shows typing when the bot is responding/working)
                options.Middleware.Add(new ShowTypingMiddleware());

                // Locale Middleware (sets UI culture based on Activity.Locale)
                options.Middleware.Add(new SetLocaleMiddleware(defaultLocale ?? "en-us"));

                // Autosave State Middleware (saves bot state after each turn)
                options.Middleware.Add(new AutoSaveStateMiddleware(userState, conversationState));
            });
        }
Ejemplo n.º 37
0
 public UserProfile(string name, string id, bool friend, UserState state, Texture2D image) : this(name, id, id, friend, state, image)
 {
 }
Ejemplo n.º 38
0
 public StateBotAccessors(ConversationState conversationState, UserState userState)
 {
     ConversationState = conversationState ?? throw new ArgumentNullException(nameof(conversationState));
     UserState         = userState ?? throw new ArgumentNullException(nameof(userState));
 }
Ejemplo n.º 39
0
 public StateBot(ConversationState conversationState, UserState userState)
 {
     _conversationState = conversationState;
     _userState         = userState;
 }
Ejemplo n.º 40
0
 public static IMessage ChangeState(UserState state)
 {
     return MessageHelper.BuildMessage(MessageHeaders.CHANGE_STATE, writer => writer.WriteUserState(state));
 }
Ejemplo n.º 41
0
 public static void DeleteUserState(UserState userState)
 {
     UserStateService.DeleteUserState(userState);
 }
Ejemplo n.º 42
0
        /// <summary>
        /// This method gets called by the runtime. Use this method to add services to the container.
        /// </summary>
        /// <param name="services">The <see cref="IServiceCollection"/> specifies the contract for a collection of service descriptors.</param>
        /// <seealso cref="IStatePropertyAccessor{T}"/>
        /// <seealso cref="https://docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/dependency-injection"/>
        /// <seealso cref="https://docs.microsoft.com/en-us/azure/bot-service/bot-service-manage-channels?view=azure-bot-service-4.0"/>
        public void ConfigureServices(IServiceCollection services)
        {
            var secretKey   = Configuration.GetSection("botFileSecret")?.Value;
            var botFilePath = Configuration.GetSection("botFilePath")?.Value;

            if (!File.Exists(botFilePath))
            {
                throw new FileNotFoundException($"The .bot configuration file was not found. botFilePath: {botFilePath}");
            }

            // Loads .bot configuration file and adds a singleton that your Bot can access through dependency injection.
            BotConfiguration botConfig = null;

            try
            {
                botConfig = BotConfiguration.Load(botFilePath, secretKey);
            }
            catch
            {
                var msg = @"Error reading bot file. Please ensure you have valid botFilePath and botFileSecret set for your environment.
        - You can find the botFilePath and botFileSecret in the Azure App Service application settings.
        - If you are running this bot locally, consider adding a appsettings.json file with botFilePath and botFileSecret.
        - See https://aka.ms/about-bot-file to learn more about .bot file its use and bot configuration.
        ";
                throw new InvalidOperationException(msg);
            }

            services.AddSingleton(sp => botConfig ?? throw new InvalidOperationException($"The .bot configuration file could not be loaded. botFilePath: {botFilePath}"));

            // Retrieve current endpoint.
            var environment = _isProduction ? "production" : "development";
            var service     = botConfig.Services.FirstOrDefault(s => s.Type == "endpoint" && s.Name == environment);

            if (service == null && _isProduction)
            {
                // Attempt to load development environment
                service = botConfig.Services.Where(s => s.Type == "endpoint" && s.Name == "development").FirstOrDefault();
            }

            if (!(service is EndpointService endpointService))
            {
                throw new InvalidOperationException($"The .bot file does not contain an endpoint with name '{environment}'.");
            }

            // Memory Storage is for local bot debugging only. When the bot is restarted, everything stored in memory will be gone.
            IStorage dataStore = new MemoryStorage();

            // For production bots use the Azure Blob or
            // Azure CosmosDB storage providers. For the Azure
            // based storage providers, add the Microsoft.Bot.Builder.Azure
            // Nuget package to your solution. That package is found at:
            // https://www.nuget.org/packages/Microsoft.Bot.Builder.Azure/
            // Un-comment the following lines to use Azure Blob Storage
            // // Storage configuration name or ID from the .bot file.
            // const string StorageConfigurationId = "<STORAGE-NAME-OR-ID-FROM-BOT-FILE>";
            // var blobConfig = botConfig.FindServiceByNameOrId(StorageConfigurationId);
            // if (!(blobConfig is BlobStorageService blobStorageConfig))
            // {
            //    throw new InvalidOperationException($"The .bot file does not contain an blob storage with name '{StorageConfigurationId}'.");
            // }
            // // Default container name.
            // const string DefaultBotContainer = "<DEFAULT-CONTAINER>";
            // var storageContainer = string.IsNullOrWhiteSpace(blobStorageConfig.Container) ? DefaultBotContainer : blobStorageConfig.Container;
            // IStorage dataStore = new Microsoft.Bot.Builder.Azure.AzureBlobStorage(blobStorageConfig.ConnectionString, storageContainer);

            services.AddBot <dialogBotBot>(options =>
            {
                options.CredentialProvider = new ConfigurationCredentialProvider(Configuration);
                //options.CredentialProvider = new SimpleCredentialProvider(endpointService.AppId, endpointService.AppPassword);

                // Catches any errors that occur during a conversation turn and logs them to currently
                // configured ILogger.
                ILogger logger = _loggerFactory.CreateLogger <dialogBotBot>();

                options.OnTurnError = async(context, exception) =>
                {
                    logger.LogError($"Exception caught : {exception}");
                    await context.SendActivityAsync("Sorry, it looks like something went wrong.");
                };

                //Add middleware
                options.Middleware.Add(new Middleware());

                // Create and add conversation state.
                var conversationState = new ConversationState(dataStore);
                options.State.Add(conversationState);

                // Create and add user state.
                var userState = new UserState(dataStore);
                options.State.Add(userState);
            });

            services.AddSingleton <dialogBotAccessors>(sp =>
            {
                var options = sp.GetRequiredService <IOptions <BotFrameworkOptions> >().Value;
                // Create the custom state accessor.
                // State accessors enable other components to read and write individual properties of state.
                //var userState = options.State.OfType<UserState>().FirstOrDefault();
                var conversationState = options.State.OfType <ConversationState>().FirstOrDefault();
                if (conversationState == null)
                {
                    throw new InvalidOperationException("ConversationState must be defined and added before adding conversation-scoped state accessors.");
                }

                var userState = options.State.OfType <UserState>().FirstOrDefault();
                if (userState == null)
                {
                    throw new InvalidOperationException("UserState must be defined and added before adding user-scoped state accessors.");
                }

                var accessors = new dialogBotAccessors(conversationState, userState)
                {
                    CounterState            = conversationState.CreateProperty <CounterState>(dialogBotAccessors.CounterStateName),
                    ConversationDialogState = conversationState.CreateProperty <DialogState>("DialogState"),
                    UserProfile             = userState.CreateProperty <UserProfile>("UserProfile"),
                };

                return(accessors);
            });

            // Create and register a LUIS recognizer.
            services.AddSingleton(sp =>
            {
                // Set up Luis
                var luisApp = new LuisApplication(
                    applicationId: "8d5bf38e-108c-47f3-a03f-84c4da0aa8c9",
                    endpointKey: "7f267a067ce249639d74e9c23c9b3f7e",
                    endpoint: "https://westus.api.cognitive.microsoft.com/luis/v2.0/apps/8d5bf38e-108c-47f3-a03f-84c4da0aa8c9?verbose=true&timezoneOffset=-360&subscription-key=7f267a067ce249639d74e9c23c9b3f7e&q=");
                // Specify LUIS options. These may vary for your bot.
                var luisPredictionOptions = new LuisPredictionOptions
                {
                    IncludeAllIntents = true,
                };
                return(new LuisRecognizer(
                           application: luisApp,
                           predictionOptions: luisPredictionOptions,
                           includeApiResults: true));
            });

            // Create and register a QnA service and knowledgebase
            services.AddSingleton(sp =>
            {
                var hostPath        = "https://pedroqna.azurewebsites.net/qnamaker";
                var endpointKey     = "647d6f22-f64f-4732-a87f-ee7c48a2b1f7";
                var knowledgebaseId = "7e7af984-c985-4211-8ed2-923fed042f9f";
                var qnaOptions      = float.TryParse("0.4F", out float scoreThreshold)
                    ? new QnAMakerOptions
                {
                    ScoreThreshold = scoreThreshold,
                    Top            = 1
                } : null;
                return(new QnAMaker(
                           new QnAMakerEndpoint
                {
                    EndpointKey = endpointKey,
                    Host = hostPath,
                    KnowledgeBaseId = knowledgebaseId,
                },
                           qnaOptions));
            });
        }
Ejemplo n.º 43
0
 public static UserState AddUserState(UserState userState)
 {
     return(UserStateService.AddUserState(userState));
 }
Ejemplo n.º 44
0
    public float dashStopTime           = 0; //本次dash 停止时间

    public PC2dStateManager()
    {
        lastState      = currentState = UserState.Start;
        stateEnterTime = Time.time;
    }
Ejemplo n.º 45
0
        /// <summary>
        /// This method gets called by the runtime. Use this method to add services to the container.
        /// </summary>
        /// <param name="services">The <see cref="IServiceCollection"/> specifies the contract for a collection of service descriptors.</param>
        /// <seealso cref="IStatePropertyAccessor{T}"/>
        /// <seealso cref="https://docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/dependency-injection"/>
        /// <seealso cref="https://docs.microsoft.com/en-us/azure/bot-service/bot-service-manage-channels?view=azure-bot-service-4.0"/>
        public void ConfigureServices(IServiceCollection services)
        {
            var secretKey   = Configuration.GetSection("botFileSecret")?.Value;
            var botFilePath = Configuration.GetSection("botFilePath")?.Value;

            if (!File.Exists(botFilePath))
            {
                throw new FileNotFoundException(
                          $"The .bot configuration file was not found. botFilePath: {botFilePath}");
            }

            // Loads .bot configuration file and adds a singleton that your Bot can access through dependency injection.
            BotConfiguration botConfig = null;

            try
            {
                botConfig = BotConfiguration.Load(botFilePath, secretKey);
            }
            catch
            {
                var msg =
                    @"Error reading bot file. Please ensure you have valid botFilePath and botFileSecret set for your environment.
        - You can find the botFilePath and botFileSecret in the Azure App Service application settings.
        - If you are running this bot locally, consider adding a appsettings.json file with botFilePath and botFileSecret.
        - See https://aka.ms/about-bot-file to learn more about .bot file its use and bot configuration.
        ";
                throw new InvalidOperationException(msg);
            }

            services.AddSingleton(sp =>
                                  botConfig ??
                                  throw new InvalidOperationException(
                                      $"The .bot configuration file could not be loaded. botFilePath: {botFilePath}"));

            // Retrieve current endpoint.
            var environment = _isProduction ? "production" : "development";
            var service     = botConfig.Services.FirstOrDefault(s => s.Type == "endpoint" && s.Name == environment);

            if (service == null && _isProduction)
            {
                // Attempt to load development environment
                service = botConfig.Services.FirstOrDefault(s => s.Type == "endpoint" && s.Name == "development");
            }

            if (!(service is EndpointService endpointService))
            {
                throw new InvalidOperationException(
                          $"The .bot file does not contain an endpoint with name '{environment}'.");
            }
            services.AddSingleton(endpointService);

            // Memory Storage is for local bot debugging only. When the bot
            // is restarted, everything stored in memory will be gone.
            IStorage dataStore = new MemoryStorage();

            // For production bots use the Azure Blob or
            // Azure CosmosDB storage providers. For the Azure
            // based storage providers, add the Microsoft.Bot.Builder.Azure
            // Nuget package to your solution. That package is found at:
            // https://www.nuget.org/packages/Microsoft.Bot.Builder.Azure/
            // Un-comment the following lines to use Azure Blob Storage
            // // Storage configuration name or ID from the .bot file.
            // const string StorageConfigurationId = "<STORAGE-NAME-OR-ID-FROM-BOT-FILE>";
            // var blobConfig = botConfig.FindServiceByNameOrId(StorageConfigurationId);
            // if (!(blobConfig is BlobStorageService blobStorageConfig))
            // {
            //    throw new InvalidOperationException($"The .bot file does not contain an blob storage with name '{StorageConfigurationId}'.");
            // }
            // // Default container name.
            // const string DefaultBotContainer = "<DEFAULT-CONTAINER>";
            // var storageContainer = string.IsNullOrWhiteSpace(blobStorageConfig.Container) ? DefaultBotContainer : blobStorageConfig.Container;
            // IStorage dataStore = new Microsoft.Bot.Builder.Azure.AzureBlobStorage(blobStorageConfig.ConnectionString, storageContainer);

            // Create and add conversation state.
            var conversationState = new ConversationState(dataStore);

            services.AddSingleton(conversationState);

            // Create and add conversation state.
            var userState = new UserState(dataStore);

            services.AddSingleton(userState);

            // Initialize Bot Connected Services client.
            var connectedServices = new BotServices(botConfig);

            services.AddSingleton(sp => connectedServices);

            // Add and configure Agent Framework
            services.AddAgentFramework();
            services.AddSingleton <IAgentContextProvider, AgentContextProvider>();
            services.AddSingleton <IEventAggregator>(_ => new ReplayEventAggregator(replayWindow: TimeSpan.FromSeconds(30)));
            services.Configure <AgentOptions>(options =>
            {
                options.EndpointHost = Environment.GetEnvironmentVariable("ENDPOINT_HOST")
                                       ?? Configuration.GetSection("AgentOptions:EndpointHost").Get <string>()
                                       ?? Environment.GetEnvironmentVariable("ASPNETCORE_URLS");
            });

            services.AddBot <AgentBotBot>(options =>
            {
                options.CredentialProvider =
                    new SimpleCredentialProvider(endpointService.AppId, endpointService.AppPassword);

                // Catches any errors that occur during a conversation turn and logs them to currently
                // configured ILogger.
                ILogger logger = _loggerFactory.CreateLogger <AgentBotBot>();

                options.OnTurnError = async(context, exception) =>
                {
                    logger.LogError($"Exception caught : {exception}");
                    await context.SendActivityAsync("Sorry, it looks like something went wrong.");
                };
            });
        }
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers().AddNewtonsoftJson();

            // Create the Bot Framework Adapter with error handling enabled.
            services.AddSingleton <IBotFrameworkHttpAdapter, AdapterWithErrorHandler>();
            // Create and register state accesssors.
            // Acessors created here are passed into the IBot-derived class on every turn.
            services.AddSingleton <PictureBotAccessors>(sp =>
            {
                var options = sp.GetRequiredService <IOptions <BotFrameworkOptions> >().Value;
                if (options == null)
                {
                    throw new InvalidOperationException("BotFrameworkOptions must be configured prior to setting up the state accessors");
                }

                var conversationState = services.BuildServiceProvider().GetService <ConversationState>();
                if (conversationState == null)
                {
                    throw new InvalidOperationException("ConversationState must be defined and added before adding conversation-scoped state   accessors.");
                }

                // Create the custom state accessor.
                // State accessors enable other components to read and write individual properties of state.
                var accessors = new PictureBotAccessors(conversationState)
                {
                    PictureState        = conversationState.CreateProperty <PictureState>(PictureBotAccessors.PictureStateName),
                    DialogStateAccessor = conversationState.CreateProperty <DialogState>("DialogState"),
                };

                return(accessors);
            });

            // Create and register a LUIS recognizer.
            services.AddSingleton(sp =>
            {
                var luisAppId    = Configuration.GetSection("luisAppId")?.Value;
                var luisAppKey   = Configuration.GetSection("luisAppKey")?.Value;
                var luisEndPoint = Configuration.GetSection("luisEndPoint")?.Value;

                // Get LUIS information
                var luisApp = new LuisApplication(luisAppId, luisAppKey, luisEndPoint);

                // Specify LUIS options. These may vary for your bot.
                var luisPredictionOptions = new LuisPredictionOptions
                {
                    IncludeAllIntents = true,
                };

                // Create the recognizer
                var recognizer = new LuisRecognizer(luisApp, luisPredictionOptions, true, null);
                return(recognizer);
            });

            services.AddSingleton(sp =>
            {
                string cogsBaseUrl = Configuration.GetSection("cogsBaseUrl")?.Value;
                string cogsKey     = Configuration.GetSection("cogsKey")?.Value;

                var credentials            = new ApiKeyServiceClientCredentials(cogsKey);
                TextAnalyticsClient client = new TextAnalyticsClient(credentials)
                {
                    Endpoint = cogsBaseUrl
                };

                return(client);
            });

            // Create the bot as a transient. In this case the ASP Controller is expecting an IBot.
            services.AddBot <Bots.PictureBot>(options =>
            {
                var appId      = Configuration.GetSection("MicrosoftAppId")?.Value;
                var appSecret  = Configuration.GetSection("MicrosoftAppPassword")?.Value; options.CredentialProvider = new SimpleCredentialProvider(appId, appSecret);                // Creates a logger for the application to use.
                ILogger logger = _loggerFactory.CreateLogger <PictureBot.Bots.PictureBot>();

                // Catches any errors that occur during a conversation turn and logs them.
                options.OnTurnError = async(context, exception) =>
                {
                    logger.LogError($"Exception caught : {exception}");
                    await context.SendActivityAsync("Sorry, it looks like something went wrong.");
                };

                // The Memory Storage used here is for local bot debugging only. When the bot
                // is restarted, everything stored in memory will be gone.
                var blobConnectionString = Configuration.GetSection("BlobStorageConnectionString")?.Value;
                var blobContainer        = Configuration.GetSection("BlobStorageContainer")?.Value;
                IStorage dataStore       = new Microsoft.Bot.Builder.Azure.AzureBlobStorage(blobConnectionString, blobContainer);

                // For production bots use the Azure Blob or
                // Azure CosmosDB storage providers. For the Azure
                // based storage providers, add the Microsoft.Bot.Builder.Azure
                // Nuget package to your solution. That package is found at:
                // https://www.nuget.org/packages/Microsoft.Bot.Builder.Azure/
                // Uncomment the following lines to use Azure Blob Storage
                // //Storage configuration name or ID from the .bot file.
                // const string StorageConfigurationId = "<STORAGE-NAME-OR-ID-FROM-BOT-FILE>";
                // var blobConfig = botConfig.FindServiceByNameOrId(StorageConfigurationId);
                // if (!(blobConfig is BlobStorageService blobStorageConfig))
                // {
                //    throw new InvalidOperationException($"The .bot file does not contain an blob storage with name '{StorageConfigurationId}'.");
                // }
                // // Default container name.
                // const string DefaultBotContainer = "botstate";
                // var storageContainer = string.IsNullOrWhiteSpace(blobStorageConfig.Container) ? DefaultBotContainer : blobStorageConfig.Container;
                // IStorage dataStore = new Microsoft.Bot.Builder.Azure.AzureBlobStorage(blobStorageConfig.ConnectionString, storageContainer);

                // Create Conversation State object.
                // The Conversation State object is where we persist anything at the conversation-scope.
                var userState         = new UserState(dataStore);
                var conversationState = new ConversationState(dataStore);

                // Create the User state.
                services.AddSingleton <UserState>(userState);

                // Create the Conversation state.
                services.AddSingleton <ConversationState>(conversationState);

                var middleware = options.Middleware;

                // Add middleware below with "middleware.Add(...."
                // Add Regex below
                middleware.Add(new RegExpRecognizerMiddleware()
                               .AddIntent("search", new Regex("search picture(?:s)*(.*)|search pic(?:s)*(.*)", RegexOptions.IgnoreCase))
                               .AddIntent("share", new Regex("share picture(?:s)*(.*)|share pic(?:s)*(.*)", RegexOptions.IgnoreCase))
                               .AddIntent("order", new Regex("order picture(?:s)*(.*)|order print(?:s)*(.*)|order pic(?:s)*(.*)", RegexOptions.IgnoreCase))
                               .AddIntent("help", new Regex("help(.*)", RegexOptions.IgnoreCase)));
            });

            services.AddMvc(options => options.EnableEndpointRouting = false);
        }
Ejemplo n.º 47
0
        public async Task AdaptiveDialogBotSetTestOptions()
        {
            // Arrange
            var logger = NullLogger <AdaptiveDialogBot> .Instance;

            var storage                    = new MemoryStorage();
            var conversationState          = new ConversationState(storage);
            var userState                  = new UserState(storage);
            var skillConversationIdFactory = new SkillConversationIdFactory(storage);
            var languagePolicy             = new LanguagePolicy("en-US");

            var resourceExplorer = new ResourceExplorer();
            var resourceProvider = new MockResourceProvider(resourceExplorer);

            resourceProvider.Add("main.dialog", new MockResource("{ \"$kind\": \"Microsoft.AdaptiveDialog\" }"));
            resourceExplorer.AddResourceProvider(resourceProvider);

            var botFrameworkClientMock = new Mock <BotFrameworkClient>();

            var botFrameworkAuthenticationMock = new Mock <BotFrameworkAuthentication>();

            botFrameworkAuthenticationMock.Setup(bfa => bfa.CreateBotFrameworkClient()).Returns(botFrameworkClientMock.Object);

            // The test dialog being used here happens to not send anything so we only need to mock the type.
            var adapterMock = new Mock <BotAdapter>();

            // Type "event" and Name of "SetTestOptions" should store Value in ConversationState.
            // ChannelId and Conversation.Id are required for ConversationState and
            // ChannelId and From.Id are required for UserState.
            var activity = new Activity
            {
                Type         = "event",
                Name         = "SetTestOptions",
                ChannelId    = "test-channel",
                Conversation = new ConversationAccount {
                    Id = "test-conversation-id"
                },
                From = new ChannelAccount {
                    Id = "test-id"
                },
                Value = new JObject {
                    { "randomSeed", new JValue(123) }, { "randomValue", new JValue(456) }
                }
            };

            var turnContext = new TurnContext(adapterMock.Object, activity);

            var telemetryClient = new NullBotTelemetryClient();

            // Act
            var bot = new AdaptiveDialogBot(
                "main.dialog",
                "main.lg",
                resourceExplorer,
                conversationState,
                userState,
                skillConversationIdFactory,
                languagePolicy,
                botFrameworkAuthenticationMock.Object,
                telemetryClient,
                logger: logger);

            await bot.OnTurnAsync(turnContext, CancellationToken.None);

            // Assert TestOptions are in Conversation
            var testOptionsAccessor = conversationState.CreateProperty <JObject>("TestOptions");

            Assert.Equal(123, (await testOptionsAccessor.GetAsync(turnContext)).GetValue("randomSeed"));
            Assert.Equal(456, (await testOptionsAccessor.GetAsync(turnContext)).GetValue("randomValue"));
        }
Ejemplo n.º 48
0
 private bool CheckUserState(UserState state)
 {
     return(_users.TrueForAll(x => x.State == state));
 }
 public EmptyBot1(ConversationState conversationState, UserState userState, T dialog, ILogger <DialogBot <T> > logger) : base(conversationState, userState, dialog, logger)
 {
 }
Ejemplo n.º 50
0
        private async Task InitializeSkill(DialogContext dc)
        {
            try
            {
                var skillDefinition    = dc.ActiveDialog.State[ActiveSkillStateKey] as SkillDefinition;
                var skillConfiguration = _skills[skillDefinition.Id];

                IStorage storage;

                if (skillConfiguration.CosmosDbOptions != null)
                {
                    var cosmosDbOptions = skillConfiguration.CosmosDbOptions;
                    cosmosDbOptions.CollectionId = skillDefinition.Name;
                    storage = new CosmosDbStorage(cosmosDbOptions);
                }
                else
                {
                    storage = new MemoryStorage();
                }

                // Initialize skill state
                var userState         = new UserState(storage);
                var conversationState = new ConversationState(storage);

                // Create skill instance
                try
                {
                    var skillType = Type.GetType(skillDefinition.Assembly);
                    _activatedSkill = (IBot)Activator.CreateInstance(skillType, skillConfiguration, conversationState, userState, _telemetryClient, null, true);
                }
                catch (Exception e)
                {
                    var message = $"Skill ({skillDefinition.Name}) could not be created.";
                    throw new InvalidOperationException(message, e);
                }

                _inProcAdapter = new InProcAdapter
                {
                    // set up skill turn error handling
                    OnTurnError = async(context, exception) =>
                    {
                        await context.SendActivityAsync(context.Activity.CreateReply(CommonResponses.ErrorMessage_SkillError));

                        await dc.Context.SendActivityAsync(new Activity(type : ActivityTypes.Trace, text : $"Skill Error: {exception.Message} | {exception.StackTrace}"));

                        // Log exception in AppInsights
                        _telemetryClient.TrackExceptionEx(exception, context.Activity);
                    },
                };

                _inProcAdapter.Use(new EventDebuggerMiddleware());
                _inProcAdapter.Use(new SetLocaleMiddleware(dc.Context.Activity.Locale ?? "en-us"));
                _inProcAdapter.Use(new AutoSaveStateMiddleware(userState, conversationState));
                _skillInitialized = true;
            }
            catch
            {
                // something went wrong initializing the skill, so end dialog cleanly and throw so the error is logged
                _skillInitialized = false;
                await dc.EndDialogAsync();

                throw;
            }
        }
Ejemplo n.º 51
0
 public UserStateChanged(User user, UserState previousState)
 {
     User          = user;
     PreviousState = previousState;
 }
Ejemplo n.º 52
0
        public override void Configure(IFunctionsHostBuilder builder)
        {
            var binDirectory  = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
            var rootDirectory = Directory.GetParent(binDirectory).FullName;

            var rootConfiguration = BuildConfiguration(rootDirectory);

            var settings = new BotSettings();

            rootConfiguration.Bind(settings);

            var services = builder.Services;

            services.AddSingleton <IConfiguration>(rootConfiguration);

            services.AddLogging();

            // Create the credential provider to be used with the Bot Framework Adapter.
            services.AddSingleton <ICredentialProvider, ConfigurationCredentialProvider>();
            services.AddSingleton <BotAdapter>(sp => (BotFrameworkHttpAdapter)sp.GetService <IBotFrameworkHttpAdapter>());

            // Register AuthConfiguration to enable custom claim validation.
            services.AddSingleton <AuthenticationConfiguration>();

            // Adaptive component registration
            ComponentRegistration.Add(new DialogsComponentRegistration());
            ComponentRegistration.Add(new DeclarativeComponentRegistration());
            ComponentRegistration.Add(new AdaptiveComponentRegistration());
            ComponentRegistration.Add(new LanguageGenerationComponentRegistration());
            ComponentRegistration.Add(new QnAMakerComponentRegistration());
            ComponentRegistration.Add(new LuisComponentRegistration());

            // This is for custom action component registration.
            //ComponentRegistration.Add(new CustomActionComponentRegistration());

            // Register the skills client and skills request handler.
            services.AddSingleton <SkillConversationIdFactoryBase, SkillConversationIdFactory>();
            services.AddHttpClient <BotFrameworkClient, SkillHttpClient>();
            services.AddSingleton <ChannelServiceHandler, SkillHandler>();

            // Register telemetry client, initializers and middleware
            services.AddApplicationInsightsTelemetry(settings.ApplicationInsights.InstrumentationKey);
            services.AddSingleton <ITelemetryInitializer, OperationCorrelationTelemetryInitializer>();
            services.AddSingleton <ITelemetryInitializer, TelemetryBotIdInitializer>();
            services.AddSingleton <IBotTelemetryClient, BotTelemetryClient>();
            services.AddSingleton <TelemetryLoggerMiddleware>(sp =>
            {
                var telemetryClient = sp.GetService <IBotTelemetryClient>();
                return(new TelemetryLoggerMiddleware(telemetryClient, logPersonalInformation: settings.Telemetry.LogPersonalInformation));
            });
            services.AddSingleton <TelemetryInitializerMiddleware>(sp =>
            {
                var httpContextAccessor       = sp.GetService <IHttpContextAccessor>();
                var telemetryLoggerMiddleware = sp.GetService <TelemetryLoggerMiddleware>();
                return(new TelemetryInitializerMiddleware(httpContextAccessor, telemetryLoggerMiddleware, settings.Telemetry.LogActivities));
            });

            // Storage
            IStorage storage;

            if (ConfigSectionValid(settings.CosmosDb.AuthKey))
            {
                storage = new CosmosDbPartitionedStorage(settings.CosmosDb);
            }
            else
            {
                storage = new MemoryStorage();
            }

            services.AddSingleton(storage);
            var userState         = new UserState(storage);
            var conversationState = new ConversationState(storage);

            services.AddSingleton(userState);
            services.AddSingleton(conversationState);

            // Resource explorer to track declarative assets
            var resourceExplorer = new ResourceExplorer().AddFolder(Path.Combine(rootDirectory, settings.Bot ?? "."));

            services.AddSingleton(resourceExplorer);

            // Adapter
            services.AddSingleton <IBotFrameworkHttpAdapter, BotFrameworkHttpAdapter>(s =>
            {
                // Retrieve required dependencies
                //IConfiguration configuration = s.GetService<IConfiguration>();
                IStorage storage    = s.GetService <IStorage>();
                UserState userState = s.GetService <UserState>();
                ConversationState conversationState = s.GetService <ConversationState>();
                TelemetryInitializerMiddleware telemetryInitializerMiddleware = s.GetService <TelemetryInitializerMiddleware>();

                var adapter = new BotFrameworkHttpAdapter(new ConfigurationCredentialProvider(rootConfiguration));

                adapter
                .UseStorage(storage)
                .UseBotState(userState, conversationState)
                .Use(new RegisterClassMiddleware <IConfiguration>(rootConfiguration))
                .Use(telemetryInitializerMiddleware);

                // Configure Middlewares
                ConfigureTranscriptLoggerMiddleware(adapter, settings);
                ConfigureInspectionMiddleWare(adapter, settings, s);
                ConfigureShowTypingMiddleWare(adapter, settings);

                adapter.OnTurnError = async(turnContext, exception) =>
                {
                    await turnContext.SendActivityAsync(exception.Message).ConfigureAwait(false);
                    await conversationState.ClearStateAsync(turnContext).ConfigureAwait(false);
                    await conversationState.SaveChangesAsync(turnContext).ConfigureAwait(false);
                };

                return(adapter);
            });

            var defaultLocale = rootConfiguration.GetValue <string>("defaultLanguage") ?? "en-us";

            var removeRecipientMention = settings?.Feature?.RemoveRecipientMention ?? false;

            // Bot
            services.AddSingleton <IBot>(s =>
                                         new ComposerBot(
                                             s.GetService <ConversationState>(),
                                             s.GetService <UserState>(),
                                             s.GetService <ResourceExplorer>(),
                                             s.GetService <BotFrameworkClient>(),
                                             s.GetService <SkillConversationIdFactoryBase>(),
                                             s.GetService <IBotTelemetryClient>(),
                                             GetRootDialog(Path.Combine(rootDirectory, settings.Bot)),
                                             defaultLocale,
                                             removeRecipientMention));
        }
Ejemplo n.º 53
0
 private void SetUserState(UserState state)
 {
     _users.ForEach(x => x.State = state);
 }
Ejemplo n.º 54
0
        public void ConfigureServices(IServiceCollection services)
        {
            // Load the connected services from .bot file.
            var botFilePath   = Configuration.GetSection("botFilePath")?.Value;
            var botFileSecret = Configuration.GetSection("botFileSecret")?.Value;
            var botConfig     = BotConfiguration.Load(botFilePath ?? @".\CalendarSkill.bot", botFileSecret);

            services.AddSingleton(sp => botConfig ?? throw new InvalidOperationException($"The .bot config file could not be loaded."));

            // Use Application Insights
            services.AddBotApplicationInsights(botConfig);

            // Initializes your bot service clients and adds a singleton that your Bot can access through dependency injection.
            var parameters         = Configuration.GetSection("parameters")?.Get <string[]>();
            var configuration      = Configuration.GetSection("configuration")?.GetChildren()?.ToDictionary(x => x.Key, y => y.Value as object);
            var supportedProviders = Configuration.GetSection("supportedProviders")?.Get <string[]>();
            var languageModels     = Configuration.GetSection("languageModels").Get <Dictionary <string, Dictionary <string, string> > >();
            var connectedServices  = new SkillConfiguration(botConfig, languageModels, supportedProviders, parameters, configuration);

            services.AddSingleton <ISkillConfiguration>(sp => connectedServices);

            // Initialize Bot State
            var cosmosDbService = botConfig.Services.FirstOrDefault(s => s.Type == ServiceTypes.CosmosDB) ?? throw new Exception("Please configure your CosmosDb service in your .bot file.");
            var cosmosDb        = cosmosDbService as CosmosDbService;
            var cosmosOptions   = new CosmosDbStorageOptions()
            {
                CosmosDBEndpoint = new Uri(cosmosDb.Endpoint),
                AuthKey          = cosmosDb.Key,
                CollectionId     = cosmosDb.Collection,
                DatabaseId       = cosmosDb.Database,
            };
            var dataStore         = new CosmosDbStorage(cosmosOptions);
            var userState         = new UserState(dataStore);
            var conversationState = new ConversationState(dataStore);

            services.AddSingleton(dataStore);
            services.AddSingleton(userState);
            services.AddSingleton(conversationState);
            services.AddSingleton(new BotStateSet(userState, conversationState));

            // Initialize calendar service client
            services.AddSingleton <IServiceManager, ServiceManager>();

            // Add the bot with options
            services.AddBot <CalendarSkill>(options =>
            {
                // Load the connected services from .bot file.
                var environment = _isProduction ? "production" : "development";
                var service     = botConfig.Services.FirstOrDefault(s => s.Type == ServiceTypes.Endpoint && s.Name == environment);
                if (!(service is EndpointService endpointService))
                {
                    throw new InvalidOperationException($"The .bot file does not contain an endpoint with name '{environment}'.");
                }

                options.CredentialProvider = new SimpleCredentialProvider(endpointService.AppId, endpointService.AppPassword);

                // Telemetry Middleware (logs activity messages in Application Insights)
                var appInsightsService = botConfig.Services.FirstOrDefault(s => s.Type == ServiceTypes.AppInsights) ?? throw new Exception("Please configure your AppInsights connection in your .bot file.");
                var instrumentationKey = (appInsightsService as AppInsightsService).InstrumentationKey;
                var sp = services.BuildServiceProvider();
                var telemetryClient   = sp.GetService <IBotTelemetryClient>();
                var appInsightsLogger = new TelemetryLoggerMiddleware(telemetryClient, logUserName: true, logOriginalMessage: true);
                options.Middleware.Add(appInsightsLogger);

                // Catches any errors that occur during a conversation turn and logs them to AppInsights.
                options.OnTurnError = async(context, exception) =>
                {
                    CultureInfo.CurrentUICulture = new CultureInfo(context.Activity.Locale);
                    await context.SendActivityAsync(context.Activity.CreateReply(CalendarSharedResponses.CalendarErrorMessage));
                    await context.SendActivityAsync(new Activity(type: ActivityTypes.Trace, text: $"Calendar Skill Error: {exception.Message} | {exception.StackTrace}"));
                    telemetryClient.TrackException(exception);
                };

                // Transcript Middleware (saves conversation history in a standard format)
                var storageService       = botConfig.Services.FirstOrDefault(s => s.Type == ServiceTypes.BlobStorage) ?? throw new Exception("Please configure your Azure Storage service in your .bot file.");
                var blobStorage          = storageService as BlobStorageService;
                var transcriptStore      = new AzureBlobTranscriptStore(blobStorage.ConnectionString, blobStorage.Container);
                var transcriptMiddleware = new TranscriptLoggerMiddleware(transcriptStore);
                options.Middleware.Add(transcriptMiddleware);

                // Typing Middleware (automatically shows typing when the bot is responding/working)
                var typingMiddleware = new ShowTypingMiddleware();
                options.Middleware.Add(typingMiddleware);

                options.Middleware.Add(new AutoSaveStateMiddleware(userState, conversationState));

                var defaultLocale = Configuration.GetSection("defaultLocale").Get <string>();
                options.Middleware.Add(new SetLocaleMiddleware(defaultLocale ?? "en"));
            });
        }
Ejemplo n.º 55
0
 public void Initialize()
 {
     _state = _saveMangager.Load <UserState>(state_fileName);
 }
Ejemplo n.º 56
0
 public static void ModifyUserState(UserState userState)
 {
     UserStateService.ModifyUserState(userState);
 }
Ejemplo n.º 57
0
 public WelcomeUserStateAccessors(UserState userState)
 {
     UserState = userState ?? throw new ArgumentNullException(nameof(userState));
 }
Ejemplo n.º 58
0
 public DialogAndWelcomeBot(ConversationState conversationState, UserState userState, T dialog, ILogger <DialogBot <T> > logger)
     : base(conversationState, userState, dialog, logger)
 {
     //_conversationState = ConversationState
 }
Ejemplo n.º 59
0
 /// <summary>
 /// Create user state
 /// </summary>
 public User(UserState state)
 {
     _state = state ?? new UserState();
 }
Ejemplo n.º 60
0
        private async Task InitializeSkill(DialogContext dc)
        {
            try
            {
                IStorage storage;

                if (_skillConfiguration.CosmosDbOptions != null)
                {
                    var cosmosDbOptions = _skillConfiguration.CosmosDbOptions;
                    cosmosDbOptions.CollectionId = _skillDefinition.Name;
                    storage = new CosmosDbStorage(cosmosDbOptions);
                }
                else
                {
                    storage = new MemoryStorage();
                }

                // Initialize skill state
                var userState         = new UserState(storage);
                var conversationState = new ConversationState(storage);

                // Create skill instance
                try
                {
                    var skillType = Type.GetType(_skillDefinition.Assembly);

                    // Have to use refined BindingFlags to allow for optional parameters on constructors.
                    _activatedSkill = (IBot)Activator.CreateInstance(
                        skillType,
                        BindingFlags.CreateInstance | BindingFlags.Public | BindingFlags.Instance | BindingFlags.OptionalParamBinding,
                        default(Binder),
                        new object[] { _skillConfiguration, conversationState, userState, _telemetryClient, true },
                        CultureInfo.CurrentCulture);
                }
                catch (Exception e)
                {
                    var message = $"Skill ({_skillDefinition.Name}) could not be created.";
                    throw new InvalidOperationException(message, e);
                }

                _inProcAdapter = new InProcAdapter
                {
                    // set up skill turn error handling
                    OnTurnError = async(context, exception) =>
                    {
                        await context.SendActivityAsync(_responseManager.GetResponse(CommonResponses.ErrorMessage_SkillError));

                        await dc.Context.SendActivityAsync(new Activity(type : ActivityTypes.Trace, text : $"Skill Error: {exception.Message} | {exception.StackTrace}"));

                        // Log exception in AppInsights
                        _telemetryClient.TrackExceptionEx(exception, context.Activity);
                    },
                };

                _inProcAdapter.Use(new EventDebuggerMiddleware());
                _inProcAdapter.Use(new SetLocaleMiddleware(dc.Context.Activity.Locale ?? "en-us"));
                _inProcAdapter.Use(new AutoSaveStateMiddleware(userState, conversationState));
                _skillInitialized = true;
            }
            catch
            {
                // something went wrong initializing the skill, so end dialog cleanly and throw so the error is logged
                _skillInitialized = false;
                await dc.EndDialogAsync();

                throw;
            }
        }