Drop genericobject.{cpp,h} (#9629)

* Drop genericobject.{cpp,h}

This file is not for generic object but for ActiveObject message passing.
Put ownership of the various commands to the right objects and cleanup the related code.

* Protect ServerActiveObject::m_messages_out

* typo fix
This commit is contained in:
Loïc Blot 2020-04-10 19:49:20 +02:00 committed by GitHub
parent 2349d31bae
commit f648fb76ae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 300 additions and 407 deletions

@ -176,7 +176,6 @@ LOCAL_SRC_FILES := \
jni/src/environment.cpp \ jni/src/environment.cpp \
jni/src/face_position_cache.cpp \ jni/src/face_position_cache.cpp \
jni/src/filesys.cpp \ jni/src/filesys.cpp \
jni/src/genericobject.cpp \
jni/src/gettext.cpp \ jni/src/gettext.cpp \
jni/src/gui/guiAnimatedImage.cpp \ jni/src/gui/guiAnimatedImage.cpp \
jni/src/gui/guiBackgroundImage.cpp \ jni/src/gui/guiBackgroundImage.cpp \

@ -384,7 +384,6 @@ set(common_SRCS
environment.cpp environment.cpp
face_position_cache.cpp face_position_cache.cpp
filesys.cpp filesys.cpp
genericobject.cpp
gettext.cpp gettext.cpp
httpfetch.cpp httpfetch.cpp
hud.cpp hud.cpp

@ -55,6 +55,22 @@ struct ActiveObjectMessage
std::string datastring; std::string datastring;
}; };
enum ActiveObjectCommand {
AO_CMD_SET_PROPERTIES,
AO_CMD_UPDATE_POSITION,
AO_CMD_SET_TEXTURE_MOD,
AO_CMD_SET_SPRITE,
AO_CMD_PUNCHED,
AO_CMD_UPDATE_ARMOR_GROUPS,
AO_CMD_SET_ANIMATION,
AO_CMD_SET_BONE_POSITION,
AO_CMD_ATTACH_TO,
AO_CMD_SET_PHYSICS_OVERRIDE,
AO_CMD_UPDATE_NAMETAG_ATTRIBUTES,
AO_CMD_SPAWN_INFANT,
AO_CMD_SET_ANIMATION_SPEED
};
/* /*
Parent class for ServerActiveObject and ClientActiveObject Parent class for ServerActiveObject and ClientActiveObject
*/ */

