]> git.lizzy.rs Git - dragonfireclient.git/blob - src/script/lua_api/l_util.cpp
Fix compiler warning about sign comparison
[dragonfireclient.git] / src / script / lua_api / l_util.cpp
1 /*
2 Minetest
3 Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #include "lua_api/l_util.h"
21 #include "lua_api/l_internal.h"
22 #include "common/c_converter.h"
23 #include "common/c_content.h"
24 #include "cpp_api/s_async.h"
25 #include "serialization.h"
26 #include "json/json.h"
27 #include "debug.h"
28 #include "porting.h"
29 #include "log.h"
30 #include "tool.h"
31 #include "filesys.h"
32 #include "settings.h"
33 #include "util/auth.h"
34
35 // debug(...)
36 // Writes a line to dstream
37 int ModApiUtil::l_debug(lua_State *L)
38 {
39         NO_MAP_LOCK_REQUIRED;
40         // Handle multiple parameters to behave like standard lua print()
41         int n = lua_gettop(L);
42         lua_getglobal(L, "tostring");
43         for (int i = 1; i <= n; i++) {
44                 /*
45                         Call tostring(i-th argument).
46                         This is what print() does, and it behaves a bit
47                         differently from directly calling lua_tostring.
48                 */
49                 lua_pushvalue(L, -1);  /* function to be called */
50                 lua_pushvalue(L, i);   /* value to print */
51                 lua_call(L, 1, 1);
52                 size_t len;
53                 const char *s = lua_tolstring(L, -1, &len);
54                 if (i > 1)
55                         dstream << "\t";
56                 if (s)
57                         dstream << std::string(s, len);
58                 lua_pop(L, 1);
59         }
60         dstream << std::endl;
61         return 0;
62 }
63
64 // log([level,] text)
65 // Writes a line to the logger.
66 // The one-argument version logs to infostream.
67 // The two-argument version accept a log level: error, action, info, or verbose.
68 int ModApiUtil::l_log(lua_State *L)
69 {
70         NO_MAP_LOCK_REQUIRED;
71         std::string text;
72         LogMessageLevel level = LMT_INFO;
73         if (lua_isnone(L, 2)) {
74                 text = lua_tostring(L, 1);
75         }
76         else {
77                 std::string levelname = luaL_checkstring(L, 1);
78                 text = luaL_checkstring(L, 2);
79                 if(levelname == "error")
80                         level = LMT_ERROR;
81                 else if(levelname == "action")
82                         level = LMT_ACTION;
83                 else if(levelname == "verbose")
84                         level = LMT_VERBOSE;
85                 else if (levelname == "deprecated") {
86                         log_deprecated(L,text);
87                         return 0;
88                 }
89
90         }
91         log_printline(level, text);
92         return 0;
93 }
94
95 // setting_set(name, value)
96 int ModApiUtil::l_setting_set(lua_State *L)
97 {
98         NO_MAP_LOCK_REQUIRED;
99         const char *name = luaL_checkstring(L, 1);
100         const char *value = luaL_checkstring(L, 2);
101         g_settings->set(name, value);
102         return 0;
103 }
104
105 // setting_get(name)
106 int ModApiUtil::l_setting_get(lua_State *L)
107 {
108         NO_MAP_LOCK_REQUIRED;
109         const char *name = luaL_checkstring(L, 1);
110         try{
111                 std::string value = g_settings->get(name);
112                 lua_pushstring(L, value.c_str());
113         } catch(SettingNotFoundException &e){
114                 lua_pushnil(L);
115         }
116         return 1;
117 }
118
119 // setting_setbool(name)
120 int ModApiUtil::l_setting_setbool(lua_State *L)
121 {
122         NO_MAP_LOCK_REQUIRED;
123         const char *name = luaL_checkstring(L, 1);
124         bool value = lua_toboolean(L, 2);
125         g_settings->setBool(name, value);
126         return 0;
127 }
128
129 // setting_getbool(name)
130 int ModApiUtil::l_setting_getbool(lua_State *L)
131 {
132         NO_MAP_LOCK_REQUIRED;
133         const char *name = luaL_checkstring(L, 1);
134         try{
135                 bool value = g_settings->getBool(name);
136                 lua_pushboolean(L, value);
137         } catch(SettingNotFoundException &e){
138                 lua_pushnil(L);
139         }
140         return 1;
141 }
142
143 // setting_save()
144 int ModApiUtil::l_setting_save(lua_State *L)
145 {
146         NO_MAP_LOCK_REQUIRED;
147         if(g_settings_path != "")
148                 g_settings->updateConfigFile(g_settings_path.c_str());
149         return 0;
150 }
151
152 // parse_json(str[, nullvalue])
153 int ModApiUtil::l_parse_json(lua_State *L)
154 {
155         NO_MAP_LOCK_REQUIRED;
156
157         const char *jsonstr = luaL_checkstring(L, 1);
158
159         // Use passed nullvalue or default to nil
160         int nullindex = 2;
161         if (lua_isnone(L, nullindex)) {
162                 lua_pushnil(L);
163                 nullindex = lua_gettop(L);
164         }
165
166         Json::Value root;
167
168         {
169                 Json::Reader reader;
170                 std::istringstream stream(jsonstr);
171
172                 if (!reader.parse(stream, root)) {
173                         errorstream << "Failed to parse json data "
174                                 << reader.getFormattedErrorMessages();
175                         errorstream << "data: \"" << jsonstr << "\""
176                                 << std::endl;
177                         lua_pushnil(L);
178                         return 1;
179                 }
180         }
181
182         if (!push_json_value(L, root, nullindex)) {
183                 errorstream << "Failed to parse json data, "
184                         << "depth exceeds lua stack limit" << std::endl;
185                 errorstream << "data: \"" << jsonstr << "\"" << std::endl;
186                 lua_pushnil(L);
187         }
188         return 1;
189 }
190
191 // write_json(data[, styled]) -> string or nil and error message
192 int ModApiUtil::l_write_json(lua_State *L)
193 {
194         NO_MAP_LOCK_REQUIRED;
195
196         bool styled = false;
197         if (!lua_isnone(L, 2)) {
198                 styled = lua_toboolean(L, 2);
199                 lua_pop(L, 1);
200         }
201
202         Json::Value root;
203         try {
204                 read_json_value(L, root, 1);
205         } catch (SerializationError &e) {
206                 lua_pushnil(L);
207                 lua_pushstring(L, e.what());
208                 return 2;
209         }
210
211         std::string out;
212         if (styled) {
213                 Json::StyledWriter writer;
214                 out = writer.write(root);
215         } else {
216                 Json::FastWriter writer;
217                 out = writer.write(root);
218         }
219         lua_pushlstring(L, out.c_str(), out.size());
220         return 1;
221 }
222
223 // get_dig_params(groups, tool_capabilities[, time_from_last_punch])
224 int ModApiUtil::l_get_dig_params(lua_State *L)
225 {
226         NO_MAP_LOCK_REQUIRED;
227         std::map<std::string, int> groups;
228         read_groups(L, 1, groups);
229         ToolCapabilities tp = read_tool_capabilities(L, 2);
230         if(lua_isnoneornil(L, 3))
231                 push_dig_params(L, getDigParams(groups, &tp));
232         else
233                 push_dig_params(L, getDigParams(groups, &tp,
234                                         luaL_checknumber(L, 3)));
235         return 1;
236 }
237
238 // get_hit_params(groups, tool_capabilities[, time_from_last_punch])
239 int ModApiUtil::l_get_hit_params(lua_State *L)
240 {
241         NO_MAP_LOCK_REQUIRED;
242         std::map<std::string, int> groups;
243         read_groups(L, 1, groups);
244         ToolCapabilities tp = read_tool_capabilities(L, 2);
245         if(lua_isnoneornil(L, 3))
246                 push_hit_params(L, getHitParams(groups, &tp));
247         else
248                 push_hit_params(L, getHitParams(groups, &tp,
249                                         luaL_checknumber(L, 3)));
250         return 1;
251 }
252
253 // get_password_hash(name, raw_password)
254 int ModApiUtil::l_get_password_hash(lua_State *L)
255 {
256         NO_MAP_LOCK_REQUIRED;
257         std::string name = luaL_checkstring(L, 1);
258         std::string raw_password = luaL_checkstring(L, 2);
259         std::string hash = translatePassword(name, raw_password);
260         lua_pushstring(L, hash.c_str());
261         return 1;
262 }
263
264 // is_yes(arg)
265 int ModApiUtil::l_is_yes(lua_State *L)
266 {
267         NO_MAP_LOCK_REQUIRED;
268
269         lua_getglobal(L, "tostring"); // function to be called
270         lua_pushvalue(L, 1); // 1st argument
271         lua_call(L, 1, 1); // execute function
272         std::string str(lua_tostring(L, -1)); // get result
273         lua_pop(L, 1);
274
275         bool yes = is_yes(str);
276         lua_pushboolean(L, yes);
277         return 1;
278 }
279
280 int ModApiUtil::l_get_builtin_path(lua_State *L)
281 {
282         std::string path = porting::path_share + DIR_DELIM + "builtin";
283         lua_pushstring(L, path.c_str());
284         return 1;
285 }
286
287 // compress(data, method, level)
288 int ModApiUtil::l_compress(lua_State *L)
289 {
290         size_t size;
291         const char *data = luaL_checklstring(L, 1, &size);
292
293         int level = -1;
294         if (!lua_isnone(L, 3) && !lua_isnil(L, 3))
295                 level = luaL_checknumber(L, 3);
296
297         std::ostringstream os;
298         compressZlib(std::string(data, size), os, level);
299
300         std::string out = os.str();
301
302         lua_pushlstring(L, out.data(), out.size());
303         return 1;
304 }
305
306 // decompress(data, method)
307 int ModApiUtil::l_decompress(lua_State *L)
308 {
309         size_t size;
310         const char * data = luaL_checklstring(L, 1, &size);
311
312         std::istringstream is(std::string(data, size));
313         std::ostringstream os;
314         decompressZlib(is, os);
315
316         std::string out = os.str();
317
318         lua_pushlstring(L, out.data(), out.size());
319         return 1;
320 }
321
322 void ModApiUtil::Initialize(lua_State *L, int top)
323 {
324         API_FCT(debug);
325         API_FCT(log);
326
327         API_FCT(setting_set);
328         API_FCT(setting_get);
329         API_FCT(setting_setbool);
330         API_FCT(setting_getbool);
331         API_FCT(setting_save);
332
333         API_FCT(parse_json);
334         API_FCT(write_json);
335
336         API_FCT(get_dig_params);
337         API_FCT(get_hit_params);
338
339         API_FCT(get_password_hash);
340
341         API_FCT(is_yes);
342
343         API_FCT(get_builtin_path);
344
345         API_FCT(compress);
346         API_FCT(decompress);
347 }
348
349 void ModApiUtil::InitializeAsync(AsyncEngine& engine)
350 {
351         ASYNC_API_FCT(debug);
352         ASYNC_API_FCT(log);
353
354         //ASYNC_API_FCT(setting_set);
355         ASYNC_API_FCT(setting_get);
356         //ASYNC_API_FCT(setting_setbool);
357         ASYNC_API_FCT(setting_getbool);
358         //ASYNC_API_FCT(setting_save);
359
360         ASYNC_API_FCT(parse_json);
361         ASYNC_API_FCT(write_json);
362
363         ASYNC_API_FCT(is_yes);
364
365         ASYNC_API_FCT(get_builtin_path);
366
367         ASYNC_API_FCT(compress);
368         ASYNC_API_FCT(decompress);
369 }
370