private void TorrentRemovedAlert(Core.torrent_removed_alert a) { Interlocked.MemoryBarrier(); using (Core.Sha1Hash sha1hash = a.info_hash) { string hash = sha1hash.ToString(); if (TorrentList.ToList().Any(e => e.Hash == hash)) { Models.TorrentItem ti = TorrentList.ToList().First(f => f.Hash == hash); log.Debug("removing {0}", ti.Name); Application.Current.Dispatcher.BeginInvoke( System.Windows.Threading.DispatcherPriority.Normal, (Action) delegate() { TorrentList.Remove(ti); }); log.Info("{0} removed", ti.Name); } if (File.Exists("./Fastresume/" + hash + ".fastresume")) { File.Delete("./Fastresume/" + hash + ".fastresume"); } if (File.Exists("./Fastresume/" + hash + ".torrent")) { File.Delete("./Fastresume/" + hash + ".torrent"); } } }
private void PieceFinishedAlert(piece_finished_alert a) { Interlocked.MemoryBarrier(); using (Core.TorrentHandle th = a.handle) using (Core.Sha1Hash hash = th.info_hash()) { if (TorrentList.ToList().Any(x => x.Hash == hash.ToString())) { Models.TorrentItem ti = TorrentList.First(z => z.Hash == hash.ToString()); if (!ReferenceEquals(null, ti.Pieces.Parts) && ti.Pieces.Parts.Any(q => q.Id == a.piece_index)) { ti.Pieces.Parts[a.piece_index].Downloaded = true; log.Debug("{0} for {1}", a.piece_index, ti.Name); foreach (Models.FileEntry item in ti.FileList) { foreach (Models.Part part in item.Pieces.Where(k => k.Id == a.piece_index)) { part.Downloaded = true; } } if (ti.SequentialDownload) { if (ti.Pieces.Parts.Any(w => w.Downloaded == false)) { Models.Part mp = ti.Pieces.Parts.First(w => w.Downloaded == false); mp.Priority = 7; th.piece_priority(mp.Id, 7); } } } } } }
public FileEntry(Core.FileEntry fe) { Pieces = new ObservableCollection <Part>(); using (Core.Sha1Hash hash = fe.filehash) { Filehash = hash.ToString(); } Size = fe.size; Update(fe); }
public void RemoveTorrent(string hash, bool deleteFileToo = false) { using (Core.Sha1Hash sha1hash = new Core.Sha1Hash(hash)) using (Core.TorrentHandle th = _torrentSession.find_torrent(sha1hash)) { if (th != null && th.is_valid()) { _torrentSession.remove_torrent(th, Convert.ToInt32(deleteFileToo)); } } }
public void ResumeTorrent(string hash) { using (Core.Sha1Hash sha1hash = new Core.Sha1Hash(hash)) using (Core.TorrentHandle th = _torrentSession.find_torrent(sha1hash)) { if (th != null && th.is_valid()) { th.resume(); } } }
private void torrentItem_PropertyChanged(object sender, PropertyChangedEventArgs e) { Interlocked.MemoryBarrier(); if (e.PropertyName == "SequentialDownload") { Models.TorrentItem ti = (Models.TorrentItem)sender; using (Core.Sha1Hash hash = new Core.Sha1Hash(ti.Hash)) using (Core.TorrentHandle th = _torrentSession.find_torrent(hash)) { th.set_sequential_download(ti.SequentialDownload); if (ti.SequentialDownload) { // lower all parts priority to 1 foreach (Models.Part mp in ti.Pieces.Parts.Where(x => x.Downloaded == false)) { mp.Priority = 1; th.piece_priority(mp.Id, 1); } // highest priority only at first an last part if not already downloaded if (ti.Pieces.Parts.First().Downloaded == false || ti.Pieces.Parts.Last().Downloaded == false) { Models.Part firstPart = ti.Pieces.Parts.First(); Models.Part lastPart = ti.Pieces.Parts.Last(); firstPart.Priority = 7; lastPart.Priority = 7; th.piece_priority(firstPart.Id, 7); th.piece_priority(lastPart.Id, 7); } else { // first and last part already downloaded, proceed with next undownloaded part if (ti.Pieces.Parts.Any(w => w.Downloaded == false)) { Models.Part mp = ti.Pieces.Parts.First(w => w.Downloaded == false); mp.Priority = 7; th.piece_priority(mp.Id, 7); } } } else { // not sequencial, all part with default priority foreach (Models.Part mp in ti.Pieces.Parts.Where(x => x.Downloaded == false)) { mp.Priority = 4; th.piece_priority(mp.Id, 4); } } } } }
private async void StateUpdateAlert(Core.state_update_alert a) { Interlocked.MemoryBarrier(); log.Trace("state update alert for {0} torrents", a.status.Count()); if (a.status.Count() > 0 && log.IsDebugEnabled) { log.Debug("state update alert for {0} torrents", a.status.Count()); } foreach (Core.TorrentStatus ts in a.status) { using (ts) using (Core.Sha1Hash hash = ts.info_hash) { if (TorrentList.ToList().Any(z => z.Hash == hash.ToString())) { Models.TorrentItem ti = TorrentList.First(e => e.Hash == hash.ToString()); await System.Threading.Tasks.Task.Run(() => ti.Update(ts)); } } } }
public void Terminate() { Interlocked.MemoryBarrier(); log.Debug("Terminating"); IsTsunamiEnabled = false; _torrentSession.stop_natpmp(); _torrentSession.stop_upnp(); _torrentSession.stop_dht(); _torrentSession.stop_lsd(); _torrentSession.pause(); log.Debug("torrentSession paused"); log.Debug("stopping ticker"); _dispatcherTimer.Stop(); _dispatcherTimer.Enabled = false; log.Debug("ticker stopped"); while (!_torrentSession.alerts_empty()) { log.Debug("torrentSession alerts not empty. waiting 250ms"); Thread.Sleep(250); } log.Debug("torrentSession alerts empty!"); //stopWeb(); log.Debug("start save_state"); TerminateSaveResume(); log.Debug("save_state finished"); //outstanding_resume_data = 0; List <Models.TorrentItem> myList = new List <Models.TorrentItem>(TorrentList); log.Debug("need to process {0} torrents", myList.Count); int index = 0; foreach (Models.TorrentItem item in myList) { index++; log.Debug("processing torrent {0}", index); using (Core.Sha1Hash sha1hash = new Core.Sha1Hash(item.Hash)) { using (Core.TorrentHandle th = _torrentSession.find_torrent(sha1hash)) { if (th.has_metadata() && th.need_save_resume_data()) { log.Debug("{0} has metadata and need save resume. processing.", index); th.save_resume_data(1 | 2 | 4); ++outstanding_resume_data; log.Debug("{0} save resume executed: waiting 100ms", index); System.Threading.Thread.Sleep(100); } else { log.Debug("{0} no metadata or need save resume", index); } } } } //foreach (Models.TorrentItem item in myList) //{ // index++; // log.Debug("processing torrent " + index); // using (Core.Sha1Hash sha1hash = new Core.Sha1Hash(item.Hash)) // using (Core.TorrentHandle th = _torrentSession.find_torrent(sha1hash)) // { // if (th.has_metadata() && th.need_save_resume_data()) // { // log.Debug(index + " has metadata and need save resume. processing."); // th.save_resume_data(1 | 2 | 4); // ++outstanding_resume_data; // log.Debug(index + " save resume executed: waiting 100ms"); // System.Threading.Thread.Sleep(100); // } // else // { // log.Debug(index + " no metadata or need save resume"); // } // } //} no_more_resume = true; if (outstanding_resume_data != 0) { log.Debug("outstanding_resume_data = {0}: wait one", outstanding_resume_data); no_more_data.WaitOne(); } log.Debug("starting clear_alert_callback"); _torrentSession.clear_alert_callback(); log.Debug("clear_alert_callback finished"); log.Info("closed"); }
public TorrentItem(Core.TorrentStatus ts) { Formatter = x => ((int)x).ToString() + "%"; FileList = new ObservableCollection <FileEntry>(); using (Core.Sha1Hash hash = ts.info_hash) { Hash = hash.ToString(); } FileEntry fe; int piecesOffset = 0; using (Core.TorrentInfo tf = ts.torrent_file()) using (Core.FileStorage fs = tf.files()) { // per ogni file nel torrent for (int i = 0; i <= tf.num_files() - 1; i++) { using (Core.FileEntry cfe = fs.at(i)) using (Core.Sha1Hash hash = cfe.filehash) { // lo inserisco fe = new FileEntry(cfe); fe.FileName = fs.file_name(i); fe.IsValid = fs.is_valid(); fe.PieceSize = fs.piece_size(i); if (fe.PieceSize > fe.Size) { // one piece fe.Pieces.Add(new Part() { Id = piecesOffset, Downloaded = false, Priority = 4 }); } else { decimal piecesUsed = fe.Size / fe.PieceSize; for (int u = 0; u < piecesUsed; u++) { fe.Pieces.Add(new Part() { Id = piecesOffset, Downloaded = false, Priority = 4 }); piecesOffset++; } } FileList.Add(fe); } } } if (FileList.Count == 0) { // non ci sono file nel torrent fe = new FileEntry(); fe.FileName = ts.name; FileList.Add(fe); } SequentialDownload = ts.sequential_download; Update(ts); }