Subversion Repositories Kolibri OS

Rev

Rev 3216 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
3191 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
3
;; Copyright (C) KolibriOS team 2004-2013. All rights reserved.    ;;
4
;; Distributed under terms of the GNU General Public License       ;;
5
;;                                                                 ;;
6
;;                                                                 ;;
7
;;         GNU GENERAL PUBLIC LICENSE                              ;;
8
;;          Version 2, June 1991                                   ;;
9
;;                                                                 ;;
10
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
11
 
12
 
13
server_parser:
14
 
15
        mov     esi, servercommand
16
 
17
        cmp     byte [esi], ':'
18
        jne     .parse
19
 
20
  .spaceloop:
21
        lodsb
22
        test    al, al
23
        jz      .fail
24
        cmp     al, ' '
25
        jne     .spaceloop
26
 
27
  .parse:
28
        mov     eax, [esi]
29
        or      eax, 0x20202020
30
        mov     edi, server_commands
31
        mov     ecx, server_commands.number
32
 
33
  .loop:
34
        scasd
35
        je      .got_cmd
36
        add     edi, 4
37
        dec     ecx
38
        jnz     .loop
39
 
40
  .fail:
41
        ret
42
 
43
  .got_cmd:
3215 hidnplayr 44
        jmp     dword[edi]
3191 hidnplayr 45
 
46
 
47
server_commands:
48
 
49
        dd      '328 ', cmd_328
50
        dd      '332 ', cmd_topic
51
        dd      '333 ', cmd_333         ; nickname and time of topic
52
        dd      '353 ', cmd_353         ; name reply
53
        dd      '366 ', cmd_366         ; end of names list
54
        dd      '372 ', cmd_372         ; motd
55
        dd      '375 ', cmd_375         ; start of motd
56
        dd      '376 ', cmd_376         ; end of motd
57
        dd      '421 ', cmd_421         ; unknown command
58
        dd      'join', cmd_join
59
        dd      'kick', cmd_kick
60
        dd      'mode', cmd_mode
61
        dd      'nick', cmd_nick
62
        dd      'part', cmd_part
63
        dd      'ping', cmd_ping
64
        dd      'priv', cmd_privmsg
65
        dd      'quit', cmd_quit
66
        dd      'noti', cmd_notice
67
 
68
        .number = ($ - server_commands) / 8
69
 
70
compare_to_nick:
71
 
72
        push    esi
73
        mov     ecx, MAX_NICK_LEN
74
        mov     esi, user_nick
75
  .loop:
76
        lodsb
77
        cmp     al, ' '
78
        jbe     .done
79
        cmp     al, 'a'
80
        jb      .ok
81
        cmp     al, 'z'
82
        ja      .ok
83
        sub     al, 0x20
84
  .ok:
85
 
86
        mov     bl, byte[edi]
87
        cmp     bl, 'a'
88
        jb      .ok2
89
        cmp     bl, 'z'
90
        ja      .ok2
91
        sub     bl, 0x20
92
  .ok2:
93
        cmp     bl, al
94
        jne     .not_equal
95
        inc     edi
96
        dec     ecx
97
        jnz     .loop
98
 
99
  .done:
100
        xor     eax, eax
101
        pop     esi
102
        ret
103
 
104
  .not_equal:
105
        or      eax, -1
106
        pop     esi
107
        ret
108
 
109
 
110
 
111
find_window:
112
 
113
;        mov     [window_print],
114
 
115
        ret
116
 
117
 
118
 
119
cmd_328:
120
cmd_421:
121
cmd_372:
122
cmd_375:
123
cmd_376:
124
        add     esi, 4
125
        jmp     cmd_notice.loop
126
 
127
cmd_notice:
128
 
129
        cmp     byte[servercommand], ':'
130
        jne     .gogogo
131
 
132
        mov     byte [esi-1], 0
133
        push    esi
134
        mov     esi, str_1
135
        call    print_text2
136
        mov     esi, servercommand+1
137
        call    print_text2
138
        mov     esi, str_2
139
        call    print_text2
140
        pop     esi
141
 
142
  .gogogo:
143
        add     esi, 6
144
 
145
  .loop:
146
        inc     esi
147
        cmp     byte [esi], 0
148
        je      .fail
3212 hidnplayr 149
;        cmp     byte [esi], 10  ; newline
150
;        je      server_parser.parse
3191 hidnplayr 151
        cmp     byte [esi], ' '
152
        jne     .loop
153
 
154
  .loop2:
155
        inc     esi
156
        cmp     byte [esi], 0
157
        je      .fail
158
        cmp     byte [esi], ' '
159
        je      .loop2
160
        cmp     byte [esi], ':'
161
        je      .loop2
162
 
163
        call    print_text2
164
        mov     esi, str_newline
165
        call    print_text2
166
 
167
  .fail:
168
 
169
        ret
170
 
171
 
172
 
173
cmd_ping:
174
 
175
; Just change PING to PONG
176
        mov     dword[esi], 'PONG'
177
 
178
; Find the end of the command
179
        lea     edi, [esi + 5]
180
        xor     al, al
181
        repne   scasb
182
 
183
; Now send it back
184
        mov     edx, esi
185
        mov     esi, edi
186
        mov     word [esi], 0x0d0a
187
        inc     esi
188
        inc     esi
189
        sub     esi, edx
190
        mcall   send, [socketnum], , , 0
191
 
192
        ret
193
 
194
 
195
 
196
cmd_privmsg:
197
 
3214 hidnplayr 198
        add     esi, 8  ; skip 'PRIVMSG '
199
 
3191 hidnplayr 200
; Check if it was destined for me privately
201
        mov     edi, servercommand+1
202
        call    compare_to_nick
203
;;;        je      .private
204
 
205
; If not, find the correct window ???
206
 
207
; now find the end of nick
208
        mov     edi, esi
209
  .loop:
210
        inc     edi
211
        cmp     byte [edi], 0
212
        je      .fail
213
        cmp     byte [edi], ' '
214
        jne     .loop
215
 
216
  .loop2:
217
        inc     edi
218
        cmp     byte [edi], 0
219
        je      .fail
220
        cmp     byte [edi], ' '
221
        je      .loop2
222
        cmp     byte [edi], ':'
223
        je      .loop2
224
        cmp     byte [edi], 1
225
        je      cmd_ctcp
226
 
227
; Action?
228
        cmp     dword[edi+1], 'ACTI'
229
        je      .action
230
 
231
; nope, just plain old privmsg
232
if TIMESTAMP
233
        call    print_timestamp
234
end if
235
 
236
        push    edi
237
        mov     bl, '<'
238
        call    print_character
239
 
240
        mov     eax, servercommand+1
241
        mov     dl, '!'
242
        call    print_text
243
 
244
        mov     bl, '>'
245
        call    print_character
246
 
247
        mov     bl, ' '
248
        call    print_character
249
 
250
        pop     esi
251
        call    print_text2
252
 
253
        mov     bl, 10
254
        call    print_character
255
 
256
  .fail:
257
        ret
258
 
259
  .action:
260
        push    edi
261
        if TIMESTAMP
262
        call    print_timestamp
263
        end if
264
 
265
        mov     esi, action_header_short
266
        call    print_text2
267
 
268
        mov     eax, servercommand+1
269
        mov     dl, ' '
270
        call    print_text
271
 
272
        mov     bl, ' '
273
        call    print_character
274
 
275
        pop     esi
276
        add     esi, 8
277
        call    print_text2
278
 
279
        mov     bl, 10
280
        call    print_character
281
 
282
        ret
283
 
284
cmd_ctcp:
285
 
286
        cmp     dword[edi+1], 'VERS'
287
        je      .version
288
 
289
        cmp     dword[edi+1], 'TIME'
290
        je      .time
291
 
292
        cmp     dword[edi+1], 'PING'
293
        je      .ping
294
 
295
        ret
296
 
297
  .time:
298
        lea     esi, [edi+1]
299
        mov     byte [edi+5], ' '
300
        add     edi, 6
301
 
302
        ; TODO: add system date (fn 29) in human readable format
303
 
304
        mcall   3                       ; get system time
305
 
306
        mov     ecx, 3
307
  .timeloop:
308
        mov     bl, al
309
        shr     al, 4
