unit PKSTconst;

interface
uses
  SysUtils, HashUnit, IdStack, Contnrs, windows;

type
  on_fileproc = procedure(const node, filename: string) of object;
  on_msgproc = procedure(const node, msg: string) of object;
  on_rcvproc = procedure(const filename: string; const filesize,rcvsize: Int64) of object;
  on_sendproc = procedure(const node: string; const filename: string; const filesize,rcvsize: Int64) of object;

const
  PKST_DATASIZES : array [0..15] of Integer = (1376, 1934, 2958, 3982, 5006, 6030, 7054, 8078, 10126, 12174, 14222, 16270, 20366, 24462, 32654, 64000);

  PKSTFLAG = $5453504B;                // "PKST"
  PKSTVERSION = $1000;                 // 版本 1.00
  PKSTSCHFILENAME = 'gridcom.sch';

//  PKST_DATASIZE = 1400;                // 数据包大小
  PKST_DATAWINDOW = 3;                 // 数据窗口大小

  PKST_ServerLicenses = 2;             // 发布服务器授权数
  PKST_NodeLicenses = 10;              // 节点授权数

  PKST_SERVERPORT = 6644;              // 服务器监听端口
  PKST_CLIENTPORT = 9413;              // 客户端监听端口

  PKST_MAXTASK   = 3;                  // 最大任务数
  PKST_MAXCLIENT = 50;                 // 最大客户端连接数
  PKST_MAXSERVER = 2;                  // 最大服务端数目。

  PKST_CONN_TIMEOUT = 10;              // 连接超时
  PKST_CONN_LIVETIMEOUT = 60;          // 连接保持超时
  PKST_CONN_LIVE = 30;                 // 连接保持发送间隔
  PKST_DATA_TIMEOUT = 40;              // 数据传送超时

  PKST_CONNECT  = $00;                 // 连接
  PKST_REPLY    = $01;                 // 应答
  PKST_NODEINFO = $10;                 // 节点信息
  PKST_NODELIST = $11;                 // 节点列表
  PKST_ASKNLIST = $12;                 // 请求节点列表
  PKST_PUBLISH  = $20;                 // 发布信息
  PKST_DOWNLOAD = $30;                 // 下载请求
  PKST_MSG      = $40;                 // 消息
  PKST_SUBTITLE = $50;                 // 字幕
  PKST_DATA     = $FF;                 // 数据

  PKST_REQUEST_OK  = $00;              // 请求被接收
  PKST_REQUEST_ERR = $01;              // 请求被拒绝

  PKST_DATA_OK  = $00;                 // 数据成功接收
  PKST_DATA_TRY = $01;                 // 数据接收出错,要求重试
  PKST_DATA_ERR = $02;                 // 数据接收出错,不要求重试

Type
  PPKSTHead = ^TPKSTHead;
  TPKSTHead = packed record
    Flag     : Cardinal;
    Version  : word;
    DataType : Byte;
    DataSize : word;
  end;

  PPKSTNodeData = ^TPKSTNodeData;
  TPKSTNodeData = packed record
    NodeID   : TGUID;
    LocalIP  : TIdInAddr;
    NodeName : array [0..0] of Char;
  end;

  PPKSTNode = ^TPKSTNode;
  TPKSTNode = packed record
    IP      : TIdInAddr;
    LocalIP : TIdInAddr;            // 本地IP
    Port    : Word;
  end;

{
  PPKSTNodeInfo = ^TPKSTNodeInfo;
  TPKSTNodeInfo = packed record
    NodeAdd  : TPKSTNode;
    NodeID   : TGUID;
    NodeName : string;
  end;
{}

  PAPKSTNode = ^APKSTNode;
  APKSTNode  = array [0..0] of TPKSTNode;
  DAPKSTNode = array of TPKSTNode;

  PPKSTNodeList = ^TPKSTNodeList;
  TPKSTNodeList = packed record
    ListID    : TGUID;
    NodeCount : Integer;
    Reserve   : array [0..2] of Integer;
    NodeList  : APKSTNode;
  end;

  PPKSTASKNList = ^TPKSTASKNList;
  TPKSTASKNList = packed record
    ASKID      : TGUID;
    ServerName : array [0..0] of Char;
  end;

  PPKSTPublish = ^TPKSTPublish;
  TPKSTPublish = packed record
    PublishID : TGUID;
    FileHash  : TMD5Digest;
    FileSize  : Int64;
    FileName  : array [0..0] of Char;
  end;


  PPKSTDownload = ^TPKSTDownload;
  TPKSTDownload = packed record
    RequestID  : TGUID;
    TaskID     : TGUID;
    FileHash   : TMD5Digest;
    FileSize   : Int64;
    StartPos   : Int64;
    FileName   : array [0..0] of Char;
  end;

  PPKSTDLReply = ^TPKSTDLReply;
  TPKSTDLReply = packed record
    RequestID  : TGUID;
    SRCNode    : TGUID;
    State      : Byte;
  end;


  PPKSTData = ^TPKSTData;
  TPKSTData = packed record
    DataID     : TGUID;
    TaskID     : TGUID;
    FileSize   : Int64;
    StartPos   : Int64;
    DataSize   : word;
    Crc32      : DWord;
    Data   : array [0..0] of Byte;
  end;

  PPKSTDataReply = ^TPKSTDataReply;
  TPKSTDataReply = packed record
    DataID     : TGUID;
    State      : Byte;
    StartPos   : Int64;
  end;


  PPKSTDLinfo = ^TPKSTDLinfo;
  TPKSTDLinfo = packed record
    DLNode       : TGUID;
    SRCNode      : TGUID;
    DLState      : Byte;
    DownloadSize : Int64;
    FileSize     : Int64;
    FileHash     : TMD5Digest;
    Filename     : array [0..0] of Char;
  end;

  PPKSTReport = ^TPKSTReport;
  TPKSTReport = packed record
    ReportID     : TGUID;
    DownloadInfo : TPKSTDLinfo;
  end;

  TPKSTDownLoadInfo = record
    FileName       : string;
    SaveFileName   : string;
    PublishServer  : string;
    FileHash       : TMD5Digest;
    FileSize       : Int64;
    DownloadedSize : Int64;
  end;

{
  TPKSTDownLoadInfoEX = record
    DownloadID   : TGUID;
    DownloadHost : string;
    DownloadPort : Integer;
    StartTime    : TDateTime;
    Lastresponse : TDateTime;
    TryCount     : Integer;
    DownloadInfo : TPKSTDownLoadInfo;
  end;
{}

  TPKSTNodeInfo = Class
    NodeID       : TGUID;
    NodeName     : string;
    NodeState    : Byte;
    NodeAdd      : TPKSTNode;
    Lastresponse : Cardinal;
  end;

  TPKSTNodeInfoEX = Class
    ServerID     : TGUID;
    ServerName   : string;
    ServerHost   : string;
    LocalIP      : TIdInAddr;
    Lastresponse : Cardinal;
    ServerState  : Byte;
    Nodes        : TObjectList;            //List of TPKSTNodeInfo;
  public
    constructor Create;
    destructor Destroy; override;
  end;

  TPKSTDLTaskInfo = Class
    DownloadID   : TGUID;
    DownloadHost : string;
    DownloadPort : Integer;
    Node         : TPKSTNode;
    StartTime    : TDateTime;
    Lastresponse : TDateTime;
    TryCount     : Integer;
    DownloadInfo : TPKSTDownLoadInfo;
    State        : Integer;
    HFile        : THandle;
    HifoFile     : THandle;
    TempFileName : string;
  end;

  TPKSTHashData = packed record
    FileName : string;
    FileHash : TMD5Digest;
    case Integer of
      0:
        (FileSize : Int64;
         FileTime : TFileTime);
      1: (FileSizeRec : Int64Rec;
         FileTimeInt64 : Int64)
  end;

implementation

uses Classes;

{ TPKSTNodeInfoEX }

constructor TPKSTNodeInfoEX.Create;
begin
  Nodes := TObjectList.Create;
end;

destructor TPKSTNodeInfoEX.Destroy;
var
  i: integer;
begin
  for i:= Nodes.Count-1 downto 0 do
    TPKSTNodeInfo(Nodes.Extract(Nodes.Items[i])).Free;
  Nodes.Free;  
  inherited;
end;

end.
