rnd-19981017-1
[rocksndiamonds.git] / src / netserv.c
1 /*
2  *   A server for a multi-player version of Tetris
3  *
4  *   Copyright (C) 1996 Roger Espel Llima <roger.espel.llima@pobox.com>
5  *
6  *   Started: 10 Oct 1996
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation. See the file COPYING for details.
11  *
12  */
13
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <unistd.h>
17 #include <fcntl.h>
18 #include <sys/types.h>
19 #include <sys/time.h>
20 #include <signal.h>
21 #include <sys/socket.h>
22 #include <errno.h>
23 #include <string.h>
24 #include <netinet/in.h>
25 #include <netinet/tcp.h>
26 #include <arpa/inet.h>
27 #include <netdb.h>
28
29 #include "netserv.h"
30 #include "misc.h"
31
32 static int clients = 0;
33 static int bots = 0;
34 static int onceonly = 0;
35 static int timetoplay = 0;
36 static int is_daemon = 0;
37 static int levelnr = 5;
38 static int mode = -1;
39 static int paused = 0;
40
41 struct user
42 {
43   int fd;
44   unsigned char nick[16];
45   unsigned char number;
46   struct user *next, *nextvictim;
47   char active;
48   char introduced;
49   unsigned char readbuf[MAX_BUFFER_SIZE];
50   int nread;
51   unsigned char writbuf[MAX_BUFFER_SIZE];
52   int nwrite;
53   char playing;
54   char isbot;
55   int lines;
56   unsigned int games;
57   unsigned char action;
58   int action_received;
59 };
60
61 static struct user *user0 = NULL;
62
63 #define NEXT(u) ((u)->next ? (u)->next : user0)
64
65 static struct sockaddr_in saddr;
66 static int lfd;
67 static unsigned char realbuf[512], *buf = realbuf + 4;
68
69 static int interrupt;
70 static int tcp = -1;
71
72 static unsigned long frame_counter = 0;
73
74 static fd_set fds;
75
76 static void syserr(char *s)
77 {
78   if (!is_daemon)
79     fprintf(stderr, "fatal: %s failed.\n", s);
80   exit(1);
81 }
82
83 static void addtobuffer(struct user *u, unsigned char *b, int len)
84 {
85   if (u->nwrite + len >= MAX_BUFFER_SIZE)
86     Error(ERR_EXIT, "internal error: network send buffer overflow");
87
88   memcpy(u->writbuf + u->nwrite, b, len);
89   u->nwrite += len;
90 }
91
92 static void flushuser(struct user *u)
93 {
94   if (u->nwrite)
95   {
96     write(u->fd, u->writbuf, u->nwrite);
97     u->nwrite = 0;
98   }
99 }
100
101 static void broadcast(struct user *except, int len, int activeonly)
102 {
103   struct user *u;
104
105   realbuf[0] = realbuf[1] = realbuf[2] = 0;
106   realbuf[3] = (unsigned char)len;
107   for (u=user0; u; u=u->next)
108     if (u != except && (u->active || !activeonly) && u->introduced)
109       addtobuffer(u, realbuf, 4 + len);
110 }
111
112 static void sendtoone(struct user *to, int len)
113 {
114   realbuf[0] = realbuf[1] = realbuf[2] = 0;
115   realbuf[3] = (unsigned char)len;
116   addtobuffer(to, realbuf, 4 + len);
117 }
118
119 static void dropuser(struct user *u)
120 {
121   struct user *v, *w;
122   
123   if (options.verbose)
124     printf("RND_SERVER: dropping client %d (%s)\n", u->number, u->nick);
125
126   if (u == user0)
127     user0 = u->next;
128   else
129   {
130     for (v=user0; v; v=v->next)
131     {
132       if (v->next && v->next == u)
133       {
134         v->next = u->next;
135         break;
136       }
137     }
138   }
139   close(u->fd);
140
141   if (u->introduced)
142   {
143     buf[0] = u->number;
144     buf[1] = OP_PLAYER_DISCONNECTED;
145     broadcast(u, 2, 0);
146   }
147
148   for (v=user0; v; v=v->next)
149   {
150     if (v->nextvictim == u)
151     {
152       for (w=NEXT(v); w!=v; w=NEXT(w))
153       {
154         if (w->active && w->playing)
155         {
156           v->nextvictim = w;
157           break;
158         }
159       }
160       if (v->nextvictim == u)
161         v->nextvictim = NULL;
162     }
163   }
164
165   if (u->isbot)
166     bots--;
167
168   free(u);
169   clients--;
170
171   if (onceonly && clients == bots)
172   {
173     if (options.verbose)
174     {
175       printf("RND_SERVER: no clients left\n");
176       printf("RND_SERVER: aborting\n");
177     }
178     exit(0);
179   }
180
181   if (clients == 0)
182   {
183     mode = -1;
184     levelnr = 5;
185     timetoplay = 0;
186   }
187 }
188
189 static void new_connect(int fd)
190 {
191   struct user *u, *v;
192   unsigned char nxn;
193
194   u = checked_malloc(sizeof (struct user));
195
196   u->fd = fd;
197   u->nick[0] = 0;
198   u->next = user0;
199   u->nextvictim = NULL;
200   u->active = 0;
201   u->nread = 0;
202   u->nwrite = 0;
203   u->playing = 0;
204   u->isbot = 0;
205   u->introduced = 0;
206   u->games = 0;
207   u->action = 0;
208   u->action_received = 0;
209
210   user0 = u;
211
212   nxn = 1;
213
214  again:
215   v = u->next;
216   while(v)
217   {
218     if (v->number == nxn)
219     {
220       nxn++;
221       goto again;
222     }
223     v = v->next;
224   }
225
226   u->number = nxn;
227   if (options.verbose)
228     printf("RND_SERVER: client %d connecting from %s\n", nxn, inet_ntoa(saddr.sin_addr));
229   clients++;
230
231   buf[0] = 0;
232   buf[1] = OP_YOUR_NUMBER;
233   buf[2] = u->number;
234   sendtoone(u, 3);
235 }
236
237 static void Handle_OP_PROTOCOL_VERSION(struct user *u, unsigned int len)
238 {
239   if (len != 5 || buf[2] != PROT_VERS_1 || buf[3] != PROT_VERS_2)
240   {
241     if (options.verbose)
242       printf("RND_SERVER: client %d (%s) has wrong protocol version %d.%d.%d\n", u->number, u->nick, buf[2], buf[3], buf[4]);
243
244     buf[0] = 0;
245     buf[1] = OP_BADVERS;
246     buf[2] = PROT_VERS_1;
247     buf[3] = PROT_VERS_2;
248     buf[4] = PROT_VERS_3;
249     sendtoone(u, 5);
250     flushuser(u);
251
252     dropuser(u);
253     interrupt = 1;
254   }
255   else
256   {
257     if (options.verbose)
258       printf("RND_SERVER: client %d (%s) uses protocol version %d.%d.%d\n", u->number, u->nick, buf[2], buf[3], buf[4]);
259   }
260 }
261
262 static void Handle_OP_NUMBER_WANTED(struct user *u)
263 {
264   struct user *v;
265   int client_nr = u->number;
266   int nr_wanted = buf[2];
267   int nr_is_free = 1;
268
269   if (options.verbose)
270     printf("RND_SERVER: client %d (%s) wants to switch to # %d\n",
271            u->number, u->nick, nr_wanted);
272
273   for (v=user0; v; v=v->next)
274   {
275     if (v->number == nr_wanted)
276     {
277       nr_is_free = 0;
278       break;
279     }
280   }
281
282   if (options.verbose)
283   {
284     if (nr_is_free)
285       printf("RND_SERVER: client %d (%s) switches to # %d\n",
286              u->number, u->nick, nr_wanted);
287     else if (u->number == nr_wanted)
288       printf("RND_SERVER: client %d (%s) still has # %d\n",
289              u->number, u->nick, nr_wanted);
290     else
291       printf("RND_SERVER: client %d (%s) cannot switch (client %d still exists)\n",
292              u->number, u->nick, nr_wanted);
293   }
294
295   if (nr_is_free)
296     u->number = nr_wanted;
297
298   buf[0] = client_nr;
299   buf[1] = OP_NUMBER_WANTED;
300   buf[2] = nr_wanted;
301   buf[3] = u->number;
302
303   /*
304   sendtoone(u, 4);
305   */
306
307   broadcast(NULL, 4, 0);
308 }
309
310 static void Handle_OP_NICKNAME(struct user *u, unsigned int len)
311 {
312   struct user *v;
313   int i;
314
315   if (len>16)
316     len=16;
317   memcpy(u->nick, &buf[2], len-2);
318   u->nick[len-2] = 0;
319   for (i=0; i<len-2; i++)
320   {
321     if (u->nick[i] < ' ' || 
322         (u->nick[i] > 0x7e && u->nick[i] <= 0xa0))
323     {
324       u->nick[i] = 0;
325       break;
326     }
327   }
328
329   if (!u->introduced)
330   {
331     buf[0] = u->number;
332     buf[1] = OP_PLAYER_CONNECTED;
333     broadcast(u, 2, 0);
334   }
335               
336   if (options.verbose)
337     printf("RND_SERVER: client %d calls itself \"%s\"\n", u->number, u->nick);
338   buf[1] = OP_NICKNAME;
339   broadcast(u, len, 0);
340
341   if (!u->introduced)
342   {
343     for (v=user0; v; v=v->next)
344     {
345       if (v != u && v->introduced)
346       {
347         buf[0] = v->number;
348         buf[1] = OP_PLAYER_CONNECTED;
349         buf[2] = (v->games >> 8);
350         buf[3] = (v->games & 0xff);
351         sendtoone(u, 4);
352         buf[1] = OP_NICKNAME;
353         memcpy(&buf[2], v->nick, 14);
354         sendtoone(u, 2+strlen(v->nick));
355       }
356     }
357     if (levelnr != 5)
358     {
359       buf[0] = 0;
360       buf[1] = OP_LEVEL;
361       buf[2] = levelnr;
362       sendtoone(u, 3);
363     }
364     if (mode >= 0)
365     {
366       buf[1] = OP_MODE;
367       buf[2] = mode;
368       sendtoone(u, 3);
369     }
370   }
371
372   u->introduced = 1;
373 }
374
375 static void Handle_OP_START_PLAYING(struct user *u)
376 {
377   struct user *v, *w;
378
379   if (options.verbose)
380     printf("RND_SERVER: client %d (%s) starts game [level %d from levedir %d (%s)]\n",
381            u->number, u->nick,
382            (buf[2] << 8) + buf[3],
383            (buf[4] << 8) + buf[5],
384            &buf[6]);
385   timetoplay = 0;
386
387   for (w=user0; w; w=w->next)
388   {
389     if (w->introduced)
390     {
391       w->active = 1;
392       w->playing = 1;
393       w->lines = 0;
394       w->nextvictim = NULL;
395       for (v=NEXT(w); v!=w; v=NEXT(v))
396       {
397         if (v->introduced)
398         {
399           w->nextvictim = v;
400           break;
401         }
402       }
403     }
404   }
405
406   /*
407   if (paused)
408   {
409     paused = 0;
410     buf[1] = OP_CONT;
411     broadcast(NULL, 2, 0);
412   }
413   buf[1] = OP_START_PLAYING;
414   broadcast(NULL, 2, 0);
415   */
416
417   /* reset frame counter */
418   frame_counter = 0;
419
420   /* reset player actions */
421   for (v=user0; v; v=v->next)
422   {
423     v->action = 0;
424     v->action_received = 0;
425   }
426
427   broadcast(NULL, 10 + strlen(&buf[10])+1, 0);
428 }
429
430 static void Handle_OP_PAUSE_PLAYING(struct user *u)
431 {
432   if (options.verbose)
433     printf("RND_SERVER: client %d (%s) pauses game\n", u->number, u->nick);
434   broadcast(NULL, 2, 0);
435   paused = 1;
436 }
437
438 static void Handle_OP_CONTINUE_PLAYING(struct user *u)
439 {
440   if (options.verbose)
441     printf("RND_SERVER: client %d (%s) continues game\n", u->number, u->nick);
442   broadcast(NULL, 2, 0);
443   paused = 0;
444 }
445
446 static void Handle_OP_STOP_PLAYING(struct user *u)
447 {
448   if (options.verbose)
449     printf("RND_SERVER: client %d (%s) stops game\n", u->number, u->nick);
450   broadcast(NULL, 2, 0);
451 }
452
453 static void Handle_OP_MOVE_FIGURE(struct user *u)
454 {
455   struct user *v;
456   int last_client_nr = 0;
457   int i;
458
459   /* store player action */
460   for (v=user0; v; v=v->next)
461   {
462     if (v->number == u->number)
463     {
464       v->action = buf[2];
465       v->action_received = 1;
466     }
467   }
468
469   /* check if server received action from each player */
470   for (v=user0; v; v=v->next)
471   {
472     if (!v->action_received)
473       return;
474
475     if (v->number > last_client_nr)
476       last_client_nr = v->number;
477   }
478
479   /* initialize all player actions to zero */
480   for (i=0; i<last_client_nr; i++)
481     buf[6 + i] = 0;
482
483   /* broadcast actions of all players to all players */
484   for (v=user0; v; v=v->next)
485   {
486     buf[6 + v->number-1] = v->action;
487     v->action = 0;
488     v->action_received = 0;
489   }
490
491   buf[2] = (unsigned char)((frame_counter >> 24) & 0xff);
492   buf[3] = (unsigned char)((frame_counter >> 16) & 0xff);
493   buf[4] = (unsigned char)((frame_counter >>  8) & 0xff);
494   buf[5] = (unsigned char)((frame_counter >>  0) & 0xff);
495
496   broadcast(NULL, 6 + last_client_nr, 0);
497
498   frame_counter++;
499
500   /*
501     if (verbose)
502     printf("RND_SERVER: frame %d: client %d (%s) moves player [0x%02x]\n",
503     frame_counter,
504     u->number, u->nick, buf[2]);
505   */
506 }
507
508 void NetworkServer(int port, int serveronly)
509 {
510   int i, sl, on;
511   struct user *u, *v, *w;
512   int mfd;
513   int r; 
514   unsigned int len;
515   struct protoent *tcpproto;
516   struct timeval tv;
517   int is_daemon = 0;
518
519 #ifndef NeXT
520   struct sigaction sact;
521 #endif
522
523   if (port == 0)
524     port = DEFAULTPORT;
525
526   if (!serveronly)
527     onceonly = 1;
528
529   if ((tcpproto = getprotobyname("tcp")) != NULL)
530     tcp = tcpproto->p_proto;
531
532 #ifdef NeXT
533   signal(SIGPIPE, SIG_IGN);
534 #else
535   sact.sa_handler = SIG_IGN;
536   sigemptyset(&sact.sa_mask);
537   sact.sa_flags = 0;
538   sigaction(SIGPIPE, &sact, NULL);
539 #endif
540
541
542   lfd = socket(PF_INET, SOCK_STREAM, 0);
543   saddr.sin_family = AF_INET;
544   saddr.sin_addr.s_addr = htonl(INADDR_ANY);
545   saddr.sin_port = htons(port);
546
547   if (lfd < 0)
548     syserr("socket");
549   on = 1;
550
551   setsockopt(lfd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(int));
552   if (bind(lfd, (struct sockaddr *)&saddr, sizeof(saddr)) < 0)
553     syserr("bind");
554
555   listen(lfd, 5);
556
557   if (is_daemon)
558   {
559     /* become a daemon, breaking all ties with the controlling terminal */
560     options.verbose = 0;
561     for (i=0; i<255; i++)
562     {
563       if (i != lfd)
564         close(i);
565     }
566
567     if (fork())
568       exit(0);
569     setsid();
570     if (fork())
571       exit(0);
572     chdir("/");
573
574     /* open a fake stdin, stdout, stderr, just in case */
575     open("/dev/null", O_RDONLY);
576     open("/dev/null", O_WRONLY);
577     open("/dev/null", O_WRONLY);
578   }
579
580   if (options.verbose)
581   {
582     printf("rocksndiamonds network server: started up, listening on port %d\n",
583            port);
584     printf("rocksndiamonds network server: using protocol version %d.%d.%d\n",
585            PROT_VERS_1, PROT_VERS_2, PROT_VERS_3);
586   }
587
588   while(1)
589   {
590     interrupt = 0;
591
592     /*
593     if (timetoplay && time(NULL) >= timetoplay)
594     {
595       buf[0] = 0;
596       do_play();
597       if (options.verbose)
598         printf("RND_SERVER: everyone lost... restarting game\n");
599       timetoplay = 0;
600     }
601     */
602
603     for (u=user0; u; u=u->next)
604       flushuser(u);
605
606     FD_ZERO(&fds);
607     mfd = lfd;
608     u = user0;
609     while (u)
610     {
611       FD_SET(u->fd, &fds);
612       if (u->fd > mfd)
613         mfd = u->fd;
614       u = u->next;
615     }
616     FD_SET(lfd, &fds);
617     tv.tv_sec = 0;
618     tv.tv_usec = 500000;
619     if ((sl = select(mfd + 1, &fds, NULL, NULL, &tv)) < 0)
620       if (errno != EINTR)
621         syserr("select");
622       else continue;
623     
624     if (sl < 0)
625       continue;
626
627     if (clients > 0 && clients == bots)
628     {
629       if (options.verbose)
630         printf("RND_SERVER: only bots left... dropping all bots\n");
631       while (user0)
632         dropuser(user0);
633       continue;
634     }
635     
636     if (sl == 0)
637       continue;
638
639     if (FD_ISSET(lfd, &fds))
640     {
641       int newfd, slen;
642
643       slen = sizeof(saddr);
644       newfd = accept(lfd, (struct sockaddr *)&saddr, &slen);
645       if (newfd < 0)
646       {
647         if (errno != EINTR)
648           syserr("accept");
649       }
650       else
651       {
652         if (tcp != -1)
653         {
654           on = 1;
655           setsockopt(newfd, tcp, TCP_NODELAY, (char *)&on, sizeof(int));
656         }
657         new_connect(newfd);
658       }
659       continue;
660     }
661
662     u = user0;
663
664     do
665     {
666       if (FD_ISSET(u->fd, &fds))
667       {
668         r = read(u->fd, u->readbuf + u->nread, MAX_BUFFER_SIZE - u->nread);
669         if (r <= 0)
670         {
671           if (options.verbose)
672             printf("RND_SERVER: EOF from client %d (%s)\n", u->number, u->nick);
673           dropuser(u);
674           interrupt = 1;
675           break;
676         }
677         u->nread += r;
678         while (u->nread >= 4 && u->nread >= 4 + u->readbuf[3])
679         {
680           len = u->readbuf[3];
681           if (u->readbuf[0] || u->readbuf[1] || u->readbuf[2])
682           {
683             if (options.verbose)
684               printf("RND_SERVER: crap from client %d (%s)\n", u->number, u->nick);
685             write(u->fd, "\033]50;kanji24\007\033#8\033(0", 19);
686             dropuser(u);
687             interrupt = 1;
688             break;
689           }
690           memcpy(buf, &u->readbuf[4], len);
691           u->nread -= 4 + len;
692           memmove(u->readbuf, u->readbuf + 4 + len, u->nread);
693
694           buf[0] = u->number;
695           if (!u->introduced && buf[1] != OP_NICKNAME)
696           {
697             if (options.verbose)
698               printf("RND_SERVER: !(client %d)->introduced && buf[1]==%d (expected OP_NICKNAME)\n", buf[0], buf[1]);
699
700             dropuser(u);
701             interrupt = 1;
702             break;
703           }
704
705           switch(buf[1])
706           {
707             case OP_NICKNAME:
708               Handle_OP_NICKNAME(u, len);
709               break;
710
711             case OP_PROTOCOL_VERSION:
712               Handle_OP_PROTOCOL_VERSION(u, len);
713               break;
714
715             case OP_NUMBER_WANTED:
716               Handle_OP_NUMBER_WANTED(u);
717               break;
718
719             case OP_START_PLAYING:
720               Handle_OP_START_PLAYING(u);
721               break;
722
723             case OP_PAUSE_PLAYING:
724               Handle_OP_PAUSE_PLAYING(u);
725               break;
726
727             case OP_CONTINUE_PLAYING:
728               Handle_OP_CONTINUE_PLAYING(u);
729               break;
730
731             case OP_STOP_PLAYING:
732               Handle_OP_STOP_PLAYING(u);
733               break;
734
735             case OP_MOVE_FIGURE:
736               Handle_OP_MOVE_FIGURE(u);
737               break;
738
739             case OP_KILL:
740               for (v=user0; v; v=v->next)
741               {
742                 if (v->number == buf[2])
743                   break;
744               }
745               if (v)
746               {
747                 if (v->isbot)
748                 {
749                   if (options.verbose)
750                     printf("RND_SERVER: client %d (%s) kills bot %d (%s)\n", u->number, u->nick, v->number, v->nick);
751
752                   dropuser(v);
753                   interrupt = 1;
754                   break;
755                 }
756                 else
757                 {
758                   if (options.verbose)
759                     printf("RND_SERVER: client %d (%s) attempting to kill non-bot %d (%s)\n", u->number, u->nick, v->number, v->nick);
760                 }
761               }
762               break;
763
764             case OP_MODE:
765               mode = buf[2];
766               if (options.verbose)
767                 printf("RND_SERVER: client %d (%s) sets mode %d (%s)\n", u->number, u->nick, buf[2], buf[2] == 0 ? "normal" : (buf[2] == 1 ? "fun" : "unknown"));
768               broadcast(NULL, 3, 0);
769               break;
770
771             case OP_BOT:
772               if (!u->isbot)
773                 bots++;
774               u->isbot = 1;
775               if (options.verbose)
776                 printf("RND_SERVER: client %d (%s) declares itself to be a bot\n", u->number, u->nick);
777               break;
778             
779             case OP_LEVEL:
780               levelnr = buf[2];
781               if (options.verbose)
782                 printf("RND_SERVER: client %d (%s) sets level %d\n", u->number, u->nick, buf[2]);
783               broadcast(NULL, 3, 0);
784               break;
785
786             case OP_LOST:
787               {
788                 struct user *won = NULL;
789
790                 if (options.verbose)
791                   printf("RND_SERVER: client %d (%s) has lost\n", u->number, u->nick);
792                 u->playing = 0;
793                 broadcast(u, 2, 1);
794                 i = 0;
795                 for (v=user0; v; v=v->next)
796                 {
797                   if (v->nextvictim == u)
798                   {
799                     for (w=NEXT(v); w!=v; w=NEXT(w))
800                     {
801                       if (w->active && w->playing)
802                       {
803                         v->nextvictim = w;
804                         break;
805                       }
806                     }
807                     if (v->nextvictim == u)
808                       v->nextvictim = NULL;
809                   }
810                 }
811                 for (v=user0; v; v=v->next)
812                 {
813                   if (v->playing)
814                   {
815                     i++;
816                     won = v;
817                   }
818                 }
819                 if (i == 1)
820                 {
821                   buf[0] = won->number;
822                   buf[1] = OP_WON;
823                   won->games++;
824                   broadcast(NULL, 2, 0);
825                 }
826                 else if (i == 0)
827                 {
828                   buf[0] = u->number;
829                   buf[1] = OP_WON;
830                   u->games++;
831                   broadcast(NULL, 2, 0);
832                 }
833                 if (i < 2 && clients > 1)
834                   timetoplay = time(NULL) + 4;
835               }
836               break;
837             
838             case OP_ZERO:
839               broadcast(NULL, 2, 0);
840               if (options.verbose)
841                 printf("RND_SERVER: client %d (%s) resets the game counters\n", u->number, u->nick);
842               for (v=user0; v; v=v->next)
843                 v->games = 0;
844               break;
845
846             case OP_CLEAR:
847             case OP_GROW:
848               broadcast(u, 2, 1);
849               break;
850
851             case OP_MSG:
852               buf[len] = '\0';
853               if (options.verbose)
854                 printf("RND_SERVER: client %d (%s) sends message: %s\n", u->number, u->nick, &buf[2]);
855               broadcast(u, len, 0);
856               break;
857
858             case OP_LINES:
859               if (len != 3)
860               {
861                 if (options.verbose)
862                   printf("RND_SERVER: client %d (%s) sends crap for an OP_LINES\n", u->number, u->nick);
863
864                 dropuser(u);
865                 interrupt = 1;
866                 break;
867               }
868               if (u->nextvictim)
869               {
870                 if (options.verbose)
871                   printf("RND_SERVER: client %d (%s) sends %d %s to client %d (%s)\n", u->number, u->nick, (int)buf[2], buf[2] == 1 ? "line" : "lines", u->nextvictim->number, u->nextvictim->nick);
872                 sendtoone(u->nextvictim, 3);
873                 buf[3] = u->nextvictim->number;
874                 buf[1] = OP_LINESTO;
875                 broadcast(u->nextvictim, 4, 1);
876                 for (v=NEXT(u->nextvictim); v!=u->nextvictim; v=NEXT(v))
877                 {
878                   if (v->active && v != u && v->playing)
879                   {
880                     u->nextvictim = v;
881                     break;
882                   }
883                 }
884               }
885               else if (options.verbose)
886                 printf("RND_SERVER: client %d (%s) makes %d %s but has no victim\n", u->number, u->nick, (int)buf[2], buf[2] == 1 ? "line" : "lines");
887               break;
888             
889             default:
890               if (options.verbose)
891                 printf("RND_SERVER: opcode %d from client %d (%s) not understood\n", buf[0], u->number, u->nick);
892           }
893         }
894       }
895
896       if (u && !interrupt)
897         u = u->next;
898     }
899     while (u && !interrupt);
900   }
901 }