You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
RnQ/RnQ/RnQProtocol.pas

1822 lines
50 KiB
Plaintext

{
This file is part of R&Q.
Under same license
}
unit RnQProtocol;
{$I RnQConfig.inc}
interface
uses
Windows, Classes, Types,
RnQNet, RDGlobal,
// globalLib,
RnQPrefsLib,
RnQGraphics32;
// contacts;
{$I NoRTTI.inc}
type
TwhatLog=(WL_connected, WL_disconnected,
WL_serverGot, WL_serverSent,
WL_heSent, WL_meSent, WL_connecting,
WL_sent_text, WL_rcvd_text{$IFDEF DEBUG_PACKETS}, WL_unknown{$ENDIF DEBUG_PACKETS});
Tstatus = (SC_ONLINE = 0, SC_OFFLINE, SC_UNK);
type
TXStatStr = record
Cap, Desc : String;
end;
type
TLIST_TYPES = (LT_ROSTER, LT_VISIBLE, LT_INVISIBLE, LT_TEMPVIS, LT_SPAM);
PStatusProp = ^TStatusProp;
TStatusProp = record
Cptn : String;
ShortName : AnsiString;
ImageName : TPicName;
idx : byte;
end;
type
TStatusArray = array of TStatusProp;
TStatusMenu = array of Byte;
TOnStatusDisable = packed record
tips,
blinking,
sounds,
OpenChat :boolean;
end;
TSessionParams = record
secret : String;
token : String;
tokenExpIn : Integer;
tokenTime : Integer;
end;
const
ICQProtoID = 1; //!!! ICQ +AIM
{$IFDEF ICQ_ONLY}
MAXProtoID = 1;
cProtosDesc : array[1..1] of String = ('ICQ');
{$ELSE ~ICQ_ONLY}
MRAProtoID = 2; //!!! Mail.ru Agent
XMPProtoID = 3; //!!! Jabber
OBIMProtoID = 4;
// AIMProtoID = 4; //!!! AIM
MAXProtoID = 4;
// ProtosDesc : array[1..4] of String = ('ICQ', 'AIM', 'Mail.ru Agent', 'XMPP');
cProtosDesc : array[1..4] of String = ('ICQ', 'Mail.ru Agent', 'XMPP', 'OBIMP');
{$ENDIF ICQ_ONLY}
const
cUsedProtos2 = [ICQProtoID
{$IFNDEF ICQ_ONLY}
{$IFDEF PROTOCOL_MRA}
,MRAProtoID
{$ENDIF PROTOCOL_MRA}
{$IFDEF PROTOCOL_XMP}
,XMPProtoID
{$ENDIF PROTOCOL_XMP}
{$IFDEF PROTOCOL_BIM}
,OBIMProtoID
{$ENDIF PROTOCOL_BIM}
{$ENDIF ICQ_ONLY}
];
cProtocolsCount =
{$IFDEF PROTOCOL_ICQ}
1+
{$ENDIF PROTOCOL_ICQ}
{$IFDEF PROTOCOL_MRA}
1+
{$ENDIF PROTOCOL_MRA}
{$IFDEF PROTOCOL_XMP}
1+
{$ENDIF PROTOCOL_XMP}
{$IFDEF PROTOCOL_BIM}
1+
{$ENDIF PROTOCOL_BIM}
0;
cUsedProtos : array[0..cProtocolsCount-1] of byte =
{$IFDEF ICQ_ONLY}
(ICQProtoID
{$ELSE ~ICQ_ONLY}
(
{$IFDEF PROTOCOL_ICQ}
ICQProtoID,
{$ENDIF PROTOCOL_ICQ}
{$IFDEF PROTOCOL_MRA}
MRAProtoID,
{$ENDIF PROTOCOL_MRA}
{$IFDEF PROTOCOL_BIM}
OBIMProtoID,
{$ENDIF PROTOCOL_BIM}
{$IFDEF PROTOCOL_XMP}
XMPProtoID
{$ENDIF PROTOCOL_XMP}
{$ENDIF ICQ_ONLY}
);
type
{$IFDEF UID_IS_UNICODE}
TUID = String;
TUID_Char = Char;
{$ELSE ansi}
TUID = AnsiString;
TUID_Char = AnsiChar;
{$ENDIF UID_IS_UNICODE}
TRnQContact = class;
TRnQCList = class;
TRnQCntClass = class of TRnQContact;
TRnQProtocol = class;
TProtoNotify = procedure (Sender:TRnQProtocol; event:Integer) of object;
TRnQProtoClass = class of TRnQProtocol;
TProtoEvent=(
IE_error,
IE_online,
IE_offline,
IE_incoming,
IE_outgoing,
IE_msg
);
{$IFDEF usesDC}
TProtoDirect=class;
Tdirects=class(Tlist)
proto : TRnQProtocol;
constructor create(sess_ : TRnQProtocol);
destructor Destroy; override;
function newFor(c:TRnQContact): TProtoDirect;
function findID(id : UInt64): TProtoDirect;
end; // Tdirects
// TDirectMode = (dm_init, dm_bin_direct, dm_bin_proxy_init, dm_bin_proxy);
TDirectMode = (dm_bin_direct, dm_bin_proxy);
TDirectDataAvailable = procedure (Sender: TObject; ErrCode: Word) of object;
TDirectDataNext = procedure (Sender: TObject; var Data : RawByteString;
var IsLast : Boolean) of object;
TDirectNotification = procedure (Sender: TObject; ErrCode: Word;
msg : String) of object;
TProtoDirect=class
protected
P_host, P_port: AnsiString;
public
sock : TRnQSocket;
eventID : UInt64;
contact : TRnQContact;
directs : Tdirects;
imserver : boolean;
imSender : Boolean;
needResume : Boolean;
Directed : Boolean;
UseLocProxy : Boolean;
mode : TDirectMode;
stage : byte;
kind :(DK_none, DK_file);
fileDesc : String;
// fileName :string;
// fileData :string;
buf : RawByteString;
fileCntReceived, fileCntTotal:integer;
fileSizeReceived, fileSizeTotal: Int64;
transferChkSum, fileChkSum : Cardinal;
receivedChkSum : Cardinal;
// Received : Int64;
fileName: String;
myspeed :integer;
hisVer :integer;
AOLProxy : record
ip : Cardinal;
port : word;
end;
data :pointer;
constructor Create; Virtual;
destructor Destroy; override;
protected
FOnDataAvailable, FOnDisconnect : TDirectDataAvailable;
FOnDataNext : TDirectDataNext;
FOnNotification : TDirectNotification;
{ procedure connected(Sender: TObject; Error: Word);
procedure received(Sender: TObject; Error: Word);
procedure sended(Sender: TObject; Error: Word);
procedure disconnected(Sender: TObject; Error: Word);
}
function myPort:integer;
// function myinfo:TRnQContact;
procedure sendPkt(const s: RawByteString);
{ function sendProxyCMD(cmd, flags :word; const data: RawByteString):boolean;
procedure connected2cli;
function parseFileDC0101(s : RawByteString) : Boolean;
function parseFileDC0205(s : RawByteString) : Boolean; // Resume request
procedure sendFilePrompt; // 0101
procedure sendACK_File; // 0202
procedure sendDone_File; // 0204
// procedure parseVcard(s : RawByteString);
}
public
// destructor Destroy;
{ procedure connect;
procedure connect2proxy;
procedure listen;
procedure close;
procedure Failed;
}
procedure ProcessSend;
// procedure DoneTransfer;
procedure logMsg(err : Word; const msg : String);
property OnDataAvailable : TDirectDataAvailable read FOnDataAvailable
write FOnDataAvailable;
property OnDataNext : TDirectDataNext read FOnDataNext
write FOnDataNext;
property OnDisconnect : TDirectDataAvailable read FOnDisconnect
write FOnDisconnect;
property OnNotification : TDirectNotification read FOnNotification
write FOnNotification;
property host:AnsiString read P_host;
property port:AnsiString read P_port;
end; // Tdirect
{$ENDIF usesDC}
// IRnQProtocol = interface;
(*
IRnQProtocol = interface//(IInterface)
['{BBAA1D48-8480-4E7D-ADEB-EE6AE65D393D}']
// public
// listener :TicqNotify;
// sock :Twsocket;
// server :Twsocket;
// directs :Tdirects;
// myInfo : TContact;
// constructor create;
// destructor destroy;
// procedure connect; overload;
// procedure connect(createUIN:boolean); overload;
// public
function getStatuses : TStatusArray;
function getVisibilitis : TStatusArray;
function getStatusMenu : TStatusMenu;
function getVisMenu : TStatusMenu;
function getContactClass : TRnQCntClass;
function getContact(const UID : TUID) : TRnQContact;
{ Get the algorithm name }
function ProtoName : String;
function ProtoElem : TRnQProtocol;
procedure GetPrefs(var pp : TRnQPref);
procedure SetPrefs(pp : TRnQPref);
procedure ResetPrefs;
procedure Clear;
procedure disconnect;
// procedure setStatus(s:Tstatus; inv:boolean);
// function getStatus:Tstatus;
function isOnline:boolean;
function isOffline:boolean;
function isReady:boolean; // we can send commands
function isConnecting:boolean;
function getStatus:byte;
procedure setStatus(st : Byte);
function getVisibility : byte;
function IsInvisible : Boolean;
function getStatusName: String;
function getStatusImg : TPicName;
function getXStatus:byte;
function imVisibleTo(c:TRnQContact):boolean;
procedure getClientPicAndDesc4(c:TRnQContact; var pPic : TPicName; var CliDesc : String);
function isMyAcc(c : TRnQContact) : Boolean;
function getMyInfo : TRnQContact;
function maxCharsFor(const c:TRnQContact):integer;
// function canSendMsgFor(c:TRnQContact; msg : String):integer;
// manage contact lists
function readList(l : TLIST_TYPES):TRnQCList;
procedure AddToList(l : TLIST_TYPES; cl:TRnQCList); overLoad;
procedure RemFromList(l : TLIST_TYPES; cl:TRnQCList); OverLoad;
// manage contacts
procedure AddToList(l : TLIST_TYPES; cnt:TRnQContact); OverLoad;
procedure RemFromList(l : TLIST_TYPES; cnt:TRnQContact); OverLoad;
function addContact(c:TRnQContact; isLocal : Boolean = false):boolean;
function removeContact(c:TRnQContact):boolean;
function validUid1(const uin:TUID):boolean;
// function getContact(uid : TUID) : TRnQContact;
function sendMsg(cnt : TRnQContact; var flags:dword; const msg:string; var requiredACK:boolean):integer; // returns handle
procedure UpdateGroupOf(cnt : TRnQContact);
// event managing
procedure InputChangedFor(cnt :TRnQContact; InpIsEmpty : Boolean; timeOut : boolean = false);
function compareStatusFor(cnt1, Cnt2 : TRnqContact) : Smallint;
procedure sendkeepalive;
// procedure notifyListeners(ev:TicqEvent);
// send packets
{
// function sendFLAP(ch:word; data:string):boolean;
// function sendSNAC(fam,sub:word; data:string):boolean;
// procedure sendKeepalive;
// function sendMsg(uin,flags:dword; msg:string; var requiredACK:boolean):integer; // returns handle
// procedure sendSMS(dest, msg:string; ack:boolean);
function sendAutoMsgReq(uin:integer):integer;
procedure sendContacts(uin,flags:dword; cl:TcontactList);
procedure sendQueryInfo(uin:integer);
procedure sendAddedYou(uin:integer);
function sendFileReq(uin:integer; msg,fn:string; size:integer):integer; // returns handle
procedure sendFileOk(msgID:TmsgID; c:Tcontact);
procedure sendFileAck(msgID:TmsgID);
procedure sendFileAbort(msgID:TmsgID);
procedure sendACK(status:integer; msg, snac:string);
procedure sendStatusCode;
procedure sendCreateUIN;
procedure sendDeleteUIN;
procedure sendSaveMyInfoAs(c:Tcontact);
procedure sendReqOfflineMsgs;
procedure sendDeleteOfflineMsgs;
procedure RemoveMeFromHisCL(uin : Integer);
}
procedure SetListener(l : TProtoNotify);
procedure AuthGrant(Cnt : TRnQContact);
procedure AuthRequest(cnt : TRnQContact; const reason : String);
function getPwd : String;
procedure setPwd(const pPWD : String);
function pwdEqual(const pass : String) : Boolean;
// procedure setMyInfo(cnt : TRnQContact);
function getStatusDisable : TOnStatusDisable;
function getPrefPage : TPrefFrameClass;
property pwd:String read getPwd write setPwd;
// property MyInfo :TRnQContact read getMyInfo write setMyInfo;
property statuses : TStatusArray read getStatuses;
end; // IRnQProtocol
*)
// TRnQProtocol = class (TObject, IRnQProtocol)
TRnQProtocol = class
// constructor Create; Virtual; Abstract;
// destructor Destroy; Virtual; Abstract;
// const ContactType : TRnQContactType = TICQContact;
// class function GetId: Word; virtual; abstract;
protected
FRefCount : Integer;
MyAccount : TUID;
listener : TProtoNotify;
public
fContactClass : TRnQCntClass;
progLogon : double;
loginServerAddr : String;
loginServerPort : AnsiString;
sock : TRnQSocket;
aProxy : Tproxy;
AccIDX : Integer;
{$IFDEF usesDC}
// server :Twsocket;
directs : Tdirects;
{$ENDIF usesDC}
SupportTypingNotif,
isSendTypingNotif : Boolean;
// contactsDB : TRnQCList;
class function _GetProtoName: string; virtual; abstract;
class function _isProtoUid(var uin:TUID):boolean; virtual; abstract;
class function _isValidUid1(const uin:TUID):boolean; virtual; abstract;
class function _getDefHost : Thostport; virtual; abstract;
class function _getContactClass : TRnQCntClass; virtual; abstract;
class function _getProtoServers : String; virtual; abstract;
class function _getProtoID : Byte; Virtual; Abstract;
class function _MaxPWDLen: Integer; virtual; abstract;
// class function _CreateProto(const uid : TUID) : IRnQProtocol; Virtual; Abstract;
class function _CreateProto(const uid : TUID) : TRnQProtocol; Virtual; Abstract;
class function _RegisterUser(var pUID : TUID; var pPWD : String): Boolean; Virtual; Abstract;
// Constructor Create(uid : TUID); Virtual; Abstract;
procedure SetListener(l : TProtoNotify); Virtual;
function getStatuses : TStatusArray; Virtual; Abstract;
function getVisibilitis : TStatusArray; Virtual; Abstract;
function getStatusMenu : TStatusMenu; Virtual; Abstract;
function getVisMenu : TStatusMenu; Virtual; Abstract;
function getContactClass : TRnQCntClass; Virtual; Abstract;
function getContact(const UID : TUID) : TRnQContact; Virtual; Abstract;
// function ProtoName : String; Virtual; Abstract;
function ProtoName : String; inline;
function ProtoElem : TRnQProtocol; inline;
procedure GetPrefs(var pp : TRnQPref); Virtual;
procedure SetPrefs(pp : TRnQPref); Virtual;
procedure ResetPrefs; Virtual;
procedure Clear; Virtual; Abstract;
procedure disconnect; Virtual; Abstract;
// procedure setStatus(s:Tstatus; inv:boolean);
// function getStatus:Tstatus;
function isOnline:boolean; Virtual; Abstract;
function isOffline:boolean; Virtual; Abstract;
function isReady:boolean; Virtual; Abstract; // we can send commands
function isConnecting:boolean; Virtual; Abstract;
function isSSCL:boolean; Virtual; Abstract;
function getStatus:byte; Virtual; Abstract;
procedure setStatus(st : Byte); Virtual; Abstract;
function getVisibility : byte; Virtual; Abstract;
function IsInvisible : Boolean; Virtual; Abstract;
function getStatusName: String; Virtual; Abstract;
function getStatusImg : TPicName; Virtual; Abstract;
function getXStatus:byte; Virtual; Abstract;
function imVisibleTo(c:TRnQContact):boolean; Virtual; Abstract;
procedure getClientPicAndDesc4(cnt:TRnQContact; var pPic : TPicName; var CliDesc : String); Virtual; Abstract;
function isMyAcc(c : TRnQContact) : Boolean; Virtual; Abstract;
function maxCharsFor(const c:TRnQContact; isBin : Boolean = false):integer; Virtual; Abstract;
// function canSendMsgFor(c:TRnQContact; msg : String):integer;
function canAddCntOutOfGroup : Boolean; Virtual; Abstract;
// manage contact lists
function readList(l : TLIST_TYPES):TRnQCList; Virtual; Abstract;
procedure AddToList(l : TLIST_TYPES; cl:TRnQCList); overLoad; Virtual; Abstract;
procedure RemFromList(l : TLIST_TYPES; cl:TRnQCList); OverLoad; Virtual; Abstract;
// manage contacts
procedure AddToList(l : TLIST_TYPES; cnt:TRnQContact); OverLoad; Virtual; Abstract;
procedure RemFromList(l : TLIST_TYPES; cnt:TRnQContact); OverLoad; Virtual; Abstract;
function isInList(l : TLIST_TYPES; cnt:TRnQContact) : Boolean; Virtual; Abstract;
function addContact(c:TRnQContact; isLocal : Boolean = false):boolean; Virtual; Abstract;
function removeContact(c:TRnQContact):boolean; Virtual; Abstract;
function validUid1(const uin:TUID):boolean; inline;
// function getContact(uid : TUID) : TRnQContact;
function ContactExists(const UID : TUID) : Boolean;
function sendMsg(cnt : TRnQContact; var flags:dword; const msg:string; var requiredACK:boolean):integer; Virtual; Abstract; // returns handle
procedure UpdateGroupOf(cnt : TRnQContact); Virtual; Abstract;
{$IFDEF usesDC}
function getNewDirect : TProtoDirect; Virtual; Abstract;
{$ENDIF usesDC}
// event managing
procedure InputChangedFor(cnt :TRnQContact; InpIsEmpty : Boolean; timeOut : boolean = false); Virtual; Abstract;
function compareStatusFor(cnt1, Cnt2 : TRnqContact) : Smallint; Virtual; Abstract;
procedure sendkeepalive; Virtual; Abstract;
procedure AuthGrant(Cnt : TRnQContact); Virtual; Abstract;
procedure AuthRequest(cnt : TRnQContact; const reason : String); Virtual; Abstract;
function getPwd : String; Virtual; Abstract;
function getPwdOnly : String; Virtual; Abstract;
function getSession : TSessionParams; Virtual; Abstract;
procedure setPwd(const pPWD : String); Virtual; Abstract;
function pwdEqual(const pass : String) : Boolean; Virtual; Abstract;
function getMyInfo : TRnQContact; Virtual; Abstract;
// procedure setMyInfo(cnt : TRnQContact);
function getStatusDisable : TOnStatusDisable; Virtual; Abstract;
function getPrefPage : TPrefFrameClass; Virtual; Abstract;
function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
function _AddRef: Integer; stdcall;
function _Release: Integer; stdcall;
procedure AfterConstruction; override; final;
procedure BeforeDestruction; override; final;
function getShowStr : String;
property ProtoID : byte read _getProtoID;
// class function getProtoByUID(uid : TUID) : TRnQProtoClass;
property MyAccNum : TUID read MyAccount;
property RefCount: Integer read FRefCount;
property pwd: String read getPwd write setPwd;
// property MyInfo :TRnQContact read getMyInfo write setMyInfo;
property statuses : TStatusArray read getStatuses;
property curXStatus : Byte read getXStatus;
end;
//type
// TRnQProto = class (TRnQProtocol, IRnQProtocol)
// end;
{
TRnQProtoHelper = class //(TObject, IRnQProtocol)
// constructor Create; Virtual; Abstract;
// destructor Destroy; Virtual; Abstract;
// const ContactType : TRnQContactType = TICQContact;
// class function GetId: Word; virtual; abstract;
function GetProtoName: string; virtual; abstract;
function isValidUid(var uin:TUID):boolean; virtual; abstract;
function GetClass : TRnQProtoClass; virtual; abstract;
// class function getProtoByUID(uid : TUID) : TRnQProtoClass;
end;
}
// PRnQContact = ^TRnQContact;
TRnQContact = class //(TObject)
public
UID : TUID;
UID2cmp : TUID; // LowerCase and without delimiters
SSIID : Integer;
// ClientStr : AnsiString;
ClientPic : TPicName;
ClientDesc : String;
fDisplay, // if user want to rename this contact
nick,
first,
last,
lclImportant : String;
// iProto : IRnQProtocol;
fProto : TRnQProtocol;
antispam : record
Tryes : Byte;
lastQuests : array of String;
end;
CntIsLocal : Boolean;
Authorized,
SendTransl:Boolean; // By Rapid D
typing : packed record
typingTime : TDateTime;
bSupport,
bIsTyping,
bIAmTyping : Boolean;
end;
group : Integer;
birth,
birthL, // Local Birthdate
LastBDInform,
lastTimeSeenOnline:TdateTime; // local time
{$IFDEF RNQ_AVATARS}
Icon_Path : String;
// icon : packed record
icon : packed record
Bmp : TRnQBitmap;
cash : TRnQBitmap;
ToShow : Byte;
Flags : byte;
HL : byte;
// icon_ShowPh : Boolean;
IsBmp : Boolean;
ID : Word;
// icon : Tbitmap;
end;
{$ENDIF RNQ_AVATARS}
data:pointer;
class function trimUID(const uid : TUID) : TUID; virtual; abstract;
constructor Create(pProto : TRnQProtocol; const uin_: TUID); Virtual;
destructor Destroy; override;
procedure clear; Virtual; abstract;
procedure clear1;
function getStatus : byte; virtual; abstract;
function getStatusName : String; virtual; abstract;
function statusImg : TPicName; virtual; abstract;
function isOnline : Boolean; virtual; abstract;
function isInvisible : Boolean; virtual; abstract;
function isOffline : Boolean; virtual; abstract;
function canEdit : Boolean; virtual; abstract;
function _getProtoID : Byte; inline;
function displayed:string;
function displayed4All:string;
function uin2Show : String; virtual; abstract;
function getFN : String;
function equals(c:TRnQContact):boolean; reintroduce; OverLoad;
function equals(const pUID: TUID):boolean; reintroduce; OverLoad;
function equals(pUIN: Integer):boolean; reintroduce; OverLoad;
procedure SetDisplay(const s : String); Virtual;
function GetDBrow : RawByteString; virtual; abstract;
function ParseDBrow(ItemType : Integer; const item : RawByteString) : Boolean; virtual; abstract;
procedure ViewInfo; virtual; abstract;
function isAcceptFile : Boolean; Virtual;
function GetBDay : TDateTime;
function Days2Bd : smallInt;
function imVisibleTo : Boolean;
function isInRoster : Boolean;
function isInList(l : TLIST_TYPES) : Boolean;
procedure SetGroupName(const pName : String);
// public
// function GetProto : IRnQProtocol;
function buin: RawByteString;
property Display : string read fDisplay write SetDisplay;
property ProtoID : byte read _getProtoID;
property Status : byte read getStatus;
end;
TcontactProc=procedure(c:TRnQContact);
TRnQContactType = type of TRnQContact;
TRnQCList=class(Tlist)
protected
enumIdx:integer;
public
procedure resetEnumeration;
function hasMore:boolean;
function getNext:TRnQContact;
function get(cls : TRnQContactType; const UID:TUID):TRnQContact; OverLoad;
function get(cls : TRnQContactType; const uin:integer):TRnQcontact; overload; //OverRide;
function getAt(const idx:integer):TRnQContact;
function putAt(const idx:integer; c:TRnQContact):boolean;
function exists(c:TRnQContact):boolean; overload;
function exists(const pProto : TRnQProtocol; const uin:TUID):boolean; overload;
function empty:boolean;
function add(const pProto : TRnQProtocol; const UID:TUID):TRnQcontact; overload; //OverRide;
function add(c:TRnQContact):boolean; overload;
function add(p:pointer):boolean; overload;
function add(cl:TRnQCList):TRnQCList; overload;
function remove(c:TRnQContact):boolean; overload;
function remove(p:pointer):boolean; overload;
function remove(cl:TRnQCList):TRnQCList; overload;
function intersect(cl:TRnQCList):TRnQCList;
function toString:RawByteString; reintroduce;
// function fromString(cls : TRnQContactType; const s: RawByteString; db:TRnQCList):boolean;
function fromString(pr : TRnQProtocol; const s: RawByteString; db:TRnQCList):boolean;
function clone:TRnQCList;
procedure assign(cl:TRnQCList);
procedure apply(p:TcontactProc);
// procedure setStatus(st: TStatus);
// function idxOf(iProto : IRnQProtocol; uin:TUID):integer; overload;
function idxOf(cls : TRnQContactType; const uin:TUID):integer; overload;
function idxOf(uin: Integer):integer; overload;
function _idxOf(const uid:TUID):integer; overload;
// function idxBySSID(ssid:Word):integer;
function buinlist: RawByteString;
function toIntArray:TIntegerDynArray;
// function getCount(group:integer=-1; OnlyOnline : Boolean = false):integer;
function getCount(group:integer; OnlyOnline : Boolean = false):integer;
procedure getOnlOfflCount(var pOnlCount, pOfflCount : Integer);
// procedure SetStatus(st: Byte);
// function C8SSIByGrp(grID : Integer): String;
// function SSIByGrp(grID : Integer): String;
property Count;
end; // TcontactList
var
// protocols : array of IRnQProtocol;
RnQProtos : array of TRnQProtoClass;
// RnQProtos : array of TRnQProtoHelper;
contactsDB: TRnQCList;
onContactCreation, onContactDestroying:TcontactProc;
onStatusDisable :array [0..15] of TOnStatusDisable;
// procedure RegisterProtocol(proto : IRnQProtocol);
// procedure RegisterProto(proto : TRnQProtoHelper);
procedure RegisterProto(proto : TRnQProtoClass);
// function ActiveProto : IRnQProtocol; Inline;
procedure logProtoPkt(what:TwhatLog; const head : String; const data: RawByteString='');
procedure FlushLogPktFile;
// function activeICQ : TicqSession; Inline;
procedure setProgBar(const proto:TRnQProtocol; v:double);
function Int2UID(const i : Integer) : TUID; Inline;
const
LogWhatNames:array [TwhatLog] of string=('CONNECTED','DISCONNECTED','CLIENT','SERVER','DC RCVD','DC SENT',
'CONNECTING', 'CLIENT', 'SERVER'{$IFDEF DEBUG_PACKETS}, 'UNKNOWN'{$ENDIF DEBUG_PACKETS});
// Flags for messages
IF_multiple = 1 shl 0; // multiple recipients
IF_offline = 1 shl 1; // sent while you were offline
IF_urgent = 1 shl 2; // send msg urgent
IF_noblink = 1 shl 3; // send to contact list
IF_no_matter = 1 shl 10; // If set, don't play sound
const // Avatar type
IS_AVATAR = 0;
IS_PHOTO = 1;
IS_NONE = 2;
var
GMToffset:TdateTime; // add it to a GMT time, subtract it from your local time
GMToffset0:TdateTime; // For OfflineMsg-s & ViewInfo
implementation
uses
SysUtils, StrUtils, OverbyteIcsWSocket,
{$IFDEF UNICODE}
AnsiStrings,
{$ENDIF UNICODE}
RQLog, RnQFileUtil, RQUtil, RDUtils, RnQGlobal, RnQCrypt, RnQPics,
globalLib, mainDlg, utilLib,
ThemesLib;
const
LogPics : array[TwhatLog] of TPicName = (PIC_CONNECTING, PIC_OFFGOING,
PIC_LEFT, PIC_RIGHT,
PIC_RIGHT, PIC_LEFT, PIC_CONNECTING,
PIC_LEFT, PIC_RIGHT{$IFDEF DEBUG_PACKETS}, PIC_HELP{$ENDIF DEBUG_PACKETS});
var
logPktFileData : AnsiString;
// ActProto : Integer;
{function ActiveProto : IRnQProtocol; inline;
begin
// if (ActProto >=0) and (ActProto < Length(protocols)) then
// Result := protocols[ActProto]
// else
// Result := NIL;
result := ICQ;
end;
}
{function trimUID(uid : TUID) : TUID;
var
i : word;
begin
result := '';
// i := 1;
// while i <= Length(uid) do
for I := 1 to length(uid) do
begin
if uid[i] in UID_CHARS then
Result := Result + uid[i];
// inc(i);
end;
end;
}
function TRnQProtocol.QueryInterface(const IID: TGUID; out Obj): HResult;
const
E_NOINTERFACE = HResult( $80004002 );
begin
if GetInterface( IID, Obj ) then
begin
Result := 0;
end else
begin
Result := E_NOINTERFACE;
end;
end;
function TRnQProtocol._AddRef: Integer;
begin
Result := InterlockedIncrement( FRefCount );
end;
function TRnQProtocol._Release: Integer;
begin
Result := InterlockedDecrement( FRefCount );
// if Result = 0 then
// Destroy;
end;
procedure TRnQProtocol.AfterConstruction;
begin
// Release the constructor's implicit refcount
InterlockedDecrement( FRefCount );
end;
procedure TRnQProtocol.BeforeDestruction;
begin
//if RefCount <> 0 then Error( reInvalidPtr );
end;
procedure TRnQProtocol.SetListener(l : TProtoNotify);
begin
listener := l;
end;
function TRnQProtocol.ProtoName : String;
begin
Result := _GetProtoName;
end;
function TRnQProtocol.ProtoElem : TRnQProtocol;
begin
Result := self;
end;
function TRnQProtocol.validUid1(const uin:TUID):boolean;
begin
Result := (Length(uin)>0) and self._isValidUid1(uin);
end;
function TRnQProtocol.ContactExists(const UID : TUID) : Boolean;
begin
Result := contactsDB.exists(self, uid);
end;
function TRnQProtocol.getShowStr : String;
var
mi : TRnQContact;
begin
mi := getMyInfo;
if Assigned(mi) then
Result := getMyInfo.displayed
else
Result := MyAccNum;
Result := '(' + _GetProtoName + ') ' + Result;
end;
procedure TRnQProtocol.GetPrefs(var pp: TRnQPref);
begin
pp.addPrefStr('last-server-ip', lastserverIP);
pp.addPrefStr('last-server-addr', lastserverAddr);
pp.addPrefStr('server-host', MainProxy.serv.host);
pp.addPrefInt('server-port', MainProxy.serv.port);
// pp.addPrefStr('server-host', LoginServer.host);
// pp.addPrefInt('server-port', LoginServer.port);
pp.addPrefBool('typing-notify-flag', SupportTypingNotif);
pp.addPrefBool('show-typing', isSendTypingNotif);
if not dontSavePwd //and not locked
then
pp.addPrefBlob64('crypted-password64', passCrypt(StrToUTF8(pwd)))
else
pp.DeletePref('crypted-password64');
pp.DeletePref('crypted-password');
end;
procedure TRnQProtocol.SetPrefs(pp: TRnQPref);
begin
if pp.prefExists('crypted-password64') then
pwd := UnUTF(passDecrypt(pp.getPrefBlob64Def('crypted-password64')))
else
pwd := passDecrypt(pp.getPrefBlobDef('crypted-password'));
pp.getPrefStr('last-server-ip', lastserverIP);
pp.getPrefStr('last-server-addr', lastserverAddr);
pp.getPrefBool('typing-notify-flag', SupportTypingNotif);
pp.getPrefBool('show-typing', isSendTypingNotif);
end;
procedure TRnQProtocol.ResetPrefs;
begin
lastServerIP:= '';
lastserverAddr := '';
SupportTypingNotif := True;
isSendTypingNotif := True;
pwd := '';
end;
{ TRnQContact }
{function TRnQContact.GetProto: IRnQProtocol;
begin
result := ICQ;
end;}
constructor TRnQcontact.create(pProto : TRnQProtocol; const uin_: TUID);
begin
inherited create;
clear1;
uid:=trimUID(uin_);
UID2cmp := LowerCase(uid);
fProto := pProto;
// if assigned(onContactCreation) then onContactCreation(self);
end; // create
destructor TRnQcontact.Destroy;
//var
// i : Byte;
begin
if assigned(onContactDestroying) then onContactDestroying(self);
SetLength(UID2cmp, 0);
SetLength(uid, 0);
inherited Destroy;
end;
function TRnQContact._getProtoID : Byte;
begin
Result := fProto.ProtoID;
end;
function TRnQContact.displayed: string;
begin
if display > '' then
result:=display else
if nick > '' then
result:=nick else
if first > '' then
result:=first else
if last > '' then
result:=last else
result:= uid;
if Length(result) > MaxDispayedLen then
SetLength(result, MaxDispayedLen);
end;
function TRnQContact.displayed4All: string;
begin
if nick > '' then
result:=nick else
if first > '' then
result:=first else
if last > '' then
result:=last else
result:= uid;
if Length(result) > MaxDispayedLen then
SetLength(result, MaxDispayedLen);
end;
function TRnQcontact.getFN : String;
begin
Result := Self.fProto.ProtoName + '_' + UID2cmp;
end;
// destroy
procedure TRnQcontact.clear1;
begin
uid:='';
UID2cmp := '';
nick:='';
first:='';
last:='';
// status:=SC_UNK;
fDisplay:='';
birthL:=0;
SSIID := 0;
// ClientStr := '';
ClientPic := '';
ClientDesc := '';
lclImportant := '';
CntIsLocal := True;
antispam.Tryes := 0;
icon.Bmp := NIL;
icon.cash :=NIL;
// antispam.lastQuests
//nodb:=FALSE;
end; // clear
function TRnQcontact.equals(c:TRnQcontact):boolean;
//var
// i, j : Byte;
begin
try
if (not assigned(self)) or (not assigned(c)) or (UID2cmp='') or (c.UID2cmp='') then
result := false
else
{ begin
i := 1; j := 1;
repeat
while uid[i] = ' ' do inc(i);
while c.uid[j] = ' ' do inc(j);
if (UpperCase(uid[i]) <> UpperCase(c.uid[j])) then
begin
result := false;
Exit;
end;
inc(i); inc(j);
until (j > Length(c.UID)) or (i > Length(UID));
if (j > Length(c.UID)) and (i > Length(UID)) then
result := True
else
result := false;
end;}
//
result:=(c.UID2cmp = UID2cmp)
except
result := False;
end;
end;
function TRnQcontact.equals(pUIN: Integer):boolean;
var
// i, j : Byte;
vUID : TUID;
begin
// try
vUID := Int2UID(pUIN);
if (not assigned(self)) or (self.UID2cmp='') or (vUID='') then
result := false
else
{ begin
i := 1; j := 1;
repeat
while uid[i] = ' ' do inc(i);
while pUIN[j] = ' ' do inc(j);
if (UpperCase(uid[i]) <> UpperCase(pUIN[j])) then
begin
result := false;
Exit;
end;
inc(i); inc(j);
until (j > Length(pUIN)) or (i > Length(UID));
if (j > Length(pUIN)) and (i > Length(UID)) then
result := True
else
result := false;
end;}
//
result:=(UID2cmp = vUID)
// except
// result := False;
// end;
end;
function TRnQcontact.equals(const pUID: TUID): boolean;
var
// i, j: Byte;
vUID: TUID;
begin
try
vUID := LowerCase(trimUID(pUID));
if (not assigned(self)) or (self.UID2cmp = '') or (vUID = '') then
Result := False
else
{ begin
i := 1; j := 1;
repeat
while uid[i] = ' ' do inc(i);
while pUIN[j] = ' ' do inc(j);
if (UpperCase(uid[i]) <> UpperCase(pUIN[j])) then
begin
result := false;
Exit;
end;
inc(i); inc(j);
until (j > Length(pUIN)) or (i > Length(UID));
if (j > Length(pUIN)) and (i > Length(UID)) then
result := True
else
result := false;
end;}
//
Result := (UID2cmp = vUID)
except
Result := False;
end;
end;
procedure TRnQcontact.SetDisplay(const s : String);
begin
fDisplay := s;
end;
function TRnQcontact.buin: RawByteString;
begin
// result:=intToStr(uin);
// result := uid;
// Result := uinAsStr;
result := AnsiChar(length(UID2cmp))+ AnsiString( UID2cmp ); // !!!!!!!!!
end; // buin
function TRnQcontact.imVisibleTo : Boolean;
begin
Result := fProto.imVisibleTo(self);
end;
function TRnQcontact.isInRoster : Boolean;
begin
Result := fProto.isInList(LT_ROSTER, self);
end;
function TRnQContact.isAcceptFile: Boolean;
begin
Result := false;
end;
function TRnQcontact.isInList(l : TLIST_TYPES) : Boolean;
begin
Result := fProto.isInList(l, self);
end;
function TRnQcontact.GetBDay : TDateTime;
begin
if birthL > 0 then
result := birthL
else
if birth > 0 then
result := birth
else
result := 0;
end;
function TRnQcontact.Days2Bd : smallInt;
const
// maxDate = EncodeDate(3000, 1, 1);
maxYear = 3000;
maxDate = maxYear * 365 + maxYear div 4 - maxYear div 100 + maxYear div 400 + 1 - DateDelta;
var
bd : TDateTime;
y, m, d : Word;
y2, m2, d2 : Word;
begin
bd := GetBDay;
if (bd = 0) or (bd > maxDate) then
Result := 2000//-1
else
begin
DecodeDate(date, y,m,d);
DecodeDate(bd, y2,m2,d2);
if (m2 < m) or ((m2=m) and (d2 < d)) then
y2 := y+1
else
y2 := y;
if not TryEncodeDate(y2, m2, d2, bd) then
if not TryEncodeDate(y2, m2+1, 1, bd) then // if 29 February :)
begin
Result := 2000;
Exit;
end;
Result := Trunc(bd - Date);
end;
end;
procedure TRnQcontact.SetGroupName(const pName : String);
var
gId : Integer;
begin
gID := groups.name2id(pName);
if gID >= 0 then
begin
self.group := gID
end
else
begin
if pName > '' then
begin
gID := groups.add();
groups.rename(gID, pName);
end
else
gId := 2000;
end;
self.group := gID;
end;
/////////////// TRnQCList ///////////////////////////////////////////////
function TRnQCList.getAt(const idx:integer):TRnQcontact;
begin
if (idx>=0) and (idx
// result:=TRnQContact(items[idx])
// result:= PRnQContact(List^[Idx])^
// result:= TRnQContact(List^[Idx])
result:= TRnQContact(List[Idx])
else
result:=NIL
end; // getAt
function TRnQCList.idxOf(cls : TRnQContactType; const uin: TUID):integer;
var
min,max:integer;
u : TUID;
uid : TUID;
c : TRnQcontact;
begin
UID := LowerCase(cls.trimUID(uin));
if TList(Self).count = 0 then
begin
result:=-1;
exit;
end;
min:=0;
max:= TList(Self).count - 1;
repeat
result:=(min+max) div 2;
c := getAt(result);
if Assigned(c) then
u:=c.UID2cmp
else
u := '';
if u = uid then
exit
else
if u > uid then
max:=result-1
else
min:=result+1;
until min > max;
result:=-1;
end; // idxOf
function TRnQCList._idxOf(const uid: TUID):integer;
var
min,max:integer;
u : TUID;
// uid : TUID;
c : TRnQcontact;
begin
// UID := AnsiLowerCase(iProto.getContactClass.trimUID(uin));
if count = 0 then
begin
result:=-1;
exit;
end;
min:=0;
max:=count-1;
repeat
result:=(min+max) div 2;
c := getAt(result);
if Assigned(c) then
u:=c.UID2cmp
else
u := '';
if u = uid then
exit
else
if u > uid then
max:=result-1
else
min:=result+1;
until min > max;
result:=-1;
end; // idxOf
function TRnQCList.idxOf(uin: Integer):integer;
var
min,max:integer;
// u : TUID;
uid : TUID;
c : TRnQcontact;
begin
uid := Int2UID(uin);
min:=0;
max:=count-1;
if max > 0 then
repeat
result:=(min+max) div 2;
c := getAt(result);
if Assigned(c) then
begin
if c.UID2cmp = uid then
exit
else
if c.UID2cmp > uid then
max:=result-1
else
min:=result+1;
end
else
min:=result+1;
until min > max;
result:=-1;
end; // idxOf
function TRnQCList.exists(c:TRnQContact):boolean;
begin result:=(c<>NIL) and (_idxOf(c.UID2cmp)>=0) end;
function TRnQCList.exists(const pProto : TRnQProtocol; const uin: TUID):boolean;
begin result:=idxOf(pProto.getContactClass, uin)>=0 end;
function TRnQCList.add(p:pointer):boolean;
begin result:=Tobject(p) is TRnQContact and add(TRnQContact(p)) end;
function TRnQCList.add(c:TRnQContact):boolean;
var
i:integer;
min,max:integer;
cnt : TRnQContact;
begin
result:=(c<>NIL) and not exists(c);
if result then
begin
// i:=0;
// while (i getAt(i).UID2cmp) do
// inc(i);
min:=0;
max:=count-1;
if max >= 0 then
repeat
i:=(min+max) div 2;
// i:=(min+max) shr 1;
cnt := getAt(i);
if Assigned(cnt) then
begin
// if c.UID2cmp = getAt(i).UID2cmp then
// exit
// else
if c.UID2cmp > cnt.UID2cmp then
min := i+1
else
max := i-1;
end
else
min:= i+1;
until min > max;
i := min;
insert(i, c);
end;
end; // add
function TRnQCList.putAt(const idx:integer; c:TRnQContact):boolean;
begin
result:=(c<>NIL) and not exists(c);
if result then
insert(idx, c);
end; // putAt
function TRnQCList.empty:boolean;
begin result:= count=0 end;
function TRnQCList.remove(c:TRnQContact):boolean;
begin result:=inherited remove(c) >= 0 end;
function TRnQCList.remove(p:pointer):boolean;
//begin result:= Tobject(p^) is TRnQContact and remove(PRnQContact(p)^) end;
begin result:= Tobject(p^) is TRnQContact and remove(TRnQContact(p)) end;
function TRnQCList.add(cl:TRnQCList):TRnQCList;
var
i:integer;
begin
result:=self;
if cl=NIL then exit;
for i:=0 to cl.count-1 do
add(cl.getAt(i));
end; // add
function TRnQCList.get(cls : TRnQContactType; const uin:integer):TRnQContact;
var
i:integer;
begin
i:=idxOf(uin);
if i >= 0 then
result:= TRnQContact(getAt(i))
else
begin
{
result:= cls.create(IntToStrA(uin));
add(result);
}
result := NIL;
end;
end; // getDB
function TRnQCList.add(const pProto : TRnQProtocol; const uid: TUID):TRnQcontact;
var
i:integer;
cls : TRnQCntClass;
u : TUID;
begin
Result := NIL;
cls := pProto.getContactClass;
if (Length(UID) = 0) then
Exit;
u := LowerCase(cls.trimUID(uid));
if Length(u)=0 then
Exit;
i:=_idxOf(u);
if i >= 0 then
result:= getAt(i)
else
begin
// result:= iProto.getContact(uid);
result:= cls.Create(pProto, uid);
add(result);
end;
end; // add
function TRnQCList.get(cls : TRnQContactType; const uid: TUID):TRnQContact;
var
i:integer;
u : TUID;
begin
Result := NIL;
if (Length(UID) = 0) then
Exit;
u := LowerCase(cls.trimUID(uid));
if (Length(u)=0) then
Exit;
i:=_idxOf(u);
if i >= 0 then
result:= getAt(i)
else
begin
{ result:= cls.create(uid);
add(result);}
result:= NIL;
end;
end; // getDB
function TRnQCList.remove(cl:TRnQCList):TRnQCList;
begin
result:=self;
if cl=NIL then exit;
inherited assign(cl, laSrcUnique);
end; // remove
function TRnQCList.intersect(cl:TRnQCList):TRnQCList;
begin
result:=self;
if cl=NIL then
begin
clear;
exit;
end;
inherited assign(cl, laAnd);
end; // intersect
function TRnQCList.toString: RawByteString;
var
i:integer;
begin
result:='';
for i:=0 to count-1 do
// result:=result + TRnQContact(items[i]).uid + CRLF;
// result:=result + PRnQContact(List^[I]).uid + CRLF;
// result:=result + StrToUTF8(TRnQContact(List^[I]).UID) + CRLF;
result:=result + StrToUTF8(TRnQContact(List[I]).UID) + CRLF;
end;
//function TRnQCList.fromString(cls : TRnQContactType; const s: RawByteString; db:TRnQCList):boolean;
function TRnQCList.fromString(pr : TRnQProtocol; const s: RawByteString; db:TRnQCList):boolean;
var
i:integer;
s1 : RawByteString;
ofs : Integer;
len : Integer;
begin
result:=TRUE;
clear;
ofs := 1;
// i := 1;
len := Length(s);
// while s>'' do
// while i>0 do
while ofs
begin
// i:=pos(#10,s);
i:=posEx(AnsiString(#10),s, ofs);
if (i>1) and (s[i-1]=#13) then
dec(i);
if i=0 then
i:= Len+1;
// s1 := copy(s,1,i-1);
s1 := copy(s, ofs, i-ofs);
try
// add(db.get(cls, UTF8ToStr(s1)))
add(db.add(pr, UTF8ToStr(s1)))
except
result:=FALSE
end;
if s[i]=#13 then
inc(i);
// system.delete(s,1,i);
ofs := i+1;
end;
end; // fromString
function TRnQCList.clone: TRnQCList;
var
i: integer;
begin
result := TRnQCList.create;
for i := 0 to count - 1 do
result.add(getAt(i))
end; // clone
procedure TRnQCList.resetEnumeration;
begin
enumIdx := 0
end;
function TRnQCList.hasMore:boolean;
begin
result := enumIdx < count
end;
function TRnQCList.getNext: TRnQContact;
begin
result := getAt(enumIdx);
inc(enumIdx);
end; // getNext
procedure TRnQCList.assign(cl: TRnQCList);
begin
if cl = nil then
clear
else
inherited assign(cl, laCopy)
end;
procedure TRnQCList.apply(p:TcontactProc);
var
i:integer;
begin
i:=0;
while i < count do
begin
// p(PRnQContact(items[i])^);
p(TRnQContact(items[i]));
inc(i);
end;
end;
function TRnQCList.buinlist:RawByteString;
var
i:integer;
begin
result:='';
i:=0;
while i < count do
begin
// result:=result+ PRnQContact(items[i]).buin;
result:=result+ TRnQContact(items[i]).buin;
inc(i);
end;
end; // buinList
function TRnQCList.toIntArray:TIntegerDynArray;
var
i:integer;
begin
setlength(result,count);
for i:=0 to count-1 do
// result[i]:=StrToIntDef(PRnQContact(items[i]).uid, 0);
result[i]:=StrToIntDef(TRnQContact(items[i]).uid, 0);
end; // toIntArray
function TRnQCList.getCount(group:integer; OnlyOnline : Boolean = false):integer;
var
i:integer;
begin
if group=-1 then
begin
result:=inherited count;
exit;
end;
result:=0;
for i:=0 to count-1 do
// if (TRnQContact(items[i]).group = group)
// and ((not OnlyOnline) or TRnQContact(items[i]).isOnline) then
// if (TRnQContact(List^[I]).group = group)
// if (TRnQContact(List^[I]).group = group)
if (TRnQContact(List[I]).group = group)
// and ((not OnlyOnline) or TRnQContact(List^[I]).isOnline) then
and ((not OnlyOnline) or TRnQContact(List[I]).isOnline) then
inc(result);
end; // count
procedure TRnQCList.getOnlOfflCount(var pOnlCount, pOfflCount : Integer);
var
// a, b,
i : Integer;
begin
pOnlCount:=0;
pOfflCount:=0;
for i:=0 to TList(self).count-1 do
with TRnQcontact(getAt(i)) do
// if group = groupid then
if isOffline then
inc(pOfflCount)
else
inc(pOnlCount);
// pOnlCount := a;
// pOfflCount := b;
end;
{procedure TRnQCList.SetStatus(st: Byte);
var
i:integer;
cnt : TRnQContact;
begin
for i:=0 to count-1 do
begin
cnt := getAt(i);
// if cnt is TICQContact then
// TICQContact(cnt).status:=st;
cnt.status := st;
end;
end;}
procedure logProtoPkt(what:TwhatLog; const head : String; const data: RawByteString='');
var
sA : RawByteString;
sU : String;
needHash : Boolean;
begin
needHash := not (what in [WL_sent_text, WL_rcvd_text]);
if needHash then
begin
sA := data;
sU := '';
end
else
begin
sA := '';
sU := String(data);
end;
if (logpref.pkts.onwindow) then
logEvPkt(head, sU, sA, LogPics[what], needHash);
if logpref.pkts.onfile then
begin
if needHash then
sA := hexDump(data)
else
sA := data;
logPktFileData := logPktFileData + AnsiString(head)+CRLF+ sA +CRLF;
end;
end;
procedure FlushLogPktFile;
begin
if Length(logPktFileData) > 0 then
if appendFile(logPath+packetslogFilename, logPktFileData)
or (Length(logPktFileData) > MByte) then
logPktFileData := '';
end;
{procedure RegisterProto(proto : TRnQProtoHelper);
var
i : Integer;
begin
i := Length(RnQProtos);
SetLength(RnQProtos, i+1);
RnQProtos[i] := proto;
end;
}
procedure RegisterProto(proto : TRnQProtoClass);
var
i : Integer;
begin
i := Length(RnQProtos);
SetLength(RnQProtos, i+1);
RnQProtos[i] := proto;
end;
procedure setProgBar(const proto:TRnQProtocol; v:double);
begin
if Assigned(proto) then
proto.progLogon := v
else
progStart := v;
//sbar.repaint;
if Assigned(RnQMain.PntBar) then
rnqMain.PntBar.repaint;
if assigned(statusIcon) and assigned(statusIcon.trayIcon) then
statusIcon.trayIcon.update;
end;
{$IFDEF usesDC}
constructor Tdirects.create(sess_ : TRnQProtocol);
begin
proto := sess_;
end; // create
destructor Tdirects.Destroy;
var
i:Integer;
begin
for i:=count-1 downto 0 do
TProtoDirect(items[i]).free;
inherited;
end; // destroy
function Tdirects.newFor(c:TRnQContact):TProtoDirect;
begin
result := c.fProto.getNewDirect;
if Assigned(Result) then
begin
result.contact:=c;
result.directs:=self;
add(result);
end;
end; // newFor
function Tdirects.findID(id : UInt64):TProtoDirect;
var
i:Integer;
begin
Result := NIL;
for i:=count-1 downto 0 do
if TProtoDirect(items[i]).eventID = id then
begin
Result := TProtoDirect(items[i]);
Exit;
end;
end;
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
constructor TProtoDirect.create;
begin
sock:=TRnQSocket.create(NIL);
sock.tag:=integer(@self);
// sock.OnDataAvailable:=received;
// sock.OnSessionClosed:=disconnected;
//sock.OnSocksError := OnProxyError;
imserver:=TRUE;
kind:=DK_none;
stage := 0;
mode := dm_bin_direct;
Directed := False;
needResume := False;
AOLProxy.ip := 0;
AOLProxy.port := 0;
UseLocProxy := True;
myspeed:=100;
end; // create
destructor TProtoDirect.Destroy;
begin
directs.remove(self);
if (sock.State = wsConnected)or
(sock.State = wsListening)
then
begin
sock.Close;
sock.WaitForClose; // prevent to change properties while the socket is open
end;
sock.free;
SetLength(buf, 0);
SetLength(P_host, 0);
SetLength(P_port, 0);
SetLength(fileName, 0);
// SetLength(buf, 0);
inherited;
end; // destroy
procedure TProtoDirect.ProcessSend;
var
b : Boolean;
begin
SetLength(buf, 0);
b := false;
if Assigned(OnDataNext) then
OnDataNext(self, buf, b);
if Length(buf)>0 then
sendPkt(buf);
if b then
sock.Close;
end;
function TProtoDirect.myPort:integer;
begin
tryStrToInt(sock.getxPort, result)
end;
procedure TProtoDirect.sendPkt(const s: RawByteString);
begin
//s:=word_LEasStr(length(s))+s;
//sock.sendStr(s);
sock.PutStringInSendBuffer(s);
if sock.State <> wsClosed then
begin
sock.Send(nil, 0);
//sock.SendFlags :=
//sock.SocketSndBufSize
//sock.Send(s);
{
with TicqSession(directs.proto) do
// with directs.proto do
begin
eventData:=s;
eventDirect:=self;
notifyListeners(IE_dcSent);
end;}
end;
end; // sendPkt
procedure TProtoDirect.logMsg(err : Word; const msg : String);
begin
if Assigned(OnNotification) then
OnNotification(Self, err, msg);
end;
{$ENDIF usesDC}
///////////////////////////////////////////////////////////////////////
function Int2UID(const i : Integer) : TUID;
begin
{$IFDEF UID_IS_UNICODE}
Result := IntToStr(i)
{$ELSE ansi}
Result := IntToStrA(i)
{$ENDIF UID_IS_UNICODE}
end;
var
TZinfo:TTimeZoneInformation;
INITIALIZATION
GetTimeZoneInformation(TZinfo);
case GetTimeZoneInformation(TZInfo) of
TIME_ZONE_ID_STANDARD: GMToffset:=TZInfo.StandardBias;
TIME_ZONE_ID_DAYLIGHT: GMToffset:=TZInfo.DaylightBias;
else GMToffset := 0;
end;
GMToffset:=-(TZinfo.bias+GMToffset)/(24*60);
GMToffset0 :=-(TZinfo.bias)/(24*60);
// ActProto := -1;
contactsDB:=TRnQCList.create;
FINALIZATION
contactsDB.free;
end.