rnd-19981118-2
[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     {
621       if (errno != EINTR)
622         syserr("select");
623       else
624         continue;
625     }
626
627     if (sl < 0)
628       continue;
629
630     if (clients > 0 && clients == bots)
631     {
632       if (options.verbose)
633         printf("RND_SERVER: only bots left... dropping all bots\n");
634       while (user0)
635         dropuser(user0);
636       continue;
637     }
638     
639     if (sl == 0)
640       continue;
641
642     if (FD_ISSET(lfd, &fds))
643     {
644       int newfd, slen;
645
646       slen = sizeof(saddr);
647       newfd = accept(lfd, (struct sockaddr *)&saddr, &slen);
648       if (newfd < 0)
649       {
650         if (errno != EINTR)
651           syserr("accept");
652       }
653       else
654       {
655         if (tcp != -1)
656         {
657           on = 1;
658           setsockopt(newfd, tcp, TCP_NODELAY, (char *)&on, sizeof(int));
659         }
660         new_connect(newfd);
661       }
662       continue;
663     }
664
665     u = user0;
666
667     do
668     {
669       if (FD_ISSET(u->fd, &fds))
670       {
671         r = read(u->fd, u->readbuf + u->nread, MAX_BUFFER_SIZE - u->nread);
672         if (r <= 0)
673         {
674           if (options.verbose)
675             printf("RND_SERVER: EOF from client %d (%s)\n", u->number, u->nick);
676           dropuser(u);
677           interrupt = 1;
678           break;
679         }
680         u->nread += r;
681         while (u->nread >= 4 && u->nread >= 4 + u->readbuf[3])
682         {
683           len = u->readbuf[3];
684           if (u->readbuf[0] || u->readbuf[1] || u->readbuf[2])
685           {
686             if (options.verbose)
687               printf("RND_SERVER: crap from client %d (%s)\n", u->number, u->nick);
688             write(u->fd, "\033]50;kanji24\007\033#8\033(0", 19);
689             dropuser(u);
690             interrupt = 1;
691             break;
692           }
693           memcpy(buf, &u->readbuf[4], len);
694           u->nread -= 4 + len;
695           memmove(u->readbuf, u->readbuf + 4 + len, u->nread);
696
697           buf[0] = u->number;
698           if (!u->introduced && buf[1] != OP_NICKNAME)
699           {
700             if (options.verbose)
701               printf("RND_SERVER: !(client %d)->introduced && buf[1]==%d (expected OP_NICKNAME)\n", buf[0], buf[1]);
702
703             dropuser(u);
704             interrupt = 1;
705             break;
706           }
707
708           switch(buf[1])
709           {
710             case OP_NICKNAME:
711               Handle_OP_NICKNAME(u, len);
712               break;
713
714             case OP_PROTOCOL_VERSION:
715               Handle_OP_PROTOCOL_VERSION(u, len);
716               break;
717
718             case OP_NUMBER_WANTED:
719               Handle_OP_NUMBER_WANTED(u);
720               break;
721
722             case OP_START_PLAYING:
723               Handle_OP_START_PLAYING(u);
724               break;
725
726             case OP_PAUSE_PLAYING:
727               Handle_OP_PAUSE_PLAYING(u);
728               break;
729
730             case OP_CONTINUE_PLAYING:
731               Handle_OP_CONTINUE_PLAYING(u);
732               break;
733
734             case OP_STOP_PLAYING:
735               Handle_OP_STOP_PLAYING(u);
736               break;
737
738             case OP_MOVE_FIGURE:
739               Handle_OP_MOVE_FIGURE(u);
740               break;
741
742             case OP_KILL:
743               for (v=user0; v; v=v->next)
744               {
745                 if (v->number == buf[2])
746                   break;
747               }
748               if (v)
749               {
750                 if (v->isbot)
751                 {
752                   if (options.verbose)
753                     printf("RND_SERVER: client %d (%s) kills bot %d (%s)\n", u->number, u->nick, v->number, v->nick);
754
755                   dropuser(v);
756                   interrupt = 1;
757                   break;
758                 }
759                 else
760                 {
761                   if (options.verbose)
762                     printf("RND_SERVER: client %d (%s) attempting to kill non-bot %d (%s)\n", u->number, u->nick, v->number, v->nick);
763                 }
764               }
765               break;
766
767             case OP_MODE:
768               mode = buf[2];
769               if (options.verbose)
770                 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"));
771               broadcast(NULL, 3, 0);
772               break;
773
774             case OP_BOT:
775               if (!u->isbot)
776                 bots++;
777               u->isbot = 1;
778               if (options.verbose)
779                 printf("RND_SERVER: client %d (%s) declares itself to be a bot\n", u->number, u->nick);
780               break;
781             
782             case OP_LEVEL:
783               levelnr = buf[2];
784               if (options.verbose)
785                 printf("RND_SERVER: client %d (%s) sets level %d\n", u->number, u->nick, buf[2]);
786               broadcast(NULL, 3, 0);
787               break;
788
789             case OP_LOST:
790               {
791                 struct user *won = NULL;
792
793                 if (options.verbose)
794                   printf("RND_SERVER: client %d (%s) has lost\n", u->number, u->nick);
795                 u->playing = 0;
796                 broadcast(u, 2, 1);
797                 i = 0;
798                 for (v=user0; v; v=v->next)
799                 {
800                   if (v->nextvictim == u)
801                   {
802                     for (w=NEXT(v); w!=v; w=NEXT(w))
803                     {
804                       if (w->active && w->playing)
805                       {
806                         v->nextvictim = w;
807                         break;
808                       }
809                     }
810                     if (v->nextvictim == u)
811                       v->nextvictim = NULL;
812                   }
813                 }
814                 for (v=user0; v; v=v->next)
815                 {
816                   if (v->playing)
817                   {
818                     i++;
819                     won = v;
820                   }
821                 }
822                 if (i == 1)
823                 {
824                   buf[0] = won->number;
825                   buf[1] = OP_WON;
826                   won->games++;
827                   broadcast(NULL, 2, 0);
828                 }
829                 else if (i == 0)
830                 {
831                   buf[0] = u->number;
832                   buf[1] = OP_WON;
833                   u->games++;
834                   broadcast(NULL, 2, 0);
835                 }
836                 if (i < 2 && clients > 1)
837                   timetoplay = time(NULL) + 4;
838               }
839               break;
840             
841             case OP_ZERO:
842               broadcast(NULL, 2, 0);
843               if (options.verbose)
844                 printf("RND_SERVER: client %d (%s) resets the game counters\n", u->number, u->nick);
845               for (v=user0; v; v=v->next)
846                 v->games = 0;
847               break;
848
849             case OP_CLEAR:
850             case OP_GROW:
851               broadcast(u, 2, 1);
852               break;
853
854             case OP_MSG:
855               buf[len] = '\0';
856               if (options.verbose)
857                 printf("RND_SERVER: client %d (%s) sends message: %s\n", u->number, u->nick, &buf[2]);
858               broadcast(u, len, 0);
859               break;
860
861             case OP_LINES:
862               if (len != 3)
863               {
864                 if (options.verbose)
865                   printf("RND_SERVER: client %d (%s) sends crap for an OP_LINES\n", u->number, u->nick);
866
867                 dropuser(u);
868                 interrupt = 1;
869                 break;
870               }
871               if (u->nextvictim)
872               {
873                 if (options.verbose)
874                   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);
875                 sendtoone(u->nextvictim, 3);
876                 buf[3] = u->nextvictim->number;
877                 buf[1] = OP_LINESTO;
878                 broadcast(u->nextvictim, 4, 1);
879                 for (v=NEXT(u->nextvictim); v!=u->nextvictim; v=NEXT(v))
880                 {
881                   if (v->active && v != u && v->playing)
882                   {
883                     u->nextvictim = v;
884                     break;
885                   }
886                 }
887               }
888               else if (options.verbose)
889                 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");
890               break;
891             
892             default:
893               if (options.verbose)
894                 printf("RND_SERVER: opcode %d from client %d (%s) not understood\n", buf[0], u->number, u->nick);
895           }
896         }
897       }
898
899       if (u && !interrupt)
900         u = u->next;
901     }
902     while (u && !interrupt);
903   }
904 }