Index: simutrans/trunk/network/network_cmd.h =================================================================== --- simutrans/trunk/network/network_cmd.h (revision 8342) +++ simutrans/trunk/network/network_cmd.h (working copy) @@ -30,6 +30,7 @@ NWC_CHG_PLAYER, NWC_SCENARIO, NWC_SCENARIO_RULES, + NWC_STEP, NWC_COUNT }; Index: simutrans/trunk/network/network_cmd_ingame.cc =================================================================== --- simutrans/trunk/network/network_cmd_ingame.cc (revision 8342) +++ simutrans/trunk/network/network_cmd_ingame.cc (working copy) @@ -50,6 +50,7 @@ case NWC_SCENARIO: nwc = new nwc_scenario_t(); break; case NWC_SCENARIO_RULES: nwc = new nwc_scenario_rules_t(); break; + case NWC_STEP: nwc = new nwc_step_t(); break; default: dbg->warning("network_command_t::read_from_socket", "received unknown packet id %d", p->get_id()); } Index: simutrans/trunk/network/network_cmd_ingame.h =================================================================== --- simutrans/trunk/network/network_cmd_ingame.h (revision 8342) +++ simutrans/trunk/network/network_cmd_ingame.h (working copy) @@ -357,4 +357,18 @@ static bool cmp_default_param(const char *d1, const char *d2); }; +/** +* nwc_step_t +* @from-server: +* @data contains the current sync_steps of the server +* defining the maximum sync_steps a client can advance to. +*/ +class nwc_step_t : public network_world_command_t { +public: + nwc_step_t() : network_world_command_t(NWC_STEP, 0, 0) { } + nwc_step_t(uint32 sync_steps, uint32 map_counter) : network_world_command_t(NWC_STEP, sync_steps, map_counter) {}; + virtual bool execute(karte_t *) { return true;} + virtual const char* get_name() { return "nwc_step_t"; } +}; + #endif Index: simutrans/trunk/simworld.cc =================================================================== --- simutrans/trunk/simworld.cc (revision 8342) +++ simutrans/trunk/simworld.cc (working copy) @@ -1247,6 +1247,7 @@ steps = 0; network_frame_count = 0; sync_steps = 0; + sync_steps_barrier = sync_steps; map_counter = 0; recalc_average_speed(); // resets timeline koord::locality_factor = settings.get_locality_factor( last_year ); @@ -2001,6 +2002,7 @@ idle_time = 0; network_frame_count = 0; sync_steps = 0; + sync_steps_barrier = sync_steps; for( uint i=0; iwarning("karte_t::network_game_set_pause", "steps=%d sync_steps=%d pause=%d", steps, sync_steps, pause_); @@ -6385,6 +6389,14 @@ *ms_difference = timediff; } } + } else if( nwc->get_id() == NWC_STEP ) { + // advancing sync_steps_barrier + nwc_step_t* nwstep = (nwc_step_t*)nwc; + + uint32 const ssbarrier = nwstep->get_sync_step(); + if( sync_steps_barrier < ssbarrier ) { + sync_steps_barrier = ssbarrier; + } } // check random number generator states @@ -6525,6 +6537,7 @@ finish_loop = false; sync_steps = 0; + sync_steps_barrier = sync_steps; network_frame_count = 0; vector_tplhashes_ok; // bit set: this client can do something with this player @@ -6607,7 +6620,8 @@ // time for the next step? uint32 time = dr_time(); if( (sint32)next_step_time - (sint32)time <= 0 ) { - if( step_mode&PAUSE_FLAG ) { + if( step_mode&PAUSE_FLAG || + (env_t::networkmode && !env_t::server && sync_steps >= sync_steps_barrier) ) { // only update display sync_step( 0, false, true ); idle_time = 100; @@ -6635,6 +6649,7 @@ ms_difference -= nst_diff; } + sync_step( (fix_ratio_frame_time*time_multiplier)/16, true, true ); if (++network_frame_count == settings.get_frames_per_step()) { // ever fourth frame @@ -6647,6 +6662,10 @@ LCHKLST(sync_steps) = checklist_t(get_random_seed(), halthandle_t::get_next_check(), linehandle_t::get_next_check(), convoihandle_t::get_next_check()); // some server side tasks if( env_t::networkmode && env_t::server ) { + // broadcast step + nwc_step_t* nwcstep = new nwc_step_t(sync_steps, map_counter); + network_send_all(nwcstep, true); + // broadcast sync info regularly and when lagged const sint64 timelag = (sint32)dr_time() - (sint32)next_step_time; if( (network_frame_count == 0 && timelag > fix_ratio_frame_time * settings.get_server_frames_ahead() / 2) || (sync_steps % env_t::server_sync_steps_between_checks) == 0 ) { Index: simutrans/trunk/simworld.h =================================================================== --- simutrans/trunk/simworld.h (revision 8342) +++ simutrans/trunk/simworld.h (working copy) @@ -488,6 +488,9 @@ /// @note variable used in interactive() uint32 sync_steps; + + // The maximum sync_steps that a client can safely advance to. + uint32 sync_steps_barrier; #define LAST_CHECKLISTS_COUNT 64 /// @note variable used in interactive() checklist_t last_checklists[LAST_CHECKLISTS_COUNT];