예제 #1
0
        public void Research(ulong key)
        {
            if (!Network.Responsive)
            {
                return;
            }

            // limit re-search to once per 30 secs
            DateTime timeout = default(DateTime);

            if (NextResearch.TryGetValue(key, out timeout))
            {
                if (Core.TimeNow < timeout)
                {
                    return;
                }
            }

            uint            version = 0;
            OpVersionedFile file    = GetFile(key);

            if (file != null)
            {
                version = file.Header.Version + 1;
            }

            StartSearch(key, version);

            NextResearch[key] = Core.TimeNow.AddSeconds(3);
        }
예제 #2
0
        void LocalSync_TagReceived(ulong user, byte[] tag)
        {
            if (tag.Length == 0)
            {
                return;
            }

            uint version = 0;

            OpVersionedFile file = GetFile(user);

            if (file != null)
            {
                version = CompactNum.ToUInt32(tag, 0, tag.Length);

                // version old, so we need the latest localSync file
                // wont cause loop because localsync's fileAquired will only fire on new version of localSync
                if (version < file.Header.Version)
                {
                    Core.Sync.Research(user);
                }
            }

            // if newer file on network, or this node is in our cache area, find it
            if ((file != null && version > file.Header.Version) ||

                (file == null && ((!GlobalIM && Network.Routing.InCacheArea(user)) ||
                                  (GlobalIM && Core.Buddies.BuddyList.SafeContainsKey(user)))))
            {
                StartSearch(user, version); // this could be called from a patch given to another user, direct connect not gauranteed
            }
        }
예제 #3
0
        private void Process_VersionedFile(DataReq data, SignedData signed, VersionedFileHeader header)
        {
            Core.IndexKey(header.KeyID, ref header.Key);

            OpVersionedFile current = GetFile(header.KeyID);

            // if link loaded
            if (current != null)
            {
                // lower version
                if (header.Version < current.Header.Version)
                {
                    if (data != null && data.Source != null)
                    {
                        Store.Send_StoreReq(data.Source, data.LocalProxy, new DataReq(null, current.UserID, Service, DataType, current.SignedHeader));
                    }

                    return;
                }

                // higher version
                else if (header.Version > current.Header.Version)
                {
                    CacheFile(signed, header);
                }
            }

            // else load file, set new header after file loaded
            else
            {
                CacheFile(signed, header);
            }
        }
예제 #4
0
        public OpVersionedFile GetFile(ulong id)
        {
            OpVersionedFile vfile = null;

            FileMap.SafeTryGetValue(id, out vfile);

            return(vfile);
        }
예제 #5
0
파일: LocalSync.cs 프로젝트: nandub/DeOps
        void Cache_FileRemoved(OpVersionedFile file)
        {
            if (InRange.ContainsKey(file.UserID))
            {
                InRange.Remove(file.UserID);
            }

            if (OutofRange.ContainsKey(file.UserID))
            {
                OutofRange.Remove(file.UserID);
            }
        }
예제 #6
0
        void Search_Local(ulong key, byte[] parameters, List <byte[]> results)
        {
            uint minVersion = BitConverter.ToUInt32(parameters, 0);

            OpVersionedFile vfile = GetFile(key);

            if (vfile != null)
            {
                if (vfile.Header.Version >= minVersion)
                {
                    results.Add(vfile.SignedHeader);
                }
            }
        }
예제 #7
0
        bool Transfers_FileSearch(ulong key, FileDetails details)
        {
            OpVersionedFile vfile = GetFile(key);

            if (vfile != null)
            {
                if (details.Size == vfile.Header.FileSize && Utilities.MemCompare(details.Hash, vfile.Header.FileHash))
                {
                    return(true);
                }
            }

            return(false);
        }
