#include "cool.h" #include "string.h" #include "netio.h" #include "buf.h" #include "netio_private.h" #include "servers.h" static struct timeval msec2timeval (int msec); static void player_command (Player * p, char *command); static void player_output(Player *p, const char *msg, char newline ); static void player_output(Player *p, const char *msg, char newline ) { String *str; str = string_cpy (msg); if( newline ) str = string_cat (str, "\r\n"); buf_add (&p->output, str); } void tell(Playerid player, const char *msg, char newline ) { Player *p; for(p = players; p; p = p->next) { if (p->id == player) { player_output(p, msg, newline ); break; } } } void tell_fd(SOCKET fd, const char *msg, char newline) { Player *p; for (p = players; p; p = p->next) { if (p->fd == fd) { player_output(p, msg, newline ); break; } } } static void player_disconnect(Player *p) { /* make one last-ditch attempt to flush output buffer */ send_output(p->fd, &p->output); disconnect_player(p->id); remove_player(p); } void disconnect(Playerid who) { Player *p; for (p = players; p; p = p->next) { if (p->id == who) { player_disconnect(p); } } } void disconnect_fd(SOCKET fd) { Player *p; for (p = players; p; p = p->next) { if (p->fd == fd) { player_disconnect(p); } } } void player_command(Player *p, char *command) { while(isspace((int)*command)) { command++; } parse(p->id, command, p->fd); } #define MSEC(T) (T.tv_sec * 1000 + T.tv_usec / 1000) static struct timeval msec2timeval(int msec) { struct timeval r; r.tv_sec = msec / 1000; r.tv_usec = (msec % 1000 ) * 1000; return r; } void parse_connect (char *msg, char **command, char **user, char **pass) { while (*msg && isascii (*msg) && isspace ((int)*msg)) /* skip whitespace */ msg++; *command = msg; while (*msg && isascii (*msg) && !isspace ((int)*msg)) /* skip command */ msg++; if (*msg) { *msg++ = '\0'; /* terminate cmd */ } while (*msg && isascii (*msg) && isspace ((int)*msg)) /* skip whitespace */ msg++; *user = msg; while (*msg && isascii (*msg) && !isspace ((int)*msg)) /* skip user */ msg++; if (*msg) { *msg++ = '\0'; /* terminate user */ } while (*msg && isascii (*msg) && isspace ((int)*msg)) /* skip whitespace */ msg++; *pass = msg; while (*msg && isascii (*msg) && !isspace ((int)*msg)) /* skip password */ msg++; *msg = '\0'; /* terminate pass */ } void queue_player_commands(struct timeval cur_time, struct timeval *timeout) { Player *p; int msec_since_last; static struct timeval last = { 0, 0 }; struct timeval new; msec_since_last = MSEC (cur_time) - MSEC (last); last = cur_time; for (p = players; p; p = p->next) { p->quota += msec_since_last; if (p->quota > MAX_CMDS * MSEC_PER_CMD) { p->quota = MAX_CMDS * MSEC_PER_CMD; } if (p->input.head && p->quota >= 0) { player_command (p, p->input.head->str->str); buf_delhead (&p->input); p->quota -= MSEC_PER_CMD; } if (p->input.head && p->quota < 0) { /* return when quota is positive */ new = msec2timeval (-p->quota); *timeout = (timercmp (&new, timeout, <))? new : *timeout; } } } void set_parse(SOCKET fd, Playerid player) { Player *p, *pnext; for (p = players; p; p = pnext) { pnext = p->next; if (p->id == player && p->fd != fd) { /* write(p->fd, DISCONNECT_MSG, strlen (DISCONNECT_MSG)); */ disconnect_player(p->id); remove_player(p); } else if (p->fd == fd) { p->connected = 1; p->id = player; } } }