diff options
Diffstat (limited to 'src/server.cpp')
-rw-r--r-- | src/server.cpp | 220 |
1 files changed, 58 insertions, 162 deletions
diff --git a/src/server.cpp b/src/server.cpp index 9f3db34d9..177551881 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -2377,13 +2377,6 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) */ if(a->getType() == IACTION_MOVE) { - InventoryList *rlist = player->inventory.getList("craftresult"); - assert(rlist); - InventoryList *clist = player->inventory.getList("craft"); - assert(clist); - InventoryList *mlist = player->inventory.getList("main"); - assert(mlist); - IMoveAction *ma = (IMoveAction*)a; ma->from_inv.applyCurrentPlayer(player->getName()); @@ -2398,98 +2391,36 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) (ma->to_inv.name == player->getName()); /* - Disable moving items into craftresult from elsewhere + Disable moving items out of craftpreview */ - if(to_inv_is_current_player - && ma->to_list == "craftresult" - && (!from_inv_is_current_player - || ma->from_list != "craftresult")) + if(ma->from_list == "craftpreview") { infostream<<"Ignoring IMoveAction from " <<(ma->from_inv.dump())<<":"<<ma->from_list <<" to "<<(ma->to_inv.dump())<<":"<<ma->to_list - <<" because dst is craftresult" - <<" and src isn't craftresult"<<std::endl; + <<" because src is "<<ma->from_list<<std::endl; delete a; return; } /* - Handle crafting (source is craftresult, which is preview) + Disable moving items into craftresult and craftpreview */ - if(from_inv_is_current_player - && ma->from_list == "craftresult" - && player->craftresult_is_preview - && g_settings->getBool("creative_mode") == false) + if(ma->to_list == "craftpreview" || ma->to_list == "craftresult") { - ItemStack crafting_result; - bool crafting_possible = GetCraftingResult(peer_id, - crafting_result, false); - - /* - If the craftresult is placed on itself, - crafting takes place and result is moved - into main list. - */ - if(crafting_possible - && to_inv_is_current_player - && ma->to_list == "craftresult") - { - if(mlist->roomForItem(crafting_result)) - { - actionstream<<player->getName() - <<" crafts " - <<crafting_result.getItemString() - <<std::endl; - - // Decrement crafting materials - GetCraftingResult(peer_id, crafting_result, true); - mlist->addItem(crafting_result); - rlist->clearItems(); - player->craftresult_is_preview = true; - srp->m_inventory_not_sent = true; - } - - } - /* - Otherwise, if the destination is part of - the same player's inventory, crafting - takes place normally. - */ - else if(crafting_possible - && to_inv_is_current_player) - { - InventoryList *list = player->inventory.getList(ma->to_list); - if(list && list->itemFits(ma->to_i, crafting_result)) - { - actionstream<<player->getName() - <<" crafts " - <<crafting_result.getItemString() - <<std::endl; - - // Decrement crafting materials - GetCraftingResult(peer_id, crafting_result, true); - list->addItem(ma->to_i, crafting_result); - rlist->clearItems(); - player->craftresult_is_preview = true; - srp->m_inventory_not_sent = true; - } - } - - // Do not apply the action normally. + infostream<<"Ignoring IMoveAction from " + <<(ma->from_inv.dump())<<":"<<ma->from_list + <<" to "<<(ma->to_inv.dump())<<":"<<ma->to_list + <<" because dst is "<<ma->to_list<<std::endl; delete a; return; } - /* - Non-crafting move - */ - // Disallow moving items in elsewhere than player's inventory // if not allowed to interact if((getPlayerPrivs(player) & PRIV_INTERACT) == 0 - && (from_inv_is_current_player - || to_inv_is_current_player)) + && (!from_inv_is_current_player + || !to_inv_is_current_player)) { infostream<<"Cannot move outside of player's inventory: " <<"No interact privilege"<<std::endl; @@ -2550,9 +2481,45 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) } } } + /* + Handle restrictions and special cases of the craft action + */ + else if(a->getType() == IACTION_CRAFT) + { + ICraftAction *ca = (ICraftAction*)a; + + ca->craft_inv.applyCurrentPlayer(player->getName()); + + //bool craft_inv_is_current_player = + // (ca->craft_inv.type == InventoryLocation::PLAYER) && + // (ca->craft_inv.name == player->getName()); + + // Disallow crafting if not allowed to interact + if((getPlayerPrivs(player) & PRIV_INTERACT) == 0) + { + infostream<<"Cannot craft: " + <<"No interact privilege"<<std::endl; + delete a; + return; + } + + // If player is not an admin, check for ownership of inventory + if((getPlayerPrivs(player) & PRIV_SERVER) == 0) + { + std::string owner_craft = getInventoryOwner(ca->craft_inv); + if(owner_craft != "" && owner_craft != player->getName()) + { + infostream<<"WARNING: "<<player->getName() + <<" tried to access an inventory that" + <<" belongs to "<<owner_craft<<std::endl; + delete a; + return; + } + } + } // Do the action - a->apply(this, srp); + a->apply(this, srp, this); // Eat the action delete a; } @@ -4049,95 +4016,24 @@ void Server::RespawnPlayer(Player *player) SendPlayerHP(player); } -bool Server::GetCraftingResult(u16 peer_id, ItemStack &result, bool decrementInput) -{ - DSTACK(__FUNCTION_NAME); - - Player* player = m_env->getPlayer(peer_id); - assert(player); - - // Get the crafting InventoryList of the player in which we will operate - InventoryList *clist = player->inventory.getList("craft"); - assert(clist); - - // Mangle crafting grid to an another format - CraftInput ci; - ci.method = CRAFT_METHOD_NORMAL; - ci.width = 3; - for(u16 i=0; i<9; i++) - { - ci.items.push_back(clist->getItem(i)); - } - - // Find out what is crafted and add it to result item slot - CraftOutput co; - bool found = m_craftdef->getCraftResult(ci, co, decrementInput, this); - if(found) - result.deSerialize(co.item, m_itemdef); - - if(decrementInput) - { - // CraftInput has been changed, apply changes in clist - for(u16 i=0; i<9; i++) - { - clist->changeItem(i, ci.items[i]); - } - } - - return found; -} - void Server::UpdateCrafting(u16 peer_id) { DSTACK(__FUNCTION_NAME); Player* player = m_env->getPlayer(peer_id); assert(player); - ServerRemotePlayer *srp = static_cast<ServerRemotePlayer*>(player); + // Get a preview for crafting + ItemStack preview; // No crafting in creative mode - if(g_settings->getBool("creative_mode")) - return; - - // Get the InventoryLists of the player in which we will operate - InventoryList *clist = player->inventory.getList("craft"); - assert(clist); - InventoryList *rlist = player->inventory.getList("craftresult"); - assert(rlist); - InventoryList *mlist = player->inventory.getList("main"); - assert(mlist); - - // If the result list is not a preview and is not empty, try to - // throw the item into main list - if(!player->craftresult_is_preview && rlist->getUsedSlots() != 0) - { - // Grab item out of craftresult - ItemStack item = rlist->changeItem(0, ItemStack()); - // Try to put in main - ItemStack leftover = mlist->addItem(item); - // If there are leftovers, put them back to craftresult - rlist->addItem(leftover); - // Inventory was modified - srp->m_inventory_not_sent = true; - } - - // If result list is empty, we will make it preview what would be - // crafted - if(rlist->getUsedSlots() == 0) - player->craftresult_is_preview = true; - - // If it is a preview, find out what is the crafting result - // and put it in - if(player->craftresult_is_preview) - { - // Clear the possible old preview in it - rlist->clearItems(); - - // Put the new preview in - ItemStack crafting_result; - if(GetCraftingResult(peer_id, crafting_result, false)) - rlist->addItem(crafting_result); - } + if(g_settings->getBool("creative_mode") == false) + getCraftingResult(&player->inventory, preview, false, this); + + // Put the new preview in + InventoryList *plist = player->inventory.getList("craftpreview"); + assert(plist); + assert(plist->getSize() >= 1); + plist->changeItem(0, preview); } RemoteClient* Server::getClient(u16 peer_id) |