private void SetResumePrio(string torrentFile, int fileNum, byte newPrio) { if (!SetPrios) { return; } if (fileNum == -1) { fileNum = 0; } BTDictionary dict = GetTorrentDict(torrentFile); BTItem p = dict?.GetItem("prio"); if (p is null || (p.Type != BTChunk.kString)) { return; } BTString prioString = (BTString)(p); if ((fileNum < 0) || (fileNum > prioString.Data.Length)) { return; } Altered = true; PrioWasSet = true; prioString.Data[fileNum] = newPrio; }
public BTItem ReadString(System.IO.Stream sr, long length) { System.IO.BinaryReader br = new System.IO.BinaryReader(sr); byte[] c = br.ReadBytes((int)length); BTString bts = new BTString(); bts.Data = c; return(bts); }
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 void FixFileguard() { // finally, fix up ".fileguard" // this is the SHA1 of the entire file, without the .fileguard ResumeDat.GetDict().RemoveItem(".fileguard"); System.IO.MemoryStream ms = new System.IO.MemoryStream(); ResumeDat.Write(ms); System.Security.Cryptography.SHA1Managed sha1 = new System.Security.Cryptography.SHA1Managed(); byte[] theHash = sha1.ComputeHash(ms.GetBuffer(), 0, (int)ms.Length); ms.Close(); string newfg = BTString.CharsToHex(theHash, 0, 20); ResumeDat.GetDict().Items.Add(new BTDictionaryItem(".fileguard", new BTString(newfg))); }
private static int PercentBitsOn(BTString s) { int totalBits = 0; int bitsOn = 0; foreach (byte t in s.Data) { totalBits += 8; byte c = t; for (int j = 0; j < 8; j++) { if ((c & 0x01) != 0) { bitsOn++; } c >>= 1; } } return((100 * bitsOn + totalBits / 2) / totalBits); }
public string GetResumePrio(string torrentFile, int fileNum) { BTDictionary dict = GetTorrentDict(torrentFile); if (dict is null) { return(""); } BTItem p = dict.GetItem("prio"); if ((p is null) || (p.Type != BTChunk.kString)) { return(""); } BTString prioString = (BTString)(p); if ((fileNum < 0) || (fileNum > prioString.Data.Length)) { return(""); } int pr = prioString.Data[fileNum]; if (pr == BTPrio.Normal) { return("Normal"); } if (pr == BTPrio.Skip) { return("Skip"); } return(pr.ToString()); }
public BTItem ReadString(Stream sr, Int64 length) { BinaryReader br = new BinaryReader(sr); byte[] c = br.ReadBytes((int) length); BTString bts = new BTString(); bts.Data = c; return bts; }
public static int PercentBitsOn(BTString s) { int totalBits = 0; int bitsOn = 0; for (int i = 0; i < s.Data.Length; i++) { totalBits += 8; byte c = s.Data[i]; for (int j = 0; j < 8; j++) { if ((c & 0x01) != 0) bitsOn++; c >>= 1; } } return (100 * bitsOn + totalBits / 2) / totalBits; }
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 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); }