3 Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
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.
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.
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.
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"
33 #include "util/auth.h"
36 // Writes a line to dstream
37 int ModApiUtil::l_debug(lua_State *L)
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++) {
45 Call tostring(i-th argument).
46 This is what print() does, and it behaves a bit
47 differently from directly calling lua_tostring.
49 lua_pushvalue(L, -1); /* function to be called */
50 lua_pushvalue(L, i); /* value to print */
53 const char *s = lua_tolstring(L, -1, &len);
57 dstream << std::string(s, len);
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)
72 LogMessageLevel level = LMT_INFO;
73 if (lua_isnone(L, 2)) {
74 text = lua_tostring(L, 1);
77 std::string levelname = luaL_checkstring(L, 1);
78 text = luaL_checkstring(L, 2);
79 if(levelname == "error")
81 else if(levelname == "action")
83 else if(levelname == "verbose")
85 else if (levelname == "deprecated") {
86 log_deprecated(L,text);
91 log_printline(level, text);
95 // setting_set(name, value)
96 int ModApiUtil::l_setting_set(lua_State *L)
99 const char *name = luaL_checkstring(L, 1);
100 const char *value = luaL_checkstring(L, 2);
101 g_settings->set(name, value);
106 int ModApiUtil::l_setting_get(lua_State *L)
108 NO_MAP_LOCK_REQUIRED;
109 const char *name = luaL_checkstring(L, 1);
111 std::string value = g_settings->get(name);
112 lua_pushstring(L, value.c_str());
113 } catch(SettingNotFoundException &e){
119 // setting_setbool(name)
120 int ModApiUtil::l_setting_setbool(lua_State *L)
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);
129 // setting_getbool(name)
130 int ModApiUtil::l_setting_getbool(lua_State *L)
132 NO_MAP_LOCK_REQUIRED;
133 const char *name = luaL_checkstring(L, 1);
135 bool value = g_settings->getBool(name);
136 lua_pushboolean(L, value);
137 } catch(SettingNotFoundException &e){
144 int ModApiUtil::l_setting_save(lua_State *L)
146 NO_MAP_LOCK_REQUIRED;
147 if(g_settings_path != "")
148 g_settings->updateConfigFile(g_settings_path.c_str());
152 // parse_json(str[, nullvalue])
153 int ModApiUtil::l_parse_json(lua_State *L)
155 NO_MAP_LOCK_REQUIRED;
157 const char *jsonstr = luaL_checkstring(L, 1);
159 // Use passed nullvalue or default to nil
161 if (lua_isnone(L, nullindex)) {
163 nullindex = lua_gettop(L);
170 std::istringstream stream(jsonstr);
172 if (!reader.parse(stream, root)) {
173 errorstream << "Failed to parse json data "
174 << reader.getFormattedErrorMessages();
175 errorstream << "data: \"" << jsonstr << "\""
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;
191 // write_json(data[, styled]) -> string or nil and error message
192 int ModApiUtil::l_write_json(lua_State *L)
194 NO_MAP_LOCK_REQUIRED;
197 if (!lua_isnone(L, 2)) {
198 styled = lua_toboolean(L, 2);
204 read_json_value(L, root, 1);
205 } catch (SerializationError &e) {
207 lua_pushstring(L, e.what());
213 Json::StyledWriter writer;
214 out = writer.write(root);
216 Json::FastWriter writer;
217 out = writer.write(root);
219 lua_pushlstring(L, out.c_str(), out.size());
223 // get_dig_params(groups, tool_capabilities[, time_from_last_punch])
224 int ModApiUtil::l_get_dig_params(lua_State *L)
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));
233 push_dig_params(L, getDigParams(groups, &tp,
234 luaL_checknumber(L, 3)));
238 // get_hit_params(groups, tool_capabilities[, time_from_last_punch])
239 int ModApiUtil::l_get_hit_params(lua_State *L)
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));
248 push_hit_params(L, getHitParams(groups, &tp,
249 luaL_checknumber(L, 3)));
253 // get_password_hash(name, raw_password)
254 int ModApiUtil::l_get_password_hash(lua_State *L)
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());
265 int ModApiUtil::l_is_yes(lua_State *L)
267 NO_MAP_LOCK_REQUIRED;
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
275 bool yes = is_yes(str);
276 lua_pushboolean(L, yes);
280 int ModApiUtil::l_get_builtin_path(lua_State *L)
282 std::string path = porting::path_share + DIR_DELIM + "builtin";
283 lua_pushstring(L, path.c_str());
287 // compress(data, method, level)
288 int ModApiUtil::l_compress(lua_State *L)
291 const char *data = luaL_checklstring(L, 1, &size);
294 if (!lua_isnone(L, 3) && !lua_isnil(L, 3))
295 level = luaL_checknumber(L, 3);
297 std::ostringstream os;
298 compressZlib(std::string(data, size), os, level);
300 std::string out = os.str();
302 lua_pushlstring(L, out.data(), out.size());
306 // decompress(data, method)
307 int ModApiUtil::l_decompress(lua_State *L)
310 const char * data = luaL_checklstring(L, 1, &size);
312 std::istringstream is(std::string(data, size));
313 std::ostringstream os;
314 decompressZlib(is, os);
316 std::string out = os.str();
318 lua_pushlstring(L, out.data(), out.size());
322 void ModApiUtil::Initialize(lua_State *L, int top)
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);
336 API_FCT(get_dig_params);
337 API_FCT(get_hit_params);
339 API_FCT(get_password_hash);
343 API_FCT(get_builtin_path);
349 void ModApiUtil::InitializeAsync(AsyncEngine& engine)
351 ASYNC_API_FCT(debug);
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);
360 ASYNC_API_FCT(parse_json);
361 ASYNC_API_FCT(write_json);
363 ASYNC_API_FCT(is_yes);
365 ASYNC_API_FCT(get_builtin_path);
367 ASYNC_API_FCT(compress);
368 ASYNC_API_FCT(decompress);