Thu, 12 Jun 2003 05:01:11 +0000
[gaim-migrate @ 6269]
regain the ability to remember what plugins we had loaded
| 2086 | 1 | /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
| 2 | ||
| 3 | /* | |
| 4 | * $Id: tcpchathandle.c 2096 2001-07-31 01:00:39Z warmenhoven $ | |
| 5 | * | |
| 6 | * Copyright (C) 1998-2001, Denis V. Dmitrienko <denis@null.net> and | |
| 7 | * Bill Soudan <soudan@kde.org> | |
| 8 | * | |
| 9 | * This program is free software; you can redistribute it and/or modify | |
| 10 | * it under the terms of the GNU General Public License as published by | |
| 11 | * the Free Software Foundation; either version 2 of the License, or | |
| 12 | * (at your option) any later version. | |
| 13 | * | |
| 14 | * This program is distributed in the hope that it will be useful, | |
| 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 17 | * GNU General Public License for more details. | |
| 18 | * | |
| 19 | * You should have received a copy of the GNU General Public License | |
| 20 | * along with this program; if not, write to the Free Software | |
| 21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
| 22 | * | |
| 23 | */ | |
| 24 | ||
| 25 | #include <stdlib.h> | |
| 26 | ||
| 27 | #include "icqlib.h" | |
| 28 | ||
| 29 | #include "stdpackets.h" | |
| 30 | #include "chatsession.h" | |
| 31 | ||
| 32 | void icq_HandleChatAck(icq_TCPLink *plink, icq_Packet *p, int port) | |
| 33 | { | |
| 34 | icq_TCPLink *pchatlink; | |
| 35 | icq_ChatSession *pchat; | |
| 36 | icq_Packet *p2; | |
| 37 | ||
| 38 | pchatlink=icq_TCPLinkNew(plink->icqlink); | |
| 39 | pchatlink->type=TCP_LINK_CHAT; | |
| 40 | pchatlink->id=p->id; | |
| 41 | ||
| 42 | /* once the ack packet has been processed, create a new chat session */ | |
| 43 | pchat=icq_ChatSessionNew(plink->icqlink); | |
| 44 | ||
| 45 | pchat->id=p->id; | |
| 46 | pchat->remote_uin=plink->remote_uin; | |
| 47 | pchat->tcplink=pchatlink; | |
| 48 | ||
| 49 | invoke_callback(plink->icqlink, icq_RequestNotify)(plink->icqlink, p->id, | |
| 50 | ICQ_NOTIFY_CHATSESSION, sizeof(icq_ChatSession), pchat); | |
| 51 | ||
| 52 | icq_ChatSessionSetStatus(pchat, CHAT_STATUS_CONNECTING); | |
| 53 | icq_TCPLinkConnect(pchatlink, plink->remote_uin, port); | |
| 54 | ||
| 55 | pchatlink->session=pchat; | |
| 56 | ||
| 57 | p2=icq_TCPCreateChatInfoPacket(pchatlink, plink->icqlink->icq_Nick, | |
| 58 | 0x00ffffff, 0x00000000); | |
| 59 | icq_TCPLinkSend(pchatlink, p2); | |
| 60 | ||
| 61 | } | |
| 62 | ||
| 63 | void icq_HandleChatHello(icq_TCPLink *plink) | |
| 64 | { | |
| 65 | ||
| 66 | /* once the hello packet has been processed and we know which uin this | |
| 67 | * link is for, we can link up with a chat session */ | |
| 68 | icq_ChatSession *pchat=icq_FindChatSession(plink->icqlink, | |
| 69 | plink->remote_uin); | |
| 70 | ||
| 71 | if(pchat) | |
| 72 | { | |
| 73 | plink->id=pchat->id; | |
| 74 | plink->session=pchat; | |
| 75 | icq_ChatSessionSetStatus(pchat, CHAT_STATUS_WAIT_NAME); | |
| 76 | ||
| 77 | } else { | |
| 78 | ||
| 79 | icq_FmtLog(plink->icqlink, ICQ_LOG_WARNING, | |
| 80 | "unexpected chat hello received from %d, closing link\n", | |
| 81 | plink->remote_uin); | |
| 82 | icq_TCPLinkClose(plink); | |
| 83 | } | |
| 84 | ||
| 85 | } | |
| 86 | ||
| 87 | void icq_TCPOnChatReqReceived(icq_Link *icqlink, DWORD uin, | |
| 88 | const char *message, DWORD id) | |
| 89 | { | |
| 90 | /* use the current system time for time received */ | |
| 91 | time_t t=time(0); | |
| 92 | struct tm *ptime=localtime(&t); | |
| 93 | ||
| 94 | #ifdef TCP_PACKET_TRACE | |
| 95 | printf("chat request packet received from %lu { sequence=%lx, message=%s }\n", | |
| 96 | uin, id, message); | |
| 97 | #endif /* TCP_PACKET_TRACE */ | |
| 98 | ||
| 99 | invoke_callback(icqlink,icq_RecvChatReq)(icqlink, uin, ptime->tm_hour, | |
| 100 | ptime->tm_min, ptime->tm_mday, ptime->tm_mon+1, ptime->tm_year+1900, | |
| 101 | message, id); | |
| 102 | ||
| 103 | /* don't send an acknowledgement to the remote client! | |
| 104 | * GUI is responsible for sending acknowledgement once user accepts | |
| 105 | * or denies using icq_TCPSendChatAck */ | |
| 106 | } | |
| 107 | ||
| 108 | void icq_TCPChatUpdateFont(icq_ChatSession *psession, const char *font, | |
| 109 | WORD encoding, DWORD style, DWORD size) | |
| 110 | { | |
| 111 | icq_Link *icqlink = psession->icqlink; | |
| 112 | int packet_len, fontlen; | |
| 113 | char *buffer; | |
| 114 | ||
| 115 | buffer = malloc(packet_len = (2 + (fontlen = strlen(font) + 1)) + | |
| 116 | 2 + 1 + (4+1)*2); | |
| 117 | buffer[0] = '\x11'; | |
| 118 | *((DWORD *)&buffer[1]) = style; | |
| 119 | buffer[5] = '\x12'; | |
| 120 | *((DWORD *)&buffer[6]) = size; | |
| 121 | buffer[10] = '\x10'; | |
| 122 | *((WORD *)&buffer[11]) = fontlen; | |
| 123 | strcpy(&buffer[13], font); | |
| 124 | ||
| 125 | icq_RusConv("wk", &buffer[13]); | |
| 126 | ||
| 127 | *((WORD *)&buffer[13 + fontlen]) = encoding; | |
| 128 | ||
| 129 | invoke_callback(icqlink, icq_ChatNotify)(psession, CHAT_NOTIFY_DATA, | |
| 130 | packet_len, buffer); | |
| 131 | ||
| 132 | free(buffer); | |
| 133 | } | |
| 134 | ||
| 135 | void icq_TCPChatUpdateColors(icq_ChatSession *psession, DWORD foreground, | |
| 136 | DWORD background) | |
| 137 | { | |
| 138 | icq_Link *icqlink = psession->icqlink; | |
| 139 | char buffer[10]; | |
| 140 | ||
| 141 | buffer[0] = '\x00'; | |
| 142 | *((DWORD *)&buffer[1]) = foreground; | |
| 143 | buffer[5] = '\x01'; | |
| 144 | *((DWORD *)&buffer[6]) = background; | |
| 145 | ||
| 146 | invoke_callback(icqlink, icq_ChatNotify)(psession, | |
| 147 | CHAT_NOTIFY_DATA, sizeof(buffer), buffer); | |
| 148 | } | |
| 149 | ||
| 150 | void icq_TCPProcessChatPacket(icq_Packet *p, icq_TCPLink *plink) | |
| 151 | { | |
| 152 | DWORD code; | |
| 153 | DWORD remote_uin; | |
| 154 | DWORD ip1, ip2; | |
| 155 | DWORD fg, bg, fontstyle, fontsize; | |
| 156 | WORD port1, encoding; | |
| 157 | icq_Packet *presponse; | |
| 158 | icq_ChatSession *pchat=(icq_ChatSession *)plink->session; | |
| 159 | const char *font, *user; | |
| 160 | ||
| 161 | icq_PacketBegin(p); | |
| 162 | ||
| 163 | code=icq_PacketRead32(p); | |
| 164 | remote_uin=icq_PacketRead32(p); | |
| 165 | ||
| 166 | if(code==0x00000006 || code==0x00070004) | |
| 167 | { | |
| 168 | font = (char *)NULL; | |
| 169 | encoding = 0; | |
| 170 | fontstyle = 0; | |
| 171 | fontsize = 0; | |
| 172 | if(code == 0x00070004) | |
| 173 | { | |
| 174 | ip1 = icq_PacketRead32(p); | |
| 175 | ip2 = icq_PacketRead32(p); | |
| 176 | icq_PacketRead8(p); | |
| 177 | port1 = icq_PacketRead16(p); | |
| 178 | fontsize = icq_PacketRead32(p); | |
| 179 | fontstyle = icq_PacketRead32(p); | |
| 180 | font = icq_PacketReadString(p); | |
| 181 | encoding = icq_PacketRead16(p); | |
| 182 | } | |
| 183 | else | |
| 184 | { | |
| 185 | ip1 = icq_PacketRead32(p); | |
| 186 | ip2 = icq_PacketRead32(p); | |
| 187 | port1 = icq_PacketRead16(p); | |
| 188 | icq_PacketRead8(p); | |
| 189 | fontsize = icq_PacketRead32(p); | |
| 190 | fontstyle = icq_PacketRead32(p); | |
| 191 | font = icq_PacketReadString(p); | |
| 192 | encoding = icq_PacketRead16(p); | |
| 193 | } | |
| 194 | if(font) | |
| 195 | icq_TCPChatUpdateFont(pchat, font, encoding, fontstyle, fontsize); | |
| 196 | icq_ChatSessionSetStatus(pchat, CHAT_STATUS_READY); | |
| 197 | plink->mode|=TCP_LINK_MODE_RAW; | |
| 198 | } | |
| 199 | else | |
| 200 | if(remote_uin>0xffffff00) | |
| 201 | { | |
| 202 | remote_uin=icq_PacketRead32(p); | |
| 203 | user = icq_PacketReadString(p); | |
| 204 | icq_PacketRead16(p); /* Unknown */; | |
| 205 | fg = icq_PacketRead32(p); | |
| 206 | bg = icq_PacketRead32(p); | |
| 207 | icq_TCPChatUpdateColors(pchat, fg, bg); | |
| 208 | ||
| 209 | presponse=icq_TCPCreateChatInfo2Packet(plink, plink->icqlink->icq_Nick, | |
| 210 | 0x00ffffff, 0x00000000); | |
| 211 | icq_PacketSend(presponse, plink->socket); | |
| 212 | icq_PacketDelete(presponse); | |
| 213 | icq_ChatSessionSetStatus(pchat, CHAT_STATUS_WAIT_FONT); | |
| 214 | } | |
| 215 | else | |
| 216 | { | |
| 217 | user = icq_PacketReadString(p); | |
| 218 | fg = icq_PacketRead32(p); | |
| 219 | bg = icq_PacketRead32(p); | |
| 220 | icq_TCPChatUpdateColors(pchat, fg, bg); | |
| 221 | font = (char *)NULL; | |
| 222 | encoding = 0; | |
| 223 | fontstyle = 0; | |
| 224 | fontsize = 0; | |
| 225 | if((code = icq_PacketRead32(p)) == 0x00070004) | |
| 226 | { | |
| 227 | icq_PacketRead32(p); | |
| 228 | ip1 = icq_PacketRead32(p); | |
| 229 | ip2 = icq_PacketRead32(p); | |
| 230 | icq_PacketRead8(p); | |
| 231 | port1 = icq_PacketRead16(p); | |
| 232 | fontsize = icq_PacketRead32(p); | |
| 233 | fontstyle = icq_PacketRead32(p); | |
| 234 | font = icq_PacketReadString(p); | |
| 235 | encoding = icq_PacketRead16(p); | |
| 236 | } | |
| 237 | else if(code == 0x00000006) | |
| 238 | { | |
| 239 | icq_PacketRead32(p); | |
| 240 | ip1 = icq_PacketRead32(p); | |
| 241 | ip2 = icq_PacketRead32(p); | |
| 242 | port1 = icq_PacketRead16(p); | |
| 243 | icq_PacketRead8(p); | |
| 244 | fontsize = icq_PacketRead32(p); | |
| 245 | fontstyle = icq_PacketRead32(p); | |
| 246 | font = icq_PacketReadString(p); | |
| 247 | encoding = icq_PacketRead16(p); | |
| 248 | } | |
| 249 | if(font) | |
| 250 | icq_TCPChatUpdateFont(pchat, font, encoding, fontstyle, fontsize); | |
| 251 | presponse=icq_TCPCreateChatFontInfoPacket(plink); | |
| 252 | icq_PacketSend(presponse, plink->socket); | |
| 253 | icq_PacketDelete(presponse); | |
| 254 | /* notify app that chat connection has been established */ | |
| 255 | icq_ChatSessionSetStatus(pchat, CHAT_STATUS_READY); | |
| 256 | plink->mode|=TCP_LINK_MODE_RAW; | |
| 257 | } | |
| 258 | } | |
| 259 |