From bf19f7ae9ceacf9e6a65e097be443ae3f5c85232 Mon Sep 17 00:00:00 2001 From: "madmaxoft@gmail.com" Date: Thu, 23 Feb 2012 22:51:03 +0000 Subject: [PATCH] Made the viewdistance settable by users and default in settings.ini. The default is 9. git-svn-id: http://mc-server.googlecode.com/svn/trunk@326 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- source/cClientHandle.cpp | 33 +++++++++++++++++++++++----- source/cClientHandle.h | 13 ++++++++--- source/cServer.cpp | 47 +++++++++++++++++++++++++++++----------- source/cServer.h | 2 ++ source/cWorld.h | 6 ----- 5 files changed, 73 insertions(+), 28 deletions(-) diff --git a/source/cClientHandle.cpp b/source/cClientHandle.cpp index 70fa8e455..78032611e 100644 --- a/source/cClientHandle.cpp +++ b/source/cClientHandle.cpp @@ -86,8 +86,9 @@ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // cClientHandle: -cClientHandle::cClientHandle(const cSocket & a_Socket) - : m_ProtocolVersion(23) +cClientHandle::cClientHandle(const cSocket & a_Socket, int a_ViewDistance) + : m_ViewDistance(a_ViewDistance) + , m_ProtocolVersion(23) , m_pSendThread(NULL) , m_Socket(a_Socket) , m_Semaphore(MAX_SEMAPHORES) @@ -342,7 +343,7 @@ void cClientHandle::StreamChunks(void) { int RelX = (*itr).m_ChunkX - ChunkPosX; int RelZ = (*itr).m_ChunkZ - ChunkPosZ; - if ((RelX > VIEWDISTANCE) || (RelX < -VIEWDISTANCE) || (RelZ > VIEWDISTANCE) || (RelZ < -VIEWDISTANCE)) + if ((RelX > m_ViewDistance) || (RelX < -m_ViewDistance) || (RelZ > m_ViewDistance) || (RelZ < -m_ViewDistance)) { World->RemoveChunkClient(itr->m_ChunkX, itr->m_ChunkY, itr->m_ChunkZ, this); Send( cPacket_PreChunk( itr->m_ChunkX, itr->m_ChunkZ, false ) ); @@ -357,7 +358,7 @@ void cClientHandle::StreamChunks(void) { int RelX = (*itr).m_ChunkX - ChunkPosX; int RelZ = (*itr).m_ChunkZ - ChunkPosZ; - if ((RelX > VIEWDISTANCE) || (RelX < -VIEWDISTANCE) || (RelZ > VIEWDISTANCE) || (RelZ < -VIEWDISTANCE)) + if ((RelX > m_ViewDistance) || (RelX < -m_ViewDistance) || (RelZ > m_ViewDistance) || (RelZ < -m_ViewDistance)) { itr = m_ChunksToSend.erase(itr); } @@ -370,7 +371,7 @@ void cClientHandle::StreamChunks(void) // Add all chunks that are in range and not yet in m_LoadedChunks: // Queue these smartly - from the center out to the edge - for (int d = 0; d <= VIEWDISTANCE; ++d) // cycle through (square) distance, from nearest to furthest + for (int d = 0; d <= m_ViewDistance; ++d) // cycle through (square) distance, from nearest to furthest { // For each distance add chunks in a hollow square centered around current position: for (int i = -d; i <= d; ++i) @@ -386,7 +387,7 @@ void cClientHandle::StreamChunks(void) } // for d // Touch chunks GENERATEDISTANCE ahead to let them generate: - for (int d = VIEWDISTANCE + 1; d <= VIEWDISTANCE + GENERATEDISTANCE; ++d) // cycle through (square) distance, from nearest to furthest + for (int d = m_ViewDistance + 1; d <= m_ViewDistance + GENERATEDISTANCE; ++d) // cycle through (square) distance, from nearest to furthest { // For each distance touch chunks in a hollow square centered around current position: for (int i = -d; i <= d; ++i) @@ -1890,6 +1891,26 @@ const AString & cClientHandle::GetUsername(void) const +void cClientHandle::SetViewDistance(int a_ViewDistance) +{ + if (a_ViewDistance < MIN_VIEW_DISTANCE) + { + a_ViewDistance = MIN_VIEW_DISTANCE; + } + if (a_ViewDistance > MAX_VIEW_DISTANCE) + { + a_ViewDistance = MAX_VIEW_DISTANCE; + } + m_ViewDistance = a_ViewDistance; + + // Need to re-stream chunks for the change to become apparent: + StreamChunks(); +} + + + + + void cClientHandle::DataReceived(const char * a_Data, int a_Size) { // Data is received from the client diff --git a/source/cClientHandle.h b/source/cClientHandle.h index ffe25db2b..6b567a88b 100644 --- a/source/cClientHandle.h +++ b/source/cClientHandle.h @@ -65,8 +65,12 @@ public: }; static const int MAXBLOCKCHANGEINTERACTIONS = 10; // 5 didn't help, 10 seems to have done the trick + + static const int DEFAULT_VIEW_DISTANCE = 9; // The default ViewDistance (used when no value is set in Settings.ini) + static const int MAX_VIEW_DISTANCE = 10; + static const int MIN_VIEW_DISTANCE = 4; - cClientHandle(const cSocket & a_Socket); + cClientHandle(const cSocket & a_Socket, int a_ViewDistance); ~cClientHandle(); const cSocket & GetSocket(void) const {return m_Socket; } @@ -99,11 +103,14 @@ public: const AString & GetUsername(void) const; inline short GetPing() { return m_Ping; } + + void SetViewDistance(int a_ViewDistance); private: - static const int VIEWDISTANCE = 4; // Number of chunks the player can see in each direction; 4 is the minimum ( http://wiki.vg/Protocol_FAQ#.E2.80.A6all_connecting_clients_spasm_and_jerk_uncontrollably.21 ) - static const int GENERATEDISTANCE = 1; // Server generates this many chunks AHEAD of player sight. + int m_ViewDistance; // Number of chunks the player can see in each direction; 4 is the minimum ( http://wiki.vg/Protocol_FAQ#.E2.80.A6all_connecting_clients_spasm_and_jerk_uncontrollably.21 ) + + static const int GENERATEDISTANCE = 2; // Server generates this many chunks AHEAD of player sight. 2 is the minimum, since foliage is generated 1 step behind chunk terrain generation int m_ProtocolVersion; AString m_Username; diff --git a/source/cServer.cpp b/source/cServer.cpp index a1ff76292..8462fa915 100644 --- a/source/cServer.cpp +++ b/source/cServer.cpp @@ -174,20 +174,10 @@ bool cServer::InitServer( int a_Port ) m_bIsConnected = true; cIniFile IniFile("settings.ini"); - if( IniFile.ReadFile() ) + if (IniFile.ReadFile()) { g_bWaterPhysics = IniFile.GetValueB("Physics", "Water", false ); - /* Replaced below with 1.0.0 compatible ServerID generation - - std::string ServerID = IniFile.GetValue("Server", "ServerID"); - if( ServerID.empty() ) - { - ServerID = "MCServer"; - IniFile.SetValue("Server", "ServerID", ServerID, true ); - IniFile.WriteFile(); - } - */ m_pState->ServerID = "-"; if (IniFile.GetValueB("Authentication", "Authenticate")) { @@ -201,6 +191,23 @@ bool cServer::InitServer( int a_Port ) ServerID.resize(16, '0'); m_pState->ServerID = ServerID; } + + m_ClientViewDistance = IniFile.GetValueI("Server", "DefaultViewDistance", -1); + if (m_ClientViewDistance == -1) + { + m_ClientViewDistance = cClientHandle::DEFAULT_VIEW_DISTANCE; + LOG("[Server].DefaultViewDistance not set, using a default of %d", m_ClientViewDistance); + } + if (m_ClientViewDistance < cClientHandle::MIN_VIEW_DISTANCE) + { + m_ClientViewDistance = cClientHandle::MIN_VIEW_DISTANCE; + LOGINFO("Setting default viewdistance to the minimum of %d", m_ClientViewDistance); + } + if (m_ClientViewDistance > cClientHandle::MAX_VIEW_DISTANCE) + { + m_ClientViewDistance = cClientHandle::MAX_VIEW_DISTANCE; + LOGINFO("Setting default viewdistance to the maximum of %d", m_ClientViewDistance); + } } return true; } @@ -273,7 +280,7 @@ void cServer::StartListenClient() LOG("Client \"%s\" connected!", ClientIP.c_str()); - cClientHandle *NewHandle = new cClientHandle(SClient); + cClientHandle *NewHandle = new cClientHandle(SClient, m_ClientViewDistance); if (!m_SocketThreads.AddClient(&(NewHandle->GetSocket()), NewHandle)) { // For some reason SocketThreads have rejected the handle, clean it up @@ -398,9 +405,11 @@ bool from_string( bool cServer::Command( cClientHandle & a_Client, const char* a_Cmd ) { - cPluginManager* PM = cRoot::Get()->GetPluginManager(); + cPluginManager* PM = cRoot::Get()->GetPluginManager(); if( PM->CallHook( cPluginManager::E_PLUGIN_CHAT, 2, a_Cmd, a_Client.GetPlayer() ) ) + { return true; + } std::string Command( a_Cmd ); if( Command.length() <= 0 ) return false; @@ -417,6 +426,18 @@ bool cServer::Command( cClientHandle & a_Client, const char* a_Cmd ) a_Client.Send( cPacket_Chat(cChatColor::Green + Pos)); return true; } + + if (split[0].compare("/viewdistance") == 0) + { + if (split.size() != 2) + { + a_Client.Send(cPacket_Chat(cChatColor::Green + "Invalid syntax, expected 1 parameter, the numebr of chunks to stream")); + return false; + } + int dist = atol(split[1].c_str()); + a_Client.SetViewDistance(dist); + return true; + } return false; } diff --git a/source/cServer.h b/source/cServer.h index 7e42cb1e7..3e7fbf094 100644 --- a/source/cServer.h +++ b/source/cServer.h @@ -69,6 +69,8 @@ private: sServerState* m_pState; cSocketThreads m_SocketThreads; + + int m_ClientViewDistance; // The default view distance for clients; settable in Settings.ini // Time since server was started float m_Millisecondsf; diff --git a/source/cWorld.h b/source/cWorld.h index 2fc907b3a..7551740ab 100644 --- a/source/cWorld.h +++ b/source/cWorld.h @@ -59,14 +59,8 @@ public: int GetHeight( int a_X, int a_Z ); //tolua_export - //void AddClient( cClientHandle* a_Client ); - //void RemoveClient( cClientHandle* a_Client ); - //ClientList & GetClients(); - void Broadcast( const cPacket & a_Packet, cClientHandle* a_Exclude = 0 ); - void BroadcastToChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, cPacket & a_Packet, cClientHandle * a_Exclude = NULL); - void BroadcastToChunkOfBlock(int a_X, int a_Y, int a_Z, cPacket * a_Packet, cClientHandle * a_Exclude = NULL); void MarkChunkDirty (int a_ChunkX, int a_ChunkY, int a_ChunkZ);