예제 #8
0
        string Transfers_FileRequest(ulong key, FileDetails details)
        {
            OpVersionedFile vfile = GetFile(key);

            if (vfile != null)
            {
                if (details.Size == vfile.Header.FileSize && Utilities.MemCompare(details.Hash, vfile.Header.FileHash))
                {
                    return(GetFilePath(vfile.Header));
                }
            }


            return(null);
        }
예제 #9
0
        void Store_Patch(DhtAddress source, byte[] data)
        {
            if (data.Length < 9)
            {
                return;
            }

            ulong user = BitConverter.ToUInt64(data, 0);

            if (!Network.Routing.InCacheArea(user))
            {
                return;
            }

            uint version = CompactNum.ToUInt32(data, 8, data.Length - 8);

            OpVersionedFile vfile = GetFile(user);

            if (vfile != null && vfile.Header != null)
            {
                if (vfile.Header.Version > version)
                {
                    Store.Send_StoreReq(source, null, new DataReq(null, vfile.UserID, Service, DataType, vfile.SignedHeader));
                    return;
                }


                vfile.Unique = false; // network has current or newer version

                if (vfile.Header.Version == version)
                {
                    return;
                }

                // else our version is old, download below
            }


            if (Network.Established)
            {
                Network.Searches.SendDirectRequest(source, user, Service, DataType, BitConverter.GetBytes(version));
            }
            else
            {
                DownloadLater[user] = version;
            }
        }
예제 #10
0
파일: LocalSync.cs 프로젝트: nandub/DeOps
        void Cache_FileAquired(OpVersionedFile file)
        {
            ServiceData data = ServiceData.Decode(file.Header.Extra);

            if (GlobalIM) // cant check here if in buddy list because on localSync load, buddy list is null
            {
                InRange[file.UserID] = data;
            }

            if (Network.Routing.InCacheArea(file.UserID))
            {
                InRange[file.UserID] = data;
            }
            else
            {
                OutofRange[file.UserID] = data;
            }

            InvokeTags(file.UserID, data);
        }
예제 #11
0
파일: LocalSync.cs 프로젝트: nandub/DeOps
        void Locations_TagReceived(DhtAddress address, ulong user, byte[] tag)
        {
            // if user not cached, we only active search their info if in local cache area

            if (tag.Length == 0)
            {
                return;
            }

            uint version = 0;

            OpVersionedFile file = Cache.GetFile(user);

            if (file != null)
            {
                version = CompactNum.ToUInt32(tag, 0, tag.Length);

                if (version < file.Header.Version)
                {
                    Store.Send_StoreReq(address, null, new DataReq(null, file.UserID, ServiceID, DataTypeSync, file.SignedHeader));
                }
            }

            // get new version of local sync file
            if ((file != null && version > file.Header.Version) ||

                (file == null && ((!GlobalIM && Network.Routing.InCacheArea(user)) ||
                                  (GlobalIM && Core.Buddies.BuddyList.SafeContainsKey(user)))))
            {
                Cache.Research(user);
            }

            // ensure we have the lastest versions of the user's services
            if (file != null)
            {
                CheckTags(file.UserID);
            }
        }
예제 #12
0
        private void Cache_FileAquired(OpVersionedFile file)
        {
            if (file.UserID != Network.Local.UserID)
                return;

            // only we can open the buddly list stored on the network
            byte[] key = Core.User.Settings.KeyPair.Decrypt(file.Header.FileKey, false);

            using (TaggedStream tagged = new TaggedStream(Cache.GetFilePath(file.Header), Network.Protocol))
            using (IVCryptoStream crypto = IVCryptoStream.Load(tagged, key))
            {
                BuddyList.SafeClear();

                PacketStream stream = new PacketStream(crypto, Network.Protocol, FileAccess.Read);

                G2Header root = null;

                while (stream.ReadPacket(ref root))
                    if (root.Name == BuddyPacket.Buddy)
                    {
                        OpBuddy buddy = OpBuddy.Decode(root);
                        ulong id = Utilities.KeytoID(buddy.Key);

                        Core.IndexKey(id, ref buddy.Key);
                        Core.IndexName(id, buddy.Name);

                        if(buddy.Ignored)
                            IgnoreList.SafeAdd(id, buddy);
                        else
                            BuddyList.SafeAdd(id, buddy);
                    }
            }

            Core.RunInGuiThread(GuiUpdate);
        }
예제 #13
0
 public OpTrust(OpVersionedFile file)
 {
     File = file;
 }
예제 #14
0
        void Cache_FileRemoved(OpVersionedFile file)
        {
            OpTrust trust = GetTrust(file.UserID);

            if (trust == null)
                return;

            ProjectRoots.LockReading(delegate()
            {
                foreach (uint project in trust.Links.Keys)
                    if(ProjectRoots.ContainsKey(project))
                        ProjectRoots[project].SafeRemove(trust.Links[project]);
            });

            trust.Reset();
            trust.Loaded = false;
            TrustMap.SafeRemove(file.UserID);

            // alert services/gui
            if (LinkUpdate != null)
                LinkUpdate.Invoke(trust);

            Core.RunInGuiThread(GuiUpdate, trust.UserID);
        }
예제 #15
0
        private void Cache_FileAquired(OpVersionedFile cachefile)
        {
            try
            {
                // get link directly, even if in unloaded state we need the same reference
                OpTrust trust = null;
                TrustMap.SafeTryGetValue(cachefile.UserID, out trust);

                if (trust == null)
                {
                    trust = new OpTrust(cachefile);
                    TrustMap.SafeAdd(cachefile.UserID, trust);
                }
                else
                    trust.File = cachefile;

                // clean roots, if link has loopID, remove loop node entirely, it will be recreated if needed later
                ProjectRoots.LockReading(delegate()
                {
                    foreach (uint project in ProjectRoots.Keys)
                    {
                        OpLink link = trust.GetLink(project);

                        if (link == null)
                            continue;

                        ThreadedList<OpLink> roots = ProjectRoots[project];

                        roots.SafeRemove(link);

                        // remove loop node
                        if (link.LoopRoot != null)
                            roots.LockReading(delegate()
                            {
                                foreach (OpLink root in roots)
                                    if (root.UserID == link.LoopRoot.UserID)
                                    {
                                        roots.SafeRemove(root); // root is a loop node

                                        // remove associations with loop node
                                        foreach (OpLink downlink in root.Downlinks)
                                            downlink.LoopRoot = null;

                                        break;
                                    }
                            });
                    }
                });

                trust.Reset();

                // load data from link file
                string inheritName = null;
                string inheritOp = null;
                Bitmap inheritIcon = null;
                byte[] inheritSplash = null;

                using (TaggedStream file = new TaggedStream(Cache.GetFilePath(cachefile.Header), Network.Protocol))
                using (IVCryptoStream crypto = IVCryptoStream.Load(file, cachefile.Header.FileKey))
                {
                    PacketStream stream = new PacketStream(crypto, Network.Protocol, FileAccess.Read);

                    G2Header packetRoot = null;

                    while (stream.ReadPacket(ref packetRoot))
                    {
                        if (packetRoot.Name == DataPacket.SignedData)
                        {
                            SignedData signed = SignedData.Decode(packetRoot);
                            G2Header embedded = new G2Header(signed.Data);

                            // figure out data contained
                            if (G2Protocol.ReadPacket(embedded))
                            {
                                if (embedded.Name == TrustPacket.ProjectData)
                                {
                                    ProjectData project = ProjectData.Decode(embedded);
                                    Process_ProjectData(trust, signed, project);

                                    if (project.ID == 0)
                                    {
                                        inheritName = project.UserName;
                                        inheritOp = project.Name;
                                    }
                                }

                                else if (embedded.Name == TrustPacket.LinkData)
                                    Process_LinkData(trust, signed, LinkData.Decode(embedded));
                            }
                        }

                        else if (packetRoot.Name == TrustPacket.WebCache)
                            Network.Cache.AddWebCache(WebCache.Decode(packetRoot));

                        else if (packetRoot.Name == TrustPacket.Icon)
                            inheritIcon = IconPacket.Decode(packetRoot).OpIcon;

                        else if (packetRoot.Name == TrustPacket.Splash)
                        {
                            LargeDataPacket splash = LargeDataPacket.Decode(packetRoot);

                            if (splash.Size > 0)
                                inheritSplash = LargeDataPacket.Read(splash, stream, TrustPacket.Splash);
                        }
                    }
                }

                // set new header
                trust.Loaded = true;

                // set as root if node has no uplinks
                foreach (OpLink link in trust.Links.Values)
                    if (link.Uplink == null)
                        AddRoot(link);
                    // if uplink is unknown - process link data will search for the unknown parent

                // if loop created, create new loop node with unique ID, assign all nodes in loop the ID and add as downlinks
                foreach (OpLink link in trust.Links.Values)
                    if (IsLooped(link))
                    {
                        uint project = link.Project;

                        OpLink loop = new OpTrust(project, (ulong)Core.RndGen.Next()).GetLink(project);
                        loop.IsLoopRoot = true;

                        List<ulong> uplinks = GetUnconfirmedUplinkIDs(trust.UserID, project);
                        uplinks.Add(trust.UserID);

                        foreach (ulong uplink in uplinks)
                        {
                            OpLink member = GetLink(uplink, project);

                            if (member == null)
                                continue;

                            member.LoopRoot = loop;

                            loop.Downlinks.Add(member);
                            loop.Confirmed.Add(member.UserID); //needed for getlowers
                        }

                        AddRoot(loop);
                    }

                trust.CheckRequestVersions();

                if (LinkUpdate != null)
                    LinkUpdate.Invoke(trust);

                if (Core.NewsWorthy(trust.UserID, 0, false))
                    Core.MakeNews(ServiceIDs.Trust, "Trust updated by " + Core.GetName(trust.UserID), trust.UserID, 0, true);

                // update subs
                if (Network.Established)
                {
                    List<LocationData> locations = new List<LocationData>();

                    ProjectRoots.LockReading(delegate()
                    {
                        foreach (uint project in ProjectRoots.Keys)
                            if (Core.UserID == trust.UserID || IsHigher(trust.UserID, project))
                                GetLocsBelow(Core.UserID, project, locations);
                    });

                    Store.PublishDirect(locations, trust.UserID, ServiceID, 0, cachefile.SignedHeader);
                }

                // inherit local settings
                if(Core.UserID == trust.UserID)
                {
                    if (inheritName != null)
                        Core.User.Settings.UserName = inheritName;
                }

                // inherit settings from highest node, first node in loop
                if (IsInheritNode(trust.UserID))
                {
                    if (inheritOp != null)
                        Core.User.Settings.Operation = inheritOp;

                    if (inheritIcon != null)
                    {
                        Core.User.OpIcon = inheritIcon;
                        Core.User.IconUpdate();
                    }

                    if (inheritSplash != null)
                        Core.User.OpSplash = (Bitmap)Bitmap.FromStream(new MemoryStream(inheritSplash));
                    else
                        Core.User.OpSplash = null;
                }

                // update interface node
                Core.RunInGuiThread(GuiUpdate, trust.UserID);

                foreach (OpLink link in trust.Links.Values)
                    foreach (OpLink downlink in link.Downlinks)
                        Core.RunInGuiThread(GuiUpdate, downlink.UserID);

            }
            catch (Exception ex)
            {
                Network.UpdateLog("Link", "Error loading file " + ex.Message);
            }
        }
