From 423d8c1b0d3841f6ce9756ab0d6b2e10408fc89b Mon Sep 17 00:00:00 2001 From: est31 Date: Wed, 18 May 2016 06:18:08 +0200 Subject: Tolerate packet reordering in the early init process Fixes a bug where packet reordering made the server give the client two peer ids instead of one. This in turn confused reliable packet sending and made connecting to the server fail. The client usually sends three packets at init: one "dummy" packet consisting of two 0 bytes, and the init packet as well as its legacy counterpart. The last one can be turned off since commit af30183124d40a969040d7de4b3a487feec466e4, but this is of lower relevance for the bug. The relevant part here is that network packet reorder (which is a normal occurence) can make the packets reach the server in different order. If reorder puts the dummy packet further behind, the following would happen before the patch: 1. The server will get one of the init packets on channel 1 and assign the client a peer id, as the packet will have zero as peer id. 2. The server sends a CONTROLTYPE_SET_PEER_ID packet to inform the client of the peer id. 3. The next packet from the client will contain the peer id set by the server. 4. The server sets the m_has_sent_with_id member for the client's peer structure to true. 5. Now the dummy packet arrives. It has a peer id of zero, therefore the server searches whether it already has a peer id for the address the packet was sent from. The search fails because m_has_sent_with_id was set to true and the server only searched for peers with m_has_sent_with_id set to false. 6. In a working setup, the server would assign the dummy packet to the correct peer id. However the server instead now assigns a second peer id and peer structure to the peer, and assign the packet to that new peer. 7. In order to inform the peer of its peer id, the server sends a CONTROLTYPE_SET_PEER_ID command packet, reliably, to the peer. This packet uses the new peer id. 8. The client sends an ack to that packet, not with the new peer id but with the peer id sent in 2. 9. This packet reaches the server, but it drops the ACK as the peer id does not map to any un-ACK-ed packets with that seqnum. The same time, the server still waits for an ACK with the new peer id, which of course won't come. This causes the server to periodically re-try sending that packet, and the client ACKing it each time. Steps 7-9 cause annoyances and erroneous output, but don't cause the connection failure itself. The actual mistake that causes the connection failure happens in 6: The server does not assign the dummy packet to the correct peer, but to a newly created one. Therefore, all further packets sent by the client on channel 0 are now buffered by the server as it waits for the dummy packet to reach the peer, which of course doesn't happen as the server assigned that packet to the second peer it created for the client. This makes the connection code indefinitely buffer the TOSERVER_CLIENT_READY packet, not passing it to higher level code, which stalls the continuation of the further init process indefinitely and causes the actual bug. Maybe this can be caused by reordered init packets as well, the only studied case was where network has reliably reordered the dummy packet to get sent after the init packets. The patch fixes the bug by not ignoring peers where m_has_sent_with_id has been set anymore. The other changes of the patch are just cleanups of unused methods and fields and additional explanatory comments. One could think of alternate ways to fix the bug: * The client could simply take the new peer id and continue communicating with that. This is however worse than the fix as it requires the peer id set command to be sent reliably (which currently happens, but it cant be changed anymore). Also, such a change would require both server and client to be patched in order for the bug to be fixed, as right now the client ignores peer id set commands after the peer id is different from PEER_ID_INEXISTENT and the server requires modification too to change the peer id internally. And, most importantly, right now we guarantee higher level server code that the peer id for a certain peer does not change. This guarantee would have to be broken, and it would require much larger changes to the server than this patch means. * One could stop sending the dummy packet. One may be unsure whether this is a good idea, as the meaning of the dummy packet is not known (it might be there for something important), and as it is possible that the init packets may cause this problem as well (although it may be possible too that they can't cause this). Thanks to @auouymous who had originally reported this bug and who has helped patiently in finding its cause. --- src/network/connection.cpp | 13 ++++--------- src/network/connection.h | 19 ++++--------------- 2 files changed, 8 insertions(+), 24 deletions(-) (limited to 'src/network') diff --git a/src/network/connection.cpp b/src/network/connection.cpp index f7452d8e4..02c0aa165 100644 --- a/src/network/connection.cpp +++ b/src/network/connection.cpp @@ -2167,12 +2167,12 @@ void ConnectionReceiveThread::receive() throw InvalidIncomingDataException("Channel doesn't exist"); } - /* preserve original peer_id for later usage */ - u16 packet_peer_id = peer_id; - /* Try to identify peer by sender address (may happen on join) */ if (peer_id == PEER_ID_INEXISTENT) { peer_id = m_connection->lookupPeer(sender); + // We do not have to remind the peer of its + // peer id as the CONTROLTYPE_SET_PEER_ID + // command was sent reliably. } /* The peer was not found in our lists. Add it. */ @@ -2214,11 +2214,6 @@ void ConnectionReceiveThread::receive() } } - - /* mark peer as seen with id */ - if (!(packet_peer_id == PEER_ID_INEXISTENT)) - peer->setSentWithID(); - peer->ResetTimeout(); Channel *channel = 0; @@ -2756,7 +2751,7 @@ u16 Connection::lookupPeer(Address& sender) for(; j != m_peers.end(); ++j) { Peer *peer = j->second; - if (peer->isActive()) + if (peer->isPendingDeletion()) continue; Address tocheck; diff --git a/src/network/connection.h b/src/network/connection.h index fe2c9819d..5ee53b9d4 100644 --- a/src/network/connection.h +++ b/src/network/connection.h @@ -663,8 +663,7 @@ class Peer { m_last_rtt(-1.0), m_usage(0), m_timeout_counter(0.0), - m_last_timeout_check(porting::getTimeMs()), - m_has_sent_with_id(false) + m_last_timeout_check(porting::getTimeMs()) { m_rtt.avg_rtt = -1.0; m_rtt.jitter_avg = -1.0; @@ -687,21 +686,16 @@ class Peer { virtual void PutReliableSendCommand(ConnectionCommand &c, unsigned int max_packet_size) {}; - virtual bool isActive() { return false; }; - virtual bool getAddress(MTProtocols type, Address& toset) = 0; + bool isPendingDeletion() + { MutexAutoLock lock(m_exclusive_access_mutex); return m_pending_deletion; }; + void ResetTimeout() {MutexAutoLock lock(m_exclusive_access_mutex); m_timeout_counter=0.0; }; bool isTimedOut(float timeout); - void setSentWithID() - { MutexAutoLock lock(m_exclusive_access_mutex); m_has_sent_with_id = true; }; - - bool hasSentWithID() - { MutexAutoLock lock(m_exclusive_access_mutex); return m_has_sent_with_id; }; - unsigned int m_increment_packets_remaining; unsigned int m_increment_bytes_remaining; @@ -776,8 +770,6 @@ class Peer { float m_timeout_counter; u32 m_last_timeout_check; - - bool m_has_sent_with_id; }; class UDPPeer : public Peer @@ -795,9 +787,6 @@ public: void PutReliableSendCommand(ConnectionCommand &c, unsigned int max_packet_size); - bool isActive() - { return ((hasSentWithID()) && (!m_pending_deletion)); }; - bool getAddress(MTProtocols type, Address& toset); void setNonLegacyPeer(); -- cgit v1.2.3 From d499ec483837fa7210176ef39beba2d5a3a5a61d Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Fri, 27 May 2016 21:08:23 -0700 Subject: Particles: Add option to remove particles on collision Adds the particle option `collision_removal = bool` Some particles are hard to use right now since they either go through solid blocks (without collision detection), and with collision detection enabled they (e.g. raindrops) would just stop dead on the floor and sit there until they expire, or worse, scrape along a wall or ceiling. We can solve the problem by adding a boolean flag that tells the particle to be removed if it ever collides with something. This will make it easier to add rain that doesn't fall through your roof or stick on the top of it. Or clouds and smoke that don't go through trees. Particles that collide with this flag are marked expired unconditionally, causing them to be treated like normal expired particles and cleaned up normally. Documentation is adjusted accordingly. An added bonus of this patch is that particles can potentially collide many times with nodes, and this reduces the amount of collisions to 1 (max), which may end up reducing particle load on the client. --- doc/lua_api.txt | 6 ++++++ src/client.h | 2 ++ src/network/clientpackethandler.cpp | 7 +++++++ src/network/networkprotocol.h | 2 ++ src/particles.cpp | 39 +++++++++++++++++++++++-------------- src/particles.h | 5 +++++ src/script/lua_api/l_particles.cpp | 24 ++++++++++++++++------- src/server.cpp | 19 ++++++++++++------ src/server.h | 12 ++++++++---- 9 files changed, 84 insertions(+), 32 deletions(-) (limited to 'src/network') diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 01763fd73..03f2dad32 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -3885,6 +3885,9 @@ Definition tables size = 1, collisiondetection = false, -- ^ collisiondetection: if true collides with physical objects + collision_removal = false, + -- ^ collision_removal: if true then particle is removed when it collides, + -- ^ requires collisiondetection = true to have any effect vertical = false, -- ^ vertical: if true faces player using y axis only texture = "image.png", @@ -3914,6 +3917,9 @@ Definition tables -- ^ minsize/maxsize, minexptime/maxexptime (expirationtime) collisiondetection = false, -- ^ collisiondetection: if true uses collision detection + collision_removal = false, + -- ^ collision_removal: if true then particle is removed when it collides, + -- ^ requires collisiondetection = true to have any effect vertical = false, -- ^ vertical: if true faces player using y axis only texture = "image.png", diff --git a/src/client.h b/src/client.h index cdadb9d3e..a7eb22ad9 100644 --- a/src/client.h +++ b/src/client.h @@ -182,6 +182,7 @@ struct ClientEvent f32 expirationtime; f32 size; bool collisiondetection; + bool collision_removal; bool vertical; std::string *texture; } spawn_particle; @@ -199,6 +200,7 @@ struct ClientEvent f32 minsize; f32 maxsize; bool collisiondetection; + bool collision_removal; bool vertical; std::string *texture; u32 id; diff --git a/src/network/clientpackethandler.cpp b/src/network/clientpackethandler.cpp index 0498f4048..48c573da5 100644 --- a/src/network/clientpackethandler.cpp +++ b/src/network/clientpackethandler.cpp @@ -898,8 +898,10 @@ void Client::handleCommand_SpawnParticle(NetworkPacket* pkt) bool collisiondetection = readU8(is); std::string texture = deSerializeLongString(is); bool vertical = false; + bool collision_removal = false; try { vertical = readU8(is); + collision_removal = readU8(is); } catch (...) {} ClientEvent event; @@ -910,6 +912,7 @@ void Client::handleCommand_SpawnParticle(NetworkPacket* pkt) event.spawn_particle.expirationtime = expirationtime; event.spawn_particle.size = size; event.spawn_particle.collisiondetection = collisiondetection; + event.spawn_particle.collision_removal = collision_removal; event.spawn_particle.vertical = vertical; event.spawn_particle.texture = new std::string(texture); @@ -942,8 +945,11 @@ void Client::handleCommand_AddParticleSpawner(NetworkPacket* pkt) *pkt >> id; bool vertical = false; + bool collision_removal = false; try { *pkt >> vertical; + *pkt >> collision_removal; + } catch (...) {} ClientEvent event; @@ -961,6 +967,7 @@ void Client::handleCommand_AddParticleSpawner(NetworkPacket* pkt) event.add_particlespawner.minsize = minsize; event.add_particlespawner.maxsize = maxsize; event.add_particlespawner.collisiondetection = collisiondetection; + event.add_particlespawner.collision_removal = collision_removal; event.add_particlespawner.vertical = vertical; event.add_particlespawner.texture = new std::string(texture); event.add_particlespawner.id = id; diff --git a/src/network/networkprotocol.h b/src/network/networkprotocol.h index 177b97680..3a9483efb 100644 --- a/src/network/networkprotocol.h +++ b/src/network/networkprotocol.h @@ -474,6 +474,7 @@ enum ToClientCommand u8 bool vertical u32 len u8[len] texture + u8 collision_removal */ TOCLIENT_ADD_PARTICLESPAWNER = 0x47, @@ -495,6 +496,7 @@ enum ToClientCommand u32 len u8[len] texture u32 id + u8 collision_removal */ TOCLIENT_DELETE_PARTICLESPAWNER_LEGACY = 0x48, diff --git a/src/particles.cpp b/src/particles.cpp index 525258a25..ccca691d1 100644 --- a/src/particles.cpp +++ b/src/particles.cpp @@ -54,6 +54,7 @@ Particle::Particle( float expirationtime, float size, bool collisiondetection, + bool collision_removal, bool vertical, video::ITexture *texture, v2f texpos, @@ -85,6 +86,7 @@ Particle::Particle( m_player = player; m_size = size; m_collisiondetection = collisiondetection; + m_collision_removal = collision_removal; m_vertical = vertical; // Irrlicht stuff @@ -126,20 +128,21 @@ void Particle::render() void Particle::step(float dtime) { m_time += dtime; - if (m_collisiondetection) - { + if (m_collisiondetection) { aabb3f box = m_collisionbox; - v3f p_pos = m_pos*BS; - v3f p_velocity = m_velocity*BS; - collisionMoveSimple(m_env, m_gamedef, - BS*0.5, box, - 0, dtime, - &p_pos, &p_velocity, m_acceleration * BS); - m_pos = p_pos/BS; - m_velocity = p_velocity/BS; - } - else - { + v3f p_pos = m_pos * BS; + v3f p_velocity = m_velocity * BS; + collisionMoveResult r = collisionMoveSimple(m_env, + m_gamedef, BS * 0.5, box, 0, dtime, &p_pos, + &p_velocity, m_acceleration * BS); + if (m_collision_removal && r.collides) { + // force expiration of the particle + m_expiration = -1.0; + } else { + m_pos = p_pos / BS; + m_velocity = p_velocity / BS; + } + } else { m_velocity += m_acceleration * dtime; m_pos += m_velocity * dtime; } @@ -210,8 +213,8 @@ ParticleSpawner::ParticleSpawner(IGameDef* gamedef, scene::ISceneManager *smgr, u16 amount, float time, v3f minpos, v3f maxpos, v3f minvel, v3f maxvel, v3f minacc, v3f maxacc, float minexptime, float maxexptime, float minsize, float maxsize, - bool collisiondetection, bool vertical, video::ITexture *texture, u32 id, - ParticleManager *p_manager) : + bool collisiondetection, bool collision_removal, bool vertical, + video::ITexture *texture, u32 id, ParticleManager *p_manager) : m_particlemanager(p_manager) { m_gamedef = gamedef; @@ -230,6 +233,7 @@ ParticleSpawner::ParticleSpawner(IGameDef* gamedef, scene::ISceneManager *smgr, m_minsize = minsize; m_maxsize = maxsize; m_collisiondetection = collisiondetection; + m_collision_removal = collision_removal; m_vertical = vertical; m_texture = texture; m_time = 0; @@ -277,6 +281,7 @@ void ParticleSpawner::step(float dtime, ClientEnvironment* env) exptime, size, m_collisiondetection, + m_collision_removal, m_vertical, m_texture, v2f(0.0, 0.0), @@ -317,6 +322,7 @@ void ParticleSpawner::step(float dtime, ClientEnvironment* env) exptime, size, m_collisiondetection, + m_collision_removal, m_vertical, m_texture, v2f(0.0, 0.0), @@ -446,6 +452,7 @@ void ParticleManager::handleParticleEvent(ClientEvent *event, IGameDef *gamedef, event->add_particlespawner.minsize, event->add_particlespawner.maxsize, event->add_particlespawner.collisiondetection, + event->add_particlespawner.collision_removal, event->add_particlespawner.vertical, texture, event->add_particlespawner.id, @@ -480,6 +487,7 @@ void ParticleManager::handleParticleEvent(ClientEvent *event, IGameDef *gamedef, event->spawn_particle.expirationtime, event->spawn_particle.size, event->spawn_particle.collisiondetection, + event->spawn_particle.collision_removal, event->spawn_particle.vertical, texture, v2f(0.0, 0.0), @@ -555,6 +563,7 @@ void ParticleManager::addNodeParticle(IGameDef* gamedef, scene::ISceneManager* s visual_size, true, false, + false, texture, texpos, texsize); diff --git a/src/particles.h b/src/particles.h index dda84385c..bc3ca53b7 100644 --- a/src/particles.h +++ b/src/particles.h @@ -30,6 +30,7 @@ with this program; if not, write to the Free Software Foundation, Inc., struct ClientEvent; class ParticleManager; +class ClientEnvironment; class Particle : public scene::ISceneNode { @@ -45,6 +46,7 @@ class Particle : public scene::ISceneNode float expirationtime, float size, bool collisiondetection, + bool collision_removal, bool vertical, video::ITexture *texture, v2f texpos, @@ -97,6 +99,7 @@ private: float m_size; u8 m_light; bool m_collisiondetection; + bool m_collision_removal; bool m_vertical; v3s16 m_camera_offset; }; @@ -115,6 +118,7 @@ class ParticleSpawner float minexptime, float maxexptime, float minsize, float maxsize, bool collisiondetection, + bool collision_removal, bool vertical, video::ITexture *texture, u32 id, @@ -148,6 +152,7 @@ class ParticleSpawner video::ITexture *m_texture; std::vector m_spawntimes; bool m_collisiondetection; + bool m_collision_removal; bool m_vertical; }; diff --git a/src/script/lua_api/l_particles.cpp b/src/script/lua_api/l_particles.cpp index f6c1725de..263e35407 100644 --- a/src/script/lua_api/l_particles.cpp +++ b/src/script/lua_api/l_particles.cpp @@ -21,13 +21,16 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "lua_api/l_internal.h" #include "common/c_converter.h" #include "server.h" +#include "particles.h" // add_particle({pos=, velocity=, acceleration=, expirationtime=, -// size=, collisiondetection=, vertical=, texture=, player=}) +// size=, collisiondetection=, collision_removal=, vertical=, +// texture=, player=}) // pos/velocity/acceleration = {x=num, y=num, z=num} // expirationtime = num (seconds) // size = num // collisiondetection = bool +// collision_removal = bool // vertical = bool // texture = e.g."default_wood.png" int ModApiParticles::l_add_particle(lua_State *L) @@ -41,8 +44,8 @@ int ModApiParticles::l_add_particle(lua_State *L) float expirationtime, size; expirationtime = size = 1; - bool collisiondetection, vertical; - collisiondetection = vertical = false; + bool collisiondetection, vertical, collision_removal; + collisiondetection = vertical = collision_removal = false; std::string texture = ""; std::string playername = ""; @@ -94,12 +97,14 @@ int ModApiParticles::l_add_particle(lua_State *L) size = getfloatfield_default(L, 1, "size", 1); collisiondetection = getboolfield_default(L, 1, "collisiondetection", collisiondetection); + collision_removal = getboolfield_default(L, 1, + "collision_removal", collision_removal); vertical = getboolfield_default(L, 1, "vertical", vertical); texture = getstringfield_default(L, 1, "texture", ""); playername = getstringfield_default(L, 1, "playername", ""); } - getServer(L)->spawnParticle(playername, pos, vel, acc, - expirationtime, size, collisiondetection, vertical, texture); + getServer(L)->spawnParticle(playername, pos, vel, acc, expirationtime, size, + collisiondetection, collision_removal, vertical, texture); return 1; } @@ -110,6 +115,7 @@ int ModApiParticles::l_add_particle(lua_State *L) // minexptime=, maxexptime=, // minsize=, maxsize=, // collisiondetection=, +// collision_removal=, // vertical=, // texture=, // player=}) @@ -117,6 +123,7 @@ int ModApiParticles::l_add_particle(lua_State *L) // minexptime/maxexptime = num (seconds) // minsize/maxsize = num // collisiondetection = bool +// collision_removal = bool // vertical = bool // texture = e.g."default_wood.png" int ModApiParticles::l_add_particlespawner(lua_State *L) @@ -129,8 +136,8 @@ int ModApiParticles::l_add_particlespawner(lua_State *L) minpos= maxpos= minvel= maxvel= minacc= maxacc= v3f(0, 0, 0); float time, minexptime, maxexptime, minsize, maxsize; time= minexptime= maxexptime= minsize= maxsize= 1; - bool collisiondetection, vertical; - collisiondetection= vertical= false; + bool collisiondetection, vertical, collision_removal; + collisiondetection = vertical = collision_removal = false; std::string texture = ""; std::string playername = ""; @@ -189,6 +196,8 @@ int ModApiParticles::l_add_particlespawner(lua_State *L) maxsize = getfloatfield_default(L, 1, "maxsize", maxsize); collisiondetection = getboolfield_default(L, 1, "collisiondetection", collisiondetection); + collision_removal = getboolfield_default(L, 1, + "collision_removal", collision_removal); vertical = getboolfield_default(L, 1, "vertical", vertical); texture = getstringfield_default(L, 1, "texture", ""); playername = getstringfield_default(L, 1, "playername", ""); @@ -201,6 +210,7 @@ int ModApiParticles::l_add_particlespawner(lua_State *L) minexptime, maxexptime, minsize, maxsize, collisiondetection, + collision_removal, vertical, texture, playername); lua_pushnumber(L, id); diff --git a/src/server.cpp b/src/server.cpp index a3b686c25..ada45dc68 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -1673,7 +1673,8 @@ void Server::SendShowFormspecMessage(u16 peer_id, const std::string &formspec, // Spawns a particle on peer with peer_id void Server::SendSpawnParticle(u16 peer_id, v3f pos, v3f velocity, v3f acceleration, float expirationtime, float size, bool collisiondetection, - bool vertical, std::string texture) + bool collision_removal, + bool vertical, const std::string &texture) { DSTACK(FUNCTION_NAME); @@ -1683,6 +1684,7 @@ void Server::SendSpawnParticle(u16 peer_id, v3f pos, v3f velocity, v3f accelerat << size << collisiondetection; pkt.putLongString(texture); pkt << vertical; + pkt << collision_removal; if (peer_id != PEER_ID_INEXISTENT) { Send(&pkt); @@ -1695,7 +1697,8 @@ void Server::SendSpawnParticle(u16 peer_id, v3f pos, v3f velocity, v3f accelerat // Adds a ParticleSpawner on peer with peer_id void Server::SendAddParticleSpawner(u16 peer_id, u16 amount, float spawntime, v3f minpos, v3f maxpos, v3f minvel, v3f maxvel, v3f minacc, v3f maxacc, float minexptime, float maxexptime, - float minsize, float maxsize, bool collisiondetection, bool vertical, std::string texture, u32 id) + float minsize, float maxsize, bool collisiondetection, bool collision_removal, + bool vertical, const std::string &texture, u32 id) { DSTACK(FUNCTION_NAME); @@ -1708,6 +1711,7 @@ void Server::SendAddParticleSpawner(u16 peer_id, u16 amount, float spawntime, v3 pkt.putLongString(texture); pkt << id << vertical; + pkt << collision_removal; if (peer_id != PEER_ID_INEXISTENT) { Send(&pkt); @@ -3160,7 +3164,8 @@ void Server::notifyPlayers(const std::wstring &msg) void Server::spawnParticle(const std::string &playername, v3f pos, v3f velocity, v3f acceleration, float expirationtime, float size, bool - collisiondetection, bool vertical, const std::string &texture) + collisiondetection, bool collision_removal, + bool vertical, const std::string &texture) { // m_env will be NULL if the server is initializing if (!m_env) @@ -3175,13 +3180,15 @@ void Server::spawnParticle(const std::string &playername, v3f pos, } SendSpawnParticle(peer_id, pos, velocity, acceleration, - expirationtime, size, collisiondetection, vertical, texture); + expirationtime, size, collisiondetection, + collision_removal, vertical, texture); } u32 Server::addParticleSpawner(u16 amount, float spawntime, v3f minpos, v3f maxpos, v3f minvel, v3f maxvel, v3f minacc, v3f maxacc, float minexptime, float maxexptime, float minsize, float maxsize, - bool collisiondetection, bool vertical, const std::string &texture, + bool collisiondetection, bool collision_removal, + bool vertical, const std::string &texture, const std::string &playername) { // m_env will be NULL if the server is initializing @@ -3200,7 +3207,7 @@ u32 Server::addParticleSpawner(u16 amount, float spawntime, SendAddParticleSpawner(peer_id, amount, spawntime, minpos, maxpos, minvel, maxvel, minacc, maxacc, minexptime, maxexptime, minsize, maxsize, - collisiondetection, vertical, texture, id); + collisiondetection, collision_removal, vertical, texture, id); return id; } diff --git a/src/server.h b/src/server.h index daf51dee1..7ee15a463 100644 --- a/src/server.h +++ b/src/server.h @@ -275,7 +275,8 @@ public: void spawnParticle(const std::string &playername, v3f pos, v3f velocity, v3f acceleration, float expirationtime, float size, - bool collisiondetection, bool vertical, const std::string &texture); + bool collisiondetection, bool collision_removal, + bool vertical, const std::string &texture); u32 addParticleSpawner(u16 amount, float spawntime, v3f minpos, v3f maxpos, @@ -283,7 +284,8 @@ public: v3f minacc, v3f maxacc, float minexptime, float maxexptime, float minsize, float maxsize, - bool collisiondetection, bool vertical, const std::string &texture, + bool collisiondetection, bool collision_removal, + bool vertical, const std::string &texture, const std::string &playername); void deleteParticleSpawner(const std::string &playername, u32 id); @@ -456,7 +458,8 @@ private: v3f minacc, v3f maxacc, float minexptime, float maxexptime, float minsize, float maxsize, - bool collisiondetection, bool vertical, std::string texture, u32 id); + bool collisiondetection, bool collision_removal, + bool vertical, const std::string &texture, u32 id); void SendDeleteParticleSpawner(u16 peer_id, u32 id); @@ -464,7 +467,8 @@ private: void SendSpawnParticle(u16 peer_id, v3f pos, v3f velocity, v3f acceleration, float expirationtime, float size, - bool collisiondetection, bool vertical, std::string texture); + bool collisiondetection, bool collision_removal, + bool vertical, const std::string &texture); u32 SendActiveObjectRemoveAdd(u16 peer_id, const std::string &datas); void SendActiveObjectMessages(u16 peer_id, const std::string &datas, bool reliable = true); -- cgit v1.2.3 From 7ea4a03c835d68a6fb58aa55aa6a6315ec80b79f Mon Sep 17 00:00:00 2001 From: Robert Kiraly Date: Fri, 3 Jun 2016 00:50:21 -0700 Subject: Sapier's fix for the RESEND RELIABLE problem (#4170) --- src/network/connection.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'src/network') diff --git a/src/network/connection.cpp b/src/network/connection.cpp index 02c0aa165..b711cae11 100644 --- a/src/network/connection.cpp +++ b/src/network/connection.cpp @@ -71,6 +71,9 @@ static inline float CALC_DTIME(unsigned int lasttime, unsigned int curtime) { #define PING_TIMEOUT 5.0 +/* maximum number of retries for reliable packets */ +#define MAX_RELIABLE_RETRY 5 + static u16 readPeerId(u8 *packetdata) { return readU16(&packetdata[4]); @@ -1399,6 +1402,7 @@ void ConnectionSendThread::runTimeouts(float dtime) } float resend_timeout = dynamic_cast(&peer)->getResendTimeout(); + bool retry_count_exceeded = false; for(u16 i=0; i timed_outs; @@ -1438,6 +1442,13 @@ void ConnectionSendThread::runTimeouts(float dtime) channel->UpdateBytesLost(k->data.getSize()); k->resend_count++; + if (k-> resend_count > MAX_RELIABLE_RETRY) { + retry_count_exceeded = true; + timeouted_peers.push_back(peer->id); + /* no need to check additional packets if a single one did timeout*/ + break; + } + LOG(derr_con<getDesc() <<"RE-SENDING timed-out RELIABLE to " << k->address.serializeString() @@ -1452,9 +1463,18 @@ void ConnectionSendThread::runTimeouts(float dtime) // do not handle rtt here as we can't decide if this packet was // lost or really takes more time to transmit } + + if (retry_count_exceeded) { + break; /* no need to check other channels if we already did timeout */ + } + channel->UpdateTimers(dtime,dynamic_cast(&peer)->getLegacyPeer()); } + /* skip to next peer if we did timeout */ + if (retry_count_exceeded) + continue; + /* send ping if necessary */ if (dynamic_cast(&peer)->Ping(dtime,data)) { LOG(dout_con<getDesc() -- cgit v1.2.3 From e58a55aa82dfc66325a694dcc3519d3c0f3388a6 Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Thu, 10 Dec 2015 22:58:11 -0800 Subject: Make plantlike drawtype more fun Adds several new ways that the plantlike drawtype mesh can be changed. This requires paramtype2 = "meshoptions" to be set in the node definition. The drawtype for these nodes should be "plantlike". These modifications are all done using param2. This field is now a complex bitfield that allows some or more of the combinations to be chosen, and the mesh draw code will choose the options based as neeeded for each plantlike node. bit layout: bits 0, 1 and 2 (values 0x1 through 0x7) are for choosing the plant mesh shape: 0 - ordinary plantlike plant ("x" shaped) 1 - ordinary plant, but rotated 45 degrees ("+" shaped) 2 - a plant with 3 faces ("*" shaped) 3 - a plant with 4 faces ("#" shaped) 4 - a plant with 4 faces ("#" shaped, leaning outwards) 5 through 7 are unused and reserved for future mesh shapes. bit 3 (0x8) causes the plant to be randomly offset in the x,z plane. The plant should fall within the 1x1x1 nodebox if regularly sized. bit 4 (0x10) causes the plant mesh to grow by sqrt(2), and will cause the plant mesh to fill out 1x1x1, and appear slightly larger. Texture makers will want to make their plant texture 23x16 pixels to have the best visual fit in 1x1x1 size. bit 5 (0x20) causes each face of the plant to have a slight negative Y offset in position, descending up to 0.125 downwards into the node below. Because this is per face, this causes the plant model to be less symmetric. bit 6 (0x40) through bit 7 (0x80) are unused and reserved for future use. !(https://youtu.be/qWuI664krsI) --- doc/lua_api.txt | 16 +++++ src/content_mapblock.cpp | 152 +++++++++++++++++++++++++++++++++++++++--- src/network/networkprotocol.h | 4 +- src/nodedef.cpp | 5 +- src/nodedef.h | 2 + src/script/cpp_api/s_node.cpp | 1 + 6 files changed, 167 insertions(+), 13 deletions(-) (limited to 'src/network') diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 38f19aadc..440edd963 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -578,6 +578,22 @@ node definition: ^ The rotation of this node is stored in param2. Plants are rotated this way. Values range 0 - 179. The value stored in param2 is multiplied by two to get the actual rotation of the node. + paramtype2 == "meshoptions" + ^ Only valid for "plantlike". The value of param2 becomes a bitfield which can + be used to change how the client draws plantlike nodes. Bits 0, 1 and 2 form + a mesh selector. Currently the following meshes are choosable: + 0 = a "x" shaped plant (ordinary plant) + 1 = a "+" shaped plant (just rotated 45 degrees) + 2 = a "*" shaped plant with 3 faces instead of 2 + 3 = a "#" shaped plant with 4 faces instead of 2 + 4 = a "#" shaped plant with 4 faces that lean outwards + 5-7 are unused and reserved for future meshes. + Bits 3 through 7 are optional flags that can be combined and give these + effects: + bit 3 (0x08) - Makes the plant slightly vary placement horizontally + bit 4 (0x10) - Makes the plant mesh 1.4x larger + bit 5 (0x20) - Moves each face randomly a small bit down (1/8 max) + bits 6-7 are reserved for future use. collision_box = { type = "fixed", fixed = { diff --git a/src/content_mapblock.cpp b/src/content_mapblock.cpp index 6a83bd8f3..b86b97822 100644 --- a/src/content_mapblock.cpp +++ b/src/content_mapblock.cpp @@ -28,6 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include "gamedef.h" #include "log.h" +#include "noise.h" // Create a cuboid. @@ -1104,6 +1105,8 @@ void mapblock_mesh_generate_special(MeshMakeData *data, break;} case NDT_PLANTLIKE: { + PseudoRandom rng(x<<8 | z | y<<16); + TileSpec tile = getNodeTileN(n, p, 0, data); tile.material_flags |= MATERIAL_FLAG_CRACK_OVERLAY; @@ -1111,9 +1114,18 @@ void mapblock_mesh_generate_special(MeshMakeData *data, video::SColor c = MapBlock_LightColor(255, l, f.light_source); float s = BS / 2 * f.visual_scale; + // add sqrt(2) visual scale + if ((f.param_type_2 == CPT2_MESHOPTIONS) && ((n.param2 & 0x10) != 0)) + s *= 1.41421; + + float random_offset_X = .0; + float random_offset_Z = .0; + if ((f.param_type_2 == CPT2_MESHOPTIONS) && ((n.param2 & 0x8) != 0)) { + random_offset_X = BS * ((rng.next() % 16 / 16.0) * 0.29 - 0.145); + random_offset_Z = BS * ((rng.next() % 16 / 16.0) * 0.29 - 0.145); + } - for (int j = 0; j < 2; j++) - { + for (int j = 0; j < 4; j++) { video::S3DVertex vertices[4] = { video::S3DVertex(-s,-BS/2, 0, 0,0,0, c, 0,1), @@ -1121,28 +1133,146 @@ void mapblock_mesh_generate_special(MeshMakeData *data, video::S3DVertex( s,-BS/2 + s*2,0, 0,0,0, c, 1,0), video::S3DVertex(-s,-BS/2 + s*2,0, 0,0,0, c, 0,0), }; + float rotate_degree = 0; + u8 p2mesh = 0; if (f.param_type_2 == CPT2_DEGROTATE) rotate_degree = n.param2 * 2; - - if (j == 0) { - for(u16 i = 0; i < 4; i++) - vertices[i].Pos.rotateXZBy(46 + rotate_degree); - } else if (j == 1) { - for(u16 i = 0; i < 4; i++) - vertices[i].Pos.rotateXZBy(-44 + rotate_degree); + else if (f.param_type_2 != CPT2_MESHOPTIONS) { + if (j == 0) { + for (u16 i = 0; i < 4; i++) + vertices[i].Pos.rotateXZBy(46 + rotate_degree); + } else if (j == 1) { + for (u16 i = 0; i < 4; i++) + vertices[i].Pos.rotateXZBy(-44 + rotate_degree); + } + } else { + p2mesh = n.param2 & 0x7; + switch (p2mesh) { + case 0: + // x + if (j == 0) { + for (u16 i = 0; i < 4; i++) + vertices[i].Pos.rotateXZBy(46); + } else if (j == 1) { + for (u16 i = 0; i < 4; i++) + vertices[i].Pos.rotateXZBy(-44); + } + break; + case 1: + // + + if (j == 0) { + for (u16 i = 0; i < 4; i++) + vertices[i].Pos.rotateXZBy(91); + } else if (j == 1) { + for (u16 i = 0; i < 4; i++) + vertices[i].Pos.rotateXZBy(1); + } + break; + case 2: + // * + if (j == 0) { + for (u16 i = 0; i < 4; i++) + vertices[i].Pos.rotateXZBy(121); + } else if (j == 1) { + for (u16 i = 0; i < 4; i++) + vertices[i].Pos.rotateXZBy(241); + } else { // (j == 2) + for (u16 i = 0; i < 4; i++) + vertices[i].Pos.rotateXZBy(1); + } + break; + case 3: + // # + switch (j) { + case 0: + for (u16 i = 0; i < 4; i++) { + vertices[i].Pos.rotateXZBy(1); + vertices[i].Pos.Z += BS / 4; + } + break; + case 1: + for (u16 i = 0; i < 4; i++) { + vertices[i].Pos.rotateXZBy(91); + vertices[i].Pos.X += BS / 4; + } + break; + case 2: + for (u16 i = 0; i < 4; i++) { + vertices[i].Pos.rotateXZBy(181); + vertices[i].Pos.Z -= BS / 4; + } + break; + case 3: + for (u16 i = 0; i < 4; i++) { + vertices[i].Pos.rotateXZBy(271); + vertices[i].Pos.X -= BS / 4; + } + break; + } + break; + case 4: + // outward leaning #-like + switch (j) { + case 0: + for (u16 i = 2; i < 4; i++) + vertices[i].Pos.Z -= BS / 2; + for (u16 i = 0; i < 4; i++) + vertices[i].Pos.rotateXZBy(1); + break; + case 1: + for (u16 i = 2; i < 4; i++) + vertices[i].Pos.Z -= BS / 2; + for (u16 i = 0; i < 4; i++) + vertices[i].Pos.rotateXZBy(91); + break; + case 2: + for (u16 i = 2; i < 4; i++) + vertices[i].Pos.Z -= BS / 2; + for (u16 i = 0; i < 4; i++) + vertices[i].Pos.rotateXZBy(181); + break; + case 3: + for (u16 i = 2; i < 4; i++) + vertices[i].Pos.Z -= BS / 2; + for (u16 i = 0; i < 4; i++) + vertices[i].Pos.rotateXZBy(271); + break; + } + break; + } } - for (int i = 0; i < 4; i++) - { + for (int i = 0; i < 4; i++) { vertices[i].Pos *= f.visual_scale; vertices[i].Pos.Y += BS/2 * (f.visual_scale - 1); vertices[i].Pos += intToFloat(p, BS); + // move to a random spot to avoid moire + if ((f.param_type_2 == CPT2_MESHOPTIONS) && ((n.param2 & 0x8) != 0)) { + vertices[i].Pos.X += random_offset_X; + vertices[i].Pos.Z += random_offset_Z; + } + // randomly move each face up/down + if ((f.param_type_2 == CPT2_MESHOPTIONS) && ((n.param2 & 0x20) != 0)) { + PseudoRandom yrng(j | x<<16 | z<<8 | y<<24 ); + vertices[i].Pos.Y -= BS * ((yrng.next() % 16 / 16.0) * 0.125); + } } u16 indices[] = {0, 1, 2, 2, 3, 0}; // Add to mesh collector collector.append(tile, vertices, 4, indices, 6); + + // stop adding faces for meshes with less than 4 faces + if (f.param_type_2 == CPT2_MESHOPTIONS) { + if (((p2mesh == 0) || (p2mesh == 1)) && (j == 1)) + break; + else if ((p2mesh == 2) && (j == 2)) + break; + } else if (j == 1) { + break; + } + } break;} case NDT_FIRELIKE: diff --git a/src/network/networkprotocol.h b/src/network/networkprotocol.h index 3a9483efb..e3fcae0c6 100644 --- a/src/network/networkprotocol.h +++ b/src/network/networkprotocol.h @@ -136,9 +136,11 @@ with this program; if not, write to the Free Software Foundation, Inc., backface_culling: backwards compatibility for playing with newer client on pre-27 servers. Add nodedef v3 - connected nodeboxes + PROTOCOL_VERSION 28: + CPT2_MESHOPTIONS */ -#define LATEST_PROTOCOL_VERSION 27 +#define LATEST_PROTOCOL_VERSION 28 // Server's supported network protocol range #define SERVER_PROTOCOL_VERSION_MIN 13 diff --git a/src/nodedef.cpp b/src/nodedef.cpp index 764203efc..646375575 100644 --- a/src/nodedef.cpp +++ b/src/nodedef.cpp @@ -387,7 +387,10 @@ void ContentFeatures::serialize(std::ostream &os, u16 protocol_version) const writeU8(os, post_effect_color.getGreen()); writeU8(os, post_effect_color.getBlue()); writeU8(os, param_type); - writeU8(os, param_type_2); + if ((protocol_version < 28) && (param_type_2 == CPT2_MESHOPTIONS)) + writeU8(os, CPT2_NONE); + else + writeU8(os, param_type_2); writeU8(os, is_ground_content); writeU8(os, light_propagates); writeU8(os, sunlight_propagates); diff --git a/src/nodedef.h b/src/nodedef.h index 1c2f792d8..f17c53727 100644 --- a/src/nodedef.h +++ b/src/nodedef.h @@ -65,6 +65,8 @@ enum ContentParamType2 CPT2_LEVELED, // 2D rotation for things like plants CPT2_DEGROTATE, + // Mesh options for plants + CPT2_MESHOPTIONS }; enum LiquidType diff --git a/src/script/cpp_api/s_node.cpp b/src/script/cpp_api/s_node.cpp index 17f0f0dac..379ed773f 100644 --- a/src/script/cpp_api/s_node.cpp +++ b/src/script/cpp_api/s_node.cpp @@ -58,6 +58,7 @@ struct EnumString ScriptApiNode::es_ContentParamType2[] = {CPT2_WALLMOUNTED, "wallmounted"}, {CPT2_LEVELED, "leveled"}, {CPT2_DEGROTATE, "degrotate"}, + {CPT2_MESHOPTIONS, "meshoptions"}, {0, NULL}, }; -- cgit v1.2.3 From d4c76258e37337ea585cf24d8e05b50a30fa307d Mon Sep 17 00:00:00 2001 From: Loic Blot Date: Tue, 4 Oct 2016 18:17:12 +0200 Subject: Chat: new settings to prevent spam Added the following chat coreside features * Chat messages length limit * Message rate limiting * Message rate kicking Note: * handleChat now takes RemotePlayer pointer instead of u16 to remove useless lookups --- builtin/settingtypes.txt | 9 ++++++ minetest.conf.example | 14 +++++++++- src/defaultsettings.cpp | 3 ++ src/network/serverpackethandler.cpp | 10 +++---- src/player.cpp | 56 ++++++++++++++++++++++++++++++++++++- src/player.h | 16 ++++++++++- src/server.cpp | 25 +++++++++++++++-- src/server.h | 3 +- 8 files changed, 125 insertions(+), 11 deletions(-) (limited to 'src/network') diff --git a/builtin/settingtypes.txt b/builtin/settingtypes.txt index 15fab0f30..95cc826a0 100644 --- a/builtin/settingtypes.txt +++ b/builtin/settingtypes.txt @@ -774,6 +774,15 @@ time_speed (Time speed) int 72 # Interval of saving important changes in the world, stated in seconds. server_map_save_interval (Map save interval) float 5.3 +# Set the maximum character length of a chat message sent by clients. +# chat_message_max_size int 500 + +# Limit a single player to send X messages per 10 seconds. +# chat_message_limit_per_10sec float 10.0 + +# Kick player if send more than X messages per 10 seconds. +# chat_message_limit_trigger_kick int 50 + [**Physics] movement_acceleration_default (Default acceleration) float 3 diff --git a/minetest.conf.example b/minetest.conf.example index 9c8015625..b1b202786 100644 --- a/minetest.conf.example +++ b/minetest.conf.example @@ -933,6 +933,18 @@ # type: float # server_map_save_interval = 5.3 +# Set the maximum character length of a chat message sent by clients. (0 to disable) +# type: integer +# chat_message_max_size = 500 + +# Limit a single player to send X messages per 10 seconds. (0 to disable) +# type: float +# chat_message_limit_per_10sec = 8.0 + +# Kick player if send more than X messages per 10 seconds. (0 to disable) +# type: integer +# chat_message_limit_trigger_kick = 50 + ### Physics # type: float @@ -1523,7 +1535,7 @@ # profiler.default_report_format = txt # The file path relative to your worldpath in which profiles will be saved to. -# +# # type: string # profiler.report_path = "" diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index 4520bac2f..00c233a42 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -285,6 +285,9 @@ void set_default_settings(Settings *settings) settings->setDefault("server_unload_unused_data_timeout", "29"); settings->setDefault("max_objects_per_block", "49"); settings->setDefault("server_map_save_interval", "5.3"); + settings->setDefault("chat_message_max_size", "500"); + settings->setDefault("chat_message_limit_per_10sec", "8.0"); + settings->setDefault("chat_message_limit_trigger_kick", "50"); settings->setDefault("sqlite_synchronous", "2"); settings->setDefault("full_block_send_enable_min_time_from_building", "2.0"); settings->setDefault("dedicated_server_step", "0.1"); diff --git a/src/network/serverpackethandler.cpp b/src/network/serverpackethandler.cpp index 1bcb78a8a..a8bfd9068 100644 --- a/src/network/serverpackethandler.cpp +++ b/src/network/serverpackethandler.cpp @@ -1065,7 +1065,7 @@ void Server::handleCommand_ChatMessage(NetworkPacket* pkt) std::wstring wname = narrow_to_wide(name); std::wstring answer_to_sender = handleChat(name, wname, message, - true, pkt->getPeerId()); + true, dynamic_cast(player)); if (!answer_to_sender.empty()) { // Send the answer to sender SendChatMessage(pkt->getPeerId(), answer_to_sender); @@ -1656,16 +1656,16 @@ void Server::handleCommand_Interact(NetworkPacket* pkt) } } // action == 4 - + /* 5: rightclick air */ else if (action == 5) { ItemStack item = playersao->getWieldedItem(); - - actionstream << player->getName() << " activates " + + actionstream << player->getName() << " activates " << item.name << std::endl; - + if (m_script->item_OnSecondaryUse( item, playersao)) { if( playersao->setWieldedItem(item)) { diff --git a/src/player.cpp b/src/player.cpp index 5949712a5..fd72d63b6 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -227,10 +227,25 @@ void Player::clearHud() } } +// static config cache for remoteplayer +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(IGameDef *gamedef, const char *name): Player(gamedef, name), - m_sao(NULL) + m_sao(NULL), + m_last_chat_message_sent(time(NULL)), + m_chat_message_allowance(5.0f), + m_message_rate_overhead(0) { + if (!RemotePlayer::m_setting_cache_loaded) { + RemotePlayer::m_setting_chat_message_limit_per_10sec = + g_settings->getFloat("chat_message_limit_per_10sec"); + RemotePlayer::m_setting_chat_message_limit_trigger_kick = + g_settings->getU16("chat_message_limit_trigger_kick"); + RemotePlayer::m_setting_cache_loaded = true; + } movement_acceleration_default = g_settings->getFloat("movement_acceleration_default") * BS; movement_acceleration_air = g_settings->getFloat("movement_acceleration_air") * BS; movement_acceleration_fast = g_settings->getFloat("movement_acceleration_fast") * BS; @@ -304,3 +319,42 @@ void RemotePlayer::setPosition(const v3f &position) m_sao->setBasePosition(position); } +const RemotePlayerChatResult RemotePlayer::canSendChatMessage() +{ + // Rate limit messages + u32 now = time(NULL); + float time_passed = now - m_last_chat_message_sent; + m_last_chat_message_sent = now; + + // If this feature is disabled + if (m_setting_chat_message_limit_per_10sec <= 0.0) { + return RPLAYER_CHATRESULT_OK; + } + + m_chat_message_allowance += time_passed * (m_setting_chat_message_limit_per_10sec / 8.0f); + if (m_chat_message_allowance > m_setting_chat_message_limit_per_10sec) { + m_chat_message_allowance = m_setting_chat_message_limit_per_10sec; + } + + if (m_chat_message_allowance < 1.0f) { + infostream << "Player " << m_name + << " chat limited due to excessive message amount." << std::endl; + + // Kick player if flooding is too intensive + m_message_rate_overhead++; + if (m_message_rate_overhead > RemotePlayer::m_setting_chat_message_limit_trigger_kick) { + return RPLAYER_CHATRESULT_KICK; + } + + return RPLAYER_CHATRESULT_FLOODING; + } + + // Reinit message overhead + if (m_message_rate_overhead > 0) { + m_message_rate_overhead = 0; + } + + m_chat_message_allowance -= 1.0f; + return RPLAYER_CHATRESULT_OK; +} + diff --git a/src/player.h b/src/player.h index eab00bb04..f38effa9d 100644 --- a/src/player.h +++ b/src/player.h @@ -439,7 +439,11 @@ private: Mutex m_mutex; }; - +enum RemotePlayerChatResult { + RPLAYER_CHATRESULT_OK, + RPLAYER_CHATRESULT_FLOODING, + RPLAYER_CHATRESULT_KICK, +}; /* Player on the server */ @@ -457,8 +461,18 @@ public: { m_sao = sao; } void setPosition(const v3f &position); + const RemotePlayerChatResult canSendChatMessage(); + private: PlayerSAO *m_sao; + + static bool m_setting_cache_loaded; + static float m_setting_chat_message_limit_per_10sec; + static u16 m_setting_chat_message_limit_trigger_kick; + + u32 m_last_chat_message_sent; + float m_chat_message_allowance; + u16 m_message_rate_overhead; }; #endif diff --git a/src/server.cpp b/src/server.cpp index fb241f179..c615aee13 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -358,6 +358,7 @@ Server::Server( add_legacy_abms(m_env, m_nodedef); m_liquid_transform_every = g_settings->getFloat("liquid_update"); + m_max_chatmessage_length = g_settings->getU16("chat_message_max_size"); } Server::~Server() @@ -2734,8 +2735,7 @@ void Server::handleChatInterfaceEvent(ChatEvent *evt) } std::wstring Server::handleChat(const std::string &name, const std::wstring &wname, - const std::wstring &wmessage, bool check_shout_priv, - u16 peer_id_to_avoid_sending) + const std::wstring &wmessage, bool check_shout_priv, RemotePlayer *player) { // If something goes wrong, this player is to blame RollbackScopeActor rollback_scope(m_rollback, @@ -2753,6 +2753,26 @@ std::wstring Server::handleChat(const std::string &name, const std::wstring &wna if (ate) return L""; + switch (player->canSendChatMessage()) { + case RPLAYER_CHATRESULT_FLOODING: { + std::wstringstream ws; + ws << L"You cannot send more messages. You are limited to " + << g_settings->getFloat("chat_message_limit_per_10sec") + << " messages per 10 seconds."; + return ws.str(); + } + case RPLAYER_CHATRESULT_KICK: + DenyAccess_Legacy(player->peer_id, L"You have been kicked due to message flooding."); + return L""; + case RPLAYER_CHATRESULT_OK: break; + default: FATAL_ERROR("Unhandled chat filtering result found."); + } + + if (m_max_chatmessage_length > 0 && wmessage.length() > m_max_chatmessage_length) { + return L"Your message exceed the maximum chat message limit set on the server. " + "It was refused. Send a shorter message"; + } + // Commands are implemented in Lua, so only catch invalid // commands that were not "eaten" and send an error back if (wmessage[0] == L'/') { @@ -2787,6 +2807,7 @@ std::wstring Server::handleChat(const std::string &name, const std::wstring &wna std::vector clients = m_clients.getClientIDs(); + u16 peer_id_to_avoid_sending = (player ? player->peer_id : PEER_ID_INEXISTENT); for (u16 i = 0; i < clients.size(); i++) { u16 cid = clients[i]; if (cid != peer_id_to_avoid_sending) diff --git a/src/server.h b/src/server.h index 7ee15a463..3ad894b38 100644 --- a/src/server.h +++ b/src/server.h @@ -487,7 +487,7 @@ private: std::wstring handleChat(const std::string &name, const std::wstring &wname, const std::wstring &wmessage, bool check_shout_priv = false, - u16 peer_id_to_avoid_sending = PEER_ID_INEXISTENT); + RemotePlayer *player = NULL); void handleAdminChat(const ChatEventChat *evt); v3f findSpawnPos(); @@ -522,6 +522,7 @@ private: // If true, do not allow multiple players and hide some multiplayer // functionality bool m_simple_singleplayer_mode; + u16 m_max_chatmessage_length; // Thread can set; step() will throw as ServerError MutexedVariable m_async_fatal_error; -- cgit v1.2.3 From 667975fe3adee935a3f4d2b1a421a295771c664d Mon Sep 17 00:00:00 2001 From: Loic Blot Date: Thu, 6 Oct 2016 08:48:20 +0200 Subject: Use more unordered_maps to improve performance in c++11 builds --- src/client.cpp | 9 +++------ src/client.h | 6 +++--- src/clientobject.cpp | 10 ++++------ src/clientobject.h | 3 ++- src/content_cao.cpp | 2 +- src/network/clientpackethandler.cpp | 4 +--- src/script/lua_api/l_mapgen.cpp | 4 ++-- src/server.cpp | 8 ++++---- src/util/string.h | 3 ++- 9 files changed, 22 insertions(+), 27 deletions(-) (limited to 'src/network') diff --git a/src/client.cpp b/src/client.cpp index a599e21dc..63653998a 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -623,10 +623,8 @@ void Client::step(float dtime) Update positions of sounds attached to objects */ { - for(std::map::iterator - i = m_sounds_to_objects.begin(); - i != m_sounds_to_objects.end(); ++i) - { + for(UNORDERED_MAP::iterator i = m_sounds_to_objects.begin(); + i != m_sounds_to_objects.end(); ++i) { int client_id = i->first; u16 object_id = i->second; ClientActiveObject *cao = m_env.getActiveObject(object_id); @@ -645,8 +643,7 @@ void Client::step(float dtime) m_removed_sounds_check_timer = 0; // Find removed sounds and clear references to them std::vector removed_server_ids; - for(std::map::iterator - i = m_sounds_server_to_client.begin(); + for(UNORDERED_MAP::iterator i = m_sounds_server_to_client.begin(); i != m_sounds_server_to_client.end();) { s32 server_id = i->first; int client_id = i->second; diff --git a/src/client.h b/src/client.h index fb479068f..a71c1dcbc 100644 --- a/src/client.h +++ b/src/client.h @@ -663,11 +663,11 @@ private: // Sounds float m_removed_sounds_check_timer; // Mapping from server sound ids to our sound ids - std::map m_sounds_server_to_client; + UNORDERED_MAP m_sounds_server_to_client; // And the other way! - std::map m_sounds_client_to_server; + UNORDERED_MAP m_sounds_client_to_server; // And relations to objects - std::map m_sounds_to_objects; + UNORDERED_MAP m_sounds_to_objects; // Privileges UNORDERED_SET m_privileges; diff --git a/src/clientobject.cpp b/src/clientobject.cpp index a11757ea6..ff3f47187 100644 --- a/src/clientobject.cpp +++ b/src/clientobject.cpp @@ -43,12 +43,11 @@ ClientActiveObject* ClientActiveObject::create(ActiveObjectType type, IGameDef *gamedef, ClientEnvironment *env) { // Find factory function - std::map::iterator n; - n = m_types.find(type); + UNORDERED_MAP::iterator n = m_types.find(type); if(n == m_types.end()) { // If factory is not found, just return. - warningstream<<"ClientActiveObject: No factory for type=" - <<(int)type< +#include "util/cpp11_container.h" /* @@ -103,7 +104,7 @@ protected: ClientEnvironment *m_env; private: // Used for creating objects based on type - static std::map m_types; + static UNORDERED_MAP m_types; }; struct DistanceSortedActiveObject diff --git a/src/content_cao.cpp b/src/content_cao.cpp index a141690f6..33dae6822 100644 --- a/src/content_cao.cpp +++ b/src/content_cao.cpp @@ -51,7 +51,7 @@ struct ToolCapabilities; #define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")" -std::map ClientActiveObject::m_types; +UNORDERED_MAP ClientActiveObject::m_types; SmoothTranslator::SmoothTranslator(): vect_old(0,0,0), diff --git a/src/network/clientpackethandler.cpp b/src/network/clientpackethandler.cpp index 48c573da5..6d42edd7d 100644 --- a/src/network/clientpackethandler.cpp +++ b/src/network/clientpackethandler.cpp @@ -812,9 +812,7 @@ void Client::handleCommand_StopSound(NetworkPacket* pkt) *pkt >> server_id; - std::map::iterator i = - m_sounds_server_to_client.find(server_id); - + UNORDERED_MAP::iterator i = m_sounds_server_to_client.find(server_id); if (i != m_sounds_server_to_client.end()) { int client_id = i->second; m_sound->stopSound(client_id); diff --git a/src/script/lua_api/l_mapgen.cpp b/src/script/lua_api/l_mapgen.cpp index a176f4f52..da8e71cdc 100644 --- a/src/script/lua_api/l_mapgen.cpp +++ b/src/script/lua_api/l_mapgen.cpp @@ -244,7 +244,7 @@ bool read_schematic_def(lua_State *L, int index, schem->schemdata = new MapNode[numnodes]; size_t names_base = names->size(); - std::map name_id_map; + UNORDERED_MAP name_id_map; u32 i = 0; for (lua_pushnil(L); lua_next(L, -2); i++, lua_pop(L, 1)) { @@ -266,7 +266,7 @@ bool read_schematic_def(lua_State *L, int index, u8 param2 = getintfield_default(L, -1, "param2", 0); //// Find or add new nodename-to-ID mapping - std::map::iterator it = name_id_map.find(name); + UNORDERED_MAP::iterator it = name_id_map.find(name); content_t name_index; if (it != name_id_map.end()) { name_index = it->second; diff --git a/src/server.cpp b/src/server.cpp index a8494f76e..e9983ba11 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -794,7 +794,7 @@ void Server::AsyncRunStep(bool initial_step) // Key = object id // Value = data sent by object - std::map* > buffered_messages; + UNORDERED_MAP* > buffered_messages; // Get active object messages from environment for(;;) { @@ -803,7 +803,7 @@ void Server::AsyncRunStep(bool initial_step) break; std::vector* message_list = NULL; - std::map* >::iterator n; + UNORDERED_MAP* >::iterator n; n = buffered_messages.find(aom.id); if (n == buffered_messages.end()) { message_list = new std::vector; @@ -824,7 +824,7 @@ void Server::AsyncRunStep(bool initial_step) std::string reliable_data; std::string unreliable_data; // Go through all objects in message buffer - for (std::map* >::iterator + for (UNORDERED_MAP* >::iterator j = buffered_messages.begin(); j != buffered_messages.end(); ++j) { // If object is not known by client, skip it @@ -868,7 +868,7 @@ void Server::AsyncRunStep(bool initial_step) m_clients.unlock(); // Clear buffered_messages - for(std::map* >::iterator + for(UNORDERED_MAP* >::iterator i = buffered_messages.begin(); i != buffered_messages.end(); ++i) { delete i->second; diff --git a/src/util/string.h b/src/util/string.h index 724543a36..572c37150 100644 --- a/src/util/string.h +++ b/src/util/string.h @@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #define UTIL_STRING_HEADER #include "irrlichttypes_bloated.h" +#include "cpp11_container.h" #include #include #include @@ -54,7 +55,7 @@ with this program; if not, write to the Free Software Foundation, Inc., (((unsigned char)(x) < 0xe0) ? 2 : \ (((unsigned char)(x) < 0xf0) ? 3 : 4)) -typedef std::map StringMap; +typedef UNORDERED_MAP StringMap; struct FlagDesc { const char *name; -- cgit v1.2.3 From 155288ee981c70f505526347cb2bcda4df1c8e6b Mon Sep 17 00:00:00 2001 From: Loic Blot Date: Thu, 6 Oct 2016 19:20:12 +0200 Subject: use unordered containers where possible (patch 4 on X) Also remove some unused parameters/functions --- src/content_sao.cpp | 28 ++++++++++++++++++---------- src/content_sao.h | 5 +++-- src/guiFormSpecMenu.h | 4 +--- src/map.h | 1 + src/mapblock_mesh.cpp | 24 ++++++++++-------------- src/mapblock_mesh.h | 15 ++++++++------- src/network/serverpackethandler.cpp | 4 +--- src/script/cpp_api/s_async.cpp | 3 ++- src/script/cpp_api/s_async.h | 2 +- src/server.cpp | 21 +++++++++------------ src/server.h | 16 ++++++---------- src/util/numeric.cpp | 2 +- src/util/numeric.h | 37 ++----------------------------------- 13 files changed, 63 insertions(+), 99 deletions(-) (limited to 'src/network') diff --git a/src/content_sao.cpp b/src/content_sao.cpp index 1e7e788e9..895c26044 100644 --- a/src/content_sao.cpp +++ b/src/content_sao.cpp @@ -347,8 +347,10 @@ void LuaEntitySAO::step(float dtime, bool send_recommended) if(m_bone_position_sent == false){ m_bone_position_sent = true; - for(std::map >::const_iterator ii = m_bone_position.begin(); ii != m_bone_position.end(); ++ii){ - std::string str = gob_cmd_update_bone_position((*ii).first, (*ii).second.X, (*ii).second.Y); + for (UNORDERED_MAP >::const_iterator + ii = m_bone_position.begin(); ii != m_bone_position.end(); ++ii){ + std::string str = gob_cmd_update_bone_position((*ii).first, + (*ii).second.X, (*ii).second.Y); // create message and add to list ActiveObjectMessage aom(getId(), true, str); m_messages_out.push(aom); @@ -383,8 +385,10 @@ std::string LuaEntitySAO::getClientInitializationData(u16 protocol_version) os< >::const_iterator ii = m_bone_position.begin(); ii != m_bone_position.end(); ++ii){ - os< >::const_iterator + ii = m_bone_position.begin(); ii != m_bone_position.end(); ++ii) { + os << serializeLongString(gob_cmd_update_bone_position((*ii).first, + (*ii).second.X, (*ii).second.Y)); // m_bone_position.size } os< >::const_iterator ii = m_bone_position.begin(); ii != m_bone_position.end(); ++ii){ + for (UNORDERED_MAP >::const_iterator + ii = m_bone_position.begin(); ii != m_bone_position.end(); ++ii) { os< >::const_iterator ii = m_bone_position.begin(); ii != m_bone_position.end(); ++ii){ - std::string str = gob_cmd_update_bone_position((*ii).first, (*ii).second.X, (*ii).second.Y); + for (UNORDERED_MAP >::const_iterator + ii = m_bone_position.begin(); ii != m_bone_position.end(); ++ii) { + std::string str = gob_cmd_update_bone_position((*ii).first, + (*ii).second.X, (*ii).second.Y); // create message and add to list ActiveObjectMessage aom(getId(), true, str); m_messages_out.push(aom); } } - if(m_attachment_sent == false){ + if (!m_attachment_sent){ 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 = gob_cmd_update_attachment(m_attachment_parent_id, + m_attachment_bone, m_attachment_position, m_attachment_rotation); // create message and add to list ActiveObjectMessage aom(getId(), true, str); m_messages_out.push(aom); diff --git a/src/content_sao.h b/src/content_sao.h index 44d40d332..ccae90b77 100644 --- a/src/content_sao.h +++ b/src/content_sao.h @@ -112,7 +112,7 @@ private: bool m_animation_loop; bool m_animation_sent; - std::map > m_bone_position; + UNORDERED_MAP > m_bone_position; bool m_bone_position_sent; int m_attachment_parent_id; @@ -321,7 +321,8 @@ private: bool m_animation_loop; bool m_animation_sent; - std::map > m_bone_position; // Stores position and rotation for each bone name + // Stores position and rotation for each bone name + UNORDERED_MAP > m_bone_position; bool m_bone_position_sent; int m_attachment_parent_id; diff --git a/src/guiFormSpecMenu.h b/src/guiFormSpecMenu.h index 21054b725..153720975 100644 --- a/src/guiFormSpecMenu.h +++ b/src/guiFormSpecMenu.h @@ -409,8 +409,6 @@ protected: std::vector > > m_dropdowns; ItemSpec *m_selected_item; - f32 m_timer1; - f32 m_timer2; u32 m_selected_amount; bool m_selected_dragging; @@ -462,7 +460,7 @@ private: GUITable::TableOptions table_options; GUITable::TableColumns table_columns; // used to restore table selection/scroll/treeview state - std::map table_dyndata; + UNORDERED_MAP table_dyndata; } parserData; typedef struct { diff --git a/src/map.h b/src/map.h index 13775fde1..c73fa92bf 100644 --- a/src/map.h +++ b/src/map.h @@ -32,6 +32,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "voxel.h" #include "modifiedstate.h" #include "util/container.h" +#include "util/cpp11_container.h" #include "nodetimer.h" #include "map_settings_manager.h" diff --git a/src/mapblock_mesh.cpp b/src/mapblock_mesh.cpp index a11fb5887..00f83e7ab 100644 --- a/src/mapblock_mesh.cpp +++ b/src/mapblock_mesh.cpp @@ -1033,7 +1033,7 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset): m_enable_shaders = data->m_use_shaders; m_use_tangent_vertices = data->m_use_tangent_vertices; m_enable_vbo = g_settings->getBool("enable_vbo"); - + if (g_settings->getBool("enable_minimap")) { m_minimap_mapblock = new MinimapMapblock; m_minimap_mapblock->getMinimapNodes( @@ -1298,10 +1298,8 @@ bool MapBlockMesh::animate(bool faraway, float time, int crack, u32 daynight_rat // Cracks if(crack != m_last_crack) { - for(std::map::iterator - i = m_crack_materials.begin(); - i != m_crack_materials.end(); ++i) - { + for (UNORDERED_MAP::iterator i = m_crack_materials.begin(); + i != m_crack_materials.end(); ++i) { scene::IMeshBuffer *buf = m_mesh->getMeshBuffer(i->first); std::string basename = i->second; @@ -1315,9 +1313,9 @@ bool MapBlockMesh::animate(bool faraway, float time, int crack, u32 daynight_rat // If the current material is also animated, // update animation info - std::map::iterator anim_iter = - m_animation_tiles.find(i->first); - if(anim_iter != m_animation_tiles.end()){ + UNORDERED_MAP::iterator anim_iter = + m_animation_tiles.find(i->first); + if (anim_iter != m_animation_tiles.end()){ TileSpec &tile = anim_iter->second; tile.texture = new_texture; tile.texture_id = new_texture_id; @@ -1330,10 +1328,8 @@ bool MapBlockMesh::animate(bool faraway, float time, int crack, u32 daynight_rat } // Texture animation - for(std::map::iterator - i = m_animation_tiles.begin(); - i != m_animation_tiles.end(); ++i) - { + for (UNORDERED_MAP::iterator i = m_animation_tiles.begin(); + i != m_animation_tiles.end(); ++i) { const TileSpec &tile = i->second; // Figure out current frame int frameoffset = m_animation_frame_offsets[i->first]; @@ -1443,7 +1439,7 @@ void MeshCollector::append(const TileSpec &tile, vertices[i].Color, vertices[i].TCoords); p->vertices.push_back(vert); } - } + } for (u32 i = 0; i < numIndices; i++) { u32 j = indices[i] + vertex_count; @@ -1499,7 +1495,7 @@ void MeshCollector::append(const TileSpec &tile, vertices[i].Normal, c, vertices[i].TCoords); p->vertices.push_back(vert); } - } + } for (u32 i = 0; i < numIndices; i++) { u32 j = indices[i] + vertex_count; diff --git a/src/mapblock_mesh.h b/src/mapblock_mesh.h index f89fbe669..8376468da 100644 --- a/src/mapblock_mesh.h +++ b/src/mapblock_mesh.h @@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "irrlichttypes_extrabloated.h" #include "client/tile.h" #include "voxel.h" +#include "util/cpp11_container.h" #include class IGameDef; @@ -121,7 +122,7 @@ public: if(m_animation_force_timer > 0) m_animation_force_timer--; } - + void updateCameraOffset(v3s16 camera_offset); private: @@ -144,20 +145,20 @@ private: // Last crack value passed to animate() int m_last_crack; // Maps mesh buffer (i.e. material) indices to base texture names - std::map m_crack_materials; + UNORDERED_MAP m_crack_materials; // Animation info: texture animationi // Maps meshbuffers to TileSpecs - std::map m_animation_tiles; - std::map m_animation_frames; // last animation frame - std::map m_animation_frame_offsets; - + UNORDERED_MAP m_animation_tiles; + UNORDERED_MAP m_animation_frames; // last animation frame + UNORDERED_MAP m_animation_frame_offsets; + // Animation info: day/night transitions // Last daynight_ratio value passed to animate() u32 m_last_daynight_ratio; // For each meshbuffer, maps vertex indices to (day,night) pairs std::map > > m_daynight_diffs; - + // Camera offset info -> do we have to translate the mesh? v3s16 m_camera_offset; }; diff --git a/src/network/serverpackethandler.cpp b/src/network/serverpackethandler.cpp index a8bfd9068..f9061cc4f 100644 --- a/src/network/serverpackethandler.cpp +++ b/src/network/serverpackethandler.cpp @@ -1693,9 +1693,7 @@ void Server::handleCommand_RemovedSounds(NetworkPacket* pkt) *pkt >> id; - std::map::iterator i = - m_playing_sounds.find(id); - + UNORDERED_MAP::iterator i = m_playing_sounds.find(id); if (i == m_playing_sounds.end()) continue; diff --git a/src/script/cpp_api/s_async.cpp b/src/script/cpp_api/s_async.cpp index 9bf3fcf49..1fb84fab6 100644 --- a/src/script/cpp_api/s_async.cpp +++ b/src/script/cpp_api/s_async.cpp @@ -81,6 +81,7 @@ bool AsyncEngine::registerFunction(const char* name, lua_CFunction func) if (initDone) { return false; } + functionList[name] = func; return true; } @@ -203,7 +204,7 @@ void AsyncEngine::pushFinishedJobs(lua_State* L) { /******************************************************************************/ void AsyncEngine::prepareEnvironment(lua_State* L, int top) { - for (std::map::iterator it = functionList.begin(); + for (UNORDERED_MAP::iterator it = functionList.begin(); it != functionList.end(); it++) { lua_pushstring(L, it->first.c_str()); lua_pushcfunction(L, it->second); diff --git a/src/script/cpp_api/s_async.h b/src/script/cpp_api/s_async.h index 8d612d58c..016381e5f 100644 --- a/src/script/cpp_api/s_async.h +++ b/src/script/cpp_api/s_async.h @@ -132,7 +132,7 @@ private: bool initDone; // Internal store for registred functions - std::map functionList; + UNORDERED_MAP functionList; // Internal counter to create job IDs unsigned int jobIdCounter; diff --git a/src/server.cpp b/src/server.cpp index 639e6462a..2dd070b1a 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -868,7 +868,7 @@ void Server::AsyncRunStep(bool initial_step) m_clients.unlock(); // Clear buffered_messages - for(UNORDERED_MAP* >::iterator + for (UNORDERED_MAP* >::iterator i = buffered_messages.begin(); i != buffered_messages.end(); ++i) { delete i->second; @@ -2016,16 +2016,15 @@ s32 Server::playSound(const SimpleSoundSpec &spec, void Server::stopSound(s32 handle) { // Get sound reference - std::map::iterator i = - m_playing_sounds.find(handle); - if(i == m_playing_sounds.end()) + UNORDERED_MAP::iterator i = m_playing_sounds.find(handle); + if (i == m_playing_sounds.end()) return; ServerPlayingSound &psound = i->second; NetworkPacket pkt(TOCLIENT_STOP_SOUND, 4); pkt << handle; - for(std::set::iterator i = psound.clients.begin(); + for (UNORDERED_SET::iterator i = psound.clients.begin(); i != psound.clients.end(); ++i) { // Send as reliable m_clients.send(*i, 0, &pkt, true); @@ -2322,7 +2321,7 @@ void Server::sendMediaAnnouncement(u16 peer_id) NetworkPacket pkt(TOCLIENT_ANNOUNCE_MEDIA, 0, peer_id); pkt << (u16) m_media.size(); - for (std::map::iterator i = m_media.begin(); + for (UNORDERED_MAP::iterator i = m_media.begin(); i != m_media.end(); ++i) { pkt << i->first << i->second.sha1_digest; } @@ -2367,7 +2366,7 @@ void Server::sendRequestedMedia(u16 peer_id, i != tosend.end(); ++i) { const std::string &name = *i; - if(m_media.find(name) == m_media.end()) { + if (m_media.find(name) == m_media.end()) { errorstream<<"Server::sendRequestedMedia(): Client asked for " <<"unknown file \""<<(name)<<"\""<::iterator - i = m_playing_sounds.begin(); - i != m_playing_sounds.end();) - { + for (UNORDERED_MAP::iterator + i = m_playing_sounds.begin(); i != m_playing_sounds.end();) { ServerPlayingSound &psound = i->second; psound.clients.erase(peer_id); - if(psound.clients.empty()) + if (psound.clients.empty()) m_playing_sounds.erase(i++); else ++i; diff --git a/src/server.h b/src/server.h index 3ad894b38..34427a71a 100644 --- a/src/server.h +++ b/src/server.h @@ -157,7 +157,7 @@ struct ServerSoundParams struct ServerPlayingSound { ServerSoundParams params; - std::set clients; // peer ids + UNORDERED_SET clients; // peer ids }; class Server : public con::PeerHandler, public MapEventReceiver, @@ -243,11 +243,9 @@ public: std::wstring getStatusString(); // read shutdown state - inline bool getShutdownRequested() - { return m_shutdown_requested; } + inline bool getShutdownRequested() const { return m_shutdown_requested; } // request server to shutdown - inline void requestShutdown() { m_shutdown_requested = true; } void requestShutdown(const std::string &msg, bool reconnect) { m_shutdown_requested = true; @@ -323,8 +321,7 @@ public: const ModSpec* getModSpec(const std::string &modname) const; void getModNames(std::vector &modlist); std::string getBuiltinLuaPath(); - inline std::string getWorldPath() const - { return m_path_world; } + inline std::string getWorldPath() const { return m_path_world; } inline bool isSingleplayer() { return m_simple_singleplayer_mode; } @@ -356,8 +353,7 @@ public: bool setSky(Player *player, const video::SColor &bgcolor, const std::string &type, const std::vector ¶ms); - bool overrideDayNightRatio(Player *player, bool do_override, - float brightness); + bool overrideDayNightRatio(Player *player, bool do_override, float brightness); /* con::PeerHandler implementation. */ void peerAdded(con::Peer *peer); @@ -654,12 +650,12 @@ private: u16 m_ignore_map_edit_events_peer_id; // media files known to server - std::map m_media; + UNORDERED_MAP m_media; /* Sounds */ - std::map m_playing_sounds; + UNORDERED_MAP m_playing_sounds; s32 m_next_sound_id; /* diff --git a/src/util/numeric.cpp b/src/util/numeric.cpp index 42ebd9022..6a7bfcac9 100644 --- a/src/util/numeric.cpp +++ b/src/util/numeric.cpp @@ -27,7 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include -std::map > FacePositionCache::m_cache; +UNORDERED_MAP > FacePositionCache::m_cache; Mutex FacePositionCache::m_cache_mutex; // Calculate the borders of a "d-radius" cube // TODO: Make it work without mutex and data races, probably thread-local diff --git a/src/util/numeric.h b/src/util/numeric.h index 615327864..4cdc254c3 100644 --- a/src/util/numeric.h +++ b/src/util/numeric.h @@ -26,8 +26,8 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "../irr_v3d.h" #include "../irr_aabb3d.h" #include "../threading/mutex.h" +#include "cpp11_container.h" #include -#include #include @@ -41,26 +41,10 @@ public: static std::vector getFacePositions(u16 d); private: static void generateFacePosition(u16 d); - static std::map > m_cache; + static UNORDERED_MAP > m_cache; static Mutex m_cache_mutex; }; -class IndentationRaiser -{ -public: - IndentationRaiser(u16 *indentation) - { - m_indentation = indentation; - (*m_indentation)++; - } - ~IndentationRaiser() - { - (*m_indentation)--; - } -private: - u16 *m_indentation; -}; - inline s16 getContainerPos(s16 p, s16 d) { return (p>=0 ? p : p-d+1) / d; @@ -149,23 +133,6 @@ inline bool isInArea(v3s16 p, v3s16 d) #define rangelim(d, min, max) ((d) < (min) ? (min) : ((d)>(max)?(max):(d))) #define myfloor(x) ((x) > 0.0 ? (int)(x) : (int)(x) - 1) -inline v3s16 arealim(v3s16 p, s16 d) -{ - if(p.X < 0) - p.X = 0; - if(p.Y < 0) - p.Y = 0; - if(p.Z < 0) - p.Z = 0; - if(p.X > d-1) - p.X = d-1; - if(p.Y > d-1) - p.Y = d-1; - if(p.Z > d-1) - p.Z = d-1; - return p; -} - // The naive swap performs better than the xor version #define SWAP(t, x, y) do { \ t temp = x; \ -- cgit v1.2.3 From 8bcd10b872bc88c6f474913d6efb8d53c50c5ae1 Mon Sep 17 00:00:00 2001 From: Loic Blot Date: Sat, 8 Oct 2016 10:38:04 +0200 Subject: Player/LocalPlayer/RemotePlayer inheritance cleanup (part 1 on X) * LocalPlayer take ownership of maxHudId as it's the only caller * RemotePlayer take ownership of day night ratio as it's the only user * Pass getPlayerControl as const reference to prevent object copy on each call (perf improvement in ObjectRef::l_get_player_control call) * getPlayerSAO is now only RemotePlayer call * get/setHotbarItemCount is now RemotePlayer owned * Server: Use RemotePlayer instead of Player object on concerned call to properly fix the object type * PlayerSAO now uses RemotePlayer instead of Player because it's only server side * ObjectRef::getplayer also returns RemotePlayer as it's linked with PlayerSAO --- src/content_sao.cpp | 7 ++--- src/content_sao.h | 14 +++------ src/game.cpp | 2 +- src/localplayer.h | 2 ++ src/network/clientpackethandler.cpp | 6 ++-- src/network/serverpackethandler.cpp | 31 ++++++++++++++----- src/player.h | 62 ++++++++++++++----------------------- src/script/lua_api/l_env.cpp | 4 +-- src/script/lua_api/l_object.cpp | 16 +++++----- src/script/lua_api/l_object.h | 3 +- src/server.cpp | 52 ++++++++++++++----------------- src/server.h | 13 ++++---- 12 files changed, 103 insertions(+), 109 deletions(-) (limited to 'src/network') diff --git a/src/content_sao.cpp b/src/content_sao.cpp index 895c26044..2317cbdfe 100644 --- a/src/content_sao.cpp +++ b/src/content_sao.cpp @@ -751,7 +751,7 @@ bool LuaEntitySAO::collideWithObjects(){ // No prototype, PlayerSAO does not need to be deserialized -PlayerSAO::PlayerSAO(ServerEnvironment *env_, Player *player_, u16 peer_id_, +PlayerSAO::PlayerSAO(ServerEnvironment *env_, RemotePlayer *player_, u16 peer_id_, const std::set &privs, bool is_singleplayer): ServerActiveObject(env_, v3f(0,0,0)), m_player(player_), @@ -833,11 +833,10 @@ void PlayerSAO::addedToEnvironment(u32 dtime_s) void PlayerSAO::removingFromEnvironment() { ServerActiveObject::removingFromEnvironment(); - if(m_player->getPlayerSAO() == this) - { + if (m_player->getPlayerSAO() == this) { m_player->setPlayerSAO(NULL); m_player->peer_id = 0; - m_env->savePlayer((RemotePlayer*)m_player); + m_env->savePlayer(m_player); m_env->removePlayer(m_player); } } diff --git a/src/content_sao.h b/src/content_sao.h index ccae90b77..c97db4922 100644 --- a/src/content_sao.h +++ b/src/content_sao.h @@ -160,7 +160,7 @@ public: class PlayerSAO : public ServerActiveObject { public: - PlayerSAO(ServerEnvironment *env_, Player *player_, u16 peer_id_, + PlayerSAO(ServerEnvironment *env_, RemotePlayer *player_, u16 peer_id_, const std::set &privs, bool is_singleplayer); ~PlayerSAO(); ActiveObjectType getType() const @@ -231,14 +231,8 @@ public: void disconnected(); - Player* getPlayer() - { - return m_player; - } - u16 getPeerID() const - { - return m_peer_id; - } + RemotePlayer* getPlayer() { return m_player; } + u16 getPeerID() const { return m_peer_id; } // Cheat prevention @@ -291,7 +285,7 @@ public: private: std::string getPropertyPacket(); - Player *m_player; + RemotePlayer *m_player; u16 m_peer_id; Inventory *m_inventory; s16 m_damage; diff --git a/src/game.cpp b/src/game.cpp index 22d9ffef6..5bb08e27a 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -2851,7 +2851,7 @@ void Game::processItemSelection(u16 *new_playeritem) s32 wheel = input->getMouseWheel(); u16 max_item = MYMIN(PLAYER_INVENTORY_SIZE - 1, - player->hud_hotbar_itemcount - 1); + player->hud_hotbar_itemcount - 1); s32 dir = wheel; diff --git a/src/localplayer.h b/src/localplayer.h index 3ae0c4e51..8897adc5e 100644 --- a/src/localplayer.h +++ b/src/localplayer.h @@ -80,6 +80,8 @@ public: m_cao = toset; } + u32 maxHudId() const { return hud.size(); } + private: void accelerateHorizontal(const v3f &target_speed, const f32 max_increase); void accelerateVertical(const v3f &target_speed, const f32 max_increase); diff --git a/src/network/clientpackethandler.cpp b/src/network/clientpackethandler.cpp index 6d42edd7d..35e350f20 100644 --- a/src/network/clientpackethandler.cpp +++ b/src/network/clientpackethandler.cpp @@ -1122,7 +1122,7 @@ void Client::handleCommand_HudSetParam(NetworkPacket* pkt) *pkt >> param >> value; - Player *player = m_env.getLocalPlayer(); + LocalPlayer *player = m_env.getLocalPlayer(); assert(player != NULL); if (param == HUD_PARAM_HOTBAR_ITEMCOUNT && value.size() == 4) { @@ -1131,10 +1131,10 @@ void Client::handleCommand_HudSetParam(NetworkPacket* pkt) player->hud_hotbar_itemcount = hotbar_itemcount; } else if (param == HUD_PARAM_HOTBAR_IMAGE) { - ((LocalPlayer *) player)->hotbar_image = value; + player->hotbar_image = value; } else if (param == HUD_PARAM_HOTBAR_SELECTED_IMAGE) { - ((LocalPlayer *) player)->hotbar_selected_image = value; + player->hotbar_selected_image = value; } } diff --git a/src/network/serverpackethandler.cpp b/src/network/serverpackethandler.cpp index f9061cc4f..3fba7f720 100644 --- a/src/network/serverpackethandler.cpp +++ b/src/network/serverpackethandler.cpp @@ -800,7 +800,8 @@ void Server::handleCommand_PlayerPos(NetworkPacket* pkt) pitch = modulo360f(pitch); yaw = modulo360f(yaw); - Player *player = m_env->getPlayer(pkt->getPeerId()); + RemotePlayer *player = + dynamic_cast(m_env->getPlayer(pkt->getPeerId())); if (player == NULL) { errorstream << "Server::ProcessData(): Canceling: " "No player for peer_id=" << pkt->getPeerId() @@ -879,7 +880,9 @@ void Server::handleCommand_DeletedBlocks(NetworkPacket* pkt) void Server::handleCommand_InventoryAction(NetworkPacket* pkt) { - Player *player = m_env->getPlayer(pkt->getPeerId()); + RemotePlayer *player = + dynamic_cast(m_env->getPlayer(pkt->getPeerId())); + if (player == NULL) { errorstream << "Server::ProcessData(): Canceling: " "No player for peer_id=" << pkt->getPeerId() @@ -1078,7 +1081,9 @@ void Server::handleCommand_Damage(NetworkPacket* pkt) *pkt >> damage; - Player *player = m_env->getPlayer(pkt->getPeerId()); + RemotePlayer *player = + dynamic_cast(m_env->getPlayer(pkt->getPeerId())); + if (player == NULL) { errorstream << "Server::ProcessData(): Canceling: " "No player for peer_id=" << pkt->getPeerId() @@ -1112,7 +1117,9 @@ void Server::handleCommand_Breath(NetworkPacket* pkt) *pkt >> breath; - Player *player = m_env->getPlayer(pkt->getPeerId()); + RemotePlayer *player = + dynamic_cast(m_env->getPlayer(pkt->getPeerId())); + if (player == NULL) { errorstream << "Server::ProcessData(): Canceling: " "No player for peer_id=" << pkt->getPeerId() @@ -1224,7 +1231,9 @@ void Server::handleCommand_PlayerItem(NetworkPacket* pkt) if (pkt->getSize() < 2) return; - Player *player = m_env->getPlayer(pkt->getPeerId()); + RemotePlayer *player = + dynamic_cast(m_env->getPlayer(pkt->getPeerId())); + if (player == NULL) { errorstream << "Server::ProcessData(): Canceling: " "No player for peer_id=" << pkt->getPeerId() @@ -1299,7 +1308,9 @@ void Server::handleCommand_Interact(NetworkPacket* pkt) verbosestream << "TOSERVER_INTERACT: action=" << (int)action << ", item=" << item_i << ", pointed=" << pointed.dump() << std::endl; - Player *player = m_env->getPlayer(pkt->getPeerId()); + RemotePlayer *player = + dynamic_cast(m_env->getPlayer(pkt->getPeerId())); + if (player == NULL) { errorstream << "Server::ProcessData(): Canceling: " "No player for peer_id=" << pkt->getPeerId() @@ -1719,7 +1730,9 @@ void Server::handleCommand_NodeMetaFields(NetworkPacket* pkt) fields[fieldname] = pkt->readLongString(); } - Player *player = m_env->getPlayer(pkt->getPeerId()); + RemotePlayer *player = + dynamic_cast(m_env->getPlayer(pkt->getPeerId())); + if (player == NULL) { errorstream << "Server::ProcessData(): Canceling: " "No player for peer_id=" << pkt->getPeerId() @@ -1769,7 +1782,9 @@ void Server::handleCommand_InventoryFields(NetworkPacket* pkt) fields[fieldname] = pkt->readLongString(); } - Player *player = m_env->getPlayer(pkt->getPeerId()); + RemotePlayer *player = + dynamic_cast(m_env->getPlayer(pkt->getPeerId())); + if (player == NULL) { errorstream << "Server::ProcessData(): Canceling: " "No player for peer_id=" << pkt->getPeerId() diff --git a/src/player.h b/src/player.h index f38effa9d..fbd88fc71 100644 --- a/src/player.h +++ b/src/player.h @@ -233,16 +233,6 @@ public: return size; } - void setHotbarItemcount(s32 hotbar_itemcount) - { - hud_hotbar_itemcount = hotbar_itemcount; - } - - s32 getHotbarItemcount() - { - return hud_hotbar_itemcount; - } - void setHotbarImage(const std::string &name) { hud_hotbar_image = name; @@ -278,18 +268,6 @@ public: *params = m_sky_params; } - void overrideDayNightRatio(bool do_override, float ratio) - { - m_day_night_ratio_do_override = do_override; - m_day_night_ratio = ratio; - } - - void getDayNightRatio(bool *do_override, float *ratio) - { - *do_override = m_day_night_ratio_do_override; - *ratio = m_day_night_ratio; - } - void setLocalAnimations(v2s32 frames[4], float frame_speed) { for (int i = 0; i < 4; i++) @@ -309,11 +287,6 @@ public: return false; } - virtual PlayerSAO *getPlayerSAO() - { - return NULL; - } - virtual void setPlayerSAO(PlayerSAO *sao) { FATAL_ERROR("FIXME"); @@ -335,7 +308,7 @@ public: void setModified(const bool x) { m_dirty = x; - if (x == false) + if (!x) inventory.setModified(x); } @@ -391,10 +364,7 @@ public: std::string inventory_formspec; PlayerControl control; - PlayerControl getPlayerControl() - { - return control; - } + const PlayerControl& getPlayerControl() { return control; } u32 keyPressed; @@ -403,9 +373,6 @@ public: u32 addHud(HudElement* hud); HudElement* removeHud(u32 id); void clearHud(); - u32 maxHudId() { - return hud.size(); - } u32 hud_flags; s32 hud_hotbar_itemcount; @@ -429,9 +396,6 @@ protected: std::string m_sky_type; video::SColor m_sky_bgcolor; std::vector m_sky_params; - - bool m_day_night_ratio_do_override; - float m_day_night_ratio; private: // Protect some critical areas // hud for example can be modified by EmergeThread @@ -463,6 +427,25 @@ public: const RemotePlayerChatResult canSendChatMessage(); + void setHotbarItemcount(s32 hotbar_itemcount) + { + hud_hotbar_itemcount = hotbar_itemcount; + } + + s32 getHotbarItemcount() const { return hud_hotbar_itemcount; } + + void overrideDayNightRatio(bool do_override, float ratio) + { + m_day_night_ratio_do_override = do_override; + m_day_night_ratio = ratio; + } + + void getDayNightRatio(bool *do_override, float *ratio) + { + *do_override = m_day_night_ratio_do_override; + *ratio = m_day_night_ratio; + } + private: PlayerSAO *m_sao; @@ -473,6 +456,9 @@ private: u32 m_last_chat_message_sent; float m_chat_message_allowance; u16 m_message_rate_overhead; + + bool m_day_night_ratio_do_override; + float m_day_night_ratio; }; #endif diff --git a/src/script/lua_api/l_env.cpp b/src/script/lua_api/l_env.cpp index ebdea09e4..f6ea23e95 100644 --- a/src/script/lua_api/l_env.cpp +++ b/src/script/lua_api/l_env.cpp @@ -494,8 +494,8 @@ int ModApiEnvMod::l_get_player_by_name(lua_State *L) // Do it const char *name = luaL_checkstring(L, 1); - Player *player = env->getPlayer(name); - if(player == NULL){ + RemotePlayer *player = dynamic_cast(env->getPlayer(name)); + if (player == NULL){ lua_pushnil(L); return 1; } diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp index befae4253..4e1a1c159 100644 --- a/src/script/lua_api/l_object.cpp +++ b/src/script/lua_api/l_object.cpp @@ -107,7 +107,7 @@ PlayerSAO* ObjectRef::getplayersao(ObjectRef *ref) return (PlayerSAO*)obj; } -Player* ObjectRef::getplayer(ObjectRef *ref) +RemotePlayer* ObjectRef::getplayer(ObjectRef *ref) { PlayerSAO *playersao = getplayersao(ref); if (playersao == NULL) @@ -1212,8 +1212,8 @@ int ObjectRef::l_get_player_control(lua_State *L) lua_pushlstring(L, "", 0); return 1; } - // Do it - PlayerControl control = player->getPlayerControl(); + + const PlayerControl &control = player->getPlayerControl(); lua_newtable(L); lua_pushboolean(L, control.up); lua_setfield(L, -2, "up"); @@ -1467,7 +1467,7 @@ int ObjectRef::l_hud_set_flags(lua_State *L) { NO_MAP_LOCK_REQUIRED; ObjectRef *ref = checkobject(L, 1); - Player *player = getplayer(ref); + RemotePlayer *player = getplayer(ref); if (player == NULL) return 0; @@ -1519,7 +1519,7 @@ int ObjectRef::l_hud_set_hotbar_itemcount(lua_State *L) { NO_MAP_LOCK_REQUIRED; ObjectRef *ref = checkobject(L, 1); - Player *player = getplayer(ref); + RemotePlayer *player = getplayer(ref); if (player == NULL) return 0; @@ -1537,7 +1537,7 @@ int ObjectRef::l_hud_get_hotbar_itemcount(lua_State *L) { NO_MAP_LOCK_REQUIRED; ObjectRef *ref = checkobject(L, 1); - Player *player = getplayer(ref); + RemotePlayer *player = getplayer(ref); if (player == NULL) return 0; @@ -1677,7 +1677,7 @@ int ObjectRef::l_override_day_night_ratio(lua_State *L) { NO_MAP_LOCK_REQUIRED; ObjectRef *ref = checkobject(L, 1); - Player *player = getplayer(ref); + RemotePlayer *player = getplayer(ref); if (player == NULL) return 0; @@ -1700,7 +1700,7 @@ int ObjectRef::l_get_day_night_ratio(lua_State *L) { NO_MAP_LOCK_REQUIRED; ObjectRef *ref = checkobject(L, 1); - Player *player = getplayer(ref); + RemotePlayer *player = getplayer(ref); if (player == NULL) return 0; diff --git a/src/script/lua_api/l_object.h b/src/script/lua_api/l_object.h index a37d29535..a7ac9dff9 100644 --- a/src/script/lua_api/l_object.h +++ b/src/script/lua_api/l_object.h @@ -27,6 +27,7 @@ class ServerActiveObject; class LuaEntitySAO; class PlayerSAO; class Player; +class RemotePlayer; /* ObjectRef @@ -47,7 +48,7 @@ private: static PlayerSAO* getplayersao(ObjectRef *ref); - static Player* getplayer(ObjectRef *ref); + static RemotePlayer* getplayer(ObjectRef *ref); // Exported functions diff --git a/src/server.cpp b/src/server.cpp index 2dd070b1a..11ffba343 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -1256,7 +1256,7 @@ Inventory* Server::getInventory(const InventoryLocation &loc) break; case InventoryLocation::PLAYER: { - Player *player = m_env->getPlayer(loc.name.c_str()); + RemotePlayer *player = dynamic_cast(m_env->getPlayer(loc.name.c_str())); if(!player) return NULL; PlayerSAO *playersao = player->getPlayerSAO(); @@ -1296,9 +1296,12 @@ void Server::setInventoryModified(const InventoryLocation &loc, bool playerSend) if (!playerSend) return; - Player *player = m_env->getPlayer(loc.name.c_str()); - if(!player) + RemotePlayer *player = + dynamic_cast(m_env->getPlayer(loc.name.c_str())); + + if (!player) return; + PlayerSAO *playersao = player->getPlayerSAO(); if(!playersao) return; @@ -2637,19 +2640,16 @@ void Server::DeleteClient(u16 peer_id, ClientDeletionReason reason) ++i; } - Player *player = m_env->getPlayer(peer_id); + RemotePlayer *player = dynamic_cast(m_env->getPlayer(peer_id)); /* Run scripts and remove from environment */ - { - if(player != NULL) - { - PlayerSAO *playersao = player->getPlayerSAO(); - assert(playersao); + if(player != NULL) { + PlayerSAO *playersao = player->getPlayerSAO(); + assert(playersao); - m_script->on_leaveplayer(playersao, reason == CDR_TIMEOUT); + m_script->on_leaveplayer(playersao, reason == CDR_TIMEOUT); - playersao->disconnected(); - } + playersao->disconnected(); } /* @@ -2691,7 +2691,7 @@ void Server::DeleteClient(u16 peer_id, ClientDeletionReason reason) SendChatMessage(PEER_ID_INEXISTENT,message); } -void Server::UpdateCrafting(Player* player) +void Server::UpdateCrafting(RemotePlayer* player) { DSTACK(FUNCTION_NAME); @@ -2701,7 +2701,8 @@ void Server::UpdateCrafting(Player* player) loc.setPlayer(player->getName()); std::vector output_replacements; getCraftingResult(&player->inventory, preview, output_replacements, false, this); - m_env->getScriptIface()->item_CraftPredict(preview, player->getPlayerSAO(), (&player->inventory)->getList("craft"), loc); + m_env->getScriptIface()->item_CraftPredict(preview, player->getPlayerSAO(), + (&player->inventory)->getList("craft"), loc); // Put the new preview in InventoryList *plist = player->inventory.getList("craftpreview"); @@ -2851,8 +2852,8 @@ std::string Server::getPlayerName(u16 peer_id) PlayerSAO* Server::getPlayerSAO(u16 peer_id) { - Player *player = m_env->getPlayer(peer_id); - if(player == NULL) + RemotePlayer *player = dynamic_cast(m_env->getPlayer(peer_id)); + if (player == NULL) return NULL; return player->getPlayerSAO(); } @@ -2917,8 +2918,9 @@ void Server::reportPrivsModified(const std::string &name) reportPrivsModified(player->getName()); } } else { - Player *player = m_env->getPlayer(name.c_str()); - if(!player) + RemotePlayer *player = + dynamic_cast(m_env->getPlayer(name.c_str())); + if (!player) return; SendPlayerPrivileges(player->peer_id); PlayerSAO *sao = player->getPlayerSAO(); @@ -3025,7 +3027,7 @@ bool Server::hudChange(Player *player, u32 id, HudElementStat stat, void *data) return true; } -bool Server::hudSetFlags(Player *player, u32 flags, u32 mask) +bool Server::hudSetFlags(RemotePlayer *player, u32 flags, u32 mask) { if (!player) return false; @@ -3043,10 +3045,11 @@ bool Server::hudSetFlags(Player *player, u32 flags, u32 mask) return true; } -bool Server::hudSetHotbarItemcount(Player *player, s32 hotbar_itemcount) +bool Server::hudSetHotbarItemcount(RemotePlayer *player, s32 hotbar_itemcount) { if (!player) return false; + if (hotbar_itemcount <= 0 || hotbar_itemcount > HUD_HOTBAR_ITEMCOUNT_MAX) return false; @@ -3057,13 +3060,6 @@ bool Server::hudSetHotbarItemcount(Player *player, s32 hotbar_itemcount) return true; } -s32 Server::hudGetHotbarItemcount(Player *player) -{ - if (!player) - return 0; - return player->getHotbarItemcount(); -} - void Server::hudSetHotbarImage(Player *player, std::string name) { if (!player) @@ -3130,7 +3126,7 @@ bool Server::setSky(Player *player, const video::SColor &bgcolor, return true; } -bool Server::overrideDayNightRatio(Player *player, bool do_override, +bool Server::overrideDayNightRatio(RemotePlayer *player, bool do_override, float ratio) { if (!player) diff --git a/src/server.h b/src/server.h index 34427a71a..331a91a52 100644 --- a/src/server.h +++ b/src/server.h @@ -34,6 +34,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "environment.h" #include "chat_interface.h" #include "clientiface.h" +#include "player.h" #include "network/networkpacket.h" #include #include @@ -48,7 +49,6 @@ class IWritableCraftDefManager; class BanManager; class EventManager; class Inventory; -class Player; class PlayerSAO; class IRollbackManager; struct RollbackAction; @@ -336,9 +336,10 @@ public: u32 hudAdd(Player *player, HudElement *element); bool hudRemove(Player *player, u32 id); bool hudChange(Player *player, u32 id, HudElementStat stat, void *value); - bool hudSetFlags(Player *player, u32 flags, u32 mask); - bool hudSetHotbarItemcount(Player *player, s32 hotbar_itemcount); - s32 hudGetHotbarItemcount(Player *player); + bool hudSetFlags(RemotePlayer *player, u32 flags, u32 mask); + bool hudSetHotbarItemcount(RemotePlayer *player, s32 hotbar_itemcount); + s32 hudGetHotbarItemcount(RemotePlayer *player) const + { return player->getHotbarItemcount(); } void hudSetHotbarImage(Player *player, std::string name); std::string hudGetHotbarImage(Player *player); void hudSetHotbarSelectedImage(Player *player, std::string name); @@ -353,7 +354,7 @@ public: bool setSky(Player *player, const video::SColor &bgcolor, const std::string &type, const std::vector ¶ms); - bool overrideDayNightRatio(Player *player, bool do_override, float brightness); + bool overrideDayNightRatio(RemotePlayer *player, bool do_override, float brightness); /* con::PeerHandler implementation. */ void peerAdded(con::Peer *peer); @@ -475,7 +476,7 @@ private: void DiePlayer(u16 peer_id); void RespawnPlayer(u16 peer_id); void DeleteClient(u16 peer_id, ClientDeletionReason reason); - void UpdateCrafting(Player *player); + void UpdateCrafting(RemotePlayer *player); void handleChatInterfaceEvent(ChatEvent *evt); -- cgit v1.2.3 From 656faf7373587bc59b47986a28dbd2fce4c45474 Mon Sep 17 00:00:00 2001 From: Loic Blot Date: Sat, 8 Oct 2016 12:21:41 +0200 Subject: Player/LocalPlayer/RemotePlayer inheritance cleanup (part 2 on X) * Server/Client Environments now have an helper to cast Player object in the right type to use it * Server: use RemotePlayer everywhere and remove previous added casts * Client: use LocalPlayer where needed * Environment: remove unused functions (getPlayers(), getRandomConnectedPlayer(), getNearestConnectedPlayer()) --- src/client.cpp | 2 +- src/environment.cpp | 84 +++++++++---------------------------- src/environment.h | 18 ++++---- src/network/serverpackethandler.cpp | 24 ++++------- src/script/lua_api/l_inventory.cpp | 2 +- src/script/lua_api/l_inventory.h | 9 +--- src/script/lua_api/l_object.cpp | 20 ++++----- src/script/lua_api/l_object.h | 1 - src/script/lua_api/l_server.cpp | 21 +++++----- src/server.cpp | 26 ++++++------ src/server.h | 21 +++++----- src/serverobject.h | 25 ++++++----- 12 files changed, 97 insertions(+), 156 deletions(-) (limited to 'src/network') diff --git a/src/client.cpp b/src/client.cpp index 63653998a..392dabde6 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -1418,7 +1418,7 @@ Inventory* Client::getInventory(const InventoryLocation &loc) break; case InventoryLocation::PLAYER: { - Player *player = m_env.getPlayer(loc.name.c_str()); + LocalPlayer *player = m_env.getPlayer(loc.name.c_str()); if(!player) return NULL; return &player->inventory; diff --git a/src/environment.cpp b/src/environment.cpp index 34b3c34f4..d30b70527 100644 --- a/src/environment.cpp +++ b/src/environment.cpp @@ -127,65 +127,6 @@ Player * Environment::getPlayer(const char *name) return NULL; } -Player * Environment::getRandomConnectedPlayer() -{ - std::vector connected_players = getPlayers(true); - u32 chosen_one = myrand() % connected_players.size(); - u32 j = 0; - for(std::vector::iterator - i = connected_players.begin(); - i != connected_players.end(); ++i) { - if(j == chosen_one) { - Player *player = *i; - return player; - } - j++; - } - return NULL; -} - -Player * Environment::getNearestConnectedPlayer(v3f pos) -{ - std::vector connected_players = getPlayers(true); - f32 nearest_d = 0; - Player *nearest_player = NULL; - for(std::vector::iterator - i = connected_players.begin(); - i != connected_players.end(); ++i) { - Player *player = *i; - f32 d = player->getPosition().getDistanceFrom(pos); - if(d < nearest_d || nearest_player == NULL) { - nearest_d = d; - nearest_player = player; - } - } - return nearest_player; -} - -std::vector Environment::getPlayers() -{ - return m_players; -} - -std::vector Environment::getPlayers(bool ignore_disconnected) -{ - std::vector newlist; - for(std::vector::iterator - i = m_players.begin(); - i != m_players.end(); ++i) { - Player *player = *i; - - if(ignore_disconnected) { - // Ignore disconnected players - if(player->peer_id == 0) - continue; - } - - newlist.push_back(player); - } - return newlist; -} - u32 Environment::getDayNightRatio() { MutexAutoLock lock(this->m_time_lock); @@ -199,11 +140,6 @@ void Environment::setTimeOfDaySpeed(float speed) m_time_of_day_speed = speed; } -float Environment::getTimeOfDaySpeed() -{ - return m_time_of_day_speed; -} - void Environment::setDayNightRatioOverride(bool enable, u32 value) { MutexAutoLock lock(this->m_time_lock); @@ -625,6 +561,16 @@ ServerMap & ServerEnvironment::getServerMap() return *m_map; } +RemotePlayer *ServerEnvironment::getPlayer(const u16 peer_id) +{ + return dynamic_cast(Environment::getPlayer(peer_id)); +} + +RemotePlayer *ServerEnvironment::getPlayer(const char* name) +{ + return dynamic_cast(Environment::getPlayer(name)); +} + bool ServerEnvironment::line_of_sight(v3f pos1, v3f pos2, float stepsize, v3s16 *p) { float distance = pos1.getDistanceFrom(pos2); @@ -2349,6 +2295,16 @@ ClientMap & ClientEnvironment::getClientMap() return *m_map; } +LocalPlayer *ClientEnvironment::getPlayer(const u16 peer_id) +{ + return dynamic_cast(Environment::getPlayer(peer_id)); +} + +LocalPlayer *ClientEnvironment::getPlayer(const char* name) +{ + return dynamic_cast(Environment::getPlayer(name)); +} + void ClientEnvironment::addPlayer(Player *player) { DSTACK(FUNCTION_NAME); diff --git a/src/environment.h b/src/environment.h index 1ba7b196f..66d9c19c0 100644 --- a/src/environment.h +++ b/src/environment.h @@ -74,12 +74,6 @@ public: virtual void addPlayer(Player *player); void removePlayer(Player *player); - Player * getPlayer(u16 peer_id); - Player * getPlayer(const char *name); - Player * getRandomConnectedPlayer(); - Player * getNearestConnectedPlayer(v3f pos); - std::vector getPlayers(); - std::vector getPlayers(bool ignore_disconnected); u32 getDayNightRatio(); @@ -91,7 +85,6 @@ public: void stepTimeOfDay(float dtime); void setTimeOfDaySpeed(float speed); - float getTimeOfDaySpeed(); void setDayNightRatioOverride(bool enable, u32 value); @@ -101,6 +94,9 @@ public: u32 m_added_objects; protected: + Player * getPlayer(u16 peer_id); + Player * getPlayer(const char *name); + // peer_ids in here should be unique, except that there may be many 0s std::vector m_players; @@ -440,6 +436,8 @@ public: void setStaticForActiveObjectsInBlock(v3s16 blockpos, bool static_exists, v3s16 static_block=v3s16(0,0,0)); + RemotePlayer *getPlayer(const u16 peer_id); + RemotePlayer *getPlayer(const char* name); private: /* @@ -640,8 +638,10 @@ public: { m_player_names.remove(name); } void updateCameraOffset(v3s16 camera_offset) { m_camera_offset = camera_offset; } - v3s16 getCameraOffset() - { return m_camera_offset; } + v3s16 getCameraOffset() const { return m_camera_offset; } + + LocalPlayer *getPlayer(const u16 peer_id); + LocalPlayer *getPlayer(const char* name); private: ClientMap *m_map; diff --git a/src/network/serverpackethandler.cpp b/src/network/serverpackethandler.cpp index 3fba7f720..6ef768295 100644 --- a/src/network/serverpackethandler.cpp +++ b/src/network/serverpackethandler.cpp @@ -800,8 +800,7 @@ void Server::handleCommand_PlayerPos(NetworkPacket* pkt) pitch = modulo360f(pitch); yaw = modulo360f(yaw); - RemotePlayer *player = - dynamic_cast(m_env->getPlayer(pkt->getPeerId())); + RemotePlayer *player = m_env->getPlayer(pkt->getPeerId()); if (player == NULL) { errorstream << "Server::ProcessData(): Canceling: " "No player for peer_id=" << pkt->getPeerId() @@ -880,8 +879,7 @@ void Server::handleCommand_DeletedBlocks(NetworkPacket* pkt) void Server::handleCommand_InventoryAction(NetworkPacket* pkt) { - RemotePlayer *player = - dynamic_cast(m_env->getPlayer(pkt->getPeerId())); + RemotePlayer *player = m_env->getPlayer(pkt->getPeerId()); if (player == NULL) { errorstream << "Server::ProcessData(): Canceling: " @@ -1081,8 +1079,7 @@ void Server::handleCommand_Damage(NetworkPacket* pkt) *pkt >> damage; - RemotePlayer *player = - dynamic_cast(m_env->getPlayer(pkt->getPeerId())); + RemotePlayer *player = m_env->getPlayer(pkt->getPeerId()); if (player == NULL) { errorstream << "Server::ProcessData(): Canceling: " @@ -1117,8 +1114,7 @@ void Server::handleCommand_Breath(NetworkPacket* pkt) *pkt >> breath; - RemotePlayer *player = - dynamic_cast(m_env->getPlayer(pkt->getPeerId())); + RemotePlayer *player = m_env->getPlayer(pkt->getPeerId()); if (player == NULL) { errorstream << "Server::ProcessData(): Canceling: " @@ -1231,8 +1227,7 @@ void Server::handleCommand_PlayerItem(NetworkPacket* pkt) if (pkt->getSize() < 2) return; - RemotePlayer *player = - dynamic_cast(m_env->getPlayer(pkt->getPeerId())); + RemotePlayer *player = m_env->getPlayer(pkt->getPeerId()); if (player == NULL) { errorstream << "Server::ProcessData(): Canceling: " @@ -1308,8 +1303,7 @@ void Server::handleCommand_Interact(NetworkPacket* pkt) verbosestream << "TOSERVER_INTERACT: action=" << (int)action << ", item=" << item_i << ", pointed=" << pointed.dump() << std::endl; - RemotePlayer *player = - dynamic_cast(m_env->getPlayer(pkt->getPeerId())); + RemotePlayer *player = m_env->getPlayer(pkt->getPeerId()); if (player == NULL) { errorstream << "Server::ProcessData(): Canceling: " @@ -1730,8 +1724,7 @@ void Server::handleCommand_NodeMetaFields(NetworkPacket* pkt) fields[fieldname] = pkt->readLongString(); } - RemotePlayer *player = - dynamic_cast(m_env->getPlayer(pkt->getPeerId())); + RemotePlayer *player = m_env->getPlayer(pkt->getPeerId()); if (player == NULL) { errorstream << "Server::ProcessData(): Canceling: " @@ -1782,8 +1775,7 @@ void Server::handleCommand_InventoryFields(NetworkPacket* pkt) fields[fieldname] = pkt->readLongString(); } - RemotePlayer *player = - dynamic_cast(m_env->getPlayer(pkt->getPeerId())); + RemotePlayer *player = m_env->getPlayer(pkt->getPeerId()); if (player == NULL) { errorstream << "Server::ProcessData(): Canceling: " diff --git a/src/script/lua_api/l_inventory.cpp b/src/script/lua_api/l_inventory.cpp index de9f9374a..110e68d23 100644 --- a/src/script/lua_api/l_inventory.cpp +++ b/src/script/lua_api/l_inventory.cpp @@ -420,7 +420,7 @@ void InvRef::create(lua_State *L, const InventoryLocation &loc) luaL_getmetatable(L, className); lua_setmetatable(L, -2); } -void InvRef::createPlayer(lua_State *L, Player *player) +void InvRef::createPlayer(lua_State *L, RemotePlayer *player) { NO_MAP_LOCK_REQUIRED; InventoryLocation loc; diff --git a/src/script/lua_api/l_inventory.h b/src/script/lua_api/l_inventory.h index 2d4b29d0c..cc5333965 100644 --- a/src/script/lua_api/l_inventory.h +++ b/src/script/lua_api/l_inventory.h @@ -25,7 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "inventory.h" #include "inventorymanager.h" -class Player; +class RemotePlayer; /* InvRef @@ -112,7 +112,7 @@ public: // Creates an InvRef and leaves it on top of stack // Not callable from Lua; all references are created on the C side. static void create(lua_State *L, const InventoryLocation &loc); - static void createPlayer(lua_State *L, Player *player); + static void createPlayer(lua_State *L, RemotePlayer *player); static void createNodeMeta(lua_State *L, v3s16 p); static void Register(lua_State *L); }; @@ -123,11 +123,6 @@ private: static int l_get_inventory(lua_State *L); - static void inventory_set_list_from_lua(Inventory *inv, const char *name, - lua_State *L, int tableindex, int forcesize); - static void inventory_get_list_to_lua(Inventory *inv, const char *name, - lua_State *L); - public: static void Initialize(lua_State *L, int top); }; diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp index 34e175ad0..b58d8e6cd 100644 --- a/src/script/lua_api/l_object.cpp +++ b/src/script/lua_api/l_object.cpp @@ -508,7 +508,7 @@ int ObjectRef::l_set_local_animation(lua_State *L) { NO_MAP_LOCK_REQUIRED; ObjectRef *ref = checkobject(L, 1); - Player *player = getplayer(ref); + RemotePlayer *player = getplayer(ref); if (player == NULL) return 0; // Do it @@ -554,7 +554,7 @@ int ObjectRef::l_set_eye_offset(lua_State *L) { NO_MAP_LOCK_REQUIRED; ObjectRef *ref = checkobject(L, 1); - Player *player = getplayer(ref); + RemotePlayer *player = getplayer(ref); if (player == NULL) return 0; // Do it @@ -1256,7 +1256,7 @@ int ObjectRef::l_hud_add(lua_State *L) { NO_MAP_LOCK_REQUIRED; ObjectRef *ref = checkobject(L, 1); - Player *player = getplayer(ref); + RemotePlayer *player = getplayer(ref); if (player == NULL) return 0; @@ -1319,7 +1319,7 @@ int ObjectRef::l_hud_remove(lua_State *L) { NO_MAP_LOCK_REQUIRED; ObjectRef *ref = checkobject(L, 1); - Player *player = getplayer(ref); + RemotePlayer *player = getplayer(ref); if (player == NULL) return 0; @@ -1339,7 +1339,7 @@ int ObjectRef::l_hud_change(lua_State *L) { NO_MAP_LOCK_REQUIRED; ObjectRef *ref = checkobject(L, 1); - Player *player = getplayer(ref); + RemotePlayer *player = getplayer(ref); if (player == NULL) return 0; @@ -1552,7 +1552,7 @@ int ObjectRef::l_hud_set_hotbar_image(lua_State *L) { NO_MAP_LOCK_REQUIRED; ObjectRef *ref = checkobject(L, 1); - Player *player = getplayer(ref); + RemotePlayer *player = getplayer(ref); if (player == NULL) return 0; @@ -1567,7 +1567,7 @@ int ObjectRef::l_hud_get_hotbar_image(lua_State *L) { NO_MAP_LOCK_REQUIRED; ObjectRef *ref = checkobject(L, 1); - Player *player = getplayer(ref); + RemotePlayer *player = getplayer(ref); if (player == NULL) return 0; @@ -1581,7 +1581,7 @@ int ObjectRef::l_hud_set_hotbar_selected_image(lua_State *L) { NO_MAP_LOCK_REQUIRED; ObjectRef *ref = checkobject(L, 1); - Player *player = getplayer(ref); + RemotePlayer *player = getplayer(ref); if (player == NULL) return 0; @@ -1596,7 +1596,7 @@ int ObjectRef::l_hud_get_hotbar_selected_image(lua_State *L) { NO_MAP_LOCK_REQUIRED; ObjectRef *ref = checkobject(L, 1); - Player *player = getplayer(ref); + RemotePlayer *player = getplayer(ref); if (player == NULL) return 0; @@ -1610,7 +1610,7 @@ int ObjectRef::l_set_sky(lua_State *L) { NO_MAP_LOCK_REQUIRED; ObjectRef *ref = checkobject(L, 1); - Player *player = getplayer(ref); + RemotePlayer *player = getplayer(ref); if (player == NULL) return 0; diff --git a/src/script/lua_api/l_object.h b/src/script/lua_api/l_object.h index a7ac9dff9..dfc1b49d2 100644 --- a/src/script/lua_api/l_object.h +++ b/src/script/lua_api/l_object.h @@ -26,7 +26,6 @@ with this program; if not, write to the Free Software Foundation, Inc., class ServerActiveObject; class LuaEntitySAO; class PlayerSAO; -class Player; class RemotePlayer; /* diff --git a/src/script/lua_api/l_server.cpp b/src/script/lua_api/l_server.cpp index 59d3f5c70..95e5da07f 100644 --- a/src/script/lua_api/l_server.cpp +++ b/src/script/lua_api/l_server.cpp @@ -106,7 +106,7 @@ int ModApiServer::l_get_player_ip(lua_State *L) { NO_MAP_LOCK_REQUIRED; const char * name = luaL_checkstring(L, 1); - Player *player = getEnv(L)->getPlayer(name); + RemotePlayer *player = dynamic_cast(getEnv(L))->getPlayer(name); if(player == NULL) { lua_pushnil(L); // no such player @@ -133,9 +133,8 @@ int ModApiServer::l_get_player_information(lua_State *L) NO_MAP_LOCK_REQUIRED; const char * name = luaL_checkstring(L, 1); - Player *player = getEnv(L)->getPlayer(name); - if(player == NULL) - { + RemotePlayer *player = dynamic_cast(getEnv(L))->getPlayer(name); + if (player == NULL) { lua_pushnil(L); // no such player return 1; } @@ -278,15 +277,15 @@ int ModApiServer::l_ban_player(lua_State *L) { NO_MAP_LOCK_REQUIRED; const char * name = luaL_checkstring(L, 1); - Player *player = getEnv(L)->getPlayer(name); - if(player == NULL) - { + RemotePlayer *player = dynamic_cast(getEnv(L))->getPlayer(name); + if (player == NULL) { lua_pushboolean(L, false); // no such player return 1; } try { - Address addr = getServer(L)->getPeerAddress(getEnv(L)->getPlayer(name)->peer_id); + Address addr = getServer(L)->getPeerAddress( + dynamic_cast(getEnv(L))->getPlayer(name)->peer_id); std::string ip_str = addr.serializeString(); getServer(L)->setIpBanned(ip_str, name); } @@ -314,9 +313,9 @@ int ModApiServer::l_kick_player(lua_State *L) { message = "Kicked."; } - Player *player = getEnv(L)->getPlayer(name); - if (player == NULL) - { + + RemotePlayer *player = dynamic_cast(getEnv(L))->getPlayer(name); + if (player == NULL) { lua_pushboolean(L, false); // No such player return 1; } diff --git a/src/server.cpp b/src/server.cpp index 540d23b9d..dee8a3d70 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -2638,7 +2638,7 @@ void Server::DeleteClient(u16 peer_id, ClientDeletionReason reason) ++i; } - RemotePlayer *player = dynamic_cast(m_env->getPlayer(peer_id)); + RemotePlayer *player = m_env->getPlayer(peer_id); /* Run scripts and remove from environment */ if(player != NULL) { @@ -2850,7 +2850,7 @@ std::string Server::getPlayerName(u16 peer_id) PlayerSAO* Server::getPlayerSAO(u16 peer_id) { - RemotePlayer *player = dynamic_cast(m_env->getPlayer(peer_id)); + RemotePlayer *player = m_env->getPlayer(peer_id); if (player == NULL) return NULL; return player->getPlayerSAO(); @@ -2989,7 +2989,7 @@ bool Server::showFormspec(const char *playername, const std::string &formspec, return true; } -u32 Server::hudAdd(Player *player, HudElement *form) +u32 Server::hudAdd(RemotePlayer *player, HudElement *form) { if (!player) return -1; @@ -3001,7 +3001,7 @@ u32 Server::hudAdd(Player *player, HudElement *form) return id; } -bool Server::hudRemove(Player *player, u32 id) { +bool Server::hudRemove(RemotePlayer *player, u32 id) { if (!player) return false; @@ -3016,7 +3016,7 @@ bool Server::hudRemove(Player *player, u32 id) { return true; } -bool Server::hudChange(Player *player, u32 id, HudElementStat stat, void *data) +bool Server::hudChange(RemotePlayer *player, u32 id, HudElementStat stat, void *data) { if (!player) return false; @@ -3058,7 +3058,7 @@ bool Server::hudSetHotbarItemcount(RemotePlayer *player, s32 hotbar_itemcount) return true; } -void Server::hudSetHotbarImage(Player *player, std::string name) +void Server::hudSetHotbarImage(RemotePlayer *player, std::string name) { if (!player) return; @@ -3067,14 +3067,14 @@ void Server::hudSetHotbarImage(Player *player, std::string name) SendHUDSetParam(player->peer_id, HUD_PARAM_HOTBAR_IMAGE, name); } -std::string Server::hudGetHotbarImage(Player *player) +std::string Server::hudGetHotbarImage(RemotePlayer *player) { if (!player) return ""; return player->getHotbarImage(); } -void Server::hudSetHotbarSelectedImage(Player *player, std::string name) +void Server::hudSetHotbarSelectedImage(RemotePlayer *player, std::string name) { if (!player) return; @@ -3083,7 +3083,7 @@ void Server::hudSetHotbarSelectedImage(Player *player, std::string name) SendHUDSetParam(player->peer_id, HUD_PARAM_HOTBAR_SELECTED_IMAGE, name); } -std::string Server::hudGetHotbarSelectedImage(Player *player) +std::string Server::hudGetHotbarSelectedImage(RemotePlayer *player) { if (!player) return ""; @@ -3091,8 +3091,8 @@ std::string Server::hudGetHotbarSelectedImage(Player *player) return player->getHotbarSelectedImage(); } -bool Server::setLocalPlayerAnimations(Player *player, - v2s32 animation_frames[4], f32 frame_speed) +bool Server::setLocalPlayerAnimations(RemotePlayer *player, + v2s32 animation_frames[4], f32 frame_speed) { if (!player) return false; @@ -3102,7 +3102,7 @@ bool Server::setLocalPlayerAnimations(Player *player, return true; } -bool Server::setPlayerEyeOffset(Player *player, v3f first, v3f third) +bool Server::setPlayerEyeOffset(RemotePlayer *player, v3f first, v3f third) { if (!player) return false; @@ -3113,7 +3113,7 @@ bool Server::setPlayerEyeOffset(Player *player, v3f first, v3f third) return true; } -bool Server::setSky(Player *player, const video::SColor &bgcolor, +bool Server::setSky(RemotePlayer *player, const video::SColor &bgcolor, const std::string &type, const std::vector ¶ms) { if (!player) diff --git a/src/server.h b/src/server.h index 555aab692..8eb1afc9f 100644 --- a/src/server.h +++ b/src/server.h @@ -307,25 +307,26 @@ public: Map & getMap() { return m_env->getMap(); } ServerEnvironment & getEnv() { return *m_env; } - u32 hudAdd(Player *player, HudElement *element); - bool hudRemove(Player *player, u32 id); - bool hudChange(Player *player, u32 id, HudElementStat stat, void *value); + u32 hudAdd(RemotePlayer *player, HudElement *element); + bool hudRemove(RemotePlayer *player, u32 id); + bool hudChange(RemotePlayer *player, u32 id, HudElementStat stat, void *value); bool hudSetFlags(RemotePlayer *player, u32 flags, u32 mask); bool hudSetHotbarItemcount(RemotePlayer *player, s32 hotbar_itemcount); s32 hudGetHotbarItemcount(RemotePlayer *player) const { return player->getHotbarItemcount(); } - void hudSetHotbarImage(Player *player, std::string name); - std::string hudGetHotbarImage(Player *player); - void hudSetHotbarSelectedImage(Player *player, std::string name); - std::string hudGetHotbarSelectedImage(Player *player); + void hudSetHotbarImage(RemotePlayer *player, std::string name); + std::string hudGetHotbarImage(RemotePlayer *player); + void hudSetHotbarSelectedImage(RemotePlayer *player, std::string name); + std::string hudGetHotbarSelectedImage(RemotePlayer *player); inline Address getPeerAddress(u16 peer_id) { return m_con.GetPeerAddress(peer_id); } - bool setLocalPlayerAnimations(Player *player, v2s32 animation_frames[4], f32 frame_speed); - bool setPlayerEyeOffset(Player *player, v3f first, v3f third); + bool setLocalPlayerAnimations(RemotePlayer *player, v2s32 animation_frames[4], + f32 frame_speed); + bool setPlayerEyeOffset(RemotePlayer *player, v3f first, v3f third); - bool setSky(Player *player, const video::SColor &bgcolor, + bool setSky(RemotePlayer *player, const video::SColor &bgcolor, const std::string &type, const std::vector ¶ms); bool overrideDayNightRatio(RemotePlayer *player, bool do_override, float brightness); diff --git a/src/serverobject.h b/src/serverobject.h index 9f8d5403c..cfe2b6bcc 100644 --- a/src/serverobject.h +++ b/src/serverobject.h @@ -44,7 +44,6 @@ Some planning class ServerEnvironment; struct ItemStack; -class Player; struct ToolCapabilities; struct ObjectProperties; @@ -69,23 +68,23 @@ public: // environment virtual bool environmentDeletes() const { return true; } - + // Create a certain type of ServerActiveObject static ServerActiveObject* create(ActiveObjectType type, ServerEnvironment *env, u16 id, v3f pos, const std::string &data); - + /* Some simple getters/setters */ v3f getBasePosition(){ return m_base_position; } void setBasePosition(v3f pos){ m_base_position = pos; } ServerEnvironment* getEnv(){ return m_env; } - + /* Some more dynamic interface */ - + virtual void setPos(v3f pos) { setBasePosition(pos); } // continuous: if true, object does not stop immediately at pos @@ -96,7 +95,7 @@ public: virtual float getMinimumSavedMovement(); virtual std::string getDescription(){return "SAO";} - + /* Step object in time. Messages added to messages are sent to client over network. @@ -108,13 +107,13 @@ public: packet. */ virtual void step(float dtime, bool send_recommended){} - + /* The return value of this is passed to the client-side object when it is created */ virtual std::string getClientInitializationData(u16 protocol_version){return "";} - + /* The return value of this is passed to the server-side object when it is created (converted from static to active - actually @@ -131,7 +130,7 @@ public: */ virtual bool isStaticAllowed() const {return true;} - + // Returns tool wear virtual int punch(v3f dir, const ToolCapabilities *toolcap=NULL, @@ -207,7 +206,7 @@ public: - This can be set to true by anything else too. */ bool m_removed; - + /* This is set to true when an object should be removed from the active object list but couldn't be removed because the id has to be @@ -218,7 +217,7 @@ public: list. */ bool m_pending_deactivation; - + /* Whether the object's static data has been stored to a block */ @@ -228,12 +227,12 @@ public: a copy of the static data resides. */ v3s16 m_static_block; - + /* Queue of messages to be sent to the client */ std::queue m_messages_out; - + protected: // Used for creating objects based on type typedef ServerActiveObject* (*Factory) -- cgit v1.2.3 From fd5a130b86c08f0b3190c3d81affd4869c139fb7 Mon Sep 17 00:00:00 2001 From: Loic Blot Date: Sat, 8 Oct 2016 16:31:22 +0200 Subject: More code cleanup (UNORDERED + RemotePlayer/LocalPlayer) * ClientEnvironment now uses UNORDERED MAP for active objects * Use RemotePlayer and LocalPlayer everywhere it's possible * Minor code style fixes * Drop Client::getBreath() unused function --- src/client.cpp | 21 +++----- src/client.h | 1 - src/clientiface.cpp | 13 ++--- src/content_cao.cpp | 7 ++- src/environment.cpp | 105 ++++++++++++++++-------------------- src/environment.h | 12 ++--- src/network/clientpackethandler.cpp | 18 +++---- src/network/serverpackethandler.cpp | 6 +-- src/script/lua_api/l_object.cpp | 36 ++++++------- src/server.cpp | 57 ++++++++++---------- 10 files changed, 124 insertions(+), 152 deletions(-) (limited to 'src/network') diff --git a/src/client.cpp b/src/client.cpp index 392dabde6..cd010e592 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -383,7 +383,7 @@ void Client::step(float dtime) if(counter <= 0.0) { counter = 2.0; - Player *myplayer = m_env.getLocalPlayer(); + LocalPlayer *myplayer = m_env.getLocalPlayer(); FATAL_ERROR_IF(myplayer == NULL, "Local player not found in environment."); u16 proto_version_min = g_settings->getFlag("send_pre_v25_init") ? @@ -613,7 +613,7 @@ void Client::step(float dtime) { // Do this every seconds after TOCLIENT_INVENTORY // Reset the locally changed inventory to the authoritative inventory - Player *player = m_env.getLocalPlayer(); + LocalPlayer *player = m_env.getLocalPlayer(); player->inventory = *m_inventory_from_server; m_inventory_updated = true; } @@ -1191,7 +1191,7 @@ void Client::sendChatMessage(const std::wstring &message) void Client::sendChangePassword(const std::string &oldpassword, const std::string &newpassword) { - Player *player = m_env.getLocalPlayer(); + LocalPlayer *player = m_env.getLocalPlayer(); if (player == NULL) return; @@ -1317,7 +1317,7 @@ void Client::sendPlayerPos() void Client::sendPlayerItem(u16 item) { - Player *myplayer = m_env.getLocalPlayer(); + LocalPlayer *myplayer = m_env.getLocalPlayer(); if(myplayer == NULL) return; @@ -1398,7 +1398,7 @@ bool Client::getLocalInventoryUpdated() // Copies the inventory of the local player to parameter void Client::getLocalInventory(Inventory &dst) { - Player *player = m_env.getLocalPlayer(); + LocalPlayer *player = m_env.getLocalPlayer(); assert(player != NULL); dst = player->inventory; } @@ -1411,7 +1411,7 @@ Inventory* Client::getInventory(const InventoryLocation &loc) break; case InventoryLocation::CURRENT_PLAYER: { - Player *player = m_env.getLocalPlayer(); + LocalPlayer *player = m_env.getLocalPlayer(); assert(player != NULL); return &player->inventory; } @@ -1537,18 +1537,11 @@ void Client::setCrack(int level, v3s16 pos) u16 Client::getHP() { - Player *player = m_env.getLocalPlayer(); + LocalPlayer *player = m_env.getLocalPlayer(); assert(player != NULL); return player->hp; } -u16 Client::getBreath() -{ - Player *player = m_env.getLocalPlayer(); - assert(player != NULL); - return player->getBreath(); -} - bool Client::getChatMessage(std::wstring &message) { if(m_chat_queue.size() == 0) diff --git a/src/client.h b/src/client.h index a71c1dcbc..72baac2d2 100644 --- a/src/client.h +++ b/src/client.h @@ -460,7 +460,6 @@ public: void setCrack(int level, v3s16 pos); u16 getHP(); - u16 getBreath(); bool checkPrivilege(const std::string &priv) const { return (m_privileges.count(priv) != 0); } diff --git a/src/clientiface.cpp b/src/clientiface.cpp index e7ad39579..e55c07cb6 100644 --- a/src/clientiface.cpp +++ b/src/clientiface.cpp @@ -77,9 +77,9 @@ void RemoteClient::GetNextBlocks ( if(m_nothing_to_send_pause_timer >= 0) return; - Player *player = env->getPlayer(peer_id); + RemotePlayer *player = env->getPlayer(peer_id); // This can happen sometimes; clients and players are not in perfect sync. - if(player == NULL) + if (player == NULL) return; // Won't send anything if already sending @@ -645,8 +645,7 @@ void ClientInterface::step(float dtime) void ClientInterface::UpdatePlayerList() { - if (m_env != NULL) - { + if (m_env != NULL) { std::vector clients = getClientIDs(); m_clients_names.clear(); @@ -654,10 +653,8 @@ void ClientInterface::UpdatePlayerList() if(!clients.empty()) infostream<<"Players:"<::iterator - i = clients.begin(); - i != clients.end(); ++i) { - Player *player = m_env->getPlayer(*i); + for (std::vector::iterator i = clients.begin(); i != clients.end(); ++i) { + RemotePlayer *player = m_env->getPlayer(*i); if (player == NULL) continue; diff --git a/src/content_cao.cpp b/src/content_cao.cpp index 207a630d7..a53768149 100644 --- a/src/content_cao.cpp +++ b/src/content_cao.cpp @@ -655,12 +655,11 @@ void GenericCAO::initialize(const std::string &data) if(m_is_player) { - Player *player = m_env->getPlayer(m_name.c_str()); - if(player && player->isLocal()) - { + LocalPlayer *player = m_env->getPlayer(m_name.c_str()); + if (player && player->isLocal()) { m_is_local_player = true; m_is_visible = false; - LocalPlayer* localplayer = dynamic_cast(player); + LocalPlayer* localplayer = player; assert( localplayer != NULL ); localplayer->setCAO(this); diff --git a/src/environment.cpp b/src/environment.cpp index d30b70527..bc246f66c 100644 --- a/src/environment.cpp +++ b/src/environment.cpp @@ -105,20 +105,20 @@ void Environment::removePlayer(Player* player) } } -Player * Environment::getPlayer(u16 peer_id) +Player *Environment::getPlayer(u16 peer_id) { - for(std::vector::iterator i = m_players.begin(); + for (std::vector::iterator i = m_players.begin(); i != m_players.end(); ++i) { Player *player = *i; - if(player->peer_id == peer_id) + if (player->peer_id == peer_id) return player; } return NULL; } -Player * Environment::getPlayer(const char *name) +Player *Environment::getPlayer(const char *name) { - for(std::vector::iterator i = m_players.begin(); + for (std::vector::iterator i = m_players.begin(); i != m_players.end(); ++i) { Player *player = *i; if(strcmp(player->getName(), name) == 0) @@ -602,11 +602,9 @@ void ServerEnvironment::kickAllPlayers(AccessDeniedCode reason, const std::string &str_reason, bool reconnect) { for (std::vector::iterator it = m_players.begin(); - it != m_players.end(); - ++it) { + it != m_players.end(); ++it) { ((Server*)m_gamedef)->DenyAccessVerCompliant((*it)->peer_id, - (*it)->protocol_version, (AccessDeniedCode)reason, - str_reason, reconnect); + (*it)->protocol_version, reason, str_reason, reconnect); } } @@ -633,14 +631,14 @@ void ServerEnvironment::savePlayer(RemotePlayer *player) player->save(players_path); } -Player *ServerEnvironment::loadPlayer(const std::string &playername) +RemotePlayer *ServerEnvironment::loadPlayer(const std::string &playername) { bool newplayer = false; bool found = false; std::string players_path = m_path_world + DIR_DELIM "players" DIR_DELIM; std::string path = players_path + playername; - RemotePlayer *player = static_cast(getPlayer(playername.c_str())); + RemotePlayer *player = getPlayer(playername.c_str()); if (!player) { player = new RemotePlayer(m_gamedef, ""); newplayer = true; @@ -1254,10 +1252,10 @@ void ServerEnvironment::step(float dtime) */ { ScopeProfiler sp(g_profiler, "SEnv: handle players avg", SPT_AVG); - for(std::vector::iterator i = m_players.begin(); - i != m_players.end(); ++i) - { - Player *player = *i; + for (std::vector::iterator i = m_players.begin(); + i != m_players.end(); ++i) { + RemotePlayer *player = dynamic_cast(*i); + assert(player); // Ignore disconnected players if(player->peer_id == 0) @@ -1277,12 +1275,12 @@ void ServerEnvironment::step(float dtime) Get player block positions */ std::vector players_blockpos; - for(std::vector::iterator - i = m_players.begin(); + for (std::vector::iterator i = m_players.begin(); i != m_players.end(); ++i) { - Player *player = *i; + RemotePlayer *player = dynamic_cast(*i); + assert(player); // Ignore disconnected players - if(player->peer_id == 0) + if (player->peer_id == 0) continue; v3s16 blockpos = getNodeBlockPos( @@ -1381,8 +1379,7 @@ void ServerEnvironment::step(float dtime) block->m_node_timers.step((float)dtime); if (!elapsed_timers.empty()) { MapNode n; - for (std::vector::iterator - i = elapsed_timers.begin(); + for (std::vector::iterator i = elapsed_timers.begin(); i != elapsed_timers.end(); ++i) { n = block->getNodeNoEx(i->position); p = i->position + block->getPosRelative(); @@ -1571,7 +1568,7 @@ u16 ServerEnvironment::addActiveObject(ServerActiveObject *object) Finds out what new objects have been added to inside a radius around a position */ -void ServerEnvironment::getAddedActiveObjects(Player *player, s16 radius, +void ServerEnvironment::getAddedActiveObjects(RemotePlayer *player, s16 radius, s16 player_radius, std::set ¤t_objects, std::queue &added_objects) @@ -1624,7 +1621,7 @@ void ServerEnvironment::getAddedActiveObjects(Player *player, s16 radius, Finds out what objects have been removed from inside a radius around a position */ -void ServerEnvironment::getRemovedActiveObjects(Player *player, s16 radius, +void ServerEnvironment::getRemovedActiveObjects(RemotePlayer *player, s16 radius, s16 player_radius, std::set ¤t_objects, std::queue &removed_objects) @@ -2269,10 +2266,8 @@ ClientEnvironment::ClientEnvironment(ClientMap *map, scene::ISceneManager *smgr, ClientEnvironment::~ClientEnvironment() { // delete active objects - for(std::map::iterator - i = m_active_objects.begin(); - i != m_active_objects.end(); ++i) - { + for (UNORDERED_MAP::iterator i = m_active_objects.begin(); + i != m_active_objects.end(); ++i) { delete i->second; } @@ -2312,18 +2307,18 @@ void ClientEnvironment::addPlayer(Player *player) It is a failure if player is local and there already is a local player */ - FATAL_ERROR_IF(player->isLocal() == true && getLocalPlayer() != NULL, - "Player is local but there is already a local player"); + FATAL_ERROR_IF(player->isLocal() && getLocalPlayer() != NULL, + "Player is local but there is already a local player"); Environment::addPlayer(player); } -LocalPlayer * ClientEnvironment::getLocalPlayer() +LocalPlayer *ClientEnvironment::getLocalPlayer() { for(std::vector::iterator i = m_players.begin(); i != m_players.end(); ++i) { Player *player = *i; - if(player->isLocal()) + if (player->isLocal()) return (LocalPlayer*)player; } return NULL; @@ -2407,11 +2402,11 @@ void ClientEnvironment::step(float dtime) { // Apply physics - if(free_move == false && is_climbing == false) + if(!free_move && !is_climbing) { // Gravity v3f speed = lplayer->getSpeed(); - if(lplayer->in_liquid == false) + if(!lplayer->in_liquid) speed.Y -= lplayer->movement_gravity * lplayer->physics_override_gravity * dtime_part * 2; // Liquid floating / sinking @@ -2566,14 +2561,15 @@ void ClientEnvironment::step(float dtime) /* Stuff that can be done in an arbitarily large dtime */ - for(std::vector::iterator i = m_players.begin(); + for (std::vector::iterator i = m_players.begin(); i != m_players.end(); ++i) { - Player *player = *i; + LocalPlayer *player = dynamic_cast(*i); + assert(player); /* Handle non-local players */ - if(player->isLocal() == false) { + if (!player->isLocal()) { // Move player->move(dtime, this, 100*BS); @@ -2604,10 +2600,8 @@ void ClientEnvironment::step(float dtime) g_profiler->avg("CEnv: num of objects", m_active_objects.size()); bool update_lighting = m_active_object_light_update_interval.step(dtime, 0.21); - for(std::map::iterator - i = m_active_objects.begin(); - i != m_active_objects.end(); ++i) - { + for (UNORDERED_MAP::iterator i = m_active_objects.begin(); + i != m_active_objects.end(); ++i) { ClientActiveObject* obj = i->second; // Step object obj->step(dtime, this); @@ -2666,15 +2660,14 @@ GenericCAO* ClientEnvironment::getGenericCAO(u16 id) ClientActiveObject* ClientEnvironment::getActiveObject(u16 id) { - std::map::iterator n; - n = m_active_objects.find(id); - if(n == m_active_objects.end()) + UNORDERED_MAP::iterator n = m_active_objects.find(id); + if (n == m_active_objects.end()) return NULL; return n->second; } -bool isFreeClientActiveObjectId(u16 id, - std::map &objects) +bool isFreeClientActiveObjectId(const u16 id, + UNORDERED_MAP &objects) { if(id == 0) return false; @@ -2682,19 +2675,17 @@ bool isFreeClientActiveObjectId(u16 id, return objects.find(id) == objects.end(); } -u16 getFreeClientActiveObjectId( - std::map &objects) +u16 getFreeClientActiveObjectId(UNORDERED_MAP &objects) { //try to reuse id's as late as possible static u16 last_used_id = 0; u16 startid = last_used_id; - for(;;) - { + for(;;) { last_used_id ++; - if(isFreeClientActiveObjectId(last_used_id, objects)) + if (isFreeClientActiveObjectId(last_used_id, objects)) return last_used_id; - if(last_used_id == startid) + if (last_used_id == startid) return 0; } } @@ -2714,8 +2705,7 @@ u16 ClientEnvironment::addActiveObject(ClientActiveObject *object) } object->setId(new_id); } - if(isFreeClientActiveObjectId(object->getId(), m_active_objects) == false) - { + if(!isFreeClientActiveObjectId(object->getId(), m_active_objects)) { infostream<<"ClientEnvironment::addActiveObject(): " <<"id is not free ("<getId()<<")"< &dest) { - for(std::map::iterator - i = m_active_objects.begin(); - i != m_active_objects.end(); ++i) - { + for (UNORDERED_MAP::iterator i = m_active_objects.begin(); + i != m_active_objects.end(); ++i) { ClientActiveObject* obj = i->second; f32 d = (obj->getPosition() - origin).getLength(); diff --git a/src/environment.h b/src/environment.h index 66d9c19c0..99066c367 100644 --- a/src/environment.h +++ b/src/environment.h @@ -94,8 +94,8 @@ public: u32 m_added_objects; protected: - Player * getPlayer(u16 peer_id); - Player * getPlayer(const char *name); + Player *getPlayer(u16 peer_id); + Player *getPlayer(const char *name); // peer_ids in here should be unique, except that there may be many 0s std::vector m_players; @@ -324,7 +324,7 @@ public: // Save players void saveLoadedPlayers(); void savePlayer(RemotePlayer *player); - Player *loadPlayer(const std::string &playername); + RemotePlayer *loadPlayer(const std::string &playername); /* Save and load time of day and game timer @@ -368,7 +368,7 @@ public: Find out what new objects have been added to inside a radius around a position */ - void getAddedActiveObjects(Player *player, s16 radius, + void getAddedActiveObjects(RemotePlayer *player, s16 radius, s16 player_radius, std::set ¤t_objects, std::queue &added_objects); @@ -377,7 +377,7 @@ public: Find out what new objects have been removed from inside a radius around a position */ - void getRemovedActiveObjects(Player* player, s16 radius, + void getRemovedActiveObjects(RemotePlayer* player, s16 radius, s16 player_radius, std::set ¤t_objects, std::queue &removed_objects); @@ -649,7 +649,7 @@ private: ITextureSource *m_texturesource; IGameDef *m_gamedef; IrrlichtDevice *m_irr; - std::map m_active_objects; + UNORDERED_MAP m_active_objects; std::vector m_simple_objects; std::queue m_client_event_queue; IntervalLimiter m_active_object_light_update_interval; diff --git a/src/network/clientpackethandler.cpp b/src/network/clientpackethandler.cpp index 35e350f20..b39356e92 100644 --- a/src/network/clientpackethandler.cpp +++ b/src/network/clientpackethandler.cpp @@ -110,7 +110,7 @@ void Client::handleCommand_AuthAccept(NetworkPacket* pkt) playerpos -= v3f(0, BS / 2, 0); // Set player position - Player *player = m_env.getLocalPlayer(); + LocalPlayer *player = m_env.getLocalPlayer(); assert(player != NULL); player->setPosition(playerpos); @@ -176,7 +176,7 @@ void Client::handleCommand_InitLegacy(NetworkPacket* pkt) // Set player position - Player *player = m_env.getLocalPlayer(); + LocalPlayer *player = m_env.getLocalPlayer(); assert(player != NULL); player->setPosition(playerpos_f); @@ -333,7 +333,7 @@ void Client::handleCommand_Inventory(NetworkPacket* pkt) std::string datastring(pkt->getString(0), pkt->getSize()); std::istringstream is(datastring, std::ios_base::binary); - Player *player = m_env.getLocalPlayer(); + LocalPlayer *player = m_env.getLocalPlayer(); assert(player != NULL); player->inventory.deSerialize(is); @@ -486,7 +486,7 @@ void Client::handleCommand_ActiveObjectMessages(NetworkPacket* pkt) void Client::handleCommand_Movement(NetworkPacket* pkt) { - Player *player = m_env.getLocalPlayer(); + LocalPlayer *player = m_env.getLocalPlayer(); assert(player != NULL); float mad, maa, maf, msw, mscr, msf, mscl, msj, lf, lfs, ls, g; @@ -511,7 +511,7 @@ void Client::handleCommand_Movement(NetworkPacket* pkt) void Client::handleCommand_HP(NetworkPacket* pkt) { - Player *player = m_env.getLocalPlayer(); + LocalPlayer *player = m_env.getLocalPlayer(); assert(player != NULL); u8 oldhp = player->hp; @@ -532,7 +532,7 @@ void Client::handleCommand_HP(NetworkPacket* pkt) void Client::handleCommand_Breath(NetworkPacket* pkt) { - Player *player = m_env.getLocalPlayer(); + LocalPlayer *player = m_env.getLocalPlayer(); assert(player != NULL); u16 breath; @@ -544,7 +544,7 @@ void Client::handleCommand_Breath(NetworkPacket* pkt) void Client::handleCommand_MovePlayer(NetworkPacket* pkt) { - Player *player = m_env.getLocalPlayer(); + LocalPlayer *player = m_env.getLocalPlayer(); assert(player != NULL); v3f pos; @@ -840,7 +840,7 @@ void Client::handleCommand_Privileges(NetworkPacket* pkt) void Client::handleCommand_InventoryFormSpec(NetworkPacket* pkt) { - Player *player = m_env.getLocalPlayer(); + LocalPlayer *player = m_env.getLocalPlayer(); assert(player != NULL); // Store formspec in LocalPlayer @@ -1098,7 +1098,7 @@ void Client::handleCommand_HudSetFlags(NetworkPacket* pkt) *pkt >> flags >> mask; - Player *player = m_env.getLocalPlayer(); + LocalPlayer *player = m_env.getLocalPlayer(); assert(player != NULL); bool was_minimap_visible = player->hud_flags & HUD_FLAG_MINIMAP_VISIBLE; diff --git a/src/network/serverpackethandler.cpp b/src/network/serverpackethandler.cpp index 6ef768295..554025747 100644 --- a/src/network/serverpackethandler.cpp +++ b/src/network/serverpackethandler.cpp @@ -1052,7 +1052,7 @@ void Server::handleCommand_ChatMessage(NetworkPacket* pkt) message += (wchar_t)tmp_wchar; } - Player *player = m_env->getPlayer(pkt->getPeerId()); + RemotePlayer *player = m_env->getPlayer(pkt->getPeerId()); if (player == NULL) { errorstream << "Server::ProcessData(): Canceling: " "No player for peer_id=" << pkt->getPeerId() @@ -1179,7 +1179,7 @@ void Server::handleCommand_Password(NetworkPacket* pkt) newpwd += c; } - Player *player = m_env->getPlayer(pkt->getPeerId()); + RemotePlayer *player = m_env->getPlayer(pkt->getPeerId()); if (player == NULL) { errorstream << "Server::ProcessData(): Canceling: " "No player for peer_id=" << pkt->getPeerId() @@ -1255,7 +1255,7 @@ void Server::handleCommand_PlayerItem(NetworkPacket* pkt) void Server::handleCommand_Respawn(NetworkPacket* pkt) { - Player *player = m_env->getPlayer(pkt->getPeerId()); + RemotePlayer *player = m_env->getPlayer(pkt->getPeerId()); if (player == NULL) { errorstream << "Server::ProcessData(): Canceling: " "No player for peer_id=" << pkt->getPeerId() diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp index b58d8e6cd..74b33da37 100644 --- a/src/script/lua_api/l_object.cpp +++ b/src/script/lua_api/l_object.cpp @@ -533,7 +533,7 @@ int ObjectRef::l_get_local_animation(lua_State *L) { NO_MAP_LOCK_REQUIRED ObjectRef *ref = checkobject(L, 1); - Player *player = getplayer(ref); + RemotePlayer *player = getplayer(ref); if (player == NULL) return 0; @@ -584,7 +584,7 @@ int ObjectRef::l_get_eye_offset(lua_State *L) { NO_MAP_LOCK_REQUIRED; ObjectRef *ref = checkobject(L, 1); - Player *player = getplayer(ref); + RemotePlayer *player = getplayer(ref); if (player == NULL) return 0; // Do it @@ -762,7 +762,7 @@ int ObjectRef::l_is_player(lua_State *L) { NO_MAP_LOCK_REQUIRED; ObjectRef *ref = checkobject(L, 1); - Player *player = getplayer(ref); + RemotePlayer *player = getplayer(ref); lua_pushboolean(L, (player != NULL)); return 1; } @@ -973,7 +973,7 @@ int ObjectRef::l_is_player_connected(lua_State *L) { NO_MAP_LOCK_REQUIRED; ObjectRef *ref = checkobject(L, 1); - Player *player = getplayer(ref); + RemotePlayer *player = getplayer(ref); lua_pushboolean(L, (player != NULL && player->peer_id != 0)); return 1; } @@ -983,7 +983,7 @@ int ObjectRef::l_get_player_name(lua_State *L) { NO_MAP_LOCK_REQUIRED; ObjectRef *ref = checkobject(L, 1); - Player *player = getplayer(ref); + RemotePlayer *player = getplayer(ref); if (player == NULL) { lua_pushlstring(L, "", 0); return 1; @@ -998,7 +998,7 @@ int ObjectRef::l_get_player_velocity(lua_State *L) { NO_MAP_LOCK_REQUIRED; ObjectRef *ref = checkobject(L, 1); - Player *player = getplayer(ref); + RemotePlayer *player = getplayer(ref); if (player == NULL) { lua_pushnil(L); return 1; @@ -1013,7 +1013,7 @@ int ObjectRef::l_get_look_dir(lua_State *L) { NO_MAP_LOCK_REQUIRED; ObjectRef *ref = checkobject(L, 1); - Player *player = getplayer(ref); + RemotePlayer *player = getplayer(ref); if (player == NULL) return 0; // Do it float pitch = player->getRadPitchDep(); @@ -1033,7 +1033,7 @@ int ObjectRef::l_get_look_pitch(lua_State *L) "Deprecated call to get_look_pitch, use get_look_vertical instead"); ObjectRef *ref = checkobject(L, 1); - Player *player = getplayer(ref); + RemotePlayer *player = getplayer(ref); if (player == NULL) return 0; // Do it lua_pushnumber(L, player->getRadPitchDep()); @@ -1050,7 +1050,7 @@ int ObjectRef::l_get_look_yaw(lua_State *L) "Deprecated call to get_look_yaw, use get_look_horizontal instead"); ObjectRef *ref = checkobject(L, 1); - Player *player = getplayer(ref); + RemotePlayer *player = getplayer(ref); if (player == NULL) return 0; // Do it lua_pushnumber(L, player->getRadYawDep()); @@ -1062,7 +1062,7 @@ int ObjectRef::l_get_look_vertical(lua_State *L) { NO_MAP_LOCK_REQUIRED; ObjectRef *ref = checkobject(L, 1); - Player *player = getplayer(ref); + RemotePlayer *player = getplayer(ref); if (player == NULL) return 0; // Do it lua_pushnumber(L, player->getRadPitch()); @@ -1074,7 +1074,7 @@ int ObjectRef::l_get_look_horizontal(lua_State *L) { NO_MAP_LOCK_REQUIRED; ObjectRef *ref = checkobject(L, 1); - Player *player = getplayer(ref); + RemotePlayer *player = getplayer(ref); if (player == NULL) return 0; // Do it lua_pushnumber(L, player->getRadYaw()); @@ -1179,7 +1179,7 @@ int ObjectRef::l_set_inventory_formspec(lua_State *L) { NO_MAP_LOCK_REQUIRED; ObjectRef *ref = checkobject(L, 1); - Player *player = getplayer(ref); + RemotePlayer *player = getplayer(ref); if (player == NULL) return 0; std::string formspec = luaL_checkstring(L, 2); @@ -1194,7 +1194,7 @@ int ObjectRef::l_get_inventory_formspec(lua_State *L) { NO_MAP_LOCK_REQUIRED; ObjectRef *ref = checkobject(L, 1); - Player *player = getplayer(ref); + RemotePlayer *player = getplayer(ref); if (player == NULL) return 0; std::string formspec = player->inventory_formspec; @@ -1207,7 +1207,7 @@ int ObjectRef::l_get_player_control(lua_State *L) { NO_MAP_LOCK_REQUIRED; ObjectRef *ref = checkobject(L, 1); - Player *player = getplayer(ref); + RemotePlayer *player = getplayer(ref); if (player == NULL) { lua_pushlstring(L, "", 0); return 1; @@ -1241,7 +1241,7 @@ int ObjectRef::l_get_player_control_bits(lua_State *L) { NO_MAP_LOCK_REQUIRED; ObjectRef *ref = checkobject(L, 1); - Player *player = getplayer(ref); + RemotePlayer *player = getplayer(ref); if (player == NULL) { lua_pushlstring(L, "", 0); return 1; @@ -1416,7 +1416,7 @@ int ObjectRef::l_hud_get(lua_State *L) { NO_MAP_LOCK_REQUIRED; ObjectRef *ref = checkobject(L, 1); - Player *player = getplayer(ref); + RemotePlayer *player = getplayer(ref); if (player == NULL) return 0; @@ -1493,7 +1493,7 @@ int ObjectRef::l_hud_get_flags(lua_State *L) { NO_MAP_LOCK_REQUIRED; ObjectRef *ref = checkobject(L, 1); - Player *player = getplayer(ref); + RemotePlayer *player = getplayer(ref); if (player == NULL) return 0; @@ -1649,7 +1649,7 @@ int ObjectRef::l_get_sky(lua_State *L) { NO_MAP_LOCK_REQUIRED; ObjectRef *ref = checkobject(L, 1); - Player *player = getplayer(ref); + RemotePlayer *player = getplayer(ref); if (player == NULL) return 0; video::SColor bgcolor(255, 255, 255, 255); diff --git a/src/server.cpp b/src/server.cpp index dee8a3d70..67dbe1545 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -692,7 +692,7 @@ void Server::AsyncRunStep(bool initial_step) if (client->getState() < CS_DefinitionsSent) continue; - Player *player = m_env->getPlayer(client->peer_id); + RemotePlayer *player = m_env->getPlayer(client->peer_id); if (player == NULL) { // This can happen if the client timeouts somehow /*warningstream<getPlayer(peer_id); + RemotePlayer *player = m_env->getPlayer(peer_id); assert(player); NetworkPacket pkt(TOCLIENT_MOVE_PLAYER, sizeof(v3f) + sizeof(f32) * 2, peer_id); @@ -1896,7 +1896,7 @@ void Server::SendEyeOffset(u16 peer_id, v3f first, v3f third) } void Server::SendPlayerPrivileges(u16 peer_id) { - Player *player = m_env->getPlayer(peer_id); + RemotePlayer *player = m_env->getPlayer(peer_id); assert(player); if(player->peer_id == PEER_ID_INEXISTENT) return; @@ -1917,7 +1917,7 @@ void Server::SendPlayerPrivileges(u16 peer_id) void Server::SendPlayerInventoryFormspec(u16 peer_id) { - Player *player = m_env->getPlayer(peer_id); + RemotePlayer *player = m_env->getPlayer(peer_id); assert(player); if(player->peer_id == PEER_ID_INEXISTENT) return; @@ -1962,7 +1962,7 @@ s32 Server::playSound(const SimpleSoundSpec &spec, std::vector dst_clients; if(params.to_player != "") { - Player *player = m_env->getPlayer(params.to_player.c_str()); + RemotePlayer *player = m_env->getPlayer(params.to_player.c_str()); if(!player){ infostream<<"Server::playSound: Player \""< clients = m_clients.getClientIDs(); - for(std::vector::iterator - i = clients.begin(); i != clients.end(); ++i) { - Player *player = m_env->getPlayer(*i); - if(!player) + for (std::vector::iterator i = clients.begin(); i != clients.end(); ++i) { + RemotePlayer *player = m_env->getPlayer(*i); + if (!player) continue; - if(pos_exists) { + if (pos_exists) { if(player->getPosition().getDistanceFrom(pos) > params.max_hear_distance) continue; @@ -2048,7 +2047,7 @@ void Server::sendRemoveNode(v3s16 p, u16 ignore_id, i != clients.end(); ++i) { if (far_players) { // Get player - if(Player *player = m_env->getPlayer(*i)) { + if (RemotePlayer *player = m_env->getPlayer(*i)) { // If player is far away, only set modified blocks not sent v3f player_pos = player->getPosition(); if(player_pos.getDistanceFrom(p_f) > maxd) { @@ -2076,7 +2075,7 @@ void Server::sendAddNode(v3s16 p, MapNode n, u16 ignore_id, if(far_players) { // Get player - if(Player *player = m_env->getPlayer(*i)) { + if (RemotePlayer *player = m_env->getPlayer(*i)) { // If player is far away, only set modified blocks not sent v3f player_pos = player->getPosition(); if(player_pos.getDistanceFrom(p_f) > maxd) { @@ -2661,8 +2660,8 @@ void Server::DeleteClient(u16 peer_id, ClientDeletionReason reason) for(std::vector::iterator i = clients.begin(); i != clients.end(); ++i) { // Get player - Player *player = m_env->getPlayer(*i); - if(!player) + RemotePlayer *player = m_env->getPlayer(*i); + if (!player) continue; // Get name of player @@ -2842,8 +2841,8 @@ RemoteClient* Server::getClientNoEx(u16 peer_id, ClientState state_min) std::string Server::getPlayerName(u16 peer_id) { - Player *player = m_env->getPlayer(peer_id); - if(player == NULL) + RemotePlayer *player = m_env->getPlayer(peer_id); + if (player == NULL) return "[id="+itos(peer_id)+"]"; return player->getName(); } @@ -2870,13 +2869,12 @@ std::wstring Server::getStatusString() bool first = true; os< clients = m_clients.getClientIDs(); - for(std::vector::iterator i = clients.begin(); - i != clients.end(); ++i) { + for (std::vector::iterator i = clients.begin(); i != clients.end(); ++i) { // Get player - Player *player = m_env->getPlayer(*i); + RemotePlayer *player = m_env->getPlayer(*i); // Get name of player std::wstring name = L"unknown"; - if(player != NULL) + if (player != NULL) name = narrow_to_wide(player->getName()); // Add name to information string if(!first) @@ -2912,12 +2910,11 @@ void Server::reportPrivsModified(const std::string &name) std::vector clients = m_clients.getClientIDs(); for(std::vector::iterator i = clients.begin(); i != clients.end(); ++i) { - Player *player = m_env->getPlayer(*i); + RemotePlayer *player = m_env->getPlayer(*i); reportPrivsModified(player->getName()); } } else { - RemotePlayer *player = - dynamic_cast(m_env->getPlayer(name.c_str())); + RemotePlayer *player = m_env->getPlayer(name.c_str()); if (!player) return; SendPlayerPrivileges(player->peer_id); @@ -2932,8 +2929,8 @@ void Server::reportPrivsModified(const std::string &name) void Server::reportInventoryFormspecModified(const std::string &name) { - Player *player = m_env->getPlayer(name.c_str()); - if(!player) + RemotePlayer *player = m_env->getPlayer(name.c_str()); + if (!player) return; SendPlayerInventoryFormspec(player->peer_id); } @@ -2963,7 +2960,7 @@ void Server::notifyPlayer(const char *name, const std::wstring &msg) m_admin_chat->outgoing_queue.push_back(new ChatEventChat("", msg)); } - Player *player = m_env->getPlayer(name); + RemotePlayer *player = m_env->getPlayer(name); if (!player) { return; } @@ -2981,7 +2978,7 @@ bool Server::showFormspec(const char *playername, const std::string &formspec, if (!m_env) return false; - Player *player = m_env->getPlayer(playername); + RemotePlayer *player = m_env->getPlayer(playername); if (!player) return false; @@ -3152,7 +3149,7 @@ void Server::spawnParticle(const std::string &playername, v3f pos, u16 peer_id = PEER_ID_INEXISTENT; if (playername != "") { - Player* player = m_env->getPlayer(playername.c_str()); + RemotePlayer* player = m_env->getPlayer(playername.c_str()); if (!player) return; peer_id = player->peer_id; @@ -3176,7 +3173,7 @@ u32 Server::addParticleSpawner(u16 amount, float spawntime, u16 peer_id = PEER_ID_INEXISTENT; if (playername != "") { - Player* player = m_env->getPlayer(playername.c_str()); + RemotePlayer* player = m_env->getPlayer(playername.c_str()); if (!player) return -1; peer_id = player->peer_id; @@ -3199,7 +3196,7 @@ void Server::deleteParticleSpawner(const std::string &playername, u32 id) u16 peer_id = PEER_ID_INEXISTENT; if (playername != "") { - Player* player = m_env->getPlayer(playername.c_str()); + RemotePlayer* player = m_env->getPlayer(playername.c_str()); if (!player) return; peer_id = player->peer_id; -- cgit v1.2.3 From c9e7a27eeb628be78a835abadf8afe1177eb90c5 Mon Sep 17 00:00:00 2001 From: raymoo Date: Thu, 4 Aug 2016 13:09:21 -0700 Subject: Attached particle spawners --- doc/lua_api.txt | 2 + src/client.h | 1 + src/content_sao.cpp | 10 ++++- src/environment.cpp | 24 +++++++++++ src/environment.h | 4 +- src/network/clientpackethandler.cpp | 3 ++ src/particles.cpp | 81 ++++++++++++++++++++++++------------- src/particles.h | 3 +- src/script/lua_api/l_particles.cpp | 11 +++++ src/server.cpp | 17 ++++++-- src/server.h | 2 + src/serverobject.cpp | 1 - src/serverobject.h | 10 +++++ 13 files changed, 132 insertions(+), 37 deletions(-) (limited to 'src/network') diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 6bdcd4fe4..a1d598e7d 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -4120,6 +4120,8 @@ The Biome API is still in an experimental phase and subject to change. collision_removal = false, -- ^ collision_removal: if true then particle is removed when it collides, -- ^ requires collisiondetection = true to have any effect + attached = ObjectRef, + -- ^ attached: if defined, makes particle positions relative to this object. vertical = false, -- ^ vertical: if true faces player using y axis only texture = "image.png", diff --git a/src/client.h b/src/client.h index 6d24c0b1d..9f5bda059 100644 --- a/src/client.h +++ b/src/client.h @@ -201,6 +201,7 @@ struct ClientEvent f32 maxsize; bool collisiondetection; bool collision_removal; + u16 attached_id; bool vertical; std::string *texture; u32 id; diff --git a/src/content_sao.cpp b/src/content_sao.cpp index 5d3ed38bc..375a43c90 100644 --- a/src/content_sao.cpp +++ b/src/content_sao.cpp @@ -156,6 +156,11 @@ LuaEntitySAO::~LuaEntitySAO() if(m_registered){ m_env->getScriptIface()->luaentity_Remove(m_id); } + + for (UNORDERED_SET::iterator it = m_attached_particle_spawners.begin(); + it != m_attached_particle_spawners.end(); ++it) { + m_env->deleteParticleSpawner(*it, false); + } } void LuaEntitySAO::addedToEnvironment(u32 dtime_s) @@ -817,7 +822,6 @@ PlayerSAO::~PlayerSAO() { if(m_inventory != &m_player->inventory) delete m_inventory; - } std::string PlayerSAO::getDescription() @@ -844,6 +848,10 @@ void PlayerSAO::removingFromEnvironment() m_player->peer_id = 0; m_env->savePlayer(m_player); m_env->removePlayer(m_player); + for (UNORDERED_SET::iterator it = m_attached_particle_spawners.begin(); + it != m_attached_particle_spawners.end(); ++it) { + m_env->deleteParticleSpawner(*it, false); + } } } diff --git a/src/environment.cpp b/src/environment.cpp index ceaa01d7a..ceaf40d89 100644 --- a/src/environment.cpp +++ b/src/environment.cpp @@ -1518,6 +1518,30 @@ u32 ServerEnvironment::addParticleSpawner(float exptime) return id; } +u32 ServerEnvironment::addParticleSpawner(float exptime, u16 attached_id) +{ + u32 id = addParticleSpawner(exptime); + m_particle_spawner_attachments[id] = attached_id; + if (ServerActiveObject *obj = getActiveObject(attached_id)) { + obj->attachParticleSpawner(id); + } + return id; +} + +void ServerEnvironment::deleteParticleSpawner(u32 id, bool remove_from_object) +{ + m_particle_spawners.erase(id); + UNORDERED_MAP::iterator it = m_particle_spawner_attachments.find(id); + if (it != m_particle_spawner_attachments.end()) { + u16 obj_id = (*it).second; + ServerActiveObject *sao = getActiveObject(obj_id); + if (sao != NULL && remove_from_object) { + sao->detachParticleSpawner(id); + } + m_particle_spawner_attachments.erase(id); + } +} + ServerActiveObject* ServerEnvironment::getActiveObject(u16 id) { ActiveObjectMap::iterator n = m_active_objects.find(id); diff --git a/src/environment.h b/src/environment.h index 83ad69562..3f3c1cf2c 100644 --- a/src/environment.h +++ b/src/environment.h @@ -329,7 +329,8 @@ public: void loadDefaultMeta(); u32 addParticleSpawner(float exptime); - void deleteParticleSpawner(u32 id) { m_particle_spawners.erase(id); } + u32 addParticleSpawner(float exptime, u16 attached_id); + void deleteParticleSpawner(u32 id, bool remove_from_object = true); /* External ActiveObject interface @@ -519,6 +520,7 @@ private: // Particles IntervalLimiter m_particle_management_interval; UNORDERED_MAP m_particle_spawners; + UNORDERED_MAP m_particle_spawner_attachments; }; #ifndef SERVER diff --git a/src/network/clientpackethandler.cpp b/src/network/clientpackethandler.cpp index b39356e92..090741f9f 100644 --- a/src/network/clientpackethandler.cpp +++ b/src/network/clientpackethandler.cpp @@ -944,9 +944,11 @@ void Client::handleCommand_AddParticleSpawner(NetworkPacket* pkt) bool vertical = false; bool collision_removal = false; + u16 attached_id = 0; try { *pkt >> vertical; *pkt >> collision_removal; + *pkt >> attached_id; } catch (...) {} @@ -966,6 +968,7 @@ void Client::handleCommand_AddParticleSpawner(NetworkPacket* pkt) event.add_particlespawner.maxsize = maxsize; event.add_particlespawner.collisiondetection = collisiondetection; event.add_particlespawner.collision_removal = collision_removal; + event.add_particlespawner.attached_id = attached_id; event.add_particlespawner.vertical = vertical; event.add_particlespawner.texture = new std::string(texture); event.add_particlespawner.id = id; diff --git a/src/particles.cpp b/src/particles.cpp index ccca691d1..2efee6ada 100644 --- a/src/particles.cpp +++ b/src/particles.cpp @@ -213,7 +213,7 @@ ParticleSpawner::ParticleSpawner(IGameDef* gamedef, scene::ISceneManager *smgr, u16 amount, float time, v3f minpos, v3f maxpos, v3f minvel, v3f maxvel, v3f minacc, v3f maxacc, float minexptime, float maxexptime, float minsize, float maxsize, - bool collisiondetection, bool collision_removal, bool vertical, + bool collisiondetection, bool collision_removal, u16 attached_id, bool vertical, video::ITexture *texture, u32 id, ParticleManager *p_manager) : m_particlemanager(p_manager) { @@ -234,6 +234,7 @@ ParticleSpawner::ParticleSpawner(IGameDef* gamedef, scene::ISceneManager *smgr, m_maxsize = maxsize; m_collisiondetection = collisiondetection; m_collision_removal = collision_removal; + m_attached_id = attached_id; m_vertical = vertical; m_texture = texture; m_time = 0; @@ -251,6 +252,15 @@ void ParticleSpawner::step(float dtime, ClientEnvironment* env) { m_time += dtime; + bool unloaded = false; + v3f attached_offset = v3f(0,0,0); + if (m_attached_id != 0) { + if (ClientActiveObject *attached = env->getActiveObject(m_attached_id)) + attached_offset = attached->getPosition() / BS; + else + unloaded = true; + } + if (m_spawntime != 0) // Spawner exists for a predefined timespan { for(std::vector::iterator i = m_spawntimes.begin(); @@ -260,33 +270,41 @@ void ParticleSpawner::step(float dtime, ClientEnvironment* env) { m_amount--; - v3f pos = random_v3f(m_minpos, m_maxpos); - v3f vel = random_v3f(m_minvel, m_maxvel); - v3f acc = random_v3f(m_minacc, m_maxacc); - float exptime = rand()/(float)RAND_MAX - *(m_maxexptime-m_minexptime) - +m_minexptime; - float size = rand()/(float)RAND_MAX - *(m_maxsize-m_minsize) - +m_minsize; - - Particle* toadd = new Particle( - m_gamedef, - m_smgr, - m_player, - env, - pos, - vel, - acc, - exptime, - size, - m_collisiondetection, - m_collision_removal, - m_vertical, - m_texture, - v2f(0.0, 0.0), - v2f(1.0, 1.0)); - m_particlemanager->addParticle(toadd); + // Pretend to, but don't actually spawn a + // particle if it is attached to an unloaded + // object. + if (!unloaded) { + v3f pos = random_v3f(m_minpos, m_maxpos) + + attached_offset; + v3f vel = random_v3f(m_minvel, m_maxvel); + v3f acc = random_v3f(m_minacc, m_maxacc); + // Make relative to offest + pos += attached_offset; + float exptime = rand()/(float)RAND_MAX + *(m_maxexptime-m_minexptime) + +m_minexptime; + float size = rand()/(float)RAND_MAX + *(m_maxsize-m_minsize) + +m_minsize; + + Particle* toadd = new Particle( + m_gamedef, + m_smgr, + m_player, + env, + pos, + vel, + acc, + exptime, + size, + m_collisiondetection, + m_collision_removal, + m_vertical, + m_texture, + v2f(0.0, 0.0), + v2f(1.0, 1.0)); + m_particlemanager->addParticle(toadd); + } i = m_spawntimes.erase(i); } else @@ -297,11 +315,15 @@ void ParticleSpawner::step(float dtime, ClientEnvironment* env) } else // Spawner exists for an infinity timespan, spawn on a per-second base { + // Skip this step if attached to an unloaded object + if (unloaded) + return; for (int i = 0; i <= m_amount; i++) { if (rand()/(float)RAND_MAX < dtime) { - v3f pos = random_v3f(m_minpos, m_maxpos); + v3f pos = random_v3f(m_minpos, m_maxpos) + + attached_offset; v3f vel = random_v3f(m_minvel, m_maxvel); v3f acc = random_v3f(m_minacc, m_maxacc); float exptime = rand()/(float)RAND_MAX @@ -453,6 +475,7 @@ void ParticleManager::handleParticleEvent(ClientEvent *event, IGameDef *gamedef, event->add_particlespawner.maxsize, event->add_particlespawner.collisiondetection, event->add_particlespawner.collision_removal, + event->add_particlespawner.attached_id, event->add_particlespawner.vertical, texture, event->add_particlespawner.id, diff --git a/src/particles.h b/src/particles.h index bc3ca53b7..eb8c6665d 100644 --- a/src/particles.h +++ b/src/particles.h @@ -119,6 +119,7 @@ class ParticleSpawner float minsize, float maxsize, bool collisiondetection, bool collision_removal, + u16 attached_id, bool vertical, video::ITexture *texture, u32 id, @@ -154,7 +155,7 @@ class ParticleSpawner bool m_collisiondetection; bool m_collision_removal; bool m_vertical; - + u16 m_attached_id; }; /** diff --git a/src/script/lua_api/l_particles.cpp b/src/script/lua_api/l_particles.cpp index 263e35407..667ac7272 100644 --- a/src/script/lua_api/l_particles.cpp +++ b/src/script/lua_api/l_particles.cpp @@ -18,6 +18,7 @@ with this program; if not, write to the Free Software Foundation, Inc., */ #include "lua_api/l_particles.h" +#include "lua_api/l_object.h" #include "lua_api/l_internal.h" #include "common/c_converter.h" #include "server.h" @@ -138,6 +139,7 @@ int ModApiParticles::l_add_particlespawner(lua_State *L) time= minexptime= maxexptime= minsize= maxsize= 1; bool collisiondetection, vertical, collision_removal; collisiondetection = vertical = collision_removal = false; + ServerActiveObject *attached = NULL; std::string texture = ""; std::string playername = ""; @@ -198,6 +200,14 @@ int ModApiParticles::l_add_particlespawner(lua_State *L) "collisiondetection", collisiondetection); collision_removal = getboolfield_default(L, 1, "collision_removal", collision_removal); + + lua_getfield(L, 1, "attached"); + if (!lua_isnil(L, -1)) { + ObjectRef *ref = ObjectRef::checkobject(L, -1); + lua_pop(L, 1); + attached = ObjectRef::getobject(ref); + } + vertical = getboolfield_default(L, 1, "vertical", vertical); texture = getstringfield_default(L, 1, "texture", ""); playername = getstringfield_default(L, 1, "playername", ""); @@ -211,6 +221,7 @@ int ModApiParticles::l_add_particlespawner(lua_State *L) minsize, maxsize, collisiondetection, collision_removal, + attached, vertical, texture, playername); lua_pushnumber(L, id); diff --git a/src/server.cpp b/src/server.cpp index a93c143c7..e67f37d56 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -1678,7 +1678,7 @@ void Server::SendSpawnParticle(u16 peer_id, v3f pos, v3f velocity, v3f accelerat void Server::SendAddParticleSpawner(u16 peer_id, u16 amount, float spawntime, v3f minpos, v3f maxpos, v3f minvel, v3f maxvel, v3f minacc, v3f maxacc, float minexptime, float maxexptime, float minsize, float maxsize, bool collisiondetection, bool collision_removal, - bool vertical, const std::string &texture, u32 id) + u16 attached_id, bool vertical, const std::string &texture, u32 id) { DSTACK(FUNCTION_NAME); @@ -1692,6 +1692,7 @@ void Server::SendAddParticleSpawner(u16 peer_id, u16 amount, float spawntime, v3 pkt << id << vertical; pkt << collision_removal; + pkt << attached_id; if (peer_id != PEER_ID_INEXISTENT) { Send(&pkt); @@ -3156,7 +3157,7 @@ u32 Server::addParticleSpawner(u16 amount, float spawntime, v3f minpos, v3f maxpos, v3f minvel, v3f maxvel, v3f minacc, v3f maxacc, float minexptime, float maxexptime, float minsize, float maxsize, bool collisiondetection, bool collision_removal, - bool vertical, const std::string &texture, + ServerActiveObject *attached, bool vertical, const std::string &texture, const std::string &playername) { // m_env will be NULL if the server is initializing @@ -3171,11 +3172,19 @@ u32 Server::addParticleSpawner(u16 amount, float spawntime, peer_id = player->peer_id; } - u32 id = m_env->addParticleSpawner(spawntime); + u16 attached_id = attached ? attached->getId() : 0; + + u32 id; + if (attached_id == 0) + id = m_env->addParticleSpawner(spawntime); + else + id = m_env->addParticleSpawner(spawntime, attached_id); + SendAddParticleSpawner(peer_id, amount, spawntime, minpos, maxpos, minvel, maxvel, minacc, maxacc, minexptime, maxexptime, minsize, maxsize, - collisiondetection, collision_removal, vertical, texture, id); + collisiondetection, collision_removal, attached_id, vertical, + texture, id); return id; } diff --git a/src/server.h b/src/server.h index 6ee61a0eb..5fc2a9133 100644 --- a/src/server.h +++ b/src/server.h @@ -258,6 +258,7 @@ public: float minexptime, float maxexptime, float minsize, float maxsize, bool collisiondetection, bool collision_removal, + ServerActiveObject *attached, bool vertical, const std::string &texture, const std::string &playername); @@ -434,6 +435,7 @@ private: float minexptime, float maxexptime, float minsize, float maxsize, bool collisiondetection, bool collision_removal, + u16 attached_id, bool vertical, const std::string &texture, u32 id); void SendDeleteParticleSpawner(u16 peer_id, u32 id); diff --git a/src/serverobject.cpp b/src/serverobject.cpp index 236d7e8dc..191247829 100644 --- a/src/serverobject.cpp +++ b/src/serverobject.cpp @@ -98,4 +98,3 @@ bool ServerActiveObject::setWieldedItem(const ItemStack &item) } return false; } - diff --git a/src/serverobject.h b/src/serverobject.h index cfe2b6bcc..63650e3be 100644 --- a/src/serverobject.h +++ b/src/serverobject.h @@ -188,6 +188,15 @@ public: { return 0; } virtual ItemStack getWieldedItem() const; virtual bool setWieldedItem(const ItemStack &item); + inline void attachParticleSpawner(u32 id) + { + m_attached_particle_spawners.insert(id); + } + inline void detachParticleSpawner(u32 id) + { + m_attached_particle_spawners.erase(id); + } + /* Number of players which know about this object. Object won't be @@ -242,6 +251,7 @@ protected: ServerEnvironment *m_env; v3f m_base_position; + UNORDERED_SET m_attached_particle_spawners; private: // Used for creating objects based on type -- cgit v1.2.3 From 9d25242c5c1411d692254cf910345d51c9a24fa3 Mon Sep 17 00:00:00 2001 From: Ner'zhul Date: Sun, 30 Oct 2016 14:53:26 +0100 Subject: PlayerSAO/LocalPlayer refactor: (#4612) * Create UnitSAO, a common part between PlayerSAO & LuaEntitySAO * Move breath to PlayerSAO & LocalPlayer * Migrate m_yaw from (Remote)Player & LuaEntitySAO to UnitSAO * Migrate m_yaw from Player to LocalPlayer for client * Move some functions outside of player class to PlayerSAO/RemotePlayer or LocalPlayer depending on which class needs it * Move pitch to LocalPlayer & PlayerSAO * Move m_position from Player to LocalPlayer * Move camera_barely_in_ceiling to LocalPlayer as it's used only there * use PlayerSAO::m_base_position for Server side positions * remove a unused variable * ServerActiveObject::setPos now uses const ref * use ServerEnv::loadPlayer unconditionnaly as it creates RemotePlayer only if it's not already loaded * Move hp from Player to LocalPlayer * Move m_hp from LuaEntitySAO to UnitSAO * Use m_hp from PlayerSAO/UnitSAO instead of RemotePlayer --- src/clientiface.cpp | 14 ++-- src/collision.cpp | 2 +- src/content_sao.cpp | 155 +++++++++++++++++++----------------- src/content_sao.h | 62 +++++++++++---- src/environment.cpp | 35 ++++---- src/environment.h | 7 +- src/localplayer.cpp | 7 ++ src/localplayer.h | 41 ++++++++++ src/network/clientpackethandler.cpp | 1 - src/network/serverpackethandler.cpp | 55 +++++++------ src/player.cpp | 14 +--- src/player.h | 50 ------------ src/remoteplayer.cpp | 66 +++++++-------- src/remoteplayer.h | 35 +------- src/script/lua_api/l_object.cpp | 32 ++++---- src/server.cpp | 71 +++++++++-------- src/serverobject.h | 2 +- src/unittest/test_player.cpp | 39 +++++---- 18 files changed, 353 insertions(+), 335 deletions(-) (limited to 'src/network') diff --git a/src/clientiface.cpp b/src/clientiface.cpp index d78cf1c53..d2e3a6da0 100644 --- a/src/clientiface.cpp +++ b/src/clientiface.cpp @@ -29,7 +29,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "environment.h" #include "map.h" #include "emerge.h" -#include "serverobject.h" // TODO this is used for cleanup of only +#include "content_sao.h" // TODO this is used for cleanup of only #include "log.h" #include "util/srp.h" @@ -82,6 +82,10 @@ void RemoteClient::GetNextBlocks ( if (player == NULL) return; + PlayerSAO *sao = player->getPlayerSAO(); + if (sao == NULL) + return; + // Won't send anything if already sending if(m_blocks_sending.size() >= g_settings->getU16 ("max_simultaneous_block_sends_per_client")) @@ -90,7 +94,7 @@ void RemoteClient::GetNextBlocks ( return; } - v3f playerpos = player->getPosition(); + v3f playerpos = sao->getBasePosition(); v3f playerspeed = player->getSpeed(); v3f playerspeeddir(0,0,0); if(playerspeed.getLength() > 1.0*BS) @@ -103,10 +107,10 @@ void RemoteClient::GetNextBlocks ( v3s16 center = getNodeBlockPos(center_nodepos); // Camera position and direction - v3f camera_pos = player->getEyePosition(); + v3f camera_pos = sao->getEyePosition(); v3f camera_dir = v3f(0,0,1); - camera_dir.rotateYZBy(player->getPitch()); - camera_dir.rotateXZBy(player->getYaw()); + camera_dir.rotateYZBy(sao->getPitch()); + camera_dir.rotateXZBy(sao->getYaw()); /*infostream<<"camera_dir=("<(env); - if (s_env != 0) { + if (s_env != NULL) { f32 distance = speed_f->getLength(); std::vector s_objects; s_env->getObjectsInsideRadius(s_objects, *pos_f, distance * 1.5); diff --git a/src/content_sao.cpp b/src/content_sao.cpp index 375a43c90..23a064085 100644 --- a/src/content_sao.cpp +++ b/src/content_sao.cpp @@ -118,14 +118,12 @@ LuaEntitySAO proto_LuaEntitySAO(NULL, v3f(0,0,0), "_prototype", ""); LuaEntitySAO::LuaEntitySAO(ServerEnvironment *env, v3f pos, const std::string &name, const std::string &state): - ServerActiveObject(env, pos), + UnitSAO(env, pos), m_init_name(name), m_init_state(state), m_registered(false), - m_hp(-1), m_velocity(0,0,0), m_acceleration(0,0,0), - m_yaw(0), m_properties_sent(true), m_last_sent_yaw(0), m_last_sent_position(0,0,0), @@ -664,16 +662,6 @@ v3f LuaEntitySAO::getAcceleration() return m_acceleration; } -void LuaEntitySAO::setYaw(float yaw) -{ - m_yaw = yaw; -} - -float LuaEntitySAO::getYaw() -{ - return m_yaw; -} - void LuaEntitySAO::setTextureMod(const std::string &mod) { std::string str = gob_cmd_set_texture_mod(mod); @@ -762,10 +750,9 @@ bool LuaEntitySAO::collideWithObjects(){ // No prototype, PlayerSAO does not need to be deserialized -PlayerSAO::PlayerSAO(ServerEnvironment *env_, RemotePlayer *player_, u16 peer_id_, - const std::set &privs, bool is_singleplayer): - ServerActiveObject(env_, v3f(0,0,0)), - m_player(player_), +PlayerSAO::PlayerSAO(ServerEnvironment *env_, u16 peer_id_, bool is_singleplayer): + UnitSAO(env_, v3f(0,0,0)), + m_player(NULL), m_peer_id(peer_id_), m_inventory(NULL), m_damage(0), @@ -777,7 +764,6 @@ PlayerSAO::PlayerSAO(ServerEnvironment *env_, RemotePlayer *player_, u16 peer_id m_position_not_sent(false), m_armor_groups_sent(false), m_properties_sent(true), - m_privs(privs), m_is_singleplayer(is_singleplayer), m_animation_speed(0), m_animation_blend(0), @@ -786,6 +772,8 @@ PlayerSAO::PlayerSAO(ServerEnvironment *env_, RemotePlayer *player_, u16 peer_id m_bone_position_sent(false), m_attachment_parent_id(0), m_attachment_sent(false), + m_breath(PLAYER_MAX_BREATH), + m_pitch(0), // public m_physics_override_speed(1), m_physics_override_jump(1), @@ -794,10 +782,7 @@ PlayerSAO::PlayerSAO(ServerEnvironment *env_, RemotePlayer *player_, u16 peer_id m_physics_override_sneak_glitch(true), m_physics_override_sent(false) { - assert(m_player); // pre-condition assert(m_peer_id != 0); // pre-condition - setBasePosition(m_player->getPosition()); - m_inventory = &m_player->inventory; m_armor_groups["fleshy"] = 100; m_prop.hp_max = PLAYER_MAX_HP; @@ -816,6 +801,7 @@ PlayerSAO::PlayerSAO(ServerEnvironment *env_, RemotePlayer *player_, u16 peer_id // end of default appearance m_prop.is_visible = true; m_prop.makes_footstep_sound = true; + m_hp = PLAYER_MAX_HP; } PlayerSAO::~PlayerSAO() @@ -824,6 +810,14 @@ PlayerSAO::~PlayerSAO() delete m_inventory; } +void PlayerSAO::initialize(RemotePlayer *player, const std::set &privs) +{ + assert(player); + m_player = player; + m_privs = privs; + m_inventory = &m_player->inventory; +} + std::string PlayerSAO::getDescription() { return std::string("player ") + m_player->getName(); @@ -833,10 +827,10 @@ std::string PlayerSAO::getDescription() void PlayerSAO::addedToEnvironment(u32 dtime_s) { ServerActiveObject::addedToEnvironment(dtime_s); - ServerActiveObject::setBasePosition(m_player->getPosition()); + ServerActiveObject::setBasePosition(m_base_position); m_player->setPlayerSAO(this); m_player->peer_id = m_peer_id; - m_last_good_position = m_player->getPosition(); + m_last_good_position = m_base_position; } // Called before removing from environment @@ -844,9 +838,9 @@ void PlayerSAO::removingFromEnvironment() { ServerActiveObject::removingFromEnvironment(); if (m_player->getPlayerSAO() == this) { - m_player->setPlayerSAO(NULL); m_player->peer_id = 0; m_env->savePlayer(m_player); + m_player->setPlayerSAO(NULL); m_env->removePlayer(m_player); for (UNORDERED_SET::iterator it = m_attached_particle_spawners.begin(); it != m_attached_particle_spawners.end(); ++it) { @@ -870,8 +864,8 @@ std::string PlayerSAO::getClientInitializationData(u16 protocol_version) os<getName()); // name writeU8(os, 1); // is_player writeS16(os, getId()); //id - writeV3F1000(os, m_player->getPosition() + v3f(0,BS*1,0)); - writeF1000(os, m_player->getYaw()); + writeV3F1000(os, m_base_position + v3f(0,BS*1,0)); + writeF1000(os, m_yaw); writeS16(os, getHP()); writeU8(os, 6 + m_bone_position.size() + m_attachment_child_ids.size()); // number of messages stuffed in here @@ -900,8 +894,8 @@ std::string PlayerSAO::getClientInitializationData(u16 protocol_version) writeU8(os, 0); // version os<getName()); // name writeU8(os, 1); // is_player - writeV3F1000(os, m_player->getPosition() + v3f(0,BS*1,0)); - writeF1000(os, m_player->getYaw()); + writeV3F1000(os, m_base_position + v3f(0,BS*1,0)); + writeF1000(os, m_yaw); writeS16(os, getHP()); writeU8(os, 2); // number of messages stuffed in here os<setPosition(m_last_good_position); + setBasePosition(m_last_good_position); ((Server*)m_env->getGameDef())->SendMovePlayer(m_peer_id); } @@ -969,14 +963,13 @@ void PlayerSAO::step(float dtime, bool send_recommended) // Each frame, parent position is copied if the object is attached, otherwise it's calculated normally // If the object gets detached this comes into effect automatically from the last known origin - if(isAttached()) - { + if (isAttached()) { v3f pos = m_env->getActiveObject(m_attachment_parent_id)->getBasePosition(); m_last_good_position = pos; - m_player->setPosition(pos); + setBasePosition(pos); } - if(send_recommended == false) + if (!send_recommended) return; // If the object is attached client-side, don't waste bandwidth sending its position to clients @@ -988,12 +981,12 @@ void PlayerSAO::step(float dtime, bool send_recommended) if(isAttached()) // Just in case we ever do send attachment position too pos = m_env->getActiveObject(m_attachment_parent_id)->getBasePosition(); else - pos = m_player->getPosition() + v3f(0,BS*1,0); + pos = m_base_position + v3f(0,BS*1,0); std::string str = gob_cmd_update_position( pos, v3f(0,0,0), v3f(0,0,0), - m_player->getYaw(), + m_yaw, true, false, update_interval @@ -1003,7 +996,7 @@ void PlayerSAO::step(float dtime, bool send_recommended) m_messages_out.push(aom); } - if(m_armor_groups_sent == false) { + if (!m_armor_groups_sent) { m_armor_groups_sent = true; std::string str = gob_cmd_update_armor_groups( m_armor_groups); @@ -1012,7 +1005,7 @@ void PlayerSAO::step(float dtime, bool send_recommended) m_messages_out.push(aom); } - if(m_physics_override_sent == false){ + if (!m_physics_override_sent) { 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, @@ -1022,7 +1015,7 @@ void PlayerSAO::step(float dtime, bool send_recommended) m_messages_out.push(aom); } - if(m_animation_sent == false){ + if (!m_animation_sent) { m_animation_sent = true; std::string str = gob_cmd_update_animation( m_animation_range, m_animation_speed, m_animation_blend, m_animation_loop); @@ -1055,16 +1048,20 @@ void PlayerSAO::step(float dtime, bool send_recommended) void PlayerSAO::setBasePosition(const v3f &position) { + if (m_player && position != m_base_position) + m_player->setDirty(true); + // This needs to be ran for attachments too ServerActiveObject::setBasePosition(position); m_position_not_sent = true; } -void PlayerSAO::setPos(v3f pos) +void PlayerSAO::setPos(const v3f &pos) { if(isAttached()) return; - m_player->setPosition(pos); + + setBasePosition(pos); // Movement caused by this command is always valid m_last_good_position = pos; ((Server*)m_env->getGameDef())->SendMovePlayer(m_peer_id); @@ -1074,22 +1071,34 @@ void PlayerSAO::moveTo(v3f pos, bool continuous) { if(isAttached()) return; - m_player->setPosition(pos); + + setBasePosition(pos); // Movement caused by this command is always valid m_last_good_position = pos; ((Server*)m_env->getGameDef())->SendMovePlayer(m_peer_id); } -void PlayerSAO::setYaw(float yaw) +void PlayerSAO::setYaw(const float yaw, bool send_data) { - m_player->setYaw(yaw); - ((Server*)m_env->getGameDef())->SendMovePlayer(m_peer_id); + if (m_player && yaw != m_yaw) + m_player->setDirty(true); + + UnitSAO::setYaw(yaw); + + // Datas should not be sent at player initialization + if (send_data) + ((Server*)m_env->getGameDef())->SendMovePlayer(m_peer_id); } -void PlayerSAO::setPitch(float pitch) +void PlayerSAO::setPitch(const float pitch, bool send_data) { - m_player->setPitch(pitch); - ((Server*)m_env->getGameDef())->SendMovePlayer(m_peer_id); + if (m_player && pitch != m_pitch) + m_player->setDirty(true); + + m_pitch = pitch; + + if (send_data) + ((Server*)m_env->getGameDef())->SendMovePlayer(m_peer_id); } int PlayerSAO::punch(v3f dir, @@ -1153,13 +1162,8 @@ int PlayerSAO::punch(v3f dir, return hitparams.wear; } -void PlayerSAO::rightClick(ServerActiveObject *clicker) -{ -} - -s16 PlayerSAO::getHP() const +void PlayerSAO::rightClick(ServerActiveObject *) { - return m_player->hp; } s16 PlayerSAO::readDamage() @@ -1169,12 +1173,16 @@ s16 PlayerSAO::readDamage() return damage; } -void PlayerSAO::setHP(s16 hp) +void PlayerSAO::setHP(s16 hp, bool direct) { - s16 oldhp = m_player->hp; + if (direct) { + m_hp = hp; + return; + } + + s16 oldhp = m_hp; - s16 hp_change = m_env->getScriptIface()->on_player_hpchange(this, - hp - oldhp); + s16 hp_change = m_env->getScriptIface()->on_player_hpchange(this, hp - oldhp); if (hp_change == 0) return; hp = oldhp + hp_change; @@ -1184,11 +1192,11 @@ void PlayerSAO::setHP(s16 hp) else if (hp > PLAYER_MAX_HP) hp = PLAYER_MAX_HP; - if(hp < oldhp && g_settings->getBool("enable_damage") == false) { + if (hp < oldhp && !g_settings->getBool("enable_damage")) { return; } - m_player->hp = hp; + m_hp = hp; if (oldhp > hp) m_damage += (oldhp - hp); @@ -1198,14 +1206,12 @@ void PlayerSAO::setHP(s16 hp) m_properties_sent = false; } -u16 PlayerSAO::getBreath() const +void PlayerSAO::setBreath(const u16 breath) { - return m_player->getBreath(); -} + if (m_player && breath != m_breath) + m_player->setDirty(true); -void PlayerSAO::setBreath(u16 breath) -{ - m_player->setBreath(breath); + m_breath = breath; } void PlayerSAO::setArmorGroups(const ItemGroupList &armor_groups) @@ -1355,7 +1361,7 @@ bool PlayerSAO::checkMovementCheat() { if (isAttached() || m_is_singleplayer || g_settings->getBool("disable_anticheat")) { - m_last_good_position = m_player->getPosition(); + m_last_good_position = m_base_position; return false; } @@ -1382,7 +1388,7 @@ bool PlayerSAO::checkMovementCheat() // Tolerance. The lag pool does this a bit. //player_max_speed *= 2.5; - v3f diff = (m_player->getPosition() - m_last_good_position); + v3f diff = (m_base_position - m_last_good_position); float d_vert = diff.Y; diff.Y = 0; float d_horiz = diff.getLength(); @@ -1392,27 +1398,26 @@ bool PlayerSAO::checkMovementCheat() required_time = d_vert / player_max_speed; // Moving upwards if (m_move_pool.grab(required_time)) { - m_last_good_position = m_player->getPosition(); + m_last_good_position = m_base_position; } else { actionstream << "Player " << m_player->getName() << " moved too fast; resetting position" << std::endl; - m_player->setPosition(m_last_good_position); + setBasePosition(m_last_good_position); cheated = true; } return cheated; } -bool PlayerSAO::getCollisionBox(aabb3f *toset) { - //update collision box - *toset = m_player->getCollisionbox(); - +bool PlayerSAO::getCollisionBox(aabb3f *toset) +{ + *toset = aabb3f(-BS * 0.30, 0.0, -BS * 0.30, BS * 0.30, BS * 1.75, BS * 0.30); toset->MinEdge += m_base_position; toset->MaxEdge += m_base_position; - return true; } -bool PlayerSAO::collideWithObjects(){ +bool PlayerSAO::collideWithObjects() +{ return true; } diff --git a/src/content_sao.h b/src/content_sao.h index 76a3a37da..4ea6277ff 100644 --- a/src/content_sao.h +++ b/src/content_sao.h @@ -23,12 +23,35 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "serverobject.h" #include "itemgroup.h" #include "object_properties.h" +#include "constants.h" + +class UnitSAO: public ServerActiveObject +{ +public: + UnitSAO(ServerEnvironment *env, v3f pos): + ServerActiveObject(env, pos), + m_hp(-1), m_yaw(0) {} + virtual ~UnitSAO() {} + + virtual void setYaw(const float yaw) { m_yaw = yaw; } + float getYaw() const { return m_yaw; }; + f32 getRadYaw() const { return m_yaw * core::DEGTORAD; } + // Deprecated + f32 getRadYawDep() const { return (m_yaw + 90.) * core::DEGTORAD; } + + s16 getHP() const { return m_hp; } + // Use a function, if isDead can be defined by other conditions + bool isDead() const { return m_hp == 0; } +protected: + s16 m_hp; + float m_yaw; +}; /* LuaEntitySAO needs some internals exposed. */ -class LuaEntitySAO : public ServerActiveObject +class LuaEntitySAO : public UnitSAO { public: LuaEntitySAO(ServerEnvironment *env, v3f pos, @@ -74,8 +97,7 @@ public: v3f getVelocity(); void setAcceleration(v3f acceleration); v3f getAcceleration(); - void setYaw(float yaw); - float getYaw(); + void setTextureMod(const std::string &mod); void setSprite(v2s16 p, int num_frames, float framelength, bool select_horiz_by_yawpitch); @@ -91,10 +113,9 @@ private: bool m_registered; struct ObjectProperties m_prop; - s16 m_hp; v3f m_velocity; v3f m_acceleration; - float m_yaw; + ItemGroupList m_armor_groups; bool m_properties_sent; @@ -158,11 +179,10 @@ public: class RemotePlayer; -class PlayerSAO : public ServerActiveObject +class PlayerSAO : public UnitSAO { public: - PlayerSAO(ServerEnvironment *env_, RemotePlayer *player_, u16 peer_id_, - const std::set &privs, bool is_singleplayer); + PlayerSAO(ServerEnvironment *env_, u16 peer_id_, bool is_singleplayer); ~PlayerSAO(); ActiveObjectType getType() const { return ACTIVEOBJECT_TYPE_PLAYER; } @@ -182,10 +202,14 @@ public: bool isAttached(); void step(float dtime, bool send_recommended); void setBasePosition(const v3f &position); - void setPos(v3f pos); + void setPos(const v3f &pos); void moveTo(v3f pos, bool continuous); - void setYaw(float); - void setPitch(float); + void setYaw(const float yaw, bool send_data = true); + void setPitch(const float pitch, bool send_data = true); + f32 getPitch() const { return m_pitch; } + f32 getRadPitch() const { return m_pitch * core::DEGTORAD; } + // Deprecated + f32 getRadPitchDep() const { return -1.0 * m_pitch * core::DEGTORAD; } /* Interaction interface @@ -196,11 +220,10 @@ public: ServerActiveObject *puncher, float time_from_last_punch); void rightClick(ServerActiveObject *clicker); - s16 getHP() const; - void setHP(s16 hp); + void setHP(s16 hp, bool direct = false); s16 readDamage(); - u16 getBreath() const; - void setBreath(u16 breath); + u16 getBreath() const { return m_breath; } + void setBreath(const u16 breath); void setArmorGroups(const ItemGroupList &armor_groups); ItemGroupList getArmorGroups(); void setAnimation(v2f frame_range, float frame_speed, float frame_blend, bool frame_loop); @@ -283,6 +306,11 @@ public: bool getCollisionBox(aabb3f *toset); bool collideWithObjects(); + void initialize(RemotePlayer *player, const std::set &privs); + + v3f getEyePosition() const { return m_base_position + getEyeOffset(); } + v3f getEyeOffset() const { return v3f(0, BS * 1.625f, 0); } + private: std::string getPropertyPacket(); @@ -326,8 +354,8 @@ private: v3f m_attachment_position; v3f m_attachment_rotation; bool m_attachment_sent; - - + u16 m_breath; + f32 m_pitch; public: float m_physics_override_speed; float m_physics_override_jump; diff --git a/src/environment.cpp b/src/environment.cpp index ecda1b6a4..13c64b37c 100644 --- a/src/environment.cpp +++ b/src/environment.cpp @@ -608,9 +608,8 @@ void ServerEnvironment::saveLoadedPlayers() for (std::vector::iterator it = m_players.begin(); it != m_players.end(); ++it) { - RemotePlayer *player = static_cast(*it); - if (player->checkModified()) { - player->save(players_path, m_gamedef); + if ((*it)->checkModified()) { + (*it)->save(players_path, m_gamedef); } } } @@ -623,7 +622,7 @@ void ServerEnvironment::savePlayer(RemotePlayer *player) player->save(players_path, m_gamedef); } -RemotePlayer *ServerEnvironment::loadPlayer(const std::string &playername) +RemotePlayer *ServerEnvironment::loadPlayer(const std::string &playername, PlayerSAO *sao) { bool newplayer = false; bool found = false; @@ -641,7 +640,8 @@ RemotePlayer *ServerEnvironment::loadPlayer(const std::string &playername) std::ifstream is(path.c_str(), std::ios_base::binary); if (!is.good()) continue; - player->deSerialize(is, path); + + player->deSerialize(is, path, sao); is.close(); if (player->getName() == playername) { @@ -657,11 +657,13 @@ RemotePlayer *ServerEnvironment::loadPlayer(const std::string &playername) << " not found" << std::endl; if (newplayer) delete player; + return NULL; } - if (newplayer) + if (newplayer) { addPlayer(player); + } player->setModified(false); return player; } @@ -1271,12 +1273,16 @@ void ServerEnvironment::step(float dtime) i != m_players.end(); ++i) { RemotePlayer *player = dynamic_cast(*i); assert(player); + // Ignore disconnected players if (player->peer_id == 0) continue; + PlayerSAO *playersao = player->getPlayerSAO(); + assert(playersao); + v3s16 blockpos = getNodeBlockPos( - floatToInt(player->getPosition(), BS)); + floatToInt(playersao->getBasePosition(), BS)); players_blockpos.push_back(blockpos); } @@ -1584,7 +1590,7 @@ u16 ServerEnvironment::addActiveObject(ServerActiveObject *object) Finds out what new objects have been added to inside a radius around a position */ -void ServerEnvironment::getAddedActiveObjects(RemotePlayer *player, s16 radius, +void ServerEnvironment::getAddedActiveObjects(PlayerSAO *playersao, s16 radius, s16 player_radius, std::set ¤t_objects, std::queue &added_objects) @@ -1594,7 +1600,6 @@ void ServerEnvironment::getAddedActiveObjects(RemotePlayer *player, s16 radius, if (player_radius_f < 0) player_radius_f = 0; - /* Go through the object list, - discard m_removed objects, @@ -1602,20 +1607,21 @@ void ServerEnvironment::getAddedActiveObjects(RemotePlayer *player, s16 radius, - discard objects that are found in current_objects. - add remaining objects to added_objects */ - for(ActiveObjectMap::iterator i = m_active_objects.begin(); + for (ActiveObjectMap::iterator i = m_active_objects.begin(); i != m_active_objects.end(); ++i) { u16 id = i->first; // Get object ServerActiveObject *object = i->second; - if(object == NULL) + if (object == NULL) continue; // Discard if removed or deactivating if(object->m_removed || object->m_pending_deactivation) continue; - f32 distance_f = object->getBasePosition().getDistanceFrom(player->getPosition()); + f32 distance_f = object->getBasePosition(). + getDistanceFrom(playersao->getBasePosition()); if (object->getType() == ACTIVEOBJECT_TYPE_PLAYER) { // Discard if too far if (distance_f > player_radius_f && player_radius_f != 0) @@ -1637,7 +1643,7 @@ void ServerEnvironment::getAddedActiveObjects(RemotePlayer *player, s16 radius, Finds out what objects have been removed from inside a radius around a position */ -void ServerEnvironment::getRemovedActiveObjects(RemotePlayer *player, s16 radius, +void ServerEnvironment::getRemovedActiveObjects(PlayerSAO *playersao, s16 radius, s16 player_radius, std::set ¤t_objects, std::queue &removed_objects) @@ -1647,7 +1653,6 @@ void ServerEnvironment::getRemovedActiveObjects(RemotePlayer *player, s16 radius if (player_radius_f < 0) player_radius_f = 0; - /* Go through current_objects; object is removed if: - object is not found in m_active_objects (this is actually an @@ -1675,7 +1680,7 @@ void ServerEnvironment::getRemovedActiveObjects(RemotePlayer *player, s16 radius continue; } - f32 distance_f = object->getBasePosition().getDistanceFrom(player->getPosition()); + f32 distance_f = object->getBasePosition().getDistanceFrom(playersao->getBasePosition()); if (object->getType() == ACTIVEOBJECT_TYPE_PLAYER) { if (distance_f <= player_radius_f || player_radius_f == 0) continue; diff --git a/src/environment.h b/src/environment.h index 3f3c1cf2c..4bee40e57 100644 --- a/src/environment.h +++ b/src/environment.h @@ -54,6 +54,7 @@ class ClientMap; class GameScripting; class Player; class RemotePlayer; +class PlayerSAO; class Environment { @@ -315,7 +316,7 @@ public: // Save players void saveLoadedPlayers(); void savePlayer(RemotePlayer *player); - RemotePlayer *loadPlayer(const std::string &playername); + RemotePlayer *loadPlayer(const std::string &playername, PlayerSAO *sao); void addPlayer(RemotePlayer *player); void removePlayer(RemotePlayer *player); @@ -362,7 +363,7 @@ public: Find out what new objects have been added to inside a radius around a position */ - void getAddedActiveObjects(RemotePlayer *player, s16 radius, + void getAddedActiveObjects(PlayerSAO *playersao, s16 radius, s16 player_radius, std::set ¤t_objects, std::queue &added_objects); @@ -371,7 +372,7 @@ public: Find out what new objects have been removed from inside a radius around a position */ - void getRemovedActiveObjects(RemotePlayer *player, s16 radius, + void getRemovedActiveObjects(PlayerSAO *playersao, s16 radius, s16 player_radius, std::set ¤t_objects, std::queue &removed_objects); diff --git a/src/localplayer.cpp b/src/localplayer.cpp index bc242a59d..71efb2343 100644 --- a/src/localplayer.cpp +++ b/src/localplayer.cpp @@ -35,6 +35,7 @@ with this program; if not, write to the Free Software Foundation, Inc., LocalPlayer::LocalPlayer(Client *gamedef, const char *name): Player(name, gamedef->idef()), parent(0), + hp(PLAYER_MAX_HP), got_teleported(false), isAttached(false), touching_ground(false), @@ -62,6 +63,7 @@ LocalPlayer::LocalPlayer(Client *gamedef, const char *name): light_color(255,255,255,255), hurt_tilt_timer(0.0f), hurt_tilt_strength(0.0f), + m_position(0,0,0), m_sneak_node(32767,32767,32767), m_sneak_node_exists(false), m_need_to_get_new_sneak_node(true), @@ -69,6 +71,11 @@ LocalPlayer::LocalPlayer(Client *gamedef, const char *name): m_old_node_below(32767,32767,32767), m_old_node_below_type("air"), m_can_jump(false), + m_breath(PLAYER_MAX_BREATH), + m_yaw(0), + m_pitch(0), + camera_barely_in_ceiling(false), + m_collisionbox(-BS * 0.30, 0.0, -BS * 0.30, BS * 0.30, BS * 1.75, BS * 0.30), m_cao(NULL), m_gamedef(gamedef) { diff --git a/src/localplayer.h b/src/localplayer.h index eb727d7e3..749f8f8ce 100644 --- a/src/localplayer.h +++ b/src/localplayer.h @@ -40,6 +40,7 @@ public: ClientActiveObject *parent; + u16 hp; bool got_teleported; bool isAttached; bool touching_ground; @@ -99,10 +100,45 @@ public: u32 maxHudId() const { return hud.size(); } + u16 getBreath() const { return m_breath; } + void setBreath(u16 breath) { m_breath = breath; } + + v3s16 getLightPosition() const + { + return floatToInt(m_position + v3f(0,BS+BS/2,0), BS); + } + + void setYaw(f32 yaw) + { + m_yaw = yaw; + } + + f32 getYaw() const { return m_yaw; } + + void setPitch(f32 pitch) + { + m_pitch = pitch; + } + + f32 getPitch() const { return m_pitch; } + + void setPosition(const v3f &position) + { + m_position = position; + } + + v3f getPosition() const { return m_position; } + v3f getEyePosition() const { return m_position + getEyeOffset(); } + v3f getEyeOffset() const + { + float eye_height = camera_barely_in_ceiling ? 1.5f : 1.625f; + return v3f(0, BS * eye_height, 0); + } private: void accelerateHorizontal(const v3f &target_speed, const f32 max_increase); void accelerateVertical(const v3f &target_speed, const f32 max_increase); + v3f m_position; // This is used for determining the sneaking range v3s16 m_sneak_node; // Whether the player is allowed to sneak @@ -117,6 +153,11 @@ private: v3s16 m_old_node_below; std::string m_old_node_below_type; bool m_can_jump; + u16 m_breath; + f32 m_yaw; + f32 m_pitch; + bool camera_barely_in_ceiling; + aabb3f m_collisionbox; GenericCAO* m_cao; Client *m_gamedef; diff --git a/src/network/clientpackethandler.cpp b/src/network/clientpackethandler.cpp index 090741f9f..411982f69 100644 --- a/src/network/clientpackethandler.cpp +++ b/src/network/clientpackethandler.cpp @@ -634,7 +634,6 @@ void Client::handleCommand_AnnounceMedia(NetworkPacket* pkt) m_media_downloader->addFile(name, sha1_raw); } - std::vector remote_media; try { std::string str; diff --git a/src/network/serverpackethandler.cpp b/src/network/serverpackethandler.cpp index 554025747..5e70b4c6c 100644 --- a/src/network/serverpackethandler.cpp +++ b/src/network/serverpackethandler.cpp @@ -809,13 +809,6 @@ void Server::handleCommand_PlayerPos(NetworkPacket* pkt) return; } - // If player is dead we don't care of this packet - if (player->isDead()) { - verbosestream << "TOSERVER_PLAYERPOS: " << player->getName() - << " is dead. Ignoring packet"; - return; - } - PlayerSAO *playersao = player->getPlayerSAO(); if (playersao == NULL) { errorstream << "Server::ProcessData(): Canceling: " @@ -825,10 +818,17 @@ void Server::handleCommand_PlayerPos(NetworkPacket* pkt) return; } - player->setPosition(position); + // If player is dead we don't care of this packet + if (playersao->isDead()) { + verbosestream << "TOSERVER_PLAYERPOS: " << player->getName() + << " is dead. Ignoring packet"; + return; + } + + playersao->setBasePosition(position); player->setSpeed(speed); - player->setPitch(pitch); - player->setYaw(yaw); + playersao->setPitch(pitch, false); + playersao->setYaw(yaw, false); player->keyPressed = keyPressed; player->control.up = (keyPressed & 1); player->control.down = (keyPressed & 2); @@ -1100,7 +1100,7 @@ void Server::handleCommand_Damage(NetworkPacket* pkt) if (g_settings->getBool("enable_damage")) { actionstream << player->getName() << " damaged by " - << (int)damage << " hp at " << PP(player->getPosition() / BS) + << (int)damage << " hp at " << PP(playersao->getBasePosition() / BS) << std::endl; playersao->setHP(playersao->getHP() - damage); @@ -1124,16 +1124,6 @@ void Server::handleCommand_Breath(NetworkPacket* pkt) return; } - /* - * If player is dead, we don't need to update the breath - * He is dead ! - */ - if (player->isDead()) { - verbosestream << "TOSERVER_BREATH: " << player->getName() - << " is dead. Ignoring packet"; - return; - } - PlayerSAO *playersao = player->getPlayerSAO(); if (playersao == NULL) { @@ -1144,6 +1134,16 @@ void Server::handleCommand_Breath(NetworkPacket* pkt) return; } + /* + * If player is dead, we don't need to update the breath + * He is dead ! + */ + if (playersao->isDead()) { + verbosestream << "TOSERVER_BREATH: " << player->getName() + << " is dead. Ignoring packet"; + return; + } + playersao->setBreath(breath); SendPlayerBreath(pkt->getPeerId()); } @@ -1264,13 +1264,16 @@ void Server::handleCommand_Respawn(NetworkPacket* pkt) return; } - if (!player->isDead()) + PlayerSAO *playersao = player->getPlayerSAO(); + assert(playersao); + + if (!playersao->isDead()) return; RespawnPlayer(pkt->getPeerId()); actionstream << player->getName() << " respawns at " - << PP(player->getPosition()/BS) << std::endl; + << PP(playersao->getBasePosition() / BS) << std::endl; // ActiveObject is added to environment in AsyncRunStep after // the previous addition has been successfully removed @@ -1322,9 +1325,9 @@ void Server::handleCommand_Interact(NetworkPacket* pkt) return; } - if (player->isDead()) { + if (playersao->isDead()) { verbosestream << "TOSERVER_INTERACT: " << player->getName() - << " is dead. Ignoring packet"; + << " is dead. Ignoring packet"; return; } @@ -1455,7 +1458,7 @@ void Server::handleCommand_Interact(NetworkPacket* pkt) ToolCapabilities toolcap = punchitem.getToolCapabilities(m_itemdef); v3f dir = (pointed_object->getBasePosition() - - (player->getPosition() + player->getEyeOffset()) + (playersao->getBasePosition() + playersao->getEyeOffset()) ).normalize(); float time_from_last_punch = playersao->resetTimeFromLastPunch(); diff --git a/src/player.cpp b/src/player.cpp index fa82a79f4..9c321d571 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -30,18 +30,11 @@ with this program; if not, write to the Free Software Foundation, Inc., Player::Player(const char *name, IItemDefManager *idef): - camera_barely_in_ceiling(false), inventory(idef), - hp(PLAYER_MAX_HP), peer_id(PEER_ID_INEXISTENT), keyPressed(0), // protected - m_breath(PLAYER_MAX_BREATH), - m_pitch(0), - m_yaw(0), - m_speed(0,0,0), - m_position(0,0,0), - m_collisionbox(-BS*0.30,0.0,-BS*0.30,BS*0.30,BS*1.75,BS*0.30) + m_speed(0,0,0) { strlcpy(m_name, name, PLAYERNAME_SIZE); @@ -90,11 +83,6 @@ Player::~Player() clearHud(); } -v3s16 Player::getLightPosition() const -{ - return floatToInt(m_position + v3f(0,BS+BS/2,0), BS); -} - u32 Player::addHud(HudElement *toadd) { MutexAutoLock lock(m_mutex); diff --git a/src/player.h b/src/player.h index 6ac5dfe65..5f9bb7ec9 100644 --- a/src/player.h +++ b/src/player.h @@ -129,49 +129,7 @@ public: m_speed = speed; } - v3f getPosition() - { - return m_position; - } - - v3s16 getLightPosition() const; - - v3f getEyeOffset() - { - float eye_height = camera_barely_in_ceiling ? 1.5f : 1.625f; - return v3f(0, BS * eye_height, 0); - } - - v3f getEyePosition() - { - return m_position + getEyeOffset(); - } - - virtual void setPosition(const v3f &position) - { - m_position = position; - } - - virtual void setPitch(f32 pitch) - { - m_pitch = pitch; - } - - virtual void setYaw(f32 yaw) - { - m_yaw = yaw; - } - - f32 getPitch() const { return m_pitch; } - f32 getYaw() const { return m_yaw; } - u16 getBreath() const { return m_breath; } - - virtual void setBreath(u16 breath) { m_breath = breath; } - - f32 getRadPitch() const { return m_pitch * core::DEGTORAD; } - f32 getRadYaw() const { return m_yaw * core::DEGTORAD; } const char *getName() const { return m_name; } - aabb3f getCollisionbox() const { return m_collisionbox; } u32 getFreeHudID() { @@ -183,7 +141,6 @@ public: return size; } - bool camera_barely_in_ceiling; v3f eye_offset_first; v3f eye_offset_third; @@ -205,8 +162,6 @@ public: v2s32 local_animations[4]; float local_animation_speed; - u16 hp; - u16 peer_id; std::string inventory_formspec; @@ -225,12 +180,7 @@ public: s32 hud_hotbar_itemcount; protected: char m_name[PLAYERNAME_SIZE]; - u16 m_breath; - f32 m_pitch; - f32 m_yaw; v3f m_speed; - v3f m_position; - aabb3f m_collisionbox; std::vector hud; private: diff --git a/src/remoteplayer.cpp b/src/remoteplayer.cpp index f64d1d690..605346928 100644 --- a/src/remoteplayer.cpp +++ b/src/remoteplayer.cpp @@ -96,7 +96,7 @@ void RemotePlayer::save(std::string savedir, IGameDef *gamedef) infostream << "Failed to open " << path << std::endl; return; } - testplayer.deSerialize(is, path); + testplayer.deSerialize(is, path, NULL); is.close(); if (strcmp(testplayer.getName(), m_name) == 0) { // Open file and serialize @@ -115,37 +115,46 @@ void RemotePlayer::save(std::string savedir, IGameDef *gamedef) return; } -void RemotePlayer::deSerialize(std::istream &is, const std::string &playername) +void RemotePlayer::deSerialize(std::istream &is, const std::string &playername, + PlayerSAO *sao) { Settings args; if (!args.parseConfigLines(is, "PlayerArgsEnd")) { - throw SerializationError("PlayerArgsEnd of player " + - playername + " not found!"); + throw SerializationError("PlayerArgsEnd of player " + playername + " not found!"); } m_dirty = true; //args.getS32("version"); // Version field value not used std::string name = args.get("name"); strlcpy(m_name, name.c_str(), PLAYERNAME_SIZE); - setPitch(args.getFloat("pitch")); - setYaw(args.getFloat("yaw")); - setPosition(args.getV3F("position")); - try { - hp = args.getS32("hp"); - } catch(SettingNotFoundException &e) { - hp = PLAYER_MAX_HP; - } - try { - m_breath = args.getS32("breath"); - } catch(SettingNotFoundException &e) { - m_breath = PLAYER_MAX_BREATH; + if (sao) { + try { + sao->setHP(args.getS32("hp"), true); + } catch(SettingNotFoundException &e) { + sao->setHP(PLAYER_MAX_HP, true); + } + + try { + sao->setBasePosition(args.getV3F("position")); + } catch (SettingNotFoundException &e) {} + + try { + sao->setPitch(args.getFloat("pitch"), false); + } catch (SettingNotFoundException &e) {} + try { + sao->setYaw(args.getFloat("yaw"), false); + } catch (SettingNotFoundException &e) {} + + try { + sao->setBreath(args.getS32("breath")); + } catch (SettingNotFoundException &e) {} } inventory.deSerialize(is); - if(inventory.getList("craftpreview") == NULL) { + if (inventory.getList("craftpreview") == NULL) { // Convert players without craftpreview inventory.addList("craftpreview", 1); @@ -167,11 +176,14 @@ void RemotePlayer::serialize(std::ostream &os) args.setS32("version", 1); args.set("name", m_name); //args.set("password", m_password); - args.setFloat("pitch", m_pitch); - args.setFloat("yaw", m_yaw); - args.setV3F("position", m_position); - args.setS32("hp", hp); - args.setS32("breath", m_breath); + + if (m_sao) { + args.setS32("hp", m_sao->getHP()); + args.setV3F("position", m_sao->getBasePosition()); + args.setFloat("pitch", m_sao->getPitch()); + args.setFloat("yaw", m_sao->getYaw()); + args.setS32("breath", m_sao->getBreath()); + } args.writeLines(os); @@ -180,16 +192,6 @@ void RemotePlayer::serialize(std::ostream &os) inventory.serialize(os); } -void RemotePlayer::setPosition(const v3f &position) -{ - if (position != m_position) - m_dirty = true; - - Player::setPosition(position); - if(m_sao) - m_sao->setBasePosition(position); -} - const RemotePlayerChatResult RemotePlayer::canSendChatMessage() { // Rate limit messages diff --git a/src/remoteplayer.h b/src/remoteplayer.h index 1b1a90de3..61b5a23de 100644 --- a/src/remoteplayer.h +++ b/src/remoteplayer.h @@ -40,11 +40,10 @@ public: virtual ~RemotePlayer() {} void save(std::string savedir, IGameDef *gamedef); - void deSerialize(std::istream &is, const std::string &playername); + void deSerialize(std::istream &is, const std::string &playername, PlayerSAO *sao); PlayerSAO *getPlayerSAO() { return m_sao; } void setPlayerSAO(PlayerSAO *sao) { m_sao = sao; } - void setPosition(const v3f &position); const RemotePlayerChatResult canSendChatMessage(); @@ -67,9 +66,6 @@ public: *ratio = m_day_night_ratio; } - // Use a function, if isDead can be defined by other conditions - bool isDead() const { return hp == 0; } - void setHotbarImage(const std::string &name) { hud_hotbar_image = name; @@ -90,12 +86,6 @@ public: return hud_hotbar_selected_image; } - // Deprecated - f32 getRadPitchDep() const { return -1.0 * m_pitch * core::DEGTORAD; } - - // Deprecated - f32 getRadYawDep() const { return (m_yaw + 90.) * core::DEGTORAD; } - void setSky(const video::SColor &bgcolor, const std::string &type, const std::vector ¶ms) { @@ -121,27 +111,6 @@ public: inventory.setModified(x); } - virtual void setBreath(u16 breath) - { - if (breath != m_breath) - m_dirty = true; - Player::setBreath(breath); - } - - virtual void setPitch(f32 pitch) - { - if (pitch != m_pitch) - m_dirty = true; - Player::setPitch(pitch); - } - - virtual void setYaw(f32 yaw) - { - if (yaw != m_yaw) - m_dirty = true; - Player::setYaw(yaw); - } - void setLocalAnimations(v2s32 frames[4], float frame_speed) { for (int i = 0; i < 4; i++) @@ -156,6 +125,8 @@ public: *frame_speed = local_animation_speed; } + void setDirty(bool dirty) { m_dirty = true; } + u16 protocol_version; private: /* diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp index 23994181c..cf124f17c 100644 --- a/src/script/lua_api/l_object.cpp +++ b/src/script/lua_api/l_object.cpp @@ -1013,11 +1013,11 @@ int ObjectRef::l_get_look_dir(lua_State *L) { NO_MAP_LOCK_REQUIRED; ObjectRef *ref = checkobject(L, 1); - RemotePlayer *player = getplayer(ref); - if (player == NULL) return 0; + PlayerSAO* co = getplayersao(ref); + if (co == NULL) return 0; // Do it - float pitch = player->getRadPitchDep(); - float yaw = player->getRadYawDep(); + float pitch = co->getRadPitchDep(); + float yaw = co->getRadYawDep(); v3f v(cos(pitch)*cos(yaw), sin(pitch), cos(pitch)*sin(yaw)); push_v3f(L, v); return 1; @@ -1033,10 +1033,10 @@ int ObjectRef::l_get_look_pitch(lua_State *L) "Deprecated call to get_look_pitch, use get_look_vertical instead"); ObjectRef *ref = checkobject(L, 1); - RemotePlayer *player = getplayer(ref); - if (player == NULL) return 0; + PlayerSAO* co = getplayersao(ref); + if (co == NULL) return 0; // Do it - lua_pushnumber(L, player->getRadPitchDep()); + lua_pushnumber(L, co->getRadPitchDep()); return 1; } @@ -1050,10 +1050,10 @@ int ObjectRef::l_get_look_yaw(lua_State *L) "Deprecated call to get_look_yaw, use get_look_horizontal instead"); ObjectRef *ref = checkobject(L, 1); - RemotePlayer *player = getplayer(ref); - if (player == NULL) return 0; + PlayerSAO* co = getplayersao(ref); + if (co == NULL) return 0; // Do it - lua_pushnumber(L, player->getRadYawDep()); + lua_pushnumber(L, co->getRadYawDep()); return 1; } @@ -1062,10 +1062,10 @@ int ObjectRef::l_get_look_vertical(lua_State *L) { NO_MAP_LOCK_REQUIRED; ObjectRef *ref = checkobject(L, 1); - RemotePlayer *player = getplayer(ref); - if (player == NULL) return 0; + PlayerSAO* co = getplayersao(ref); + if (co == NULL) return 0; // Do it - lua_pushnumber(L, player->getRadPitch()); + lua_pushnumber(L, co->getRadPitch()); return 1; } @@ -1074,10 +1074,10 @@ int ObjectRef::l_get_look_horizontal(lua_State *L) { NO_MAP_LOCK_REQUIRED; ObjectRef *ref = checkobject(L, 1); - RemotePlayer *player = getplayer(ref); - if (player == NULL) return 0; + PlayerSAO* co = getplayersao(ref); + if (co == NULL) return 0; // Do it - lua_pushnumber(L, player->getRadYaw()); + lua_pushnumber(L, co->getRadYaw()); return 1; } diff --git a/src/server.cpp b/src/server.cpp index e67f37d56..cd526ad77 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -701,11 +701,15 @@ void Server::AsyncRunStep(bool initial_step) continue; } + PlayerSAO *playersao = player->getPlayerSAO(); + if (playersao == NULL) + continue; + std::queue removed_objects; std::queue added_objects; - m_env->getRemovedActiveObjects(player, radius, player_radius, + m_env->getRemovedActiveObjects(playersao, radius, player_radius, client->m_known_objects, removed_objects); - m_env->getAddedActiveObjects(player, radius, player_radius, + m_env->getAddedActiveObjects(playersao, radius, player_radius, client->m_known_objects, added_objects); // Ignore if nothing happened @@ -1108,7 +1112,7 @@ PlayerSAO* Server::StageTwoClientInit(u16 peer_id) SendPlayerBreath(peer_id); // Show death screen if necessary - if (player->isDead()) + if (playersao->isDead()) SendDeathscreen(peer_id, false, v3f(0,0,0)); // Note things in chat if not in simple singleplayer mode @@ -1860,18 +1864,18 @@ void Server::SendMovePlayer(u16 peer_id) DSTACK(FUNCTION_NAME); RemotePlayer *player = m_env->getPlayer(peer_id); assert(player); + PlayerSAO *sao = player->getPlayerSAO(); + assert(sao); NetworkPacket pkt(TOCLIENT_MOVE_PLAYER, sizeof(v3f) + sizeof(f32) * 2, peer_id); - pkt << player->getPosition() << player->getPitch() << player->getYaw(); + pkt << sao->getBasePosition() << sao->getPitch() << sao->getYaw(); { - v3f pos = player->getPosition(); - f32 pitch = player->getPitch(); - f32 yaw = player->getYaw(); + v3f pos = sao->getBasePosition(); verbosestream << "Server: Sending TOCLIENT_MOVE_PLAYER" << " pos=(" << pos.X << "," << pos.Y << "," << pos.Z << ")" - << " pitch=" << pitch - << " yaw=" << yaw + << " pitch=" << sao->getPitch() + << " yaw=" << sao->getYaw() << std::endl; } @@ -1984,8 +1988,12 @@ s32 Server::playSound(const SimpleSoundSpec &spec, if (!player) continue; + PlayerSAO *sao = player->getPlayerSAO(); + if (!sao) + continue; + if (pos_exists) { - if(player->getPosition().getDistanceFrom(pos) > + if(sao->getBasePosition().getDistanceFrom(pos) > params.max_hear_distance) continue; } @@ -2044,14 +2052,17 @@ void Server::sendRemoveNode(v3s16 p, u16 ignore_id, pkt << p; std::vector clients = m_clients.getClientIDs(); - for(std::vector::iterator i = clients.begin(); - i != clients.end(); ++i) { + for (std::vector::iterator i = clients.begin(); i != clients.end(); ++i) { if (far_players) { // Get player if (RemotePlayer *player = m_env->getPlayer(*i)) { + PlayerSAO *sao = player->getPlayerSAO(); + if (!sao) + continue; + // If player is far away, only set modified blocks not sent - v3f player_pos = player->getPosition(); - if(player_pos.getDistanceFrom(p_f) > maxd) { + v3f player_pos = sao->getBasePosition(); + if (player_pos.getDistanceFrom(p_f) > maxd) { far_players->push_back(*i); continue; } @@ -2071,14 +2082,16 @@ void Server::sendAddNode(v3s16 p, MapNode n, u16 ignore_id, v3f p_f = intToFloat(p, BS); std::vector clients = m_clients.getClientIDs(); - for(std::vector::iterator i = clients.begin(); - i != clients.end(); ++i) { - - if(far_players) { + for(std::vector::iterator i = clients.begin(); i != clients.end(); ++i) { + if (far_players) { // Get player if (RemotePlayer *player = m_env->getPlayer(*i)) { + PlayerSAO *sao = player->getPlayerSAO(); + if (!sao) + continue; + // If player is far away, only set modified blocks not sent - v3f player_pos = player->getPosition(); + v3f player_pos = sao->getBasePosition(); if(player_pos.getDistanceFrom(p_f) > maxd) { far_players->push_back(*i); continue; @@ -3426,10 +3439,9 @@ PlayerSAO* Server::emergePlayer(const char *name, u16 peer_id, u16 proto_version return NULL; } - // Load player if it isn't already loaded - if (!player) { - player = m_env->loadPlayer(name); - } + // Create a new player active object + PlayerSAO *playersao = new PlayerSAO(m_env, peer_id, isSingleplayer()); + player = m_env->loadPlayer(name, playersao); // Create player if it doesn't exist if (!player) { @@ -3438,8 +3450,7 @@ PlayerSAO* Server::emergePlayer(const char *name, u16 peer_id, u16 proto_version // Set player position infostream<<"Server: Finding spawn place for player \"" <setPosition(pos); + playersao->setBasePosition(findSpawnPos()); // Make sure the player is saved player->setModified(true); @@ -3450,18 +3461,14 @@ PlayerSAO* Server::emergePlayer(const char *name, u16 peer_id, u16 proto_version // If the player exists, ensure that they respawn inside legal bounds // This fixes an assert crash when the player can't be added // to the environment - if (objectpos_over_limit(player->getPosition())) { + if (objectpos_over_limit(playersao->getBasePosition())) { actionstream << "Respawn position for player \"" << name << "\" outside limits, resetting" << std::endl; - v3f pos = findSpawnPos(); - player->setPosition(pos); + playersao->setBasePosition(findSpawnPos()); } } - // Create a new player active object - PlayerSAO *playersao = new PlayerSAO(m_env, player, peer_id, - getPlayerEffectivePrivs(player->getName()), - isSingleplayer()); + playersao->initialize(player, getPlayerEffectivePrivs(player->getName())); player->protocol_version = proto_version; diff --git a/src/serverobject.h b/src/serverobject.h index 63650e3be..9884eb0a1 100644 --- a/src/serverobject.h +++ b/src/serverobject.h @@ -85,7 +85,7 @@ public: Some more dynamic interface */ - virtual void setPos(v3f pos) + virtual void setPos(const v3f &pos) { setBasePosition(pos); } // continuous: if true, object does not stop immediately at pos virtual void moveTo(v3f pos, bool continuous) diff --git a/src/unittest/test_player.cpp b/src/unittest/test_player.cpp index 5de9eaaf2..fba422475 100644 --- a/src/unittest/test_player.cpp +++ b/src/unittest/test_player.cpp @@ -46,11 +46,14 @@ void TestPlayer::runTests(IGameDef *gamedef) void TestPlayer::testSave(IGameDef *gamedef) { RemotePlayer rplayer("testplayer_save", gamedef->idef()); - rplayer.setBreath(10); - rplayer.hp = 8; - rplayer.setYaw(0.1f); - rplayer.setPitch(0.6f); - rplayer.setPosition(v3f(450.2f, -15.7f, 68.1f)); + PlayerSAO sao(NULL, 1, false); + sao.initialize(&rplayer, std::set()); + rplayer.setPlayerSAO(&sao); + sao.setBreath(10); + sao.setHP(8, true); + sao.setYaw(0.1f, false); + sao.setPitch(0.6f, false); + sao.setBasePosition(v3f(450.2f, -15.7f, 68.1f)); rplayer.save(".", gamedef); UASSERT(fs::PathExists("testplayer_save")); } @@ -58,24 +61,28 @@ void TestPlayer::testSave(IGameDef *gamedef) void TestPlayer::testLoad(IGameDef *gamedef) { RemotePlayer rplayer("testplayer_load", gamedef->idef()); - rplayer.setBreath(10); - rplayer.hp = 8; - rplayer.setYaw(0.1f); - rplayer.setPitch(0.6f); - rplayer.setPosition(v3f(450.2f, -15.7f, 68.1f)); + PlayerSAO sao(NULL, 1, false); + sao.initialize(&rplayer, std::set()); + rplayer.setPlayerSAO(&sao); + sao.setBreath(10); + sao.setHP(8, true); + sao.setYaw(0.1f, false); + sao.setPitch(0.6f, false); + sao.setBasePosition(v3f(450.2f, -15.7f, 68.1f)); rplayer.save(".", gamedef); UASSERT(fs::PathExists("testplayer_load")); RemotePlayer rplayer_load("testplayer_load", gamedef->idef()); + PlayerSAO sao_load(NULL, 2, false); std::ifstream is("testplayer_load", std::ios_base::binary); UASSERT(is.good()); - rplayer_load.deSerialize(is, "testplayer_load"); + rplayer_load.deSerialize(is, "testplayer_load", &sao_load); is.close(); UASSERT(strcmp(rplayer_load.getName(), "testplayer_load") == 0); - UASSERT(rplayer.getBreath() == 10); - UASSERT(rplayer.hp == 8); - UASSERT(rplayer.getYaw() == 0.1f); - UASSERT(rplayer.getPitch() == 0.6f); - UASSERT(rplayer.getPosition() == v3f(450.2f, -15.7f, 68.1f)); + UASSERT(sao_load.getBreath() == 10); + UASSERT(sao_load.getHP() == 8); + UASSERT(sao_load.getYaw() == 0.1f); + UASSERT(sao_load.getPitch() == 0.6f); + UASSERT(sao_load.getBasePosition() == v3f(450.2f, -15.7f, 68.1f)); } -- cgit v1.2.3 From 595932a8602292f28333ce14e20cee4b6d8820c1 Mon Sep 17 00:00:00 2001 From: Loic Blot Date: Sun, 30 Oct 2016 16:12:09 +0100 Subject: Fix overloading problems mentioned by clang --- src/content_sao.cpp | 28 ++++++++++++++-------------- src/content_sao.h | 13 +++++++++---- src/network/serverpackethandler.cpp | 4 ++-- src/remoteplayer.cpp | 8 ++++---- src/script/lua_api/l_object.cpp | 8 ++++---- src/unittest/test_player.cpp | 12 ++++++------ 6 files changed, 39 insertions(+), 34 deletions(-) (limited to 'src/network') diff --git a/src/content_sao.cpp b/src/content_sao.cpp index 23a064085..5fb8f936e 100644 --- a/src/content_sao.cpp +++ b/src/content_sao.cpp @@ -507,7 +507,7 @@ void LuaEntitySAO::rightClick(ServerActiveObject *clicker) m_env->getScriptIface()->luaentity_Rightclick(m_id, clicker); } -void LuaEntitySAO::setPos(v3f pos) +void LuaEntitySAO::setPos(const v3f &pos) { if(isAttached()) return; @@ -1078,27 +1078,32 @@ void PlayerSAO::moveTo(v3f pos, bool continuous) ((Server*)m_env->getGameDef())->SendMovePlayer(m_peer_id); } -void PlayerSAO::setYaw(const float yaw, bool send_data) +void PlayerSAO::setYaw(const float yaw) { if (m_player && yaw != m_yaw) m_player->setDirty(true); UnitSAO::setYaw(yaw); +} - // Datas should not be sent at player initialization - if (send_data) - ((Server*)m_env->getGameDef())->SendMovePlayer(m_peer_id); +void PlayerSAO::setYawAndSend(const float yaw) +{ + setYaw(yaw); + ((Server*)m_env->getGameDef())->SendMovePlayer(m_peer_id); } -void PlayerSAO::setPitch(const float pitch, bool send_data) +void PlayerSAO::setPitch(const float pitch) { if (m_player && pitch != m_pitch) m_player->setDirty(true); m_pitch = pitch; +} - if (send_data) - ((Server*)m_env->getGameDef())->SendMovePlayer(m_peer_id); +void PlayerSAO::setPitchAndSend(const float pitch) +{ + setPitch(pitch); + ((Server*)m_env->getGameDef())->SendMovePlayer(m_peer_id); } int PlayerSAO::punch(v3f dir, @@ -1173,13 +1178,8 @@ s16 PlayerSAO::readDamage() return damage; } -void PlayerSAO::setHP(s16 hp, bool direct) +void PlayerSAO::setHP(s16 hp) { - if (direct) { - m_hp = hp; - return; - } - s16 oldhp = m_hp; s16 hp_change = m_env->getScriptIface()->on_player_hpchange(this, hp - oldhp); diff --git a/src/content_sao.h b/src/content_sao.h index 4ea6277ff..5d837a466 100644 --- a/src/content_sao.h +++ b/src/content_sao.h @@ -73,7 +73,7 @@ public: ServerActiveObject *puncher=NULL, float time_from_last_punch=1000000); void rightClick(ServerActiveObject *clicker); - void setPos(v3f pos); + void setPos(const v3f &pos); void moveTo(v3f pos, bool continuous); float getMinimumSavedMovement(); std::string getDescription(); @@ -204,8 +204,12 @@ public: void setBasePosition(const v3f &position); void setPos(const v3f &pos); void moveTo(v3f pos, bool continuous); - void setYaw(const float yaw, bool send_data = true); - void setPitch(const float pitch, bool send_data = true); + void setYaw(const float yaw); + // Data should not be sent at player initialization + void setYawAndSend(const float yaw); + void setPitch(const float pitch); + // Data should not be sent at player initialization + void setPitchAndSend(const float pitch); f32 getPitch() const { return m_pitch; } f32 getRadPitch() const { return m_pitch * core::DEGTORAD; } // Deprecated @@ -220,7 +224,8 @@ public: ServerActiveObject *puncher, float time_from_last_punch); void rightClick(ServerActiveObject *clicker); - void setHP(s16 hp, bool direct = false); + void setHP(s16 hp); + void setHPRaw(s16 hp) { m_hp = hp; } s16 readDamage(); u16 getBreath() const { return m_breath; } void setBreath(const u16 breath); diff --git a/src/network/serverpackethandler.cpp b/src/network/serverpackethandler.cpp index 5e70b4c6c..80eec140d 100644 --- a/src/network/serverpackethandler.cpp +++ b/src/network/serverpackethandler.cpp @@ -827,8 +827,8 @@ void Server::handleCommand_PlayerPos(NetworkPacket* pkt) playersao->setBasePosition(position); player->setSpeed(speed); - playersao->setPitch(pitch, false); - playersao->setYaw(yaw, false); + playersao->setPitch(pitch); + playersao->setYaw(yaw); player->keyPressed = keyPressed; player->control.up = (keyPressed & 1); player->control.down = (keyPressed & 2); diff --git a/src/remoteplayer.cpp b/src/remoteplayer.cpp index 605346928..f4a79dd08 100644 --- a/src/remoteplayer.cpp +++ b/src/remoteplayer.cpp @@ -131,9 +131,9 @@ void RemotePlayer::deSerialize(std::istream &is, const std::string &playername, if (sao) { try { - sao->setHP(args.getS32("hp"), true); + sao->setHPRaw(args.getS32("hp")); } catch(SettingNotFoundException &e) { - sao->setHP(PLAYER_MAX_HP, true); + sao->setHPRaw(PLAYER_MAX_HP); } try { @@ -141,10 +141,10 @@ void RemotePlayer::deSerialize(std::istream &is, const std::string &playername, } catch (SettingNotFoundException &e) {} try { - sao->setPitch(args.getFloat("pitch"), false); + sao->setPitch(args.getFloat("pitch")); } catch (SettingNotFoundException &e) {} try { - sao->setYaw(args.getFloat("yaw"), false); + sao->setYaw(args.getFloat("yaw")); } catch (SettingNotFoundException &e) {} try { diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp index cf124f17c..42395717f 100644 --- a/src/script/lua_api/l_object.cpp +++ b/src/script/lua_api/l_object.cpp @@ -1090,7 +1090,7 @@ int ObjectRef::l_set_look_vertical(lua_State *L) if (co == NULL) return 0; float pitch = luaL_checknumber(L, 2) * core::RADTODEG; // Do it - co->setPitch(pitch); + co->setPitchAndSend(pitch); return 1; } @@ -1103,7 +1103,7 @@ int ObjectRef::l_set_look_horizontal(lua_State *L) if (co == NULL) return 0; float yaw = luaL_checknumber(L, 2) * core::RADTODEG; // Do it - co->setYaw(yaw); + co->setYawAndSend(yaw); return 1; } @@ -1121,7 +1121,7 @@ int ObjectRef::l_set_look_pitch(lua_State *L) if (co == NULL) return 0; float pitch = luaL_checknumber(L, 2) * core::RADTODEG; // Do it - co->setPitch(pitch); + co->setPitchAndSend(pitch); return 1; } @@ -1139,7 +1139,7 @@ int ObjectRef::l_set_look_yaw(lua_State *L) if (co == NULL) return 0; float yaw = luaL_checknumber(L, 2) * core::RADTODEG; // Do it - co->setYaw(yaw); + co->setYawAndSend(yaw); return 1; } diff --git a/src/unittest/test_player.cpp b/src/unittest/test_player.cpp index fba422475..85fbc8b2d 100644 --- a/src/unittest/test_player.cpp +++ b/src/unittest/test_player.cpp @@ -50,9 +50,9 @@ void TestPlayer::testSave(IGameDef *gamedef) sao.initialize(&rplayer, std::set()); rplayer.setPlayerSAO(&sao); sao.setBreath(10); - sao.setHP(8, true); - sao.setYaw(0.1f, false); - sao.setPitch(0.6f, false); + sao.setHPRaw(8); + sao.setYaw(0.1f); + sao.setPitch(0.6f); sao.setBasePosition(v3f(450.2f, -15.7f, 68.1f)); rplayer.save(".", gamedef); UASSERT(fs::PathExists("testplayer_save")); @@ -65,9 +65,9 @@ void TestPlayer::testLoad(IGameDef *gamedef) sao.initialize(&rplayer, std::set()); rplayer.setPlayerSAO(&sao); sao.setBreath(10); - sao.setHP(8, true); - sao.setYaw(0.1f, false); - sao.setPitch(0.6f, false); + sao.setHPRaw(8); + sao.setYaw(0.1f); + sao.setPitch(0.6f); sao.setBasePosition(v3f(450.2f, -15.7f, 68.1f)); rplayer.save(".", gamedef); UASSERT(fs::PathExists("testplayer_load")); -- cgit v1.2.3 From e4031156f13d062b03960e7ef1c9221f749f884b Mon Sep 17 00:00:00 2001 From: raymoo Date: Fri, 11 Nov 2016 23:22:39 -0800 Subject: Add control information to player interacts (#4685) --- src/client.cpp | 52 +++++++++++++++++----------- src/network/networkpacket.h | 1 + src/network/serverpackethandler.cpp | 68 +++++++++++++++++++++---------------- src/server.h | 4 +++ 4 files changed, 76 insertions(+), 49 deletions(-) (limited to 'src/network') diff --git a/src/client.cpp b/src/client.cpp index 62bd274aa..3726f5bc4 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -929,6 +929,30 @@ void Client::Send(NetworkPacket* pkt) serverCommandFactoryTable[pkt->getCommand()].reliable); } +// Will fill up 12 + 12 + 4 + 4 + 4 bytes +void writePlayerPos(LocalPlayer *myplayer, NetworkPacket *pkt) +{ + v3f pf = myplayer->getPosition() * 100; + v3f sf = myplayer->getSpeed() * 100; + s32 pitch = myplayer->getPitch() * 100; + s32 yaw = myplayer->getYaw() * 100; + u32 keyPressed = myplayer->keyPressed; + + v3s32 position(pf.X, pf.Y, pf.Z); + v3s32 speed(sf.X, sf.Y, sf.Z); + + /* + Format: + [0] v3s32 position*100 + [12] v3s32 speed*100 + [12+12] s32 pitch*100 + [12+12+4] s32 yaw*100 + [12+12+4+4] u32 keyPressed + */ + + *pkt << position << speed << pitch << yaw << keyPressed; +} + void Client::interact(u8 action, const PointedThing& pointed) { if(m_state != LC_Ready) { @@ -938,12 +962,17 @@ void Client::interact(u8 action, const PointedThing& pointed) return; } + LocalPlayer *myplayer = m_env.getLocalPlayer(); + if (myplayer == NULL) + return; + /* [0] u16 command [2] u8 action [3] u16 item - [5] u32 length of the next item + [5] u32 length of the next item (plen) [9] serialized PointedThing + [9 + plen] player position information actions: 0: start digging (from undersurface) or use 1: stop digging (all parameters ignored) @@ -963,6 +992,8 @@ void Client::interact(u8 action, const PointedThing& pointed) pkt.putLongString(tmp_os.str()); + writePlayerPos(myplayer, &pkt); + Send(&pkt); } @@ -1291,26 +1322,9 @@ void Client::sendPlayerPos() assert(myplayer->peer_id == our_peer_id); - v3f pf = myplayer->getPosition(); - v3f sf = myplayer->getSpeed(); - s32 pitch = myplayer->getPitch() * 100; - s32 yaw = myplayer->getYaw() * 100; - u32 keyPressed = myplayer->keyPressed; - - v3s32 position(pf.X*100, pf.Y*100, pf.Z*100); - v3s32 speed(sf.X*100, sf.Y*100, sf.Z*100); - /* - Format: - [0] v3s32 position*100 - [12] v3s32 speed*100 - [12+12] s32 pitch*100 - [12+12+4] s32 yaw*100 - [12+12+4+4] u32 keyPressed - */ - NetworkPacket pkt(TOSERVER_PLAYERPOS, 12 + 12 + 4 + 4 + 4); - pkt << position << speed << pitch << yaw << keyPressed; + writePlayerPos(myplayer, &pkt); Send(&pkt); } diff --git a/src/network/networkpacket.h b/src/network/networkpacket.h index 72f8cabe2..524470999 100644 --- a/src/network/networkpacket.h +++ b/src/network/networkpacket.h @@ -40,6 +40,7 @@ public: u32 getSize() { return m_datasize; } u16 getPeerId() { return m_peer_id; } u16 getCommand() { return m_command; } + const u32 getRemainingBytes() const { return m_datasize - m_read_offset; } // Returns a c-string without copying. // A better name for this would be getRawString() diff --git a/src/network/serverpackethandler.cpp b/src/network/serverpackethandler.cpp index 80eec140d..d56424b75 100644 --- a/src/network/serverpackethandler.cpp +++ b/src/network/serverpackethandler.cpp @@ -774,9 +774,10 @@ void Server::handleCommand_GotBlocks(NetworkPacket* pkt) } } -void Server::handleCommand_PlayerPos(NetworkPacket* pkt) +void Server::process_PlayerPos(RemotePlayer *player, PlayerSAO *playersao, + NetworkPacket *pkt) { - if (pkt->getSize() < 12 + 12 + 4 + 4) + if (pkt->getRemainingBytes() < 12 + 12 + 4 + 4) return; v3s32 ps, ss; @@ -791,7 +792,7 @@ void Server::handleCommand_PlayerPos(NetworkPacket* pkt) f32 yaw = (f32)f32yaw / 100.0; u32 keyPressed = 0; - if (pkt->getSize() >= 12 + 12 + 4 + 4 + 4) + if (pkt->getRemainingBytes() >= 4) *pkt >> keyPressed; v3f position((f32)ps.X / 100.0, (f32)ps.Y / 100.0, (f32)ps.Z / 100.0); @@ -800,6 +801,30 @@ void Server::handleCommand_PlayerPos(NetworkPacket* pkt) pitch = modulo360f(pitch); yaw = modulo360f(yaw); + playersao->setBasePosition(position); + player->setSpeed(speed); + playersao->setPitch(pitch); + playersao->setYaw(yaw); + player->keyPressed = keyPressed; + player->control.up = (keyPressed & 1); + player->control.down = (keyPressed & 2); + player->control.left = (keyPressed & 4); + player->control.right = (keyPressed & 8); + player->control.jump = (keyPressed & 16); + player->control.aux1 = (keyPressed & 32); + player->control.sneak = (keyPressed & 64); + player->control.LMB = (keyPressed & 128); + player->control.RMB = (keyPressed & 256); + + if (playersao->checkMovementCheat()) { + // Call callbacks + m_script->on_cheat(playersao, "moved_too_fast"); + SendMovePlayer(pkt->getPeerId()); + } +} + +void Server::handleCommand_PlayerPos(NetworkPacket* pkt) +{ RemotePlayer *player = m_env->getPlayer(pkt->getPeerId()); if (player == NULL) { errorstream << "Server::ProcessData(): Canceling: " @@ -825,26 +850,7 @@ void Server::handleCommand_PlayerPos(NetworkPacket* pkt) return; } - playersao->setBasePosition(position); - player->setSpeed(speed); - playersao->setPitch(pitch); - playersao->setYaw(yaw); - player->keyPressed = keyPressed; - player->control.up = (keyPressed & 1); - player->control.down = (keyPressed & 2); - player->control.left = (keyPressed & 4); - player->control.right = (keyPressed & 8); - player->control.jump = (keyPressed & 16); - player->control.aux1 = (keyPressed & 32); - player->control.sneak = (keyPressed & 64); - player->control.LMB = (keyPressed & 128); - player->control.RMB = (keyPressed & 256); - - if (playersao->checkMovementCheat()) { - // Call callbacks - m_script->on_cheat(playersao, "moved_too_fast"); - SendMovePlayer(pkt->getPeerId()); - } + process_PlayerPos(player, playersao, pkt); } void Server::handleCommand_DeletedBlocks(NetworkPacket* pkt) @@ -1281,15 +1287,13 @@ void Server::handleCommand_Respawn(NetworkPacket* pkt) void Server::handleCommand_Interact(NetworkPacket* pkt) { - std::string datastring(pkt->getString(0), pkt->getSize()); - std::istringstream is(datastring, std::ios_base::binary); - /* [0] u16 command [2] u8 action [3] u16 item - [5] u32 length of the next item + [5] u32 length of the next item (plen) [9] serialized PointedThing + [9 + plen] player position information actions: 0: start digging (from undersurface) or use 1: stop digging (all parameters ignored) @@ -1297,9 +1301,11 @@ void Server::handleCommand_Interact(NetworkPacket* pkt) 3: place block or item (to abovesurface) 4: use item */ - u8 action = readU8(is); - u16 item_i = readU16(is); - std::istringstream tmp_is(deSerializeLongString(is), std::ios::binary); + u8 action; + u16 item_i; + *pkt >> action; + *pkt >> item_i; + std::istringstream tmp_is(pkt->readLongString(), std::ios::binary); PointedThing pointed; pointed.deSerialize(tmp_is); @@ -1331,6 +1337,8 @@ void Server::handleCommand_Interact(NetworkPacket* pkt) return; } + process_PlayerPos(player, playersao, pkt); + v3f player_pos = playersao->getLastGoodPosition(); // Update wielded item diff --git a/src/server.h b/src/server.h index f8b3ec106..9e844e36c 100644 --- a/src/server.h +++ b/src/server.h @@ -197,6 +197,10 @@ public: void Send(NetworkPacket* pkt); + // Helper for handleCommand_PlayerPos and handleCommand_Interact + void process_PlayerPos(RemotePlayer *player, PlayerSAO *playersao, + NetworkPacket *pkt); + // Both setter and getter need no envlock, // can be called freely from threads void setTimeOfDay(u32 time); -- cgit v1.2.3 From 93e3555eae2deaeca69ee252cfa9cc9c3e0e49ef Mon Sep 17 00:00:00 2001 From: Foghrye4 Date: Mon, 14 Nov 2016 18:09:59 +0400 Subject: Adding particle blend, glow and animation (#4705) --- builtin/common/misc_helpers.lua | 37 +++++++ doc/lua_api.txt | 189 ++++++++++++++++++++++++++++++++- src/client.h | 18 ++++ src/network/clientpackethandler.cpp | 111 ++++++++++++++------ src/nodedef.cpp | 4 +- src/nodedef.h | 11 +- src/particles.cpp | 203 +++++++++++++++++++++++++++++++++--- src/particles.h | 32 +++++- src/script/common/c_content.cpp | 13 +-- src/script/common/c_content.h | 2 +- src/script/common/c_converter.cpp | 22 ++++ src/script/common/c_converter.h | 2 + src/script/lua_api/l_particles.cpp | 166 ++++++++++++++++++++++++++++- src/server.cpp | 44 ++++++-- src/server.h | 27 ++++- 15 files changed, 800 insertions(+), 81 deletions(-) (limited to 'src/network') diff --git a/builtin/common/misc_helpers.lua b/builtin/common/misc_helpers.lua index c2dc7514d..a495058d9 100644 --- a/builtin/common/misc_helpers.lua +++ b/builtin/common/misc_helpers.lua @@ -237,6 +237,43 @@ function math.sign(x, tolerance) return 0 end +-------------------------------------------------------------------------------- +-- Video enums and pack function + +-- E_BLEND_FACTOR +minetest.ebf = { + zero = 0, -- src & dest (0, 0, 0, 0) + one = 1, -- src & dest (1, 1, 1, 1) + dst_color = 2, -- src (destR, destG, destB, destA) + one_minus_dst_color = 3, -- src (1-destR, 1-destG, 1-destB, 1-destA) + src_color = 4, -- dest (srcR, srcG, srcB, srcA) + one_minus_src_color = 5, -- dest (1-srcR, 1-srcG, 1-srcB, 1-srcA) + src_alpha = 6, -- src & dest (srcA, srcA, srcA, srcA) + one_minus_src_alpha = 7, -- src & dest (1-srcA, 1-srcA, 1-srcA, 1-srcA) + dst_alpha = 8, -- src & dest (destA, destA, destA, destA) + one_minus_dst_alpha = 9, -- src & dest (1-destA, 1-destA, 1-destA, 1-destA) + src_alpha_saturate = 10,-- src (min(srcA, 1-destA), idem, ...) +} + +-- E_MODULATE_FUNC +minetest.emfn = { + modulate_1x = 1, + modulate_2x = 2, + modulate_4x = 4, +} + +-- E_ALPHA_SOURCE +minetest.eas = { + none = 0, + vertex_color = 1, + texture = 2, +} + +-- BlendFunc = source * sourceFactor + dest * destFactor +function minetest.pack_texture_blend_func(srcFact, dstFact, modulate, alphaSource) + return alphaSource * 4096 + modulate * 256 + srcFact * 16 + dstFact +end + -------------------------------------------------------------------------------- function get_last_folder(text,count) local parts = text:split(DIR_DELIM) diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 7d552c980..3b3f17634 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -414,6 +414,119 @@ the word "`alpha`", then each texture pixel will contain the RGB of `` and the alpha of `` multiplied by the alpha of the texture pixel. +Particle blend +-------------- +Blend function is defined by integer number. +There is a huge number of acceptable blend modificators. +Colour of a resulting pixel calculated using formulae: + + red = source_red * source_factor + destination_red * destination_factor + +and so on for every channel. + +Here is a some examples: + +Default value: + + material_type_param = 0, + +Use this value to disable blending. Texture will be applied to existing pixels +using alpha channel of it. Its recomended to use 1-bit alpha +in that case. This value will leave z-buffer writeable. + +Additive blend: + + material_type_param = 12641, + +Source = src_alpha, destination = one, alpha source is a texture and +vertex_color, modulate_1x. +Black color is completely transparent, white color is completely opaque. +Alpha channel still used to calculate result color, but not nessesary. +'destination = one' means that resulting color will be calculated using +overwritten pixels values. +For example with color of source (our texture) RGBA = (0,192,255,63) +"blue-cyan", 1/4 opaque. +and already rendered pixel color (40,192,0) "dark lime green" we will get color: + +R = source_red(0) * source_factor(src_alpha=63/255) + + destination_red(40) * destination_factor(one) = + 0 * 63/255 + 40 * 1 = 40 + +G = 192 * 63/255 + 192 * 1 = 239 +B = 255 * 63/255 + 0 * 1 = 63 + +Result: (40,239,63), "green" (a kind of). +Note, if you made a texture with some kind of shape with colour 662211h +it will appear dark red with a single particle, then yellow with a +several of them and white if player looking thru a lot of them. With +this you could made a nice-looking fire. + +Substractive blend: + + material_type_param = 12548, + +Source = zero, destination = src_color, alpha source is a texture and +vertex_color, modulate_1x. +Texture darkness act like an alpha channel. +Black color is completely opaque, white color is completely transparent. +'destination = src_color' means that destination in multiplied by +a source values. 'source = zero' means that source values ignored +(multiplied by 0). + +Invert blend: + + material_type_param = 12597, + +Source = one_minus_dst_color, destination = one_minus_src_alpha, alpha source +is a texture and vertex_color, modulate_1x. +Pixels invert color if source color value is big enough. If not, they just +black. +'destination = one_minus_src_alpha' means, that effect is masked by a +source alpha channel. + +You can design and use your own blend using those enum values and function +'minetest.pack_texture_blend_func'. Returned value of a function is +your 'material_type_param'. + +A values in a brackets is a multiplicators of a red, green, blue +and alpha channels respectively. + +* 'minetest.ebf': global table, containing blend factor enum values. Such as: + * zero = 0 -- src & dest (0, 0, 0, 0) + * one = 1 -- src & dest (1, 1, 1, 1) + * dst_color = 2 -- src (destR, destG, destB, destA) + * one_minus_dst_color = 3 -- src (1-destR, 1-destG, 1-destB, 1-destA) + * src_color = 4 -- dest (srcR, srcG, srcB, srcA) + * one_minus_src_color = 5 -- dest (1-srcR, 1-srcG, 1-srcB, 1-srcA) + * src_alpha = 6 -- src & dest (srcA, srcA, srcA, srcA) + * one_minus_src_alpha = 7 -- src & dest (1-srcA, 1-srcA, 1-srcA, 1-srcA) + * dst_alpha = 8 -- src & dest (destA, destA, destA, destA) + * one_minus_dst_alpha = 9 -- src & dest (1-destA, 1-destA, 1-destA, 1-destA) + * src_alpha_saturate = 10 -- src (min(srcA, 1-destA), idem, ...) + +* 'minetest.emfn': global table, containing modulate enum values. + * Multiply the components of the arguments, and shift the products to the + * left by x bits for brightening. Contain: + * modulate_1x = 1 -- no bit shift + * modulate_2x = 2 -- 1 bits shift + * modulate_4x = 4 -- 2 bits shift + +'modulate_4x' is quite useful when you want to make additive blend stronger +with a lower amount of particles. + +* 'minetest.eas': global table, containing alpha source enum values. Such as: + * none = 0 -- do not use alpha. + * vertex_color = 1 -- use vertex color alpha. + * texture = 2 -- use texture alpha. + +You can use both 'vertex_color' and 'texture' source by using value 3. + +* 'minetest.pack_texture_blend_func(srcFact, dstFact, modulate, alphaSource)': return integer + * Pack texture blend funcion variable. Depending from that variable blend + * function will be applied in time of a render poligons with selected material. + * Therefore resulting pixel will be 'source * srcFact + destination * dstFact' + * Use result of this function as 'material_type_param'. + Sounds ------ Only Ogg Vorbis files are supported. @@ -3650,7 +3763,7 @@ Definition tables ### Tile definition * `"image.png"` -* `{name="image.png", animation={Tile Animation definition}}` +* `{name="image.png", animation={Animation definition}}` * `{name="image.png", backface_culling=bool, tileable_vertical=bool, tileable_horizontal=bool}` * backface culling enabled by default for most nodes @@ -3661,8 +3774,50 @@ Definition tables * deprecated, yet still supported field names: * `image` (name) -### Tile animation definition -* `{type="vertical_frames", aspect_w=16, aspect_h=16, length=3.0}` +### Animation definition + +#### Node animation, particle and particle spawners +* `{ type="vertical_frames", + aspect_w=16, + -- ^ specify width of a picture in pixels. + aspect_h=16, + -- ^ specify height of a frame in pixels. + length=3.0 + -- ^ specify full loop length. + first_frame = 0, -- <- only for particles, use + min_first_frame = 0, -- <- for particle spawners + max_first_frame = 0, + loop_animation = true, -- <- only for particles and particle spawners + -- specify if animation should start from beginning after last frame. +}` + +#### Particle and particle spawners only +* `{ + type="2d_animation_sheet", -- <- only for particles and particle spawners + vertical_frame_num = 1, + horizontal_frame_num = 1, + -- ^ specify amount of frames in texture. + -- Can be used both for animation or for texture transform + -- together with first_frame variable. + -- A animation texture separated on equal parts of frames, + -- by horizontal and vertical numbers. For example with + -- vertical_frame_num = 4 and horizontal_frame_num = 3 we got + -- 4*3 = 12 frames in total. Animation sequence start from + -- left top frame and go on to the right until reach end of + -- row. Next row also start from left frame. + first_frame = 0, -- <- only for particles, use + min_first_frame = 0, -- <- for particle spawners + max_first_frame = 0, + -- ^ specify first frame to start animation. + frame_length = -1, + -- ^ specify length of a frame in seconds. Negative and zero values + -- disable animation. A sequence with vertical_frame_num = 4 and + -- horizontal_frame_num = 3, first_frame = 4 and frame_length = 0.1 + -- will end in (4*3-4)*0.1 = 0.8 seconds. + loop_animation = true, + -- specify if animation should start from beginning after last frame. +}` + * All settings are optional. Default values is located in this example. ### Node definition (`register_node`) @@ -4117,6 +4272,20 @@ The Biome API is still in an experimental phase and subject to change. -- ^ Uses texture (string) playername = "singleplayer" -- ^ optional, if specified spawns particle only on the player's client + material_type_param = 12641, + -- ^ optional, if specified spawns particle with + -- specified material type param and disable z-buffer. + -- Some examples: + -- Default value: 0, + -- Additive blend: 12641, + -- Substractive blend: 12548, + -- Invert blend: 12597, + -- See also "Particle blend". + animation = {Animation definition}, + -- ^ see above. Note, that particle and particle spawners have differences. + glow = 15, + -- ^ optional, specify particle self-luminescence in darkness. + values may vary from 0 (no glow) to 15 (bright glow). } ### `ParticleSpawner` definition (`add_particlespawner`) @@ -4151,6 +4320,20 @@ The Biome API is still in an experimental phase and subject to change. -- ^ Uses texture (string) playername = "singleplayer" -- ^ Playername is optional, if specified spawns particle only on the player's client + material_type_param = 12641, + -- ^ optional, if specified spawns particle with specified material type + -- param and disable z-buffer. + -- Some examples: + -- Default value: 0, + -- Additive blend: 12641, + -- Substractive blend: 12548, + -- Invert blend: 12597, + -- See also "Particle blend". + animation = {Animation definition}, + -- ^ see above. Note, that particle and particle spawners have differences. + glow = 15, + -- ^ optional, specify particle self-luminescence in darkness. + values may vary from 0 (no glow) to 15 (bright glow). } ### `HTTPRequest` definition (`HTTPApiTable.fetch_async`, `HTTPApiTable.fetch_async`) diff --git a/src/client.h b/src/client.h index 9f5bda059..c51daf7bc 100644 --- a/src/client.h +++ b/src/client.h @@ -35,6 +35,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "hud.h" #include "particles.h" #include "network/networkpacket.h" +#include "nodedef.h" // AnimationType struct MeshMakeData; class MapBlockMesh; @@ -185,6 +186,14 @@ struct ClientEvent bool collision_removal; bool vertical; std::string *texture; + u32 material_type_param; + AnimationType animation_type; + u16 vertical_frame_num; + u16 horizontal_frame_num; + u16 first_frame; + float frame_length; + bool loop_animation; + u8 glow; } spawn_particle; struct{ u16 amount; @@ -205,6 +214,15 @@ struct ClientEvent bool vertical; std::string *texture; u32 id; + u32 material_type_param; + AnimationType animation_type; + u16 vertical_frame_num; + u16 horizontal_frame_num; + u16 min_first_frame; + u16 max_first_frame; + float frame_length; + bool loop_animation; + u8 glow; } add_particlespawner; struct{ u32 id; diff --git a/src/network/clientpackethandler.cpp b/src/network/clientpackethandler.cpp index 411982f69..03baf078a 100644 --- a/src/network/clientpackethandler.cpp +++ b/src/network/clientpackethandler.cpp @@ -896,23 +896,46 @@ void Client::handleCommand_SpawnParticle(NetworkPacket* pkt) std::string texture = deSerializeLongString(is); bool vertical = false; bool collision_removal = false; + u32 material_type_param = 0; + AnimationType animation_type = AT_NONE; + u16 vertical_frame_num = 1; + u16 horizontal_frame_num = 1; + u16 first_frame = 0; + float frame_length = -1; + bool loop_animation = true; + u8 glow = 0; try { vertical = readU8(is); collision_removal = readU8(is); + material_type_param = readU32(is); + animation_type = (AnimationType)readU8(is); + vertical_frame_num = readU16(is); + horizontal_frame_num = readU16(is); + first_frame = readU16(is); + frame_length = readF1000(is); + loop_animation = readU8(is); + glow = readU8(is); } catch (...) {} ClientEvent event; - event.type = CE_SPAWN_PARTICLE; - event.spawn_particle.pos = new v3f (pos); - event.spawn_particle.vel = new v3f (vel); - event.spawn_particle.acc = new v3f (acc); - event.spawn_particle.expirationtime = expirationtime; - event.spawn_particle.size = size; - event.spawn_particle.collisiondetection = collisiondetection; - event.spawn_particle.collision_removal = collision_removal; - event.spawn_particle.vertical = vertical; - event.spawn_particle.texture = new std::string(texture); - + event.type = CE_SPAWN_PARTICLE; + event.spawn_particle.pos = new v3f (pos); + event.spawn_particle.vel = new v3f (vel); + event.spawn_particle.acc = new v3f (acc); + event.spawn_particle.expirationtime = expirationtime; + event.spawn_particle.size = size; + event.spawn_particle.collisiondetection = collisiondetection; + event.spawn_particle.collision_removal = collision_removal; + event.spawn_particle.vertical = vertical; + event.spawn_particle.texture = new std::string(texture); + event.spawn_particle.material_type_param = material_type_param; + event.spawn_particle.animation_type = animation_type; + event.spawn_particle.vertical_frame_num = vertical_frame_num; + event.spawn_particle.horizontal_frame_num = horizontal_frame_num; + event.spawn_particle.first_frame = first_frame; + event.spawn_particle.frame_length = frame_length; + event.spawn_particle.loop_animation = loop_animation; + event.spawn_particle.glow = glow; m_client_event_queue.push(event); } @@ -932,6 +955,15 @@ void Client::handleCommand_AddParticleSpawner(NetworkPacket* pkt) float maxsize; bool collisiondetection; u32 id; + u32 material_type_param = 0; + u8 animation_type = (u8)AT_NONE; + u16 vertical_frame_num = 1; + u16 horizontal_frame_num = 1; + u16 min_first_frame = 0; + u16 max_first_frame = 0; + float frame_length = -1; + bool loop_animation = true; + u8 glow = 0; *pkt >> amount >> spawntime >> minpos >> maxpos >> minvel >> maxvel >> minacc >> maxacc >> minexptime >> maxexptime >> minsize @@ -948,29 +980,46 @@ void Client::handleCommand_AddParticleSpawner(NetworkPacket* pkt) *pkt >> vertical; *pkt >> collision_removal; *pkt >> attached_id; - + *pkt >> material_type_param; + *pkt >> animation_type; + *pkt >> vertical_frame_num; + *pkt >> horizontal_frame_num; + *pkt >> min_first_frame; + *pkt >> max_first_frame; + *pkt >> frame_length; + *pkt >> loop_animation; + *pkt >> glow; } catch (...) {} ClientEvent event; - event.type = CE_ADD_PARTICLESPAWNER; - event.add_particlespawner.amount = amount; - event.add_particlespawner.spawntime = spawntime; - event.add_particlespawner.minpos = new v3f (minpos); - event.add_particlespawner.maxpos = new v3f (maxpos); - event.add_particlespawner.minvel = new v3f (minvel); - event.add_particlespawner.maxvel = new v3f (maxvel); - event.add_particlespawner.minacc = new v3f (minacc); - event.add_particlespawner.maxacc = new v3f (maxacc); - event.add_particlespawner.minexptime = minexptime; - event.add_particlespawner.maxexptime = maxexptime; - event.add_particlespawner.minsize = minsize; - event.add_particlespawner.maxsize = maxsize; - event.add_particlespawner.collisiondetection = collisiondetection; - event.add_particlespawner.collision_removal = collision_removal; - event.add_particlespawner.attached_id = attached_id; - event.add_particlespawner.vertical = vertical; - event.add_particlespawner.texture = new std::string(texture); - event.add_particlespawner.id = id; + event.type = CE_ADD_PARTICLESPAWNER; + event.add_particlespawner.amount = amount; + event.add_particlespawner.spawntime = spawntime; + event.add_particlespawner.minpos = new v3f (minpos); + event.add_particlespawner.maxpos = new v3f (maxpos); + event.add_particlespawner.minvel = new v3f (minvel); + event.add_particlespawner.maxvel = new v3f (maxvel); + event.add_particlespawner.minacc = new v3f (minacc); + event.add_particlespawner.maxacc = new v3f (maxacc); + event.add_particlespawner.minexptime = minexptime; + event.add_particlespawner.maxexptime = maxexptime; + event.add_particlespawner.minsize = minsize; + event.add_particlespawner.maxsize = maxsize; + event.add_particlespawner.collisiondetection = collisiondetection; + event.add_particlespawner.collision_removal = collision_removal; + event.add_particlespawner.attached_id = attached_id; + event.add_particlespawner.vertical = vertical; + event.add_particlespawner.texture = new std::string(texture); + event.add_particlespawner.id = id; + event.add_particlespawner.material_type_param = material_type_param; + event.add_particlespawner.animation_type = (AnimationType)animation_type; + event.add_particlespawner.vertical_frame_num = vertical_frame_num; + event.add_particlespawner.horizontal_frame_num = horizontal_frame_num; + event.add_particlespawner.min_first_frame = min_first_frame; + event.add_particlespawner.max_first_frame = max_first_frame; + event.add_particlespawner.frame_length = frame_length; + event.add_particlespawner.loop_animation = loop_animation; + event.add_particlespawner.glow = glow; m_client_event_queue.push(event); } diff --git a/src/nodedef.cpp b/src/nodedef.cpp index 39ea1a60e..c690e6720 100644 --- a/src/nodedef.cpp +++ b/src/nodedef.cpp @@ -211,7 +211,7 @@ void TileDef::deSerialize(std::istream &is, const u8 contenfeatures_version, con { int version = readU8(is); name = deSerializeString(is); - animation.type = (TileAnimationType)readU8(is); + animation.type = (AnimationType)readU8(is); animation.aspect_w = readU16(is); animation.aspect_h = readU16(is); animation.length = readF1000(is); @@ -531,7 +531,7 @@ void ContentFeatures::fillTileAttribs(ITextureSource *tsrc, TileSpec *tile, tile->material_flags = 0; if (backface_culling) tile->material_flags |= MATERIAL_FLAG_BACKFACE_CULLING; - if (tiledef->animation.type == TAT_VERTICAL_FRAMES) + if (tiledef->animation.type == AT_VERTICAL_FRAMES) tile->material_flags |= MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES; if (tiledef->tileable_horizontal) tile->material_flags |= MATERIAL_FLAG_TILEABLE_HORIZONTAL; diff --git a/src/nodedef.h b/src/nodedef.h index 80396f992..f47517c4a 100644 --- a/src/nodedef.h +++ b/src/nodedef.h @@ -161,9 +161,10 @@ enum NodeDrawType /* Stand-alone definition of a TileSpec (basically a server-side TileSpec) */ -enum TileAnimationType{ - TAT_NONE=0, - TAT_VERTICAL_FRAMES=1, +enum AnimationType{ + AT_NONE = 0, + AT_VERTICAL_FRAMES = 1, + AT_2D_ANIMATION_SHEET = 2, }; struct TileDef { @@ -172,7 +173,7 @@ struct TileDef bool tileable_horizontal; bool tileable_vertical; struct{ - enum TileAnimationType type; + enum AnimationType type; int aspect_w; // width for aspect ratio int aspect_h; // height for aspect ratio float length; // seconds @@ -184,7 +185,7 @@ struct TileDef backface_culling = true; tileable_horizontal = true; tileable_vertical = true; - animation.type = TAT_NONE; + animation.type = AT_NONE; animation.aspect_w = 1; animation.aspect_h = 1; animation.length = 1.0; diff --git a/src/particles.cpp b/src/particles.cpp index f20fb4083..538487028 100644 --- a/src/particles.cpp +++ b/src/particles.cpp @@ -43,6 +43,22 @@ v3f random_v3f(v3f min, v3f max) rand()/(float)RAND_MAX*(max.Z-min.Z)+min.Z); } +u32 check_material_type_param(u32 material_type_param) +{ + u32 alphaSource = (material_type_param & 0x0000F000) >> 12; + u32 modulo = (material_type_param & 0x00000F00) >> 8; + u32 srcFact = (material_type_param & 0x000000F0) >> 4; + u32 dstFact = material_type_param & 0x0000000F; + if (alphaSource <= 3 && modulo <= 4 && srcFact <= 10 && dstFact <= 10) { + return material_type_param; + } else { + errorstream << "Server send incorrect "; + errorstream << "material_type_param value for particle."; + errorstream << std::endl; + return 0; + } +} + Particle::Particle( IGameDef *gamedef, scene::ISceneManager* smgr, @@ -58,7 +74,14 @@ Particle::Particle( bool vertical, video::ITexture *texture, v2f texpos, - v2f texsize + v2f texsize, + u32 material_type_param, + u16 vertical_frame_num, + u16 horizontal_frame_num, + u16 first_frame, + float frame_length, + bool loop_animation, + u8 glow ): scene::ISceneNode(smgr->getRootSceneNode(), smgr) { @@ -71,11 +94,26 @@ Particle::Particle( m_material.setFlag(video::EMF_BACK_FACE_CULLING, false); m_material.setFlag(video::EMF_BILINEAR_FILTER, false); m_material.setFlag(video::EMF_FOG_ENABLE, true); - m_material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; + if (material_type_param != 0) { + m_material.MaterialType = video::EMT_ONETEXTURE_BLEND; + m_material.MaterialTypeParam = irr::core::FR(material_type_param); + // We must disable z-buffer if we want to avoid transparent pixels + // to overlap pixels with lower z-value. + m_material.setFlag(video::EMF_ZWRITE_ENABLE, false); + } else { + m_material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; + } m_material.setTexture(0, texture); + m_texpos = texpos; m_texsize = texsize; - + m_vertical_frame_num = vertical_frame_num; + m_horizontal_frame_num = horizontal_frame_num; + m_first_frame = first_frame; + m_frame_length = frame_length; + m_loop_animation = loop_animation; + m_texsize.Y /= m_vertical_frame_num; + m_texsize.X /= m_horizontal_frame_num; // Particle related m_pos = pos; @@ -88,6 +126,7 @@ Particle::Particle( m_collisiondetection = collisiondetection; m_collision_removal = collision_removal; m_vertical = vertical; + m_glow = glow; // Irrlicht stuff m_collisionbox = aabb3f @@ -170,16 +209,29 @@ void Particle::updateLight() else light = blend_light(m_env->getDayNightRatio(), LIGHT_SUN, 0); - m_light = decode_light(light); + m_light = decode_light(light + m_glow); } void Particle::updateVertices() { video::SColor c(255, m_light, m_light, m_light); - f32 tx0 = m_texpos.X; - f32 tx1 = m_texpos.X + m_texsize.X; - f32 ty0 = m_texpos.Y; - f32 ty1 = m_texpos.Y + m_texsize.Y; + u16 frame = m_first_frame; + if (m_frame_length > 0) { + if (m_loop_animation) + frame = m_first_frame + (u32)(m_time / m_frame_length) + % (m_vertical_frame_num * + m_horizontal_frame_num - m_first_frame); + else if (m_time >= + (m_vertical_frame_num * m_horizontal_frame_num + - m_first_frame) * m_frame_length) + frame = m_vertical_frame_num * m_horizontal_frame_num - 1; + else + frame = m_first_frame + (u16)(m_time / m_frame_length); + } + f32 tx0 = m_texpos.X + m_texsize.X * (frame % m_horizontal_frame_num); + f32 tx1 = m_texpos.X + m_texsize.X * (frame % m_horizontal_frame_num + 1); + f32 ty0 = m_texpos.Y + m_texsize.Y * (frame / m_horizontal_frame_num); + f32 ty1 = m_texpos.Y + m_texsize.Y * (frame / m_horizontal_frame_num + 1); m_vertices[0] = video::S3DVertex(-m_size/2,-m_size/2,0, 0,0,0, c, tx0, ty1); @@ -214,7 +266,16 @@ ParticleSpawner::ParticleSpawner(IGameDef* gamedef, scene::ISceneManager *smgr, v3f minpos, v3f maxpos, v3f minvel, v3f maxvel, v3f minacc, v3f maxacc, float minexptime, float maxexptime, float minsize, float maxsize, bool collisiondetection, bool collision_removal, u16 attached_id, bool vertical, - video::ITexture *texture, u32 id, ParticleManager *p_manager) : + video::ITexture *texture, u32 id, + u32 material_type_param, + u16 vertical_frame_num, + u16 horizontal_frame_num, + u16 min_first_frame, + u16 max_first_frame, + float frame_length, + bool loop_animation, + u8 glow, + ParticleManager *p_manager) : m_particlemanager(p_manager) { m_gamedef = gamedef; @@ -238,6 +299,14 @@ ParticleSpawner::ParticleSpawner(IGameDef* gamedef, scene::ISceneManager *smgr, m_vertical = vertical; m_texture = texture; m_time = 0; + m_vertical_frame_num = vertical_frame_num; + m_horizontal_frame_num = horizontal_frame_num; + m_min_first_frame = min_first_frame; + m_max_first_frame = max_first_frame; + m_frame_length = frame_length; + m_loop_animation = loop_animation; + m_material_type_param = material_type_param; + m_glow = glow; for (u16 i = 0; i<=m_amount; i++) { @@ -251,7 +320,6 @@ ParticleSpawner::~ParticleSpawner() {} void ParticleSpawner::step(float dtime, ClientEnvironment* env) { m_time += dtime; - bool unloaded = false; v3f attached_offset = v3f(0,0,0); if (m_attached_id != 0) { @@ -285,7 +353,10 @@ void ParticleSpawner::step(float dtime, ClientEnvironment* env) float size = rand()/(float)RAND_MAX *(m_maxsize-m_minsize) +m_minsize; - + u16 first_frame = m_min_first_frame + + rand() % + (m_max_first_frame - + m_min_first_frame + 1); Particle* toadd = new Particle( m_gamedef, m_smgr, @@ -301,7 +372,14 @@ void ParticleSpawner::step(float dtime, ClientEnvironment* env) m_vertical, m_texture, v2f(0.0, 0.0), - v2f(1.0, 1.0)); + v2f(1.0, 1.0), + m_material_type_param, + m_vertical_frame_num, + m_horizontal_frame_num, + first_frame, + m_frame_length, + m_loop_animation, + m_glow); m_particlemanager->addParticle(toadd); } i = m_spawntimes.erase(i); @@ -331,7 +409,10 @@ void ParticleSpawner::step(float dtime, ClientEnvironment* env) float size = rand()/(float)RAND_MAX *(m_maxsize-m_minsize) +m_minsize; - + u16 first_frame = m_min_first_frame + + rand() % + (m_max_first_frame - + m_min_first_frame + 1); Particle* toadd = new Particle( m_gamedef, m_smgr, @@ -347,7 +428,14 @@ void ParticleSpawner::step(float dtime, ClientEnvironment* env) m_vertical, m_texture, v2f(0.0, 0.0), - v2f(1.0, 1.0)); + v2f(1.0, 1.0), + m_material_type_param, + m_vertical_frame_num, + m_horizontal_frame_num, + first_frame, + m_frame_length, + m_loop_animation, + m_glow); m_particlemanager->addParticle(toadd); } } @@ -459,6 +547,39 @@ void ParticleManager::handleParticleEvent(ClientEvent *event, IGameDef *gamedef, video::ITexture *texture = gamedef->tsrc()->getTextureForMesh(*(event->add_particlespawner.texture)); + float frame_length = -1; + u16 vertical_frame_num = 1; + u16 horizontal_frame_num = 1; + u32 material_type_param = + check_material_type_param(event->add_particlespawner.material_type_param); + + switch (event->add_particlespawner.animation_type) { + case AT_NONE: + break; + case AT_VERTICAL_FRAMES: { + v2u32 size = texture->getOriginalSize(); + int frame_height = (float)size.X / + (float)event->add_particlespawner.vertical_frame_num * + (float)event->add_particlespawner.horizontal_frame_num; + vertical_frame_num = size.Y / frame_height; + frame_length = + event->add_particlespawner.frame_length / + vertical_frame_num; + break; + } + case AT_2D_ANIMATION_SHEET: { + vertical_frame_num = + event->add_particlespawner.vertical_frame_num; + horizontal_frame_num = + event->add_particlespawner.horizontal_frame_num; + frame_length = + event->add_particlespawner.frame_length; + break; + } + default: + break; + } + ParticleSpawner* toadd = new ParticleSpawner(gamedef, smgr, player, event->add_particlespawner.amount, event->add_particlespawner.spawntime, @@ -478,6 +599,14 @@ void ParticleManager::handleParticleEvent(ClientEvent *event, IGameDef *gamedef, event->add_particlespawner.vertical, texture, event->add_particlespawner.id, + material_type_param, + vertical_frame_num, + horizontal_frame_num, + event->add_particlespawner.min_first_frame, + event->add_particlespawner.max_first_frame, + frame_length, + event->add_particlespawner.loop_animation, + event->add_particlespawner.glow, this); /* delete allocated content of event */ @@ -502,6 +631,39 @@ void ParticleManager::handleParticleEvent(ClientEvent *event, IGameDef *gamedef, video::ITexture *texture = gamedef->tsrc()->getTextureForMesh(*(event->spawn_particle.texture)); + float frame_length = -1; + u16 vertical_frame_num = 1; + u16 horizontal_frame_num = 1; + u32 material_type_param = + check_material_type_param(event->spawn_particle.material_type_param); + + switch (event->spawn_particle.animation_type) { + case AT_NONE: + break; + case AT_VERTICAL_FRAMES: { + v2u32 size = texture->getOriginalSize(); + int frame_height = (float)size.X / + (float)event->spawn_particle.vertical_frame_num * + (float)event->spawn_particle.horizontal_frame_num; + vertical_frame_num = size.Y / frame_height; + frame_length = + event->spawn_particle.frame_length / + vertical_frame_num; + break; + } + case AT_2D_ANIMATION_SHEET: { + vertical_frame_num = + event->spawn_particle.vertical_frame_num; + horizontal_frame_num = + event->spawn_particle.horizontal_frame_num; + frame_length = + event->spawn_particle.frame_length; + break; + } + default: + break; + } + Particle* toadd = new Particle(gamedef, smgr, player, m_env, *event->spawn_particle.pos, *event->spawn_particle.vel, @@ -513,13 +675,21 @@ void ParticleManager::handleParticleEvent(ClientEvent *event, IGameDef *gamedef, event->spawn_particle.vertical, texture, v2f(0.0, 0.0), - v2f(1.0, 1.0)); + v2f(1.0, 1.0), + material_type_param, + vertical_frame_num, + horizontal_frame_num, + event->spawn_particle.first_frame, + frame_length, + event->spawn_particle.loop_animation, + event->spawn_particle.glow); addParticle(toadd); delete event->spawn_particle.pos; delete event->spawn_particle.vel; delete event->spawn_particle.acc; + delete event->spawn_particle.texture; break; } @@ -588,7 +758,8 @@ void ParticleManager::addNodeParticle(IGameDef* gamedef, scene::ISceneManager* s false, texture, texpos, - texsize); + texsize, + 0, 1, 1, 0, -1, true, 0); addParticle(toadd); } diff --git a/src/particles.h b/src/particles.h index eb8c6665d..6d8c6139f 100644 --- a/src/particles.h +++ b/src/particles.h @@ -50,7 +50,14 @@ class Particle : public scene::ISceneNode bool vertical, video::ITexture *texture, v2f texpos, - v2f texsize + v2f texsize, + u32 material_type_param, + u16 vertical_frame_num, + u16 horizontal_frame_num, + u16 first_frame, + float frame_length, + bool loop_animation, + u8 glow ); ~Particle(); @@ -102,6 +109,12 @@ private: bool m_collision_removal; bool m_vertical; v3s16 m_camera_offset; + u16 m_vertical_frame_num; + u16 m_horizontal_frame_num; + u16 m_first_frame; + float m_frame_length; + bool m_loop_animation; + u8 m_glow; }; class ParticleSpawner @@ -123,8 +136,15 @@ class ParticleSpawner bool vertical, video::ITexture *texture, u32 id, + u32 material_type_param, + u16 vertical_frame_num, + u16 horizontal_frame_num, + u16 min_first_frame, + u16 max_first_frame, + float frame_length, + bool loop_animation, + u8 glow, ParticleManager* p_manager); - ~ParticleSpawner(); void step(float dtime, ClientEnvironment *env); @@ -156,6 +176,14 @@ class ParticleSpawner bool m_collision_removal; bool m_vertical; u16 m_attached_id; + u32 m_material_type_param; + u16 m_vertical_frame_num; + u16 m_horizontal_frame_num; + u16 m_min_first_frame; + u16 m_max_first_frame; + float m_frame_length; + bool m_loop_animation; + u8 m_glow; }; /** diff --git a/src/script/common/c_content.cpp b/src/script/common/c_content.cpp index f20a65903..d4a25b68b 100644 --- a/src/script/common/c_content.cpp +++ b/src/script/common/c_content.cpp @@ -35,10 +35,11 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "noise.h" #include -struct EnumString es_TileAnimationType[] = +struct EnumString es_AnimationType[] = { - {TAT_NONE, "none"}, - {TAT_VERTICAL_FRAMES, "vertical_frames"}, + {AT_NONE, "none"}, + {AT_VERTICAL_FRAMES, "vertical_frames"}, + {AT_2D_ANIMATION_SHEET, "2d_animation_sheet"}, {0, NULL}, }; @@ -335,9 +336,9 @@ TileDef read_tiledef(lua_State *L, int index, u8 drawtype) lua_getfield(L, index, "animation"); if(lua_istable(L, -1)){ // {type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0} - tiledef.animation.type = (TileAnimationType) - getenumfield(L, -1, "type", es_TileAnimationType, - TAT_NONE); + tiledef.animation.type = (AnimationType) + getenumfield(L, -1, "type", es_AnimationType, + AT_NONE); tiledef.animation.aspect_w = getintfield_default(L, -1, "aspect_w", 16); tiledef.animation.aspect_h = diff --git a/src/script/common/c_content.h b/src/script/common/c_content.h index 2a2228b6d..32fdb4f04 100644 --- a/src/script/common/c_content.h +++ b/src/script/common/c_content.h @@ -159,6 +159,6 @@ bool push_json_value (lua_State *L, void read_json_value (lua_State *L, Json::Value &root, int index, u8 recursion = 0); -extern struct EnumString es_TileAnimationType[]; +extern struct EnumString es_AnimationType[]; #endif /* C_CONTENT_H_ */ diff --git a/src/script/common/c_converter.cpp b/src/script/common/c_converter.cpp index f36298915..cfb5e26db 100644 --- a/src/script/common/c_converter.cpp +++ b/src/script/common/c_converter.cpp @@ -513,6 +513,28 @@ int getintfield_default(lua_State *L, int table, return result; } +int check_material_type_param(lua_State *L, int table, + const char *fieldname, int default_) +{ + int material_type_param = + getintfield_default(L, table, fieldname, default_); + u32 alphaSource = (material_type_param & 0x0000F000) >> 12; + u32 modulo = (material_type_param & 0x00000F00) >> 8; + u32 srcFact = (material_type_param & 0x000000F0) >> 4; + u32 dstFact = material_type_param & 0x0000000F; + if (alphaSource <= 3 && modulo <= 4 && srcFact <= 10 && dstFact <= 10) { + return material_type_param; + } else { + std::ostringstream error_text; + error_text << "Incorrect material_type_param value "; + error_text << "for particle or particle spawner."; + error_text << std::endl; + throw LuaError(error_text.str()); + return 0; + } +} + + float getfloatfield_default(lua_State *L, int table, const char *fieldname, float default_) { diff --git a/src/script/common/c_converter.h b/src/script/common/c_converter.h index a5fbee765..71ac735c1 100644 --- a/src/script/common/c_converter.h +++ b/src/script/common/c_converter.h @@ -45,6 +45,8 @@ float getfloatfield_default(lua_State *L, int table, const char *fieldname, float default_); int getintfield_default (lua_State *L, int table, const char *fieldname, int default_); +int check_material_type_param(lua_State *L, int table, + const char *fieldname, int default_); bool getstringfield(lua_State *L, int table, const char *fieldname, std::string &result); diff --git a/src/script/lua_api/l_particles.cpp b/src/script/lua_api/l_particles.cpp index 667ac7272..b0a57ce6d 100644 --- a/src/script/lua_api/l_particles.cpp +++ b/src/script/lua_api/l_particles.cpp @@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "lua_api/l_object.h" #include "lua_api/l_internal.h" #include "common/c_converter.h" +#include "common/c_content.h" #include "server.h" #include "particles.h" @@ -34,6 +35,9 @@ with this program; if not, write to the Free Software Foundation, Inc., // collision_removal = bool // vertical = bool // texture = e.g."default_wood.png" +// material_type_param = num +// animation = animation definition +// glow = indexed color or color string int ModApiParticles::l_add_particle(lua_State *L) { MAP_LOCK_REQUIRED; @@ -44,13 +48,24 @@ int ModApiParticles::l_add_particle(lua_State *L) float expirationtime, size; expirationtime = size = 1; + float frame_or_loop_length = -1; + + AnimationType animation_type = AT_NONE; + + u16 vertical_frame_num_or_aspect = 1; + u16 horizontal_frame_num_or_aspect = 1; + u16 first_frame = 0; bool collisiondetection, vertical, collision_removal; collisiondetection = vertical = collision_removal = false; + bool loop_animation = true; std::string texture = ""; std::string playername = ""; + u32 material_type_param = 0; + u8 glow = 0; + if (lua_gettop(L) > 1) // deprecated { log_deprecated(L, "Deprecated add_particle call with individual parameters instead of definition"); @@ -94,8 +109,61 @@ int ModApiParticles::l_add_particle(lua_State *L) acc = lua_istable(L, -1) ? check_v3f(L, -1) : acc; lua_pop(L, 1); - expirationtime = getfloatfield_default(L, 1, "expirationtime", 1); + expirationtime = getfloatfield_default(L, 1, "expirationtime", 1); size = getfloatfield_default(L, 1, "size", 1); + + lua_getfield(L, 1, "animation"); + if (lua_istable(L, -1)) { + animation_type = (AnimationType) + getenumfield(L, -1, "type", es_AnimationType, + AT_NONE); + } + switch (animation_type) { + case AT_NONE: + break; + case AT_2D_ANIMATION_SHEET: + frame_or_loop_length = + getfloatfield_default(L, -1, "frame_length", -1); + vertical_frame_num_or_aspect = + getintfield_default(L, -1, "vertical_frame_num", 1); + horizontal_frame_num_or_aspect = + getintfield_default(L, -1, "horizontal_frame_num", 1); + first_frame = + getintfield_default(L, -1, "first_frame", 0); + loop_animation = + getboolfield_default(L, -1, "loop_animation", true); + break; + case AT_VERTICAL_FRAMES: + frame_or_loop_length = + getfloatfield_default(L, -1, "length", -1); + vertical_frame_num_or_aspect = + getintfield_default(L, -1, "aspect_w", 1); + horizontal_frame_num_or_aspect = + getintfield_default(L, -1, "aspect_h", 1); + first_frame = + getintfield_default(L, -1, "first_frame", 0); + loop_animation = + getboolfield_default(L, -1, "loop_animation", true); + break; + default: + break; + } + lua_pop(L, 1); + + if (animation_type == AT_2D_ANIMATION_SHEET && + first_frame >= vertical_frame_num_or_aspect * + horizontal_frame_num_or_aspect) { + std::ostringstream error_text; + error_text << "first_frame should be lower, than " + << "vertical_frame_num * horizontal_frame_num. " + << "Got first_frame=" << first_frame + << ", vertical_frame_num=" + << vertical_frame_num_or_aspect + << " and horizontal_frame_num=" + << horizontal_frame_num_or_aspect << std::endl; + throw LuaError(error_text.str()); + } + collisiondetection = getboolfield_default(L, 1, "collisiondetection", collisiondetection); collision_removal = getboolfield_default(L, 1, @@ -103,9 +171,16 @@ int ModApiParticles::l_add_particle(lua_State *L) vertical = getboolfield_default(L, 1, "vertical", vertical); texture = getstringfield_default(L, 1, "texture", ""); playername = getstringfield_default(L, 1, "playername", ""); + material_type_param = check_material_type_param(L, 1, "material_type_param", 0); + glow = getintfield_default (L, 1, "glow", 0); } - getServer(L)->spawnParticle(playername, pos, vel, acc, expirationtime, size, - collisiondetection, collision_removal, vertical, texture); + getServer(L)->spawnParticle(playername, pos, vel, acc, expirationtime, + size, collisiondetection, collision_removal, vertical, + texture, material_type_param, + animation_type, + vertical_frame_num_or_aspect, + horizontal_frame_num_or_aspect, + first_frame, frame_or_loop_length, loop_animation, glow); return 1; } @@ -127,21 +202,33 @@ int ModApiParticles::l_add_particle(lua_State *L) // collision_removal = bool // vertical = bool // texture = e.g."default_wood.png" +// material_type_param = num +// animation = animation definition +// glow = indexed color or color string int ModApiParticles::l_add_particlespawner(lua_State *L) { MAP_LOCK_REQUIRED; // Get parameters u16 amount = 1; + u16 vertical_frame_num_or_aspect = 1; + u16 horizontal_frame_num_or_aspect = 1; + u16 min_first_frame = 0; + u16 max_first_frame = 0; v3f minpos, maxpos, minvel, maxvel, minacc, maxacc; minpos= maxpos= minvel= maxvel= minacc= maxacc= v3f(0, 0, 0); float time, minexptime, maxexptime, minsize, maxsize; time= minexptime= maxexptime= minsize= maxsize= 1; + AnimationType animation_type = AT_NONE; + float frame_or_loop_length = -1; bool collisiondetection, vertical, collision_removal; collisiondetection = vertical = collision_removal = false; + bool loop_animation = true; ServerActiveObject *attached = NULL; std::string texture = ""; std::string playername = ""; + u32 material_type_param = 0; + u8 glow = 0; if (lua_gettop(L) > 1) //deprecated { @@ -196,6 +283,65 @@ int ModApiParticles::l_add_particlespawner(lua_State *L) maxexptime = getfloatfield_default(L, 1, "maxexptime", maxexptime); minsize = getfloatfield_default(L, 1, "minsize", minsize); maxsize = getfloatfield_default(L, 1, "maxsize", maxsize); + + + lua_getfield(L, 1, "animation"); + if (lua_istable(L, -1)) { + animation_type = (AnimationType) + getenumfield(L, -1, "type", es_AnimationType, + AT_NONE); + } + switch (animation_type) { + case AT_NONE: + break; + case AT_2D_ANIMATION_SHEET: + frame_or_loop_length = + getfloatfield_default(L, -1, "frame_length", -1); + vertical_frame_num_or_aspect = + getintfield_default(L, -1, "vertical_frame_num", 1); + horizontal_frame_num_or_aspect = + getintfield_default(L, -1, "horizontal_frame_num", 1); + min_first_frame = + getintfield_default(L, -1, "min_first_frame", 0); + max_first_frame = + getintfield_default(L, -1, "max_first_frame", 0); + loop_animation = + getboolfield_default(L, -1, "loop_animation", true); + break; + case AT_VERTICAL_FRAMES: + frame_or_loop_length = + getfloatfield_default(L, -1, "length", -1); + vertical_frame_num_or_aspect = + getintfield_default(L, -1, "aspect_w", 1); + horizontal_frame_num_or_aspect = + getintfield_default(L, -1, "aspect_h", 1); + min_first_frame = + getintfield_default(L, -1, "min_first_frame", 0); + max_first_frame = + getintfield_default(L, -1, "max_first_frame", 0); + loop_animation = + getboolfield_default(L, -1, "loop_animation", true); + break; + default: + break; + } + lua_pop(L, 1); + + if (animation_type == AT_2D_ANIMATION_SHEET && + max_first_frame >= vertical_frame_num_or_aspect * + horizontal_frame_num_or_aspect) { + std::ostringstream error_text; + error_text << "max_first_frame should be lower, than " + << "vertical_frame_num * horizontal_frame_num. " + << "Got max_first_frame=" + << max_first_frame + << ", vertical_frame_num=" + << vertical_frame_num_or_aspect + << " and horizontal_frame_num=" + << horizontal_frame_num_or_aspect << std::endl; + throw LuaError(error_text.str()); + } + collisiondetection = getboolfield_default(L, 1, "collisiondetection", collisiondetection); collision_removal = getboolfield_default(L, 1, @@ -211,6 +357,8 @@ int ModApiParticles::l_add_particlespawner(lua_State *L) vertical = getboolfield_default(L, 1, "vertical", vertical); texture = getstringfield_default(L, 1, "texture", ""); playername = getstringfield_default(L, 1, "playername", ""); + material_type_param = check_material_type_param(L, 1, "material_type_param", 0); + glow = getintfield_default(L, 1, "glow", 0); } u32 id = getServer(L)->addParticleSpawner(amount, time, @@ -223,9 +371,17 @@ int ModApiParticles::l_add_particlespawner(lua_State *L) collision_removal, attached, vertical, - texture, playername); + texture, + playername, + material_type_param, + animation_type, + vertical_frame_num_or_aspect, + horizontal_frame_num_or_aspect, + min_first_frame, max_first_frame, + frame_or_loop_length, + loop_animation, + glow); lua_pushnumber(L, id); - return 1; } diff --git a/src/server.cpp b/src/server.cpp index 48331e4f8..cef57be88 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -1658,7 +1658,11 @@ void Server::SendShowFormspecMessage(u16 peer_id, const std::string &formspec, void Server::SendSpawnParticle(u16 peer_id, v3f pos, v3f velocity, v3f acceleration, float expirationtime, float size, bool collisiondetection, bool collision_removal, - bool vertical, const std::string &texture) + bool vertical, const std::string &texture, + u32 material_type_param, AnimationType animation_type, + u16 vertical_frame_num, u16 horizontal_frame_num, u16 first_frame, + float frame_length, bool loop_animation, + u8 glow) { DSTACK(FUNCTION_NAME); @@ -1670,6 +1674,12 @@ void Server::SendSpawnParticle(u16 peer_id, v3f pos, v3f velocity, v3f accelerat pkt << vertical; pkt << collision_removal; + pkt << material_type_param + << (u8)animation_type + << vertical_frame_num + << horizontal_frame_num << first_frame + << frame_length << loop_animation << glow; + if (peer_id != PEER_ID_INEXISTENT) { Send(&pkt); } @@ -1682,7 +1692,10 @@ void Server::SendSpawnParticle(u16 peer_id, v3f pos, v3f velocity, v3f accelerat void Server::SendAddParticleSpawner(u16 peer_id, u16 amount, float spawntime, v3f minpos, v3f maxpos, v3f minvel, v3f maxvel, v3f minacc, v3f maxacc, float minexptime, float maxexptime, float minsize, float maxsize, bool collisiondetection, bool collision_removal, - u16 attached_id, bool vertical, const std::string &texture, u32 id) + u16 attached_id, bool vertical, const std::string &texture, u32 id, + u32 material_type_param, AnimationType animation_type, u16 vertical_frame_num, u16 horizontal_frame_num, + u16 min_first_frame, u16 max_first_frame, float frame_length, + bool loop_animation, u8 glow) { DSTACK(FUNCTION_NAME); @@ -1698,6 +1711,12 @@ void Server::SendAddParticleSpawner(u16 peer_id, u16 amount, float spawntime, v3 pkt << collision_removal; pkt << attached_id; + pkt << material_type_param + << (u8)animation_type + << vertical_frame_num << horizontal_frame_num + << min_first_frame << max_first_frame + << frame_length << loop_animation << glow; + if (peer_id != PEER_ID_INEXISTENT) { Send(&pkt); } @@ -3147,7 +3166,11 @@ void Server::spawnParticle(const std::string &playername, v3f pos, v3f velocity, v3f acceleration, float expirationtime, float size, bool collisiondetection, bool collision_removal, - bool vertical, const std::string &texture) + bool vertical, const std::string &texture, + u32 material_type_param, AnimationType animation_type, + u16 vertical_frame_num, u16 horizontal_frame_num, u16 first_frame, + float frame_length, bool loop_animation, + u8 glow) { // m_env will be NULL if the server is initializing if (!m_env) @@ -3163,7 +3186,11 @@ void Server::spawnParticle(const std::string &playername, v3f pos, SendSpawnParticle(peer_id, pos, velocity, acceleration, expirationtime, size, collisiondetection, - collision_removal, vertical, texture); + collision_removal, vertical, texture, + material_type_param, animation_type, + vertical_frame_num, horizontal_frame_num, + first_frame, frame_length, loop_animation, + glow); } u32 Server::addParticleSpawner(u16 amount, float spawntime, @@ -3171,7 +3198,9 @@ u32 Server::addParticleSpawner(u16 amount, float spawntime, float minexptime, float maxexptime, float minsize, float maxsize, bool collisiondetection, bool collision_removal, ServerActiveObject *attached, bool vertical, const std::string &texture, - const std::string &playername) + const std::string &playername, u32 material_type_param, AnimationType animation_type, + u16 vertical_frame_num, u16 horizontal_frame_num, u16 min_first_frame, u16 max_first_frame, + float frame_length, bool loop_animation, u8 glow) { // m_env will be NULL if the server is initializing if (!m_env) @@ -3197,7 +3226,10 @@ u32 Server::addParticleSpawner(u16 amount, float spawntime, minpos, maxpos, minvel, maxvel, minacc, maxacc, minexptime, maxexptime, minsize, maxsize, collisiondetection, collision_removal, attached_id, vertical, - texture, id); + texture, id, material_type_param, animation_type, + vertical_frame_num, horizontal_frame_num, + min_first_frame, max_first_frame, frame_length, loop_animation, + glow); return id; } diff --git a/src/server.h b/src/server.h index 9e844e36c..9a8d22b2e 100644 --- a/src/server.h +++ b/src/server.h @@ -26,6 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "hud.h" #include "gamedef.h" #include "serialization.h" // For SER_FMT_VER_INVALID +#include "nodedef.h" // AnimationType #include "mods.h" #include "inventorymanager.h" #include "subgame.h" @@ -254,7 +255,11 @@ public: v3f pos, v3f velocity, v3f acceleration, float expirationtime, float size, bool collisiondetection, bool collision_removal, - bool vertical, const std::string &texture); + bool vertical, const std::string &texture, + u32 material_type_param, AnimationType animation_type, + u16 vertical_frame_num, u16 horizontal_frame_num, u16 first_frame, + float frame_length, bool loop_animation, + u8 glow); u32 addParticleSpawner(u16 amount, float spawntime, v3f minpos, v3f maxpos, @@ -265,7 +270,12 @@ public: bool collisiondetection, bool collision_removal, ServerActiveObject *attached, bool vertical, const std::string &texture, - const std::string &playername); + const std::string &playername, + u32 material_type_param, AnimationType animation_type, + u16 vertical_frame_num, u16 horizontal_frame_num, + u16 min_first_frame, u16 max_first_frame, + float frame_length, bool loop_animation, + u8 glow); void deleteParticleSpawner(const std::string &playername, u32 id); @@ -441,7 +451,12 @@ private: float minsize, float maxsize, bool collisiondetection, bool collision_removal, u16 attached_id, - bool vertical, const std::string &texture, u32 id); + bool vertical, const std::string &texture, u32 id, + u32 material_type_param, AnimationType animation_type, + u16 vertical_frame_num, u16 horizontal_frame_num, + u16 min_first_frame, u16 max_first_frame, + float frame_length, bool loop_animation, + u8 glow); void SendDeleteParticleSpawner(u16 peer_id, u32 id); @@ -450,7 +465,11 @@ private: v3f pos, v3f velocity, v3f acceleration, float expirationtime, float size, bool collisiondetection, bool collision_removal, - bool vertical, const std::string &texture); + bool vertical, const std::string &texture, + u32 material_type_param, AnimationType animation_type, + u16 vertical_frame_num, u16 horizontal_frame_num, u16 first_frame, + float frame_length, bool loop_animation, + u8 glow); u32 SendActiveObjectRemoveAdd(u16 peer_id, const std::string &datas); void SendActiveObjectMessages(u16 peer_id, const std::string &datas, bool reliable = true); -- cgit v1.2.3 From 5fd1ef9b589419e2464f5599ea47a2f28f4d7b7b Mon Sep 17 00:00:00 2001 From: sfan5 Date: Mon, 14 Nov 2016 15:28:06 +0100 Subject: Revert "Adding particle blend, glow and animation (#4705)" This reverts commit 93e3555eae2deaeca69ee252cfa9cc9c3e0e49ef. --- builtin/common/misc_helpers.lua | 37 ------- doc/lua_api.txt | 189 +-------------------------------- src/client.h | 18 ---- src/network/clientpackethandler.cpp | 111 ++++++-------------- src/nodedef.cpp | 4 +- src/nodedef.h | 11 +- src/particles.cpp | 203 +++--------------------------------- src/particles.h | 32 +----- src/script/common/c_content.cpp | 13 ++- src/script/common/c_content.h | 2 +- src/script/common/c_converter.cpp | 22 ---- src/script/common/c_converter.h | 2 - src/script/lua_api/l_particles.cpp | 166 +---------------------------- src/server.cpp | 44 ++------ src/server.h | 27 +---- 15 files changed, 81 insertions(+), 800 deletions(-) (limited to 'src/network') diff --git a/builtin/common/misc_helpers.lua b/builtin/common/misc_helpers.lua index a495058d9..c2dc7514d 100644 --- a/builtin/common/misc_helpers.lua +++ b/builtin/common/misc_helpers.lua @@ -237,43 +237,6 @@ function math.sign(x, tolerance) return 0 end --------------------------------------------------------------------------------- --- Video enums and pack function - --- E_BLEND_FACTOR -minetest.ebf = { - zero = 0, -- src & dest (0, 0, 0, 0) - one = 1, -- src & dest (1, 1, 1, 1) - dst_color = 2, -- src (destR, destG, destB, destA) - one_minus_dst_color = 3, -- src (1-destR, 1-destG, 1-destB, 1-destA) - src_color = 4, -- dest (srcR, srcG, srcB, srcA) - one_minus_src_color = 5, -- dest (1-srcR, 1-srcG, 1-srcB, 1-srcA) - src_alpha = 6, -- src & dest (srcA, srcA, srcA, srcA) - one_minus_src_alpha = 7, -- src & dest (1-srcA, 1-srcA, 1-srcA, 1-srcA) - dst_alpha = 8, -- src & dest (destA, destA, destA, destA) - one_minus_dst_alpha = 9, -- src & dest (1-destA, 1-destA, 1-destA, 1-destA) - src_alpha_saturate = 10,-- src (min(srcA, 1-destA), idem, ...) -} - --- E_MODULATE_FUNC -minetest.emfn = { - modulate_1x = 1, - modulate_2x = 2, - modulate_4x = 4, -} - --- E_ALPHA_SOURCE -minetest.eas = { - none = 0, - vertex_color = 1, - texture = 2, -} - --- BlendFunc = source * sourceFactor + dest * destFactor -function minetest.pack_texture_blend_func(srcFact, dstFact, modulate, alphaSource) - return alphaSource * 4096 + modulate * 256 + srcFact * 16 + dstFact -end - -------------------------------------------------------------------------------- function get_last_folder(text,count) local parts = text:split(DIR_DELIM) diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 3b3f17634..7d552c980 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -414,119 +414,6 @@ the word "`alpha`", then each texture pixel will contain the RGB of `` and the alpha of `` multiplied by the alpha of the texture pixel. -Particle blend --------------- -Blend function is defined by integer number. -There is a huge number of acceptable blend modificators. -Colour of a resulting pixel calculated using formulae: - - red = source_red * source_factor + destination_red * destination_factor - -and so on for every channel. - -Here is a some examples: - -Default value: - - material_type_param = 0, - -Use this value to disable blending. Texture will be applied to existing pixels -using alpha channel of it. Its recomended to use 1-bit alpha -in that case. This value will leave z-buffer writeable. - -Additive blend: - - material_type_param = 12641, - -Source = src_alpha, destination = one, alpha source is a texture and -vertex_color, modulate_1x. -Black color is completely transparent, white color is completely opaque. -Alpha channel still used to calculate result color, but not nessesary. -'destination = one' means that resulting color will be calculated using -overwritten pixels values. -For example with color of source (our texture) RGBA = (0,192,255,63) -"blue-cyan", 1/4 opaque. -and already rendered pixel color (40,192,0) "dark lime green" we will get color: - -R = source_red(0) * source_factor(src_alpha=63/255) + - destination_red(40) * destination_factor(one) = - 0 * 63/255 + 40 * 1 = 40 - -G = 192 * 63/255 + 192 * 1 = 239 -B = 255 * 63/255 + 0 * 1 = 63 - -Result: (40,239,63), "green" (a kind of). -Note, if you made a texture with some kind of shape with colour 662211h -it will appear dark red with a single particle, then yellow with a -several of them and white if player looking thru a lot of them. With -this you could made a nice-looking fire. - -Substractive blend: - - material_type_param = 12548, - -Source = zero, destination = src_color, alpha source is a texture and -vertex_color, modulate_1x. -Texture darkness act like an alpha channel. -Black color is completely opaque, white color is completely transparent. -'destination = src_color' means that destination in multiplied by -a source values. 'source = zero' means that source values ignored -(multiplied by 0). - -Invert blend: - - material_type_param = 12597, - -Source = one_minus_dst_color, destination = one_minus_src_alpha, alpha source -is a texture and vertex_color, modulate_1x. -Pixels invert color if source color value is big enough. If not, they just -black. -'destination = one_minus_src_alpha' means, that effect is masked by a -source alpha channel. - -You can design and use your own blend using those enum values and function -'minetest.pack_texture_blend_func'. Returned value of a function is -your 'material_type_param'. - -A values in a brackets is a multiplicators of a red, green, blue -and alpha channels respectively. - -* 'minetest.ebf': global table, containing blend factor enum values. Such as: - * zero = 0 -- src & dest (0, 0, 0, 0) - * one = 1 -- src & dest (1, 1, 1, 1) - * dst_color = 2 -- src (destR, destG, destB, destA) - * one_minus_dst_color = 3 -- src (1-destR, 1-destG, 1-destB, 1-destA) - * src_color = 4 -- dest (srcR, srcG, srcB, srcA) - * one_minus_src_color = 5 -- dest (1-srcR, 1-srcG, 1-srcB, 1-srcA) - * src_alpha = 6 -- src & dest (srcA, srcA, srcA, srcA) - * one_minus_src_alpha = 7 -- src & dest (1-srcA, 1-srcA, 1-srcA, 1-srcA) - * dst_alpha = 8 -- src & dest (destA, destA, destA, destA) - * one_minus_dst_alpha = 9 -- src & dest (1-destA, 1-destA, 1-destA, 1-destA) - * src_alpha_saturate = 10 -- src (min(srcA, 1-destA), idem, ...) - -* 'minetest.emfn': global table, containing modulate enum values. - * Multiply the components of the arguments, and shift the products to the - * left by x bits for brightening. Contain: - * modulate_1x = 1 -- no bit shift - * modulate_2x = 2 -- 1 bits shift - * modulate_4x = 4 -- 2 bits shift - -'modulate_4x' is quite useful when you want to make additive blend stronger -with a lower amount of particles. - -* 'minetest.eas': global table, containing alpha source enum values. Such as: - * none = 0 -- do not use alpha. - * vertex_color = 1 -- use vertex color alpha. - * texture = 2 -- use texture alpha. - -You can use both 'vertex_color' and 'texture' source by using value 3. - -* 'minetest.pack_texture_blend_func(srcFact, dstFact, modulate, alphaSource)': return integer - * Pack texture blend funcion variable. Depending from that variable blend - * function will be applied in time of a render poligons with selected material. - * Therefore resulting pixel will be 'source * srcFact + destination * dstFact' - * Use result of this function as 'material_type_param'. - Sounds ------ Only Ogg Vorbis files are supported. @@ -3763,7 +3650,7 @@ Definition tables ### Tile definition * `"image.png"` -* `{name="image.png", animation={Animation definition}}` +* `{name="image.png", animation={Tile Animation definition}}` * `{name="image.png", backface_culling=bool, tileable_vertical=bool, tileable_horizontal=bool}` * backface culling enabled by default for most nodes @@ -3774,50 +3661,8 @@ Definition tables * deprecated, yet still supported field names: * `image` (name) -### Animation definition - -#### Node animation, particle and particle spawners -* `{ type="vertical_frames", - aspect_w=16, - -- ^ specify width of a picture in pixels. - aspect_h=16, - -- ^ specify height of a frame in pixels. - length=3.0 - -- ^ specify full loop length. - first_frame = 0, -- <- only for particles, use - min_first_frame = 0, -- <- for particle spawners - max_first_frame = 0, - loop_animation = true, -- <- only for particles and particle spawners - -- specify if animation should start from beginning after last frame. -}` - -#### Particle and particle spawners only -* `{ - type="2d_animation_sheet", -- <- only for particles and particle spawners - vertical_frame_num = 1, - horizontal_frame_num = 1, - -- ^ specify amount of frames in texture. - -- Can be used both for animation or for texture transform - -- together with first_frame variable. - -- A animation texture separated on equal parts of frames, - -- by horizontal and vertical numbers. For example with - -- vertical_frame_num = 4 and horizontal_frame_num = 3 we got - -- 4*3 = 12 frames in total. Animation sequence start from - -- left top frame and go on to the right until reach end of - -- row. Next row also start from left frame. - first_frame = 0, -- <- only for particles, use - min_first_frame = 0, -- <- for particle spawners - max_first_frame = 0, - -- ^ specify first frame to start animation. - frame_length = -1, - -- ^ specify length of a frame in seconds. Negative and zero values - -- disable animation. A sequence with vertical_frame_num = 4 and - -- horizontal_frame_num = 3, first_frame = 4 and frame_length = 0.1 - -- will end in (4*3-4)*0.1 = 0.8 seconds. - loop_animation = true, - -- specify if animation should start from beginning after last frame. -}` - * All settings are optional. Default values is located in this example. +### Tile animation definition +* `{type="vertical_frames", aspect_w=16, aspect_h=16, length=3.0}` ### Node definition (`register_node`) @@ -4272,20 +4117,6 @@ The Biome API is still in an experimental phase and subject to change. -- ^ Uses texture (string) playername = "singleplayer" -- ^ optional, if specified spawns particle only on the player's client - material_type_param = 12641, - -- ^ optional, if specified spawns particle with - -- specified material type param and disable z-buffer. - -- Some examples: - -- Default value: 0, - -- Additive blend: 12641, - -- Substractive blend: 12548, - -- Invert blend: 12597, - -- See also "Particle blend". - animation = {Animation definition}, - -- ^ see above. Note, that particle and particle spawners have differences. - glow = 15, - -- ^ optional, specify particle self-luminescence in darkness. - values may vary from 0 (no glow) to 15 (bright glow). } ### `ParticleSpawner` definition (`add_particlespawner`) @@ -4320,20 +4151,6 @@ The Biome API is still in an experimental phase and subject to change. -- ^ Uses texture (string) playername = "singleplayer" -- ^ Playername is optional, if specified spawns particle only on the player's client - material_type_param = 12641, - -- ^ optional, if specified spawns particle with specified material type - -- param and disable z-buffer. - -- Some examples: - -- Default value: 0, - -- Additive blend: 12641, - -- Substractive blend: 12548, - -- Invert blend: 12597, - -- See also "Particle blend". - animation = {Animation definition}, - -- ^ see above. Note, that particle and particle spawners have differences. - glow = 15, - -- ^ optional, specify particle self-luminescence in darkness. - values may vary from 0 (no glow) to 15 (bright glow). } ### `HTTPRequest` definition (`HTTPApiTable.fetch_async`, `HTTPApiTable.fetch_async`) diff --git a/src/client.h b/src/client.h index c51daf7bc..9f5bda059 100644 --- a/src/client.h +++ b/src/client.h @@ -35,7 +35,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "hud.h" #include "particles.h" #include "network/networkpacket.h" -#include "nodedef.h" // AnimationType struct MeshMakeData; class MapBlockMesh; @@ -186,14 +185,6 @@ struct ClientEvent bool collision_removal; bool vertical; std::string *texture; - u32 material_type_param; - AnimationType animation_type; - u16 vertical_frame_num; - u16 horizontal_frame_num; - u16 first_frame; - float frame_length; - bool loop_animation; - u8 glow; } spawn_particle; struct{ u16 amount; @@ -214,15 +205,6 @@ struct ClientEvent bool vertical; std::string *texture; u32 id; - u32 material_type_param; - AnimationType animation_type; - u16 vertical_frame_num; - u16 horizontal_frame_num; - u16 min_first_frame; - u16 max_first_frame; - float frame_length; - bool loop_animation; - u8 glow; } add_particlespawner; struct{ u32 id; diff --git a/src/network/clientpackethandler.cpp b/src/network/clientpackethandler.cpp index 03baf078a..411982f69 100644 --- a/src/network/clientpackethandler.cpp +++ b/src/network/clientpackethandler.cpp @@ -896,46 +896,23 @@ void Client::handleCommand_SpawnParticle(NetworkPacket* pkt) std::string texture = deSerializeLongString(is); bool vertical = false; bool collision_removal = false; - u32 material_type_param = 0; - AnimationType animation_type = AT_NONE; - u16 vertical_frame_num = 1; - u16 horizontal_frame_num = 1; - u16 first_frame = 0; - float frame_length = -1; - bool loop_animation = true; - u8 glow = 0; try { vertical = readU8(is); collision_removal = readU8(is); - material_type_param = readU32(is); - animation_type = (AnimationType)readU8(is); - vertical_frame_num = readU16(is); - horizontal_frame_num = readU16(is); - first_frame = readU16(is); - frame_length = readF1000(is); - loop_animation = readU8(is); - glow = readU8(is); } catch (...) {} ClientEvent event; - event.type = CE_SPAWN_PARTICLE; - event.spawn_particle.pos = new v3f (pos); - event.spawn_particle.vel = new v3f (vel); - event.spawn_particle.acc = new v3f (acc); - event.spawn_particle.expirationtime = expirationtime; - event.spawn_particle.size = size; - event.spawn_particle.collisiondetection = collisiondetection; - event.spawn_particle.collision_removal = collision_removal; - event.spawn_particle.vertical = vertical; - event.spawn_particle.texture = new std::string(texture); - event.spawn_particle.material_type_param = material_type_param; - event.spawn_particle.animation_type = animation_type; - event.spawn_particle.vertical_frame_num = vertical_frame_num; - event.spawn_particle.horizontal_frame_num = horizontal_frame_num; - event.spawn_particle.first_frame = first_frame; - event.spawn_particle.frame_length = frame_length; - event.spawn_particle.loop_animation = loop_animation; - event.spawn_particle.glow = glow; + event.type = CE_SPAWN_PARTICLE; + event.spawn_particle.pos = new v3f (pos); + event.spawn_particle.vel = new v3f (vel); + event.spawn_particle.acc = new v3f (acc); + event.spawn_particle.expirationtime = expirationtime; + event.spawn_particle.size = size; + event.spawn_particle.collisiondetection = collisiondetection; + event.spawn_particle.collision_removal = collision_removal; + event.spawn_particle.vertical = vertical; + event.spawn_particle.texture = new std::string(texture); + m_client_event_queue.push(event); } @@ -955,15 +932,6 @@ void Client::handleCommand_AddParticleSpawner(NetworkPacket* pkt) float maxsize; bool collisiondetection; u32 id; - u32 material_type_param = 0; - u8 animation_type = (u8)AT_NONE; - u16 vertical_frame_num = 1; - u16 horizontal_frame_num = 1; - u16 min_first_frame = 0; - u16 max_first_frame = 0; - float frame_length = -1; - bool loop_animation = true; - u8 glow = 0; *pkt >> amount >> spawntime >> minpos >> maxpos >> minvel >> maxvel >> minacc >> maxacc >> minexptime >> maxexptime >> minsize @@ -980,46 +948,29 @@ void Client::handleCommand_AddParticleSpawner(NetworkPacket* pkt) *pkt >> vertical; *pkt >> collision_removal; *pkt >> attached_id; - *pkt >> material_type_param; - *pkt >> animation_type; - *pkt >> vertical_frame_num; - *pkt >> horizontal_frame_num; - *pkt >> min_first_frame; - *pkt >> max_first_frame; - *pkt >> frame_length; - *pkt >> loop_animation; - *pkt >> glow; + } catch (...) {} ClientEvent event; - event.type = CE_ADD_PARTICLESPAWNER; - event.add_particlespawner.amount = amount; - event.add_particlespawner.spawntime = spawntime; - event.add_particlespawner.minpos = new v3f (minpos); - event.add_particlespawner.maxpos = new v3f (maxpos); - event.add_particlespawner.minvel = new v3f (minvel); - event.add_particlespawner.maxvel = new v3f (maxvel); - event.add_particlespawner.minacc = new v3f (minacc); - event.add_particlespawner.maxacc = new v3f (maxacc); - event.add_particlespawner.minexptime = minexptime; - event.add_particlespawner.maxexptime = maxexptime; - event.add_particlespawner.minsize = minsize; - event.add_particlespawner.maxsize = maxsize; - event.add_particlespawner.collisiondetection = collisiondetection; - event.add_particlespawner.collision_removal = collision_removal; - event.add_particlespawner.attached_id = attached_id; - event.add_particlespawner.vertical = vertical; - event.add_particlespawner.texture = new std::string(texture); - event.add_particlespawner.id = id; - event.add_particlespawner.material_type_param = material_type_param; - event.add_particlespawner.animation_type = (AnimationType)animation_type; - event.add_particlespawner.vertical_frame_num = vertical_frame_num; - event.add_particlespawner.horizontal_frame_num = horizontal_frame_num; - event.add_particlespawner.min_first_frame = min_first_frame; - event.add_particlespawner.max_first_frame = max_first_frame; - event.add_particlespawner.frame_length = frame_length; - event.add_particlespawner.loop_animation = loop_animation; - event.add_particlespawner.glow = glow; + event.type = CE_ADD_PARTICLESPAWNER; + event.add_particlespawner.amount = amount; + event.add_particlespawner.spawntime = spawntime; + event.add_particlespawner.minpos = new v3f (minpos); + event.add_particlespawner.maxpos = new v3f (maxpos); + event.add_particlespawner.minvel = new v3f (minvel); + event.add_particlespawner.maxvel = new v3f (maxvel); + event.add_particlespawner.minacc = new v3f (minacc); + event.add_particlespawner.maxacc = new v3f (maxacc); + event.add_particlespawner.minexptime = minexptime; + event.add_particlespawner.maxexptime = maxexptime; + event.add_particlespawner.minsize = minsize; + event.add_particlespawner.maxsize = maxsize; + event.add_particlespawner.collisiondetection = collisiondetection; + event.add_particlespawner.collision_removal = collision_removal; + event.add_particlespawner.attached_id = attached_id; + event.add_particlespawner.vertical = vertical; + event.add_particlespawner.texture = new std::string(texture); + event.add_particlespawner.id = id; m_client_event_queue.push(event); } diff --git a/src/nodedef.cpp b/src/nodedef.cpp index c690e6720..39ea1a60e 100644 --- a/src/nodedef.cpp +++ b/src/nodedef.cpp @@ -211,7 +211,7 @@ void TileDef::deSerialize(std::istream &is, const u8 contenfeatures_version, con { int version = readU8(is); name = deSerializeString(is); - animation.type = (AnimationType)readU8(is); + animation.type = (TileAnimationType)readU8(is); animation.aspect_w = readU16(is); animation.aspect_h = readU16(is); animation.length = readF1000(is); @@ -531,7 +531,7 @@ void ContentFeatures::fillTileAttribs(ITextureSource *tsrc, TileSpec *tile, tile->material_flags = 0; if (backface_culling) tile->material_flags |= MATERIAL_FLAG_BACKFACE_CULLING; - if (tiledef->animation.type == AT_VERTICAL_FRAMES) + if (tiledef->animation.type == TAT_VERTICAL_FRAMES) tile->material_flags |= MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES; if (tiledef->tileable_horizontal) tile->material_flags |= MATERIAL_FLAG_TILEABLE_HORIZONTAL; diff --git a/src/nodedef.h b/src/nodedef.h index f47517c4a..80396f992 100644 --- a/src/nodedef.h +++ b/src/nodedef.h @@ -161,10 +161,9 @@ enum NodeDrawType /* Stand-alone definition of a TileSpec (basically a server-side TileSpec) */ -enum AnimationType{ - AT_NONE = 0, - AT_VERTICAL_FRAMES = 1, - AT_2D_ANIMATION_SHEET = 2, +enum TileAnimationType{ + TAT_NONE=0, + TAT_VERTICAL_FRAMES=1, }; struct TileDef { @@ -173,7 +172,7 @@ struct TileDef bool tileable_horizontal; bool tileable_vertical; struct{ - enum AnimationType type; + enum TileAnimationType type; int aspect_w; // width for aspect ratio int aspect_h; // height for aspect ratio float length; // seconds @@ -185,7 +184,7 @@ struct TileDef backface_culling = true; tileable_horizontal = true; tileable_vertical = true; - animation.type = AT_NONE; + animation.type = TAT_NONE; animation.aspect_w = 1; animation.aspect_h = 1; animation.length = 1.0; diff --git a/src/particles.cpp b/src/particles.cpp index 538487028..f20fb4083 100644 --- a/src/particles.cpp +++ b/src/particles.cpp @@ -43,22 +43,6 @@ v3f random_v3f(v3f min, v3f max) rand()/(float)RAND_MAX*(max.Z-min.Z)+min.Z); } -u32 check_material_type_param(u32 material_type_param) -{ - u32 alphaSource = (material_type_param & 0x0000F000) >> 12; - u32 modulo = (material_type_param & 0x00000F00) >> 8; - u32 srcFact = (material_type_param & 0x000000F0) >> 4; - u32 dstFact = material_type_param & 0x0000000F; - if (alphaSource <= 3 && modulo <= 4 && srcFact <= 10 && dstFact <= 10) { - return material_type_param; - } else { - errorstream << "Server send incorrect "; - errorstream << "material_type_param value for particle."; - errorstream << std::endl; - return 0; - } -} - Particle::Particle( IGameDef *gamedef, scene::ISceneManager* smgr, @@ -74,14 +58,7 @@ Particle::Particle( bool vertical, video::ITexture *texture, v2f texpos, - v2f texsize, - u32 material_type_param, - u16 vertical_frame_num, - u16 horizontal_frame_num, - u16 first_frame, - float frame_length, - bool loop_animation, - u8 glow + v2f texsize ): scene::ISceneNode(smgr->getRootSceneNode(), smgr) { @@ -94,26 +71,11 @@ Particle::Particle( m_material.setFlag(video::EMF_BACK_FACE_CULLING, false); m_material.setFlag(video::EMF_BILINEAR_FILTER, false); m_material.setFlag(video::EMF_FOG_ENABLE, true); - if (material_type_param != 0) { - m_material.MaterialType = video::EMT_ONETEXTURE_BLEND; - m_material.MaterialTypeParam = irr::core::FR(material_type_param); - // We must disable z-buffer if we want to avoid transparent pixels - // to overlap pixels with lower z-value. - m_material.setFlag(video::EMF_ZWRITE_ENABLE, false); - } else { - m_material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; - } + m_material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; m_material.setTexture(0, texture); - m_texpos = texpos; m_texsize = texsize; - m_vertical_frame_num = vertical_frame_num; - m_horizontal_frame_num = horizontal_frame_num; - m_first_frame = first_frame; - m_frame_length = frame_length; - m_loop_animation = loop_animation; - m_texsize.Y /= m_vertical_frame_num; - m_texsize.X /= m_horizontal_frame_num; + // Particle related m_pos = pos; @@ -126,7 +88,6 @@ Particle::Particle( m_collisiondetection = collisiondetection; m_collision_removal = collision_removal; m_vertical = vertical; - m_glow = glow; // Irrlicht stuff m_collisionbox = aabb3f @@ -209,29 +170,16 @@ void Particle::updateLight() else light = blend_light(m_env->getDayNightRatio(), LIGHT_SUN, 0); - m_light = decode_light(light + m_glow); + m_light = decode_light(light); } void Particle::updateVertices() { video::SColor c(255, m_light, m_light, m_light); - u16 frame = m_first_frame; - if (m_frame_length > 0) { - if (m_loop_animation) - frame = m_first_frame + (u32)(m_time / m_frame_length) - % (m_vertical_frame_num * - m_horizontal_frame_num - m_first_frame); - else if (m_time >= - (m_vertical_frame_num * m_horizontal_frame_num - - m_first_frame) * m_frame_length) - frame = m_vertical_frame_num * m_horizontal_frame_num - 1; - else - frame = m_first_frame + (u16)(m_time / m_frame_length); - } - f32 tx0 = m_texpos.X + m_texsize.X * (frame % m_horizontal_frame_num); - f32 tx1 = m_texpos.X + m_texsize.X * (frame % m_horizontal_frame_num + 1); - f32 ty0 = m_texpos.Y + m_texsize.Y * (frame / m_horizontal_frame_num); - f32 ty1 = m_texpos.Y + m_texsize.Y * (frame / m_horizontal_frame_num + 1); + f32 tx0 = m_texpos.X; + f32 tx1 = m_texpos.X + m_texsize.X; + f32 ty0 = m_texpos.Y; + f32 ty1 = m_texpos.Y + m_texsize.Y; m_vertices[0] = video::S3DVertex(-m_size/2,-m_size/2,0, 0,0,0, c, tx0, ty1); @@ -266,16 +214,7 @@ ParticleSpawner::ParticleSpawner(IGameDef* gamedef, scene::ISceneManager *smgr, v3f minpos, v3f maxpos, v3f minvel, v3f maxvel, v3f minacc, v3f maxacc, float minexptime, float maxexptime, float minsize, float maxsize, bool collisiondetection, bool collision_removal, u16 attached_id, bool vertical, - video::ITexture *texture, u32 id, - u32 material_type_param, - u16 vertical_frame_num, - u16 horizontal_frame_num, - u16 min_first_frame, - u16 max_first_frame, - float frame_length, - bool loop_animation, - u8 glow, - ParticleManager *p_manager) : + video::ITexture *texture, u32 id, ParticleManager *p_manager) : m_particlemanager(p_manager) { m_gamedef = gamedef; @@ -299,14 +238,6 @@ ParticleSpawner::ParticleSpawner(IGameDef* gamedef, scene::ISceneManager *smgr, m_vertical = vertical; m_texture = texture; m_time = 0; - m_vertical_frame_num = vertical_frame_num; - m_horizontal_frame_num = horizontal_frame_num; - m_min_first_frame = min_first_frame; - m_max_first_frame = max_first_frame; - m_frame_length = frame_length; - m_loop_animation = loop_animation; - m_material_type_param = material_type_param; - m_glow = glow; for (u16 i = 0; i<=m_amount; i++) { @@ -320,6 +251,7 @@ ParticleSpawner::~ParticleSpawner() {} void ParticleSpawner::step(float dtime, ClientEnvironment* env) { m_time += dtime; + bool unloaded = false; v3f attached_offset = v3f(0,0,0); if (m_attached_id != 0) { @@ -353,10 +285,7 @@ void ParticleSpawner::step(float dtime, ClientEnvironment* env) float size = rand()/(float)RAND_MAX *(m_maxsize-m_minsize) +m_minsize; - u16 first_frame = m_min_first_frame + - rand() % - (m_max_first_frame - - m_min_first_frame + 1); + Particle* toadd = new Particle( m_gamedef, m_smgr, @@ -372,14 +301,7 @@ void ParticleSpawner::step(float dtime, ClientEnvironment* env) m_vertical, m_texture, v2f(0.0, 0.0), - v2f(1.0, 1.0), - m_material_type_param, - m_vertical_frame_num, - m_horizontal_frame_num, - first_frame, - m_frame_length, - m_loop_animation, - m_glow); + v2f(1.0, 1.0)); m_particlemanager->addParticle(toadd); } i = m_spawntimes.erase(i); @@ -409,10 +331,7 @@ void ParticleSpawner::step(float dtime, ClientEnvironment* env) float size = rand()/(float)RAND_MAX *(m_maxsize-m_minsize) +m_minsize; - u16 first_frame = m_min_first_frame + - rand() % - (m_max_first_frame - - m_min_first_frame + 1); + Particle* toadd = new Particle( m_gamedef, m_smgr, @@ -428,14 +347,7 @@ void ParticleSpawner::step(float dtime, ClientEnvironment* env) m_vertical, m_texture, v2f(0.0, 0.0), - v2f(1.0, 1.0), - m_material_type_param, - m_vertical_frame_num, - m_horizontal_frame_num, - first_frame, - m_frame_length, - m_loop_animation, - m_glow); + v2f(1.0, 1.0)); m_particlemanager->addParticle(toadd); } } @@ -547,39 +459,6 @@ void ParticleManager::handleParticleEvent(ClientEvent *event, IGameDef *gamedef, video::ITexture *texture = gamedef->tsrc()->getTextureForMesh(*(event->add_particlespawner.texture)); - float frame_length = -1; - u16 vertical_frame_num = 1; - u16 horizontal_frame_num = 1; - u32 material_type_param = - check_material_type_param(event->add_particlespawner.material_type_param); - - switch (event->add_particlespawner.animation_type) { - case AT_NONE: - break; - case AT_VERTICAL_FRAMES: { - v2u32 size = texture->getOriginalSize(); - int frame_height = (float)size.X / - (float)event->add_particlespawner.vertical_frame_num * - (float)event->add_particlespawner.horizontal_frame_num; - vertical_frame_num = size.Y / frame_height; - frame_length = - event->add_particlespawner.frame_length / - vertical_frame_num; - break; - } - case AT_2D_ANIMATION_SHEET: { - vertical_frame_num = - event->add_particlespawner.vertical_frame_num; - horizontal_frame_num = - event->add_particlespawner.horizontal_frame_num; - frame_length = - event->add_particlespawner.frame_length; - break; - } - default: - break; - } - ParticleSpawner* toadd = new ParticleSpawner(gamedef, smgr, player, event->add_particlespawner.amount, event->add_particlespawner.spawntime, @@ -599,14 +478,6 @@ void ParticleManager::handleParticleEvent(ClientEvent *event, IGameDef *gamedef, event->add_particlespawner.vertical, texture, event->add_particlespawner.id, - material_type_param, - vertical_frame_num, - horizontal_frame_num, - event->add_particlespawner.min_first_frame, - event->add_particlespawner.max_first_frame, - frame_length, - event->add_particlespawner.loop_animation, - event->add_particlespawner.glow, this); /* delete allocated content of event */ @@ -631,39 +502,6 @@ void ParticleManager::handleParticleEvent(ClientEvent *event, IGameDef *gamedef, video::ITexture *texture = gamedef->tsrc()->getTextureForMesh(*(event->spawn_particle.texture)); - float frame_length = -1; - u16 vertical_frame_num = 1; - u16 horizontal_frame_num = 1; - u32 material_type_param = - check_material_type_param(event->spawn_particle.material_type_param); - - switch (event->spawn_particle.animation_type) { - case AT_NONE: - break; - case AT_VERTICAL_FRAMES: { - v2u32 size = texture->getOriginalSize(); - int frame_height = (float)size.X / - (float)event->spawn_particle.vertical_frame_num * - (float)event->spawn_particle.horizontal_frame_num; - vertical_frame_num = size.Y / frame_height; - frame_length = - event->spawn_particle.frame_length / - vertical_frame_num; - break; - } - case AT_2D_ANIMATION_SHEET: { - vertical_frame_num = - event->spawn_particle.vertical_frame_num; - horizontal_frame_num = - event->spawn_particle.horizontal_frame_num; - frame_length = - event->spawn_particle.frame_length; - break; - } - default: - break; - } - Particle* toadd = new Particle(gamedef, smgr, player, m_env, *event->spawn_particle.pos, *event->spawn_particle.vel, @@ -675,21 +513,13 @@ void ParticleManager::handleParticleEvent(ClientEvent *event, IGameDef *gamedef, event->spawn_particle.vertical, texture, v2f(0.0, 0.0), - v2f(1.0, 1.0), - material_type_param, - vertical_frame_num, - horizontal_frame_num, - event->spawn_particle.first_frame, - frame_length, - event->spawn_particle.loop_animation, - event->spawn_particle.glow); + v2f(1.0, 1.0)); addParticle(toadd); delete event->spawn_particle.pos; delete event->spawn_particle.vel; delete event->spawn_particle.acc; - delete event->spawn_particle.texture; break; } @@ -758,8 +588,7 @@ void ParticleManager::addNodeParticle(IGameDef* gamedef, scene::ISceneManager* s false, texture, texpos, - texsize, - 0, 1, 1, 0, -1, true, 0); + texsize); addParticle(toadd); } diff --git a/src/particles.h b/src/particles.h index 6d8c6139f..eb8c6665d 100644 --- a/src/particles.h +++ b/src/particles.h @@ -50,14 +50,7 @@ class Particle : public scene::ISceneNode bool vertical, video::ITexture *texture, v2f texpos, - v2f texsize, - u32 material_type_param, - u16 vertical_frame_num, - u16 horizontal_frame_num, - u16 first_frame, - float frame_length, - bool loop_animation, - u8 glow + v2f texsize ); ~Particle(); @@ -109,12 +102,6 @@ private: bool m_collision_removal; bool m_vertical; v3s16 m_camera_offset; - u16 m_vertical_frame_num; - u16 m_horizontal_frame_num; - u16 m_first_frame; - float m_frame_length; - bool m_loop_animation; - u8 m_glow; }; class ParticleSpawner @@ -136,15 +123,8 @@ class ParticleSpawner bool vertical, video::ITexture *texture, u32 id, - u32 material_type_param, - u16 vertical_frame_num, - u16 horizontal_frame_num, - u16 min_first_frame, - u16 max_first_frame, - float frame_length, - bool loop_animation, - u8 glow, ParticleManager* p_manager); + ~ParticleSpawner(); void step(float dtime, ClientEnvironment *env); @@ -176,14 +156,6 @@ class ParticleSpawner bool m_collision_removal; bool m_vertical; u16 m_attached_id; - u32 m_material_type_param; - u16 m_vertical_frame_num; - u16 m_horizontal_frame_num; - u16 m_min_first_frame; - u16 m_max_first_frame; - float m_frame_length; - bool m_loop_animation; - u8 m_glow; }; /** diff --git a/src/script/common/c_content.cpp b/src/script/common/c_content.cpp index d4a25b68b..f20a65903 100644 --- a/src/script/common/c_content.cpp +++ b/src/script/common/c_content.cpp @@ -35,11 +35,10 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "noise.h" #include -struct EnumString es_AnimationType[] = +struct EnumString es_TileAnimationType[] = { - {AT_NONE, "none"}, - {AT_VERTICAL_FRAMES, "vertical_frames"}, - {AT_2D_ANIMATION_SHEET, "2d_animation_sheet"}, + {TAT_NONE, "none"}, + {TAT_VERTICAL_FRAMES, "vertical_frames"}, {0, NULL}, }; @@ -336,9 +335,9 @@ TileDef read_tiledef(lua_State *L, int index, u8 drawtype) lua_getfield(L, index, "animation"); if(lua_istable(L, -1)){ // {type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0} - tiledef.animation.type = (AnimationType) - getenumfield(L, -1, "type", es_AnimationType, - AT_NONE); + tiledef.animation.type = (TileAnimationType) + getenumfield(L, -1, "type", es_TileAnimationType, + TAT_NONE); tiledef.animation.aspect_w = getintfield_default(L, -1, "aspect_w", 16); tiledef.animation.aspect_h = diff --git a/src/script/common/c_content.h b/src/script/common/c_content.h index 32fdb4f04..2a2228b6d 100644 --- a/src/script/common/c_content.h +++ b/src/script/common/c_content.h @@ -159,6 +159,6 @@ bool push_json_value (lua_State *L, void read_json_value (lua_State *L, Json::Value &root, int index, u8 recursion = 0); -extern struct EnumString es_AnimationType[]; +extern struct EnumString es_TileAnimationType[]; #endif /* C_CONTENT_H_ */ diff --git a/src/script/common/c_converter.cpp b/src/script/common/c_converter.cpp index cfb5e26db..f36298915 100644 --- a/src/script/common/c_converter.cpp +++ b/src/script/common/c_converter.cpp @@ -513,28 +513,6 @@ int getintfield_default(lua_State *L, int table, return result; } -int check_material_type_param(lua_State *L, int table, - const char *fieldname, int default_) -{ - int material_type_param = - getintfield_default(L, table, fieldname, default_); - u32 alphaSource = (material_type_param & 0x0000F000) >> 12; - u32 modulo = (material_type_param & 0x00000F00) >> 8; - u32 srcFact = (material_type_param & 0x000000F0) >> 4; - u32 dstFact = material_type_param & 0x0000000F; - if (alphaSource <= 3 && modulo <= 4 && srcFact <= 10 && dstFact <= 10) { - return material_type_param; - } else { - std::ostringstream error_text; - error_text << "Incorrect material_type_param value "; - error_text << "for particle or particle spawner."; - error_text << std::endl; - throw LuaError(error_text.str()); - return 0; - } -} - - float getfloatfield_default(lua_State *L, int table, const char *fieldname, float default_) { diff --git a/src/script/common/c_converter.h b/src/script/common/c_converter.h index 71ac735c1..a5fbee765 100644 --- a/src/script/common/c_converter.h +++ b/src/script/common/c_converter.h @@ -45,8 +45,6 @@ float getfloatfield_default(lua_State *L, int table, const char *fieldname, float default_); int getintfield_default (lua_State *L, int table, const char *fieldname, int default_); -int check_material_type_param(lua_State *L, int table, - const char *fieldname, int default_); bool getstringfield(lua_State *L, int table, const char *fieldname, std::string &result); diff --git a/src/script/lua_api/l_particles.cpp b/src/script/lua_api/l_particles.cpp index b0a57ce6d..667ac7272 100644 --- a/src/script/lua_api/l_particles.cpp +++ b/src/script/lua_api/l_particles.cpp @@ -21,7 +21,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "lua_api/l_object.h" #include "lua_api/l_internal.h" #include "common/c_converter.h" -#include "common/c_content.h" #include "server.h" #include "particles.h" @@ -35,9 +34,6 @@ with this program; if not, write to the Free Software Foundation, Inc., // collision_removal = bool // vertical = bool // texture = e.g."default_wood.png" -// material_type_param = num -// animation = animation definition -// glow = indexed color or color string int ModApiParticles::l_add_particle(lua_State *L) { MAP_LOCK_REQUIRED; @@ -48,24 +44,13 @@ int ModApiParticles::l_add_particle(lua_State *L) float expirationtime, size; expirationtime = size = 1; - float frame_or_loop_length = -1; - - AnimationType animation_type = AT_NONE; - - u16 vertical_frame_num_or_aspect = 1; - u16 horizontal_frame_num_or_aspect = 1; - u16 first_frame = 0; bool collisiondetection, vertical, collision_removal; collisiondetection = vertical = collision_removal = false; - bool loop_animation = true; std::string texture = ""; std::string playername = ""; - u32 material_type_param = 0; - u8 glow = 0; - if (lua_gettop(L) > 1) // deprecated { log_deprecated(L, "Deprecated add_particle call with individual parameters instead of definition"); @@ -109,61 +94,8 @@ int ModApiParticles::l_add_particle(lua_State *L) acc = lua_istable(L, -1) ? check_v3f(L, -1) : acc; lua_pop(L, 1); - expirationtime = getfloatfield_default(L, 1, "expirationtime", 1); + expirationtime = getfloatfield_default(L, 1, "expirationtime", 1); size = getfloatfield_default(L, 1, "size", 1); - - lua_getfield(L, 1, "animation"); - if (lua_istable(L, -1)) { - animation_type = (AnimationType) - getenumfield(L, -1, "type", es_AnimationType, - AT_NONE); - } - switch (animation_type) { - case AT_NONE: - break; - case AT_2D_ANIMATION_SHEET: - frame_or_loop_length = - getfloatfield_default(L, -1, "frame_length", -1); - vertical_frame_num_or_aspect = - getintfield_default(L, -1, "vertical_frame_num", 1); - horizontal_frame_num_or_aspect = - getintfield_default(L, -1, "horizontal_frame_num", 1); - first_frame = - getintfield_default(L, -1, "first_frame", 0); - loop_animation = - getboolfield_default(L, -1, "loop_animation", true); - break; - case AT_VERTICAL_FRAMES: - frame_or_loop_length = - getfloatfield_default(L, -1, "length", -1); - vertical_frame_num_or_aspect = - getintfield_default(L, -1, "aspect_w", 1); - horizontal_frame_num_or_aspect = - getintfield_default(L, -1, "aspect_h", 1); - first_frame = - getintfield_default(L, -1, "first_frame", 0); - loop_animation = - getboolfield_default(L, -1, "loop_animation", true); - break; - default: - break; - } - lua_pop(L, 1); - - if (animation_type == AT_2D_ANIMATION_SHEET && - first_frame >= vertical_frame_num_or_aspect * - horizontal_frame_num_or_aspect) { - std::ostringstream error_text; - error_text << "first_frame should be lower, than " - << "vertical_frame_num * horizontal_frame_num. " - << "Got first_frame=" << first_frame - << ", vertical_frame_num=" - << vertical_frame_num_or_aspect - << " and horizontal_frame_num=" - << horizontal_frame_num_or_aspect << std::endl; - throw LuaError(error_text.str()); - } - collisiondetection = getboolfield_default(L, 1, "collisiondetection", collisiondetection); collision_removal = getboolfield_default(L, 1, @@ -171,16 +103,9 @@ int ModApiParticles::l_add_particle(lua_State *L) vertical = getboolfield_default(L, 1, "vertical", vertical); texture = getstringfield_default(L, 1, "texture", ""); playername = getstringfield_default(L, 1, "playername", ""); - material_type_param = check_material_type_param(L, 1, "material_type_param", 0); - glow = getintfield_default (L, 1, "glow", 0); } - getServer(L)->spawnParticle(playername, pos, vel, acc, expirationtime, - size, collisiondetection, collision_removal, vertical, - texture, material_type_param, - animation_type, - vertical_frame_num_or_aspect, - horizontal_frame_num_or_aspect, - first_frame, frame_or_loop_length, loop_animation, glow); + getServer(L)->spawnParticle(playername, pos, vel, acc, expirationtime, size, + collisiondetection, collision_removal, vertical, texture); return 1; } @@ -202,33 +127,21 @@ int ModApiParticles::l_add_particle(lua_State *L) // collision_removal = bool // vertical = bool // texture = e.g."default_wood.png" -// material_type_param = num -// animation = animation definition -// glow = indexed color or color string int ModApiParticles::l_add_particlespawner(lua_State *L) { MAP_LOCK_REQUIRED; // Get parameters u16 amount = 1; - u16 vertical_frame_num_or_aspect = 1; - u16 horizontal_frame_num_or_aspect = 1; - u16 min_first_frame = 0; - u16 max_first_frame = 0; v3f minpos, maxpos, minvel, maxvel, minacc, maxacc; minpos= maxpos= minvel= maxvel= minacc= maxacc= v3f(0, 0, 0); float time, minexptime, maxexptime, minsize, maxsize; time= minexptime= maxexptime= minsize= maxsize= 1; - AnimationType animation_type = AT_NONE; - float frame_or_loop_length = -1; bool collisiondetection, vertical, collision_removal; collisiondetection = vertical = collision_removal = false; - bool loop_animation = true; ServerActiveObject *attached = NULL; std::string texture = ""; std::string playername = ""; - u32 material_type_param = 0; - u8 glow = 0; if (lua_gettop(L) > 1) //deprecated { @@ -283,65 +196,6 @@ int ModApiParticles::l_add_particlespawner(lua_State *L) maxexptime = getfloatfield_default(L, 1, "maxexptime", maxexptime); minsize = getfloatfield_default(L, 1, "minsize", minsize); maxsize = getfloatfield_default(L, 1, "maxsize", maxsize); - - - lua_getfield(L, 1, "animation"); - if (lua_istable(L, -1)) { - animation_type = (AnimationType) - getenumfield(L, -1, "type", es_AnimationType, - AT_NONE); - } - switch (animation_type) { - case AT_NONE: - break; - case AT_2D_ANIMATION_SHEET: - frame_or_loop_length = - getfloatfield_default(L, -1, "frame_length", -1); - vertical_frame_num_or_aspect = - getintfield_default(L, -1, "vertical_frame_num", 1); - horizontal_frame_num_or_aspect = - getintfield_default(L, -1, "horizontal_frame_num", 1); - min_first_frame = - getintfield_default(L, -1, "min_first_frame", 0); - max_first_frame = - getintfield_default(L, -1, "max_first_frame", 0); - loop_animation = - getboolfield_default(L, -1, "loop_animation", true); - break; - case AT_VERTICAL_FRAMES: - frame_or_loop_length = - getfloatfield_default(L, -1, "length", -1); - vertical_frame_num_or_aspect = - getintfield_default(L, -1, "aspect_w", 1); - horizontal_frame_num_or_aspect = - getintfield_default(L, -1, "aspect_h", 1); - min_first_frame = - getintfield_default(L, -1, "min_first_frame", 0); - max_first_frame = - getintfield_default(L, -1, "max_first_frame", 0); - loop_animation = - getboolfield_default(L, -1, "loop_animation", true); - break; - default: - break; - } - lua_pop(L, 1); - - if (animation_type == AT_2D_ANIMATION_SHEET && - max_first_frame >= vertical_frame_num_or_aspect * - horizontal_frame_num_or_aspect) { - std::ostringstream error_text; - error_text << "max_first_frame should be lower, than " - << "vertical_frame_num * horizontal_frame_num. " - << "Got max_first_frame=" - << max_first_frame - << ", vertical_frame_num=" - << vertical_frame_num_or_aspect - << " and horizontal_frame_num=" - << horizontal_frame_num_or_aspect << std::endl; - throw LuaError(error_text.str()); - } - collisiondetection = getboolfield_default(L, 1, "collisiondetection", collisiondetection); collision_removal = getboolfield_default(L, 1, @@ -357,8 +211,6 @@ int ModApiParticles::l_add_particlespawner(lua_State *L) vertical = getboolfield_default(L, 1, "vertical", vertical); texture = getstringfield_default(L, 1, "texture", ""); playername = getstringfield_default(L, 1, "playername", ""); - material_type_param = check_material_type_param(L, 1, "material_type_param", 0); - glow = getintfield_default(L, 1, "glow", 0); } u32 id = getServer(L)->addParticleSpawner(amount, time, @@ -371,17 +223,9 @@ int ModApiParticles::l_add_particlespawner(lua_State *L) collision_removal, attached, vertical, - texture, - playername, - material_type_param, - animation_type, - vertical_frame_num_or_aspect, - horizontal_frame_num_or_aspect, - min_first_frame, max_first_frame, - frame_or_loop_length, - loop_animation, - glow); + texture, playername); lua_pushnumber(L, id); + return 1; } diff --git a/src/server.cpp b/src/server.cpp index cef57be88..48331e4f8 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -1658,11 +1658,7 @@ void Server::SendShowFormspecMessage(u16 peer_id, const std::string &formspec, void Server::SendSpawnParticle(u16 peer_id, v3f pos, v3f velocity, v3f acceleration, float expirationtime, float size, bool collisiondetection, bool collision_removal, - bool vertical, const std::string &texture, - u32 material_type_param, AnimationType animation_type, - u16 vertical_frame_num, u16 horizontal_frame_num, u16 first_frame, - float frame_length, bool loop_animation, - u8 glow) + bool vertical, const std::string &texture) { DSTACK(FUNCTION_NAME); @@ -1674,12 +1670,6 @@ void Server::SendSpawnParticle(u16 peer_id, v3f pos, v3f velocity, v3f accelerat pkt << vertical; pkt << collision_removal; - pkt << material_type_param - << (u8)animation_type - << vertical_frame_num - << horizontal_frame_num << first_frame - << frame_length << loop_animation << glow; - if (peer_id != PEER_ID_INEXISTENT) { Send(&pkt); } @@ -1692,10 +1682,7 @@ void Server::SendSpawnParticle(u16 peer_id, v3f pos, v3f velocity, v3f accelerat void Server::SendAddParticleSpawner(u16 peer_id, u16 amount, float spawntime, v3f minpos, v3f maxpos, v3f minvel, v3f maxvel, v3f minacc, v3f maxacc, float minexptime, float maxexptime, float minsize, float maxsize, bool collisiondetection, bool collision_removal, - u16 attached_id, bool vertical, const std::string &texture, u32 id, - u32 material_type_param, AnimationType animation_type, u16 vertical_frame_num, u16 horizontal_frame_num, - u16 min_first_frame, u16 max_first_frame, float frame_length, - bool loop_animation, u8 glow) + u16 attached_id, bool vertical, const std::string &texture, u32 id) { DSTACK(FUNCTION_NAME); @@ -1711,12 +1698,6 @@ void Server::SendAddParticleSpawner(u16 peer_id, u16 amount, float spawntime, v3 pkt << collision_removal; pkt << attached_id; - pkt << material_type_param - << (u8)animation_type - << vertical_frame_num << horizontal_frame_num - << min_first_frame << max_first_frame - << frame_length << loop_animation << glow; - if (peer_id != PEER_ID_INEXISTENT) { Send(&pkt); } @@ -3166,11 +3147,7 @@ void Server::spawnParticle(const std::string &playername, v3f pos, v3f velocity, v3f acceleration, float expirationtime, float size, bool collisiondetection, bool collision_removal, - bool vertical, const std::string &texture, - u32 material_type_param, AnimationType animation_type, - u16 vertical_frame_num, u16 horizontal_frame_num, u16 first_frame, - float frame_length, bool loop_animation, - u8 glow) + bool vertical, const std::string &texture) { // m_env will be NULL if the server is initializing if (!m_env) @@ -3186,11 +3163,7 @@ void Server::spawnParticle(const std::string &playername, v3f pos, SendSpawnParticle(peer_id, pos, velocity, acceleration, expirationtime, size, collisiondetection, - collision_removal, vertical, texture, - material_type_param, animation_type, - vertical_frame_num, horizontal_frame_num, - first_frame, frame_length, loop_animation, - glow); + collision_removal, vertical, texture); } u32 Server::addParticleSpawner(u16 amount, float spawntime, @@ -3198,9 +3171,7 @@ u32 Server::addParticleSpawner(u16 amount, float spawntime, float minexptime, float maxexptime, float minsize, float maxsize, bool collisiondetection, bool collision_removal, ServerActiveObject *attached, bool vertical, const std::string &texture, - const std::string &playername, u32 material_type_param, AnimationType animation_type, - u16 vertical_frame_num, u16 horizontal_frame_num, u16 min_first_frame, u16 max_first_frame, - float frame_length, bool loop_animation, u8 glow) + const std::string &playername) { // m_env will be NULL if the server is initializing if (!m_env) @@ -3226,10 +3197,7 @@ u32 Server::addParticleSpawner(u16 amount, float spawntime, minpos, maxpos, minvel, maxvel, minacc, maxacc, minexptime, maxexptime, minsize, maxsize, collisiondetection, collision_removal, attached_id, vertical, - texture, id, material_type_param, animation_type, - vertical_frame_num, horizontal_frame_num, - min_first_frame, max_first_frame, frame_length, loop_animation, - glow); + texture, id); return id; } diff --git a/src/server.h b/src/server.h index 9a8d22b2e..9e844e36c 100644 --- a/src/server.h +++ b/src/server.h @@ -26,7 +26,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "hud.h" #include "gamedef.h" #include "serialization.h" // For SER_FMT_VER_INVALID -#include "nodedef.h" // AnimationType #include "mods.h" #include "inventorymanager.h" #include "subgame.h" @@ -255,11 +254,7 @@ public: v3f pos, v3f velocity, v3f acceleration, float expirationtime, float size, bool collisiondetection, bool collision_removal, - bool vertical, const std::string &texture, - u32 material_type_param, AnimationType animation_type, - u16 vertical_frame_num, u16 horizontal_frame_num, u16 first_frame, - float frame_length, bool loop_animation, - u8 glow); + bool vertical, const std::string &texture); u32 addParticleSpawner(u16 amount, float spawntime, v3f minpos, v3f maxpos, @@ -270,12 +265,7 @@ public: bool collisiondetection, bool collision_removal, ServerActiveObject *attached, bool vertical, const std::string &texture, - const std::string &playername, - u32 material_type_param, AnimationType animation_type, - u16 vertical_frame_num, u16 horizontal_frame_num, - u16 min_first_frame, u16 max_first_frame, - float frame_length, bool loop_animation, - u8 glow); + const std::string &playername); void deleteParticleSpawner(const std::string &playername, u32 id); @@ -451,12 +441,7 @@ private: float minsize, float maxsize, bool collisiondetection, bool collision_removal, u16 attached_id, - bool vertical, const std::string &texture, u32 id, - u32 material_type_param, AnimationType animation_type, - u16 vertical_frame_num, u16 horizontal_frame_num, - u16 min_first_frame, u16 max_first_frame, - float frame_length, bool loop_animation, - u8 glow); + bool vertical, const std::string &texture, u32 id); void SendDeleteParticleSpawner(u16 peer_id, u32 id); @@ -465,11 +450,7 @@ private: v3f pos, v3f velocity, v3f acceleration, float expirationtime, float size, bool collisiondetection, bool collision_removal, - bool vertical, const std::string &texture, - u32 material_type_param, AnimationType animation_type, - u16 vertical_frame_num, u16 horizontal_frame_num, u16 first_frame, - float frame_length, bool loop_animation, - u8 glow); + bool vertical, const std::string &texture); u32 SendActiveObjectRemoveAdd(u16 peer_id, const std::string &datas); void SendActiveObjectMessages(u16 peer_id, const std::string &datas, bool reliable = true); -- cgit v1.2.3 From 785a9a6c1af424b0a46f334de7176c9e67341cfb Mon Sep 17 00:00:00 2001 From: TeTpaAka Date: Thu, 25 Jun 2015 13:06:49 +0200 Subject: Wieldhand: Allow overriding the hand --- doc/lua_api.txt | 7 +++++++ src/content_sao.cpp | 36 ++++++++++++++++++++++++++++++++++++ src/content_sao.h | 2 ++ src/game.cpp | 17 +++++++++++++++++ src/network/serverpackethandler.cpp | 5 +---- src/player.cpp | 1 + 6 files changed, 64 insertions(+), 4 deletions(-) (limited to 'src/network') diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 760a829d3..9da0fb4f9 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -1759,6 +1759,13 @@ Inventory locations * `"nodemeta:,,"`: Any node metadata * `"detached:"`: A detached inventory +Player Inventory lists +---------------------- +* `main`: list containing the default inventory +* `craft`: list containing the craft input +* `craftpreview`: list containing the craft output +* `hand`: list containing an override for the empty hand + `ColorString` ------------- `#RGB` defines a color in hexadecimal format. diff --git a/src/content_sao.cpp b/src/content_sao.cpp index 6caea5198..609673ed9 100644 --- a/src/content_sao.cpp +++ b/src/content_sao.cpp @@ -1341,6 +1341,42 @@ std::string PlayerSAO::getWieldList() const return "main"; } +ItemStack PlayerSAO::getWieldedItem() const +{ + const Inventory *inv = getInventory(); + ItemStack ret; + const InventoryList *mlist = inv->getList(getWieldList()); + if (mlist && getWieldIndex() < (s32)mlist->getSize()) + ret = mlist->getItem(getWieldIndex()); + if (ret.name.empty()) { + const InventoryList *hlist = inv->getList("hand"); + if (hlist) + ret = hlist->getItem(0); + } + return ret; +} + +bool PlayerSAO::setWieldedItem(const ItemStack &item) +{ + Inventory *inv = getInventory(); + if (inv) { + InventoryList *mlist = inv->getList(getWieldList()); + if (mlist) { + ItemStack olditem = mlist->getItem(getWieldIndex()); + if (olditem.name.empty()) { + InventoryList *hlist = inv->getList("hand"); + if (hlist) { + hlist->changeItem(0, item); + return true; + } + } + mlist->changeItem(getWieldIndex(), item); + return true; + } + } + return false; +} + int PlayerSAO::getWieldIndex() const { return m_wield_index; diff --git a/src/content_sao.h b/src/content_sao.h index f58c7dadb..c5b066f50 100644 --- a/src/content_sao.h +++ b/src/content_sao.h @@ -251,6 +251,8 @@ public: const Inventory* getInventory() const; InventoryLocation getInventoryLocation() const; std::string getWieldList() const; + ItemStack getWieldedItem() const; + bool setWieldedItem(const ItemStack &item); int getWieldIndex() const; void setWieldIndex(int i); diff --git a/src/game.cpp b/src/game.cpp index 671682348..e6d38d0a0 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -3684,6 +3684,12 @@ void Game::updateCamera(VolatileRunFlags *flags, u32 busy_time, if (mlist && client->getPlayerItem() < mlist->getSize()) playeritem = mlist->getItem(client->getPlayerItem()); } + if (playeritem.getDefinition(itemdef_manager).name.empty()) { // override the hand + InventoryList *hlist = local_inventory->getList("hand"); + if (hlist) + playeritem = hlist->getItem(0); + } + ToolCapabilities playeritem_toolcap = playeritem.getToolCapabilities(itemdef_manager); @@ -3768,6 +3774,11 @@ void Game::processPlayerInteraction(GameRunData *runData, playeritem = mlist->getItem(client->getPlayerItem()); } + if (playeritem.getDefinition(itemdef_manager).name.empty()) { // override the hand + InventoryList *hlist = local_inventory->getList("hand"); + if (hlist) + playeritem = hlist->getItem(0); + } const ItemDefinition &playeritem_def = playeritem.getDefinition(itemdef_manager); @@ -4321,8 +4332,14 @@ void Game::updateFrame(ProfilerGraph *graph, RunStats *stats, if (mlist && (client->getPlayerItem() < mlist->getSize())) { ItemStack item = mlist->getItem(client->getPlayerItem()); + if (item.getDefinition(itemdef_manager).name.empty()) { // override the hand + InventoryList *hlist = local_inventory->getList("hand"); + if (hlist) + item = hlist->getItem(0); + } camera->wield(item); } + runData->update_wielded_item_trigger = false; } diff --git a/src/network/serverpackethandler.cpp b/src/network/serverpackethandler.cpp index d56424b75..70eb0a828 100644 --- a/src/network/serverpackethandler.cpp +++ b/src/network/serverpackethandler.cpp @@ -1529,10 +1529,7 @@ void Server::handleCommand_Interact(NetworkPacket* pkt) m_script->on_cheat(playersao, "finished_unknown_dig"); } // Get player's wielded item - ItemStack playeritem; - InventoryList *mlist = playersao->getInventory()->getList("main"); - if (mlist != NULL) - playeritem = mlist->getItem(playersao->getWieldIndex()); + ItemStack playeritem = playersao->getWieldedItem(); ToolCapabilities playeritem_toolcap = playeritem.getToolCapabilities(m_itemdef); // Get diggability and expected digging time diff --git a/src/player.cpp b/src/player.cpp index 9c321d571..85bc639ec 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -40,6 +40,7 @@ Player::Player(const char *name, IItemDefManager *idef): inventory.clear(); inventory.addList("main", PLAYER_INVENTORY_SIZE); + inventory.addList("hand", 1); InventoryList *craft = inventory.addList("craft", 9); craft->setWidth(3); inventory.addList("craftpreview", 1); -- cgit v1.2.3 From 5dc61988788e44bc87e8c57c0beded97d4efdf05 Mon Sep 17 00:00:00 2001 From: lhofhansl Date: Wed, 30 Nov 2016 00:13:14 -0800 Subject: Optimize/adjust blocks/ActiveObjects sent at the server based on client settings. (#4811) Optimize/adjust blocks and active blocks sent at the server based on client settings. --- src/camera.cpp | 5 ++-- src/client.cpp | 52 ++++++++++++++++++++++++------------- src/clientiface.cpp | 15 ++++++++--- src/clientmap.h | 4 ++- src/content_sao.cpp | 18 +++++++++++++ src/content_sao.h | 6 +++++ src/localplayer.cpp | 2 ++ src/localplayer.h | 2 ++ src/network/networkprotocol.h | 2 ++ src/network/serverpackethandler.cpp | 13 ++++++++++ src/server.cpp | 8 ++++-- 11 files changed, 99 insertions(+), 28 deletions(-) (limited to 'src/network') diff --git a/src/camera.cpp b/src/camera.cpp index b86f218fe..43980db1c 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -484,13 +484,12 @@ void Camera::update(LocalPlayer* player, f32 frametime, f32 busytime, void Camera::updateViewingRange() { + f32 viewing_range = g_settings->getFloat("viewing_range"); + m_draw_control.wanted_range = viewing_range; if (m_draw_control.range_all) { m_cameranode->setFarValue(100000.0); return; } - - f32 viewing_range = g_settings->getFloat("viewing_range"); - m_draw_control.wanted_range = viewing_range; m_cameranode->setFarValue((viewing_range < 2000) ? 2000 * BS : viewing_range * BS); } diff --git a/src/client.cpp b/src/client.cpp index 3726f5bc4..5a3dc5df7 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -930,13 +930,16 @@ void Client::Send(NetworkPacket* pkt) } // Will fill up 12 + 12 + 4 + 4 + 4 bytes -void writePlayerPos(LocalPlayer *myplayer, NetworkPacket *pkt) +void writePlayerPos(LocalPlayer *myplayer, ClientMap *clientMap, NetworkPacket *pkt) { - v3f pf = myplayer->getPosition() * 100; - v3f sf = myplayer->getSpeed() * 100; - s32 pitch = myplayer->getPitch() * 100; - s32 yaw = myplayer->getYaw() * 100; - u32 keyPressed = myplayer->keyPressed; + v3f pf = myplayer->getPosition() * 100; + v3f sf = myplayer->getSpeed() * 100; + s32 pitch = myplayer->getPitch() * 100; + s32 yaw = myplayer->getYaw() * 100; + u32 keyPressed = myplayer->keyPressed; + // scaled by 80, so that pi can fit into a u8 + u8 fov = clientMap->getCameraFov() * 80; + u8 wanted_range = clientMap->getControl().wanted_range / MAP_BLOCKSIZE; v3s32 position(pf.X, pf.Y, pf.Z); v3s32 speed(sf.X, sf.Y, sf.Z); @@ -948,9 +951,11 @@ void writePlayerPos(LocalPlayer *myplayer, NetworkPacket *pkt) [12+12] s32 pitch*100 [12+12+4] s32 yaw*100 [12+12+4+4] u32 keyPressed + [12+12+4+4+1] u8 fov*80 + [12+12+4+4+4+1] u8 wanted_range / MAP_BLOCKSIZE */ - *pkt << position << speed << pitch << yaw << keyPressed; + *pkt << fov << wanted_range; } void Client::interact(u8 action, const PointedThing& pointed) @@ -992,7 +997,7 @@ void Client::interact(u8 action, const PointedThing& pointed) pkt.putLongString(tmp_os.str()); - writePlayerPos(myplayer, &pkt); + writePlayerPos(myplayer, &m_env.getClientMap(), &pkt); Send(&pkt); } @@ -1296,19 +1301,30 @@ void Client::sendPlayerPos() if(myplayer == NULL) return; + ClientMap &map = m_env.getClientMap(); + + u8 camera_fov = map.getCameraFov(); + u8 wanted_range = map.getControl().wanted_range; + // Save bandwidth by only updating position when something changed if(myplayer->last_position == myplayer->getPosition() && - myplayer->last_speed == myplayer->getSpeed() && - myplayer->last_pitch == myplayer->getPitch() && - myplayer->last_yaw == myplayer->getYaw() && - myplayer->last_keyPressed == myplayer->keyPressed) + myplayer->last_speed == myplayer->getSpeed() && + myplayer->last_pitch == myplayer->getPitch() && + myplayer->last_yaw == myplayer->getYaw() && + myplayer->last_keyPressed == myplayer->keyPressed && + myplayer->last_camera_fov == camera_fov && + myplayer->last_wanted_range == wanted_range) return; - myplayer->last_position = myplayer->getPosition(); - myplayer->last_speed = myplayer->getSpeed(); - myplayer->last_pitch = myplayer->getPitch(); - myplayer->last_yaw = myplayer->getYaw(); - myplayer->last_keyPressed = myplayer->keyPressed; + myplayer->last_position = myplayer->getPosition(); + myplayer->last_speed = myplayer->getSpeed(); + myplayer->last_pitch = myplayer->getPitch(); + myplayer->last_yaw = myplayer->getYaw(); + myplayer->last_keyPressed = myplayer->keyPressed; + myplayer->last_camera_fov = camera_fov; + myplayer->last_wanted_range = wanted_range; + + //infostream << "Sending Player Position information" << std::endl; u16 our_peer_id; { @@ -1324,7 +1340,7 @@ void Client::sendPlayerPos() NetworkPacket pkt(TOSERVER_PLAYERPOS, 12 + 12 + 4 + 4 + 4); - writePlayerPos(myplayer, &pkt); + writePlayerPos(myplayer, &map, &pkt); Send(&pkt); } diff --git a/src/clientiface.cpp b/src/clientiface.cpp index bdc16f31c..abe878ecc 100644 --- a/src/clientiface.cpp +++ b/src/clientiface.cpp @@ -173,12 +173,20 @@ void RemoteClient::GetNextBlocks ( */ s32 new_nearest_unsent_d = -1; - const s16 full_d_max = g_settings->getS16("max_block_send_distance"); - const s16 d_opt = g_settings->getS16("block_send_optimize_distance"); + // get view range and camera fov from the client + s16 wanted_range = sao->getWantedRange(); + float camera_fov = sao->getFov(); + // if FOV, wanted_range are not available (old client), fall back to old default + if (wanted_range <= 0) wanted_range = 1000; + if (camera_fov <= 0) camera_fov = (72.0*M_PI/180) * 4./3.; + + const s16 full_d_max = MYMIN(g_settings->getS16("max_block_send_distance"), wanted_range); + const s16 d_opt = MYMIN(g_settings->getS16("block_send_optimize_distance"), wanted_range); const s16 d_blocks_in_sight = full_d_max * BS * MAP_BLOCKSIZE; + //infostream << "Fov from client " << camera_fov << " full_d_max " << full_d_max << std::endl; s16 d_max = full_d_max; - s16 d_max_gen = g_settings->getS16("max_block_generate_distance"); + s16 d_max_gen = MYMIN(g_settings->getS16("max_block_generate_distance"), wanted_range); // Don't loop very much at a time s16 max_d_increment_at_time = 2; @@ -242,7 +250,6 @@ void RemoteClient::GetNextBlocks ( FOV setting. The default of 72 degrees is fine. */ - float camera_fov = (72.0*M_PI/180) * 4./3.; if(isBlockInSight(p, camera_pos, camera_dir, camera_fov, d_blocks_in_sight) == false) { continue; diff --git a/src/clientmap.h b/src/clientmap.h index 8855eecf6..cb686ff33 100644 --- a/src/clientmap.h +++ b/src/clientmap.h @@ -138,7 +138,9 @@ public: { return (m_last_drawn_sectors.find(p) != m_last_drawn_sectors.end()); } - + + const MapDrawControl & getControl() const { return m_control; } + f32 getCameraFov() const { return m_camera_fov; } private: Client *m_client; diff --git a/src/content_sao.cpp b/src/content_sao.cpp index 609673ed9..77ab51a02 100644 --- a/src/content_sao.cpp +++ b/src/content_sao.cpp @@ -781,6 +781,8 @@ PlayerSAO::PlayerSAO(ServerEnvironment *env_, u16 peer_id_, bool is_singleplayer m_attachment_sent(false), m_breath(PLAYER_MAX_BREATH), m_pitch(0), + m_fov(0), + m_wanted_range(0), // public m_physics_override_speed(1), m_physics_override_jump(1), @@ -1099,6 +1101,22 @@ void PlayerSAO::setYaw(const float yaw) UnitSAO::setYaw(yaw); } +void PlayerSAO::setFov(const float fov) +{ + if (m_player && fov != m_fov) + m_player->setDirty(true); + + m_fov = fov; +} + +void PlayerSAO::setWantedRange(const s16 range) +{ + if (m_player && range != m_wanted_range) + m_player->setDirty(true); + + m_wanted_range = range; +} + void PlayerSAO::setYawAndSend(const float yaw) { setYaw(yaw); diff --git a/src/content_sao.h b/src/content_sao.h index c5b066f50..86255183d 100644 --- a/src/content_sao.h +++ b/src/content_sao.h @@ -214,6 +214,10 @@ public: f32 getRadPitch() const { return m_pitch * core::DEGTORAD; } // Deprecated f32 getRadPitchDep() const { return -1.0 * m_pitch * core::DEGTORAD; } + void setFov(const float pitch); + f32 getFov() const { return m_fov; } + void setWantedRange(const s16 range); + s16 getWantedRange() const { return m_wanted_range; } /* Interaction interface @@ -364,6 +368,8 @@ private: bool m_attachment_sent; u16 m_breath; f32 m_pitch; + f32 m_fov; + s16 m_wanted_range; public: float m_physics_override_speed; float m_physics_override_jump; diff --git a/src/localplayer.cpp b/src/localplayer.cpp index 71efb2343..4d0ca0600 100644 --- a/src/localplayer.cpp +++ b/src/localplayer.cpp @@ -56,6 +56,8 @@ LocalPlayer::LocalPlayer(Client *gamedef, const char *name): last_pitch(0), last_yaw(0), last_keyPressed(0), + last_camera_fov(0), + last_wanted_range(0), camera_impact(0.f), last_animation(NO_ANIM), hotbar_image(""), diff --git a/src/localplayer.h b/src/localplayer.h index 749f8f8ce..7a1cb7466 100644 --- a/src/localplayer.h +++ b/src/localplayer.h @@ -75,6 +75,8 @@ public: float last_pitch; float last_yaw; unsigned int last_keyPressed; + u8 last_camera_fov; + u8 last_wanted_range; float camera_impact; diff --git a/src/network/networkprotocol.h b/src/network/networkprotocol.h index e3fcae0c6..c9919e1c4 100644 --- a/src/network/networkprotocol.h +++ b/src/network/networkprotocol.h @@ -651,6 +651,8 @@ enum ToServerCommand [2+12+12] s32 pitch*100 [2+12+12+4] s32 yaw*100 [2+12+12+4+4] u32 keyPressed + [2+12+12+4+4+1] u8 fov*80 + [2+12+12+4+4+4+1] u8 wanted_range / MAP_BLOCKSIZE */ TOSERVER_GOTBLOCKS = 0x24, diff --git a/src/network/serverpackethandler.cpp b/src/network/serverpackethandler.cpp index 70eb0a828..5e50bb865 100644 --- a/src/network/serverpackethandler.cpp +++ b/src/network/serverpackethandler.cpp @@ -782,6 +782,7 @@ void Server::process_PlayerPos(RemotePlayer *player, PlayerSAO *playersao, v3s32 ps, ss; s32 f32pitch, f32yaw; + u8 f32fov; *pkt >> ps; *pkt >> ss; @@ -792,8 +793,18 @@ void Server::process_PlayerPos(RemotePlayer *player, PlayerSAO *playersao, f32 yaw = (f32)f32yaw / 100.0; u32 keyPressed = 0; + // default behavior (in case an old client doesn't send these) + f32 fov = (72.0*M_PI/180) * 4./3.; + u8 wanted_range = 0; + if (pkt->getRemainingBytes() >= 4) *pkt >> keyPressed; + if (pkt->getRemainingBytes() >= 1) { + *pkt >> f32fov; + fov = (f32)f32fov / 80.0; + } + if (pkt->getRemainingBytes() >= 1) + *pkt >> wanted_range; v3f position((f32)ps.X / 100.0, (f32)ps.Y / 100.0, (f32)ps.Z / 100.0); v3f speed((f32)ss.X / 100.0, (f32)ss.Y / 100.0, (f32)ss.Z / 100.0); @@ -805,6 +816,8 @@ void Server::process_PlayerPos(RemotePlayer *player, PlayerSAO *playersao, player->setSpeed(speed); playersao->setPitch(pitch); playersao->setYaw(yaw); + playersao->setFov(fov); + playersao->setWantedRange(wanted_range); player->keyPressed = keyPressed; player->control.up = (keyPressed & 1); player->control.down = (keyPressed & 2); diff --git a/src/server.cpp b/src/server.cpp index fe67ac96e..c9d5c7129 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -705,11 +705,15 @@ void Server::AsyncRunStep(bool initial_step) if (playersao == NULL) continue; + s16 my_radius = MYMIN(radius, playersao->getWantedRange() * MAP_BLOCKSIZE); + if (my_radius <= 0) my_radius = radius; + //infostream << "Server: Active Radius " << my_radius << std::endl; + std::queue removed_objects; std::queue added_objects; - m_env->getRemovedActiveObjects(playersao, radius, player_radius, + m_env->getRemovedActiveObjects(playersao, my_radius, player_radius, client->m_known_objects, removed_objects); - m_env->getAddedActiveObjects(playersao, radius, player_radius, + m_env->getAddedActiveObjects(playersao, my_radius, player_radius, client->m_known_objects, added_objects); // Ignore if nothing happened -- cgit v1.2.3 From 8a7dc838a8c1f8f2a5e9b710a8ee27d4d00715f9 Mon Sep 17 00:00:00 2001 From: Lars Hofhansl Date: Wed, 30 Nov 2016 21:42:22 -0800 Subject: Optimize block sent: Fix rendering issue --- src/client.cpp | 4 ++-- src/clientiface.cpp | 2 +- src/network/serverpackethandler.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src/network') diff --git a/src/client.cpp b/src/client.cpp index 5a3dc5df7..e9d273c69 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -951,7 +951,7 @@ void writePlayerPos(LocalPlayer *myplayer, ClientMap *clientMap, NetworkPacket * [12+12] s32 pitch*100 [12+12+4] s32 yaw*100 [12+12+4+4] u32 keyPressed - [12+12+4+4+1] u8 fov*80 + [12+12+4+4+4] u8 fov*80 [12+12+4+4+4+1] u8 wanted_range / MAP_BLOCKSIZE */ *pkt << position << speed << pitch << yaw << keyPressed; @@ -1338,7 +1338,7 @@ void Client::sendPlayerPos() assert(myplayer->peer_id == our_peer_id); - NetworkPacket pkt(TOSERVER_PLAYERPOS, 12 + 12 + 4 + 4 + 4); + NetworkPacket pkt(TOSERVER_PLAYERPOS, 12 + 12 + 4 + 4 + 4 + 1 + 1); writePlayerPos(myplayer, &map, &pkt); diff --git a/src/clientiface.cpp b/src/clientiface.cpp index abe878ecc..0390cf0ff 100644 --- a/src/clientiface.cpp +++ b/src/clientiface.cpp @@ -357,7 +357,7 @@ queue_full_break: } else if(nearest_emergefull_d != -1){ new_nearest_unsent_d = nearest_emergefull_d; } else { - if(d > g_settings->getS16("max_block_send_distance")){ + if(d > full_d_max){ new_nearest_unsent_d = 0; m_nothing_to_send_pause_timer = 2.0; } else { diff --git a/src/network/serverpackethandler.cpp b/src/network/serverpackethandler.cpp index 5e50bb865..dca9aabc4 100644 --- a/src/network/serverpackethandler.cpp +++ b/src/network/serverpackethandler.cpp @@ -794,7 +794,7 @@ void Server::process_PlayerPos(RemotePlayer *player, PlayerSAO *playersao, u32 keyPressed = 0; // default behavior (in case an old client doesn't send these) - f32 fov = (72.0*M_PI/180) * 4./3.; + f32 fov = 0; u8 wanted_range = 0; if (pkt->getRemainingBytes() >= 4) -- cgit v1.2.3 From 60772071e9b63c24a939078c706b713f46bf3279 Mon Sep 17 00:00:00 2001 From: Rogier-5 Date: Sun, 11 Dec 2016 19:49:49 +0100 Subject: Fix computation of viewing range (in blocks) sent to server (#4882) Fixes #4878 Also remove an artificial viewing range reduction that (presumably) was added to compensate for miscomputed viewing ranges, and that doesn't seem to be needed any more (thanks to lhofhansl). --- src/client.cpp | 5 +++-- src/game.cpp | 2 +- src/network/networkprotocol.h | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) (limited to 'src/network') diff --git a/src/client.cpp b/src/client.cpp index e9d273c69..7e88e5562 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -20,6 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include #include +#include #include #include "threading/mutex_auto_lock.h" #include "util/auth.h" @@ -939,7 +940,7 @@ void writePlayerPos(LocalPlayer *myplayer, ClientMap *clientMap, NetworkPacket * u32 keyPressed = myplayer->keyPressed; // scaled by 80, so that pi can fit into a u8 u8 fov = clientMap->getCameraFov() * 80; - u8 wanted_range = clientMap->getControl().wanted_range / MAP_BLOCKSIZE; + u8 wanted_range = std::ceil(clientMap->getControl().wanted_range / MAP_BLOCKSIZE); v3s32 position(pf.X, pf.Y, pf.Z); v3s32 speed(sf.X, sf.Y, sf.Z); @@ -952,7 +953,7 @@ void writePlayerPos(LocalPlayer *myplayer, ClientMap *clientMap, NetworkPacket * [12+12+4] s32 yaw*100 [12+12+4+4] u32 keyPressed [12+12+4+4+4] u8 fov*80 - [12+12+4+4+4+1] u8 wanted_range / MAP_BLOCKSIZE + [12+12+4+4+4+1] u8 ceil(wanted_range / MAP_BLOCKSIZE) */ *pkt << position << speed << pitch << yaw << keyPressed; *pkt << fov << wanted_range; diff --git a/src/game.cpp b/src/game.cpp index cc6e5a0e3..18b28c142 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -4214,7 +4214,7 @@ void Game::updateFrame(ProfilerGraph *graph, RunStats *stats, if (draw_control->range_all) { runData->fog_range = 100000 * BS; } else { - runData->fog_range = 0.9 * draw_control->wanted_range * BS; + runData->fog_range = draw_control->wanted_range * BS; } /* diff --git a/src/network/networkprotocol.h b/src/network/networkprotocol.h index c9919e1c4..018b392b6 100644 --- a/src/network/networkprotocol.h +++ b/src/network/networkprotocol.h @@ -652,7 +652,7 @@ enum ToServerCommand [2+12+12+4] s32 yaw*100 [2+12+12+4+4] u32 keyPressed [2+12+12+4+4+1] u8 fov*80 - [2+12+12+4+4+4+1] u8 wanted_range / MAP_BLOCKSIZE + [2+12+12+4+4+4+1] u8 ceil(wanted_range / MAP_BLOCKSIZE) */ TOSERVER_GOTBLOCKS = 0x24, -- cgit v1.2.3