310
        add     al, '0'
311
        stosb
312
 
313
        mov     al, bl
314
        and     al, 0x0f
315
        add     al, '0'
316
        stosb
317
 
318
        dec     ecx
319
        jz      .timedone
320
 
321
        mov     al, ':'
322
        stosb
323
        shr     eax, 8
324
        jmp     .timeloop
325
 
326
  .timedone:
327
        xor     al, al
328
        stosb
329
        call    ctcp_reply
330
 
331
        if TIMESTAMP
332
        call    print_timestamp
333
        end if
334
 
335
        mov     esi, ctcp_header
336
        call    print_text2
337
 
338
        mov     esi, servercommand+1
339
        call    print_text2
340
 
341
        mov     esi, ctcp_time
342
        call    print_text2
343
 
344
        ret
345
 
346
  .version:
347
        mov     esi, str_version
348
        call    ctcp_reply
349
 
350
        if TIMESTAMP
351
        call    print_timestamp
352
        end if
353
 
354
        mov     esi, ctcp_header
355
        call    print_text2
356
 
357
        mov     esi, servercommand+1
358
        call    print_text2
359
 
360
        mov     esi, ctcp_version
361
        call    print_text2
362
 
363
        ret
364
 
365
  .ping:
366
        lea     esi, [edi+1]
367
        call    ctcp_reply
368
 
369
        if TIMESTAMP
370
        call    print_timestamp
371
        end if
372
 
373
        mov     esi, ctcp_header
374
        call    print_text2
375
 
376
        mov     esi, servercommand+1
377
        call    print_text2
378
 
379
        mov     esi, ctcp_ping
380
        call    print_text2
381
 
382
        ret
383
 
384
 
385
 
386
ctcp_reply:
387
 
388
        push    esi
389
 
390
        mov     dword [usercommand], 'NOTI'
391
        mov     dword [usercommand+4], 'CE  '
392
 
393
        mov     esi, servercommand+1
394
        mov     edi, usercommand+7
395
  .nickloop:
396
        lodsb
397
        cmp     al, '!'
398
        je      .done
399
        cmp     al, ' '
400
        je      .done
401
        test    al, al
402
        je      .fail
403
        stosb
404
        jmp     .nickloop
405
  .done:
406
        mov     byte [esi-1], 0
407
        mov     ax, ' :'
408
        stosw
409
        mov     al, 1
410
        stosb
411
 
412
        pop     esi
413
  .replyloop:
414
        lodsb
415
        cmp     al, 1
416
        jbe     .done2
417
        stosb
418
        jmp     .replyloop
419
  .done2:
420
 
421
        mov     al, 1
422
        stosb
423
        mov     ax, 0x0a0d
424
        stosw
425
 
426
        lea     esi, [edi - usercommand]
427
        mcall   send, [socketnum], usercommand, , 0
428
  .fail:
429
        ret
430
 
431
 
432
 
433
cmd_part:
3215 hidnplayr 434
        add     esi, 5  ; skip 'PART '
3191 hidnplayr 435
 
436
; Is it me who parted?
437
        mov     edi, servercommand+1
438
        call    compare_to_nick
439
        jne     .dont_close
440
 
441
; yes, close the window
442
        mov     edi, [window_print]
443
        mov     [edi + window.flags], FLAG_UPDATED + FLAG_CLOSE
444
 
445
        ret
446
 
447
; somebody else parted, just print message
448
  .dont_close:
449
        push    esi
450
        mov     esi, action_header
451
        call    print_text2
452
 
453
        mov     eax, servercommand+1
454
        mov     dl, '!'
455
        mov     cl, ' '
456
        call    print_text
457
 
458
        mov     esi, has_left_channel
459
        call    print_text2
460
 
461
        pop     esi
462
        call    print_text2
463
 
3215 hidnplayr 464
        mov     esi, str_newline
465
        call    print_text2
466
 
467
;;; TODO: dec [window.users], remove username from the userlist
468
 
469
 
3191 hidnplayr 470
        ret
471
 
472
 
473
 
474
cmd_join:
3215 hidnplayr 475
        add     esi, 5  ; skip 'JOIN '
476
 
