mirror of
https://github.com/minetest/minetest.git
synced 2024-11-27 10:03:45 +01:00
Send ActiveObjects once right after Init2
This commit is contained in:
parent
9acd36bf99
commit
81c7f0ae04
@ -1243,8 +1243,14 @@ void Client::sendPlayerPos()
|
|||||||
u8 camera_fov = map.getCameraFov();
|
u8 camera_fov = map.getCameraFov();
|
||||||
u8 wanted_range = map.getControl().wanted_range;
|
u8 wanted_range = map.getControl().wanted_range;
|
||||||
|
|
||||||
// Save bandwidth by only updating position when something changed
|
// Save bandwidth by only updating position when
|
||||||
if(myplayer->last_position == myplayer->getPosition() &&
|
// player is not dead and something changed
|
||||||
|
|
||||||
|
if (m_activeobjects_received && myplayer->isDead())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (
|
||||||
|
myplayer->last_position == myplayer->getPosition() &&
|
||||||
myplayer->last_speed == myplayer->getSpeed() &&
|
myplayer->last_speed == myplayer->getSpeed() &&
|
||||||
myplayer->last_pitch == myplayer->getPitch() &&
|
myplayer->last_pitch == myplayer->getPitch() &&
|
||||||
myplayer->last_yaw == myplayer->getYaw() &&
|
myplayer->last_yaw == myplayer->getYaw() &&
|
||||||
|
@ -339,6 +339,8 @@ public:
|
|||||||
{ return m_nodedef_received; }
|
{ return m_nodedef_received; }
|
||||||
bool mediaReceived()
|
bool mediaReceived()
|
||||||
{ return !m_media_downloader; }
|
{ return !m_media_downloader; }
|
||||||
|
const bool activeObjectsReceived() const
|
||||||
|
{ return m_activeobjects_received; }
|
||||||
|
|
||||||
u16 getProtoVersion()
|
u16 getProtoVersion()
|
||||||
{ return m_proto_ver; }
|
{ return m_proto_ver; }
|
||||||
@ -539,6 +541,7 @@ private:
|
|||||||
std::queue<ClientEvent *> m_client_event_queue;
|
std::queue<ClientEvent *> m_client_event_queue;
|
||||||
bool m_itemdef_received = false;
|
bool m_itemdef_received = false;
|
||||||
bool m_nodedef_received = false;
|
bool m_nodedef_received = false;
|
||||||
|
bool m_activeobjects_received = false;
|
||||||
bool m_mods_loaded = false;
|
bool m_mods_loaded = false;
|
||||||
ClientMediaDownloader *m_media_downloader;
|
ClientMediaDownloader *m_media_downloader;
|
||||||
|
|
||||||
|
@ -463,6 +463,10 @@ void Client::handleCommand_ActiveObjectRemoveAdd(NetworkPacket* pkt)
|
|||||||
infostream << "handleCommand_ActiveObjectRemoveAdd: " << e.what()
|
infostream << "handleCommand_ActiveObjectRemoveAdd: " << e.what()
|
||||||
<< ". The packet is unreliable, ignoring" << std::endl;
|
<< ". The packet is unreliable, ignoring" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// m_activeobjects_received is false before the first
|
||||||
|
// TOCLIENT_ACTIVE_OBJECT_REMOVE_ADD packet is received
|
||||||
|
m_activeobjects_received = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::handleCommand_ActiveObjectMessages(NetworkPacket* pkt)
|
void Client::handleCommand_ActiveObjectMessages(NetworkPacket* pkt)
|
||||||
|
@ -298,9 +298,6 @@ void Server::handleCommand_Init2(NetworkPacket* pkt)
|
|||||||
infostream << "Server: Sending content to "
|
infostream << "Server: Sending content to "
|
||||||
<< getPlayerName(pkt->getPeerId()) << std::endl;
|
<< getPlayerName(pkt->getPeerId()) << std::endl;
|
||||||
|
|
||||||
// Send player movement settings
|
|
||||||
SendMovement(pkt->getPeerId());
|
|
||||||
|
|
||||||
// Send item definitions
|
// Send item definitions
|
||||||
SendItemDef(pkt->getPeerId(), m_itemdef, protocol_version);
|
SendItemDef(pkt->getPeerId(), m_itemdef, protocol_version);
|
||||||
|
|
||||||
@ -312,9 +309,25 @@ void Server::handleCommand_Init2(NetworkPacket* pkt)
|
|||||||
// Send media announcement
|
// Send media announcement
|
||||||
sendMediaAnnouncement(pkt->getPeerId(), lang);
|
sendMediaAnnouncement(pkt->getPeerId(), lang);
|
||||||
|
|
||||||
|
RemoteClient *client;
|
||||||
|
{
|
||||||
|
MutexAutoLock(m_con);
|
||||||
|
client = getClient(pkt->getPeerId(), CS_InitDone);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send active objects
|
||||||
|
{
|
||||||
|
PlayerSAO *sao = getPlayerSAO(pkt->getPeerId());
|
||||||
|
if (client && sao)
|
||||||
|
SendActiveObjectRemoveAdd(client, sao);
|
||||||
|
}
|
||||||
|
|
||||||
// Send detached inventories
|
// Send detached inventories
|
||||||
sendDetachedInventories(pkt->getPeerId(), false);
|
sendDetachedInventories(pkt->getPeerId(), false);
|
||||||
|
|
||||||
|
// Send player movement settings
|
||||||
|
SendMovement(pkt->getPeerId());
|
||||||
|
|
||||||
// Send time of day
|
// Send time of day
|
||||||
u16 time = m_env->getTimeOfDay();
|
u16 time = m_env->getTimeOfDay();
|
||||||
float time_speed = g_settings->getFloat("time_speed");
|
float time_speed = g_settings->getFloat("time_speed");
|
||||||
@ -323,11 +336,10 @@ void Server::handleCommand_Init2(NetworkPacket* pkt)
|
|||||||
SendCSMRestrictionFlags(pkt->getPeerId());
|
SendCSMRestrictionFlags(pkt->getPeerId());
|
||||||
|
|
||||||
// Warnings about protocol version can be issued here
|
// Warnings about protocol version can be issued here
|
||||||
if (getClient(pkt->getPeerId())->net_proto_version < LATEST_PROTOCOL_VERSION) {
|
if (client->net_proto_version < LATEST_PROTOCOL_VERSION) {
|
||||||
SendChatMessage(pkt->getPeerId(), ChatMessage(CHATMESSAGE_TYPE_SYSTEM,
|
SendChatMessage(pkt->getPeerId(), ChatMessage(CHATMESSAGE_TYPE_SYSTEM,
|
||||||
L"# Server: WARNING: YOUR CLIENT'S VERSION MAY NOT BE FULLY COMPATIBLE "
|
L"# Server: WARNING: YOUR CLIENT'S VERSION MAY NOT BE FULLY COMPATIBLE "
|
||||||
L"WITH THIS SERVER!"));
|
L"WITH THIS SERVER!"));
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
215
src/server.cpp
215
src/server.cpp
@ -620,124 +620,27 @@ void Server::AsyncRunStep(bool initial_step)
|
|||||||
|
|
||||||
m_clients.lock();
|
m_clients.lock();
|
||||||
const RemoteClientMap &clients = m_clients.getClientList();
|
const RemoteClientMap &clients = m_clients.getClientList();
|
||||||
ScopeProfiler sp(g_profiler, "Server: update visible objects");
|
ScopeProfiler sp(g_profiler, "Server: update objects within range");
|
||||||
|
|
||||||
// Radius inside which objects are active
|
|
||||||
static thread_local const s16 radius =
|
|
||||||
g_settings->getS16("active_object_send_range_blocks") * MAP_BLOCKSIZE;
|
|
||||||
|
|
||||||
// Radius inside which players are active
|
|
||||||
static thread_local const bool is_transfer_limited =
|
|
||||||
g_settings->exists("unlimited_player_transfer_distance") &&
|
|
||||||
!g_settings->getBool("unlimited_player_transfer_distance");
|
|
||||||
static thread_local const s16 player_transfer_dist =
|
|
||||||
g_settings->getS16("player_transfer_distance") * MAP_BLOCKSIZE;
|
|
||||||
s16 player_radius = player_transfer_dist;
|
|
||||||
if (player_radius == 0 && is_transfer_limited)
|
|
||||||
player_radius = radius;
|
|
||||||
|
|
||||||
for (const auto &client_it : clients) {
|
for (const auto &client_it : clients) {
|
||||||
RemoteClient *client = client_it.second;
|
RemoteClient *client = client_it.second;
|
||||||
|
|
||||||
// If definitions and textures have not been sent, don't
|
|
||||||
// send objects either
|
|
||||||
if (client->getState() < CS_DefinitionsSent)
|
if (client->getState() < CS_DefinitionsSent)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
RemotePlayer *player = m_env->getPlayer(client->peer_id);
|
// This can happen if the client times out somehow
|
||||||
if (!player) {
|
if (!m_env->getPlayer(client->peer_id))
|
||||||
// This can happen if the client timeouts somehow
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
PlayerSAO *playersao = player->getPlayerSAO();
|
PlayerSAO *playersao = getPlayerSAO(client->peer_id);
|
||||||
if (!playersao)
|
if (!playersao)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
s16 my_radius = MYMIN(radius, playersao->getWantedRange() * MAP_BLOCKSIZE);
|
SendActiveObjectRemoveAdd(client, playersao);
|
||||||
if (my_radius <= 0) my_radius = radius;
|
|
||||||
//infostream << "Server: Active Radius " << my_radius << std::endl;
|
|
||||||
|
|
||||||
std::queue<u16> removed_objects;
|
|
||||||
std::queue<u16> added_objects;
|
|
||||||
m_env->getRemovedActiveObjects(playersao, my_radius, player_radius,
|
|
||||||
client->m_known_objects, removed_objects);
|
|
||||||
m_env->getAddedActiveObjects(playersao, my_radius, player_radius,
|
|
||||||
client->m_known_objects, added_objects);
|
|
||||||
|
|
||||||
// Ignore if nothing happened
|
|
||||||
if (removed_objects.empty() && added_objects.empty()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string data_buffer;
|
|
||||||
|
|
||||||
char buf[4];
|
|
||||||
|
|
||||||
// Handle removed objects
|
|
||||||
writeU16((u8*)buf, removed_objects.size());
|
|
||||||
data_buffer.append(buf, 2);
|
|
||||||
while (!removed_objects.empty()) {
|
|
||||||
// Get object
|
|
||||||
u16 id = removed_objects.front();
|
|
||||||
ServerActiveObject* obj = m_env->getActiveObject(id);
|
|
||||||
|
|
||||||
// Add to data buffer for sending
|
|
||||||
writeU16((u8*)buf, id);
|
|
||||||
data_buffer.append(buf, 2);
|
|
||||||
|
|
||||||
// Remove from known objects
|
|
||||||
client->m_known_objects.erase(id);
|
|
||||||
|
|
||||||
if(obj && obj->m_known_by_count > 0)
|
|
||||||
obj->m_known_by_count--;
|
|
||||||
removed_objects.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle added objects
|
|
||||||
writeU16((u8*)buf, added_objects.size());
|
|
||||||
data_buffer.append(buf, 2);
|
|
||||||
while (!added_objects.empty()) {
|
|
||||||
// Get object
|
|
||||||
u16 id = added_objects.front();
|
|
||||||
ServerActiveObject* obj = m_env->getActiveObject(id);
|
|
||||||
|
|
||||||
// Get object type
|
|
||||||
u8 type = ACTIVEOBJECT_TYPE_INVALID;
|
|
||||||
if (!obj)
|
|
||||||
warningstream << FUNCTION_NAME << ": NULL object" << std::endl;
|
|
||||||
else
|
|
||||||
type = obj->getSendType();
|
|
||||||
|
|
||||||
// Add to data buffer for sending
|
|
||||||
writeU16((u8*)buf, id);
|
|
||||||
data_buffer.append(buf, 2);
|
|
||||||
writeU8((u8*)buf, type);
|
|
||||||
data_buffer.append(buf, 1);
|
|
||||||
|
|
||||||
if(obj)
|
|
||||||
data_buffer.append(serializeLongString(
|
|
||||||
obj->getClientInitializationData(client->net_proto_version)));
|
|
||||||
else
|
|
||||||
data_buffer.append(serializeLongString(""));
|
|
||||||
|
|
||||||
// Add to known objects
|
|
||||||
client->m_known_objects.insert(id);
|
|
||||||
|
|
||||||
if(obj)
|
|
||||||
obj->m_known_by_count++;
|
|
||||||
|
|
||||||
added_objects.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 pktSize = SendActiveObjectRemoveAdd(client->peer_id, data_buffer);
|
|
||||||
verbosestream << "Server: Sent object remove/add: "
|
|
||||||
<< removed_objects.size() << " removed, "
|
|
||||||
<< added_objects.size() << " added, "
|
|
||||||
<< "packet size is " << pktSize << std::endl;
|
|
||||||
}
|
}
|
||||||
m_clients.unlock();
|
m_clients.unlock();
|
||||||
|
|
||||||
|
// Save mod storages if modified
|
||||||
m_mod_storage_save_timer -= dtime;
|
m_mod_storage_save_timer -= dtime;
|
||||||
if (m_mod_storage_save_timer <= 0.0f) {
|
if (m_mod_storage_save_timer <= 0.0f) {
|
||||||
infostream << "Saving registered mod storages." << std::endl;
|
infostream << "Saving registered mod storages." << std::endl;
|
||||||
@ -1089,9 +992,9 @@ PlayerSAO* Server::StageTwoClientInit(session_t peer_id)
|
|||||||
return playersao;
|
return playersao;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Server::handleCommand(NetworkPacket* pkt)
|
inline void Server::handleCommand(NetworkPacket *pkt)
|
||||||
{
|
{
|
||||||
const ToServerCommandHandler& opHandle = toServerCommandTable[pkt->getCommand()];
|
const ToServerCommandHandler &opHandle = toServerCommandTable[pkt->getCommand()];
|
||||||
(this->*opHandle.handler)(pkt);
|
(this->*opHandle.handler)(pkt);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1925,12 +1828,106 @@ void Server::SendPlayerFormspecPrepend(session_t peer_id)
|
|||||||
Send(&pkt);
|
Send(&pkt);
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 Server::SendActiveObjectRemoveAdd(session_t peer_id, const std::string &datas)
|
void Server::SendActiveObjectRemoveAdd(RemoteClient *client, PlayerSAO *playersao)
|
||||||
{
|
{
|
||||||
NetworkPacket pkt(TOCLIENT_ACTIVE_OBJECT_REMOVE_ADD, datas.size(), peer_id);
|
// Radius inside which objects are active
|
||||||
pkt.putRawString(datas.c_str(), datas.size());
|
static thread_local const s16 radius =
|
||||||
|
g_settings->getS16("active_object_send_range_blocks") * MAP_BLOCKSIZE;
|
||||||
|
|
||||||
|
// Radius inside which players are active
|
||||||
|
static thread_local const bool is_transfer_limited =
|
||||||
|
g_settings->exists("unlimited_player_transfer_distance") &&
|
||||||
|
!g_settings->getBool("unlimited_player_transfer_distance");
|
||||||
|
|
||||||
|
static thread_local const s16 player_transfer_dist =
|
||||||
|
g_settings->getS16("player_transfer_distance") * MAP_BLOCKSIZE;
|
||||||
|
|
||||||
|
s16 player_radius = player_transfer_dist == 0 && is_transfer_limited ?
|
||||||
|
radius : player_transfer_dist;
|
||||||
|
|
||||||
|
s16 my_radius = MYMIN(radius, playersao->getWantedRange() * MAP_BLOCKSIZE);
|
||||||
|
if (my_radius <= 0)
|
||||||
|
my_radius = radius;
|
||||||
|
|
||||||
|
std::queue<u16> removed_objects, added_objects;
|
||||||
|
m_env->getRemovedActiveObjects(playersao, my_radius, player_radius,
|
||||||
|
client->m_known_objects, removed_objects);
|
||||||
|
m_env->getAddedActiveObjects(playersao, my_radius, player_radius,
|
||||||
|
client->m_known_objects, added_objects);
|
||||||
|
|
||||||
|
int removed_count = removed_objects.size();
|
||||||
|
int added_count = added_objects.size();
|
||||||
|
|
||||||
|
if (removed_objects.empty() && added_objects.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
char buf[4];
|
||||||
|
std::string data;
|
||||||
|
|
||||||
|
// Handle removed objects
|
||||||
|
writeU16((u8*)buf, removed_objects.size());
|
||||||
|
data.append(buf, 2);
|
||||||
|
while (!removed_objects.empty()) {
|
||||||
|
// Get object
|
||||||
|
u16 id = removed_objects.front();
|
||||||
|
ServerActiveObject* obj = m_env->getActiveObject(id);
|
||||||
|
|
||||||
|
// Add to data buffer for sending
|
||||||
|
writeU16((u8*)buf, id);
|
||||||
|
data.append(buf, 2);
|
||||||
|
|
||||||
|
// Remove from known objects
|
||||||
|
client->m_known_objects.erase(id);
|
||||||
|
|
||||||
|
if (obj && obj->m_known_by_count > 0)
|
||||||
|
obj->m_known_by_count--;
|
||||||
|
|
||||||
|
removed_objects.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle added objects
|
||||||
|
writeU16((u8*)buf, added_objects.size());
|
||||||
|
data.append(buf, 2);
|
||||||
|
while (!added_objects.empty()) {
|
||||||
|
// Get object
|
||||||
|
u16 id = added_objects.front();
|
||||||
|
ServerActiveObject* obj = m_env->getActiveObject(id);
|
||||||
|
|
||||||
|
// Get object type
|
||||||
|
u8 type = ACTIVEOBJECT_TYPE_INVALID;
|
||||||
|
if (!obj)
|
||||||
|
warningstream << FUNCTION_NAME << ": NULL object" << std::endl;
|
||||||
|
else
|
||||||
|
type = obj->getSendType();
|
||||||
|
|
||||||
|
// Add to data buffer for sending
|
||||||
|
writeU16((u8*)buf, id);
|
||||||
|
data.append(buf, 2);
|
||||||
|
writeU8((u8*)buf, type);
|
||||||
|
data.append(buf, 1);
|
||||||
|
|
||||||
|
if (obj)
|
||||||
|
data.append(serializeLongString(
|
||||||
|
obj->getClientInitializationData(client->net_proto_version)));
|
||||||
|
else
|
||||||
|
data.append(serializeLongString(""));
|
||||||
|
|
||||||
|
// Add to known objects
|
||||||
|
client->m_known_objects.insert(id);
|
||||||
|
|
||||||
|
if (obj)
|
||||||
|
obj->m_known_by_count++;
|
||||||
|
|
||||||
|
added_objects.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkPacket pkt(TOCLIENT_ACTIVE_OBJECT_REMOVE_ADD, data.size(), client->peer_id);
|
||||||
|
pkt.putRawString(data.c_str(), data.size());
|
||||||
Send(&pkt);
|
Send(&pkt);
|
||||||
return pkt.getSize();
|
|
||||||
|
verbosestream << "Server::SendActiveObjectRemoveAdd: "
|
||||||
|
<< removed_count << " removed, " << added_count << " added, "
|
||||||
|
<< "packet size is " << pkt.getSize() << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::SendActiveObjectMessages(session_t peer_id, const std::string &datas,
|
void Server::SendActiveObjectMessages(session_t peer_id, const std::string &datas,
|
||||||
|
@ -469,7 +469,7 @@ private:
|
|||||||
bool vertical, const std::string &texture,
|
bool vertical, const std::string &texture,
|
||||||
const struct TileAnimationParams &animation, u8 glow);
|
const struct TileAnimationParams &animation, u8 glow);
|
||||||
|
|
||||||
u32 SendActiveObjectRemoveAdd(session_t peer_id, const std::string &datas);
|
void SendActiveObjectRemoveAdd(RemoteClient *client, PlayerSAO *playersao);
|
||||||
void SendActiveObjectMessages(session_t peer_id, const std::string &datas,
|
void SendActiveObjectMessages(session_t peer_id, const std::string &datas,
|
||||||
bool reliable = true);
|
bool reliable = true);
|
||||||
void SendCSMRestrictionFlags(session_t peer_id);
|
void SendCSMRestrictionFlags(session_t peer_id);
|
||||||
|
Loading…
Reference in New Issue
Block a user