On 7/11/07, Jon Keating wrote:
The list is the place to send it. I haven't been active due to being
sick since last week and then went on a 4-day vacation to Guam. Just
got back today so I will probably take a look at it tomorrow or
Friday.
And no, no one is currently working on anything related to ICQ6, but
crashes should be a high priority.
Jon
This is a new patch. This was made against svn rev. 5000 and includes
patches 1 and 2 (If you apply this patch, you don't need the other two).
This (hopefully) fixes the problem with retrieving the auto away message on
ICQ6 if you had the previous 2 xtraz patches applied and it also clears up
the code a little bit.
I put everything in one patch because I think it's easier for code
reviewing, but if you need one that only contains the differences with 1 and
2, you only have to ask. ;-)
As usual, comments and suggestions are welcome. :-)
Thanks!
Seba
Index: icqd-srv.cpp
===================================================================
--- src/icqd-srv.cpp svn rev. 5000
+++ src/icqd-srv.cpp 2007-07-11 19:19:10.000000000 -0300
@@ -39,6 +39,7 @@
#include "licq_countrycodes.h"
#include "licq_protoplugind.h"
+
void CICQDaemon::ProtoAddUser(const char *_szId, unsigned long _nPPID,
bool _bAuthRequired)
{
@@ -586,6 +587,7 @@
if (!u) return 0;
int nCmd;
+
switch (u->Status())
{
case ICQ_STATUS_AWAY:
@@ -598,6 +600,8 @@
nCmd = ICQ_CMDxTCP_READxOCCUPIEDxMSG; break;
case ICQ_STATUS_FREEFORCHAT:
nCmd = ICQ_CMDxTCP_READxFFCxMSG; break;
+ case ICQ_STATUS_XTRAZ:
+ nCmd = ICQ_CMDxTCP_READxXSTATUSxMSG; break;
default:
nCmd = ICQ_CMDxTCP_READxAWAYxMSG; break;
}
@@ -2411,7 +2415,7 @@
CPacket::SetRealIp(NetworkIpToPacketIp(realIP));
ICQOwner *owner = gUserManager.FetchOwner(LOCK_W);
owner->SetIp(realIP);
- gUserManager.DropOwner();
+ gUserManager.DropOwner();
char buf[32];
gLog.Info(tr("%sServer says we are at %s.\n"), L_SRVxSTR, ip_ntoa(realIP, buf));
@@ -2796,6 +2800,19 @@
{
version = "mICQ";
}
+ else {
+ for (int xc=0; xc < XTRA_AWAY_COUNT; xc++) {
+ if (memcmp(caps+(i * CAP_LENGTH), XtraAwayCaps[xc],
+ 16) == 0) {
+ nNewStatus = ICQ_STATUS_XTRAZ;
+ ChangeUserStatus(u, nNewStatus);
+ gLog.Info(tr("%s%s (%s) changed status: %s (%s)\n"),
+ L_SRVxSTR, u->GetAlias(), u->IdString(), u->StatusStr(), XtraAwayNames[xc]);
+ break;
+ }
+ }
+ }
+
}
delete [] caps;
@@ -3789,6 +3806,7 @@
delete [] buf;
break;
}
+ char szMsgTemp;
delete [] szId;
break;
}
@@ -3803,7 +3821,6 @@
nMsgID = packet.UnpackUnsignedLongBE(); // lower bits, what licq uses
nFormat = packet.UnpackUnsignedShortBE();
nUin = packet.UnpackUinString();
-
u = gUserManager.FetchUser(nUin, LOCK_W);
if (u == NULL)
{
@@ -3820,8 +3837,7 @@
{
if ((*iter)->nId == nMsgID && (*iter)->nUin == nUin)
{
- gLog.Warn("%sReverse connection from %s failed.\n", L_WARNxSTR,
- u->GetAlias());
+ gLog.Warn("%sReverse connection from %s failed.\n", L_WARNxSTR, u->GetAlias());
(*iter)->bSuccess = false;
(*iter)->bFinished = true;
bFound = true;
@@ -3872,7 +3888,6 @@
nSequence = packet.UnpackUnsignedShortBE();
packet.incDataPosRead(nLen - 2);
packet >> nMsgType;
-
if (memcmp(GUID, PLUGIN_NORMAL, GUID_LENGTH) != 0)
{
unsigned char nChannel = ICQ_CHNxUNKNOWN;
@@ -3888,13 +3903,41 @@
}
packet >> nAckFlags >> nMsgFlags >> nLen;
-
- char szMessage[nLen + 1];
+ if (nMsgType == 0x1A && nLen<=1) { // Xstatus or ICQ6 Auto Response
+ char szMsgTemp;
+ if (nLen == 1) // If size is 1, we read one byte and ignore it
+ packet >> szMsgTemp;
+ packet >> nLen; // Size of the full packet
+ for (unsigned short i = 0; i < nLen; i++) // We don't care about its contents for the moment
+ packet >> szMsgTemp;
+ packet >> nLen; // Size of the packet containing the message
+ for (unsigned short i = 0; i < 2; i++) // We don't care about its contents for the moment
+ packet >> szMsgTemp;
+ packet >> nLen; // This is the actual size of the message
+ for (unsigned short i = 0; i < 2; i++) // We don't care about its contents for the moment
+ packet >> szMsgTemp;
+ }
+ char szMessage[nLen+1];
for (unsigned short i = 0; i < nLen; i++)
packet >> szMessage[i];
szMessage[nLen] = '\0';
gTranslator.ServerToClient(szMessage);
-
+ if (nMsgType == 0x1A) { // Xstatus or ICQ6 Auto Response
+ char *desc, *title, *temp;
+ if ((desc=strstr(szMessage,"<desc>"))!= NULL) { // Xstatus
+ temp=strstr(szMessage,"</desc>");
+ temp[0]=0;
+ desc=desc+12;
+ if ((title=strstr(szMessage,"<title>"))!= NULL) {
+ temp=strstr(szMessage,"</title>");
+ temp[0]=0;
+ title=title+13;
+ }
+ strcpy(szMessage,title);
+ strcat(szMessage, " - ");
+ strcat(szMessage, desc);
+ }
+ }
if (nAckFlags == ICQ_TCPxACK_REFUSE)
{
pExtendedAck = new CExtendedAck(false, 0, szMessage);
Index: icqpacket.cpp
===================================================================
--- src/icqpacket.cpp svn rev. 5000
+++ src/icqpacket.cpp 2007-07-11 19:19:10.000000000 -0300
@@ -923,7 +923,7 @@
CPU_CapabilitySettings::CPU_CapabilitySettings()
: CPU_CommonFamily(ICQ_SNACxFAM_LOCATION, ICQ_SNACxLOC_SETxUSERxINFO)
{
- char data[7][CAP_LENGTH];
+ char data[8][CAP_LENGTH];
m_nSize += 4 + sizeof(data);
InitBuffer();
@@ -934,6 +934,7 @@
memcpy(data[4], ICQ_CAPABILITY_AIMxINTER, CAP_LENGTH);
memcpy(data[5], ICQ_CAPABILITY_RTFxMSGS, CAP_LENGTH);
memcpy(data[6], ICQ_CAPABILITY_ICHAT, CAP_LENGTH);
+ memcpy(data[7], ICQ_CAPABILITY_XTRAZ, CAP_LENGTH);
// Send our licq version
data[3][12] = INT_VERSION / 1000;
@@ -2029,7 +2030,7 @@
ICQ_CAPABILITY_SRVxRELAY, nMsgID1, nMsgID2)
{
m_nSize += 54;
-
+
m_nMsgFlags = _nMsgFlags;
m_nSequence = _nSequence;
@@ -2043,7 +2044,9 @@
case ICQ_STATUS_DND: m_nSubCommand = ICQ_CMDxTCP_READxDNDxMSG; break;
case ICQ_STATUS_OCCUPIED: m_nSubCommand = ICQ_CMDxTCP_READxOCCUPIEDxMSG; break;
case ICQ_STATUS_FREEFORCHAT: m_nSubCommand = ICQ_CMDxTCP_READxFFCxMSG; break;
- default: m_nSubCommand = ICQ_CMDxTCP_READxAWAYxMSG; break;
+ case ICQ_STATUS_XTRAZ: CPU_ReqXtrazMessage(u, ICQ_CMDxTCP_READxXSTATUSxMSG, m_nMsgFlags, _bAck, _nSequence, nMsgID1, nMsgID2); return; break;
+ default: m_nSubCommand = ICQ_CMDxTCP_READxAWAYxMSG; break;
+ //default: CPU_ReqXtrazMessage(u, ICQ_CMDxTCP_READxXSTATUSxMSG, m_nMsgFlags, _bAck, _nSequence, nMsgID1, nMsgID2); return; break;
}
InitBuffer();
}
@@ -2053,6 +2056,53 @@
}
}
+void CPU_AdvancedMessage::CPU_ReqXtrazMessage(ICQUser *u, unsigned short _nMsgType,
+ unsigned short _nMsgFlags, bool _bAck, unsigned short _nSequence,
+ unsigned long nMsgID1, unsigned long nMsgID2)
+{
+ char szUin[13];
+ ICQOwner *o = gUserManager.FetchOwner(LOCK_R);
+ snprintf(szUin, 13, "%lu", o->Uin());
+ unsigned long nUinLen = strlen(szUin);
+
+ m_nSize += 339 + nUinLen;
+
+ m_nMsgFlags = _nMsgFlags;
+ m_nSequence = _nSequence;
+ m_nSubCommand = ICQ_CMDxTCP_READxXSTATUSxMSG;
+ m_bDirectInfo = 0;
+ InitBuffer();
+ if (m_nSubCommand == ICQ_CMDxTCP_READxXSTATUSxMSG) {
+ char tempXtraz[273];
+ buffer->PackUnsignedShort(0x004F);
+ buffer->PackUnsignedShort(0x603B);
+ buffer->PackUnsignedShort(0xEFB3);
+ buffer->PackUnsignedShort(0x2AD8);
+ buffer->PackUnsignedShort(0x456C);
+ buffer->PackUnsignedShort(0xE0A4);
+ buffer->PackUnsignedShort(0x5A9C);
+ buffer->PackUnsignedShort(0x675E);
+ buffer->PackUnsignedShort(0x65E8);
+ buffer->PackUnsignedShort(0x0008);
+ buffer->PackUnsignedShort(0x002A);
+ buffer->PackUnsignedShort(0x0000);
+ snprintf(tempXtraz, 43, "%s", "Script Plug-in: Remote Notification Arrive"); // text
+ buffer->Pack(tempXtraz,43);
+ buffer->PackChar(0x00);
+ buffer->PackChar(0x01);
+ buffer->PackUnsignedLongBE(0x00000000);
+ buffer->PackUnsignedLongBE(0x00000000);
+ buffer->PackUnsignedLongBE(0x00000000);
+ buffer->PackUnsignedShort(0x0114);
+ buffer->PackUnsignedShort(0x0000);
+ buffer->PackUnsignedShort(0x0110);
+ buffer->PackUnsignedShort(0x0000);
+ snprintf(tempXtraz, 265+nUinLen, "<N><QUERY><Q><PluginID>srvMng</PluginID></Q></QUERY><NOTIFY><srv><id>cAwaySrv</id><req><id>AwayStat</id><trans>2</trans><senderId>%s</senderId></req></srv></NOTIFY></N>\r\n", szUin); // text
+ buffer->Pack(tempXtraz,264+nUinLen);
+ gUserManager.DropOwner();
+ }
+}
+
void CPU_AdvancedMessage::InitBuffer()
{
CPU_Type2Message::InitBuffer();
@@ -4988,7 +5038,7 @@
gTranslator.ClientToServer(m_szMessage);
m_nSize -= m_nMsgLen;
- m_nMsgLen = strlen(m_szMessage) + 1;
+ m_nMsgLen = strlen(m_szMessage);
m_nSize += m_nMsgLen;
}
Index: user.cpp
===================================================================
--- src/user.cpp svn rev. 5000
+++ src/user.cpp 2007-07-11 19:19:10.000000000 -0300
@@ -2450,7 +2450,8 @@
else if (m_nStatus & ICQ_STATUS_AWAY) return ICQ_STATUS_AWAY;
else if (m_nStatus & ICQ_STATUS_FREEFORCHAT) return ICQ_STATUS_FREEFORCHAT;
else if ((m_nStatus & 0xFF) == 0x00) return ICQ_STATUS_ONLINE;
- else return (ICQ_STATUS_OFFLINE - 1);
+ else if (m_nStatus & ICQ_STATUS_XTRAZ) return ICQ_STATUS_XTRAZ;
+ else return (ICQ_STATUS_OFFLINE - 1);
}
void ICQUser::SetStatusOffline()
@@ -2752,6 +2753,7 @@
else if (n & ICQ_STATUS_NA) return b ? tr("(Not Available)") : tr("Not Available");
else if (n & ICQ_STATUS_AWAY) return b ? tr("(Away)") : tr("Away");
else if (n & ICQ_STATUS_FREEFORCHAT) return b ? tr("(Free for Chat)") : tr("Free for Chat");
+ else if (n & ICQ_STATUS_XTRAZ) return b ? tr("(Xstatus)") : tr("Xstatus");
else if (n << 24 == 0x00) return b ? tr("(Online)") : tr("Online");
else return "Unknown";
}
@@ -2765,6 +2767,7 @@
else if (n & ICQ_STATUS_NA) return b ? tr("(N/A)") : tr("N/A");
else if (n & ICQ_STATUS_AWAY) return b ? tr("(Away)") : tr("Away");
else if (n & ICQ_STATUS_FREEFORCHAT) return b ? tr("(FFC)") : tr("FFC");
+ else if (n & ICQ_STATUS_XTRAZ) return b ? tr("(Xtra)") : tr("Xtra");
else if (n << 24 == 0x00) return b ? tr("(On)") : tr("On");
else return "???";
}
Index: licq_packets.h
===================================================================
--- include/licq_packets.h svn rev. 5000
+++ include/licq_packets.h 2007-07-11 19:19:10.000000000 -0300
@@ -744,12 +744,36 @@
unsigned long nID2 = 0);
protected:
void InitBuffer();
+ void CPU_ReqXtrazMessage(ICQUser *u, unsigned short _nMsgType,
+ unsigned short _nMsgFlags, bool _bAck,
+ unsigned short _nSequence,
+ unsigned long nID1 = 0,
+ unsigned long nID2 = 0);
unsigned short m_nMsgType;
unsigned short m_nMsgFlags;
unsigned short m_nSequence;
};
+//-----AdvancedMessage---------------------------------------------------------
+/*class CPU_ReqXtrazMessage : public CPU_Type2Message
+{
+public:
+ CPU_ReqXtrazMessage(ICQUser *u, unsigned short _nMsgType,
+ unsigned short _nMsgFlags, bool _bAck,
+ unsigned short _nSequence,
+ unsigned long nID1 = 0,
+ unsigned long nID2 = 0);
+protected:
+ void InitBuffer();
+
+ unsigned short m_nMsgType;
+ unsigned short m_nMsgFlags;
+ unsigned short m_nSequence;
+};*/
+
+
+
//-----ChatRequest-------------------------------------------------------------
class CPU_ChatRequest : public CPU_AdvancedMessage
{
Index: licq_icq.h
===================================================================
--- include/licq_icq.h svn rev. 5000
+++ include/licq_icq.h 2007-07-11 19:19:10.000000000 -0300
@@ -7,8 +7,8 @@
#define MODE_INDIRECT 0x02
#define MODE_DENIED 0x01 // user denies direct connection from "any" user
-#define ICQ_VERSION 8
-const unsigned short ICQ_VERSION_TCP = 0x0008;
+#define ICQ_VERSION 9
+const unsigned short ICQ_VERSION_TCP = 0x0009;
#define LICQ_WITHSSL 0x7D800000
#define LICQ_WITHOUTSSL 0x7D000000
@@ -323,6 +323,8 @@
const unsigned short ICQ_CMDxTCP_READxDNDxMSG = 0x03EB;
const unsigned short ICQ_CMDxTCP_READxFFCxMSG = 0x03EC;
const unsigned char ICQ_CMDxTCP_HANDSHAKE = 0xFF;
+const unsigned short ICQ_CMDxTCP_READxXSTATUSxMSG = 0x001A;
+
// Sub Commands
const unsigned short ICQ_CMDxSUB_MSG = 0x0001;
@@ -376,6 +378,7 @@
const unsigned short ICQ_STATUS_NA = 0x0004;
const unsigned short ICQ_STATUS_OCCUPIED = 0x0010;
const unsigned short ICQ_STATUS_FREEFORCHAT = 0x0020;
+const unsigned short ICQ_STATUS_XTRAZ = 0x0008; // Not a real status
// TCP status for ack packets
const unsigned short ICQ_TCPxACK_ONLINE = 0x0000;
@@ -598,6 +601,40 @@
{ 0xDD, 0xCF, 0x0E, 0xA9, 0x71, 0x95, 0x40, 0x48, 0xA9, 0xC6, 0x41, 0x32, 0x06, 0xD6, 0xF2, 0x80 }
};
+const char XtraAwayNames[XTRA_AWAY_COUNT][0x20] = {
+ "Angry",
+ "Taking a bath",
+ "Tired",
+ "Party",
+ "Drinking beer",
+ "Thinking",
+ "Eating",
+ "Watching TV",
+ "Meeting",
+ "Coffee",
+ "Listening to music",
+ "Business",
+ "Shooting",
+ "Having fun",
+ "On the phone",
+ "Gaming",
+ "Studying",
+ "Shopping",
+ "Feeling sick",
+ "Sleeping",
+ "Surfing",
+ "Browsing",
+ "Working",
+ "Typing",
+ "Picnic",
+ "Cooking",
+ "Smoking",
+ "I'm high",
+ "On WC",
+ "To be or not to be",
+ "Watching pro7 on TV",
+ "Love"
+};
// For protocol plugins