ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/socket/loop.c
(Generate patch)

Comparing deliantra/server/socket/loop.c (file contents):
Revision 1.1.1.1 by root, Fri Feb 3 07:14:44 2006 UTC vs.
Revision 1.11 by root, Mon Jul 24 23:25:27 2006 UTC

1 1
2/* 2/*
3 * static char *rcsid_loop_c = 3 * static char *rcsid_loop_c =
4 * "$Id: loop.c,v 1.1.1.1 2006/02/03 07:14:44 root Exp $"; 4 * "$Id: loop.c,v 1.11 2006/07/24 23:25:27 root Exp $";
5 */ 5 */
6 6
7/* 7/*
8 CrossFire, A Multiplayer game for X-windows 8 CrossFire, A Multiplayer game for X-windows
9 9
78 */ 78 */
79 79
80typedef void (*func_uint8_int_ns) (char*, int, NewSocket *); 80typedef void (*func_uint8_int_ns) (char*, int, NewSocket *);
81 81
82struct NsCmdMapping { 82struct NsCmdMapping {
83 char *cmdname; 83 const char *cmdname;
84 func_uint8_int_ns cmdproc; 84 func_uint8_int_ns cmdproc;
85}; 85};
86 86
87typedef void (*func_uint8_int_pl)(char*, int, player *); 87typedef void (*func_uint8_int_pl)(char*, int, player *);
88struct PlCmdMapping { 88struct PlCmdMapping {
89 char *cmdname; 89 const char *cmdname;
90 func_uint8_int_pl cmdproc; 90 func_uint8_int_pl cmdproc;
91 uint8 flag; 91 uint8 flag;
92}; 92};
93 93
94/** 94/**
113 { "ncom", (func_uint8_int_pl)NewPlayerCmd, 1}, 113 { "ncom", (func_uint8_int_pl)NewPlayerCmd, 1},
114 { "lookat", LookAt, 1}, 114 { "lookat", LookAt, 1},
115 { "lock", (func_uint8_int_pl)LockItem, 1}, 115 { "lock", (func_uint8_int_pl)LockItem, 1},
116 { "mark", (func_uint8_int_pl)MarkItem, 1}, 116 { "mark", (func_uint8_int_pl)MarkItem, 1},
117 { "mapredraw", MapRedrawCmd, 0}, /* Added: phil */ 117 { "mapredraw", MapRedrawCmd, 0}, /* Added: phil */
118 { "mapinfo", MapInfoCmd, 2}, /* CF+ */
119 { "ext", ExtCmd, 2}, /* CF+ */
118 { NULL, NULL, 0} /* terminator */ 120 { NULL, NULL, 0} /* terminator */
119}; 121};
120 122
121/** Face-related commands */ 123/** Face-related commands */
122static struct NsCmdMapping nscommands[] = { 124static struct NsCmdMapping nscommands[] = {
182 /* This is not the most efficient block, but keeps the code simpler - 184 /* This is not the most efficient block, but keeps the code simpler -
183 * we basically read a byte at a time until we get a newline, error, 185 * we basically read a byte at a time until we get a newline, error,
184 * or no more characters to read. 186 * or no more characters to read.
185 */ 187 */
186 do { 188 do {
189 /* hack to disable old socket mode without creating too many conflicts */
187 if (ns->inbuf.len >= MAXSOCKBUF-1) { 190 if (1 || ns->inbuf.len >= MAXSOCKBUF-1) {
188 ns->status = Ns_Dead; 191 ns->status = Ns_Dead;
189 LOG(llevDebug, "Old input socket sent too much data without newline\n"); 192 LOG(llevDebug, "Old input socket sent too much data without newline\n");
190 return; 193 return;
191 } 194 }
192#ifdef WIN32 /* ***win32: change oldsocket read() to recv() */ 195#ifdef WIN32 /* ***win32: change oldsocket read() to recv() */
322 * starting a connection) 325 * starting a connection)
323 */ 326 */
324 327
325void HandleClient(NewSocket *ns, player *pl) 328void HandleClient(NewSocket *ns, player *pl)
326{ 329{
327 int len=0,i; 330 int len=0,i,cnt;
328 unsigned char *data; 331 unsigned char *data;
329 332
330 /* Loop through this - maybe we have several complete packets here. */ 333 /* Loop through this - maybe we have several complete packets here. */
331 while (1) { 334 // limit to a few commands only, though, as to not monopolise the server
335 for (cnt = 16; cnt--; ) {
332 /* If it is a player, and they don't have any speed left, we 336 /* If it is a player, and they don't have any speed left, we
333 * return, and will read in the data when they do have time. 337 * return, and will read in the data when they do have time.
334 */ 338 */
335 if (pl && pl->state==ST_PLAYING && pl->ob != NULL && pl->ob->speed_left < 0) { 339 if (pl && pl->state==ST_PLAYING && pl->ob != NULL && pl->ob->speed_left < 0) {
336 return; 340 return;
363 return; 367 return;
364 } 368 }
365 /* Still dont have a full packet */ 369 /* Still dont have a full packet */
366 if (i==0) return; 370 if (i==0) return;
367 371
372// //D//TODO//temporarily log long commands
373// if (ns->inbuf.len >= 40 && pl && pl->ob)
374// LOG (llevDebug, "HandleClient: long comamnd from <%s,%s> %d<%s>\n", pl->ob->name, ns->host, ns->inbuf.len, ns->inbuf.buf + 2);
375
368 /* First, break out beginning word. There are at least 376 /* First, break out beginning word. There are at least
369 * a few commands that do not have any paremeters. If 377 * a few commands that do not have any paremeters. If
370 * we get such a command, don't worry about trying 378 * we get such a command, don't worry about trying
371 * to break it up. 379 * to break it up.
372 */ 380 */
381 ns->inbuf.buf[ns->inbuf.len]='\0'; /* Terminate buffer - useful for string data */ 389 ns->inbuf.buf[ns->inbuf.len]='\0'; /* Terminate buffer - useful for string data */
382 for (i=0; nscommands[i].cmdname !=NULL; i++) { 390 for (i=0; nscommands[i].cmdname !=NULL; i++) {
383 if (strcmp((char*)ns->inbuf.buf+2,nscommands[i].cmdname)==0) { 391 if (strcmp((char*)ns->inbuf.buf+2,nscommands[i].cmdname)==0) {
384 nscommands[i].cmdproc((char*)data,len,ns); 392 nscommands[i].cmdproc((char*)data,len,ns);
385 ns->inbuf.len=0; 393 ns->inbuf.len=0;
386 return; 394 return;//D// not doing this causes random memory corruption
395 goto next_packet;
387 } 396 }
388 } 397 }
389 /* Player must be in the playing state or the flag on the 398 /* Player must be in the playing state or the flag on the
390 * the command must be zero for the user to use the command - 399 * the command must be zero for the user to use the command -
391 * otherwise, a player cam save, be in the play_again state, and 400 * otherwise, a player cam save, be in the play_again state, and
392 * the map they were on getsswapped out, yet things that try to look 401 * the map they were on gets swapped out, yet things that try to look
393 * at the map causes a crash. If the command is valid, but 402 * at the map causes a crash. If the command is valid, but
394 * one they can't use, we still swallow it up. 403 * one they can't use, we still swallow it up.
395 */ 404 */
396 if (pl) for (i=0; plcommands[i].cmdname !=NULL; i++) { 405 if (pl) for (i=0; plcommands[i].cmdname !=NULL; i++) {
397 if (strcmp((char*)ns->inbuf.buf+2,plcommands[i].cmdname)==0) { 406 if (strcmp((char*)ns->inbuf.buf+2,plcommands[i].cmdname)==0) {
398 if (pl->state == ST_PLAYING || plcommands[i].flag == 0) 407 if (pl->state == ST_PLAYING || !(plcommands[i].flag & 1))
399 plcommands[i].cmdproc((char*)data,len,pl); 408 plcommands[i].cmdproc((char*)data,len,pl);
400 ns->inbuf.len=0; 409 ns->inbuf.len=0;
401 return; 410 //D// not doing this causes random memory corruption
411 if (plcommands[i].flag & 2)
412 goto next_packet;
413 return;
402 } 414 }
403 } 415 }
404 /* If we get here, we didn't find a valid command. Logging 416 /* If we get here, we didn't find a valid command. Logging
405 * this might be questionable, because a broken client/malicious 417 * this might be questionable, because a broken client/malicious
406 * user could certainly send a whole bunch of invalid commands. 418 * user could certainly send a whole bunch of invalid commands.
407 */ 419 */
408 LOG(llevDebug,"Bad command from client (%s)\n",ns->inbuf.buf+2); 420 LOG(llevDebug,"Bad command from client (%s)\n",ns->inbuf.buf+2);
421 next_packet:
422 ;
409 } 423 }
410} 424}
411 425
412 426
413/***************************************************************************** 427/*****************************************************************************
502 while (select(socket_info.max_filedescriptor, &readfs, NULL, NULL, &Timeout)==0); 516 while (select(socket_info.max_filedescriptor, &readfs, NULL, NULL, &Timeout)==0);
503 517
504 reset_sleep(); /* Or the game would go too fast */ 518 reset_sleep(); /* Or the game would go too fast */
505} 519}
506 520
521void flush_sockets(void)
522{
523 player *pl;
524
525 for (pl = first_player; pl != NULL; pl = pl->next)
526 if (pl->socket.status != Ns_Dead)
527 Socket_Flush (&pl->socket);
528}
507 529
508/** 530/**
509 * This checks the sockets for input and exceptions, does the right thing. 531 * This checks the sockets for input and exceptions, does the right thing.
510 * 532 *
511 * A bit of this code is grabbed out of socket.c 533 * A bit of this code is grabbed out of socket.c
563 FD_SET((uint32)pl->socket.fd, &tmp_exceptions); 585 FD_SET((uint32)pl->socket.fd, &tmp_exceptions);
564 pl=pl->next; 586 pl=pl->next;
565 } 587 }
566 } 588 }
567 589
590#if 0
591 // the event system and plugins require the server ti run at all times.
592 // since its primarily cf.schmorp.de we are interested in, and
593 // that is supposed to run all the time anyway, its globally disabled
594 // until we can use Event.
568 if (socket_info.nconns==1 && first_player==NULL) 595 if (socket_info.nconns==1 && first_player==NULL)
569 block_until_new_connection(); 596 block_until_new_connection();
597#endif
570 598
571 /* Reset timeout each time, since some OS's will change the values on 599 /* Reset timeout each time, since some OS's will change the values on
572 * the return from select. 600 * the return from select.
573 */ 601 */
574 socket_info.timeout.tv_sec = 0; 602 socket_info.timeout.tv_sec = 0;
709 if (pl->last_weight != -1 && pl->last_weight != WEIGHT(pl->ob)) { 737 if (pl->last_weight != -1 && pl->last_weight != WEIGHT(pl->ob)) {
710 esrv_update_item(UPD_WEIGHT, pl->ob, pl->ob); 738 esrv_update_item(UPD_WEIGHT, pl->ob, pl->ob);
711 if(pl->last_weight != WEIGHT(pl->ob)) 739 if(pl->last_weight != WEIGHT(pl->ob))
712 LOG(llevError, "esrv_update_item(UPD_WEIGHT) did not set player weight: is %lu, should be %lu\n", (unsigned long)pl->last_weight, WEIGHT(pl->ob)); 740 LOG(llevError, "esrv_update_item(UPD_WEIGHT) did not set player weight: is %lu, should be %lu\n", (unsigned long)pl->last_weight, WEIGHT(pl->ob));
713 } 741 }
714 if (pl->ob->map && pl->ob->map->in_memory==MAP_IN_MEMORY) 742 /* draw_client_map does sanity checking that map is
743 * valid, so don't do it here.
744 */
715 draw_client_map(pl->ob); 745 draw_client_map(pl->ob);
716 if (pl->socket.update_look) esrv_draw_look(pl->ob); 746 if (pl->socket.update_look) esrv_draw_look(pl->ob);
717 } 747 }
718 } 748 }
719 } 749 }
720} 750}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines