Skip to content
Snippets Groups Projects
Commit 9d5ccafb authored by Perttu Ahola's avatar Perttu Ahola
Browse files

changed server to do object management at longer intervals (0.5s)

parent 26eb607a
No related branches found
No related tags found
No related merge requests found
...@@ -449,227 +449,231 @@ void ServerEnvironment::step(float dtime) ...@@ -449,227 +449,231 @@ void ServerEnvironment::step(float dtime)
obj->step(dtime, m_active_object_messages, send_recommended); obj->step(dtime, m_active_object_messages, send_recommended);
} }
/* if(m_object_management_interval.step(dtime, 0.5))
Remove objects that satisfy (m_removed && m_known_by_count==0)
*/
{ {
core::list<u16> objects_to_remove; /*
for(core::map<u16, ServerActiveObject*>::Iterator Remove objects that satisfy (m_removed && m_known_by_count==0)
i = m_active_objects.getIterator(); */
i.atEnd()==false; i++)
{ {
u16 id = i.getNode()->getKey(); core::list<u16> objects_to_remove;
ServerActiveObject* obj = i.getNode()->getValue(); for(core::map<u16, ServerActiveObject*>::Iterator
// This shouldn't happen but check it i = m_active_objects.getIterator();
if(obj == NULL) i.atEnd()==false; i++)
{ {
dstream<<"WARNING: NULL object found in ServerEnvironment" u16 id = i.getNode()->getKey();
<<" while finding removed objects. id="<<id<<std::endl; ServerActiveObject* obj = i.getNode()->getValue();
// This shouldn't happen but check it
if(obj == NULL)
{
dstream<<"WARNING: NULL object found in ServerEnvironment"
<<" while finding removed objects. id="<<id<<std::endl;
// Id to be removed from m_active_objects
objects_to_remove.push_back(id);
continue;
}
// If not m_removed, don't remove.
if(obj->m_removed == false)
continue;
// Delete static data from block
if(obj->m_static_exists)
{
MapBlock *block = m_map->getBlockNoCreateNoEx(obj->m_static_block);
if(block)
{
block->m_static_objects.remove(id);
block->setChangedFlag();
}
}
// If m_known_by_count > 0, don't actually remove.
if(obj->m_known_by_count > 0)
continue;
// Delete
delete obj;
// Id to be removed from m_active_objects // Id to be removed from m_active_objects
objects_to_remove.push_back(id); objects_to_remove.push_back(id);
continue;
} }
// If not m_removed, don't remove. // Remove references from m_active_objects
if(obj->m_removed == false) for(core::list<u16>::Iterator i = objects_to_remove.begin();
continue; i != objects_to_remove.end(); i++)
// Delete static data from block
if(obj->m_static_exists)
{ {
MapBlock *block = m_map->getBlockNoCreateNoEx(obj->m_static_block); m_active_objects.remove(*i);
if(block)
{
block->m_static_objects.remove(id);
block->setChangedFlag();
}
} }
// If m_known_by_count > 0, don't actually remove.
if(obj->m_known_by_count > 0)
continue;
// Delete
delete obj;
// Id to be removed from m_active_objects
objects_to_remove.push_back(id);
}
// Remove references from m_active_objects
for(core::list<u16>::Iterator i = objects_to_remove.begin();
i != objects_to_remove.end(); i++)
{
m_active_objects.remove(*i);
} }
}
const s16 to_active_max_blocks = 3;
const f32 to_static_max_f = (to_active_max_blocks+1)*MAP_BLOCKSIZE*BS;
/*
Convert stored objects from blocks near the players to active.
*/
for(core::list<Player*>::Iterator i = m_players.begin();
i != m_players.end(); i++)
{
Player *player = *i;
// Ignore disconnected players
if(player->peer_id == 0)
continue;
v3f playerpos = player->getPosition(); const s16 to_active_max_blocks = 3;
const f32 to_static_max_f = (to_active_max_blocks+1)*MAP_BLOCKSIZE*BS;
v3s16 blockpos0 = getNodeBlockPos(floatToInt(playerpos, BS));
v3s16 bpmin = blockpos0 - v3s16(1,1,1)*to_active_max_blocks; /*
v3s16 bpmax = blockpos0 + v3s16(1,1,1)*to_active_max_blocks; Convert stored objects from blocks near the players to active.
// Loop through all nearby blocks */
for(s16 x=bpmin.X; x<=bpmax.X; x++) for(core::list<Player*>::Iterator i = m_players.begin();
for(s16 y=bpmin.Y; y<=bpmax.Y; y++) i != m_players.end(); i++)
for(s16 z=bpmin.Z; z<=bpmax.Z; z++)
{ {
v3s16 blockpos(x,y,z); Player *player = *i;
MapBlock *block = m_map->getBlockNoCreateNoEx(blockpos);
if(block==NULL) // Ignore disconnected players
continue; if(player->peer_id == 0)
// Ignore if no stored objects (to not set changed flag)
if(block->m_static_objects.m_stored.size() == 0)
continue; continue;
// This will contain the leftovers of the stored list
core::list<StaticObject> new_stored; v3f playerpos = player->getPosition();
// Loop through stored static objects
for(core::list<StaticObject>::Iterator v3s16 blockpos0 = getNodeBlockPos(floatToInt(playerpos, BS));
i = block->m_static_objects.m_stored.begin(); v3s16 bpmin = blockpos0 - v3s16(1,1,1)*to_active_max_blocks;
i != block->m_static_objects.m_stored.end(); i++) v3s16 bpmax = blockpos0 + v3s16(1,1,1)*to_active_max_blocks;
// Loop through all nearby blocks
for(s16 x=bpmin.X; x<=bpmax.X; x++)
for(s16 y=bpmin.Y; y<=bpmax.Y; y++)
for(s16 z=bpmin.Z; z<=bpmax.Z; z++)
{ {
/*dstream<<"INFO: Server: Creating an active object from " v3s16 blockpos(x,y,z);
<<"static data"<<std::endl;*/ MapBlock *block = m_map->getBlockNoCreateNoEx(blockpos);
StaticObject &s_obj = *i; if(block==NULL)
// Create an active object from the data
ServerActiveObject *obj = ServerActiveObject::create
(s_obj.type, this, 0, s_obj.pos, s_obj.data);
if(obj==NULL)
{
// This is necessary to preserve stuff during bugs
// and errors
new_stored.push_back(s_obj);
continue; continue;
// Ignore if no stored objects (to not set changed flag)
if(block->m_static_objects.m_stored.size() == 0)
continue;
// This will contain the leftovers of the stored list
core::list<StaticObject> new_stored;
// Loop through stored static objects
for(core::list<StaticObject>::Iterator
i = block->m_static_objects.m_stored.begin();
i != block->m_static_objects.m_stored.end(); i++)
{
/*dstream<<"INFO: Server: Creating an active object from "
<<"static data"<<std::endl;*/
StaticObject &s_obj = *i;
// Create an active object from the data
ServerActiveObject *obj = ServerActiveObject::create
(s_obj.type, this, 0, s_obj.pos, s_obj.data);
if(obj==NULL)
{
// This is necessary to preserve stuff during bugs
// and errors
new_stored.push_back(s_obj);
continue;
}
// This will also add the object to the active static list
addActiveObject(obj);
//u16 id = addActiveObject(obj);
} }
// This will also add the object to the active static list // Clear stored list
addActiveObject(obj); block->m_static_objects.m_stored.clear();
//u16 id = addActiveObject(obj); // Add leftover stuff to stored list
} for(core::list<StaticObject>::Iterator
// Clear stored list i = new_stored.begin();
block->m_static_objects.m_stored.clear(); i != new_stored.end(); i++)
// Add leftover stuff to stored list {
for(core::list<StaticObject>::Iterator StaticObject &s_obj = *i;
i = new_stored.begin(); block->m_static_objects.m_stored.push_back(s_obj);
i != new_stored.end(); i++) }
{ block->setChangedFlag();
StaticObject &s_obj = *i;
block->m_static_objects.m_stored.push_back(s_obj);
} }
block->setChangedFlag();
} }
}
/* /*
Convert objects that are far away from all the players to static. Convert objects that are far away from all the players to static.
*/ */
{
core::list<u16> objects_to_remove;
for(core::map<u16, ServerActiveObject*>::Iterator
i = m_active_objects.getIterator();
i.atEnd()==false; i++)
{ {
ServerActiveObject* obj = i.getNode()->getValue(); core::list<u16> objects_to_remove;
u16 id = i.getNode()->getKey(); for(core::map<u16, ServerActiveObject*>::Iterator
v3f objectpos = obj->getBasePosition(); i = m_active_objects.getIterator();
i.atEnd()==false; i++)
// This shouldn't happen but check it
if(obj == NULL)
{ {
dstream<<"WARNING: NULL object found in ServerEnvironment" ServerActiveObject* obj = i.getNode()->getValue();
<<std::endl; u16 id = i.getNode()->getKey();
continue; v3f objectpos = obj->getBasePosition();
}
// If known by some client, don't convert to static.
if(obj->m_known_by_count > 0)
continue;
// If close to some player, don't convert to static. // This shouldn't happen but check it
bool close_to_player = false; if(obj == NULL)
for(core::list<Player*>::Iterator i = m_players.begin(); {
i != m_players.end(); i++) dstream<<"WARNING: NULL object found in ServerEnvironment"
{ <<std::endl;
Player *player = *i; continue;
}
// Ignore disconnected players // If known by some client, don't convert to static.
if(player->peer_id == 0) if(obj->m_known_by_count > 0)
continue; continue;
v3f playerpos = player->getPosition(); // If close to some player, don't convert to static.
f32 d = playerpos.getDistanceFrom(objectpos); bool close_to_player = false;
if(d < to_static_max_f) for(core::list<Player*>::Iterator i = m_players.begin();
i != m_players.end(); i++)
{ {
close_to_player = true; Player *player = *i;
break;
// Ignore disconnected players
if(player->peer_id == 0)
continue;
v3f playerpos = player->getPosition();
f32 d = playerpos.getDistanceFrom(objectpos);
if(d < to_static_max_f)
{
close_to_player = true;
break;
}
} }
}
if(close_to_player) if(close_to_player)
continue; continue;
/* /*
Update the static data and remove the active object. Update the static data and remove the active object.
*/ */
// Delete old static object // Delete old static object
MapBlock *oldblock = NULL; MapBlock *oldblock = NULL;
if(obj->m_static_exists) if(obj->m_static_exists)
{ {
MapBlock *block = m_map->getBlockNoCreateNoEx(obj->m_static_block); MapBlock *block = m_map->getBlockNoCreateNoEx
(obj->m_static_block);
if(block)
{
block->m_static_objects.remove(id);
oldblock = block;
}
}
// Add new static object
std::string staticdata = obj->getStaticData();
StaticObject s_obj(obj->getType(), objectpos, staticdata);
// Add to the block where the object is located in
v3s16 blockpos = getNodeBlockPos(floatToInt(objectpos, BS));
MapBlock *block = m_map->getBlockNoCreateNoEx(blockpos);
if(block) if(block)
{ {
block->m_static_objects.remove(id); block->m_static_objects.insert(0, s_obj);
oldblock = block; block->setChangedFlag();
obj->m_static_exists = true;
obj->m_static_block = block->getPos();
} }
// If not possible, add back to previous block
else if(oldblock)
{
oldblock->m_static_objects.insert(0, s_obj);
oldblock->setChangedFlag();
obj->m_static_exists = true;
obj->m_static_block = oldblock->getPos();
}
else{
dstream<<"WARNING: Server: Could not find a block for "
<<"storing static object"<<std::endl;
obj->m_static_exists = false;
continue;
}
/*dstream<<"INFO: Server: Stored static data. Deleting object."
<<std::endl;*/
// Delete active object
delete obj;
// Id to be removed from m_active_objects
objects_to_remove.push_back(id);
} }
// Add new static object // Remove references from m_active_objects
std::string staticdata = obj->getStaticData(); for(core::list<u16>::Iterator i = objects_to_remove.begin();
StaticObject s_obj(obj->getType(), objectpos, staticdata); i != objects_to_remove.end(); i++)
// Add to the block where the object is located in
v3s16 blockpos = getNodeBlockPos(floatToInt(objectpos, BS));
MapBlock *block = m_map->getBlockNoCreateNoEx(blockpos);
if(block)
{
block->m_static_objects.insert(0, s_obj);
block->setChangedFlag();
obj->m_static_exists = true;
obj->m_static_block = block->getPos();
}
// If not possible, add back to previous block
else if(oldblock)
{ {
oldblock->m_static_objects.insert(0, s_obj); m_active_objects.remove(*i);
oldblock->setChangedFlag();
obj->m_static_exists = true;
obj->m_static_block = oldblock->getPos();
}
else{
dstream<<"WARNING: Server: Could not find a block for "
<<"storing static object"<<std::endl;
obj->m_static_exists = false;
continue;
} }
/*dstream<<"INFO: Server: Stored static data. Deleting object."
<<std::endl;*/
// Delete active object
delete obj;
// Id to be removed from m_active_objects
objects_to_remove.push_back(id);
}
// Remove references from m_active_objects
for(core::list<u16>::Iterator i = objects_to_remove.begin();
i != objects_to_remove.end(); i++)
{
m_active_objects.remove(*i);
} }
} }
......
...@@ -35,6 +35,7 @@ with this program; if not, write to the Free Software Foundation, Inc., ...@@ -35,6 +35,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "player.h" #include "player.h"
#include "map.h" #include "map.h"
#include <ostream> #include <ostream>
#include "utility.h"
class Environment class Environment
{ {
...@@ -154,6 +155,7 @@ class ServerEnvironment : public Environment ...@@ -154,6 +155,7 @@ class ServerEnvironment : public Environment
Queue<ActiveObjectMessage> m_active_object_messages; Queue<ActiveObjectMessage> m_active_object_messages;
float m_random_spawn_timer; float m_random_spawn_timer;
float m_send_recommended_timer; float m_send_recommended_timer;
IntervalLimiter m_object_management_interval;
}; };
#ifndef SERVER #ifndef SERVER
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment