51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#include <set>
-#include <list>
-#include <map>
#include "environment.h"
#include "filesys.h"
#include "porting.h"
#include "mapblock.h"
#include "serverobject.h"
#include "content_sao.h"
-#include "mapgen.h"
#include "settings.h"
#include "log.h"
#include "profiler.h"
-#include "cpp_api/scriptapi.h"
+#include "scripting_game.h"
#include "nodedef.h"
#include "nodemetadata.h"
#include "main.h" // For g_settings, g_profiler
#endif
#include "daynightratio.h"
#include "map.h"
+#include "emerge.h"
#include "util/serialize.h"
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
return newlist;
}
-void Environment::printPlayers(std::ostream &o)
-{
- o<<"Players in environment:"<<std::endl;
- for(std::list<Player*>::iterator i = m_players.begin();
- i != m_players.end(); i++)
- {
- Player *player = *i;
- o<<"Player peer_id="<<player->peer_id<<std::endl;
- }
-}
-
u32 Environment::getDayNightRatio()
{
bool smooth = g_settings->getBool("enable_shaders");
ServerEnvironment
*/
-ServerEnvironment::ServerEnvironment(ServerMap *map, ScriptApi *scriptIface,
+ServerEnvironment::ServerEnvironment(ServerMap *map,
+ GameScripting *scriptIface,
IGameDef *gamedef, IBackgroundBlockEmerger *emerger):
m_map(map),
m_script(scriptIface),
m_active_block_interval_overload_skip(0),
m_game_time(0),
m_game_time_fraction_counter(0),
- m_recommended_send_interval(0.1)
+ m_recommended_send_interval(0.1),
+ m_max_lag_estimate(0.1)
{
+ m_use_weather = g_settings->getBool("weather");
}
ServerEnvironment::~ServerEnvironment()
if(player->checkModified())
{
// Open file and serialize
- std::ofstream os(path.c_str(), std::ios_base::binary);
- if(os.good() == false)
+ std::ostringstream ss(std::ios_base::binary);
+ player->serialize(ss);
+ if(!fs::safeWriteToFile(path, ss.str()))
{
- infostream<<"Failed to overwrite "<<path<<std::endl;
+ infostream<<"Failed to write "<<path<<std::endl;
continue;
}
- player->serialize(os);
saved_players.insert(player);
} else {
saved_players.insert(player);
/*infostream<<"Saving player "<<player->getName()<<" to "
<<path<<std::endl;*/
// Open file and serialize
- std::ofstream os(path.c_str(), std::ios_base::binary);
- if(os.good() == false)
+ std::ostringstream ss(std::ios_base::binary);
+ player->serialize(ss);
+ if(!fs::safeWriteToFile(path, ss.str()))
{
- infostream<<"Failed to overwrite "<<path<<std::endl;
+ infostream<<"Failed to write "<<path<<std::endl;
continue;
}
- player->serialize(os);
saved_players.insert(player);
}
}
std::string path = savedir + "/env_meta.txt";
// Open file and serialize
- std::ofstream os(path.c_str(), std::ios_base::binary);
- if(os.good() == false)
- {
- infostream<<"ServerEnvironment::saveMeta(): Failed to open "
- <<path<<std::endl;
- throw SerializationError("Couldn't save env meta");
- }
+ std::ostringstream ss(std::ios_base::binary);
Settings args;
args.setU64("game_time", m_game_time);
args.setU64("time_of_day", getTimeOfDay());
- args.writeLines(os);
- os<<"EnvArgsEnd\n";
+ args.writeLines(ss);
+ ss<<"EnvArgsEnd\n";
+
+ if(!fs::safeWriteToFile(path, ss.str()))
+ {
+ infostream<<"ServerEnvironment::saveMeta(): Failed to write "
+ <<path<<std::endl;
+ throw SerializationError("Couldn't save env meta");
+ }
}
void ServerEnvironment::loadMeta(const std::string &savedir)
// Activate stored objects
activateObjects(block, dtime_s);
+
+ // Calculate weather conditions
+ if (m_use_weather) {
+ m_map->updateBlockHeat(this, block->getPos() * MAP_BLOCKSIZE, block);
+ m_map->updateBlockHumidity(this, block->getPos() * MAP_BLOCKSIZE, block);
+ } else {
+ block->heat = HEAT_UNDEFINED;
+ block->humidity = HUMIDITY_UNDEFINED;
+ block->weather_update_time = 0;
+ }
// Run node timers
std::map<v3s16, NodeTimer> elapsed_timers =
MapBlock *block = m_map->getBlockNoCreateNoEx(p);
if(block==NULL){
// Block needs to be fetched first
- m_emerger->queueBlockEmerge(p, false);
+ m_emerger->enqueueBlockEmerge(
+ PEER_ID_INEXISTENT, p, false);
m_active_blocks.m_list.erase(p);
continue;
}
if(m_active_object_messages.empty())
return ActiveObjectMessage(0);
- return m_active_object_messages.pop_front();
+ ActiveObjectMessage message = m_active_object_messages.front();
+ m_active_object_messages.pop_front();
+ return message;
}
/*
<<"activating objects of block "<<PP(block->getPos())
<<" ("<<block->m_static_objects.m_stored.size()
<<" objects)"<<std::endl;
- bool large_amount = (block->m_static_objects.m_stored.size() > 49);
+ bool large_amount = (block->m_static_objects.m_stored.size() > g_settings->getU16("max_objects_per_block"));
if(large_amount){
errorstream<<"suspiciously large amount of objects detected: "
<<block->m_static_objects.m_stored.size()<<" in "
if(block)
{
- if(block->m_static_objects.m_stored.size() >= 49){
+ if(block->m_static_objects.m_stored.size() >= g_settings->getU16("max_objects_per_block")){
errorstream<<"ServerEnv: Trying to store id="<<obj->getId()
<<" statically but block "<<PP(blockpos)
<<" already contains "
<<block->m_static_objects.m_stored.size()
- <<" (over 49) objects."
+ <<" objects."
<<" Forcing delete."<<std::endl;
force_delete = true;
} else {
v3s16 p = floatToInt(pf + v3f(0, BS*1.6, 0), BS);
MapNode n = m_map->getNodeNoEx(p);
ContentFeatures c = m_gamedef->ndef()->get(n);
- if(c.isLiquid() && c.drowning && lplayer->hp > 0){
+ u8 drowning_damage = c.drowning;
+ if(drowning_damage > 0 && lplayer->hp > 0){
u16 breath = lplayer->getBreath();
if(breath > 10){
breath = 11;
updateLocalPlayerBreath(breath);
}
- if(lplayer->getBreath() == 0){
- damageLocalPlayer(1, true);
+ if(lplayer->getBreath() == 0 && drowning_damage > 0){
+ damageLocalPlayer(drowning_damage, true);
}
}
if(m_breathing_interval.step(dtime, 0.5))
if (!lplayer->hp){
lplayer->setBreath(11);
}
- else if(!c.isLiquid() || !c.drowning){
+ else if(c.drowning == 0){
u16 breath = lplayer->getBreath();
if(breath <= 10){
breath += 1;
ClientEnvEvent ClientEnvironment::getClientEvent()
{
+ ClientEnvEvent event;
if(m_client_event_queue.empty())
- {
- ClientEnvEvent event;
event.type = CEE_NONE;
- return event;
+ else {
+ event = m_client_event_queue.front();
+ m_client_event_queue.pop_front();
}
- return m_client_event_queue.pop_front();
+ return event;
}
#endif // #ifndef SERVER