Subversion Repositories Kolibri OS

Rev

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

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                                 ;;
  3. ;; Copyright (C) KolibriOS team 2004-2024. All rights reserved.    ;;
  4. ;; Distributed under terms of the GNU General Public License       ;;
  5. ;;                                                                 ;;
  6. ;;   Written by hidnplayr@kolibrios.org                            ;;
  7. ;;                                                                 ;;
  8. ;;         GNU GENERAL PUBLIC LICENSE                              ;;
  9. ;;          Version 2, June 1991                                   ;;
  10. ;;                                                                 ;;
  11. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  12.  
  13.  
  14. server_parser:
  15.  
  16.         mov     esi, servercommand
  17.         mov     ebx, ecx
  18.  
  19.         cmp     byte [esi], ':'
  20.         jne     .parse
  21.  
  22.   .spaceloop:
  23.         lodsb
  24.         test    al, al
  25.         jz      .fail
  26.         cmp     al, ' '
  27.         jne     .spaceloop
  28.  
  29.   .parse:
  30.         mov     eax, [esi]
  31.         or      eax, 0x20202020         ; convert to lowercase
  32.         mov     edi, server_commands
  33.         mov     ecx, server_commands.number
  34.  
  35.   .loop:
  36.         scasd
  37.         je      .got_cmd
  38.         add     edi, 4
  39.         dec     ecx
  40.         jnz     .loop
  41.  
  42.   .fail:
  43.         ret
  44.  
  45.   .got_cmd:
  46.         mov     ecx, ebx
  47.         jmp     dword[edi]
  48.  
  49.  
  50. server_commands:
  51.  
  52.         dd      '001 ', cmd_welcome
  53.         dd      '002 ', cmd_justprint
  54.         dd      '003 ', cmd_justprint
  55.         dd      '004 ', cmd_justprint
  56.         dd      '005 ', cmd_justprint
  57.  
  58.         dd      '250 ', cmd_justprint
  59.         dd      '251 ', cmd_justprint
  60.         dd      '252 ', cmd_justprint
  61.         dd      '253 ', cmd_justprint
  62.         dd      '254 ', cmd_justprint
  63.         dd      '255 ', cmd_justprint
  64.  
  65.         dd      '265 ', cmd_justprint
  66.         dd      '266 ', cmd_justprint
  67.  
  68.         dd      '311 ', cmd_justprint   ; RPL_WHOISUSER
  69.         dd      '312 ', cmd_justprint   ; RPL_WHOISSERVER
  70.         dd      '317 ', cmd_justprint   ; RPL_WHOISIDLE
  71.         dd      '318 ', cmd_justprint   ; RPL_ENDOFWHOIS
  72.         dd      '319 ', cmd_justprint   ; RPL_WHOISCHANNELS
  73.         dd      '322 ', cmd_322         ; RPL_LIST
  74.         dd      '323 ', cmd_323         ; RPL_LISTEND
  75.         dd      '324 ', cmd_justprint   ; RPL_CHANNELMODEIS
  76.         dd      '328 ', cmd_justprint   ; RPL_CHANNEL_URL
  77.         dd      '329 ', cmd_justprint   ; RPL_CREATIONTIME
  78.         dd      '330 ', cmd_justprint
  79.         dd      '332 ', cmd_topic       ; topic
  80.         dd      '333 ', cmd_333         ; nickname and time of topic
  81.         dd      '338 ', cmd_justprint   ; RPL_CHANPASSOK
  82.         dd      '353 ', cmd_353         ; name reply
  83.         dd      '366 ', cmd_366         ; end of names list
  84.         dd      '372 ', cmd_justprint   ; motd
  85.         dd      '375 ', cmd_justprint   ; start of motd
  86.         dd      '376 ', cmd_justprint   ; end of motd
  87.         dd      '421 ', cmd_justprint   ; unknown command
  88.         dd      '432 ', cmd_justprint   ; erroneous nickname
  89.         dd      '433 ', cmd_justprint   ; nickname already in use
  90.         dd      '436 ', cmd_justprint   ; nickname collision
  91.         dd      '671 ', cmd_justprint   ; RPL_WHOISSECURE
  92.  
  93.         dd      'join', cmd_join
  94.         dd      'kick', cmd_kick
  95.         dd      'mode', cmd_mode
  96.         dd      'nick', cmd_nick
  97.         dd      'part', cmd_part
  98.         dd      'ping', cmd_ping
  99.         dd      'priv', cmd_privmsg
  100.         dd      'quit', cmd_quit
  101.         dd      'noti', cmd_notice
  102.  
  103.         .number = ($ - server_commands) / 8
  104.  
  105.  
  106. align 4
  107. compare_to_nick:
  108.  
  109.         push    esi
  110.         mov     ecx, MAX_NICK_LEN
  111.         mov     esi, user_nick
  112.   .loop:
  113.         lodsb
  114.         cmp     al, ' '
  115.         jbe     .done
  116.         test    al, al
  117.         jz      .done
  118.         cmp     al, 'a'
  119.         jb      .ok
  120.         cmp     al, 'z'
  121.         ja      .ok
  122.         sub     al, 0x20
  123.   .ok:
  124.  
  125.         mov     bl, byte[edi]
  126.         cmp     bl, 'a'
  127.         jb      .ok2
  128.         cmp     bl, 'z'
  129.         ja      .ok2
  130.         sub     bl, 0x20
  131.   .ok2:
  132.         cmp     bl, al
  133.         jne     .not_equal
  134.         inc     edi
  135.         dec     ecx
  136.         jnz     .loop
  137.  
  138.   .done:
  139.         xor     eax, eax
  140.         pop     esi
  141.         ret
  142.  
  143.   .not_equal:
  144.         or      eax, -1
  145.         pop     esi
  146.         ret
  147.  
  148.  
  149.  
  150. align 4
  151. skip_parameter:
  152.  
  153. ; First: skip the parameter (scan untill space or colon)
  154.   .part1:
  155.         lodsb
  156.         cmp     al, ' '
  157.         je      .part2
  158.         cmp     al, ':'
  159.         jne     .part1
  160.  
  161. ; Skip all trailing spaces
  162.   .part3:
  163.         lodsb
  164.         cmp     al, ' '
  165.         je      .part3
  166.         dec     esi
  167.         ret
  168.  
  169. ; Now, skip all trailing spaces and first semicolon
  170.   .part2:
  171.         lodsb
  172.         cmp     al, ' '
  173.         je      .part2
  174.         cmp     al, ':'
  175.         je      .part3
  176.         dec     esi
  177.         ret
  178.  
  179.  
  180.  
  181. cmd_welcome:
  182.  
  183.         mov     [status], STATUS_LOGGED_IN
  184.  
  185. cmd_justprint:
  186.  
  187.         add     esi, 4
  188.         call    skip_parameter          ; our nickname
  189.  
  190.         call    print_asciiz
  191.  
  192.         mov     al, 10
  193.         call    print_char
  194.  
  195.         ret
  196.  
  197.  
  198.  
  199. cmd_notice:
  200.  
  201.         if TIMESTAMP
  202.         call    print_timestamp
  203.         end if
  204.  
  205.         cmp     byte[servercommand], ':'
  206.         jne     .gogogo
  207.  
  208.         mov     byte [esi-1], 0
  209.         push    esi
  210.         mov     esi, str_1
  211.         call    print_asciiz
  212.         mov     esi, servercommand+1
  213.         mov     bl, '!'
  214.         call    print_string
  215.         mov     esi, str_2
  216.         call    print_asciiz
  217.         pop     esi
  218.  
  219.   .gogogo:
  220.         add     esi, 6
  221.         call    skip_parameter
  222.         call    skip_parameter
  223.         call    print_asciiz
  224.  
  225.         mov     al, 10
  226.         call    print_char
  227.  
  228.         ret
  229.  
  230.  
  231.  
  232. cmd_ping:
  233.  
  234. ; Just change PING to PONG
  235.         mov     dword[esi], 'PONG'
  236.  
  237. ; Append \r\n
  238.         mov     word[esi+ecx], 0x0a0d
  239.  
  240. ; And send the response to the server
  241.         mov     edx, esi
  242.         lea     esi, [ecx+2]
  243.         mcall   send, [socketnum], , , 0
  244.  
  245.         ret
  246.  
  247.  
  248.  
  249. cmd_privmsg:
  250.  
  251.         mov     eax, dword[esi+4]
  252.         or      eax, 0x20202020
  253.         cmp     eax, 'msg '
  254.         jne     .fail
  255.         add     esi, 8          ; skip 'PRIVMSG '
  256.  
  257.         mov     edi, esi
  258.         call    compare_to_nick
  259.         jne     .channel
  260.  
  261. ; private chat message
  262.         push    esi
  263.         mov     esi, servercommand+1
  264.         call    window_open
  265.         test    ebx, ebx
  266.         jz      .fail2
  267.         pop     esi
  268.         call    skip_parameter  ; our own nickname
  269.         jmp     .print
  270.  
  271.   .channel:
  272.         call    window_open
  273.         test    ebx, ebx
  274.         jz      .fail
  275.  
  276.   .print:
  277.         cmp     byte[esi], 1    ; Client to Client protocol?
  278.         je      cmd_ctcp
  279.  
  280.         if TIMESTAMP
  281.         call    print_timestamp
  282.         end if
  283.  
  284.         push    esi
  285.         mov     al, '<'
  286.         call    print_char
  287.  
  288.         mov     esi, servercommand+1
  289.         mov     bl, '!'
  290.         call    print_string
  291.  
  292.         mov     al, '>'
  293.         call    print_char
  294.  
  295.         mov     al, ' '
  296.         call    print_char
  297.  
  298.         pop     esi
  299.         call    print_asciiz
  300.  
  301.         mov     al, 10
  302.         call    print_char
  303.  
  304.         ret
  305.  
  306.   .fail2:
  307.         pop     esi
  308.   .fail:
  309.         ret
  310.  
  311.  
  312.  
  313.  
  314. cmd_ctcp:
  315.  
  316.         inc     esi
  317.         mov     eax, dword[esi]
  318.         or      eax, 0x20202020
  319.  
  320.         cmp     eax, 'vers'
  321.         je      .version
  322.         cmp     eax, 'time'
  323.         je      .time
  324.         cmp     eax, 'ping'
  325.         je      .ping
  326.         cmp     eax, 'acti'
  327.         je      .action
  328.         cmp     eax, 'dcc '    ; TODO
  329.         je      cmd_dcc
  330.  
  331. ; Unknown CTCP command - just print to window
  332.  
  333.   .just_print:
  334.  
  335.         push    esi
  336.  
  337.         if TIMESTAMP
  338.         call    print_timestamp
  339.         end if
  340.  
  341.         mov     esi, ctcp_header_recv
  342.         call    print_asciiz
  343.  
  344.         mov     al, '<'
  345.         call    print_char
  346.  
  347.         mov     esi, servercommand+1    ; print nickname
  348.         mov     bl, '!'
  349.         call    print_string
  350.  
  351.         mov     al, '>'
  352.         call    print_char
  353.  
  354.         mov     al, ' '
  355.         call    print_char
  356.  
  357.         pop     esi
  358.         mov     bl, 1
  359.         call    print_string
  360.  
  361.         mov     al, 10
  362.         call    print_char
  363.  
  364.         ret
  365.  
  366.   .time:
  367.         mov     byte[esi+4], ' '
  368.         lea     edi, [esi+5]
  369.  
  370.         ; TODO: add system date (fn 29) in human readable format
  371.  
  372.         mcall   3                       ; get system time
  373.  
  374.         mov     ecx, 3
  375.   .timeloop:
  376.         mov     bl, al
  377.         shr     al, 4
  378.         add     al, '0'
  379.         stosb
  380.  
  381.         mov     al, bl
  382.         and     al, 0x0f
  383.         add     al, '0'
  384.         stosb
  385.  
  386.         dec     ecx
  387.         jz      .timedone
  388.  
  389.         mov     al, ':'
  390.         stosb
  391.         shr     eax, 8
  392.         jmp     .timeloop
  393.  
  394.   .timedone:
  395.         xor     al, al
  396.         stosb
  397.         call    ctcp_reply
  398.  
  399.         if TIMESTAMP
  400.         call    print_timestamp
  401.         end if
  402.  
  403.         mov     esi, ctcp_header
  404.         call    print_asciiz
  405.  
  406.         mov     esi, servercommand+1
  407.         call    print_asciiz
  408.  
  409.         mov     esi, ctcp_time
  410.         call    print_asciiz
  411.  
  412.         ret
  413.  
  414.   .version:
  415.         mov     esi, str_version
  416.         call    ctcp_reply
  417.  
  418.         if TIMESTAMP
  419.         call    print_timestamp
  420.         end if
  421.  
  422.         mov     esi, ctcp_header
  423.         call    print_asciiz
  424.  
  425.         mov     esi, servercommand+1
  426.         call    print_asciiz
  427.  
  428.         mov     esi, ctcp_version
  429.         call    print_asciiz
  430.  
  431.         ret
  432.  
  433.   .ping:
  434.         call    ctcp_reply
  435.  
  436.         if TIMESTAMP
  437.         call    print_timestamp
  438.         end if
  439.  
  440.         mov     esi, ctcp_header
  441.         call    print_asciiz
  442.  
  443.         mov     esi, servercommand+1
  444.         call    print_asciiz
  445.  
  446.         mov     esi, ctcp_ping
  447.         call    print_asciiz
  448.  
  449.         ret
  450.  
  451.   .action:
  452.         add     esi, 7
  453.         push    esi
  454.  
  455.         if TIMESTAMP
  456.         call    print_timestamp
  457.         end if
  458.  
  459.         mov     esi, action_header
  460.         call    print_asciiz
  461.  
  462.         mov     esi, servercommand+1    ; print nickname
  463.         mov     bl, '!'
  464.         call    print_string
  465.  
  466.         mov     al, ' '
  467.         call    print_char
  468.  
  469.         pop     esi
  470.         call    print_asciiz
  471.  
  472.         mov     al, 10
  473.         call    print_char
  474.  
  475.         ret
  476.  
  477.  
  478. cmd_dcc:
  479.         add     esi, 4
  480.         mov     eax, dword[esi]
  481.         or      eax, 0x202020
  482.  
  483.         cmp     eax, 'send'
  484.         je      .send
  485.  
  486.         ret
  487.  
  488.   .send:
  489.         call    window_open
  490.         test    ebx, ebx
  491.         jz      .fail
  492.         mov     [ebx + window.type], WINDOWTYPE_DCC
  493.  
  494.   .fail:
  495.  
  496.         ret
  497.  
  498.  
  499.  
  500. ctcp_reply:
  501.  
  502.         push    esi
  503.         mov     dword[user_command], 'NOTI'
  504.         mov     dword[user_command+4], 'CE  '
  505.  
  506.         mov     esi, servercommand+1
  507.         mov     edi, user_command+7
  508.   .nickloop:
  509.         lodsb
  510.         cmp     al, '!'
  511.         je      .done
  512.         cmp     al, ' '
  513.         je      .done
  514.         test    al, al
  515.         je      .fail
  516.         stosb
  517.         jmp     .nickloop
  518.   .done:
  519.         mov     byte [esi-1], 0
  520.         mov     ax, ' :'
  521.         stosw
  522.         mov     al, 1
  523.         stosb
  524.  
  525.         pop     esi
  526.   .replyloop:
  527.         lodsb
  528.         cmp     al, 1
  529.         jbe     .done2
  530.         stosb
  531.         jmp     .replyloop
  532.   .done2:
  533.  
  534.         mov     al, 1
  535.         stosb
  536.         mov     ax, 0x0a0d
  537.         stosw
  538.  
  539.         lea     esi, [edi - user_command]
  540.         mcall   send, [socketnum], user_command, , 0
  541.   .fail:
  542.         ret
  543.  
  544.  
  545.  
  546. cmd_part:
  547.  
  548.         cmp     byte [esi+4], ' '
  549.         jne     .fail
  550.         add     esi, 5  ; skip 'PART '
  551.         cmp     byte[esi], ':'
  552.         jne     @f
  553.         inc     esi
  554.   @@:  
  555.  
  556. ; Is it me who parted?
  557.         mov     edi, servercommand+1
  558.         call    compare_to_nick
  559.         jne     .not_me
  560.  
  561. ; yes, close the window (if its open)
  562.         call    window_find
  563.         test    ebx, ebx
  564.         jz      @f
  565.         call    window_close
  566.   @@:
  567.   .fail:
  568.  
  569.         ret
  570.  
  571.  
  572. ; somebody else parted, just print message
  573.   .not_me:
  574.         push    esi
  575.         call    window_open
  576.         test    ebx, ebx
  577.         jz      .fail2
  578.  
  579.         if TIMESTAMP
  580.         call    print_timestamp
  581.         end if
  582.  
  583.         mov     esi, part_header
  584.         call    print_asciiz
  585.  
  586.         mov     esi, servercommand+1
  587.         mov     bl, '!'
  588.         call    print_string
  589.  
  590.         mov     esi, has_left_channel
  591.         call    print_asciiz
  592.  
  593.         pop     esi
  594.         call    print_asciiz
  595.  
  596.         mov     al, 10
  597.         call    print_char
  598.  
  599.         mov     ebx, [window_print]
  600.         mov     esi, servercommand+1
  601.         call    user_remove
  602.  
  603.         ret
  604.  
  605.   .fail2:
  606.         pop     esi
  607.  
  608.         ret
  609.  
  610.  
  611.  
  612. cmd_join:
  613.  
  614.         cmp     byte[esi+4], ' '
  615.         jne     .fail
  616.         add     esi, 5  ; skip 'JOIN '
  617.         cmp     byte[esi], ':'
  618.         jne     @f
  619.         inc     esi
  620.   @@:  
  621.  
  622. ; did we join a channel?
  623.         mov     edi, servercommand+1
  624.         call    compare_to_nick
  625.         jne     .not_me
  626.  
  627.         push    esi
  628.         call    window_open
  629.         test    ebx, ebx
  630.         jz      .fail
  631.         mov     [ebx + window.type], WINDOWTYPE_CHANNEL
  632.         mov     [window_active], ebx
  633.  
  634.         if TIMESTAMP
  635.         call    print_timestamp
  636.         end if
  637.  
  638.         mov     esi, join_header
  639.         call    print_asciiz
  640.  
  641.         mov     esi, str_talking
  642.         call    print_asciiz
  643.  
  644.         pop     esi
  645.         mov     bl, ' '
  646.         call    print_string
  647.  
  648.         mov     al, 10
  649.         call    print_char
  650.  
  651.         call    draw_window
  652.  
  653.         ret
  654.  
  655.   .not_me:
  656.         push    esi
  657.         call    window_open
  658.         test    ebx, ebx
  659.         jz      .fail
  660.  
  661.         if TIMESTAMP
  662.         call    print_timestamp
  663.         end if
  664.  
  665.         mov     esi, join_header
  666.         call    print_asciiz
  667.  
  668.         mov     esi, servercommand+1
  669.         mov     bl, '!'
  670.         call    print_string
  671.  
  672.         mov     esi, joins_channel
  673.         call    print_asciiz
  674.  
  675.         pop     esi
  676.         call    print_asciiz
  677.  
  678.         mov     al, 10
  679.         call    print_char
  680.  
  681.         mov     ebx, [window_print]
  682.         mov     esi, servercommand+1
  683.         call    user_add
  684.  
  685.         ret
  686.  
  687.   .fail:
  688.         pop     esi
  689.         ret
  690.  
  691.  
  692.  
  693.  
  694. cmd_nick:
  695.  
  696.         cmp     byte[esi+4], ' '
  697.         jne     .fail
  698.         add     esi, 5          ; skip 'NICK '
  699.         cmp     byte[esi], ':'
  700.         jne     @f
  701.         inc     esi
  702.   @@:
  703.  
  704. ; Is it me who changed nick?
  705.         push    esi
  706.         mov     edi, servercommand+1
  707.         call    compare_to_nick
  708.         jne     .not_me
  709.  
  710. ; Yup, update user_nick
  711.         mov     ecx, MAX_NICK_LEN-1
  712.         mov     esi, [esp]
  713.         mov     edi, user_nick
  714.   @@:
  715.         lodsb
  716.         test    al, al
  717.         jz      @f
  718.         cmp     al, ' '
  719.         je      @f
  720.         cmp     al, 10
  721.         je      @f
  722.         cmp     al, 13
  723.         je      @f
  724.         cmp     al, ':'
  725.         je      @r
  726.         stosb
  727.         dec     ecx
  728.         jnz     @r
  729.   @@:
  730.         xor     al, al
  731.         stosb
  732.  
  733. ; Print a message on the server window
  734.         mov     [window_print], windows
  735.  
  736.         mov     esi, str_nickchange
  737.         call    print_asciiz
  738.  
  739.         mov     esi, user_nick
  740.         call    print_asciiz
  741.  
  742.         mov     al, 10
  743.         call    print_char
  744.  
  745.   .not_me:
  746.  
  747. ; Update in userlist
  748.         mov     ebx, windows
  749.         mov     ecx, MAX_WINDOWS
  750.   .window_loop:
  751.         push    ecx ebx
  752.         cmp     [ebx + window.type], WINDOWTYPE_CHANNEL
  753.         jne     .next_window
  754.  
  755.         mov     esi, servercommand+1
  756.         call    user_remove
  757.         test    edi, edi
  758.         jz      .next_window
  759.  
  760.         mov     esi, [esp + 8]
  761.         call    user_add
  762.  
  763. ; And print a notification in the channel
  764.         mov     [window_print], ebx
  765.  
  766.         if TIMESTAMP
  767.         call    print_timestamp
  768.         end if
  769.  
  770.         mov     esi, nick_header
  771.         call    print_asciiz
  772.  
  773.         mov     esi, servercommand+1
  774.         mov     bl, '!'
  775.         call    print_string
  776.  
  777.         mov     esi, is_now_known_as
  778.         call    print_asciiz
  779.  
  780.         mov     esi, [esp + 8]
  781.         call    print_asciiz
  782.  
  783.         mov     al, 10
  784.         call    print_char
  785.  
  786. ; Now do this for all open windows
  787.   .next_window:
  788.         pop     ebx ecx
  789.         add     ebx, sizeof.window
  790.         dec     ecx
  791.         jnz     .window_loop
  792.  
  793.         pop     esi
  794.  
  795.   .fail:
  796.  
  797.         ret
  798.  
  799.  
  800.  
  801.  
  802. cmd_kick:
  803.  
  804.         cmp     byte [esi+4], ' '
  805.         jne     .fail
  806.         add     esi, 5  ; skip 'KICK '
  807.  
  808. ; TODO: Is it me who got kicked?
  809. ; if so, mark channel as disconnected
  810.  
  811.   .not_me:
  812. ; find the channel user has been kicked from
  813.         push    esi
  814.         call    window_open
  815.         test    ebx, ebx
  816.         jz      .fail
  817.         push    esi
  818.  
  819.         if TIMESTAMP
  820.         call    print_timestamp
  821.         end if
  822.  
  823.         mov     esi, kick_header
  824.         call    print_asciiz
  825.  
  826.         pop     esi
  827.         mov     bl, ' '
  828.         call    print_string
  829.  
  830.         mov     esi, str_kicked
  831.         call    print_asciiz
  832.  
  833.         pop     esi
  834.         mov     bl, ' '
  835.         call    print_string
  836.  
  837.         mov     esi, str_by
  838.         call    print_asciiz
  839.  
  840.         mov     esi, servercommand+1
  841.         mov     bl, '!'
  842.         call    print_string
  843.  
  844.         mov     al, 10
  845.         call    print_char
  846.  
  847.         mov     ebx, [window_print]
  848.         mov     esi, servercommand+1
  849.         call    user_remove
  850.  
  851.         ret
  852.  
  853.   .fail:
  854.         pop     esi
  855.  
  856.         ret
  857.  
  858.  
  859.  
  860. cmd_quit:
  861.  
  862.         cmp     byte [esi+4], ' '
  863.         jne     .fail
  864.  
  865.         mov     ebx, windows
  866.         mov     ecx, MAX_WINDOWS
  867.  
  868.   .window_loop:
  869.         push    ecx
  870.         cmp     [ebx + window.type], WINDOWTYPE_CHANNEL
  871.         jne     .next_window
  872.  
  873.         mov     esi, servercommand+1
  874.         call    user_remove
  875.         test    edi, edi
  876.         jz      .next_window
  877.  
  878.         push    ebx
  879.         mov     [window_print], ebx
  880.  
  881.         if TIMESTAMP
  882.         call    print_timestamp
  883.         end if
  884.  
  885.         mov     esi, quit_header
  886.         call    print_asciiz
  887.  
  888.         mov     esi, servercommand+1
  889.         mov     bl, '!'
  890.         call    print_string
  891.  
  892.         mov     esi, has_quit_irc
  893.         call    print_asciiz
  894.  
  895. ; TODO: check if quit message was given, and print it to the window
  896.         pop     ebx
  897.   .next_window:
  898.         pop     ecx
  899.         add     ebx, sizeof.window
  900.         dec     ecx
  901.         jnz     .window_loop
  902.  
  903.   .fail:
  904.  
  905.  
  906.         ret
  907.  
  908.  
  909.  
  910. cmd_mode:
  911.  
  912.         cmp     byte [esi+4], ' '
  913.         jne     .fail
  914.         add     esi, 5  ; skip 'MODE '
  915.         push    esi
  916.         call    window_find
  917.         test    ebx, ebx
  918.         jz      .user
  919.         mov     [esp], esi
  920.         mov     [window_print], ebx
  921.  
  922.         if TIMESTAMP
  923.         call    print_timestamp
  924.         end if
  925.  
  926.         mov     esi, mode_header
  927.         call    print_asciiz
  928.  
  929.         mov     esi, servercommand+1
  930.         mov     bl, '!'
  931.         call    print_string
  932.  
  933.         mov     esi, sets_mode
  934.         call    print_asciiz
  935.  
  936.         pop     esi
  937.         call    print_asciiz
  938.  
  939.         mov     al, 10
  940.         call    print_char
  941.  
  942. ; TODO: keep track of user modes in username list
  943.  
  944.   .fail:
  945.         ret
  946.  
  947.  
  948.   .user:
  949.         if TIMESTAMP
  950.         call    print_timestamp
  951.         end if
  952.  
  953.         mov     esi, mode_header
  954.         call    print_asciiz
  955.  
  956.         mov     esi, [esp]
  957.         mov     bl, ' '
  958.         call    print_string
  959.  
  960.         mov     esi, sets_mode
  961.         call    print_asciiz
  962.  
  963.         pop     esi
  964.         call    skip_parameter
  965.         call    print_asciiz
  966.  
  967.         mov     al, 10
  968.         call    print_char
  969.  
  970.         ret
  971.  
  972.  
  973. cmd_353:                ; channel usernames reply
  974.  
  975.         add     esi, 4  ; skip '353 '
  976.         call    skip_parameter
  977.         inc     esi     ; channel type '*', '=' or '@'
  978.         inc     esi     ; ' '
  979.         call    window_open
  980.         test    ebx, ebx
  981.         jz      .fail
  982.  
  983. ; now find window ptr and check if this is the first 353 message
  984.         mov     ebx, [window_print]
  985.         test    [ebx + window.flags], FLAG_RECEIVING_NAMES
  986.         jnz     .add
  987.  
  988.         or      [ebx + window.flags], FLAG_RECEIVING_NAMES
  989. ;        mov     [ebx + window.users], 0
  990.         ; TODO: remove all users?
  991.  
  992.   .add:
  993.         lodsb
  994.         test    al, al
  995.         jz      .done
  996.         cmp     al, ' '
  997.         je      .add
  998.         dec     esi
  999.         call    user_add
  1000.         jmp     .add
  1001.  
  1002.   .done:
  1003.         call    draw_user_list
  1004.  
  1005.   .fail:
  1006.         ret
  1007.  
  1008.  
  1009.  
  1010.  
  1011.  
  1012. cmd_366:        ; channel usernames end
  1013.  
  1014.         add     esi, 4          ; skip '366 '
  1015.         call    skip_parameter
  1016.         call    window_open
  1017.         test    ebx, ebx
  1018.         jz      .fail
  1019.         and     [ebx + window.flags], not FLAG_RECEIVING_NAMES
  1020.   .fail:
  1021.  
  1022.         ret
  1023.  
  1024.  
  1025.  
  1026.  
  1027. cmd_topic:
  1028.  
  1029.         add     esi, 4          ; skip '332 '
  1030.         call    skip_parameter
  1031.         call    window_open
  1032.         test    ebx, ebx
  1033.         jz      .fail
  1034.  
  1035.         if TIMESTAMP
  1036.         call    print_timestamp
  1037.         end if
  1038.  
  1039.         push    esi
  1040.         mov     esi, topic_header
  1041.         call    print_asciiz
  1042.  
  1043.         mov     esi, str_topic
  1044.         call    print_asciiz
  1045.  
  1046.         pop     esi
  1047.         call    print_asciiz
  1048.  
  1049.         mov     esi, str_topic_end
  1050.         call    print_asciiz
  1051.  
  1052.   .fail:
  1053.  
  1054.         ret
  1055.  
  1056.  
  1057. cmd_333:
  1058.  
  1059.         add     esi, 4          ; skip '333 '
  1060.         call    skip_parameter
  1061.         call    window_open
  1062.         test    ebx, ebx
  1063.         jz      .fail
  1064.  
  1065.         if TIMESTAMP
  1066.         call    print_timestamp
  1067.         end if
  1068.  
  1069.         push    esi
  1070.         mov     esi, topic_header
  1071.         call    print_asciiz
  1072.  
  1073.         mov     esi, str_setby
  1074.         call    print_asciiz
  1075.  
  1076.         pop     esi
  1077.         mov     bl, '!'
  1078.         call    print_string
  1079.  
  1080.         mov     al, 10
  1081.         call    print_char
  1082.  
  1083.   .fail:
  1084.  
  1085.         ret
  1086.  
  1087.  
  1088.  
  1089. cmd_322:        ; LIST
  1090.  
  1091.         add     esi, 4
  1092.         call    skip_parameter
  1093.  
  1094.         push    esi
  1095.         mov     esi, str_list
  1096.         call    window_open
  1097.         test    ebx, ebx
  1098.         jz      .fail
  1099.  
  1100.         mov     [window_active], ebx
  1101.         call    draw_window_tabs
  1102.         pop     esi
  1103.         call    print_asciiz
  1104.         mov     al, 10
  1105.         call    print_char
  1106.  
  1107.         ret
  1108.  
  1109.   .fail:
  1110.         pop     esi
  1111.  
  1112.         ret
  1113.  
  1114. cmd_323:        ; LIST END
  1115.  
  1116.         ret
  1117.