X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fserver.cpp;h=6d34a0fac1dd89f323f5775463714385f11a661f;hb=61ffe1eac4565bbb74b79677a618e7f4dd894d3c;hp=330ce21c2c912cdeccd8e6e8c78d74f7df6c3538;hpb=0b97ad838466ed44296a2c663b2dc034feb51f67;p=dragonfireclient.git diff --git a/src/server.cpp b/src/server.cpp index 330ce21c2..6d34a0fac 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -41,6 +41,9 @@ with this program; if not, write to the Free Software Foundation, Inc., #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<<")" @@ -685,7 +688,11 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime, //if(server->m_emerge_queue.peerItemCount(peer_id) < 1) // Allow two blocks in queue per client //if(server->m_emerge_queue.peerItemCount(peer_id) < 2) - if(server->m_emerge_queue.peerItemCount(peer_id) < 25) + u32 max_emerge = 25; + // Make it more responsive when needing to generate stuff + if(surely_not_found_on_disk) + max_emerge = 5; + if(server->m_emerge_queue.peerItemCount(peer_id) < max_emerge) { //infostream<<"Adding block to emerge queue"< &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 \""<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); @@ -2090,6 +2155,15 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) /* 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(); @@ -2299,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 */ @@ -2371,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) @@ -2378,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) { @@ -2430,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." + <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" @@ -2561,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) { @@ -2587,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); } } @@ -2613,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); @@ -2661,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); } /* @@ -2695,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. @@ -2733,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; @@ -2804,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++) @@ -2965,7 +3093,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) NodeMetadata *meta = m_env->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); @@ -2977,16 +3105,11 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) MapBlock *block = m_env->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) { @@ -3091,7 +3214,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) p.Y = stoi(fn.next(",")); p.Z = stoi(fn.next(",")); NodeMetadata *meta = m_env->getMap().getNodeMetadata(p); - if(meta && meta->typeId() == CONTENT_LOCKABLE_CHEST) { + if(meta && meta->typeId() == LEGN(m_nodedef, "CONTENT_LOCKABLE_CHEST")) { LockingChestNodeMetadata *lcm = (LockingChestNodeMetadata*)meta; if (lcm->getOwner() != player->getName()) return; @@ -3109,7 +3232,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) p.Y = stoi(fn.next(",")); p.Z = stoi(fn.next(",")); NodeMetadata *meta = m_env->getMap().getNodeMetadata(p); - if(meta && meta->typeId() == CONTENT_LOCKABLE_CHEST) { + if(meta && meta->typeId() == LEGN(m_nodedef, "CONTENT_LOCKABLE_CHEST")) { LockingChestNodeMetadata *lcm = (LockingChestNodeMetadata*)meta; if (lcm->getOwner() != player->getName()) return; @@ -3430,14 +3553,12 @@ void Server::inventoryModified(InventoryContext *c, std::string id) NodeMetadata *meta = m_env->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; } @@ -3565,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 "<