diff --git a/src/client/client.cpp b/src/client/client.cpp index 0908e52f9..89873ade3 100644 --- a/src/client/client.cpp +++ b/src/client/client.cpp @@ -1313,7 +1313,7 @@ void Client::removeNode(v3s16 p) * @param is_valid_position * @return */ -MapNode Client::getNode(v3s16 p, bool *is_valid_position) +MapNode Client::CSMGetNode(v3s16 p, bool *is_valid_position) { if (checkCSMRestrictionFlag(CSMRestrictionFlags::CSM_RF_LOOKUP_NODES)) { v3s16 ppos = floatToInt(m_env.getLocalPlayer()->getPosition(), BS); @@ -1325,6 +1325,18 @@ MapNode Client::getNode(v3s16 p, bool *is_valid_position) return m_env.getMap().getNode(p, is_valid_position); } +int Client::CSMClampRadius(v3s16 pos, int radius) +{ + if (!checkCSMRestrictionFlag(CSMRestrictionFlags::CSM_RF_LOOKUP_NODES)) + return radius; + // This is approximate and will cause some allowed nodes to be excluded + v3s16 ppos = floatToInt(m_env.getLocalPlayer()->getPosition(), BS); + u32 distance = ppos.getDistanceFrom(pos); + if (distance >= m_csm_restriction_noderange) + return 0; + return std::min(radius, m_csm_restriction_noderange - distance); +} + void Client::addNode(v3s16 p, MapNode n, bool remove_metadata) { //TimeTaker timer1("Client::addNode()"); diff --git a/src/client/client.h b/src/client/client.h index 53b47edd0..5f3362509 100644 --- a/src/client/client.h +++ b/src/client/client.h @@ -261,14 +261,10 @@ public: // Causes urgent mesh updates (unlike Map::add/removeNodeWithEvent) void removeNode(v3s16 p); - /** - * Helper function for Client Side Modding - * CSM restrictions are applied there, this should not be used for core engine - * @param p - * @param is_valid_position - * @return - */ - MapNode getNode(v3s16 p, bool *is_valid_position); + // helpers to enforce CSM restrictions + MapNode CSMGetNode(v3s16 p, bool *is_valid_position); + int CSMClampRadius(v3s16 pos, int radius); + void addNode(v3s16 p, MapNode n, bool remove_metadata = true); void setPlayerControl(PlayerControl &control); diff --git a/src/script/lua_api/l_client.cpp b/src/script/lua_api/l_client.cpp index febf528de..08976ee11 100644 --- a/src/script/lua_api/l_client.cpp +++ b/src/script/lua_api/l_client.cpp @@ -36,6 +36,9 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "util/string.h" #include "nodedef.h" +#define checkCSMRestrictionFlag(flag) \ + ( getClient(L)->checkCSMRestrictionFlag(CSMRestrictionFlags::flag) ) + // get_current_modname() int ModApiClient::l_get_current_modname(lua_State *L) { @@ -106,11 +109,8 @@ int ModApiClient::l_send_chat_message(lua_State *L) // If server disabled this API, discard - // clang-format off - if (getClient(L)->checkCSMRestrictionFlag( - CSMRestrictionFlags::CSM_RF_CHAT_MESSAGES)) + if (checkCSMRestrictionFlag(CSM_RF_CHAT_MESSAGES)) return 0; - // clang-format on std::string message = luaL_checkstring(L, 1); getClient(L)->sendChatMessage(utf8_to_wide(message)); @@ -127,12 +127,8 @@ int ModApiClient::l_clear_out_chat_queue(lua_State *L) // get_player_names() int ModApiClient::l_get_player_names(lua_State *L) { - // clang-format off - if (getClient(L)->checkCSMRestrictionFlag( - CSMRestrictionFlags::CSM_RF_READ_PLAYERINFO)) { + if (checkCSMRestrictionFlag(CSM_RF_READ_PLAYERINFO)) return 0; - } - // clang-format on const std::list &plist = getClient(L)->getConnectedPlayerNames(); lua_createtable(L, plist.size(), 0); @@ -201,7 +197,7 @@ int ModApiClient::l_get_node_or_nil(lua_State *L) // Do it bool pos_ok; - MapNode n = getClient(L)->getNode(pos, &pos_ok); + MapNode n = getClient(L)->CSMGetNode(pos, &pos_ok); if (pos_ok) { // Return node pushnode(L, n, getClient(L)->ndef()); @@ -308,11 +304,8 @@ int ModApiClient::l_get_item_def(lua_State *L) IItemDefManager *idef = gdef->idef(); assert(idef); - // clang-format off - if (getClient(L)->checkCSMRestrictionFlag( - CSMRestrictionFlags::CSM_RF_READ_ITEMDEFS)) + if (checkCSMRestrictionFlag(CSM_RF_READ_ITEMDEFS)) return 0; - // clang-format on if (!lua_isstring(L, 1)) return 0; @@ -339,11 +332,8 @@ int ModApiClient::l_get_node_def(lua_State *L) if (!lua_isstring(L, 1)) return 0; - // clang-format off - if (getClient(L)->checkCSMRestrictionFlag( - CSMRestrictionFlags::CSM_RF_READ_NODEDEFS)) + if (checkCSMRestrictionFlag(CSM_RF_READ_NODEDEFS)) return 0; - // clang-format on std::string name = readParam(L, 1); const ContentFeatures &cf = ndef->get(ndef->getId(name)); diff --git a/src/script/lua_api/l_env.cpp b/src/script/lua_api/l_env.cpp index 8c2b6ffd8..203ffcfdc 100644 --- a/src/script/lua_api/l_env.cpp +++ b/src/script/lua_api/l_env.cpp @@ -769,11 +769,8 @@ int ModApiEnvMod::l_find_node_near(lua_State *L) #ifndef SERVER // Client API limitations - if (getClient(L) && - getClient(L)->checkCSMRestrictionFlag( - CSMRestrictionFlags::CSM_RF_LOOKUP_NODES)) { - radius = std::max(radius, getClient(L)->getCSMNodeRangeLimit()); - } + if (getClient(L)) + radius = getClient(L)->CSMClampRadius(pos, radius); #endif for (int d = start_radius; d <= radius; d++) {