@ -450,7 +450,7 @@ void ClientEnvironment::addActiveObject(u16 id, u8 type,
// Object initialized: // Object initialized:
if ((obj = getActiveObject(new_id))) { if ((obj = getActiveObject(new_id))) {
// Final step is to update all children which are already known // Final step is to update all children which are already known
// Data provided by GENERIC_CMD_SPAWN_INFANT // Data provided by AO_CMD_SPAWN_INFANT
const auto &children = obj->getAttachmentChildIds(); const auto &children = obj->getAttachmentChildIds();
for (auto c_id : children) { for (auto c_id : children) {
if (auto *o = getActiveObject(c_id)) if (auto *o = getActiveObject(c_id))

@ -304,7 +304,6 @@ void TestCAO::processMessage(const std::string &data)
GenericCAO GenericCAO
*/ */
#include "genericobject.h"
#include "clientobject.h" #include "clientobject.h"
GenericCAO::GenericCAO(Client *client, ClientEnvironment *env): GenericCAO::GenericCAO(Client *client, ClientEnvironment *env):
@ -1421,14 +1420,23 @@ void GenericCAO::updateAttachments()
} }
} }
void GenericCAO::readAOMessageProperties(std::istream &is)
{
// Reset object properties first
m_prop = ObjectProperties();
// Then read the whole new stream
m_prop.deSerialize(is);
}
void GenericCAO::processMessage(const std::string &data) void GenericCAO::processMessage(const std::string &data)
{ {
//infostream<<"GenericCAO: Got message"<<std::endl; //infostream<<"GenericCAO: Got message"<<std::endl;
std::istringstream is(data, std::ios::binary); std::istringstream is(data, std::ios::binary);
// command // command
u8 cmd = readU8(is); u8 cmd = readU8(is);
if (cmd == GENERIC_CMD_SET_PROPERTIES) { if (cmd == AO_CMD_SET_PROPERTIES) {
m_prop = gob_read_set_properties(is); readAOMessageProperties(is);
m_selection_box = m_prop.selectionbox; m_selection_box = m_prop.selectionbox;
m_selection_box.MinEdge *= BS; m_selection_box.MinEdge *= BS;
@ -1456,7 +1464,7 @@ void GenericCAO::processMessage(const std::string &data)
m_prop.nametag = m_name; m_prop.nametag = m_name;
expireVisuals(); expireVisuals();
} else if (cmd == GENERIC_CMD_UPDATE_POSITION) { } else if (cmd == AO_CMD_UPDATE_POSITION) {
// Not sent by the server if this object is an attachment. // Not sent by the server if this object is an attachment.
// We might however get here if the server notices the object being detached before the client. // We might however get here if the server notices the object being detached before the client.
m_position = readV3F32(is); m_position = readV3F32(is);
@ -1490,7 +1498,7 @@ void GenericCAO::processMessage(const std::string &data)
} }
rot_translator.update(m_rotation, false, update_interval); rot_translator.update(m_rotation, false, update_interval);
updateNodePos(); updateNodePos();
} else if (cmd == GENERIC_CMD_SET_TEXTURE_MOD) { } else if (cmd == AO_CMD_SET_TEXTURE_MOD) {
std::string mod = deSerializeString(is); std::string mod = deSerializeString(is);
// immediatly reset a engine issued texture modifier if a mod sends a different one // immediatly reset a engine issued texture modifier if a mod sends a different one
@ -1499,7 +1507,7 @@ void GenericCAO::processMessage(const std::string &data)
updateTextures(m_previous_texture_modifier); updateTextures(m_previous_texture_modifier);
} }
updateTextures(mod); updateTextures(mod);
} else if (cmd == GENERIC_CMD_SET_SPRITE) { } else if (cmd == AO_CMD_SET_SPRITE) {
v2s16 p = readV2S16(is); v2s16 p = readV2S16(is);
int num_frames = readU16(is); int num_frames = readU16(is);
float framelength = readF32(is); float framelength = readF32(is);
@ -1511,7 +1519,7 @@ void GenericCAO::processMessage(const std::string &data)
m_tx_select_horiz_by_yawpitch = select_horiz_by_yawpitch; m_tx_select_horiz_by_yawpitch = select_horiz_by_yawpitch;
updateTexturePos(); updateTexturePos();
} else if (cmd == GENERIC_CMD_SET_PHYSICS_OVERRIDE) { } else if (cmd == AO_CMD_SET_PHYSICS_OVERRIDE) {
float override_speed = readF32(is); float override_speed = readF32(is);
float override_jump = readF32(is); float override_jump = readF32(is);
float override_gravity = readF32(is); float override_gravity = readF32(is);
@ -1531,7 +1539,7 @@ void GenericCAO::processMessage(const std::string &data)
player->physics_override_sneak_glitch = sneak_glitch; player->physics_override_sneak_glitch = sneak_glitch;
player->physics_override_new_move = new_move; player->physics_override_new_move = new_move;
} }
} else if (cmd == GENERIC_CMD_SET_ANIMATION) { } else if (cmd == AO_CMD_SET_ANIMATION) {
// TODO: change frames send as v2s32 value // TODO: change frames send as v2s32 value
v2f range = readV2F32(is); v2f range = readV2F32(is);
if (!m_is_local_player) { if (!m_is_local_player) {
@ -1565,17 +1573,17 @@ void GenericCAO::processMessage(const std::string &data)
updateAnimation(); updateAnimation();
} }
} }
} else if (cmd == GENERIC_CMD_SET_ANIMATION_SPEED) { } else if (cmd == AO_CMD_SET_ANIMATION_SPEED) {
m_animation_speed = readF32(is); m_animation_speed = readF32(is);
updateAnimationSpeed(); updateAnimationSpeed();
} else if (cmd == GENERIC_CMD_SET_BONE_POSITION) { } else if (cmd == AO_CMD_SET_BONE_POSITION) {
std::string bone = deSerializeString(is); std::string bone = deSerializeString(is);
v3f position = readV3F32(is); v3f position = readV3F32(is);
v3f rotation = readV3F32(is); v3f rotation = readV3F32(is);
m_bone_position[bone] = core::vector2d<v3f>(position, rotation); m_bone_position[bone] = core::vector2d<v3f>(position, rotation);
updateBonePosition(); updateBonePosition();
} else if (cmd == GENERIC_CMD_ATTACH_TO) { } else if (cmd == AO_CMD_ATTACH_TO) {
u16 parent_id = readS16(is); u16 parent_id = readS16(is);
std::string bone = deSerializeString(is); std::string bone = deSerializeString(is);
v3f position = readV3F32(is); v3f position = readV3F32(is);
@ -1586,7 +1594,7 @@ void GenericCAO::processMessage(const std::string &data)
// localplayer itself can't be attached to localplayer // localplayer itself can't be attached to localplayer
if (!m_is_local_player) if (!m_is_local_player)
m_is_visible = !m_attached_to_local; m_is_visible = !m_attached_to_local;
} else if (cmd == GENERIC_CMD_PUNCHED) { } else if (cmd == AO_CMD_PUNCHED) {
u16 result_hp = readU16(is); u16 result_hp = readU16(is);
// Use this instead of the send damage to not interfere with prediction // Use this instead of the send damage to not interfere with prediction
@ -1624,7 +1632,7 @@ void GenericCAO::processMessage(const std::string &data)
if (!m_is_player) if (!m_is_player)
clearChildAttachments(); clearChildAttachments();
} }
} else if (cmd == GENERIC_CMD_UPDATE_ARMOR_GROUPS) { } else if (cmd == AO_CMD_UPDATE_ARMOR_GROUPS) {
m_armor_groups.clear(); m_armor_groups.clear();
int armor_groups_size = readU16(is); int armor_groups_size = readU16(is);
for(int i=0; i<armor_groups_size; i++) for(int i=0; i<armor_groups_size; i++)
@ -1633,7 +1641,7 @@ void GenericCAO::processMessage(const std::string &data)
int rating = readS16(is); int rating = readS16(is);
m_armor_groups[name] = rating; m_armor_groups[name] = rating;
} }
} else if (cmd == GENERIC_CMD_UPDATE_NAMETAG_ATTRIBUTES) { } else if (cmd == AO_CMD_UPDATE_NAMETAG_ATTRIBUTES) {
// Deprecated, for backwards compatibility only. // Deprecated, for backwards compatibility only.
readU8(is); // version readU8(is); // version
m_prop.nametag_color = readARGB8(is); m_prop.nametag_color = readARGB8(is);
@ -1643,7 +1651,7 @@ void GenericCAO::processMessage(const std::string &data)
pos.Y = m_prop.collisionbox.MaxEdge.Y + 0.3f; pos.Y = m_prop.collisionbox.MaxEdge.Y + 0.3f;
m_nametag->nametag_pos = pos; m_nametag->nametag_pos = pos;
} }
} else if (cmd == GENERIC_CMD_SPAWN_INFANT) { } else if (cmd == AO_CMD_SPAWN_INFANT) {
u16 child_id = readU16(is); u16 child_id = readU16(is);
u8 type = readU8(is); // maybe this will be useful later u8 type = readU8(is); // maybe this will be useful later
(void)type; (void)type;

@ -68,6 +68,7 @@ struct SmoothTranslatorWrappedv3f : SmoothTranslator<v3f>
class GenericCAO : public ClientActiveObject class GenericCAO : public ClientActiveObject
{ {
private: private:
void readAOMessageProperties(std::istream &is);
// Only set at initialization // Only set at initialization
std::string m_name = ""; std::string m_name = "";
bool m_is_player = false; bool m_is_player = false;

@ -27,7 +27,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "remoteplayer.h" #include "remoteplayer.h"
#include "server.h" #include "server.h"
#include "scripting_server.h" #include "scripting_server.h"
#include "genericobject.h"
#include "settings.h" #include "settings.h"
#include <algorithm> #include <algorithm>
#include <cmath> #include <cmath>
@ -289,6 +288,120 @@ void UnitSAO::notifyObjectPropertiesModified()
m_properties_sent = false; m_properties_sent = false;
} }
std::string UnitSAO::generateUpdateAttachmentCommand() const
{
std::ostringstream os(std::ios::binary);
// command
writeU8(os, AO_CMD_ATTACH_TO);
// parameters
writeS16(os, m_attachment_parent_id);
os << serializeString(m_attachment_bone);
writeV3F32(os, m_attachment_position);
writeV3F32(os, m_attachment_rotation);
return os.str();
}
std::string UnitSAO::generateUpdateBonePositionCommand(const std::string &bone,
const v3f &position, const v3f &rotation)
{
std::ostringstream os(std::ios::binary);
// command
writeU8(os, AO_CMD_SET_BONE_POSITION);
// parameters
os << serializeString(bone);
writeV3F32(os, position);
writeV3F32(os, rotation);
return os.str();
}
std::string UnitSAO::generateUpdateAnimationSpeedCommand() const
{
std::ostringstream os(std::ios::binary);
// command
writeU8(os, AO_CMD_SET_ANIMATION_SPEED);
// parameters
writeF32(os, m_animation_speed);
return os.str();
}
std::string UnitSAO::generateUpdateAnimationCommand() const
{
std::ostringstream os(std::ios::binary);
// command
writeU8(os, AO_CMD_SET_ANIMATION);
// parameters
writeV2F32(os, m_animation_range);
writeF32(os, m_animation_speed);
writeF32(os, m_animation_blend);
// these are sent inverted so we get true when the server sends nothing
writeU8(os, !m_animation_loop);
return os.str();
}
std::string UnitSAO::generateUpdateArmorGroupsCommand() const
{
std::ostringstream os(std::ios::binary);
writeU8(os, AO_CMD_UPDATE_ARMOR_GROUPS);
writeU16(os, m_armor_groups.size());
for (const auto &armor_group : m_armor_groups) {
os<<serializeString(armor_group.first);
writeS16(os, armor_group.second);
}
return os.str();
}
std::string UnitSAO::generateUpdatePositionCommand(const v3f &position, const v3f &velocity,
const v3f &acceleration, const v3f &rotation, bool do_interpolate, bool is_movement_end,
f32 update_interval)
{
std::ostringstream os(std::ios::binary);
// command
writeU8(os, AO_CMD_UPDATE_POSITION);
// pos
writeV3F32(os, position);
// velocity
writeV3F32(os, velocity);
// acceleration
writeV3F32(os, acceleration);
// rotation
writeV3F32(os, rotation);
// do_interpolate
writeU8(os, do_interpolate);
// is_end_position (for interpolation)
writeU8(os, is_movement_end);
// update_interval (for interpolation)
writeF32(os, update_interval);
return os.str();
}
std::string UnitSAO::generateSetPropertiesCommand(const ObjectProperties &prop) const
{
std::ostringstream os(std::ios::binary);
writeU8(os, AO_CMD_SET_PROPERTIES);
prop.serialize(os);
return os.str();
}
std::string UnitSAO::generatePunchCommand(u16 result_hp) const
{
std::ostringstream os(std::ios::binary);
// command
writeU8(os, AO_CMD_PUNCHED);
// result_hp
writeU16(os, result_hp);
return os.str();
}
void UnitSAO::sendPunchCommand()
{
m_messages_out.emplace(getId(), true, generatePunchCommand(getHP()));
}
/* /*
LuaEntitySAO LuaEntitySAO
*/ */
@ -500,17 +613,13 @@ void LuaEntitySAO::step(float dtime, bool send_recommended)
if (!m_armor_groups_sent) { if (!m_armor_groups_sent) {
m_armor_groups_sent = true; m_armor_groups_sent = true;
std::string str = gob_cmd_update_armor_groups(
m_armor_groups);
// create message and add to list // create message and add to list
ActiveObjectMessage aom(getId(), true, str); m_messages_out.emplace(getId(), true, generateUpdateArmorGroupsCommand());
m_messages_out.push(aom);
} }
if (!m_animation_sent) { if (!m_animation_sent) {
m_animation_sent = true; m_animation_sent = true;
std::string str = gob_cmd_update_animation( std::string str = generateUpdateAnimationCommand();
m_animation_range, m_animation_speed, m_animation_blend, m_animation_loop);
// create message and add to list // create message and add to list
ActiveObjectMessage aom(getId(), true, str); ActiveObjectMessage aom(getId(), true, str);
m_messages_out.push(aom); m_messages_out.push(aom);
@ -518,7 +627,7 @@ void LuaEntitySAO::step(float dtime, bool send_recommended)
if (!m_animation_speed_sent) { if (!m_animation_speed_sent) {
m_animation_speed_sent = true; m_animation_speed_sent = true;
std::string str = gob_cmd_update_animation_speed(m_animation_speed); std::string str = generateUpdateAnimationSpeedCommand();
// create message and add to list // create message and add to list
ActiveObjectMessage aom(getId(), true, str); ActiveObjectMessage aom(getId(), true, str);
m_messages_out.push(aom); m_messages_out.push(aom);
@ -528,7 +637,7 @@ void LuaEntitySAO::step(float dtime, bool send_recommended)
m_bone_position_sent = true; m_bone_position_sent = true;
for (std::unordered_map<std::string, core::vector2d<v3f>>::const_iterator for (std::unordered_map<std::string, core::vector2d<v3f>>::const_iterator
ii = m_bone_position.begin(); ii != m_bone_position.end(); ++ii){ ii = m_bone_position.begin(); ii != m_bone_position.end(); ++ii){
std::string str = gob_cmd_update_bone_position((*ii).first, std::string str = generateUpdateBonePositionCommand((*ii).first,
(*ii).second.X, (*ii).second.Y); (*ii).second.X, (*ii).second.Y);
// create message and add to list // create message and add to list
ActiveObjectMessage aom(getId(), true, str); ActiveObjectMessage aom(getId(), true, str);
@ -538,7 +647,7 @@ void LuaEntitySAO::step(float dtime, bool send_recommended)
if (!m_attachment_sent) { if (!m_attachment_sent) {
m_attachment_sent = true; m_attachment_sent = true;
std::string str = gob_cmd_update_attachment(m_attachment_parent_id, m_attachment_bone, m_attachment_position, m_attachment_rotation); std::string str = generateUpdateAttachmentCommand();
// create message and add to list // create message and add to list
ActiveObjectMessage aom(getId(), true, str); ActiveObjectMessage aom(getId(), true, str);
m_messages_out.push(aom); m_messages_out.push(aom);
@ -560,16 +669,14 @@ std::string LuaEntitySAO::getClientInitializationData(u16 protocol_version)
std::ostringstream msg_os(std::ios::binary); std::ostringstream msg_os(std::ios::binary);
msg_os << serializeLongString(getPropertyPacket()); // message 1 msg_os << serializeLongString(getPropertyPacket()); // message 1
msg_os << serializeLongString(gob_cmd_update_armor_groups(m_armor_groups)); // 2 msg_os << serializeLongString(generateUpdateArmorGroupsCommand()); // 2
msg_os << serializeLongString(gob_cmd_update_animation( msg_os << serializeLongString(generateUpdateAnimationCommand()); // 3
m_animation_range, m_animation_speed, m_animation_blend, m_animation_loop)); // 3
for (std::unordered_map<std::string, core::vector2d<v3f>>::const_iterator for (std::unordered_map<std::string, core::vector2d<v3f>>::const_iterator
ii = m_bone_position.begin(); ii != m_bone_position.end(); ++ii) { ii = m_bone_position.begin(); ii != m_bone_position.end(); ++ii) {
msg_os << serializeLongString(gob_cmd_update_bone_position((*ii).first, msg_os << serializeLongString(generateUpdateBonePositionCommand((*ii).first,
(*ii).second.X, (*ii).second.Y)); // m_bone_position.size (*ii).second.X, (*ii).second.Y)); // m_bone_position.size
} }
msg_os << serializeLongString(gob_cmd_update_attachment(m_attachment_parent_id, msg_os << serializeLongString(generateUpdateAttachmentCommand()); // 4
m_attachment_bone, m_attachment_position, m_attachment_rotation)); // 4
int message_count = 4 + m_bone_position.size(); int message_count = 4 + m_bone_position.size();
for (std::unordered_set<int>::const_iterator ii = m_attachment_child_ids.begin(); for (std::unordered_set<int>::const_iterator ii = m_attachment_child_ids.begin();
(ii != m_attachment_child_ids.end()); ++ii) { (ii != m_attachment_child_ids.end()); ++ii) {
@ -577,12 +684,11 @@ std::string LuaEntitySAO::getClientInitializationData(u16 protocol_version)
message_count++; message_count++;
// TODO after a protocol bump: only send the object initialization data // TODO after a protocol bump: only send the object initialization data
// to older clients (superfluous since this message exists) // to older clients (superfluous since this message exists)
msg_os << serializeLongString(gob_cmd_update_infant(*ii, obj->getSendType(), msg_os << serializeLongString(obj->generateUpdateInfantCommand(*ii, protocol_version));
obj->getClientInitializationData(protocol_version)));
} }
} }
msg_os << serializeLongString(gob_cmd_set_texture_mod(m_current_texture_modifier)); msg_os << serializeLongString(generateSetTextureModCommand());
message_count++; message_count++;
writeU8(os, message_count); writeU8(os, message_count);
@ -655,10 +761,8 @@ u16 LuaEntitySAO::punch(v3f dir,
setHP((s32)getHP() - result.damage, setHP((s32)getHP() - result.damage,
PlayerHPChangeReason(PlayerHPChangeReason::PLAYER_PUNCH, puncher)); PlayerHPChangeReason(PlayerHPChangeReason::PLAYER_PUNCH, puncher));
std::string str = gob_cmd_punched(getHP());
// create message and add to list // create message and add to list
ActiveObjectMessage aom(getId(), true, str); sendPunchCommand();
m_messages_out.push(aom);
} }
} }
@ -750,11 +854,9 @@ v3f LuaEntitySAO::getAcceleration()
void LuaEntitySAO::setTextureMod(const std::string &mod) void LuaEntitySAO::setTextureMod(const std::string &mod)
{ {
std::string str = gob_cmd_set_texture_mod(mod);
m_current_texture_modifier = mod; m_current_texture_modifier = mod;
// create message and add to list // create message and add to list
ActiveObjectMessage aom(getId(), true, str); m_messages_out.emplace(getId(), true, generateSetTextureModCommand());
m_messages_out.push(aom);
} }
std::string LuaEntitySAO::getTextureMod() const std::string LuaEntitySAO::getTextureMod() const
@ -762,18 +864,42 @@ std::string LuaEntitySAO::getTextureMod() const
return m_current_texture_modifier; return m_current_texture_modifier;
} }
std::string LuaEntitySAO::generateSetTextureModCommand() const
{
std::ostringstream os(std::ios::binary);
// command
writeU8(os, AO_CMD_SET_TEXTURE_MOD);
// parameters
os << serializeString(m_current_texture_modifier);
return os.str();
}
std::string LuaEntitySAO::generateSetSpriteCommand(v2s16 p, u16 num_frames,
f32 framelength, bool select_horiz_by_yawpitch)
{
std::ostringstream os(std::ios::binary);
// command
writeU8(os, AO_CMD_SET_SPRITE);
// parameters
writeV2S16(os, p);
writeU16(os, num_frames);
writeF32(os, framelength);
writeU8(os, select_horiz_by_yawpitch);
return os.str();
}
void LuaEntitySAO::setSprite(v2s16 p, int num_frames, float framelength, void LuaEntitySAO::setSprite(v2s16 p, int num_frames, float framelength,
bool select_horiz_by_yawpitch) bool select_horiz_by_yawpitch)
{ {
std::string str = gob_cmd_set_sprite( std::string str = generateSetSpriteCommand(
p, p,
num_frames, num_frames,
framelength, framelength,
select_horiz_by_yawpitch select_horiz_by_yawpitch
); );
// create message and add to list // create message and add to list
ActiveObjectMessage aom(getId(), true, str); m_messages_out.emplace(getId(), true, str);
m_messages_out.push(aom);
} }
std::string LuaEntitySAO::getName() std::string LuaEntitySAO::getName()
@ -783,7 +909,7 @@ std::string LuaEntitySAO::getName()
std::string LuaEntitySAO::getPropertyPacket() std::string LuaEntitySAO::getPropertyPacket()
{ {
return gob_cmd_set_properties(m_prop); return generateSetPropertiesCommand(m_prop);
} }
void LuaEntitySAO::sendPosition(bool do_interpolate, bool is_movement_end) void LuaEntitySAO::sendPosition(bool do_interpolate, bool is_movement_end)
@ -802,7 +928,7 @@ void LuaEntitySAO::sendPosition(bool do_interpolate, bool is_movement_end)
float update_interval = m_env->getSendRecommendedInterval(); float update_interval = m_env->getSendRecommendedInterval();
std::string str = gob_cmd_update_position( std::string str = generateUpdatePositionCommand(
m_base_position, m_base_position,
m_velocity, m_velocity,
m_acceleration, m_acceleration,
@ -812,8 +938,7 @@ void LuaEntitySAO::sendPosition(bool do_interpolate, bool is_movement_end)
update_interval update_interval
); );
// create message and add to list // create message and add to list
ActiveObjectMessage aom(getId(), false, str); m_messages_out.emplace(getId(), false, str);
m_messages_out.push(aom);
} }
bool LuaEntitySAO::getCollisionBox(aabb3f *toset) const bool LuaEntitySAO::getCollisionBox(aabb3f *toset) const
@ -949,28 +1074,23 @@ std::string PlayerSAO::getClientInitializationData(u16 protocol_version)
std::ostringstream msg_os(std::ios::binary); std::ostringstream msg_os(std::ios::binary);
msg_os << serializeLongString(getPropertyPacket()); // message 1 msg_os << serializeLongString(getPropertyPacket()); // message 1
msg_os << serializeLongString(gob_cmd_update_armor_groups(m_armor_groups)); // 2 msg_os << serializeLongString(generateUpdateArmorGroupsCommand()); // 2
msg_os << serializeLongString(gob_cmd_update_animation( msg_os << serializeLongString(generateUpdateAnimationCommand()); // 3
m_animation_range, m_animation_speed, m_animation_blend, m_animation_loop)); // 3
for (std::unordered_map<std::string, core::vector2d<v3f>>::const_iterator for (std::unordered_map<std::string, core::vector2d<v3f>>::const_iterator
ii = m_bone_position.begin(); ii != m_bone_position.end(); ++ii) { ii = m_bone_position.begin(); ii != m_bone_position.end(); ++ii) {
msg_os << serializeLongString(gob_cmd_update_bone_position((*ii).first, msg_os << serializeLongString(generateUpdateBonePositionCommand((*ii).first,
(*ii).second.X, (*ii).second.Y)); // m_bone_position.size (*ii).second.X, (*ii).second.Y)); // m_bone_position.size
} }
msg_os << serializeLongString(gob_cmd_update_attachment(m_attachment_parent_id, msg_os << serializeLongString(generateUpdateAttachmentCommand()); // 4
m_attachment_bone, m_attachment_position, m_attachment_rotation)); // 4 msg_os << serializeLongString(generateUpdatePhysicsOverrideCommand()); // 5
msg_os << serializeLongString(gob_cmd_update_physics_override(m_physics_override_speed, // (AO_CMD_UPDATE_NAMETAG_ATTRIBUTES) : Deprecated, for backwards compatibility only.
m_physics_override_jump, m_physics_override_gravity, m_physics_override_sneak, msg_os << serializeLongString(generateUpdateNametagAttributesCommand(m_prop.nametag_color)); // 6
m_physics_override_sneak_glitch, m_physics_override_new_move)); // 5
// (GENERIC_CMD_UPDATE_NAMETAG_ATTRIBUTES) : Deprecated, for backwards compatibility only.
msg_os << serializeLongString(gob_cmd_update_nametag_attributes(m_prop.nametag_color)); // 6
int message_count = 6 + m_bone_position.size(); int message_count = 6 + m_bone_position.size();
for (std::unordered_set<int>::const_iterator ii = m_attachment_child_ids.begin(); for (std::unordered_set<int>::const_iterator ii = m_attachment_child_ids.begin();
ii != m_attachment_child_ids.end(); ++ii) { ii != m_attachment_child_ids.end(); ++ii) {
if (ServerActiveObject *obj = m_env->getActiveObject(*ii)) { if (ServerActiveObject *obj = m_env->getActiveObject(*ii)) {
message_count++; message_count++;
msg_os << serializeLongString(gob_cmd_update_infant(*ii, obj->getSendType(), msg_os << serializeLongString(obj->generateUpdateInfantCommand(*ii, protocol_version));
obj->getClientInitializationData(protocol_version)));
} }
} }
@ -1116,7 +1236,7 @@ void PlayerSAO::step(float dtime, bool send_recommended)
else else
pos = m_base_position; pos = m_base_position;
std::string str = gob_cmd_update_position( std::string str = generateUpdatePositionCommand(
pos, pos,
v3f(0.0f, 0.0f, 0.0f), v3f(0.0f, 0.0f, 0.0f),
v3f(0.0f, 0.0f, 0.0f), v3f(0.0f, 0.0f, 0.0f),
@ -1126,61 +1246,63 @@ void PlayerSAO::step(float dtime, bool send_recommended)
update_interval update_interval
); );
// create message and add to list // create message and add to list
ActiveObjectMessage aom(getId(), false, str); m_messages_out.emplace(getId(), false, str);
m_messages_out.push(aom);
} }
if (!m_armor_groups_sent) { if (!m_armor_groups_sent) {
m_armor_groups_sent = true; m_armor_groups_sent = true;
std::string str = gob_cmd_update_armor_groups(
m_armor_groups);
// create message and add to list // create message and add to list
ActiveObjectMessage aom(getId(), true, str); m_messages_out.emplace(getId(), true, generateUpdateArmorGroupsCommand());
m_messages_out.push(aom);
} }
if (!m_physics_override_sent) { if (!m_physics_override_sent) {
m_physics_override_sent = true; m_physics_override_sent = true;
std::string str = gob_cmd_update_physics_override(m_physics_override_speed,
m_physics_override_jump, m_physics_override_gravity,
m_physics_override_sneak, m_physics_override_sneak_glitch,
m_physics_override_new_move);
// create message and add to list // create message and add to list
ActiveObjectMessage aom(getId(), true, str); m_messages_out.emplace(getId(), true, generateUpdatePhysicsOverrideCommand());
m_messages_out.push(aom);
} }
if (!m_animation_sent) { if (!m_animation_sent) {
m_animation_sent = true; m_animation_sent = true;
std::string str = gob_cmd_update_animation(
m_animation_range, m_animation_speed, m_animation_blend, m_animation_loop);
// create message and add to list // create message and add to list
ActiveObjectMessage aom(getId(), true, str); m_messages_out.emplace(getId(), true, generateUpdateAnimationCommand());
m_messages_out.push(aom);
} }
if (!m_bone_position_sent) { if (!m_bone_position_sent) {
m_bone_position_sent = true; m_bone_position_sent = true;
for (std::unordered_map<std::string, core::vector2d<v3f>>::const_iterator for (std::unordered_map<std::string, core::vector2d<v3f>>::const_iterator
ii = m_bone_position.begin(); ii != m_bone_position.end(); ++ii) { ii = m_bone_position.begin(); ii != m_bone_position.end(); ++ii) {
std::string str = gob_cmd_update_bone_position((*ii).first, std::string str = generateUpdateBonePositionCommand((*ii).first,
(*ii).second.X, (*ii).second.Y); (*ii).second.X, (*ii).second.Y);
// create message and add to list // create message and add to list
ActiveObjectMessage aom(getId(), true, str); m_messages_out.emplace(getId(), true, str);
m_messages_out.push(aom);
} }
} }
if (!m_attachment_sent) { if (!m_attachment_sent) {
m_attachment_sent = true; m_attachment_sent = true;
std::string str = gob_cmd_update_attachment(m_attachment_parent_id, std::string str = generateUpdateAttachmentCommand();
m_attachment_bone, m_attachment_position, m_attachment_rotation);
// create message and add to list // create message and add to list
ActiveObjectMessage aom(getId(), true, str); ActiveObjectMessage aom(getId(), true, str);
m_messages_out.push(aom); m_messages_out.push(aom);
} }
} }
std::string PlayerSAO::generateUpdatePhysicsOverrideCommand() const
{
std::ostringstream os(std::ios::binary);
// command
writeU8(os, AO_CMD_SET_PHYSICS_OVERRIDE);
// parameters
writeF32(os, m_physics_override_speed);
writeF32(os, m_physics_override_jump);
writeF32(os, m_physics_override_gravity);
// these are sent inverted so we get true when the server sends nothing
writeU8(os, !m_physics_override_sneak);
writeU8(os, !m_physics_override_sneak_glitch);
writeU8(os, !m_physics_override_new_move);
return os.str();
}
void PlayerSAO::setBasePosition(const v3f &position) void PlayerSAO::setBasePosition(const v3f &position)
{ {
if (m_player && position != m_base_position) if (m_player && position != m_base_position)
@ -1284,10 +1406,8 @@ u16 PlayerSAO::punch(v3f dir,
// No effect if PvP disabled or if immortal // No effect if PvP disabled or if immortal
if (isImmortal() || !g_settings->getBool("enable_pvp")) { if (isImmortal() || !g_settings->getBool("enable_pvp")) {
if (puncher->getType() == ACTIVEOBJECT_TYPE_PLAYER) { if (puncher->getType() == ACTIVEOBJECT_TYPE_PLAYER) {
std::string str = gob_cmd_punched(getHP());
// create message and add to list // create message and add to list
ActiveObjectMessage aom(getId(), true, str); sendPunchCommand();
m_messages_out.push(aom);
return 0; return 0;
} }
} }
@ -1307,10 +1427,8 @@ u16 PlayerSAO::punch(v3f dir,
PlayerHPChangeReason(PlayerHPChangeReason::PLAYER_PUNCH, puncher)); PlayerHPChangeReason(PlayerHPChangeReason::PLAYER_PUNCH, puncher));
} else { // override client prediction } else { // override client prediction
if (puncher->getType() == ACTIVEOBJECT_TYPE_PLAYER) { if (puncher->getType() == ACTIVEOBJECT_TYPE_PLAYER) {
std::string str = gob_cmd_punched(getHP());
// create message and add to list // create message and add to list
ActiveObjectMessage aom(getId(), true, str); sendPunchCommand();
m_messages_out.push(aom);
} }
} }
@ -1408,7 +1526,7 @@ void PlayerSAO::unlinkPlayerSessionAndSave()
std::string PlayerSAO::getPropertyPacket() std::string PlayerSAO::getPropertyPacket()
{ {
m_prop.is_visible = (true); m_prop.is_visible = (true);
return gob_cmd_set_properties(m_prop); return generateSetPropertiesCommand(m_prop);
} }
void PlayerSAO::setMaxSpeedOverride(const v3f &vel) void PlayerSAO::setMaxSpeedOverride(const v3f &vel)

