コード例 #1
0
ファイル: SNAC13.cs プロジェクト: pkt30/OscarLib
        /// <summary>
        /// Processes a "You Were Added" notification sent by the server -- SNAC(13,1C)
        /// </summary>
        /// <param name="dp">A <see cref="DataPacket"/> object with a buffer containing SNAC(13,1C)</param>
        /// <remarks>
        /// The server only sends this SNAC to ICQ clients, so the packet is passed to to the
        /// <see cref="IcqManager"/> for dealing-with
        /// </remarks>
        public static void ProcessAddedMessage(DataPacket dp)
        {
            int length = dp.Data.ReadByte();
            String uin = dp.Data.ReadString(length, Encoding.ASCII);

            dp.ParentSession.OnAddedToRemoteList(uin);
        }
コード例 #2
0
ファイル: SNAC08.cs プロジェクト: pkt30/OscarLib
        /// <summary>
        /// Processes a popup message sent by the server -- SNAC(08,02)
        /// </summary>
        /// <param name="dp">A <see cref="DataPacket"/> object with a buffer containing SNAC(08,02)</param>
        public static void ProcessPopupMessage(DataPacket dp)
        {
            TlvBlock tlvs = new TlvBlock(dp.Data.ReadByteArrayToEnd());
            string message = tlvs.ReadString(0x0001, Encoding.ASCII);
            string url = tlvs.ReadString(0x0002, Encoding.ASCII);
            ushort width = tlvs.ReadUshort(0x0003);
            ushort height = tlvs.ReadUshort(0x0004);
            ushort delay = tlvs.ReadUshort(0x0005);

            dp.ParentSession.OnPopupMessage(width, height, delay, url, message);
        }
コード例 #3
0
ファイル: SNACFunctions.cs プロジェクト: pkt30/OscarLib
        /// <summary>
        /// Enqueues a SNAC for transmission with the appropriate RateClass
        /// </summary>
        /// <param name="dp">A <see cref="DataPacket"/> object</param>
        /// <remarks>
        /// <para>
        /// This needs commenting
        /// </para>
        /// </remarks>
        public static void BuildFLAP(DataPacket dp)
        {
            // Build the FLAP header
            dp.FLAP.DatagramSequenceNumber = 0; // Gets bound in Connection.cs
            dp.FLAP.Channel = (byte) FLAPChannels.SNACData;

            // Build the size of the data to be sent, not counting the FLAP header
            dp.FLAP.DataSize = (ushort) (10 + dp.Data.GetByteCount());
            dp.Data.PrependOscarHeaders(dp.FLAP, dp.SNAC);
            SNACFunctions.DispatchToRateClass(dp);
        }
コード例 #4
0
ファイル: ProcessQueue.cs プロジェクト: pkt30/OscarLib
 /// <summary>
 /// Enqueues a data packet to be processed by SNAC handling functions
 /// </summary>
 /// <param name="dp">A <see cref="DataPacket"/> object</param>
 public void Enqueue(DataPacket dp)
 {
     lock (this)
     {
         processQueue.Enqueue(dp);
         if (!hasTimerBeenSet)
         {
             SetDispatchTimer();
         }
     }
 }
コード例 #5
0
ファイル: SNAC0F.cs プロジェクト: pkt30/OscarLib
        /// <summary>
        /// Processes a list of known interests from the server -- SNAC(0F,05)
        /// </summary>
        /// <param name="dp">A <see cref="DataPacket"/> object with a buffer containing SNAC(0F,05)</param>
        /// <remarks>
        /// libfaim doesn't implement the interest list fetching, so this one's thanks to Mark Doliner's
        /// ([email protected]) documentation.
        /// </remarks>
        public static void ProcessInterestList(DataPacket dp)
        {
            dp.Data.ReadUshort(); // First two bytes: 0x0001
            ushort num_items = dp.Data.ReadUshort();
            InterestItem[] interests = new InterestItem[num_items];
            for (int i = 0; i < num_items; i++)
            {
                interests[i] = dp.Data.ReadInterestItem();
            }

            dp.ParentSession.OnInterestsReceived(interests);
        }
コード例 #6
0
        /// <summary>
        /// Process an incoming <see cref="DataPacket"/> from SNAC family 0x0017
        /// </summary>
        /// <param name="dp">A <see cref="DataPacket"/> received by the server</param>
        public void ProcessIncomingPacket(csammisrun.OscarLib.Utility.DataPacket dp)
        {
            switch (dp.SNAC.FamilySubtypeID)
            {
            case AUTH_KEY_RESPONSE:
                SendAuthorizationRequest(dp);
                break;

            case AUTH_LOGIN_RESPONSE:
                ProcessLoginResponse(dp);
                break;
            }
        }
コード例 #7
0
ファイル: SNAC0A.cs プロジェクト: pkt30/OscarLib
        /// <summary>
        /// Processes the results of a search-by-email request -- SNAC(0A,03)
        /// </summary>
        /// <param name="dp">A <see cref="DataPacket"/> object with a buffer containing SNAC(0A,03)</param>
        public static void ProcessSearchResults(DataPacket dp)
        {
            string email = (string) dp.ParentSession.RetrieveRequestID(dp.SNAC.RequestID);
            List<string> accts = new List<string>();

            while (dp.Data.HasMoreData)
            {
                ushort key = dp.Data.ReadUshort();
                accts.Add(dp.Data.ReadString(dp.Data.ReadUshort(), Encoding.ASCII));
            }

            dp.ParentSession.OnSearchByEmailResults(email, accts.ToArray());
        }
コード例 #8
0
ファイル: PacketDispatcher.cs プロジェクト: pkt30/OscarLib
 /// <summary>
 /// Dispatches a newly received <see cref="DataPacket"/> according to its SNAC family
 /// </summary>
 /// <param name="dp">The packet to dispatch</param>
 /// <returns><c>true</c> if the packet was handled, <c>false</c> if no handlers were registered for its SNAC family</returns>
 public bool DispatchPacket(DataPacket dp)
 {
     bool handled = false;
     if (handlers.ContainsKey(dp.SNAC.FamilyServiceID))
     {
         if (handlers[dp.SNAC.FamilyServiceID] != null)
         {
             handlers[dp.SNAC.FamilyServiceID].ProcessIncomingPacket(dp);
             handled = true;
         }
     }
     return handled;
 }
コード例 #9
0
ファイル: SNACFunctions.cs プロジェクト: pkt30/OscarLib
 /// <summary>
 /// Reads the error code and subcode from a SNAC(XX,01) packet
 /// </summary>
 /// <param name="dp">A <see cref="DataPacket"/> object containing SNAC(XX,01)</param>
 /// <param name="errorCode">The main error code contained in the SNAC</param>
 /// <param name="subCode">The subcode contained in the SNAC, or 0 if there is no subcode present</param>
 public static void GetSNACErrorCodes(DataPacket dp, out ushort errorCode, out ushort subCode)
 {
     errorCode = dp.Data.ReadUshort();
     subCode = 0;
     if (dp.Data.HasMoreData)
     {
         using (TlvBlock tlvs = dp.Data.ReadTlvBlockByLength(dp.Data.GetRemainingByteCount()))
         {
             if (tlvs.HasTlv(0x0008))
             {
                 subCode = tlvs.ReadUshort(0x0008);
             }
         }
     }
 }
コード例 #10
0
ファイル: SNAC01.cs プロジェクト: pkt30/OscarLib
        /// <summary>
        /// Sends an acknowledgement of the server's rate limitations -- SNAC(01,08)
        /// </summary>
        /// <param name="dp">A <see cref="DataPacket"/> object</param>
        /// <param name="classes">The known rate classes to acknowledge</param>
        public static void AcknowledgeRateLimitations(DataPacket dp, ushort[] classes)
        {
            Session sess = dp.ParentSession;

            SNACHeader sh = new SNACHeader();
            sh.FamilyServiceID = (ushort)SNACFamily.BasicOscarService;
            sh.FamilySubtypeID = (ushort)GenericServiceControls.AcknowledgeRateLimits;
            sh.Flags = 0x0000;
            sh.RequestID = Session.GetNextRequestID();

            ByteStream stream = new ByteStream();
            for (int i = 0; i < classes.Length; i++)
            {
                stream.WriteUshort(classes[i]);
            }

            DataPacket dp2 = Marshal.BuildDataPacket(sess, sh, stream);
            dp2.ParentConnection = dp.ParentConnection;
            SNACFunctions.BuildFLAP(dp2);

            sess.OnLoginStatusUpdate("Protocol negotiation complete", 0.66);

            /*
             * If this is the initial services connection, we call the remaining SNACs
             * in the login sequence.
             * Otherwise, this is the last step in setting up a new service connection,
             * and we send SNAC(01,02) here.
             */
            if (!sess.LoggedIn)
            {
                // Start stage 3, services setup
                RequestOwnInformation(sess);
                SNAC13.RequestParametersList(sess);
                SNAC13.RequestInitialContactList(sess);
                sess.Statuses.RequestParameters();
                sess.Messages.RequestParametersList();
                SNAC09.RequestParametersList(sess);
                sess.Statuses.ReportClientCapabilities();
                sess.Statuses.SetProfile(sess.Statuses.Profile);
            }
            else
            {
                SendReadyNotification(dp);
            }
        }
コード例 #11
0
ファイル: SearchManager.cs プロジェクト: saroj82/OscarLib
 /// <summary>
 /// Process an incoming <see cref="DataPacket"/> from SNAC family 0x000A or 0x000F
 /// </summary>
 /// <param name="dp">A <see cref="DataPacket"/> received by the server</param>
 public void ProcessIncomingPacket(csammisrun.OscarLib.Utility.DataPacket dp)
 {
     if (dp.SNAC.FamilyServiceID == SNAC_USERLOOKUP_FAMILY)
     {
         switch (dp.SNAC.FamilySubtypeID)
         {
         case USERLOOKUP_EMAIL_RESULTS:
             ProcessEmailSearchResults(dp);
             break;
         }
     }
     else if (dp.SNAC.FamilyServiceID == SNAC_DIRECTORY_FAMILY)
     {
         switch (dp.SNAC.FamilySubtypeID)
         {
         }
     }
 }
コード例 #12
0
ファイル: UsageStatsService.cs プロジェクト: saroj82/OscarLib
        public void ProcessIncomingPacket(Utility.DataPacket dp)
        {
            switch ((UsageStatsService)dp.SNAC.FamilySubtypeID)
            {
            case UsageStatsService.ClientServerError:
                SNACFunctions.ProcessErrorNotification(dp);
                break;

            case UsageStatsService.SetMinimumInterval:
                ProcessReportInterval(dp);
                break;

            case UsageStatsService.UsageReportAck:
                ProcessReportAck(dp);
                break;

            default:
                break;
            }
        }
