/// <summary> /// Saves UserInputAggregate to the database /// (V2.0, in the old version (V1.0) each entry was stored in a corresponding table) /// </summary> /// <param name="ma"></param> internal static void SaveUserInputSnapshotToDatabase(UserInputAggregate ma) { var sb = new StringBuilder(); sb.Append("INSERT INTO '"); sb.Append(Settings.DbTableUserInput_v2); sb.Append("' (time, tsStart, tsEnd, keyTotal, keyOther, keyBackspace, keyNavigate, clickTotal, clickOther, clickLeft, clickRight, scrollDelta, movedDistance) VALUES ("); sb.Append("strftime('%Y-%m-%d %H:%M:%f', 'now', 'localtime'), "); sb.Append(Database.GetInstance().QTime(ma.TsStart)); sb.Append(","); sb.Append(Database.GetInstance().QTime(ma.TsEnd)); sb.Append(","); sb.Append(Database.GetInstance().Q(ma.KeyTotal)); sb.Append(","); sb.Append(Database.GetInstance().Q(ma.KeyOther)); sb.Append(","); sb.Append(Database.GetInstance().Q(ma.KeyBackspace)); sb.Append(","); sb.Append(Database.GetInstance().Q(ma.KeyNavigate)); sb.Append(","); sb.Append(Database.GetInstance().Q(ma.ClickTotal)); sb.Append(","); sb.Append(Database.GetInstance().Q(ma.ClickOther)); sb.Append(","); sb.Append(Database.GetInstance().Q(ma.ClickLeft)); sb.Append(","); sb.Append(Database.GetInstance().Q(ma.ClickRight)); sb.Append(","); sb.Append(Database.GetInstance().Q(ma.ScrollDelta)); sb.Append(","); sb.Append(Database.GetInstance().Q(ma.MovedDistance)); sb.Append(");"); var query = sb.ToString(); Database.GetInstance().ExecuteDefaultQuery(query); }
/// <summary> /// For: Mouse Movement Data /// Dequeues the respective buffer, adds it to a list (which prepares the data for saving) /// and updates the UserInputaggregate. Finally, it deletes the used items from the list. /// </summary> /// <param name="aggregate"></param> /// <param name="tsStart"></param> /// <param name="tsEnd"></param> private void AddMouseMovementsToAggregate(UserInputAggregate aggregate, DateTime tsStart, DateTime tsEnd) { // dequeue buffer MouseMovementSnapshot e; while (!MouseMovementBuffer.IsEmpty) { MouseMovementBuffer.TryDequeue(out e); MouseMovementListToSave.Add(e); } // save all items between tsStart - tsEnd if (MouseMovementListToSave == null || MouseMovementListToSave.Count == 0) return; var thisIntervalMouseMovements = MouseMovementListToSave.Where(i => i.Timestamp >= tsStart && i.Timestamp < tsEnd); aggregate.MovedDistance = (int)CalculateMouseMovementDistance(thisIntervalMouseMovements); // delete all items older than tsEnd MouseMovementListToSave.RemoveAll(i => i.Timestamp < tsEnd); }
/// <summary> /// For: Mouse Scrolls Data /// Dequeues the respective buffer, adds it to a list (which prepares the data for saving) /// and updates the UserInputaggregate. Finally, it deletes the used items from the list. /// </summary> /// <param name="aggregate"></param> /// <param name="tsStart"></param> /// <param name="tsEnd"></param> private void AddMouseScrollsToAggregate(UserInputAggregate aggregate, DateTime tsStart, DateTime tsEnd) { // dequeue buffer MouseScrollSnapshot e; while (!MouseScrollsBuffer.IsEmpty) { MouseScrollsBuffer.TryDequeue(out e); MouseScrollsListToSave.Add(e); } // save all items between tsStart - tsEnd if (MouseScrollsListToSave == null || MouseScrollsListToSave.Count == 0) return; var thisIntervalMouseScrolls = MouseScrollsListToSave.Where(i => i.Timestamp >= tsStart && i.Timestamp < tsEnd); aggregate.ScrollDelta = thisIntervalMouseScrolls.Sum(i => Math.Abs(i.ScrollDelta)); // delete all items older than tsEnd MouseScrollsListToSave.RemoveAll(i => i.Timestamp < tsEnd); }
/// <summary> /// For: Mouse Clicks Data /// Dequeues the respective buffer, adds it to a list (which prepares the data for saving) /// and updates the UserInputaggregate. Finally, it deletes the used items from the list. /// </summary> /// <param name="aggregate"></param> /// <param name="tsStart"></param> /// <param name="tsEnd"></param> private void AddMouseClicksToAggregate(UserInputAggregate aggregate, DateTime tsStart, DateTime tsEnd) { // dequeue buffer MouseClickEvent e; while (!MouseClickBuffer.IsEmpty) { MouseClickBuffer.TryDequeue(out e); MouseClickListToSave.Add(e); } // save all items between tsStart - tsEnd if (MouseClickListToSave == null || MouseClickListToSave.Count == 0) return; var thisIntervalMouseClicks = MouseClickListToSave.Where(i => i.Timestamp >= tsStart && i.Timestamp < tsEnd); aggregate.ClickLeft = thisIntervalMouseClicks.Count(i => i.Button == MouseButtons.Left); aggregate.ClickRight = thisIntervalMouseClicks.Count(i => i.Button == MouseButtons.Right); aggregate.ClickOther = thisIntervalMouseClicks.Count(i => (i.Button != MouseButtons.Left && i.Button != MouseButtons.Right)); aggregate.ClickTotal = aggregate.ClickLeft + aggregate.ClickRight + aggregate.ClickOther; // delete all items older than tsEnd MouseClickListToSave.RemoveAll(i => i.Timestamp < tsEnd); }
/// <summary> /// For: Keystrokes Data /// Dequeues the respective buffer, adds it to a list (which prepares the data for saving) /// and updates the UserInputaggregate. Finally, it deletes the used items from the list. /// </summary> /// <param name="aggregate"></param> /// <param name="tsStart"></param> /// <param name="tsEnd"></param> private void AddKeystrokesToAggregate(UserInputAggregate aggregate, DateTime tsStart, DateTime tsEnd) { // dequeue buffer KeystrokeEvent e; while (!KeystrokeBuffer.IsEmpty) { KeystrokeBuffer.TryDequeue(out e); KeystrokeListToSave.Add(e); } // save all items between tsStart - tsEnd if (KeystrokeListToSave == null || KeystrokeListToSave.Count == 0) return; var thisIntervalKeystrokes = KeystrokeListToSave.Where(i => i.Timestamp >= tsStart && i.Timestamp < tsEnd); aggregate.KeyNavigate = thisIntervalKeystrokes.Count(i => i.KeystrokeType == KeystrokeType.Navigate); aggregate.KeyBackspace = thisIntervalKeystrokes.Count(i => i.KeystrokeType == KeystrokeType.Backspace); aggregate.KeyOther = thisIntervalKeystrokes.Count(i => i.KeystrokeType == KeystrokeType.Key); aggregate.KeyTotal = aggregate.KeyNavigate + aggregate.KeyBackspace + aggregate.KeyOther; // delete all items older than tsEnd KeystrokeListToSave.RemoveAll(i => i.Timestamp < tsEnd); }
/// <summary> /// dequeues the currently counted number of elements from the buffer and saves them to the database /// (it can happen that more elements are added to the end of the queue while this happens, /// those elements will be safed to the database in the next run of this method) /// </summary> private void SaveInputBufferToDatabase() { try { var aggregate = new UserInputAggregate(); // time interval to save var now = DateTime.Now; var tsEnd = now.AddSeconds(-now.Second).AddSeconds(-Settings.UserInputAggregationIntervalInSeconds); // round to minute, - 60s var tsStart = tsEnd.AddSeconds(-Settings.UserInputAggregationIntervalInSeconds); // tsEnd - 60s aggregate.TsStart = tsStart; aggregate.TsEnd = tsEnd; AddKeystrokesToAggregate(aggregate, tsStart, tsEnd); AddMouseClicksToAggregate(aggregate, tsStart, tsEnd); AddMouseScrollsToAggregate(aggregate, tsStart, tsEnd); AddMouseMovementsToAggregate(aggregate, tsStart, tsEnd); // save aggregate to database Queries.SaveUserInputSnapshotToDatabase(aggregate); } catch (Exception e) { //Logger.WriteToLogFile(e); } }