int RequestMessageProcessor::process_incoming_msg(LSP_Packet& packet) { /* Call the base class function before processing further */ if(MessageProcessor::process_incoming_msg(packet) == FAILURE) return FAILURE; switch(packet.getType()) { case ACK: process_ack_packet(packet); break; case DATA: return process_data_packet(packet); default: fprintf( stderr, "Unknown Packet Type!\n"); packet.print(); } return SUCCESS; }
i4_bool g1_client_class::poll() // returns false if server is not responding { if (!listen || !send) { return 0; } if (state==JOIN_START) { i4_time_class now; if (now.milli_diff(last_responce_time)>40000) // if it's been 40 secs assume server dead { i4_message_box("Server not responding","The server is not responding any more. ",MSG_OK); return i4_F; } w8 packet[512]; i4_ram_file_class r(packet, sizeof(packet)); r.write_8(G1_PK_I_WANNA_JOIN); r.write_16(use_port); r.write_counted_str(*g1_resources.username); if (!send->write(packet, r.tell())) { return i4_F; } } if (state==SYNCING) //set from the main loop as soon as the map is loaded { PACKET(pack,fp); //we just resend this message till we get the matching reply fp.write_8(G1_PK_LOADING_DONE); send_server(pack,&fp); } int noloops=0; while (listen->ready_to_read() && noloops<10) { w8 packet[MAX_PACKET_SIZE]; i4_net_address * a; int s=listen->read_from(packet, sizeof(packet), a); if (a->equals(server_address)) { i4_ram_file_class r(packet, sizeof(packet)); w8 new_message=r.read_8(); switch (new_message) { case G1_PK_YOU_HAVE_JOINED: { player_num=(w8)r.read_16(); if (map_name) { delete map_name; } map_name=r.read_counted_str(); i4_warning("We were accepted by the server to join"); state=CONNECTING; last_responce_time.get(); } break; case G1_PK_WE_ARE_STARTING: { num_players=r.read_32(); if (state==CONNECTING) { i4_warning("Loading game data"); //don't do this twice. //i4_user_message_event_class u(G1_START_NEW_GAME); i4_file_open_message_class u(G1_SAVEGAME_LOAD_OK, new i4_str (* map_name)); i4_kernel.send_event(i4_current_app, &u); state=LOADING; } //li_call("hide_main_menu"); } break; case G1_PK_GAME_START: { //from now on, it's the main loops task to know that //this is a net game if (state!=RUNNING) { int num_ais=r.read_32(); if (num_ais>G1_MAX_PLAYERS) { i4_error("ERROR: Local Golgotha version supports fewer players than this game needs. Check your version."); num_ais=G1_MAX_PLAYERS; } i4_str * ainame=0; g1_team_api_class * newai=0; for (int ais=0; ais<num_ais; ais++) { //the player the next ai is for w32 aifor=r.read_32(); ainame=r.read_counted_str(); char buf[100]; i4_os_string(*ainame,buf,100); newai=g1_create_ai(buf,0); if (strcmp(buf,"human")==0) { //this will be the local player g1_player_man.local_player=ais; i4_warning("We were assigned player number %i.",ais); } g1_player_man.get(ais)->set_ai(newai); newai->init(); delete ainame; } g1_global_id.enable_networking(ID_NET_CLIENT); state=RUNNING; i4_warning("The game is in sync and has started"); } //this message is sent by the server if all clients are ready } break; case G1_PK_GAME_DATA: { process_data_packet(r,i4_F); } break; default: { if (new_message>=G1_PK_ID_BASE && new_message<=G1_PK_ID_END) { r.seek(0); g1_global_id.receive_packet(&r); } } } } delete a; noloops++; } return i4_T; }
void g1_server_class::process_client_packet(w8 * packet, int packet_length, int client_num) { clients[client_num].last_data.get(); i4_ram_file_class r(packet, packet_length); w8 msg=r.read_8(); switch (msg) { case G1_PK_I_WANNA_JOIN: { r.read_16(); // skip use port delete clients[client_num].username; clients[client_num].username=r.read_counted_str(); send_player_joined(client_num); } break; case G1_PK_LOADING_DONE: { clients[client_num].flags|=READY; i4_bool ok=i4_T; for (int i=0; i<G1_MAX_PLAYERS; i++) { if (clients[i].addr && !(clients[i].flags&READY)) { ok=i4_F; //at least one is not yet ready; } } if (ok&&state==SYNCING) { int rem_players,player,k,k2; rem_players=0; player=1; //zero is always neutral, //1 is usually local (server) player if (player==local_player_num) { player++; } for(k=0; k<G1_MAX_PLAYERS; k++) { if (clients[k].addr!=0) { rem_players++; clients[k].remote_player_num=player; player++; if (player==local_player_num) { player++; } } } for (player=0; player<G1_MAX_PLAYERS; player++) { if (clients[player].addr) { PACKET(sp,s); s.write_8(G1_PK_GAME_START); s.write_32(G1_MAX_PLAYERS); //So many ai's are going to follow for (k=0; k<G1_MAX_PLAYERS; k++) { s.write_32(k); g1_player_info_class * pl=g1_player_man.get(k); i4_bool found=i4_F; if (k==0) //the neutral player { s.write_counted_str(*(pl->get_ai()->ai_name())); found=i4_T; } else if (k==local_player_num) { s.write_counted_str("remote_player"); found=i4_T; } else { for (k2=0; k2<G1_MAX_PLAYERS; k2++) { if (clients[k2].addr && clients[k2].remote_player_num==k) { //this automatically indicates //that it is the remote local player //(only one player can be human at a time on //a particular machine) s.write_counted_str("human"); found=i4_T; break; } } } if (!found) //this player will stay the same as originally defined on the map { s.write_counted_str(*(pl->get_ai()->ai_name())); found=i4_T; } } send_to(sp,&s,player); send_to(sp,&s,player); //its important! } } //finally, set the matching ai's also for the server for (player=0; player<G1_MAX_PLAYERS; player++) { g1_team_api_class * newai=0; i4_bool found=i4_F; if (player==0) { newai=g1_create_ai("ai_neutral",0); g1_player_man.get(player)->set_ai(newai); newai->init(); found=i4_T; } else if (player==local_player_num) { newai=g1_create_ai("human",0); g1_player_man.get(player)->set_ai(newai); newai->init(); g1_player_man.local_player=player; found=i4_T; } else { for (k2=0; k2<G1_MAX_PLAYERS; k2++) { if (clients[k2].addr && clients[k2].remote_player_num==player) { //player "player" is a remote player newai=g1_create_ai("remote_player"); g1_player_man.get(player)->set_ai(newai); newai->init(); found=i4_T; } } } //in all other cases, we read the correct ai from the disk } g1_global_id.enable_networking(ID_NET_SERVER); state=RUNNING; i4_warning("Server: Switched to running state."); } } break; case G1_PK_GAME_DATA: { process_data_packet(r,i4_T); /* r.read_32();//skip empty field w32 ticksent=r.read_32();//to which tick does this packet belong? //here follows: reading out the objects g1_realtime_loader_class *rtloader=new g1_realtime_loader_class(&r,i4_F,i4_F); w32 objfor=rtloader->read_32(); w16 typefor=0; while (objfor!=0) { if (objfor==g1_global_id_manager_class::ID_DELETEPROPAGATE) { //don't delete if object just doesn't exist locally. objfor=rtloader->read_32(); g1_object_class *obdel=g1_global_id.checked_get(objfor); if (obdel) { obdel->set_flag(g1_object_class::THINKING,1);//Perhaps was not thinking locally obdel->stop_thinking(); obdel->unoccupy_location(); obdel->request_remove(); } } else { typefor=rtloader->read_16(); g1_object_class *obj=g1_global_id.checked_get(objfor); if (!obj) { //Object seems to be new //obj=g1_create_object(typefor); if (typefor>=0 && typefor<=g1_last_object_type) { //The object will just be in sync obj=g1_object_type_array[typefor]->create_object(typefor,rtloader); obj->occupy_location(); obj->grab_old(); if (obj->get_flag(g1_object_class::THINKING)) obj->request_think(); g1_player_man.get(obj->player_num)->add_object(obj->global_id); } else { i4_error("ERROR: Unknown object type requested"); delete rtloader; return; } //g1_global_id.assign(objfor,obj); } else { obj->load(rtloader); } obj->set_flag(g1_object_class::NEEDS_SYNC,1); } objfor=rtloader->read_32(); } //don't forget to mark these as to be resent. delete rtloader; */ } break; default: { if (msg>=G1_PK_ID_BASE && msg<=G1_PK_ID_END) { r.seek(0); g1_global_id.receive_packet(&r); } } } }
int main( void ) { uint8_t already_converted = 0; uint8_t outlier_count = 0; uint16_t new_sonar_value = 0; /* initialize Robostix 1 */ controller_init( ); while( 1 ) { /* check if communication is upright */ if( flag_check_delay ) { check_receive_delay( ); } /* check if new serial or parallel data available */ if( serial_is_new_data( ) )//|| parallel_is_new_data( ) ) { process_data_packet( ); } /* check if new IMU data available */ if( dm3gx1_is_new_data( ) && !dm3gx1_get_data( &javiator_data ) ) { javiator_data.state |= ST_NEW_DATA_IMU; } /* check if new analog sonar data available */ if( minia_is_new_data( ) && !already_converted ) { /* convert sonar data */ adc_convert( ADC_CH_SONAR ); already_converted = 1; } else if( !minia_is_new_data( ) ) { already_converted = 0; } /* check if new converted sonar data available */ if( adc_is_new_data( ADC_CH_SONAR ) && !adc_get_data( ADC_CH_SONAR, &new_sonar_value ) ) { if( abs( javiator_data.sonar - new_sonar_value ) < 15 || outlier_count > 1 ) { javiator_data.sonar = new_sonar_value; outlier_count = 0; } else { ++outlier_count; } javiator_data.state |= ST_NEW_DATA_SONAR; } /* check if new converted battery data available */ if( adc_is_new_data( ADC_CH_BATT ) ) { adc_get_data( ADC_CH_BATT, &javiator_data.batt ); } } return( 0 ); }