예제 #16
0
 public OpStorage(OpVersionedFile file)
 {
     File = file;
 }
예제 #17
0
        void Cache_FileRemoved(OpVersionedFile file)
        {
            if(InRange.ContainsKey(file.UserID))
                InRange.Remove(file.UserID);

            if (OutofRange.ContainsKey(file.UserID))
                OutofRange.Remove(file.UserID);
        }
예제 #18
0
        void Cache_FileRemoved(OpVersionedFile file)
        {
            OpStorage storage = GetStorage(file.UserID);

            if(storage != null)
                UnloadHeaderFile(GetFilePath(storage), storage.File.Header.FileKey);

            StorageMap.SafeRemove(file.UserID);
        }
예제 #19
0
        private void Cache_FileAquired(OpVersionedFile file)
        {
            OpPlan prevPlan = GetPlan(file.UserID, false);

            OpPlan newPlan = new OpPlan(file);
            PlanMap.SafeAdd(newPlan.UserID, newPlan);

            if (file.UserID == Core.UserID)
                LocalPlan = newPlan;

            if ((newPlan == LocalPlan) || (prevPlan != null && prevPlan.Loaded)) // if loaded, reload
                LoadPlan(newPlan.UserID);

            // update subs
            if (Network.Established)
            {
                List<LocationData> locations = new List<LocationData>();

                Trust.ProjectRoots.LockReading(delegate()
                {
                    foreach (uint project in Trust.ProjectRoots.Keys)
                        if (newPlan.UserID == Core.UserID || Trust.IsHigher(newPlan.UserID, project))
                            Trust.GetLocsBelow(Core.UserID, project, locations);
                });

                Store.PublishDirect(locations, newPlan.UserID, ServiceID, DataTypeFile, newPlan.File.SignedHeader);
            }

            // see if we need to update our own goal estimates
            if (newPlan.UserID != Core.UserID && LocalPlan != null)
                Trust.ProjectRoots.LockReading(delegate()
                {
                    foreach (uint project in Trust.ProjectRoots.Keys)
                        if (Trust.IsLower(Core.UserID, newPlan.UserID, project)) // updated plan must be lower than us to have an effect
                            foreach (int ident in LocalPlan.GoalMap.Keys)
                            {
                                if (!newPlan.Loaded)
                                    LoadPlan(newPlan.UserID);

                                // if updated plan part of the same goal ident, re-estimate our own goals, incorporating update's changes
                                if (newPlan.GoalMap.ContainsKey(ident) || newPlan.ItemMap.ContainsKey(ident))
                                    foreach (PlanGoal goal in LocalPlan.GoalMap[ident])
                                    {
                                        int completed = 0, total = 0;

                                        GetEstimate(goal, ref completed, ref total);

                                        if (completed != goal.EstCompleted || total != goal.EstTotal)
                                        {
                                            goal.EstCompleted = completed;
                                            goal.EstTotal = total;

                                            if (RunSaveLocal == 0) // if countdown not started, start
                                                RunSaveLocal = SaveInterval;
                                        }
                                    }
                            }
                });

            Core.RunInGuiThread(PlanUpdate, newPlan);

            if (Core.NewsWorthy(newPlan.UserID, 0, false))
                Core.MakeNews(ServiceIDs.Plan, "Plan updated by " + Core.GetName(newPlan.UserID), newPlan.UserID, 0, false);
        }
