aboutsummaryrefslogtreecommitdiff
path: root/src/script/lua_api/l_internal.h
blob: de73ff42ab02675b36abc199549302f1baaef20e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
/*
Minetest
Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

/******************************************************************************/
/******************************************************************************/
/* WARNING!!!! do NOT add this header in any include file or any code file    */
/*             not being a modapi file!!!!!!!!                                */
/******************************************************************************/
/******************************************************************************/

#pragma once

#include "common/c_internal.h"

#define luamethod(class, name) {#name, class::l_##name}

#define luamethod_dep(class, good, bad)                                     \
		{#bad, [](lua_State *L) -> int {                                    \
			return l_deprecated_function(L, #good, #bad, &class::l_##good); \
		}}

#define luamethod_aliased(class, good, bad) \
		luamethod(class, good),               \
		luamethod_dep(class, good, bad)

#define API_FCT(name) registerFunction(L, #name, l_##name, top)

// For future use
#define MAP_LOCK_REQUIRED ((void)0)
#define NO_MAP_LOCK_REQUIRED ((void)0)

/* In debug mode ensure no code tries to retrieve the server env when it isn't
 * actually available (in CSM) */
#if !defined(SERVER) && !defined(NDEBUG)
#define DEBUG_ASSERT_NO_CLIENTAPI                    \
	FATAL_ERROR_IF(getClient(L) != nullptr, "Tried " \
		"to retrieve ServerEnvironment on client")
#else
#define DEBUG_ASSERT_NO_CLIENTAPI ((void)0)
#endif

// Retrieve ServerEnvironment pointer as `env` (no map lock)
#define GET_ENV_PTR_NO_MAP_LOCK                              \
	DEBUG_ASSERT_NO_CLIENTAPI;                               \
	ServerEnvironment *env = (ServerEnvironment *)getEnv(L); \
	if (env == NULL)                                         \
		return 0

// Retrieve ServerEnvironment pointer as `env`
#define GET_ENV_PTR         \
	MAP_LOCK_REQUIRED;      \
	GET_ENV_PTR_NO_MAP_LOCK

// Retrieve Environment pointer as `env` (no map lock)
#define GET_PLAIN_ENV_PTR_NO_MAP_LOCK            \
	Environment *env = getEnv(L);                \
	if (env == NULL)                             \
		return 0

// Retrieve Environment pointer as `env`
#define GET_PLAIN_ENV_PTR         \
	MAP_LOCK_REQUIRED;            \
	GET_PLAIN_ENV_PTR_NO_MAP_LOCK
243' href='#n243'>243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362
/*
Minetest
Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#include "cpp_api/s_player.h"
#include "cpp_api/s_internal.h"
#include "common/c_converter.h"
#include "common/c_content.h"
#include "debug.h"
#include "inventorymanager.h"
#include "lua_api/l_inventory.h"
#include "lua_api/l_item.h"
#include "util/string.h"

void ScriptApiPlayer::on_newplayer(ServerActiveObject *player)
{
	SCRIPTAPI_PRECHECKHEADER

	// Get core.registered_on_newplayers
	lua_getglobal(L, "core");
	lua_getfield(L, -1, "registered_on_newplayers");
	// Call callbacks
	objectrefGetOrCreate(L, player);
	runCallbacks(1, RUN_CALLBACKS_MODE_FIRST);
}

void ScriptApiPlayer::on_dieplayer(ServerActiveObject *player, const PlayerHPChangeReason &reason)
{
	SCRIPTAPI_PRECHECKHEADER

	// Get callback table
	lua_getglobal(L, "core");
	lua_getfield(L, -1, "registered_on_dieplayers");

	// Push arguments
	objectrefGetOrCreate(L, player);
	pushPlayerHPChangeReason(L, reason);

	// Run callbacks
	runCallbacks(2, RUN_CALLBACKS_MODE_FIRST);
}

bool ScriptApiPlayer::on_punchplayer(ServerActiveObject *player,
		ServerActiveObject *hitter,
		float time_from_last_punch,
		const ToolCapabilities *toolcap,
		v3f dir,
		s16 damage)
{
	SCRIPTAPI_PRECHECKHEADER
	// Get core.registered_on_punchplayers
	lua_getglobal(L, "core");
	lua_getfield(L, -1, "registered_on_punchplayers");
	// Call callbacks
	objectrefGetOrCreate(L, player);
	objectrefGetOrCreate(L, hitter);
	lua_pushnumber(L, time_from_last_punch);
	push_tool_capabilities(L, *toolcap);
	push_v3f(L, dir);
	lua_pushnumber(L, damage);
	runCallbacks(6, RUN_CALLBACKS_MODE_OR);
	return readParam<bool>(L, -1);
}

s32 ScriptApiPlayer::on_player_hpchange(ServerActiveObject *player,
	s32 hp_change, const PlayerHPChangeReason &reason)
{
	SCRIPTAPI_PRECHECKHEADER

	int error_handler = PUSH_ERROR_HANDLER(L);

	// Get core.registered_on_player_hpchange
	lua_getglobal(L, "core");
	lua_getfield(L, -1, "registered_on_player_hpchange");
	lua_remove(L, -2);

	// Push arguments
	objectrefGetOrCreate(L, player);
	lua_pushnumber(L, hp_change);
	pushPlayerHPChangeReason(L, reason);

	// Call callbacks
	PCALL_RES(lua_pcall(L, 3, 1, error_handler));
	hp_change = lua_tointeger(L, -1);
	lua_pop(L, 2); // Pop result and error handler
	return hp_change;
}

bool ScriptApiPlayer::on_respawnplayer(ServerActiveObject *player)
{
	SCRIPTAPI_PRECHECKHEADER

	// Get core.registered_on_respawnplayers
	lua_getglobal(L, "core");
	lua_getfield(L, -1, "registered_on_respawnplayers");
	// Call callbacks
	objectrefGetOrCreate(L, player);
	runCallbacks(1, RUN_CALLBACKS_MODE_OR);
	return readParam<bool>(L, -1);
}

bool ScriptApiPlayer::on_prejoinplayer(
	const std::string &name,
	const std::string &ip,
	std::string *reason)
{
	SCRIPTAPI_PRECHECKHEADER

	// Get core.registered_on_prejoinplayers
	lua_getglobal(L, "core");
	lua_getfield(L, -1, "registered_on_prejoinplayers");
	lua_pushstring(L, name.c_str());
	lua_pushstring(L, ip.c_str());
	runCallbacks(2, RUN_CALLBACKS_MODE_OR);
	if (lua_isstring(L, -1)) {
		reason->assign(readParam<std::string>(L, -1));
		return true;
	}
	return false;
}

bool ScriptApiPlayer::can_bypass_userlimit(const std::string &name, const std::string &ip)
{
	SCRIPTAPI_PRECHECKHEADER

	// Get core.registered_on_prejoinplayers
	lua_getglobal(L, "core");