📄 bttrackerscrape.pas
字号:
unit BTTrackerScrape;
interface
uses
SysUtils, Contnrs, Hashes, Classes, BCode, MessageDigests, TSpyUtil;
type
TTrackerFile = class(TObject)
private
_Hash: String;
_Complete: Integer;
_Incomplete: Integer;
_Name: String;
_Downloaded: Integer;
public
property Hash: String read _Hash;
property Complete: Integer read _Complete;
property Incomplete: Integer read _Incomplete;
property Name: String read _Name;
property Downloaded: Integer read _Downloaded;
constructor Create(Hash: String; Complete: Integer; Incomplete: Integer; Name: String = ''; Downloaded: Integer = -1);
end;
TTrackerScrape = class(TObject)
private
_Err: TStringList;
_Files: TObjectHash;
_Tree: TObjectHash;
public
property Errors: TStringList read _Err;
property Files: TObjectHash read _Files;
property Tree: TObjectHash read _Tree;
constructor Create();
destructor Destroy(); override;
function Load(Stream: TStream): Boolean;
end;
implementation
{ TTrackerFile }
constructor TTrackerFile.Create(Hash: String; Complete, Incomplete: Integer; Name: String; Downloaded: Integer);
begin
_Hash := Hash;
_Complete := Complete;
_Incomplete := Incomplete;
_Name := Name;
_Downloaded := Downloaded;
inherited Create();
end;
{ TTrackerScrape }
constructor TTrackerScrape.Create();
begin
_Err := TStringList.Create();
_Files := TObjectHash.Create();
inherited Create();
end;
destructor TTrackerScrape.Destroy();
begin
FreeAndNil(_Err);
FreeAndNil(_Files);
inherited Destroy();
end;
function TTrackerScrape.Load(Stream: TStream): Boolean;
var
r: Boolean;
o: TObject;
f, info: TObjectHash;
h, k, n: String;
c, i, d: Integer;
begin
r := False;
_Files.Clear();
FreeAndNil(_Tree);
try
try
o := bdecodeStream(Stream);
if (o <> nil) then begin
if(o is TObjectHash) then begin
_Tree := o as TObjectHash;
if(_Tree.Exists('files')) then begin
if(_Tree['files'] is TObjectHash) then begin
f := _Tree['files'] as TObjectHash;
f.Restart();
while(f.Next()) do begin
k := f.CurrentKey();
if(f[k] is TObjectHash) then begin
info := f[k] as TObjectHash;
h := bin2Hex(k);
if(info.Exists('complete')) then c := (info['complete'] as TInt64).Value else c := -1;
if(info.Exists('incomplete')) then i := (info['incomplete'] as TInt64).Value else i := -1;
if(info.Exists('downloaded')) then d := (info['downloaded'] as TInt64).Value else d := -1;
if(info.Exists('name')) then n := (info['name'] as TString).Value else n := '';
_Files.Items[h] := TTrackerFile.Create(h,c,i,n,d);
end else begin
_Err.Add('Invalid Tracker Response; info for torrent[' + h + '] should be a dictionary');
end;
end;
r := True;
end else begin
_Err.Add('Invalid Tracker Response; "files" segment is not a list?');
end;
end else begin
_Err.Add('Invalid Tracker Response; missing "files" segment');
end;
end else begin
_Err.Add('Invalid Tracker Response; metainfo is malformed (not a dictionary)');
end;
end else begin
_Err.Add('Invalid Tracker Response; not bencoded metainfo');
end;
finally
if(not r) then FreeAndNil(o);
end;
except
_Err.Add('Error while trying to parse the Tracker state');
end;
Result := r;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -