public List <string> AllFilesInTorrent() { List <string> r = new List <string>(); BTItem bti = GetItem("info"); if ((bti is null) || (bti.Type != BTChunk.kDictionary)) { return(null); } BTDictionary infoDict = (BTDictionary)(bti); bti = infoDict.GetItem("files"); if (bti is null) // single file torrent { bti = infoDict.GetItem("name"); if ((bti is null) || (bti.Type != BTChunk.kString)) { return(null); } r.Add(((BTString)bti).AsString()); } else { // multiple file torrent BTList fileList = (BTList)(bti); foreach (BTItem it in fileList.Items) { BTDictionary file = (BTDictionary)(it); BTItem thePath = file.GetItem("path"); if (thePath.Type != BTChunk.kList) { return(null); } BTList pathList = (BTList)(thePath); // want the last of the items in the list, which is the filename itself int n = pathList.Items.Count - 1; if (n < 0) { return(null); } BTString fileName = (BTString)(pathList.Items[n]); r.Add(fileName.AsString()); } } return(r); }
public BTItem ReadList(System.IO.FileStream sr) { BTList ll = new BTList(); for (;;) { BTItem next = ReadNext(sr); if (next.Type == BTChunk.kListOrDictionaryEnd) { return(ll); } ll.Items.Add(next); } }
public void AlterResume(string torrentFile, int fileNum, string toHere) { toHere = RemoveUT(toHere); BTDictionary dict = this.GetTorrentDict(torrentFile); if (dict == null) return; this.Altered = true; if (fileNum == -1) // single file torrent { BTItem p = dict.GetItem("path"); if (p == null) dict.Items.Add(new BTDictionaryItem("path", new BTString(toHere))); else { if (p.Type != BTChunk.kString) return; ((BTString) p).SetString(toHere); } } else { // multiple file torrent, uses a list called "targets" BTItem p = dict.GetItem("targets"); BTList theList = null; if (p == null) { theList = new BTList(); dict.Items.Add(new BTDictionaryItem("targets", theList)); } else { if (p.Type != BTChunk.kList) return; theList = (BTList) (p); } if (theList == null) return; // the list contains two element lists, of integer/string which are filenumber/path BTList thisFileList = null; // see if this file is already in the list for (int i = 0; i < theList.Items.Count; i++) { if (theList.Items[i].Type != BTChunk.kList) return; BTList l2 = (BTList) (theList.Items[i]); if ((l2.Items.Count != 2) || (l2.Items[0].Type != BTChunk.kInteger) || (l2.Items[1].Type != BTChunk.kString)) return; int n = (int) ((BTInteger) (l2.Items[0])).Value; if (n == fileNum) { thisFileList = l2; break; } } if (thisFileList == null) // didn't find it { thisFileList = new BTList(); thisFileList.Items.Add(new BTInteger(fileNum)); thisFileList.Items.Add(new BTString(toHere)); theList.Items.Add(thisFileList); } else thisFileList.Items[1] = new BTString(toHere); } }
public BTItem ReadList(FileStream sr) { BTList ll = new BTList(); for (;;) { BTItem next = this.ReadNext(sr); if (next.Type == BTChunk.kListOrDictionaryEnd) return ll; ll.Items.Add(next); } }
public bool ProcessTorrentFile(string torrentFile, TreeView tvTree, CommandLineArgs args) { // ---------------------------------------- // read in torrent file if (tvTree != null) { tvTree.Nodes.Clear(); } BEncodeLoader bel = new BEncodeLoader(); BTFile btFile = bel.Load(torrentFile); if (btFile is null) { return(false); } BTItem bti = btFile.GetItem("info"); if ((bti is null) || (bti.Type != BTChunk.kDictionary)) { return(false); } BTDictionary infoDict = (BTDictionary)(bti); bti = infoDict.GetItem("piece length"); if ((bti is null) || (bti.Type != BTChunk.kInteger)) { return(false); } long pieceSize = ((BTInteger)bti).Value; bti = infoDict.GetItem("pieces"); if ((bti is null) || (bti.Type != BTChunk.kString)) { return(false); } BTString torrentPieces = (BTString)(bti); bti = infoDict.GetItem("files"); if (bti is null) // single file torrent { bti = infoDict.GetItem("name"); if ((bti is null) || (bti.Type != BTChunk.kString)) { return(false); } BTString di = (BTString)(bti); string nameInTorrent = di.AsString(); BTItem fileSizeI = infoDict.GetItem("length"); long fileSize = ((BTInteger)fileSizeI).Value; NewTorrentEntry(torrentFile, -1); if (DoHashChecking) { byte[] torrentPieceHash = torrentPieces.StringTwentyBytePiece(0); FileInfo fi = FindLocalFileWithHashAt(torrentPieceHash, 0, pieceSize, fileSize); if (fi != null) { FoundFileOnDiskForFileInTorrent(torrentFile, fi, -1, nameInTorrent); } else { DidNotFindFileOnDiskForFileInTorrent(torrentFile, -1, nameInTorrent); } } FinishedTorrentEntry(torrentFile, -1, nameInTorrent); // don't worry about updating overallPosition as this is the only file in the torrent } else { long overallPosition = 0; long lastPieceLeftover = 0; if (bti.Type != BTChunk.kList) { return(false); } BTList fileList = (BTList)(bti); // list of dictionaries for (int i = 0; i < fileList.Items.Count; i++) { Prog(100 * i / fileList.Items.Count, i.ToString()); if (fileList.Items[i].Type != BTChunk.kDictionary) { return(false); } BTDictionary file = (BTDictionary)(fileList.Items[i]); BTItem thePath = file.GetItem("path"); if (thePath.Type != BTChunk.kList) { return(false); } BTList pathList = (BTList)(thePath); // want the last of the items in the list, which is the filename itself int n = pathList.Items.Count - 1; if (n < 0) { return(false); } BTString fileName = (BTString)(pathList.Items[n]); BTItem fileSizeI = file.GetItem("length"); long fileSize = ((BTInteger)fileSizeI).Value; int pieceNum = (int)(overallPosition / pieceSize); if (overallPosition % pieceSize != 0) { pieceNum++; } NewTorrentEntry(torrentFile, i); if (DoHashChecking) { byte[] torrentPieceHash = torrentPieces.StringTwentyBytePiece(pieceNum); FileInfo fi = FindLocalFileWithHashAt(torrentPieceHash, lastPieceLeftover, pieceSize, fileSize); if (fi != null) { FoundFileOnDiskForFileInTorrent(torrentFile, fi, i, fileName.AsString()); } else { DidNotFindFileOnDiskForFileInTorrent(torrentFile, i, fileName.AsString()); } } FinishedTorrentEntry(torrentFile, i, fileName.AsString()); int sizeInPieces = (int)(fileSize / pieceSize); if (fileSize % pieceSize != 0) { sizeInPieces++; // another partial piece } lastPieceLeftover = (lastPieceLeftover + (int)((sizeInPieces * pieceSize) - fileSize)) % pieceSize; overallPosition += fileSize; } // for each file in the torrent } if (tvTree != null) { tvTree.BeginUpdate(); btFile.Tree(tvTree.Nodes); tvTree.ExpandAll(); tvTree.EndUpdate(); tvTree.Update(); } Prog(0, string.Empty); return(true); }
public void AlterResume(string torrentFile, int fileNum, string toHere) { toHere = RemoveUT(toHere); BTDictionary dict = GetTorrentDict(torrentFile); if (dict is null) { return; } Altered = true; if (fileNum == -1) // single file torrent { BTItem p = dict.GetItem("path"); if (p is null) { dict.Items.Add(new BTDictionaryItem("path", new BTString(toHere))); } else { if (p.Type != BTChunk.kString) { return; } ((BTString)p).SetString(toHere); } } else { // multiple file torrent, uses a list called "targets" BTItem p = dict.GetItem("targets"); BTList theList = null; if (p is null) { theList = new BTList(); dict.Items.Add(new BTDictionaryItem("targets", theList)); } else { if (p.Type != BTChunk.kList) { return; } theList = (BTList)(p); } // the list contains two element lists, of integer/string which are filenumber/path BTList thisFileList = null; // see if this file is already in the list foreach (BTItem t in theList.Items) { if (t.Type != BTChunk.kList) { return; } BTList l2 = (BTList)(t); if ((l2.Items.Count != 2) || (l2.Items[0].Type != BTChunk.kInteger) || (l2.Items[1].Type != BTChunk.kString)) { return; } int n = (int)((BTInteger)(l2.Items[0])).Value; if (n == fileNum) { thisFileList = l2; break; } } if (thisFileList is null) // didn't find it { thisFileList = new BTList(); thisFileList.Items.Add(new BTInteger(fileNum)); thisFileList.Items.Add(new BTString(toHere)); theList.Items.Add(thisFileList); } else { thisFileList.Items[1] = new BTString(toHere); } } }
public List <TorrentEntry> AllFilesBeingDownloaded() { List <TorrentEntry> r = new List <TorrentEntry>(); BEncodeLoader bel = new BEncodeLoader(); foreach (BTDictionaryItem dictitem in ResumeDat.GetDict().Items) { if ((dictitem.Type != BTChunk.kDictionaryItem)) { continue; } if ((dictitem.Key == ".fileguard") || (dictitem.Data.Type != BTChunk.kDictionary)) { continue; } if (dictitem.Data is BTError err) { logger.Error($"Error finding BT items: {err.Message}"); return(r); } BTDictionary d2 = (BTDictionary)(dictitem.Data); BTItem p = d2.GetItem("prio"); if ((p is null) || (p.Type != BTChunk.kString)) { continue; } BTString prioString = (BTString)(p); string directoryName = Path.GetDirectoryName(ResumeDatPath) + System.IO.Path.DirectorySeparatorChar; string torrentFile = dictitem.Key; if (!File.Exists(torrentFile)) // if the torrent file doesn't exist { torrentFile = directoryName + torrentFile; // ..try prepending the resume.dat folder's path to it. } if (!File.Exists(torrentFile)) { continue; // can't find it. give up! } BTFile tor = bel.Load(torrentFile); if (tor is null) { continue; } List <string> a = tor.AllFilesInTorrent(); if (a is null) { continue; } int c = 0; p = d2.GetItem("path"); if ((p is null) || (p.Type != BTChunk.kString)) { continue; } string defaultFolder = ((BTString)p).AsString(); BTItem targets = d2.GetItem("targets"); bool hasTargets = ((targets != null) && (targets.Type == BTChunk.kList)); BTList targetList = (BTList)(targets); //foreach (var i in d2.Items) //{ //logger.Info($" {i.Key} {i.Data.AsText()}"); //} foreach (string s in a) { if ((c < prioString.Data.Length) && (prioString.Data[c] != BTPrio.Skip)) { try { string saveTo = FileHelper .FileInFolder(defaultFolder, TVSettings.Instance.FilenameFriendly(s)).Name; if (hasTargets) { // see if there is a target for this (the c'th) file foreach (BTItem t in targetList.Items) { BTList l = (BTList)(t); BTInteger n = (BTInteger)(l.Items[0]); BTString dest = (BTString)(l.Items[1]); if (n.Value == c) { saveTo = dest.AsString(); break; } } } int percent = (a.Count == 1) ? PercentBitsOn((BTString)(d2.GetItem("have"))) : -1; bool completed = ((BTInteger)d2.GetItem("order")).Value == -1; TorrentEntry te = new TorrentEntry(torrentFile, saveTo, percent, completed, torrentFile); r.Add(te); } catch (System.IO.PathTooLongException ptle) { //this is not the file we are looking for logger.Debug(ptle); } } c++; } } return(r); }