aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJude Melton-Houghton <jwmhjwmh@gmail.com>2022-09-03 22:05:07 -0400
committerJude Melton-Houghton <jwmhjwmh@gmail.com>2022-12-24 08:24:59 -0500
commit5c248c2d7de3db54e85f7c388743a2eb8e36fee4 (patch)
treeb0d27690b3e852b207345dc5e00dc4457a7e6268 /src
parent7701e70dc92262c41d68cf1c9f7fbd0c333e5c52 (diff)
downloadminetest-5c248c2d7de3db54e85f7c388743a2eb8e36fee4.tar.xz
Add callback on_mapblocks_changed
Diffstat (limited to 'src')
-rw-r--r--src/script/common/c_converter.h9
-rw-r--r--src/script/cpp_api/s_env.cpp33
-rw-r--r--src/script/cpp_api/s_env.h7
-rw-r--r--src/serverenvironment.cpp25
-rw-r--r--src/serverenvironment.h16
5 files changed, 87 insertions, 3 deletions
diff --git a/src/script/common/c_converter.h b/src/script/common/c_converter.h
index 2af726d16..f1e4e47ec 100644
--- a/src/script/common/c_converter.h
+++ b/src/script/common/c_converter.h
@@ -121,3 +121,12 @@ void warn_if_field_exists(lua_State *L, int table,
size_t write_array_slice_float(lua_State *L, int table_index, float *data,
v3u16 data_size, v3u16 slice_offset, v3u16 slice_size);
+
+// This must match the implementation in builtin/game/misc_s.lua
+// Note that this returns a floating point result as Lua integers are 32-bit
+inline lua_Number hash_node_position(v3s16 pos)
+{
+ return (((s64)pos.Z + 0x8000L) << 32)
+ | (((s64)pos.Y + 0x8000L) << 16)
+ | ((s64)pos.X + 0x8000L);
+}
diff --git a/src/script/cpp_api/s_env.cpp b/src/script/cpp_api/s_env.cpp
index e49113405..3cbb13cd2 100644
--- a/src/script/cpp_api/s_env.cpp
+++ b/src/script/cpp_api/s_env.cpp
@@ -299,3 +299,36 @@ void ScriptApiEnv::on_liquid_transformed(
runCallbacks(2, RUN_CALLBACKS_MODE_FIRST);
}
+
+void ScriptApiEnv::on_mapblocks_changed(const std::unordered_set<v3s16> &set)
+{
+ SCRIPTAPI_PRECHECKHEADER
+
+ // Get core.registered_on_mapblocks_changed
+ lua_getglobal(L, "core");
+ lua_getfield(L, -1, "registered_on_mapblocks_changed");
+ luaL_checktype(L, -1, LUA_TTABLE);
+ lua_remove(L, -2);
+
+ // Convert the set to a set of position hashes
+ lua_createtable(L, 0, set.size());
+ for(const v3s16 &p : set) {
+ lua_pushnumber(L, hash_node_position(p));
+ lua_pushboolean(L, true);
+ lua_rawset(L, -3);
+ }
+ lua_pushinteger(L, set.size());
+
+ runCallbacks(2, RUN_CALLBACKS_MODE_FIRST);
+}
+
+bool ScriptApiEnv::has_on_mapblocks_changed()
+{
+ SCRIPTAPI_PRECHECKHEADER
+
+ // Get core.registered_on_mapblocks_changed
+ lua_getglobal(L, "core");
+ lua_getfield(L, -1, "registered_on_mapblocks_changed");
+ luaL_checktype(L, -1, LUA_TTABLE);
+ return lua_objlen(L, -1) > 0;
+}
diff --git a/src/script/cpp_api/s_env.h b/src/script/cpp_api/s_env.h
index 9a50a01cc..bc4c4cd4d 100644
--- a/src/script/cpp_api/s_env.h
+++ b/src/script/cpp_api/s_env.h
@@ -22,6 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "cpp_api/s_base.h"
#include "irr_v3d.h"
#include "mapnode.h"
+#include <unordered_set>
#include <vector>
class ServerEnvironment;
@@ -48,5 +49,11 @@ public:
// Called after liquid transform changes
void on_liquid_transformed(const std::vector<std::pair<v3s16, MapNode>> &list);
+ // Called after mapblock changes
+ void on_mapblocks_changed(const std::unordered_set<v3s16> &set);
+
+ // Determines whether there are any on_mapblocks_changed callbacks
+ bool has_on_mapblocks_changed();
+
void initializeEnvironment(ServerEnvironment *env);
};
diff --git a/src/serverenvironment.cpp b/src/serverenvironment.cpp
index 9dd5ba621..aa6ba2f96 100644
--- a/src/serverenvironment.cpp
+++ b/src/serverenvironment.cpp
@@ -382,6 +382,18 @@ void ActiveBlockList::update(std::vector<PlayerSAO*> &active_players,
}
/*
+ OnMapblocksChangedReceiver
+*/
+
+void OnMapblocksChangedReceiver::onMapEditEvent(const MapEditEvent &event)
+{
+ assert(receiving);
+ for (const v3s16 &p : event.modified_blocks) {
+ modified_blocks.insert(p);
+ }
+}
+
+/*
ServerEnvironment
*/
@@ -476,6 +488,11 @@ void ServerEnvironment::init()
m_player_database = openPlayerDatabase(player_backend_name, m_path_world, conf);
m_auth_database = openAuthDatabase(auth_backend_name, m_path_world, conf);
+
+ if (m_map && m_script->has_on_mapblocks_changed()) {
+ m_map->addEventReceiver(&m_on_mapblocks_changed_receiver);
+ m_on_mapblocks_changed_receiver.receiving = true;
+ }
}
ServerEnvironment::~ServerEnvironment()
@@ -1570,6 +1587,14 @@ void ServerEnvironment::step(float dtime)
// Send outdated detached inventories
m_server->sendDetachedInventories(PEER_ID_INEXISTENT, true);
+ // Notify mods of modified mapblocks
+ if (m_on_mapblocks_changed_receiver.receiving &&
+ !m_on_mapblocks_changed_receiver.modified_blocks.empty()) {
+ std::unordered_set<v3s16> modified_blocks;
+ std::swap(modified_blocks, m_on_mapblocks_changed_receiver.modified_blocks);
+ m_script->on_mapblocks_changed(modified_blocks);
+ }
+
const auto end_time = porting::getTimeUs();
m_step_time_counter->increment(end_time - start_time);
}
diff --git a/src/serverenvironment.h b/src/serverenvironment.h
index 5c4b23f40..bb40a33ce 100644
--- a/src/serverenvironment.h
+++ b/src/serverenvironment.h
@@ -21,7 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "activeobject.h"
#include "environment.h"
-#include "mapnode.h"
+#include "map.h"
#include "settings.h"
#include "server/activeobjectmgr.h"
#include "util/numeric.h"
@@ -30,9 +30,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <random>
class IGameDef;
-class ServerMap;
struct GameParams;
-class MapBlock;
class RemotePlayer;
class PlayerDatabase;
class AuthDatabase;
@@ -194,6 +192,16 @@ public:
};
/*
+ ServerEnvironment::m_on_mapblocks_changed_receiver
+*/
+struct OnMapblocksChangedReceiver : public MapEventReceiver {
+ std::unordered_set<v3s16> modified_blocks;
+ bool receiving = false;
+
+ void onMapEditEvent(const MapEditEvent &event) override;
+};
+
+/*
Operation mode for ServerEnvironment::clearObjects()
*/
enum ClearObjectsMode {
@@ -455,6 +463,8 @@ private:
Server *m_server;
// Active Object Manager
server::ActiveObjectMgr m_ao_manager;
+ // on_mapblocks_changed map event receiver
+ OnMapblocksChangedReceiver m_on_mapblocks_changed_receiver;
// World path
const std::string m_path_world;
// Outgoing network message buffer for active objects