Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Add player:get_meta(), deprecate player attributes (#7202)
* Add player:get_meta(), deprecate player attributes
- Loading branch information
|
@@ -347,6 +347,7 @@ LOCAL_SRC_FILES += \ |
|
|
jni/src/script/lua_api/l_nodetimer.cpp \ |
|
|
jni/src/script/lua_api/l_noise.cpp \ |
|
|
jni/src/script/lua_api/l_object.cpp \ |
|
|
jni/src/script/lua_api/l_playermeta.cpp \ |
|
|
jni/src/script/lua_api/l_particles.cpp \ |
|
|
jni/src/script/lua_api/l_particles_local.cpp\ |
|
|
jni/src/script/lua_api/l_rollback.cpp \ |
|
|
|
@@ -3902,7 +3902,7 @@ An interface to use mod channels on client and server |
|
|
* Message size is limited to 65535 characters by protocol. |
|
|
|
|
|
### `MetaDataRef` |
|
|
See `StorageRef`, `NodeMetaRef` and `ItemStackMetaRef`. |
|
|
See `StorageRef`, `NodeMetaRef`, `ItemStackMetaRef`, and `PlayerMetaRef`. |
|
|
|
|
|
#### Methods |
|
|
* `set_string(name, value)` |
|
@@ -3952,6 +3952,15 @@ Can be obtained via `minetest.get_mod_storage()` during load time. |
|
|
#### Methods |
|
|
* All methods in MetaDataRef |
|
|
|
|
|
### `PlayerMetaRef` |
|
|
Player metadata. |
|
|
Uses the same method of storage as the deprecated player attribute API, so |
|
|
data there will also be in player meta. |
|
|
Can be obtained using `player:get_meta()`. |
|
|
|
|
|
#### Methods |
|
|
* All methods in MetaDataRef |
|
|
|
|
|
### `NodeTimerRef` |
|
|
Node Timers: a high resolution persistent per-node timer. |
|
|
Can be gotten via `minetest.get_node_timer(pos)`. |
|
@@ -4101,14 +4110,15 @@ This is basically a reference to a C++ `ServerActiveObject` |
|
|
* `0`: player is drowning |
|
|
* max: bubbles bar is not shown |
|
|
* See Object Properties for more information |
|
|
* `set_attribute(attribute, value)`: |
|
|
* `set_attribute(attribute, value)`: DEPRECATED, use get_meta() instead |
|
|
* Sets an extra attribute with value on player. |
|
|
* `value` must be a string, or a number which will be converted to a |
|
|
string. |
|
|
* If `value` is `nil`, remove attribute from player. |
|
|
* `get_attribute(attribute)`: |
|
|
* `get_attribute(attribute)`: DEPRECATED, use get_meta() instead |
|
|
* Returns value (a string) for extra attribute. |
|
|
* Returns `nil` if no attribute found. |
|
|
* `get_meta()`: Returns a PlayerMetaRef. |
|
|
* `set_inventory_formspec(formspec)` |
|
|
* Redefine player's inventory form |
|
|
* Should usually be called in `on_joinplayer` |
|
|
|
@@ -13,7 +13,7 @@ assert(pseudo:next() == 13854) |
|
|
-- HP Change Reasons |
|
|
-- |
|
|
local expect = nil |
|
|
minetest.register_on_joinplayer(function(player) |
|
|
local function run_hpchangereason_tests(player) |
|
|
expect = { type = "set_hp", from = "mod" } |
|
|
player:set_hp(3) |
|
|
assert(expect == nil) |
|
@@ -25,8 +25,7 @@ minetest.register_on_joinplayer(function(player) |
|
|
expect = { df = 3458973454, type = "fall", from = "mod" } |
|
|
player:set_hp(10, { type = "fall", df = 3458973454 }) |
|
|
assert(expect == nil) |
|
|
end) |
|
|
|
|
|
end |
|
|
minetest.register_on_player_hpchange(function(player, hp, reason) |
|
|
for key, value in pairs(reason) do |
|
|
assert(expect[key] == value) |
|
@@ -38,3 +37,32 @@ minetest.register_on_player_hpchange(function(player, hp, reason) |
|
|
|
|
|
expect = nil |
|
|
end) |
|
|
|
|
|
|
|
|
|
|
|
local function run_player_meta_tests(player) |
|
|
local meta = player:get_meta() |
|
|
meta:set_string("foo", "bar") |
|
|
assert(meta:get_string("foo") == "bar") |
|
|
|
|
|
local meta2 = player:get_meta() |
|
|
assert(meta2:get_string("foo") == "bar") |
|
|
assert(meta:equals(meta2)) |
|
|
assert(player:get_attribute("foo") == "bar") |
|
|
|
|
|
meta:set_string("bob", "dillan") |
|
|
assert(meta:get_string("foo") == "bar") |
|
|
assert(meta:get_string("bob") == "dillan") |
|
|
assert(meta2:get_string("foo") == "bar") |
|
|
assert(meta2:get_string("bob") == "dillan") |
|
|
assert(meta:equals(meta2)) |
|
|
assert(player:get_attribute("foo") == "bar") |
|
|
assert(player:get_attribute("bob") == "dillan") |
|
|
end |
|
|
|
|
|
local function run_player_tests(player) |
|
|
run_hpchangereason_tests(player) |
|
|
run_player_meta_tests(player) |
|
|
minetest.chat_send_all("All tests pass!") |
|
|
end |
|
|
minetest.register_on_joinplayer(run_player_tests) |
|
@@ -197,7 +197,6 @@ class LagPool |
|
|
} |
|
|
}; |
|
|
|
|
|
typedef std::unordered_map<std::string, std::string> PlayerAttributes; |
|
|
class RemotePlayer; |
|
|
|
|
|
class PlayerSAO : public UnitSAO |
|
@@ -269,49 +268,6 @@ class PlayerSAO : public UnitSAO |
|
|
int getWieldIndex() const; |
|
|
void setWieldIndex(int i); |
|
|
|
|
|
/* |
|
|
Modding interface |
|
|
*/ |
|
|
inline void setExtendedAttribute(const std::string &attr, const std::string &value) |
|
|
{ |
|
|
m_extra_attributes[attr] = value; |
|
|
m_extended_attributes_modified = true; |
|
|
} |
|
|
|
|
|
inline bool getExtendedAttribute(const std::string &attr, std::string *value) |
|
|
{ |
|
|
if (m_extra_attributes.find(attr) == m_extra_attributes.end()) |
|
|
return false; |
|
|
|
|
|
*value = m_extra_attributes[attr]; |
|
|
return true; |
|
|
} |
|
|
|
|
|
inline void removeExtendedAttribute(const std::string &attr) |
|
|
{ |
|
|
PlayerAttributes::iterator it = m_extra_attributes.find(attr); |
|
|
if (it == m_extra_attributes.end()) |
|
|
return; |
|
|
|
|
|
m_extra_attributes.erase(it); |
|
|
m_extended_attributes_modified = true; |
|
|
} |
|
|
|
|
|
inline const PlayerAttributes &getExtendedAttributes() |
|
|
{ |
|
|
return m_extra_attributes; |
|
|
} |
|
|
|
|
|
inline bool extendedAttributesModified() const |
|
|
{ |
|
|
return m_extended_attributes_modified; |
|
|
} |
|
|
|
|
|
inline void setExtendedAttributeModified(bool v) |
|
|
{ |
|
|
m_extended_attributes_modified = v; |
|
|
} |
|
|
|
|
|
/* |
|
|
PlayerSAO-specific |
|
|
*/ |
|
@@ -375,6 +331,8 @@ class PlayerSAO : public UnitSAO |
|
|
v3f getEyePosition() const { return m_base_position + getEyeOffset(); } |
|
|
v3f getEyeOffset() const; |
|
|
|
|
|
inline Metadata &getMeta() { return m_meta; } |
|
|
|
|
|
private: |
|
|
std::string getPropertyPacket(); |
|
|
void unlinkPlayerSessionAndSave(); |
|
@@ -410,8 +368,7 @@ class PlayerSAO : public UnitSAO |
|
|
f32 m_fov = 0.0f; |
|
|
s16 m_wanted_range = 0.0f; |
|
|
|
|
|
PlayerAttributes m_extra_attributes; |
|
|
bool m_extended_attributes_modified = false; |
|
|
Metadata m_meta; |
|
|
public: |
|
|
float m_physics_override_speed = 1.0f; |
|
|
float m_physics_override_jump = 1.0f; |
|
|
|
@@ -518,7 +518,7 @@ void PlayerDatabasePostgreSQL::savePlayer(RemotePlayer *player) |
|
|
} |
|
|
|
|
|
execPrepared("remove_player_metadata", 1, rmvalues); |
|
|
const PlayerAttributes &attrs = sao->getExtendedAttributes(); |
|
|
const StringMap &attrs = sao->getMeta().getStrings(); |
|
|
for (const auto &attr : attrs) { |
|
|
const char *meta_values[] = { |
|
|
player->getName(), |
|
@@ -527,6 +527,7 @@ void PlayerDatabasePostgreSQL::savePlayer(RemotePlayer *player) |
|
|
}; |
|
|
execPrepared("save_player_metadata", 3, meta_values); |
|
|
} |
|
|
sao->getMeta().setModified(false); |
|
|
endSave(); |
|
|
} |
|
|
|
|
@@ -594,8 +595,9 @@ bool PlayerDatabasePostgreSQL::loadPlayer(RemotePlayer *player, PlayerSAO *sao) |
|
|
|
|
|
int numrows = PQntuples(results); |
|
|
for (int row = 0; row < numrows; row++) { |
|
|
sao->setExtendedAttribute(PQgetvalue(results, row, 0),PQgetvalue(results, row, 1)); |
|
|
sao->getMeta().setString(PQgetvalue(results, row, 0), PQgetvalue(results, row, 1)); |
|
|
} |
|
|
sao->getMeta().setModified(false); |
|
|
|
|
|
PQclear(results); |
|
|
|
|
|
|
@@ -520,14 +520,15 @@ void PlayerDatabaseSQLite3::savePlayer(RemotePlayer *player) |
|
|
sqlite3_vrfy(sqlite3_step(m_stmt_player_metadata_remove), SQLITE_DONE); |
|
|
sqlite3_reset(m_stmt_player_metadata_remove); |
|
|
|
|
|
const PlayerAttributes &attrs = sao->getExtendedAttributes(); |
|
|
const StringMap &attrs = sao->getMeta().getStrings(); |
|
|
for (const auto &attr : attrs) { |
|
|
str_to_sqlite(m_stmt_player_metadata_add, 1, player->getName()); |
|
|
str_to_sqlite(m_stmt_player_metadata_add, 2, attr.first); |
|
|
str_to_sqlite(m_stmt_player_metadata_add, 3, attr.second); |
|
|
sqlite3_vrfy(sqlite3_step(m_stmt_player_metadata_add), SQLITE_DONE); |
|
|
sqlite3_reset(m_stmt_player_metadata_add); |
|
|
} |
|
|
sao->getMeta().setModified(false); |
|
|
|
|
|
endSave(); |
|
|
} |
|
@@ -578,8 +579,9 @@ bool PlayerDatabaseSQLite3::loadPlayer(RemotePlayer *player, PlayerSAO *sao) |
|
|
std::string attr = sqlite_to_string(m_stmt_player_metadata_load, 0); |
|
|
std::string value = sqlite_to_string(m_stmt_player_metadata_load, 1); |
|
|
|
|
|
sao->setExtendedAttribute(attr, value); |
|
|
sao->getMeta().setString(attr, value); |
|
|
} |
|
|
sao->getMeta().setModified(false); |
|
|
sqlite3_reset(m_stmt_player_metadata_load); |
|
|
return true; |
|
|
} |
|
|
|
|
@@ -1,3 +1,23 @@ |
|
|
/* |
|
|
Minetest |
|
|
Copyright (C) 2017-8 rubenwardy <rw@rubenwardy.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 "itemstackmetadata.h" |
|
|
#include "util/serialize.h" |
|
|
#include "util/strfnd.h" |
|
|
|
|
@@ -1,6 +1,6 @@ |
|
|
/* |
|
|
Minetest |
|
|
Copyright (C) 2010-2013 rubenwardy <rubenwardy@gmail.com> |
|
|
Copyright (C) 2017-8 rubenwardy <rw@rubenwardy.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 |
|
|
|
@@ -27,6 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc., |
|
|
void Metadata::clear() |
|
|
{ |
|
|
m_stringvars.clear(); |
|
|
m_modified = true; |
|
|
} |
|
|
|
|
|
bool Metadata::empty() const |
|
@@ -68,6 +69,18 @@ const std::string &Metadata::getString(const std::string &name, u16 recursion) c |
|
|
return resolveString(it->second, recursion); |
|
|
} |
|
|
|
|
|
bool Metadata::getStringToRef( |
|
|
const std::string &name, std::string &str, u16 recursion) const |
|
|
{ |
|
|
StringMap::const_iterator it = m_stringvars.find(name); |
|
|
if (it == m_stringvars.end()) { |
|
|
return false; |
|
|
} |
|
|
|
|
|
str = resolveString(it->second, recursion); |
|
|
return true; |
|
|
} |
|
|
|
|
|
/** |
|
|
* Sets var to name key in the metadata storage |
|
|
* |
|
@@ -88,6 +101,7 @@ bool Metadata::setString(const std::string &name, const std::string &var) |
|
|
} |
|
|
|
|
|
m_stringvars[name] = var; |
|
|
m_modified = true; |
|
|
return true; |
|
|
} |
|
|
|
|
|
|
@@ -26,6 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc., |
|
|
|
|
|
class Metadata |
|
|
{ |
|
|
bool m_modified = false; |
|
|
public: |
|
|
virtual ~Metadata() = default; |
|
|
|
|
@@ -45,14 +46,18 @@ class Metadata |
|
|
size_t size() const; |
|
|
bool contains(const std::string &name) const; |
|
|
const std::string &getString(const std::string &name, u16 recursion = 0) const; |
|
|
bool getStringToRef(const std::string &name, std::string &str, u16 recursion = 0) const; |
|
|
virtual bool setString(const std::string &name, const std::string &var); |
|
|
inline bool removeString(const std::string &name) { return setString(name, ""); } |
|
|
const StringMap &getStrings() const |
|
|
{ |
|
|
return m_stringvars; |
|
|
} |
|
|
// Add support for variable names in values |
|
|
const std::string &resolveString(const std::string &str, u16 recursion = 0) const; |
|
|
|
|
|
inline bool isModified() const { return m_modified; } |
|
|
inline void setModified(bool v) { m_modified = v; } |
|
|
protected: |
|
|
StringMap m_stringvars; |
|
|
|
|
|
}; |
|
@@ -72,14 +72,15 @@ void RemotePlayer::serializeExtraAttributes(std::string &output) |
|
|
{ |
|
|
assert(m_sao); |
|
|
Json::Value json_root; |
|
|
const PlayerAttributes &attrs = m_sao->getExtendedAttributes(); |
|
|
|
|
|
const StringMap &attrs = m_sao->getMeta().getStrings(); |
|
|
for (const auto &attr : attrs) { |
|
|
json_root[attr.first] = attr.second; |
|
|
} |
|
|
|
|
|
output = fastWriteJson(json_root); |
|
|
|
|
|
m_sao->setExtendedAttributeModified(false); |
|
|
m_sao->getMeta().setModified(false); |
|
|
} |
|
|
|
|
|
|
|
@@ -132,8 +133,9 @@ void RemotePlayer::deSerialize(std::istream &is, const std::string &playername, |
|
|
const Json::Value::Members attr_list = attr_root.getMemberNames(); |
|
|
for (const auto &it : attr_list) { |
|
|
Json::Value attr_value = attr_root[it]; |
|
|
sao->setExtendedAttribute(it, attr_value.asString()); |
|
|
sao->getMeta().setString(it, attr_value.asString()); |
|
|
} |
|
|
sao->getMeta().setModified(false); |
|
|
} catch (SettingNotFoundException &e) {} |
|
|
} |
|
|
|
|
|
|
@@ -15,6 +15,7 @@ set(common_SCRIPT_LUA_API_SRCS |
|
|
${CMAKE_CURRENT_SOURCE_DIR}/l_noise.cpp |
|
|
${CMAKE_CURRENT_SOURCE_DIR}/l_object.cpp |
|
|
${CMAKE_CURRENT_SOURCE_DIR}/l_particles.cpp |
|
|
${CMAKE_CURRENT_SOURCE_DIR}/l_playermeta.cpp |
|
|
${CMAKE_CURRENT_SOURCE_DIR}/l_rollback.cpp |
|
|
${CMAKE_CURRENT_SOURCE_DIR}/l_server.cpp |
|
|
${CMAKE_CURRENT_SOURCE_DIR}/l_settings.cpp |
|
|
|
|
@@ -1,6 +1,8 @@ |
|
|
/* |
|
|
Minetest |
|
|
Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com> |
|
|
Copyright (C) 2017-8 rubenwardy <rw@rubenwardy.com> |
|
|
Copyright (C) 2017 raymoo |
|
|
|
|
|
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 |
|
|
|
|
@@ -1,6 +1,8 @@ |
|
|
/* |
|
|
Minetest |
|
|
Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com> |
|
|
Copyright (C) 2017-8 rubenwardy <rw@rubenwardy.com> |
|
|
Copyright (C) 2017 raymoo |
|
|
|
|
|
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 |
|
|
|
|
@@ -1,6 +1,7 @@ |
|
|
/* |
|
|
Minetest |
|
|
Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com> |
|
|
Copyright (C) 2017-8 rubenwardy <rw@rubenwardy.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 |
|
|
Oops, something went wrong.