3191 hidnplayr 477
; compare nick: did we join a channel?
478
        mov     edi, servercommand+1
479
        call    compare_to_nick
480
        jne     .no_new_window
481
 
482
; create channel window - search for empty slot
483
        mov     ebx, windows
484
        mov     ecx, MAX_WINDOWS
485
  .loop:
486
        cmp     [ebx + window.data_ptr], 0
487
        je      .free_found
488
        add     ebx, sizeof.window
489
        dec     ecx
490
        jnz     .loop
491
; Error: no more available windows!! ;;;;; TODO
492
  .fail:
493
        ret
494
 
495
  .free_found:
496
        push    ebx
497
        call    window_create
498
        pop     ebx
499
        test    eax, eax
500
        jz      .fail
501
        mov     [ebx + window.data_ptr], eax
502
        mov     [ebx + window.type], WINDOWTYPE_CHANNEL
503
        mov     [ebx + window.flags], 0
3214 hidnplayr 504
 
3191 hidnplayr 505
        call    window_set_name
506
 
507
        mov     [window_open], ebx
508
        mov     [window_print], ebx
509
        call    window_refresh
510
 
511
        push    esi
512
        mov     esi, action_header
513
        call    print_text2
514
 
515
        mov     esi, str_talking
516
        call    print_text2
517
 
518
        pop     eax
519
        mov     dl, ' '
520
        call    print_text
521
 
522
        mov     esi, str_dotnewline
523
        call    print_text2
524
 
525
        call    draw_window
526
 
527
        ret
528
 
529
  .no_new_window:
530
        push    esi
531
        call    window_set_name
532
 
533
        mov     esi, action_header
534
        call    print_text2
535
 
536
        mov     eax, servercommand+1
537
        mov     dl, ' '
538
        call    print_text
539
 
540
        mov     esi, joins_channel
541
        call    print_text2
542
 
543
        pop     esi
544
        call    print_text2
545
 
546
        mov     esi, str_newline
547
        call    print_text2
548
 
3215 hidnplayr 549
;;; TODO: inc [window.users], add username to the userlist
550
 
3191 hidnplayr 551
        ret
552
 
553
 
554
 
555
 
556
cmd_nick:       ; FIXME
557
 
3215 hidnplayr 558
        add     esi, 5  ; skip 'NICK '
559
 
3191 hidnplayr 560
        push    esi
561
; test for change of my nick
562
        mov     esi, servercommand+1
563
        mov     edi, user_nick
564
        mov     ecx, MAX_NICK_LEN
565
        rep     cmpsb
566
        cmp     byte[edi-1], 0
567
        jne     .notmy
568
        cmp     byte[esi-1], '!'
569
        jne     .notmy
570
 
571
; yes, this is my nick, set to new
572
        pop     esi
573
        or      ecx, -1
574
        mov     edi, esi
575
        xor     eax, eax
576
        repne   scasb
577
        neg     ecx
578
        cmp     ecx, MAX_NICK_LEN
579
        jb      @f
580
        mov     ecx, MAX_NICK_LEN
581
      @@:
582
        mov     edi, user_nick
583
        rep     movsb
584
  .notmy:
585
 
586
; replace nick in all lists of users
587
        mov     ebx, windows
588
  .channels:
589
        mov     esi, [ebx + window.data_ptr]
590
        lea     esi, [esi + window_data.names]
591
;;;;;        mov     edx, [esi + window_data.nameslen]
592
        add     edx, esi
593
  .nicks:
594
        mov     edi, servercommand+1
595
        cmp     byte[esi], '@'
596
        jne     @f
597
        inc     esi
598
 
599
  @@:
600
        cmp     esi, edx
601
        jae     .srcdone
602
        lodsb
603
        cmp     al, ' '
604
        je      .srcdone
605
        scasb
606
        je      @b
607
 
608
  @@:
609
        cmp     esi, edx
610
        jae     .nextchannel
611
        lodsb
612
        cmp     al, ' '
613
        jne     @b
614
 
615
  .nextnick:
616
        cmp     esi, edx
617
        jae     .nextchannel
618
        lodsb
619
        cmp     al, ' '
620
        jz      .nextnick
