Skip to content

Commit

Permalink
Allow managing object observers
Browse files Browse the repository at this point in the history
Switch player names to `std::string`
  • Loading branch information
appgurueu authored and LoneWolfHT committed Dec 25, 2023
1 parent 73a3df1 commit ecb3194
Show file tree
Hide file tree
Showing 28 changed files with 215 additions and 57 deletions.
14 changes: 14 additions & 0 deletions doc/lua_api.md
Original file line number Diff line number Diff line change
Expand Up @@ -7583,6 +7583,20 @@ child will follow movement and rotation of that bone.
* `get_bone_overrides()`: returns all bone overrides as table `{[bonename] = override, ...}`
* `set_properties(object property table)`
* `get_properties()`: returns a table of all object properties
* `set_observers(observers)`: sets observers (players this object is sent to)
* If `observers` is `nil`, the object's observers are "unmanaged":
The object is sent to all players (in proximity). This is the default.
* `observers` is a "set" of player names: `{[player name] = true, [other player name] = true, ...}`
* A player is an observer if and only if the player's name is a key in the `observers` table.
* The values are irrelevant. To prevent the mistake of expecting `[player name] = false`
to "uninstall" a player as an observer, they must be truthy.
* If players are managed, they always need to have themselves as observers.
* Attachments:
* If an object's observers are managed, the observers of all children need to be managed too.
* The observers of children need to be a subset of the observers of parents.
* `get_observers()`:
* returns `nil` if the observers are unmanaged
* returns a table with all observer names as keys and `true` values (a "set") otherwise
* `is_player()`: returns true for players, false otherwise
* `get_nametag_attributes()`
* returns a table with the attributes of the nametag of an object
Expand Down
1 change: 1 addition & 0 deletions games/devtest/mods/testentities/init.lua
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
dofile(minetest.get_modpath("testentities").."/visuals.lua")
dofile(minetest.get_modpath("testentities").."/observers.lua")
dofile(minetest.get_modpath("testentities").."/selectionbox.lua")
dofile(minetest.get_modpath("testentities").."/armor.lua")
37 changes: 37 additions & 0 deletions games/devtest/mods/testentities/observers.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
local function player_names_excluding(exclude_player_name)
local player_names = {}
for _, player in ipairs(minetest.get_connected_players()) do
player_names[player:get_player_name()] = true
end
player_names[exclude_player_name] = nil
return player_names
end

