/* Put a message onto the output buffer */ void net_put_message(netconnection_t *nc, netmsg msg) { int type, size; #if NET_DEBUG printf("net_put_message(%s)\n", net_message_name(msg.type)); #endif type = (int)msg.type; if( type >= NUM_NETMESSAGES ) { printf("Unknown message type %d\n", type); return; } size = netmsg_table[type].size; if( nc->output.size + size > NETBUFSIZ ) { printf("Output full. Auto-flushing.\n"); net_output_flush(nc); if( nc->output.size + size > NETBUFSIZ ) { printf("Could not write output to %s. Discarding buffer\n", nc->remote_address); nc->output.size = 0; return; } } tonet(&msg); /* To network byte order */ memcpy(nc->output.buf + nc->output.size, &msg, size); nc->output.size += size; }
void net_close_connection(netconnection_t *nc) { if( nc ) { net_output_flush(nc); close(nc->fd); if( nc->record_fd ) close(nc->record_fd); free(nc); } }
void sv_net_update_clients(void) { client_t *cl; for( cl = cl_root ; cl != NULL ; cl = cl->next ) { if( cl->status == ACTIVE ) { sv_net_update_statusbar(cl); event_draw(cl); sv_net_send_entities(cl); sv_netmsg_send_message(cl, NETMSG_END_FRAME); } net_output_flush(cl->nc); } }
int cl_network_connect(char *sv_name, int port) { struct hostent *hp; struct sockaddr_in addr; netmsg msg; demo_header header; int sock = -1; if( client.demo != DEMO_PLAY ) { /* A real connection, not just a demo */ memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = htons(port); if(!client.with_ggz) { sock = net_init_socket(); if( (addr.sin_addr.s_addr = inet_addr(sv_name)) == INADDR_NONE ) { if((hp = gethostbyname(sv_name)) == NULL) { close(sock); sock = -1; return 0; } else { addr.sin_addr.s_addr = *(long *) hp->h_addr; } } if( connect(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0 ) { perror("connect"); close(sock); sock = -1; return 0; } } else { /* ggz mode */ signal(SIGPIPE, SIG_IGN); /* Ignore Pipe errors */ if( (sock = ggz_client_get_sock()) < 0 ) { sock = -1; return 0; } /* avoid perdig effect */ sleep(3); } } switch( client.demo ) { case DEMO_RECORD: printf("RECORDING Connection.......\n"); header.x_tiles = client.x_tiles; header.y_tiles = client.y_tiles; header.fps = client.fps; server = net_rec_new_connection(sock, client.demoname, header); break; case DEMO_PLAY: server = net_fake_connection(client.demoname, &header); client.x_tiles = header.x_tiles; client.y_tiles = header.y_tiles; client.view_w = client.x_tiles * TILE_W; client.view_h = client.y_tiles * TILE_H; break; case DEMO_NONE: default: server = net_new_connection(sock); } if( server == NULL ) { printf("Couldn't create new connection\n"); close(sock); sock = -1; return 0; } client.connected = 1; client.sv_status = JOINING; printf("Joining Game....\n"); cl_netmsg_send_join(); printf("Querying Server info......\n"); cl_netmsg_send_query_sv_info(); net_output_flush(server); /* FIXME: This alarm() does not work correctly */ alarm(10); /* Timeout after 10 secs */ signal(SIGALRM, sigcatcher); printf("Reading data from server...... "); while( net_input_flush(server, NM_ALL) > 0 ) { printf("Got something!\n"); while( (msg = net_next_message(server, NM_ALL)).type != NETMSG_NONE ) { if( msg.type == NETMSG_SV_INFO ) { /* Got server info ok, we can join the game */ alarm(0); cl_net_handle_message(msg); return 1; } else if(msg.type == NETMSG_REJECTION || msg.type == NETMSG_QUIT){ /* We were rejected or another error occured trying to join */ alarm(0); cl_net_handle_message(msg); return 0; } else if( client.debug ) { printf("IGNORING message type %d!\n", msg.type); } } } alarm(0); printf("TIMED OUT waiting for server info!\n"); cl_network_disconnect(); return 0; }
void cl_net_finish(void) { net_output_flush(server); }