public static void Load()
 {
     lock (_lock)
     {
         using (var db = new SqlDatabase <BubbleGroupSettings>(GetPath()))
         {
             var toRemoves = new List <BubbleGroupSettings>();
             foreach (var settings in db.Store.ToList())
             {
                 var bubbleGroup = BubbleGroupManager.Find(settings.Guid);
                 if (bubbleGroup == null)
                 {
                     toRemoves.Add(settings);
                 }
                 else
                 {
                     bubbleGroup.Settings = settings;
                 }
             }
             if (toRemoves.Any())
             {
                 foreach (var toRemove in toRemoves)
                 {
                     db.Remove(toRemove);
                 }
             }
         }
     }
 }
        internal static void LoadAll()
        {
            lock (Lock)
            {
                var sw = new Stopwatch();
                sw.Start();

                var location = GetLocation();

                try
                {
                    if (File.Exists(location))
                    {
                        using (var fs = File.OpenRead(location))
                        {
                            var items = Serializer.Deserialize<List<BubbleGroupCache>>(fs);

                            foreach (var item in items)
                            {
                                var associatedGroup = BubbleGroupManager.Find(item.Guid);

                                if (associatedGroup == null)
                                {
                                    continue;
                                }

                                var unifiedGroup = associatedGroup as UnifiedBubbleGroup;
                                if (unifiedGroup != null)
                                {
                                    associatedGroup = unifiedGroup.PrimaryGroup;
                                }
                                Bind(associatedGroup, item);
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    Utils.DebugPrint("Failed to load bubble group cache: " + ex);
                    if (File.Exists(location))
                    {
                        File.Delete(location);
                    }
                }

                sw.Stop();
                Utils.DebugPrint("Loading bubble group cache took " + sw.ElapsedMilliseconds + "ms.");
            }
        }
        internal static void OnBubbleReceived(Bubble b)
        {
            var visualBubble = b as VisualBubble;

            if (visualBubble != null)
            {
                try
                {
                    BubbleManager.Group(visualBubble);
                }
                catch (Exception ex)
                {
                    Utils.DebugPrint("Problem in OnBubbleReceived (VisualBubble) from service " +
                                     visualBubble.Service.Information.ServiceName + ": " + ex.Message);
                }

                if (visualBubble.Direction == Bubble.BubbleDirection.Incoming &&
                    IsRunning(visualBubble.Service) &&
                    BubbleQueueManager.HasQueuedBubbles(b.Service.Information.ServiceName, true, true))
                {
                    Utils.DebugPrint("Sending queued bubbles as we're getting some received.");
                    BubbleQueueManager.Send(new [] { b.Service.Information.ServiceName });
                }
            }
            else if (b is AbstractBubble)
            {
                Utils.DebugPrint("We got an abstract bubble: " + b.GetType().Name + " Address: " + b.Address);

                BubbleGroup group = null;

                var deliveredBubble = b as DeliveredBubble;
                if (deliveredBubble != null)
                {
                    @group = BubbleGroupManager.FindWithAddress(deliveredBubble.Service, deliveredBubble.Address);

                    if (@group != null)
                    {
                        BubbleGroupFactory.LoadFullyIfNeeded(@group);

                        var bubbles = @group.Bubbles;

                        for (var i = bubbles.Count - 1; i >= 0; i--)
                        {
                            var bubble = bubbles[i];

                            if (bubble.ID != deliveredBubble.VisualBubbleID)
                            {
                                continue;
                            }

                            BubbleManager.UpdateStatus(bubble, Bubble.BubbleStatus.Delivered, @group);

                            if (@group.Service.Information.DoesSupport(typeof(DeliveredBubbleReceipt)))
                            {
                                BubbleManager.Send(new DeliveredBubbleReceipt(Time.GetNowUnixTimestamp(), Bubble.BubbleDirection.Outgoing,
                                                                              @group.Service, bubble));
                            }

                            break;
                        }
                    }
                }

                var readBubble = b as ReadBubble;
                if (readBubble != null)
                {
                    @group = BubbleGroupManager.FindWithAddress(readBubble.Service, readBubble.Address);
                    if (@group != null)
                    {
                        BubbleGroupFactory.LoadFullyIfNeeded(@group);

                        if (@group.ReadTimes == null || [email protected])
                        {
                            @group.ReadTimes = new []
                            {
                                new DisaReadTime
                                {
                                    ParticipantAddress = readBubble.ParticipantAddress,
                                    Time = readBubble.ReadTime
                                }
                            };
                        }
                        else
                        {
                            var readTimes = @group.ReadTimes.ToList();

                            var duplicateReadTime = readTimes.FirstOrDefault(x =>
                                                                             @group.Service.BubbleGroupComparer(x.ParticipantAddress, readBubble.ParticipantAddress));
                            if (duplicateReadTime != null)
                            {
                                readTimes.Remove(duplicateReadTime);
                            }

                            readTimes.Add(new DisaReadTime
                            {
                                ParticipantAddress = readBubble.ParticipantAddress,
                                Time = readBubble.ReadTime
                            });

                            @group.ReadTimes = readTimes.ToArray();
                        }
                    }
                }

                var prescenceBubble = b as PresenceBubble;
                if (prescenceBubble != null)
                {
                    @group = BubbleGroupManager.Find(bubbleGroup =>
                                                     !bubbleGroup.IsParty &&
                                                     bubbleGroup.Service ==
                                                     prescenceBubble.Service &&
                                                     prescenceBubble.Service.BubbleGroupComparer(
                                                         bubbleGroup.Address,
                                                         prescenceBubble.Address));

                    if (@group != null)
                    {
                        if ([email protected] && !prescenceBubble.Available)
                        {
                            var oldPresence = @group.PresenceType;
                            @group.PresenceType = PresenceBubble.PresenceType.Unavailable;
                            if (oldPresence != prescenceBubble.Presence)
                            {
                                BubbleGroupManager.UpdateLastOnline(@group);
                            }
                        }
                        else
                        {
                            @group.PresenceType         = prescenceBubble.Presence;
                            @group.PresencePlatformType = prescenceBubble.Platform;
                        }

                        if (!prescenceBubble.Available)
                        {
                            @group.Typing = false;
                        }
                    }
                }

                var typingBubble = b as TypingBubble;
                if (typingBubble != null)
                {
                    @group = BubbleGroupManager.Find(bubbleGroup =>
                                                     !bubbleGroup.IsParty &&
                                                     bubbleGroup.Service ==
                                                     typingBubble.Service &&
                                                     typingBubble.Service.BubbleGroupComparer(
                                                         bubbleGroup.Address,
                                                         typingBubble.Address));

                    if (@group != null)
                    {
                        if (@group.Presence)
                        {
                            @group.Typing        = typingBubble.Typing;
                            @group.TypingIsAudio = typingBubble.IsAudio;
                        }
                        else
                        {
                            @group.Typing = false;
                        }
                    }
                }

                try
                {
                    if (@group != null)
                    {
                        BubbleGroupEvents.RaiseNewAbstractBubble(b as AbstractBubble, @group);
                    }
                }
                catch (Exception ex)
                {
                    Utils.DebugPrint("Problem in OnBubbleReceived (AbstractBubble) from service " +
                                     b.Service.Information.ServiceName + ": " + ex.Message);
                }
            }
        }
Esempio n. 4
0
        private static bool LoadInternal(SqlDatabase <Entry> db)
        {
            var entries = GetAllEntries(db);

            if (entries == null)
            {
                return(false);
            }

            var bubbleGroupsActualCount = Directory.GetFiles(BubbleGroupDatabase.GetBaseLocation(), "*.*", SearchOption.AllDirectories).Length;
            var entriesCount            = entries.Count(x => !x.Unified);

            if (!(bubbleGroupsActualCount > entriesCount - 5 &&
                  bubbleGroupsActualCount < entriesCount + 5))
            {
                Utils.DebugPrint("Actual count does not match index count (+-5 tolerance). We'll have to re-generate index.");
                return(false);
            }

            foreach (var entry in entries)
            {
                if (entry.Unified)
                {
                    continue;
                }

                var service = ServiceManager.GetByName(entry.Service);
                if (service != null)
                {
                    var mostRecentVisualBubble = DeserializeBubble(entry.LastBubble);
                    mostRecentVisualBubble.Service = service;
                    mostRecentVisualBubble.ID      = entry.LastBubbleGuid;

                    var bubbleGroup = new BubbleGroup(mostRecentVisualBubble, entry.Guid, true);

                    BubbleGroupManager.BubbleGroupsAdd(bubbleGroup, true);
                }
                else
                {
                    Utils.DebugPrint("Could not obtain a valid service object from " + entry.Id + " (" + entry.Service + ")");
                }
            }

            foreach (var entry in entries)
            {
                if (!entry.Unified)
                {
                    continue;
                }

                var innerGroups = new List <BubbleGroup>();

                var innerGroupsIds = entry.UnifiedBubbleGroupsGuids.Split(',');
                if (innerGroupsIds != null)
                {
                    foreach (var innerGroupId in innerGroupsIds)
                    {
                        var innerGroup = BubbleGroupManager.Find(innerGroupId);
                        if (innerGroup == null)
                        {
                            Utils.DebugPrint("Unified group, inner group " + innerGroupId + " could not be related.");
                        }
                        else
                        {
                            innerGroups.Add(innerGroup);
                        }
                    }
                }

                if (!innerGroups.Any())
                {
                    Utils.DebugPrint("This unified group has no inner groups. Skipping this unified group.");
                    continue;
                }

                var primaryGroup = innerGroups.FirstOrDefault(x => x.ID == entry.UnifiedPrimaryBubbleGroupGuid);
                if (primaryGroup == null)
                {
                    Utils.DebugPrint("Unified group, primary group " + entry.UnifiedPrimaryBubbleGroupGuid +
                                     " could not be related. Skipping this unified group.");
                    continue;
                }

                var id = entry.Guid;

                var unifiedGroup = BubbleGroupFactory.CreateUnifiedInternal(innerGroups, primaryGroup, id);

                var sendingGroup = innerGroups.FirstOrDefault(x => x.ID == entry.UnifiedSendingBubbleGroupGuid);
                if (sendingGroup != null)
                {
                    unifiedGroup._sendingGroup = sendingGroup;
                }

                BubbleGroupManager.BubbleGroupsAdd(unifiedGroup, true);
            }

            return(true);
        }
        internal static void LoadAllPartiallyIfPossible(int bubblesPerGroup = 100)
        {
            var corruptedGroups = new List <string>();

            var bubbleGroupsLocations       = Directory.GetFiles(BubbleGroupDatabase.GetBaseLocation(), "*.*", SearchOption.AllDirectories);
            var bubbleGroupsLocationsSorted =
                bubbleGroupsLocations.OrderByDescending(x => Time.GetUnixTimestamp(File.GetLastWriteTime(x))).ToList();

            foreach (var bubbleGroupLocation in bubbleGroupsLocationsSorted)
            {
                String groupId = null;
                try
                {
                    var groupHeader = Path.GetFileNameWithoutExtension(bubbleGroupLocation);

                    var groupDelimeter = groupHeader.IndexOf("^", StringComparison.Ordinal);
                    var serviceName    = groupHeader.Substring(0, groupDelimeter);
                    groupId = groupHeader.Substring(groupDelimeter + 1);

                    var service = ServiceManager.GetByName(serviceName);

                    if (service == null)
                    {
                        Utils.DebugPrint("Service " + serviceName +
                                         " not found in AllServices!");
                        continue;
                    }

                    var deserializedBubbleGroup = LoadPartiallyIfPossible(bubbleGroupLocation, service, groupId, bubblesPerGroup);
                    if (deserializedBubbleGroup == null)
                    {
                        throw new Exception("DeserializedBubbleGroup is nothing.");
                    }
                    BubbleGroupManager.BubbleGroupsAdd(deserializedBubbleGroup);
                }
                catch (Exception ex)
                {
                    Utils.DebugPrint("Group " + bubbleGroupLocation + " is corrupt. Deleting. " + ex);
                    File.Delete(bubbleGroupLocation);
                    if (groupId != null)
                    {
                        corruptedGroups.Add(groupId);
                    }
                }
            }

            var migrationResaveNeeded  = false;
            var corruptedUnifiedGroups =
                new List <SimpleDatabase <UnifiedBubbleGroup, DisaUnifiedBubbleGroupEntry> .Container>();
            var removeFromRuntime =
                new List <SimpleDatabase <UnifiedBubbleGroup, DisaUnifiedBubbleGroupEntry> .Container>();

            foreach (var group in UnifiedBubbleGroupsDatabase)
            {
                var innerGroupCorrupt = false;
                var innerGroups       = new List <BubbleGroup>();
                foreach (var innerGroupId in @group.Serializable.GroupIds)
                {
                    var innerGroup = BubbleGroupManager.Find(innerGroupId);
                    if (innerGroup == null)
                    {
                        Utils.DebugPrint("Unified group, inner group " + innerGroupId +
                                         " could not be related.");
                        if (corruptedGroups.Contains(innerGroupId))
                        {
                            Utils.DebugPrint(
                                "It was detected that this inner group was corrupted and deleted. Will delete unified group.");
                            innerGroupCorrupt = true;
                            corruptedUnifiedGroups.Add(@group);
                        }
                    }
                    else
                    {
                        innerGroups.Add(innerGroup);
                    }
                }
                if (!innerGroups.Any())
                {
                    Utils.DebugPrint("Yuck. This unified group has no inner groups. Removing from runtime.");
                    removeFromRuntime.Add(@group);
                    continue;
                }
                if (innerGroupCorrupt)
                {
                    continue;
                }

                var primaryGroup = innerGroups.FirstOrDefault(x => x.ID == @group.Serializable.PrimaryGroupId);
                if (primaryGroup == null)
                {
                    Utils.DebugPrint("Unified group, primary group " + @group.Serializable.PrimaryGroupId +
                                     " could not be related. Removing from runtime.");
                    removeFromRuntime.Add(@group);
                    continue;
                }

                var id = @group.Serializable.Id;

                var unifiedGroup = CreateUnifiedInternal(innerGroups, primaryGroup, id);
                if (id == null)
                {
                    migrationResaveNeeded  = true;
                    @group.Serializable.Id = unifiedGroup.ID;
                }

                var sendingGroup = innerGroups.FirstOrDefault(x => x.ID == @group.Serializable.SendingGroupId);
                if (sendingGroup != null)
                {
                    unifiedGroup.SendingGroup = sendingGroup;
                }

                @group.Object = unifiedGroup;
                BubbleGroupManager.BubbleGroupsAdd(unifiedGroup);
            }
            if (removeFromRuntime.Any())
            {
                foreach (var group in removeFromRuntime)
                {
                    UnifiedBubbleGroupsDatabase.Remove(@group);
                }
            }
            if (corruptedUnifiedGroups.Any())
            {
                foreach (var group in corruptedUnifiedGroups)
                {
                    UnifiedBubbleGroupsDatabase.Remove(@group);
                }
            }
            if (migrationResaveNeeded)
            {
                Utils.DebugPrint("It was detected that we need to save migration changes for UnifiedBubbleGroups.");
                UnifiedBubbleGroupsDatabase.SaveChanges();
            }

            try
            {
                foreach (var groupCache in BubbleGroupCacheManager.Load())
                {
                    var associatedGroup = BubbleGroupManager.Find(groupCache.Guid);
                    if (associatedGroup == null)
                    {
                        continue;
                    }

                    var unifiedGroup = associatedGroup as UnifiedBubbleGroup;
                    if (unifiedGroup != null)
                    {
                        associatedGroup = unifiedGroup.PrimaryGroup;
                    }

                    associatedGroup.Title = groupCache.Name;
                    associatedGroup.Photo = groupCache.Photo;
                    associatedGroup.IsPhotoSetInitiallyFromCache = true;
                    if (groupCache.Participants != null)
                    {
                        associatedGroup.Participants = groupCache.Participants.ToSynchronizedCollection();
                        foreach (var participant in associatedGroup.Participants)
                        {
                            participant.IsPhotoSetInitiallyFromCache = true;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Utils.DebugPrint("Failed to load bubble groups!: " + ex);
            }

            BubbleGroupSettingsManager.Load();
        }