Ejemplo n.º 1
0
        public static bool GetLinksAndTorrent(string internalName,
                                              out List <string> links,
                                              out byte[] torrent,
                                              out List <string> dependencies,
                                              out ResourceType resourceType,
                                              out string torrentFileName)
        {
            var db = new ZkDataContext();

            var resource = db.Resources.SingleOrDefault(x => x.InternalName == internalName);

            if (resource == null)
            {
                torrent         = null;
                links           = null;
                dependencies    = null;
                resourceType    = ResourceType.Map;
                torrentFileName = null;
                return(false);
            }

            dependencies = resource.ResourceDependencies.Select(x => x.NeedsInternalName).ToList();
            resourceType = resource.TypeID;

            var bestOld = resource.ResourceContentFiles.FirstOrDefault(x => x.LinkCount == resource.ResourceContentFiles.Max(y => y.LinkCount));

            if (bestOld != null && bestOld.LinkCount > 0 && (resource.MissionID != null ||
                                                             (resource.LastLinkCheck != null && DateTime.UtcNow.Subtract(resource.LastLinkCheck.Value).TotalHours < 2)))
            {
                // use cached values for missions or resources checked less than 1 day ago
                links           = PlasmaServer.GetLinkArray(bestOld);
                torrent         = PlasmaServer.GetTorrentData(bestOld);
                torrentFileName = PlasmaServer.GetTorrentFileName(bestOld);
                if (links.Count > 0)
                {
                    db.Database.ExecuteSqlCommand("UPDATE Resources SET DownloadCount = DownloadCount+1 WHERE ResourceID={0}", resource.ResourceID);
                }
                else
                {
                    db.Database.ExecuteSqlCommand("UPDATE Resources SET NoLinkDownloadCount = NoLinkDownloadCount+1 WHERE ResourceID={0}", resource.ResourceID);
                }

                return(true);
            }

            RequestData data;
            var         isNew = false;

            lock (Requests)
            {
                if (!Requests.TryGetValue(resource.ResourceID, out data))
                {
                    data  = new RequestData(resource.ResourceID);
                    isNew = true;
                    Requests.Add(resource.ResourceID, data);
                }
            }

            if (!isNew)
            {
                // request is ongoing, wait for completion
                data.WaitHandle.WaitOne();
                torrentFileName = PlasmaServer.GetTorrentFileName(data.ContentFile);
                links           = PlasmaServer.GetLinkArray(data.ContentFile);
                torrent         = PlasmaServer.GetTorrentData(data.ContentFile);
                if (links.Count > 0)
                {
                    db.Database.ExecuteSqlCommand("UPDATE Resources SET DownloadCount = DownloadCount+1 WHERE ResourceID={0}", resource.ResourceID);
                }
                else
                {
                    db.Database.ExecuteSqlCommand("UPDATE Resources SET NoLinkDownloadCount = NoLinkDownloadCount+1 WHERE ResourceID={0}", resource.ResourceID);
                }
                return(true);
            }
            else
            {
                // new request - actually perform it
                try
                {
                    var toCheck = from x in resource.ResourceContentFiles
                                  group x by new { x.FileName, x.Length }
                    into g
                    where !g.Key.FileName.EndsWith(".sdp")
                    select g.First();

                    Task.WaitAll(toCheck.Select(x => Task.Factory.StartNew(() => UpdateLinks(x))).ToArray());

                    db.SaveChanges();

                    // find best content file - the one with most links
                    var best = resource.ResourceContentFiles.FirstOrDefault(x => x.LinkCount == resource.ResourceContentFiles.Max(y => y.LinkCount));

                    if (best != null)
                    {
                        data.ContentFile = best;
                    }
                    else
                    {
                        data.ContentFile = resource.ResourceContentFiles.First();  // all content files sux, reurn any
                    }
                    links           = PlasmaServer.GetLinkArray(data.ContentFile);
                    torrent         = PlasmaServer.GetTorrentData(data.ContentFile);
                    torrentFileName = PlasmaServer.GetTorrentFileName(data.ContentFile);
                    if (links.Count > 0)
                    {
                        resource.DownloadCount++;
                    }
                    else
                    {
                        resource.NoLinkDownloadCount++;
                    }
                    db.SaveChanges();
                    return(true);
                }
                finally
                {
                    lock (Requests) Requests.Remove(data.ResourceID);
                    data.WaitHandle.Set(); // notify other waiting Requests that its done
                }
            }
        }