#include "constants.h"
#include "voxel.h"
#include "config.h"
+#include "version.h"
#include "filesys.h"
#include "mapblock.h"
#include "serverobject.h"
m_objectdata_timer = 0.0;
m_emergethread_trigger_timer = 0.0;
m_savemap_timer = 0.0;
- m_clients_number = 0;
- m_env_mutex.Init();
- m_con_mutex.Init();
- m_step_dtime_mutex.Init();
m_step_dtime = 0.0;
if(path_world == "")
m_mods = modconf.getMods();
std::vector<ModSpec> unsatisfied_mods = modconf.getUnsatisfiedMods();
// complain about mods with unsatisfied dependencies
- if(!modconf.isConsistent())
+ if(!modconf.isConsistent())
{
for(std::vector<ModSpec>::iterator it = unsatisfied_mods.begin();
it != unsatisfied_mods.end(); ++it)
worldmt_settings.readConfigFile(worldmt.c_str());
std::vector<std::string> names = worldmt_settings.getNames();
std::set<std::string> load_mod_names;
- for(std::vector<std::string>::iterator it = names.begin();
+ for(std::vector<std::string>::iterator it = names.begin();
it != names.end(); ++it)
- {
- std::string name = *it;
+ {
+ std::string name = *it;
if(name.compare(0,9,"load_mod_")==0 && worldmt_settings.getBool(name))
load_mod_names.insert(name.substr(9));
}
it != unsatisfied_mods.end(); ++it)
load_mod_names.erase((*it).name);
if(!load_mod_names.empty())
- {
+ {
errorstream << "The following mods could not be found:";
for(std::set<std::string>::iterator it = load_mod_names.begin();
it != load_mod_names.end(); ++it)
counter = 0.0;
JMutexAutoLock lock2(m_con_mutex);
- m_clients_number = 0;
+ m_clients_names.clear();
if(m_clients.size() != 0)
infostream<<"Players:"<<std::endl;
for(std::map<u16, RemoteClient*>::iterator
continue;
infostream<<"* "<<player->getName()<<"\t";
client->PrintInfo(infostream);
- ++m_clients_number;
+ m_clients_names.push_back(player->getName());
}
}
}
float &counter = m_masterserver_timer;
if(!isSingleplayer() && (!counter || counter >= 300.0) && g_settings->getBool("server_announce") == true)
{
- ServerList::sendAnnounce(!counter ? "start" : "update", m_clients_number, m_uptime.get(), m_gamespec.id, m_mods);
+ ServerList::sendAnnounce(!counter ? "start" : "update", m_clients_names, m_uptime.get(), m_env->getGameTime(), m_gamespec.id, m_mods);
counter = 0.01;
}
counter += dtime;
// for them.
std::list<u16> far_players;
- if(event->type == MEET_ADDNODE)
+ if(event->type == MEET_ADDNODE || event->type == MEET_SWAPNODE)
{
//infostream<<"Server: MEET_ADDNODE"<<std::endl;
prof.add("MEET_ADDNODE", 1);
if(disable_single_change_sending)
sendAddNode(event->p, event->n, event->already_known_by_peer,
- &far_players, 5);
+ &far_players, 5, event->type == MEET_ADDNODE);
else
sendAddNode(event->p, event->n, event->already_known_by_peer,
- &far_players, 30);
+ &far_players, 30, event->type == MEET_ADDNODE);
}
else if(event->type == MEET_REMOVENODE)
{
DenyAccess(peer_id, std::wstring(
L"Your client's version is not supported.\n"
L"Server version is ")
- + narrow_to_wide(VERSION_STRING) + L"."
+ + narrow_to_wide(minetest_version_simple) + L"."
);
return;
}
DenyAccess(peer_id, std::wstring(
L"Your client's version is not supported.\n"
L"Server version is ")
- + narrow_to_wide(VERSION_STRING) + L",\n"
+ + narrow_to_wide(minetest_version_simple) + L",\n"
+ L"server's PROTOCOL_VERSION is "
+ narrow_to_wide(itos(SERVER_PROTOCOL_VERSION_MIN))
+ L"..."
DenyAccess(peer_id, std::wstring(
L"Your client's version is not supported.\n"
L"Server version is ")
- + narrow_to_wide(VERSION_STRING) + L",\n"
+ + narrow_to_wide(minetest_version_simple) + L",\n"
+ L"server's PROTOCOL_VERSION (strict) is "
+ narrow_to_wide(itos(LATEST_PROTOCOL_VERSION))
+ L", client's PROTOCOL_VERSION is "
}
/*infostream<<"Server::ProcessData(): Moved player "<<peer_id<<" to "
- <<"("<<position.X<<","<<position.Y<<","<<position.Z<<")"
- <<" pitch="<<pitch<<" yaw="<<yaw<<std::endl;*/
+ <<"("<<position.X<<","<<position.Y<<","<<position.Z<<")"
+ <<" pitch="<<pitch<<" yaw="<<yaw<<std::endl;*/
+
}
else if(command == TOSERVER_GOTBLOCKS)
{
}
void Server::sendAddNode(v3s16 p, MapNode n, u16 ignore_id,
- std::list<u16> *far_players, float far_d_nodes)
+ std::list<u16> *far_players, float far_d_nodes,
+ bool remove_metadata)
{
float maxd = far_d_nodes*BS;
v3f p_f = intToFloat(p, BS);
}
// Create packet
- u32 replysize = 8 + MapNode::serializedLength(client->serialization_version);
+ u32 replysize = 9 + MapNode::serializedLength(client->serialization_version);
SharedBuffer<u8> reply(replysize);
writeU16(&reply[0], TOCLIENT_ADDNODE);
writeS16(&reply[2], p.X);
writeS16(&reply[4], p.Y);
writeS16(&reply[6], p.Z);
n.serialize(&reply[8], client->serialization_version);
+ u32 index = 8 + MapNode::serializedLength(client->serialization_version);
+ writeU8(&reply[index], remove_metadata ? 0 : 1);
+
+ if (!remove_metadata) {
+ if (client->net_proto_version <= 21) {
+ // Old clients always clear metadata; fix it
+ // by sending the full block again.
+ client->SetBlockNotSent(p);
+ }
+ }
// Send as reliable
m_con.Send(client->peer_id, 0, reply, true);
// Get a preview for crafting
ItemStack preview;
+ InventoryLocation loc;
+ loc.setPlayer(player->getName());
getCraftingResult(&player->inventory, preview, false, this);
+ m_env->getScriptIface()->item_CraftPredict(preview, player->getPlayerSAO(), (&player->inventory)->getList("craft"), loc);
// Put the new preview in
InventoryList *plist = player->inventory.getList("craftpreview");
std::wostringstream os(std::ios_base::binary);
os<<L"# Server: ";
// Version
- os<<L"version="<<narrow_to_wide(VERSION_STRING);
+ os<<L"version="<<narrow_to_wide(minetest_version_simple);
// Uptime
os<<L", uptime="<<m_uptime.get();
// Max lag estimate
-range + (myrand() % (range * 2)));
// Get ground height at point
- s16 groundheight = map.findGroundLevel(nodepos2d);
+ s16 groundheight = map.findGroundLevel(nodepos2d, g_settings->getBool("cache_block_before_spawn"));
if (groundheight <= water_level) // Don't go underwater
continue;
- if (groundheight > water_level + 6) // Don't go to high places
+ if (groundheight > water_level + g_settings->getS16("max_spawn_height")) // Don't go to high places
continue;
nodepos = v3s16(nodepos2d.X, groundheight, nodepos2d.Y);