621
        dec     esi
622
        jmp     .nicks
623
 
624
 
625
  .srcdone:
626
        cmp     byte [edi], '!'
627
        jne     .nextnick
628
 
629
; here we have esi -> end of nick which must be replaced to [servercommand_position]+6
630
        lea     edx, [edi-servercommand-1]
631
        sub     esi, edx
632
        or      ecx, -1
633
        xor     eax, eax
634
;        mov     edi, [servercommand_position]        ;;;;; FIXME
635
        repnz   scasb
636
        not     ecx
637
        dec     ecx
638
        push    ecx
639
        cmp     ecx, edx
640
        jb      .decrease
641
        jz      .copy
642
  .increase:
643
 
644
; new nick is longer than the old
645
        push    esi
646
        lea     edi, [ebx+120*10] ;;;;;;
647
        lea     esi, [edi+edx]
648
        sub     esi, ecx
649
        mov     ecx, esi
650
        sub     ecx, [esp]
651
        dec     esi
652
        dec     edi
653
        std
654
        rep     movsb
655
        cld
656
        pop     esi
657
        jmp     .copy
658
  .decrease:
659
; new nick is shorter than the old
660
        push    esi
661
        lea     edi, [esi+ecx]
662
        add     esi, edx
663
        lea     ecx, [ebx+120*10]
664
        sub     ecx, edi
665
        rep     movsb
666
        pop     esi
667
  .copy:
668
; copy nick
669
        mov     edi, esi
670
        dec     edi
671
;        mov     esi, [servercommand_position]        ;;;;; FIXME
672
        pop     ecx
673
        sub     edx, ecx
674
        sub     [ebx-4], edx
675
        rep     movsb
676
        mov     al, ' '
677
        stosb
678
 
679
  .nextchannel:
680
        add     ebx, sizeof.window
681
        cmp     ebx, windows + sizeof.window*MAX_WINDOWS
682
        jb      .channels
683
 
684
;        mov  [text_start], window_text + 120*80
685
 new_all_channels3:
686
 
687
        mov     esi, action_header_short
688
        call    print_text2
689
 
690
        mov     eax, servercommand+1
691
        mov     dl,'!'
692
        call    print_text
693
 
694
        mov     esi,is_now_known_as
695
        call    print_text2
696
 
697
;       mov     esi,[servercommand_position]        ;;;;; FIXME
698
        call    print_text2
699
 
700
;;;        call    notify_channel_thread
701
 
702
; go to next window (and check if its a channel!)
703
 
704
;        add     [text_start], 120*80
705
;        cmp     [text_start], I_END+120*80*20
706
;        jb      new_all_channels3
707
 
708
        ret
709
 
710
 
711
 
712
 
713
cmd_kick:
3215 hidnplayr 714
        add     esi, 5  ; skip 'KICK '
3191 hidnplayr 715
; Is it me who got kicked?
716
        mov     edi, servercommand+1
717
        call    compare_to_nick
718
        jne     .not_me
719
 
720
; TODO: mark channel as disconnected
721
 
722
  .not_me:
723
; find the channel user has been kicked from
724
        push    esi
725
        mov     esi, action_header_short
726
        call    print_text2
727
 
728
        mov     eax, servercommand+1
729
        mov     dl,'!'
730
        call    print_text
731
 
732
        mov     esi, kicked
733
        call    print_text2
734
 
735
        pop     esi
736
        call    print_text2
737
 
3215 hidnplayr 738
;;; TODO: dec [window.users], remove username from the userlist
739
 
3191 hidnplayr 740
        ret
741
 
742
 
743
 
744
cmd_quit:
745
 
746
        mov     esi, action_header
747
        call    print_text2
748
 
749
        mov     eax, servercommand+1
750
        mov     dl, '!'
751
        call    print_text
752
 
753
        mov     esi, has_quit_irc
754
        call    print_text2
755
 
3215 hidnplayr 756
;;; TODO: dec [window.users], remove username from the userlist
757
 
3191 hidnplayr 758
        ret
759
 
760
 
761
 
762
cmd_mode:
763
 
3215 hidnplayr 764
        add     esi, 5  ; skip 'MODE '
765
 