minetest.register_entity("testentities:observable", {
initial_properties = {
visual = "sprite",
textures = { "testentities_sprite.png" },
static_save = false,
infotext = "Punch to set observers to anyone but you"
},
on_activate = function(self)
self.object:set_armor_groups({punch_operable = 1})
assert(self.object:get_observers() == nil)
-- Using a value of `false` in the table should error.
assert(not pcall(self.object, self.object.set_observers, self.object, {test = false}))
end,
on_punch = function(self, puncher)
local puncher_name = puncher:get_player_name()
local observers = player_names_excluding(puncher_name)
self.object:set_observers(observers)
local got_observers = self.object:get_observers()
for name in pairs(observers) do
assert(got_observers[name])
end
for name in pairs(got_observers) do
assert(observers[name])
end
self.object:set_properties({infotext = "Excluding " .. puncher_name})
return true
end
})
2 changes: 1 addition & 1 deletion src/client/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1579,7 +1579,7 @@ Inventory* Client::getInventory(const InventoryLocation &loc)
{
// Check if we are working with local player inventory
LocalPlayer *player = m_env.getLocalPlayer();
if (!player || strcmp(player->getName(), loc.name.c_str()) != 0)
if (!player || player->getName() != loc.name)
return NULL;
return &player->inventory;
}
Expand Down
2 changes: 1 addition & 1 deletion src/client/content_cao.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@ void GenericCAO::processInitData(const std::string &data)
if (m_is_player) {
// Check if it's the current player
LocalPlayer *player = m_env->getLocalPlayer();
if (player && strcmp(player->getName(), m_name.c_str()) == 0) {
if (player && player->getName() == m_name) {
m_is_local_player = true;
m_is_visible = false;
player->setCAO(this);
Expand Down
3 changes: 2 additions & 1 deletion src/client/localplayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,

#include "localplayer.h"
#include <cmath>
#include <string>
#include "mtevent.h"
#include "collision.h"
#include "nodedef.h"
Expand All @@ -32,7 +33,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
LocalPlayer
*/

LocalPlayer::LocalPlayer(Client *client, const char *name):
LocalPlayer::LocalPlayer(Client *client, const std::string name):
Player(name, client->idef()),
m_client(client)
{
Expand Down
3 changes: 2 additions & 1 deletion src/client/localplayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "settings.h"
#include "lighting.h"
#include <list>
#include <string>

class Client;
class Environment;
Expand All @@ -45,7 +46,7 @@ enum class LocalPlayerAnimation
class LocalPlayer : public Player
{
public:
LocalPlayer(Client *client, const char *name);
LocalPlayer(Client *client, const std::string name);
virtual ~LocalPlayer() = default;

// Initialize hp to 0, so that no hearts will be shown if server
Expand Down
9 changes: 4 additions & 5 deletions src/database/database-files.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,7 @@ void PlayerDatabaseFiles::deSerialize(RemotePlayer *p, std::istream &is,

p->m_dirty = true;
//args.getS32("version"); // Version field value not used
const std::string &name = args.get("name");
strlcpy(p->m_name, name.c_str(), PLAYERNAME_SIZE);
p->m_name = args.get("name");

if (sao) {
try {
Expand Down Expand Up @@ -95,7 +94,7 @@ void PlayerDatabaseFiles::deSerialize(RemotePlayer *p, std::istream &is,
p->inventory.deSerialize(is);
} catch (SerializationError &e) {
errorstream << "Failed to deserialize player inventory. player_name="
<< name << " " << e.what() << std::endl;
<< p->getName() << " " << e.what() << std::endl;
}

if (!p->inventory.getList("craftpreview") && p->inventory.getList("craftresult")) {
Expand All @@ -118,7 +117,7 @@ void PlayerDatabaseFiles::serialize(RemotePlayer *p, std::ostream &os)
// Utilize a Settings object for storing values
Settings args("PlayerArgsEnd");
args.setS32("version", 1);
args.set("name", p->m_name);
args.set("name", p->getName());

PlayerSAO *sao = p->getPlayerSAO();
// This should not happen
Expand Down Expand Up @@ -172,7 +171,7 @@ void PlayerDatabaseFiles::savePlayer(RemotePlayer *player)

deSerialize(&testplayer, is, path, NULL);
is.close();
if (strcmp(testplayer.getName(), player->getName()) == 0) {
if (testplayer.getName() == player->getName()) {
path_found = true;
continue;
}
Expand Down
14 changes: 7 additions & 7 deletions src/database/database-postgresql.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -468,15 +468,15 @@ void PlayerDatabasePostgreSQL::savePlayer(RemotePlayer *player)
std::string hp = itos(sao->getHP());
std::string breath = itos(sao->getBreath());
const char *values[] = {
player->getName(),
player->getName().c_str(),
pitch.c_str(),
yaw.c_str(),
posx.c_str(), posy.c_str(), posz.c_str(),
hp.c_str(),
breath.c_str()
};

const char* rmvalues[] = { player->getName() };
const char* rmvalues[] = { player->getName().c_str() };
beginSave();

if (getPGVersion() < 90500) {
Expand All @@ -501,7 +501,7 @@ void PlayerDatabasePostgreSQL::savePlayer(RemotePlayer *player)
inv_id = itos(i), lsize = itos(list->getSize());

const char* inv_values[] = {
player->getName(),
player->getName().c_str(),
inv_id.c_str(),
width.c_str(),
name.c_str(),
Expand All @@ -516,7 +516,7 @@ void PlayerDatabasePostgreSQL::savePlayer(RemotePlayer *player)
std::string itemStr = oss.str(), slotId = itos(j);

const char* invitem_values[] = {
player->getName(),
player->getName().c_str(),
inv_id.c_str(),
slotId.c_str(),
itemStr.c_str()
Expand All @@ -529,7 +529,7 @@ void PlayerDatabasePostgreSQL::savePlayer(RemotePlayer *player)
const StringMap &attrs = sao->getMeta().getStrings();
for (const auto &attr : attrs) {
const char *meta_values[] = {
player->getName(),
player->getName().c_str(),
attr.first.c_str(),
attr.second.c_str()
};
Expand All @@ -545,7 +545,7 @@ bool PlayerDatabasePostgreSQL::loadPlayer(RemotePlayer *player, PlayerSAO *sao)
sanity_check(sao);
verifyDatabase();

const char *values[] = { player->getName() };
const char *values[] = { player->getName().c_str() };
PGresult *results = execPrepared("load_player", 1, values, false, false);

// Player not found, return not found
Expand Down Expand Up @@ -580,7 +580,7 @@ bool PlayerDatabasePostgreSQL::loadPlayer(RemotePlayer *player, PlayerSAO *sao)
std::string invIdStr = itos(invId);

const char* values2[] = {
player->getName(),
player->getName().c_str(),
invIdStr.c_str()
};
PGresult *results2 = execPrepared("load_player_inventory_items", 2,
Expand Down
5 changes: 0 additions & 5 deletions src/database/database-sqlite3.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,6 @@ class Database_SQLite3 : public Database
sqlite3_vrfy(sqlite3_bind_text(s, iCol, str.c_str(), str.size(), NULL));
}

inline void str_to_sqlite(sqlite3_stmt *s, int iCol, const char *str) const
{
sqlite3_vrfy(sqlite3_bind_text(s, iCol, str, strlen(str), NULL));
}

inline void int_to_sqlite(sqlite3_stmt *s, int iCol, int val) const
{
sqlite3_vrfy(sqlite3_bind_int(s, iCol, val));
Expand Down
6 changes: 3 additions & 3 deletions src/network/serverpackethandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -612,7 +612,7 @@ void Server::handleCommand_InventoryAction(NetworkPacket* pkt)

// If something goes wrong, this player is to blame
RollbackScopeActor rollback_scope(m_rollback,
std::string("player:")+player->getName());
"player:" + player->getName());

/*
Note: Always set inventory not sent, to repair cases
Expand Down Expand Up @@ -1067,7 +1067,7 @@ void Server::handleCommand_Interact(NetworkPacket *pkt)
If something goes wrong, this player is to blame
*/
RollbackScopeActor rollback_scope(m_rollback,
std::string("player:")+player->getName());
"player:" + player->getName());

switch (action) {
// Start digging or punch object
Expand Down Expand Up @@ -1399,7 +1399,7 @@ void Server::handleCommand_NodeMetaFields(NetworkPacket* pkt)

// If something goes wrong, this player is to blame
RollbackScopeActor rollback_scope(m_rollback,
std::string("player:")+player->getName());
"player:" + player->getName());

// Check the target node for rollback data; leave others unnoticed
RollbackNode rn_old(&m_env->getMap(), p, this);
Expand Down
4 changes: 2 additions & 2 deletions src/player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "porting.h" // strlcpy


Player::Player(const char *name, IItemDefManager *idef):
Player::Player(const std::string name, IItemDefManager *idef):
inventory(idef)
{
strlcpy(m_name, name, PLAYERNAME_SIZE);
m_name = name;

inventory.clear();
inventory.addList("main", PLAYER_INVENTORY_SIZE);
Expand Down
7 changes: 4 additions & 3 deletions src/player.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "util/basic_macros.h"
#include <list>
#include <mutex>
#include <string>

#define PLAYERNAME_SIZE 20

Expand Down Expand Up @@ -143,7 +144,7 @@ class Player
{
public:

Player(const char *name, IItemDefManager *idef);
Player(const std::string name, IItemDefManager *idef);
virtual ~Player() = 0;

DISABLE_CLASS_COPY(Player);
Expand All @@ -166,7 +167,7 @@ class Player
m_speed = speed;
}

const char *getName() const { return m_name; }
const std::string& getName() const { return m_name; }

u32 getFreeHudID()
{
Expand Down Expand Up @@ -233,7 +234,7 @@ class Player
s32 hud_hotbar_itemcount;

protected:
char m_name[PLAYERNAME_SIZE];
std::string m_name;
v3f m_speed; // velocity; in BS-space
u16 m_wield_index = 0;
PlayerFovSpec m_fov_override_spec = { 0.0f, false, 0.0f };
Expand Down
2 changes: 1 addition & 1 deletion src/remoteplayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ bool RemotePlayer::m_setting_cache_loaded = false;
float RemotePlayer::m_setting_chat_message_limit_per_10sec = 0.0f;
u16 RemotePlayer::m_setting_chat_message_limit_trigger_kick = 0;

RemotePlayer::RemotePlayer(const char *name, IItemDefManager *idef):
RemotePlayer::RemotePlayer(const std::string name, IItemDefManager *idef):
Player(name, idef)
{
if (!RemotePlayer::m_setting_cache_loaded) {
Expand Down
2 changes: 1 addition & 1 deletion src/remoteplayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class RemotePlayer : public Player
friend class PlayerDatabaseFiles;

public:
RemotePlayer(const char *name, IItemDefManager *idef);
RemotePlayer(const std::string name, IItemDefManager *idef);
virtual ~RemotePlayer() = default;

PlayerSAO *getPlayerSAO() { return m_sao; }
Expand Down
4 changes: 2 additions & 2 deletions src/script/cpp_api/s_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ void ScriptApiServer::freeDynamicMediaCallback(u32 token)
lua_pop(L, 2);
}

void ScriptApiServer::on_dynamic_media_added(u32 token, const char *playername)
void ScriptApiServer::on_dynamic_media_added(u32 token, const std::string &playername)
{
SCRIPTAPI_PRECHECKHEADER

Expand All @@ -257,6 +257,6 @@ void ScriptApiServer::on_dynamic_media_added(u32 token, const char *playername)
lua_rawgeti(L, -1, token);
luaL_checktype(L, -1, LUA_TFUNCTION);

lua_pushstring(L, playername);
lua_pushstring(L, playername.c_str());
PCALL_RES(lua_pcall(L, 1, 0, error_handler));
}
2 changes: 1 addition & 1 deletion src/script/cpp_api/s_server.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class ScriptApiServer
/* dynamic media handling */
static u32 allocateDynamicMediaCallback(lua_State *L, int f_idx);
void freeDynamicMediaCallback(u32 token);
void on_dynamic_media_added(u32 token, const char *playername);
void on_dynamic_media_added(u32 token, const std::string &playername);

private:
void getAuthHandler();
Expand Down
2 changes: 1 addition & 1 deletion src/script/lua_api/l_localplayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ int LuaLocalPlayer::l_get_name(lua_State *L)
{
LocalPlayer *player = getobject(L, 1);

lua_pushstring(L, player->getName());
lua_pushstring(L, player->getName().c_str());
return 1;
}

Expand Down
Loading

0 comments on commit ecb3194

Please sign in to comment.