Inventory: Add ServerEnv checks for calls during script init

This fixes 'minetest.get_inventory' calls to players or nodes during the load phase.
This commit is contained in:
SmallJoker 2022-01-04 18:39:27 +01:00
parent 1965628705
commit d33ab97434

@ -39,24 +39,29 @@ ServerInventoryManager::~ServerInventoryManager()
Inventory *ServerInventoryManager::getInventory(const InventoryLocation &loc) Inventory *ServerInventoryManager::getInventory(const InventoryLocation &loc)
{ {
// No m_env check here: allow creation and modification of detached inventories
switch (loc.type) { switch (loc.type) {
case InventoryLocation::UNDEFINED: case InventoryLocation::UNDEFINED:
case InventoryLocation::CURRENT_PLAYER: case InventoryLocation::CURRENT_PLAYER:
break; break;
case InventoryLocation::PLAYER: { case InventoryLocation::PLAYER: {
if (!m_env)
return nullptr;
RemotePlayer *player = m_env->getPlayer(loc.name.c_str()); RemotePlayer *player = m_env->getPlayer(loc.name.c_str());
if (!player) if (!player)
return NULL; return NULL;
PlayerSAO *playersao = player->getPlayerSAO(); PlayerSAO *playersao = player->getPlayerSAO();
if (!playersao) return playersao ? playersao->getInventory() : nullptr;
return NULL;
return playersao->getInventory();
} break; } break;
case InventoryLocation::NODEMETA: { case InventoryLocation::NODEMETA: {
if (!m_env)
return nullptr;
NodeMetadata *meta = m_env->getMap().getNodeMetadata(loc.p); NodeMetadata *meta = m_env->getMap().getNodeMetadata(loc.p);
if (!meta) return meta ? meta->getInventory() : nullptr;
return NULL;
return meta->getInventory();
} break; } break;
case InventoryLocation::DETACHED: { case InventoryLocation::DETACHED: {
auto it = m_detached_inventories.find(loc.name); auto it = m_detached_inventories.find(loc.name);
@ -151,12 +156,13 @@ bool ServerInventoryManager::removeDetachedInventory(const std::string &name)
const std::string &owner = inv_it->second.owner; const std::string &owner = inv_it->second.owner;
if (!owner.empty()) { if (!owner.empty()) {
if (m_env) {
RemotePlayer *player = m_env->getPlayer(owner.c_str()); RemotePlayer *player = m_env->getPlayer(owner.c_str());
if (player && player->getPeerId() != PEER_ID_INEXISTENT) if (player && player->getPeerId() != PEER_ID_INEXISTENT)
m_env->getGameDef()->sendDetachedInventory( m_env->getGameDef()->sendDetachedInventory(
nullptr, name, player->getPeerId()); nullptr, name, player->getPeerId());
}
} else if (m_env) { } else if (m_env) {
// Notify all players about the change as soon ServerEnv exists // Notify all players about the change as soon ServerEnv exists
m_env->getGameDef()->sendDetachedInventory( m_env->getGameDef()->sendDetachedInventory(