⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 icqworks.pas

📁 ICQ客户端源代码
💻 PAS
📖 第 1 页 / 共 5 页
字号:
  S: String;
begin
  count := 0;
  S := '';
  if Contacts.Count > 0 then
    for i := 0 to Contacts.Count - 1 do
    begin
      if ExtractName(Contacts.Strings[i]) <> '' then
      begin
        S := S + ExtractName(Contacts.Strings[i]) + #$fe;
        if ExtractValue(Contacts.Strings[i]) = '' then
          S := S + ExtractName(Contacts.Strings[i]) + #$fe
        else
          S := S + ExtractValue(Contacts.Strings[i]) + #$fe;
        Inc(count);
      end;
    end;
  Result := IntToStr(count) + #$fe + S;
end;

{-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=}
{The first packet sent by the client after connecting and receiving
the SRV_HELLO packet from the server. The packet basiclly identifies
what kind and version of client is connecting along with the user's
UIN and password.}
procedure CreateCLI_IDENT(Pkt: PRawPkt; UIN: LongWord; Password: String; var Seq: Word);
begin
  PktInit(Pkt, 1, Seq);                         //Channel 1
  PktInt(Pkt, 1, 4);                            //00 00 00 01
  PktTLV(Pkt, 1, IntToStr(UIN));                //Adding user's UIN

  ICQEncryptPassStr(Password);                  //Encrypt password
  PktTLV(Pkt, 2, Password);                     //Adding encrypted password

  // Pack client identification details. We identify ourselves as ICQ 2003b.
  // eraser 13.05.2004
  PktTLV(Pkt, 3, 'ICQ Inc. - Product of ICQ (TM).2003b.5.56.1.3916.85');   //Cookie
  //Uknowns
  PktInt(Pkt, $00160002, 4); PktInt(Pkt, $010a, 2);
  PktInt(Pkt, $00170002, 4); PktInt(Pkt, $0005, 2);
  PktInt(Pkt, $00180002, 4); PktInt(Pkt, $0025, 2);
  PktInt(Pkt, $00190002, 4); PktInt(Pkt, $0001, 2);
  PktInt(Pkt, $001a0002, 4); PktInt(Pkt, $0e90, 2);
  PktInt(Pkt, $00140004, 4); PktInt(Pkt, $00000055, 4);
  PktTLV(Pkt, $000f, 'en');
  PktTLV(Pkt, $000e, 'us');
  PktFinal(Pkt);                                //Finalize packet
end;

{Sent as the first packet after the client has logged in
to the second server and received the SRV_HELLO packet.}
procedure CreateCLI_COOKIE(Pkt: PRawPkt; const Cookie: String; var Seq: Word);
begin
  PktInit(Pkt, 1, Seq);                         //Channel 1
  PktInt(Pkt, 1, 4);                            //00 00 00 01
  PktTLV(Pkt, 6, Cookie);                       //TLV(06) Cookie
  PktFinal(Pkt);                                //Finalize packet
end;

{This packet is a response to SNAC(1,3), SRV_FAMILIES. This tells
the server which SNAC families and their corresponding versions
which the client understands. This also seems to identify the client
as an ICQ vice AIM client to the server.}
procedure CreateCLI_FAMILIES(Pkt: PRawPkt; var Seq: Word);
begin
  PktInit(Pkt, 2, Seq);                         //Channel 2
  PktSnac(Pkt, 1, $17, 0, 0);                   //Snac: Type x01/x17, ID x0000, Flags 0
  PktInt(Pkt, $00010003, 4);                    //Family x01 is Version x03
  PktInt(Pkt, $00130002, 4);                    //Family x13 at Version x02
  PktInt(Pkt, $00020001, 4);                    //Family x02 at Version x01
  PktInt(Pkt, $00030001, 4);                    //Family x03 at Version x01
  PktInt(Pkt, $00150001, 4);                    //Family x15 at Version x01
  PktInt(Pkt, $00040001, 4);                    //Family x04 at Version x01
  PktInt(Pkt, $00060001, 4);                    //Family x06 at Version x01
  PktInt(Pkt, $00090001, 4);                    //Family x09 at Version x01
  PktInt(Pkt, $000A0001, 4);                    //Family x0A at Version x01
  PktInt(Pkt, $000B0001, 4);                    //Family x0B at Version x01
  PktFinal(Pkt);                                //Finalize packet
end;

{This packet requests from the server several bits of information most
likely regarding how fast certain packets can be sent to the server and
possibly a maximum packet size as well.}
procedure CreateCLI_RATESREQUEST(Pkt: PRawPkt; var Seq: Word);
begin
  PktInit(Pkt, 2, Seq);                         //Channel 2
  PktSnac(Pkt, $01, $06, 0, 0);                 //Snac: Type x01/x06, ID x0000, Flags 0
  PktFinal(Pkt);                                //Finalize packet