@ -67,6 +67,19 @@ public:
ServerActiveObject *getParent() const; ServerActiveObject *getParent() const;
ObjectProperties* accessObjectProperties(); ObjectProperties* accessObjectProperties();
void notifyObjectPropertiesModified(); void notifyObjectPropertiesModified();
std::string generateUpdateAttachmentCommand() const;
std::string generateUpdateAnimationSpeedCommand() const;
std::string generateUpdateAnimationCommand() const;
std::string generateUpdateArmorGroupsCommand() const;
static std::string generateUpdatePositionCommand(const v3f &position, const v3f &velocity,
const v3f &acceleration, const v3f &rotation, bool do_interpolate,
bool is_movement_end, f32 update_interval);
std::string generateSetPropertiesCommand(const ObjectProperties &prop) const;
void sendPunchCommand();
static std::string generateUpdateBonePositionCommand(const std::string &bone,
const v3f &position, const v3f &rotation);
protected: protected:
u16 m_hp = 1; u16 m_hp = 1;
@ -98,6 +111,8 @@ protected:
private: private:
void onAttach(int parent_id); void onAttach(int parent_id);
void onDetach(int parent_id); void onDetach(int parent_id);
std::string generatePunchCommand(u16 result_hp) const;
}; };
/* /*
@ -155,6 +170,9 @@ public:
private: private:
std::string getPropertyPacket(); std::string getPropertyPacket();
void sendPosition(bool do_interpolate, bool is_movement_end); void sendPosition(bool do_interpolate, bool is_movement_end);
std::string generateSetTextureModCommand() const;
static std::string generateSetSpriteCommand(v2s16 p, u16 num_frames, f32 framelength,
bool select_horiz_by_yawpitch);
std::string m_init_name; std::string m_init_name;
std::string m_init_state; std::string m_init_state;
@ -350,6 +368,7 @@ public:
private: private:
std::string getPropertyPacket(); std::string getPropertyPacket();
void unlinkPlayerSessionAndSave(); void unlinkPlayerSessionAndSave();
std::string generateUpdatePhysicsOverrideCommand() const;
RemotePlayer *m_player = nullptr; RemotePlayer *m_player = nullptr;
session_t m_peer_id = 0; session_t m_peer_id = 0;

@ -1,207 +0,0 @@
/*
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 "genericobject.h"
#include <sstream>
#include "util/serialize.h"
std::string gob_cmd_set_properties(const ObjectProperties &prop)
{
std::ostringstream os(std::ios::binary);
writeU8(os, GENERIC_CMD_SET_PROPERTIES);
prop.serialize(os);
return os.str();
}
ObjectProperties gob_read_set_properties(std::istream &is)
{
ObjectProperties prop;
prop.deSerialize(is);
return prop;
}
std::string gob_cmd_update_position(
v3f position,
v3f velocity,
v3f acceleration,
v3f rotation,
bool do_interpolate,
bool is_movement_end,
f32 update_interval
){
std::ostringstream os(std::ios::binary);
// command
writeU8(os, GENERIC_CMD_UPDATE_POSITION);
// pos
writeV3F32(os, position);
// velocity
writeV3F32(os, velocity);
// acceleration
writeV3F32(os, acceleration);
// rotation
writeV3F32(os, rotation);
// do_interpolate
writeU8(os, do_interpolate);
// is_end_position (for interpolation)
writeU8(os, is_movement_end);
// update_interval (for interpolation)
writeF32(os, update_interval);
return os.str();
}
std::string gob_cmd_set_texture_mod(const std::string &mod)
{
std::ostringstream os(std::ios::binary);
// command
writeU8(os, GENERIC_CMD_SET_TEXTURE_MOD);
// parameters
os<<serializeString(mod);
return os.str();
}
std::string gob_cmd_set_sprite(
v2s16 p,
u16 num_frames,
f32 framelength,
bool select_horiz_by_yawpitch
){
std::ostringstream os(std::ios::binary);
// command
writeU8(os, GENERIC_CMD_SET_SPRITE);
// parameters
writeV2S16(os, p);
writeU16(os, num_frames);
writeF32(os, framelength);
writeU8(os, select_horiz_by_yawpitch);
return os.str();
}
std::string gob_cmd_punched(u16 result_hp)
{
std::ostringstream os(std::ios::binary);
// command
writeU8(os, GENERIC_CMD_PUNCHED);
// result_hp
writeU16(os, result_hp);
return os.str();
}
std::string gob_cmd_update_armor_groups(const ItemGroupList &armor_groups)
{
std::ostringstream os(std::ios::binary);
writeU8(os, GENERIC_CMD_UPDATE_ARMOR_GROUPS);
writeU16(os, armor_groups.size());
for (const auto &armor_group : armor_groups) {
os<<serializeString(armor_group.first);
writeS16(os, armor_group.second);
}
return os.str();
}
std::string gob_cmd_update_physics_override(float physics_override_speed, float physics_override_jump,
float physics_override_gravity, bool sneak, bool sneak_glitch, bool new_move)
{
std::ostringstream os(std::ios::binary);
// command
writeU8(os, GENERIC_CMD_SET_PHYSICS_OVERRIDE);
// parameters
writeF32(os, physics_override_speed);
writeF32(os, physics_override_jump);
writeF32(os, physics_override_gravity);
// these are sent inverted so we get true when the server sends nothing
writeU8(os, !sneak);
writeU8(os, !sneak_glitch);
writeU8(os, !new_move);
return os.str();
}
std::string gob_cmd_update_animation(v2f frames, float frame_speed, float frame_blend, bool frame_loop)
{
std::ostringstream os(std::ios::binary);
// command
writeU8(os, GENERIC_CMD_SET_ANIMATION);
// parameters
writeV2F32(os, frames);
writeF32(os, frame_speed);
writeF32(os, frame_blend);
// these are sent inverted so we get true when the server sends nothing
writeU8(os, !frame_loop);
return os.str();
}
std::string gob_cmd_update_animation_speed(float frame_speed)
{
std::ostringstream os(std::ios::binary);
// command
writeU8(os, GENERIC_CMD_SET_ANIMATION_SPEED);
// parameters
writeF32(os, frame_speed);
return os.str();
}
std::string gob_cmd_update_bone_position(const std::string &bone, v3f position,
v3f rotation)
{
std::ostringstream os(std::ios::binary);
// command
writeU8(os, GENERIC_CMD_SET_BONE_POSITION);
// parameters
os<<serializeString(bone);
writeV3F32(os, position);
writeV3F32(os, rotation);
return os.str();
}
std::string gob_cmd_update_attachment(int parent_id, const std::string &bone,
v3f position, v3f rotation)
{
std::ostringstream os(std::ios::binary);
// command
writeU8(os, GENERIC_CMD_ATTACH_TO);
// parameters
writeS16(os, parent_id);
os<<serializeString(bone);
writeV3F32(os, position);
writeV3F32(os, rotation);
return os.str();
}
std::string gob_cmd_update_nametag_attributes(video::SColor color)
{
std::ostringstream os(std::ios::binary);
// command
writeU8(os, GENERIC_CMD_UPDATE_NAMETAG_ATTRIBUTES);
// parameters
writeU8(os, 1); // version for forward compatibility
writeARGB8(os, color);
return os.str();
}
std::string gob_cmd_update_infant(u16 id, u8 type,
const std::string &client_initialization_data)
{
std::ostringstream os(std::ios::binary);
// command
writeU8(os, GENERIC_CMD_SPAWN_INFANT);
// parameters
writeU16(os, id);
writeU8(os, type);
os<<serializeLongString(client_initialization_data);
return os.str();
}

@ -1,87 +0,0 @@
/*
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.
*/
#pragma once
#include <string>
#include "irrlichttypes_bloated.h"
#include <iostream>
#include "itemgroup.h"
enum GenericCMD {
GENERIC_CMD_SET_PROPERTIES,
GENERIC_CMD_UPDATE_POSITION,
GENERIC_CMD_SET_TEXTURE_MOD,
GENERIC_CMD_SET_SPRITE,
GENERIC_CMD_PUNCHED,
GENERIC_CMD_UPDATE_ARMOR_GROUPS,
GENERIC_CMD_SET_ANIMATION,
GENERIC_CMD_SET_BONE_POSITION,
GENERIC_CMD_ATTACH_TO,
GENERIC_CMD_SET_PHYSICS_OVERRIDE,
GENERIC_CMD_UPDATE_NAMETAG_ATTRIBUTES,
GENERIC_CMD_SPAWN_INFANT,
GENERIC_CMD_SET_ANIMATION_SPEED
};
#include "object_properties.h"
std::string gob_cmd_set_properties(const ObjectProperties &prop);
ObjectProperties gob_read_set_properties(std::istream &is);
std::string gob_cmd_update_position(
v3f position,
v3f velocity,
v3f acceleration,
v3f rotation,
bool do_interpolate,
bool is_movement_end,
f32 update_interval
);
std::string gob_cmd_set_texture_mod(const std::string &mod);
std::string gob_cmd_set_sprite(
v2s16 p,
u16 num_frames,
f32 framelength,
bool select_horiz_by_yawpitch
);
std::string gob_cmd_punched(u16 result_hp);
std::string gob_cmd_update_armor_groups(const ItemGroupList &armor_groups);
std::string gob_cmd_update_physics_override(float physics_override_speed,
float physics_override_jump, float physics_override_gravity,
bool sneak, bool sneak_glitch, bool new_move);
std::string gob_cmd_update_animation(v2f frames, float frame_speed, float frame_blend, bool frame_loop);
std::string gob_cmd_update_animation_speed(float frame_speed);
std::string gob_cmd_update_bone_position(const std::string &bone, v3f position,
v3f rotation);
std::string gob_cmd_update_attachment(int parent_id, const std::string &bone,
v3f position, v3f rotation);
std::string gob_cmd_update_nametag_attributes(video::SColor color);
std::string gob_cmd_update_infant(u16 id, u8 type,
const std::string &client_initialization_data);

