From 11c7849bdf53557bc327fee06bddbbf1e23c4512 Mon Sep 17 00:00:00 2001 From: Test_User Date: Fri, 28 Jun 2024 08:00:00 +0800 Subject: Hax's version of Minetest Server 5.6.0 --- .gitignore | 2 + AppImageBuilder.yml | 54 --------------------- android/gradlew | 0 builtin/common/information_formspecs.lua | 4 +- builtin/common/misc_helpers.lua | 1 + builtin/common/vector.lua | 8 ++++ builtin/game/register.lua | 20 +++++++- doc/mkdocs/build.sh | 0 doc/mkdocs/docs/img/favicon.ico | Bin 34 -> 9662 bytes src/craftdef.cpp | 1 + src/emerge.cpp | 54 +++++++++++---------- src/inventorymanager.cpp | 80 ++++++++++++++++++++++++++++++- src/map.cpp | 36 +++++--------- src/map.h | 22 ++++++++- src/mapblock.h | 7 ++- src/mapgen/dungeongen.cpp | 40 ++++++++-------- src/mapnode.h | 2 +- src/mapsector.cpp | 51 ++++++++------------ src/mapsector.h | 18 +++---- src/network/connection.cpp | 24 +++++++--- src/network/connectionthreads.cpp | 4 +- src/network/serverpackethandler.cpp | 21 ++++++-- src/script/cpp_api/s_player.cpp | 58 +++++++++++++++++++++- src/script/cpp_api/s_player.h | 9 +++- src/script/cpp_api/s_security.cpp | 20 ++++---- src/script/lua_api/l_env.cpp | 78 +++++++++++++++++++++++++++++- src/script/lua_api/l_env.h | 3 ++ src/script/lua_api/l_object.cpp | 10 ++-- src/script/lua_api/l_server.cpp | 2 - src/script/lua_api/l_util.cpp | 2 +- src/server.cpp | 43 +++++++++++++---- src/server/luaentity_sao.cpp | 2 +- src/server/mods.cpp | 15 ++++++ src/server/unit_sao.cpp | 5 +- src/serverenvironment.cpp | 3 ++ src/serverlist.cpp | 22 ++++----- src/util/png.cpp | 0 src/util/pointedthing.cpp | 6 +-- src/util/pointedthing.h | 4 +- util/buildbot/buildwin32.sh | 0 40 files changed, 489 insertions(+), 242 deletions(-) delete mode 100644 AppImageBuilder.yml mode change 100755 => 100644 android/gradlew mode change 100644 => 100755 builtin/common/information_formspecs.lua mode change 100755 => 100644 doc/mkdocs/build.sh mode change 120000 => 100755 doc/mkdocs/docs/img/favicon.ico mode change 100755 => 100644 src/util/png.cpp mode change 100644 => 100755 src/util/pointedthing.cpp mode change 100755 => 100644 util/buildbot/buildwin32.sh 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 old mode 100755 new mode 100644 diff --git a/builtin/common/information_formspecs.lua b/builtin/common/information_formspecs.lua old mode 100644 new mode 100755 index 1445a017c..d4426aff4 --- 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 old mode 100755 new mode 100644 diff --git a/doc/mkdocs/docs/img/favicon.ico b/doc/mkdocs/docs/img/favicon.ico deleted file mode 120000 index cac34a30c..000000000 --- a/doc/mkdocs/docs/img/favicon.ico +++ /dev/null @@ -1 +0,0 @@ -../../../../misc/minetest-icon.ico \ No newline at end of file diff --git a/doc/mkdocs/docs/img/favicon.ico b/doc/mkdocs/docs/img/favicon.ico new file mode 100755 index 000000000..82af67bf9 Binary files /dev/null and b/doc/mkdocs/docs/img/favicon.ico 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 *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" - <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" - <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 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::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 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> 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 pendingDisconnect; std::map 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 #include - #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 +#include +#include + 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(L, 1); u16 initial_wear = readParam(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(m_path_world); std::vector 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(); 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 old mode 100755 new mode 100644 diff --git a/src/util/pointedthing.cpp b/src/util/pointedthing.cpp old mode 100644 new mode 100755 index b906264d0..6aa37dfe8 --- 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 old mode 100755 new mode 100644 -- cgit v1.2.3