Exemple #1
0
static int csend(int nr,unsigned char *buf,int len)
{
        int size;

        if (!player[nr]) return -1;

	while (len) {
		if (player[nr]->iptr>=player[nr]->optr) {
			size=OBUFSIZE-player[nr]->iptr;
		} else {
			size=player[nr]->optr-player[nr]->iptr;
		}
		size=min(size,len);
		memcpy(player[nr]->obuf+player[nr]->iptr,buf,size);

		player[nr]->iptr+=size; if (player[nr]->iptr==OBUFSIZE) player[nr]->iptr=0;
		buf+=size; len-=size;

		if (player[nr]->iptr==player[nr]->optr) {
			//xlog("send buffer overflow, kicking player %d",nr);
                        kick_player(nr,NULL);
                        return -1;
		}
		//xlog("add: iptr=%d, optr=%d, len=%d, size=%d",player[nr]->iptr,player[nr]->optr,len,size);
	}
        return 0;
}
Exemple #2
0
static void send_player(int nr)
{
        int ret,len;
        unsigned long long prof;

        if (player[nr]->iptr<player[nr]->optr) {
                len=OBUFSIZE-player[nr]->optr;
        } else {
                len=player[nr]->iptr-player[nr]->optr;
        }

	//xlog("rem: iptr=%d, optr=%d, len=%d",player[nr]->iptr,player[nr]->optr,len);

        prof=prof_start(11); ret=send(player[nr]->sock,player[nr]->obuf+player[nr]->optr,len,0); prof_stop(11,prof);
        if (ret==-1) {  // send failure
		//xlog("send failure, kicking player %d",nr);
                kick_player(nr,NULL);
                return;
        }

        player[nr]->optr+=ret;

        if (player[nr]->optr==OBUFSIZE) player[nr]->optr=0;

	sent_bytes_raw+=ret+60;
	sent_bytes+=ret;
}
Exemple #3
0
// careful here, any csend might clear player[n]!
void pflush(void)
{
	int n,ilen,olen,csize,ret,olow,ohigh;
	unsigned char obuf[OBUFSIZE];
	unsigned long long prof;
	
	for (n=1; n<MAXPLAYER; n++) {
		if (!player[n]) continue;
	
		ilen=player[n]->tptr;

		if (ilen>16) {
			player[n]->zs.next_in=player[n]->tbuf;
			player[n]->zs.avail_in=ilen;
	
			player[n]->zs.next_out=obuf;
			player[n]->zs.avail_out=OBUFSIZE;

                        prof=prof_start(12); ret=deflate(&player[n]->zs,Z_SYNC_FLUSH); prof_stop(12,prof);
			if (ret!=Z_OK) {
				elog("compression failure #1, kicking player %d",n);
				kick_player(n,NULL);
				continue;
			}
	
			if (player[n]->zs.avail_in) {
				elog("compression failure #2, kicking player %d",n);
				kick_player(n,NULL);
				continue;
			 }
	
			csize=OBUFSIZE-player[n]->zs.avail_out;
	
			olen=(csize);
			
			if (olen>63) {			
				ohigh=(olen>>8)|0x80;
				olow=olen&255;
	
				csend(n,(void*)(&ohigh),1);
				csend(n,(void*)(&olow),1);
			} else {
Exemple #4
0
void psend(int nr,char *buf,int len)
{
	if (!player[nr]) return;
	
	if (player[nr]->tptr+len>=OBUFSIZE) {
		xlog("tptr overflow!");
		kick_player(nr,NULL);
		return;
	}
	memcpy(player[nr]->tbuf+player[nr]->tptr,buf,len);
	player[nr]->tptr+=len;
}
Exemple #5
0
static void rec_player(int nr)
{
        int len;

        len=recv(player[nr]->sock,(char*)player[nr]->inbuf+player[nr]->in_len,256-player[nr]->in_len,0);

        if (len<1) {    // receive failure
                if (errno!=EWOULDBLOCK) {
			//xlog("receive failure, kicking player %d",nr);
                        kick_player(nr,NULL);
                }
                return;
        }
        player[nr]->in_len+=len;
	
	rec_bytes_raw+=len+60;
	rec_bytes+=len;
}
Exemple #6
0
/* true return value indicates that connection must be closed */
int process_msg(int fd, char* msg)
{
    int client_proto_major;
    int client_proto_minor;
    char * args;
    char * ptr, * ptr2;
    char * msg_orig;

    /* check for leading protocol tag */
    if (!str_begins_static_str(msg, "FB/")
            || strlen(msg) < 8) {  // 8 stands for "FB/M.m f"(oo)
        send_line_log(fd, fl_line_unrecognized, msg);
        return 1;
    }

    /* check if client protocol is compatible; for simplicity, we don't support client protocol more recent
     * than server protocol, we suppose that our servers are upgraded when a new release appears (but of
     * course client protocol older is supported within the major protocol) */
    client_proto_major = charstar_to_int(msg + 3);
    client_proto_minor = charstar_to_int(msg + 5);
    if (client_proto_major != proto_major
            || client_proto_minor > proto_minor) {
        send_line_log(fd, fl_proto_mismatch, msg);
        return 1;
    }

    if (remote_proto_minor[fd] == -1)
        remote_proto_minor[fd] = client_proto_minor;

    msg_orig = strdup(msg);

    /* after protocol, first word is command, then possible args */
    current_command = msg + 7; // 7 stands for "FB/M.m "
    if ((ptr = strchr(current_command, ' '))) {
        *ptr = '\0';
        args = current_command + strlen(current_command) + 1;
    } else
        args = NULL;

    if (streq(current_command, "PING")) {
        send_line_log(fd, ok_pong, msg_orig);
    } else if (streq(current_command, "NICK")) {
        if (!args) {
            send_line_log(fd, wn_missing_arguments, msg_orig);
        } else {
            if ((ptr = strchr(args, ' ')))
                *ptr = '\0';
            if (strlen(args) > 10)
                args[10] = '\0';
            if (!is_nick_ok(args)) {
                send_line_log(fd, wn_nick_invalid, msg_orig);
            } else {
                if (nick[fd] != NULL) {
                    free(nick[fd]);
                }
                nick[fd] = strdup(args);
                calculate_list_games();
                send_ok(fd, msg_orig);
            }
        }
    } else if (streq(current_command, "GEOLOC")) {
        if (!args) {
            send_line_log(fd, wn_missing_arguments, msg_orig);
        } else {
            if ((ptr = strchr(args, ' ')))
                *ptr = '\0';
            if (strlen(args) > 13)  // sign, 4 digits, dot, colon, sign, 4 digits, dot
                args[13] = '\0';
            if (geoloc[fd] != NULL) {
                free(geoloc[fd]);
            }
            geoloc[fd] = strdup(args);
            calculate_list_games();
            send_ok(fd, msg_orig);
        }
    } else if (streq(current_command, "CREATE")) {
        if (!args) {
            send_line_log(fd, wn_missing_arguments, msg_orig);
        } else {
            if ((ptr = strchr(args, ' ')))
                *ptr = '\0';
            if (strlen(args) > 10)
                args[10] = '\0';
            if (!is_nick_ok(args)) {
                send_line_log(fd, wn_nick_invalid, msg_orig);
            } else if (!nick_available(args)) {
                send_line_log(fd, wn_nick_in_use, msg_orig);
            } else if (already_in_game(fd)) {
                send_line_log(fd, wn_already_in_game, msg_orig);
            } else if (games_open == 16) {  // FB client can display 16 max
                send_line_log(fd, wn_max_open_games, msg_orig);
            } else {
                create_game(fd, strdup(args));
                send_ok(fd, msg_orig);
            }
        }
    } else if (streq(current_command, "JOIN")) {
        if (!args || !(ptr = strchr(args, ' '))) {
            send_line_log(fd, wn_missing_arguments, msg_orig);
        } else {
            struct game * g;
            char* nick = ptr + 1;
            *ptr = '\0';
            if ((ptr2 = strchr(ptr, ' ')))
                *ptr2 = '\0';
            if (strlen(nick) > 10)
                nick[10] = '\0';
            if (!is_nick_ok(nick)) {
                send_line_log(fd, wn_nick_invalid, msg_orig);
            } else if (!nick_available(nick)) {
                send_line_log(fd, wn_nick_in_use, msg_orig);
            } else if (already_in_game(fd)) {
                send_line_log(fd, wn_already_in_game, msg_orig);
            } else if (!(g = find_game_by_nick(args))) {
                send_line_log(fd, wn_no_such_game, msg_orig);
            } else {
                if (add_player(g, fd, strdup(nick)))
                    send_ok(fd, msg_orig);
                else
                    send_line_log(fd, wn_game_full, msg_orig);
            }
        }
    } else if (streq(current_command, "KICK")) {
        if (!args) {
            send_line_log(fd, wn_missing_arguments, msg_orig);
        } else {
            if ((ptr = strchr(args, ' ')))
                *ptr = '\0';
            if (strlen(args) > 10)
                args[10] = '\0';
            if (!already_in_game(fd)) {
                send_line_log(fd, wn_not_in_game, msg_orig);
            } else {
                struct game * g = find_game_by_fd(fd);
                if (g->players_conn[0] != fd) {
                    send_line_log(fd, wn_not_creator, msg_orig);
                } else {
                    kick_player(fd, g, args);
                }
            }
        }
    } else if (streq(current_command, "PART")) {
        if (!already_in_game(fd)) {
            send_line_log(fd, wn_not_in_game, msg_orig);
        } else {
            player_part_game(fd);
            send_ok(fd, msg_orig);
        }
    } else if (streq(current_command, "LIST")) {
        send_line_log(fd, list_games_str, msg_orig);
    } else if (streq(current_command, "STATUS")) {  // 1.0 command
        if (!already_in_game(fd)) {
            send_line_log(fd, wn_not_in_game, msg_orig);
        } else {
            status(fd, msg_orig);
        }
    } else if (streq(current_command, "STATUSGEO")) {
        if (!already_in_game(fd)) {
            send_line_log(fd, wn_not_in_game, msg_orig);
        } else {
            status_geo(fd, msg_orig);
        }
    } else if (streq(current_command, "PROTOCOL_LEVEL")) {
        if (!already_in_game(fd)) {
            send_line_log(fd, wn_not_in_game, msg_orig);
        } else {
            protocol_level(fd, msg_orig);
        }
    } else if (streq(current_command, "TALK")) {
        if (!args) {
            send_line_log(fd, wn_missing_arguments, msg_orig);
        } else {
            talk(fd, args);
        }
    } else if (streq(current_command, "START")) {
        if (!already_in_game(fd)) {
            send_line_log(fd, wn_not_in_game, msg_orig);
        } else {
            start_game(fd);
        }
    } else if (streq(current_command, "CLOSE")) {
        if (!already_in_game(fd)) {
            send_line_log(fd, wn_not_in_game, msg_orig);
        } else {
            close_game(fd);
        }
    } else if (streq(current_command, "SETOPTIONS")) {
        if (!args) {
            send_line_log(fd, wn_missing_arguments, msg_orig);
        } else if (!already_in_game(fd)) {
            send_line_log(fd, wn_not_in_game, msg_orig);
        } else {
            setoptions(fd, args);
        }
    } else if (streq(current_command, "LEADER_CHECK_GAME_START")) {
        if (!already_in_game(fd)) {
            send_line_log(fd, wn_not_in_game, msg_orig);
        } else {
            leader_check_game_start(fd);
        }
    } else if (streq(current_command, "OK_GAME_START")) {
        if (!already_in_game(fd)) {
            send_line_log(fd, wn_not_in_game, msg_orig);
        } else {
            ok_start_game(fd);
        }
    } else if (streq(current_command, "ADMIN_REREAD")) {
        if (!admin_authorized[fd]) {
            send_line_log(fd, wn_denied, msg_orig);
        } else {
            reread();
            send_ok(fd, "ADMIN_REREAD");
        }
    } else {
        send_line_log(fd, wn_unknown_command, msg);
    }

    free(msg_orig);
    current_command = NULL;

    return 0;
}