ICQWorks.pas
资源名称:DarkMoon.rar [点击查看]
上传用户:hndmjx
上传日期:2014-09-16
资源大小:3369k
文件大小:154k
源码类别:
Delphi控件源码
开发平台:
Delphi
- unit ICQWorks {TICQClient, TICQDb contants & procedures};
- {(C) Alex Demchenko(alex@ritlabs.com)}
- {$R-} //Remove range checking
- {$DEFINE USE_ASM} //Remove this line to use pascal code instead of assembler (where it's possible)
- interface
- uses
- Windows, Classes;
- const
- MAX_DATA_LEN = 8192; //Maximum packet size
- //Online statuses
- S_ONLINE = $00000000; //Online
- S_INVISIBLE = $00000100; //Invisible
- S_AWAY = $00000001; //Away
- S_NA = $00000005; //N/A
- S_OCCUPIED = $00000011; //Occupied
- S_DND = $00000013; //Do Not Disturb
- S_FFC = $00000020; //Free For Chat
- //Flags used with statuses
- S_SHOWIP = $00020000; //show ip (for older clients), IP edit removed in ICQ2000a+ :)
- S_WEBAWARE = $00030000; //do not show status from the www
- S_ALLOWDCONN = $00000000; //allow direct connection with everyone
- S_ALLOWDAUTH = $10000000; //allow direct connection upon authorization
- S_ALLOWDLIST = $20000000; //allow direct connection with users in contact list
- //Message types
- M_PLAIN = $01; //Plain message
- M_CHAT = $02; //Chat request
- M_FILE = $03; //File request
- M_URL = $04; //URL
- M_AUTH_REQ = $06; //Auth request
- M_AUTH_DENIED = $07; //Deny auth
- M_AUTH_GIVEN = $08; //Authorize
- M_WEB_PAGE = $0D;
- M_EMAIL_EXPRESS = $0E;
- M_CONTACTS = $13;
- M_ADVANCED = $1A; //Seems to be an advanced-msg type (contacts, file requests, etc)
- //Genders
- GEN_FEMALE = 1; //Gender: Female
- GEN_MALE = 2; //Gender: Male
- //CLI_TOICQSRV commands
- CMD_ACKOFFMSG = $3E;
- CMD_REQOFFMSG = $3C;
- CMD_REQINFO = $7D0;
- TFLAPSZ: Word = 6; //Size of FLAP header
- TSNACSZ: Word = 10; //Size of SNAC header
- //SRV UIN Flags
- U_NORMAL = $0000; //Normal list entry
- U_VISIBLE_LIST = $0002; //User in visible list
- U_INVISIBLE_LIST = $0003; //User in invisible list
- U_IGNORE_LIST = $000e; //User in ignore list
- ACC_NORMAL = $0; //Normally accepted
- ACC_NO_OCCUPIED = $9; //Not accepted, occupied
- ACC_NO_DND = $A; //Not accepted, dnd
- ACC_AWAY = $4; //Accepted but away
- ACC_NA = $E; //Accepted but NA
- ACC_CONTACTLST = $C; //Accepted to contact list (no blink in tray)
- //Auto message requests
- GET_AWAY = $E8; //Get away message
- GET_OCCUPIED = $E9; //Get occupied message
- GET_NA = $EA; //Get N/A message
- GET_DND = $EB; //Get DND message
- GET_FFC = $EC; //Get FFC(Free For Chat) message
- //Buddy types
- BUDDY_NORMAL = $0000; //A normal contact list entry
- BUDDY_GROUP = $0001; //A larger group header
- BUDDY_IGNORE = $000e; //A contact on the ignore list
- BUDDY_INVISIBLE = $0003; //A contact on the invisible list
- BUDDY_VISIBLE = $0002; //A contact on the visible list
- //SSL errors
- ERRSSL_NOTFOUND = $0002; //User not found
- ERRSSL_EXISTS = $0003; //Added buddy already exists
- ERRSSL_AUTH = $000e; //User not authorized
- ERRSSL_OTHER = $000a; //Other SSL error
- ERRSSL_NOERROR = $0000; //No error (changed successfully)
- ICQClientVer_Major = 1; //Major version of component
- ICQClientVer_Minor = 18; //Minor version of component
- type
- //File request record
- TFTRequestRec = record
- ReqType: Byte;
- ITime, IRandomID: LongWord;
- UIN: LongWord;
- Description: String;
- FileName: String;
- FileSize: LongWord;
- Seq: Word;
- Port: Word;
- end;
- //File start record
- TFTStartRec = record
- UIN: LongWord;
- FilesCount: LongWord;
- Speed: LongWord;
- end;
- //Error types
- TErrorType = (ERR_SOCKET, ERR_INTERNAL, ERR_WARNING, ERR_PROXY, ERR_PROTOCOL, ERR_CONNTIMEOUT, ERR_LOGIN);
- //Proxy types
- TProxyType = (P_NONE, P_SOCKS4, P_SOCKS5{, P_HTTP});
- //Info types
- TInfoType = (INFO_GENERAL, INFO_MORE, INFO_ABOUT, INFO_PASSWORD);
- //Database types, used in ICQDb.pas
- TDbType = (DB_ICQ, DB_MIRANDA);
- //Flap header
- PFlapHdr = ^TFlapHdr;
- TFlapHdr = record
- Ident: Byte;
- ChID: Byte;
- Seq: Word;
- DataLen: Word;
- end;
- //Snac header
- PSnacHdr = ^TSnacHdr;
- TSnacHdr = record
- Family: Word;
- SubType: Word;
- Flags: array[0..1] of Byte;
- ReqID: LongWord;
- end;
- //Raw packet
- PRawPkt = ^TRawPkt;
- TRawPkt = record
- Data: array[0..MAX_DATA_LEN - 1] of Byte;
- Len: Word;
- end;
- //Filetransfer init call back function
- TOnFTInit = procedure(Sender: TObject; UIN: LongWord; FileCount, TotalBytes, Speed: LongWord; NickName: String) of object;
- TOnFTStart = procedure(Sender: TObject; StartRec: TFTStartRec; FileName: String; FileSize, Speed: LongWord) of object;
- TOnFTFileData = procedure(Sender: TObject; UIN: LongWord; Data: Pointer; DataLen: LongWord; LastPacket: Boolean) of object;
- function IntToStr(Value: Int64): String;
- function StrToInt(const Value: String): LongWord;
- function IntToHex(Int: Int64; IntSize: Byte): String;
- function HexToInt(Value: String): LongWord;
- procedure ICQEncryptPass(SrcBuf: Pointer; BufLen: LongWord);
- procedure ICQEncryptPassStr(var Pass: String);
- function Swap16(Value: Word): Word;
- function Swap32(Value: LongWord): LongWord;
- {Low-level functions}
- {-- Adding data --}
- procedure PktAddData(Pkt: PRawPkt; Data: Pointer; DataLen: LongWord);
- procedure PktAddArrBuf(Pkt: PRawPkt; Data: Pointer; DataLen: LongWord);
- procedure PktInit(Pkt: PRawPkt; Channel: Byte; var Seq: Word);
- procedure PktInitRaw(Pkt: PRawPkt);
- procedure PktFinal(Pkt: PRawPkt);
- procedure PktSnac(Pkt: PRawPkt; Family, SubType: Word; ID: LongWord; Flags: Word);
- procedure PktInt(Pkt: PRawPkt; Value: LongWord; IntSize: Byte);
- procedure PktLInt(Pkt: PRawPkt; Value: LongWord; IntSize: Byte);
- procedure PktStr(Pkt: PRawPkt; const S: String);
- procedure PktLStr(Pkt: PRawPkt; const S: String); overload;
- procedure PktLStr(Pkt: PRawPkt; S: LongWord); overload;
- procedure PktWStr(Pkt: PRawPkt; const S: String);
- procedure PktDWStr(Pkt: PRawPkt; const S: String);
- procedure PktLNTS(Pkt: PRawPkt; const S: String);
- procedure PktLLNTS(Pkt: PRawPkt; const S: String);
- procedure PktTLV(Pkt: PRawPkt; T, L: Word; V: LongWord); overload;
- procedure PktTLV(Pkt: PRawPkt; T: Word; const V: String); overload;
- procedure PktTLV(Pkt: PRawPkt; T, L: Word; V: Pointer); overload;
- {-- Extracting data --}
- function GetInt(Pkt: PRawPkt; IntSize: Byte): LongWord;
- function GetLInt(Pkt: PRawPkt; IntSize: Byte): LongWord;
- function GetStr(Pkt: PRawPkt; StrLen: Word): String;
- function GetTLVStr(Pkt: PRawPkt; var T: Word): String;
- function GetTLVInt(Pkt: PRawPkt; var T: Word): LongWord;
- procedure GetSnac(Pkt: PRawPkt; var Snac: TSnacHdr);
- function GetLStr(Pkt: PRawPkt): String;
- function GetWStr(Pkt: PRawPkt): String;
- function GetDWStr(Pkt: PRawPkt): String;
- function GetLNTS(Pkt: PRawPkt): String;
- {High-level functions}
- function StrToLanguageI(const Value: String): Word;
- function StrToCountryI(const Value: String): Word;
- function StrToInterestI(const Value: String): Word;
- function StrToOccupationI(const Value: String): Word;
- function StrToPastI(const Value: String): Word;
- function StrToOrganizationI(const Value: String): Word;
- procedure ParseContacts(Value: String; var List: TStringList);
- function MakeContactsStr(Contacts: TStringList): String;
- {Packet creation functions}
- procedure CreateCLI_IDENT(Pkt: PRawPkt; UIN: LongWord; Password: String; var Seq: Word);
- procedure CreateCLI_COOKIE(Pkt: PRawPkt; const Cookie: String; var Seq: Word);
- procedure CreateCLI_FAMILIES(Pkt: PRawPkt; var Seq: Word);
- procedure CreateCLI_RATESREQUEST(Pkt: PRawPkt; var Seq: Word);
- procedure CreateCLI_ACKRATES(Pkt: PRawPkt; var Seq: Word);
- procedure CreateCLI_REQINFO(Pkt: PRawPkt; var Seq: Word);
- procedure CreateCLI_REQUNKNOWN(Pkt: PRawPkt; var Seq: Word);
- procedure CreateCLI_REQROSTER(Pkt: PRawPkt; var Seq: Word);
- procedure CreateCLI_CHECKROSTER(Pkt: PRawPkt; var Seq: Word);
- procedure CreateCLI_REQLOCATION(Pkt: PRawPkt; var Seq: Word);
- procedure CreateCLI_REQBUDDY(Pkt: PRawPkt; var Seq: Word);
- procedure CreateCLI_REQICBM(Pkt: PRawPkt; var Seq: Word);
- procedure CreateCLI_SETSTATUS(Pkt: PRawPkt; Status: LongWord; IP: LongInt; Port: Word; Cookie: LongWord; ProxyType: TProxyType; var Seq: Word);
- procedure CreateCLI_SETSTATUS_SHORT(Pkt: PRawPkt; Status: LongWord; var Seq: Word);
- procedure CreateCLI_REQBOS(Pkt: PRawPkt; var Seq: Word);
- procedure CreateCLI_SETUSERINFO(Pkt: PRawPkt; var Seq: Word);
- procedure CreateCLI_SETICBM(Pkt: PRawPkt; var Seq: Word);
- procedure CreateCLI_READY(Pkt: PRawPkt; var Seq: Word);
- procedure CreateCLI_TOICQSRV(Pkt: PRawPkt; UIN: LongWord; Command: Word; Data: Pointer; DataLen: LongWord; var Seq, Seq2: Word);
- procedure CreateCLI_ADDCONTACT(Pkt: PRawPkt; UIN: String; var Seq: Word);
- procedure CreateCLI_REMOVECONTACT(Pkt: PRawPkt; UIN: LongWord; var Seq: Word);
- procedure CreateCLI_ADDVISIBLE(Pkt: PRawPkt; UINs: TStrings; var Seq: Word);
- procedure CreateCLI_REMVISIBLE(Pkt: PRawPkt; UIN: LongWord; var Seq: Word);
- procedure CreateCLI_ADDINVISIBLE(Pkt: PRawPkt; UINs: TStrings; var Seq: Word);
- procedure CreateCLI_REMINVISIBLE(Pkt: PRawPkt; UIN: LongWord; var Seq: Word);
- procedure CreateCLI_ACKOFFLINEMSGS(Pkt: PRawPkt; UIN: LongWord; var Seq, Seq2: Word);
- procedure CreateCLI_SENDMSG(Pkt: PRawPkt; ITime, IRandom, UIN: LongWord; const Msg: String; var Seq: Word);
- procedure CreateCLI_SENDURL(Pkt: PRawPkt; ITime, IRandom, MyUIN, UIN: LongWord; const URL, Description: String; var Seq: Word);
- procedure CreateCLI_AUTHORIZE(Pkt: PRawPkt; UIN: LongWord; Auth: Byte; Reason: String; var Seq: Word);
- procedure CreateCLI_METAREQINFO(Pkt: PRawPkt; UIN, dUIN: LongWord; var Seq, Seq2: Word);
- procedure CreateCLI_SEARCHBYMAIL(Pkt: PRawPkt; UIN: LongWord; const Email: String; var Seq, Seq2: Word);
- procedure CreateCLI_SEARCHBYUIN(Pkt: PRawPkt; UIN: LongWord; DUIN: LongWord; var Seq, Seq2: Word);
- procedure CreateCLI_SEARCHBYNAME(Pkt: PRawPkt; UIN: LongWord; const FirstName, LastName, NickName, Email: String; var Seq, Seq2: Word);
- procedure CreateCLI_SEARCHRANDOM(Pkt: PRawPkt; UIN: LongWord; Group: Word; var Seq, Seq2: Word);
- procedure CreateCLI_SEARCHWP(Pkt: PRawPkt; UIN: LongWord; First, Last, Nick, Email: String; MinAge, MaxAge: Word; Gender: Byte; Language: Byte; City: String; Country: Word; Company, Department, Position: String; Occupation: Byte; Organization: Word; OrganKeyWords: String; Affiliation: Word; AffiKeyWords, KeyWord: String; Online: Byte; var Seq, Seq2: Word);
- procedure CreateCLI_METASETMORE(Pkt: PRawPkt; UIN: LongWord; Age: Word; Gender: Byte; HomePage: String; BirthYear: Word; BirthMonth, BirthDay, Lang1, Lang2, Lang3: Byte; var Seq, Seq2: Word);
- procedure CreateCLI_METASETGENERAL(Pkt: PRawPkt; UIN: LongWord; const NickName, FirstName, LastName, Email, City, State, Phone, Fax, Street, Cellular, Zip: String; Country: Word; TimeZone: Byte; PublishEmail: Boolean; var Seq, Seq2: Word);
- procedure CreateCLI_METASETABOUT(Pkt: PRawPkt; UIN: LongWord; const About: String; var Seq, Seq2: Word);
- procedure CreateCLI_SENDSMS(Pkt: PRawPkt; UIN: LongWord; const Destination, Text: String; CodePage: Word; const Time: String; var Seq, Seq2: Word);
- procedure CreateCLI_SENDMSG_ADVANCED(Pkt: PRawPkt; ITime, IRandom, UIN: LongWord; const Msg: String; RTFFormat: Boolean; var Seq: Word);
- procedure CreateCLI_SENDMSG_FILEACK(Pkt: PRawPkt; FFSeq: Word; ITime, IRandom, UIN, FileSize: LongWord; const FileDesc, FileName: String; Port: Word; var Seq: Word);
- procedure CreateCLI_SENDMSG_FILEDECLINE(Pkt: PRawPkt; FFSeq: Word; ITime, IRandom, UIN, FileSize: LongWord; const FileDesc, FileName, Reason: String; Port: Word; var Seq: Word);
- procedure CreateCLI_HELLO(Pkt: PRawPkt; var Seq: Word);
- procedure CreateCLI_GOODBYE(Pkt: PRawPkt; var Seq: Word);
- procedure CreateCLI_REGISTERUSER(Pkt: PRawPkt; const Password: String; var Seq: Word);
- procedure CreateCLI_REQAWAYMSG(Pkt: PRawPkt; ITime, IRandom, UIN: LongWord; Status: Byte; var Seq: Word);
- procedure CreateCLI_SENDCONTACTS(Pkt: PRawPkt; ITime, IRandom, UIN: LongWord; Contacts: TStringList; var Seq: Word);
- procedure CreateCLI_SENDCONTACTS_REQ(Pkt: PRawPkt; ITime, IRandom, UIN: LongWord; Reason: String; var Seq: Word);
- procedure CreateCLI_UNREGUIN(Pkt: PRawPkt; UIN: LongWord; const Password: String; var Seq, Seq2: Word);
- procedure CreateCLI_METASETPASS(Pkt: PRawPkt; UIN: LongWord; const Password: String; Buffer: Pointer; BufLen: Word; var Seq, Seq2: Word);
- procedure CreateCLI_METASETPERMISSIONS(Pkt: PRawPkt; UIN: LongWord; AuthorizationRequired, WebAware: Boolean; var Seq, Seq2: Word);
- procedure CreateCLI_METAREQINFO_SHORT(Pkt: PRawPkt; UIN, DestUIN: LongWord; var Seq, Seq2: Word);
- procedure CreateCLI_REQAUTH(Pkt: PRawPkt; UIN: LongWord; Msg: String; var Seq: Word);
- procedure CreateCLI_KEEPALIVE(Pkt: PRawPkt; var Seq: Word);
- procedure CreateCLI_ADDSTART(Pkt: PRawPkt; FirstUpload: Boolean; var Seq: Word);
- procedure CreateCLI_ADDEND(Pkt: PRawPkt; var Seq: Word);
- procedure CreateCLI_UPDATEGROUP(Pkt: PRawPkt; Name: String; Tag: Word; IDs: TStringList; var Seq: Word);
- procedure CreateCLI_UPDATEBUDDY(Pkt: PRawPkt; UIN, Name, SMSNumber: String; Tag, ID: Word; BuddyType: Word; NotAuthorized: Boolean; var Seq: Word);
- procedure CreateCLI_ADDBUDDY(Pkt: PRawPkt; UIN, Name, SMSNumber: String; Tag, ID: Word; BuddyType: Word; NotAuthorized: Boolean; var Seq: Word);
- procedure CreateCLI_DELETEBUDDY(Pkt: PRawPkt; UIN, Name, SMSNumber: String; Tag, ID: Word; BuddyType: Word; NotAuthorized, IsGroup: Boolean; var Seq: Word);
- {Misc functions}
- function SnacToStr(Family, SubType: Word): String;
- function SrvMetaToStr(V1, V2: Word): String;
- function PeerCmdToStr(Cmd: Byte): String;
- function DumpPacket(Buffer: Pointer; BufLen: Word): String;
- function Rtf2Txt(const Value: String): String;
- function StatusToStr(Value: LongWord): String;
- function CountryToStr(Value: Word): String;
- function LanguageToStr(Value: Byte): String;
- function OccupationToStr(Value: Word): String;
- function InterestToStr(Value: Word): String;
- function PastToStr(Value: Word): String;
- function AffiliationToStr(Value: Word): String;
- function LoadPacketRaw(Pkt: PRawPkt; const FName: String): Boolean;
- function LoadPacket(Pkt: PRawPkt; const FName: String; var Flap: TFlapHdr; var Snac: TSnacHdr): Boolean;
- function FileExists(const FileName: String): Boolean;
- function FileSize(const FName: String): LongWord;
- procedure LogText(const FName, Text: String);
- procedure ShowMessage(const Value: String); overload;
- procedure ShowMessage(Value: LongWord); overload;
- function ExtractName(const Value: String): String;
- function ExtractValue(const Value: String): String;
- function UTF8ToStr(Value: String): String;
- function UTF8ToStrSmart(Value: String): String;
- function GetXMLEntry(const Tag, Msg: String): String;
- {SMS functions}
- function StrToUTF8(Value: String): String;
- function STime: String;
- function GetSMSTime: String;
- function DecryptPak(Pak: Pointer; Size: LongWord; Ver: Byte): Boolean;
- procedure EncryptPak(Pak: Pointer; Size: LongWord; Ver: Byte);
- {Peer packet functions}
- procedure CreatePEER_INIT(Pkt: PRawPkt; Cookie, DestUIN, SrcUIN, SrcPort, SrcIPExt, SrcIPInt: LongWord; ProxyType: TProxyType);
- procedure CreatePEER_INIT2(Pkt: PRawPkt; Ack: Boolean);
- procedure CreatePEER_ACK(Pkt: PRawPkt);
- function CreatePEER_MSG(Pkt: PRawPkt; const Msg: String; RTFFormat: Boolean; var Seq: Word): Word;
- procedure CreatePEER_MSGACK(Pkt: PRawPkt; Seq: Word);
- procedure CreatePEER_AUTOMSG_ACK(Pkt: PRawPkt; Answer: String; Status, Seq: Word);
- function CreatePEER_CONTACTS(Pkt: PRawPkt; Contacts: TStringList; var Seq: Word): Word;
- function CreatePEER_CONTACTREQ(Pkt: PRawPkt; const Reason: String; var Seq: Word): Word;
- function CreatePEER_FILEINIT(Pkt: PRawPkt; Response: Boolean; FileDescription, FileName: String; Port: Word; FileLength: LongWord; var Seq: Word; Reason: String; Accept: Boolean): Word;
- procedure CreatePEER_FILEINITACK(Pkt: PRawPkt; Speed: LongWord; Nick: String);
- procedure CreatePEER_FILE_INIT2(Pkt: PRawPkt; Count, Bytes, Speed: LongWord);
- function CreateHTTP_Header(Method: String; URL, Host: String; DataLen: LongWord): String;
- procedure CreateHTTP_DATA(Pkt: PRawPkt; PType: Word; Data: Pointer; DataLen: LongWord);
- function CreateHTTP_INIT: String;
- function CreateHTTP_RECV(Host, SID: String): String;
- procedure CreateHTTP_LOGIN(Pkt: PRawPkt; Host: String; Port: Word);
- function Decrypt99bPassword(UIN, CryptIV: LongWord; const HexPass: String): String;
- function DecryptMirandaPassword(const Value: String): String;
- //Text constants
- //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- //------------------------------------------------------------------------------------------------------------
- const
- Countries: array[0..242] of record Ident: Word; Value: String end =
- ((Ident: 1; Value: 'USA'),
- (Ident: 7; Value: 'Russia'),
- (Ident: 20; Value: 'Egypt'),
- (Ident: 27; Value: 'South Africa'),
- (Ident: 30; Value: 'Greece'),
- (Ident: 31; Value: 'Netherlands'),
- (Ident: 32; Value: 'Belgium'),
- (Ident: 33; Value: 'France'),
- (Ident: 34; Value: 'Spain'),
- (Ident: 36; Value: 'Hungary'),
- (Ident: 39; Value: 'Italy'),
- (Ident: 40; Value: 'Romania'),
- (Ident: 41; Value: 'Switzerland'),
- (Ident: 42; Value: 'Czech Republic'),
- (Ident: 43; Value: 'Austria'),
- (Ident: 44; Value: 'United Kingdom'),
- (Ident: 45; Value: 'Denmark'),
- (Ident: 46; Value: 'Sweden'),
- (Ident: 47; Value: 'Norway'),
- (Ident: 48; Value: 'Poland'),
- (Ident: 49; Value: 'Germany'),
- (Ident: 51; Value: 'Peru'),
- (Ident: 52; Value: 'Mexico'),
- (Ident: 53; Value: 'Cuba'),
- (Ident: 54; Value: 'Argentina'),
- (Ident: 55; Value: 'Brazil'),
- (Ident: 56; Value: 'Chile'),
- (Ident: 57; Value: 'Colombia'),
- (Ident: 58; Value: 'Venezuela'),
- (Ident: 60; Value: 'Malaysia'),
- (Ident: 61; Value: 'Australia'),
- (Ident: 62; Value: 'Indonesia'),
- (Ident: 63; Value: 'Philippines'),
- (Ident: 64; Value: 'New Zealand'),
- (Ident: 65; Value: 'Singapore'),
- (Ident: 66; Value: 'Thailand'),
- (Ident: 81; Value: 'Japan'),
- (Ident: 82; Value: 'Korea (Republic of)'),
- (Ident: 84; Value: 'Vietnam'),
- (Ident: 86; Value: 'China'),
- (Ident: 90; Value: 'Turkey'),
- (Ident: 91; Value: 'India'),
- (Ident: 92; Value: 'Pakistan'),
- (Ident: 93; Value: 'Afghanistan'),
- (Ident: 94; Value: 'Sri Lanka'),
- (Ident: 95; Value: 'Myanmar'),
- (Ident: 98; Value: 'Iran'),
- (Ident: 101; Value: 'Anguilla'),
- (Ident: 102; Value: 'Antigua'),
- (Ident: 103; Value: 'Bahamas'),
- (Ident: 104; Value: 'Barbados'),
- (Ident: 105; Value: 'Bermuda'),
- (Ident: 106; Value: 'British Virgin Islands'),
- (Ident: 107; Value: 'Canada'),
- (Ident: 108; Value: 'Cayman Islands'),
- (Ident: 109; Value: 'Dominica'),
- (Ident: 110; Value: 'Dominican Republic'),
- (Ident: 111; Value: 'Grenada'),
- (Ident: 112; Value: 'Jamaica'),
- (Ident: 113; Value: 'Montserrat'),
- (Ident: 114; Value: 'Nevis'),
- (Ident: 115; Value: 'St. Kitts'),
- (Ident: 116; Value: 'St. Vincent and the Grenadines'),
- (Ident: 117; Value: 'Trinidad and Tobago'),
- (Ident: 118; Value: 'Turks and Caicos Islands'),
- (Ident: 120; Value: 'Barbuda'),
- (Ident: 121; Value: 'Puerto Rico'),
- (Ident: 122; Value: 'Saint Lucia'),
- (Ident: 123; Value: 'United States Virgin Islands'),
- (Ident: 212; Value: 'Morocco'),
- (Ident: 213; Value: 'Algeria'),
- (Ident: 216; Value: 'Tunisia'),
- (Ident: 218; Value: 'Libya'),
- (Ident: 220; Value: 'Gambia'),
- (Ident: 221; Value: 'Senegal Republic'),
- (Ident: 222; Value: 'Mauritania'),
- (Ident: 223; Value: 'Mali'),
- (Ident: 224; Value: 'Guinea'),
- (Ident: 225; Value: 'Ivory Coast'),
- (Ident: 226; Value: 'Burkina Faso'),
- (Ident: 227; Value: 'Niger'),
- (Ident: 228; Value: 'Togo'),
- (Ident: 229; Value: 'Benin'),
- (Ident: 230; Value: 'Mauritius'),
- (Ident: 231; Value: 'Liberia'),
- (Ident: 232; Value: 'Sierra Leone'),
- (Ident: 233; Value: 'Ghana'),
- (Ident: 234; Value: 'Nigeria'),
- (Ident: 235; Value: 'Chad'),
- (Ident: 236; Value: 'Central African Republic'),
- (Ident: 237; Value: 'Cameroon'),
- (Ident: 238; Value: 'Cape Verde Islands'),
- (Ident: 239; Value: 'Sao Tome and Principe'),
- (Ident: 240; Value: 'Equatorial Guinea'),
- (Ident: 241; Value: 'Gabon'),
- (Ident: 242; Value: 'Congo'),
- (Ident: 243; Value: 'Dem. Rep. of the Congo'),
- (Ident: 244; Value: 'Angola'),
- (Ident: 245; Value: 'Guinea-Bissau'),
- (Ident: 246; Value: 'Diego Garcia'),
- (Ident: 247; Value: 'Ascension Island'),
- (Ident: 248; Value: 'Seychelle Islands'),
- (Ident: 249; Value: 'Sudan'),
- (Ident: 250; Value: 'Rwanda'),
- (Ident: 251; Value: 'Ethiopia'),
- (Ident: 252; Value: 'Somalia'),
- (Ident: 253; Value: 'Djibouti'),
- (Ident: 254; Value: 'Kenya'),
- (Ident: 255; Value: 'Tanzania'),
- (Ident: 256; Value: 'Uganda'),
- (Ident: 257; Value: 'Burundi'),
- (Ident: 258; Value: 'Mozambique'),
- (Ident: 260; Value: 'Zambia'),
- (Ident: 261; Value: 'Madagascar'),
- (Ident: 262; Value: 'Reunion Island'),
- (Ident: 263; Value: 'Zimbabwe'),
- (Ident: 264; Value: 'Namibia'),
- (Ident: 265; Value: 'Malawi'),
- (Ident: 266; Value: 'Lesotho'),
- (Ident: 267; Value: 'Botswana'),
- (Ident: 268; Value: 'Swaziland'),
- (Ident: 269; Value: 'Mayotte Island'),
- (Ident: 290; Value: 'St. Helena'),
- (Ident: 291; Value: 'Eritrea'),
- (Ident: 297; Value: 'Aruba'),
- (Ident: 298; Value: 'Faeroe Islands'),
- (Ident: 299; Value: 'Greenland'),
- (Ident: 350; Value: 'Gibraltar'),
- (Ident: 351; Value: 'Portugal'),
- (Ident: 352; Value: 'Luxembourg'),
- (Ident: 353; Value: 'Ireland'),
- (Ident: 354; Value: 'Iceland'),
- (Ident: 355; Value: 'Albania'),
- (Ident: 356; Value: 'Malta'),
- (Ident: 357; Value: 'Cyprus'),
- (Ident: 358; Value: 'Finland'),
- (Ident: 359; Value: 'Bulgaria'),
- (Ident: 370; Value: 'Lithuania'),
- (Ident: 371; Value: 'Latvia'),
- (Ident: 372; Value: 'Estonia'),
- (Ident: 373; Value: 'Moldova'),
- (Ident: 374; Value: 'Armenia'),
- (Ident: 375; Value: 'Belarus'),
- (Ident: 376; Value: 'Andorra'),
- (Ident: 377; Value: 'Monaco'),
- (Ident: 378; Value: 'San Marino'),
- (Ident: 379; Value: 'Vatican City'),
- (Ident: 380; Value: 'Ukraine'),
- (Ident: 381; Value: 'Yugoslavia'),
- (Ident: 385; Value: 'Croatia'),
- (Ident: 386; Value: 'Slovenia'),
- (Ident: 387; Value: 'Bosnia and Herzegovina'),
- (Ident: 389; Value: 'F.Y.R.O.M. (Former Yugoslav Republic of Macedonia)'),
- (Ident: 500; Value: 'Falkland Islands'),
- (Ident: 501; Value: 'Belize'),
- (Ident: 502; Value: 'Guatemala'),
- (Ident: 503; Value: 'El Salvador'),
- (Ident: 504; Value: 'Honduras'),
- (Ident: 505; Value: 'Nicaragua'),
- (Ident: 506; Value: 'Costa Rica'),
- (Ident: 507; Value: 'Panama'),
- (Ident: 508; Value: 'St. Pierre and Miquelon'),
- (Ident: 509; Value: 'Haiti'),
- (Ident: 590; Value: 'Guadeloupe'),
- (Ident: 591; Value: 'Bolivia'),
- (Ident: 592; Value: 'Guyana'),
- (Ident: 593; Value: 'Ecuador'),
- (Ident: 594; Value: 'French Guiana'),
- (Ident: 595; Value: 'Paraguay'),
- (Ident: 596; Value: 'Martinique'),
- (Ident: 597; Value: 'Suriname'),
- (Ident: 598; Value: 'Uruguay'),
- (Ident: 599; Value: 'Netherlands Antilles'),
- (Ident: 670; Value: 'Saipan Island'),
- (Ident: 671; Value: 'Guam'),
- (Ident: 672; Value: 'Christmas Island'),
- (Ident: 673; Value: 'Brunei'),
- (Ident: 674; Value: 'Nauru'),
- (Ident: 675; Value: 'Papua New Guinea'),
- (Ident: 676; Value: 'Tonga'),
- (Ident: 677; Value: 'Solomon Islands'),
- (Ident: 678; Value: 'Vanuatu'),
- (Ident: 679; Value: 'Fiji Islands'),
- (Ident: 680; Value: 'Palau'),
- (Ident: 681; Value: 'Wallis and Futuna Islands'),
- (Ident: 682; Value: 'Cook Islands'),
- (Ident: 683; Value: 'Niue'),
- (Ident: 684; Value: 'American Samoa'),
- (Ident: 685; Value: 'Western Samoa'),
- (Ident: 686; Value: 'Kiribati Republic'),
- (Ident: 687; Value: 'New Caledonia'),
- (Ident: 688; Value: 'Tuvalu'),
- (Ident: 689; Value: 'French Polynesia'),
- (Ident: 690; Value: 'Tokelau'),
- (Ident: 691; Value: 'Micronesia, Federated States of'),
- (Ident: 692; Value: 'Marshall Islands'),
- (Ident: 705; Value: 'Kazakhstan'),
- (Ident: 706; Value: 'Kyrgyz Republic'),
- (Ident: 708; Value: 'Tajikistan'),
- (Ident: 709; Value: 'Turkmenistan'),
- (Ident: 711; Value: 'Uzbekistan'),
- (Ident: 800; Value: 'International Freephone Service'),
- (Ident: 850; Value: 'Korea (North)'),
- (Ident: 852; Value: 'Hong Kong'),
- (Ident: 853; Value: 'Macau'),
- (Ident: 855; Value: 'Cambodia'),
- (Ident: 856; Value: 'Laos'),
- (Ident: 870; Value: 'INMARSAT'),
- (Ident: 871; Value: 'INMARSAT (Atlantic-East)'),
- (Ident: 872; Value: 'INMARSAT (Pacific)'),
- (Ident: 873; Value: 'INMARSAT (Indian)'),
- (Ident: 874; Value: 'INMARSAT (Atlantic-West)'),
- (Ident: 880; Value: 'Bangladesh'),
- (Ident: 886; Value: 'Taiwan, Republic of China'),
- (Ident: 960; Value: 'Maldives'),
- (Ident: 961; Value: 'Lebanon'),
- (Ident: 962; Value: 'Jordan'),
- (Ident: 963; Value: 'Syria'),
- (Ident: 964; Value: 'Iraq'),
- (Ident: 965; Value: 'Kuwait'),
- (Ident: 966; Value: 'Saudi Arabia'),
- (Ident: 967; Value: 'Yemen'),
- (Ident: 968; Value: 'Oman'),
- (Ident: 971; Value: 'United Arab Emirates'),
- (Ident: 972; Value: 'Israel'),
- (Ident: 973; Value: 'Bahrain'),
- (Ident: 974; Value: 'Qatar'),
- (Ident: 975; Value: 'Bhutan'),
- (Ident: 976; Value: 'Mongolia'),
- (Ident: 977; Value: 'Nepal'),
- (Ident: 994; Value: 'Azerbaijan'),
- (Ident: 995; Value: 'Georgia'),
- (Ident: 2691; Value: 'Comoros'),
- (Ident: 4101; Value: 'Liechtenstein'),
- (Ident: 4201; Value: 'Slovak Republic'),
- (Ident: 5399; Value: 'Guantanamo Bay'),
- (Ident: 5901; Value: 'French Antilles'),
- (Ident: 6101; Value: 'Cocos-Keeling Islands'),
- (Ident: 6701; Value: 'Rota Island'),
- (Ident: 6702; Value: 'Tinian Island'),
- (Ident: 6721; Value: 'Australian Antarctic Territory'),
- (Ident: 6722; Value: 'Norfolk Island'),
- (Ident: 9999; Value: 'Unknown'));
- Languages: array[0..72] of record Ident: Byte; Value: String end =
- ((Ident: 1; Value: 'Arabic'),
- (Ident: 2; Value: 'Bhojpuri'),
- (Ident: 3; Value: 'Bulgarian'),
- (Ident: 4; Value: 'Burmese'),
- (Ident: 5; Value: 'Cantonese'),
- (Ident: 6; Value: 'Catalan'),
- (Ident: 7; Value: 'Chinese'),
- (Ident: 8; Value: 'Croatian'),
- (Ident: 9; Value: 'Czech'),
- (Ident: 10; Value: 'Danish'),
- (Ident: 11; Value: 'Dutch'),
- (Ident: 12; Value: 'English'),
- (Ident: 13; Value: 'Esperanto'),
- (Ident: 14; Value: 'Estonian'),
- (Ident: 15; Value: 'Farci'),
- (Ident: 16; Value: 'Finnish'),
- (Ident: 17; Value: 'French'),
- (Ident: 18; Value: 'Gaelic'),
- (Ident: 19; Value: 'German'),
- (Ident: 20; Value: 'Greek'),
- (Ident: 21; Value: 'Hebrew'),
- (Ident: 22; Value: 'Hindi'),
- (Ident: 23; Value: 'Hungarian'),
- (Ident: 24; Value: 'Icelandic'),
- (Ident: 25; Value: 'Indonesian'),
- (Ident: 26; Value: 'Italian'),
- (Ident: 27; Value: 'Japanese'),
- (Ident: 28; Value: 'Khmer'),
- (Ident: 29; Value: 'Korean'),
- (Ident: 30; Value: 'Lao'),
- (Ident: 31; Value: 'Latvian'),
- (Ident: 32; Value: 'Lithuanian'),
- (Ident: 33; Value: 'Malay'),
- (Ident: 34; Value: 'Norwegian'),
- (Ident: 35; Value: 'Polish'),
- (Ident: 36; Value: 'Portuguese'),
- (Ident: 37; Value: 'Romanian'),
- (Ident: 38; Value: 'Russian'),
- (Ident: 39; Value: 'Serbo-Croatian'),
- (Ident: 40; Value: 'Slovak'),
- (Ident: 41; Value: 'Slovenian'),
- (Ident: 42; Value: 'Somali'),
- (Ident: 43; Value: 'Spanish'),
- (Ident: 44; Value: 'Swahili'),
- (Ident: 45; Value: 'Swedish'),
- (Ident: 46; Value: 'Tagalog'),
- (Ident: 47; Value: 'Tatar'),
- (Ident: 48; Value: 'Thai'),
- (Ident: 49; Value: 'Turkish'),
- (Ident: 50; Value: 'Ukrainian'),
- (Ident: 51; Value: 'Urdu'),
- (Ident: 52; Value: 'Vietnamese'),
- (Ident: 53; Value: 'Yiddish'),
- (Ident: 54; Value: 'Yoruba'),
- (Ident: 55; Value: 'Afrikaans'),
- (Ident: 56; Value: 'Bosnian'),
- (Ident: 57; Value: 'Persian'),
- (Ident: 58; Value: 'Albanian'),
- (Ident: 59; Value: 'Armenian'),
- (Ident: 60; Value: 'Punjabi'),
- (Ident: 61; Value: 'Chamorro'),
- (Ident: 62; Value: 'Mongolian'),
- (Ident: 63; Value: 'Mandarin'),
- (Ident: 64; Value: 'Taiwanese'),
- (Ident: 65; Value: 'Macedonian'),
- (Ident: 66; Value: 'Sindhi'),
- (Ident: 67; Value: 'Welsh'),
- (Ident: 68; Value: 'Azerbaijani'),
- (Ident: 69; Value: 'Kurdish'),
- (Ident: 70; Value: 'Gujarati'),
- (Ident: 71; Value: 'Tamil'),
- (Ident: 72; Value: 'Belorussian'),
- (Ident: 255; Value: 'Unknown'));
- Occupations: array[1..17] of record Ident: Byte; Value: String end =
- ((Ident: 1; Value: 'Academic'),
- (Ident: 2; Value: 'Administrative'),
- (Ident: 3; Value: 'Art/Entertainment'),
- (Ident: 4; Value: 'College Student'),
- (Ident: 5; Value: 'Computers'),
- (Ident: 6; Value: 'Community & Social'),
- (Ident: 7; Value: 'Education'),
- (Ident: 8; Value: 'Engineering'),
- (Ident: 9; Value: 'Financial Services'),
- (Ident: 10; Value: 'Government'),
- (Ident: 11; Value: 'High School Student'),
- (Ident: 12; Value: 'Home'),
- (Ident: 13; Value: 'ICQ - Providing Help'),
- (Ident: 14; Value: 'Law'),
- (Ident: 15; Value: 'Managerial'),
- (Ident: 16; Value: 'Manufacturing'),
- (Ident: 17; Value: 'Medical/Health'));
- Interests: array[100..150] of record Ident: Byte; Value: String end =
- ((Ident: 100; Value: 'Art'),
- (Ident: 101; Value: 'Cars'),
- (Ident: 102; Value: 'Celebrity Fans'),
- (Ident: 103; Value: 'Collections'),
- (Ident: 104; Value: 'Computers'),
- (Ident: 105; Value: 'Culture & Literature'),
- (Ident: 106; Value: 'Fitness'),
- (Ident: 107; Value: 'Games'),
- (Ident: 108; Value: 'Hobbies'),
- (Ident: 109; Value: 'ICQ - Providing Help'),
- (Ident: 110; Value: 'Internet'),
- (Ident: 111; Value: 'Lifestyle'),
- (Ident: 112; Value: 'Movies/TV'),
- (Ident: 113; Value: 'Music'),
- (Ident: 114; Value: 'Outdoor Activities'),
- (Ident: 115; Value: 'Parenting'),
- (Ident: 116; Value: 'Pets/Animals'),
- (Ident: 117; Value: 'Religion'),
- (Ident: 118; Value: 'Science/Technology'),
- (Ident: 119; Value: 'Skills'),
- (Ident: 120; Value: 'Sports'),
- (Ident: 121; Value: 'Web Design'),
- (Ident: 122; Value: 'Nature and Environment'),
- (Ident: 123; Value: 'News & Media'),
- (Ident: 124; Value: 'Government'),
- (Ident: 125; Value: 'Business & Economy'),
- (Ident: 126; Value: 'Mystics'),
- (Ident: 127; Value: 'Travel'),
- (Ident: 128; Value: 'Astronomy'),
- (Ident: 129; Value: 'Space'),
- (Ident: 130; Value: 'Clothing'),
- (Ident: 131; Value: 'Parties'),
- (Ident: 132; Value: 'Women'),
- (Ident: 133; Value: 'Social science'),
- (Ident: 134; Value: '60''s'),
- (Ident: 135; Value: '70''s'),
- (Ident: 136; Value: '80''s'),
- (Ident: 137; Value: '50''s'),
- (Ident: 138; Value: 'Finance and corporate'),
- (Ident: 139; Value: 'Entertainment'),
- (Ident: 140; Value: 'Consumer electronics'),
- (Ident: 141; Value: 'Retail stores'),
- (Ident: 142; Value: 'Health and beauty'),
- (Ident: 143; Value: 'Media'),
- (Ident: 144; Value: 'Household products'),
- (Ident: 145; Value: 'Mail order catalog'),
- (Ident: 146; Value: 'Business services'),
- (Ident: 147; Value: 'Audio and visual'),
- (Ident: 148; Value: 'Sporting and athletic'),
- (Ident: 149; Value: 'Publishing'),
- (Ident: 150; Value: 'Home automation'));
- RandGroups: array[1..11] of record Ident: Byte; Value: String end =
- ((Ident: 1; Value: 'General'),
- (Ident: 2; Value: 'Romance'),
- (Ident: 3; Value: 'Games'),
- (Ident: 4; Value: 'Students'),
- (Ident: 5; Value: '20 something'),
- (Ident: 6; Value: '30 something'),
- (Ident: 7; Value: '40 something'),
- (Ident: 8; Value: '50+'),
- (Ident: 9; Value: 'Romance'),
- (Ident: 10; Value: 'Man requesting woman'),
- (Ident: 11; Value: 'Woman requesting man'));
- Organizations: array[0..19] of record Ident: Word; Value: String end =
- ((Ident: 200; Value: 'Alumni Org.'),
- (Ident: 201; Value: 'Charity Org.'),
- (Ident: 202; Value: 'Club/Social Org.'),
- (Ident: 203; Value: 'Community Org.'),
- (Ident: 204; Value: 'Cultural Org.'),
- (Ident: 205; Value: 'Fan Clubs'),
- (Ident: 206; Value: 'Fraternity/Sorority'),
- (Ident: 207; Value: 'Hobbyists Org.'),
- (Ident: 208; Value: 'International Org.'),
- (Ident: 209; Value: 'Nature and Environment Org.'),
- (Ident: 210; Value: 'Professional Org.'),
- (Ident: 211; Value: 'Scientific/Technical Org.'),
- (Ident: 212; Value: 'Self Improvement Group'),
- (Ident: 213; Value: 'Spiritual/Religious Org.'),
- (Ident: 214; Value: 'Sports Org.'),
- (Ident: 215; Value: 'Support Org.'),
- (Ident: 216; Value: 'Trade and Business Org.'),
- (Ident: 217; Value: 'Union'),
- (Ident: 218; Value: 'Volunteer Org.'),
- (Ident: 299; Value: 'Other'));
- Pasts: array[0..7] of record Ident: Word; Value: String end =
- ((Ident: 300; Value: 'Elementary School'),
- (Ident: 301; Value: 'High School'),
- (Ident: 302; Value: 'College'),
- (Ident: 303; Value: 'University'),
- (Ident: 304; Value: 'Military'),
- (Ident: 305; Value: 'Past Work Place'),
- (Ident: 306; Value: 'Past Organization'),
- (Ident: 399; Value: 'Other'));
- //------------------------------------------------------------------------------------------------------------
- //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
- implementation
- const
- FileSignature: array[0..15] of Byte = ($f0, $2d, $12, $d9, $30, $91, $d3, $11,
- $8d, $d7, $00, $10, $4b, $06, $46, $2e);
- ContactsSignature: array[0..15] of Byte = ($2a, $0e, $7d, $46, $76, $76, $d4, $11,
- $bc, $e6, $00, $04, $ac, $96, $1e, $a6);
- function IntToStr(Value: Int64): String;
- begin
- Str(Value, Result);
- end;
- function StrToInt(const Value: String): LongWord;
- var
- nCode: Integer;
- begin
- Val(Value, Result, nCode);
- end;
- const
- HexChars: array[0..15] of Char = ('0', '1', '2', '3', '4', '5',
- '6', '7', '8', '9', 'a', 'b',
- 'c', 'd', 'e', 'f');
- function IntToHex(Int: Int64; IntSize: Byte): String;
- var
- n: Byte;
- begin
- Result := '';
- for n := 0 to IntSize - 1 do
- begin
- Result := HexChars[Int and $F] + Result;
- Int := Int shr $4;
- end;
- end;
- function HexToInt(Value: String): LongWord;
- const
- HexStr: String = '0123456789abcdef';
- var
- i: Word;
- begin
- Result := 0;
- if Value = '' then Exit;
- for i := 1 to Length(Value) do
- Inc(Result, (Pos(Value[i], HexStr) - 1) shl ((Length(Value) - i) shl 2));
- end;
- const
- TXorData: array[0..15] of Byte = (
- $F3, $26, $81, $C4, $39, $86, $DB, $92,
- $71, $A3, $B9, $E6, $53, $7A, $95, $7C
- );
- procedure ICQEncryptPass(SrcBuf: Pointer; BufLen: LongWord); assembler;
- asm
- or edx,edx
- jz @@end
- @@loop:
- mov cl,byte ptr[eax + edx - 1]
- xor cl,byte ptr[TXorData + edx - 1]
- mov byte ptr[eax + edx - 1],cl
- dec edx
- jnz @@loop
- @@end:
- end;
- procedure ICQEncryptPassStr(var Pass: String);
- var
- i: Word;
- begin
- for i := 1 to Length(Pass) do
- Pass[i] := Chr(Ord(Pass[i]) xor TXorData[i - 1]);
- end;
- function Swap16(Value: Word): Word; assembler;
- asm
- rol ax,8
- end;
- function Swap32(Value: LongWord): LongWord; assembler;
- asm
- bswap eax
- end;
- {----------------------------------------------}
- //Adding data in reverse order
- procedure PktAddData(Pkt: PRawPkt; Data: Pointer; DataLen: LongWord);
- var
- i: Word;
- begin
- if DataLen = 0 then Exit;
- for i := 0 to DataLen - 1 do
- PByte(LongWord(Pkt) + Pkt^.Len + i)^ := PByte(LongWord(Data) + DataLen - i - 1)^;
- Inc(Pkt^.Len, DataLen);
- end;
- //Adding data in direct order(local arrays, merging 2 or more packets)
- procedure PktAddArrBuf(Pkt: PRawPkt; Data: Pointer; DataLen: LongWord);
- begin
- if DataLen = 0 then Exit;
- Move(Data^, Ptr(LongWord(Pkt) + Pkt^.Len)^, DataLen);
- Inc(Pkt^.Len, DataLen);
- end;
- procedure PktInt(Pkt: PRawPkt; Value: LongWord; IntSize: Byte);
- begin
- PktAddData(Pkt, @Value, IntSize);
- end;
- procedure PktLInt(Pkt: PRawPkt; Value: LongWord; IntSize: Byte);
- begin
- PktAddArrBuf(Pkt, @Value, IntSize);
- end;
- procedure PktStr(Pkt: PRawPkt; const S: String);
- begin
- if Length(S) = 0 then Exit;
- Move(PChar(S)^, Ptr(LongWord(Pkt) + Pkt.Len)^, Length(S));
- Inc(Pkt^.Len, Length(S));
- end;
- procedure PktLStr(Pkt: PRawPkt; const S: String); overload;
- begin
- PktInt(Pkt, Length(S), 1);
- PktStr(Pkt, S);
- end;
- procedure PktLStr(Pkt: PRawPkt; S: LongWord); overload;
- begin
- PktLStr(Pkt, IntToStr(S));
- end;
- procedure PktWStr(Pkt: PRawPkt; const S: String);
- begin
- if Length(S) = 0 then
- begin
- PktInt(Pkt, 0, 2);
- Exit;
- end;
- PktInt(Pkt, Length(S), 2);
- PktStr(Pkt, S);
- end;
- procedure PktDWStr(Pkt: PRawPkt; const S: String);
- begin
- PktLInt(Pkt, Length(S), 4);
- PktStr(Pkt, S);
- end;
- procedure PktLNTS(Pkt: PRawPkt; const S: String);
- begin
- if Length(S) = 0 then
- begin
- PktInt(Pkt, 0, 2);
- Exit;
- end;
- PktLInt(Pkt, Length(S) + 1, 2);
- PktStr(Pkt, S);
- PktInt(Pkt, 0, 1);
- end;
- procedure PktLLNTS(Pkt: PRawPkt; const S: String);
- begin
- if Length(S) = 0 then
- begin
- PktInt(Pkt, 0, 2);
- Exit;
- end;
- PktLInt(Pkt, Length(S) + 3, 2);
- PktLNTS(Pkt, S);
- end;
- {--}
- function GetInt(Pkt: PRawPkt; IntSize: Byte): LongWord;
- var
- i: Word;
- begin
- Result := 0;
- if IntSize = 0 then Exit;
- if Pkt^.Len > 8100 then Exit;
- for i := Pkt^.Len to Pkt^.Len + IntSize - 1 do
- Inc(Result, PByte(LongWord(Pkt) + i)^ shl ((Pkt^.Len + IntSize - 1 - i) * 8));
- Inc(Pkt^.Len, IntSize);
- end;
- function GetLInt(Pkt: PRawPkt; IntSize: Byte): LongWord;
- var
- i, c: Word;
- begin
- Result := 0; c := 0;
- if IntSize = 0 then Exit;
- if Pkt^.Len > 8100 then Exit;
- for i := Pkt^.Len to Pkt^.Len + IntSize - 1 do
- begin
- Inc(Result, PByte(LongWord(Pkt) + Pkt^.Len + IntSize - c - 1)^ shl ((Pkt^.Len + IntSize - 1 - i) * 8));
- Inc(c);
- end;
- Inc(Pkt^.Len, IntSize);
- end;
- function GetStr(Pkt: PRawPkt; StrLen: Word): String;
- begin
- Result := '';
- while StrLen > 0 do
- begin
- Result := Result + PChar(LongWord(Pkt) + Pkt^.Len)^;
- Inc(Pkt^.Len);
- Dec(StrLen);
- if Pkt^.Len > 8100 then Exit;
- end;
- end;
- function GetTLVStr(Pkt: PRawPkt; var T: Word): String;
- var
- ISize: Word;
- begin
- T := GetInt(Pkt, 2); //Get type
- ISize := GetInt(Pkt, 2); //Get data length
- Result := GetStr(Pkt, ISize); //Get data
- end;
- function GetTLVInt(Pkt: PRawPkt; var T: Word): LongWord;
- var
- ISize: Word;
- begin
- T := GetInt(Pkt, 2); //Get type
- ISize := GetInt(Pkt, 2); //Get data length
- Result := GetInt(Pkt, ISize); //Get data
- end;
- procedure GetSnac(Pkt: PRawPkt; var Snac: TSnacHdr);
- begin
- Snac := PSnacHdr(LongWord(Pkt) + Pkt^.Len)^;
- Snac.Family := Swap16(Snac.Family);
- Snac.SubType := Swap16(Snac.SubType);
- Snac.ReqID := Swap32(Snac.ReqID);
- Inc(Pkt^.Len, TSNACSZ);
- end;
- function GetLStr(Pkt: PRawPkt): String;
- begin
- Result := GetStr(Pkt, GetInt(Pkt, 1));
- end;
- function GetWStr(Pkt: PRawPkt): String;
- begin
- Result := GetStr(Pkt, GetInt(Pkt, 2));
- end;
- function GetDWStr(Pkt: PRawPkt): String;
- begin
- Result := GetStr(Pkt, GetLInt(Pkt, 4));
- end;
- function GetLNTS(Pkt: PRawPkt): String;
- begin
- Result := GetStr(Pkt, GetLInt(Pkt, 2) - 1);
- Inc(Pkt^.Len, 1);
- end;
- {--------}
- procedure PktTLV(Pkt: PRawPkt; T, L: Word; V: LongWord); overload;
- begin
- PktInt(Pkt, T, 2); //Add type
- PktInt(Pkt, L, 2); //Add length
- PktInt(Pkt, V, L); //Add value
- end;
- procedure PktTLV(Pkt: PRawPkt; T: Word; const V: String); overload;
- begin
- PktInt(Pkt, T, 2); //Add type
- PktInt(Pkt, Length(V), 2); //Add length
- PktStr(Pkt, V); //Add value
- end;
- procedure PktTLV(Pkt: PRawPkt; T, L: Word; V: Pointer); overload; //for arrays
- begin
- PktInt(Pkt, T, 2); //Add type
- PktInt(Pkt, L, 2); //Add length
- PktAddArrBuf(Pkt, V, L); //Add value
- end;
- procedure PktInit(Pkt: PRawPkt; Channel: Byte; var Seq: Word);
- begin
- Pkt^.Len := 0; //Starting size of packet to 0
- PktInt(Pkt, $2A, 1); //Ident, always $2A
- PktInt(Pkt, Channel, 1); //Channel
- PktInt(Pkt, SEQ, 2); Inc(SEQ);//Seq
- PktInt(Pkt, 0, 2); //Reserved for size
- end;
- {$IFDEF USE_ASM}
- procedure PktInitRaw(Pkt: PRawPkt); assembler;
- asm
- mov word ptr[eax + MAX_DATA_LEN], 0 //Default size of the packet
- end;
- {$ELSE}
- procedure PktInitRaw(Pkt: PRawPkt);
- begin
- Pkt^.Len := 0; //Default size of the packet
- end;
- {$ENDIF}
- //Used with PktInit only
- {$IFDEF USE_ASM}
- procedure PktFinal(Pkt: PRawPkt); assembler;
- asm
- mov cx,word ptr[eax + MAX_DATA_LEN]
- sub cx,TFLAPSZ
- rol cx,8
- mov word ptr[eax + 4], cx //Store the packet size (without flap header size)
- end;
- {$ELSE}
- procedure PktFinal(Pkt: PRawPkt);
- begin
- PWord(LongWord(Pkt) + 4)^ := Swap16(Pkt.Len - TFLAPSZ); //Store the packet size (without flap header size)
- end;
- {$ENDIF}
- procedure PktSnac(Pkt: PRawPkt; Family, SubType: Word; ID: LongWord; Flags: Word);
- begin
- PktInt(Pkt, Family, 2); //Snac family
- PktInt(Pkt, SubType, 2); //Snac subtype
- PktInt(Pkt, Flags, 2); //Snac flags
- PktInt(Pkt, ID, 4); //Snac reference
- end;
- {@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@}
- function StrToLanguageI(const Value: String): Word;
- var
- i: Word;
- begin
- for i := Low(Languages) to High(Languages) do
- if Languages[i].Value = Value then
- begin
- Result := Languages[i].Ident;
- Exit;
- end;
- Result := 0;
- end;
- function StrToCountryI(const Value: String): Word;
- var
- i: Word;
- begin
- for i := Low(Countries) to High(Countries) do
- if Countries[i].Value = Value then
- begin
- Result := Countries[i].Ident;
- Exit;
- end;
- Result := 0;
- end;
- function StrToInterestI(const Value: String): Word;
- var
- i: Word;
- begin
- for i := Low(Interests) to High(Interests) do
- if Interests[i].Value = Value then
- begin
- Result := Interests[i].Ident;
- Exit;
- end;
- Result := 0;
- end;
- function StrToOccupationI(const Value: String): Word;
- var
- i: Word;
- begin
- for i := Low(Occupations) to High(Occupations) do
- if Occupations[i].Value = Value then
- begin
- Result := Occupations[i].Ident;
- Exit;
- end;
- Result := 0;
- end;
- function StrToPastI(const Value: String): Word;
- var
- i: Word;
- begin
- for i := Low(Pasts) to High(Pasts) do
- if Pasts[i].Value = Value then
- begin
- Result := Pasts[i].Ident;
- Exit;
- end;
- Result := 0;
- end;
- function StrToOrganizationI(const Value: String): Word;
- var
- i: Word;
- begin
- for i := Low(Organizations) to High(Organizations) do
- if Organizations[i].Value = Value then
- begin
- Result := Organizations[i].Ident;
- Exit;
- end;
- Result := 0;
- end;
- {Parse contacts responses.}
- procedure ParseContacts(Value: String; var List: TStringList);
- var
- i, l: Word;
- FName, FUIN: String;
- begin
- l := 0; FName := ''; FUIN := '';
- if Length(Value) > Pos(#$fe, Value) + 1 then
- for i := Pos(#$fe, Value) + 1 to Length(Value) do
- begin
- if Value[i] = #$fe then
- Inc(l)
- else
- begin
- if l mod 2 = 0 then
- FName := FName + Value[i]
- else
- FUIN := FUIN + Value[i];
- end;
- if l = 2 then
- begin
- if (FName <> '') and (FUIN <> '') then
- List.Add(FName + '=' + FUIN);
- FName := '';
- FUIN := '';
- l := 0;
- end;
- end;
- end;
- {Create string representation of list with contacts.}
- function MakeContactsStr(Contacts: TStringList): String;
- var
- i, count: Word;
- 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
- PktTLV(Pkt, 3, 'ICQ Inc. - Product of ICQ (TM).2001b.5.15.1.3634.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, $000f, 2);
- PktInt(Pkt, $00190002, 4); PktInt(Pkt, $0001, 2);
- PktInt(Pkt, $001a0002, 4); PktInt(Pkt, $0e32, 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, $0008, 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
- //PktInt(@lpkt, $FFFFFFFF, 4); //time(NULL): Wed Sep 19 13:53:51 2001
- //PktInt(@lpkt, $00010201, 4); //time(NULL): Thu Nov 08 22:54:27 2001
- //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;
- {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);
- Inc(Seq2);
- end;
- {This is sent at login and when you add a new user to your
- contact list. It contains a list of all the uin's in you're
- contact list. ****May be repeated multiple times****}
- procedure CreateCLI_ADDCONTACT(Pkt: PRawPkt; UIN: String; var Seq: Word);
- begin
- PktInit(Pkt, 2, Seq); //Channel 2
- PktSnac(Pkt, $03, $04, 0, 0); //Snac: Type x03/x04, ID x0000, Flags 0
- PktLStr(Pkt, UIN); //UIN
- PktFinal(Pkt); //Finalize packet
- end;
- {Sent to remove contacts from contact list.}
- procedure CreateCLI_REMOVECONTACT(Pkt: PRawPkt; UIN: LongWord; var Seq: Word);
- begin
- PktInit(Pkt, 2, Seq); //Channel 2
- PktSnac(Pkt, $03, $05, 0, 0); //Snac: Type x03/x05, ID x0000, Flags 0
- PktLStr(Pkt, IntToStr(UIN)); //List of UINs to remove from contact list.
- PktFinal(Pkt); //Finalize packet
- end;
- {Add UINs to your visible list.}
- procedure CreateCLI_ADDVISIBLE(Pkt: PRawPkt; UINs: TStrings; var Seq: Word);
- var
- i: Word;
- begin
- PktInit(Pkt, 2, Seq); //Channel 2
- PktSnac(Pkt, $09, $05, 0, 0); //Snac: Type x09/x05, ID x0000, Flags 0
- if UINs.Count > 0 then
- for i := 0 to UINs.Count - 1 do
- PktLStr(Pkt, UINs.Strings[i]);
- PktFinal(Pkt); //Finalize packet
- end;
- {Remove UINs from your visible list.}
- procedure CreateCLI_REMVISIBLE(Pkt: PRawPkt; UIN: LongWord; var Seq: Word);
- begin
- PktInit(Pkt, 2, Seq); //Channel 2
- PktSnac(Pkt, $09, $06, 0, 0); //Snac: Type x09/x05, ID x0000, Flags 0
- PktLStr(Pkt, IntToStr(UIN)); //The UINs to remove from your invisible list.
- PktFinal(Pkt); //Finalize packet
- end;
- {List of UINs to add to invisible list. ****May be repeated multiple times****}
- procedure CreateCLI_ADDINVISIBLE(Pkt: PRawPkt; UINs: TStrings; var Seq: Word);
- var
- i: Word;
- begin
- PktInit(Pkt, 2, Seq); //Channel 2
- PktSnac(Pkt, $09, $07, 0, 0); //Snac: Type x09/x05, ID x0000, Flags 0
- if UINs.Count > 0 then
- for i := 0 to UINs.Count - 1 do
- PktLStr(Pkt, UINs.Strings[i]);
- PktFinal(Pkt); //Finalize packet
- end;
- {Remove UINs from your invisible list...}
- procedure CreateCLI_REMINVISIBLE(Pkt: PRawPkt; UIN: LongWord; var Seq: Word);
- begin
- PktInit(Pkt, 2, Seq); //Channel 2
- PktSnac(Pkt, $09, $08, 0, 0); //Snac: Type x09/x05, ID x0000, Flags 0
- PktLStr(Pkt, IntToStr(UIN)); //The UINs to remove from your invisible list.
- PktFinal(Pkt); //Finalize packet
- end;
- {Acknowledge the receipt of all offline messages.}
- procedure CreateCLI_ACKOFFLINEMSGS(Pkt: PRawPkt; UIN: LongWord; var Seq, Seq2: Word);
- begin
- CreateCLI_TOICQSRV(Pkt, UIN, CMD_ACKOFFMSG, nil, 0, Seq, Seq2);
- end;
- {Send a message.}
- procedure CreateCLI_SENDMSG(Pkt: PRawPkt; ITime, IRandom, UIN: LongWord; const Msg: String; var Seq: Word);
- var
- lpkt: TRawPkt;
- pmsg: TRawPkt;
- begin
- PktInit(Pkt, 2, Seq); //Channel 2
- PktSnac(Pkt, $04, $06, 0, 0); //Snac: Type x04/x06, ID x0000, Flags 0
- PktInt(Pkt, ITime, 4); //MID
- PktInt(Pkt, IRandom, 4); //MID
- PktInt(Pkt, 1, 2); //type, 1 - text messages
- PktLStr(Pkt, UIN); //The UIN to send the message to.
- PktInitRaw(@lpkt); //Allocate packet for incapsulated TLV(02)
- PktTLV(@lpkt, 1281, 1, 1); //Unknown: 0x1 = 1.
- PktInitRaw(@pmsg); //Allocate packet for incapsulated TLV(257)
- PktInt(@pmsg, 0, 4); //Unknown: empty. vICQ uses 00 00 ff ff.
- PktStr(@pmsg, Msg); //Finally, the message to send.
- PktTLV(@lpkt, 257, pmsg.Len, @pmsg); //Add TLV(257)
- PktTLV(Pkt, 2, lpkt.Len, @lpkt); //Add TLV(2)
- PktTLV(Pkt, 6, 0, 0); //Always present empty TLV.
- PktFinal(Pkt); //Finalize packet
- end;
- {Send an URL.}
- procedure CreateCLI_SENDURL(Pkt: PRawPkt; ITime, IRandom, MyUIN, UIN: LongWord; const URL, Description: String; var Seq: Word);
- var
- lpkt: TRawPkt;
- S: String;
- begin
- PktInit(Pkt, 2, Seq); //Channel 2
- PktSnac(Pkt, $04, $06, 0, 0); //Snac: Type x04/x06, ID x0000, Flags 0
- PktInt(Pkt, ITime, 4); //MID
- PktInt(Pkt, IRandom, 4); //MID
- PktInt(Pkt, 4, 2); //type, 1 - url etc messages
- PktLStr(Pkt, UIN); //The UIN to sent the message to.
- PktInitRaw(@lpkt); //Allocate packet for incapsulated TLV(5)
- PktLInt(@lpkt, MyUIN, 4); //My UIN.
- PktInt(@lpkt, 4, 1); //The message type as in the old protocol.
- PktInt(@lpkt, 0, 1); //Unknown flags; possibly the message flags.
- S := Description + #$fe + URL; //Concatinate: Decription + 0xFE + URL
- PktLNTS(@lpkt, S); //Finally the URL to send.
- PktTLV(Pkt, 5, lpkt.Len, @lpkt); //Add TLV(5)
- PktTLV(Pkt, 6, 0, 0); //Always present empty TLV.
- PktFinal(Pkt); //Finalize packet
- end;
- {Grant another user's request for authorization (in response to SRV_AUTH_REQ).}
- procedure CreateCLI_AUTHORIZE(Pkt: PRawPkt; UIN: LongWord; Auth: Byte; Reason: String; var Seq: Word);
- begin
- if Auth = 1 then Reason := '';
- PktInit(Pkt, 2, Seq); //Channel 2
- PktSnac(Pkt, $13, $1A, 0, 0); //Snac: Type x13/x1A, ID x0000, Flags 0
- PktLStr(Pkt, UIN); //UIN of the user to authorize.
- PktInt(Pkt, Auth, 1); //Decline or authorize the contact add request: 00 - decline, 01 - authorize
- PktInt(Pkt, Length(Reason), 2); //Length of the following reason; always 0 for authorize.
- PktStr(Pkt, Reason); //Reason for declining authorization as ASCII string.
- PktInt(Pkt, 0, 2); //Unknown: empty.
- PktFinal(Pkt); //Finalize packet
- end;
- {Request information about another user.}
- procedure CreateCLI_METAREQINFO(Pkt: PRawPkt; UIN, dUIN: LongWord; var Seq, Seq2: Word);
- var
- lpkt: TRawPkt;
- begin
- PktInitRaw(@lpkt);
- PktLInt(@lpkt, $04b2, 2); //CLI_METAREQINFO 0x04d0, ICQ 2002a sends 0xb204
- PktLInt(@lpkt, dUIN, 4);
- CreateCLI_TOICQSRV(Pkt, UIN, $07D0, @lpkt, lpkt.Len, Seq, Seq2);
- end;
- {Searches user by email.}
- procedure CreateCLI_SEARCHBYMAIL(Pkt: PRawPkt; UIN: LongWord; const Email: String; var Seq, Seq2: Word);
- var
- lpkt: TRawPkt;
- begin
- PktInitRaw(@lpkt);
- PktInt(@lpkt, $7305, 2); //CLI_SEARCHBYMAIL
- PktInt(@lpkt, $5e01, 2); //The key to search for: 0x15e = 350 = email address
- PktLLNTS(@lpkt, Email); //The email address to search for.
- CreateCLI_TOICQSRV(Pkt, UIN, $07D0, @lpkt, lpkt.Len, Seq, Seq2); //Incapsulate in CLI_TOICQSRV
- end;
- {Searches user by UIN.}
- procedure CreateCLI_SEARCHBYUIN(Pkt: PRawPkt; UIN: LongWord; DUIN: LongWord; var Seq, Seq2: Word);
- var
- lpkt: TRawPkt;
- begin
- PktInitRaw(@lpkt);
- PktInt(@lpkt, $6905, 2); //CLI_SEARCHBYUIN
- PktInt(@lpkt, $3601, 2); //The key to search for: 0x15e = 350 = email address
- PktInt(@lpkt, $0400, 2); //Length of the following data
- PktInt(@lpkt, Swap32(DUIN), 4); //UIN
- CreateCLI_TOICQSRV(Pkt, UIN, $07D0, @lpkt, lpkt.Len, Seq, Seq2); //Incapsulate in CLI_TOICQSRV
- end;
- {Search for a user by most common options.}
- procedure CreateCLI_SEARCHBYNAME(Pkt: PRawPkt; UIN: LongWord; const FirstName, LastName, NickName, Email: String; var Seq, Seq2: Word);
- var
- lpkt: TRawPkt;
- begin
- PktInitRaw(@lpkt);
- PktInt(@lpkt, $5F05, 2); //CLI_SEARCHBYNAME
- if Length(FirstName) <> 0 then
- begin
- PktInt(@lpkt, $4001, 2); //The key to search for: 0x140 = 320 = first name.
- PktLLNTS(@lpkt, FirstName); //The first name to search for.
- end;
- if Length(LastName) <> 0 then
- begin
- PktInt(@lpkt, $4a01, 2); //The key to search for: 0x14a = 330 = last name.
- PktLLNTS(@lpkt, LastName); //The last name to search for.
- end;
- if Length(NickName) <> 0 then
- begin
- PktInt(@lpkt, $5401, 2); //The key to search for: 0x154 = 340 = nick.
- PktLLNTS(@lpkt, NickName); //The nick name to search for.
- end;
- if Length(Email) <> 0 then
- begin
- PktInt(@lpkt, $5e01, 2); //The key to search for: 0x15e = 350 = email address.
- PktLLNTS(@lpkt, Email); //The email address to search for.
- end;
- CreateCLI_TOICQSRV(Pkt, UIN, $07D0, @lpkt, lpkt.Len, Seq, Seq2); //Incapsulate in CLI_TOICQSRV
- end;
- {Ask for a random UIN from a user in given chat group.}
- procedure CreateCLI_SEARCHRANDOM(Pkt: PRawPkt; UIN: LongWord; Group: Word; var Seq, Seq2: Word);
- var
- lpkt: TRawPkt;
- begin
- PktInitRaw(@lpkt);
- PktInt(@lpkt, $4E07, 2); //CLI_SEARCHRANDOM Channel: 2, SNAC(21,2) 2000/1870
- PktInt(@lpkt, Swap16(Group), 2); //The random chat group to request a UIN from.
- CreateCLI_TOICQSRV(Pkt, UIN, $07D0, @lpkt, lpkt.Len, Seq, Seq2); //Incapsulate in CLI_TOICQSRV
- end;
- {Do an extensive search for a user.}
- procedure CreateCLI_SEARCHWP(Pkt: PRawPkt; UIN: LongWord; First, Last, Nick, Email: String; MinAge, MaxAge: Word;
- Gender: Byte; Language: Byte; City: String; Country: Word; Company, Department, Position: String;
- Occupation: Byte; Organization: Word; OrganKeyWords: String; Affiliation: Word; AffiKeyWords,
- KeyWord: String; Online: Byte; var Seq, Seq2: Word);
- var
- lpkt: TRawPkt;
- begin
- if (Gender <> GEN_MALE) and (Gender <> GEN_FEMALE) then
- Gender := 0; //Don't care about gender
- PktInitRaw(@lpkt); //Initialize temporary packet
- PktInt(@lpkt, $5F05, 2); //CLI_SEARCHBYPERSINF, Channel: 2, SNAC(21,2) 2000/1375
- if First <> '' then begin PktInt(@lpkt, $4001, 2); PktLLNTS(@lpkt, First); end; //Fist Name
- if Last <> '' then begin PktInt(@lpkt, $4a01, 2); PktLLNTS(@lpkt, Last); end; //Last Name
- if Nick <> '' then begin PktInt(@lpkt, $5401, 2); PktLLNTS(@lpkt, Nick); end; //Nick Name
- if Email <> '' then begin PktInt(@lpkt, $5e01, 2); PktLLNTS(@lpkt, Email); end; //Email
- if Gender <> 0 then begin PktInt(@lpkt, $7c01, 2); PktInt(@lpkt, $0100, 2); PktInt(@lpkt, Gender, 1); end; //Gender
- if (MinAge <> 0) and (MaxAge <> 0) then begin PktInt(@lpkt, $6801, 2); PktInt(@lpkt, $0400, 2); PktLInt(@lpkt, MinAge, 2); PktLInt(@lpkt, MaxAge, 2); end; //Age
- if City <> '' then begin PktInt(@lpkt, $9001, 2); PktLLNTS(@lpkt, City); end; //City/State
- if Country <> 0 then begin PktInt(@lpkt, $a401, 2); PktInt(@lpkt, $0200, 2); PktLInt(@lpkt, Country, 2); end; //Country
- if Language <> 0 then begin PktInt(@lpkt, $8601, 2); PktInt(@lpkt, $0200, 2); PktLInt(@lpkt, Language, 2); end; //Language
- if Company <> '' then begin PktInt(@lpkt, $ae01, 2); PktLLNTS(@lpkt, Company); end; //Company
- if Department <> '' then begin PktInt(@lpkt, $b801, 2); PktLLNTS(@lpkt, Department); end; //Department
- if Occupation <> 0 then begin PktInt(@lpkt, $cc01, 2); PktInt(@lpkt, $0200, 2); PktLInt(@lpkt, Occupation, 2); end; //Occupation
- if Position <> '' then begin PktInt(@lpkt, $c201, 2); PktLLNTS(@lpkt, Position); end;
- if Affiliation <> 0 then begin PktInt(@lpkt, $d601, 2); PktInt(@lpkt, 3 + Length(AffiKeyWords), 2); PktLInt(@lpkt, Affiliation, 2); PktLNTS(@lpkt, AffiKeyWords); end; //Affiliation
- if Organization <> 0 then begin PktInt(@lpkt, $fe01, 2); PktInt(@lpkt, 3 + Length(OrganKeyWords), 2); PktLInt(@lpkt, Organization, 2); PktLNTS(@lpkt, OrganKeyWords); end; //Organization
- if KeyWord <> '' then begin PktInt(@lpkt, $2602, 2); PktLLNTS(@lpkt, KeyWord); end; //Search by KeyWord
- if Online = 1 then begin PktInt(@lpkt, $3002, 2); PktInt(@lpkt, $0100, 2); PktInt(@lpkt, $01, 1); end; //Search only online users
- CreateCLI_TOICQSRV(Pkt, UIN, $07D0, @lpkt, lpkt.Len, Seq, Seq2); //Incapsulate in CLI_TOICQSRV
- end;
- {Set more information about yourself.}
- procedure CreateCLI_METASETMORE(Pkt: PRawPkt; UIN: LongWord; Age: Word; Gender: Byte; HomePage: String; BirthYear: Word; BirthMonth, BirthDay, Lang1, Lang2, Lang3: Byte; var Seq, Seq2: Word);
- var
- lpkt: TRawPkt;
- begin
- if (Gender <> GEN_MALE) and (Gender <> GEN_FEMALE) then
- Gender := 0; //Gender not specified.
- PktInitRaw(@lpkt); //Initialize packet
- PktInt(@lpkt, $FD03, 2); //CLI_METASETMORE Channel: 2, SNAC(21,2) 2000/1021
- PktLInt(@lpkt, Age, 2); //Your age.
- PktInt(@lpkt, Gender, 1); //Your gender.
- PktLNTS(@lpkt, HomePage); //Your personal home page.
- PktLInt(@lpkt, BirthYear, 2); //Your year of birth.
- PktInt(@lpkt, BirthMonth, 1); //Your month of birth.
- PktInt(@lpkt, BirthDay, 1); //Your day of birth.
- PktInt(@lpkt, Lang1, 1); //Your first language. Numbers according to a table.
- PktInt(@lpkt, Lang2, 1); //Your second language. Numbers according to a table.
- PktInt(@lpkt, Lang3, 1); //Your third language. Numbers according to a table.
- CreateCLI_TOICQSRV(Pkt, UIN, $07D0, @lpkt, lpkt.Len, Seq, Seq2); //Incapsulate in CLI_TOICQSRV
- end;
- {Set general information about yourself.}
- procedure CreateCLI_METASETGENERAL(Pkt: PRawPkt; UIN: LongWord; const NickName, FirstName, LastName, Email, City, State, Phone, Fax, Street, Cellular, Zip: String; Country: Word; TimeZone: Byte; PublishEmail: Boolean; var Seq, Seq2: Word);
- var
- lpkt: TRawPkt;
- begin
- PktInitRaw(@lpkt);
- PktInt(@lpkt, $EA03, 2); //CLI_METASETGENERAL Channel: 2, SNAC(21,2) 2000/1002
- PktLNTS(@lpkt, NickName); //The nick of the user.
- PktLNTS(@lpkt, FirstName); //The first name of the user.
- PktLNTS(@lpkt, LastName); //The last name of the user.
- PktLNTS(@lpkt, Email); //The email address of the user.
- PktLNTS(@lpkt, City); //The city the user lives in.
- PktLNTS(@lpkt, State); //The state the user lives in.
- PktLNTS(@lpkt, Phone); //The phone number of the user.
- PktLNTS(@lpkt, Fax); //The fax number of the user.
- PktLNTS(@lpkt, Street); //The street the user lives in.
- PktLNTS(@lpkt, Cellular); //The cell phone number of the user.
- PktLNTS(@lpkt, Zip); //The zip code of the user.
- PktLInt(@lpkt, Country, 2); //The country the user lives in according to a table.
- PktInt(@lpkt, TimeZone, 1); //The timezone the user lives in, as multiples of 30minutes relative to UTC.
- PktInt(@lpkt, Ord(PublishEmail), 1); //Publush email: 1 = yes, 0 = no.
- CreateCLI_TOICQSRV(Pkt, UIN, $07D0, @lpkt, lpkt.Len, Seq, Seq2); //Incapsulate in CLI_TOICQSRV
- end;
- {Set the about string.}
- procedure CreateCLI_METASETABOUT(Pkt: PRawPkt; UIN: LongWord; const About: String; var Seq, Seq2: Word);
- var
- lpkt: TRawPkt;
- begin
- PktInitRaw(@lpkt);
- PktInt(@lpkt, $0604, 2); //CLI_METASETABOUT Channel: 2, SNAC(21,2) 2000/1030
- PktLNTS(@lpkt, About); //The about information string to set.
- CreateCLI_TOICQSRV(Pkt, UIN, $07D0, @lpkt, lpkt.Len, Seq, Seq2); //Incapsulate in CLI_TOICQSRV
- end;
- {Send SMS message.}
- procedure CreateCLI_SENDSMS(Pkt: PRawPkt; UIN: LongWord; const Destination, Text: String; CodePage: Word; const Time: String; var Seq, Seq2: Word);
- var
- lpkt: TRawPkt;
- S: String;
- begin
- PktInitRaw(@lpkt);
- PktInt(@lpkt, $8214, 2); //CLI_SENDSMS Channel: 2, SNAC(21,2) 2000/5250
- PktInt(@lpkt, $0001, 2); //Unknown: 0x1 = 1.
- PktInt(@lpkt, $0016, 2); //Unknown: 0x16 = 22.
- PktInt(@lpkt, 0, 4);
- PktInt(@lpkt, 0, 4);
- PktInt(@lpkt, 0, 4);
- PktInt(@lpkt, 0, 4);
- //Format message
- S := '<icq_sms_message>' +
- '<destination>' + Destination + '</destination>' +
- '<text>' + StrToUTF8(Text) + '</text>' +
- '<codepage>' + IntToStr(CodePage) + '</codepage>' +
- '<senders_UIN>' + IntToStr(UIN) + '</senders_UIN>' +
- '<senders_name>TICQClient</senders_name>' +
- '<delivery_receipt>Yes</delivery_receipt>' +
- '<time>' + Time + '</time>' +
- '</icq_sms_message>';
- PktTLV(@lpkt, 0, S); //The message as a XML entity
- CreateCLI_TOICQSRV(Pkt, UIN, $07D0, @lpkt, lpkt.Len, Seq, Seq2); //Incapsulate in CLI_TOICQSRV
- end;
- {Sends a messaged/request with advanced options}
- procedure CreateCLI_SENDADVMSG_CUSTOM(Pkt: PRawPkt; FFSeq: Word; ITime, IRandom, UIN: LongWord; CMD, MSGTYPE: Byte; ACMD: Word; const Msg: String; Data: Pointer; DataLen: LongWord; RTFFormat: Boolean; var Seq: Word; Accept: Boolean = True);
- var
- lpTLV05: TRawPkt;
- lpTLV2711: TRawPkt;
- const
- StrGuid: String = '{97B12751-243C-4334-AD22-D6ABF73F1492}';
- Capabilities: array[0..15] of Byte = ($09, $46, $13, $49, $4C, $7F, $11, $D1,
- $82, $22, $44, $45, $53, $54, $00, $00);
- begin
- PktInit(Pkt, 2, Seq); //Channel 2
- PktSnac(Pkt, $04, $06, 0, 0); //Snac: Type x04/x06, ID x0000, Flags 0
- PktInt(Pkt, ITime, 4); //Seems to be a time stamp in 1/1500 sec since 8am of that Sunday.
- PktInt(Pkt, IRandom, 2); //A seemingly random ID generated for each message.
- PktInt(Pkt, $00000002, 4); //The message type used
- PktLStr(Pkt, UIN); //Destination UIN.
- PktInitRaw(@lpTLV2711); //TLV(2711)
- PktInt(@lpTLV2711, $1b, 1); //If this value is not present, this is not a message packet.
- PktInt(@lpTLV2711, $0008, 2); //This is the version of the TCP protocol that the sending client uses.
- PktInt(@lpTLV2711, $00, 1); //Unknown
- PktInt(@lpTLV2711, $00000000, 4); //Caps, empty
- PktInt(@lpTLV2711, $00000000, 4); //Caps, empty
- PktInt(@lpTLV2711, $00000000, 4); //Caps, empty
- PktInt(@lpTLV2711, $00000000, 4); //Caps, empty
- PktInt(@lpTLV2711, $0000, 2); //Unknown
- PktInt(@lpTLV2711, $03, 1); //Unknown
- PktInt(@lpTLV2711, $00000000, 4); //0 = normal message, 4 = file ok or file request.
- PktInt(@lpTLV2711, FFSeq, 2); //SEQ1
- PktInt(@lpTLV2711, $0e00, 2); //Unknown, seen: 0x1200 and 0x0e00.
- PktInt(@lpTLV2711, FFSeq, 2); //SEQ1
- PktInt(@lpTLV2711, $00000000, 4); //Unknown, always zero.
- PktInt(@lpTLV2711, $00000000, 4); //Unknown, always zero.
- PktInt(@lpTLV2711, $00000000, 4); //Unknown, always zero.
- PktInt(@lpTLV2711, CMD, 1); //0x01 - normal message, 0x1a - filerequest/response, contacts
- PktInt(@lpTLV2711, MSGTYPE, 1); //00 - normal message 80 - multiple recipients 03 - auto reply message request.
- PktInt(@lpTLV2711, $0000, 2); //Usually 0, seen 0x2000.
- PktInt(@lpTLV2711, $0000, 2); //Usually 0, seen 0x0002 in information request messages.
- if Length(Msg) = 0 then
- begin
- PktLInt(@lpTLV2711, $0001, 2); //Length of the message
- PktInt(@lpTLV2711, $00, 1); //The message should always have null terminator, event if it's empty
- end else
- PktLNTS(@lpTLV2711, Msg); //The message!
- if CMD = $01 then
- begin
- PktInt(@lpTLV2711, $00000000, 4); //Only present in actual real messages, this will be the background color of the text box in RGB0 format.
- PktInt(@lpTLV2711, $FFFFFF00, 4); //Only present in actual real messages, this will be the text color of the message in RGB0 format.
- end else
- PktAddArrBuf(@lpTLV2711, Data, DataLen); //Add packet specific data
- if RTFFormat then //If we are using RTF format, then add GUID
- begin
- PktLInt(@lpTLV2711, Length(StrGuid), 4); //This is a little-endian string length of the following GUID. This is only present in real messages sent by the latest 2001b client build 3659.
- PktStr(@lpTLV2711, StrGuid); //This GUID seems to indicate that the client is capable of handling Multibyte Wide Character Strings as messages. Only present in real messages sent by build 3659 2001b clients.
- end;
- PktInitRaw(@lpTLV05); //TLV(05)
- PktInt(@lpTLV05, $0000, 2); //0x0000 - normal message
- PktInt(@lpTLV05, ITime, 4); //Seems to be a time stamp in 1/1500 sec since 8am of that Sunday.
- PktInt(@lpTLV05, IRandom, 2); //A seemingly random ID generated for each message.
- PktInt(@lpTLV05, $0000, 2); //Unknown: 0.
- PktAddArrBuf(@lpTLV05, @Capabilities, 16); //One of the capabilities sent in CLI_SETUSERINFO
- PktTLV(@lpTLV05, $000a, 2, ACMD); //0x0001 - normal message 0x0002 - file ack or file ok
- PktTLV(@lpTLV05, $000f, 0, $00); //Unknown, empty.
- //PktTLV(@lpTLV05, $0003, $0004, $c0a86516); //Timestamp
- //PktTLV(@lpTLV05, $0005, $0002, $5d3c); //Unknown
- PktTLV(@lpTLV05, $2711, lpTLV2711.Len, @lpTLV2711); //Incapsulate TLV2711 into TLV05
- PktTLV(Pkt, $05, lpTLV05.Len, @lpTLV05); //Incapsulate TLV05 into Pkt
- PktTLV(Pkt, $0003, 0, 0); //Unknown, empty TLV(03)
- PktFinal(Pkt); //Finalize packet
- end;
- {Sends a messaged with advanced options}
- procedure CreateCLI_SENDMSG_ADVANCED(Pkt: PRawPkt; ITime, IRandom, UIN: LongWord; const Msg: String; RTFFormat: Boolean; var Seq: Word);
- begin
- CreateCLI_SENDADVMSG_CUSTOM(Pkt, $FFFF, ITime, IRandom, UIN, $01, $00, $0001, Msg, nil, 0, RTFFormat, Seq, True);
- end;
- {Sends an ack with advanced options}
- procedure CreateCLI_SENDMSG_FILEACK(Pkt: PRawPkt; FFSeq: Word; ITime, IRandom, UIN, FileSize: LongWord; const FileDesc, FileName: String; Port: Word; var Seq: Word);
- var