void world_sync() { int i; for (i = 1; i <= MAX_PLAYERS; i++) if (players[i]) { update_players(players[i]); } }
int run() { timer_srv.reset(new boost::asio::io_service()); the_net.reset(new net_server<koko_socket>(2)); boost::system::error_code ec; the_config.load_from_file(); db_.reset(new utf8_data_base(the_config.accdb_host_, the_config.accdb_user_,the_config.accdb_pwd_, the_config.accdb_name_)); if(!db_->grabdb()){ glb_log.write_log("database start failed!!!!"); return -1; } db_delay_helper_[0].set_db_ptr(db_); if (start_network() != 0){ goto _EXIT; } { boost::shared_ptr<boost::thread> td(new boost::thread(boost::bind(db_thread_func, db_delay_helper_))); cache_persistent_threads.push_back(td); } int idle_count = 0; task_on_5sec* ptask = new task_on_5sec(*timer_srv); task.reset(ptask); ptask->schedule(1000); ptask->routine(); while(!glb_exit) { bool busy = false; timer_srv->reset(); timer_srv->poll(); the_net->ios_.reset(); the_net->ios_.poll(); handle_pending_logins(); pickup_player_msgs(busy); handle_player_msgs(); update_players(); smsg_ptr pmsg; broadcast_msg_.pop_front(pmsg); if(pmsg.get()) broadcast_msg(pmsg); boost::posix_time::milliseconds ms(20); boost::this_thread::sleep(ms); } _EXIT: return 0; }
void test_update_players_from_compress(TestContext* tc) { int assertion; int compress; PixelUpdate pu; //Create maze Maze maze; maze_build_from_file(&maze,"test.map"); //Initialize a dummy player Player test_player; player_init(&test_player); test_player.cell = &maze.get[0][0]; test_player.id = 0; test_player.state = PLAYER_FREE; test_player.team = TEAM_RED; //Compress Player compress_player(&test_player,&compress,PLAYER_ADDED); //Update Maze based on compressed player update_players(1,&compress,&maze,&pu); assertion = (maze.get[0][0].player)==(&maze.players[TEAM_RED].at[0]); should("match the address of the player stored in the cell to the address of the player in the plist",assertion,tc); assertion = (maze.get[0][0].player->state)==(PLAYER_FREE); should("match the player's state before the compress",assertion,tc); }
// ZZZ: split out from update_world()'s loop. static int update_world_elements_one_tick() { if (m1_solo_player_in_terminal()) { update_m1_solo_player_in_terminal(GameQueue); } else { L_Call_Idle(); update_lights(); update_medias(); update_platforms(); update_control_panels(); // don't put after update_players update_players(GameQueue, false); move_projectiles(); move_monsters(); update_effects(); recreate_objects(); handle_random_sound_image(); animate_scenery(); // LP additions: if (film_profile.animate_items) { animate_items(); } AnimTxtr_Update(); ChaseCam_Update(); motion_sensor_scan(); check_m1_exploration(); #if !defined(DISABLE_NETWORKING) update_net_game(); #endif // !defined(DISABLE_NETWORKING) } if(check_level_change()) { return kUpdateChangeLevel; } #if !defined(DISABLE_NETWORKING) if(game_is_over()) { return kUpdateGameOver; } #endif // !defined(DISABLE_NETWORKING) dynamic_world->tick_count+= 1; dynamic_world->game_information.game_time_remaining-= 1; return kUpdateNormalCompletion; }
/* process_sync_request After the RPC thread recieves a sync response from the server we update the object information in the maze, the broken walls in the maze and the players in the game parameter: maze pointer to the client's local copy of the maze parameter: ch handle to a Proto_Client parameter: hdr pointer to hdr that contains unmarshalled data return: int return code */ int process_sync_request(Maze* maze, Proto_Client_Handle ch, Proto_Msg_Hdr* hdr) { // Variable Declaration int* broken_walls_compress; int* player_compress; int* object_compress; int offset; //Get number of elements for walls and players int num_walls = hdr->pstate.v2.raw; int num_players = hdr->pstate.v3.raw; //Malloc the variables broken_walls_compress = (int*) malloc(num_walls*sizeof(int)); player_compress = (int*) malloc(num_players*sizeof(int)); object_compress = (int*) malloc(4*sizeof(int)); //Get the data from the body of the message offset = 0; offset = get_compress_from_body(ch, offset, num_walls, broken_walls_compress); offset = get_compress_from_body(ch, offset, num_players, player_compress); offset = get_compress_from_body(ch, offset, 4, object_compress); PixelUpdate pu; //null pointer to get the below to work update_objects(4,object_compress,maze, &pu); update_walls(num_walls,broken_walls_compress,maze, &pu); update_players(num_players,player_compress,maze, &pu); //De-allocate the malloced variables free(broken_walls_compress); free(player_compress); free(object_compress); if(proto_debug()) { } return hdr->gstate.v0.raw; }
std::pair<bool, int16> update_world() { short theElapsedTime = 0; bool canUpdate = true; int theUpdateResult = kUpdateNormalCompletion; #ifndef DISABLE_NETWORKING if (game_is_networked) NetProcessMessagesInGame(); #endif while(canUpdate) { // If we have flags in the GameQueue, or can put a tick's-worth there, we're ok. // Note that GameQueue should be stocked evenly (i.e. every player has the same # of flags) if(GameQueue->countActionFlags(0) == 0) { canUpdate = overlay_queue_with_queue_into_queue(GetRealActionQueues(), GetLuaActionQueues(), GameQueue); } if(!sPredictionWanted) { // See if the speed-limiter (net time or heartbeat count) will let us advance a tick #if !defined(DISABLE_NETWORKING) int theMostRecentAllowedTick = game_is_networked ? NetGetNetTime() : get_heartbeat_count(); #else int theMostRecentAllowedTick = get_heartbeat_count(); #endif if(dynamic_world->tick_count >= theMostRecentAllowedTick) { canUpdate = false; } } // If we can't update, we can't update. We're done for now. if(!canUpdate) { break; } // Transition from predictive -> real update mode, if necessary. exit_predictive_mode(); // Capture the flags for each player for use in prediction for(short i = 0; i < dynamic_world->player_count; i++) sMostRecentFlagsForPlayer[i] = GameQueue->peekActionFlags(i, 0); theUpdateResult = update_world_elements_one_tick(); theElapsedTime++; L_Call_PostIdle(); if(theUpdateResult != kUpdateNormalCompletion || Movie::instance()->IsRecording()) { canUpdate = false; } } // This and the following voodoo comes, effectively, from Bungie's code. if(theUpdateResult == kUpdateChangeLevel) { theElapsedTime = 0; } /* Game is over. */ if(theUpdateResult == kUpdateGameOver) { game_timed_out(); theElapsedTime = 0; } else if (theElapsedTime) { update_interface(theElapsedTime); update_fades(); } check_recording_replaying(); // ZZZ: Prediction! bool didPredict = false; if(theUpdateResult == kUpdateNormalCompletion && sPredictionWanted) { NetUpdateUnconfirmedActionFlags(); // We use "2" to make sure there's always room for our one set of elements. // (thePredictiveQueues should always hold only 0 or 1 element for each player.) ActionQueues thePredictiveQueues(dynamic_world->player_count, 2, true); // Observe, since we don't use a speed-limiter in predictive mode, that there cannot be flags // stranded in the GameQueue. Unfortunately this approach will mispredict if a script is // controlling the local player. We could be smarter about it if that eventually becomes an issue. for ( ; sPredictedTicks < NetGetUnconfirmedActionFlagsCount(); sPredictedTicks++) { // Real -> predictive transition, if necessary enter_predictive_mode(); // Enqueue stuff into thePredictiveQueues for(short thePlayerIndex = 0; thePlayerIndex < dynamic_world->player_count; thePlayerIndex++) { uint32 theFlags = (thePlayerIndex == local_player_index) ? NetGetUnconfirmedActionFlag(sPredictedTicks) : sMostRecentFlagsForPlayer[thePlayerIndex]; thePredictiveQueues.enqueueActionFlags(thePlayerIndex, &theFlags, 1); } // update_players() will dequeue the elements we just put in there update_players(&thePredictiveQueues, true); didPredict = true; } // loop while local player has flags we haven't used for prediction } // if we should predict // we return separately 1. "whether to redraw" and 2. "how many game-ticks elapsed" return std::pair<bool, int16>(didPredict || theElapsedTime != 0, theElapsedTime); }