Better NICK command support, support for channels with many users.

git-svn-id: svn://kolibrios.org@3222 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
hidnplayr 2013-02-03 22:52:24 +00:00
parent b1255773b2
commit ff07ff5192
3 changed files with 78 additions and 156 deletions

View File

@ -24,6 +24,7 @@ STATUS_CONNECTED = 3
; window flags ; window flags
FLAG_UPDATED = 1 shl 0 FLAG_UPDATED = 1 shl 0
FLAG_CLOSE = 1 shl 1 FLAG_CLOSE = 1 shl 1
FLAG_RECEIVING_NAMES = 1 shl 2
; window types ; window types
WINDOWTYPE_SERVER = 0 WINDOWTYPE_SERVER = 0
@ -49,6 +50,7 @@ TEXT_Y = 45
TOP_Y = 40 TOP_Y = 40
MAX_WINDOWS = 20 MAX_WINDOWS = 20
MAX_USERS = 4096
MAX_NICK_LEN = 32 MAX_NICK_LEN = 32
MAX_REAL_LEN = 32 ; realname MAX_REAL_LEN = 32 ; realname
@ -104,7 +106,7 @@ ends
struct window_data struct window_data
text rb 120*60 text rb 120*60
title rb 256 title rb 256
names rb 1200 names rb MAX_NICK_LEN * MAX_USERS
usertext rb 256 usertext rb 256
usertextlen dd ? usertextlen dd ?
ends ends
@ -311,7 +313,7 @@ ctcp_time db '] TIME',10,0
has_left_channel db ' has left ', 0 has_left_channel db ' has left ', 0
joins_channel db ' has joined ', 0 joins_channel db ' has joined ', 0
is_now_known_as db ' is now known as ', 0 is_now_known_as db ' is now known as ', 0
has_quit_irc db ' has quit IRC', 0 has_quit_irc db ' has quit IRC', 10, 0
sets_mode db ' sets mode ', 0 sets_mode db ' sets mode ', 0
kicked db ' is kicked from ', 0 kicked db ' is kicked from ', 0
str_talking db 'Now talking in ',0 str_talking db 'Now talking in ',0

View File

@ -534,7 +534,7 @@ cmd_join:
call print_text2 call print_text2
mov eax, servercommand+1 mov eax, servercommand+1
mov dl, ' ' mov dl, '!'
call print_text call print_text
mov esi, joins_channel mov esi, joins_channel
@ -553,137 +553,37 @@ cmd_join:
cmd_nick: ; FIXME cmd_nick:
add esi, 5 ; skip 'NICK ' add esi, 5 ; skip 'NICK '
push esi push esi
; test for change of my nick ; Is it me who changed nick?
mov esi, servercommand+1
mov edi, user_nick
mov ecx, MAX_NICK_LEN
rep cmpsb
cmp byte[edi-1], 0
jne .notmy
cmp byte[esi-1], '!'
jne .notmy
; yes, this is my nick, set to new
pop esi
or ecx, -1
mov edi, esi
xor eax, eax
repne scasb
neg ecx
cmp ecx, MAX_NICK_LEN
jb @f
mov ecx, MAX_NICK_LEN
@@:
mov edi, user_nick
rep movsb
.notmy:
; replace nick in all lists of users
mov ebx, windows
.channels:
mov esi, [ebx + window.data_ptr]
lea esi, [esi + window_data.names]
;;;;; mov edx, [esi + window_data.nameslen]
add edx, esi
.nicks:
mov edi, servercommand+1 mov edi, servercommand+1
cmp byte[esi], '@' call compare_to_nick
jne @f jne .not_me
inc esi
@@: mov ecx, MAX_NICK_LEN-1
cmp esi, edx
jae .srcdone
lodsb
cmp al, ' '
je .srcdone
scasb
je @b
@@:
cmp esi, edx
jae .nextchannel
lodsb
cmp al, ' '
jne @b
.nextnick:
cmp esi, edx
jae .nextchannel
lodsb
cmp al, ' '
jz .nextnick
dec esi
jmp .nicks
.srcdone:
cmp byte [edi], '!'
jne .nextnick
; here we have esi -> end of nick which must be replaced to [servercommand_position]+6
lea edx, [edi-servercommand-1]
sub esi, edx
or ecx, -1
xor eax, eax
; mov edi, [servercommand_position] ;;;;; FIXME
repnz scasb
not ecx
dec ecx
push ecx
cmp ecx, edx
jb .decrease
jz .copy
.increase:
; new nick is longer than the old
push esi push esi
lea edi, [ebx+120*10] ;;;;;; .copyloop:
lea esi, [edi+edx] lodsb
sub esi, ecx test al, al
mov ecx, esi jz .copydone
sub ecx, [esp] cmp al, ' '
dec esi je .copydone
dec edi
std
rep movsb
cld
pop esi
jmp .copy
.decrease:
; new nick is shorter than the old
push esi
lea edi, [esi+ecx]
add esi, edx
lea ecx, [ebx+120*10]
sub ecx, edi
rep movsb
pop esi
.copy:
; copy nick
mov edi, esi
dec edi
; mov esi, [servercommand_position] ;;;;; FIXME
pop ecx
sub edx, ecx
sub [ebx-4], edx
rep movsb
mov al, ' '
stosb stosb
dec ecx
jnz .copyloop
.copydone:
xor al, al
stosb
pop esi
.nextchannel: .not_me:
add ebx, sizeof.window
cmp ebx, windows + sizeof.window*MAX_WINDOWS
jb .channels
; mov [text_start], window_text + 120*80 ; TODO: if we reach here: change nick in userlist(s)
new_all_channels3:
push esi
mov esi, action_header_short mov esi, action_header_short
call print_text2 call print_text2
@ -694,16 +594,11 @@ cmd_nick: ; FIXME
mov esi, is_now_known_as mov esi, is_now_known_as
call print_text2 call print_text2
; mov esi,[servercommand_position] ;;;;; FIXME pop esi
call print_text2 call print_text2
;;; call notify_channel_thread mov esi, str_newline
call print_text2
; go to next window (and check if its a channel!)
; add [text_start], 120*80
; cmp [text_start], I_END+120*80*20
; jb new_all_channels3
ret ret
@ -735,6 +630,9 @@ cmd_kick:
pop esi pop esi
call print_text2 call print_text2
mov esi, str_newline
call print_text2
;;; TODO: dec [window.users], remove username from the userlist ;;; TODO: dec [window.users], remove username from the userlist
ret ret
@ -789,8 +687,6 @@ cmd_353: ; channel usernames reply
add esi, 4 ; skip '353 ' add esi, 4 ; skip '353 '
; TODO: mark a bit that we are receiving names
; first, find the channel name ; first, find the channel name
.loop1: .loop1:
lodsb lodsb
@ -798,46 +694,67 @@ cmd_353: ; channel usernames reply
je .got_channel je .got_channel
test al, al test al, al
jnz .loop1 jnz .loop1
ret ret
.got_channel: .got_channel:
; call find_channel ;;;; ASSUME current channel for now
mov ebx, [window_print]
mov [ebx + window.users], 0 ;;; FIXME: Only if we have just set the receiving names bit
mov eax, [ebx + window.data_ptr]
lea edi, [eax + window_data.names]
mov edx, edi
; now find the semicolon separating channelname and usernames ; now find the semicolon separating channelname and usernames
.loop2: .loop2:
lodsb lodsb
cmp al, ':' cmp al, ':'
je .newname je .got_list
test al, al test al, al
jnz .loop2 jnz .loop2
ret ret
.got_list:
; now find window ptr and check if this is the first 353 message
mov ebx, [window_print]
test [ebx + window.flags], FLAG_RECEIVING_NAMES
jnz .start
or [ebx + window.flags], FLAG_RECEIVING_NAMES
mov [ebx + window.users], 0
.start:
mov eax, [ebx + window.users]
xor edx, edx
mov ecx, MAX_NICK_LEN
mul ecx
; eax is now offset
add eax, [ebx + window.data_ptr]
lea edi, [eax + window_data.names]
mov edx, edi
lea ecx, [eax + window_data.names]
add ecx, MAX_NICK_LEN + MAX_USERS
.newname:
cmp edi, ecx ; check buffer overflow
jae .done
inc [ebx + window.users]
.namesloop:
lodsb
test al, al
jz .done
cmp al, ' ' ; names list is separated with spaces
je .next
stosb
jmp .namesloop
.next: .next:
add edx, MAX_NICK_LEN add edx, MAX_NICK_LEN
mov edi, edx mov edi, edx
;;; cmp edi, .. ; TODO: Check for buffer overflow .loop3:
.newname:
inc [ebx + window.users]
.namesloop:
; now the names list begins, separated with spaces
lodsb lodsb
test al, al test al, al
jz .done jz .done
cmp al, ' ' cmp al, ' '
jz .next je .loop3
stosb stosb
jmp .namesloop jmp .newname
.done: .done:
call redraw_channel_list call redraw_channel_list
ret ret
@ -848,7 +765,8 @@ cmd_353: ; channel usernames reply
cmd_366: ; channel usernames end cmd_366: ; channel usernames end
; TODO: clear the bit that we are receiving names mov ebx, [window_print]
and [ebx + window.flags], not FLAG_RECEIVING_NAMES
ret ret

View File

@ -222,13 +222,15 @@ read_incoming_data:
jnc .nextpacket ; if CF is set, we need more data jnc .nextpacket ; if CF is set, we need more data
cmp al, 10 cmp al, 10
je .got_command je .got_command
cmp al, 13
je .got_command
stosb stosb
jmp .byteloop jmp .byteloop
; we have a command, call the serverparser ; we have a command, call the serverparser
.got_command: .got_command:
mov byte[edi-1], 0 ; mark the end of the command mov byte[edi], 0 ; mark the end of the command
push esi edx push esi edx
call server_parser call server_parser
pop edx esi pop edx esi