コード例 #13
0
ファイル: SNAC17.cs プロジェクト: pkt30/OscarLib
        /// <summary>
        /// Processes a login response -- SNAC(17,03)
        /// </summary>
        /// <param name="dp">A <see cref="DataPacket"/> object containing SNAC(17,03)</param>
        public static void ProcessLoginResponse(DataPacket dp)
        {
            // Pull apart SNAC(17,03)
            Cookie cookie;
            string BOSaddress;

            using (TlvBlock tlvs = new TlvBlock(dp.Data.ReadByteArrayToEnd()))
            {
                if (tlvs.HasTlv(0x0008))
                {
                    ushort errorcode = tlvs.ReadUshort(0x0008);
                    dp.ParentSession.OnLoginFailed((LoginErrorCode)errorcode);
                    return;
                }

                BOSaddress = tlvs.ReadString(0x0005, Encoding.ASCII);
                cookie = Cookie.GetReceivedCookie(tlvs.ReadByteArray(0x0006));
            }

            // Shut down the authorization connection
            // Socket shutdown is initiated by the server
            dp.ParentSession.OnLoginStatusUpdate("Authorized", 0.33);
            dp.ParentConnection.DisconnectFromServer(false);

            // Create a new connection to the BOS server
            Connection newconn = dp.ParentSession.Connections.CreateNewConnection(0x0001);

            string[] bosinfo = BOSaddress.Split(':');

            newconn.ServerConnectionCompleted +=
                new ServerConnectionCompletedHandler(newconn_ServerConnnectionCompleted);
            newconn.Server = bosinfo[0];
            newconn.Port = Int32.Parse(bosinfo[1]);
            newconn.Cookie = cookie;
            newconn.ConnectToServer();

            // The connection process continues when the server sends SNAC(01,03)
        }
コード例 #14
0
ファイル: SNAC17.cs プロジェクト: pkt30/OscarLib
        /// <summary>
        /// Sends authorization request -- SNAC(17,02)
        /// </summary>
        /// <param name="dp">A <see cref="DataPacket"/> object containing SNAC(17,07)</param>
        public static void SendAuthorizationRequest(DataPacket dp)
        {
            // Pull apart SNAC(17,07)
            byte[] key = dp.Data.ReadByteArray(dp.Data.ReadUshort());

            // Construct SNAC(17,02)
            SNACHeader header = new SNACHeader();
            header.FamilyServiceID = (ushort) SNACFamily.AuthorizationRegistrationService;
            header.FamilySubtypeID = (ushort) AuthorizationRegistrationService.LoginRequest;
            header.Flags = 0;
            header.RequestID = Session.GetNextRequestID();

            OSCARIdentification id = dp.ParentSession.ClientIdentification;

            ByteStream stream = new ByteStream();
            using (TlvBlock tlvs = new TlvBlock())
            {
                tlvs.WriteString(0x0001, dp.ParentSession.ScreenName, Encoding.ASCII);
                tlvs.WriteString(0x0003, id.ClientName, Encoding.ASCII);
                tlvs.WriteString(0x000F, "en", Encoding.ASCII);
                tlvs.WriteString(0x000E, "us", Encoding.ASCII);
                tlvs.WriteUint(0x0014, id.ClientDistribution);
                tlvs.WriteUshort(0x0016, id.ClientId);
                tlvs.WriteUshort(0x0017, id.ClientMajor);
                tlvs.WriteUshort(0x0018, id.ClientMinor);
                tlvs.WriteUshort(0x0019, id.ClientLesser);
                tlvs.WriteUshort(0x001A, id.ClientBuild);
                tlvs.WriteByteArray(0x0025, dp.ParentSession.HashPassword(key));
                tlvs.WriteByte(0x004A, 0x01);
                tlvs.WriteEmpty(0x004C);
                stream.WriteTlvBlock(tlvs);
            }

            DataPacket newPacket = Marshal.BuildDataPacket(dp.ParentSession, header, stream);
            newPacket.ParentConnection = dp.ParentConnection;
            SNACFunctions.BuildFLAP(newPacket);
        }
コード例 #15
0
ファイル: SNACFunctions.cs プロジェクト: pkt30/OscarLib
        /// <summary>
        /// Send a data packet to the rate class that will send it
        /// </summary>
        /// <param name="dp">A <see cref="DataPacket"/> object</param>
        public static void DispatchToRateClass(DataPacket dp)
        {
            if (dp.ParentConnection == null)
            {
                dp.ParentConnection = dp.ParentSession.Connections.GetByFamily(
                    dp.SNAC.FamilyServiceID);
                if (dp.ParentConnection == null || dp.ParentConnection.ReadyForData == false)
                {
                    dp.ParentSession.Connections.AddDelayedPacket(dp.SNAC.FamilyServiceID, dp);
                    return;
                }
            }

            int key = (int) (dp.SNAC.FamilyServiceID << 16) | dp.SNAC.FamilySubtypeID;
            RateClass rc = dp.ParentSession.RateClasses[key];
            if (rc != null)
            {
                rc.Enqueue(dp);
            }
            else
            {
                dp.ParentConnection.SendFLAP(dp.Data.GetBytes());
            }
        }
コード例 #16
0
ファイル: ServiceManager.cs プロジェクト: pkt30/OscarLib
        /// <summary>
        /// Sends SNAC(01,06) in response to SNAC(01,18)
        /// </summary>
        /// <param name="dp">A <see cref="DataPacket"/> object with a buffer containing SNAC(01,18)</param>
        /// <remarks>OscarLib doesn't store the version list, so this method just sends SNAC(01,06) for rate limit info</remarks>
        private void ProcessVersionsListAndGetRateLimits(DataPacket dp)
        {
            // Construct SNAC (01,06)
            SNACHeader sh = new SNACHeader();
            sh.FamilyServiceID = SNAC_BOS_FAMILY;
            sh.FamilySubtypeID = BOS_RATE_LIMIT_REQUST;

            DataPacket dp2 = Marshal.BuildDataPacket(parent, sh, new ByteStream());
            dp2.ParentConnection = dp.ParentConnection;
            SNACFunctions.BuildFLAP(dp2);
        }
