version 1.41 | | version 1.42 |
---|
| | |
| | |
/* | | /* |
* static char *rcsid_loop_c = | | * static char *rcsid_loop_c = |
* "$Id: loop.c,v 1.41 2006/02/10 23:59:28 akirschbaum Exp $"; | | * "$Id: loop.c,v 1.42 2006/03/18 15:05:37 ryo_saeba Exp $"; |
*/ | | */ |
| | |
/* | | /* |
| | |
* we end up having 2 tables. | | * we end up having 2 tables. |
*/ | | */ |
| | |
typedef void (*func_uint8_int_ns) (char*, int, NewSocket *); | | typedef void (*func_uint8_int_ns) (char*, int, socket_struct *); |
| | |
struct NsCmdMapping { | | struct client_cmd_mapping { |
const char *cmdname; | | const char *cmdname; |
func_uint8_int_ns cmdproc; | | func_uint8_int_ns cmdproc; |
}; | | }; |
| | |
typedef void (*func_uint8_int_pl)(char*, int, player *); | | typedef void (*func_uint8_int_pl)(char*, int, player *); |
struct PlCmdMapping { | | struct player_cmd_mapping { |
const char *cmdname; | | const char *cmdname; |
func_uint8_int_pl cmdproc; | | func_uint8_int_pl cmdproc; |
uint8 flag; | | uint8 flag; |
}; | | }; |
| | |
/** | | /** |
* Dispatch table for the server. | | * Dispatch tables for the server. |
* | | * |
* CmdMapping is the dispatch table for the server, used in HandleClient, | | * CmdMapping is the dispatch table for the server, used in handle_client, |
* which gets called when the client has input. All commands called here | | * which gets called when the client has input. All commands called here |
* use the same parameter form (char* data, int len, int clientnum. | | * use the same parameter form (char* data, int len, int clientnum. |
* We do implicit casts, because the data that is being passed is | | * We do implicit casts, because the data that is being passed is |
| | |
* flag is 1 if the player must be in the playing state to issue the | | * flag is 1 if the player must be in the playing state to issue the |
* command, 0 if they can issue it at any time. | | * command, 0 if they can issue it at any time. |
*/ | | */ |
static struct PlCmdMapping plcommands[] = { | | /** Commands sent by the player during the game play itself */ |
{ "examine", ExamineCmd, 1}, | | static struct player_cmd_mapping player_commands[] = { |
{ "apply", ApplyCmd, 1}, | | { "examine", examine_cmd, 1}, |
{ "move", MoveCmd, 1}, | | { "apply", apply_cmd, 1}, |
{ "reply", ReplyCmd, 0}, | | { "move", move_cmd, 1}, |
{ "command", PlayerCmd, 1}, | | { "reply", reply_cmd, 0}, |
{ "ncom", (func_uint8_int_pl)NewPlayerCmd, 1}, | | { "command", player_cmd, 1}, |
{ "lookat", LookAt, 1}, | | { "ncom", (func_uint8_int_pl)new_player_cmd, 1}, |
{ "lock", (func_uint8_int_pl)LockItem, 1}, | | { "lookat", look_at_cmd, 1}, |
{ "mark", (func_uint8_int_pl)MarkItem, 1}, | | { "lock", (func_uint8_int_pl)lock_item_cmd, 1}, |
{ "mapredraw", MapRedrawCmd, 0}, /* Added: phil */ | | { "mark", (func_uint8_int_pl)mark_item_cmd, 1}, |
| | { "mapredraw", map_redraw_cmd, 0}, /* Added: phil */ |
{ NULL, NULL, 0} /* terminator */ | | { NULL, NULL, 0} /* terminator */ |
}; | | }; |
| | |
/** Face-related commands */ | | /** Commands sent directly by client, when connecting */ |
static struct NsCmdMapping nscommands[] = { | | static struct client_cmd_mapping client_commands[] = { |
{ "addme", AddMeCmd }, | | { "addme", add_me_cmd }, |
{ "askface", SendFaceCmd}, /* Added: phil */ | | { "askface", send_face_cmd}, /* Added: phil */ |
{ "requestinfo", RequestInfo}, | | { "requestinfo", request_info_cmd}, |
{ "setfacemode", SetFaceMode}, | | { "setfacemode", set_face_mode_cmd}, |
{ "setsound", SetSound}, | | { "setsound", set_sound_cmd}, |
{ "setup", SetUp}, | | { "setup", set_up_cmd}, |
{ "version", VersionCmd }, | | { "version", version_cmd }, |
{ "toggleextendedinfos", ToggleExtendedInfos}, /*Added: tchize*/ | | { "toggleextendedinfos", toggle_extended_infos_cmd}, /*Added: tchize*/ |
{ "toggleextendedtext", ToggleExtendedText}, /*Added: tchize*/ | | { "toggleextendedtext", toggle_extended_text_cmd}, /*Added: tchize*/ |
{ "asksmooth", AskSmooth}, /*Added: tchize (smoothing technologies)*/ | | { "asksmooth", ask_smooth_cmd}, /*Added: tchize (smoothing technologies)*/ |
{ NULL, NULL} /* terminator (I, II & III)*/ | | { NULL, NULL} /* terminator (I, II & III)*/ |
}; | | }; |
| | |
/** | | /** |
* RequestInfo is sort of a meta command. There is some specific | | * request_info_cmd is sort of a meta command. There is some specific |
* request of information, but we call other functions to provide | | * request of information, but we call other functions to provide |
* that information. | | * that information. |
*/ | | */ |
void RequestInfo(char *buf, int len, NewSocket *ns) | | void request_info_cmd(char *buf, int len, socket_struct *ns) |
{ | | { |
char *params=NULL, *cp; | | char *params=NULL, *cp; |
/* No match */ | | /* No match */ |
| | |
/** | | /** |
* Handles old socket format. | | * Handles old socket format. |
*/ | | */ |
void Handle_Oldsocket(NewSocket *ns) | | void handle_oldsocket(socket_struct *ns) |
{ | | { |
int stat,i; | | int stat,i; |
CommFunc command; | | command_function command; |
char buf[MAX_BUF],*cp; | | char buf[MAX_BUF],*cp; |
object ob; | | object ob; |
player pl; | | player pl; |
| | |
/** | | /** |
* Handle client input. | | * Handle client input. |
* | | * |
* HandleClient is actually not named really well - we only get here once | | * handle_client is actually not named really well - we only get here once |
* there is input, so we don't do exception or other stuff here. | | * there is input, so we don't do exception or other stuff here. |
* sock is the output socket information. pl is the player associated | | * sock is the output socket information. pl is the player associated |
* with this socket, null if no player (one of the init_sockets for just | | * with this socket, null if no player (one of the init_sockets for just |
* starting a connection) | | * starting a connection) |
*/ | | */ |
| | |
void HandleClient(NewSocket *ns, player *pl) | | void handle_client(socket_struct *ns, player *pl) |
{ | | { |
int len=0,i; | | int len=0,i; |
unsigned char *data; | | unsigned char *data; |
| | |
} | | } |
| | |
if (ns->status == Ns_Old) { | | if (ns->status == Ns_Old) { |
Handle_Oldsocket(ns); | | handle_oldsocket(ns); |
return; | | return; |
} | | } |
i=SockList_ReadPacket(ns->fd, &ns->inbuf, MAXSOCKBUF-1); | | i=SockList_ReadPacket(ns->fd, &ns->inbuf, MAXSOCKBUF-1); |
| | |
| | |
if (i<0) { | | if (i<0) { |
#ifdef ESRV_DEBUG | | #ifdef ESRV_DEBUG |
LOG(llevDebug,"HandleClient: Read error on connection player %s\n", (pl?pl->ob->name:"None")); | | LOG(llevDebug,"handle_client: Read error on connection player %s\n", (pl?pl->ob->name:"None")); |
#endif | | #endif |
/* Caller will take care of cleaning this up */ | | /* Caller will take care of cleaning this up */ |
ns->status =Ns_Dead; | | ns->status =Ns_Dead; |
| | |
else len=0; | | else len=0; |
| | |
ns->inbuf.buf[ns->inbuf.len]='\0'; /* Terminate buffer - useful for string data */ | | ns->inbuf.buf[ns->inbuf.len]='\0'; /* Terminate buffer - useful for string data */ |
for (i=0; nscommands[i].cmdname !=NULL; i++) { | | for (i=0; client_commands[i].cmdname !=NULL; i++) { |
if (strcmp((char*)ns->inbuf.buf+2,nscommands[i].cmdname)==0) { | | if (strcmp((char*)ns->inbuf.buf+2,client_commands[i].cmdname)==0) { |
nscommands[i].cmdproc((char*)data,len,ns); | | client_commands[i].cmdproc((char*)data,len,ns); |
ns->inbuf.len=0; | | ns->inbuf.len=0; |
return; | | return; |
} | | } |
| | |
* at the map causes a crash. If the command is valid, but | | * at the map causes a crash. If the command is valid, but |
* one they can't use, we still swallow it up. | | * one they can't use, we still swallow it up. |
*/ | | */ |
if (pl) for (i=0; plcommands[i].cmdname !=NULL; i++) { | | if (pl) for (i=0; player_commands[i].cmdname !=NULL; i++) { |
if (strcmp((char*)ns->inbuf.buf+2,plcommands[i].cmdname)==0) { | | if (strcmp((char*)ns->inbuf.buf+2,player_commands[i].cmdname)==0) { |
if (pl->state == ST_PLAYING || plcommands[i].flag == 0) | | if (pl->state == ST_PLAYING || player_commands[i].flag == 0) |
plcommands[i].cmdproc((char*)data,len,pl); | | player_commands[i].cmdproc((char*)data,len,pl); |
ns->inbuf.len=0; | | ns->inbuf.len=0; |
return; | | return; |
} | | } |
| | |
#endif | | #endif |
/* If this is the case, all sockets currently in used */ | | /* If this is the case, all sockets currently in used */ |
if (socket_info.allocated_sockets <= socket_info.nconns) { | | if (socket_info.allocated_sockets <= socket_info.nconns) { |
init_sockets = realloc(init_sockets,sizeof(NewSocket)*(socket_info.nconns+1)); | | init_sockets = realloc(init_sockets,sizeof(socket_struct)*(socket_info.nconns+1)); |
if (!init_sockets) fatal(OUT_OF_MEMORY); | | if (!init_sockets) fatal(OUT_OF_MEMORY); |
newsocknum = socket_info.allocated_sockets; | | newsocknum = socket_info.allocated_sockets; |
socket_info.allocated_sockets++; | | socket_info.allocated_sockets++; |
| | |
else { | | else { |
char buf[MAX_BUF]; | | char buf[MAX_BUF]; |
long ip; | | long ip; |
NewSocket *ns; | | socket_struct *ns; |
| | |
ns = &init_sockets[newsocknum]; | | ns = &init_sockets[newsocknum]; |
| | |
| | |
init_sockets[newsocknum].fd = -1; | | init_sockets[newsocknum].fd = -1; |
} | | } |
else { | | else { |
InitConnection(ns, buf); | | init_connection(ns, buf); |
socket_info.nconns++; | | socket_info.nconns++; |
} | | } |
} | | } |
| | |
continue; | | continue; |
} | | } |
if (FD_ISSET(init_sockets[i].fd, &tmp_read)) { | | if (FD_ISSET(init_sockets[i].fd, &tmp_read)) { |
HandleClient(&init_sockets[i], NULL); | | handle_client(&init_sockets[i], NULL); |
} | | } |
if (FD_ISSET(init_sockets[i].fd, &tmp_write)) { | | if (FD_ISSET(init_sockets[i].fd, &tmp_write)) { |
init_sockets[i].can_write=1; | | init_sockets[i].can_write=1; |
| | |
final_free_player(pl); | | final_free_player(pl); |
} | | } |
else { | | else { |
HandleClient(&pl->socket, pl); | | handle_client(&pl->socket, pl); |
/* If the player has left the game, then the socket status | | /* If the player has left the game, then the socket status |
* will be set to this be the leave function. We don't | | * will be set to this be the leave function. We don't |
* need to call leave again, as it has already been called | | * need to call leave again, as it has already been called |