3191 hidnplayr 766
        push    esi
767
        mov     esi, action_header_short
768
        call    print_text2
769
 
770
        mov     eax, servercommand+1
771
        mov     dl, ' '
772
        call    print_text
773
 
774
        mov     esi, sets_mode
775
        call    print_text2
776
 
777
        pop     esi
778
        call    print_text2
779
 
780
        mov     esi, str_newline
781
        call    print_text2
782
 
3215 hidnplayr 783
;;; TODO: change username if needed
784
 
3191 hidnplayr 785
        ret
786
 
787
 
788
cmd_353:        ; channel usernames reply
789
 
3215 hidnplayr 790
        add     esi, 4  ; skip '353 '
791
 
3191 hidnplayr 792
; TODO: mark a bit that we are receiving names
793
 
794
; first, find the channel name
795
  .loop1:
796
        lodsb
797
        cmp     al, '#'
798
        je      .got_channel
799
        test    al, al
800
        jnz     .loop1
801
 
802
        ret
803
 
804
  .got_channel:
805
;        call    find_channel   ;;;; ASSUME current channel for now
806
        mov     ebx, [window_print]
3215 hidnplayr 807
        mov     [ebx + window.users], 0              ;;; FIXME: Only if we have just set the receiving names bit
808
        mov     eax, [ebx + window.data_ptr]
809
        lea     edi, [eax + window_data.names]
3216 hidnplayr 810
        mov     edx, edi
3191 hidnplayr 811
 
812
; now find the semicolon separating channelname and usernames
813
  .loop2:
814
        lodsb
815
        cmp     al, ':'
3216 hidnplayr 816
        je      .newname
3191 hidnplayr 817
        test    al, al
818
        jnz     .loop2
819
 
820
        ret
821
 
3216 hidnplayr 822
  .next:
823
        add     edx, MAX_NICK_LEN
824
        mov     edi, edx
825
;;;        cmp     edi, ..              ; TODO: Check for buffer overflow
826
 
827
  .newname:
828
        inc     [ebx + window.users]
3191 hidnplayr 829
  .namesloop:
830
; now the names list begins, separated with spaces
831
        lodsb
832
        test    al, al
833
        jz      .done
834
        cmp     al, ' '
835
        jz      .next
836
        stosb
837
        jmp     .namesloop
838
 
839
  .done:
840
 
3220 hidnplayr 841
        call    redraw_channel_list
3191 hidnplayr 842
 
3215 hidnplayr 843
        ret
844
 
845
 
846
 
847
 
848
 
3191 hidnplayr 849
cmd_366:        ; channel usernames end
850
 
851
; TODO: clear the bit that we are receiving names
852
 
853
 
854
        ret
855
 
856
 
857
cmd_topic:
858
 
3215 hidnplayr 859
        add     esi, 4  ; skip '332 '
860
 
3191 hidnplayr 861
  .loop:
862
        lodsb
863
        test    al, al
864
        je      .fail
865
        cmp     al, ':'
866
        jne     .loop
867
 
868
        push    esi
869
        mov     esi, action_header
870
        call    print_text2
871
 
872
        mov     esi, str_topic
873
        call    print_text2
874
 
875
        pop     esi
876
        call    print_text2
877
 
878
        mov     esi, str_newline
879
        call    print_text2
880
 
881
  .fail:
882
        ret
883
 
884
 
885
cmd_333:
886
 
3215 hidnplayr 887
        add     esi, 4  ; skip '333 '
888
 
3191 hidnplayr 889
; TODO: check channelname and change pointer accordingly
890
 
891
        mov     ecx, 3  ; number of spaces to find
892
  .loop:
893
        lodsb
894
        test    al, al
895
        je      .fail
896
        cmp     al, ' '
897
        jne     .loop
898
        dec     ecx
899
        jnz     .loop   ; find some more spaces
900
 
901
        push    esi
902
        mov     esi, action_header
903
        call    print_text2
904
 
905
        mov     esi, str_setby
906
        call    print_text2
907
 
908
        pop     esi
909
        call    print_text2
910
 
911
        mov     esi, str_newline
912
        call    print_text2
913
 
914
  .fail:
915
        ret
916