コード例 #17
0
ファイル: ServiceManager.cs プロジェクト: pkt30/OscarLib
 /// <summary>
 /// Processes a request for client verification -- SNAC(01,1F)
 /// </summary>
 /// <param name="dp">A <see cref="DataPacket"/> object with a buffer containing SNAC(01,1F)</param>
 /// <remarks>See the entry for <see cref="SendVerificationResponse"/> for a description of
 /// how this SNAC is used.</remarks>
 private void ProcessVerificationRequest(DataPacket dp)
 {
     SendVerificationResponse();
 }
コード例 #18
0
ファイル: ServiceManager.cs プロジェクト: pkt30/OscarLib
        /// <summary>
        /// Processes the server-supported family list -- SNAC(01,03)
        /// </summary>
        /// <param name="dp">A <see cref="DataPacket"/> object containing SNAC(01,03)</param>
        private void ProcessServicesList(DataPacket dp)
        {
            // Get the list of supported families and populate the session list
            while (dp.Data.HasMoreData)
            {
                ushort family = dp.Data.ReadUshort();
                // Add family to connection list, unless it is 0x0001, because all
                // connections (except authorization) handle this family
                if (family != SNAC_BOS_FAMILY)
                {
                    parent.Connections.AssignFamily(family, dp.ParentConnection);
                }
            }

            // Request the server versions of these services
            RequestServiceVersions(dp.ParentConnection);
        }
コード例 #19
0
ファイル: ServiceManager.cs プロジェクト: pkt30/OscarLib
 /// <summary>
 /// Processes a resume request from the server -- SNAC(01,0D)
 /// </summary>
 /// <param name="dp">A <see cref="DataPacket"/> object with a buffer containing SNAC(01,0D)</param>
 private void ProcessResumeRequest(DataPacket dp)
 {
     // TODO: Tell the connection it can start sending again
 }
コード例 #20
0
ファイル: ServiceManager.cs プロジェクト: pkt30/OscarLib
        /// <summary>
        /// Processes the list of rate limitations -- SNAC(01,07)
        /// </summary>
        /// <param name="dp">A <see cref="DataPacket"/> object containing SNAC(01,07)</param>
        /// <remarks>This is the last step in setting up a secondary service connection,
        /// and the trigger to initialize basic services for the primary connection.</remarks>
        private void ProcessRateLimitations(DataPacket dp)
        {
            ushort num_classes = dp.Data.ReadUshort();
            ushort[] classes = new ushort[num_classes];

            RateClassManager rcm = parent.RateClasses;

            // Get the rate class attributes out of the SNAC
            for (int i = 0; i < num_classes; i++)
            {
                ushort id = dp.Data.ReadUshort();
                RateClass rc = rcm.GetByID(id);
                rc.WindowSize = dp.Data.ReadUint();
                rc.ClearLevel = dp.Data.ReadUint();
                rc.AlertLevel = dp.Data.ReadUint();
                rc.LimitLevel = dp.Data.ReadUint();
                rc.DisconnectLevel = dp.Data.ReadUint();
                rc.CurrentLevel = dp.Data.ReadUint();
                rc.MaxLevel = dp.Data.ReadUint();
                if (parent.Families.GetFamilyVersion(0x0001) >= 3)
                {
                    rc.LastTime = dp.Data.ReadUint();
                    rc.IsDroppingSNACs = dp.Data.ReadByte() != 0;
                }
                rcm.SetByID(id, rc);
                rc.StartLimitedTransmission();

                classes[i] = id;
            }

            // Register rates with the session's ConnectionList
            for (int i = 0; i < num_classes; i++)
            {
                ushort id = dp.Data.ReadUshort();
                ushort num_pairs = dp.Data.ReadUshort();

                for (int j = 0; j < num_pairs; j++)
                {
                    ushort family = dp.Data.ReadUshort();
                    ushort subtype = dp.Data.ReadUshort();
                    if (family == 0x04)
                    {
                        if (id == 1)
                        {
                            Console.WriteLine("** SNAC 4 handled by RC " + id);
                        }
                        else
                        {
                            Console.WriteLine("SNAC 4-{0} handled by RC " + id, subtype);
                        }
                    }
                    else if (family == 0x02 && subtype == 0x05)
                    {
                        Console.WriteLine("** 02,05 handled by RC " + id);
                    }
                    rcm.SetRateClassKey(family, subtype, id);
                }
            }

            // Construct SNAC(01,08)
            SNACHeader sh = new SNACHeader();
            sh.FamilyServiceID = SNAC_BOS_FAMILY;
            sh.FamilySubtypeID = BOS_ACKNOWLEDGE_RATE_LIMITS;

            ByteStream stream = new ByteStream();
            for (int i = 0; i < classes.Length; i++)
            {
                stream.WriteUshort(classes[i]);
            }

            DataPacket dp2 = Marshal.BuildDataPacket(parent, sh, stream);
            dp2.ParentConnection = dp.ParentConnection;
            SNACFunctions.BuildFLAP(dp2);

            parent.OnLoginStatusUpdate("Protocol negotiation complete", 0.66);

            /*
             * If this is the initial services connection, we call the remaining SNACs
             * in the login sequence.
             * Otherwise, this is the last step in setting up a new service connection,
             * and we send SNAC(01,02) here.
             */
            if (!parent.LoggedIn)
            {
                // Start stage 3, services setup
                RequestOnlineInformation();
                SNAC13.RequestParametersList(parent);
                SNAC13.RequestInitialContactList(parent);
                parent.Statuses.RequestParameters();
                parent.Messages.RequestParametersList();
                SNAC09.RequestParametersList(parent);
                parent.Statuses.ReportClientCapabilities();
                parent.Statuses.SetProfile(parent.Statuses.Profile);
            }
            else
            {
                SendReadyNotification(dp.ParentConnection);
            }
        }
コード例 #21
0
ファイル: ServiceManager.cs プロジェクト: pkt30/OscarLib
        /// <summary>
        /// Process a rate change message from the server -- SNAC(01,0A)
        /// </summary>
        /// <param name="dp">A <see cref="DataPacket"/> object with a buffer containing SNAC(01,0A)</param>
        private void ProcessRateChange(DataPacket dp)
        {
            ushort rateCode = dp.Data.ReadUshort();
            while (dp.Data.HasMoreData)
            {
                ushort classID = dp.Data.ReadUshort();

                RateClass targetClass = parent.RateClasses.GetByID(classID);
                switch (rateCode)
                {
                    case 1:
                        break;
                    case 2:
                        targetClass.State = RateClassState.Warning;
                        break;
                    case 3:
                        targetClass.State = RateClassState.Limited;
                        break;
                    case 4:
                        targetClass.State = RateClassState.Normal;
                        break;
                }
                targetClass.WindowSize = dp.Data.ReadUint();
                targetClass.ClearLevel = dp.Data.ReadUint();
                targetClass.AlertLevel = dp.Data.ReadUint();
                targetClass.LimitLevel = dp.Data.ReadUint();
                targetClass.DisconnectLevel = dp.Data.ReadUint();
                targetClass.CurrentLevel = dp.Data.ReadUint();
                targetClass.MaxLevel = dp.Data.ReadUint();
                targetClass.LastTime = dp.Data.ReadUint();
                targetClass.IsDroppingSNACs = dp.Data.ReadByte() != 0;
                parent.RateClasses.SetByID(classID, targetClass);
            }
        }
コード例 #22
0
ファイル: UsageStatsService.cs プロジェクト: pkt30/OscarLib
 /// <summary>
 /// Set minimum report interval -- SNAC(0b,02)
 /// </summary>
 /// <param name="dp">A <see cref="DataPacket"/> object with a buffer containing SNAC(0b,02)</param>
 private void ProcessReportInterval(DataPacket dp)
 {
     // read report interval in hours
     ushort n = dp.Data.ReadUshort();
     if (n > 0) statsIntervalMins = (ulong)(n * 60);
 }
コード例 #23
0
ファイル: ServiceManager.cs プロジェクト: pkt30/OscarLib
 /// <summary>
 /// Processes the client's own online information -- SNAC(01,0F)
 /// </summary>
 /// <param name="dp">A <see cref="DataPacket"/> object with a buffer containing SNAC(01,0F)</param>
 private void ProcessOwnInformation(DataPacket dp)
 {
     UserInfo ui = dp.Data.ReadUserInfo();
     if (ui.Icon != null)
     {
         parent.Graphics.OwnBuddyIcon = ui.Icon;
     }
     IPAddress ipAddress = null;
     if (parent.Connections.LocalExternalIP == null)
         if (IPAddress.TryParse(ui.ExternalIPAddress.ToString(), out ipAddress))
             parent.Connections.LocalExternalIP = ipAddress;
 }
コード例 #24
0
ファイル: ServiceManager.cs プロジェクト: pkt30/OscarLib
        /// <summary>
        /// Processes the server response to a new family request -- SNAC(01,05)
        /// </summary>
        /// <param name="dp">A <see cref="DataPacket"/> object containing SNAC(01,05)</param>
        private void ProcessNewServiceResponse(DataPacket dp)
        {
            int startIndex = 0;
            byte[] SNACData = dp.Data.ReadByteArrayToEnd();
            if (SNACData[0] == 0x00 && SNACData[1] == 0x06)
            {
                startIndex += 2; // What the heck is this...0x0006, some families, some of the time?
            }

            using (TlvBlock tlvs = new TlvBlock(SNACData, startIndex))
            {
                ushort family = tlvs.ReadUshort(NEW_SERVICE_FAMILY);
                string BOSaddress = tlvs.ReadString(NEW_SERVICE_ADDRESS, Encoding.ASCII);
                byte[] cookie = tlvs.ReadByteArray(NEW_SERVICE_COOKIE);

                Connection newconn = null;
                object store = dp.ParentSession.RetrieveRequestID(dp.SNAC.RequestID);

                if (family != 0x000E)
                {
                    newconn = dp.ParentSession.Connections.CreateNewConnection(family);
                }
                else
                {
                    ChatRoom roominfo = (ChatRoom)store;
                    newconn = dp.ParentSession.Connections.CreateNewChatConnection(roominfo);
                }

                string[] bosinfo = BOSaddress.Split(':');
                int port = 0;
                if (bosinfo.Length == 2)
                {
                    port = Int32.Parse(bosinfo[1]);
                }
                else
                {
                    port = dp.ParentSession.ServerSettings.LoginPort;
                }

                newconn.ServerConnectionCompleted += delegate { newconn.ReadHeader(); };
                newconn.Server = bosinfo[0];
                newconn.Port = port;
                newconn.Cookie = new Cookie(cookie);
                newconn.ConnectToServer();
            }

            // The connection process continues when the server sends SNAC(01,03)
        }
コード例 #25
0
ファイル: ServiceManager.cs プロジェクト: pkt30/OscarLib
        /// <summary>
        /// Processes a server migration notification -- SNAC(01,12)
        /// </summary>
        /// <param name="dp">A <see cref="DataPacket"/> object with a buffer containing SNAC(01,12)</param>
        private void ProcessMigrationNotice(DataPacket dp)
        {
            //KSD-SYSTEMS - changed at 26.05.2011
            // Process migration
            //dp.ParentSession.OnError(ServerErrorCode.OscarLibUnsupportedFunction);

            dp.ParentSession.OnStatusUpdate("Server-Address changed");

            dp.ParentSession.OnLoginStatusUpdate("Connecting to server", 0.00);
            parent.Authorization.ProcessLoginResponse(dp);
        }
コード例 #26
0
        /// <summary>
        /// Sends authorization request -- SNAC(17,02)
        /// </summary>
        /// <param name="dp">A <see cref="DataPacket"/> object containing SNAC(17,07)</param>
        void SendAuthorizationRequest(DataPacket dp)
        {
            // Pull apart SNAC(17,07)
            byte[] key = dp.Data.ReadByteArray(dp.Data.ReadUshort());

            // Construct SNAC(17,02)
            SNACHeader header = new SNACHeader();
            header.FamilyServiceID = SNAC_AUTH_FAMILY;
            header.FamilySubtypeID = AUTH_LOGIN_REQUEST;

            OSCARIdentification id = parent.ClientIdentification;

            ByteStream stream = new ByteStream();
            using (TlvBlock tlvs = new TlvBlock())
            {
                tlvs.WriteString(0x0001, parent.ScreenName, Encoding.ASCII);
                tlvs.WriteString(0x0003, id.ClientName, Encoding.ASCII);
                tlvs.WriteString(0x000F, "en", Encoding.ASCII);
                tlvs.WriteString(0x000E, "us", Encoding.ASCII);
                tlvs.WriteUint(0x0014, id.ClientDistribution);
                tlvs.WriteUshort(0x0016, id.ClientId);
                tlvs.WriteUshort(0x0017, id.ClientMajor);
                tlvs.WriteUshort(0x0018, id.ClientMinor);
                tlvs.WriteUshort(0x0019, id.ClientLesser);
                tlvs.WriteUshort(0x001A, id.ClientBuild);
                tlvs.WriteByteArray(0x0025, parent.HashPassword(key));
                tlvs.WriteByte(0x004A, 0x01);
                tlvs.WriteEmpty(0x004C);
                stream.WriteTlvBlock(tlvs);
            }

            DataPacket newPacket = Marshal.BuildDataPacket(parent, header, stream);
            newPacket.ParentConnection = dp.ParentConnection;
            SNACFunctions.BuildFLAP(newPacket);
        }
コード例 #27
0
ファイル: RateClass.cs プロジェクト: pkt30/OscarLib
 /// <summary>
 /// Enqueues a DataPacket to be sent asynchronously
 /// </summary>
 public void Enqueue(DataPacket dp)
 {
     lock (this)
     {
         _sendqueue.Enqueue(dp);
     }
 }
コード例 #28
0
ファイル: ByteStream.cs プロジェクト: pkt30/OscarLib
        /// <summary>
        /// Creates a <see cref="DataPacket"/> from the beginning of the stream
        /// </summary>
        /// <returns>A new <see cref="DataPacket"/></returns>
        public DataPacket CreateDataPacket()
        {
            if (dataIndex != 0)
            {
                throw new Exception("A DataPacket can only be created from an unused ByteStream");
            }

            SNACHeader header = new SNACHeader(this);

            if ((header.Flags & 0x8000) != 0)
            {
                dataIndex += 2 + ReadUshort(); // Read past family version information
            }

            DataPacket retval = new DataPacket(this);
            retval.SNAC = header;
            return retval;
        }
コード例 #29
0
ファイル: ServiceManager.cs プロジェクト: pkt30/OscarLib
        /// <summary>
        /// Processes a pause request from the server -- SNAC(01,0B)
        /// </summary>
        /// <param name="dp">A <see cref="DataPacket"/> object with a buffer containing SNAC(01,0B)</param>
        private void ProcessPauseRequest(DataPacket dp)
        {
            // TODO:  Actually tell the connection to stop sending in preparation for the migration
            SNACHeader sh = new SNACHeader();
            sh.FamilyServiceID = SNAC_BOS_FAMILY;
            sh.FamilySubtypeID = BOS_PAUSE_CONNECTION_RESPONSE;

            DataPacket dp2 = Marshal.BuildDataPacket(parent, sh, new ByteStream());
            dp2.ParentConnection = dp.ParentConnection;
            SNACFunctions.BuildFLAP(dp2);
        }
コード例 #30
0
        /// <summary>
        /// Processes a login response -- SNAC(17,03)
        /// </summary>
        /// <param name="dp">A <see cref="DataPacket"/> object containing SNAC(17,03)</param>
        internal void ProcessLoginResponse(DataPacket dp)
        {
            // Pull apart SNAC(17,03)
            Cookie cookie;
            string BOSaddress;

            using (TlvBlock tlvs = new TlvBlock(dp.Data.ReadByteArrayToEnd()))
            {
                if (tlvs.HasTlv(0x0008))
                {
                    ushort errorcode = tlvs.ReadUshort(0x0008);
                    parent.OnLoginFailed((LoginErrorCode)errorcode);
                    return;
                }

                BOSaddress = tlvs.ReadString(0x0005, Encoding.ASCII);
                cookie = Cookie.GetReceivedCookie(tlvs.ReadByteArray(0x0006));
            }

            // Shut down the authorization connection
            // Socket shutdown is initiated by the server
            parent.OnLoginStatusUpdate("Authorized", 0.33);
            dp.ParentConnection.DisconnectFromServer(false);

            // Create a new connection to the BOS server
            Connection newconn = parent.Connections.CreateNewConnection(0x0001);

            string[] bosinfo = BOSaddress.Split(':');

            newconn.ServerConnectionCompleted += delegate(Connection conn) { conn.ReadyForData = true; conn.ReadHeader(); };
            newconn.Server = bosinfo[0];
            if (bosinfo.Length == 2)
                newconn.Port = Int32.Parse(bosinfo[1]);
            else
                newconn.Port = dp.ParentConnection.Port;

            Logging.WriteString("Connect to Server after auth. Address from dp: {0} - Address to connect: {1}:{2}", BOSaddress, newconn.Server, newconn.Port);

            newconn.Cookie = cookie;
            newconn.ConnectToServer();

            // The login process continues when the server sends SNAC(01,03) on the new connection
        }
コード例 #31
0
ファイル: ServiceManager.cs プロジェクト: pkt30/OscarLib
        /// <summary>
        /// Notifies the OSCAR server that the new connection is ready to receive service-specific data
        /// </summary>
        /// <remarks>
        /// This SNAC must be sent within 30ish seconds of connection, or the connection will drop.
        /// This should not ever be a problem, barring a lost connection well below the level of this library.
        /// </remarks>
        public void SendReadyNotification(Connection conn)
        {
            // Build SNAC(01,02)
            SNACHeader sh = new SNACHeader();
            sh.FamilyServiceID = SNAC_BOS_FAMILY;
            sh.FamilySubtypeID = BOS_CONNECTION_READY;

            ushort[] families = parent.Connections.GetFamilies(conn);
            FamilyManager fm = parent.Families;

            Array.Sort(families);
            Array.Reverse(families);

            bool isChatRoomConnection = false;
            bool isChatNavService = false;

            ByteStream stream = new ByteStream();
            DataPacket[][] delayedframes = new DataPacket[families.Length][];

            for (int i = 0; i < families.Length; i++)
            {
                ushort family = families[i];
                delayedframes[i] = parent.Connections.GetDelayedPackets(family);

                stream.WriteUshort(family);
                stream.WriteUshort(fm.GetFamilyVersion(family));
                stream.WriteUshort(fm.GetFamilyToolID(family));
                stream.WriteUshort(fm.GetFamilyToolVersion(family));

                if (family == 0x000D)
                {
                    isChatNavService = true;
                }
                else if (family == 0x000E)
                {
                    isChatRoomConnection = true;
                }
            }

            /*
             * The initial service connection has to send SNAC(01,1E) before it actually
             * sends SNAC(01,02), thus the check for the initial connection here
             * and after it gets sent.
            */
            if (!parent.LoggedIn)
            {
                SetAvailableMessage(parent.Statuses.AvailableMessage);
                SetDCInfo();
                SetExtendedICQStatus(parent.Statuses.ICQFlags, parent.Statuses.ICQStatus);
            }

            // The connection is done, so start sending keepalives
            conn.Connecting = false;
            conn.ReadyForData = true;

            DataPacket dp = Marshal.BuildDataPacket(parent, sh, stream);
            dp.ParentConnection = conn;
            SNACFunctions.BuildFLAP(dp);

            /*
             * If this is a new service connection, there is probably at least one
             * delayed packet. Process those packets. Additionally, if the new connection is
             * a chatroom connection, query the Rendezvous manager to see if it is the result
             * of an explict room creation (or implict, as in accepting a chat invitation).
             * If it was explict, notify the user that it's done
             */
            if (parent.LoggedIn)
            {
                foreach (DataPacket[] list in delayedframes)
                {
                    if (list == null) continue;
                    foreach (DataPacket dp_delay in list)
                    {
                        dp_delay.ParentConnection = conn;
                        SNACFunctions.DispatchToRateClass(dp_delay);
                    }
                }

                if (isChatNavService)
                {
                    parent.ChatRooms.OnChatNavServiceAvailable();
                }
                else if (isChatRoomConnection)
                {
                    ChatRoom chatRoom = parent.Connections.GetChatByConnection((ChatConnection)conn);
                    parent.ChatRooms.OnChatRoomConnectionAvailable(chatRoom);
                }
            }
        }
コード例 #32
0
ファイル: SNAC15.cs プロジェクト: pkt30/OscarLib
        public static void ProcessInfoResponse(DataPacket dp)
        {
            // The first four bytes of this are the TLV 0x0001
            // header which encapsulates the rest of the data
            int index = 4;

            ushort cmdlength = dp.Data.ReadUshortLE();
            uint my_uin = dp.Data.ReadUintLE();
            ushort command = dp.Data.ReadUshortLE();
            ushort requestID = dp.Data.ReadUshortLE();

            Encoding enc = Encoding.ASCII;

            switch (command)
            {
                case 0x0041:
                    break;
                case 0x0042:
                    // Gaim does a callback here
                    break;
                case 0x07DA:
                    ICQInfo info = new ICQInfo();
                    // RecallICQInfo(requestid)
                    ushort subtype = dp.Data.ReadUshortLE();
                    index++; // 0x0A
                    switch (subtype)
                    {
                        case 0x00A0:
                            break;
                        case 0x00AA:
                            break;
                        case 0x00C8:
                            info.Nickname = dp.Data.ReadString(dp.Data.ReadUshortLE(), Encoding.ASCII);
                            info.Firstname = dp.Data.ReadString(dp.Data.ReadUshortLE(), Encoding.ASCII);
                            info.Lastname = dp.Data.ReadString(dp.Data.ReadUshortLE(), Encoding.ASCII);
                            info.Email = dp.Data.ReadString(dp.Data.ReadUshortLE(), Encoding.ASCII);
                            info.HomeCity = dp.Data.ReadString(dp.Data.ReadUshortLE(), Encoding.ASCII);
                            info.HomeState = dp.Data.ReadString(dp.Data.ReadUshortLE(), Encoding.ASCII);
                            info.HomePhone = dp.Data.ReadString(dp.Data.ReadUshortLE(), Encoding.ASCII);
                            info.HomeFax = dp.Data.ReadString(dp.Data.ReadUshortLE(), Encoding.ASCII);
                            info.HomeAddress = dp.Data.ReadString(dp.Data.ReadUshortLE(), Encoding.ASCII);
                            info.MobilePhone = dp.Data.ReadString(dp.Data.ReadUshortLE(), Encoding.ASCII);
                            info.HomeZip = dp.Data.ReadString(dp.Data.ReadUshortLE(), Encoding.ASCII);
                            info.HomeCountry = dp.Data.ReadUshortLE();
                            break;
                        case 0x00DC:
                            info.Age = dp.Data.ReadByte();
                            index++; // unknown
                            info.Gender = dp.Data.ReadByte();
                            info.PersonalURL = dp.Data.ReadString(dp.Data.ReadUshortLE(), Encoding.ASCII);
                            info.BirthYear = dp.Data.ReadUshortLE();
                            info.BirthMonth = dp.Data.ReadByte();
                            info.BirthDay = dp.Data.ReadByte();
                            info.Language1 = dp.Data.ReadByte();
                            info.Language2 = dp.Data.ReadByte();
                            info.Language3 = dp.Data.ReadByte();
                            break;
                        case 0x00D2:
                            info.WorkCity = dp.Data.ReadString(dp.Data.ReadUshortLE(), Encoding.ASCII);
                            info.WorkState = dp.Data.ReadString(dp.Data.ReadUshortLE(), Encoding.ASCII);
                            info.WorkPhone = dp.Data.ReadString(dp.Data.ReadUshortLE(), Encoding.ASCII);
                            info.WorkFax = dp.Data.ReadString(dp.Data.ReadUshortLE(), Encoding.ASCII);
                            info.WorkAddress = dp.Data.ReadString(dp.Data.ReadUshortLE(), Encoding.ASCII);
                            info.WorkZip = dp.Data.ReadString(dp.Data.ReadUshortLE(), Encoding.ASCII);
                            info.WorkCountry = dp.Data.ReadUshortLE();
                            info.WorkCompany = dp.Data.ReadString(dp.Data.ReadUshortLE(), Encoding.ASCII);
                            info.WorkDivision = dp.Data.ReadString(dp.Data.ReadUshortLE(), Encoding.ASCII);
                            info.WorkPosition = dp.Data.ReadString(dp.Data.ReadUshortLE(), Encoding.ASCII);
                            index += 2;
                            info.WorkWebsite = dp.Data.ReadString(dp.Data.ReadUshortLE(), Encoding.ASCII);
                            break;
                        case 0x00E6:
                            info.Information = dp.Data.ReadString(dp.Data.ReadUshortLE(), Encoding.ASCII);
                            break;
                        case 0x00EB:
                            ushort numaddresses = dp.Data.ReadUshortLE();
                            info.EmailAddresses = new string[numaddresses];
                            for (int i = 0; i < numaddresses; i++)
                            {
                                info.EmailAddresses[i] = dp.Data.ReadString(dp.Data.ReadUshortLE(), Encoding.ASCII);
                                if (i + 1 != numaddresses)
                                    index++;
                            }
                            break;
                        case 0x00F0:
                            break;
                        case 0x00FA:
                            break;
                        case 0x0104:
                            info.Nickname = dp.Data.ReadString(dp.Data.ReadUshortLE(), Encoding.ASCII);
                            info.Firstname = dp.Data.ReadString(dp.Data.ReadUshortLE(), Encoding.ASCII);
                            info.Lastname = dp.Data.ReadString(dp.Data.ReadUshortLE(), Encoding.ASCII);

                            break;
                        case 0x010E:
                            break;
                        case 0x019A:
                            index += 2;
                            info.Screenname = dp.Data.ReadUintLE().ToString();
                            info.Nickname = dp.Data.ReadString(dp.Data.ReadUshortLE(), Encoding.ASCII);
                            info.Firstname = dp.Data.ReadString(dp.Data.ReadUshortLE(), Encoding.ASCII);
                            info.Lastname = dp.Data.ReadString(dp.Data.ReadUshortLE(), Encoding.ASCII);
                            info.Email = dp.Data.ReadString(dp.Data.ReadUshortLE(), Encoding.ASCII);
                            break;
                    } // End the subtype switch statement
                    break;

                    // Do some crazy multipart snac stuff
                default:
                    index += cmdlength;
                    break;
            }
        }
コード例 #33
0
ファイル: ServiceManager.cs プロジェクト: pkt30/OscarLib
        /// <summary>
        /// Processes the client's own extended status update sent by the server -- SNAC(01,21)
        /// </summary>
        /// <param name="dp">A <see cref="DataPacket"/> object with a buffer containing SNAC(01,21)</param>
        private void ProcessExtendedStatus(DataPacket dp)
        {
            // Messages are starting with a 0x0004...what the heck?
            dp.Data.ReadUshort();
            ushort type = dp.Data.ReadUshort();
            byte flags = dp.Data.ReadByte();
            byte length = dp.Data.ReadByte();

            if (type == EXTSTATUS_ICON1 || type == EXTSTATUS_ICON2)
            {
                // TODO:  Some icon bullcrap, I don't know
            }
            else // Available message
            {
            }
        }