+
+ /*
+ Non-crafting move
+ */
+
+ // Disallow moving items in elsewhere than player's inventory
+ // if not allowed to build
+ if((getPlayerPrivs(player) & PRIV_BUILD) == 0
+ && (ma->from_inv != "current_player"
+ || ma->to_inv != "current_player"))
+ {
+ infostream<<"Cannot move outside of player's inventory: "
+ <<"No build privilege"<<std::endl;
+ delete a;
+ return;
+ }
+
+ // If player is not an admin, check for ownership of src
+ if(ma->from_inv != "current_player"
+ && (getPlayerPrivs(player) & PRIV_SERVER) == 0)
+ {
+ Strfnd fn(ma->from_inv);
+ std::string id0 = fn.next(":");
+ if(id0 == "nodemeta")
+ {
+ v3s16 p;
+ p.X = stoi(fn.next(","));
+ p.Y = stoi(fn.next(","));
+ p.Z = stoi(fn.next(","));
+ NodeMetadata *meta = m_env->getMap().getNodeMetadata(p);
+ if(meta->getOwner() != "" &&
+ meta->getOwner() != player->getName())
+ {
+ infostream<<"Cannot move item: "
+ "not owner of metadata"
+ <<std::endl;
+ delete a;
+ return;
+ }
+ }
+ }
+ // If player is not an admin, check for ownership of dst
+ if(ma->to_inv != "current_player"
+ && (getPlayerPrivs(player) & PRIV_SERVER) == 0)
+ {
+ Strfnd fn(ma->to_inv);
+ std::string id0 = fn.next(":");
+ if(id0 == "nodemeta")
+ {
+ v3s16 p;
+ p.X = stoi(fn.next(","));
+ p.Y = stoi(fn.next(","));
+ p.Z = stoi(fn.next(","));
+ NodeMetadata *meta = m_env->getMap().getNodeMetadata(p);
+ if(meta->getOwner() != "" &&
+ meta->getOwner() != player->getName())
+ {
+ infostream<<"Cannot move item: "
+ "not owner of metadata"
+ <<std::endl;
+ delete a;
+ return;
+ }
+ }
+ }
+ }
+ /*
+ Handle restrictions and special cases of the drop action
+ */
+ else if(a->getType() == IACTION_DROP)
+ {
+ IDropAction *da = (IDropAction*)a;
+ // Disallow dropping items if not allowed to build
+ if((getPlayerPrivs(player) & PRIV_BUILD) == 0)
+ {
+ delete a;
+ return;
+ }
+ // If player is not an admin, check for ownership
+ else if (da->from_inv != "current_player"
+ && (getPlayerPrivs(player) & PRIV_SERVER) == 0)
+ {
+ Strfnd fn(da->from_inv);
+ std::string id0 = fn.next(":");
+ if(id0 == "nodemeta")
+ {
+ v3s16 p;
+ p.X = stoi(fn.next(","));
+ p.Y = stoi(fn.next(","));
+ p.Z = stoi(fn.next(","));
+ NodeMetadata *meta = m_env->getMap().getNodeMetadata(p);
+ if(meta->getOwner() != "" &&
+ meta->getOwner() != player->getName())
+ {
+ infostream<<"Cannot move item: "
+ "not owner of metadata"
+ <<std::endl;
+ delete a;
+ return;
+ }
+ }
+ }
+ }
+
+ // Do the action
+ a->apply(&c, this, m_env);
+ // Eat the action
+ delete a;
+ }
+ else if(command == TOSERVER_CHAT_MESSAGE)
+ {
+ /*
+ u16 command
+ u16 length
+ wstring message
+ */
+ u8 buf[6];
+ std::string datastring((char*)&data[2], datasize-2);
+ std::istringstream is(datastring, std::ios_base::binary);
+
+ // Read stuff
+ is.read((char*)buf, 2);
+ u16 len = readU16(buf);
+
+ std::wstring message;
+ for(u16 i=0; i<len; i++)
+ {
+ is.read((char*)buf, 2);
+ message += (wchar_t)readU16(buf);
+ }
+
+ // Get player name of this client
+ std::wstring name = narrow_to_wide(player->getName());
+
+ // Run script hook
+ bool ate = scriptapi_on_chat_message(m_lua, player->getName(),
+ wide_to_narrow(message));
+ // If script ate the message, don't proceed
+ if(ate)
+ return;
+
+ // Line to send to players
+ std::wstring line;
+ // Whether to send to the player that sent the line
+ bool send_to_sender = false;
+ // Whether to send to other players
+ bool send_to_others = false;
+
+ // Local player gets all privileges regardless of
+ // what's set on their account.
+ u64 privs = getPlayerPrivs(player);
+
+ // Parse commands
+ if(message[0] == L'/')
+ {
+ size_t strip_size = 1;
+ if (message[1] == L'#') // support old-style commans
+ ++strip_size;
+ message = message.substr(strip_size);
+
+ WStrfnd f1(message);
+ f1.next(L" "); // Skip over /#whatever
+ std::wstring paramstring = f1.next(L"");
+
+ ServerCommandContext *ctx = new ServerCommandContext(
+ str_split(message, L' '),
+ paramstring,
+ this,
+ m_env,
+ player,
+ privs);
+
+ std::wstring reply(processServerCommand(ctx));
+ send_to_sender = ctx->flags & SEND_TO_SENDER;
+ send_to_others = ctx->flags & SEND_TO_OTHERS;
+
+ if (ctx->flags & SEND_NO_PREFIX)
+ line += reply;
+ else
+ line += L"Server: " + reply;
+
+ delete ctx;
+