mirror of
https://github.com/luanti-org/luanti.git
synced 2025-06-27 16:36:03 +00:00
Allow managing object observers
----- Co-authored-by: sfan5 <sfan5@live.de> Co-authored-by: SmallJoker <SmallJoker@users.noreply.github.com>
This commit is contained in:
parent
cc8e7a569e
commit
6874c358ea
15 changed files with 284 additions and 22 deletions
|
@ -27,6 +27,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#include "common/c_converter.h"
|
||||
#include "common/c_content.h"
|
||||
#include "log.h"
|
||||
#include "player.h"
|
||||
#include "server/serveractiveobject.h"
|
||||
#include "tool.h"
|
||||
#include "remoteplayer.h"
|
||||
#include "server.h"
|
||||
|
@ -36,6 +38,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#include "server/player_sao.h"
|
||||
#include "server/serverinventorymgr.h"
|
||||
#include "server/unit_sao.h"
|
||||
#include "util/string.h"
|
||||
|
||||
using object_t = ServerActiveObject::object_t;
|
||||
|
||||
|
@ -837,6 +840,85 @@ int ObjectRef::l_get_properties(lua_State *L)
|
|||
return 1;
|
||||
}
|
||||
|
||||
// set_observers(self, observers)
|
||||
int ObjectRef::l_set_observers(lua_State *L)
|
||||
{
|
||||
GET_ENV_PTR;
|
||||
ObjectRef *ref = checkObject<ObjectRef>(L, 1);
|
||||
ServerActiveObject *sao = getobject(ref);
|
||||
if (sao == nullptr)
|
||||
throw LuaError("Invalid ObjectRef");
|
||||
|
||||
// Reset object to "unmanaged" (sent to everyone)?
|
||||
if (lua_isnoneornil(L, 2)) {
|
||||
sao->m_observers.reset();
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::unordered_set<std::string> observer_names;
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, 2) != 0) {
|
||||
std::string name = readParam<std::string>(L, -2);
|
||||
if (name.empty())
|
||||
throw LuaError("Observer name is empty");
|
||||
if (name.size() > PLAYERNAME_SIZE)
|
||||
throw LuaError("Observer name is too long");
|
||||
if (!string_allowed(name, PLAYERNAME_ALLOWED_CHARS))
|
||||
throw LuaError("Observer name contains invalid characters");
|
||||
if (!lua_toboolean(L, -1)) // falsy value?
|
||||
throw LuaError("Values in the `observers` table need to be true");
|
||||
observer_names.insert(std::move(name));
|
||||
lua_pop(L, 1); // pop value, keep key
|
||||
}
|
||||
|
||||
RemotePlayer *player = getplayer(ref);
|
||||
if (player != nullptr) {
|
||||
observer_names.insert(player->getName());
|
||||
}
|
||||
|
||||
sao->m_observers = std::move(observer_names);
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<typename F>
|
||||
static int get_observers(lua_State *L, F observer_getter)
|
||||
{
|
||||
ObjectRef *ref = ObjectRef::checkObject<ObjectRef>(L, 1);
|
||||
ServerActiveObject *sao = ObjectRef::getobject(ref);
|
||||
if (sao == nullptr)
|
||||
throw LuaError("invalid ObjectRef");
|
||||
|
||||
const auto observers = observer_getter(sao);
|
||||
if (!observers) {
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
// Push set of observers {[name] = true}
|
||||
lua_createtable(L, 0, observers->size());
|
||||
for (auto &name : *observers) {
|
||||
lua_pushboolean(L, true);
|
||||
lua_setfield(L, -2, name.c_str());
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
// get_observers(self)
|
||||
int ObjectRef::l_get_observers(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
return get_observers(L, [](auto sao) { return sao->m_observers; });
|
||||
}
|
||||
|
||||
// get_effective_observers(self)
|
||||
int ObjectRef::l_get_effective_observers(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
return get_observers(L, [](auto sao) {
|
||||
// The cache may be outdated, so we always have to recalculate.
|
||||
return sao->recalculateEffectiveObservers();
|
||||
});
|
||||
}
|
||||
|
||||
// is_player(self)
|
||||
int ObjectRef::l_is_player(lua_State *L)
|
||||
{
|
||||
|
@ -2676,6 +2758,9 @@ luaL_Reg ObjectRef::methods[] = {
|
|||
luamethod(ObjectRef, get_properties),
|
||||
luamethod(ObjectRef, set_nametag_attributes),
|
||||
luamethod(ObjectRef, get_nametag_attributes),
|
||||
luamethod(ObjectRef, set_observers),
|
||||
luamethod(ObjectRef, get_observers),
|
||||
luamethod(ObjectRef, get_effective_observers),
|
||||
|
||||
luamethod_aliased(ObjectRef, set_velocity, setvelocity),
|
||||
luamethod_aliased(ObjectRef, add_velocity, add_player_velocity),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue