From 6ea558f8ac57a391b6f54c534441f930b0609cea Mon Sep 17 00:00:00 2001 From: savilli <78875209+savilli@users.noreply.github.com> Date: Tue, 12 Oct 2021 21:12:49 +0300 Subject: Fix player HP desync between client and server --- src/server/player_sao.cpp | 5 +++-- src/server/player_sao.h | 6 +++++- 2 files changed, 8 insertions(+), 3 deletions(-) (limited to 'src/server') diff --git a/src/server/player_sao.cpp b/src/server/player_sao.cpp index d4d036726..690823bb7 100644 --- a/src/server/player_sao.cpp +++ b/src/server/player_sao.cpp @@ -462,7 +462,7 @@ void PlayerSAO::rightClick(ServerActiveObject *clicker) m_env->getScriptIface()->on_rightclickplayer(this, clicker); } -void PlayerSAO::setHP(s32 hp, const PlayerHPChangeReason &reason) +void PlayerSAO::setHP(s32 hp, const PlayerHPChangeReason &reason, bool send) { if (hp == (s32)m_hp) return; // Nothing to do @@ -490,7 +490,8 @@ void PlayerSAO::setHP(s32 hp, const PlayerHPChangeReason &reason) if ((hp == 0) != (oldhp == 0)) m_properties_sent = false; - m_env->getGameDef()->SendPlayerHPOrDie(this, reason); + if (send) + m_env->getGameDef()->SendPlayerHPOrDie(this, reason); } void PlayerSAO::setBreath(const u16 breath, bool send) diff --git a/src/server/player_sao.h b/src/server/player_sao.h index 8e2d8803f..1429d7129 100644 --- a/src/server/player_sao.h +++ b/src/server/player_sao.h @@ -112,7 +112,11 @@ public: u16 punch(v3f dir, const ToolCapabilities *toolcap, ServerActiveObject *puncher, float time_from_last_punch); void rightClick(ServerActiveObject *clicker); - void setHP(s32 hp, const PlayerHPChangeReason &reason); + void setHP(s32 hp, const PlayerHPChangeReason &reason) override + { + return setHP(hp, reason, true); + } + void setHP(s32 hp, const PlayerHPChangeReason &reason, bool send); void setHPRaw(u16 hp) { m_hp = hp; } u16 getBreath() const { return m_breath; } void setBreath(const u16 breath, bool send = true); -- cgit v1.2.3 From 86b44ecd8280d8304aa26a600fc004d40a970020 Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Wed, 20 Oct 2021 19:50:16 +0000 Subject: Add no_texture.png as fallback for unspecified textures --- doc/texture_packs.txt | 3 ++- games/devtest/mods/broken/init.lua | 11 +++++++++++ games/devtest/mods/broken/mod.conf | 2 ++ src/client/content_cao.cpp | 10 +++++----- src/client/game.cpp | 5 ++--- src/client/hud.cpp | 25 ++++++++++++++++++------- src/client/wieldmesh.cpp | 11 ++++++++--- src/nodedef.cpp | 17 ++++++++++++++--- src/object_properties.cpp | 2 +- src/server/luaentity_sao.cpp | 5 +++++ textures/base/pack/no_texture.png | Bin 0 -> 281 bytes 11 files changed, 68 insertions(+), 23 deletions(-) create mode 100644 games/devtest/mods/broken/init.lua create mode 100644 games/devtest/mods/broken/mod.conf create mode 100644 textures/base/pack/no_texture.png (limited to 'src/server') diff --git a/doc/texture_packs.txt b/doc/texture_packs.txt index 8af2cbad6..f738032b6 100644 --- a/doc/texture_packs.txt +++ b/doc/texture_packs.txt @@ -90,9 +90,10 @@ by texture packs. All existing fallback textures can be found in the directory * `minimap_mask_square.png`: mask used for the square minimap * `minimap_overlay_round.png`: overlay texture for the round minimap * `minimap_overlay_square.png`: overlay texture for the square minimap -* `no_texture_airlike.png`: fallback inventory image for airlike nodes * `object_marker_red.png`: texture for players on the minimap * `player_marker.png`: texture for the own player on the square minimap +* `no_texture_airlike.png`: fallback inventory image for airlike nodes +* `no_texture.png`: fallback image for unspecified textures * `player.png`: front texture of the 2D upright sprite player * `player_back.png`: back texture of the 2D upright sprite player diff --git a/games/devtest/mods/broken/init.lua b/games/devtest/mods/broken/init.lua new file mode 100644 index 000000000..04993ca16 --- /dev/null +++ b/games/devtest/mods/broken/init.lua @@ -0,0 +1,11 @@ +-- Register stuff with empty definitions to test if Minetest fallback options +-- for these things work properly. + +-- The itemstrings are deliberately kept descriptive to keep them easy to +-- recognize. + +minetest.register_node("broken:node_with_empty_definition", {}) +minetest.register_tool("broken:tool_with_empty_definition", {}) +minetest.register_craftitem("broken:craftitem_with_empty_definition", {}) + +minetest.register_entity("broken:entity_with_empty_definition", {}) diff --git a/games/devtest/mods/broken/mod.conf b/games/devtest/mods/broken/mod.conf new file mode 100644 index 000000000..a24378a34 --- /dev/null +++ b/games/devtest/mods/broken/mod.conf @@ -0,0 +1,2 @@ +name = broken +description = Register items and an entity with empty definitions to test fallback diff --git a/src/client/content_cao.cpp b/src/client/content_cao.cpp index da78cae7c..1e79d00c9 100644 --- a/src/client/content_cao.cpp +++ b/src/client/content_cao.cpp @@ -647,7 +647,7 @@ void GenericCAO::addToScene(ITextureSource *tsrc, scene::ISceneManager *smgr) m_matrixnode, v2f(1, 1), v3f(0,0,0), -1); m_spritenode->grab(); m_spritenode->setMaterialTexture(0, - tsrc->getTextureForMesh("unknown_node.png")); + tsrc->getTextureForMesh("no_texture.png")); setSceneNodeMaterial(m_spritenode); @@ -1288,7 +1288,7 @@ void GenericCAO::updateTextures(std::string mod) if (m_spritenode) { if (m_prop.visual == "sprite") { - std::string texturestring = "unknown_node.png"; + std::string texturestring = "no_texture.png"; if (!m_prop.textures.empty()) texturestring = m_prop.textures[0]; texturestring += mod; @@ -1367,7 +1367,7 @@ void GenericCAO::updateTextures(std::string mod) { for (u32 i = 0; i < 6; ++i) { - std::string texturestring = "unknown_node.png"; + std::string texturestring = "no_texture.png"; if(m_prop.textures.size() > i) texturestring = m_prop.textures[i]; texturestring += mod; @@ -1400,7 +1400,7 @@ void GenericCAO::updateTextures(std::string mod) } else if (m_prop.visual == "upright_sprite") { scene::IMesh *mesh = m_meshnode->getMesh(); { - std::string tname = "unknown_object.png"; + std::string tname = "no_texture.png"; if (!m_prop.textures.empty()) tname = m_prop.textures[0]; tname += mod; @@ -1422,7 +1422,7 @@ void GenericCAO::updateTextures(std::string mod) buf->getMaterial().setFlag(video::EMF_ANISOTROPIC_FILTER, use_anisotropic_filter); } { - std::string tname = "unknown_object.png"; + std::string tname = "no_texture.png"; if (m_prop.textures.size() >= 2) tname = m_prop.textures[1]; else if (!m_prop.textures.empty()) diff --git a/src/client/game.cpp b/src/client/game.cpp index a6448f40d..57951dc95 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -3331,9 +3331,8 @@ void Game::handlePointingAtNode(const PointedThing &pointed, } else { MapNode n = map.getNode(nodepos); - if (nodedef_manager->get(n).tiledef[0].name == "unknown_node.png") { - m_game_ui->setInfoText(L"Unknown node: " + - utf8_to_wide(nodedef_manager->get(n).name)); + if (nodedef_manager->get(n).name == "unknown") { + m_game_ui->setInfoText(L"Unknown node"); } } diff --git a/src/client/hud.cpp b/src/client/hud.cpp index 0620759da..e08d2ef02 100644 --- a/src/client/hud.cpp +++ b/src/client/hud.cpp @@ -1007,11 +1007,15 @@ void drawItemStack( bool draw_overlay = false; + bool has_mesh = false; + ItemMesh *imesh; + // Render as mesh if animated or no inventory image if ((enable_animations && rotation_kind < IT_ROT_NONE) || def.inventory_image.empty()) { - ItemMesh *imesh = client->idef()->getWieldMesh(def.name, client); - if (!imesh || !imesh->mesh) - return; + imesh = client->idef()->getWieldMesh(def.name, client); + has_mesh = imesh && imesh->mesh; + } + if (has_mesh) { scene::IMesh *mesh = imesh->mesh; driver->clearBuffers(video::ECBF_DEPTH); s32 delta = 0; @@ -1103,10 +1107,17 @@ void drawItemStack( draw_overlay = def.type == ITEM_NODE && def.inventory_image.empty(); } else { // Otherwise just draw as 2D video::ITexture *texture = client->idef()->getInventoryTexture(def.name, client); - if (!texture) - return; - video::SColor color = - client->idef()->getItemstackColor(item, client); + video::SColor color; + if (texture) { + color = client->idef()->getItemstackColor(item, client); + } else { + color = video::SColor(255, 255, 255, 255); + ITextureSource *tsrc = client->getTextureSource(); + texture = tsrc->getTexture("no_texture.png"); + if (!texture) + return; + } + const video::SColor colors[] = { color, color, color, color }; draw2DImageFilterScaled(driver, texture, rect, diff --git a/src/client/wieldmesh.cpp b/src/client/wieldmesh.cpp index 6beed3f3a..0a4cb3b86 100644 --- a/src/client/wieldmesh.cpp +++ b/src/client/wieldmesh.cpp @@ -458,9 +458,14 @@ void WieldMeshSceneNode::setItem(const ItemStack &item, Client *client, bool che material.setFlag(video::EMF_TRILINEAR_FILTER, m_trilinear_filter); } return; - } else if (!def.inventory_image.empty()) { - setExtruded(def.inventory_image, def.inventory_overlay, def.wield_scale, - tsrc, 1); + } else { + if (!def.inventory_image.empty()) { + setExtruded(def.inventory_image, def.inventory_overlay, def.wield_scale, + tsrc, 1); + } else { + setExtruded("no_texture.png", "", def.wield_scale, tsrc, 1); + } + m_colors.emplace_back(); // overlay is white, if present m_colors.emplace_back(true, video::SColor(0xFFFFFFFF)); diff --git a/src/nodedef.cpp b/src/nodedef.cpp index 703df4dee..f0e0024be 100644 --- a/src/nodedef.cpp +++ b/src/nodedef.cpp @@ -796,8 +796,10 @@ void ContentFeatures::updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc TileDef tdef[6]; for (u32 j = 0; j < 6; j++) { tdef[j] = tiledef[j]; - if (tdef[j].name.empty()) - tdef[j].name = "unknown_node.png"; + if (tdef[j].name.empty()) { + tdef[j].name = "no_texture.png"; + tdef[j].backface_culling = false; + } } // also the overlay tiles TileDef tdef_overlay[6]; @@ -805,8 +807,13 @@ void ContentFeatures::updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc tdef_overlay[j] = tiledef_overlay[j]; // also the special tiles TileDef tdef_spec[6]; - for (u32 j = 0; j < CF_SPECIAL_COUNT; j++) + for (u32 j = 0; j < CF_SPECIAL_COUNT; j++) { tdef_spec[j] = tiledef_special[j]; + if (tdef_spec[j].name.empty()) { + tdef_spec[j].name = "no_texture.png"; + tdef_spec[j].backface_culling = false; + } + } bool is_liquid = false; @@ -1052,6 +1059,10 @@ void NodeDefManager::clear() { ContentFeatures f; f.name = "unknown"; + TileDef unknownTile; + unknownTile.name = "unknown_node.png"; + for (int t = 0; t < 6; t++) + f.tiledef[t] = unknownTile; // Insert directly into containers content_t c = CONTENT_UNKNOWN; m_content_features[c] = f; diff --git a/src/object_properties.cpp b/src/object_properties.cpp index db06f8930..c7f6becf0 100644 --- a/src/object_properties.cpp +++ b/src/object_properties.cpp @@ -28,7 +28,7 @@ static const video::SColor NULL_BGCOLOR{0, 1, 1, 1}; ObjectProperties::ObjectProperties() { - textures.emplace_back("unknown_object.png"); + textures.emplace_back("no_texture.png"); colors.emplace_back(255,255,255,255); } diff --git a/src/server/luaentity_sao.cpp b/src/server/luaentity_sao.cpp index 3bcbe107b..1d65ac306 100644 --- a/src/server/luaentity_sao.cpp +++ b/src/server/luaentity_sao.cpp @@ -108,7 +108,12 @@ void LuaEntitySAO::addedToEnvironment(u32 dtime_s) m_env->getScriptIface()-> luaentity_Activate(m_id, m_init_state, dtime_s); } else { + // It's an unknown object + // Use entitystring as infotext for debugging m_prop.infotext = m_init_name; + // Set unknown object texture + m_prop.textures.clear(); + m_prop.textures.emplace_back("unknown_object.png"); } } diff --git a/textures/base/pack/no_texture.png b/textures/base/pack/no_texture.png new file mode 100644 index 000000000..681b81082 Binary files /dev/null and b/textures/base/pack/no_texture.png differ -- cgit v1.2.3 From 6910c8d920acedb3f1df1ac03a5cdf14f5fb6081 Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Sun, 31 Oct 2021 22:33:33 +0000 Subject: Fix number of tool uses being off by 1..32767 (#11110) --- builtin/game/item.lua | 2 +- doc/lua_api.txt | 13 +-- games/devtest/mods/basetools/init.lua | 44 +++++---- .../mods/basetools/textures/basetools_dirtpick.png | Bin 307 -> 0 bytes games/devtest/mods/util_commands/init.lua | 53 +++++++++++ src/client/content_cao.cpp | 3 +- src/client/game.cpp | 3 +- src/network/serverpackethandler.cpp | 7 +- src/script/lua_api/l_object.cpp | 2 +- src/script/lua_api/l_util.cpp | 19 ++-- src/script/lua_api/l_util.h | 4 +- src/server/luaentity_sao.cpp | 8 +- src/server/luaentity_sao.h | 5 +- src/server/player_sao.cpp | 7 +- src/server/player_sao.h | 4 +- src/server/serveractiveobject.h | 7 +- src/tool.cpp | 99 ++++++++++++++++++--- src/tool.h | 18 ++-- 18 files changed, 228 insertions(+), 70 deletions(-) delete mode 100644 games/devtest/mods/basetools/textures/basetools_dirtpick.png (limited to 'src/server') diff --git a/builtin/game/item.lua b/builtin/game/item.lua index 039947584..c9ccb8801 100644 --- a/builtin/game/item.lua +++ b/builtin/game/item.lua @@ -613,7 +613,7 @@ function core.node_dig(pos, node, digger) if wielded then local wdef = wielded:get_definition() local tp = wielded:get_tool_capabilities() - local dp = core.get_dig_params(def and def.groups, tp) + local dp = core.get_dig_params(def and def.groups, tp, wielded:get_wear()) if wdef and wdef.after_use then wielded = wdef.after_use(wielded, digger, node, dp) or wielded else diff --git a/doc/lua_api.txt b/doc/lua_api.txt index e47df4686..f3007671b 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -1953,8 +1953,9 @@ to implement this. ### Uses (tools only) Determines how many uses the tool has when it is used for digging a node, -of this group, of the maximum level. For lower leveled nodes, the use count -is multiplied by `3^leveldiff`. +of this group, of the maximum level. The maximum supported number of +uses is 65535. The special number 0 is used for infinite uses. +For lower leveled nodes, the use count is multiplied by `3^leveldiff`. `leveldiff` is the difference of the tool's `maxlevel` `groupcaps` and the node's `level` group. The node cannot be dug if `leveldiff` is less than zero. @@ -3475,8 +3476,8 @@ Helper functions * `minetest.pointed_thing_to_face_pos(placer, pointed_thing)`: returns a position. * returns the exact position on the surface of a pointed node -* `minetest.get_dig_params(groups, tool_capabilities)`: Simulates an item - that digs a node. +* `minetest.get_dig_params(groups, tool_capabilities [, wear])`: + Simulates an item that digs a node. Returns a table with the following fields: * `diggable`: `true` if node can be dug, `false` otherwise. * `time`: Time it would take to dig the node. @@ -3485,7 +3486,8 @@ Helper functions Parameters: * `groups`: Table of the node groups of the node that would be dug * `tool_capabilities`: Tool capabilities table of the item -* `minetest.get_hit_params(groups, tool_capabilities [, time_from_last_punch])`: + * `wear`: Amount of wear the tool starts with (default: 0) +* `minetest.get_hit_params(groups, tool_capabilities [, time_from_last_punch [, wear]])`: Simulates an item that punches an object. Returns a table with the following fields: * `hp`: How much damage the punch would cause. @@ -3494,6 +3496,7 @@ Helper functions * `groups`: Damage groups of the object * `tool_capabilities`: Tool capabilities table of the item * `time_from_last_punch`: time in seconds since last punch action + * `wear`: Amount of wear the item starts with (default: 0) diff --git a/games/devtest/mods/basetools/init.lua b/games/devtest/mods/basetools/init.lua index bd7480030..fd83b82eb 100644 --- a/games/devtest/mods/basetools/init.lua +++ b/games/devtest/mods/basetools/init.lua @@ -16,11 +16,11 @@ Tool types: Tool materials: -* Dirt: dig nodes of rating 3, one use only * Wood: dig nodes of rating 3 * Stone: dig nodes of rating 3 or 2 * Steel: dig nodes of rating 3, 2 or 1 * Mese: dig "everything" instantly +* n-Uses: can be used n times before breaking ]] -- The hand @@ -92,20 +92,6 @@ minetest.register_tool("basetools:pick_mese", { -- Pickaxes: Dig cracky -- --- This should break after only 1 use -minetest.register_tool("basetools:pick_dirt", { - description = "Dirt Pickaxe".."\n".. - "Digs cracky=3".."\n".. - "1 use only", - inventory_image = "basetools_dirtpick.png", - tool_capabilities = { - max_drop_level=0, - groupcaps={ - cracky={times={[3]=2.00}, uses=1, maxlevel=0} - }, - }, -}) - minetest.register_tool("basetools:pick_wood", { description = "Wooden Pickaxe".."\n".. "Digs cracky=3", @@ -348,3 +334,31 @@ minetest.register_tool("basetools:dagger_steel", { damage_groups = {fleshy=2}, } }) + +-- Test tool uses and punch_attack_uses +local uses = { 1, 2, 3, 5, 10, 50, 100, 1000, 10000, 65535 } +for i=1, #uses do + local u = uses[i] + local color = string.format("#FF00%02X", math.floor(((i-1)/#uses) * 255)) + minetest.register_tool("basetools:pick_uses_"..string.format("%05d", u), { + description = u.."-Uses Pickaxe".."\n".. + "Digs cracky=3", + inventory_image = "basetools_steelpick.png^[colorize:"..color..":127", + tool_capabilities = { + max_drop_level=0, + groupcaps={ + cracky={times={[3]=0.1, [2]=0.2, [1]=0.3}, uses=u, maxlevel=0} + }, + }, + }) + + minetest.register_tool("basetools:sword_uses_"..string.format("%05d", u), { + description = u.."-Uses Sword".."\n".. + "Damage: fleshy=1", + inventory_image = "basetools_woodsword.png^[colorize:"..color..":127", + tool_capabilities = { + damage_groups = {fleshy=1}, + punch_attack_uses = u, + }, + }) +end diff --git a/games/devtest/mods/basetools/textures/basetools_dirtpick.png b/games/devtest/mods/basetools/textures/basetools_dirtpick.png deleted file mode 100644 index 20a021d72..000000000 Binary files a/games/devtest/mods/basetools/textures/basetools_dirtpick.png and /dev/null differ diff --git a/games/devtest/mods/util_commands/init.lua b/games/devtest/mods/util_commands/init.lua index ca5dca2d9..79acaa0d0 100644 --- a/games/devtest/mods/util_commands/init.lua +++ b/games/devtest/mods/util_commands/init.lua @@ -114,6 +114,59 @@ minetest.register_chatcommand("detach", { end, }) +minetest.register_chatcommand("use_tool", { + params = "(dig ) | (hit ) []", + description = "Apply tool wear a number of times, as if it were used for digging", + func = function(name, param) + local player = minetest.get_player_by_name(name) + if not player then + return false, "No player." + end + local mode, group, level, uses = string.match(param, "([a-z]+) ([a-z0-9]+) (-?%d+) (%d+)") + if not mode then + mode, group, level = string.match(param, "([a-z]+) ([a-z0-9]+) (-?%d+)") + uses = 1 + end + if not mode or not group or not level then + return false + end + if mode ~= "dig" and mode ~= "hit" then + return false + end + local tool = player:get_wielded_item() + local caps = tool:get_tool_capabilities() + if not caps or tool:get_count() == 0 then + return false, "No tool in hand." + end + local actual_uses = 0 + for u=1, uses do + local wear = tool:get_wear() + local dp + if mode == "dig" then + dp = minetest.get_dig_params({[group]=3, level=level}, caps, wear) + else + dp = minetest.get_hit_params({[group]=100}, caps, level, wear) + end + tool:add_wear(dp.wear) + actual_uses = actual_uses + 1 + if tool:get_count() == 0 then + break + end + end + player:set_wielded_item(tool) + if tool:get_count() == 0 then + return true, string.format("Tool used %d time(s). ".. + "The tool broke after %d use(s).", uses, actual_uses) + else + local wear = tool:get_wear() + return true, string.format("Tool used %d time(s). ".. + "Final wear=%d", uses, wear) + end + end, +}) + + + -- Use this to test waypoint capabilities minetest.register_chatcommand("test_waypoints", { params = "[change_immediate]", diff --git a/src/client/content_cao.cpp b/src/client/content_cao.cpp index 1e79d00c9..5c8465b22 100644 --- a/src/client/content_cao.cpp +++ b/src/client/content_cao.cpp @@ -1870,7 +1870,8 @@ bool GenericCAO::directReportPunch(v3f dir, const ItemStack *punchitem, m_armor_groups, toolcap, punchitem, - time_from_last_punch); + time_from_last_punch, + punchitem->wear); if(result.did_punch && result.damage != 0) { diff --git a/src/client/game.cpp b/src/client/game.cpp index 57951dc95..7f0aff49c 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -3619,7 +3619,8 @@ void Game::handleDigging(const PointedThing &pointed, const v3s16 &nodepos, // cheat detection. // Get digging parameters DigParams params = getDigParams(nodedef_manager->get(n).groups, - &selected_item.getToolCapabilities(itemdef_manager)); + &selected_item.getToolCapabilities(itemdef_manager), + selected_item.wear); // If can't dig, try hand if (!params.diggable) { diff --git a/src/network/serverpackethandler.cpp b/src/network/serverpackethandler.cpp index d4bef3ca2..c1ddb5005 100644 --- a/src/network/serverpackethandler.cpp +++ b/src/network/serverpackethandler.cpp @@ -1119,8 +1119,8 @@ void Server::handleCommand_Interact(NetworkPacket *pkt) float time_from_last_punch = playersao->resetTimeFromLastPunch(); - u16 wear = pointed_object->punch(dir, &toolcap, playersao, - time_from_last_punch); + u32 wear = pointed_object->punch(dir, &toolcap, playersao, + time_from_last_punch, tool_item.wear); // Callback may have changed item, so get it again playersao->getWieldedItem(&selected_item); @@ -1173,7 +1173,8 @@ void Server::handleCommand_Interact(NetworkPacket *pkt) // Get diggability and expected digging time DigParams params = getDigParams(m_nodedef->get(n).groups, - &selected_item.getToolCapabilities(m_itemdef)); + &selected_item.getToolCapabilities(m_itemdef), + selected_item.wear); // If can't dig, try hand if (!params.diggable) { params = getDigParams(m_nodedef->get(n).groups, diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp index b7185f7ec..072b13d80 100644 --- a/src/script/lua_api/l_object.cpp +++ b/src/script/lua_api/l_object.cpp @@ -174,7 +174,7 @@ int ObjectRef::l_punch(lua_State *L) v3f dir = readParam(L, 5, sao->getBasePosition() - puncher->getBasePosition()); dir.normalize(); - u16 wear = sao->punch(dir, &toolcap, puncher, time_from_last_punch); + u32 wear = sao->punch(dir, &toolcap, puncher, time_from_last_punch); lua_pushnumber(L, wear); return 1; diff --git a/src/script/lua_api/l_util.cpp b/src/script/lua_api/l_util.cpp index 2405cd90d..53319ccfd 100644 --- a/src/script/lua_api/l_util.cpp +++ b/src/script/lua_api/l_util.cpp @@ -160,28 +160,33 @@ int ModApiUtil::l_write_json(lua_State *L) return 1; } -// get_dig_params(groups, tool_capabilities) +// get_dig_params(groups, tool_capabilities[, wear]) int ModApiUtil::l_get_dig_params(lua_State *L) { NO_MAP_LOCK_REQUIRED; ItemGroupList groups; read_groups(L, 1, groups); ToolCapabilities tp = read_tool_capabilities(L, 2); - push_dig_params(L, getDigParams(groups, &tp)); + if (lua_isnoneornil(L, 3)) { + push_dig_params(L, getDigParams(groups, &tp)); + } else { + u16 wear = readParam(L, 3); + push_dig_params(L, getDigParams(groups, &tp, wear)); + } return 1; } -// get_hit_params(groups, tool_capabilities[, time_from_last_punch]) +// get_hit_params(groups, tool_capabilities[, time_from_last_punch, [, wear]]) int ModApiUtil::l_get_hit_params(lua_State *L) { NO_MAP_LOCK_REQUIRED; std::unordered_map groups; read_groups(L, 1, groups); ToolCapabilities tp = read_tool_capabilities(L, 2); - if(lua_isnoneornil(L, 3)) - push_hit_params(L, getHitParams(groups, &tp)); - else - push_hit_params(L, getHitParams(groups, &tp, readParam(L, 3))); + float time_from_last_punch = readParam(L, 3, 1000000); + int wear = readParam(L, 4, 0); + push_hit_params(L, getHitParams(groups, &tp, + time_from_last_punch, wear)); return 1; } diff --git a/src/script/lua_api/l_util.h b/src/script/lua_api/l_util.h index cc91e8d39..314e92f5c 100644 --- a/src/script/lua_api/l_util.h +++ b/src/script/lua_api/l_util.h @@ -50,10 +50,10 @@ private: // write_json(data[, styled]) static int l_write_json(lua_State *L); - // get_dig_params(groups, tool_capabilities[, time_from_last_punch]) + // get_dig_params(groups, tool_capabilities[, wear]) static int l_get_dig_params(lua_State *L); - // get_hit_params(groups, tool_capabilities[, time_from_last_punch]) + // get_hit_params(groups, tool_capabilities[, time_from_last_punch[, wear]]) static int l_get_hit_params(lua_State *L); // check_password_entry(name, entry, password) diff --git a/src/server/luaentity_sao.cpp b/src/server/luaentity_sao.cpp index 1d65ac306..82f6da231 100644 --- a/src/server/luaentity_sao.cpp +++ b/src/server/luaentity_sao.cpp @@ -305,10 +305,11 @@ void LuaEntitySAO::getStaticData(std::string *result) const *result = os.str(); } -u16 LuaEntitySAO::punch(v3f dir, +u32 LuaEntitySAO::punch(v3f dir, const ToolCapabilities *toolcap, ServerActiveObject *puncher, - float time_from_last_punch) + float time_from_last_punch, + u16 initial_wear) { if (!m_registered) { // Delete unknown LuaEntities when punched @@ -326,7 +327,8 @@ u16 LuaEntitySAO::punch(v3f dir, m_armor_groups, toolcap, &tool_item, - time_from_last_punch); + time_from_last_punch, + initial_wear); bool damage_handled = m_env->getScriptIface()->luaentity_Punch(m_id, puncher, time_from_last_punch, toolcap, dir, result.did_punch ? result.damage : 0); diff --git a/src/server/luaentity_sao.h b/src/server/luaentity_sao.h index 6883ae1b9..87b664a8b 100644 --- a/src/server/luaentity_sao.h +++ b/src/server/luaentity_sao.h @@ -44,9 +44,10 @@ public: bool isStaticAllowed() const { return m_prop.static_save; } bool shouldUnload() const { return true; } void getStaticData(std::string *result) const; - u16 punch(v3f dir, const ToolCapabilities *toolcap = nullptr, + u32 punch(v3f dir, const ToolCapabilities *toolcap = nullptr, ServerActiveObject *puncher = nullptr, - float time_from_last_punch = 1000000.0f); + float time_from_last_punch = 1000000.0f, + u16 initial_wear = 0); void rightClick(ServerActiveObject *clicker); void setPos(const v3f &pos); void moveTo(v3f pos, bool continuous); diff --git a/src/server/player_sao.cpp b/src/server/player_sao.cpp index 690823bb7..83e17f830 100644 --- a/src/server/player_sao.cpp +++ b/src/server/player_sao.cpp @@ -409,10 +409,11 @@ void PlayerSAO::setLookPitchAndSend(const float pitch) m_env->getGameDef()->SendMovePlayer(m_peer_id); } -u16 PlayerSAO::punch(v3f dir, +u32 PlayerSAO::punch(v3f dir, const ToolCapabilities *toolcap, ServerActiveObject *puncher, - float time_from_last_punch) + float time_from_last_punch, + u16 initial_wear) { if (!toolcap) return 0; @@ -430,7 +431,7 @@ u16 PlayerSAO::punch(v3f dir, s32 old_hp = getHP(); HitParams hitparams = getHitParams(m_armor_groups, toolcap, - time_from_last_punch); + time_from_last_punch, initial_wear); PlayerSAO *playersao = m_player->getPlayerSAO(); diff --git a/src/server/player_sao.h b/src/server/player_sao.h index 1429d7129..47fe85413 100644 --- a/src/server/player_sao.h +++ b/src/server/player_sao.h @@ -109,8 +109,8 @@ public: Interaction interface */ - u16 punch(v3f dir, const ToolCapabilities *toolcap, ServerActiveObject *puncher, - float time_from_last_punch); + u32 punch(v3f dir, const ToolCapabilities *toolcap, ServerActiveObject *puncher, + float time_from_last_punch, u16 initial_wear = 0); void rightClick(ServerActiveObject *clicker); void setHP(s32 hp, const PlayerHPChangeReason &reason) override { diff --git a/src/server/serveractiveobject.h b/src/server/serveractiveobject.h index 51f445914..5b0ee2d9b 100644 --- a/src/server/serveractiveobject.h +++ b/src/server/serveractiveobject.h @@ -145,11 +145,12 @@ public: virtual bool shouldUnload() const { return true; } - // Returns tool wear - virtual u16 punch(v3f dir, + // Returns added tool wear + virtual u32 punch(v3f dir, const ToolCapabilities *toolcap = nullptr, ServerActiveObject *puncher = nullptr, - float time_from_last_punch = 1000000.0f) + float time_from_last_punch = 1000000.0f, + u16 initial_wear = 0) { return 0; } virtual void rightClick(ServerActiveObject *clicker) {} diff --git a/src/tool.cpp b/src/tool.cpp index 3f639a69e..b0749286d 100644 --- a/src/tool.cpp +++ b/src/tool.cpp @@ -183,9 +183,74 @@ void ToolCapabilities::deserializeJson(std::istream &is) } } +static u32 calculateResultWear(const u32 uses, const u16 initial_wear) +{ + if (uses == 0) { + // Trivial case: Infinite uses + return 0; + } + /* Finite uses. This is not trivial, + as the maximum wear is not neatly evenly divisible by + most possible uses numbers. For example, for 128 + uses, the calculation of wear is trivial, as + 65536 / 128 uses = 512 wear, + so the tool will get 512 wear 128 times in its lifetime. + But for a number like 130, this does not work: + 65536 / 130 uses = 504.123... wear. + Since wear must be an integer, we will get + 504*130 = 65520, which would lead to the wrong number + of uses. + + Instead, we partition the "wear range" into blocks: + A block represents a single use and can be + of two possible sizes: normal and oversized. + A normal block is equal to floor(65536 / uses). + An oversized block is a normal block plus 1. + Then we determine how many oversized and normal + blocks we need and finally, whether we add + the normal wear or the oversized wear. + + Example for 130 uses: + * Normal wear = 504 + * Number of normal blocks = 114 + * Oversized wear = 505 + * Number of oversized blocks = 16 + + If we add everything together, we get: + 114*504 + 16*505 = 65536 + */ + u32 result_wear; + u32 wear_normal = ((U16_MAX+1) / uses); + // Will be non-zero if its not evenly divisible + u16 blocks_oversize = (U16_MAX+1) % uses; + // Whether to add one extra wear point in case + // of oversized wear. + u16 wear_extra = 0; + if (blocks_oversize > 0) { + u16 blocks_normal = uses - blocks_oversize; + /* When the wear has reached this value, we + know that wear_normal has been applied + for blocks_normal times, therefore, + only oversized blocks remain. + This also implies the raw tool wear number + increases a bit faster after this point, + but this should be barely noticable by the + player. + */ + u16 wear_extra_at = blocks_normal * wear_normal; + if (initial_wear >= wear_extra_at) { + wear_extra = 1; + } + } + result_wear = wear_normal + wear_extra; + return result_wear; +} + DigParams getDigParams(const ItemGroupList &groups, - const ToolCapabilities *tp) + const ToolCapabilities *tp, + const u16 initial_wear) { + // Group dig_immediate defaults to fixed time and no wear if (tp->groupcaps.find("dig_immediate") == tp->groupcaps.cend()) { switch (itemgroup_get(groups, "dig_immediate")) { @@ -201,7 +266,7 @@ DigParams getDigParams(const ItemGroupList &groups, // Values to be returned (with a bit of conversion) bool result_diggable = false; float result_time = 0.0; - float result_wear = 0.0; + u32 result_wear = 0; std::string result_main_group; int level = itemgroup_get(groups, "level"); @@ -224,20 +289,22 @@ DigParams getDigParams(const ItemGroupList &groups, if (!result_diggable || time < result_time) { result_time = time; result_diggable = true; - if (cap.uses != 0) - result_wear = 1.0 / cap.uses / pow(3.0, leveldiff); - else - result_wear = 0; + // The actual number of uses increases + // exponentially with leveldiff. + // If the levels are equal, real_uses equals cap.uses. + u32 real_uses = cap.uses * pow(3.0, leveldiff); + real_uses = MYMIN(real_uses, U16_MAX); + result_wear = calculateResultWear(real_uses, initial_wear); result_main_group = groupname; } } - u16 wear_i = U16_MAX * result_wear; - return DigParams(result_diggable, result_time, wear_i, result_main_group); + return DigParams(result_diggable, result_time, result_wear, result_main_group); } HitParams getHitParams(const ItemGroupList &armor_groups, - const ToolCapabilities *tp, float time_from_last_punch) + const ToolCapabilities *tp, float time_from_last_punch, + u16 initial_wear) { s16 damage = 0; float result_wear = 0.0f; @@ -249,10 +316,12 @@ HitParams getHitParams(const ItemGroupList &armor_groups, damage += damageGroup.second * punch_interval_multiplier * armor / 100.0; } - if (tp->punch_attack_uses > 0) - result_wear = 1.0f / tp->punch_attack_uses * punch_interval_multiplier; + if (tp->punch_attack_uses > 0) { + result_wear = calculateResultWear(tp->punch_attack_uses, initial_wear); + result_wear *= punch_interval_multiplier; + } - u16 wear_i = U16_MAX * result_wear; + u32 wear_i = (u32) result_wear; return {damage, wear_i}; } @@ -266,7 +335,8 @@ PunchDamageResult getPunchDamage( const ItemGroupList &armor_groups, const ToolCapabilities *toolcap, const ItemStack *punchitem, - float time_from_last_punch + float time_from_last_punch, + u16 initial_wear ){ bool do_hit = true; { @@ -286,7 +356,8 @@ PunchDamageResult getPunchDamage( if(do_hit) { HitParams hitparams = getHitParams(armor_groups, toolcap, - time_from_last_punch); + time_from_last_punch, + punchitem->wear); result.did_punch = true; result.wear = hitparams.wear; result.damage = hitparams.hp; diff --git a/src/tool.h b/src/tool.h index 59dd501f5..0e3388485 100644 --- a/src/tool.h +++ b/src/tool.h @@ -88,10 +88,10 @@ struct DigParams // Digging time in seconds float time; // Caused wear - u16 wear; + u32 wear; // u32 because wear could be 65536 (single-use tool) std::string main_group; - DigParams(bool a_diggable = false, float a_time = 0.0f, u16 a_wear = 0, + DigParams(bool a_diggable = false, float a_time = 0.0f, u32 a_wear = 0, const std::string &a_main_group = ""): diggable(a_diggable), time(a_time), @@ -101,21 +101,24 @@ struct DigParams }; DigParams getDigParams(const ItemGroupList &groups, - const ToolCapabilities *tp); + const ToolCapabilities *tp, + const u16 initial_wear = 0); struct HitParams { s16 hp; - u16 wear; + // Caused wear + u32 wear; // u32 because wear could be 65536 (single-use weapon) - HitParams(s16 hp_ = 0, u16 wear_ = 0): + HitParams(s16 hp_ = 0, u32 wear_ = 0): hp(hp_), wear(wear_) {} }; HitParams getHitParams(const ItemGroupList &armor_groups, - const ToolCapabilities *tp, float time_from_last_punch); + const ToolCapabilities *tp, float time_from_last_punch, + u16 initial_wear = 0); HitParams getHitParams(const ItemGroupList &armor_groups, const ToolCapabilities *tp); @@ -135,7 +138,8 @@ PunchDamageResult getPunchDamage( const ItemGroupList &armor_groups, const ToolCapabilities *toolcap, const ItemStack *punchitem, - float time_from_last_punch + float time_from_last_punch, + u16 initial_wear = 0 ); f32 getToolRange(const ItemDefinition &def_selected, const ItemDefinition &def_hand); -- cgit v1.2.3 From d9d219356aa31cd953303580ccde7f0e27dd0fe6 Mon Sep 17 00:00:00 2001 From: sfan5 Date: Mon, 6 Dec 2021 00:04:33 +0100 Subject: Fix get_bone_position() on unset bones modifying their position closes #11840 --- src/server/unit_sao.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src/server') diff --git a/src/server/unit_sao.cpp b/src/server/unit_sao.cpp index acbdd478a..9a49b0f43 100644 --- a/src/server/unit_sao.cpp +++ b/src/server/unit_sao.cpp @@ -84,8 +84,11 @@ void UnitSAO::setBonePosition(const std::string &bone, v3f position, v3f rotatio void UnitSAO::getBonePosition(const std::string &bone, v3f *position, v3f *rotation) { - *position = m_bone_position[bone].X; - *rotation = m_bone_position[bone].Y; + auto it = m_bone_position.find(bone); + if (it != m_bone_position.end()) { + *position = it->second.X; + *rotation = it->second.Y; + } } // clang-format off -- cgit v1.2.3 From d33ab97434633683196cee2c4593160736899124 Mon Sep 17 00:00:00 2001 From: SmallJoker Date: Tue, 4 Jan 2022 18:39:27 +0100 Subject: Inventory: Add ServerEnv checks for calls during script init This fixes 'minetest.get_inventory' calls to players or nodes during the load phase. --- src/server/serverinventorymgr.cpp | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) (limited to 'src/server') diff --git a/src/server/serverinventorymgr.cpp b/src/server/serverinventorymgr.cpp index 3aee003b4..63d1645cb 100644 --- a/src/server/serverinventorymgr.cpp +++ b/src/server/serverinventorymgr.cpp @@ -39,24 +39,29 @@ ServerInventoryManager::~ServerInventoryManager() Inventory *ServerInventoryManager::getInventory(const InventoryLocation &loc) { + // No m_env check here: allow creation and modification of detached inventories + switch (loc.type) { case InventoryLocation::UNDEFINED: case InventoryLocation::CURRENT_PLAYER: break; case InventoryLocation::PLAYER: { + if (!m_env) + return nullptr; + RemotePlayer *player = m_env->getPlayer(loc.name.c_str()); if (!player) return NULL; + PlayerSAO *playersao = player->getPlayerSAO(); - if (!playersao) - return NULL; - return playersao->getInventory(); + return playersao ? playersao->getInventory() : nullptr; } break; case InventoryLocation::NODEMETA: { + if (!m_env) + return nullptr; + NodeMetadata *meta = m_env->getMap().getNodeMetadata(loc.p); - if (!meta) - return NULL; - return meta->getInventory(); + return meta ? meta->getInventory() : nullptr; } break; case InventoryLocation::DETACHED: { auto it = m_detached_inventories.find(loc.name); @@ -151,12 +156,13 @@ bool ServerInventoryManager::removeDetachedInventory(const std::string &name) const std::string &owner = inv_it->second.owner; if (!owner.empty()) { - RemotePlayer *player = m_env->getPlayer(owner.c_str()); - - if (player && player->getPeerId() != PEER_ID_INEXISTENT) - m_env->getGameDef()->sendDetachedInventory( - nullptr, name, player->getPeerId()); + if (m_env) { + RemotePlayer *player = m_env->getPlayer(owner.c_str()); + if (player && player->getPeerId() != PEER_ID_INEXISTENT) + m_env->getGameDef()->sendDetachedInventory( + nullptr, name, player->getPeerId()); + } } else if (m_env) { // Notify all players about the change as soon ServerEnv exists m_env->getGameDef()->sendDetachedInventory( -- cgit v1.2.3 From 72b14bd994659163d4c2ea0d769d329df8a0f937 Mon Sep 17 00:00:00 2001 From: savilli <78875209+savilli@users.noreply.github.com> Date: Sat, 15 Jan 2022 17:44:55 +0100 Subject: Don't call on_dieplayer callback two times (#11874) --- src/network/serverpackethandler.cpp | 3 +-- src/server.cpp | 51 +++++++++++++------------------------ src/server.h | 6 ++--- src/server/player_sao.cpp | 37 +++++++++++++-------------- src/server/player_sao.h | 4 +-- 5 files changed, 41 insertions(+), 60 deletions(-) (limited to 'src/server') diff --git a/src/network/serverpackethandler.cpp b/src/network/serverpackethandler.cpp index 37b62c5cb..12dc24460 100644 --- a/src/network/serverpackethandler.cpp +++ b/src/network/serverpackethandler.cpp @@ -819,8 +819,7 @@ void Server::handleCommand_Damage(NetworkPacket* pkt) << std::endl; PlayerHPChangeReason reason(PlayerHPChangeReason::FALL); - playersao->setHP((s32)playersao->getHP() - (s32)damage, reason, false); - SendPlayerHPOrDie(playersao, reason); // correct client side prediction + playersao->setHP((s32)playersao->getHP() - (s32)damage, reason, true); } } diff --git a/src/server.cpp b/src/server.cpp index 6cf790de1..45156db61 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -1095,11 +1095,12 @@ PlayerSAO* Server::StageTwoClientInit(session_t peer_id) // Send inventory SendInventory(playersao, false); - // Send HP or death screen + // Send HP + SendPlayerHP(playersao); + + // Send death screen if (playersao->isDead()) SendDeathscreen(peer_id, false, v3f(0,0,0)); - else - SendPlayerHP(peer_id); // Send Breath SendPlayerBreath(playersao); @@ -1365,18 +1366,21 @@ void Server::SendMovement(session_t peer_id) Send(&pkt); } -void Server::SendPlayerHPOrDie(PlayerSAO *playersao, const PlayerHPChangeReason &reason) +void Server::HandlePlayerHPChange(PlayerSAO *playersao, const PlayerHPChangeReason &reason) { - if (playersao->isImmortal()) - return; + m_script->player_event(playersao, "health_changed"); + SendPlayerHP(playersao); - session_t peer_id = playersao->getPeerID(); - bool is_alive = !playersao->isDead(); + // Send to other clients + playersao->sendPunchCommand(); - if (is_alive) - SendPlayerHP(peer_id); - else - DiePlayer(peer_id, reason); + if (playersao->isDead()) + HandlePlayerDeath(playersao, reason); +} + +void Server::SendPlayerHP(PlayerSAO *playersao) +{ + SendHP(playersao->getPeerID(), playersao->getHP()); } void Server::SendHP(session_t peer_id, u16 hp) @@ -1810,18 +1814,6 @@ void Server::SendTimeOfDay(session_t peer_id, u16 time, f32 time_speed) } } -void Server::SendPlayerHP(session_t peer_id) -{ - PlayerSAO *playersao = getPlayerSAO(peer_id); - assert(playersao); - - SendHP(peer_id, playersao->getHP()); - m_script->player_event(playersao,"health_changed"); - - // Send to other clients - playersao->sendPunchCommand(); -} - void Server::SendPlayerBreath(PlayerSAO *sao) { assert(sao); @@ -2750,23 +2742,18 @@ void Server::sendDetachedInventories(session_t peer_id, bool incremental) Something random */ -void Server::DiePlayer(session_t peer_id, const PlayerHPChangeReason &reason) +void Server::HandlePlayerDeath(PlayerSAO *playersao, const PlayerHPChangeReason &reason) { - PlayerSAO *playersao = getPlayerSAO(peer_id); - assert(playersao); - infostream << "Server::DiePlayer(): Player " << playersao->getPlayer()->getName() << " dies" << std::endl; - playersao->setHP(0, reason); playersao->clearParentAttachment(); // Trigger scripted stuff m_script->on_dieplayer(playersao, reason); - SendPlayerHP(peer_id); - SendDeathscreen(peer_id, false, v3f(0,0,0)); + SendDeathscreen(playersao->getPeerID(), false, v3f(0,0,0)); } void Server::RespawnPlayer(session_t peer_id) @@ -2787,8 +2774,6 @@ void Server::RespawnPlayer(session_t peer_id) // setPos will send the new position to client playersao->setPos(findSpawnPos()); } - - SendPlayerHP(peer_id); } diff --git a/src/server.h b/src/server.h index 12158feb7..2741b3157 100644 --- a/src/server.h +++ b/src/server.h @@ -350,7 +350,8 @@ public: void printToConsoleOnly(const std::string &text); - void SendPlayerHPOrDie(PlayerSAO *player, const PlayerHPChangeReason &reason); + void HandlePlayerHPChange(PlayerSAO *sao, const PlayerHPChangeReason &reason); + void SendPlayerHP(PlayerSAO *sao); void SendPlayerBreath(PlayerSAO *sao); void SendInventory(PlayerSAO *playerSAO, bool incremental); void SendMovePlayer(session_t peer_id); @@ -438,7 +439,6 @@ private: virtual void SendChatMessage(session_t peer_id, const ChatMessage &message); void SendTimeOfDay(session_t peer_id, u16 time, f32 time_speed); - void SendPlayerHP(session_t peer_id); void SendLocalPlayerAnimations(session_t peer_id, v2s32 animation_frames[4], f32 animation_speed); @@ -510,7 +510,7 @@ private: Something random */ - void DiePlayer(session_t peer_id, const PlayerHPChangeReason &reason); + void HandlePlayerDeath(PlayerSAO* sao, const PlayerHPChangeReason &reason); void RespawnPlayer(session_t peer_id); void DeleteClient(session_t peer_id, ClientDeletionReason reason); void UpdateCrafting(RemotePlayer *player); diff --git a/src/server/player_sao.cpp b/src/server/player_sao.cpp index 83e17f830..d076d5783 100644 --- a/src/server/player_sao.cpp +++ b/src/server/player_sao.cpp @@ -463,36 +463,33 @@ void PlayerSAO::rightClick(ServerActiveObject *clicker) m_env->getScriptIface()->on_rightclickplayer(this, clicker); } -void PlayerSAO::setHP(s32 hp, const PlayerHPChangeReason &reason, bool send) +void PlayerSAO::setHP(s32 target_hp, const PlayerHPChangeReason &reason, bool from_client) { - if (hp == (s32)m_hp) - return; // Nothing to do + target_hp = rangelim(target_hp, 0, U16_MAX); - if (m_hp <= 0 && hp < (s32)m_hp) - return; // Cannot take more damage + if (target_hp == m_hp) + return; // Nothing to do - { - s32 hp_change = m_env->getScriptIface()->on_player_hpchange(this, hp - m_hp, reason); - if (hp_change == 0) - return; + s32 hp_change = m_env->getScriptIface()->on_player_hpchange(this, target_hp - (s32)m_hp, reason); - hp = m_hp + hp_change; - } + s32 hp = (s32)m_hp + std::min(hp_change, U16_MAX); // Protection against s32 overflow + hp = rangelim(hp, 0, U16_MAX); - s32 oldhp = m_hp; - hp = rangelim(hp, 0, m_prop.hp_max); + if (hp > m_prop.hp_max) + hp = m_prop.hp_max; - if (hp < oldhp && isImmortal()) - return; // Do not allow immortal players to be damaged - - m_hp = hp; + if (hp < m_hp && isImmortal()) + hp = m_hp; // Do not allow immortal players to be damaged // Update properties on death - if ((hp == 0) != (oldhp == 0)) + if ((hp == 0) != (m_hp == 0)) m_properties_sent = false; - if (send) - m_env->getGameDef()->SendPlayerHPOrDie(this, reason); + if (hp != m_hp) { + m_hp = hp; + m_env->getGameDef()->HandlePlayerHPChange(this, reason); + } else if (from_client) + m_env->getGameDef()->SendPlayerHP(this); } void PlayerSAO::setBreath(const u16 breath, bool send) diff --git a/src/server/player_sao.h b/src/server/player_sao.h index 47fe85413..96d8f7189 100644 --- a/src/server/player_sao.h +++ b/src/server/player_sao.h @@ -114,9 +114,9 @@ public: void rightClick(ServerActiveObject *clicker); void setHP(s32 hp, const PlayerHPChangeReason &reason) override { - return setHP(hp, reason, true); + return setHP(hp, reason, false); } - void setHP(s32 hp, const PlayerHPChangeReason &reason, bool send); + void setHP(s32 hp, const PlayerHPChangeReason &reason, bool from_client); void setHPRaw(u16 hp) { m_hp = hp; } u16 getBreath() const { return m_breath; } void setBreath(const u16 breath, bool send = true); -- cgit v1.2.3 From 128f6359e936bcdc5e26409ddd73438bce9c6dd6 Mon Sep 17 00:00:00 2001 From: rubenwardy Date: Sun, 30 Jan 2022 22:40:53 +0000 Subject: Use virtual paths to specify exact mod to enable (#11784) --- builtin/mainmenu/dlg_config_world.lua | 25 ++++++++-- builtin/mainmenu/dlg_settings_advanced.lua | 2 +- builtin/mainmenu/pkgmgr.lua | 72 +++++++++++++++++++--------- doc/menu_lua_api.txt | 17 +++++-- doc/world_format.txt | 13 +++++ src/content/mods.cpp | 76 +++++++++++++++++++++--------- src/content/mods.h | 57 ++++++++++++++++++---- src/content/subgames.cpp | 11 ++--- src/content/subgames.h | 10 ++-- src/script/lua_api/l_mainmenu.cpp | 12 ++--- src/server/mods.cpp | 6 ++- 11 files changed, 222 insertions(+), 79 deletions(-) (limited to 'src/server') diff --git a/builtin/mainmenu/dlg_config_world.lua b/builtin/mainmenu/dlg_config_world.lua index 9bdf92a74..510d9f804 100644 --- a/builtin/mainmenu/dlg_config_world.lua +++ b/builtin/mainmenu/dlg_config_world.lua @@ -205,14 +205,19 @@ local function handle_buttons(this, fields) local mods = worldfile:to_table() local rawlist = this.data.list:get_raw_list() + local was_set = {} for i = 1, #rawlist do local mod = rawlist[i] if not mod.is_modpack and not mod.is_game_content then if modname_valid(mod.name) then - worldfile:set("load_mod_" .. mod.name, - mod.enabled and "true" or "false") + if mod.enabled then + worldfile:set("load_mod_" .. mod.name, mod.virtual_path) + was_set[mod.name] = true + elseif not was_set[mod.name] then + worldfile:set("load_mod_" .. mod.name, "false") + end elseif mod.enabled then gamedata.errormessage = fgettext_ne("Failed to enable mo" .. "d \"$1\" as it contains disallowed characters. " .. @@ -256,12 +261,26 @@ local function handle_buttons(this, fields) if fields.btn_enable_all_mods then local list = this.data.list:get_raw_list() + -- When multiple copies of a mod are installed, we need to avoid enabling multiple of them + -- at a time. So lets first collect all the enabled mods, and then use this to exclude + -- multiple enables. + + local was_enabled = {} for i = 1, #list do if not list[i].is_game_content - and not list[i].is_modpack then + and not list[i].is_modpack and list[i].enabled then + was_enabled[list[i].name] = true + end + end + + for i = 1, #list do + if not list[i].is_game_content and not list[i].is_modpack and + not was_enabled[list[i].name] then list[i].enabled = true + was_enabled[list[i].name] = true end end + enabled_all = true return true end diff --git a/builtin/mainmenu/dlg_settings_advanced.lua b/builtin/mainmenu/dlg_settings_advanced.lua index 06fd32d84..772509670 100644 --- a/builtin/mainmenu/dlg_settings_advanced.lua +++ b/builtin/mainmenu/dlg_settings_advanced.lua @@ -378,7 +378,7 @@ local function parse_config_file(read_all, parse_mods) -- Parse mods local mods_category_initialized = false local mods = {} - get_mods(core.get_modpath(), mods) + get_mods(core.get_modpath(), "mods", mods) for _, mod in ipairs(mods) do local path = mod.path .. DIR_DELIM .. FILENAME local file = io.open(path, "r") diff --git a/builtin/mainmenu/pkgmgr.lua b/builtin/mainmenu/pkgmgr.lua index 6de671529..eeeb5641b 100644 --- a/builtin/mainmenu/pkgmgr.lua +++ b/builtin/mainmenu/pkgmgr.lua @@ -100,12 +100,13 @@ local function load_texture_packs(txtpath, retval) end end -function get_mods(path,retval,modpack) +function get_mods(path, virtual_path, retval, modpack) local mods = core.get_dir_list(path, true) for _, name in ipairs(mods) do if name:sub(1, 1) ~= "." then - local prefix = path .. DIR_DELIM .. name + local mod_path = path .. DIR_DELIM .. name + local mod_virtual_path = virtual_path .. "/" .. name local toadd = { dir_name = name, parent_dir = path, @@ -114,18 +115,18 @@ function get_mods(path,retval,modpack) -- Get config file local mod_conf - local modpack_conf = io.open(prefix .. DIR_DELIM .. "modpack.conf") + local modpack_conf = io.open(mod_path .. DIR_DELIM .. "modpack.conf") if modpack_conf then toadd.is_modpack = true modpack_conf:close() - mod_conf = Settings(prefix .. DIR_DELIM .. "modpack.conf"):to_table() + mod_conf = Settings(mod_path .. DIR_DELIM .. "modpack.conf"):to_table() if mod_conf.name then name = mod_conf.name toadd.is_name_explicit = true end else - mod_conf = Settings(prefix .. DIR_DELIM .. "mod.conf"):to_table() + mod_conf = Settings(mod_path .. DIR_DELIM .. "mod.conf"):to_table() if mod_conf.name then name = mod_conf.name toadd.is_name_explicit = true @@ -136,12 +137,13 @@ function get_mods(path,retval,modpack) toadd.name = name toadd.author = mod_conf.author toadd.release = tonumber(mod_conf.release) or 0 - toadd.path = prefix + toadd.path = mod_path + toadd.virtual_path = mod_virtual_path toadd.type = "mod" -- Check modpack.txt -- Note: modpack.conf is already checked above - local modpackfile = io.open(prefix .. DIR_DELIM .. "modpack.txt") + local modpackfile = io.open(mod_path .. DIR_DELIM .. "modpack.txt") if modpackfile then modpackfile:close() toadd.is_modpack = true @@ -153,7 +155,7 @@ function get_mods(path,retval,modpack) elseif toadd.is_modpack then toadd.type = "modpack" toadd.is_modpack = true - get_mods(prefix, retval, name) + get_mods(mod_path, mod_virtual_path, retval, name) end end end @@ -397,6 +399,14 @@ function pkgmgr.is_modpack_entirely_enabled(data, name) return true end +local function disable_all_by_name(list, name, except) + for i=1, #list do + if list[i].name == name and list[i] ~= except then + list[i].enabled = false + end + end +end + ---------- toggles or en/disables a mod or modpack and its dependencies -------- local function toggle_mod_or_modpack(list, toggled_mods, enabled_mods, toset, mod) if not mod.is_modpack then @@ -404,6 +414,9 @@ local function toggle_mod_or_modpack(list, toggled_mods, enabled_mods, toset, mo if toset == nil then toset = not mod.enabled end + if toset then + disable_all_by_name(list, mod.name, mod) + end if mod.enabled ~= toset then mod.enabled = toset toggled_mods[#toggled_mods+1] = mod.name @@ -648,8 +661,8 @@ function pkgmgr.preparemodlist(data) --read global mods local modpaths = core.get_modpaths() - for _, modpath in ipairs(modpaths) do - get_mods(modpath, global_mods) + for key, modpath in pairs(modpaths) do + get_mods(modpath, key, global_mods) end for i=1,#global_mods,1 do @@ -688,22 +701,37 @@ function pkgmgr.preparemodlist(data) DIR_DELIM .. "world.mt" local worldfile = Settings(filename) - - for key,value in pairs(worldfile:to_table()) do + for key, value in pairs(worldfile:to_table()) do if key:sub(1, 9) == "load_mod_" then key = key:sub(10) - local element = nil - for i=1,#retval,1 do + local mod_found = false + + local fallback_found = false + local fallback_mod = nil + + for i=1, #retval do if retval[i].name == key and - not retval[i].is_modpack then - element = retval[i] - break + not retval[i].is_modpack then + if core.is_yes(value) or retval[i].virtual_path == value then + retval[i].enabled = true + mod_found = true + break + elseif fallback_found then + -- Only allow fallback if only one mod matches + fallback_mod = nil + else + fallback_found = true + fallback_mod = retval[i] + end end end - if element ~= nil then - element.enabled = value ~= "false" and value ~= "nil" and value - else - core.log("info", "Mod: " .. key .. " " .. dump(value) .. " but not found") + + if not mod_found then + if fallback_mod and value:find("/") then + fallback_mod.enabled = true + else + core.log("info", "Mod: " .. key .. " " .. dump(value) .. " but not found") + end end end end @@ -797,7 +825,7 @@ function pkgmgr.get_game_mods(gamespec, retval) if gamespec ~= nil and gamespec.gamemods_path ~= nil and gamespec.gamemods_path ~= "" then - get_mods(gamespec.gamemods_path, retval) + get_mods(gamespec.gamemods_path, ("games/%s/mods"):format(gamespec.id), retval) end end diff --git a/doc/menu_lua_api.txt b/doc/menu_lua_api.txt index a8928441e..c2931af31 100644 --- a/doc/menu_lua_api.txt +++ b/doc/menu_lua_api.txt @@ -221,13 +221,24 @@ Package - content which is downloadable from the content db, may or may not be i * returns path to global user data, the directory that contains user-provided mods, worlds, games, and texture packs. * core.get_modpath() (possible in async calls) - * returns path to global modpath, where mods can be installed + * returns path to global modpath in the user path, where mods can be installed * core.get_modpaths() (possible in async calls) - * returns list of paths to global modpaths, where mods have been installed - + * returns table of virtual path to global modpaths, where mods have been installed The difference with "core.get_modpath" is that no mods should be installed in these directories by Minetest -- they might be read-only. + Ex: + + ``` + { + mods = "/home/user/.minetest/mods", + share = "/usr/share/minetest/mods", + + -- Custom dirs can be specified by the MINETEST_MOD_DIR env variable + ["/path/to/custom/dir"] = "/path/to/custom/dir", + } + ``` + * core.get_clientmodpath() (possible in async calls) * returns path to global client-side modpath * core.get_gamepath() (possible in async calls) diff --git a/doc/world_format.txt b/doc/world_format.txt index eb1d7f728..98c9d2009 100644 --- a/doc/world_format.txt +++ b/doc/world_format.txt @@ -133,6 +133,19 @@ Example content (added indentation and - explanations): load_mod_ = false - whether is to be loaded in this world auth_backend = files - which DB backend to use for authentication data +For load_mod_, the possible values are: + +* `false` - Do not load the mod. +* `true` - Load the mod from wherever it is found (may cause conflicts if the same mod appears also in some other place). +* `mods/modpack/moddir` - Relative path to the mod + * Must be one of the following: + * `mods/`: mods in the user path's mods folder (ex `/home/user/.minetest/mods`) + * `share/`: mods in the share's mods folder (ex: `/usr/share/minetest/mods`) + * `/path/to/env`: you can use absolute paths to mods inside folders specified with the `MINETEST_MOD_PATH` env variable. + * Other locations and absolute paths are not supported + * Note that `moddir` is the directory name, not the mod name specified in mod.conf. + + Player File Format =================== diff --git a/src/content/mods.cpp b/src/content/mods.cpp index 455506967..f75119bbb 100644 --- a/src/content/mods.cpp +++ b/src/content/mods.cpp @@ -89,7 +89,7 @@ void parseModContents(ModSpec &spec) modpack2_is.close(); spec.is_modpack = true; - spec.modpack_content = getModsInPath(spec.path, true); + spec.modpack_content = getModsInPath(spec.path, spec.virtual_path, true); } else { Settings info; @@ -167,13 +167,14 @@ void parseModContents(ModSpec &spec) } std::map getModsInPath( - const std::string &path, bool part_of_modpack) + const std::string &path, const std::string &virtual_path, bool part_of_modpack) { // NOTE: this function works in mutual recursion with parseModContents std::map result; std::vector dirlist = fs::GetDirListing(path); - std::string modpath; + std::string mod_path; + std::string mod_virtual_path; for (const fs::DirListNode &dln : dirlist) { if (!dln.dir) @@ -185,10 +186,14 @@ std::map getModsInPath( if (modname[0] == '.') continue; - modpath.clear(); - modpath.append(path).append(DIR_DELIM).append(modname); + mod_path.clear(); + mod_path.append(path).append(DIR_DELIM).append(modname); - ModSpec spec(modname, modpath, part_of_modpack); + mod_virtual_path.clear(); + // Intentionally uses / to keep paths same on different platforms + mod_virtual_path.append(virtual_path).append("/").append(modname); + + ModSpec spec(modname, mod_path, part_of_modpack, mod_virtual_path); parseModContents(spec); result.insert(std::make_pair(modname, spec)); } @@ -228,9 +233,9 @@ void ModConfiguration::printUnsatisfiedModsError() const } } -void ModConfiguration::addModsInPath(const std::string &path) +void ModConfiguration::addModsInPath(const std::string &path, const std::string &virtual_path) { - addMods(flattenMods(getModsInPath(path))); + addMods(flattenMods(getModsInPath(path, virtual_path))); } void ModConfiguration::addMods(const std::vector &new_mods) @@ -294,29 +299,39 @@ void ModConfiguration::addMods(const std::vector &new_mods) } void ModConfiguration::addModsFromConfig( - const std::string &settings_path, const std::set &mods) + const std::string &settings_path, + const std::unordered_map &modPaths) { Settings conf; - std::set load_mod_names; + std::unordered_map load_mod_names; conf.readConfigFile(settings_path.c_str()); std::vector names = conf.getNames(); for (const std::string &name : names) { - if (name.compare(0, 9, "load_mod_") == 0 && conf.get(name) != "false" && - conf.get(name) != "nil") - load_mod_names.insert(name.substr(9)); + const auto &value = conf.get(name); + if (name.compare(0, 9, "load_mod_") == 0 && value != "false" && + value != "nil") + load_mod_names[name.substr(9)] = value; } std::vector addon_mods; - for (const std::string &i : mods) { - std::vector addon_mods_in_path = flattenMods(getModsInPath(i)); + std::unordered_map> candidates; + + for (const auto &modPath : modPaths) { + std::vector addon_mods_in_path = flattenMods(getModsInPath(modPath.second, modPath.first)); for (std::vector::const_iterator it = addon_mods_in_path.begin(); it != addon_mods_in_path.end(); ++it) { const ModSpec &mod = *it; - if (load_mod_names.count(mod.name) != 0) - addon_mods.push_back(mod); - else + const auto &pair = load_mod_names.find(mod.name); + if (pair != load_mod_names.end()) { + if (is_yes(pair->second) || pair->second == mod.virtual_path) { + addon_mods.push_back(mod); + } else { + candidates[pair->first].emplace_back(mod.virtual_path); + } + } else { conf.setBool("load_mod_" + mod.name, false); + } } } conf.updateConfigFile(settings_path.c_str()); @@ -335,9 +350,22 @@ void ModConfiguration::addModsFromConfig( if (!load_mod_names.empty()) { errorstream << "The following mods could not be found:"; - for (const std::string &mod : load_mod_names) - errorstream << " \"" << mod << "\""; + for (const auto &pair : load_mod_names) + errorstream << " \"" << pair.first << "\""; errorstream << std::endl; + + for (const auto &pair : load_mod_names) { + const auto &candidate = candidates.find(pair.first); + if (candidate != candidates.end()) { + errorstream << "Unable to load " << pair.first << " as the specified path " + << pair.second << " could not be found. " + << "However, it is available in the following locations:" + << std::endl; + for (const auto &path : candidate->second) { + errorstream << " - " << path << std::endl; + } + } + } } } @@ -413,10 +441,12 @@ void ModConfiguration::resolveDependencies() ClientModConfiguration::ClientModConfiguration(const std::string &path) : ModConfiguration(path) { - std::set paths; + std::unordered_map paths; std::string path_user = porting::path_user + DIR_DELIM + "clientmods"; - paths.insert(path); - paths.insert(path_user); + if (path != path_user) { + paths["share"] = path; + } + paths["mods"] = path_user; std::string settings_path = path_user + DIR_DELIM + "mods.conf"; addModsFromConfig(settings_path, paths); diff --git a/src/content/mods.h b/src/content/mods.h index dd3b6e0e6..ab0a9300e 100644 --- a/src/content/mods.h +++ b/src/content/mods.h @@ -51,17 +51,36 @@ struct ModSpec bool part_of_modpack = false; bool is_modpack = false; + /** + * A constructed canonical path to represent this mod's location. + * This intended to be used as an identifier for a modpath that tolerates file movement, + * and cannot be used to read the mod files. + * + * Note that `mymod` is the directory name, not the mod name specified in mod.conf. + * + * Ex: + * + * - mods/mymod + * - mods/mymod (1) + * (^ this would have name=mymod in mod.conf) + * - mods/modpack1/mymod + * - games/mygame/mods/mymod + * - worldmods/mymod + */ + std::string virtual_path; + // For logging purposes std::vector deprecation_msgs; // if modpack: std::map modpack_content; - ModSpec(const std::string &name = "", const std::string &path = "") : - name(name), path(path) + + ModSpec() { } - ModSpec(const std::string &name, const std::string &path, bool part_of_modpack) : - name(name), path(path), part_of_modpack(part_of_modpack) + + ModSpec(const std::string &name, const std::string &path, bool part_of_modpack, const std::string &virtual_path) : + name(name), path(path), part_of_modpack(part_of_modpack), virtual_path(virtual_path) { } @@ -71,8 +90,16 @@ struct ModSpec // Retrieves depends, optdepends, is_modpack and modpack_content void parseModContents(ModSpec &mod); -std::map getModsInPath( - const std::string &path, bool part_of_modpack = false); +/** + * Gets a list of all mods and modpacks in path + * + * @param Path to search, should be absolute + * @param part_of_modpack Is this searching within a modpack? + * @param virtual_path Virtual path for this directory, see comment in ModSpec + * @returns map of mods + */ +std::map getModsInPath(const std::string &path, + const std::string &virtual_path, bool part_of_modpack = false); // replaces modpack Modspecs with their content std::vector flattenMods(const std::map &mods); @@ -97,15 +124,25 @@ public: protected: ModConfiguration(const std::string &worldpath); - // adds all mods in the given path. used for games, modpacks - // and world-specific mods (worldmods-folders) - void addModsInPath(const std::string &path); + + /** + * adds all mods in the given path. used for games, modpacks + * and world-specific mods (worldmods-folders) + * + * @param path To search, should be absolute + * @param virtual_path Virtual path for this directory, see comment in ModSpec + */ + void addModsInPath(const std::string &path, const std::string &virtual_path); // adds all mods in the set. void addMods(const std::vector &new_mods); + /** + * @param settings_path Path to world.mt + * @param modPaths Map from virtual name to mod path + */ void addModsFromConfig(const std::string &settings_path, - const std::set &mods); + const std::unordered_map &modPaths); void checkConflictsAndDeps(); diff --git a/src/content/subgames.cpp b/src/content/subgames.cpp index 62e82e0e4..23355990e 100644 --- a/src/content/subgames.cpp +++ b/src/content/subgames.cpp @@ -107,14 +107,13 @@ SubgameSpec findSubgame(const std::string &id) std::string gamemod_path = game_path + DIR_DELIM + "mods"; // Find mod directories - std::set mods_paths; - if (!user_game) - mods_paths.insert(share + DIR_DELIM + "mods"); - if (user != share || user_game) - mods_paths.insert(user + DIR_DELIM + "mods"); + std::unordered_map mods_paths; + mods_paths["mods"] = user + DIR_DELIM + "mods"; + if (!user_game && user != share) + mods_paths["share"] = share + DIR_DELIM + "mods"; for (const std::string &mod_path : getEnvModPaths()) { - mods_paths.insert(mod_path); + mods_paths[fs::AbsolutePath(mod_path)] = mod_path; } // Get meta diff --git a/src/content/subgames.h b/src/content/subgames.h index 4a50803e8..d36b4952f 100644 --- a/src/content/subgames.h +++ b/src/content/subgames.h @@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include +#include #include class Settings; @@ -33,13 +34,16 @@ struct SubgameSpec int release; std::string path; std::string gamemods_path; - std::set addon_mods_paths; + + /** + * Map from virtual path to mods path + */ + std::unordered_map addon_mods_paths; std::string menuicon_path; SubgameSpec(const std::string &id = "", const std::string &path = "", const std::string &gamemods_path = "", - const std::set &addon_mods_paths = - std::set(), + const std::unordered_map &addon_mods_paths = {}, const std::string &name = "", const std::string &menuicon_path = "", const std::string &author = "", int release = 0) : diff --git a/src/script/lua_api/l_mainmenu.cpp b/src/script/lua_api/l_mainmenu.cpp index 736ad022f..db031dde5 100644 --- a/src/script/lua_api/l_mainmenu.cpp +++ b/src/script/lua_api/l_mainmenu.cpp @@ -323,9 +323,9 @@ int ModApiMainMenu::l_get_games(lua_State *L) lua_newtable(L); int table2 = lua_gettop(L); int internal_index = 1; - for (const std::string &addon_mods_path : game.addon_mods_paths) { + for (const auto &addon_mods_path : game.addon_mods_paths) { lua_pushnumber(L, internal_index); - lua_pushstring(L, addon_mods_path.c_str()); + lua_pushstring(L, addon_mods_path.second.c_str()); lua_settable(L, table2); internal_index++; } @@ -533,14 +533,14 @@ int ModApiMainMenu::l_get_modpath(lua_State *L) /******************************************************************************/ int ModApiMainMenu::l_get_modpaths(lua_State *L) { - int index = 1; lua_newtable(L); + ModApiMainMenu::l_get_modpath(L); - lua_rawseti(L, -2, index); + lua_setfield(L, -2, "mods"); + for (const std::string &component : getEnvModPaths()) { - index++; lua_pushstring(L, component.c_str()); - lua_rawseti(L, -2, index); + lua_setfield(L, -2, fs::AbsolutePath(component).c_str()); } return 1; } diff --git a/src/server/mods.cpp b/src/server/mods.cpp index 609d8c346..ba76d4746 100644 --- a/src/server/mods.cpp +++ b/src/server/mods.cpp @@ -41,8 +41,10 @@ ServerModManager::ServerModManager(const std::string &worldpath) : SubgameSpec gamespec = findWorldSubgame(worldpath); // Add all game mods and all world mods - addModsInPath(gamespec.gamemods_path); - addModsInPath(worldpath + DIR_DELIM + "worldmods"); + std::string game_virtual_path; + game_virtual_path.append("games/").append(gamespec.id).append("/mods"); + addModsInPath(gamespec.gamemods_path, game_virtual_path); + addModsInPath(worldpath + DIR_DELIM + "worldmods", "worldmods"); // Load normal mods std::string worldmt = worldpath + DIR_DELIM + "world.mt"; -- cgit v1.2.3 From 5683bb76cc3a60d952c9f58c41adaa5f195dd3f4 Mon Sep 17 00:00:00 2001 From: ShadowNinja Date: Wed, 1 Dec 2021 18:30:40 -0500 Subject: Fix compiler warnings --- src/CMakeLists.txt | 6 ++++-- src/client/clientlauncher.cpp | 2 ++ src/client/shader.cpp | 10 ++++----- src/serialization.cpp | 14 ------------ src/server/player_sao.h | 48 ++++++++++++++++++++--------------------- src/terminal_chat_console.cpp | 3 ++- src/unittest/test_irrptr.cpp | 4 +++- src/unittest/test_voxelarea.cpp | 4 ++-- src/util/srp.cpp | 4 ++-- 9 files changed, 44 insertions(+), 51 deletions(-) (limited to 'src/server') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ac4c1de73..2de68a8f0 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -470,6 +470,9 @@ endif() include_directories( ${PROJECT_BINARY_DIR} ${PROJECT_SOURCE_DIR} + ${PROJECT_SOURCE_DIR}/script +) +include_directories(SYSTEM ${ZLIB_INCLUDE_DIR} ${ZSTD_INCLUDE_DIR} ${SQLITE3_INCLUDE_DIR} @@ -477,7 +480,6 @@ include_directories( ${GMP_INCLUDE_DIR} ${JSON_INCLUDE_DIR} ${LUA_BIT_INCLUDE_DIR} - ${PROJECT_SOURCE_DIR}/script ) if(USE_GETTEXT) @@ -485,7 +487,7 @@ if(USE_GETTEXT) endif() if(BUILD_CLIENT) - include_directories( + include_directories(SYSTEM ${FREETYPE_INCLUDE_DIRS} ${SOUND_INCLUDE_DIRS} ${X11_INCLUDE_DIR} diff --git a/src/client/clientlauncher.cpp b/src/client/clientlauncher.cpp index 063154316..54c561d11 100644 --- a/src/client/clientlauncher.cpp +++ b/src/client/clientlauncher.cpp @@ -564,6 +564,8 @@ void ClientLauncher::speed_tests() // volatile to avoid some potential compiler optimisations volatile static s16 temp16; volatile static f32 tempf; + // Silence compiler warning + (void)temp16; static v3f tempv3f1; static v3f tempv3f2; static std::string tempstring; diff --git a/src/client/shader.cpp b/src/client/shader.cpp index 1be9ef128..bbb872761 100644 --- a/src/client/shader.cpp +++ b/src/client/shader.cpp @@ -242,11 +242,6 @@ public: MainShaderConstantSetter() : m_world_view_proj("mWorldViewProj") , m_world("mWorld") -#if ENABLE_GLES - , m_world_view("mWorldView") - , m_texture("mTexture") - , m_normal("mNormal") -#endif , m_shadow_view_proj("m_ShadowViewProj") , m_light_direction("v_LightDirection") , m_texture_res("f_textureresolution") @@ -261,6 +256,11 @@ public: , m_perspective_bias1_pixel("xyPerspectiveBias1") , m_perspective_zbias_vertex("zPerspectiveBias") , m_perspective_zbias_pixel("zPerspectiveBias") +#if ENABLE_GLES + , m_world_view("mWorldView") + , m_texture("mTexture") + , m_normal("mNormal") +#endif {} ~MainShaderConstantSetter() = default; diff --git a/src/serialization.cpp b/src/serialization.cpp index d3009bc83..11164a0ed 100644 --- a/src/serialization.cpp +++ b/src/serialization.cpp @@ -108,7 +108,6 @@ void decompressZlib(std::istream &is, std::ostream &os, size_t limit) char output_buffer[bufsize]; int status = 0; int ret; - int bytes_read = 0; int bytes_written = 0; int input_buffer_len = 0; @@ -122,8 +121,6 @@ void decompressZlib(std::istream &is, std::ostream &os, size_t limit) z.avail_in = 0; - //dstream<<"initial fail="< &privs); diff --git a/src/terminal_chat_console.cpp b/src/terminal_chat_console.cpp index 9e3d33736..b12261c3b 100644 --- a/src/terminal_chat_console.cpp +++ b/src/terminal_chat_console.cpp @@ -17,6 +17,7 @@ with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#include #include "config.h" #if USE_CURSES #include "version.h" @@ -398,7 +399,7 @@ void TerminalChatConsole::step(int ch) minutes = (float)minutes / 1000 * 60; if (m_game_time) - printw(" | Game %d Time of day %02d:%02d ", + printw(" | Game %" PRIu64 " Time of day %02d:%02d ", m_game_time, hours, minutes); // draw text diff --git a/src/unittest/test_irrptr.cpp b/src/unittest/test_irrptr.cpp index 3484f1514..2fb7cfcd6 100644 --- a/src/unittest/test_irrptr.cpp +++ b/src/unittest/test_irrptr.cpp @@ -93,7 +93,9 @@ void TestIrrPtr::testRefCounting() #if defined(__clang__) #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wself-assign-overloaded" + #if __clang_major__ >= 7 + #pragma GCC diagnostic ignored "-Wself-assign-overloaded" + #endif #pragma GCC diagnostic ignored "-Wself-move" #endif diff --git a/src/unittest/test_voxelarea.cpp b/src/unittest/test_voxelarea.cpp index 9826d2ee7..1d72650d7 100644 --- a/src/unittest/test_voxelarea.cpp +++ b/src/unittest/test_voxelarea.cpp @@ -120,7 +120,7 @@ void TestVoxelArea::test_extent() VoxelArea v1(v3s16(-1337, -547, -789), v3s16(-147, 447, 669)); UASSERT(v1.getExtent() == v3s16(1191, 995, 1459)); - VoxelArea v2(v3s16(32493, -32507, 32753), v3s16(32508, -32492, 32768)); + VoxelArea v2(v3s16(32493, -32507, 32753), v3s16(32508, -32492, -32768)); UASSERT(v2.getExtent() == v3s16(16, 16, 16)); } @@ -129,7 +129,7 @@ void TestVoxelArea::test_volume() VoxelArea v1(v3s16(-1337, -547, -789), v3s16(-147, 447, 669)); UASSERTEQ(s32, v1.getVolume(), 1728980655); - VoxelArea v2(v3s16(32493, -32507, 32753), v3s16(32508, -32492, 32768)); + VoxelArea v2(v3s16(32493, -32507, 32753), v3s16(32508, -32492, -32768)); UASSERTEQ(s32, v2.getVolume(), 4096); } diff --git a/src/util/srp.cpp b/src/util/srp.cpp index ceb2fef9e..daa7f332b 100644 --- a/src/util/srp.cpp +++ b/src/util/srp.cpp @@ -354,7 +354,7 @@ static size_t hash_length(SRP_HashAlgorithm alg) case SRP_SHA384: return SHA384_DIGEST_LENGTH; case SRP_SHA512: return SHA512_DIGEST_LENGTH; */ - default: return -1; + default: return 0; }; } // clang-format on @@ -422,7 +422,7 @@ static SRP_Result H_nn( } static SRP_Result H_ns(mpz_t result, SRP_HashAlgorithm alg, const unsigned char *n, - size_t len_n, const unsigned char *bytes, uint32_t len_bytes) + size_t len_n, const unsigned char *bytes, size_t len_bytes) { unsigned char buff[SHA512_DIGEST_LENGTH]; size_t nbytes = len_n + len_bytes; -- cgit v1.2.3