Subversion Repositories Kolibri OS

Rev

Rev 2296 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ; compiler:     FASM 1.67.21
  2. ; name:         ICQ client for Kolibri
  3. ; version:      0.1.30
  4. ; written by:   LV
  5. ; e-mail:       lv4evil@yandex.ru
  6.  
  7.  
  8. include "lang.inc"
  9. include "macros.inc"
  10. ;purge mov
  11. ;include "ASCL9/ascl.inc"
  12. ;include "../../../debug.inc"
  13. include "editbox.inc"
  14.  
  15. MEOS_APP_START
  16.  
  17. ;include "../../../debug.inc"
  18. include "2000.inc"
  19. include "comp.inc"
  20. ;include "fsio.inc"
  21. include "dos2win.inc"
  22. include "parser.inc"
  23. include "ssi.inc"
  24.  
  25. use_edit_box procinfo,22,5
  26.  
  27. ;
  28. ; Если == 0, код для использования контакт листа
  29. ; на сервере не ассемблируется
  30. ;
  31. USE_SSI = 1
  32. ;
  33. ;
  34.  
  35. CODE
  36.    
  37.    
  38.     ;mov eax, 40
  39.     ;mov ebx, 47h
  40.     ;int 40h
  41.  
  42.     ;
  43.     ; Загрузка конфигов
  44.     ;
  45.  
  46.     mov  eax, fname
  47.     call    parseconf
  48.     ;
  49.     ; Вывод загруженной информации
  50.     ;
  51.  
  52.     mov eax, cfg_message
  53.     xor ebx, ebx
  54.     call writemsg
  55.  
  56.     call showcfg
  57.  
  58.    
  59.     ;call    loaduin
  60.     call    draw_window            ; at first create and draw the window
  61.    
  62.     ;call    buttonbox
  63.  
  64.   wait_event:                      ; main cycle
  65.     ;mov     eax, 23
  66.     ;mov     ebx, 20
  67.     ;int     0x40
  68.     mcall 23,20
  69.  
  70.     cmp     eax, 1                 ;   if event == 1
  71.     je      redraw                 ;     jump to redraw handler
  72.     cmp     eax, 2                 ;   else if event == 2
  73.     je      key                    ;     jump to key handler
  74.     cmp     eax, 3                 ;   else if event == 3
  75.     je      button                 ;     jump to button handler
  76.    
  77.     ;
  78.     ; Ждем данных
  79.     ;
  80.    
  81.     mcall 53,2,[socket]
  82.     cmp     eax, 0
  83.     jnz     read_socket
  84.  
  85.     mouse_edit_box inputbox
  86.     ;
  87.     ; Если есть соединение с сервером, посылаем пакеты - подтвеждения каждые 60 с
  88.     ; не требуется
  89. ;    call    sendkeep
  90.    
  91.     jmp     wait_event             ;   else return to the start of main cycle
  92.  
  93.  
  94.   redraw:                          ; redraw event handler
  95.     call    draw_window
  96.     jmp     wait_event
  97.  
  98.  
  99.   key:                             ; get key code
  100.    
  101.     mcall 2
  102.  
  103.     cmp ah, 0Dh                    ; Пробел - отправить сообщение
  104.     jz send
  105.  
  106.  
  107.     key_edit_box inputbox
  108.  
  109.     jmp     wait_event
  110.  
  111.  
  112.   button:                          ; button event handler
  113.     ;mov     eax, 17               ;   get button identifier
  114.     ;int     0x40
  115.     mcall 17
  116.  
  117.     cmp     ah, 2
  118.     jz      connect
  119.  
  120.     cmp     ah, 3
  121.     jz      disconnect
  122.  
  123.     cmp     ah, 4
  124.     jz      send
  125.  
  126.     ;
  127.     ; Проверяем, не нажата ли кнопка в КЛ
  128.     ; 100 <ID <= 100+UINS
  129.     cmp ah, UINS+100
  130.     jnc @f
  131.     cmp ah, 100
  132.     jc @f
  133.     ;
  134.     ; Нажата
  135.     ;
  136.     sub ah, 100
  137.     mov [curruser], ah
  138.     ;
  139.     ; Выводим строчку, кому
  140.     ;
  141.     shr eax, 8
  142.     and eax, 000000FFh
  143.     push eax
  144.     mov eax, CUSER
  145.     call strlen
  146.     mov ecx, eax
  147.     mov eax, CUSER
  148.     mov ebx, buff
  149.     call strcpy
  150.     pop eax
  151.     mov ebx, NAME_LEN
  152.     imul ebx, eax
  153.     lea eax, [names + ebx]
  154.     mov [buff + ecx], ' ' ; Пробел
  155.     lea ebx, [buff + ecx + 1]
  156.     mov ecx, NAME_LEN
  157.     ;debug
  158.      push ebx
  159.      mov ebx, NAME_LEN
  160.      call print_mem
  161.      pop ebx
  162.     ;
  163.     call strcpy
  164.     mov eax, buff
  165.     xor ebx, ebx
  166.     call writemsg
  167.  
  168.  
  169.  
  170.  
  171.   @@:
  172.     cmp     ah, 1
  173.     jne     wait_event             ;   return if button id != 1
  174.  
  175.     ;   exit application
  176.     mcall -1
  177.  
  178.  
  179.   draw_window:
  180.     ; start drawing
  181.     mcall 12,1
  182.  
  183.     mcall 0,(100*65536+700),(100*65536+500),0x14ffffff,0,head
  184.  
  185.     draw_edit_box inputbox
  186.  
  187.     rect 10, 30, 500, 450, 0
  188.  
  189.     draw_button 600, 460, 60, 15, 2, 'CONNECT'
  190.     ;draw_button 600, 460, 60, 15, 3, 'Disconnect'
  191.     draw_button 530, 460, 60, 15, 4, 'SEND'
  192.  
  193.     call    printbuff
  194.     call    buttonbox
  195.  
  196.     ;
  197.     ; Image
  198.     ;
  199.     ;mov eax, 7
  200.     ;mov ebx, redicq
  201.     ;mov ecx, 15*65536+15
  202.     ;mov edx, 100*65536+100
  203.     ;int 40h
  204.  
  205.  
  206.    
  207.  
  208.    ; finish drawing
  209.    mcall 12,2
  210.  
  211.   ret
  212.  
  213. ;
  214. ;  Соединение
  215. ;
  216.   connect:
  217.   lea eax, [vtable + vartable.icqip]
  218.   call ip_parser
  219.   call htonl
  220.   data_debug 'IP:', eax
  221.  
  222.   ;mov eax, ICQ_IP
  223.   mov ebx, ICQ_PORT
  224.   call srv_connect
  225.  
  226.  
  227.  
  228.   jmp wait_event
  229.  
  230.  
  231. ;
  232. ;
  233. ;
  234.   disconnect:
  235.   mov ecx, [socket]
  236.   call closesocket
  237.  
  238.   jmp wait_event
  239.  
  240.  
  241. ;
  242. ;
  243. ;
  244.   send:
  245.   ;
  246.   ; Определяем, не сменен ли текущий УИН
  247.   ;
  248.   ; Для смены используется / в начале строки и номер уина
  249.   ; по порядку. Если длина > 2 символов, считается, что передан
  250.   ; сам уин - для отправки сообщений юзерам, которых нет в КЛ
  251.   ;
  252.     mov al, [inputbuff]
  253.     cmp al, '/'
  254.     jnz sd_message
  255.     ; Смена уина
  256.     ;mov al, [inputbuff+2]
  257.     ;cmp al, 20h
  258.     ;jz sd_use_kl
  259.     mov al, [inputbuff+3]
  260.     cmp al, 20h            ; Пробел
  261.     jz sd_use_kl
  262.     ;
  263.     ; Ищем первый пробел, им должен закончиться уин
  264.     ;
  265.     xor ecx, ecx
  266.   sd_loop:
  267.     mov al, [inputbuff+ecx]
  268.     cmp al, 20h
  269.     jz sd_space
  270.     cmp al, 0
  271.     jz  wait_event
  272.     inc ecx
  273.     jmp sd_loop
  274.  
  275.   sd_space:
  276.     ;
  277.     ; Заменяем пробел на 0, отсылаем сообщение
  278.     mov [inputbuff+ecx], byte 0
  279.     lea ebx, [inputbuff+1]
  280.     lea eax, [inputbuff+ecx+1]
  281.     call sendmsg
  282.     mov ebx, 0000FFh
  283.     call writemsg
  284.     jmp wait_event
  285.  
  286.  
  287.  
  288.   sd_use_kl:
  289.     lea eax, [inputbuff+1]
  290.     mov [inputbuff+3], byte 0
  291.     call ascitoint
  292.     lea eax, [eax-1]    ; Т.к. в КЛ отсчет с 0
  293.     mov [curruser], al
  294.    
  295.  
  296.   sd_message:
  297.   ;
  298.   ; Сообщение
  299.     movzx eax, [curruser]
  300.     mov ebx, UIN_LEN
  301.     imul ebx, eax
  302.     lea ebx, [uins+ebx]
  303.     mov al, [inputbuff]
  304.     cmp al, '/'
  305.     jz @f
  306.     mov eax, inputbuff
  307.     jmp sd_send
  308.   @@:
  309.     ;mov al, [inputbuff+2]
  310.     ;cmp al, ' '
  311.     ;jz @f
  312.     lea eax, [inputbuff+4]
  313.     ;jmp sd_send
  314.   ;@@: lea eax, [inputbuff+3]
  315.  
  316.   sd_send:
  317.     call sendmsg
  318.     mov ebx, 0000FFh
  319.     call writemsg
  320.  
  321.  
  322.   jmp wait_event
  323.  
  324.  
  325. ;
  326. ; Есть принятые данные
  327. ;
  328.   read_socket:
  329.     pushf
  330.     pushad
  331.     ;write_debug 'Some data in socket'
  332.     ;
  333.     ; Проверяем, не был ли получен заголовок отдельно от данных
  334.     ; в предыдущем цикле
  335.     ;
  336.     cmp [hrf], 1
  337.     jz rs_head_recived
  338.  
  339.   rs_check_sock:
  340.     ;mov eax, 53
  341.     ;mov ebx, 2
  342.     ;mov ecx, [socket]
  343.     ;int 40h
  344.     mcall 53,2,[socket]
  345.     cmp eax, 6 ; Flap head size
  346.     jc r_end
  347.     ;
  348.     ; Принимаем заголовок
  349.     ;
  350.     xor edx, edx
  351.  
  352.     ;mov ecx, [socket]
  353.    rs_loop:
  354.     ;mov eax,  53
  355.     ;mov ebx, 3
  356.     ;int 40h
  357.     mcall 53,3,[socket]
  358.  
  359.     mov [mbuff+edx], bl
  360.     inc edx
  361.     cmp edx, 6
  362.  
  363.     jnz rs_loop
  364.     ;
  365.     ; Заполняем заголовок
  366.     ;
  367.     ;xor eax, eax
  368.  
  369.     ;
  370.     ; Заголовок принят!
  371.     ;
  372.     mov [hrf], 1
  373.  
  374.     mov bl, [mbuff]
  375.     mov [rflap.bId], bl
  376.  
  377.     mov bl, [mbuff+1]
  378.     mov [rflap.bCh], bl
  379.  
  380.     mov bh, [mbuff+2]
  381.     mov bl, [mbuff+3]
  382.     mov [rflap.wSn], bx
  383.  
  384.     mov bh, [mbuff+4]
  385.     mov bl, [mbuff+5]
  386.     mov [rflap.wDs], bx
  387.  
  388.     ;
  389.     ; Принимаем данные
  390.     ;
  391.     ;xor edx, edx
  392.     cmp [rflap.bId], 2Ah
  393.     jnz rs_flap_error
  394.     ;
  395.     ;  Проверяем, получены ли данные
  396.     ;
  397.   rs_head_recived:
  398.  
  399.     ;mov eax, 53
  400.     ;mov ebx, 2
  401.     ;mov ecx, [socket]
  402.     ;int 40h
  403.     mcall 53,2,[socket]
  404.  
  405.     cmp ax, [rflap.wDs]   ; Размер данных
  406.     jc r_end
  407.     ;
  408.     ;
  409.     mov ax, [rflap.wDs]
  410.     ;
  411.     ; Проверяем размер данных
  412.     ;
  413.     cmp ax, MBUFF_SIZE+1
  414.     jnc rs_big_flap
  415.  
  416.     xor esi, esi    
  417.     mov esi, eax
  418.     xor edx, edx
  419.  
  420.     ;mov ecx, [socket]
  421.  
  422.    rs_data_loop:
  423.     cmp edx, esi
  424.     jz rs_data_end
  425.  
  426.     ;mov eax, 53
  427.     ;mov ebx, 3
  428.     ;int 40h
  429.     mcall 53,3,[socket]
  430.     mov [mbuff+edx], bl
  431.     inc edx
  432.     jmp rs_data_loop
  433.  
  434.     ;
  435.     ; Данные приняты
  436.     ;
  437.     rs_data_end:
  438.     mov [hrf], 0
  439.     ;write_debug 'Some data recived'
  440.     ;
  441.     ;
  442.     ;
  443.     cmp [login], 0
  444.     jz rs_login
  445.     call main_loop
  446.     ;
  447.     ; Есть смысл проверить сокет на наличие следующего заголовка
  448.     ;
  449.     ;jmp r_end
  450.     jmp rs_check_sock
  451.  
  452.  
  453.     rs_login:
  454.     call srv_login
  455.     ;write_debug 'Exited srv_login'
  456.     ;jmp r_end
  457.     jmp rs_check_sock
  458.  
  459.     rs_flap_error:
  460.     write_debug 'Invalid Flap'
  461.     ;
  462.     ; FLAP.id неверный. нужно закрыть сокет
  463.     ;
  464.  
  465.     mov ecx, [socket]
  466.     ;call closesocket
  467.     jmp r_end
  468.  
  469.     ;
  470.     ;  Слишком большой пакет!
  471.     ;
  472.     rs_big_flap:
  473.  
  474.     write_debug 'Too BIG FLAP Recived'
  475.     mov [hrf], 0
  476.  
  477.     ;mov ecx, [socket]
  478.     mov ax, [rflap.wDs]
  479.     xor esi, esi    
  480.     mov esi, eax
  481.     xor edx, edx
  482.  
  483.    rs_data_loop2:
  484.     cmp edx, esi
  485.     jz r_end
  486.  
  487.     ;mov eax, 53
  488.     ;mov ebx, 3
  489.     ;int 40h
  490.     mcall 53,3,[socket]
  491.     ;mov [mbuff+edx], bl
  492.     inc edx
  493.     jmp rs_data_loop2
  494.  
  495.  
  496.  
  497.  
  498.  
  499.     r_end:
  500.    
  501.     popad
  502.     popf
  503.   jmp wait_event
  504.  
  505. ; Соединение с сервером, возвращает в eax - хэндл сокета
  506. ; передаем в еах IP адрес сервера
  507. ; в ebx - порт
  508.   srv_connect:  
  509.     push ecx
  510.     push edx
  511.     push esi
  512.     push edi
  513.     push ebx
  514.    
  515.     mov esi, eax             ; IP - в esi
  516.     ; find free port
  517.     mov    ecx, 1000         ; Определяем локальный порт, начинаем с 1000
  518.  
  519.     getlp:
  520.     inc    ecx
  521.     push   ecx
  522.     ;mov    eax, 53
  523.     ;mov    ebx, 9
  524.     ;int    0x40
  525.     mcall 53,9,ecx
  526.     pop    ecx
  527.     cmp    eax, 0            ; этот локальный порт используется?
  528.     jz     getlp             ; да - продолжаем перебирать
  529.     ;OK ecx = port number
  530.     ;Open Socket
  531.     ;mov eax, 53
  532.     ;mov ebx, 5
  533.     xor edx, edx
  534.     ;mov dx, ICQ_PORT
  535.     pop edx
  536.     ;mov esi,ICQ_IP
  537.     ;mov edi, 1;SOCKET_ACTIVE
  538.  
  539.     ;int 40h
  540.     mcall 53, 5, ecx, edx, esi, 1
  541.     ;
  542.     mov [socket], eax
  543.  
  544.     ;
  545.     ; Ждем установки соедиения
  546.     mov ecx, eax
  547.   srv_loop:
  548.  
  549.     ;mov eax, 5
  550.     ;mov ebx, 50
  551.     ;int 40h
  552.     mcall 5, 50
  553.  
  554.  
  555.    
  556.     ;mov eax, 53
  557.     ;mov ebx, 6
  558.     ;int 40h
  559.     mcall 53, 6, ecx
  560.     cmp eax, TCB_ESTABLISHED
  561.     jz fin
  562.     cmp eax, 11
  563.     jae c_end
  564.     ;
  565.    
  566.     ;inc [timer]
  567.     ;cmp [timer], 50
  568.     ;jz srv_err
  569.     jmp srv_loop
  570.  
  571.  
  572.  
  573.   ;srv_err:
  574.     ;mov [timer], word 0
  575.     ;cmp eax,-1
  576.     ;jnz fin
  577.     ;delay 100
  578.     write_debug 'CONNECTION FAILED'                   ;Подключение не удалось
  579.     jmp c_end
  580.     ;connrcted:  
  581.                                           ;CONNECTED
  582.    
  583.     fin:
  584.     write_debug 'Connected!!!!'
  585.   c_end:
  586.     pop edi
  587.     pop esi
  588.     pop edx
  589.     pop ecx
  590.     ;pop ebx
  591.   ret
  592.  
  593. ;
  594. ; --> ecx socket handle
  595. ;
  596.  
  597.   srv_login:
  598.     pushf
  599.     push eax
  600.     push ebx
  601.     ;push ecx
  602.     push edx
  603.  
  604.     ;
  605.     ; Определяем тип полученных данных
  606.     ;
  607.     movzx eax, [rflap.bCh]
  608.     cmp eax, 01
  609.     jz s_new_connection
  610.     cmp eax, 04
  611.     jz s_cookie        ; cookie
  612.     jmp l_flap_err
  613.  
  614.   s_new_connection:
  615.     ;
  616.     ; Проверяем полученный пакет
  617.     ;
  618.     movzx eax, [rflap.wDs]
  619.     cmp eax, 4
  620.     jnz l_len_err
  621.     mov eax, dword [mbuff]
  622.     cmp eax, 01000000h      ; 00 00 00 01
  623.     jnz l_data_err
  624.     ;
  625.     ;Формируем пакет для соединения
  626.     ;
  627.     ;mov [flap.bId], FLAP_ID
  628.     mov [flap.bCh], NEW_CONNECTION
  629.    
  630.     ;mov eax, 26
  631.     ;mov ebx, 9
  632.     ;int 40h
  633.     mcall 26, 9
  634.     mov [seq], ax
  635.  
  636.     mov [flap.wSn], ax      ; Sequence number
  637.     ;mov [buff],0
  638.     ;mov [buff+1],0
  639.     ;mov [buff+2],0
  640.     mov dword [buff], 0x01000000 ;login Protokol version  00 00 00 01
  641.     ;mov[buff+4],0
  642.     mov word [buff+4], 0x0100; TLV.TYPE = UIN     00 01
  643.  
  644.     lea eax, [vtable + vartable.uin]
  645.     call strlen
  646.     mov [buff+6], ah
  647.     mov [buff+7], al ; Length of UIN
  648.     mov edx, eax
  649.     add edx, 7                 ; в edx длина заполненного буфера
  650.    
  651.     mov ecx, eax              ;Длина строки
  652.  
  653.     lea eax, [vtable + vartable.uin]
  654.     lea ebx, [buff+8]         ; + размер данных в буфере + 1
  655.  
  656.     call strcpy
  657.  
  658.    
  659.     lea eax, [vtable + vartable.pass]
  660.     call roast
  661.    
  662.     mov [buff+edx+2], 2 ; TLV.TYPE - rosted password
  663.     call strlen
  664.     mov [buff+edx+4], al
  665.     mov [buff+edx+3], ah  ; Length of pass
  666.  
  667.     add edx, 4
  668.     mov ebx, buff
  669.     add ebx, edx               ; назначение
  670.     add edx, eax               ; Сохраняем в EDX длину заполненного буфнра
  671.     mov ecx, eax               ; Длина строки
  672.     lea eax, [vtable + vartable.pass]              ; Источник
  673.     inc ebx
  674.     call strcpy
  675.    
  676.     mov [buff+edx+2], 3 ; TLV.TYPE - client id string
  677.     mov eax, ID_STRING
  678.     call strlen
  679.     mov [buff+edx+4], al
  680.     mov [buff+edx+3], ah
  681.  
  682.     add edx, 4
  683.     mov ecx, eax
  684.     mov ebx, buff
  685.     add ebx, edx
  686.     add edx, eax
  687.     inc ebx
  688.     mov eax, ID_STRING
  689.     call strcpy
  690.  
  691.     xor eax, eax
  692.  
  693.     mov [buff+edx+2], 016h  ; TLV.TYPE - Client id
  694.     mov [buff+edx+4], 2
  695.     mov ax, ID_NUM
  696.     call htons
  697.     mov word [buff+edx+5], ax
  698.     add edx, 6
  699.  
  700.     mov [buff+edx+2], 017h ; Client major version
  701.     mov [buff+edx+4], 2
  702.     mov ax, MAJOR
  703.     call htons
  704.     mov word [buff+edx+5], ax
  705.     add edx, 6
  706.  
  707.     mov [buff+edx+2], 018h ; Client minor version
  708.     mov [buff+edx+4], 2
  709.     mov ax, MINOR
  710.     call htons
  711.     mov word [buff+edx+5], ax
  712.     add edx, 6
  713.  
  714.     mov [buff+edx+2], 019h ; Client lesser version
  715.     mov [buff+edx+4], 2
  716.     mov ax, LESSER
  717.     call htons
  718.     mov word [buff+edx+5], ax
  719.     add edx, 6
  720.  
  721.     mov [buff+edx+2], 01Ah ; Client build number
  722.     mov [buff+edx+4], 2
  723.     mov ax, BUILD
  724.     call htons
  725.     mov word [buff+edx+5], ax
  726.     add edx, 6
  727.    
  728.     mov [buff+edx+2], 014h ; Client distribution number
  729.     mov [buff+edx+4], 4
  730.     mov eax, DISTR
  731.     call htonl
  732.     mov dword [buff+edx+5], eax
  733.     add edx, 8
  734.  
  735.     mov [buff+edx+2], 0Fh ; Client language
  736.     mov eax, CL_LANG
  737.     call strlen
  738.     mov word [buff+edx+4], ax
  739.     add edx, 4
  740.     mov ecx, eax
  741.     mov ebx, buff
  742.     add ebx, edx
  743.     inc ebx
  744.     add edx, eax
  745.     mov eax, CL_LANG
  746.     call strcpy
  747.  
  748.     mov [buff+edx+2], 0Eh ; Client country
  749.     mov eax, CL_COUNTRY
  750.     call strlen
  751.     mov word [buff+edx+4], ax
  752.     add edx, 4
  753.     mov ecx, eax
  754.     mov ebx, buff
  755.     add ebx, edx
  756.     inc ebx
  757.     add edx, eax
  758.     mov eax, CL_COUNTRY
  759.     call strcpy
  760.    
  761.    ;write_debug 'Connect attemption'
  762.    ; mov eax, ICQ_IP
  763.    ; call srv_connect
  764.    ; cmp eax, -1   ; Подключение не удалось
  765.    ; jz l_fin
  766.  
  767.    ; mov ecx, eax
  768.    ; mov eax, rflap
  769.    ; mov ebx, lbuff
  770.    ; call recvflap
  771.    
  772.   ;  cmp eax, -1
  773.    ; jz l_flap_err
  774.    ; cmp [rflap.bCh], 01 ; AUTH channel
  775.    ; jnz l_ch_err
  776.    ; cmp eax, 4
  777.    ; jnz l_len_err
  778.    ; cmp dword [lbuff+3], dword 1
  779.    ; jnz l_data_err
  780.  
  781.     mov ecx, [socket]
  782.     inc dx
  783.     mov [flap.wDs], dx ; Data size
  784.     mov eax, flap
  785.     mov ebx, buff
  786.     call sendflap
  787.     cmp eax, 0
  788.     jnz l_fin           ; Неуспех
  789.     jmp l_end
  790.    
  791.  
  792.     s_cookie:
  793.     ;mov eax, rflap
  794.     ;mov ebx, buff
  795.     ;call recvflap
  796.     ;cmp eax, -1
  797.     ;jz l_flap_err
  798.     ;cmp [rflap.bCh], 4
  799.     ;jnz l_ch_err
  800.  
  801.     ;write_debug 'UIN'
  802.     xor ebx, ebx
  803.  
  804.    uin_loop:
  805.     xor eax, eax
  806.     mov ax, word [mbuff+ebx]
  807.     cmp ax, 0100h              ;  00 01 TLV.Type UIN
  808.     jz l_uin_ok                  ;  Теперь сервер передает еще данные при соединении, а потом опять
  809.     add ebx, 5                   ; тот же TLV 1  (новый формат пакекта)
  810.     cmp ebx, 5
  811.     ja l_tlvt_err
  812.     jmp uin_loop
  813.  
  814.  
  815.  
  816.  
  817.  
  818.   l_uin_ok:
  819.     mov eax, ebx
  820.     xor ebx, ebx
  821.     mov bl, [mbuff+eax+3]           ;
  822.     mov bh, [mbuff+eax+2]           ;  Длина данных
  823.     ;
  824.     ;  UIN Пока не проверяется
  825.     ;
  826.    
  827.  
  828.     lea ebx, [ebx+eax+4]
  829.     mov ax, word [mbuff+ebx]
  830.     cmp ax, 0500h             ; 00 05 Bos address
  831.     jz l_all_ok
  832.     cmp ax, 0400h             ; UIN incorrect
  833.     jz l_uin_err
  834.     cmp ax, 0800h
  835.     jz l_pass_err
  836.     jmp l_tlvt_err
  837.     ;
  838.     ; если неверный UIN/ пароль, получаем TLV.TYPE 4/8
  839.     ;
  840.  
  841.     l_all_ok:
  842.     xor ecx, ecx
  843.     mov cl, [mbuff+ebx+3]       ;length
  844.     mov ch, [mbuff+ebx+2]       ;
  845.    
  846.     lea eax, [mbuff+ebx+4]
  847.     push ebx
  848.     mov ebx, bos_address
  849.     call strcpy
  850.     pop ebx
  851.     add ebx, ecx
  852.     lea ebx, [ebx+4]                ; Размер заголовка                
  853.     ;        
  854.     ; cookie
  855.     ;
  856.     ;write_debug 'Login Cookie'
  857.  
  858.     xor eax, eax
  859.     mov ax, word [mbuff+ebx]
  860.     cmp ax, 0600h                  ; TLV.Type cookie
  861.     jnz l_tlvt_err
  862.     mov cl, [mbuff+ebx+3]           ;
  863.     mov ch, [mbuff+ebx+2]           ; Length
  864.     mov [cookie_len], cx
  865.     lea eax, [mbuff+ebx+4]
  866.     push ebx
  867.     mov ebx, srv_cookie
  868.     call strcpy
  869.     pop ebx
  870.            
  871.     ;                        
  872.     ;  Соединяемся с BOS    
  873.     ;                      
  874.     ;call srv_disconnect
  875.     mov ecx, [socket]
  876.     write_debug 'Closing socket'
  877.     ;call closesocket
  878.     ;
  879.     ;
  880.     ;
  881.     ;FIXME!!!
  882.     ;Закомменторовано из-за проблемы с сетевым стеком
  883.     ;закрытие сокета завешивает систему
  884.     ;mcall 53, 8, ecx
  885.  
  886.  
  887.                        
  888.     mov eax, bos_address
  889.     call ip_parser
  890.    
  891.     call htonl
  892.     data_debug 'BOS Address: ', eax
  893.     data_debug 'BOS Port: ', ebx
  894.     mov [bos_ip], eax      
  895.     mov [bos_port], ebx    
  896.     call srv_connect
  897.     mov [login], 1                ; Соединение с основным сервером установлено
  898.     ;mov [socket], eax
  899.                            
  900.  
  901.    
  902.     jmp l_end
  903.     ;
  904.     ;
  905.     ;
  906.     l_pass_err:
  907.     write_debug 'PASSWORD INVALID'
  908.     jmp l_fin
  909.  
  910.     l_uin_err:
  911.     write_debug 'UIN INVALID'
  912.     jmp l_fin
  913.  
  914.     l_data_err:
  915.     write_debug 'LOGIN DATA MISMATCH'
  916.     jmp l_fin
  917.  
  918.     l_len_err:
  919.     write_debug 'RECIVED DATA LENGTH MISMATCH'
  920.     jmp l_fin
  921.  
  922.     l_tlvt_err:
  923.     write_debug 'TLV TYPE MISMATCH'
  924.     jmp l_fin
  925.  
  926.     l_ch_err:
  927.     write_debug 'FLAP CHANNEL MISMATCH'
  928.     jmp l_fin
  929.  
  930.     l_flap_err:
  931.     write_debug 'FLAP ID MISMATCH / RECIVE ERROR'
  932.  
  933.     l_fin:
  934.  
  935.     ;
  936.     ; Необходимо закрыть сокет
  937.     ;
  938.     ;call srv_disconnect
  939.     call closesocket
  940.     l_end:
  941.     pop edx
  942.     ;pop ecx
  943.     pop ebx
  944.     pop eax
  945.     popf                          
  946.   ret                
  947.  
  948. ;
  949. ; Length of string
  950. ; input eax = offset string
  951. ; output eax = strlen
  952. ;
  953.   strlen:
  954.     push ebx
  955.     push ecx
  956.     pushf
  957.     xor ebx, ebx
  958.     xor ecx, ecx
  959.  
  960.     loop_s:
  961.     mov cl, [eax+ebx]
  962.     cmp ecx,0
  963.     jz  nl
  964.     inc ebx
  965.     jmp loop_s
  966.  
  967.     nl:
  968.     mov eax, ebx
  969.     popf
  970.     pop ecx
  971.     pop ebx
  972.   ret
  973.  
  974. ;
  975. ; Roasting password
  976. ; EAX = offset password
  977. ;
  978.  
  979.   roast:
  980.     pushf
  981.     push ecx
  982.     push ebx
  983.  
  984.     xor ecx, ecx
  985.     xor ebx, ebx
  986.  
  987.     loop_r:
  988.     mov bl, [eax+ecx] ;Символ из массива пароля
  989.     cmp bl, 0         ;Конец строки
  990.     jz r_fin
  991.    
  992.     xor bl, [ROASTING_ARRAY+ecx]
  993.     mov [eax+ecx], bl
  994.     inc ecx
  995.     jmp loop_r
  996.  
  997.     r_fin:
  998.     pop ebx
  999.     pop ecx
  1000.     popf
  1001.   ret
  1002.  
  1003.  
  1004. ;
  1005. ;Copy string of bytes
  1006. ;В EAX = адрес исходной строки
  1007. ;В EBX = адрес назначения
  1008. ;В ECX = длина строки
  1009. ;
  1010.   strcpy:
  1011.     pushf
  1012.     push esi
  1013.     push edi
  1014.     push ecx
  1015.  
  1016.     cld      ;Обрабатываем строку от начала к концу
  1017.     mov esi, eax
  1018.     mov edi, ebx
  1019.  
  1020.     rep movsb
  1021.  
  1022.     pop ecx
  1023.     pop edi
  1024.     pop esi
  1025.     popf    
  1026.   ret
  1027.  
  1028.  
  1029. ;
  1030. ; Макрос для сравнения строк
  1031. ;
  1032. macro strcmp first, second, len
  1033. {
  1034.    push ecx
  1035.    push esi
  1036.    push edi
  1037.  
  1038.    mov ecx, len
  1039.    mov esi, first
  1040.    mov edi, second
  1041.    repe cmpsb
  1042.  
  1043.    pop edi
  1044.    pop esi
  1045.    pop ecx
  1046.  
  1047. }
  1048.  
  1049.  
  1050. ;
  1051. ; Заполняет буфер, по адресу в ebx
  1052. ; данными, по адресу eax, в
  1053. ; cx  - Тип TLV
  1054. ; dx  - длина данных
  1055. ;
  1056. ;
  1057.  
  1058.   tlvstr:
  1059.     ;pushf
  1060.     push edx
  1061.     push ecx
  1062.     push ebx
  1063.  
  1064.     mov [ebx], ch     ; Type
  1065.     mov [ebx+1], cl
  1066.  
  1067.     mov [ebx+2], dh   ; Length
  1068.     mov [ebx+3], dl
  1069.    
  1070.     lea ebx, [ebx+4]
  1071.     ; EBX = offset of destination
  1072.     mov ecx, edx
  1073.  
  1074.     call strcpy
  1075.  
  1076.     pop ebx
  1077.     pop ecx
  1078.     pop edx
  1079.     ;popf
  1080.   ret
  1081.  
  1082. ;
  1083. ; eax - указатель на FLAP_head
  1084. ; ebx - указатель на массив, заполненный данными
  1085. ; ecx - хендл сокета
  1086. ;
  1087. ; В eax возвращает результат записи в сокет
  1088. ;
  1089.   sendflap:
  1090.     pushf
  1091.     push edx
  1092.     ;push ecx
  1093.     push esi
  1094.     push ebx
  1095.     push ecx
  1096.  
  1097.     xor edx, edx
  1098.  
  1099.     mov dl, [eax]          ; ID byte
  1100.     mov [sbuff], dl
  1101.  
  1102.     mov dl, [eax+1]        ; FLAP channel
  1103.     mov [sbuff+1], dl
  1104.  
  1105.     mov dl, [eax+2]        ; FLAP datagramm seq number
  1106.     mov [sbuff+3], dl      ; меняем местами байты для передачи по сети
  1107.     mov dl, [eax+3]
  1108.     mov [sbuff+2], dl
  1109.  
  1110.     mov dl, [eax+4]        ; FLAP data size
  1111.     mov [sbuff+5], dl
  1112.     mov dl, [eax+5]
  1113.     mov [sbuff+4], dl
  1114.     mov dx, word [eax+4]
  1115.  
  1116.     xchg ecx, edx           ; ecx - size edx - handle
  1117.     mov eax, ebx            ; data
  1118.     mov ebx, sbuff          ; dest
  1119.     add ebx, 6              ; + header size
  1120.     call strcpy
  1121.  
  1122.     xchg ecx, edx           ; ecx - handle, edx - data size
  1123.  
  1124.     s_wait:
  1125.     ;mov eax, 53             ; Проверяем состояние сокета. Если соедиение
  1126.     ;mov ebx, 6              ; установлено - посылаем буфер, если сокет закрыт, уходим
  1127.     ;int 40h
  1128.     mcall 53, 6, ecx
  1129.     cmp eax, TCB_ESTABLISHED ; установлено
  1130.     jz s_est
  1131.     cmp eax, TCB_CLOSED
  1132.     jz s_fin
  1133.     cmp eax, 12            ;  У меня такое было, когда соединение устанавливалось с пустотой :-)
  1134.     jnc s_fin              ;
  1135.  
  1136.    
  1137.     ;mov eax, 5
  1138.     ;mov ebx, 1
  1139.     ;int 40h                ; Ждем
  1140.     mcall 5, 1
  1141.     jmp s_wait
  1142.  
  1143.  
  1144.     s_est:
  1145.     ;mov eax, 53
  1146.     ;mov ebx, 7             ; писать в сокет
  1147.  
  1148.     add edx, 6             ; + size of header
  1149.     ;mov esi, sbuff         ; data
  1150.     ;int 40h
  1151.     mcall 53, 7, ecx, edx, sbuff
  1152.  
  1153.     s_fin:
  1154.     pop ecx
  1155.     pop ebx
  1156.     pop esi
  1157.     ;pop ecx
  1158.     pop edx
  1159.     popf
  1160.   ret
  1161.  
  1162.  
  1163. ;
  1164. ; eax - указатель на буфер
  1165. ; ebx - значение, которым необходимо затолнить. Используется только bl
  1166. ; ecx - размер
  1167. ;
  1168.  
  1169.   memset:
  1170.     pushf
  1171.     push edi
  1172.     push eax
  1173.     push ebx
  1174.     push ecx
  1175.  
  1176.     cld
  1177.     mov edi, eax
  1178.     mov eax, ebx
  1179.     rep stosb
  1180.  
  1181.     pop ecx
  1182.     pop ebx
  1183.     pop eax
  1184.     pop edi
  1185.     popf
  1186.   ret
  1187.  
  1188. ;
  1189. ; Парсим TLV
  1190. ; <-- в eax адрес TLV
  1191. ; <-- в ebx адрес буфера, который нужно заполнить
  1192. ; --> в ebx длина полученных данных
  1193. ; --> в eax тип TLV
  1194. ;
  1195.  
  1196.   tlvpar:
  1197.     pushf
  1198.     ;push esi
  1199.     ;push edi
  1200.     push ecx
  1201.     xor ecx, ecx
  1202.  
  1203.     mov cl, [eax+3]  ;TLV.Length
  1204.     mov ch, [eax+2]
  1205.     call strcpy
  1206.  
  1207.     xor eax, eax
  1208.     mov al, [ebx+1]  ;TLV.Type
  1209.     mov ah, [ebx]
  1210.     mov ebx, ecx
  1211.  
  1212.  
  1213.     pop ecx
  1214.     ;pop edi
  1215.     ;pop esi
  1216.     popf
  1217.   ret
  1218.  
  1219. ;
  1220. ;  <-- ECX - хендл сокета, который нужно закрыть
  1221. ;  --> ECX - Результат (Ненадежно)
  1222. ;
  1223.   closesocket:
  1224.     push eax
  1225.     ;push ebx
  1226.  
  1227.     ;mov eax, 53
  1228.     ;mov ebx, 8
  1229.     ;int 40h
  1230.     mcall 53, 8, ecx
  1231.  
  1232.     mov ecx, eax
  1233.  
  1234.     ;pop ebx
  1235.     pop eax
  1236.   ret
  1237.  
  1238. ;
  1239. ; ecx <-- хендл сокета
  1240. ;
  1241. ;
  1242.  
  1243.   srv_disconnect:
  1244.     pushf
  1245.     push eax
  1246.     push ebx
  1247.     mov [flap.bId], FLAP_ID
  1248.     mov [flap.bCh], 4      ;Disconnect
  1249.     xor eax, eax
  1250.     mov ax, [seq]
  1251.     mov [flap.wSn], ax
  1252.     mov [flap.wDs], 0
  1253.     mov eax, flap
  1254.     mov ebx, buff
  1255.     call sendflap
  1256.  
  1257.  
  1258.     pop ebx
  1259.     pop eax
  1260.     popf
  1261.   ret
  1262.  
  1263. ;
  1264. ; <-- eax [bos_address]
  1265. ; --> eax = IP ADDRESS
  1266. ; --> ebx = port number
  1267. ;
  1268. par_buff db 9 dup 0
  1269.  
  1270.   ip_parser:
  1271.     pushf
  1272.     push ecx
  1273.     push edx
  1274.     push esi
  1275.     push edi
  1276.  
  1277.     xor ecx, ecx
  1278.     ;xor eax, eax
  1279.     mov ebx, eax
  1280.     xor edx, edx
  1281.     xor esi, esi
  1282.     xor edi, edi
  1283.    
  1284.     ip_loop:
  1285.     xor eax, eax
  1286.     ;xor edx, edx
  1287.     mov al, [ebx+ecx]
  1288.     cmp al, '.'
  1289.     jz ip_dot
  1290.    
  1291.     cmp al, 0
  1292.     jz ip_end_str
  1293.    
  1294.     cmp al, ':'
  1295.     jz ip_colon
  1296.    
  1297.     ;sub al, 30h
  1298.     ;cmp al, 9
  1299.     ;ja ip_err        ; Не цифра
  1300.    
  1301.     mov [par_buff+edx], al
  1302.     inc ecx
  1303.     inc edx
  1304.     jmp ip_loop
  1305.  
  1306.     ip_dot:
  1307.     ;xor eax, eax
  1308.     mov [par_buff+edx], 0 ; Конец строки
  1309.     mov eax, par_buff
  1310.     call ascitoint
  1311.  
  1312.     ;data_debug 'Debug eax: ', eax
  1313.  
  1314.     cmp ecx, 0       ; Не может начинаться с точки
  1315.     jz ip_err
  1316.     shl esi, 8       ; Сдвигаем предыдущий байт
  1317.     add esi, eax
  1318.     inc ecx
  1319.     xor edx, edx     ; Счетчик буфера = 0
  1320.     jmp ip_loop
  1321.  
  1322.  
  1323.     ip_colon:         ; : В строке адреса
  1324.     inc edi           ; Было :
  1325.     jmp ip_dot
  1326.    
  1327.     ip_end_str:
  1328.     cmp edi, 1
  1329.     jz @f
  1330.                           ; : Не было
  1331.     mov [par_buff+edx], 0 ; Конец строки
  1332.     mov eax, par_buff
  1333.     call ascitoint
  1334.     shl esi, 8       ; Сдвигаем предыдущий байт
  1335.     add esi, eax
  1336.     ;mov eax, esi     ; IP в 16 ричной форме
  1337.     xor ebx, ebx    ; Номера порта нет
  1338.     jmp ip_end
  1339.  
  1340.     @@:                            ; Было :
  1341.     mov [par_buff+edx], 0          
  1342.     mov eax, par_buff
  1343.     call ascitoint
  1344.     mov ebx, eax
  1345.     jmp ip_end
  1346.  
  1347.     ip_err:
  1348.     xor esi, esi
  1349.  
  1350.     ip_end:
  1351.     mov eax, esi
  1352.  
  1353.     pop edi
  1354.     pop esi
  1355.     pop edx
  1356.     pop ecx
  1357.     popf
  1358.   ret
  1359.  
  1360. ;
  1361. ; <-- eax указатель на asci
  1362. ; --> eax int
  1363. ;
  1364.   ascitoint:
  1365.     pushf
  1366.     push ebx
  1367.     push ecx
  1368.     push edx
  1369.     push esi
  1370.     push edi
  1371.  
  1372.     xor ebx, ebx  
  1373.     xor ecx, ecx
  1374.     xor edx, edx
  1375.     ;xor esi, esi
  1376.     xor edi, edi
  1377.    
  1378.     ati_loop:
  1379.     mov bl, [eax+ecx]
  1380.     cmp bl, 0         ; Конец строки
  1381.     jz ati_str_end
  1382.     cmp bl, 39h
  1383.     ja ati_err        ; Не цифра
  1384.     cmp bl, 30h
  1385.     jb ati_err
  1386.  
  1387.     inc ecx
  1388.     jmp ati_loop
  1389.  
  1390.     ati_str_end:      ; В ecx длина строки
  1391.     ;dec ecx           ; Установим на последний символ
  1392.     add eax, ecx      ; Указатель на строку + Длина строки
  1393.     dec eax
  1394.    
  1395.     ati_loop2:
  1396.     cmp edx, ecx
  1397.     jz ati_all
  1398.     push eax
  1399.     sub eax, edx              ; Вычесть счетчик
  1400.     movzx ebx, byte [eax]     ; В bl символ
  1401.     ;pop eax
  1402.     sub bl, 30h       ; Вычисляем 10тичную цифру
  1403.  
  1404.     ;push eax
  1405.     mov eax, ebx     ; В eax - цифра
  1406.     mov ebx, 10      ; Множитель
  1407.  
  1408.     xor esi, esi
  1409.  
  1410.     ati_mul:
  1411.  
  1412.     cmp esi, edx     ; Умножаем на 10 n раз
  1413.     jz ati_mul_end
  1414.     ;push eax
  1415.     ;mov eax, ebx
  1416.     imul eax, ebx
  1417.     ;mov ebx, eax
  1418.     ;pop eax
  1419.     inc esi
  1420.     jmp ati_mul
  1421.  
  1422.  
  1423.     ati_mul_end:
  1424.     mov ebx, eax    ; В ebx вычисленное число
  1425.     pop eax
  1426.  
  1427.     add edi, ebx
  1428.     inc edx
  1429.     jmp ati_loop2
  1430.  
  1431.     ati_all:
  1432.     mov eax, edi
  1433.     jmp ati_end
  1434.  
  1435.     ati_err:
  1436.  
  1437.     ;ati_str_end:
  1438.     xor eax, eax
  1439.  
  1440.     ati_end:
  1441.     pop edi
  1442.     pop esi
  1443.     pop edx
  1444.     pop ecx
  1445.     pop ebx
  1446.     popf
  1447.   ret
  1448.  
  1449. ;
  1450. ;
  1451. ; <-- ecx хендл сокета
  1452. ; <-- eax указатель на структуру SNAC_head
  1453. ; <-- ebx указатель на данные
  1454. ; <-- edx размер данных
  1455. ; --> eax результат записи в сокет
  1456. ;
  1457.  
  1458. snac_buff db 1024 dup 0
  1459.  
  1460.   sendsnac:
  1461.     pushf
  1462.     push esi
  1463.     push edi
  1464.     push ebx
  1465.     push edx
  1466.     ;xor ebx, ebx
  1467.     mov esi, ecx            ; хендл сокета
  1468.     mov edi, ebx            ; Указатель на данные
  1469.  
  1470.     xor ebx, ebx
  1471.     mov bl, [eax]           ;
  1472.     mov [snac_buff+1], bl   ; Family ID
  1473.     mov bl, [eax+1]         ; Конвертируется в BigEndian
  1474.     mov [snac_buff], bl     ;
  1475.  
  1476.     mov bl, [eax+2]         ;
  1477.     mov [snac_buff+3], bl   ; Subtype ID
  1478.     mov bl, [eax+3]         ;
  1479.     mov [snac_buff+2], bl   ;
  1480.    
  1481.     mov bl, [eax+4]         ;
  1482.     mov [snac_buff+5], bl   ;
  1483.     mov bl, [eax+5]         ; Flags
  1484.     mov [snac_buff+4], bl   ;
  1485.  
  1486.     mov bl, [eax+6]         ;
  1487.     mov [snac_buff+9], bl   ;
  1488.     mov bl, [eax+7]         ;
  1489.     mov [snac_buff+8], bl   ;
  1490.     mov bl, [eax+8]         ; Reqest ID
  1491.     mov [snac_buff+7], bl   ;
  1492.     mov bl, [eax+9]         ;
  1493.     mov [snac_buff+6], bl   ;
  1494.  
  1495.     lea ebx, [snac_buff+10]                              
  1496.  
  1497.     mov eax, edi            ; Указатель на данные
  1498.     ;add ebx, 10             ; + размер заголовка SNAC
  1499.     mov ecx, edx            ; размер данных
  1500.     call strcpy
  1501.  
  1502.  
  1503.     mov ecx, esi            ; Хендл сокета
  1504.     mov [flap.bId], FLAP_ID
  1505.     mov [flap.bCh], 2       ; Канал для посылки SNAC
  1506.     xor ebx, ebx
  1507.     inc [seq]               ; seq Увеличивается на 1 при каждой посылке
  1508.     mov bx, [seq]
  1509.     mov [flap.wSn], bx
  1510.     add edx, 10             ; размер данных + размер заголовка SNAC
  1511.     mov [flap.wDs], dx
  1512.     mov eax, flap
  1513.     mov ebx, snac_buff
  1514.     call sendflap
  1515.  
  1516.     pop edx
  1517.     pop ebx
  1518.     pop edi
  1519.     pop esi
  1520.     popf
  1521.   ret
  1522.  
  1523.  
  1524.  
  1525. ; Обработка всех пактов, приходящих от сервера
  1526. ; ECX <-- Хендл сокета
  1527. ;
  1528. ;
  1529. ;
  1530. ;
  1531. ;        
  1532.   main_loop:
  1533.     pushf
  1534.     ;push eax
  1535.     ;push ebx
  1536.     ;push edx
  1537.     pushad
  1538.  
  1539.     mov ecx, [socket]
  1540.     ;
  1541.     ;  ждем пакет
  1542.     ;
  1543.   ;m_loop:
  1544.     ;mov eax, 53
  1545.     ;mov ebx, 2
  1546.     ;int 40h
  1547.     ;cmp eax, 6       ; размер заголоака FLAP
  1548.     ;jnc recived      ; >=
  1549.     ;
  1550.     ; Уходим
  1551.     ;
  1552.     ;jmp m_fin
  1553.     ;mov eax, 5
  1554.     ;mov ebx, 5
  1555.     ;int 40h
  1556.     ;jmp m_loop
  1557.     ;
  1558.     ;  есть пакет
  1559.     ;
  1560.   ;recived:
  1561.     ;mov eax, rflap
  1562.     ;mov ebx, rbuff
  1563.     ;call recvflap
  1564.     ;
  1565.     ; Определяем тип принятого FLAP
  1566.     ;
  1567.     xor ebx, ebx
  1568.     mov bl, [rflap.bCh]
  1569.     cmp bl, 1                ; Установка соединения
  1570.     jz  m_login
  1571.     cmp bl, 2
  1572.     jz m_snac                ; Получен SNAC
  1573.     cmp bl, 3
  1574.     jz m_flap_err            ; FLAP-level error
  1575.     cmp bl, 4
  1576.     jz m_close_conn          ; Закрытие соединения
  1577.     cmp bl, 5
  1578.     jz m_keep_alive          ;
  1579.     ;
  1580.     ; Обработка рассоединения
  1581.     ;
  1582.   m_close_conn:
  1583.     write_debug 'Another Computer Use YOUR UIN!'
  1584.     call srv_disconnect
  1585.     call closesocket
  1586.     jmp m_fin
  1587.     ;
  1588.     ; обработка соединения
  1589.     ;
  1590.   m_login:
  1591.     ;
  1592.     ; проверяем версию протокола
  1593.     ;
  1594.     xor eax, eax
  1595.     mov al, [mbuff+3]
  1596.     cmp eax, 1
  1597.     jnz m_login_other    ; Не подходит
  1598.  
  1599.  
  1600.     ;
  1601.     ; генерируем случайный seq
  1602.     ; Для этого берем время, прошедшее с момента запуска системы
  1603.     ;
  1604.     ;mov eax, 26
  1605.     ;mov ebx, 9
  1606.     ;int 40h
  1607.     mcall 26, 9
  1608.     mov [seq], ax
  1609.     ;
  1610.     ; Отдаем серверу cookie
  1611.     ;
  1612.     mov [flap.bCh], 1
  1613.     mov [flap.wSn], ax
  1614.     xor eax, eax
  1615.     mov ax, [cookie_len]
  1616.     add eax, 8            ; TLV len + protocol version len
  1617.     mov [flap.wDs], ax
  1618.     mov dword [buff], 01000000h  ; 00 00 00 01 Номер протокола
  1619.     mov word [buff+4], 0600h     ; 00 06   TLV.Type
  1620.  
  1621.     mov ax, [cookie_len]
  1622.     mov [buff+6], ah             ;
  1623.     mov [buff+7], al             ; TLV.Length
  1624.  
  1625.     mov edx, ecx                 ; edx <-- socket handle
  1626.  
  1627.     mov ecx, eax                 ; ecx <-- cookie len
  1628.     mov eax, srv_cookie          ; Src
  1629.     lea ebx, [buff+8]
  1630.     call strcpy
  1631.    
  1632.     mov ecx, edx                 ; ecx <-- socket handle
  1633.     mov eax, flap
  1634.     mov ebx, buff
  1635.     call sendflap
  1636.     jmp m_fin
  1637.  
  1638.     m_login_other:
  1639.     jmp m_fin
  1640.  
  1641.     ;
  1642.     ; Как обработать ошибку, я не знаю
  1643.     ;
  1644.   m_flap_err:
  1645.   jmp m_fin
  1646.  
  1647.     ;
  1648.     ; Пока не обрабатывается
  1649.     ;
  1650.   m_keep_alive:
  1651.   jmp m_fin
  1652.  
  1653.  
  1654.     ;
  1655.     ; Получен SNAC
  1656.     ; Распознаем его тип
  1657.     ;
  1658.   m_snac:
  1659.     mov eax, rsnac
  1660.     mov ebx, mbuff
  1661.     call snacpar
  1662.     xor ebx, ebx
  1663.     xor edx, edx
  1664.     mov bx, [rsnac.wFid]
  1665.     mov dx, [rsnac.wSid]
  1666.  
  1667.     cmp bx, 1
  1668.     jz m_snac_1              ;Generic service controls
  1669.     cmp bx, 2
  1670.     jz m_snac_2              ;Location services
  1671.     cmp bx, 3
  1672.     jz m_snac_3              ;Buddy List management service
  1673.     cmp bx, 4
  1674.     jz m_snac_4              ;ICBM (messages) service
  1675.     cmp bx, 9
  1676.     jz m_snac_9              ;Privacy management service
  1677.     cmp bx, 015h
  1678.     jz m_snac_15             ;ICQ specific extensions service
  1679.     cmp bx, 013h
  1680.     jz m_snac_13             ;Server Side Information (SSI) service
  1681.    
  1682.     jmp m_other_snac
  1683.     ;
  1684.     ;   FAMILY 1
  1685.     ;
  1686.   m_snac_1:
  1687.     cmp dx, 7
  1688.     jz m_snac_1_7
  1689.     cmp dx, 3
  1690.     jz m_snac_1_3
  1691.     cmp dx, 018h
  1692.     jz m_snac_1_18
  1693.     cmp dx, 01Fh
  1694.     jz m_snac_1_f
  1695.     cmp dx, 13h
  1696.     jz m_snac_13
  1697.     cmp dx, 1
  1698.     jz m_snac_1_1
  1699.     jmp m_snac_1_other
  1700.     ;
  1701.     ; Rate limits information response
  1702.     ;
  1703.   m_snac_1_7:              ; Отвечаем
  1704.     mov [ssnac.wFid], 1    ; Family
  1705.     mov [ssnac.wSid], 8    ; Subtype
  1706.     mov [ssnac.dRi], 8
  1707.     mov word [buff], 0100h   ; 0001
  1708.     mov word [buff+2], 0200h ; 0002
  1709.     mov word [buff+4], 0300h ; 0003
  1710.     mov word [buff+6], 0400h ; 0004
  1711.     mov word [buff+8], 0500h ; 0005
  1712.     mov eax, ssnac
  1713.     mov ebx, buff
  1714.     mov edx, 10              ; Размер данных
  1715.     call sendsnac
  1716.     ;
  1717.     ; Client ask server location service limitations
  1718.     ;
  1719.     mov [ssnac.wFid], 2    ; Family
  1720.     mov [ssnac.wSid], 2    ; Subtype
  1721.     mov [ssnac.dRi], 2
  1722.     mov eax, ssnac
  1723.     mov ebx, buff
  1724.     xor edx, edx
  1725.     call sendsnac
  1726.  
  1727.     jmp m_fin
  1728.  
  1729.     ;
  1730.     ;  Server supported snac families list
  1731.     ;
  1732.   m_snac_1_3:
  1733.     ;
  1734.     ;  Server sends supported services list
  1735.     ;
  1736.  
  1737.     ;
  1738.     ;   SNAC(01,17)      
  1739.     ;   Client ask for services version numbers
  1740.     ;
  1741.     mov [ssnac.wFid], 1    ; Family
  1742.     mov [ssnac.wSid], 17h    ; Subtype
  1743.     mov [ssnac.dRi], 17h
  1744.     ;
  1745.     ;   Список сервисов, которые нам нужны
  1746.     ;
  1747.     ;    xx xx          word            family number #1
  1748.     ;    xx xx          word            family version
  1749.     ;      ...           ...             ...
  1750.     ;
  1751.  
  1752.     ;
  1753.     ; Поправил из дампа &RQ
  1754.     ;
  1755.     mov word [buff], 0100h   ; 0001
  1756.     mov word [buff+2], 0300h ; 0003
  1757.  
  1758.     mov word [buff+4], 1300h ; 0013
  1759.     mov word [buff+6], 0200h ; 0002
  1760.  
  1761.     mov word [buff+8], 0200h ; 0002
  1762.     mov word [buff+10], 0100h ; 0001
  1763.  
  1764.     mov word [buff+12], 0300h ; 0002
  1765.     mov word [buff+14], 0100h ; 0001
  1766.  
  1767.     mov word [buff+16], 1500h ; 0015
  1768.     mov word [buff+18], 0100h ; 0001
  1769.  
  1770.     mov word [buff+20], 0400h ; 0004
  1771.     mov word [buff+22], 0100h ; 0001
  1772.  
  1773.     mov word [buff+24], 0600h ; 0006
  1774.     mov word [buff+26], 0100h ; 0001
  1775.  
  1776.     mov word [buff+28], 0900h ; 0009
  1777.     mov word [buff+30], 0100h ; 0001
  1778.  
  1779.     mov word [buff+32], 1300h ; 0013
  1780.     mov word [buff+34], 0400h ; 0004
  1781.  
  1782.     mov word [buff+36], 1500h ; 0015
  1783.     mov word [buff+38], 0400h ; 0004
  1784.  
  1785.     mov word [buff+40], 1000h ; 0010
  1786.     mov word [buff+42], 0100h ; 0001
  1787.  
  1788.  
  1789.  
  1790.     mov eax, ssnac
  1791.     mov ebx, buff
  1792.     mov edx, 44
  1793.     call sendsnac
  1794.  
  1795.     jmp m_fin
  1796.  
  1797.  
  1798.     ;
  1799.     ; Server services versions
  1800.     ;
  1801.   m_snac_1_18:
  1802.     ;
  1803.     ; Обработки пока нет
  1804.     ;
  1805.  
  1806.     ;
  1807.     ; Client ask server for rate limits info
  1808.     ; SNAC(01,06)
  1809.     ;
  1810.     mov [ssnac.wFid], 1    ; Family
  1811.     mov [ssnac.wSid], 6    ; Subtype
  1812.     mov [ssnac.dRi], 6
  1813.     mov eax, ssnac
  1814.     mov ebx, buff
  1815.     xor edx, edx
  1816.     call sendsnac
  1817.  
  1818.  
  1819.  
  1820.     jmp m_fin
  1821.  
  1822.     ;
  1823.     ; Requested online info response
  1824.     ;
  1825.   m_snac_1_f:
  1826.     ;
  1827.     ;Тут должна быть наша информация, пока обработки нет
  1828.     ;
  1829.  
  1830.  
  1831.     jmp m_fin
  1832.  
  1833.     ;
  1834.     ; Message of the day (MOTD)
  1835.     ;
  1836.   m_snac_1_13:
  1837.     ;
  1838.     ; Нечего обрабатывать :-))
  1839.     ;
  1840.     jmp m_fin
  1841.  
  1842.     ;
  1843.     ; Сообщение об ошибке
  1844.     ;
  1845.  
  1846.   m_snac_1_1:
  1847.     xor eax, eax
  1848.     mov ax, word [mbuff+10]
  1849.     call ntohs
  1850.     data_debug 'SERVER SEND ERROR #', eax
  1851.  
  1852.  
  1853.     jmp m_fin
  1854.  
  1855.  
  1856.   m_snac_1_other:
  1857.      data_debug 'Unknown SNAC Family 1 recived, type ', edx
  1858.      jmp m_fin
  1859.  
  1860.  
  1861.  
  1862.     ;
  1863.     ; Family 2
  1864.     ;
  1865.   m_snac_2:
  1866.     cmp dx, 3
  1867.     jz m_snac_2_3
  1868.     jmp m_snac_2_other
  1869.     ;
  1870.     ; Server replies via location service limitations
  1871.     ;
  1872.   m_snac_2_3:
  1873.     ;
  1874.     ;  Обработки пока нет
  1875.     ;
  1876.  
  1877.     ;
  1878.     ;  посылаем capabilities / profile
  1879.     ;
  1880.     mov [ssnac.wFid], 2    ; Family
  1881.     mov [ssnac.wSid], 4    ; Subtype
  1882.     mov [ssnac.dRi], 4
  1883.  
  1884.     ;mov eax, CAPABILITIES
  1885.     ;mov ebx, buff
  1886.     ;push ecx
  1887.     ;mov ecx, 5             ; TLV.Type(0x05) - CLSID values
  1888.     ;mov edx, C_LEN
  1889.     ;call tlvstr
  1890.     ;pop ecx
  1891.     mov word [buff], 0500h  ; 00 05
  1892.     mov eax, C_LEN
  1893.     call htons
  1894.     mov word [buff+2], ax
  1895.  
  1896.  
  1897.  
  1898.     push ecx
  1899.  
  1900.     mov eax, CAPABILITIES
  1901.     lea ebx, [buff+4]
  1902.     mov ecx, C_LEN
  1903.     call strcpy
  1904.  
  1905.     pop ecx
  1906.  
  1907.  
  1908.     mov eax, ssnac
  1909.     mov ebx, buff
  1910.     mov edx, C_LEN+4            ; Длина данных+размер заголовка TLV
  1911.     call sendsnac
  1912.  
  1913.     ;
  1914.     ; запрашиваем server BLM service limitations
  1915.     ;
  1916.     mov [ssnac.wFid], 3    ; Family
  1917.     mov [ssnac.wSid], 2    ; Subtype
  1918.     mov [ssnac.dRi], 2
  1919.     mov eax, ssnac
  1920.     mov ebx, buff
  1921.     xor edx, edx
  1922.     call sendsnac
  1923.  
  1924.  
  1925.     jmp m_fin
  1926.  
  1927.   m_snac_2_other:
  1928.     write_debug 'Unknown SNAC Family 2 Recived'
  1929.     jmp m_fin
  1930.  
  1931.  
  1932.  
  1933.     ;
  1934.     ;  FAMILY 3
  1935.     ;
  1936.   m_snac_3:
  1937.     cmp dx, 3
  1938.     jz m_snac_3_3
  1939.     cmp dx, 0Bh
  1940.     jz m_snac_3_b
  1941.     cmp dx, 0Ch
  1942.     jz m_snac_3_c
  1943.     jmp m_snac_3_other
  1944.  
  1945.     ;
  1946.     ; Server replies via BLM service limitations
  1947.     ;
  1948.   m_snac_3_3:
  1949.     ;
  1950.     ; Обработки пока нет
  1951.     ;
  1952.  
  1953.     ;
  1954.     ; Client ask server for ICBM service parameters
  1955.     ;
  1956.     mov [ssnac.wFid], 4    ; Family
  1957.     mov [ssnac.wSid], 4    ; Subtype
  1958.     mov [ssnac.dRi], 4     ; request-id
  1959.     mov eax, ssnac
  1960.     mov ebx, buff
  1961.     xor edx, edx
  1962.     call sendsnac
  1963.  
  1964.  
  1965.  
  1966.     jmp m_fin
  1967.  
  1968.     ;
  1969.     ;  User online notification
  1970.     ;
  1971.   m_snac_3_b:
  1972.     ;
  1973.     ; Из всей информации пока нужен только статус
  1974.     ;
  1975.     xor edx, edx           ; Счетчик - номер UIN в массиве
  1976.     xor ecx, ecx
  1977.     xor eax, eax
  1978.     cld             ; В направлении увеличения адресов
  1979.  
  1980.     dec edx
  1981.   m_snac_3_b_loop:
  1982.     inc edx
  1983.     cmp edx, UINS
  1984.     jnc m_snac_3_b_end     ;>=
  1985.  
  1986.     mov cl, [mbuff+10]     ; Длина УИН
  1987.     mov eax, ecx
  1988.     mov edi, UIN_LEN
  1989.     imul edi, edx
  1990.     lea edi, [uins+edi]    
  1991.     lea esi, [mbuff+11]
  1992.     repe cmpsb
  1993.    
  1994.     jnz m_snac_3_b_loop
  1995.     ;
  1996.     ; UIN Определен
  1997.     ;
  1998.  
  1999.     ;
  2000.     ; Найти TLV со статусом
  2001.     ; сохранять edx
  2002.  
  2003.     xor esi, esi    ; Счетчик TLV
  2004.  
  2005.     xor ecx, ecx                      
  2006.     mov ch, byte [mbuff + eax + 13]   ; Кол-во TLV в цепочке
  2007.     mov cl, byte [mbuff + eax + 14]   ;
  2008.  
  2009.     lea eax, [eax + 10 + 5]    ; eax указатель на цепочку TLV
  2010.     lea eax, [mbuff + eax]     ;
  2011.  
  2012.  
  2013.   m_snac_3_b_next_tlv:
  2014.     cmp esi, ecx
  2015.     jz m_snac_3_b_endchain
  2016.  
  2017.  
  2018.     xor ebx, ebx
  2019.     mov bh, [eax]              ;
  2020.     mov bl, [eax + 1]          ; TLV.Type
  2021.  
  2022.     data_debug 'TLV type', ebx
  2023.  
  2024.     cmp ebx, 0x06              ;TLV.Type(0x06) - user status
  2025.     jz m_snac_3_b_status
  2026.  
  2027.     ;
  2028.     ; Разбираем цепочку дальше
  2029.     ;
  2030.  
  2031.     get_next_tlv
  2032.     inc esi
  2033.     jmp m_snac_3_b_next_tlv
  2034.  
  2035.  
  2036.  
  2037.     ; FIXME Неоптимально - код будет удален
  2038.     ;
  2039.     ;lea ecx, [eax+10+11]           ; +sizeof SNAC_head + offset #2 TLV
  2040.     ;mov ax, word [mbuff+ecx]            ;#2 TLV.Type
  2041.     ;cmp ax, 0C00h                  ;dc info (optional)
  2042.     ;jz m_snac_3_b_dc
  2043.     ;cmp ax, 0A00h                  ;external ip address
  2044.     ;jz m_snac_3_b_extip
  2045.     ;jmp m_snac_3_b_bad_tlv
  2046.    
  2047.  
  2048.   ;m_snac_3_b_dc:
  2049.     ;
  2050.     ; Пропускаем этот TLV
  2051.     ;
  2052.     ;lea ecx, [ecx+41]
  2053.   ;m_snac_3_b_extip:
  2054.     ;
  2055.     ; И этот :-)
  2056.     ;lea ecx, [ecx+8]
  2057.     ;mov ax, word [mbuff+ecx]
  2058.     ;cmp ax, 0600h                 ;TLV.Type(0x0A) - external ip address
  2059.     ;jz m_snac_3_b_status
  2060.     ;jmp m_snac_3_b_bad_tlv
  2061.     ;
  2062.     ;
  2063.  
  2064.  
  2065.   m_snac_3_b_status:
  2066.     ;
  2067.     ; статус
  2068.     ;
  2069.     mov ecx, eax
  2070.     mov eax, dword [ecx + 4]
  2071.     ;mov eax, dword [mbuff+ecx+4]
  2072.     call ntohl
  2073.     ;mov ebx, 4
  2074.     ;imul ebx, edx
  2075.     ;mov [stats+ebx], eax
  2076.     mov ecx, eax
  2077.     mov ebx, NAME_LEN
  2078.     imul ebx, edx
  2079.     lea ebx, [names+ebx]
  2080.     mov eax, edx
  2081.     call loadbb
  2082.     jmp m_fin
  2083.  
  2084.  
  2085.   m_snac_3_b_bad_tlv:
  2086.     write_debug 'TLV Type Mismatch in SNAC(3,b)'
  2087.     jmp m_fin
  2088.  
  2089.   m_snac_3_b_end:
  2090.     write_debug 'UIN not in local Contact List'
  2091.     jmp m_fin
  2092.  
  2093.   m_snac_3_b_endchain:
  2094.     jmp m_fin
  2095.  
  2096.  
  2097.  
  2098.   m_snac_3_c:
  2099.     ;
  2100.     ; User offline notification
  2101.     ;
  2102.   xor edx, edx
  2103.   xor ecx, ecx
  2104.  
  2105.     dec edx
  2106.     m_snac_3_c_loop:
  2107.     inc edx
  2108.     cmp edx, UINS
  2109.     jnc m_snac_3_b_end     ;>=
  2110.  
  2111.     mov cl, [mbuff+10]     ; Длина УИН
  2112.     mov edi, UIN_LEN
  2113.     imul edi ,edx
  2114.     lea edi, [uins+edi]    
  2115.     lea esi, [mbuff+11]
  2116.     repe cmpsb
  2117.     jnz m_snac_3_c_loop
  2118.     ;
  2119.     ; UIN Определен
  2120.     ;
  2121.     ;mov eax, -1
  2122.     ;mov ebx, 4
  2123.     ;imul ebx, edx
  2124.     ;mov [stats+ebx], eax
  2125.     mov ecx, -1
  2126.     mov ebx, NAME_LEN
  2127.     imul ebx, edx
  2128.     lea ebx, [names+ebx]
  2129.     mov eax, edx
  2130.     call loadbb
  2131.     jmp m_fin
  2132.  
  2133.  
  2134.  
  2135.  
  2136.  
  2137.  
  2138.   m_snac_3_other:
  2139.     write_debug 'Unknown SNAC Family 3 Recived'
  2140.     jmp m_fin
  2141.  
  2142.  
  2143.     ;
  2144.     ;  FAMILY 4
  2145.     ;
  2146.   m_snac_4:
  2147.     cmp dx, 5
  2148.     jz m_snac_4_5
  2149.     cmp dx, 7
  2150.     jz m_snac_4_7
  2151.     jmp m_snac_4_other
  2152.  
  2153.     ;
  2154.     ;  Server sends ICBM service parameters to client
  2155.     ;
  2156.   m_snac_4_5:
  2157.     ;
  2158.     ;  Обработки пока нет
  2159.     ;
  2160.  
  2161.     ;
  2162.     ;  Client change default ICBM parameters command
  2163.     ;
  2164.     mov [ssnac.wFid], 4    ; Family
  2165.     mov [ssnac.wSid], 2    ; Subtype
  2166.     mov [ssnac.dRi], 2     ; request-id
  2167.  
  2168.     mov eax, ICBM_PARAMS
  2169.     mov ebx, buff
  2170.     push ecx
  2171.     mov ecx, ICBMP_LEN
  2172.     call strcpy
  2173.     pop ecx
  2174.  
  2175.     mov eax, ssnac
  2176.     mov ebx, buff
  2177.     mov edx, ICBMP_LEN
  2178.     call sendsnac
  2179.  
  2180.     ;
  2181.     ;   Client ask server PRM service limitations
  2182.     ;
  2183.     mov [ssnac.wFid], 9    ; Family
  2184.     mov [ssnac.wSid], 2    ; Subtype
  2185.     mov [ssnac.dRi], 2     ; request-id
  2186.     mov eax, ssnac
  2187.     mov ebx, buff
  2188.     xor edx, edx
  2189.     call sendsnac
  2190.  
  2191.  
  2192.     jmp m_fin
  2193.  
  2194.     ;
  2195.     ;  Message for client from server
  2196.     ;
  2197.   m_snac_4_7:
  2198.     ;
  2199.     ;  Определяем тип сообщения по полю message channel
  2200.     ;
  2201.     xor eax, eax
  2202.     mov ax, word [mbuff+10+8]           ; +10 - размер SNAC
  2203.                                         ; +8 смещение до message channel
  2204.     cmp ax, 0100h                       ; 00 01
  2205.     jz m_snac_ch1
  2206.     cmp ax, 0200h
  2207.     jz m_snac_ch2
  2208.     cmp ax, 0400h
  2209.     jz m_snac_ch4
  2210.     jmp m_ch_other
  2211.     ;
  2212.     ;  channel 1 plain text
  2213.     ;
  2214.   m_snac_ch1:
  2215.     ;
  2216.     ; Т.к в очередной раз описание протокола не совпадает с реальностью
  2217.     ; разбираем все TLV по порядку
  2218.  
  2219.     mov eax, dword [mbuff+10]          ; cookie
  2220.     mov [msg_cookie1], eax
  2221.     mov eax, dword [mbuff+10+4]
  2222.     mov [msg_cookie2], eax             ; Используются для потверждения приема сообщений
  2223.  
  2224.     mov al, [mbuff+10+10]              ; Sender UIN length
  2225.     mov [ui.bUinLength], al
  2226.  
  2227.     push ecx
  2228.     movzx ecx, al
  2229.  
  2230.     lea eax, [mbuff+10+11]             ; UIN string
  2231.     lea ebx, [ui.bUin]                 ; Dest
  2232.     call strcpy
  2233.  
  2234.     lea ecx, [ecx+10+15]               ; первый TLV
  2235.    
  2236.  
  2237.  m_snac_ch1_loop:
  2238.  
  2239.     movzx eax, word [mbuff+ecx]
  2240.     cmp eax, 0100h                     ;TLV.Type(0x01) - user class
  2241.     jz m_snac_ch1_1
  2242.     cmp eax, 0600h                     ;TLV.Type(0x06) - user status
  2243.     jz m_snac_ch1_6
  2244.     cmp eax, 0800h                     ; Unknown type
  2245.     jz m_snac_ch1_8
  2246.     cmp eax, 0500h                     ; Unknown type
  2247.     jz m_snac_ch1_5
  2248.     cmp eax, 0F00h                     ; TLV.Type(0x0f) - user idle time
  2249.     jz m_snac_ch1_f
  2250.     cmp eax, 0300h                     ; TLV.Type(0x03) - account creation time
  2251.     jz m_snac_ch1_3
  2252.     cmp eax, 0400h                     ; TLV.Type(0x04) - automated response flag
  2253.     jz m_snac_ch1_4
  2254.     cmp eax, 0200h                     ; TLV.Type(0x02) - message data
  2255.     jz m_snac_ch1_mess
  2256.     jmp m_snac_msg_tlv_err
  2257.  
  2258.     ;
  2259.     ; Возможно, дополнительная ииформация будет обрабатываться
  2260.     ; но пока нет
  2261.  
  2262.   m_snac_ch1_1:
  2263.     movzx eax, word [mbuff+ecx+2]       ; TLV.Length
  2264.     call ntohs
  2265.     lea ecx, [eax+ecx+4]
  2266.     jmp m_snac_ch1_loop
  2267.  
  2268.   m_snac_ch1_6:
  2269.  
  2270.     mov eax, dword [mbuff+ecx+4]            ; User status
  2271.     call ntohl
  2272.     mov [ui.dUserStatus], eax
  2273.  
  2274.  
  2275.     movzx eax, word [mbuff+ecx+2]       ; TLV.Length
  2276.     call ntohs
  2277.     lea ecx, [eax+ecx+4]
  2278.     ;
  2279.     ;
  2280.    
  2281.    
  2282.     jmp m_snac_ch1_loop
  2283.  
  2284.   m_snac_ch1_8:
  2285.     movzx eax, word [mbuff+ecx+2]       ; TLV.Length
  2286.     call ntohs
  2287.     lea ecx, [eax+ecx+4]
  2288.     jmp m_snac_ch1_loop
  2289.  
  2290.   m_snac_ch1_5:
  2291.     movzx eax, word [mbuff+ecx+2]       ; TLV.Length
  2292.     call ntohs
  2293.     lea ecx, [eax+ecx+4]
  2294.     jmp m_snac_ch1_loop
  2295.  
  2296.   m_snac_ch1_f:
  2297.     movzx eax, word [mbuff+ecx+2]       ; TLV.Length
  2298.     call ntohs
  2299.     lea ecx, [eax+ecx+4]
  2300.     jmp m_snac_ch1_loop
  2301.  
  2302.   m_snac_ch1_3:
  2303.     movzx eax, word [mbuff+ecx+2]       ; TLV.Length
  2304.     call ntohs
  2305.     lea ecx, [eax+ecx+4]
  2306.     jmp m_snac_ch1_loop
  2307.  
  2308.  
  2309.   m_snac_ch1_4:
  2310.     ;movzx eax, word [buff+ecx+2]       ; TLV.Length
  2311.     lea ecx, [ecx+4]
  2312.     jmp m_snac_ch1_loop
  2313.  
  2314.  
  2315.  
  2316.   m_snac_ch1_mess:
  2317.     ;
  2318.     ;
  2319.     movzx eax, word [mbuff+ecx+4]    ;
  2320.     cmp eax, 0105h                   ; 05 fragment identifier (array of required capabilities)
  2321.     jnz m_snac_ch1_fr_err            ; 01 fragment version
  2322.  
  2323.     movzx eax, word [mbuff+ecx+6]    ; Length
  2324.     call ntohs
  2325.  
  2326.     lea ecx, [ecx+eax+8]             ; Пропускаем  byte array of required capabilities (1 - text)
  2327.  
  2328.     movzx eax, word [mbuff+ecx]      ;  fragment identifier (message text)
  2329.     cmp eax, 0101h                   ;  fragment version
  2330.     jnz m_snac_ch1_fr_err
  2331.  
  2332.     movzx eax, word [mbuff+ecx+2]    ; TLV Length
  2333.     call ntohs
  2334.     xchg eax, ecx
  2335.  
  2336.     lea eax, [eax+8]                 ; Начало текстового сообщения
  2337.     lea ecx, [ecx-4]                 ; - sizeof Message charset number, Message charset subset
  2338.  
  2339.     push eax
  2340.     push ecx
  2341.  
  2342.     ;
  2343.     ;  Выводим Message From UIN
  2344.     ;
  2345.  
  2346.     mov eax, MESS
  2347.     call strlen
  2348.     mov ecx, eax
  2349.  
  2350.     mov eax, MESS
  2351.     mov ebx, buff
  2352.     call strcpy
  2353.  
  2354.     lea ebx, [ebx + ecx]
  2355.  
  2356.     ;
  2357.     ; Неплохо было бы вывести не UIN а Nickname, если он есть в контакт листе
  2358.     ;
  2359.     xor esi, esi    ; Счетчик
  2360.  
  2361.    m_snac_ch1_next_uin:
  2362.  
  2363.     cmp esi, UINS
  2364.     jz m_snac_ch1_notfound
  2365.  
  2366.     mov edx, UIN_LEN
  2367.     imul edx, esi
  2368.  
  2369.     lea edx, [uins + edx]
  2370.     movzx ecx, byte [ui.bUinLength]
  2371.     strcmp edx, ui.bUin, ecx
  2372.     jz m_snac_ch1_uin
  2373.  
  2374.     inc esi
  2375.     jmp m_snac_ch1_next_uin
  2376.  
  2377.  
  2378.     ;
  2379.     ; Подходящий UIN есть в контакт-листе
  2380.     ;
  2381.    m_snac_ch1_uin:
  2382.  
  2383.     mov edx, NAME_LEN
  2384.     imul edx, esi
  2385.  
  2386.     lea edx, [names + edx]
  2387.     mov eax, edx
  2388.  
  2389.  
  2390.     call strlen
  2391.     mov ecx, eax
  2392.  
  2393.     mov eax, edx
  2394.     call strcpy
  2395.  
  2396.     jmp m_snac_ch1_msgfrom
  2397.  
  2398.  
  2399.     ;
  2400.     ; Если подходящего UIN нет в контакт-листе
  2401.     ;
  2402.    m_snac_ch1_notfound:
  2403.    
  2404.     lea eax, [ui.bUin]
  2405.     movzx ecx, byte [ui.bUinLength]
  2406.     call strcpy
  2407.  
  2408.     ;
  2409.     ; Вывод сообщения "от кого"
  2410.     ;
  2411.    m_snac_ch1_msgfrom:
  2412.  
  2413.     mov [ebx + ecx], byte 0
  2414.  
  2415.     mov eax, buff
  2416.     xor ebx, ebx
  2417.  
  2418.     call writemsg
  2419.     ;
  2420.     ;  Само сообщение
  2421.     ;
  2422.  
  2423.     pop ecx
  2424.     pop eax
  2425.     lea eax, [mbuff+eax]
  2426.  
  2427.     mov ebx, buff
  2428.     call strcpy
  2429.     mov [ebx+ecx], byte 0
  2430.    
  2431.     mov eax, buff
  2432.     call win2dos
  2433.     mov ebx, 00FF0000h
  2434.     call writemsg
  2435.  
  2436.     ;
  2437.     ;  Подтверждаем прием
  2438.     ;
  2439.  
  2440.     pop ecx
  2441.     ;
  2442.     ; Пока не реализовано, т.к. не могу найти клиент, который это использует :-)
  2443.     ;
  2444.  
  2445.     jmp m_fin
  2446.  
  2447.   m_snac_msg_tlv_err:
  2448.     write_debug 'TLV TYPE MISMATCH'
  2449.     pop ecx
  2450.     jmp m_fin
  2451.  
  2452.   m_snac_ch1_fr_err:
  2453.     write_debug 'UNKNOWN FRAGMENT IDENTIFIER OR FRAGMENT VERSION'
  2454.  
  2455.   ;m_snac_ch1_end:
  2456.     pop ecx
  2457.  
  2458.     jmp m_fin
  2459.  
  2460.     ;
  2461.     ;   Channel 2 message format (rtf messages, rendezvous)
  2462.     ;
  2463.   m_snac_ch2:
  2464.     ;
  2465.     ;  отправим сообщение, что канал не поддерживается
  2466.     ;  нужны куки и уин
  2467.     mov eax, dword [mbuff+10]
  2468.     mov [msg_cookie1], eax
  2469.     mov eax, dword [mbuff+10+4]
  2470.     mov [msg_cookie2], eax
  2471.  
  2472.     mov al, [mbuff+10+10]              ; Sender UIN length
  2473.     mov [ui.bUinLength], al
  2474.  
  2475.     push ecx
  2476.     movzx ecx, al
  2477.  
  2478.     lea eax, [mbuff+10+11]             ; UIN string
  2479.     lea ebx, [ui.bUin]                 ; Dest
  2480.     call strcpy
  2481.  
  2482.  
  2483.     mov [ssnac.wFid], 4      ; Family
  2484.     mov [ssnac.wSid], 0Bh    ; Subtype
  2485.     mov [ssnac.dRi], 0Bh
  2486.  
  2487.     mov eax, [msg_cookie1]
  2488.     mov dword [buff], eax
  2489.     mov eax, [msg_cookie2]
  2490.     mov dword [buff+4], eax
  2491.     mov word [buff+8], 0200h      ; Channel 2
  2492.  
  2493.     mov al, [ui.bUinLength]
  2494.     mov [buff+10], al
  2495.     lea eax, [ui.bUin]
  2496.     lea ebx, [buff+11]
  2497.     call strcpy
  2498.     lea ecx, [ecx+11]
  2499.  
  2500.     mov word [buff+ecx], 0100h    ; reason code (1 - unsupported channel, 2 - busted payload, 3 - channel specific)
  2501.     mov edx, ecx
  2502.  
  2503.     pop ecx
  2504.     mov eax, ssnac
  2505.     mov ebx, buff
  2506.     call sendsnac
  2507.  
  2508.  
  2509.     jmp m_fin
  2510.  
  2511.     ;
  2512.     ;  Channel 4 message format (typed old-style messages)
  2513.     ;
  2514.   m_snac_ch4:
  2515.  
  2516.  
  2517.  
  2518.   m_ch_other:
  2519.     write_debug 'Unknown message channel'
  2520.  
  2521.     jmp m_fin
  2522.  
  2523.  
  2524.   m_snac_4_other:
  2525.     write_debug 'Unknown SNAC Family 4 recived'
  2526.     jmp m_fin
  2527.  
  2528.  
  2529.  
  2530.     ;
  2531.     ; FAMILY 9
  2532.     ;
  2533.   m_snac_9:
  2534.     cmp dx, 3
  2535.     jz m_snac_9_3
  2536.     jmp m_snac_9_other
  2537.  
  2538.     ;
  2539.     ; Server sends PRM service limitations to client
  2540.     ;
  2541.   m_snac_9_3:
  2542.     ;
  2543.     ; Обработки пока нет
  2544.     ;
  2545.     if USE_SSI <> 0
  2546.  
  2547.     ;
  2548.     ; Запрос КЛ с сервера
  2549.     ;
  2550.  
  2551.     ;
  2552.     ; Request contact list (first time)
  2553.     ;
  2554.     mov [ssnac.wFid], 13h    ; Family
  2555.     mov [ssnac.wSid], 04h    ; Subtype
  2556.     mov [ssnac.dRi], 04h     ; request-id
  2557.  
  2558.     mov eax, ssnac
  2559.     mov ebx, buff
  2560.     xor edx, edx            
  2561.     call sendsnac
  2562.  
  2563.  
  2564.     else
  2565.  
  2566.  
  2567.     ; Отключено, тк не поддерживается SIQ
  2568.     ;
  2569.  
  2570.     ;
  2571.     ;  Client ask server for SSI service limitations
  2572.     ;
  2573.     ;mov [ssnac.wFid], 13h  ; Family
  2574.     ;mov [ssnac.wSid], 2    ; Subtype
  2575.     ;mov [ssnac.dRi], 2     ; request-id
  2576.     ;mov eax, ssnac
  2577.     ;mov ebx, buff
  2578.     ;xor edx, edx
  2579.     ;call sendsnac
  2580.  
  2581.     ;
  2582.     ; последняя стадия соединения
  2583.     ;
  2584.  
  2585.     ;
  2586.     ; Запрашиваем свою информацию
  2587.     ;
  2588.     mov [ssnac.wFid], 1  ; Family
  2589.     mov [ssnac.wSid], 0Eh    ; Subtype
  2590.     mov [ssnac.dRi], 0Eh     ; request-id
  2591.  
  2592.     mov eax, ssnac
  2593.     mov ebx, buff
  2594.     xor edx, edx             ; TLV head len
  2595.     call sendsnac
  2596.  
  2597.  
  2598.     ;
  2599.     ; Client sends its DC info and status to server
  2600.     ;
  2601.     mov [ssnac.wFid], 1  ; Family
  2602.     mov [ssnac.wSid], 1Eh    ; Subtype
  2603.     mov [ssnac.dRi], 1Eh     ; request-id
  2604.  
  2605.     mov [buff], 0           ;  TLV type 06
  2606.     mov [buff+1], 6h        ;
  2607.     mov [buff+2], 0         ;  TLV data length
  2608.     mov [buff+3], 4         ;
  2609.     ;
  2610.     ;
  2611.     mov ax, STATUS_DCDISABLED  ; DC disabled
  2612.     call htons
  2613.     mov word [buff+4], ax
  2614.     mov ax, STATUS_ONLINE
  2615.     mov [status], ax
  2616.     mov word [buff+6], ax
  2617.  
  2618.     mov eax, ssnac
  2619.     mov ebx, buff
  2620.     mov edx, 8           ; TLV head len+ data len
  2621.     call sendsnac
  2622.  
  2623.  
  2624.     ;
  2625.     ;  Выгружаем на сервер КЛ
  2626.     ;
  2627.     call uploadkl
  2628.  
  2629.     ;
  2630.     ; Выгружаем инвизибл лист, пока пустой
  2631.     ;
  2632.     mov [ssnac.wFid], 9  ; Family
  2633.     mov [ssnac.wSid], 7    ; Subtype
  2634.     mov [ssnac.dRi], 7
  2635.  
  2636.     mov eax, ssnac
  2637.     mov ebx, buff
  2638.     xor edx, edx
  2639.     call sendsnac
  2640.  
  2641.     ;
  2642.     ; В &RQ Есть пакет установки разрешений. я использую его без изменения
  2643.     ;  т.к. не знаю, что он содержит
  2644.     ; - возможно, буду использовать позднее
  2645.  
  2646.     ;mov [ssnac.wFid], 15  ; Family
  2647.     ;mov [ssnac.wSid], 2    ; Subtype
  2648.     ;mov [ssnac.dRi], 2
  2649.  
  2650.     ;mov word [buff], 0100h   ; 00 01 encapsulated META_DATA
  2651.     ;mov word [buff+2], 1000h ; 00 10     Len
  2652.     ;mov word [buff+4], 000Eh ;  LE Len
  2653.     ;mov word [buff+10], 07D0h ; META_DATA_REQ
  2654.  
  2655.  
  2656.     ;mov eax, UIN
  2657.     ;call ascitoint
  2658.     ;mov dword [buff+6], eax
  2659.  
  2660.     ;mov word [buff+12], 0102h   ; request sequence number (incrementing)
  2661.     ;mov word [buff+14], 0424h   ; META_SET_PERMS_USERINFO
  2662.     ;mov [buff+16], 1            ; authorization (1-required, 0-not required)
  2663.     ;mov [buff+17], byte 0       ; webaware (0-no, 1-yes)
  2664.     ;mov [buff+18], 1             ; dc_perms (0-any, 1-contact, 2-authorization)
  2665.     ;mov [buff+19], 0            ;unknown
  2666.  
  2667.     ;mov eax, ssnac
  2668.     ;mov ebx, buff
  2669.     ;mov edx, 20
  2670.  
  2671.  
  2672.     ;
  2673.     ; Client READY command
  2674.     ;
  2675.     mov [ssnac.wFid], 1  ; Family
  2676.     mov [ssnac.wSid], 2    ; Subtype
  2677.     mov [ssnac.dRi], 2     ; request-id
  2678.  
  2679.     mov eax, FAMILY_ARR
  2680.     mov ebx, buff
  2681.     push ecx
  2682.     mov ecx, FA_LEN
  2683.     call strcpy
  2684.     pop ecx
  2685.  
  2686.     mov eax, ssnac
  2687.     mov ebx, buff
  2688.     mov edx, FA_LEN
  2689.     call sendsnac
  2690.  
  2691.  
  2692.     ;
  2693.     ; Запрашиваем offline сообщения
  2694.     ;
  2695.     mov [ssnac.wFid], 15h  ; Family
  2696.     mov [ssnac.wSid], 2    ; Subtype
  2697.     mov [ssnac.dRi], 2     ; request-id
  2698.  
  2699.     mov word [buff], 0100h      ;  TLV type 01
  2700.     mov word [buff+2], 0A00h    ;  00 0a Длина
  2701.     mov word [buff+4], 0008h    ;  08 00
  2702.     lea eax, [vtable + vartable.uin]
  2703.     call ascitoint
  2704.     mov dword [buff+6], eax
  2705.  
  2706.     mov word [buff+10],  003Ch ; 3C 00 - Запрос на оффлайновые сообщения
  2707.     mov word [buff+12],  0002  ; 02 00 - request sequence number
  2708.    
  2709.     mov edx, 14        ; Общий размер данных в буфере
  2710.  
  2711.     mov eax, ssnac
  2712.     mov ebx, buff
  2713.     call sendsnac
  2714.  
  2715.    
  2716.  
  2717.     ;
  2718.     ; Запрашиваем информацию всех UIN
  2719.     ;
  2720.     call getinfo
  2721.     ;
  2722.     ; завершено соединение
  2723.     ;
  2724.     mov [login], 2
  2725.  
  2726.  
  2727.     end if   ; USE_SSI = 0
  2728.  
  2729.     jmp m_fin
  2730.  
  2731.   m_snac_9_other:
  2732.     write_debug 'Unknown SNAC Family 9 Recived'
  2733.     jmp m_fin
  2734.  
  2735.  
  2736.     ;
  2737.     ; FAMILY 13
  2738.     ;
  2739.   m_snac_13:
  2740.     cmp dx, 3
  2741.     jz m_snac_13_3
  2742.     cmp dx, 6
  2743.     jz m_snac_13_6
  2744.     cmp dx, 0fh
  2745.     jz m_snac_13_F
  2746.  
  2747.     jmp m_snac_13_other
  2748.  
  2749.     ;
  2750.     ; Server sends SSI service limitations to client
  2751.     ;
  2752.   m_snac_13_3:
  2753.     ;
  2754.     ; Обработки пока нет
  2755.     ;
  2756.  
  2757.     ;
  2758.     ;  SNAC(13,05)        Client check if its local SSI copy is up-to-date
  2759.     ;
  2760.     mov [ssnac.wFid], 13h  ; Family
  2761.     mov [ssnac.wSid], 5    ; Subtype
  2762.     mov [ssnac.dRi], 5     ; request-id
  2763.     mov eax, ssnac
  2764.     ;
  2765.     ;
  2766.     ;
  2767.     mov [buff], 03Dh      ;
  2768.     mov [buff+1], 0E7h    ;     modification date/time of client local SSI copy
  2769.     mov [buff+2], 48h     ;
  2770.     mov [buff+3], 17h     ;
  2771.     ;
  2772.     ;
  2773.     mov [buff+4], 00      ;
  2774.     mov [buff+5], 00h     ;     number of items in client local SSI copy
  2775.    
  2776.     mov ebx, buff
  2777.     mov edx, 5
  2778.     call sendsnac
  2779.  
  2780.     jmp m_fin
  2781.  
  2782.  
  2783.     ;
  2784.     ; Server contact list reply
  2785.     ;
  2786.   m_snac_13_6:
  2787.  
  2788.     lea eax, [mbuff+10]     ; В eax загружаем адрес приемного буфера+ размер заголовка snac
  2789.  
  2790.     call ssi_process_data   ; Обработка пакета с КЛ
  2791.  
  2792.     ;
  2793.     ; Активируем SSI
  2794.     ;
  2795.  
  2796.     mov [ssnac.wFid], 13h  ; Family
  2797.     mov [ssnac.wSid], 7    ; Subtype
  2798.     mov [ssnac.dRi], 7     ; request-id
  2799.     mov eax, ssnac
  2800.     mov ebx, buff
  2801.     xor edx, edx
  2802.     call sendsnac
  2803.  
  2804.  
  2805.     ;
  2806.     ; последняя стадия соединения
  2807.     ;
  2808.  
  2809.     ;
  2810.     ; Запрашиваем свою информацию
  2811.     ;
  2812.     mov [ssnac.wFid], 1  ; Family
  2813.     mov [ssnac.wSid], 0Eh    ; Subtype
  2814.     mov [ssnac.dRi], 0Eh     ; request-id
  2815.  
  2816.     mov eax, ssnac
  2817.     mov ebx, buff
  2818.     xor edx, edx             ; TLV head len
  2819.     call sendsnac
  2820.  
  2821.  
  2822.     ;
  2823.     ; Client sends its DC info and status to server
  2824.     ;
  2825.     mov [ssnac.wFid], 1  ; Family
  2826.     mov [ssnac.wSid], 1Eh    ; Subtype
  2827.     mov [ssnac.dRi], 1Eh     ; request-id
  2828.  
  2829.     mov [buff], 0           ;  TLV type 06
  2830.     mov [buff+1], 6h        ;
  2831.     mov [buff+2], 0         ;  TLV data length
  2832.     mov [buff+3], 4         ;
  2833.     ;
  2834.     ;
  2835.     mov ax, STATUS_DCDISABLED  ; DC disabled
  2836.     call htons
  2837.     mov word [buff+4], ax
  2838.     mov ax, STATUS_ONLINE
  2839.     mov [status], ax
  2840.     mov word [buff+6], ax
  2841.  
  2842.     mov eax, ssnac
  2843.     mov ebx, buff
  2844.     mov edx, 8           ; TLV head len+ data len
  2845.     call sendsnac
  2846.  
  2847.  
  2848.     ;
  2849.     ;  Выгружаем на сервер КЛ
  2850.     ;   FIXME Возможно, здесь не нужна эта функция
  2851.     ;call uploadkl
  2852.  
  2853.     ;
  2854.     ; Выгружаем инвизибл лист, пока пустой
  2855.     ;
  2856.     ;mov [ssnac.wFid], 9  ; Family
  2857.     ;mov [ssnac.wSid], 7    ; Subtype
  2858.     ;mov [ssnac.dRi], 7
  2859.  
  2860.     ;mov eax, ssnac
  2861.     ;mov ebx, buff
  2862.     ;xor edx, edx
  2863.     ;call sendsnac
  2864.  
  2865.     ;
  2866.     ; В &RQ Есть пакет установки разрешений. я использую его без изменения
  2867.     ;  т.к. не знаю, что он содержит
  2868.     ; - возможно, буду использовать позднее
  2869.  
  2870.     ;mov [ssnac.wFid], 15  ; Family
  2871.     ;mov [ssnac.wSid], 2    ; Subtype
  2872.     ;mov [ssnac.dRi], 2
  2873.  
  2874.     ;mov word [buff], 0100h   ; 00 01 encapsulated META_DATA
  2875.     ;mov word [buff+2], 1000h ; 00 10     Len
  2876.     ;mov word [buff+4], 000Eh ;  LE Len
  2877.     ;mov word [buff+10], 07D0h ; META_DATA_REQ
  2878.  
  2879.  
  2880.     ;mov eax, UIN
  2881.     ;call ascitoint
  2882.     ;mov dword [buff+6], eax
  2883.  
  2884.     ;mov word [buff+12], 0102h   ; request sequence number (incrementing)
  2885.     ;mov word [buff+14], 0424h   ; META_SET_PERMS_USERINFO
  2886.     ;mov [buff+16], 1            ; authorization (1-required, 0-not required)
  2887.     ;mov [buff+17], byte 0       ; webaware (0-no, 1-yes)
  2888.     ;mov [buff+18], 1             ; dc_perms (0-any, 1-contact, 2-authorization)
  2889.     ;mov [buff+19], 0            ;unknown
  2890.  
  2891.     ;mov eax, ssnac
  2892.     ;mov ebx, buff
  2893.     ;mov edx, 20
  2894.  
  2895.  
  2896.     ;
  2897.     ; Client READY command
  2898.     ;
  2899.     mov [ssnac.wFid], 1  ; Family
  2900.     mov [ssnac.wSid], 2    ; Subtype
  2901.     mov [ssnac.dRi], 2     ; request-id
  2902.  
  2903.     mov eax, FAMILY_ARR
  2904.     mov ebx, buff
  2905.     push ecx
  2906.     mov ecx, FA_LEN
  2907.     call strcpy
  2908.     pop ecx
  2909.  
  2910.     mov eax, ssnac
  2911.     mov ebx, buff
  2912.     mov edx, FA_LEN
  2913.     call sendsnac
  2914.  
  2915.  
  2916.     ;
  2917.     ; Запрашиваем offline сообщения
  2918.     ;
  2919.     mov [ssnac.wFid], 15h  ; Family
  2920.     mov [ssnac.wSid], 2    ; Subtype
  2921.     mov [ssnac.dRi], 2     ; request-id
  2922.  
  2923.     mov word [buff], 0100h      ;  TLV type 01
  2924.     mov word [buff+2], 0A00h    ;  00 0a Длина
  2925.     mov word [buff+4], 0008h    ;  08 00
  2926.     lea eax, [vtable + vartable.uin]
  2927.     call ascitoint
  2928.     mov dword [buff+6], eax
  2929.  
  2930.     mov word [buff+10],  003Ch ; 3C 00 - Запрос на оффлайновые сообщения
  2931.     mov word [buff+12],  0002  ; 02 00 - request sequence number
  2932.    
  2933.     mov edx, 14        ; Общий размер данных в буфере
  2934.  
  2935.     mov eax, ssnac
  2936.     mov ebx, buff
  2937.     call sendsnac
  2938.  
  2939.    
  2940.  
  2941.     ;
  2942.     ; Запрашиваем информацию всех UIN
  2943.     ; FIXME Возможно, здесь не нужна эта функция
  2944.     ;call getinfo
  2945.     ;
  2946.     ; завершено соединение
  2947.     ;
  2948.     mov [login], 2
  2949.  
  2950.  
  2951.     jmp m_fin
  2952.  
  2953.  
  2954.  
  2955.  
  2956.     ;
  2957.     ;  Server tell client its local copy up-to-date
  2958.     ;
  2959.   m_snac_13_F:
  2960.     ;
  2961.     ;  Обработки нет
  2962.     ;
  2963.  
  2964.     ;
  2965.     ;  Client activates server SSI data
  2966.     ;
  2967.     mov [ssnac.wFid], 13h  ; Family
  2968.     mov [ssnac.wSid], 7    ; Subtype
  2969.     mov [ssnac.dRi], 7     ; request-id
  2970.     mov eax, ssnac
  2971.     mov ebx, buff
  2972.     xor edx, edx
  2973.     call sendsnac
  2974.  
  2975.     ;
  2976.     ; последняя стадия соединения
  2977.     ;
  2978.  
  2979.     ;
  2980.     ; Client sends its DC info and status to server
  2981.     ;
  2982.     mov [ssnac.wFid], 1  ; Family
  2983.     mov [ssnac.wSid], 1Eh    ; Subtype
  2984.     mov [ssnac.dRi], 1Eh     ; request-id
  2985.  
  2986.     mov [buff], 0           ;  TLV type 06
  2987.     mov [buff+1], 6h        ;
  2988.     mov [buff+2], 0         ;  TLV data length
  2989.     mov [buff+3], 4         ;
  2990.     ;
  2991.     ;
  2992.     mov ax, STATUS_DCDISABLED  ; DC disabled
  2993.     call htons
  2994.     mov word [buff+4], ax
  2995.     ;
  2996.     ;
  2997.     mov ax, [status]
  2998.     mov word [buff+6], ax
  2999.  
  3000.     mov eax, ssnac
  3001.     mov ebx, buff
  3002.     mov edx, 8           ; TLV head len+ data len
  3003.     call sendsnac
  3004.  
  3005.     ;
  3006.     ; Client READY command
  3007.     ;
  3008.     mov [ssnac.wFid], 1  ; Family
  3009.     mov [ssnac.wSid], 2    ; Subtype
  3010.     mov [ssnac.dRi], 2     ; request-id
  3011.  
  3012.     mov eax, FAMILY_ARR
  3013.     mov ebx, buff
  3014.     push ecx
  3015.     mov ecx, FA_LEN
  3016.     call strcpy
  3017.     pop ecx
  3018.  
  3019.     mov eax, ssnac
  3020.     mov ebx, buff
  3021.     mov edx, FA_LEN
  3022.     call sendsnac
  3023.  
  3024.  
  3025.     ;
  3026.     ; Запрашиваем offline сообщения
  3027.     ;
  3028.     mov [ssnac.wFid], 15h  ; Family
  3029.     mov [ssnac.wSid], 2    ; Subtype
  3030.     mov [ssnac.dRi], 2     ; request-id
  3031.  
  3032.     mov word [buff], 0100h      ;  TLV type 01
  3033.     mov word [buff+2], 0A00h    ;  00 0a Длина
  3034.     mov word [buff+4], 0008h    ;  08 00
  3035.     lea eax, [vtable + vartable.uin]
  3036.     call ascitoint
  3037.     mov dword [buff+6], eax
  3038.  
  3039.     mov [buff+10],  003Ch ; 3C 00 - Запрос на оффлайновые сообщения
  3040.     mov [buff+12],  0002  ; 02 00 - request sequence number
  3041.    
  3042.     mov edx, 14        ; Общий размер данных в буфере
  3043.  
  3044.     mov eax, ssnac
  3045.     mov ebx, buff
  3046.     call sendsnac
  3047.  
  3048.  
  3049.  
  3050.     jmp m_fin
  3051.  
  3052.   m_snac_13_other:
  3053.     write_debug 'Unknown SNAC Family 13 Recived'
  3054.     jmp m_fin
  3055.  
  3056.  
  3057.  
  3058.  
  3059.     ;
  3060.     ;  Family 15
  3061.     ;
  3062.  
  3063.   m_snac_15:
  3064.    
  3065.     cmp dx, 3
  3066.     jz m_snac_15_3
  3067.    
  3068.     jmp m_snac_15_other
  3069.  
  3070.  
  3071.     ;
  3072.     ; Server sends message #N
  3073.     ;
  3074.   m_snac_15_3:
  3075.     ;
  3076.     ; Определяем подтип принятого пакета
  3077.     ;
  3078.  
  3079.     ;write_debug 'SNAC 15, 3'
  3080.  
  3081.     xor eax, eax
  3082.     mov ax, word [mbuff+10]  ; + SNAC.head size
  3083.     cmp ax, 0100h            ; 00 01 TLV type
  3084.     jnz m_snac_tlv_err
  3085.  
  3086.     mov ax, word [mbuff+10+10]
  3087.     cmp ax, 0041h             ; Offline Message
  3088.     jz m_snac_offline_mes
  3089.     cmp ax, 0042h             ; End messages
  3090.     jz m_snac_offline_end
  3091.     cmp ax, 07DAh
  3092.     jz m_snac_meta_data
  3093.  
  3094.  
  3095.     write_debug 'Unknown Subtype SNAC (15,3)'
  3096.     jmp m_fin
  3097.  
  3098.   m_snac_offline_mes:
  3099.     mov eax, MESS                      ;
  3100.     call strlen                        ;  Выводим строку с сообщением о отправителе и времени отправки
  3101.     push ecx                           ;
  3102.     mov ecx, eax                   ;
  3103.     mov eax, MESS
  3104.     mov ebx, buff
  3105.     call strcpy
  3106.  
  3107.     mov eax, dword [mbuff+14+10]          ; Sender UIN
  3108.     lea ebx, [buff+ecx]                ; После строчки о сообщении
  3109.     call int2strd
  3110.  
  3111.     lea ebx, [ebx+eax]
  3112.     mov [ebx], byte ' '
  3113.     inc ebx
  3114.  
  3115.                                        ; + Длина UIN
  3116.     movzx eax, byte [mbuff+21+10]         ; Day
  3117.     call int2strd
  3118.  
  3119.     lea ebx, [ebx+eax]
  3120.     mov [ebx], byte '.'
  3121.     inc ebx
  3122.  
  3123.    
  3124.     movzx eax, byte [mbuff+20+10]         ;Mounth
  3125.     call int2strd
  3126.  
  3127.     lea ebx, [ebx+eax]
  3128.     mov [ebx], byte ' '
  3129.     inc ebx
  3130.  
  3131.     movzx eax, [mbuff+22+10]              ; Hour
  3132.     call int2strd
  3133.  
  3134.     lea ebx, [ebx+eax]
  3135.     mov [ebx], byte ':'
  3136.     inc ebx
  3137.  
  3138.     movzx eax, [mbuff+23+10]              ; Minute
  3139.     call int2strd
  3140.  
  3141.     lea ebx, [ebx+eax]
  3142.     ;mov [ebx], byte ' '
  3143.     ;inc ebx
  3144.  
  3145.     mov [ebx], byte 0                      ; Str end
  3146.     mov eax, buff
  3147.     xor ebx, ebx
  3148.  
  3149.     call writemsg
  3150.  
  3151.     movzx ecx, word [mbuff+26+10]             ; Длина соообщения
  3152.     lea eax, [mbuff+28+10]
  3153.     mov ebx, buff
  3154.     call strcpy
  3155.  
  3156.     mov [ebx+ecx], byte 0
  3157.  
  3158.     mov eax, buff
  3159.     call win2dos                              ;перекодируем
  3160.