@@ -354,6 +354,7 @@ ServerEnvironment::ServerEnvironment(ServerMap *map,
354
354
m_active_block_interval_overload_skip(0 ),
355
355
m_game_time(0 ),
356
356
m_game_time_fraction_counter(0 ),
357
+ m_last_clear_objects_time(0 ),
357
358
m_recommended_send_interval(0.1 ),
358
359
m_max_lag_estimate(0.1 )
359
360
{
@@ -503,6 +504,7 @@ void ServerEnvironment::saveMeta()
503
504
Settings args;
504
505
args.setU64 (" game_time" , m_game_time);
505
506
args.setU64 (" time_of_day" , getTimeOfDay ());
507
+ args.setU64 (" last_clear_objects_time" , m_last_clear_objects_time);
506
508
args.writeLines (ss);
507
509
ss<<" EnvArgsEnd\n " ;
508
510
@@ -546,6 +548,13 @@ void ServerEnvironment::loadMeta()
546
548
// This is not as important
547
549
setTimeOfDay (9000 );
548
550
}
551
+
552
+ try {
553
+ m_last_clear_objects_time = args.getU64 (" last_clear_objects_time" );
554
+ } catch (SettingNotFoundException &e) {
555
+ // If missing, do as if clearObjects was never called
556
+ m_last_clear_objects_time = 0 ;
557
+ }
549
558
}
550
559
551
560
struct ActiveABM
@@ -739,13 +748,19 @@ void ServerEnvironment::activateBlock(MapBlock *block, u32 additional_dtime)
739
748
// Get time difference
740
749
u32 dtime_s = 0 ;
741
750
u32 stamp = block->getTimestamp ();
742
- if (m_game_time > stamp && stamp != BLOCK_TIMESTAMP_UNDEFINED)
743
- dtime_s = m_game_time - block-> getTimestamp () ;
751
+ if (m_game_time > stamp && stamp != BLOCK_TIMESTAMP_UNDEFINED)
752
+ dtime_s = m_game_time - stamp ;
744
753
dtime_s += additional_dtime;
745
754
746
755
/* infostream<<"ServerEnvironment::activateBlock(): block timestamp: "
747
756
<<stamp<<", game time: "<<m_game_time<<std::endl;*/
748
757
758
+ // Remove stored static objects if clearObjects was called since block's timestamp
759
+ if (stamp == BLOCK_TIMESTAMP_UNDEFINED || stamp < m_last_clear_objects_time) {
760
+ block->m_static_objects .m_stored .clear ();
761
+ // do not set changed flag to avoid unnecessary mapblock writes
762
+ }
763
+
749
764
// Set current time as timestamp
750
765
block->setTimestampNoChangedFlag (m_game_time);
751
766
@@ -858,30 +873,30 @@ void ServerEnvironment::getObjectsInsideRadius(std::vector<u16> &objects, v3f po
858
873
}
859
874
}
860
875
861
- void ServerEnvironment::clearAllObjects ( )
876
+ void ServerEnvironment::clearObjects (ClearObjectsMode mode )
862
877
{
863
- infostream<< " ServerEnvironment::clearAllObjects (): "
864
- << " Removing all active objects" << std::endl;
878
+ infostream << " ServerEnvironment::clearObjects (): "
879
+ << " Removing all active objects" << std::endl;
865
880
std::vector<u16> objects_to_remove;
866
- for (std::map<u16, ServerActiveObject*>::iterator
881
+ for (std::map<u16, ServerActiveObject*>::iterator
867
882
i = m_active_objects.begin ();
868
883
i != m_active_objects.end (); ++i) {
869
884
ServerActiveObject* obj = i->second ;
870
- if (obj->getType () == ACTIVEOBJECT_TYPE_PLAYER)
885
+ if (obj->getType () == ACTIVEOBJECT_TYPE_PLAYER)
871
886
continue ;
872
887
u16 id = i->first ;
873
888
// Delete static object if block is loaded
874
- if (obj->m_static_exists ){
889
+ if (obj->m_static_exists ) {
875
890
MapBlock *block = m_map->getBlockNoCreateNoEx (obj->m_static_block );
876
- if (block){
891
+ if (block) {
877
892
block->m_static_objects .remove (id);
878
893
block->raiseModified (MOD_STATE_WRITE_NEEDED,
879
894
MOD_REASON_CLEAR_ALL_OBJECTS);
880
895
obj->m_static_exists = false ;
881
896
}
882
897
}
883
898
// If known by some client, don't delete immediately
884
- if (obj->m_known_by_count > 0 ){
899
+ if (obj->m_known_by_count > 0 ) {
885
900
obj->m_pending_deactivation = true ;
886
901
obj->m_removed = true ;
887
902
continue ;
@@ -893,39 +908,46 @@ void ServerEnvironment::clearAllObjects()
893
908
m_script->removeObjectReference (obj);
894
909
895
910
// Delete active object
896
- if (obj->environmentDeletes ())
911
+ if (obj->environmentDeletes ())
897
912
delete obj;
898
913
// Id to be removed from m_active_objects
899
914
objects_to_remove.push_back (id);
900
915
}
901
916
902
917
// Remove references from m_active_objects
903
- for (std::vector<u16>::iterator i = objects_to_remove.begin ();
918
+ for (std::vector<u16>::iterator i = objects_to_remove.begin ();
904
919
i != objects_to_remove.end (); ++i) {
905
920
m_active_objects.erase (*i);
906
921
}
907
922
908
923
// Get list of loaded blocks
909
924
std::vector<v3s16> loaded_blocks;
910
- infostream<< " ServerEnvironment::clearAllObjects (): "
911
- << " Listing all loaded blocks" << std::endl;
925
+ infostream << " ServerEnvironment::clearObjects (): "
926
+ << " Listing all loaded blocks" << std::endl;
912
927
m_map->listAllLoadedBlocks (loaded_blocks);
913
- infostream<< " ServerEnvironment::clearAllObjects (): "
914
- << " Done listing all loaded blocks: "
915
- << loaded_blocks.size ()<<std::endl;
928
+ infostream << " ServerEnvironment::clearObjects (): "
929
+ << " Done listing all loaded blocks: "
930
+ << loaded_blocks.size ()<<std::endl;
916
931
917
932
// Get list of loadable blocks
918
933
std::vector<v3s16> loadable_blocks;
919
- infostream<<" ServerEnvironment::clearAllObjects(): "
920
- <<" Listing all loadable blocks" <<std::endl;
921
- m_map->listAllLoadableBlocks (loadable_blocks);
922
- infostream<<" ServerEnvironment::clearAllObjects(): "
923
- <<" Done listing all loadable blocks: "
924
- <<loadable_blocks.size ()
925
- <<" , now clearing" <<std::endl;
934
+ if (mode == CLEAR_OBJECTS_MODE_FULL) {
935
+ infostream << " ServerEnvironment::clearObjects(): "
936
+ << " Listing all loadable blocks" << std::endl;
937
+ m_map->listAllLoadableBlocks (loadable_blocks);
938
+ infostream << " ServerEnvironment::clearObjects(): "
939
+ << " Done listing all loadable blocks: "
940
+ << loadable_blocks.size () << std::endl;
941
+ } else {
942
+ loadable_blocks = loaded_blocks;
943
+ }
944
+
945
+ infostream << " ServerEnvironment::clearObjects(): "
946
+ << " Now clearing objects in " << loadable_blocks.size ()
947
+ << " blocks" << std::endl;
926
948
927
949
// Grab a reference on each loaded block to avoid unloading it
928
- for (std::vector<v3s16>::iterator i = loaded_blocks.begin ();
950
+ for (std::vector<v3s16>::iterator i = loaded_blocks.begin ();
929
951
i != loaded_blocks.end (); ++i) {
930
952
v3s16 p = *i;
931
953
MapBlock *block = m_map->getBlockNoCreateNoEx (p);
@@ -934,24 +956,27 @@ void ServerEnvironment::clearAllObjects()
934
956
}
935
957
936
958
// Remove objects in all loadable blocks
937
- u32 unload_interval = g_settings->getS32 (" max_clearobjects_extra_loaded_blocks" );
938
- unload_interval = MYMAX (unload_interval, 1 );
959
+ u32 unload_interval = U32_MAX;
960
+ if (mode == CLEAR_OBJECTS_MODE_FULL) {
961
+ unload_interval = g_settings->getS32 (" max_clearobjects_extra_loaded_blocks" );
962
+ unload_interval = MYMAX (unload_interval, 1 );
963
+ }
939
964
u32 report_interval = loadable_blocks.size () / 10 ;
940
965
u32 num_blocks_checked = 0 ;
941
966
u32 num_blocks_cleared = 0 ;
942
967
u32 num_objs_cleared = 0 ;
943
- for (std::vector<v3s16>::iterator i = loadable_blocks.begin ();
968
+ for (std::vector<v3s16>::iterator i = loadable_blocks.begin ();
944
969
i != loadable_blocks.end (); ++i) {
945
970
v3s16 p = *i;
946
971
MapBlock *block = m_map->emergeBlock (p, false );
947
- if (!block){
948
- errorstream<< " ServerEnvironment::clearAllObjects (): "
949
- << " Failed to emerge block " << PP (p)<< std::endl;
972
+ if (!block) {
973
+ errorstream << " ServerEnvironment::clearObjects (): "
974
+ << " Failed to emerge block " << PP (p) << std::endl;
950
975
continue ;
951
976
}
952
977
u32 num_stored = block->m_static_objects .m_stored .size ();
953
978
u32 num_active = block->m_static_objects .m_active .size ();
954
- if (num_stored != 0 || num_active != 0 ){
979
+ if (num_stored != 0 || num_active != 0 ) {
955
980
block->m_static_objects .m_stored .clear ();
956
981
block->m_static_objects .m_active .clear ();
957
982
block->raiseModified (MOD_STATE_WRITE_NEEDED,
@@ -961,33 +986,35 @@ void ServerEnvironment::clearAllObjects()
961
986
}
962
987
num_blocks_checked++;
963
988
964
- if (report_interval != 0 &&
965
- num_blocks_checked % report_interval == 0 ){
989
+ if (report_interval != 0 &&
990
+ num_blocks_checked % report_interval == 0 ) {
966
991
float percent = 100.0 * (float )num_blocks_checked /
967
- loadable_blocks.size ();
968
- infostream<< " ServerEnvironment::clearAllObjects (): "
969
- << " Cleared " << num_objs_cleared<< " objects"
970
- << " in " << num_blocks_cleared<< " blocks ("
971
- << percent<< " %)" << std::endl;
992
+ loadable_blocks.size ();
993
+ infostream << " ServerEnvironment::clearObjects (): "
994
+ << " Cleared " << num_objs_cleared << " objects"
995
+ << " in " << num_blocks_cleared << " blocks ("
996
+ << percent << " %)" << std::endl;
972
997
}
973
- if (num_blocks_checked % unload_interval == 0 ){
998
+ if (num_blocks_checked % unload_interval == 0 ) {
974
999
m_map->unloadUnreferencedBlocks ();
975
1000
}
976
1001
}
977
1002
m_map->unloadUnreferencedBlocks ();
978
1003
979
1004
// Drop references that were added above
980
- for (std::vector<v3s16>::iterator i = loaded_blocks.begin ();
1005
+ for (std::vector<v3s16>::iterator i = loaded_blocks.begin ();
981
1006
i != loaded_blocks.end (); ++i) {
982
1007
v3s16 p = *i;
983
1008
MapBlock *block = m_map->getBlockNoCreateNoEx (p);
984
1009
assert (block);
985
1010
block->refDrop ();
986
1011
}
987
1012
988
- infostream<<" ServerEnvironment::clearAllObjects(): "
989
- <<" Finished: Cleared " <<num_objs_cleared<<" objects"
990
- <<" in " <<num_blocks_cleared<<" blocks" <<std::endl;
1013
+ m_last_clear_objects_time = m_game_time;
1014
+
1015
+ infostream << " ServerEnvironment::clearObjects(): "
1016
+ << " Finished: Cleared " << num_objs_cleared << " objects"
1017
+ << " in " << num_blocks_cleared << " blocks" << std::endl;
991
1018
}
992
1019
993
1020
void ServerEnvironment::step (float dtime)
0 commit comments