예제 #20
0
        private void CacheFile(SignedData signedHeader, VersionedFileHeader header)
        {
            if (Core.InvokeRequired)
            {
                Debug.Assert(false);
            }

            try
            {
                // check if file exists
                string path = "";
                if (header.FileHash != null)
                {
                    path = GetFilePath(header);
                    if (!File.Exists(path))
                    {
                        Download(signedHeader, header);
                        return;
                    }
                }

                // get file
                OpVersionedFile prevFile = GetFile(header.KeyID);

                if (prevFile != null)
                {
                    if (header.Version < prevFile.Header.Version)
                    {
                        return; // dont update with older version
                    }
                }
                OpVersionedFile newFile = new OpVersionedFile(header.Key);


                // set new header
                newFile.Header       = header;
                newFile.SignedHeader = signedHeader.Encode(Network.Protocol);
                newFile.Unique       = !Network.Established;

                FileMap.SafeAdd(header.KeyID, newFile);

                RunSaveHeaders = true;

                if (FileAquired != null)
                {
                    FileAquired.Invoke(newFile);
                }


                // delete old file - do after aquired event so invoked (storage) can perform clean up operation
                if (prevFile != null && prevFile.Header.FileHash != null)
                {
                    string oldPath = GetFilePath(prevFile.Header);
                    if (path != oldPath && File.Exists(oldPath))
                    {
                        try { File.Delete(oldPath); }
                        catch { }
                    }
                }
            }
            catch (Exception ex)
            {
                Core.Network.UpdateLog("VersionedFile", "Error caching data " + ex.Message);
            }
        }
