X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fserver.cpp;h=6d34a0fac1dd89f323f5775463714385f11a661f;hb=61ffe1eac4565bbb74b79677a618e7f4dd894d3c;hp=14c019d52fc8e6e944756e11d672d20e9e4daed9;hpb=2419d0029ac36952aaa74b685d529a3592adb6aa;p=dragonfireclient.git
diff --git a/src/server.cpp b/src/server.cpp
index 14c019d52..6d34a0fac 100644
--- a/src/server.cpp
+++ b/src/server.cpp
@@ -39,6 +39,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "settings.h"
#include "profiler.h"
#include "log.h"
+#include "script.h"
+#include "scriptapi.h"
+#include "nodedef.h"
+#include "tooldef.h"
+#include "craftdef.h"
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
@@ -185,7 +190,7 @@ void * EmergeThread::Thread()
<<"("<
m_env.getMap());
+ ServerMap &map = ((ServerMap&)m_server->m_env->getMap());
//core::map changed_blocks;
//core::map lighting_invalidated_blocks;
@@ -250,7 +255,7 @@ void * EmergeThread::Thread()
MapEditEventIgnorer ign(&m_server->m_ignore_map_edit_events);
// Activate objects and stuff
- m_server->m_env.activateBlock(block, 3600);
+ m_server->m_env->activateBlock(block, 3600);
}
}
else
@@ -354,11 +359,10 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
// Increment timers
m_nothing_to_send_pause_timer -= dtime;
+ m_nearest_unsent_reset_timer += dtime;
if(m_nothing_to_send_pause_timer >= 0)
{
- // Keep this reset
- m_nearest_unsent_reset_timer = 0;
return;
}
@@ -372,7 +376,7 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
//TimeTaker timer("RemoteClient::GetNextBlocks");
- Player *player = server->m_env.getPlayer(peer_id);
+ Player *player = server->m_env->getPlayer(peer_id);
assert(player != NULL);
@@ -410,17 +414,13 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
/*infostream<<"m_nearest_unsent_reset_timer="
< 10.0)
+ // Reset periodically to workaround for some bugs or stuff
+ if(m_nearest_unsent_reset_timer > 20.0)
{
m_nearest_unsent_reset_timer = 0;
m_nearest_unsent_d = 0;
- /*infostream<<"Resetting m_nearest_unsent_d for "
- <getPlayerName(peer_id)<getPlayerName(peer_id)<getS16("max_block_generate_distance");
// Don't loop very much at a time
- if(d_max > d_start+1)
- d_max = d_start+1;
+ s16 max_d_increment_at_time = 2;
+ if(d_max > d_start + max_d_increment_at_time)
+ d_max = d_start + max_d_increment_at_time;
/*if(d_max_gen > d_start+2)
d_max_gen = d_start+2;*/
//infostream<<"Starting from "<getPlayerName(peer_id)<m_emerge_queue.addBlock(peer_id, p, flags);
server->m_emergethread.trigger();
+
+ if(nearest_emerged_d == -1)
+ nearest_emerged_d = d;
+ } else {
+ if(nearest_emergefull_d == -1)
+ nearest_emergefull_d = d;
}
// get next one.
continue;
}
+ if(nearest_sent_d == -1)
+ nearest_sent_d = d;
+
/*
Add block to send queue
*/
+ /*errorstream<<"sending from d="<getPlayerName(peer_id)< g_settings->getS16("max_block_send_distance")){
+ new_nearest_unsent_d = 0;
+ m_nothing_to_send_pause_timer = 2.0;
+ /*infostream<<"GetNextBlocks(): d wrapped around for "
+ <getPlayerName(peer_id)
+ <<"; setting to 0 and pausing"<=
- g_settings->getS16("max_block_send_distance"))
- {
- // Pause time in seconds
- m_nothing_to_send_pause_timer = 1.0;
- /*infostream<<"nothing to send to "
- <getPlayerName(peer_id)
- <<" (d="< players = server->m_env.getPlayers(true);
+ core::list players = server->m_env->getPlayers(true);
// Write player count
u16 playercount = players.size();
@@ -946,6 +949,35 @@ u32 PIChecksum(core::list &l)
return checksum;
}
+struct ModSpec
+{
+ std::string name;
+ std::string path;
+
+ ModSpec(const std::string &name_="", const std::string path_=""):
+ name(name_),
+ path(path_)
+ {}
+};
+
+static core::list getMods(core::list &modspaths)
+{
+ core::list mods;
+ for(core::list::Iterator i = modspaths.begin();
+ i != modspaths.end(); i++){
+ std::string modspath = *i;
+ std::vector dirlist = fs::GetDirListing(modspath);
+ for(u32 j=0; j mods = getMods(m_modspaths);
+ for(core::list::Iterator i = mods.begin();
+ i != mods.end(); i++){
+ ModSpec mod = *i;
+ infostream<<"Server: Loading mod \""<getMap().addEventReceiver(this);
// If file exists, load environment metadata
- if(fs::PathExists(m_mapsavedir+"/env_meta.txt"))
+ if(fs::PathExists(m_mapsavedir+DIR_DELIM+"env_meta.txt"))
{
infostream<<"Server: Loading environment metadata"<loadMeta(m_mapsavedir);
}
// Load players
infostream<<"Server: Loading players"<deSerializePlayers(m_mapsavedir);
}
Server::~Server()
@@ -1035,13 +1122,13 @@ Server::~Server()
Save players
*/
infostream<<"Server: Saving players"<serializePlayers(m_mapsavedir);
/*
Save environment metadata
*/
infostream<<"Server: Saving environment metadata"<saveMeta(m_mapsavedir);
}
/*
@@ -1064,13 +1151,23 @@ Server::~Server()
{
u16 peer_id = i.getNode()->getKey();
JMutexAutoLock envlock(m_env_mutex);
- m_env.removePlayer(peer_id);
+ m_env->removePlayer(peer_id);
}*/
// Delete client
delete i.getNode()->getValue();
}
}
+
+ // Delete Environment
+ delete m_env;
+
+ delete m_toolmgr;
+ delete m_nodedef;
+
+ // Deinitialize scripting
+ infostream<<"Server: Deinitializing scripting"<setTimeOfDay((m_env->getTimeOfDay() + units) % 24000);
//infostream<<"Server: m_time_of_day = "<getValue();
- //Player *player = m_env.getPlayer(client->peer_id);
+ //Player *player = m_env->getPlayer(client->peer_id);
SharedBuffer data = makePacket_TOCLIENT_TIME_OF_DAY(
- m_env.getTimeOfDay());
+ m_env->getTimeOfDay());
// Send as reliable
m_con.Send(client->peer_id, 0, data, true);
}
@@ -1215,16 +1312,16 @@ void Server::AsyncRunStep()
// Step environment
ScopeProfiler sp(g_profiler, "SEnv step");
ScopeProfiler sp2(g_profiler, "SEnv step avg", SPT_AVG);
- m_env.step(dtime);
+ m_env->step(dtime);
}
- const float map_timer_and_unload_dtime = 5.15;
+ const float map_timer_and_unload_dtime = 2.92;
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,
+ m_env->getMap().timerUpdate(map_timer_and_unload_dtime,
g_settings->getFloat("server_unload_unused_data_timeout"));
}
@@ -1245,13 +1342,13 @@ void Server::AsyncRunStep()
ScopeProfiler sp(g_profiler, "Server: liquid transform");
core::map modified_blocks;
- m_env.getMap().transformLiquids(modified_blocks);
+ m_env->getMap().transformLiquids(modified_blocks);
#if 0
/*
Update lighting
*/
core::map lighting_modified_blocks;
- ServerMap &map = ((ServerMap&)m_env.getMap());
+ ServerMap &map = ((ServerMap&)m_env->getMap());
map.updateLighting(modified_blocks, lighting_modified_blocks);
// Add blocks modified by lighting to modified_blocks
@@ -1301,7 +1398,7 @@ void Server::AsyncRunStep()
{
//u16 peer_id = i.getNode()->getKey();
RemoteClient *client = i.getNode()->getValue();
- Player *player = m_env.getPlayer(client->peer_id);
+ Player *player = m_env->getPlayer(client->peer_id);
if(player==NULL)
continue;
infostream<<"* "<getName()<<"\t";
@@ -1332,7 +1429,7 @@ void Server::AsyncRunStep()
i.atEnd() == false; i++)
{
RemoteClient *client = i.getNode()->getValue();
- Player *player = m_env.getPlayer(client->peer_id);
+ Player *player = m_env->getPlayer(client->peer_id);
if(player==NULL)
{
// This can happen if the client timeouts somehow
@@ -1345,9 +1442,9 @@ void Server::AsyncRunStep()
core::map removed_objects;
core::map added_objects;
- m_env.getRemovedActiveObjects(pos, radius,
+ m_env->getRemovedActiveObjects(pos, radius,
client->m_known_objects, removed_objects);
- m_env.getAddedActiveObjects(pos, radius,
+ m_env->getAddedActiveObjects(pos, radius,
client->m_known_objects, added_objects);
// Ignore if nothing happened
@@ -1370,7 +1467,7 @@ void Server::AsyncRunStep()
{
// Get object
u16 id = i.getNode()->getKey();
- ServerActiveObject* obj = m_env.getActiveObject(id);
+ ServerActiveObject* obj = m_env->getActiveObject(id);
// Add to data buffer for sending
writeU16((u8*)buf, i.getNode()->getKey());
@@ -1392,7 +1489,7 @@ void Server::AsyncRunStep()
{
// Get object
u16 id = i.getNode()->getKey();
- ServerActiveObject* obj = m_env.getActiveObject(id);
+ ServerActiveObject* obj = m_env->getActiveObject(id);
// Get object type
u8 type = ACTIVEOBJECT_TYPE_INVALID;
@@ -1458,7 +1555,7 @@ void Server::AsyncRunStep()
}
}
- m_env.setKnownActiveObjects(whatever);
+ m_env->setKnownActiveObjects(whatever);
#endif
}
@@ -1470,7 +1567,7 @@ void Server::AsyncRunStep()
JMutexAutoLock envlock(m_env_mutex);
JMutexAutoLock conlock(m_con_mutex);
- ScopeProfiler sp(g_profiler, "Server: sending object messages");
+ //ScopeProfiler sp(g_profiler, "Server: sending object messages");
// Key = object id
// Value = data sent by object
@@ -1479,7 +1576,7 @@ void Server::AsyncRunStep()
// Get active object messages from environment
for(;;)
{
- ActiveObjectMessage aom = m_env.getActiveObjectMessage();
+ ActiveObjectMessage aom = m_env->getActiveObjectMessage();
if(aom.id == 0)
break;
@@ -1668,7 +1765,7 @@ void Server::AsyncRunStep()
{
v3s16 p = i.getNode()->getKey();
modified_blocks2.insert(p,
- m_env.getMap().getBlockNoCreateNoEx(p));
+ m_env->getMap().getBlockNoCreateNoEx(p));
}
// Set blocks not sent
for(core::list::Iterator
@@ -1710,7 +1807,7 @@ void Server::AsyncRunStep()
JMutexAutoLock lock1(m_env_mutex);
JMutexAutoLock lock2(m_con_mutex);
- ScopeProfiler sp(g_profiler, "Server: sending player positions");
+ //ScopeProfiler sp(g_profiler, "Server: sending player positions");
SendObjectData(counter);
@@ -1755,15 +1852,15 @@ void Server::AsyncRunStep()
JMutexAutoLock lock(m_env_mutex);
/*// Unload unused data (delete from memory)
- m_env.getMap().unloadUnusedData(
+ m_env->getMap().unloadUnusedData(
g_settings->getFloat("server_unload_unused_sectors_timeout"));
*/
- /*u32 deleted_count = m_env.getMap().unloadUnusedData(
+ /*u32 deleted_count = m_env->getMap().unloadUnusedData(
g_settings->getFloat("server_unload_unused_sectors_timeout"));
*/
// Save only changed parts
- m_env.getMap().save(true);
+ m_env->getMap().save(true);
/*if(deleted_count > 0)
{
@@ -1772,10 +1869,10 @@ void Server::AsyncRunStep()
}*/
// Save players
- m_env.serializePlayers(m_mapsavedir);
+ m_env->serializePlayers(m_mapsavedir);
// Save environment metadata
- m_env.saveMeta(m_mapsavedir);
+ m_env->saveMeta(m_mapsavedir);
}
}
}
@@ -1783,14 +1880,13 @@ void Server::AsyncRunStep()
void Server::Receive()
{
DSTACK(__FUNCTION_NAME);
- u32 data_maxsize = 10000;
- Buffer data(data_maxsize);
+ SharedBuffer data;
u16 peer_id;
u32 datasize;
try{
{
JMutexAutoLock conlock(m_con_mutex);
- datasize = m_con.Receive(peer_id, *data, data_maxsize);
+ datasize = m_con.Receive(peer_id, data);
}
// This has to be called so that the client list gets synced
@@ -1818,7 +1914,7 @@ void Server::Receive()
<<" has apparently closed connection. "
<<"Removing player."<removePlayer(peer_id);*/
}
}
@@ -1829,9 +1925,18 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
JMutexAutoLock envlock(m_env_mutex);
JMutexAutoLock conlock(m_con_mutex);
- con::Peer *peer;
try{
- peer = m_con.GetPeer(peer_id);
+ Address address = m_con.GetPeerAddress(peer_id);
+
+ // drop player if is ip is banned
+ if(m_banmanager.isIpBanned(address.serializeString())){
+ SendAccessDenied(m_con, peer_id,
+ L"Your ip is banned. Banned name was "
+ +narrow_to_wide(m_banmanager.getBanName(
+ address.serializeString())));
+ m_con.DeletePeer(peer_id);
+ return;
+ }
}
catch(con::PeerNotFoundException &e)
{
@@ -1840,17 +1945,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
return;
}
- // drop player if is ip is banned
- if(m_banmanager.isIpBanned(peer->address.serializeString())){
- SendAccessDenied(m_con, peer_id,
- L"Your ip is banned. Banned name was "
- +narrow_to_wide(m_banmanager.getBanName(
- peer->address.serializeString())));
- m_con.deletePeer(peer_id, false);
- return;
- }
-
- u8 peer_ser_ver = getClient(peer->id)->serialization_version;
+ u8 peer_ser_ver = getClient(peer_id)->serialization_version;
try
{
@@ -1871,7 +1966,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
return;
infostream<<"Server: Got TOSERVER_INIT from "
- <id<serialization_version = deployed;
- getClient(peer->id)->pending_serialization_version = deployed;
+ getClient(peer_id)->pending_serialization_version = deployed;
if(deployed == SER_FMT_VER_INVALID)
{
@@ -1906,7 +2001,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
net_proto_version = readU16(&data[2+1+PLAYERNAME_SIZE+PASSWORD_SIZE]);
}
- getClient(peer->id)->net_proto_version = net_proto_version;
+ getClient(peer_id)->net_proto_version = net_proto_version;
if(net_proto_version == 0)
{
@@ -2034,7 +2129,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
writeU16(&reply[0], TOCLIENT_INIT);
writeU8(&reply[2], deployed);
writeV3S16(&reply[2+1], floatToInt(player->getPosition()+v3f(0,BS/2,0), BS));
- writeU64(&reply[2+1+6], m_env.getServerMap().getSeed());
+ writeU64(&reply[2+1+6], m_env->getServerMap().getSeed());
// Send as reliable
m_con.Send(peer_id, 0, reply, true);
@@ -2051,27 +2146,36 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
if(command == TOSERVER_INIT2)
{
infostream<<"Server: Got TOSERVER_INIT2 from "
- <id<id)->serialization_version
- = getClient(peer->id)->pending_serialization_version;
+ getClient(peer_id)->serialization_version
+ = getClient(peer_id)->pending_serialization_version;
/*
Send some initialization data
*/
+
+ // Send tool definitions
+ SendToolDef(m_con, peer_id, m_toolmgr);
+
+ // Send node definitions
+ SendNodeDef(m_con, peer_id, m_nodedef);
+
+ // Send textures
+ SendTextures(peer_id);
// Send player info to all players
SendPlayerInfos();
// Send inventory to player
- UpdateCrafting(peer->id);
- SendInventory(peer->id);
+ UpdateCrafting(peer_id);
+ SendInventory(peer_id);
// Send player items to all players
SendPlayerItems();
- Player *player = m_env.getPlayer(peer_id);
+ Player *player = m_env->getPlayer(peer_id);
// Send HP
SendPlayerHP(player);
@@ -2079,8 +2183,8 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
// Send time of day
{
SharedBuffer data = makePacket_TOCLIENT_TIME_OF_DAY(
- m_env.getTimeOfDay());
- m_con.Send(peer->id, 0, data, true);
+ m_env->getTimeOfDay());
+ m_con.Send(peer_id, 0, data, true);
}
// Send information about server to player in chat
@@ -2089,7 +2193,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
// Send information about joining in chat
{
std::wstring name = L"unknown";
- Player *player = m_env.getPlayer(peer_id);
+ Player *player = m_env->getPlayer(peer_id);
if(player != NULL)
name = narrow_to_wide(player->getName());
@@ -2101,7 +2205,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
}
// Warnings about protocol version can be issued here
- if(getClient(peer->id)->net_proto_version < PROTOCOL_VERSION)
+ if(getClient(peer_id)->net_proto_version < PROTOCOL_VERSION)
{
SendChatMessage(peer_id, L"# Server: WARNING: YOUR CLIENT IS OLD AND MAY WORK PROPERLY WITH THIS SERVER");
}
@@ -2125,7 +2229,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
if(client->serialization_version == SER_FMT_VER_INVALID)
continue;
// Get player
- Player *player = m_env.getPlayer(client->peer_id);
+ Player *player = m_env->getPlayer(client->peer_id);
if(!player)
continue;
// Get name of player
@@ -2147,7 +2251,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
return;
}
- Player *player = m_env.getPlayer(peer_id);
+ Player *player = m_env->getPlayer(peer_id);
if(player == NULL){
infostream<<"Server::ProcessData(): Cancelling: "
@@ -2255,7 +2359,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
u16 id = readS16(&data[3]);
u16 item_i = readU16(&data[5]);
- ServerActiveObject *obj = m_env.getActiveObject(id);
+ ServerActiveObject *obj = m_env->getActiveObject(id);
if(obj == NULL)
{
@@ -2269,10 +2373,23 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
return;
//TODO: Check that object is reasonably close
+
+ // Get ServerRemotePlayer
+ ServerRemotePlayer *srp = (ServerRemotePlayer*)player;
+
+ // Update wielded item
+ srp->wieldItem(item_i);
- // Left click, pick object up (usually)
+ // Left click, pick/punch
if(button == 0)
{
+ actionstream<getName()<<" punches object "
+ <getId()<punch(srp);
+
+#if 0
/*
Try creating inventory item
*/
@@ -2341,6 +2458,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
SendInventory(player->peer_id);
}
}
+#endif
}
// Right click, do something with object
if(button == 1)
@@ -2348,18 +2466,16 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
actionstream<getName()<<" right clicks object "
<getId()<hp;
-
// Do stuff
- obj->rightClick(player);
-
- // Send back stuff
- if(player->hp != oldhp)
- {
- SendPlayerHP(player);
- }
+ obj->rightClick(srp);
}
+
+ /*
+ Update player state to client
+ */
+ SendPlayerHP(player);
+ UpdateCrafting(player->peer_id);
+ SendInventory(player->peer_id);
}
else if(command == TOSERVER_GROUND_ACTION)
{
@@ -2400,6 +2516,33 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
NOTE: This can be used in the future to check if
somebody is cheating, by checking the timing.
*/
+ bool cannot_punch_node = false;
+
+ MapNode n(CONTENT_IGNORE);
+
+ try
+ {
+ n = m_env->getMap().getNode(p_under);
+ }
+ catch(InvalidPositionException &e)
+ {
+ infostream<<"Server: Not punching: Node not found."
+ <<" Adding block to emerge queue."
+ <id);
+ RemoteClient *client = getClient(peer_id);
JMutexAutoLock digmutex(client->m_dig_mutex);
client->m_dig_tool_item = -1;
#endif
@@ -2426,19 +2569,20 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
u8 mineral = MINERAL_NONE;
bool cannot_remove_node = false;
-
+
+ MapNode n(CONTENT_IGNORE);
try
{
- MapNode n = m_env.getMap().getNode(p_under);
+ n = m_env->getMap().getNode(p_under);
// Get mineral
- mineral = n.getMineral();
+ mineral = n.getMineral(m_nodedef);
// Get material at position
material = n.getContent();
// If not yet cancelled
if(cannot_remove_node == false)
{
// If it's not diggable, do nothing
- if(content_diggable(material) == false)
+ if(m_nodedef->get(material).diggable == false)
{
infostream<<"Server: Not finishing digging: "
<<"Node not diggable"
@@ -2450,7 +2594,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
if(cannot_remove_node == false)
{
// Get node metadata
- NodeMetadata *meta = m_env.getMap().getNodeMetadata(p_under);
+ NodeMetadata *meta = m_env->getMap().getNodeMetadata(p_under);
if(meta && meta->nodeRemovalDisabled() == true)
{
infostream<<"Server: Not finishing digging: "
@@ -2531,8 +2675,10 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
std::string toolname = titem->getToolName();
// Get digging properties for material and tool
+ ToolDiggingProperties tp =
+ m_toolmgr->getDiggingProperties(toolname);
DiggingProperties prop =
- getDiggingProperties(material, toolname);
+ getDiggingProperties(material, &tp, m_nodedef);
if(prop.diggable == false)
{
@@ -2557,16 +2703,16 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
InventoryItem *item = NULL;
if(mineral != MINERAL_NONE)
- item = getDiggedMineralItem(mineral);
+ item = getDiggedMineralItem(mineral, this);
// If not mineral
if(item == NULL)
{
- std::string &dug_s = content_features(material).dug_item;
+ const std::string &dug_s = m_nodedef->get(material).dug_item;
if(dug_s != "")
{
std::istringstream is(dug_s, std::ios::binary);
- item = InventoryItem::deSerialize(is);
+ item = InventoryItem::deSerialize(is, this);
}
}
@@ -2583,25 +2729,25 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
item = NULL;
if(mineral != MINERAL_NONE)
- item = getDiggedMineralItem(mineral);
+ item = getDiggedMineralItem(mineral, this);
// If not mineral
if(item == NULL)
{
- std::string &extra_dug_s = content_features(material).extra_dug_item;
- s32 extra_rarity = content_features(material).extra_dug_item_rarity;
+ const std::string &extra_dug_s = m_nodedef->get(material).extra_dug_item;
+ s32 extra_rarity = m_nodedef->get(material).extra_dug_item_rarity;
if(extra_dug_s != "" && extra_rarity != 0
&& myrand() % extra_rarity == 0)
{
- std::istringstream is(extra_dug_s, std::ios::binary);
- item = InventoryItem::deSerialize(is);
+ std::istringstream is(extra_dug_s, std::ios::binary);
+ item = InventoryItem::deSerialize(is, this);
}
}
if(item != NULL)
{
- // Add a item to inventory
- player->inventory.addItem("main", item);
+ // Add a item to inventory
+ player->inventory.addItem("main", item);
// Send inventory
UpdateCrafting(player->peer_id);
@@ -2616,7 +2762,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
{
MapEditEventIgnorer ign(&m_ignore_map_edit_events);
- m_env.getMap().removeNodeAndUpdate(p_under, modified_blocks);
+ m_env->getMap().removeNodeAndUpdate(p_under, modified_blocks);
}
/*
Set blocks not sent to far players
@@ -2631,6 +2777,12 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
continue;
client->SetBlocksNotSent(modified_blocks);
}
+
+ /*
+ Run script hook
+ */
+ ServerRemotePlayer *srp = (ServerRemotePlayer*)player;
+ scriptapi_environment_on_dignode(m_lua, p_under, n, srp);
}
/*
@@ -2657,7 +2809,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
{
try{
// Don't add a node if this is not a free space
- MapNode n2 = m_env.getMap().getNode(p_over);
+ MapNode n2 = m_env->getMap().getNode(p_over);
bool no_enough_privs =
((getPlayerPrivs(player) & PRIV_BUILD)==0);
if(no_enough_privs)
@@ -2665,7 +2817,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
<<" because privileges are "<get(n2).buildable_to == false
|| no_enough_privs)
{
// Client probably has wrong data.
@@ -2691,7 +2843,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
}
// Reset build time counter
- getClient(peer->id)->m_time_from_building = 0.0;
+ getClient(peer_id)->m_time_from_building = 0.0;
// Create node data
MaterialItem *mitem = (MaterialItem*)item;
@@ -2703,11 +2855,11 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
<<" at "<get(n).wall_mounted)
n.param2 = packDir(p_under - p_over);
// Calculate the direction for furnaces and chests and stuff
- if(content_features(n).param_type == CPT_FACEDIR_SIMPLE)
+ if(m_nodedef->get(n).param_type == CPT_FACEDIR_SIMPLE)
{
v3f playerpos = player->getPosition();
v3f blockpos = intToFloat(p_over, BS) - playerpos;
@@ -2758,7 +2910,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
MapEditEventIgnorer ign(&m_ignore_map_edit_events);
std::string p_name = std::string(player->getName());
- m_env.getMap().addNodeAndUpdate(p_over, n, modified_blocks, p_name);
+ m_env->getMap().addNodeAndUpdate(p_over, n, modified_blocks, p_name);
}
/*
Set blocks not sent to far players
@@ -2774,11 +2926,17 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
client->SetBlocksNotSent(modified_blocks);
}
+ /*
+ Run script hook
+ */
+ ServerRemotePlayer *srp = (ServerRemotePlayer*)player;
+ scriptapi_environment_on_placenode(m_lua, p_over, n, srp);
+
/*
Calculate special events
*/
- /*if(n.d == CONTENT_MESE)
+ /*if(n.d == LEGN(m_nodedef, "CONTENT_MESE"))
{
u32 count = 0;
for(s16 z=-1; z<=1; z++)
@@ -2800,7 +2958,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
Check that the block is loaded so that the item
can properly be added to the static list too
*/
- MapBlock *block = m_env.getMap().getBlockNoCreateNoEx(blockpos);
+ MapBlock *block = m_env->getMap().getBlockNoCreateNoEx(blockpos);
if(block==NULL)
{
infostream<<"Error while placing object: "
@@ -2823,15 +2981,15 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
// Calculate a position for it
v3f pos = intToFloat(p_over, BS);
//pos.Y -= BS*0.45;
- pos.Y -= BS*0.25; // let it drop a bit
+ /*pos.Y -= BS*0.25; // let it drop a bit
// Randomize a bit
pos.X += BS*0.2*(float)myrand_range(-1000,1000)/1000.0;
- pos.Z += BS*0.2*(float)myrand_range(-1000,1000)/1000.0;
+ pos.Z += BS*0.2*(float)myrand_range(-1000,1000)/1000.0;*/
/*
Create the object
*/
- ServerActiveObject *obj = item->createSAO(&m_env, 0, pos);
+ ServerActiveObject *obj = item->createSAO(m_env, 0, pos);
if(obj == NULL)
{
@@ -2845,7 +3003,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
<<" at "<addActiveObject(obj);
infostream<<"Placed object"<getMap().getNodeMetadata(p);
if(!meta)
return;
- if(meta->typeId() != CONTENT_SIGN_WALL)
+ if(meta->typeId() != LEGN(m_nodedef, "CONTENT_SIGN_WALL"))
return;
SignNodeMetadata *signmeta = (SignNodeMetadata*)meta;
signmeta->setText(text);
@@ -2944,19 +3102,14 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
<<" at "<getMap().getBlockNoCreateNoEx(blockpos);
if(block)
{
- block->setChangedFlag();
+ block->raiseModified(MOD_STATE_WRITE_NEEDED,
+ "sign node text");
}
- for(core::map::Iterator
- i = m_clients.getIterator();
- i.atEnd()==false; i++)
- {
- RemoteClient *client = i.getNode()->getValue();
- client->SetBlockNotSent(blockpos);
- }
+ setBlockNotSent(blockpos);
}
else if(command == TOSERVER_INVENTORY_ACTION)
{
@@ -3060,8 +3213,8 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
p.X = stoi(fn.next(","));
p.Y = stoi(fn.next(","));
p.Z = stoi(fn.next(","));
- NodeMetadata *meta = m_env.getMap().getNodeMetadata(p);
- if(meta && meta->typeId() == CONTENT_LOCKABLE_CHEST) {
+ NodeMetadata *meta = m_env->getMap().getNodeMetadata(p);
+ if(meta && meta->typeId() == LEGN(m_nodedef, "CONTENT_LOCKABLE_CHEST")) {
LockingChestNodeMetadata *lcm = (LockingChestNodeMetadata*)meta;
if (lcm->getOwner() != player->getName())
return;
@@ -3078,8 +3231,8 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
p.X = stoi(fn.next(","));
p.Y = stoi(fn.next(","));
p.Z = stoi(fn.next(","));
- NodeMetadata *meta = m_env.getMap().getNodeMetadata(p);
- if(meta && meta->typeId() == CONTENT_LOCKABLE_CHEST) {
+ NodeMetadata *meta = m_env->getMap().getNodeMetadata(p);
+ if(meta && meta->typeId() == LEGN(m_nodedef, "CONTENT_LOCKABLE_CHEST")) {
LockingChestNodeMetadata *lcm = (LockingChestNodeMetadata*)meta;
if (lcm->getOwner() != player->getName())
return;
@@ -3161,7 +3314,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
str_split(message, L' '),
paramstring,
this,
- &m_env,
+ m_env,
player,
privs);
@@ -3364,7 +3517,7 @@ Inventory* Server::getInventory(InventoryContext *c, std::string id)
p.X = stoi(fn.next(","));
p.Y = stoi(fn.next(","));
p.Z = stoi(fn.next(","));
- NodeMetadata *meta = m_env.getMap().getNodeMetadata(p);
+ NodeMetadata *meta = m_env->getMap().getNodeMetadata(p);
if(meta)
return meta->getInventory();
infostream<<"nodemeta at ("<getMap().getNodeMetadata(p);
if(meta)
meta->inventoryModified();
-
- for(core::map::Iterator
- i = m_clients.getIterator();
- i.atEnd()==false; i++)
- {
- RemoteClient *client = i.getNode()->getValue();
- client->SetBlockNotSent(blockpos);
- }
+
+ MapBlock *block = m_env->getMap().getBlockNoCreateNoEx(blockpos);
+ if(block)
+ block->raiseModified(MOD_STATE_WRITE_NEEDED);
+
+ setBlockNotSent(blockpos);
return;
}
@@ -3423,7 +3574,7 @@ core::list Server::getPlayerInfo()
core::list list;
- core::list players = m_env.getPlayers();
+ core::list players = m_env->getPlayers();
core::list::Iterator i;
for(i = players.begin();
@@ -3434,11 +3585,10 @@ core::list Server::getPlayerInfo()
Player *player = *i;
try{
- con::Peer *peer = m_con.GetPeer(player->peer_id);
- // Copy info from peer to info struct
- info.id = peer->id;
- info.address = peer->address;
- info.avg_rtt = peer->avg_rtt;
+ // Copy info from connection to info struct
+ info.id = player->peer_id;
+ info.address = m_con.GetPeerAddress(player->peer_id);
+ info.avg_rtt = m_con.GetPeerAvgRTT(player->peer_id);
}
catch(con::PeerNotFoundException &e)
{
@@ -3536,6 +3686,56 @@ void Server::SendDeathscreen(con::Connection &con, u16 peer_id,
con.Send(peer_id, 0, data, true);
}
+void Server::SendToolDef(con::Connection &con, u16 peer_id,
+ IToolDefManager *tooldef)
+{
+ DSTACK(__FUNCTION_NAME);
+ std::ostringstream os(std::ios_base::binary);
+
+ /*
+ u16 command
+ u32 length of the next item
+ serialized ToolDefManager
+ */
+ writeU16(os, TOCLIENT_TOOLDEF);
+ std::ostringstream tmp_os(std::ios::binary);
+ tooldef->serialize(tmp_os);
+ os< > texture_bunches;
+ texture_bunches.push_back(core::list());
+
+ u32 texture_size_bunch_total = 0;
+ core::list mods = getMods(m_modspaths);
+ for(core::list::Iterator i = mods.begin();
+ i != mods.end(); i++){
+ ModSpec mod = *i;
+ std::string texturepath = mod.path + DIR_DELIM + "textures";
+ std::vector dirlist = fs::GetDirListing(texturepath);
+ for(u32 j=0; j= bytes_per_bunch){
+ texture_bunches.push_back(core::list());
+ texture_size_bunch_total = 0;
+ }
+ }
+ }
+
+ /* Create and send packets */
+
+ u32 num_bunches = texture_bunches.size();
+ for(u32 i=0; i::Iterator
+ j = texture_bunches[i].begin();
+ j != texture_bunches[i].end(); j++){
+ os<name);
+ os<data);
+ }
+
+ // Make data buffer
+ std::string s = os.str();
+ infostream<<"Server::SendTextures(): bunch "<isSavingEnabled() == false)
+ if(((ServerMap*)(&m_env->getMap()))->isSavingEnabled() == false)
os<get("motd") != "")
os<get("motd"));
@@ -4130,18 +4458,58 @@ void Server::saveConfig()
void Server::notifyPlayer(const char *name, const std::wstring msg)
{
- Player *player = m_env.getPlayer(name);
+ Player *player = m_env->getPlayer(name);
if(!player)
return;
SendChatMessage(player->peer_id, std::wstring(L"Server: -!- ")+msg);
}
+void Server::notifyPlayers(const std::wstring msg)
+{
+ BroadcastChatMessage(msg);
+}
+
+// IGameDef interface
+// Under envlock
+IToolDefManager* Server::getToolDefManager()
+{
+ return m_toolmgr;
+}
+INodeDefManager* Server::getNodeDefManager()
+{
+ return m_nodedef;
+}
+ICraftDefManager* Server::getCraftDefManager()
+{
+ return m_craftdef;
+}
+ITextureSource* Server::getTextureSource()
+{
+ return NULL;
+}
+u16 Server::allocateUnknownNodeId(const std::string &name)
+{
+ return m_nodedef->allocateDummy(name);
+}
+
+IWritableToolDefManager* Server::getWritableToolDefManager()
+{
+ return m_toolmgr;
+}
+IWritableNodeDefManager* Server::getWritableNodeDefManager()
+{
+ return m_nodedef;
+}
+IWritableCraftDefManager* Server::getWritableCraftDefManager()
+{
+ return m_craftdef;
+}
+
v3f findSpawnPos(ServerMap &map)
{
//return v3f(50,50,50)*BS;
- v2s16 nodepos;
- s16 groundheight = 0;
+ v3s16 nodepos;
#if 0
nodepos = v2s16(0,0);
@@ -4154,13 +4522,11 @@ v3f findSpawnPos(ServerMap &map)
{
s32 range = 1 + i;
// We're going to try to throw the player to this position
- nodepos = v2s16(-range + (myrand()%(range*2)),
+ v2s16 nodepos2d = v2s16(-range + (myrand()%(range*2)),
-range + (myrand()%(range*2)));
- v2s16 sectorpos = getNodeSectorPos(nodepos);
- // Get sector (NOTE: Don't get because it's slow)
- //m_env.getMap().emergeSector(sectorpos);
+ //v2s16 sectorpos = getNodeSectorPos(nodepos2d);
// Get ground height at point (fallbacks to heightmap function)
- groundheight = map.findGroundLevel(nodepos);
+ s16 groundheight = map.findGroundLevel(nodepos2d);
// Don't go underwater
if(groundheight < WATER_LEVEL)
{
@@ -4173,22 +4539,33 @@ v3f findSpawnPos(ServerMap &map)
//infostream<<"-> Underwater"<= 2){
+ is_good = true;
+ nodepos.Y -= 1;
+ break;
+ }
+ }
+ nodepos.Y++;
+ }
+ if(is_good){
+ // Found a good place
+ //infostream<<"Searched through "<getPlayer(name);
if(player != NULL)
{
// If player is already connected, cancel
@@ -4217,7 +4594,7 @@ Player *Server::emergePlayer(const char *name, const char *password, u16 peer_id
player->inventory_backup = new Inventory();
*(player->inventory_backup) = player->inventory;
// Set creative inventory
- craft_set_creative_inventory(player);
+ craft_set_creative_inventory(player, this);
}
return player;
@@ -4226,7 +4603,7 @@ Player *Server::emergePlayer(const char *name, const char *password, u16 peer_id
/*
If player with the wanted peer_id already exists, cancel.
*/
- if(m_env.getPlayer(peer_id) != NULL)
+ if(m_env->getPlayer(peer_id) != NULL)
{
infostream<<"emergePlayer(): Player with wrong name but same"
" peer_id already exists"<peer_id = c.peer_id;
- //player->peer_id = PEER_ID_INEXISTENT;
- player->peer_id = peer_id;
- player->updateName(name);
+ // Add authentication stuff
m_authmanager.add(name);
m_authmanager.setPassword(name, password);
m_authmanager.setPrivs(name,
@@ -4252,17 +4625,17 @@ Player *Server::emergePlayer(const char *name, const char *password, u16 peer_id
*/
infostream<<"Server: Finding spawn place for player \""
- <getName()<<"\""<getServerMap());
- player->setPosition(pos);
+ player = new ServerRemotePlayer(m_env, pos, peer_id, name);
/*
Add player to environment
*/
- m_env.addPlayer(player);
+ m_env->addPlayer(player);
/*
Add stuff to inventory
@@ -4275,11 +4648,11 @@ Player *Server::emergePlayer(const char *name, const char *password, u16 peer_id
player->inventory_backup = new Inventory();
*(player->inventory_backup) = player->inventory;
// Set creative inventory
- craft_set_creative_inventory(player);
+ craft_set_creative_inventory(player, this);
}
else if(g_settings->getBool("give_initial_stuff"))
{
- craft_give_initial_stuff(player);
+ craft_give_initial_stuff(player, this);
}
return player;
@@ -4333,7 +4706,7 @@ void Server::handlePeerChange(PeerChange &c)
{
// Get object
u16 id = i.getNode()->getKey();
- ServerActiveObject* obj = m_env.getActiveObject(id);
+ ServerActiveObject* obj = m_env->getActiveObject(id);
if(obj && obj->m_known_by_count > 0)
obj->m_known_by_count--;
@@ -4342,7 +4715,7 @@ void Server::handlePeerChange(PeerChange &c)
// Collect information about leaving in chat
std::wstring message;
{
- Player *player = m_env.getPlayer(c.peer_id);
+ Player *player = m_env->getPlayer(c.peer_id);
if(player != NULL)
{
std::wstring name = narrow_to_wide(player->getName());
@@ -4356,12 +4729,12 @@ void Server::handlePeerChange(PeerChange &c)
/*// Delete player
{
- m_env.removePlayer(c.peer_id);
+ m_env->removePlayer(c.peer_id);
}*/
// Set player client disconnected
{
- Player *player = m_env.getPlayer(c.peer_id);
+ Player *player = m_env->getPlayer(c.peer_id);
if(player != NULL)
player->peer_id = 0;
@@ -4380,7 +4753,7 @@ void Server::handlePeerChange(PeerChange &c)
if(client->serialization_version == SER_FMT_VER_INVALID)
continue;
// Get player
- Player *player = m_env.getPlayer(client->peer_id);
+ Player *player = m_env->getPlayer(client->peer_id);
if(!player)
continue;
// Get name of player