aboutsummaryrefslogtreecommitdiff
path: root/src/script/lua_api/l_auth.cpp
blob: 0fc57ba3a71d0d2e00c5bb2292127fc8dd33b1c7 (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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
/*
Minetest
Copyright (C) 2018 bendeutsch, Ben Deutsch <ben@bendeutsch.de>

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 "lua_api/l_auth.h"
#include "lua_api/l_internal.h"
#include "common/c_converter.h"
#include "common/c_content.h"
#include "cpp_api/s_base.h"
#include "server.h"
#include "environment.h"
#include "database/database.h"
#include <algorithm>

// common start: ensure auth db
AuthDatabase *ModApiAuth::getAuthDb(lua_State *L)
{
	ServerEnvironment *server_environment =
			dynamic_cast<ServerEnvironment *>(getEnv(L));
	if (!server_environment)
		return nullptr;
	return server_environment->getAuthDatabase();
}

void ModApiAuth::pushAuthEntry(lua_State *L, const AuthEntry &authEntry)
{
	lua_newtable(L);
	int table = lua_gettop(L);
	// id
	lua_pushnumber(L, authEntry.id);
	lua_setfield(L, table, "id");
	// name
	lua_pushstring(L, authEntry.name.c_str());
	lua_setfield(L, table, "name");
	// password
	lua_pushstring(L, authEntry.password.c_str());
	lua_setfield(L, table, "password");
	// privileges
	lua_newtable(L);
	int privtable = lua_gettop(L);
	for (const std::string &privs : authEntry.privileges) {
		lua_pushboolean(L, true);
		lua_setfield(L, privtable, privs.c_str());
	}
	lua_setfield(L, table, "privileges");
	// last_login
	lua_pushnumber(L, authEntry.last_login);
	lua_setfield(L, table, "last_login");

	lua_pushvalue(L, table);
}

// auth_read(name)
int ModApiAuth::l_auth_read(lua_State *L)
{
	NO_MAP_LOCK_REQUIRED;
	AuthDatabase *auth_db = getAuthDb(L);
	if (!auth_db)
		return 0;
	AuthEntry authEntry;
	const char *name = luaL_checkstring(L, 1);
	bool success = auth_db->getAuth(std::string(name), authEntry);
	if (!success)
		return 0;

	pushAuthEntry(L, authEntry);
	return 1;
}

// auth_save(table)
int ModApiAuth::l_auth_save(lua_State *L)
{
	NO_MAP_LOCK_REQUIRED;
	AuthDatabase *auth_db = getAuthDb(L);
	if (!auth_db)
		return 0;
	luaL_checktype(L, 1, LUA_TTABLE);
	int table = 1;
	AuthEntry authEntry;
	bool success;
	success = getintfield(L, table, "id", authEntry.id);
	success = success && getstringfield(L, table, "name", authEntry.name);
	success = success && getstringfield(L, table, "password", authEntry.password);
	lua_getfield(L, table, "privileges");
	if (lua_istable(L, -1)) {
		lua_pushnil(L);
		while (lua_next(L, -2)) {
			authEntry.privileges.emplace_back(
					lua_tostring(L, -2)); // the key, not the value
			lua_pop(L, 1);
		}
	} else {
		success = false;
	}
	lua_pop(L, 1); // the table
	success = success && getintfield(L, table, "last_login", authEntry.last_login);

	if (!success) {
		lua_pushboolean(L, false);
		return 1;
	}

	lua_pushboolean(L, auth_db->saveAuth(authEntry));
	return 1;
}

// auth_create(table)
int ModApiAuth::l_auth_create(lua_State *L)
{
	NO_MAP_LOCK_REQUIRED;
	AuthDatabase *auth_db = getAuthDb(L);
	if (!auth_db)
		return 0;
	luaL_checktype(L, 1, LUA_TTABLE);
	int table = 1;
	AuthEntry authEntry;
	bool success;
	// no meaningful id field, we assume
	success = getstringfield(L, table, "name", authEntry.name);
	success = success && getstringfield(L, table, "password", authEntry.password);
	lua_getfield(L, table, "privileges");
	if (lua_istable(L, -1)) {
		lua_pushnil(L);
		while (lua_next(L, -2)) {
			authEntry.privileges.emplace_back(
					lua_tostring(L, -2)); // the key, not the value
			lua_pop(L, 1);
		}
	} else {
		success = false;
	}
	lua_pop(L, 1); // the table
	success = success && getintfield(L, table, "last_login", authEntry.last_login);

	if (!success)
		return 0;

	if (auth_db->createAuth(authEntry)) {
		pushAuthEntry(L, authEntry);
		return 1;
	}

	return 0;
}

// auth_delete(name)
int ModApiAuth::l_auth_delete(lua_State *L)
{
	NO_MAP_LOCK_REQUIRED;
	AuthDatabase *auth_db = getAuthDb(L);
	if (!auth_db)
		return 0;
	std::string name(luaL_checkstring(L, 1));
	lua_pushboolean(L, auth_db->deleteAuth(name));
	return 1;
}

// auth_list_names()
int ModApiAuth::l_auth_list_names(lua_State *L)
{
	NO_MAP_LOCK_REQUIRED;
	AuthDatabase *auth_db = getAuthDb(L);
	if (!auth_db)
		return 0;
	std::vector<std::string> names;
	auth_db->listNames(names);
	lua_createtable(L, names.size(), 0);
	int table = lua_gettop(L);
	int i = 1;
	for (const std::string &name : names) {
		lua_pushstring(L, name.c_str());
		lua_rawseti(L, table, i++);
	}
	return 1;
}

// auth_reload()
int ModApiAuth::l_auth_reload(lua_State *L)
{
	NO_MAP_LOCK_REQUIRED;
	AuthDatabase *auth_db = getAuthDb(L);
	if (auth_db)
		auth_db->reload();
	return 0;
}

void ModApiAuth::Initialize(lua_State *L, int top)
{

	lua_newtable(L);
	int auth_top = lua_gettop(L);

	registerFunction(L, "read", l_auth_read, auth_top);
	registerFunction(L, "save", l_auth_save, auth_top);
	registerFunction(L, "create", l_auth_create, auth_top);
	registerFunction(L, "delete", l_auth_delete, auth_top);
	registerFunction(L, "list_names", l_auth_list_names, auth_top);
	registerFunction(L, "reload", l_auth_reload, auth_top);

	lua_setfield(L, top, "auth");
}
span class="hl kwa">false, w_speed = nil, } } advtrains.trackplacer.register_tracktype("advtrains_signals_ks:hs") advtrains.trackplacer.register_tracktype("advtrains_signals_ks:ra") advtrains.trackplacer.register_tracktype("advtrains_signals_ks:sign") advtrains.trackplacer.register_tracktype("advtrains_signals_ks:sign_lf") advtrains.trackplacer.register_tracktype("advtrains_signals_ks:sign_lf7") advtrains.trackplacer.register_tracktype("advtrains_signals_ks:zs3") advtrains.trackplacer.register_tracktype("advtrains_signals_ks:zs3v") advtrains.trackplacer.register_tracktype("advtrains_signals_ks:mast") for _, rtab in ipairs({ {rot = "0", sbox = {-1/8, -1/2, -1/2, 1/8, 1/2, -1/4}, ici=true}, {rot = "30", sbox = {-3/8, -1/2, -1/2, -1/8, 1/2, -1/4},}, {rot = "45", sbox = {-1/2, -1/2, -1/2, -1/4, 1/2, -1/4},}, {rot = "60", sbox = {-1/2, -1/2, -3/8, -1/4, 1/2, -1/8},}, }) do local rot = rtab.rot for typ, prts in pairs({ danger = {asp = advtrains.interlocking.DANGER, n = "slow", ici=true}, slow = { asp = function(pos) return { main = getzs3(pos) or -1, proceed_as_main = true, dst = 0 } end, n = "nextslow" }, nextslow = { asp = function(pos) return { main = getzs3(pos) or -1, proceed_as_main = true, dst = getzs3v(pos) or 6 } end, n = "free" }, free = { asp = function(pos) return { main = getzs3(pos) or -1, proceed_as_main = true, dst = -1 } end, n = "shunt" }, shunt = {asp = { main = 0, shunt = true} , n = "danger"}, }) do local tile = "advtrains_signals_ks_ltm_"..typ..".png" local afunc = prts.asp if type(afunc) == "table" then afunc = function() return prts.asp end end if typ == "nextslow" then tile = { name = tile, animation = { type = "vertical_frames", aspect_w = 32, aspect_h = 32, length = 1, } } end minetest.register_node("advtrains_signals_ks:hs_"..typ.."_"..rot, { description = "Ks Main Signal", drawtype = "mesh", mesh = "advtrains_signals_ks_main_smr"..rot..".obj", tiles = {"advtrains_signals_ks_mast.png", "advtrains_signals_ks_head.png", "advtrains_signals_ks_head.png", tile}, paramtype="light", sunlight_propagates=true, light_source = 4, paramtype2 = "facedir", selection_box = { type = "fixed", fixed = {rtab.sbox, {-1/4, -1/2, -1/4, 1/4, -7/16, 1/4}} }, groups = { cracky = 2, advtrains_signal = 2, not_blocking_trains = 1, save_in_at_nodedb = 1, not_in_creative_inventory = (rtab.ici and prts.ici) and 0 or 1, }, drop = "advtrains_signals_ks:hs_danger_0", inventory_image = "advtrains_signals_ks_hs_inv.png", advtrains = { set_aspect = setaspectf(rot), supported_aspects = suppasp, get_aspect = afunc, }, on_rightclick = advtrains.interlocking.signal_rc_handler, can_dig = advtrains.interlocking.signal_can_dig, after_dig_node = advtrains.interlocking.signal_after_dig, }) -- rotatable by trackworker advtrains.trackplacer.add_worked("advtrains_signals_ks:hs", typ, "_"..rot) end --Rangiersignale: for typ, prts in pairs({ danger = {asp = { main = false, shunt = false }, n = "shuntd", ici=true}, shuntd = {asp = { main = false, shunt = true } , n = "danger"}, }) do minetest.register_node("advtrains_signals_ks:ra_"..typ.."_"..rot, { description = "Ks Shunting Signal", drawtype = "mesh", mesh = "advtrains_signals_ks_sht_smr"..rot..".obj", tiles = {"advtrains_signals_ks_mast.png", "advtrains_signals_ks_head.png", "advtrains_signals_ks_head.png", "advtrains_signals_ks_ltm_"..typ..".png"}, paramtype="light", sunlight_propagates=true, light_source = 4, paramtype2 = "facedir", selection_box = { type = "fixed", fixed = {-1/4, -1/2, -1/4, 1/4, 0, 1/4} }, groups = { cracky = 2, advtrains_signal = 2, not_blocking_trains = 1, save_in_at_nodedb = 1, not_in_creative_inventory = (rtab.ici and prts.ici) and 0 or 1, }, drop = "advtrains_signals_ks:ra_danger_0", inventory_image = "advtrains_signals_ks_ra_inv.png", advtrains = { set_aspect = setaspectf_ra(rot), supported_aspects = suppasp_ra, get_aspect = function(pos, node) return prts.asp end, }, on_rightclick = advtrains.interlocking.signal_rc_handler, can_dig = advtrains.interlocking.signal_can_dig, after_dig_node = advtrains.interlocking.signal_after_dig, }) -- rotatable by trackworker advtrains.trackplacer.add_worked("advtrains_signals_ks:ra", typ, "_"..rot) end -- Schilder: local function register_sign(prefix, typ, nxt, description, mesh, tile2, dtyp, inv, asp) minetest.register_node("advtrains_signals_ks:"..prefix.."_"..typ.."_"..rot, { description = description, drawtype = "mesh", mesh = "advtrains_signals_ks_"..mesh.."_smr"..rot..".obj", tiles = {"advtrains_signals_ks_signpost.png", tile2}, paramtype="light", sunlight_propagates=true, light_source = 4, paramtype2 = "facedir", selection_box = { type = "fixed", fixed = {rtab.sbox, {-1/4, -1/2, -1/4, 1/4, -7/16, 1/4}} }, groups = { cracky = 2, advtrains_signal = 2, not_blocking_trains = 1, save_in_at_nodedb = 1, not_in_creative_inventory = (rtab.ici and typ == dtyp) and 0 or 1, }, drop = "advtrains_signals_ks:"..prefix.."_"..dtyp.."_0", inventory_image = inv, advtrains = { get_aspect = function() return asp end }, on_rightclick = advtrains.interlocking.signal_rc_handler, can_dig = advtrains.interlocking.signal_can_dig, after_dig_node = advtrains.interlocking.signal_after_dig, }) -- rotatable by trackworker advtrains.trackplacer.add_worked("advtrains_signals_ks:"..prefix, typ, "_"..rot, nxt) end for typ, prts in pairs { ["hfs"] = {asp = {main = false, shunt = false}, n = "pam", mesh = "_hfs", owntile = true}, ["pam"] = {asp = {main = -1, shunt = false, proceed_as_main = true}, n = "ne4"}, ["ne4"] = {asp = {}, n = "ne3x1", mesh="_ne4", owntile = true}, ["ne3x1"] = {asp = {}, n = "ne3x2", mesh="_ne3", owntile = true}, ["ne3x2"] = {asp = {}, n = "ne3x3", mesh="_ne3", owntile = true}, ["ne3x3"] = {asp = {}, n = "ne3x4", mesh="_ne3", owntile = true}, ["ne3x4"] = {asp = {}, n = "ne3x5", mesh="_ne3", owntile = true}, ["ne3x5"] = {asp = {}, n = "hfs", mesh="_ne3", owntile = true}, } do local mesh = prts.mesh or "" local tile2 = "advtrains_signals_ks_sign_lf7.png^(advtrains_signals_ks_sign_"..typ..".png^[makealpha:255,255,255)" if prts.owntile then tile2 = "advtrains_signals_ks_sign_"..typ..".png" end register_sign("sign", typ, prts.n, "Signal Sign", "sign"..mesh, tile2, "hfs", "advtrains_signals_ks_sign_lf7.png", prts.asp) end for typ, prts in pairs { -- Speed restrictions: ["4"] = {asp = { main = 4, shunt = true }, n = "6"}, ["6"] = {asp = { main = 6, shunt = true }, n = "8"}, ["8"] = {asp = { main = 8, shunt = true }, n = "12"}, ["12"] = {asp = { main = 12, shunt = true }, n = "16"}, ["16"] = {asp = { main = 16, shunt = true }, n = "e"}, -- Speed restriction lifted ["e"] = {asp = { main = -1, shunt = true }, n = "4", mesh = "_zs10"}, } do local mesh = tonumber(typ) and "_zs3" or prts.mesh or "" local tile2 = "[combine:40x40:0,0=\\(advtrains_signals_ks_sign_off.png\\^[resize\\:40x40\\):3,-2=advtrains_signals_ks_sign_"..typ..".png^[invert:rgb" if typ == "e" then tile2 = "advtrains_signals_ks_sign_zs10.png" end register_sign("sign", typ, prts.n, "Permanent local speed restriction sign", "sign"..mesh, tile2, "8", "advtrains_signals_ks_sign_8.png^[invert:rgb", prts.asp) end for typ, prts in pairs { ["4"] = {main = 4, n = "6"}, ["6"] = {main = 6, n = "8"}, ["8"] = {main = 8, n = "12"}, ["12"] = {main = 12, n = "16"}, ["16"] = {main = 16, n = "e"}, ["e"] = {main = -1, n = "4"}, } do local tile2 = "advtrains_signals_ks_sign_lf7.png^(advtrains_signals_ks_sign_"..typ..".png^[makealpha:255,255,255)"..(typ == "e" and "" or "^[multiply:orange") local inv = "advtrains_signals_ks_sign_lf7.png^(advtrains_signals_ks_sign_8.png^[makealpha:255,255,255)^[multiply:orange" register_sign("sign_lf", typ, prts.n, "Temporary local speed restriction sign", "sign", tile2, "8", inv, {main = prts.main, shunt = true, type = "temp"}) end for typ, prts in pairs { ["4"] = {main = 4, n = "6"}, ["6"] = {main = 6, n = "8"}, ["8"] = {main = 8, n = "12"}, ["12"] = {main = 12, n = "16"}, ["16"] = {main = 16, n = "20"}, ["20"] = {main = 20, n = "4"}, } do local tile2 = "advtrains_signals_ks_sign_lf7.png^(advtrains_signals_ks_sign_"..typ..".png^[makealpha:255,255,255)" local inv = "advtrains_signals_ks_sign_lf7.png^(advtrains_signals_ks_sign_8.png^[makealpha:255,255,255)" register_sign("sign_lf7", typ, prts.n, "Line speed restriction sign", "sign", tile2, "8", inv, {main = prts.main, shunt = true, type = "line"}) end -- Geschwindigkeits(vor)anzeiger für Ks-Signale for typ, prts in pairs({ ["off"] = {n = "4", ici = true}, ["4"] = {n = "6"}, ["6"] = {n = "8"}, ["8"] = {n = "12"}, ["12"] = {n = "16"}, ["16"] = {n = "off"}, }) do local def = { drawtype = "mesh", tiles = {"advtrains_signals_ks_mast.png","advtrains_signals_ks_head.png","advtrains_signals_ks_sign_"..typ..".png^[invert:rgb^[noalpha"}, paramtype = "light", sunlight_propagates = true, light_source = 4,