@ -70,8 +70,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
PROTOCOL_VERSION 14: PROTOCOL_VERSION 14:
Added transfer of player pressed keys to the server Added transfer of player pressed keys to the server
Added new messages for mesh and bone animation, as well as attachments Added new messages for mesh and bone animation, as well as attachments
GENERIC_CMD_SET_ANIMATION AO_CMD_SET_ANIMATION
GENERIC_CMD_SET_BONE_POSITION AO_CMD_SET_BONE_POSITION
GENERIC_CMD_SET_ATTACHMENT GENERIC_CMD_SET_ATTACHMENT
PROTOCOL_VERSION 15: PROTOCOL_VERSION 15:
Serialization format changes Serialization format changes
@ -87,7 +87,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
damageGroups added to ToolCapabilities damageGroups added to ToolCapabilities
sound_place added to ItemDefinition sound_place added to ItemDefinition
PROTOCOL_VERSION 19: PROTOCOL_VERSION 19:
GENERIC_CMD_SET_PHYSICS_OVERRIDE AO_CMD_SET_PHYSICS_OVERRIDE
PROTOCOL_VERSION 20: PROTOCOL_VERSION 20:
TOCLIENT_HUDADD TOCLIENT_HUDADD
TOCLIENT_HUDRM TOCLIENT_HUDRM
@ -131,7 +131,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
Add TOCLIENT_HELLO for presenting server to client after client Add TOCLIENT_HELLO for presenting server to client after client
presentation presentation
Add TOCLIENT_AUTH_ACCEPT to accept connection from client Add TOCLIENT_AUTH_ACCEPT to accept connection from client
Rename GENERIC_CMD_SET_ATTACHMENT to GENERIC_CMD_ATTACH_TO Rename GENERIC_CMD_SET_ATTACHMENT to AO_CMD_ATTACH_TO
PROTOCOL_VERSION 26: PROTOCOL_VERSION 26:
Add TileDef tileable_horizontal, tileable_vertical flags Add TileDef tileable_horizontal, tileable_vertical flags
PROTOCOL_VERSION 27: PROTOCOL_VERSION 27:

@ -35,7 +35,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "filesys.h" #include "filesys.h"
#include "mapblock.h" #include "mapblock.h"
#include "serverobject.h" #include "serverobject.h"
#include "genericobject.h"
#include "settings.h" #include "settings.h"
#include "profiler.h" #include "profiler.h"
#include "log.h" #include "log.h"
@ -721,7 +720,7 @@ void Server::AsyncRunStep(bool initial_step)
// Go through every message // Go through every message
for (const ActiveObjectMessage &aom : *list) { for (const ActiveObjectMessage &aom : *list) {
// Send position updates to players who do not see the attachment // Send position updates to players who do not see the attachment
if (aom.datastring[0] == GENERIC_CMD_UPDATE_POSITION) { if (aom.datastring[0] == AO_CMD_UPDATE_POSITION) {
if (sao->getId() == player->getId()) if (sao->getId() == player->getId())
continue; continue;
@ -1819,9 +1818,7 @@ void Server::SendPlayerHP(session_t peer_id)
m_script->player_event(playersao,"health_changed"); m_script->player_event(playersao,"health_changed");
// Send to other clients // Send to other clients
std::string str = gob_cmd_punched(playersao->getHP()); playersao->sendPunchCommand();
ActiveObjectMessage aom(playersao->getId(), true, str);
playersao->m_messages_out.push(aom);
} }
void Server::SendPlayerBreath(PlayerSAO *sao) void Server::SendPlayerBreath(PlayerSAO *sao)

@ -1420,10 +1420,7 @@ void ServerEnvironment::step(float dtime)
// Step object // Step object
obj->step(dtime, send_recommended); obj->step(dtime, send_recommended);
// Read messages from object // Read messages from object
while (!obj->m_messages_out.empty()) { obj->dumpAOMessagesToQueue(m_active_object_messages);
this->m_active_object_messages.push(obj->m_messages_out.front());
obj->m_messages_out.pop();
}
}; };
m_ao_manager.step(dtime, cb_state); m_ao_manager.step(dtime, cb_state);
} }

@ -81,3 +81,34 @@ bool ServerActiveObject::setWieldedItem(const ItemStack &item)
{ {
return false; return false;
} }
std::string ServerActiveObject::generateUpdateInfantCommand(u16 infant_id, u16 protocol_version)
{
std::ostringstream os(std::ios::binary);
// command
writeU8(os, AO_CMD_SPAWN_INFANT);
// parameters
writeU16(os, infant_id);
writeU8(os, getSendType());
os << serializeLongString(getClientInitializationData(protocol_version));
return os.str();
}
std::string ServerActiveObject::generateUpdateNametagAttributesCommand(const video::SColor &color) const
{
std::ostringstream os(std::ios::binary);
// command
writeU8(os, AO_CMD_UPDATE_NAMETAG_ATTRIBUTES);
// parameters
writeU8(os, 1); // version for forward compatibility
writeARGB8(os, color);
return os.str();
}
void ServerActiveObject::dumpAOMessagesToQueue(std::queue<ActiveObjectMessage> &queue)
{
while (!m_messages_out.empty()) {
queue.push(m_messages_out.front());
m_messages_out.pop();
}
}

@ -113,7 +113,7 @@ public:
The return value of this is passed to the client-side object The return value of this is passed to the client-side object
when it is created when it is created
*/ */
virtual std::string getClientInitializationData(u16 protocol_version){return "";} virtual std::string getClientInitializationData(u16 protocol_version) {return "";}
/* /*
The return value of this is passed to the server-side object The return value of this is passed to the server-side object
@ -192,6 +192,10 @@ public:
m_attached_particle_spawners.erase(id); m_attached_particle_spawners.erase(id);
} }
std::string generateUpdateInfantCommand(u16 infant_id, u16 protocol_version);
std::string generateUpdateNametagAttributesCommand(const video::SColor &color) const;
void dumpAOMessagesToQueue(std::queue<ActiveObjectMessage> &queue);
/* /*
Number of players which know about this object. Object won't be Number of players which know about this object. Object won't be
@ -236,11 +240,6 @@ public:
*/ */
v3s16 m_static_block = v3s16(1337,1337,1337); v3s16 m_static_block = v3s16(1337,1337,1337);
/*
Queue of messages to be sent to the client
*/
std::queue<ActiveObjectMessage> m_messages_out;
protected: protected:
virtual void onAttach(int parent_id) {} virtual void onAttach(int parent_id) {}
virtual void onDetach(int parent_id) {} virtual void onDetach(int parent_id) {}
@ -255,6 +254,11 @@ protected:
v3f m_base_position; v3f m_base_position;
std::unordered_set<u32> m_attached_particle_spawners; std::unordered_set<u32> m_attached_particle_spawners;
/*
Queue of messages to be sent to the client
*/
std::queue<ActiveObjectMessage> m_messages_out;
private: private:
// Used for creating objects based on type // Used for creating objects based on type
static std::map<u16, Factory> m_types; static std::map<u16, Factory> m_types;

@ -151,8 +151,6 @@ src/fontengine.h
src/game.cpp src/game.cpp
src/gamedef.h src/gamedef.h
src/game.h src/game.h
src/genericobject.cpp
src/genericobject.h
src/gettext.cpp src/gettext.cpp
src/gettext.h src/gettext.h
src/gui/guiAnimatedImage.cpp src/gui/guiAnimatedImage.cpp