int game_client::process_net() { if (client_sock->error()) return 0; if (game_sock->ready_to_read()) // any game data comming in? { net_packet tmp; // don't store in main packet in case something is wrong with this packet and server still needs old one int bytes_received = game_sock->read(tmp.data, PACKET_MAX_SIZE); if (bytes_received == tmp.packet_size() + tmp.packet_prefix_size()) // was the packet complete? { uint16_t rec_crc = tmp.get_checksum(); if (rec_crc == tmp.calc_checksum()) { if (base->current_tick == tmp.tick_received()) { base->packet = tmp; wait_local_input = 1; base->input_state = INPUT_PROCESSING; // tell engine to start processing } // else fprintf(stderr,"received stale packet (got %d, expected %d)\n",tmp.tick_received(),base->current_tick); } else fprintf(stderr, "received packet with bad checksum\n"); } else fprintf(stderr, "incomplete packet, read %d, should be %d\n", bytes_received, tmp.packet_size() + tmp.packet_prefix_size()); } if (client_sock->ready_to_read()) { if (!process_server_command()) { main_net_cfg->state = net_configuration::RESTART_SINGLE; start_running = 0; strcpy(lsf, "abuse.lsp"); wait_local_input = 1; base->input_state = INPUT_PROCESSING; // tell engine to start processing return 0; } } return 1; }
//Game functions void * game_f( void *data ) { struct gamedata_t *mygamedata; mygamedata = (struct gamedata_t *) data; struct playerdata_t *myplayers; bool run=true; int retval; struct epoll_event event_setup; myplayers = malloc( sizeof (struct playerdata_t) * MAX_PLAYERS ); for( int i = 0; i < MAX_PLAYERS; i++ ){ myplayers[i].playerid = -1; } mygamedata->numplayers=0; // (MAX_PLAYERS+1) because of the extra pipe to talk to the server mygamedata->epfd = epoll_create ( MAX_PLAYERS + 1 ); //printf( "NG %d ip rd %d ip wr %d op rd %d op wr %d epfd %d tid %lu\n", mygamedata->gamenumber, mygamedata->input[READPIPE], mygamedata->input[WRITEPIPE], mygamedata->output[READPIPE], mygamedata->output[WRITEPIPE], mygamedata->epfd, pthread_self() ); printf( "New Game %d\n", mygamedata->gamenumber ); //Setting bit 63 == this is a server command event_setup.data.u64 = SRV_CMD; event_setup.events = EPOLLIN; if ( -1 == epoll_ctl( mygamedata->epfd, EPOLL_CTL_ADD, mygamedata->input[READPIPE], &event_setup ) ) { retval = errno; //we return just a success/failure value printf( "Error adding server fd to epoll list\n" ); pthread_exit( (void *) (long)retval ); } while( run ) { int numevents; struct epoll_event event_list[MAX_EVENTS]; // Wait forever for an event from a player or the server // Later, for a dyamic game that has timed updates, the // -1 is replaced with how many ms to wait // printf( "Game %d waiting for event\n", mygamedata->gamenumber ); numevents = epoll_wait( mygamedata->epfd, event_list, MAX_EVENTS, -1 ); // Save a variable by counting down ( currently MAX_EVENTS // is 1) , does it matter if we start at the end? for( numevents--;numevents >= 0; numevents-- ) { if( event_list[numevents].data.u64 == ( SRV_CMD ) ) { run = process_server_command( mygamedata, myplayers ); } else { // Process player command printf( "Player command received\n" ); run = process_player_command( mygamedata, myplayers, (int) event_list[numevents].data.u64 ); } } } game_cleanup( mygamedata, myplayers ); retval = EXIT_SUCCESS; pthread_exit( (void *) (long)retval ); }