что-то опять меня накрыло написать класс для работы с аськой. теперь на дотнете. полпути прошёл, но выдохся на этапе прописывания сборки/разборки всех 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("");
}
}
}
ещё раз повторюсь, что аськовый протокол пожалуй лидирует по сочетанию Дебильность*Распространённость.
но надо же его одолеть-то...
Ответить
|