end;

{This packet is sent in response to the SRV_RATES SNAC(1,7). This
packet contains the same group numbers as was in the SRV_RATES
packet and is an acknowledgement of their receipt.}
procedure CreateCLI_ACKRATES(Pkt: PRawPkt; var Seq: Word);
begin
  PktInit(Pkt, 2, Seq);                         //Channel 2
  PktSnac(Pkt, $01, $08, 0, 0);                 //Type x01/x08, ID x0000, Flags 0
  PktInt(Pkt, $0001, 2);                        //Group1 - 0x0001
  PktInt(Pkt, $0002, 2);                        //Group2 - 0x0002
  PktInt(Pkt, $0003, 2);                        //Group3 - 0x0003
  PktInt(Pkt, $0004, 2);                        //Group4 - 0x0004
  PktInt(Pkt, $0005, 2);                        //Group5 - 0x0005
  PktFinal(Pkt);                                //Finalize packet
end;

{This command requests from the server certain information
about the client that is stored on the server}
procedure CreateCLI_REQINFO(Pkt: PRawPkt; var Seq: Word);
begin
  PktInit(Pkt, 2, Seq);                         //Channel 2
  PktSnac(Pkt, $01, $0E, 0, 0);                 //Snac: Type x01/x0E, ID x0000, Flags 0
  PktFinal(Pkt);                                //Finalize packet
end;

{Unknown}
procedure CreateCLI_REQUNKNOWN(Pkt: PRawPkt; var Seq: Word);
begin
  PktInit(Pkt, 2, Seq);                         //Channel 2
  PktSnac(Pkt, $13, $02, 0, 0);                 //Snac: Type x13/x02, ID x0000, Flags 0
  PktFinal(Pkt);                                //Finalize packet
end;

{This command, like CLI_CHECKROSTER, requests the server side contact list.
The difference between CLI_REQROSTER and CLI_CHECKROSTER is that CLI_REQROSTER
has no parameters, and always causes SRV_REPLYROSTER (rather than
SRV_REPLYROSTEROK). My guess is that CLI_REQROSTER is sent instead of
CLI_CHECKROSTER when the client does not have a cached copy of the contact
list; ie, the first time a user logs in with a particular client.}
procedure CreateCLI_REQROSTER(Pkt: PRawPkt; var Seq: Word);
begin
  PktInit(Pkt, 2, Seq);                         //Channel 2
  PktSnac(Pkt, $13, $04, $00010004, 0);         //Snac: Type x13/x04, ID x00010004, Flags 0
  PktFinal(Pkt);                                //Finalize packet
end;

{Synchronizes the server side contact list with the client's.
If the passed values match those on the server, SNAC(13,F)
SRV_REPLYROSTEROK will be returned. If the values are older
than what is on the server then SNAC(13,6) SRV_REPLYROSTER will
be returned.}
procedure CreateCLI_CHECKROSTER(Pkt: PRawPkt; var Seq: Word);
begin
  PktInit(Pkt, 2, Seq);                         //Channel 2
  PktSnac(Pkt, $13, $05, $00010005, 0);         //Snac: Type x13/x05, ID x00010005, Flags 0
  PktInt(Pkt, $3C36D709, 4);                    //time(NULL), The last modification time of the server side contact list.
  PktInt(Pkt, $0000, 2);                        //Size of server side contact list.
  PktFinal(Pkt);                                //Finalize packet
end;

{Request rights information for location service. This is from
the OSCAR document.}
procedure CreateCLI_REQLOCATION(Pkt: PRawPkt; var Seq: Word);
begin
  PktInit(Pkt, 2, Seq);                         //Channel 2
  PktSnac(Pkt, $02, $02, 0, 0);                 //Snac: Type x02/x02, ID x0000, Flags 0
  PktFinal(Pkt);                                //Finalize packet
end;

{Request rights information for buddy service. This from the OSCAR document.}
procedure CreateCLI_REQBUDDY(Pkt: PRawPkt; var Seq: Word);
begin
  PktInit(Pkt, 2, Seq);                         //Channel 2
  PktSnac(Pkt, $03, $02, 0, 0);                 //Snac: Type x03/x02, ID x0000, Flags 0
  PktFinal(Pkt);                                //Finalize packet
end;

{Request rights information for ICBM (instant messages) operations. This
from the OSCAR document.}
procedure CreateCLI_REQICBM(Pkt: PRawPkt; var Seq: Word);
begin
  PktInit(Pkt, 2, Seq);                         //Channel 2
  PktSnac(Pkt, $04, $04, 0, 0);                 //Snac: Type x04/x04, ID x0000, Flags 0
  PktFinal(Pkt);                                //Finalize packet
