Subversion Repositories Kolibri OS

Rev

Rev 6026 | Rev 9092 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

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