예제 #21
0
        void Cache_FileAquired(OpVersionedFile file)
        {
            ServiceData data = ServiceData.Decode(file.Header.Extra);

            if(GlobalIM ) // cant check here if in buddy list because on localSync load, buddy list is null
                InRange[file.UserID] = data;

            if (Network.Routing.InCacheArea(file.UserID))
                InRange[file.UserID] = data;
            else
                OutofRange[file.UserID] = data;

            InvokeTags(file.UserID, data);
        }
예제 #22
0
        void Cache_FileRemoved(OpVersionedFile file)
        {
            OpPlan plan = GetPlan(file.UserID, false);

            if (plan == null)
                return;

            PlanMap.SafeRemove(file.UserID);
        }
예제 #23
0
        void Cache_FileAquired(OpVersionedFile file)
        {
            // unload old file
            OpStorage prevStorage = GetStorage(file.UserID);
            if (prevStorage != null)
            {
                string oldPath = GetFilePath(prevStorage);

                UnloadHeaderFile(oldPath, prevStorage.File.Header.FileKey);
            }

            OpStorage newStorage = new OpStorage(file);

            StorageMap.SafeAdd(file.UserID, newStorage);

            LoadHeaderFile(GetFilePath(newStorage), newStorage, false, false);

            // record changes of higher nodes for auto-integration purposes
            Trust.ProjectRoots.LockReading(delegate()
            {
                foreach (uint project in Trust.ProjectRoots.Keys)
                {
                    List<ulong> inheritIDs = Trust.GetAutoInheritIDs(Core.UserID, project);

                    if (Core.UserID == newStorage.UserID || inheritIDs.Contains(newStorage.UserID))
                        // doesnt get called on startup because working not initialized before headers are loaded
                        if (Working.ContainsKey(project))
                        {
                            bool doSave = Working[project].RefreshHigherChanges(newStorage.UserID);

                            if (!Loading && !SavingLocal)
                                Working[project].AutoIntegrate(doSave);
                        }
                }
            });

            // update subs - this ensures file not propagated lower until we have it (prevents flood to original poster)
            if (Network.Established)
            {
                List<LocationData> locations = new List<LocationData>();

                Trust.ProjectRoots.LockReading(delegate()
                {
                    foreach (uint project in Trust.ProjectRoots.Keys)
                        if (newStorage.UserID == Core.UserID || Trust.IsHigher(newStorage.UserID, project))
                            Trust.GetLocsBelow(Core.UserID, project, locations);
                });

                Store.PublishDirect(locations, newStorage.UserID, ServiceID, FileTypeCache, file.SignedHeader);
            }

            if (StorageUpdate != null)
                Core.RunInGuiThread(StorageUpdate, newStorage);

            if (Core.NewsWorthy(newStorage.UserID, 0, false))
                Core.MakeNews(ServiceIDs.Storage, "File System updated by " + Core.GetName(newStorage.UserID), newStorage.UserID, 0, false);
        }