end;

{Request BOS rights. This from the OSCAR document.}
procedure CreateCLI_REQBOS(Pkt: PRawPkt; var Seq: Word);
begin
  PktInit(Pkt, 2, Seq);                         //Channel 2
  PktSnac(Pkt, $09, $02, 0, 0);                 //Snac: Type x09/x02, ID x0000, Flags 0
  PktFinal(Pkt);                                //Finalize packet
end;

{This packet sends the client's capabilities information to the server.}
procedure CreateCLI_SETUSERINFO(Pkt: PRawPkt; var Seq: Word);
const
  caps: array[0..$40 - 1] of Byte = (
    $09, $46, $13, $49, $4C, $7F, $11, $D1, $82, $22, $44, $45, $53, $54, $00, $00,
    $97, $B1, $27, $51, $24, $3C, $43, $34, $AD, $22, $D6, $AB, $F7, $3F, $14, $92,
    $2E, $7A, $64, $75, $FA, $DF, $4D, $C8, $88, $6F, $EA, $35, $95, $FD, $B6, $DF,
    $09, $46, $13, $44, $4C, $7F, $11, $D1, $82, $22, $44, $45, $53, $54, $00, $00
  );
begin
  PktInit(Pkt, 2, Seq);                         //Channel 2
  PktSnac(Pkt, $02, $04, 0, 0);                 //Snac: Type x02/x04, ID x0000, Flags 0
  PktTLV(Pkt, 5, Length(caps), @caps);          //Client's capabilities
  PktFinal(Pkt);                                //Finalize packet
end;

{This packet seems to change some of the values passed from the server
in SRV_REPLYICBM SNAC(4,5).}
procedure CreateCLI_SETICBM(Pkt: PRawPkt; var Seq: Word);
begin
  PktInit(Pkt, 2, Seq);                         //Channel 2
  PktSnac(Pkt, $04, $02, 0, 0);                 //Snac: Type x04/x02, ID x0000, Flags 0
  PktInt(Pkt, 0, 4);                            //0, Unknown; Numbers similar to x04/x05
  PktInt(Pkt, $0003, 2);                        //3, Unknown
  PktInt(Pkt, $1F40, 2);                        //8000, Unknown
  PktInt(Pkt, $03E7, 2);                        //999, Unknown
  PktInt(Pkt, $03E7, 2);                        //999, Unknown
  PktInt(Pkt, 0, 4);                            //0, Unknown
  PktFinal(Pkt);                                //Finalize packet
end;

{This sets the clients online status code and some other direct client
to client information as well. Used in login sequence.}
procedure CreateCLI_SETSTATUS(Pkt: PRawPkt; Status: LongWord; IP: LongInt; Port: Word; Cookie: LongWord; ProxyType: TProxyType; var Seq: Word);
var
  lpkt: TRawPkt;
begin
  PktInit(Pkt, 2, Seq);                         //Channel 2
  PktSnac(Pkt, $01, $1E, 0, 0);                 //Snac: Type x01/x1E, ID x0000, Flags 0
  PktTLV(Pkt, $06, 4, Status);                  //TLV(06) Status
  PktTLV(Pkt, $08, 2, 0);                       //TLV(08) Error code
  PktInitRaw(@lpkt);
  //{$R-}
  PktInt(@lpkt, Swap32(IP), 4);                 //The client computer's local IP address.(internal)
  //{$R+}
  PktInt(@lpkt, Port, 4);                       //This is the port to connect with when making client to client connections.
  if ProxyType = P_NONE then
    PktInt(@lpkt, $04, 1)                       //01 = Firewall (or HTTPS proxy); 02 = SOCKS4/5 proxy; 04 = 'normal' connection
  else if (ProxyType = P_SOCKS4) or (ProxyType = P_SOCKS5) then
    PktInt(@lpkt, $02, 1);
  PktInt(@lpkt, ICQ_PROTOCOL_VER, 2);                      //The highest client to client protocol version this client uses.
  PktInt(@lpkt, Cookie, 4);                     //Probably a direct client to client connection cookie.
  PktInt(@lpkt, $0000, 2);                      //0, Unknown
  PktInt(@lpkt, $0050, 2);                      //80, Unknown
  PktInt(@lpkt, $0000, 2);                      //0, Unknown
  PktInt(@lpkt, $0003, 2);                      //Count: 3

  //Theese are used in miranda-icq              // eraser
  //PktInt(@lpkt, $FFFFFFFF, 4);                //time(NULL): Miranda
  //PktInt(@lpkt, $00010201, 4);                //time(NULL): version 0.1.2.1
  //PktInt(@lpkt, $3B7248ED, 4);                //time(NULL): Thu Nov 08 22:49:54 2001

  PktInt(@lpkt, $00000000, 4);                  //time(NULL)
  PktInt(@lpkt, $00000000, 4);                  //time(NULL)
  PktInt(@lpkt, $00000000, 4);                  //time(NULL)
  PktInt(@lpkt, $0000, 2);                      //0, Unknown
  PktTLV(Pkt, $0C, lpkt.len, @lpkt.Data);       //TLV(0C)
  PktFinal(Pkt);                                //Finalize packet
end;

{Set client's online status after login.}
procedure CreateCLI_SETSTATUS_SHORT(Pkt: PRawPkt; Status: LongWord; var Seq: Word);
begin
  PktInit(Pkt, 2, Seq);                         //Channel 2
  PktSnac(Pkt, $01, $1E, 0, 0);                 //Snac: Type x01/x1E, ID x0000, Flags 0
  PktTLV(Pkt, $06, 4, Status);                  //TLV(06) Status
  PktFinal(Pkt);                                //Finalize packet
end;

{Set idle information. If idle_secs field is 0 then the user
isn't idle at all and the server informs all watching clients
to remove idletime-string in their tooltip of my uin-item.
If idle_secs field is greater then 0 then the user has already
been idle for idle_secs number of seconds. The server will
automatically keep incrementing this number, so do not repeatedly
call with new idle times.}
procedure CreateCLI_SETIDLETIME(Pkt: PRawPkt; const IsIdle: Boolean; var Seq: Word);
begin
  PktInit(Pkt, 2, Seq);             //Channel 2
  PktSnac(Pkt, $01, $11, 0, 0);     //Snac: Type x01/x11, ID x0000, Flags 0
  if IsIdle then
    PktInt(Pkt, $0000003C, 4)       //idle_secs field is 60 seconds - Show idle time = YES
  else
    PktInt(Pkt, $00000000, 4);      //idle_secs field is 0 - Show idle time = NO
  PktFinal(Pkt);                    //Finalize packet
end;

{This packet seems to pass the SNAC Families and their versions
along with some unknown other information back to the server.}
procedure CreateCLI_READY(Pkt: PRawPkt; var Seq: Word);
const
  buf: array[0..79] of Byte = (
    $00, $01, $00, $03, $01, $10, $04, $7B,
    $00, $13, $00, $02, $01, $10, $04, $7B,
    $00, $02, $00, $01, $01, $01, $04, $7B,
    $00, $03, $00, $01, $01, $10, $04, $7B,
    $00, $15, $00, $01, $01, $10, $04, $7B,
    $00, $04, $00, $01, $01, $10, $04, $7B,
    $00, $06, $00, $01, $01, $10, $04, $7B,
    $00, $09, $00, $01, $01, $10, $04, $7B,
    $00, $0A, $00, $01, $01, $10, $04, $7B,
    $00, $0B, $00, $01, $01, $10, $04, $7B
  );
begin
  PktInit(Pkt, 2, Seq);                         //Channel 2
  PktSnac(Pkt, $01, $02, 0, 0);                 //Snac: Type x01/x02, ID x0000, Flags 0
  PktAddArrBuf(Pkt, @buf, SizeOf(buf));         //Number sequence matches SNAC(x01/x17)
  PktFinal(Pkt);                                //Finalize packet
end;

{This packet seems to act as an interface between the AIM OSCAR-based server
and the old original ICQ server database.}
procedure CreateCLI_TOICQSRV(Pkt: PRawPkt; UIN: LongWord; Command: Word; Data: Pointer; DataLen: LongWord; var Seq, Seq2: Word);
var
  lpkt: TRawPkt;
  len: Word;
begin
  PktInit(Pkt, 2, Seq);                         //Channel 2
  if Seq2 = 2 then
    PktSnac(Pkt, $15, $02, $00010002, 0)        //Snac: Type x15/x02, ID x00010002, Flags 0
  else
    PktSnac(Pkt, $15, $02, $00000000, 0);       //Snac: Type x15/x02, ID x00000000, Flags 0
  PktInitRaw(@lpkt);
  Inc(lpkt.Len, 2);
  PktInt(@lpkt, Swap32(UIN), 4);
  PktInt(@lpkt, Swap16(Command), 2);
  PktInt(@lpkt, Swap16(Seq2), 2);
  PktAddArrBuf(@lpkt, Data, DataLen);
  //Store remaining size
  len := lpkt.Len;
  lpkt.Len := 0;
  PktLInt(@lpkt, len - 2, 2);
  lpkt.Len := len;
  //--
  PktTLV(Pkt, 1, lpkt.Len, @lpkt);
  PktFinal(Pkt);
 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -