Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - .NET

Страница: 1 |

 

  Вопрос: опять взялся за аську Добавлено: 19.03.07 00:44  

Автор вопроса:  Neco | Web-сайт: neco.pisem.net | ICQ: 247906854 
что-то опять меня накрыло написать класс для работы с аськой. теперь на дотнете. полпути прошёл, но выдохся на этапе прописывания сборки/разборки всех snac'ов.
давайте может дружно возьмёмся?

вот на что хватило терпения:
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace proICQ_Begin
{
    class clsICQ_C
    {
        public class ICQException : Exception
        {

            public ICQException() { }
            public ICQException(string message) : base(message) { }
            public ICQException(string message, Exception inner) : base(message, inner) { }
            protected ICQException(
              System.Runtime.Serialization.SerializationInfo info,
              System.Runtime.Serialization.StreamingContext context)
                : base(info, context) { }
        }
        public class ICQStreamWriter:IDisposable
        {
            private const int IncStep = 1000;
            Stream strm;
            byte[] buf = new byte[0];
            int pos = 0;
            public ICQStreamWriter(Stream base_stream)
            {
                if (base_stream == null) throw new ICQException("Base stream can not be null!");
                if (!base_stream.CanWrite) throw new ICQException("Base stream must be writable!");
                strm = base_stream;
            }
            public void WriteByte(byte data)
            {
                CheckSize(1);
                buf[pos] = data;
                pos += 1;
            }
            public void WriteUIn16(UInt16 data)
            {
                CheckSize(2);
                buf[pos + 0] = (byte)((data & 0xFF00) >> 8);
                buf[pos + 1] = (byte)((data & 0x00FF) >> 0);
                //buf[pos + 0] = (byte)((data & 0x00FF) >> 0);
                //buf[pos + 1] = (byte)((data & 0xFF00) >> 8);
                pos += 2;
            }
            public void WriteUIn32(UInt32 data)
            {
                CheckSize(4);
                buf[pos + 0] = (byte)((data & 0xFF000000) >> 24);
                buf[pos + 1] = (byte)((data & 0x00FF0000) >> 16);
                buf[pos + 2] = (byte)((data & 0x0000FF00) >> 8);
                buf[pos + 3] = (byte)((data & 0x000000FF) >> 0);
                //buf[pos + 0] = (byte)((data & 0x000000FF) >> 0);
                //buf[pos + 1] = (byte)((data & 0x0000FF00) >> 8);
                //buf[pos + 2] = (byte)((data & 0x00FF0000) >> 16);
                //buf[pos + 3] = (byte)((data & 0xFF000000) >> 24);
                pos += 4;
            }
            public void WriteString(String data)
            {
                int sz = data.Length;
                CheckSize(sz);
                byte[] tmp = System.Text.Encoding.Default.GetBytes(data);
                if (tmp.Length != sz) throw new ICQException("ICQStream.WriteString method: sizeof string data and array is not equal!");
                WriteByteArr(tmp);
                //Array.Copy(tmp, 0, buf, pos, sz);
                //pos += sz;
            }
            public void WriteByteArr(byte[] data)
            {
                int sz = data.Length;
                CheckSize(sz);
                Array.Copy(data, 0, buf, pos, sz);                
                pos += sz;
            }
            //public static int sent;
            public void Flush()
            {
                strm.Write(buf, 0, pos);
                strm.Flush();
                //sent += pos;
                pos = 0;
                buf = new byte[0];
                //System.Diagnostics.Debug.WriteLine("sent " + sent.ToString());
            }
            private void DebugArray()
            {
                for (int i = 0; i < pos; ++i)
                {
                    System.Diagnostics.Debug.Write(buf[i].ToString() + "\t:");
                }
                System.Diagnostics.Debug.WriteLine("");
            }
            public void Dispose()
            {
                Flush();
            }
            private void CheckSize(int next_size)
            {
                if (buf.Length < pos + next_size)
                {
                    int n_sz = buf.Length + IncStep;
                    byte[] old = buf;
                    buf = new byte[n_sz];
                    Array.Copy(old, buf, old.Length);
                    CheckSize(next_size); // ещё раз, чтобы убедиться, что хватает
                }
            }
            public Stream BaseStream
            {
                get { return strm; }
            }
        }
        public class ICQStreamReader : IDisposable
        {
            Stream strm;
            public ICQStreamReader(Stream base_stream)
            {
                strm = base_stream;
            }

            public String ReadStr(UInt16 len)
            {
                byte[] buf = ReadArray(len);
                return System.Text.Encoding.Default.GetString(buf);
            }
            public byte ReadByte()
            {
                return (byte)strm.ReadByte();
            }
            public UInt16 ReadUInt16()
            {
                return (UInt16)((strm.ReadByte() << 8) + strm.ReadByte());
            }
            public UInt32 ReadUInt32()
            {
                return (UInt32)((ReadUInt16() << 16) + ReadUInt16());
            }
            public byte[] ReadArray(UInt16 len)
            {
                byte[] rez=new byte[len];
                if (len > 0)
                    strm.Read(rez, 0, len);
                return rez;
            }

            //public Int16 ReadInt16()
            //{
            //    return (Int16)((strm.ReadByte() << 8) + strm.ReadByte());
            //}
            //public UInt16 ReadUInt16()
            //{
            //}
            //public UInt32 ReadUInt32()
            //{
            //}

            public void Dispose()
            {
                //throw new Exception("The method or operation is not implemented.");
            }
            public Stream BaseStream
            {
                get { return strm; }
            }
        }
        private class FLAP: TLVCollection
        {
            public const byte CommandStart = 0x2A;
            public byte ChannelID;
                                    //1 - канал установления соединения
                                    //2 - канал обмена данными (основная фаза работы: какие-либо полезные данные передаются только в этой фазе)
                                    //3 - канал ошибок. (на практике мне не попадался :)
                                    //4 - канал разъединения. (это проще, чем написано)
            public UInt16 SeqNum;
            //protected UInt16 m_data_len;
            public int my_len;
            public SNAC data;
            public bool IsHello;
            private byte[] chunk_arr = new byte[0];
            //public TLV[] arr_tlv;

            public UInt16 FullLength
            {
                get
                {
                    return (UInt16)(my_len + DataLength);
                }
            }
            public UInt16 DataLength
            {
                get
                {
                    UInt16 rez = 0;
                    switch (this.ChannelID)
                    {
                        case 2:
                            {
                                rez += data.FullLength;
                                break;
                            }
                        case 1:
                            {
                                rez += 4;
                                rez += this.CollectionSize;
                                break;
                            }
                        case 3:
                            {
                                throw new Exception("something forgot?");
                                //break;
                            }
                        case 4:
                            {
                                rez += (UInt16)chunk_arr.Length;
                                rez += this.CollectionSize;
                                break;
                            }
                        case 5: break;
                        default:
                            {
                                throw new ICQException("Unknown FLAP channel id!");
                            }
                    }
                    return rez;
                }
            }
            public static FLAP Create(Stream strm)
            {
                FLAP rez = new FLAP();
                using (ICQStreamReader rdr = new ICQStreamReader(strm))
                {
                    byte beg = (byte)strm.ReadByte();
                    if (beg == 255) return null; // disconnected
                    if (beg != CommandStart) throw new ICQException("Incorrect FLAP command start!");
                    rez.ChannelID = rdr.ReadByte();
                    rez.SeqNum = rdr.ReadUInt16();
                    int data_len = rdr.ReadUInt16();
                    //byte[] buff = rdr.ReadArray((UInt16) data_len);
                    //DebugArray(buff);
                    rez.my_len = 6;
                    switch (rez.ChannelID)
                    {
                        case 2:
                            {
                                rez.data = SNAC.Create(strm, data_len);
                                break;
                            }
                        case 1:
                            {
                                if (rdr.ReadUInt32() == 1)
                                {
                                    rez.IsHello = true;
                                    while (data_len > rez.DataLength)
                                    {
                                        rez.AppendTLV(TLV.Create(rdr));
                                    }
                                }
                                else
                                {
                                    throw new ICQException("Dword 0x00000001 expected with channelid=1");
                                }
                                break;
                            }
                        case 3:
                            {
                                throw new Exception("something forgot?");
                                //break;
                            }
                        case 4:
                            {
                                // писец, мля....
                                //if (data_len == 90) { rez.chunk_arr = rdr.ReadArray((UInt16)5); }
                                //if (data_len != 90) { rez.chunk_arr = rdr.ReadArray((UInt16)5); }
                                while (data_len > rez.DataLength)
                                {
                                    rez.AppendTLV(TLV.Create(rdr));
                                }
                                break;
                            }
                        case 5: break;
                        default:
                            {
                                throw new ICQException("Unknown FLAP channel id!");
                            }
                    }
                }
                return rez;
            }
            public static FLAP Create(byte inChannelID, UInt16 inSeqNum)
            {
                FLAP rez = new FLAP();
                rez.ChannelID = inChannelID;
                rez.SeqNum = inSeqNum;
                return rez;
            }
            public void WriteToStream(Stream strm)
            {
                using (ICQStreamWriter wrtr = new ICQStreamWriter(strm))
                {
                    if ((ChannelID == 1) && (!IsHello)) throw new ICQException("Братан, ты не ошибся?!");
                    wrtr.WriteByte(CommandStart);
                    wrtr.WriteByte(this.ChannelID);
                    wrtr.WriteUIn16(this.SeqNum);
                    wrtr.WriteUIn16(this.DataLength);
                    switch (this.ChannelID)
                    {
                        case 2:
                            {
                                if (data != null)
                                {
                                    data.WriteToStream(wrtr);
                                }
                                else
                                {
                                    throw new ICQException("With channel id=2 received null snac!");
                                }
                                break;
                            }
                        case 1:
                            {
                                wrtr.WriteUIn32(1); // Hello
                                WriteCollectionToStream(wrtr);
                                break;
                            }
                        case 3:
                            {
                                throw new Exception("something forgot?");
                                //break;
                            }
                        case 4:
                            {
                                wrtr.WriteByteArr(chunk_arr); // Hello
                                WriteCollectionToStream(wrtr);
                                break;
                            }
                        case 5: break;
                        default:
                            {
                                throw new ICQException("Unknown FLAP channel id!");
                            }
                    }
                }
            }
        }
        private class SNAC: TLVCollection
        {
            public UInt16 FamilyID,
                          SubTypeID;
            public byte   Flag0,
                          Flag1;
            public UInt32 RequestID;
            //public UInt16 m_data_len;
            //public TLV[] arr_tlv;

            public UInt16 my_len;
            public UInt16 FullLength
            {
                get
                {
                    return (UInt16) (my_len + this.DataLen);
                }
            }
            public int DataLen
            {
                get { return this.CollectionSize + all_data.Length; }
            }
            //private static UInt16[] coll_tlv_st_f1 = { 0x1E, 0x1E };
            //private static UInt16[] coll_b2_st_f1 = {0x03, 0x08 };
            //private static UInt16[] coll_b4_st_f1 = {0x17 };
            //private static UInt16[] coll_b8_st_f1 = {0x02 };
            //private static UInt16[] coll_no_st_f1 = {0x06, 0x0E };
            public byte[] all_data = new byte[0];

            public static SNAC Create(Stream strm, int data_len)
            {
                SNAC rez = new SNAC();
                using (ICQStreamReader rdr = new ICQStreamReader(strm))
                {
                    rez.FamilyID = rdr.ReadUInt16();
                    rez.SubTypeID = rdr.ReadUInt16();
                    rez.Flag0 = rdr.ReadByte();
                    rez.Flag1 = rdr.ReadByte();
                    rez.RequestID = rdr.ReadUInt32();
                    rez.my_len = 10;
                    rez.all_data = rdr.ReadArray((UInt16)(data_len - rez.my_len));

                    //if (rez.FamilyID == 1)
                    //{
                    //}
                    //else if (rez.FamilyID == 2)
                    //{
                    //}
                }
                return rez;
            }
            private static void LoadAll_TLV(ICQStreamReader rdr, SNAC to_snac, int data_len)
            {
                while (data_len > to_snac.FullLength)
                {
                    to_snac.AppendTLV(TLV.Create(rdr));
                }
            }
            public static SNAC Create(UInt16 inFamilyID, UInt16 inSubTypeID, UInt32 inRequestID)
            {
                return Create(inFamilyID, inSubTypeID, 0, 0, inRequestID);
            }
            public static SNAC Create(UInt16 inFamilyID, UInt16 inSubTypeID, byte inFlag0, byte inFlag1, UInt32 inRequestID)
            {
                SNAC rez = new SNAC();
                rez.FamilyID = inFamilyID;
                rez.SubTypeID = inSubTypeID;
                rez.Flag0 = inFlag0;
                rez.Flag1 = inFlag1;
                rez.RequestID = inRequestID;
                return rez;
            }
            public void WriteToStream(ICQStreamWriter wrtr)
            {
                wrtr.WriteUIn16(FamilyID);
                wrtr.WriteUIn16(SubTypeID);
                wrtr.WriteByte(Flag0);
                wrtr.WriteByte(Flag1);
                wrtr.WriteUIn32(RequestID);
                WriteCollectionToStream(wrtr);
                wrtr.WriteByteArr(all_data);
            }
        }
        private class TLVCollection
        {
            public TLV[] arr_tlv=new TLV[0];
            public TLVCollection()
            {
                arr_tlv=new TLV[0];
            }
            public void AppendTLV(TLV n_tlv)
            {
                int n_indx = GetNextIndex();
                arr_tlv[n_indx] = n_tlv;
            }
            private int GetNextIndex()
            {
                int rez_max;
                TLV[] old = arr_tlv;
                rez_max = arr_tlv.Length + 1;
                arr_tlv = new TLV[rez_max];
                Array.Copy(old, arr_tlv, old.Length);
                return rez_max - 1;
            }
            public UInt16 CollectionSize
            {
                get
                {
                    UInt16 rez = 0;
                    foreach (TLV one in arr_tlv)
                    {
                        rez += one.FullLength;
                    }
                    return rez;
                }
            }
            public TLV FindByCode(UInt16 code)
            {
                foreach (TLV one in arr_tlv)
                {
                    if (one.TypeCode == code) return one;
                }
                throw new ICQException("TLV " + code.ToString() + " not found!");
            }
            public bool ItIsHere(UInt16 code)
            {
                foreach (TLV one in arr_tlv)
                {
                    if (one.TypeCode == code) return true;
                }
                return false;
            }
            public void WriteCollectionToStream(ICQStreamWriter wrtr)
            {
                foreach (TLV one in arr_tlv)
                {
                    one.WriteToStream(wrtr);
                    //wrtr.Flush();
                }
            }
        }
        public class TLV
        {
            public enum InternalType
            { UInt_16, UInt_32, String, ByteArray };

            public UInt16 TypeCode;
            public UInt16 DataLen;
            public object Data;
            public InternalType tp;

            public UInt16 FullLength
            {
                get
                {
                    return (UInt16)(4 + DataLen);
                }
            }
            public static TLV Create(ICQStreamReader rdr)
            {
                TLV rez = new TLV();
                rez.TypeCode = rdr.ReadUInt16();
                rez.DataLen = rdr.ReadUInt16();
                rez.tp = GetInternalType(rez.TypeCode);
                switch (rez.tp)
                {
                    case InternalType.String: rez.Data = rdr.ReadStr(rez.DataLen); break;
                    case InternalType.UInt_16: rez.Data = rdr.ReadUInt16(); break;
                    case InternalType.UInt_32: rez.Data = rdr.ReadUInt32(); break;
                    case InternalType.ByteArray: rez.Data = rdr.ReadArray(rez.DataLen); break;
                    default: throw new ICQException("Unwnown Internal Type Code!");
                }
                return rez;
            }
            public static TLV Create(UInt16 inTypeCode, object inData)
            {
                try
                {
                    TLV rez;
                    switch (GetInternalType(inTypeCode))
                    {
                        case InternalType.String: rez = CreateStr((String)inData); break;
                        case InternalType.UInt_16: rez = CreateUInt16(Convert.ToUInt16(inData)); break;
                        case InternalType.UInt_32: rez = rez = CreateUInt32(Convert.ToUInt32(inData)); break;
                        case InternalType.ByteArray: rez = CreateArray((byte[])inData); break;
                        default: throw new ICQException("Unwnown Internal Type Code!");
                    }
                    rez.TypeCode = inTypeCode;
                    return rez;

                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }
            private static InternalType GetInternalType(UInt16 code)
            {
                switch (code)
                {
                    case 0x01: // string
                    case 0x03:
                    case 0x04:
                    case 0x05:
                    case 0x0B:
                    case 0x0E:
                    case 0x0F:
                    case 0x11:
                    case 0x12:
                    case 0x41:
                    case 0x42:
                    case 0x43:
                    case 0x45:
                    case 0x46:
                    case 0x47:
                    case 0x48:
                    case 0x49:
                    case 0x54:
                        {
                            return InternalType.String;
                        }
                    case (0x08): // word
                    case (0x09):
                    case (0x0C):
                    case (0x0D):
                    case (0x13):
                    case (0x16):
                    case (0x17):
                    case (0x18):
                    case (0x19):
                    case (0x1A):
                        {
                            return InternalType.UInt_16;
                        }
                    case (0x14): // dword
                    case (0x40):
                    case (0x44):
                        {
                            return InternalType.UInt_32;
                        }
                    case (0x02): // array
                    case (0x06):
                    case (0x25):
                    case (0x8E):
                        {
                            return InternalType.ByteArray;
                        }
                    default:
                        {
                            throw new ICQException("Unknown TLV type code = " + code.ToString());
                        }
                }
            }
            private static TLV CreateStr(String inData)
            {
                TLV rez = new TLV();
                rez.DataLen = (UInt16) inData.Length;
                rez.Data = inData;
                rez.tp = InternalType.String;
                return rez;
            }
            private static TLV CreateUInt16(UInt16 inData)
            {
                TLV rez = new TLV();
                rez.DataLen = 2;
                rez.Data = inData;
                rez.tp = InternalType.UInt_16;
                return rez;
            }
            private static TLV CreateUInt32(UInt32 inData)
            {
                TLV rez = new TLV();
                rez.DataLen = 4;
                rez.Data = inData;
                rez.tp = InternalType.UInt_32;
                return rez;
            }
            private static TLV CreateArray(byte[] inData)
            {
                TLV rez = new TLV();
                rez.DataLen = (UInt16) inData.Length;
                rez.Data = inData;
                rez.tp = InternalType.ByteArray;
                return rez;
            }

            public void WriteToStream(ICQStreamWriter wrtr)
            {

                wrtr.WriteUIn16(this.TypeCode);
                wrtr.WriteUIn16(this.DataLen);
                //wrtr.Flush();
                switch (this.tp)
                {
                    case InternalType.UInt_16: wrtr.WriteUIn16((UInt16)this.Data); break;
                    case InternalType.UInt_32: wrtr.WriteUIn32((UInt32)this.Data); break;
                    case InternalType.String: wrtr.WriteString((String)this.Data); break;
                    case InternalType.ByteArray: wrtr.WriteByteArr((byte[])this.Data); break;
                    default: throw new ICQException("Unknown tlv data type!");
                }
            }
        }

        private const string m_host = "205.188.179.233";
        private const int m_port = 5190;

        NetworkStream strm_dlg;

        public void Connect()
        {
            //Int16 foo = 1 + (1 << 8);
            FLAP auth_rez;
            TcpClient sck;
            sck = new TcpClient();
            sck.Connect(m_host, m_port);
            using (strm_dlg = new NetworkStream(sck.Client))
            {
                sck.ReceiveTimeout = 5000;
                sck.SendBufferSize = 1024;

                FLAP auth = FLAP.Create(strm_dlg);
                if (!auth.IsHello) throw new ICQException("Hello expected!");
                //SNAC uin=SNAC.Create()
                IncSeq(ref auth.SeqNum);

                GetLoginSNACLikeQip("123456", "123456").WriteToStream(strm_dlg);

                auth_rez = FLAP.Create(strm_dlg);
                FLAP.Create(4, (UInt16)(auth.SeqNum + 1)).WriteToStream(strm_dlg);
            }
            sck.Close();
            if (!auth_rez.ItIsHere(0x0008))
            {
                string n_addr, n_ip, n_port;
                n_addr =(string)auth_rez.FindByCode(0x0005).Data;
                int v = n_addr.IndexOf(":");
                n_ip = n_addr.Substring(0, v);
                n_port = n_addr.Substring(v + 1);
                sck = new TcpClient();
                sck.Connect(n_ip, Convert.ToInt32(n_port));
                sck.ReceiveTimeout = 5000;
                //sck.SendBufferSize = 0;
                using (Stream strm_dlg = new NetworkStream(sck.Client))
                {
                    //string cook = System.Text.Encoding.Default.GetString((byte[]) auth_rez.FindByCode(0x0006).Data);
                    FLAP tmp;
                    tmp = FLAP.Create(strm_dlg);
                    //IncSeq(ref tmp.SeqNum);
                    tmp = FLAP.Create(1, (UInt16)(tmp.SeqNum + 1));
                    tmp.AppendTLV(auth_rez.FindByCode(0x0006));
                    //tmp.AppendTLV(TLV.Create(0x0006, System.Text.Encoding.Default.GetBytes(cook)));
                    tmp.IsHello = true;

                    tmp.WriteToStream(strm_dlg);

                    tmp = FLAP.Create(strm_dlg);

                }
            }
            else
            {
                throw new ICQException("Auth failed!");
            }
            
            //login.AppendTLV(TLV.Create(0x03, "ICQ Inc. - Product of ICQ (TM).2000a.4.31.1.3143.85"));

            //login.AppendTLV(TLV.Create(0x16, 0x010A)); // Client id number
            //login.AppendTLV(TLV.Create(0x17, 0x0004)); // Client major version
            //login.AppendTLV(TLV.Create(0x18, 0x001F)); // Client minor version
            //login.AppendTLV(TLV.Create(0x19, 0x0001)); // Client lesser version
            //login.AppendTLV(TLV.Create(0x1A, 0x0C47)); // Client build number

            //login.AppendTLV(TLV.Create(0x14, 0x00000055)); // Distribution number
            //login.AppendTLV(TLV.Create(0x0F, "en"));
            //login.AppendTLV(TLV.Create(0x0E, "us"));

        }
        public void RunProxy()
        {
            BaseServer();
            BOSServer();
            //Thread th_base = new Thread(BaseServer);
            //th_base.Start();
        }
        string bos_host, bos_port;
        private void ParseBosHost(string orig)
        {
            int v = orig.IndexOf(":");
            bos_host = orig.Substring(0, v);
            bos_port = orig.Substring(v + 1);
        }
        NetworkStream base_strm_real, bos_strm_real, base_strm_client, bos_strm_client;
        object sync_base = new object();
        Socket base_server_socket,bos_server_socket;
        private void BaseServer()
        {
            TcpListener lsnr = new TcpListener(IPAddress.Loopback, 555);
            lsnr.Start();
            base_server_socket = lsnr.AcceptSocket();
            base_strm_client = new NetworkStream(base_server_socket);
            TcpClient client = new TcpClient();
            client.Connect(m_host, m_port);
            base_strm_real = new NetworkStream(client.Client);
            (new Thread(BaseReaderClient)).Start();
            (new Thread(BaseReaderReal)).Start();
        }
        private void BOSServer()
        {
            TcpListener lsnr = new TcpListener(IPAddress.Loopback, 556);
            lsnr.Start();
            bos_server_socket = lsnr.AcceptSocket();
            bos_strm_client = new NetworkStream(bos_server_socket);
            TcpClient client = new TcpClient();
            client.Connect(bos_host, Convert.ToInt32(bos_port));
            bos_strm_real = new NetworkStream(client.Client);
            (new Thread(BOSReaderReal)).Start();
            (new Thread(BOSReaderClient)).Start();
        }

        private void DebugFLAP(FLAP f)
        {
            Print("FLAP received!");
            Print("chID=" + f.ChannelID.ToString() + ";");
            switch (f.ChannelID)
            {
                case 2:
                    {
                        DebugSNAC(f.data);
                        //if (f.data != null) DebugSNAC(f.data);
                        break;
                    }
                case 1:
                    {
                        Print("is hello");
                        foreach (TLV one in f.arr_tlv)
                        {
                            DebugTLV(one);
                        }
                        break;
                    }
                case 3:
                    {
                        throw new Exception("something forgot?");
                        //break;
                    }
                case 4:
                    {
                        Print("is 4!");
                        foreach (TLV one in f.arr_tlv)
                        {
                            DebugTLV(one);
                        }
                        break;
                    }
                case 5: break;
                default:
                    {
                        throw new ICQException("Unknown FLAP channel id!");
                    }
            }
        }
        private void DebugSNAC(SNAC s)
        {
            Print("SNAC: FamID=" + s.FamilyID.ToString() + "; SubID=" + s.SubTypeID.ToString() + "; ReqId=" + s.RequestID.ToString());
            foreach (TLV one in s.arr_tlv)
            {
                DebugTLV(one);
            }
            //DebugArray(s.all_data);
        }
        private void DebugTLV(TLV t)
        {
            string str_data;
            switch (t.tp)
            {
                case TLV.InternalType.String: { str_data = t.Data.ToString(); break; }
                case TLV.InternalType.UInt_16: { str_data = t.Data.ToString(); break; }
                case TLV.InternalType.UInt_32: { str_data = t.Data.ToString(); break; }
                case TLV.InternalType.ByteArray:
                    {
                        str_data = "";
                        byte[] buf = (byte[])t.Data;
                        for (int i = 0; i < t.DataLen; ++i)
                        {
                            str_data += buf[i].ToString() + "-";
                        }
                        break;
                    }
                default: { throw new Exception("Косяк!!!"); }
            }
            Print("TLV: T=" + t.TypeCode.ToString() + "; L=" + t.DataLen.ToString() + "; V=" + str_data);
        }
        private void Print(object stroka)
        {
            System.Diagnostics.Debug.WriteLine(stroka.ToString());
        }

        private void BaseReaderReal()
        {
            bool exit = false;
            FLAP foo;
            while (true)
            {
                if (exit) break;
                try { foo = FLAP.Create(base_strm_real); }
                catch (Exception ex) { Print(ex.Message); break; }
                if (foo == null) break;
                lock (sync_base)
                {
                    Print("From real server");
                    DebugFLAP(foo);
                    Print("----------------");
                    if (foo.ItIsHere(5))
                    {
                        Print("Подменяем");
                        TLV tmp = foo.FindByCode(5);
                        ParseBosHost(tmp.Data.ToString());
                        tmp.Data = "127.0.0.1:556";
                                 // 64.12.24.36:5190
                        tmp.DataLen = (UInt16) tmp.Data.ToString().Length;
                        //exit = true;
                    }
                    foo.WriteToStream(base_strm_client);
                }
            }
            //base_strm_real.Close();
            //base_server_socket.Close();
            Print(">>>>>>>>> base real disconnected");
        }
        private void BaseReaderClient()
        {
            FLAP foo;
            while (true)
            {
                try { foo = FLAP.Create(base_strm_client); }
                catch (Exception ex) { Print(ex.Message); break; }
                if (foo == null) break;
                lock (sync_base)
                {
                    Print("From qip");
                    DebugFLAP(foo);
                    Print("----------------");
                    foo.WriteToStream(base_strm_real);
                }
            }
            Print(">>>>>>>>> base client disconnected");
            base_server_socket.Close();
        }

        private void BOSReaderReal()
        {
            FLAP foo;
            while (true)
            {
                foo = FLAP.Create(bos_strm_real);
                if (foo == null) break;
                lock (sync_base)
                {
                    Print("From BOS real server");
                    DebugFLAP(foo);
                    Print("----------------");
                    foo.WriteToStream(bos_strm_client);
                }
            }
            Print(">>>>>>>>> bos real disconnected");            
        }
        private void BOSReaderClient()
        {
            FLAP foo;
            while (true)
            {
                foo = FLAP.Create(bos_strm_client);
                if (foo == null) break;
                lock (sync_base)
                {
                    Print("From BOS qip");
                    DebugFLAP(foo);
                    Print("----------------");
                    foo.WriteToStream(bos_strm_real);
                    //bos_strm_real.WriteByte(0);
                    //bos_strm_real.Flush();
                }
            }
            Print(">>>>>>>>> bos qip disconnected");
        }

        private FLAP GetLoginSNAC(string uin, string pass)
        {
            FLAP login = FLAP.Create(1, (UInt16)(new Random()).Next(0x7FFF));
            login.IsHello = true;
            login.AppendTLV(TLV.Create(0x01, uin));
            login.AppendTLV(TLV.Create(0x02, CalcPass(pass)));
            login.AppendTLV(TLV.Create(0x03, "ICQ Inc. - Product of ICQ (TM).2003b.5.56.1.3916.85"));

            login.AppendTLV(TLV.Create(0x16, 0x010A)); // Client id number
            login.AppendTLV(TLV.Create(0x17, 0x0005)); // Client major version
            login.AppendTLV(TLV.Create(0x18, 0x0025)); // Client minor version
            login.AppendTLV(TLV.Create(0x19, 0x0001)); // Client lesser version
            login.AppendTLV(TLV.Create(0x1A, 0x0E90)); // Client build number

            login.AppendTLV(TLV.Create(0x14, 0x00000055)); // Distribution number
            login.AppendTLV(TLV.Create(0x0F, "en"));
            login.AppendTLV(TLV.Create(0x0E, "us"));
            return login;
        }
        private FLAP GetLoginSNACLikeQip(string uin, string pass)
        {
            FLAP login = FLAP.Create(1, (UInt16)(new Random()).Next(0x7FFF));
            login.IsHello = true;
            login.AppendTLV(TLV.Create(0x01, uin));
            login.AppendTLV(TLV.Create(0x02, CalcPass(pass)));
            login.AppendTLV(TLV.Create(0x03, "ICQBasic"));

            login.AppendTLV(TLV.Create(0x16, 266)); // Client id number
            login.AppendTLV(TLV.Create(0x17, 20)); // Client major version
            login.AppendTLV(TLV.Create(0x18, 52)); // Client minor version
            login.AppendTLV(TLV.Create(0x19, 0)); // Client lesser version
            login.AppendTLV(TLV.Create(0x1A, 3000)); // Client build number

            login.AppendTLV(TLV.Create(0x14, 1085)); // Distribution number
            login.AppendTLV(TLV.Create(0x0F, "en"));
            login.AppendTLV(TLV.Create(0x0E, "us"));
            return login;
        }
        private static byte[] CalcPass(string pass)
        {
            byte[] arr_pass = System.Text.Encoding.Default.GetBytes(pass);
            byte[] myxor = new byte[] { 0xF3, 0x26, 0x81, 0xC4, 0x39, 0x86, 0xDB, 0x92, 0x71, 0xA3, 0xB9, 0xE6, 0x53, 0x7A, 0x95, 0x7C };
            if (arr_pass.Length <= myxor.Length)
            {
                byte[] rez = new byte[arr_pass.Length];
                for (int i = 0; i < arr_pass.Length; ++i)
                {
                    rez[i] = (byte)(arr_pass[i] ^ myxor[i]);
                }
                return rez;
            }
            else
            {
                throw new ICQException("Too much symvols in pass!");
            }
        }
        private static void IncSeq(ref UInt16 seq)
        {
            if (seq == UInt16.MaxValue) seq = 0;
            seq += 1;
        }
        protected static void Print(Stream strm, int num)
        {
            System.Diagnostics.Debug.WriteLine("----begin----");
            for (int i = 0; i < num; ++i)
            {
                System.Diagnostics.Debug.WriteLine(strm.ReadByte().ToString());
            }
            System.Diagnostics.Debug.WriteLine("--- end ---");
        }
        //protected static Int16 ReadInt16(Stream strm)
        //{
        //    return (Int16) ((strm.ReadByte() << 8) + strm.ReadByte());
        //}
        //protected static UInt16 ReadUInt16(Stream strm)
        //{
        //    return (UInt16)((strm.ReadByte() << 8) + strm.ReadByte());
        //}
        //protected static UInt32 ReadUInt32(Stream strm)
        //{
        //    return (UInt32)((ReadInt16(strm) << 16) + ReadInt16(strm));
        //}
        //protected static Int16 ReadBuf(byte[] buf, int offset, int num_byte)
        //{
        //    Int16 rez;
        //    rez = Marshal.ReadInt16(buf[0], 0);
        //    return rez;
        //}
        private static void DebugArray(byte[] arr)
        {
            for (int i = 0; i < arr.Length; ++i)
            {
                System.Diagnostics.Debug.Write(arr[i].ToString() + ":");
            }
            System.Diagnostics.Debug.WriteLine("");
        }
    }
}


ещё раз повторюсь, что аськовый протокол пожалуй лидирует по сочетанию Дебильность*Распространённость.
но надо же его одолеть-то...

Ответить

  Ответы Всего ответов: 4  

Номер ответа: 1
Автор ответа:
 VoVaN



ICQ: 4921085 

Вопросов: 27
Ответов: 38
 Профиль | | #1 Добавлено: 19.03.07 10:56
У меня даже прочитать это терпения не хватило...

Ответить

Номер ответа: 2
Автор ответа:
 ZagZag



ICQ: 295002202 

Вопросов: 87
Ответов: 1684
 Профиль | | #2 Добавлено: 20.03.07 19:54
Оказывается сишка для меня - темный лес ((
У меня твой код не получилось запустить никак. Я просто незнаю как это сделать. Есть vs.net 2003

Неужели чтобы простенькую аську написать надо столько мороки?

Ответить

Номер ответа: 3
Автор ответа:
 HACKER


 

Разработчик Offline Client

Вопросов: 236
Ответов: 8362
 Профиль | | #3 Добавлено: 20.03.07 20:50
Неужели чтобы простенькую аську написать надо столько мороки?
Мороки больше чем ты думаешь...

Ответить

Номер ответа: 4
Автор ответа:
 Neco



ICQ: 247906854 

Вопросов: 133
Ответов: 882
 Web-сайт: neco.pisem.net
 Профиль | | #4
Добавлено: 20.03.07 21:55
ну это не сишка - это всего лишь шарп. )
а шарп это тот же васик - меня пару дней покоробило и как дома.
Только это для 2005-й студии код. Сейчас вот ты сказал и я понял, что лучше было наверное и о совместимости с первым фрэймом подумать. Но я думаю там немного изменений - юсинги убери,наверное, тут где-то говорили, что их нет там и, пожалуй, всё.

а расстраивает не эта морока, которая написана - до этого момента всё вполне закономерно. но начиная отсюда у разработчиков протокола крышу сорвало начисто.
вообще как-то странно наблюдать рядом с такой аккуратной структурой:
http://iserverd1.khstu.ru/oscar/snac_17_06.html

вот такие разношёрстные кошмары:
http://iserverd1.khstu.ru/oscar/snac_01_10.html
http://iserverd1.khstu.ru/oscar/snac_01_03.html
http://iserverd1.khstu.ru/oscar/snac_01_07.html

логика абсолютно неясна - tlv должны были быть низшим уровнем пакетов. если нужна была вложенность данных, сделали бы пакет в пакете - рекурсивно бы можно было обработать.

А на данный момент я собирался рассортировать snac'и на "нормальные" и "тупые" - "тупые" будут разбираться специальными процедурами - каждая своей. Потом этот класс я думал переименовать в ICQProtocol, на этом же уровне прописать объекты "Пользователь", "Контакт" и т.п. (на этом уровне опять же из-за "тупых" структур - процедуры разбора должны будут вносить в эти структуры данные, если бы не это, можно было поднять их на уровень выше и изменять событиями). В этом же классе я собирался прописать всю многопоточность, а вот в классе высшего уровня clsICQ эту многопоточность инкапсулировать, чтобы оставалось тока тупо его юзать. )))
и тогда количество аськовых клиентов станет резко расти, я думаю. )))

Ответить

Страница: 1 |

Поиск по форуму



© Copyright 2002-2011 VBNet.RU | Пишите нам