unit Mod_Miranda;

interface

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

type
  TIMType = (IM_ICQ, IM_AIM);

  PIMItem = ^TIMItem;
  TIMItem = record
    UIN: String;
    Password: String;
    IMType: TIMType;
  end;

  TModuleMiranda = class(TModule)
  private
    procedure FreeIMList;
    function DecryptPass(const Password: String): String;
  protected
    class function GetModuleName: String; override;
    class function GetModuleVersion: Integer; override;
    class function GetModuleID: Integer; override;
    function GetIsEmpty: Boolean; override;        
  public
    IMList: 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_MIRANDA_PASS	  = 0;
  TYPE_MIRANDA_UIN	  = 1;
  TYPE_MIRANDA_SN	  = 2;

{ TModuleMiranda }

destructor TModuleMiranda.Destroy;
begin
  FreeIMList;
  inherited;
end;

procedure TModuleMiranda.FreeIMList;
var
  i: Integer;
begin
  if IMList = nil then Exit;
  for i := 0 to IMList.Count-1 do begin
    PIMItem(IMList.Items[i]).UIN := '';
    PIMItem(IMList.Items[i]).Password := '';
    Dispose(IMList.Items[i]);
  end;
  IMList.Free;
end;

function TModuleMiranda.DecryptPass(const Password: String): String;
var
  i: Integer;
begin
  Result := '';
  for i := 1 to Length(Password) do
    Result := Result + Chr(Ord(Password[i])-5);
end;

procedure TModuleMiranda.Run;
var
  DataItem: TDataItem;
  P: PIMItem;
begin
  inherited;

  IMList := TList.Create;

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

    case DataItem.cType of
      TYPE_MIRANDA_UIN: begin
        New(P); P.IMType := IM_ICQ;
        P.UIN := IntToStr(PLongWord(@DataItem.Data[1])^);
        IMList.Add(P);
      end;
      TYPE_MIRANDA_SN: begin
        New(P); P.IMType := IM_AIM;
        P.UIN := DataItem.Data;
        IMList.Add(P);
      end;
      TYPE_MIRANDA_PASS: if P <> nil then
        P.Password := DecryptPass(DataItem.Data);
    else begin
        FError := ERR_UNK_ITEM;
        Exit;
      end;
    end;
  end;
end;

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

class function TModuleMiranda.GetModuleName: String;
begin
  Result := 'Miranda';
end;

procedure TModuleMiranda.GetAsTree;
var
  i: Integer;
begin
  inherited;
  
  Append(ModuleName, 'Этот модуль содержит ICQ и AIM пароли Miranda-IM', ICON_FOLDER);
  MoveIn;
  for i := 0 to IMList.Count-1 do
    Append(PIMItem(IMList.Items[i]).UIN, GenHTMLList(['UIN/SN: ' + PIMItem(IMList.Items[i]).UIN, 'Password: ' + PIMItem(IMList.Items[i]).Password + ' (hex: ' + PassToHex(PIMItem(IMList.Items[i]).Password) + ')']), ICON_MIRANDA);
  MoveOut;
end;

class function TModuleMiranda.GetModuleID: Integer;
begin
  Result := MODULE_MIRANDA;
end;

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

function TModuleMiranda.GetIsEmpty: Boolean;
begin
  Result := IMList.Count = 0;
end;

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

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

procedure TModuleMiranda.ImportModule(DBStream: TMemoryStream);
var
  i: Integer;
  P: PIMItem;
begin
  inherited;

  IMList := TList.Create;

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

end.
