1 | |
1 | |
2 | /* |
2 | /* |
3 | * static char *rcsid_loop_c = |
3 | * static char *rcsid_loop_c = |
4 | * "$Id: loop.c,v 1.5 2006/04/18 20:05:42 root Exp $"; |
4 | * "$Id: loop.c,v 1.6 2006/04/22 15:02:48 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 | |
… | |
… | |
112 | { "command", PlayerCmd, 1}, |
112 | { "command", PlayerCmd, 1}, |
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, 2}, /* Added: phil */ |
118 | { "mapinfo", MapInfoCmd, 0 }, /* CF+ */ |
118 | { "mapinfo", MapInfoCmd, 2}, /* CF+ */ |
119 | { NULL, NULL, 0} /* terminator */ |
119 | { NULL, NULL, 0} /* terminator */ |
120 | }; |
120 | }; |
121 | |
121 | |
122 | /** Face-related commands */ |
122 | /** Face-related commands */ |
123 | static struct NsCmdMapping nscommands[] = { |
123 | static struct NsCmdMapping nscommands[] = { |
… | |
… | |
183 | /* This is not the most efficient block, but keeps the code simpler - |
183 | /* This is not the most efficient block, but keeps the code simpler - |
184 | * we basically read a byte at a time until we get a newline, error, |
184 | * we basically read a byte at a time until we get a newline, error, |
185 | * or no more characters to read. |
185 | * or no more characters to read. |
186 | */ |
186 | */ |
187 | do { |
187 | do { |
|
|
188 | /* hack to disable old socket mode without creating too many conflicts */ |
188 | if (ns->inbuf.len >= MAXSOCKBUF-1) { |
189 | if (1 || ns->inbuf.len >= MAXSOCKBUF-1) { |
189 | ns->status = Ns_Dead; |
190 | ns->status = Ns_Dead; |
190 | LOG(llevDebug, "Old input socket sent too much data without newline\n"); |
191 | LOG(llevDebug, "Old input socket sent too much data without newline\n"); |
191 | return; |
192 | return; |
192 | } |
193 | } |
193 | #ifdef WIN32 /* ***win32: change oldsocket read() to recv() */ |
194 | #ifdef WIN32 /* ***win32: change oldsocket read() to recv() */ |
… | |
… | |
328 | int len=0,i,cnt; |
329 | int len=0,i,cnt; |
329 | unsigned char *data; |
330 | unsigned char *data; |
330 | |
331 | |
331 | /* Loop through this - maybe we have several complete packets here. */ |
332 | /* Loop through this - maybe we have several complete packets here. */ |
332 | // limit to a few commands only, though, as to not monopolise the server |
333 | // limit to a few commands only, though, as to not monopolise the server |
333 | for (cnt = 16; --cnt; ) { |
334 | for (cnt = 16; cnt--; ) { |
334 | /* If it is a player, and they don't have any speed left, we |
335 | /* If it is a player, and they don't have any speed left, we |
335 | * return, and will read in the data when they do have time. |
336 | * return, and will read in the data when they do have time. |
336 | */ |
337 | */ |
337 | if (pl && pl->state==ST_PLAYING && pl->ob != NULL && pl->ob->speed_left < 0) { |
338 | if (pl && pl->state==ST_PLAYING && pl->ob != NULL && pl->ob->speed_left < 0) { |
338 | return; |
339 | return; |
… | |
… | |
383 | ns->inbuf.buf[ns->inbuf.len]='\0'; /* Terminate buffer - useful for string data */ |
384 | ns->inbuf.buf[ns->inbuf.len]='\0'; /* Terminate buffer - useful for string data */ |
384 | for (i=0; nscommands[i].cmdname !=NULL; i++) { |
385 | for (i=0; nscommands[i].cmdname !=NULL; i++) { |
385 | if (strcmp((char*)ns->inbuf.buf+2,nscommands[i].cmdname)==0) { |
386 | if (strcmp((char*)ns->inbuf.buf+2,nscommands[i].cmdname)==0) { |
386 | nscommands[i].cmdproc((char*)data,len,ns); |
387 | nscommands[i].cmdproc((char*)data,len,ns); |
387 | ns->inbuf.len=0; |
388 | ns->inbuf.len=0; |
|
|
389 | return;//D |
388 | goto next_packet; |
390 | goto next_packet; |
389 | } |
391 | } |
390 | } |
392 | } |
391 | /* Player must be in the playing state or the flag on the |
393 | /* Player must be in the playing state or the flag on the |
392 | * the command must be zero for the user to use the command - |
394 | * the command must be zero for the user to use the command - |
393 | * otherwise, a player cam save, be in the play_again state, and |
395 | * otherwise, a player cam save, be in the play_again state, and |
394 | * the map they were on getsswapped out, yet things that try to look |
396 | * the map they were on gets swapped out, yet things that try to look |
395 | * at the map causes a crash. If the command is valid, but |
397 | * at the map causes a crash. If the command is valid, but |
396 | * one they can't use, we still swallow it up. |
398 | * one they can't use, we still swallow it up. |
397 | */ |
399 | */ |
398 | if (pl) for (i=0; plcommands[i].cmdname !=NULL; i++) { |
400 | if (pl) for (i=0; plcommands[i].cmdname !=NULL; i++) { |
399 | if (strcmp((char*)ns->inbuf.buf+2,plcommands[i].cmdname)==0) { |
401 | if (strcmp((char*)ns->inbuf.buf+2,plcommands[i].cmdname)==0) { |
400 | if (pl->state == ST_PLAYING || plcommands[i].flag == 0) |
402 | if (pl->state == ST_PLAYING || !(plcommands[i].flag & 1)) |
401 | plcommands[i].cmdproc((char*)data,len,pl); |
403 | plcommands[i].cmdproc((char*)data,len,pl); |
402 | ns->inbuf.len=0; |
404 | ns->inbuf.len=0; |
|
|
405 | if (plcommands[i].flag & 2) |
403 | goto next_packet; |
406 | goto next_packet; |
|
|
407 | return; |
404 | } |
408 | } |
405 | } |
409 | } |
406 | /* If we get here, we didn't find a valid command. Logging |
410 | /* If we get here, we didn't find a valid command. Logging |
407 | * this might be questionable, because a broken client/malicious |
411 | * this might be questionable, because a broken client/malicious |
408 | * user could certainly send a whole bunch of invalid commands. |
412 | * user could certainly send a whole bunch of invalid commands. |