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,"&lt;desc&gt;"))!= NULL) { // Xstatus
+				temp=strstr(szMessage,"&lt;/desc&gt;");
+				temp[0]=0;
+				desc=desc+12;
+				if ((title=strstr(szMessage,"&lt;title&gt;"))!= NULL) {
+					temp=strstr(szMessage,"&lt;/title&gt;");
+					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>&lt;Q&gt;&lt;PluginID&gt;srvMng&lt;/PluginID&gt;&lt;/Q&gt;</QUERY><NOTIFY>&lt;srv&gt;&lt;id&gt;cAwaySrv&lt;/id&gt;&lt;req&gt;&lt;id&gt;AwayStat&lt;/id&gt;&lt;trans&gt;2&lt;/trans&gt;&lt;senderId&gt;%s&lt;/senderId&gt;&lt;/req&gt;&lt;/srv&gt;</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

Reply via email to