aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTest_User <hax@andrewyu.org>2024-06-28 08:00:00 +0800
committerRunxi Yu <me@runxiyu.org>2024-06-28 08:00:00 +0800
commit11c7849bdf53557bc327fee06bddbbf1e23c4512 (patch)
treea90dba953d7cc9584c979ad3b6772f55c58f42ed
parent53dd648c96b899b706f30de656896713d7e8ff08 (diff)
downloadhax-minetest-server-11c7849bdf53557bc327fee06bddbbf1e23c4512.tar.gz
hax-minetest-server-11c7849bdf53557bc327fee06bddbbf1e23c4512.zip
Hax's version of Minetest Server 5.6.0
-rw-r--r--.gitignore2
-rw-r--r--AppImageBuilder.yml54
-rw-r--r--[-rwxr-xr-x]android/gradlew0
-rwxr-xr-x[-rw-r--r--]builtin/common/information_formspecs.lua4
-rw-r--r--builtin/common/misc_helpers.lua1
-rw-r--r--builtin/common/vector.lua8
-rw-r--r--builtin/game/register.lua20
-rw-r--r--[-rwxr-xr-x]doc/mkdocs/build.sh0
-rwxr-xr-x[l---------]doc/mkdocs/docs/img/favicon.icobin34 -> 9662 bytes
-rw-r--r--src/craftdef.cpp1
-rw-r--r--src/emerge.cpp54
-rw-r--r--src/inventorymanager.cpp80
-rw-r--r--src/map.cpp36
-rw-r--r--src/map.h22
-rw-r--r--src/mapblock.h7
-rw-r--r--src/mapgen/dungeongen.cpp40
-rw-r--r--src/mapnode.h2
-rw-r--r--src/mapsector.cpp51
-rw-r--r--src/mapsector.h18
-rw-r--r--src/network/connection.cpp24
-rw-r--r--src/network/connectionthreads.cpp4
-rw-r--r--src/network/serverpackethandler.cpp21
-rw-r--r--src/script/cpp_api/s_player.cpp58
-rw-r--r--src/script/cpp_api/s_player.h9
-rw-r--r--src/script/cpp_api/s_security.cpp20
-rw-r--r--src/script/lua_api/l_env.cpp78
-rw-r--r--src/script/lua_api/l_env.h3
-rw-r--r--src/script/lua_api/l_object.cpp10
-rw-r--r--src/script/lua_api/l_server.cpp2
-rw-r--r--src/script/lua_api/l_util.cpp2
-rw-r--r--src/server.cpp43
-rw-r--r--src/server/luaentity_sao.cpp2
-rw-r--r--src/server/mods.cpp15
-rw-r--r--src/server/unit_sao.cpp5
-rw-r--r--src/serverenvironment.cpp3
-rw-r--r--src/serverlist.cpp22
-rw-r--r--[-rwxr-xr-x]src/util/png.cpp0
-rwxr-xr-x[-rw-r--r--]src/util/pointedthing.cpp6
-rw-r--r--src/util/pointedthing.h4
-rw-r--r--[-rwxr-xr-x]util/buildbot/buildwin32.sh0
40 files changed, 489 insertions, 242 deletions
diff --git a/.gitignore b/.gitignore
index bb5e0a0cd..0d6af9f93 100644
--- a/.gitignore
+++ b/.gitignore
@@ -117,3 +117,5 @@ lib/irrlichtmt
# Generated mod storage database
client/mod_storage.sqlite
+
+times.txt
diff --git a/AppImageBuilder.yml b/AppImageBuilder.yml
deleted file mode 100644
index 5788e246b..000000000
--- a/AppImageBuilder.yml
+++ /dev/null
@@ -1,54 +0,0 @@
-version: 1
-
-AppDir:
- path: ./AppDir
-
- app_info:
- id: minetest
- name: Minetest
- icon: minetest
- version: !ENV ${VERSION}
- exec: usr/bin/minetest
- exec_args: $@
- runtime:
- env:
- APPDIR_LIBRARY_PATH: $APPDIR/usr/lib/x86_64-linux-gnu
-
- apt:
- arch: amd64
- sources:
- - sourceline: deb http://archive.ubuntu.com/ubuntu/ bionic main universe
- key_url: 'http://keyserver.ubuntu.com/pks/lookup?op=get&search=0x3b4fe6acc0b21f32'
- - sourceline: deb http://archive.ubuntu.com/ubuntu/ bionic-updates main universe
- - sourceline: deb http://archive.ubuntu.com/ubuntu/ bionic-backports main universe
- - sourceline: deb http://archive.ubuntu.com/ubuntu/ bionic-security main universe
-
- include:
- - libc6
- - libcurl3-gnutls
- - libfreetype6
- - libgl1
- - libjpeg-turbo8
- - libjsoncpp1
- - libleveldb1v5
- - libopenal1
- - libpng16-16
- - libsqlite3-0
- - libstdc++6
- - libvorbisfile3
- - libx11-6
- - libxxf86vm1
- - zlib1g
-
- files:
- exclude:
- - usr/share/man
- - usr/share/doc/*/README.*
- - usr/share/doc/*/changelog.*
- - usr/share/doc/*/NEWS.*
- - usr/share/doc/*/TODO.*
-
-AppImage:
- update-information: None
- sign-key: None
- arch: x86_64
diff --git a/android/gradlew b/android/gradlew
index 25e0c1148..25e0c1148 100755..100644
--- a/android/gradlew
+++ b/android/gradlew
diff --git a/builtin/common/information_formspecs.lua b/builtin/common/information_formspecs.lua
index 1445a017c..d4426aff4 100644..100755
--- a/builtin/common/information_formspecs.lua
+++ b/builtin/common/information_formspecs.lua
@@ -57,11 +57,11 @@ local function build_chatcommands_formspec(name, sel, copy)
.. "any entry in the list.").. "\n" ..
S("Double-click to copy the entry to the chat history.")
- local privs = core.get_player_privs(name)
+ local check_player_privs = core.check_player_privs
for i, data in ipairs(mod_cmds) do
rows[#rows + 1] = COLOR_BLUE .. ",0," .. F(data[1]) .. ","
for j, cmds in ipairs(data[2]) do
- local has_priv = privs[cmds[2].privs]
+ local has_priv = check_player_privs(name, cmds[2].privs)
rows[#rows + 1] = ("%s,1,%s,%s"):format(
has_priv and COLOR_GREEN or COLOR_GRAY,
cmds[1], F(cmds[2].params))
diff --git a/builtin/common/misc_helpers.lua b/builtin/common/misc_helpers.lua
index 467f18804..a8ec5817a 100644
--- a/builtin/common/misc_helpers.lua
+++ b/builtin/common/misc_helpers.lua
@@ -5,6 +5,7 @@
local string_sub, string_find = string.sub, string.find
--------------------------------------------------------------------------------
+
local function basic_dump(o)
local tp = type(o)
if tp == "number" then
diff --git a/builtin/common/vector.lua b/builtin/common/vector.lua
index a08472e32..b662f73fc 100644
--- a/builtin/common/vector.lua
+++ b/builtin/common/vector.lua
@@ -125,6 +125,14 @@ function vector.distance(a, b)
return math.sqrt(x * x + y * y + z * z)
end
+-- square roots are expensive
+function vector.distance_sq(a, b)
+ local x = a.x - b.x
+ local y = a.y - b.y
+ local z = a.z - b.z
+ return x * x + y * y + z * z
+end
+
function vector.direction(pos1, pos2)
return vector.subtract(pos2, pos1):normalize()
end
diff --git a/builtin/game/register.lua b/builtin/game/register.lua
index ee4edabbf..08856dc17 100644
--- a/builtin/game/register.lua
+++ b/builtin/game/register.lua
@@ -181,6 +181,7 @@ function core.register_item(name, itemdef)
--core.log("Registering item: " .. itemdef.name)
core.registered_items[itemdef.name] = itemdef
core.registered_aliases[itemdef.name] = nil
+
register_item_raw(itemdef)
end
@@ -207,6 +208,14 @@ end
function core.register_node(name, nodedef)
nodedef.type = "node"
+ if nodedef.use_texture_alpha == true then
+ nodedef.use_texture_alpha = "blend"
+ elseif nodedef.use_texture_alpha == false then
+ nodedef.use_texture_alpha = "opaque"
+ end
+ if nodedef.tile_images then
+ nodedef.tiles = nodedef.tile_images
+ end
core.register_item(name, nodedef)
end
@@ -305,14 +314,14 @@ function core.on_craft(itemstack, player, old_craft_list, craft_inv)
for _, func in ipairs(core.registered_on_crafts) do
itemstack = func(itemstack, player, old_craft_list, craft_inv) or itemstack
end
- return itemstack
+ return ItemStack(itemstack)
end
function core.craft_predict(itemstack, player, old_craft_list, craft_inv)
for _, func in ipairs(core.registered_craft_predicts) do
itemstack = func(itemstack, player, old_craft_list, craft_inv) or itemstack
end
- return itemstack
+ return ItemStack(itemstack)
end
-- Alias the forbidden item names to "" so they can't be
@@ -424,6 +433,7 @@ function core.run_callbacks(callbacks, mode, ...)
end
local ret = nil
for i = 1, cb_len do
+ local start_time = os.clock()
local origin = core.callback_origins[callbacks[i]]
core.set_last_run_mod(origin.mod)
local cb_ret = callbacks[i](...)
@@ -615,9 +625,15 @@ core.registered_on_player_inventory_actions, core.register_on_player_inventory_a
core.registered_allow_player_inventory_actions, core.register_allow_player_inventory_action = make_registration()
core.registered_on_rightclickplayers, core.register_on_rightclickplayer = make_registration()
core.registered_on_liquid_transformed, core.register_on_liquid_transformed = make_registration()
+core.registered_on_player_change_wield, core.register_on_player_change_wield = make_registration()
+core.registered_on_player_change_keys, core.register_on_player_change_keys = make_registration()
--
-- Compatibility for on_mapgen_init()
--
core.register_on_mapgen_init = function(func) func(core.get_mapgen_params()) end
+core.register_on_mods_loaded(function()
+ print(time_taken_a, time_taken_b)
+-- error("e")
+end)
diff --git a/doc/mkdocs/build.sh b/doc/mkdocs/build.sh
index f4d946874..f4d946874 100755..100644
--- a/doc/mkdocs/build.sh
+++ b/doc/mkdocs/build.sh
diff --git a/doc/mkdocs/docs/img/favicon.ico b/doc/mkdocs/docs/img/favicon.ico
index cac34a30c..82af67bf9 120000..100755
--- a/doc/mkdocs/docs/img/favicon.ico
+++ b/doc/mkdocs/docs/img/favicon.ico
Binary files differ
diff --git a/src/craftdef.cpp b/src/craftdef.cpp
index c05a0cfb7..30b1307b1 100644
--- a/src/craftdef.cpp
+++ b/src/craftdef.cpp
@@ -230,6 +230,7 @@ static void craftDecrementOrReplaceInput(CraftInput &input,
item.remove(1);
found_replacement = true;
output_replacements.push_back(rep);
+ pairs.erase(j);
break;
}
diff --git a/src/emerge.cpp b/src/emerge.cpp
index 3e42742f6..28b286c24 100644
--- a/src/emerge.cpp
+++ b/src/emerge.cpp
@@ -592,18 +592,19 @@ bool EmergeThread::popBlockEmerge(v3s16 *pos, BlockEmergeData *bedata)
EmergeAction EmergeThread::getBlockOrStartGen(
const v3s16 &pos, bool allow_gen, MapBlock **block, BlockMakeData *bmdata)
{
- MutexAutoLock envlock(m_server->m_env_mutex);
-
// 1). Attempt to fetch block from memory
*block = m_map->getBlockNoCreateNoEx(pos);
+
if (*block && !(*block)->isDummy()) {
- if ((*block)->isGenerated())
+ if ((*block)->isGenerated()) {
return EMERGE_FROM_MEMORY;
+ }
} else {
// 2). Attempt to load block from disk if it was not in the memory
*block = m_map->loadBlock(pos);
- if (*block && (*block)->isGenerated())
+ if (*block && (*block)->isGenerated()) {
return EMERGE_FROM_DISK;
+ }
}
// 3). Attempt to start generation
@@ -618,7 +619,6 @@ EmergeAction EmergeThread::getBlockOrStartGen(
MapBlock *EmergeThread::finishGen(v3s16 pos, BlockMakeData *bmdata,
std::map<v3s16, MapBlock *> *modified_blocks)
{
- MutexAutoLock envlock(m_server->m_env_mutex);
ScopeProfiler sp(g_profiler,
"EmergeThread: after Mapgen::makeChunk", SPT_AVG);
@@ -697,34 +697,38 @@ void *EmergeThread::run()
continue;
}
- if (blockpos_over_max_limit(pos))
- continue;
+ {
+ MutexAutoLock envlock(m_server->m_env_mutex);
+ if (blockpos_over_max_limit(pos))
+ continue;
+
+ bool allow_gen = bedata.flags & BLOCK_EMERGE_ALLOW_GEN;
+ EMERGE_DBG_OUT("pos=" PP(pos) " allow_gen=" << allow_gen);
- bool allow_gen = bedata.flags & BLOCK_EMERGE_ALLOW_GEN;
- EMERGE_DBG_OUT("pos=" PP(pos) " allow_gen=" << allow_gen);
+ action = getBlockOrStartGen(pos, allow_gen, &block, &bmdata);
+ if (action == EMERGE_GENERATED) {
+ {
+ ScopeProfiler sp(g_profiler,
+ "EmergeThread: Mapgen::makeChunk", SPT_AVG);
- action = getBlockOrStartGen(pos, allow_gen, &block, &bmdata);
- if (action == EMERGE_GENERATED) {
- {
- ScopeProfiler sp(g_profiler,
- "EmergeThread: Mapgen::makeChunk", SPT_AVG);
+ m_mapgen->makeChunk(&bmdata);
+ }
- m_mapgen->makeChunk(&bmdata);
+ block = finishGen(pos, &bmdata, &modified_blocks);
+ if (!block)
+ action = EMERGE_ERRORED;
}
- block = finishGen(pos, &bmdata, &modified_blocks);
- if (!block)
- action = EMERGE_ERRORED;
- }
+ runCompletionCallbacks(pos, action, bedata.callbacks);
- runCompletionCallbacks(pos, action, bedata.callbacks);
+ if (block)
+ modified_blocks[pos] = block;
- if (block)
- modified_blocks[pos] = block;
+ if (!modified_blocks.empty())
+ m_server->SetBlocksNotSent(modified_blocks);
- if (!modified_blocks.empty())
- m_server->SetBlocksNotSent(modified_blocks);
- modified_blocks.clear();
+ modified_blocks.clear();
+ }
}
} catch (VersionMismatchException &e) {
std::ostringstream err;
diff --git a/src/inventorymanager.cpp b/src/inventorymanager.cpp
index ecdb56a97..b3dd84b74 100644
--- a/src/inventorymanager.cpp
+++ b/src/inventorymanager.cpp
@@ -378,6 +378,15 @@ void IMoveAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame
// Move action within the same inventory
src_can_take_count = allowMove(src_item.count, player);
+ inv_from = mgr->getInventory(from_inv);
+ inv_to = mgr->getInventory(to_inv);
+ if (!inv_from || !inv_to)
+ return;
+ list_from = inv_from->getList(from_list);
+ list_to = inv_to->getList(to_list);
+ if (!list_from || !list_to)
+ return;
+
bool swap_expected = allow_swap;
allow_swap = allow_swap
&& (src_can_take_count == -1 || src_can_take_count >= src_item.count);
@@ -385,6 +394,7 @@ void IMoveAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame
int try_put_count = list_to->getItem(to_i).count;
swapDirections();
dst_can_put_count = allowMove(try_put_count, player);
+
allow_swap = allow_swap
&& (dst_can_put_count == -1 || dst_can_put_count >= try_put_count);
swapDirections();
@@ -402,6 +412,16 @@ void IMoveAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame
src_item.count = move_count;
dst_can_put_count = allowPut(src_item, player);
src_can_take_count = allowTake(src_item, player);
+
+ inv_from = mgr->getInventory(from_inv);
+ inv_to = mgr->getInventory(to_inv);
+ if (!inv_from || !inv_to)
+ return;
+ list_from = inv_from->getList(from_list);
+ list_to = inv_to->getList(to_list);
+ if (!list_from || !list_to)
+ return;
+
if (caused_by_move_somewhere)
// Reset source item count
src_item.count = src_item_count;
@@ -416,7 +436,27 @@ void IMoveAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame
swapDirections();
int src_can_take = allowPut(dst_item, player);
+
+ inv_from = mgr->getInventory(from_inv);
+ inv_to = mgr->getInventory(to_inv);
+ if (!inv_from || !inv_to)
+ return;
+ list_from = inv_from->getList(from_list);
+ list_to = inv_to->getList(to_list);
+ if (!list_from || !list_to)
+ return;
+
int dst_can_put = allowTake(dst_item, player);
+
+ inv_from = mgr->getInventory(from_inv);
+ inv_to = mgr->getInventory(to_inv);
+ if (!inv_from || !inv_to)
+ return;
+ list_from = inv_from->getList(from_list);
+ list_to = inv_to->getList(to_list);
+ if (!list_from || !list_to)
+ return;
+
allow_swap = allow_swap
&& (src_can_take == -1 || src_can_take >= dst_item.count)
&& (dst_can_put == -1 || dst_can_put >= dst_item.count);
@@ -465,6 +505,15 @@ void IMoveAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame
return;
}
+ inv_from = mgr->getInventory(from_inv);
+ inv_to = mgr->getInventory(to_inv);
+ if (!inv_from || !inv_to)
+ return;
+ list_from = inv_from->getList(from_list);
+ list_to = inv_to->getList(to_list);
+ if (!list_from || !list_to)
+ return;
+
src_item = list_from->getItem(from_i);
src_item.count = count;
ItemStack from_stack_was = list_from->getItem(from_i);
@@ -576,11 +625,20 @@ void IMoveAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame
onMove(count, player);
if (did_swap) {
// Item is now placed in source list
+
+ inv_from = mgr->getInventory(from_inv);
+ if (!inv_from)
+ return;
+ list_from = inv_from->getList(from_list);
+ if (!list_from)
+ return;
+
src_item = list_from->getItem(from_i);
swapDirections();
onMove(src_item.count, player);
swapDirections();
}
+
mgr->setInventoryModified(from_inv);
} else {
int src_item_count = src_item.count;
@@ -594,6 +652,14 @@ void IMoveAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame
src_item.count = src_item_count;
if (did_swap) {
// Item is now placed in source list
+
+ inv_from = mgr->getInventory(from_inv);
+ if (!inv_from)
+ return;
+ list_from = inv_from->getList(from_list);
+ if (!list_from)
+ return;
+
src_item = list_from->getItem(from_i);
swapDirections();
onPutAndOnTake(src_item, player);
@@ -721,6 +787,15 @@ void IDropAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame
if (src_can_take_count != -1 && src_can_take_count < take_count)
take_count = src_can_take_count;
+ // Inventory references may be stale
+ inv_from = mgr->getInventory(from_inv);
+ if (!inv_from)
+ return;
+
+ list_from = inv_from->getList(from_list);
+ if (!list_from)
+ return;
+
// Update item due executed callbacks
src_item = list_from->getItem(from_i);
@@ -935,11 +1010,12 @@ void ICraftAction::apply(InventoryManager *mgr,
output_replacement = list_main->addItem(output_replacement);
if (output_replacement.empty())
continue;
- u16 count = output_replacement.count;
+ u16 count;
do {
+ count = output_replacement.count;
PLAYER_TO_SA(player)->item_OnDrop(output_replacement, player,
player->getBasePosition());
- if (count >= output_replacement.count) {
+ if (count <= output_replacement.count) {
errorstream << "Couldn't drop replacement stack " <<
output_replacement.getItemString() << " because drop loop didn't "
"decrease count." << std::endl;
diff --git a/src/map.cpp b/src/map.cpp
index a53680065..58443a000 100644
--- a/src/map.cpp
+++ b/src/map.cpp
@@ -57,7 +57,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "database/database-postgresql.h"
#endif
-
/*
Map
*/
@@ -146,25 +145,6 @@ bool Map::isValidPosition(v3s16 p)
return (block != NULL);
}
-// Returns a CONTENT_IGNORE node if not found
-MapNode Map::getNode(v3s16 p, bool *is_valid_position)
-{
- v3s16 blockpos = getNodeBlockPos(p);
- MapBlock *block = getBlockNoCreateNoEx(blockpos);
- if (block == NULL) {
- if (is_valid_position != NULL)
- *is_valid_position = false;
- return {CONTENT_IGNORE};
- }
-
- v3s16 relpos = p - blockpos*MAP_BLOCKSIZE;
- bool is_valid_p;
- MapNode node = block->getNodeNoCheck(relpos, &is_valid_p);
- if (is_valid_position != NULL)
- *is_valid_position = is_valid_p;
- return node;
-}
-
static void set_node_in_block(MapBlock *block, v3s16 relpos, MapNode n)
{
// Never allow placing CONTENT_IGNORE, it causes problems
@@ -942,8 +922,9 @@ NodeMetadata *Map::getNodeMetadata(v3s16 p)
block = emergeBlock(blockpos, false);
}
if(!block){
- warningstream<<"Map::getNodeMetadata(): Block not found"
- <<std::endl;
+ // bleh pipeworks
+// warningstream<<"Map::getNodeMetadata(): Block not found"
+// <<std::endl;
return NULL;
}
NodeMetadata *meta = block->m_node_metadata.get(p_rel);
@@ -961,8 +942,9 @@ bool Map::setNodeMetadata(v3s16 p, NodeMetadata *meta)
block = emergeBlock(blockpos, false);
}
if(!block){
- warningstream<<"Map::setNodeMetadata(): Block not found"
- <<std::endl;
+ // bleh pipeworks
+// warningstream<<"Map::setNodeMetadata(): Block not found"
+// <<std::endl;
return false;
}
block->m_node_metadata.set(p_rel, meta);
@@ -1919,6 +1901,9 @@ MMVManip::MMVManip(Map *map):
assert(map);
}
+static_assert(sizeof(content_t) == 2 && (MAP_BLOCKSIZE/2)*2 == MAP_BLOCKSIZE, "This code will break, please rewrite.");
+static_assert(sizeof(wchar_t) == 4, "Stop using Windows");
+
void MMVManip::initialEmerge(v3s16 blockpos_min, v3s16 blockpos_max,
bool load_if_inexistent)
{
@@ -1989,6 +1974,9 @@ void MMVManip::initialEmerge(v3s16 blockpos_min, v3s16 blockpos_max,
{
s32 i = m_area.index(a.MinEdge.X,y,z);
memset(&m_flags[i], VOXELFLAG_NO_DATA, MAP_BLOCKSIZE);
+
+// RELEVANT PROBLEMATIC LINE
+ wmemset((wchar_t*)&m_data[i], (((uint32_t)CONTENT_IGNORE)<<16)|CONTENT_IGNORE, MAP_BLOCKSIZE/2);
}
}
}
diff --git a/src/map.h b/src/map.h
index 6bc2aaaee..833d750eb 100644
--- a/src/map.h
+++ b/src/map.h
@@ -27,6 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "irrlichttypes_bloated.h"
#include "mapnode.h"
+#include "mapblock.h"
#include "constants.h"
#include "voxel.h"
#include "modifiedstate.h"
@@ -49,6 +50,7 @@ class EmergeManager;
class MetricsBackend;
class ServerEnvironment;
struct BlockMakeData;
+class Server;
/*
MapEditEvent
@@ -166,7 +168,23 @@ public:
// Returns a CONTENT_IGNORE node if not found
// If is_valid_position is not NULL then this will be set to true if the
// position is valid, otherwise false
- MapNode getNode(v3s16 p, bool *is_valid_position = NULL);
+ inline MapNode getNode(v3s16 p, bool *is_valid_position = NULL)
+ {
+ v3s16 blockpos = getNodeBlockPos(p);
+ MapBlock *block = getBlockNoCreateNoEx(blockpos);
+ if (block == NULL) {
+ if (is_valid_position != NULL)
+ *is_valid_position = false;
+ return {CONTENT_IGNORE};
+ }
+
+ v3s16 relpos = p - blockpos*MAP_BLOCKSIZE;
+ bool is_valid_p;
+ MapNode node = block->getNodeNoCheck(relpos, &is_valid_p);
+ if (is_valid_position != NULL)
+ *is_valid_position = is_valid_p;
+ return node;
+ }
/*
These handle lighting but not faces.
@@ -261,7 +279,7 @@ public:
*/
bool isBlockOccluded(MapBlock *block, v3s16 cam_pos_nodes);
-protected:
+//protected:
IGameDef *m_gamedef;
std::set<MapEventReceiver*> m_event_receivers;
diff --git a/src/mapblock.h b/src/mapblock.h
index a86db7b70..18048bc1a 100644
--- a/src/mapblock.h
+++ b/src/mapblock.h
@@ -466,7 +466,7 @@ public:
void serializeNetworkSpecific(std::ostream &os);
void deSerializeNetworkSpecific(std::istream &is);
-private:
+//private:
/*
Private methods
*/
@@ -490,7 +490,7 @@ private:
return getNodeRef(p.X, p.Y, p.Z);
}
-public:
+//public:
/*
Public member variables
*/
@@ -515,8 +515,7 @@ public:
bool contents_cached = false;
// True if we never want to cache content types for this block
bool do_not_cache_contents = false;
-
-private:
+//private:
/*
Private member variables
*/
diff --git a/src/mapgen/dungeongen.cpp b/src/mapgen/dungeongen.cpp
index 1d439abeb..17ad31f31 100644
--- a/src/mapgen/dungeongen.cpp
+++ b/src/mapgen/dungeongen.cpp
@@ -93,29 +93,31 @@ void DungeonGen::generate(MMVManip *vm, u32 bseed, v3s16 nmin, v3s16 nmax)
// Dungeon generator doesn't modify places which have this set
vm->clearFlag(VMANIP_FLAG_DUNGEON_INSIDE | VMANIP_FLAG_DUNGEON_PRESERVE);
- if (dp.only_in_ground) {
- // Set all air and liquid drawtypes to be untouchable to make dungeons generate
- // in ground only.
- // Set 'ignore' to be untouchable to prevent generation in ungenerated neighbor
- // mapchunks, to avoid dungeon rooms generating outside ground.
- // Like randomwalk caves, preserve nodes that have 'is_ground_content = false',
- // to avoid dungeons that generate out beyond the edge of a mapchunk destroying
- // nodes added by mods in 'register_on_generated()'.
- for (s16 z = nmin.Z; z <= nmax.Z; z++) {
- for (s16 y = nmin.Y; y <= nmax.Y; y++) {
- u32 i = vm->m_area.index(nmin.X, y, z);
- for (s16 x = nmin.X; x <= nmax.X; x++) {
- content_t c = vm->m_data[i].getContent();
- NodeDrawType dtype = ndef->get(c).drawtype;
- if (dtype == NDT_AIRLIKE || dtype == NDT_LIQUID ||
- c == CONTENT_IGNORE || !ndef->get(c).is_ground_content)
- vm->m_flags[i] |= VMANIP_FLAG_DUNGEON_PRESERVE;
- i++;
- }
+// if (dp.only_in_ground) {
+
+ // Set all air and liquid drawtypes to be untouchable to make dungeons generate
+ // in ground only.
+ // Set 'ignore' to be untouchable to prevent generation in ungenerated neighbor
+ // mapchunks, to avoid dungeon rooms generating outside ground.
+ // Like randomwalk caves, preserve nodes that have 'is_ground_content = false',
+ // to avoid dungeons that generate out beyond the edge of a mapchunk destroying
+ // nodes added by mods in 'register_on_generated()'.
+ for (s16 z = nmin.Z; z <= nmax.Z; z++) {
+ for (s16 y = nmin.Y; y <= nmax.Y; y++) {
+ u32 i = vm->m_area.index(nmin.X, y, z);
+ for (s16 x = nmin.X; x <= nmax.X; x++) {
+ content_t c = vm->m_data[i].getContent();
+ NodeDrawType dtype = ndef->get(c).drawtype;
+ if (dtype == NDT_AIRLIKE || dtype == NDT_LIQUID ||
+ c == CONTENT_IGNORE || !ndef->get(c).is_ground_content)
+ vm->m_flags[i] |= VMANIP_FLAG_DUNGEON_PRESERVE;
+ i++;
}
}
}
+// }
+
// Add them
for (u32 i = 0; i < dp.num_dungeons; i++)
makeDungeon(v3s16(1, 1, 1) * MAP_BLOCKSIZE);
diff --git a/src/mapnode.h b/src/mapnode.h
index afd3a96be..793b10f5d 100644
--- a/src/mapnode.h
+++ b/src/mapnode.h
@@ -42,7 +42,7 @@ typedef u16 content_t;
there is enough room for dummy node IDs, which are created when
a MapBlock containing unknown node names is loaded from disk.
*/
-#define MAX_REGISTERED_CONTENT 0x7fffU
+#define MAX_REGISTERED_CONTENT 0xf800U
/*
A solid walkable node with the texture unknown_node.png.
diff --git a/src/mapsector.cpp b/src/mapsector.cpp
index 3eefa5410..4060864bd 100644
--- a/src/mapsector.cpp
+++ b/src/mapsector.cpp
@@ -27,54 +27,40 @@ MapSector::MapSector(Map *parent, v2s16 pos, IGameDef *gamedef):
m_pos(pos),
m_gamedef(gamedef)
{
+ for (s16 i = -65536/MAP_BLOCKSIZE/2; i < 65536/MAP_BLOCKSIZE/2; i++) {
+ m_blocks[i] = nullptr;
+ }
+ m_blocks_used = 0;
}
MapSector::~MapSector()
{
deleteBlocks();
+ free(&m_blocks[-65536/MAP_BLOCKSIZE/2]);
}
void MapSector::deleteBlocks()
{
- // Clear cache
- m_block_cache = nullptr;
-
// Delete all
- for (auto &block : m_blocks) {
- delete block.second;
+ for (s16 i = -65536/MAP_BLOCKSIZE/2; i < 65536/MAP_BLOCKSIZE/2; i++) {
+ if (m_blocks[i])
+ delete m_blocks[i];
}
-
- // Clear container
- m_blocks.clear();
}
MapBlock * MapSector::getBlockBuffered(s16 y)
{
- MapBlock *block;
-
- if (m_block_cache && y == m_block_cache_y) {
- return m_block_cache;
- }
-
- // If block doesn't exist, return NULL
- std::unordered_map<s16, MapBlock*>::const_iterator n = m_blocks.find(y);
- block = (n != m_blocks.end() ? n->second : nullptr);
-
- // Cache the last result
- m_block_cache_y = y;
- m_block_cache = block;
-
- return block;
+ return m_blocks[y];
}
MapBlock * MapSector::getBlockNoCreateNoEx(s16 y)
{
- return getBlockBuffered(y);
+ return (y > -2048 && y < 2047) ? getBlockBuffered(y) : nullptr;
}
MapBlock * MapSector::createBlankBlockNoInsert(s16 y)
{
- assert(getBlockBuffered(y) == NULL); // Pre-condition
+ assert(getBlockBuffered(y) == nullptr); // Pre-condition
v3s16 blockpos_map(m_pos.X, y, m_pos.Y);
@@ -88,6 +74,7 @@ MapBlock * MapSector::createBlankBlock(s16 y)
MapBlock *block = createBlankBlockNoInsert(y);
m_blocks[y] = block;
+ m_blocks_used++;
return block;
}
@@ -106,17 +93,18 @@ void MapSector::insertBlock(MapBlock *block)
// Insert into container
m_blocks[block_y] = block;
+ m_blocks_used++;
}
void MapSector::deleteBlock(MapBlock *block)
{
s16 block_y = block->getPos().Y;
- // Clear from cache
- m_block_cache = nullptr;
-
// Remove from container
- m_blocks.erase(block_y);
+ if (m_blocks[block_y]) {
+ m_blocks_used--;
+ m_blocks[block_y] = nullptr;
+ }
// Delete
delete block;
@@ -124,7 +112,8 @@ void MapSector::deleteBlock(MapBlock *block)
void MapSector::getBlocks(MapBlockVect &dest)
{
- for (auto &block : m_blocks) {
- dest.push_back(block.second);
+ for (s16 i = -65536/MAP_BLOCKSIZE/2; i < 65536/MAP_BLOCKSIZE/2; i++) {
+ if (m_blocks[i])
+ dest.push_back(m_blocks[i]);
}
}
diff --git a/src/mapsector.h b/src/mapsector.h
index ffd4cdd1d..7ebf9b413 100644
--- a/src/mapsector.h
+++ b/src/mapsector.h
@@ -39,7 +39,6 @@ class IGameDef;
class MapSector
{
public:
-
MapSector(Map *parent, v2s16 pos, IGameDef *gamedef);
virtual ~MapSector();
@@ -60,13 +59,14 @@ public:
void getBlocks(MapBlockVect &dest);
- bool empty() const { return m_blocks.empty(); }
+ bool empty() const { return m_blocks_used == 0; }
+
+ int size() const { return m_blocks_used; }
- int size() const { return m_blocks.size(); }
-protected:
+ // The array of MapBlocks
+ MapBlock** m_blocks = ((MapBlock**)malloc(65536*sizeof(*m_blocks)/MAP_BLOCKSIZE)) + 65536/MAP_BLOCKSIZE/2;
- // The pile of MapBlocks
- std::unordered_map<s16, MapBlock*> m_blocks;
+ u16 m_blocks_used = 0;
Map *m_parent;
// Position on parent (in MapBlock widths)
@@ -74,14 +74,8 @@ protected:
IGameDef *m_gamedef;
- // Last-used block is cached here for quicker access.
- // Be sure to set this to nullptr when the cached block is deleted
- MapBlock *m_block_cache = nullptr;
- s16 m_block_cache_y;
-
/*
Private methods
*/
MapBlock *getBlockBuffered(s16 y);
-
};
diff --git a/src/network/connection.cpp b/src/network/connection.cpp
index 6fb676f25..f2cdbe435 100644
--- a/src/network/connection.cpp
+++ b/src/network/connection.cpp
@@ -1040,7 +1040,9 @@ bool UDPPeer::processReliableSendCommand(
- BASE_HEADER_SIZE
- RELIABLE_HEADER_SIZE;
- sanity_check(c.data.getSize() < MAX_RELIABLE_WINDOW_SIZE*512);
+ if (c.data.getSize() >= MAX_RELIABLE_WINDOW_SIZE*512)
+ return false;
+// sanity_check(c.data.getSize() < MAX_RELIABLE_WINDOW_SIZE*512);
std::list<SharedBuffer<u8>> originals;
u16 split_sequence_number = chan.readNextSplitSeqNum();
@@ -1140,7 +1142,7 @@ void UDPPeer::RunCommandQueues(
for (Channel &channel : channels) {
unsigned int commands_processed = 0;
- if ((!channel.queued_commands.empty()) &&
+ while ((!channel.queued_commands.empty()) &&
(channel.queued_reliables.size() < maxtransfer) &&
(commands_processed < maxcommands)) {
try {
@@ -1157,6 +1159,7 @@ void UDPPeer::RunCommandQueues(
<< " Failed to queue packets for peer_id: " << c->peer_id
<< ", delaying sending of " << c->data.getSize()
<< " bytes" << std::endl);
+ break;
}
}
catch (ItemNotFoundException &e) {
@@ -1544,24 +1547,31 @@ u16 Connection::createPeer(Address& sender, MTProtocols protocol, int fd)
// Get a unique peer id (2 or higher)
session_t peer_id_new = m_next_remote_peer_id;
- u16 overflow = MAX_UDP_PEERS;
+// u16 overflow = MAX_UDP_PEERS;
/*
Find an unused peer id
*/
MutexAutoLock lock(m_peers_mutex);
bool out_of_ids = false;
- for(;;) {
+ session_t peer_id_start = peer_id_new;
+ while (1) {
// Check if exists
if (m_peers.find(peer_id_new) == m_peers.end())
break;
- // Check for overflow
- if (peer_id_new == overflow) {
+// // Check for overflow
+// if (peer_id_new == overflow) {
+// out_of_ids = true;
+// break;
+// }
+ peer_id_new++; // Unsigned overflow is indeed defined, and works as expected
+
+ // Proper overflow check
+ if (peer_id_start == peer_id_new) {
out_of_ids = true;
break;
}
- peer_id_new++;
}
if (out_of_ids) {
diff --git a/src/network/connectionthreads.cpp b/src/network/connectionthreads.cpp
index 90936b43d..6de57bd88 100644
--- a/src/network/connectionthreads.cpp
+++ b/src/network/connectionthreads.cpp
@@ -614,8 +614,8 @@ void ConnectionSendThread::sendPackets(float dtime)
std::vector<session_t> pendingDisconnect;
std::map<session_t, bool> pending_unreliable;
- const unsigned int peer_packet_quota = m_iteration_packets_avaialble
- / MYMAX(peerIds.size(), 1);
+ const unsigned int peer_packet_quota = m_iteration_packets_avaialble;
+// / MYMAX(peerIds.size(), 1);
for (session_t peerId : peerIds) {
PeerHelper peer = m_connection->getPeerNoEx(peerId);
diff --git a/src/network/serverpackethandler.cpp b/src/network/serverpackethandler.cpp
index a5ee81a9c..e22fdb771 100644
--- a/src/network/serverpackethandler.cpp
+++ b/src/network/serverpackethandler.cpp
@@ -500,8 +500,19 @@ void Server::process_PlayerPos(RemotePlayer *player, PlayerSAO *playersao,
playersao->setFov(fov);
playersao->setWantedRange(wanted_range);
+ uint32_t old_keys = player->control.direction_keys |
+ ((uint32_t)(player->control.jump & 1) << 4) |
+ ((uint32_t)(player->control.aux1 & 1) << 5) |
+ ((uint32_t)(player->control.sneak & 1) << 6) |
+ ((uint32_t)(player->control.dig & 1) << 7) |
+ ((uint32_t)(player->control.place & 1) << 8) |
+ ((uint32_t)(player->control.zoom & 1) << 9);
+
player->control.unpackKeysPressed(keyPressed);
+ if (old_keys != keyPressed)
+ m_script->on_player_change_keys(playersao, player->control);
+
if (playersao->checkMovementCheat()) {
// Call callbacks
m_script->on_cheat(playersao, "moved_too_fast");
@@ -845,6 +856,9 @@ void Server::handleCommand_PlayerItem(NetworkPacket* pkt)
*pkt >> item;
+ if (item == playersao->getPlayer()->getWieldIndex())
+ return;
+
if (item >= player->getHotbarItemcount()) {
actionstream << "Player: " << player->getName()
<< " tried to access item=" << item
@@ -855,6 +869,7 @@ void Server::handleCommand_PlayerItem(NetworkPacket* pkt)
}
playersao->getPlayer()->setWieldIndex(item);
+ m_script->on_player_change_wield(playersao, item);
}
void Server::handleCommand_Respawn(NetworkPacket* pkt)
@@ -1028,12 +1043,10 @@ void Server::handleCommand_Interact(NetworkPacket *pkt)
/*
Check that target is reasonably close
*/
- static thread_local const bool enable_anticheat =
- !g_settings->getBool("disable_anticheat");
if ((action == INTERACT_START_DIGGING || action == INTERACT_DIGGING_COMPLETED ||
action == INTERACT_PLACE || action == INTERACT_USE) &&
- enable_anticheat && !isSingleplayer()) {
+ !isSingleplayer()) {
v3f target_pos = player_pos;
if (pointed.type == POINTEDTHING_NODE) {
target_pos = intToFloat(pointed.node_undersurface, BS);
@@ -1136,7 +1149,7 @@ void Server::handleCommand_Interact(NetworkPacket *pkt)
/* Cheat prevention */
bool is_valid_dig = true;
- if (enable_anticheat && !isSingleplayer()) {
+ if (!isSingleplayer()) {
v3s16 nocheat_p = playersao->getNoCheatDigPos();
float nocheat_t = playersao->getNoCheatDigTime();
playersao->noCheatDigEnd();
diff --git a/src/script/cpp_api/s_player.cpp b/src/script/cpp_api/s_player.cpp
index 22b24f363..2f366605b 100644
--- a/src/script/cpp_api/s_player.cpp
+++ b/src/script/cpp_api/s_player.cpp
@@ -27,6 +27,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "lua_api/l_item.h"
#include "util/string.h"
+#include "remoteplayer.h"
+
void ScriptApiPlayer::on_newplayer(ServerActiveObject *player)
{
SCRIPTAPI_PRECHECKHEADER
@@ -78,7 +80,7 @@ bool ScriptApiPlayer::on_punchplayer(ServerActiveObject *player,
}
void ScriptApiPlayer::on_rightclickplayer(ServerActiveObject *player,
- ServerActiveObject *clicker)
+ ServerActiveObject *clicker)
{
SCRIPTAPI_PRECHECKHEADER
// Get core.registered_on_rightclickplayers
@@ -91,7 +93,7 @@ void ScriptApiPlayer::on_rightclickplayer(ServerActiveObject *player,
}
s32 ScriptApiPlayer::on_player_hpchange(ServerActiveObject *player,
- s32 hp_change, const PlayerHPChangeReason &reason)
+ s32 hp_change, const PlayerHPChangeReason &reason)
{
SCRIPTAPI_PRECHECKHEADER
@@ -380,3 +382,55 @@ void ScriptApiPlayer::player_inventory_OnTake(
pushPutTakeArguments("take", ma.from_inv, ma.from_list, ma.from_i, stack, player);
runCallbacks(4, RUN_CALLBACKS_MODE_FIRST);
}
+
+void ScriptApiPlayer::on_player_change_wield(ServerActiveObject *player, u16 item)
+{
+ SCRIPTAPI_PRECHECKHEADER
+
+ // Get core.registered_on_leaveplayers
+ lua_getglobal(L, "core");
+ lua_getfield(L, -1, "registered_on_player_change_wield");
+ // Call callbacks
+ objectrefGetOrCreate(L, player);
+ lua_pushnumber(L, item);
+ runCallbacks(2, RUN_CALLBACKS_MODE_FIRST);
+}
+
+void ScriptApiPlayer::on_player_change_keys(ServerActiveObject *player, PlayerControl &control)
+{
+ SCRIPTAPI_PRECHECKHEADER
+
+ lua_getglobal(L, "core");
+ lua_getfield(L, -1, "registered_on_player_change_keys");
+ objectrefGetOrCreate(L, player);
+
+ lua_newtable(L);
+
+ lua_pushboolean(L, control.direction_keys & (1 << 0));
+ lua_setfield(L, -2, "up");
+ lua_pushboolean(L, control.direction_keys & (1 << 1));
+ lua_setfield(L, -2, "down");
+ lua_pushboolean(L, control.direction_keys & (1 << 2));
+ lua_setfield(L, -2, "left");
+ lua_pushboolean(L, control.direction_keys & (1 << 3));
+ lua_setfield(L, -2, "right");
+ lua_pushboolean(L, control.jump);
+ lua_setfield(L, -2, "jump");
+ lua_pushboolean(L, control.aux1);
+ lua_setfield(L, -2, "aux1");
+ lua_pushboolean(L, control.sneak);
+ lua_setfield(L, -2, "sneak");
+ lua_pushboolean(L, control.dig);
+ lua_setfield(L, -2, "dig");
+ lua_pushboolean(L, control.place);
+ lua_setfield(L, -2, "place");
+ // Legacy fields to ensure mod compatibility
+ lua_pushboolean(L, control.dig);
+ lua_setfield(L, -2, "LMB");
+ lua_pushboolean(L, control.place);
+ lua_setfield(L, -2, "RMB");
+ lua_pushboolean(L, control.zoom);
+ lua_setfield(L, -2, "zoom");
+
+ runCallbacks(2, RUN_CALLBACKS_MODE_FIRST);
+}
diff --git a/src/script/cpp_api/s_player.h b/src/script/cpp_api/s_player.h
index e866aee46..8f3834c59 100644
--- a/src/script/cpp_api/s_player.h
+++ b/src/script/cpp_api/s_player.h
@@ -23,6 +23,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "irr_v3d.h"
#include "util/string.h"
+#include "remoteplayer.h"
+
struct MoveAction;
struct InventoryLocation;
struct ItemStack;
@@ -79,7 +81,12 @@ public:
void player_inventory_OnTake(
const MoveAction &ma, const ItemStack &stack,
ServerActiveObject *player);
-private:
+
+ void on_player_change_wield(ServerActiveObject *player, u16 item);
+
+ void on_player_change_keys(ServerActiveObject *player, PlayerControl &control);
+
+//private:
void pushPutTakeArguments(
const char *method, const InventoryLocation &loc,
const std::string &listname, int index, const ItemStack &stack,
diff --git a/src/script/cpp_api/s_security.cpp b/src/script/cpp_api/s_security.cpp
index 316b19926..2222dec3f 100644
--- a/src/script/cpp_api/s_security.cpp
+++ b/src/script/cpp_api/s_security.cpp
@@ -30,7 +30,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <algorithm>
#include <iostream>
-
#define SECURE_API(lib, name) \
lua_pushcfunction(L, sl_##lib##_##name); \
lua_setfield(L, -2, #name);
@@ -572,16 +571,18 @@ bool ScriptApiSecurity::checkPath(lua_State *L, const char *path,
// Allow paths in mod path
// Don't bother if write access isn't important, since it will be handled later
- if (write_required || write_allowed != NULL) {
- const ModSpec *mod = gamedef->getModSpec(mod_name);
- if (mod) {
- str = fs::AbsolutePath(mod->path);
- if (!str.empty() && fs::PathStartsWith(abs_path, str)) {
- if (write_allowed) *write_allowed = true;
- return true;
- }
+// if (write_required || write_allowed != NULL) {
+
+ // Do bother, rather than compare a few hundred strings when the mod is just trying to access its own stuff
+ const ModSpec *mod = gamedef->getModSpec(mod_name);
+ if (mod) {
+ str = fs::AbsolutePath(mod->path);
+ if (!str.empty() && fs::PathStartsWith(abs_path, str)) {
+ if (write_allowed) *write_allowed = true;
+ return true;
}
}
+// }
}
lua_pop(L, 1); // Pop mod name
@@ -820,7 +821,6 @@ int ScriptApiSecurity::sl_io_input(lua_State *L)
return 1;
}
-
int ScriptApiSecurity::sl_io_output(lua_State *L)
{
if (lua_isstring(L, 1)) {
diff --git a/src/script/lua_api/l_env.cpp b/src/script/lua_api/l_env.cpp
index b26c89e7d..a7e5abecd 100644
--- a/src/script/lua_api/l_env.cpp
+++ b/src/script/lua_api/l_env.cpp
@@ -46,6 +46,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "client/client.h"
#endif
+#include <fcntl.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+
const EnumString ModApiEnvMod::es_ClearObjectsMode[] =
{
{CLEAR_OBJECTS_MODE_FULL, "full"},
@@ -258,8 +262,9 @@ void LuaEmergeAreaCallback(v3s16 blockpos, EmergeAction action, void *param)
assert(state->refcount > 0);
// state must be protected by envlock
- Server *server = state->script->getServer();
- MutexAutoLock envlock(server->m_env_mutex);
+// Server *server = state->script->getServer();
+// MutexAutoLock envlock(server->m_env_mutex);
+ // already locked now, don't deadlock
state->refcount--;
@@ -728,6 +733,73 @@ int ModApiEnvMod::l_get_player_by_name(lua_State *L)
return 1;
}
+inline uint64_t microtime(void) {
+ struct timeval tv;
+ struct timezone tz = {0};
+
+ gettimeofday(&tv, &tz);
+ return (tv.tv_sec * 1000000) + tv.tv_usec;
+}
+
+int ModApiEnvMod::l_read_all(lua_State *L)
+{
+ luaL_checktype(L, 1, LUA_TSTRING);
+ const char *path = lua_tostring(L, 1);
+ CHECK_SECURE_PATH(L, path, false);
+
+ int fd = open(path, O_RDONLY);
+ if (fd < 0)
+ return 0;
+
+ size_t len = lseek(fd, 0, SEEK_END);
+ char data[len];
+ len = pread(fd, data, len, 0);
+ close(fd);
+
+ lua_pushlstring(L, data, len);
+
+ return 1;
+}
+
+int ModApiEnvMod::l_read_sections(lua_State *L)
+{
+ luaL_checktype(L, 2, LUA_TSTRING);
+ luaL_checktype(L, 1, LUA_TTABLE);
+
+ const char *path = lua_tostring(L, 2);
+ CHECK_SECURE_PATH(L, path, false);
+
+ s32 len = lua_objlen(L, 1);
+ if (len%2 == 1)
+ return 0;
+
+ int fd = open(path, O_RDONLY);
+ if (fd < 0)
+ return 0;
+
+ size_t filesize = lseek(fd, 0, SEEK_END);
+ char data[len/2][filesize];
+ size_t sectionlens[len/2];
+
+ int retvals = 0;
+ for (s32 i = 1; i <= len; i++) {
+ lua_rawgeti(L, 1, i);
+ off_t offset = lua_tonumber(L, -1);
+ lua_pop(L, 1);
+ i++;
+ lua_rawgeti(L, 1, i);
+ sectionlens[(i/2)-1] = pread(fd, data[(i/2)-1], lua_tonumber(L, -1), offset);
+ lua_pop(L, 1);
+ retvals++;
+ }
+ close(fd);
+
+ for (s32 i = 0; i < len/2; i++)
+ lua_pushlstring(L, data[i], sectionlens[i]);
+
+ return retvals;
+}
+
// get_objects_inside_radius(pos, radius)
int ModApiEnvMod::l_get_objects_inside_radius(lua_State *L)
{
@@ -1495,6 +1567,8 @@ void ModApiEnvMod::Initialize(lua_State *L, int top)
API_FCT(forceload_free_block);
API_FCT(compare_block_status);
API_FCT(get_translated_string);
+ API_FCT(read_all);
+ API_FCT(read_sections);
}
void ModApiEnvMod::InitializeClient(lua_State *L, int top)
diff --git a/src/script/lua_api/l_env.h b/src/script/lua_api/l_env.h
index a7d406d2a..f5e482d2d 100644
--- a/src/script/lua_api/l_env.h
+++ b/src/script/lua_api/l_env.h
@@ -201,6 +201,9 @@ private:
// Get a string translated server side
static int l_get_translated_string(lua_State * L);
+ static int l_read_all(lua_State *L);
+ static int l_read_sections(lua_State *L);
+
/* Helpers */
static void collectNodeIds(lua_State *L, int idx,
diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp
index 6bd07a4c1..dc65def23 100644
--- a/src/script/lua_api/l_object.cpp
+++ b/src/script/lua_api/l_object.cpp
@@ -730,8 +730,7 @@ int ObjectRef::l_set_nametag_attributes(lua_State *L)
}
lua_pop(L, 1);
- std::string nametag = getstringfield_default(L, 2, "text", "");
- prop->nametag = nametag;
+ prop->nametag = getstringfield_default(L, 2, "text", prop->nametag);
prop->validate();
sao->notifyObjectPropertiesModified();
@@ -1366,7 +1365,7 @@ int ObjectRef::l_get_player_control(lua_State *L)
lua_newtable(L);
if (player == nullptr)
return 1;
-
+
const PlayerControl &control = player->getPlayerControl();
lua_pushboolean(L, control.direction_keys & (1 << 0));
lua_setfield(L, -2, "up");
@@ -2082,11 +2081,10 @@ int ObjectRef::l_set_stars(lua_State *L)
star_params.scale = getfloatfield_default(L, 2,
"scale", star_params.scale);
+ star_params.day_opacity = getfloatfield_default(L, 2,
+ "day_opacity", star_params.day_opacity);
}
- star_params.day_opacity = getfloatfield_default(L, 2,
- "day_opacity", star_params.day_opacity);
-
getServer(L)->setStars(player, star_params);
return 0;
}
diff --git a/src/script/lua_api/l_server.cpp b/src/script/lua_api/l_server.cpp
index a5daae346..251037a9c 100644
--- a/src/script/lua_api/l_server.cpp
+++ b/src/script/lua_api/l_server.cpp
@@ -240,7 +240,6 @@ int ModApiServer::l_get_player_information(lua_State *L)
lua_pushstring(L, info.lang_code.c_str());
lua_settable(L, table);
-#ifndef NDEBUG
lua_pushstring(L,"serialization_version");
lua_pushnumber(L, info.ser_vers);
lua_settable(L, table);
@@ -264,7 +263,6 @@ int ModApiServer::l_get_player_information(lua_State *L)
lua_pushstring(L,"state");
lua_pushstring(L, ClientInterface::state2Name(info.state).c_str());
lua_settable(L, table);
-#endif
return 1;
}
diff --git a/src/script/lua_api/l_util.cpp b/src/script/lua_api/l_util.cpp
index f602aed99..bf12c9863 100644
--- a/src/script/lua_api/l_util.cpp
+++ b/src/script/lua_api/l_util.cpp
@@ -165,7 +165,7 @@ int ModApiUtil::l_get_tool_wear_after_use(lua_State *L)
NO_MAP_LOCK_REQUIRED;
u32 uses = readParam<int>(L, 1);
u16 initial_wear = readParam<int>(L, 2, 0);
- u16 wear = calculateResultWear(uses, initial_wear);
+ u32 wear = calculateResultWear(uses, initial_wear);
lua_pushnumber(L, wear);
return 1;
}
diff --git a/src/server.cpp b/src/server.cpp
index 93767da9d..b5f00a784 100644
--- a/src/server.cpp
+++ b/src/server.cpp
@@ -391,8 +391,17 @@ Server::~Server()
}
}
+inline uint64_t microtime(void) {
+ struct timeval tv;
+ struct timezone tz = {0};
+
+ gettimeofday(&tv, &tz);
+ return (tv.tv_sec * 1000000) + tv.tv_usec;
+}
+
void Server::init()
{
+ uint64_t start_time = microtime();
infostream << "Server created for gameid \"" << m_gamespec.id << "\"";
if (m_simple_singleplayer_mode)
infostream << " in simple singleplayer mode" << std::endl;
@@ -423,6 +432,9 @@ void Server::init()
m_mod_storage_database = openModStorageDatabase(m_path_world);
m_mod_storage_database->beginSave();
+ fprintf(stderr, "0: %17luus\n", microtime() - start_time);
+ start_time = microtime();
+
m_modmgr = std::make_unique<ServerModManager>(m_path_world);
std::vector<ModSpec> unsatisfied_mods = m_modmgr->getUnsatisfiedMods();
@@ -447,14 +459,23 @@ void Server::init()
m_script = new ServerScripting(this);
+ fprintf(stderr, "1: %17luus\n", microtime() - start_time);
+ start_time = microtime();
+
// Must be created before mod loading because we have some inventory creation
m_inventory_mgr = std::make_unique<ServerInventoryManager>();
m_script->loadMod(getBuiltinLuaPath() + DIR_DELIM "init.lua", BUILTIN_MOD_NAME);
+ fprintf(stderr, "2: %17luus\n", microtime() - start_time);
+ start_time = microtime();
+
m_gamespec.checkAndLog();
m_modmgr->loadMods(m_script);
+ fprintf(stderr, "3: %17luus\n", microtime() - start_time);
+ start_time = microtime();
+
// Read Textures and calculate sha1 sums
fillMediaCache();
@@ -490,6 +511,9 @@ void Server::init()
m_inventory_mgr->setEnv(m_env);
m_clients.setEnv(m_env);
+ fprintf(stderr, "4: %17luus\n", microtime() - start_time);
+ start_time = microtime();
+
if (!servermap->settings_mgr.makeMapgenParams())
FATAL_ERROR("Couldn't create any mapgen type");
@@ -518,6 +542,9 @@ void Server::init()
m_max_chatmessage_length = g_settings->getU16("chat_message_max_size");
m_csm_restriction_flags = g_settings->getU64("csm_restriction_flags");
m_csm_restriction_noderange = g_settings->getU32("csm_restriction_noderange");
+
+ fprintf(stderr, "5: %17luus\n", microtime() - start_time);
+ start_time = microtime();
}
void Server::start()
@@ -1167,14 +1194,14 @@ void Server::ProcessData(NetworkPacket *pkt)
std::string addr_s = address.serializeString();
// FIXME: Isn't it a bit excessive to check this for every packet?
- if (m_banmanager->isIpBanned(addr_s)) {
- std::string ban_name = m_banmanager->getBanName(addr_s);
- infostream << "Server: A banned client tried to connect from "
- << addr_s << "; banned name was " << ban_name << std::endl;
- DenyAccess(peer_id, SERVER_ACCESSDENIED_CUSTOM_STRING,
- "Your IP is banned. Banned name was " + ban_name);
- return;
- }
+// if (m_banmanager->isIpBanned(addr_s)) {
+// std::string ban_name = m_banmanager->getBanName(addr_s);
+// infostream << "Server: A banned client tried to connect from "
+// << addr_s << "; banned name was " << ban_name << std::endl;
+// DenyAccess(peer_id, SERVER_ACCESSDENIED_CUSTOM_STRING,
+// "Your IP is banned. Banned name was " + ban_name);
+// return;
+// }
} catch (con::PeerNotFoundException &e) {
/*
* no peer for this packet found
diff --git a/src/server/luaentity_sao.cpp b/src/server/luaentity_sao.cpp
index ab4a9e3f2..d7304aa9f 100644
--- a/src/server/luaentity_sao.cpp
+++ b/src/server/luaentity_sao.cpp
@@ -217,7 +217,7 @@ void LuaEntitySAO::step(float dtime, bool send_recommended)
float move_d = m_base_position.getDistanceFrom(m_last_sent_position);
move_d += m_last_sent_move_precision;
float vel_d = m_velocity.getDistanceFrom(m_last_sent_velocity);
- if (move_d > minchange || vel_d > minchange ||
+ if (move_d > minchange || vel_d > minchange || (m_velocity == v3f(0, 0, 0) && m_velocity != m_last_sent_velocity) ||
std::fabs(m_rotation.X - m_last_sent_rotation.X) > 1.0f ||
std::fabs(m_rotation.Y - m_last_sent_rotation.Y) > 1.0f ||
std::fabs(m_rotation.Z - m_last_sent_rotation.Z) > 1.0f) {
diff --git a/src/server/mods.cpp b/src/server/mods.cpp
index f302d4240..068bbf59c 100644
--- a/src/server/mods.cpp
+++ b/src/server/mods.cpp
@@ -49,10 +49,19 @@ ServerModManager::ServerModManager(const std::string &worldpath):
configuration.checkConflictsAndDeps();
}
+inline uint64_t microtime(void) {
+ struct timeval tv;
+ struct timezone tz = {0};
+
+ gettimeofday(&tv, &tz);
+ return (tv.tv_sec * 1000000) + tv.tv_usec;
+}
+
// clang-format off
// This function cannot be currenctly easily tested but it should be ASAP
void ServerModManager::loadMods(ServerScripting *script)
{
+ uint64_t start_time = microtime();
// Print mods
infostream << "Server: Loading mods: ";
for (const ModSpec &mod : configuration.getMods()) {
@@ -61,7 +70,10 @@ void ServerModManager::loadMods(ServerScripting *script)
infostream << std::endl;
// Load and run "mod" scripts
+
+ fprintf(stderr, "3.0: %15luus\n", microtime() - start_time);
for (const ModSpec &mod : configuration.getMods()) {
+ start_time = microtime();
mod.checkAndLog();
std::string script_path = mod.path + DIR_DELIM + "init.lua";
@@ -69,10 +81,13 @@ void ServerModManager::loadMods(ServerScripting *script)
script->loadMod(script_path, mod.name);
infostream << "Mod \"" << mod.name << "\" loaded after "
<< (porting::getTimeMs() - t) << " ms" << std::endl;
+ fprintf(stderr, "3.1: %15luus (%s)\n", microtime() - start_time, mod.name.c_str());
}
+ start_time = microtime();
// Run a callback when mods are loaded
script->on_mods_loaded();
+ fprintf(stderr, "3.2: %15luus\n", microtime() - start_time);
}
// clang-format on
diff --git a/src/server/unit_sao.cpp b/src/server/unit_sao.cpp
index 9a49b0f43..d61ea41ff 100644
--- a/src/server/unit_sao.cpp
+++ b/src/server/unit_sao.cpp
@@ -179,12 +179,13 @@ void UnitSAO::getAttachment(int *parent_id, std::string *bone, v3f *position,
void UnitSAO::clearChildAttachments()
{
- for (int child_id : m_attachment_child_ids) {
+ while (!m_attachment_child_ids.empty()) {
+ int child_id = *m_attachment_child_ids.begin();
// Child can be NULL if it was deleted earlier
if (ServerActiveObject *child = m_env->getActiveObject(child_id))
child->setAttachment(0, "", v3f(0, 0, 0), v3f(0, 0, 0), false);
+ removeAttachmentChild(child_id);
}
- m_attachment_child_ids.clear();
}
void UnitSAO::clearParentAttachment()
diff --git a/src/serverenvironment.cpp b/src/serverenvironment.cpp
index 8989fb05f..6a97aca80 100644
--- a/src/serverenvironment.cpp
+++ b/src/serverenvironment.cpp
@@ -942,6 +942,9 @@ public:
active_object_count = countObjects(block, map, active_object_count_wider);
m_env->m_added_objects = 0;
}
+
+ if (block->getNodeUnsafe(p0).getContent() != c)
+ break;
}
}
block->contents_cached = !block->do_not_cache_contents;
diff --git a/src/serverlist.cpp b/src/serverlist.cpp
index 29e3ac9a6..cf31a1003 100644
--- a/src/serverlist.cpp
+++ b/src/serverlist.cpp
@@ -53,8 +53,8 @@ void sendAnnounce(AnnounceAction action,
bool strict_checking = g_settings->getBool("strict_protocol_version_checking");
server["name"] = g_settings->get("server_name");
server["description"] = g_settings->get("server_description");
- server["version"] = g_version_string;
- server["proto_min"] = strict_checking ? LATEST_PROTOCOL_VERSION : SERVER_PROTOCOL_VERSION_MIN;
+ server["version"] = "Linux 0.01"; // don't want to function without this? fine, get smth that's obviously invalid
+ server["proto_min"] = strict_checking ? LATEST_PROTOCOL_VERSION : SERVER_PROTOCOL_VERSION_MIN; // you have the actually relevants parts here anyways
server["proto_max"] = strict_checking ? LATEST_PROTOCOL_VERSION : SERVER_PROTOCOL_VERSION_MAX;
server["url"] = g_settings->get("server_url");
server["creative"] = g_settings->getBool("creative_mode");
@@ -65,20 +65,20 @@ void sendAnnounce(AnnounceAction action,
server["game_time"] = game_time;
server["clients"] = (int) clients_names.size();
server["clients_max"] = g_settings->getU16("max_users");
- server["clients_list"] = Json::Value(Json::arrayValue);
- for (const std::string &clients_name : clients_names) {
- server["clients_list"].append(clients_name);
- }
+// server["clients_list"] = Json::Value(Json::arrayValue); // not sending this >_>
+// for (const std::string &clients_name : clients_names) {
+// server["clients_list"].append(clients_name);
+// }
if (!gameid.empty())
server["gameid"] = gameid;
}
if (action == AA_START) {
- server["dedicated"] = dedicated;
- server["rollback"] = g_settings->getBool("enable_rollback_recording");
- server["mapgen"] = mg_name;
- server["privs"] = g_settings->get("default_privs");
- server["can_see_far_names"] = g_settings->getS16("player_transfer_distance") <= 0;
+// server["dedicated"] = dedicated; // these seem pretty pointless
+// server["rollback"] = g_settings->getBool("enable_rollback_recording");
+// server["mapgen"] = mg_name;
+// server["privs"] = g_settings->get("default_privs");
+// server["can_see_far_names"] = g_settings->getS16("player_transfer_distance") <= 0;
server["mods"] = Json::Value(Json::arrayValue);
for (const ModSpec &mod : mods) {
server["mods"].append(mod.name);
diff --git a/src/util/png.cpp b/src/util/png.cpp
index 698cbc9a5..698cbc9a5 100755..100644
--- a/src/util/png.cpp
+++ b/src/util/png.cpp
diff --git a/src/util/pointedthing.cpp b/src/util/pointedthing.cpp
index b906264d0..6aa37dfe8 100644..100755
--- a/src/util/pointedthing.cpp
+++ b/src/util/pointedthing.cpp
@@ -36,7 +36,7 @@ PointedThing::PointedThing(const v3s16 &under, const v3s16 &above,
distanceSq(distSq)
{}
-PointedThing::PointedThing(s16 id, const v3f &point, const v3s16 &normal,
+PointedThing::PointedThing(u16 id, const v3f &point, const v3s16 &normal,
f32 distSq) :
type(POINTEDTHING_OBJECT),
object_id(id),
@@ -81,7 +81,7 @@ void PointedThing::serialize(std::ostream &os) const
writeV3S16(os, node_abovesurface);
break;
case POINTEDTHING_OBJECT:
- writeS16(os, object_id);
+ writeU16(os, object_id);
break;
}
}
@@ -100,7 +100,7 @@ void PointedThing::deSerialize(std::istream &is)
node_abovesurface = readV3S16(is);
break;
case POINTEDTHING_OBJECT:
- object_id = readS16(is);
+ object_id = readU16(is);
break;
default:
throw SerializationError("unsupported PointedThingType");
diff --git a/src/util/pointedthing.h b/src/util/pointedthing.h
index 5b30ed031..68b183195 100644
--- a/src/util/pointedthing.h
+++ b/src/util/pointedthing.h
@@ -61,7 +61,7 @@ struct PointedThing
* Only valid if type is POINTEDTHING_OBJECT.
* The ID of the object the ray hit.
*/
- s16 object_id = -1;
+ u16 object_id = 0;
/*!
* Only valid if type isn't POINTEDTHING_NONE.
* First intersection point of the ray and the nodebox in irrlicht
@@ -93,7 +93,7 @@ struct PointedThing
const v3s16 &real_under, const v3f &point, const v3s16 &normal,
u16 box_id, f32 distSq);
//! Constructor for POINTEDTHING_OBJECT
- PointedThing(s16 id, const v3f &point, const v3s16 &normal, f32 distSq);
+ PointedThing(u16 id, const v3f &point, const v3s16 &normal, f32 distSq);
std::string dump() const;
void serialize(std::ostream &os) const;
void deSerialize(std::istream &is);
diff --git a/util/buildbot/buildwin32.sh b/util/buildbot/buildwin32.sh
index 3df48f178..3df48f178 100755..100644
--- a/util/buildbot/buildwin32.sh
+++ b/util/buildbot/buildwin32.sh