// Increment timers
m_nothing_to_send_pause_timer -= dtime;
+ m_nearest_unsent_reset_timer += dtime;
if(m_nothing_to_send_pause_timer >= 0)
{
- // Keep this reset
- m_nearest_unsent_reset_timer = 0;
return;
}
/*infostream<<"m_nearest_unsent_reset_timer="
<<m_nearest_unsent_reset_timer<<std::endl;*/
- // This has to be incremented only when the nothing to send pause
- // is not active
- m_nearest_unsent_reset_timer += dtime;
-
- // Reset periodically to avoid possible bugs or other mishaps
- if(m_nearest_unsent_reset_timer > 10.0)
+ // Reset periodically to workaround for some bugs or stuff
+ if(m_nearest_unsent_reset_timer > 20.0)
{
m_nearest_unsent_reset_timer = 0;
m_nearest_unsent_d = 0;
- /*infostream<<"Resetting m_nearest_unsent_d for "
- <<server->getPlayerName(peer_id)<<std::endl;*/
+ //infostream<<"Resetting m_nearest_unsent_d for "
+ // <<server->getPlayerName(peer_id)<<std::endl;
}
//s16 last_nearest_unsent_d = m_nearest_unsent_d;
s16 d_max_gen = g_settings->getS16("max_block_generate_distance");
// Don't loop very much at a time
- if(d_max > d_start+1)
- d_max = d_start+1;
+ s16 max_d_increment_at_time = 2;
+ if(d_max > d_start + max_d_increment_at_time)
+ d_max = d_start + max_d_increment_at_time;
/*if(d_max_gen > d_start+2)
d_max_gen = d_start+2;*/
//infostream<<"Starting from "<<d_start<<std::endl;
- bool sending_something = false;
-
- bool no_blocks_found_for_sending = true;
-
+ s32 nearest_emerged_d = -1;
+ s32 nearest_emergefull_d = -1;
+ s32 nearest_sent_d = -1;
bool queue_is_full = false;
s16 d;
for(d = d_start; d <= d_max; d++)
{
+ /*errorstream<<"checking d="<<d<<" for "
+ <<server->getPlayerName(peer_id)<<std::endl;*/
//infostream<<"RemoteClient::SendBlocks(): d="<<d<<std::endl;
/*
if(abs(p.Y - center.Y) > d_max_gen - d_max_gen / 3)
generate = false;*/
- // Limit the send area vertically to 2/3
- if(abs(p.Y - center.Y) > d_max_gen - d_max_gen / 3)
+ // Limit the send area vertically to 1/2
+ if(abs(p.Y - center.Y) > d_max / 2)
continue;
}
-#if 1
+#if 0
/*
If block is far away, don't generate it unless it is
near ground level.
#endif
//infostream<<"d="<<d<<std::endl;
-
+#if 1
/*
Don't generate or send if not in sight
FIXME This only works if the client uses a small enough
{
continue;
}
-
+#endif
/*
Don't send already sent blocks
*/
Block is near ground level if night-time mesh
differs from day-time mesh.
*/
- if(d > 3)
+ if(d >= 4)
{
if(block->dayNightDiffed() == false)
continue;
continue;
}
- /*
- Record the lowest d from which a block has been
- found being not sent and possibly to exist
- */
- if(no_blocks_found_for_sending)
- {
- if(generate == true)
- new_nearest_unsent_d = d;
- }
-
- no_blocks_found_for_sending = false;
-
/*
Add inexistent block to emerge queue.
*/
// Allow only one block in emerge queue
//if(server->m_emerge_queue.peerItemCount(peer_id) < 1)
// Allow two blocks in queue per client
- if(server->m_emerge_queue.peerItemCount(peer_id) < 2)
+ //if(server->m_emerge_queue.peerItemCount(peer_id) < 2)
+ if(server->m_emerge_queue.peerItemCount(peer_id) < 25)
{
//infostream<<"Adding block to emerge queue"<<std::endl;
server->m_emerge_queue.addBlock(peer_id, p, flags);
server->m_emergethread.trigger();
+
+ if(nearest_emerged_d == -1)
+ nearest_emerged_d = d;
+ } else {
+ if(nearest_emergefull_d == -1)
+ nearest_emergefull_d = d;
}
// get next one.
continue;
}
+ if(nearest_sent_d == -1)
+ nearest_sent_d = d;
+
/*
Add block to send queue
*/
+ /*errorstream<<"sending from d="<<d<<" to "
+ <<server->getPlayerName(peer_id)<<std::endl;*/
+
PrioritySortedBlockTransfer q((float)d, p, peer_id);
dest.push_back(q);
num_blocks_selected += 1;
- sending_something = true;
}
}
queue_full_break:
//infostream<<"Stopped at "<<d<<std::endl;
- if(no_blocks_found_for_sending)
- {
- if(queue_is_full == false)
- new_nearest_unsent_d = d;
+ // If nothing was found for sending and nothing was queued for
+ // emerging, continue next time browsing from here
+ if(nearest_emerged_d != -1){
+ new_nearest_unsent_d = nearest_emerged_d;
+ } else if(nearest_emergefull_d != -1){
+ new_nearest_unsent_d = nearest_emergefull_d;
+ } else {
+ if(d > g_settings->getS16("max_block_send_distance")){
+ new_nearest_unsent_d = 0;
+ m_nothing_to_send_pause_timer = 2.0;
+ /*infostream<<"GetNextBlocks(): d wrapped around for "
+ <<server->getPlayerName(peer_id)
+ <<"; setting to 0 and pausing"<<std::endl;*/
+ } else {
+ if(nearest_sent_d != -1)
+ new_nearest_unsent_d = nearest_sent_d;
+ else
+ new_nearest_unsent_d = d;
+ }
}
if(new_nearest_unsent_d != -1)
m_nearest_unsent_d = new_nearest_unsent_d;
- if(sending_something == false)
- {
- m_nothing_to_send_counter++;
- if((s16)m_nothing_to_send_counter >=
- g_settings->getS16("max_block_send_distance"))
- {
- // Pause time in seconds
- m_nothing_to_send_pause_timer = 1.0;
- /*infostream<<"nothing to send to "
- <<server->getPlayerName(peer_id)
- <<" (d="<<d<<")"<<std::endl;*/
- }
- }
- else
- {
- m_nothing_to_send_counter = 0;
- }
-
/*timer_result = timer.stop(true);
if(timer_result != 0)
infostream<<"GetNextBlocks duration: "<<timer_result<<" (!=0)"<<std::endl;*/
}
/*
- Get and write object data
- */
-
- /*
- Get nearby blocks.
-
- For making players to be able to build to their nearby
- environment (building is not possible on blocks that are not
- in memory):
- - Set blocks changed
- - Add blocks to emerge queue if they are not found
-
- SUGGESTION: These could be ignored from the backside of the player
+ Get and write object data (dummy, for compatibility)
*/
- Player *player = server->m_env.getPlayer(peer_id);
-
- assert(player);
-
- v3f playerpos = player->getPosition();
- v3f playerspeed = player->getSpeed();
-
- v3s16 center_nodepos = floatToInt(playerpos, BS);
- v3s16 center = getNodeBlockPos(center_nodepos);
-
// Write block count
writeU16(buf, 0);
os.write((char*)buf, 2);
m_thread.stop();
// Initialize connection
- m_con.setTimeoutMs(30);
+ m_con.SetTimeoutMs(30);
m_con.Serve(port);
// Start thread
{
DSTACK(__FUNCTION_NAME);
+ g_profiler->add("Server::AsyncRunStep (num)", 1);
+
float dtime;
{
JMutexAutoLock lock1(m_step_dtime_mutex);
}
{
- ScopeProfiler sp(g_profiler, "Server: selecting and sending "
- "blocks to clients");
+ ScopeProfiler sp(g_profiler, "Server: sel and send blocks to clients");
// Send blocks to clients
SendBlocks(dtime);
}
if(dtime < 0.001)
return;
+
+ g_profiler->add("Server::AsyncRunStep with dtime (num)", 1);
//infostream<<"Server steps "<<dtime<<std::endl;
//infostream<<"Server::AsyncRunStep(): dtime="<<dtime<<std::endl;
{
// This has to be called so that the client list gets synced
// with the peer list of the connection
- ScopeProfiler sp(g_profiler, "Server: peer change handling");
handlePeerChanges();
}
{
JMutexAutoLock lock(m_env_mutex);
// Step environment
- ScopeProfiler sp(g_profiler, "Server: environment step");
+ ScopeProfiler sp(g_profiler, "SEnv step");
+ ScopeProfiler sp2(g_profiler, "SEnv step avg", SPT_AVG);
m_env.step(dtime);
}
JMutexAutoLock envlock(m_env_mutex);
JMutexAutoLock conlock(m_con_mutex);
- ScopeProfiler sp(g_profiler, "Server: checking added and deleted objects");
+ ScopeProfiler sp(g_profiler, "Server: checking added and deleted objs");
// Radius inside which objects are active
s16 radius = g_settings->getS16("active_object_send_range_blocks");
JMutexAutoLock envlock(m_env_mutex);
JMutexAutoLock conlock(m_con_mutex);
- ScopeProfiler sp(g_profiler, "Server: sending object messages");
+ //ScopeProfiler sp(g_profiler, "Server: sending object messages");
// Key = object id
// Value = data sent by object
/*
Send object positions
- TODO: Get rid of MapBlockObjects
*/
{
float &counter = m_objectdata_timer;
JMutexAutoLock lock1(m_env_mutex);
JMutexAutoLock lock2(m_con_mutex);
- ScopeProfiler sp(g_profiler, "Server: sending mbo positions");
+ //ScopeProfiler sp(g_profiler, "Server: sending player positions");
SendObjectData(counter);
void Server::Receive()
{
DSTACK(__FUNCTION_NAME);
- u32 data_maxsize = 10000;
- Buffer<u8> data(data_maxsize);
+ SharedBuffer<u8> data;
u16 peer_id;
u32 datasize;
try{
{
JMutexAutoLock conlock(m_con_mutex);
- datasize = m_con.Receive(peer_id, *data, data_maxsize);
+ datasize = m_con.Receive(peer_id, data);
}
// This has to be called so that the client list gets synced
JMutexAutoLock envlock(m_env_mutex);
JMutexAutoLock conlock(m_con_mutex);
- con::Peer *peer;
try{
- peer = m_con.GetPeer(peer_id);
+ Address address = m_con.GetPeerAddress(peer_id);
+
+ // drop player if is ip is banned
+ if(m_banmanager.isIpBanned(address.serializeString())){
+ SendAccessDenied(m_con, peer_id,
+ L"Your ip is banned. Banned name was "
+ +narrow_to_wide(m_banmanager.getBanName(
+ address.serializeString())));
+ m_con.DeletePeer(peer_id);
+ return;
+ }
}
catch(con::PeerNotFoundException &e)
{
return;
}
- // drop player if is ip is banned
- if(m_banmanager.isIpBanned(peer->address.serializeString())){
- SendAccessDenied(m_con, peer_id,
- L"Your ip is banned. Banned name was "
- +narrow_to_wide(m_banmanager.getBanName(
- peer->address.serializeString())));
- m_con.deletePeer(peer_id, false);
- return;
- }
-
- u8 peer_ser_ver = getClient(peer->id)->serialization_version;
+ u8 peer_ser_ver = getClient(peer_id)->serialization_version;
try
{
return;
infostream<<"Server: Got TOSERVER_INIT from "
- <<peer->id<<std::endl;
+ <<peer_id<<std::endl;
// First byte after command is maximum supported
// serialization version
deployed = SER_FMT_VER_INVALID;
//peer->serialization_version = deployed;
- getClient(peer->id)->pending_serialization_version = deployed;
+ getClient(peer_id)->pending_serialization_version = deployed;
if(deployed == SER_FMT_VER_INVALID)
{
net_proto_version = readU16(&data[2+1+PLAYERNAME_SIZE+PASSWORD_SIZE]);
}
- getClient(peer->id)->net_proto_version = net_proto_version;
+ getClient(peer_id)->net_proto_version = net_proto_version;
if(net_proto_version == 0)
{
if(command == TOSERVER_INIT2)
{
infostream<<"Server: Got TOSERVER_INIT2 from "
- <<peer->id<<std::endl;
+ <<peer_id<<std::endl;
- getClient(peer->id)->serialization_version
- = getClient(peer->id)->pending_serialization_version;
+ getClient(peer_id)->serialization_version
+ = getClient(peer_id)->pending_serialization_version;
/*
Send some initialization data
SendPlayerInfos();
// Send inventory to player
- UpdateCrafting(peer->id);
- SendInventory(peer->id);
+ UpdateCrafting(peer_id);
+ SendInventory(peer_id);
// Send player items to all players
SendPlayerItems();
{
SharedBuffer<u8> data = makePacket_TOCLIENT_TIME_OF_DAY(
m_env.getTimeOfDay());
- m_con.Send(peer->id, 0, data, true);
+ m_con.Send(peer_id, 0, data, true);
}
// Send information about server to player in chat
}
// Warnings about protocol version can be issued here
- if(getClient(peer->id)->net_proto_version < PROTOCOL_VERSION)
+ if(getClient(peer_id)->net_proto_version < PROTOCOL_VERSION)
{
SendChatMessage(peer_id, L"# Server: WARNING: YOUR CLIENT IS OLD AND MAY WORK PROPERLY WITH THIS SERVER");
}
else if(action == 2)
{
#if 0
- RemoteClient *client = getClient(peer->id);
+ RemoteClient *client = getClient(peer_id);
JMutexAutoLock digmutex(client->m_dig_mutex);
client->m_dig_tool_item = -1;
#endif
}
// Reset build time counter
- getClient(peer->id)->m_time_from_building = 0.0;
+ getClient(peer_id)->m_time_from_building = 0.0;
// Create node data
MaterialItem *mitem = (MaterialItem*)item;
Player *player = *i;
try{
- con::Peer *peer = m_con.GetPeer(player->peer_id);
- // Copy info from peer to info struct
- info.id = peer->id;
- info.address = peer->address;
- info.avg_rtt = peer->avg_rtt;
+ // Copy info from connection to info struct
+ info.id = player->peer_id;
+ info.address = m_con.GetPeerAddress(player->peer_id);
+ info.avg_rtt = m_con.GetPeerAvgRTT(player->peer_id);
}
catch(con::PeerNotFoundException &e)
{
SendChatMessage(player->peer_id, std::wstring(L"Server: -!- ")+msg);
}
+void Server::notifyPlayers(const std::wstring msg)
+{
+ BroadcastChatMessage(msg);
+}
+
v3f findSpawnPos(ServerMap &map)
{
//return v3f(50,50,50)*BS;