kolibrios-fun/programs/network/ircc/userparser.inc

631 lines
14 KiB
PHP

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; Written by hidnplayr@kolibrios.org ;;
;; ;;
;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
user_parser:
push [window_active] ; print to the current window
pop [window_print]
mov eax, [edit1.size]
test eax, eax
jz .ret ; ignore empty commands
mov word[usercommand + eax], 0x0a0d ; terminate the line
cmp byte[usercommand], '/' ; is it a server command ?
je server_command
; Ignore data commands when not connected.
cmp [status], STATUS_CONNECTED
jne .notconnected
; Ok, we said something, print it to our textbox
; TODO: dont send if it's a server window?
if TIMESTAMP
call print_timestamp
end if
mov al, '<'
call print_char
mov esi, user_nick
call print_asciiz
mov al, '>'
call print_char
mov al, ' '
call print_char
mov eax, [edit1.size]
mov byte[usercommand + eax],0
mov esi, usercommand
call print_asciiz
mov al, 10
call print_char
; and now send it to the server
mov dword[packetbuf], 'PRIV'
mov dword[packetbuf+4], 'MSG '
mov esi, [window_active]
add esi, window.name
mov edi, packetbuf+8
mov ecx, MAX_WINDOWNAME_LEN
.loop:
lodsb
test al, al
jz .done
stosb
dec ecx
jnz .loop
.done:
mov ax, ' :'
stosw
mov esi, usercommand
mov ecx, [edit1.size]
inc ecx
call recode
; end the command with a CRLF
mov ax, 0x0a0d
stosw
lea esi, [edi - packetbuf]
mcall send, [socketnum], packetbuf, , 0
.ret:
ret
.notconnected:
mov esi, str_notconnected
call print_asciiz
ret
user_commands:
dd 'nick', cmd_usr_nick
dd 'real', cmd_usr_real
dd 'serv', cmd_usr_server
dd 'help', cmd_usr_help
dd 'code', cmd_usr_code
.number2 = ($ - user_commands) / 8
; All following commands require a connection to the server.
dd 'quer', cmd_usr_quer
dd 'quit', cmd_usr_quit
dd 'part', cmd_usr_part
dd 'ctcp', cmd_usr_ctcp
dd 'msg ', cmd_usr_msg
.number = ($ - user_commands) / 8
server_command:
mov eax, dword[usercommand+1] ; skip '/'
or eax, 0x20202020 ; convert to lowercase
mov edi, user_commands
mov ecx, user_commands.number
cmp [status], STATUS_CONNECTED
je .loop
mov ecx, user_commands.number2
.loop:
scasd
je .got_cmd
add edi, 4
dec ecx
jnz .loop
cmp [status], STATUS_CONNECTED
jne .notconnected
; Commands shorter then 3 chars are placed here
and eax, 0x00ffffff
cmp eax, 'me '
je cmd_usr_me
jmp cmd_usr_send ; If none of the previous commands, just send to server
.got_cmd:
jmp dword[edi]
.notconnected:
mov esi, str_notconnected
call print_asciiz
ret
cmd_usr_msg:
lea esi, [usercommand+5]
mov dword[packetbuf], 'PRIV'
mov dword[packetbuf+4], 'MSG '
lea edi, [packetbuf+8]
@@:
lodsb
test al, al
jz .fail
cmp al, 10
je .fail
cmp al, 13
je .fail
stosb
cmp al, ' '
jne @r
mov al, ':'
stosb
push edi
@@:
lodsb
test al, al
jz @f
cmp al, 10
je @f
cmp al, 13
je @f
stosb
jmp @r
@@:
; end the command with a CRLF
mov ax, 0x0a0d
stosw
mov byte[edi], 0
lea esi, [edi - packetbuf]
mcall send, [socketnum], packetbuf, , 0
; now print to the window
if TIMESTAMP
call print_timestamp
end if
mov esi, msg_header
call print_asciiz
mov esi, packetbuf+8
mov bl, ' '
call print_string
mov al, '*'
call print_char
mov al, ' '
call print_char
pop esi
call print_asciiz
.fail:
ret
cmd_usr_quit:
mov esi, quit_msg
cmp byte[usercommand+5], ' '
jne .with_message
lea esi, [usercommand+6]
.with_message:
call cmd_usr_quit_server
mcall close, [socketnum]
mov [status], STATUS_DISCONNECTED
mov ecx, MAX_WINDOWS
mov edi, windows
.loop:
mov [window_print], edi
push edi ecx
call window_close
pop ecx edi
add edi, sizeof.window
dec ecx
jnz .loop
ret
; esi = quit message
cmd_usr_quit_server:
; User wants to close a channel, send PART command to server
mov dword[packetbuf], 'QUIT'
mov word[packetbuf+4], ' :'
lea edi, [packetbuf+6]
; Append our quit msg
@@:
lodsb
cmp al, 13
je @f
test al, al
jz @f
stosb
jmp @r
@@:
; end the command with a CRLF
mov ax, 0x0a0d
stosw
lea esi, [edi - packetbuf] ; calculate length
mcall send, [socketnum], packetbuf, , 0 ; and finally send to server
ret
cmd_usr_nick:
cmp [edit1.size], 5
je .dontsend
cmp byte[usercommand+5], ' '
jne .fail
cmp [socketnum], 0
je .dontsend
; Request nickname change to server
mov dword[usercommand+1], 'NICK'
mov esi, [edit1.size]
mov word[usercommand + esi], 0x0a0d
inc esi
mcall send, [socketnum], usercommand+1, , 0
.fail:
ret
; We arent logged in yet, directly change user_nick field and print notification to user.
.dontsend:
mov ecx, MAX_NICK_LEN
mov esi, usercommand+6
mov edi, user_nick
@@:
lodsb
cmp al, 13
je @f
stosb
dec ecx
jnz @r
@@:
xor al, al
stosb
mov esi, str_nickchange
call print_asciiz
mov esi, user_nick
call print_asciiz
mov al, 10
call print_char
ret
cmd_usr_real:
cmp byte[usercommand+5], ' '
jne cmd_usr_send
mov ecx, MAX_REAL_LEN
mov esi, usercommand+6
mov edi, user_real_name
.loop:
lodsb
cmp al, 13
je .done
stosb
dec ecx
jnz .loop
.done:
xor al, al
stosb
mov esi, str_realchange
call print_asciiz
mov esi, user_real_name
call print_asciiz
mov al, 10
call print_char
ret
cmd_usr_server:
mov eax, dword[usercommand+5] ; check for 'er ', we only checked 'serv'
or eax, 0x00002020
and eax, 0x00ffffff
cmp eax, 'er '
jne cmd_usr_send
mov ecx, [edit1.size] ; ok now set the address
sub ecx, 8
mov esi, usercommand+8
.now:
push esi
mov edi, irc_server_name
.loop: ; copy until zero byte, or ecx reaches zero.
lodsb
stosb
test al, al
jz .done
dec ecx
jnz .loop
xor al, al
stosb
.done:
pop esi
; set it also in window name
mov ebx, [window_print]
call window_set_name
; now connect
call socket_connect
ret
cmd_usr_quer:
mov esi, usercommand+7
call window_open
; test ebx, ebx
; jz .fail
ret
cmd_usr_help:
mov esi, str_help
call print_asciiz
ret
cmd_usr_code:
; TODO
ret
; User typed a part command
cmd_usr_part:
cmp byte[usercommand+5], 13 ; parameters given?
jne cmd_usr_send ; yes, send command straight to server
; close active window
cmd_usr_close_window:
mov esi, [window_active]
cmp [esi + window.type], WINDOWTYPE_SERVER
je .not_channel
lea esi, [esi + window.name]
call cmd_usr_part_channel
call window_close
ret
.not_channel:
cmp [esi + window.type], WINDOWTYPE_CHAT
jne .not_chat
call window_close
.not_chat:
ret
; Send part command to server
; esi must point to channel name (ASCIIZ)
cmd_usr_part_channel:
; User wants to close a channel, send PART command to server
mov dword[packetbuf], 'PART'
mov byte[packetbuf+4], ' '
lea edi, [packetbuf+5]
@@:
lodsb
test al, al
jz @f
cmp al, 13
je @f
cmp al, 10
je @f
stosb
jmp @r
@@:
; end the command with a CRLF
mov ax, 0x0a0d
stosw
lea esi, [edi - packetbuf] ; calculate length
mcall send, [socketnum], packetbuf, , 0 ; and finally send to server
ret
cmd_usr_ctcp:
cmp byte[usercommand+5], ' '
jne cmd_usr_send
mov esi, usercommand+6
; prepare a 'PRIVMSG '
mov dword[packetbuf], 'PRIV'
mov dword[packetbuf+4], 'MSG '
lea edi, [packetbuf+8]
; append the destination (nickname/channel)
@@:
lodsb
test al, al
jz .fail
cmp al, ' '
je @f
stosb
jmp @r
@@:
mov ax, ' :'
stosw
mov al, 0x01
stosb
; copy the message itself
@@:
lodsb
test al, al
jz @f
cmp al, 13
je @f
cmp al, 10
je @f
stosb
jmp @r
@@:
; end of message
mov al, 0x01
stosb
mov ax, 0x0a0d
stosw
; now send it away
lea esi, [edi - packetbuf] ; calculate length
mcall send, [socketnum], packetbuf, , 0 ; and finally send to server
;; TODO: print to window
.fail:
ret
cmd_usr_me:
; prepare a 'PRIVMSG '
mov dword[packetbuf], 'PRIV'
mov dword[packetbuf+4], 'MSG '
lea edi, [packetbuf+8]
; append the destination (nickname/channel)
mov esi, [window_active]
lea esi, [esi + window.name]
@@:
lodsb
test al, al
je @f
stosb
jmp @r
@@:
; Make the CTCP action header
mov eax, ' :' + 0x01 shl 16 + 'A' shl 24
stosd
mov eax, 'CTIO'
stosd
mov al, 'N'
stosb
; copy the message itself (including first space)
mov esi, usercommand+3
@@:
lodsb
cmp al, 13
je @f
stosb
jmp @r
@@:
; end of CTCP message
mov al, 0x01
stosb
mov ax, 0x0a0d
stosw
; now send it to the server
lea esi, [edi - packetbuf] ; calculate length
mcall send, [socketnum], packetbuf, , 0 ; and finally send to server
; print to local window
if TIMESTAMP
call print_timestamp
end if
mov esi, action_header
call print_asciiz
mov esi, user_nick
call print_asciiz
mov esi, usercommand+3
mov bl, 13
call print_string
mov al, 10
call print_char
ret
; The user typed some undefined command, just recode it and send to the server
cmd_usr_send:
mov esi, usercommand+1
mov ecx, [edit1.size]
inc ecx
mov edi, packetbuf
call recode
lea esi, [edi - packetbuf]
mcall send, [socketnum], packetbuf, , 0
ret