예제 #24
0
파일: LocalSync.cs 프로젝트: nandub/DeOps
        byte[] Locations_GetTag()
        {
            OpVersionedFile file = Cache.GetFile(Core.UserID);

            return((file != null) ? CompactNum.GetBytes(file.Header.Version) : null);
        }
예제 #25
0
        public OpVersionedFile UpdateLocal(string tempPath, byte[] key, byte[] extra)
        {
            OpVersionedFile vfile = null;

            if (Core.InvokeRequired)
            {
                // block until completed
                Core.RunInCoreBlocked(delegate() { vfile = UpdateLocal(tempPath, key, extra); });
                return(vfile);
            }

            vfile = GetFile(Core.UserID);

            VersionedFileHeader header = null;

            if (vfile != null)
            {
                header = vfile.Header;
            }

            string oldFile = null;

            if (header != null && header.FileHash != null)
            {
                oldFile = GetFilePath(header);
            }

            if (header == null)
            {
                header = new VersionedFileHeader();
            }


            header.Key   = Core.User.Settings.KeyPublic;
            header.KeyID = Core.UserID; // set so keycheck works
            header.Version++;
            header.FileKey = key;
            header.Extra   = extra;


            // finish building header
            if (key != null)
            {
                Utilities.HashTagFile(tempPath, Network.Protocol, ref header.FileHash, ref header.FileSize);

                // move file, overwrite if need be
                string finalPath = GetFilePath(header);
                File.Move(tempPath, finalPath);
            }

            CacheFile(new SignedData(Network.Protocol, Core.User.Settings.KeyPair, header), header);

            SaveHeaders();

            if (oldFile != null && File.Exists(oldFile)) // delete after move to ensure a copy always exists (names different)
            {
                try { File.Delete(oldFile); }
                catch { }
            }

            vfile = GetFile(Core.UserID);

            if (!LocalSync)
            {
                Core.Sync.UpdateLocal(); // calls this same function for local sync which publishes
            }
            else if (GlobalIM)
            {
                Core.Locations.UpdateLocation();
            }

            else if (Network.Established)
            {
                Store.PublishNetwork(Core.UserID, Service, DataType, vfile.SignedHeader);
                Core.Locations.UpdateLocation();
            }

            else
            {
                vfile.Unique = true; // publish when connected
            }
            return(vfile);
        }
예제 #26
0
        private void CacheFile(SignedData signedHeader, VersionedFileHeader header)
        {
            if (Core.InvokeRequired)
                Debug.Assert(false);

            try
            {
                // check if file exists
                string path = "";
                if (header.FileHash != null)
                {
                    path = GetFilePath(header);
                    if (!File.Exists(path))
                    {
                        Download(signedHeader, header);
                        return;
                    }
                }

                // get file
                OpVersionedFile prevFile = GetFile(header.KeyID);

                if (prevFile != null)
                    if (header.Version < prevFile.Header.Version)
                        return; // dont update with older version

                OpVersionedFile newFile = new OpVersionedFile(header.Key);

                // set new header
                newFile.Header = header;
                newFile.SignedHeader = signedHeader.Encode(Network.Protocol);
                newFile.Unique = !Network.Established;

                FileMap.SafeAdd(header.KeyID, newFile);

                RunSaveHeaders = true;

                if(FileAquired != null)
                    FileAquired.Invoke(newFile);

                // delete old file - do after aquired event so invoked (storage) can perform clean up operation
                if (prevFile != null && prevFile.Header.FileHash != null)
                {
                    string oldPath = GetFilePath(prevFile.Header);
                    if (path != oldPath && File.Exists(oldPath))
                        try { File.Delete(oldPath); }
                        catch { }
                }
            }
            catch (Exception ex)
            {
                Core.Network.UpdateLog("VersionedFile", "Error caching data " + ex.Message);
            }
        }
예제 #27
0
        public bool Loaded; // true if blocks/goals loaded

        #endregion Fields

        #region Constructors

        public OpPlan(OpVersionedFile file)
        {
            File = file;
        }