mirror of
https://github.com/minetest/minetest.git
synced 2024-11-27 01:53:45 +01:00
map unloading is now a whole lot better
This commit is contained in:
parent
3fccc67eb7
commit
dd22ea051a
@ -9,6 +9,10 @@
|
|||||||
#
|
#
|
||||||
# Further documentation:
|
# Further documentation:
|
||||||
# http://celeron.55.lt/~celeron55/minetest/wiki/doku.php
|
# http://celeron.55.lt/~celeron55/minetest/wiki/doku.php
|
||||||
|
#
|
||||||
|
# NOTE: This file might not be up-to-date, refer to the
|
||||||
|
# defaultsettings.cpp file for an up-to-date list:
|
||||||
|
# https://bitbucket.org/celeron55/minetest/src/tip/src/defaultsettings.cpp
|
||||||
|
|
||||||
#
|
#
|
||||||
# Client side stuff
|
# Client side stuff
|
||||||
@ -92,7 +96,7 @@
|
|||||||
#random_input = false
|
#random_input = false
|
||||||
|
|
||||||
# Timeout for client to remove unused map data from memory
|
# Timeout for client to remove unused map data from memory
|
||||||
#client_delete_unused_sectors_timeout = 1200
|
#client_unload_unused_data_timeout = 1200
|
||||||
|
|
||||||
#
|
#
|
||||||
# Server side stuff
|
# Server side stuff
|
||||||
@ -140,6 +144,6 @@
|
|||||||
#time_speed = 1440
|
#time_speed = 1440
|
||||||
|
|
||||||
#time_send_interval = 5
|
#time_send_interval = 5
|
||||||
#server_unload_unused_sectors_timeout = 60
|
#server_unload_unused_data_timeout = 60
|
||||||
#server_map_save_interval = 60
|
#server_map_save_interval = 60
|
||||||
|
|
||||||
|
@ -199,7 +199,7 @@ Client::Client(
|
|||||||
m_access_denied(false)
|
m_access_denied(false)
|
||||||
{
|
{
|
||||||
m_packetcounter_timer = 0.0;
|
m_packetcounter_timer = 0.0;
|
||||||
m_delete_unused_sectors_timer = 0.0;
|
//m_delete_unused_sectors_timer = 0.0;
|
||||||
m_connection_reinit_timer = 0.0;
|
m_connection_reinit_timer = 0.0;
|
||||||
m_avg_rtt_timer = 0.0;
|
m_avg_rtt_timer = 0.0;
|
||||||
m_playerpos_send_timer = 0.0;
|
m_playerpos_send_timer = 0.0;
|
||||||
@ -303,7 +303,11 @@ void Client::step(float dtime)
|
|||||||
m_packetcounter.clear();
|
m_packetcounter.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get connection status
|
||||||
|
bool connected = connectedAndInitialized();
|
||||||
|
|
||||||
|
#if 0
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Delete unused sectors
|
Delete unused sectors
|
||||||
@ -324,8 +328,7 @@ void Client::step(float dtime)
|
|||||||
|
|
||||||
core::list<v3s16> deleted_blocks;
|
core::list<v3s16> deleted_blocks;
|
||||||
|
|
||||||
float delete_unused_sectors_timeout =
|
g_settings.getFloat("client_unload_unused_data_timeout");
|
||||||
g_settings.getFloat("client_delete_unused_sectors_timeout");
|
|
||||||
|
|
||||||
// Delete sector blocks
|
// Delete sector blocks
|
||||||
/*u32 num = m_env.getMap().unloadUnusedData
|
/*u32 num = m_env.getMap().unloadUnusedData
|
||||||
@ -392,8 +395,7 @@ void Client::step(float dtime)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
bool connected = connectedAndInitialized();
|
|
||||||
|
|
||||||
if(connected == false)
|
if(connected == false)
|
||||||
{
|
{
|
||||||
@ -438,6 +440,67 @@ void Client::step(float dtime)
|
|||||||
Do stuff if connected
|
Do stuff if connected
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Run Map's timers and unload unused data
|
||||||
|
*/
|
||||||
|
const float map_timer_and_unload_dtime = 5.25;
|
||||||
|
if(m_map_timer_and_unload_interval.step(dtime, map_timer_and_unload_dtime))
|
||||||
|
{
|
||||||
|
ScopeProfiler sp(&g_profiler, "Client: map timer and unload");
|
||||||
|
core::list<v3s16> deleted_blocks;
|
||||||
|
m_env.getMap().timerUpdate(map_timer_and_unload_dtime,
|
||||||
|
g_settings.getFloat("client_unload_unused_data_timeout"),
|
||||||
|
&deleted_blocks);
|
||||||
|
|
||||||
|
/*if(deleted_blocks.size() > 0)
|
||||||
|
dstream<<"Client: Unloaded "<<deleted_blocks.size()
|
||||||
|
<<" unused blocks"<<std::endl;*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Send info to server
|
||||||
|
NOTE: This loop is intentionally iterated the way it is.
|
||||||
|
*/
|
||||||
|
|
||||||
|
core::list<v3s16>::Iterator i = deleted_blocks.begin();
|
||||||
|
core::list<v3s16> sendlist;
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
if(sendlist.size() == 255 || i == deleted_blocks.end())
|
||||||
|
{
|
||||||
|
if(sendlist.size() == 0)
|
||||||
|
break;
|
||||||
|
/*
|
||||||
|
[0] u16 command
|
||||||
|
[2] u8 count
|
||||||
|
[3] v3s16 pos_0
|
||||||
|
[3+6] v3s16 pos_1
|
||||||
|
...
|
||||||
|
*/
|
||||||
|
u32 replysize = 2+1+6*sendlist.size();
|
||||||
|
SharedBuffer<u8> reply(replysize);
|
||||||
|
writeU16(&reply[0], TOSERVER_DELETEDBLOCKS);
|
||||||
|
reply[2] = sendlist.size();
|
||||||
|
u32 k = 0;
|
||||||
|
for(core::list<v3s16>::Iterator
|
||||||
|
j = sendlist.begin();
|
||||||
|
j != sendlist.end(); j++)
|
||||||
|
{
|
||||||
|
writeV3S16(&reply[2+1+6*k], *j);
|
||||||
|
k++;
|
||||||
|
}
|
||||||
|
m_con.Send(PEER_ID_SERVER, 1, reply, true);
|
||||||
|
|
||||||
|
if(i == deleted_blocks.end())
|
||||||
|
break;
|
||||||
|
|
||||||
|
sendlist.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
sendlist.push_back(*i);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Handle environment
|
Handle environment
|
||||||
*/
|
*/
|
||||||
@ -453,23 +516,23 @@ void Client::step(float dtime)
|
|||||||
//TimeTaker envtimer("env step", m_device);
|
//TimeTaker envtimer("env step", m_device);
|
||||||
// Step environment
|
// Step environment
|
||||||
m_env.step(dtime);
|
m_env.step(dtime);
|
||||||
|
|
||||||
// Step active blocks
|
/*
|
||||||
|
Handle active blocks
|
||||||
|
NOTE: These old objects are DEPRECATED. TODO: Remove
|
||||||
|
*/
|
||||||
for(core::map<v3s16, bool>::Iterator
|
for(core::map<v3s16, bool>::Iterator
|
||||||
i = m_active_blocks.getIterator();
|
i = m_active_blocks.getIterator();
|
||||||
i.atEnd() == false; i++)
|
i.atEnd() == false; i++)
|
||||||
{
|
{
|
||||||
v3s16 p = i.getNode()->getKey();
|
v3s16 p = i.getNode()->getKey();
|
||||||
|
|
||||||
MapBlock *block = NULL;
|
MapBlock *block = m_env.getMap().getBlockNoCreateNoEx(p);
|
||||||
try
|
if(block == NULL)
|
||||||
{
|
continue;
|
||||||
block = m_env.getMap().getBlockNoCreate(p);
|
|
||||||
block->stepObjects(dtime, false, m_env.getDayNightRatio());
|
// Step MapBlockObjects
|
||||||
}
|
block->stepObjects(dtime, false, m_env.getDayNightRatio());
|
||||||
catch(InvalidPositionException &e)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1183,6 +1246,7 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
Read block objects
|
Read block objects
|
||||||
|
NOTE: Deprecated stuff here, TODO: Remove
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Read active block count
|
// Read active block count
|
||||||
|
@ -28,6 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "jmutex.h"
|
#include "jmutex.h"
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
#include "clientobject.h"
|
#include "clientobject.h"
|
||||||
|
#include "utility.h" // For IntervalLimiter
|
||||||
|
|
||||||
struct MeshMakeData;
|
struct MeshMakeData;
|
||||||
|
|
||||||
@ -306,11 +307,11 @@ private:
|
|||||||
void sendPlayerInfo();
|
void sendPlayerInfo();
|
||||||
|
|
||||||
float m_packetcounter_timer;
|
float m_packetcounter_timer;
|
||||||
float m_delete_unused_sectors_timer;
|
|
||||||
float m_connection_reinit_timer;
|
float m_connection_reinit_timer;
|
||||||
float m_avg_rtt_timer;
|
float m_avg_rtt_timer;
|
||||||
float m_playerpos_send_timer;
|
float m_playerpos_send_timer;
|
||||||
float m_ignore_damage_timer; // Used after server moves player
|
float m_ignore_damage_timer; // Used after server moves player
|
||||||
|
IntervalLimiter m_map_timer_and_unload_interval;
|
||||||
|
|
||||||
MeshUpdateThread m_mesh_update_thread;
|
MeshUpdateThread m_mesh_update_thread;
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ enum ToClientCommand
|
|||||||
[0] u16 TOSERVER_INIT
|
[0] u16 TOSERVER_INIT
|
||||||
[2] u8 deployed version
|
[2] u8 deployed version
|
||||||
[3] v3s16 player's position + v3f(0,BS/2,0) floatToInt'd
|
[3] v3s16 player's position + v3f(0,BS/2,0) floatToInt'd
|
||||||
([4] u64 map seed (new as of 2011-02-27))
|
[12] u64 map seed (new as of 2011-02-27)
|
||||||
|
|
||||||
NOTE: The position in here is deprecated; position is
|
NOTE: The position in here is deprecated; position is
|
||||||
explicitly sent afterwards
|
explicitly sent afterwards
|
||||||
|
@ -56,7 +56,7 @@ void set_default_settings()
|
|||||||
g_settings.setDefault("screenH", "600");
|
g_settings.setDefault("screenH", "600");
|
||||||
g_settings.setDefault("address", "");
|
g_settings.setDefault("address", "");
|
||||||
g_settings.setDefault("random_input", "false");
|
g_settings.setDefault("random_input", "false");
|
||||||
g_settings.setDefault("client_delete_unused_sectors_timeout", "1200");
|
g_settings.setDefault("client_unload_unused_data_timeout", "1200");
|
||||||
g_settings.setDefault("enable_fog", "true");
|
g_settings.setDefault("enable_fog", "true");
|
||||||
g_settings.setDefault("new_style_water", "false");
|
g_settings.setDefault("new_style_water", "false");
|
||||||
g_settings.setDefault("new_style_leaves", "true");
|
g_settings.setDefault("new_style_leaves", "true");
|
||||||
@ -94,7 +94,7 @@ void set_default_settings()
|
|||||||
g_settings.setDefault("max_block_generate_distance", "8");
|
g_settings.setDefault("max_block_generate_distance", "8");
|
||||||
g_settings.setDefault("time_send_interval", "20");
|
g_settings.setDefault("time_send_interval", "20");
|
||||||
g_settings.setDefault("time_speed", "96");
|
g_settings.setDefault("time_speed", "96");
|
||||||
g_settings.setDefault("server_unload_unused_sectors_timeout", "60");
|
g_settings.setDefault("server_unload_unused_data_timeout", "60");
|
||||||
g_settings.setDefault("server_map_save_interval", "60");
|
g_settings.setDefault("server_map_save_interval", "60");
|
||||||
g_settings.setDefault("full_block_send_enable_min_time_from_building", "2.0");
|
g_settings.setDefault("full_block_send_enable_min_time_from_building", "2.0");
|
||||||
//g_settings.setDefault("dungeon_rarity", "0.025");
|
//g_settings.setDefault("dungeon_rarity", "0.025");
|
||||||
|
@ -660,14 +660,6 @@ void ServerEnvironment::step(float dtime)
|
|||||||
m_game_time_fraction_counter -= (float)inc_i;
|
m_game_time_fraction_counter -= (float)inc_i;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
Let map update it's timers
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
//TimeTaker timer("Server m_map->timerUpdate()");
|
|
||||||
m_map->timerUpdate(dtime);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Handle players
|
Handle players
|
||||||
*/
|
*/
|
||||||
@ -1469,11 +1461,6 @@ void ClientEnvironment::step(float dtime)
|
|||||||
bool free_move = g_settings.getBool("free_move");
|
bool free_move = g_settings.getBool("free_move");
|
||||||
bool footprints = g_settings.getBool("footprints");
|
bool footprints = g_settings.getBool("footprints");
|
||||||
|
|
||||||
{
|
|
||||||
//TimeTaker timer("Client m_map->timerUpdate()");
|
|
||||||
m_map->timerUpdate(dtime);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get local player
|
// Get local player
|
||||||
LocalPlayer *lplayer = getLocalPlayer();
|
LocalPlayer *lplayer = getLocalPlayer();
|
||||||
assert(lplayer);
|
assert(lplayer);
|
||||||
@ -1672,7 +1659,7 @@ void ClientEnvironment::step(float dtime)
|
|||||||
// Step object
|
// Step object
|
||||||
obj->step(dtime, this);
|
obj->step(dtime, this);
|
||||||
|
|
||||||
if(m_active_object_light_update_interval.step(dtime, 0.5))
|
if(m_active_object_light_update_interval.step(dtime, 0.21))
|
||||||
{
|
{
|
||||||
// Update lighting
|
// Update lighting
|
||||||
//u8 light = LIGHT_MAX;
|
//u8 light = LIGHT_MAX;
|
||||||
|
124
src/main.cpp
124
src/main.cpp
@ -27,6 +27,33 @@ NOTE: Global locale is now set at initialization
|
|||||||
NOTE: If VBO (EHM_STATIC) is used, remember to explicitly free the
|
NOTE: If VBO (EHM_STATIC) is used, remember to explicitly free the
|
||||||
hardware buffer (it is not freed automatically)
|
hardware buffer (it is not freed automatically)
|
||||||
|
|
||||||
|
NOTE: A random to-do list saved here as documentation:
|
||||||
|
A list of "active blocks" in which stuff happens. (+=done)
|
||||||
|
+ Add a never-resetted game timer to the server
|
||||||
|
+ Add a timestamp value to blocks
|
||||||
|
+ The simple rule: All blocks near some player are "active"
|
||||||
|
- Do stuff in real time in active blocks
|
||||||
|
+ Handle objects
|
||||||
|
- Grow grass, delete leaves without a tree
|
||||||
|
- Spawn some mobs based on some rules
|
||||||
|
- Transform cobble to mossy cobble near water
|
||||||
|
- Run a custom script
|
||||||
|
- ...And all kinds of other dynamic stuff
|
||||||
|
+ Keep track of when a block becomes active and becomes inactive
|
||||||
|
+ When a block goes inactive:
|
||||||
|
+ Store objects statically to block
|
||||||
|
+ Store timer value as the timestamp
|
||||||
|
+ When a block goes active:
|
||||||
|
+ Create active objects out of static objects
|
||||||
|
- Simulate the results of what would have happened if it would have
|
||||||
|
been active for all the time
|
||||||
|
- Grow a lot of grass and so on
|
||||||
|
+ Initially it is fine to send information about every active object
|
||||||
|
to every player. Eventually it should be modified to only send info
|
||||||
|
about the nearest ones.
|
||||||
|
+ This was left to be done by the old system and it sends only the
|
||||||
|
nearest ones.
|
||||||
|
|
||||||
Old, wild and random suggestions that probably won't be done:
|
Old, wild and random suggestions that probably won't be done:
|
||||||
-------------------------------------------------------------
|
-------------------------------------------------------------
|
||||||
|
|
||||||
@ -73,9 +100,6 @@ SUGG: Make the amount of blocks sending to client and the total
|
|||||||
SUGG: Meshes of blocks could be split into 6 meshes facing into
|
SUGG: Meshes of blocks could be split into 6 meshes facing into
|
||||||
different directions and then only those drawn that need to be
|
different directions and then only those drawn that need to be
|
||||||
|
|
||||||
SUGG: Calculate lighting per vertex to get a lighting effect like in
|
|
||||||
bartwe's game
|
|
||||||
|
|
||||||
SUGG: Background music based on cellular automata?
|
SUGG: Background music based on cellular automata?
|
||||||
http://www.earslap.com/projectslab/otomata
|
http://www.earslap.com/projectslab/otomata
|
||||||
|
|
||||||
@ -90,6 +114,8 @@ SUGG: Make a system for pregenerating quick information for mapblocks, so
|
|||||||
or even generated.
|
or even generated.
|
||||||
|
|
||||||
SUGG: Erosion simulation at map generation time
|
SUGG: Erosion simulation at map generation time
|
||||||
|
- This might be plausible if larger areas of map were pregenerated
|
||||||
|
without lighting (which is slow)
|
||||||
- Simulate water flows, which would carve out dirt fast and
|
- Simulate water flows, which would carve out dirt fast and
|
||||||
then turn stone into gravel and sand and relocate it.
|
then turn stone into gravel and sand and relocate it.
|
||||||
- How about relocating minerals, too? Coal and gold in
|
- How about relocating minerals, too? Coal and gold in
|
||||||
@ -231,6 +257,7 @@ FIXME: Server sometimes goes into some infinite PeerNotFoundException loop
|
|||||||
* Fix the problem with the server constantly saving one or a few
|
* Fix the problem with the server constantly saving one or a few
|
||||||
blocks? List the first saved block, maybe it explains.
|
blocks? List the first saved block, maybe it explains.
|
||||||
- It is probably caused by oscillating water
|
- It is probably caused by oscillating water
|
||||||
|
- TODO: Investigate if this still happens (this is a very old one)
|
||||||
* Make a small history check to transformLiquids to detect and log
|
* Make a small history check to transformLiquids to detect and log
|
||||||
continuous oscillations, in such detail that they can be fixed.
|
continuous oscillations, in such detail that they can be fixed.
|
||||||
|
|
||||||
@ -238,42 +265,12 @@ FIXME: The new optimized map sending doesn't sometimes send enough blocks
|
|||||||
from big caves and such
|
from big caves and such
|
||||||
FIXME: Block send distance configuration does not take effect for some reason
|
FIXME: Block send distance configuration does not take effect for some reason
|
||||||
|
|
||||||
SUGG: Map unloading based on sector reference is not very good, it keeps
|
|
||||||
unnecessary stuff in memory. I guess. Investigate this.
|
|
||||||
|
|
||||||
TODO: When block is placed and it has param_type==CPT_FACEDIR_SIMPLE, set
|
|
||||||
the direction accordingly.
|
|
||||||
|
|
||||||
Environment:
|
Environment:
|
||||||
------------
|
------------
|
||||||
|
|
||||||
TODO: A list of "active blocks" in which stuff happens. (+=done)
|
TODO: Add proper hooks to when adding and removing active blocks
|
||||||
+ Add a never-resetted game timer to the server
|
|
||||||
+ Add a timestamp value to blocks
|
TODO: Finish the ActiveBlockModifier stuff and use it for something
|
||||||
+ The simple rule: All blocks near some player are "active"
|
|
||||||
- Do stuff in real time in active blocks
|
|
||||||
+ Handle objects
|
|
||||||
TODO: Make proper hooks in here
|
|
||||||
- Grow grass, delete leaves without a tree
|
|
||||||
- Spawn some mobs based on some rules
|
|
||||||
- Transform cobble to mossy cobble near water
|
|
||||||
- Run a custom script
|
|
||||||
- ...And all kinds of other dynamic stuff
|
|
||||||
+ Keep track of when a block becomes active and becomes inactive
|
|
||||||
+ When a block goes inactive:
|
|
||||||
+ Store objects statically to block
|
|
||||||
+ Store timer value as the timestamp
|
|
||||||
+ When a block goes active:
|
|
||||||
+ Create active objects out of static objects
|
|
||||||
TODO: Make proper hooks in here
|
|
||||||
- Simulate the results of what would have happened if it would have
|
|
||||||
been active for all the time
|
|
||||||
- Grow a lot of grass and so on
|
|
||||||
+ Initially it is fine to send information about every active object
|
|
||||||
to every player. Eventually it should be modified to only send info
|
|
||||||
about the nearest ones.
|
|
||||||
+ This was left to be done by the old system and it sends only the
|
|
||||||
nearest ones.
|
|
||||||
|
|
||||||
Objects:
|
Objects:
|
||||||
--------
|
--------
|
||||||
@ -285,6 +282,7 @@ TODO: Get rid of MapBlockObjects and use only ActiveObjects
|
|||||||
|
|
||||||
SUGG: MovingObject::move and Player::move are basically the same.
|
SUGG: MovingObject::move and Player::move are basically the same.
|
||||||
combine them.
|
combine them.
|
||||||
|
- NOTE: This is a bit tricky because player has the sneaking ability
|
||||||
- NOTE: Player::move is more up-to-date.
|
- NOTE: Player::move is more up-to-date.
|
||||||
- NOTE: There is a simple move implementation now in collision.{h,cpp}
|
- NOTE: There is a simple move implementation now in collision.{h,cpp}
|
||||||
- NOTE: MovingObject will be deleted (MapBlockObject)
|
- NOTE: MovingObject will be deleted (MapBlockObject)
|
||||||
@ -303,42 +301,17 @@ TODO: Mineral and ground material properties
|
|||||||
TODO: Flowing water to actually contain flow direction information
|
TODO: Flowing water to actually contain flow direction information
|
||||||
- There is a space for this - it just has to be implemented.
|
- There is a space for this - it just has to be implemented.
|
||||||
|
|
||||||
SUGG: Try out the notch way of generating maps, that is, make bunches
|
|
||||||
of low-res 3d noise and interpolate linearly.
|
|
||||||
|
|
||||||
Mapgen v2 (the current one):
|
|
||||||
* Possibly add some kind of erosion and other stuff
|
|
||||||
* Better water generation (spread it to underwater caverns but don't
|
|
||||||
fill dungeons that don't touch big water masses)
|
|
||||||
* When generating a chunk and the neighboring chunk doesn't have mud
|
|
||||||
and stuff yet and the ground is fairly flat, the mud will flow to
|
|
||||||
the other chunk making nasty straight walls when the other chunk
|
|
||||||
is generated. Fix it. Maybe just a special case if the ground is
|
|
||||||
flat?
|
|
||||||
* Consider not updating this one and make a good mainly block-based
|
|
||||||
generator
|
|
||||||
|
|
||||||
SUGG: Make two "modified states", one that forces the block to be saved at
|
|
||||||
the next save event, and one that makes the block to be saved at exit
|
|
||||||
time.
|
|
||||||
|
|
||||||
TODO: Add a not_fully_generated flag to MapBlock, which would be set for
|
|
||||||
blocks that contain eg. trees from neighboring generations but haven't
|
|
||||||
been generated itself. This is required for the future generator.
|
|
||||||
|
|
||||||
Misc. stuff:
|
Misc. stuff:
|
||||||
------------
|
------------
|
||||||
- Make sure server handles removing grass when a block is placed (etc)
|
TODO: Make sure server handles removing grass when a block is placed (etc)
|
||||||
- The client should not do it by itself
|
- The client should not do it by itself
|
||||||
- Block cube placement around player's head
|
- NOTE: I think nobody does it currently...
|
||||||
- Protocol version field
|
TODO: Block cube placement around player's head
|
||||||
- Consider getting some textures from cisoun's texture pack
|
TODO: Protocol version field
|
||||||
- Ask from Cisoun
|
TODO: Think about using same bits for material for fences and doors, for
|
||||||
- Make sure the fence implementation and data format is good
|
example
|
||||||
- Think about using same bits for material for fences and doors, for
|
TODO: Move mineral to param2, increment map serialization version, add
|
||||||
example
|
conversion
|
||||||
- Finish the ActiveBlockModifier stuff and use it for something
|
|
||||||
- Move mineral to param2, increment map serialization version, add conversion
|
|
||||||
|
|
||||||
TODO: Add a per-sector database to store surface stuff as simple flags/values
|
TODO: Add a per-sector database to store surface stuff as simple flags/values
|
||||||
- Light?
|
- Light?
|
||||||
@ -354,8 +327,6 @@ TODO: Restart irrlicht completely when coming back to main menu from game.
|
|||||||
|
|
||||||
TODO: Merge bahamada's audio stuff (clean patch available)
|
TODO: Merge bahamada's audio stuff (clean patch available)
|
||||||
|
|
||||||
TODO: Merge spongie's chest/furnace direction (by hand)
|
|
||||||
|
|
||||||
TODO: Merge key configuration menu (no clean patch available)
|
TODO: Merge key configuration menu (no clean patch available)
|
||||||
|
|
||||||
Making it more portable:
|
Making it more portable:
|
||||||
@ -373,9 +344,6 @@ Stuff to do after release:
|
|||||||
Doing currently:
|
Doing currently:
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
TODO: Use MapBlock::resetUsageTimer() in appropriate places
|
|
||||||
(on client and server)
|
|
||||||
|
|
||||||
======================================================================
|
======================================================================
|
||||||
|
|
||||||
*/
|
*/
|
||||||
@ -404,16 +372,12 @@ TODO: Use MapBlock::resetUsageTimer() in appropriate places
|
|||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
//#include <jmutexautolock.h>
|
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "common_irrlicht.h"
|
#include "common_irrlicht.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
//#include "map.h"
|
|
||||||
//#include "player.h"
|
|
||||||
#include "test.h"
|
#include "test.h"
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
//#include "client.h"
|
|
||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
#include "porting.h"
|
#include "porting.h"
|
||||||
#include "gettime.h"
|
#include "gettime.h"
|
||||||
@ -422,8 +386,6 @@ TODO: Use MapBlock::resetUsageTimer() in appropriate places
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "guiMainMenu.h"
|
#include "guiMainMenu.h"
|
||||||
#include "mineral.h"
|
#include "mineral.h"
|
||||||
//#include "noise.h"
|
|
||||||
//#include "tile.h"
|
|
||||||
#include "materials.h"
|
#include "materials.h"
|
||||||
#include "game.h"
|
#include "game.h"
|
||||||
#include "keycode.h"
|
#include "keycode.h"
|
||||||
|
99
src/map.cpp
99
src/map.cpp
@ -1386,8 +1386,15 @@ bool Map::dayNightDiffed(v3s16 blockpos)
|
|||||||
/*
|
/*
|
||||||
Updates usage timers
|
Updates usage timers
|
||||||
*/
|
*/
|
||||||
void Map::timerUpdate(float dtime)
|
void Map::timerUpdate(float dtime, float unload_timeout,
|
||||||
|
core::list<v3s16> *unloaded_blocks)
|
||||||
{
|
{
|
||||||
|
bool save_before_unloading = (mapType() == MAPTYPE_SERVER);
|
||||||
|
|
||||||
|
core::list<v2s16> sector_deletion_queue;
|
||||||
|
u32 deleted_blocks_count = 0;
|
||||||
|
u32 saved_blocks_count = 0;
|
||||||
|
|
||||||
core::map<v2s16, MapSector*>::Iterator si;
|
core::map<v2s16, MapSector*>::Iterator si;
|
||||||
|
|
||||||
si = m_sectors.getIterator();
|
si = m_sectors.getIterator();
|
||||||
@ -1395,13 +1402,60 @@ void Map::timerUpdate(float dtime)
|
|||||||
{
|
{
|
||||||
MapSector *sector = si.getNode()->getValue();
|
MapSector *sector = si.getNode()->getValue();
|
||||||
|
|
||||||
|
bool all_blocks_deleted = true;
|
||||||
|
|
||||||
core::list<MapBlock*> blocks;
|
core::list<MapBlock*> blocks;
|
||||||
sector->getBlocks(blocks);
|
sector->getBlocks(blocks);
|
||||||
for(core::list<MapBlock*>::Iterator i = blocks.begin();
|
for(core::list<MapBlock*>::Iterator i = blocks.begin();
|
||||||
i != blocks.end(); i++)
|
i != blocks.end(); i++)
|
||||||
{
|
{
|
||||||
(*i)->incrementUsageTimer(dtime);
|
MapBlock *block = (*i);
|
||||||
|
|
||||||
|
block->incrementUsageTimer(dtime);
|
||||||
|
|
||||||
|
if(block->getUsageTimer() > unload_timeout)
|
||||||
|
{
|
||||||
|
v3s16 p = block->getPos();
|
||||||
|
|
||||||
|
// Save if modified
|
||||||
|
if(block->getModified() != MOD_STATE_CLEAN
|
||||||
|
&& save_before_unloading)
|
||||||
|
{
|
||||||
|
saveBlock(block);
|
||||||
|
saved_blocks_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete from memory
|
||||||
|
sector->deleteBlock(block);
|
||||||
|
|
||||||
|
if(unloaded_blocks)
|
||||||
|
unloaded_blocks->push_back(p);
|
||||||
|
|
||||||
|
deleted_blocks_count++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
all_blocks_deleted = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(all_blocks_deleted)
|
||||||
|
{
|
||||||
|
sector_deletion_queue.push_back(si.getNode()->getKey());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finally delete the empty sectors
|
||||||
|
deleteSectors(sector_deletion_queue);
|
||||||
|
|
||||||
|
if(deleted_blocks_count != 0)
|
||||||
|
{
|
||||||
|
PrintInfo(dstream); // ServerMap/ClientMap:
|
||||||
|
dstream<<"Unloaded "<<deleted_blocks_count
|
||||||
|
<<" blocks from memory";
|
||||||
|
if(save_before_unloading)
|
||||||
|
dstream<<", of which "<<saved_blocks_count<<" were written";
|
||||||
|
dstream<<"."<<std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1420,6 +1474,7 @@ void Map::deleteSectors(core::list<v2s16> &list)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
void Map::unloadUnusedData(float timeout,
|
void Map::unloadUnusedData(float timeout,
|
||||||
core::list<v3s16> *deleted_blocks)
|
core::list<v3s16> *deleted_blocks)
|
||||||
{
|
{
|
||||||
@ -1474,6 +1529,7 @@ void Map::unloadUnusedData(float timeout,
|
|||||||
//return sector_deletion_queue.getSize();
|
//return sector_deletion_queue.getSize();
|
||||||
//return deleted_blocks_count;
|
//return deleted_blocks_count;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void Map::PrintInfo(std::ostream &out)
|
void Map::PrintInfo(std::ostream &out)
|
||||||
{
|
{
|
||||||
@ -1500,7 +1556,7 @@ void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks)
|
|||||||
*/
|
*/
|
||||||
v3s16 p0 = m_transforming_liquid.pop_front();
|
v3s16 p0 = m_transforming_liquid.pop_front();
|
||||||
|
|
||||||
MapNode n0 = getNode(p0);
|
MapNode n0 = getNodeNoEx(p0);
|
||||||
|
|
||||||
// Don't deal with non-liquids
|
// Don't deal with non-liquids
|
||||||
if(content_liquid(n0.d) == false)
|
if(content_liquid(n0.d) == false)
|
||||||
@ -1532,13 +1588,10 @@ void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks)
|
|||||||
};
|
};
|
||||||
for(u16 i=0; i<5; i++)
|
for(u16 i=0; i<5; i++)
|
||||||
{
|
{
|
||||||
try
|
|
||||||
{
|
|
||||||
|
|
||||||
bool from_top = (i==0);
|
bool from_top = (i==0);
|
||||||
|
|
||||||
v3s16 p2 = p0 + dirs_from[i];
|
v3s16 p2 = p0 + dirs_from[i];
|
||||||
MapNode n2 = getNode(p2);
|
MapNode n2 = getNodeNoEx(p2);
|
||||||
|
|
||||||
if(content_liquid(n2.d))
|
if(content_liquid(n2.d))
|
||||||
{
|
{
|
||||||
@ -1572,10 +1625,6 @@ void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks)
|
|||||||
if(new_liquid_level > new_liquid_level_max)
|
if(new_liquid_level > new_liquid_level_max)
|
||||||
new_liquid_level_max = new_liquid_level;
|
new_liquid_level_max = new_liquid_level;
|
||||||
}
|
}
|
||||||
|
|
||||||
}catch(InvalidPositionException &e)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
} //for
|
} //for
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1618,20 +1667,13 @@ void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks)
|
|||||||
};
|
};
|
||||||
for(u16 i=0; i<6; i++)
|
for(u16 i=0; i<6; i++)
|
||||||
{
|
{
|
||||||
try
|
|
||||||
{
|
|
||||||
|
|
||||||
v3s16 p2 = p0 + dirs[i];
|
v3s16 p2 = p0 + dirs[i];
|
||||||
|
|
||||||
MapNode n2 = getNode(p2);
|
MapNode n2 = getNodeNoEx(p2);
|
||||||
if(content_flowing_liquid(n2.d))
|
if(content_flowing_liquid(n2.d))
|
||||||
{
|
{
|
||||||
m_transforming_liquid.push_back(p2);
|
m_transforming_liquid.push_back(p2);
|
||||||
}
|
}
|
||||||
|
|
||||||
}catch(InvalidPositionException &e)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1652,9 +1694,6 @@ void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks)
|
|||||||
};
|
};
|
||||||
for(u16 i=0; i<5; i++)
|
for(u16 i=0; i<5; i++)
|
||||||
{
|
{
|
||||||
try
|
|
||||||
{
|
|
||||||
|
|
||||||
bool to_bottom = (i == 0);
|
bool to_bottom = (i == 0);
|
||||||
|
|
||||||
// If liquid is at lowest possible height, it's not going
|
// If liquid is at lowest possible height, it's not going
|
||||||
@ -1680,7 +1719,7 @@ void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks)
|
|||||||
|
|
||||||
v3s16 p2 = p0 + dirs_to[i];
|
v3s16 p2 = p0 + dirs_to[i];
|
||||||
|
|
||||||
MapNode n2 = getNode(p2);
|
MapNode n2 = getNodeNoEx(p2);
|
||||||
//dstream<<"[1] n2.param="<<(int)n2.param<<std::endl;
|
//dstream<<"[1] n2.param="<<(int)n2.param<<std::endl;
|
||||||
|
|
||||||
if(content_liquid(n2.d))
|
if(content_liquid(n2.d))
|
||||||
@ -1746,10 +1785,6 @@ void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks)
|
|||||||
// If n2_changed to bottom, don't flow anywhere else
|
// If n2_changed to bottom, don't flow anywhere else
|
||||||
if(to_bottom && flowed && !is_source)
|
if(to_bottom && flowed && !is_source)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}catch(InvalidPositionException &e)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
loopcount++;
|
loopcount++;
|
||||||
@ -1945,7 +1980,6 @@ ServerMap::~ServerMap()
|
|||||||
{
|
{
|
||||||
if(m_map_saving_enabled)
|
if(m_map_saving_enabled)
|
||||||
{
|
{
|
||||||
//save(false);
|
|
||||||
// Save only changed parts
|
// Save only changed parts
|
||||||
save(true);
|
save(true);
|
||||||
dstream<<DTIME<<"Server: saved map to "<<m_savedir<<std::endl;
|
dstream<<DTIME<<"Server: saved map to "<<m_savedir<<std::endl;
|
||||||
@ -2104,11 +2138,15 @@ MapBlock* ServerMap::finishBlockMake(mapgen::BlockMakeData *data,
|
|||||||
/*
|
/*
|
||||||
NOTE: Lighting and object adding shouldn't really be here, but
|
NOTE: Lighting and object adding shouldn't really be here, but
|
||||||
lighting is a bit tricky to move properly to makeBlock.
|
lighting is a bit tricky to move properly to makeBlock.
|
||||||
TODO: Do this the right way anyway.
|
TODO: Do this the right way anyway, that is, move it to makeBlock.
|
||||||
|
- There needs to be some way for makeBlock to report back if
|
||||||
|
the lighting update is going further down because of the
|
||||||
|
new block blocking light
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Update lighting
|
Update lighting
|
||||||
|
NOTE: This takes ~60ms, TODO: Investigate why
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
TimeTaker t("finishBlockMake lighting update");
|
TimeTaker t("finishBlockMake lighting update");
|
||||||
@ -3418,6 +3456,9 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
|
|||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Okay, this block will be drawn. Reset usage timer.
|
||||||
|
block->resetUsageTimer();
|
||||||
|
|
||||||
// This is ugly (spherical distance limit?)
|
// This is ugly (spherical distance limit?)
|
||||||
/*if(m_control.range_all == false &&
|
/*if(m_control.range_all == false &&
|
||||||
|
15
src/map.h
15
src/map.h
@ -223,19 +223,23 @@ public:
|
|||||||
|
|
||||||
virtual void save(bool only_changed){assert(0);};
|
virtual void save(bool only_changed){assert(0);};
|
||||||
|
|
||||||
// Server implements this
|
// Server implements this.
|
||||||
|
// Client leaves it as no-op.
|
||||||
virtual void saveBlock(MapBlock *block){};
|
virtual void saveBlock(MapBlock *block){};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Updates usage timers
|
Updates usage timers and unloads unused blocks and sectors.
|
||||||
|
Saves modified blocks before unloading on MAPTYPE_SERVER.
|
||||||
*/
|
*/
|
||||||
void timerUpdate(float dtime);
|
void timerUpdate(float dtime, float unload_timeout,
|
||||||
|
core::list<v3s16> *unloaded_blocks=NULL);
|
||||||
|
|
||||||
// Deletes sectors and their blocks from memory
|
// Deletes sectors and their blocks from memory
|
||||||
// Takes cache into account
|
// Takes cache into account
|
||||||
// If deleted sector is in sector cache, clears cache
|
// If deleted sector is in sector cache, clears cache
|
||||||
void deleteSectors(core::list<v2s16> &list);
|
void deleteSectors(core::list<v2s16> &list);
|
||||||
|
|
||||||
|
#if 0
|
||||||
/*
|
/*
|
||||||
Unload unused data
|
Unload unused data
|
||||||
= flush changed to disk and delete from memory, if usage timer of
|
= flush changed to disk and delete from memory, if usage timer of
|
||||||
@ -243,8 +247,9 @@ public:
|
|||||||
*/
|
*/
|
||||||
void unloadUnusedData(float timeout,
|
void unloadUnusedData(float timeout,
|
||||||
core::list<v3s16> *deleted_blocks=NULL);
|
core::list<v3s16> *deleted_blocks=NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
// For debug printing
|
// For debug printing. Prints "Map: ", "ServerMap: " or "ClientMap: "
|
||||||
virtual void PrintInfo(std::ostream &out);
|
virtual void PrintInfo(std::ostream &out);
|
||||||
|
|
||||||
void transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks);
|
void transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks);
|
||||||
|
117
src/server.cpp
117
src/server.cpp
@ -602,6 +602,9 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
|
|||||||
bool block_is_invalid = false;
|
bool block_is_invalid = false;
|
||||||
if(block != NULL)
|
if(block != NULL)
|
||||||
{
|
{
|
||||||
|
// Reset usage timer, this block will be of use in the future.
|
||||||
|
block->resetUsageTimer();
|
||||||
|
|
||||||
// Block is dummy if data doesn't exist.
|
// Block is dummy if data doesn't exist.
|
||||||
// It means it has been not found from disk and not generated
|
// It means it has been not found from disk and not generated
|
||||||
if(block->isDummy())
|
if(block->isDummy())
|
||||||
@ -1297,12 +1300,21 @@ void Server::AsyncRunStep()
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
// Step environment
|
|
||||||
// This also runs Map's timers
|
|
||||||
JMutexAutoLock lock(m_env_mutex);
|
JMutexAutoLock lock(m_env_mutex);
|
||||||
|
// Step environment
|
||||||
ScopeProfiler sp(&g_profiler, "Server: environment step");
|
ScopeProfiler sp(&g_profiler, "Server: environment step");
|
||||||
m_env.step(dtime);
|
m_env.step(dtime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const float map_timer_and_unload_dtime = 5.15;
|
||||||
|
if(m_map_timer_and_unload_interval.step(dtime, map_timer_and_unload_dtime))
|
||||||
|
{
|
||||||
|
JMutexAutoLock lock(m_env_mutex);
|
||||||
|
// Run Map's timers and unload unused data
|
||||||
|
ScopeProfiler sp(&g_profiler, "Server: map timer and unload");
|
||||||
|
m_env.getMap().timerUpdate(map_timer_and_unload_dtime,
|
||||||
|
g_settings.getFloat("server_unload_unused_data_timeout"));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Do background stuff
|
Do background stuff
|
||||||
@ -1665,8 +1677,15 @@ void Server::AsyncRunStep()
|
|||||||
if(m_unsent_map_edit_queue.size() >= 4)
|
if(m_unsent_map_edit_queue.size() >= 4)
|
||||||
disable_single_change_sending = true;
|
disable_single_change_sending = true;
|
||||||
|
|
||||||
|
bool got_any_events = false;
|
||||||
|
|
||||||
|
// We'll log the amount of each
|
||||||
|
Profiler prof;
|
||||||
|
|
||||||
while(m_unsent_map_edit_queue.size() != 0)
|
while(m_unsent_map_edit_queue.size() != 0)
|
||||||
{
|
{
|
||||||
|
got_any_events = true;
|
||||||
|
|
||||||
MapEditEvent* event = m_unsent_map_edit_queue.pop_front();
|
MapEditEvent* event = m_unsent_map_edit_queue.pop_front();
|
||||||
|
|
||||||
// Players far away from the change are stored here.
|
// Players far away from the change are stored here.
|
||||||
@ -1676,7 +1695,8 @@ void Server::AsyncRunStep()
|
|||||||
|
|
||||||
if(event->type == MEET_ADDNODE)
|
if(event->type == MEET_ADDNODE)
|
||||||
{
|
{
|
||||||
dstream<<"Server: MEET_ADDNODE"<<std::endl;
|
//dstream<<"Server: MEET_ADDNODE"<<std::endl;
|
||||||
|
prof.add("MEET_ADDNODE", 1);
|
||||||
if(disable_single_change_sending)
|
if(disable_single_change_sending)
|
||||||
sendAddNode(event->p, event->n, event->already_known_by_peer,
|
sendAddNode(event->p, event->n, event->already_known_by_peer,
|
||||||
&far_players, 5);
|
&far_players, 5);
|
||||||
@ -1686,7 +1706,8 @@ void Server::AsyncRunStep()
|
|||||||
}
|
}
|
||||||
else if(event->type == MEET_REMOVENODE)
|
else if(event->type == MEET_REMOVENODE)
|
||||||
{
|
{
|
||||||
dstream<<"Server: MEET_REMOVENODE"<<std::endl;
|
//dstream<<"Server: MEET_REMOVENODE"<<std::endl;
|
||||||
|
prof.add("MEET_REMOVENODE", 1);
|
||||||
if(disable_single_change_sending)
|
if(disable_single_change_sending)
|
||||||
sendRemoveNode(event->p, event->already_known_by_peer,
|
sendRemoveNode(event->p, event->already_known_by_peer,
|
||||||
&far_players, 5);
|
&far_players, 5);
|
||||||
@ -1697,15 +1718,18 @@ void Server::AsyncRunStep()
|
|||||||
else if(event->type == MEET_BLOCK_NODE_METADATA_CHANGED)
|
else if(event->type == MEET_BLOCK_NODE_METADATA_CHANGED)
|
||||||
{
|
{
|
||||||
dstream<<"Server: MEET_BLOCK_NODE_METADATA_CHANGED"<<std::endl;
|
dstream<<"Server: MEET_BLOCK_NODE_METADATA_CHANGED"<<std::endl;
|
||||||
|
prof.add("MEET_BLOCK_NODE_METADATA_CHANGED", 1);
|
||||||
setBlockNotSent(event->p);
|
setBlockNotSent(event->p);
|
||||||
}
|
}
|
||||||
else if(event->type == MEET_OTHER)
|
else if(event->type == MEET_OTHER)
|
||||||
{
|
{
|
||||||
|
prof.add("MEET_OTHER", 1);
|
||||||
dstream<<"WARNING: Server: MEET_OTHER not implemented"
|
dstream<<"WARNING: Server: MEET_OTHER not implemented"
|
||||||
<<std::endl;
|
<<std::endl;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
prof.add("unknown", 1);
|
||||||
dstream<<"WARNING: Server: Unknown MapEditEvent "
|
dstream<<"WARNING: Server: Unknown MapEditEvent "
|
||||||
<<((u32)event->type)<<std::endl;
|
<<((u32)event->type)<<std::endl;
|
||||||
}
|
}
|
||||||
@ -1743,6 +1767,13 @@ void Server::AsyncRunStep()
|
|||||||
if(count >= 1 && m_unsent_map_edit_queue.size() < 100)
|
if(count >= 1 && m_unsent_map_edit_queue.size() < 100)
|
||||||
break;*/
|
break;*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(got_any_events)
|
||||||
|
{
|
||||||
|
dstream<<"Server: MapEditEvents:"<<std::endl;
|
||||||
|
prof.print(dstream);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1765,39 +1796,6 @@ void Server::AsyncRunStep()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
Step node metadata
|
|
||||||
TODO: Move to ServerEnvironment and utilize active block stuff
|
|
||||||
*/
|
|
||||||
/*{
|
|
||||||
//TimeTaker timer("Step node metadata");
|
|
||||||
|
|
||||||
JMutexAutoLock envlock(m_env_mutex);
|
|
||||||
JMutexAutoLock conlock(m_con_mutex);
|
|
||||||
|
|
||||||
ScopeProfiler sp(&g_profiler, "Server: stepping node metadata");
|
|
||||||
|
|
||||||
core::map<v3s16, MapBlock*> changed_blocks;
|
|
||||||
m_env.getMap().nodeMetadataStep(dtime, changed_blocks);
|
|
||||||
|
|
||||||
// Use setBlockNotSent
|
|
||||||
|
|
||||||
for(core::map<v3s16, MapBlock*>::Iterator
|
|
||||||
i = changed_blocks.getIterator();
|
|
||||||
i.atEnd() == false; i++)
|
|
||||||
{
|
|
||||||
MapBlock *block = i.getNode()->getValue();
|
|
||||||
|
|
||||||
for(core::map<u16, RemoteClient*>::Iterator
|
|
||||||
i = m_clients.getIterator();
|
|
||||||
i.atEnd()==false; i++)
|
|
||||||
{
|
|
||||||
RemoteClient *client = i.getNode()->getValue();
|
|
||||||
client->SetBlockNotSent(block->getPos());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Trigger emergethread (it somehow gets to a non-triggered but
|
Trigger emergethread (it somehow gets to a non-triggered but
|
||||||
bysy state sometimes)
|
bysy state sometimes)
|
||||||
@ -1829,30 +1827,29 @@ void Server::AsyncRunStep()
|
|||||||
|
|
||||||
// Map
|
// Map
|
||||||
JMutexAutoLock lock(m_env_mutex);
|
JMutexAutoLock lock(m_env_mutex);
|
||||||
if(((ServerMap*)(&m_env.getMap()))->isSavingEnabled() == true)
|
|
||||||
|
/*// Unload unused data (delete from memory)
|
||||||
|
m_env.getMap().unloadUnusedData(
|
||||||
|
g_settings.getFloat("server_unload_unused_sectors_timeout"));
|
||||||
|
*/
|
||||||
|
/*u32 deleted_count = m_env.getMap().unloadUnusedData(
|
||||||
|
g_settings.getFloat("server_unload_unused_sectors_timeout"));
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Save only changed parts
|
||||||
|
m_env.getMap().save(true);
|
||||||
|
|
||||||
|
/*if(deleted_count > 0)
|
||||||
{
|
{
|
||||||
// Unload unused data (delete from memory)
|
dout_server<<"Server: Unloaded "<<deleted_count
|
||||||
m_env.getMap().unloadUnusedData(
|
<<" blocks from memory"<<std::endl;
|
||||||
g_settings.getFloat("server_unload_unused_sectors_timeout"));
|
}*/
|
||||||
/*u32 deleted_count = m_env.getMap().unloadUnusedData(
|
|
||||||
g_settings.getFloat("server_unload_unused_sectors_timeout"));
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Save only changed parts
|
// Save players
|
||||||
m_env.getMap().save(true);
|
m_env.serializePlayers(m_mapsavedir);
|
||||||
|
|
||||||
/*if(deleted_count > 0)
|
// Save environment metadata
|
||||||
{
|
m_env.saveMeta(m_mapsavedir);
|
||||||
dout_server<<"Server: Unloaded "<<deleted_count
|
|
||||||
<<" blocks from memory"<<std::endl;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
// Save players
|
|
||||||
m_env.serializePlayers(m_mapsavedir);
|
|
||||||
|
|
||||||
// Save environment metadata
|
|
||||||
m_env.saveMeta(m_mapsavedir);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3336,7 +3333,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||||||
|
|
||||||
void Server::onMapEditEvent(MapEditEvent *event)
|
void Server::onMapEditEvent(MapEditEvent *event)
|
||||||
{
|
{
|
||||||
dstream<<"Server::onMapEditEvent()"<<std::endl;
|
//dstream<<"Server::onMapEditEvent()"<<std::endl;
|
||||||
if(m_ignore_map_edit_events)
|
if(m_ignore_map_edit_events)
|
||||||
return;
|
return;
|
||||||
MapEditEvent *e = event->clone();
|
MapEditEvent *e = event->clone();
|
||||||
|
@ -534,6 +534,7 @@ private:
|
|||||||
float m_objectdata_timer;
|
float m_objectdata_timer;
|
||||||
float m_emergethread_trigger_timer;
|
float m_emergethread_trigger_timer;
|
||||||
float m_savemap_timer;
|
float m_savemap_timer;
|
||||||
|
IntervalLimiter m_map_timer_and_unload_interval;
|
||||||
|
|
||||||
// NOTE: If connection and environment are both to be locked,
|
// NOTE: If connection and environment are both to be locked,
|
||||||
// environment shall be locked first.
|
// environment shall be locked first.
|
||||||
|
Loading…
Reference in New Issue
Block a user