From 48540940b6c28bb4378abfeb500ec45a625b37b6 Mon Sep 17 00:00:00 2001 From: Vadim Dashevskiy Date: Tue, 15 May 2012 10:38:20 +0000 Subject: initial commit git-svn-id: http://svn.miranda-ng.org/main/trunk@2 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/AimOscar/client.cpp | 1002 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1002 insertions(+) create mode 100644 protocols/AimOscar/client.cpp (limited to 'protocols/AimOscar/client.cpp') diff --git a/protocols/AimOscar/client.cpp b/protocols/AimOscar/client.cpp new file mode 100644 index 0000000000..6c3dbfb86a --- /dev/null +++ b/protocols/AimOscar/client.cpp @@ -0,0 +1,1002 @@ +/* +Plugin of Miranda IM for communicating with users of the AIM protocol. +Copyright (c) 2008-2012 Boris Krasnovskiy +Copyright (C) 2005-2006 Aaron Myles Landwehr + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +#include "aim.h" +#include "version.h" + +int CAimProto::aim_send_connection_packet(HANDLE hServerConn,unsigned short &seqno,char *buf) +{ + return aim_sendflap(hServerConn,0x01,4,buf,seqno); +} + +int CAimProto::aim_authkey_request(HANDLE hServerConn,unsigned short &seqno) +{ + unsigned short offset=0; + char* buf=(char*)alloca(SNAC_SIZE+TLV_HEADER_SIZE*3+strlen(username)); + aim_writesnac(0x17,0x06,offset,buf); + aim_writetlv(0x01,(unsigned short)strlen(username),username,offset,buf); + aim_writetlv(0x4B,0,0,offset,buf); + aim_writetlv(0x5A,0,0,offset,buf); + return aim_sendflap(hServerConn,0x02,offset,buf,seqno); +} + +int CAimProto::aim_auth_request(HANDLE hServerConn,unsigned short &seqno,const char* key,const char* language, + const char* country, const char* username, const char* password) +{ + unsigned short offset=0; + mir_md5_byte_t pass_hash[16]; + mir_md5_byte_t auth_hash[16]; + mir_md5_state_t state; + + mir_md5_init(&state); + mir_md5_append(&state,(const mir_md5_byte_t *)password, (int)strlen(password)); + mir_md5_finish(&state,pass_hash); + mir_md5_init(&state); + mir_md5_append(&state,(mir_md5_byte_t*)key, (int)strlen(key)); + mir_md5_append(&state,(mir_md5_byte_t*)pass_hash,MD5_HASH_LENGTH); + mir_md5_append(&state,(mir_md5_byte_t*)AIM_MD5_STRING, sizeof(AIM_MD5_STRING)-1); + mir_md5_finish(&state,auth_hash); + + char client_id[64]; + int client_id_len = mir_snprintf(client_id, sizeof(client_id), "Miranda AIM, version %s", __VERSION_STRING); + + char* buf=(char*)alloca(SNAC_SIZE+TLV_HEADER_SIZE*14+MD5_HASH_LENGTH+strlen(username)+client_id_len+30+strlen(language)+strlen(country)); + + aim_writesnac(0x17,0x02,offset,buf); + aim_writetlv(0x01,(unsigned short)strlen(username),username,offset,buf); + aim_writetlv(0x25,MD5_HASH_LENGTH,(char*)auth_hash,offset,buf); + aim_writetlv(0x4C,0,0,offset,buf);//signifies new password hash instead of old method + aim_writetlv(0x03,(unsigned short)client_id_len,client_id,offset,buf); + aim_writetlvshort(0x17,AIM_CLIENT_MAJOR_VERSION,offset,buf); + aim_writetlvshort(0x18,AIM_CLIENT_MINOR_VERSION,offset,buf); + aim_writetlvshort(0x19,AIM_CLIENT_LESSER_VERSION,offset,buf); + aim_writetlvshort(0x1A,AIM_CLIENT_BUILD_NUMBER,offset,buf); + aim_writetlvshort(0x16,AIM_CLIENT_ID_NUMBER,offset,buf); + aim_writetlvlong(0x14,AIM_CLIENT_DISTRIBUTION_NUMBER,offset,buf); + aim_writetlv(0x0F,(unsigned short)strlen(language),language,offset,buf); + aim_writetlv(0x0E,(unsigned short)strlen(country),country,offset,buf); + aim_writetlvchar(0x4A,getByte(AIM_KEY_FSC, 0) ? 3 : 1,offset,buf); +// aim_writetlvchar(0x94,0,offset,buf); + if (!getByte(AIM_KEY_DSSL, 0)) + aim_writetlv(0x8c,0,NULL,offset,buf); // Request SSL connection + return aim_sendflap(hServerConn,0x02,offset,buf,seqno); +} + +int CAimProto::aim_send_cookie(HANDLE hServerConn,unsigned short &seqno,int cookie_size,char * cookie) +{ + unsigned short offset=0; + char* buf=(char*)alloca(TLV_HEADER_SIZE*2+cookie_size); + aim_writelong(0x01,offset,buf);//protocol version number + aim_writetlv(0x06,(unsigned short)cookie_size,cookie,offset,buf); + return aim_sendflap(hServerConn,0x01,offset,buf,seqno); +} + +int CAimProto::aim_send_service_request(HANDLE hServerConn,unsigned short &seqno) +{ + unsigned short offset=0; + char buf[SNAC_SIZE+TLV_HEADER_SIZE*12]; + aim_writesnac(0x01,0x17,offset,buf); + aim_writefamily(AIM_SERVICE_GENERIC,offset,buf); + aim_writefamily(AIM_SERVICE_SSI,offset,buf); + aim_writefamily(AIM_SERVICE_LOCATION,offset,buf); + aim_writefamily(AIM_SERVICE_BUDDYLIST,offset,buf); + aim_writefamily(AIM_SERVICE_MESSAGING,offset,buf); + aim_writefamily(AIM_SERVICE_ICQ,offset,buf); + aim_writefamily(AIM_SERVICE_INVITATION,offset,buf); + aim_writefamily(AIM_SERVICE_POPUP,offset,buf); + aim_writefamily(AIM_SERVICE_BOS,offset,buf); + aim_writefamily(AIM_SERVICE_USERLOOKUP,offset,buf); + aim_writefamily(AIM_SERVICE_STATS,offset,buf); + aim_writefamily(AIM_SERVICE_UNKNOWN,offset,buf); + return aim_sendflap(hServerConn,0x02,offset,buf,seqno); +} + +int CAimProto::aim_new_service_request(HANDLE hServerConn,unsigned short &seqno,unsigned short service) +{ + unsigned short offset=0; + char buf[SNAC_SIZE+2+TLV_HEADER_SIZE]; + aim_writesnac(0x01,0x04,offset,buf); + aim_writeshort(service,offset,buf); + if (!getByte(AIM_KEY_DSSL, 0)) + aim_writetlv(0x8c,0,NULL,offset,buf); + return aim_sendflap(hServerConn,0x02,offset,buf,seqno); +} + +int CAimProto::aim_request_rates(HANDLE hServerConn,unsigned short &seqno) +{ + unsigned short offset=0; + char buf[SNAC_SIZE]; + aim_writesnac(0x01,0x06,offset,buf); + return aim_sendflap(hServerConn,0x02,offset,buf,seqno); +} + +int CAimProto::aim_accept_rates(HANDLE hServerConn,unsigned short &seqno) +{ + unsigned short offset=0; + char buf[SNAC_SIZE*2]; + aim_writesnac(0x01,0x08,offset,buf); + aim_writegeneric(10,AIM_SERVICE_RATES,offset,buf); + return aim_sendflap(hServerConn,0x02,offset,buf,seqno); +} + +int CAimProto::aim_request_icbm(HANDLE hServerConn,unsigned short &seqno) +{ + unsigned short offset=0; + char buf[SNAC_SIZE]; + aim_writesnac(0x04,0x04,offset,buf); + return aim_sendflap(hServerConn,0x02,offset,buf,seqno); +} + +int CAimProto::aim_set_icbm(HANDLE hServerConn,unsigned short &seqno) +{ + const unsigned icbm_flags = ICBM_CHANNEL_MSGS_ALLOWED | ICBM_MISSED_CALLS_ENABLED | + ICBM_EVENTS_ALLOWED | ICBM_SMS_SUPPORTED | ICBM_OFFLINE_MSGS_ALLOWED; +// const unsigned icbm_flags = 0x3db; + + unsigned short offset=0; + char buf[SNAC_SIZE+16]; + aim_writesnac(0x04,0x02,offset,buf); + aim_writeshort(0,offset,buf); //channel + aim_writelong(icbm_flags,offset,buf); //flags + aim_writeshort(0x1f40,offset,buf); //max snac size 8000 + aim_writeshort(0x03e7,offset,buf); //max sender warning level 999 (0-1000) WinAim default + aim_writeshort(0x03e7,offset,buf); //max receiver warning level 999 (0-1000) WinAim default + aim_writelong(0,offset,buf); //min message interval, ms 0 + return aim_sendflap(hServerConn,0x02,offset,buf,seqno); +} + +int CAimProto::aim_request_offline_msgs(HANDLE hServerConn,unsigned short &seqno) +{ + unsigned short offset=0; + char buf[SNAC_SIZE]; + aim_writesnac(0x04,0x10,offset,buf); // Subtype for offline messages 0x10 + return aim_sendflap(hServerConn,0x02,offset,buf,seqno); +} + +int CAimProto::aim_request_list(HANDLE hServerConn,unsigned short &seqno) +{ + unsigned short offset=0; + char buf[SNAC_SIZE]; + aim_writesnac(0x13,0x04,offset,buf); + return aim_sendflap(hServerConn,0x02,offset,buf,seqno); +} + +int CAimProto::aim_activate_list(HANDLE hServerConn,unsigned short &seqno) +{ + unsigned short offset=0; + char buf[SNAC_SIZE]; + aim_writesnac(0x13,0x07,offset,buf); + return aim_sendflap(hServerConn,0x02,offset,buf,seqno); +} + +/* +0000 00 05 00 02 00 17 00 06 00 03 00 00 00 00 07 00 ................ +0010 01 00 00 08 00 01 01 00 0a 00 14 00 02 00 08 66 ...............f +0020 61 63 65 62 6f 6f 6b 00 06 67 6f 6f 67 6c 65 acebook..google + +int CAimProto::aim_request_rights(HANDLE hServerConn,unsigned short &seqno) +{ + unsigned short offset=0; + char buf[SNAC_SIZE+50]; + aim_writesnac(0x03,0x02,offset,buf); + aim_writetlvshort(0x05,0x17,offset,buf); + aim_writetlv(0x06,3,"\x0\x0",offset,buf); + aim_writetlvchar(0x07,0x01,offset,buf); + aim_writetlvshort(0x05,0x17,offset,buf); + aim_writetlvshort(0x05,0x17,offset,buf); + return aim_sendflap(hServerConn,0x02,offset,buf,seqno); +} +*/ +int CAimProto::aim_set_caps(HANDLE hServerConn,unsigned short &seqno) +{ + unsigned short offset=0; + int i=1; + char buf[SNAC_SIZE+TLV_HEADER_SIZE*3+AIM_CAPS_LENGTH*50+sizeof(AIM_MSG_TYPE)]; + char temp[AIM_CAPS_LENGTH*20]; + memcpy(temp,AIM_CAP_SHORT_CAPS,AIM_CAPS_LENGTH); + memcpy(&temp[AIM_CAPS_LENGTH*i++],AIM_CAP_HOST_STATUS_TEXT_AWARE,AIM_CAPS_LENGTH); + memcpy(&temp[AIM_CAPS_LENGTH*i++],AIM_CAP_SMART_CAPS,AIM_CAPS_LENGTH); + memcpy(&temp[AIM_CAPS_LENGTH*i++],AIM_CAP_FILE_TRANSFER,AIM_CAPS_LENGTH); +// memcpy(&temp[AIM_CAPS_LENGTH*i++],AIM_CAP_HAS_MICROPHONE,AIM_CAPS_LENGTH); +// memcpy(&temp[AIM_CAPS_LENGTH*i++],AIM_CAP_RTCAUDIO,AIM_CAPS_LENGTH); +// memcpy(&temp[AIM_CAPS_LENGTH*i++],AIM_CAP_HAS_CAMERA,AIM_CAPS_LENGTH); +// memcpy(&temp[AIM_CAPS_LENGTH*i++],AIM_CAP_RTCVIDEO,AIM_CAPS_LENGTH); + memcpy(&temp[AIM_CAPS_LENGTH*i++],AIM_CAP_BUDDY_ICON,AIM_CAPS_LENGTH); + memcpy(&temp[AIM_CAPS_LENGTH*i++],AIM_CAP_CHAT,AIM_CAPS_LENGTH); + memcpy(&temp[AIM_CAPS_LENGTH*i++],AIM_CAP_SUPPORT_ICQ,AIM_CAPS_LENGTH); +// memcpy(&temp[AIM_CAPS_LENGTH*i++],AIM_CAP_ICQ_SERVER_RELAY,AIM_CAPS_LENGTH); + memcpy(&temp[AIM_CAPS_LENGTH*i++],AIM_CAP_UTF8,AIM_CAPS_LENGTH); + memcpy(&temp[AIM_CAPS_LENGTH*i++],AIM_CAP_MIRANDA,AIM_CAPS_LENGTH); + if(getByte(AIM_KEY_HF, 0)) + memcpy(&temp[AIM_CAPS_LENGTH*i++],AIM_CAP_HIPTOP,AIM_CAPS_LENGTH); + aim_writesnac(0x02,0x04,offset,buf); + aim_writetlv(0x05,(unsigned short)(AIM_CAPS_LENGTH*i),temp,offset,buf); + + return aim_sendflap(hServerConn,0x02,offset,buf,seqno); +} + +int CAimProto::aim_set_profile(HANDLE hServerConn,unsigned short &seqno, char* amsg)//user info +{ + aimString str(amsg); + const char *charset = str.isUnicode() ? AIM_MSG_TYPE_UNICODE : AIM_MSG_TYPE; + const unsigned short charset_len = (unsigned short)strlen(charset); + + const char* msg = str.getBuf(); + const unsigned short msg_len = str.getSize(); + + char* buf=(char*)alloca(SNAC_SIZE+TLV_HEADER_SIZE*3+1+charset_len+msg_len); + unsigned short offset=0; + + aim_writesnac(0x02,0x04,offset,buf); + aim_writetlvchar(0x0c,1,offset,buf); + aim_writetlv(0x01,charset_len,charset,offset,buf); + aim_writetlv(0x02,msg_len,msg,offset,buf); + return aim_sendflap(hServerConn,0x02,offset,buf,seqno); +} + +int CAimProto::aim_client_ready(HANDLE hServerConn,unsigned short &seqno) +{ + unsigned short offset=0; + NETLIBBIND nlb = {0}; + nlb.cbSize = sizeof(nlb); + nlb.pfnNewConnectionV2 = (NETLIBNEWCONNECTIONPROC_V2)aim_direct_connection_initiated; + nlb.pExtra = this; + hDirectBoundPort = (HANDLE)CallService(MS_NETLIB_BINDPORT, (WPARAM)hNetlibPeer, (LPARAM)&nlb); + if (hDirectBoundPort == NULL) + { + ShowPopup(LPGEN("Aim was unable to bind to a port. File transfers may not succeed in some cases."), ERROR_POPUP); + } + else + { + local_port = nlb.wPort; + internal_ip = nlb.dwInternalIP; + } + + char buf[SNAC_SIZE+TLV_HEADER_SIZE*22]; + aim_writesnac(0x01,0x02,offset,buf); + aim_writefamily(AIM_SERVICE_GENERIC,offset,buf); + aim_writegeneric(4,AIM_TOOL_VERSION,offset,buf); + aim_writefamily(AIM_SERVICE_SSI,offset,buf); + aim_writegeneric(4,AIM_TOOL_VERSION,offset,buf); + aim_writefamily(AIM_SERVICE_LOCATION,offset,buf); + aim_writegeneric(4,AIM_TOOL_VERSION,offset,buf); + aim_writefamily(AIM_SERVICE_BUDDYLIST,offset,buf); + aim_writegeneric(4,AIM_TOOL_VERSION,offset,buf); + aim_writefamily(AIM_SERVICE_MESSAGING,offset,buf); + aim_writegeneric(4,AIM_TOOL_VERSION,offset,buf); + aim_writefamily(AIM_SERVICE_ICQ,offset,buf); + aim_writegeneric(4,AIM_TOOL_VERSION,offset,buf); + aim_writefamily(AIM_SERVICE_INVITATION,offset,buf); + aim_writegeneric(4,AIM_TOOL_VERSION,offset,buf); + //removed extra generic server + aim_writefamily(AIM_SERVICE_POPUP,offset,buf); + aim_writegeneric(4,"\x01\x04\0\x01",offset,buf);//different version number like trillian 3.1 + aim_writefamily(AIM_SERVICE_BOS,offset,buf); + aim_writegeneric(4,AIM_TOOL_VERSION,offset,buf); + aim_writefamily(AIM_SERVICE_USERLOOKUP,offset,buf); + aim_writegeneric(4,AIM_TOOL_VERSION,offset,buf); + aim_writefamily(AIM_SERVICE_STATS,offset,buf); + aim_writegeneric(4,AIM_TOOL_VERSION,offset,buf); + return aim_sendflap(hServerConn,0x02,offset,buf,seqno); +} + +int CAimProto::aim_mail_ready(HANDLE hServerConn,unsigned short &seqno) +{ + unsigned short offset=0; + char buf[SNAC_SIZE+TLV_HEADER_SIZE*4]; + aim_writesnac(0x01,0x02,offset,buf); + aim_writefamily(AIM_SERVICE_GENERIC,offset,buf); + aim_writegeneric(4,AIM_TOOL_VERSION,offset,buf); + aim_writefamily(AIM_SERVICE_MAIL,offset,buf); + aim_writegeneric(4,AIM_TOOL_VERSION,offset,buf); + return aim_sendflap(hServerConn,0x02,offset,buf,seqno); +} + +int CAimProto::aim_avatar_ready(HANDLE hServerConn,unsigned short &seqno) +{ + unsigned short offset=0; + char buf[SNAC_SIZE+TLV_HEADER_SIZE*4]; + aim_writesnac(0x01,0x02,offset,buf); + aim_writefamily(AIM_SERVICE_GENERIC,offset,buf); + aim_writegeneric(4,AIM_TOOL_VERSION,offset,buf); + aim_writefamily(AIM_SERVICE_AVATAR,offset,buf); + aim_writegeneric(4,AIM_TOOL_VERSION,offset,buf); + return aim_sendflap(hServerConn,0x02,offset,buf,seqno); +} + +int CAimProto::aim_chatnav_ready(HANDLE hServerConn,unsigned short &seqno) +{ + unsigned short offset=0; + char buf[SNAC_SIZE+TLV_HEADER_SIZE*4]; + aim_writesnac(0x01,0x02,offset,buf); + aim_writefamily(AIM_SERVICE_GENERIC,offset,buf); + aim_writegeneric(4,AIM_TOOL_VERSION,offset,buf); + aim_writefamily(AIM_SERVICE_CHATNAV,offset,buf); + aim_writegeneric(4,AIM_TOOL_VERSION,offset,buf); + return aim_sendflap(hServerConn,0x02,offset,buf,seqno); +} + +int CAimProto::aim_chat_ready(HANDLE hServerConn,unsigned short &seqno) +{ + unsigned short offset=0; + char buf[SNAC_SIZE+TLV_HEADER_SIZE*4]; + aim_writesnac(0x01,0x02,offset,buf); + aim_writefamily(AIM_SERVICE_GENERIC,offset,buf); + aim_writegeneric(4,AIM_TOOL_VERSION,offset,buf); + aim_writefamily(AIM_SERVICE_CHAT,offset,buf); + aim_writegeneric(4,AIM_TOOL_VERSION,offset,buf); + return aim_sendflap(hServerConn,0x02,offset,buf,seqno); +} + +int CAimProto::aim_send_message(HANDLE hServerConn,unsigned short &seqno,const char* sn,char* amsg,bool auto_response, bool blast) +{ + aimString str(amsg); + + const char* msg = str.getBuf(); + const unsigned short msg_len = str.getSize(); + + unsigned short tlv_offset=0; + char* tlv_buf=(char*)alloca(5+msg_len+8); + + char icbm_cookie[8]; + CallService(MS_UTILS_GETRANDOM, 8, (LPARAM)icbm_cookie); + + aim_writegeneric(5,"\x05\x01\x00\x01\x01",tlv_offset,tlv_buf); // icbm im capabilities + aim_writeshort(0x0101,tlv_offset,tlv_buf); // icbm im text tag + aim_writeshort(msg_len+4,tlv_offset,tlv_buf); // icbm im text tag length + aim_writeshort(str.isUnicode()?2:0,tlv_offset,tlv_buf); // character set + aim_writeshort(0,tlv_offset,tlv_buf); // language + + aim_writegeneric(msg_len,msg,tlv_offset,tlv_buf); // message text + + unsigned short offset=0; + unsigned short sn_length=(unsigned short)strlen(sn); + char* buf= (char*)alloca(SNAC_SIZE+8+3+sn_length+TLV_HEADER_SIZE*3+tlv_offset); + + aim_writesnac(0x04,0x06,offset,buf,get_random()); + aim_writegeneric(8,icbm_cookie,offset,buf); // icbm cookie + aim_writeshort(0x01,offset,buf); // channel + aim_writechar((unsigned char)sn_length,offset,buf); // screen name len + aim_writegeneric(sn_length,sn,offset,buf); // screen name + + aim_writetlv(0x02,tlv_offset,tlv_buf,offset,buf); + + if (!blast) + { + if(auto_response) + aim_writetlv(0x04,0,0,offset,buf); // auto-response message + else + { + aim_writetlv(0x03,0,0,offset,buf); // message ack request + aim_writetlv(0x06,0,0,offset,buf); // offline message storage + } + } + return aim_sendflap(hServerConn,0x02,offset,buf,seqno) ? 0 : *(int*)icbm_cookie & 0x7fffffff; +} + +int CAimProto::aim_query_profile(HANDLE hServerConn,unsigned short &seqno,char* sn) +{ + unsigned short offset=0; + unsigned short sn_length=(unsigned short)strlen(sn); + char* buf=(char*)alloca(SNAC_SIZE+5+sn_length); + aim_writesnac(0x02,0x15,offset,buf); + aim_writelong(0x01,offset,buf); + aim_writechar((unsigned char)sn_length,offset,buf); + aim_writegeneric(sn_length,sn,offset,buf); + return aim_sendflap(hServerConn,0x02,offset,buf,seqno)==0; +} + +int CAimProto::aim_delete_contact(HANDLE hServerConn, unsigned short &seqno, char* sn, unsigned short item_id, + unsigned short group_id, unsigned short list, bool nil) +{ + unsigned short offset=0; + unsigned short sn_length=(unsigned short)strlen(sn); + char* buf=(char*)alloca(SNAC_SIZE+sn_length+10); + aim_writesnac(0x13,0x0a,offset,buf, get_random()); // SSI Delete + aim_writeshort(sn_length,offset,buf); // screen name length + aim_writegeneric(sn_length,sn,offset,buf); // screen name + aim_writeshort(group_id,offset,buf); // group id + aim_writeshort(item_id,offset,buf); // buddy id + aim_writeshort(list,offset,buf); // buddy type + aim_writeshort(nil?4:0,offset,buf); // length of extra data + if (nil) aim_writetlv(0x6a,0,NULL,offset,buf); + return aim_sendflap(hServerConn,0x02,offset,buf,seqno); +} + +int CAimProto::aim_add_contact(HANDLE hServerConn, unsigned short &seqno, const char* sn, unsigned short item_id, + unsigned short group_id, unsigned short list, char* nick, char* note) +{ + unsigned short offset=0; + unsigned short sn_length=(unsigned short)strlen(sn); + unsigned short nick_length = (unsigned short)_strlens(nick); + unsigned short note_length = (unsigned short)_strlens(note); + unsigned short tlv_len = nick || note ? TLV_HEADER_SIZE * 2 + nick_length + note_length : 0; + + char* buf=(char*)alloca(SNAC_SIZE + sn_length + 10 + tlv_len); + aim_writesnac(0x13,0x08,offset,buf, get_random()); // SSI Add + aim_writeshort(sn_length,offset,buf); // screen name length + aim_writegeneric(sn_length,sn,offset,buf); // screen name + aim_writeshort(group_id,offset,buf); // group id + aim_writeshort(item_id,offset,buf); // buddy id + aim_writeshort(list,offset, buf); // buddy type + aim_writeshort(tlv_len,offset,buf); // length of extra data + + if (nick || note) + { + aim_writetlv(0x13c,note_length,note,offset,buf); + aim_writetlv(0x131,nick_length,nick,offset,buf); + } + return aim_sendflap(hServerConn, 0x02, offset, buf, seqno); +} + +int CAimProto::aim_mod_group(HANDLE hServerConn, unsigned short &seqno, const char* name, unsigned short group_id, + char* members, unsigned short members_length) +{ + unsigned short offset=0; + unsigned short name_length=(unsigned short)strlen(name); + char* buf=(char*)alloca(SNAC_SIZE+TLV_HEADER_SIZE+name_length+members_length+10); + aim_writesnac(0x13,0x09,offset,buf, get_random()); // SSI Edit + aim_writeshort(name_length,offset,buf); // group name length + aim_writegeneric(name_length,name,offset,buf); // group name + aim_writeshort(group_id,offset,buf); // group id + aim_writeshort(0,offset,buf); // buddy id + aim_writeshort(1,offset,buf); // buddy type: Group + aim_writeshort(TLV_HEADER_SIZE+members_length,offset,buf); // length of extra data + aim_writetlv(0xc8,members_length,members,offset,buf); + return aim_sendflap(hServerConn,0x02,offset,buf,seqno); +} + +int CAimProto::aim_mod_buddy(HANDLE hServerConn, unsigned short &seqno, const char* sn, + unsigned short buddy_id, unsigned short group_id, + char* nick, char* note) +{ + unsigned short offset=0; + unsigned short sn_length = (unsigned short)strlen(sn); + unsigned short nick_length = (unsigned short)_strlens(nick); + unsigned short note_length = (unsigned short)_strlens(note); + unsigned short tlv_len = TLV_HEADER_SIZE * 2 + nick_length + note_length; + + char* buf=(char*)alloca(SNAC_SIZE+sn_length+10+tlv_len); + aim_writesnac(0x13,0x09,offset,buf, get_random()); // SSI Edit + aim_writeshort(sn_length,offset,buf); // screen name length + aim_writegeneric(sn_length,sn,offset,buf); // screen name + aim_writeshort(buddy_id,offset,buf); // buddy id + aim_writeshort(group_id,offset,buf); // group id + aim_writeshort(0,offset,buf); // buddy type: Buddy + aim_writeshort(tlv_len,offset,buf); // length of extra data + + aim_writetlv(0x13c,note_length,note,offset,buf); + aim_writetlv(0x131,nick_length,nick,offset,buf); + return aim_sendflap(hServerConn,0x02,offset,buf,seqno); +} + +int CAimProto::aim_set_pd_info(HANDLE hServerConn, unsigned short &seqno) +{ + unsigned short offset=0; + char buf[SNAC_SIZE+TLV_HEADER_SIZE*3+20]; + unsigned short req = 0x09; + if (pd_info_id == 0) + { + pd_info_id = get_random(); + req = 0x08; + } + aim_writesnac(0x13,req,offset,buf, get_random()); // SSI Edit/Add + aim_writeshort(0,offset,buf); // name length + aim_writeshort(0,offset,buf); // group id (root) + aim_writeshort(pd_info_id,offset,buf); // buddy id + aim_writeshort(0x4,offset,buf); // pd info id + aim_writeshort(0x15,offset,buf); // size + aim_writetlvchar(0xca,pd_mode,offset,buf); // pd mode + aim_writetlvlong(0xcb,0xffffffff,offset,buf); // pd mask + aim_writetlvlong(0xcc,pd_flags,offset,buf); // pd flags + return aim_sendflap(hServerConn,0x02,offset,buf,seqno); +} + +int CAimProto::aim_ssi_update_preferences(HANDLE hServerConn, unsigned short &seqno) +{ + unsigned short offset = 0; + char buf[SNAC_SIZE+TLV_HEADER_SIZE*4+100]; + unsigned short req = 0x09; + if (pref1_id == 0) + { + pref1_id = get_random(); + req = 0x08; + } + aim_writesnac(0x13,req,offset,buf, get_random()); // SSI Edit/Add + aim_writeshort(0,offset,buf); // group name length + aim_writeshort(0,offset,buf); // group id (root) + aim_writeshort(pref1_id,offset,buf); // buddy id + aim_writeshort(5,offset,buf); // buddy type: Presence + + unsigned short tlv_len = TLV_HEADER_SIZE * 2 + 8; + if (pref2_len) tlv_len += TLV_HEADER_SIZE + pref2_len; + if (pref2_set_len) tlv_len += TLV_HEADER_SIZE + pref2_set_len; + + aim_writeshort(tlv_len,offset,buf); // length of extra data + aim_writetlvlong(0xc9,pref1_flags,offset,buf); // Update Buddy preferences 1 + aim_writetlvlong(0xd6,pref1_set_flags,offset,buf); // Update Buddy preferences 1 + if (pref2_len) + aim_writetlv(0xd7,pref2_len,pref2_flags,offset,buf); // Update Buddy preferences 2 + if (pref2_set_len) + aim_writetlv(0xd8,pref2_set_len,pref2_set_flags,offset,buf);// Update Buddy preferences 2 + return aim_sendflap(hServerConn,0x02,offset,buf,seqno); +} + +int CAimProto::aim_ssi_update(HANDLE hServerConn, unsigned short &seqno, bool start) +{ + unsigned short offset=0; + char buf[SNAC_SIZE]; + aim_writesnac(0x13,start?0x11:0x12,offset,buf); + return aim_sendflap(hServerConn,0x02,offset,buf,seqno)==0; +} + +int CAimProto::aim_keepalive(HANDLE hServerConn,unsigned short &seqno) +{ + return aim_sendflap(hServerConn,0x05,4,"\x0\x0\x0\xEE",seqno); +} + +// used when requesting a regular file transfer +int CAimProto::aim_send_file(HANDLE hServerConn, unsigned short &seqno, + unsigned long ip, unsigned short port, + bool force_proxy, file_transfer *ft) +{ + char msg_frag[2048]; + unsigned short frag_offset=0; + + aim_writeshort(0,frag_offset,msg_frag); // request type + aim_writegeneric(8,ft->icbm_cookie,frag_offset,msg_frag); // icbm cookie + aim_writegeneric(AIM_CAPS_LENGTH, AIM_CAP_FILE_TRANSFER, + frag_offset, msg_frag); // uuid + aim_writetlvshort(0x0a,++ft->req_num,frag_offset,msg_frag); // request number +// aim_writetlvshort(0x12,2,frag_offset,msg_frag); // max protocol version + + aim_writetlvlong(0x02,ip,frag_offset,msg_frag); // ip + aim_writetlvlong(0x16,~ip,frag_offset,msg_frag); // ip check + + aim_writetlvshort(0x05,port,frag_offset,msg_frag); // port + aim_writetlvshort(0x17,~port,frag_offset,msg_frag); // port ip check + + if (force_proxy) + aim_writetlv(0x10,0,0,frag_offset,msg_frag); // request proxy transfer + else + aim_writetlvlong(0x03,internal_ip,frag_offset,msg_frag); // ip + + if (ft->req_num == 1) + { + if (ft->message) + { + aimString dscr(ft->message); + + const char* charset = dscr.isUnicode() ? "unicode-2-0" : "us-ascii"; + const unsigned short charset_len = (unsigned short)strlen(charset); + + const char* desc_msg = dscr.getBuf(); + const unsigned short desc_len = dscr.getSize(); + + aim_writetlv(0x0e,2,"en",frag_offset,msg_frag); // language used by the data + aim_writetlv(0x0d,charset_len,charset,frag_offset,msg_frag);// charset used by the data + aim_writetlv(0x0c,desc_len,desc_msg,frag_offset,msg_frag); // invitaion text + } + + aim_writetlv(0x0f,0,0,frag_offset,msg_frag); // request host check + + const char* fname = get_fname(ft->file); + const unsigned short fnlen = (unsigned short)strlen(fname); + + char* fblock = (char*)alloca(9 + fnlen); + *(unsigned short*)&fblock[0] = _htons(ft->pfts.totalFiles > 1 ? 2 : 1); // single file transfer + *(unsigned short*)&fblock[2] = _htons(ft->pfts.totalFiles); // number of files + *(unsigned long*) &fblock[4] = _htonl(ft->pfts.totalBytes); // total bytes in files + memcpy(&fblock[8], fname, fnlen + 1); + + const char* enc = is_utf(fname) ? "utf-8" : "us-ascii"; + aim_writetlv(0x2711,9+fnlen,fblock,frag_offset,msg_frag); // extra data, file names, size + aim_writetlv(0x2712,8,enc,frag_offset,msg_frag); // character set used by data +// aim_writetlvlong64(0x2713,ft->pfts.totalBytes,frag_offset,msg_frag); // file length + + LOG("Attempting to Send a file to a buddy."); + } + else + { + aim_writetlvshort(0x14,0x0a,frag_offset,msg_frag); // Counter proposal reason + } + + unsigned short offset=0; + unsigned short sn_length=(unsigned short)strlen(ft->sn); + char* buf=(char*)alloca(SNAC_SIZE+TLV_HEADER_SIZE*2+12+frag_offset+sn_length); + aim_writesnac(0x04,0x06,offset,buf); // msg to host + aim_writegeneric(8,ft->icbm_cookie,offset,buf); // icbm cookie + aim_writeshort(2,offset,buf); // icbm channel + aim_writechar((unsigned char)sn_length,offset,buf); // screen name length + aim_writegeneric(sn_length,ft->sn,offset,buf); // screen name + aim_writetlv(0x05,frag_offset,msg_frag,offset,buf); // icbm tags + aim_writetlv(0x03,0,0,offset,buf); // request ack + + char cip[20]; + long_ip_to_char_ip(ip, cip); + LOG("IP for Buddy to connect to: %s:%u", cip, port); + return aim_sendflap(hServerConn,0x02,offset,buf,seqno)==0; +} + + +int CAimProto::aim_file_ad(HANDLE hServerConn,unsigned short &seqno,char* sn, char* icbm_cookie, bool deny, unsigned short max_ver) +{ + unsigned short frag_offset=0; + char msg_frag[10+AIM_CAPS_LENGTH+TLV_HEADER_SIZE*2+6]; + aim_writeshort(deny ? 1 : 2,frag_offset,msg_frag); // icbm accept / deny + aim_writegeneric(8,icbm_cookie,frag_offset,msg_frag); // icbm cookie + aim_writegeneric(AIM_CAPS_LENGTH, + AIM_CAP_FILE_TRANSFER,frag_offset,msg_frag); // uuid + +// if (max_ver > 1) +// aim_writetlvshort(0x12,2,frag_offset,msg_frag); // max protocol version + + unsigned short sn_length=(unsigned short)strlen(sn); + unsigned short offset=0; + char* buf=(char*)alloca(SNAC_SIZE+TLV_HEADER_SIZE+21+frag_offset+sn_length); + aim_writesnac(0x04,0x06,offset,buf); // msg to host + aim_writegeneric(8,icbm_cookie,offset,buf); // icbm cookie + aim_writeshort(2,offset,buf); // icbm channel + aim_writechar((unsigned char)sn_length,offset,buf); // screen name length + aim_writegeneric(sn_length,sn,offset,buf); // screen name + aim_writetlv(0x05,frag_offset,msg_frag,offset,buf); // icbm tags + + LOG("%s a file transfer.", deny ? "Denying" : "Accepting"); + return aim_sendflap(hServerConn,0x02,offset,buf,seqno)==0; +} + +int CAimProto::aim_typing_notification(HANDLE hServerConn,unsigned short &seqno,char* sn,unsigned short type) +{ + unsigned short offset=0; + unsigned short sn_length=(unsigned short)strlen(sn); + char* buf= (char*)alloca(SNAC_SIZE+sn_length+13); + aim_writesnac(0x04,0x14,offset,buf); + aim_writegeneric(8,"\0\0\0\0\0\0\0\0",offset,buf); // icbm cookie + aim_writeshort(1,offset,buf); // icbm channel + aim_writechar((unsigned char)sn_length,offset,buf); // screen name length + aim_writegeneric(sn_length,sn,offset,buf); // screen name + aim_writeshort(type,offset,buf); // typing event + return aim_sendflap(hServerConn,0x02,offset,buf,seqno); +} + +int CAimProto::aim_set_idle(HANDLE hServerConn,unsigned short &seqno,unsigned long seconds) +{ + unsigned short offset=0; + char buf[SNAC_SIZE+4]; + aim_writesnac(0x01,0x11,offset,buf); + aim_writelong(seconds,offset,buf); + return aim_sendflap(hServerConn,0x02,offset,buf,seqno); +} + +int CAimProto::aim_request_mail(HANDLE hServerConn,unsigned short &seqno) +{ + unsigned short offset=0; + char buf[SNAC_SIZE+34]; + aim_writesnac(0x18,0x06,offset,buf); + aim_writegeneric(34, + "\x00\x02" + "\xb3\x80\x9a\xd8\x0d\xba\x11\xd5\x9f\x8a\x00\x60\xb0\xee\x06\x31" + "\x5d\x5e\x17\x08\x55\xaa\x11\xd3\xb1\x43\x00\x60\xb0\xfb\x1e\xcb", + offset,buf); + return aim_sendflap(hServerConn,0x02,offset,buf,seqno); +} + +int CAimProto::aim_activate_mail(HANDLE hServerConn,unsigned short &seqno) +{ + unsigned short offset=0; + char buf[SNAC_SIZE+17]; + aim_writesnac(0x18,0x16,offset,buf); + aim_writegeneric(17,"\x02\x04\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00",offset,buf); + return aim_sendflap(hServerConn,0x02,offset,buf,seqno); +} + +int CAimProto::aim_request_avatar(HANDLE hServerConn,unsigned short &seqno, const char* sn, unsigned short bart_type, const char* hash, unsigned short hash_size) +{ + unsigned short offset=0; + unsigned char sn_length=(unsigned char)strlen(sn); + char* buf= (char*)alloca(SNAC_SIZE+sn_length+hash_size+12); + aim_writesnac(0x10,0x06,offset,buf); + aim_writechar(sn_length,offset,buf); // screen name length + aim_writegeneric(sn_length,sn,offset,buf); // screen name + aim_writechar(1,offset,buf); // number of BART ID + aim_writebartid(bart_type,0,hash_size,hash,offset,buf); + return aim_sendflap(hServerConn,0x02,offset,buf,seqno); +} + +int CAimProto::aim_set_avatar_hash(HANDLE hServerConn, unsigned short &seqno, char flags, unsigned short bart_type, unsigned short &id, char size, const char* hash) +{ + unsigned short offset=0; + + char bart_type_txt[8]; + ultoa(bart_type, bart_type_txt, 10); + unsigned short bart_type_len = (unsigned short)strlen(bart_type_txt); + + unsigned short req = 0x09; + if (id == 0) + { + id = get_random(); + req = 0x08; + } + + char* buf = (char*)alloca(SNAC_SIZE + TLV_HEADER_SIZE * 2 + 20 + size + bart_type_len); + aim_writesnac(0x13,req,offset,buf, get_random()); // SSI Edit/Add + aim_writeshort(bart_type_len,offset,buf); // name length + aim_writegeneric(bart_type_len,bart_type_txt,offset,buf); // name + aim_writeshort(0,offset,buf); // group id + aim_writeshort(id,offset,buf); // buddy id + aim_writeshort(0x14,offset,buf); // buddy type: Buddy Icon + aim_writeshort(2+size+TLV_HEADER_SIZE,offset,buf); // length of extra data + + char* buf2 = (char*)alloca(2+size); + buf2[0] = flags; + buf2[1] = (char)size; + memcpy(&buf2[2], hash, size); + aim_writetlv(0xd5, 2+size, buf2, offset, buf); // BART + + return aim_sendflap(hServerConn,0x02,offset,buf,seqno); +} + +int CAimProto::aim_delete_avatar_hash(HANDLE hServerConn, unsigned short &seqno, char flags, unsigned short bart_type, unsigned short & id) +{ + unsigned short offset=0; + + if (id == 0) return -1; + id = 0; + + char bart_type_txt[8]; + ultoa(bart_type, bart_type_txt, 10); + unsigned short bart_type_len = (unsigned short)strlen(bart_type_txt); + + char* buf = (char*)alloca(SNAC_SIZE + 20 + bart_type_len); + aim_writesnac(0x13,0x0a,offset,buf, get_random()); // SSI Delete + aim_writeshort(bart_type_len,offset,buf); // name length + aim_writegeneric(bart_type_len,bart_type_txt,offset,buf); // name + aim_writeshort(0,offset,buf); // group id + aim_writeshort(id,offset,buf); // buddy id + aim_writeshort(0x14,offset,buf); // buddy type: Buddy Icon + aim_writeshort(0,offset,buf); // length of extra data + + return aim_sendflap(hServerConn,0x02,offset,buf,seqno); +} + +int CAimProto::aim_upload_avatar(HANDLE hServerConn, unsigned short &seqno, unsigned short bart_type, const char* avatar, unsigned short avatar_size) +{ + unsigned short offset=0; + char* buf=(char*)alloca(SNAC_SIZE+22+avatar_size); + aim_writesnac(0x10,0x02,offset,buf); + aim_writeshort(bart_type,offset,buf); // BART id + aim_writeshort(avatar_size,offset,buf); + aim_writegeneric(avatar_size,avatar,offset,buf); + return aim_sendflap(hServerConn,0x02,offset,buf,seqno); +} + +int CAimProto::aim_search_by_email(HANDLE hServerConn,unsigned short &seqno, const char* email) +{ + unsigned short offset=0; + char em_length=(char)strlen(email); + char* buf= (char*)alloca(SNAC_SIZE+em_length); + aim_writesnac(0x0a,0x02,offset,buf); // Email search + aim_writegeneric(em_length,email,offset,buf); + return aim_sendflap(hServerConn,0x02,offset,buf,seqno); +} + +int CAimProto::aim_chatnav_request_limits(HANDLE hServerConn,unsigned short &seqno) +{ + unsigned short offset=0; + char buf[SNAC_SIZE]; + aim_writesnac(0x0d,0x02,offset,buf); + return aim_sendflap(hServerConn,0x02,offset,buf,seqno) ? -1 : 0; +} + +int CAimProto::aim_chatnav_create(HANDLE hServerConn,unsigned short &seqno, char* room, unsigned short exchage) +{ + //* Join Pseudo Room (Get's the info we need for the real connection) + unsigned short room_len = (unsigned short)strlen(room); + + unsigned short offset=0; + char* buf=(char*)alloca(SNAC_SIZE+10+room_len+26); + aim_writesnac(0x0d,0x08,offset,buf); + aim_writeshort(exchage,offset,buf); // Exchange + aim_writechar(6,offset,buf); // Command Length + aim_writegeneric(6,"create",offset,buf); // Command + aim_writeshort(0xffff,offset,buf); // Last Instance + aim_writechar(1,offset,buf); // Detail + aim_writeshort(3,offset,buf); // Number of TLVs + aim_writetlv(0xd3,room_len,room,offset,buf); // Room Name + aim_writetlv(0xd6,8,"us-ascii",offset,buf); // Character Set + aim_writetlv(0xd7,2,"en",offset,buf); // Language Encoding + + return aim_sendflap(hServerConn,0x02,offset,buf,seqno); +} + +int CAimProto::aim_chatnav_room_info(HANDLE hServerConn,unsigned short &seqno, char* chat_cookie, unsigned short exchange, unsigned short instance) +{ + unsigned short offset=0; + unsigned short chat_cookie_len = (unsigned short)strlen(chat_cookie); + char* buf=(char*)alloca(SNAC_SIZE+7+chat_cookie_len); + aim_writesnac(0x0d,0x04,offset,buf); + aim_writeshort(exchange,offset,buf); // Exchange + aim_writechar((unsigned char)chat_cookie_len,offset,buf); // Chat Cookie Length + aim_writegeneric(chat_cookie_len,chat_cookie,offset,buf); // Chat Cookie + aim_writeshort(instance,offset,buf); // Last Instance + aim_writechar(1,offset,buf); // Detail + return aim_sendflap(hServerConn,0x02,offset,buf,seqno); +} + +int CAimProto::aim_chat_join_room(HANDLE hServerConn,unsigned short &seqno, char* chat_cookie, + unsigned short exchange, unsigned short instance, unsigned short id) +{ + unsigned short offset=0; + unsigned short cookie_len = (unsigned short)strlen(chat_cookie); + char* buf=(char*)alloca(SNAC_SIZE+TLV_HEADER_SIZE*2+cookie_len+8); + aim_writesnac(0x01,0x04,offset,buf,id); + aim_writeshort(0x0e,offset,buf); // Service request for Chat + + aim_writeshort(0x01,offset,buf); // Tag + aim_writeshort(cookie_len+5,offset,buf); // Length + aim_writeshort(exchange,offset,buf); // Value - Exchange + aim_writechar((unsigned char)cookie_len,offset,buf); // Value - Cookie Length + aim_writegeneric(cookie_len,chat_cookie,offset,buf); // Value - Cookie + aim_writeshort(instance,offset,buf); // Value - Instance + + if (!getByte(AIM_KEY_DSSL, 0)) + aim_writetlv(0x8c,0,NULL,offset,buf); // Request SSL connection + + return aim_sendflap(hServerConn,0x02,offset,buf,seqno); +} + +int CAimProto::aim_chat_send_message(HANDLE hServerConn, unsigned short &seqno, char *amsg) +{ + aimString str(amsg); + + const char* charset = str.isUnicode() ? "unicode-2-0" : "us-ascii"; + const unsigned short chrset_len = (unsigned short)strlen(charset); + + const char* msg = str.getBuf(); + const unsigned short msg_len = str.getSize(); + + unsigned short tlv_offset=0; + char* tlv_buf=(char*)alloca(TLV_HEADER_SIZE*4+chrset_len+msg_len+20); + aim_writetlv(0x04,13,"text/x-aolrtf",tlv_offset,tlv_buf); // Format + aim_writetlv(0x02,chrset_len,charset,tlv_offset,tlv_buf); // Character Set + aim_writetlv(0x03,2,"en",tlv_offset,tlv_buf); // Language Encoding + aim_writetlv(0x01,msg_len,msg,tlv_offset,tlv_buf); // Message + + unsigned short offset=0; + char* buf=(char*)alloca(SNAC_SIZE+8+2+TLV_HEADER_SIZE*3+tlv_offset); + aim_writesnac(0x0e,0x05,offset,buf); + aim_writegeneric(8,"\0\0\0\0\0\0\0\0",offset,buf); // Message Cookie (can be random) + aim_writeshort(0x03,offset,buf); // Message Channel (Always 3 for chat) + aim_writetlv(0x01,0,NULL,offset,buf); // Public/Whisper flag + aim_writetlv(0x06,0,NULL,offset,buf); // Enable Reflection flag + aim_writetlv(0x05,tlv_offset,tlv_buf,offset,buf); // Message Information TLV + + return aim_sendflap(hServerConn,0x02,offset,buf,seqno); +} + +int CAimProto::aim_chat_invite(HANDLE hServerConn,unsigned short &seqno, char* chat_cookie, unsigned short exchange, unsigned short instance, char* sn, char* msg) +{ + unsigned short offset=0; + unsigned short chat_cookie_len = (unsigned short)strlen(chat_cookie); + unsigned short sn_len = (unsigned short)strlen(sn); + unsigned short msg_len = (unsigned short)strlen(msg); + char* buf=(char*)alloca(SNAC_SIZE+64+chat_cookie_len+sn_len+msg_len); + aim_writesnac(0x04,0x06,offset,buf); + aim_writegeneric(8,"\0\0\0\0\0\0\0\0",offset,buf); // ICBM Cookie + aim_writeshort(2,offset,buf); // ICBM Channel + aim_writechar((unsigned char)sn_len,offset,buf); // Screen Name Length + aim_writegeneric(sn_len,sn,offset,buf); // Screen Name + + aim_writeshort(0x05,offset,buf); // Rendezvous Message Data TLV + aim_writeshort(49+msg_len+chat_cookie_len,offset,buf); // TLV size + + aim_writeshort(0,offset,buf); // Message Type (0) - Request + aim_writegeneric(8,"\0\0\0\0\0\0\0\0",offset,buf); // ICBM Cookie (same as above) + aim_writegeneric(16,AIM_CAP_CHAT,offset,buf); // Capability + + aim_writetlvshort(0x0a,1,offset,buf); // Sequence Number TLV + aim_writetlv(0x0f,0,NULL,offset,buf); // Request Host Caps Check TLV + aim_writetlv(0x0c,msg_len,msg,offset,buf); // Invitation Message TLV + + aim_writeshort(0x2711,offset,buf); // Capability TLV + aim_writeshort(chat_cookie_len+5,offset,buf); // Length + aim_writeshort(exchange,offset,buf); // Value - Exchange + aim_writechar((unsigned char)chat_cookie_len,offset,buf); // Value - Cookie Length + aim_writegeneric(chat_cookie_len,chat_cookie,offset,buf); // Value - Cookie + aim_writeshort(instance,offset,buf); // Value - Instance + + return aim_sendflap(hServerConn,0x02,offset,buf,seqno); +} + +int CAimProto::aim_chat_deny(HANDLE hServerConn,unsigned short &seqno,char* sn,char* icbm_cookie) +{ + unsigned short offset=0; + unsigned short sn_length=(unsigned short)strlen(sn); + char* buf=(char*)alloca(SNAC_SIZE+20+sn_length); + aim_writesnac(0x04,0x0b,offset,buf); + aim_writegeneric(8,icbm_cookie,offset,buf); // ICBM Cookie + aim_writeshort(2,offset,buf); // Channel + aim_writechar((unsigned char)sn_length,offset,buf); // Screen Name length + aim_writegeneric(sn_length,sn,offset,buf); // Screen Name + aim_writeshort(3,offset,buf); // Error code + aim_writeshort(2,offset,buf); // Error code + aim_writeshort(1,offset,buf); // Error code + return aim_sendflap(hServerConn,0x02,offset,buf,seqno)==0; +} + +int CAimProto::aim_admin_ready(HANDLE hServerConn,unsigned short &seqno) +{ + unsigned short offset=0; + char buf[SNAC_SIZE+TLV_HEADER_SIZE*4]; + aim_writesnac(0x01,0x02,offset,buf); + aim_writefamily(AIM_SERVICE_GENERIC,offset,buf); + aim_writegeneric(4,AIM_TOOL_VERSION,offset,buf); + aim_writefamily(AIM_SERVICE_ADMIN,offset,buf); + aim_writegeneric(4,AIM_TOOL_VERSION,offset,buf); + return aim_sendflap(hServerConn,0x02,offset,buf,seqno); +} + +int CAimProto::aim_admin_format_name(HANDLE hServerConn,unsigned short &seqno, const char* sn) +{ + unsigned short offset=0; + unsigned short sn_len = (unsigned short)strlen(sn); + char* buf=(char*)alloca(SNAC_SIZE+TLV_HEADER_SIZE+sn_len); + aim_writesnac(0x07,0x04,offset,buf); + aim_writetlv(0x01,sn_len,sn,offset,buf); + return aim_sendflap(hServerConn,0x02,offset,buf,seqno); +} + +int CAimProto::aim_admin_change_email(HANDLE hServerConn,unsigned short &seqno, const char* email) +{ + unsigned short offset=0; + unsigned short email_len = (unsigned short)strlen(email); + char* buf=(char*)alloca(SNAC_SIZE+TLV_HEADER_SIZE+email_len); + aim_writesnac(0x07,0x04,offset,buf); + aim_writetlv(0x11,email_len,email,offset,buf); + return aim_sendflap(hServerConn,0x02,offset,buf,seqno); +} + +int CAimProto::aim_admin_change_password(HANDLE hServerConn,unsigned short &seqno, const char* cur_pw, const char* new_pw) +{ + unsigned short offset=0; + unsigned short cur_pw_len = (unsigned short)strlen(cur_pw); + unsigned short new_pw_len = (unsigned short)strlen(new_pw); + char* buf=(char*)alloca(SNAC_SIZE+2*TLV_HEADER_SIZE+cur_pw_len+new_pw_len); + aim_writesnac(0x07,0x04,offset,buf); + aim_writetlv(0x02,new_pw_len,new_pw,offset,buf); + aim_writetlv(0x12,cur_pw_len,cur_pw,offset,buf); + return aim_sendflap(hServerConn,0x02,offset,buf,seqno); +} + +int CAimProto::aim_admin_request_info(HANDLE hServerConn,unsigned short &seqno, const unsigned short &type) +{ + // types: 0x01 - nickname, 0x11 - email info, 0x13 - registration status + unsigned short offset=0; + char buf[SNAC_SIZE+TLV_HEADER_SIZE]; + aim_writesnac(0x07,0x02,offset,buf); + aim_writetlv(type,0,NULL,offset,buf); + return aim_sendflap(hServerConn,0x02,offset,buf,seqno); +} + +int CAimProto::aim_admin_account_confirm(HANDLE hServerConn,unsigned short &seqno) +{ + unsigned short offset=0; + char buf[SNAC_SIZE+TLV_HEADER_SIZE]; + aim_writesnac(0x07,0x06,offset,buf); + return aim_sendflap(hServerConn,0x02,offset,buf,seqno); +} -- cgit v1.2.3