]> git.lizzy.rs Git - dragonfireclient.git/blobdiff - src/script/lua_api/l_util.cpp
Fix number of tool uses being off by 1..32767 (#11110)
[dragonfireclient.git] / src / script / lua_api / l_util.cpp
index a58c3a196a36bb5de4786be5506b4bf1fe9754ec..53319ccfd2a21f569446181be0ba80a63f5a0096 100644 (file)
@@ -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 "irrlichttypes_extrabloated.h"
 #include "lua_api/l_util.h"
 #include "lua_api/l_internal.h"
 #include "lua_api/l_settings.h"
@@ -39,12 +40,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "version.h"
 #include "util/hex.h"
 #include "util/sha1.h"
+#include "util/png.h"
 #include <algorithm>
-
+#include <cstdio>
 
 // log([level,] text)
 // Writes a line to the logger.
-// The one-argument version logs to infostream.
+// The one-argument version logs to LL_NONE.
 // The two-argument version accepts a log level.
 // Either the special case "deprecated" for deprecation notices, or any specified in
 // Logger::stringToLevel(name).
@@ -59,7 +61,7 @@ int ModApiUtil::l_log(lua_State *L)
                std::string name = luaL_checkstring(L, 1);
                text = luaL_checkstring(L, 2);
                if (name == "deprecated") {
-                       log_deprecated(L, text);
+                       log_deprecated(L, text, 2);
                        return 0;
                }
                level = Logger::stringToLevel(name);
@@ -158,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<int>(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<std::string, int> 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<float>(L, 3)));
+       float time_from_last_punch = readParam<float>(L, 3, 1000000);
+       int wear = readParam<int>(L, 4, 0);
+       push_hit_params(L, getHitParams(groups, &tp,
+               time_from_last_punch, wear));
        return 1;
 }
 
@@ -239,21 +246,23 @@ int ModApiUtil::l_is_yes(lua_State *L)
        return 1;
 }
 
-// is_nan(arg)
-int ModApiUtil::l_is_nan(lua_State *L)
+// get_builtin_path()
+int ModApiUtil::l_get_builtin_path(lua_State *L)
 {
        NO_MAP_LOCK_REQUIRED;
 
-       lua_pushboolean(L, isNaN(L, 1));
+       std::string path = porting::path_share + DIR_DELIM + "builtin" + DIR_DELIM;
+       lua_pushstring(L, path.c_str());
+
        return 1;
 }
 
-// get_builtin_path()
-int ModApiUtil::l_get_builtin_path(lua_State *L)
+// get_user_path()
+int ModApiUtil::l_get_user_path(lua_State *L)
 {
        NO_MAP_LOCK_REQUIRED;
 
-       std::string path = porting::path_share + DIR_DELIM + "builtin" + DIR_DELIM;
+       std::string path = porting::path_user;
        lua_pushstring(L, path.c_str());
 
        return 1;
@@ -268,11 +277,11 @@ int ModApiUtil::l_compress(lua_State *L)
        const char *data = luaL_checklstring(L, 1, &size);
 
        int level = -1;
-       if (!lua_isnone(L, 3) && !lua_isnil(L, 3))
-               level = readParam<float>(L, 3);
+       if (!lua_isnoneornil(L, 3))
+               level = readParam<int>(L, 3);
 
-       std::ostringstream os;
-       compressZlib(std::string(data, size), os, level);
+       std::ostringstream os(std::ios_base::binary);
+       compressZlib(reinterpret_cast<const u8 *>(data), size, os, level);
 
        std::string out = os.str();
 
@@ -288,8 +297,8 @@ int ModApiUtil::l_decompress(lua_State *L)
        size_t size;
        const char *data = luaL_checklstring(L, 1, &size);
 
-       std::istringstream is(std::string(data, size));
-       std::ostringstream os;
+       std::istringstream is(std::string(data, size), std::ios_base::binary);
+       std::ostringstream os(std::ios_base::binary);
        decompressZlib(is, os);
 
        std::string out = os.str();
@@ -318,9 +327,13 @@ int ModApiUtil::l_decode_base64(lua_State *L)
        NO_MAP_LOCK_REQUIRED;
 
        size_t size;
-       const char *data = luaL_checklstring(L, 1, &size);
+       const char *d = luaL_checklstring(L, 1, &size);
+       const std::string data = std::string(d, size);
 
-       std::string out = base64_decode(std::string(data, size));
+       if (!base64_is_valid(data))
+               return 0;
+
+       std::string out = base64_decode(data);
 
        lua_pushlstring(L, out.data(), out.size());
        return 1;
@@ -473,6 +486,84 @@ int ModApiUtil::l_sha1(lua_State *L)
        return 1;
 }
 
+// colorspec_to_colorstring(colorspec)
+int ModApiUtil::l_colorspec_to_colorstring(lua_State *L)
+{
+       NO_MAP_LOCK_REQUIRED;
+
+       video::SColor color(0);
+       if (read_color(L, 1, &color)) {
+               char colorstring[10];
+               snprintf(colorstring, 10, "#%02X%02X%02X%02X",
+                       color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha());
+               lua_pushstring(L, colorstring);
+               return 1;
+       }
+
+       return 0;
+}
+
+// colorspec_to_bytes(colorspec)
+int ModApiUtil::l_colorspec_to_bytes(lua_State *L)
+{
+       NO_MAP_LOCK_REQUIRED;
+
+       video::SColor color(0);
+       if (read_color(L, 1, &color)) {
+               u8 colorbytes[4] = {
+                       (u8) color.getRed(),
+                       (u8) color.getGreen(),
+                       (u8) color.getBlue(),
+                       (u8) color.getAlpha(),
+               };
+               lua_pushlstring(L, (const char*) colorbytes, 4);
+               return 1;
+       }
+
+       return 0;
+}
+
+// encode_png(w, h, data, level)
+int ModApiUtil::l_encode_png(lua_State *L)
+{
+       NO_MAP_LOCK_REQUIRED;
+
+       // The args are already pre-validated on the lua side.
+       u32 width = readParam<int>(L, 1);
+       u32 height = readParam<int>(L, 2);
+       const char *data = luaL_checklstring(L, 3, NULL);
+       s32 compression = readParam<int>(L, 4);
+
+       std::string out = encodePNG((const u8*)data, width, height, compression);
+
+       lua_pushlstring(L, out.data(), out.size());
+       return 1;
+}
+
+// get_last_run_mod()
+int ModApiUtil::l_get_last_run_mod(lua_State *L)
+{
+       NO_MAP_LOCK_REQUIRED;
+
+       lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_CURRENT_MOD_NAME);
+       std::string current_mod = readParam<std::string>(L, -1, "");
+       if (current_mod.empty()) {
+               lua_pop(L, 1);
+               lua_pushstring(L, getScriptApiBase(L)->getOrigin().c_str());
+       }
+       return 1;
+}
+
+// set_last_run_mod(modname)
+int ModApiUtil::l_set_last_run_mod(lua_State *L)
+{
+       NO_MAP_LOCK_REQUIRED;
+
+       const char *mod = luaL_checkstring(L, 1);
+       getScriptApiBase(L)->setOriginDirect(mod);
+       return 0;
+}
+
 void ModApiUtil::Initialize(lua_State *L, int top)
 {
        API_FCT(log);
@@ -489,9 +580,9 @@ void ModApiUtil::Initialize(lua_State *L, int top)
        API_FCT(get_password_hash);
 
        API_FCT(is_yes);
-       API_FCT(is_nan);
 
        API_FCT(get_builtin_path);
+       API_FCT(get_user_path);
 
        API_FCT(compress);
        API_FCT(decompress);
@@ -507,6 +598,13 @@ void ModApiUtil::Initialize(lua_State *L, int top)
 
        API_FCT(get_version);
        API_FCT(sha1);
+       API_FCT(colorspec_to_colorstring);
+       API_FCT(colorspec_to_bytes);
+
+       API_FCT(encode_png);
+
+       API_FCT(get_last_run_mod);
+       API_FCT(set_last_run_mod);
 
        LuaSettings::create(L, g_settings, g_settings_path);
        lua_setfield(L, top, "settings");
@@ -522,7 +620,6 @@ void ModApiUtil::InitializeClient(lua_State *L, int top)
        API_FCT(write_json);
 
        API_FCT(is_yes);
-       API_FCT(is_nan);
 
        API_FCT(compress);
        API_FCT(decompress);
@@ -532,6 +629,8 @@ void ModApiUtil::InitializeClient(lua_State *L, int top)
 
        API_FCT(get_version);
        API_FCT(sha1);
+       API_FCT(colorspec_to_colorstring);
+       API_FCT(colorspec_to_bytes);
 }
 
 void ModApiUtil::InitializeAsync(lua_State *L, int top)
@@ -546,6 +645,7 @@ void ModApiUtil::InitializeAsync(lua_State *L, int top)
        API_FCT(is_yes);
 
        API_FCT(get_builtin_path);
+       API_FCT(get_user_path);
 
        API_FCT(compress);
        API_FCT(decompress);
@@ -558,8 +658,12 @@ void ModApiUtil::InitializeAsync(lua_State *L, int top)
 
        API_FCT(get_version);
        API_FCT(sha1);
+       API_FCT(colorspec_to_colorstring);
+       API_FCT(colorspec_to_bytes);
+
+       API_FCT(get_last_run_mod);
+       API_FCT(set_last_run_mod);
 
        LuaSettings::create(L, g_settings, g_settings_path);
        lua_setfield(L, top, "settings");
 }
-